zerg-ztc 0.1.10 → 0.1.12
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/bin/.gitkeep +0 -0
- package/bin/ztc-audio-darwin-arm64 +0 -0
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +63 -2
- package/dist/App.js.map +1 -1
- package/dist/agent/commands/dictation.d.ts +3 -0
- package/dist/agent/commands/dictation.d.ts.map +1 -0
- package/dist/agent/commands/dictation.js +10 -0
- package/dist/agent/commands/dictation.js.map +1 -0
- package/dist/agent/commands/index.d.ts.map +1 -1
- package/dist/agent/commands/index.js +2 -1
- package/dist/agent/commands/index.js.map +1 -1
- package/dist/agent/commands/types.d.ts +7 -0
- package/dist/agent/commands/types.d.ts.map +1 -1
- package/dist/components/InputArea.d.ts +1 -0
- package/dist/components/InputArea.d.ts.map +1 -1
- package/dist/components/InputArea.js +591 -43
- package/dist/components/InputArea.js.map +1 -1
- package/dist/components/SingleMessage.d.ts.map +1 -1
- package/dist/components/SingleMessage.js +157 -7
- package/dist/components/SingleMessage.js.map +1 -1
- package/dist/config/types.d.ts +6 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/ui/views/status_bar.js +2 -2
- package/dist/ui/views/status_bar.js.map +1 -1
- package/dist/utils/dictation.d.ts +46 -0
- package/dist/utils/dictation.d.ts.map +1 -0
- package/dist/utils/dictation.js +409 -0
- package/dist/utils/dictation.js.map +1 -0
- package/dist/utils/dictation_native.d.ts +51 -0
- package/dist/utils/dictation_native.d.ts.map +1 -0
- package/dist/utils/dictation_native.js +236 -0
- package/dist/utils/dictation_native.js.map +1 -0
- package/dist/utils/path_format.d.ts +20 -0
- package/dist/utils/path_format.d.ts.map +1 -0
- package/dist/utils/path_format.js +90 -0
- package/dist/utils/path_format.js.map +1 -0
- package/dist/utils/table.d.ts +38 -0
- package/dist/utils/table.d.ts.map +1 -0
- package/dist/utils/table.js +133 -0
- package/dist/utils/table.js.map +1 -0
- package/dist/utils/tool_trace.d.ts +7 -2
- package/dist/utils/tool_trace.d.ts.map +1 -1
- package/dist/utils/tool_trace.js +156 -51
- package/dist/utils/tool_trace.js.map +1 -1
- package/package.json +5 -1
- package/src/App.tsx +0 -813
- package/src/agent/agent.ts +0 -534
- package/src/agent/backends/anthropic.ts +0 -86
- package/src/agent/backends/gemini.ts +0 -119
- package/src/agent/backends/inception.ts +0 -23
- package/src/agent/backends/index.ts +0 -17
- package/src/agent/backends/openai.ts +0 -23
- package/src/agent/backends/openai_compatible.ts +0 -143
- package/src/agent/backends/types.ts +0 -83
- package/src/agent/commands/clipboard.ts +0 -77
- package/src/agent/commands/config.ts +0 -204
- package/src/agent/commands/debug.ts +0 -23
- package/src/agent/commands/emulation.ts +0 -80
- package/src/agent/commands/execution.ts +0 -9
- package/src/agent/commands/help.ts +0 -20
- package/src/agent/commands/history.ts +0 -13
- package/src/agent/commands/index.ts +0 -46
- package/src/agent/commands/input_mode.ts +0 -22
- package/src/agent/commands/keybindings.ts +0 -40
- package/src/agent/commands/model.ts +0 -11
- package/src/agent/commands/models.ts +0 -116
- package/src/agent/commands/permissions.ts +0 -64
- package/src/agent/commands/retry.ts +0 -9
- package/src/agent/commands/shell.ts +0 -68
- package/src/agent/commands/skills.ts +0 -54
- package/src/agent/commands/status.ts +0 -19
- package/src/agent/commands/types.ts +0 -80
- package/src/agent/commands/update.ts +0 -32
- package/src/agent/factory.ts +0 -60
- package/src/agent/index.ts +0 -20
- package/src/agent/runtime/capabilities.ts +0 -7
- package/src/agent/runtime/memory.ts +0 -23
- package/src/agent/runtime/policy.ts +0 -48
- package/src/agent/runtime/session.ts +0 -18
- package/src/agent/runtime/tracing.ts +0 -23
- package/src/agent/tools/file.ts +0 -178
- package/src/agent/tools/index.ts +0 -52
- package/src/agent/tools/screenshot.ts +0 -821
- package/src/agent/tools/search.ts +0 -138
- package/src/agent/tools/shell.ts +0 -69
- package/src/agent/tools/skills.ts +0 -28
- package/src/agent/tools/types.ts +0 -14
- package/src/agent/tools/zerg.ts +0 -50
- package/src/cli.tsx +0 -163
- package/src/components/ActivityLine.tsx +0 -23
- package/src/components/FullScreen.tsx +0 -79
- package/src/components/Header.tsx +0 -27
- package/src/components/InputArea.tsx +0 -1096
- package/src/components/MessageList.tsx +0 -71
- package/src/components/SingleMessage.tsx +0 -59
- package/src/components/StatusBar.tsx +0 -55
- package/src/components/index.tsx +0 -8
- package/src/config/types.ts +0 -12
- package/src/config.ts +0 -186
- package/src/debug/logger.ts +0 -14
- package/src/emulation/README.md +0 -24
- package/src/emulation/catalog.ts +0 -82
- package/src/emulation/trace_style.ts +0 -8
- package/src/emulation/types.ts +0 -7
- package/src/skills/index.ts +0 -36
- package/src/skills/loader.ts +0 -135
- package/src/skills/registry.ts +0 -6
- package/src/skills/types.ts +0 -10
- package/src/types.ts +0 -84
- package/src/ui/README.md +0 -44
- package/src/ui/core/factory.ts +0 -9
- package/src/ui/core/index.ts +0 -4
- package/src/ui/core/input.ts +0 -38
- package/src/ui/core/input_segments.ts +0 -410
- package/src/ui/core/input_state.ts +0 -17
- package/src/ui/core/layout_yoga.ts +0 -122
- package/src/ui/core/style.ts +0 -38
- package/src/ui/core/types.ts +0 -54
- package/src/ui/ink/index.tsx +0 -1
- package/src/ui/ink/render.tsx +0 -60
- package/src/ui/views/activity_line.ts +0 -33
- package/src/ui/views/app.ts +0 -111
- package/src/ui/views/header.ts +0 -44
- package/src/ui/views/input_area.ts +0 -255
- package/src/ui/views/message_list.ts +0 -443
- package/src/ui/views/status_bar.ts +0 -114
- package/src/ui/vue/index.ts +0 -53
- package/src/ui/web/frame_render.tsx +0 -148
- package/src/ui/web/index.tsx +0 -1
- package/src/ui/web/render.tsx +0 -41
- package/src/utils/clipboard.ts +0 -39
- package/src/utils/clipboard_image.ts +0 -40
- package/src/utils/diff.ts +0 -52
- package/src/utils/image_preview.ts +0 -36
- package/src/utils/models.ts +0 -98
- package/src/utils/path_complete.ts +0 -173
- package/src/utils/shell.ts +0 -72
- package/src/utils/spinner_frames.ts +0 -1
- package/src/utils/spinner_verbs.ts +0 -23
- package/src/utils/tool_summary.ts +0 -56
- package/src/utils/tool_trace.ts +0 -216
- package/src/utils/update.ts +0 -44
- package/src/utils/version.ts +0 -15
- package/src/web/index.html +0 -352
- package/src/web/mirror-favicon.svg +0 -4
- package/src/web/mirror.html +0 -641
- package/src/web/mirror_hook.ts +0 -25
- package/src/web/mirror_server.ts +0 -204
- package/tsconfig.json +0 -22
- package/vite.config.ts +0 -363
package/src/utils/shell.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { exec, ExecException } from 'child_process';
|
|
2
|
-
import { promisify } from 'util';
|
|
3
|
-
import { resolve } from 'path';
|
|
4
|
-
import { stat } from 'fs/promises';
|
|
5
|
-
|
|
6
|
-
import type { ShellResult } from '../agent/commands/types.js';
|
|
7
|
-
|
|
8
|
-
const execAsync = promisify(exec);
|
|
9
|
-
|
|
10
|
-
const MAX_BUFFER = 1024 * 1024;
|
|
11
|
-
const MAX_OUTPUT = 10000;
|
|
12
|
-
const DEFAULT_TIMEOUT_MS = 30000;
|
|
13
|
-
const DANGEROUS = ['rm -rf /', 'mkfs', ':(){:|:&};:'];
|
|
14
|
-
|
|
15
|
-
export async function runShellCommand(command: string, cwd: string): Promise<ShellResult> {
|
|
16
|
-
if (DANGEROUS.some(entry => command.includes(entry))) {
|
|
17
|
-
throw new Error('Command rejected for safety reasons');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const resolvedCwd = resolve(cwd);
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
const { stdout, stderr } = await execAsync(command, {
|
|
24
|
-
cwd: resolvedCwd,
|
|
25
|
-
timeout: DEFAULT_TIMEOUT_MS,
|
|
26
|
-
maxBuffer: MAX_BUFFER
|
|
27
|
-
});
|
|
28
|
-
const clippedStdout = stdout.slice(0, MAX_OUTPUT);
|
|
29
|
-
const clippedStderr = stderr.slice(0, MAX_OUTPUT);
|
|
30
|
-
return {
|
|
31
|
-
command,
|
|
32
|
-
cwd: resolvedCwd,
|
|
33
|
-
stdout: clippedStdout,
|
|
34
|
-
stderr: clippedStderr,
|
|
35
|
-
exitCode: 0,
|
|
36
|
-
truncated: stdout.length > MAX_OUTPUT || stderr.length > MAX_OUTPUT
|
|
37
|
-
};
|
|
38
|
-
} catch (err) {
|
|
39
|
-
const error = err as ExecException & { stdout?: string; stderr?: string; code?: number };
|
|
40
|
-
const stdout = String(error.stdout || '');
|
|
41
|
-
const stderr = String(error.stderr || error.message || '');
|
|
42
|
-
const clippedStdout = stdout.slice(0, MAX_OUTPUT);
|
|
43
|
-
const clippedStderr = stderr.slice(0, MAX_OUTPUT);
|
|
44
|
-
return {
|
|
45
|
-
command,
|
|
46
|
-
cwd: resolvedCwd,
|
|
47
|
-
stdout: clippedStdout,
|
|
48
|
-
stderr: clippedStderr,
|
|
49
|
-
exitCode: typeof error.code === 'number' ? error.code : 1,
|
|
50
|
-
truncated: stdout.length > MAX_OUTPUT || stderr.length > MAX_OUTPUT
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export async function resolveWorkingDir(current: string, target?: string): Promise<string> {
|
|
56
|
-
const base = current || process.cwd();
|
|
57
|
-
let path = target?.trim() || '';
|
|
58
|
-
|
|
59
|
-
// Expand tilde to home directory
|
|
60
|
-
if (path.startsWith('~/')) {
|
|
61
|
-
path = resolve(process.env.HOME || '', path.slice(2));
|
|
62
|
-
} else if (path === '~') {
|
|
63
|
-
path = process.env.HOME || '';
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const next = path.length > 0 ? resolve(base, path) : base;
|
|
67
|
-
const info = await stat(next);
|
|
68
|
-
if (!info.isDirectory()) {
|
|
69
|
-
throw new Error('Not a directory');
|
|
70
|
-
}
|
|
71
|
-
return next;
|
|
72
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const SPINNER_FRAMES = ['-', '\\', '|', '/'];
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_SPINNER_VERBS = [
|
|
2
|
-
'Thinking',
|
|
3
|
-
'Reticulating splines',
|
|
4
|
-
'Allocating time slices',
|
|
5
|
-
'Negotiating with entropy',
|
|
6
|
-
'Consulting the archives',
|
|
7
|
-
'Organizing thoughts',
|
|
8
|
-
'Compiling context',
|
|
9
|
-
'Assembling response',
|
|
10
|
-
'Tracing dependencies',
|
|
11
|
-
'Resolving intent'
|
|
12
|
-
];
|
|
13
|
-
|
|
14
|
-
export function parseSpinnerVerbs(input: string): string[] {
|
|
15
|
-
return input
|
|
16
|
-
.split(/[,|;\n]+/g)
|
|
17
|
-
.map(part => part.trim())
|
|
18
|
-
.filter(Boolean);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function formatSpinnerVerbs(verbs: string[]): string {
|
|
22
|
-
return verbs.length === 0 ? '(none)' : verbs.join(', ');
|
|
23
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
type ParsedResult = Record<string, unknown>;
|
|
2
|
-
|
|
3
|
-
function parseResult(raw: string): ParsedResult | null {
|
|
4
|
-
try {
|
|
5
|
-
const data = JSON.parse(raw) as ParsedResult;
|
|
6
|
-
if (data && typeof data === 'object') return data;
|
|
7
|
-
} catch {
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
10
|
-
return null;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function summarizeToolResult(tool: string, raw: string): string {
|
|
14
|
-
const parsed = parseResult(raw);
|
|
15
|
-
if (!parsed) {
|
|
16
|
-
const trimmed = raw.trim();
|
|
17
|
-
return trimmed.length > 140 ? `${trimmed.slice(0, 140)}...` : trimmed || 'Done';
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (tool === 'read_file') {
|
|
21
|
-
const path = String(parsed.path || '');
|
|
22
|
-
const size = parsed.size ? ` (${parsed.size} bytes)` : '';
|
|
23
|
-
return `Read ${path}${size}`;
|
|
24
|
-
}
|
|
25
|
-
if (tool === 'write_file') {
|
|
26
|
-
const path = String(parsed.path || '');
|
|
27
|
-
const action = String(parsed.action || 'written');
|
|
28
|
-
return `Wrote ${path} (${action})`;
|
|
29
|
-
}
|
|
30
|
-
if (tool === 'list_directory') {
|
|
31
|
-
const path = String(parsed.path || '');
|
|
32
|
-
const entries = Array.isArray(parsed.entries) ? parsed.entries.length : 0;
|
|
33
|
-
return `Listed ${path} (${entries} items)`;
|
|
34
|
-
}
|
|
35
|
-
if (tool === 'run_command') {
|
|
36
|
-
const cwd = String(parsed.cwd || '');
|
|
37
|
-
const cmd = String(parsed.command || '');
|
|
38
|
-
return `Ran ${cmd}${cwd ? ` (cwd ${cwd})` : ''}`;
|
|
39
|
-
}
|
|
40
|
-
if (tool === 'search') {
|
|
41
|
-
const count = parsed.count ? String(parsed.count) : '0';
|
|
42
|
-
const path = String(parsed.path || '');
|
|
43
|
-
return `Found ${count} matches${path ? ` in ${path}` : ''}`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const fallback = raw.trim();
|
|
47
|
-
return fallback.length > 140 ? `${fallback.slice(0, 140)}...` : fallback || 'Done';
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function summarizeToolArgs(args: Record<string, unknown>): string {
|
|
51
|
-
const entries = Object.entries(args)
|
|
52
|
-
.map(([key, value]) => `${key}=${String(value)}`)
|
|
53
|
-
.slice(0, 3);
|
|
54
|
-
if (entries.length === 0) return '';
|
|
55
|
-
return `(${entries.join(', ')}${Object.keys(args).length > 3 ? ', ...' : ''})`;
|
|
56
|
-
}
|
package/src/utils/tool_trace.ts
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import { getTraceStyle, TraceStyle } from '../emulation/trace_style.js';
|
|
2
|
-
|
|
3
|
-
const toolLabels: Record<string, string> = {
|
|
4
|
-
run_command: 'Bash',
|
|
5
|
-
read_file: 'Read',
|
|
6
|
-
write_file: 'Update',
|
|
7
|
-
list_directory: 'List',
|
|
8
|
-
search: 'Search'
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
function formatValue(value: unknown): string {
|
|
12
|
-
if (typeof value === 'string') {
|
|
13
|
-
const escaped = value.replace(/\n/g, '\\n');
|
|
14
|
-
return `"${escaped}"`;
|
|
15
|
-
}
|
|
16
|
-
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
17
|
-
return String(value);
|
|
18
|
-
}
|
|
19
|
-
return JSON.stringify(value);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function formatArgs(tool: string, args: Record<string, unknown>): string {
|
|
23
|
-
if (tool === 'run_command') {
|
|
24
|
-
const command = args.command ? String(args.command) : '';
|
|
25
|
-
const cwd = args.cwd ? `, cwd: ${formatValue(args.cwd)}` : '';
|
|
26
|
-
const timeout = args.timeout ? `, timeout: ${formatValue(args.timeout)}` : '';
|
|
27
|
-
return `(${command}${cwd}${timeout})`;
|
|
28
|
-
}
|
|
29
|
-
if (tool === 'search') {
|
|
30
|
-
const pattern = args.pattern ? `pattern: ${formatValue(args.pattern)}` : '';
|
|
31
|
-
const path = args.path ? `path: ${formatValue(args.path)}` : '';
|
|
32
|
-
const output = args.output_mode ? `output_mode: ${formatValue(args.output_mode)}` : '';
|
|
33
|
-
const parts = [pattern, path, output].filter(Boolean);
|
|
34
|
-
return parts.length ? `(${parts.join(', ')})` : '';
|
|
35
|
-
}
|
|
36
|
-
if (tool === 'read_file' || tool === 'write_file' || tool === 'list_directory') {
|
|
37
|
-
const path = args.path ? formatValue(args.path) : '""';
|
|
38
|
-
return `(${path})`;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const entries = Object.entries(args).map(([key, value]) => `${key}: ${formatValue(value)}`);
|
|
42
|
-
return entries.length ? `(${entries.join(', ')})` : '';
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function parseResult(raw: string): Record<string, unknown> | null {
|
|
46
|
-
try {
|
|
47
|
-
const data = JSON.parse(raw) as Record<string, unknown>;
|
|
48
|
-
if (data && typeof data === 'object') return data;
|
|
49
|
-
} catch {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function formatOutcome(tool: string, result: string, durationMs?: number): string {
|
|
56
|
-
const parsed = parseResult(result);
|
|
57
|
-
const duration = typeof durationMs === 'number' ? ` in ${(durationMs / 1000).toFixed(1)}s` : '';
|
|
58
|
-
|
|
59
|
-
if (parsed && tool === 'search') {
|
|
60
|
-
const count = typeof parsed.count === 'number' ? parsed.count : 0;
|
|
61
|
-
const label = count === 1 ? 'match' : 'matches';
|
|
62
|
-
return `Found ${count} ${label}${duration}`;
|
|
63
|
-
}
|
|
64
|
-
if (parsed && tool === 'run_command') {
|
|
65
|
-
const stdout = String(parsed.stdout || '');
|
|
66
|
-
const stderr = String(parsed.stderr || '');
|
|
67
|
-
const lines = (stdout || stderr).trim().split('\n').filter(Boolean).length;
|
|
68
|
-
const label = lines === 1 ? 'line' : 'lines';
|
|
69
|
-
return lines > 0 ? `Output ${lines} ${label}${duration}` : `Command finished${duration}`;
|
|
70
|
-
}
|
|
71
|
-
if (parsed && tool === 'read_file') {
|
|
72
|
-
const path = String(parsed.path || '');
|
|
73
|
-
const size = parsed.size ? `${parsed.size} bytes` : 'unknown size';
|
|
74
|
-
const truncated = parsed.truncated ? ' (truncated)' : '';
|
|
75
|
-
return `Read ${path} (${size})${duration}${truncated}`;
|
|
76
|
-
}
|
|
77
|
-
if (parsed && tool === 'write_file') {
|
|
78
|
-
const path = String(parsed.path || '');
|
|
79
|
-
const action = String(parsed.action || 'written');
|
|
80
|
-
return `Updated ${path} (${action})${duration}`;
|
|
81
|
-
}
|
|
82
|
-
if (parsed && tool === 'list_directory') {
|
|
83
|
-
const path = String(parsed.path || '');
|
|
84
|
-
const entries = Array.isArray(parsed.entries) ? parsed.entries.length : 0;
|
|
85
|
-
return `Listed ${path} (${entries} items)${duration}`;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return `Done${duration}`;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function buildOutputLines(tool: string, result: string): { lines: string[]; truncated: boolean } {
|
|
92
|
-
const parsed = parseResult(result);
|
|
93
|
-
if (!parsed) {
|
|
94
|
-
return { lines: [], truncated: false };
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (tool === 'run_command') {
|
|
98
|
-
const stdout = String(parsed.stdout || '');
|
|
99
|
-
const stderr = String(parsed.stderr || '');
|
|
100
|
-
const combined = [stdout, stderr].filter(Boolean).join('\n');
|
|
101
|
-
const lines = combined.split('\n').filter(Boolean);
|
|
102
|
-
return { lines, truncated: Boolean(parsed.truncated) };
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (tool === 'search') {
|
|
106
|
-
const matches = Array.isArray(parsed.matches) ? parsed.matches : [];
|
|
107
|
-
const lines = matches.map((entry: unknown) => {
|
|
108
|
-
if (!entry || typeof entry !== 'object') return '';
|
|
109
|
-
const row = entry as Record<string, unknown>;
|
|
110
|
-
const file = String(row.path || '');
|
|
111
|
-
const line = row.line ? `:${row.line}` : '';
|
|
112
|
-
const text = String(row.text || '');
|
|
113
|
-
return `${file}${line} ${text}`.trim();
|
|
114
|
-
}).filter(Boolean);
|
|
115
|
-
return { lines, truncated: Boolean(parsed.truncated) };
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (tool === 'read_file') {
|
|
119
|
-
const content = String(parsed.content || '');
|
|
120
|
-
const lines = content.split('\n');
|
|
121
|
-
return { lines, truncated: Boolean(parsed.truncated) };
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (tool === 'write_file') {
|
|
125
|
-
const diff = typeof parsed.diff === 'string' ? parsed.diff : '';
|
|
126
|
-
const lines = diff ? diff.split('\n') : [];
|
|
127
|
-
return { lines, truncated: Boolean(parsed.truncated) };
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return { lines: [], truncated: false };
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export function formatToolStart(tool: string, args: Record<string, unknown>, emulationId?: string): string {
|
|
134
|
-
const style = getTraceStyle(emulationId);
|
|
135
|
-
const label = toolLabels[tool] || tool;
|
|
136
|
-
const argsText = formatArgs(tool, args);
|
|
137
|
-
if (style === 'claude_code') {
|
|
138
|
-
return `⏺ ${label}${argsText}`;
|
|
139
|
-
}
|
|
140
|
-
if (style === 'codex') {
|
|
141
|
-
if (tool === 'run_command') {
|
|
142
|
-
const command = args.command ? String(args.command) : '';
|
|
143
|
-
return `! ${command}`;
|
|
144
|
-
}
|
|
145
|
-
return `⏺ ${label}${argsText}`;
|
|
146
|
-
}
|
|
147
|
-
return `> ${label}${argsText}`;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export function formatToolEnd(tool: string, result: string, durationMs?: number, emulationId?: string): string {
|
|
151
|
-
const style = getTraceStyle(emulationId);
|
|
152
|
-
const summary = formatOutcome(tool, result, durationMs);
|
|
153
|
-
if (style === 'claude_code') {
|
|
154
|
-
return `⎿ ${summary}`;
|
|
155
|
-
}
|
|
156
|
-
if (style === 'codex') {
|
|
157
|
-
if (tool === 'run_command') {
|
|
158
|
-
const { lines } = buildOutputLines(tool, result);
|
|
159
|
-
if (lines.length === 0) {
|
|
160
|
-
return ` ⎿ (No content)`;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return ` ⎿ ${summary}`;
|
|
164
|
-
}
|
|
165
|
-
return `< ${summary}`;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export function formatToolError(tool: string, error: string, emulationId?: string): string {
|
|
169
|
-
const style = getTraceStyle(emulationId);
|
|
170
|
-
if (style === 'claude_code') {
|
|
171
|
-
return `⎿ ${tool} failed: ${error}`;
|
|
172
|
-
}
|
|
173
|
-
if (style === 'codex') {
|
|
174
|
-
return ` ${tool} failed: ${error}`;
|
|
175
|
-
}
|
|
176
|
-
return `< ${tool} failed: ${error}`;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export function buildToolOutputMessage(
|
|
180
|
-
tool: string,
|
|
181
|
-
result: string,
|
|
182
|
-
durationMs?: number,
|
|
183
|
-
emulationId?: string
|
|
184
|
-
): { preview: string; full: string; truncated: boolean } {
|
|
185
|
-
const { lines, truncated } = buildOutputLines(tool, result);
|
|
186
|
-
if (lines.length === 0) {
|
|
187
|
-
const summary = formatToolEnd(tool, result, durationMs, emulationId);
|
|
188
|
-
return { preview: summary, full: summary, truncated: false };
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const maxLines = 8;
|
|
192
|
-
const previewLines = lines.slice(0, maxLines);
|
|
193
|
-
const remaining = lines.length - previewLines.length;
|
|
194
|
-
const expandHint = truncated || remaining > 0 ? ' (ctrl+o to expand)' : '';
|
|
195
|
-
|
|
196
|
-
const summary = formatToolEnd(tool, result, durationMs, emulationId);
|
|
197
|
-
const previewBlock = [
|
|
198
|
-
summary,
|
|
199
|
-
...previewLines.map(line => ` ${line}`)
|
|
200
|
-
];
|
|
201
|
-
if (expandHint) {
|
|
202
|
-
const extraLabel = remaining > 0 ? `… +${remaining} lines` : '…';
|
|
203
|
-
previewBlock.push(` ${extraLabel}${expandHint}`);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const fullBlock = [
|
|
207
|
-
summary,
|
|
208
|
-
...lines.map(line => ` ${line}`)
|
|
209
|
-
];
|
|
210
|
-
|
|
211
|
-
return {
|
|
212
|
-
preview: previewBlock.join('\n'),
|
|
213
|
-
full: fullBlock.join('\n'),
|
|
214
|
-
truncated: Boolean(expandHint)
|
|
215
|
-
};
|
|
216
|
-
}
|
package/src/utils/update.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
const PACKAGE_NAME = 'zerg-ztc';
|
|
2
|
-
|
|
3
|
-
export interface UpdateCheck {
|
|
4
|
-
current: string;
|
|
5
|
-
latest: string;
|
|
6
|
-
hasUpdate: boolean;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function parseVersion(value: string): number[] {
|
|
10
|
-
return value.split('.').map(part => Number(part.replace(/[^0-9]/g, '')) || 0);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function compareVersions(a: string, b: string): number {
|
|
14
|
-
const pa = parseVersion(a);
|
|
15
|
-
const pb = parseVersion(b);
|
|
16
|
-
const len = Math.max(pa.length, pb.length);
|
|
17
|
-
for (let i = 0; i < len; i += 1) {
|
|
18
|
-
const av = pa[i] ?? 0;
|
|
19
|
-
const bv = pb[i] ?? 0;
|
|
20
|
-
if (av > bv) return 1;
|
|
21
|
-
if (av < bv) return -1;
|
|
22
|
-
}
|
|
23
|
-
return 0;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export async function fetchLatestVersion(): Promise<string> {
|
|
27
|
-
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
|
|
28
|
-
headers: { 'Accept': 'application/json' }
|
|
29
|
-
});
|
|
30
|
-
if (!res.ok) {
|
|
31
|
-
throw new Error(`Version check failed (${res.status})`);
|
|
32
|
-
}
|
|
33
|
-
const data = await res.json() as { version?: string };
|
|
34
|
-
return data.version || '0.0.0';
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function checkForUpdate(current: string): Promise<UpdateCheck> {
|
|
38
|
-
const latest = await fetchLatestVersion();
|
|
39
|
-
return {
|
|
40
|
-
current,
|
|
41
|
-
latest,
|
|
42
|
-
hasUpdate: compareVersions(latest, current) > 0
|
|
43
|
-
};
|
|
44
|
-
}
|
package/src/utils/version.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'fs';
|
|
2
|
-
import { dirname, resolve } from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
|
|
5
|
-
export function getVersion(): string {
|
|
6
|
-
try {
|
|
7
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
const pkgPath = resolve(here, '../../package.json');
|
|
9
|
-
const raw = readFileSync(pkgPath, 'utf-8');
|
|
10
|
-
const parsed = JSON.parse(raw) as { version?: string };
|
|
11
|
-
return parsed.version || '0.0.0';
|
|
12
|
-
} catch {
|
|
13
|
-
return '0.0.0';
|
|
14
|
-
}
|
|
15
|
-
}
|