@bastani/atomic 0.5.17 → 0.5.18-0

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 (26) hide show
  1. package/README.md +14 -1
  2. package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts +50 -54
  3. package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts.map +1 -1
  4. package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts +17 -36
  5. package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts.map +1 -1
  6. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/heuristic.d.ts +1 -1
  7. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts +64 -44
  8. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts.map +1 -1
  9. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scratch.d.ts +43 -0
  10. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scratch.d.ts.map +1 -0
  11. package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts +17 -39
  12. package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts.map +1 -1
  13. package/package.json +1 -1
  14. package/src/cli.ts +21 -2
  15. package/src/commands/cli/session.test.ts +223 -0
  16. package/src/commands/cli/session.ts +117 -1
  17. package/src/completions/bash.ts +3 -3
  18. package/src/completions/fish.ts +13 -7
  19. package/src/completions/powershell.ts +3 -0
  20. package/src/completions/zsh.ts +2 -1
  21. package/src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts +260 -157
  22. package/src/sdk/workflows/builtin/deep-research-codebase/copilot/index.ts +224 -125
  23. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/heuristic.ts +2 -2
  24. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.ts +428 -469
  25. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/scratch.ts +115 -0
  26. package/src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts +249 -137
package/README.md CHANGED
@@ -220,6 +220,12 @@ atomic session connect <session-name>
220
220
 
221
221
  # Interactive session picker (fuzzy-search)
222
222
  atomic session connect
223
+
224
+ # Kill a session by name (prompts for confirmation)
225
+ atomic session kill <session-name>
226
+
227
+ # Kill all sessions in scope (prompts for confirmation)
228
+ atomic session kill
223
229
  ```
224
230
 
225
231
  Session names follow a predictable pattern:
@@ -979,6 +985,7 @@ During `atomic chat`, there is no Atomic-owned TUI — `atomic chat -a <agent>`
979
985
  | `atomic workflow list` | List available workflows, grouped by source |
980
986
  | `atomic session list` | List all running sessions on the atomic tmux socket |
981
987
  | `atomic session connect [name]` | Attach to a session (interactive picker when no name given) |
988
+ | `atomic session kill [name]` | Kill a session by name, or all sessions when no name is given |
982
989
  | `atomic completions <shell>` | Output shell completion script (bash, zsh, fish, powershell) |
983
990
  | `atomic config set <k> <v>` | Set configuration values (currently supports `telemetry`) |
984
991
 
@@ -1000,12 +1007,15 @@ The `session` command is available at three levels — scoped or global:
1000
1007
  | ---------------------------------------- | ----------------------------------------------------- |
1001
1008
  | `atomic session list` | List all running sessions |
1002
1009
  | `atomic session connect [name]` | Attach to a session (interactive picker when no name) |
1010
+ | `atomic session kill [name]` | Kill a session, or all sessions when no name is given |
1003
1011
  | `atomic chat session list` | List running chat sessions only |
1004
1012
  | `atomic chat session connect [name]` | Attach to a chat session |
1013
+ | `atomic chat session kill [name]` | Kill a chat session, or all chat sessions |
1005
1014
  | `atomic workflow session list` | List running workflow sessions only |
1006
1015
  | `atomic workflow session connect [name]` | Attach to a workflow session |
1016
+ | `atomic workflow session kill [name]` | Kill a workflow session, or all workflow sessions |
1007
1017
 
1008
- Both `list` and `connect` accept `-a <agent>` (repeatable) to filter by agent backend.
1018
+ `list`, `connect`, and `kill` all accept `-a <agent>` (repeatable) to filter by agent backend. `kill` prompts for confirmation before terminating sessions.
1009
1019
 
1010
1020
  ```bash
1011
1021
  atomic session list # All sessions
@@ -1013,6 +1023,9 @@ atomic session list -a claude # Only Claude sessions
1013
1023
  atomic session connect my-session # Attach by name
1014
1024
  atomic session connect # Interactive picker
1015
1025
  atomic chat session list -a copilot # Chat sessions for Copilot only
1026
+ atomic session kill my-session # Kill one session by name
1027
+ atomic session kill # Kill all sessions (with confirmation)
1028
+ atomic workflow session kill -a claude # Kill all Claude workflow sessions
1016
1029
  ```
1017
1030
 
1018
1031
  #### `atomic chat` Flags
@@ -1,64 +1,60 @@
1
1
  /**
2
2
  * deep-research-codebase / claude
3
3
  *
4
- * A deterministically-orchestrated, distributed version of the
5
- * `research-codebase` skill. The research-codebase skill spawns
6
- * codebase-locator / codebase-analyzer / codebase-pattern-finder /
7
- * codebase-research-locator / codebase-research-analyzer /
8
- * codebase-online-researcher sub-agents on the fly via LLM judgment;
9
- * this workflow spawns the same agents on a deterministic schedule
10
- * driven by the codebase's lines of code.
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.
12
+ *
13
+ * Why SDK primitives instead of in-prompt orchestration:
14
+ *
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.
19
+ *
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.
24
+ *
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.
28
+ *
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.
11
32
  *
12
33
  * Topology:
13
34
  *
14
- * ┌─→ codebase-scout
35
+ * ┌─→ codebase-scout (visible)
15
36
  * parent ─┤
16
- * └─→ research-history
17
- *
18
- *
19
- * ┌──────────────────────────────────────────────────┐
20
- * │ explorer-1 explorer-2 ... explorer-N │ (Promise.all, headless)
21
- * └──────────────────────────────────────────────────┘
22
- *
23
- *
24
- * aggregator
25
- *
26
- * Explorers run headless (in-process, no tmux window) — they are transparent
27
- * to the graph, so the visible topology is: [scout, history] → aggregator.
28
- *
29
- * Stage 1a — codebase-scout
30
- * Pure-TypeScript: lists files (git ls-files), counts LOC (batched wc -l),
31
- * renders a depth-bounded ASCII tree, and bin-packs directories into N
32
- * partitions where N is determined by the LOC heuristic. Then makes one
33
- * short LLM call to produce an architectural orientation that primes the
34
- * downstream explorers. Returns structured data via `handle.result` and
35
- * the agent's prose via `ctx.transcript(handle)`.
36
- *
37
- * Stage 1b — research-history (parallel sibling of scout)
38
- * Dispatches the codebase-research-locator and codebase-research-analyzer
39
- * sub-agents over the project's existing research/ directory to surface
40
- * prior decisions, completed investigations, and unresolved questions.
41
- * Output is consumed via session transcript (≤400 words) and feeds into
42
- * the aggregator as supplementary context.
43
- *
44
- * Stage 2 — explorer-1..N (parallel; depends on scout + history)
45
- * Each explorer is a coordinator that dispatches specialized sub-agents
46
- * over its assigned partition (single LOC-balanced slice of the codebase):
47
- * - codebase-locator → finds relevant files in the partition
48
- * - codebase-analyzer → documents how the most relevant files work
49
- * - codebase-pattern-finder → finds existing pattern examples
50
- * - codebase-online-researcher → (conditional) external library docs
51
- * The explorer never reads files directly — it orchestrates specialists
52
- * and writes a synthesized findings document to a known scratch path.
53
- *
54
- * Stage 3 — aggregator
55
- * Reads each explorer's scratch file by path (file-based handoff to keep
56
- * the aggregator's own context lean — we deliberately do NOT inline N
57
- * transcripts into the prompt). Folds in the research-history overview
58
- * as supplementary context. Synthesizes a single research document at
59
- * research/docs/YYYY-MM-DD-<slug>.md.
60
- *
61
- * Context-engineering decisions are documented at each stage below.
37
+ * └─→ history-locator → history-analyzer (headless)
38
+ *
39
+ *
40
+ * ┌──────────────────────────────────────────────────────────────────────┐
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) │
50
+ * └──────────────────────────────────────────────────────────────────────┘
51
+ *
52
+ *
53
+ * aggregator (visible)
54
+ *
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
62
58
  */
63
59
  declare const _default: import("../../../index.ts").WorkflowDefinition<"claude", "prompt">;
64
60
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;;AA4BH,wBA4Na"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;;AAsCH,wBA6Ta"}
@@ -1,48 +1,29 @@
1
1
  /**
2
2
  * deep-research-codebase / copilot
3
3
  *
4
- * Copilot replica of the Claude deep-research-codebase workflow. The Claude
5
- * version dispatches specialist sub-agents (codebase-locator, codebase-
6
- * analyzer, etc.) inside a single explorer session via `@"name (agent)"`
7
- * syntax a Claude-specific feature. Copilot sessions are bound to a single
8
- * agent for their entire lifetime, so we keep the SAME graph topology
9
- * (scout ∥ history → explorer-1..N → aggregator) but drive each explorer
10
- * through the locate → analyze → patterns → synthesize sequence inline using
11
- * the default agent's built-in file tools.
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.
12
8
  *
13
- * Topology (identical to Claude version):
9
+ * Copilot-specific concerns baked in (see references/failure-modes.md):
14
10
  *
15
- * ┌─→ codebase-scout
16
- * parent ─┤
17
- * └─→ research-history
18
- * │
19
- * ▼
20
- * ┌──────────────────────────────────────────────────┐
21
- * │ explorer-1 explorer-2 ... explorer-N │ (Promise.all, headless)
22
- * └──────────────────────────────────────────────────┘
23
- * │
24
- * ▼
25
- * aggregator
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.
26
14
  *
27
- * Explorers run headless (in-process, no tmux window) they are transparent
28
- * to the graph, so the visible topology is: [scout, history] → aggregator.
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`.
29
19
  *
30
- * Copilot-specific concerns baked in:
20
+ * F6 every prompt explicitly requires trailing prose AFTER any tool
21
+ * call so `getAssistantText()` and downstream `transcript()` reads are
22
+ * never empty.
31
23
  *
24
+ * • F9 — `s.save()` receives `SessionEvent[]` from `s.session.getMessages()`.
32
25
  *
33
- * F5 — every `ctx.stage()` call is a FRESH session with no memory of prior
34
- * stages. We forward the scout overview, history overview, and partition
35
- * assignment explicitly into each explorer's first prompt. The aggregator
36
- * gets the same plus the explorer scratch file paths.
37
- *
38
- * • F9 — `s.save()` receives `SessionEvent[]` via `s.session.getMessages()`
39
- * (Copilot's correct shape). Passing anything else breaks downstream
40
- * `transcript()` reads.
41
- *
42
- * • F6 — every prompt explicitly requires trailing prose AFTER any tool
43
- * call, so `transcript()` is never empty. A Copilot turn whose final
44
- * message is a tool call produces an empty assistant.message terminator
45
- * (F1); trailing prose is our insurance.
26
+ * See claude/index.ts for the full design rationale and topology diagram.
46
27
  */
47
28
  declare const _default: import("../../../index.ts").WorkflowDefinition<"copilot", "prompt">;
48
29
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/copilot/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;;AAuBH,wBAiMa"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/copilot/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;AA6CH,wBAiSa"}
@@ -2,7 +2,7 @@
2
2
  * Determine how many parallel explorer sub-agents to spawn for the
3
3
  * deep-research-codebase workflow, based on lines of code in the codebase.
4
4
  *
5
- * Scales linearly: one explorer per `LOC_PER_EXPLORER` (2.5K) lines of code,
5
+ * Scales linearly: one explorer per `LOC_PER_EXPLORER` (5K) lines of code,
6
6
  * with a floor of 2 for tiny or empty codebases. The actual number of
7
7
  * spawned explorers is still bounded by the number of partition units
8
8
  * the scout finds (see `partitionUnits` in ./scout.ts), so we never get
@@ -1,20 +1,40 @@
1
1
  /**
2
2
  * Prompt builders for the deep-research-codebase workflow.
3
3
  *
4
+ * Each builder produces a focused, single-responsibility prompt for one
5
+ * specialist sub-agent. The sub-agents themselves are dispatched as separate
6
+ * `ctx.stage(...)` calls via the provider SDK's native `agent` parameter
7
+ * (Claude SDK options, Copilot sessionOpts, OpenCode session.prompt). Because
8
+ * each sub-agent already carries a detailed system prompt in `.claude/agents/`,
9
+ * `.opencode/agents/`, and `.github/agents/`, these user-prompts are intentionally
10
+ * short — they only supply the topic, the scope, and the output shape the
11
+ * downstream synthesizer expects.
12
+ *
4
13
  * Context-engineering principles applied throughout:
5
- * - Position-aware placement: the research question is repeated at the
6
- * TOP and BOTTOM of every prompt (recall is 85-95% at the edges and
7
- * drops to 76-82% in the middle see context-fundamentals).
8
- * - Informativity over exhaustiveness: each explorer prompt contains
9
- * only that explorer's partition, never the full file list.
10
- * - Explicit trailing commentary (F6): every prompt asks the agent to
11
- * produce a short text summary AFTER any tool/file output, so the
12
- * transcript is not empty when downstream stages read it.
13
- * - File-based handoff (filesystem-context skill): explorer findings
14
- * are written to disk and the aggregator reads them by path, instead
15
- * of inlining N transcripts into the aggregator's prompt.
16
- * - Documentarian role: every prompt explicitly forbids critique or
17
- * improvement suggestions; we are recording what exists.
14
+ *
15
+ * Position-aware framing: the research question is repeated at the TOP
16
+ * and BOTTOM of every prompt. Long-context recall is strongest at the
17
+ * edges of the context window (see `context-fundamentals`).
18
+ *
19
+ * Informativity over exhaustiveness: each per-partition prompt embeds
20
+ * ONLY that partition's directories never the full file list. This
21
+ * keeps token cost roughly constant in N rather than O(N²).
22
+ *
23
+ * Forward-only data flow: the analyzer prompt embeds the locator's
24
+ * output verbatim; the online-researcher prompt does the same. No
25
+ * sub-agent has to re-discover what its sibling already produced.
26
+ *
27
+ * • Trailing-prose guarantee (failure-modes F6): every prompt asks for a
28
+ * short prose recap as the final assistant turn so downstream stages
29
+ * reading via `transcript()` never get an empty string when the agent
30
+ * ends on a tool call.
31
+ *
32
+ * • Documentarian framing: every prompt explicitly forbids critique or
33
+ * improvement suggestions. We are recording what EXISTS.
34
+ *
35
+ * • File-based handoff (filesystem-context skill): explorer findings are
36
+ * written deterministically to a scratch file by TypeScript (no extra
37
+ * LLM "synthesizer" stage) and the aggregator reads them by path.
18
38
  */
19
39
  import type { PartitionUnit } from "./scout.ts";
20
40
  /** Slugify the user's prompt for use in the final research filename. */
@@ -27,52 +47,52 @@ export declare function buildScoutPrompt(opts: {
27
47
  explorerCount: number;
28
48
  partitionPreview: PartitionUnit[][];
29
49
  }): string;
30
- export declare function buildExplorerPrompt(opts: {
50
+ /** codebase-locator find files in the partition relevant to the question. */
51
+ export declare function buildLocatorPrompt(opts: {
31
52
  question: string;
53
+ partition: PartitionUnit[];
54
+ root: string;
55
+ scoutOverview: string;
32
56
  index: number;
33
57
  total: number;
58
+ }): string;
59
+ /** codebase-pattern-finder — surface concrete reusable code patterns. */
60
+ export declare function buildPatternFinderPrompt(opts: {
61
+ question: string;
34
62
  partition: PartitionUnit[];
35
- scoutOverview: string;
36
- scratchPath: string;
37
63
  root: string;
64
+ scoutOverview: string;
65
+ index: number;
66
+ total: number;
38
67
  }): string;
39
- /**
40
- * The research-history scout dispatches specialized sub-agents to surface
41
- * historical context from the project's `research/` directory:
42
- * - codebase-research-locator → finds prior research docs about the topic
43
- * - codebase-research-analyzer → extracts key insights from the most
44
- * relevant docs
45
- *
46
- * Output is consumed via session transcript (not file write) — kept short
47
- * (≤400 words) so the aggregator can embed it cheaply.
48
- */
49
- export declare function buildHistoryPrompt(opts: {
68
+ /** codebase-analyzer — document HOW the most relevant impl files work. */
69
+ export declare function buildAnalyzerPrompt(opts: {
50
70
  question: string;
71
+ partition: PartitionUnit[];
72
+ locatorOutput: string;
51
73
  root: string;
74
+ scoutOverview: string;
75
+ index: number;
76
+ total: number;
52
77
  }): string;
53
- /**
54
- * Generic explorer prompt (Copilot / OpenCode). Drives a single default-agent
55
- * session through the locate → analyze → patterns → synthesize sequence using
56
- * built-in tools directly, instead of Claude's sub-agent dispatch.
57
- */
58
- export declare function buildExplorerPromptGeneric(opts: {
78
+ /** codebase-online-researcher — focused external doc fetch when libs are central. */
79
+ export declare function buildOnlineResearcherPrompt(opts: {
59
80
  question: string;
81
+ partition: PartitionUnit[];
82
+ locatorOutput: string;
83
+ root: string;
60
84
  index: number;
61
85
  total: number;
62
- partition: PartitionUnit[];
63
- scoutOverview: string;
64
- historyOverview: string;
65
- scratchPath: string;
86
+ }): string;
87
+ /** codebase-research-locator — find prior research docs about the topic. */
88
+ export declare function buildHistoryLocatorPrompt(opts: {
89
+ question: string;
66
90
  root: string;
67
91
  }): string;
68
- /**
69
- * Generic research-history prompt (Copilot / OpenCode). A single default-agent
70
- * session searches the project's research/ directory using its own file tools,
71
- * instead of dispatching Claude's codebase-research-locator / analyzer
72
- * sub-agents.
73
- */
74
- export declare function buildHistoryPromptGeneric(opts: {
92
+ /** codebase-research-analyzer — synthesize insights from located research docs. */
93
+ export declare function buildHistoryAnalyzerPrompt(opts: {
75
94
  question: string;
95
+ locatorOutput: string;
76
96
  root: string;
77
97
  }): string;
78
98
  export declare function buildAggregatorPrompt(opts: {
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhD,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAUpD;AAMD,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,CA2DT;AAMD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAwKT;AAMD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAkET;AAkBD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAgLT;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAoET;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,CA6IT"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAYhD,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAUpD;AA6BD,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,IAAI,EAAE,MAAM,CAAC;IACb,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,IAAI,EAAE,MAAM,CAAC;IACb,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,IAAI,EAAE,MAAM,CAAC;IACb,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,IAAI,EAAE,MAAM,CAAC;IACb,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;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAsDT;AAED,mFAAmF;AACnF,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Deterministic synthesis of per-partition explorer scratch files.
3
+ *
4
+ * Each partition is investigated by four specialist sub-agents dispatched
5
+ * directly via the provider SDK's `agent` parameter:
6
+ *
7
+ * - codebase-locator → file index for the partition
8
+ * - codebase-pattern-finder → reusable code patterns in the partition
9
+ * - codebase-analyzer → how the most relevant impl files work
10
+ * - codebase-online-researcher → external library docs (when central)
11
+ *
12
+ * Rather than spawn a fifth "synthesizer" LLM stage just to concatenate four
13
+ * markdown sections, we do that synthesis in plain TypeScript here. This keeps
14
+ * the per-partition cost at exactly four LLM calls and avoids burning tokens
15
+ * on a step whose output is fully determined by its inputs.
16
+ *
17
+ * The file we write is the canonical handoff to the aggregator — it MUST keep
18
+ * the heading shape that buildAggregatorPrompt() promises ("Scope / Files in
19
+ * Scope / How It Works / Patterns / External References / Out-of-Partition
20
+ * References"), or the aggregator will look for sections that don't exist.
21
+ */
22
+ import type { PartitionUnit } from "./scout.ts";
23
+ export type ExplorerSections = {
24
+ index: number;
25
+ total: number;
26
+ partition: PartitionUnit[];
27
+ /** Full assistant text from the codebase-locator sub-agent. */
28
+ locatorOutput: string;
29
+ /** Full assistant text from the codebase-pattern-finder sub-agent. */
30
+ patternsOutput: string;
31
+ /** Full assistant text from the codebase-analyzer sub-agent. */
32
+ analyzerOutput: string;
33
+ /** Full assistant text from the codebase-online-researcher sub-agent. */
34
+ onlineOutput: string;
35
+ };
36
+ /** Render the markdown body deterministically. */
37
+ export declare function renderExplorerMarkdown(sections: ExplorerSections): string;
38
+ /**
39
+ * Write a partition's deterministic scratch file. Returns the absolute path so
40
+ * the caller can record it in the explorer manifest the aggregator reads.
41
+ */
42
+ export declare function writeExplorerScratchFile(scratchPath: string, sections: ExplorerSections): Promise<string>;
43
+ //# sourceMappingURL=scratch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scratch.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/helpers/scratch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,cAAc,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAOF,kDAAkD;AAClD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAsDzE;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,MAAM,CAAC,CAKjB"}
@@ -1,51 +1,29 @@
1
1
  /**
2
2
  * deep-research-codebase / opencode
3
3
  *
4
- * OpenCode replica of the Claude deep-research-codebase workflow. The Claude
5
- * version dispatches specialist sub-agents (codebase-locator, codebase-
6
- * analyzer, etc.) inside a single explorer session via `@"name (agent)"`
7
- * syntax a Claude-specific feature. OpenCode sessions are bound to a
8
- * single agent for their lifetime, so we keep the SAME graph topology
9
- * (scout ∥ history → explorer-1..N → aggregator) but drive each explorer
10
- * through the locate → analyze → patterns → synthesize sequence inline using
11
- * the default agent's built-in file tools.
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.
12
8
  *
13
- * Topology (identical to Claude version):
9
+ * OpenCode-specific concerns baked in (see references/failure-modes.md):
14
10
  *
15
- * ┌─→ codebase-scout
16
- * parent ─┤
17
- * └─→ research-history
18
- * │
19
- * ▼
20
- * ┌──────────────────────────────────────────────────┐
21
- * │ explorer-1 explorer-2 ... explorer-N │ (Promise.all, headless)
22
- * └──────────────────────────────────────────────────┘
23
- * │
24
- * ▼
25
- * aggregator
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.
26
14
  *
27
- * Explorers run headless (in-process, no tmux window) — they are transparent
28
- * to the graph, so the visible topology is: [scout, history] → aggregator.
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.
29
18
  *
30
- * OpenCode-specific concerns baked in:
19
+ * F6 every prompt explicitly requires trailing prose so transcripts and
20
+ * `extractResponseText()` reads are never empty.
31
21
  *
32
- * F5every `ctx.stage()` call is a FRESH session with no memory of
33
- * prior stages. We forward the scout overview, history overview, and
34
- * partition assignment explicitly into each explorer's first prompt.
22
+ * 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.
35
25
  *
36
- * F9 — `s.save()` receives the `{ info, parts }` payload from
37
- * `s.client.session.prompt()` via `result.data!`. Passing the full
38
- * `result` (with its wrapping) or raw `result.data.parts` breaks
39
- * downstream `transcript()` reads.
40
- *
41
- * • F6 — every prompt explicitly requires trailing prose AFTER any tool
42
- * call so the rendered transcript has content. OpenCode's `parts` array
43
- * mixes text/tool/reasoning/file parts; without trailing text the
44
- * transcript extractor returns an empty string.
45
- *
46
- * • F3 — transcript extraction relies on the runtime's text-only rendering
47
- * of `result.data.parts`. The helpers call `ctx.transcript(handle)` which
48
- * returns `{ path, content }` where content is already text-filtered.
26
+ * See claude/index.ts for the full design rationale and topology diagram.
49
27
  */
50
28
  declare const _default: import("../../../index.ts").WorkflowDefinition<"opencode", "prompt">;
51
29
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;;AAuBH,wBA6Na"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;AAsCH,wBAoVa"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/atomic",
3
- "version": "0.5.17",
3
+ "version": "0.5.18-0",
4
4
  "description": "Configuration management CLI and SDK for coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/cli.ts CHANGED
@@ -13,6 +13,7 @@
13
13
  * atomic workflow session connect <id> Attach to a session
14
14
  * atomic session list List all running sessions
15
15
  * atomic session connect [id] Interactive session picker
16
+ * atomic session kill [id] Kill a session (or all when no id)
16
17
  * atomic config set <key> <value> Set configuration value
17
18
  * atomic --version Show version
18
19
  * atomic --help Show help
@@ -77,6 +78,22 @@ function addSessionSubcommand(parent: Command, scope: "chat" | "workflow" | "all
77
78
  }
78
79
  });
79
80
 
81
+ sessionCmd
82
+ .command("kill")
83
+ .description("Kill a running session (omit id to kill all)")
84
+ .argument("[session_id]", "Session name to kill (omit to kill all)")
85
+ .option(
86
+ "-a, --agent <name>",
87
+ `Filter by agent backend (${Object.keys(AGENT_CONFIG).join(", ")}); repeatable`,
88
+ collectAgent,
89
+ [] as string[],
90
+ )
91
+ .action(async (sessionId, localOpts) => {
92
+ const { sessionKillCommand } = await import("./commands/cli/session.ts");
93
+ const exitCode = await sessionKillCommand(sessionId, localOpts.agent, scope);
94
+ process.exit(exitCode);
95
+ });
96
+
80
97
  return sessionCmd;
81
98
  }
82
99
 
@@ -131,7 +148,8 @@ Examples:
131
148
  $ atomic chat -a opencode Start OpenCode interactively
132
149
  $ atomic chat -a claude "fix the bug" Claude with initial prompt
133
150
  $ atomic chat session list List running sessions
134
- $ atomic chat session connect <id> Attach to a session`,
151
+ $ atomic chat session connect <id> Attach to a session
152
+ $ atomic chat session kill [id] Kill a chat session (or all)`,
135
153
  )
136
154
  .action(async (localOpts, cmd) => {
137
155
  const validAgents = Object.keys(AGENT_CONFIG);
@@ -201,7 +219,8 @@ Examples:
201
219
  $ atomic workflow -n gen-spec -a claude --research_doc=notes.md --focus=standard
202
220
  Run a structured-input workflow
203
221
  $ atomic workflow session list List running sessions
204
- $ atomic workflow session connect <id> Attach to a session`,
222
+ $ atomic workflow session connect <id> Attach to a session
223
+ $ atomic workflow session kill [id] Kill a workflow session (or all)`,
205
224
  )
206
225
  .action(async (localOpts, cmd) => {
207
226
  const { workflowCommand } = await import("./commands/cli/workflow.ts");