@pugi/cli 0.1.0-beta.4 → 0.1.0-beta.41

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 (250) hide show
  1. package/THIRD_PARTY_NOTICES.md +40 -0
  2. package/assets/pugi-mascot.ansi +15 -25
  3. package/bin/run.js +33 -1
  4. package/dist/commands/jobs-watch.js +201 -0
  5. package/dist/commands/jobs.js +15 -0
  6. package/dist/commands/smoke.js +133 -0
  7. package/dist/core/agent-progress/cleanup.js +134 -0
  8. package/dist/core/agent-progress/schema.js +144 -0
  9. package/dist/core/agent-progress/writer.js +101 -0
  10. package/dist/core/artifact-chain/dispatcher.js +148 -0
  11. package/dist/core/artifact-chain/exporter.js +164 -0
  12. package/dist/core/artifact-chain/state.js +243 -0
  13. package/dist/core/artifact-chain/steps.js +169 -0
  14. package/dist/core/auth/ensure-authenticated.js +129 -0
  15. package/dist/core/auth/env-provider.js +238 -0
  16. package/dist/core/auto-update/channels.js +122 -0
  17. package/dist/core/auto-update/checker.js +241 -0
  18. package/dist/core/auto-update/state.js +235 -0
  19. package/dist/core/bare-mode/index.js +107 -0
  20. package/dist/core/bash-classifier.js +108 -1
  21. package/dist/core/checkpoint/resumer.js +149 -0
  22. package/dist/core/checkpoint/rewinder.js +291 -0
  23. package/dist/core/codegraph/decision-store.js +248 -0
  24. package/dist/core/codegraph/detect-repo.js +459 -0
  25. package/dist/core/codegraph/install.js +134 -0
  26. package/dist/core/codegraph/offer-hook.js +220 -0
  27. package/dist/core/compact/auto-trigger.js +96 -0
  28. package/dist/core/compact/buffer-rewriter.js +115 -0
  29. package/dist/core/compact/summarizer.js +208 -0
  30. package/dist/core/compact/token-counter.js +108 -0
  31. package/dist/core/consensus/diff-capture.js +73 -0
  32. package/dist/core/context/index.js +7 -0
  33. package/dist/core/context/markdown-traverse.js +255 -0
  34. package/dist/core/cost/rate-card.js +129 -0
  35. package/dist/core/cost/tracker.js +221 -0
  36. package/dist/core/denial-tracking/index.js +8 -0
  37. package/dist/core/denial-tracking/state.js +264 -0
  38. package/dist/core/diagnostics/probe-runner.js +93 -0
  39. package/dist/core/diagnostics/probes/api.js +46 -0
  40. package/dist/core/diagnostics/probes/auth.js +86 -0
  41. package/dist/core/diagnostics/probes/bare-mode.js +42 -0
  42. package/dist/core/diagnostics/probes/cli-version.js +127 -0
  43. package/dist/core/diagnostics/probes/config.js +72 -0
  44. package/dist/core/diagnostics/probes/denial-tracking.js +57 -0
  45. package/dist/core/diagnostics/probes/disk.js +81 -0
  46. package/dist/core/diagnostics/probes/git.js +65 -0
  47. package/dist/core/diagnostics/probes/mcp.js +75 -0
  48. package/dist/core/diagnostics/probes/node.js +59 -0
  49. package/dist/core/diagnostics/probes/pnpm.js +36 -0
  50. package/dist/core/diagnostics/probes/pugi-md.js +89 -0
  51. package/dist/core/diagnostics/probes/session.js +74 -0
  52. package/dist/core/diagnostics/probes/status-snapshot.js +488 -0
  53. package/dist/core/diagnostics/probes/workspace.js +63 -0
  54. package/dist/core/diagnostics/types.js +70 -0
  55. package/dist/core/dispatch/cache-cleanup.js +197 -0
  56. package/dist/core/dispatch/cache-handoff.js +295 -0
  57. package/dist/core/edits/dispatch.js +218 -2
  58. package/dist/core/edits/journal.js +199 -0
  59. package/dist/core/edits/layer-d-ast.js +557 -14
  60. package/dist/core/edits/verify-hook.js +273 -0
  61. package/dist/core/edits/worktree.js +322 -0
  62. package/dist/core/engine/anvil-client.js +115 -5
  63. package/dist/core/engine/budgets.js +98 -0
  64. package/dist/core/engine/context-prefix.js +155 -0
  65. package/dist/core/engine/intent.js +260 -0
  66. package/dist/core/engine/native-pugi.js +860 -211
  67. package/dist/core/engine/prompts.js +88 -2
  68. package/dist/core/engine/strip-internal-fields.js +124 -0
  69. package/dist/core/engine/tool-bridge.js +1045 -36
  70. package/dist/core/feedback/queue.js +177 -0
  71. package/dist/core/feedback/submitter.js +145 -0
  72. package/dist/core/file-cache.js +113 -1
  73. package/dist/core/hooks/events.js +44 -0
  74. package/dist/core/hooks/index.js +15 -0
  75. package/dist/core/hooks/registry.js +213 -0
  76. package/dist/core/hooks/runner.js +236 -0
  77. package/dist/core/hooks/v2/event-emitter.js +115 -0
  78. package/dist/core/hooks/v2/executor.js +282 -0
  79. package/dist/core/hooks/v2/index.js +25 -0
  80. package/dist/core/hooks/v2/lifecycle.js +104 -0
  81. package/dist/core/hooks/v2/loader.js +216 -0
  82. package/dist/core/hooks/v2/matcher.js +125 -0
  83. package/dist/core/hooks/v2/trust.js +143 -0
  84. package/dist/core/hooks/v2/types.js +86 -0
  85. package/dist/core/lsp/cache.js +105 -0
  86. package/dist/core/lsp/client.js +776 -0
  87. package/dist/core/lsp/language-detect.js +66 -0
  88. package/dist/core/lsp/post-edit-diagnostics.js +171 -0
  89. package/dist/core/mcp/client.js +75 -6
  90. package/dist/core/mcp/http-server.js +553 -0
  91. package/dist/core/mcp/orchestrator-tools.js +662 -0
  92. package/dist/core/mcp/permission.js +190 -0
  93. package/dist/core/mcp/registry.js +24 -2
  94. package/dist/core/mcp/server-tools.js +219 -0
  95. package/dist/core/mcp/server.js +397 -0
  96. package/dist/core/memory/dual-write.js +416 -0
  97. package/dist/core/memory/phase1-kinds.js +20 -0
  98. package/dist/core/memory-sync/queue.js +158 -0
  99. package/dist/core/onboarding/ensure-initialized.js +133 -0
  100. package/dist/core/onboarding/marker.js +111 -0
  101. package/dist/core/onboarding/telemetry-state.js +108 -0
  102. package/dist/core/output-style/presets.js +176 -0
  103. package/dist/core/output-style/state.js +185 -0
  104. package/dist/core/permissions/auto-classifier.js +124 -0
  105. package/dist/core/permissions/circuit-breaker.js +83 -0
  106. package/dist/core/permissions/gate.js +278 -0
  107. package/dist/core/permissions/index.js +20 -0
  108. package/dist/core/permissions/mode.js +174 -0
  109. package/dist/core/permissions/state.js +241 -0
  110. package/dist/core/permissions/tool-class.js +93 -0
  111. package/dist/core/prd-check/parser.js +215 -0
  112. package/dist/core/prd-check/reporter.js +127 -0
  113. package/dist/core/prd-check/session-review.js +557 -0
  114. package/dist/core/prd-check/verifiers.js +223 -0
  115. package/dist/core/pugi-md/context-injector.js +76 -0
  116. package/dist/core/pugi-md/walk-up.js +207 -0
  117. package/dist/core/release-notes/parser.js +241 -0
  118. package/dist/core/release-notes/state.js +116 -0
  119. package/dist/core/repl/history.js +11 -1
  120. package/dist/core/repl/model-pricing.js +135 -0
  121. package/dist/core/repl/session.js +1899 -38
  122. package/dist/core/repl/slash-commands.js +406 -21
  123. package/dist/core/repl/store/session-store.js +31 -2
  124. package/dist/core/repl/workspace-context.js +22 -0
  125. package/dist/core/repo-map/build.js +125 -0
  126. package/dist/core/repo-map/cache.js +185 -0
  127. package/dist/core/repo-map/extractor.js +254 -0
  128. package/dist/core/repo-map/formatter.js +145 -0
  129. package/dist/core/repo-map/scanner.js +211 -0
  130. package/dist/core/retry-budget/budget.js +284 -0
  131. package/dist/core/retry-budget/index.js +5 -0
  132. package/dist/core/session.js +92 -0
  133. package/dist/core/settings.js +80 -0
  134. package/dist/core/share/formatter.js +271 -0
  135. package/dist/core/share/redactor.js +221 -0
  136. package/dist/core/share/uploader.js +267 -0
  137. package/dist/core/skills/defaults.js +457 -0
  138. package/dist/core/smoke/headless-driver.js +174 -0
  139. package/dist/core/smoke/orchestrator.js +194 -0
  140. package/dist/core/smoke/runner.js +238 -0
  141. package/dist/core/smoke/scenario-parser.js +316 -0
  142. package/dist/core/subagents/dispatcher-real.js +600 -0
  143. package/dist/core/subagents/dispatcher.js +113 -24
  144. package/dist/core/subagents/index.js +18 -5
  145. package/dist/core/subagents/isolation-matrix.js +213 -0
  146. package/dist/core/subagents/spawn.js +19 -4
  147. package/dist/core/telemetry/emitter.js +229 -0
  148. package/dist/core/telemetry/queue.js +251 -0
  149. package/dist/core/theme/context.js +91 -0
  150. package/dist/core/theme/presets.js +228 -0
  151. package/dist/core/theme/state.js +181 -0
  152. package/dist/core/todos/invariant.js +10 -0
  153. package/dist/core/todos/state.js +177 -0
  154. package/dist/core/transport/version-interceptor.js +166 -0
  155. package/dist/core/vim/keymap.js +288 -0
  156. package/dist/core/vim/state.js +92 -0
  157. package/dist/index.js +28 -0
  158. package/dist/runtime/bootstrap.js +190 -0
  159. package/dist/runtime/cli.js +3073 -321
  160. package/dist/runtime/commands/cancel.js +231 -0
  161. package/dist/runtime/commands/chain.js +489 -0
  162. package/dist/runtime/commands/codegraph-status.js +227 -0
  163. package/dist/runtime/commands/compact.js +297 -0
  164. package/dist/runtime/commands/cost.js +199 -0
  165. package/dist/runtime/commands/delegate.js +242 -11
  166. package/dist/runtime/commands/dispatch.js +126 -0
  167. package/dist/runtime/commands/doctor.js +390 -0
  168. package/dist/runtime/commands/feedback.js +184 -0
  169. package/dist/runtime/commands/hooks.js +184 -0
  170. package/dist/runtime/commands/lsp.js +368 -0
  171. package/dist/runtime/commands/mcp.js +879 -0
  172. package/dist/runtime/commands/memory.js +508 -0
  173. package/dist/runtime/commands/model.js +237 -0
  174. package/dist/runtime/commands/onboarding.js +275 -0
  175. package/dist/runtime/commands/patch.js +128 -0
  176. package/dist/runtime/commands/permissions.js +112 -0
  177. package/dist/runtime/commands/plan.js +143 -0
  178. package/dist/runtime/commands/prd-check.js +285 -0
  179. package/dist/runtime/commands/redo-blob-store.js +92 -0
  180. package/dist/runtime/commands/redo.js +361 -0
  181. package/dist/runtime/commands/release-notes.js +229 -0
  182. package/dist/runtime/commands/repo-map.js +95 -0
  183. package/dist/runtime/commands/report.js +299 -0
  184. package/dist/runtime/commands/resume.js +118 -0
  185. package/dist/runtime/commands/review-consensus.js +17 -2
  186. package/dist/runtime/commands/rewind.js +333 -0
  187. package/dist/runtime/commands/sessions.js +163 -0
  188. package/dist/runtime/commands/share.js +316 -0
  189. package/dist/runtime/commands/status.js +186 -0
  190. package/dist/runtime/commands/stickers.js +82 -0
  191. package/dist/runtime/commands/style.js +194 -0
  192. package/dist/runtime/commands/theme.js +196 -0
  193. package/dist/runtime/commands/undo.js +32 -0
  194. package/dist/runtime/commands/update.js +289 -0
  195. package/dist/runtime/commands/vim.js +140 -0
  196. package/dist/runtime/commands/worktree.js +177 -0
  197. package/dist/runtime/headless-repl.js +195 -0
  198. package/dist/runtime/headless.js +543 -0
  199. package/dist/runtime/load-hooks-or-exit.js +71 -0
  200. package/dist/runtime/plan-decompose.js +531 -0
  201. package/dist/runtime/version.js +65 -0
  202. package/dist/tools/agent-tool.js +229 -0
  203. package/dist/tools/apply-patch.js +556 -0
  204. package/dist/tools/ask-user-question.js +213 -0
  205. package/dist/tools/ask-user.js +115 -0
  206. package/dist/tools/file-tools.js +85 -14
  207. package/dist/tools/lsp-tools.js +189 -0
  208. package/dist/tools/mcp-tool.js +260 -0
  209. package/dist/tools/multi-edit.js +361 -0
  210. package/dist/tools/powershell.js +156 -0
  211. package/dist/tools/registry.js +51 -0
  212. package/dist/tools/skill-tool.js +96 -0
  213. package/dist/tools/tasks.js +208 -0
  214. package/dist/tools/todo-write.js +184 -0
  215. package/dist/tools/web-fetch.js +147 -2
  216. package/dist/tools/web-search.js +458 -0
  217. package/dist/tui/agent-progress-card.js +111 -0
  218. package/dist/tui/agent-tree.js +10 -0
  219. package/dist/tui/ask-modal.js +2 -2
  220. package/dist/tui/ask-user-question-prompt.js +192 -0
  221. package/dist/tui/compact-banner.js +81 -0
  222. package/dist/tui/conversation-pane.js +82 -8
  223. package/dist/tui/cost-table.js +111 -0
  224. package/dist/tui/doctor-table.js +46 -0
  225. package/dist/tui/feedback-prompt.js +156 -0
  226. package/dist/tui/input-box.js +69 -2
  227. package/dist/tui/markdown-render.js +4 -4
  228. package/dist/tui/onboarding-wizard.js +240 -0
  229. package/dist/tui/permissions-picker.js +86 -0
  230. package/dist/tui/render.js +35 -0
  231. package/dist/tui/repl-render.js +303 -13
  232. package/dist/tui/repl-splash.js +2 -2
  233. package/dist/tui/repl.js +72 -14
  234. package/dist/tui/splash.js +1 -1
  235. package/dist/tui/status-bar.js +94 -16
  236. package/dist/tui/status-table.js +7 -0
  237. package/dist/tui/stickers-art.js +136 -0
  238. package/dist/tui/style-table.js +28 -0
  239. package/dist/tui/theme-table.js +29 -0
  240. package/dist/tui/tool-stream-pane.js +52 -3
  241. package/dist/tui/update-banner.js +20 -2
  242. package/dist/tui/vim-input.js +267 -0
  243. package/docs/examples/codegraph.mcp.json +10 -0
  244. package/package.json +12 -6
  245. package/test/scenarios/codegen-create-file.scenario.txt +13 -0
  246. package/test/scenarios/compact-force.scenario.txt +11 -0
  247. package/test/scenarios/identity.scenario.txt +11 -0
  248. package/test/scenarios/persona-handoff.scenario.txt +11 -0
  249. package/test/scenarios/walkback.scenario.txt +12 -0
  250. package/dist/core/engine/compaction-hook.js +0 -154
@@ -0,0 +1,229 @@
1
+ /**
2
+ * `agent` tool — β2 S3 (2026-05-26).
3
+ *
4
+ * Exposes the subagent spawn primitive as a first-class tool call so
5
+ * the root Mira persona (or any orchestrator-capable parent loop) can
6
+ * delegate a brief to a specialist child via the standard tool-use
7
+ * grammar instead of via the legacy `<pugi-delegate>` XML sidechannel.
8
+ *
9
+ * Grammar:
10
+ *
11
+ * {
12
+ * "role": "coder" | "verifier" | "reviewer" | "researcher" | ...,
13
+ * "brief": "one-paragraph task description",
14
+ * "isolation": "worktree" | "shared_fs" | "auto" // optional, default "auto"
15
+ * }
16
+ *
17
+ * Returns a JSON envelope:
18
+ *
19
+ * {
20
+ * "ok": true,
21
+ * "taskId": "subagent-<uuid>",
22
+ * "role": "coder",
23
+ * "personaSlug": "dev",
24
+ * "status": "shipped" | "blocked" | "failed",
25
+ * "summary": "...",
26
+ * "filesChanged": ["src/...", "src/..."],
27
+ * "toolCallCount": N,
28
+ * "tokensIn": N,
29
+ * "tokensOut": N,
30
+ * "durationMs": N,
31
+ * "worktreePath": "/path/.pugi/worktrees/<uuid>" // only when worktree isolation used
32
+ * }
33
+ *
34
+ * Why expose this as a tool rather than baking it into the engine
35
+ * loop directly:
36
+ *
37
+ * - The model's existing tool-use grammar is what every modern Anvil
38
+ * provider speaks natively. Wrapping delegation as a tool means the
39
+ * model can decide WHEN to spawn a child the same way it decides
40
+ * when to read/edit/bash — no special-case prompt engineering.
41
+ * - The `agent` tool is gated by the isolation-matrix capability map
42
+ * (only `orchestrator`-class roles see it in their tools schema).
43
+ * A coder/reviewer/verifier cannot recursively spawn grandchildren
44
+ * because they never see the `agent` tool in the first place.
45
+ * - The audit log threads cleanly: parent's `tool_call: agent(...)`
46
+ * pairs with the child's `subagent.spawned/tool_call/completed`
47
+ * events, and a single SSE replay yields the full tree.
48
+ */
49
+ import { z } from 'zod';
50
+ import { randomUUID } from 'node:crypto';
51
+ import { relative as relativePath } from 'node:path';
52
+ import { spawnSubagentWithOutcome } from '../core/subagents/spawn.js';
53
+ import { inheritCacheContext } from '../core/dispatch/cache-handoff.js';
54
+ /**
55
+ * Argument schema. `isolation: 'auto'` defers to the role-default
56
+ * isolation tier (set by `isolationForRole` in dispatcher.ts). The
57
+ * explicit `worktree` opt-in forces worktree isolation even for roles
58
+ * whose default is `shared_fs_serialized`; `shared_fs` does the
59
+ * inverse (forces shared-fs even for roles whose default is `worktree`).
60
+ *
61
+ * The role enum mirrors the SDK's SubagentRole — keep both in lockstep.
62
+ *
63
+ * Leak P0 L2 (2026-05-27): `z.strictObject` rejects ANY additional or
64
+ * aliased fields at parse time. Matches the openclaude FileEditTool /
65
+ * FileWriteTool posture (research memo §1.1). The model-facing JSON
66
+ * schema already declares `additionalProperties: false`; the strict
67
+ * Zod variant is defense-in-depth — if the bridge ever bypasses the
68
+ * model-side gate (raw test fixture, internal dispatch), the runtime
69
+ * still refuses unknown keys instead of silently dropping them.
70
+ */
71
+ export const agentToolArgsSchema = z.strictObject({
72
+ role: z.enum([
73
+ 'orchestrator',
74
+ 'architect',
75
+ 'coder',
76
+ 'verifier',
77
+ 'reviewer',
78
+ 'researcher',
79
+ 'release',
80
+ 'devops',
81
+ 'design_qa',
82
+ ]).describe('SubagentRole — selects persona + isolation tier.'),
83
+ brief: z
84
+ .string()
85
+ .min(1, 'brief must not be empty')
86
+ .max(8000, 'brief must be ≤ 8000 chars')
87
+ .describe('One-paragraph task description forwarded to the child as the user prompt. '
88
+ + 'Be concrete: include filenames, expected behavior, and acceptance criteria.'),
89
+ isolation: z
90
+ .enum(['worktree', 'shared_fs', 'auto'])
91
+ .optional()
92
+ .describe('Optional override. `worktree` forces a scratch git worktree for write isolation; '
93
+ + '`shared_fs` forces same-tree execution; `auto` (default) defers to the role tier.'),
94
+ });
95
+ /**
96
+ * Dispatch a subagent via the `agent` tool. Returns the JSON envelope
97
+ * the executor wraps into the tool result frame. Throws when the
98
+ * arguments fail schema validation — the executor catches and feeds
99
+ * the message back to the model so it can correct itself.
100
+ */
101
+ export async function agentTool(args, ctx) {
102
+ const validated = agentToolArgsSchema.parse(args);
103
+ if (!ctx.engineClient) {
104
+ // Hard refusal: the `agent` tool is real-backend-only. Surfacing a
105
+ // structured envelope (instead of throwing) lets the model decide
106
+ // whether to abandon the delegation or to fall back to in-process
107
+ // work. Throwing here would terminate the parent loop on a tool
108
+ // error frame, which is the wrong UX when the issue is config.
109
+ return {
110
+ ok: false,
111
+ taskId: `subagent-rejected-${randomUUID()}`,
112
+ role: validated.role,
113
+ personaSlug: '',
114
+ status: 'failed',
115
+ summary: 'agent tool unavailable: no engine client wired through the parent dispatch. '
116
+ + 'Run pugi via the standard CLI entrypoints; the in-memory test harness does '
117
+ + 'not currently support real subagent spawn.',
118
+ filesChanged: [],
119
+ toolCallCount: 0,
120
+ tokensIn: 0,
121
+ tokensOut: 0,
122
+ durationMs: 0,
123
+ };
124
+ }
125
+ // β2 S10 pre-flight (best-effort): refuse the spawn if the child's
126
+ // role-default token budget exceeds the parent's remaining budget.
127
+ // The check is conservative — it uses the child's DEFAULT envelope
128
+ // because we do not know the actual run cost ahead of time. Roles
129
+ // can downscale via SubagentTask.budget overrides; this gate just
130
+ // catches the gross case (parent has 5k left, child default 80k).
131
+ if (ctx.parentBudgetRemaining?.tokens !== undefined) {
132
+ const { budgetForRole } = await import('../core/subagents/dispatcher.js');
133
+ const childDefault = budgetForRole(validated.role, undefined);
134
+ if (childDefault.tokens > ctx.parentBudgetRemaining.tokens) {
135
+ return {
136
+ ok: false,
137
+ taskId: `subagent-budget-refused-${randomUUID()}`,
138
+ role: validated.role,
139
+ personaSlug: '',
140
+ status: 'blocked',
141
+ summary: `agent spawn refused: child '${validated.role}' default budget is ${childDefault.tokens} tokens `
142
+ + `but parent has only ${ctx.parentBudgetRemaining.tokens} tokens remaining. `
143
+ + 'Tighten the child task budget or finish the parent first.',
144
+ filesChanged: [],
145
+ toolCallCount: 0,
146
+ tokensIn: 0,
147
+ tokensOut: 0,
148
+ durationMs: 0,
149
+ };
150
+ }
151
+ }
152
+ const task = {
153
+ id: `subagent-${randomUUID()}`,
154
+ role: validated.role,
155
+ prompt: validated.brief,
156
+ // `auto` permission mode matches the parent loop's default; the
157
+ // isolation-matrix capability gate provides the load-bearing
158
+ // restriction layer regardless of permissionMode.
159
+ permissionMode: 'auto',
160
+ };
161
+ // L10 (2026-05-27): synthesize a prompt-cache inheritance handle for
162
+ // the child before we dispatch. The handle is persisted under
163
+ // `.pugi/cache-refs/<childAgentId>.json` so:
164
+ // - The child engine loop's first turn (dispatcher-real.ts) can
165
+ // forward parent_cache_id onto Anvil — provider-dependent honour
166
+ // (Anthropic cache_control breakpoints today; OpenAI/Gemini
167
+ // silently ignore until Anvil grows per-provider adapters).
168
+ // - Operators can introspect via `pugi dispatch list-cache-refs`.
169
+ // - `pugi dispatch clear-cache-refs --older-than 1h` can GC after
170
+ // a long session.
171
+ // Failure to persist must NOT block the dispatch — the handle is a
172
+ // best-effort optimisation; if disk is full or the workspace root is
173
+ // read-only, we degrade silently to a cache-miss dispatch.
174
+ try {
175
+ inheritCacheContext(ctx.session.id, task.id, {
176
+ workspaceRoot: ctx.session.root,
177
+ ...(ctx.now ? { now: ctx.now } : {}),
178
+ });
179
+ }
180
+ catch {
181
+ // Silent degrade: cache inheritance is forward-compat, not load-bearing.
182
+ }
183
+ const useWorktree = validated.isolation === 'worktree'
184
+ ? true
185
+ : validated.isolation === 'shared_fs'
186
+ ? false
187
+ : undefined; // 'auto' → defer to role default
188
+ const outcome = await spawnSubagentWithOutcome(task, ctx.session, {
189
+ engineClient: ctx.engineClient,
190
+ ...(useWorktree !== undefined ? { useWorktreeIsolation: useWorktree } : {}),
191
+ });
192
+ const envelope = {
193
+ // `ok` = subagent did not crash. Both `shipped` (real work) and
194
+ // `replied` (text-only completion, added 2026-05-26) count as
195
+ // non-crash outcomes; the caller can branch on the explicit
196
+ // `status` field below if it needs to distinguish them.
197
+ ok: outcome.result.status === 'shipped' || outcome.result.status === 'replied',
198
+ taskId: outcome.result.taskId,
199
+ role: outcome.result.role,
200
+ personaSlug: outcome.result.personaSlug,
201
+ status: outcome.result.status,
202
+ summary: outcome.result.summary,
203
+ filesChanged: outcome.result.filesChanged,
204
+ toolCallCount: outcome.result.toolCallCount,
205
+ tokensIn: outcome.result.tokensIn,
206
+ tokensOut: outcome.result.tokensOut,
207
+ durationMs: outcome.result.durationMs,
208
+ };
209
+ if (outcome.worktreeHandle) {
210
+ // β2a r2 (Codex P1, 2026-05-26): emit the worktree path RELATIVE to
211
+ // the parent session's workspace root. The envelope is JSON-stringified
212
+ // into the parent loop's tool_result frame and from there flows to the
213
+ // provider on every subsequent assistant turn — shipping the absolute
214
+ // path (`/Users/<operator>/Web/.../.pugi/worktrees/<uuid>`) leaks the
215
+ // operator's home directory to the upstream provider on every spawn.
216
+ //
217
+ // The composeSummary path (dispatcher-real.ts §β2a r1) already scrubs
218
+ // the summary text via the same `relative()` wrapping; this is the
219
+ // matching fix for the structured envelope field that r1 missed.
220
+ // The relative form (`.pugi/worktrees/<uuid>`) is enough for the
221
+ // operator's local `pugi worktree promote/drop` commands which run
222
+ // resolved against ctx.session.root anyway.
223
+ const relPath = relativePath(ctx.session.root, outcome.worktreeHandle.path)
224
+ || outcome.worktreeHandle.path;
225
+ envelope.worktreePath = relPath;
226
+ }
227
+ return envelope;
228
+ }
229
+ //# sourceMappingURL=agent-tool.js.map