zelari-code 2.51.0 → 2.53.0
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/cli/acp/invariants.js +183 -0
- package/dist/cli/acp/invariants.js.map +1 -0
- package/dist/cli/acp/protocol.js +36 -3
- package/dist/cli/acp/protocol.js.map +1 -1
- package/dist/cli/acp/server.js +51 -15
- package/dist/cli/acp/server.js.map +1 -1
- package/dist/cli/acp/turnAdapter.js +2 -1
- package/dist/cli/acp/turnAdapter.js.map +1 -1
- package/dist/cli/app.js +17 -4
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/companion/framePolicy.js +116 -0
- package/dist/cli/companion/framePolicy.js.map +1 -0
- package/dist/cli/components/ChatStream.js +2 -2
- package/dist/cli/components/ChatStream.js.map +1 -1
- package/dist/cli/components/SelectList.js +51 -14
- package/dist/cli/components/SelectList.js.map +1 -1
- package/dist/cli/components/StatusBar.js +6 -2
- package/dist/cli/components/StatusBar.js.map +1 -1
- package/dist/cli/components/ToolOutput.js +2 -2
- package/dist/cli/components/ToolOutput.js.map +1 -1
- package/dist/cli/components/fuzzyMatch.js +108 -0
- package/dist/cli/components/fuzzyMatch.js.map +1 -0
- package/dist/cli/components/statusChips.js +47 -0
- package/dist/cli/components/statusChips.js.map +1 -1
- package/dist/cli/components/toolFormat.js +19 -7
- package/dist/cli/components/toolFormat.js.map +1 -1
- package/dist/cli/headless/protocol.js +39 -2
- package/dist/cli/headless/protocol.js.map +1 -1
- package/dist/cli/hooks/useSlashDispatch.js +5 -2
- package/dist/cli/hooks/useSlashDispatch.js.map +1 -1
- package/dist/cli/inbox.js +220 -0
- package/dist/cli/inbox.js.map +1 -0
- package/dist/cli/main.bundled.js +3551 -2528
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/main.js +22 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/serve/harnessServer.js +7 -0
- package/dist/cli/serve/harnessServer.js.map +1 -1
- package/dist/cli/sessionManager.js +9 -2
- package/dist/cli/sessionManager.js.map +1 -1
- package/dist/cli/skillsCheck.js +209 -0
- package/dist/cli/skillsCheck.js.map +1 -0
- package/dist/cli/slashCommands.js +9 -0
- package/dist/cli/slashCommands.js.map +1 -1
- package/dist/cli/slashHandlers/provider.js.map +1 -1
- package/dist/cli/slashHandlers/sessions.js +131 -0
- package/dist/cli/slashHandlers/sessions.js.map +1 -0
- package/dist/cli/statusline/statuslineItems.js +22 -3
- package/dist/cli/statusline/statuslineItems.js.map +1 -1
- package/dist/cli/statusline/verdictFeed.js +245 -0
- package/dist/cli/statusline/verdictFeed.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* companion/framePolicy — fail-loudly frame-type policy for the serve +
|
|
3
|
+
* companion display pipeline (OpenHarness post-mortem).
|
|
4
|
+
*
|
|
5
|
+
* The failure mode this closes: an emitter starts producing a frame `type`
|
|
6
|
+
* that nobody added to the display allowlist. Nothing crashes — the clients
|
|
7
|
+
* quietly drop the frame (or render it raw), and the feature looks "shipped"
|
|
8
|
+
* while the phone/desktop never sees it. Silent loss is the worst outcome, so
|
|
9
|
+
* the mismatch is made FATAL at serve startup instead: a process that cannot
|
|
10
|
+
* display what it emits must not accept clients.
|
|
11
|
+
*
|
|
12
|
+
* Two lists, deliberately separate:
|
|
13
|
+
*
|
|
14
|
+
* EMITTED_FRAME_TYPES — what the code can actually put on the
|
|
15
|
+
* wire (grounded in the emitters: the
|
|
16
|
+
* harness protocol frames, the permission /
|
|
17
|
+
* ask-user bridges, the companion run
|
|
18
|
+
* manager, and the BrainEvents forwarded
|
|
19
|
+
* verbatim to companion clients).
|
|
20
|
+
* COMPANION_DISPLAY_FRAME_TYPES — the display policy: every frame type the
|
|
21
|
+
* companion surface is allowed to consume.
|
|
22
|
+
*
|
|
23
|
+
* `assertFramePolicyComplete` is the gate. Extending the emitted vocabulary
|
|
24
|
+
* therefore requires a deliberate second edit (the allowlist); forgetting it
|
|
25
|
+
* fails the boot with the exact type names, never a silent drop.
|
|
26
|
+
*
|
|
27
|
+
* Zero runtime deps: the emitters own the writes, this module only mirrors
|
|
28
|
+
* their vocabulary as literals (each group names the file it came from).
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Every frame `type` the serve/ and companion/ emitters can produce.
|
|
32
|
+
*
|
|
33
|
+
* Keep this honest: it is the code's claim about its own output. When an
|
|
34
|
+
* emitter gains a new literal, add it here AND to
|
|
35
|
+
* COMPANION_DISPLAY_FRAME_TYPES in the same commit — the startup assert
|
|
36
|
+
* enforces the rest.
|
|
37
|
+
*/
|
|
38
|
+
export const EMITTED_FRAME_TYPES = [
|
|
39
|
+
// -- harness stdio protocol (serve/harnessServer.ts + headless/protocol.ts)
|
|
40
|
+
'protocol_info',
|
|
41
|
+
'control_accepted',
|
|
42
|
+
'control_applied',
|
|
43
|
+
'control_rejected',
|
|
44
|
+
// -- interactive bridges (serve/permissionBridge.ts, serve/askUserBridge.ts):
|
|
45
|
+
// the `type` written on the wire for each request/settlement pair.
|
|
46
|
+
'permission.request',
|
|
47
|
+
'permission.settled',
|
|
48
|
+
'ask_user.request',
|
|
49
|
+
'ask_user.settled',
|
|
50
|
+
// -- companion run wrapper (companion/runManager.ts + companion/serve.ts)
|
|
51
|
+
'trust.pending',
|
|
52
|
+
'trust.settled',
|
|
53
|
+
'log',
|
|
54
|
+
'error',
|
|
55
|
+
'run_finished',
|
|
56
|
+
// -- BrainEvents forwarded verbatim to companion clients (runManager.ts
|
|
57
|
+
// re-emits whatever the harness transport hands it; the companion SSE
|
|
58
|
+
// pipes those frames straight to the phone/desktop).
|
|
59
|
+
'agent_start',
|
|
60
|
+
'agent_end',
|
|
61
|
+
'agent_spawned',
|
|
62
|
+
'agent_status',
|
|
63
|
+
'agent_tool',
|
|
64
|
+
'agent_ended',
|
|
65
|
+
'message_start',
|
|
66
|
+
'message_delta',
|
|
67
|
+
'message_end',
|
|
68
|
+
'thinking_delta',
|
|
69
|
+
'tool_execution_start',
|
|
70
|
+
'tool_execution_update',
|
|
71
|
+
'tool_execution_end',
|
|
72
|
+
'queue_update',
|
|
73
|
+
'session_compacted',
|
|
74
|
+
'member_cost',
|
|
75
|
+
'council_mode',
|
|
76
|
+
'task_update',
|
|
77
|
+
'task_snapshot',
|
|
78
|
+
'kraken_progress',
|
|
79
|
+
'kraken_metrics',
|
|
80
|
+
'context_metrics',
|
|
81
|
+
];
|
|
82
|
+
/**
|
|
83
|
+
* Display policy: the frame types companion clients render. Today it mirrors
|
|
84
|
+
* the emitted vocabulary one-for-one (that is why the boot gate passes); it is
|
|
85
|
+
* a SEPARATE list on purpose so that adding an emitted frame stays a conscious
|
|
86
|
+
* policy decision, and so that dropping a policy entry fails the boot too
|
|
87
|
+
* instead of silently blinding the display.
|
|
88
|
+
*/
|
|
89
|
+
export const COMPANION_DISPLAY_FRAME_TYPES = [
|
|
90
|
+
...EMITTED_FRAME_TYPES,
|
|
91
|
+
];
|
|
92
|
+
/** Same policy as a set (the shape the assert consumes). */
|
|
93
|
+
export const COMPANION_DISPLAY_FRAME_ALLOWLIST = new Set(COMPANION_DISPLAY_FRAME_TYPES);
|
|
94
|
+
/**
|
|
95
|
+
* Throw when any emitted frame type is missing from the display allowlist.
|
|
96
|
+
* The message names EVERY offending type (de-duplicated, sorted) plus the file
|
|
97
|
+
* that owns the policy, so the fix is mechanical.
|
|
98
|
+
*/
|
|
99
|
+
export function assertFramePolicyComplete(emittedTypes, allowlist) {
|
|
100
|
+
const missing = [...new Set(emittedTypes)].filter((t) => !allowlist.has(t)).sort();
|
|
101
|
+
if (missing.length === 0)
|
|
102
|
+
return;
|
|
103
|
+
throw new Error(`[frame-policy] ${missing.length} emitted frame type(s) missing from the companion ` +
|
|
104
|
+
`display allowlist: ${missing.join(', ')}. Add them to ` +
|
|
105
|
+
`COMPANION_DISPLAY_FRAME_TYPES in src/cli/companion/framePolicy.ts (or stop ` +
|
|
106
|
+
`emitting them) — a frame outside the allowlist is silently dropped by ` +
|
|
107
|
+
`companion clients (OpenHarness post-mortem).`);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Gate the REAL pair. Called by the serve entry before any client can connect,
|
|
111
|
+
* so drift is fatal at startup rather than invisible at runtime.
|
|
112
|
+
*/
|
|
113
|
+
export function assertCompanionFramePolicy() {
|
|
114
|
+
assertFramePolicyComplete(EMITTED_FRAME_TYPES, COMPANION_DISPLAY_FRAME_ALLOWLIST);
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=framePolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framePolicy.js","sourceRoot":"","sources":["../../../src/cli/companion/framePolicy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAsB;IACpD,4EAA4E;IAC5E,eAAe;IACf,kBAAkB;IAClB,iBAAiB;IACjB,kBAAkB;IAClB,8EAA8E;IAC9E,sEAAsE;IACtE,oBAAoB;IACpB,oBAAoB;IACpB,kBAAkB;IAClB,kBAAkB;IAClB,0EAA0E;IAC1E,eAAe;IACf,eAAe;IACf,KAAK;IACL,OAAO;IACP,cAAc;IACd,wEAAwE;IACxE,yEAAyE;IACzE,wDAAwD;IACxD,aAAa;IACb,WAAW;IACX,eAAe;IACf,cAAc;IACd,YAAY;IACZ,aAAa;IACb,eAAe;IACf,eAAe;IACf,aAAa;IACb,gBAAgB;IAChB,sBAAsB;IACtB,uBAAuB;IACvB,oBAAoB;IACpB,cAAc;IACd,mBAAmB;IACnB,aAAa;IACb,cAAc;IACd,aAAa;IACb,eAAe;IACf,iBAAiB;IACjB,gBAAgB;IAChB,iBAAiB;CAClB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAsB;IAC9D,GAAG,mBAAmB;CACvB,CAAC;AAEF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,iCAAiC,GAAwB,IAAI,GAAG,CAC3E,6BAA6B,CAC9B,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,YAA+B,EAC/B,SAA8B;IAE9B,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACnF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACjC,MAAM,IAAI,KAAK,CACb,kBAAkB,OAAO,CAAC,MAAM,oDAAoD;QAClF,sBAAsB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB;QACxD,6EAA6E;QAC7E,wEAAwE;QACxE,8CAA8C,CACjD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B;IACxC,yBAAyB,CAAC,mBAAmB,EAAE,iCAAiC,CAAC,CAAC;AACpF,CAAC"}
|
|
@@ -19,9 +19,9 @@ import { TUI_PALETTE } from './tuiPalette.js';
|
|
|
19
19
|
* duration (the invocation hasn't ended yet). Finalized tool messages
|
|
20
20
|
* render via the stateless `ToolOutput` policy (Phase 3).
|
|
21
21
|
*/
|
|
22
|
-
export function renderMessage(m, live = false) {
|
|
22
|
+
export function renderMessage(m, live = false, verbose = false) {
|
|
23
23
|
if (m.role === 'tool') {
|
|
24
|
-
return (React.createElement(ToolOutput, { key: m.id, toolName: m.toolName ?? 'tool', summary: m.content, body: m.toolResult ?? m.content, ok: m.toolOk, durationMs: m.toolDurationMs, live: live }));
|
|
24
|
+
return (React.createElement(ToolOutput, { key: m.id, toolName: m.toolName ?? 'tool', summary: m.content, body: m.toolResult ?? m.content, ok: m.toolOk, durationMs: m.toolDurationMs, live: live, verbose: verbose }));
|
|
25
25
|
}
|
|
26
26
|
return (React.createElement(Box, { key: m.id, flexDirection: "column", marginBottom: 1 },
|
|
27
27
|
React.createElement(Text, { color: m.role === 'user'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatStream.js","sourceRoot":"","sources":["../../../src/cli/components/ChatStream.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAwC9C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,aAAa,
|
|
1
|
+
{"version":3,"file":"ChatStream.js","sourceRoot":"","sources":["../../../src/cli/components/ChatStream.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAwC9C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,aAAa,CAC3B,CAAc,EACd,IAAI,GAAG,KAAK,EACZ,OAAO,GAAG,KAAK;IAEf,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CACL,oBAAC,UAAU,IACT,GAAG,EAAE,CAAC,CAAC,EAAE,EACT,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,MAAM,EAC9B,OAAO,EAAE,CAAC,CAAC,OAAO,EAClB,IAAI,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,OAAO,EAC/B,EAAE,EAAE,CAAC,CAAC,MAAM,EACZ,UAAU,EAAE,CAAC,CAAC,cAAc,EAC5B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,GAChB,CACH,CAAC;IACJ,CAAC;IACD,OAAO,CACL,oBAAC,GAAG,IAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,aAAa,EAAC,QAAQ,EAAC,YAAY,EAAE,CAAC;QACpD,oBAAC,IAAI,IACH,KAAK,EACH,CAAC,CAAC,IAAI,KAAK,MAAM;gBACf,CAAC,CAAC,WAAW,CAAC,KAAK;gBACnB,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW;oBACtB,CAAC,CAAC,WAAW,CAAC,OAAO;oBACrB,CAAC,CAAC,WAAW,CAAC,IAAI,EAExB,IAAI;YAEH,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;;YAAG,CAAC,CAAC,IAAI;YACrE,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CACxC,oBAAC,IAAI,IAAC,KAAK,EAAE,WAAW,CAAC,QAAQ;;gBAAM,CAAC,CAAC,UAAU,CAAQ,CAC5D,CAAC,CAAC,CAAC,IAAI,CACH;QACP,oBAAC,GAAG,IAAC,UAAU,EAAE,CAAC;YAChB,oBAAC,IAAI,QAAE,CAAC,CAAC,OAAO,CAAQ,CACpB,CACF,CACP,CAAC;AACJ,CAAC;AAiBD,SAAS,cAAc,CAAC,EAAE,QAAQ,EAAmB;IACnD,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,IACjD,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACvB,oBAAC,IAAI,IAAC,QAAQ,qEAAsE,CACrF,CAAC,CAAC,CAAC,CACF,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CACtC,CACG,CACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AAErD,8EAA8E;AAC9E,4EAA4E;AAC5E,0EAA0E;AAC1E,8EAA8E;AAC9E,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAgC,EAChC,OAAe,EACf,MAAc;IAEd,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;AACvB,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { Box, Text, useInput, useStdin } from 'ink';
|
|
3
3
|
import { TUI_PALETTE } from './tuiPalette.js';
|
|
4
|
+
import { fuzzyMatch } from './fuzzyMatch.js';
|
|
4
5
|
/**
|
|
5
6
|
* Pure windowing helper (exported for tests): index of the first visible
|
|
6
7
|
* item so the cursor stays roughly centered while the list scrolls.
|
|
@@ -11,46 +12,79 @@ export function windowStart(index, count, maxVisible) {
|
|
|
11
12
|
const half = Math.floor(maxVisible / 2);
|
|
12
13
|
return Math.max(0, Math.min(index - half, count - maxVisible));
|
|
13
14
|
}
|
|
15
|
+
/** Anything a terminal can deliver as a literal character (no control codes). */
|
|
16
|
+
const PRINTABLE_INPUT = /^[^\u0000-\u001f\u007f]+$/;
|
|
14
17
|
/**
|
|
15
18
|
* SelectList — arrow-key picker rendered in the dynamic region (v0.7.10).
|
|
16
19
|
*
|
|
17
20
|
* Used by `/provider` and `/model` (no args) to make providers and models
|
|
18
|
-
* selectable instead of typed
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
21
|
+
* selectable instead of typed, and by `/sessions` (v2.53) for the fuzzy
|
|
22
|
+
* session picker. The App swaps it in for the InputBar while open, so
|
|
23
|
+
* ink-text-input never competes for keystrokes. ↑/↓ move (with wrap-around),
|
|
24
|
+
* enter selects, esc cancels. Long lists scroll inside a `maxVisible` window
|
|
25
|
+
* so the dynamic region stays under a screen.
|
|
26
|
+
*
|
|
27
|
+
* v2.53 filter: when filterable, typed characters build a query and the list
|
|
28
|
+
* is re-ranked live by `fuzzyMatch` (every whitespace-separated term must
|
|
29
|
+
* match — multi-term AND). An empty query shows the unfiltered list, so the
|
|
30
|
+
* picker behaves exactly like the pre-filter one until the user types.
|
|
31
|
+
* Backspace widens; esc cancels (the query is only ever a view over the list,
|
|
32
|
+
* never state the caller sees).
|
|
22
33
|
*/
|
|
23
|
-
export function SelectList({ title, items, onSelect, onCancel, maxVisible = 8, }) {
|
|
34
|
+
export function SelectList({ title, items, onSelect, onCancel, maxVisible = 8, filterable, filterPlaceholder = 'type to filter', }) {
|
|
24
35
|
const firstCurrent = items.findIndex((i) => i.current);
|
|
25
36
|
const [index, setIndex] = useState(firstCurrent === -1 ? 0 : firstCurrent);
|
|
37
|
+
const [query, setQuery] = useState('');
|
|
26
38
|
const { isRawModeSupported } = useStdin();
|
|
27
|
-
|
|
39
|
+
const searchable = filterable ?? items.some((i) => (i.searchText ?? '').length > 0);
|
|
40
|
+
// The filter is a VIEW over `items`: with an empty query the original order
|
|
41
|
+
// (and therefore the original picker behavior) is preserved.
|
|
42
|
+
const shown = searchable ? fuzzyMatch(query, items) : items;
|
|
43
|
+
// The active cursor can fall outside the shown list (query narrowed, or
|
|
44
|
+
// `items` changed under a non-empty query) — clamp for keys and render alike.
|
|
45
|
+
const active = shown.length === 0 ? 0 : Math.min(index, shown.length - 1);
|
|
46
|
+
const typeQuery = (next) => {
|
|
47
|
+
setQuery(next);
|
|
48
|
+
setIndex(0); // best match first: the cursor jumps to the head of the list
|
|
49
|
+
};
|
|
50
|
+
useInput((input, key) => {
|
|
28
51
|
if (key.upArrow) {
|
|
29
|
-
setIndex((
|
|
52
|
+
setIndex(() => (shown.length === 0 ? 0 : (active - 1 + shown.length) % shown.length));
|
|
30
53
|
}
|
|
31
54
|
else if (key.downArrow) {
|
|
32
|
-
setIndex((
|
|
55
|
+
setIndex(() => (shown.length === 0 ? 0 : (active + 1) % shown.length));
|
|
33
56
|
}
|
|
34
57
|
else if (key.return) {
|
|
35
|
-
const item =
|
|
58
|
+
const item = shown[active];
|
|
36
59
|
if (item)
|
|
37
60
|
onSelect(item.value);
|
|
38
61
|
}
|
|
39
62
|
else if (key.escape) {
|
|
40
63
|
onCancel();
|
|
41
64
|
}
|
|
65
|
+
else if (searchable) {
|
|
66
|
+
if (key.backspace || key.delete)
|
|
67
|
+
typeQuery(query.slice(0, -1));
|
|
68
|
+
else if (PRINTABLE_INPUT.test(input))
|
|
69
|
+
typeQuery(query + input);
|
|
70
|
+
}
|
|
42
71
|
}, { isActive: isRawModeSupported === true });
|
|
43
|
-
const start = windowStart(
|
|
44
|
-
const visible =
|
|
45
|
-
const below =
|
|
72
|
+
const start = windowStart(active, shown.length, maxVisible);
|
|
73
|
+
const visible = shown.slice(start, start + maxVisible);
|
|
74
|
+
const below = shown.length - (start + visible.length);
|
|
46
75
|
return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: TUI_PALETTE.borderFocus, paddingX: 1 },
|
|
47
76
|
React.createElement(Text, { bold: true, color: TUI_PALETTE.brand }, title),
|
|
77
|
+
searchable && (React.createElement(Text, { wrap: "truncate" },
|
|
78
|
+
'filter: ',
|
|
79
|
+
query.length > 0
|
|
80
|
+
? React.createElement(Text, { color: TUI_PALETTE.brandAlt }, query)
|
|
81
|
+
: React.createElement(Text, { dimColor: true }, filterPlaceholder))),
|
|
48
82
|
start > 0 && React.createElement(Text, { dimColor: true },
|
|
49
83
|
" \u2191 ",
|
|
50
84
|
start,
|
|
51
85
|
" more"),
|
|
52
86
|
visible.map((item, i) => {
|
|
53
|
-
const selected = start + i ===
|
|
87
|
+
const selected = start + i === active;
|
|
54
88
|
return (React.createElement(Text, { key: item.value, wrap: "truncate", color: selected ? TUI_PALETTE.brand : undefined },
|
|
55
89
|
selected ? '❯ ' : ' ',
|
|
56
90
|
React.createElement(Text, { bold: selected }, item.label),
|
|
@@ -63,6 +97,9 @@ export function SelectList({ title, items, onSelect, onCancel, maxVisible = 8, }
|
|
|
63
97
|
" \u2193 ",
|
|
64
98
|
below,
|
|
65
99
|
" more"),
|
|
66
|
-
React.createElement(Text, { dimColor: true }, "
|
|
100
|
+
shown.length === 0 && React.createElement(Text, { dimColor: true }, " no matches \u2014 backspace widens"),
|
|
101
|
+
React.createElement(Text, { dimColor: true }, searchable
|
|
102
|
+
? '↑/↓ move · type to filter · enter select · esc cancel'
|
|
103
|
+
: '↑/↓ move · enter select · esc cancel')));
|
|
67
104
|
}
|
|
68
105
|
//# sourceMappingURL=SelectList.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectList.js","sourceRoot":"","sources":["../../../src/cli/components/SelectList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"SelectList.js","sourceRoot":"","sources":["../../../src/cli/components/SelectList.tsx"],"names":[],"mappings":"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"}
|
|
@@ -17,7 +17,7 @@ import { TUI_PALETTE, modeColor } from './tuiPalette.js';
|
|
|
17
17
|
* region as short as possible. A single status line + the input bar + the
|
|
18
18
|
* streaming tail is always well under a screen, so no full repaint.
|
|
19
19
|
*/
|
|
20
|
-
function StatusBarImpl({ model, provider, sessionId, sessionActive, queueCount = 0, busy = false, mode = 'kraken', phase = 'build', cwd, elapsedMs = null, lastMs = null, costUsd = 0, cachedTokens = 0, cacheHitRate = 0, contextUsed = 0, contextLimit = 0, todoSummary = null, krakenLive = null, krakenGraph = null, verify = null, permissions = null, jail = null, }) {
|
|
20
|
+
function StatusBarImpl({ model, provider, sessionId, sessionActive, queueCount = 0, busy = false, mode = 'kraken', phase = 'build', cwd, elapsedMs = null, lastMs = null, costUsd = 0, cachedTokens = 0, cacheHitRate = 0, contextUsed = 0, contextLimit = 0, todoSummary = null, krakenLive = null, krakenGraph = null, verify = null, permissions = null, jail = null, verdict = null, }) {
|
|
21
21
|
const ctxLabel = contextLimit > 0
|
|
22
22
|
? `${formatTokens(contextUsed)}/${formatTokens(contextLimit)}`
|
|
23
23
|
: contextUsed > 0
|
|
@@ -45,6 +45,9 @@ function StatusBarImpl({ model, provider, sessionId, sessionActive, queueCount =
|
|
|
45
45
|
jail ? (React.createElement(React.Fragment, null,
|
|
46
46
|
React.createElement(Text, { dimColor: true }, " \u00B7 "),
|
|
47
47
|
React.createElement(Text, { bold: true, color: jail.tone }, jail.label))) : null,
|
|
48
|
+
verdict ? (React.createElement(React.Fragment, null,
|
|
49
|
+
React.createElement(Text, { dimColor: true }, " \u00B7 "),
|
|
50
|
+
React.createElement(Text, { bold: true, color: verdict.tone }, verdict.label))) : null,
|
|
48
51
|
React.createElement(Text, { bold: true, color: TUI_PALETTE.brand }, provider),
|
|
49
52
|
React.createElement(Text, { dimColor: true }, " \u00B7 "),
|
|
50
53
|
React.createElement(Text, null, model),
|
|
@@ -136,7 +139,8 @@ export function statusBarPropsEqual(prev, next) {
|
|
|
136
139
|
prev.krakenGraph === next.krakenGraph &&
|
|
137
140
|
statusChipPropsEqual(prev.verify, next.verify) &&
|
|
138
141
|
statusChipPropsEqual(prev.permissions, next.permissions) &&
|
|
139
|
-
statusChipPropsEqual(prev.jail, next.jail)
|
|
142
|
+
statusChipPropsEqual(prev.jail, next.jail) &&
|
|
143
|
+
statusChipPropsEqual(prev.verdict, next.verdict));
|
|
140
144
|
}
|
|
141
145
|
export const StatusBar = React.memo(StatusBarImpl, statusBarPropsEqual);
|
|
142
146
|
//# sourceMappingURL=StatusBar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../src/cli/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../src/cli/components/StatusBar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -16,7 +16,7 @@ function borderColor(toolName, ok) {
|
|
|
16
16
|
return TUI_PALETTE.brand;
|
|
17
17
|
}
|
|
18
18
|
function ToolOutputImpl(props) {
|
|
19
|
-
const { toolName, summary, body, ok, durationMs, live = false } = props;
|
|
19
|
+
const { toolName, summary, body, ok, durationMs, live = false, verbose = false } = props;
|
|
20
20
|
const color = borderColor(toolName, ok);
|
|
21
21
|
const { stdout } = useStdout();
|
|
22
22
|
// B3: clamp bordered box width so boxes don't stretch to full terminal and
|
|
@@ -32,7 +32,7 @@ function ToolOutputImpl(props) {
|
|
|
32
32
|
}
|
|
33
33
|
// Finalized — format the body per tool policy (B1).
|
|
34
34
|
const isError = ok === false;
|
|
35
|
-
const formatted = formatToolResult(toolName, body);
|
|
35
|
+
const formatted = formatToolResult(toolName, body, { verbose });
|
|
36
36
|
const status = ok ? '✓' : '✗';
|
|
37
37
|
const summaryLine = [
|
|
38
38
|
status,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolOutput.js","sourceRoot":"","sources":["../../../src/cli/components/ToolOutput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAiB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"ToolOutput.js","sourceRoot":"","sources":["../../../src/cli/components/ToolOutput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fuzzyMatch — dependency-free fuzzy filter for the interactive pickers.
|
|
3
|
+
*
|
|
4
|
+
* Matching (documented choice): the query is split on whitespace into terms
|
|
5
|
+
* and EVERY term must match — a multi-term query is an AND, never an OR. Each
|
|
6
|
+
* term matches when its characters appear IN ORDER anywhere in the candidate's
|
|
7
|
+
* lowercased `searchText` (classic fuzzy-finder subsequence matching, the
|
|
8
|
+
* fzf/`:Telescope` model): "kr gr" hits "kraken graph", "kwk" hits
|
|
9
|
+
* "kraken-worktree-key". Terms run against the whole searchText, not per-field,
|
|
10
|
+
* so a single term may span fields ("kraken /repo").
|
|
11
|
+
*
|
|
12
|
+
* Ranking (deliberately small and deterministic):
|
|
13
|
+
* 1. a whole-query substring hit outranks scattered term hits;
|
|
14
|
+
* 2. prefix hits outrank mid-string hits;
|
|
15
|
+
* 3. earlier first-match and word-start hits score higher;
|
|
16
|
+
* 4. adjacent (consecutive) matches score higher;
|
|
17
|
+
* 5. shorter searchText wins remaining ties; original order breaks the rest.
|
|
18
|
+
*
|
|
19
|
+
* Pure: no DOM, no I/O, no deps — the pickers pass plain `{searchText}` items.
|
|
20
|
+
*/
|
|
21
|
+
/** True for characters that continue a word (`-`, `_`, `/`, `.` are separators). */
|
|
22
|
+
function isWordChar(ch) {
|
|
23
|
+
return /[a-z0-9]/i.test(ch);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Score one term against one haystack (lowercased by the caller).
|
|
27
|
+
* Returns null when the term is not a subsequence of `text`.
|
|
28
|
+
*/
|
|
29
|
+
function scoreTerm(term, text) {
|
|
30
|
+
let ti = 0;
|
|
31
|
+
let last = -1;
|
|
32
|
+
let first = -1;
|
|
33
|
+
let score = 0;
|
|
34
|
+
for (let i = 0; i < text.length && ti < term.length; i++) {
|
|
35
|
+
if (text[i] !== term[ti])
|
|
36
|
+
continue;
|
|
37
|
+
if (first < 0)
|
|
38
|
+
first = i;
|
|
39
|
+
// Word-start hits (index 0 or right after a separator) are the strongest
|
|
40
|
+
// signal a fuzzy finder has: "gr" should find "graph", not "grep".
|
|
41
|
+
score += i === 0 || !isWordChar(text[i - 1] ?? '') ? 3 : 1;
|
|
42
|
+
if (last >= 0 && i === last + 1)
|
|
43
|
+
score += 1; // consecutive run
|
|
44
|
+
last = i;
|
|
45
|
+
ti++;
|
|
46
|
+
}
|
|
47
|
+
if (ti < term.length)
|
|
48
|
+
return null;
|
|
49
|
+
if (first === 0)
|
|
50
|
+
score += 4; // starts the haystack
|
|
51
|
+
else if (first > 0 && !isWordChar(text[first - 1] ?? ''))
|
|
52
|
+
score += 2; // word start
|
|
53
|
+
// Earlier matches win: a hit at index 0-3 gets a small positional bonus.
|
|
54
|
+
score += Math.max(0, 3 - first);
|
|
55
|
+
return score;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Score a full query (possibly several whitespace-separated terms) against a
|
|
59
|
+
* haystack. `null` = no match; 0 = empty query (matches everything).
|
|
60
|
+
*/
|
|
61
|
+
export function fuzzyScore(query, searchText) {
|
|
62
|
+
const terms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 0);
|
|
63
|
+
if (terms.length === 0)
|
|
64
|
+
return 0;
|
|
65
|
+
const text = searchText.toLowerCase();
|
|
66
|
+
let total = 0;
|
|
67
|
+
for (const term of terms) {
|
|
68
|
+
const s = scoreTerm(term, text);
|
|
69
|
+
if (s === null)
|
|
70
|
+
return null; // AND: one failing term drops the candidate
|
|
71
|
+
total += s;
|
|
72
|
+
}
|
|
73
|
+
const whole = query.toLowerCase().trim().replace(/\s+/g, ' ');
|
|
74
|
+
// Exact-ish feel: the query as typed (spaces squashed) appearing verbatim.
|
|
75
|
+
if (whole.length > 1 && text.includes(whole))
|
|
76
|
+
total += 20;
|
|
77
|
+
else if (text.startsWith(terms[0]))
|
|
78
|
+
total += 4; // prefix of the haystack
|
|
79
|
+
return total;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Rank `items` for `query`. An empty/whitespace-only query returns every item
|
|
83
|
+
* in its ORIGINAL order (the picker then shows the unfiltered list); otherwise
|
|
84
|
+
* matching items come back best-first, ties broken by original order.
|
|
85
|
+
*/
|
|
86
|
+
export function fuzzyMatch(query, items) {
|
|
87
|
+
const terms = query.split(/\s+/).filter((t) => t.length > 0);
|
|
88
|
+
if (terms.length === 0)
|
|
89
|
+
return [...items];
|
|
90
|
+
const ranked = [];
|
|
91
|
+
items.forEach((item, index) => {
|
|
92
|
+
const score = fuzzyScore(query, item.searchText ?? '');
|
|
93
|
+
if (score === null)
|
|
94
|
+
return;
|
|
95
|
+
ranked.push({ item, score, index });
|
|
96
|
+
});
|
|
97
|
+
ranked.sort((a, b) => {
|
|
98
|
+
if (b.score !== a.score)
|
|
99
|
+
return b.score - a.score;
|
|
100
|
+
const la = (a.item.searchText ?? '').length;
|
|
101
|
+
const lb = (b.item.searchText ?? '').length;
|
|
102
|
+
if (la !== lb)
|
|
103
|
+
return la - lb; // denser haystacks win
|
|
104
|
+
return a.index - b.index; // stable
|
|
105
|
+
});
|
|
106
|
+
return ranked.map((r) => r.item);
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=fuzzyMatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuzzyMatch.js","sourceRoot":"","sources":["../../../src/cli/components/fuzzyMatch.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,9 +16,14 @@
|
|
|
16
16
|
* permission / policy-load env vars, the CI flag and the registered
|
|
17
17
|
* policy-load surface. A runtime change of any of them re-resolves the chip.
|
|
18
18
|
*/
|
|
19
|
+
import { existsSync, statSync } from 'node:fs';
|
|
20
|
+
import path from 'node:path';
|
|
21
|
+
import { resolveSessionsDir } from '@zelari/core/session';
|
|
19
22
|
import { activeJailMode, probeJailBackend, OS_JAIL_ENV } from '../safety/osJail.js';
|
|
20
23
|
import { activePolicyLoadSurface, POLICY_LOAD_MODE_ENV } from '../safety/policyLoadMode.js';
|
|
21
24
|
import { loadStatusLineConfig } from '../statusline/statuslineConfig.js';
|
|
25
|
+
import { readVerdictFeed, verdictFeedText } from '../statusline/verdictFeed.js';
|
|
26
|
+
import { getCurrentSessionId } from '../sessionManager.js';
|
|
22
27
|
/**
|
|
23
28
|
* t114: is this item part of the user's (or default) status-line order?
|
|
24
29
|
* Answers from the persisted config, so `/statusline off jail` hides the chip
|
|
@@ -85,4 +90,46 @@ export function cachedJailStatusChip(env = process.env, platform = process.platf
|
|
|
85
90
|
export function resetJailChipCacheForTests() {
|
|
86
91
|
chipCache = null;
|
|
87
92
|
}
|
|
93
|
+
/** Pure: feed -> chip. Exported for tests; never touches disk. */
|
|
94
|
+
export function verdictChipFromFeed(feed, env = process.env) {
|
|
95
|
+
const label = verdictFeedText(feed, env);
|
|
96
|
+
if (label === null)
|
|
97
|
+
return null;
|
|
98
|
+
const tone = feed?.ready === true ? 'green' : feed?.verdict === 'BLOCKED' ? 'red' : 'yellow';
|
|
99
|
+
return { label, tone };
|
|
100
|
+
}
|
|
101
|
+
/** Every input the verdict chip depends on, flattened into a comparable key. */
|
|
102
|
+
function verdictChipKey(env) {
|
|
103
|
+
const sessionId = getCurrentSessionId();
|
|
104
|
+
let mtime = 'none';
|
|
105
|
+
if (sessionId) {
|
|
106
|
+
try {
|
|
107
|
+
const file = path.join(resolveSessionsDir({ env }), sessionId, 'events.jsonl');
|
|
108
|
+
mtime = existsSync(file) ? String(statSync(file).mtimeMs) : 'none';
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
mtime = 'none';
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return `${sessionId ?? 'no-session'}|${env.ZELARI_VERDICT_FEED ?? ''}|${mtime}`;
|
|
115
|
+
}
|
|
116
|
+
let verdictChipCache = null;
|
|
117
|
+
/**
|
|
118
|
+
* Cached verdict chip — safe to call from a render body. Opt-in item: it only
|
|
119
|
+
* paints when `/statusline on verdict` added it to the configured order.
|
|
120
|
+
*/
|
|
121
|
+
export function cachedVerdictStatusChip(env = process.env) {
|
|
122
|
+
if (!statusLineItemEnabled('verdict'))
|
|
123
|
+
return null;
|
|
124
|
+
const key = verdictChipKey(env);
|
|
125
|
+
if (verdictChipCache && verdictChipCache.key === key)
|
|
126
|
+
return verdictChipCache.chip;
|
|
127
|
+
const chip = verdictChipFromFeed(readVerdictFeed({ env }), env);
|
|
128
|
+
verdictChipCache = { key, chip };
|
|
129
|
+
return chip;
|
|
130
|
+
}
|
|
131
|
+
/** TEST-ONLY: drop the memoized verdict chip (same discipline as the jail chip). */
|
|
132
|
+
export function resetVerdictChipCacheForTests() {
|
|
133
|
+
verdictChipCache = null;
|
|
134
|
+
}
|
|
88
135
|
//# sourceMappingURL=statusChips.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statusChips.js","sourceRoot":"","sources":["../../../src/cli/components/statusChips.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"statusChips.js","sourceRoot":"","sources":["../../../src/cli/components/statusChips.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,9 +37,14 @@ function tryParseJson(s) {
|
|
|
37
37
|
return null;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Truncate an array of lines to the cap, appending a `… (+K lines)` marker.
|
|
42
|
+
* `capOverride < 0` disables truncation entirely (ctrl+O verbose mode).
|
|
43
|
+
*/
|
|
44
|
+
function truncateLines(lines, capOverride) {
|
|
45
|
+
const cap = capOverride ?? toolOutputLineCap();
|
|
46
|
+
if (cap < 0)
|
|
47
|
+
return lines;
|
|
43
48
|
if (lines.length <= cap)
|
|
44
49
|
return lines;
|
|
45
50
|
return [...lines.slice(0, cap), `… (+${lines.length - cap} lines)`];
|
|
@@ -66,7 +71,9 @@ export function toolResultForStorage(toolName, result, isError, maxChars = TOOL_
|
|
|
66
71
|
if (isError) {
|
|
67
72
|
return result.length > maxChars ? `${result.slice(0, maxChars)}…` : result;
|
|
68
73
|
}
|
|
69
|
-
|
|
74
|
+
// v2.51 ctrl+O: store the UNTRUNCATED body (line-wise) so the verbose
|
|
75
|
+
// toggle can reveal it at render time; the 8000-char bound still applies.
|
|
76
|
+
const formatted = formatToolResult(toolName, result, { verbose: true });
|
|
70
77
|
let display = formatted.lines.join("\n");
|
|
71
78
|
if (formatted.meta)
|
|
72
79
|
display += `\n${formatted.meta}`;
|
|
@@ -140,7 +147,10 @@ function formatGrepContentResult(matches, filesSearched) {
|
|
|
140
147
|
* @param resultStr the raw result string (JSON envelope from the harness, or
|
|
141
148
|
* a plain string for non-JSON tools / errors)
|
|
142
149
|
*/
|
|
143
|
-
export function formatToolResult(toolName, resultStr) {
|
|
150
|
+
export function formatToolResult(toolName, resultStr, opts) {
|
|
151
|
+
// v2.51 ctrl+O: verbose disables the display line cap (storage keeps the
|
|
152
|
+
// full body anyway; only the renderer truncates by default).
|
|
153
|
+
const capOverride = opts?.verbose ? -1 : undefined;
|
|
144
154
|
const preLine = resultStr.trim().split("\n")[0] ?? "";
|
|
145
155
|
if (PREFORMATTED_RESULT_RE.test(preLine) &&
|
|
146
156
|
resultStr
|
|
@@ -172,7 +182,7 @@ export function formatToolResult(toolName, resultStr) {
|
|
|
172
182
|
metaParts.push("⚠ interactive prompt cancelled — needs non-interactive flags or manual file creation");
|
|
173
183
|
}
|
|
174
184
|
return {
|
|
175
|
-
lines: truncateLines(lines),
|
|
185
|
+
lines: truncateLines(lines, capOverride),
|
|
176
186
|
meta: metaParts.length > 0 ? metaParts.join(" · ") : undefined,
|
|
177
187
|
};
|
|
178
188
|
}
|
|
@@ -262,7 +272,9 @@ export function formatToolResult(toolName, resultStr) {
|
|
|
262
272
|
}
|
|
263
273
|
// Fallback: treat as plain text (split on real newlines; if it's JSON we
|
|
264
274
|
// already failed to match a known shape, so show it verbatim).
|
|
265
|
-
return {
|
|
275
|
+
return {
|
|
276
|
+
lines: truncateLines(resultStr.replace(/\r\n/g, "\n").split("\n"), capOverride),
|
|
277
|
+
};
|
|
266
278
|
}
|
|
267
279
|
/** Make a path relative to cwd when possible (shorter display). */
|
|
268
280
|
function rel(p) {
|