very-happy-cli 0.2.90 → 0.2.91

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 (31) hide show
  1. package/dist/{AcpBackend-BV4wSnJ3.mjs → AcpBackend-B5RRlzLU.mjs} +1 -1
  2. package/dist/{AcpBackend-CnYZFdd0.cjs → AcpBackend-GqveWg8u.cjs} +1 -1
  3. package/dist/{AcpSessionManager-Cyne6Rmg.mjs → AcpSessionManager-Ij1pI5Ex.mjs} +1 -1
  4. package/dist/{AcpSessionManager-BPBdrrME.cjs → AcpSessionManager-YcrSZwvq.cjs} +1 -1
  5. package/dist/{config-CgXitj0f.cjs → config-C4NCw7Dz.cjs} +2 -2
  6. package/dist/{config-BEdyyciP.mjs → config-ra8iKxdU.mjs} +2 -2
  7. package/dist/{index-B1wTVXjt.cjs → index-C1HIm7NY.cjs} +4 -4
  8. package/dist/{index-Dfu5uvjk.mjs → index-CB5H7YI6.mjs} +5 -5
  9. package/dist/{index-4YmVbx7j.cjs → index-FkXJNwiy.cjs} +87 -31
  10. package/dist/{index-an09rejO.mjs → index-UCYD5Wk3.mjs} +84 -28
  11. package/dist/index.cjs +2 -2
  12. package/dist/index.mjs +2 -2
  13. package/dist/{installTerminalHooks-DDpVxk8-.cjs → installTerminalHooks-CoK5wNcA.cjs} +2 -2
  14. package/dist/{installTerminalHooks-C-OgZr5k.mjs → installTerminalHooks-TkkGzzbI.mjs} +2 -2
  15. package/dist/lib.cjs +1 -1
  16. package/dist/lib.d.cts +34 -0
  17. package/dist/lib.d.mts +34 -0
  18. package/dist/lib.mjs +1 -1
  19. package/dist/{mcp-Du-N0qlK.mjs → mcp-C3MiqObi.mjs} +2 -2
  20. package/dist/{mcp-B6Nq-RUL.cjs → mcp-DcRvswVI.cjs} +2 -2
  21. package/dist/{runGemini-DBr_TiTL.mjs → runGemini-BbC0uwUj.mjs} +4 -4
  22. package/dist/{runGemini-ChG7cGMC.cjs → runGemini-Dnvd2gWq.cjs} +4 -4
  23. package/dist/{runOpenClaw-Cbde8t92.mjs → runOpenClaw--nbqTW3K.mjs} +3 -3
  24. package/dist/{runOpenClaw-D2jtVgpC.cjs → runOpenClaw-CnuTBNQW.cjs} +3 -3
  25. package/dist/{send-BHliX59m.mjs → send-9nJxn09Y.mjs} +2 -2
  26. package/dist/{send-Bjen1TUE.cjs → send-DkKOPatx.cjs} +2 -2
  27. package/dist/{spawn-JxaPHAoP.mjs → spawn-CRW4ioms.mjs} +2 -2
  28. package/dist/{spawn-CH1Rq-LW.cjs → spawn-DE7WhS8Y.cjs} +2 -2
  29. package/dist/{types-DS3i_5LV.mjs → types-BKyjG23_.mjs} +251 -15
  30. package/dist/{types-BNGeiP1C.cjs → types-ClDADuxP.cjs} +252 -16
  31. package/package.json +7 -7
@@ -29,7 +29,7 @@ import { SandboxManager } from '@anthropic-ai/sandbox-runtime';
29
29
  import { Expo } from 'expo-server-sdk';
30
30
 
31
31
  var name = "very-happy-cli";
32
- var version = "0.2.90";
32
+ var version = "0.2.91";
33
33
  var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
34
34
  var author = "Kirill Dubovitskiy";
35
35
  var contributors = [
@@ -142,12 +142,12 @@ var dependencies = {
142
142
  zod: "^4.0.0"
143
143
  };
144
144
  var optionalDependencies = {
145
- "very-happy-tools-arm64-darwin": "0.2.90",
146
- "very-happy-tools-x64-darwin": "0.2.90",
147
- "very-happy-tools-arm64-linux": "0.2.90",
148
- "very-happy-tools-x64-linux": "0.2.90",
149
- "very-happy-tools-arm64-win32": "0.2.90",
150
- "very-happy-tools-x64-win32": "0.2.90"
145
+ "very-happy-tools-arm64-darwin": "0.2.91",
146
+ "very-happy-tools-x64-darwin": "0.2.91",
147
+ "very-happy-tools-arm64-linux": "0.2.91",
148
+ "very-happy-tools-x64-linux": "0.2.91",
149
+ "very-happy-tools-arm64-win32": "0.2.91",
150
+ "very-happy-tools-x64-win32": "0.2.91"
151
151
  };
152
152
  var devDependencies = {
153
153
  "@slopus/happy-wire": "workspace:*",
@@ -639,9 +639,27 @@ const sessionToolCallStartEventSchema = z.object({
639
639
  description: z.string(),
640
640
  args: z.record(z.string(), z.unknown())
641
641
  });
642
+ const sessionSubagentResultSchema = z.object({
643
+ text: z.string(),
644
+ truncated: z.boolean().optional()
645
+ });
646
+ const sessionSubagentUsageSchema = z.object({
647
+ toolUses: z.number().optional(),
648
+ totalTokens: z.number().optional(),
649
+ durationMs: z.number().optional()
650
+ });
642
651
  const sessionToolCallEndEventSchema = z.object({
643
652
  t: z.literal("tool-call-end"),
644
- call: z.string()
653
+ call: z.string(),
654
+ // Foreground Agent/Task completion: the sub-agent's final report + run
655
+ // totals (SDK `tool_use_result`). Absent for ordinary tools and for the
656
+ // background stub ("Async agent launched").
657
+ result: sessionSubagentResultSchema.extend({
658
+ isError: z.boolean().optional(),
659
+ stats: sessionSubagentUsageSchema.extend({
660
+ toolStats: z.record(z.string(), z.unknown()).optional()
661
+ }).optional()
662
+ }).optional()
645
663
  });
646
664
  const sessionFileEventSchema = z.object({
647
665
  t: z.literal("file"),
@@ -660,7 +678,10 @@ const sessionTurnStartEventSchema = z.object({
660
678
  });
661
679
  const sessionStartEventSchema = z.object({
662
680
  t: z.literal("start"),
663
- title: z.string().optional()
681
+ title: z.string().optional(),
682
+ // B-260-P2: identity from SDK task_started / Agent tool input.
683
+ description: z.string().optional(),
684
+ subagentType: z.string().optional()
664
685
  });
665
686
  const sessionTurnEndStatusSchema = z.enum(["completed", "failed", "cancelled"]);
666
687
  const sessionTurnUsageSchema = z.object({
@@ -683,7 +704,21 @@ const sessionTurnEndEventSchema = z.object({
683
704
  usage: sessionTurnUsageSchema.optional()
684
705
  });
685
706
  const sessionStopEventSchema = z.object({
686
- t: z.literal("stop")
707
+ t: z.literal("stop"),
708
+ // B-260-P2: from SDK task_notification. A second `stop` for the same
709
+ // subagent may follow carrying `result` once the notification user message
710
+ // (which holds the <result> block) arrives; consumers fold by subagent id.
711
+ status: z.enum(["completed", "failed", "stopped"]).optional(),
712
+ result: sessionSubagentResultSchema.optional(),
713
+ usage: sessionSubagentUsageSchema.optional()
714
+ });
715
+ const sessionProgressEventSchema = z.object({
716
+ t: z.literal("progress"),
717
+ toolUses: z.number(),
718
+ lastTool: z.string().optional(),
719
+ totalTokens: z.number().optional(),
720
+ durationMs: z.number().optional(),
721
+ summary: z.string().optional()
687
722
  });
688
723
  const sessionEventSchema = z.discriminatedUnion("t", [
689
724
  sessionTextEventSchema,
@@ -694,7 +729,8 @@ const sessionEventSchema = z.discriminatedUnion("t", [
694
729
  sessionTurnStartEventSchema,
695
730
  sessionStartEventSchema,
696
731
  sessionTurnEndEventSchema,
697
- sessionStopEventSchema
732
+ sessionStopEventSchema,
733
+ sessionProgressEventSchema
698
734
  ]);
699
735
  const sessionEnvelopeSchema = z.object({
700
736
  id: z.string(),
@@ -725,7 +761,14 @@ const sessionEnvelopeSchema = z.object({
725
761
  path: ["role"]
726
762
  });
727
763
  }
728
- if ((envelope.ev.t === "start" || envelope.ev.t === "stop") && envelope.role !== "agent") {
764
+ if (envelope.ev.t === "progress" && !envelope.subagent) {
765
+ ctx.addIssue({
766
+ code: z.ZodIssueCode.custom,
767
+ message: "progress events must carry a subagent",
768
+ path: ["subagent"]
769
+ });
770
+ }
771
+ if ((envelope.ev.t === "start" || envelope.ev.t === "stop" || envelope.ev.t === "progress") && envelope.role !== "agent") {
729
772
  ctx.addIssue({
730
773
  code: z.ZodIssueCode.custom,
731
774
  message: `${envelope.ev.t} events must use role "agent"`,
@@ -2149,6 +2192,69 @@ function shouldReconnect() {
2149
2192
  return true;
2150
2193
  }
2151
2194
 
2195
+ const SUBAGENT_RESULT_MAX_CHARS = 16384;
2196
+ const SUBAGENT_PROGRESS_MIN_INTERVAL_MS = 5e3;
2197
+ function capSubagentText(text, max = SUBAGENT_RESULT_MAX_CHARS) {
2198
+ const trimmed = text.trim();
2199
+ if (trimmed.length <= max) return { text: trimmed };
2200
+ return { text: trimmed.slice(0, max), truncated: true };
2201
+ }
2202
+ function toolUseResultToText(toolUseResult) {
2203
+ if (!toolUseResult || typeof toolUseResult !== "object") return null;
2204
+ const content = toolUseResult.content;
2205
+ if (typeof content === "string") return content;
2206
+ if (!Array.isArray(content)) return null;
2207
+ const parts = [];
2208
+ for (const block of content) {
2209
+ if (block && typeof block === "object" && block.type === "text" && typeof block.text === "string") {
2210
+ parts.push(block.text);
2211
+ }
2212
+ }
2213
+ return parts.length > 0 ? parts.join("\n") : null;
2214
+ }
2215
+ function toolUseResultStatus(toolUseResult) {
2216
+ if (!toolUseResult || typeof toolUseResult !== "object") return "unknown";
2217
+ const status = toolUseResult.status;
2218
+ if (status === "async_launched") return "async_launched";
2219
+ if (status === "completed") return "completed";
2220
+ return "unknown";
2221
+ }
2222
+ function toolUseResultStats(toolUseResult) {
2223
+ if (!toolUseResult || typeof toolUseResult !== "object") return void 0;
2224
+ const r = toolUseResult;
2225
+ const stats = {};
2226
+ if (typeof r.totalToolUseCount === "number") stats.toolUses = r.totalToolUseCount;
2227
+ if (typeof r.totalTokens === "number") stats.totalTokens = r.totalTokens;
2228
+ if (typeof r.totalDurationMs === "number") stats.durationMs = r.totalDurationMs;
2229
+ if (r.toolStats && typeof r.toolStats === "object") stats.toolStats = r.toolStats;
2230
+ return Object.keys(stats).length > 0 ? stats : void 0;
2231
+ }
2232
+ function parseTaskNotificationText(text) {
2233
+ if (!/<task-notification>/i.test(text)) return null;
2234
+ const pick = (tag) => text.match(new RegExp(`<${tag}>([\\s\\S]*?)</${tag}>`, "i"))?.[1] ?? null;
2235
+ const rawStatus = pick("status")?.trim().toLowerCase() ?? null;
2236
+ const status = rawStatus === "completed" || rawStatus === "failed" || rawStatus === "stopped" ? rawStatus : null;
2237
+ let resultText = pick("result");
2238
+ let result = null;
2239
+ if (resultText !== null) {
2240
+ resultText = resultText.replace(/^\s*\[harness:[^\]]*\]\s*/i, "").replace(/<usage>[\s\S]*?<\/usage>/gi, "").trim();
2241
+ if (resultText.length > 0) result = capSubagentText(resultText);
2242
+ }
2243
+ return {
2244
+ toolUseId: pick("tool-use-id")?.trim() || null,
2245
+ taskId: pick("task-id")?.trim() || null,
2246
+ status,
2247
+ summary: pick("summary")?.trim() || null,
2248
+ result
2249
+ };
2250
+ }
2251
+ function shouldEmitProgress(previous, toolUses, now) {
2252
+ if (!previous) return true;
2253
+ if (previous.lastToolUses === toolUses) return false;
2254
+ return now - previous.lastAt >= SUBAGENT_PROGRESS_MIN_INTERVAL_MS;
2255
+ }
2256
+
2257
+ const SUBAGENT_BUFFER_MAX_MESSAGES = 100;
2152
2258
  function isSubagentTool(name) {
2153
2259
  return name === "Task" || name === "Agent";
2154
2260
  }
@@ -2217,6 +2323,7 @@ function bufferSubagentMessage(state, subagent, message) {
2217
2323
  const buffer = getBufferedSubagentMessages(state);
2218
2324
  const queue = buffer.get(subagent) ?? [];
2219
2325
  queue.push(message);
2326
+ while (queue.length > SUBAGENT_BUFFER_MAX_MESSAGES) queue.shift();
2220
2327
  buffer.set(subagent, queue);
2221
2328
  }
2222
2329
  function consumeBufferedSubagentMessages(state, subagent) {
@@ -2237,6 +2344,31 @@ function getActiveSubagents(state) {
2237
2344
  }
2238
2345
  return state.activeSubagents;
2239
2346
  }
2347
+ function getAgentToolCalls(state) {
2348
+ if (!state.agentToolCalls) state.agentToolCalls = /* @__PURE__ */ new Set();
2349
+ return state.agentToolCalls;
2350
+ }
2351
+ function getSubagentMeta(state) {
2352
+ if (!state.subagentMeta) state.subagentMeta = /* @__PURE__ */ new Map();
2353
+ return state.subagentMeta;
2354
+ }
2355
+ function getStubSubagents(state) {
2356
+ if (!state.stubSubagents) state.stubSubagents = /* @__PURE__ */ new Set();
2357
+ return state.stubSubagents;
2358
+ }
2359
+ function getProgressThrottle(state) {
2360
+ if (!state.progressThrottle) state.progressThrottle = /* @__PURE__ */ new Map();
2361
+ return state.progressThrottle;
2362
+ }
2363
+ function nowOf(state) {
2364
+ return state.now ? state.now() : Date.now();
2365
+ }
2366
+ function rememberSubagentMeta(state, subagent, meta) {
2367
+ const existing = getSubagentMeta(state).get(subagent) ?? {};
2368
+ const description = typeof meta.description === "string" && meta.description.trim() ? meta.description.trim() : existing.description;
2369
+ const subagentType = typeof meta.subagentType === "string" && meta.subagentType.trim() ? meta.subagentType.trim() : existing.subagentType;
2370
+ getSubagentMeta(state).set(subagent, { ...description ? { description } : {}, ...subagentType ? { subagentType } : {} });
2371
+ }
2240
2372
  function pickAssistantUsage(message) {
2241
2373
  if (message.type !== "assistant") return void 0;
2242
2374
  const usage = message.message?.usage;
@@ -2413,13 +2545,26 @@ function maybeEmitSubagentStart(state, turn, subagent, envelopes) {
2413
2545
  return;
2414
2546
  }
2415
2547
  const title = getSubagentTitles(state).get(subagent);
2548
+ const meta = getSubagentMeta(state).get(subagent);
2416
2549
  envelopes.push(createEnvelope("agent", {
2417
2550
  t: "start",
2418
- ...title ? { title } : {}
2551
+ ...title ? { title } : {},
2552
+ ...meta?.description ? { description: meta.description } : {},
2553
+ ...meta?.subagentType ? { subagentType: meta.subagentType } : {}
2419
2554
  }, { turn, subagent }));
2420
2555
  started.add(subagent);
2421
2556
  getActiveSubagents(state).add(subagent);
2422
2557
  }
2558
+ function emitSubagentStopWithStatus(state, turn, subagent, envelopes, payload) {
2559
+ envelopes.push(createEnvelope("agent", {
2560
+ t: "stop",
2561
+ ...payload.status ? { status: payload.status } : {},
2562
+ ...payload.result ? { result: payload.result } : {},
2563
+ ...payload.usage ? { usage: payload.usage } : {}
2564
+ }, { ...turn ? { turn } : {}, subagent }));
2565
+ getActiveSubagents(state).delete(subagent);
2566
+ getStartedSubagents(state).delete(subagent);
2567
+ }
2423
2568
  function maybeEmitSubagentStop(state, turn, subagent, envelopes) {
2424
2569
  const active = getActiveSubagents(state);
2425
2570
  if (!active.has(subagent)) {
@@ -2431,8 +2576,6 @@ function maybeEmitSubagentStop(state, turn, subagent, envelopes) {
2431
2576
  function clearSubagentTracking(state) {
2432
2577
  getUuidToProviderSubagent(state).clear();
2433
2578
  getTaskPromptToSubagents(state).clear();
2434
- getProviderSubagentToSessionSubagent(state).clear();
2435
- getSubagentTitles(state).clear();
2436
2579
  getBufferedSubagentMessages(state).clear();
2437
2580
  getHiddenParentToolCalls(state).clear();
2438
2581
  getStartedSubagents(state).clear();
@@ -2493,6 +2636,58 @@ function closeClaudeTurnWithStatus(state, status, meta) {
2493
2636
  function mapClaudeLogMessageToSessionEnvelopes(message, state) {
2494
2637
  return mapClaudeLogMessageToSessionEnvelopesInternal(message, state);
2495
2638
  }
2639
+ function mapTaskLifecycleSystemMessage(message, state, envelopes) {
2640
+ const raw = message;
2641
+ const subtype = typeof raw.subtype === "string" ? raw.subtype : "";
2642
+ if (!subtype.startsWith("task_")) return;
2643
+ if (raw.skip_transcript === true) return;
2644
+ const toolUseId = typeof raw.tool_use_id === "string" && raw.tool_use_id.length > 0 ? raw.tool_use_id : null;
2645
+ if (!toolUseId || !getAgentToolCalls(state).has(toolUseId)) return;
2646
+ const subagent = ensureSessionSubagentIdForProviderSubagent(state, toolUseId);
2647
+ const usage = raw.usage && typeof raw.usage === "object" ? {
2648
+ ...typeof raw.usage.tool_uses === "number" ? { toolUses: raw.usage.tool_uses } : {},
2649
+ ...typeof raw.usage.total_tokens === "number" ? { totalTokens: raw.usage.total_tokens } : {},
2650
+ ...typeof raw.usage.duration_ms === "number" ? { durationMs: raw.usage.duration_ms } : {}
2651
+ } : void 0;
2652
+ if (subtype === "task_started") {
2653
+ rememberSubagentMeta(state, subagent, { description: raw.description, subagentType: raw.subagent_type });
2654
+ const turn = ensureTurn(state, envelopes);
2655
+ getStartedSubagents(state).delete(subagent);
2656
+ maybeEmitSubagentStart(state, turn, subagent, envelopes);
2657
+ return;
2658
+ }
2659
+ if (subtype === "task_progress") {
2660
+ const toolUses = typeof raw.usage?.tool_uses === "number" ? raw.usage.tool_uses : 0;
2661
+ const throttle = getProgressThrottle(state);
2662
+ const now = nowOf(state);
2663
+ if (!shouldEmitProgress(throttle.get(subagent), toolUses, now)) return;
2664
+ throttle.set(subagent, { lastAt: now, lastToolUses: toolUses });
2665
+ const turn = ensureTurn(state, envelopes);
2666
+ maybeEmitSubagentStart(state, turn, subagent, envelopes);
2667
+ envelopes.push(createEnvelope("agent", {
2668
+ t: "progress",
2669
+ toolUses,
2670
+ ...typeof raw.last_tool_name === "string" && raw.last_tool_name ? { lastTool: raw.last_tool_name } : {},
2671
+ ...usage?.totalTokens !== void 0 ? { totalTokens: usage.totalTokens } : {},
2672
+ ...usage?.durationMs !== void 0 ? { durationMs: usage.durationMs } : {},
2673
+ ...typeof raw.summary === "string" && raw.summary.trim() ? { summary: raw.summary.trim() } : {}
2674
+ }, { turn, subagent }));
2675
+ return;
2676
+ }
2677
+ if (subtype === "task_notification") {
2678
+ const status = raw.status === "completed" || raw.status === "failed" || raw.status === "stopped" ? raw.status : "completed";
2679
+ emitSubagentStopWithStatus(state, state.currentTurnId ?? void 0, subagent, envelopes, {
2680
+ status,
2681
+ ...usage ? { usage } : {}
2682
+ });
2683
+ getStubSubagents(state).delete(subagent);
2684
+ getProgressThrottle(state).delete(subagent);
2685
+ return;
2686
+ }
2687
+ if (subtype === "task_updated" && raw.patch?.is_backgrounded === true) {
2688
+ getStubSubagents(state).add(subagent);
2689
+ }
2690
+ }
2496
2691
  function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
2497
2692
  const envelopes = [];
2498
2693
  const claudeUuid = pickUuid(message);
@@ -2513,6 +2708,7 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
2513
2708
  };
2514
2709
  }
2515
2710
  if (message.type === "system") {
2711
+ mapTaskLifecycleSystemMessage(message, state, envelopes);
2516
2712
  return {
2517
2713
  currentTurnId: state.currentTurnId,
2518
2714
  envelopes
@@ -2554,6 +2750,9 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
2554
2750
  queueTaskPromptSubagent(state, prompt, call);
2555
2751
  }
2556
2752
  setSubagentTitle(state, sessionSubagentForCall, pickTaskTitle(block.input) ?? prompt);
2753
+ getAgentToolCalls(state).add(call);
2754
+ const input = block.input ?? {};
2755
+ rememberSubagentMeta(state, sessionSubagentForCall, { description: input.description, subagentType: input.subagent_type });
2557
2756
  }
2558
2757
  if (shouldHideParentToolCall(name)) {
2559
2758
  getHiddenParentToolCalls(state).add(call);
@@ -2598,6 +2797,18 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
2598
2797
  maybeEmitSubagentStart(state, turnId2, subagent, envelopes);
2599
2798
  envelopes.push(createEnvelope("agent", { t: "text", text: message.message.content }, { turn: turnId2, subagent, claudeUuid }));
2600
2799
  } else {
2800
+ const origin = message.origin;
2801
+ if (origin?.kind === "task-notification" || /<task-notification>/i.test(message.message.content)) {
2802
+ const fields = parseTaskNotificationText(message.message.content);
2803
+ const providerId = fields?.toolUseId ?? null;
2804
+ const subagentForNotification = providerId && getAgentToolCalls(state).has(providerId) ? getSessionSubagentIdForProviderSubagent(state, providerId) : void 0;
2805
+ if (fields && subagentForNotification && (fields.result || fields.status)) {
2806
+ emitSubagentStopWithStatus(state, state.currentTurnId ?? void 0, subagentForNotification, envelopes, {
2807
+ ...fields.status ? { status: fields.status } : {},
2808
+ ...fields.result ? { result: fields.result } : {}
2809
+ });
2810
+ }
2811
+ }
2601
2812
  closeTurn(state, "completed", envelopes);
2602
2813
  envelopes.push(createEnvelope("user", { t: "text", text: message.message.content }, { claudeUuid }));
2603
2814
  }
@@ -2628,6 +2839,31 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
2628
2839
  getHiddenParentToolCalls(state).delete(block.tool_use_id);
2629
2840
  continue;
2630
2841
  }
2842
+ if (sessionSubagentForToolResult && getAgentToolCalls(state).has(block.tool_use_id)) {
2843
+ const toolUseResult = message.tool_use_result;
2844
+ const resultStatus = toolUseResultStatus(toolUseResult);
2845
+ if (resultStatus === "async_launched") {
2846
+ getStubSubagents(state).add(sessionSubagentForToolResult);
2847
+ envelopes.push(createEnvelope("agent", { t: "tool-call-end", call: block.tool_use_id }, { turn: turnId, subagent }));
2848
+ continue;
2849
+ }
2850
+ if (resultStatus === "completed") {
2851
+ const text = toolUseResultToText(toolUseResult);
2852
+ const stats = toolUseResultStats(toolUseResult);
2853
+ const result = text ? capSubagentText(text) : void 0;
2854
+ emitSubagentStopWithStatus(state, turnId, sessionSubagentForToolResult, envelopes, {
2855
+ status: "completed",
2856
+ ...result ? { result } : {},
2857
+ ...stats ? { usage: { toolUses: stats.toolUses, totalTokens: stats.totalTokens, durationMs: stats.durationMs } } : {}
2858
+ });
2859
+ envelopes.push(createEnvelope("agent", {
2860
+ t: "tool-call-end",
2861
+ call: block.tool_use_id,
2862
+ ...result ? { result: { ...result, ...stats ? { stats } : {} } } : {}
2863
+ }, { turn: turnId, subagent }));
2864
+ continue;
2865
+ }
2866
+ }
2631
2867
  if (sessionSubagentForToolResult) {
2632
2868
  maybeEmitSubagentStop(state, turnId, sessionSubagentForToolResult, envelopes);
2633
2869
  }