@nghyane/arcane 0.1.8 → 0.1.10

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@nghyane/arcane",
4
- "version": "0.1.8",
4
+ "version": "0.1.10",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://github.com/nghyane/arcane",
7
7
  "author": "Can Bölük",
@@ -44,12 +44,12 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@mozilla/readability": "0.6.0",
47
- "@nghyane/arcane-stats": "^0.1.7",
48
- "@nghyane/arcane-agent": "^0.1.7",
49
- "@nghyane/arcane-codemode": "^0.1.7",
50
- "@nghyane/arcane-ai": "^0.1.7",
47
+ "@nghyane/arcane-stats": "^0.1.8",
48
+ "@nghyane/arcane-agent": "^0.1.8",
49
+ "@nghyane/arcane-codemode": "^0.1.9",
50
+ "@nghyane/arcane-ai": "^0.1.8",
51
51
  "@nghyane/arcane-natives": "^0.1.7",
52
- "@nghyane/arcane-tui": "^0.1.7",
52
+ "@nghyane/arcane-tui": "^0.1.8",
53
53
  "@nghyane/arcane-utils": "^0.1.6",
54
54
  "@sinclair/typebox": "^0.34.48",
55
55
  "@xterm/headless": "^6.0.0",
@@ -548,16 +548,6 @@ export const SETTINGS_SCHEMA = {
548
548
  submenu: true,
549
549
  },
550
550
  },
551
- "task.maxRecursionDepth": {
552
- type: "number",
553
- default: 2,
554
- ui: {
555
- tab: "tools",
556
- label: "Task max recursion depth",
557
- description: "How many levels deep subagents can spawn their own subagents",
558
- submenu: true,
559
- },
560
- },
561
551
  "task.disabledAgents": {
562
552
  type: "array",
563
553
  default: [] as string[],
@@ -232,12 +232,7 @@ export function parseAgentFields(frontmatter: Record<string, unknown>): ParsedAg
232
232
  return null;
233
233
  }
234
234
 
235
- let tools = parseArrayOrCSV(frontmatter.tools);
236
-
237
- // Subagents with output schema need submit_result to return structured data
238
- if (tools && frontmatter.output && !tools.includes("submit_result")) {
239
- tools = [...tools, "submit_result"];
240
- }
235
+ const tools = parseArrayOrCSV(frontmatter.tools);
241
236
 
242
237
  const model = parseModelList(frontmatter.model);
243
238
  const thinkingLevel = parseThinkingLevel(frontmatter);
package/src/index.ts CHANGED
@@ -179,6 +179,7 @@ export {
179
179
  loadSshTool,
180
180
  PythonTool,
181
181
  ReadTool,
182
+ type SubagentContext,
182
183
  type ToolSession,
183
184
  WriteTool,
184
185
  } from "./sdk";
@@ -121,12 +121,12 @@ export function startMemoryStartupTask(options: {
121
121
  settings: Settings;
122
122
  modelRegistry: ModelRegistry;
123
123
  agentDir: string;
124
- taskDepth: number;
124
+ isSubagent: boolean;
125
125
  }): void {
126
- const { session, settings, modelRegistry, agentDir, taskDepth } = options;
126
+ const { session, settings, modelRegistry, agentDir, isSubagent } = options;
127
127
  const cfg = loadMemoryConfig(settings);
128
128
  if (!cfg.enabled) return;
129
- if (taskDepth > 0) return;
129
+ if (isSubagent) return;
130
130
  if (!session.sessionManager.getSessionFile()) return;
131
131
 
132
132
  const dbPath = getAgentDbPath(agentDir);
@@ -85,14 +85,6 @@ const OPTION_PROVIDERS: Partial<Record<SettingPath, OptionProvider>> = {
85
85
  { value: "32", label: "32 tasks" },
86
86
  { value: "64", label: "64 tasks" },
87
87
  ],
88
- // Task max recursion depth
89
- "task.maxRecursionDepth": [
90
- { value: "-1", label: "Unlimited" },
91
- { value: "0", label: "None" },
92
- { value: "1", label: "Single" },
93
- { value: "2", label: "Double" },
94
- { value: "3", label: "Triple" },
95
- ],
96
88
  // Todo max reminders
97
89
  "todo.reminders.max": [
98
90
  { value: "1", label: "1 reminder" },
@@ -890,10 +890,11 @@ function applyCharacterMatch(
890
890
  const adjustedNewText = adjustIndentation(normalizedOldText, matchOutcome.match.actualText, newText);
891
891
 
892
892
  const warnings: string[] = [];
893
- if (matchOutcome.dominantFuzzy && matchOutcome.match) {
893
+ if (matchOutcome.match && matchOutcome.match.confidence < 0.97) {
894
894
  const similarity = Math.round(matchOutcome.match.confidence * 100);
895
+ const qualifier = matchOutcome.dominantFuzzy ? "Dominant fuzzy" : "Fuzzy";
895
896
  warnings.push(
896
- `Dominant fuzzy match selected in ${path} near line ${matchOutcome.match.startLine} (${similarity}% similar).`,
897
+ `${qualifier} match applied in ${path} near line ${matchOutcome.match.startLine} (${similarity}% similar).`,
897
898
  );
898
899
  }
899
900
 
@@ -1152,9 +1153,16 @@ function computeReplacements(
1152
1153
 
1153
1154
  const found = searchResult.index;
1154
1155
 
1155
- if (searchResult.strategy === "fuzzy-dominant") {
1156
+ if (
1157
+ searchResult.strategy === "prefix" ||
1158
+ searchResult.strategy === "substring" ||
1159
+ searchResult.strategy === "fuzzy" ||
1160
+ searchResult.strategy === "fuzzy-dominant"
1161
+ ) {
1156
1162
  const similarity = Math.round(searchResult.confidence * 100);
1157
- warnings.push(`Dominant fuzzy match selected in ${path} near line ${found + 1} (${similarity}% similar).`);
1163
+ warnings.push(
1164
+ `Non-exact match applied in ${path} near line ${found + 1} (${similarity}% similar, strategy: ${searchResult.strategy}).`,
1165
+ );
1158
1166
  }
1159
1167
 
1160
1168
  // Reject if match is ambiguous (prefix/substring matching found multiple matches)
@@ -8,7 +8,7 @@ Finish only the assigned work and return the minimum useful result.
8
8
  - Avoid full-file reads unless necessary.
9
9
  - Prefer edits to existing files over creating new ones.
10
10
  - NEVER create documentation files (*.md) unless explicitly requested.
11
- - When spawning subagents with the Task tool, include a 5-8 word user-facing description.
11
+ - When done, write a concise summary of what you did as your final response. This is your output.
12
12
  - Include the smallest relevant code snippet when discussing code or config.
13
13
  - Follow the main agent's instructions.
14
14
  </directives>
@@ -11,20 +11,8 @@ For additional parent conversation context, check {{contextFile}} (`tail -100` o
11
11
  {{/if}}
12
12
 
13
13
  <critical>
14
- - MUST call `submit_result` exactly once when finished. No JSON in text. No plain-text summary. Pass result via `data` parameter.
15
- - Todo tracking is parent-owned. Do not create or maintain a separate todo list in this subagent.
16
- {{#if outputSchema}}
17
- - If cannot complete, call `submit_result` with `status="aborted"` and error message. Do not provide success result or pretend completion.
18
- {{else}}
19
- - If cannot complete, call `submit_result` with `status="aborted"` and error message. Do not claim success.
20
- {{/if}}
21
- {{#if outputSchema}}
22
- - `data` parameter MUST be valid JSON matching TypeScript interface:
23
- ```ts
24
- {{jtdToTypeScript outputSchema}}
25
- ```
26
- {{/if}}
27
- - If cannot complete, call `submit_result` exactly once with result indicating failure/abort status (use failure/notes field if available). Do not claim success.
14
+ - When done, stop. Your final text response is your output the parent receives it as the task result.
15
+ - If cannot complete, report failure clearly in your final response. Do not claim success.
28
16
  - Do NOT abort due to uncertainty or missing info that can be obtained via tools or repo context. Use `find`/`grep`/`read` first, then proceed with reasonable defaults if multiple options are acceptable.
29
17
  - Aborting is only acceptable when truly blocked after exhausting tools and reasonable attempts. If you abort, include what you tried and the exact blocker in the result.
30
18
  - Keep going until request is fully fulfilled. This matters.
@@ -115,8 +115,17 @@ The question is not "does this work?" but "under what conditions? What happens o
115
115
  - Skip entirely for single-step or trivial requests.
116
116
 
117
117
  {{#has tools "task"}}
118
- ### Parallel Execution
119
- Use the Task tool when work genuinely forks into independent streams:
118
+ ### Delegation
119
+ You have subagents. Pick the right one:
120
+ - "I need to think through architecture/plan" → **Oracle**
121
+ - "I need to understand unfamiliar code" → **Explore / Librarian**
122
+ - "I know what to do, need parallel execution" → **Task tool**
123
+
124
+ Workflow for complex work: Oracle (plan) → Explore (validate scope) → Task (execute).
125
+
126
+ Task tool is a fire-and-forget executor — a productive junior engineer who cannot ask follow-ups once started. Prompt it with detailed instructions, enumerate deliverables, include constraints and verification steps.
127
+
128
+ Use Task tool when work genuinely forks into independent streams:
120
129
  - Editing 4+ files with no dependencies between edits
121
130
  - Investigating 2+ independent subsystems
122
131
  - Work that decomposes into pieces not needing each other's results
@@ -231,18 +240,7 @@ Current date: {{date}}
231
240
 
232
241
  {{#has tools "task"}}
233
242
  <parallel_reflex>
234
- When work forks, you fork.
235
-
236
- Notice the sequential habit:
237
- - Comfort in doing one thing at a time
238
- - Illusion that order = correctness
239
- - Assumption that B depends on A
240
- **Use Task tool when:**
241
- - Editing 4+ files with no dependencies between edits
242
- - Investigating 2+ independent subsystems
243
- - Work decomposes into pieces not needing each other's results
244
-
245
- Sequential work requires justification. If you cannot articulate why B depends on A → parallelize.
243
+ When work forks, you fork. Sequential work requires justification — if you cannot articulate why B depends on A, parallelize via Task tool.
246
244
  </parallel_reflex>
247
245
  {{/has}}
248
246
 
@@ -1,18 +1,12 @@
1
1
  # Task
2
2
 
3
- Launch subagents to execute parallel, well-scoped tasks.
3
+ Launch a fire-and-forget subagent to execute well-scoped work. Think of it as a productive junior engineer who cannot ask follow-ups once started.
4
+ - **Use for**: Multi-file implementations, cross-layer refactors, mass migrations, boilerplate generation
5
+ - **Don't use for**: Exploratory work, architectural decisions, single-file edits, reading a file
4
6
 
5
- ## What subagents inherit automatically
6
- Subagents receive the **full system prompt**, including AGENTS.md, context files, and skills. Do NOT repeat project rules, coding conventions, or style guidelines in `context` — they already have them.
7
+ ## Subagent capabilities
7
8
 
8
- ## What subagents do NOT have
9
- Subagents have no access to your conversation history. They don't know:
10
- - Decisions you made but didn't write down
11
- - Which approach you chose among alternatives
12
- - What you learned from reading files during this session
13
- - Requirements the user stated only in conversation
14
-
15
- Subagents CAN grep the parent conversation file for supplementary details.
9
+ Subagents receive the **full system prompt**, including AGENTS.md, context files, and skills. They have no access to your conversation history — they don't know decisions you made, approaches you chose, or requirements stated only in conversation. Subagents CAN grep the parent conversation file for supplementary details.
16
10
  ---
17
11
 
18
12
  ## Parameters
@@ -22,35 +16,18 @@ Subagents CAN grep the parent conversation file for supplementary details.
22
16
  Shared background prepended verbatim to every task `assignment`. Use only for session-specific information subagents lack.
23
17
 
24
18
  <critical>
25
- Do NOT include project rules, coding conventions, or style guidelines — subagents already have AGENTS.md and context files in their system prompt. Repeating them wastes tokens and inflates context. Restating any rule from AGENTS.md in `context` is a bug — treat it like a lint error.
19
+ Do NOT include project rules, coding conventions, or style guidelines — subagents already have AGENTS.md. Restating any rule from AGENTS.md in `context` is a bug.
26
20
  </critical>
27
- **Before writing each line of context, ask:** "Would this sentence be true for ANY task in this repo, or only for THIS specific batch?" If it applies to any task → it's a project rule → the subagent already has it → delete the line.
28
-
29
- WRONG — restating project rules the subagent already has:
30
- ```
31
- ## Constraints
32
- - Use X import style, not Y (per AGENTS.md)
33
- - Use Z for private fields per AGENTS.md
34
- - Run the formatter after changes
35
- - Follow the logging convention
36
- ```
37
- Every line above restates a project convention. The subagent reads AGENTS.md. Delete them all.
38
-
39
- RIGHT — only session-specific decisions the subagent cannot infer from project files:
40
- ```
41
- ## Constraints
42
- - We decided to use approach A over B (session decision)
43
- - The migration target type is `Foo` from `bar` package (looked up this session)
44
- ```
21
+ **Before writing each line of context, ask:** "Would this sentence be true for ANY task in this repo, or only for THIS specific batch?" If it applies to any task → the subagent already has it → delete the line.
45
22
 
46
23
  Use template; omit non-applicable sections:
47
24
 
48
25
  ````
49
26
  ## Goal
50
- One sentence: batch accomplishes together.
27
+ One sentence: what the batch accomplishes together.
51
28
 
52
29
  ## Non-goals
53
- Explicitly exclude tempting scope — what tasks must not touch/attempt.
30
+ Explicitly exclude tempting scope — what tasks must not touch.
54
31
 
55
32
  ## Constraints
56
33
  - Task-specific MUST / MUST NOT rules not already in AGENTS.md
@@ -58,49 +35,43 @@ Explicitly exclude tempting scope — what tasks must not touch/attempt.
58
35
 
59
36
  ## Reference Files
60
37
  - `path/to/file.ext` — pattern demo
61
- - `path/to/other.ext` — reuse or avoid
62
38
 
63
39
  ## API Contract (if tasks produce/consume shared interface)
64
40
  ```language
65
- // Exact type definitions, function signatures, interface shapes
41
+ // Exact type definitions, function signatures
66
42
  ```
67
43
 
68
44
  ## Acceptance (global)
69
45
  - Definition of "done" for batch
70
- - Note: build/test/lint verification happens AFTER all tasks complete — not inside tasks (see below)
46
+ - For parallel tasks, build/test/lint verification happens AFTER all tasks complete — not inside tasks. Single tasks may self-verify.
71
47
  ````
72
- **Belongs in `context`**: task-specific goal, non-goals, session decisions, reference paths, shared type definitions, API contracts, global acceptance commands — anything 2+ tasks need that isn't already in AGENTS.md.
73
- **Rule of thumb:** if repeat in 2+ tasks, belongs in `context`.
74
- **Does NOT belong in `context`**: project rules already in AGENTS.md/context files, per-task file lists, one-off requirements (go in `assignment`), and strict response contracts that only apply to one task.
48
+ **Belongs in `context`**: session decisions, reference paths, shared type definitions, API contracts, global acceptance — anything 2+ tasks need that isn't in AGENTS.md.
49
+ **Does NOT belong**: project rules from AGENTS.md, per-task file lists, one-off requirements (go in `assignment`).
75
50
 
76
51
  ### `tasks` (required)
77
52
 
78
- Array tasks execute in parallel.
53
+ Array of tasks that execute in parallel.
79
54
 
80
55
  |Field|Required|Purpose|
81
56
  |---|---|---|
82
- |`id`|✓|CamelCase identifier, max 32 chars|
83
- |`description`|✓|Short one-liner for UI display only — not seen by subagent|
84
- |`assignment`|✓|Complete per-task instructions. See [Writing an assignment](#writing-an-assignment).|
85
- |`skills`||Skill names preload. Use only when changes correctness — don’t spam every task.|
86
-
87
- Outputs are free-form text/JSON from each subtask. If you need strict structure, define it clearly inside each `assignment` and validate at the caller.
57
+ |`id`|yes|CamelCase identifier, max 32 chars|
58
+ |`description`|yes|Short one-liner for UI display only — not seen by subagent|
59
+ |`assignment`|yes|Complete per-task instructions (see below)|
60
+ |`skills`||Skill names to preload. Use only when it changes correctness.|
88
61
  ---
89
62
 
90
63
  ## Writing an assignment
91
64
 
92
- <critical>## Task scope
93
-
94
- `assignment` must contain enough info for agent to act **without asking a clarifying question**.
95
- **Minimum bar:** assignment under ~8 lines or missing acceptance criteria = too vague. One-liners guaranteed failure.
65
+ <critical>
66
+ `assignment` must contain enough info for the subagent to act **without asking a clarifying question**. One-liners guarantee failure.
96
67
 
97
- Use structure every assignment:
68
+ Use this structure:
98
69
 
99
70
  ```
100
71
  ## Target
101
72
  - Files: exact path(s)
102
73
  - Symbols/entrypoints: specific functions, types, exports
103
- - Non-goals: what task must NOT touch (prevents scope creep)
74
+ - Non-goals: what task must NOT touch
104
75
 
105
76
  ## Change
106
77
  - Step-by-step: add/remove/rename/restructure
@@ -108,168 +79,68 @@ Use structure every assignment:
108
79
 
109
80
  ## Edge Cases / Don't Break
110
81
  - Tricky case 1: ...
111
- - Tricky case 2: ...
112
- - Existing behavior must survive: ...
82
+ - Existing behavior that must survive: ...
113
83
 
114
84
  ## Acceptance (task-local)
115
85
  - Expected behavior or observable result
116
- - DO NOT include project-wide build/test/lint commands (see below)
86
+ - For parallel tasks: DO NOT include project-wide build/test/lint commands
117
87
  ```
118
88
 
119
- `context` carries shared background. `assignment` carries only delta: file-specific instructions, local edge cases, per-task acceptance checks. Never duplicate shared constraints across assignments.
120
-
121
- ### Anti-patterns (ban these)
122
- **Vague assignments** — agent guesses wrong or stalls:
123
- - "Refactor this to be cleaner."
124
- - "Migrate to N-API."
125
- - "Fix the bug in streaming."
126
- - "Update all constructors in `src/**/*.ts`."
127
- **Vague context** — forces agent invent conventions:
128
- - "Use existing patterns."
129
- - "Follow conventions."
130
- - "No WASM."
131
- **Redundant context** — wastes tokens repeating what subagents already have:
132
- - Restating AGENTS.md rules (coding style, import conventions, formatting commands, logger usage, etc.)
133
- - Repeating project constraints from context files
134
- - Listing tool/framework preferences already documented in the repo
135
-
136
- If a constraint appears in AGENTS.md, it MUST NOT appear in `context`. The subagent has the full system prompt.
137
-
138
- If tempted to write above, expand using templates.
139
- **Test/lint commands in parallel tasks** — edit wars:
140
- Parallel agents share working tree. If two agents run `bun check` or `bun test` concurrently, they see each other's half-finished edits, "fix" phantom errors, loop. **Never tell parallel tasks run project-wide build/test/lint commands.** Each task edits, stops. Caller verifies after all tasks complete.
141
- **If you can't specify scope yet**, create **Discovery task** first: enumerate files, find callsites, list candidates. Then fan out with explicit paths.
89
+ `context` carries shared background. `assignment` carries only delta: file-specific instructions, local edge cases, per-task acceptance.
142
90
 
143
91
  ### Delegate intent, not keystrokes
144
92
 
145
- Your role as tech lead: set direction, define boundaries, call out pitfalls — then get out of way. Dont read every file, decide every edit, dictate line-by-line. That makes you bottleneck; agent typist.
146
- **Be specific about:** constraints, naming conventions, API contracts, "dont break" items, acceptance criteria.
147
- **Delegate:** code reading, approach selection, exact edit locations, implementation details. Agent has tools, can reason about code.
148
-
149
- Micromanaging (you think, agent types):
150
- ```
151
- assignment: "In src/api/handler.ts, line 47, change `throw err` to `throw new ApiError(err.message, 500)`.
152
- On line 63, wrap fetch call try/catch return 502 on failure.
153
- On line 89, add null check before accessing resp.body..."
154
- ```
155
-
156
- Delegating (agent thinks within constraints):
157
- ```
158
- assignment: "## Target\n- Files: src/api/handler.ts\n\n## Change\nImprove error handling: replace raw throws
159
- with typed ApiError instances, add try/catch around external calls, guard against null responses.\n\n
160
- ## Edge Cases / Don't Break\n- Existing error codes in tests must still match\n
161
- - Don't change public function signatures"
162
- ```
163
-
164
- First style wastes your time, brittle if code shifts. Second gives agent room to do work.
93
+ Your role is tech lead: set direction, define boundaries, call out pitfalls — then get out of the way. Don't dictate line-by-line edits.
94
+ **Be specific about:** constraints, naming, API contracts, "don't break" items, acceptance criteria.
95
+ **Delegate:** code reading, approach selection, exact edit locations, implementation details.
165
96
  </critical>
166
97
 
167
- ## Example
168
-
169
- <example type="bad" label="Duplicated context inflates tokens">
170
- <tasks>
171
- <task name="Grep">
172
- <description>Port grep module from WASM to N-API...</description>
173
- <assignment>Port grep module from WASM to N-API... (same blob repeated)</assignment>
174
- </task>
175
- </tasks>
176
- </example>
177
-
178
- <example type="good" label="Shared rules in context, only deltas in assignment">
179
- <context>
180
- ## Goal
181
- Port WASM modules to N-API, matching existing arcane-natives conventions.
182
-
183
- ## Non-goals
184
- Do not touch TS bindings or downstream consumers — separate phase.
185
-
186
- ## Constraints
187
- - MUST use `#[napi]` attribute macro on all exports
188
- - MUST return `napi::Result<T>` for fallible ops; never panic
189
- - MUST use `spawn_blocking` for filesystem I/O or >1ms work
190
- ...
191
-
192
- ## Acceptance (global)
193
- - Caller verifies after all tasks: `cargo test -p arcane-natives` and `cargo build -p arcane-natives` with no warnings
194
- - Individual tasks must NOT run these commands themselves
195
- </context>
196
-
197
- <tasks>
198
- <task name="PortGrep">
199
- <description>Port grep module to N-API</description>
200
- <assignment>
201
- ## Target
202
- - Files: `src/grep.rs`, `src/lib.rs` (registration only)
203
- - Symbols: search, search_multi, compile_pattern
204
-
205
- ## Change
206
- - Implement three N-API exports in grep.rs:
207
- - `search(pattern: JsString, path: JsString, env: Env) -> napi::Result<Vec<Match>>`
208
- ...
209
-
210
- ## Acceptance (task-local)
211
- - Three functions exported with correct signatures (caller verifies build after all tasks)
212
- </assignment>
213
- </task>
214
-
215
- <task name="PortHighlight">
216
- <description>Port highlight module to N-API</description>
217
- <assignment>
218
- ## Target
219
- - Files: `src/highlight.rs`, `src/lib.rs` (registration only)
220
- ...
221
- </assignment>
222
- </task>
223
- </tasks>
224
- </example>
98
+ ### Anti-patterns
99
+ **Vague assignments** — subagent guesses wrong or stalls:
100
+ - "Refactor this to be cleaner."
101
+ - "Fix the bug in streaming."
102
+ - "Update all constructors in `src/**/*.ts`."
103
+ **Test/lint in parallel tasks** edit wars:
104
+ Parallel agents share working tree. If two agents run `bun check` concurrently, they see each other's half-finished edits, "fix" phantom errors, loop. **Never tell parallel tasks to run project-wide build/test/lint.** Each task edits, stops. Caller verifies after all complete. Single-task launches may include verification.
105
+ **If you can't specify scope yet**, create a **Discovery task** first: enumerate files, find callsites, list candidates. Then fan out with explicit paths.
225
106
  ---
226
107
 
227
108
  ## Task scope
228
109
 
229
- Each task small, well-defined scope — **at most 35 files**.
230
- **Signs task too broad:**
231
- - File paths use globs (`src/**/*.ts`) instead of explicit names
232
- - Assignment says "update all" / "migrate everything" / "refactor across"
233
- - Scope covers entire package or directory tree
234
- **Fix:** enumerate files first (grep/glob discovery), then fan out one task per file or small cluster.
110
+ Each task: small, well-defined — **at most 3-5 files**.
111
+ **Signs task is too broad:** file paths use globs, assignment says "update all" / "migrate everything", scope covers entire package.
112
+ **Fix:** enumerate files first (grep/glob), then fan out one task per file or small cluster.
235
113
  ---
236
114
 
237
115
  ## Parallelization
238
116
  **Test:** Can task B produce correct output without seeing task A's result?
239
117
  - **Yes** → parallelize
240
- - **No** → run sequentially (A completes, then launch B with A output in context)
118
+ - **No** → sequential (A completes, then launch B with A's output in context)
241
119
 
242
120
  ### Must be sequential
243
121
 
244
122
  |First|Then|Reason|
245
123
  |---|---|---|
246
124
  |Define types/interfaces|Implement consumers|Consumers need contract|
247
- |Create API exports|Write bindings/callers|Callers need export names/signatures|
248
- |Scaffold structure|Implement bodies|Bodies need shape|
125
+ |Create API exports|Write bindings/callers|Callers need signatures|
249
126
  |Core module|Dependent modules|Dependents import from core|
250
- |Schema/DB migration|Application logic|Logic depends on new schema shape|
251
127
 
252
128
  ### Safe to parallelize
253
129
  - Independent modules, no cross-imports
254
130
  - Tests for already-implemented code
255
131
  - Isolated file-scoped refactors
256
- - Documentation for stable APIs
257
-
258
- ### Phased execution
259
132
 
260
- Layered work with dependencies:
261
- **Phase 1 — Foundation** (do yourself or single task): define interfaces, create scaffolds, establish API shape. Never fan out until contract known.
262
- **Phase 2 — Parallel implementation**: fan out tasks consuming same known interface. Include Phase 1 API contract in `context`.
133
+ ### Multi-phase pattern
134
+ **Phase 1 — Sequential**: define shared contracts (types, interfaces, schemas).
135
+ **Phase 2 — Parallel**: fan out tasks consuming same known interface.
263
136
  **Phase 3 — Integration** (do yourself): wire modules, fix mismatches, verify builds.
264
- **Phase 4 — Dependent layer**: fan out tasks consuming Phase 2 outputs.
265
137
  ---
266
138
 
267
139
  ## Pre-flight checklist
268
140
 
269
141
  Before calling tool, verify:
270
- - [ ] `context` includes only session-specific info not already in AGENTS.md/context files
271
- - [ ] Each `assignment` follows assignment template not one-liner
272
- - [ ] Each `assignment` includes edge cases / "don’t break" items
273
- - [ ] Tasks truly parallel (no hidden dependencies)
274
- - [ ] Scope small, file paths explicit (no globs)
275
- - [ ] No task runs project-wide build/test/lint — you do after all tasks complete
142
+ - [ ] `context` includes only session-specific info not already in AGENTS.md
143
+ - [ ] Each assignment has Target, Change, Edge Cases, Acceptance sections
144
+ - [ ] Assignments reference exact file paths (no globs)
145
+ - [ ] Scope small, file paths explicit
146
+ - [ ] Parallel tasks don't run project-wide build/test/lint — you do after all tasks complete (single tasks may self-verify)
@@ -18,11 +18,11 @@ Use proactively:
18
18
  - in_progress: working
19
19
  - completed: finished
20
20
  2. **Task Management**:
21
- - Update status in real time
22
- - Mark complete IMMEDIATELY after finishing (no batching)
23
- - Keep exactly ONE task in_progress at a time
21
+ - Update status each turn
22
+ - Mark completed after each code execution finishes — do not defer to a later turn
23
+ - Multiple tasks may be in_progress simultaneously when working in parallel
24
24
  - Remove tasks no longer relevant
25
- - Complete tasks in list order (do not mark later tasks completed while earlier tasks remain incomplete)
25
+ - Mark tasks completed as they finish, regardless of list order
26
26
  3. **Task Completion Requirements**:
27
27
  - ONLY mark completed when FULLY accomplished
28
28
  - On errors/blockers/inability to finish, keep in_progress
package/src/sdk.ts CHANGED
@@ -72,6 +72,7 @@ import {
72
72
  loadSshTool,
73
73
  PythonTool,
74
74
  ReadTool,
75
+ type SubagentContext,
75
76
  setPreferredImageProvider,
76
77
  setPreferredSearchProvider,
77
78
  type Tool,
@@ -157,12 +158,8 @@ export interface CreateAgentSessionOptions {
157
158
  /** Tool names explicitly requested (enables disabled-by-default tools) */
158
159
  toolNames?: string[];
159
160
 
160
- /** Output schema for structured completion (subagents) */
161
- outputSchema?: unknown;
162
- /** Whether to include the submit_result tool by default */
163
- requireSubmitResultTool?: boolean;
164
- /** Task recursion depth (for subagent sessions). Default: 0 */
165
- taskDepth?: number;
161
+ /** Whether this is a subagent session. Default: false */
162
+ isSubagent?: boolean;
166
163
  /** Parent task ID prefix for nested artifact naming (e.g., "6-Extensions") */
167
164
  parentTaskPrefix?: string;
168
165
 
@@ -223,6 +220,7 @@ export {
223
220
  PythonTool,
224
221
  ReadTool,
225
222
  WriteTool,
223
+ type SubagentContext,
226
224
  type ToolSession,
227
225
  };
228
226
 
@@ -629,8 +627,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
629
627
 
630
628
  // For subagent sessions using GitHub Copilot, add X-Initiator header
631
629
  // to ensure proper billing (agent-initiated vs user-initiated)
632
- const taskDepth = options.taskDepth ?? 0;
633
- const forceCopilotAgentInitiator = taskDepth > 0;
630
+ const isSubagent = options.isSubagent ?? false;
631
+ const forceCopilotAgentInitiator = isSubagent;
634
632
  if (forceCopilotAgentInitiator && model?.provider === "github-copilot") {
635
633
  model = {
636
634
  ...model,
@@ -722,9 +720,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
722
720
  contextFiles,
723
721
  skills,
724
722
  eventBus,
725
- outputSchema: options.outputSchema,
726
- requireSubmitResultTool: options.requireSubmitResultTool,
727
- taskDepth: options.taskDepth ?? 0,
723
+ isSubagent: options.isSubagent ?? false,
728
724
  getSessionFile: () => sessionManager.getSessionFile() ?? null,
729
725
  getSessionId: () => sessionManager.getSessionId?.() ?? null,
730
726
  getSessionSpawns: () => options.spawns ?? "*",
@@ -736,10 +732,12 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
736
732
  if (model) return formatModelString(model);
737
733
  return undefined;
738
734
  },
739
- getCompactContext: () => session.formatCompactContext(),
735
+ subagentContext: {
736
+ getCompactContext: () => session.formatCompactContext(),
737
+ authStorage,
738
+ modelRegistry,
739
+ },
740
740
  settings,
741
- authStorage,
742
- modelRegistry,
743
741
  };
744
742
 
745
743
  // Initialize internal URL router for internal protocols (agent://, artifact://, memory://, skill://, rule://)
@@ -798,7 +796,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
798
796
  });
799
797
  time("discoverAndLoadMCPTools");
800
798
  mcpManager = mcpResult.manager;
801
- toolSession.mcpManager = mcpManager;
799
+ if (!toolSession.subagentContext) toolSession.subagentContext = {};
800
+ toolSession.subagentContext.mcpManager = mcpManager;
802
801
 
803
802
  // If we extracted Exa API keys from MCP configs and EXA_AARCANE_KEY isn't set, use the first one
804
803
  if (mcpResult.exaApiKeys.length > 0 && !$env.EXA_AARCANE_KEY) {
@@ -1273,7 +1272,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1273
1272
  settings,
1274
1273
  modelRegistry,
1275
1274
  agentDir,
1276
- taskDepth,
1275
+ isSubagent,
1277
1276
  });
1278
1277
 
1279
1278
  return {