Skip to content

feat(admin): runtime install of subscription CLIs from the admin UI - #816

Merged
Weegy merged 2 commits into
mainfrom
feat/cli-runtime-install
Aug 21, 2026
Merged

feat(admin): runtime install of subscription CLIs from the admin UI#816
Weegy merged 2 commits into
mainfrom
feat/cli-runtime-install

Conversation

@Weegy

@Weegy Weegy commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Enabler for #294, extends the #309 Subscription-CLIs subsystem.

The public image deliberately does not bundle the vendor CLIs (INSTALL_SUBSCRIPTION_CLIS=false — redistributing proprietary CLIs needs legal review), so a missing CLI dead-ended in manual shell steps on the Subscription-CLIs admin page. This PR adds an operator-triggered runtime install ("nachinstallieren"): npm install from the public npm registry into CLI_TOOLS_DIR on the persisted volume, surfaced as an Install now button with progress polling.

Middleware

  • New cliInstallService: fixed package allowlist (claude → @anthropic-ai/claude-code, codex → @openai/codex, gemini → @google/gemini-cli), optional version behind a strict semver gate, execFile without a shell, bounded time/output, host-global single-flight (slot reserved before any await — TOCTOU-safe).
  • New routes on the existing auth-required router: POST /api/v1/admin/cli-backends/:id/install (202 started / 200 already installed / 409 conflict / 400 bad id or version) and GET /:id/install/status.
  • Detector + auth service resolve binaries via CLI_TOOLS_DIR/bin before PATH, so a volume install is visible to detection and the in-app login without PATH mutation.
  • CLI_TOOLS_DIR + CODEX_HOME documented in middleware/.env.example; CHANGELOG entry added.

Web-UI

  • InstallBox (new component) with progress polling, poll bail-out after repeated failures, dedicated 409 message; manual steps stay one click away. i18n en+de. Panel split to stay under the 500-line rule.

Verification

  • npm install -g --prefix … @openai/codex smoke-tested in node:22.23.2-slim (exit 0, codex-cli 0.149.0 runs).
  • Fly volume writability confirmed: entrypoint chowns /data and drops to node via gosu.

Test plan

  • middleware: typecheck, lint, test/cliInstallService.test.ts 14/14 (allowlist/semver injection rejection, single-flight incl. TOCTOU regression, failure log tail, route 202/409/400) + detector suite 10/10
  • web-ui: typecheck, lint, i18n:check, vitest 15/15 (panel + i18n parity)
  • CI green (middleware / web-ui / schema / audit)

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Weegy added 2 commits August 21, 2026 08:48
The public image deliberately does not bundle the vendor CLIs
(INSTALL_SUBSCRIPTION_CLIS=false - redistribution needs legal review), so a
missing CLI dead-ended in manual shell steps on the Subscription-CLIs page.
Adds an operator-triggered npm install from the public registry into
CLI_TOOLS_DIR on the persisted volume, surfaced as an Install button.

- middleware: cliInstallService (fixed package allowlist, strict semver
  gate, execFile without shell, bounded time/output, host-global
  single-flight reserved before any await), routes
  POST /api/v1/admin/cli-backends/:id/install (202/409/400) and
  GET /:id/install/status; detector + auth service resolve the binary via
  CLI_TOOLS_DIR/bin before PATH; CLI_TOOLS_DIR + CODEX_HOME documented in
  .env.example
- web-ui: InstallBox with progress polling (bail-out after repeated poll
  failures, dedicated 409 conflict message), i18n en+de, panel split to
  stay under the 500-line rule
- tests: middleware service + route suites (incl. TOCTOU regression for
  the single-flight slot), component tests for the install flow

Enabler for #294 (Sign in with ChatGPT / codex device auth); extends #309.
@Weegy
Weegy merged commit 71f03f4 into main Aug 21, 2026
9 checks passed
@Weegy
Weegy deleted the feat/cli-runtime-install branch August 21, 2026 06:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant