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.
- package/dist/{AcpBackend-BV4wSnJ3.mjs → AcpBackend-B5RRlzLU.mjs} +1 -1
- package/dist/{AcpBackend-CnYZFdd0.cjs → AcpBackend-GqveWg8u.cjs} +1 -1
- package/dist/{AcpSessionManager-Cyne6Rmg.mjs → AcpSessionManager-Ij1pI5Ex.mjs} +1 -1
- package/dist/{AcpSessionManager-BPBdrrME.cjs → AcpSessionManager-YcrSZwvq.cjs} +1 -1
- package/dist/{config-CgXitj0f.cjs → config-C4NCw7Dz.cjs} +2 -2
- package/dist/{config-BEdyyciP.mjs → config-ra8iKxdU.mjs} +2 -2
- package/dist/{index-B1wTVXjt.cjs → index-C1HIm7NY.cjs} +4 -4
- package/dist/{index-Dfu5uvjk.mjs → index-CB5H7YI6.mjs} +5 -5
- package/dist/{index-4YmVbx7j.cjs → index-FkXJNwiy.cjs} +87 -31
- package/dist/{index-an09rejO.mjs → index-UCYD5Wk3.mjs} +84 -28
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-DDpVxk8-.cjs → installTerminalHooks-CoK5wNcA.cjs} +2 -2
- package/dist/{installTerminalHooks-C-OgZr5k.mjs → installTerminalHooks-TkkGzzbI.mjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +34 -0
- package/dist/lib.d.mts +34 -0
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-Du-N0qlK.mjs → mcp-C3MiqObi.mjs} +2 -2
- package/dist/{mcp-B6Nq-RUL.cjs → mcp-DcRvswVI.cjs} +2 -2
- package/dist/{runGemini-DBr_TiTL.mjs → runGemini-BbC0uwUj.mjs} +4 -4
- package/dist/{runGemini-ChG7cGMC.cjs → runGemini-Dnvd2gWq.cjs} +4 -4
- package/dist/{runOpenClaw-Cbde8t92.mjs → runOpenClaw--nbqTW3K.mjs} +3 -3
- package/dist/{runOpenClaw-D2jtVgpC.cjs → runOpenClaw-CnuTBNQW.cjs} +3 -3
- package/dist/{send-BHliX59m.mjs → send-9nJxn09Y.mjs} +2 -2
- package/dist/{send-Bjen1TUE.cjs → send-DkKOPatx.cjs} +2 -2
- package/dist/{spawn-JxaPHAoP.mjs → spawn-CRW4ioms.mjs} +2 -2
- package/dist/{spawn-CH1Rq-LW.cjs → spawn-DE7WhS8Y.cjs} +2 -2
- package/dist/{types-DS3i_5LV.mjs → types-BKyjG23_.mjs} +251 -15
- package/dist/{types-BNGeiP1C.cjs → types-ClDADuxP.cjs} +252 -16
- package/package.json +7 -7
|
@@ -51,7 +51,7 @@ var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
|
|
|
51
51
|
var pty__namespace = /*#__PURE__*/_interopNamespaceDefault(pty);
|
|
52
52
|
|
|
53
53
|
var name = "very-happy-cli";
|
|
54
|
-
var version = "0.2.
|
|
54
|
+
var version = "0.2.91";
|
|
55
55
|
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
56
56
|
var author = "Kirill Dubovitskiy";
|
|
57
57
|
var contributors = [
|
|
@@ -164,12 +164,12 @@ var dependencies = {
|
|
|
164
164
|
zod: "^4.0.0"
|
|
165
165
|
};
|
|
166
166
|
var optionalDependencies = {
|
|
167
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
168
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
169
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
170
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
171
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
172
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
167
|
+
"very-happy-tools-arm64-darwin": "0.2.91",
|
|
168
|
+
"very-happy-tools-x64-darwin": "0.2.91",
|
|
169
|
+
"very-happy-tools-arm64-linux": "0.2.91",
|
|
170
|
+
"very-happy-tools-x64-linux": "0.2.91",
|
|
171
|
+
"very-happy-tools-arm64-win32": "0.2.91",
|
|
172
|
+
"very-happy-tools-x64-win32": "0.2.91"
|
|
173
173
|
};
|
|
174
174
|
var devDependencies = {
|
|
175
175
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -661,9 +661,27 @@ const sessionToolCallStartEventSchema = z__namespace.object({
|
|
|
661
661
|
description: z__namespace.string(),
|
|
662
662
|
args: z__namespace.record(z__namespace.string(), z__namespace.unknown())
|
|
663
663
|
});
|
|
664
|
+
const sessionSubagentResultSchema = z__namespace.object({
|
|
665
|
+
text: z__namespace.string(),
|
|
666
|
+
truncated: z__namespace.boolean().optional()
|
|
667
|
+
});
|
|
668
|
+
const sessionSubagentUsageSchema = z__namespace.object({
|
|
669
|
+
toolUses: z__namespace.number().optional(),
|
|
670
|
+
totalTokens: z__namespace.number().optional(),
|
|
671
|
+
durationMs: z__namespace.number().optional()
|
|
672
|
+
});
|
|
664
673
|
const sessionToolCallEndEventSchema = z__namespace.object({
|
|
665
674
|
t: z__namespace.literal("tool-call-end"),
|
|
666
|
-
call: z__namespace.string()
|
|
675
|
+
call: z__namespace.string(),
|
|
676
|
+
// Foreground Agent/Task completion: the sub-agent's final report + run
|
|
677
|
+
// totals (SDK `tool_use_result`). Absent for ordinary tools and for the
|
|
678
|
+
// background stub ("Async agent launched").
|
|
679
|
+
result: sessionSubagentResultSchema.extend({
|
|
680
|
+
isError: z__namespace.boolean().optional(),
|
|
681
|
+
stats: sessionSubagentUsageSchema.extend({
|
|
682
|
+
toolStats: z__namespace.record(z__namespace.string(), z__namespace.unknown()).optional()
|
|
683
|
+
}).optional()
|
|
684
|
+
}).optional()
|
|
667
685
|
});
|
|
668
686
|
const sessionFileEventSchema = z__namespace.object({
|
|
669
687
|
t: z__namespace.literal("file"),
|
|
@@ -682,7 +700,10 @@ const sessionTurnStartEventSchema = z__namespace.object({
|
|
|
682
700
|
});
|
|
683
701
|
const sessionStartEventSchema = z__namespace.object({
|
|
684
702
|
t: z__namespace.literal("start"),
|
|
685
|
-
title: z__namespace.string().optional()
|
|
703
|
+
title: z__namespace.string().optional(),
|
|
704
|
+
// B-260-P2: identity from SDK task_started / Agent tool input.
|
|
705
|
+
description: z__namespace.string().optional(),
|
|
706
|
+
subagentType: z__namespace.string().optional()
|
|
686
707
|
});
|
|
687
708
|
const sessionTurnEndStatusSchema = z__namespace.enum(["completed", "failed", "cancelled"]);
|
|
688
709
|
const sessionTurnUsageSchema = z__namespace.object({
|
|
@@ -705,7 +726,21 @@ const sessionTurnEndEventSchema = z__namespace.object({
|
|
|
705
726
|
usage: sessionTurnUsageSchema.optional()
|
|
706
727
|
});
|
|
707
728
|
const sessionStopEventSchema = z__namespace.object({
|
|
708
|
-
t: z__namespace.literal("stop")
|
|
729
|
+
t: z__namespace.literal("stop"),
|
|
730
|
+
// B-260-P2: from SDK task_notification. A second `stop` for the same
|
|
731
|
+
// subagent may follow carrying `result` once the notification user message
|
|
732
|
+
// (which holds the <result> block) arrives; consumers fold by subagent id.
|
|
733
|
+
status: z__namespace.enum(["completed", "failed", "stopped"]).optional(),
|
|
734
|
+
result: sessionSubagentResultSchema.optional(),
|
|
735
|
+
usage: sessionSubagentUsageSchema.optional()
|
|
736
|
+
});
|
|
737
|
+
const sessionProgressEventSchema = z__namespace.object({
|
|
738
|
+
t: z__namespace.literal("progress"),
|
|
739
|
+
toolUses: z__namespace.number(),
|
|
740
|
+
lastTool: z__namespace.string().optional(),
|
|
741
|
+
totalTokens: z__namespace.number().optional(),
|
|
742
|
+
durationMs: z__namespace.number().optional(),
|
|
743
|
+
summary: z__namespace.string().optional()
|
|
709
744
|
});
|
|
710
745
|
const sessionEventSchema = z__namespace.discriminatedUnion("t", [
|
|
711
746
|
sessionTextEventSchema,
|
|
@@ -716,7 +751,8 @@ const sessionEventSchema = z__namespace.discriminatedUnion("t", [
|
|
|
716
751
|
sessionTurnStartEventSchema,
|
|
717
752
|
sessionStartEventSchema,
|
|
718
753
|
sessionTurnEndEventSchema,
|
|
719
|
-
sessionStopEventSchema
|
|
754
|
+
sessionStopEventSchema,
|
|
755
|
+
sessionProgressEventSchema
|
|
720
756
|
]);
|
|
721
757
|
const sessionEnvelopeSchema = z__namespace.object({
|
|
722
758
|
id: z__namespace.string(),
|
|
@@ -747,7 +783,14 @@ const sessionEnvelopeSchema = z__namespace.object({
|
|
|
747
783
|
path: ["role"]
|
|
748
784
|
});
|
|
749
785
|
}
|
|
750
|
-
if (
|
|
786
|
+
if (envelope.ev.t === "progress" && !envelope.subagent) {
|
|
787
|
+
ctx.addIssue({
|
|
788
|
+
code: z__namespace.ZodIssueCode.custom,
|
|
789
|
+
message: "progress events must carry a subagent",
|
|
790
|
+
path: ["subagent"]
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
if ((envelope.ev.t === "start" || envelope.ev.t === "stop" || envelope.ev.t === "progress") && envelope.role !== "agent") {
|
|
751
794
|
ctx.addIssue({
|
|
752
795
|
code: z__namespace.ZodIssueCode.custom,
|
|
753
796
|
message: `${envelope.ev.t} events must use role "agent"`,
|
|
@@ -1484,7 +1527,7 @@ class RpcHandlerManager {
|
|
|
1484
1527
|
}
|
|
1485
1528
|
}
|
|
1486
1529
|
|
|
1487
|
-
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-
|
|
1530
|
+
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-ClDADuxP.cjs', document.baseURI).href))));
|
|
1488
1531
|
function projectPath() {
|
|
1489
1532
|
const path = path$1.resolve(__dirname$1, "..");
|
|
1490
1533
|
return path;
|
|
@@ -2171,6 +2214,69 @@ function shouldReconnect() {
|
|
|
2171
2214
|
return true;
|
|
2172
2215
|
}
|
|
2173
2216
|
|
|
2217
|
+
const SUBAGENT_RESULT_MAX_CHARS = 16384;
|
|
2218
|
+
const SUBAGENT_PROGRESS_MIN_INTERVAL_MS = 5e3;
|
|
2219
|
+
function capSubagentText(text, max = SUBAGENT_RESULT_MAX_CHARS) {
|
|
2220
|
+
const trimmed = text.trim();
|
|
2221
|
+
if (trimmed.length <= max) return { text: trimmed };
|
|
2222
|
+
return { text: trimmed.slice(0, max), truncated: true };
|
|
2223
|
+
}
|
|
2224
|
+
function toolUseResultToText(toolUseResult) {
|
|
2225
|
+
if (!toolUseResult || typeof toolUseResult !== "object") return null;
|
|
2226
|
+
const content = toolUseResult.content;
|
|
2227
|
+
if (typeof content === "string") return content;
|
|
2228
|
+
if (!Array.isArray(content)) return null;
|
|
2229
|
+
const parts = [];
|
|
2230
|
+
for (const block of content) {
|
|
2231
|
+
if (block && typeof block === "object" && block.type === "text" && typeof block.text === "string") {
|
|
2232
|
+
parts.push(block.text);
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
return parts.length > 0 ? parts.join("\n") : null;
|
|
2236
|
+
}
|
|
2237
|
+
function toolUseResultStatus(toolUseResult) {
|
|
2238
|
+
if (!toolUseResult || typeof toolUseResult !== "object") return "unknown";
|
|
2239
|
+
const status = toolUseResult.status;
|
|
2240
|
+
if (status === "async_launched") return "async_launched";
|
|
2241
|
+
if (status === "completed") return "completed";
|
|
2242
|
+
return "unknown";
|
|
2243
|
+
}
|
|
2244
|
+
function toolUseResultStats(toolUseResult) {
|
|
2245
|
+
if (!toolUseResult || typeof toolUseResult !== "object") return void 0;
|
|
2246
|
+
const r = toolUseResult;
|
|
2247
|
+
const stats = {};
|
|
2248
|
+
if (typeof r.totalToolUseCount === "number") stats.toolUses = r.totalToolUseCount;
|
|
2249
|
+
if (typeof r.totalTokens === "number") stats.totalTokens = r.totalTokens;
|
|
2250
|
+
if (typeof r.totalDurationMs === "number") stats.durationMs = r.totalDurationMs;
|
|
2251
|
+
if (r.toolStats && typeof r.toolStats === "object") stats.toolStats = r.toolStats;
|
|
2252
|
+
return Object.keys(stats).length > 0 ? stats : void 0;
|
|
2253
|
+
}
|
|
2254
|
+
function parseTaskNotificationText(text) {
|
|
2255
|
+
if (!/<task-notification>/i.test(text)) return null;
|
|
2256
|
+
const pick = (tag) => text.match(new RegExp(`<${tag}>([\\s\\S]*?)</${tag}>`, "i"))?.[1] ?? null;
|
|
2257
|
+
const rawStatus = pick("status")?.trim().toLowerCase() ?? null;
|
|
2258
|
+
const status = rawStatus === "completed" || rawStatus === "failed" || rawStatus === "stopped" ? rawStatus : null;
|
|
2259
|
+
let resultText = pick("result");
|
|
2260
|
+
let result = null;
|
|
2261
|
+
if (resultText !== null) {
|
|
2262
|
+
resultText = resultText.replace(/^\s*\[harness:[^\]]*\]\s*/i, "").replace(/<usage>[\s\S]*?<\/usage>/gi, "").trim();
|
|
2263
|
+
if (resultText.length > 0) result = capSubagentText(resultText);
|
|
2264
|
+
}
|
|
2265
|
+
return {
|
|
2266
|
+
toolUseId: pick("tool-use-id")?.trim() || null,
|
|
2267
|
+
taskId: pick("task-id")?.trim() || null,
|
|
2268
|
+
status,
|
|
2269
|
+
summary: pick("summary")?.trim() || null,
|
|
2270
|
+
result
|
|
2271
|
+
};
|
|
2272
|
+
}
|
|
2273
|
+
function shouldEmitProgress(previous, toolUses, now) {
|
|
2274
|
+
if (!previous) return true;
|
|
2275
|
+
if (previous.lastToolUses === toolUses) return false;
|
|
2276
|
+
return now - previous.lastAt >= SUBAGENT_PROGRESS_MIN_INTERVAL_MS;
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2279
|
+
const SUBAGENT_BUFFER_MAX_MESSAGES = 100;
|
|
2174
2280
|
function isSubagentTool(name) {
|
|
2175
2281
|
return name === "Task" || name === "Agent";
|
|
2176
2282
|
}
|
|
@@ -2239,6 +2345,7 @@ function bufferSubagentMessage(state, subagent, message) {
|
|
|
2239
2345
|
const buffer = getBufferedSubagentMessages(state);
|
|
2240
2346
|
const queue = buffer.get(subagent) ?? [];
|
|
2241
2347
|
queue.push(message);
|
|
2348
|
+
while (queue.length > SUBAGENT_BUFFER_MAX_MESSAGES) queue.shift();
|
|
2242
2349
|
buffer.set(subagent, queue);
|
|
2243
2350
|
}
|
|
2244
2351
|
function consumeBufferedSubagentMessages(state, subagent) {
|
|
@@ -2259,6 +2366,31 @@ function getActiveSubagents(state) {
|
|
|
2259
2366
|
}
|
|
2260
2367
|
return state.activeSubagents;
|
|
2261
2368
|
}
|
|
2369
|
+
function getAgentToolCalls(state) {
|
|
2370
|
+
if (!state.agentToolCalls) state.agentToolCalls = /* @__PURE__ */ new Set();
|
|
2371
|
+
return state.agentToolCalls;
|
|
2372
|
+
}
|
|
2373
|
+
function getSubagentMeta(state) {
|
|
2374
|
+
if (!state.subagentMeta) state.subagentMeta = /* @__PURE__ */ new Map();
|
|
2375
|
+
return state.subagentMeta;
|
|
2376
|
+
}
|
|
2377
|
+
function getStubSubagents(state) {
|
|
2378
|
+
if (!state.stubSubagents) state.stubSubagents = /* @__PURE__ */ new Set();
|
|
2379
|
+
return state.stubSubagents;
|
|
2380
|
+
}
|
|
2381
|
+
function getProgressThrottle(state) {
|
|
2382
|
+
if (!state.progressThrottle) state.progressThrottle = /* @__PURE__ */ new Map();
|
|
2383
|
+
return state.progressThrottle;
|
|
2384
|
+
}
|
|
2385
|
+
function nowOf(state) {
|
|
2386
|
+
return state.now ? state.now() : Date.now();
|
|
2387
|
+
}
|
|
2388
|
+
function rememberSubagentMeta(state, subagent, meta) {
|
|
2389
|
+
const existing = getSubagentMeta(state).get(subagent) ?? {};
|
|
2390
|
+
const description = typeof meta.description === "string" && meta.description.trim() ? meta.description.trim() : existing.description;
|
|
2391
|
+
const subagentType = typeof meta.subagentType === "string" && meta.subagentType.trim() ? meta.subagentType.trim() : existing.subagentType;
|
|
2392
|
+
getSubagentMeta(state).set(subagent, { ...description ? { description } : {}, ...subagentType ? { subagentType } : {} });
|
|
2393
|
+
}
|
|
2262
2394
|
function pickAssistantUsage(message) {
|
|
2263
2395
|
if (message.type !== "assistant") return void 0;
|
|
2264
2396
|
const usage = message.message?.usage;
|
|
@@ -2435,13 +2567,26 @@ function maybeEmitSubagentStart(state, turn, subagent, envelopes) {
|
|
|
2435
2567
|
return;
|
|
2436
2568
|
}
|
|
2437
2569
|
const title = getSubagentTitles(state).get(subagent);
|
|
2570
|
+
const meta = getSubagentMeta(state).get(subagent);
|
|
2438
2571
|
envelopes.push(createEnvelope("agent", {
|
|
2439
2572
|
t: "start",
|
|
2440
|
-
...title ? { title } : {}
|
|
2573
|
+
...title ? { title } : {},
|
|
2574
|
+
...meta?.description ? { description: meta.description } : {},
|
|
2575
|
+
...meta?.subagentType ? { subagentType: meta.subagentType } : {}
|
|
2441
2576
|
}, { turn, subagent }));
|
|
2442
2577
|
started.add(subagent);
|
|
2443
2578
|
getActiveSubagents(state).add(subagent);
|
|
2444
2579
|
}
|
|
2580
|
+
function emitSubagentStopWithStatus(state, turn, subagent, envelopes, payload) {
|
|
2581
|
+
envelopes.push(createEnvelope("agent", {
|
|
2582
|
+
t: "stop",
|
|
2583
|
+
...payload.status ? { status: payload.status } : {},
|
|
2584
|
+
...payload.result ? { result: payload.result } : {},
|
|
2585
|
+
...payload.usage ? { usage: payload.usage } : {}
|
|
2586
|
+
}, { ...turn ? { turn } : {}, subagent }));
|
|
2587
|
+
getActiveSubagents(state).delete(subagent);
|
|
2588
|
+
getStartedSubagents(state).delete(subagent);
|
|
2589
|
+
}
|
|
2445
2590
|
function maybeEmitSubagentStop(state, turn, subagent, envelopes) {
|
|
2446
2591
|
const active = getActiveSubagents(state);
|
|
2447
2592
|
if (!active.has(subagent)) {
|
|
@@ -2453,8 +2598,6 @@ function maybeEmitSubagentStop(state, turn, subagent, envelopes) {
|
|
|
2453
2598
|
function clearSubagentTracking(state) {
|
|
2454
2599
|
getUuidToProviderSubagent(state).clear();
|
|
2455
2600
|
getTaskPromptToSubagents(state).clear();
|
|
2456
|
-
getProviderSubagentToSessionSubagent(state).clear();
|
|
2457
|
-
getSubagentTitles(state).clear();
|
|
2458
2601
|
getBufferedSubagentMessages(state).clear();
|
|
2459
2602
|
getHiddenParentToolCalls(state).clear();
|
|
2460
2603
|
getStartedSubagents(state).clear();
|
|
@@ -2515,6 +2658,58 @@ function closeClaudeTurnWithStatus(state, status, meta) {
|
|
|
2515
2658
|
function mapClaudeLogMessageToSessionEnvelopes(message, state) {
|
|
2516
2659
|
return mapClaudeLogMessageToSessionEnvelopesInternal(message, state);
|
|
2517
2660
|
}
|
|
2661
|
+
function mapTaskLifecycleSystemMessage(message, state, envelopes) {
|
|
2662
|
+
const raw = message;
|
|
2663
|
+
const subtype = typeof raw.subtype === "string" ? raw.subtype : "";
|
|
2664
|
+
if (!subtype.startsWith("task_")) return;
|
|
2665
|
+
if (raw.skip_transcript === true) return;
|
|
2666
|
+
const toolUseId = typeof raw.tool_use_id === "string" && raw.tool_use_id.length > 0 ? raw.tool_use_id : null;
|
|
2667
|
+
if (!toolUseId || !getAgentToolCalls(state).has(toolUseId)) return;
|
|
2668
|
+
const subagent = ensureSessionSubagentIdForProviderSubagent(state, toolUseId);
|
|
2669
|
+
const usage = raw.usage && typeof raw.usage === "object" ? {
|
|
2670
|
+
...typeof raw.usage.tool_uses === "number" ? { toolUses: raw.usage.tool_uses } : {},
|
|
2671
|
+
...typeof raw.usage.total_tokens === "number" ? { totalTokens: raw.usage.total_tokens } : {},
|
|
2672
|
+
...typeof raw.usage.duration_ms === "number" ? { durationMs: raw.usage.duration_ms } : {}
|
|
2673
|
+
} : void 0;
|
|
2674
|
+
if (subtype === "task_started") {
|
|
2675
|
+
rememberSubagentMeta(state, subagent, { description: raw.description, subagentType: raw.subagent_type });
|
|
2676
|
+
const turn = ensureTurn(state, envelopes);
|
|
2677
|
+
getStartedSubagents(state).delete(subagent);
|
|
2678
|
+
maybeEmitSubagentStart(state, turn, subagent, envelopes);
|
|
2679
|
+
return;
|
|
2680
|
+
}
|
|
2681
|
+
if (subtype === "task_progress") {
|
|
2682
|
+
const toolUses = typeof raw.usage?.tool_uses === "number" ? raw.usage.tool_uses : 0;
|
|
2683
|
+
const throttle = getProgressThrottle(state);
|
|
2684
|
+
const now = nowOf(state);
|
|
2685
|
+
if (!shouldEmitProgress(throttle.get(subagent), toolUses, now)) return;
|
|
2686
|
+
throttle.set(subagent, { lastAt: now, lastToolUses: toolUses });
|
|
2687
|
+
const turn = ensureTurn(state, envelopes);
|
|
2688
|
+
maybeEmitSubagentStart(state, turn, subagent, envelopes);
|
|
2689
|
+
envelopes.push(createEnvelope("agent", {
|
|
2690
|
+
t: "progress",
|
|
2691
|
+
toolUses,
|
|
2692
|
+
...typeof raw.last_tool_name === "string" && raw.last_tool_name ? { lastTool: raw.last_tool_name } : {},
|
|
2693
|
+
...usage?.totalTokens !== void 0 ? { totalTokens: usage.totalTokens } : {},
|
|
2694
|
+
...usage?.durationMs !== void 0 ? { durationMs: usage.durationMs } : {},
|
|
2695
|
+
...typeof raw.summary === "string" && raw.summary.trim() ? { summary: raw.summary.trim() } : {}
|
|
2696
|
+
}, { turn, subagent }));
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
if (subtype === "task_notification") {
|
|
2700
|
+
const status = raw.status === "completed" || raw.status === "failed" || raw.status === "stopped" ? raw.status : "completed";
|
|
2701
|
+
emitSubagentStopWithStatus(state, state.currentTurnId ?? void 0, subagent, envelopes, {
|
|
2702
|
+
status,
|
|
2703
|
+
...usage ? { usage } : {}
|
|
2704
|
+
});
|
|
2705
|
+
getStubSubagents(state).delete(subagent);
|
|
2706
|
+
getProgressThrottle(state).delete(subagent);
|
|
2707
|
+
return;
|
|
2708
|
+
}
|
|
2709
|
+
if (subtype === "task_updated" && raw.patch?.is_backgrounded === true) {
|
|
2710
|
+
getStubSubagents(state).add(subagent);
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2518
2713
|
function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
|
|
2519
2714
|
const envelopes = [];
|
|
2520
2715
|
const claudeUuid = pickUuid(message);
|
|
@@ -2535,6 +2730,7 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
|
|
|
2535
2730
|
};
|
|
2536
2731
|
}
|
|
2537
2732
|
if (message.type === "system") {
|
|
2733
|
+
mapTaskLifecycleSystemMessage(message, state, envelopes);
|
|
2538
2734
|
return {
|
|
2539
2735
|
currentTurnId: state.currentTurnId,
|
|
2540
2736
|
envelopes
|
|
@@ -2576,6 +2772,9 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
|
|
|
2576
2772
|
queueTaskPromptSubagent(state, prompt, call);
|
|
2577
2773
|
}
|
|
2578
2774
|
setSubagentTitle(state, sessionSubagentForCall, pickTaskTitle(block.input) ?? prompt);
|
|
2775
|
+
getAgentToolCalls(state).add(call);
|
|
2776
|
+
const input = block.input ?? {};
|
|
2777
|
+
rememberSubagentMeta(state, sessionSubagentForCall, { description: input.description, subagentType: input.subagent_type });
|
|
2579
2778
|
}
|
|
2580
2779
|
if (shouldHideParentToolCall(name)) {
|
|
2581
2780
|
getHiddenParentToolCalls(state).add(call);
|
|
@@ -2620,6 +2819,18 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
|
|
|
2620
2819
|
maybeEmitSubagentStart(state, turnId2, subagent, envelopes);
|
|
2621
2820
|
envelopes.push(createEnvelope("agent", { t: "text", text: message.message.content }, { turn: turnId2, subagent, claudeUuid }));
|
|
2622
2821
|
} else {
|
|
2822
|
+
const origin = message.origin;
|
|
2823
|
+
if (origin?.kind === "task-notification" || /<task-notification>/i.test(message.message.content)) {
|
|
2824
|
+
const fields = parseTaskNotificationText(message.message.content);
|
|
2825
|
+
const providerId = fields?.toolUseId ?? null;
|
|
2826
|
+
const subagentForNotification = providerId && getAgentToolCalls(state).has(providerId) ? getSessionSubagentIdForProviderSubagent(state, providerId) : void 0;
|
|
2827
|
+
if (fields && subagentForNotification && (fields.result || fields.status)) {
|
|
2828
|
+
emitSubagentStopWithStatus(state, state.currentTurnId ?? void 0, subagentForNotification, envelopes, {
|
|
2829
|
+
...fields.status ? { status: fields.status } : {},
|
|
2830
|
+
...fields.result ? { result: fields.result } : {}
|
|
2831
|
+
});
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2623
2834
|
closeTurn(state, "completed", envelopes);
|
|
2624
2835
|
envelopes.push(createEnvelope("user", { t: "text", text: message.message.content }, { claudeUuid }));
|
|
2625
2836
|
}
|
|
@@ -2650,6 +2861,31 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
|
|
|
2650
2861
|
getHiddenParentToolCalls(state).delete(block.tool_use_id);
|
|
2651
2862
|
continue;
|
|
2652
2863
|
}
|
|
2864
|
+
if (sessionSubagentForToolResult && getAgentToolCalls(state).has(block.tool_use_id)) {
|
|
2865
|
+
const toolUseResult = message.tool_use_result;
|
|
2866
|
+
const resultStatus = toolUseResultStatus(toolUseResult);
|
|
2867
|
+
if (resultStatus === "async_launched") {
|
|
2868
|
+
getStubSubagents(state).add(sessionSubagentForToolResult);
|
|
2869
|
+
envelopes.push(createEnvelope("agent", { t: "tool-call-end", call: block.tool_use_id }, { turn: turnId, subagent }));
|
|
2870
|
+
continue;
|
|
2871
|
+
}
|
|
2872
|
+
if (resultStatus === "completed") {
|
|
2873
|
+
const text = toolUseResultToText(toolUseResult);
|
|
2874
|
+
const stats = toolUseResultStats(toolUseResult);
|
|
2875
|
+
const result = text ? capSubagentText(text) : void 0;
|
|
2876
|
+
emitSubagentStopWithStatus(state, turnId, sessionSubagentForToolResult, envelopes, {
|
|
2877
|
+
status: "completed",
|
|
2878
|
+
...result ? { result } : {},
|
|
2879
|
+
...stats ? { usage: { toolUses: stats.toolUses, totalTokens: stats.totalTokens, durationMs: stats.durationMs } } : {}
|
|
2880
|
+
});
|
|
2881
|
+
envelopes.push(createEnvelope("agent", {
|
|
2882
|
+
t: "tool-call-end",
|
|
2883
|
+
call: block.tool_use_id,
|
|
2884
|
+
...result ? { result: { ...result, ...stats ? { stats } : {} } } : {}
|
|
2885
|
+
}, { turn: turnId, subagent }));
|
|
2886
|
+
continue;
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2653
2889
|
if (sessionSubagentForToolResult) {
|
|
2654
2890
|
maybeEmitSubagentStop(state, turnId, sessionSubagentForToolResult, envelopes);
|
|
2655
2891
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "very-happy-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.91",
|
|
4
4
|
"description": "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.",
|
|
5
5
|
"author": "Kirill Dubovitskiy",
|
|
6
6
|
"contributors": [
|
|
@@ -113,12 +113,12 @@
|
|
|
113
113
|
"zod": "^4.0.0"
|
|
114
114
|
},
|
|
115
115
|
"optionalDependencies": {
|
|
116
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
117
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
118
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
119
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
120
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
121
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
116
|
+
"very-happy-tools-arm64-darwin": "0.2.91",
|
|
117
|
+
"very-happy-tools-x64-darwin": "0.2.91",
|
|
118
|
+
"very-happy-tools-arm64-linux": "0.2.91",
|
|
119
|
+
"very-happy-tools-x64-linux": "0.2.91",
|
|
120
|
+
"very-happy-tools-arm64-win32": "0.2.91",
|
|
121
|
+
"very-happy-tools-x64-win32": "0.2.91"
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
124
|
"@slopus/happy-wire": "workspace:*",
|