Skip to content

Codespace delivery mode: company-managed Codespace support - #1

Merged
jmenestr merged 15 commits into
mainfrom
codespace-support
Jun 24, 2026
Merged

jmenestr merged 15 commits into
mainfrom
codespace-support

Conversation

@jmenestr

Copy link
Copy Markdown
Owner

Brings the full GitHub Codespaces delivery mode to firstmate, rebased onto current main (includes kunchenguid#60/kunchenguid#61).

What's included

  • Codespace delivery adapter - registry-driven discovery, scout + ship support, lease-based robustness.
  • Cursor harness + configurable per-project codespace agent ([codespace owner/repo <harness>]).
  • Company-managed Codespace hardening - runnable-treehouse gate + source-build fallback (older glibc), harness command/PATH resolution (e.g. agent), guarded GitHub-token injection before fetch, and a per-task status mirror into local state for the perch dashboard.
  • Lease repo-dir fix - cd into the Codespace repo checkout before treehouse get/treehouse return.
  • New bin/fm-codespace-lib.sh (shared remote env prefix) + extended tests/fm-codespace.test.sh.

Validation

Full no-mistakes gate green: review / test / document / lint all passed clean; codespace + teardown test suites green; shellcheck + bash -n clean.

Verified end-to-end against a live company Codespace (transcend-io/main, Debian 11).

jmenestr added 15 commits June 23, 2026 17:07
Adds `[codespace]` as a fourth delivery mode in data/projects.md.
Crewmates SSH into the project's GitHub Codespace via `gh codespace ssh`,
run treehouse worktrees there, and write status to `~/firstmate-state/<id>.status`.
Firstmate supervises via a generated `state/<id>.check.sh` that polls the
remote status file at FM_CHECK_INTERVAL cadence.

Changes:
- fm-project-mode.sh: recognise codespace as a valid mode
- fm-spawn.sh: codespace spawn path (discover codespace, copy brief, SSH+treehouse+claude);
  mode resolution moved before window creation so codespace path can exit early
- fm-brief.sh: codespace case writes to ~/firstmate-state/<id>.status and mkdir-ps it first
- fm-teardown.sh: read codespace= from meta; remote dirty check when remote_worktree known;
  skip local fleet sync for codespace tasks
- AGENTS.md: codespace entry in delivery mode table
- README.md: document [codespace] registry format, discovery, FM_CODESPACE_REMOTE_STATE
- tests/fm-codespace.test.sh: 5 tests covering mode parsing and spawn check.sh generation
…d robustness

Complete the codespace delivery-mode adapter:

- No local clone: derive owner/repo from the [codespace owner/repo] registry
  line via `fm-project-mode.sh --slug`, not a clone's origin remote. A codespace
  project registers with no clone at all.
- Lease-based worktree: spawn polls for SSH-ready, then leases a worktree with
  `treehouse get --lease` (capturing its remote path) instead of fire-and-forget
  `sleep 8`s; the path is recorded in meta for teardown safety.
- Scout + codespace end to end: a codespace scout brief writes its report and
  status to the remote firstmate-state dir; teardown copies the report back over
  SSH and applies the report-exists contract regardless of mode.
- Teardown safety: ship teardown SSHes in and refuses on uncommitted/unpushed
  work; the worktree lease is released with `treehouse return`, and a failed
  return stops with state intact rather than leaking the lease.

tests/fm-codespace.test.sh covers slug parsing, lease-path capture in meta,
scout report-back, and the teardown checks.
Add cursor-agent as a verified harness adapter:
- launch_template cursor case (cursor-agent --force "$(cat brief)"); no
  turn-end hook (cursor has none), so supervision uses busy-signature +
  staleness + status writes
- fm-harness.sh detects cursor (CURSOR_INVOKED_AS env marker + command name)
- fm-watch.sh / fm-tmux-lib.sh busy regex add cursor's "ctrl+c to stop" footer
- AGENTS.md section 4 cursor table (busy/exit/interrupt/skill, quirks)

Make the codespace delivery path use a per-project configured harness:
- registry bracket gains an optional harness: [codespace owner/repo <harness>],
  default claude, parsed via fm-project-mode.sh --codespace-harness
- the codespace remote command launches the resolved harness (not hardcoded
  claude); meta and spawn summary record the real harness
- codespace spawn idempotently bootstraps prerequisites before leasing
  (remote state dir + treehouse install when missing); fails with the one-time
  install command when treehouse cannot be made available

Extend tests/fm-codespace.test.sh for harness parsing, configured-harness
launch, and the prerequisite bootstrap (success + actionable failure).
Make the codespace delivery mode work against an older base image with no
personal dotfiles, no non-interactive git auth, and a Cursor CLI installed
under a different name, and surface codespace status to perch.

- Gate on a treehouse that RUNS (treehouse --version), not just one on PATH;
  fall back to a go-install source build when the prebuilt binary crashes
  (e.g. GLIBC_2.34 on Debian 11 glibc 2.31).
- Source login profiles + force PATH on every remote command, and resolve the
  cursor binary (cursor-agent or plain 'agent') at launch time.
- Inject the Codespace GITHUB_TOKEN (guarded on the company secrets file) for
  both the lease and the launch so git fetch/push authenticate.
- Mirror new remote status lines into local state/<id>.status for perch,
  deduped via check.last and stdout-silent to avoid a double-wake or loop.

Extends tests/fm-codespace.test.sh to cover each fix; existing cases stay green.
The codespace lease ran 'treehouse get --lease' over 'gh codespace ssh',
which starts in the session HOME, not the repo checkout. 'treehouse get'
operates on the current git repo (git rev-parse --show-toplevel), so the
lease failed with 'not in a git repository'.

Prepend a cd into the codespace repo checkout (/workspaces/<repo-basename>,
derived from the owner/repo slug) before the lease. If that path is not a
git repo, fall back to the single git checkout under /workspaces/*; if none
is found, fail with an actionable error instead of treehouse's cryptic one.

Scoped to the lease step only: bootstrap, the launch (already cds into the
leased worktree), and teardown's lease-release are unchanged. Adds tests
asserting the lease cds into the derived checkout and exercising the
fallback resolution logic.
@jmenestr
jmenestr merged commit 6bb4141 into main Jun 24, 2026
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