@volter-ai-dev/supercode-ui 0.1.16 → 0.1.18
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/components.mjs +77 -12
- package/controller.mjs +5 -0
- package/conversation.mjs +77 -12
- package/core.mjs +81 -11
- package/embed.mjs +77 -12
- package/messenger.mjs +77 -12
- package/package.json +1 -1
- package/styles.css +1 -0
package/components.mjs
CHANGED
|
@@ -116,6 +116,12 @@ function sourceString(source, keys) {
|
|
|
116
116
|
const match = new RegExp(`(?:^|[,{\\s])["']?(?:${names})["']?\\s*:\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
|
|
117
117
|
return decodedLiteral(match?.[1]);
|
|
118
118
|
}
|
|
119
|
+
function assignedString(source, keys) {
|
|
120
|
+
if (!source) return "";
|
|
121
|
+
const names = keys.join("|");
|
|
122
|
+
const match = new RegExp(`\\b(?:${names})\\s*=\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
|
|
123
|
+
return decodedLiteral(match?.[1]);
|
|
124
|
+
}
|
|
119
125
|
function callArgumentSource(source, open) {
|
|
120
126
|
let depth = 1;
|
|
121
127
|
let quote = "";
|
|
@@ -257,6 +263,13 @@ function planItems(args) {
|
|
|
257
263
|
return [{ label: boundedString(label, 300), status: firstString(value, ["status"]) }];
|
|
258
264
|
}).slice(0, 12);
|
|
259
265
|
}
|
|
266
|
+
function agentItems(name, resultText) {
|
|
267
|
+
if (!/list.?agents/i.test(name)) return [];
|
|
268
|
+
return (resultText ?? "").split("\n").flatMap((line) => {
|
|
269
|
+
const parts = line.trim().split(/\s+·\s+/).filter(Boolean);
|
|
270
|
+
return parts.length > 1 ? [{ label: boundedString(parts[0], 120), status: boundedString(parts.slice(1).join(" \xB7 "), 180) }] : [];
|
|
271
|
+
}).slice(0, 12);
|
|
272
|
+
}
|
|
260
273
|
function editPreview(args, resultText, source) {
|
|
261
274
|
const direct = firstString(args, ["patch", "diff"]);
|
|
262
275
|
if (direct) return direct;
|
|
@@ -272,6 +285,42 @@ function editPreview(args, resultText, source) {
|
|
|
272
285
|
if (patch) return patch;
|
|
273
286
|
return /^(?:diff --git|@@ |--- |\+\+\+ )/m.test(resultText ?? "") ? resultText : "";
|
|
274
287
|
}
|
|
288
|
+
function toolResultEnvelope(resultText) {
|
|
289
|
+
const match = /^Script (?:completed|failed)\r?\nWall time ([0-9.]+) seconds\r?\nOutput:\r?\n([\s\S]*)$/.exec(resultText ?? "");
|
|
290
|
+
if (!match) {
|
|
291
|
+
try {
|
|
292
|
+
const value = JSON.parse(resultText ?? "");
|
|
293
|
+
const object = record(value);
|
|
294
|
+
return {
|
|
295
|
+
preview: typeof value === "string" ? value : firstString(object, ["output", "message", "text", "summary", "result"]) || resultText || "",
|
|
296
|
+
value: object,
|
|
297
|
+
durationMs: null
|
|
298
|
+
};
|
|
299
|
+
} catch {
|
|
300
|
+
return { preview: resultText ?? "", value: null, durationMs: null };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
const durationMs = Number(match[1]) * 1e3;
|
|
304
|
+
try {
|
|
305
|
+
const value = record(JSON.parse(match[2]));
|
|
306
|
+
return {
|
|
307
|
+
preview: typeof value?.output === "string" ? value.output : match[2],
|
|
308
|
+
value,
|
|
309
|
+
durationMs: Number.isFinite(durationMs) ? durationMs : null
|
|
310
|
+
};
|
|
311
|
+
} catch {
|
|
312
|
+
return { preview: match[2], value: null, durationMs: Number.isFinite(durationMs) ? durationMs : null };
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function semanticAgentPreview(name, status, outcome) {
|
|
316
|
+
const normalized = name.toLocaleLowerCase();
|
|
317
|
+
if (status === "error") return outcome.preview;
|
|
318
|
+
if (/^(?:agent|task)$|spawn.?agent/.test(normalized) && outcome.preview) return "Agent is working in the background.";
|
|
319
|
+
if (/send.?message|followup.?task/.test(normalized) && outcome.preview) {
|
|
320
|
+
return /resumed from transcript|resumedAgentId/i.test(outcome.preview) ? "Agent resumed in the background." : "Message delivered.";
|
|
321
|
+
}
|
|
322
|
+
return outcome.preview;
|
|
323
|
+
}
|
|
275
324
|
function verificationCommand(command) {
|
|
276
325
|
let shell = "";
|
|
277
326
|
let quote = "";
|
|
@@ -304,12 +353,13 @@ function verificationCommand(command) {
|
|
|
304
353
|
function classifyTool(name, command) {
|
|
305
354
|
const normalized = name.toLocaleLowerCase();
|
|
306
355
|
if (/write_stdin|^wait$/.test(normalized)) return "command";
|
|
307
|
-
if (/update.?plan|todo|checklist|taskcreate|taskupdate/.test(normalized)) return "plan";
|
|
356
|
+
if (/update.?plan|todo|checklist|taskcreate|taskupdate|create.?goal|update.?goal/.test(normalized)) return "plan";
|
|
308
357
|
if (/search.?replace|edit|write|patch|replace|create_file|apply_patch/.test(normalized)) return "edit";
|
|
309
358
|
if (/read|view|open_file|list_dir/.test(normalized)) return "read";
|
|
359
|
+
if (/web.?search|web.?fetch|fetch.?url/.test(normalized)) return "web";
|
|
310
360
|
if (/search|find|grep|glob|toolsearch/.test(normalized)) return "search";
|
|
311
361
|
if (/browser|web|fetch|url/.test(normalized)) return "web";
|
|
312
|
-
if (/agent|subagent|
|
|
362
|
+
if (/agent|subagent|send.?message|delegate|followup.?task|taskstop|taskoutput|^task$/.test(normalized)) return "agent";
|
|
313
363
|
if (/test|typecheck|lint|build/.test(normalized)) return "test";
|
|
314
364
|
if (/terminal|bash|shell|command|exec|write_stdin|^wait$/.test(normalized)) return verificationCommand(command) ? "test" : "command";
|
|
315
365
|
return "other";
|
|
@@ -318,9 +368,17 @@ function toolAction(status, category, name, tools) {
|
|
|
318
368
|
const position = status === "pending" ? 0 : status === "error" ? 2 : 1;
|
|
319
369
|
if (tools.length > 1) return [`Running ${tools.length} actions`, `Ran ${tools.length} actions`, `${tools.length} actions failed`][position];
|
|
320
370
|
const normalized = name.toLocaleLowerCase();
|
|
321
|
-
if (/
|
|
322
|
-
if (/kill_command_or_subagent/.test(normalized)) return ["Stopping", "Stopped", "Stop failed"][position];
|
|
371
|
+
if (/send.?message|followup.?task/.test(normalized)) return ["Messaging agent", "Messaged agent", "Agent message failed"][position];
|
|
372
|
+
if (/taskstop|interrupt.?agent|kill_command_or_subagent/.test(normalized)) return ["Stopping agent", "Stopped agent", "Stop failed"][position];
|
|
373
|
+
if (/list.?agents|taskoutput|wait.?agent/.test(normalized)) return ["Checking agents", "Checked agents", "Agent check failed"][position];
|
|
323
374
|
if (/get_command_or_subagent_output|write_stdin|^wait$/.test(normalized)) return ["Waiting for", "Checked", "Check failed"][position];
|
|
375
|
+
if (/web.?search/.test(normalized)) return ["Searching web", "Searched web", "Web search failed"][position];
|
|
376
|
+
if (/web.?fetch|fetch.?url/.test(normalized)) return ["Fetching page", "Fetched page", "Page fetch failed"][position];
|
|
377
|
+
if (/^skill$|use.?skill|load.?skill/.test(normalized)) return ["Loading skill", "Loaded skill", "Skill load failed"][position];
|
|
378
|
+
if (/taskcreate/.test(normalized)) return ["Adding task", "Added task", "Task creation failed"][position];
|
|
379
|
+
if (/taskupdate/.test(normalized)) return ["Updating task", "Updated task", "Task update failed"][position];
|
|
380
|
+
if (/create.?goal/.test(normalized)) return ["Creating goal", "Created goal", "Goal creation failed"][position];
|
|
381
|
+
if (/update.?goal/.test(normalized)) return ["Updating goal", "Updated goal", "Goal update failed"][position];
|
|
324
382
|
const actions = {
|
|
325
383
|
read: ["Reading", "Read", "Read failed"],
|
|
326
384
|
search: ["Searching", "Searched", "Search failed"],
|
|
@@ -336,18 +394,22 @@ function toolAction(status, category, name, tools) {
|
|
|
336
394
|
function createToolPresentation(entry) {
|
|
337
395
|
const envelope = toolEnvelope(entry);
|
|
338
396
|
const args = envelope.args;
|
|
397
|
+
const outcome = toolResultEnvelope(entry.resultText);
|
|
398
|
+
const patchSource = assignedString(envelope.source, ["patch"]) || envelope.source;
|
|
339
399
|
const command = firstString(args, ["command", "cmd"]) || sourceString(envelope.callSource, ["command", "cmd"]);
|
|
340
400
|
const category = classifyTool(envelope.name, command || envelope.source || entry.arguments || "");
|
|
341
|
-
const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.callSource, ["file_path", "target_file", "target_directory", "path"]) || patchPath(
|
|
401
|
+
const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.callSource, ["file_path", "target_file", "target_directory", "path"]) || patchPath(patchSource);
|
|
342
402
|
const query = firstString(args, ["query", "pattern"]) || sourceString(envelope.callSource, ["query", "pattern", "q"]);
|
|
343
403
|
const url = firstString(args, ["url"]) || sourceString(envelope.callSource, ["url", "ref_id"]);
|
|
344
|
-
const subject = firstString(args, ["subject", "description", "summary", "task", "prompt"]) || sourceString(envelope.callSource, ["subject", "description", "summary", "task", "prompt"]);
|
|
404
|
+
const subject = firstString(args, ["subject", "description", "summary", "task", "objective", "prompt"]) || sourceString(envelope.callSource, ["subject", "description", "summary", "task", "objective", "prompt"]);
|
|
405
|
+
const agentTarget = category === "agent" ? firstString(record(outcome.value), ["command", "name"]) || firstString(args, ["target", "task_name", "taskId", "task_id", "agentId", "agent_id", "resume", "team_name"]) || sourceString(envelope.callSource, ["target", "task_name", "taskId", "task_id", "agentId", "agent_id", "resume", "team_name"]) : "";
|
|
406
|
+
const skillTarget = /^skill$|use.?skill|load.?skill/i.test(envelope.name) ? firstString(args, ["skill", "name"]) || sourceString(envelope.callSource, ["skill", "name"]) : "";
|
|
345
407
|
const background = /get_command_or_subagent_output|kill_command_or_subagent/i.test(envelope.name) ? "background task" : /write_stdin|^wait$/i.test(envelope.name) ? "background command" : "";
|
|
346
|
-
const items = planItems(args);
|
|
408
|
+
const items = category === "agent" ? agentItems(envelope.name, outcome.preview) : planItems(args);
|
|
347
409
|
const taskId = firstString(args, ["taskId", "task_id"]);
|
|
348
410
|
const planTarget = category === "plan" ? items.length ? `${items.length} ${items.length === 1 ? "item" : "items"}` : taskId ? `task ${taskId}` : "" : "";
|
|
349
|
-
const target = path || command || query || url || subject || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
350
|
-
const previewSource = category === "edit" ? editPreview(args,
|
|
411
|
+
const target = path || command || query || url || subject || agentTarget || skillTarget || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
412
|
+
const previewSource = category === "edit" ? editPreview(args, outcome.preview, patchSource) : category === "agent" ? semanticAgentPreview(envelope.name, entry.status ?? "completed", outcome) : outcome.preview;
|
|
351
413
|
const result = record(entry.resultContent);
|
|
352
414
|
const metadata = record(entry.metadata);
|
|
353
415
|
const resultMetadata = record(result?.metadata);
|
|
@@ -366,8 +428,8 @@ function createToolPresentation(entry) {
|
|
|
366
428
|
fields: usefulToolFields(args),
|
|
367
429
|
items,
|
|
368
430
|
tools: envelope.tools,
|
|
369
|
-
exitCode: explicitNumber([result, resultMetadata, metadata], ["exit_code", "exitCode", "pi_bash_exit_code"]),
|
|
370
|
-
durationMs: explicitNumber([result, resultMetadata, metadata], ["duration_ms", "durationMs", "elapsed_ms", "elapsedMs", "totalDurationMs"]),
|
|
431
|
+
exitCode: explicitNumber([outcome.value, result, resultMetadata, metadata], ["exit_code", "exitCode", "pi_bash_exit_code"]),
|
|
432
|
+
durationMs: explicitNumber([outcome.value, result, resultMetadata, metadata], ["duration_ms", "durationMs", "elapsed_ms", "elapsedMs", "totalDurationMs"]) ?? outcome.durationMs,
|
|
371
433
|
additions: explicitNumber([result, resultMetadata, metadata], ["additions", "lines_added"]),
|
|
372
434
|
deletions: explicitNumber([result, resultMetadata, metadata], ["deletions", "lines_removed"]),
|
|
373
435
|
matches: explicitNumber([result, resultMetadata, metadata], ["matches", "match_count", "result_count"])
|
|
@@ -1184,7 +1246,10 @@ function ToolPreview({ presentation, entry }) {
|
|
|
1184
1246
|
presentation.url ? /* @__PURE__ */ jsx4("code", { children: presentation.url }) : null,
|
|
1185
1247
|
presentation.preview ? /* @__PURE__ */ jsx4("p", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx4("small", { children: pending ? "Waiting for the page" : "No page summary returned" })
|
|
1186
1248
|
] });
|
|
1187
|
-
if (presentation.detail === "agent") return /* @__PURE__ */ jsx4("section", { class: "scui-agent-preview", children: presentation.
|
|
1249
|
+
if (presentation.detail === "agent") return /* @__PURE__ */ jsx4("section", { class: "scui-agent-preview", children: presentation.items?.length ? /* @__PURE__ */ jsx4("ol", { class: "scui-agent-roster", children: presentation.items.map((item, index) => /* @__PURE__ */ jsxs3("li", { children: [
|
|
1250
|
+
/* @__PURE__ */ jsx4("strong", { children: item.label }),
|
|
1251
|
+
/* @__PURE__ */ jsx4("small", { children: item.status })
|
|
1252
|
+
] }, `${item.label}:${index}`)) }) : presentation.preview ? /* @__PURE__ */ jsx4("pre", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx4("small", { children: pending ? "Agent is working" : "No textual handoff returned" }) });
|
|
1188
1253
|
if (presentation.detail === "plan") return /* @__PURE__ */ jsx4("ol", { class: "scui-plan-preview", children: presentation.items?.map((item, index) => /* @__PURE__ */ jsxs3("li", { "data-status": item.status, children: [
|
|
1189
1254
|
/* @__PURE__ */ jsx4("i", { "aria-hidden": "true" }),
|
|
1190
1255
|
/* @__PURE__ */ jsx4("span", { children: item.label })
|
package/controller.mjs
CHANGED
|
@@ -141,6 +141,11 @@ function projectConversationEntry(entry, maxEntryChars) {
|
|
|
141
141
|
};
|
|
142
142
|
projected.presentation = createToolPresentation({
|
|
143
143
|
...projected,
|
|
144
|
+
// Presentation is a small semantic projection, so derive it before the raw native
|
|
145
|
+
// envelope is bounded for transport. Large Agent prompts and patches routinely exceed the
|
|
146
|
+
// widget cap; parsing the truncated JSON made their useful description/path disappear.
|
|
147
|
+
arguments: (entry.arguments ?? '').trim(),
|
|
148
|
+
resultText: (entry.resultText ?? '').trim(),
|
|
144
149
|
resultContent: entry.resultContent,
|
|
145
150
|
metadata: entry.metadata,
|
|
146
151
|
});
|
package/conversation.mjs
CHANGED
|
@@ -102,6 +102,12 @@ function sourceString(source, keys) {
|
|
|
102
102
|
const match = new RegExp(`(?:^|[,{\\s])["']?(?:${names})["']?\\s*:\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
|
|
103
103
|
return decodedLiteral(match?.[1]);
|
|
104
104
|
}
|
|
105
|
+
function assignedString(source, keys) {
|
|
106
|
+
if (!source) return "";
|
|
107
|
+
const names = keys.join("|");
|
|
108
|
+
const match = new RegExp(`\\b(?:${names})\\s*=\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
|
|
109
|
+
return decodedLiteral(match?.[1]);
|
|
110
|
+
}
|
|
105
111
|
function callArgumentSource(source, open) {
|
|
106
112
|
let depth = 1;
|
|
107
113
|
let quote = "";
|
|
@@ -243,6 +249,13 @@ function planItems(args) {
|
|
|
243
249
|
return [{ label: boundedString(label, 300), status: firstString(value, ["status"]) }];
|
|
244
250
|
}).slice(0, 12);
|
|
245
251
|
}
|
|
252
|
+
function agentItems(name, resultText) {
|
|
253
|
+
if (!/list.?agents/i.test(name)) return [];
|
|
254
|
+
return (resultText ?? "").split("\n").flatMap((line) => {
|
|
255
|
+
const parts = line.trim().split(/\s+·\s+/).filter(Boolean);
|
|
256
|
+
return parts.length > 1 ? [{ label: boundedString(parts[0], 120), status: boundedString(parts.slice(1).join(" \xB7 "), 180) }] : [];
|
|
257
|
+
}).slice(0, 12);
|
|
258
|
+
}
|
|
246
259
|
function editPreview(args, resultText, source) {
|
|
247
260
|
const direct = firstString(args, ["patch", "diff"]);
|
|
248
261
|
if (direct) return direct;
|
|
@@ -258,6 +271,42 @@ function editPreview(args, resultText, source) {
|
|
|
258
271
|
if (patch) return patch;
|
|
259
272
|
return /^(?:diff --git|@@ |--- |\+\+\+ )/m.test(resultText ?? "") ? resultText : "";
|
|
260
273
|
}
|
|
274
|
+
function toolResultEnvelope(resultText) {
|
|
275
|
+
const match = /^Script (?:completed|failed)\r?\nWall time ([0-9.]+) seconds\r?\nOutput:\r?\n([\s\S]*)$/.exec(resultText ?? "");
|
|
276
|
+
if (!match) {
|
|
277
|
+
try {
|
|
278
|
+
const value = JSON.parse(resultText ?? "");
|
|
279
|
+
const object = record(value);
|
|
280
|
+
return {
|
|
281
|
+
preview: typeof value === "string" ? value : firstString(object, ["output", "message", "text", "summary", "result"]) || resultText || "",
|
|
282
|
+
value: object,
|
|
283
|
+
durationMs: null
|
|
284
|
+
};
|
|
285
|
+
} catch {
|
|
286
|
+
return { preview: resultText ?? "", value: null, durationMs: null };
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
const durationMs = Number(match[1]) * 1e3;
|
|
290
|
+
try {
|
|
291
|
+
const value = record(JSON.parse(match[2]));
|
|
292
|
+
return {
|
|
293
|
+
preview: typeof value?.output === "string" ? value.output : match[2],
|
|
294
|
+
value,
|
|
295
|
+
durationMs: Number.isFinite(durationMs) ? durationMs : null
|
|
296
|
+
};
|
|
297
|
+
} catch {
|
|
298
|
+
return { preview: match[2], value: null, durationMs: Number.isFinite(durationMs) ? durationMs : null };
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function semanticAgentPreview(name, status, outcome) {
|
|
302
|
+
const normalized = name.toLocaleLowerCase();
|
|
303
|
+
if (status === "error") return outcome.preview;
|
|
304
|
+
if (/^(?:agent|task)$|spawn.?agent/.test(normalized) && outcome.preview) return "Agent is working in the background.";
|
|
305
|
+
if (/send.?message|followup.?task/.test(normalized) && outcome.preview) {
|
|
306
|
+
return /resumed from transcript|resumedAgentId/i.test(outcome.preview) ? "Agent resumed in the background." : "Message delivered.";
|
|
307
|
+
}
|
|
308
|
+
return outcome.preview;
|
|
309
|
+
}
|
|
261
310
|
function verificationCommand(command) {
|
|
262
311
|
let shell = "";
|
|
263
312
|
let quote = "";
|
|
@@ -290,12 +339,13 @@ function verificationCommand(command) {
|
|
|
290
339
|
function classifyTool(name, command) {
|
|
291
340
|
const normalized = name.toLocaleLowerCase();
|
|
292
341
|
if (/write_stdin|^wait$/.test(normalized)) return "command";
|
|
293
|
-
if (/update.?plan|todo|checklist|taskcreate|taskupdate/.test(normalized)) return "plan";
|
|
342
|
+
if (/update.?plan|todo|checklist|taskcreate|taskupdate|create.?goal|update.?goal/.test(normalized)) return "plan";
|
|
294
343
|
if (/search.?replace|edit|write|patch|replace|create_file|apply_patch/.test(normalized)) return "edit";
|
|
295
344
|
if (/read|view|open_file|list_dir/.test(normalized)) return "read";
|
|
345
|
+
if (/web.?search|web.?fetch|fetch.?url/.test(normalized)) return "web";
|
|
296
346
|
if (/search|find|grep|glob|toolsearch/.test(normalized)) return "search";
|
|
297
347
|
if (/browser|web|fetch|url/.test(normalized)) return "web";
|
|
298
|
-
if (/agent|subagent|
|
|
348
|
+
if (/agent|subagent|send.?message|delegate|followup.?task|taskstop|taskoutput|^task$/.test(normalized)) return "agent";
|
|
299
349
|
if (/test|typecheck|lint|build/.test(normalized)) return "test";
|
|
300
350
|
if (/terminal|bash|shell|command|exec|write_stdin|^wait$/.test(normalized)) return verificationCommand(command) ? "test" : "command";
|
|
301
351
|
return "other";
|
|
@@ -304,9 +354,17 @@ function toolAction(status, category, name, tools) {
|
|
|
304
354
|
const position = status === "pending" ? 0 : status === "error" ? 2 : 1;
|
|
305
355
|
if (tools.length > 1) return [`Running ${tools.length} actions`, `Ran ${tools.length} actions`, `${tools.length} actions failed`][position];
|
|
306
356
|
const normalized = name.toLocaleLowerCase();
|
|
307
|
-
if (/
|
|
308
|
-
if (/kill_command_or_subagent/.test(normalized)) return ["Stopping", "Stopped", "Stop failed"][position];
|
|
357
|
+
if (/send.?message|followup.?task/.test(normalized)) return ["Messaging agent", "Messaged agent", "Agent message failed"][position];
|
|
358
|
+
if (/taskstop|interrupt.?agent|kill_command_or_subagent/.test(normalized)) return ["Stopping agent", "Stopped agent", "Stop failed"][position];
|
|
359
|
+
if (/list.?agents|taskoutput|wait.?agent/.test(normalized)) return ["Checking agents", "Checked agents", "Agent check failed"][position];
|
|
309
360
|
if (/get_command_or_subagent_output|write_stdin|^wait$/.test(normalized)) return ["Waiting for", "Checked", "Check failed"][position];
|
|
361
|
+
if (/web.?search/.test(normalized)) return ["Searching web", "Searched web", "Web search failed"][position];
|
|
362
|
+
if (/web.?fetch|fetch.?url/.test(normalized)) return ["Fetching page", "Fetched page", "Page fetch failed"][position];
|
|
363
|
+
if (/^skill$|use.?skill|load.?skill/.test(normalized)) return ["Loading skill", "Loaded skill", "Skill load failed"][position];
|
|
364
|
+
if (/taskcreate/.test(normalized)) return ["Adding task", "Added task", "Task creation failed"][position];
|
|
365
|
+
if (/taskupdate/.test(normalized)) return ["Updating task", "Updated task", "Task update failed"][position];
|
|
366
|
+
if (/create.?goal/.test(normalized)) return ["Creating goal", "Created goal", "Goal creation failed"][position];
|
|
367
|
+
if (/update.?goal/.test(normalized)) return ["Updating goal", "Updated goal", "Goal update failed"][position];
|
|
310
368
|
const actions = {
|
|
311
369
|
read: ["Reading", "Read", "Read failed"],
|
|
312
370
|
search: ["Searching", "Searched", "Search failed"],
|
|
@@ -322,18 +380,22 @@ function toolAction(status, category, name, tools) {
|
|
|
322
380
|
function createToolPresentation(entry) {
|
|
323
381
|
const envelope = toolEnvelope(entry);
|
|
324
382
|
const args = envelope.args;
|
|
383
|
+
const outcome = toolResultEnvelope(entry.resultText);
|
|
384
|
+
const patchSource = assignedString(envelope.source, ["patch"]) || envelope.source;
|
|
325
385
|
const command = firstString(args, ["command", "cmd"]) || sourceString(envelope.callSource, ["command", "cmd"]);
|
|
326
386
|
const category = classifyTool(envelope.name, command || envelope.source || entry.arguments || "");
|
|
327
|
-
const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.callSource, ["file_path", "target_file", "target_directory", "path"]) || patchPath(
|
|
387
|
+
const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.callSource, ["file_path", "target_file", "target_directory", "path"]) || patchPath(patchSource);
|
|
328
388
|
const query = firstString(args, ["query", "pattern"]) || sourceString(envelope.callSource, ["query", "pattern", "q"]);
|
|
329
389
|
const url = firstString(args, ["url"]) || sourceString(envelope.callSource, ["url", "ref_id"]);
|
|
330
|
-
const subject = firstString(args, ["subject", "description", "summary", "task", "prompt"]) || sourceString(envelope.callSource, ["subject", "description", "summary", "task", "prompt"]);
|
|
390
|
+
const subject = firstString(args, ["subject", "description", "summary", "task", "objective", "prompt"]) || sourceString(envelope.callSource, ["subject", "description", "summary", "task", "objective", "prompt"]);
|
|
391
|
+
const agentTarget = category === "agent" ? firstString(record(outcome.value), ["command", "name"]) || firstString(args, ["target", "task_name", "taskId", "task_id", "agentId", "agent_id", "resume", "team_name"]) || sourceString(envelope.callSource, ["target", "task_name", "taskId", "task_id", "agentId", "agent_id", "resume", "team_name"]) : "";
|
|
392
|
+
const skillTarget = /^skill$|use.?skill|load.?skill/i.test(envelope.name) ? firstString(args, ["skill", "name"]) || sourceString(envelope.callSource, ["skill", "name"]) : "";
|
|
331
393
|
const background = /get_command_or_subagent_output|kill_command_or_subagent/i.test(envelope.name) ? "background task" : /write_stdin|^wait$/i.test(envelope.name) ? "background command" : "";
|
|
332
|
-
const items = planItems(args);
|
|
394
|
+
const items = category === "agent" ? agentItems(envelope.name, outcome.preview) : planItems(args);
|
|
333
395
|
const taskId = firstString(args, ["taskId", "task_id"]);
|
|
334
396
|
const planTarget = category === "plan" ? items.length ? `${items.length} ${items.length === 1 ? "item" : "items"}` : taskId ? `task ${taskId}` : "" : "";
|
|
335
|
-
const target = path || command || query || url || subject || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
336
|
-
const previewSource = category === "edit" ? editPreview(args,
|
|
397
|
+
const target = path || command || query || url || subject || agentTarget || skillTarget || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
398
|
+
const previewSource = category === "edit" ? editPreview(args, outcome.preview, patchSource) : category === "agent" ? semanticAgentPreview(envelope.name, entry.status ?? "completed", outcome) : outcome.preview;
|
|
337
399
|
const result = record(entry.resultContent);
|
|
338
400
|
const metadata = record(entry.metadata);
|
|
339
401
|
const resultMetadata = record(result?.metadata);
|
|
@@ -352,8 +414,8 @@ function createToolPresentation(entry) {
|
|
|
352
414
|
fields: usefulToolFields(args),
|
|
353
415
|
items,
|
|
354
416
|
tools: envelope.tools,
|
|
355
|
-
exitCode: explicitNumber([result, resultMetadata, metadata], ["exit_code", "exitCode", "pi_bash_exit_code"]),
|
|
356
|
-
durationMs: explicitNumber([result, resultMetadata, metadata], ["duration_ms", "durationMs", "elapsed_ms", "elapsedMs", "totalDurationMs"]),
|
|
417
|
+
exitCode: explicitNumber([outcome.value, result, resultMetadata, metadata], ["exit_code", "exitCode", "pi_bash_exit_code"]),
|
|
418
|
+
durationMs: explicitNumber([outcome.value, result, resultMetadata, metadata], ["duration_ms", "durationMs", "elapsed_ms", "elapsedMs", "totalDurationMs"]) ?? outcome.durationMs,
|
|
357
419
|
additions: explicitNumber([result, resultMetadata, metadata], ["additions", "lines_added"]),
|
|
358
420
|
deletions: explicitNumber([result, resultMetadata, metadata], ["deletions", "lines_removed"]),
|
|
359
421
|
matches: explicitNumber([result, resultMetadata, metadata], ["matches", "match_count", "result_count"])
|
|
@@ -783,7 +845,10 @@ function ToolPreview({ presentation, entry }) {
|
|
|
783
845
|
presentation.url ? /* @__PURE__ */ jsx3("code", { children: presentation.url }) : null,
|
|
784
846
|
presentation.preview ? /* @__PURE__ */ jsx3("p", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx3("small", { children: pending ? "Waiting for the page" : "No page summary returned" })
|
|
785
847
|
] });
|
|
786
|
-
if (presentation.detail === "agent") return /* @__PURE__ */ jsx3("section", { class: "scui-agent-preview", children: presentation.
|
|
848
|
+
if (presentation.detail === "agent") return /* @__PURE__ */ jsx3("section", { class: "scui-agent-preview", children: presentation.items?.length ? /* @__PURE__ */ jsx3("ol", { class: "scui-agent-roster", children: presentation.items.map((item, index) => /* @__PURE__ */ jsxs2("li", { children: [
|
|
849
|
+
/* @__PURE__ */ jsx3("strong", { children: item.label }),
|
|
850
|
+
/* @__PURE__ */ jsx3("small", { children: item.status })
|
|
851
|
+
] }, `${item.label}:${index}`)) }) : presentation.preview ? /* @__PURE__ */ jsx3("pre", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx3("small", { children: pending ? "Agent is working" : "No textual handoff returned" }) });
|
|
787
852
|
if (presentation.detail === "plan") return /* @__PURE__ */ jsx3("ol", { class: "scui-plan-preview", children: presentation.items?.map((item, index) => /* @__PURE__ */ jsxs2("li", { "data-status": item.status, children: [
|
|
788
853
|
/* @__PURE__ */ jsx3("i", { "aria-hidden": "true" }),
|
|
789
854
|
/* @__PURE__ */ jsx3("span", { children: item.label })
|
package/core.mjs
CHANGED
|
@@ -131,6 +131,13 @@ function sourceString(source, keys) {
|
|
|
131
131
|
return decodedLiteral(match?.[1]);
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
function assignedString(source, keys) {
|
|
135
|
+
if (!source) return '';
|
|
136
|
+
const names = keys.join('|');
|
|
137
|
+
const match = new RegExp(`\\b(?:${names})\\s*=\\s*(\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
|
|
138
|
+
return decodedLiteral(match?.[1]);
|
|
139
|
+
}
|
|
140
|
+
|
|
134
141
|
function callArgumentSource(source, open) {
|
|
135
142
|
let depth = 1;
|
|
136
143
|
let quote = '';
|
|
@@ -243,6 +250,14 @@ function planItems(args) {
|
|
|
243
250
|
}).slice(0, 12);
|
|
244
251
|
}
|
|
245
252
|
|
|
253
|
+
function agentItems(name, resultText) {
|
|
254
|
+
if (!/list.?agents/i.test(name)) return [];
|
|
255
|
+
return (resultText ?? '').split('\n').flatMap((line) => {
|
|
256
|
+
const parts = line.trim().split(/\s+·\s+/).filter(Boolean);
|
|
257
|
+
return parts.length > 1 ? [{ label: boundedString(parts[0], 120), status: boundedString(parts.slice(1).join(' · '), 180) }] : [];
|
|
258
|
+
}).slice(0, 12);
|
|
259
|
+
}
|
|
260
|
+
|
|
246
261
|
function editPreview(args, resultText, source) {
|
|
247
262
|
const direct = firstString(args, ['patch', 'diff']);
|
|
248
263
|
if (direct) return direct;
|
|
@@ -259,6 +274,44 @@ function editPreview(args, resultText, source) {
|
|
|
259
274
|
return /^(?:diff --git|@@ |--- |\+\+\+ )/m.test(resultText ?? '') ? resultText : '';
|
|
260
275
|
}
|
|
261
276
|
|
|
277
|
+
function toolResultEnvelope(resultText) {
|
|
278
|
+
const match = /^Script (?:completed|failed)\r?\nWall time ([0-9.]+) seconds\r?\nOutput:\r?\n([\s\S]*)$/.exec(resultText ?? '');
|
|
279
|
+
if (!match) {
|
|
280
|
+
try {
|
|
281
|
+
const value = JSON.parse(resultText ?? '');
|
|
282
|
+
const object = record(value);
|
|
283
|
+
return {
|
|
284
|
+
preview: typeof value === 'string' ? value : firstString(object, ['output', 'message', 'text', 'summary', 'result']) || resultText || '',
|
|
285
|
+
value: object,
|
|
286
|
+
durationMs: null,
|
|
287
|
+
};
|
|
288
|
+
} catch {
|
|
289
|
+
return { preview: resultText ?? '', value: null, durationMs: null };
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const durationMs = Number(match[1]) * 1_000;
|
|
293
|
+
try {
|
|
294
|
+
const value = record(JSON.parse(match[2]));
|
|
295
|
+
return {
|
|
296
|
+
preview: typeof value?.output === 'string' ? value.output : match[2],
|
|
297
|
+
value,
|
|
298
|
+
durationMs: Number.isFinite(durationMs) ? durationMs : null,
|
|
299
|
+
};
|
|
300
|
+
} catch {
|
|
301
|
+
return { preview: match[2], value: null, durationMs: Number.isFinite(durationMs) ? durationMs : null };
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function semanticAgentPreview(name, status, outcome) {
|
|
306
|
+
const normalized = name.toLocaleLowerCase();
|
|
307
|
+
if (status === 'error') return outcome.preview;
|
|
308
|
+
if (/^(?:agent|task)$|spawn.?agent/.test(normalized) && outcome.preview) return 'Agent is working in the background.';
|
|
309
|
+
if (/send.?message|followup.?task/.test(normalized) && outcome.preview) {
|
|
310
|
+
return /resumed from transcript|resumedAgentId/i.test(outcome.preview) ? 'Agent resumed in the background.' : 'Message delivered.';
|
|
311
|
+
}
|
|
312
|
+
return outcome.preview;
|
|
313
|
+
}
|
|
314
|
+
|
|
262
315
|
function verificationCommand(command) {
|
|
263
316
|
let shell = '';
|
|
264
317
|
let quote = '';
|
|
@@ -276,12 +329,13 @@ function verificationCommand(command) {
|
|
|
276
329
|
function classifyTool(name, command) {
|
|
277
330
|
const normalized = name.toLocaleLowerCase();
|
|
278
331
|
if (/write_stdin|^wait$/.test(normalized)) return 'command';
|
|
279
|
-
if (/update.?plan|todo|checklist|taskcreate|taskupdate/.test(normalized)) return 'plan';
|
|
332
|
+
if (/update.?plan|todo|checklist|taskcreate|taskupdate|create.?goal|update.?goal/.test(normalized)) return 'plan';
|
|
280
333
|
if (/search.?replace|edit|write|patch|replace|create_file|apply_patch/.test(normalized)) return 'edit';
|
|
281
334
|
if (/read|view|open_file|list_dir/.test(normalized)) return 'read';
|
|
335
|
+
if (/web.?search|web.?fetch|fetch.?url/.test(normalized)) return 'web';
|
|
282
336
|
if (/search|find|grep|glob|toolsearch/.test(normalized)) return 'search';
|
|
283
337
|
if (/browser|web|fetch|url/.test(normalized)) return 'web';
|
|
284
|
-
if (/agent|subagent|
|
|
338
|
+
if (/agent|subagent|send.?message|delegate|followup.?task|taskstop|taskoutput|^task$/.test(normalized)) return 'agent';
|
|
285
339
|
if (/test|typecheck|lint|build/.test(normalized)) return 'test';
|
|
286
340
|
if (/terminal|bash|shell|command|exec|write_stdin|^wait$/.test(normalized)) return verificationCommand(command) ? 'test' : 'command';
|
|
287
341
|
return 'other';
|
|
@@ -291,9 +345,17 @@ function toolAction(status, category, name, tools) {
|
|
|
291
345
|
const position = status === 'pending' ? 0 : status === 'error' ? 2 : 1;
|
|
292
346
|
if (tools.length > 1) return [`Running ${tools.length} actions`, `Ran ${tools.length} actions`, `${tools.length} actions failed`][position];
|
|
293
347
|
const normalized = name.toLocaleLowerCase();
|
|
294
|
-
if (/
|
|
295
|
-
if (/kill_command_or_subagent/.test(normalized)) return ['Stopping', 'Stopped', 'Stop failed'][position];
|
|
348
|
+
if (/send.?message|followup.?task/.test(normalized)) return ['Messaging agent', 'Messaged agent', 'Agent message failed'][position];
|
|
349
|
+
if (/taskstop|interrupt.?agent|kill_command_or_subagent/.test(normalized)) return ['Stopping agent', 'Stopped agent', 'Stop failed'][position];
|
|
350
|
+
if (/list.?agents|taskoutput|wait.?agent/.test(normalized)) return ['Checking agents', 'Checked agents', 'Agent check failed'][position];
|
|
296
351
|
if (/get_command_or_subagent_output|write_stdin|^wait$/.test(normalized)) return ['Waiting for', 'Checked', 'Check failed'][position];
|
|
352
|
+
if (/web.?search/.test(normalized)) return ['Searching web', 'Searched web', 'Web search failed'][position];
|
|
353
|
+
if (/web.?fetch|fetch.?url/.test(normalized)) return ['Fetching page', 'Fetched page', 'Page fetch failed'][position];
|
|
354
|
+
if (/^skill$|use.?skill|load.?skill/.test(normalized)) return ['Loading skill', 'Loaded skill', 'Skill load failed'][position];
|
|
355
|
+
if (/taskcreate/.test(normalized)) return ['Adding task', 'Added task', 'Task creation failed'][position];
|
|
356
|
+
if (/taskupdate/.test(normalized)) return ['Updating task', 'Updated task', 'Task update failed'][position];
|
|
357
|
+
if (/create.?goal/.test(normalized)) return ['Creating goal', 'Created goal', 'Goal creation failed'][position];
|
|
358
|
+
if (/update.?goal/.test(normalized)) return ['Updating goal', 'Updated goal', 'Goal update failed'][position];
|
|
297
359
|
const actions = {
|
|
298
360
|
read: ['Reading', 'Read', 'Read failed'],
|
|
299
361
|
search: ['Searching', 'Searched', 'Search failed'],
|
|
@@ -310,18 +372,26 @@ function toolAction(status, category, name, tools) {
|
|
|
310
372
|
export function createToolPresentation(entry) {
|
|
311
373
|
const envelope = toolEnvelope(entry);
|
|
312
374
|
const args = envelope.args;
|
|
375
|
+
const outcome = toolResultEnvelope(entry.resultText);
|
|
376
|
+
const patchSource = assignedString(envelope.source, ['patch']) || envelope.source;
|
|
313
377
|
const command = firstString(args, ['command', 'cmd']) || sourceString(envelope.callSource, ['command', 'cmd']);
|
|
314
378
|
const category = classifyTool(envelope.name, command || envelope.source || entry.arguments || '');
|
|
315
|
-
const path = firstString(args, ['file_path', 'target_file', 'target_directory', 'path']) || sourceString(envelope.callSource, ['file_path', 'target_file', 'target_directory', 'path']) || patchPath(
|
|
379
|
+
const path = firstString(args, ['file_path', 'target_file', 'target_directory', 'path']) || sourceString(envelope.callSource, ['file_path', 'target_file', 'target_directory', 'path']) || patchPath(patchSource);
|
|
316
380
|
const query = firstString(args, ['query', 'pattern']) || sourceString(envelope.callSource, ['query', 'pattern', 'q']);
|
|
317
381
|
const url = firstString(args, ['url']) || sourceString(envelope.callSource, ['url', 'ref_id']);
|
|
318
|
-
const subject = firstString(args, ['subject', 'description', 'summary', 'task', 'prompt']) || sourceString(envelope.callSource, ['subject', 'description', 'summary', 'task', 'prompt']);
|
|
382
|
+
const subject = firstString(args, ['subject', 'description', 'summary', 'task', 'objective', 'prompt']) || sourceString(envelope.callSource, ['subject', 'description', 'summary', 'task', 'objective', 'prompt']);
|
|
383
|
+
const agentTarget = category === 'agent'
|
|
384
|
+
? firstString(record(outcome.value), ['command', 'name']) || firstString(args, ['target', 'task_name', 'taskId', 'task_id', 'agentId', 'agent_id', 'resume', 'team_name']) || sourceString(envelope.callSource, ['target', 'task_name', 'taskId', 'task_id', 'agentId', 'agent_id', 'resume', 'team_name'])
|
|
385
|
+
: '';
|
|
386
|
+
const skillTarget = /^skill$|use.?skill|load.?skill/i.test(envelope.name)
|
|
387
|
+
? firstString(args, ['skill', 'name']) || sourceString(envelope.callSource, ['skill', 'name'])
|
|
388
|
+
: '';
|
|
319
389
|
const background = /get_command_or_subagent_output|kill_command_or_subagent/i.test(envelope.name) ? 'background task' : /write_stdin|^wait$/i.test(envelope.name) ? 'background command' : '';
|
|
320
|
-
const items = planItems(args);
|
|
390
|
+
const items = category === 'agent' ? agentItems(envelope.name, outcome.preview) : planItems(args);
|
|
321
391
|
const taskId = firstString(args, ['taskId', 'task_id']);
|
|
322
392
|
const planTarget = category === 'plan' ? items.length ? `${items.length} ${items.length === 1 ? 'item' : 'items'}` : taskId ? `task ${taskId}` : '' : '';
|
|
323
|
-
const target = path || command || query || url || subject || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
324
|
-
const previewSource = category === 'edit' ? editPreview(args,
|
|
393
|
+
const target = path || command || query || url || subject || agentTarget || skillTarget || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
394
|
+
const previewSource = category === 'edit' ? editPreview(args, outcome.preview, patchSource) : category === 'agent' ? semanticAgentPreview(envelope.name, entry.status ?? 'completed', outcome) : outcome.preview;
|
|
325
395
|
const result = record(entry.resultContent);
|
|
326
396
|
const metadata = record(entry.metadata);
|
|
327
397
|
const resultMetadata = record(result?.metadata);
|
|
@@ -340,8 +410,8 @@ export function createToolPresentation(entry) {
|
|
|
340
410
|
fields: usefulToolFields(args),
|
|
341
411
|
items,
|
|
342
412
|
tools: envelope.tools,
|
|
343
|
-
exitCode: explicitNumber([result, resultMetadata, metadata], ['exit_code', 'exitCode', 'pi_bash_exit_code']),
|
|
344
|
-
durationMs: explicitNumber([result, resultMetadata, metadata], ['duration_ms', 'durationMs', 'elapsed_ms', 'elapsedMs', 'totalDurationMs']),
|
|
413
|
+
exitCode: explicitNumber([outcome.value, result, resultMetadata, metadata], ['exit_code', 'exitCode', 'pi_bash_exit_code']),
|
|
414
|
+
durationMs: explicitNumber([outcome.value, result, resultMetadata, metadata], ['duration_ms', 'durationMs', 'elapsed_ms', 'elapsedMs', 'totalDurationMs']) ?? outcome.durationMs,
|
|
345
415
|
additions: explicitNumber([result, resultMetadata, metadata], ['additions', 'lines_added']),
|
|
346
416
|
deletions: explicitNumber([result, resultMetadata, metadata], ['deletions', 'lines_removed']),
|
|
347
417
|
matches: explicitNumber([result, resultMetadata, metadata], ['matches', 'match_count', 'result_count']),
|
package/embed.mjs
CHANGED
|
@@ -119,6 +119,12 @@ function sourceString(source, keys) {
|
|
|
119
119
|
const match = new RegExp(`(?:^|[,{\\s])["']?(?:${names})["']?\\s*:\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
|
|
120
120
|
return decodedLiteral(match?.[1]);
|
|
121
121
|
}
|
|
122
|
+
function assignedString(source, keys) {
|
|
123
|
+
if (!source) return "";
|
|
124
|
+
const names = keys.join("|");
|
|
125
|
+
const match = new RegExp(`\\b(?:${names})\\s*=\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
|
|
126
|
+
return decodedLiteral(match?.[1]);
|
|
127
|
+
}
|
|
122
128
|
function callArgumentSource(source, open) {
|
|
123
129
|
let depth = 1;
|
|
124
130
|
let quote = "";
|
|
@@ -260,6 +266,13 @@ function planItems(args) {
|
|
|
260
266
|
return [{ label: boundedString(label, 300), status: firstString(value, ["status"]) }];
|
|
261
267
|
}).slice(0, 12);
|
|
262
268
|
}
|
|
269
|
+
function agentItems(name, resultText) {
|
|
270
|
+
if (!/list.?agents/i.test(name)) return [];
|
|
271
|
+
return (resultText ?? "").split("\n").flatMap((line) => {
|
|
272
|
+
const parts = line.trim().split(/\s+·\s+/).filter(Boolean);
|
|
273
|
+
return parts.length > 1 ? [{ label: boundedString(parts[0], 120), status: boundedString(parts.slice(1).join(" \xB7 "), 180) }] : [];
|
|
274
|
+
}).slice(0, 12);
|
|
275
|
+
}
|
|
263
276
|
function editPreview(args, resultText, source) {
|
|
264
277
|
const direct = firstString(args, ["patch", "diff"]);
|
|
265
278
|
if (direct) return direct;
|
|
@@ -275,6 +288,42 @@ function editPreview(args, resultText, source) {
|
|
|
275
288
|
if (patch) return patch;
|
|
276
289
|
return /^(?:diff --git|@@ |--- |\+\+\+ )/m.test(resultText ?? "") ? resultText : "";
|
|
277
290
|
}
|
|
291
|
+
function toolResultEnvelope(resultText) {
|
|
292
|
+
const match = /^Script (?:completed|failed)\r?\nWall time ([0-9.]+) seconds\r?\nOutput:\r?\n([\s\S]*)$/.exec(resultText ?? "");
|
|
293
|
+
if (!match) {
|
|
294
|
+
try {
|
|
295
|
+
const value = JSON.parse(resultText ?? "");
|
|
296
|
+
const object = record(value);
|
|
297
|
+
return {
|
|
298
|
+
preview: typeof value === "string" ? value : firstString(object, ["output", "message", "text", "summary", "result"]) || resultText || "",
|
|
299
|
+
value: object,
|
|
300
|
+
durationMs: null
|
|
301
|
+
};
|
|
302
|
+
} catch {
|
|
303
|
+
return { preview: resultText ?? "", value: null, durationMs: null };
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
const durationMs = Number(match[1]) * 1e3;
|
|
307
|
+
try {
|
|
308
|
+
const value = record(JSON.parse(match[2]));
|
|
309
|
+
return {
|
|
310
|
+
preview: typeof value?.output === "string" ? value.output : match[2],
|
|
311
|
+
value,
|
|
312
|
+
durationMs: Number.isFinite(durationMs) ? durationMs : null
|
|
313
|
+
};
|
|
314
|
+
} catch {
|
|
315
|
+
return { preview: match[2], value: null, durationMs: Number.isFinite(durationMs) ? durationMs : null };
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function semanticAgentPreview(name, status, outcome) {
|
|
319
|
+
const normalized = name.toLocaleLowerCase();
|
|
320
|
+
if (status === "error") return outcome.preview;
|
|
321
|
+
if (/^(?:agent|task)$|spawn.?agent/.test(normalized) && outcome.preview) return "Agent is working in the background.";
|
|
322
|
+
if (/send.?message|followup.?task/.test(normalized) && outcome.preview) {
|
|
323
|
+
return /resumed from transcript|resumedAgentId/i.test(outcome.preview) ? "Agent resumed in the background." : "Message delivered.";
|
|
324
|
+
}
|
|
325
|
+
return outcome.preview;
|
|
326
|
+
}
|
|
278
327
|
function verificationCommand(command) {
|
|
279
328
|
let shell = "";
|
|
280
329
|
let quote = "";
|
|
@@ -307,12 +356,13 @@ function verificationCommand(command) {
|
|
|
307
356
|
function classifyTool(name, command) {
|
|
308
357
|
const normalized = name.toLocaleLowerCase();
|
|
309
358
|
if (/write_stdin|^wait$/.test(normalized)) return "command";
|
|
310
|
-
if (/update.?plan|todo|checklist|taskcreate|taskupdate/.test(normalized)) return "plan";
|
|
359
|
+
if (/update.?plan|todo|checklist|taskcreate|taskupdate|create.?goal|update.?goal/.test(normalized)) return "plan";
|
|
311
360
|
if (/search.?replace|edit|write|patch|replace|create_file|apply_patch/.test(normalized)) return "edit";
|
|
312
361
|
if (/read|view|open_file|list_dir/.test(normalized)) return "read";
|
|
362
|
+
if (/web.?search|web.?fetch|fetch.?url/.test(normalized)) return "web";
|
|
313
363
|
if (/search|find|grep|glob|toolsearch/.test(normalized)) return "search";
|
|
314
364
|
if (/browser|web|fetch|url/.test(normalized)) return "web";
|
|
315
|
-
if (/agent|subagent|
|
|
365
|
+
if (/agent|subagent|send.?message|delegate|followup.?task|taskstop|taskoutput|^task$/.test(normalized)) return "agent";
|
|
316
366
|
if (/test|typecheck|lint|build/.test(normalized)) return "test";
|
|
317
367
|
if (/terminal|bash|shell|command|exec|write_stdin|^wait$/.test(normalized)) return verificationCommand(command) ? "test" : "command";
|
|
318
368
|
return "other";
|
|
@@ -321,9 +371,17 @@ function toolAction(status, category, name, tools) {
|
|
|
321
371
|
const position = status === "pending" ? 0 : status === "error" ? 2 : 1;
|
|
322
372
|
if (tools.length > 1) return [`Running ${tools.length} actions`, `Ran ${tools.length} actions`, `${tools.length} actions failed`][position];
|
|
323
373
|
const normalized = name.toLocaleLowerCase();
|
|
324
|
-
if (/
|
|
325
|
-
if (/kill_command_or_subagent/.test(normalized)) return ["Stopping", "Stopped", "Stop failed"][position];
|
|
374
|
+
if (/send.?message|followup.?task/.test(normalized)) return ["Messaging agent", "Messaged agent", "Agent message failed"][position];
|
|
375
|
+
if (/taskstop|interrupt.?agent|kill_command_or_subagent/.test(normalized)) return ["Stopping agent", "Stopped agent", "Stop failed"][position];
|
|
376
|
+
if (/list.?agents|taskoutput|wait.?agent/.test(normalized)) return ["Checking agents", "Checked agents", "Agent check failed"][position];
|
|
326
377
|
if (/get_command_or_subagent_output|write_stdin|^wait$/.test(normalized)) return ["Waiting for", "Checked", "Check failed"][position];
|
|
378
|
+
if (/web.?search/.test(normalized)) return ["Searching web", "Searched web", "Web search failed"][position];
|
|
379
|
+
if (/web.?fetch|fetch.?url/.test(normalized)) return ["Fetching page", "Fetched page", "Page fetch failed"][position];
|
|
380
|
+
if (/^skill$|use.?skill|load.?skill/.test(normalized)) return ["Loading skill", "Loaded skill", "Skill load failed"][position];
|
|
381
|
+
if (/taskcreate/.test(normalized)) return ["Adding task", "Added task", "Task creation failed"][position];
|
|
382
|
+
if (/taskupdate/.test(normalized)) return ["Updating task", "Updated task", "Task update failed"][position];
|
|
383
|
+
if (/create.?goal/.test(normalized)) return ["Creating goal", "Created goal", "Goal creation failed"][position];
|
|
384
|
+
if (/update.?goal/.test(normalized)) return ["Updating goal", "Updated goal", "Goal update failed"][position];
|
|
327
385
|
const actions = {
|
|
328
386
|
read: ["Reading", "Read", "Read failed"],
|
|
329
387
|
search: ["Searching", "Searched", "Search failed"],
|
|
@@ -339,18 +397,22 @@ function toolAction(status, category, name, tools) {
|
|
|
339
397
|
function createToolPresentation(entry) {
|
|
340
398
|
const envelope = toolEnvelope(entry);
|
|
341
399
|
const args = envelope.args;
|
|
400
|
+
const outcome = toolResultEnvelope(entry.resultText);
|
|
401
|
+
const patchSource = assignedString(envelope.source, ["patch"]) || envelope.source;
|
|
342
402
|
const command = firstString(args, ["command", "cmd"]) || sourceString(envelope.callSource, ["command", "cmd"]);
|
|
343
403
|
const category = classifyTool(envelope.name, command || envelope.source || entry.arguments || "");
|
|
344
|
-
const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.callSource, ["file_path", "target_file", "target_directory", "path"]) || patchPath(
|
|
404
|
+
const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.callSource, ["file_path", "target_file", "target_directory", "path"]) || patchPath(patchSource);
|
|
345
405
|
const query = firstString(args, ["query", "pattern"]) || sourceString(envelope.callSource, ["query", "pattern", "q"]);
|
|
346
406
|
const url = firstString(args, ["url"]) || sourceString(envelope.callSource, ["url", "ref_id"]);
|
|
347
|
-
const subject = firstString(args, ["subject", "description", "summary", "task", "prompt"]) || sourceString(envelope.callSource, ["subject", "description", "summary", "task", "prompt"]);
|
|
407
|
+
const subject = firstString(args, ["subject", "description", "summary", "task", "objective", "prompt"]) || sourceString(envelope.callSource, ["subject", "description", "summary", "task", "objective", "prompt"]);
|
|
408
|
+
const agentTarget = category === "agent" ? firstString(record(outcome.value), ["command", "name"]) || firstString(args, ["target", "task_name", "taskId", "task_id", "agentId", "agent_id", "resume", "team_name"]) || sourceString(envelope.callSource, ["target", "task_name", "taskId", "task_id", "agentId", "agent_id", "resume", "team_name"]) : "";
|
|
409
|
+
const skillTarget = /^skill$|use.?skill|load.?skill/i.test(envelope.name) ? firstString(args, ["skill", "name"]) || sourceString(envelope.callSource, ["skill", "name"]) : "";
|
|
348
410
|
const background = /get_command_or_subagent_output|kill_command_or_subagent/i.test(envelope.name) ? "background task" : /write_stdin|^wait$/i.test(envelope.name) ? "background command" : "";
|
|
349
|
-
const items = planItems(args);
|
|
411
|
+
const items = category === "agent" ? agentItems(envelope.name, outcome.preview) : planItems(args);
|
|
350
412
|
const taskId = firstString(args, ["taskId", "task_id"]);
|
|
351
413
|
const planTarget = category === "plan" ? items.length ? `${items.length} ${items.length === 1 ? "item" : "items"}` : taskId ? `task ${taskId}` : "" : "";
|
|
352
|
-
const target = path || command || query || url || subject || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
353
|
-
const previewSource = category === "edit" ? editPreview(args,
|
|
414
|
+
const target = path || command || query || url || subject || agentTarget || skillTarget || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
415
|
+
const previewSource = category === "edit" ? editPreview(args, outcome.preview, patchSource) : category === "agent" ? semanticAgentPreview(envelope.name, entry.status ?? "completed", outcome) : outcome.preview;
|
|
354
416
|
const result = record(entry.resultContent);
|
|
355
417
|
const metadata = record(entry.metadata);
|
|
356
418
|
const resultMetadata = record(result?.metadata);
|
|
@@ -369,8 +431,8 @@ function createToolPresentation(entry) {
|
|
|
369
431
|
fields: usefulToolFields(args),
|
|
370
432
|
items,
|
|
371
433
|
tools: envelope.tools,
|
|
372
|
-
exitCode: explicitNumber([result, resultMetadata, metadata], ["exit_code", "exitCode", "pi_bash_exit_code"]),
|
|
373
|
-
durationMs: explicitNumber([result, resultMetadata, metadata], ["duration_ms", "durationMs", "elapsed_ms", "elapsedMs", "totalDurationMs"]),
|
|
434
|
+
exitCode: explicitNumber([outcome.value, result, resultMetadata, metadata], ["exit_code", "exitCode", "pi_bash_exit_code"]),
|
|
435
|
+
durationMs: explicitNumber([outcome.value, result, resultMetadata, metadata], ["duration_ms", "durationMs", "elapsed_ms", "elapsedMs", "totalDurationMs"]) ?? outcome.durationMs,
|
|
374
436
|
additions: explicitNumber([result, resultMetadata, metadata], ["additions", "lines_added"]),
|
|
375
437
|
deletions: explicitNumber([result, resultMetadata, metadata], ["deletions", "lines_removed"]),
|
|
376
438
|
matches: explicitNumber([result, resultMetadata, metadata], ["matches", "match_count", "result_count"])
|
|
@@ -1190,7 +1252,10 @@ function ToolPreview({ presentation, entry }) {
|
|
|
1190
1252
|
presentation.url ? /* @__PURE__ */ jsx4("code", { children: presentation.url }) : null,
|
|
1191
1253
|
presentation.preview ? /* @__PURE__ */ jsx4("p", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx4("small", { children: pending ? "Waiting for the page" : "No page summary returned" })
|
|
1192
1254
|
] });
|
|
1193
|
-
if (presentation.detail === "agent") return /* @__PURE__ */ jsx4("section", { class: "scui-agent-preview", children: presentation.
|
|
1255
|
+
if (presentation.detail === "agent") return /* @__PURE__ */ jsx4("section", { class: "scui-agent-preview", children: presentation.items?.length ? /* @__PURE__ */ jsx4("ol", { class: "scui-agent-roster", children: presentation.items.map((item, index) => /* @__PURE__ */ jsxs3("li", { children: [
|
|
1256
|
+
/* @__PURE__ */ jsx4("strong", { children: item.label }),
|
|
1257
|
+
/* @__PURE__ */ jsx4("small", { children: item.status })
|
|
1258
|
+
] }, `${item.label}:${index}`)) }) : presentation.preview ? /* @__PURE__ */ jsx4("pre", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx4("small", { children: pending ? "Agent is working" : "No textual handoff returned" }) });
|
|
1194
1259
|
if (presentation.detail === "plan") return /* @__PURE__ */ jsx4("ol", { class: "scui-plan-preview", children: presentation.items?.map((item, index) => /* @__PURE__ */ jsxs3("li", { "data-status": item.status, children: [
|
|
1195
1260
|
/* @__PURE__ */ jsx4("i", { "aria-hidden": "true" }),
|
|
1196
1261
|
/* @__PURE__ */ jsx4("span", { children: item.label })
|
package/messenger.mjs
CHANGED
|
@@ -116,6 +116,12 @@ function sourceString(source, keys) {
|
|
|
116
116
|
const match = new RegExp(`(?:^|[,{\\s])["']?(?:${names})["']?\\s*:\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
|
|
117
117
|
return decodedLiteral(match?.[1]);
|
|
118
118
|
}
|
|
119
|
+
function assignedString(source, keys) {
|
|
120
|
+
if (!source) return "";
|
|
121
|
+
const names = keys.join("|");
|
|
122
|
+
const match = new RegExp(`\\b(?:${names})\\s*=\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
|
|
123
|
+
return decodedLiteral(match?.[1]);
|
|
124
|
+
}
|
|
119
125
|
function callArgumentSource(source, open) {
|
|
120
126
|
let depth = 1;
|
|
121
127
|
let quote = "";
|
|
@@ -257,6 +263,13 @@ function planItems(args) {
|
|
|
257
263
|
return [{ label: boundedString(label, 300), status: firstString(value, ["status"]) }];
|
|
258
264
|
}).slice(0, 12);
|
|
259
265
|
}
|
|
266
|
+
function agentItems(name, resultText) {
|
|
267
|
+
if (!/list.?agents/i.test(name)) return [];
|
|
268
|
+
return (resultText ?? "").split("\n").flatMap((line) => {
|
|
269
|
+
const parts = line.trim().split(/\s+·\s+/).filter(Boolean);
|
|
270
|
+
return parts.length > 1 ? [{ label: boundedString(parts[0], 120), status: boundedString(parts.slice(1).join(" \xB7 "), 180) }] : [];
|
|
271
|
+
}).slice(0, 12);
|
|
272
|
+
}
|
|
260
273
|
function editPreview(args, resultText, source) {
|
|
261
274
|
const direct = firstString(args, ["patch", "diff"]);
|
|
262
275
|
if (direct) return direct;
|
|
@@ -272,6 +285,42 @@ function editPreview(args, resultText, source) {
|
|
|
272
285
|
if (patch) return patch;
|
|
273
286
|
return /^(?:diff --git|@@ |--- |\+\+\+ )/m.test(resultText ?? "") ? resultText : "";
|
|
274
287
|
}
|
|
288
|
+
function toolResultEnvelope(resultText) {
|
|
289
|
+
const match = /^Script (?:completed|failed)\r?\nWall time ([0-9.]+) seconds\r?\nOutput:\r?\n([\s\S]*)$/.exec(resultText ?? "");
|
|
290
|
+
if (!match) {
|
|
291
|
+
try {
|
|
292
|
+
const value = JSON.parse(resultText ?? "");
|
|
293
|
+
const object = record(value);
|
|
294
|
+
return {
|
|
295
|
+
preview: typeof value === "string" ? value : firstString(object, ["output", "message", "text", "summary", "result"]) || resultText || "",
|
|
296
|
+
value: object,
|
|
297
|
+
durationMs: null
|
|
298
|
+
};
|
|
299
|
+
} catch {
|
|
300
|
+
return { preview: resultText ?? "", value: null, durationMs: null };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
const durationMs = Number(match[1]) * 1e3;
|
|
304
|
+
try {
|
|
305
|
+
const value = record(JSON.parse(match[2]));
|
|
306
|
+
return {
|
|
307
|
+
preview: typeof value?.output === "string" ? value.output : match[2],
|
|
308
|
+
value,
|
|
309
|
+
durationMs: Number.isFinite(durationMs) ? durationMs : null
|
|
310
|
+
};
|
|
311
|
+
} catch {
|
|
312
|
+
return { preview: match[2], value: null, durationMs: Number.isFinite(durationMs) ? durationMs : null };
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function semanticAgentPreview(name, status, outcome) {
|
|
316
|
+
const normalized = name.toLocaleLowerCase();
|
|
317
|
+
if (status === "error") return outcome.preview;
|
|
318
|
+
if (/^(?:agent|task)$|spawn.?agent/.test(normalized) && outcome.preview) return "Agent is working in the background.";
|
|
319
|
+
if (/send.?message|followup.?task/.test(normalized) && outcome.preview) {
|
|
320
|
+
return /resumed from transcript|resumedAgentId/i.test(outcome.preview) ? "Agent resumed in the background." : "Message delivered.";
|
|
321
|
+
}
|
|
322
|
+
return outcome.preview;
|
|
323
|
+
}
|
|
275
324
|
function verificationCommand(command) {
|
|
276
325
|
let shell = "";
|
|
277
326
|
let quote = "";
|
|
@@ -304,12 +353,13 @@ function verificationCommand(command) {
|
|
|
304
353
|
function classifyTool(name, command) {
|
|
305
354
|
const normalized = name.toLocaleLowerCase();
|
|
306
355
|
if (/write_stdin|^wait$/.test(normalized)) return "command";
|
|
307
|
-
if (/update.?plan|todo|checklist|taskcreate|taskupdate/.test(normalized)) return "plan";
|
|
356
|
+
if (/update.?plan|todo|checklist|taskcreate|taskupdate|create.?goal|update.?goal/.test(normalized)) return "plan";
|
|
308
357
|
if (/search.?replace|edit|write|patch|replace|create_file|apply_patch/.test(normalized)) return "edit";
|
|
309
358
|
if (/read|view|open_file|list_dir/.test(normalized)) return "read";
|
|
359
|
+
if (/web.?search|web.?fetch|fetch.?url/.test(normalized)) return "web";
|
|
310
360
|
if (/search|find|grep|glob|toolsearch/.test(normalized)) return "search";
|
|
311
361
|
if (/browser|web|fetch|url/.test(normalized)) return "web";
|
|
312
|
-
if (/agent|subagent|
|
|
362
|
+
if (/agent|subagent|send.?message|delegate|followup.?task|taskstop|taskoutput|^task$/.test(normalized)) return "agent";
|
|
313
363
|
if (/test|typecheck|lint|build/.test(normalized)) return "test";
|
|
314
364
|
if (/terminal|bash|shell|command|exec|write_stdin|^wait$/.test(normalized)) return verificationCommand(command) ? "test" : "command";
|
|
315
365
|
return "other";
|
|
@@ -318,9 +368,17 @@ function toolAction(status, category, name, tools) {
|
|
|
318
368
|
const position = status === "pending" ? 0 : status === "error" ? 2 : 1;
|
|
319
369
|
if (tools.length > 1) return [`Running ${tools.length} actions`, `Ran ${tools.length} actions`, `${tools.length} actions failed`][position];
|
|
320
370
|
const normalized = name.toLocaleLowerCase();
|
|
321
|
-
if (/
|
|
322
|
-
if (/kill_command_or_subagent/.test(normalized)) return ["Stopping", "Stopped", "Stop failed"][position];
|
|
371
|
+
if (/send.?message|followup.?task/.test(normalized)) return ["Messaging agent", "Messaged agent", "Agent message failed"][position];
|
|
372
|
+
if (/taskstop|interrupt.?agent|kill_command_or_subagent/.test(normalized)) return ["Stopping agent", "Stopped agent", "Stop failed"][position];
|
|
373
|
+
if (/list.?agents|taskoutput|wait.?agent/.test(normalized)) return ["Checking agents", "Checked agents", "Agent check failed"][position];
|
|
323
374
|
if (/get_command_or_subagent_output|write_stdin|^wait$/.test(normalized)) return ["Waiting for", "Checked", "Check failed"][position];
|
|
375
|
+
if (/web.?search/.test(normalized)) return ["Searching web", "Searched web", "Web search failed"][position];
|
|
376
|
+
if (/web.?fetch|fetch.?url/.test(normalized)) return ["Fetching page", "Fetched page", "Page fetch failed"][position];
|
|
377
|
+
if (/^skill$|use.?skill|load.?skill/.test(normalized)) return ["Loading skill", "Loaded skill", "Skill load failed"][position];
|
|
378
|
+
if (/taskcreate/.test(normalized)) return ["Adding task", "Added task", "Task creation failed"][position];
|
|
379
|
+
if (/taskupdate/.test(normalized)) return ["Updating task", "Updated task", "Task update failed"][position];
|
|
380
|
+
if (/create.?goal/.test(normalized)) return ["Creating goal", "Created goal", "Goal creation failed"][position];
|
|
381
|
+
if (/update.?goal/.test(normalized)) return ["Updating goal", "Updated goal", "Goal update failed"][position];
|
|
324
382
|
const actions = {
|
|
325
383
|
read: ["Reading", "Read", "Read failed"],
|
|
326
384
|
search: ["Searching", "Searched", "Search failed"],
|
|
@@ -336,18 +394,22 @@ function toolAction(status, category, name, tools) {
|
|
|
336
394
|
function createToolPresentation(entry) {
|
|
337
395
|
const envelope = toolEnvelope(entry);
|
|
338
396
|
const args = envelope.args;
|
|
397
|
+
const outcome = toolResultEnvelope(entry.resultText);
|
|
398
|
+
const patchSource = assignedString(envelope.source, ["patch"]) || envelope.source;
|
|
339
399
|
const command = firstString(args, ["command", "cmd"]) || sourceString(envelope.callSource, ["command", "cmd"]);
|
|
340
400
|
const category = classifyTool(envelope.name, command || envelope.source || entry.arguments || "");
|
|
341
|
-
const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.callSource, ["file_path", "target_file", "target_directory", "path"]) || patchPath(
|
|
401
|
+
const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.callSource, ["file_path", "target_file", "target_directory", "path"]) || patchPath(patchSource);
|
|
342
402
|
const query = firstString(args, ["query", "pattern"]) || sourceString(envelope.callSource, ["query", "pattern", "q"]);
|
|
343
403
|
const url = firstString(args, ["url"]) || sourceString(envelope.callSource, ["url", "ref_id"]);
|
|
344
|
-
const subject = firstString(args, ["subject", "description", "summary", "task", "prompt"]) || sourceString(envelope.callSource, ["subject", "description", "summary", "task", "prompt"]);
|
|
404
|
+
const subject = firstString(args, ["subject", "description", "summary", "task", "objective", "prompt"]) || sourceString(envelope.callSource, ["subject", "description", "summary", "task", "objective", "prompt"]);
|
|
405
|
+
const agentTarget = category === "agent" ? firstString(record(outcome.value), ["command", "name"]) || firstString(args, ["target", "task_name", "taskId", "task_id", "agentId", "agent_id", "resume", "team_name"]) || sourceString(envelope.callSource, ["target", "task_name", "taskId", "task_id", "agentId", "agent_id", "resume", "team_name"]) : "";
|
|
406
|
+
const skillTarget = /^skill$|use.?skill|load.?skill/i.test(envelope.name) ? firstString(args, ["skill", "name"]) || sourceString(envelope.callSource, ["skill", "name"]) : "";
|
|
345
407
|
const background = /get_command_or_subagent_output|kill_command_or_subagent/i.test(envelope.name) ? "background task" : /write_stdin|^wait$/i.test(envelope.name) ? "background command" : "";
|
|
346
|
-
const items = planItems(args);
|
|
408
|
+
const items = category === "agent" ? agentItems(envelope.name, outcome.preview) : planItems(args);
|
|
347
409
|
const taskId = firstString(args, ["taskId", "task_id"]);
|
|
348
410
|
const planTarget = category === "plan" ? items.length ? `${items.length} ${items.length === 1 ? "item" : "items"}` : taskId ? `task ${taskId}` : "" : "";
|
|
349
|
-
const target = path || command || query || url || subject || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
350
|
-
const previewSource = category === "edit" ? editPreview(args,
|
|
411
|
+
const target = path || command || query || url || subject || agentTarget || skillTarget || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
412
|
+
const previewSource = category === "edit" ? editPreview(args, outcome.preview, patchSource) : category === "agent" ? semanticAgentPreview(envelope.name, entry.status ?? "completed", outcome) : outcome.preview;
|
|
351
413
|
const result = record(entry.resultContent);
|
|
352
414
|
const metadata = record(entry.metadata);
|
|
353
415
|
const resultMetadata = record(result?.metadata);
|
|
@@ -366,8 +428,8 @@ function createToolPresentation(entry) {
|
|
|
366
428
|
fields: usefulToolFields(args),
|
|
367
429
|
items,
|
|
368
430
|
tools: envelope.tools,
|
|
369
|
-
exitCode: explicitNumber([result, resultMetadata, metadata], ["exit_code", "exitCode", "pi_bash_exit_code"]),
|
|
370
|
-
durationMs: explicitNumber([result, resultMetadata, metadata], ["duration_ms", "durationMs", "elapsed_ms", "elapsedMs", "totalDurationMs"]),
|
|
431
|
+
exitCode: explicitNumber([outcome.value, result, resultMetadata, metadata], ["exit_code", "exitCode", "pi_bash_exit_code"]),
|
|
432
|
+
durationMs: explicitNumber([outcome.value, result, resultMetadata, metadata], ["duration_ms", "durationMs", "elapsed_ms", "elapsedMs", "totalDurationMs"]) ?? outcome.durationMs,
|
|
371
433
|
additions: explicitNumber([result, resultMetadata, metadata], ["additions", "lines_added"]),
|
|
372
434
|
deletions: explicitNumber([result, resultMetadata, metadata], ["deletions", "lines_removed"]),
|
|
373
435
|
matches: explicitNumber([result, resultMetadata, metadata], ["matches", "match_count", "result_count"])
|
|
@@ -1187,7 +1249,10 @@ function ToolPreview({ presentation, entry }) {
|
|
|
1187
1249
|
presentation.url ? /* @__PURE__ */ jsx4("code", { children: presentation.url }) : null,
|
|
1188
1250
|
presentation.preview ? /* @__PURE__ */ jsx4("p", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx4("small", { children: pending ? "Waiting for the page" : "No page summary returned" })
|
|
1189
1251
|
] });
|
|
1190
|
-
if (presentation.detail === "agent") return /* @__PURE__ */ jsx4("section", { class: "scui-agent-preview", children: presentation.
|
|
1252
|
+
if (presentation.detail === "agent") return /* @__PURE__ */ jsx4("section", { class: "scui-agent-preview", children: presentation.items?.length ? /* @__PURE__ */ jsx4("ol", { class: "scui-agent-roster", children: presentation.items.map((item, index) => /* @__PURE__ */ jsxs3("li", { children: [
|
|
1253
|
+
/* @__PURE__ */ jsx4("strong", { children: item.label }),
|
|
1254
|
+
/* @__PURE__ */ jsx4("small", { children: item.status })
|
|
1255
|
+
] }, `${item.label}:${index}`)) }) : presentation.preview ? /* @__PURE__ */ jsx4("pre", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx4("small", { children: pending ? "Agent is working" : "No textual handoff returned" }) });
|
|
1191
1256
|
if (presentation.detail === "plan") return /* @__PURE__ */ jsx4("ol", { class: "scui-plan-preview", children: presentation.items?.map((item, index) => /* @__PURE__ */ jsxs3("li", { "data-status": item.status, children: [
|
|
1192
1257
|
/* @__PURE__ */ jsx4("i", { "aria-hidden": "true" }),
|
|
1193
1258
|
/* @__PURE__ */ jsx4("span", { children: item.label })
|
package/package.json
CHANGED
package/styles.css
CHANGED
|
@@ -158,6 +158,7 @@
|
|
|
158
158
|
.scui-code-preview { margin:0; padding:5px 0; overflow:auto; counter-reset:line; color:var(--scui-fg); font:9.5px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace; list-style:none }.scui-code-preview li { display:grid; grid-template-columns:31px minmax(max-content,1fr); min-height:15px }.scui-code-preview li > span { padding-right:7px; color:var(--scui-muted); text-align:right; user-select:none }.scui-code-preview code { padding:0 8px; white-space:pre }.scui-code-preview li[data-tone="add"] { background:color-mix(in srgb,var(--scui-success) 11%,transparent) }.scui-code-preview li[data-tone="remove"] { background:color-mix(in srgb,var(--scui-danger) 10%,transparent) }.scui-code-preview li[data-tone="hunk"] { color:var(--scui-accent) }
|
|
159
159
|
.scui-search-preview header { display:flex; align-items:center; gap:6px; padding:7px 8px; border-bottom:1px solid var(--scui-border) }.scui-search-preview header span { color:var(--scui-muted) }.scui-search-preview header code { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }.scui-search-preview ol { display:grid; margin:0; padding:3px 0; list-style:none }.scui-search-preview li { display:grid; grid-template-columns:minmax(0,auto) auto minmax(70px,1fr); align-items:baseline; gap:5px; padding:3px 8px; border-bottom:1px solid color-mix(in srgb,var(--scui-border) 60%,transparent) }.scui-search-preview li:last-child { border:0 }.scui-search-preview li code { overflow:hidden; color:var(--scui-accent); text-overflow:ellipsis; white-space:nowrap }.scui-search-preview li small { color:var(--scui-muted) }.scui-search-preview li span { min-width:0; overflow:hidden; color:var(--scui-fg); text-overflow:ellipsis; white-space:nowrap }.scui-search-preview p { margin:0; padding:8px; color:var(--scui-muted) }
|
|
160
160
|
.scui-web-preview,.scui-agent-preview { display:grid; gap:6px; padding:8px }.scui-web-preview > code { overflow:hidden; color:var(--scui-accent); text-overflow:ellipsis; white-space:nowrap }.scui-web-preview p,.scui-agent-preview p { margin:0; color:var(--scui-fg); line-height:1.45 }.scui-web-preview small,.scui-agent-preview small,.scui-tool-empty { padding:8px; color:var(--scui-muted) }
|
|
161
|
+
.scui-agent-roster { display:grid; gap:1px; margin:0; padding:0; list-style:none }.scui-agent-roster li { display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:center; gap:8px; min-height:27px; padding:3px 6px; border-bottom:1px solid var(--scui-border) }.scui-agent-roster li:last-child { border-bottom:0 }.scui-agent-roster strong { min-width:0; overflow:hidden; color:var(--scui-fg); font:10px ui-monospace,SFMono-Regular,Menlo,monospace; text-overflow:ellipsis; white-space:nowrap }.scui-agent-roster small { padding:0; text-align:right; white-space:nowrap }
|
|
161
162
|
.scui-plan-preview { display:grid; gap:5px; margin:0; padding:8px; list-style:none }.scui-plan-preview li { display:flex; align-items:flex-start; gap:6px; color:var(--scui-fg) }.scui-plan-preview li i { flex:0 0 8px; width:8px; height:8px; margin-top:3px; border:1px solid var(--scui-border-strong); border-radius:50% }.scui-plan-preview li[data-status="completed"] { color:var(--scui-muted); text-decoration:line-through }.scui-plan-preview li[data-status="completed"] i { border-color:var(--scui-success); background:var(--scui-success) }.scui-plan-preview li[data-status="in_progress"] i { border-color:var(--scui-accent); box-shadow:inset 0 0 0 2px var(--scui-bg-raised); background:var(--scui-accent) }
|
|
162
163
|
.scui-tool-fields { display:grid; gap:5px; margin:0; padding:0 8px 8px }.scui-tool-fields > div { display:grid; grid-template-columns:minmax(65px,auto) 1fr; gap:8px }.scui-tool-fields dt { color:var(--scui-muted) }.scui-tool-fields dd { min-width:0; margin:0; overflow-wrap:anywhere; color:var(--scui-fg) }
|
|
163
164
|
.scui-tool-actions { display:flex; gap:5px; padding:0 8px }.scui-tool-actions button { padding:3px 6px; border:1px solid var(--scui-border); border-radius:5px; background:transparent; color:var(--scui-muted); cursor:pointer; font:inherit; font-size:9.5px }.scui-tool-actions button:hover { border-color:var(--scui-border-strong); color:var(--scui-fg) }
|