Skip to content

GitHub Connection panel: give amico[bot] a face in the Connections UI (Phase 2 of #399) #403

Description

@aarontrowbridge

Important

Problem

The amico[bot] identity (#399) shipped headless: the gh shim and git credential helper arm from ~/.amico/github.json, but that file must be hand-written. The built-in GitHub Connection slot in the Connections panel (CONTEXT.md glossary) is still unimplemented — configuring the bot means editing JSON by hand, with no validator, no status card, and no removal path.

Approach

Flesh out the built-in GitHub Connection in the Connections panel: a form (app_id, installation_id, PEM upload) that writes the exact #399 file contract, a validator that exercises the real mint path (JWT → GET /app, installation-token mint), a status card (connected / invalid / unconfigured-with-passthrough-note), and a remove path that returns the shims to byte-identical passthrough.

Approaches Considered

Scope

In: panel entry + credential-file writer, PEM stored 0600 beside the config, validator spawn (the pasqal validator pattern against the shipped node bundle), status card, remove path, hermetic tests.
Out: fleet propagation (Phase 3, follow-up issue) — per-machine config is out of this slice's reach. Out: keychain storage (deferred with the Approach note above). Out: webhooks/callbacks — the App stays credential-only. Out: automating Phase 0 — GitHub offers no headless App-creation API; the org-owner UI flow stays manual.

Assumptions / Open Qs

PEM lives at ~/.amico/github-app.pem (0600) with pem_path pointing at it. The validator executes the shipped CLI bundle (exact surface — a verb on amico vs a dedicated bin — is the dev's call, per Prior Art).


Acceptance Criteria

  1. Panel entry for the built-in GitHub connection collects app_id, installation_id, and a PEM file; Save writes ~/.amico/github.json + the 0600 PEM file matching the GitHub App identity: amico[bot] acts for Amicode on harmoniqs repos (token core + gh/git shims) #399 contract (amico-run's readGithubAppConfig accepts them; the shim arms on the next server spawn).
  2. Validator exercises the REAL mint path — JWT signature + GET /app for the App identity, installation-token mint for the installation — and the status card reports connected / invalid (actionable, token-free reason) / unconfigured (passthrough active).
  3. No secret is ever rendered: the PEM body and any minted token never appear in the webview, status cards, logs, or telemetry; errors are token-free by construction (the github_app.ts stance).
  4. Remove deletes both files → the shims return to byte-identical passthrough; status returns to unconfigured.
  5. Sandbox isolation honored end-to-end: the panel resolves the file via the same AMICO_GITHUB_FILE override already carried in SANDBOX_ENV_PASSTHROUGH — never a hardcoded path.
  6. Hermetic tests (fetch-seam fakes, no network — the pasqal_launch.test.ts pattern); typecheck + suites green.

Key Decisions

  • One contract, two frontends: the panel reads/writes the same ~/.amico/github.json the CLI reads — never a parallel store.
  • Validation routes through the shipped node bundle via spawn (the AMICO_PYTHON / pasqal_validate.py precedent), not a JWT-mint reimplementation in the extension host.
  • Status derivation is file-presence + on-demand live check (the Connections panel pattern) — never a background poller.
Prior Art / Patterns
  • packages/amico-run/src/github_app.ts — the file contract (readGithubAppConfig), the mint path (mintAppJwt, fetchInstallationToken, ensureInstallationToken), token-free ConfigErrors.
  • packages/extension/src/pasqal_assets.ts + pasqal_python.ts — validator resolution and spawn for a Connections-panel credential.
  • packages/amico-run/src/pasqal_devices.ts~/.amico/*.json + env-override config resolution.
  • packages/extension/src/server_auth.tsSANDBOX_ENV_PASSTHROUGH already carries AMICO_GITHUB_FILE / AMICO_GITHUB_TOKEN_FILE.
  • CONTEXT.md glossary — the built-in Connection entry (validator + brand icon + status vocabulary).

Source

Notes

Phase 0 (org App creation, installation, PEM download) is manual and stays manual. Phase 3 (fleet propagation) follows as its own issue.

Metadata

Metadata

Labels

area:nodearea:uihitlHuman-in-the-loop — needs human review/decision

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions