klyro 0.1.53 → 0.1.55
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/anthropic-adapter.js +22 -2
- package/dist/agent/registry.js +11 -1
- package/dist/agent/retry.d.ts +5 -0
- package/dist/agent/retry.js +28 -1
- package/dist/agent/runtime.d.ts +2 -0
- package/dist/agent/runtime.js +48 -35
- package/dist/chat.js +2 -2
- package/dist/checkpoints/store.js +86 -7
- package/dist/cli/config.js +13 -1
- package/dist/cli/repl.js +200 -36
- package/dist/cli/run.js +88 -69
- package/dist/context/klyro-md.d.ts +5 -0
- package/dist/context/klyro-md.js +28 -6
- package/dist/context/tokenizer.js +8 -1
- package/dist/index.js +49 -14
- package/dist/persistence/session.d.ts +2 -0
- package/dist/persistence/session.js +11 -5
- package/dist/persistence/store.d.ts +7 -0
- package/dist/persistence/store.js +77 -28
- package/dist/policy/engine.d.ts +10 -1
- package/dist/policy/engine.js +33 -2
- package/dist/tools/fs/apply-patch.d.ts +16 -1
- package/dist/tools/fs/apply-patch.js +163 -75
- package/dist/tools/fs/edit-file.d.ts +13 -0
- package/dist/tools/fs/edit-file.js +96 -54
- package/dist/tools/fs/list-dir.d.ts +2 -0
- package/dist/tools/fs/list-dir.js +7 -5
- package/dist/tools/fs/multi-edit.js +12 -1
- package/dist/tools/fs/read-file.js +1 -1
- package/dist/tools/fs/read-history.d.ts +2 -2
- package/dist/tools/fs/read-history.js +39 -7
- package/dist/tools/fs/write-file.js +1 -1
- package/dist/tools/normalize.js +11 -1
- package/dist/tools/shell/background.d.ts +5 -0
- package/dist/tools/shell/background.js +29 -0
- package/dist/tools/shell/shell-exec.d.ts +9 -0
- package/dist/tools/shell/shell-exec.js +54 -8
- package/dist/tools/verify/run-verify.js +2 -2
- package/dist/tui/app.js +10 -5
- package/dist/tui/app.test.js +42 -0
- package/dist/tui/approval.d.ts +1 -1
- package/dist/tui/approval.js +20 -5
- package/dist/tui/diff.d.ts +5 -19
- package/dist/tui/diff.js +9 -25
- package/dist/tui/status.d.ts +4 -8
- package/dist/tui/status.js +8 -17
- package/dist/tui/transcript.d.ts +13 -20
- package/dist/tui/transcript.js +9 -74
- package/dist/verification/engine.js +4 -4
- package/package.json +1 -1
package/dist/tui/transcript.js
CHANGED
|
@@ -1,74 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (!args || args === '{}')
|
|
11
|
-
return '';
|
|
12
|
-
let parsed = null;
|
|
13
|
-
try {
|
|
14
|
-
parsed = JSON.parse(args);
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
return args.slice(0, 80);
|
|
18
|
-
}
|
|
19
|
-
switch (name) {
|
|
20
|
-
case 'read_file':
|
|
21
|
-
case 'write_file':
|
|
22
|
-
case 'edit_file':
|
|
23
|
-
return typeof parsed.path === 'string' ? parsed.path : '';
|
|
24
|
-
case 'shell_exec':
|
|
25
|
-
return typeof parsed.command === 'string' ? parsed.command : '';
|
|
26
|
-
case 'search_files':
|
|
27
|
-
case 'grep': {
|
|
28
|
-
const q = parsed.query ?? parsed.pattern;
|
|
29
|
-
return typeof q === 'string' ? `"${q}"` : '';
|
|
30
|
-
}
|
|
31
|
-
case 'list_directory':
|
|
32
|
-
return typeof parsed.path === 'string' ? parsed.path : '';
|
|
33
|
-
case 'git_status':
|
|
34
|
-
case 'git_diff':
|
|
35
|
-
return '';
|
|
36
|
-
default:
|
|
37
|
-
return '';
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
function TranscriptRow({ item }) {
|
|
41
|
-
if (item.kind === 'text') {
|
|
42
|
-
const color = item.role === 'user' ? 'blue' : undefined;
|
|
43
|
-
return (_jsx(Box, { marginY: 0, children: _jsxs(Text, { color: color, children: [item.role === 'user' ? '> ' : '', item.text] }) }));
|
|
44
|
-
}
|
|
45
|
-
if (item.kind === 'tool') {
|
|
46
|
-
return _jsx(ToolCard, { item: item });
|
|
47
|
-
}
|
|
48
|
-
if (item.kind === 'policy') {
|
|
49
|
-
const color = item.action === 'allow' ? 'green' : item.action === 'deny' ? 'red' : 'yellow';
|
|
50
|
-
return (_jsxs(Box, { paddingLeft: 2, children: [_jsx(Text, { color: "gray", children: "[policy] " }), _jsx(Text, { color: color, children: item.action }), _jsxs(Text, { color: "gray", children: [" ", item.name] }), item.reason ? _jsxs(Text, { color: "gray", children: [" \u2014 ", item.reason] }) : null] }));
|
|
51
|
-
}
|
|
52
|
-
if (item.kind === 'file_changed') {
|
|
53
|
-
const color = item.op === 'deleted' ? 'red' : item.op === 'created' ? 'green' : 'yellow';
|
|
54
|
-
const glyph = item.op === 'created' ? '+' : item.op === 'deleted' ? '-' : '~';
|
|
55
|
-
return (_jsx(Box, { paddingLeft: 2, children: _jsxs(Text, { color: color, children: ["[", glyph, " ", item.op, "] ", item.path] }) }));
|
|
56
|
-
}
|
|
57
|
-
if (item.kind === 'error') {
|
|
58
|
-
return (_jsx(Box, { paddingLeft: 2, children: _jsxs(Text, { color: "red", children: ["[error] ", item.message] }) }));
|
|
59
|
-
}
|
|
60
|
-
if (item.kind === 'diff') {
|
|
61
|
-
return _jsx(DiffView, { hunks: item.hunks, summary: item.summary });
|
|
62
|
-
}
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
function ToolCard({ item }) {
|
|
66
|
-
const summary = summarizeTool(item.name, item.args);
|
|
67
|
-
const borderColor = item.status === 'error' ? 'red' : item.status === 'running' ? 'cyan' : 'gray';
|
|
68
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: borderColor, marginY: 1, paddingX: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: "gray", children: "\u250C\u2500 " }), _jsx(Text, { bold: true, children: item.name }), item.status === 'running' ? (_jsxs(Text, { color: "cyan", children: [" ", _jsx(Spinner, { type: "dots" }), " running"] })) : item.status === 'error' ? (_jsx(Text, { color: "red", children: " \u2717 error" })) : (_jsxs(Text, { color: "green", children: [" \u2713 ", item.latencyMs ?? 0, "ms"] })), _jsx(Text, { color: "gray", children: " \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" })] }), summary ? (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { children: truncate(summary, 200) }) })) : null, item.status !== 'running' && item.result ? (_jsx(Box, { paddingLeft: 2, flexDirection: "column", children: _jsxs(Text, { color: item.isError ? 'red' : 'gray', children: [item.isError ? '✗ ' : '→ ', truncate(item.result, 400)] }) })) : null, _jsx(Box, { children: _jsx(Text, { color: "gray", children: "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }) })] }));
|
|
69
|
-
}
|
|
70
|
-
function truncate(s, max) {
|
|
71
|
-
if (s.length <= max)
|
|
72
|
-
return s;
|
|
73
|
-
return s.slice(0, max) + '…';
|
|
74
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Transcript item types — the scrollable entry list owned by App.
|
|
3
|
+
*
|
|
4
|
+
* NOTE: the old Transcript/TranscriptRow/ToolCard presentational components
|
|
5
|
+
* were removed: App renders entries inline (grouped tool activity), and the
|
|
6
|
+
* standalone components' tests gave false coverage for UI nobody sees.
|
|
7
|
+
* Only the item types remain.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
@@ -18,7 +18,10 @@ function appendCapped(current, chunk) {
|
|
|
18
18
|
return next.length > MAX_VERIFY_BYTES ? next.slice(0, MAX_VERIFY_BYTES) + '\n... [truncated]' : next;
|
|
19
19
|
}
|
|
20
20
|
// SEC-004: denylist for dangerous patterns in verify commands.
|
|
21
|
-
//
|
|
21
|
+
// Destructive-only: the verify command comes from CLI flags, project config,
|
|
22
|
+
// or auto-detected package scripts (never model-controlled), so shell
|
|
23
|
+
// metacharacters ($(), backticks, pipes) that are legitimate in test scripts
|
|
24
|
+
// are allowed here — unlike shell_exec's model-facing denylist.
|
|
22
25
|
const DANGEROUS_VERIFY_PATTERNS = [
|
|
23
26
|
{ pattern: /rm\s+-rf?\s+\//, reason: 'recursive delete at filesystem root' },
|
|
24
27
|
{ pattern: /rm\s+-rf?\s+\/\/+/, reason: 'recursive delete at filesystem root (//)' },
|
|
@@ -39,9 +42,6 @@ const DANGEROUS_VERIFY_PATTERNS = [
|
|
|
39
42
|
{ pattern: /curl.*\|\s*(sh|bash|zsh|python|python3|perl|ruby|php)/i, reason: 'curl|sh to unknown host' },
|
|
40
43
|
{ pattern: /wget.*\|\s*(sh|bash|python|perl|ruby)/i, reason: 'wget|sh pipe' },
|
|
41
44
|
{ pattern: /rm\s+-rf\s+--no-preserve-root\s+\//, reason: 'recursive delete --no-preserve-root' },
|
|
42
|
-
{ pattern: /\$\(/, reason: 'command substitution $()' },
|
|
43
|
-
{ pattern: /`[^`]*`/, reason: 'command substitution via backticks' },
|
|
44
|
-
{ pattern: /\|\s*bash\b|\|\s*sh\b/, reason: 'pipe to shell' },
|
|
45
45
|
{ pattern: /;\s*rm\s+-rf/, reason: 'chained rm -rf' },
|
|
46
46
|
{ pattern: /&&\s*rm\s+-rf/, reason: 'chained rm -rf' },
|
|
47
47
|
{ pattern: /\|\|\s*rm\s+-rf/, reason: 'chained rm -rf' },
|
package/package.json
CHANGED