@bastani/atomic 0.6.3 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/.agents/skills/ast-grep/SKILL.md +323 -0
  2. package/.agents/skills/ast-grep/references/rule_reference.md +297 -0
  3. package/.agents/skills/ripgrep/SKILL.md +382 -0
  4. package/.mcp.json +5 -6
  5. package/dist/commands/cli/claude-inflight-hook.d.ts +100 -0
  6. package/dist/commands/cli/claude-inflight-hook.d.ts.map +1 -0
  7. package/dist/commands/cli/claude-stop-hook.d.ts +2 -0
  8. package/dist/commands/cli/claude-stop-hook.d.ts.map +1 -1
  9. package/dist/lib/spawn.d.ts +1 -1
  10. package/dist/lib/spawn.d.ts.map +1 -1
  11. package/dist/sdk/providers/claude.d.ts +36 -0
  12. package/dist/sdk/providers/claude.d.ts.map +1 -1
  13. package/dist/sdk/providers/copilot.d.ts +17 -1
  14. package/dist/sdk/providers/copilot.d.ts.map +1 -1
  15. package/dist/sdk/runtime/executor.d.ts.map +1 -1
  16. package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts +49 -34
  17. package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts.map +1 -1
  18. package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts +18 -16
  19. package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts.map +1 -1
  20. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/batching.d.ts +43 -0
  21. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/batching.d.ts.map +1 -0
  22. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts +30 -0
  23. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts.map +1 -1
  24. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scout.d.ts +2 -1
  25. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scout.d.ts.map +1 -1
  26. package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts +18 -16
  27. package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts.map +1 -1
  28. package/dist/services/config/additional-instructions.d.ts +67 -0
  29. package/dist/services/config/additional-instructions.d.ts.map +1 -0
  30. package/package.json +3 -1
  31. package/src/cli.ts +18 -1
  32. package/src/commands/cli/chat/index.ts +52 -2
  33. package/src/commands/cli/claude-inflight-hook.test.ts +598 -0
  34. package/src/commands/cli/claude-inflight-hook.ts +359 -0
  35. package/src/commands/cli/claude-stop-hook.ts +40 -4
  36. package/src/commands/cli/init/index.ts +9 -0
  37. package/src/lib/spawn.ts +6 -2
  38. package/src/sdk/providers/claude.ts +131 -0
  39. package/src/sdk/providers/copilot.ts +30 -1
  40. package/src/sdk/runtime/executor.ts +43 -2
  41. package/src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts +318 -158
  42. package/src/sdk/workflows/builtin/deep-research-codebase/copilot/index.ts +253 -129
  43. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/batching.ts +65 -0
  44. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/ignore-by-default.d.ts +8 -0
  45. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.ts +203 -12
  46. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/scout.ts +248 -78
  47. package/src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts +258 -146
  48. package/src/services/config/additional-instructions.ts +273 -0
  49. package/src/services/system/auto-sync.ts +10 -1
@@ -1 +1 @@
1
- {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/sdk/runtime/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,KAAK,EACV,kBAAkB,EAElB,aAAa,EAKb,SAAS,EAET,YAAY,EAEZ,kBAAkB,EAInB,MAAM,aAAa,CAAC;AAwErB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAa5C,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,iBAAiB;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAoDD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,SAAS,CAgB1D;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,IAAI,OAAO,CAKtD;AAyBD;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAMhD;AAuFD;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAKzC;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAMzC;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,GAAG,SAAS,GACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,MAAM,EAAE,SAAS,aAAa,EAAE,GAC/B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAejC;AAMD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAmFf;AAoDD,gGAAgG;AAChG,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAOvE;AA2OD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,CA0CrE;AAOD;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACjF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAClC,OAAO,EAAE,yBAAyB,EAClC,UAAU,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GACrC,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAuB5B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CAC5D;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,EACvC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAChC,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,EAAE,CACA,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GAC3C,MAAM,IAAI,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAChC,MAAM,IAAI,CA0BZ;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAChC,MAAM,IAAI,CAwBZ;AAsFD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,EAAE,GACf,MAAM,EAAE,CAMV;AAED,KAAK,4BAA4B,GAAG,IAAI,CACtC,kBAAkB,CAAC,SAAS,CAAC,EAC7B,aAAa,GAAG,iBAAiB,CAClC,CAAC;AAEF,UAAU,sBAAsB;IAC9B,aAAa,EAAE,4BAA4B,CAAC;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,aAAa,EAAE,kBAAkB,CAAC,SAAS,CAAC,EAC5C,kBAAkB,CAAC,EAAE,MAAM,GAC1B,sBAAsB,CAsBxB;AAomBD;;;;;;;;;GASG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAG5D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,KAAK,kBAAkB,GAAG,SAAS,GAC1E,OAAO,CAAC,OAAO,CAAC,CAmBlB;AAED,wBAAsB,eAAe,CACnC,UAAU,EAAE,kBAAkB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAgKf"}
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/sdk/runtime/executor.ts"],"names":[],"mappings":"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"}
@@ -2,33 +2,44 @@
2
2
  * deep-research-codebase / claude
3
3
  *
4
4
  * A deterministically-orchestrated, distributed codebase researcher built on
5
- * the Claude Agent SDK's native sub-agent dispatch. Specialist sub-agents
6
- * (codebase-locator / codebase-pattern-finder / codebase-analyzer /
7
- * codebase-online-researcher / codebase-research-locator /
8
- * codebase-research-analyzer) are spawned as separate headless `ctx.stage()`
9
- * calls each binds the SDK's `agent` option to the desired specialist
10
- * instead of relying on a coordinator agent that dispatches them via the
11
- * `@"name (agent)"` prompt syntax.
5
+ * the Claude Agent SDK with **batched** Task-tool fan-out. Specialist
6
+ * sub-agents (codebase-locator / codebase-pattern-finder / codebase-analyzer
7
+ * / codebase-online-researcher) run inside batch sessions: each batch is a
8
+ * single `ctx.stage()` whose orchestrator turn dispatches up to
9
+ * MAX_TASKS_PER_BATCH (≈10) specialists in parallel via the Task tool.
10
+ * Research-history specialists (codebase-research-locator /
11
+ * codebase-research-analyzer) remain as their own small pipeline since they
12
+ * have a strict sequential dependency and run only twice per workflow.
12
13
  *
13
- * Why SDK primitives instead of in-prompt orchestration:
14
+ * Why batched Task-tool dispatch instead of one ctx.stage per specialist:
14
15
  *
15
- * • Each specialist runs in an ISOLATED conversation. The locator's giant
16
- * file index doesn't pollute the analyzer's context window, and the
17
- * online-researcher doesn't see the analyzer's reasoning at all. This is
18
- * `multi-agent-patterns` swarm-style isolation, not orchestrator-style.
16
+ * • SDK-level fan-out scales by codebase size at 5K LOC per partition
17
+ * and 4 specialists per partition, a 750K-LOC codebase would otherwise
18
+ * spawn 600 `claude` subprocesses. Batches of 10 cap that at ~60 SDK
19
+ * sessions, with each session internally fanning out via Task tool.
19
20
  *
20
- * • There is no orchestrator turn whose context grows linearly with the
21
- * number of specialists. Token cost per partition is bounded by the four
22
- * specialists' independent prompts adding more partitions scales
23
- * cleanly because every fan-out is a fresh session.
21
+ * • ~10 parallel Task tool sub-agents per single message is the practical
22
+ * ceiling before rate limits, context contention, and degraded
23
+ * coordination kick in (no documented hard cap; tunable in
24
+ * helpers/batching.ts).
24
25
  *
25
- * • Failure of one specialist does not abort the partition mid-thought
26
- * the runtime fails the stage, but its siblings' outputs are still on
27
- * disk and the aggregator can continue with whatever completed.
26
+ * • Sub-agents still run in ISOLATED contexts Task tool gives every
27
+ * sub-agent its own conversation window, so the locator's file index
28
+ * doesn't pollute the analyzer the way it would inside a shared
29
+ * conversation. (multi-agent-patterns swarm isolation.)
28
30
  *
29
- * • The synthesis step that combines specialist outputs is plain TypeScript
30
- * (`renderExplorerMarkdown` in helpers/scratch.ts) no extra LLM call
31
- * just to concatenate four markdown sections.
31
+ * • The orchestrator's turn does NOT grow linearly with sub-agent count:
32
+ * each Task sub-agent writes its verbatim findings to a per-task scratch
33
+ * file and returns just "DONE", so the orchestrator collects N short
34
+ * confirmations rather than N transcripts (filesystem-context skill).
35
+ *
36
+ * • Failure isolation is preserved at two levels: (1) Promise.allSettled
37
+ * around the batches means one failed batch doesn't abort siblings;
38
+ * (2) inside a batch, the orchestrator is instructed not to retry
39
+ * failed Task sub-agents — the synthesis step tolerates missing files.
40
+ *
41
+ * • Synthesis remains plain TypeScript (`renderExplorerMarkdown` in
42
+ * helpers/scratch.ts) — no extra LLM call just to concatenate sections.
32
43
  *
33
44
  * Topology:
34
45
  *
@@ -38,23 +49,27 @@
38
49
  * │
39
50
  * ▼
40
51
  * ┌──────────────────────────────────────────────────────────────────────┐
41
- * │ Per-partition (Promise.all over partitions, all stages headless):
42
- * │
43
- * │ locator-i ∥ pattern-finder-i (Layer 1, parallel)
44
- * │
45
- * │
46
- * │ analyzer-i ∥ online-researcher-i (Layer 2, parallel)
47
- * │ │
48
- * │
49
- * │ deterministic write to scratch file (TS helper, no LLM)
52
+ * │ Wave 1 (locator + pattern-finder, no inter-deps):
53
+ * │ wave1-batch-1 ∥ wave1-batch-2 ∥ ... (Promise.allSettled)
54
+ * │ └── each batch session: orchestrator dispatches ≤10 Task
55
+ * │ sub-agents in one assistant message; each writes to disk
56
+ * │
57
+ * │
58
+ * │ TS reads locator-i.md files from disk for Layer 2 prompts
59
+ * │
60
+ * │
61
+ * │ Wave 2 (analyzer + online-researcher, embed locator output): │
62
+ * │ wave2-batch-1 ∥ wave2-batch-2 ∥ ... (Promise.allSettled) │
63
+ * │ │ │
64
+ * │ ▼ │
65
+ * │ Per partition i: TS reads 4 specialist files + writes explorer-i.md │
50
66
  * └──────────────────────────────────────────────────────────────────────┘
51
67
  * │
52
68
  * ▼
53
69
  * aggregator (visible)
54
70
  *
55
- * Specialist stages run headless (in-process via the Agent SDK's `query()`),
56
- * so they are transparent to the workflow graph. The visible nodes are just:
57
- * parent → [codebase-scout] → aggregator
71
+ * Batch sessions are headless (transparent to the workflow graph). Visible
72
+ * nodes: parent [codebase-scout] aggregator.
58
73
  */
59
74
  declare const _default: import("../../../index.ts").WorkflowDefinition<"claude", readonly [{
60
75
  readonly name: "prompt";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;;;;;;;AAsCH,wBAwTa"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEG;;;;;;;AAuFH,wBAwZa"}
@@ -1,29 +1,31 @@
1
1
  /**
2
2
  * deep-research-codebase / copilot
3
3
  *
4
- * Copilot replica of the Claude deep-research-codebase workflow. Specialist
5
- * sub-agents are dispatched as separate headless `ctx.stage()` calls — each
6
- * binds the SDK's session to a single named agent via `sessionOpts: { agent }`,
7
- * which is the SDK-native way to spawn a sub-agent on Copilot.
4
+ * Copilot replica of the Claude deep-research-codebase workflow with the
5
+ * same **batched** Task-tool fan-out. Specialist sub-agents run inside batch
6
+ * sessions: each batch is a single `ctx.stage()` whose orchestrator turn
7
+ * dispatches up to MAX_TASKS_PER_BATCH (≈10) specialists in parallel via
8
+ * Copilot's `agent` tool (alias `Task`, see Copilot subagents docs).
9
+ * Research-history specialists remain as their own sequential sub-pipeline.
8
10
  *
9
- * Copilot-specific concerns baked in (see references/failure-modes.md):
11
+ * See claude/index.ts for the full design rationale and topology diagram.
10
12
  *
11
- * F5 every `ctx.stage()` is a FRESH session. Each specialist receives
12
- * everything it needs (research question, scope, scout overview, and —
13
- * for layer-2 specialists — verbatim locator output) in its first prompt.
13
+ * Copilot-specific concerns baked in (see references/failure-modes.md):
14
14
  *
15
15
  * • F1 — Copilot's last assistant turn is often empty when the agent ends
16
- * on a tool call. We use `getAssistantText()` (canonical concatenation
17
- * of every top-level non-empty assistant turn, ignoring sub-agent
18
- * `parentToolCallId` traffic) instead of `.at(-1).data.content`.
16
+ * on a tool call. Batch sessions don't read `getAssistantText` for the
17
+ * orchestrator output (sub-agents write to disk; the orchestrator's text
18
+ * reply is just a short tally), so this is no longer load-bearing for
19
+ * Stage 2 — but the history pipeline still depends on it.
19
20
  *
20
- * • F6 — every prompt explicitly requires trailing prose AFTER any tool
21
- * call so `getAssistantText()` and downstream `transcript()` reads are
22
- * never empty.
21
+ * • F5 — every `ctx.stage()` is a FRESH session. Batch session prompts
22
+ * embed everything the orchestrator needs (per-task subagent_type,
23
+ * output path, and verbatim specialist prompt) in the first turn.
23
24
  *
24
- * • F9`s.save()` receives `SessionEvent[]` from `s.session.getMessages()`.
25
+ * • F6orchestrator prompt requires a single-line tally as the trailing
26
+ * turn so transcripts are never empty.
25
27
  *
26
- * See claude/index.ts for the full design rationale and topology diagram.
28
+ * F9 — `s.save()` receives `SessionEvent[]` from `s.session.getMessages()`.
27
29
  */
28
30
  declare const _default: import("../../../index.ts").WorkflowDefinition<"copilot", readonly [{
29
31
  readonly name: "prompt";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/copilot/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;;;;;AA6CH,wBA4Ra"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/copilot/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;;;;;;;AAiFH,wBAkXa"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Batching primitives for the deep-research-codebase workflow.
3
+ *
4
+ * The workflow caps SDK-level fan-out by grouping specialist invocations into
5
+ * "batch sessions" — one `ctx.stage()` per batch. Inside each batch session,
6
+ * the default Claude Code agent dispatches up to MAX_TASKS_PER_BATCH
7
+ * sub-agents in parallel via the Task tool. This keeps the parallel SDK
8
+ * subprocess count proportional to (specialists / 10) rather than to
9
+ * specialists itself, which scales linearly with codebase size.
10
+ *
11
+ * The per-message Task fan-out cap is empirical: there's no documented hard
12
+ * limit, but ~10 parallel sub-agents per single message is the reliable
13
+ * ceiling before rate limits, context contention, and degraded coordination
14
+ * kick in. Lower this if you see batch sessions stalling or returning
15
+ * partial completions; raise it only after measuring.
16
+ */
17
+ import type { PartitionUnit } from "./scout.ts";
18
+ /** Maximum Task-tool sub-agent dispatches per single batch session. */
19
+ export declare const MAX_TASKS_PER_BATCH = 10;
20
+ /** Specialist kinds that share Layer 1 (no inter-task dependencies). */
21
+ export type Layer1Kind = "locator" | "pattern-finder";
22
+ /** Specialist kinds that share Layer 2 (depend on Layer 1 locator output). */
23
+ export type Layer2Kind = "analyzer" | "online-researcher";
24
+ /** Maps a specialist kind to the Claude agent name it dispatches as. */
25
+ export declare const SUBAGENT_TYPE: Record<Layer1Kind | Layer2Kind, string>;
26
+ export type Layer1Task = {
27
+ kind: Layer1Kind;
28
+ partitionIndex: number;
29
+ partition: PartitionUnit[];
30
+ /** Absolute path the sub-agent must write its verbatim findings to. */
31
+ outputPath: string;
32
+ };
33
+ export type Layer2Task = {
34
+ kind: Layer2Kind;
35
+ partitionIndex: number;
36
+ partition: PartitionUnit[];
37
+ outputPath: string;
38
+ /** Verbatim locator text for this partition, embedded into the prompt. */
39
+ locatorOutput: string;
40
+ };
41
+ /** Split a flat task list into fixed-size chunks (last chunk may be smaller). */
42
+ export declare function chunkBatches<T>(items: T[], size?: number): T[][];
43
+ //# sourceMappingURL=batching.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batching.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/helpers/batching.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,wEAAwE;AACxE,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,gBAAgB,CAAC;AAEtD,8EAA8E;AAC9E,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,mBAAmB,CAAC;AAE1D,wEAAwE;AACxE,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,UAAU,GAAG,UAAU,EAAE,MAAM,CAKjE,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,UAAU,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,UAAU,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,CAAC,EAC5B,KAAK,EAAE,CAAC,EAAE,EACV,IAAI,GAAE,MAA4B,GACjC,CAAC,EAAE,EAAE,CAOP"}
@@ -103,4 +103,34 @@ export declare function buildAggregatorPrompt(opts: {
103
103
  scoutOverview: string;
104
104
  historyOverview: string;
105
105
  }): string;
106
+ /**
107
+ * Wrap a specialist prompt with the "write to file, reply with token only"
108
+ * envelope. The envelope is what the orchestrator hands to the Task tool's
109
+ * `prompt` parameter — the inner specialist prompt is built by the existing
110
+ * `buildLocatorPrompt` / `buildPatternFinderPrompt` / etc. and embedded
111
+ * verbatim so prompt semantics stay identical to the unbatched workflow.
112
+ */
113
+ export declare function wrapPromptForTaskDispatch(opts: {
114
+ specialistPrompt: string;
115
+ outputPath: string;
116
+ agentLabel: string;
117
+ }): string;
118
+ /**
119
+ * Build the orchestrator prompt for a batch session. The orchestrator's job
120
+ * is purely deterministic dispatch — fire one Task tool call per task in
121
+ * **a single assistant message** so they execute in parallel, then report a
122
+ * one-line tally. It must NOT inline sub-agent findings, paraphrase the
123
+ * embedded prompts, or retry failures — siblings still run and synthesis
124
+ * tolerates missing files.
125
+ */
126
+ export declare function buildBatchOrchestratorPrompt(opts: {
127
+ wave: 1 | 2;
128
+ batchIndex: number;
129
+ totalBatches: number;
130
+ tasks: Array<{
131
+ subagentType: string;
132
+ prompt: string;
133
+ outputPath: string;
134
+ }>;
135
+ }): string;
106
136
  //# sourceMappingURL=prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAYhD,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAUpD;AAqBD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,aAAa,EAAE,EAAE,CAAC;CACrC,GAAG,MAAM,CAyDT;AAeD,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,CAuET;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,CAwDT;AAED,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,CA0FT;AAED,qFAAqF;AACrF,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,CA2ET;AAMD,4EAA4E;AAC5E,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC9C,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAoDT;AAED,mFAAmF;AACnF,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAuDT;AAMD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE;QACb,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,aAAa,EAAE,CAAC;KAC5B,EAAE,CAAC;IACJ,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB,GAAG,MAAM,CAwIT"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Responsibilities:
5
5
  * 1. Discover the codebase root (git toplevel, falling back to cwd).
6
- * 2. List all source files, respecting .gitignore when in a git repo.
6
+ * 2. List all source files, honoring `.gitignore` via git ls-files in repos
7
+ * and via `rg --files` in non-repo directories that still have one.
7
8
  * 3. Count lines of code per file using batched `wc -l`.
8
9
  * 4. Render a compact directory tree (depth-bounded) for prompt context.
9
10
  * 5. Build "partition units" by aggregating LOC at depth-1, then drilling
@@ -1 +1 @@
1
- {"version":3,"file":"scout.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/helpers/scout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA+BH,2BAA2B;AAC3B,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB,CAAC;AAEF,yEAAyE;AACzE,wBAAgB,eAAe,IAAI,MAAM,CAUxC;AAmMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAiBzD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,EAAE,EACtB,KAAK,EAAE,MAAM,GACZ,aAAa,EAAE,EAAE,CAwBnB"}
1
+ {"version":3,"file":"scout.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/helpers/scout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA4JH,2BAA2B;AAC3B,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB,CAAC;AAEF,yEAAyE;AACzE,wBAAgB,eAAe,IAAI,MAAM,CAexC;AA0OD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAiBzD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,EAAE,EACtB,KAAK,EAAE,MAAM,GACZ,aAAa,EAAE,EAAE,CAwBnB"}
@@ -1,29 +1,31 @@
1
1
  /**
2
2
  * deep-research-codebase / opencode
3
3
  *
4
- * OpenCode replica of the Claude deep-research-codebase workflow. Specialist
5
- * sub-agents are dispatched as separate headless `ctx.stage()` calls — each
6
- * call passes `agent: "<name>"` to `s.client.session.prompt()` directly,
7
- * which is OpenCode's SDK-native way to route a turn to a sub-agent.
4
+ * OpenCode replica of the Claude deep-research-codebase workflow with the
5
+ * same **batched** Task-tool fan-out. Specialist sub-agents run inside batch
6
+ * sessions: each batch is a single `ctx.stage()` whose orchestrator turn
7
+ * dispatches up to MAX_TASKS_PER_BATCH (≈10) specialists in parallel via
8
+ * OpenCode's `task` tool. The default agent must have `task: "allow"` in
9
+ * its permission ruleset (see `.opencode/agents/worker.md` for the
10
+ * canonical example).
11
+ *
12
+ * See claude/index.ts for the full design rationale and topology diagram.
8
13
  *
9
14
  * OpenCode-specific concerns baked in (see references/failure-modes.md):
10
15
  *
11
- * • F5every `ctx.stage()` is a FRESH session. Each specialist receives
12
- * everything it needs (research question, scope, scout overview, and —
13
- * for layer-2 specialists verbatim locator output) in its first prompt.
16
+ * • F3 — `result.data!.parts` is heterogenous. Batch sessions don't read
17
+ * `extractResponseText` for orchestrator output (sub-agents write to
18
+ * disk; the orchestrator reply is just a short tally), but the history
19
+ * pipeline still uses it.
14
20
  *
15
- * • F3 — `result.data!.parts` is a heterogenous array (text/tool/reasoning/
16
- * file parts). Use `extractResponseText()` to filter to text parts only;
17
- * concatenating raw `parts` produces `[object Object]` strings.
21
+ * • F5every `ctx.stage()` is a FRESH session. Batch session prompts
22
+ * embed everything the orchestrator needs in the first turn.
18
23
  *
19
- * • F6 — every prompt explicitly requires trailing prose so transcripts and
20
- * `extractResponseText()` reads are never empty.
24
+ * • F6 — orchestrator prompt requires a single-line tally as the trailing
25
+ * turn so transcripts are never empty.
21
26
  *
22
27
  * • F9 — `s.save()` receives the unwrapped `{ info, parts }` payload from
23
- * `result.data!`; passing the full `result` or raw `result.data!.parts`
24
- * breaks downstream `transcript()` reads.
25
- *
26
- * See claude/index.ts for the full design rationale and topology diagram.
28
+ * `result.data!`.
27
29
  */
28
30
  declare const _default: import("../../../index.ts").WorkflowDefinition<"opencode", readonly [{
29
31
  readonly name: "prompt";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;;;;;AAsCH,wBA8Ua"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;;;;;;;AAwEH,wBA0Za"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Default seed contents for `~/.atomic/AGENTS.md`. Markdown-format because
3
+ * Copilot CLI / OpenCode read instruction files as Markdown; Claude's
4
+ * `--append-system-prompt-file` accepts arbitrary text and is happy with
5
+ * Markdown too.
6
+ */
7
+ export declare const ADDITIONAL_INSTRUCTIONS = "This section provides you with **CRITICAL** instructions that will help you to maintain coherency in long-horizon context-heavy tasks and better support users:\n\n<user_experience>\n- Always ask clarifying questions if the user's request is ambiguous or lacks necessary details. NEVER make assumptions about what the user wants.\n- If you find yourself circling in thought and asking what the user \"really\" wants, stop and ask the user for clarification. It's better to ask than to guess.\n</user_experience>\n\n<tool_policies>\nFollow these tool selection and usage rules in order of priority:\n\n1. **Browser search and automation**:\n\nUse playwright-cli (refer to playwright-cli skill) for ALL browser automation tasks, including web research, form filling, and UI interaction:\n - ALWAYS load the playwright-cli skill before usage with the Skill tool.\n - ALWAYS ASSUME playwright-cli is installed. If the `playwright-cli` command fails, fall back to `bunx playwright-cli`.\n\n2. **Structural code search**:\n\nYou are operating in an environment where ast-grep is installed. For any code search that requires understanding of syntax or code structure, you should default to using `ast-grep --lang [language] -p '<pattern>'`. Rely on your ast-grep skill for best practices. Adjust the --lang flag as needed for the specific programming language. Avoid using text-only search tools unless a plain-text search is explicitly requested.\n\n3. **Testing**: ALWAYS invoke your test-driven-development skill BEFORE creating or modifying any tests.\n\n4. **Sub-agent Orchestration**: You have a large number of tools available to you. The most important one is the one that allows you to dispatch sub-agents: either `Agent` or `Task`.\n\nAll non-trivial operations should be delegated to sub-agents. You should delegate research and codebase understanding tasks to codebase-analyzer, codebase-locator and codebase-pattern-locator sub-agents.\n\nYou should delegate running bash commands (particularly ones that are likely to produce lots of output) such as investigating with the `aws` CLI, using the `gh` CLI, digging through logs to `Bash` sub-agents.\n\nYou should use separate sub-agents for separate tasks, and you may launch them in parallel - but do not delegate multiple tasks that are likely to have significant overlap to separate sub-agents.\n\nIMPORTANT: if the user has already given you a task, you should proceed with that task using this approach.\nIMPORTANT: sometimes sub-agents will take a long time. DO NOT attempt to do the job yourself while waiting for the sub-agent to respond. Instead, use the time to plan out your next steps, or ask the user follow-up questions to clarify the task requirements.\n\nIf you have not already been explicitly given a task, you should ask the user what task they would like for you to work on - do not assume or begin working on a ticket automatically.\n\n5. **Debugging**: When a user asks about debugging, ALWAYS spawn a debugger sub-agent first.\n - Do not attempt to debug or analyze code yourself without first consulting the debugger sub-agent.\n - Explain the debugger's insights to the user clearly and concisely.\n - Once the user confirms, implement the necessary code changes based on those insights.\n - If the user has follow-up questions, spawn additional debugger and research sub-agents as needed.\n</tool_policies>\n\n<engineering_principles>\nSoftware engineering is fundamentally about **managing complexity** to prevent technical debt. When implementing features, prioritize maintainability and testability over cleverness.\n\n**Core Principles:**\n- **Single Responsibility (SRP):** Every class and module must have exactly one reason to change. If a unit does more than one job, split it.\n- **Dependency Inversion (DIP):** Depend on abstractions (interfaces), never on concrete implementations. Inject dependencies; do not instantiate them internally.\n- **KISS:** Keep solutions as simple as possible. Reject unnecessary abstraction layers.\n- **YAGNI:** Do not build generic frameworks or add configurability for hypothetical future requirements. Solve the problem at hand.\n\n**Design Patterns** \u2014 Use Gang of Four patterns as a shared vocabulary for recurring problems:\n- **Creational:** Use _Factory_ or _Builder_ to abstract complex object creation and isolate construction logic.\n- **Structural:** Use _Adapter_ or _Facade_ to decouple core logic from external APIs or legacy code.\n- **Behavioral:** Use _Strategy_ to make algorithms interchangeable. Use _Observer_ for event-driven communication between decoupled components.\n\n**Architectural Hygiene:**\n- **Separation of Concerns:** Isolate business logic (Domain) from infrastructure (Database, UI, networking). Never let infrastructure details leak into domain code.\n- **Anti-Pattern Detection:** Watch for **God Objects** (classes with too many responsibilities) and **Spaghetti Code** (tightly coupled, hard-to-follow control flow). Refactor them using polymorphism and clear interfaces.\n\nCreate **seams** in your software using interfaces and abstractions. This ensures code remains flexible, testable, and capable of evolving independently.\n</engineering_principles>\n";
8
+ /** Path to the global seed: `~/.atomic/AGENTS.md`. */
9
+ export declare function getGlobalAdditionalInstructionsPath(): string;
10
+ /** Path to the per-project override: `<projectRoot>/.atomic/AGENTS.md`. */
11
+ export declare function getLocalAdditionalInstructionsPath(projectRoot: string): string;
12
+ /**
13
+ * Resolve the effective additional-instructions file for a project.
14
+ *
15
+ * Returns the project-local override if it exists, otherwise the global
16
+ * seed. Returns `undefined` only if neither exists — which can happen on a
17
+ * fresh dev checkout that hasn't yet run `autoSyncIfStale` (the seed write).
18
+ *
19
+ * Sync `existsSync` is intentional: this is called on every spawn and we
20
+ * want the cost to be a single `stat` per provider, not an `await`.
21
+ */
22
+ export declare function resolveAdditionalInstructionsPath(projectRoot: string): string | undefined;
23
+ /**
24
+ * Read the resolved file's contents, or `undefined` if no file exists.
25
+ * Used by SDK paths that need the raw string (Claude `systemPrompt.append`,
26
+ * Copilot `systemMessage.content`).
27
+ */
28
+ export declare function resolveAdditionalInstructionsContent(projectRoot: string): Promise<string | undefined>;
29
+ /**
30
+ * Write `~/.atomic/AGENTS.md` with {@link ADDITIONAL_INSTRUCTIONS} if (and
31
+ * only if) the file is missing. Idempotent and safe to call on every CLI
32
+ * start; the user is free to edit the file afterward without atomic
33
+ * clobbering their changes on upgrade.
34
+ */
35
+ export declare function seedGlobalAdditionalInstructions(): Promise<void>;
36
+ /**
37
+ * Ensure the resolved `AGENTS.md` is wired into
38
+ * `<projectRoot>/.opencode/opencode.json`'s `instructions` array.
39
+ *
40
+ * OpenCode (CLI and SDK alike) consumes the `instructions` field from
41
+ * project config; there's no flag or env var that injects an instruction
42
+ * file. Strategy:
43
+ * - Resolve the effective path via {@link resolveAdditionalInstructionsPath}.
44
+ * - Strip any prior atomic-managed entries (matches `.atomic/AGENTS.md`).
45
+ * - Append the absolute resolved path. Absolute is fine because OpenCode
46
+ * happily takes them; we don't expect the user to commit this entry
47
+ * across machines (and even if they do, the next run reconciles it).
48
+ * - When nothing resolves (file truly missing on this machine), we still
49
+ * run the cleanup pass so a previously-seeded entry doesn't leak.
50
+ *
51
+ * No-op on `.opencode/opencode.json` files we don't own (i.e. we never
52
+ * create the file ourselves; `applyManagedOnboardingFiles` is responsible
53
+ * for that). When the file is absent, this helper simply returns.
54
+ *
55
+ * Concurrency: this is a read-modify-write on `opencode.json` with no
56
+ * cross-process lock. Two concurrent `atomic` invocations (e.g. parallel
57
+ * `chat -a opencode` sessions, or a workflow racing the chat startup) can
58
+ * interleave reads and writes — A reads, B reads, A writes, B writes —
59
+ * and B's write loses any user-managed `instructions` entries A added in
60
+ * between. The window is tiny (a single `readFile` + `JSON.parse` +
61
+ * `writeFile`) and the damage is bounded: only concurrent edits to
62
+ * non-atomic entries are at risk, and the next reconcile pass restores
63
+ * the atomic entry. If this becomes a real problem in practice, wrap the
64
+ * read-modify-write in a file lock (`proper-lockfile` or similar).
65
+ */
66
+ export declare function reconcileOpencodeInstructions(projectRoot: string): Promise<void>;
67
+ //# sourceMappingURL=additional-instructions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"additional-instructions.d.ts","sourceRoot":"","sources":["../../../src/services/config/additional-instructions.ts"],"names":[],"mappings":"AAsBA;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,2nKA8DnC,CAAC;AAUF,sDAAsD;AACtD,wBAAgB,mCAAmC,IAAI,MAAM,CAE5D;AAED,2EAA2E;AAC3E,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,MAAM,GAClB,MAAM,CAER;AAED;;;;;;;;;GASG;AACH,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CAMpB;AAED;;;;GAIG;AACH,wBAAsB,oCAAoC,CACxD,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS7B;AAED;;;;;GAKG;AACH,wBAAsB,gCAAgC,IAAI,OAAO,CAAC,IAAI,CAAC,CAKtE;AAuCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,6BAA6B,CACjD,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAwCf"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/atomic",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "Configuration management CLI and SDK for coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -85,6 +85,8 @@
85
85
  "@opentui/react": "0.1.102",
86
86
  "commander": "^14.0.3",
87
87
  "ignore": "^7.0.5",
88
+ "ignore-by-default": "^2.1.0",
89
+ "linguist-languages": "^9.3.2",
88
90
  "yaml": "^2.8.3",
89
91
  "zod": "^4.3.6"
90
92
  },
package/src/cli.ts CHANGED
@@ -297,6 +297,22 @@ Examples:
297
297
  process.exit(exitCode);
298
298
  });
299
299
 
300
+ // ── Internal: Claude Subagent / TeammateIdle lifecycle hook handler ───
301
+ program
302
+ .command("_claude-inflight-hook", { hidden: true })
303
+ .description("Internal: Claude Code Subagent/TeammateIdle lifecycle hook handler — touches/removes inflight markers, or waits for them to drain")
304
+ .argument("<mode>", "start (SubagentStart), stop (SubagentStop), or wait (TeammateIdle)")
305
+ .action(async (mode: string) => {
306
+ if (mode !== "start" && mode !== "stop" && mode !== "wait") {
307
+ // Silent exit-0 to match the handler's contract — never red
308
+ // hook errors in transcripts.
309
+ process.exit(0);
310
+ }
311
+ const { claudeInflightHookCommand } = await import("./commands/cli/claude-inflight-hook.ts");
312
+ const exitCode = await claudeInflightHookCommand(mode);
313
+ process.exit(exitCode);
314
+ });
315
+
300
316
  // ── Completions command ────────────────────────────────────────────────
301
317
  program
302
318
  .command("completions")
@@ -373,7 +389,8 @@ async function main(): Promise<void> {
373
389
  argv[0] === "_footer" ||
374
390
  argv[0] === "_claude-stop-hook" ||
375
391
  argv[0] === "_claude-ask-hook" ||
376
- argv[0] === "_claude-session-start-hook";
392
+ argv[0] === "_claude-session-start-hook" ||
393
+ argv[0] === "_claude-inflight-hook";
377
394
 
378
395
  if (!isInfoCommand) {
379
396
  const { autoSyncIfStale } = await import(
@@ -16,6 +16,10 @@ import { mkdir, writeFile, rm } from "node:fs/promises";
16
16
  import { AGENT_CONFIG, type AgentKey } from "../../../services/config/index.ts";
17
17
  import { getProviderOverrides } from "../../../services/config/atomic-config.ts";
18
18
  import { getCopilotScmDisableFlags } from "../../../services/config/scm-sync.ts";
19
+ import {
20
+ resolveAdditionalInstructionsPath,
21
+ } from "../../../services/config/additional-instructions.ts";
22
+ import { dirname } from "node:path";
19
23
  import { ensureProjectSetup } from "../init/index.ts";
20
24
  import { COLORS } from "../../../theme/colors.ts";
21
25
  import { isCommandInstalled } from "../../../services/system/detect.ts";
@@ -88,7 +92,32 @@ export async function buildAgentArgs(
88
92
  const scmFlags =
89
93
  agentType === "copilot" ? await getCopilotScmDisableFlags(projectRoot) : [];
90
94
 
91
- return [...flags, ...scmFlags, ...passthroughArgs];
95
+ // Claude Code is the only one with a flag that takes an instructions file.
96
+ // OpenCode and Copilot CLI consume the file via config (.opencode/opencode.json
97
+ // `instructions` array) and env var (`COPILOT_CUSTOM_INSTRUCTIONS_DIRS`)
98
+ // respectively — see `applyManagedOnboardingFiles` and `chatCommand`'s env
99
+ // build. Skipped silently when no file resolves so the CLI still spawns
100
+ // even on a fresh checkout that hasn't run `autoSyncIfStale` yet.
101
+ const instructionsFlags: string[] = [];
102
+ if (agentType === "claude") {
103
+ const path = resolveAdditionalInstructionsPath(projectRoot);
104
+ if (path) instructionsFlags.push("--append-system-prompt-file", path);
105
+ }
106
+
107
+ return [...flags, ...scmFlags, ...instructionsFlags, ...passthroughArgs];
108
+ }
109
+
110
+ /**
111
+ * Directory containing the resolved additional-instructions `AGENTS.md`,
112
+ * or `undefined` if no file resolves. Used to set
113
+ * `COPILOT_CUSTOM_INSTRUCTIONS_DIRS` on Copilot spawns — Copilot loads
114
+ * `AGENTS.md` from each dir on that list.
115
+ */
116
+ export function getAdditionalInstructionsDir(
117
+ projectRoot: string,
118
+ ): string | undefined {
119
+ const path = resolveAdditionalInstructionsPath(projectRoot);
120
+ return path ? dirname(path) : undefined;
92
121
  }
93
122
 
94
123
  function generateChatId(): string {
@@ -213,12 +242,33 @@ export async function chatCommand(options: ChatCommandOptions = {}): Promise<num
213
242
  const overrides = await getProviderOverrides(agentType, projectRoot);
214
243
  // ATOMIC_AGENT must be baked into the launcher env so the agent CLI
215
244
  // and anything it spawns can read it from process start.
216
- const envVars = {
245
+ const envVars: Record<string, string> = {
217
246
  ...config.env_vars,
218
247
  ...overrides.envVars,
219
248
  ATOMIC_AGENT: agentType,
220
249
  };
221
250
 
251
+ // Copilot CLI loads `AGENTS.md` from any directory listed in
252
+ // `COPILOT_CUSTOM_INSTRUCTIONS_DIRS` (comma-separated). Point it at the
253
+ // resolved AGENTS.md's parent dir so our additional instructions get
254
+ // appended to the persona without touching the project's `AGENTS.md`.
255
+ // Skip dirs containing a comma — Copilot CLI has no documented escape
256
+ // syntax for the list separator, so a comma in the path (rare on POSIX,
257
+ // possible in Windows usernames) would be misparsed as a list boundary.
258
+ if (agentType === "copilot") {
259
+ const dir = getAdditionalInstructionsDir(projectRoot);
260
+ if (dir && dir.includes(",")) {
261
+ console.error(
262
+ `${COLORS.yellow}Warning: skipping COPILOT_CUSTOM_INSTRUCTIONS_DIRS entry because the path contains a comma, which Copilot CLI cannot escape: ${dir}${COLORS.reset}`,
263
+ );
264
+ } else if (dir) {
265
+ const existing = envVars.COPILOT_CUSTOM_INSTRUCTIONS_DIRS;
266
+ envVars.COPILOT_CUSTOM_INSTRUCTIONS_DIRS = existing
267
+ ? `${existing},${dir}`
268
+ : dir;
269
+ }
270
+ }
271
+
222
272
  // ── No TTY: tmux attach requires a real terminal ──
223
273
  if (!process.stdin.isTTY) {
224
274
  return spawnDirect(cmd, projectRoot, envVars);