@volter-ai-dev/supercode-ui 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components.mjs +141 -40
- package/conversation.mjs +137 -40
- package/core.mjs +111 -29
- package/embed.mjs +141 -40
- package/index.d.ts +5 -1
- package/messenger.mjs +141 -40
- package/package.json +1 -1
- package/styles.css +3 -0
package/messenger.mjs
CHANGED
|
@@ -85,10 +85,10 @@ function boundedString(value, max) {
|
|
|
85
85
|
if (typeof value !== "string") return "";
|
|
86
86
|
return value.length <= max ? value : `${value.slice(0, max)}\u2026`;
|
|
87
87
|
}
|
|
88
|
-
function
|
|
88
|
+
function argumentValue(argumentsText) {
|
|
89
89
|
if (!argumentsText) return null;
|
|
90
90
|
try {
|
|
91
|
-
return
|
|
91
|
+
return JSON.parse(argumentsText);
|
|
92
92
|
} catch {
|
|
93
93
|
return null;
|
|
94
94
|
}
|
|
@@ -99,6 +99,33 @@ function firstString(source, keys) {
|
|
|
99
99
|
}
|
|
100
100
|
return "";
|
|
101
101
|
}
|
|
102
|
+
function decodedLiteral(value) {
|
|
103
|
+
if (!value) return "";
|
|
104
|
+
if (value.startsWith('"')) {
|
|
105
|
+
try {
|
|
106
|
+
return JSON.parse(value);
|
|
107
|
+
} catch {
|
|
108
|
+
return "";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return value.slice(1, -1).replaceAll("\\n", "\n").replaceAll("\\t", " ").replaceAll("\\r", "\r").replaceAll("\\`", "`").replaceAll("\\'", "'").replaceAll("\\\\", "\\");
|
|
112
|
+
}
|
|
113
|
+
function sourceString(source, keys) {
|
|
114
|
+
if (!source) return "";
|
|
115
|
+
const names = keys.join("|");
|
|
116
|
+
const match = new RegExp(`\\b(?:${names})\\s*:\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
|
|
117
|
+
return decodedLiteral(match?.[1]);
|
|
118
|
+
}
|
|
119
|
+
function toolEnvelope(entry) {
|
|
120
|
+
const value = argumentValue(entry.arguments);
|
|
121
|
+
const source = typeof value === "string" ? value : "";
|
|
122
|
+
const tools = source ? [...new Set([...source.matchAll(/\btools\.([A-Za-z0-9_]+)/g)].map((match) => match[1]))].slice(0, 8) : [];
|
|
123
|
+
const name = tools.length === 1 ? tools[0] : entry.label ?? "tool";
|
|
124
|
+
return { args: record(value), source, tools, name };
|
|
125
|
+
}
|
|
126
|
+
function patchPath(source) {
|
|
127
|
+
return /\*\*\* (?:Update|Add|Delete) File:\s*([^\r\n]+)/.exec(source)?.[1]?.trim() ?? "";
|
|
128
|
+
}
|
|
102
129
|
function explicitNumber(sources, keys) {
|
|
103
130
|
for (const source of sources) {
|
|
104
131
|
for (const key of keys) {
|
|
@@ -132,7 +159,7 @@ function planItems(args) {
|
|
|
132
159
|
return [{ label: boundedString(label, 300), status: firstString(value, ["status"]) }];
|
|
133
160
|
}).slice(0, 12);
|
|
134
161
|
}
|
|
135
|
-
function editPreview(args, resultText) {
|
|
162
|
+
function editPreview(args, resultText, source) {
|
|
136
163
|
const direct = firstString(args, ["patch", "diff"]);
|
|
137
164
|
if (direct) return direct;
|
|
138
165
|
const oldText = firstString(args, ["old_string"]);
|
|
@@ -143,21 +170,63 @@ function editPreview(args, resultText) {
|
|
|
143
170
|
...newText.split("\n").map((line) => `+ ${line}`)
|
|
144
171
|
].join("\n");
|
|
145
172
|
}
|
|
173
|
+
const patch = /\*\*\* Begin Patch[\s\S]*?\*\*\* End Patch/.exec(source ?? "")?.[0];
|
|
174
|
+
if (patch) return patch;
|
|
146
175
|
return /^(?:diff --git|@@ |--- |\+\+\+ )/m.test(resultText ?? "") ? resultText : "";
|
|
147
176
|
}
|
|
177
|
+
function classifyTool(name, command) {
|
|
178
|
+
const normalized = name.toLocaleLowerCase();
|
|
179
|
+
if (/write_stdin|^wait$/.test(normalized)) return "command";
|
|
180
|
+
if (/update.?plan|todo|checklist|taskcreate|taskupdate/.test(normalized)) return "plan";
|
|
181
|
+
if (/search.?replace|edit|write|patch|replace|create_file|apply_patch/.test(normalized)) return "edit";
|
|
182
|
+
if (/read|view|open_file|list_dir/.test(normalized)) return "read";
|
|
183
|
+
if (/search|find|grep|glob|toolsearch/.test(normalized)) return "search";
|
|
184
|
+
if (/browser|web|fetch|url/.test(normalized)) return "web";
|
|
185
|
+
if (/agent|subagent|sendmessage|delegate|^task$/.test(normalized)) return "agent";
|
|
186
|
+
if (/test|typecheck|lint|build/.test(normalized)) return "test";
|
|
187
|
+
if (/terminal|bash|shell|command|exec|write_stdin|^wait$/.test(normalized)) return /\b(test|typecheck|lint|build)\b/i.test(command) ? "test" : "command";
|
|
188
|
+
return "other";
|
|
189
|
+
}
|
|
190
|
+
function toolAction(status, category, name, tools) {
|
|
191
|
+
const position = status === "pending" ? 0 : status === "error" ? 2 : 1;
|
|
192
|
+
if (tools.length > 1) return [`Running ${tools.length} actions`, `Ran ${tools.length} actions`, `${tools.length} actions failed`][position];
|
|
193
|
+
const normalized = name.toLocaleLowerCase();
|
|
194
|
+
if (/sendmessage/.test(normalized)) return ["Messaging agent", "Messaged agent", "Agent message failed"][position];
|
|
195
|
+
if (/kill_command_or_subagent/.test(normalized)) return ["Stopping", "Stopped", "Stop failed"][position];
|
|
196
|
+
if (/get_command_or_subagent_output|write_stdin|^wait$/.test(normalized)) return ["Waiting for", "Checked", "Check failed"][position];
|
|
197
|
+
const actions = {
|
|
198
|
+
read: ["Reading", "Read", "Read failed"],
|
|
199
|
+
search: ["Searching", "Searched", "Search failed"],
|
|
200
|
+
edit: ["Editing", "Edited", "Edit failed"],
|
|
201
|
+
command: ["Running command", "Ran command", "Command failed"],
|
|
202
|
+
test: ["Running tests", "Ran tests", "Tests failed"],
|
|
203
|
+
web: ["Browsing", "Browsed", "Browser action failed"],
|
|
204
|
+
agent: ["Starting agent", "Started agent", "Agent failed"],
|
|
205
|
+
plan: ["Updating plan", "Updated plan", "Plan update failed"]
|
|
206
|
+
};
|
|
207
|
+
return actions[category]?.[position] ?? (status === "error" ? `${name} failed` : name.replaceAll(/[_-]+/g, " "));
|
|
208
|
+
}
|
|
148
209
|
function createToolPresentation(entry) {
|
|
149
|
-
const
|
|
150
|
-
const
|
|
151
|
-
const command = firstString(args, ["command", "cmd"]);
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
const
|
|
155
|
-
const
|
|
156
|
-
const
|
|
157
|
-
const
|
|
210
|
+
const envelope = toolEnvelope(entry);
|
|
211
|
+
const args = envelope.args;
|
|
212
|
+
const command = firstString(args, ["command", "cmd"]) || sourceString(envelope.source, ["command", "cmd"]);
|
|
213
|
+
const category = classifyTool(envelope.name, command || envelope.source || entry.arguments || "");
|
|
214
|
+
const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.source, ["file_path", "target_file", "target_directory", "path"]) || patchPath(envelope.source);
|
|
215
|
+
const query = firstString(args, ["query", "pattern"]) || sourceString(envelope.source, ["query", "pattern", "q"]);
|
|
216
|
+
const url = firstString(args, ["url"]) || sourceString(envelope.source, ["url", "ref_id"]);
|
|
217
|
+
const subject = firstString(args, ["subject", "description", "summary", "task", "prompt"]) || sourceString(envelope.source, ["subject", "description", "summary", "task", "prompt"]);
|
|
218
|
+
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" : "";
|
|
219
|
+
const items = planItems(args);
|
|
220
|
+
const taskId = firstString(args, ["taskId", "task_id"]);
|
|
221
|
+
const planTarget = category === "plan" ? items.length ? `${items.length} ${items.length === 1 ? "item" : "items"}` : taskId ? `task ${taskId}` : "" : "";
|
|
222
|
+
const target = path || command || query || url || subject || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
223
|
+
const previewSource = category === "edit" ? editPreview(args, entry.resultText, envelope.source) : entry.resultText ?? "";
|
|
158
224
|
const result = record(entry.resultContent);
|
|
159
225
|
const metadata = record(entry.metadata);
|
|
226
|
+
const resultMetadata = record(result?.metadata);
|
|
160
227
|
return {
|
|
228
|
+
name: boundedString(envelope.name, 120),
|
|
229
|
+
action: boundedString(toolAction(entry.status ?? "completed", category, envelope.name, envelope.tools), 120),
|
|
161
230
|
category,
|
|
162
231
|
detail: toolDetail(category),
|
|
163
232
|
target: boundedString(target, 300),
|
|
@@ -168,12 +237,13 @@ function createToolPresentation(entry) {
|
|
|
168
237
|
subject: boundedString(subject, MAX_TOOL_FIELD_CHARS),
|
|
169
238
|
preview: boundedString(previewSource, MAX_TOOL_PREVIEW_CHARS),
|
|
170
239
|
fields: usefulToolFields(args),
|
|
171
|
-
items
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
240
|
+
items,
|
|
241
|
+
tools: envelope.tools,
|
|
242
|
+
exitCode: explicitNumber([result, resultMetadata, metadata], ["exit_code", "exitCode", "pi_bash_exit_code"]),
|
|
243
|
+
durationMs: explicitNumber([result, resultMetadata, metadata], ["duration_ms", "durationMs", "elapsed_ms", "elapsedMs", "totalDurationMs"]),
|
|
244
|
+
additions: explicitNumber([result, resultMetadata, metadata], ["additions", "lines_added"]),
|
|
245
|
+
deletions: explicitNumber([result, resultMetadata, metadata], ["deletions", "lines_removed"]),
|
|
246
|
+
matches: explicitNumber([result, resultMetadata, metadata], ["matches", "match_count", "result_count"])
|
|
177
247
|
};
|
|
178
248
|
}
|
|
179
249
|
function readToolPresentation(value, entry) {
|
|
@@ -188,7 +258,10 @@ function readToolPresentation(value, entry) {
|
|
|
188
258
|
const planItem = record(raw);
|
|
189
259
|
return planItem && typeof planItem.label === "string" ? [{ label: boundedString(planItem.label, 300), status: boundedString(planItem.status, 40) }] : [];
|
|
190
260
|
}).slice(0, 12) : generated.items;
|
|
261
|
+
const tools = Array.isArray(item.tools) ? item.tools.filter((tool) => typeof tool === "string").map((tool) => boundedString(tool, 120)).slice(0, 8) : generated.tools;
|
|
191
262
|
return {
|
|
263
|
+
name: boundedString(item.name, 120) || generated.name,
|
|
264
|
+
action: boundedString(item.action, 120) || generated.action,
|
|
192
265
|
category: TOOL_CATEGORIES.has(item.category) ? item.category : generated.category,
|
|
193
266
|
detail: TOOL_DETAILS.has(item.detail) ? item.detail : generated.detail,
|
|
194
267
|
target: boundedString(item.target, 300) || generated.target,
|
|
@@ -200,6 +273,7 @@ function readToolPresentation(value, entry) {
|
|
|
200
273
|
preview: boundedString(item.preview, MAX_TOOL_PREVIEW_CHARS) || generated.preview,
|
|
201
274
|
fields,
|
|
202
275
|
items,
|
|
276
|
+
tools,
|
|
203
277
|
exitCode: nullableNumber(item.exitCode) ?? generated.exitCode,
|
|
204
278
|
durationMs: nullableNumber(item.durationMs) ?? generated.durationMs,
|
|
205
279
|
additions: nullableNumber(item.additions) ?? generated.additions,
|
|
@@ -433,16 +507,9 @@ function groupConversation(entries) {
|
|
|
433
507
|
}
|
|
434
508
|
function toolCategory(entry) {
|
|
435
509
|
if (TOOL_CATEGORIES.has(entry.presentation?.category)) return entry.presentation.category;
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
if (/edit|write|patch|replace|create_file/.test(name)) return "edit";
|
|
440
|
-
if (/test|typecheck|lint|build/.test(name)) return "test";
|
|
441
|
-
if (/terminal|bash|shell|command|exec/.test(name)) return /\b(test|typecheck|lint|build)\b/i.test(entry.arguments ?? "") ? "test" : "command";
|
|
442
|
-
if (/browser|web|fetch|url/.test(name)) return "web";
|
|
443
|
-
if (/update.?plan|todo|checklist/.test(name)) return "plan";
|
|
444
|
-
if (/subagent|spawn.?agent|delegate|^task$/.test(name)) return "agent";
|
|
445
|
-
return "other";
|
|
510
|
+
const envelope = toolEnvelope(entry);
|
|
511
|
+
const command = firstString(envelope.args, ["command", "cmd"]) || sourceString(envelope.source, ["command", "cmd"]);
|
|
512
|
+
return classifyTool(envelope.name, command || envelope.source || entry.arguments || "");
|
|
446
513
|
}
|
|
447
514
|
function toolTarget(argumentsText) {
|
|
448
515
|
if (!argumentsText) return "";
|
|
@@ -468,7 +535,8 @@ function activitySummary(entries) {
|
|
|
468
535
|
if (pending) return `${entries.length} actions in progress`;
|
|
469
536
|
if (failed) return `${entries.length} actions \xB7 ${failed} failed`;
|
|
470
537
|
if ([...counts.keys()].every((key) => key === "read" || key === "search")) return `Explored ${entries.length} ${entries.length === 1 ? "item" : "items"}`;
|
|
471
|
-
|
|
538
|
+
const nouns = { read: ["read", "reads"], search: ["search", "searches"], edit: ["edit", "edits"], command: ["command", "commands"], test: ["test run", "test runs"], web: ["web action", "web actions"], agent: ["agent action", "agent actions"], plan: ["plan update", "plan updates"], other: ["action", "actions"] };
|
|
539
|
+
return [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3).map(([category, count]) => `${count} ${nouns[category][count === 1 ? 0 : 1]}`).join(" \xB7 ");
|
|
472
540
|
}
|
|
473
541
|
function canContinueHere(state) {
|
|
474
542
|
if (state.mode !== "mirror" || state.canSend) return false;
|
|
@@ -691,7 +759,8 @@ function ToolIcon({ category }) {
|
|
|
691
759
|
const Glyph = TOOL_ICONS[category] ?? TOOL_ICONS.other;
|
|
692
760
|
return /* @__PURE__ */ jsx3("svg", { class: "scui-tool-icon", viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", "stroke-width": "1.35", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(Glyph, {}) });
|
|
693
761
|
}
|
|
694
|
-
function
|
|
762
|
+
function toolAction2(entry, category, presentation) {
|
|
763
|
+
if (presentation?.action) return presentation.action;
|
|
695
764
|
const status = entry.status ?? "completed";
|
|
696
765
|
const actions = {
|
|
697
766
|
read: ["Reading", "Read", "Read failed"],
|
|
@@ -745,6 +814,16 @@ function ToolMetrics({ presentation }) {
|
|
|
745
814
|
].filter(Boolean);
|
|
746
815
|
return metrics.length ? /* @__PURE__ */ jsx3("div", { class: "scui-tool-metrics", children: metrics.map((metric) => /* @__PURE__ */ jsx3("span", { children: metric }, metric)) }) : null;
|
|
747
816
|
}
|
|
817
|
+
function PendingElapsed({ now }) {
|
|
818
|
+
const clock = now ?? Date.now;
|
|
819
|
+
const started = useRef2(clock());
|
|
820
|
+
const [elapsed, setElapsed] = useState2(0);
|
|
821
|
+
useEffect2(() => {
|
|
822
|
+
const timer = setInterval(() => setElapsed(Math.max(0, clock() - started.current)), 1e3);
|
|
823
|
+
return () => clearInterval(timer);
|
|
824
|
+
}, [clock]);
|
|
825
|
+
return /* @__PURE__ */ jsx3("small", { class: "scui-tool-elapsed", children: elapsed < 1e3 ? "now" : formatDuration(elapsed) });
|
|
826
|
+
}
|
|
748
827
|
function LinePreview({ value, kind }) {
|
|
749
828
|
if (!value) return null;
|
|
750
829
|
return /* @__PURE__ */ jsx3("ol", { class: "scui-code-preview", "data-kind": kind, children: stripAnsi(value).split("\n").map((line, index) => {
|
|
@@ -802,16 +881,31 @@ function ToolPreview({ presentation, entry }) {
|
|
|
802
881
|
presentation.url ? /* @__PURE__ */ jsx3("code", { children: presentation.url }) : null,
|
|
803
882
|
presentation.preview ? /* @__PURE__ */ jsx3("p", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx3("small", { children: pending ? "Waiting for the page" : "No page summary returned" })
|
|
804
883
|
] });
|
|
805
|
-
if (presentation.detail === "agent") return /* @__PURE__ */
|
|
806
|
-
presentation.subject ? /* @__PURE__ */ jsx3("p", { children: presentation.subject }) : null,
|
|
807
|
-
presentation.preview ? /* @__PURE__ */ jsx3("pre", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx3("small", { children: pending ? "Agent is working" : "No textual handoff returned" })
|
|
808
|
-
] });
|
|
884
|
+
if (presentation.detail === "agent") return /* @__PURE__ */ jsx3("section", { class: "scui-agent-preview", children: presentation.preview ? /* @__PURE__ */ jsx3("pre", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx3("small", { children: pending ? "Agent is working" : "No textual handoff returned" }) });
|
|
809
885
|
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: [
|
|
810
886
|
/* @__PURE__ */ jsx3("i", { "aria-hidden": "true" }),
|
|
811
887
|
/* @__PURE__ */ jsx3("span", { children: item.label })
|
|
812
888
|
] }, `${item.label}:${index}`)) });
|
|
813
889
|
return presentation.preview ? /* @__PURE__ */ jsx3("pre", { class: "scui-tool-output", "data-error": failed, children: stripAnsi(presentation.preview) }) : null;
|
|
814
890
|
}
|
|
891
|
+
function ToolActions({ presentation, adapter }) {
|
|
892
|
+
const [copied, setCopied] = useState2(false);
|
|
893
|
+
const reset = useRef2(null);
|
|
894
|
+
useEffect2(() => () => clearTimeout(reset.current), []);
|
|
895
|
+
if (!adapter?.copyText) return null;
|
|
896
|
+
const action = presentation.command ? ["Copy command", presentation.command] : presentation.path ? ["Copy path", presentation.path] : presentation.url ? ["Copy URL", presentation.url] : presentation.query ? ["Copy query", presentation.query] : null;
|
|
897
|
+
const copy = async () => {
|
|
898
|
+
await adapter.copyText(action[1]);
|
|
899
|
+
setCopied(true);
|
|
900
|
+
clearTimeout(reset.current);
|
|
901
|
+
reset.current = setTimeout(() => setCopied(false), 1500);
|
|
902
|
+
};
|
|
903
|
+
return action ? /* @__PURE__ */ jsx3("div", { class: "scui-tool-actions", children: /* @__PURE__ */ jsx3("button", { type: "button", onClick: copy, children: copied ? "Copied" : action[0] }) }) : null;
|
|
904
|
+
}
|
|
905
|
+
function ToolStack({ tools }) {
|
|
906
|
+
if (tools.length < 2) return null;
|
|
907
|
+
return /* @__PURE__ */ jsx3("div", { class: "scui-tool-stack", "aria-label": "Coordinated tools", children: tools.map((tool) => /* @__PURE__ */ jsx3("span", { children: tool.replaceAll("__", " \xB7 ").replaceAll("_", " ") }, tool)) });
|
|
908
|
+
}
|
|
815
909
|
function TechnicalDetails({ entry }) {
|
|
816
910
|
if (!entry.arguments && !entry.resultText) return null;
|
|
817
911
|
return /* @__PURE__ */ jsxs2("details", { class: "scui-tool-technical", children: [
|
|
@@ -849,35 +943,42 @@ function TranscriptEntry({ entry, state, adapter }) {
|
|
|
849
943
|
entry.truncated ? /* @__PURE__ */ jsx3("small", { class: "scui-truncated", children: "Entry truncated by host \xB7 load native session for the complete value" }) : null
|
|
850
944
|
] });
|
|
851
945
|
}
|
|
852
|
-
function ToolRow({ entry, workspace, open = false }) {
|
|
946
|
+
function ToolRow({ entry, workspace, open = false, adapter }) {
|
|
853
947
|
const presentation = entry.presentation ?? createToolPresentation(entry);
|
|
948
|
+
const [expanded, setExpanded] = useState2(open || entry.status === "pending");
|
|
949
|
+
useEffect2(() => {
|
|
950
|
+
if (entry.status === "pending") setExpanded(true);
|
|
951
|
+
}, [entry.status]);
|
|
854
952
|
const target = compactToolTarget(presentation.target, workspace);
|
|
855
953
|
const hasDetail = Boolean(entry.arguments || entry.resultText || presentation.preview || presentation.fields.length);
|
|
856
954
|
const category = presentation.category ?? toolCategory(entry);
|
|
857
955
|
const summary = /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
858
956
|
/* @__PURE__ */ jsx3(ToolIcon, { category }),
|
|
859
|
-
/* @__PURE__ */ jsx3("strong", { children:
|
|
957
|
+
/* @__PURE__ */ jsx3("strong", { children: toolAction2(entry, category, presentation) }),
|
|
860
958
|
target ? /* @__PURE__ */ jsx3("code", { class: "scui-tool-target", title: presentation.target, children: target }) : null,
|
|
861
959
|
/* @__PURE__ */ jsx3("span", { class: "scui-spacer" }),
|
|
960
|
+
entry.status === "pending" ? /* @__PURE__ */ jsx3(PendingElapsed, { now: adapter?.now }) : null,
|
|
862
961
|
/* @__PURE__ */ jsx3("span", { class: "scui-tool-status", role: "status", "data-status": entry.status ?? "completed", "aria-label": entry.status ?? "completed", children: entry.status === "pending" ? /* @__PURE__ */ jsx3("i", {}) : entry.status === "error" ? "\xD7" : "\u2713" }),
|
|
863
962
|
hasDetail ? /* @__PURE__ */ jsx3("span", { class: "scui-tool-chevron", "aria-hidden": "true", children: "\u203A" }) : null
|
|
864
963
|
] });
|
|
865
964
|
if (!hasDetail) return /* @__PURE__ */ jsx3("div", { class: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, children: /* @__PURE__ */ jsx3("div", { class: "scui-tool-head", children: summary }) });
|
|
866
|
-
return /* @__PURE__ */ jsxs2("details", { class: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, open:
|
|
965
|
+
return /* @__PURE__ */ jsxs2("details", { class: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, open: expanded, onToggle: (event) => setExpanded(event.currentTarget.open), children: [
|
|
867
966
|
/* @__PURE__ */ jsx3("summary", { class: "scui-tool-head", children: summary }),
|
|
868
967
|
/* @__PURE__ */ jsxs2("div", { class: "scui-tool-detail", children: [
|
|
869
968
|
/* @__PURE__ */ jsx3(ToolMetrics, { presentation }),
|
|
969
|
+
/* @__PURE__ */ jsx3(ToolStack, { tools: presentation.tools ?? [] }),
|
|
870
970
|
/* @__PURE__ */ jsx3(ToolPreview, { presentation, entry }),
|
|
871
971
|
presentation.fields.length ? /* @__PURE__ */ jsx3("dl", { class: "scui-tool-fields", children: presentation.fields.map((field) => /* @__PURE__ */ jsxs2("div", { children: [
|
|
872
972
|
/* @__PURE__ */ jsx3("dt", { children: field.label }),
|
|
873
973
|
/* @__PURE__ */ jsx3("dd", { children: field.value })
|
|
874
974
|
] }, field.label)) }) : null,
|
|
975
|
+
/* @__PURE__ */ jsx3(ToolActions, { presentation, adapter }),
|
|
875
976
|
/* @__PURE__ */ jsx3(TechnicalDetails, { entry })
|
|
876
977
|
] })
|
|
877
978
|
] });
|
|
878
979
|
}
|
|
879
|
-
function ActivityGroup({ entries, state }) {
|
|
880
|
-
if (entries.length === 1) return /* @__PURE__ */ jsx3("section", { class: "scui-activity", "data-single": "true", children: /* @__PURE__ */ jsx3(ToolRow, { entry: entries[0], workspace: state.workspace }) });
|
|
980
|
+
function ActivityGroup({ entries, state, adapter }) {
|
|
981
|
+
if (entries.length === 1) return /* @__PURE__ */ jsx3("section", { class: "scui-activity", "data-single": "true", children: /* @__PURE__ */ jsx3(ToolRow, { entry: entries[0], workspace: state.workspace, adapter }) });
|
|
881
982
|
const active = entries.some((entry) => entry.status === "pending");
|
|
882
983
|
const [open, setOpen] = useState2(active);
|
|
883
984
|
const id = useId();
|
|
@@ -895,7 +996,7 @@ function ActivityGroup({ entries, state }) {
|
|
|
895
996
|
entries.length
|
|
896
997
|
] })
|
|
897
998
|
] }),
|
|
898
|
-
open ? /* @__PURE__ */ jsx3("div", { id, children: entries.map((entry) => /* @__PURE__ */ jsx3(ToolRow, { entry, workspace: state.workspace }, entry.id)) }) : null
|
|
999
|
+
open ? /* @__PURE__ */ jsx3("div", { id, children: entries.map((entry) => /* @__PURE__ */ jsx3(ToolRow, { entry, workspace: state.workspace, adapter }, entry.id)) }) : null
|
|
899
1000
|
] });
|
|
900
1001
|
}
|
|
901
1002
|
function TaskPlan({ plan }) {
|
package/package.json
CHANGED
package/styles.css
CHANGED
|
@@ -137,15 +137,18 @@
|
|
|
137
137
|
.scui-tool { min-width:0 }.scui-tool summary { list-style:none }.scui-tool summary::-webkit-details-marker { display:none }.scui-tool-head { cursor:default }.scui-tool > summary.scui-tool-head { cursor:pointer }.scui-tool-icon { flex:0 0 14px; width:14px; height:14px; color:var(--scui-muted) }.scui-tool-head strong { flex:none; color:var(--scui-fg); font-size:10.5px; font-weight:600; white-space:nowrap }
|
|
138
138
|
.scui-tool-target { min-width:0; overflow:hidden; padding:0; background:transparent; color:var(--scui-muted); font:10px ui-monospace,SFMono-Regular,Menlo,monospace; text-overflow:ellipsis; white-space:nowrap }
|
|
139
139
|
.scui-tool-status { display:grid; flex:0 0 13px; width:13px; height:13px; place-items:center; color:var(--scui-success); font-size:10px }.scui-tool-status[data-status="pending"] { color:var(--scui-accent) }.scui-tool-status[data-status="error"] { color:var(--scui-danger); font-size:13px }.scui-tool-status i { box-sizing:border-box; width:11px; height:11px; border:1.5px solid currentColor; border-right-color:transparent; border-radius:50%; animation:scui-spin .75s linear infinite }
|
|
140
|
+
.scui-tool-elapsed { flex:none; color:var(--scui-muted); font:9px ui-monospace,SFMono-Regular,Menlo,monospace }
|
|
140
141
|
.scui-tool-chevron { flex:none; font-size:15px; line-height:1; transition:transform 120ms }.scui-tool[open] .scui-tool-chevron { transform:rotate(90deg) }
|
|
141
142
|
.scui-tool-detail { display:grid; gap:7px; max-height:240px; margin:2px 0 7px 20px; overflow:auto; border:1px solid var(--scui-border); border-radius:7px; background:var(--scui-bg-raised); font-size:10px }
|
|
142
143
|
.scui-tool-metrics { display:flex; flex-wrap:wrap; gap:4px; padding:7px 7px 0 }.scui-tool-metrics span { padding:2px 5px; border:1px solid var(--scui-border); border-radius:9px; color:var(--scui-muted); font:9px ui-monospace,SFMono-Regular,Menlo,monospace }.scui-tool[data-status="error"] .scui-tool-metrics span { border-color:color-mix(in srgb,var(--scui-danger) 30%,var(--scui-border)) }
|
|
144
|
+
.scui-tool-stack { display:flex; flex-wrap:wrap; gap:4px; padding:7px 8px 0 }.scui-tool-stack span { padding:2px 5px; border-radius:4px; background:var(--scui-fill); color:var(--scui-muted); font:9px ui-monospace,SFMono-Regular,Menlo,monospace }
|
|
143
145
|
.scui-terminal { min-width:0; overflow:hidden; background:color-mix(in srgb,var(--scui-fg) 7%,var(--scui-bg)); color:var(--scui-fg) }.scui-terminal header { display:flex; align-items:center; gap:7px; min-height:29px; padding:0 8px; border-bottom:1px solid var(--scui-border) }.scui-terminal header > span { display:flex; gap:3px }.scui-terminal header i { width:5px; height:5px; border-radius:50%; background:var(--scui-border-strong) }.scui-terminal header code { min-width:0; overflow:hidden; color:var(--scui-muted); font:9.5px ui-monospace,SFMono-Regular,Menlo,monospace; text-overflow:ellipsis; white-space:nowrap }.scui-terminal pre,.scui-tool-output,.scui-agent-preview pre { max-height:150px; margin:0; padding:8px; overflow:auto; overflow-wrap:anywhere; color:var(--scui-fg); font:10px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace; white-space:pre-wrap }.scui-terminal pre[data-error="true"],.scui-tool-output[data-error="true"] { color:var(--scui-danger) }.scui-terminal-wait,.scui-terminal-empty { display:flex; align-items:center; gap:6px; padding:9px; color:var(--scui-muted) }.scui-terminal-wait i { width:5px; height:5px; border-radius:50%; background:var(--scui-accent); animation:scui-breathe 1.2s ease-in-out infinite }
|
|
144
146
|
.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) }
|
|
145
147
|
.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) }
|
|
146
148
|
.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) }
|
|
147
149
|
.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) }
|
|
148
150
|
.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) }
|
|
151
|
+
.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) }
|
|
149
152
|
.scui-tool-technical { margin:0 8px 8px; color:var(--scui-muted) }.scui-tool-technical > summary { cursor:pointer; font-size:9.5px }.scui-tool-technical > div { display:grid; gap:8px; margin-top:5px; padding:7px; border-left:1px solid var(--scui-border) }.scui-tool-technical section,.scui-tool-technical dl,.scui-tool-technical dl > div { display:grid; gap:3px; margin:0 }.scui-tool-technical strong,.scui-tool-technical dt { color:var(--scui-muted); font-weight:600 }.scui-tool-technical dd { min-width:0; margin:0 }.scui-tool-technical pre { max-height:110px; margin:0; overflow:auto; overflow-wrap:anywhere; color:var(--scui-fg); font:9.5px/1.45 ui-monospace,SFMono-Regular,Menlo,monospace; white-space:pre-wrap }.scui-tool-technical pre[data-error="true"] { color:var(--scui-danger) }
|
|
150
153
|
.scui-request { padding:9px; border:1px solid var(--scui-warning); border-radius:9px; background:color-mix(in srgb,var(--scui-warning) 8%,var(--scui-bg)) }.scui-request-actions { display:flex; flex-wrap:wrap; gap:5px }.scui-request-actions button { padding:5px 8px; border:1px solid var(--scui-border-strong); border-radius:6px; background:var(--scui-bg); cursor:pointer }
|
|
151
154
|
.scui-request-done { color:var(--scui-muted); font-size:10.5px }
|