nolo-cli 0.49.1 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/{_executeModel-KE4PQSZ3.js → _executeModel-JKEH7ACW.js} +48 -42
  2. package/{action-IU6ON7ZB.js → action-VSG2IYP3.js} +8 -8
  3. package/{addContentAction-5V5CCI3I.js → addContentAction-2HJJITDI.js} +8 -7
  4. package/{addDialogAgentAction-KF3KZZNZ.js → addDialogAgentAction-7BSQVVL5.js} +10 -9
  5. package/{agentDeleteCommand-Z67TJG3W.js → agentDeleteCommand-SVXKS5SC.js} +30 -28
  6. package/{agentEmailCommands-7LPIK7JE.js → agentEmailCommands-WN7QBTP3.js} +57 -52
  7. package/{agentListCommands-5J2IM3IT.js → agentListCommands-2BEBOQIG.js} +42 -33
  8. package/{agentMachineCommands-YXH6FXUQ.js → agentMachineCommands-WALP3ONU.js} +30 -28
  9. package/{agentRecordCommands-GZLCDVUS.js → agentRecordCommands-E652SW57.js} +55 -50
  10. package/{agentRunCommand-WYH5Q54Q.js → agentRunCommand-6VXWXKCS.js} +60 -53
  11. package/{agentRunControl-4GHHSXFZ.js → agentRunControl-LJVFDJGU.js} +3 -1
  12. package/{agentRuntimeLocal-A6EF3RUY.js → agentRuntimeLocal-SBG7BDFQ.js} +30 -26
  13. package/{agentSlice-ARTDF6VD.js → agentSlice-3WYXIGEO.js} +8 -8
  14. package/{agentSuperviseCommands-VB6BUS5H.js → agentSuperviseCommands-F3RFAL7K.js} +2 -2
  15. package/{appDeleteCommands-V2B7ZCLC.js → appDeleteCommands-NTUNMEXY.js} +31 -29
  16. package/{appDeployCommands-AXQU44RD.js → appDeployCommands-DISWXRTL.js} +31 -29
  17. package/{appDeployStatusCommands-FWGSC2UM.js → appDeployStatusCommands-IKRA6B6F.js} +31 -29
  18. package/{appGetCommands-67R3RFZK.js → appGetCommands-UMOP2DFV.js} +31 -29
  19. package/{appListCommands-TTASJPGV.js → appListCommands-ZKFD2AKS.js} +31 -29
  20. package/{authCommand-QOPOEYEK.js → authCommand-BS3CQC6I.js} +11 -11
  21. package/{chatQueueReduxAdapter-6CAHUQ4O.js → chatQueueReduxAdapter-A3YH4MT4.js} +24 -21
  22. package/{chunk-76UA7376.js → chunk-273FJUYI.js} +6 -6
  23. package/{chunk-7CH6U3FL.js → chunk-2GRGFCF6.js} +2 -4
  24. package/{chunk-T27IEBNQ.js → chunk-2QDDKFG5.js} +74 -1
  25. package/{chunk-IRJVFYOH.js → chunk-2TLYVDTN.js} +321 -1100
  26. package/{chunk-6BYAXNH5.js → chunk-3QOCS5IF.js} +11 -2
  27. package/chunk-6IGD47IC.js +19 -0
  28. package/{chunk-GFD7TIZU.js → chunk-6TUT5ZJD.js} +4 -6
  29. package/chunk-6YTOJY35.js +352 -0
  30. package/{chunk-B54WOZ77.js → chunk-7H7GQL6V.js} +2 -2
  31. package/{chunk-OYNDYVSE.js → chunk-B45YNDAE.js} +1 -1
  32. package/{chunk-UQWFIWHX.js → chunk-BKIDF5LV.js} +1 -1
  33. package/{chunk-5XCW6RQG.js → chunk-BUBPRCIU.js} +1 -1
  34. package/chunk-BYXBJQAS.js +0 -0
  35. package/{chunk-X7S7OFUX.js → chunk-CEVCRRHU.js} +4 -4
  36. package/{chunk-SP3DPVBH.js → chunk-DEIGUGP6.js} +2 -2
  37. package/{chunk-V2IPBG5U.js → chunk-DGEPT6FH.js} +1 -1
  38. package/{chunk-3AOLVADY.js → chunk-DVINR3PL.js} +1 -1
  39. package/{chunk-NN3AMBY3.js → chunk-DXOELY7S.js} +64 -69
  40. package/{chunk-OFZPJ3NT.js → chunk-E4MARS3Q.js} +1 -1
  41. package/{chunk-QUCSAM43.js → chunk-EAYBPWHX.js} +87 -66
  42. package/{chunk-DQLYEGP7.js → chunk-EGVY3GMT.js} +1 -1
  43. package/{chunk-2JYSSXLY.js → chunk-EJFW7TRP.js} +5 -26
  44. package/{chunk-HPZL4IBN.js → chunk-FGRCSLPV.js} +34 -45
  45. package/{chunk-WL3UOGYO.js → chunk-G4WSLTQF.js} +31 -97
  46. package/{chunk-HR5XDXYM.js → chunk-G5SQVIFZ.js} +3 -3
  47. package/{chunk-J3UALFHL.js → chunk-GHE5XMVR.js} +1 -1
  48. package/{chunk-6SMMK7MD.js → chunk-GKB4AZKV.js} +440 -2981
  49. package/{chunk-IKSFDJXB.js → chunk-GKNGRBE6.js} +150 -27
  50. package/{chunk-Q24S4NDF.js → chunk-HQTK2SFT.js} +1 -1
  51. package/{chunk-GDGIEGHV.js → chunk-IPTZ5TVU.js} +7 -6
  52. package/{chunk-4RXXP6WD.js → chunk-J7KDNHUO.js} +5 -64
  53. package/{chunk-QDHZCAH3.js → chunk-KNQ5LYVZ.js} +57 -2
  54. package/{chunk-VRJUIUIY.js → chunk-KVVNC5V3.js} +2 -2
  55. package/{chunk-CVT7L2WZ.js → chunk-LVCAWHI5.js} +4 -4
  56. package/{chunk-WX5E6HZS.js → chunk-N6SLQMSA.js} +6 -6
  57. package/{chunk-SQTVMYMU.js → chunk-NTZO3KX2.js} +3 -3
  58. package/{chunk-LGUQHYAL.js → chunk-O5FLGN2L.js} +3 -2
  59. package/{chunk-WKOEOQCI.js → chunk-OSUZKICS.js} +1600 -190
  60. package/{chunk-EXDR5D6X.js → chunk-Q2QN2RHG.js} +7 -7
  61. package/{chunk-L3JWI7WX.js → chunk-QOKAKDPE.js} +15 -11
  62. package/{chunk-757BGY6Y.js → chunk-RFYXK6KI.js} +1 -1
  63. package/chunk-RQSN75DW.js +1766 -0
  64. package/{chunk-HCMFFI2G.js → chunk-S3JNURSO.js} +2 -2
  65. package/{chunk-YZ2WE6CW.js → chunk-SAJSBPI2.js} +2 -2
  66. package/{chunk-WHVQA7PJ.js → chunk-SCBBGS2N.js} +23 -5
  67. package/chunk-SGSJBBKP.js +297 -0
  68. package/{chunk-GFUOVFQA.js → chunk-TUBNQ3OF.js} +2 -2
  69. package/{chunk-BANYWEYY.js → chunk-TY3ADTX5.js} +1 -1
  70. package/chunk-UAD2WT54.js +64 -0
  71. package/{chunk-SW7RCUGA.js → chunk-UEV5WVQV.js} +3 -3
  72. package/{chunk-EURF2SV6.js → chunk-UMCMW5R3.js} +51 -34
  73. package/{chunk-K524MUQC.js → chunk-VFDRZHPM.js} +16 -16
  74. package/{chunk-5WADL4O7.js → chunk-W22UTILW.js} +3 -3
  75. package/{chunk-IKTHA3JH.js → chunk-WERPP2S7.js} +2 -2
  76. package/{chunk-GBADO3SM.js → chunk-WSUHBABG.js} +1 -1
  77. package/{chunk-U5Z7LFZF.js → chunk-X3OGKR5Q.js} +4 -4
  78. package/{chunk-AVKUDHJO.js → chunk-X5LRMXTS.js} +10 -10
  79. package/{chunk-DIQCV4FR.js → chunk-X665UCNM.js} +1 -1
  80. package/{chunk-HCBQVVFZ.js → chunk-X7P6EJUY.js} +4 -4
  81. package/{chunk-HHBXCRJS.js → chunk-XOJRZUPF.js} +4 -4
  82. package/{chunk-MRWGHF56.js → chunk-YDH3FDFQ.js} +12 -356
  83. package/{chunk-TNPCQNGQ.js → chunk-YEFRCO5N.js} +4 -9
  84. package/{chunk-RO2IUWZE.js → chunk-YUKTCDVN.js} +1 -1
  85. package/{chunk-56W233KG.js → chunk-YWY25N4V.js} +1 -1
  86. package/{chunk-RU5D3B22.js → chunk-ZDS63Y4O.js} +2 -2
  87. package/chunk-ZJ7UHBJS.js +89 -0
  88. package/{chunk-SG65C33A.js → chunk-ZLMG6NRV.js} +4 -4
  89. package/{codingSkills-BYQI6EPT.js → codingSkills-FQPCEIWL.js} +2 -2
  90. package/contentThunks-J33BZB3E.js +71 -0
  91. package/{createAgentAutomationAction-7BBF5YXN.js → createAgentAutomationAction-HTMTGX6Q.js} +25 -21
  92. package/{createDialogAction-B5URPHP4.js → createDialogAction-WYQBSN6A.js} +27 -23
  93. package/{createPageAction-ISJKM5Q3.js → createPageAction-ICRRK3SA.js} +27 -22
  94. package/{dbSlice-FWF5F4L7.js → dbSlice-YORO4VL4.js} +6 -6
  95. package/{deleteFile-NPZ64DFN.js → deleteFile-JYKRT7C3.js} +4 -4
  96. package/{dialogCommands-XHH4MVA4.js → dialogCommands-FRSIAPKY.js} +31 -29
  97. package/{dialogSlice-NRAN5X7F.js → dialogSlice-5KPVIAWH.js} +24 -21
  98. package/{docCreateCommands-FUN2Z7HQ.js → docCreateCommands-DBRJMPDX.js} +30 -28
  99. package/{docDeleteCommands-OZDPFXPF.js → docDeleteCommands-BCYPLWXN.js} +31 -29
  100. package/{docReadCommands-FIPK7LE3.js → docReadCommands-L5JX4Q7G.js} +30 -28
  101. package/{docStore-LUS7SWC3.js → docStore-34NXLCEO.js} +8 -33
  102. package/{docUpdateCommands-BZ5GKAN4.js → docUpdateCommands-RELG7XJD.js} +30 -28
  103. package/fetchMessages-KZQVBXKY.js +1 -1
  104. package/{getPricing-HAU62AFM.js → getPricing-FM7TJZFV.js} +4 -4
  105. package/{handleSendMessageAction-RA4OD2ZH.js → handleSendMessageAction-MEYK7RPD.js} +25 -22
  106. package/index.js +64 -64
  107. package/{machineCommands-WDAYEFBE.js → machineCommands-YSXTOWHQ.js} +59 -54
  108. package/{machineWsRunDispatch-TPQ2FQVS.js → machineWsRunDispatch-DNAYOPQT.js} +54 -49
  109. package/memberThunks-KVPBG4V7.js +638 -0
  110. package/{models-4QF4BJVY.js → models-CW5EL6Z7.js} +2 -2
  111. package/package.json +2 -3
  112. package/{read-J7RVVCHH.js → read-NIOV5F7W.js} +4 -4
  113. package/{readDocTool-G2WBM4IH.js → readDocTool-ULKJ5BEM.js} +1 -1
  114. package/{readlineWorkspace-HN44KGIF.js → readlineWorkspace-KZ3LPQG2.js} +829 -393
  115. package/{removeDialogAgentAction-RMPISD42.js → removeDialogAgentAction-JGSCPML3.js} +12 -11
  116. package/{runAgentClientLoop-ZYUI22EA.js → runAgentClientLoop-O2AUHIJT.js} +46 -40
  117. package/{setDialogExtraReferencesAction-7BUTHDAL.js → setDialogExtraReferencesAction-CORU64NM.js} +9 -8
  118. package/{setPrimaryDialogAgentAction-WCYIBGZ4.js → setPrimaryDialogAgentAction-5VS2VKLZ.js} +12 -11
  119. package/{settingSlice-7NN2MI6Y.js → settingSlice-3GNGTC2T.js} +7 -7
  120. package/{skillDiscovery-COX56OBO.js → skillDiscovery-CYUCJMAG.js} +3 -3
  121. package/{spaceCommands-OJ2567D4.js → spaceCommands-OI7RIB2T.js} +30 -28
  122. package/{streamAgentChatTurn-FNFMMGNN.js → streamAgentChatTurn-TA3PGS6C.js} +61 -54
  123. package/{switchDialogAgentAction-WGMMQHDI.js → switchDialogAgentAction-LP433X4D.js} +10 -9
  124. package/{tableCommands-P2TXJ3CF.js → tableCommands-R6WFRDYF.js} +1 -1
  125. package/{toolApiClient-B2MFXMEG.js → toolApiClient-53U4UDFF.js} +3 -2
  126. package/{tools-QCDR3UMD.js → tools-6ZPQ75XA.js} +37 -32
  127. package/{tuiSummaryLlmCaller-LCGT62QC.js → tuiSummaryLlmCaller-YKYQB4ZL.js} +17 -15
  128. package/{updateDialogTitleAction-Y3OGJWDB.js → updateDialogTitleAction-LRJ7NSOS.js} +26 -22
  129. package/chunk-EUG45QJR.js +0 -6104
  130. package/spaceSlice-F7JCOZEF.js +0 -127
  131. package/{chunk-NQ4N4IGO.js → chunk-CS6TCJ7E.js} +3 -3
@@ -1,6 +1,3 @@
1
- import {
2
- generateRunReport
3
- } from "./chunk-J3UALFHL.js";
4
1
  import {
5
2
  buildLocalRunEnv,
6
3
  isFullstackCodingAgentRef,
@@ -10,6 +7,9 @@ import {
10
7
  resolveServerUrl,
11
8
  writeUsage
12
9
  } from "./chunk-LYGNQHUW.js";
10
+ import {
11
+ resolveMachineId
12
+ } from "./chunk-ESHYE7WU.js";
13
13
  import {
14
14
  agentRunCardLabels,
15
15
  createCliLocalRuntimeAdapter,
@@ -19,7 +19,12 @@ import {
19
19
  parseAgentRunEvent,
20
20
  t,
21
21
  toolLabel
22
- } from "./chunk-QUCSAM43.js";
22
+ } from "./chunk-EAYBPWHX.js";
23
+ import {
24
+ readCredentialEntry,
25
+ recordCredentialProbe,
26
+ resolveCredentialKeyWithFallback
27
+ } from "./chunk-NI2BS6UD.js";
23
28
  import {
24
29
  getReadableCliDb
25
30
  } from "./chunk-43CXXVJD.js";
@@ -27,11 +32,14 @@ import {
27
32
  normalizeAgentHandle,
28
33
  readDbRecord,
29
34
  resolveAgentRecordFromHybridStore
30
- } from "./chunk-DQLYEGP7.js";
35
+ } from "./chunk-EGVY3GMT.js";
31
36
  import {
32
37
  NOLO_PROJECT_MANAGER_AGENT_KEY,
33
38
  isLocalCliAgentKey
34
39
  } from "./chunk-EKLRRZIN.js";
40
+ import {
41
+ generateRunReport
42
+ } from "./chunk-GHE5XMVR.js";
35
43
  import {
36
44
  CliProviderQuotaError
37
45
  } from "./chunk-JDSUTNYY.js";
@@ -42,17 +50,14 @@ import {
42
50
  readRunRecord,
43
51
  resolveRunQueuePath,
44
52
  spawnLocalBackgroundRun
45
- } from "./chunk-WHVQA7PJ.js";
46
- import {
47
- resolveMachineId
48
- } from "./chunk-ESHYE7WU.js";
53
+ } from "./chunk-SCBBGS2N.js";
49
54
  import {
50
55
  applyModelLayerOverride,
51
56
  buildModelLayerOverride
52
57
  } from "./chunk-LTRXGFMS.js";
53
58
  import {
54
59
  formatAgentListCard
55
- } from "./chunk-WKOEOQCI.js";
60
+ } from "./chunk-OSUZKICS.js";
56
61
  import {
57
62
  isTransientFetchError
58
63
  } from "./chunk-5XTOKQLW.js";
@@ -66,26 +71,25 @@ import {
66
71
  formatStartRunCard,
67
72
  formatStatusRunCard,
68
73
  formatStopRunCard,
69
- isAgentRunTerminalStatus,
70
- runShowsLogTail
74
+ isAgentRunTerminalStatus
71
75
  } from "./chunk-KXKQO4Q6.js";
72
76
  import {
73
77
  buildMemorySubjectsForAgent,
74
78
  chooseMemoryOwners,
75
79
  loadMemoryCandidatesFromDb,
76
80
  resolveAgentMemoryPolicy
77
- } from "./chunk-AVKUDHJO.js";
81
+ } from "./chunk-X5LRMXTS.js";
78
82
  import {
79
83
  API_REPORTED_COST_MULTIPLIER,
80
84
  normalizeUsage,
81
85
  parseUiAskChoiceContent
82
- } from "./chunk-EURF2SV6.js";
86
+ } from "./chunk-UMCMW5R3.js";
83
87
  import {
84
88
  getDefaultCliLocalRuntimeDb
85
89
  } from "./chunk-IA3A5373.js";
86
90
  import {
87
91
  buildSkillDiscoveryContextLayer
88
- } from "./chunk-OFZPJ3NT.js";
92
+ } from "./chunk-E4MARS3Q.js";
89
93
  import {
90
94
  parseExternalSkillMarkdown,
91
95
  parseSkillDocProtocol
@@ -93,12 +97,11 @@ import {
93
97
  import {
94
98
  LOCAL_AGENT_CONFIG_MISSING_CODE,
95
99
  LOCAL_TURN_ABORTED_CODE,
96
- readActionGate,
97
- readCommandActionGatePayload
98
- } from "./chunk-IKSFDJXB.js";
100
+ readActionGate
101
+ } from "./chunk-GKNGRBE6.js";
99
102
  import {
100
103
  resolveAgentRuntimeConfigFromRecord
101
- } from "./chunk-CVT7L2WZ.js";
104
+ } from "./chunk-LVCAWHI5.js";
102
105
  import {
103
106
  createThinkParserState,
104
107
  flushThinkParser,
@@ -107,20 +110,22 @@ import {
107
110
  import {
108
111
  resolveClientVersion,
109
112
  resolvePlatformAuthToken
110
- } from "./chunk-SP3DPVBH.js";
113
+ } from "./chunk-DEIGUGP6.js";
111
114
  import {
112
- isQuotaExhaustedError
115
+ isQuotaExhaustedError,
116
+ mergeAvailabilityDeadline,
117
+ resolveCooldownGate
113
118
  } from "./chunk-IWUMSAQF.js";
114
119
  import {
115
120
  DEFAULT_CONTEXT_WINDOW,
116
121
  getModelContextWindow
117
- } from "./chunk-SW7RCUGA.js";
122
+ } from "./chunk-UEV5WVQV.js";
118
123
  import {
119
124
  clipCompactText
120
- } from "./chunk-HR5XDXYM.js";
125
+ } from "./chunk-G5SQVIFZ.js";
121
126
  import {
122
127
  findModelConfig
123
- } from "./chunk-QDHZCAH3.js";
128
+ } from "./chunk-KNQ5LYVZ.js";
124
129
  import {
125
130
  compactWhitespace
126
131
  } from "./chunk-DWLEOOGR.js";
@@ -133,7 +138,7 @@ import {
133
138
  buildMemoryUseGuidanceLayer,
134
139
  partitionScopedBlocks,
135
140
  renderTurnContextBlocksWithScope
136
- } from "./chunk-3AOLVADY.js";
141
+ } from "./chunk-DVINR3PL.js";
137
142
  import {
138
143
  readPipeText,
139
144
  spawnProcess
@@ -145,7 +150,7 @@ import {
145
150
  CLIENT_VERSION_TOO_OLD_CODE,
146
151
  NOLO_CLIENT_VERSION_HEADER,
147
152
  buildClientVersionUpgradeMessage
148
- } from "./chunk-WL3UOGYO.js";
153
+ } from "./chunk-G4WSLTQF.js";
149
154
  import {
150
155
  parsePositiveFiniteNumberOrFallback
151
156
  } from "./chunk-Y5GCAMGP.js";
@@ -159,7 +164,7 @@ import {
159
164
  BUILTIN_NOLO_AGENT_KEY,
160
165
  BUILTIN_NOLO_AGENT_NAME,
161
166
  builtinAgentCatalogEntryById
162
- } from "./chunk-2JYSSXLY.js";
167
+ } from "./chunk-EJFW7TRP.js";
163
168
  import {
164
169
  parsePublicAgentId
165
170
  } from "./chunk-BJIRLHJR.js";
@@ -1240,13 +1245,6 @@ function setActiveThemeMode(mode) {
1240
1245
  function setActiveBrightness(brightness) {
1241
1246
  setActiveThemeMode(brightness ?? "terminal");
1242
1247
  }
1243
- var activeDensity = "spacious";
1244
- function getActiveDensity() {
1245
- return activeDensity;
1246
- }
1247
- function setActiveDensity(density) {
1248
- activeDensity = density;
1249
- }
1250
1248
  var TRUECOLOR_TERM_PROGRAMS = /* @__PURE__ */ new Set([
1251
1249
  "iterm.app",
1252
1250
  "wezterm",
@@ -2824,11 +2822,6 @@ function scanStringCommentRegions(line, lang) {
2824
2822
  }
2825
2823
  return regions;
2826
2824
  }
2827
- function detectCodeLangFromPath(filePath) {
2828
- if (!filePath) return "unknown";
2829
- const ext = filePath.split(".").pop() ?? "";
2830
- return normalizeCodeLang(ext);
2831
- }
2832
2825
  function highlightCodeLine(line, lang, brightness) {
2833
2826
  const info = colorSeq("info", brightness);
2834
2827
  if (lang === "unknown") {
@@ -2915,6 +2908,14 @@ function normalizeListLine(line) {
2915
2908
  }
2916
2909
  return line;
2917
2910
  }
2911
+ function isPolishListLikeLine(line) {
2912
+ return LIST_LIKE_RE_FOR_GUARD.test(normalizeListLine(line));
2913
+ }
2914
+ var LIST_LIKE_RE_FOR_GUARD = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
2915
+ function polishBreathInsertsBlankBetween(cur, next) {
2916
+ if (cur === "" || next === "") return false;
2917
+ return isPolishListLikeLine(cur) !== isPolishListLikeLine(next);
2918
+ }
2918
2919
  function convertMarkdownTablesForTerminal(text) {
2919
2920
  const lines = text.split("\n");
2920
2921
  const out = [];
@@ -2982,7 +2983,7 @@ function polishAssistantStructure(text, options = {}) {
2982
2983
  return line;
2983
2984
  });
2984
2985
  const afterHeading = maskedLines.join("\n").replace(/([^\n])\n(#{1,3} )/g, "$1\n\n$2").replace(/^(#{1,3} .+)\n(?!\n)/gm, "$1\n\n").replace(/\n{4,}/g, "\n\n\n");
2985
- const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]/;
2986
+ const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
2986
2987
  const headingLines = afterHeading.split("\n");
2987
2988
  const breathed = [];
2988
2989
  for (let i = 0; i < headingLines.length; i++) {
@@ -3401,16 +3402,6 @@ function formatReadItemPath(rawPath, metadata, customHomedir) {
3401
3402
  const clippedPath = clipPathAware(formattedPath, 72);
3402
3403
  return `${clippedPath}${rangePart}`;
3403
3404
  }
3404
- function formatReadTreeLines(items, customHomedir) {
3405
- const count = items.length;
3406
- const header = `Read (${count})`;
3407
- const lines = items.map((item, index) => {
3408
- const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
3409
- const pathWithRange = formatReadItemPath(item.path, item.metadata, customHomedir);
3410
- return { connector, pathWithRange };
3411
- });
3412
- return { header, count, lines };
3413
- }
3414
3405
  function formatSearchItemQuery(query, path, customHomedir) {
3415
3406
  let text = (query || "").trim();
3416
3407
  if (path) {
@@ -3422,16 +3413,6 @@ function formatSearchItemQuery(query, path, customHomedir) {
3422
3413
  if (!text) return "search";
3423
3414
  return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
3424
3415
  }
3425
- function formatSearchTreeLines(items, customHomedir) {
3426
- const count = items.length;
3427
- const header = `Search (${count})`;
3428
- const lines = items.map((item, index) => {
3429
- const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
3430
- const queryText = formatSearchItemQuery(item.query, item.path, customHomedir);
3431
- return { connector, queryText };
3432
- });
3433
- return { header, count, lines };
3434
- }
3435
3416
  function formatRunItemCommand(command, exitCode, timedOut) {
3436
3417
  let text = compactWhitespace(command || "");
3437
3418
  if (!text) text = "command";
@@ -3440,453 +3421,24 @@ function formatRunItemCommand(command, exitCode, timedOut) {
3440
3421
  if (typeof exitCode === "number" && exitCode !== 0) return `${text} (exit ${exitCode})`;
3441
3422
  return text;
3442
3423
  }
3443
- function formatRunTreeLines(items) {
3444
- const count = items.length;
3445
- const header = `Run (${count})`;
3446
- const lines = items.map((item, index) => {
3447
- const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
3448
- const commandText = formatRunItemCommand(item.command, item.exitCode, item.timedOut);
3449
- return { connector, commandText };
3450
- });
3451
- return { header, count, lines };
3452
- }
3453
3424
  function formatFetchItemUrl(url) {
3454
3425
  const text = (url || "").trim();
3455
3426
  if (!text) return "webpage";
3456
3427
  return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
3457
3428
  }
3458
- function formatFetchTreeLines(items) {
3459
- const count = items.length;
3460
- const header = `Fetch (${count})`;
3461
- const lines = items.map((item, index) => {
3462
- const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
3463
- const urlText = formatFetchItemUrl(item.url);
3464
- return { connector, urlText };
3465
- });
3466
- return { header, count, lines };
3467
- }
3468
-
3469
- // node_modules/diff/libesm/diff/base.js
3470
- var Diff = class {
3471
- diff(oldStr, newStr, options = {}) {
3472
- let callback;
3473
- if (typeof options === "function") {
3474
- callback = options;
3475
- options = {};
3476
- } else if ("callback" in options) {
3477
- callback = options.callback;
3478
- }
3479
- const oldString = this.castInput(oldStr, options);
3480
- const newString = this.castInput(newStr, options);
3481
- const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
3482
- const newTokens = this.removeEmpty(this.tokenize(newString, options));
3483
- return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);
3484
- }
3485
- diffWithOptionsObj(oldTokens, newTokens, options, callback) {
3486
- var _a;
3487
- const done = (value) => {
3488
- value = this.postProcess(value, options);
3489
- if (callback) {
3490
- setTimeout(function() {
3491
- callback(value);
3492
- }, 0);
3493
- return void 0;
3494
- } else {
3495
- return value;
3496
- }
3497
- };
3498
- const newLen = newTokens.length, oldLen = oldTokens.length;
3499
- let editLength = 1;
3500
- let maxEditLength = newLen + oldLen;
3501
- if (options.maxEditLength != null) {
3502
- maxEditLength = Math.min(maxEditLength, options.maxEditLength);
3503
- }
3504
- const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity;
3505
- const abortAfterTimestamp = Date.now() + maxExecutionTime;
3506
- const bestPath = [{ oldPos: -1, lastComponent: void 0 }];
3507
- let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
3508
- if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
3509
- return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
3510
- }
3511
- let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
3512
- const execEditLength = () => {
3513
- for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
3514
- let basePath;
3515
- const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];
3516
- if (removePath) {
3517
- bestPath[diagonalPath - 1] = void 0;
3518
- }
3519
- let canAdd = false;
3520
- if (addPath) {
3521
- const addPathNewPos = addPath.oldPos - diagonalPath;
3522
- canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;
3523
- }
3524
- const canRemove = removePath && removePath.oldPos + 1 < oldLen;
3525
- if (!canAdd && !canRemove) {
3526
- bestPath[diagonalPath] = void 0;
3527
- continue;
3528
- }
3529
- if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
3530
- basePath = this.addToPath(addPath, true, false, 0, options);
3531
- } else {
3532
- basePath = this.addToPath(removePath, false, true, 1, options);
3533
- }
3534
- newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);
3535
- if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
3536
- return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;
3537
- } else {
3538
- bestPath[diagonalPath] = basePath;
3539
- if (basePath.oldPos + 1 >= oldLen) {
3540
- maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
3541
- }
3542
- if (newPos + 1 >= newLen) {
3543
- minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
3544
- }
3545
- }
3546
- }
3547
- editLength++;
3548
- };
3549
- if (callback) {
3550
- (function exec() {
3551
- setTimeout(function() {
3552
- if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
3553
- return callback(void 0);
3554
- }
3555
- if (!execEditLength()) {
3556
- exec();
3557
- }
3558
- }, 0);
3559
- })();
3560
- } else {
3561
- while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
3562
- const ret = execEditLength();
3563
- if (ret) {
3564
- return ret;
3565
- }
3566
- }
3567
- }
3568
- }
3569
- addToPath(path, added, removed, oldPosInc, options) {
3570
- const last = path.lastComponent;
3571
- if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
3572
- return {
3573
- oldPos: path.oldPos + oldPosInc,
3574
- lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
3575
- };
3576
- } else {
3577
- return {
3578
- oldPos: path.oldPos + oldPosInc,
3579
- lastComponent: { count: 1, added, removed, previousComponent: last }
3580
- };
3581
- }
3582
- }
3583
- extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
3584
- const newLen = newTokens.length, oldLen = oldTokens.length;
3585
- let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
3586
- while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
3587
- newPos++;
3588
- oldPos++;
3589
- commonCount++;
3590
- if (options.oneChangePerToken) {
3591
- basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
3592
- }
3593
- }
3594
- if (commonCount && !options.oneChangePerToken) {
3595
- basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
3596
- }
3597
- basePath.oldPos = oldPos;
3598
- return newPos;
3599
- }
3600
- equals(left, right, options) {
3601
- if (options.comparator) {
3602
- return options.comparator(left, right);
3603
- } else {
3604
- return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
3605
- }
3606
- }
3607
- removeEmpty(array) {
3608
- const ret = [];
3609
- for (let i = 0; i < array.length; i++) {
3610
- if (array[i]) {
3611
- ret.push(array[i]);
3612
- }
3613
- }
3614
- return ret;
3615
- }
3616
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
3617
- castInput(value, options) {
3618
- return value;
3619
- }
3620
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
3621
- tokenize(value, options) {
3622
- return Array.from(value);
3623
- }
3624
- join(chars) {
3625
- return chars.join("");
3626
- }
3627
- postProcess(changeObjects, options) {
3628
- return changeObjects;
3629
- }
3630
- get useLongestToken() {
3631
- return false;
3632
- }
3633
- buildValues(lastComponent, newTokens, oldTokens) {
3634
- const components = [];
3635
- let nextComponent;
3636
- while (lastComponent) {
3637
- components.push(lastComponent);
3638
- nextComponent = lastComponent.previousComponent;
3639
- delete lastComponent.previousComponent;
3640
- lastComponent = nextComponent;
3641
- }
3642
- components.reverse();
3643
- const componentLen = components.length;
3644
- let componentPos = 0, newPos = 0, oldPos = 0;
3645
- for (; componentPos < componentLen; componentPos++) {
3646
- const component = components[componentPos];
3647
- if (!component.removed) {
3648
- if (!component.added && this.useLongestToken) {
3649
- let value = newTokens.slice(newPos, newPos + component.count);
3650
- value = value.map(function(value2, i) {
3651
- const oldValue = oldTokens[oldPos + i];
3652
- return oldValue.length > value2.length ? oldValue : value2;
3653
- });
3654
- component.value = this.join(value);
3655
- } else {
3656
- component.value = this.join(newTokens.slice(newPos, newPos + component.count));
3657
- }
3658
- newPos += component.count;
3659
- if (!component.added) {
3660
- oldPos += component.count;
3661
- }
3662
- } else {
3663
- component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
3664
- oldPos += component.count;
3665
- }
3666
- }
3667
- return components;
3668
- }
3669
- };
3670
-
3671
- // node_modules/diff/libesm/diff/line.js
3672
- var LineDiff = class extends Diff {
3673
- constructor() {
3674
- super(...arguments);
3675
- this.tokenize = tokenize;
3676
- }
3677
- equals(left, right, options) {
3678
- if (options.ignoreWhitespace) {
3679
- if (!options.newlineIsToken || !left.includes("\n")) {
3680
- left = left.trim();
3681
- }
3682
- if (!options.newlineIsToken || !right.includes("\n")) {
3683
- right = right.trim();
3684
- }
3685
- } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
3686
- if (left.endsWith("\n")) {
3687
- left = left.slice(0, -1);
3688
- }
3689
- if (right.endsWith("\n")) {
3690
- right = right.slice(0, -1);
3691
- }
3692
- }
3693
- return super.equals(left, right, options);
3694
- }
3695
- };
3696
- var lineDiff = new LineDiff();
3697
- function diffLines(oldStr, newStr, options) {
3698
- return lineDiff.diff(oldStr, newStr, options);
3699
- }
3700
- function tokenize(value, options) {
3701
- if (options.stripTrailingCr) {
3702
- value = value.replace(/\r\n/g, "\n");
3703
- }
3704
- const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/);
3705
- if (!linesAndNewlines[linesAndNewlines.length - 1]) {
3706
- linesAndNewlines.pop();
3707
- }
3708
- for (let i = 0; i < linesAndNewlines.length; i++) {
3709
- const line = linesAndNewlines[i];
3710
- if (i % 2 && !options.newlineIsToken) {
3711
- retLines[retLines.length - 1] += line;
3712
- } else {
3713
- retLines.push(line);
3714
- }
3715
- }
3716
- return retLines;
3717
- }
3718
3429
 
3719
3430
  // packages/cli/client/toolOutput.ts
3720
- function normalizeToolDisplayMode(raw, fallback = "normal") {
3721
- const normalized = asTrimmedLowercaseString(raw);
3722
- if (normalized === "hide" || normalized === "off" || normalized === "false" || normalized === "0") {
3723
- return "hide";
3724
- }
3725
- if (normalized === "verbose" || normalized === "debug" || normalized === "trace" || normalized === "full") {
3726
- return "verbose";
3727
- }
3728
- if (normalized === "normal" || normalized === "summary" || normalized === "on") {
3729
- return "normal";
3730
- }
3731
- if (normalized === "pro" || normalized === "compact" || normalized === "minimal" || normalized === "short") {
3732
- return "pro";
3733
- }
3734
- return fallback;
3735
- }
3736
- function resolveToolDisplayMode(env = process.env) {
3737
- const legacyTrace = asTrimmedLowercaseString(env.NOLO_TRACE_TOOLS);
3738
- if (legacyTrace === "0" || legacyTrace === "false" || legacyTrace === "off") {
3739
- return "hide";
3740
- }
3741
- if (legacyTrace === "verbose" || legacyTrace === "full") {
3742
- return "verbose";
3743
- }
3744
- return normalizeToolDisplayMode(env.NOLO_CLI_TOOLS ?? env.NOLO_TOOLS, "normal");
3745
- }
3746
- function shouldEmitToolEvents(mode) {
3747
- return mode !== "hide";
3748
- }
3749
3431
  function clip(value, max = 72) {
3750
3432
  return clipCompactText(value, max, "\u2026");
3751
3433
  }
3752
- function formatActiveToolLabel(event) {
3753
- const toolName = event.toolName || "tool";
3754
- const args = clipPathAware(event.argumentsPreview ?? "");
3755
- const label = toolLabel(toolName);
3756
- return args ? `${label} ${args}` : label;
3757
- }
3758
3434
  function formatConservativeActiveToolLabel(event) {
3759
3435
  return toolLabel(event.toolName || "tool");
3760
3436
  }
3761
- function compactResultHint(event) {
3762
- const gate = readActionGate(event.metadata?.actionGate);
3763
- if (gate) {
3764
- const commandPayload = gate.kind === "handoff" ? readCommandActionGatePayload(gate.payload) : null;
3765
- const command = commandPayload?.displayCommand ?? commandPayload?.command.join(" ") ?? "";
3766
- const detail = command.trim() ? command : gate.title;
3767
- return { inline: `${t("toolNeedsAction")}: ${clip(detail, 120)}` };
3768
- }
3769
- if (event.metadata?.timedOut) return { inline: t("toolTimedOut") };
3770
- if (event.toolName === "readFile" && event.metadata) {
3771
- const range = readReadFileRange(event.metadata);
3772
- if (range) return { inline: range };
3773
- }
3774
- if (event.toolName === "editFile" && event.metadata) {
3775
- const res = formatEditFileSnippet(event.metadata);
3776
- if (res) {
3777
- const stats = [];
3778
- if (res.addedCount > 0) stats.push(`+${res.addedCount}`);
3779
- if (res.removedCount > 0) stats.push(`-${res.removedCount}`);
3780
- const inline = stats.length > 0 ? `(${stats.join(", ")})` : "";
3781
- return { inline, detail: res.lines };
3782
- }
3783
- }
3784
- if (event.toolName === "writeFile" && event.metadata) {
3785
- const totalLines = event.metadata.totalLines ?? event.metadata.lines;
3786
- if (typeof totalLines === "number" && totalLines > 0) {
3787
- return { inline: `(+${totalLines})` };
3788
- }
3789
- }
3790
- const summary = event.summary;
3791
- if (!summary) return { inline: "" };
3792
- const exitMatch = summary.match(/exit=(\d+)/);
3793
- if (exitMatch && exitMatch[1] !== "0") return { inline: `${t("toolExitCode")} ${exitMatch[1]}` };
3794
- return { inline: "" };
3795
- }
3796
- function readReadFileRange(metadata) {
3797
- const startLine = metadata.startLine;
3798
- const endLine = metadata.endLine;
3799
- const totalLines = metadata.totalLines;
3800
- const truncated = metadata.truncated;
3801
- if (typeof startLine !== "number" || typeof endLine !== "number" || typeof totalLines !== "number") {
3802
- return void 0;
3803
- }
3804
- if (!truncated && startLine === 1 && endLine === totalLines) return void 0;
3805
- return `${startLine}-${endLine}/${totalLines}`;
3806
- }
3807
- var EDIT_SNIPPET_MAX_LINES = 24;
3808
- var DEFAULT_EDIT_SNIPPET_MAX_WIDTH = 96;
3809
- function resolveEditSnippetMaxWidth(env = process.env, columns) {
3810
- if (env.NOLO_TEST_DIFF_WIDTH) {
3811
- const parsed = parseInt(env.NOLO_TEST_DIFF_WIDTH, 10);
3812
- if (!Number.isNaN(parsed) && parsed > 0) return parsed;
3813
- }
3814
- const cols = typeof columns === "number" ? columns : typeof process !== "undefined" && typeof process.stdout?.columns === "number" ? process.stdout.columns : 0;
3815
- if (cols > 0) {
3816
- return Math.max(80, Math.min(160, cols - 8));
3817
- }
3818
- return DEFAULT_EDIT_SNIPPET_MAX_WIDTH;
3819
- }
3820
- function formatEditFileSnippet(metadata) {
3821
- const oldSnippet = typeof metadata.oldSnippet === "string" ? metadata.oldSnippet : void 0;
3822
- const newSnippet = typeof metadata.newSnippet === "string" ? metadata.newSnippet : void 0;
3823
- if (!oldSnippet && !newSnippet) return void 0;
3824
- const maxWidth = resolveEditSnippetMaxWidth();
3825
- if (oldSnippet && !newSnippet) {
3826
- const lines = snippetLinesWithKind(oldSnippet, "removed", maxWidth);
3827
- return { lines, addedCount: 0, removedCount: lines.length };
3828
- }
3829
- if (newSnippet && !oldSnippet) {
3830
- const lines = snippetLinesWithKind(newSnippet, "added", maxWidth);
3831
- return { lines, addedCount: lines.length, removedCount: 0 };
3832
- }
3833
- const parts = diffLines(oldSnippet, newSnippet);
3834
- const all = [];
3835
- let addedCount = 0;
3836
- let removedCount = 0;
3837
- for (const part of parts) {
3838
- const kind = part.added ? "added" : part.removed ? "removed" : "context";
3839
- const raw = part.value.split("\n");
3840
- if (raw.length > 0 && raw[raw.length - 1] === "") raw.pop();
3841
- for (const line of raw) {
3842
- if (kind === "added") addedCount++;
3843
- if (kind === "removed") removedCount++;
3844
- all.push(buildEditLine(kind, line, maxWidth));
3845
- }
3846
- }
3847
- const changeCount = all.filter((l) => l.kind !== "context").length;
3848
- if (changeCount === 0) return void 0;
3849
- return {
3850
- lines: windowAndTruncate(all, EDIT_SNIPPET_MAX_LINES),
3851
- addedCount,
3852
- removedCount
3853
- };
3854
- }
3855
- function prefixFor(kind) {
3856
- return kind === "added" ? "+ " : kind === "removed" ? "- " : " ";
3857
- }
3858
- function buildEditLine(kind, body, maxWidth = resolveEditSnippetMaxWidth()) {
3859
- return { kind, text: prefixFor(kind) + truncateByDisplayWidth(body, maxWidth) };
3860
- }
3861
- function snippetLinesWithKind(snippet, kind, maxWidth = resolveEditSnippetMaxWidth()) {
3862
- const lines = snippet.split(/\r?\n/).filter((line) => line.length > 0);
3863
- return lines.slice(0, EDIT_SNIPPET_MAX_LINES).map((line) => buildEditLine(kind, line, maxWidth));
3437
+ function isRunToolName(name) {
3438
+ return name === "execShell" || name === "runCommand" || name === "launchProcess";
3864
3439
  }
3865
- function truncateByDisplayWidth(line, maxWidth) {
3866
- if (displayWidth(line) <= maxWidth) return line;
3867
- let width = 0;
3868
- let kept = "";
3869
- for (const char of line) {
3870
- const w = displayWidth(char);
3871
- if (width + w + 1 > maxWidth) break;
3872
- kept += char;
3873
- width += w;
3874
- }
3875
- return `${kept}\u2026`;
3876
- }
3877
- function windowAndTruncate(lines, maxLines) {
3878
- if (lines.length <= maxLines) return lines;
3879
- const firstChange = lines.findIndex((l) => l.kind !== "context");
3880
- if (firstChange === -1) return lines.slice(0, maxLines);
3881
- const half = Math.floor(maxLines / 2);
3882
- let start = Math.max(0, firstChange - half);
3883
- if (start + maxLines > lines.length) start = Math.max(0, lines.length - maxLines);
3884
- const kept = lines.slice(start, start + maxLines);
3885
- const omitted = lines.length - kept.length;
3886
- if (omitted > 0) {
3887
- kept.push({ kind: "context", text: ` \u2026 +${omitted} more lines` });
3888
- }
3889
- return kept;
3440
+ function isReadToolName(name) {
3441
+ return name === "readFile";
3890
3442
  }
3891
3443
  function isFailedToolResult(event) {
3892
3444
  const exitCode = event.metadata?.exitCode;
@@ -3894,9 +3446,6 @@ function isFailedToolResult(event) {
3894
3446
  if (typeof exitCode === "number" && exitCode !== 0) return true;
3895
3447
  return Boolean(event.metadata?.timedOut);
3896
3448
  }
3897
- function isNeedsActionToolResult(event) {
3898
- return Boolean(event.metadata?.actionGate);
3899
- }
3900
3449
  function parseUiAskChoiceForCli(event) {
3901
3450
  if (event.toolName !== "ask_user" && !event.metadata?.uiAskChoice) {
3902
3451
  return null;
@@ -4080,10 +3629,6 @@ function recoverOrchestrationCard(event, toolName, opts) {
4080
3629
  if (kind === "stop") return formatStopRunCard(snapshot.status, labels);
4081
3630
  return renderRunCard(snapshot, opts);
4082
3631
  }
4083
- function parseControlAgentRunStatusEvent(event) {
4084
- const parsed = parseAgentRunEvent(event);
4085
- return parsed?.kind === "status" ? parsed.snapshot : null;
4086
- }
4087
3632
  function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
4088
3633
  const safe = opts?.safe === true;
4089
3634
  const rawLabel = toolLabel(toolName);
@@ -4153,59 +3698,32 @@ function sanitizeRunCardForNormal(lines) {
4153
3698
  }
4154
3699
  return out;
4155
3700
  }
4156
- function mergeRunSnapshot(previous, next) {
4157
- return {
4158
- ...previous,
4159
- ...next,
4160
- errorMessage: next.errorMessage ?? previous.errorMessage,
4161
- logLines: next.logLines ?? previous.logLines,
4162
- logKey: next.logKey || previous.logKey,
4163
- toolCallCount: next.toolCallCount ?? previous.toolCallCount,
4164
- lastToolNames: next.lastToolNames ?? previous.lastToolNames,
4165
- lastAssistantText: next.lastAssistantText ?? previous.lastAssistantText,
4166
- startedAt: next.startedAt ?? previous.startedAt,
4167
- finishedAt: next.finishedAt ?? previous.finishedAt
4168
- };
4169
- }
4170
- function formatFoldedControlStatusCard(snapshot, colorEnabled) {
4171
- const body = renderRunCard(snapshot, { includeLogTail: snapshot.includeLogTail });
4172
- return formatOrchestrationCardBlock(
4173
- {
4174
- type: "tool-result",
4175
- round: 0,
4176
- toolCallId: `fold-${snapshot.runId}`,
4177
- toolName: "controlAgentRun",
4178
- content: "",
4179
- metadata: { displayData: body }
4180
- },
4181
- "controlAgentRun",
4182
- colorEnabled
4183
- );
4184
- }
4185
- function formatVerboseToolEvent(event, colorEnabled) {
4186
- const round = event.round + 1;
4187
- const detail = event.argumentsPreview ? ` ${event.argumentsPreview}` : "";
4188
- if (event.type === "tool-call") {
4189
- return formatToolTraceLine(`[nolo:tool] #${round} -> ${event.toolName}${detail}`, colorEnabled);
4190
- }
4191
- if (event.type === "tool-error") {
4192
- const elapsed2 = typeof event.elapsedMs === "number" ? ` ${event.elapsedMs}ms` : "";
4193
- return formatToolTraceLine(
4194
- `[nolo:tool] #${round} !! ${event.toolName}${elapsed2}: ${event.message ?? "failed"}`,
4195
- colorEnabled,
4196
- "error"
4197
- );
4198
- }
4199
- const elapsed = typeof event.elapsedMs === "number" ? ` ${event.elapsedMs}ms` : "";
4200
- if (event.type === "tool-result" && (event.toolName === "ask_user" || event.metadata?.uiAskChoice)) {
4201
- const block = formatUiAskChoiceBlock(event, colorEnabled);
4202
- if (block) return `${formatToolTraceLine(`[nolo:tool] #${round} <- ${event.toolName}${elapsed}`, colorEnabled)}${block}`;
4203
- }
4204
- const summary = event.summary ? ` ${event.summary}` : "";
4205
- return formatToolTraceLine(
4206
- `[nolo:tool] #${round} <- ${event.toolName}${elapsed}${summary}`,
4207
- colorEnabled
4208
- );
3701
+ var NORMAL_TOOL_GIST_MAX = 28;
3702
+ function gistClip(value, max = NORMAL_TOOL_GIST_MAX) {
3703
+ const oneLine = value.replace(/\s+/g, " ").trim();
3704
+ if (!oneLine) return "";
3705
+ return oneLine.length <= max ? oneLine : `${oneLine.slice(0, max - 1)}\u2026`;
3706
+ }
3707
+ function commandHeadGist(command) {
3708
+ const trimmed = command.replace(/\s+/g, " ").trim();
3709
+ if (!trimmed || /[|;&<>`$]/.test(trimmed)) return "";
3710
+ const tokens = trimmed.split(" ");
3711
+ if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(tokens[0])) return "";
3712
+ if (["cd", "pushd", "popd", "source", "."].includes(tokens[0])) return "";
3713
+ return gistClip(tokens.slice(0, 2).join(" "), 24);
3714
+ }
3715
+ function pathBasenameGist(path) {
3716
+ const segments = path.split(/[\\/]/).filter((segment) => segment.length > 0);
3717
+ const base = segments.pop();
3718
+ return base ? gistClip(base) : "";
3719
+ }
3720
+ function normalToolGist(event) {
3721
+ const metadata = event.metadata ?? {};
3722
+ const path = typeof metadata.path === "string" ? metadata.path : "";
3723
+ if (path) return pathBasenameGist(path);
3724
+ const command = typeof metadata.command === "string" ? metadata.command : "";
3725
+ if (command) return commandHeadGist(command);
3726
+ return "";
4209
3727
  }
4210
3728
  function formatNormalToolLine(event, pending, colorEnabled) {
4211
3729
  if (event.type === "tool-call") return "";
@@ -4235,150 +3753,8 @@ function formatNormalToolLine(event, pending, colorEnabled) {
4235
3753
  if (isFailedToolResult(event)) {
4236
3754
  return formatToolTraceLine(`\u25B8 ${label} \u2717 ${t("toolFailed")}`, colorEnabled, "error");
4237
3755
  }
4238
- return formatToolTraceLine(`\u25B8 ${label} \u2713`, colorEnabled);
4239
- }
4240
- function isReadToolName(name) {
4241
- if (!name) return false;
4242
- return name === "read" || name === "readFile" || name === "read_file" || name === "readWorkspaceFile";
4243
- }
4244
- function isSearchToolName(name) {
4245
- if (!name) return false;
4246
- return name === "grep" || name === "codeSearch" || name === "code_search" || name === "globFiles" || name === "glob_files" || name === "glob" || name === "searchWorkspace" || name === "search_workspace" || name === "search_all_spaces" || name === "search";
4247
- }
4248
- function isRunToolName(name) {
4249
- if (!name) return false;
4250
- return name === "execShell" || name === "runCommand" || name === "run_command" || name === "launchProcess";
4251
- }
4252
- function isFetchToolName(name) {
4253
- if (!name) return false;
4254
- return name === "fetchWebpage" || name === "fetch_webpage";
4255
- }
4256
- function isWebSearchToolName(name) {
4257
- if (!name) return false;
4258
- return name === "exa_search" || name === "exaSearch";
4259
- }
4260
- function isRunResultFoldable(event) {
4261
- return Boolean(event.metadata?.actionGate) === false;
4262
- }
4263
- function formatSearchTreeBlockForCli(items, colorEnabled) {
4264
- if (items.length === 0) return "";
4265
- const { count, lines } = formatSearchTreeLines(items);
4266
- const titleText = toolLabel("codeSearch");
4267
- if (!colorEnabled) {
4268
- const headerLine2 = `\u2022 ${titleText} (${count})
4269
- `;
4270
- const treeLines2 = lines.map((l) => ` ${l.connector}${l.queryText}`).join("\n");
4271
- return `${headerLine2}${treeLines2}
4272
- `;
4273
- }
4274
- const bullet = themeText("\u2022", "chrome", true);
4275
- const title = styleCliText(titleText, "bold", true);
4276
- const countText = themeText(`(${count})`, "muted", true);
4277
- const headerLine = `${bullet} ${title} ${countText}
4278
- `;
4279
- const treeLines = lines.map((l) => {
4280
- const connector = themeText(` ${l.connector}`, "chrome", true);
4281
- const queryText = themeText(l.queryText, "muted", true);
4282
- return `${connector}${queryText}`;
4283
- }).join("\n");
4284
- return `${headerLine}${treeLines}
4285
- `;
4286
- }
4287
- function formatReadTreeBlockForCli(items, colorEnabled) {
4288
- if (items.length === 0) return "";
4289
- const { count, lines } = formatReadTreeLines(items);
4290
- const titleText = toolLabel("readFile");
4291
- if (!colorEnabled) {
4292
- const headerLine2 = `\u2022 ${titleText} (${count})
4293
- `;
4294
- const treeLines2 = lines.map((l) => ` ${l.connector}${l.pathWithRange}`).join("\n");
4295
- return `${headerLine2}${treeLines2}
4296
- `;
4297
- }
4298
- const bullet = themeText("\u2022", "chrome", true);
4299
- const title = styleCliText(titleText, "bold", true);
4300
- const countText = themeText(`(${count})`, "muted", true);
4301
- const headerLine = `${bullet} ${title} ${countText}
4302
- `;
4303
- const treeLines = lines.map((l) => {
4304
- const connector = themeText(` ${l.connector}`, "chrome", true);
4305
- const pathText = themeText(l.pathWithRange, "muted", true);
4306
- return `${connector}${pathText}`;
4307
- }).join("\n");
4308
- return `${headerLine}${treeLines}
4309
- `;
4310
- }
4311
- function formatRunTreeBlockForCli(items, colorEnabled) {
4312
- if (items.length === 0) return "";
4313
- const { count, lines } = formatRunTreeLines(items);
4314
- const titleText = toolLabel("execShell");
4315
- if (!colorEnabled) {
4316
- const headerLine2 = `\u2022 ${titleText} (${count})
4317
- `;
4318
- const treeLines2 = lines.map((l) => ` ${l.connector}${l.commandText}`).join("\n");
4319
- return `${headerLine2}${treeLines2}
4320
- `;
4321
- }
4322
- const bullet = themeText("\u2022", "chrome", true);
4323
- const title = styleCliText(titleText, "bold", true);
4324
- const countText = themeText(`(${count})`, "muted", true);
4325
- const headerLine = `${bullet} ${title} ${countText}
4326
- `;
4327
- const treeLines = lines.map((l) => {
4328
- const connector = themeText(` ${l.connector}`, "chrome", true);
4329
- const commandText = themeText(l.commandText, "muted", true);
4330
- return `${connector}${commandText}`;
4331
- }).join("\n");
4332
- return `${headerLine}${treeLines}
4333
- `;
4334
- }
4335
- function formatWebSearchTreeBlockForCli(items, colorEnabled) {
4336
- if (items.length === 0) return "";
4337
- const { count, lines } = formatSearchTreeLines(items);
4338
- const titleText = toolLabel("exa_search");
4339
- if (!colorEnabled) {
4340
- const headerLine2 = `\u2022 ${titleText} (${count})
4341
- `;
4342
- const treeLines2 = lines.map((l) => ` ${l.connector}${l.queryText}`).join("\n");
4343
- return `${headerLine2}${treeLines2}
4344
- `;
4345
- }
4346
- const bullet = themeText("\u2022", "chrome", true);
4347
- const title = styleCliText(titleText, "bold", true);
4348
- const countText = themeText(`(${count})`, "muted", true);
4349
- const headerLine = `${bullet} ${title} ${countText}
4350
- `;
4351
- const treeLines = lines.map((l) => {
4352
- const connector = themeText(` ${l.connector}`, "chrome", true);
4353
- const queryText = themeText(l.queryText, "muted", true);
4354
- return `${connector}${queryText}`;
4355
- }).join("\n");
4356
- return `${headerLine}${treeLines}
4357
- `;
4358
- }
4359
- function formatFetchTreeBlockForCli(items, colorEnabled) {
4360
- if (items.length === 0) return "";
4361
- const { count, lines } = formatFetchTreeLines(items);
4362
- const titleText = toolLabel("fetchWebpage");
4363
- if (!colorEnabled) {
4364
- const headerLine2 = `\u2022 ${titleText} (${count})
4365
- `;
4366
- const treeLines2 = lines.map((l) => ` ${l.connector}${l.urlText}`).join("\n");
4367
- return `${headerLine2}${treeLines2}
4368
- `;
4369
- }
4370
- const bullet = themeText("\u2022", "chrome", true);
4371
- const title = styleCliText(titleText, "bold", true);
4372
- const countText = themeText(`(${count})`, "muted", true);
4373
- const headerLine = `${bullet} ${title} ${countText}
4374
- `;
4375
- const treeLines = lines.map((l) => {
4376
- const connector = themeText(` ${l.connector}`, "chrome", true);
4377
- const urlText = themeText(l.urlText, "muted", true);
4378
- return `${connector}${urlText}`;
4379
- }).join("\n");
4380
- return `${headerLine}${treeLines}
4381
- `;
3756
+ const gist = normalToolGist(event);
3757
+ return formatToolTraceLine(gist ? `\u25B8 ${label} \xB7 ${gist} \u2713` : `\u25B8 ${label} \u2713`, colorEnabled);
4382
3758
  }
4383
3759
  function resolveLoadSkillName(event) {
4384
3760
  const metaName = typeof event.metadata?.name === "string" ? event.metadata.name : void 0;
@@ -4443,326 +3819,63 @@ function formatLoadSkillBlock(event, colorEnabled, opts) {
4443
3819
  return `${star} ${labelPart}: ${namePart}
4444
3820
  `;
4445
3821
  }
4446
- function formatCompactToolLine(event, pending, colorEnabled) {
4447
- const toolName = event.toolName || pending?.toolName || "tool";
4448
- const todoBlock = formatTodoListForCli(event, colorEnabled);
4449
- if (todoBlock) return todoBlock;
4450
- if (isReadToolName(toolName) && event.type === "tool-result") {
4451
- const rawPath = (typeof event.metadata?.path === "string" ? event.metadata.path : void 0) || (typeof event.metadata?.filePath === "string" ? event.metadata.filePath : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
4452
- return formatReadTreeBlockForCli([{ path: rawPath, metadata: event.metadata }], colorEnabled);
4453
- }
4454
- if (isSearchToolName(toolName) && event.type === "tool-result") {
4455
- const rawQuery = (typeof event.metadata?.query === "string" ? event.metadata.query : void 0) || (typeof event.metadata?.pattern === "string" ? event.metadata.pattern : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
4456
- const rawPath = typeof event.metadata?.path === "string" ? event.metadata.path : void 0;
4457
- return formatSearchTreeBlockForCli([{ query: rawQuery, path: rawPath }], colorEnabled);
4458
- }
4459
- if (isFetchToolName(toolName) && event.type === "tool-result") {
4460
- const rawUrl = (typeof event.metadata?.url === "string" ? event.metadata.url : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
4461
- return formatFetchTreeBlockForCli([{ url: rawUrl }], colorEnabled);
4462
- }
4463
- if (isRunToolName(toolName) && event.type === "tool-result" && isRunResultFoldable(event)) {
4464
- const rawCommand = (typeof event.metadata?.command === "string" ? event.metadata.command : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
4465
- const exitCode = typeof event.metadata?.exitCode === "number" ? event.metadata.exitCode : void 0;
4466
- const timedOut = Boolean(event.metadata?.timedOut);
4467
- return formatRunTreeBlockForCli([{ command: rawCommand, exitCode, timedOut }], colorEnabled);
4468
- }
4469
- const rawArgs = clipPathAware(event.argumentsPreview || pending?.argumentsPreview || "", 72);
4470
- const rawLabel = toolLabel(toolName);
4471
- const label = rawArgs ? `${rawLabel} ${rawArgs}` : rawLabel;
4472
- if (event.type === "tool-error") {
4473
- const message = clip(event.message ?? t("toolFailed"), 96);
4474
- return formatToolTraceLine(`\u25B8 ${label} \u2717 ${message}`, colorEnabled, "error");
4475
- }
4476
- const loadSkillBlock = formatLoadSkillBlock(event, colorEnabled);
4477
- if (loadSkillBlock) return loadSkillBlock;
4478
- if (event.type === "tool-result" && (toolName === "listAgents" || toolName === "startAgentRun" || toolName === "controlAgentRun")) {
4479
- return formatOrchestrationCardBlock(event, toolName, colorEnabled);
4480
- }
4481
- if (event.type === "tool-result" && (event.toolName === "ask_user" || event.metadata?.uiAskChoice)) {
4482
- const block = formatUiAskChoiceBlock(event, colorEnabled);
4483
- if (block) return block;
4484
- }
4485
- const hint = compactResultHint(event);
4486
- const suffix = hint.inline ? ` ${hint.inline}` : "";
4487
- const failed = isFailedToolResult(event);
4488
- const marker = failed ? "\u2717" : isNeedsActionToolResult(event) ? "!" : "\u2713";
4489
- let mainLine;
4490
- if (!colorEnabled) {
4491
- mainLine = `\u25B8 ${label} ${marker}${suffix}
4492
- `;
4493
- } else {
4494
- const chromePointer = themeText("\u25B8", "chrome", true);
4495
- const mutedLabel = themeText(rawLabel, "muted", true);
4496
- const argsPart = rawArgs ? ` ${dimCliText(rawArgs, true)}` : "";
4497
- const statusToken = failed ? themeText("\u2717", "danger", true) : isNeedsActionToolResult(event) ? themeText("!", "warning", true) : themeText("\u2713", "success", true);
4498
- const suffixPart = hint.inline ? ` ${dimCliText(hint.inline, true)}` : "";
4499
- mainLine = `${chromePointer} ${mutedLabel}${argsPart} ${statusToken}${suffixPart}
4500
- `;
4501
- }
4502
- if (!hint.detail?.length) return mainLine;
4503
- const filePath = typeof event.metadata?.path === "string" ? event.metadata.path : event.argumentsPreview;
4504
- return `${mainLine}${formatEditDetailBlock(hint.detail, colorEnabled, filePath)}`;
4505
- }
4506
- function formatEditDetailBlock(lines, colorEnabled, filePath, env = process.env) {
4507
- if (!colorEnabled) {
4508
- return lines.map((line) => ` ${line.text}
4509
- `).join("");
4510
- }
4511
- const isTruecolor = supportsTruecolor(env);
4512
- const lang = isTruecolor ? detectCodeLangFromPath(filePath) : "unknown";
4513
- const brightness = resolveTuiBrightness(env);
4514
- const padTo = Math.max(...lines.map((line) => displayWidth(line.text))) + 1;
4515
- return lines.map((line) => ` ${renderDiffLine({
4516
- kind: line.kind,
4517
- text: line.text,
4518
- highlightedText: shouldHighlightEditLine(line, lang, isTruecolor) ? buildHighlightedEditLine(line, lang, brightness, env) : void 0,
4519
- padTo,
4520
- colorEnabled: true,
4521
- env
4522
- })}
4523
- `).join("");
4524
- }
4525
- function shouldHighlightEditLine(line, lang, isTruecolor) {
4526
- if (!isTruecolor || lang === "unknown") return false;
4527
- if (line.text.startsWith(" \u2026") || line.text.startsWith("\u2026")) return false;
4528
- return line.text.length >= 2;
4529
- }
4530
- function buildHighlightedEditLine(line, lang, brightness, env) {
4531
- const prefix = line.text.slice(0, 2);
4532
- const body = line.text.slice(2);
4533
- const prefixToken = line.kind === "added" ? "success" : line.kind === "removed" ? "danger" : "chrome";
4534
- const coloredPrefix = themeText(prefix, prefixToken, true, env);
4535
- const highlightedBody = highlightCodeLine(body, lang, brightness);
4536
- return `${coloredPrefix}${highlightedBody}`;
4537
- }
4538
- function createToolEventFormatter(mode, colorEnabled = resolveCliColorEnabled(), opts = {}) {
4539
- const suppressRunProgressCards = opts.suppressRunProgressCards === true;
3822
+ var TUI_TREE_MARKER = "TUI_TREE\n";
3823
+ var TUI_TREE_END = "";
3824
+ function createToolEventFormatter(colorEnabled = resolveCliColorEnabled(), opts = {}) {
4540
3825
  const pending = /* @__PURE__ */ new Map();
4541
- let readBuffer = [];
4542
- let searchBuffer = [];
4543
- let runBuffer = [];
4544
- let fetchBuffer = [];
4545
- let webSearchBuffer = [];
4546
- let statusFold = null;
4547
- const lastEmittedLogByRunId = /* @__PURE__ */ new Map();
4548
- const lastPrintedCardByRunId = /* @__PURE__ */ new Map();
4549
- const cardSubstance = (snapshot) => JSON.stringify([
4550
- snapshot.status,
4551
- snapshot.toolCallCount ?? -1,
4552
- snapshot.lastToolNames ?? [],
4553
- snapshot.lastAssistantText ?? "",
4554
- snapshot.errorMessage ?? "",
4555
- snapshot.logKey
4556
- ]);
4557
- const flushStatusFold = () => {
4558
- if (!statusFold) return "";
4559
- const fold = statusFold;
4560
- statusFold = null;
4561
- const substance = cardSubstance(fold);
4562
- if (lastPrintedCardByRunId.get(fold.runId) === substance) return "";
4563
- const prevLog = lastEmittedLogByRunId.get(fold.runId);
4564
- const changed = Boolean(fold.logKey) && fold.logKey !== prevLog;
4565
- if (suppressRunProgressCards) {
4566
- const terminal = isAgentRunTerminalStatus(fold.status);
4567
- if (!terminal && !fold.errorMessage && !changed) {
4568
- lastPrintedCardByRunId.set(fold.runId, substance);
4569
- return "";
4570
- }
4571
- }
4572
- lastPrintedCardByRunId.set(fold.runId, substance);
4573
- if (changed && runShowsLogTail(fold.status)) {
4574
- lastEmittedLogByRunId.set(fold.runId, fold.logKey);
4575
- }
4576
- return formatFoldedControlStatusCard({ ...fold, includeLogTail: changed }, colorEnabled);
4577
- };
4578
- const flushToolBuffers = () => {
4579
- let out = "";
4580
- if (readBuffer.length > 0) {
4581
- const items = readBuffer.map((evt) => {
4582
- const call = pending.get(evt.toolCallId);
4583
- const rawPath = (typeof evt.metadata?.path === "string" ? evt.metadata.path : void 0) || (typeof evt.metadata?.filePath === "string" ? evt.metadata.filePath : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
4584
- return { path: rawPath, metadata: evt.metadata };
4585
- });
4586
- for (const evt of readBuffer) pending.delete(evt.toolCallId);
4587
- readBuffer = [];
4588
- out += formatReadTreeBlockForCli(items, colorEnabled);
4589
- }
4590
- if (searchBuffer.length > 0) {
4591
- const items = searchBuffer.map((evt) => {
4592
- const call = pending.get(evt.toolCallId);
4593
- const rawQuery = (typeof evt.metadata?.query === "string" ? evt.metadata.query : void 0) || (typeof evt.metadata?.pattern === "string" ? evt.metadata.pattern : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
4594
- const rawPath = typeof evt.metadata?.path === "string" ? evt.metadata.path : void 0;
4595
- return { query: rawQuery, path: rawPath };
4596
- });
4597
- for (const evt of searchBuffer) pending.delete(evt.toolCallId);
4598
- searchBuffer = [];
4599
- out += formatSearchTreeBlockForCli(items, colorEnabled);
4600
- }
4601
- if (runBuffer.length > 0) {
4602
- const items = runBuffer.map((evt) => {
4603
- const call = pending.get(evt.toolCallId);
4604
- const rawCommand = (typeof evt.metadata?.command === "string" ? evt.metadata.command : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
4605
- const exitCode = typeof evt.metadata?.exitCode === "number" ? evt.metadata.exitCode : void 0;
4606
- const timedOut = Boolean(evt.metadata?.timedOut);
4607
- return { command: rawCommand, exitCode, timedOut };
4608
- });
4609
- for (const evt of runBuffer) pending.delete(evt.toolCallId);
4610
- runBuffer = [];
4611
- out += formatRunTreeBlockForCli(items, colorEnabled);
4612
- }
4613
- if (fetchBuffer.length > 0) {
4614
- const items = fetchBuffer.map((evt) => {
4615
- const call = pending.get(evt.toolCallId);
4616
- const rawUrl = (typeof evt.metadata?.url === "string" ? evt.metadata.url : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
4617
- return { url: rawUrl };
4618
- });
4619
- for (const evt of fetchBuffer) pending.delete(evt.toolCallId);
4620
- fetchBuffer = [];
4621
- out += formatFetchTreeBlockForCli(items, colorEnabled);
4622
- }
4623
- if (webSearchBuffer.length > 0) {
4624
- const items = webSearchBuffer.map((evt) => {
4625
- const call = pending.get(evt.toolCallId);
4626
- const rawQuery = (typeof evt.metadata?.query === "string" ? evt.metadata.query : void 0) || (typeof evt.metadata?.pattern === "string" ? evt.metadata.pattern : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
4627
- return { query: rawQuery };
4628
- });
4629
- for (const evt of webSearchBuffer) pending.delete(evt.toolCallId);
4630
- webSearchBuffer = [];
4631
- out += formatWebSearchTreeBlockForCli(items, colorEnabled);
4632
- }
4633
- return out;
4634
- };
4635
- const flushBuffers = () => `${flushStatusFold()}${flushToolBuffers()}`;
4636
- const bufferToolResult = (buffer, event) => {
4637
- const flushed = flushStatusFold();
4638
- buffer.push(event);
4639
- return flushed;
3826
+ let tree = null;
3827
+ const treeKind = (name) => isRunToolName(name) ? "Run" : isReadToolName(name) ? "Read" : name === "exa_search" ? "Search" : name === "fetchWebpage" ? "Fetch" : null;
3828
+ const treeLine = (kind, items) => {
3829
+ const label = kind === "Run" ? toolLabel("execShell") : kind === "Read" ? toolLabel("readFile") : kind === "Fetch" ? toolLabel("fetchWebpage") : toolLabel("exa_search");
3830
+ return `${TUI_TREE_MARKER}${label} (${items.length})
3831
+ ${items.map((item, i) => `${i === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 "}${item} \u2713`).join("\n")}${TUI_TREE_END}
3832
+ `;
4640
3833
  };
4641
- const formatter = (event) => {
4642
- if (mode === "hide") return "";
4643
- if (mode === "verbose") return formatVerboseToolEvent(event, colorEnabled);
4644
- if (mode === "normal") {
4645
- if (event.type === "tool-call") {
4646
- pending.set(event.toolCallId, {
4647
- toolName: event.toolName,
4648
- argumentsPreview: event.argumentsPreview
4649
- });
4650
- return "";
4651
- }
4652
- const call2 = pending.get(event.toolCallId);
4653
- pending.delete(event.toolCallId);
4654
- return formatNormalToolLine(event, call2, colorEnabled);
4655
- }
4656
- if (event.toolName === "controlAgentRun") {
4657
- if (event.type === "tool-call") {
4658
- pending.set(event.toolCallId, {
4659
- toolName: event.toolName,
4660
- argumentsPreview: event.argumentsPreview
4661
- });
4662
- return "";
4663
- }
4664
- if (event.type === "tool-result") {
4665
- const snapshot = parseControlAgentRunStatusEvent(event);
4666
- if (snapshot) {
4667
- let out = flushToolBuffers();
4668
- const open = statusFold;
4669
- const sameRun = open?.runId === snapshot.runId;
4670
- if (open && (!sameRun || open.status !== snapshot.status)) {
4671
- out += flushStatusFold();
4672
- }
4673
- statusFold = open && sameRun ? mergeRunSnapshot(open, snapshot) : snapshot;
4674
- pending.delete(event.toolCallId);
4675
- if (isAgentRunTerminalStatus(snapshot.status)) {
4676
- out += flushBuffers();
4677
- }
4678
- return out;
4679
- }
4680
- const flushed2 = flushBuffers();
4681
- const call2 = pending.get(event.toolCallId);
4682
- pending.delete(event.toolCallId);
4683
- return `${flushed2}${formatCompactToolLine(event, call2, colorEnabled)}`;
4684
- }
4685
- }
4686
- if (isReadToolName(event.toolName)) {
4687
- if (event.type === "tool-call") {
4688
- pending.set(event.toolCallId, {
4689
- toolName: event.toolName,
4690
- argumentsPreview: event.argumentsPreview
4691
- });
4692
- return "";
4693
- }
4694
- if (event.type === "tool-result") {
4695
- return bufferToolResult(readBuffer, event);
4696
- }
4697
- }
4698
- if (isSearchToolName(event.toolName)) {
4699
- if (event.type === "tool-call") {
4700
- pending.set(event.toolCallId, {
4701
- toolName: event.toolName,
4702
- argumentsPreview: event.argumentsPreview
4703
- });
4704
- return "";
4705
- }
4706
- if (event.type === "tool-result") {
4707
- return bufferToolResult(searchBuffer, event);
4708
- }
4709
- }
4710
- if (isRunToolName(event.toolName)) {
4711
- if (event.type === "tool-result" && !isRunResultFoldable(event)) {
4712
- const flushed2 = flushBuffers();
4713
- const call2 = pending.get(event.toolCallId);
4714
- pending.delete(event.toolCallId);
4715
- return `${flushed2}${formatCompactToolLine(event, call2, colorEnabled)}`;
4716
- }
4717
- if (event.type === "tool-call") {
4718
- pending.set(event.toolCallId, {
4719
- toolName: event.toolName,
4720
- argumentsPreview: event.argumentsPreview
4721
- });
4722
- return "";
4723
- }
4724
- if (event.type === "tool-result") {
4725
- return bufferToolResult(runBuffer, event);
4726
- }
4727
- }
4728
- if (isFetchToolName(event.toolName)) {
4729
- if (event.type === "tool-call") {
4730
- pending.set(event.toolCallId, {
4731
- toolName: event.toolName,
4732
- argumentsPreview: event.argumentsPreview
4733
- });
4734
- return "";
4735
- }
4736
- if (event.type === "tool-result") {
4737
- return bufferToolResult(fetchBuffer, event);
4738
- }
3834
+ const formatTreeEvent = (event, call) => {
3835
+ if (!opts.tuiTrees || event.type !== "tool-result") return null;
3836
+ if (isFailedToolResult(event) || event.metadata?.failed || event.metadata?.timedOut || readActionGate(event.metadata?.actionGate)) {
3837
+ tree = null;
3838
+ return null;
4739
3839
  }
4740
- if (isWebSearchToolName(event.toolName)) {
4741
- if (event.type === "tool-call") {
4742
- pending.set(event.toolCallId, {
4743
- toolName: event.toolName,
4744
- argumentsPreview: event.argumentsPreview
4745
- });
4746
- return "";
4747
- }
4748
- if (event.type === "tool-result") {
4749
- return bufferToolResult(webSearchBuffer, event);
4750
- }
3840
+ const name = event.toolName || call?.toolName || "tool";
3841
+ const kind = treeKind(name);
3842
+ if (!kind) {
3843
+ tree = null;
3844
+ return null;
4751
3845
  }
4752
- const flushed = flushBuffers();
3846
+ let item = "";
3847
+ const m = event.metadata ?? {};
3848
+ if (kind === "Run") {
3849
+ const command = typeof m.command === "string" ? m.command : "";
3850
+ item = command ? formatRunItemCommand(command, typeof m.exitCode === "number" ? m.exitCode : void 0, Boolean(m.timedOut)) : "command";
3851
+ }
3852
+ if (kind === "Read") item = formatReadItemPath(typeof m.path === "string" ? m.path : typeof m.filePath === "string" ? m.filePath : "file", m);
3853
+ if (kind === "Search") item = formatSearchItemQuery(typeof m.query === "string" ? m.query : typeof m.pattern === "string" ? m.pattern : "search", typeof m.path === "string" ? m.path : void 0);
3854
+ if (kind === "Fetch") item = formatFetchItemUrl(typeof m.url === "string" ? m.url : "webpage");
3855
+ if (!item) item = toolLabel(name);
3856
+ if (tree?.kind !== kind) tree = { kind, items: [] };
3857
+ tree.items.push(item);
3858
+ if (tree.items.length < 2) return formatNormalToolLine(event, call, colorEnabled);
3859
+ return treeLine(kind, tree.items);
3860
+ };
3861
+ const format = (event) => {
4753
3862
  if (event.type === "tool-call") {
4754
3863
  pending.set(event.toolCallId, {
4755
3864
  toolName: event.toolName,
4756
3865
  argumentsPreview: event.argumentsPreview
4757
3866
  });
4758
- return flushed;
3867
+ return "";
4759
3868
  }
4760
3869
  const call = pending.get(event.toolCallId);
4761
3870
  pending.delete(event.toolCallId);
4762
- return `${flushed}${formatCompactToolLine(event, call, colorEnabled)}`;
3871
+ const treeOutput = formatTreeEvent(event, call);
3872
+ if (treeOutput !== null) return treeOutput;
3873
+ return formatNormalToolLine(event, call, colorEnabled);
4763
3874
  };
4764
- formatter.flush = flushBuffers;
4765
- return formatter;
3875
+ format.reset = () => {
3876
+ tree = null;
3877
+ };
3878
+ return format;
4766
3879
  }
4767
3880
  function createSseToolEventAdapter(onEvent) {
4768
3881
  let round = 0;
@@ -4923,7 +4036,7 @@ ${this.text}
4923
4036
  0,
4924
4037
  Math.floor((Date.now() - this.startTime) / 1e3)
4925
4038
  );
4926
- const thinkingPart = this.thinkingHint ? `: ${truncateThinkingHint(this.thinkingHint, 60)}` : "";
4039
+ const thinkingPart = this.thinkingHint ? dimCliText(`: ${truncateThinkingHint(this.thinkingHint, 60)}`) : "";
4927
4040
  return `${themeColorSequence("accent")}${frame}\x1B[39m ${this.text}${thinkingPart} (${formatElapsed(elapsedSeconds)})`;
4928
4041
  }
4929
4042
  };
@@ -4980,10 +4093,8 @@ function createCliTurnOutput(params) {
4980
4093
  const { options } = params;
4981
4094
  const workingLabel = params.workingLabel ?? `${options.agentName} -> working`;
4982
4095
  const spinner = params.spinner ?? new Spinner(options.output, workingLabel, Boolean(options.activityReporter));
4983
- const toolDisplayMode = resolveToolDisplayMode(options.env);
4984
- const traceLocalTools = shouldEmitToolEvents(toolDisplayMode);
4985
- const formatToolEvent = createToolEventFormatter(toolDisplayMode, void 0, {
4986
- suppressRunProgressCards: typeof options.onAgentRunStatus === "function"
4096
+ const formatToolEvent = createToolEventFormatter(void 0, {
4097
+ tuiTrees: options.output.tuiTrees === true
4987
4098
  });
4988
4099
  const eventMode = resolveAgentEventMode(options);
4989
4100
  const showThinking = options.showThinking !== false;
@@ -4991,12 +4102,27 @@ function createCliTurnOutput(params) {
4991
4102
  let everStreamedAnyText = false;
4992
4103
  let printedAssistantLabel = false;
4993
4104
  let thinkState = createThinkParserState();
4105
+ let thinkingFirstAt = null;
4106
+ let thinkingLastAt = 0;
4107
+ const markThinkingActivity = () => {
4108
+ const now = Date.now();
4109
+ if (thinkingFirstAt === null) thinkingFirstAt = now;
4110
+ thinkingLastAt = now;
4111
+ };
4112
+ const writeThinkingTrace = () => {
4113
+ if (thinkingFirstAt === null) return;
4114
+ const seconds = Math.max(0, Math.round((thinkingLastAt - thinkingFirstAt) / 1e3));
4115
+ thinkingFirstAt = null;
4116
+ if (seconds < 1) return;
4117
+ options.output.write(`${dimCliText(t("thinkingTraceLine", formatElapsed(seconds)))}
4118
+ `);
4119
+ };
4994
4120
  let compactionEvent = null;
4995
4121
  const assistantLabelManaged = options.output.assistantLabelManaged === true;
4996
4122
  const writeToolOutput = (chunk) => {
4997
4123
  if (!chunk) return;
4998
4124
  if (typeof options.output.writeToolBlock === "function") {
4999
- options.output.writeToolBlock(chunk);
4125
+ if (!options.output.writeToolBlock(chunk)) formatToolEvent.reset?.();
5000
4126
  } else {
5001
4127
  options.output.write(chunk);
5002
4128
  }
@@ -5006,13 +4132,16 @@ function createCliTurnOutput(params) {
5006
4132
  });
5007
4133
  const writeVisibleAssistantChunk = (chunk) => {
5008
4134
  if (!chunk) return;
4135
+ formatToolEvent.reset?.();
5009
4136
  const parsed = processThinkChunk(chunk, thinkState);
5010
4137
  thinkState = parsed.state;
5011
4138
  if (!parsed.content && !parsed.reasoning) return;
5012
4139
  if (showThinking && parsed.reasoning) {
4140
+ markThinkingActivity();
5013
4141
  spinner.setThinkingHint(parsed.reasoning);
5014
4142
  }
5015
4143
  if (!parsed.content) return;
4144
+ writeThinkingTrace();
5016
4145
  spinner.stop();
5017
4146
  options.activityReporter?.(null);
5018
4147
  if (!printedAssistantLabel) {
@@ -5027,7 +4156,6 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
5027
4156
  renderWriter.push(parsed.content);
5028
4157
  };
5029
4158
  const handleToolEvent = (event) => {
5030
- if (!traceLocalTools) return;
5031
4159
  const chunk = eventMode === "jsonl" ? formatToolJsonEvent(event) : formatToolEvent(event);
5032
4160
  if (eventMode === "jsonl") {
5033
4161
  options.output.write(chunk);
@@ -5045,8 +4173,8 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
5045
4173
  if (chunk) {
5046
4174
  writeToolOutput(chunk);
5047
4175
  }
5048
- if ((toolDisplayMode === "compact" || toolDisplayMode === "pro" || toolDisplayMode === "normal") && event.type === "tool-call") {
5049
- const activeLabel = toolDisplayMode === "normal" ? formatConservativeActiveToolLabel(event) : formatActiveToolLabel(event);
4176
+ if (event.type === "tool-call") {
4177
+ const activeLabel = formatConservativeActiveToolLabel(event);
5050
4178
  spinner.show(activeLabel);
5051
4179
  options.activityReporter?.(activeLabel);
5052
4180
  }
@@ -5059,20 +4187,15 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
5059
4187
  };
5060
4188
  return {
5061
4189
  spinner,
5062
- toolDisplayMode,
5063
- traceLocalTools,
5064
4190
  eventMode,
5065
4191
  pushText(chunk) {
5066
- if (eventMode !== "jsonl" && formatToolEvent.flush) {
5067
- const pendingToolOutput = formatToolEvent.flush();
5068
- if (pendingToolOutput) {
5069
- writeToolOutput(pendingToolOutput);
5070
- }
5071
- }
5072
4192
  writeVisibleAssistantChunk(chunk);
5073
4193
  },
5074
4194
  pushThinking(chunk) {
5075
- if (showThinking) spinner.setThinkingHint(chunk);
4195
+ if (showThinking) {
4196
+ markThinkingActivity();
4197
+ spinner.setThinkingHint(chunk);
4198
+ }
5076
4199
  },
5077
4200
  handleToolEvent,
5078
4201
  /** 记录一条 compaction 观测事件(TUI 在 turn 结束时渲染一行 dim 摘要)。 */
@@ -5087,15 +4210,12 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
5087
4210
  finish(fallbackContent) {
5088
4211
  spinner.stop();
5089
4212
  options.activityReporter?.(null);
4213
+ writeThinkingTrace();
5090
4214
  const flushedThink = flushThinkParser(thinkState);
5091
4215
  thinkState = flushedThink.state;
5092
4216
  if (flushedThink.content) {
5093
4217
  writeVisibleAssistantChunk(flushedThink.content);
5094
4218
  }
5095
- const pendingToolOutput = formatToolEvent.flush ? formatToolEvent.flush() : "";
5096
- if (pendingToolOutput) {
5097
- writeToolOutput(pendingToolOutput);
5098
- }
5099
4219
  if (streamedAssistantText) {
5100
4220
  renderWriter.flush();
5101
4221
  options.output.write("\n");
@@ -5307,6 +4427,10 @@ ${describeClientVersionTooOldFailure(message, error)}`);
5307
4427
  function resolveAuthToken2(env) {
5308
4428
  return resolvePlatformAuthToken(env);
5309
4429
  }
4430
+ function resolveFileWriteGateEnabled(env) {
4431
+ const raw = (env.NOLO_CLI_WRITE_GATE ?? "").trim().toLowerCase();
4432
+ return raw !== "off" && raw !== "0" && raw !== "false";
4433
+ }
5310
4434
  function isMachineBoundLocalhostCustomProvider(agentConfig) {
5311
4435
  const machineId = agentConfig?.runtimeBinding && typeof agentConfig.runtimeBinding === "object" ? String(agentConfig.runtimeBinding.machineId ?? "").trim() : "";
5312
4436
  const providerUrl = asTrimmedString(agentConfig?.customProviderUrl);
@@ -5398,7 +4522,16 @@ function isKnownServerPlatformAgent(options) {
5398
4522
  // packages/core/collapsedPaste.ts
5399
4523
  var COLLAPSE_PASTE_MIN_LINES = 8;
5400
4524
  var COLLAPSE_PASTE_MIN_CHARS = 400;
5401
- var COLLAPSED_PASTE_PLACEHOLDER_RE = /\[paste #(\d+) · (\d+) lines\]/g;
4525
+ var COLLAPSED_PASTE_PLACEHOLDER_RE = (
4526
+ // 兼容两种格式:旧 `[paste #N · L lines]` 与新 `[paste #N · L lines · preview]`。
4527
+ // preview 段用负向先行断言排除模型引用(`…; full content available via
4528
+ // readPastedText(pasteId=N)`):legacy 无 scope 的模型引用与新 chip 形状重叠,
4529
+ // 若被当作 chip 匹配,跨会话残留的引用会被错误展开/替换(破坏 durable
4530
+ // fallback 语义)。preview 与模型引用尾段在生成时都不会包含该标记原文之外
4531
+ // 的歧义,此处按"完整模型引用尾段"精确排除。
4532
+ /\[paste #(\d+) · (\d+) lines(?: · (?![^\]]*; full content available via readPastedText\(pasteId=\d+\))([^\]]*))?\]/g
4533
+ );
4534
+ var COLLAPSED_PASTE_PREVIEW_MAX_CHARS = 24;
5402
4535
  var COLLAPSED_PASTE_MODEL_REFERENCE_RE = /\[paste #(\d+)(?: scope:([a-zA-Z0-9_-]+))? · [^\]]+; full content available via readPastedText\(pasteId=(\d+)\)\]/g;
5403
4536
  function countTextLines(text) {
5404
4537
  if (text.length === 0) return 0;
@@ -5438,9 +4571,22 @@ function estimatePasteBytes(text) {
5438
4571
  }
5439
4572
  return bytes;
5440
4573
  }
4574
+ function buildCollapsedPastePreview(text) {
4575
+ const firstNonEmptyLine = text.split(/\r\n|\r|\n/).find((line) => line.trim().length > 0) ?? "";
4576
+ let preview = compactWhitespace(firstNonEmptyLine);
4577
+ preview = preview.replace(new RegExp("\\]|\\p{C}", "gu"), "").trim();
4578
+ if (preview.length === 0) return "";
4579
+ const chars = Array.from(preview);
4580
+ if (chars.length > COLLAPSED_PASTE_PREVIEW_MAX_CHARS) {
4581
+ return chars.slice(0, COLLAPSED_PASTE_PREVIEW_MAX_CHARS).join("") + "\u2026";
4582
+ }
4583
+ return preview;
4584
+ }
5441
4585
  function formatCollapsedPastePlaceholder(id, text) {
5442
4586
  const lines = countTextLines(text);
5443
- return `[paste #${id} \xB7 ${lines} lines]`;
4587
+ const preview = buildCollapsedPastePreview(text);
4588
+ if (!preview) return `[paste #${id} \xB7 ${lines} lines]`;
4589
+ return `[paste #${id} \xB7 ${lines} lines \xB7 ${preview}]`;
5444
4590
  }
5445
4591
  function generatePasteScope() {
5446
4592
  if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
@@ -5553,7 +4699,7 @@ function findCollapsedPasteSpanAt(buffer, pos, opts = {}) {
5553
4699
  // packages/cli/client/agentRun.ts
5554
4700
  import { ulid } from "ulid";
5555
4701
  async function loadRunLocalAgentTurn() {
5556
- const { runLocalAgentTurn } = await import("./agentRuntimeLocal-A6EF3RUY.js");
4702
+ const { runLocalAgentTurn } = await import("./agentRuntimeLocal-SBG7BDFQ.js");
5557
4703
  return runLocalAgentTurn;
5558
4704
  }
5559
4705
  var stripDebugNoise = (s) => s.replace(/\s*raw="[\s\S]*"/g, "").replace(/\s*raw=\S+/g, "").replace(/\s*headers=\[[^\]]*\]/g, "").replace(/\s*headers=\S+/g, "").trim();
@@ -6179,6 +5325,7 @@ async function runLocalAgentTurnForCli(options, settings) {
6179
5325
  } : {},
6180
5326
  continueDialogId: currentDialogId,
6181
5327
  fileWriteSessionId: currentDialogId,
5328
+ fileWriteGateEnabled: resolveFileWriteGateEnabled(options.env),
6182
5329
  spaceId: options.spaceId,
6183
5330
  category: options.category,
6184
5331
  inheritedFromDialogKey: options.inheritedFromDialogKey,
@@ -6204,11 +5351,13 @@ async function runLocalAgentTurnForCli(options, settings) {
6204
5351
  options.onLoopEvent?.(event);
6205
5352
  },
6206
5353
  ...options.abortSignal ? { abortSignal: options.abortSignal } : {},
6207
- ...turnOutput.traceLocalTools ? {
6208
- onToolEvent: (event) => {
6209
- turnOutput.handleToolEvent(event);
6210
- }
6211
- } : {},
5354
+ // 回合内注入(TUI 后台 run 唤醒直投):透传给 local loop。
5355
+ ...options.drainInjections ? { drainInjections: options.drainInjections } : {},
5356
+ // tool-gist-fold 后 onToolEvent 无条件挂载(不再受 traceLocalTools 开关
5357
+ // 控制,显示模式合并为单一 gist/折叠通道)——保留 alpha 的新形态。
5358
+ onToolEvent: (event) => {
5359
+ turnOutput.handleToolEvent(event);
5360
+ },
6212
5361
  ...!options.noStream ? {
6213
5362
  onTextDelta: (chunk) => {
6214
5363
  turnOutput.pushText(chunk);
@@ -6266,6 +5415,43 @@ async function runLocalAgentTurnForCli(options, settings) {
6266
5415
  };
6267
5416
  }
6268
5417
  }
5418
+ async function checkLocalAvailabilityBeforeHttpDispatch(options) {
5419
+ const adapter = resolveLocalRuntimeAdapter(options);
5420
+ if (!adapter || typeof adapter.loadAgentConfig !== "function") return null;
5421
+ let config;
5422
+ try {
5423
+ config = await adapter.loadAgentConfig(options.agentKey);
5424
+ } catch {
5425
+ return null;
5426
+ }
5427
+ if (!config || typeof config !== "object") return null;
5428
+ const baseRecord = config.rawRecord ?? config;
5429
+ const credentialKey = resolveCredentialKeyWithFallback(baseRecord);
5430
+ const agentLevelAt = baseRecord.nextAvailableAt;
5431
+ const agentLevelNextAvailableAt = typeof agentLevelAt === "number" && Number.isFinite(agentLevelAt) ? agentLevelAt : void 0;
5432
+ if (!credentialKey && agentLevelNextAvailableAt === void 0) return null;
5433
+ const env = options.env;
5434
+ const now = Date.now();
5435
+ const entry = credentialKey ? await readCredentialEntry(credentialKey, env, now).catch(() => void 0) : void 0;
5436
+ const entryAt = entry?.nextAvailableAt;
5437
+ const effectiveNextAvailableAt = typeof entryAt === "number" ? mergeAvailabilityDeadline(agentLevelNextAvailableAt, entryAt) : agentLevelNextAvailableAt;
5438
+ if (typeof effectiveNextAvailableAt !== "number") return null;
5439
+ const gateDecision = resolveCooldownGate(
5440
+ { nextAvailableAt: effectiveNextAvailableAt, lastProbeAt: entry?.lastProbeAt },
5441
+ now
5442
+ );
5443
+ if (gateDecision === "probe" && credentialKey) {
5444
+ await recordCredentialProbe(credentialKey, env, now).catch(() => void 0);
5445
+ return null;
5446
+ }
5447
+ if (gateDecision !== "blocked") return null;
5448
+ options.output.write(
5449
+ `[nolo] Agent ${options.agentName || options.agentKey} is temporarily unavailable (429 cooldown) until ${new Date(Number(effectiveNextAvailableAt)).toISOString()}.
5450
+ Dispatch aborted before reaching the server. Pick another agent via listAgents, or retry after the cooldown.
5451
+ `
5452
+ );
5453
+ return { exitCode: 1 };
5454
+ }
6269
5455
  async function runAgentTurn(options) {
6270
5456
  const authToken = resolveAuthToken2(options.env);
6271
5457
  const runtimeMode = resolveRequestedRuntimeMode(options);
@@ -6330,26 +5516,50 @@ async function runAgentTurn(options) {
6330
5516
  );
6331
5517
  return { exitCode: 1 };
6332
5518
  }
5519
+ const localBlock = await checkLocalAvailabilityBeforeHttpDispatch(options);
5520
+ if (localBlock) {
5521
+ return { exitCode: localBlock.exitCode };
5522
+ }
6333
5523
  return runHttpAgentTurn(options, authToken);
6334
5524
  }
6335
5525
 
6336
5526
  // packages/cli/agentRunCommand.ts
6337
5527
  import * as nodeFs from "node:fs";
6338
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
6339
- import { join as join2 } from "node:path";
6340
5528
 
6341
5529
  // packages/cli/client/autoModelRouter.ts
6342
5530
  var CLI_AUTO_ROUTE_AGENT_KEY = BUILTIN_NOLO_AGENT_KEY;
6343
5531
 
5532
+ // packages/agent-runtime/agentsMd.ts
5533
+ import { existsSync, readFileSync } from "node:fs";
5534
+ import { join } from "node:path";
5535
+ var AGENTS_MD_MAX_BYTES = 8192;
5536
+ var AGENTS_MD_CANDIDATES = ["AGENTS.md", "CLAUDE.md"];
5537
+ function readAgentsMdLayerFromDisk(cwd) {
5538
+ for (const name of AGENTS_MD_CANDIDATES) {
5539
+ const filePath = join(cwd, name);
5540
+ if (!existsSync(filePath)) continue;
5541
+ try {
5542
+ let content = readFileSync(filePath, "utf8").trim();
5543
+ if (!content) continue;
5544
+ if (Buffer.byteLength(content, "utf8") > AGENTS_MD_MAX_BYTES) {
5545
+ content = Buffer.from(content, "utf8").subarray(0, AGENTS_MD_MAX_BYTES).toString("utf8") + "\n\n<!-- AGENTS.md truncated -->";
5546
+ }
5547
+ return buildAgentsMdLayer(content, name);
5548
+ } catch {
5549
+ }
5550
+ }
5551
+ return null;
5552
+ }
5553
+
6344
5554
  // packages/cli/agentRunPrompts.ts
6345
- import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
6346
- import { dirname, extname, isAbsolute, join, relative as relativePath, resolve, sep } from "node:path";
5555
+ import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync } from "node:fs";
5556
+ import { dirname, extname, isAbsolute, join as join2, relative as relativePath, resolve, sep } from "node:path";
6347
5557
  function workflowRefToCandidatePath(cwd, ref) {
6348
5558
  const normalized = ref.trim();
6349
5559
  if (!normalized) return "";
6350
5560
  if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
6351
5561
  const directPath = resolve(cwd, normalized);
6352
- if (existsSync(directPath)) return directPath;
5562
+ if (existsSync2(directPath)) return directPath;
6353
5563
  }
6354
5564
  const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
6355
5565
  return resolve(cwd, "docs", "workflows", `${fileName}.md`);
@@ -6362,21 +5572,21 @@ function skillRefToCandidatePath(cwd, ref) {
6362
5572
  if (!normalized) return "";
6363
5573
  if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
6364
5574
  const directPath = resolve(cwd, normalized);
6365
- if (existsSync(directPath)) return directPath;
5575
+ if (existsSync2(directPath)) return directPath;
6366
5576
  }
6367
5577
  const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
6368
5578
  for (const dir of SKILL_SEARCH_DIRS) {
6369
5579
  const skillMdPath = resolve(cwd, dir, fileName, "SKILL.md");
6370
- if (existsSync(skillMdPath)) return skillMdPath;
5580
+ if (existsSync2(skillMdPath)) return skillMdPath;
6371
5581
  }
6372
5582
  return resolve(cwd, ".agents", "skills", fileName, "SKILL.md");
6373
5583
  }
6374
5584
  async function resolveWorkflowReference(ref, cwd = process.cwd()) {
6375
5585
  const path = workflowRefToCandidatePath(cwd, ref);
6376
- if (!path || !existsSync(path)) {
5586
+ if (!path || !existsSync2(path)) {
6377
5587
  throw new Error(`Workflow reference not found: ${ref}`);
6378
5588
  }
6379
- const markdown = readFileSync(path, "utf8");
5589
+ const markdown = readFileSync2(path, "utf8");
6380
5590
  const parsed = parseSkillDocProtocol(markdown);
6381
5591
  return {
6382
5592
  ref,
@@ -6393,8 +5603,8 @@ function inlineRelativeRefs(body, skillDir) {
6393
5603
  const absPath = resolve(skillDir, cleaned);
6394
5604
  const relative = relativePath(normalizedSkillDir, absPath);
6395
5605
  if (relative.startsWith("..") || isAbsolute(relative)) return match;
6396
- if (!existsSync(absPath) || !absPath.endsWith(".md")) return match;
6397
- const refContent = readFileSync(absPath, "utf8");
5606
+ if (!existsSync2(absPath) || !absPath.endsWith(".md")) return match;
5607
+ const refContent = readFileSync2(absPath, "utf8");
6398
5608
  return `
6399
5609
 
6400
5610
  ### ${label}
@@ -6405,8 +5615,8 @@ ${refContent}
6405
5615
  });
6406
5616
  }
6407
5617
  function listSkillScripts(skillDir) {
6408
- const scriptsDir = join(skillDir, "scripts");
6409
- if (!existsSync(scriptsDir) || !statSync(scriptsDir).isDirectory()) return null;
5618
+ const scriptsDir = join2(skillDir, "scripts");
5619
+ if (!existsSync2(scriptsDir) || !statSync(scriptsDir).isDirectory()) return null;
6410
5620
  const entries = readdirSync(scriptsDir).filter((e) => !e.startsWith("."));
6411
5621
  if (entries.length === 0) return null;
6412
5622
  return [
@@ -6433,10 +5643,10 @@ async function resolveSkillReference(ref, options = {}) {
6433
5643
  } else {
6434
5644
  const cwd = options.cwd ?? process.cwd();
6435
5645
  const path = skillRefToCandidatePath(cwd, ref);
6436
- if (!path || !existsSync(path)) {
5646
+ if (!path || !existsSync2(path)) {
6437
5647
  throw new Error(`Skill reference not found: ${ref}`);
6438
5648
  }
6439
- markdown = readFileSync(path, "utf8");
5649
+ markdown = readFileSync2(path, "utf8");
6440
5650
  filePath = path;
6441
5651
  skillDir = dirname(path);
6442
5652
  }
@@ -6541,8 +5751,8 @@ function prependSubjectDialogMarker(message, subjectDialogKey) {
6541
5751
  function normalizeCliImageInput(input) {
6542
5752
  if (/^(https?:|data:|file:)/i.test(input)) return input;
6543
5753
  const absolutePath = resolve(input);
6544
- if (!existsSync(absolutePath)) return input;
6545
- const base64 = readFileSync(absolutePath).toString("base64");
5754
+ if (!existsSync2(absolutePath)) return input;
5755
+ const base64 = readFileSync2(absolutePath).toString("base64");
6546
5756
  return `data:${imageMimeTypeForPath(absolutePath)};base64,${base64}`;
6547
5757
  }
6548
5758
  function imageMimeTypeForPath(path) {
@@ -6735,16 +5945,16 @@ var buildCjkTokens = (text) => {
6735
5945
  }
6736
5946
  return tokens;
6737
5947
  };
6738
- var tokenize2 = (text) => {
5948
+ var tokenize = (text) => {
6739
5949
  const normalized = text.toLowerCase();
6740
5950
  const wordTokens = normalized.split(/[\s,.;:!?()[\]{}"'`,。!?:;、]+/).map((token) => token.trim()).filter((token) => token.length >= 2);
6741
5951
  return [...wordTokens, ...buildCjkTokens(normalized)];
6742
5952
  };
6743
5953
  var keywordScore = (query, item) => {
6744
- const queryTokens = new Set(tokenize2(query));
5954
+ const queryTokens = new Set(tokenize(query));
6745
5955
  if (queryTokens.size === 0) return 0;
6746
5956
  const haystack = /* @__PURE__ */ new Set([
6747
- ...tokenize2(item.content),
5957
+ ...tokenize(item.content),
6748
5958
  ...(item.tags ?? []).map((tag) => tag.toLowerCase()),
6749
5959
  item.patternKey?.toLowerCase() ?? ""
6750
5960
  ]);
@@ -7046,6 +6256,21 @@ var resolveCliMemory = async (input) => {
7046
6256
  function resolvePositiveMs(value, fallback) {
7047
6257
  return parsePositiveFiniteNumberOrFallback(value, fallback);
7048
6258
  }
6259
+ function resolveRunOutcome(input) {
6260
+ switch (input.kind) {
6261
+ case "stall":
6262
+ return { status: "failed", exitCode: 1 };
6263
+ case "timeout":
6264
+ return { status: "timeout", exitCode: 124 };
6265
+ case "result": {
6266
+ const failed = input.isStalledOrTruncated || input.exitCode !== 0;
6267
+ if (!failed) {
6268
+ return { status: "done", exitCode: 0 };
6269
+ }
6270
+ return { status: "failed", exitCode: input.exitCode !== 0 ? input.exitCode : 1 };
6271
+ }
6272
+ }
6273
+ }
7049
6274
  async function resolveAgentRunAgentKey(args) {
7050
6275
  if (!args.agentInput.trim() || args.agentInput.startsWith("agent-")) {
7051
6276
  return void 0;
@@ -7081,11 +6306,14 @@ async function runAgentRunCommand(args, deps) {
7081
6306
  deps.stallTimeoutMs ?? env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS,
7082
6307
  5 * 6e4
7083
6308
  );
6309
+ const stallEnvExplicitlySet = typeof env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS === "string" && env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS.trim().length > 0;
6310
+ const armStallWatchdog = hasRegistry || stallEnvExplicitlySet;
6311
+ const armTimeoutWatchdog = typeof parsed.timeoutMs === "number" && parsed.timeoutMs > 0;
7084
6312
  let timedOut = false;
7085
6313
  let stalled = false;
7086
6314
  let timeoutTimer;
7087
6315
  let stallTimer;
7088
- const activityTracker = hasRegistry ? createRunActivityTracker(childRunId, {
6316
+ const activityTracker = armStallWatchdog ? createRunActivityTracker(childRunId ?? "__foreground__", {
7089
6317
  env,
7090
6318
  homedir: deps.homedir,
7091
6319
  fs: deps.fs,
@@ -7098,7 +6326,7 @@ async function runAgentRunCommand(args, deps) {
7098
6326
  activityTracker?.dispose();
7099
6327
  };
7100
6328
  let rejectOnWatchdogFailure;
7101
- const watchdogFailure = hasRegistry ? new Promise((_, reject) => {
6329
+ const watchdogFailure = armStallWatchdog || armTimeoutWatchdog ? new Promise((_, reject) => {
7102
6330
  rejectOnWatchdogFailure = reject;
7103
6331
  }) : void 0;
7104
6332
  const raceWithWatchdog = (work) => watchdogFailure ? Promise.race([work, watchdogFailure]) : work;
@@ -7108,7 +6336,15 @@ async function runAgentRunCommand(args, deps) {
7108
6336
  } catch {
7109
6337
  }
7110
6338
  };
7111
- if (hasRegistry) {
6339
+ const finalizeWatchdogOutcome = (outcome, note) => {
6340
+ if (!hasRegistry) return;
6341
+ (deps.finalizeRunRecord ?? finalizeRunRecord)(
6342
+ childRunId,
6343
+ { status: outcome.status, exitCode: outcome.exitCode, note },
6344
+ { env, homedir: deps.homedir, fs: deps.fs, now: deps.now }
6345
+ );
6346
+ };
6347
+ if (armStallWatchdog) {
7112
6348
  stallTimer = setInterval(() => {
7113
6349
  if (timedOut || stalled) return;
7114
6350
  const activity = activityTracker?.getActivity();
@@ -7126,31 +6362,25 @@ async function runAgentRunCommand(args, deps) {
7126
6362
  const note = `stalled: no progress for ${stallTimeoutMs}ms`;
7127
6363
  output.write(`[nolo] local run ${note}
7128
6364
  `);
7129
- (deps.finalizeRunRecord ?? finalizeRunRecord)(
7130
- childRunId,
7131
- { status: "failed", note },
7132
- { env, homedir: deps.homedir, fs: deps.fs, now: deps.now }
7133
- );
6365
+ const outcome = resolveRunOutcome({ kind: "stall" });
6366
+ finalizeWatchdogOutcome(outcome, note);
7134
6367
  rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
7135
- exitFromWatchdog(1);
6368
+ exitFromWatchdog(outcome.exitCode);
7136
6369
  }
7137
6370
  }, Math.min(stallTimeoutMs, 1e4));
7138
- if (typeof parsed.timeoutMs === "number" && parsed.timeoutMs > 0) {
7139
- timeoutTimer = setTimeout(() => {
7140
- timedOut = true;
7141
- clearWatchdogs();
7142
- const note = `timed out after ${parsed.timeoutMs}ms`;
7143
- output.write(`[nolo] local run ${note}
6371
+ }
6372
+ if (armTimeoutWatchdog) {
6373
+ timeoutTimer = setTimeout(() => {
6374
+ timedOut = true;
6375
+ clearWatchdogs();
6376
+ const note = `timed out after ${parsed.timeoutMs}ms`;
6377
+ output.write(`[nolo] local run ${note}
7144
6378
  `);
7145
- (deps.finalizeRunRecord ?? finalizeRunRecord)(
7146
- childRunId,
7147
- { status: "timeout", note },
7148
- { env, homedir: deps.homedir, fs: deps.fs, now: deps.now }
7149
- );
7150
- rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
7151
- exitFromWatchdog(124);
7152
- }, parsed.timeoutMs);
7153
- }
6379
+ const outcome = resolveRunOutcome({ kind: "timeout" });
6380
+ finalizeWatchdogOutcome(outcome, note);
6381
+ rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
6382
+ exitFromWatchdog(outcome.exitCode);
6383
+ }, parsed.timeoutMs);
7154
6384
  }
7155
6385
  const wantsFallbackSuggestions = parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0;
7156
6386
  const rawAgentInput = resolveRawAgentInput(args, deps.commandPath) ?? parsed.agentKey;
@@ -7305,22 +6535,8 @@ async function runAgentRunCommand(args, deps) {
7305
6535
  let memoryOverlayLayer = null;
7306
6536
  let memoryUseGuidanceLayer = null;
7307
6537
  if (!isSubtask) {
7308
- const AGENTS_MD_MAX = 8192;
7309
- for (const name of ["AGENTS.md", "CLAUDE.md"]) {
7310
- const agentsMdPath = join2(cliCwd, name);
7311
- if (existsSync2(agentsMdPath)) {
7312
- try {
7313
- let mdContent = readFileSync2(agentsMdPath, "utf8").trim();
7314
- if (!mdContent) continue;
7315
- if (Buffer.byteLength(mdContent, "utf8") > AGENTS_MD_MAX) {
7316
- mdContent = Buffer.from(mdContent, "utf8").subarray(0, AGENTS_MD_MAX).toString("utf8") + "\n\n<!-- AGENTS.md truncated -->";
7317
- }
7318
- scopedLayers.push(buildAgentsMdLayer(mdContent, name));
7319
- break;
7320
- } catch {
7321
- }
7322
- }
7323
- }
6538
+ const agentsMdLayer = readAgentsMdLayerFromDisk(cliCwd);
6539
+ if (agentsMdLayer) scopedLayers.push(agentsMdLayer);
7324
6540
  skillContentBlocks.push(...buildSkillContextBlocks(skillReferences));
7325
6541
  scopedLayers.push(buildSkillDiscoveryContextLayer(cliCwd));
7326
6542
  if (!deps.memoryRecallDisabled) {
@@ -7511,12 +6727,16 @@ async function runAgentRunCommand(args, deps) {
7511
6727
  if (typeof childRunId === "string" && childRunId.length > 0) {
7512
6728
  const isStalledOrTruncated = result.emptyAssistantFallbackReason === "length_truncated" || result.emptyAssistantFallbackReason === "stream_truncated" || result.emptyAssistantFallbackReason === "repetition_loop" || result.emptyAssistantFallbackReason === "stagnant_tool_calls";
7513
6729
  const truncationNote = isStalledOrTruncated ? { note: `empty assistant output: ${result.emptyAssistantFallbackReason}` } : {};
7514
- const finalStatus = isStalledOrTruncated || result.exitCode !== 0 ? "failed" : "done";
6730
+ const outcome = resolveRunOutcome({
6731
+ kind: "result",
6732
+ exitCode: result.exitCode,
6733
+ isStalledOrTruncated
6734
+ });
7515
6735
  await (deps.finalizeRunRecord ?? finalizeRunRecord)(
7516
6736
  childRunId,
7517
6737
  {
7518
- status: finalStatus,
7519
- exitCode: result.exitCode,
6738
+ status: outcome.status,
6739
+ exitCode: outcome.exitCode,
7520
6740
  dialogId: result.dialogId,
7521
6741
  ...truncationNote
7522
6742
  },
@@ -7588,8 +6808,6 @@ export {
7588
6808
  getActiveThemeMode,
7589
6809
  setActiveThemeMode,
7590
6810
  setActiveBrightness,
7591
- getActiveDensity,
7592
- setActiveDensity,
7593
6811
  detectSystemBrightnessFromEnv,
7594
6812
  resolveTuiBrightness,
7595
6813
  resolveTuiThemeMode,
@@ -7602,8 +6820,9 @@ export {
7602
6820
  themeText,
7603
6821
  tuiRenderThemeFingerprint,
7604
6822
  setMathRenderingEnabled,
6823
+ polishBreathInsertsBlankBetween,
7605
6824
  formatAssistantDisplay,
7606
- normalizeToolDisplayMode,
6825
+ TUI_TREE_MARKER,
7607
6826
  COLLAPSED_PASTE_PLACEHOLDER_RE,
7608
6827
  shouldCollapsePaste,
7609
6828
  createCollapsedPasteStore,
@@ -7615,6 +6834,7 @@ export {
7615
6834
  expandRangeToCollapsedPasteChips,
7616
6835
  findCollapsedPasteSpanAt,
7617
6836
  runAgentTurn,
6837
+ readAgentsMdLayerFromDisk,
7618
6838
  resolveWorkflowReference,
7619
6839
  resolveSkillReference,
7620
6840
  buildSkillContextBlocks,
@@ -7622,6 +6842,7 @@ export {
7622
6842
  normalizeCliImageInput,
7623
6843
  inspectLocalRunWorkspace,
7624
6844
  resolveCliMemory,
6845
+ resolveRunOutcome,
7625
6846
  runAgentRunCommand,
7626
6847
  isBalanceExhaustedError
7627
6848
  };