nolo-cli 0.33.0-alpha.9 → 0.34.0-alpha.3

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 (164) hide show
  1. package/{_executeModel-2WR4RTZZ.js → _executeModel-TMUXL7J5.js} +64 -65
  2. package/{action-OQWPNKAH.js → action-KMBZ3LCZ.js} +12 -12
  3. package/{addContentAction-YVINZQTF.js → addContentAction-KQ44UT2U.js} +10 -10
  4. package/{addDialogAgentAction-6IOCIEPI.js → addDialogAgentAction-ILSDCMYL.js} +9 -9
  5. package/{agentDeleteCommand-H22WRYC6.js → agentDeleteCommand-KA2IQAPG.js} +40 -39
  6. package/{agentEmailCommands-DGJVCMCG.js → agentEmailCommands-UIYBGCZW.js} +74 -75
  7. package/{agentListCommands-6NWMLIMQ.js → agentListCommands-L6JNUOLH.js} +47 -37
  8. package/{agentMachineCommands-5MUO6RDI.js → agentMachineCommands-5CQW5NZR.js} +37 -36
  9. package/agentProviderCommands-65ZC2WB4.js +122 -0
  10. package/{agentPullCommand-YH5GEBK4.js → agentPullCommand-TSWAJPS2.js} +1 -1
  11. package/agentRecordCommands-VUDJQIZH.js +112 -0
  12. package/agentRunCommand-EJWYF3BL.js +132 -0
  13. package/{agentRunControl-SCIVRZWX.js → agentRunControl-7MUPSYDQ.js} +7 -1
  14. package/{agentRuntimeLocal-PRAR3NCW.js → agentRuntimeLocal-XXBMDMBU.js} +33 -33
  15. package/{agentSlice-AMDSTXP5.js → agentSlice-HTIEYKIU.js} +12 -12
  16. package/agentSuperviseCommands-MKWW3ICX.js +640 -0
  17. package/{appDeleteCommands-L5PKC42V.js → appDeleteCommands-OUBL6VHB.js} +35 -34
  18. package/{appDeployCommands-3J7Z4XWV.js → appDeployCommands-BZSS2MX4.js} +35 -34
  19. package/{appDeployStatusCommands-YTRPXE72.js → appDeployStatusCommands-P2ZQOY5X.js} +35 -34
  20. package/{appGetCommands-JVXV5WXD.js → appGetCommands-WCFWQZZM.js} +35 -34
  21. package/{appListCommands-7KDEOJSO.js → appListCommands-FVJ3QNL7.js} +35 -34
  22. package/{authCommand-6Y5LTMZB.js → authCommand-B2XRHNJH.js} +19 -19
  23. package/{authCommands-EAPFGNHN.js → authCommands-GWABTFMR.js} +6 -6
  24. package/{chatQueueReduxAdapter-ZKSS6XRV.js → chatQueueReduxAdapter-ZP2ZS63U.js} +28 -28
  25. package/{chunk-UM4H3URE.js → chunk-23KKIMD5.js} +7 -7
  26. package/chunk-2BWU4ORW.js +2574 -0
  27. package/{chunk-2UECQ7RE.js → chunk-3AOLVADY.js} +1 -1
  28. package/{chunk-M2YMQOLC.js → chunk-4APLX2RT.js} +75 -10
  29. package/{chunk-ZHYK3N56.js → chunk-4AWH4LQA.js} +3 -1
  30. package/{chunk-3GZXL6FM.js → chunk-4DMPISV6.js} +7 -3
  31. package/{chunk-BQ3OHLR5.js → chunk-5GQ6XCJY.js} +1217 -691
  32. package/{chunk-GOIDVXK5.js → chunk-5LDKQUOT.js} +21 -8
  33. package/{chunk-OIQPORYI.js → chunk-64KIQZA2.js} +175 -2
  34. package/{chunk-6XIE5ZGI.js → chunk-6HIGYUBQ.js} +1 -1
  35. package/chunk-6XG52ZQ6.js +146 -0
  36. package/{chunk-FMEVI5TG.js → chunk-7CH6U3FL.js} +1 -1
  37. package/chunk-AA2YUJNV.js +54 -0
  38. package/{chunk-7INB7NXF.js → chunk-AE5GVFMG.js} +294 -54
  39. package/{chunk-UNOTBWZZ.js → chunk-B6H5XCT2.js} +8 -8
  40. package/{chunk-NNWHHCVP.js → chunk-BMB563Y6.js} +10 -4
  41. package/{chunk-DFUPZE6V.js → chunk-C6ELZQ7H.js} +249 -34
  42. package/{chunk-7KNERA53.js → chunk-E2OQ5N2F.js} +87 -13
  43. package/{chunk-6HYVJV7B.js → chunk-ESHYE7WU.js} +2 -1
  44. package/{chunk-KHCLMKZZ.js → chunk-EY7V7REW.js} +280 -6
  45. package/{chunk-JZPBVBIY.js → chunk-FD36SCCD.js} +19 -8
  46. package/{chunk-DKMOY3QI.js → chunk-FGLKRJDI.js} +54 -3
  47. package/{chunk-MQWVAOIU.js → chunk-FT4XBCK4.js} +33 -158
  48. package/{chunk-2QTEYCR7.js → chunk-FTM4KUOZ.js} +17 -17
  49. package/{chunk-U4TRT5V4.js → chunk-GEPHJJW4.js} +1 -1
  50. package/{chunk-7YYHKBJP.js → chunk-GKHV4UH5.js} +1 -1
  51. package/{chunk-2IVEXF7P.js → chunk-GUYMR3JL.js} +6 -33
  52. package/{chunk-YDTYDA5W.js → chunk-GZRMWK5R.js} +6 -4
  53. package/{chunk-X664KVEV.js → chunk-HHBXCRJS.js} +204 -123
  54. package/{chunk-AN7DGYMW.js → chunk-I7VDDN45.js} +4579 -3131
  55. package/{chunk-DSBGWT2C.js → chunk-IEEEWIVO.js} +10 -10
  56. package/{chunk-75U775RZ.js → chunk-IFS5CUEH.js} +1 -1
  57. package/{chunk-WLH5BAKX.js → chunk-IIOHYLIG.js} +9 -4
  58. package/{chunk-UEAUAXYS.js → chunk-ILZY5B4U.js} +2063 -214
  59. package/chunk-IMHO5LC6.js +370 -0
  60. package/{chunk-ADLYMQB6.js → chunk-IZCHPD7T.js} +52 -3
  61. package/{chunk-ITIA6OAQ.js → chunk-IZNJDUJ4.js} +5 -5
  62. package/{chunk-X2DAEZ3X.js → chunk-J5NMOM35.js} +1 -1
  63. package/{chunk-RPRRIFXV.js → chunk-JI2TIPLP.js} +1 -1
  64. package/{chunk-EGRJC4ZN.js → chunk-JIADXJYU.js} +1 -1
  65. package/{chunk-IHEC7VBF.js → chunk-K4KIFRIN.js} +1 -1
  66. package/{chunk-WJSW43QZ.js → chunk-L3JWI7WX.js} +0 -1
  67. package/{chunk-3RUW3ONU.js → chunk-LD6Y6RJY.js} +4 -4
  68. package/chunk-M3JQWYBC.js +387 -0
  69. package/{chunk-GM6PU7B6.js → chunk-MEYIRKDN.js} +0 -1
  70. package/{chunk-6YXDOOSH.js → chunk-MGIHZ5CJ.js} +4 -4
  71. package/{chunk-4F5M2MW5.js → chunk-MJWX4JQO.js} +2 -2
  72. package/{chunk-Q5ITEGIN.js → chunk-N4XRDM26.js} +1 -1
  73. package/{chunk-5CS33IBL.js → chunk-NQ4N4IGO.js} +11 -12
  74. package/{chunk-ZZ2MH7LE.js → chunk-O6OSWFZQ.js} +0 -1
  75. package/{chunk-RJKIB55Y.js → chunk-OSCSEJJR.js} +15 -8
  76. package/{chunk-HUCT7HID.js → chunk-P2I7ELDC.js} +3 -3
  77. package/{chunk-BXPBZVRE.js → chunk-PILJX4DH.js} +285 -251
  78. package/{chunk-SCUETSRP.js → chunk-PV734VZX.js} +1 -1
  79. package/{chunk-XLLTJXAD.js → chunk-QI3CHZUT.js} +39 -2672
  80. package/{chunk-WNHST4IE.js → chunk-RKRXAL3V.js} +5451 -5013
  81. package/{chunk-7E72JMBB.js → chunk-SMPAUSX5.js} +46 -5
  82. package/{chunk-5X4GQ53C.js → chunk-TLBZMLLJ.js} +7 -7
  83. package/{chunk-ASDXPOJH.js → chunk-U6QQLXWI.js} +1 -1
  84. package/{chunk-NUO3QFWD.js → chunk-UNHKVD2N.js} +1 -1
  85. package/{chunk-GE6IWA5N.js → chunk-UNZDCI3O.js} +126 -1
  86. package/{chunk-CPYYM4RJ.js → chunk-V5GA74HI.js} +19 -5
  87. package/{chunk-FXFGNOT2.js → chunk-VFVCYIRQ.js} +1 -1
  88. package/{chunk-G7E4NWFE.js → chunk-W445DPVT.js} +1 -1
  89. package/{chunk-EMW55KKX.js → chunk-WBZE7C6S.js} +1 -1
  90. package/{chunk-3UG2IIZ3.js → chunk-WN5AJG5I.js} +1 -1
  91. package/{chunk-KSRFVP36.js → chunk-WRN7L5CS.js} +1 -1
  92. package/{chunk-GJXRIOLS.js → chunk-WRP5TTM6.js} +4 -84
  93. package/chunk-X2K2JSO4.js +163 -0
  94. package/{chunk-OR2HNLVO.js → chunk-X6EN3KJX.js} +279 -477
  95. package/{chunk-VWY2CZD2.js → chunk-XMFDQYWA.js} +3 -3
  96. package/{chunk-IKWTTKWG.js → chunk-XQES6LXQ.js} +2 -2
  97. package/{chunk-IR6W62Q6.js → chunk-XT73C4VH.js} +18 -21
  98. package/{chunk-7L5CQQIT.js → chunk-Y5W623XU.js} +15 -15
  99. package/{chunk-RY57GLGW.js → chunk-YPREESF4.js} +42 -5
  100. package/{chunk-BQXOGBFN.js → chunk-YZ2WE6CW.js} +2 -2
  101. package/{chunk-DNQK7M7K.js → chunk-Z7COG62J.js} +4 -4
  102. package/{chunk-3WXRAHCG.js → chunk-ZBB3MZR3.js} +3 -3
  103. package/{cliExecutor-DW3PHGEL.js → cliExecutor-BBUVQU4L.js} +2 -2
  104. package/{clipboardy-MMBYVRLF.js → clipboardy-PRUHGPGC.js} +4 -3
  105. package/{codingSkills-DY5MINPG.js → codingSkills-6F4EQFCM.js} +4 -5
  106. package/cooldownCommands-C2SZLEEO.js +90 -0
  107. package/{createAgentAutomationAction-GVSJL2CI.js → createAgentAutomationAction-TGUXUZCY.js} +28 -30
  108. package/createDialogAction-FD5AEOUF.js +58 -0
  109. package/{createPageAction-M2VDKBYS.js → createPageAction-NPC3LYNK.js} +31 -34
  110. package/{dbSlice-UI2VCBLG.js → dbSlice-PIQGICNM.js} +9 -9
  111. package/{deleteFile-XQXPBFFB.js → deleteFile-NPZ64DFN.js} +4 -4
  112. package/{dialogCommands-26DBYNBT.js → dialogCommands-ZF2RSNCG.js} +37 -36
  113. package/{dialogSlice-FFGLRCBL.js → dialogSlice-6BINHWQT.js} +27 -27
  114. package/dist-VODFSGNG.js +7442 -0
  115. package/{docCreateCommands-F2ASWG6B.js → docCreateCommands-4VQ5MOHP.js} +36 -36
  116. package/{docDeleteCommands-A4URDZPI.js → docDeleteCommands-M7WLNVPB.js} +37 -37
  117. package/{docReadCommands-DO6VHDZD.js → docReadCommands-6LU6P2WT.js} +36 -36
  118. package/{docStore-EDAE7RNT.js → docStore-SIUFLABN.js} +29 -31
  119. package/{docUpdateCommands-ZTXZ3RTP.js → docUpdateCommands-S2LX4ENL.js} +39 -39
  120. package/{fetchMessages-7QRCCRYK.js → fetchMessages-CUEFN4GQ.js} +4 -4
  121. package/{getPricing-L2ENXWHV.js → getPricing-P3E2WRIH.js} +5 -5
  122. package/{handleSendMessageAction-CIRLGHOC.js → handleSendMessageAction-QVG5YNZY.js} +29 -29
  123. package/index.js +92 -77
  124. package/{localDialogRead-SLMPV5SK.js → localDialogRead-P7CHFMIC.js} +1 -1
  125. package/{localRuntimeAuthority-E3R24J4T.js → localRuntimeAuthority-S77B5QVB.js} +6 -2
  126. package/{localRuntimeDb-DDZCJFQZ.js → localRuntimeDb-N3H3HQ7G.js} +1 -1
  127. package/{machineCommands-NIQNCYJV.js → machineCommands-OSEBN7BZ.js} +76 -77
  128. package/{machineInfo-M6KB6HZN.js → machineInfo-66ZFUMLE.js} +1 -1
  129. package/{machineWsRunDispatch-EMTSQGAR.js → machineWsRunDispatch-NTJQCIIF.js} +68 -69
  130. package/{models-OX2S5C6Q.js → models-L7S2EKPM.js} +2 -2
  131. package/package.json +1 -1
  132. package/{read-2VHEHCAN.js → read-6C2XD3YZ.js} +5 -5
  133. package/{readDocTool-CSWD6NPC.js → readDocTool-Y7AB365O.js} +1 -1
  134. package/{readlineWorkspace-A2JBJWLI.js → readlineWorkspace-JPME5S7A.js} +4860 -3476
  135. package/{removeDialogAgentAction-2T7BPM3T.js → removeDialogAgentAction-KG5WMJRZ.js} +13 -13
  136. package/{runAgentClientLoop-BV4736ED.js → runAgentClientLoop-SOKEXCUF.js} +61 -61
  137. package/{runtimeDoctorCommands-KIKM6BIO.js → runtimeDoctorCommands-HT4O2PXL.js} +6 -6
  138. package/{setDialogExtraReferencesAction-GPT37HTW.js → setDialogExtraReferencesAction-O2NLXMSM.js} +10 -10
  139. package/{setPrimaryDialogAgentAction-3746P7IW.js → setPrimaryDialogAgentAction-FYYUY7PB.js} +13 -13
  140. package/{settingSlice-FIFOQ6OR.js → settingSlice-GPLI6E3M.js} +11 -11
  141. package/{skillDiscovery-KLLKXPUO.js → skillDiscovery-GPUDHDTZ.js} +3 -4
  142. package/{slateUtils-VO2FU36K.js → slateUtils-RIZES3PV.js} +1 -1
  143. package/{spaceCommands-AYZQHDB3.js → spaceCommands-Z5JLMFFJ.js} +223 -37
  144. package/{spaceSlice-43BNF22B.js → spaceSlice-Z3BGCLGX.js} +28 -30
  145. package/{streamAgentChatTurn-OLLRSITV.js → streamAgentChatTurn-INF5RGK4.js} +115 -129
  146. package/{switchDialogAgentAction-MQTUTQHL.js → switchDialogAgentAction-GH5P6Q3Z.js} +9 -9
  147. package/{chunk-IDAU4UFS.js → syncMapping-N6RGXGBW.js} +11 -11
  148. package/{tableCommands-QE47K72R.js → tableCommands-PQUJ55AS.js} +3 -3
  149. package/{tools-2SI3FXLL.js → tools-ZELMSJZ3.js} +45 -47
  150. package/{tuiSummaryLlmCaller-EAWQ3IZX.js → tuiSummaryLlmCaller-LH7F2SP7.js} +18 -18
  151. package/{updateCommands-AK2RDOFR.js → updateCommands-MNDUIKN7.js} +2 -2
  152. package/{updateDialogTitleAction-YJEQFYOA.js → updateDialogTitleAction-EDUCIB7G.js} +31 -33
  153. package/agentRecordCommands-YMGKT2WF.js +0 -113
  154. package/agentRunCommand-LYEMVQJH.js +0 -131
  155. package/chunk-AETZ7AD6.js +0 -274
  156. package/chunk-D5JI6VDM.js +0 -1800
  157. package/chunk-M3JEW6N6.js +0 -193
  158. package/chunk-ZURFOV5J.js +0 -105
  159. package/chunk-ZWS6DUHX.js +0 -480
  160. package/createDialogAction-VVR46Q2A.js +0 -61
  161. package/syncMapping-RK2MANUX.js +0 -43
  162. package/{chunk-KMSZPTM6.js → chunk-2WKUUY2E.js} +3 -3
  163. package/{chunk-CWMSB67P.js → chunk-AGGIDPCZ.js} +0 -0
  164. package/{chunk-SAQQLJZ5.js → chunk-JDSUTNYY.js} +3 -3
@@ -1,3 +1,6 @@
1
+ import {
2
+ generateRunReport
3
+ } from "./chunk-IMHO5LC6.js";
1
4
  import {
2
5
  buildLocalRunEnv,
3
6
  isFullstackCodingAgentRef,
@@ -6,65 +9,92 @@ import {
6
9
  resolveRawAgentInput,
7
10
  resolveServerUrl,
8
11
  writeUsage
9
- } from "./chunk-ZHYK3N56.js";
10
- import {
11
- getReadableCliDb
12
- } from "./chunk-NUO3QFWD.js";
13
- import {
14
- normalizeAgentHandle,
15
- readDbRecord,
16
- resolveAgentRecordFromHybridStore
17
- } from "./chunk-YDTYDA5W.js";
12
+ } from "./chunk-4AWH4LQA.js";
18
13
  import {
19
14
  agentRunCardLabels,
20
15
  createCliLocalRuntimeAdapter,
21
16
  getCliLocale,
22
17
  isBuiltinNoloAgentRef,
23
18
  isSubtaskRun,
19
+ isTransientFetchError,
24
20
  parseAgentRunEvent,
25
21
  t,
26
22
  toolLabel
27
- } from "./chunk-WNHST4IE.js";
23
+ } from "./chunk-RKRXAL3V.js";
24
+ import {
25
+ getReadableCliDb
26
+ } from "./chunk-UNHKVD2N.js";
27
+ import {
28
+ normalizeAgentHandle,
29
+ readDbRecord,
30
+ resolveAgentRecordFromHybridStore
31
+ } from "./chunk-GZRMWK5R.js";
28
32
  import {
29
33
  NOLO_PROJECT_MANAGER_AGENT_KEY,
30
34
  isLocalCliAgentKey
31
35
  } from "./chunk-EKLRRZIN.js";
36
+ import {
37
+ CliProviderQuotaError
38
+ } from "./chunk-JDSUTNYY.js";
39
+ import {
40
+ createRunActivityTracker,
41
+ finalizeRunRecord,
42
+ readRunRecord,
43
+ spawnLocalBackgroundRun
44
+ } from "./chunk-E2OQ5N2F.js";
45
+ import {
46
+ resolveMachineId
47
+ } from "./chunk-ESHYE7WU.js";
32
48
  import {
33
49
  applyModelLayerOverride,
34
50
  buildModelLayerOverride
35
51
  } from "./chunk-LTRXGFMS.js";
36
- import {
37
- resolveMachineId
38
- } from "./chunk-6HYVJV7B.js";
39
52
  import {
40
53
  formatAgentListCard
41
- } from "./chunk-BQ3OHLR5.js";
54
+ } from "./chunk-5GQ6XCJY.js";
42
55
  import {
43
56
  isGatewayHttpStatus
44
57
  } from "./chunk-RQSOAMPJ.js";
45
58
  import {
46
- getDefaultCliLocalRuntimeDb
47
- } from "./chunk-Q5ITEGIN.js";
59
+ formatFinishedRunCard,
60
+ formatListRunsCard,
61
+ formatNotFoundRunCard,
62
+ formatStartRunCard,
63
+ formatStatusRunCard,
64
+ formatStopRunCard,
65
+ isAgentRunTerminalStatus,
66
+ runShowsLogTail
67
+ } from "./chunk-KXKQO4Q6.js";
48
68
  import {
49
69
  buildMemorySubjectsForAgent,
50
70
  chooseMemoryOwners,
51
71
  loadMemoryCandidatesFromDb,
52
72
  resolveAgentMemoryPolicy
53
- } from "./chunk-7L5CQQIT.js";
73
+ } from "./chunk-Y5W623XU.js";
54
74
  import {
55
75
  API_REPORTED_COST_MULTIPLIER,
56
76
  normalizeUsage,
57
77
  parseUiAskChoiceContent
58
- } from "./chunk-BXPBZVRE.js";
78
+ } from "./chunk-PILJX4DH.js";
59
79
  import {
60
- resolveAgentRuntimeConfigFromRecord
61
- } from "./chunk-OIQPORYI.js";
80
+ getDefaultCliLocalRuntimeDb
81
+ } from "./chunk-N4XRDM26.js";
82
+ import {
83
+ buildSkillDiscoveryContextLayer
84
+ } from "./chunk-2BWU4ORW.js";
85
+ import {
86
+ parseExternalSkillMarkdown,
87
+ parseSkillDocProtocol
88
+ } from "./chunk-EY7V7REW.js";
62
89
  import {
63
90
  LOCAL_AGENT_CONFIG_MISSING_CODE,
64
91
  LOCAL_TURN_ABORTED_CODE,
65
92
  readActionGate,
66
93
  readCommandActionGatePayload
67
- } from "./chunk-D5JI6VDM.js";
94
+ } from "./chunk-I7VDDN45.js";
95
+ import {
96
+ resolveAgentRuntimeConfigFromRecord
97
+ } from "./chunk-64KIQZA2.js";
68
98
  import {
69
99
  createThinkParserState,
70
100
  flushThinkParser,
@@ -72,55 +102,33 @@ import {
72
102
  } from "./chunk-N7J63Q6C.js";
73
103
  import {
74
104
  resolvePlatformAuthToken
75
- } from "./chunk-7YYHKBJP.js";
105
+ } from "./chunk-GKHV4UH5.js";
106
+ import {
107
+ isQuotaExhaustedError
108
+ } from "./chunk-X2K2JSO4.js";
76
109
  import {
77
110
  DEFAULT_CONTEXT_WINDOW,
78
111
  getModelContextWindow
79
- } from "./chunk-GJXRIOLS.js";
112
+ } from "./chunk-WRP5TTM6.js";
80
113
  import {
81
114
  clipCompactText
82
- } from "./chunk-DKMOY3QI.js";
115
+ } from "./chunk-FGLKRJDI.js";
83
116
  import {
84
117
  findModelConfig
85
- } from "./chunk-DFUPZE6V.js";
118
+ } from "./chunk-C6ELZQ7H.js";
86
119
  import {
87
- buildSkillDiscoveryContextLayer
88
- } from "./chunk-ZURFOV5J.js";
120
+ compactWhitespace
121
+ } from "./chunk-DWLEOOGR.js";
122
+ import {
123
+ toErrorMessage
124
+ } from "./chunk-HNMXYYJR.js";
89
125
  import {
90
126
  buildAgentsMdLayer,
91
127
  buildMemoryOverlayLayer,
92
128
  buildMemoryUseGuidanceLayer,
93
129
  partitionScopedBlocks,
94
130
  renderTurnContextBlocksWithScope
95
- } from "./chunk-2UECQ7RE.js";
96
- import {
97
- parseExternalSkillMarkdown,
98
- parseSkillDocProtocol
99
- } from "./chunk-AETZ7AD6.js";
100
- import {
101
- compactWhitespace
102
- } from "./chunk-DWLEOOGR.js";
103
- import {
104
- createRunActivityTracker,
105
- finalizeRunRecord,
106
- spawnLocalBackgroundRun
107
- } from "./chunk-7KNERA53.js";
108
- import {
109
- formatFinishedRunCard,
110
- formatListRunsCard,
111
- formatNotFoundRunCard,
112
- formatStartRunCard,
113
- formatStatusRunCard,
114
- formatStopRunCard,
115
- isAgentRunTerminalStatus,
116
- runShowsLogTail
117
- } from "./chunk-KXKQO4Q6.js";
118
- import {
119
- CliProviderQuotaError
120
- } from "./chunk-SAQQLJZ5.js";
121
- import {
122
- toErrorMessage
123
- } from "./chunk-HNMXYYJR.js";
131
+ } from "./chunk-3AOLVADY.js";
124
132
  import {
125
133
  readPipeText,
126
134
  spawnProcess
@@ -133,7 +141,7 @@ import {
133
141
  } from "./chunk-Y5GCAMGP.js";
134
142
  import {
135
143
  createMemoryKey
136
- } from "./chunk-KMSZPTM6.js";
144
+ } from "./chunk-2WKUUY2E.js";
137
145
  import {
138
146
  asTrimmedLowercaseString
139
147
  } from "./chunk-QSJ3HFEF.js";
@@ -141,13 +149,13 @@ import {
141
149
  BUILTIN_NOLO_AGENT_KEY,
142
150
  BUILTIN_NOLO_AGENT_NAME,
143
151
  builtinAgentCatalogEntryById
144
- } from "./chunk-IR6W62Q6.js";
145
- import {
146
- asTrimmedString
147
- } from "./chunk-3EUW3WEO.js";
152
+ } from "./chunk-XT73C4VH.js";
148
153
  import {
149
154
  parsePublicAgentId
150
155
  } from "./chunk-BJIRLHJR.js";
156
+ import {
157
+ asTrimmedString
158
+ } from "./chunk-3EUW3WEO.js";
151
159
  import {
152
160
  isLoopbackUrl
153
161
  } from "./chunk-4SN6J65J.js";
@@ -227,7 +235,8 @@ function buildTurnTokenUsage(usage, model) {
227
235
  const contextWindow = resolveContextWindow(model);
228
236
  const remaining = contextWindow && parsed.input > 0 ? Math.max(0, contextWindow - parsed.input) : void 0;
229
237
  const rawCost = typeof usage?.cost === "number" ? usage.cost : void 0;
230
- const credits = rawCost !== void 0 && rawCost > 0 ? rawCost * API_REPORTED_COST_MULTIPLIER : void 0;
238
+ const isPlatformBilled = usage?.billing_unit === "credits";
239
+ const credits = rawCost !== void 0 && rawCost > 0 ? isPlatformBilled ? rawCost : rawCost * API_REPORTED_COST_MULTIPLIER : void 0;
231
240
  return {
232
241
  ...parsed,
233
242
  ...contextWindow ? { contextWindow } : {},
@@ -317,11 +326,243 @@ function dimCliText(text, enabled = resolveCliColorEnabled()) {
317
326
  return styleCliText(text, "dim", enabled);
318
327
  }
319
328
 
329
+ // node_modules/ansi-regex/index.js
330
+ function ansiRegex({ onlyFirst = false } = {}) {
331
+ const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
332
+ const osc = `(?:\\u001B\\][^\\u0007\\u001B\\u009C]*${ST})`;
333
+ const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
334
+ const pattern = `${osc}|${csi}`;
335
+ return new RegExp(pattern, onlyFirst ? void 0 : "g");
336
+ }
337
+
338
+ // node_modules/strip-ansi/index.js
339
+ var regex = ansiRegex();
340
+ function stripAnsi(string) {
341
+ if (typeof string !== "string") {
342
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
343
+ }
344
+ if (!string.includes("\x1B") && !string.includes("\x9B")) {
345
+ return string;
346
+ }
347
+ return string.replace(regex, "");
348
+ }
349
+
350
+ // node_modules/get-east-asian-width/lookup-data.js
351
+ var ambiguousMinimalCodePoint = 161;
352
+ var ambiguousMaximumCodePoint = 1114109;
353
+ var ambiguousRanges = [161, 161, 164, 164, 167, 168, 170, 170, 173, 174, 176, 180, 182, 186, 188, 191, 198, 198, 208, 208, 215, 216, 222, 225, 230, 230, 232, 234, 236, 237, 240, 240, 242, 243, 247, 250, 252, 252, 254, 254, 257, 257, 273, 273, 275, 275, 283, 283, 294, 295, 299, 299, 305, 307, 312, 312, 319, 322, 324, 324, 328, 331, 333, 333, 338, 339, 358, 359, 363, 363, 462, 462, 464, 464, 466, 466, 468, 468, 470, 470, 472, 472, 474, 474, 476, 476, 593, 593, 609, 609, 708, 708, 711, 711, 713, 715, 717, 717, 720, 720, 728, 731, 733, 733, 735, 735, 768, 879, 913, 929, 931, 937, 945, 961, 963, 969, 1025, 1025, 1040, 1103, 1105, 1105, 8208, 8208, 8211, 8214, 8216, 8217, 8220, 8221, 8224, 8226, 8228, 8231, 8240, 8240, 8242, 8243, 8245, 8245, 8251, 8251, 8254, 8254, 8308, 8308, 8319, 8319, 8321, 8324, 8364, 8364, 8451, 8451, 8453, 8453, 8457, 8457, 8467, 8467, 8470, 8470, 8481, 8482, 8486, 8486, 8491, 8491, 8531, 8532, 8539, 8542, 8544, 8555, 8560, 8569, 8585, 8585, 8592, 8601, 8632, 8633, 8658, 8658, 8660, 8660, 8679, 8679, 8704, 8704, 8706, 8707, 8711, 8712, 8715, 8715, 8719, 8719, 8721, 8721, 8725, 8725, 8730, 8730, 8733, 8736, 8739, 8739, 8741, 8741, 8743, 8748, 8750, 8750, 8756, 8759, 8764, 8765, 8776, 8776, 8780, 8780, 8786, 8786, 8800, 8801, 8804, 8807, 8810, 8811, 8814, 8815, 8834, 8835, 8838, 8839, 8853, 8853, 8857, 8857, 8869, 8869, 8895, 8895, 8978, 8978, 9312, 9449, 9451, 9547, 9552, 9587, 9600, 9615, 9618, 9621, 9632, 9633, 9635, 9641, 9650, 9651, 9654, 9655, 9660, 9661, 9664, 9665, 9670, 9672, 9675, 9675, 9678, 9681, 9698, 9701, 9711, 9711, 9733, 9734, 9737, 9737, 9742, 9743, 9756, 9756, 9758, 9758, 9792, 9792, 9794, 9794, 9824, 9825, 9827, 9829, 9831, 9834, 9836, 9837, 9839, 9839, 9886, 9887, 9919, 9919, 9926, 9933, 9935, 9939, 9941, 9953, 9955, 9955, 9960, 9961, 9963, 9969, 9972, 9972, 9974, 9977, 9979, 9980, 9982, 9983, 10045, 10045, 10102, 10111, 11094, 11097, 12872, 12879, 57344, 63743, 65024, 65039, 65533, 65533, 127232, 127242, 127248, 127277, 127280, 127337, 127344, 127373, 127375, 127376, 127387, 127404, 917760, 917999, 983040, 1048573, 1048576, 1114109];
354
+ var fullwidthMinimalCodePoint = 12288;
355
+ var fullwidthMaximumCodePoint = 65510;
356
+ var fullwidthRanges = [12288, 12288, 65281, 65376, 65504, 65510];
357
+ var wideMinimalCodePoint = 4352;
358
+ var wideMaximumCodePoint = 262141;
359
+ var wideRanges = [4352, 4447, 8986, 8987, 9001, 9002, 9193, 9196, 9200, 9200, 9203, 9203, 9725, 9726, 9748, 9749, 9776, 9783, 9800, 9811, 9855, 9855, 9866, 9871, 9875, 9875, 9889, 9889, 9898, 9899, 9917, 9918, 9924, 9925, 9934, 9934, 9940, 9940, 9962, 9962, 9970, 9971, 9973, 9973, 9978, 9978, 9981, 9981, 9989, 9989, 9994, 9995, 10024, 10024, 10060, 10060, 10062, 10062, 10067, 10069, 10071, 10071, 10133, 10135, 10160, 10160, 10175, 10175, 11035, 11036, 11088, 11088, 11093, 11093, 11904, 11929, 11931, 12019, 12032, 12245, 12272, 12287, 12289, 12350, 12353, 12438, 12441, 12543, 12549, 12591, 12593, 12686, 12688, 12773, 12783, 12830, 12832, 12871, 12880, 42124, 42128, 42182, 43360, 43388, 44032, 55203, 63744, 64255, 65040, 65049, 65072, 65106, 65108, 65126, 65128, 65131, 94176, 94180, 94192, 94198, 94208, 101589, 101631, 101662, 101760, 101874, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 119552, 119638, 119648, 119670, 126980, 126980, 127183, 127183, 127374, 127374, 127377, 127386, 127488, 127490, 127504, 127547, 127552, 127560, 127568, 127569, 127584, 127589, 127744, 127776, 127789, 127797, 127799, 127868, 127870, 127891, 127904, 127946, 127951, 127955, 127968, 127984, 127988, 127988, 127992, 128062, 128064, 128064, 128066, 128252, 128255, 128317, 128331, 128334, 128336, 128359, 128378, 128378, 128405, 128406, 128420, 128420, 128507, 128591, 128640, 128709, 128716, 128716, 128720, 128722, 128725, 128728, 128732, 128735, 128747, 128748, 128756, 128764, 128992, 129003, 129008, 129008, 129292, 129338, 129340, 129349, 129351, 129535, 129648, 129660, 129664, 129674, 129678, 129734, 129736, 129736, 129741, 129756, 129759, 129770, 129775, 129784, 131072, 196605, 196608, 262141];
360
+
361
+ // node_modules/get-east-asian-width/utilities.js
362
+ var isInRange = (ranges, codePoint) => {
363
+ let low = 0;
364
+ let high = Math.floor(ranges.length / 2) - 1;
365
+ while (low <= high) {
366
+ const mid = Math.floor((low + high) / 2);
367
+ const i = mid * 2;
368
+ if (codePoint < ranges[i]) {
369
+ high = mid - 1;
370
+ } else if (codePoint > ranges[i + 1]) {
371
+ low = mid + 1;
372
+ } else {
373
+ return true;
374
+ }
375
+ }
376
+ return false;
377
+ };
378
+
379
+ // node_modules/get-east-asian-width/lookup.js
380
+ var commonCjkCodePoint = 19968;
381
+ var [wideFastPathStart, wideFastPathEnd] = /* @__PURE__ */ findWideFastPathRange(wideRanges);
382
+ function findWideFastPathRange(ranges) {
383
+ let fastPathStart = ranges[0];
384
+ let fastPathEnd = ranges[1];
385
+ for (let index = 0; index < ranges.length; index += 2) {
386
+ const start = ranges[index];
387
+ const end = ranges[index + 1];
388
+ if (commonCjkCodePoint >= start && commonCjkCodePoint <= end) {
389
+ return [start, end];
390
+ }
391
+ if (end - start > fastPathEnd - fastPathStart) {
392
+ fastPathStart = start;
393
+ fastPathEnd = end;
394
+ }
395
+ }
396
+ return [fastPathStart, fastPathEnd];
397
+ }
398
+ var isAmbiguous = (codePoint) => {
399
+ if (codePoint < ambiguousMinimalCodePoint || codePoint > ambiguousMaximumCodePoint) {
400
+ return false;
401
+ }
402
+ return isInRange(ambiguousRanges, codePoint);
403
+ };
404
+ var isFullWidth = (codePoint) => {
405
+ if (codePoint < fullwidthMinimalCodePoint || codePoint > fullwidthMaximumCodePoint) {
406
+ return false;
407
+ }
408
+ return isInRange(fullwidthRanges, codePoint);
409
+ };
410
+ var isWide = (codePoint) => {
411
+ if (codePoint >= wideFastPathStart && codePoint <= wideFastPathEnd) {
412
+ return true;
413
+ }
414
+ if (codePoint < wideMinimalCodePoint || codePoint > wideMaximumCodePoint) {
415
+ return false;
416
+ }
417
+ return isInRange(wideRanges, codePoint);
418
+ };
419
+
420
+ // node_modules/get-east-asian-width/index.js
421
+ function validate(codePoint) {
422
+ if (!Number.isSafeInteger(codePoint)) {
423
+ throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
424
+ }
425
+ }
426
+ function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
427
+ validate(codePoint);
428
+ if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
429
+ return 2;
430
+ }
431
+ return 1;
432
+ }
433
+
434
+ // node_modules/string-width/index.js
435
+ var segmenter = new Intl.Segmenter();
436
+ var zeroWidthClusterRegex = new RegExp("^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Format}|\\p{Nonspacing_Mark}|\\p{Enclosing_Mark}|\\p{Surrogate})+$", "v");
437
+ var leadingNonPrintingRegex = new RegExp("^[\\p{Default_Ignorable_Code_Point}\\p{Control}\\p{Format}\\p{Nonspacing_Mark}\\p{Enclosing_Mark}\\p{Surrogate}]+", "v");
438
+ var spacingMarkRegex = new RegExp("\\p{Spacing_Mark}", "v");
439
+ var rgiEmojiRegex = new RegExp("^\\p{RGI_Emoji}$", "v");
440
+ var unqualifiedKeycapRegex = /^[\d#*]\u20E3$/;
441
+ var extendedPictographicRegex = new RegExp("\\p{Extended_Pictographic}", "gu");
442
+ function isDoubleWidthNonRgiEmojiSequence(segment) {
443
+ if (segment.length > 50) {
444
+ return false;
445
+ }
446
+ if (unqualifiedKeycapRegex.test(segment)) {
447
+ return true;
448
+ }
449
+ if (segment.includes("\u200D")) {
450
+ const pictographics = segment.match(extendedPictographicRegex);
451
+ return pictographics !== null && pictographics.length >= 2;
452
+ }
453
+ return false;
454
+ }
455
+ function baseVisible(segment) {
456
+ return segment.replace(leadingNonPrintingRegex, "");
457
+ }
458
+ function isZeroWidthCluster(segment) {
459
+ return zeroWidthClusterRegex.test(segment);
460
+ }
461
+ function isHangulLeadingJamo(codePoint) {
462
+ return codePoint >= 4352 && codePoint <= 4447 || codePoint >= 43360 && codePoint <= 43388;
463
+ }
464
+ function isHangulVowelJamo(codePoint) {
465
+ return codePoint >= 4448 && codePoint <= 4519 || codePoint >= 55216 && codePoint <= 55238;
466
+ }
467
+ function isHangulTrailingJamo(codePoint) {
468
+ return codePoint >= 4520 && codePoint <= 4607 || codePoint >= 55243 && codePoint <= 55291;
469
+ }
470
+ function isHangulJamo(codePoint) {
471
+ return isHangulLeadingJamo(codePoint) || isHangulVowelJamo(codePoint) || isHangulTrailingJamo(codePoint);
472
+ }
473
+ function hangulClusterWidth(visibleSegment, eastAsianWidthOptions) {
474
+ const codePoints = [];
475
+ for (const character of visibleSegment) {
476
+ if (zeroWidthClusterRegex.test(character)) {
477
+ continue;
478
+ }
479
+ codePoints.push(character.codePointAt(0));
480
+ }
481
+ if (codePoints.length === 0) {
482
+ return void 0;
483
+ }
484
+ let width = 0;
485
+ for (let index = 0; index < codePoints.length; index++) {
486
+ const codePoint = codePoints[index];
487
+ if (!isHangulJamo(codePoint)) {
488
+ if (width === 0) {
489
+ return void 0;
490
+ }
491
+ for (let remaining = index; remaining < codePoints.length; remaining++) {
492
+ width += eastAsianWidth(codePoints[remaining], eastAsianWidthOptions);
493
+ }
494
+ return width;
495
+ }
496
+ if (isHangulLeadingJamo(codePoint) && isHangulVowelJamo(codePoints[index + 1])) {
497
+ width += 2;
498
+ index += isHangulTrailingJamo(codePoints[index + 2]) ? 2 : 1;
499
+ continue;
500
+ }
501
+ width += eastAsianWidth(codePoint, eastAsianWidthOptions);
502
+ }
503
+ return width;
504
+ }
505
+ function trailingWidth(visibleSegment, eastAsianWidthOptions) {
506
+ let extra = 0;
507
+ let first = true;
508
+ for (const character of visibleSegment) {
509
+ if (first) {
510
+ first = false;
511
+ continue;
512
+ }
513
+ if (spacingMarkRegex.test(character) || character >= "\uFF00" && character <= "\uFFEF") {
514
+ extra += eastAsianWidth(character.codePointAt(0), eastAsianWidthOptions);
515
+ }
516
+ }
517
+ return extra;
518
+ }
519
+ function stringWidth(input, options = {}) {
520
+ if (typeof input !== "string" || input.length === 0) {
521
+ return 0;
522
+ }
523
+ const {
524
+ ambiguousIsNarrow = true,
525
+ countAnsiEscapeCodes = false
526
+ } = options;
527
+ let string = input;
528
+ if (!countAnsiEscapeCodes && (string.includes("\x1B") || string.includes("\x9B"))) {
529
+ string = stripAnsi(string);
530
+ }
531
+ if (string.length === 0) {
532
+ return 0;
533
+ }
534
+ if (/^[\u0020-\u007E]*$/.test(string)) {
535
+ return string.length;
536
+ }
537
+ let width = 0;
538
+ const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
539
+ for (const { segment } of segmenter.segment(string)) {
540
+ if (isZeroWidthCluster(segment)) {
541
+ continue;
542
+ }
543
+ if (rgiEmojiRegex.test(segment) || isDoubleWidthNonRgiEmojiSequence(segment)) {
544
+ width += 2;
545
+ continue;
546
+ }
547
+ const visibleSegment = baseVisible(segment);
548
+ const hangulWidth = hangulClusterWidth(visibleSegment, eastAsianWidthOptions);
549
+ if (hangulWidth !== void 0) {
550
+ width += hangulWidth;
551
+ continue;
552
+ }
553
+ const codePoint = visibleSegment.codePointAt(0);
554
+ width += eastAsianWidth(codePoint, eastAsianWidthOptions);
555
+ width += trailingWidth(visibleSegment, eastAsianWidthOptions);
556
+ }
557
+ return width;
558
+ }
559
+
320
560
  // packages/cli/tui/tuiAnsi.ts
321
561
  var ANSI_ESCAPE_REGEX = /\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/g;
322
- var OSC_HYPERLINK_REGEX = /\x1b\]8;;[^\x07\x1b]*(?:\x07|\x1b\\)\x1b\]8;;(?:\x07|\x1b\\)|\x1b\]8;;[^\x07\x1b]*(?:\x07|\x1b\\)/g;
323
- function stripAnsi(text) {
324
- return text.replace(OSC_HYPERLINK_REGEX, "").replace(ANSI_ESCAPE_REGEX, "");
562
+ var ALL_ANSI_ESCAPE_REGEX = ansiRegex();
563
+ var FIRST_ANSI_ESCAPE_REGEX = ansiRegex({ onlyFirst: true });
564
+ function stripAnsi2(text) {
565
+ return text.replace(ANSI_ESCAPE_REGEX, "").replace(ALL_ANSI_ESCAPE_REGEX, "");
325
566
  }
326
567
  var SGR_SEQUENCE_REGEX = /^\x1b\[[0-9;]*m/;
327
568
  var TRAILING_SGR_REGEX = /(?:\x1b\[[0-9;]*m)+$/;
@@ -382,30 +623,78 @@ function applyTerminalOutputToText(existing, chunk) {
382
623
  }
383
624
  return text;
384
625
  }
385
- function displayWidth(str) {
386
- let width = 0;
387
- for (const char of str) {
388
- const code = char.codePointAt(0) ?? 0;
389
- if (code < 32 || code === 127) continue;
390
- if (code >= 4352 && code <= 4447 || // 0x2768-0x2775 (ornamental brackets, incl. the ❯ prompt at U+276F)
391
- // render narrow in terminals; counting them wide drifts the cursor.
392
- code >= 9728 && code <= 10175 && !(code >= 10088 && code <= 10101) || // 0x2B00-0x2BFF (Misc Symbols and Arrows, incl. ⬢ U+2B22 used as the
393
- // status-line agent icon) render double-wide in common monospace fonts;
394
- // counting ⬢ as width 1 drifts the whole status line right of the icon.
395
- code >= 11008 && code <= 11263 || code >= 11904 && code <= 12350 || code >= 12352 && code <= 13247 || code >= 13312 && code <= 19903 || code >= 19968 && code <= 42191 || code >= 44032 && code <= 55203 || code >= 63744 && code <= 64255 || code >= 65072 && code <= 65135 || code >= 65281 && code <= 65376 || code >= 65504 && code <= 65510 || code >= 127744 && code <= 129791 || code >= 131072 && code <= 196605 || code >= 196608 && code <= 262141 || // East Asian Ambiguous CJK quotation marks (U+201C/D “ ”, U+2018/9 ‘ ’).
396
- // In CJK locale + CJK fonts these render double-wide like 全角 punctuation;
397
- // in English fonts they stay width 1. Follow the active locale so Chinese
398
- // replies align correctly without breaking English terminal output.
399
- getCliLocale() === "zh" && (code === 8220 || code === 8221 || code === 8216 || code === 8217)) {
400
- width += 2;
401
- } else {
402
- width += 1;
626
+ function isAmbiguousWideSymbolCode(code) {
627
+ return code >= 8592 && code <= 8597 || // ←↑→↓↔↕
628
+ code === 8656 || code === 8658 || code === 8660 || // ⇐⇒⇔
629
+ code === 215 || code === 247 || code === 177 || // ×÷±
630
+ code === 8226 || code === 183;
631
+ }
632
+ function isForceWideSymbolCode(code) {
633
+ return code >= 9728 && code <= 10175 && !(code >= 10088 && code <= 10101) || code >= 11008 && code <= 11263 || code >= 127744 && code <= 129791 || isAmbiguousWideSymbolCode(code);
634
+ }
635
+ function isCjkQuoteCode(code) {
636
+ return code === 8220 || code === 8221 || code === 8216 || code === 8217;
637
+ }
638
+ function scanWidthNeeds(plain, locale) {
639
+ let hasNonAscii = false;
640
+ for (let i = 0; i < plain.length; i++) {
641
+ const cc = plain.charCodeAt(i);
642
+ if (isAmbiguousWideSymbolCode(cc)) {
643
+ return { hasNonAscii: true, hasCandidate: true };
644
+ }
645
+ if (cc < 8192) continue;
646
+ hasNonAscii = true;
647
+ let code = cc;
648
+ if (cc >= 55296 && cc <= 56319 && i + 1 < plain.length) {
649
+ const lo = plain.charCodeAt(i + 1);
650
+ if (lo >= 56320 && lo <= 57343) {
651
+ code = (cc - 55296) * 1024 + (lo - 56320) + 65536;
652
+ i += 1;
653
+ }
654
+ }
655
+ if (isForceWideSymbolCode(code) || locale === "zh" && isCjkQuoteCode(code)) {
656
+ return { hasNonAscii: true, hasCandidate: true };
403
657
  }
404
658
  }
659
+ return { hasNonAscii, hasCandidate: false };
660
+ }
661
+ var displayWidthCache = /* @__PURE__ */ new Map();
662
+ var DISPLAY_WIDTH_CACHE_MAX = 4096;
663
+ function displayWidth(str) {
664
+ const plain = stripAnsi2(str);
665
+ const locale = getCliLocale();
666
+ const needs = scanWidthNeeds(plain, locale);
667
+ if (!needs.hasNonAscii) {
668
+ return stringWidth(plain);
669
+ }
670
+ const key = locale + "\0" + plain;
671
+ const cached = displayWidthCache.get(key);
672
+ if (cached !== void 0) return cached;
673
+ const base = stringWidth(plain);
674
+ if (!needs.hasCandidate) {
675
+ if (displayWidthCache.size >= DISPLAY_WIDTH_CACHE_MAX) {
676
+ const eldest = displayWidthCache.keys().next().value;
677
+ if (eldest !== void 0) displayWidthCache.delete(eldest);
678
+ }
679
+ displayWidthCache.set(key, base);
680
+ return base;
681
+ }
682
+ let width = base;
683
+ for (const { segment } of graphemeSegmenter.segment(plain)) {
684
+ const code = segment.codePointAt(0) ?? 0;
685
+ if (isForceWideSymbolCode(code) || locale === "zh" && isCjkQuoteCode(code)) {
686
+ if (stringWidth(segment) === 1) width += 1;
687
+ }
688
+ }
689
+ if (displayWidthCache.size >= DISPLAY_WIDTH_CACHE_MAX) {
690
+ const eldest = displayWidthCache.keys().next().value;
691
+ if (eldest !== void 0) displayWidthCache.delete(eldest);
692
+ }
693
+ displayWidthCache.set(key, width);
405
694
  return width;
406
695
  }
407
696
  function visibleWidth(str) {
408
- return displayWidth(stripAnsi(str));
697
+ return displayWidth(stripAnsi2(str));
409
698
  }
410
699
  function truncateAnsi(text, maxWidth) {
411
700
  if (maxWidth <= 0) return "";
@@ -473,6 +762,7 @@ function padOrTruncateToWidth(text, width) {
473
762
  return `${text}${" ".repeat(width - textWidth)}`;
474
763
  }
475
764
  var SGR_RESET_REGEX = /^\x1b\[0?m$/;
765
+ var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
476
766
  function tokenizeAnsiLine(line) {
477
767
  const tokens = [];
478
768
  let index = 0;
@@ -480,28 +770,125 @@ function tokenizeAnsiLine(line) {
480
770
  if (line[index] === "\x1B") {
481
771
  const osc = line.slice(index).match(/^\x1b\]8;;[^\x07\x1b]*(?:\x07|\x1b\\)/);
482
772
  if (osc) {
483
- tokens.push({ kind: "sgr", value: osc[0], width: 0 });
773
+ tokens.push({ kind: "sgr", value: osc[0], width: 0, charIndex: index });
484
774
  index += osc[0].length;
485
775
  continue;
486
776
  }
487
777
  const sgr = SGR_SEQUENCE_REGEX.exec(line.slice(index));
488
778
  if (sgr) {
489
- tokens.push({ kind: "sgr", value: sgr[0], width: 0 });
779
+ tokens.push({ kind: "sgr", value: sgr[0], width: 0, charIndex: index });
490
780
  index += sgr[0].length;
491
781
  continue;
492
782
  }
783
+ const csi = line.slice(index).match(/^\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/);
784
+ if (csi) {
785
+ index += csi[0].length;
786
+ continue;
787
+ }
788
+ const escape = FIRST_ANSI_ESCAPE_REGEX.exec(line.slice(index));
789
+ if (escape?.index === 0) {
790
+ index += escape[0].length;
791
+ continue;
792
+ }
793
+ index += 1;
794
+ continue;
493
795
  }
494
- const codePoint = line.codePointAt(index) ?? 0;
495
- const value = String.fromCodePoint(codePoint);
496
- tokens.push({ kind: "char", value, width: displayWidth(value) });
497
- index += value.length;
796
+ let nextEsc = line.indexOf("\x1B", index);
797
+ if (nextEsc === -1) nextEsc = line.length;
798
+ const chunk = line.slice(index, nextEsc);
799
+ for (const item of graphemeSegmenter.segment(chunk)) {
800
+ tokens.push({
801
+ kind: "char",
802
+ value: item.segment,
803
+ width: displayWidth(item.segment),
804
+ charIndex: index + item.index
805
+ });
806
+ }
807
+ index = nextEsc;
498
808
  }
499
809
  return tokens;
500
810
  }
501
- function wrapTranscriptLine(line, columns, hangingIndent = "") {
502
- if (line === "") return [""];
811
+ function buildSourceMapping(rawLine, styledLine, prefixCharCount) {
812
+ let contentStart = 0;
813
+ const headingMatch = rawLine.match(/^(#{1,3})\s+(.+)$/);
814
+ let lineToParse = rawLine;
815
+ if (headingMatch) {
816
+ contentStart = headingMatch[1].length + 1;
817
+ while (contentStart < rawLine.length && rawLine[contentStart] === " ") contentStart++;
818
+ lineToParse = rawLine.slice(contentStart);
819
+ }
820
+ const INLINE_RE = /(\[([^\]]+)\]\(([^)\s]+)\)|`([^`]+)`|\*\*(.+?)\*\*|(?<!\*)\*([^*]+?)\*(?!\*)|~~([^~]+?)~~)/g;
821
+ const mapping = [];
822
+ let lastIdx = 0;
823
+ let match;
824
+ while ((match = INLINE_RE.exec(lineToParse)) !== null) {
825
+ const plainBefore = lineToParse.slice(lastIdx, match.index);
826
+ for (let c = 0; c < plainBefore.length; c++) {
827
+ mapping.push(contentStart + lastIdx + c);
828
+ }
829
+ const fullMatch = match[0];
830
+ if (match[2] !== void 0 && match[3] !== void 0) {
831
+ const linkText = match[2];
832
+ const linkUrl = match[3];
833
+ const textOffset = contentStart + match.index + 1;
834
+ for (let c = 0; c < linkText.length; c++) {
835
+ mapping.push(textOffset + c);
836
+ }
837
+ const parenOffset = textOffset + linkText.length;
838
+ mapping.push(parenOffset);
839
+ mapping.push(parenOffset + 1);
840
+ const urlOffset = parenOffset + 2;
841
+ for (let c = 0; c < linkUrl.length; c++) {
842
+ mapping.push(urlOffset + c);
843
+ }
844
+ mapping.push(urlOffset + linkUrl.length);
845
+ } else if (match[4] !== void 0) {
846
+ const codeText = match[4];
847
+ const codeOffset = contentStart + match.index + 1;
848
+ for (let c = 0; c < codeText.length; c++) {
849
+ mapping.push(codeOffset + c);
850
+ }
851
+ } else if (match[5] !== void 0) {
852
+ const boldText = match[5];
853
+ const boldOffset = contentStart + match.index + 2;
854
+ for (let c = 0; c < boldText.length; c++) {
855
+ mapping.push(boldOffset + c);
856
+ }
857
+ } else if (match[6] !== void 0) {
858
+ const italicText = match[6];
859
+ const italicOffset = contentStart + match.index + 1;
860
+ for (let c = 0; c < italicText.length; c++) {
861
+ mapping.push(italicOffset + c);
862
+ }
863
+ } else if (match[7] !== void 0) {
864
+ const strikeText = match[7];
865
+ const strikeOffset = contentStart + match.index + 2;
866
+ for (let c = 0; c < strikeText.length; c++) {
867
+ mapping.push(strikeOffset + c);
868
+ }
869
+ }
870
+ lastIdx = match.index + fullMatch.length;
871
+ }
872
+ const plainRest = lineToParse.slice(lastIdx);
873
+ for (let c = 0; c < plainRest.length; c++) {
874
+ mapping.push(contentStart + lastIdx + c);
875
+ }
876
+ return mapping;
877
+ }
878
+ function wrapTranscriptLineWithLayout(line, columns, hangingIndent = "", lineSourceStart = 0, prefixWidth = 0, prefixCharCount = 0, sourceMapping, rawLineLength) {
879
+ if (line === "") {
880
+ const rawLen = rawLineLength ?? 0;
881
+ return [
882
+ {
883
+ rendered: "",
884
+ sourceStart: lineSourceStart,
885
+ sourceEnd: lineSourceStart + rawLen,
886
+ prefixWidth
887
+ }
888
+ ];
889
+ }
503
890
  const tokens = tokenizeAnsiLine(line);
504
- const result = [];
891
+ const rows = [];
505
892
  let activeStyles = [];
506
893
  const applyStyleToken = (value) => {
507
894
  if (SGR_RESET_REGEX.test(value)) {
@@ -513,10 +900,11 @@ function wrapTranscriptLine(line, columns, hangingIndent = "") {
513
900
  let start = 0;
514
901
  while (start < tokens.length) {
515
902
  if (tokens.slice(start).every((token) => token.kind === "sgr")) {
516
- if (result.length > 0) break;
903
+ if (rows.length > 0) break;
517
904
  }
518
905
  const openingStyles = [...activeStyles];
519
- const isContinuation = result.length > 0 && hangingIndent.length > 0;
906
+ const isContinuation = rows.length > 0;
907
+ const currentPrefixWidth = isContinuation ? visibleWidth(hangingIndent) : prefixWidth;
520
908
  const indentWidth = isContinuation ? visibleWidth(hangingIndent) : 0;
521
909
  const maxSegmentWidth = Math.max(1, columns - indentWidth);
522
910
  let width = 0;
@@ -531,7 +919,7 @@ function wrapTranscriptLine(line, columns, hangingIndent = "") {
531
919
  if (width + token.width > maxSegmentWidth && width > 0) break;
532
920
  width += token.width;
533
921
  end += 1;
534
- if (token.value === " " || token.value === " ") {
922
+ if ((token.value === " " || token.value === " ") && token.charIndex >= prefixCharCount) {
535
923
  lastBreak = end;
536
924
  }
537
925
  }
@@ -556,21 +944,78 @@ function wrapTranscriptLine(line, columns, hangingIndent = "") {
556
944
  const prefix = openingStyles.join("");
557
945
  const needsReset = (sawStyle || activeStyles.length > 0) && !segment.endsWith("\x1B[0m");
558
946
  const lineContent = `${prefix}${segment}${needsReset ? "\x1B[0m" : ""}`;
559
- result.push(isContinuation ? `${hangingIndent}${lineContent}` : lineContent);
947
+ const rowRendered = isContinuation && hangingIndent.length > 0 ? `${hangingIndent}${lineContent}` : lineContent;
948
+ let segSourceStart = lineSourceStart;
949
+ let segSourceEnd = lineSourceStart;
950
+ let foundFirst = false;
951
+ const rowMapping = [];
952
+ let plainCharIndex = 0;
953
+ for (let i = 0; i < start; i++) {
954
+ const tok = tokens[i];
955
+ if (tok.kind === "char" && tok.charIndex >= prefixCharCount) {
956
+ plainCharIndex += tok.value.length;
957
+ }
958
+ }
959
+ for (let i = start; i < segmentEnd; i++) {
960
+ const tok = tokens[i];
961
+ if (tok.kind === "char" && tok.charIndex >= prefixCharCount) {
962
+ const mappedOffset = sourceMapping && sourceMapping[plainCharIndex] !== void 0 ? sourceMapping[plainCharIndex] : plainCharIndex;
963
+ if (!foundFirst) {
964
+ segSourceStart = lineSourceStart + mappedOffset;
965
+ foundFirst = true;
966
+ }
967
+ for (let c = 0; c < tok.value.length; c++) {
968
+ const idx = plainCharIndex + c;
969
+ const mapped = sourceMapping && sourceMapping[idx] !== void 0 ? sourceMapping[idx] : idx;
970
+ rowMapping.push(lineSourceStart + mapped);
971
+ }
972
+ const lastCharIdx = plainCharIndex + tok.value.length - 1;
973
+ const mappedEndOffset = sourceMapping && sourceMapping[lastCharIdx] !== void 0 ? sourceMapping[lastCharIdx] + 1 : plainCharIndex + tok.value.length;
974
+ segSourceEnd = lineSourceStart + mappedEndOffset;
975
+ plainCharIndex += tok.value.length;
976
+ }
977
+ }
560
978
  start = segmentEnd;
979
+ let softWrapJoiner = "";
561
980
  while (start < tokens.length) {
562
981
  const token = tokens[start];
563
- if (token.kind === "char" && token.value === " ") {
982
+ if (token.kind === "char" && token.value === " " && token.charIndex >= prefixCharCount) {
983
+ softWrapJoiner += token.value;
984
+ const mappedOffset = sourceMapping && sourceMapping[plainCharIndex] !== void 0 ? sourceMapping[plainCharIndex] + 1 : plainCharIndex + 1;
985
+ segSourceEnd = lineSourceStart + mappedOffset;
986
+ plainCharIndex += token.value.length;
564
987
  start += 1;
565
988
  continue;
566
989
  }
567
990
  break;
568
991
  }
992
+ if (start >= tokens.length && rawLineLength !== void 0) {
993
+ segSourceEnd = lineSourceStart + rawLineLength;
994
+ }
995
+ rows.push({
996
+ rendered: rowRendered,
997
+ sourceStart: segSourceStart,
998
+ sourceEnd: segSourceEnd,
999
+ prefixWidth: currentPrefixWidth,
1000
+ sourceMapping: rowMapping.length > 0 ? rowMapping : void 0,
1001
+ softWrapped: start < tokens.length,
1002
+ softWrapJoiner
1003
+ });
569
1004
  }
570
- return result.length > 0 ? result : [""];
1005
+ return rows.length > 0 ? rows : [
1006
+ {
1007
+ rendered: "",
1008
+ sourceStart: lineSourceStart,
1009
+ sourceEnd: lineSourceStart + (rawLineLength ?? 0),
1010
+ prefixWidth
1011
+ }
1012
+ ];
1013
+ }
1014
+ function wrapTranscriptLine(line, columns, hangingIndent = "") {
1015
+ return wrapTranscriptLineWithLayout(line, columns, hangingIndent).map((r) => r.rendered);
571
1016
  }
572
1017
  function buildWindowTitle(title) {
573
- const plain = stripAnsi(title).replace(/[\x00-\x1f\x7f]+/g, " ");
1018
+ const plain = stripAnsi2(title).replace(/[\x00-\x1f\x7f]+/g, " ");
574
1019
  let truncated = "";
575
1020
  let width = 0;
576
1021
  const maxCols = 80;
@@ -749,12 +1194,17 @@ function setActiveThemeName(name) {
749
1194
  }
750
1195
  return false;
751
1196
  }
752
- var activeBrightness = null;
753
- function getActiveBrightness() {
754
- return activeBrightness;
1197
+ var activeThemeMode = "terminal";
1198
+ var resolvedBrightness = null;
1199
+ function getActiveThemeMode() {
1200
+ return activeThemeMode;
1201
+ }
1202
+ function setActiveThemeMode(mode) {
1203
+ activeThemeMode = mode;
1204
+ if (mode === "terminal") resolvedBrightness = null;
755
1205
  }
756
1206
  function setActiveBrightness(brightness) {
757
- activeBrightness = brightness;
1207
+ setActiveThemeMode(brightness ?? "terminal");
758
1208
  }
759
1209
  var activeDensity = "spacious";
760
1210
  function getActiveDensity() {
@@ -797,7 +1247,8 @@ function resolveTuiBrightness(env = process.env) {
797
1247
  const explicit = (env.NOLO_TUI_THEME ?? "").trim().toLowerCase();
798
1248
  if (explicit === "light") return "light";
799
1249
  if (explicit === "dark") return "dark";
800
- if (activeBrightness) return activeBrightness;
1250
+ if (activeThemeMode !== "terminal") return activeThemeMode;
1251
+ if (resolvedBrightness) return resolvedBrightness;
801
1252
  const colorfgbg = env.COLORFGBG ?? "";
802
1253
  if (colorfgbg) {
803
1254
  const parts = colorfgbg.split(";");
@@ -809,6 +1260,12 @@ function resolveTuiBrightness(env = process.env) {
809
1260
  if (sys) return sys;
810
1261
  return "dark";
811
1262
  }
1263
+ function resolveTuiThemeMode(env = process.env, fallback = activeThemeMode) {
1264
+ const explicit = (env.NOLO_TUI_THEME ?? "").trim().toLowerCase();
1265
+ if (explicit === "light" || explicit === "dark") return explicit;
1266
+ if (explicit === "terminal" || explicit === "auto") return "terminal";
1267
+ return fallback;
1268
+ }
812
1269
  function hexToSgr(hex) {
813
1270
  const r = Number.parseInt(hex.slice(0, 2), 16);
814
1271
  const g = Number.parseInt(hex.slice(2, 4), 16);
@@ -835,11 +1292,15 @@ function setActiveTerminalBaseHex(hex) {
835
1292
  }
836
1293
  activeTerminalBaseHex = readHexChannels(hex.replace(/^#/, "").toUpperCase()) ? hex.replace(/^#/, "").toUpperCase() : null;
837
1294
  }
1295
+ function resetWorkspaceThemeState() {
1296
+ setActiveThemeMode("terminal");
1297
+ setActiveTerminalBaseHex(null);
1298
+ }
838
1299
  function applyDetectedBackground(detected) {
839
1300
  const normalizedHex = detected.hex.replace(/^#/, "").toUpperCase();
840
1301
  const hexChanged = normalizedHex !== "" && normalizedHex !== activeTerminalBaseHex;
841
- const changed = detected.brightness !== activeBrightness || hexChanged;
842
- setActiveBrightness(detected.brightness);
1302
+ const changed = detected.brightness !== resolvedBrightness || hexChanged;
1303
+ resolvedBrightness = detected.brightness;
843
1304
  setActiveTerminalBaseHex(detected.hex);
844
1305
  return changed;
845
1306
  }
@@ -879,6 +1340,7 @@ function blendHex(fg, base, weight) {
879
1340
  return `${r}${g}${b}`;
880
1341
  }
881
1342
  function diffLineSequences(env = process.env, brightness = resolveTuiBrightness(env)) {
1343
+ if (resolveTuiThemeMode(env) === "terminal") return null;
882
1344
  if (!supportsTruecolor(env)) return null;
883
1345
  const palette = THEME_PALETTES[activeThemeName] ?? THEME_PALETTES.trail;
884
1346
  const successHex = palette[brightness].success.hex;
@@ -937,10 +1399,12 @@ function renderDiffLine(args) {
937
1399
  });
938
1400
  }
939
1401
  function surfaceBackgroundSequence(env = process.env, brightness = resolveTuiBrightness(env)) {
1402
+ if (resolveTuiThemeMode(env) === "terminal") return "";
940
1403
  if (!supportsTruecolor(env)) return "";
941
1404
  return hexToBgSgr((SURFACE_HEX[activeThemeName] ?? SURFACE_HEX.trail)[brightness]);
942
1405
  }
943
1406
  function userSurfaceBackgroundSequence(env = process.env, brightness = resolveTuiBrightness(env)) {
1407
+ if (resolveTuiThemeMode(env) === "terminal") return "";
944
1408
  if (!supportsTruecolor(env)) return "";
945
1409
  const palette = THEME_PALETTES[activeThemeName] ?? THEME_PALETTES.trail;
946
1410
  const accentHex = palette[brightness].accent.hex;
@@ -950,12 +1414,18 @@ function userSurfaceBackgroundSequence(env = process.env, brightness = resolveTu
950
1414
  function themeColorSequence(token, env = process.env, brightness = resolveTuiBrightness(env)) {
951
1415
  const palette = THEME_PALETTES[activeThemeName] ?? THEME_PALETTES.trail;
952
1416
  const entry = palette[brightness][token];
953
- return supportsTruecolor(env) ? hexToSgr(entry.hex) : entry.ansiFallback;
1417
+ return resolveTuiThemeMode(env) !== "terminal" && supportsTruecolor(env) ? hexToSgr(entry.hex) : entry.ansiFallback;
954
1418
  }
955
1419
  function themeText(text, token, colorEnabled = resolveCliColorEnabled(), env = process.env) {
956
1420
  if (!colorEnabled) return text;
957
1421
  return `${themeColorSequence(token, env)}${text}\x1B[39m`;
958
1422
  }
1423
+ function tuiRenderThemeFingerprint(colorEnabled, env = process.env) {
1424
+ const mode = resolveTuiThemeMode(env);
1425
+ const colorKind = !colorEnabled ? "plain" : mode !== "terminal" && supportsTruecolor(env) ? "truecolor" : "ansi";
1426
+ const surface = colorEnabled ? userSurfaceBackgroundSequence(env) : "";
1427
+ return `${activeThemeName}|${mode}|${colorKind}|${surface}`;
1428
+ }
959
1429
  function classifyDiffLine(line) {
960
1430
  if (line.startsWith("@@")) return "hunk";
961
1431
  if (line.startsWith("+") && !line.startsWith("+++")) return "added";
@@ -963,8 +1433,850 @@ function classifyDiffLine(line) {
963
1433
  return "context";
964
1434
  }
965
1435
 
966
- // packages/cli/client/assistantOutput.ts
1436
+ // packages/cli/client/mermaid.ts
967
1437
  var STYLE = {
1438
+ reset: "\x1B[0m"
1439
+ };
1440
+ function maskLabelSpans(line, restores = []) {
1441
+ const text = line.replace(
1442
+ /("[^"\n]*"|\[[^\]\n]*\]|\{[^}\n]*\}|\([^()\n]*\)|\|[^|\n]*\|)/g,
1443
+ (m) => {
1444
+ const idx = restores.push(m) - 1;
1445
+ return `\0M${idx}\0`;
1446
+ }
1447
+ );
1448
+ return { text, restores };
1449
+ }
1450
+ function unmask(masked, restores) {
1451
+ return masked.replace(/\x00M(\d+)\x00/g, (_, i) => restores[+i] ?? "");
1452
+ }
1453
+ function decodeShape(rest) {
1454
+ let lm;
1455
+ if (lm = rest.match(/^\[\s*"([^"]*)"\s*\]/)) return { shape: "rect", label: lm[1] };
1456
+ if (lm = rest.match(/^\(\s*\(\s*"?([^"()]*)"?\s*\)\s*\)/)) return { shape: "stadium", label: lm[1] };
1457
+ if (lm = rest.match(/^\(\s*\[\s*"?([^"()]*)"?\s*\]\s*\)/)) return { shape: "stadium", label: lm[1] };
1458
+ if (lm = rest.match(/^\[\s*([^\[\]]+)\s*\]/)) return { shape: "rect", label: lm[1] };
1459
+ if (lm = rest.match(/^\{\s*([^}]*)\s*\}/)) return { shape: "diamond", label: lm[1] };
1460
+ if (lm = rest.match(/^\(\s*"?([^[\]()]*)"?\s*\)/)) return { shape: "rounded", label: lm[1] };
1461
+ return null;
1462
+ }
1463
+ function parseNodeSeg(seg) {
1464
+ const t2 = seg.trim();
1465
+ if (!t2) return null;
1466
+ const m = t2.match(/^([A-Za-z_][A-Za-z0-9_-]*)(.*)$/s);
1467
+ if (!m) return null;
1468
+ const id = m[1];
1469
+ const rest = m[2].trim();
1470
+ if (rest && decodeShape(rest) === null) return null;
1471
+ const dec = decodeShape(rest);
1472
+ return { id, shape: dec ? dec.shape : "rect", label: (dec ? dec.label : id).trim() || id };
1473
+ }
1474
+ function stripComment(line) {
1475
+ const idx = line.indexOf("%%");
1476
+ return (idx >= 0 ? line.slice(0, idx) : line).trim().replace(/[,;]\s*$/, "");
1477
+ }
1478
+ var DIAGRAM_HEADERS = /^\s*(graph|flowchart|subgraph|end)\b|^\s*(sequenceDiagram|sequence|gantt|classDiagram|stateDiagram|erDiagram|requirementDiagram|pie|journey|mindmap|sankey|timeline)\b/;
1479
+ function parseMermaid(source) {
1480
+ const nodes = /* @__PURE__ */ new Map();
1481
+ const edges = [];
1482
+ const skipped = [];
1483
+ const parseStatement = (maskedStmt, restores) => {
1484
+ const parts = maskedStmt.split(/-->/);
1485
+ if (parts.length < 2) {
1486
+ const parsed = parseNodeSeg(unmask(parts[0], restores).trim());
1487
+ if (parsed) {
1488
+ nodes.set(parsed.id, { id: parsed.id, label: parsed.label, shape: parsed.shape });
1489
+ return true;
1490
+ }
1491
+ return false;
1492
+ }
1493
+ const lineNodes = /* @__PURE__ */ new Map();
1494
+ const lineEdges = [];
1495
+ let ok = true;
1496
+ let fromPrev = null;
1497
+ for (let i = 0; i < parts.length; i++) {
1498
+ let seg = parts[i];
1499
+ let label;
1500
+ if (i > 0) {
1501
+ const restored = unmask(seg, restores);
1502
+ const pm = restored.match(/^\|\s*([^|]*)\s*\|([\s\S]*)$/);
1503
+ if (pm) {
1504
+ label = pm[1].trim() || void 0;
1505
+ seg = pm[2];
1506
+ }
1507
+ }
1508
+ const nodeText = unmask(seg, restores).trim();
1509
+ const parsed = parseNodeSeg(nodeText);
1510
+ if (!parsed) {
1511
+ ok = false;
1512
+ break;
1513
+ }
1514
+ const prev = lineNodes.get(parsed.id);
1515
+ lineNodes.set(parsed.id, {
1516
+ id: parsed.id,
1517
+ label: parsed.label !== parsed.id && parsed.label ? parsed.label : prev?.label ?? parsed.label,
1518
+ shape: parsed.shape !== "rect" ? parsed.shape : prev?.shape ?? parsed.shape
1519
+ });
1520
+ if (i > 0 && fromPrev !== null) lineEdges.push({ from: fromPrev, to: parsed.id, label });
1521
+ fromPrev = parsed.id;
1522
+ }
1523
+ if (!ok) return false;
1524
+ for (const [id, n] of lineNodes) {
1525
+ const cur = nodes.get(id);
1526
+ if (cur) {
1527
+ if (n.label !== id) cur.label = n.label;
1528
+ if (n.shape !== "rect") cur.shape = n.shape;
1529
+ } else nodes.set(id, n);
1530
+ }
1531
+ for (const e of lineEdges) edges.push(e);
1532
+ return true;
1533
+ };
1534
+ for (const raw of source.split("\n")) {
1535
+ const line = stripComment(raw);
1536
+ if (!line) continue;
1537
+ if (DIAGRAM_HEADERS.test(line)) continue;
1538
+ const restores = [];
1539
+ const { text: masked1 } = maskLabelSpans(line, restores);
1540
+ let norm = masked1.replace(/-{2,}>/g, "-->");
1541
+ norm = norm.replace(/\.?-[.]?->/g, "-->");
1542
+ norm = norm.replace(/={2,}>/g, "-->");
1543
+ norm = norm.replace(/--\s*([^>]+?)\s*-->/g, "-->|$1|");
1544
+ const { text: masked } = maskLabelSpans(norm, restores);
1545
+ const stmts = masked.split(";").map((s) => s.trim()).filter(Boolean);
1546
+ const results = stmts.map((s) => parseStatement(s, restores));
1547
+ if (results.some((r) => !r)) {
1548
+ skipped.push(raw.trim());
1549
+ }
1550
+ }
1551
+ return { nodes, edges, skipped };
1552
+ }
1553
+ function assignLayers(flow) {
1554
+ const layer = /* @__PURE__ */ new Map();
1555
+ const adj = /* @__PURE__ */ new Map();
1556
+ const indeg = /* @__PURE__ */ new Map();
1557
+ for (const id of flow.nodes.keys()) {
1558
+ adj.set(id, []);
1559
+ indeg.set(id, 0);
1560
+ }
1561
+ for (const e of flow.edges) {
1562
+ adj.get(e.from)?.push(e.to);
1563
+ indeg.set(e.to, (indeg.get(e.to) ?? 0) + 1);
1564
+ }
1565
+ const queue = [];
1566
+ for (const [id, d] of indeg) {
1567
+ if (d === 0) {
1568
+ layer.set(id, 0);
1569
+ queue.push(id);
1570
+ }
1571
+ }
1572
+ let head = 0;
1573
+ while (head < queue.length) {
1574
+ const cur = queue[head++];
1575
+ const l = layer.get(cur) ?? 0;
1576
+ for (const next of adj.get(cur) ?? []) {
1577
+ if ((layer.get(next) ?? 0) < l + 1) {
1578
+ layer.set(next, l + 1);
1579
+ queue.push(next);
1580
+ }
1581
+ }
1582
+ }
1583
+ if (queue.length === 0) {
1584
+ for (const id of flow.nodes.keys()) if (!layer.has(id)) layer.set(id, 0);
1585
+ }
1586
+ return layer;
1587
+ }
1588
+ function wrapLabel(label, width) {
1589
+ const clean = label.replace(/\s+/g, " ").trim();
1590
+ if (!clean) return [""];
1591
+ if (clean.length <= width) return [clean];
1592
+ const words = clean.split(" ");
1593
+ const lines = [];
1594
+ let cur = "";
1595
+ for (const w of words) {
1596
+ if ((cur + " " + w).trim().length > width && cur) {
1597
+ lines.push(cur);
1598
+ cur = w;
1599
+ } else {
1600
+ cur = cur ? cur + " " + w : w;
1601
+ }
1602
+ }
1603
+ if (cur) lines.push(cur);
1604
+ return lines;
1605
+ }
1606
+ function boxCorners(shape) {
1607
+ switch (shape) {
1608
+ case "diamond":
1609
+ return { l: "<", r: ">" };
1610
+ case "rounded":
1611
+ case "stadium":
1612
+ return { l: "(", r: ")" };
1613
+ case "parallelogram":
1614
+ return { l: "/", r: "\\" };
1615
+ default:
1616
+ return { l: "[", r: "]" };
1617
+ }
1618
+ }
1619
+ function drawBox(node, width, accent) {
1620
+ const inner = wrapLabel(node.label, Math.max(1, width - 2));
1621
+ const { l, r } = boxCorners(node.shape);
1622
+ const rows = [];
1623
+ rows.push(accent(l + "\u2500".repeat(width) + r));
1624
+ for (const text of inner) {
1625
+ const pad = " ".repeat(Math.max(0, width - 2 - text.length));
1626
+ rows.push(accent(l + " " + text + pad + " " + r));
1627
+ }
1628
+ rows.push(accent(l + "\u2500".repeat(width) + r));
1629
+ return rows;
1630
+ }
1631
+ function renderMermaid(flow, brightness, colorEnabled = true) {
1632
+ const accentTok = themeColorSequence("accent", process.env, brightness);
1633
+ const warningTok = themeColorSequence("warning", process.env, brightness);
1634
+ const mutedTok = themeColorSequence("muted", process.env, brightness);
1635
+ const wrap = (s, tok) => colorEnabled ? `${tok}${s}${STYLE.reset}` : s;
1636
+ const cAccent = (s) => wrap(s, accentTok);
1637
+ const cWarn = (s) => wrap(s, warningTok);
1638
+ const cMuted = (s) => wrap(s, mutedTok);
1639
+ if (flow.nodes.size === 0) {
1640
+ const sk = flow.skipped.join("\n");
1641
+ return cMuted("(empty mermaid diagram)") + (sk ? "\n" + cMuted(sk) : "");
1642
+ }
1643
+ const layers = assignLayers(flow);
1644
+ const maxLayer = Math.max(...Array.from(layers.values(), (v) => v));
1645
+ const byLayer = [];
1646
+ for (let l = 0; l <= maxLayer; l++) byLayer.push([]);
1647
+ for (const [id] of flow.nodes) byLayer[layers.get(id) ?? 0].push(id);
1648
+ const width = Math.max(
1649
+ 8,
1650
+ ...Array.from(flow.nodes.values(), (n) => n.label.length + 2)
1651
+ );
1652
+ const GAP = 3;
1653
+ const edgeLabel = /* @__PURE__ */ new Map();
1654
+ for (const e of flow.edges) {
1655
+ if (e.label && !edgeLabel.has(`${e.from}:${e.to}`)) {
1656
+ edgeLabel.set(`${e.from}:${e.to}`, e.label);
1657
+ }
1658
+ }
1659
+ const out = [];
1660
+ for (let l = 0; l <= maxLayer; l++) {
1661
+ const layerIds = byLayer[l] ?? [];
1662
+ if (layerIds.length === 0) continue;
1663
+ const boxes = layerIds.map((id) => drawBox(flow.nodes.get(id), width, cAccent));
1664
+ const boxHeight = Math.max(...boxes.map((b) => b.length));
1665
+ const colStart = (bi) => bi * (width + GAP);
1666
+ for (let r = 0; r < boxHeight; r++) {
1667
+ let line = "";
1668
+ boxes.forEach((b, bi) => {
1669
+ const cell = b[r] ?? b[b.length - 1];
1670
+ const col = colStart(bi);
1671
+ if (line.length < col) line += " ".repeat(col - line.length);
1672
+ line += cell;
1673
+ });
1674
+ out.push(line);
1675
+ }
1676
+ if (l < maxLayer) {
1677
+ const down = layerIds.map(
1678
+ (id) => flow.edges.some(
1679
+ (e) => e.from === id && (layers.get(e.to) ?? -1) === l + 1
1680
+ )
1681
+ );
1682
+ if (down.some(Boolean)) {
1683
+ let stemRow = "";
1684
+ layerIds.forEach((_, bi) => {
1685
+ if (!down[bi]) return;
1686
+ const mid = colStart(bi) + Math.floor(width / 2);
1687
+ if (stemRow.length < mid) stemRow += " ".repeat(mid - stemRow.length);
1688
+ stemRow += "\u2502";
1689
+ });
1690
+ out.push(stemRow);
1691
+ let arrowRow = "";
1692
+ layerIds.forEach((_, bi) => {
1693
+ if (!down[bi]) return;
1694
+ const mid = colStart(bi) + Math.floor(width / 2);
1695
+ if (arrowRow.length < mid) arrowRow += " ".repeat(mid - arrowRow.length);
1696
+ arrowRow += cWarn("\u25BC");
1697
+ });
1698
+ out.push(arrowRow);
1699
+ const labels = layerIds.flatMap((id, bi) => {
1700
+ if (!down[bi]) return [];
1701
+ return flow.edges.filter((e) => e.from === id && (layers.get(e.to) ?? -1) === l + 1).map((e) => edgeLabel.get(`${e.from}:${e.to}`)).filter((t2) => !!t2);
1702
+ });
1703
+ if (labels.length > 0) {
1704
+ out.push(cMuted(" \u2937 " + labels.join(" / ")));
1705
+ }
1706
+ }
1707
+ }
1708
+ }
1709
+ if (flow.skipped.length > 0) {
1710
+ out.push(cMuted("(skipped)"));
1711
+ for (const s of flow.skipped) out.push(cMuted(s));
1712
+ }
1713
+ return out.join("\n");
1714
+ }
1715
+ function renderMermaidBlock(source, brightness, colorEnabled = true) {
1716
+ const flow = parseMermaid(source);
1717
+ if (flow.nodes.size === 0) {
1718
+ return source;
1719
+ }
1720
+ return renderMermaid(flow, brightness, colorEnabled);
1721
+ }
1722
+
1723
+ // packages/cli/client/mathText.ts
1724
+ var mathRenderingEnabled = true;
1725
+ function setMathRenderingEnabled(enabled) {
1726
+ mathRenderingEnabled = enabled;
1727
+ }
1728
+ var GREEK_LETTERS = {
1729
+ alpha: "\u03B1",
1730
+ beta: "\u03B2",
1731
+ gamma: "\u03B3",
1732
+ delta: "\u03B4",
1733
+ epsilon: "\u03B5",
1734
+ varepsilon: "\u03B5",
1735
+ zeta: "\u03B6",
1736
+ eta: "\u03B7",
1737
+ theta: "\u03B8",
1738
+ vartheta: "\u03B8",
1739
+ iota: "\u03B9",
1740
+ kappa: "\u03BA",
1741
+ lambda: "\u03BB",
1742
+ mu: "\u03BC",
1743
+ nu: "\u03BD",
1744
+ xi: "\u03BE",
1745
+ omicron: "\u03BF",
1746
+ pi: "\u03C0",
1747
+ varpi: "\u03C0",
1748
+ rho: "\u03C1",
1749
+ varrho: "\u03C1",
1750
+ sigma: "\u03C3",
1751
+ varsigma: "\u03C3",
1752
+ tau: "\u03C4",
1753
+ upsilon: "\u03C5",
1754
+ phi: "\u03C6",
1755
+ varphi: "\u03C6",
1756
+ chi: "\u03C7",
1757
+ psi: "\u03C8",
1758
+ omega: "\u03C9",
1759
+ Gamma: "\u0393",
1760
+ Delta: "\u0394",
1761
+ Theta: "\u0398",
1762
+ Lambda: "\u039B",
1763
+ Xi: "\u039E",
1764
+ Pi: "\u03A0",
1765
+ Sigma: "\u03A3",
1766
+ Upsilon: "\u03A5",
1767
+ Phi: "\u03A6",
1768
+ Psi: "\u03A8",
1769
+ Omega: "\u03A9"
1770
+ };
1771
+ var OPERATORS_AND_SYMBOLS = {
1772
+ // Operators
1773
+ times: "\xD7",
1774
+ div: "\xF7",
1775
+ pm: "\xB1",
1776
+ mp: "\u2213",
1777
+ cdot: "\xB7",
1778
+ bullet: "\xB7",
1779
+ circ: "\u2218",
1780
+ ast: "*",
1781
+ star: "\u2605",
1782
+ // Relations
1783
+ leq: "\u2264",
1784
+ le: "\u2264",
1785
+ geq: "\u2265",
1786
+ ge: "\u2265",
1787
+ neq: "\u2260",
1788
+ ne: "\u2260",
1789
+ approx: "\u2248",
1790
+ equiv: "\u2261",
1791
+ sim: "\u223C",
1792
+ simeq: "\u2243",
1793
+ cong: "\u2245",
1794
+ propto: "\u221D",
1795
+ ll: "\u226A",
1796
+ gg: "\u226B",
1797
+ // Arrows
1798
+ to: "\u2192",
1799
+ rightarrow: "\u2192",
1800
+ longrightarrow: "\u2192",
1801
+ gets: "\u2190",
1802
+ leftarrow: "\u2190",
1803
+ longleftarrow: "\u2190",
1804
+ Rightarrow: "\u21D2",
1805
+ implies: "\u21D2",
1806
+ Longrightarrow: "\u21D2",
1807
+ Leftarrow: "\u21D0",
1808
+ Longleftarrow: "\u21D0",
1809
+ Leftrightarrow: "\u21D4",
1810
+ iff: "\u21D4",
1811
+ Longleftrightarrow: "\u21D4",
1812
+ leftrightarrow: "\u2194",
1813
+ uparrow: "\u2191",
1814
+ downarrow: "\u2193",
1815
+ mapsto: "\u21A6",
1816
+ // Sets & Logic
1817
+ in: "\u2208",
1818
+ notin: "\u2209",
1819
+ ni: "\u220B",
1820
+ owns: "\u220B",
1821
+ subset: "\u2282",
1822
+ supset: "\u2283",
1823
+ subseteq: "\u2286",
1824
+ supseteq: "\u2287",
1825
+ cap: "\u2229",
1826
+ cup: "\u222A",
1827
+ setminus: "\\",
1828
+ emptyset: "\u2205",
1829
+ varnothing: "\u2205",
1830
+ forall: "\u2200",
1831
+ exists: "\u2203",
1832
+ nexists: "\u2204",
1833
+ land: "\u2227",
1834
+ wedge: "\u2227",
1835
+ lor: "\u2228",
1836
+ vee: "\u2228",
1837
+ neg: "\xAC",
1838
+ lnot: "\xAC",
1839
+ top: "\u22A4",
1840
+ bot: "\u22A5",
1841
+ // Calculus & Special
1842
+ infty: "\u221E",
1843
+ inf: "\u221E",
1844
+ partial: "\u2202",
1845
+ nabla: "\u2207",
1846
+ angle: "\u2220",
1847
+ perp: "\u22A5",
1848
+ degree: "\xB0",
1849
+ prime: "\u2032",
1850
+ hbar: "\u0127",
1851
+ ell: "\u2113",
1852
+ Re: "\u211C",
1853
+ Im: "\u2111",
1854
+ aleph: "\u2135",
1855
+ // Punctuation dots
1856
+ dots: "\u2026",
1857
+ ldots: "\u2026",
1858
+ cdots: "\u2026",
1859
+ vdots: "\u22EE",
1860
+ ddots: "\u22F1",
1861
+ // Large operators
1862
+ sum: "\u2211",
1863
+ prod: "\u220F",
1864
+ coprod: "\u2210",
1865
+ int: "\u222B",
1866
+ iint: "\u222C",
1867
+ iiint: "\u222D",
1868
+ oint: "\u222E"
1869
+ };
1870
+ var SUPERSCRIPTS = {
1871
+ "0": "\u2070",
1872
+ "1": "\xB9",
1873
+ "2": "\xB2",
1874
+ "3": "\xB3",
1875
+ "4": "\u2074",
1876
+ "5": "\u2075",
1877
+ "6": "\u2076",
1878
+ "7": "\u2077",
1879
+ "8": "\u2078",
1880
+ "9": "\u2079",
1881
+ "+": "\u207A",
1882
+ "-": "\u207B",
1883
+ "=": "\u207C",
1884
+ "(": "\u207D",
1885
+ ")": "\u207E",
1886
+ a: "\u1D43",
1887
+ b: "\u1D47",
1888
+ c: "\u1D9C",
1889
+ d: "\u1D48",
1890
+ e: "\u1D49",
1891
+ f: "\u1DA0",
1892
+ g: "\u1D4D",
1893
+ h: "\u02B0",
1894
+ i: "\u2071",
1895
+ j: "\u02B2",
1896
+ k: "\u1D4F",
1897
+ l: "\u02E1",
1898
+ m: "\u1D50",
1899
+ n: "\u207F",
1900
+ o: "\u1D52",
1901
+ p: "\u1D56",
1902
+ r: "\u02B3",
1903
+ s: "\u02E2",
1904
+ t: "\u1D57",
1905
+ u: "\u1D58",
1906
+ v: "\u1D5B",
1907
+ w: "\u02B7",
1908
+ x: "\u02E3",
1909
+ y: "\u02B8",
1910
+ z: "\u1DBB",
1911
+ A: "\u1D2C",
1912
+ B: "\u1D2E",
1913
+ D: "\u1D30",
1914
+ E: "\u1D31",
1915
+ G: "\u1D33",
1916
+ H: "\u1D34",
1917
+ I: "\u1D35",
1918
+ J: "\u1D36",
1919
+ K: "\u1D37",
1920
+ L: "\u1D38",
1921
+ M: "\u1D39",
1922
+ N: "\u1D3A",
1923
+ O: "\u1D3C",
1924
+ P: "\u1D3E",
1925
+ R: "\u1D3F",
1926
+ T: "\u1D40",
1927
+ U: "\u1D41",
1928
+ V: "\u2C7D",
1929
+ W: "\u1D42"
1930
+ };
1931
+ var SUBSCRIPTS = {
1932
+ "0": "\u2080",
1933
+ "1": "\u2081",
1934
+ "2": "\u2082",
1935
+ "3": "\u2083",
1936
+ "4": "\u2084",
1937
+ "5": "\u2085",
1938
+ "6": "\u2086",
1939
+ "7": "\u2087",
1940
+ "8": "\u2088",
1941
+ "9": "\u2089",
1942
+ "+": "\u208A",
1943
+ "-": "\u208B",
1944
+ "=": "\u208C",
1945
+ "(": "\u208D",
1946
+ ")": "\u208E",
1947
+ a: "\u2090",
1948
+ e: "\u2091",
1949
+ h: "\u2095",
1950
+ i: "\u1D62",
1951
+ j: "\u2C7C",
1952
+ k: "\u2096",
1953
+ l: "\u2097",
1954
+ m: "\u2098",
1955
+ n: "\u2099",
1956
+ o: "\u2092",
1957
+ p: "\u209A",
1958
+ r: "\u1D63",
1959
+ s: "\u209B",
1960
+ t: "\u209C",
1961
+ u: "\u1D64",
1962
+ v: "\u1D65",
1963
+ x: "\u2093"
1964
+ };
1965
+ function hasUnsupportedLatex(latex) {
1966
+ if (/\\(newcommand|renewcommand|def|let)\b/.test(latex)) {
1967
+ return true;
1968
+ }
1969
+ if (/\\begin\s*\{/.test(latex)) {
1970
+ return true;
1971
+ }
1972
+ return false;
1973
+ }
1974
+ function extractBalancedBraces(text, startIndex) {
1975
+ if (text[startIndex] !== "{") return null;
1976
+ let depth = 0;
1977
+ for (let i = startIndex; i < text.length; i++) {
1978
+ if (text[i] === "{") {
1979
+ depth++;
1980
+ } else if (text[i] === "}") {
1981
+ depth--;
1982
+ if (depth === 0) {
1983
+ return { content: text.slice(startIndex + 1, i), endIndex: i };
1984
+ }
1985
+ }
1986
+ }
1987
+ return null;
1988
+ }
1989
+ function extractBalancedBrackets(text, startIndex) {
1990
+ if (text[startIndex] !== "[") return null;
1991
+ let depth = 0;
1992
+ for (let i = startIndex; i < text.length; i++) {
1993
+ if (text[i] === "[") {
1994
+ depth++;
1995
+ } else if (text[i] === "]") {
1996
+ depth--;
1997
+ if (depth === 0) {
1998
+ return { content: text.slice(startIndex + 1, i), endIndex: i };
1999
+ }
2000
+ }
2001
+ }
2002
+ return null;
2003
+ }
2004
+ function toSuperscriptString(raw) {
2005
+ let res = "";
2006
+ for (const char of raw) {
2007
+ const s = SUPERSCRIPTS[char];
2008
+ if (!s) return null;
2009
+ res += s;
2010
+ }
2011
+ return res;
2012
+ }
2013
+ function toSubscriptString(raw) {
2014
+ let res = "";
2015
+ for (const char of raw) {
2016
+ const s = SUBSCRIPTS[char];
2017
+ if (!s) return null;
2018
+ res += s;
2019
+ }
2020
+ return res;
2021
+ }
2022
+ function transpileLatexToUnicode(latex) {
2023
+ if (!mathRenderingEnabled) return latex;
2024
+ const trimmed = latex.trim();
2025
+ if (!trimmed) return "";
2026
+ if (hasUnsupportedLatex(trimmed)) {
2027
+ return trimmed;
2028
+ }
2029
+ let s = trimmed;
2030
+ s = s.replace(/\\left\s*\\\{/g, "{").replace(/\\right\s*\\\}/g, "}").replace(/\\left\s*([(\[|.])?/g, (_, p) => p === "." ? "" : p ?? "").replace(/\\right\s*([)\]|.])?/g, (_, p) => p === "." ? "" : p ?? "");
2031
+ s = s.replace(/\\(?:text|mathrm|mathbf|mathit|operatorname|mathtt|mathsf)\s*\{([^}]*)\}/g, "$1");
2032
+ s = s.replace(/\\qquad/g, " ").replace(/\\quad/g, " ").replace(/\\[,;:!]/g, " ").replace(/\\ /g, " ");
2033
+ while (s.includes("\\frac")) {
2034
+ const idx = s.indexOf("\\frac");
2035
+ let afterFrac = idx + 5;
2036
+ while (afterFrac < s.length && /\s/.test(s[afterFrac] ?? "")) afterFrac++;
2037
+ const numMatch = extractBalancedBraces(s, afterFrac);
2038
+ if (!numMatch) break;
2039
+ let afterNum = numMatch.endIndex + 1;
2040
+ while (afterNum < s.length && /\s/.test(s[afterNum] ?? "")) afterNum++;
2041
+ const denMatch = extractBalancedBraces(s, afterNum);
2042
+ if (!denMatch) break;
2043
+ const numTranspiled = transpileLatexToUnicode(numMatch.content);
2044
+ const denTranspiled = transpileLatexToUnicode(denMatch.content);
2045
+ const isAtomic = (t2) => /^[a-zA-Z0-9α-ωΑ-Ω∞π\\]+$/.test(t2.trim());
2046
+ const numOut = isAtomic(numTranspiled) ? numTranspiled.trim() : `(${numTranspiled.trim()})`;
2047
+ const denOut = isAtomic(denTranspiled) ? denTranspiled.trim() : `(${denTranspiled.trim()})`;
2048
+ const fracReplacement = `${numOut}/${denOut}`;
2049
+ s = s.slice(0, idx) + fracReplacement + s.slice(denMatch.endIndex + 1);
2050
+ }
2051
+ while (s.includes("\\sqrt")) {
2052
+ const idx = s.indexOf("\\sqrt");
2053
+ let afterSqrt = idx + 5;
2054
+ while (afterSqrt < s.length && /\s/.test(s[afterSqrt] ?? "")) afterSqrt++;
2055
+ let rootDegree = null;
2056
+ if (s[afterSqrt] === "[") {
2057
+ const bracketMatch = extractBalancedBrackets(s, afterSqrt);
2058
+ if (bracketMatch) {
2059
+ rootDegree = transpileLatexToUnicode(bracketMatch.content);
2060
+ afterSqrt = bracketMatch.endIndex + 1;
2061
+ while (afterSqrt < s.length && /\s/.test(s[afterSqrt] ?? "")) afterSqrt++;
2062
+ }
2063
+ }
2064
+ const radMatch = extractBalancedBraces(s, afterSqrt);
2065
+ if (!radMatch) break;
2066
+ const radContent = transpileLatexToUnicode(radMatch.content).trim();
2067
+ let rootSym = "\u221A";
2068
+ if (rootDegree === "3") {
2069
+ rootSym = "\u221B";
2070
+ } else if (rootDegree === "4") {
2071
+ rootSym = "\u221C";
2072
+ } else if (rootDegree) {
2073
+ const supDeg = toSuperscriptString(rootDegree);
2074
+ rootSym = supDeg ? `${supDeg}\u221A` : `^(${rootDegree})\u221A`;
2075
+ }
2076
+ const sqrtReplacement = `${rootSym}(${radContent})`;
2077
+ s = s.slice(0, idx) + sqrtReplacement + s.slice(radMatch.endIndex + 1);
2078
+ }
2079
+ s = s.replace(/\\([a-zA-Z]+)/g, (fullMatch, name) => {
2080
+ if (GREEK_LETTERS[name]) return GREEK_LETTERS[name];
2081
+ if (OPERATORS_AND_SYMBOLS[name]) return OPERATORS_AND_SYMBOLS[name];
2082
+ return fullMatch;
2083
+ });
2084
+ s = processSubSuperscripts(s);
2085
+ s = s.replace(/\\([{}%$_&])/g, "$1");
2086
+ s = s.replace(/\s{2,}/g, " ").trim();
2087
+ return s;
2088
+ }
2089
+ function processSubSuperscripts(text) {
2090
+ let result = "";
2091
+ let i = 0;
2092
+ while (i < text.length) {
2093
+ if (text[i] === "^" || text[i] === "_") {
2094
+ const isSuper = text[i] === "^";
2095
+ i++;
2096
+ let rawInner = "";
2097
+ if (i < text.length && text[i] === "{") {
2098
+ const braceMatch = extractBalancedBraces(text, i);
2099
+ if (braceMatch) {
2100
+ rawInner = braceMatch.content;
2101
+ i = braceMatch.endIndex + 1;
2102
+ } else {
2103
+ result += `${isSuper ? "^" : "_"}{`;
2104
+ i++;
2105
+ continue;
2106
+ }
2107
+ } else if (i < text.length) {
2108
+ rawInner = text[i] ?? "";
2109
+ i++;
2110
+ }
2111
+ const transpiledInner = transpileLatexToUnicode(rawInner);
2112
+ const converted = isSuper ? toSuperscriptString(transpiledInner) : toSubscriptString(transpiledInner);
2113
+ if (converted !== null && converted.length > 0) {
2114
+ result += converted;
2115
+ } else {
2116
+ const marker = isSuper ? "^" : "_";
2117
+ result += `${marker}(${transpiledInner})`;
2118
+ }
2119
+ } else {
2120
+ result += text[i];
2121
+ i++;
2122
+ }
2123
+ }
2124
+ return result;
2125
+ }
2126
+ function renderMathBlock(latex, options = {}) {
2127
+ const trimmed = latex.trim();
2128
+ if (!mathRenderingEnabled) {
2129
+ return `\x1B[2m${trimmed}\x1B[0m`;
2130
+ }
2131
+ if (hasUnsupportedLatex(trimmed)) {
2132
+ return `\x1B[2m${trimmed}\x1B[0m`;
2133
+ }
2134
+ const columns = options.columns && options.columns > 10 ? options.columns : 80;
2135
+ const fracMatch = trimmed.match(/^\\frac\s*\{([\s\S]+)\}\s*\{([\s\S]+)\}$/);
2136
+ if (fracMatch) {
2137
+ const num = transpileLatexToUnicode(fracMatch[1] ?? "");
2138
+ const den = transpileLatexToUnicode(fracMatch[2] ?? "");
2139
+ if (num.length > 8 || den.length > 8 || num.includes("+") || den.includes("+") || num.includes("-") || den.includes("-")) {
2140
+ const width = Math.max(visibleWidth(num), visibleWidth(den)) + 2;
2141
+ const bar = "\u2500".repeat(width);
2142
+ const padNum = " ".repeat(Math.max(0, Math.floor((width - visibleWidth(num)) / 2)));
2143
+ const padDen = " ".repeat(Math.max(0, Math.floor((width - visibleWidth(den)) / 2)));
2144
+ const l1 = padNum + num;
2145
+ const l2 = bar;
2146
+ const l3 = padDen + den;
2147
+ const centerIndent2 = Math.max(0, Math.floor((columns - width) / 2));
2148
+ const indent2 = " ".repeat(centerIndent2);
2149
+ return `\x1B[2m${indent2}${l1}
2150
+ ${indent2}${l2}
2151
+ ${indent2}${l3}\x1B[0m`;
2152
+ }
2153
+ }
2154
+ const transpiled = transpileLatexToUnicode(trimmed);
2155
+ const lines = transpiled.split("\n");
2156
+ const maxLineW = Math.max(...lines.map((l) => visibleWidth(l)));
2157
+ const centerIndent = Math.max(0, Math.floor((columns - maxLineW) / 2));
2158
+ const indent = " ".repeat(centerIndent);
2159
+ const centeredLines = lines.map((line) => `${indent}${line}`);
2160
+ return `\x1B[2m${centeredLines.join("\n")}\x1B[0m`;
2161
+ }
2162
+ function isCurrencyOrNonMath(leadingChar, inner, trailingChar) {
2163
+ if (!inner || /^\s/.test(inner) || /\s$/.test(inner)) return true;
2164
+ if (/[a-zA-Z0-9]/.test(leadingChar)) return true;
2165
+ if (/^(?:\d[\d,]*(?:\.\d+)?|\.\d+)$/.test(inner)) return true;
2166
+ if (/^\d/.test(inner)) {
2167
+ if (/\d/.test(trailingChar)) return true;
2168
+ if (/[\u4e00-\u9fa5]/.test(inner)) return true;
2169
+ if (/\b(to|and|or|for|is|between|with|at|from|dollars?|cents?|usd|cny|rmb|eur|gbp)\b/i.test(inner)) return true;
2170
+ if (/,\s*\d/.test(inner)) return true;
2171
+ if (/\s+/.test(inner) && !/[=+\-*/\\^_<>]/.test(inner)) return true;
2172
+ }
2173
+ return false;
2174
+ }
2175
+ function maskMathInLine(line, brightness) {
2176
+ const replacements = [];
2177
+ let out = "";
2178
+ let i = 0;
2179
+ while (i < line.length) {
2180
+ if (line[i] === "\\") {
2181
+ if (line.startsWith("\\(", i)) {
2182
+ const closeIdx = line.indexOf("\\)", i + 2);
2183
+ if (closeIdx !== -1) {
2184
+ const inner = line.slice(i + 2, closeIdx);
2185
+ const id = replacements.length;
2186
+ const transpiled = transpileLatexToUnicode(inner);
2187
+ replacements.push(transpiled);
2188
+ out += `\0M${id}\0`;
2189
+ i = closeIdx + 2;
2190
+ continue;
2191
+ }
2192
+ }
2193
+ if (line.startsWith("\\[", i)) {
2194
+ const closeIdx = line.indexOf("\\]", i + 2);
2195
+ if (closeIdx !== -1) {
2196
+ const inner = line.slice(i + 2, closeIdx);
2197
+ const id = replacements.length;
2198
+ const transpiled = transpileLatexToUnicode(inner);
2199
+ replacements.push(transpiled);
2200
+ out += `\0M${id}\0`;
2201
+ i = closeIdx + 2;
2202
+ continue;
2203
+ }
2204
+ }
2205
+ out += line[i];
2206
+ if (i + 1 < line.length) {
2207
+ out += line[i + 1];
2208
+ i += 2;
2209
+ } else {
2210
+ i += 1;
2211
+ }
2212
+ continue;
2213
+ }
2214
+ if (line[i] === "`") {
2215
+ let runLen = 1;
2216
+ while (i + runLen < line.length && line[i + runLen] === "`") {
2217
+ runLen++;
2218
+ }
2219
+ const fence = "`".repeat(runLen);
2220
+ const closeIdx = line.indexOf(fence, i + runLen);
2221
+ if (closeIdx !== -1) {
2222
+ const span = line.slice(i, closeIdx + runLen);
2223
+ out += span;
2224
+ i = closeIdx + runLen;
2225
+ continue;
2226
+ }
2227
+ }
2228
+ if (line[i] === "$") {
2229
+ if (line.startsWith("$$", i)) {
2230
+ const closeIdx = line.indexOf("$$", i + 2);
2231
+ if (closeIdx !== -1) {
2232
+ const inner = line.slice(i + 2, closeIdx);
2233
+ const id = replacements.length;
2234
+ const transpiled = transpileLatexToUnicode(inner);
2235
+ replacements.push(transpiled);
2236
+ out += `\0M${id}\0`;
2237
+ i = closeIdx + 2;
2238
+ continue;
2239
+ }
2240
+ }
2241
+ const nextChar = line[i + 1] ?? "";
2242
+ if (nextChar && !/\s/.test(nextChar) && nextChar !== "$") {
2243
+ let closeIdx = -1;
2244
+ for (let j = i + 1; j < line.length; j++) {
2245
+ if (line[j] === "$" && line[j - 1] !== "\\") {
2246
+ if (!/\s/.test(line[j - 1] ?? "")) {
2247
+ closeIdx = j;
2248
+ break;
2249
+ }
2250
+ }
2251
+ }
2252
+ if (closeIdx !== -1) {
2253
+ const inner = line.slice(i + 1, closeIdx);
2254
+ const leadingChar = i > 0 ? line[i - 1] ?? "" : "";
2255
+ const trailingChar = closeIdx + 1 < line.length ? line[closeIdx + 1] ?? "" : "";
2256
+ if (!isCurrencyOrNonMath(leadingChar, inner, trailingChar)) {
2257
+ const id = replacements.length;
2258
+ const transpiled = transpileLatexToUnicode(inner);
2259
+ replacements.push(transpiled);
2260
+ out += `\0M${id}\0`;
2261
+ i = closeIdx + 1;
2262
+ continue;
2263
+ }
2264
+ }
2265
+ }
2266
+ }
2267
+ out += line[i];
2268
+ i++;
2269
+ }
2270
+ return {
2271
+ maskedText: out,
2272
+ restore: (styled) => {
2273
+ return styled.replace(/\x00M(\d+)\x00/g, (_, id) => replacements[Number(id)] ?? "");
2274
+ }
2275
+ };
2276
+ }
2277
+
2278
+ // packages/cli/client/inlineMarkdown.ts
2279
+ var STYLE2 = {
968
2280
  reset: "\x1B[0m",
969
2281
  bold: "\x1B[1m",
970
2282
  dim: "\x1B[2m"
@@ -972,20 +2284,359 @@ var STYLE = {
972
2284
  function colorSeq(token, brightness) {
973
2285
  return themeColorSequence(token, process.env, brightness);
974
2286
  }
2287
+ function renderMarkdownLink(match, text, url) {
2288
+ const visible = `${text} (${url})`;
2289
+ return `\x1B]8;;${url}\x1B\\${visible}\x1B]8;;\x1B\\`;
2290
+ }
2291
+ var MARKDOWN_LINK_RE = /\[([^\]]+)\]\(([^)\s]+)\)/g;
2292
+ function styleInlineMarkdown(line, brightness) {
2293
+ const inlineCode = colorSeq("muted", brightness);
2294
+ const reset = STYLE2.reset;
2295
+ const bold = STYLE2.bold;
2296
+ const dim = STYLE2.dim;
2297
+ const zwsCode = "\u200B";
2298
+ const mathMask = maskMathInLine(line, brightness);
2299
+ const styled = mathMask.maskedText.replace(MARKDOWN_LINK_RE, (m, t2, u) => renderMarkdownLink(m, t2, u)).replace(
2300
+ /\u200b([^\u200b\n]+)\u200b/g,
2301
+ (_m, inner) => `${zwsCode}${inlineCode}${inner}${reset}${zwsCode}`
2302
+ ).replace(/`([^`]+)`/g, `${inlineCode}$1${reset}`).replace(/\*\*(.+?)\*\*/g, `${bold}$1${reset}`).replace(/(?<!\*)\*([^*]+?)\*(?!\*)/g, `${dim}$1${reset}`).replace(/~~([^~]+?)~~/g, `${dim}\x1B[9m$1\x1B[29m${reset}`);
2303
+ return mathMask.restore(styled);
2304
+ }
2305
+
2306
+ // packages/cli/client/markdownTable.ts
2307
+ var SENTINEL_OPEN = "";
2308
+ var SENTINEL_CLOSE = "";
2309
+ function maskCellInternals(cell) {
2310
+ let out = "";
2311
+ let index = 0;
2312
+ while (index < cell.length) {
2313
+ const ch = cell[index];
2314
+ if (ch === "\\" && cell[index + 1] === "|") {
2315
+ out += `${SENTINEL_OPEN}0${SENTINEL_CLOSE}`;
2316
+ index += 2;
2317
+ continue;
2318
+ }
2319
+ if (ch === "`") {
2320
+ const end = cell.indexOf("`", index + 1);
2321
+ if (end > index) {
2322
+ out += cell.slice(index, end + 1).replace(/\|/g, `${SENTINEL_OPEN}1${SENTINEL_CLOSE}`);
2323
+ index = end + 1;
2324
+ continue;
2325
+ }
2326
+ }
2327
+ out += ch;
2328
+ index += 1;
2329
+ }
2330
+ return out;
2331
+ }
2332
+ function unmaskCell(cell) {
2333
+ return cell.replace(/\x010\x02/g, "|").replace(/\x011\x02/g, "|");
2334
+ }
975
2335
  function splitTableCells(line) {
976
2336
  const trimmed = line.trim();
977
2337
  if (!trimmed.includes("|")) return [];
978
2338
  const core = trimmed.replace(/^\|/, "").replace(/\|$/, "");
979
- return core.split("|").map((cell) => cell.trim()).filter(Boolean);
2339
+ const masked = maskCellInternals(core);
2340
+ return masked.split("|").map((cell) => unmaskCell(cell.trim()));
2341
+ }
2342
+ function parseTableAligns(sepLine) {
2343
+ return splitTableCells(sepLine).map((cell) => {
2344
+ const left = cell.startsWith(":");
2345
+ const right = cell.length > 1 && cell.endsWith(":");
2346
+ if (left && right) return "center";
2347
+ if (right) return "right";
2348
+ return "left";
2349
+ });
980
2350
  }
981
- function isTableSeparator(line) {
2351
+ function isTableSeparatorLine(line) {
982
2352
  const cells = splitTableCells(line);
983
- return cells.length > 0 && cells.every((cell) => /^:?-{3,}:?$/.test(cell));
2353
+ return cells.length > 0 && cells.every((cell) => /^:?-+:?$/.test(cell));
984
2354
  }
985
2355
  function isTableRow(line) {
986
2356
  const cells = splitTableCells(line);
987
2357
  return cells.length >= 2 && cells.some((cell) => cell.length > 0);
988
2358
  }
2359
+ function parseMarkdownTableBlock(rows) {
2360
+ if (rows.length < 2) return null;
2361
+ const headerLine = rows[0];
2362
+ const sepLine = rows[1] ?? "";
2363
+ if (!isTableSeparatorLine(sepLine)) return null;
2364
+ const headers = splitTableCells(headerLine ?? "");
2365
+ if (headers.length < 2) return null;
2366
+ const aligns = parseTableAligns(sepLine);
2367
+ while (aligns.length < headers.length) aligns.push("left");
2368
+ const tableRows = [];
2369
+ for (let i = 2; i < rows.length; i++) {
2370
+ const cells = splitTableCells(rows[i] ?? "");
2371
+ if (cells.length === 0) continue;
2372
+ const padded = [];
2373
+ for (let c = 0; c < headers.length; c += 1) padded.push(cells[c] ?? "");
2374
+ tableRows.push(padded);
2375
+ }
2376
+ return { headers, aligns, rows: tableRows };
2377
+ }
2378
+ function resolveTableWidth(explicit, env = process.env) {
2379
+ if (typeof explicit === "number" && explicit > 0) return explicit;
2380
+ const override = parseInt(env.NOLO_TEST_TABLE_WIDTH, 10);
2381
+ if (!Number.isNaN(override) && override > 0) return override;
2382
+ const cols = typeof process !== "undefined" && typeof process.stdout?.columns === "number" ? process.stdout.columns : 0;
2383
+ if (cols > 0) return cols;
2384
+ return 80;
2385
+ }
2386
+ function wrapCellToWidth(text, max) {
2387
+ if (max <= 0 || displayWidth(text) <= max) return [text];
2388
+ const tokens = tokenizeAnsiLine(text);
2389
+ const charTokenIdx = [];
2390
+ tokens.forEach((t2, i) => {
2391
+ if (t2.kind === "char") charTokenIdx.push(i);
2392
+ });
2393
+ const n = charTokenIdx.length;
2394
+ if (n === 0) return [text];
2395
+ const widths = charTokenIdx.map((i) => tokens[i].width);
2396
+ const prefix = [0];
2397
+ for (let i = 0; i < widths.length; i += 1) prefix.push(prefix[i] + widths[i]);
2398
+ const segWidth = (a, b) => prefix[b] - prefix[a];
2399
+ const sliceTokens = (a, b) => {
2400
+ const startTok = a === 0 ? 0 : charTokenIdx[a - 1] + 1;
2401
+ const endTok = b < n ? charTokenIdx[b] - 1 : tokens.length - 1;
2402
+ return tokens.slice(startTok, endTok + 1);
2403
+ };
2404
+ const applyStyles = (slice, state) => {
2405
+ const next = [...state];
2406
+ for (const t2 of slice) {
2407
+ if (t2.kind !== "sgr") continue;
2408
+ if (OSC8_CLOSER_REGEX.test(t2.value)) {
2409
+ for (let i = next.length - 1; i >= 0; i -= 1) {
2410
+ if (OSC8_OPENER_REGEX.test(next[i])) {
2411
+ next.splice(i, 1);
2412
+ break;
2413
+ }
2414
+ }
2415
+ } else if (OSC8_OPENER_REGEX.test(t2.value)) {
2416
+ next.push(t2.value);
2417
+ } else if (SGR_RESET_REGEX2.test(t2.value)) {
2418
+ for (let i = next.length - 1; i >= 0; i -= 1) {
2419
+ if (!OSC8_OPENER_REGEX.test(next[i]) && !OSC8_CLOSER_REGEX.test(next[i])) {
2420
+ next.splice(i, 1);
2421
+ }
2422
+ }
2423
+ } else {
2424
+ next.push(t2.value);
2425
+ }
2426
+ }
2427
+ return next;
2428
+ };
2429
+ const renderSegment = (slice, opening) => {
2430
+ const raw = slice.map((t2) => t2.value).join("");
2431
+ const endState = applyStyles(slice, opening);
2432
+ const hasOpenOsc = endState.some((v) => OSC8_OPENER_REGEX.test(v));
2433
+ const hasOpenSgr = endState.some(
2434
+ (v) => !OSC8_OPENER_REGEX.test(v) && !OSC8_CLOSER_REGEX.test(v)
2435
+ );
2436
+ const prefix2 = opening.length > 0 ? opening.join("") : "";
2437
+ let suffix = "";
2438
+ if (hasOpenOsc) suffix += "\x1B]8;;\x1B\\";
2439
+ if (hasOpenSgr && !raw.endsWith("\x1B[0m")) suffix += "\x1B[0m";
2440
+ return `${prefix2}${raw}${suffix}`;
2441
+ };
2442
+ const segments = [];
2443
+ let active = [];
2444
+ let start = 0;
2445
+ for (let i = 1; i < n; i += 1) {
2446
+ if (segWidth(start, i + 1) <= max) continue;
2447
+ let cut = -1;
2448
+ for (let j = i - 1; j > start; j -= 1) {
2449
+ if (tokens[charTokenIdx[j]].value !== " ") continue;
2450
+ if (segWidth(start, j) <= max && segWidth(j + 1, i + 1) <= max) {
2451
+ cut = j;
2452
+ break;
2453
+ }
2454
+ }
2455
+ if (cut >= 0) {
2456
+ const slice = sliceTokens(start, cut);
2457
+ segments.push(renderSegment(slice, active));
2458
+ active = applyStyles(slice, active);
2459
+ start = cut + 1;
2460
+ } else {
2461
+ let hard = start;
2462
+ let w = 0;
2463
+ while (hard < i && widths[hard] > 0 && w + widths[hard] <= max) {
2464
+ w += widths[hard];
2465
+ hard += 1;
2466
+ }
2467
+ if (hard <= start) hard = start + 1;
2468
+ const slice = sliceTokens(start, hard);
2469
+ segments.push(renderSegment(slice, active));
2470
+ active = applyStyles(slice, active);
2471
+ start = hard;
2472
+ }
2473
+ }
2474
+ if (start < n) {
2475
+ const slice = sliceTokens(start, n);
2476
+ segments.push(renderSegment(slice, active));
2477
+ }
2478
+ return segments.length > 0 ? segments : [text];
2479
+ }
2480
+ var SGR_RESET_REGEX2 = /^\x1b\[0?m$/;
2481
+ var OSC8_OPENER_REGEX = /^\x1b\]8;;[^\x07\x1b]+(?:\x07|\x1b\\)$/;
2482
+ var OSC8_CLOSER_REGEX = /^\x1b\]8;;\x1b\\$/;
2483
+ function padCell(text, width, align) {
2484
+ const pad = width - displayWidth(text);
2485
+ if (pad <= 0) return text;
2486
+ switch (align) {
2487
+ case "right":
2488
+ return " ".repeat(pad) + text;
2489
+ case "center": {
2490
+ const left = Math.floor(pad / 2);
2491
+ return " ".repeat(left) + text + " ".repeat(pad - left);
2492
+ }
2493
+ case "left":
2494
+ default:
2495
+ return text + " ".repeat(pad);
2496
+ }
2497
+ }
2498
+ function computeColumnWidths(headers, rows, available) {
2499
+ const colCount = headers.length;
2500
+ const natural = headers.map((h, i) => {
2501
+ let max = displayWidth(h ?? "");
2502
+ for (const row of rows) {
2503
+ const w = displayWidth(row[i] ?? "");
2504
+ if (w > max) max = w;
2505
+ }
2506
+ return max;
2507
+ });
2508
+ const border = 2 * colCount + 1;
2509
+ const total = () => border + natural.reduce((a, b) => a + b, 0);
2510
+ if (total() <= available) return natural;
2511
+ const minPerCol = Math.max(2, Math.floor((available - border) / colCount));
2512
+ let guard = colCount * 64;
2513
+ while (total() > available && guard-- > 0) {
2514
+ let widest = 0;
2515
+ for (let i = 1; i < colCount; i += 1) {
2516
+ if (natural[i] > natural[widest]) widest = i;
2517
+ }
2518
+ if (natural[widest] <= minPerCol) break;
2519
+ const overflow = total() - available;
2520
+ const delta = Math.min(
2521
+ natural[widest] - minPerCol,
2522
+ Math.max(1, Math.ceil(overflow / 2))
2523
+ );
2524
+ natural[widest] -= delta;
2525
+ }
2526
+ return natural;
2527
+ }
2528
+ function makeStyle(brightness, headerToken) {
2529
+ const color = themeColorSequence(headerToken, process.env, brightness);
2530
+ const boldOn = "\x1B[1m";
2531
+ const reset = "\x1B[0m";
2532
+ const paint = (t2) => `${color}${boldOn}${t2}${reset}`;
2533
+ return { header: paint, label: paint };
2534
+ }
2535
+ function boxLine(left, mid, right, widths) {
2536
+ const seg = widths.map((w) => "\u2500".repeat(w + 2));
2537
+ return `${left}${seg.join(mid)}${right}`;
2538
+ }
2539
+ function dataRow(cells, aligns, widths, style, header) {
2540
+ const parts = cells.map((cell, i) => {
2541
+ const width = widths[i] ?? 0;
2542
+ const align = aligns[i] ?? "left";
2543
+ const padded = padCell(cell, width, align);
2544
+ const styled = header ? style.header(padded) : padded;
2545
+ return ` ${styled} \u2502`;
2546
+ });
2547
+ return `\u2502${parts.join("")}`;
2548
+ }
2549
+ function renderBoxTable(table, width, style) {
2550
+ const colCount = table.headers.length;
2551
+ const widths = computeColumnWidths(table.headers, table.rows, width);
2552
+ const headerGrid = table.headers.map(
2553
+ (h, i) => wrapCellToWidth(h, widths[i] ?? 0)
2554
+ );
2555
+ const bodyGrids = table.rows.map(
2556
+ (row) => row.map((cell, i) => wrapCellToWidth(cell, widths[i] ?? 0))
2557
+ );
2558
+ const headerDisplayRows = Math.max(1, ...headerGrid.map((g) => g.length));
2559
+ const bodyDisplayRows = bodyGrids.map(
2560
+ (r) => Math.max(1, ...r.map((g) => g.length))
2561
+ );
2562
+ const lines = [];
2563
+ lines.push(boxLine("\u250C", "\u252C", "\u2510", widths));
2564
+ for (let r = 0; r < headerDisplayRows; r += 1) {
2565
+ lines.push(
2566
+ dataRow(
2567
+ Array.from({ length: colCount }, (_, c) => headerGrid[c]?.[r] ?? ""),
2568
+ table.aligns,
2569
+ widths,
2570
+ style,
2571
+ true
2572
+ )
2573
+ );
2574
+ }
2575
+ lines.push(boxLine("\u251C", "\u253C", "\u2524", widths));
2576
+ bodyGrids.forEach((_, rec) => {
2577
+ for (let r = 0; r < bodyDisplayRows[rec]; r += 1) {
2578
+ lines.push(
2579
+ dataRow(
2580
+ Array.from(
2581
+ { length: colCount },
2582
+ (_2, c) => bodyGrids[rec][c]?.[r] ?? ""
2583
+ ),
2584
+ table.aligns,
2585
+ widths,
2586
+ style,
2587
+ false
2588
+ )
2589
+ );
2590
+ }
2591
+ });
2592
+ lines.push(boxLine("\u2514", "\u2534", "\u2518", widths));
2593
+ return lines.join("\n");
2594
+ }
2595
+ function renderRecordCards(table, width, style) {
2596
+ const lines = [];
2597
+ table.rows.forEach((row, idx) => {
2598
+ if (idx > 0) lines.push("");
2599
+ const first = row[0] ?? "";
2600
+ for (const seg of wrapCellToWidth(first, Math.max(4, width))) {
2601
+ lines.push(style.label(seg));
2602
+ }
2603
+ for (let i = 1; i < table.headers.length; i += 1) {
2604
+ const label = table.headers[i] ?? `col${i}`;
2605
+ const value = row[i] ?? "";
2606
+ const labelLine = `${style.label(label)}: `;
2607
+ const indent = " ".repeat(displayWidth(label) + 2);
2608
+ const valueSegs = wrapCellToWidth(
2609
+ value,
2610
+ Math.max(4, width - displayWidth(label) - 2)
2611
+ );
2612
+ if (valueSegs.length === 0 || valueSegs[0] === "") {
2613
+ lines.push(labelLine);
2614
+ } else {
2615
+ lines.push(labelLine + valueSegs[0]);
2616
+ for (let k = 1; k < valueSegs.length; k += 1) {
2617
+ lines.push(indent + valueSegs[k]);
2618
+ }
2619
+ }
2620
+ }
2621
+ });
2622
+ return lines.join("\n");
2623
+ }
2624
+ function renderMarkdownTable(table, options = {}) {
2625
+ const brightness = options.brightness ?? resolveTuiBrightness();
2626
+ const width = resolveTableWidth(options.width);
2627
+ const style = makeStyle(brightness, options.headerToken ?? "chrome");
2628
+ const styledTable = {
2629
+ headers: table.headers.map((h) => styleInlineMarkdown(h, brightness)),
2630
+ aligns: table.aligns,
2631
+ rows: table.rows.map((r) => r.map((c) => styleInlineMarkdown(c, brightness)))
2632
+ };
2633
+ if (width < 40 || table.headers.length > 6) {
2634
+ return renderRecordCards(styledTable, width, style);
2635
+ }
2636
+ return renderBoxTable(styledTable, width, style);
2637
+ }
2638
+
2639
+ // packages/cli/client/assistantOutput.ts
989
2640
  function isPipeWrappedTableRow(line) {
990
2641
  const trimmed = line.trim();
991
2642
  return trimmed.startsWith("|") && trimmed.endsWith("|") && isTableRow(line);
@@ -1143,7 +2794,7 @@ function detectCodeLangFromPath(filePath) {
1143
2794
  function highlightCodeLine(line, lang, brightness) {
1144
2795
  const info = colorSeq("info", brightness);
1145
2796
  if (lang === "unknown") {
1146
- return `${info}${line}${STYLE.reset}`;
2797
+ return `${info}${line}${STYLE2.reset}`;
1147
2798
  }
1148
2799
  if (lang === "diff") {
1149
2800
  return renderDiffLine({ kind: classifyDiffLine(line), text: line, colorEnabled: true });
@@ -1154,8 +2805,8 @@ function highlightCodeLine(line, lang, brightness) {
1154
2805
  const success = colorSeq("success", brightness);
1155
2806
  const warning = colorSeq("warning", brightness);
1156
2807
  const chrome = colorSeq("chrome", brightness);
1157
- const dim = STYLE.dim;
1158
- const reset = STYLE.reset;
2808
+ const dim = STYLE2.dim;
2809
+ const reset = STYLE2.reset;
1159
2810
  const out = [];
1160
2811
  let cursor = 0;
1161
2812
  for (const region of regions) {
@@ -1207,12 +2858,6 @@ function emitPlainGap(text, keywords, info, accent, warning, reset) {
1207
2858
  }
1208
2859
  return parts.join("");
1209
2860
  }
1210
- function tableRowToBullet(line) {
1211
- const row = splitTableCells(line);
1212
- const label = row[0] ?? "";
1213
- const detail = row.slice(1).join(" \u2014 ").trim();
1214
- return detail ? ` \u2022 ${label} \u2014 ${detail}` : ` \u2022 ${label}`;
1215
- }
1216
2861
  var UNORDERED_LIST_RE = /^(\s*)([-*+])\s+(.+)$/;
1217
2862
  var ORDERED_LIST_RE = /^(\s*)(\d+)\.\s+(.+)$/;
1218
2863
  var TASK_LIST_RE = /^(\s*)([-*+])\s+\[([ xX])\]\s+(.+)$/;
@@ -1248,17 +2893,36 @@ function convertMarkdownTablesForTerminal(text) {
1248
2893
  continue;
1249
2894
  }
1250
2895
  const next = lines[index + 1] ?? "";
1251
- if (isTableRow(line) && isTableSeparator(next)) {
1252
- index += 1;
1253
- while (index + 1 < lines.length && isTableRow(lines[index + 1] ?? "") && !isTableSeparator(lines[index + 1] ?? "")) {
1254
- index += 1;
1255
- out.push(tableRowToBullet(lines[index] ?? ""));
2896
+ if (isTableRow(line) && isTableSeparatorLine(next)) {
2897
+ const block = [line, next];
2898
+ let cursor = index + 2;
2899
+ while (cursor < lines.length && isTableRow(lines[cursor] ?? "") && !isTableSeparatorLine(lines[cursor] ?? "")) {
2900
+ block.push(lines[cursor] ?? "");
2901
+ cursor += 1;
2902
+ }
2903
+ index = cursor - 1;
2904
+ const table = parseMarkdownTableBlock(block);
2905
+ const hasBody = table !== null && table.rows.length > 0;
2906
+ if (table && hasBody) {
2907
+ out.push(renderMarkdownTable(table));
2908
+ if (out[out.length - 1] !== "") out.push("");
2909
+ } else {
2910
+ for (const l of block) out.push(l);
1256
2911
  }
1257
- if (out.length > 0 && out[out.length - 1] !== "") out.push("");
1258
2912
  continue;
1259
2913
  }
1260
2914
  if (isPipeWrappedTableRow(line)) {
1261
- if (!isTableSeparator(line)) out.push(tableRowToBullet(line));
2915
+ if (!isTableSeparatorLine(line)) {
2916
+ const cells = splitTableCells(line);
2917
+ out.push(
2918
+ renderMarkdownTable({
2919
+ headers: ["record", ...cells.slice(1).map((_, i) => `col${i + 1}`)],
2920
+ aligns: ["left", ...cells.slice(1).map(() => "left")],
2921
+ rows: [cells]
2922
+ })
2923
+ );
2924
+ if (out[out.length - 1] !== "") out.push("");
2925
+ }
1262
2926
  continue;
1263
2927
  }
1264
2928
  out.push(normalizeListLine(line));
@@ -1298,80 +2962,150 @@ function polishAssistantStructure(text, options = {}) {
1298
2962
  );
1299
2963
  return options.trimEdges === false ? polished : polished.trim();
1300
2964
  }
1301
- function renderMarkdownLink(match, text, url) {
1302
- const visible = `${text} (${url})`;
1303
- return `\x1B]8;;${url}\x1B\\${visible}\x1B]8;;\x1B\\`;
1304
- }
1305
- var MARKDOWN_LINK_RE = /\[([^\]]+)\]\(([^)\s]+)\)/g;
1306
- function styleInlineMarkdown(line, brightness) {
1307
- const inlineCode = colorSeq("muted", brightness);
1308
- const reset = STYLE.reset;
1309
- const bold = STYLE.bold;
1310
- const dim = STYLE.dim;
1311
- return line.replace(MARKDOWN_LINK_RE, (m, t2, u) => renderMarkdownLink(m, t2, u)).replace(/`([^`]+)`/g, `${inlineCode}$1${reset}`).replace(/\*\*(.+?)\*\*/g, `${bold}$1${reset}`).replace(/(?<!\*)\*([^*]+?)\*(?!\*)/g, `${dim}$1${reset}`).replace(/~~([^~]+?)~~/g, `${dim}\x1B[9m$1\x1B[29m${reset}`);
1312
- }
1313
2965
  function styleRichMarkdownLine(line, brightness) {
1314
2966
  const heading = line.match(/^(#{1,3})\s+(.+)$/);
1315
2967
  if (heading) {
1316
2968
  const level = heading[1].length;
1317
2969
  const title = heading[2];
1318
2970
  if (level === 1) {
1319
- return `${STYLE.bold}\x1B[4m${colorSeq("accent", brightness)}${title}${STYLE.reset}`;
2971
+ return `${STYLE2.bold}\x1B[4m${colorSeq("accent", brightness)}${title}${STYLE2.reset}`;
1320
2972
  }
1321
2973
  if (level === 2) {
1322
- return `${STYLE.bold}${colorSeq("warning", brightness)}${title}${STYLE.reset}`;
2974
+ return `${STYLE2.bold}${colorSeq("warning", brightness)}${title}${STYLE2.reset}`;
1323
2975
  }
1324
- return `${STYLE.bold}${colorSeq("info", brightness)}${title}${STYLE.reset}`;
2976
+ return `${STYLE2.bold}${colorSeq("info", brightness)}${title}${STYLE2.reset}`;
1325
2977
  }
1326
2978
  if (line.startsWith("\u8FDB\u5165 nolo-plan")) {
1327
- return `${colorSeq("chrome", brightness)}${STYLE.dim}${line}${STYLE.reset}`;
2979
+ return `${colorSeq("chrome", brightness)}${STYLE2.dim}${line}${STYLE2.reset}`;
1328
2980
  }
1329
2981
  const blockquote = line.match(/^>\s?(.*)$/);
1330
2982
  if (blockquote) {
1331
2983
  const border = colorSeq("chrome", brightness);
1332
2984
  const content = blockquote[1];
1333
- return `${border}\u2502${STYLE.reset} ${STYLE.dim}${content}${STYLE.reset}`;
2985
+ return `${border}\u2502${STYLE2.reset} ${STYLE2.dim}${content}${STYLE2.reset}`;
1334
2986
  }
1335
2987
  if (/^---+$/.test(line.trim())) {
1336
- return `${colorSeq("chrome", brightness)}${"\u2500".repeat(Math.min(line.trim().length, 40))}${STYLE.reset}`;
2988
+ return `${colorSeq("chrome", brightness)}${"\u2500".repeat(Math.min(line.trim().length, 40))}${STYLE2.reset}`;
1337
2989
  }
1338
2990
  const bullet = line.match(/^(\s*)(•)\s(.+)$/);
1339
2991
  if (bullet) {
1340
2992
  const styled = styleInlineMarkdown(bullet[3], brightness);
1341
- return `${bullet[1]}${colorSeq("accent", brightness)}\u2022${STYLE.reset} ${styled}`;
2993
+ return `${bullet[1]}${colorSeq("accent", brightness)}\u2022${STYLE2.reset} ${styled}`;
1342
2994
  }
1343
2995
  const ordered = line.match(/^(\s*)(\d+\.)\s(.+)$/);
1344
2996
  if (ordered) {
1345
2997
  const styled = styleInlineMarkdown(ordered[3], brightness);
1346
- return `${ordered[1]}${colorSeq("chrome", brightness)}${ordered[2]}${STYLE.reset} ${styled}`;
2998
+ return `${ordered[1]}${colorSeq("chrome", brightness)}${ordered[2]}${STYLE2.reset} ${styled}`;
1347
2999
  }
1348
3000
  const task = line.match(/^(\s*)(☐|☑)\s(.+)$/);
1349
3001
  if (task) {
1350
3002
  const styled = styleInlineMarkdown(task[3], brightness);
1351
- return `${task[1]}${colorSeq("accent", brightness)}${task[2]}${STYLE.reset} ${styled}`;
3003
+ return `${task[1]}${colorSeq("accent", brightness)}${task[2]}${STYLE2.reset} ${styled}`;
1352
3004
  }
1353
3005
  return styleInlineMarkdown(line, brightness);
1354
3006
  }
3007
+ function renderMermaidBody(bodyLines, brightness) {
3008
+ const body = bodyLines.join("\n");
3009
+ const rendered = renderMermaidBlock(body, brightness, true);
3010
+ if (rendered === body) {
3011
+ return bodyLines.map((l) => highlightCodeLine(l, "unknown", brightness)).join("\n");
3012
+ }
3013
+ return rendered;
3014
+ }
1355
3015
  function formatAssistantDisplay(text, options = {}) {
1356
3016
  const brightness = resolveTuiBrightness();
1357
3017
  const polished = polishAssistantStructure(text, options);
3018
+ const lines = polished.split("\n");
3019
+ const out = [];
3020
+ let i = 0;
1358
3021
  let inFence = false;
1359
3022
  let fenceLang = "unknown";
1360
- return polished.split("\n").map((line) => {
3023
+ let inMermaid = false;
3024
+ let mermaidBody = null;
3025
+ const flushMermaid = () => {
3026
+ if (mermaidBody !== null) {
3027
+ out.push(renderMermaidBody(mermaidBody, brightness));
3028
+ mermaidBody = null;
3029
+ }
3030
+ };
3031
+ while (i < lines.length) {
3032
+ const line = lines[i];
1361
3033
  if (isCodeFenceLine(line)) {
3034
+ const lang = readFenceLanguage(line);
3035
+ if (inMermaid) {
3036
+ flushMermaid();
3037
+ inMermaid = false;
3038
+ inFence = false;
3039
+ out.push(`${STYLE2.dim}${line}${STYLE2.reset}`);
3040
+ i++;
3041
+ continue;
3042
+ }
1362
3043
  if (inFence) {
1363
3044
  fenceLang = "unknown";
1364
- } else {
1365
- fenceLang = normalizeCodeLang(readFenceLanguage(line));
3045
+ inFence = false;
3046
+ out.push(`${STYLE2.dim}${line}${STYLE2.reset}`);
3047
+ i++;
3048
+ continue;
1366
3049
  }
1367
- inFence = !inFence;
1368
- return `${STYLE.dim}${line}${STYLE.reset}`;
3050
+ inFence = true;
3051
+ fenceLang = normalizeCodeLang(lang);
3052
+ if (/^mermaid$/i.test(lang)) {
3053
+ inMermaid = true;
3054
+ mermaidBody = [];
3055
+ }
3056
+ out.push(`${STYLE2.dim}${line}${STYLE2.reset}`);
3057
+ i++;
3058
+ continue;
3059
+ }
3060
+ if (inMermaid && mermaidBody !== null) {
3061
+ mermaidBody.push(line);
3062
+ i++;
3063
+ continue;
1369
3064
  }
1370
3065
  if (inFence) {
1371
- return highlightCodeLine(line, fenceLang, brightness);
3066
+ out.push(highlightCodeLine(line, fenceLang, brightness));
3067
+ i++;
3068
+ continue;
1372
3069
  }
1373
- return styleRichMarkdownLine(line, brightness);
1374
- }).join("\n");
3070
+ const trimmed = line.trim();
3071
+ if (trimmed.startsWith("$$") || trimmed.startsWith("\\[")) {
3072
+ const isBracket = trimmed.startsWith("\\[");
3073
+ const closeMarker = isBracket ? "\\]" : "$$";
3074
+ if (trimmed.length > 2 && trimmed.endsWith(closeMarker)) {
3075
+ const inner = trimmed.slice(2, trimmed.length - 2);
3076
+ out.push(renderMathBlock(inner));
3077
+ i++;
3078
+ continue;
3079
+ }
3080
+ const blockLines = [];
3081
+ const firstInner = trimmed.slice(2).trim();
3082
+ if (firstInner) blockLines.push(firstInner);
3083
+ let j = i + 1;
3084
+ let closed = false;
3085
+ while (j < lines.length) {
3086
+ const curLine = lines[j] ?? "";
3087
+ const curTrim = curLine.trim();
3088
+ if (curTrim.endsWith(closeMarker) || curTrim === closeMarker) {
3089
+ const lastInner = curTrim.slice(0, curTrim.length - 2).trim();
3090
+ if (lastInner) blockLines.push(lastInner);
3091
+ closed = true;
3092
+ j++;
3093
+ break;
3094
+ }
3095
+ blockLines.push(curLine);
3096
+ j++;
3097
+ }
3098
+ if (closed) {
3099
+ out.push(renderMathBlock(blockLines.join("\n")));
3100
+ i = j;
3101
+ continue;
3102
+ }
3103
+ }
3104
+ out.push(styleRichMarkdownLine(line, brightness));
3105
+ i++;
3106
+ }
3107
+ flushMermaid();
3108
+ return out.join("\n");
1375
3109
  }
1376
3110
  function emitFormattedAssistantBlock(write, text, trailingNewline = false) {
1377
3111
  if (!text) return;
@@ -1396,6 +3130,8 @@ function createRenderAwareStreamWriter(args) {
1396
3130
  let buffer = "";
1397
3131
  let inFence = false;
1398
3132
  let fenceLang = "unknown";
3133
+ let inMermaid = false;
3134
+ let mermaidBody = [];
1399
3135
  let lastKind = null;
1400
3136
  const PARTIAL_FLUSH_THRESHOLD = 48;
1401
3137
  const emitBreathIfNeeded = (nextKind) => {
@@ -1412,7 +3148,7 @@ function createRenderAwareStreamWriter(args) {
1412
3148
  const whitespaceIndex = graphemes.slice(0, cut).findLastIndex((part) => /\s/.test(part));
1413
3149
  if (whitespaceIndex > 0) cut = whitespaceIndex + 1;
1414
3150
  const prefix = graphemes.slice(0, cut).join("");
1415
- const hasUnsafeMarkdownPrefix = /[`*_~\[]/.test(prefix) || /^\s*[#>]/.test(prefix) || /!\[/.test(prefix);
3151
+ const hasUnsafeMarkdownPrefix = /[`*_~\[$]/.test(prefix) || /^\s*[#>]/.test(prefix) || /!\[/.test(prefix);
1416
3152
  if (hasUnsafeMarkdownPrefix) return;
1417
3153
  emitBreathIfNeeded("prose");
1418
3154
  emitFormattedAssistantBlock(args.write, prefix, false);
@@ -1425,19 +3161,44 @@ function createRenderAwareStreamWriter(args) {
1425
3161
  if (lines.length < 2) break;
1426
3162
  const firstLine = lines[0] ?? "";
1427
3163
  if (isCodeFenceLine(firstLine)) {
3164
+ if (inMermaid) {
3165
+ const diagram = renderMermaidBody(mermaidBody, brightness);
3166
+ args.write(diagram + "\n");
3167
+ mermaidBody = [];
3168
+ inMermaid = false;
3169
+ inFence = false;
3170
+ fenceLang = "unknown";
3171
+ emitBreathIfNeeded("other");
3172
+ args.write(`${STYLE2.dim}${firstLine}${STYLE2.reset}
3173
+ `);
3174
+ lastKind = "other";
3175
+ buffer = lines.slice(1).join("\n");
3176
+ continue;
3177
+ }
1428
3178
  if (inFence) {
1429
3179
  fenceLang = "unknown";
3180
+ inFence = false;
1430
3181
  } else {
1431
- fenceLang = normalizeCodeLang(readFenceLanguage(firstLine));
3182
+ const lang = readFenceLanguage(firstLine);
3183
+ fenceLang = normalizeCodeLang(lang);
3184
+ if (/^mermaid$/i.test(lang)) {
3185
+ inMermaid = true;
3186
+ mermaidBody = [];
3187
+ }
3188
+ inFence = true;
1432
3189
  }
1433
- inFence = !inFence;
1434
3190
  emitBreathIfNeeded("other");
1435
- args.write(`${STYLE.dim}${firstLine}${STYLE.reset}
3191
+ args.write(`${STYLE2.dim}${firstLine}${STYLE2.reset}
1436
3192
  `);
1437
3193
  lastKind = "other";
1438
3194
  buffer = lines.slice(1).join("\n");
1439
3195
  continue;
1440
3196
  }
3197
+ if (inMermaid) {
3198
+ mermaidBody.push(firstLine);
3199
+ buffer = lines.slice(1).join("\n");
3200
+ continue;
3201
+ }
1441
3202
  if (inFence) {
1442
3203
  args.write(`${highlightCodeLine(firstLine, fenceLang, brightness)}
1443
3204
  `);
@@ -1445,12 +3206,50 @@ function createRenderAwareStreamWriter(args) {
1445
3206
  buffer = lines.slice(1).join("\n");
1446
3207
  continue;
1447
3208
  }
3209
+ const trimmedFirst = firstLine.trim();
3210
+ if ((trimmedFirst.startsWith("$$") || trimmedFirst.startsWith("\\[")) && !inFence) {
3211
+ const isBracket = trimmedFirst.startsWith("\\[");
3212
+ const closeMarker = isBracket ? "\\]" : "$$";
3213
+ if (trimmedFirst.length > 2 && trimmedFirst.endsWith(closeMarker)) {
3214
+ emitBreathIfNeeded("other");
3215
+ const inner = trimmedFirst.slice(2, trimmedFirst.length - 2);
3216
+ args.write(renderMathBlock(inner) + "\n");
3217
+ lastKind = "other";
3218
+ buffer = lines.slice(1).join("\n");
3219
+ continue;
3220
+ }
3221
+ let closeIndex = -1;
3222
+ for (let j = 1; j < lines.length; j++) {
3223
+ const curTrim = lines[j]?.trim() ?? "";
3224
+ if (curTrim.endsWith(closeMarker) || curTrim === closeMarker) {
3225
+ closeIndex = j;
3226
+ break;
3227
+ }
3228
+ }
3229
+ if (closeIndex === -1) {
3230
+ break;
3231
+ }
3232
+ emitBreathIfNeeded("other");
3233
+ const blockLines = lines.slice(0, closeIndex + 1);
3234
+ const firstInner = blockLines[0].trim().slice(2).trim();
3235
+ const middleLines = blockLines.slice(1, -1);
3236
+ const lastTrim = blockLines[blockLines.length - 1].trim();
3237
+ const lastInner = lastTrim.slice(0, lastTrim.length - 2).trim();
3238
+ const innerParts = [];
3239
+ if (firstInner) innerParts.push(firstInner);
3240
+ innerParts.push(...middleLines);
3241
+ if (lastInner) innerParts.push(lastInner);
3242
+ args.write(renderMathBlock(innerParts.join("\n")) + "\n");
3243
+ lastKind = "other";
3244
+ buffer = lines.slice(closeIndex + 1).join("\n");
3245
+ continue;
3246
+ }
1448
3247
  if (isTableRow(firstLine)) {
1449
3248
  const nextLineComplete = lines.length > 2;
1450
3249
  if (!nextLineComplete) break;
1451
- if (isTableSeparator(lines[1] ?? "")) {
3250
+ if (isTableSeparatorLine(lines[1] ?? "")) {
1452
3251
  let end = 2;
1453
- while (end < lines.length && isTableRow(lines[end] ?? "") && !isTableSeparator(lines[end] ?? "")) {
3252
+ while (end < lines.length && isTableRow(lines[end] ?? "") && !isTableSeparatorLine(lines[end] ?? "")) {
1454
3253
  end += 1;
1455
3254
  }
1456
3255
  const tableComplete = end < lines.length - 1;
@@ -1481,6 +3280,14 @@ function createRenderAwareStreamWriter(args) {
1481
3280
  flushPartialProse();
1482
3281
  },
1483
3282
  flush() {
3283
+ if (inMermaid) {
3284
+ if (buffer) mermaidBody.push(...buffer.split("\n"));
3285
+ args.write(renderMermaidBody(mermaidBody, brightness) + "\n");
3286
+ mermaidBody = [];
3287
+ inMermaid = false;
3288
+ buffer = "";
3289
+ return;
3290
+ }
1484
3291
  if (!buffer) return;
1485
3292
  if (inFence) {
1486
3293
  args.write(buffer);
@@ -2321,7 +4128,7 @@ function isReadToolName(name) {
2321
4128
  }
2322
4129
  function isSearchToolName(name) {
2323
4130
  if (!name) return false;
2324
- return name === "grep" || name === "searchFiles" || name === "search_files" || name === "globFiles" || name === "glob_files" || name === "glob" || name === "searchWorkspace" || name === "search_workspace" || name === "search_all_spaces" || name === "search";
4131
+ 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";
2325
4132
  }
2326
4133
  function isRunToolName(name) {
2327
4134
  if (!name) return false;
@@ -2341,7 +4148,7 @@ function isRunResultFoldable(event) {
2341
4148
  function formatSearchTreeBlockForCli(items, colorEnabled) {
2342
4149
  if (items.length === 0) return "";
2343
4150
  const { count, lines } = formatSearchTreeLines(items);
2344
- const titleText = toolLabel("searchFiles");
4151
+ const titleText = toolLabel("codeSearch");
2345
4152
  if (!colorEnabled) {
2346
4153
  const headerLine2 = `\u2022 ${titleText} (${count})
2347
4154
  `;
@@ -2992,6 +4799,28 @@ ${this.text}
2992
4799
  };
2993
4800
 
2994
4801
  // packages/cli/client/agentRunOutput.ts
4802
+ function formatCompactionSummaryLine(event) {
4803
+ if (!event) return "";
4804
+ const action = event.reason === "tool_stub" ? "stub \u5DE5\u5177\u8F93\u51FA" : "\u751F\u6210\u5386\u53F2\u6458\u8981";
4805
+ let detail = action;
4806
+ if (typeof event.stubbedCount === "number") {
4807
+ detail = `stub ${event.stubbedCount} \u6761\u5DE5\u5177\u8F93\u51FA`;
4808
+ }
4809
+ const saved = typeof event.savedTokens === "number" ? event.savedTokens : void 0;
4810
+ let line = `\u5DF2\u538B\u7F29\u4E0A\u4E0B\u6587\uFF1A${detail}`;
4811
+ if (saved !== void 0) {
4812
+ let k;
4813
+ if (saved >= 1e3) {
4814
+ const v = (saved / 1e3).toFixed(1);
4815
+ k = v.replace(/\.0$/, "") + "k";
4816
+ } else {
4817
+ k = String(saved);
4818
+ }
4819
+ line += `\uFF0C\u7701\u7EA6 ${k} tokens`;
4820
+ }
4821
+ line += "\n";
4822
+ return `${STYLE2.dim}${line}${STYLE2.reset}`;
4823
+ }
2995
4824
  function formatAssistantResponseForCli(text) {
2996
4825
  return formatAssistantDisplay(
2997
4826
  formatAssistantTextForCli(text)
@@ -3030,6 +4859,7 @@ function createCliTurnOutput(params) {
3030
4859
  let everStreamedAnyText = false;
3031
4860
  let printedAssistantLabel = false;
3032
4861
  let thinkState = createThinkParserState();
4862
+ let compactionEvent = null;
3033
4863
  const renderWriter = createRenderAwareStreamWriter({
3034
4864
  write: (chunk) => options.output.write(chunk)
3035
4865
  });
@@ -3102,6 +4932,10 @@ ${options.agentName} > `);
3102
4932
  spinner.setThinkingHint(chunk);
3103
4933
  },
3104
4934
  handleToolEvent,
4935
+ /** 记录一条 compaction 观测事件(TUI 在 turn 结束时渲染一行 dim 摘要)。 */
4936
+ recordCompaction(event) {
4937
+ compactionEvent = event;
4938
+ },
3105
4939
  showWorking(label) {
3106
4940
  const activeLabel = label ?? workingLabel;
3107
4941
  spinner.show(activeLabel);
@@ -3136,6 +4970,10 @@ ${options.agentName} > (no text response)
3136
4970
  `);
3137
4971
  }
3138
4972
  }
4973
+ const compactionLine = formatCompactionSummaryLine(compactionEvent);
4974
+ if (compactionLine) {
4975
+ options.output.write(compactionLine);
4976
+ }
3139
4977
  }
3140
4978
  };
3141
4979
  }
@@ -3304,7 +5142,7 @@ async function detectCurrentMachineId(env) {
3304
5142
  const fromEnv = (env.NOLO_CURRENT_MACHINE_ID || env.NOLO_MACHINE_ID || "").trim();
3305
5143
  if (fromEnv) return fromEnv;
3306
5144
  try {
3307
- const { detectMachineInfo } = await import("./machineInfo-M6KB6HZN.js");
5145
+ const { detectMachineInfo } = await import("./machineInfo-66ZFUMLE.js");
3308
5146
  const machine = await detectMachineInfo({ probeLaunchable: true });
3309
5147
  return asOptionalTrimmedString(machine?.machineId);
3310
5148
  } catch {
@@ -3521,7 +5359,7 @@ function findCollapsedPasteSpanAt(buffer, pos, opts = {}) {
3521
5359
  // packages/cli/client/agentRun.ts
3522
5360
  import { ulid } from "ulid";
3523
5361
  async function loadRunLocalAgentTurn() {
3524
- const { runLocalAgentTurn } = await import("./agentRuntimeLocal-PRAR3NCW.js");
5362
+ const { runLocalAgentTurn } = await import("./agentRuntimeLocal-XXBMDMBU.js");
3525
5363
  return runLocalAgentTurn;
3526
5364
  }
3527
5365
  async function resolveCurrentMachineId(options) {
@@ -3753,6 +5591,10 @@ function describeLocalRunFailure(message) {
3753
5591
  }
3754
5592
  const cls = classifyLocalRunError(message);
3755
5593
  if (cls.kind === "generic") {
5594
+ if (isTransientFetchError(message)) {
5595
+ return `${RUN_UNAVAILABLE_PREFIX} (${message}). ${NO_FALLBACK} The upstream connection dropped mid-request (transient network/gateway issue \u2014 not a local credential or config problem). Send again (or say "continue") to retry in the same conversation.
5596
+ `;
5597
+ }
3756
5598
  return `${RUN_UNAVAILABLE_PREFIX} (${message}). ${NO_FALLBACK} Fix the local credential/config and retry, ${SERVER_FALLBACK_HINT}.
3757
5599
  `;
3758
5600
  }
@@ -4054,11 +5896,8 @@ async function runLocalAgentTurnForCli(options, settings) {
4054
5896
  "[nolo] \u5F53\u524D agent \u4E0D\u652F\u6301\u56FE\u7247\u8F93\u5165\uFF0C\u5DF2\u7528\u5360\u4F4D\u6587\u672C\u66FF\u4EE3\u3002\u8981\u5B8C\u6574\u56FE\u7247\u7406\u89E3\u53EF /switch \u5230 Kimi K2.6\u3002\n"
4055
5897
  );
4056
5898
  }
4057
- if (event.kind === "image-preprocessed") {
4058
- options.output.write(
4059
- `[nolo] \u5DF2\u7528\u89C6\u89C9\u6A21\u578B\u89E3\u6790 ${event.imageCount} \u5F20\u56FE\u7247\u4E3A\u6587\u5B57\u63CF\u8FF0\uFF0C\u4F9B\u5F53\u524D agent \u4F7F\u7528\u3002
4060
- `
4061
- );
5899
+ if (event.kind === "compaction") {
5900
+ turnOutput.recordCompaction(event);
4062
5901
  }
4063
5902
  options.onLoopEvent?.(event);
4064
5903
  },
@@ -4071,6 +5910,9 @@ async function runLocalAgentTurnForCli(options, settings) {
4071
5910
  ...!options.noStream ? {
4072
5911
  onTextDelta: (chunk) => {
4073
5912
  turnOutput.pushText(chunk);
5913
+ },
5914
+ onReasoningDelta: (chunk) => {
5915
+ turnOutput.pushThinking(chunk);
4074
5916
  }
4075
5917
  } : {}
4076
5918
  });
@@ -4080,6 +5922,7 @@ async function runLocalAgentTurnForCli(options, settings) {
4080
5922
  dialogId: result.dialogId,
4081
5923
  title: result.title,
4082
5924
  ...result.titlePatchPromise ? { titlePatchPromise: result.titlePatchPromise } : {},
5925
+ ...result.emptyAssistantFallbackReason ? { emptyAssistantFallbackReason: result.emptyAssistantFallbackReason } : {},
4083
5926
  turnTokens: buildTurnTokenUsage(result.usage, result.model)
4084
5927
  };
4085
5928
  } catch (error) {
@@ -4317,6 +6160,20 @@ ${patch}${skill.content}`);
4317
6160
  }
4318
6161
  return blocks;
4319
6162
  }
6163
+ var OUTPUT_FORMAT_GUIDANCE = [
6164
+ "Output format guidance:",
6165
+ "- Use semantic Markdown by default.",
6166
+ "- Use tables for genuinely multi-column structured data.",
6167
+ "- Use $...$ or $$...$$ for mathematical expressions.",
6168
+ "- Use ```mermaid fenced blocks only when diagrams materially clarify a process, dependency, architecture, or state transition.",
6169
+ "- Use language-tagged fenced blocks for code.",
6170
+ "- Do not add tables or Mermaid for decoration; when complex syntax is uncertain, prefer plain Markdown or text.",
6171
+ ""
6172
+ ].join("\n");
6173
+ function prependOutputFormatGuidance(message) {
6174
+ if (message.startsWith(OUTPUT_FORMAT_GUIDANCE)) return message;
6175
+ return `${OUTPUT_FORMAT_GUIDANCE}${message}`;
6176
+ }
4320
6177
  function prependWorkflowReferencePrompt(message, workflow) {
4321
6178
  if (!workflow) return message;
4322
6179
  const config = workflow.config;
@@ -4868,40 +6725,6 @@ var resolveCliMemory = async (input) => {
4868
6725
  }
4869
6726
  };
4870
6727
 
4871
- // packages/ai/tools/agent/quotaCircuitBreaker.ts
4872
- var QUOTA_ERROR_PATTERNS = [
4873
- /429/,
4874
- /quota/i,
4875
- /rate\s*limit/i,
4876
- /too\s*many\s*requests/i,
4877
- /额度/,
4878
- /上限/,
4879
- /用尽/,
4880
- /CliProviderQuotaError/i
4881
- ];
4882
- function isCliProviderQuotaErrorShape(error) {
4883
- if (!error || typeof error !== "object") return false;
4884
- const e = error;
4885
- return e.name === "CliProviderQuotaError" || typeof e.message === "string" && e.message.startsWith("[QUOTA_LIMITED:");
4886
- }
4887
- function isQuotaExhaustedError(error) {
4888
- if (!error) return false;
4889
- if (isCliProviderQuotaErrorShape(error)) return true;
4890
- if (error instanceof Error) {
4891
- return QUOTA_ERROR_PATTERNS.some((pattern) => pattern.test(error.message));
4892
- }
4893
- if (typeof error === "string") {
4894
- return QUOTA_ERROR_PATTERNS.some((pattern) => pattern.test(error));
4895
- }
4896
- const maybeStatus = error.status;
4897
- if (typeof maybeStatus === "number" && maybeStatus === 429) return true;
4898
- const maybeStatusCode = error.statusCode;
4899
- if (typeof maybeStatusCode === "number" && maybeStatusCode === 429) return true;
4900
- return false;
4901
- }
4902
- var DEFAULT_QUOTA_BREAKER_MS = 6 * 3600 * 1e3;
4903
- var DEFAULT_AGENT_NOT_FOUND_BREAKER_MS = 15 * 60 * 1e3;
4904
-
4905
6728
  // packages/cli/agentRunCommand.ts
4906
6729
  function resolvePositiveMs(value, fallback) {
4907
6730
  return parsePositiveFiniteNumberOrFallback(value, fallback);
@@ -5131,6 +6954,7 @@ async function runAgentRunCommand(args, deps) {
5131
6954
  msgFile: readFlagValue(args, "--msg-file"),
5132
6955
  message: parsed.message,
5133
6956
  timeoutMs: parsed.timeoutMs,
6957
+ ...parsed.dodCommands?.length ? { dodCommands: parsed.dodCommands } : {},
5134
6958
  output
5135
6959
  },
5136
6960
  {
@@ -5217,7 +7041,7 @@ async function runAgentRunCommand(args, deps) {
5217
7041
  message: prependWorkflowReferencePrompt(
5218
7042
  prependSubjectDialogMarker(
5219
7043
  prependFeatureWorktreeInstruction(
5220
- effectiveMessage,
7044
+ prependOutputFormatGuidance(effectiveMessage),
5221
7045
  parsed.injectFeatureWorktreeInstruction
5222
7046
  ),
5223
7047
  parsed.subjectDialogKey
@@ -5325,13 +7149,16 @@ async function runAgentRunCommand(args, deps) {
5325
7149
  }
5326
7150
  }
5327
7151
  if (typeof childRunId === "string" && childRunId.length > 0) {
5328
- const finalStatus = result.exitCode === 0 ? "done" : "failed";
7152
+ const isTruncated = result.emptyAssistantFallbackReason === "length_truncated" || result.emptyAssistantFallbackReason === "stream_truncated";
7153
+ const truncationNote = isTruncated ? { note: `empty assistant output: ${result.emptyAssistantFallbackReason}` } : {};
7154
+ const finalStatus = isTruncated || result.exitCode !== 0 ? "failed" : "done";
5329
7155
  await (deps.finalizeRunRecord ?? finalizeRunRecord)(
5330
7156
  childRunId,
5331
7157
  {
5332
7158
  status: finalStatus,
5333
7159
  exitCode: result.exitCode,
5334
- dialogId: result.dialogId
7160
+ dialogId: result.dialogId,
7161
+ ...truncationNote
5335
7162
  },
5336
7163
  {
5337
7164
  env,
@@ -5340,6 +7167,23 @@ async function runAgentRunCommand(args, deps) {
5340
7167
  now: deps.now
5341
7168
  }
5342
7169
  );
7170
+ try {
7171
+ const record = (deps.readRunRecord ?? readRunRecord)(childRunId, {
7172
+ env,
7173
+ homedir: deps.homedir,
7174
+ fs: deps.fs
7175
+ });
7176
+ if (record) {
7177
+ await (deps.generateRunReport ?? generateRunReport)(record, {
7178
+ env,
7179
+ homedir: deps.homedir,
7180
+ fs: deps.fs,
7181
+ now: deps.now
7182
+ });
7183
+ }
7184
+ } catch (reportError) {
7185
+ console.warn(`[nolo] failed to generate run report for ${childRunId}:`, reportError);
7186
+ }
5343
7187
  }
5344
7188
  return result.exitCode;
5345
7189
  }
@@ -5363,7 +7207,7 @@ export {
5363
7207
  resolveCliColorEnabled,
5364
7208
  dimCliText,
5365
7209
  ANSI_ESCAPE_REGEX,
5366
- stripAnsi,
7210
+ stripAnsi2 as stripAnsi,
5367
7211
  applyTerminalOutputToText,
5368
7212
  displayWidth,
5369
7213
  visibleWidth,
@@ -5372,25 +7216,32 @@ export {
5372
7216
  countPhysicalLines,
5373
7217
  takeDisplayWidth,
5374
7218
  padOrTruncateToWidth,
7219
+ tokenizeAnsiLine,
7220
+ buildSourceMapping,
7221
+ wrapTranscriptLineWithLayout,
5375
7222
  wrapTranscriptLine,
5376
7223
  buildWindowTitle,
5377
7224
  wrapTextToLines,
5378
7225
  THEME_PALETTES,
5379
7226
  getActiveThemeName,
5380
7227
  setActiveThemeName,
5381
- getActiveBrightness,
7228
+ getActiveThemeMode,
7229
+ setActiveThemeMode,
5382
7230
  setActiveBrightness,
5383
7231
  getActiveDensity,
5384
7232
  setActiveDensity,
5385
7233
  detectSystemBrightnessFromEnv,
5386
7234
  resolveTuiBrightness,
5387
- setActiveTerminalBaseHex,
7235
+ resolveTuiThemeMode,
7236
+ resetWorkspaceThemeState,
5388
7237
  applyDetectedBackground,
5389
7238
  renderSurfaceLine,
5390
7239
  surfaceBackgroundSequence,
5391
7240
  userSurfaceBackgroundSequence,
5392
7241
  themeColorSequence,
5393
7242
  themeText,
7243
+ tuiRenderThemeFingerprint,
7244
+ setMathRenderingEnabled,
5394
7245
  formatAssistantDisplay,
5395
7246
  normalizeToolDisplayMode,
5396
7247
  COLLAPSED_PASTE_PLACEHOLDER_RE,
@@ -5411,8 +7262,6 @@ export {
5411
7262
  normalizeCliImageInput,
5412
7263
  inspectLocalRunWorkspace,
5413
7264
  resolveCliMemory,
5414
- QUOTA_ERROR_PATTERNS,
5415
- isQuotaExhaustedError,
5416
7265
  runAgentRunCommand,
5417
7266
  isBalanceExhaustedError
5418
7267
  };