All notable changes to airgap-cpp-devkit are documented here.
Format follows Keep a Changelog. Versions follow Semantic Versioning.
server/internal/api/network.go— internet probes (/api/network,/api/updates, update download) are now gated behindallow_egressindevkit.config.json(defaultsfalse); previously the server unconditionally dialled8.8.8.8:53andapi.github.comon every/api/updatescall, breaking the air-gap contractexamples/devkit.config.json— addedallow_egress: falsefield so the template is explicit;server/internal/config/config.gogains the matchingAllowEgressfield
tools/dev-tools/git/setup.sh— now exits 0 with a "skipping" message on Linux (wasexit 1); matches the pattern already used by notepadpp, servy, sourcetree, and grpc
server/main.go— browser auto-open URL corrected from?token=to?devkit_token=; the auth handler requiresdevkit_tokenbut the launch URL was using the wrong parameter name, causing every auto-open to return 401
README.md— Configuration section updated:setup_completeandallow_egressnow shown in the example block with explanation; Network status and Update checker feature rows clarified to reflect the egress gate; First-run setup note corrected (was describing the wrong condition)
1.3.3 — 2026-05-03
scripts/build-server.sh— removed unconditionalgo mod tidy+go mod download; build now uses-mod=vendorwhenserver/vendor/is present; exits with a clear error whenGOPROXY=offand the vendor dir is absent instead of silently reaching out to the networkscripts/install-cli.shstep 1 — no longer callsgit submodule updatewhenprebuilt/is already populated; in a true air-gap (no network) it warns and continues rather than hard-failing the entire install
server/internal/api/auth.go—GET /auth/bootstrapnow reads?devkit_token=(was?token=), matching the token middleware and README; using the documented query parameter now correctly sets the session cookieserver/internal/api/handlers.go—prefixOverridePathmoved to~/.config/airgap-cpp-devkit/prefix(viaos.UserConfigDir()); previously pointed at the nonexistentmanager/src/…path, causingPOST /api/prefixto always return 500packages/pip-packages/devkit.json— correctedsetuppath fromlanguages/python/setup.sh(resolved to a nonexistent sibling) to../../tools/languages/python/setup.sh;GET /install/pip-packagesno longer returns "No such file or directory"
tools/dev-tools/vscode-extensions/setup.sh—VSIX_DIRnow triesprebuilt/dev-tools/vscode-extensions/first, then falls back toprebuilt/dev-tools/vscode/extensions/andprebuilt/dev-tools/vscode/; was hard-coded to the missingvscode-extensions/pathtools/toolchains/ninja/setup.sh— tar member changed fromninjato./ninjato match archive entry format; extraction no longer fails with "Not found in archive"tools/toolchains/gcc/setup.sh— non-root Linux install now usesrpm2cpio | cpio -idmvto extract RPM payloads into$PREFIX; previously hard-exited with "Root required" for non-root users despite README claiming user-prefix mode is supported
server/internal/config/config.go— on a fresh install with nodevkit.config.json,SetupCompletenow defaults totrue; everyGET /api/*no longer silently 302-redirects to/setupbefore the user has a chance to complete the wizard
scripts/launch.sh— default port corrected8080 → 9090to match README anddevkit.config.jsondocumentationscripts/launch.sh—_free_port()now usesss -ltnp/lsofon Linux instead ofnetstat -ano(which parses Windows column layout and misidentifies Linux's Timer column as a PID)scripts/launch.sh—--yes,--profile,--prefix,--admin,--rebuildflags are now forwarded toinstall-cli.shwhen the server binary is missing and the script falls back to CLI install; previously all CLI flags were silently droppedscripts/status.sh— staletools/toolchains/clang/style-formatter/paths updated totools/toolchains/llvm/style-formatter/scripts/install-cli.sh— header comment updated: removed stale Python 3.8+ requirement, corrected port reference to 9090, replacedclangpath withllvm
1.3.2 — 2026-05-01
scripts/sign-binaries.sh— Authenticode (Windows, viaosslsigncodeorsigntool) and GPG detached-signature (Linux) supportscripts/verify-signatures.sh— verify Authenticode and GPG signatures on prebuilt binariesscripts/virustotal-scan.sh— VirusTotal API v3 scan with JSON report output; supports files >32 MB via large-file upload URLci/sign.sh— thin CI entry-point that callsscripts/sign-binaries.sh.github/workflows/sign-and-scan.yml— manualworkflow_dispatchworkflow to sign binaries and/or run VirusTotal scan in CIosslsigncode 2.13entry inscripts/download-prebuilt.sh(Windows zip + Linux source archive)
scripts/release.sh— integrated signing (--skip-sign) and VirusTotal scan (--skip-vt) steps; both are run by default when env vars are present.github/workflows/build-llvm-rhel8.yml—actions/upload-artifactv4.6.0 → v7.0.1;actions/download-artifactv4 → v8.0.1 (pinned SHA).github/workflows/smoke-test.yml—actions/upload-artifactv4.6.0 → v7.0.1 (pinned SHA).gitignore— added.claudeignore- Server binaries rebuilt against current Go toolchain
1.3.1 — 2026-05-01
scripts/launch.sh,scripts/uninstall.sh,tests/check-installed-tools.sh— removed unused variables flagged by ShellCheck (SC2034)scripts/pkg.sh— fixed printf format/argument mismatch (SC2183) by splitting composite argument into two separate argstests/run-tests.sh,tests/check-installed-tools.sh— added ShellCheck source directive for non-constantsourcepaths (SC1090)tests/validate-manifests.sh— removed redundant quotes around regex RHS in[[ =~ ]](SC2076)
- Go deps:
go-chi/chiv5.2.2 → v5.2.5,golang.org/x/textv0.22.0 → v0.36.0; server binaries rebuilt - Python build deps:
setuptools>=75,wheel>=0.45
1.3.0 — 2026-05-01
- Repository layout — aligned to project standard:
ci/(renamed from.ci/),scripts/launch.sh,scripts/install-cli.sh,scripts/uninstall.sh(moved from root),docs/TOOLS.md(moved from root),ci/Dockerfile.rhel8-test(moved from root) - CI workflows —
ci.ymlthinned to callci/lint.sh,ci/test.sh, andci/smoke.sh; server health-check logic extracted toci/smoke.sh - All Jenkinsfile,
.gitlab-ci.yml,smoke-test.yml, andrhel8-test.ymlreferences updated for new script paths scripts/launch.shandscripts/install-cli.shinternal path resolution updated for new location inscripts/
ci/build.sh,ci/test.sh,ci/lint.sh,ci/release.sh,ci/smoke.sh— canonical CI entry-point scripts.github/CODEOWNERS— primary maintainer assigned for all files and CI paths.github/dependabot.yml— weekly dependency updates for Go modules, pip, and GitHub Actionsdocs/assets/— home for project screenshots and diagramsexamples/— placeholder for runnable configuration examplespackages/python/src/airgap_devkit/py.typed— PEP 561 typed package markerpackages/python/.python-version— pinned Python version for the packaging environment.pre-commit-config.yaml— ruff lint/format and standard pre-commit hooks
1.2.1 — 2026-05-01
Dockerfile.rhel8-test— RHEL 8 CI$(ldd --version | head -1)command substitution was evaluated by the outer/bin/shand the result embedded unquoted, causing bash to choke on the parentheses inldd (GNU libc) 2.28with a syntax error; wrapped the substitution in escaped double quotes so the parentheses are safely quoted when bash receives the string.github/workflows/— updatedactions/checkoutfrom v4.2.2 (Node.js 20, deprecated) to v4.3.1 (Node.js 24) across all three workflow files
1.2.0 — 2026-05-01
- Manual install fallback — when the devkit-ui cannot complete an installation, a "Show manual install commands" button appears in the terminal drawer; clicking it opens a modal with tabbed Windows / Linux steps, pre-filled copy-ready shell commands, and split-archive reassembly instructions generated from
GET /api/tool/{id}/manual-install GET /api/tool/{id}/manual-installAPI endpoint — returns platform-specific env block, install command, custom prefix example, split-archive reassembly commands, and per-platform notesscanPrebuiltParts— server-side scanner that finds.part-*files inprebuilt/and buildscat | tarreassembly commands for each split archivescripts/manual-install.sh— CLI fallback installer;--listenumerates tools,--tool <id>installs,--prefixsets a custom path,--verify-onlyconfirms split parts are presentdocs/manual-install.md— step-by-step manual install guide for Windows (Git Bash) and Linux, with tool-specific examples, manual split-archive reassembly commands, receipt creation, PATH wiring, and troubleshooting table.github/workflows/rhel8-test.yml— CI workflow that buildsDockerfile.rhel8-testand runs the full install + smoke-test suite inside UBI 8.10 (RHEL 8 / glibc 2.28); triggers on install-related path changes, weekly Monday schedule, andworkflow_dispatch
install-cli.sh— added--adminflag (selects system-wide install prefix);Jenkinsfileand.gitlab-ci.ymlboth pass--adminwhenADMIN_INSTALL=truebut the flag was previously unrecognised, crashing the install stepJenkinsfileand.gitlab-ci.ymlserver-ops stage — all API calls now includeX-DevKit-Tokenheader;auth.gorequires the token for every route except/health,/auth/bootstrap, and/static/, so everycurlto/api/config,/api/health/tools, etc. was returning 401.gitlab-ci.yml— replace fragile/proc/*/cmdlinePID scan inafter_scriptwith a.server.pidfile (after_scriptruns in a fresh shell and cannot access variables set in the main script)
1.1.0 — 2026-04-30
- First-run setup wizard —
/setuppage with animated gradient UI; server redirects all requests there until setup is complete (setup_completeflag indevkit.config.json) - Team Config Repository sync — configure a git repo URL in Settings; devkit auto-syncs team config on every launch and provides a manual sync button with last-sync status indicator
server/internal/team/package —CloneOrPull,LoadConfig,LastCommithelpers for team config git syncsetupCheckmiddleware — enforces setup wizard flow on first launch before any dashboard accessvalidateRepoURL— server-side validation for team config repo URL inputsanitizeDisplayName— sanitization for display name fieldsGET /api/team/statusandPOST /api/team/syncAPI endpoints for team config sync- Dashboard installed/all filter — clickable stat chip to toggle between all tools and installed-only view
escHtmlandescJshelper functions in dashboard JS to prevent XSS in dynamic content- GitHub update version badges in the dashboard update checker UI
scripts/release.sh— atomic version bump, Go binary build, Python wheel build, and optional PyPI uploadscripts/download-prebuilt.sh— download prebuilt binaries from GitHub releasespackages/python/— PyPI package source (pyproject.toml,__main__.py,__init__.py, stage-binaries script)dist/to.gitignore— wheel build artifacts are no longer tracked.github/profile/README.md— GitHub org profile landing page
devkit.config.jsonschema: addedteam_config_repo(string) andsetup_complete(bool) fields/api/configacceptsteam_config_repo; triggers background sync when the repo URL changes- Removed
7zipfrom the built-incpp-devanddevopsprofile tool lists .gitignore: fixed.pyirctypo →.pypirc; addeddist/build artifact exclusionREADME.md: updated version reference to v1.1.0
1.0.1-rc.2 — 2026-04-26
.gitignore— added.devkit-tokenand TLS certificate exclusions- Updated
prebuilt/submodule to v1.0.1-rc.2 binaries
1.0.0-rc.1 — 2026-04-25
CONTRIBUTING.md— dual-licensing CLA with copyright assignment and patent grantCHANGELOG.md— Keep a Changelog format with full backfilled historySECURITY.md— private disclosure policy, SLA table, scope definition, security design notesCODE_OF_CONDUCT.md— professional conduct standards and enforcement contact.github/ISSUE_TEMPLATE/bug_report.md— structured bug report template.github/ISSUE_TEMPLATE/feature_request.md— feature request template with air-gap compatibility checklist.github/ISSUE_TEMPLATE/config.yml— issue chooser with security advisory, discussions, and commercial licensing links.github/pull_request_template.md— PR checklist enforcing binary policy, SBOM, syntax checks.github/FUNDING.yml— GitHub sponsor button placeholderSUPPORT.md— help channels: issues, discussions, security email, commercial contact- AGPL v3 license badge and CI badge in README
- Contributing and License sections in README with dual-licensing note
- Version bumped to v1.0.0-rc.1 — first release candidate
LICENSE— relicensed from custom Source-Available License v1.0 to GNU Affero General Public License v3.0SECURITY.md— corrected TLS note:--tlsauto-generates a self-signed certificate.editorconfig— added Go (tabs), JSON (2-space), and Makefile (tabs) sections
0.2.0-alpha.2 — 2025-04-19
- Session token authentication — one-time bootstrap redirect on first launch; token saved to
.devkit-token - Optional HTTPS support — pass
--tls-certand--tls-keytolaunch.sh - Response header hardening (
X-Content-Type-Options,X-Frame-Options,Cache-Control) - VS Code integration tool entry
- DevKit Manager is now a single pre-compiled Go binary; no Python, pip, or runtime dependencies required
launch.shselects the correct binary for the current platform automatically
0.2.0-alpha.1 — 2025-04-13
- CI/CD pipeline (GitHub Actions): build + smoke-test matrix across Windows and RHEL
- Atlassian integration placeholders
- Layout configuration support in
devkit.config.json - My Team button relocated to top bar for quicker access
- Top bar height adjusted for denser layout
- Profile cards and settings panel layout polish
0.1.0 — 2025-03
- Initial air-gapped C++ developer toolkit
- FastAPI + HTMX devkit-ui with SSE live install output
- Tool auto-discovery from
devkit.jsonper tool directory - Install receipt tracking (
INSTALL_RECEIPT.txt) - Air-gap wheel vendoring under
tools/dev-tools/devkit-ui/vendor/ - Multi-profile support:
cpp-dev,devops,minimal,full - Team config export/import (
GET /api/export,POST /api/import) - Update checker comparing installed version vs current
devkit.json - SBOM generation (
scripts/generate-sbom.sh→sbom.spdx.json) - Windows 11 (Git Bash) and RHEL 8 (Bash 4.x) support