@drisp/cli 0.5.8 → 0.5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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-XIWMD4GT.js";
100
+ } from "./chunk-2QMUBFZZ.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 [runtimeError2, setRuntimeError] = useState4(
1685
+ const [runtimeError, setRuntimeError] = useState4(
1735
1686
  () => runtime.getLastError()
1736
1687
  );
1737
1688
  const restoredTokens = useMemo3(
@@ -1747,6 +1698,13 @@ function useFeed(runtime, messages = [], initialAllowedTools, sessionStore, opti
1747
1698
  () => options?.dashboardFeedPublisher ?? createPairedFeedPublisher(),
1748
1699
  [options?.dashboardFeedPublisher]
1749
1700
  );
1701
+ const ownsFeedPublisher = !options?.dashboardFeedPublisher;
1702
+ useEffect(() => {
1703
+ if (!ownsFeedPublisher) return;
1704
+ return () => {
1705
+ dashboardFeedPublisher.close();
1706
+ };
1707
+ }, [ownsFeedPublisher, dashboardFeedPublisher]);
1750
1708
  const dashboardDecisionInboxRef = useRef(
1751
1709
  options?.dashboardDecisionInbox ?? null
1752
1710
  );
@@ -2118,7 +2076,7 @@ function useFeed(runtime, messages = [], initialAllowedTools, sessionStore, opti
2118
2076
  currentRun: mapperRef.current.getCurrentRun(),
2119
2077
  actors: mapperRef.current.getActors(),
2120
2078
  isServerRunning,
2121
- runtimeError: runtimeError2,
2079
+ runtimeError,
2122
2080
  currentPermissionRequest,
2123
2081
  permissionQueueCount: permissionQueue.length,
2124
2082
  resolvePermission,
@@ -2962,896 +2920,108 @@ var chalk = createChalk();
2962
2920
  var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
2963
2921
  var source_default = chalk;
2964
2922
 
2965
- // node_modules/ansi-regex/index.js
2966
- function ansiRegex({ onlyFirst = false } = {}) {
2967
- const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
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
- }
2923
+ // src/ui/hooks/useTextInput.ts
2924
+ import { useReducer, useCallback as useCallback6, useEffect as useEffect5, useRef as useRef4 } from "react";
2925
+ import { useInput as useInput6, useStdin } from "ink";
2982
2926
 
2983
- // node_modules/get-east-asian-width/lookup.js
2984
- function isAmbiguous(x) {
2985
- return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109;
2986
- }
2987
- function isFullWidth(x) {
2988
- return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
2989
- }
2990
- function isWide(x) {
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;
2927
+ // src/ui/hooks/usePanelMouseWheel.ts
2928
+ import process4 from "process";
2929
+ import { useEffect as useEffect4 } from "react";
2930
+ var ENABLE_MOUSE_TRACKING = "\x1B[?1000h\x1B[?1006h";
2931
+ var DISABLE_MOUSE_TRACKING = "\x1B[?1006l\x1B[?1000l";
2932
+ var PANEL_MOUSE_SCROLL_LINES = 3;
2933
+ function contains(rect, col, row) {
2934
+ return col >= rect.left && col <= rect.right && row >= rect.top && row <= rect.bottom;
2992
2935
  }
2993
-
2994
- // node_modules/get-east-asian-width/index.js
2995
- function validate(codePoint) {
2996
- if (!Number.isSafeInteger(codePoint)) {
2997
- throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
2936
+ function parseSgrWheelEvents(data) {
2937
+ const sgrMouseRe = /\x1B\[<(64|65);(\d+);(\d+)[Mm]/g;
2938
+ const events = [];
2939
+ let match;
2940
+ while ((match = sgrMouseRe.exec(data)) !== null) {
2941
+ events.push({
2942
+ direction: match[1] === "64" ? "up" : "down",
2943
+ col: Number.parseInt(match[2], 10),
2944
+ row: Number.parseInt(match[3], 10)
2945
+ });
2998
2946
  }
2947
+ return events;
2999
2948
  }
3000
- function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
3001
- validate(codePoint);
3002
- if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
3003
- return 2;
3004
- }
3005
- return 1;
2949
+ function looksLikeMouseEscapeSequence(input) {
2950
+ if (input.length === 0) return false;
2951
+ if (parseSgrWheelEvents(input).length > 0) return true;
2952
+ return /^\[<\d+;\d+;\d+[Mm]$/.test(input) || /^\d+;\d+;\d+[Mm]$/.test(input);
3006
2953
  }
3007
-
3008
- // node_modules/string-width/index.js
3009
- var segmenter = new Intl.Segmenter();
3010
- var zeroWidthClusterRegex = new RegExp("^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Format}|\\p{Mark}|\\p{Surrogate})+$", "v");
3011
- var leadingNonPrintingRegex = new RegExp("^[\\p{Default_Ignorable_Code_Point}\\p{Control}\\p{Format}\\p{Mark}\\p{Surrogate}]+", "v");
3012
- var rgiEmojiRegex = new RegExp("^\\p{RGI_Emoji}$", "v");
3013
- function baseVisible(segment) {
3014
- return segment.replace(leadingNonPrintingRegex, "");
3015
- }
3016
- function isZeroWidthCluster(segment) {
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
- }
2954
+ function parseSgrClickEvents(data) {
2955
+ const sgrMouseRe = /\x1B\[<0;(\d+);(\d+)M/g;
2956
+ const events = [];
2957
+ let match;
2958
+ while ((match = sgrMouseRe.exec(data)) !== null) {
2959
+ events.push({
2960
+ button: "left",
2961
+ col: Number.parseInt(match[1], 10),
2962
+ row: Number.parseInt(match[2], 10)
2963
+ });
3027
2964
  }
3028
- return extra;
2965
+ return events;
3029
2966
  }
3030
- function stringWidth(input, options = {}) {
3031
- if (typeof input !== "string" || input.length === 0) {
3032
- return 0;
2967
+ function resolvePanelTarget(rects, col, row) {
2968
+ if (rects.input && contains(rects.input, col, row)) {
2969
+ return "input";
3033
2970
  }
3034
- const {
3035
- ambiguousIsNarrow = true,
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;
2971
+ if (rects.messages && contains(rects.messages, col, row)) {
2972
+ return "messages";
3044
2973
  }
3045
- let width = 0;
3046
- const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
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);
2974
+ if (contains(rects.feed, col, row)) {
2975
+ return "feed";
3058
2976
  }
3059
- return width;
2977
+ return null;
3060
2978
  }
3061
-
3062
- // node_modules/ansi-styles/index.js
3063
- var ANSI_BACKGROUND_OFFSET2 = 10;
3064
- var wrapAnsi162 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
3065
- var wrapAnsi2562 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
3066
- var wrapAnsi16m2 = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
3067
- var styles3 = {
3068
- modifier: {
3069
- reset: [0, 0],
3070
- // 21 isn't widely supported and 22 does the same thing
3071
- bold: [1, 22],
3072
- dim: [2, 22],
3073
- italic: [3, 23],
3074
- underline: [4, 24],
3075
- overline: [53, 55],
3076
- inverse: [7, 27],
3077
- hidden: [8, 28],
3078
- strikethrough: [9, 29]
3079
- },
3080
- color: {
3081
- black: [30, 39],
3082
- red: [31, 39],
3083
- green: [32, 39],
3084
- yellow: [33, 39],
3085
- blue: [34, 39],
3086
- magenta: [35, 39],
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
- ];
2979
+ function buildPanelRects({
2980
+ splitMode,
2981
+ frameWidth,
2982
+ feedStartRow,
2983
+ panelRows,
2984
+ messagePanelWidth,
2985
+ feedPanelWidth,
2986
+ inputStartRow,
2987
+ inputRows
2988
+ }) {
2989
+ const top = feedStartRow;
2990
+ const bottom = feedStartRow + Math.max(0, panelRows - 1);
2991
+ const innerLeft = 2;
2992
+ const inputRect = inputStartRow !== void 0 && inputRows !== void 0 && inputRows > 0 ? {
2993
+ left: innerLeft,
2994
+ right: Math.max(innerLeft, frameWidth - 1),
2995
+ top: inputStartRow,
2996
+ bottom: inputStartRow + inputRows - 1
2997
+ } : void 0;
2998
+ if (!splitMode) {
2999
+ return {
3000
+ feed: {
3001
+ left: innerLeft,
3002
+ right: Math.max(innerLeft, frameWidth - 1),
3003
+ top,
3004
+ bottom
3193
3005
  },
3194
- enumerable: false
3006
+ input: inputRect
3007
+ };
3008
+ }
3009
+ const messageLeft = innerLeft;
3010
+ const messageRight = messageLeft + messagePanelWidth;
3011
+ const feedLeft = messageRight + 1;
3012
+ const feedRight = feedLeft + Math.max(0, feedPanelWidth - 1);
3013
+ return {
3014
+ messages: {
3015
+ left: messageLeft,
3016
+ right: messageRight,
3017
+ top,
3018
+ bottom
3195
3019
  },
3196
- hexToAnsi256: {
3197
- value: (hex) => styles3.rgbToAnsi256(...styles3.hexToRgb(hex)),
3198
- enumerable: false
3199
- },
3200
- ansi256ToAnsi: {
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
3020
+ feed: {
3021
+ left: feedLeft,
3022
+ right: feedRight,
3023
+ top,
3024
+ bottom
3855
3025
  },
3856
3026
  input: inputRect
3857
3027
  };
@@ -4639,7 +3809,7 @@ function useTodoPanel({
4639
3809
  const todoItemsCacheRef = useRef7(null);
4640
3810
  const nextTodoItems = (() => {
4641
3811
  const fromTasks = tasks.map((task, index) => ({
4642
- id: `task-${index}-${task.content.replace(/[^a-zA-Z0-9]/g, "").slice(0, 16)}`,
3812
+ id: (task.taskId ? `task-${task.taskId}` : void 0) ?? `task-${index}-${task.content.replace(/[^a-zA-Z0-9]/g, "").slice(0, 16)}`,
4643
3813
  text: task.content,
4644
3814
  priority: "P1",
4645
3815
  status: toTodoStatus(task.status),
@@ -4944,2360 +4114,152 @@ function useMessageKeyboard({
4944
4114
  if (key.upArrow) {
4945
4115
  callbacks.moveCursor(-1);
4946
4116
  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
4117
+ }
4118
+ if (key.downArrow) {
4119
+ callbacks.moveCursor(1);
4120
+ return;
4121
+ }
4122
+ } finally {
4123
+ done();
4124
+ }
4125
+ },
4126
+ { isActive }
6860
4127
  );
6861
4128
  }
6862
- function buildMessageEntry(item, activeRunId, messageCounter) {
6863
- const summary = compactText(item.content, 200);
6864
- const details = item.content;
6865
- return {
6866
- id: `M${String(messageCounter).padStart(3, "0")}`,
6867
- ts: item.timestamp.getTime(),
6868
- runId: activeRunId,
6869
- op: item.role === "user" ? "User Msg" : "Agent Msg",
6870
- opTag: item.role === "user" ? "msg.user" : "msg.agent",
6871
- actor: item.role === "user" ? "USER" : "AGENT",
6872
- actorId: item.role === "user" ? "user" : "agent:root",
6873
- toolColumn: "",
6874
- summary,
6875
- summarySegments: [{ text: summary, role: "plain" }],
6876
- searchText: `${summary}
6877
- ${details}`,
6878
- error: false,
6879
- expandable: details.length > 120,
6880
- details,
6881
- duplicateActor: false
6882
- };
6883
- }
6884
- function shouldSkipEvent(event, verbose) {
6885
- if (!verbose && VERBOSE_ONLY_KINDS.has(event.kind)) {
6886
- return true;
6887
- }
6888
- if (!verbose && event.kind === "stop.request" && !event.data.stop_hook_active) {
6889
- return true;
6890
- }
6891
- return false;
6892
- }
6893
- function mergedToolUseId(event, postByToolUseId) {
6894
- if (event.kind !== "tool.post" && event.kind !== "tool.failure" || isSubagentTool(event.data.tool_name) || !postByToolUseId) {
6895
- return void 0;
6896
- }
6897
- const toolUseId = event.data.tool_use_id;
6898
- if (!toolUseId) return void 0;
6899
- return postByToolUseId.get(toolUseId) === event ? toolUseId : void 0;
6900
- }
6901
- function pairedPostForEvent(event, postByToolUseId) {
6902
- if (event.kind !== "tool.pre" && event.kind !== "permission.request" || isSubagentTool(event.data.tool_name) || !event.data.tool_use_id) {
6903
- return void 0;
6904
- }
6905
- return postByToolUseId?.get(event.data.tool_use_id);
6906
- }
6907
- function pendingToolUpdateUseId(event) {
6908
- if (event.kind !== "tool.delta" && event.kind !== "tool.post" && event.kind !== "tool.failure") {
6909
- return void 0;
6910
- }
6911
- if (isSubagentTool(event.data.tool_name)) {
6912
- return void 0;
6913
- }
6914
- return event.data.tool_use_id;
6915
- }
6916
- function buildEventEntry(event, subagentTypes, pairedPost) {
6917
- const opTag = pairedPost ? mergedEventOperation(event, pairedPost) : eventOperation(event);
6918
- const op = pairedPost ? mergedEventLabel(event, pairedPost) : eventLabel(event);
6919
- const summaryResult = pairedPost ? mergedEventSummary(event, pairedPost) : eventSummary(event);
6920
- const { text: summary, segments: summarySegments } = summaryResult;
6921
- const toolColumn = event.kind === "tool.pre" || event.kind === "tool.post" || event.kind === "tool.failure" ? resolveToolColumn(event.data.tool_name) : resolveEventToolColumn(event);
6922
- return {
6923
- id: event.event_id,
6924
- ts: event.ts,
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)
4129
+
4130
+ // src/ui/hooks/useTodoKeyboard.ts
4131
+ import { useRef as useRef8 } from "react";
4132
+ import { useInput as useInput10 } from "ink";
4133
+ function useTodoKeyboard({
4134
+ isActive,
4135
+ todoCursor,
4136
+ visibleTodoItems,
4137
+ filteredEntries,
4138
+ callbacks
4139
+ }) {
4140
+ const visibleTodoItemsRef = useRef8(visibleTodoItems);
4141
+ visibleTodoItemsRef.current = visibleTodoItems;
4142
+ const filteredEntriesRef = useRef8(filteredEntries);
4143
+ filteredEntriesRef.current = filteredEntries;
4144
+ useInput10(
4145
+ (input, key) => {
4146
+ const done = startInputMeasure("todo.keyboard", input, key);
4147
+ try {
4148
+ if (key.escape) {
4149
+ callbacks.focusFeed();
4150
+ return;
4151
+ }
4152
+ if (key.tab) {
4153
+ callbacks.cycleFocus();
4154
+ return;
4155
+ }
4156
+ if (key.upArrow) {
4157
+ callbacks.moveTodoCursor(-1);
4158
+ return;
4159
+ }
4160
+ if (key.downArrow) {
4161
+ callbacks.moveTodoCursor(1);
4162
+ return;
4163
+ }
4164
+ if (input === " ") {
4165
+ callbacks.toggleTodoStatus(todoCursor);
4166
+ return;
4167
+ }
4168
+ if (key.return) {
4169
+ if (todoCursor < 0 || todoCursor >= visibleTodoItemsRef.current.length) {
4170
+ return;
4171
+ }
4172
+ const selected = visibleTodoItemsRef.current[todoCursor];
4173
+ if (!selected.linkedEventId) return;
4174
+ const idx = filteredEntriesRef.current.findIndex(
4175
+ (entry) => entry.id === selected.linkedEventId
4176
+ );
4177
+ if (idx >= 0) {
4178
+ callbacks.revealFeedCursor(idx);
4179
+ }
4180
+ return;
4181
+ }
4182
+ if (input.toLowerCase() === "a") {
4183
+ callbacks.openNormalInput();
4184
+ callbacks.setInputValue("");
4185
+ return;
4186
+ }
4187
+ } finally {
4188
+ done();
4189
+ }
4190
+ },
4191
+ { isActive }
6954
4192
  );
6955
4193
  }
6956
- function rememberPendingEntry(pendingEntryIndexByToolUseId, entry, index) {
6957
- const event = entry.feedEvent;
6958
- if (!event) return;
6959
- if (event.kind !== "tool.pre" && event.kind !== "permission.request" || isSubagentTool(event.data.tool_name) || !event.data.tool_use_id || entry.pairedPostEvent) {
6960
- return;
6961
- }
6962
- pendingEntryIndexByToolUseId.set(event.data.tool_use_id, index);
6963
- }
6964
- function recomputeDuplicateActorAt(entries, index) {
6965
- const entry = entries[index];
6966
- if (index === 0) {
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;
4194
+
4195
+ // src/ui/hooks/useSpinner.ts
4196
+ import { useState as useState8, useEffect as useEffect7 } from "react";
4197
+ var BRAILLE_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
4198
+ var DEFAULT_SPINNER_INTERVAL_MS = 1e3;
4199
+ function useSpinner(active, intervalMs = DEFAULT_SPINNER_INTERVAL_MS) {
4200
+ const [frameIndex, setFrameIndex] = useState8(0);
4201
+ useEffect7(() => {
4202
+ if (!active) {
4203
+ setFrameIndex(0);
4204
+ return;
6997
4205
  }
6998
- }
6999
- return true;
4206
+ const timer = setInterval(() => {
4207
+ startPerfCycle("timer:spinner", { scope: "spinner" });
4208
+ setFrameIndex((i) => (i + 1) % BRAILLE_FRAMES.length);
4209
+ }, intervalMs);
4210
+ return () => clearInterval(timer);
4211
+ }, [active, intervalMs]);
4212
+ if (!active) return "";
4213
+ return BRAILLE_FRAMES[frameIndex] ?? "\u280B";
7000
4214
  }
7001
- function canAppendIncrementally(previous, feedItems, feedEvents, verbose) {
7002
- if (!previous) return false;
7003
- if (previous.verbose !== verbose) return false;
7004
- return sameFeedItemPrefix(previous.feedItems, feedItems) && sameFeedEventPrefix(previous.feedEvents, feedEvents);
4215
+
4216
+ // src/ui/hooks/useTodoDisplayItems.ts
4217
+ import { useEffect as useEffect8, useMemo as useMemo8, useState as useState9 } from "react";
4218
+ function hasTickingElapsedItems(items) {
4219
+ return items.some(
4220
+ (item) => item.status === "doing" && item.startedAtMs !== void 0
4221
+ );
7005
4222
  }
7006
- function buildTimelineCache(feedItems, feedEvents, postByToolUseId, verbose) {
7007
- const entries = [];
7008
- let activeRunId;
7009
- let messageCounter = 1;
7010
- const subagentTypes = buildSubagentTypeMap(feedEvents);
7011
- const pendingEntryIndexByToolUseId = /* @__PURE__ */ new Map();
7012
- for (const item of feedItems) {
7013
- if (item.type === "message") {
7014
- entries.push(buildMessageEntry(item.data, activeRunId, messageCounter++));
7015
- continue;
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
- };
4223
+ function buildTodoDisplayItems(items, nowMs, isWorking, pausedAtMs) {
4224
+ let changed = false;
4225
+ const nextItems = items.map((item) => {
4226
+ const hasElapsed = item.startedAtMs !== void 0 && (item.status === "doing" || item.status === "done" || item.status === "failed");
4227
+ const endMs = item.completedAtMs ?? (isWorking ? nowMs : pausedAtMs ?? nowMs);
4228
+ const elapsed = hasElapsed ? formatElapsed(Math.max(0, endMs - item.startedAtMs)) : void 0;
4229
+ if (elapsed === item.elapsed) return item;
4230
+ changed = true;
4231
+ return { ...item, elapsed };
4232
+ });
4233
+ return changed ? nextItems : items;
7046
4234
  }
7047
- function appendTimelineCache(previous, feedItems, feedEvents, postByToolUseId) {
7048
- const entries = previous.entries.slice();
7049
- const subagentTypes = new Map(previous.subagentTypes);
7050
- updateSubagentTypeMap(
7051
- subagentTypes,
7052
- feedEvents.slice(previous.feedEvents.length)
7053
- );
7054
- const pendingEntryIndexByToolUseId = new Map(
7055
- previous.pendingEntryIndexByToolUseId
4235
+ function useTodoDisplayItems({
4236
+ items,
4237
+ isWorking,
4238
+ pausedAtMs,
4239
+ active,
4240
+ tickMs = 1e3
4241
+ }) {
4242
+ const [nowMs, setNowMs] = useState9(() => Date.now());
4243
+ const hasDoingItems = useMemo8(() => hasTickingElapsedItems(items), [items]);
4244
+ useEffect8(() => {
4245
+ if (!active || !isWorking || !hasDoingItems) return;
4246
+ const id = setInterval(() => {
4247
+ startPerfCycle("timer:todo-header", {
4248
+ scope: "todo.elapsed",
4249
+ items: items.length
4250
+ });
4251
+ setNowMs(Date.now());
4252
+ }, tickMs);
4253
+ return () => clearInterval(id);
4254
+ }, [active, isWorking, hasDoingItems, items.length, tickMs]);
4255
+ return useMemo8(
4256
+ () => buildTodoDisplayItems(items, nowMs, isWorking, pausedAtMs),
4257
+ [items, nowMs, isWorking, pausedAtMs]
7056
4258
  );
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
4259
  }
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
4260
 
7300
4261
  // src/ui/hooks/useTimeline.ts
4262
+ import { useMemo as useMemo9, useRef as useRef9, useCallback as useCallback10 } from "react";
7301
4263
  var EMPTY_MATCHES = Object.freeze([]);
7302
4264
  var EMPTY_MATCH_SET = Object.freeze(/* @__PURE__ */ new Set());
7303
4265
  function useTimeline({
@@ -7536,7 +4498,7 @@ function detectLanguage(filePath) {
7536
4498
  function isMarkdownRenderable(language) {
7537
4499
  return language === void 0 || language === "markdown";
7538
4500
  }
7539
- function prop3(obj, key) {
4501
+ function prop(obj, key) {
7540
4502
  if (typeof obj === "object" && obj !== null) {
7541
4503
  return obj[key];
7542
4504
  }
@@ -7551,21 +4513,21 @@ function extractTextContent(response) {
7551
4513
  if (typeof block === "string") {
7552
4514
  parts.push(block);
7553
4515
  } else if (typeof block === "object" && block !== null) {
7554
- const text = prop3(block, "text");
4516
+ const text = prop(block, "text");
7555
4517
  if (typeof text === "string") parts.push(text);
7556
4518
  }
7557
4519
  }
7558
4520
  if (parts.length > 0) return parts.join("\n").trim();
7559
4521
  }
7560
4522
  if (typeof response === "object") {
7561
- const text = prop3(response, "text");
7562
- if (typeof text === "string" && prop3(response, "type") === "text") {
4523
+ const text = prop(response, "text");
4524
+ if (typeof text === "string" && prop(response, "type") === "text") {
7563
4525
  return text.trim();
7564
4526
  }
7565
- const content = prop3(response, "content");
4527
+ const content = prop(response, "content");
7566
4528
  if (content != null) return extractTextContent(content);
7567
4529
  for (const key of ["result", "message", "output"]) {
7568
- const val = prop3(response, key);
4530
+ const val = prop(response, key);
7569
4531
  if (typeof val === "string") return val;
7570
4532
  }
7571
4533
  }
@@ -7610,10 +4572,10 @@ ${err}` : err : out;
7610
4572
  }
7611
4573
  return { type: "code", content: extractTextContent(response), maxLines: 10 };
7612
4574
  }
7613
- function extractFileContent2(block) {
7614
- const fileContent = prop3(prop3(block, "file"), "content");
4575
+ function extractFileContent(block) {
4576
+ const fileContent = prop(prop(block, "file"), "content");
7615
4577
  if (typeof fileContent === "string") return fileContent;
7616
- const text = prop3(block, "text");
4578
+ const text = prop(block, "text");
7617
4579
  if (typeof text === "string") return text;
7618
4580
  return void 0;
7619
4581
  }
@@ -7621,7 +4583,7 @@ function extractRead(input, response) {
7621
4583
  const blocks = Array.isArray(response) ? response : [response];
7622
4584
  let content;
7623
4585
  for (const block of blocks) {
7624
- content = extractFileContent2(block);
4586
+ content = extractFileContent(block);
7625
4587
  if (content) break;
7626
4588
  }
7627
4589
  const language = detectLanguage(input["file_path"]);
@@ -7639,9 +4601,9 @@ function parseDiffLine(raw) {
7639
4601
  return { type: "context", content };
7640
4602
  }
7641
4603
  function parseStructuredPatch(response) {
7642
- const patch = prop3(response, "structuredPatch");
4604
+ const patch = prop(response, "structuredPatch");
7643
4605
  if (!patch) return void 0;
7644
- const rawHunks = prop3(patch, "hunks");
4606
+ const rawHunks = prop(patch, "hunks");
7645
4607
  if (!Array.isArray(rawHunks)) return void 0;
7646
4608
  return rawHunks.map((h) => {
7647
4609
  const oldStart = typeof h.oldStart === "number" ? h.oldStart : 1;
@@ -7678,7 +4640,7 @@ function extractWrite(input, response) {
7678
4640
  }
7679
4641
  const content = typeof input["content"] === "string" ? input["content"] : "";
7680
4642
  const filePath = String(
7681
- prop3(response, "filePath") ?? input["file_path"] ?? ""
4643
+ prop(response, "filePath") ?? input["file_path"] ?? ""
7682
4644
  );
7683
4645
  if (!content) {
7684
4646
  return { type: "text", content: `Wrote ${filePath}` };
@@ -7705,7 +4667,7 @@ function extractGrep(_input, response) {
7705
4667
  return { type: "list", items, maxItems: 10, groupBy: "secondary" };
7706
4668
  }
7707
4669
  function extractGlob(_input, response) {
7708
- const filenames = prop3(response, "filenames");
4670
+ const filenames = prop(response, "filenames");
7709
4671
  if (Array.isArray(filenames)) {
7710
4672
  const items2 = filenames.filter((f) => typeof f === "string").map((f) => ({ primary: f }));
7711
4673
  return { type: "list", items: items2, maxItems: 10, displayMode: "tree" };
@@ -7715,22 +4677,22 @@ function extractGlob(_input, response) {
7715
4677
  return { type: "list", items, maxItems: 10 };
7716
4678
  }
7717
4679
  function extractWebFetch(_input, response) {
7718
- const result = prop3(response, "result");
4680
+ const result = prop(response, "result");
7719
4681
  const content = typeof result === "string" ? result : extractTextContent(response);
7720
4682
  return { type: "text", content, maxLines: 10 };
7721
4683
  }
7722
4684
  function formatSearchLink(item) {
7723
- const title = prop3(item, "title");
4685
+ const title = prop(item, "title");
7724
4686
  if (typeof title !== "string") return null;
7725
- const url = prop3(item, "url");
4687
+ const url = prop(item, "url");
7726
4688
  return typeof url === "string" ? `- [${title}](${url})` : `- ${title}`;
7727
4689
  }
7728
4690
  function extractWebSearch(_input, response) {
7729
- const results = prop3(response, "results");
4691
+ const results = prop(response, "results");
7730
4692
  if (Array.isArray(results)) {
7731
4693
  const links = [];
7732
4694
  for (const entry of results) {
7733
- const content = prop3(entry, "content");
4695
+ const content = prop(entry, "content");
7734
4696
  const items = Array.isArray(content) ? content : [entry];
7735
4697
  for (const item of items) {
7736
4698
  const link = formatSearchLink(item);
@@ -7768,10 +4730,10 @@ function extractSkill(input, response) {
7768
4730
  }
7769
4731
  if (typeof response === "object" && response !== null) {
7770
4732
  const items = [];
7771
- const success = prop3(response, "success");
7772
- const commandName = prop3(response, "commandName");
7773
- const message = prop3(response, "message");
7774
- const allowedTools = prop3(response, "allowedTools");
4733
+ const success = prop(response, "success");
4734
+ const commandName = prop(response, "commandName");
4735
+ const message = prop(response, "message");
4736
+ const allowedTools = prop(response, "allowedTools");
7775
4737
  if (skill) items.push({ secondary: "skill", primary: skill });
7776
4738
  if (typeof commandName === "string" && commandName.trim()) {
7777
4739
  items.push({ secondary: "command", primary: commandName.trim() });
@@ -8298,7 +5260,7 @@ function extractToolSubject(toolName, toolInput) {
8298
5260
  return void 0;
8299
5261
  }
8300
5262
  }
8301
- function eventLabel2(event) {
5263
+ function eventLabel(event) {
8302
5264
  if (isDefaultRenderKind(event.kind)) return "Event";
8303
5265
  switch (event.kind) {
8304
5266
  case "tool.delta":
@@ -8384,7 +5346,7 @@ function eventLabel2(event) {
8384
5346
  }
8385
5347
  function buildCompactHeader(event, width, opts = {}) {
8386
5348
  const theme = opts.theme ?? darkTheme;
8387
- const label = eventLabel2(event);
5349
+ const label = eventLabel(event);
8388
5350
  const time = formatClock(event.ts);
8389
5351
  let title = source_default.bold.hex(theme.detail.title)(label);
8390
5352
  if (opts.subject) {
@@ -8545,6 +5507,9 @@ function renderDetailLines(event, width, pairedPostEvent, theme = darkTheme) {
8545
5507
  case "compact.post":
8546
5508
  case "cwd.changed":
8547
5509
  case "file.changed":
5510
+ case "instructions.loaded":
5511
+ case "worktree.create":
5512
+ case "worktree.remove":
8548
5513
  case "stop.failure":
8549
5514
  case "permission.denied":
8550
5515
  case "elicitation.request":
@@ -11933,7 +8898,7 @@ function useRuntimeSelectors() {
11933
8898
  const questionQueueCount = useHookContextSelector((v) => v.questionQueueCount);
11934
8899
  const resolveQuestion = useHookContextSelector((v) => v.resolveQuestion);
11935
8900
  const isServerRunning = useHookContextSelector((v) => v.isServerRunning);
11936
- const runtimeError2 = useHookContextSelector((v) => v.runtimeError);
8901
+ const runtimeError = useHookContextSelector((v) => v.runtimeError);
11937
8902
  const postByToolUseId = useHookContextSelector((v) => v.postByToolUseId);
11938
8903
  const allocateSeq = useHookContextSelector((v) => v.allocateSeq);
11939
8904
  const clearEvents = useHookContextSelector((v) => v.clearEvents);
@@ -11958,7 +8923,7 @@ function useRuntimeSelectors() {
11958
8923
  questionQueueCount,
11959
8924
  resolveQuestion,
11960
8925
  isServerRunning,
11961
- runtimeError: runtimeError2,
8926
+ runtimeError,
11962
8927
  postByToolUseId,
11963
8928
  allocateSeq,
11964
8929
  clearEvents,
@@ -12942,7 +9907,7 @@ function AppContent({
12942
9907
  isServerRunning,
12943
9908
  recordTokens,
12944
9909
  restoredTokens,
12945
- runtimeError: runtimeError2,
9910
+ runtimeError,
12946
9911
  hookCommandFeed
12947
9912
  } = useRuntimeSelectors();
12948
9913
  const currentSessionId = session?.session_id ?? null;
@@ -13087,7 +10052,7 @@ function AppContent({
13087
10052
  if (!current) {
13088
10053
  return current;
13089
10054
  }
13090
- const isActiveHookServerStartupFailure = current.failureStage === "startup_timeout" && !!runtimeError2 && !isServerRunning && current.message === runtimeError2.message;
10055
+ const isActiveHookServerStartupFailure = current.failureStage === "startup_timeout" && !!runtimeError && !isServerRunning && current.message === runtimeError.message;
13091
10056
  if (isActiveHookServerStartupFailure) {
13092
10057
  return current;
13093
10058
  }
@@ -13096,21 +10061,21 @@ function AppContent({
13096
10061
  }
13097
10062
  return null;
13098
10063
  });
13099
- }, [feedEvents.length, isServerRunning, runtimeError2]);
10064
+ }, [feedEvents.length, isServerRunning, runtimeError]);
13100
10065
  useEffect14(() => {
13101
10066
  if (!shouldTrackClaudeStartup || !isTelemetryEnabled()) return;
13102
- if (!runtimeError2 || isServerRunning) {
10067
+ if (!runtimeError || isServerRunning) {
13103
10068
  runtimeStartupDiagnosticsSignatureRef.current = null;
13104
10069
  return;
13105
10070
  }
13106
- const signature = `${runtimeError2.code}:${runtimeError2.message}`;
10071
+ const signature = `${runtimeError.code}:${runtimeError.message}`;
13107
10072
  if (signature === runtimeStartupDiagnosticsSignatureRef.current) {
13108
10073
  return;
13109
10074
  }
13110
10075
  runtimeStartupDiagnosticsSignatureRef.current = signature;
13111
10076
  const diagnosticsEvent = createPendingStartupDiagnosticsEvent({
13112
10077
  failureStage: "startup_timeout",
13113
- message: runtimeError2.message,
10078
+ message: runtimeError.message,
13114
10079
  feedEventCount: feedEvents.length
13115
10080
  });
13116
10081
  if (diagnosticsConsent === true) {
@@ -13123,7 +10088,7 @@ function AppContent({
13123
10088
  emitClaudeStartupDiagnostics,
13124
10089
  feedEvents.length,
13125
10090
  isServerRunning,
13126
- runtimeError2,
10091
+ runtimeError,
13127
10092
  shouldTrackClaudeStartup
13128
10093
  ]);
13129
10094
  useEffect14(() => {
@@ -13138,7 +10103,7 @@ function AppContent({
13138
10103
  return;
13139
10104
  }
13140
10105
  const derivedFailure = deriveStartupTimeoutFailure({
13141
- runtimeError: runtimeError2,
10106
+ runtimeError,
13142
10107
  isServerRunning,
13143
10108
  isHarnessRunning,
13144
10109
  harnessLabel
@@ -13175,7 +10140,7 @@ function AppContent({
13175
10140
  harnessLabel,
13176
10141
  isHarnessRunning,
13177
10142
  isServerRunning,
13178
- runtimeError2,
10143
+ runtimeError,
13179
10144
  shouldTrackClaudeStartup
13180
10145
  ]);
13181
10146
  const addMessage = useCallback19(
@@ -13292,13 +10257,13 @@ function AppContent({
13292
10257
  setPendingStartupDiagnostics(null);
13293
10258
  setStartupFailure(null);
13294
10259
  addMessage("user", result.text);
13295
- if (!isServerRunning && runtimeError2) {
10260
+ if (!isServerRunning && runtimeError) {
13296
10261
  setStartupFailure({
13297
- message: runtimeError2.message,
13298
- failureCode: runtimeError2.code === "socket_path_too_long" ? "socket_path_too_long" : "hook_server_unavailable"
10262
+ message: runtimeError.message,
10263
+ failureCode: runtimeError.code === "socket_path_too_long" ? "socket_path_too_long" : "hook_server_unavailable"
13299
10264
  });
13300
10265
  emitNotification(
13301
- `Athena failed to start ${harnessLabel}: ${runtimeError2.message}`,
10266
+ `Athena failed to start ${harnessLabel}: ${runtimeError.message}`,
13302
10267
  `${harnessLabel} Startup Error`
13303
10268
  );
13304
10269
  return;
@@ -13354,13 +10319,13 @@ function AppContent({
13354
10319
  spawn: (prompt, sessionId2, configOverride) => {
13355
10320
  setPendingStartupDiagnostics(null);
13356
10321
  setStartupFailure(null);
13357
- if (!isServerRunning && runtimeError2) {
10322
+ if (!isServerRunning && runtimeError) {
13358
10323
  setStartupFailure({
13359
- message: runtimeError2.message,
13360
- failureCode: runtimeError2.code === "socket_path_too_long" ? "socket_path_too_long" : "hook_server_unavailable"
10324
+ message: runtimeError.message,
10325
+ failureCode: runtimeError.code === "socket_path_too_long" ? "socket_path_too_long" : "hook_server_unavailable"
13361
10326
  });
13362
10327
  emitNotification(
13363
- `Athena failed to start ${harnessLabel}: ${runtimeError2.message}`,
10328
+ `Athena failed to start ${harnessLabel}: ${runtimeError.message}`,
13364
10329
  `${harnessLabel} Startup Error`
13365
10330
  );
13366
10331
  return Promise.resolve();
@@ -13388,7 +10353,7 @@ function AppContent({
13388
10353
  spawnHarness,
13389
10354
  currentSessionId,
13390
10355
  isServerRunning,
13391
- runtimeError2,
10356
+ runtimeError,
13392
10357
  exit,
13393
10358
  clearScreen,
13394
10359
  onShowSessions,
@@ -14868,7 +11833,7 @@ var tasksCommand = {
14868
11833
  };
14869
11834
 
14870
11835
  // src/app/commands/builtins/setup.ts
14871
- var setup2 = {
11836
+ var setup = {
14872
11837
  name: "setup",
14873
11838
  description: "Re-run the setup wizard",
14874
11839
  category: "ui",
@@ -14876,7 +11841,7 @@ var setup2 = {
14876
11841
  ctx.showSetup();
14877
11842
  }
14878
11843
  };
14879
- var setup_default = setup2;
11844
+ var setup_default = setup;
14880
11845
 
14881
11846
  // src/app/commands/builtins/telemetry.ts
14882
11847
  var telemetryCommand = {
@@ -15705,7 +12670,7 @@ var cachedVersion = null;
15705
12670
  function readPackageVersion() {
15706
12671
  if (cachedVersion !== null) return cachedVersion;
15707
12672
  try {
15708
- const injected = "0.5.8";
12673
+ const injected = "0.5.11";
15709
12674
  if (typeof injected === "string" && injected.length > 0) {
15710
12675
  cachedVersion = injected;
15711
12676
  return cachedVersion;