Skip to content

feat(dev): re-sync installed dev hosts on epoch swap behind the stable proxy (#179 stage 2) - #343

Merged
ScriptedAlchemy merged 1 commit into
mainfrom
feat/179-s2-host-sync
Sep 3, 2026
Merged

feat(dev): re-sync installed dev hosts on epoch swap behind the stable proxy (#179 stage 2)#343
ScriptedAlchemy merged 1 commit into
mainfrom
feat/179-s2-host-sync

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Summary

Stage 2 of #179: agent-bundle dev --install-host <claude|codex|cursor> (repeatable) installs the developed plugin into real hosts as a marked DEV VARIANT and re-syncs skills/hooks/mcp-apps/manifests into the installed locations on every successful epoch swap — hosts pick up changes without reinstall. Hooks are spawned per event, so they adopt the new epoch on the next event; the MCP surface stays live through the stage-1 proxy (#339).

  • Dev install: first successful epoch installs through the ordinary installBundle path (real claude/codex plugin CLIs, Cursor copy), with the MCP document rewritten to the stable proxy command and a .agent-bundle-dev.json marker (schemaVersion 1, projectRoot, host, epochId).
  • Stable, host-spawnable proxy command (single seam dev/dev-proxy-command.ts): process.execPath + the framework's own resolved CLI entry (package-root walk → declared bin → existence check; no PATH assumption) + dev proxy --root <project> --server <name> --target <host>. Never rewritten to an epoch path on swap (byte-identical mcp document pinned in tests).
  • Re-sync on artifact.available: each epoch copies into an immutable generation under .agent-bundle-dev/generations/<epochId>; top-level directories switch by atomic symlink (junction on Windows) rename, top-level files by atomic sibling rename — a host never reads a torn tree (the first swap after install renames the real directory aside before the pointer lands). Failed publish rolls back to the previous generation and emits AB7202 on a new epoch-scoped dev.host.sync project event; failed builds emit nothing (last-good stays). Generations pruned to {current, previous}.
  • Claude/Codex re-sync writes the host-owned cache directly — no host CLI invocation per epoch (pinned: command-runner call count unchanged across a swap).
  • Workbench wire mirror updated (log-client.ts devLogKinds) so dev.host.sync / dev.host.sync.diagnostic frames don't hard-fail the Logs page with AB8093; project SSE is unaffected (named events, no listener).
  • Shutdown leaves the dev install in place: skills/hooks remain, and the proxy fails closed (AB8025) until that project's dev server runs again.

Tests

tests/dev-host-install.test.ts (integration pool + test:host-install script):

  • Cursor (unconditional): dev-variant layout + marker; epoch swap re-points skills/hooks atomically; mcp document byte-identical; failed build → no change; failed re-sync → previous generation restored + AB7202 event; generation pruning to {current, previous}.
  • Real DevCoordinator + EpochStore end-to-end: skill + hook edits propagate into the isolated Cursor install after a real rebuild; broken source leaves the install and marker untouched.
  • Claude / Codex (binary-gated, honest skips): real host-CLI install into isolated homes, then a re-sync into the host-owned cache with zero further host CLI calls, marker advanced, skills/hooks changed, mcp document unchanged.
  • Spawn proofs (all three hosts): the exact emitted command/args spawn with no dev server running and fail closed with exit 1 + [AB8025] — proving a real host could spawn it without PATH assumptions.
  • packages/workbench/tests/log-client.test.ts covers the new kinds.

Reviewer fix included: dev-host-install.test.ts was initially picked up by the "build-free, process-free" unit pool; it is now classified in integrationTestFiles and rides test:host-install.

Gates (local, rebased)

  • pnpm build / pnpm typecheck / pnpm lint (0/0) — pass
  • pnpm test:unit 2633 passed; only residue is the two known timing flakes under machine load (mcp-probe-service teardown, dispatcher deadline) — 34/34 in isolated rerun
  • pnpm test:route-unit 24/24 · pnpm test:projection 59/59
  • dev-host-install (integration config) 7/7 · pnpm test:host-install 16/16 with 0 skips (real claude + codex lanes executed)
  • workbench log-client 15/15

Part of #179 (stage 2 of 4). Changeset: minor.

@ScriptedAlchemy
ScriptedAlchemy merged commit 05f53c8 into main Sep 3, 2026
@changeset-bot

changeset-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 77ca3a9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
agent-bundle Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-03T00:24:09.759504Z 77ca3a9 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

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