@lazyingart/agintiflow 0.20.173 → 0.20.174
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/package.json +1 -1
- package/public/app.js +115 -5
- package/public/styles.css +34 -0
- package/scripts/smoke-cli-chat.js +3 -0
- package/scripts/smoke-web-ui.js +16 -0
- package/src/interactive-cli.js +101 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.174",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AgInTiFlow is a project-aware agent workspace for hybrid wet-dry R&D, hardware-aware intelligence, software automation, and industrial workflows.",
|
|
6
6
|
"license": "Apache-2.0",
|
package/public/app.js
CHANGED
|
@@ -1796,6 +1796,83 @@ function renderPlanEvent(entry) {
|
|
|
1796
1796
|
`;
|
|
1797
1797
|
}
|
|
1798
1798
|
|
|
1799
|
+
function embeddedWorkspaceChangesFromText(value = "") {
|
|
1800
|
+
const lines = String(value || "").split(/\r?\n/);
|
|
1801
|
+
const changes = [];
|
|
1802
|
+
let currentTool = "";
|
|
1803
|
+
|
|
1804
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
1805
|
+
const toolMatch = lines[index].match(/^\s*Tool:\s*(.+?)\s*$/i);
|
|
1806
|
+
if (toolMatch) {
|
|
1807
|
+
currentTool = toolMatch[1].trim();
|
|
1808
|
+
continue;
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
const pathMatch = lines[index].match(/^\s*Path:\s*(.+?)\s*$/i);
|
|
1812
|
+
if (!pathMatch) continue;
|
|
1813
|
+
|
|
1814
|
+
let cursor = index + 1;
|
|
1815
|
+
while (cursor < lines.length && !/^\s*Diff:\s*$/i.test(lines[cursor]) && !/^\s*(?:Tool|Path):\s*/i.test(lines[cursor])) {
|
|
1816
|
+
cursor += 1;
|
|
1817
|
+
}
|
|
1818
|
+
if (!/^\s*Diff:\s*$/i.test(lines[cursor] || "")) continue;
|
|
1819
|
+
|
|
1820
|
+
const diffLines = [];
|
|
1821
|
+
cursor += 1;
|
|
1822
|
+
while (cursor < lines.length) {
|
|
1823
|
+
if (diffLines.length && /^\s*(?:Tool|Path):\s*/i.test(lines[cursor])) break;
|
|
1824
|
+
if (
|
|
1825
|
+
diffLines.length &&
|
|
1826
|
+
/^\s*(?:Output:|No command output|Blocked by guardrail\.|Mock run complete\.)/i.test(lines[cursor]) &&
|
|
1827
|
+
!/^[-+@ ]/.test(lines[cursor])
|
|
1828
|
+
) {
|
|
1829
|
+
break;
|
|
1830
|
+
}
|
|
1831
|
+
diffLines.push(lines[cursor]);
|
|
1832
|
+
cursor += 1;
|
|
1833
|
+
}
|
|
1834
|
+
while (diffLines.length && !diffLines[diffLines.length - 1].trim()) diffLines.pop();
|
|
1835
|
+
if (diffLines.length) {
|
|
1836
|
+
changes.push({
|
|
1837
|
+
toolName: currentTool || "write_file",
|
|
1838
|
+
path: pathMatch[1].trim(),
|
|
1839
|
+
diff: diffLines.join("\n"),
|
|
1840
|
+
});
|
|
1841
|
+
index = Math.max(index, cursor - 1);
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
return changes;
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
function embeddedWorkspaceSummary(value = "") {
|
|
1849
|
+
const summary = [];
|
|
1850
|
+
let skippingDiff = false;
|
|
1851
|
+
for (const line of String(value || "").split(/\r?\n/)) {
|
|
1852
|
+
if (/^\s*Diff:\s*$/i.test(line)) {
|
|
1853
|
+
skippingDiff = true;
|
|
1854
|
+
continue;
|
|
1855
|
+
}
|
|
1856
|
+
if (skippingDiff && /^\s*(?:Tool|Path):\s*/i.test(line)) skippingDiff = false;
|
|
1857
|
+
if (skippingDiff) continue;
|
|
1858
|
+
if (/^\s*Path:\s*/i.test(line)) continue;
|
|
1859
|
+
summary.push(line);
|
|
1860
|
+
}
|
|
1861
|
+
return summary.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
function renderEmbeddedWorkspaceResult(value = "", entry = {}) {
|
|
1865
|
+
const changes = embeddedWorkspaceChangesFromText(value);
|
|
1866
|
+
if (changes.length === 0) return "";
|
|
1867
|
+
const summary = embeddedWorkspaceSummary(value);
|
|
1868
|
+
return `
|
|
1869
|
+
${summary ? `<div class="event-result-summary markdown-body">${renderMarkdown(summary)}</div>` : ""}
|
|
1870
|
+
<div class="embedded-change-list">
|
|
1871
|
+
${changes.map((change) => renderWorkspaceChangeEvent({ data: change, at: entry.at, content: change.path })).join("")}
|
|
1872
|
+
</div>
|
|
1873
|
+
`;
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1799
1876
|
function renderWorkspaceChangeEvent(entry) {
|
|
1800
1877
|
const data = entry.data || {};
|
|
1801
1878
|
const toolName = data.toolName || data.action || "file.changed";
|
|
@@ -1833,14 +1910,18 @@ function renderToolEvent(entry) {
|
|
|
1833
1910
|
const skipped = message === "tool.skipped";
|
|
1834
1911
|
const toolName = data.toolName || "tool";
|
|
1835
1912
|
const args = data.args || {};
|
|
1913
|
+
const resultText = String(data.result || args.result || "");
|
|
1914
|
+
const embeddedResult = resultText ? renderEmbeddedWorkspaceResult(resultText, entry) : "";
|
|
1836
1915
|
const argPreview =
|
|
1837
|
-
toolName === "
|
|
1916
|
+
toolName === "finish"
|
|
1917
|
+
? ""
|
|
1918
|
+
: toolName === "run_command" && args.command
|
|
1838
1919
|
? args.command
|
|
1839
1920
|
: args.path || args.url || args.query || args.q || (Object.keys(args).length ? JSON.stringify(args) : "");
|
|
1840
1921
|
const stdout = data.stdout ? outputPreviewText(data.stdout) : null;
|
|
1841
1922
|
const stderr = data.stderr ? outputPreviewText(data.stderr) : null;
|
|
1842
1923
|
return `
|
|
1843
|
-
<article class="event-card ${failed ? "event-failed" : skipped ? "event-muted" : "event-tool"}">
|
|
1924
|
+
<article class="event-card ${failed ? "event-failed" : skipped ? "event-muted" : toolName === "finish" ? "event-finish" : "event-tool"}">
|
|
1844
1925
|
<div class="event-card-meta">
|
|
1845
1926
|
<span>${escapeHtml(failed ? "tool failed" : skipped ? "tool skipped" : message === "tool.started" ? "tool" : "tool done")}</span>
|
|
1846
1927
|
<span>${entry.at ? escapeHtml(new Date(entry.at).toLocaleString()) : ""}</span>
|
|
@@ -1848,6 +1929,7 @@ function renderToolEvent(entry) {
|
|
|
1848
1929
|
<strong class="event-path">${escapeHtml(toolName)}</strong>
|
|
1849
1930
|
${argPreview ? `<code class="event-inline-code">${escapeHtml(argPreview)}</code>` : ""}
|
|
1850
1931
|
${data.error || data.reason ? `<div class="event-fold-note">${escapeHtml(data.error || data.reason)}</div>` : ""}
|
|
1932
|
+
${embeddedResult || (toolName === "finish" && resultText ? `<div class="markdown-body">${renderMarkdown(resultText)}</div>` : "")}
|
|
1851
1933
|
${stdout ? `<div class="log-stream-title">stdout</div><pre class="event-output">${escapeHtml(stdout.text)}</pre>` : ""}
|
|
1852
1934
|
${stdout?.hidden > 0 ? `<div class="event-fold-note">... ${stdout.hidden} more stdout line(s) folded</div>` : ""}
|
|
1853
1935
|
${stderr ? `<div class="log-stream-title">stderr</div><pre class="event-output">${escapeHtml(stderr.text)}</pre>` : ""}
|
|
@@ -1862,13 +1944,14 @@ function renderStatusEvent(entry) {
|
|
|
1862
1944
|
const label = entry.eventLabel || message.replace(/^[^.]+\./, "");
|
|
1863
1945
|
const content = data.result || data.error || data.reason || entry.content || "";
|
|
1864
1946
|
const failed = message === "session.failed";
|
|
1947
|
+
const embeddedResult = content ? renderEmbeddedWorkspaceResult(content, entry) : "";
|
|
1865
1948
|
return `
|
|
1866
|
-
<article class="event-card ${failed ? "event-failed" : "event-muted"}">
|
|
1949
|
+
<article class="event-card ${failed ? "event-failed" : message === "session.finished" && embeddedResult ? "event-finish" : "event-muted"}">
|
|
1867
1950
|
<div class="event-card-meta">
|
|
1868
1951
|
<span>${escapeHtml(label)}</span>
|
|
1869
1952
|
<span>${entry.at ? escapeHtml(new Date(entry.at).toLocaleString()) : ""}</span>
|
|
1870
1953
|
</div>
|
|
1871
|
-
${content ? `<div class="chat-content">${escapeHtml(content)}</div>` : ""}
|
|
1954
|
+
${embeddedResult || (content ? `<div class="chat-content">${escapeHtml(content)}</div>` : "")}
|
|
1872
1955
|
</article>
|
|
1873
1956
|
`;
|
|
1874
1957
|
}
|
|
@@ -1909,9 +1992,14 @@ function renderStructuredEvent(entry) {
|
|
|
1909
1992
|
|
|
1910
1993
|
function renderLogs(run) {
|
|
1911
1994
|
logsEl.dataset.mode = "active";
|
|
1995
|
+
const structuredRunResult = run.result ? renderEmbeddedWorkspaceResult(run.result, { at: run.endedAt || run.updatedAt || "" }) : "";
|
|
1912
1996
|
const parts = [
|
|
1913
1997
|
`<div class="log-line">${escapeHtml(`status=${run.status} session=${run.sessionId} provider=${run.provider} model=${run.model}`)}</div>`,
|
|
1914
|
-
|
|
1998
|
+
structuredRunResult
|
|
1999
|
+
? `<article class="event-card event-finish"><div class="event-card-meta"><span>result</span></div>${structuredRunResult}</article>`
|
|
2000
|
+
: run.result
|
|
2001
|
+
? `<div class="log-line">${escapeHtml(`result=${run.result}`)}</div>`
|
|
2002
|
+
: "",
|
|
1915
2003
|
run.error ? `<div class="log-line error">${escapeHtml(`error=${run.error}`)}</div>` : "",
|
|
1916
2004
|
];
|
|
1917
2005
|
|
|
@@ -2174,6 +2262,28 @@ function renderChat(chatEntries) {
|
|
|
2174
2262
|
</article>
|
|
2175
2263
|
`;
|
|
2176
2264
|
}
|
|
2265
|
+
if (entry.role === "tool") {
|
|
2266
|
+
try {
|
|
2267
|
+
const parsed = JSON.parse(entry.content || "{}");
|
|
2268
|
+
const toolName = parsed.toolName || "tool";
|
|
2269
|
+
return renderToolEvent({
|
|
2270
|
+
role: "event",
|
|
2271
|
+
eventType: parsed.ok === false ? "tool.failed" : "tool.completed",
|
|
2272
|
+
message: parsed.ok === false ? "tool.failed" : "tool.completed",
|
|
2273
|
+
eventLabel: parsed.ok === false ? "tool failed" : "tool done",
|
|
2274
|
+
data: parsed,
|
|
2275
|
+
content: parsed.result || toolName,
|
|
2276
|
+
at: entry.at,
|
|
2277
|
+
});
|
|
2278
|
+
} catch {
|
|
2279
|
+
return `
|
|
2280
|
+
<article class="event-card event-tool">
|
|
2281
|
+
<div class="event-card-meta">tool${entry.at ? ` · ${new Date(entry.at).toLocaleString()}` : ""}</div>
|
|
2282
|
+
<pre class="event-output">${escapeHtml(entry.content || "")}</pre>
|
|
2283
|
+
</article>
|
|
2284
|
+
`;
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2177
2287
|
const role = entry.role === "assistant" ? "assistant" : "user";
|
|
2178
2288
|
const label = role === "assistant" ? t("assistantLabel") : t("youLabel");
|
|
2179
2289
|
const content =
|
package/public/styles.css
CHANGED
|
@@ -1264,6 +1264,19 @@ button.danger {
|
|
|
1264
1264
|
border-color: rgba(59, 130, 246, 0.28);
|
|
1265
1265
|
}
|
|
1266
1266
|
|
|
1267
|
+
.event-finish {
|
|
1268
|
+
border-color: rgba(16, 185, 129, 0.36);
|
|
1269
|
+
background:
|
|
1270
|
+
radial-gradient(circle at 0% 0%, rgba(16, 185, 129, 0.14), transparent 30%),
|
|
1271
|
+
rgba(236, 253, 245, 0.46);
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
#logs .event-finish {
|
|
1275
|
+
background:
|
|
1276
|
+
radial-gradient(circle at 0% 0%, rgba(16, 185, 129, 0.16), transparent 30%),
|
|
1277
|
+
rgba(6, 78, 59, 0.28);
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1267
1280
|
.event-failed {
|
|
1268
1281
|
border-color: rgba(248, 113, 113, 0.45);
|
|
1269
1282
|
background: rgba(127, 29, 29, 0.12);
|
|
@@ -1337,6 +1350,27 @@ button.danger {
|
|
|
1337
1350
|
font-size: 0.8rem;
|
|
1338
1351
|
}
|
|
1339
1352
|
|
|
1353
|
+
.event-result-summary {
|
|
1354
|
+
margin: 4px 0 12px;
|
|
1355
|
+
padding: 10px 12px;
|
|
1356
|
+
border-radius: 12px;
|
|
1357
|
+
background: rgba(15, 118, 110, 0.08);
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
#logs .event-result-summary {
|
|
1361
|
+
background: rgba(255, 255, 255, 0.08);
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
.embedded-change-list {
|
|
1365
|
+
display: grid;
|
|
1366
|
+
gap: 8px;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
.embedded-change-list > .event-card {
|
|
1370
|
+
margin: 0;
|
|
1371
|
+
box-shadow: none;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1340
1374
|
#logs .event-fold-note {
|
|
1341
1375
|
color: #94a3b8;
|
|
1342
1376
|
}
|
|
@@ -896,6 +896,9 @@ try {
|
|
|
896
896
|
if (!latest.stdout.includes(" write ") || !latest.stdout.includes("+Created by AgInTiFlow mock mode.")) {
|
|
897
897
|
throw new Error("bare aginti resume did not replay formatted file-change diff context");
|
|
898
898
|
}
|
|
899
|
+
if (!/\bfinish\b/.test(latest.stdout) || latest.stdout.includes('{"result":"Mock run complete')) {
|
|
900
|
+
throw new Error("bare aginti resume did not render finish-result diffs in formatted mode");
|
|
901
|
+
}
|
|
899
902
|
if (latest.stdout.includes("resume note=showing chat transcript only")) {
|
|
900
903
|
throw new Error("bare aginti resume regressed to chat-only history");
|
|
901
904
|
}
|
package/scripts/smoke-web-ui.js
CHANGED
|
@@ -209,6 +209,21 @@ try {
|
|
|
209
209
|
const chatTail = (await page.locator("#chat-thread").innerText().catch(() => "")).slice(-1200);
|
|
210
210
|
throw new Error(`web UI did not render formatted file-change diff event; state=${state}\nlogs tail:\n${logsTail}\nchat tail:\n${chatTail}`);
|
|
211
211
|
}
|
|
212
|
+
try {
|
|
213
|
+
await page.waitForFunction(
|
|
214
|
+
() =>
|
|
215
|
+
[...document.querySelectorAll(".event-finish .change-diff")].some((node) =>
|
|
216
|
+
(node.textContent || "").includes("+Created by AgInTiFlow mock mode.")
|
|
217
|
+
),
|
|
218
|
+
null,
|
|
219
|
+
{ timeout: 30000 }
|
|
220
|
+
);
|
|
221
|
+
} catch (error) {
|
|
222
|
+
const state = await page.locator("#run-state").evaluate((node) => node.dataset.status || "").catch(() => "unknown");
|
|
223
|
+
const logsTail = (await page.locator("#logs").innerText().catch(() => "")).slice(-1200);
|
|
224
|
+
const chatTail = (await page.locator("#chat-thread").innerText().catch(() => "")).slice(-1200);
|
|
225
|
+
throw new Error(`web UI did not render formatted finish-result diff event; state=${state}\nlogs tail:\n${logsTail}\nchat tail:\n${chatTail}`);
|
|
226
|
+
}
|
|
212
227
|
|
|
213
228
|
await page.click("#open-settings");
|
|
214
229
|
await page.waitForSelector("#settings-modal[open]");
|
|
@@ -246,6 +261,7 @@ try {
|
|
|
246
261
|
"new-session-resets-scope",
|
|
247
262
|
"formatted-plan-event-card",
|
|
248
263
|
"formatted-file-diff-event-card",
|
|
264
|
+
"formatted-finish-result-diff-card",
|
|
249
265
|
"settings-provider-dropdowns",
|
|
250
266
|
"settings-wrapper-dropdowns",
|
|
251
267
|
],
|
package/src/interactive-cli.js
CHANGED
|
@@ -778,6 +778,71 @@ export function formatWorkspaceChange(change = {}) {
|
|
|
778
778
|
};
|
|
779
779
|
}
|
|
780
780
|
|
|
781
|
+
function embeddedWorkspaceChangesFromText(value = "") {
|
|
782
|
+
const lines = String(value || "").split(/\r?\n/);
|
|
783
|
+
const changes = [];
|
|
784
|
+
let currentTool = "";
|
|
785
|
+
|
|
786
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
787
|
+
const toolMatch = lines[index].match(/^\s*Tool:\s*(.+?)\s*$/i);
|
|
788
|
+
if (toolMatch) {
|
|
789
|
+
currentTool = toolMatch[1].trim();
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
const pathMatch = lines[index].match(/^\s*Path:\s*(.+?)\s*$/i);
|
|
794
|
+
if (!pathMatch) continue;
|
|
795
|
+
|
|
796
|
+
let cursor = index + 1;
|
|
797
|
+
while (cursor < lines.length && !/^\s*Diff:\s*$/i.test(lines[cursor]) && !/^\s*(?:Tool|Path):\s*/i.test(lines[cursor])) {
|
|
798
|
+
cursor += 1;
|
|
799
|
+
}
|
|
800
|
+
if (!/^\s*Diff:\s*$/i.test(lines[cursor] || "")) continue;
|
|
801
|
+
|
|
802
|
+
const diffLines = [];
|
|
803
|
+
cursor += 1;
|
|
804
|
+
while (cursor < lines.length) {
|
|
805
|
+
if (diffLines.length && /^\s*(?:Tool|Path):\s*/i.test(lines[cursor])) break;
|
|
806
|
+
if (
|
|
807
|
+
diffLines.length &&
|
|
808
|
+
/^\s*(?:Output:|No command output|Blocked by guardrail\.|Mock run complete\.)/i.test(lines[cursor]) &&
|
|
809
|
+
!/^[-+@ ]/.test(lines[cursor])
|
|
810
|
+
) {
|
|
811
|
+
break;
|
|
812
|
+
}
|
|
813
|
+
diffLines.push(lines[cursor]);
|
|
814
|
+
cursor += 1;
|
|
815
|
+
}
|
|
816
|
+
while (diffLines.length && !diffLines[diffLines.length - 1].trim()) diffLines.pop();
|
|
817
|
+
if (diffLines.length) {
|
|
818
|
+
changes.push({
|
|
819
|
+
toolName: currentTool || "write_file",
|
|
820
|
+
path: pathMatch[1].trim(),
|
|
821
|
+
diff: diffLines.join("\n"),
|
|
822
|
+
});
|
|
823
|
+
index = Math.max(index, cursor - 1);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
return changes;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
function embeddedWorkspaceSummary(value = "") {
|
|
831
|
+
const summary = [];
|
|
832
|
+
let skippingDiff = false;
|
|
833
|
+
for (const line of String(value || "").split(/\r?\n/)) {
|
|
834
|
+
if (/^\s*Diff:\s*$/i.test(line)) {
|
|
835
|
+
skippingDiff = true;
|
|
836
|
+
continue;
|
|
837
|
+
}
|
|
838
|
+
if (skippingDiff && /^\s*(?:Tool|Path):\s*/i.test(line)) skippingDiff = false;
|
|
839
|
+
if (skippingDiff) continue;
|
|
840
|
+
if (/^\s*Path:\s*/i.test(line)) continue;
|
|
841
|
+
summary.push(line);
|
|
842
|
+
}
|
|
843
|
+
return summary.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
844
|
+
}
|
|
845
|
+
|
|
781
846
|
function printWorkspaceChange(change = {}) {
|
|
782
847
|
if (!change?.diff) return;
|
|
783
848
|
const formatted = formatWorkspaceChange(change);
|
|
@@ -787,6 +852,15 @@ function printWorkspaceChange(change = {}) {
|
|
|
787
852
|
for (const line of formatted.lines) outputLine(`${gutter}${line}`);
|
|
788
853
|
}
|
|
789
854
|
|
|
855
|
+
function printEmbeddedWorkspaceResult(result = "", { labelName = "finish", time = "" } = {}) {
|
|
856
|
+
const changes = embeddedWorkspaceChangesFromText(result);
|
|
857
|
+
if (changes.length === 0) return false;
|
|
858
|
+
const summary = embeddedWorkspaceSummary(result);
|
|
859
|
+
if (summary) printHistoryBlock(labelName, summary, { time, bg: ansi.systemBg });
|
|
860
|
+
for (const change of changes) printWorkspaceChange(change);
|
|
861
|
+
return true;
|
|
862
|
+
}
|
|
863
|
+
|
|
790
864
|
function printPreviewBlock(role, text, { time = "", bg = ansi.systemBg, maxLines = 5 } = {}) {
|
|
791
865
|
const header = [label(role, bg).trimEnd(), time ? color(time, ansi.dim) : ""].filter(Boolean).join(" ");
|
|
792
866
|
outputLine(header);
|
|
@@ -2201,6 +2275,24 @@ async function latestSession() {
|
|
|
2201
2275
|
}
|
|
2202
2276
|
|
|
2203
2277
|
function printHistoryEntry(entry) {
|
|
2278
|
+
if (entry.role === "tool") {
|
|
2279
|
+
const time = entry.at ? new Date(entry.at).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : "";
|
|
2280
|
+
try {
|
|
2281
|
+
const parsed = JSON.parse(entry.content || "{}");
|
|
2282
|
+
if (parsed.toolName === "finish" && printEmbeddedWorkspaceResult(parsed.result || parsed.args?.result || "", { labelName: "finish", time })) {
|
|
2283
|
+
return;
|
|
2284
|
+
}
|
|
2285
|
+
if (parsed.diff) {
|
|
2286
|
+
printWorkspaceChange(parsed);
|
|
2287
|
+
return;
|
|
2288
|
+
}
|
|
2289
|
+
outputLine(`${label(parsed.ok === false ? "fail" : "done", parsed.ok === false ? ansi.red : ansi.systemBg)} ${toolStatusDetails(parsed)}`);
|
|
2290
|
+
return;
|
|
2291
|
+
} catch {
|
|
2292
|
+
printHistoryBlock("tool", entry.content, { time, bg: ansi.systemBg });
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2204
2296
|
const role = entry.role === "assistant" ? "aginti>" : entry.role === "user" ? "user>" : String(entry.role || "note");
|
|
2205
2297
|
const bg = role === "aginti>" ? ansi.agentBg : role === "user>" ? ansi.userBg : ansi.systemBg;
|
|
2206
2298
|
const time = entry.at ? new Date(entry.at).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : "";
|
|
@@ -2279,6 +2371,9 @@ function printResumeEvent(event = {}) {
|
|
|
2279
2371
|
printWorkspaceChange(data);
|
|
2280
2372
|
return true;
|
|
2281
2373
|
}
|
|
2374
|
+
if (data.toolName === "finish" && printEmbeddedWorkspaceResult(data.result || data.args?.result || "", { labelName: "finish" })) {
|
|
2375
|
+
return true;
|
|
2376
|
+
}
|
|
2282
2377
|
if (data.toolName === "run_command") {
|
|
2283
2378
|
printCommandOutputLog({
|
|
2284
2379
|
command: data.args?.command || data.command || "",
|
|
@@ -2318,6 +2413,7 @@ function printResumeEvent(event = {}) {
|
|
|
2318
2413
|
return true;
|
|
2319
2414
|
}
|
|
2320
2415
|
if (type === "session.finished") {
|
|
2416
|
+
if (printEmbeddedWorkspaceResult(data.result || "", { labelName: "finish" })) return true;
|
|
2321
2417
|
outputLine(`${label("state", ansi.systemBg)} status=finished${data.result ? ` result=${compactLine(data.result, 86)}` : ""}`);
|
|
2322
2418
|
return true;
|
|
2323
2419
|
}
|
|
@@ -4178,7 +4274,11 @@ async function runPrompt(prompt, state, packageDir, { approvalDepth = 0 } = {})
|
|
|
4178
4274
|
} else if (type === "tool.started") {
|
|
4179
4275
|
printStatusEvent(state, "tool", toolStatusDetails(data));
|
|
4180
4276
|
} else if (type === "tool.completed" || type === "tool.failed") {
|
|
4181
|
-
|
|
4277
|
+
if (data.toolName === "finish" && printEmbeddedWorkspaceResult(data.result || data.args?.result || "", { labelName: "finish" })) {
|
|
4278
|
+
// The finish tool can recap a workspace diff; render it like the original write/patch event.
|
|
4279
|
+
} else {
|
|
4280
|
+
printStatusEvent(state, type === "tool.failed" || data.ok === false ? "tool_failed" : "tool_done", toolStatusDetails(data));
|
|
4281
|
+
}
|
|
4182
4282
|
} else if (type === "file.changed") {
|
|
4183
4283
|
printWorkspaceChange(data);
|
|
4184
4284
|
} else if (type === "tool.blocked") {
|