@volter-ai-dev/supercode-ui 0.1.8 → 0.1.9
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.d.ts +1 -0
- package/components.mjs +260 -19
- package/controller.mjs +8 -2
- package/conversation.d.ts +2 -0
- package/conversation.mjs +230 -19
- package/core.d.ts +3 -0
- package/core.mjs +149 -1
- package/embed.mjs +259 -19
- package/index.d.ts +31 -1
- package/messenger.mjs +259 -19
- package/package.json +1 -1
- package/styles.css +9 -1
package/embed.mjs
CHANGED
|
@@ -67,6 +67,11 @@ var MODES = /* @__PURE__ */ new Set(["none", "control", "mirror"]);
|
|
|
67
67
|
var STRATEGIES = /* @__PURE__ */ new Set(["start", "resume", "attach", "branch", "reduce"]);
|
|
68
68
|
var STARTUP = /* @__PURE__ */ new Set(["connecting", "starting", "discovering", "ready"]);
|
|
69
69
|
var FIDELITY = /* @__PURE__ */ new Set(["byte_lossless", "value_lossless", "semantic"]);
|
|
70
|
+
var TOOL_CATEGORIES = /* @__PURE__ */ new Set(["read", "search", "edit", "command", "test", "web", "agent", "plan", "other"]);
|
|
71
|
+
var TOOL_DETAILS = /* @__PURE__ */ new Set(["file", "matches", "diff", "terminal", "web", "agent", "plan", "fields"]);
|
|
72
|
+
var MAX_TOOL_FIELDS = 8;
|
|
73
|
+
var MAX_TOOL_FIELD_CHARS = 800;
|
|
74
|
+
var MAX_TOOL_PREVIEW_CHARS = 4e3;
|
|
70
75
|
function record(value) {
|
|
71
76
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
72
77
|
}
|
|
@@ -79,6 +84,132 @@ function number(value, fallback = 0) {
|
|
|
79
84
|
function nullableNumber(value) {
|
|
80
85
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
81
86
|
}
|
|
87
|
+
function boundedString(value, max) {
|
|
88
|
+
if (typeof value !== "string") return "";
|
|
89
|
+
return value.length <= max ? value : `${value.slice(0, max)}\u2026`;
|
|
90
|
+
}
|
|
91
|
+
function argumentObject(argumentsText) {
|
|
92
|
+
if (!argumentsText) return null;
|
|
93
|
+
try {
|
|
94
|
+
return record(JSON.parse(argumentsText));
|
|
95
|
+
} catch {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function firstString(source, keys) {
|
|
100
|
+
for (const key of keys) {
|
|
101
|
+
if (typeof source?.[key] === "string" && source[key].trim()) return source[key].trim();
|
|
102
|
+
}
|
|
103
|
+
return "";
|
|
104
|
+
}
|
|
105
|
+
function explicitNumber(sources, keys) {
|
|
106
|
+
for (const source of sources) {
|
|
107
|
+
for (const key of keys) {
|
|
108
|
+
const value = source?.[key];
|
|
109
|
+
const parsed = typeof value === "string" && value.trim() !== "" ? Number(value) : value;
|
|
110
|
+
if (typeof parsed === "number" && Number.isFinite(parsed)) return parsed;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
function toolDetail(category) {
|
|
116
|
+
return { read: "file", search: "matches", edit: "diff", command: "terminal", test: "terminal", web: "web", agent: "agent", plan: "plan" }[category] ?? "fields";
|
|
117
|
+
}
|
|
118
|
+
function usefulToolFields(args) {
|
|
119
|
+
if (!args) return [];
|
|
120
|
+
const hidden = /* @__PURE__ */ new Set(["command", "cmd", "file_path", "target_file", "path", "query", "pattern", "url", "patch", "diff", "old_string", "new_string", "content", "prompt", "description", "task", "plan", "todos"]);
|
|
121
|
+
return Object.entries(args).flatMap(([key, value]) => {
|
|
122
|
+
if (hidden.has(key) || value === null || value === void 0) return [];
|
|
123
|
+
const rendered = typeof value === "string" ? value : JSON.stringify(value);
|
|
124
|
+
if (!rendered) return [];
|
|
125
|
+
return [{ label: key.replaceAll(/[_-]+/g, " ").replace(/^./, (letter) => letter.toLocaleUpperCase()), value: boundedString(rendered, MAX_TOOL_FIELD_CHARS) }];
|
|
126
|
+
}).slice(0, MAX_TOOL_FIELDS);
|
|
127
|
+
}
|
|
128
|
+
function planItems(args) {
|
|
129
|
+
const source = Array.isArray(args?.plan) ? args.plan : Array.isArray(args?.todos) ? args.todos : [];
|
|
130
|
+
return source.flatMap((item) => {
|
|
131
|
+
if (typeof item === "string" && item.trim()) return [{ label: boundedString(item.trim(), 300), status: "" }];
|
|
132
|
+
const value = record(item);
|
|
133
|
+
const label = firstString(value, ["step", "title", "content", "text"]);
|
|
134
|
+
if (!label) return [];
|
|
135
|
+
return [{ label: boundedString(label, 300), status: firstString(value, ["status"]) }];
|
|
136
|
+
}).slice(0, 12);
|
|
137
|
+
}
|
|
138
|
+
function editPreview(args, resultText) {
|
|
139
|
+
const direct = firstString(args, ["patch", "diff"]);
|
|
140
|
+
if (direct) return direct;
|
|
141
|
+
const oldText = firstString(args, ["old_string"]);
|
|
142
|
+
const newText = firstString(args, ["new_string"]);
|
|
143
|
+
if (oldText || newText) {
|
|
144
|
+
return [
|
|
145
|
+
...oldText.split("\n").map((line) => `- ${line}`),
|
|
146
|
+
...newText.split("\n").map((line) => `+ ${line}`)
|
|
147
|
+
].join("\n");
|
|
148
|
+
}
|
|
149
|
+
return /^(?:diff --git|@@ |--- |\+\+\+ )/m.test(resultText ?? "") ? resultText : "";
|
|
150
|
+
}
|
|
151
|
+
function createToolPresentation(entry) {
|
|
152
|
+
const args = argumentObject(entry.arguments);
|
|
153
|
+
const category = toolCategory({ label: entry.label, arguments: entry.arguments });
|
|
154
|
+
const command = firstString(args, ["command", "cmd"]);
|
|
155
|
+
const path = firstString(args, ["file_path", "target_file", "path"]);
|
|
156
|
+
const query = firstString(args, ["query", "pattern"]);
|
|
157
|
+
const url = firstString(args, ["url"]);
|
|
158
|
+
const subject = firstString(args, ["description", "task", "prompt"]);
|
|
159
|
+
const target = path || command || query || url || subject || toolTarget(entry.arguments);
|
|
160
|
+
const previewSource = category === "edit" ? editPreview(args, entry.resultText) : entry.resultText ?? "";
|
|
161
|
+
const result = record(entry.resultContent);
|
|
162
|
+
const metadata = record(entry.metadata);
|
|
163
|
+
return {
|
|
164
|
+
category,
|
|
165
|
+
detail: toolDetail(category),
|
|
166
|
+
target: boundedString(target, 300),
|
|
167
|
+
command: boundedString(command, MAX_TOOL_FIELD_CHARS),
|
|
168
|
+
path: boundedString(path, MAX_TOOL_FIELD_CHARS),
|
|
169
|
+
query: boundedString(query, MAX_TOOL_FIELD_CHARS),
|
|
170
|
+
url: boundedString(url, MAX_TOOL_FIELD_CHARS),
|
|
171
|
+
subject: boundedString(subject, MAX_TOOL_FIELD_CHARS),
|
|
172
|
+
preview: boundedString(previewSource, MAX_TOOL_PREVIEW_CHARS),
|
|
173
|
+
fields: usefulToolFields(args),
|
|
174
|
+
items: planItems(args),
|
|
175
|
+
exitCode: explicitNumber([result, metadata], ["exit_code", "exitCode"]),
|
|
176
|
+
durationMs: explicitNumber([result, metadata], ["duration_ms", "durationMs", "elapsed_ms", "elapsedMs"]),
|
|
177
|
+
additions: explicitNumber([result, metadata], ["additions", "lines_added"]),
|
|
178
|
+
deletions: explicitNumber([result, metadata], ["deletions", "lines_removed"]),
|
|
179
|
+
matches: explicitNumber([result, metadata], ["matches", "match_count", "result_count"])
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function readToolPresentation(value, entry) {
|
|
183
|
+
const generated = createToolPresentation(entry);
|
|
184
|
+
const item = record(value);
|
|
185
|
+
if (!item) return generated;
|
|
186
|
+
const fields = Array.isArray(item.fields) ? item.fields.flatMap((raw) => {
|
|
187
|
+
const field = record(raw);
|
|
188
|
+
return field && typeof field.label === "string" && typeof field.value === "string" ? [{ label: boundedString(field.label, 80), value: boundedString(field.value, MAX_TOOL_FIELD_CHARS) }] : [];
|
|
189
|
+
}).slice(0, MAX_TOOL_FIELDS) : generated.fields;
|
|
190
|
+
const items = Array.isArray(item.items) ? item.items.flatMap((raw) => {
|
|
191
|
+
const planItem = record(raw);
|
|
192
|
+
return planItem && typeof planItem.label === "string" ? [{ label: boundedString(planItem.label, 300), status: boundedString(planItem.status, 40) }] : [];
|
|
193
|
+
}).slice(0, 12) : generated.items;
|
|
194
|
+
return {
|
|
195
|
+
category: TOOL_CATEGORIES.has(item.category) ? item.category : generated.category,
|
|
196
|
+
detail: TOOL_DETAILS.has(item.detail) ? item.detail : generated.detail,
|
|
197
|
+
target: boundedString(item.target, 300) || generated.target,
|
|
198
|
+
command: boundedString(item.command, MAX_TOOL_FIELD_CHARS) || generated.command,
|
|
199
|
+
path: boundedString(item.path, MAX_TOOL_FIELD_CHARS) || generated.path,
|
|
200
|
+
query: boundedString(item.query, MAX_TOOL_FIELD_CHARS) || generated.query,
|
|
201
|
+
url: boundedString(item.url, MAX_TOOL_FIELD_CHARS) || generated.url,
|
|
202
|
+
subject: boundedString(item.subject, MAX_TOOL_FIELD_CHARS) || generated.subject,
|
|
203
|
+
preview: boundedString(item.preview, MAX_TOOL_PREVIEW_CHARS) || generated.preview,
|
|
204
|
+
fields,
|
|
205
|
+
items,
|
|
206
|
+
exitCode: nullableNumber(item.exitCode) ?? generated.exitCode,
|
|
207
|
+
durationMs: nullableNumber(item.durationMs) ?? generated.durationMs,
|
|
208
|
+
additions: nullableNumber(item.additions) ?? generated.additions,
|
|
209
|
+
deletions: nullableNumber(item.deletions) ?? generated.deletions,
|
|
210
|
+
matches: nullableNumber(item.matches) ?? generated.matches
|
|
211
|
+
};
|
|
212
|
+
}
|
|
82
213
|
function readTranscript(value) {
|
|
83
214
|
if (!Array.isArray(value)) return [];
|
|
84
215
|
const result = [];
|
|
@@ -96,6 +227,7 @@ function readTranscript(value) {
|
|
|
96
227
|
if (typeof item[key] === "string") entry[key] = item[key];
|
|
97
228
|
}
|
|
98
229
|
if (["pending", "completed", "error"].includes(item.status)) entry.status = item.status;
|
|
230
|
+
if (item.role === "tool") entry.presentation = readToolPresentation(item.presentation, entry);
|
|
99
231
|
if (typeof item.streaming === "boolean") entry.streaming = item.streaming;
|
|
100
232
|
if (Array.isArray(item.context)) {
|
|
101
233
|
entry.context = item.context.flatMap((raw) => {
|
|
@@ -303,6 +435,7 @@ function groupConversation(entries) {
|
|
|
303
435
|
return blocks;
|
|
304
436
|
}
|
|
305
437
|
function toolCategory(entry) {
|
|
438
|
+
if (TOOL_CATEGORIES.has(entry.presentation?.category)) return entry.presentation.category;
|
|
306
439
|
const name = entry.label?.toLocaleLowerCase() ?? "";
|
|
307
440
|
if (/read|view|open_file|list_dir/.test(name)) return "read";
|
|
308
441
|
if (/search|find|grep|glob/.test(name)) return "search";
|
|
@@ -310,7 +443,8 @@ function toolCategory(entry) {
|
|
|
310
443
|
if (/test|typecheck|lint|build/.test(name)) return "test";
|
|
311
444
|
if (/terminal|bash|shell|command|exec/.test(name)) return /\b(test|typecheck|lint|build)\b/i.test(entry.arguments ?? "") ? "test" : "command";
|
|
312
445
|
if (/browser|web|fetch|url/.test(name)) return "web";
|
|
313
|
-
if (/
|
|
446
|
+
if (/update.?plan|todo|checklist/.test(name)) return "plan";
|
|
447
|
+
if (/subagent|spawn.?agent|delegate|^task$/.test(name)) return "agent";
|
|
314
448
|
return "other";
|
|
315
449
|
}
|
|
316
450
|
function toolTarget(argumentsText) {
|
|
@@ -550,6 +684,7 @@ var TOOL_ICONS = {
|
|
|
550
684
|
/* @__PURE__ */ jsx3("circle", { cx: "9", cy: "6", r: "2.5" }),
|
|
551
685
|
/* @__PURE__ */ jsx3("path", { d: "M4 15c.4-3 2-4.5 5-4.5s4.6 1.5 5 4.5" })
|
|
552
686
|
] }),
|
|
687
|
+
plan: () => /* @__PURE__ */ jsx3(Fragment, { children: /* @__PURE__ */ jsx3("path", { d: "m3 5 1 1 2-2M3 9l1 1 2-2M3 13l1 1 2-2M8 5h7M8 9h7M8 13h7" }) }),
|
|
553
688
|
other: () => /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
554
689
|
/* @__PURE__ */ jsx3("path", { d: "M9 2.5v3M9 12.5v3M2.5 9h3M12.5 9h3" }),
|
|
555
690
|
/* @__PURE__ */ jsx3("circle", { cx: "9", cy: "9", r: "3.5" })
|
|
@@ -568,7 +703,8 @@ function toolAction(entry, category) {
|
|
|
568
703
|
command: ["Running command", "Ran command", "Command failed"],
|
|
569
704
|
test: ["Running tests", "Ran tests", "Tests failed"],
|
|
570
705
|
web: ["Browsing", "Browsed", "Browser action failed"],
|
|
571
|
-
agent: ["Starting agent", "Started agent", "Agent failed"]
|
|
706
|
+
agent: ["Starting agent", "Started agent", "Agent failed"],
|
|
707
|
+
plan: ["Updating plan", "Updated plan", "Plan update failed"]
|
|
572
708
|
};
|
|
573
709
|
const position = status === "pending" ? 0 : status === "error" ? 2 : 1;
|
|
574
710
|
if (actions[category]) return actions[category][position];
|
|
@@ -594,6 +730,113 @@ function argumentRows(argumentsText) {
|
|
|
594
730
|
}
|
|
595
731
|
return [{ key: "arguments", label: "Details", value: argumentsText }];
|
|
596
732
|
}
|
|
733
|
+
function stripAnsi(value) {
|
|
734
|
+
return value?.replaceAll(/[\u001B\u009B][[\]()#;?]*(?:(?:(?:[a-zA-Z\d]*(?:;[-a-zA-Z\d\/#&.:=?%@~_]+)*)?\u0007)|(?:(?:\d{1,4}(?:[;:]\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))/g, "") ?? "";
|
|
735
|
+
}
|
|
736
|
+
function formatDuration(value) {
|
|
737
|
+
if (value === null) return "";
|
|
738
|
+
if (value < 1e3) return `${Math.round(value)}ms`;
|
|
739
|
+
return `${(value / 1e3).toFixed(value < 1e4 ? 1 : 0)}s`;
|
|
740
|
+
}
|
|
741
|
+
function ToolMetrics({ presentation }) {
|
|
742
|
+
const metrics = [
|
|
743
|
+
presentation.matches === null ? "" : `${presentation.matches} ${presentation.matches === 1 ? "match" : "matches"}`,
|
|
744
|
+
presentation.additions === null ? "" : `+${presentation.additions}`,
|
|
745
|
+
presentation.deletions === null ? "" : `\u2212${presentation.deletions}`,
|
|
746
|
+
presentation.exitCode === null ? "" : `exit ${presentation.exitCode}`,
|
|
747
|
+
formatDuration(presentation.durationMs)
|
|
748
|
+
].filter(Boolean);
|
|
749
|
+
return metrics.length ? /* @__PURE__ */ jsx3("div", { class: "scui-tool-metrics", children: metrics.map((metric) => /* @__PURE__ */ jsx3("span", { children: metric }, metric)) }) : null;
|
|
750
|
+
}
|
|
751
|
+
function LinePreview({ value, kind }) {
|
|
752
|
+
if (!value) return null;
|
|
753
|
+
return /* @__PURE__ */ jsx3("ol", { class: "scui-code-preview", "data-kind": kind, children: stripAnsi(value).split("\n").map((line, index) => {
|
|
754
|
+
const tone = kind === "diff" ? line.startsWith("+") && !line.startsWith("+++") ? "add" : line.startsWith("-") && !line.startsWith("---") ? "remove" : line.startsWith("@@") ? "hunk" : "plain" : "plain";
|
|
755
|
+
return /* @__PURE__ */ jsxs2("li", { "data-tone": tone, children: [
|
|
756
|
+
/* @__PURE__ */ jsx3("span", { children: index + 1 }),
|
|
757
|
+
/* @__PURE__ */ jsx3("code", { children: line || " " })
|
|
758
|
+
] }, index);
|
|
759
|
+
}) });
|
|
760
|
+
}
|
|
761
|
+
function TerminalPreview({ presentation, pending, failed }) {
|
|
762
|
+
return /* @__PURE__ */ jsxs2("section", { class: "scui-terminal", children: [
|
|
763
|
+
/* @__PURE__ */ jsxs2("header", { children: [
|
|
764
|
+
/* @__PURE__ */ jsxs2("span", { "aria-hidden": "true", children: [
|
|
765
|
+
/* @__PURE__ */ jsx3("i", {}),
|
|
766
|
+
/* @__PURE__ */ jsx3("i", {}),
|
|
767
|
+
/* @__PURE__ */ jsx3("i", {})
|
|
768
|
+
] }),
|
|
769
|
+
/* @__PURE__ */ jsx3("code", { children: presentation.command ? `$ ${presentation.command}` : "Terminal" })
|
|
770
|
+
] }),
|
|
771
|
+
presentation.preview ? /* @__PURE__ */ jsx3("pre", { "data-error": failed, children: stripAnsi(presentation.preview) }) : pending ? /* @__PURE__ */ jsxs2("div", { class: "scui-terminal-wait", children: [
|
|
772
|
+
/* @__PURE__ */ jsx3("i", {}),
|
|
773
|
+
" Waiting for output"
|
|
774
|
+
] }) : /* @__PURE__ */ jsx3("div", { class: "scui-terminal-empty", children: "No output" })
|
|
775
|
+
] });
|
|
776
|
+
}
|
|
777
|
+
function SearchPreview({ presentation }) {
|
|
778
|
+
const lines = stripAnsi(presentation.preview).split("\n").filter(Boolean);
|
|
779
|
+
return /* @__PURE__ */ jsxs2("section", { class: "scui-search-preview", children: [
|
|
780
|
+
presentation.query ? /* @__PURE__ */ jsxs2("header", { children: [
|
|
781
|
+
/* @__PURE__ */ jsx3("span", { children: "Search" }),
|
|
782
|
+
/* @__PURE__ */ jsx3("code", { children: presentation.query })
|
|
783
|
+
] }) : null,
|
|
784
|
+
lines.length ? /* @__PURE__ */ jsx3("ol", { children: lines.map((line, index) => {
|
|
785
|
+
const match = /^(.*?):(\d+)(?::(\d+))?:(.*)$/.exec(line);
|
|
786
|
+
return /* @__PURE__ */ jsx3("li", { children: match ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
787
|
+
/* @__PURE__ */ jsx3("code", { children: match[1] }),
|
|
788
|
+
/* @__PURE__ */ jsxs2("small", { children: [
|
|
789
|
+
match[2],
|
|
790
|
+
match[3] ? `:${match[3]}` : ""
|
|
791
|
+
] }),
|
|
792
|
+
/* @__PURE__ */ jsx3("span", { children: match[4] })
|
|
793
|
+
] }) : /* @__PURE__ */ jsx3("span", { children: line }) }, index);
|
|
794
|
+
}) }) : /* @__PURE__ */ jsx3("p", { children: "No textual results" })
|
|
795
|
+
] });
|
|
796
|
+
}
|
|
797
|
+
function ToolPreview({ presentation, entry }) {
|
|
798
|
+
const pending = entry.status === "pending";
|
|
799
|
+
const failed = entry.status === "error";
|
|
800
|
+
if (presentation.detail === "terminal") return /* @__PURE__ */ jsx3(TerminalPreview, { presentation, pending, failed });
|
|
801
|
+
if (presentation.detail === "diff") return presentation.preview ? /* @__PURE__ */ jsx3(LinePreview, { value: presentation.preview, kind: "diff" }) : /* @__PURE__ */ jsx3("div", { class: "scui-tool-empty", children: "Edit completed without a textual diff" });
|
|
802
|
+
if (presentation.detail === "file") return presentation.preview ? /* @__PURE__ */ jsx3(LinePreview, { value: presentation.preview, kind: "file" }) : /* @__PURE__ */ jsx3("div", { class: "scui-tool-empty", children: "File contents were not included in this event" });
|
|
803
|
+
if (presentation.detail === "matches") return /* @__PURE__ */ jsx3(SearchPreview, { presentation });
|
|
804
|
+
if (presentation.detail === "web") return /* @__PURE__ */ jsxs2("section", { class: "scui-web-preview", children: [
|
|
805
|
+
presentation.url ? /* @__PURE__ */ jsx3("code", { children: presentation.url }) : null,
|
|
806
|
+
presentation.preview ? /* @__PURE__ */ jsx3("p", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx3("small", { children: pending ? "Waiting for the page" : "No page summary returned" })
|
|
807
|
+
] });
|
|
808
|
+
if (presentation.detail === "agent") return /* @__PURE__ */ jsxs2("section", { class: "scui-agent-preview", children: [
|
|
809
|
+
presentation.subject ? /* @__PURE__ */ jsx3("p", { children: presentation.subject }) : null,
|
|
810
|
+
presentation.preview ? /* @__PURE__ */ jsx3("pre", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx3("small", { children: pending ? "Agent is working" : "No textual handoff returned" })
|
|
811
|
+
] });
|
|
812
|
+
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: [
|
|
813
|
+
/* @__PURE__ */ jsx3("i", { "aria-hidden": "true" }),
|
|
814
|
+
/* @__PURE__ */ jsx3("span", { children: item.label })
|
|
815
|
+
] }, `${item.label}:${index}`)) });
|
|
816
|
+
return presentation.preview ? /* @__PURE__ */ jsx3("pre", { class: "scui-tool-output", "data-error": failed, children: stripAnsi(presentation.preview) }) : null;
|
|
817
|
+
}
|
|
818
|
+
function TechnicalDetails({ entry }) {
|
|
819
|
+
if (!entry.arguments && !entry.resultText) return null;
|
|
820
|
+
return /* @__PURE__ */ jsxs2("details", { class: "scui-tool-technical", children: [
|
|
821
|
+
/* @__PURE__ */ jsx3("summary", { children: "Technical details" }),
|
|
822
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
823
|
+
entry.arguments ? /* @__PURE__ */ jsxs2("section", { children: [
|
|
824
|
+
/* @__PURE__ */ jsx3("strong", { children: "Native arguments" }),
|
|
825
|
+
/* @__PURE__ */ jsx3("dl", { children: argumentRows(entry.arguments).map((row) => /* @__PURE__ */ jsxs2("div", { children: [
|
|
826
|
+
/* @__PURE__ */ jsx3("dt", { children: row.label }),
|
|
827
|
+
/* @__PURE__ */ jsx3("dd", { children: /* @__PURE__ */ jsx3("pre", { children: row.value }) })
|
|
828
|
+
] }, row.key)) })
|
|
829
|
+
] }) : null,
|
|
830
|
+
entry.resultText ? /* @__PURE__ */ jsxs2("section", { children: [
|
|
831
|
+
/* @__PURE__ */ jsx3("strong", { children: "Native result" }),
|
|
832
|
+
/* @__PURE__ */ jsxs2("pre", { "data-error": entry.status === "error", children: [
|
|
833
|
+
entry.resultText,
|
|
834
|
+
entry.truncated ? "\n[truncated]" : ""
|
|
835
|
+
] })
|
|
836
|
+
] }) : null
|
|
837
|
+
] })
|
|
838
|
+
] });
|
|
839
|
+
}
|
|
597
840
|
function TranscriptEntry({ entry, state, adapter }) {
|
|
598
841
|
if (entry.role === "request") return /* @__PURE__ */ jsx3(RequestCard, { entry, adapter, canRespond: state.canRespond });
|
|
599
842
|
if (entry.role === "reasoning") {
|
|
@@ -609,33 +852,30 @@ function TranscriptEntry({ entry, state, adapter }) {
|
|
|
609
852
|
entry.truncated ? /* @__PURE__ */ jsx3("small", { class: "scui-truncated", children: "Entry truncated by host \xB7 load native session for the complete value" }) : null
|
|
610
853
|
] });
|
|
611
854
|
}
|
|
612
|
-
function ToolRow({ entry, workspace }) {
|
|
613
|
-
const
|
|
614
|
-
const
|
|
615
|
-
const
|
|
855
|
+
function ToolRow({ entry, workspace, open = false }) {
|
|
856
|
+
const presentation = entry.presentation ?? createToolPresentation(entry);
|
|
857
|
+
const target = compactToolTarget(presentation.target, workspace);
|
|
858
|
+
const hasDetail = Boolean(entry.arguments || entry.resultText || presentation.preview || presentation.fields.length);
|
|
859
|
+
const category = presentation.category ?? toolCategory(entry);
|
|
616
860
|
const summary = /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
617
861
|
/* @__PURE__ */ jsx3(ToolIcon, { category }),
|
|
618
862
|
/* @__PURE__ */ jsx3("strong", { children: toolAction(entry, category) }),
|
|
619
|
-
target ? /* @__PURE__ */ jsx3("code", { class: "scui-tool-target", title:
|
|
863
|
+
target ? /* @__PURE__ */ jsx3("code", { class: "scui-tool-target", title: presentation.target, children: target }) : null,
|
|
620
864
|
/* @__PURE__ */ jsx3("span", { class: "scui-spacer" }),
|
|
621
865
|
/* @__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" }),
|
|
622
866
|
hasDetail ? /* @__PURE__ */ jsx3("span", { class: "scui-tool-chevron", "aria-hidden": "true", children: "\u203A" }) : null
|
|
623
867
|
] });
|
|
624
868
|
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 }) });
|
|
625
|
-
return /* @__PURE__ */ jsxs2("details", { class: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, children: [
|
|
869
|
+
return /* @__PURE__ */ jsxs2("details", { class: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, open: open || entry.status === "pending", children: [
|
|
626
870
|
/* @__PURE__ */ jsx3("summary", { class: "scui-tool-head", children: summary }),
|
|
627
871
|
/* @__PURE__ */ jsxs2("div", { class: "scui-tool-detail", children: [
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
entry.resultText,
|
|
636
|
-
entry.truncated ? "\n[truncated]" : ""
|
|
637
|
-
] })
|
|
638
|
-
] }) : null
|
|
872
|
+
/* @__PURE__ */ jsx3(ToolMetrics, { presentation }),
|
|
873
|
+
/* @__PURE__ */ jsx3(ToolPreview, { presentation, entry }),
|
|
874
|
+
presentation.fields.length ? /* @__PURE__ */ jsx3("dl", { class: "scui-tool-fields", children: presentation.fields.map((field) => /* @__PURE__ */ jsxs2("div", { children: [
|
|
875
|
+
/* @__PURE__ */ jsx3("dt", { children: field.label }),
|
|
876
|
+
/* @__PURE__ */ jsx3("dd", { children: field.value })
|
|
877
|
+
] }, field.label)) }) : null,
|
|
878
|
+
/* @__PURE__ */ jsx3(TechnicalDetails, { entry })
|
|
639
879
|
] })
|
|
640
880
|
] });
|
|
641
881
|
}
|
package/index.d.ts
CHANGED
|
@@ -74,6 +74,28 @@ export interface TranscriptEntryModel {
|
|
|
74
74
|
request?: TranscriptRequest;
|
|
75
75
|
code?: string;
|
|
76
76
|
context?: TranscriptContext[];
|
|
77
|
+
presentation?: ToolPresentationModel;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export type ToolCategory = 'read' | 'search' | 'edit' | 'command' | 'test' | 'web' | 'agent' | 'plan' | 'other';
|
|
81
|
+
|
|
82
|
+
export interface ToolPresentationModel {
|
|
83
|
+
category: ToolCategory;
|
|
84
|
+
detail: 'file' | 'matches' | 'diff' | 'terminal' | 'web' | 'agent' | 'plan' | 'fields';
|
|
85
|
+
target: string;
|
|
86
|
+
command: string;
|
|
87
|
+
path: string;
|
|
88
|
+
query: string;
|
|
89
|
+
url: string;
|
|
90
|
+
subject: string;
|
|
91
|
+
preview: string;
|
|
92
|
+
fields: Array<{ label: string; value: string }>;
|
|
93
|
+
items: Array<{ label: string; status: string }>;
|
|
94
|
+
exitCode: number | null;
|
|
95
|
+
durationMs: number | null;
|
|
96
|
+
additions: number | null;
|
|
97
|
+
deletions: number | null;
|
|
98
|
+
matches: number | null;
|
|
77
99
|
}
|
|
78
100
|
|
|
79
101
|
export interface TaskPlanItem {
|
|
@@ -240,6 +262,12 @@ export interface ActivityGroupProps {
|
|
|
240
262
|
adapter: UiAdapter;
|
|
241
263
|
}
|
|
242
264
|
|
|
265
|
+
export interface ToolRowProps {
|
|
266
|
+
entry: TranscriptEntryModel;
|
|
267
|
+
workspace?: string;
|
|
268
|
+
open?: boolean;
|
|
269
|
+
}
|
|
270
|
+
|
|
243
271
|
export interface TaskPlanProps {
|
|
244
272
|
plan: TaskPlanModel;
|
|
245
273
|
value?: TaskPlanModel;
|
|
@@ -285,7 +313,8 @@ export function groupConversation(entries: readonly TranscriptEntryModel[]): Arr
|
|
|
285
313
|
| { kind: 'entry'; id: string; entry: TranscriptEntryModel }
|
|
286
314
|
| { kind: 'activity'; id: string; entries: TranscriptEntryModel[] }
|
|
287
315
|
>;
|
|
288
|
-
export function toolCategory(entry: Pick<TranscriptEntryModel, 'label' | 'arguments'
|
|
316
|
+
export function toolCategory(entry: Pick<TranscriptEntryModel, 'label' | 'arguments' | 'presentation'>): ToolCategory;
|
|
317
|
+
export function createToolPresentation(entry: Pick<TranscriptEntryModel, 'label' | 'arguments' | 'resultText'> & { resultContent?: unknown; metadata?: Record<string, string> }): ToolPresentationModel;
|
|
289
318
|
export function toolTarget(argumentsText?: string): string;
|
|
290
319
|
export function compactToolTarget(target: string, workspace: string): string;
|
|
291
320
|
export function activitySummary(entries: readonly TranscriptEntryModel[]): string;
|
|
@@ -300,6 +329,7 @@ export function LoadingStatus(props: { state: SupercodeUiState; compact?: boolea
|
|
|
300
329
|
export function RequestCard(props: { entry: TranscriptEntryModel; adapter: UiAdapter; canRespond: boolean }): VNode | null;
|
|
301
330
|
export function TranscriptEntry(props: { entry: TranscriptEntryModel; state: SupercodeUiState; adapter: UiAdapter }): VNode;
|
|
302
331
|
export function ActivityGroup(props: { entries: TranscriptEntryModel[]; state: SupercodeUiState; adapter: UiAdapter }): VNode;
|
|
332
|
+
export function ToolRow(props: ToolRowProps): VNode;
|
|
303
333
|
export function TaskPlan(props: { plan: TaskPlanModel }): VNode | null;
|
|
304
334
|
export function SessionDetails(props: { semantics: SessionSemanticsModel }): VNode | null;
|
|
305
335
|
export function Conversation(props: { state: SupercodeUiState; adapter: UiAdapter; components?: MessengerComponents; slots?: MessengerSlots; memoryKey?: string; pending?: string | null }): VNode;
|