@zhijiewang/openharness 2.1.0 → 2.3.1
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/README.md +4 -4
- package/dist/DeferredTool.js +3 -1
- package/dist/Tool.d.ts +1 -1
- package/dist/agents/roles.js +58 -62
- package/dist/commands/cybergotchi.d.ts +1 -1
- package/dist/commands/cybergotchi.js +30 -30
- package/dist/commands/index.js +288 -132
- package/dist/components/App.d.ts +1 -1
- package/dist/components/App.js +6 -6
- package/dist/components/CompanionFooter.d.ts +1 -1
- package/dist/components/CompanionFooter.js +6 -8
- package/dist/components/CybergotchiBubble.js +5 -5
- package/dist/components/CybergotchiPanel.d.ts +1 -1
- package/dist/components/CybergotchiPanel.js +7 -7
- package/dist/components/CybergotchiPanelConnected.js +2 -2
- package/dist/components/CybergotchiSetup.js +26 -24
- package/dist/components/CybergotchiSprite.d.ts +1 -1
- package/dist/components/CybergotchiSprite.js +8 -12
- package/dist/components/DiffView.d.ts +1 -1
- package/dist/components/DiffView.js +10 -10
- package/dist/components/ErrorBoundary.d.ts +1 -1
- package/dist/components/ErrorBoundary.js +1 -1
- package/dist/components/InitWizard.js +65 -33
- package/dist/components/Markdown.js +2 -4
- package/dist/components/Messages.js +4 -4
- package/dist/components/PermissionPrompt.d.ts +1 -1
- package/dist/components/PermissionPrompt.js +15 -17
- package/dist/components/REPL.d.ts +1 -1
- package/dist/components/REPL.js +74 -49
- package/dist/components/Spinner.js +2 -2
- package/dist/components/TextInput.js +35 -29
- package/dist/components/ToolCallDisplay.js +3 -5
- package/dist/cybergotchi/bones.d.ts +1 -1
- package/dist/cybergotchi/bones.js +8 -8
- package/dist/cybergotchi/config.d.ts +2 -2
- package/dist/cybergotchi/config.js +13 -13
- package/dist/cybergotchi/events.d.ts +5 -5
- package/dist/cybergotchi/events.js +7 -7
- package/dist/cybergotchi/needs.d.ts +2 -2
- package/dist/cybergotchi/needs.js +7 -9
- package/dist/cybergotchi/personality.d.ts +2 -2
- package/dist/cybergotchi/personality.js +2 -2
- package/dist/cybergotchi/species.d.ts +1 -1
- package/dist/cybergotchi/species.js +145 -217
- package/dist/cybergotchi/speech.d.ts +2 -2
- package/dist/cybergotchi/speech.js +43 -43
- package/dist/cybergotchi/types.d.ts +4 -4
- package/dist/cybergotchi/types.js +26 -26
- package/dist/cybergotchi/useCybergotchi.d.ts +1 -1
- package/dist/cybergotchi/useCybergotchi.js +29 -25
- package/dist/git/index.js +11 -9
- package/dist/harness/checkpoints.js +29 -21
- package/dist/harness/config.d.ts +3 -3
- package/dist/harness/config.js +15 -9
- package/dist/harness/context-warning.d.ts +1 -1
- package/dist/harness/context-warning.js +1 -1
- package/dist/harness/cost.js +1 -1
- package/dist/harness/credentials.js +13 -13
- package/dist/harness/hooks.js +7 -5
- package/dist/harness/keybindings.js +20 -18
- package/dist/harness/marketplace.d.ts +3 -3
- package/dist/harness/marketplace.js +55 -42
- package/dist/harness/memory.d.ts +23 -5
- package/dist/harness/memory.js +142 -41
- package/dist/harness/onboarding.js +30 -10
- package/dist/harness/plugins.d.ts +9 -1
- package/dist/harness/plugins.js +54 -30
- package/dist/harness/rules.js +12 -7
- package/dist/harness/sandbox.js +15 -15
- package/dist/harness/session-db.d.ts +55 -0
- package/dist/harness/session-db.js +165 -0
- package/dist/harness/session.d.ts +1 -1
- package/dist/harness/session.js +34 -15
- package/dist/harness/store.d.ts +3 -3
- package/dist/harness/store.js +6 -4
- package/dist/harness/submit-handler.d.ts +4 -4
- package/dist/harness/submit-handler.js +25 -23
- package/dist/harness/telemetry.d.ts +1 -1
- package/dist/harness/telemetry.js +23 -19
- package/dist/harness/traces.d.ts +2 -2
- package/dist/harness/traces.js +39 -33
- package/dist/harness/verification.d.ts +1 -1
- package/dist/harness/verification.js +50 -44
- package/dist/lsp/client.js +44 -40
- package/dist/main.js +114 -59
- package/dist/mcp/DeferredMcpTool.d.ts +4 -4
- package/dist/mcp/DeferredMcpTool.js +9 -5
- package/dist/mcp/McpTool.d.ts +4 -4
- package/dist/mcp/McpTool.js +8 -4
- package/dist/mcp/client.d.ts +2 -2
- package/dist/mcp/client.js +21 -21
- package/dist/mcp/loader.d.ts +1 -1
- package/dist/mcp/loader.js +17 -12
- package/dist/mcp/registry.d.ts +3 -3
- package/dist/mcp/registry.js +97 -97
- package/dist/mcp/schema.d.ts +1 -1
- package/dist/mcp/schema.js +16 -16
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +21 -21
- package/dist/mcp/types.d.ts +3 -3
- package/dist/providers/anthropic.d.ts +2 -2
- package/dist/providers/anthropic.js +10 -9
- package/dist/providers/base.d.ts +1 -1
- package/dist/providers/index.js +10 -3
- package/dist/providers/llamacpp.d.ts +2 -2
- package/dist/providers/llamacpp.js +1 -3
- package/dist/providers/ollama.d.ts +2 -2
- package/dist/providers/ollama.js +3 -4
- package/dist/providers/openai.d.ts +2 -2
- package/dist/providers/openai.js +3 -5
- package/dist/providers/openrouter.d.ts +2 -2
- package/dist/providers/router.d.ts +1 -1
- package/dist/providers/router.js +7 -7
- package/dist/query/compress.d.ts +2 -2
- package/dist/query/compress.js +22 -21
- package/dist/query/context-manager.d.ts +1 -1
- package/dist/query/context-manager.js +5 -5
- package/dist/query/errors.js +1 -1
- package/dist/query/index.d.ts +1 -1
- package/dist/query/index.js +42 -24
- package/dist/query/tools.js +15 -12
- package/dist/query/types.d.ts +3 -1
- package/dist/query.d.ts +1 -1
- package/dist/query.js +1 -1
- package/dist/remote/auth.d.ts +2 -2
- package/dist/remote/auth.js +8 -8
- package/dist/remote/server.d.ts +3 -3
- package/dist/remote/server.js +60 -60
- package/dist/renderer/cells.js +9 -9
- package/dist/renderer/colors.js +24 -6
- package/dist/renderer/diff.d.ts +2 -2
- package/dist/renderer/diff.js +27 -19
- package/dist/renderer/differ.d.ts +1 -1
- package/dist/renderer/differ.js +9 -9
- package/dist/renderer/image.js +19 -19
- package/dist/renderer/index.d.ts +6 -6
- package/dist/renderer/index.js +163 -93
- package/dist/renderer/input.js +66 -48
- package/dist/renderer/layout.d.ts +6 -6
- package/dist/renderer/layout.js +163 -124
- package/dist/renderer/markdown.d.ts +2 -2
- package/dist/renderer/markdown.js +173 -54
- package/dist/renderer/session-browser.d.ts +2 -2
- package/dist/renderer/session-browser.js +19 -21
- package/dist/repl.d.ts +5 -5
- package/dist/repl.js +311 -198
- package/dist/sdk/index.d.ts +5 -5
- package/dist/sdk/index.js +32 -26
- package/dist/services/AgentDispatcher.d.ts +3 -3
- package/dist/services/AgentDispatcher.js +33 -29
- package/dist/services/CronExecutor.d.ts +4 -4
- package/dist/services/CronExecutor.js +12 -8
- package/dist/services/EvaluatorLoop.d.ts +3 -3
- package/dist/services/EvaluatorLoop.js +29 -21
- package/dist/services/MetaHarness.d.ts +1 -1
- package/dist/services/MetaHarness.js +34 -32
- package/dist/services/PipelineExecutor.d.ts +1 -1
- package/dist/services/PipelineExecutor.js +23 -25
- package/dist/services/SkillExtractor.d.ts +43 -0
- package/dist/services/SkillExtractor.js +163 -0
- package/dist/services/StreamingToolExecutor.d.ts +2 -2
- package/dist/services/StreamingToolExecutor.js +11 -7
- package/dist/services/a2a.d.ts +8 -8
- package/dist/services/a2a.js +44 -34
- package/dist/services/agent-messaging.d.ts +33 -15
- package/dist/services/agent-messaging.js +65 -13
- package/dist/services/cron.js +16 -16
- package/dist/tools/AgentTool/index.d.ts +5 -2
- package/dist/tools/AgentTool/index.js +25 -39
- package/dist/tools/AskUserTool/index.js +1 -1
- package/dist/tools/BashTool/index.d.ts +2 -2
- package/dist/tools/BashTool/index.js +18 -10
- package/dist/tools/CronTool/index.js +30 -12
- package/dist/tools/DiagnosticsTool/index.js +28 -22
- package/dist/tools/EnterPlanModeTool/index.js +93 -14
- package/dist/tools/EnterWorktreeTool/index.js +7 -3
- package/dist/tools/ExitPlanModeTool/index.d.ts +22 -1
- package/dist/tools/ExitPlanModeTool/index.js +20 -5
- package/dist/tools/ExitWorktreeTool/index.js +11 -4
- package/dist/tools/FileEditTool/index.js +3 -5
- package/dist/tools/FileReadTool/index.js +16 -10
- package/dist/tools/FileWriteTool/index.js +2 -2
- package/dist/tools/GlobTool/index.js +5 -9
- package/dist/tools/GrepTool/index.d.ts +2 -2
- package/dist/tools/GrepTool/index.js +14 -9
- package/dist/tools/ImageReadTool/index.js +2 -2
- package/dist/tools/KillProcessTool/index.js +11 -7
- package/dist/tools/LSTool/index.js +3 -3
- package/dist/tools/MemoryTool/index.d.ts +5 -5
- package/dist/tools/MemoryTool/index.js +28 -14
- package/dist/tools/MonitorTool/index.js +24 -19
- package/dist/tools/MultiEditTool/index.js +9 -5
- package/dist/tools/NotebookEditTool/index.js +3 -3
- package/dist/tools/ParallelAgentTool/index.d.ts +4 -4
- package/dist/tools/ParallelAgentTool/index.js +12 -6
- package/dist/tools/PipelineTool/index.js +3 -3
- package/dist/tools/PowerShellTool/index.js +10 -6
- package/dist/tools/RemoteTriggerTool/index.js +8 -4
- package/dist/tools/ScheduleWakeupTool/index.d.ts +42 -0
- package/dist/tools/ScheduleWakeupTool/index.js +115 -0
- package/dist/tools/SendMessageTool/index.js +25 -7
- package/dist/tools/SessionSearchTool/index.d.ts +15 -0
- package/dist/tools/SessionSearchTool/index.js +36 -0
- package/dist/tools/SkillTool/index.d.ts +3 -0
- package/dist/tools/SkillTool/index.js +39 -9
- package/dist/tools/TaskCreateTool/index.d.ts +2 -2
- package/dist/tools/TaskCreateTool/index.js +2 -2
- package/dist/tools/TaskGetTool/index.js +2 -2
- package/dist/tools/TaskListTool/index.js +3 -5
- package/dist/tools/TaskOutputTool/index.js +2 -2
- package/dist/tools/TaskStopTool/index.js +3 -3
- package/dist/tools/TaskUpdateTool/index.d.ts +4 -4
- package/dist/tools/TaskUpdateTool/index.js +2 -2
- package/dist/tools/ToolSearchTool/index.js +9 -6
- package/dist/tools/WebFetchTool/index.js +1 -1
- package/dist/tools/WebSearchTool/index.js +2 -6
- package/dist/tools.js +31 -30
- package/dist/types/permissions.js +15 -9
- package/dist/utils/bash-safety.d.ts +1 -1
- package/dist/utils/bash-safety.js +64 -54
- package/dist/utils/diff-algorithm.d.ts +3 -3
- package/dist/utils/diff-algorithm.js +7 -7
- package/dist/utils/fs.js +3 -3
- package/dist/utils/safe-env.js +1 -1
- package/dist/utils/theme-data.d.ts +1 -1
- package/dist/utils/theme-data.js +1 -1
- package/dist/utils/theme.d.ts +1 -1
- package/dist/utils/theme.js +1 -1
- package/dist/utils/tool-summary.d.ts +1 -1
- package/dist/utils/tool-summary.js +27 -9
- package/package.json +10 -3
package/dist/renderer/cells.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* Cell grid — 2D array of styled characters for terminal rendering.
|
|
3
3
|
*/
|
|
4
4
|
export const EMPTY_STYLE = { fg: null, bg: null, bold: false, dim: false, underline: false };
|
|
5
|
-
export const EMPTY_CELL = { char:
|
|
5
|
+
export const EMPTY_CELL = { char: " ", style: { ...EMPTY_STYLE } };
|
|
6
6
|
export function cellsEqual(a, b) {
|
|
7
|
-
return a.char === b.char &&
|
|
7
|
+
return (a.char === b.char &&
|
|
8
8
|
a.style.fg === b.style.fg &&
|
|
9
9
|
a.style.bg === b.style.bg &&
|
|
10
10
|
a.style.bold === b.style.bold &&
|
|
11
11
|
a.style.dim === b.style.dim &&
|
|
12
|
-
a.style.underline === b.style.underline;
|
|
12
|
+
a.style.underline === b.style.underline);
|
|
13
13
|
}
|
|
14
14
|
export class CellGrid {
|
|
15
15
|
width;
|
|
@@ -22,7 +22,7 @@ export class CellGrid {
|
|
|
22
22
|
for (let r = 0; r < height; r++) {
|
|
23
23
|
const row = [];
|
|
24
24
|
for (let c = 0; c < width; c++) {
|
|
25
|
-
row.push({ char:
|
|
25
|
+
row.push({ char: " ", style: { ...EMPTY_STYLE } });
|
|
26
26
|
}
|
|
27
27
|
this.cells.push(row);
|
|
28
28
|
}
|
|
@@ -31,7 +31,7 @@ export class CellGrid {
|
|
|
31
31
|
for (let r = 0; r < this.height; r++) {
|
|
32
32
|
for (let c = 0; c < this.width; c++) {
|
|
33
33
|
const cell = this.cells[r][c];
|
|
34
|
-
cell.char =
|
|
34
|
+
cell.char = " ";
|
|
35
35
|
cell.style.fg = null;
|
|
36
36
|
cell.style.bg = null;
|
|
37
37
|
cell.style.bold = false;
|
|
@@ -62,7 +62,7 @@ export class CellGrid {
|
|
|
62
62
|
let c = col;
|
|
63
63
|
for (let i = 0; i < text.length; i++) {
|
|
64
64
|
const ch = text[i];
|
|
65
|
-
if (ch ===
|
|
65
|
+
if (ch === "\n") {
|
|
66
66
|
r++;
|
|
67
67
|
c = col;
|
|
68
68
|
continue;
|
|
@@ -84,12 +84,12 @@ export class CellGrid {
|
|
|
84
84
|
*/
|
|
85
85
|
writeWrapped(row, col, text, style, wrapWidth, maxRow) {
|
|
86
86
|
const limit = maxRow ?? this.height;
|
|
87
|
-
const lines = text.split(
|
|
87
|
+
const lines = text.split("\n");
|
|
88
88
|
let r = row;
|
|
89
89
|
for (const line of lines) {
|
|
90
90
|
if (r >= limit)
|
|
91
91
|
break;
|
|
92
|
-
const words = line.split(
|
|
92
|
+
const words = line.split(" ");
|
|
93
93
|
let c = col;
|
|
94
94
|
for (const word of words) {
|
|
95
95
|
if (word.length === 0)
|
|
@@ -103,7 +103,7 @@ export class CellGrid {
|
|
|
103
103
|
}
|
|
104
104
|
// Add space before word (unless at start of line)
|
|
105
105
|
if (c > col) {
|
|
106
|
-
this.setCell(r, c,
|
|
106
|
+
this.setCell(r, c, " ", style);
|
|
107
107
|
c++;
|
|
108
108
|
}
|
|
109
109
|
// Write word character by character (may still wrap if word > wrapWidth)
|
package/dist/renderer/colors.js
CHANGED
|
@@ -2,14 +2,32 @@
|
|
|
2
2
|
* Shared ANSI color code mappings for terminal rendering.
|
|
3
3
|
*/
|
|
4
4
|
export const FG_CODES = {
|
|
5
|
-
black: 30,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
black: 30,
|
|
6
|
+
red: 31,
|
|
7
|
+
green: 32,
|
|
8
|
+
yellow: 33,
|
|
9
|
+
blue: 34,
|
|
10
|
+
magenta: 35,
|
|
11
|
+
cyan: 36,
|
|
12
|
+
white: 37,
|
|
13
|
+
gray: 90,
|
|
14
|
+
brightRed: 91,
|
|
15
|
+
brightGreen: 92,
|
|
16
|
+
brightYellow: 93,
|
|
17
|
+
brightBlue: 94,
|
|
18
|
+
brightMagenta: 95,
|
|
19
|
+
brightCyan: 96,
|
|
20
|
+
brightWhite: 97,
|
|
9
21
|
};
|
|
10
22
|
export const BG_CODES = {
|
|
11
|
-
black: 40,
|
|
12
|
-
|
|
23
|
+
black: 40,
|
|
24
|
+
red: 41,
|
|
25
|
+
green: 42,
|
|
26
|
+
yellow: 43,
|
|
27
|
+
blue: 44,
|
|
28
|
+
magenta: 45,
|
|
29
|
+
cyan: 46,
|
|
30
|
+
white: 47,
|
|
13
31
|
};
|
|
14
32
|
/** Get foreground ANSI code for a color name, defaults to white (37). */
|
|
15
33
|
export function FG(color) {
|
package/dist/renderer/diff.d.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* Diff rendering for CellGrid — used in the permission prompt
|
|
3
3
|
* to show inline diffs for write/edit tool calls.
|
|
4
4
|
*/
|
|
5
|
-
import type { CellGrid } from
|
|
5
|
+
import type { CellGrid } from "./cells.js";
|
|
6
6
|
export declare function resetDiffStyleCache(): void;
|
|
7
7
|
export type DiffLine = {
|
|
8
|
-
type:
|
|
8
|
+
type: "add" | "remove" | "context" | "separator";
|
|
9
9
|
line: string;
|
|
10
10
|
};
|
|
11
11
|
export type DiffInfo = {
|
package/dist/renderer/diff.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* Diff rendering for CellGrid — used in the permission prompt
|
|
3
3
|
* to show inline diffs for write/edit tool calls.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { HIGHLIGHT_LANGS, renderHighlightedCode } from
|
|
5
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
6
|
+
import { computeDiff, filterWithContext } from "../utils/diff-algorithm.js";
|
|
7
|
+
import { getTheme } from "../utils/theme-data.js";
|
|
8
|
+
import { HIGHLIGHT_LANGS, renderHighlightedCode } from "./markdown.js";
|
|
9
9
|
const s = (fg, bold = false, dim = false) => ({ fg, bg: null, bold, dim, underline: false });
|
|
10
10
|
const S_CONTEXT = s(null, false, true);
|
|
11
11
|
const S_SEPARATOR = s(null, false, true);
|
|
@@ -13,7 +13,9 @@ const S_HEADER = s(null, false, true);
|
|
|
13
13
|
// Theme-dependent (lazy)
|
|
14
14
|
let S_ADD, S_REMOVE, S_STAT_ADD, S_STAT_REMOVE;
|
|
15
15
|
let _diffStylesInit = false;
|
|
16
|
-
export function resetDiffStyleCache() {
|
|
16
|
+
export function resetDiffStyleCache() {
|
|
17
|
+
_diffStylesInit = false;
|
|
18
|
+
}
|
|
17
19
|
function ensureDiffStyles() {
|
|
18
20
|
if (_diffStylesInit)
|
|
19
21
|
return;
|
|
@@ -32,15 +34,21 @@ export function extractDiffInfo(toolName, argsJson) {
|
|
|
32
34
|
try {
|
|
33
35
|
const args = JSON.parse(argsJson);
|
|
34
36
|
const name = toolName.toLowerCase();
|
|
35
|
-
if (name.includes(
|
|
36
|
-
const old = existsSync(args.file_path) ? readFileSync(args.file_path,
|
|
37
|
+
if (name.includes("write") && args.file_path && args.content) {
|
|
38
|
+
const old = existsSync(args.file_path) ? readFileSync(args.file_path, "utf-8") : "";
|
|
37
39
|
return { filePath: args.file_path, oldContent: old, newContent: args.content };
|
|
38
40
|
}
|
|
39
|
-
if (name.includes(
|
|
41
|
+
if (name.includes("edit") && args.file_path && args.old_string && args.new_string) {
|
|
40
42
|
if (existsSync(args.file_path)) {
|
|
41
|
-
const old = readFileSync(args.file_path,
|
|
43
|
+
const old = readFileSync(args.file_path, "utf-8");
|
|
42
44
|
const newContent = old.replace(args.old_string, args.new_string);
|
|
43
|
-
return {
|
|
45
|
+
return {
|
|
46
|
+
filePath: args.file_path,
|
|
47
|
+
oldContent: old,
|
|
48
|
+
newContent,
|
|
49
|
+
oldString: args.old_string,
|
|
50
|
+
newString: args.new_string,
|
|
51
|
+
};
|
|
44
52
|
}
|
|
45
53
|
}
|
|
46
54
|
return null;
|
|
@@ -60,8 +68,8 @@ export function prepareDiff(diffInfo, maxLines = 20) {
|
|
|
60
68
|
const rawDiff = computeDiff(diffInfo.oldContent, diffInfo.newContent);
|
|
61
69
|
const filtered = filterWithContext(rawDiff);
|
|
62
70
|
diffInfo.cachedDisplay = filtered.slice(0, maxLines);
|
|
63
|
-
diffInfo.cachedAdds = rawDiff.filter(d => d.type ===
|
|
64
|
-
diffInfo.cachedRemoves = rawDiff.filter(d => d.type ===
|
|
71
|
+
diffInfo.cachedAdds = rawDiff.filter((d) => d.type === "add").length;
|
|
72
|
+
diffInfo.cachedRemoves = rawDiff.filter((d) => d.type === "remove").length;
|
|
65
73
|
}
|
|
66
74
|
export function renderDiff(grid, row, col, diffInfo, width, maxLines = 20) {
|
|
67
75
|
ensureDiffStyles();
|
|
@@ -77,7 +85,7 @@ export function renderDiff(grid, row, col, diffInfo, width, maxLines = 20) {
|
|
|
77
85
|
// Stats
|
|
78
86
|
if (r < grid.height) {
|
|
79
87
|
grid.writeText(r, col, `+${adds}`, S_STAT_ADD);
|
|
80
|
-
grid.writeText(r, col + `+${adds}`.length,
|
|
88
|
+
grid.writeText(r, col + `+${adds}`.length, " ", S_CONTEXT);
|
|
81
89
|
grid.writeText(r, col + `+${adds}`.length + 1, `-${removes}`, S_STAT_REMOVE);
|
|
82
90
|
r++;
|
|
83
91
|
}
|
|
@@ -85,17 +93,17 @@ export function renderDiff(grid, row, col, diffInfo, width, maxLines = 20) {
|
|
|
85
93
|
for (const d of display) {
|
|
86
94
|
if (r >= grid.height)
|
|
87
95
|
break;
|
|
88
|
-
if (d.type ===
|
|
89
|
-
grid.writeText(r, col,
|
|
96
|
+
if (d.type === "separator") {
|
|
97
|
+
grid.writeText(r, col, " ...", S_SEPARATOR);
|
|
90
98
|
r++;
|
|
91
99
|
continue;
|
|
92
100
|
}
|
|
93
|
-
const prefix = d.type ===
|
|
94
|
-
const style = d.type ===
|
|
101
|
+
const prefix = d.type === "add" ? "+ " : d.type === "remove" ? "- " : " ";
|
|
102
|
+
const style = d.type === "add" ? S_ADD : d.type === "remove" ? S_REMOVE : S_CONTEXT;
|
|
95
103
|
grid.writeText(r, col, prefix, style);
|
|
96
104
|
// Apply syntax highlighting to the code content
|
|
97
|
-
const ext = diffInfo.filePath.split(
|
|
98
|
-
const lang = ext ===
|
|
105
|
+
const ext = diffInfo.filePath.split(".").pop()?.toLowerCase() ?? "";
|
|
106
|
+
const lang = ext === "tsx" ? "tsx" : ext === "ts" ? "ts" : ext === "js" ? "js" : ext === "py" ? "py" : ext;
|
|
99
107
|
if (HIGHLIGHT_LANGS.has(lang)) {
|
|
100
108
|
renderHighlightedCode(grid, r, col + 2, d.line.slice(0, maxCol - 2), lang);
|
|
101
109
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cell-level differ — compares two CellGrids and produces minimal ANSI output.
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
4
|
+
import type { CellGrid, Style } from "./cells.js";
|
|
5
5
|
/** Convert a Style to an SGR escape sequence */
|
|
6
6
|
export declare function styleToSGR(style: Style): string;
|
|
7
7
|
/**
|
package/dist/renderer/differ.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cell-level differ — compares two CellGrids and produces minimal ANSI output.
|
|
3
3
|
*/
|
|
4
|
-
import { cellsEqual } from
|
|
5
|
-
import {
|
|
4
|
+
import { cellsEqual } from "./cells.js";
|
|
5
|
+
import { BG_CODES, FG_CODES } from "./colors.js";
|
|
6
6
|
/** Convert a Style to an SGR escape sequence */
|
|
7
7
|
export function styleToSGR(style) {
|
|
8
8
|
const codes = [0]; // reset first
|
|
@@ -16,7 +16,7 @@ export function styleToSGR(style) {
|
|
|
16
16
|
codes.push(FG_CODES[style.fg]);
|
|
17
17
|
if (style.bg && BG_CODES[style.bg])
|
|
18
18
|
codes.push(BG_CODES[style.bg]);
|
|
19
|
-
return `\x1b[${codes.join(
|
|
19
|
+
return `\x1b[${codes.join(";")}m`;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
22
|
* Compare two grids and return the ANSI string that transforms prev into next.
|
|
@@ -50,9 +50,9 @@ export function diff(prev, next, rowOffset = 0) {
|
|
|
50
50
|
}
|
|
51
51
|
// Reset style at end
|
|
52
52
|
if (parts.length > 0) {
|
|
53
|
-
parts.push(
|
|
53
|
+
parts.push("\x1b[0m");
|
|
54
54
|
}
|
|
55
|
-
return parts.join(
|
|
55
|
+
return parts.join("");
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* Write ANSI output wrapped in DEC 2026 synchronized output markers.
|
|
@@ -61,19 +61,19 @@ export function diff(prev, next, rowOffset = 0) {
|
|
|
61
61
|
export function syncWrite(output) {
|
|
62
62
|
if (!output)
|
|
63
63
|
return;
|
|
64
|
-
process.stdout.write(
|
|
64
|
+
process.stdout.write(`\x1b[?2026h${output}\x1b[?2026l`);
|
|
65
65
|
}
|
|
66
66
|
/** Clear the entire screen */
|
|
67
67
|
export function clearScreen() {
|
|
68
|
-
process.stdout.write(
|
|
68
|
+
process.stdout.write("\x1b[2J\x1b[H");
|
|
69
69
|
}
|
|
70
70
|
/** Hide cursor */
|
|
71
71
|
export function hideCursor() {
|
|
72
|
-
process.stdout.write(
|
|
72
|
+
process.stdout.write("\x1b[?25l");
|
|
73
73
|
}
|
|
74
74
|
/** Show cursor */
|
|
75
75
|
export function showCursor() {
|
|
76
|
-
process.stdout.write(
|
|
76
|
+
process.stdout.write("\x1b[?25h");
|
|
77
77
|
}
|
|
78
78
|
/** Move cursor to position */
|
|
79
79
|
export function moveCursor(row, col) {
|
package/dist/renderer/image.js
CHANGED
|
@@ -8,35 +8,35 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Detection order: TERM_PROGRAM → TERM → fallback
|
|
10
10
|
*/
|
|
11
|
-
import { IMAGE_PREFIX } from
|
|
11
|
+
import { IMAGE_PREFIX } from "../tools/ImageReadTool/index.js";
|
|
12
12
|
function detectProtocol() {
|
|
13
|
-
const termProgram = process.env.TERM_PROGRAM?.toLowerCase() ??
|
|
14
|
-
const term = process.env.TERM?.toLowerCase() ??
|
|
15
|
-
if (termProgram.includes(
|
|
16
|
-
return
|
|
13
|
+
const termProgram = process.env.TERM_PROGRAM?.toLowerCase() ?? "";
|
|
14
|
+
const term = process.env.TERM?.toLowerCase() ?? "";
|
|
15
|
+
if (termProgram.includes("kitty") || termProgram.includes("ghostty") || termProgram.includes("wezterm")) {
|
|
16
|
+
return "kitty";
|
|
17
17
|
}
|
|
18
|
-
if (termProgram.includes(
|
|
19
|
-
return
|
|
18
|
+
if (termProgram.includes("iterm") || termProgram.includes("wezterm")) {
|
|
19
|
+
return "iterm";
|
|
20
20
|
}
|
|
21
|
-
if (term.includes(
|
|
22
|
-
return
|
|
21
|
+
if (term.includes("xterm-kitty")) {
|
|
22
|
+
return "kitty";
|
|
23
23
|
}
|
|
24
|
-
return
|
|
24
|
+
return "none";
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Check if a tool output contains an image result.
|
|
28
28
|
*/
|
|
29
29
|
export function isImageOutput(output) {
|
|
30
|
-
return output.startsWith(IMAGE_PREFIX
|
|
30
|
+
return output.startsWith(`${IMAGE_PREFIX}:`);
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
33
|
* Parse an image output string into its components.
|
|
34
34
|
*/
|
|
35
35
|
function parseImageOutput(output) {
|
|
36
|
-
if (!output.startsWith(IMAGE_PREFIX
|
|
36
|
+
if (!output.startsWith(`${IMAGE_PREFIX}:`))
|
|
37
37
|
return null;
|
|
38
38
|
const rest = output.slice(IMAGE_PREFIX.length + 1);
|
|
39
|
-
const colonIdx = rest.indexOf(
|
|
39
|
+
const colonIdx = rest.indexOf(":");
|
|
40
40
|
if (colonIdx < 0)
|
|
41
41
|
return null;
|
|
42
42
|
return {
|
|
@@ -52,23 +52,23 @@ function parseImageOutput(output) {
|
|
|
52
52
|
export function renderImageInline(output, maxWidth = 60, maxHeight = 15) {
|
|
53
53
|
const parsed = parseImageOutput(output);
|
|
54
54
|
if (!parsed)
|
|
55
|
-
return
|
|
55
|
+
return "[image: parse error]";
|
|
56
56
|
const protocol = detectProtocol();
|
|
57
|
-
if (protocol ===
|
|
57
|
+
if (protocol === "kitty") {
|
|
58
58
|
return renderKitty(parsed.base64, parsed.mediaType, maxWidth, maxHeight);
|
|
59
59
|
}
|
|
60
|
-
if (protocol ===
|
|
60
|
+
if (protocol === "iterm") {
|
|
61
61
|
return renderIterm(parsed.base64, maxWidth, maxHeight);
|
|
62
62
|
}
|
|
63
63
|
// Fallback: show info
|
|
64
|
-
const sizeKB = Math.round(parsed.base64.length * 3 / 4 / 1024);
|
|
64
|
+
const sizeKB = Math.round((parsed.base64.length * 3) / 4 / 1024);
|
|
65
65
|
return `[image: ${parsed.mediaType}, ${sizeKB}KB]`;
|
|
66
66
|
}
|
|
67
67
|
/**
|
|
68
68
|
* Kitty graphics protocol.
|
|
69
69
|
* Sends base64-encoded image data via escape sequences.
|
|
70
70
|
*/
|
|
71
|
-
function renderKitty(base64,
|
|
71
|
+
function renderKitty(base64, _mediaType, maxCols, maxRows) {
|
|
72
72
|
// Kitty protocol: ESC_P ... ESC\
|
|
73
73
|
// a=T (transmit), f=100 (PNG), t=d (direct), c=cols, r=rows
|
|
74
74
|
const chunks = [];
|
|
@@ -85,7 +85,7 @@ function renderKitty(base64, mediaType, maxCols, maxRows) {
|
|
|
85
85
|
chunks.push(`\x1b_Gm=${more};${chunk}\x1b\\`);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
return chunks.join(
|
|
88
|
+
return chunks.join("");
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
91
|
* iTerm2 inline image protocol.
|
package/dist/renderer/index.d.ts
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* Flushed messages flow to scrollback; live area is rewritten in-place
|
|
4
4
|
* right after the scrollback content each frame (no absolute positioning gap).
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import { type KeyEvent } from
|
|
8
|
-
import type
|
|
9
|
-
export type { KeyEvent } from
|
|
10
|
-
export type { LayoutState, ToolCallInfo } from
|
|
6
|
+
import type { Message } from "../types/message.js";
|
|
7
|
+
import { type KeyEvent } from "./input.js";
|
|
8
|
+
import { type ToolCallInfo } from "./layout.js";
|
|
9
|
+
export type { KeyEvent } from "./input.js";
|
|
10
|
+
export type { LayoutState, ToolCallInfo } from "./layout.js";
|
|
11
11
|
export declare class TerminalRenderer {
|
|
12
12
|
private current;
|
|
13
13
|
private state;
|
|
@@ -51,7 +51,7 @@ export declare class TerminalRenderer {
|
|
|
51
51
|
text: string;
|
|
52
52
|
critical: boolean;
|
|
53
53
|
} | null): void;
|
|
54
|
-
setVimMode(mode:
|
|
54
|
+
setVimMode(mode: "normal" | "insert" | null): void;
|
|
55
55
|
setThinkingStartedAt(time: number | null): void;
|
|
56
56
|
getThinkingStartedAt(): number | null;
|
|
57
57
|
setLastThinkingSummary(summary: string | null): void;
|