@lazyingart/agintiflow 0.17.3 → 0.17.5
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 +17 -1
- package/public/styles.css +14 -0
- package/scripts/smoke-cli-chat.js +37 -2
- package/src/auth-onboarding.js +2 -2
- package/src/interactive-cli.js +32 -0
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -901,7 +901,7 @@ function renderWorkspacePanel(workspace = lastWorkspace, activity = lastWorkspac
|
|
|
901
901
|
const label = blocked ? t("blockedLabel") : t("changedLabel");
|
|
902
902
|
const path = escapeHtml(item.path || "");
|
|
903
903
|
const reason = blocked ? `<div class="subtle">${escapeHtml(item.reason || "")}</div>` : "";
|
|
904
|
-
const diff = item.diff ? `<pre class="change-diff">${
|
|
904
|
+
const diff = item.diff ? `<pre class="change-diff">${renderDiffHtml(item.diff, 1200)}</pre>` : "";
|
|
905
905
|
const hashes =
|
|
906
906
|
item.beforeHash || item.afterHash
|
|
907
907
|
? `<div class="change-meta"><span>before=${escapeHtml((item.beforeHash || "new").slice(0, 10))}</span><span>after=${escapeHtml((item.afterHash || "").slice(0, 10))}</span></div>`
|
|
@@ -1123,6 +1123,22 @@ function escapeHtml(value) {
|
|
|
1123
1123
|
);
|
|
1124
1124
|
}
|
|
1125
1125
|
|
|
1126
|
+
function renderDiffHtml(value, maxChars = 1200) {
|
|
1127
|
+
return String(value || "")
|
|
1128
|
+
.slice(0, maxChars)
|
|
1129
|
+
.split(/\r?\n/)
|
|
1130
|
+
.map((line) => {
|
|
1131
|
+
const escaped = escapeHtml(line);
|
|
1132
|
+
if (/^\+(?!\+\+)/.test(line)) return `<span class="diff-add">${escaped}</span>`;
|
|
1133
|
+
if (/^-(?!--)/.test(line)) return `<span class="diff-del">${escaped}</span>`;
|
|
1134
|
+
if (/^\+\+\+/.test(line)) return `<span class="diff-file-add">${escaped}</span>`;
|
|
1135
|
+
if (/^---/.test(line)) return `<span class="diff-file-del">${escaped}</span>`;
|
|
1136
|
+
if (/^@@/.test(line)) return `<span class="diff-hunk">${escaped}</span>`;
|
|
1137
|
+
return escaped;
|
|
1138
|
+
})
|
|
1139
|
+
.join("\n");
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1126
1142
|
function safeLinkHref(value) {
|
|
1127
1143
|
const raw = String(value || "").trim();
|
|
1128
1144
|
try {
|
package/public/styles.css
CHANGED
|
@@ -481,6 +481,20 @@ button.danger {
|
|
|
481
481
|
overflow-wrap: anywhere;
|
|
482
482
|
}
|
|
483
483
|
|
|
484
|
+
.change-diff .diff-add,
|
|
485
|
+
.change-diff .diff-file-add {
|
|
486
|
+
color: #86efac;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.change-diff .diff-del,
|
|
490
|
+
.change-diff .diff-file-del {
|
|
491
|
+
color: #fca5a5;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
.change-diff .diff-hunk {
|
|
495
|
+
color: #67e8f9;
|
|
496
|
+
}
|
|
497
|
+
|
|
484
498
|
.sandbox-card h2 {
|
|
485
499
|
margin: 0 0 4px;
|
|
486
500
|
font-size: 1.05rem;
|
|
@@ -4,7 +4,7 @@ import fs from "node:fs/promises";
|
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
|
-
import { buildPromptLayout, classifyEscapeAction, stripMarkdown } from "../src/interactive-cli.js";
|
|
7
|
+
import { buildPromptLayout, classifyEscapeAction, formatWorkspaceChange, stripMarkdown } from "../src/interactive-cli.js";
|
|
8
8
|
|
|
9
9
|
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
10
10
|
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "agintiflow-cli-chat-"));
|
|
@@ -85,6 +85,21 @@ try {
|
|
|
85
85
|
if (!renderedDiff.includes("-old") || !renderedDiff.includes("+new")) {
|
|
86
86
|
throw new Error("terminal markdown renderer dropped patch diff lines");
|
|
87
87
|
}
|
|
88
|
+
const renderedPatchEvent = formatWorkspaceChange({
|
|
89
|
+
toolName: "apply_patch",
|
|
90
|
+
path: "test_cli.py",
|
|
91
|
+
beforeHash: "aaaaaaaa11111111",
|
|
92
|
+
afterHash: "bbbbbbbb22222222",
|
|
93
|
+
diff: ["--- a/test_cli.py", "+++ b/test_cli.py", "@@ line 10 @@", "-old line", "+new line"].join("\n"),
|
|
94
|
+
});
|
|
95
|
+
if (
|
|
96
|
+
renderedPatchEvent.label !== "patch" ||
|
|
97
|
+
!renderedPatchEvent.summary.includes("test_cli.py") ||
|
|
98
|
+
!renderedPatchEvent.lines.join("\n").includes("-old line") ||
|
|
99
|
+
!renderedPatchEvent.lines.join("\n").includes("+new line")
|
|
100
|
+
) {
|
|
101
|
+
throw new Error("workspace patch event formatter did not preserve red/green diff content");
|
|
102
|
+
}
|
|
88
103
|
|
|
89
104
|
const promptLayout = buildPromptLayout(`${"x".repeat(180)}\nsecond line`, 95, 80, 24);
|
|
90
105
|
const promptText = promptLayout.renderedRows
|
|
@@ -185,7 +200,27 @@ try {
|
|
|
185
200
|
{
|
|
186
201
|
ok: true,
|
|
187
202
|
projectRoot: tempRoot,
|
|
188
|
-
checks: [
|
|
203
|
+
checks: [
|
|
204
|
+
"markdown-render",
|
|
205
|
+
"markdown-table-no-duplicate",
|
|
206
|
+
"patch-diff-render",
|
|
207
|
+
"workspace-patch-event-render",
|
|
208
|
+
"prompt-layout",
|
|
209
|
+
"user-prompt-label",
|
|
210
|
+
"escape-policy",
|
|
211
|
+
"live-input-status-layout",
|
|
212
|
+
"agent-response-gutter",
|
|
213
|
+
"aginti-md",
|
|
214
|
+
"instructions-command",
|
|
215
|
+
"skills-command",
|
|
216
|
+
"slash-prefix-autoselect",
|
|
217
|
+
"instructions-chat-edit",
|
|
218
|
+
"interactive-chat",
|
|
219
|
+
"mock-file-write",
|
|
220
|
+
"run-status",
|
|
221
|
+
"resume-latest",
|
|
222
|
+
"resume-history-full",
|
|
223
|
+
],
|
|
189
224
|
},
|
|
190
225
|
null,
|
|
191
226
|
2
|
package/src/auth-onboarding.js
CHANGED
|
@@ -107,7 +107,7 @@ function boxedLine(content, width) {
|
|
|
107
107
|
function secretInputDisplay({ value, selectedPreview, placeholder }) {
|
|
108
108
|
if (value) return color(`${"•".repeat(Math.min(value.length, 24))} (${value.length} chars)`, ansi.inputBg);
|
|
109
109
|
if (selectedPreview) return `${color(` ${selectedPreview} `, ansi.selected, ansi.bold)} ${color("selected", ansi.yellow)}`;
|
|
110
|
-
return color(placeholder || "
|
|
110
|
+
return color(String(placeholder || "").padEnd(30, " "), ansi.inputBg);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
function renderSecretBox({ title, helpText, statusText, currentPreview, value, selected, actionText }) {
|
|
@@ -119,7 +119,7 @@ function renderSecretBox({ title, helpText, statusText, currentPreview, value, s
|
|
|
119
119
|
boxedLine(color(compactLine(title, inner), ansi.bold, ansi.cyan), width),
|
|
120
120
|
helpText ? boxedLine(`${color("key", ansi.muted)} ${compactLine(helpText, inner - 6)}`, width) : "",
|
|
121
121
|
statusText ? boxedLine(`${color("status", ansi.muted)} ${compactLine(statusText, inner - 8)}`, width) : "",
|
|
122
|
-
boxedLine(`${color("input", ansi.muted)} ${secretInputDisplay({ value, selectedPreview
|
|
122
|
+
boxedLine(`${color("input", ansi.muted)} ${secretInputDisplay({ value, selectedPreview })}`, width),
|
|
123
123
|
boxedLine(color(compactLine(actionText, inner), ansi.dim), width),
|
|
124
124
|
`${color("╰", ansi.border)}${color("─", ansi.border).repeat(width - 2)}${color("╯", ansi.border)}`,
|
|
125
125
|
].filter(Boolean);
|
package/src/interactive-cli.js
CHANGED
|
@@ -356,6 +356,36 @@ function printAgentMessage(text) {
|
|
|
356
356
|
for (const line of lines) outputLine(`${responsePrefix()}${line}`);
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
+
export function formatWorkspaceChange(change = {}) {
|
|
360
|
+
const toolName = String(change.toolName || change.action || "change");
|
|
361
|
+
const path = String(change.path || "");
|
|
362
|
+
const summary = [
|
|
363
|
+
toolName,
|
|
364
|
+
path,
|
|
365
|
+
change.created ? "created" : "",
|
|
366
|
+
change.beforeHash ? `before=${String(change.beforeHash).slice(0, 8)}` : "before=new",
|
|
367
|
+
change.afterHash ? `after=${String(change.afterHash).slice(0, 8)}` : "",
|
|
368
|
+
]
|
|
369
|
+
.filter(Boolean)
|
|
370
|
+
.join(" ");
|
|
371
|
+
const diff = String(change.diff || "").trim();
|
|
372
|
+
const renderedDiff = diff ? stripMarkdown(`Diff:\n${diff}`).split("\n") : [];
|
|
373
|
+
return {
|
|
374
|
+
label: toolName === "apply_patch" || toolName.startsWith("apply_patch") ? "patch" : "write",
|
|
375
|
+
summary,
|
|
376
|
+
lines: renderedDiff,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function printWorkspaceChange(change = {}) {
|
|
381
|
+
if (!change?.diff) return;
|
|
382
|
+
const formatted = formatWorkspaceChange(change);
|
|
383
|
+
const bg = formatted.label === "patch" ? ansi.magenta : ansi.systemBg;
|
|
384
|
+
outputLine(`${label(formatted.label, bg)} ${compactLine(formatted.summary, 92)}`);
|
|
385
|
+
const gutter = `${color(" | ", bg)} `;
|
|
386
|
+
for (const line of formatted.lines) outputLine(`${gutter}${line}`);
|
|
387
|
+
}
|
|
388
|
+
|
|
359
389
|
function printPreviewBlock(role, text, { time = "", bg = ansi.systemBg, maxLines = 5 } = {}) {
|
|
360
390
|
const header = [label(role, bg).trimEnd(), time ? color(time, ansi.dim) : ""].filter(Boolean).join(" ");
|
|
361
391
|
outputLine(header);
|
|
@@ -1795,6 +1825,8 @@ async function runPrompt(prompt, state, packageDir) {
|
|
|
1795
1825
|
printStatusEvent(state, "tool", data.toolName || "unknown");
|
|
1796
1826
|
} else if (type === "tool.completed") {
|
|
1797
1827
|
printStatusEvent(state, "tool_done", data.toolName || "unknown");
|
|
1828
|
+
} else if (type === "file.changed") {
|
|
1829
|
+
printWorkspaceChange(data);
|
|
1798
1830
|
} else if (type === "tool.blocked") {
|
|
1799
1831
|
printStatusEvent(state, "tool_blocked", data.toolName || data.reason || "unknown");
|
|
1800
1832
|
} else if (type === "loop.guard") {
|