codebase-cli 2.0.0-pre.4 → 2.0.0-pre.41
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/dist/agent/agent.js +43 -15
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/config.js +61 -20
- package/dist/agent/config.js.map +1 -1
- package/dist/agent/events.bench.js +84 -0
- package/dist/agent/events.bench.js.map +1 -0
- package/dist/agent/prompt-suggestion.js +141 -0
- package/dist/agent/prompt-suggestion.js.map +1 -0
- package/dist/agent/system-prompt.js +15 -0
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/app-server/protocol.js +7 -0
- package/dist/app-server/protocol.js.map +1 -0
- package/dist/app-server/server.js +241 -0
- package/dist/app-server/server.js.map +1 -0
- package/dist/auth/cli.js +1 -1
- package/dist/auth/cli.js.map +1 -1
- package/dist/auth/credentials.js +33 -2
- package/dist/auth/credentials.js.map +1 -1
- package/dist/auth/flow.js +145 -24
- package/dist/auth/flow.js.map +1 -1
- package/dist/auth/token-manager.js +122 -0
- package/dist/auth/token-manager.js.map +1 -0
- package/dist/cli.js +56 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/builtins.js +160 -14
- package/dist/commands/builtins.js.map +1 -1
- package/dist/commands/registry.js +46 -1
- package/dist/commands/registry.js.map +1 -1
- package/dist/compaction/monitor.js +38 -0
- package/dist/compaction/monitor.js.map +1 -0
- package/dist/config/types.js.map +1 -1
- package/dist/glue/client.js +12 -2
- package/dist/glue/client.js.map +1 -1
- package/dist/hooks/manager.js +8 -2
- package/dist/hooks/manager.js.map +1 -1
- package/dist/memory/store.js +2 -3
- package/dist/memory/store.js.map +1 -1
- package/dist/plan/run-flow.js +89 -0
- package/dist/plan/run-flow.js.map +1 -0
- package/dist/projects/cli.js +92 -0
- package/dist/projects/cli.js.map +1 -0
- package/dist/projects/client.js +120 -0
- package/dist/projects/client.js.map +1 -0
- package/dist/projects/types.js +2 -0
- package/dist/projects/types.js.map +1 -0
- package/dist/skills/platform-loader.js +133 -38
- package/dist/skills/platform-loader.js.map +1 -1
- package/dist/tools/__test__/mock-tool-context.js +31 -0
- package/dist/tools/__test__/mock-tool-context.js.map +1 -0
- package/dist/tools/file-state-cache.js.map +1 -1
- package/dist/tools/read-file.js +7 -2
- package/dist/tools/read-file.js.map +1 -1
- package/dist/ui/App.js +109 -110
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/CompactionBanner.js +23 -0
- package/dist/ui/CompactionBanner.js.map +1 -0
- package/dist/ui/FirstRunSetup.js +66 -14
- package/dist/ui/FirstRunSetup.js.map +1 -1
- package/dist/ui/Input.js +370 -20
- package/dist/ui/Input.js.map +1 -1
- package/dist/ui/Markdown.js +286 -0
- package/dist/ui/Markdown.js.map +1 -0
- package/dist/ui/Message.js +110 -48
- package/dist/ui/Message.js.map +1 -1
- package/dist/ui/MessageList.js +100 -3
- package/dist/ui/MessageList.js.map +1 -1
- package/dist/ui/Permission.js +43 -20
- package/dist/ui/Permission.js.map +1 -1
- package/dist/ui/PixelC.js +25 -0
- package/dist/ui/PixelC.js.map +1 -0
- package/dist/ui/Status.js +267 -7
- package/dist/ui/Status.js.map +1 -1
- package/dist/ui/Throbber.js +11 -7
- package/dist/ui/Throbber.js.map +1 -1
- package/dist/ui/Welcome.js +59 -0
- package/dist/ui/Welcome.js.map +1 -0
- package/dist/ui/attachments.js +68 -0
- package/dist/ui/attachments.js.map +1 -0
- package/dist/ui/debug-input.js +44 -0
- package/dist/ui/debug-input.js.map +1 -0
- package/dist/ui/diff-summary.js +171 -0
- package/dist/ui/diff-summary.js.map +1 -0
- package/dist/ui/highlight.js +324 -0
- package/dist/ui/highlight.js.map +1 -0
- package/dist/ui/history-store.js +60 -0
- package/dist/ui/history-store.js.map +1 -0
- package/dist/ui/input-state.js +125 -1
- package/dist/ui/input-state.js.map +1 -1
- package/dist/ui/path-complete.js +102 -0
- package/dist/ui/path-complete.js.map +1 -0
- package/dist/ui/paths.js +41 -0
- package/dist/ui/paths.js.map +1 -0
- package/dist/ui/shell-escape.js +42 -0
- package/dist/ui/shell-escape.js.map +1 -0
- package/dist/ui/terminal-restore.js +83 -0
- package/dist/ui/terminal-restore.js.map +1 -0
- package/dist/ui/terminal-title.js +21 -0
- package/dist/ui/terminal-title.js.map +1 -0
- package/dist/ui/tool-call-line.js +83 -0
- package/dist/ui/tool-call-line.js.map +1 -0
- package/dist/ui/tool-labels.js +194 -0
- package/dist/ui/tool-labels.js.map +1 -0
- package/dist/ui/truncated-output.js +42 -0
- package/dist/ui/truncated-output.js.map +1 -0
- package/dist/ui/use-coalesced-agent-events.js +70 -0
- package/dist/ui/use-coalesced-agent-events.js.map +1 -0
- package/dist/ui/use-prompt-suggestion.js +52 -0
- package/dist/ui/use-prompt-suggestion.js.map +1 -0
- package/dist/ui/wrapped-lines.js +18 -0
- package/dist/ui/wrapped-lines.js.map +1 -0
- package/package.json +6 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { execSync } from "node:child_process";
|
|
3
|
+
import { basename } from "node:path";
|
|
4
|
+
import { Box, Text } from "ink";
|
|
5
|
+
import { PixelC } from "./PixelC.js";
|
|
6
|
+
/**
|
|
7
|
+
* Best-effort git probe for the welcome banner. Returns null if the
|
|
8
|
+
* cwd isn't a git repo (or if `git` isn't on PATH), so non-git
|
|
9
|
+
* projects get a cleaner banner instead of an empty line. We swallow
|
|
10
|
+
* all errors — the banner is decorative; a slow / failing git
|
|
11
|
+
* shouldn't block startup.
|
|
12
|
+
*/
|
|
13
|
+
function readGitInfo(cwd) {
|
|
14
|
+
try {
|
|
15
|
+
const branch = execSync("git rev-parse --abbrev-ref HEAD", {
|
|
16
|
+
cwd,
|
|
17
|
+
encoding: "utf8",
|
|
18
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
19
|
+
}).trim();
|
|
20
|
+
if (!branch)
|
|
21
|
+
return null;
|
|
22
|
+
const status = execSync("git status --porcelain", {
|
|
23
|
+
cwd,
|
|
24
|
+
encoding: "utf8",
|
|
25
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
26
|
+
});
|
|
27
|
+
const dirty = status.split("\n").filter((l) => l.trim().length > 0).length;
|
|
28
|
+
return { branch, dirty };
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Humanize an absolute timestamp into "5m ago" / "3h ago" / "2d ago" — sub-minute reads as "just now". */
|
|
35
|
+
function formatAgo(ts) {
|
|
36
|
+
const sec = Math.max(0, Math.floor((Date.now() - ts) / 1000));
|
|
37
|
+
if (sec < 60)
|
|
38
|
+
return "just now";
|
|
39
|
+
if (sec < 3600)
|
|
40
|
+
return `${Math.floor(sec / 60)}m ago`;
|
|
41
|
+
if (sec < 86400)
|
|
42
|
+
return `${Math.floor(sec / 3600)}h ago`;
|
|
43
|
+
return `${Math.floor(sec / 86400)}d ago`;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Empty-state banner shown above the input while the transcript is
|
|
47
|
+
* empty. Pixel-C logo on the left, contextual info + tips on the
|
|
48
|
+
* right. Renders once and gets pushed up by the first user message —
|
|
49
|
+
* not Static-rendered, but only a few rows so it's cheap.
|
|
50
|
+
*/
|
|
51
|
+
export function Welcome({ modelName, source, cwd, resumedFrom }) {
|
|
52
|
+
const cwdLabel = basename(cwd) || cwd;
|
|
53
|
+
const sourceLabel = source === "proxy" ? "signed in via codebase.design" : source === "byok" ? "BYOK" : `${source}`;
|
|
54
|
+
const gitInfo = readGitInfo(cwd);
|
|
55
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { marginRight: 2, children: _jsx(PixelC, {}) }), _jsxs(Box, { flexDirection: "column", justifyContent: "center", children: [_jsx(Text, { bold: true, color: "cyan", children: "codebase" }), _jsx(Text, { dimColor: true, children: modelName }), _jsxs(Text, { dimColor: true, children: [cwdLabel, " \u00B7 ", sourceLabel] }), gitInfo ? (_jsxs(Text, { dimColor: true, children: [gitInfo.branch, gitInfo.dirty > 0
|
|
56
|
+
? ` · ${gitInfo.dirty} uncommitted change${gitInfo.dirty === 1 ? "" : "s"}`
|
|
57
|
+
: " · clean"] })) : null] })] }), resumedFrom ? (_jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: "cyan", children: ["\u21BB Resumed from ", formatAgo(resumedFrom.updatedAt)] }), _jsxs(Text, { dimColor: true, children: [" ", "\u00B7 ", resumedFrom.messageCount, " message", resumedFrom.messageCount === 1 ? "" : "s"] })] })) : null, _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "Ask me to read code, edit files, run commands, or anything in between." }), _jsxs(Text, { dimColor: true, children: [_jsx(Text, { color: "cyan", children: "/" }), " commands \u00B7 ", _jsx(Text, { color: "cyan", children: "!" }), "shell \u00B7 ", _jsx(Text, { color: "cyan", children: "\u2191\u2193" }), " ", "history \u00B7 ", _jsx(Text, { color: "cyan", children: "Tab" }), " complete \u00B7 ", _jsx(Text, { color: "cyan", children: "\\" }), "+Enter for newline"] }), _jsx(Text, { dimColor: true, children: "Ctrl-C twice to exit." })] })] }));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=Welcome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Welcome.js","sourceRoot":"","sources":["../../src/ui/Welcome.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, join } from "node:path";
|
|
3
|
+
export const MAX_ATTACHMENT_BYTES = 128 * 1024;
|
|
4
|
+
export const MAX_ATTACHMENTS = 8;
|
|
5
|
+
/**
|
|
6
|
+
* Scan the prompt for `@<path>` tokens and resolve each to a readable
|
|
7
|
+
* file under (or adjacent to) the cwd. Returns one entry per resolved
|
|
8
|
+
* file; unresolved `@` mentions don't appear here and stay as literal
|
|
9
|
+
* text — we never silently drop or rewrite user input.
|
|
10
|
+
*
|
|
11
|
+
* Skip rules:
|
|
12
|
+
* - tokens without a slash or dot (email-style @alice mentions)
|
|
13
|
+
* - paths over 256 chars (clearly not a real path)
|
|
14
|
+
* - non-files (directories, sockets, ...)
|
|
15
|
+
* - files larger than MAX_ATTACHMENT_BYTES
|
|
16
|
+
* - past MAX_ATTACHMENTS total attachments per prompt
|
|
17
|
+
*/
|
|
18
|
+
export function collectAttachments(text, cwd) {
|
|
19
|
+
const out = [];
|
|
20
|
+
const seen = new Set();
|
|
21
|
+
const pattern = /@([A-Za-z0-9_./-]+)/g;
|
|
22
|
+
for (const match of text.matchAll(pattern)) {
|
|
23
|
+
if (out.length >= MAX_ATTACHMENTS)
|
|
24
|
+
break;
|
|
25
|
+
const rel = match[1];
|
|
26
|
+
if (!rel || rel.length > 256)
|
|
27
|
+
continue;
|
|
28
|
+
if (!rel.includes("/") && !rel.includes("."))
|
|
29
|
+
continue;
|
|
30
|
+
const abs = isAbsolute(rel) ? rel : join(cwd, rel);
|
|
31
|
+
if (seen.has(abs))
|
|
32
|
+
continue;
|
|
33
|
+
seen.add(abs);
|
|
34
|
+
try {
|
|
35
|
+
const stat = statSync(abs);
|
|
36
|
+
if (!stat.isFile())
|
|
37
|
+
continue;
|
|
38
|
+
if (stat.size > MAX_ATTACHMENT_BYTES)
|
|
39
|
+
continue;
|
|
40
|
+
const content = readFileSync(abs, "utf8");
|
|
41
|
+
out.push({ token: match[0], relPath: rel, absPath: abs, content });
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// File doesn't exist or isn't readable — leave the token in text.
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Build the agent-bound prompt with attachments inlined as fenced code
|
|
51
|
+
* blocks above the user's actual ask. The original `@path` tokens stay
|
|
52
|
+
* in the text so the model can correlate the references with the
|
|
53
|
+
* attached content.
|
|
54
|
+
*/
|
|
55
|
+
export function buildAttachmentPrompt(text, attachments) {
|
|
56
|
+
const parts = ["Attached files (auto-inlined from @ mentions):", ""];
|
|
57
|
+
for (const a of attachments) {
|
|
58
|
+
parts.push(`### ${a.relPath}`);
|
|
59
|
+
parts.push("```");
|
|
60
|
+
parts.push(a.content);
|
|
61
|
+
parts.push("```");
|
|
62
|
+
parts.push("");
|
|
63
|
+
}
|
|
64
|
+
parts.push("---");
|
|
65
|
+
parts.push(text);
|
|
66
|
+
return parts.join("\n");
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/ui/attachments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAS7C,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,GAAG,IAAI,CAAC;AAC/C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AAEjC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,GAAW;IAC3D,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAAG,sBAAsB,CAAC;IACvC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,IAAI,GAAG,CAAC,MAAM,IAAI,eAAe;YAAE,MAAM;QACzC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG;YAAE,SAAS;QACvC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QACvD,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;gBAAE,SAAS;YAC7B,IAAI,IAAI,CAAC,IAAI,GAAG,oBAAoB;gBAAE,SAAS;YAC/C,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1C,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QACpE,CAAC;QAAC,MAAM,CAAC;YACR,kEAAkE;QACnE,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY,EAAE,WAAkC;IACrF,MAAM,KAAK,GAAa,CAAC,gDAAgD,EAAE,EAAE,CAAC,CAAC;IAC/E,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { appendFileSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
let logPath = null;
|
|
5
|
+
let warned = false;
|
|
6
|
+
export function isDebugInputEnabled() {
|
|
7
|
+
return process.env.CODEBASE_DEBUG_INPUT === "1";
|
|
8
|
+
}
|
|
9
|
+
function resolveLogPath() {
|
|
10
|
+
if (logPath)
|
|
11
|
+
return logPath;
|
|
12
|
+
const dir = join(homedir(), ".codebase", "logs");
|
|
13
|
+
try {
|
|
14
|
+
mkdirSync(dir, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// The fs error is non-fatal; the appendFileSync below will throw
|
|
18
|
+
// the same problem and we'll surface it once via the `warned`
|
|
19
|
+
// guard, not on every keystroke.
|
|
20
|
+
}
|
|
21
|
+
logPath = join(dir, "input.log");
|
|
22
|
+
return logPath;
|
|
23
|
+
}
|
|
24
|
+
export function logInputEvent(input, key) {
|
|
25
|
+
if (!isDebugInputEnabled())
|
|
26
|
+
return;
|
|
27
|
+
try {
|
|
28
|
+
const entry = {
|
|
29
|
+
t: new Date().toISOString(),
|
|
30
|
+
// Show the actual code points so a stray \x7f or \x1b is visible.
|
|
31
|
+
input,
|
|
32
|
+
codes: Array.from(input).map((ch) => ch.charCodeAt(0)),
|
|
33
|
+
key,
|
|
34
|
+
};
|
|
35
|
+
appendFileSync(resolveLogPath(), `${JSON.stringify(entry)}\n`);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (warned)
|
|
39
|
+
return;
|
|
40
|
+
warned = true;
|
|
41
|
+
process.stderr.write(`\n[debug-input] failed to write log: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=debug-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-input.js","sourceRoot":"","sources":["../../src/ui/debug-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA8BjC,IAAI,OAAO,GAAkB,IAAI,CAAC;AAClC,IAAI,MAAM,GAAG,KAAK,CAAC;AAEnB,MAAM,UAAU,mBAAmB;IAClC,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG,CAAC;AACjD,CAAC;AAED,SAAS,cAAc;IACtB,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IACjD,IAAI,CAAC;QACJ,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACR,iEAAiE;QACjE,8DAA8D;QAC9D,iCAAiC;IAClC,CAAC;IACD,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACjC,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,GAAgB;IAC5D,IAAI,CAAC,mBAAmB,EAAE;QAAE,OAAO;IACnC,IAAI,CAAC;QACJ,MAAM,KAAK,GAAG;YACb,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC3B,kEAAkE;YAClE,KAAK;YACL,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACtD,GAAG;SACH,CAAC;QACF,cAAc,CAAC,cAAc,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,IAAI,MAAM;YAAE,OAAO;QACnB,MAAM,GAAG,IAAI,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CACnB,wCAAwC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC5F,CAAC;IACH,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { diffLines, diffWordsWithSpace } from "diff";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
import { truncate } from "./tool-labels.js";
|
|
5
|
+
/** How many change lines we'll render before collapsing to just the +/- counts. */
|
|
6
|
+
const MAX_HUNK_LINES = 12;
|
|
7
|
+
/**
|
|
8
|
+
* Build a diff summary for a completed file-edit tool call from the
|
|
9
|
+
* tool's args. We have old_string + new_string right there, so no
|
|
10
|
+
* filesystem round-trip needed. Uses the `diff` library's LCS-based
|
|
11
|
+
* line pairing — adding a single line at the top no longer marks the
|
|
12
|
+
* whole rest of the file as "changed."
|
|
13
|
+
*/
|
|
14
|
+
export function diffSummary(name, args) {
|
|
15
|
+
const a = (args ?? {});
|
|
16
|
+
if (name === "edit_file") {
|
|
17
|
+
const oldStr = typeof a.old_string === "string" ? a.old_string : "";
|
|
18
|
+
const newStr = typeof a.new_string === "string" ? a.new_string : "";
|
|
19
|
+
if (!oldStr && !newStr)
|
|
20
|
+
return null;
|
|
21
|
+
return buildDiff(oldStr, newStr);
|
|
22
|
+
}
|
|
23
|
+
if (name === "multi_edit") {
|
|
24
|
+
const edits = Array.isArray(a.edits) ? a.edits : [];
|
|
25
|
+
let added = 0;
|
|
26
|
+
let removed = 0;
|
|
27
|
+
const hunks = [];
|
|
28
|
+
let truncated = false;
|
|
29
|
+
for (const e of edits) {
|
|
30
|
+
if (!e || typeof e !== "object")
|
|
31
|
+
continue;
|
|
32
|
+
const ed = e;
|
|
33
|
+
const oldStr = typeof ed.old_string === "string" ? ed.old_string : "";
|
|
34
|
+
const newStr = typeof ed.new_string === "string" ? ed.new_string : "";
|
|
35
|
+
const sub = buildDiff(oldStr, newStr);
|
|
36
|
+
added += sub.added;
|
|
37
|
+
removed += sub.removed;
|
|
38
|
+
truncated = truncated || sub.truncated;
|
|
39
|
+
hunks.push(...sub.hunks);
|
|
40
|
+
}
|
|
41
|
+
if (added === 0 && removed === 0)
|
|
42
|
+
return null;
|
|
43
|
+
return {
|
|
44
|
+
added,
|
|
45
|
+
removed,
|
|
46
|
+
hunks: hunks.slice(0, MAX_HUNK_LINES),
|
|
47
|
+
truncated: truncated || hunks.length > MAX_HUNK_LINES,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (name === "write_file") {
|
|
51
|
+
const content = typeof a.content === "string" ? a.content : "";
|
|
52
|
+
if (!content)
|
|
53
|
+
return null;
|
|
54
|
+
const lines = content.split("\n").length;
|
|
55
|
+
return { added: lines, removed: 0, hunks: [], truncated: false };
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* LCS-based line diff, then pair adjacent remove+add changes so we can
|
|
61
|
+
* surface a word-level highlight on each paired line. When a pair has
|
|
62
|
+
* the same number of lines on each side, we line-align them and run
|
|
63
|
+
* diffWordsWithSpace per row — that's the cleanest case and matches
|
|
64
|
+
* the user expectation of "show me what actually changed in this row."
|
|
65
|
+
*/
|
|
66
|
+
function buildDiff(oldStr, newStr) {
|
|
67
|
+
const changes = diffLines(oldStr, newStr);
|
|
68
|
+
const hunks = [];
|
|
69
|
+
let added = 0;
|
|
70
|
+
let removed = 0;
|
|
71
|
+
const lineCount = (s) => (s ? s.replace(/\n$/, "").split("\n").length : 0);
|
|
72
|
+
for (let i = 0; i < changes.length; i++) {
|
|
73
|
+
const c = changes[i];
|
|
74
|
+
if (c.added)
|
|
75
|
+
added += lineCount(c.value);
|
|
76
|
+
if (c.removed)
|
|
77
|
+
removed += lineCount(c.value);
|
|
78
|
+
const next = changes[i + 1];
|
|
79
|
+
const isPair = c.removed && next?.added;
|
|
80
|
+
if (isPair) {
|
|
81
|
+
const removeLines = c.value.replace(/\n$/, "").split("\n");
|
|
82
|
+
const addLines = next.value.replace(/\n$/, "").split("\n");
|
|
83
|
+
if (removeLines.length === addLines.length) {
|
|
84
|
+
// Paired row-by-row → word-level diff per row.
|
|
85
|
+
for (let j = 0; j < removeLines.length; j++) {
|
|
86
|
+
const parts = diffWordsWithSpace(removeLines[j], addLines[j]);
|
|
87
|
+
hunks.push({
|
|
88
|
+
type: "remove",
|
|
89
|
+
text: removeLines[j],
|
|
90
|
+
wordParts: parts.filter((p) => !p.added).map((p) => ({ text: p.value, highlight: !!p.removed })),
|
|
91
|
+
});
|
|
92
|
+
hunks.push({
|
|
93
|
+
type: "add",
|
|
94
|
+
text: addLines[j],
|
|
95
|
+
wordParts: parts.filter((p) => !p.removed).map((p) => ({ text: p.value, highlight: !!p.added })),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// Asymmetric pair — show all removes then all adds without word diff.
|
|
101
|
+
for (const line of removeLines)
|
|
102
|
+
hunks.push({ type: "remove", text: line });
|
|
103
|
+
for (const line of addLines)
|
|
104
|
+
hunks.push({ type: "add", text: line });
|
|
105
|
+
}
|
|
106
|
+
i++; // Consume the paired add change.
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (c.removed || c.added) {
|
|
110
|
+
const type = c.added ? "add" : "remove";
|
|
111
|
+
for (const line of c.value.replace(/\n$/, "").split("\n")) {
|
|
112
|
+
hunks.push({ type, text: line });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Context (neither added nor removed) is dropped — the +N/-M
|
|
116
|
+
// counts plus the change lines themselves give enough orientation
|
|
117
|
+
// for the small previews we render.
|
|
118
|
+
}
|
|
119
|
+
const truncated = hunks.length > MAX_HUNK_LINES;
|
|
120
|
+
return { added, removed, hunks: hunks.slice(0, MAX_HUNK_LINES), truncated };
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Render the +N -M summary line, then up to MAX_HUNK_LINES change lines.
|
|
124
|
+
* Removed lines render in red, added lines in green. Within a paired
|
|
125
|
+
* remove/add row, the actually-changed words get a brighter background
|
|
126
|
+
* so the eye lands on the substantive change immediately.
|
|
127
|
+
*/
|
|
128
|
+
export function DiffSummary({ diff, width, keyPrefix }) {
|
|
129
|
+
const counts = diff.truncated
|
|
130
|
+
? ` +${diff.added} -${diff.removed} (preview truncated)`
|
|
131
|
+
: ` +${diff.added} -${diff.removed}`;
|
|
132
|
+
const lineWidth = Math.max(20, width - 8);
|
|
133
|
+
return (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsx(Text, { dimColor: true, children: counts }), diff.hunks.map((h, i) => {
|
|
134
|
+
const isRemove = h.type === "remove";
|
|
135
|
+
const sign = isRemove ? " - " : " + ";
|
|
136
|
+
const lineColor = isRemove ? "red" : "green";
|
|
137
|
+
const hlBg = isRemove ? "redBright" : "greenBright";
|
|
138
|
+
const key = `${keyPrefix}-h-${i}-${h.type}-${h.text.slice(0, 24)}`;
|
|
139
|
+
if (h.wordParts && h.wordParts.length > 0) {
|
|
140
|
+
// Truncate at the part boundary that crosses the width budget.
|
|
141
|
+
let used = 0;
|
|
142
|
+
const visibleParts = [];
|
|
143
|
+
for (const p of h.wordParts) {
|
|
144
|
+
const remaining = lineWidth - used;
|
|
145
|
+
if (remaining <= 0)
|
|
146
|
+
break;
|
|
147
|
+
if (p.text.length <= remaining) {
|
|
148
|
+
visibleParts.push(p);
|
|
149
|
+
used += p.text.length;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
visibleParts.push({ ...p, text: `${p.text.slice(0, Math.max(0, remaining - 1))}…` });
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// Stable keys per-word: counter-suffix is only for collision when
|
|
157
|
+
// the same word appears multiple times in a line. Avoids the
|
|
158
|
+
// array-index-as-key smell while keeping React's reconciler happy.
|
|
159
|
+
const seenCounts = new Map();
|
|
160
|
+
const keyedParts = visibleParts.map((p) => {
|
|
161
|
+
const baseKey = `${p.highlight ? "h" : "n"}:${p.text}`;
|
|
162
|
+
const count = seenCounts.get(baseKey) ?? 0;
|
|
163
|
+
seenCounts.set(baseKey, count + 1);
|
|
164
|
+
return { part: p, k: `${key}-w-${baseKey}-${count}` };
|
|
165
|
+
});
|
|
166
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: lineColor, children: sign }), _jsx(Text, { children: keyedParts.map(({ part, k }) => (_jsx(Text, { color: lineColor, backgroundColor: part.highlight ? hlBg : undefined, children: part.text }, k))) })] }, key));
|
|
167
|
+
}
|
|
168
|
+
return (_jsxs(Text, { color: lineColor, children: [sign, truncate(h.text, lineWidth)] }, key));
|
|
169
|
+
})] }));
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=diff-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-summary.js","sourceRoot":"","sources":["../../src/ui/diff-summary.tsx"],"names":[],"mappings":"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"}
|