@bastani/atomic 0.6.3 → 0.6.4-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.
- package/.agents/skills/ast-grep/SKILL.md +323 -0
- package/.agents/skills/ast-grep/references/rule_reference.md +297 -0
- package/.agents/skills/ripgrep/SKILL.md +382 -0
- package/.mcp.json +5 -6
- package/dist/commands/cli/claude-inflight-hook.d.ts +100 -0
- package/dist/commands/cli/claude-inflight-hook.d.ts.map +1 -0
- package/dist/commands/cli/claude-stop-hook.d.ts +2 -0
- package/dist/commands/cli/claude-stop-hook.d.ts.map +1 -1
- package/dist/lib/spawn.d.ts +1 -1
- package/dist/lib/spawn.d.ts.map +1 -1
- package/dist/sdk/providers/claude.d.ts +36 -0
- package/dist/sdk/providers/claude.d.ts.map +1 -1
- package/dist/sdk/providers/copilot.d.ts +17 -1
- package/dist/sdk/providers/copilot.d.ts.map +1 -1
- package/dist/sdk/runtime/executor.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts +49 -34
- package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts +18 -16
- package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/batching.d.ts +43 -0
- package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/batching.d.ts.map +1 -0
- package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts +30 -0
- package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scout.d.ts +2 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scout.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts +18 -16
- package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts.map +1 -1
- package/dist/services/config/additional-instructions.d.ts +67 -0
- package/dist/services/config/additional-instructions.d.ts.map +1 -0
- package/package.json +3 -1
- package/src/cli.ts +18 -1
- package/src/commands/cli/chat/index.ts +52 -2
- package/src/commands/cli/claude-inflight-hook.test.ts +598 -0
- package/src/commands/cli/claude-inflight-hook.ts +359 -0
- package/src/commands/cli/claude-stop-hook.ts +40 -4
- package/src/commands/cli/init/index.ts +9 -0
- package/src/lib/spawn.ts +6 -2
- package/src/sdk/providers/claude.ts +131 -0
- package/src/sdk/providers/copilot.ts +30 -1
- package/src/sdk/runtime/executor.ts +43 -2
- package/src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts +318 -158
- package/src/sdk/workflows/builtin/deep-research-codebase/copilot/index.ts +253 -129
- package/src/sdk/workflows/builtin/deep-research-codebase/helpers/batching.ts +65 -0
- package/src/sdk/workflows/builtin/deep-research-codebase/helpers/ignore-by-default.d.ts +8 -0
- package/src/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.ts +203 -12
- package/src/sdk/workflows/builtin/deep-research-codebase/helpers/scout.ts +248 -78
- package/src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts +258 -146
- package/src/services/config/additional-instructions.ts +273 -0
- 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;
|
|
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
|
|
6
|
-
* (codebase-locator / codebase-pattern-finder / codebase-analyzer
|
|
7
|
-
* codebase-online-researcher
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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
|
|
14
|
+
* Why batched Task-tool dispatch instead of one ctx.stage per specialist:
|
|
14
15
|
*
|
|
15
|
-
* •
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
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
|
-
* •
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
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
|
-
* •
|
|
26
|
-
*
|
|
27
|
-
*
|
|
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
|
|
30
|
-
*
|
|
31
|
-
* just
|
|
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
|
-
* │
|
|
42
|
-
* │
|
|
43
|
-
* │
|
|
44
|
-
* │
|
|
45
|
-
* │
|
|
46
|
-
* │
|
|
47
|
-
* │ │
|
|
48
|
-
* │
|
|
49
|
-
* │
|
|
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
|
-
*
|
|
56
|
-
*
|
|
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
|
|
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
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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
|
-
*
|
|
11
|
+
* See claude/index.ts for the full design rationale and topology diagram.
|
|
10
12
|
*
|
|
11
|
-
*
|
|
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.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
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
|
-
* •
|
|
21
|
-
*
|
|
22
|
-
*
|
|
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
|
-
* •
|
|
25
|
+
* • F6 — orchestrator prompt requires a single-line tally as the trailing
|
|
26
|
+
* turn so transcripts are never empty.
|
|
25
27
|
*
|
|
26
|
-
*
|
|
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
|
|
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;
|
|
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,
|
|
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
|
|
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
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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
|
-
* •
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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
|
-
* •
|
|
16
|
-
*
|
|
17
|
-
* concatenating raw `parts` produces `[object Object]` strings.
|
|
21
|
+
* • F5 — every `ctx.stage()` is a FRESH session. Batch session prompts
|
|
22
|
+
* embed everything the orchestrator needs in the first turn.
|
|
18
23
|
*
|
|
19
|
-
* • F6 —
|
|
20
|
-
*
|
|
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
|
|
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
|
|
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
|
+
"version": "0.6.4-0",
|
|
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
|
-
|
|
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);
|