feat: suit inject — realtime component injection (proposal + increment 1)#66
Merged
Conversation
This was referenced May 25, 2026
…arness home Reuses the suit up pipeline (composeBundle -> ProjectWriter -> lockfile) to materialize a single accessory/bundle's files across all four harness adapters into a target home, recorded under a new optional lockfile `injected:` list distinct from up's resolution/files. - composeBundle accepts outfit: null for outfit-less (inject) composition - idempotent re-inject + refuse-when-dirty, mirroring suit up - reloadDecision() pure fn: claude-code file-watched kinds -> not-required, mcp/plugin + other harnesses -> restart-required (conservative) - suit current surfaces injected components distinctly - --home / $CLAUDE_PROJECT_DIR / cwd home resolution; --target deferred (exits 2) NATS target discovery, the reload emit-side, and suit off injection-cleanup are later increments.
- idempotency now compares the computed injected lock-entries against the prior injected[] entry for the same component (order-insensitive path/sha/ mode) instead of an on-disk whole-file scan. Real accessories emit additive CLAUDE.md/AGENTS.md/GEMINI.md whose block-sha is stable across re-injects, so re-injecting an unchanged accessory now correctly reports 'unchanged'. - suit current accepts --project/--home <dir> (was hard-coded to cwd), so the injected list at an inject target home is inspectable. - regression tests: same-accessory-twice asserts no writes; additive-emitting accessory re-inject reports unchanged.
This was referenced May 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
suit inject— materialize a wardrobe component into a worker's harness home so it loads on the worker's next turn, no restart. Per operator direction this PR carries the proposal + working implementation (landing as tested increments), not a proposal alone. Branched work has been merged onto v0.15.0.Proposal
docs/proposals/2026-05-24-realtime-component-injection.md— CLI surface, conditional-reload model, lockfile-truthfulness contract, auth/trust model, failure-mode table, and the (a)–(f) slice plan. Open questions Q1–Q4 resolved per operator.Increment 1 (shipping here)
suit inject (--accessory|--bundle) <name> [--home <dir>] [--from <path>] [--dry-run] [--no-reload] [--force] [--json]suit uppipeline (composeBundle → ProjectWriter → lockfile), so a single accessory/bundle materializes across all four harnesses (claude-code/codex/gemini/pi) through the existing adapters — verified:philosophy→ 173 files.injected: []list (distinct fromup'sresolution/files); minimal-lockfile creation when the target has none. Back-compat: absent field parses unchanged.unchangedand writes nothing — compared via recorded lock-entries (additive files use the stable marker-block sha, soCLAUDE.md/AGENTS.md/GEMINI.mddon't defeat it).--force.reload: not-required | restart-required): claude-code file-watched kinds → not-required; mcp/plugin + codex/gemini/pi → restart-required (conservative). No NATS signal fired this increment.suit currentnow accepts--project/--home <dir>and surfaces injected components distinctly.--target <owner>/<session>is parsed but exits 2 ("not yet implemented: use --home") — NATS discovery is increment 2.Verification
npm run typecheck,npm run build,npm test→ 618 tests pass locally (mirrors ci.yml).injected(173 files); 2nd identical →unchanged;suit currentlists the injected component.Deferred to later increments (multi-session, per plan)
--skill/--hooksugar + NATS--targetdiscoveryinject.reloademit-side + queue-until-Stop (adapter-side; cross-repo)suit offinjection-cleanup