@drisp/cli 0.5.8 → 0.5.10
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/athena-gateway.js +1 -1
- package/dist/{chunk-XIWMD4GT.js → chunk-RN5AVH3D.js} +3541 -144
- package/dist/cli.js +302 -3344
- package/dist/dashboard-daemon.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -8,11 +8,16 @@ import {
|
|
|
8
8
|
EXEC_EXIT_CODE,
|
|
9
9
|
GatewayUnauthorizedError,
|
|
10
10
|
GatewayUnreachableError,
|
|
11
|
+
IndexedTimeline,
|
|
11
12
|
PORTABLE_PROVIDER_ENV_VARS,
|
|
12
13
|
bootstrapRuntimeConfig,
|
|
13
14
|
buildApiKeyHelperSettings,
|
|
15
|
+
buildPostByToolUseId,
|
|
14
16
|
buildProbeConfigs,
|
|
17
|
+
centerAnsi,
|
|
15
18
|
classifyFailure,
|
|
19
|
+
compactText,
|
|
20
|
+
computeInputRows,
|
|
16
21
|
connect,
|
|
17
22
|
createDashboardDecisionInbox,
|
|
18
23
|
createFeedMapper,
|
|
@@ -23,10 +28,17 @@ import {
|
|
|
23
28
|
createSessionStore,
|
|
24
29
|
createWsClientTransport,
|
|
25
30
|
credentialHelperKey,
|
|
31
|
+
cursorToVisualPosition,
|
|
26
32
|
daemonStatePaths,
|
|
27
33
|
detectClaudeVersion,
|
|
34
|
+
extractFriendlyServerName,
|
|
28
35
|
extractPermissionSnapshot,
|
|
36
|
+
fit,
|
|
37
|
+
fitAnsi,
|
|
38
|
+
formatClock,
|
|
29
39
|
formatProbeCommand,
|
|
40
|
+
formatRunLabel,
|
|
41
|
+
formatToolResponse,
|
|
30
42
|
frameGlyphs,
|
|
31
43
|
generateHookSettings,
|
|
32
44
|
generateId,
|
|
@@ -38,8 +50,9 @@ import {
|
|
|
38
50
|
hintGlyphs,
|
|
39
51
|
ingestRuntimeDecision,
|
|
40
52
|
ingestRuntimeEvent,
|
|
53
|
+
isBashToolResponse,
|
|
54
|
+
isCommandPrefix,
|
|
41
55
|
isScopedPermissionsRequest,
|
|
42
|
-
isSubagentTool,
|
|
43
56
|
isSupportedGatewayUrl,
|
|
44
57
|
listHarnessAdapters,
|
|
45
58
|
listHarnessCapabilities,
|
|
@@ -47,7 +60,9 @@ import {
|
|
|
47
60
|
lookupAllCredentials,
|
|
48
61
|
lookupCredential,
|
|
49
62
|
makeSkippedProbe,
|
|
63
|
+
mergeFeedItems,
|
|
50
64
|
messageGlyphs,
|
|
65
|
+
parseToolName,
|
|
51
66
|
probeSkipReason,
|
|
52
67
|
processRegistry,
|
|
53
68
|
progressGlyphs,
|
|
@@ -57,24 +72,32 @@ import {
|
|
|
57
72
|
register,
|
|
58
73
|
registerCleanupOnExit,
|
|
59
74
|
removeAttachmentMirror,
|
|
75
|
+
renderInputLines,
|
|
60
76
|
resolveClaudeBinary,
|
|
61
77
|
resolveClaudeSettingsSurfacePaths,
|
|
62
78
|
resolveHarnessAdapter,
|
|
63
79
|
resolveHookForwarderCommand,
|
|
64
80
|
resolveRuntimeAuthOverlay,
|
|
81
|
+
resolveToolColumn,
|
|
65
82
|
runClaudeAuthStatus,
|
|
66
83
|
runDashboardRuntimeDaemon,
|
|
67
84
|
runExec,
|
|
68
85
|
runProbe,
|
|
69
86
|
sendUdsRequest,
|
|
70
87
|
sessionsDir,
|
|
88
|
+
sliceAnsi,
|
|
89
|
+
spaces,
|
|
71
90
|
startSessionBridge,
|
|
91
|
+
stringWidth,
|
|
92
|
+
stripAnsi,
|
|
72
93
|
supportsSessionApproval,
|
|
73
94
|
todoGlyphSet,
|
|
95
|
+
visualPositionToOffset,
|
|
96
|
+
wrapText,
|
|
74
97
|
writeAttachmentMirror,
|
|
75
98
|
writeGatewayClientConfig,
|
|
76
99
|
wsClientOptionsForEndpoint
|
|
77
|
-
} from "./chunk-
|
|
100
|
+
} from "./chunk-RN5AVH3D.js";
|
|
78
101
|
import {
|
|
79
102
|
generateId as generateId2
|
|
80
103
|
} from "./chunk-BTKQ67RE.js";
|
|
@@ -160,34 +183,6 @@ import { Box as Box19, Text as Text25, useApp, useInput as useInput17, useStdout
|
|
|
160
183
|
import { useCallback, useMemo } from "react";
|
|
161
184
|
import { Box as Box2, Text as Text2, useInput as useInput2, useStdout } from "ink";
|
|
162
185
|
|
|
163
|
-
// src/shared/utils/toolNameParser.ts
|
|
164
|
-
function extractFriendlyServerName(mcpServer) {
|
|
165
|
-
const pluginMatch = /^plugin_[^_]+_(.+)$/.exec(mcpServer);
|
|
166
|
-
if (pluginMatch) {
|
|
167
|
-
return pluginMatch[1];
|
|
168
|
-
}
|
|
169
|
-
return mcpServer;
|
|
170
|
-
}
|
|
171
|
-
function parseToolName(toolName) {
|
|
172
|
-
const match = /^mcp__([^_]+(?:_[^_]+)*)__(.+)$/.exec(toolName);
|
|
173
|
-
if (match) {
|
|
174
|
-
const mcpServer = match[1];
|
|
175
|
-
const mcpAction = match[2];
|
|
176
|
-
const friendlyServer = extractFriendlyServerName(mcpServer);
|
|
177
|
-
return {
|
|
178
|
-
displayName: mcpAction,
|
|
179
|
-
isMcp: true,
|
|
180
|
-
mcpServer,
|
|
181
|
-
mcpAction,
|
|
182
|
-
serverLabel: `${friendlyServer} (MCP)`
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
return {
|
|
186
|
-
displayName: toolName,
|
|
187
|
-
isMcp: false
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
186
|
// src/ui/components/OptionList.tsx
|
|
192
187
|
import { useState } from "react";
|
|
193
188
|
import { Box, Text, useInput } from "ink";
|
|
@@ -840,50 +835,6 @@ import {
|
|
|
840
835
|
useSyncExternalStore
|
|
841
836
|
} from "react";
|
|
842
837
|
|
|
843
|
-
// src/core/feed/filter.ts
|
|
844
|
-
var TASK_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
845
|
-
"TodoWrite",
|
|
846
|
-
"TaskCreate",
|
|
847
|
-
"TaskUpdate",
|
|
848
|
-
"TaskList",
|
|
849
|
-
"TaskGet"
|
|
850
|
-
]);
|
|
851
|
-
function isTaskToolEvent(event) {
|
|
852
|
-
if (event.kind !== "tool.pre" && event.kind !== "tool.post") return false;
|
|
853
|
-
return TASK_TOOL_NAMES.has(event.data.tool_name);
|
|
854
|
-
}
|
|
855
|
-
function shouldExcludeFromFeed(event) {
|
|
856
|
-
if (isTaskToolEvent(event)) return true;
|
|
857
|
-
if (event.kind === "todo.update") return true;
|
|
858
|
-
return false;
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
// src/core/feed/items.ts
|
|
862
|
-
function mergeFeedItems(messages, feedEvents) {
|
|
863
|
-
const messageItems = messages.map((message) => ({
|
|
864
|
-
type: "message",
|
|
865
|
-
data: message
|
|
866
|
-
}));
|
|
867
|
-
const feedItems = feedEvents.filter((event) => !shouldExcludeFromFeed(event)).map((event) => ({ type: "feed", data: event }));
|
|
868
|
-
return [...messageItems, ...feedItems].sort((left, right) => {
|
|
869
|
-
if (left.data.seq !== right.data.seq) return left.data.seq - right.data.seq;
|
|
870
|
-
if (left.type === "message" && right.type !== "message") return -1;
|
|
871
|
-
if (left.type !== "message" && right.type === "message") return 1;
|
|
872
|
-
return 0;
|
|
873
|
-
});
|
|
874
|
-
}
|
|
875
|
-
function buildPostByToolUseId(events) {
|
|
876
|
-
const map = /* @__PURE__ */ new Map();
|
|
877
|
-
for (const event of events) {
|
|
878
|
-
if (event.kind !== "tool.delta" && event.kind !== "tool.post" && event.kind !== "tool.failure") {
|
|
879
|
-
continue;
|
|
880
|
-
}
|
|
881
|
-
const toolUseId = event.data.tool_use_id;
|
|
882
|
-
if (toolUseId) map.set(toolUseId, event);
|
|
883
|
-
}
|
|
884
|
-
return map;
|
|
885
|
-
}
|
|
886
|
-
|
|
887
838
|
// src/shared/utils/perf.ts
|
|
888
839
|
import fs from "fs";
|
|
889
840
|
import path from "path";
|
|
@@ -1731,7 +1682,7 @@ function useFeed(runtime, messages = [], initialAllowedTools, sessionStore, opti
|
|
|
1731
1682
|
const [isServerRunning, setIsServerRunning] = useState4(
|
|
1732
1683
|
() => runtime.getStatus() === "running"
|
|
1733
1684
|
);
|
|
1734
|
-
const [
|
|
1685
|
+
const [runtimeError, setRuntimeError] = useState4(
|
|
1735
1686
|
() => runtime.getLastError()
|
|
1736
1687
|
);
|
|
1737
1688
|
const restoredTokens = useMemo3(
|
|
@@ -2118,7 +2069,7 @@ function useFeed(runtime, messages = [], initialAllowedTools, sessionStore, opti
|
|
|
2118
2069
|
currentRun: mapperRef.current.getCurrentRun(),
|
|
2119
2070
|
actors: mapperRef.current.getActors(),
|
|
2120
2071
|
isServerRunning,
|
|
2121
|
-
runtimeError
|
|
2072
|
+
runtimeError,
|
|
2122
2073
|
currentPermissionRequest,
|
|
2123
2074
|
permissionQueueCount: permissionQueue.length,
|
|
2124
2075
|
resolvePermission,
|
|
@@ -2962,896 +2913,108 @@ var chalk = createChalk();
|
|
|
2962
2913
|
var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
2963
2914
|
var source_default = chalk;
|
|
2964
2915
|
|
|
2965
|
-
//
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
|
|
2969
|
-
const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
|
|
2970
|
-
const pattern = `${osc}|${csi}`;
|
|
2971
|
-
return new RegExp(pattern, onlyFirst ? void 0 : "g");
|
|
2972
|
-
}
|
|
2973
|
-
|
|
2974
|
-
// node_modules/strip-ansi/index.js
|
|
2975
|
-
var regex = ansiRegex();
|
|
2976
|
-
function stripAnsi(string) {
|
|
2977
|
-
if (typeof string !== "string") {
|
|
2978
|
-
throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
|
|
2979
|
-
}
|
|
2980
|
-
return string.replace(regex, "");
|
|
2981
|
-
}
|
|
2916
|
+
// src/ui/hooks/useTextInput.ts
|
|
2917
|
+
import { useReducer, useCallback as useCallback6, useEffect as useEffect5, useRef as useRef4 } from "react";
|
|
2918
|
+
import { useInput as useInput6, useStdin } from "ink";
|
|
2982
2919
|
|
|
2983
|
-
//
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9776 && x <= 9783 || x >= 9800 && x <= 9811 || x === 9855 || x >= 9866 && x <= 9871 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12773 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x >= 94192 && x <= 94198 || x >= 94208 && x <= 101589 || x >= 101631 && x <= 101662 || x >= 101760 && x <= 101874 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x >= 119552 && x <= 119638 || x >= 119648 && x <= 119670 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128728 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129674 || x >= 129678 && x <= 129734 || x === 129736 || x >= 129741 && x <= 129756 || x >= 129759 && x <= 129770 || x >= 129775 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
|
|
2920
|
+
// src/ui/hooks/usePanelMouseWheel.ts
|
|
2921
|
+
import process4 from "process";
|
|
2922
|
+
import { useEffect as useEffect4 } from "react";
|
|
2923
|
+
var ENABLE_MOUSE_TRACKING = "\x1B[?1000h\x1B[?1006h";
|
|
2924
|
+
var DISABLE_MOUSE_TRACKING = "\x1B[?1006l\x1B[?1000l";
|
|
2925
|
+
var PANEL_MOUSE_SCROLL_LINES = 3;
|
|
2926
|
+
function contains(rect, col, row) {
|
|
2927
|
+
return col >= rect.left && col <= rect.right && row >= rect.top && row <= rect.bottom;
|
|
2992
2928
|
}
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2929
|
+
function parseSgrWheelEvents(data) {
|
|
2930
|
+
const sgrMouseRe = /\x1B\[<(64|65);(\d+);(\d+)[Mm]/g;
|
|
2931
|
+
const events = [];
|
|
2932
|
+
let match;
|
|
2933
|
+
while ((match = sgrMouseRe.exec(data)) !== null) {
|
|
2934
|
+
events.push({
|
|
2935
|
+
direction: match[1] === "64" ? "up" : "down",
|
|
2936
|
+
col: Number.parseInt(match[2], 10),
|
|
2937
|
+
row: Number.parseInt(match[3], 10)
|
|
2938
|
+
});
|
|
2998
2939
|
}
|
|
2940
|
+
return events;
|
|
2999
2941
|
}
|
|
3000
|
-
function
|
|
3001
|
-
|
|
3002
|
-
if (
|
|
3003
|
-
|
|
3004
|
-
}
|
|
3005
|
-
return 1;
|
|
2942
|
+
function looksLikeMouseEscapeSequence(input) {
|
|
2943
|
+
if (input.length === 0) return false;
|
|
2944
|
+
if (parseSgrWheelEvents(input).length > 0) return true;
|
|
2945
|
+
return /^\[<\d+;\d+;\d+[Mm]$/.test(input) || /^\d+;\d+;\d+[Mm]$/.test(input);
|
|
3006
2946
|
}
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
return zeroWidthClusterRegex.test(segment);
|
|
3018
|
-
}
|
|
3019
|
-
function trailingHalfwidthWidth(segment, eastAsianWidthOptions) {
|
|
3020
|
-
let extra = 0;
|
|
3021
|
-
if (segment.length > 1) {
|
|
3022
|
-
for (const char of segment.slice(1)) {
|
|
3023
|
-
if (char >= "\uFF00" && char <= "\uFFEF") {
|
|
3024
|
-
extra += eastAsianWidth(char.codePointAt(0), eastAsianWidthOptions);
|
|
3025
|
-
}
|
|
3026
|
-
}
|
|
2947
|
+
function parseSgrClickEvents(data) {
|
|
2948
|
+
const sgrMouseRe = /\x1B\[<0;(\d+);(\d+)M/g;
|
|
2949
|
+
const events = [];
|
|
2950
|
+
let match;
|
|
2951
|
+
while ((match = sgrMouseRe.exec(data)) !== null) {
|
|
2952
|
+
events.push({
|
|
2953
|
+
button: "left",
|
|
2954
|
+
col: Number.parseInt(match[1], 10),
|
|
2955
|
+
row: Number.parseInt(match[2], 10)
|
|
2956
|
+
});
|
|
3027
2957
|
}
|
|
3028
|
-
return
|
|
2958
|
+
return events;
|
|
3029
2959
|
}
|
|
3030
|
-
function
|
|
3031
|
-
if (
|
|
3032
|
-
return
|
|
2960
|
+
function resolvePanelTarget(rects, col, row) {
|
|
2961
|
+
if (rects.input && contains(rects.input, col, row)) {
|
|
2962
|
+
return "input";
|
|
3033
2963
|
}
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
countAnsiEscapeCodes = false
|
|
3037
|
-
} = options;
|
|
3038
|
-
let string = input;
|
|
3039
|
-
if (!countAnsiEscapeCodes) {
|
|
3040
|
-
string = stripAnsi(string);
|
|
3041
|
-
}
|
|
3042
|
-
if (string.length === 0) {
|
|
3043
|
-
return 0;
|
|
2964
|
+
if (rects.messages && contains(rects.messages, col, row)) {
|
|
2965
|
+
return "messages";
|
|
3044
2966
|
}
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
for (const { segment } of segmenter.segment(string)) {
|
|
3048
|
-
if (isZeroWidthCluster(segment)) {
|
|
3049
|
-
continue;
|
|
3050
|
-
}
|
|
3051
|
-
if (rgiEmojiRegex.test(segment)) {
|
|
3052
|
-
width += 2;
|
|
3053
|
-
continue;
|
|
3054
|
-
}
|
|
3055
|
-
const codePoint = baseVisible(segment).codePointAt(0);
|
|
3056
|
-
width += eastAsianWidth(codePoint, eastAsianWidthOptions);
|
|
3057
|
-
width += trailingHalfwidthWidth(segment, eastAsianWidthOptions);
|
|
2967
|
+
if (contains(rects.feed, col, row)) {
|
|
2968
|
+
return "feed";
|
|
3058
2969
|
}
|
|
3059
|
-
return
|
|
2970
|
+
return null;
|
|
3060
2971
|
}
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
}
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
cyan: [36, 39],
|
|
3088
|
-
white: [37, 39],
|
|
3089
|
-
// Bright color
|
|
3090
|
-
blackBright: [90, 39],
|
|
3091
|
-
gray: [90, 39],
|
|
3092
|
-
// Alias of `blackBright`
|
|
3093
|
-
grey: [90, 39],
|
|
3094
|
-
// Alias of `blackBright`
|
|
3095
|
-
redBright: [91, 39],
|
|
3096
|
-
greenBright: [92, 39],
|
|
3097
|
-
yellowBright: [93, 39],
|
|
3098
|
-
blueBright: [94, 39],
|
|
3099
|
-
magentaBright: [95, 39],
|
|
3100
|
-
cyanBright: [96, 39],
|
|
3101
|
-
whiteBright: [97, 39]
|
|
3102
|
-
},
|
|
3103
|
-
bgColor: {
|
|
3104
|
-
bgBlack: [40, 49],
|
|
3105
|
-
bgRed: [41, 49],
|
|
3106
|
-
bgGreen: [42, 49],
|
|
3107
|
-
bgYellow: [43, 49],
|
|
3108
|
-
bgBlue: [44, 49],
|
|
3109
|
-
bgMagenta: [45, 49],
|
|
3110
|
-
bgCyan: [46, 49],
|
|
3111
|
-
bgWhite: [47, 49],
|
|
3112
|
-
// Bright color
|
|
3113
|
-
bgBlackBright: [100, 49],
|
|
3114
|
-
bgGray: [100, 49],
|
|
3115
|
-
// Alias of `bgBlackBright`
|
|
3116
|
-
bgGrey: [100, 49],
|
|
3117
|
-
// Alias of `bgBlackBright`
|
|
3118
|
-
bgRedBright: [101, 49],
|
|
3119
|
-
bgGreenBright: [102, 49],
|
|
3120
|
-
bgYellowBright: [103, 49],
|
|
3121
|
-
bgBlueBright: [104, 49],
|
|
3122
|
-
bgMagentaBright: [105, 49],
|
|
3123
|
-
bgCyanBright: [106, 49],
|
|
3124
|
-
bgWhiteBright: [107, 49]
|
|
3125
|
-
}
|
|
3126
|
-
};
|
|
3127
|
-
var modifierNames2 = Object.keys(styles3.modifier);
|
|
3128
|
-
var foregroundColorNames2 = Object.keys(styles3.color);
|
|
3129
|
-
var backgroundColorNames2 = Object.keys(styles3.bgColor);
|
|
3130
|
-
var colorNames2 = [...foregroundColorNames2, ...backgroundColorNames2];
|
|
3131
|
-
function assembleStyles2() {
|
|
3132
|
-
const codes = /* @__PURE__ */ new Map();
|
|
3133
|
-
for (const [groupName, group] of Object.entries(styles3)) {
|
|
3134
|
-
for (const [styleName, style] of Object.entries(group)) {
|
|
3135
|
-
styles3[styleName] = {
|
|
3136
|
-
open: `\x1B[${style[0]}m`,
|
|
3137
|
-
close: `\x1B[${style[1]}m`
|
|
3138
|
-
};
|
|
3139
|
-
group[styleName] = styles3[styleName];
|
|
3140
|
-
codes.set(style[0], style[1]);
|
|
3141
|
-
}
|
|
3142
|
-
Object.defineProperty(styles3, groupName, {
|
|
3143
|
-
value: group,
|
|
3144
|
-
enumerable: false
|
|
3145
|
-
});
|
|
3146
|
-
}
|
|
3147
|
-
Object.defineProperty(styles3, "codes", {
|
|
3148
|
-
value: codes,
|
|
3149
|
-
enumerable: false
|
|
3150
|
-
});
|
|
3151
|
-
styles3.color.close = "\x1B[39m";
|
|
3152
|
-
styles3.bgColor.close = "\x1B[49m";
|
|
3153
|
-
styles3.color.ansi = wrapAnsi162();
|
|
3154
|
-
styles3.color.ansi256 = wrapAnsi2562();
|
|
3155
|
-
styles3.color.ansi16m = wrapAnsi16m2();
|
|
3156
|
-
styles3.bgColor.ansi = wrapAnsi162(ANSI_BACKGROUND_OFFSET2);
|
|
3157
|
-
styles3.bgColor.ansi256 = wrapAnsi2562(ANSI_BACKGROUND_OFFSET2);
|
|
3158
|
-
styles3.bgColor.ansi16m = wrapAnsi16m2(ANSI_BACKGROUND_OFFSET2);
|
|
3159
|
-
Object.defineProperties(styles3, {
|
|
3160
|
-
rgbToAnsi256: {
|
|
3161
|
-
value(red, green, blue) {
|
|
3162
|
-
if (red === green && green === blue) {
|
|
3163
|
-
if (red < 8) {
|
|
3164
|
-
return 16;
|
|
3165
|
-
}
|
|
3166
|
-
if (red > 248) {
|
|
3167
|
-
return 231;
|
|
3168
|
-
}
|
|
3169
|
-
return Math.round((red - 8) / 247 * 24) + 232;
|
|
3170
|
-
}
|
|
3171
|
-
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
|
|
3172
|
-
},
|
|
3173
|
-
enumerable: false
|
|
3174
|
-
},
|
|
3175
|
-
hexToRgb: {
|
|
3176
|
-
value(hex) {
|
|
3177
|
-
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
|
|
3178
|
-
if (!matches) {
|
|
3179
|
-
return [0, 0, 0];
|
|
3180
|
-
}
|
|
3181
|
-
let [colorString] = matches;
|
|
3182
|
-
if (colorString.length === 3) {
|
|
3183
|
-
colorString = [...colorString].map((character) => character + character).join("");
|
|
3184
|
-
}
|
|
3185
|
-
const integer = Number.parseInt(colorString, 16);
|
|
3186
|
-
return [
|
|
3187
|
-
/* eslint-disable no-bitwise */
|
|
3188
|
-
integer >> 16 & 255,
|
|
3189
|
-
integer >> 8 & 255,
|
|
3190
|
-
integer & 255
|
|
3191
|
-
/* eslint-enable no-bitwise */
|
|
3192
|
-
];
|
|
2972
|
+
function buildPanelRects({
|
|
2973
|
+
splitMode,
|
|
2974
|
+
frameWidth,
|
|
2975
|
+
feedStartRow,
|
|
2976
|
+
panelRows,
|
|
2977
|
+
messagePanelWidth,
|
|
2978
|
+
feedPanelWidth,
|
|
2979
|
+
inputStartRow,
|
|
2980
|
+
inputRows
|
|
2981
|
+
}) {
|
|
2982
|
+
const top = feedStartRow;
|
|
2983
|
+
const bottom = feedStartRow + Math.max(0, panelRows - 1);
|
|
2984
|
+
const innerLeft = 2;
|
|
2985
|
+
const inputRect = inputStartRow !== void 0 && inputRows !== void 0 && inputRows > 0 ? {
|
|
2986
|
+
left: innerLeft,
|
|
2987
|
+
right: Math.max(innerLeft, frameWidth - 1),
|
|
2988
|
+
top: inputStartRow,
|
|
2989
|
+
bottom: inputStartRow + inputRows - 1
|
|
2990
|
+
} : void 0;
|
|
2991
|
+
if (!splitMode) {
|
|
2992
|
+
return {
|
|
2993
|
+
feed: {
|
|
2994
|
+
left: innerLeft,
|
|
2995
|
+
right: Math.max(innerLeft, frameWidth - 1),
|
|
2996
|
+
top,
|
|
2997
|
+
bottom
|
|
3193
2998
|
},
|
|
3194
|
-
|
|
2999
|
+
input: inputRect
|
|
3000
|
+
};
|
|
3001
|
+
}
|
|
3002
|
+
const messageLeft = innerLeft;
|
|
3003
|
+
const messageRight = messageLeft + messagePanelWidth;
|
|
3004
|
+
const feedLeft = messageRight + 1;
|
|
3005
|
+
const feedRight = feedLeft + Math.max(0, feedPanelWidth - 1);
|
|
3006
|
+
return {
|
|
3007
|
+
messages: {
|
|
3008
|
+
left: messageLeft,
|
|
3009
|
+
right: messageRight,
|
|
3010
|
+
top,
|
|
3011
|
+
bottom
|
|
3195
3012
|
},
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
value(code) {
|
|
3202
|
-
if (code < 8) {
|
|
3203
|
-
return 30 + code;
|
|
3204
|
-
}
|
|
3205
|
-
if (code < 16) {
|
|
3206
|
-
return 90 + (code - 8);
|
|
3207
|
-
}
|
|
3208
|
-
let red;
|
|
3209
|
-
let green;
|
|
3210
|
-
let blue;
|
|
3211
|
-
if (code >= 232) {
|
|
3212
|
-
red = ((code - 232) * 10 + 8) / 255;
|
|
3213
|
-
green = red;
|
|
3214
|
-
blue = red;
|
|
3215
|
-
} else {
|
|
3216
|
-
code -= 16;
|
|
3217
|
-
const remainder = code % 36;
|
|
3218
|
-
red = Math.floor(code / 36) / 5;
|
|
3219
|
-
green = Math.floor(remainder / 6) / 5;
|
|
3220
|
-
blue = remainder % 6 / 5;
|
|
3221
|
-
}
|
|
3222
|
-
const value = Math.max(red, green, blue) * 2;
|
|
3223
|
-
if (value === 0) {
|
|
3224
|
-
return 30;
|
|
3225
|
-
}
|
|
3226
|
-
let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
|
|
3227
|
-
if (value === 2) {
|
|
3228
|
-
result += 60;
|
|
3229
|
-
}
|
|
3230
|
-
return result;
|
|
3231
|
-
},
|
|
3232
|
-
enumerable: false
|
|
3233
|
-
},
|
|
3234
|
-
rgbToAnsi: {
|
|
3235
|
-
value: (red, green, blue) => styles3.ansi256ToAnsi(styles3.rgbToAnsi256(red, green, blue)),
|
|
3236
|
-
enumerable: false
|
|
3237
|
-
},
|
|
3238
|
-
hexToAnsi: {
|
|
3239
|
-
value: (hex) => styles3.ansi256ToAnsi(styles3.hexToAnsi256(hex)),
|
|
3240
|
-
enumerable: false
|
|
3241
|
-
}
|
|
3242
|
-
});
|
|
3243
|
-
return styles3;
|
|
3244
|
-
}
|
|
3245
|
-
var ansiStyles2 = assembleStyles2();
|
|
3246
|
-
var ansi_styles_default2 = ansiStyles2;
|
|
3247
|
-
|
|
3248
|
-
// node_modules/is-fullwidth-code-point/index.js
|
|
3249
|
-
function isFullwidthCodePoint(codePoint) {
|
|
3250
|
-
if (!Number.isInteger(codePoint)) {
|
|
3251
|
-
return false;
|
|
3252
|
-
}
|
|
3253
|
-
return isFullWidth(codePoint) || isWide(codePoint);
|
|
3254
|
-
}
|
|
3255
|
-
|
|
3256
|
-
// node_modules/slice-ansi/index.js
|
|
3257
|
-
var ESCAPES = /* @__PURE__ */ new Set([27, 155]);
|
|
3258
|
-
var CODE_POINT_0 = "0".codePointAt(0);
|
|
3259
|
-
var CODE_POINT_9 = "9".codePointAt(0);
|
|
3260
|
-
var MAX_ANSI_SEQUENCE_LENGTH = 19;
|
|
3261
|
-
var endCodesSet = /* @__PURE__ */ new Set();
|
|
3262
|
-
var endCodesMap = /* @__PURE__ */ new Map();
|
|
3263
|
-
for (const [start, end] of ansi_styles_default2.codes) {
|
|
3264
|
-
endCodesSet.add(ansi_styles_default2.color.ansi(end));
|
|
3265
|
-
endCodesMap.set(ansi_styles_default2.color.ansi(start), ansi_styles_default2.color.ansi(end));
|
|
3266
|
-
}
|
|
3267
|
-
function getEndCode(code) {
|
|
3268
|
-
if (endCodesSet.has(code)) {
|
|
3269
|
-
return code;
|
|
3270
|
-
}
|
|
3271
|
-
if (endCodesMap.has(code)) {
|
|
3272
|
-
return endCodesMap.get(code);
|
|
3273
|
-
}
|
|
3274
|
-
code = code.slice(2);
|
|
3275
|
-
if (code.includes(";")) {
|
|
3276
|
-
code = code[0] + "0";
|
|
3277
|
-
}
|
|
3278
|
-
const returnValue = ansi_styles_default2.codes.get(Number.parseInt(code, 10));
|
|
3279
|
-
if (returnValue) {
|
|
3280
|
-
return ansi_styles_default2.color.ansi(returnValue);
|
|
3281
|
-
}
|
|
3282
|
-
return ansi_styles_default2.reset.open;
|
|
3283
|
-
}
|
|
3284
|
-
function findNumberIndex(string) {
|
|
3285
|
-
for (let index = 0; index < string.length; index++) {
|
|
3286
|
-
const codePoint = string.codePointAt(index);
|
|
3287
|
-
if (codePoint >= CODE_POINT_0 && codePoint <= CODE_POINT_9) {
|
|
3288
|
-
return index;
|
|
3289
|
-
}
|
|
3290
|
-
}
|
|
3291
|
-
return -1;
|
|
3292
|
-
}
|
|
3293
|
-
function parseAnsiCode(string, offset) {
|
|
3294
|
-
string = string.slice(offset, offset + MAX_ANSI_SEQUENCE_LENGTH);
|
|
3295
|
-
const startIndex = findNumberIndex(string);
|
|
3296
|
-
if (startIndex !== -1) {
|
|
3297
|
-
let endIndex = string.indexOf("m", startIndex);
|
|
3298
|
-
if (endIndex === -1) {
|
|
3299
|
-
endIndex = string.length;
|
|
3300
|
-
}
|
|
3301
|
-
return string.slice(0, endIndex + 1);
|
|
3302
|
-
}
|
|
3303
|
-
}
|
|
3304
|
-
function tokenize(string, endCharacter = Number.POSITIVE_INFINITY) {
|
|
3305
|
-
const returnValue = [];
|
|
3306
|
-
let index = 0;
|
|
3307
|
-
let visibleCount = 0;
|
|
3308
|
-
while (index < string.length) {
|
|
3309
|
-
const codePoint = string.codePointAt(index);
|
|
3310
|
-
if (ESCAPES.has(codePoint)) {
|
|
3311
|
-
const code = parseAnsiCode(string, index);
|
|
3312
|
-
if (code) {
|
|
3313
|
-
returnValue.push({
|
|
3314
|
-
type: "ansi",
|
|
3315
|
-
code,
|
|
3316
|
-
endCode: getEndCode(code)
|
|
3317
|
-
});
|
|
3318
|
-
index += code.length;
|
|
3319
|
-
continue;
|
|
3320
|
-
}
|
|
3321
|
-
}
|
|
3322
|
-
const isFullWidth2 = isFullwidthCodePoint(codePoint);
|
|
3323
|
-
const character = String.fromCodePoint(codePoint);
|
|
3324
|
-
returnValue.push({
|
|
3325
|
-
type: "character",
|
|
3326
|
-
value: character,
|
|
3327
|
-
isFullWidth: isFullWidth2
|
|
3328
|
-
});
|
|
3329
|
-
index += character.length;
|
|
3330
|
-
visibleCount += isFullWidth2 ? 2 : character.length;
|
|
3331
|
-
if (visibleCount >= endCharacter) {
|
|
3332
|
-
break;
|
|
3333
|
-
}
|
|
3334
|
-
}
|
|
3335
|
-
return returnValue;
|
|
3336
|
-
}
|
|
3337
|
-
function reduceAnsiCodes(codes) {
|
|
3338
|
-
let returnValue = [];
|
|
3339
|
-
for (const code of codes) {
|
|
3340
|
-
if (code.code === ansi_styles_default2.reset.open) {
|
|
3341
|
-
returnValue = [];
|
|
3342
|
-
} else if (endCodesSet.has(code.code)) {
|
|
3343
|
-
returnValue = returnValue.filter((returnValueCode) => returnValueCode.endCode !== code.code);
|
|
3344
|
-
} else {
|
|
3345
|
-
returnValue = returnValue.filter((returnValueCode) => returnValueCode.endCode !== code.endCode);
|
|
3346
|
-
returnValue.push(code);
|
|
3347
|
-
}
|
|
3348
|
-
}
|
|
3349
|
-
return returnValue;
|
|
3350
|
-
}
|
|
3351
|
-
function undoAnsiCodes(codes) {
|
|
3352
|
-
const reduced = reduceAnsiCodes(codes);
|
|
3353
|
-
const endCodes = reduced.map(({ endCode }) => endCode);
|
|
3354
|
-
return endCodes.reverse().join("");
|
|
3355
|
-
}
|
|
3356
|
-
function sliceAnsi(string, start, end) {
|
|
3357
|
-
const tokens = tokenize(string, end);
|
|
3358
|
-
let activeCodes = [];
|
|
3359
|
-
let position = 0;
|
|
3360
|
-
let returnValue = "";
|
|
3361
|
-
let include = false;
|
|
3362
|
-
for (const token of tokens) {
|
|
3363
|
-
if (end !== void 0 && position >= end) {
|
|
3364
|
-
break;
|
|
3365
|
-
}
|
|
3366
|
-
if (token.type === "ansi") {
|
|
3367
|
-
activeCodes.push(token);
|
|
3368
|
-
if (include) {
|
|
3369
|
-
returnValue += token.code;
|
|
3370
|
-
}
|
|
3371
|
-
} else {
|
|
3372
|
-
if (!include && position >= start) {
|
|
3373
|
-
include = true;
|
|
3374
|
-
activeCodes = reduceAnsiCodes(activeCodes);
|
|
3375
|
-
returnValue = activeCodes.map(({ code }) => code).join("");
|
|
3376
|
-
}
|
|
3377
|
-
if (include) {
|
|
3378
|
-
returnValue += token.value;
|
|
3379
|
-
}
|
|
3380
|
-
position += token.isFullWidth ? 2 : token.value.length;
|
|
3381
|
-
}
|
|
3382
|
-
}
|
|
3383
|
-
returnValue += undoAnsiCodes(activeCodes);
|
|
3384
|
-
return returnValue;
|
|
3385
|
-
}
|
|
3386
|
-
|
|
3387
|
-
// src/shared/utils/format.ts
|
|
3388
|
-
var SIMPLE_ASCII_RE = /^[\x20-\x7E]*$/;
|
|
3389
|
-
var WIDTH_CACHE_MAX = 2e3;
|
|
3390
|
-
var WIDTH_CACHE_MAX_TEXT_LENGTH = 512;
|
|
3391
|
-
var SPACE_CACHE_MAX = 128;
|
|
3392
|
-
var widthCache = /* @__PURE__ */ new Map();
|
|
3393
|
-
var spaceCache = [""];
|
|
3394
|
-
function cachedStringWidth(text) {
|
|
3395
|
-
if (text.length > WIDTH_CACHE_MAX_TEXT_LENGTH) {
|
|
3396
|
-
return stringWidth(text);
|
|
3397
|
-
}
|
|
3398
|
-
const cached = widthCache.get(text);
|
|
3399
|
-
if (cached !== void 0) {
|
|
3400
|
-
widthCache.delete(text);
|
|
3401
|
-
widthCache.set(text, cached);
|
|
3402
|
-
return cached;
|
|
3403
|
-
}
|
|
3404
|
-
const measured = stringWidth(text);
|
|
3405
|
-
widthCache.set(text, measured);
|
|
3406
|
-
if (widthCache.size > WIDTH_CACHE_MAX) {
|
|
3407
|
-
const oldest = widthCache.keys().next().value;
|
|
3408
|
-
if (oldest !== void 0) {
|
|
3409
|
-
widthCache.delete(oldest);
|
|
3410
|
-
}
|
|
3411
|
-
}
|
|
3412
|
-
return measured;
|
|
3413
|
-
}
|
|
3414
|
-
function spaces(count) {
|
|
3415
|
-
if (count <= 0) return "";
|
|
3416
|
-
if (count < SPACE_CACHE_MAX) {
|
|
3417
|
-
if (count in spaceCache) {
|
|
3418
|
-
return spaceCache[count];
|
|
3419
|
-
}
|
|
3420
|
-
const generated = " ".repeat(count);
|
|
3421
|
-
spaceCache[count] = generated;
|
|
3422
|
-
return generated;
|
|
3423
|
-
}
|
|
3424
|
-
return " ".repeat(count);
|
|
3425
|
-
}
|
|
3426
|
-
function isSimpleAscii(text) {
|
|
3427
|
-
return SIMPLE_ASCII_RE.test(text);
|
|
3428
|
-
}
|
|
3429
|
-
function fitAscii(text, width) {
|
|
3430
|
-
if (width <= 0) return "";
|
|
3431
|
-
const len = text.length;
|
|
3432
|
-
if (len <= width) {
|
|
3433
|
-
const pad = width - len;
|
|
3434
|
-
return pad > 0 ? text + spaces(pad) : text;
|
|
3435
|
-
}
|
|
3436
|
-
if (width <= 3) return text.slice(0, width);
|
|
3437
|
-
return text.slice(0, width - 3) + "...";
|
|
3438
|
-
}
|
|
3439
|
-
function compactText(value, max) {
|
|
3440
|
-
const clean = value.replace(/\s+/g, " ").trim();
|
|
3441
|
-
if (max <= 0) return "";
|
|
3442
|
-
if (isSimpleAscii(clean)) {
|
|
3443
|
-
if (clean.length <= max) return clean;
|
|
3444
|
-
if (max <= 3) return clean.slice(0, max);
|
|
3445
|
-
return clean.slice(0, max - 3) + "...";
|
|
3446
|
-
}
|
|
3447
|
-
const w = cachedStringWidth(clean);
|
|
3448
|
-
if (w <= max) return clean;
|
|
3449
|
-
if (max <= 3) return sliceAnsi(clean, 0, max);
|
|
3450
|
-
return sliceAnsi(clean, 0, max - 3) + "...";
|
|
3451
|
-
}
|
|
3452
|
-
function fit(text, width) {
|
|
3453
|
-
if (isSimpleAscii(text)) {
|
|
3454
|
-
return fitAscii(text, width);
|
|
3455
|
-
}
|
|
3456
|
-
if (width <= 0) return "";
|
|
3457
|
-
const w = cachedStringWidth(text);
|
|
3458
|
-
if (w <= width) {
|
|
3459
|
-
const pad = width - w;
|
|
3460
|
-
return pad > 0 ? text + spaces(pad) : text;
|
|
3461
|
-
}
|
|
3462
|
-
if (width <= 3) return sliceAnsi(text, 0, width);
|
|
3463
|
-
return sliceAnsi(text, 0, width - 3) + "...";
|
|
3464
|
-
}
|
|
3465
|
-
function fitAnsi(text, width) {
|
|
3466
|
-
if (isSimpleAscii(text)) {
|
|
3467
|
-
return fitAscii(text, width);
|
|
3468
|
-
}
|
|
3469
|
-
if (width <= 0) return "";
|
|
3470
|
-
const visualWidth = cachedStringWidth(text);
|
|
3471
|
-
if (visualWidth <= width) {
|
|
3472
|
-
const pad = width - visualWidth;
|
|
3473
|
-
return pad > 0 ? text + spaces(pad) : text;
|
|
3474
|
-
}
|
|
3475
|
-
if (width <= 3) return sliceAnsi(text, 0, width);
|
|
3476
|
-
return sliceAnsi(text, 0, width - 3) + "...";
|
|
3477
|
-
}
|
|
3478
|
-
function centerAnsi(text, width) {
|
|
3479
|
-
if (width <= 0) return "";
|
|
3480
|
-
const visualWidth = cachedStringWidth(text);
|
|
3481
|
-
if (visualWidth >= width) return sliceAnsi(text, 0, width);
|
|
3482
|
-
const left = Math.floor((width - visualWidth) / 2);
|
|
3483
|
-
const right = width - left - visualWidth;
|
|
3484
|
-
return spaces(left) + text + spaces(right);
|
|
3485
|
-
}
|
|
3486
|
-
function formatClock(timestamp) {
|
|
3487
|
-
const d = new Date(timestamp);
|
|
3488
|
-
const hh = String(d.getHours()).padStart(2, "0");
|
|
3489
|
-
const mm = String(d.getMinutes()).padStart(2, "0");
|
|
3490
|
-
return `${hh}:${mm}`;
|
|
3491
|
-
}
|
|
3492
|
-
function formatRunLabel(runId) {
|
|
3493
|
-
if (!runId) return "R-";
|
|
3494
|
-
const direct = runId.match(/^(R\d+)$/i);
|
|
3495
|
-
if (direct) return direct[1].toUpperCase();
|
|
3496
|
-
const tail = runId.replace(/[^a-zA-Z0-9]/g, "").slice(-4);
|
|
3497
|
-
return `R${tail || "-"}`;
|
|
3498
|
-
}
|
|
3499
|
-
function actorLabel(actorId) {
|
|
3500
|
-
if (actorId === "user") return "USER";
|
|
3501
|
-
if (actorId === "agent:root") return "AGENT";
|
|
3502
|
-
if (actorId === "system") return "SYSTEM";
|
|
3503
|
-
if (actorId.startsWith("subagent:")) {
|
|
3504
|
-
return "SUB-AGENT";
|
|
3505
|
-
}
|
|
3506
|
-
return compactText(actorId.toUpperCase(), 12);
|
|
3507
|
-
}
|
|
3508
|
-
function summarizeValue(value) {
|
|
3509
|
-
if (typeof value === "string") return compactText(JSON.stringify(value), 28);
|
|
3510
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
3511
|
-
return String(value);
|
|
3512
|
-
}
|
|
3513
|
-
if (value === null || value === void 0) return String(value);
|
|
3514
|
-
if (Array.isArray(value)) return `[${value.length}]`;
|
|
3515
|
-
if (typeof value === "object") return "{...}";
|
|
3516
|
-
return compactText(String(value), 20);
|
|
3517
|
-
}
|
|
3518
|
-
function summarizeToolInput(input) {
|
|
3519
|
-
const entries = Object.entries(input);
|
|
3520
|
-
const pairs = entries.slice(0, 2).map(([key, value]) => `${key}=${summarizeValue(value)}`);
|
|
3521
|
-
const overflow = entries.length - 2;
|
|
3522
|
-
if (overflow > 0) {
|
|
3523
|
-
pairs.push(`+${overflow}`);
|
|
3524
|
-
}
|
|
3525
|
-
return pairs.join(" ");
|
|
3526
|
-
}
|
|
3527
|
-
function shortenPath(filePath) {
|
|
3528
|
-
const segments = filePath.split("/").filter(Boolean);
|
|
3529
|
-
if (segments.length <= 2) return segments.join("/");
|
|
3530
|
-
return "\u2026/" + segments.slice(-2).join("/");
|
|
3531
|
-
}
|
|
3532
|
-
function compactCommandPaths(cmd) {
|
|
3533
|
-
return cmd.replace(
|
|
3534
|
-
/\/(?:[\w.@-]+\/){2,}[\w.@-]+/g,
|
|
3535
|
-
(match) => shortenPath(match)
|
|
3536
|
-
);
|
|
3537
|
-
}
|
|
3538
|
-
function shortenPathStructured(filePath) {
|
|
3539
|
-
const segments = filePath.split("/").filter(Boolean);
|
|
3540
|
-
if (segments.length === 0) return { prefix: "", filename: filePath };
|
|
3541
|
-
const filename = segments[segments.length - 1];
|
|
3542
|
-
if (segments.length === 1) return { prefix: "", filename };
|
|
3543
|
-
if (segments.length === 2) return { prefix: segments[0] + "/", filename };
|
|
3544
|
-
return { prefix: "\u2026/" + segments[segments.length - 2] + "/", filename };
|
|
3545
|
-
}
|
|
3546
|
-
var filePathExtractor = (input) => shortenPath(String(input.file_path ?? ""));
|
|
3547
|
-
var PRIMARY_INPUT_EXTRACTORS = {
|
|
3548
|
-
Read: filePathExtractor,
|
|
3549
|
-
Write: filePathExtractor,
|
|
3550
|
-
Edit: filePathExtractor,
|
|
3551
|
-
Bash: (input) => compactText(compactCommandPaths(String(input.command ?? "")), 96),
|
|
3552
|
-
Glob: (input) => String(input.pattern ?? ""),
|
|
3553
|
-
Grep: (input) => {
|
|
3554
|
-
const p = `"${String(input.pattern ?? "")}"`;
|
|
3555
|
-
const g = input.glob ? ` ${String(input.glob)}` : "";
|
|
3556
|
-
return p + g;
|
|
3557
|
-
},
|
|
3558
|
-
Task: (input) => compactText(String(input.description ?? ""), 96),
|
|
3559
|
-
Agent: (input) => compactText(String(input.description ?? ""), 96),
|
|
3560
|
-
WebSearch: (input) => `"${String(input.query ?? "")}"`,
|
|
3561
|
-
WebFetch: (input) => compactText(String(input.url ?? ""), 96),
|
|
3562
|
-
Skill: (input) => {
|
|
3563
|
-
const name = String(input.skill ?? "");
|
|
3564
|
-
const colonIdx = name.indexOf(":");
|
|
3565
|
-
return compactText(colonIdx >= 0 ? name.slice(colonIdx + 1) : name, 80);
|
|
3566
|
-
},
|
|
3567
|
-
NotebookEdit: (input) => {
|
|
3568
|
-
const path10 = String(input.notebook_path ?? "");
|
|
3569
|
-
return path10 ? shortenPath(path10) : "";
|
|
3570
|
-
},
|
|
3571
|
-
AskUserQuestion: (input) => {
|
|
3572
|
-
const questions = input.questions;
|
|
3573
|
-
const n = Array.isArray(questions) ? questions.length : 0;
|
|
3574
|
-
return `${n} question${n !== 1 ? "s" : ""}`;
|
|
3575
|
-
}
|
|
3576
|
-
};
|
|
3577
|
-
var eidExtractor = (input) => {
|
|
3578
|
-
const eid = String(input.eid ?? "");
|
|
3579
|
-
return eid ? `eid:${eid.slice(0, 6)}\u2026` : "";
|
|
3580
|
-
};
|
|
3581
|
-
var MCP_INPUT_EXTRACTORS = {
|
|
3582
|
-
navigate: (input) => {
|
|
3583
|
-
const url = String(input.url ?? "");
|
|
3584
|
-
try {
|
|
3585
|
-
const u = new URL(url);
|
|
3586
|
-
return u.hostname.replace(/^www\./, "");
|
|
3587
|
-
} catch {
|
|
3588
|
-
return compactText(url, 96);
|
|
3589
|
-
}
|
|
3590
|
-
},
|
|
3591
|
-
find_elements: (input) => {
|
|
3592
|
-
const parts = [];
|
|
3593
|
-
if (input.kind) parts.push(String(input.kind));
|
|
3594
|
-
if (input.label) parts.push(`"${String(input.label)}"`);
|
|
3595
|
-
if (parts.length === 0 && input.region) parts.push(String(input.region));
|
|
3596
|
-
return parts.join(" ") || "elements";
|
|
3597
|
-
},
|
|
3598
|
-
get_element_details: eidExtractor,
|
|
3599
|
-
click: eidExtractor,
|
|
3600
|
-
type: (input) => {
|
|
3601
|
-
const text = String(input.text ?? "");
|
|
3602
|
-
const eid = input.eid ? String(input.eid).slice(0, 5) + "\u2026" : "";
|
|
3603
|
-
const quoted = `"${compactText(text, 72)}"`;
|
|
3604
|
-
return eid ? `${quoted} \u2192 ${eid}` : quoted;
|
|
3605
|
-
},
|
|
3606
|
-
hover: eidExtractor,
|
|
3607
|
-
select: (input) => {
|
|
3608
|
-
const value = String(input.value ?? "");
|
|
3609
|
-
return value ? `"${compactText(value, 72)}"` : "";
|
|
3610
|
-
},
|
|
3611
|
-
press: (input) => String(input.key ?? ""),
|
|
3612
|
-
scroll_page: (input) => String(input.direction ?? ""),
|
|
3613
|
-
take_screenshot: () => "",
|
|
3614
|
-
close_session: () => "session",
|
|
3615
|
-
close_page: () => ""
|
|
3616
|
-
};
|
|
3617
|
-
function summarizeToolPrimaryInput(toolName, toolInput) {
|
|
3618
|
-
if (toolName in PRIMARY_INPUT_EXTRACTORS) {
|
|
3619
|
-
if (Object.keys(toolInput).length === 0) return "";
|
|
3620
|
-
return PRIMARY_INPUT_EXTRACTORS[toolName](toolInput);
|
|
3621
|
-
}
|
|
3622
|
-
const parsed = parseToolName(toolName);
|
|
3623
|
-
if (parsed.isMcp && parsed.mcpAction) {
|
|
3624
|
-
if (parsed.mcpAction in MCP_INPUT_EXTRACTORS) {
|
|
3625
|
-
return MCP_INPUT_EXTRACTORS[parsed.mcpAction](toolInput);
|
|
3626
|
-
}
|
|
3627
|
-
}
|
|
3628
|
-
if (Object.keys(toolInput).length === 0) return "";
|
|
3629
|
-
return summarizeToolInput(toolInput);
|
|
3630
|
-
}
|
|
3631
|
-
var MAX_INPUT_ROWS = 6;
|
|
3632
|
-
var CURSOR_ON = "\x1B[7m";
|
|
3633
|
-
var CURSOR_OFF = "\x1B[27m";
|
|
3634
|
-
function cursorToVisualPosition(value, cursorOffset, width) {
|
|
3635
|
-
if (width <= 0) return { line: 0, col: cursorOffset, totalLines: 1 };
|
|
3636
|
-
const segments = value.split("\n");
|
|
3637
|
-
let visualLine = 0;
|
|
3638
|
-
let globalOffset = 0;
|
|
3639
|
-
for (let s = 0; s < segments.length; s++) {
|
|
3640
|
-
const seg = segments[s];
|
|
3641
|
-
const segEnd = globalOffset + seg.length;
|
|
3642
|
-
if (cursorOffset <= segEnd) {
|
|
3643
|
-
const posInSeg = cursorOffset - globalOffset;
|
|
3644
|
-
const totalLines2 = visualLine + countSegmentVisualLines(segments, s, width);
|
|
3645
|
-
if (seg.length === 0) {
|
|
3646
|
-
return { line: visualLine, col: 0, totalLines: totalLines2 };
|
|
3647
|
-
}
|
|
3648
|
-
const lineInSeg = Math.min(
|
|
3649
|
-
Math.floor(posInSeg / width),
|
|
3650
|
-
segmentVisualLines(seg.length, width) - 1
|
|
3651
|
-
);
|
|
3652
|
-
const colInLine = posInSeg - lineInSeg * width;
|
|
3653
|
-
return { line: visualLine + lineInSeg, col: colInLine, totalLines: totalLines2 };
|
|
3654
|
-
}
|
|
3655
|
-
visualLine += segmentVisualLines(seg.length, width);
|
|
3656
|
-
globalOffset = segEnd + 1;
|
|
3657
|
-
}
|
|
3658
|
-
const totalLines = wrapText(value, width).length;
|
|
3659
|
-
return { line: Math.max(0, totalLines - 1), col: 0, totalLines };
|
|
3660
|
-
}
|
|
3661
|
-
function segmentVisualLines(segLen, width) {
|
|
3662
|
-
return segLen === 0 ? 1 : Math.ceil(segLen / width);
|
|
3663
|
-
}
|
|
3664
|
-
function countSegmentVisualLines(segments, fromIdx, width) {
|
|
3665
|
-
let count = 0;
|
|
3666
|
-
for (let i = fromIdx; i < segments.length; i++) {
|
|
3667
|
-
count += segmentVisualLines(segments[i].length, width);
|
|
3668
|
-
}
|
|
3669
|
-
return count;
|
|
3670
|
-
}
|
|
3671
|
-
function visualPositionToOffset(value, targetLine, targetCol, width) {
|
|
3672
|
-
if (width <= 0) return targetCol;
|
|
3673
|
-
const segments = value.split("\n");
|
|
3674
|
-
let visualLine = 0;
|
|
3675
|
-
let globalOffset = 0;
|
|
3676
|
-
for (let s = 0; s < segments.length; s++) {
|
|
3677
|
-
const seg = segments[s];
|
|
3678
|
-
const numWrappedLines = segmentVisualLines(seg.length, width);
|
|
3679
|
-
if (targetLine < visualLine + numWrappedLines) {
|
|
3680
|
-
const lineInSeg = targetLine - visualLine;
|
|
3681
|
-
const lineStart = lineInSeg * width;
|
|
3682
|
-
const lineLen = Math.min(width, seg.length - lineStart);
|
|
3683
|
-
return globalOffset + lineStart + Math.min(targetCol, lineLen);
|
|
3684
|
-
}
|
|
3685
|
-
visualLine += numWrappedLines;
|
|
3686
|
-
globalOffset += seg.length + 1;
|
|
3687
|
-
}
|
|
3688
|
-
return value.length;
|
|
3689
|
-
}
|
|
3690
|
-
function renderInputLines(value, cursorOffset, width, showCursor, placeholder) {
|
|
3691
|
-
if (width <= 0) return [""];
|
|
3692
|
-
if (value.length === 0) {
|
|
3693
|
-
if (!showCursor) return [fit(placeholder, width)];
|
|
3694
|
-
const cursor = `${CURSOR_ON} ${CURSOR_OFF}`;
|
|
3695
|
-
return [cursor + fit(placeholder, width - 1)];
|
|
3696
|
-
}
|
|
3697
|
-
if (!showCursor) {
|
|
3698
|
-
const rawLines2 = wrapText(value, width);
|
|
3699
|
-
const visible = rawLines2.slice(0, MAX_INPUT_ROWS);
|
|
3700
|
-
return visible.map((line) => fit(line, width));
|
|
3701
|
-
}
|
|
3702
|
-
const rawLines = wrapText(value, width);
|
|
3703
|
-
const { line: cursorLine, col: cursorCol } = cursorToVisualPosition(
|
|
3704
|
-
value,
|
|
3705
|
-
cursorOffset,
|
|
3706
|
-
width
|
|
3707
|
-
);
|
|
3708
|
-
let viewStart = 0;
|
|
3709
|
-
if (rawLines.length > MAX_INPUT_ROWS) {
|
|
3710
|
-
viewStart = Math.max(
|
|
3711
|
-
0,
|
|
3712
|
-
Math.min(
|
|
3713
|
-
cursorLine - Math.floor(MAX_INPUT_ROWS / 2),
|
|
3714
|
-
rawLines.length - MAX_INPUT_ROWS
|
|
3715
|
-
)
|
|
3716
|
-
);
|
|
3717
|
-
}
|
|
3718
|
-
const visibleLines = rawLines.slice(viewStart, viewStart + MAX_INPUT_ROWS);
|
|
3719
|
-
return visibleLines.map((line, i) => {
|
|
3720
|
-
const globalIdx = viewStart + i;
|
|
3721
|
-
if (globalIdx === cursorLine) {
|
|
3722
|
-
const before = line.slice(0, cursorCol);
|
|
3723
|
-
const charAtCursor = cursorCol < line.length ? line[cursorCol] : " ";
|
|
3724
|
-
const after = cursorCol < line.length ? line.slice(cursorCol + 1) : "";
|
|
3725
|
-
const rendered = `${before}${CURSOR_ON}${charAtCursor}${CURSOR_OFF}${after}`;
|
|
3726
|
-
return fitAnsi(rendered, width);
|
|
3727
|
-
}
|
|
3728
|
-
return fit(line, width);
|
|
3729
|
-
});
|
|
3730
|
-
}
|
|
3731
|
-
function wrapText(text, width) {
|
|
3732
|
-
if (width <= 0) return [text];
|
|
3733
|
-
const lines = [];
|
|
3734
|
-
for (const segment of text.split("\n")) {
|
|
3735
|
-
if (segment.length === 0) {
|
|
3736
|
-
lines.push("");
|
|
3737
|
-
continue;
|
|
3738
|
-
}
|
|
3739
|
-
for (let i = 0; i < segment.length; i += width) {
|
|
3740
|
-
lines.push(segment.slice(i, i + width));
|
|
3741
|
-
}
|
|
3742
|
-
}
|
|
3743
|
-
return lines;
|
|
3744
|
-
}
|
|
3745
|
-
function computeInputRows(value, width) {
|
|
3746
|
-
if (!value || width <= 0) return 1;
|
|
3747
|
-
return Math.max(1, Math.min(wrapText(value, width).length, MAX_INPUT_ROWS));
|
|
3748
|
-
}
|
|
3749
|
-
function isCommandPrefix(value) {
|
|
3750
|
-
return value.startsWith("/") && !value.includes(" ");
|
|
3751
|
-
}
|
|
3752
|
-
|
|
3753
|
-
// src/ui/hooks/useTextInput.ts
|
|
3754
|
-
import { useReducer, useCallback as useCallback6, useEffect as useEffect5, useRef as useRef4 } from "react";
|
|
3755
|
-
import { useInput as useInput6, useStdin } from "ink";
|
|
3756
|
-
|
|
3757
|
-
// src/ui/hooks/usePanelMouseWheel.ts
|
|
3758
|
-
import process4 from "process";
|
|
3759
|
-
import { useEffect as useEffect4 } from "react";
|
|
3760
|
-
var ENABLE_MOUSE_TRACKING = "\x1B[?1000h\x1B[?1006h";
|
|
3761
|
-
var DISABLE_MOUSE_TRACKING = "\x1B[?1006l\x1B[?1000l";
|
|
3762
|
-
var PANEL_MOUSE_SCROLL_LINES = 3;
|
|
3763
|
-
function contains(rect, col, row) {
|
|
3764
|
-
return col >= rect.left && col <= rect.right && row >= rect.top && row <= rect.bottom;
|
|
3765
|
-
}
|
|
3766
|
-
function parseSgrWheelEvents(data) {
|
|
3767
|
-
const sgrMouseRe = /\x1B\[<(64|65);(\d+);(\d+)[Mm]/g;
|
|
3768
|
-
const events = [];
|
|
3769
|
-
let match;
|
|
3770
|
-
while ((match = sgrMouseRe.exec(data)) !== null) {
|
|
3771
|
-
events.push({
|
|
3772
|
-
direction: match[1] === "64" ? "up" : "down",
|
|
3773
|
-
col: Number.parseInt(match[2], 10),
|
|
3774
|
-
row: Number.parseInt(match[3], 10)
|
|
3775
|
-
});
|
|
3776
|
-
}
|
|
3777
|
-
return events;
|
|
3778
|
-
}
|
|
3779
|
-
function looksLikeMouseEscapeSequence(input) {
|
|
3780
|
-
if (input.length === 0) return false;
|
|
3781
|
-
if (parseSgrWheelEvents(input).length > 0) return true;
|
|
3782
|
-
return /^\[<\d+;\d+;\d+[Mm]$/.test(input) || /^\d+;\d+;\d+[Mm]$/.test(input);
|
|
3783
|
-
}
|
|
3784
|
-
function parseSgrClickEvents(data) {
|
|
3785
|
-
const sgrMouseRe = /\x1B\[<0;(\d+);(\d+)M/g;
|
|
3786
|
-
const events = [];
|
|
3787
|
-
let match;
|
|
3788
|
-
while ((match = sgrMouseRe.exec(data)) !== null) {
|
|
3789
|
-
events.push({
|
|
3790
|
-
button: "left",
|
|
3791
|
-
col: Number.parseInt(match[1], 10),
|
|
3792
|
-
row: Number.parseInt(match[2], 10)
|
|
3793
|
-
});
|
|
3794
|
-
}
|
|
3795
|
-
return events;
|
|
3796
|
-
}
|
|
3797
|
-
function resolvePanelTarget(rects, col, row) {
|
|
3798
|
-
if (rects.input && contains(rects.input, col, row)) {
|
|
3799
|
-
return "input";
|
|
3800
|
-
}
|
|
3801
|
-
if (rects.messages && contains(rects.messages, col, row)) {
|
|
3802
|
-
return "messages";
|
|
3803
|
-
}
|
|
3804
|
-
if (contains(rects.feed, col, row)) {
|
|
3805
|
-
return "feed";
|
|
3806
|
-
}
|
|
3807
|
-
return null;
|
|
3808
|
-
}
|
|
3809
|
-
function buildPanelRects({
|
|
3810
|
-
splitMode,
|
|
3811
|
-
frameWidth,
|
|
3812
|
-
feedStartRow,
|
|
3813
|
-
panelRows,
|
|
3814
|
-
messagePanelWidth,
|
|
3815
|
-
feedPanelWidth,
|
|
3816
|
-
inputStartRow,
|
|
3817
|
-
inputRows
|
|
3818
|
-
}) {
|
|
3819
|
-
const top = feedStartRow;
|
|
3820
|
-
const bottom = feedStartRow + Math.max(0, panelRows - 1);
|
|
3821
|
-
const innerLeft = 2;
|
|
3822
|
-
const inputRect = inputStartRow !== void 0 && inputRows !== void 0 && inputRows > 0 ? {
|
|
3823
|
-
left: innerLeft,
|
|
3824
|
-
right: Math.max(innerLeft, frameWidth - 1),
|
|
3825
|
-
top: inputStartRow,
|
|
3826
|
-
bottom: inputStartRow + inputRows - 1
|
|
3827
|
-
} : void 0;
|
|
3828
|
-
if (!splitMode) {
|
|
3829
|
-
return {
|
|
3830
|
-
feed: {
|
|
3831
|
-
left: innerLeft,
|
|
3832
|
-
right: Math.max(innerLeft, frameWidth - 1),
|
|
3833
|
-
top,
|
|
3834
|
-
bottom
|
|
3835
|
-
},
|
|
3836
|
-
input: inputRect
|
|
3837
|
-
};
|
|
3838
|
-
}
|
|
3839
|
-
const messageLeft = innerLeft;
|
|
3840
|
-
const messageRight = messageLeft + messagePanelWidth;
|
|
3841
|
-
const feedLeft = messageRight + 1;
|
|
3842
|
-
const feedRight = feedLeft + Math.max(0, feedPanelWidth - 1);
|
|
3843
|
-
return {
|
|
3844
|
-
messages: {
|
|
3845
|
-
left: messageLeft,
|
|
3846
|
-
right: messageRight,
|
|
3847
|
-
top,
|
|
3848
|
-
bottom
|
|
3849
|
-
},
|
|
3850
|
-
feed: {
|
|
3851
|
-
left: feedLeft,
|
|
3852
|
-
right: feedRight,
|
|
3853
|
-
top,
|
|
3854
|
-
bottom
|
|
3013
|
+
feed: {
|
|
3014
|
+
left: feedLeft,
|
|
3015
|
+
right: feedRight,
|
|
3016
|
+
top,
|
|
3017
|
+
bottom
|
|
3855
3018
|
},
|
|
3856
3019
|
input: inputRect
|
|
3857
3020
|
};
|
|
@@ -4639,7 +3802,7 @@ function useTodoPanel({
|
|
|
4639
3802
|
const todoItemsCacheRef = useRef7(null);
|
|
4640
3803
|
const nextTodoItems = (() => {
|
|
4641
3804
|
const fromTasks = tasks.map((task, index) => ({
|
|
4642
|
-
id: `task-${index}-${task.content.replace(/[^a-zA-Z0-9]/g, "").slice(0, 16)}`,
|
|
3805
|
+
id: (task.taskId ? `task-${task.taskId}` : void 0) ?? `task-${index}-${task.content.replace(/[^a-zA-Z0-9]/g, "").slice(0, 16)}`,
|
|
4643
3806
|
text: task.content,
|
|
4644
3807
|
priority: "P1",
|
|
4645
3808
|
status: toTodoStatus(task.status),
|
|
@@ -4944,2360 +4107,152 @@ function useMessageKeyboard({
|
|
|
4944
4107
|
if (key.upArrow) {
|
|
4945
4108
|
callbacks.moveCursor(-1);
|
|
4946
4109
|
return;
|
|
4947
|
-
}
|
|
4948
|
-
if (key.downArrow) {
|
|
4949
|
-
callbacks.moveCursor(1);
|
|
4950
|
-
return;
|
|
4951
|
-
}
|
|
4952
|
-
} finally {
|
|
4953
|
-
done();
|
|
4954
|
-
}
|
|
4955
|
-
},
|
|
4956
|
-
{ isActive }
|
|
4957
|
-
);
|
|
4958
|
-
}
|
|
4959
|
-
|
|
4960
|
-
// src/ui/hooks/useTodoKeyboard.ts
|
|
4961
|
-
import { useRef as useRef8 } from "react";
|
|
4962
|
-
import { useInput as useInput10 } from "ink";
|
|
4963
|
-
function useTodoKeyboard({
|
|
4964
|
-
isActive,
|
|
4965
|
-
todoCursor,
|
|
4966
|
-
visibleTodoItems,
|
|
4967
|
-
filteredEntries,
|
|
4968
|
-
callbacks
|
|
4969
|
-
}) {
|
|
4970
|
-
const visibleTodoItemsRef = useRef8(visibleTodoItems);
|
|
4971
|
-
visibleTodoItemsRef.current = visibleTodoItems;
|
|
4972
|
-
const filteredEntriesRef = useRef8(filteredEntries);
|
|
4973
|
-
filteredEntriesRef.current = filteredEntries;
|
|
4974
|
-
useInput10(
|
|
4975
|
-
(input, key) => {
|
|
4976
|
-
const done = startInputMeasure("todo.keyboard", input, key);
|
|
4977
|
-
try {
|
|
4978
|
-
if (key.escape) {
|
|
4979
|
-
callbacks.focusFeed();
|
|
4980
|
-
return;
|
|
4981
|
-
}
|
|
4982
|
-
if (key.tab) {
|
|
4983
|
-
callbacks.cycleFocus();
|
|
4984
|
-
return;
|
|
4985
|
-
}
|
|
4986
|
-
if (key.upArrow) {
|
|
4987
|
-
callbacks.moveTodoCursor(-1);
|
|
4988
|
-
return;
|
|
4989
|
-
}
|
|
4990
|
-
if (key.downArrow) {
|
|
4991
|
-
callbacks.moveTodoCursor(1);
|
|
4992
|
-
return;
|
|
4993
|
-
}
|
|
4994
|
-
if (input === " ") {
|
|
4995
|
-
callbacks.toggleTodoStatus(todoCursor);
|
|
4996
|
-
return;
|
|
4997
|
-
}
|
|
4998
|
-
if (key.return) {
|
|
4999
|
-
if (todoCursor < 0 || todoCursor >= visibleTodoItemsRef.current.length) {
|
|
5000
|
-
return;
|
|
5001
|
-
}
|
|
5002
|
-
const selected = visibleTodoItemsRef.current[todoCursor];
|
|
5003
|
-
if (!selected.linkedEventId) return;
|
|
5004
|
-
const idx = filteredEntriesRef.current.findIndex(
|
|
5005
|
-
(entry) => entry.id === selected.linkedEventId
|
|
5006
|
-
);
|
|
5007
|
-
if (idx >= 0) {
|
|
5008
|
-
callbacks.revealFeedCursor(idx);
|
|
5009
|
-
}
|
|
5010
|
-
return;
|
|
5011
|
-
}
|
|
5012
|
-
if (input.toLowerCase() === "a") {
|
|
5013
|
-
callbacks.openNormalInput();
|
|
5014
|
-
callbacks.setInputValue("");
|
|
5015
|
-
return;
|
|
5016
|
-
}
|
|
5017
|
-
} finally {
|
|
5018
|
-
done();
|
|
5019
|
-
}
|
|
5020
|
-
},
|
|
5021
|
-
{ isActive }
|
|
5022
|
-
);
|
|
5023
|
-
}
|
|
5024
|
-
|
|
5025
|
-
// src/ui/hooks/useSpinner.ts
|
|
5026
|
-
import { useState as useState8, useEffect as useEffect7 } from "react";
|
|
5027
|
-
var BRAILLE_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
5028
|
-
var DEFAULT_SPINNER_INTERVAL_MS = 1e3;
|
|
5029
|
-
function useSpinner(active, intervalMs = DEFAULT_SPINNER_INTERVAL_MS) {
|
|
5030
|
-
const [frameIndex, setFrameIndex] = useState8(0);
|
|
5031
|
-
useEffect7(() => {
|
|
5032
|
-
if (!active) {
|
|
5033
|
-
setFrameIndex(0);
|
|
5034
|
-
return;
|
|
5035
|
-
}
|
|
5036
|
-
const timer = setInterval(() => {
|
|
5037
|
-
startPerfCycle("timer:spinner", { scope: "spinner" });
|
|
5038
|
-
setFrameIndex((i) => (i + 1) % BRAILLE_FRAMES.length);
|
|
5039
|
-
}, intervalMs);
|
|
5040
|
-
return () => clearInterval(timer);
|
|
5041
|
-
}, [active, intervalMs]);
|
|
5042
|
-
if (!active) return "";
|
|
5043
|
-
return BRAILLE_FRAMES[frameIndex] ?? "\u280B";
|
|
5044
|
-
}
|
|
5045
|
-
|
|
5046
|
-
// src/ui/hooks/useTodoDisplayItems.ts
|
|
5047
|
-
import { useEffect as useEffect8, useMemo as useMemo8, useState as useState9 } from "react";
|
|
5048
|
-
function hasTickingElapsedItems(items) {
|
|
5049
|
-
return items.some(
|
|
5050
|
-
(item) => item.status === "doing" && item.startedAtMs !== void 0
|
|
5051
|
-
);
|
|
5052
|
-
}
|
|
5053
|
-
function buildTodoDisplayItems(items, nowMs, isWorking, pausedAtMs) {
|
|
5054
|
-
let changed = false;
|
|
5055
|
-
const nextItems = items.map((item) => {
|
|
5056
|
-
const hasElapsed = item.startedAtMs !== void 0 && (item.status === "doing" || item.status === "done" || item.status === "failed");
|
|
5057
|
-
const endMs = item.completedAtMs ?? (isWorking ? nowMs : pausedAtMs ?? nowMs);
|
|
5058
|
-
const elapsed = hasElapsed ? formatElapsed(Math.max(0, endMs - item.startedAtMs)) : void 0;
|
|
5059
|
-
if (elapsed === item.elapsed) return item;
|
|
5060
|
-
changed = true;
|
|
5061
|
-
return { ...item, elapsed };
|
|
5062
|
-
});
|
|
5063
|
-
return changed ? nextItems : items;
|
|
5064
|
-
}
|
|
5065
|
-
function useTodoDisplayItems({
|
|
5066
|
-
items,
|
|
5067
|
-
isWorking,
|
|
5068
|
-
pausedAtMs,
|
|
5069
|
-
active,
|
|
5070
|
-
tickMs = 1e3
|
|
5071
|
-
}) {
|
|
5072
|
-
const [nowMs, setNowMs] = useState9(() => Date.now());
|
|
5073
|
-
const hasDoingItems = useMemo8(() => hasTickingElapsedItems(items), [items]);
|
|
5074
|
-
useEffect8(() => {
|
|
5075
|
-
if (!active || !isWorking || !hasDoingItems) return;
|
|
5076
|
-
const id = setInterval(() => {
|
|
5077
|
-
startPerfCycle("timer:todo-header", {
|
|
5078
|
-
scope: "todo.elapsed",
|
|
5079
|
-
items: items.length
|
|
5080
|
-
});
|
|
5081
|
-
setNowMs(Date.now());
|
|
5082
|
-
}, tickMs);
|
|
5083
|
-
return () => clearInterval(id);
|
|
5084
|
-
}, [active, isWorking, hasDoingItems, items.length, tickMs]);
|
|
5085
|
-
return useMemo8(
|
|
5086
|
-
() => buildTodoDisplayItems(items, nowMs, isWorking, pausedAtMs),
|
|
5087
|
-
[items, nowMs, isWorking, pausedAtMs]
|
|
5088
|
-
);
|
|
5089
|
-
}
|
|
5090
|
-
|
|
5091
|
-
// src/ui/hooks/useTimeline.ts
|
|
5092
|
-
import { useMemo as useMemo9, useRef as useRef9, useCallback as useCallback10 } from "react";
|
|
5093
|
-
|
|
5094
|
-
// src/shared/utils/toolResponse.ts
|
|
5095
|
-
function isRecord(value) {
|
|
5096
|
-
return typeof value === "object" && value !== null;
|
|
5097
|
-
}
|
|
5098
|
-
function formatToolResponse(response) {
|
|
5099
|
-
if (response == null) return "";
|
|
5100
|
-
if (typeof response === "string") return response.trim();
|
|
5101
|
-
if (Array.isArray(response)) {
|
|
5102
|
-
const parts = [];
|
|
5103
|
-
for (const block of response) {
|
|
5104
|
-
if (!isRecord(block)) continue;
|
|
5105
|
-
if (block["type"] === "image") {
|
|
5106
|
-
parts.push("[image]");
|
|
5107
|
-
} else if (typeof block["text"] === "string") {
|
|
5108
|
-
parts.push(block["text"]);
|
|
5109
|
-
}
|
|
5110
|
-
}
|
|
5111
|
-
if (parts.length > 0) return parts.join("\n").trim();
|
|
5112
|
-
return JSON.stringify(response, null, 2);
|
|
5113
|
-
}
|
|
5114
|
-
if (isRecord(response)) {
|
|
5115
|
-
if (typeof response["text"] === "string" && response["type"] === "text") {
|
|
5116
|
-
return response["text"].trim();
|
|
5117
|
-
}
|
|
5118
|
-
if ("content" in response && response["content"] != null) {
|
|
5119
|
-
return formatToolResponse(response["content"]);
|
|
5120
|
-
}
|
|
5121
|
-
return Object.entries(response).map(([key, val]) => {
|
|
5122
|
-
const valStr = typeof val === "string" ? val : JSON.stringify(val);
|
|
5123
|
-
return ` ${key}: ${valStr}`;
|
|
5124
|
-
}).join("\n");
|
|
5125
|
-
}
|
|
5126
|
-
return String(response);
|
|
5127
|
-
}
|
|
5128
|
-
function isBashToolResponse(response) {
|
|
5129
|
-
return isRecord(response) && typeof response["stdout"] === "string";
|
|
5130
|
-
}
|
|
5131
|
-
|
|
5132
|
-
// src/core/feed/toolSummary.ts
|
|
5133
|
-
function prop(obj, key) {
|
|
5134
|
-
if (typeof obj === "object" && obj !== null) {
|
|
5135
|
-
return obj[key];
|
|
5136
|
-
}
|
|
5137
|
-
return void 0;
|
|
5138
|
-
}
|
|
5139
|
-
function extractFileContent(response) {
|
|
5140
|
-
if (Array.isArray(response)) {
|
|
5141
|
-
for (const block of response) {
|
|
5142
|
-
const fc = prop(prop(block, "file"), "content");
|
|
5143
|
-
if (typeof fc === "string") return fc;
|
|
5144
|
-
const text = prop(block, "text");
|
|
5145
|
-
if (typeof text === "string") return text;
|
|
5146
|
-
}
|
|
5147
|
-
}
|
|
5148
|
-
return void 0;
|
|
5149
|
-
}
|
|
5150
|
-
function summarizeBash(_input, response) {
|
|
5151
|
-
if (isBashToolResponse(response)) {
|
|
5152
|
-
const exitCode = prop(response, "exitCode") ?? 0;
|
|
5153
|
-
const stderr = response.stderr.trim();
|
|
5154
|
-
const firstLine = stderr.split("\n")[0] ?? "";
|
|
5155
|
-
if (stderr && Number(exitCode) !== 0) {
|
|
5156
|
-
return `exit ${exitCode} \u2014 ${firstLine}`;
|
|
5157
|
-
}
|
|
5158
|
-
return `exit ${exitCode}`;
|
|
5159
|
-
}
|
|
5160
|
-
return "";
|
|
5161
|
-
}
|
|
5162
|
-
function summarizeRead(_input, response) {
|
|
5163
|
-
const content = extractFileContent(response);
|
|
5164
|
-
if (content) {
|
|
5165
|
-
const lines = content.split("\n").length;
|
|
5166
|
-
return `${lines} lines`;
|
|
5167
|
-
}
|
|
5168
|
-
return "";
|
|
5169
|
-
}
|
|
5170
|
-
function summarizeEdit(input, _response) {
|
|
5171
|
-
const oldStr = typeof input["old_string"] === "string" ? input["old_string"] : "";
|
|
5172
|
-
const newStr = typeof input["new_string"] === "string" ? input["new_string"] : "";
|
|
5173
|
-
const oldLines = oldStr.split("\n").length;
|
|
5174
|
-
const newLines = newStr.split("\n").length;
|
|
5175
|
-
return `replaced ${oldLines} \u2192 ${newLines} lines`;
|
|
5176
|
-
}
|
|
5177
|
-
function summarizeWrite(_input, _response) {
|
|
5178
|
-
return "";
|
|
5179
|
-
}
|
|
5180
|
-
function summarizeGlob(_input, response) {
|
|
5181
|
-
const filenames = prop(response, "filenames");
|
|
5182
|
-
if (Array.isArray(filenames))
|
|
5183
|
-
return `${filenames.length} ${filenames.length === 1 ? "file" : "files"}`;
|
|
5184
|
-
const numFiles = prop(response, "numFiles");
|
|
5185
|
-
if (typeof numFiles === "number")
|
|
5186
|
-
return `${numFiles} ${numFiles === 1 ? "file" : "files"}`;
|
|
5187
|
-
return "";
|
|
5188
|
-
}
|
|
5189
|
-
function summarizeGrep(_input, response) {
|
|
5190
|
-
if (typeof response === "string") {
|
|
5191
|
-
const matches = response.split("\n").filter(Boolean).length;
|
|
5192
|
-
return `${matches} matches`;
|
|
5193
|
-
}
|
|
5194
|
-
if (typeof response === "object" && response !== null) {
|
|
5195
|
-
const numMatches = prop(response, "numMatches");
|
|
5196
|
-
if (typeof numMatches === "number") return `${numMatches} matches`;
|
|
5197
|
-
const count = prop(response, "count");
|
|
5198
|
-
if (typeof count === "number") return `${count} matches`;
|
|
5199
|
-
}
|
|
5200
|
-
return "";
|
|
5201
|
-
}
|
|
5202
|
-
function summarizeWebSearch(_input, response) {
|
|
5203
|
-
const results = prop(response, "results");
|
|
5204
|
-
if (Array.isArray(results)) {
|
|
5205
|
-
let count = 0;
|
|
5206
|
-
for (const entry of results) {
|
|
5207
|
-
const content = prop(entry, "content");
|
|
5208
|
-
count += Array.isArray(content) ? content.length : 1;
|
|
5209
|
-
}
|
|
5210
|
-
return `${count} results`;
|
|
5211
|
-
}
|
|
5212
|
-
const actionType = prop(response, "type");
|
|
5213
|
-
if (typeof actionType === "string") {
|
|
5214
|
-
return actionType.replace(/_/g, " ");
|
|
5215
|
-
}
|
|
5216
|
-
return "";
|
|
5217
|
-
}
|
|
5218
|
-
function summarizeTask(input, _response) {
|
|
5219
|
-
const agentType = input["subagent_type"] ?? "agent";
|
|
5220
|
-
return String(agentType);
|
|
5221
|
-
}
|
|
5222
|
-
var SUMMARIZERS = {
|
|
5223
|
-
Bash: summarizeBash,
|
|
5224
|
-
Read: summarizeRead,
|
|
5225
|
-
Edit: summarizeEdit,
|
|
5226
|
-
Write: summarizeWrite,
|
|
5227
|
-
Glob: summarizeGlob,
|
|
5228
|
-
Grep: summarizeGrep,
|
|
5229
|
-
WebSearch: summarizeWebSearch,
|
|
5230
|
-
Task: summarizeTask,
|
|
5231
|
-
Agent: summarizeTask
|
|
5232
|
-
};
|
|
5233
|
-
function summarizeFindElements(_input, response) {
|
|
5234
|
-
if (typeof response === "object" && response !== null) {
|
|
5235
|
-
const elements = prop(response, "elements") ?? prop(response, "items");
|
|
5236
|
-
if (Array.isArray(elements)) return `${elements.length} found`;
|
|
5237
|
-
if (Array.isArray(response)) return `${response.length} found`;
|
|
5238
|
-
}
|
|
5239
|
-
return "";
|
|
5240
|
-
}
|
|
5241
|
-
var MCP_SUMMARIZERS = {
|
|
5242
|
-
find_elements: summarizeFindElements
|
|
5243
|
-
};
|
|
5244
|
-
function summarizeToolResult(toolName, toolInput, toolResponse, error) {
|
|
5245
|
-
if (error) {
|
|
5246
|
-
const firstLine = error.split("\n")[0] ?? error;
|
|
5247
|
-
return compactText(firstLine, 160);
|
|
5248
|
-
}
|
|
5249
|
-
if (toolName in SUMMARIZERS) {
|
|
5250
|
-
try {
|
|
5251
|
-
return SUMMARIZERS[toolName](toolInput, toolResponse);
|
|
5252
|
-
} catch {
|
|
5253
|
-
return "";
|
|
5254
|
-
}
|
|
5255
|
-
}
|
|
5256
|
-
const parsed = parseToolName(toolName);
|
|
5257
|
-
if (parsed.isMcp && parsed.mcpAction) {
|
|
5258
|
-
if (parsed.mcpAction in MCP_SUMMARIZERS) {
|
|
5259
|
-
try {
|
|
5260
|
-
return MCP_SUMMARIZERS[parsed.mcpAction](toolInput, toolResponse);
|
|
5261
|
-
} catch {
|
|
5262
|
-
return "";
|
|
5263
|
-
}
|
|
5264
|
-
}
|
|
5265
|
-
}
|
|
5266
|
-
return "";
|
|
5267
|
-
}
|
|
5268
|
-
|
|
5269
|
-
// src/core/feed/verbMap.ts
|
|
5270
|
-
var MCP_VERB_MAP = {
|
|
5271
|
-
navigate: "Navigate",
|
|
5272
|
-
find_elements: "Find",
|
|
5273
|
-
click: "Click",
|
|
5274
|
-
close_session: "Close",
|
|
5275
|
-
close_page: "Close",
|
|
5276
|
-
type: "Type",
|
|
5277
|
-
take_screenshot: "Screenshot",
|
|
5278
|
-
capture_snapshot: "Snapshot",
|
|
5279
|
-
scroll_page: "Scroll",
|
|
5280
|
-
scroll_element_into_view: "Scroll",
|
|
5281
|
-
hover: "Hover",
|
|
5282
|
-
press: "Press",
|
|
5283
|
-
select: "Select",
|
|
5284
|
-
go_back: "Back",
|
|
5285
|
-
go_forward: "Forward",
|
|
5286
|
-
reload: "Reload",
|
|
5287
|
-
list_pages: "Pages",
|
|
5288
|
-
get_element_details: "Inspect",
|
|
5289
|
-
get_form_understanding: "FormScan",
|
|
5290
|
-
get_field_context: "FieldInfo",
|
|
5291
|
-
ping: "Ping",
|
|
5292
|
-
// context7
|
|
5293
|
-
"resolve-library-id": "Resolve",
|
|
5294
|
-
"query-docs": "QueryDocs"
|
|
5295
|
-
};
|
|
5296
|
-
function resolveVerb(toolName, parsed) {
|
|
5297
|
-
if (!parsed.isMcp || !parsed.mcpAction) return toolName;
|
|
5298
|
-
const mapped = MCP_VERB_MAP[parsed.mcpAction];
|
|
5299
|
-
if (mapped) return mapped;
|
|
5300
|
-
const action = parsed.mcpAction;
|
|
5301
|
-
return action.charAt(0).toUpperCase() + action.slice(1).replace(/_/g, " ");
|
|
5302
|
-
}
|
|
5303
|
-
|
|
5304
|
-
// src/core/feed/timeline.ts
|
|
5305
|
-
function opCategory(op) {
|
|
5306
|
-
const dot = op.indexOf(".");
|
|
5307
|
-
return dot >= 0 ? op.slice(0, dot) : op;
|
|
5308
|
-
}
|
|
5309
|
-
function computeDuplicateActors(entries) {
|
|
5310
|
-
for (let i = 0; i < entries.length; i++) {
|
|
5311
|
-
const prev = i > 0 ? entries[i - 1] : void 0;
|
|
5312
|
-
const sameActor = prev !== void 0 && entries[i].actorId === prev.actorId;
|
|
5313
|
-
const isBreak = prev !== void 0 && opCategory(entries[i].opTag) !== opCategory(prev.opTag);
|
|
5314
|
-
entries[i].duplicateActor = sameActor && !isBreak;
|
|
5315
|
-
}
|
|
5316
|
-
}
|
|
5317
|
-
function stripMarkdownInline(text) {
|
|
5318
|
-
return text.replace(/#{1,6}\s+/g, "").replace(/\*\*(.+?)\*\*/g, "$1").replace(/__(.+?)__/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/`(.+?)`/g, "$1").replace(/~~(.+?)~~/g, "$1");
|
|
5319
|
-
}
|
|
5320
|
-
function firstSentence(text) {
|
|
5321
|
-
const nlIdx = text.indexOf("\n");
|
|
5322
|
-
const sentIdx = text.indexOf(". ");
|
|
5323
|
-
const nlEnd = nlIdx === -1 ? Infinity : nlIdx;
|
|
5324
|
-
const sentEnd = sentIdx === -1 ? Infinity : sentIdx + 1;
|
|
5325
|
-
const end = Math.min(nlEnd, sentEnd, text.length);
|
|
5326
|
-
return text.slice(0, end).trim();
|
|
5327
|
-
}
|
|
5328
|
-
function resolveDisplayName(toolName) {
|
|
5329
|
-
const parsed = parseToolName(toolName);
|
|
5330
|
-
if (parsed.isMcp && parsed.mcpServer && parsed.mcpAction) {
|
|
5331
|
-
const friendlyServer = extractFriendlyServerName(parsed.mcpServer);
|
|
5332
|
-
return `[${friendlyServer}] ${parsed.mcpAction}`;
|
|
5333
|
-
}
|
|
5334
|
-
return toolName;
|
|
5335
|
-
}
|
|
5336
|
-
var PATH_TOOLS = /* @__PURE__ */ new Set(["Read", "Write", "Edit", "Glob", "Grep"]);
|
|
5337
|
-
function withMcpServerContext(parsed, primaryInput) {
|
|
5338
|
-
if (!parsed.isMcp || !parsed.mcpServer) return primaryInput;
|
|
5339
|
-
const server = extractFriendlyServerName(parsed.mcpServer);
|
|
5340
|
-
if (!server) return primaryInput;
|
|
5341
|
-
return primaryInput ? `[${server}] ${primaryInput}` : `[${server}]`;
|
|
5342
|
-
}
|
|
5343
|
-
function formatToolSummary(toolName, toolInput, errorSuffix) {
|
|
5344
|
-
const parsed = parseToolName(toolName);
|
|
5345
|
-
const verb = resolveVerb(toolName, parsed);
|
|
5346
|
-
const primaryInput = withMcpServerContext(
|
|
5347
|
-
parsed,
|
|
5348
|
-
summarizeToolPrimaryInput(toolName, toolInput)
|
|
5349
|
-
);
|
|
5350
|
-
const secondary = [primaryInput, errorSuffix].filter(Boolean).join(" ");
|
|
5351
|
-
if (!secondary) {
|
|
5352
|
-
const text2 = compactText(verb, 200);
|
|
5353
|
-
return { text: text2, segments: [{ text: text2, role: "verb" }] };
|
|
5354
|
-
}
|
|
5355
|
-
const full = `${verb} ${secondary}`;
|
|
5356
|
-
const text = compactText(full, 200);
|
|
5357
|
-
const rest = text.slice(verb.length);
|
|
5358
|
-
const baseName = toolName;
|
|
5359
|
-
const filePath = toolInput.file_path ?? toolInput.pattern ?? toolInput.path;
|
|
5360
|
-
if (PATH_TOOLS.has(baseName) && typeof filePath === "string") {
|
|
5361
|
-
const { prefix, filename } = shortenPathStructured(filePath);
|
|
5362
|
-
if (prefix && filename) {
|
|
5363
|
-
const idx = rest.indexOf(prefix);
|
|
5364
|
-
if (idx >= 0) {
|
|
5365
|
-
const beforeFilename = rest.slice(0, idx + prefix.length);
|
|
5366
|
-
const afterFilename = rest.slice(idx + prefix.length + filename.length);
|
|
5367
|
-
return {
|
|
5368
|
-
text,
|
|
5369
|
-
segments: [
|
|
5370
|
-
{ text: verb, role: "verb" },
|
|
5371
|
-
{ text: beforeFilename, role: "target" },
|
|
5372
|
-
{ text: filename, role: "filename" },
|
|
5373
|
-
...afterFilename ? [{ text: afterFilename, role: "target" }] : []
|
|
5374
|
-
]
|
|
5375
|
-
};
|
|
5376
|
-
}
|
|
5377
|
-
}
|
|
5378
|
-
}
|
|
5379
|
-
return {
|
|
5380
|
-
text,
|
|
5381
|
-
segments: [
|
|
5382
|
-
{ text: verb, role: "verb" },
|
|
5383
|
-
{ text: rest, role: "target" }
|
|
5384
|
-
]
|
|
5385
|
-
};
|
|
5386
|
-
}
|
|
5387
|
-
function formatPermissionSummary(event) {
|
|
5388
|
-
const base = formatToolSummary(event.data.tool_name, event.data.tool_input);
|
|
5389
|
-
const host = event.data.network_context?.host;
|
|
5390
|
-
if (!host) {
|
|
5391
|
-
return base;
|
|
5392
|
-
}
|
|
5393
|
-
const protocol = event.data.network_context?.protocol;
|
|
5394
|
-
const suffix = ` \u2192 ${protocol ? `${protocol} ` : ""}${host}`;
|
|
5395
|
-
const text = compactText(`${base.text}${suffix}`, 200);
|
|
5396
|
-
return {
|
|
5397
|
-
text,
|
|
5398
|
-
segments: [...base.segments, { text: suffix, role: "target" }]
|
|
5399
|
-
};
|
|
5400
|
-
}
|
|
5401
|
-
function formatRunEndSummary(event) {
|
|
5402
|
-
const toolText = `${event.data.counters.tool_uses} tool${event.data.counters.tool_uses === 1 ? "" : "s"}`;
|
|
5403
|
-
const failureCount = event.data.counters.tool_failures;
|
|
5404
|
-
if (failureCount > 0) {
|
|
5405
|
-
return `${event.data.status} \xB7 ${toolText}, ${failureCount} failure${failureCount === 1 ? "" : "s"}`;
|
|
5406
|
-
}
|
|
5407
|
-
return `${event.data.status} \xB7 ${toolText}`;
|
|
5408
|
-
}
|
|
5409
|
-
function harnessSummary(event) {
|
|
5410
|
-
const title = event.display?.title?.trim();
|
|
5411
|
-
if (!title) return void 0;
|
|
5412
|
-
const text = compactText(title, 200);
|
|
5413
|
-
return { text, segments: [{ text, role: "target" }] };
|
|
5414
|
-
}
|
|
5415
|
-
function postOutcome(postEvent) {
|
|
5416
|
-
if (postEvent.kind === "tool.failure") {
|
|
5417
|
-
return summarizeToolResult(
|
|
5418
|
-
postEvent.data.tool_name,
|
|
5419
|
-
postEvent.data.tool_input,
|
|
5420
|
-
void 0,
|
|
5421
|
-
postEvent.data.error
|
|
5422
|
-
);
|
|
5423
|
-
}
|
|
5424
|
-
if (postEvent.kind === "tool.post") {
|
|
5425
|
-
return summarizeToolResult(
|
|
5426
|
-
postEvent.data.tool_name,
|
|
5427
|
-
postEvent.data.tool_input,
|
|
5428
|
-
postEvent.data.tool_response
|
|
5429
|
-
);
|
|
5430
|
-
}
|
|
5431
|
-
return void 0;
|
|
5432
|
-
}
|
|
5433
|
-
function plainSummary(text) {
|
|
5434
|
-
const compact = compactText(text, 200);
|
|
5435
|
-
return { text: compact, segments: [{ text: compact, role: "target" }] };
|
|
5436
|
-
}
|
|
5437
|
-
function dataExpansion(event) {
|
|
5438
|
-
return JSON.stringify(event.data, null, 2);
|
|
5439
|
-
}
|
|
5440
|
-
function rawOrDataExpansion(event) {
|
|
5441
|
-
return JSON.stringify(event.raw ?? event.data, null, 2);
|
|
5442
|
-
}
|
|
5443
|
-
function defaultRenderer(summarize2) {
|
|
5444
|
-
return {
|
|
5445
|
-
operation: () => "event",
|
|
5446
|
-
label: () => "Event",
|
|
5447
|
-
detail: () => "\u2500",
|
|
5448
|
-
summary: (event) => plainSummary(summarize2(event)),
|
|
5449
|
-
expansion: rawOrDataExpansion
|
|
5450
|
-
};
|
|
5451
|
-
}
|
|
5452
|
-
var sessionStart = {
|
|
5453
|
-
operation: () => "sess.start",
|
|
5454
|
-
label: () => "Sess Start",
|
|
5455
|
-
detail: (event) => event.data.source,
|
|
5456
|
-
summary: (event) => plainSummary(event.data.source),
|
|
5457
|
-
expansion: rawOrDataExpansion
|
|
5458
|
-
};
|
|
5459
|
-
var sessionEnd = {
|
|
5460
|
-
operation: () => "sess.end",
|
|
5461
|
-
label: () => "Sess End",
|
|
5462
|
-
detail: () => "\u2500",
|
|
5463
|
-
summary: (event) => plainSummary(event.data.reason),
|
|
5464
|
-
expansion: rawOrDataExpansion
|
|
5465
|
-
};
|
|
5466
|
-
var runStart = {
|
|
5467
|
-
operation: () => "run.start",
|
|
5468
|
-
label: () => "Run Start",
|
|
5469
|
-
detail: () => "\u2500",
|
|
5470
|
-
summary: (event) => plainSummary(event.data.trigger.prompt_preview || "interactive"),
|
|
5471
|
-
expansion: rawOrDataExpansion
|
|
5472
|
-
};
|
|
5473
|
-
var runEnd = {
|
|
5474
|
-
operation: (event) => {
|
|
5475
|
-
if (event.data.status === "completed") return "run.ok";
|
|
5476
|
-
if (event.data.status === "failed") return "run.fail";
|
|
5477
|
-
return "run.abort";
|
|
5478
|
-
},
|
|
5479
|
-
label: (event) => {
|
|
5480
|
-
if (event.data.status === "completed") return "Run OK";
|
|
5481
|
-
if (event.data.status === "failed") return "Run Fail";
|
|
5482
|
-
return "Run Abort";
|
|
5483
|
-
},
|
|
5484
|
-
detail: () => "\u2500",
|
|
5485
|
-
summary: (event) => plainSummary(formatRunEndSummary(event)),
|
|
5486
|
-
expansion: dataExpansion,
|
|
5487
|
-
isError: (event) => event.data.status !== "completed"
|
|
5488
|
-
};
|
|
5489
|
-
var userPrompt = {
|
|
5490
|
-
operation: () => "prompt",
|
|
5491
|
-
label: () => "User Prompt",
|
|
5492
|
-
detail: () => "\u2500",
|
|
5493
|
-
summary: (event) => plainSummary(event.data.prompt),
|
|
5494
|
-
expansion: rawOrDataExpansion
|
|
5495
|
-
};
|
|
5496
|
-
var planUpdate = {
|
|
5497
|
-
operation: () => "plan.upd",
|
|
5498
|
-
label: () => "Plan Update",
|
|
5499
|
-
detail: () => "plan",
|
|
5500
|
-
summary: (event) => {
|
|
5501
|
-
if (event.data.explanation) return plainSummary(event.data.explanation);
|
|
5502
|
-
if (event.data.plan && event.data.plan.length > 0) {
|
|
5503
|
-
const completed = event.data.plan.filter(
|
|
5504
|
-
(step) => step.status === "completed"
|
|
5505
|
-
).length;
|
|
5506
|
-
return plainSummary(`${completed}/${event.data.plan.length} steps`);
|
|
5507
|
-
}
|
|
5508
|
-
return plainSummary(event.data.delta || "plan updated");
|
|
5509
|
-
},
|
|
5510
|
-
expansion: dataExpansion
|
|
5511
|
-
};
|
|
5512
|
-
var reasoningSummary = {
|
|
5513
|
-
operation: () => "reason",
|
|
5514
|
-
label: () => "Reasoning",
|
|
5515
|
-
detail: () => "summary",
|
|
5516
|
-
summary: (event) => plainSummary(firstSentence(stripMarkdownInline(event.data.message))),
|
|
5517
|
-
expansion: dataExpansion
|
|
5518
|
-
};
|
|
5519
|
-
var usageUpdate = {
|
|
5520
|
-
operation: () => "usage.upd",
|
|
5521
|
-
label: () => "Usage Update",
|
|
5522
|
-
detail: () => "tokens",
|
|
5523
|
-
summary: (event) => {
|
|
5524
|
-
const total = event.data.usage?.total;
|
|
5525
|
-
const delta = event.data.delta?.total;
|
|
5526
|
-
if (typeof total === "number" && typeof delta === "number") {
|
|
5527
|
-
return plainSummary(
|
|
5528
|
-
`${total.toLocaleString()} total (+${delta.toLocaleString()})`
|
|
5529
|
-
);
|
|
5530
|
-
}
|
|
5531
|
-
if (typeof total === "number") {
|
|
5532
|
-
return plainSummary(`${total.toLocaleString()} total`);
|
|
5533
|
-
}
|
|
5534
|
-
return plainSummary("usage updated");
|
|
5535
|
-
},
|
|
5536
|
-
expansion: dataExpansion
|
|
5537
|
-
};
|
|
5538
|
-
var toolDelta = {
|
|
5539
|
-
operation: () => "tool.call",
|
|
5540
|
-
label: () => "Tool Call",
|
|
5541
|
-
detail: (event) => resolveDisplayName(event.data.tool_name),
|
|
5542
|
-
summary: (event) => formatToolSummary(event.data.tool_name, event.data.tool_input),
|
|
5543
|
-
expansion: (event) => JSON.stringify(
|
|
5544
|
-
{ tool: event.data.tool_name, args: event.data.tool_input },
|
|
5545
|
-
null,
|
|
5546
|
-
2
|
|
5547
|
-
)
|
|
5548
|
-
};
|
|
5549
|
-
var toolPre = {
|
|
5550
|
-
operation: () => "tool.call",
|
|
5551
|
-
label: () => "Tool Call",
|
|
5552
|
-
detail: (event) => resolveDisplayName(event.data.tool_name),
|
|
5553
|
-
summary: (event) => formatToolSummary(event.data.tool_name, event.data.tool_input),
|
|
5554
|
-
expansion: (event) => JSON.stringify(
|
|
5555
|
-
{ tool: event.data.tool_name, args: event.data.tool_input },
|
|
5556
|
-
null,
|
|
5557
|
-
2
|
|
5558
|
-
)
|
|
5559
|
-
};
|
|
5560
|
-
var toolPost = {
|
|
5561
|
-
operation: () => "tool.ok",
|
|
5562
|
-
label: () => "Tool OK",
|
|
5563
|
-
detail: (event) => resolveDisplayName(event.data.tool_name),
|
|
5564
|
-
summary: (event) => formatToolSummary(event.data.tool_name, event.data.tool_input),
|
|
5565
|
-
expansion: (event) => JSON.stringify(
|
|
5566
|
-
{
|
|
5567
|
-
tool: event.data.tool_name,
|
|
5568
|
-
args: event.data.tool_input,
|
|
5569
|
-
result: event.data.tool_response
|
|
5570
|
-
},
|
|
5571
|
-
null,
|
|
5572
|
-
2
|
|
5573
|
-
)
|
|
5574
|
-
};
|
|
5575
|
-
var toolFailure = {
|
|
5576
|
-
operation: () => "tool.fail",
|
|
5577
|
-
label: () => "Tool Fail",
|
|
5578
|
-
detail: (event) => resolveDisplayName(event.data.tool_name),
|
|
5579
|
-
summary: (event) => formatToolSummary(
|
|
5580
|
-
event.data.tool_name,
|
|
5581
|
-
event.data.tool_input,
|
|
5582
|
-
event.data.error
|
|
5583
|
-
),
|
|
5584
|
-
expansion: (event) => JSON.stringify(
|
|
5585
|
-
{
|
|
5586
|
-
tool: event.data.tool_name,
|
|
5587
|
-
args: event.data.tool_input,
|
|
5588
|
-
error: event.data.error,
|
|
5589
|
-
interrupt: event.data.is_interrupt
|
|
5590
|
-
},
|
|
5591
|
-
null,
|
|
5592
|
-
2
|
|
5593
|
-
),
|
|
5594
|
-
isError: () => true
|
|
5595
|
-
};
|
|
5596
|
-
var permissionRequest = {
|
|
5597
|
-
operation: () => "perm.req",
|
|
5598
|
-
label: () => "Perm Request",
|
|
5599
|
-
detail: (event) => resolveDisplayName(event.data.tool_name),
|
|
5600
|
-
summary: (event) => formatPermissionSummary(event),
|
|
5601
|
-
expansion: (event) => JSON.stringify(
|
|
5602
|
-
{
|
|
5603
|
-
tool: event.data.tool_name,
|
|
5604
|
-
args: event.data.tool_input,
|
|
5605
|
-
suggestions: event.data.permission_suggestions
|
|
5606
|
-
},
|
|
5607
|
-
null,
|
|
5608
|
-
2
|
|
5609
|
-
)
|
|
5610
|
-
};
|
|
5611
|
-
var permissionDecision = {
|
|
5612
|
-
operation: (event) => `perm.${event.data.decision_type}`,
|
|
5613
|
-
label: (event) => {
|
|
5614
|
-
switch (event.data.decision_type) {
|
|
5615
|
-
case "allow":
|
|
5616
|
-
return "Perm Allow";
|
|
5617
|
-
case "deny":
|
|
5618
|
-
return "Perm Deny";
|
|
5619
|
-
case "ask":
|
|
5620
|
-
return "Perm Ask";
|
|
5621
|
-
case "no_opinion":
|
|
5622
|
-
return "Perm Skip";
|
|
5623
|
-
default:
|
|
5624
|
-
return "Perm Decision";
|
|
5625
|
-
}
|
|
5626
|
-
},
|
|
5627
|
-
detail: () => "\u2500",
|
|
5628
|
-
summary: (event) => {
|
|
5629
|
-
const detail = event.data.decision_type === "deny" ? event.data.message || event.data.reason : event.data.reason;
|
|
5630
|
-
return plainSummary(detail || event.data.decision_type);
|
|
5631
|
-
},
|
|
5632
|
-
expansion: rawOrDataExpansion,
|
|
5633
|
-
isError: (event) => event.data.decision_type === "deny"
|
|
5634
|
-
};
|
|
5635
|
-
var stopRequest = {
|
|
5636
|
-
operation: () => "stop.req",
|
|
5637
|
-
label: () => "Stop Request",
|
|
5638
|
-
detail: () => "\u2500",
|
|
5639
|
-
summary: (event) => plainSummary(
|
|
5640
|
-
event.data.stop_hook_active ? "Stop hook active" : "Stop hook inactive"
|
|
5641
|
-
),
|
|
5642
|
-
expansion: rawOrDataExpansion
|
|
5643
|
-
};
|
|
5644
|
-
var stopDecision = {
|
|
5645
|
-
operation: (event) => `stop.${event.data.decision_type}`,
|
|
5646
|
-
label: (event) => {
|
|
5647
|
-
switch (event.data.decision_type) {
|
|
5648
|
-
case "block":
|
|
5649
|
-
return "Stop Block";
|
|
5650
|
-
case "allow":
|
|
5651
|
-
return "Stop Allow";
|
|
5652
|
-
case "no_opinion":
|
|
5653
|
-
return "Stop Skip";
|
|
5654
|
-
default:
|
|
5655
|
-
return "Stop Decision";
|
|
5656
|
-
}
|
|
5657
|
-
},
|
|
5658
|
-
detail: () => "\u2500",
|
|
5659
|
-
summary: (event) => plainSummary(event.data.reason || event.data.decision_type),
|
|
5660
|
-
expansion: rawOrDataExpansion,
|
|
5661
|
-
isError: (event) => event.data.decision_type === "block"
|
|
5662
|
-
};
|
|
5663
|
-
var subagentStart = {
|
|
5664
|
-
operation: () => "sub.start",
|
|
5665
|
-
label: () => "Sub Start",
|
|
5666
|
-
detail: (event) => event.data.agent_type,
|
|
5667
|
-
summary: (event) => {
|
|
5668
|
-
const text = compactText(
|
|
5669
|
-
event.data.description?.trim() || `id:${event.data.agent_id}`,
|
|
5670
|
-
200
|
|
5671
|
-
);
|
|
5672
|
-
return { text, segments: [{ text, role: "target" }] };
|
|
5673
|
-
},
|
|
5674
|
-
expansion: rawOrDataExpansion
|
|
5675
|
-
};
|
|
5676
|
-
var subagentStop = {
|
|
5677
|
-
operation: () => "sub.stop",
|
|
5678
|
-
label: () => "Sub Stop",
|
|
5679
|
-
detail: (event) => event.data.agent_type,
|
|
5680
|
-
summary: (event) => {
|
|
5681
|
-
const text = compactText(
|
|
5682
|
-
event.data.description?.trim() || `id:${event.data.agent_id}`,
|
|
5683
|
-
200
|
|
5684
|
-
);
|
|
5685
|
-
return { text, segments: [{ text, role: "target" }] };
|
|
5686
|
-
},
|
|
5687
|
-
expansion: dataExpansion
|
|
5688
|
-
};
|
|
5689
|
-
var notification = {
|
|
5690
|
-
operation: () => "notify",
|
|
5691
|
-
label: () => "Notify",
|
|
5692
|
-
detail: () => "\u2500",
|
|
5693
|
-
summary: (event) => plainSummary(stripMarkdownInline(event.data.message)),
|
|
5694
|
-
expansion: rawOrDataExpansion
|
|
5695
|
-
};
|
|
5696
|
-
var runtimeError = {
|
|
5697
|
-
operation: () => "error",
|
|
5698
|
-
label: () => "Error",
|
|
5699
|
-
detail: () => "\u2500",
|
|
5700
|
-
summary: (event) => plainSummary(stripMarkdownInline(event.data.message)),
|
|
5701
|
-
expansion: dataExpansion,
|
|
5702
|
-
isError: () => true
|
|
5703
|
-
};
|
|
5704
|
-
var threadStatus = {
|
|
5705
|
-
operation: () => "thread",
|
|
5706
|
-
label: () => "Thread",
|
|
5707
|
-
detail: (event) => event.data.status_type ?? "status",
|
|
5708
|
-
summary: (event) => plainSummary(event.data.message),
|
|
5709
|
-
expansion: dataExpansion
|
|
5710
|
-
};
|
|
5711
|
-
var turnDiff = {
|
|
5712
|
-
operation: () => "diff",
|
|
5713
|
-
label: () => "Diff",
|
|
5714
|
-
detail: () => "\u2500",
|
|
5715
|
-
summary: (event) => plainSummary(event.data.message),
|
|
5716
|
-
expansion: dataExpansion
|
|
5717
|
-
};
|
|
5718
|
-
var serverRequestResolved = {
|
|
5719
|
-
operation: () => "req.done",
|
|
5720
|
-
label: () => "Request",
|
|
5721
|
-
detail: (event) => event.data.request_id ?? "request",
|
|
5722
|
-
summary: (event) => plainSummary(event.data.message),
|
|
5723
|
-
expansion: dataExpansion
|
|
5724
|
-
};
|
|
5725
|
-
var webSearch = {
|
|
5726
|
-
operation: () => "web.search",
|
|
5727
|
-
label: () => "Web Search",
|
|
5728
|
-
detail: (event) => event.data.action_type ?? event.data.phase,
|
|
5729
|
-
summary: (event) => plainSummary(event.data.message),
|
|
5730
|
-
expansion: dataExpansion
|
|
5731
|
-
};
|
|
5732
|
-
var reviewStatus = {
|
|
5733
|
-
operation: () => "review",
|
|
5734
|
-
label: () => "Review",
|
|
5735
|
-
detail: (event) => event.data.phase,
|
|
5736
|
-
summary: (event) => plainSummary(event.data.message),
|
|
5737
|
-
expansion: dataExpansion
|
|
5738
|
-
};
|
|
5739
|
-
var imageView = {
|
|
5740
|
-
operation: () => "image",
|
|
5741
|
-
label: () => "Image",
|
|
5742
|
-
detail: (event) => event.data.path ?? "image",
|
|
5743
|
-
summary: (event) => plainSummary(event.data.message),
|
|
5744
|
-
expansion: dataExpansion
|
|
5745
|
-
};
|
|
5746
|
-
var contextCompaction = {
|
|
5747
|
-
operation: () => "compact",
|
|
5748
|
-
label: () => "Compaction",
|
|
5749
|
-
detail: (event) => event.data.phase,
|
|
5750
|
-
summary: (event) => plainSummary(event.data.message),
|
|
5751
|
-
expansion: dataExpansion
|
|
5752
|
-
};
|
|
5753
|
-
var mcpProgress = {
|
|
5754
|
-
operation: () => "mcp.prog",
|
|
5755
|
-
label: () => "MCP Progress",
|
|
5756
|
-
detail: () => "\u2500",
|
|
5757
|
-
summary: (event) => plainSummary(event.data.message),
|
|
5758
|
-
expansion: dataExpansion
|
|
5759
|
-
};
|
|
5760
|
-
var terminalInput = {
|
|
5761
|
-
operation: () => "term.in",
|
|
5762
|
-
label: () => "Terminal In",
|
|
5763
|
-
detail: () => "\u2500",
|
|
5764
|
-
summary: (event) => plainSummary(event.data.message),
|
|
5765
|
-
expansion: dataExpansion
|
|
5766
|
-
};
|
|
5767
|
-
var skillsChanged = {
|
|
5768
|
-
operation: () => "skills",
|
|
5769
|
-
label: () => "Skills",
|
|
5770
|
-
detail: () => "\u2500",
|
|
5771
|
-
summary: (event) => plainSummary(event.data.message),
|
|
5772
|
-
expansion: dataExpansion
|
|
5773
|
-
};
|
|
5774
|
-
var skillsLoaded = {
|
|
5775
|
-
operation: () => "skills",
|
|
5776
|
-
label: () => "Skills",
|
|
5777
|
-
detail: () => "\u2500",
|
|
5778
|
-
summary: (event) => plainSummary(event.data.message),
|
|
5779
|
-
expansion: dataExpansion
|
|
5780
|
-
};
|
|
5781
|
-
var compactPre = {
|
|
5782
|
-
operation: () => "compact",
|
|
5783
|
-
label: () => "Compact",
|
|
5784
|
-
detail: () => "\u2500",
|
|
5785
|
-
summary: (event) => plainSummary(event.data.trigger),
|
|
5786
|
-
expansion: dataExpansion
|
|
5787
|
-
};
|
|
5788
|
-
var setup = {
|
|
5789
|
-
operation: () => "setup",
|
|
5790
|
-
label: () => "Setup",
|
|
5791
|
-
detail: () => "\u2500",
|
|
5792
|
-
summary: (event) => plainSummary(event.data.trigger),
|
|
5793
|
-
expansion: rawOrDataExpansion
|
|
5794
|
-
};
|
|
5795
|
-
var unknownHook = {
|
|
5796
|
-
operation: () => "unknown",
|
|
5797
|
-
label: () => "Unknown",
|
|
5798
|
-
detail: () => "\u2500",
|
|
5799
|
-
summary: (event) => plainSummary(event.data.hook_event_name),
|
|
5800
|
-
expansion: rawOrDataExpansion
|
|
5801
|
-
};
|
|
5802
|
-
var todoAdd = {
|
|
5803
|
-
operation: () => "todo.add",
|
|
5804
|
-
label: () => "Todo Add",
|
|
5805
|
-
detail: (event) => (event.data.priority ?? "p1").toUpperCase(),
|
|
5806
|
-
summary: (event) => plainSummary(
|
|
5807
|
-
`${event.data.priority?.toUpperCase() ?? "P1"} ${event.data.text}`
|
|
5808
|
-
),
|
|
5809
|
-
expansion: rawOrDataExpansion
|
|
5810
|
-
};
|
|
5811
|
-
var todoUpdate = {
|
|
5812
|
-
operation: () => "todo.upd",
|
|
5813
|
-
label: () => "Todo Update",
|
|
5814
|
-
detail: (event) => event.data.todo_id,
|
|
5815
|
-
summary: (event) => {
|
|
5816
|
-
const patchFields = Object.keys(event.data.patch);
|
|
5817
|
-
return plainSummary(
|
|
5818
|
-
`${event.data.todo_id} ${patchFields.length > 0 ? patchFields.join(",") : "update"}`
|
|
5819
|
-
);
|
|
5820
|
-
},
|
|
5821
|
-
expansion: rawOrDataExpansion
|
|
5822
|
-
};
|
|
5823
|
-
var todoDone = {
|
|
5824
|
-
operation: () => "todo.done",
|
|
5825
|
-
label: () => "Todo Done",
|
|
5826
|
-
detail: (event) => event.data.todo_id,
|
|
5827
|
-
summary: (event) => plainSummary(`${event.data.todo_id} ${event.data.reason || "done"}`),
|
|
5828
|
-
expansion: rawOrDataExpansion
|
|
5829
|
-
};
|
|
5830
|
-
var agentMessage = {
|
|
5831
|
-
operation: () => "agent.msg",
|
|
5832
|
-
label: () => "Agent Msg",
|
|
5833
|
-
detail: () => "\u2500",
|
|
5834
|
-
summary: (event) => {
|
|
5835
|
-
const text = compactText(
|
|
5836
|
-
firstSentence(stripMarkdownInline(event.data.message)),
|
|
5837
|
-
200
|
|
5838
|
-
);
|
|
5839
|
-
return { text, segments: [{ text, role: "plain" }] };
|
|
5840
|
-
},
|
|
5841
|
-
expansion: rawOrDataExpansion
|
|
5842
|
-
};
|
|
5843
|
-
var teammateIdle = {
|
|
5844
|
-
operation: () => "tm.idle",
|
|
5845
|
-
label: () => "Team Idle",
|
|
5846
|
-
detail: () => "\u2500",
|
|
5847
|
-
summary: (event) => plainSummary(`${event.data.teammate_name} idle in ${event.data.team_name}`),
|
|
5848
|
-
expansion: rawOrDataExpansion
|
|
5849
|
-
};
|
|
5850
|
-
var taskCompleted = {
|
|
5851
|
-
operation: () => "task.ok",
|
|
5852
|
-
label: () => "Task OK",
|
|
5853
|
-
detail: () => "\u2500",
|
|
5854
|
-
summary: (event) => plainSummary(event.data.task_subject),
|
|
5855
|
-
expansion: rawOrDataExpansion
|
|
5856
|
-
};
|
|
5857
|
-
var configChange = {
|
|
5858
|
-
operation: () => "cfg.chg",
|
|
5859
|
-
label: () => "Config Chg",
|
|
5860
|
-
detail: (event) => event.data.source,
|
|
5861
|
-
summary: (event) => plainSummary(
|
|
5862
|
-
`${event.data.source}${event.data.file_path ? ` ${event.data.file_path}` : ""}`
|
|
5863
|
-
),
|
|
5864
|
-
expansion: rawOrDataExpansion
|
|
5865
|
-
};
|
|
5866
|
-
var compactPost = defaultRenderer(
|
|
5867
|
-
(event) => `compacted (${event.data.trigger})`
|
|
5868
|
-
);
|
|
5869
|
-
var taskCreated = defaultRenderer(
|
|
5870
|
-
(event) => event.data.task_subject
|
|
5871
|
-
);
|
|
5872
|
-
var cwdChanged = defaultRenderer(
|
|
5873
|
-
(event) => `cwd \u2192 ${event.data.cwd}`
|
|
5874
|
-
);
|
|
5875
|
-
var fileChanged = defaultRenderer(
|
|
5876
|
-
(event) => `changed ${event.data.file_path}`
|
|
5877
|
-
);
|
|
5878
|
-
var stopFailure = defaultRenderer(
|
|
5879
|
-
(event) => `${event.data.error_type}${event.data.error_message ? `: ${event.data.error_message}` : ""}`
|
|
5880
|
-
);
|
|
5881
|
-
var permissionDenied = defaultRenderer(
|
|
5882
|
-
(event) => `${event.data.tool_name}${event.data.reason ? `: ${event.data.reason}` : ""}`
|
|
5883
|
-
);
|
|
5884
|
-
var elicitationRequest = defaultRenderer((event) => `elicitation from ${event.data.mcp_server}`);
|
|
5885
|
-
var elicitationResult = defaultRenderer(
|
|
5886
|
-
(event) => `${event.data.mcp_server} \u2192 ${event.data.action}`
|
|
5887
|
-
);
|
|
5888
|
-
var channelPermissionRelayed = defaultRenderer(
|
|
5889
|
-
(event) => `${event.data.channel_name}: ${event.data.tool_name} (${event.data.channel_request_id})`
|
|
5890
|
-
);
|
|
5891
|
-
var channelPermissionResolved = defaultRenderer(
|
|
5892
|
-
(event) => `${event.data.channel_name} ${event.data.source} ${event.data.tool_name}`
|
|
5893
|
-
);
|
|
5894
|
-
var channelQuestionRelayed = defaultRenderer(
|
|
5895
|
-
(event) => `${event.data.channel_name}: ${event.data.title} (${event.data.channel_request_id})`
|
|
5896
|
-
);
|
|
5897
|
-
var channelQuestionResolved = defaultRenderer(
|
|
5898
|
-
(event) => `${event.data.channel_name || event.data.source} ${event.data.source} ${event.data.title}`
|
|
5899
|
-
);
|
|
5900
|
-
var channelChatInbound = defaultRenderer((event) => `${event.data.channel_name}: ${event.data.content}`);
|
|
5901
|
-
var channelChatOutbound = defaultRenderer(
|
|
5902
|
-
(event) => `${event.data.channel_name} \u2192 ${event.data.target_peer_id}: ${event.data.content}`
|
|
5903
|
-
);
|
|
5904
|
-
var gatewayFunctionInvoked = defaultRenderer(
|
|
5905
|
-
(event) => `fn invoked: ${event.data.function_name} (${event.data.caller_kind})`
|
|
5906
|
-
);
|
|
5907
|
-
var gatewayFunctionCompleted = defaultRenderer(
|
|
5908
|
-
(event) => `fn ok: ${event.data.function_name} ${event.data.duration_ms}ms`
|
|
5909
|
-
);
|
|
5910
|
-
var gatewayFunctionFailed = defaultRenderer(
|
|
5911
|
-
(event) => `fn ${event.data.reason}: ${event.data.function_name} \u2014 ${event.data.error_message}`
|
|
5912
|
-
);
|
|
5913
|
-
var artifactsManifest = defaultRenderer(
|
|
5914
|
-
(event) => {
|
|
5915
|
-
const manifest = event.data.manifest;
|
|
5916
|
-
const count = Array.isArray(manifest.entries) ? manifest.entries.length : 0;
|
|
5917
|
-
return `artifacts manifest (${count} item${count === 1 ? "" : "s"})`;
|
|
5918
|
-
}
|
|
5919
|
-
);
|
|
5920
|
-
var RENDERERS = {
|
|
5921
|
-
"session.start": sessionStart,
|
|
5922
|
-
"session.end": sessionEnd,
|
|
5923
|
-
"run.start": runStart,
|
|
5924
|
-
"run.end": runEnd,
|
|
5925
|
-
"user.prompt": userPrompt,
|
|
5926
|
-
"plan.update": planUpdate,
|
|
5927
|
-
"reasoning.summary": reasoningSummary,
|
|
5928
|
-
"usage.update": usageUpdate,
|
|
5929
|
-
"tool.delta": toolDelta,
|
|
5930
|
-
"tool.pre": toolPre,
|
|
5931
|
-
"tool.post": toolPost,
|
|
5932
|
-
"tool.failure": toolFailure,
|
|
5933
|
-
"permission.request": permissionRequest,
|
|
5934
|
-
"permission.decision": permissionDecision,
|
|
5935
|
-
"stop.request": stopRequest,
|
|
5936
|
-
"stop.decision": stopDecision,
|
|
5937
|
-
"subagent.start": subagentStart,
|
|
5938
|
-
"subagent.stop": subagentStop,
|
|
5939
|
-
notification,
|
|
5940
|
-
"runtime.error": runtimeError,
|
|
5941
|
-
"thread.status": threadStatus,
|
|
5942
|
-
"turn.diff": turnDiff,
|
|
5943
|
-
"server.request.resolved": serverRequestResolved,
|
|
5944
|
-
"web.search": webSearch,
|
|
5945
|
-
"review.status": reviewStatus,
|
|
5946
|
-
"image.view": imageView,
|
|
5947
|
-
"context.compaction": contextCompaction,
|
|
5948
|
-
"mcp.progress": mcpProgress,
|
|
5949
|
-
"terminal.input": terminalInput,
|
|
5950
|
-
"skills.changed": skillsChanged,
|
|
5951
|
-
"skills.loaded": skillsLoaded,
|
|
5952
|
-
"compact.pre": compactPre,
|
|
5953
|
-
"compact.post": compactPost,
|
|
5954
|
-
setup,
|
|
5955
|
-
"unknown.hook": unknownHook,
|
|
5956
|
-
"todo.add": todoAdd,
|
|
5957
|
-
"todo.update": todoUpdate,
|
|
5958
|
-
"todo.done": todoDone,
|
|
5959
|
-
"agent.message": agentMessage,
|
|
5960
|
-
"teammate.idle": teammateIdle,
|
|
5961
|
-
"task.created": taskCreated,
|
|
5962
|
-
"task.completed": taskCompleted,
|
|
5963
|
-
"config.change": configChange,
|
|
5964
|
-
"cwd.changed": cwdChanged,
|
|
5965
|
-
"file.changed": fileChanged,
|
|
5966
|
-
"stop.failure": stopFailure,
|
|
5967
|
-
"permission.denied": permissionDenied,
|
|
5968
|
-
"elicitation.request": elicitationRequest,
|
|
5969
|
-
"elicitation.result": elicitationResult,
|
|
5970
|
-
"channel.permission.relayed": channelPermissionRelayed,
|
|
5971
|
-
"channel.permission.resolved": channelPermissionResolved,
|
|
5972
|
-
"channel.question.relayed": channelQuestionRelayed,
|
|
5973
|
-
"channel.question.resolved": channelQuestionResolved,
|
|
5974
|
-
"channel.chat.inbound": channelChatInbound,
|
|
5975
|
-
"channel.chat.outbound": channelChatOutbound,
|
|
5976
|
-
"gateway.function.invoked": gatewayFunctionInvoked,
|
|
5977
|
-
"gateway.function.completed": gatewayFunctionCompleted,
|
|
5978
|
-
"gateway.function.failed": gatewayFunctionFailed,
|
|
5979
|
-
"artifacts.manifest": artifactsManifest
|
|
5980
|
-
};
|
|
5981
|
-
function rendererFor(event) {
|
|
5982
|
-
return RENDERERS[event.kind];
|
|
5983
|
-
}
|
|
5984
|
-
function eventOperation(event) {
|
|
5985
|
-
return rendererFor(event).operation(event);
|
|
5986
|
-
}
|
|
5987
|
-
function eventLabel(event) {
|
|
5988
|
-
return rendererFor(event).label(event);
|
|
5989
|
-
}
|
|
5990
|
-
function eventSummary(event) {
|
|
5991
|
-
const harness = harnessSummary(event);
|
|
5992
|
-
if (harness) return harness;
|
|
5993
|
-
return rendererFor(event).summary(event);
|
|
5994
|
-
}
|
|
5995
|
-
function expansionForEvent(event) {
|
|
5996
|
-
return rendererFor(event).expansion(event);
|
|
5997
|
-
}
|
|
5998
|
-
function isEventError(event) {
|
|
5999
|
-
if (event.level === "error") return true;
|
|
6000
|
-
const renderer = rendererFor(event);
|
|
6001
|
-
return renderer.isError?.(event) ?? false;
|
|
6002
|
-
}
|
|
6003
|
-
function isEventExpandable(event) {
|
|
6004
|
-
void event;
|
|
6005
|
-
return true;
|
|
6006
|
-
}
|
|
6007
|
-
var toolPairOk = {
|
|
6008
|
-
operation: () => "tool.ok",
|
|
6009
|
-
label: () => "Tool OK",
|
|
6010
|
-
summary: (pre, post) => buildMergedToolSummary(pre, post)
|
|
6011
|
-
};
|
|
6012
|
-
var toolPairFail = {
|
|
6013
|
-
operation: () => "tool.fail",
|
|
6014
|
-
label: () => "Tool Fail",
|
|
6015
|
-
summary: (pre, post) => buildMergedToolSummary(pre, post)
|
|
6016
|
-
};
|
|
6017
|
-
var TOOL_PAIRS = {
|
|
6018
|
-
"tool.post": toolPairOk,
|
|
6019
|
-
"tool.failure": toolPairFail
|
|
6020
|
-
};
|
|
6021
|
-
function buildMergedToolSummary(event, postEvent) {
|
|
6022
|
-
const harness = harnessSummary(event) ?? harnessSummary(postEvent);
|
|
6023
|
-
if (harness) {
|
|
6024
|
-
return {
|
|
6025
|
-
...harness,
|
|
6026
|
-
outcome: postOutcome(postEvent),
|
|
6027
|
-
outcomeZero: false
|
|
6028
|
-
};
|
|
6029
|
-
}
|
|
6030
|
-
const toolName = event.data.tool_name;
|
|
6031
|
-
const preInput = event.data.tool_input;
|
|
6032
|
-
const postInput = postEvent.kind === "tool.post" || postEvent.kind === "tool.failure" ? postEvent.data.tool_input : void 0;
|
|
6033
|
-
const toolInput = postInput && Object.keys(preInput).every((k) => preInput[k] == null) ? postInput : preInput;
|
|
6034
|
-
const parsed = parseToolName(toolName);
|
|
6035
|
-
const name = resolveVerb(toolName, parsed);
|
|
6036
|
-
const primaryInput = withMcpServerContext(
|
|
6037
|
-
parsed,
|
|
6038
|
-
summarizeToolPrimaryInput(toolName, toolInput)
|
|
6039
|
-
);
|
|
6040
|
-
let resultText;
|
|
6041
|
-
if (postEvent.kind === "tool.failure") {
|
|
6042
|
-
resultText = summarizeToolResult(
|
|
6043
|
-
toolName,
|
|
6044
|
-
toolInput,
|
|
6045
|
-
void 0,
|
|
6046
|
-
postEvent.data.error
|
|
6047
|
-
);
|
|
6048
|
-
} else if (postEvent.kind === "tool.post") {
|
|
6049
|
-
resultText = summarizeToolResult(
|
|
6050
|
-
toolName,
|
|
6051
|
-
toolInput,
|
|
6052
|
-
postEvent.data.tool_response
|
|
6053
|
-
);
|
|
6054
|
-
} else {
|
|
6055
|
-
return eventSummary(event);
|
|
6056
|
-
}
|
|
6057
|
-
const prefix = primaryInput ? `${name} ${primaryInput}` : name;
|
|
6058
|
-
const prefixText = compactText(prefix, 200);
|
|
6059
|
-
const segments = primaryInput ? [
|
|
6060
|
-
{ text: name, role: "verb" },
|
|
6061
|
-
{ text: prefixText.slice(name.length), role: "target" }
|
|
6062
|
-
] : [{ text: prefixText, role: "verb" }];
|
|
6063
|
-
if (!resultText) {
|
|
6064
|
-
return { text: prefixText, segments };
|
|
6065
|
-
}
|
|
6066
|
-
return {
|
|
6067
|
-
text: prefixText,
|
|
6068
|
-
segments,
|
|
6069
|
-
outcome: resultText,
|
|
6070
|
-
outcomeZero: /^0\s/.test(resultText)
|
|
6071
|
-
};
|
|
6072
|
-
}
|
|
6073
|
-
function mergedEventOperation(event, postEvent) {
|
|
6074
|
-
if (!postEvent) return eventOperation(event);
|
|
6075
|
-
const pair = TOOL_PAIRS[postEvent.kind];
|
|
6076
|
-
if (!pair) return eventOperation(event);
|
|
6077
|
-
return pair.operation(event, postEvent);
|
|
6078
|
-
}
|
|
6079
|
-
function mergedEventLabel(event, postEvent) {
|
|
6080
|
-
if (!postEvent) return eventLabel(event);
|
|
6081
|
-
const pair = TOOL_PAIRS[postEvent.kind];
|
|
6082
|
-
if (!pair) return eventLabel(event);
|
|
6083
|
-
return pair.label(event, postEvent);
|
|
6084
|
-
}
|
|
6085
|
-
function mergedEventSummary(event, postEvent) {
|
|
6086
|
-
if (!postEvent) return eventSummary(event);
|
|
6087
|
-
if (event.kind !== "tool.pre" && event.kind !== "permission.request") {
|
|
6088
|
-
return eventSummary(event);
|
|
6089
|
-
}
|
|
6090
|
-
const pair = TOOL_PAIRS[postEvent.kind];
|
|
6091
|
-
if (!pair) return eventSummary(event);
|
|
6092
|
-
return pair.summary(event, postEvent);
|
|
6093
|
-
}
|
|
6094
|
-
var VERBOSE_ONLY_KINDS = /* @__PURE__ */ new Set([
|
|
6095
|
-
"session.start",
|
|
6096
|
-
"session.end",
|
|
6097
|
-
"run.start",
|
|
6098
|
-
"run.end",
|
|
6099
|
-
"unknown.hook",
|
|
6100
|
-
"compact.pre",
|
|
6101
|
-
"config.change",
|
|
6102
|
-
"turn.diff",
|
|
6103
|
-
"usage.update",
|
|
6104
|
-
"reasoning.summary"
|
|
6105
|
-
]);
|
|
6106
|
-
function toRunStatus(event) {
|
|
6107
|
-
switch (event.data.status) {
|
|
6108
|
-
case "completed":
|
|
6109
|
-
return "SUCCEEDED";
|
|
6110
|
-
case "failed":
|
|
6111
|
-
return "FAILED";
|
|
6112
|
-
case "aborted":
|
|
6113
|
-
return "CANCELLED";
|
|
6114
|
-
}
|
|
6115
|
-
}
|
|
6116
|
-
|
|
6117
|
-
// src/core/feed/toolDisplay.ts
|
|
6118
|
-
function prop2(obj, key) {
|
|
6119
|
-
if (typeof obj === "object" && obj !== null) {
|
|
6120
|
-
return obj[key];
|
|
6121
|
-
}
|
|
6122
|
-
return void 0;
|
|
6123
|
-
}
|
|
6124
|
-
function truncate(text, max) {
|
|
6125
|
-
if (text.length <= max) return text;
|
|
6126
|
-
if (max <= 3) return text.slice(0, max);
|
|
6127
|
-
return text.slice(0, max - 1) + "\u2026";
|
|
6128
|
-
}
|
|
6129
|
-
function extractDomain(url) {
|
|
6130
|
-
if (typeof url !== "string") return "";
|
|
6131
|
-
try {
|
|
6132
|
-
const u = new URL(url);
|
|
6133
|
-
return u.hostname.replace(/^www\./, "");
|
|
6134
|
-
} catch {
|
|
6135
|
-
return compactText(String(url), 40);
|
|
6136
|
-
}
|
|
6137
|
-
}
|
|
6138
|
-
function filePathSegments(input) {
|
|
6139
|
-
const path10 = prop2(input, "file_path") ?? prop2(input, "notebook_path") ?? "";
|
|
6140
|
-
if (typeof path10 !== "string" || !path10) return [];
|
|
6141
|
-
const { prefix, filename } = shortenPathStructured(path10);
|
|
6142
|
-
if (prefix && filename) {
|
|
6143
|
-
return [
|
|
6144
|
-
{ text: prefix, role: "target" },
|
|
6145
|
-
{ text: filename, role: "filename" }
|
|
6146
|
-
];
|
|
6147
|
-
}
|
|
6148
|
-
return [{ text: filename || path10, role: "filename" }];
|
|
6149
|
-
}
|
|
6150
|
-
function grepSegments(input) {
|
|
6151
|
-
const pattern = String(prop2(input, "pattern") ?? "");
|
|
6152
|
-
const glob = prop2(input, "glob");
|
|
6153
|
-
const parts = `"${pattern}"${glob ? ` ${String(glob)}` : ""}`;
|
|
6154
|
-
return [{ text: parts, role: "target" }];
|
|
6155
|
-
}
|
|
6156
|
-
function commandSegments(input) {
|
|
6157
|
-
const cmd = String(prop2(input, "command") ?? "");
|
|
6158
|
-
return [{ text: compactText(compactCommandPaths(cmd), 50), role: "target" }];
|
|
6159
|
-
}
|
|
6160
|
-
function countOutcome(output, label) {
|
|
6161
|
-
if (Array.isArray(output)) {
|
|
6162
|
-
return { text: `${output.length} ${label}`, zero: output.length === 0 };
|
|
6163
|
-
}
|
|
6164
|
-
if (typeof output === "object" && output !== null) {
|
|
6165
|
-
const filenames = prop2(output, "filenames");
|
|
6166
|
-
if (Array.isArray(filenames)) {
|
|
6167
|
-
return {
|
|
6168
|
-
text: `${filenames.length} ${label}`,
|
|
6169
|
-
zero: filenames.length === 0
|
|
6170
|
-
};
|
|
6171
|
-
}
|
|
6172
|
-
const numFiles = prop2(output, "numFiles");
|
|
6173
|
-
if (typeof numFiles === "number") {
|
|
6174
|
-
return { text: `${numFiles} ${label}`, zero: numFiles === 0 };
|
|
6175
|
-
}
|
|
6176
|
-
const numMatches = prop2(output, "numMatches");
|
|
6177
|
-
if (typeof numMatches === "number") {
|
|
6178
|
-
return { text: `${numMatches} ${label}`, zero: numMatches === 0 };
|
|
6179
|
-
}
|
|
6180
|
-
const count = prop2(output, "count");
|
|
6181
|
-
if (typeof count === "number") {
|
|
6182
|
-
return { text: `${count} ${label}`, zero: count === 0 };
|
|
6183
|
-
}
|
|
6184
|
-
}
|
|
6185
|
-
if (typeof output === "string") {
|
|
6186
|
-
const lines = output.split("\n").filter(Boolean).length;
|
|
6187
|
-
return { text: `${lines} ${label}`, zero: lines === 0 };
|
|
6188
|
-
}
|
|
6189
|
-
return void 0;
|
|
6190
|
-
}
|
|
6191
|
-
function exitCodeOutcome(output) {
|
|
6192
|
-
if (isBashToolResponse(output)) {
|
|
6193
|
-
const code = prop2(output, "exitCode") ?? 0;
|
|
6194
|
-
const stderr = output.stderr.trim();
|
|
6195
|
-
const firstLine = stderr.split("\n")[0] ?? "";
|
|
6196
|
-
if (stderr && Number(code) !== 0) {
|
|
6197
|
-
return { text: `exit ${code} \u2014 ${truncate(firstLine, 30)}`, zero: false };
|
|
6198
|
-
}
|
|
6199
|
-
return { text: `exit ${code}`, zero: false };
|
|
6200
|
-
}
|
|
6201
|
-
return void 0;
|
|
6202
|
-
}
|
|
6203
|
-
function webSearchOutcome(output) {
|
|
6204
|
-
const results = prop2(output, "results");
|
|
6205
|
-
if (Array.isArray(results)) {
|
|
6206
|
-
let count = 0;
|
|
6207
|
-
for (const entry of results) {
|
|
6208
|
-
const content = prop2(entry, "content");
|
|
6209
|
-
count += Array.isArray(content) ? content.length : 1;
|
|
6210
|
-
}
|
|
6211
|
-
return { text: `${count} results`, zero: count === 0 };
|
|
6212
|
-
}
|
|
6213
|
-
const actionType = prop2(output, "type");
|
|
6214
|
-
if (typeof actionType === "string") {
|
|
6215
|
-
return { text: actionType.replace(/_/g, " "), zero: false };
|
|
6216
|
-
}
|
|
6217
|
-
return void 0;
|
|
6218
|
-
}
|
|
6219
|
-
function taskOutputOutcome(output) {
|
|
6220
|
-
if (typeof output === "string" && output.trim()) {
|
|
6221
|
-
return { text: truncate(output.trim(), 30), zero: false };
|
|
6222
|
-
}
|
|
6223
|
-
return void 0;
|
|
6224
|
-
}
|
|
6225
|
-
function eidExtractor2(input) {
|
|
6226
|
-
const eid = String(prop2(input, "eid") ?? "");
|
|
6227
|
-
return eid ? [{ text: `eid:${eid.slice(0, 6)}\u2026`, role: "target" }] : [];
|
|
6228
|
-
}
|
|
6229
|
-
function eidOrLabelExtractor(input) {
|
|
6230
|
-
const label = prop2(input, "label");
|
|
6231
|
-
if (typeof label === "string" && label) {
|
|
6232
|
-
return [{ text: `"${truncate(label, 20)}"`, role: "target" }];
|
|
6233
|
-
}
|
|
6234
|
-
return eidExtractor2(input);
|
|
6235
|
-
}
|
|
6236
|
-
function findDetailsExtractor(input) {
|
|
6237
|
-
const parts = [];
|
|
6238
|
-
const kind = prop2(input, "kind");
|
|
6239
|
-
if (kind) parts.push(String(kind));
|
|
6240
|
-
const label = prop2(input, "label");
|
|
6241
|
-
if (label) parts.push(`"${String(label)}"`);
|
|
6242
|
-
if (parts.length === 0) {
|
|
6243
|
-
const region = prop2(input, "region");
|
|
6244
|
-
if (region) parts.push(String(region));
|
|
6245
|
-
}
|
|
6246
|
-
return parts.length > 0 ? [{ text: parts.join(" "), role: "target" }] : [{ text: "elements", role: "target" }];
|
|
6247
|
-
}
|
|
6248
|
-
function typeDetailsExtractor(input) {
|
|
6249
|
-
const text = String(prop2(input, "text") ?? "");
|
|
6250
|
-
const eid = prop2(input, "eid");
|
|
6251
|
-
const quoted = `"${truncate(text, 30)}"`;
|
|
6252
|
-
if (eid) {
|
|
6253
|
-
return [{ text: `${quoted} \u2192 ${String(eid).slice(0, 5)}\u2026`, role: "target" }];
|
|
6254
|
-
}
|
|
6255
|
-
return [{ text: quoted, role: "target" }];
|
|
6256
|
-
}
|
|
6257
|
-
function scrollDetailsExtractor(input) {
|
|
6258
|
-
const dir = String(prop2(input, "direction") ?? "");
|
|
6259
|
-
const amount = prop2(input, "amount");
|
|
6260
|
-
const text = amount ? `${dir} ${amount}px` : dir;
|
|
6261
|
-
return text ? [{ text, role: "target" }] : [];
|
|
6262
|
-
}
|
|
6263
|
-
function tabRefExtractor(input) {
|
|
6264
|
-
const pageId = prop2(input, "page_id");
|
|
6265
|
-
return pageId ? [{ text: `page:${String(pageId).slice(0, 6)}`, role: "target" }] : [];
|
|
6266
|
-
}
|
|
6267
|
-
function foundCountOutcome(output) {
|
|
6268
|
-
if (Array.isArray(output)) {
|
|
6269
|
-
return { text: `${output.length} found`, zero: output.length === 0 };
|
|
6270
|
-
}
|
|
6271
|
-
if (typeof output === "object" && output !== null) {
|
|
6272
|
-
const elements = prop2(output, "elements") ?? prop2(output, "items");
|
|
6273
|
-
if (Array.isArray(elements)) {
|
|
6274
|
-
return { text: `${elements.length} found`, zero: elements.length === 0 };
|
|
6275
|
-
}
|
|
6276
|
-
}
|
|
6277
|
-
return void 0;
|
|
6278
|
-
}
|
|
6279
|
-
function tabCountOutcome(output) {
|
|
6280
|
-
if (Array.isArray(output)) {
|
|
6281
|
-
return { text: `${output.length} tabs`, zero: output.length === 0 };
|
|
6282
|
-
}
|
|
6283
|
-
const pages = prop2(output, "pages");
|
|
6284
|
-
if (Array.isArray(pages)) {
|
|
6285
|
-
return { text: `${pages.length} tabs`, zero: pages.length === 0 };
|
|
6286
|
-
}
|
|
6287
|
-
return void 0;
|
|
6288
|
-
}
|
|
6289
|
-
function formCountOutcome(output) {
|
|
6290
|
-
const fields = prop2(output, "fields");
|
|
6291
|
-
if (Array.isArray(fields)) {
|
|
6292
|
-
return { text: `${fields.length} fields`, zero: fields.length === 0 };
|
|
6293
|
-
}
|
|
6294
|
-
return void 0;
|
|
6295
|
-
}
|
|
6296
|
-
function pingOutcome(output) {
|
|
6297
|
-
if (output) return { text: "ok", zero: false };
|
|
6298
|
-
return void 0;
|
|
6299
|
-
}
|
|
6300
|
-
var KNOWN_TOOL_DISPLAY = new Map([
|
|
6301
|
-
// ── Core file tools ──
|
|
6302
|
-
[
|
|
6303
|
-
"Read",
|
|
6304
|
-
{
|
|
6305
|
-
display: "Read",
|
|
6306
|
-
extractDetails: filePathSegments,
|
|
6307
|
-
extractOutcome: () => void 0
|
|
6308
|
-
}
|
|
6309
|
-
],
|
|
6310
|
-
[
|
|
6311
|
-
"Write",
|
|
6312
|
-
{
|
|
6313
|
-
display: "Write",
|
|
6314
|
-
extractDetails: filePathSegments,
|
|
6315
|
-
extractOutcome: () => void 0
|
|
6316
|
-
}
|
|
6317
|
-
],
|
|
6318
|
-
[
|
|
6319
|
-
"Edit",
|
|
6320
|
-
{
|
|
6321
|
-
display: "Edit",
|
|
6322
|
-
extractDetails: filePathSegments,
|
|
6323
|
-
extractOutcome: () => void 0
|
|
6324
|
-
}
|
|
6325
|
-
],
|
|
6326
|
-
[
|
|
6327
|
-
"Glob",
|
|
6328
|
-
{
|
|
6329
|
-
display: "Glob",
|
|
6330
|
-
extractDetails: (input) => [
|
|
6331
|
-
{ text: String(prop2(input, "pattern") ?? ""), role: "target" }
|
|
6332
|
-
],
|
|
6333
|
-
extractOutcome: (output) => countOutcome(output, "files")
|
|
6334
|
-
}
|
|
6335
|
-
],
|
|
6336
|
-
[
|
|
6337
|
-
"Grep",
|
|
6338
|
-
{
|
|
6339
|
-
display: "Grep",
|
|
6340
|
-
extractDetails: grepSegments,
|
|
6341
|
-
extractOutcome: (output) => countOutcome(output, "matches")
|
|
6342
|
-
}
|
|
6343
|
-
],
|
|
6344
|
-
[
|
|
6345
|
-
"Bash",
|
|
6346
|
-
{
|
|
6347
|
-
display: "Bash",
|
|
6348
|
-
extractDetails: commandSegments,
|
|
6349
|
-
extractOutcome: exitCodeOutcome
|
|
6350
|
-
}
|
|
6351
|
-
],
|
|
6352
|
-
// ── Web tools ──
|
|
6353
|
-
[
|
|
6354
|
-
"WebFetch",
|
|
6355
|
-
{
|
|
6356
|
-
display: "WebFetch",
|
|
6357
|
-
extractDetails: (input) => [
|
|
6358
|
-
{ text: extractDomain(prop2(input, "url")), role: "target" }
|
|
6359
|
-
],
|
|
6360
|
-
extractOutcome: () => void 0
|
|
6361
|
-
}
|
|
6362
|
-
],
|
|
6363
|
-
[
|
|
6364
|
-
"WebSearch",
|
|
6365
|
-
{
|
|
6366
|
-
display: "WebSearch",
|
|
6367
|
-
extractDetails: (input) => [
|
|
6368
|
-
{
|
|
6369
|
-
text: truncate(String(prop2(input, "query") ?? ""), 40),
|
|
6370
|
-
role: "target"
|
|
6371
|
-
}
|
|
6372
|
-
],
|
|
6373
|
-
extractOutcome: webSearchOutcome
|
|
6374
|
-
}
|
|
6375
|
-
],
|
|
6376
|
-
[
|
|
6377
|
-
"NotebookEdit",
|
|
6378
|
-
{
|
|
6379
|
-
display: "Notebook",
|
|
6380
|
-
extractDetails: filePathSegments,
|
|
6381
|
-
extractOutcome: () => void 0
|
|
6382
|
-
}
|
|
6383
|
-
],
|
|
6384
|
-
// ── Agent & task tools ──
|
|
6385
|
-
...["Task", "Agent"].map(
|
|
6386
|
-
(name) => [
|
|
6387
|
-
name,
|
|
6388
|
-
{
|
|
6389
|
-
display: "Task",
|
|
6390
|
-
extractDetails: (input) => [
|
|
6391
|
-
{
|
|
6392
|
-
text: truncate(String(prop2(input, "description") ?? ""), 50),
|
|
6393
|
-
role: "plain"
|
|
6394
|
-
}
|
|
6395
|
-
],
|
|
6396
|
-
extractOutcome: (output) => {
|
|
6397
|
-
const agentType = prop2(output, "subagent_type");
|
|
6398
|
-
return agentType ? { text: String(agentType), zero: false } : void 0;
|
|
6399
|
-
}
|
|
6400
|
-
}
|
|
6401
|
-
]
|
|
6402
|
-
),
|
|
6403
|
-
[
|
|
6404
|
-
"TaskOutput",
|
|
6405
|
-
{
|
|
6406
|
-
display: "TaskOut",
|
|
6407
|
-
extractDetails: (input) => [
|
|
6408
|
-
{ text: String(prop2(input, "task_id") ?? ""), role: "target" }
|
|
6409
|
-
],
|
|
6410
|
-
extractOutcome: taskOutputOutcome
|
|
6411
|
-
}
|
|
6412
|
-
],
|
|
6413
|
-
[
|
|
6414
|
-
"TaskStop",
|
|
6415
|
-
{
|
|
6416
|
-
display: "TaskStop",
|
|
6417
|
-
extractDetails: (input) => [
|
|
6418
|
-
{ text: String(prop2(input, "task_id") ?? ""), role: "target" }
|
|
6419
|
-
],
|
|
6420
|
-
extractOutcome: () => ({ text: "stopped", zero: false })
|
|
6421
|
-
}
|
|
6422
|
-
],
|
|
6423
|
-
[
|
|
6424
|
-
"TodoWrite",
|
|
6425
|
-
{
|
|
6426
|
-
display: "TodoWrite",
|
|
6427
|
-
extractDetails: (input) => {
|
|
6428
|
-
const todos = prop2(input, "todos");
|
|
6429
|
-
const n = Array.isArray(todos) ? todos.length : 0;
|
|
6430
|
-
return [{ text: `${n} items`, role: "target" }];
|
|
6431
|
-
},
|
|
6432
|
-
extractOutcome: () => void 0
|
|
6433
|
-
}
|
|
6434
|
-
],
|
|
6435
|
-
// ── Planning & interaction ──
|
|
6436
|
-
[
|
|
6437
|
-
"AskUserQuestion",
|
|
6438
|
-
{
|
|
6439
|
-
display: "AskUser",
|
|
6440
|
-
extractDetails: (input) => {
|
|
6441
|
-
const questions = prop2(input, "questions");
|
|
6442
|
-
const n = Array.isArray(questions) ? questions.length : 0;
|
|
6443
|
-
return [{ text: `${n} question${n !== 1 ? "s" : ""}`, role: "target" }];
|
|
6444
|
-
},
|
|
6445
|
-
extractOutcome: () => void 0
|
|
6446
|
-
}
|
|
6447
|
-
],
|
|
6448
|
-
[
|
|
6449
|
-
"EnterPlanMode",
|
|
6450
|
-
{
|
|
6451
|
-
display: "PlanMode",
|
|
6452
|
-
extractDetails: () => [],
|
|
6453
|
-
extractOutcome: () => ({ text: "entered", zero: false })
|
|
6454
|
-
}
|
|
6455
|
-
],
|
|
6456
|
-
[
|
|
6457
|
-
"ExitPlanMode",
|
|
6458
|
-
{
|
|
6459
|
-
display: "PlanMode",
|
|
6460
|
-
extractDetails: () => [],
|
|
6461
|
-
extractOutcome: () => ({ text: "submitted", zero: false })
|
|
6462
|
-
}
|
|
6463
|
-
],
|
|
6464
|
-
[
|
|
6465
|
-
"EnterWorktree",
|
|
6466
|
-
{
|
|
6467
|
-
display: "Worktree",
|
|
6468
|
-
extractDetails: (input) => [
|
|
6469
|
-
{ text: String(prop2(input, "branch") ?? ""), role: "target" }
|
|
6470
|
-
],
|
|
6471
|
-
extractOutcome: () => ({ text: "created", zero: false })
|
|
6472
|
-
}
|
|
6473
|
-
],
|
|
6474
|
-
[
|
|
6475
|
-
"ExitWorktree",
|
|
6476
|
-
{
|
|
6477
|
-
display: "Worktree",
|
|
6478
|
-
extractDetails: (input) => [
|
|
6479
|
-
{ text: String(prop2(input, "action") ?? ""), role: "target" }
|
|
6480
|
-
],
|
|
6481
|
-
extractOutcome: () => ({ text: "exited", zero: false })
|
|
6482
|
-
}
|
|
6483
|
-
],
|
|
6484
|
-
// ── Cron / scheduling ──
|
|
6485
|
-
[
|
|
6486
|
-
"CronCreate",
|
|
6487
|
-
{
|
|
6488
|
-
display: "Cron",
|
|
6489
|
-
extractDetails: (input) => [
|
|
6490
|
-
{ text: truncate(String(prop2(input, "cron") ?? ""), 30), role: "target" }
|
|
6491
|
-
],
|
|
6492
|
-
extractOutcome: () => ({ text: "created", zero: false })
|
|
6493
|
-
}
|
|
6494
|
-
],
|
|
6495
|
-
[
|
|
6496
|
-
"CronDelete",
|
|
6497
|
-
{
|
|
6498
|
-
display: "Cron",
|
|
6499
|
-
extractDetails: (input) => [
|
|
6500
|
-
{ text: String(prop2(input, "id") ?? ""), role: "target" }
|
|
6501
|
-
],
|
|
6502
|
-
extractOutcome: () => ({ text: "deleted", zero: false })
|
|
6503
|
-
}
|
|
6504
|
-
],
|
|
6505
|
-
[
|
|
6506
|
-
"CronList",
|
|
6507
|
-
{
|
|
6508
|
-
display: "Cron",
|
|
6509
|
-
extractDetails: () => [{ text: "list", role: "target" }],
|
|
6510
|
-
extractOutcome: (output) => countOutcome(output, "triggers")
|
|
6511
|
-
}
|
|
6512
|
-
],
|
|
6513
|
-
// ── Remote triggers ──
|
|
6514
|
-
[
|
|
6515
|
-
"RemoteTrigger",
|
|
6516
|
-
{
|
|
6517
|
-
display: "Trigger",
|
|
6518
|
-
extractDetails: (input) => {
|
|
6519
|
-
const action = String(prop2(input, "action") ?? "");
|
|
6520
|
-
const triggerId = prop2(input, "trigger_id");
|
|
6521
|
-
const text = triggerId ? `${action} ${String(triggerId)}` : action;
|
|
6522
|
-
return [{ text, role: "target" }];
|
|
6523
|
-
},
|
|
6524
|
-
extractOutcome: () => void 0
|
|
6525
|
-
}
|
|
6526
|
-
],
|
|
6527
|
-
[
|
|
6528
|
-
"Skill",
|
|
6529
|
-
{
|
|
6530
|
-
display: "Skill",
|
|
6531
|
-
extractDetails: (input) => {
|
|
6532
|
-
const name = String(prop2(input, "skill") ?? "");
|
|
6533
|
-
const colonIdx = name.indexOf(":");
|
|
6534
|
-
const display = colonIdx >= 0 ? name.slice(colonIdx + 1) : name;
|
|
6535
|
-
return [{ text: display.replace(/^\//, ""), role: "target" }];
|
|
6536
|
-
},
|
|
6537
|
-
extractOutcome: () => void 0
|
|
6538
|
-
}
|
|
6539
|
-
]
|
|
6540
|
-
]);
|
|
6541
|
-
var MCP_VERB_DISPLAY = /* @__PURE__ */ new Map([
|
|
6542
|
-
// ── Navigation ──
|
|
6543
|
-
[
|
|
6544
|
-
"navigate",
|
|
6545
|
-
{
|
|
6546
|
-
display: "Navigate",
|
|
6547
|
-
extractDetails: (i) => [
|
|
6548
|
-
{ text: extractDomain(prop2(i, "url")), role: "target" }
|
|
6549
|
-
],
|
|
6550
|
-
extractOutcome: () => void 0
|
|
6551
|
-
}
|
|
6552
|
-
],
|
|
6553
|
-
[
|
|
6554
|
-
"reload",
|
|
6555
|
-
{
|
|
6556
|
-
display: "Reload",
|
|
6557
|
-
extractDetails: () => [],
|
|
6558
|
-
extractOutcome: () => void 0
|
|
6559
|
-
}
|
|
6560
|
-
],
|
|
6561
|
-
[
|
|
6562
|
-
"go_back",
|
|
6563
|
-
{
|
|
6564
|
-
display: "Back",
|
|
6565
|
-
extractDetails: () => [],
|
|
6566
|
-
extractOutcome: () => void 0
|
|
6567
|
-
}
|
|
6568
|
-
],
|
|
6569
|
-
[
|
|
6570
|
-
"go_forward",
|
|
6571
|
-
{
|
|
6572
|
-
display: "Forward",
|
|
6573
|
-
extractDetails: () => [],
|
|
6574
|
-
extractOutcome: () => void 0
|
|
6575
|
-
}
|
|
6576
|
-
],
|
|
6577
|
-
// ── Element interaction ──
|
|
6578
|
-
[
|
|
6579
|
-
"find_elements",
|
|
6580
|
-
{
|
|
6581
|
-
display: "Find",
|
|
6582
|
-
extractDetails: findDetailsExtractor,
|
|
6583
|
-
extractOutcome: foundCountOutcome
|
|
6584
|
-
}
|
|
6585
|
-
],
|
|
6586
|
-
[
|
|
6587
|
-
"click",
|
|
6588
|
-
{
|
|
6589
|
-
display: "Click",
|
|
6590
|
-
extractDetails: eidOrLabelExtractor,
|
|
6591
|
-
extractOutcome: () => void 0
|
|
6592
|
-
}
|
|
6593
|
-
],
|
|
6594
|
-
[
|
|
6595
|
-
"type",
|
|
6596
|
-
{
|
|
6597
|
-
display: "Type",
|
|
6598
|
-
extractDetails: typeDetailsExtractor,
|
|
6599
|
-
extractOutcome: () => void 0
|
|
6600
|
-
}
|
|
6601
|
-
],
|
|
6602
|
-
[
|
|
6603
|
-
"press",
|
|
6604
|
-
{
|
|
6605
|
-
display: "Press",
|
|
6606
|
-
extractDetails: (i) => [
|
|
6607
|
-
{ text: String(prop2(i, "key") ?? ""), role: "target" }
|
|
6608
|
-
],
|
|
6609
|
-
extractOutcome: () => void 0
|
|
6610
|
-
}
|
|
6611
|
-
],
|
|
6612
|
-
[
|
|
6613
|
-
"select",
|
|
6614
|
-
{
|
|
6615
|
-
display: "Select",
|
|
6616
|
-
extractDetails: (i) => [
|
|
6617
|
-
{ text: String(prop2(i, "value") ?? ""), role: "target" }
|
|
6618
|
-
],
|
|
6619
|
-
extractOutcome: () => void 0
|
|
6620
|
-
}
|
|
6621
|
-
],
|
|
6622
|
-
[
|
|
6623
|
-
"hover",
|
|
6624
|
-
{
|
|
6625
|
-
display: "Hover",
|
|
6626
|
-
extractDetails: eidOrLabelExtractor,
|
|
6627
|
-
extractOutcome: () => void 0
|
|
6628
|
-
}
|
|
6629
|
-
],
|
|
6630
|
-
// ── Inspection ──
|
|
6631
|
-
[
|
|
6632
|
-
"get_element_details",
|
|
6633
|
-
{
|
|
6634
|
-
display: "Inspect",
|
|
6635
|
-
extractDetails: eidExtractor2,
|
|
6636
|
-
extractOutcome: () => void 0
|
|
6637
|
-
}
|
|
6638
|
-
],
|
|
6639
|
-
[
|
|
6640
|
-
"take_screenshot",
|
|
6641
|
-
{
|
|
6642
|
-
display: "Screenshot",
|
|
6643
|
-
extractDetails: () => [],
|
|
6644
|
-
extractOutcome: () => ({ text: "captured", zero: false })
|
|
6645
|
-
}
|
|
6646
|
-
],
|
|
6647
|
-
[
|
|
6648
|
-
"capture_snapshot",
|
|
6649
|
-
{
|
|
6650
|
-
display: "Snapshot",
|
|
6651
|
-
extractDetails: () => [],
|
|
6652
|
-
extractOutcome: () => void 0
|
|
6653
|
-
}
|
|
6654
|
-
],
|
|
6655
|
-
[
|
|
6656
|
-
"get_form_understanding",
|
|
6657
|
-
{
|
|
6658
|
-
display: "FormScan",
|
|
6659
|
-
extractDetails: () => [],
|
|
6660
|
-
extractOutcome: formCountOutcome
|
|
6661
|
-
}
|
|
6662
|
-
],
|
|
6663
|
-
[
|
|
6664
|
-
"get_field_context",
|
|
6665
|
-
{
|
|
6666
|
-
display: "FieldCtx",
|
|
6667
|
-
extractDetails: eidExtractor2,
|
|
6668
|
-
extractOutcome: () => void 0
|
|
6669
|
-
}
|
|
6670
|
-
],
|
|
6671
|
-
// ── Scroll ──
|
|
6672
|
-
[
|
|
6673
|
-
"scroll_page",
|
|
6674
|
-
{
|
|
6675
|
-
display: "Scroll",
|
|
6676
|
-
extractDetails: scrollDetailsExtractor,
|
|
6677
|
-
extractOutcome: () => void 0
|
|
6678
|
-
}
|
|
6679
|
-
],
|
|
6680
|
-
[
|
|
6681
|
-
"scroll_element_into_view",
|
|
6682
|
-
{
|
|
6683
|
-
display: "ScrollTo",
|
|
6684
|
-
extractDetails: eidExtractor2,
|
|
6685
|
-
extractOutcome: () => void 0
|
|
6686
|
-
}
|
|
6687
|
-
],
|
|
6688
|
-
// ── Session ──
|
|
6689
|
-
[
|
|
6690
|
-
"close_session",
|
|
6691
|
-
{
|
|
6692
|
-
display: "Close",
|
|
6693
|
-
extractDetails: () => [{ text: "session", role: "target" }],
|
|
6694
|
-
extractOutcome: () => void 0
|
|
6695
|
-
}
|
|
6696
|
-
],
|
|
6697
|
-
[
|
|
6698
|
-
"close_page",
|
|
6699
|
-
{
|
|
6700
|
-
display: "ClosePage",
|
|
6701
|
-
extractDetails: tabRefExtractor,
|
|
6702
|
-
extractOutcome: () => void 0
|
|
6703
|
-
}
|
|
6704
|
-
],
|
|
6705
|
-
[
|
|
6706
|
-
"list_pages",
|
|
6707
|
-
{
|
|
6708
|
-
display: "ListPages",
|
|
6709
|
-
extractDetails: () => [],
|
|
6710
|
-
extractOutcome: tabCountOutcome
|
|
6711
|
-
}
|
|
6712
|
-
],
|
|
6713
|
-
[
|
|
6714
|
-
"ping",
|
|
6715
|
-
{
|
|
6716
|
-
display: "Ping",
|
|
6717
|
-
extractDetails: () => [],
|
|
6718
|
-
extractOutcome: pingOutcome
|
|
6719
|
-
}
|
|
6720
|
-
],
|
|
6721
|
-
// ── Context7 ──
|
|
6722
|
-
[
|
|
6723
|
-
"resolve-library-id",
|
|
6724
|
-
{
|
|
6725
|
-
display: "Resolve",
|
|
6726
|
-
extractDetails: (i) => [
|
|
6727
|
-
{
|
|
6728
|
-
text: truncate(String(prop2(i, "libraryName") ?? ""), 30),
|
|
6729
|
-
role: "target"
|
|
6730
|
-
}
|
|
6731
|
-
],
|
|
6732
|
-
extractOutcome: () => void 0
|
|
6733
|
-
}
|
|
6734
|
-
],
|
|
6735
|
-
[
|
|
6736
|
-
"query-docs",
|
|
6737
|
-
{
|
|
6738
|
-
display: "QueryDocs",
|
|
6739
|
-
extractDetails: (i) => [
|
|
6740
|
-
{
|
|
6741
|
-
text: truncate(String(prop2(i, "query") ?? ""), 40),
|
|
6742
|
-
role: "target"
|
|
6743
|
-
}
|
|
6744
|
-
],
|
|
6745
|
-
extractOutcome: () => void 0
|
|
6746
|
-
}
|
|
6747
|
-
]
|
|
6748
|
-
]);
|
|
6749
|
-
function humanizeToolName(raw) {
|
|
6750
|
-
const display = raw.split(/[_-]/).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
6751
|
-
return display.length > 14 ? display.slice(0, 13) + "\u2026" : display;
|
|
6752
|
-
}
|
|
6753
|
-
function resolveToolColumn(toolName) {
|
|
6754
|
-
const parsed = parseToolName(toolName);
|
|
6755
|
-
const known = KNOWN_TOOL_DISPLAY.get(parsed.displayName);
|
|
6756
|
-
if (known) return known.display;
|
|
6757
|
-
if (parsed.isMcp && parsed.mcpAction) {
|
|
6758
|
-
const mcp = MCP_VERB_DISPLAY.get(parsed.mcpAction);
|
|
6759
|
-
if (mcp) return mcp.display;
|
|
6760
|
-
}
|
|
6761
|
-
return parsed.isMcp && parsed.mcpAction ? humanizeToolName(parsed.mcpAction) : humanizeToolName(parsed.displayName);
|
|
6762
|
-
}
|
|
6763
|
-
function resolveEventToolColumn(event) {
|
|
6764
|
-
switch (event.kind) {
|
|
6765
|
-
case "subagent.start":
|
|
6766
|
-
case "subagent.stop":
|
|
6767
|
-
return event.data.agent_type;
|
|
6768
|
-
case "permission.request":
|
|
6769
|
-
return resolveToolColumn(event.data.tool_name);
|
|
6770
|
-
case "setup":
|
|
6771
|
-
case "session.start":
|
|
6772
|
-
case "session.end":
|
|
6773
|
-
case "run.start":
|
|
6774
|
-
case "run.end":
|
|
6775
|
-
case "user.prompt":
|
|
6776
|
-
case "plan.update":
|
|
6777
|
-
case "reasoning.summary":
|
|
6778
|
-
case "usage.update":
|
|
6779
|
-
case "tool.delta":
|
|
6780
|
-
case "tool.pre":
|
|
6781
|
-
case "tool.post":
|
|
6782
|
-
case "tool.failure":
|
|
6783
|
-
case "permission.decision":
|
|
6784
|
-
case "permission.denied":
|
|
6785
|
-
case "stop.request":
|
|
6786
|
-
case "stop.decision":
|
|
6787
|
-
case "stop.failure":
|
|
6788
|
-
case "notification":
|
|
6789
|
-
case "runtime.error":
|
|
6790
|
-
case "thread.status":
|
|
6791
|
-
case "turn.diff":
|
|
6792
|
-
case "server.request.resolved":
|
|
6793
|
-
case "web.search":
|
|
6794
|
-
case "review.status":
|
|
6795
|
-
case "image.view":
|
|
6796
|
-
case "context.compaction":
|
|
6797
|
-
case "mcp.progress":
|
|
6798
|
-
case "terminal.input":
|
|
6799
|
-
case "skills.changed":
|
|
6800
|
-
case "skills.loaded":
|
|
6801
|
-
case "compact.pre":
|
|
6802
|
-
case "compact.post":
|
|
6803
|
-
case "unknown.hook":
|
|
6804
|
-
case "todo.add":
|
|
6805
|
-
case "todo.update":
|
|
6806
|
-
case "todo.done":
|
|
6807
|
-
case "agent.message":
|
|
6808
|
-
case "teammate.idle":
|
|
6809
|
-
case "task.created":
|
|
6810
|
-
case "task.completed":
|
|
6811
|
-
case "config.change":
|
|
6812
|
-
case "cwd.changed":
|
|
6813
|
-
case "file.changed":
|
|
6814
|
-
case "elicitation.request":
|
|
6815
|
-
case "elicitation.result":
|
|
6816
|
-
case "channel.permission.relayed":
|
|
6817
|
-
case "channel.permission.resolved":
|
|
6818
|
-
case "channel.question.relayed":
|
|
6819
|
-
case "channel.question.resolved":
|
|
6820
|
-
case "channel.chat.inbound":
|
|
6821
|
-
case "channel.chat.outbound":
|
|
6822
|
-
case "gateway.function.invoked":
|
|
6823
|
-
case "gateway.function.completed":
|
|
6824
|
-
case "gateway.function.failed":
|
|
6825
|
-
case "artifacts.manifest":
|
|
6826
|
-
return "";
|
|
6827
|
-
}
|
|
6828
|
-
}
|
|
6829
|
-
|
|
6830
|
-
// src/core/feed/indexedTimeline.ts
|
|
6831
|
-
var MAX_SEARCH_CACHE_SIZE = 8;
|
|
6832
|
-
function subagentActorLabel(_agentType, _agentId) {
|
|
6833
|
-
return "SUB AGENT";
|
|
6834
|
-
}
|
|
6835
|
-
function buildSubagentTypeMap(feedEvents) {
|
|
6836
|
-
const map = /* @__PURE__ */ new Map();
|
|
6837
|
-
updateSubagentTypeMap(map, feedEvents);
|
|
6838
|
-
return map;
|
|
6839
|
-
}
|
|
6840
|
-
function updateSubagentTypeMap(map, feedEvents) {
|
|
6841
|
-
for (const event of feedEvents) {
|
|
6842
|
-
if (event.kind !== "subagent.start" && event.kind !== "subagent.stop") {
|
|
6843
|
-
continue;
|
|
6844
|
-
}
|
|
6845
|
-
const agentId = event.data.agent_id;
|
|
6846
|
-
const agentType = event.data.agent_type;
|
|
6847
|
-
if (!agentId || !agentType || map.has(agentId)) continue;
|
|
6848
|
-
map.set(agentId, agentType);
|
|
6849
|
-
}
|
|
6850
|
-
}
|
|
6851
|
-
function resolveActorLabel(event, subagentTypes) {
|
|
6852
|
-
if (!event.actor_id.startsWith("subagent:")) {
|
|
6853
|
-
return actorLabel(event.actor_id);
|
|
6854
|
-
}
|
|
6855
|
-
const agentId = event.actor_id.slice("subagent:".length);
|
|
6856
|
-
const eventAgentType = event.kind === "subagent.start" || event.kind === "subagent.stop" ? event.data.agent_type : void 0;
|
|
6857
|
-
return subagentActorLabel(
|
|
6858
|
-
eventAgentType || subagentTypes.get(agentId),
|
|
6859
|
-
agentId
|
|
4110
|
+
}
|
|
4111
|
+
if (key.downArrow) {
|
|
4112
|
+
callbacks.moveCursor(1);
|
|
4113
|
+
return;
|
|
4114
|
+
}
|
|
4115
|
+
} finally {
|
|
4116
|
+
done();
|
|
4117
|
+
}
|
|
4118
|
+
},
|
|
4119
|
+
{ isActive }
|
|
6860
4120
|
);
|
|
6861
4121
|
}
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
}
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
}
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
runId: event.run_id,
|
|
6926
|
-
op,
|
|
6927
|
-
opTag,
|
|
6928
|
-
actor: resolveActorLabel(event, subagentTypes),
|
|
6929
|
-
actorId: event.actor_id,
|
|
6930
|
-
toolColumn,
|
|
6931
|
-
summary,
|
|
6932
|
-
summarySegments,
|
|
6933
|
-
summaryOutcome: summaryResult.outcome,
|
|
6934
|
-
summaryOutcomeZero: summaryResult.outcomeZero,
|
|
6935
|
-
searchText: summary,
|
|
6936
|
-
error: isEventError(event) || pairedPost?.kind === "tool.failure",
|
|
6937
|
-
expandable: isEventExpandable(event),
|
|
6938
|
-
details: "",
|
|
6939
|
-
feedEvent: event,
|
|
6940
|
-
pairedPostEvent: pairedPost,
|
|
6941
|
-
duplicateActor: false
|
|
6942
|
-
};
|
|
6943
|
-
}
|
|
6944
|
-
function maybeBuildEventEntry(event, subagentTypes, postByToolUseId, verbose) {
|
|
6945
|
-
if (shouldSkipEvent(event, verbose)) return null;
|
|
6946
|
-
if (event.kind === "tool.delta") return null;
|
|
6947
|
-
if (mergedToolUseId(event, postByToolUseId)) {
|
|
6948
|
-
return null;
|
|
6949
|
-
}
|
|
6950
|
-
return buildEventEntry(
|
|
6951
|
-
event,
|
|
6952
|
-
subagentTypes,
|
|
6953
|
-
pairedPostForEvent(event, postByToolUseId)
|
|
4122
|
+
|
|
4123
|
+
// src/ui/hooks/useTodoKeyboard.ts
|
|
4124
|
+
import { useRef as useRef8 } from "react";
|
|
4125
|
+
import { useInput as useInput10 } from "ink";
|
|
4126
|
+
function useTodoKeyboard({
|
|
4127
|
+
isActive,
|
|
4128
|
+
todoCursor,
|
|
4129
|
+
visibleTodoItems,
|
|
4130
|
+
filteredEntries,
|
|
4131
|
+
callbacks
|
|
4132
|
+
}) {
|
|
4133
|
+
const visibleTodoItemsRef = useRef8(visibleTodoItems);
|
|
4134
|
+
visibleTodoItemsRef.current = visibleTodoItems;
|
|
4135
|
+
const filteredEntriesRef = useRef8(filteredEntries);
|
|
4136
|
+
filteredEntriesRef.current = filteredEntries;
|
|
4137
|
+
useInput10(
|
|
4138
|
+
(input, key) => {
|
|
4139
|
+
const done = startInputMeasure("todo.keyboard", input, key);
|
|
4140
|
+
try {
|
|
4141
|
+
if (key.escape) {
|
|
4142
|
+
callbacks.focusFeed();
|
|
4143
|
+
return;
|
|
4144
|
+
}
|
|
4145
|
+
if (key.tab) {
|
|
4146
|
+
callbacks.cycleFocus();
|
|
4147
|
+
return;
|
|
4148
|
+
}
|
|
4149
|
+
if (key.upArrow) {
|
|
4150
|
+
callbacks.moveTodoCursor(-1);
|
|
4151
|
+
return;
|
|
4152
|
+
}
|
|
4153
|
+
if (key.downArrow) {
|
|
4154
|
+
callbacks.moveTodoCursor(1);
|
|
4155
|
+
return;
|
|
4156
|
+
}
|
|
4157
|
+
if (input === " ") {
|
|
4158
|
+
callbacks.toggleTodoStatus(todoCursor);
|
|
4159
|
+
return;
|
|
4160
|
+
}
|
|
4161
|
+
if (key.return) {
|
|
4162
|
+
if (todoCursor < 0 || todoCursor >= visibleTodoItemsRef.current.length) {
|
|
4163
|
+
return;
|
|
4164
|
+
}
|
|
4165
|
+
const selected = visibleTodoItemsRef.current[todoCursor];
|
|
4166
|
+
if (!selected.linkedEventId) return;
|
|
4167
|
+
const idx = filteredEntriesRef.current.findIndex(
|
|
4168
|
+
(entry) => entry.id === selected.linkedEventId
|
|
4169
|
+
);
|
|
4170
|
+
if (idx >= 0) {
|
|
4171
|
+
callbacks.revealFeedCursor(idx);
|
|
4172
|
+
}
|
|
4173
|
+
return;
|
|
4174
|
+
}
|
|
4175
|
+
if (input.toLowerCase() === "a") {
|
|
4176
|
+
callbacks.openNormalInput();
|
|
4177
|
+
callbacks.setInputValue("");
|
|
4178
|
+
return;
|
|
4179
|
+
}
|
|
4180
|
+
} finally {
|
|
4181
|
+
done();
|
|
4182
|
+
}
|
|
4183
|
+
},
|
|
4184
|
+
{ isActive }
|
|
6954
4185
|
);
|
|
6955
4186
|
}
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
entry.duplicateActor = false;
|
|
6968
|
-
return;
|
|
6969
|
-
}
|
|
6970
|
-
const prev = entries[index - 1];
|
|
6971
|
-
const sameActor = entry.actorId === prev.actorId;
|
|
6972
|
-
const isBreak = opCategory(entry.opTag) !== opCategory(prev.opTag);
|
|
6973
|
-
entry.duplicateActor = sameActor && !isBreak;
|
|
6974
|
-
}
|
|
6975
|
-
function recomputeDuplicateActorsAround(entries, index) {
|
|
6976
|
-
recomputeDuplicateActorAt(entries, index);
|
|
6977
|
-
if (index + 1 < entries.length) {
|
|
6978
|
-
recomputeDuplicateActorAt(entries, index + 1);
|
|
6979
|
-
}
|
|
6980
|
-
}
|
|
6981
|
-
function sameFeedItemPrefix(previous, next) {
|
|
6982
|
-
if (next.length < previous.length) return false;
|
|
6983
|
-
for (let i = 0; i < previous.length; i++) {
|
|
6984
|
-
const prev = previous[i];
|
|
6985
|
-
const curr = next[i];
|
|
6986
|
-
if (prev.type !== curr.type || prev.data !== curr.data) {
|
|
6987
|
-
return false;
|
|
6988
|
-
}
|
|
6989
|
-
}
|
|
6990
|
-
return true;
|
|
6991
|
-
}
|
|
6992
|
-
function sameFeedEventPrefix(previous, next) {
|
|
6993
|
-
if (next.length < previous.length) return false;
|
|
6994
|
-
for (let i = 0; i < previous.length; i++) {
|
|
6995
|
-
if (previous[i] !== next[i]) {
|
|
6996
|
-
return false;
|
|
4187
|
+
|
|
4188
|
+
// src/ui/hooks/useSpinner.ts
|
|
4189
|
+
import { useState as useState8, useEffect as useEffect7 } from "react";
|
|
4190
|
+
var BRAILLE_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
4191
|
+
var DEFAULT_SPINNER_INTERVAL_MS = 1e3;
|
|
4192
|
+
function useSpinner(active, intervalMs = DEFAULT_SPINNER_INTERVAL_MS) {
|
|
4193
|
+
const [frameIndex, setFrameIndex] = useState8(0);
|
|
4194
|
+
useEffect7(() => {
|
|
4195
|
+
if (!active) {
|
|
4196
|
+
setFrameIndex(0);
|
|
4197
|
+
return;
|
|
6997
4198
|
}
|
|
6998
|
-
|
|
6999
|
-
|
|
4199
|
+
const timer = setInterval(() => {
|
|
4200
|
+
startPerfCycle("timer:spinner", { scope: "spinner" });
|
|
4201
|
+
setFrameIndex((i) => (i + 1) % BRAILLE_FRAMES.length);
|
|
4202
|
+
}, intervalMs);
|
|
4203
|
+
return () => clearInterval(timer);
|
|
4204
|
+
}, [active, intervalMs]);
|
|
4205
|
+
if (!active) return "";
|
|
4206
|
+
return BRAILLE_FRAMES[frameIndex] ?? "\u280B";
|
|
7000
4207
|
}
|
|
7001
|
-
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
4208
|
+
|
|
4209
|
+
// src/ui/hooks/useTodoDisplayItems.ts
|
|
4210
|
+
import { useEffect as useEffect8, useMemo as useMemo8, useState as useState9 } from "react";
|
|
4211
|
+
function hasTickingElapsedItems(items) {
|
|
4212
|
+
return items.some(
|
|
4213
|
+
(item) => item.status === "doing" && item.startedAtMs !== void 0
|
|
4214
|
+
);
|
|
7005
4215
|
}
|
|
7006
|
-
function
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
const event = item.data;
|
|
7018
|
-
if (event.kind === "run.start") {
|
|
7019
|
-
activeRunId = event.run_id;
|
|
7020
|
-
}
|
|
7021
|
-
const entry = maybeBuildEventEntry(
|
|
7022
|
-
event,
|
|
7023
|
-
subagentTypes,
|
|
7024
|
-
postByToolUseId,
|
|
7025
|
-
verbose
|
|
7026
|
-
);
|
|
7027
|
-
if (entry) {
|
|
7028
|
-
const index = entries.push(entry) - 1;
|
|
7029
|
-
rememberPendingEntry(pendingEntryIndexByToolUseId, entry, index);
|
|
7030
|
-
}
|
|
7031
|
-
if (event.kind === "run.end") {
|
|
7032
|
-
activeRunId = void 0;
|
|
7033
|
-
}
|
|
7034
|
-
}
|
|
7035
|
-
computeDuplicateActors(entries);
|
|
7036
|
-
return {
|
|
7037
|
-
feedItems,
|
|
7038
|
-
feedEvents,
|
|
7039
|
-
entries,
|
|
7040
|
-
activeRunId,
|
|
7041
|
-
messageCounter,
|
|
7042
|
-
subagentTypes,
|
|
7043
|
-
pendingEntryIndexByToolUseId,
|
|
7044
|
-
verbose
|
|
7045
|
-
};
|
|
4216
|
+
function buildTodoDisplayItems(items, nowMs, isWorking, pausedAtMs) {
|
|
4217
|
+
let changed = false;
|
|
4218
|
+
const nextItems = items.map((item) => {
|
|
4219
|
+
const hasElapsed = item.startedAtMs !== void 0 && (item.status === "doing" || item.status === "done" || item.status === "failed");
|
|
4220
|
+
const endMs = item.completedAtMs ?? (isWorking ? nowMs : pausedAtMs ?? nowMs);
|
|
4221
|
+
const elapsed = hasElapsed ? formatElapsed(Math.max(0, endMs - item.startedAtMs)) : void 0;
|
|
4222
|
+
if (elapsed === item.elapsed) return item;
|
|
4223
|
+
changed = true;
|
|
4224
|
+
return { ...item, elapsed };
|
|
4225
|
+
});
|
|
4226
|
+
return changed ? nextItems : items;
|
|
7046
4227
|
}
|
|
7047
|
-
function
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
const
|
|
7055
|
-
|
|
4228
|
+
function useTodoDisplayItems({
|
|
4229
|
+
items,
|
|
4230
|
+
isWorking,
|
|
4231
|
+
pausedAtMs,
|
|
4232
|
+
active,
|
|
4233
|
+
tickMs = 1e3
|
|
4234
|
+
}) {
|
|
4235
|
+
const [nowMs, setNowMs] = useState9(() => Date.now());
|
|
4236
|
+
const hasDoingItems = useMemo8(() => hasTickingElapsedItems(items), [items]);
|
|
4237
|
+
useEffect8(() => {
|
|
4238
|
+
if (!active || !isWorking || !hasDoingItems) return;
|
|
4239
|
+
const id = setInterval(() => {
|
|
4240
|
+
startPerfCycle("timer:todo-header", {
|
|
4241
|
+
scope: "todo.elapsed",
|
|
4242
|
+
items: items.length
|
|
4243
|
+
});
|
|
4244
|
+
setNowMs(Date.now());
|
|
4245
|
+
}, tickMs);
|
|
4246
|
+
return () => clearInterval(id);
|
|
4247
|
+
}, [active, isWorking, hasDoingItems, items.length, tickMs]);
|
|
4248
|
+
return useMemo8(
|
|
4249
|
+
() => buildTodoDisplayItems(items, nowMs, isWorking, pausedAtMs),
|
|
4250
|
+
[items, nowMs, isWorking, pausedAtMs]
|
|
7056
4251
|
);
|
|
7057
|
-
let activeRunId = previous.activeRunId;
|
|
7058
|
-
let messageCounter = previous.messageCounter;
|
|
7059
|
-
for (const item of feedItems.slice(previous.feedItems.length)) {
|
|
7060
|
-
if (item.type === "message") {
|
|
7061
|
-
const index = entries.push(
|
|
7062
|
-
buildMessageEntry(item.data, activeRunId, messageCounter++)
|
|
7063
|
-
) - 1;
|
|
7064
|
-
recomputeDuplicateActorsAround(entries, index);
|
|
7065
|
-
continue;
|
|
7066
|
-
}
|
|
7067
|
-
const event = item.data;
|
|
7068
|
-
if (event.kind === "run.start") {
|
|
7069
|
-
activeRunId = event.run_id;
|
|
7070
|
-
}
|
|
7071
|
-
const resolvedToolUseId = pendingToolUpdateUseId(event);
|
|
7072
|
-
if (resolvedToolUseId) {
|
|
7073
|
-
const pendingIndex = pendingEntryIndexByToolUseId.get(resolvedToolUseId);
|
|
7074
|
-
if (pendingIndex !== void 0) {
|
|
7075
|
-
const pendingEntry = entries[pendingIndex];
|
|
7076
|
-
if (pendingEntry.feedEvent) {
|
|
7077
|
-
entries[pendingIndex] = buildEventEntry(
|
|
7078
|
-
pendingEntry.feedEvent,
|
|
7079
|
-
subagentTypes,
|
|
7080
|
-
event
|
|
7081
|
-
);
|
|
7082
|
-
if (event.kind === "tool.post" || event.kind === "tool.failure") {
|
|
7083
|
-
pendingEntryIndexByToolUseId.delete(resolvedToolUseId);
|
|
7084
|
-
}
|
|
7085
|
-
recomputeDuplicateActorsAround(entries, pendingIndex);
|
|
7086
|
-
}
|
|
7087
|
-
}
|
|
7088
|
-
continue;
|
|
7089
|
-
}
|
|
7090
|
-
const entry = maybeBuildEventEntry(
|
|
7091
|
-
event,
|
|
7092
|
-
subagentTypes,
|
|
7093
|
-
postByToolUseId,
|
|
7094
|
-
previous.verbose
|
|
7095
|
-
);
|
|
7096
|
-
if (entry) {
|
|
7097
|
-
const index = entries.push(entry) - 1;
|
|
7098
|
-
recomputeDuplicateActorsAround(entries, index);
|
|
7099
|
-
rememberPendingEntry(pendingEntryIndexByToolUseId, entry, index);
|
|
7100
|
-
}
|
|
7101
|
-
if (event.kind === "run.end") {
|
|
7102
|
-
activeRunId = void 0;
|
|
7103
|
-
}
|
|
7104
|
-
}
|
|
7105
|
-
return {
|
|
7106
|
-
feedItems,
|
|
7107
|
-
feedEvents,
|
|
7108
|
-
entries,
|
|
7109
|
-
activeRunId,
|
|
7110
|
-
messageCounter,
|
|
7111
|
-
subagentTypes,
|
|
7112
|
-
pendingEntryIndexByToolUseId,
|
|
7113
|
-
verbose: previous.verbose
|
|
7114
|
-
};
|
|
7115
4252
|
}
|
|
7116
|
-
var IndexedTimeline = class {
|
|
7117
|
-
cache = null;
|
|
7118
|
-
runIndex = /* @__PURE__ */ new Map();
|
|
7119
|
-
errorPositions = /* @__PURE__ */ new Set();
|
|
7120
|
-
_runSummaryMap = /* @__PURE__ */ new Map();
|
|
7121
|
-
_runSummariesDirty = true;
|
|
7122
|
-
_runSummariesCache = [];
|
|
7123
|
-
_lastFeedEventsLength = 0;
|
|
7124
|
-
searchCache = /* @__PURE__ */ new Map();
|
|
7125
|
-
lastFilteredRef = null;
|
|
7126
|
-
detailCache = /* @__PURE__ */ new WeakMap();
|
|
7127
|
-
searchTextCache = /* @__PURE__ */ new WeakMap();
|
|
7128
|
-
verbose = false;
|
|
7129
|
-
update(feedItems, feedEvents, postByToolUseId, verbose) {
|
|
7130
|
-
this.verbose = verbose;
|
|
7131
|
-
const incremental = canAppendIncrementally(
|
|
7132
|
-
this.cache,
|
|
7133
|
-
feedItems,
|
|
7134
|
-
feedEvents,
|
|
7135
|
-
this.verbose
|
|
7136
|
-
);
|
|
7137
|
-
if (incremental) {
|
|
7138
|
-
this.updateRunSummaries(feedEvents);
|
|
7139
|
-
this.cache = appendTimelineCache(
|
|
7140
|
-
this.cache,
|
|
7141
|
-
feedItems,
|
|
7142
|
-
feedEvents,
|
|
7143
|
-
postByToolUseId
|
|
7144
|
-
);
|
|
7145
|
-
} else {
|
|
7146
|
-
this.rebuildRunSummaries(feedEvents);
|
|
7147
|
-
this.cache = buildTimelineCache(
|
|
7148
|
-
feedItems,
|
|
7149
|
-
feedEvents,
|
|
7150
|
-
postByToolUseId,
|
|
7151
|
-
this.verbose
|
|
7152
|
-
);
|
|
7153
|
-
}
|
|
7154
|
-
this.rebuildIndexes();
|
|
7155
|
-
}
|
|
7156
|
-
getEntries() {
|
|
7157
|
-
return this.cache?.entries ?? [];
|
|
7158
|
-
}
|
|
7159
|
-
getFilteredView(runFilter, errorsOnly) {
|
|
7160
|
-
const entries = this.getEntries();
|
|
7161
|
-
if ((!runFilter || runFilter === "all") && !errorsOnly) {
|
|
7162
|
-
return entries;
|
|
7163
|
-
}
|
|
7164
|
-
let candidateIndices;
|
|
7165
|
-
if (runFilter && runFilter !== "all") {
|
|
7166
|
-
candidateIndices = this.runIndex.get(runFilter) ?? [];
|
|
7167
|
-
} else {
|
|
7168
|
-
candidateIndices = Array.from({ length: entries.length }, (_, i) => i);
|
|
7169
|
-
}
|
|
7170
|
-
if (errorsOnly) {
|
|
7171
|
-
candidateIndices = candidateIndices.filter(
|
|
7172
|
-
(i) => this.errorPositions.has(i)
|
|
7173
|
-
);
|
|
7174
|
-
}
|
|
7175
|
-
return candidateIndices.map((i) => entries[i]);
|
|
7176
|
-
}
|
|
7177
|
-
getSearchMatches(filteredEntries, query) {
|
|
7178
|
-
const q = query.trim().toLowerCase();
|
|
7179
|
-
if (!q) return [];
|
|
7180
|
-
if (filteredEntries !== this.lastFilteredRef) {
|
|
7181
|
-
this.searchCache.clear();
|
|
7182
|
-
this.lastFilteredRef = filteredEntries;
|
|
7183
|
-
}
|
|
7184
|
-
const cached = this.searchCache.get(q);
|
|
7185
|
-
if (cached && cached.lastScanned === filteredEntries.length) {
|
|
7186
|
-
return cached.matches;
|
|
7187
|
-
}
|
|
7188
|
-
const startFrom = cached ? cached.lastScanned : 0;
|
|
7189
|
-
const matches = cached ? [...cached.matches] : [];
|
|
7190
|
-
for (let i = startFrom; i < filteredEntries.length; i++) {
|
|
7191
|
-
const searchText = this.getEntrySearchText(filteredEntries[i]);
|
|
7192
|
-
if (searchText.toLowerCase().includes(q)) {
|
|
7193
|
-
matches.push(i);
|
|
7194
|
-
}
|
|
7195
|
-
}
|
|
7196
|
-
this.searchCache.set(q, { matches, lastScanned: filteredEntries.length });
|
|
7197
|
-
if (this.searchCache.size > MAX_SEARCH_CACHE_SIZE) {
|
|
7198
|
-
const oldest = this.searchCache.keys().next().value;
|
|
7199
|
-
if (oldest !== void 0) {
|
|
7200
|
-
this.searchCache.delete(oldest);
|
|
7201
|
-
}
|
|
7202
|
-
}
|
|
7203
|
-
return matches;
|
|
7204
|
-
}
|
|
7205
|
-
getEntrySearchText(entry) {
|
|
7206
|
-
const cached = this.searchTextCache.get(entry);
|
|
7207
|
-
if (cached !== void 0) return cached;
|
|
7208
|
-
if (!entry.feedEvent) {
|
|
7209
|
-
this.searchTextCache.set(entry, entry.searchText);
|
|
7210
|
-
return entry.searchText;
|
|
7211
|
-
}
|
|
7212
|
-
const details = this.getEntryDetails(entry);
|
|
7213
|
-
const searchText = details ? `${entry.summary}
|
|
7214
|
-
${details}` : entry.summary;
|
|
7215
|
-
this.searchTextCache.set(entry, searchText);
|
|
7216
|
-
return searchText;
|
|
7217
|
-
}
|
|
7218
|
-
getEntryDetails(entry) {
|
|
7219
|
-
if (entry.details) return entry.details;
|
|
7220
|
-
if (!entry.feedEvent) return entry.summary;
|
|
7221
|
-
const cached = this.detailCache.get(entry);
|
|
7222
|
-
if (cached !== void 0) return cached;
|
|
7223
|
-
const details = isEventExpandable(entry.feedEvent) ? expansionForEvent(entry.feedEvent) : "";
|
|
7224
|
-
this.detailCache.set(entry, details);
|
|
7225
|
-
return details;
|
|
7226
|
-
}
|
|
7227
|
-
getRunSummaries() {
|
|
7228
|
-
if (this._runSummariesDirty) {
|
|
7229
|
-
this._runSummariesCache = Array.from(this._runSummaryMap.values()).sort(
|
|
7230
|
-
(a, b) => a.startedAt - b.startedAt
|
|
7231
|
-
);
|
|
7232
|
-
this._runSummariesDirty = false;
|
|
7233
|
-
}
|
|
7234
|
-
return this._runSummariesCache;
|
|
7235
|
-
}
|
|
7236
|
-
processRunEvent(event) {
|
|
7237
|
-
if (event.kind === "run.start") {
|
|
7238
|
-
this._runSummaryMap.set(event.run_id, {
|
|
7239
|
-
runId: event.run_id,
|
|
7240
|
-
title: compactText(
|
|
7241
|
-
event.data.trigger.prompt_preview || "Untitled run",
|
|
7242
|
-
46
|
|
7243
|
-
),
|
|
7244
|
-
status: "RUNNING",
|
|
7245
|
-
startedAt: event.ts
|
|
7246
|
-
});
|
|
7247
|
-
this._runSummariesDirty = true;
|
|
7248
|
-
} else if (event.kind === "run.end") {
|
|
7249
|
-
const existing = this._runSummaryMap.get(event.run_id);
|
|
7250
|
-
if (existing) {
|
|
7251
|
-
existing.status = toRunStatus(event);
|
|
7252
|
-
existing.endedAt = event.ts;
|
|
7253
|
-
} else {
|
|
7254
|
-
this._runSummaryMap.set(event.run_id, {
|
|
7255
|
-
runId: event.run_id,
|
|
7256
|
-
title: "Untitled run",
|
|
7257
|
-
status: toRunStatus(event),
|
|
7258
|
-
startedAt: event.ts,
|
|
7259
|
-
endedAt: event.ts
|
|
7260
|
-
});
|
|
7261
|
-
}
|
|
7262
|
-
this._runSummariesDirty = true;
|
|
7263
|
-
}
|
|
7264
|
-
}
|
|
7265
|
-
rebuildRunSummaries(feedEvents) {
|
|
7266
|
-
this._runSummaryMap.clear();
|
|
7267
|
-
this._runSummariesDirty = true;
|
|
7268
|
-
this._lastFeedEventsLength = 0;
|
|
7269
|
-
this.updateRunSummaries(feedEvents);
|
|
7270
|
-
}
|
|
7271
|
-
updateRunSummaries(feedEvents) {
|
|
7272
|
-
for (let i = this._lastFeedEventsLength; i < feedEvents.length; i++) {
|
|
7273
|
-
this.processRunEvent(feedEvents[i]);
|
|
7274
|
-
}
|
|
7275
|
-
this._lastFeedEventsLength = feedEvents.length;
|
|
7276
|
-
}
|
|
7277
|
-
addToIndex(entry, index) {
|
|
7278
|
-
const runId = entry.runId ?? "__none__";
|
|
7279
|
-
let indices = this.runIndex.get(runId);
|
|
7280
|
-
if (!indices) {
|
|
7281
|
-
indices = [];
|
|
7282
|
-
this.runIndex.set(runId, indices);
|
|
7283
|
-
}
|
|
7284
|
-
indices.push(index);
|
|
7285
|
-
if (entry.error) {
|
|
7286
|
-
this.errorPositions.add(index);
|
|
7287
|
-
}
|
|
7288
|
-
}
|
|
7289
|
-
rebuildIndexes() {
|
|
7290
|
-
this.runIndex.clear();
|
|
7291
|
-
this.errorPositions.clear();
|
|
7292
|
-
this.searchCache.clear();
|
|
7293
|
-
const entries = this.getEntries();
|
|
7294
|
-
for (let i = 0; i < entries.length; i++) {
|
|
7295
|
-
this.addToIndex(entries[i], i);
|
|
7296
|
-
}
|
|
7297
|
-
}
|
|
7298
|
-
};
|
|
7299
4253
|
|
|
7300
4254
|
// src/ui/hooks/useTimeline.ts
|
|
4255
|
+
import { useMemo as useMemo9, useRef as useRef9, useCallback as useCallback10 } from "react";
|
|
7301
4256
|
var EMPTY_MATCHES = Object.freeze([]);
|
|
7302
4257
|
var EMPTY_MATCH_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
7303
4258
|
function useTimeline({
|
|
@@ -7536,7 +4491,7 @@ function detectLanguage(filePath) {
|
|
|
7536
4491
|
function isMarkdownRenderable(language) {
|
|
7537
4492
|
return language === void 0 || language === "markdown";
|
|
7538
4493
|
}
|
|
7539
|
-
function
|
|
4494
|
+
function prop(obj, key) {
|
|
7540
4495
|
if (typeof obj === "object" && obj !== null) {
|
|
7541
4496
|
return obj[key];
|
|
7542
4497
|
}
|
|
@@ -7551,21 +4506,21 @@ function extractTextContent(response) {
|
|
|
7551
4506
|
if (typeof block === "string") {
|
|
7552
4507
|
parts.push(block);
|
|
7553
4508
|
} else if (typeof block === "object" && block !== null) {
|
|
7554
|
-
const text =
|
|
4509
|
+
const text = prop(block, "text");
|
|
7555
4510
|
if (typeof text === "string") parts.push(text);
|
|
7556
4511
|
}
|
|
7557
4512
|
}
|
|
7558
4513
|
if (parts.length > 0) return parts.join("\n").trim();
|
|
7559
4514
|
}
|
|
7560
4515
|
if (typeof response === "object") {
|
|
7561
|
-
const text =
|
|
7562
|
-
if (typeof text === "string" &&
|
|
4516
|
+
const text = prop(response, "text");
|
|
4517
|
+
if (typeof text === "string" && prop(response, "type") === "text") {
|
|
7563
4518
|
return text.trim();
|
|
7564
4519
|
}
|
|
7565
|
-
const content =
|
|
4520
|
+
const content = prop(response, "content");
|
|
7566
4521
|
if (content != null) return extractTextContent(content);
|
|
7567
4522
|
for (const key of ["result", "message", "output"]) {
|
|
7568
|
-
const val =
|
|
4523
|
+
const val = prop(response, key);
|
|
7569
4524
|
if (typeof val === "string") return val;
|
|
7570
4525
|
}
|
|
7571
4526
|
}
|
|
@@ -7610,10 +4565,10 @@ ${err}` : err : out;
|
|
|
7610
4565
|
}
|
|
7611
4566
|
return { type: "code", content: extractTextContent(response), maxLines: 10 };
|
|
7612
4567
|
}
|
|
7613
|
-
function
|
|
7614
|
-
const fileContent =
|
|
4568
|
+
function extractFileContent(block) {
|
|
4569
|
+
const fileContent = prop(prop(block, "file"), "content");
|
|
7615
4570
|
if (typeof fileContent === "string") return fileContent;
|
|
7616
|
-
const text =
|
|
4571
|
+
const text = prop(block, "text");
|
|
7617
4572
|
if (typeof text === "string") return text;
|
|
7618
4573
|
return void 0;
|
|
7619
4574
|
}
|
|
@@ -7621,7 +4576,7 @@ function extractRead(input, response) {
|
|
|
7621
4576
|
const blocks = Array.isArray(response) ? response : [response];
|
|
7622
4577
|
let content;
|
|
7623
4578
|
for (const block of blocks) {
|
|
7624
|
-
content =
|
|
4579
|
+
content = extractFileContent(block);
|
|
7625
4580
|
if (content) break;
|
|
7626
4581
|
}
|
|
7627
4582
|
const language = detectLanguage(input["file_path"]);
|
|
@@ -7639,9 +4594,9 @@ function parseDiffLine(raw) {
|
|
|
7639
4594
|
return { type: "context", content };
|
|
7640
4595
|
}
|
|
7641
4596
|
function parseStructuredPatch(response) {
|
|
7642
|
-
const patch =
|
|
4597
|
+
const patch = prop(response, "structuredPatch");
|
|
7643
4598
|
if (!patch) return void 0;
|
|
7644
|
-
const rawHunks =
|
|
4599
|
+
const rawHunks = prop(patch, "hunks");
|
|
7645
4600
|
if (!Array.isArray(rawHunks)) return void 0;
|
|
7646
4601
|
return rawHunks.map((h) => {
|
|
7647
4602
|
const oldStart = typeof h.oldStart === "number" ? h.oldStart : 1;
|
|
@@ -7678,7 +4633,7 @@ function extractWrite(input, response) {
|
|
|
7678
4633
|
}
|
|
7679
4634
|
const content = typeof input["content"] === "string" ? input["content"] : "";
|
|
7680
4635
|
const filePath = String(
|
|
7681
|
-
|
|
4636
|
+
prop(response, "filePath") ?? input["file_path"] ?? ""
|
|
7682
4637
|
);
|
|
7683
4638
|
if (!content) {
|
|
7684
4639
|
return { type: "text", content: `Wrote ${filePath}` };
|
|
@@ -7705,7 +4660,7 @@ function extractGrep(_input, response) {
|
|
|
7705
4660
|
return { type: "list", items, maxItems: 10, groupBy: "secondary" };
|
|
7706
4661
|
}
|
|
7707
4662
|
function extractGlob(_input, response) {
|
|
7708
|
-
const filenames =
|
|
4663
|
+
const filenames = prop(response, "filenames");
|
|
7709
4664
|
if (Array.isArray(filenames)) {
|
|
7710
4665
|
const items2 = filenames.filter((f) => typeof f === "string").map((f) => ({ primary: f }));
|
|
7711
4666
|
return { type: "list", items: items2, maxItems: 10, displayMode: "tree" };
|
|
@@ -7715,22 +4670,22 @@ function extractGlob(_input, response) {
|
|
|
7715
4670
|
return { type: "list", items, maxItems: 10 };
|
|
7716
4671
|
}
|
|
7717
4672
|
function extractWebFetch(_input, response) {
|
|
7718
|
-
const result =
|
|
4673
|
+
const result = prop(response, "result");
|
|
7719
4674
|
const content = typeof result === "string" ? result : extractTextContent(response);
|
|
7720
4675
|
return { type: "text", content, maxLines: 10 };
|
|
7721
4676
|
}
|
|
7722
4677
|
function formatSearchLink(item) {
|
|
7723
|
-
const title =
|
|
4678
|
+
const title = prop(item, "title");
|
|
7724
4679
|
if (typeof title !== "string") return null;
|
|
7725
|
-
const url =
|
|
4680
|
+
const url = prop(item, "url");
|
|
7726
4681
|
return typeof url === "string" ? `- [${title}](${url})` : `- ${title}`;
|
|
7727
4682
|
}
|
|
7728
4683
|
function extractWebSearch(_input, response) {
|
|
7729
|
-
const results =
|
|
4684
|
+
const results = prop(response, "results");
|
|
7730
4685
|
if (Array.isArray(results)) {
|
|
7731
4686
|
const links = [];
|
|
7732
4687
|
for (const entry of results) {
|
|
7733
|
-
const content =
|
|
4688
|
+
const content = prop(entry, "content");
|
|
7734
4689
|
const items = Array.isArray(content) ? content : [entry];
|
|
7735
4690
|
for (const item of items) {
|
|
7736
4691
|
const link = formatSearchLink(item);
|
|
@@ -7768,10 +4723,10 @@ function extractSkill(input, response) {
|
|
|
7768
4723
|
}
|
|
7769
4724
|
if (typeof response === "object" && response !== null) {
|
|
7770
4725
|
const items = [];
|
|
7771
|
-
const success =
|
|
7772
|
-
const commandName =
|
|
7773
|
-
const message =
|
|
7774
|
-
const allowedTools =
|
|
4726
|
+
const success = prop(response, "success");
|
|
4727
|
+
const commandName = prop(response, "commandName");
|
|
4728
|
+
const message = prop(response, "message");
|
|
4729
|
+
const allowedTools = prop(response, "allowedTools");
|
|
7775
4730
|
if (skill) items.push({ secondary: "skill", primary: skill });
|
|
7776
4731
|
if (typeof commandName === "string" && commandName.trim()) {
|
|
7777
4732
|
items.push({ secondary: "command", primary: commandName.trim() });
|
|
@@ -8298,7 +5253,7 @@ function extractToolSubject(toolName, toolInput) {
|
|
|
8298
5253
|
return void 0;
|
|
8299
5254
|
}
|
|
8300
5255
|
}
|
|
8301
|
-
function
|
|
5256
|
+
function eventLabel(event) {
|
|
8302
5257
|
if (isDefaultRenderKind(event.kind)) return "Event";
|
|
8303
5258
|
switch (event.kind) {
|
|
8304
5259
|
case "tool.delta":
|
|
@@ -8384,7 +5339,7 @@ function eventLabel2(event) {
|
|
|
8384
5339
|
}
|
|
8385
5340
|
function buildCompactHeader(event, width, opts = {}) {
|
|
8386
5341
|
const theme = opts.theme ?? darkTheme;
|
|
8387
|
-
const label =
|
|
5342
|
+
const label = eventLabel(event);
|
|
8388
5343
|
const time = formatClock(event.ts);
|
|
8389
5344
|
let title = source_default.bold.hex(theme.detail.title)(label);
|
|
8390
5345
|
if (opts.subject) {
|
|
@@ -8545,6 +5500,9 @@ function renderDetailLines(event, width, pairedPostEvent, theme = darkTheme) {
|
|
|
8545
5500
|
case "compact.post":
|
|
8546
5501
|
case "cwd.changed":
|
|
8547
5502
|
case "file.changed":
|
|
5503
|
+
case "instructions.loaded":
|
|
5504
|
+
case "worktree.create":
|
|
5505
|
+
case "worktree.remove":
|
|
8548
5506
|
case "stop.failure":
|
|
8549
5507
|
case "permission.denied":
|
|
8550
5508
|
case "elicitation.request":
|
|
@@ -11933,7 +8891,7 @@ function useRuntimeSelectors() {
|
|
|
11933
8891
|
const questionQueueCount = useHookContextSelector((v) => v.questionQueueCount);
|
|
11934
8892
|
const resolveQuestion = useHookContextSelector((v) => v.resolveQuestion);
|
|
11935
8893
|
const isServerRunning = useHookContextSelector((v) => v.isServerRunning);
|
|
11936
|
-
const
|
|
8894
|
+
const runtimeError = useHookContextSelector((v) => v.runtimeError);
|
|
11937
8895
|
const postByToolUseId = useHookContextSelector((v) => v.postByToolUseId);
|
|
11938
8896
|
const allocateSeq = useHookContextSelector((v) => v.allocateSeq);
|
|
11939
8897
|
const clearEvents = useHookContextSelector((v) => v.clearEvents);
|
|
@@ -11958,7 +8916,7 @@ function useRuntimeSelectors() {
|
|
|
11958
8916
|
questionQueueCount,
|
|
11959
8917
|
resolveQuestion,
|
|
11960
8918
|
isServerRunning,
|
|
11961
|
-
runtimeError
|
|
8919
|
+
runtimeError,
|
|
11962
8920
|
postByToolUseId,
|
|
11963
8921
|
allocateSeq,
|
|
11964
8922
|
clearEvents,
|
|
@@ -12942,7 +9900,7 @@ function AppContent({
|
|
|
12942
9900
|
isServerRunning,
|
|
12943
9901
|
recordTokens,
|
|
12944
9902
|
restoredTokens,
|
|
12945
|
-
runtimeError
|
|
9903
|
+
runtimeError,
|
|
12946
9904
|
hookCommandFeed
|
|
12947
9905
|
} = useRuntimeSelectors();
|
|
12948
9906
|
const currentSessionId = session?.session_id ?? null;
|
|
@@ -13087,7 +10045,7 @@ function AppContent({
|
|
|
13087
10045
|
if (!current) {
|
|
13088
10046
|
return current;
|
|
13089
10047
|
}
|
|
13090
|
-
const isActiveHookServerStartupFailure = current.failureStage === "startup_timeout" && !!
|
|
10048
|
+
const isActiveHookServerStartupFailure = current.failureStage === "startup_timeout" && !!runtimeError && !isServerRunning && current.message === runtimeError.message;
|
|
13091
10049
|
if (isActiveHookServerStartupFailure) {
|
|
13092
10050
|
return current;
|
|
13093
10051
|
}
|
|
@@ -13096,21 +10054,21 @@ function AppContent({
|
|
|
13096
10054
|
}
|
|
13097
10055
|
return null;
|
|
13098
10056
|
});
|
|
13099
|
-
}, [feedEvents.length, isServerRunning,
|
|
10057
|
+
}, [feedEvents.length, isServerRunning, runtimeError]);
|
|
13100
10058
|
useEffect14(() => {
|
|
13101
10059
|
if (!shouldTrackClaudeStartup || !isTelemetryEnabled()) return;
|
|
13102
|
-
if (!
|
|
10060
|
+
if (!runtimeError || isServerRunning) {
|
|
13103
10061
|
runtimeStartupDiagnosticsSignatureRef.current = null;
|
|
13104
10062
|
return;
|
|
13105
10063
|
}
|
|
13106
|
-
const signature = `${
|
|
10064
|
+
const signature = `${runtimeError.code}:${runtimeError.message}`;
|
|
13107
10065
|
if (signature === runtimeStartupDiagnosticsSignatureRef.current) {
|
|
13108
10066
|
return;
|
|
13109
10067
|
}
|
|
13110
10068
|
runtimeStartupDiagnosticsSignatureRef.current = signature;
|
|
13111
10069
|
const diagnosticsEvent = createPendingStartupDiagnosticsEvent({
|
|
13112
10070
|
failureStage: "startup_timeout",
|
|
13113
|
-
message:
|
|
10071
|
+
message: runtimeError.message,
|
|
13114
10072
|
feedEventCount: feedEvents.length
|
|
13115
10073
|
});
|
|
13116
10074
|
if (diagnosticsConsent === true) {
|
|
@@ -13123,7 +10081,7 @@ function AppContent({
|
|
|
13123
10081
|
emitClaudeStartupDiagnostics,
|
|
13124
10082
|
feedEvents.length,
|
|
13125
10083
|
isServerRunning,
|
|
13126
|
-
|
|
10084
|
+
runtimeError,
|
|
13127
10085
|
shouldTrackClaudeStartup
|
|
13128
10086
|
]);
|
|
13129
10087
|
useEffect14(() => {
|
|
@@ -13138,7 +10096,7 @@ function AppContent({
|
|
|
13138
10096
|
return;
|
|
13139
10097
|
}
|
|
13140
10098
|
const derivedFailure = deriveStartupTimeoutFailure({
|
|
13141
|
-
runtimeError
|
|
10099
|
+
runtimeError,
|
|
13142
10100
|
isServerRunning,
|
|
13143
10101
|
isHarnessRunning,
|
|
13144
10102
|
harnessLabel
|
|
@@ -13175,7 +10133,7 @@ function AppContent({
|
|
|
13175
10133
|
harnessLabel,
|
|
13176
10134
|
isHarnessRunning,
|
|
13177
10135
|
isServerRunning,
|
|
13178
|
-
|
|
10136
|
+
runtimeError,
|
|
13179
10137
|
shouldTrackClaudeStartup
|
|
13180
10138
|
]);
|
|
13181
10139
|
const addMessage = useCallback19(
|
|
@@ -13292,13 +10250,13 @@ function AppContent({
|
|
|
13292
10250
|
setPendingStartupDiagnostics(null);
|
|
13293
10251
|
setStartupFailure(null);
|
|
13294
10252
|
addMessage("user", result.text);
|
|
13295
|
-
if (!isServerRunning &&
|
|
10253
|
+
if (!isServerRunning && runtimeError) {
|
|
13296
10254
|
setStartupFailure({
|
|
13297
|
-
message:
|
|
13298
|
-
failureCode:
|
|
10255
|
+
message: runtimeError.message,
|
|
10256
|
+
failureCode: runtimeError.code === "socket_path_too_long" ? "socket_path_too_long" : "hook_server_unavailable"
|
|
13299
10257
|
});
|
|
13300
10258
|
emitNotification(
|
|
13301
|
-
`Athena failed to start ${harnessLabel}: ${
|
|
10259
|
+
`Athena failed to start ${harnessLabel}: ${runtimeError.message}`,
|
|
13302
10260
|
`${harnessLabel} Startup Error`
|
|
13303
10261
|
);
|
|
13304
10262
|
return;
|
|
@@ -13354,13 +10312,13 @@ function AppContent({
|
|
|
13354
10312
|
spawn: (prompt, sessionId2, configOverride) => {
|
|
13355
10313
|
setPendingStartupDiagnostics(null);
|
|
13356
10314
|
setStartupFailure(null);
|
|
13357
|
-
if (!isServerRunning &&
|
|
10315
|
+
if (!isServerRunning && runtimeError) {
|
|
13358
10316
|
setStartupFailure({
|
|
13359
|
-
message:
|
|
13360
|
-
failureCode:
|
|
10317
|
+
message: runtimeError.message,
|
|
10318
|
+
failureCode: runtimeError.code === "socket_path_too_long" ? "socket_path_too_long" : "hook_server_unavailable"
|
|
13361
10319
|
});
|
|
13362
10320
|
emitNotification(
|
|
13363
|
-
`Athena failed to start ${harnessLabel}: ${
|
|
10321
|
+
`Athena failed to start ${harnessLabel}: ${runtimeError.message}`,
|
|
13364
10322
|
`${harnessLabel} Startup Error`
|
|
13365
10323
|
);
|
|
13366
10324
|
return Promise.resolve();
|
|
@@ -13388,7 +10346,7 @@ function AppContent({
|
|
|
13388
10346
|
spawnHarness,
|
|
13389
10347
|
currentSessionId,
|
|
13390
10348
|
isServerRunning,
|
|
13391
|
-
|
|
10349
|
+
runtimeError,
|
|
13392
10350
|
exit,
|
|
13393
10351
|
clearScreen,
|
|
13394
10352
|
onShowSessions,
|
|
@@ -14868,7 +11826,7 @@ var tasksCommand = {
|
|
|
14868
11826
|
};
|
|
14869
11827
|
|
|
14870
11828
|
// src/app/commands/builtins/setup.ts
|
|
14871
|
-
var
|
|
11829
|
+
var setup = {
|
|
14872
11830
|
name: "setup",
|
|
14873
11831
|
description: "Re-run the setup wizard",
|
|
14874
11832
|
category: "ui",
|
|
@@ -14876,7 +11834,7 @@ var setup2 = {
|
|
|
14876
11834
|
ctx.showSetup();
|
|
14877
11835
|
}
|
|
14878
11836
|
};
|
|
14879
|
-
var setup_default =
|
|
11837
|
+
var setup_default = setup;
|
|
14880
11838
|
|
|
14881
11839
|
// src/app/commands/builtins/telemetry.ts
|
|
14882
11840
|
var telemetryCommand = {
|
|
@@ -15705,7 +12663,7 @@ var cachedVersion = null;
|
|
|
15705
12663
|
function readPackageVersion() {
|
|
15706
12664
|
if (cachedVersion !== null) return cachedVersion;
|
|
15707
12665
|
try {
|
|
15708
|
-
const injected = "0.5.
|
|
12666
|
+
const injected = "0.5.10";
|
|
15709
12667
|
if (typeof injected === "string" && injected.length > 0) {
|
|
15710
12668
|
cachedVersion = injected;
|
|
15711
12669
|
return cachedVersion;
|