zerg-ztc 0.1.10 → 0.1.11

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.
Files changed (64) hide show
  1. package/dist/App.d.ts.map +1 -1
  2. package/dist/App.js +63 -2
  3. package/dist/App.js.map +1 -1
  4. package/dist/agent/commands/dictation.d.ts +3 -0
  5. package/dist/agent/commands/dictation.d.ts.map +1 -0
  6. package/dist/agent/commands/dictation.js +10 -0
  7. package/dist/agent/commands/dictation.js.map +1 -0
  8. package/dist/agent/commands/index.d.ts.map +1 -1
  9. package/dist/agent/commands/index.js +2 -1
  10. package/dist/agent/commands/index.js.map +1 -1
  11. package/dist/agent/commands/types.d.ts +7 -0
  12. package/dist/agent/commands/types.d.ts.map +1 -1
  13. package/dist/components/InputArea.d.ts +1 -0
  14. package/dist/components/InputArea.d.ts.map +1 -1
  15. package/dist/components/InputArea.js +591 -43
  16. package/dist/components/InputArea.js.map +1 -1
  17. package/dist/components/SingleMessage.d.ts.map +1 -1
  18. package/dist/components/SingleMessage.js +157 -7
  19. package/dist/components/SingleMessage.js.map +1 -1
  20. package/dist/config/types.d.ts +6 -0
  21. package/dist/config/types.d.ts.map +1 -1
  22. package/dist/ui/views/status_bar.js +2 -2
  23. package/dist/ui/views/status_bar.js.map +1 -1
  24. package/dist/utils/dictation.d.ts +46 -0
  25. package/dist/utils/dictation.d.ts.map +1 -0
  26. package/dist/utils/dictation.js +409 -0
  27. package/dist/utils/dictation.js.map +1 -0
  28. package/dist/utils/dictation_native.d.ts +51 -0
  29. package/dist/utils/dictation_native.d.ts.map +1 -0
  30. package/dist/utils/dictation_native.js +216 -0
  31. package/dist/utils/dictation_native.js.map +1 -0
  32. package/dist/utils/path_format.d.ts +20 -0
  33. package/dist/utils/path_format.d.ts.map +1 -0
  34. package/dist/utils/path_format.js +90 -0
  35. package/dist/utils/path_format.js.map +1 -0
  36. package/dist/utils/table.d.ts +38 -0
  37. package/dist/utils/table.d.ts.map +1 -0
  38. package/dist/utils/table.js +133 -0
  39. package/dist/utils/table.js.map +1 -0
  40. package/dist/utils/tool_trace.d.ts +7 -2
  41. package/dist/utils/tool_trace.d.ts.map +1 -1
  42. package/dist/utils/tool_trace.js +156 -51
  43. package/dist/utils/tool_trace.js.map +1 -1
  44. package/package.json +4 -1
  45. package/packages/ztc-dictation/Cargo.toml +43 -0
  46. package/packages/ztc-dictation/README.md +65 -0
  47. package/packages/ztc-dictation/bin/.gitkeep +0 -0
  48. package/packages/ztc-dictation/index.d.ts +16 -0
  49. package/packages/ztc-dictation/index.js +74 -0
  50. package/packages/ztc-dictation/package.json +41 -0
  51. package/packages/ztc-dictation/src/main.rs +430 -0
  52. package/src/App.tsx +98 -1
  53. package/src/agent/commands/dictation.ts +11 -0
  54. package/src/agent/commands/index.ts +2 -0
  55. package/src/agent/commands/types.ts +8 -0
  56. package/src/components/InputArea.tsx +606 -42
  57. package/src/components/SingleMessage.tsx +248 -9
  58. package/src/config/types.ts +7 -0
  59. package/src/ui/views/status_bar.ts +2 -2
  60. package/src/utils/dictation.ts +467 -0
  61. package/src/utils/dictation_native.ts +258 -0
  62. package/src/utils/path_format.ts +99 -0
  63. package/src/utils/table.ts +171 -0
  64. package/src/utils/tool_trace.ts +184 -54
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dictation_native.js","sourceRoot":"","sources":["../../src/utils/dictation_native.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Shorten a path for display:
3
+ * - Replace home directory with ~
4
+ * - Truncate middle of long paths
5
+ * - Show basename prominently
6
+ */
7
+ export declare function shortenPath(path: string, maxLength?: number): string;
8
+ /**
9
+ * Format a path for trace display - very compact
10
+ */
11
+ export declare function formatTracePath(path: string): string;
12
+ /**
13
+ * Format bytes in human readable form
14
+ */
15
+ export declare function formatBytes(bytes: number): string;
16
+ /**
17
+ * Format duration in human readable form
18
+ */
19
+ export declare function formatDuration(ms: number): string;
20
+ //# sourceMappingURL=path_format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path_format.d.ts","sourceRoot":"","sources":["../../src/utils/path_format.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAK,GAAG,MAAM,CAsChE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA0BpD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMjD"}
@@ -0,0 +1,90 @@
1
+ import { homedir } from 'os';
2
+ import { basename, dirname } from 'path';
3
+ /**
4
+ * Shorten a path for display:
5
+ * - Replace home directory with ~
6
+ * - Truncate middle of long paths
7
+ * - Show basename prominently
8
+ */
9
+ export function shortenPath(path, maxLength = 60) {
10
+ if (!path)
11
+ return '';
12
+ // Replace home directory with ~
13
+ const home = homedir();
14
+ let shortened = path;
15
+ if (path.startsWith(home)) {
16
+ shortened = '~' + path.slice(home.length);
17
+ }
18
+ // If short enough, return as-is
19
+ if (shortened.length <= maxLength) {
20
+ return shortened;
21
+ }
22
+ // Truncate middle, keeping start and end
23
+ const base = basename(shortened);
24
+ const dir = dirname(shortened);
25
+ // Always show at least the basename
26
+ if (base.length >= maxLength - 4) {
27
+ return '…' + base.slice(-(maxLength - 1));
28
+ }
29
+ // Show as much of the directory as we can
30
+ const availableForDir = maxLength - base.length - 2; // 2 for /…
31
+ if (availableForDir < 10) {
32
+ return '…/' + base;
33
+ }
34
+ // Split dir and keep start + end
35
+ const startLen = Math.floor(availableForDir * 0.4);
36
+ const endLen = availableForDir - startLen - 1; // 1 for …
37
+ const dirStart = dir.slice(0, startLen);
38
+ const dirEnd = dir.slice(-endLen);
39
+ return `${dirStart}…${dirEnd}/${base}`;
40
+ }
41
+ /**
42
+ * Format a path for trace display - very compact
43
+ */
44
+ export function formatTracePath(path) {
45
+ if (!path)
46
+ return '""';
47
+ const home = homedir();
48
+ let formatted = path;
49
+ // Replace home with ~
50
+ if (path.startsWith(home)) {
51
+ formatted = '~' + path.slice(home.length);
52
+ }
53
+ // For very long paths, just show basename with hint
54
+ if (formatted.length > 50) {
55
+ const base = basename(formatted);
56
+ const dir = dirname(formatted);
57
+ // Show abbreviated dir + full basename
58
+ if (dir.length > 30) {
59
+ const dirParts = dir.split('/').filter(Boolean);
60
+ if (dirParts.length > 3) {
61
+ const abbreviated = dirParts.slice(0, 2).join('/') + '/…/' + dirParts.slice(-1).join('/');
62
+ return abbreviated + '/' + base;
63
+ }
64
+ }
65
+ }
66
+ return formatted;
67
+ }
68
+ /**
69
+ * Format bytes in human readable form
70
+ */
71
+ export function formatBytes(bytes) {
72
+ if (bytes < 1024)
73
+ return `${bytes} bytes`;
74
+ if (bytes < 1024 * 1024)
75
+ return `${(bytes / 1024).toFixed(1)} KB`;
76
+ return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
77
+ }
78
+ /**
79
+ * Format duration in human readable form
80
+ */
81
+ export function formatDuration(ms) {
82
+ if (ms < 1000)
83
+ return `${ms}ms`;
84
+ if (ms < 60000)
85
+ return `${(ms / 1000).toFixed(1)}s`;
86
+ const mins = Math.floor(ms / 60000);
87
+ const secs = Math.round((ms % 60000) / 1000);
88
+ return `${mins}m${secs}s`;
89
+ }
90
+ //# sourceMappingURL=path_format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path_format.js","sourceRoot":"","sources":["../../src/utils/path_format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Box-drawing table utilities
3
+ * Uses Unicode box-drawing characters for clean terminal tables
4
+ */
5
+ export interface TableColumn {
6
+ header: string;
7
+ key: string;
8
+ width?: number;
9
+ align?: 'left' | 'right' | 'center';
10
+ }
11
+ export interface TableOptions {
12
+ rounded?: boolean;
13
+ headerSeparator?: boolean;
14
+ compact?: boolean;
15
+ }
16
+ /**
17
+ * Format data as a box-drawing table
18
+ */
19
+ export declare function formatTable(columns: TableColumn[], rows: Record<string, unknown>[], options?: TableOptions): string;
20
+ /**
21
+ * Simple two-column table (key-value style)
22
+ */
23
+ export declare function formatKeyValueTable(data: Array<{
24
+ label: string;
25
+ value: string;
26
+ }>, options?: TableOptions): string;
27
+ /**
28
+ * Format a schedule/calendar table
29
+ */
30
+ export declare function formatScheduleTable(events: Array<{
31
+ time: string;
32
+ event: string;
33
+ }>, options?: TableOptions): string;
34
+ /**
35
+ * Simple horizontal line/divider
36
+ */
37
+ export declare function formatDivider(width?: number, char?: string): string;
38
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/utils/table.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgCH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;CACrC;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA6BD;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,WAAW,EAAE,EACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,OAAO,GAAE,YAAiB,GACzB,MAAM,CAoDR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAC7C,OAAO,GAAE,YAAiB,GACzB,MAAM,CAOR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAC9C,OAAO,GAAE,YAAiB,GACzB,MAAM,CAMR;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,SAAK,EAAE,IAAI,SAAM,GAAG,MAAM,CAE5D"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Box-drawing table utilities
3
+ * Uses Unicode box-drawing characters for clean terminal tables
4
+ */
5
+ // Box-drawing characters
6
+ const BOX = {
7
+ topLeft: '┌',
8
+ topRight: '┐',
9
+ bottomLeft: '└',
10
+ bottomRight: '┘',
11
+ horizontal: '─',
12
+ vertical: '│',
13
+ leftT: '├',
14
+ rightT: '┤',
15
+ topT: '┬',
16
+ bottomT: '┴',
17
+ cross: '┼'
18
+ };
19
+ // Light box (for subtler tables)
20
+ const BOX_LIGHT = {
21
+ topLeft: '╭',
22
+ topRight: '╮',
23
+ bottomLeft: '╰',
24
+ bottomRight: '╯',
25
+ horizontal: '─',
26
+ vertical: '│',
27
+ leftT: '├',
28
+ rightT: '┤',
29
+ topT: '┬',
30
+ bottomT: '┴',
31
+ cross: '┼'
32
+ };
33
+ function padString(str, width, align = 'left') {
34
+ const visibleLength = str.replace(/\x1b\[[0-9;]*m/g, '').length;
35
+ const padding = Math.max(0, width - visibleLength);
36
+ if (align === 'right') {
37
+ return ' '.repeat(padding) + str;
38
+ }
39
+ if (align === 'center') {
40
+ const left = Math.floor(padding / 2);
41
+ const right = padding - left;
42
+ return ' '.repeat(left) + str + ' '.repeat(right);
43
+ }
44
+ return str + ' '.repeat(padding);
45
+ }
46
+ function getColumnWidths(columns, rows) {
47
+ return columns.map(col => {
48
+ const headerWidth = col.header.length;
49
+ const dataWidth = rows.reduce((max, row) => {
50
+ const value = String(row[col.key] || '');
51
+ const visibleLength = value.replace(/\x1b\[[0-9;]*m/g, '').length;
52
+ return Math.max(max, visibleLength);
53
+ }, 0);
54
+ return col.width || Math.max(headerWidth, dataWidth);
55
+ });
56
+ }
57
+ /**
58
+ * Format data as a box-drawing table
59
+ */
60
+ export function formatTable(columns, rows, options = {}) {
61
+ const { rounded = false, headerSeparator = true, compact = false } = options;
62
+ const box = rounded ? BOX_LIGHT : BOX;
63
+ const widths = getColumnWidths(columns, rows);
64
+ const lines = [];
65
+ // Top border
66
+ const topBorder = box.topLeft +
67
+ widths.map(w => box.horizontal.repeat(w + 2)).join(box.topT) +
68
+ box.topRight;
69
+ lines.push(topBorder);
70
+ // Header row
71
+ const headerRow = box.vertical +
72
+ columns.map((col, i) => ' ' + padString(col.header, widths[i], 'center') + ' ').join(box.vertical) +
73
+ box.vertical;
74
+ lines.push(headerRow);
75
+ // Header separator
76
+ if (headerSeparator) {
77
+ const separator = box.leftT +
78
+ widths.map(w => box.horizontal.repeat(w + 2)).join(box.cross) +
79
+ box.rightT;
80
+ lines.push(separator);
81
+ }
82
+ // Data rows
83
+ for (const row of rows) {
84
+ const dataRow = box.vertical +
85
+ columns.map((col, i) => {
86
+ const value = String(row[col.key] || '');
87
+ return ' ' + padString(value, widths[i], col.align) + ' ';
88
+ }).join(box.vertical) +
89
+ box.vertical;
90
+ lines.push(dataRow);
91
+ // Row separator (if not compact)
92
+ if (!compact && rows.indexOf(row) < rows.length - 1) {
93
+ const rowSep = box.leftT +
94
+ widths.map(w => box.horizontal.repeat(w + 2)).join(box.cross) +
95
+ box.rightT;
96
+ lines.push(rowSep);
97
+ }
98
+ }
99
+ // Bottom border
100
+ const bottomBorder = box.bottomLeft +
101
+ widths.map(w => box.horizontal.repeat(w + 2)).join(box.bottomT) +
102
+ box.bottomRight;
103
+ lines.push(bottomBorder);
104
+ return lines.join('\n');
105
+ }
106
+ /**
107
+ * Simple two-column table (key-value style)
108
+ */
109
+ export function formatKeyValueTable(data, options = {}) {
110
+ const columns = [
111
+ { header: 'Key', key: 'label', align: 'left' },
112
+ { header: 'Value', key: 'value', align: 'left' }
113
+ ];
114
+ const rows = data.map(d => ({ label: d.label, value: d.value }));
115
+ return formatTable(columns, rows, { ...options, headerSeparator: false });
116
+ }
117
+ /**
118
+ * Format a schedule/calendar table
119
+ */
120
+ export function formatScheduleTable(events, options = {}) {
121
+ const columns = [
122
+ { header: 'Time', key: 'time', align: 'left', width: 7 },
123
+ { header: 'Event', key: 'event', align: 'left' }
124
+ ];
125
+ return formatTable(columns, events, { rounded: true, compact: true, ...options });
126
+ }
127
+ /**
128
+ * Simple horizontal line/divider
129
+ */
130
+ export function formatDivider(width = 80, char = '─') {
131
+ return char.repeat(width);
132
+ }
133
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../../src/utils/table.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,14 @@
1
1
  export declare function formatToolStart(tool: string, args: Record<string, unknown>, emulationId?: string): string;
2
2
  export declare function formatToolEnd(tool: string, result: string, durationMs?: number, emulationId?: string): string;
3
3
  export declare function formatToolError(tool: string, error: string, emulationId?: string): string;
4
- export declare function buildToolOutputMessage(tool: string, result: string, durationMs?: number, emulationId?: string): {
4
+ export interface ToolOutputMessage {
5
5
  preview: string;
6
6
  full: string;
7
7
  truncated: boolean;
8
- };
8
+ diffLines?: Array<{
9
+ type: 'add' | 'remove' | 'context';
10
+ text: string;
11
+ }>;
12
+ }
13
+ export declare function buildToolOutputMessage(tool: string, result: string, durationMs?: number, emulationId?: string): ToolOutputMessage;
9
14
  //# sourceMappingURL=tool_trace.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool_trace.d.ts","sourceRoot":"","sources":["../../src/utils/tool_trace.ts"],"names":[],"mappings":"AAoIA,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAezG;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAgB7G;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CASzF;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GACnB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAgCvD"}
1
+ {"version":3,"file":"tool_trace.d.ts","sourceRoot":"","sources":["../../src/utils/tool_trace.ts"],"names":[],"mappings":"AAkOA,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAgBzG;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAiB7G;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAiBzF;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzE;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GACnB,iBAAiB,CAmDnB"}
@@ -1,41 +1,61 @@
1
1
  import { getTraceStyle } from '../emulation/trace_style.js';
2
+ import { formatTracePath, formatBytes, formatDuration } from './path_format.js';
2
3
  const toolLabels = {
3
4
  run_command: 'Bash',
4
5
  read_file: 'Read',
5
6
  write_file: 'Update',
6
7
  list_directory: 'List',
7
- search: 'Search'
8
+ search: 'Search',
9
+ screenshot: 'Screenshot',
10
+ list_windows: 'ListWindows',
11
+ run_and_capture: 'RunCapture'
8
12
  };
9
- function formatValue(value) {
10
- if (typeof value === 'string') {
11
- const escaped = value.replace(/\n/g, '\\n');
12
- return `"${escaped}"`;
13
- }
14
- if (typeof value === 'number' || typeof value === 'boolean') {
15
- return String(value);
16
- }
17
- return JSON.stringify(value);
18
- }
19
13
  function formatArgs(tool, args) {
14
+ // Compact arg formatting - just show the key values
20
15
  if (tool === 'run_command') {
21
16
  const command = args.command ? String(args.command) : '';
22
- const cwd = args.cwd ? `, cwd: ${formatValue(args.cwd)}` : '';
23
- const timeout = args.timeout ? `, timeout: ${formatValue(args.timeout)}` : '';
24
- return `(${command}${cwd}${timeout})`;
17
+ // Truncate long commands
18
+ const truncated = command.length > 60 ? command.slice(0, 57) + '...' : command;
19
+ return `(${truncated})`;
25
20
  }
26
21
  if (tool === 'search') {
27
- const pattern = args.pattern ? `pattern: ${formatValue(args.pattern)}` : '';
28
- const path = args.path ? `path: ${formatValue(args.path)}` : '';
29
- const output = args.output_mode ? `output_mode: ${formatValue(args.output_mode)}` : '';
30
- const parts = [pattern, path, output].filter(Boolean);
31
- return parts.length ? `(${parts.join(', ')})` : '';
22
+ const pattern = args.pattern ? String(args.pattern) : '';
23
+ const path = args.path ? formatTracePath(String(args.path)) : '';
24
+ if (path) {
25
+ return `(${pattern}, ${path})`;
26
+ }
27
+ return `(${pattern})`;
32
28
  }
33
29
  if (tool === 'read_file' || tool === 'write_file' || tool === 'list_directory') {
34
- const path = args.path ? formatValue(args.path) : '""';
30
+ const path = args.path ? formatTracePath(String(args.path)) : '';
35
31
  return `(${path})`;
36
32
  }
37
- const entries = Object.entries(args).map(([key, value]) => `${key}: ${formatValue(value)}`);
38
- return entries.length ? `(${entries.join(', ')})` : '';
33
+ if (tool === 'screenshot') {
34
+ if (args.app)
35
+ return `(app: "${args.app}")`;
36
+ if (args.pid)
37
+ return `(pid: ${args.pid})`;
38
+ if (args.windowId)
39
+ return `(windowId: ${args.windowId})`;
40
+ return '';
41
+ }
42
+ if (tool === 'list_windows') {
43
+ if (args.filter)
44
+ return `(filter: "${args.filter}")`;
45
+ return '';
46
+ }
47
+ // Generic: show first few args compactly
48
+ const entries = Object.entries(args).slice(0, 3);
49
+ if (entries.length === 0)
50
+ return '';
51
+ const parts = entries.map(([key, value]) => {
52
+ if (typeof value === 'string') {
53
+ const v = value.length > 30 ? value.slice(0, 27) + '...' : value;
54
+ return `${key}: "${v}"`;
55
+ }
56
+ return `${key}: ${value}`;
57
+ });
58
+ return `(${parts.join(', ')})`;
39
59
  }
40
60
  function parseResult(raw) {
41
61
  try {
@@ -48,9 +68,42 @@ function parseResult(raw) {
48
68
  }
49
69
  return null;
50
70
  }
71
+ function parseDiff(diff) {
72
+ if (!diff || !diff.includes('@@'))
73
+ return null;
74
+ const lines = diff.split('\n');
75
+ let addedLines = 0;
76
+ let removedLines = 0;
77
+ const hunks = [];
78
+ let currentHunk = null;
79
+ for (const line of lines) {
80
+ if (line.startsWith('@@')) {
81
+ if (currentHunk)
82
+ hunks.push(currentHunk);
83
+ currentHunk = { header: line, lines: [] };
84
+ continue;
85
+ }
86
+ if (!currentHunk)
87
+ continue;
88
+ if (line.startsWith('+') && !line.startsWith('+++')) {
89
+ addedLines++;
90
+ currentHunk.lines.push({ type: 'add', text: line.slice(1) });
91
+ }
92
+ else if (line.startsWith('-') && !line.startsWith('---')) {
93
+ removedLines++;
94
+ currentHunk.lines.push({ type: 'remove', text: line.slice(1) });
95
+ }
96
+ else if (line.startsWith(' ')) {
97
+ currentHunk.lines.push({ type: 'context', text: line.slice(1) });
98
+ }
99
+ }
100
+ if (currentHunk)
101
+ hunks.push(currentHunk);
102
+ return { addedLines, removedLines, hunks };
103
+ }
51
104
  function formatOutcome(tool, result, durationMs) {
52
105
  const parsed = parseResult(result);
53
- const duration = typeof durationMs === 'number' ? ` in ${(durationMs / 1000).toFixed(1)}s` : '';
106
+ const duration = typeof durationMs === 'number' ? ` in ${formatDuration(durationMs)}` : '';
54
107
  if (parsed && tool === 'search') {
55
108
  const count = typeof parsed.count === 'number' ? parsed.count : 0;
56
109
  const label = count === 1 ? 'match' : 'matches';
@@ -61,23 +114,36 @@ function formatOutcome(tool, result, durationMs) {
61
114
  const stderr = String(parsed.stderr || '');
62
115
  const lines = (stdout || stderr).trim().split('\n').filter(Boolean).length;
63
116
  const label = lines === 1 ? 'line' : 'lines';
64
- return lines > 0 ? `Output ${lines} ${label}${duration}` : `Command finished${duration}`;
117
+ return lines > 0 ? `Output ${lines} ${label}${duration}` : `Done${duration}`;
65
118
  }
66
119
  if (parsed && tool === 'read_file') {
67
- const path = String(parsed.path || '');
68
- const size = parsed.size ? `${parsed.size} bytes` : 'unknown size';
120
+ const path = formatTracePath(String(parsed.path || ''));
121
+ const size = typeof parsed.size === 'number' ? formatBytes(parsed.size) : '';
69
122
  const truncated = parsed.truncated ? ' (truncated)' : '';
70
- return `Read ${path} (${size})${duration}${truncated}`;
123
+ return `${path} (${size})${duration}${truncated}`;
71
124
  }
72
125
  if (parsed && tool === 'write_file') {
73
- const path = String(parsed.path || '');
74
- const action = String(parsed.action || 'written');
75
- return `Updated ${path} (${action})${duration}`;
126
+ const path = formatTracePath(String(parsed.path || ''));
127
+ const diff = parseDiff(String(parsed.diff || ''));
128
+ if (diff) {
129
+ const parts = [];
130
+ if (diff.addedLines > 0)
131
+ parts.push(`+${diff.addedLines}`);
132
+ if (diff.removedLines > 0)
133
+ parts.push(`-${diff.removedLines}`);
134
+ const summary = parts.length > 0 ? ` (${parts.join(', ')} lines)` : '';
135
+ return `${path}${summary}${duration}`;
136
+ }
137
+ return `${path}${duration}`;
76
138
  }
77
139
  if (parsed && tool === 'list_directory') {
78
- const path = String(parsed.path || '');
140
+ const path = formatTracePath(String(parsed.path || ''));
79
141
  const entries = Array.isArray(parsed.entries) ? parsed.entries.length : 0;
80
- return `Listed ${path} (${entries} items)${duration}`;
142
+ return `${path} (${entries} items)${duration}`;
143
+ }
144
+ if (parsed && tool === 'screenshot') {
145
+ const desc = String(parsed.description || 'Screenshot captured');
146
+ return `${desc}${duration}`;
81
147
  }
82
148
  return `Done${duration}`;
83
149
  }
@@ -99,7 +165,7 @@ function buildOutputLines(tool, result) {
99
165
  if (!entry || typeof entry !== 'object')
100
166
  return '';
101
167
  const row = entry;
102
- const file = String(row.path || '');
168
+ const file = formatTracePath(String(row.path || ''));
103
169
  const line = row.line ? `:${row.line}` : '';
104
170
  const text = String(row.text || '');
105
171
  return `${file}${line} ${text}`.trim();
@@ -112,9 +178,26 @@ function buildOutputLines(tool, result) {
112
178
  return { lines, truncated: Boolean(parsed.truncated) };
113
179
  }
114
180
  if (tool === 'write_file') {
115
- const diff = typeof parsed.diff === 'string' ? parsed.diff : '';
116
- const lines = diff ? diff.split('\n') : [];
117
- return { lines, truncated: Boolean(parsed.truncated) };
181
+ // Return formatted diff lines
182
+ const diff = parseDiff(String(parsed.diff || ''));
183
+ if (diff && diff.hunks.length > 0) {
184
+ const lines = [];
185
+ for (const hunk of diff.hunks) {
186
+ for (const line of hunk.lines) {
187
+ if (line.type === 'add') {
188
+ lines.push(`+ ${line.text}`);
189
+ }
190
+ else if (line.type === 'remove') {
191
+ lines.push(`- ${line.text}`);
192
+ }
193
+ else {
194
+ lines.push(` ${line.text}`);
195
+ }
196
+ }
197
+ }
198
+ return { lines, truncated: Boolean(parsed.truncated) };
199
+ }
200
+ return { lines: [], truncated: false };
118
201
  }
119
202
  return { lines: [], truncated: false };
120
203
  }
@@ -138,7 +221,7 @@ export function formatToolEnd(tool, result, durationMs, emulationId) {
138
221
  const style = getTraceStyle(emulationId);
139
222
  const summary = formatOutcome(tool, result, durationMs);
140
223
  if (style === 'claude_code') {
141
- return `⎿ ${summary}`;
224
+ return `⎿ ${summary}`;
142
225
  }
143
226
  if (style === 'codex') {
144
227
  if (tool === 'run_command') {
@@ -153,17 +236,37 @@ export function formatToolEnd(tool, result, durationMs, emulationId) {
153
236
  }
154
237
  export function formatToolError(tool, error, emulationId) {
155
238
  const style = getTraceStyle(emulationId);
239
+ const label = toolLabels[tool] || tool;
240
+ // Provide helpful error messages
241
+ let displayError = error;
242
+ if (error.includes('Screen Recording permission')) {
243
+ displayError = 'Screen Recording permission required (System Settings > Privacy & Security)';
244
+ }
156
245
  if (style === 'claude_code') {
157
- return `⎿ ${tool} failed: ${error}`;
246
+ return `⎿ ${label} failed: ${displayError}`;
158
247
  }
159
248
  if (style === 'codex') {
160
- return ` ${tool} failed: ${error}`;
249
+ return ` ${label} failed: ${displayError}`;
161
250
  }
162
- return `< ${tool} failed: ${error}`;
251
+ return `< ${label} failed: ${displayError}`;
163
252
  }
164
253
  export function buildToolOutputMessage(tool, result, durationMs, emulationId) {
165
254
  const { lines, truncated } = buildOutputLines(tool, result);
166
- if (lines.length === 0) {
255
+ const parsed = parseResult(result);
256
+ // For write_file, extract diff info
257
+ let diffLines;
258
+ if (tool === 'write_file' && parsed) {
259
+ const diff = parseDiff(String(parsed.diff || ''));
260
+ if (diff && diff.hunks.length > 0) {
261
+ diffLines = [];
262
+ for (const hunk of diff.hunks) {
263
+ for (const line of hunk.lines) {
264
+ diffLines.push({ type: line.type, text: line.text });
265
+ }
266
+ }
267
+ }
268
+ }
269
+ if (lines.length === 0 && !diffLines) {
167
270
  const summary = formatToolEnd(tool, result, durationMs, emulationId);
168
271
  return { preview: summary, full: summary, truncated: false };
169
272
  }
@@ -172,22 +275,24 @@ export function buildToolOutputMessage(tool, result, durationMs, emulationId) {
172
275
  const remaining = lines.length - previewLines.length;
173
276
  const expandHint = truncated || remaining > 0 ? ' (ctrl+o to expand)' : '';
174
277
  const summary = formatToolEnd(tool, result, durationMs, emulationId);
175
- const previewBlock = [
176
- summary,
177
- ...previewLines.map(line => ` ${line}`)
178
- ];
278
+ const indent = ' ';
279
+ const previewBlock = [summary];
280
+ for (const line of previewLines) {
281
+ previewBlock.push(`${indent}${line}`);
282
+ }
179
283
  if (expandHint) {
180
284
  const extraLabel = remaining > 0 ? `… +${remaining} lines` : '…';
181
- previewBlock.push(` ${extraLabel}${expandHint}`);
285
+ previewBlock.push(`${indent}${extraLabel}${expandHint}`);
286
+ }
287
+ const fullBlock = [summary];
288
+ for (const line of lines) {
289
+ fullBlock.push(`${indent}${line}`);
182
290
  }
183
- const fullBlock = [
184
- summary,
185
- ...lines.map(line => ` ${line}`)
186
- ];
187
291
  return {
188
292
  preview: previewBlock.join('\n'),
189
293
  full: fullBlock.join('\n'),
190
- truncated: Boolean(expandHint)
294
+ truncated: Boolean(expandHint),
295
+ diffLines
191
296
  };
192
297
  }
193
298
  //# sourceMappingURL=tool_trace.js.map