Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

479 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

airgap-cpp-devkit

Author: Nima Shafie

CI Platform Air-gapped Latest Release PyPI

Air-gapped C++ developer toolkit for network-restricted environments. All tools work offline. All dependencies are vendored in-repo or in the prebuilt/ submodule.

v1.3.66 — DevKit Manager is a single pre-compiled Go binary with built-in session token authentication and optional HTTPS. No Python, no pip, no runtime dependencies required to run the UI.


Quick Start

Step 1 — Clone the repo (first time only)

git clone <this-repo-url>
cd airgap-cpp-devkit
git submodule update --init --recursive

Step 2 — Start the DevKit Manager

Windows (Git Bash) and Linux:

bash scripts/launch.sh

The script selects the correct pre-compiled binary for your platform, starts the server, and opens the browser automatically. On first run a session token is generated and saved to .devkit-token; the browser is authenticated automatically via a one-time bootstrap redirect.

Keep the terminal open while you use the DevKit Manager — it is the server. Press Ctrl+C to stop.

The port is read from devkit.config.json (default 9090). Pass --port to override it for a single session.

Step 3 — Install tools

  1. Pick a profile for a one-click batch install:
    • Minimal — core tools only (clang, cmake, python, style-formatter)
    • C++ Developer — full C++ stack (clang, cmake, python, conan, VS Code extensions, sqlite)
    • DevOps — infrastructure tools (cmake, python, conan, sqlite)
    • Full — every available tool
  2. Or click Install next to any individual tool.
  3. Custom profiles can be created and saved from the Settings panel.

No binary? Run bash scripts/launch.sh --rebuild to compile the server binary from the vendored Go source (requires Go 1.21+). Then rerun bash scripts/launch.sh.

No UI needed? Use the CLI directly: bash scripts/internal/install-cli.sh For headless/CI installs: bash scripts/internal/install-cli.sh --yes --profile cpp-dev

Deploying for a team or a locked-down laptop? See docs/DEPLOYMENT.md for the two supported models: an admin hosting one shared server for the whole team (bash scripts/serve.sh), or per-user no-admin local installs (bash scripts/launch.sh).


scripts/launch.sh Flags

bash scripts/launch.sh                      # launch UI and open browser
bash scripts/launch.sh --port 9090          # custom port (one session only)
bash scripts/launch.sh --host 0.0.0.0       # bind to all interfaces (LAN / remote access)
bash scripts/launch.sh --no-browser         # start server, don't open browser
bash scripts/launch.sh --tls                # enable HTTPS with a self-signed certificate
bash scripts/launch.sh --cli                # skip UI, run scripts/internal/install-cli.sh directly
bash scripts/launch.sh --rebuild            # rebuild binary from source, then launch

Configuration

devkit.config.json at the repo root controls the server and UI. It is read at startup; changes take effect on next launch.

{
  "team_name":       "My Team",
  "org_name":        "",
  "devkit_name":     "AirGap DevKit",
  "theme_color":     "#2563eb",
  "dashboard_title": "Tool Dashboard",
  "hostname":        "127.0.0.1",
  "port":            9090,
  "default_profile": "minimal",
  "setup_complete":  true,
  "allow_egress":    false
}

allow_egress: false (default) keeps the server fully air-gapped — /api/network always returns online: false and /api/updates returns an empty list without probing the internet. Set to true only on machines with intentional internet access to enable the update checker and network latency probe.

Team identity (team_name, org_name, devkit_name, theme_color) can also be pushed live via POST /api/config or through CI/CD pipelines without restarting.


DevKit Manager Features

The manager is a self-contained Go binary with an embedded web UI. Features:

Feature Description
Token authentication Every request requires a session token (header, cookie, or query param). Token is auto-generated on first run and saved to .devkit-token.
HTTPS / TLS Pass --tls to serve over HTTPS with an auto-generated self-signed certificate (devkit-tls.crt / devkit-tls.key).
Tool dashboard Install/uninstall status per tool; one-click install and rebuild
Profile installs Batch install via built-in or custom profiles
Custom profiles Create, save, and delete named profiles (profiles.json)
Team config Export (GET /api/export) and import (POST /api/import) full config snapshots
Package upload Push .zip bundle archives to the server (POST /packages/upload); 256 MB total / 64 MB per-file limit enforced
Install prefix View, override, or reset the install path without editing files
Dashboard layout Reorder tool categories; changes persisted in layout.json
Tool meta overrides Override display name, description, or icon per tool
Version management Keep multiple installed versions per tool; switch active version
Live install log SSE-streamed output per tool; log history browser
Health checks GET /api/health/tools — verifies all installed tool binaries respond
Network status GET /api/network — returns online: false unless allow_egress: true is set in devkit.config.json
Update checker GET /api/updates — compares pinned manifest versions against GitHub releases; requires allow_egress: true

Authentication

All API requests (except GET /health and static assets) require the session token. Pass it via any of:

# Header (recommended for scripts/CI)
curl -H "X-DevKit-Token: <token>" http://127.0.0.1:9090/api/tools

# Cookie (set automatically by the browser after the bootstrap redirect)

# One-time URL hand-off — the ONLY endpoint that accepts the token in the query
# string. It sets the session cookie and redirects to the UI.
curl -c cookies.txt "http://127.0.0.1:9090/auth/bootstrap?devkit_token=<token>&next=/"

The token in the query string is accepted only by /auth/bootstrap. Data endpoints such as /api/tools?devkit_token=<token> return 401 Unauthorized by design — a URL-borne token would otherwise leak into history, referrer headers and access logs. Use the X-DevKit-Token header for scripted calls.

The token is printed to the terminal on startup and saved to .devkit-token in the repo root (readable by the current user only).

API Endpoints (selected)

GET  /health                         — server liveness check (no token required)
GET  /auth/bootstrap                 — exchange URL token for session cookie, redirect to UI

# Tool install/uninstall actions — respond with SSE (text/event-stream) live output
GET  /install/<id>                   — install a tool (streams progress)
GET  /uninstall/<id>                 — uninstall a tool (streams progress)
GET  /check/<id>                     — run the tool's check_cmd (streams output)
GET  /versions/<id>                  — show installed version info
GET  /logs/<id>                      — stream the last install log
GET  /install-pkg/<id>               — install a package bundle (streams progress)
GET  /remove-pkg/<id>                — remove a package bundle (streams progress)
GET  /install-profile/<name>         — install all tools in a profile (streams progress)
GET  /download-update/<id>           — download a tool update

# Metadata and configuration
GET  /api/tools                      — full tool list with install status
GET  /api/tool/{id}                  — single tool detail
GET  /api/health/tools               — binary health check for all installed tools
GET  /api/network                    — network connectivity probe
GET  /api/updates                    — pending version updates
GET  /api/export                     — export team config as JSON
POST /api/import                     — import team config
POST /api/config                     — update team identity live
GET  /api/profiles                   — list profiles
POST /api/profiles                   — create/update a profile
DELETE /api/profiles/{id}            — delete a profile
POST /packages/upload                — upload a .zip package bundle
GET  /api/prefix                     — current install prefix
POST /api/prefix                     — override install prefix
DELETE /api/prefix                   — reset to auto-detected prefix
GET  /api/layout                     — current dashboard layout
POST /api/layout                     — save layout
DELETE /api/layout                   — reset to defaults

First-run setup: the server redirects /api/* to /setup when devkit.config.json exists but has "setup_complete": false. The repo ships a default devkit.config.json with "setup_complete": true so new installs skip the wizard. For headless/CI use, verify that setup_complete is true in your config file before hitting the API.


CI/CD Integration

Pipeline files ship in the repo root and delegate to ci/.

File Platform
Jenkinsfile Jenkins
.gitlab-ci.yml GitLab CI/CD
ci/atlassian/jira-update.sh Jira issue updater
ci/atlassian/confluence-update.sh Confluence page writer

Both pipelines implement the same logical stages:

Validate → Configure → Install → Server Operations → Smoke Tests → Atlassian
Stage What it does
Validate Checks all devkit.json and manifest.json files for syntax and required fields
Configure Patches devkit.config.json with pipeline parameters (team, profile, port)
Install Runs scripts/internal/install-cli.sh --yes --profile <PROFILE> on Linux and/or Windows agents
Server Operations Starts the server; reads token from .devkit-token; pushes team identity; handles package upload, config import/export
Smoke Tests Runs tests/run-tests.sh to verify all installed tools respond
Atlassian Posts build result to a Jira issue and overwrites a Confluence status page

CI note: All DevKit Manager API calls from pipelines must include the X-DevKit-Token header. The token is available at .devkit-token after the server has started.

Key Pipeline Parameters

Parameter Default Description
PROFILE minimal minimal, cpp-dev, devops, full
TARGET_OS linux linux, windows, or both
TEAM_NAME My Team Written to devkit.config.json
UPLOAD_PACKAGE false Upload a .zip bundle to the running server
EXPORT_TEAM_CONFIG false Archive the current team config as a build artifact
IMPORT_TEAM_CONFIG (blank) Raw JSON to POST to /api/import
SAVE_PROFILE_JSON (blank) JSON to create/update a custom install profile
ATLASSIAN_UPDATE false Push build result to Jira + Confluence

Triggering via API

Jenkins:

curl -X POST "https://jenkins.example.com/job/airgap-devkit/buildWithParameters" \
  --user "user:api-token" \
  --data "PROFILE=cpp-dev&TEAM_NAME=Backend+Team&ATLASSIAN_UPDATE=true&JIRA_ISSUE_KEY=DEVKIT-42"

GitLab:

curl -X POST "https://gitlab.example.com/api/v4/projects/PROJECT_ID/trigger/pipeline" \
  --form "token=TRIGGER_TOKEN" --form "ref=main" \
  --form "variables[PROFILE]=cpp-dev" --form "variables[TEAM_NAME]=Backend Team"

See ci/README.md for full setup instructions and ci/atlassian/README.md for Atlassian configuration.


Deployment Scenarios

Base case — Pre-built binaries allowed

git clone <this-repo-url>
cd airgap-cpp-devkit
git submodule update --init --recursive
bash scripts/launch.sh          # opens DevKit Manager
# or: bash scripts/internal/install-cli.sh --yes --profile cpp-dev

Worst case — Binaries not permitted, source only

Skip the submodule. Both the DevKit Manager and scripts/internal/install-cli.sh detect that prebuilt/ is absent and fall back to building all tools from vendored source.

git clone <this-repo-url>
cd airgap-cpp-devkit
# Do NOT run: git submodule update --init --recursive
bash scripts/launch.sh          # opens DevKit Manager
# or: bash scripts/internal/install-cli.sh

Server binary — if prebuilt/bin/ is absent, run bash scripts/launch.sh --rebuild once to compile the Go server from server/.


Install Modes

Admin/root detection is automatic. System-wide is attempted first; per-user is used if the current process cannot write to the system path.

Mode Windows Linux
Admin (system-wide) C:\Program Files\airgap-cpp-devkit\<tool>\ /opt/airgap-cpp-devkit/<tool>/
User (per-user) %LOCALAPPDATA%\airgap-cpp-devkit\<tool>\ ~/.local/share/airgap-cpp-devkit/<tool>/

Each tool writes INSTALL_RECEIPT.txt on success. <prefix>/env.sh wires PATH into ~/.bashrc. To install system-wide on Windows, open Git Bash as Administrator.

The active prefix can be viewed or overridden from the DevKit Manager Settings panel, or via the API (GET /api/prefix, POST /api/prefix).


Tools

Directory Purpose Required?
tools/toolchains/llvm/style-formatter/ LLVM C++ style enforcement via Git pre-commit hook Yes
tools/toolchains/clang/source-build/ clang-format + clang-tidy from LLVM 22.1.3; prebuilt or source build No
tools/build-tools/cmake/ CMake 4.4.2 — prebuilt or source build; RHEL/Rocky 8, 9, 10 + Windows No
tools/dev-tools/git-bundle/ Transfers Git repos with nested submodules across air-gapped boundaries Yes
tools/toolchains/lcov/ Code coverage via lcov 2.5 + gcov; vendored Perl deps included No
tools/languages/python/ Portable Python 3.14.4 — Windows embeddable + Linux standalone No
tools/languages/dotnet/ Portable .NET 10 SDK 10.0.302 — Windows + Linux, no installer No
tools/dev-tools/vscode-extensions/ Offline VS Code extensions: C/C++, C++ TestMate, Python No
tools/toolchains/gcc/windows/ GCC 15.2.0 + MinGW-w64 13.0.0 UCRT for Windows No
tools/dev-tools/servy/ Servy 8.9 — Windows service manager (no-op on Linux) No
tools/dev-tools/conan/ Conan 2.27.1 — C/C++ package manager, no Python required No
tools/frameworks/grpc/ gRPC v1.83.0 — Windows prebuilt per MSVC toolset (VS 2019/2022/2026, Release or Debug) + Linux RHEL/Rocky 8/9/10 (x86_64) No
tools/lib/zlib/ zlib 1.3.2 — gzip/DEFLATE compression library; vendored source, CMake build; Windows + Linux No
tools/dev-tools/filezilla/ FileZilla 3.70.4 — FTP/SFTP client; Windows + Linux No
tools/dev-tools/gdb/ GDB 17.2 — Linux source build (~25 min) No
tools/dev-tools/notepadpp/ Notepad++ 8.9.7 — Windows only; portable zip or NSIS installer No
tools/dev-tools/putty/ PuTTY 0.84 — Windows MSI + Linux source build No
tools/dev-tools/sourcetree/ SourceTree 3.4.31 — Git GUI client; Windows only No

Prerequisites

Platform DevKit Manager CLI installer
Windows 11 Git Bash (MINGW64) Git Bash (MINGW64)
RHEL/Rocky 8, 9, 10 Bash 4.x Bash 4.x
Debian 10+ / Ubuntu 20.04+ / openSUSE·SLES 15+ / Arch / Fedora Bash 4.x Bash 4.x
Alpine 3.21+ (musl) Bash (required) Bash (required)

Linux tool selection is keyed off the host libc (glibc vs musl), not the distro name. The glibc 2.28 floor build (from RHEL 8) runs on every glibc distro listed above; a fully-static musl build covers Alpine and other musl hosts. New distros that use one of these two libc families require no new code.

Alpine / BusyBox note: the entry-point scripts (launch.sh, serve.sh, install-cli.sh) require bash — they use BASH_SOURCE, arrays and [[ ]], which BusyBox ash (Alpine's default shell) does not support. Install it with apk add bash; on an air-gapped Alpine host, stage the bash apk first. The DevKit Manager server binary itself runs fine under musl without bash.

The DevKit Manager binary (prebuilt/bin/) has no runtime dependencies. Python is not required to run the UI. It is bundled as an optional installable tool in tools/languages/python/.

To rebuild the server binary from source: Go 1.21+ is required.


Development Setup

git clone <this-repo-url>
cd airgap-cpp-devkit
git submodule update --init --recursive

# Launch DevKit Manager (uses prebuilt binary)
bash scripts/launch.sh

# Or rebuild the binary from source first
bash scripts/launch.sh --rebuild

Useful commands

bash -n <script.sh> && echo "OK"                        # syntax-check before running
bash scripts/launch.sh --no-browser                     # dev mode, logs in terminal
bash scripts/launch.sh --tls --no-browser               # HTTPS mode

# Health check (no token required)
# Note: --noproxy '*' bypasses http_proxy/https_proxy — on a corporate LAN those
# are usually set and would otherwise send the loopback request to the proxy,
# which fails. (Equivalently: export no_proxy=127.0.0.1,localhost.)
curl -s --noproxy '*' http://127.0.0.1:9090/health

# API calls — pass token via header
TOKEN=$(cat .devkit-token)
curl -s --noproxy '*' -H "X-DevKit-Token: $TOKEN" http://127.0.0.1:9090/api/tools

bash tests/run-tests.sh --verbose
bash scripts/internal/install-cli.sh --yes --profile cpp-dev
bash scripts/internal/generate-sbom.sh
bash scripts/internal/status.sh                                   # print install status of all tools
bash scripts/internal/pkg.sh list                                 # list all bundled tools and versions
bash scripts/internal/pkg.sh set-version cmake 3.31.0

Deploying to Production Repositories

Optional. Only needed if you want to enforce LLVM C++ style in another repository using this devkit as a submodule.

The formatter lives as a submodule in each production repo. Developers only ever run bash setup.sh.

Step 1 — Add the submodule (once per repo)

cd your-cpp-project/

git submodule add \
    <airgap-cpp-devkit-repo-url> \
    tools/style-formatter

git submodule update --init --recursive

Step 2 — Copy setup.sh into the repo root

cp tools/toolchains/llvm/style-formatter/docs/production-repo-template/setup.sh ./setup.sh

Step 3 — Append .gitignore entries

cat tools/toolchains/llvm/style-formatter/docs/gitignore-snippet.txt >> .gitignore

Step 4 — Commit and push

git add .gitmodules tools/style-formatter setup.sh .gitignore
git commit -m "chore: add LLVM C++ style enforcement"
git push

What developers do after this (once per machine)

git clone <your-cpp-project-url>
cd your-cpp-project
bash setup.sh

Done. Every subsequent git commit enforces LLVM style.


Design Principles

Principle How it is met
Air-gapped All dependencies vendored in-repo or in prebuilt/ submodule
Binary-restricted environments Skip prebuilt/; build all tools from vendored source
No runtime dependencies DevKit Manager is a single static Go binary
Admin + user install Admin detection at runtime; system-wide or per-user paths
Install transparency Install receipt + timestamped log file written on every bootstrap
Cross-platform Windows 11 (Git Bash / MINGW64) + Linux: glibc distros (RHEL/Rocky 8/9/10, Debian/Ubuntu, SUSE, Arch, Fedora) + Alpine/musl
Integrity verification SHA256 pinned in manifest.json for all vendored archives
Team/CI ready Jenkins + GitLab pipelines; Jira + Confluence integration

Repository Structure

airgap-cpp-devkit/
+-- README.md                              <- you are here
+-- CHANGELOG.md
+-- CONTRIBUTING.md
+-- CODE_OF_CONDUCT.md
+-- SECURITY.md
+-- SUPPORT.md
+-- LICENSE
+-- sbom.spdx.json                         <- root aggregate SBOM (SPDX 2.3)
+-- layout.json                            <- dashboard category/tool ordering
+-- Jenkinsfile                            <- Jenkins declarative pipeline (thin)
+-- .gitlab-ci.yml                         <- GitLab CI/CD pipeline (thin)
+-- .gitmodules                            <- submodule pointers (prebuilt, tools)
|
+-- ci/                                    <- CI/CD scripts and platform configs
|   +-- build.sh                           <- build the Go server binary
|   +-- test.sh                            <- run manifest validation suite
|   +-- lint.sh                            <- syntax-check all shell scripts
|   +-- release.sh                         <- thin wrapper around scripts/internal/release.sh
|   +-- smoke.sh                           <- server health check (used by ci.yml)
|   +-- Dockerfile.linux-test             <- RHEL/Rocky 8/9/10 (UBI) integration test image
|   +-- Dockerfile.debian-test           <- Debian 12 (apt/glibc) integration test image
|   +-- Dockerfile.alpine-test           <- Alpine 3.21 (apk/musl) integration test image
|   +-- atlassian/
|   |   +-- jira-update.sh                 <- post build result to Jira issue
|   |   +-- confluence-update.sh           <- overwrite Confluence status page
|   |   +-- atlassian.config.json          <- config template (no secrets committed)
|   +-- jenkins/                           <- Jenkins setup docs
|   +-- gitlab/                            <- GitLab setup docs
|
+-- .github/
|   +-- workflows/
|   |   +-- ci.yml                         <- thin; calls ci/lint.sh, ci/test.sh, ci/smoke.sh
|   |   +-- smoke-test.yml                 <- weekly + manual install regression
|   |   +-- linux-integration.yml          <- multi-distro integration test matrix (RHEL/Rocky 8/9/10, Debian 12, Alpine 3.21); push/PR runs rhel-9 + debian-12; weekly schedule runs all five
|   |   +-- build-llvm-linux.yml           <- builds Clang/LLVM per distro (8/9/10)
|   +-- ISSUE_TEMPLATE/
|   +-- PULL_REQUEST_TEMPLATE.md
|   +-- CODEOWNERS
|   +-- dependabot.yml
|
+-- docs/
|   +-- assets/                            <- screenshots and diagrams
|   +-- TOOLS.md                           <- single-page tool inventory
|   +-- manual-install.md                  <- manual install guide
|
+-- examples/                              <- runnable config examples
|
+-- scripts/
|   +-- launch.sh                          <- PRIMARY entry point (starts Go server)
|   +-- internal/                          <- helper scripts (not run directly)
|   |   +-- install-cli.sh                <- CLI installer / headless installs
|   |   +-- uninstall.sh                  <- removes all installed tools
|   |   +-- release.sh                    <- version bump + build + PyPI upload
|   |   +-- generate-sbom.sh              <- regenerates all SBOM timestamps
|   |   +-- status.sh                     <- prints install status of all tools
|   |   +-- pkg.sh                        <- package management helper
|   |   +-- manual-install.sh             <- fallback installer (no UI)
|   |   +-- build-server.sh               <- builds Go binary from source
|   |   +-- install-mode.sh               <- shared admin/user detection library
|   |   +-- setup-prebuilt-submodule.sh   <- initialize prebuilt submodule
|   |   +-- download-prebuilt.sh          <- downloads/stages prebuilt binaries
|   |   +-- sign-binaries.sh              <- Authenticode + GPG binary signing
|   |   +-- verify-signatures.sh          <- verifies binary signatures
|   |   +-- virustotal-scan.sh            <- VirusTotal API v3 scan
|   |   +-- fetch-vscode-extensions.py    <- mirrors .vsix files for offline use
|
+-- tests/
|   +-- run-tests.sh                       <- post-install smoke tests
|   +-- validate-manifests.sh              <- validates devkit.json/manifest.json syntax
|   +-- check-installed-tools.sh           <- tests check_cmd for installed tools
|
+-- server/                                <- Go server source (DevKit Manager)
|   +-- main.go
|   +-- go.mod / go.sum
|   +-- internal/
|   |   +-- api/                           <- HTTP handlers, routes, SSE, bundling
|   |   |   +-- auth.go                    <- session token middleware
|   |   |   +-- version.go                 <- AppVersion constant
|   |   +-- config/                        <- devkit.config.json loader
|   |   +-- tools/                         <- tool discovery and status
|   +-- web/                               <- embedded web UI (templates, assets)
|
+-- packages/
|   +-- python/                            <- PyPI packaging wrapper
|   |   +-- pyproject.toml
|   |   +-- src/airgap_devkit/
|   +-- pip-packages/                      <- vendored pip wheels
|
+-- prebuilt/                              <- SUBMODULE (separate repo, optional)
|   +-- bin/                               <- devkit-server binaries (Linux + Windows)
|   +-- languages/python/                  <- Python 3.14.4
|   +-- toolchains/                        <- Clang, GCC, LLVM binaries
|
+-- tools/                                 <- SUBMODULE (airgap-devkit/tools)
    +-- build-tools/cmake/
    +-- dev-tools/
    +-- frameworks/grpc/
    +-- languages/
    +-- toolchains/

Contributing

Contributions are welcome. See CONTRIBUTING.md for the CLA, coding conventions, and PR checklist. Security vulnerabilities go to SECURITY.md — not to public issues.


License

AGPL-3.0-or-later — see LICENSE. A commercial license is available for use cases that can't accept AGPL terms; contact nimzshafie@gmail.com.

OS/distribution logos under server/web/static/img/ are from Simple Icons (CC0-1.0); see docs/THIRD-PARTY-NOTICES.md for attributions.

About

Engine and pip package for the airgap-devkit ecosystem — FastAPI web UI, tool discovery, profile management, and online/air-gap mode detection

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages