nolo-cli 0.50.0-alpha.1 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{_executeModel-4BPV4B2U.js → _executeModel-JKEH7ACW.js} +48 -42
- package/{action-IU6ON7ZB.js → action-VSG2IYP3.js} +8 -8
- package/{addContentAction-5V5CCI3I.js → addContentAction-2HJJITDI.js} +8 -7
- package/{addDialogAgentAction-KF3KZZNZ.js → addDialogAgentAction-7BSQVVL5.js} +10 -9
- package/{agentDeleteCommand-KZSETRE3.js → agentDeleteCommand-SVXKS5SC.js} +30 -28
- package/{agentEmailCommands-5TEW64UO.js → agentEmailCommands-WN7QBTP3.js} +57 -52
- package/{agentListCommands-KVLURCS7.js → agentListCommands-2BEBOQIG.js} +42 -33
- package/{agentMachineCommands-4LQF5YB5.js → agentMachineCommands-WALP3ONU.js} +30 -28
- package/{agentRecordCommands-OXC6JSH6.js → agentRecordCommands-E652SW57.js} +55 -50
- package/{agentRunCommand-4AXTA7MR.js → agentRunCommand-6VXWXKCS.js} +60 -53
- package/{agentRunControl-4GHHSXFZ.js → agentRunControl-LJVFDJGU.js} +3 -1
- package/{agentRuntimeLocal-SIQYQGSK.js → agentRuntimeLocal-SBG7BDFQ.js} +30 -26
- package/{agentSlice-VD3BAJAU.js → agentSlice-3WYXIGEO.js} +8 -8
- package/{agentSuperviseCommands-VB6BUS5H.js → agentSuperviseCommands-F3RFAL7K.js} +2 -2
- package/{appDeleteCommands-LSIIQFYN.js → appDeleteCommands-NTUNMEXY.js} +31 -29
- package/{appDeployCommands-VYGKN7HU.js → appDeployCommands-DISWXRTL.js} +31 -29
- package/{appDeployStatusCommands-ODFHFUR7.js → appDeployStatusCommands-IKRA6B6F.js} +31 -29
- package/{appGetCommands-DPQY67UZ.js → appGetCommands-UMOP2DFV.js} +31 -29
- package/{appListCommands-EFXENXWX.js → appListCommands-ZKFD2AKS.js} +31 -29
- package/{authCommand-WLWOEVYI.js → authCommand-BS3CQC6I.js} +11 -11
- package/{chatQueueReduxAdapter-N5432EP2.js → chatQueueReduxAdapter-A3YH4MT4.js} +24 -21
- package/{chunk-76UA7376.js → chunk-273FJUYI.js} +6 -6
- package/{chunk-7CH6U3FL.js → chunk-2GRGFCF6.js} +2 -4
- package/{chunk-T27IEBNQ.js → chunk-2QDDKFG5.js} +74 -1
- package/{chunk-WWXZYFWM.js → chunk-2TLYVDTN.js} +464 -1135
- package/{chunk-6BYAXNH5.js → chunk-3QOCS5IF.js} +11 -2
- package/chunk-6IGD47IC.js +19 -0
- package/{chunk-QDNFRWAX.js → chunk-6TUT5ZJD.js} +4 -6
- package/chunk-6YTOJY35.js +352 -0
- package/{chunk-B54WOZ77.js → chunk-7H7GQL6V.js} +2 -2
- package/{chunk-OYNDYVSE.js → chunk-B45YNDAE.js} +1 -1
- package/{chunk-OZ4JNDIL.js → chunk-BKIDF5LV.js} +1 -1
- package/{chunk-5XCW6RQG.js → chunk-BUBPRCIU.js} +1 -1
- package/chunk-BYXBJQAS.js +0 -0
- package/{chunk-X7S7OFUX.js → chunk-CEVCRRHU.js} +4 -4
- package/{chunk-JBL24PK6.js → chunk-DEIGUGP6.js} +2 -2
- package/{chunk-V2IPBG5U.js → chunk-DGEPT6FH.js} +1 -1
- package/{chunk-3AOLVADY.js → chunk-DVINR3PL.js} +1 -1
- package/{chunk-HMMOAG2I.js → chunk-DXOELY7S.js} +67 -69
- package/{chunk-OFZPJ3NT.js → chunk-E4MARS3Q.js} +1 -1
- package/{chunk-27MWS6HD.js → chunk-EAYBPWHX.js} +179 -86
- package/{chunk-DQLYEGP7.js → chunk-EGVY3GMT.js} +1 -1
- package/{chunk-2JYSSXLY.js → chunk-EJFW7TRP.js} +5 -26
- package/{chunk-4YAMAMNA.js → chunk-FGRCSLPV.js} +36 -46
- package/{chunk-VFN256RI.js → chunk-G4WSLTQF.js} +56 -97
- package/{chunk-HR5XDXYM.js → chunk-G5SQVIFZ.js} +3 -3
- package/{chunk-J3UALFHL.js → chunk-GHE5XMVR.js} +1 -1
- package/{chunk-7M72YPM2.js → chunk-GKB4AZKV.js} +440 -2981
- package/{chunk-S3HB4CQY.js → chunk-GKNGRBE6.js} +256 -40
- package/{chunk-Q24S4NDF.js → chunk-HQTK2SFT.js} +1 -1
- package/{chunk-XB7ACJFH.js → chunk-IPTZ5TVU.js} +7 -6
- package/{chunk-4RXXP6WD.js → chunk-J7KDNHUO.js} +5 -64
- package/{chunk-BO3YFOZR.js → chunk-KNQ5LYVZ.js} +57 -2
- package/{chunk-AV4Z57LV.js → chunk-KVVNC5V3.js} +2 -2
- package/{chunk-VKSBVRGP.js → chunk-LVCAWHI5.js} +4 -4
- package/{chunk-5JXRVJAC.js → chunk-N6SLQMSA.js} +6 -6
- package/{chunk-SQTVMYMU.js → chunk-NTZO3KX2.js} +3 -3
- package/{chunk-LGUQHYAL.js → chunk-O5FLGN2L.js} +3 -2
- package/{chunk-72COHDZR.js → chunk-OSUZKICS.js} +1600 -190
- package/{chunk-HIDPTO4B.js → chunk-Q2QN2RHG.js} +7 -7
- package/{chunk-L3JWI7WX.js → chunk-QOKAKDPE.js} +15 -11
- package/{chunk-4ZL2KBI7.js → chunk-RFYXK6KI.js} +1 -1
- package/chunk-RQSN75DW.js +1766 -0
- package/{chunk-RPO6WAZV.js → chunk-S3JNURSO.js} +2 -2
- package/{chunk-YZ2WE6CW.js → chunk-SAJSBPI2.js} +2 -2
- package/{chunk-WHVQA7PJ.js → chunk-SCBBGS2N.js} +23 -5
- package/chunk-SGSJBBKP.js +297 -0
- package/{chunk-FTSPVLKJ.js → chunk-TUBNQ3OF.js} +2 -2
- package/{chunk-BANYWEYY.js → chunk-TY3ADTX5.js} +1 -1
- package/chunk-UAD2WT54.js +64 -0
- package/{chunk-F22JQTSX.js → chunk-UEV5WVQV.js} +3 -3
- package/{chunk-MCX2LX27.js → chunk-UMCMW5R3.js} +51 -34
- package/{chunk-6L6UPZNH.js → chunk-VFDRZHPM.js} +16 -16
- package/{chunk-C2WF2OY7.js → chunk-W22UTILW.js} +3 -3
- package/{chunk-W3RZLXMA.js → chunk-WERPP2S7.js} +2 -2
- package/{chunk-AZ6DT2UD.js → chunk-WSUHBABG.js} +1 -1
- package/{chunk-3YVCM5PE.js → chunk-X3OGKR5Q.js} +4 -4
- package/{chunk-IERBSHMR.js → chunk-X5LRMXTS.js} +10 -10
- package/{chunk-DIQCV4FR.js → chunk-X665UCNM.js} +1 -1
- package/{chunk-HCBQVVFZ.js → chunk-X7P6EJUY.js} +4 -4
- package/{chunk-HHBXCRJS.js → chunk-XOJRZUPF.js} +4 -4
- package/{chunk-MRWGHF56.js → chunk-YDH3FDFQ.js} +12 -356
- package/{chunk-TNPCQNGQ.js → chunk-YEFRCO5N.js} +4 -9
- package/{chunk-RO2IUWZE.js → chunk-YUKTCDVN.js} +1 -1
- package/{chunk-Y7TGWSUN.js → chunk-YWY25N4V.js} +1 -1
- package/{chunk-Z7A54NFZ.js → chunk-ZDS63Y4O.js} +2 -2
- package/chunk-ZJ7UHBJS.js +89 -0
- package/{chunk-SG65C33A.js → chunk-ZLMG6NRV.js} +4 -4
- package/{codingSkills-BYQI6EPT.js → codingSkills-FQPCEIWL.js} +2 -2
- package/contentThunks-J33BZB3E.js +71 -0
- package/{createAgentAutomationAction-IHKV53QC.js → createAgentAutomationAction-HTMTGX6Q.js} +25 -21
- package/{createDialogAction-4ARDCKPP.js → createDialogAction-WYQBSN6A.js} +27 -23
- package/{createPageAction-GQOCPICU.js → createPageAction-ICRRK3SA.js} +27 -22
- package/{dbSlice-FWF5F4L7.js → dbSlice-YORO4VL4.js} +6 -6
- package/{deleteFile-NPZ64DFN.js → deleteFile-JYKRT7C3.js} +4 -4
- package/{dialogCommands-YOTCP26N.js → dialogCommands-FRSIAPKY.js} +31 -29
- package/{dialogSlice-NX26W623.js → dialogSlice-5KPVIAWH.js} +24 -21
- package/{docCreateCommands-JVAMHES4.js → docCreateCommands-DBRJMPDX.js} +30 -28
- package/{docDeleteCommands-LW5DWICT.js → docDeleteCommands-BCYPLWXN.js} +31 -29
- package/{docReadCommands-AQOZS3I5.js → docReadCommands-L5JX4Q7G.js} +30 -28
- package/{docStore-YAE7GYHZ.js → docStore-34NXLCEO.js} +8 -33
- package/{docUpdateCommands-FFGGX5RG.js → docUpdateCommands-RELG7XJD.js} +30 -28
- package/fetchMessages-KZQVBXKY.js +1 -1
- package/{getPricing-JNOCWYDH.js → getPricing-FM7TJZFV.js} +4 -4
- package/{handleSendMessageAction-7YKH4UBI.js → handleSendMessageAction-MEYK7RPD.js} +25 -22
- package/index.js +64 -64
- package/{machineCommands-FMMFBMCQ.js → machineCommands-YSXTOWHQ.js} +59 -54
- package/{machineWsRunDispatch-UODRJY63.js → machineWsRunDispatch-DNAYOPQT.js} +54 -49
- package/memberThunks-KVPBG4V7.js +638 -0
- package/{models-N4NXQ44D.js → models-CW5EL6Z7.js} +2 -2
- package/package.json +2 -3
- package/{read-J7RVVCHH.js → read-NIOV5F7W.js} +4 -4
- package/{readDocTool-G2WBM4IH.js → readDocTool-ULKJ5BEM.js} +1 -1
- package/{readlineWorkspace-GVDEA7RH.js → readlineWorkspace-KZ3LPQG2.js} +866 -377
- package/{removeDialogAgentAction-RMPISD42.js → removeDialogAgentAction-JGSCPML3.js} +12 -11
- package/{runAgentClientLoop-6NCW5AS6.js → runAgentClientLoop-O2AUHIJT.js} +46 -40
- package/{setDialogExtraReferencesAction-7BUTHDAL.js → setDialogExtraReferencesAction-CORU64NM.js} +9 -8
- package/{setPrimaryDialogAgentAction-WCYIBGZ4.js → setPrimaryDialogAgentAction-5VS2VKLZ.js} +12 -11
- package/{settingSlice-7NN2MI6Y.js → settingSlice-3GNGTC2T.js} +7 -7
- package/{skillDiscovery-COX56OBO.js → skillDiscovery-CYUCJMAG.js} +3 -3
- package/{spaceCommands-7MJVL4XR.js → spaceCommands-OI7RIB2T.js} +30 -28
- package/{streamAgentChatTurn-UAKCHWFN.js → streamAgentChatTurn-TA3PGS6C.js} +61 -54
- package/{switchDialogAgentAction-WGMMQHDI.js → switchDialogAgentAction-LP433X4D.js} +10 -9
- package/{tableCommands-P2TXJ3CF.js → tableCommands-R6WFRDYF.js} +1 -1
- package/{toolApiClient-B2MFXMEG.js → toolApiClient-53U4UDFF.js} +3 -2
- package/{tools-ROUITGAR.js → tools-6ZPQ75XA.js} +37 -32
- package/{tuiSummaryLlmCaller-U4EGD2SX.js → tuiSummaryLlmCaller-YKYQB4ZL.js} +17 -15
- package/{updateDialogTitleAction-R4M6ZXCX.js → updateDialogTitleAction-LRJ7NSOS.js} +26 -22
- package/chunk-EUG45QJR.js +0 -6104
- package/spaceSlice-JVVDCGA3.js +0 -127
- package/{chunk-NQ4N4IGO.js → chunk-CS6TCJ7E.js} +3 -3
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
generateRunReport
|
|
3
|
-
} from "./chunk-J3UALFHL.js";
|
|
4
1
|
import {
|
|
5
2
|
buildLocalRunEnv,
|
|
6
3
|
isFullstackCodingAgentRef,
|
|
@@ -10,6 +7,9 @@ import {
|
|
|
10
7
|
resolveServerUrl,
|
|
11
8
|
writeUsage
|
|
12
9
|
} from "./chunk-LYGNQHUW.js";
|
|
10
|
+
import {
|
|
11
|
+
resolveMachineId
|
|
12
|
+
} from "./chunk-ESHYE7WU.js";
|
|
13
13
|
import {
|
|
14
14
|
agentRunCardLabels,
|
|
15
15
|
createCliLocalRuntimeAdapter,
|
|
@@ -19,7 +19,12 @@ import {
|
|
|
19
19
|
parseAgentRunEvent,
|
|
20
20
|
t,
|
|
21
21
|
toolLabel
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-EAYBPWHX.js";
|
|
23
|
+
import {
|
|
24
|
+
readCredentialEntry,
|
|
25
|
+
recordCredentialProbe,
|
|
26
|
+
resolveCredentialKeyWithFallback
|
|
27
|
+
} from "./chunk-NI2BS6UD.js";
|
|
23
28
|
import {
|
|
24
29
|
getReadableCliDb
|
|
25
30
|
} from "./chunk-43CXXVJD.js";
|
|
@@ -27,11 +32,14 @@ import {
|
|
|
27
32
|
normalizeAgentHandle,
|
|
28
33
|
readDbRecord,
|
|
29
34
|
resolveAgentRecordFromHybridStore
|
|
30
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-EGVY3GMT.js";
|
|
31
36
|
import {
|
|
32
37
|
NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
33
38
|
isLocalCliAgentKey
|
|
34
39
|
} from "./chunk-EKLRRZIN.js";
|
|
40
|
+
import {
|
|
41
|
+
generateRunReport
|
|
42
|
+
} from "./chunk-GHE5XMVR.js";
|
|
35
43
|
import {
|
|
36
44
|
CliProviderQuotaError
|
|
37
45
|
} from "./chunk-JDSUTNYY.js";
|
|
@@ -42,17 +50,14 @@ import {
|
|
|
42
50
|
readRunRecord,
|
|
43
51
|
resolveRunQueuePath,
|
|
44
52
|
spawnLocalBackgroundRun
|
|
45
|
-
} from "./chunk-
|
|
46
|
-
import {
|
|
47
|
-
resolveMachineId
|
|
48
|
-
} from "./chunk-ESHYE7WU.js";
|
|
53
|
+
} from "./chunk-SCBBGS2N.js";
|
|
49
54
|
import {
|
|
50
55
|
applyModelLayerOverride,
|
|
51
56
|
buildModelLayerOverride
|
|
52
57
|
} from "./chunk-LTRXGFMS.js";
|
|
53
58
|
import {
|
|
54
59
|
formatAgentListCard
|
|
55
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-OSUZKICS.js";
|
|
56
61
|
import {
|
|
57
62
|
isTransientFetchError
|
|
58
63
|
} from "./chunk-5XTOKQLW.js";
|
|
@@ -66,26 +71,25 @@ import {
|
|
|
66
71
|
formatStartRunCard,
|
|
67
72
|
formatStatusRunCard,
|
|
68
73
|
formatStopRunCard,
|
|
69
|
-
isAgentRunTerminalStatus
|
|
70
|
-
runShowsLogTail
|
|
74
|
+
isAgentRunTerminalStatus
|
|
71
75
|
} from "./chunk-KXKQO4Q6.js";
|
|
72
76
|
import {
|
|
73
77
|
buildMemorySubjectsForAgent,
|
|
74
78
|
chooseMemoryOwners,
|
|
75
79
|
loadMemoryCandidatesFromDb,
|
|
76
80
|
resolveAgentMemoryPolicy
|
|
77
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-X5LRMXTS.js";
|
|
78
82
|
import {
|
|
79
83
|
API_REPORTED_COST_MULTIPLIER,
|
|
80
84
|
normalizeUsage,
|
|
81
85
|
parseUiAskChoiceContent
|
|
82
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-UMCMW5R3.js";
|
|
83
87
|
import {
|
|
84
88
|
getDefaultCliLocalRuntimeDb
|
|
85
89
|
} from "./chunk-IA3A5373.js";
|
|
86
90
|
import {
|
|
87
91
|
buildSkillDiscoveryContextLayer
|
|
88
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-E4MARS3Q.js";
|
|
89
93
|
import {
|
|
90
94
|
parseExternalSkillMarkdown,
|
|
91
95
|
parseSkillDocProtocol
|
|
@@ -93,12 +97,11 @@ import {
|
|
|
93
97
|
import {
|
|
94
98
|
LOCAL_AGENT_CONFIG_MISSING_CODE,
|
|
95
99
|
LOCAL_TURN_ABORTED_CODE,
|
|
96
|
-
readActionGate
|
|
97
|
-
|
|
98
|
-
} from "./chunk-S3HB4CQY.js";
|
|
100
|
+
readActionGate
|
|
101
|
+
} from "./chunk-GKNGRBE6.js";
|
|
99
102
|
import {
|
|
100
103
|
resolveAgentRuntimeConfigFromRecord
|
|
101
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-LVCAWHI5.js";
|
|
102
105
|
import {
|
|
103
106
|
createThinkParserState,
|
|
104
107
|
flushThinkParser,
|
|
@@ -107,20 +110,22 @@ import {
|
|
|
107
110
|
import {
|
|
108
111
|
resolveClientVersion,
|
|
109
112
|
resolvePlatformAuthToken
|
|
110
|
-
} from "./chunk-
|
|
113
|
+
} from "./chunk-DEIGUGP6.js";
|
|
111
114
|
import {
|
|
112
|
-
isQuotaExhaustedError
|
|
115
|
+
isQuotaExhaustedError,
|
|
116
|
+
mergeAvailabilityDeadline,
|
|
117
|
+
resolveCooldownGate
|
|
113
118
|
} from "./chunk-IWUMSAQF.js";
|
|
114
119
|
import {
|
|
115
120
|
DEFAULT_CONTEXT_WINDOW,
|
|
116
121
|
getModelContextWindow
|
|
117
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-UEV5WVQV.js";
|
|
118
123
|
import {
|
|
119
124
|
clipCompactText
|
|
120
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-G5SQVIFZ.js";
|
|
121
126
|
import {
|
|
122
127
|
findModelConfig
|
|
123
|
-
} from "./chunk-
|
|
128
|
+
} from "./chunk-KNQ5LYVZ.js";
|
|
124
129
|
import {
|
|
125
130
|
compactWhitespace
|
|
126
131
|
} from "./chunk-DWLEOOGR.js";
|
|
@@ -133,7 +138,7 @@ import {
|
|
|
133
138
|
buildMemoryUseGuidanceLayer,
|
|
134
139
|
partitionScopedBlocks,
|
|
135
140
|
renderTurnContextBlocksWithScope
|
|
136
|
-
} from "./chunk-
|
|
141
|
+
} from "./chunk-DVINR3PL.js";
|
|
137
142
|
import {
|
|
138
143
|
readPipeText,
|
|
139
144
|
spawnProcess
|
|
@@ -145,7 +150,7 @@ import {
|
|
|
145
150
|
CLIENT_VERSION_TOO_OLD_CODE,
|
|
146
151
|
NOLO_CLIENT_VERSION_HEADER,
|
|
147
152
|
buildClientVersionUpgradeMessage
|
|
148
|
-
} from "./chunk-
|
|
153
|
+
} from "./chunk-G4WSLTQF.js";
|
|
149
154
|
import {
|
|
150
155
|
parsePositiveFiniteNumberOrFallback
|
|
151
156
|
} from "./chunk-Y5GCAMGP.js";
|
|
@@ -159,7 +164,7 @@ import {
|
|
|
159
164
|
BUILTIN_NOLO_AGENT_KEY,
|
|
160
165
|
BUILTIN_NOLO_AGENT_NAME,
|
|
161
166
|
builtinAgentCatalogEntryById
|
|
162
|
-
} from "./chunk-
|
|
167
|
+
} from "./chunk-EJFW7TRP.js";
|
|
163
168
|
import {
|
|
164
169
|
parsePublicAgentId
|
|
165
170
|
} from "./chunk-BJIRLHJR.js";
|
|
@@ -1240,13 +1245,6 @@ function setActiveThemeMode(mode) {
|
|
|
1240
1245
|
function setActiveBrightness(brightness) {
|
|
1241
1246
|
setActiveThemeMode(brightness ?? "terminal");
|
|
1242
1247
|
}
|
|
1243
|
-
var activeDensity = "spacious";
|
|
1244
|
-
function getActiveDensity() {
|
|
1245
|
-
return activeDensity;
|
|
1246
|
-
}
|
|
1247
|
-
function setActiveDensity(density) {
|
|
1248
|
-
activeDensity = density;
|
|
1249
|
-
}
|
|
1250
1248
|
var TRUECOLOR_TERM_PROGRAMS = /* @__PURE__ */ new Set([
|
|
1251
1249
|
"iterm.app",
|
|
1252
1250
|
"wezterm",
|
|
@@ -2824,11 +2822,6 @@ function scanStringCommentRegions(line, lang) {
|
|
|
2824
2822
|
}
|
|
2825
2823
|
return regions;
|
|
2826
2824
|
}
|
|
2827
|
-
function detectCodeLangFromPath(filePath) {
|
|
2828
|
-
if (!filePath) return "unknown";
|
|
2829
|
-
const ext = filePath.split(".").pop() ?? "";
|
|
2830
|
-
return normalizeCodeLang(ext);
|
|
2831
|
-
}
|
|
2832
2825
|
function highlightCodeLine(line, lang, brightness) {
|
|
2833
2826
|
const info = colorSeq("info", brightness);
|
|
2834
2827
|
if (lang === "unknown") {
|
|
@@ -2915,6 +2908,14 @@ function normalizeListLine(line) {
|
|
|
2915
2908
|
}
|
|
2916
2909
|
return line;
|
|
2917
2910
|
}
|
|
2911
|
+
function isPolishListLikeLine(line) {
|
|
2912
|
+
return LIST_LIKE_RE_FOR_GUARD.test(normalizeListLine(line));
|
|
2913
|
+
}
|
|
2914
|
+
var LIST_LIKE_RE_FOR_GUARD = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
|
|
2915
|
+
function polishBreathInsertsBlankBetween(cur, next) {
|
|
2916
|
+
if (cur === "" || next === "") return false;
|
|
2917
|
+
return isPolishListLikeLine(cur) !== isPolishListLikeLine(next);
|
|
2918
|
+
}
|
|
2918
2919
|
function convertMarkdownTablesForTerminal(text) {
|
|
2919
2920
|
const lines = text.split("\n");
|
|
2920
2921
|
const out = [];
|
|
@@ -2982,7 +2983,7 @@ function polishAssistantStructure(text, options = {}) {
|
|
|
2982
2983
|
return line;
|
|
2983
2984
|
});
|
|
2984
2985
|
const afterHeading = maskedLines.join("\n").replace(/([^\n])\n(#{1,3} )/g, "$1\n\n$2").replace(/^(#{1,3} .+)\n(?!\n)/gm, "$1\n\n").replace(/\n{4,}/g, "\n\n\n");
|
|
2985
|
-
const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]/;
|
|
2986
|
+
const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
|
|
2986
2987
|
const headingLines = afterHeading.split("\n");
|
|
2987
2988
|
const breathed = [];
|
|
2988
2989
|
for (let i = 0; i < headingLines.length; i++) {
|
|
@@ -3401,16 +3402,6 @@ function formatReadItemPath(rawPath, metadata, customHomedir) {
|
|
|
3401
3402
|
const clippedPath = clipPathAware(formattedPath, 72);
|
|
3402
3403
|
return `${clippedPath}${rangePart}`;
|
|
3403
3404
|
}
|
|
3404
|
-
function formatReadTreeLines(items, customHomedir) {
|
|
3405
|
-
const count = items.length;
|
|
3406
|
-
const header = `Read (${count})`;
|
|
3407
|
-
const lines = items.map((item, index) => {
|
|
3408
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3409
|
-
const pathWithRange = formatReadItemPath(item.path, item.metadata, customHomedir);
|
|
3410
|
-
return { connector, pathWithRange };
|
|
3411
|
-
});
|
|
3412
|
-
return { header, count, lines };
|
|
3413
|
-
}
|
|
3414
3405
|
function formatSearchItemQuery(query, path, customHomedir) {
|
|
3415
3406
|
let text = (query || "").trim();
|
|
3416
3407
|
if (path) {
|
|
@@ -3422,16 +3413,6 @@ function formatSearchItemQuery(query, path, customHomedir) {
|
|
|
3422
3413
|
if (!text) return "search";
|
|
3423
3414
|
return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3424
3415
|
}
|
|
3425
|
-
function formatSearchTreeLines(items, customHomedir) {
|
|
3426
|
-
const count = items.length;
|
|
3427
|
-
const header = `Search (${count})`;
|
|
3428
|
-
const lines = items.map((item, index) => {
|
|
3429
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3430
|
-
const queryText = formatSearchItemQuery(item.query, item.path, customHomedir);
|
|
3431
|
-
return { connector, queryText };
|
|
3432
|
-
});
|
|
3433
|
-
return { header, count, lines };
|
|
3434
|
-
}
|
|
3435
3416
|
function formatRunItemCommand(command, exitCode, timedOut) {
|
|
3436
3417
|
let text = compactWhitespace(command || "");
|
|
3437
3418
|
if (!text) text = "command";
|
|
@@ -3440,453 +3421,24 @@ function formatRunItemCommand(command, exitCode, timedOut) {
|
|
|
3440
3421
|
if (typeof exitCode === "number" && exitCode !== 0) return `${text} (exit ${exitCode})`;
|
|
3441
3422
|
return text;
|
|
3442
3423
|
}
|
|
3443
|
-
function formatRunTreeLines(items) {
|
|
3444
|
-
const count = items.length;
|
|
3445
|
-
const header = `Run (${count})`;
|
|
3446
|
-
const lines = items.map((item, index) => {
|
|
3447
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3448
|
-
const commandText = formatRunItemCommand(item.command, item.exitCode, item.timedOut);
|
|
3449
|
-
return { connector, commandText };
|
|
3450
|
-
});
|
|
3451
|
-
return { header, count, lines };
|
|
3452
|
-
}
|
|
3453
3424
|
function formatFetchItemUrl(url) {
|
|
3454
3425
|
const text = (url || "").trim();
|
|
3455
3426
|
if (!text) return "webpage";
|
|
3456
3427
|
return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3457
3428
|
}
|
|
3458
|
-
function formatFetchTreeLines(items) {
|
|
3459
|
-
const count = items.length;
|
|
3460
|
-
const header = `Fetch (${count})`;
|
|
3461
|
-
const lines = items.map((item, index) => {
|
|
3462
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3463
|
-
const urlText = formatFetchItemUrl(item.url);
|
|
3464
|
-
return { connector, urlText };
|
|
3465
|
-
});
|
|
3466
|
-
return { header, count, lines };
|
|
3467
|
-
}
|
|
3468
|
-
|
|
3469
|
-
// node_modules/diff/libesm/diff/base.js
|
|
3470
|
-
var Diff = class {
|
|
3471
|
-
diff(oldStr, newStr, options = {}) {
|
|
3472
|
-
let callback;
|
|
3473
|
-
if (typeof options === "function") {
|
|
3474
|
-
callback = options;
|
|
3475
|
-
options = {};
|
|
3476
|
-
} else if ("callback" in options) {
|
|
3477
|
-
callback = options.callback;
|
|
3478
|
-
}
|
|
3479
|
-
const oldString = this.castInput(oldStr, options);
|
|
3480
|
-
const newString = this.castInput(newStr, options);
|
|
3481
|
-
const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
|
|
3482
|
-
const newTokens = this.removeEmpty(this.tokenize(newString, options));
|
|
3483
|
-
return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);
|
|
3484
|
-
}
|
|
3485
|
-
diffWithOptionsObj(oldTokens, newTokens, options, callback) {
|
|
3486
|
-
var _a;
|
|
3487
|
-
const done = (value) => {
|
|
3488
|
-
value = this.postProcess(value, options);
|
|
3489
|
-
if (callback) {
|
|
3490
|
-
setTimeout(function() {
|
|
3491
|
-
callback(value);
|
|
3492
|
-
}, 0);
|
|
3493
|
-
return void 0;
|
|
3494
|
-
} else {
|
|
3495
|
-
return value;
|
|
3496
|
-
}
|
|
3497
|
-
};
|
|
3498
|
-
const newLen = newTokens.length, oldLen = oldTokens.length;
|
|
3499
|
-
let editLength = 1;
|
|
3500
|
-
let maxEditLength = newLen + oldLen;
|
|
3501
|
-
if (options.maxEditLength != null) {
|
|
3502
|
-
maxEditLength = Math.min(maxEditLength, options.maxEditLength);
|
|
3503
|
-
}
|
|
3504
|
-
const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity;
|
|
3505
|
-
const abortAfterTimestamp = Date.now() + maxExecutionTime;
|
|
3506
|
-
const bestPath = [{ oldPos: -1, lastComponent: void 0 }];
|
|
3507
|
-
let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
|
|
3508
|
-
if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
|
|
3509
|
-
return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
|
|
3510
|
-
}
|
|
3511
|
-
let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
|
|
3512
|
-
const execEditLength = () => {
|
|
3513
|
-
for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
|
|
3514
|
-
let basePath;
|
|
3515
|
-
const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];
|
|
3516
|
-
if (removePath) {
|
|
3517
|
-
bestPath[diagonalPath - 1] = void 0;
|
|
3518
|
-
}
|
|
3519
|
-
let canAdd = false;
|
|
3520
|
-
if (addPath) {
|
|
3521
|
-
const addPathNewPos = addPath.oldPos - diagonalPath;
|
|
3522
|
-
canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;
|
|
3523
|
-
}
|
|
3524
|
-
const canRemove = removePath && removePath.oldPos + 1 < oldLen;
|
|
3525
|
-
if (!canAdd && !canRemove) {
|
|
3526
|
-
bestPath[diagonalPath] = void 0;
|
|
3527
|
-
continue;
|
|
3528
|
-
}
|
|
3529
|
-
if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
|
|
3530
|
-
basePath = this.addToPath(addPath, true, false, 0, options);
|
|
3531
|
-
} else {
|
|
3532
|
-
basePath = this.addToPath(removePath, false, true, 1, options);
|
|
3533
|
-
}
|
|
3534
|
-
newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);
|
|
3535
|
-
if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
|
|
3536
|
-
return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;
|
|
3537
|
-
} else {
|
|
3538
|
-
bestPath[diagonalPath] = basePath;
|
|
3539
|
-
if (basePath.oldPos + 1 >= oldLen) {
|
|
3540
|
-
maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
|
|
3541
|
-
}
|
|
3542
|
-
if (newPos + 1 >= newLen) {
|
|
3543
|
-
minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
|
|
3544
|
-
}
|
|
3545
|
-
}
|
|
3546
|
-
}
|
|
3547
|
-
editLength++;
|
|
3548
|
-
};
|
|
3549
|
-
if (callback) {
|
|
3550
|
-
(function exec() {
|
|
3551
|
-
setTimeout(function() {
|
|
3552
|
-
if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
|
|
3553
|
-
return callback(void 0);
|
|
3554
|
-
}
|
|
3555
|
-
if (!execEditLength()) {
|
|
3556
|
-
exec();
|
|
3557
|
-
}
|
|
3558
|
-
}, 0);
|
|
3559
|
-
})();
|
|
3560
|
-
} else {
|
|
3561
|
-
while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
|
|
3562
|
-
const ret = execEditLength();
|
|
3563
|
-
if (ret) {
|
|
3564
|
-
return ret;
|
|
3565
|
-
}
|
|
3566
|
-
}
|
|
3567
|
-
}
|
|
3568
|
-
}
|
|
3569
|
-
addToPath(path, added, removed, oldPosInc, options) {
|
|
3570
|
-
const last = path.lastComponent;
|
|
3571
|
-
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
3572
|
-
return {
|
|
3573
|
-
oldPos: path.oldPos + oldPosInc,
|
|
3574
|
-
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
3575
|
-
};
|
|
3576
|
-
} else {
|
|
3577
|
-
return {
|
|
3578
|
-
oldPos: path.oldPos + oldPosInc,
|
|
3579
|
-
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
3580
|
-
};
|
|
3581
|
-
}
|
|
3582
|
-
}
|
|
3583
|
-
extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
|
|
3584
|
-
const newLen = newTokens.length, oldLen = oldTokens.length;
|
|
3585
|
-
let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
|
|
3586
|
-
while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
|
|
3587
|
-
newPos++;
|
|
3588
|
-
oldPos++;
|
|
3589
|
-
commonCount++;
|
|
3590
|
-
if (options.oneChangePerToken) {
|
|
3591
|
-
basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
3592
|
-
}
|
|
3593
|
-
}
|
|
3594
|
-
if (commonCount && !options.oneChangePerToken) {
|
|
3595
|
-
basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
3596
|
-
}
|
|
3597
|
-
basePath.oldPos = oldPos;
|
|
3598
|
-
return newPos;
|
|
3599
|
-
}
|
|
3600
|
-
equals(left, right, options) {
|
|
3601
|
-
if (options.comparator) {
|
|
3602
|
-
return options.comparator(left, right);
|
|
3603
|
-
} else {
|
|
3604
|
-
return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
|
|
3605
|
-
}
|
|
3606
|
-
}
|
|
3607
|
-
removeEmpty(array) {
|
|
3608
|
-
const ret = [];
|
|
3609
|
-
for (let i = 0; i < array.length; i++) {
|
|
3610
|
-
if (array[i]) {
|
|
3611
|
-
ret.push(array[i]);
|
|
3612
|
-
}
|
|
3613
|
-
}
|
|
3614
|
-
return ret;
|
|
3615
|
-
}
|
|
3616
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3617
|
-
castInput(value, options) {
|
|
3618
|
-
return value;
|
|
3619
|
-
}
|
|
3620
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3621
|
-
tokenize(value, options) {
|
|
3622
|
-
return Array.from(value);
|
|
3623
|
-
}
|
|
3624
|
-
join(chars) {
|
|
3625
|
-
return chars.join("");
|
|
3626
|
-
}
|
|
3627
|
-
postProcess(changeObjects, options) {
|
|
3628
|
-
return changeObjects;
|
|
3629
|
-
}
|
|
3630
|
-
get useLongestToken() {
|
|
3631
|
-
return false;
|
|
3632
|
-
}
|
|
3633
|
-
buildValues(lastComponent, newTokens, oldTokens) {
|
|
3634
|
-
const components = [];
|
|
3635
|
-
let nextComponent;
|
|
3636
|
-
while (lastComponent) {
|
|
3637
|
-
components.push(lastComponent);
|
|
3638
|
-
nextComponent = lastComponent.previousComponent;
|
|
3639
|
-
delete lastComponent.previousComponent;
|
|
3640
|
-
lastComponent = nextComponent;
|
|
3641
|
-
}
|
|
3642
|
-
components.reverse();
|
|
3643
|
-
const componentLen = components.length;
|
|
3644
|
-
let componentPos = 0, newPos = 0, oldPos = 0;
|
|
3645
|
-
for (; componentPos < componentLen; componentPos++) {
|
|
3646
|
-
const component = components[componentPos];
|
|
3647
|
-
if (!component.removed) {
|
|
3648
|
-
if (!component.added && this.useLongestToken) {
|
|
3649
|
-
let value = newTokens.slice(newPos, newPos + component.count);
|
|
3650
|
-
value = value.map(function(value2, i) {
|
|
3651
|
-
const oldValue = oldTokens[oldPos + i];
|
|
3652
|
-
return oldValue.length > value2.length ? oldValue : value2;
|
|
3653
|
-
});
|
|
3654
|
-
component.value = this.join(value);
|
|
3655
|
-
} else {
|
|
3656
|
-
component.value = this.join(newTokens.slice(newPos, newPos + component.count));
|
|
3657
|
-
}
|
|
3658
|
-
newPos += component.count;
|
|
3659
|
-
if (!component.added) {
|
|
3660
|
-
oldPos += component.count;
|
|
3661
|
-
}
|
|
3662
|
-
} else {
|
|
3663
|
-
component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
|
|
3664
|
-
oldPos += component.count;
|
|
3665
|
-
}
|
|
3666
|
-
}
|
|
3667
|
-
return components;
|
|
3668
|
-
}
|
|
3669
|
-
};
|
|
3670
|
-
|
|
3671
|
-
// node_modules/diff/libesm/diff/line.js
|
|
3672
|
-
var LineDiff = class extends Diff {
|
|
3673
|
-
constructor() {
|
|
3674
|
-
super(...arguments);
|
|
3675
|
-
this.tokenize = tokenize;
|
|
3676
|
-
}
|
|
3677
|
-
equals(left, right, options) {
|
|
3678
|
-
if (options.ignoreWhitespace) {
|
|
3679
|
-
if (!options.newlineIsToken || !left.includes("\n")) {
|
|
3680
|
-
left = left.trim();
|
|
3681
|
-
}
|
|
3682
|
-
if (!options.newlineIsToken || !right.includes("\n")) {
|
|
3683
|
-
right = right.trim();
|
|
3684
|
-
}
|
|
3685
|
-
} else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
|
|
3686
|
-
if (left.endsWith("\n")) {
|
|
3687
|
-
left = left.slice(0, -1);
|
|
3688
|
-
}
|
|
3689
|
-
if (right.endsWith("\n")) {
|
|
3690
|
-
right = right.slice(0, -1);
|
|
3691
|
-
}
|
|
3692
|
-
}
|
|
3693
|
-
return super.equals(left, right, options);
|
|
3694
|
-
}
|
|
3695
|
-
};
|
|
3696
|
-
var lineDiff = new LineDiff();
|
|
3697
|
-
function diffLines(oldStr, newStr, options) {
|
|
3698
|
-
return lineDiff.diff(oldStr, newStr, options);
|
|
3699
|
-
}
|
|
3700
|
-
function tokenize(value, options) {
|
|
3701
|
-
if (options.stripTrailingCr) {
|
|
3702
|
-
value = value.replace(/\r\n/g, "\n");
|
|
3703
|
-
}
|
|
3704
|
-
const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/);
|
|
3705
|
-
if (!linesAndNewlines[linesAndNewlines.length - 1]) {
|
|
3706
|
-
linesAndNewlines.pop();
|
|
3707
|
-
}
|
|
3708
|
-
for (let i = 0; i < linesAndNewlines.length; i++) {
|
|
3709
|
-
const line = linesAndNewlines[i];
|
|
3710
|
-
if (i % 2 && !options.newlineIsToken) {
|
|
3711
|
-
retLines[retLines.length - 1] += line;
|
|
3712
|
-
} else {
|
|
3713
|
-
retLines.push(line);
|
|
3714
|
-
}
|
|
3715
|
-
}
|
|
3716
|
-
return retLines;
|
|
3717
|
-
}
|
|
3718
3429
|
|
|
3719
3430
|
// packages/cli/client/toolOutput.ts
|
|
3720
|
-
function normalizeToolDisplayMode(raw, fallback = "normal") {
|
|
3721
|
-
const normalized = asTrimmedLowercaseString(raw);
|
|
3722
|
-
if (normalized === "hide" || normalized === "off" || normalized === "false" || normalized === "0") {
|
|
3723
|
-
return "hide";
|
|
3724
|
-
}
|
|
3725
|
-
if (normalized === "verbose" || normalized === "debug" || normalized === "trace" || normalized === "full") {
|
|
3726
|
-
return "verbose";
|
|
3727
|
-
}
|
|
3728
|
-
if (normalized === "normal" || normalized === "summary" || normalized === "on") {
|
|
3729
|
-
return "normal";
|
|
3730
|
-
}
|
|
3731
|
-
if (normalized === "pro" || normalized === "compact" || normalized === "minimal" || normalized === "short") {
|
|
3732
|
-
return "pro";
|
|
3733
|
-
}
|
|
3734
|
-
return fallback;
|
|
3735
|
-
}
|
|
3736
|
-
function resolveToolDisplayMode(env = process.env) {
|
|
3737
|
-
const legacyTrace = asTrimmedLowercaseString(env.NOLO_TRACE_TOOLS);
|
|
3738
|
-
if (legacyTrace === "0" || legacyTrace === "false" || legacyTrace === "off") {
|
|
3739
|
-
return "hide";
|
|
3740
|
-
}
|
|
3741
|
-
if (legacyTrace === "verbose" || legacyTrace === "full") {
|
|
3742
|
-
return "verbose";
|
|
3743
|
-
}
|
|
3744
|
-
return normalizeToolDisplayMode(env.NOLO_CLI_TOOLS ?? env.NOLO_TOOLS, "normal");
|
|
3745
|
-
}
|
|
3746
|
-
function shouldEmitToolEvents(mode) {
|
|
3747
|
-
return mode !== "hide";
|
|
3748
|
-
}
|
|
3749
3431
|
function clip(value, max = 72) {
|
|
3750
3432
|
return clipCompactText(value, max, "\u2026");
|
|
3751
3433
|
}
|
|
3752
|
-
function formatActiveToolLabel(event) {
|
|
3753
|
-
const toolName = event.toolName || "tool";
|
|
3754
|
-
const args = clipPathAware(event.argumentsPreview ?? "");
|
|
3755
|
-
const label = toolLabel(toolName);
|
|
3756
|
-
return args ? `${label} ${args}` : label;
|
|
3757
|
-
}
|
|
3758
3434
|
function formatConservativeActiveToolLabel(event) {
|
|
3759
3435
|
return toolLabel(event.toolName || "tool");
|
|
3760
3436
|
}
|
|
3761
|
-
function
|
|
3762
|
-
|
|
3763
|
-
if (gate) {
|
|
3764
|
-
const commandPayload = gate.kind === "handoff" ? readCommandActionGatePayload(gate.payload) : null;
|
|
3765
|
-
const command = commandPayload?.displayCommand ?? commandPayload?.command.join(" ") ?? "";
|
|
3766
|
-
const detail = command.trim() ? command : gate.title;
|
|
3767
|
-
return { inline: `${t("toolNeedsAction")}: ${clip(detail, 120)}` };
|
|
3768
|
-
}
|
|
3769
|
-
if (event.metadata?.timedOut) return { inline: t("toolTimedOut") };
|
|
3770
|
-
if (event.toolName === "readFile" && event.metadata) {
|
|
3771
|
-
const range = readReadFileRange(event.metadata);
|
|
3772
|
-
if (range) return { inline: range };
|
|
3773
|
-
}
|
|
3774
|
-
if (event.toolName === "editFile" && event.metadata) {
|
|
3775
|
-
const res = formatEditFileSnippet(event.metadata);
|
|
3776
|
-
if (res) {
|
|
3777
|
-
const stats = [];
|
|
3778
|
-
if (res.addedCount > 0) stats.push(`+${res.addedCount}`);
|
|
3779
|
-
if (res.removedCount > 0) stats.push(`-${res.removedCount}`);
|
|
3780
|
-
const inline = stats.length > 0 ? `(${stats.join(", ")})` : "";
|
|
3781
|
-
return { inline, detail: res.lines };
|
|
3782
|
-
}
|
|
3783
|
-
}
|
|
3784
|
-
if (event.toolName === "writeFile" && event.metadata) {
|
|
3785
|
-
const totalLines = event.metadata.totalLines ?? event.metadata.lines;
|
|
3786
|
-
if (typeof totalLines === "number" && totalLines > 0) {
|
|
3787
|
-
return { inline: `(+${totalLines})` };
|
|
3788
|
-
}
|
|
3789
|
-
}
|
|
3790
|
-
const summary = event.summary;
|
|
3791
|
-
if (!summary) return { inline: "" };
|
|
3792
|
-
const exitMatch = summary.match(/exit=(\d+)/);
|
|
3793
|
-
if (exitMatch && exitMatch[1] !== "0") return { inline: `${t("toolExitCode")} ${exitMatch[1]}` };
|
|
3794
|
-
return { inline: "" };
|
|
3795
|
-
}
|
|
3796
|
-
function readReadFileRange(metadata) {
|
|
3797
|
-
const startLine = metadata.startLine;
|
|
3798
|
-
const endLine = metadata.endLine;
|
|
3799
|
-
const totalLines = metadata.totalLines;
|
|
3800
|
-
const truncated = metadata.truncated;
|
|
3801
|
-
if (typeof startLine !== "number" || typeof endLine !== "number" || typeof totalLines !== "number") {
|
|
3802
|
-
return void 0;
|
|
3803
|
-
}
|
|
3804
|
-
if (!truncated && startLine === 1 && endLine === totalLines) return void 0;
|
|
3805
|
-
return `${startLine}-${endLine}/${totalLines}`;
|
|
3806
|
-
}
|
|
3807
|
-
var EDIT_SNIPPET_MAX_LINES = 24;
|
|
3808
|
-
var DEFAULT_EDIT_SNIPPET_MAX_WIDTH = 96;
|
|
3809
|
-
function resolveEditSnippetMaxWidth(env = process.env, columns) {
|
|
3810
|
-
if (env.NOLO_TEST_DIFF_WIDTH) {
|
|
3811
|
-
const parsed = parseInt(env.NOLO_TEST_DIFF_WIDTH, 10);
|
|
3812
|
-
if (!Number.isNaN(parsed) && parsed > 0) return parsed;
|
|
3813
|
-
}
|
|
3814
|
-
const cols = typeof columns === "number" ? columns : typeof process !== "undefined" && typeof process.stdout?.columns === "number" ? process.stdout.columns : 0;
|
|
3815
|
-
if (cols > 0) {
|
|
3816
|
-
return Math.max(80, Math.min(160, cols - 8));
|
|
3817
|
-
}
|
|
3818
|
-
return DEFAULT_EDIT_SNIPPET_MAX_WIDTH;
|
|
3819
|
-
}
|
|
3820
|
-
function formatEditFileSnippet(metadata) {
|
|
3821
|
-
const oldSnippet = typeof metadata.oldSnippet === "string" ? metadata.oldSnippet : void 0;
|
|
3822
|
-
const newSnippet = typeof metadata.newSnippet === "string" ? metadata.newSnippet : void 0;
|
|
3823
|
-
if (!oldSnippet && !newSnippet) return void 0;
|
|
3824
|
-
const maxWidth = resolveEditSnippetMaxWidth();
|
|
3825
|
-
if (oldSnippet && !newSnippet) {
|
|
3826
|
-
const lines = snippetLinesWithKind(oldSnippet, "removed", maxWidth);
|
|
3827
|
-
return { lines, addedCount: 0, removedCount: lines.length };
|
|
3828
|
-
}
|
|
3829
|
-
if (newSnippet && !oldSnippet) {
|
|
3830
|
-
const lines = snippetLinesWithKind(newSnippet, "added", maxWidth);
|
|
3831
|
-
return { lines, addedCount: lines.length, removedCount: 0 };
|
|
3832
|
-
}
|
|
3833
|
-
const parts = diffLines(oldSnippet, newSnippet);
|
|
3834
|
-
const all = [];
|
|
3835
|
-
let addedCount = 0;
|
|
3836
|
-
let removedCount = 0;
|
|
3837
|
-
for (const part of parts) {
|
|
3838
|
-
const kind = part.added ? "added" : part.removed ? "removed" : "context";
|
|
3839
|
-
const raw = part.value.split("\n");
|
|
3840
|
-
if (raw.length > 0 && raw[raw.length - 1] === "") raw.pop();
|
|
3841
|
-
for (const line of raw) {
|
|
3842
|
-
if (kind === "added") addedCount++;
|
|
3843
|
-
if (kind === "removed") removedCount++;
|
|
3844
|
-
all.push(buildEditLine(kind, line, maxWidth));
|
|
3845
|
-
}
|
|
3846
|
-
}
|
|
3847
|
-
const changeCount = all.filter((l) => l.kind !== "context").length;
|
|
3848
|
-
if (changeCount === 0) return void 0;
|
|
3849
|
-
return {
|
|
3850
|
-
lines: windowAndTruncate(all, EDIT_SNIPPET_MAX_LINES),
|
|
3851
|
-
addedCount,
|
|
3852
|
-
removedCount
|
|
3853
|
-
};
|
|
3854
|
-
}
|
|
3855
|
-
function prefixFor(kind) {
|
|
3856
|
-
return kind === "added" ? "+ " : kind === "removed" ? "- " : " ";
|
|
3857
|
-
}
|
|
3858
|
-
function buildEditLine(kind, body, maxWidth = resolveEditSnippetMaxWidth()) {
|
|
3859
|
-
return { kind, text: prefixFor(kind) + truncateByDisplayWidth(body, maxWidth) };
|
|
3860
|
-
}
|
|
3861
|
-
function snippetLinesWithKind(snippet, kind, maxWidth = resolveEditSnippetMaxWidth()) {
|
|
3862
|
-
const lines = snippet.split(/\r?\n/).filter((line) => line.length > 0);
|
|
3863
|
-
return lines.slice(0, EDIT_SNIPPET_MAX_LINES).map((line) => buildEditLine(kind, line, maxWidth));
|
|
3437
|
+
function isRunToolName(name) {
|
|
3438
|
+
return name === "execShell" || name === "runCommand" || name === "launchProcess";
|
|
3864
3439
|
}
|
|
3865
|
-
function
|
|
3866
|
-
|
|
3867
|
-
let width = 0;
|
|
3868
|
-
let kept = "";
|
|
3869
|
-
for (const char of line) {
|
|
3870
|
-
const w = displayWidth(char);
|
|
3871
|
-
if (width + w + 1 > maxWidth) break;
|
|
3872
|
-
kept += char;
|
|
3873
|
-
width += w;
|
|
3874
|
-
}
|
|
3875
|
-
return `${kept}\u2026`;
|
|
3876
|
-
}
|
|
3877
|
-
function windowAndTruncate(lines, maxLines) {
|
|
3878
|
-
if (lines.length <= maxLines) return lines;
|
|
3879
|
-
const firstChange = lines.findIndex((l) => l.kind !== "context");
|
|
3880
|
-
if (firstChange === -1) return lines.slice(0, maxLines);
|
|
3881
|
-
const half = Math.floor(maxLines / 2);
|
|
3882
|
-
let start = Math.max(0, firstChange - half);
|
|
3883
|
-
if (start + maxLines > lines.length) start = Math.max(0, lines.length - maxLines);
|
|
3884
|
-
const kept = lines.slice(start, start + maxLines);
|
|
3885
|
-
const omitted = lines.length - kept.length;
|
|
3886
|
-
if (omitted > 0) {
|
|
3887
|
-
kept.push({ kind: "context", text: ` \u2026 +${omitted} more lines` });
|
|
3888
|
-
}
|
|
3889
|
-
return kept;
|
|
3440
|
+
function isReadToolName(name) {
|
|
3441
|
+
return name === "readFile";
|
|
3890
3442
|
}
|
|
3891
3443
|
function isFailedToolResult(event) {
|
|
3892
3444
|
const exitCode = event.metadata?.exitCode;
|
|
@@ -3894,9 +3446,6 @@ function isFailedToolResult(event) {
|
|
|
3894
3446
|
if (typeof exitCode === "number" && exitCode !== 0) return true;
|
|
3895
3447
|
return Boolean(event.metadata?.timedOut);
|
|
3896
3448
|
}
|
|
3897
|
-
function isNeedsActionToolResult(event) {
|
|
3898
|
-
return Boolean(event.metadata?.actionGate);
|
|
3899
|
-
}
|
|
3900
3449
|
function parseUiAskChoiceForCli(event) {
|
|
3901
3450
|
if (event.toolName !== "ask_user" && !event.metadata?.uiAskChoice) {
|
|
3902
3451
|
return null;
|
|
@@ -3999,36 +3548,45 @@ function formatToolTraceLine(text, colorEnabled, accent = "none") {
|
|
|
3999
3548
|
return `${dimCliText(text, true)}
|
|
4000
3549
|
`;
|
|
4001
3550
|
}
|
|
3551
|
+
var cleanUserText = (value) => stripAnsi2(value).replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
|
|
4002
3552
|
function renderRunCard(snapshot, opts) {
|
|
4003
3553
|
const labels = agentRunCardLabels();
|
|
4004
3554
|
const timing = { startedAt: snapshot.startedAt, finishedAt: snapshot.finishedAt };
|
|
4005
|
-
const
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
3555
|
+
const safe = opts?.safe === true;
|
|
3556
|
+
const name = safe ? cleanUserText(snapshot.agentName ?? "agent") : snapshot.agentName ?? "agent";
|
|
3557
|
+
const source = safe ? {
|
|
3558
|
+
...snapshot,
|
|
3559
|
+
agentName: snapshot.agentName ? cleanUserText(snapshot.agentName) : snapshot.agentName,
|
|
3560
|
+
taskPreview: snapshot.taskPreview ? cleanUserText(snapshot.taskPreview) : snapshot.taskPreview,
|
|
3561
|
+
lastAssistantText: snapshot.lastAssistantText ? cleanUserText(snapshot.lastAssistantText) : snapshot.lastAssistantText,
|
|
3562
|
+
lastToolNames: snapshot.lastToolNames?.map(cleanUserText)
|
|
3563
|
+
} : snapshot;
|
|
3564
|
+
const hadError = safe && Boolean(source.errorMessage?.trim());
|
|
3565
|
+
const errorFields = safe ? { errorMessage: void 0, logLines: void 0 } : { errorMessage: source.errorMessage, logLines: source.logLines };
|
|
3566
|
+
const body = isAgentRunTerminalStatus(snapshot.status) ? formatFinishedRunCard(name, snapshot.status, {
|
|
3567
|
+
runId: snapshot.runId,
|
|
3568
|
+
toolCallCount: source.toolCallCount,
|
|
3569
|
+
lastToolNames: source.lastToolNames,
|
|
3570
|
+
lastAssistantText: source.lastAssistantText,
|
|
3571
|
+
...errorFields,
|
|
3572
|
+
timing,
|
|
3573
|
+
...opts?.includeLogTail !== void 0 ? { includeLogTail: opts.includeLogTail } : {},
|
|
3574
|
+
labels
|
|
3575
|
+
}) : formatStatusRunCard(name, snapshot.status, {
|
|
4020
3576
|
runId: snapshot.runId,
|
|
4021
|
-
toolCallCount:
|
|
4022
|
-
lastToolNames:
|
|
4023
|
-
lastAssistantText:
|
|
4024
|
-
|
|
4025
|
-
logLines: snapshot.logLines,
|
|
3577
|
+
toolCallCount: source.toolCallCount,
|
|
3578
|
+
lastToolNames: source.lastToolNames,
|
|
3579
|
+
lastAssistantText: source.lastAssistantText,
|
|
3580
|
+
...errorFields,
|
|
4026
3581
|
timing,
|
|
4027
3582
|
...opts?.includeLogTail !== void 0 ? { includeLogTail: opts.includeLogTail } : {},
|
|
4028
3583
|
labels
|
|
4029
3584
|
});
|
|
3585
|
+
return hadError ? `${body}
|
|
3586
|
+
error ${t("runDiagnosticsHidden")}` : body;
|
|
4030
3587
|
}
|
|
4031
|
-
function recoverOrchestrationCard(event, toolName) {
|
|
3588
|
+
function recoverOrchestrationCard(event, toolName, opts) {
|
|
3589
|
+
const safe = opts?.safe === true;
|
|
4032
3590
|
const content = typeof event.content === "string" ? event.content : "";
|
|
4033
3591
|
const trimmed = content.trim();
|
|
4034
3592
|
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return null;
|
|
@@ -4059,27 +3617,26 @@ function recoverOrchestrationCard(event, toolName) {
|
|
|
4059
3617
|
if (!parsedEvent) return null;
|
|
4060
3618
|
const { kind, snapshot } = parsedEvent;
|
|
4061
3619
|
if (kind === "start") {
|
|
4062
|
-
|
|
4063
|
-
|
|
3620
|
+
const name = safe ? cleanUserText(snapshot.agentName ?? "agent") : snapshot.agentName ?? "agent";
|
|
3621
|
+
const task = snapshot.taskPreview ? safe ? cleanUserText(snapshot.taskPreview) : snapshot.taskPreview : snapshot.taskPreview;
|
|
3622
|
+
return formatStartRunCard(name, snapshot.status, {
|
|
3623
|
+
task,
|
|
4064
3624
|
runId: snapshot.runId,
|
|
4065
3625
|
labels
|
|
4066
3626
|
});
|
|
4067
3627
|
}
|
|
4068
3628
|
if (kind === "gone") return formatNotFoundRunCard(labels);
|
|
4069
3629
|
if (kind === "stop") return formatStopRunCard(snapshot.status, labels);
|
|
4070
|
-
return renderRunCard(snapshot);
|
|
3630
|
+
return renderRunCard(snapshot, opts);
|
|
4071
3631
|
}
|
|
4072
|
-
function
|
|
4073
|
-
const
|
|
4074
|
-
return parsed?.kind === "status" ? parsed.snapshot : null;
|
|
4075
|
-
}
|
|
4076
|
-
function formatOrchestrationCardBlock(event, toolName, colorEnabled) {
|
|
3632
|
+
function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
|
|
3633
|
+
const safe = opts?.safe === true;
|
|
4077
3634
|
const rawLabel = toolLabel(toolName);
|
|
4078
3635
|
const bakedCard = typeof event.metadata?.displayData === "string" && event.metadata.displayData.trim() ? event.metadata.displayData : "";
|
|
4079
|
-
const rawDataStr = recoverOrchestrationCard(event, toolName) || bakedCard || (typeof event.content === "string" ? event.content : "");
|
|
3636
|
+
const rawDataStr = recoverOrchestrationCard(event, toolName, { safe }) || bakedCard || (typeof event.content === "string" ? event.content : "");
|
|
4080
3637
|
const failed = event.type === "tool-error" || isFailedToolResult(event) || Boolean(event.metadata?.failed) || /^Error:/i.test(rawDataStr.trim());
|
|
4081
3638
|
if (failed) {
|
|
4082
|
-
const firstLine = rawDataStr.trim().split("\n")[0] || event.summary || event.message || t("toolFailed");
|
|
3639
|
+
const firstLine = safe ? t("toolFailed") : rawDataStr.trim().split("\n")[0] || event.summary || event.message || t("toolFailed");
|
|
4083
3640
|
const message = clip(firstLine, 96);
|
|
4084
3641
|
if (!colorEnabled) {
|
|
4085
3642
|
return `\u2717 ${rawLabel} ${message}
|
|
@@ -4092,11 +3649,12 @@ function formatOrchestrationCardBlock(event, toolName, colorEnabled) {
|
|
|
4092
3649
|
`;
|
|
4093
3650
|
}
|
|
4094
3651
|
const displayData = rawDataStr.trim();
|
|
4095
|
-
const lines = displayData ? displayData.split("\n")
|
|
3652
|
+
const lines = displayData ? displayData.split("\n") : [];
|
|
3653
|
+
const projected = safe ? sanitizeRunCardForNormal(lines) : lines;
|
|
4096
3654
|
if (!colorEnabled) {
|
|
4097
3655
|
let out2 = `\u25CF ${rawLabel}
|
|
4098
3656
|
`;
|
|
4099
|
-
for (const line of
|
|
3657
|
+
for (const line of projected) {
|
|
4100
3658
|
out2 += ` ${line}
|
|
4101
3659
|
`;
|
|
4102
3660
|
}
|
|
@@ -4106,65 +3664,66 @@ function formatOrchestrationCardBlock(event, toolName, colorEnabled) {
|
|
|
4106
3664
|
const labelPart = themeText(rawLabel, "muted", true);
|
|
4107
3665
|
let out = `${bullet} ${labelPart}
|
|
4108
3666
|
`;
|
|
4109
|
-
for (const line of
|
|
3667
|
+
for (const line of projected) {
|
|
4110
3668
|
out += ` ${themeText(line, "muted", true)}
|
|
4111
3669
|
`;
|
|
4112
3670
|
}
|
|
4113
3671
|
return out;
|
|
4114
3672
|
}
|
|
4115
|
-
function
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
"controlAgentRun",
|
|
4141
|
-
colorEnabled
|
|
4142
|
-
);
|
|
4143
|
-
}
|
|
4144
|
-
function formatVerboseToolEvent(event, colorEnabled) {
|
|
4145
|
-
const round = event.round + 1;
|
|
4146
|
-
const detail = event.argumentsPreview ? ` ${event.argumentsPreview}` : "";
|
|
4147
|
-
if (event.type === "tool-call") {
|
|
4148
|
-
return formatToolTraceLine(`[nolo:tool] #${round} -> ${event.toolName}${detail}`, colorEnabled);
|
|
4149
|
-
}
|
|
4150
|
-
if (event.type === "tool-error") {
|
|
4151
|
-
const elapsed2 = typeof event.elapsedMs === "number" ? ` ${event.elapsedMs}ms` : "";
|
|
4152
|
-
return formatToolTraceLine(
|
|
4153
|
-
`[nolo:tool] #${round} !! ${event.toolName}${elapsed2}: ${event.message ?? "failed"}`,
|
|
4154
|
-
colorEnabled,
|
|
4155
|
-
"error"
|
|
4156
|
-
);
|
|
4157
|
-
}
|
|
4158
|
-
const elapsed = typeof event.elapsedMs === "number" ? ` ${event.elapsedMs}ms` : "";
|
|
4159
|
-
if (event.type === "tool-result" && (event.toolName === "ask_user" || event.metadata?.uiAskChoice)) {
|
|
4160
|
-
const block = formatUiAskChoiceBlock(event, colorEnabled);
|
|
4161
|
-
if (block) return `${formatToolTraceLine(`[nolo:tool] #${round} <- ${event.toolName}${elapsed}`, colorEnabled)}${block}`;
|
|
3673
|
+
function sanitizeRunCardForNormal(lines) {
|
|
3674
|
+
const out = [];
|
|
3675
|
+
let errorIndent = null;
|
|
3676
|
+
for (const line of lines) {
|
|
3677
|
+
if (/^(log tail:?|日志尾部:?)$/i.test(line.trim())) {
|
|
3678
|
+
if (out.length > 0 && out[out.length - 1].trim() === "") out.pop();
|
|
3679
|
+
break;
|
|
3680
|
+
}
|
|
3681
|
+
if (/^\s*error\b/i.test(line)) {
|
|
3682
|
+
out.push(` error ${t("runDiagnosticsHidden")}`);
|
|
3683
|
+
errorIndent = line.length - line.trimStart().length;
|
|
3684
|
+
continue;
|
|
3685
|
+
}
|
|
3686
|
+
if (errorIndent !== null) {
|
|
3687
|
+
if (line.trim() === "") {
|
|
3688
|
+
errorIndent = null;
|
|
3689
|
+
out.push(line);
|
|
3690
|
+
continue;
|
|
3691
|
+
}
|
|
3692
|
+
const indent = line.length - line.trimStart().length;
|
|
3693
|
+
const isLabelRow = /^\s{2}[a-z][a-zA-Z0-9]*\s{2,}/.test(line);
|
|
3694
|
+
if (indent > errorIndent && !isLabelRow) continue;
|
|
3695
|
+
errorIndent = null;
|
|
3696
|
+
}
|
|
3697
|
+
out.push(line);
|
|
4162
3698
|
}
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
);
|
|
3699
|
+
return out;
|
|
3700
|
+
}
|
|
3701
|
+
var NORMAL_TOOL_GIST_MAX = 28;
|
|
3702
|
+
function gistClip(value, max = NORMAL_TOOL_GIST_MAX) {
|
|
3703
|
+
const oneLine = value.replace(/\s+/g, " ").trim();
|
|
3704
|
+
if (!oneLine) return "";
|
|
3705
|
+
return oneLine.length <= max ? oneLine : `${oneLine.slice(0, max - 1)}\u2026`;
|
|
3706
|
+
}
|
|
3707
|
+
function commandHeadGist(command) {
|
|
3708
|
+
const trimmed = command.replace(/\s+/g, " ").trim();
|
|
3709
|
+
if (!trimmed || /[|;&<>`$]/.test(trimmed)) return "";
|
|
3710
|
+
const tokens = trimmed.split(" ");
|
|
3711
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(tokens[0])) return "";
|
|
3712
|
+
if (["cd", "pushd", "popd", "source", "."].includes(tokens[0])) return "";
|
|
3713
|
+
return gistClip(tokens.slice(0, 2).join(" "), 24);
|
|
3714
|
+
}
|
|
3715
|
+
function pathBasenameGist(path) {
|
|
3716
|
+
const segments = path.split(/[\\/]/).filter((segment) => segment.length > 0);
|
|
3717
|
+
const base = segments.pop();
|
|
3718
|
+
return base ? gistClip(base) : "";
|
|
3719
|
+
}
|
|
3720
|
+
function normalToolGist(event) {
|
|
3721
|
+
const metadata = event.metadata ?? {};
|
|
3722
|
+
const path = typeof metadata.path === "string" ? metadata.path : "";
|
|
3723
|
+
if (path) return pathBasenameGist(path);
|
|
3724
|
+
const command = typeof metadata.command === "string" ? metadata.command : "";
|
|
3725
|
+
if (command) return commandHeadGist(command);
|
|
3726
|
+
return "";
|
|
4168
3727
|
}
|
|
4169
3728
|
function formatNormalToolLine(event, pending, colorEnabled) {
|
|
4170
3729
|
if (event.type === "tool-call") return "";
|
|
@@ -4176,10 +3735,10 @@ function formatNormalToolLine(event, pending, colorEnabled) {
|
|
|
4176
3735
|
if (block) return block;
|
|
4177
3736
|
}
|
|
4178
3737
|
if (event.type === "tool-result" && (toolName === "listAgents" || toolName === "startAgentRun" || toolName === "controlAgentRun")) {
|
|
4179
|
-
return formatOrchestrationCardBlock(event, toolName, colorEnabled);
|
|
3738
|
+
return formatOrchestrationCardBlock(event, toolName, colorEnabled, { safe: true });
|
|
4180
3739
|
}
|
|
4181
3740
|
if (event.type === "tool-result" && toolName === "loadSkill") {
|
|
4182
|
-
return formatLoadSkillBlock(event, colorEnabled) ?? "";
|
|
3741
|
+
return formatLoadSkillBlock(event, colorEnabled, { safe: true }) ?? "";
|
|
4183
3742
|
}
|
|
4184
3743
|
const label = toolLabel(toolName);
|
|
4185
3744
|
if (readActionGate(event.metadata?.actionGate)) {
|
|
@@ -4194,150 +3753,8 @@ function formatNormalToolLine(event, pending, colorEnabled) {
|
|
|
4194
3753
|
if (isFailedToolResult(event)) {
|
|
4195
3754
|
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${t("toolFailed")}`, colorEnabled, "error");
|
|
4196
3755
|
}
|
|
4197
|
-
|
|
4198
|
-
}
|
|
4199
|
-
function isReadToolName(name) {
|
|
4200
|
-
if (!name) return false;
|
|
4201
|
-
return name === "read" || name === "readFile" || name === "read_file" || name === "readWorkspaceFile";
|
|
4202
|
-
}
|
|
4203
|
-
function isSearchToolName(name) {
|
|
4204
|
-
if (!name) return false;
|
|
4205
|
-
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";
|
|
4206
|
-
}
|
|
4207
|
-
function isRunToolName(name) {
|
|
4208
|
-
if (!name) return false;
|
|
4209
|
-
return name === "execShell" || name === "runCommand" || name === "run_command" || name === "launchProcess";
|
|
4210
|
-
}
|
|
4211
|
-
function isFetchToolName(name) {
|
|
4212
|
-
if (!name) return false;
|
|
4213
|
-
return name === "fetchWebpage" || name === "fetch_webpage";
|
|
4214
|
-
}
|
|
4215
|
-
function isWebSearchToolName(name) {
|
|
4216
|
-
if (!name) return false;
|
|
4217
|
-
return name === "exa_search" || name === "exaSearch";
|
|
4218
|
-
}
|
|
4219
|
-
function isRunResultFoldable(event) {
|
|
4220
|
-
return Boolean(event.metadata?.actionGate) === false;
|
|
4221
|
-
}
|
|
4222
|
-
function formatSearchTreeBlockForCli(items, colorEnabled) {
|
|
4223
|
-
if (items.length === 0) return "";
|
|
4224
|
-
const { count, lines } = formatSearchTreeLines(items);
|
|
4225
|
-
const titleText = toolLabel("codeSearch");
|
|
4226
|
-
if (!colorEnabled) {
|
|
4227
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4228
|
-
`;
|
|
4229
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.queryText}`).join("\n");
|
|
4230
|
-
return `${headerLine2}${treeLines2}
|
|
4231
|
-
`;
|
|
4232
|
-
}
|
|
4233
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4234
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4235
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4236
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4237
|
-
`;
|
|
4238
|
-
const treeLines = lines.map((l) => {
|
|
4239
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4240
|
-
const queryText = themeText(l.queryText, "muted", true);
|
|
4241
|
-
return `${connector}${queryText}`;
|
|
4242
|
-
}).join("\n");
|
|
4243
|
-
return `${headerLine}${treeLines}
|
|
4244
|
-
`;
|
|
4245
|
-
}
|
|
4246
|
-
function formatReadTreeBlockForCli(items, colorEnabled) {
|
|
4247
|
-
if (items.length === 0) return "";
|
|
4248
|
-
const { count, lines } = formatReadTreeLines(items);
|
|
4249
|
-
const titleText = toolLabel("readFile");
|
|
4250
|
-
if (!colorEnabled) {
|
|
4251
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4252
|
-
`;
|
|
4253
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.pathWithRange}`).join("\n");
|
|
4254
|
-
return `${headerLine2}${treeLines2}
|
|
4255
|
-
`;
|
|
4256
|
-
}
|
|
4257
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4258
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4259
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4260
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4261
|
-
`;
|
|
4262
|
-
const treeLines = lines.map((l) => {
|
|
4263
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4264
|
-
const pathText = themeText(l.pathWithRange, "muted", true);
|
|
4265
|
-
return `${connector}${pathText}`;
|
|
4266
|
-
}).join("\n");
|
|
4267
|
-
return `${headerLine}${treeLines}
|
|
4268
|
-
`;
|
|
4269
|
-
}
|
|
4270
|
-
function formatRunTreeBlockForCli(items, colorEnabled) {
|
|
4271
|
-
if (items.length === 0) return "";
|
|
4272
|
-
const { count, lines } = formatRunTreeLines(items);
|
|
4273
|
-
const titleText = toolLabel("execShell");
|
|
4274
|
-
if (!colorEnabled) {
|
|
4275
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4276
|
-
`;
|
|
4277
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.commandText}`).join("\n");
|
|
4278
|
-
return `${headerLine2}${treeLines2}
|
|
4279
|
-
`;
|
|
4280
|
-
}
|
|
4281
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4282
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4283
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4284
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4285
|
-
`;
|
|
4286
|
-
const treeLines = lines.map((l) => {
|
|
4287
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4288
|
-
const commandText = themeText(l.commandText, "muted", true);
|
|
4289
|
-
return `${connector}${commandText}`;
|
|
4290
|
-
}).join("\n");
|
|
4291
|
-
return `${headerLine}${treeLines}
|
|
4292
|
-
`;
|
|
4293
|
-
}
|
|
4294
|
-
function formatWebSearchTreeBlockForCli(items, colorEnabled) {
|
|
4295
|
-
if (items.length === 0) return "";
|
|
4296
|
-
const { count, lines } = formatSearchTreeLines(items);
|
|
4297
|
-
const titleText = toolLabel("exa_search");
|
|
4298
|
-
if (!colorEnabled) {
|
|
4299
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4300
|
-
`;
|
|
4301
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.queryText}`).join("\n");
|
|
4302
|
-
return `${headerLine2}${treeLines2}
|
|
4303
|
-
`;
|
|
4304
|
-
}
|
|
4305
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4306
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4307
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4308
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4309
|
-
`;
|
|
4310
|
-
const treeLines = lines.map((l) => {
|
|
4311
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4312
|
-
const queryText = themeText(l.queryText, "muted", true);
|
|
4313
|
-
return `${connector}${queryText}`;
|
|
4314
|
-
}).join("\n");
|
|
4315
|
-
return `${headerLine}${treeLines}
|
|
4316
|
-
`;
|
|
4317
|
-
}
|
|
4318
|
-
function formatFetchTreeBlockForCli(items, colorEnabled) {
|
|
4319
|
-
if (items.length === 0) return "";
|
|
4320
|
-
const { count, lines } = formatFetchTreeLines(items);
|
|
4321
|
-
const titleText = toolLabel("fetchWebpage");
|
|
4322
|
-
if (!colorEnabled) {
|
|
4323
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4324
|
-
`;
|
|
4325
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.urlText}`).join("\n");
|
|
4326
|
-
return `${headerLine2}${treeLines2}
|
|
4327
|
-
`;
|
|
4328
|
-
}
|
|
4329
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4330
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4331
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4332
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4333
|
-
`;
|
|
4334
|
-
const treeLines = lines.map((l) => {
|
|
4335
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4336
|
-
const urlText = themeText(l.urlText, "muted", true);
|
|
4337
|
-
return `${connector}${urlText}`;
|
|
4338
|
-
}).join("\n");
|
|
4339
|
-
return `${headerLine}${treeLines}
|
|
4340
|
-
`;
|
|
3756
|
+
const gist = normalToolGist(event);
|
|
3757
|
+
return formatToolTraceLine(gist ? `\u25B8 ${label} \xB7 ${gist} \u2713` : `\u25B8 ${label} \u2713`, colorEnabled);
|
|
4341
3758
|
}
|
|
4342
3759
|
function resolveLoadSkillName(event) {
|
|
4343
3760
|
const metaName = typeof event.metadata?.name === "string" ? event.metadata.name : void 0;
|
|
@@ -4382,14 +3799,14 @@ function formatTodoListForCli(event, colorEnabled) {
|
|
|
4382
3799
|
const text = [`\u2611 Todo (${todos.length})`, ...lines].join("\n") + "\n";
|
|
4383
3800
|
return colorEnabled ? themeText(text, "chrome") : text;
|
|
4384
3801
|
}
|
|
4385
|
-
function formatLoadSkillBlock(event, colorEnabled) {
|
|
3802
|
+
function formatLoadSkillBlock(event, colorEnabled, opts) {
|
|
4386
3803
|
if (event.type !== "tool-result" || event.toolName !== "loadSkill") return null;
|
|
4387
3804
|
const skillName = resolveLoadSkillName(event);
|
|
4388
3805
|
const content = typeof event.content === "string" ? event.content : "";
|
|
4389
3806
|
const failed = /^Skill\s+"[^"]*"\s+not found/.test(content) || isFailedToolResult(event);
|
|
4390
3807
|
const labelText = t("usedSkillLabel");
|
|
4391
3808
|
if (failed) {
|
|
4392
|
-
const message = clip(content.split("\n")[0] || t("toolFailed"), 96);
|
|
3809
|
+
const message = opts?.safe === true ? t("toolFailed") : clip(content.split("\n")[0] || t("toolFailed"), 96);
|
|
4393
3810
|
return formatToolTraceLine(`\u25B8 ${labelText} (${skillName}) \u2717 ${message}`, colorEnabled, "error");
|
|
4394
3811
|
}
|
|
4395
3812
|
if (!colorEnabled) {
|
|
@@ -4402,326 +3819,63 @@ function formatLoadSkillBlock(event, colorEnabled) {
|
|
|
4402
3819
|
return `${star} ${labelPart}: ${namePart}
|
|
4403
3820
|
`;
|
|
4404
3821
|
}
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
if (todoBlock) return todoBlock;
|
|
4409
|
-
if (isReadToolName(toolName) && event.type === "tool-result") {
|
|
4410
|
-
const rawPath = (typeof event.metadata?.path === "string" ? event.metadata.path : void 0) || (typeof event.metadata?.filePath === "string" ? event.metadata.filePath : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4411
|
-
return formatReadTreeBlockForCli([{ path: rawPath, metadata: event.metadata }], colorEnabled);
|
|
4412
|
-
}
|
|
4413
|
-
if (isSearchToolName(toolName) && event.type === "tool-result") {
|
|
4414
|
-
const rawQuery = (typeof event.metadata?.query === "string" ? event.metadata.query : void 0) || (typeof event.metadata?.pattern === "string" ? event.metadata.pattern : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4415
|
-
const rawPath = typeof event.metadata?.path === "string" ? event.metadata.path : void 0;
|
|
4416
|
-
return formatSearchTreeBlockForCli([{ query: rawQuery, path: rawPath }], colorEnabled);
|
|
4417
|
-
}
|
|
4418
|
-
if (isFetchToolName(toolName) && event.type === "tool-result") {
|
|
4419
|
-
const rawUrl = (typeof event.metadata?.url === "string" ? event.metadata.url : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4420
|
-
return formatFetchTreeBlockForCli([{ url: rawUrl }], colorEnabled);
|
|
4421
|
-
}
|
|
4422
|
-
if (isRunToolName(toolName) && event.type === "tool-result" && isRunResultFoldable(event)) {
|
|
4423
|
-
const rawCommand = (typeof event.metadata?.command === "string" ? event.metadata.command : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4424
|
-
const exitCode = typeof event.metadata?.exitCode === "number" ? event.metadata.exitCode : void 0;
|
|
4425
|
-
const timedOut = Boolean(event.metadata?.timedOut);
|
|
4426
|
-
return formatRunTreeBlockForCli([{ command: rawCommand, exitCode, timedOut }], colorEnabled);
|
|
4427
|
-
}
|
|
4428
|
-
const rawArgs = clipPathAware(event.argumentsPreview || pending?.argumentsPreview || "", 72);
|
|
4429
|
-
const rawLabel = toolLabel(toolName);
|
|
4430
|
-
const label = rawArgs ? `${rawLabel} ${rawArgs}` : rawLabel;
|
|
4431
|
-
if (event.type === "tool-error") {
|
|
4432
|
-
const message = clip(event.message ?? t("toolFailed"), 96);
|
|
4433
|
-
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${message}`, colorEnabled, "error");
|
|
4434
|
-
}
|
|
4435
|
-
const loadSkillBlock = formatLoadSkillBlock(event, colorEnabled);
|
|
4436
|
-
if (loadSkillBlock) return loadSkillBlock;
|
|
4437
|
-
if (event.type === "tool-result" && (toolName === "listAgents" || toolName === "startAgentRun" || toolName === "controlAgentRun")) {
|
|
4438
|
-
return formatOrchestrationCardBlock(event, toolName, colorEnabled);
|
|
4439
|
-
}
|
|
4440
|
-
if (event.type === "tool-result" && (event.toolName === "ask_user" || event.metadata?.uiAskChoice)) {
|
|
4441
|
-
const block = formatUiAskChoiceBlock(event, colorEnabled);
|
|
4442
|
-
if (block) return block;
|
|
4443
|
-
}
|
|
4444
|
-
const hint = compactResultHint(event);
|
|
4445
|
-
const suffix = hint.inline ? ` ${hint.inline}` : "";
|
|
4446
|
-
const failed = isFailedToolResult(event);
|
|
4447
|
-
const marker = failed ? "\u2717" : isNeedsActionToolResult(event) ? "!" : "\u2713";
|
|
4448
|
-
let mainLine;
|
|
4449
|
-
if (!colorEnabled) {
|
|
4450
|
-
mainLine = `\u25B8 ${label} ${marker}${suffix}
|
|
4451
|
-
`;
|
|
4452
|
-
} else {
|
|
4453
|
-
const chromePointer = themeText("\u25B8", "chrome", true);
|
|
4454
|
-
const mutedLabel = themeText(rawLabel, "muted", true);
|
|
4455
|
-
const argsPart = rawArgs ? ` ${dimCliText(rawArgs, true)}` : "";
|
|
4456
|
-
const statusToken = failed ? themeText("\u2717", "danger", true) : isNeedsActionToolResult(event) ? themeText("!", "warning", true) : themeText("\u2713", "success", true);
|
|
4457
|
-
const suffixPart = hint.inline ? ` ${dimCliText(hint.inline, true)}` : "";
|
|
4458
|
-
mainLine = `${chromePointer} ${mutedLabel}${argsPart} ${statusToken}${suffixPart}
|
|
4459
|
-
`;
|
|
4460
|
-
}
|
|
4461
|
-
if (!hint.detail?.length) return mainLine;
|
|
4462
|
-
const filePath = typeof event.metadata?.path === "string" ? event.metadata.path : event.argumentsPreview;
|
|
4463
|
-
return `${mainLine}${formatEditDetailBlock(hint.detail, colorEnabled, filePath)}`;
|
|
4464
|
-
}
|
|
4465
|
-
function formatEditDetailBlock(lines, colorEnabled, filePath, env = process.env) {
|
|
4466
|
-
if (!colorEnabled) {
|
|
4467
|
-
return lines.map((line) => ` ${line.text}
|
|
4468
|
-
`).join("");
|
|
4469
|
-
}
|
|
4470
|
-
const isTruecolor = supportsTruecolor(env);
|
|
4471
|
-
const lang = isTruecolor ? detectCodeLangFromPath(filePath) : "unknown";
|
|
4472
|
-
const brightness = resolveTuiBrightness(env);
|
|
4473
|
-
const padTo = Math.max(...lines.map((line) => displayWidth(line.text))) + 1;
|
|
4474
|
-
return lines.map((line) => ` ${renderDiffLine({
|
|
4475
|
-
kind: line.kind,
|
|
4476
|
-
text: line.text,
|
|
4477
|
-
highlightedText: shouldHighlightEditLine(line, lang, isTruecolor) ? buildHighlightedEditLine(line, lang, brightness, env) : void 0,
|
|
4478
|
-
padTo,
|
|
4479
|
-
colorEnabled: true,
|
|
4480
|
-
env
|
|
4481
|
-
})}
|
|
4482
|
-
`).join("");
|
|
4483
|
-
}
|
|
4484
|
-
function shouldHighlightEditLine(line, lang, isTruecolor) {
|
|
4485
|
-
if (!isTruecolor || lang === "unknown") return false;
|
|
4486
|
-
if (line.text.startsWith(" \u2026") || line.text.startsWith("\u2026")) return false;
|
|
4487
|
-
return line.text.length >= 2;
|
|
4488
|
-
}
|
|
4489
|
-
function buildHighlightedEditLine(line, lang, brightness, env) {
|
|
4490
|
-
const prefix = line.text.slice(0, 2);
|
|
4491
|
-
const body = line.text.slice(2);
|
|
4492
|
-
const prefixToken = line.kind === "added" ? "success" : line.kind === "removed" ? "danger" : "chrome";
|
|
4493
|
-
const coloredPrefix = themeText(prefix, prefixToken, true, env);
|
|
4494
|
-
const highlightedBody = highlightCodeLine(body, lang, brightness);
|
|
4495
|
-
return `${coloredPrefix}${highlightedBody}`;
|
|
4496
|
-
}
|
|
4497
|
-
function createToolEventFormatter(mode, colorEnabled = resolveCliColorEnabled(), opts = {}) {
|
|
4498
|
-
const suppressRunProgressCards = opts.suppressRunProgressCards === true;
|
|
3822
|
+
var TUI_TREE_MARKER = "TUI_TREE\n";
|
|
3823
|
+
var TUI_TREE_END = "";
|
|
3824
|
+
function createToolEventFormatter(colorEnabled = resolveCliColorEnabled(), opts = {}) {
|
|
4499
3825
|
const pending = /* @__PURE__ */ new Map();
|
|
4500
|
-
let
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
const lastPrintedCardByRunId = /* @__PURE__ */ new Map();
|
|
4508
|
-
const cardSubstance = (snapshot) => JSON.stringify([
|
|
4509
|
-
snapshot.status,
|
|
4510
|
-
snapshot.toolCallCount ?? -1,
|
|
4511
|
-
snapshot.lastToolNames ?? [],
|
|
4512
|
-
snapshot.lastAssistantText ?? "",
|
|
4513
|
-
snapshot.errorMessage ?? "",
|
|
4514
|
-
snapshot.logKey
|
|
4515
|
-
]);
|
|
4516
|
-
const flushStatusFold = () => {
|
|
4517
|
-
if (!statusFold) return "";
|
|
4518
|
-
const fold = statusFold;
|
|
4519
|
-
statusFold = null;
|
|
4520
|
-
const substance = cardSubstance(fold);
|
|
4521
|
-
if (lastPrintedCardByRunId.get(fold.runId) === substance) return "";
|
|
4522
|
-
const prevLog = lastEmittedLogByRunId.get(fold.runId);
|
|
4523
|
-
const changed = Boolean(fold.logKey) && fold.logKey !== prevLog;
|
|
4524
|
-
if (suppressRunProgressCards) {
|
|
4525
|
-
const terminal = isAgentRunTerminalStatus(fold.status);
|
|
4526
|
-
if (!terminal && !fold.errorMessage && !changed) {
|
|
4527
|
-
lastPrintedCardByRunId.set(fold.runId, substance);
|
|
4528
|
-
return "";
|
|
4529
|
-
}
|
|
4530
|
-
}
|
|
4531
|
-
lastPrintedCardByRunId.set(fold.runId, substance);
|
|
4532
|
-
if (changed && runShowsLogTail(fold.status)) {
|
|
4533
|
-
lastEmittedLogByRunId.set(fold.runId, fold.logKey);
|
|
4534
|
-
}
|
|
4535
|
-
return formatFoldedControlStatusCard({ ...fold, includeLogTail: changed }, colorEnabled);
|
|
4536
|
-
};
|
|
4537
|
-
const flushToolBuffers = () => {
|
|
4538
|
-
let out = "";
|
|
4539
|
-
if (readBuffer.length > 0) {
|
|
4540
|
-
const items = readBuffer.map((evt) => {
|
|
4541
|
-
const call = pending.get(evt.toolCallId);
|
|
4542
|
-
const rawPath = (typeof evt.metadata?.path === "string" ? evt.metadata.path : void 0) || (typeof evt.metadata?.filePath === "string" ? evt.metadata.filePath : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4543
|
-
return { path: rawPath, metadata: evt.metadata };
|
|
4544
|
-
});
|
|
4545
|
-
for (const evt of readBuffer) pending.delete(evt.toolCallId);
|
|
4546
|
-
readBuffer = [];
|
|
4547
|
-
out += formatReadTreeBlockForCli(items, colorEnabled);
|
|
4548
|
-
}
|
|
4549
|
-
if (searchBuffer.length > 0) {
|
|
4550
|
-
const items = searchBuffer.map((evt) => {
|
|
4551
|
-
const call = pending.get(evt.toolCallId);
|
|
4552
|
-
const rawQuery = (typeof evt.metadata?.query === "string" ? evt.metadata.query : void 0) || (typeof evt.metadata?.pattern === "string" ? evt.metadata.pattern : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4553
|
-
const rawPath = typeof evt.metadata?.path === "string" ? evt.metadata.path : void 0;
|
|
4554
|
-
return { query: rawQuery, path: rawPath };
|
|
4555
|
-
});
|
|
4556
|
-
for (const evt of searchBuffer) pending.delete(evt.toolCallId);
|
|
4557
|
-
searchBuffer = [];
|
|
4558
|
-
out += formatSearchTreeBlockForCli(items, colorEnabled);
|
|
4559
|
-
}
|
|
4560
|
-
if (runBuffer.length > 0) {
|
|
4561
|
-
const items = runBuffer.map((evt) => {
|
|
4562
|
-
const call = pending.get(evt.toolCallId);
|
|
4563
|
-
const rawCommand = (typeof evt.metadata?.command === "string" ? evt.metadata.command : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4564
|
-
const exitCode = typeof evt.metadata?.exitCode === "number" ? evt.metadata.exitCode : void 0;
|
|
4565
|
-
const timedOut = Boolean(evt.metadata?.timedOut);
|
|
4566
|
-
return { command: rawCommand, exitCode, timedOut };
|
|
4567
|
-
});
|
|
4568
|
-
for (const evt of runBuffer) pending.delete(evt.toolCallId);
|
|
4569
|
-
runBuffer = [];
|
|
4570
|
-
out += formatRunTreeBlockForCli(items, colorEnabled);
|
|
4571
|
-
}
|
|
4572
|
-
if (fetchBuffer.length > 0) {
|
|
4573
|
-
const items = fetchBuffer.map((evt) => {
|
|
4574
|
-
const call = pending.get(evt.toolCallId);
|
|
4575
|
-
const rawUrl = (typeof evt.metadata?.url === "string" ? evt.metadata.url : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4576
|
-
return { url: rawUrl };
|
|
4577
|
-
});
|
|
4578
|
-
for (const evt of fetchBuffer) pending.delete(evt.toolCallId);
|
|
4579
|
-
fetchBuffer = [];
|
|
4580
|
-
out += formatFetchTreeBlockForCli(items, colorEnabled);
|
|
4581
|
-
}
|
|
4582
|
-
if (webSearchBuffer.length > 0) {
|
|
4583
|
-
const items = webSearchBuffer.map((evt) => {
|
|
4584
|
-
const call = pending.get(evt.toolCallId);
|
|
4585
|
-
const rawQuery = (typeof evt.metadata?.query === "string" ? evt.metadata.query : void 0) || (typeof evt.metadata?.pattern === "string" ? evt.metadata.pattern : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4586
|
-
return { query: rawQuery };
|
|
4587
|
-
});
|
|
4588
|
-
for (const evt of webSearchBuffer) pending.delete(evt.toolCallId);
|
|
4589
|
-
webSearchBuffer = [];
|
|
4590
|
-
out += formatWebSearchTreeBlockForCli(items, colorEnabled);
|
|
4591
|
-
}
|
|
4592
|
-
return out;
|
|
4593
|
-
};
|
|
4594
|
-
const flushBuffers = () => `${flushStatusFold()}${flushToolBuffers()}`;
|
|
4595
|
-
const bufferToolResult = (buffer, event) => {
|
|
4596
|
-
const flushed = flushStatusFold();
|
|
4597
|
-
buffer.push(event);
|
|
4598
|
-
return flushed;
|
|
3826
|
+
let tree = null;
|
|
3827
|
+
const treeKind = (name) => isRunToolName(name) ? "Run" : isReadToolName(name) ? "Read" : name === "exa_search" ? "Search" : name === "fetchWebpage" ? "Fetch" : null;
|
|
3828
|
+
const treeLine = (kind, items) => {
|
|
3829
|
+
const label = kind === "Run" ? toolLabel("execShell") : kind === "Read" ? toolLabel("readFile") : kind === "Fetch" ? toolLabel("fetchWebpage") : toolLabel("exa_search");
|
|
3830
|
+
return `${TUI_TREE_MARKER}${label} (${items.length})
|
|
3831
|
+
${items.map((item, i) => `${i === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 "}${item} \u2713`).join("\n")}${TUI_TREE_END}
|
|
3832
|
+
`;
|
|
4599
3833
|
};
|
|
4600
|
-
const
|
|
4601
|
-
if (
|
|
4602
|
-
if (
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
pending.set(event.toolCallId, {
|
|
4606
|
-
toolName: event.toolName,
|
|
4607
|
-
argumentsPreview: event.argumentsPreview
|
|
4608
|
-
});
|
|
4609
|
-
return "";
|
|
4610
|
-
}
|
|
4611
|
-
const call2 = pending.get(event.toolCallId);
|
|
4612
|
-
pending.delete(event.toolCallId);
|
|
4613
|
-
return formatNormalToolLine(event, call2, colorEnabled);
|
|
4614
|
-
}
|
|
4615
|
-
if (event.toolName === "controlAgentRun") {
|
|
4616
|
-
if (event.type === "tool-call") {
|
|
4617
|
-
pending.set(event.toolCallId, {
|
|
4618
|
-
toolName: event.toolName,
|
|
4619
|
-
argumentsPreview: event.argumentsPreview
|
|
4620
|
-
});
|
|
4621
|
-
return "";
|
|
4622
|
-
}
|
|
4623
|
-
if (event.type === "tool-result") {
|
|
4624
|
-
const snapshot = parseControlAgentRunStatusEvent(event);
|
|
4625
|
-
if (snapshot) {
|
|
4626
|
-
let out = flushToolBuffers();
|
|
4627
|
-
const open = statusFold;
|
|
4628
|
-
const sameRun = open?.runId === snapshot.runId;
|
|
4629
|
-
if (open && (!sameRun || open.status !== snapshot.status)) {
|
|
4630
|
-
out += flushStatusFold();
|
|
4631
|
-
}
|
|
4632
|
-
statusFold = open && sameRun ? mergeRunSnapshot(open, snapshot) : snapshot;
|
|
4633
|
-
pending.delete(event.toolCallId);
|
|
4634
|
-
if (isAgentRunTerminalStatus(snapshot.status)) {
|
|
4635
|
-
out += flushBuffers();
|
|
4636
|
-
}
|
|
4637
|
-
return out;
|
|
4638
|
-
}
|
|
4639
|
-
const flushed2 = flushBuffers();
|
|
4640
|
-
const call2 = pending.get(event.toolCallId);
|
|
4641
|
-
pending.delete(event.toolCallId);
|
|
4642
|
-
return `${flushed2}${formatCompactToolLine(event, call2, colorEnabled)}`;
|
|
4643
|
-
}
|
|
4644
|
-
}
|
|
4645
|
-
if (isReadToolName(event.toolName)) {
|
|
4646
|
-
if (event.type === "tool-call") {
|
|
4647
|
-
pending.set(event.toolCallId, {
|
|
4648
|
-
toolName: event.toolName,
|
|
4649
|
-
argumentsPreview: event.argumentsPreview
|
|
4650
|
-
});
|
|
4651
|
-
return "";
|
|
4652
|
-
}
|
|
4653
|
-
if (event.type === "tool-result") {
|
|
4654
|
-
return bufferToolResult(readBuffer, event);
|
|
4655
|
-
}
|
|
4656
|
-
}
|
|
4657
|
-
if (isSearchToolName(event.toolName)) {
|
|
4658
|
-
if (event.type === "tool-call") {
|
|
4659
|
-
pending.set(event.toolCallId, {
|
|
4660
|
-
toolName: event.toolName,
|
|
4661
|
-
argumentsPreview: event.argumentsPreview
|
|
4662
|
-
});
|
|
4663
|
-
return "";
|
|
4664
|
-
}
|
|
4665
|
-
if (event.type === "tool-result") {
|
|
4666
|
-
return bufferToolResult(searchBuffer, event);
|
|
4667
|
-
}
|
|
4668
|
-
}
|
|
4669
|
-
if (isRunToolName(event.toolName)) {
|
|
4670
|
-
if (event.type === "tool-result" && !isRunResultFoldable(event)) {
|
|
4671
|
-
const flushed2 = flushBuffers();
|
|
4672
|
-
const call2 = pending.get(event.toolCallId);
|
|
4673
|
-
pending.delete(event.toolCallId);
|
|
4674
|
-
return `${flushed2}${formatCompactToolLine(event, call2, colorEnabled)}`;
|
|
4675
|
-
}
|
|
4676
|
-
if (event.type === "tool-call") {
|
|
4677
|
-
pending.set(event.toolCallId, {
|
|
4678
|
-
toolName: event.toolName,
|
|
4679
|
-
argumentsPreview: event.argumentsPreview
|
|
4680
|
-
});
|
|
4681
|
-
return "";
|
|
4682
|
-
}
|
|
4683
|
-
if (event.type === "tool-result") {
|
|
4684
|
-
return bufferToolResult(runBuffer, event);
|
|
4685
|
-
}
|
|
4686
|
-
}
|
|
4687
|
-
if (isFetchToolName(event.toolName)) {
|
|
4688
|
-
if (event.type === "tool-call") {
|
|
4689
|
-
pending.set(event.toolCallId, {
|
|
4690
|
-
toolName: event.toolName,
|
|
4691
|
-
argumentsPreview: event.argumentsPreview
|
|
4692
|
-
});
|
|
4693
|
-
return "";
|
|
4694
|
-
}
|
|
4695
|
-
if (event.type === "tool-result") {
|
|
4696
|
-
return bufferToolResult(fetchBuffer, event);
|
|
4697
|
-
}
|
|
3834
|
+
const formatTreeEvent = (event, call) => {
|
|
3835
|
+
if (!opts.tuiTrees || event.type !== "tool-result") return null;
|
|
3836
|
+
if (isFailedToolResult(event) || event.metadata?.failed || event.metadata?.timedOut || readActionGate(event.metadata?.actionGate)) {
|
|
3837
|
+
tree = null;
|
|
3838
|
+
return null;
|
|
4698
3839
|
}
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
});
|
|
4705
|
-
return "";
|
|
4706
|
-
}
|
|
4707
|
-
if (event.type === "tool-result") {
|
|
4708
|
-
return bufferToolResult(webSearchBuffer, event);
|
|
4709
|
-
}
|
|
3840
|
+
const name = event.toolName || call?.toolName || "tool";
|
|
3841
|
+
const kind = treeKind(name);
|
|
3842
|
+
if (!kind) {
|
|
3843
|
+
tree = null;
|
|
3844
|
+
return null;
|
|
4710
3845
|
}
|
|
4711
|
-
|
|
3846
|
+
let item = "";
|
|
3847
|
+
const m = event.metadata ?? {};
|
|
3848
|
+
if (kind === "Run") {
|
|
3849
|
+
const command = typeof m.command === "string" ? m.command : "";
|
|
3850
|
+
item = command ? formatRunItemCommand(command, typeof m.exitCode === "number" ? m.exitCode : void 0, Boolean(m.timedOut)) : "command";
|
|
3851
|
+
}
|
|
3852
|
+
if (kind === "Read") item = formatReadItemPath(typeof m.path === "string" ? m.path : typeof m.filePath === "string" ? m.filePath : "file", m);
|
|
3853
|
+
if (kind === "Search") item = formatSearchItemQuery(typeof m.query === "string" ? m.query : typeof m.pattern === "string" ? m.pattern : "search", typeof m.path === "string" ? m.path : void 0);
|
|
3854
|
+
if (kind === "Fetch") item = formatFetchItemUrl(typeof m.url === "string" ? m.url : "webpage");
|
|
3855
|
+
if (!item) item = toolLabel(name);
|
|
3856
|
+
if (tree?.kind !== kind) tree = { kind, items: [] };
|
|
3857
|
+
tree.items.push(item);
|
|
3858
|
+
if (tree.items.length < 2) return formatNormalToolLine(event, call, colorEnabled);
|
|
3859
|
+
return treeLine(kind, tree.items);
|
|
3860
|
+
};
|
|
3861
|
+
const format = (event) => {
|
|
4712
3862
|
if (event.type === "tool-call") {
|
|
4713
3863
|
pending.set(event.toolCallId, {
|
|
4714
3864
|
toolName: event.toolName,
|
|
4715
3865
|
argumentsPreview: event.argumentsPreview
|
|
4716
3866
|
});
|
|
4717
|
-
return
|
|
3867
|
+
return "";
|
|
4718
3868
|
}
|
|
4719
3869
|
const call = pending.get(event.toolCallId);
|
|
4720
3870
|
pending.delete(event.toolCallId);
|
|
4721
|
-
|
|
3871
|
+
const treeOutput = formatTreeEvent(event, call);
|
|
3872
|
+
if (treeOutput !== null) return treeOutput;
|
|
3873
|
+
return formatNormalToolLine(event, call, colorEnabled);
|
|
3874
|
+
};
|
|
3875
|
+
format.reset = () => {
|
|
3876
|
+
tree = null;
|
|
4722
3877
|
};
|
|
4723
|
-
|
|
4724
|
-
return formatter;
|
|
3878
|
+
return format;
|
|
4725
3879
|
}
|
|
4726
3880
|
function createSseToolEventAdapter(onEvent) {
|
|
4727
3881
|
let round = 0;
|
|
@@ -4882,7 +4036,7 @@ ${this.text}
|
|
|
4882
4036
|
0,
|
|
4883
4037
|
Math.floor((Date.now() - this.startTime) / 1e3)
|
|
4884
4038
|
);
|
|
4885
|
-
const thinkingPart = this.thinkingHint ? `: ${truncateThinkingHint(this.thinkingHint, 60)}` : "";
|
|
4039
|
+
const thinkingPart = this.thinkingHint ? dimCliText(`: ${truncateThinkingHint(this.thinkingHint, 60)}`) : "";
|
|
4886
4040
|
return `${themeColorSequence("accent")}${frame}\x1B[39m ${this.text}${thinkingPart} (${formatElapsed(elapsedSeconds)})`;
|
|
4887
4041
|
}
|
|
4888
4042
|
};
|
|
@@ -4939,10 +4093,8 @@ function createCliTurnOutput(params) {
|
|
|
4939
4093
|
const { options } = params;
|
|
4940
4094
|
const workingLabel = params.workingLabel ?? `${options.agentName} -> working`;
|
|
4941
4095
|
const spinner = params.spinner ?? new Spinner(options.output, workingLabel, Boolean(options.activityReporter));
|
|
4942
|
-
const
|
|
4943
|
-
|
|
4944
|
-
const formatToolEvent = createToolEventFormatter(toolDisplayMode, void 0, {
|
|
4945
|
-
suppressRunProgressCards: typeof options.onAgentRunStatus === "function"
|
|
4096
|
+
const formatToolEvent = createToolEventFormatter(void 0, {
|
|
4097
|
+
tuiTrees: options.output.tuiTrees === true
|
|
4946
4098
|
});
|
|
4947
4099
|
const eventMode = resolveAgentEventMode(options);
|
|
4948
4100
|
const showThinking = options.showThinking !== false;
|
|
@@ -4950,12 +4102,27 @@ function createCliTurnOutput(params) {
|
|
|
4950
4102
|
let everStreamedAnyText = false;
|
|
4951
4103
|
let printedAssistantLabel = false;
|
|
4952
4104
|
let thinkState = createThinkParserState();
|
|
4105
|
+
let thinkingFirstAt = null;
|
|
4106
|
+
let thinkingLastAt = 0;
|
|
4107
|
+
const markThinkingActivity = () => {
|
|
4108
|
+
const now = Date.now();
|
|
4109
|
+
if (thinkingFirstAt === null) thinkingFirstAt = now;
|
|
4110
|
+
thinkingLastAt = now;
|
|
4111
|
+
};
|
|
4112
|
+
const writeThinkingTrace = () => {
|
|
4113
|
+
if (thinkingFirstAt === null) return;
|
|
4114
|
+
const seconds = Math.max(0, Math.round((thinkingLastAt - thinkingFirstAt) / 1e3));
|
|
4115
|
+
thinkingFirstAt = null;
|
|
4116
|
+
if (seconds < 1) return;
|
|
4117
|
+
options.output.write(`${dimCliText(t("thinkingTraceLine", formatElapsed(seconds)))}
|
|
4118
|
+
`);
|
|
4119
|
+
};
|
|
4953
4120
|
let compactionEvent = null;
|
|
4954
4121
|
const assistantLabelManaged = options.output.assistantLabelManaged === true;
|
|
4955
4122
|
const writeToolOutput = (chunk) => {
|
|
4956
4123
|
if (!chunk) return;
|
|
4957
4124
|
if (typeof options.output.writeToolBlock === "function") {
|
|
4958
|
-
options.output.writeToolBlock(chunk);
|
|
4125
|
+
if (!options.output.writeToolBlock(chunk)) formatToolEvent.reset?.();
|
|
4959
4126
|
} else {
|
|
4960
4127
|
options.output.write(chunk);
|
|
4961
4128
|
}
|
|
@@ -4965,13 +4132,16 @@ function createCliTurnOutput(params) {
|
|
|
4965
4132
|
});
|
|
4966
4133
|
const writeVisibleAssistantChunk = (chunk) => {
|
|
4967
4134
|
if (!chunk) return;
|
|
4135
|
+
formatToolEvent.reset?.();
|
|
4968
4136
|
const parsed = processThinkChunk(chunk, thinkState);
|
|
4969
4137
|
thinkState = parsed.state;
|
|
4970
4138
|
if (!parsed.content && !parsed.reasoning) return;
|
|
4971
4139
|
if (showThinking && parsed.reasoning) {
|
|
4140
|
+
markThinkingActivity();
|
|
4972
4141
|
spinner.setThinkingHint(parsed.reasoning);
|
|
4973
4142
|
}
|
|
4974
4143
|
if (!parsed.content) return;
|
|
4144
|
+
writeThinkingTrace();
|
|
4975
4145
|
spinner.stop();
|
|
4976
4146
|
options.activityReporter?.(null);
|
|
4977
4147
|
if (!printedAssistantLabel) {
|
|
@@ -4986,7 +4156,6 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
4986
4156
|
renderWriter.push(parsed.content);
|
|
4987
4157
|
};
|
|
4988
4158
|
const handleToolEvent = (event) => {
|
|
4989
|
-
if (!traceLocalTools) return;
|
|
4990
4159
|
const chunk = eventMode === "jsonl" ? formatToolJsonEvent(event) : formatToolEvent(event);
|
|
4991
4160
|
if (eventMode === "jsonl") {
|
|
4992
4161
|
options.output.write(chunk);
|
|
@@ -5004,8 +4173,8 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5004
4173
|
if (chunk) {
|
|
5005
4174
|
writeToolOutput(chunk);
|
|
5006
4175
|
}
|
|
5007
|
-
if (
|
|
5008
|
-
const activeLabel =
|
|
4176
|
+
if (event.type === "tool-call") {
|
|
4177
|
+
const activeLabel = formatConservativeActiveToolLabel(event);
|
|
5009
4178
|
spinner.show(activeLabel);
|
|
5010
4179
|
options.activityReporter?.(activeLabel);
|
|
5011
4180
|
}
|
|
@@ -5018,20 +4187,15 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5018
4187
|
};
|
|
5019
4188
|
return {
|
|
5020
4189
|
spinner,
|
|
5021
|
-
toolDisplayMode,
|
|
5022
|
-
traceLocalTools,
|
|
5023
4190
|
eventMode,
|
|
5024
4191
|
pushText(chunk) {
|
|
5025
|
-
if (eventMode !== "jsonl" && formatToolEvent.flush) {
|
|
5026
|
-
const pendingToolOutput = formatToolEvent.flush();
|
|
5027
|
-
if (pendingToolOutput) {
|
|
5028
|
-
writeToolOutput(pendingToolOutput);
|
|
5029
|
-
}
|
|
5030
|
-
}
|
|
5031
4192
|
writeVisibleAssistantChunk(chunk);
|
|
5032
4193
|
},
|
|
5033
4194
|
pushThinking(chunk) {
|
|
5034
|
-
if (showThinking)
|
|
4195
|
+
if (showThinking) {
|
|
4196
|
+
markThinkingActivity();
|
|
4197
|
+
spinner.setThinkingHint(chunk);
|
|
4198
|
+
}
|
|
5035
4199
|
},
|
|
5036
4200
|
handleToolEvent,
|
|
5037
4201
|
/** 记录一条 compaction 观测事件(TUI 在 turn 结束时渲染一行 dim 摘要)。 */
|
|
@@ -5046,15 +4210,12 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5046
4210
|
finish(fallbackContent) {
|
|
5047
4211
|
spinner.stop();
|
|
5048
4212
|
options.activityReporter?.(null);
|
|
4213
|
+
writeThinkingTrace();
|
|
5049
4214
|
const flushedThink = flushThinkParser(thinkState);
|
|
5050
4215
|
thinkState = flushedThink.state;
|
|
5051
4216
|
if (flushedThink.content) {
|
|
5052
4217
|
writeVisibleAssistantChunk(flushedThink.content);
|
|
5053
4218
|
}
|
|
5054
|
-
const pendingToolOutput = formatToolEvent.flush ? formatToolEvent.flush() : "";
|
|
5055
|
-
if (pendingToolOutput) {
|
|
5056
|
-
writeToolOutput(pendingToolOutput);
|
|
5057
|
-
}
|
|
5058
4219
|
if (streamedAssistantText) {
|
|
5059
4220
|
renderWriter.flush();
|
|
5060
4221
|
options.output.write("\n");
|
|
@@ -5266,6 +4427,10 @@ ${describeClientVersionTooOldFailure(message, error)}`);
|
|
|
5266
4427
|
function resolveAuthToken2(env) {
|
|
5267
4428
|
return resolvePlatformAuthToken(env);
|
|
5268
4429
|
}
|
|
4430
|
+
function resolveFileWriteGateEnabled(env) {
|
|
4431
|
+
const raw = (env.NOLO_CLI_WRITE_GATE ?? "").trim().toLowerCase();
|
|
4432
|
+
return raw !== "off" && raw !== "0" && raw !== "false";
|
|
4433
|
+
}
|
|
5269
4434
|
function isMachineBoundLocalhostCustomProvider(agentConfig) {
|
|
5270
4435
|
const machineId = agentConfig?.runtimeBinding && typeof agentConfig.runtimeBinding === "object" ? String(agentConfig.runtimeBinding.machineId ?? "").trim() : "";
|
|
5271
4436
|
const providerUrl = asTrimmedString(agentConfig?.customProviderUrl);
|
|
@@ -5357,7 +4522,16 @@ function isKnownServerPlatformAgent(options) {
|
|
|
5357
4522
|
// packages/core/collapsedPaste.ts
|
|
5358
4523
|
var COLLAPSE_PASTE_MIN_LINES = 8;
|
|
5359
4524
|
var COLLAPSE_PASTE_MIN_CHARS = 400;
|
|
5360
|
-
var COLLAPSED_PASTE_PLACEHOLDER_RE =
|
|
4525
|
+
var COLLAPSED_PASTE_PLACEHOLDER_RE = (
|
|
4526
|
+
// 兼容两种格式:旧 `[paste #N · L lines]` 与新 `[paste #N · L lines · preview]`。
|
|
4527
|
+
// preview 段用负向先行断言排除模型引用(`…; full content available via
|
|
4528
|
+
// readPastedText(pasteId=N)`):legacy 无 scope 的模型引用与新 chip 形状重叠,
|
|
4529
|
+
// 若被当作 chip 匹配,跨会话残留的引用会被错误展开/替换(破坏 durable
|
|
4530
|
+
// fallback 语义)。preview 与模型引用尾段在生成时都不会包含该标记原文之外
|
|
4531
|
+
// 的歧义,此处按"完整模型引用尾段"精确排除。
|
|
4532
|
+
/\[paste #(\d+) · (\d+) lines(?: · (?![^\]]*; full content available via readPastedText\(pasteId=\d+\))([^\]]*))?\]/g
|
|
4533
|
+
);
|
|
4534
|
+
var COLLAPSED_PASTE_PREVIEW_MAX_CHARS = 24;
|
|
5361
4535
|
var COLLAPSED_PASTE_MODEL_REFERENCE_RE = /\[paste #(\d+)(?: scope:([a-zA-Z0-9_-]+))? · [^\]]+; full content available via readPastedText\(pasteId=(\d+)\)\]/g;
|
|
5362
4536
|
function countTextLines(text) {
|
|
5363
4537
|
if (text.length === 0) return 0;
|
|
@@ -5397,9 +4571,22 @@ function estimatePasteBytes(text) {
|
|
|
5397
4571
|
}
|
|
5398
4572
|
return bytes;
|
|
5399
4573
|
}
|
|
4574
|
+
function buildCollapsedPastePreview(text) {
|
|
4575
|
+
const firstNonEmptyLine = text.split(/\r\n|\r|\n/).find((line) => line.trim().length > 0) ?? "";
|
|
4576
|
+
let preview = compactWhitespace(firstNonEmptyLine);
|
|
4577
|
+
preview = preview.replace(new RegExp("\\]|\\p{C}", "gu"), "").trim();
|
|
4578
|
+
if (preview.length === 0) return "";
|
|
4579
|
+
const chars = Array.from(preview);
|
|
4580
|
+
if (chars.length > COLLAPSED_PASTE_PREVIEW_MAX_CHARS) {
|
|
4581
|
+
return chars.slice(0, COLLAPSED_PASTE_PREVIEW_MAX_CHARS).join("") + "\u2026";
|
|
4582
|
+
}
|
|
4583
|
+
return preview;
|
|
4584
|
+
}
|
|
5400
4585
|
function formatCollapsedPastePlaceholder(id, text) {
|
|
5401
4586
|
const lines = countTextLines(text);
|
|
5402
|
-
|
|
4587
|
+
const preview = buildCollapsedPastePreview(text);
|
|
4588
|
+
if (!preview) return `[paste #${id} \xB7 ${lines} lines]`;
|
|
4589
|
+
return `[paste #${id} \xB7 ${lines} lines \xB7 ${preview}]`;
|
|
5403
4590
|
}
|
|
5404
4591
|
function generatePasteScope() {
|
|
5405
4592
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
@@ -5512,9 +4699,65 @@ function findCollapsedPasteSpanAt(buffer, pos, opts = {}) {
|
|
|
5512
4699
|
// packages/cli/client/agentRun.ts
|
|
5513
4700
|
import { ulid } from "ulid";
|
|
5514
4701
|
async function loadRunLocalAgentTurn() {
|
|
5515
|
-
const { runLocalAgentTurn } = await import("./agentRuntimeLocal-
|
|
4702
|
+
const { runLocalAgentTurn } = await import("./agentRuntimeLocal-SBG7BDFQ.js");
|
|
5516
4703
|
return runLocalAgentTurn;
|
|
5517
4704
|
}
|
|
4705
|
+
var stripDebugNoise = (s) => s.replace(/\s*raw="[\s\S]*"/g, "").replace(/\s*raw=\S+/g, "").replace(/\s*headers=\[[^\]]*\]/g, "").replace(/\s*headers=\S+/g, "").trim();
|
|
4706
|
+
function extractEmbeddedErrorMessage(message) {
|
|
4707
|
+
const match = /"message"\s*:\s*"((?:[^"\\]|\\.)*)"/.exec(message);
|
|
4708
|
+
if (!match) return void 0;
|
|
4709
|
+
try {
|
|
4710
|
+
const decoded = JSON.parse(`"${match[1]}"`);
|
|
4711
|
+
if (typeof decoded !== "string" || !decoded.trim()) return void 0;
|
|
4712
|
+
const cleaned = decoded.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
4713
|
+
return cleaned.trim() ? cleaned : void 0;
|
|
4714
|
+
} catch {
|
|
4715
|
+
return void 0;
|
|
4716
|
+
}
|
|
4717
|
+
}
|
|
4718
|
+
function parseEmbeddedBalanceDetails(message) {
|
|
4719
|
+
const jsonStart = message.indexOf('{"error"');
|
|
4720
|
+
if (jsonStart < 0) return void 0;
|
|
4721
|
+
try {
|
|
4722
|
+
let depth = 0;
|
|
4723
|
+
let inString = false;
|
|
4724
|
+
let escaped = false;
|
|
4725
|
+
let jsonEnd = -1;
|
|
4726
|
+
for (let i = jsonStart; i < message.length; i += 1) {
|
|
4727
|
+
const char = message[i];
|
|
4728
|
+
if (inString) {
|
|
4729
|
+
if (escaped) escaped = false;
|
|
4730
|
+
else if (char === "\\") escaped = true;
|
|
4731
|
+
else if (char === '"') inString = false;
|
|
4732
|
+
} else if (char === '"') {
|
|
4733
|
+
inString = true;
|
|
4734
|
+
} else if (char === "{") {
|
|
4735
|
+
depth += 1;
|
|
4736
|
+
} else if (char === "}" && --depth === 0) {
|
|
4737
|
+
jsonEnd = i + 1;
|
|
4738
|
+
break;
|
|
4739
|
+
}
|
|
4740
|
+
}
|
|
4741
|
+
if (jsonEnd < 0) return void 0;
|
|
4742
|
+
const parsed = JSON.parse(message.slice(jsonStart, jsonEnd));
|
|
4743
|
+
if (!parsed || typeof parsed !== "object") return void 0;
|
|
4744
|
+
const error = parsed.error;
|
|
4745
|
+
if (!error || typeof error !== "object") return void 0;
|
|
4746
|
+
const details = error.details;
|
|
4747
|
+
if (!details || typeof details !== "object") return void 0;
|
|
4748
|
+
const requiredBalance = details.requiredBalance;
|
|
4749
|
+
const currentBalance = details.currentBalance;
|
|
4750
|
+
if (typeof requiredBalance !== "number" || typeof currentBalance !== "number") {
|
|
4751
|
+
return void 0;
|
|
4752
|
+
}
|
|
4753
|
+
if (!Number.isFinite(requiredBalance) || !Number.isFinite(currentBalance) || requiredBalance <= 0) {
|
|
4754
|
+
return void 0;
|
|
4755
|
+
}
|
|
4756
|
+
return { required: String(requiredBalance), current: String(currentBalance) };
|
|
4757
|
+
} catch {
|
|
4758
|
+
return void 0;
|
|
4759
|
+
}
|
|
4760
|
+
}
|
|
5518
4761
|
async function resolveCurrentMachineId(options) {
|
|
5519
4762
|
return options.currentMachineIdResolver ? options.currentMachineIdResolver(options.env) : detectCurrentMachineId(options.env);
|
|
5520
4763
|
}
|
|
@@ -5745,7 +4988,6 @@ function describeLocalRunFailure(message, rawError) {
|
|
|
5745
4988
|
busyDetail = rawError.detail.trim();
|
|
5746
4989
|
}
|
|
5747
4990
|
if (/PLATFORM_LLM_BUSY|服务器紧张/.test(message)) {
|
|
5748
|
-
const stripDebugNoise = (s) => s.replace(/\s*raw=".*"/g, "").replace(/\s*raw=\S+/g, "").replace(/\s*headers=\[[^\]]*\]/g, "").replace(/\s*headers=\S+/g, "").trim();
|
|
5749
4991
|
const shown = stripDebugNoise(
|
|
5750
4992
|
message.replace(/\s*\(PLATFORM_LLM_BUSY\)\s*$/, "")
|
|
5751
4993
|
);
|
|
@@ -5756,7 +4998,18 @@ function describeLocalRunFailure(message, rawError) {
|
|
|
5756
4998
|
if (/UPSTREAM_402|Insufficient Balance|余额不足|insufficient\s+balance/i.test(
|
|
5757
4999
|
message
|
|
5758
5000
|
)) {
|
|
5759
|
-
|
|
5001
|
+
const cleanedMessage = stripDebugNoise(message);
|
|
5002
|
+
const fallback = cleanedMessage.replace(
|
|
5003
|
+
/^[^:]*provider failed: HTTP \d{3}\s*/,
|
|
5004
|
+
""
|
|
5005
|
+
);
|
|
5006
|
+
const balanceDetails = parseEmbeddedBalanceDetails(cleanedMessage);
|
|
5007
|
+
const shownMessage = balanceDetails ? t(
|
|
5008
|
+
"balanceInsufficientReason",
|
|
5009
|
+
balanceDetails.required,
|
|
5010
|
+
balanceDetails.current
|
|
5011
|
+
) : extractEmbeddedErrorMessage(cleanedMessage) ?? fallback;
|
|
5012
|
+
return `[nolo] ${shownMessage}
|
|
5760
5013
|
`;
|
|
5761
5014
|
}
|
|
5762
5015
|
const cls = classifyLocalRunError(message);
|
|
@@ -6071,6 +5324,8 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6071
5324
|
contextReferenceResolver: (reference) => canResolveCollapsedPasteReference(options.pastedTextStore, reference)
|
|
6072
5325
|
} : {},
|
|
6073
5326
|
continueDialogId: currentDialogId,
|
|
5327
|
+
fileWriteSessionId: currentDialogId,
|
|
5328
|
+
fileWriteGateEnabled: resolveFileWriteGateEnabled(options.env),
|
|
6074
5329
|
spaceId: options.spaceId,
|
|
6075
5330
|
category: options.category,
|
|
6076
5331
|
inheritedFromDialogKey: options.inheritedFromDialogKey,
|
|
@@ -6096,11 +5351,13 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6096
5351
|
options.onLoopEvent?.(event);
|
|
6097
5352
|
},
|
|
6098
5353
|
...options.abortSignal ? { abortSignal: options.abortSignal } : {},
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
5354
|
+
// 回合内注入(TUI 后台 run 唤醒直投):透传给 local loop。
|
|
5355
|
+
...options.drainInjections ? { drainInjections: options.drainInjections } : {},
|
|
5356
|
+
// tool-gist-fold 后 onToolEvent 无条件挂载(不再受 traceLocalTools 开关
|
|
5357
|
+
// 控制,显示模式合并为单一 gist/折叠通道)——保留 alpha 的新形态。
|
|
5358
|
+
onToolEvent: (event) => {
|
|
5359
|
+
turnOutput.handleToolEvent(event);
|
|
5360
|
+
},
|
|
6104
5361
|
...!options.noStream ? {
|
|
6105
5362
|
onTextDelta: (chunk) => {
|
|
6106
5363
|
turnOutput.pushText(chunk);
|
|
@@ -6158,6 +5415,43 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6158
5415
|
};
|
|
6159
5416
|
}
|
|
6160
5417
|
}
|
|
5418
|
+
async function checkLocalAvailabilityBeforeHttpDispatch(options) {
|
|
5419
|
+
const adapter = resolveLocalRuntimeAdapter(options);
|
|
5420
|
+
if (!adapter || typeof adapter.loadAgentConfig !== "function") return null;
|
|
5421
|
+
let config;
|
|
5422
|
+
try {
|
|
5423
|
+
config = await adapter.loadAgentConfig(options.agentKey);
|
|
5424
|
+
} catch {
|
|
5425
|
+
return null;
|
|
5426
|
+
}
|
|
5427
|
+
if (!config || typeof config !== "object") return null;
|
|
5428
|
+
const baseRecord = config.rawRecord ?? config;
|
|
5429
|
+
const credentialKey = resolveCredentialKeyWithFallback(baseRecord);
|
|
5430
|
+
const agentLevelAt = baseRecord.nextAvailableAt;
|
|
5431
|
+
const agentLevelNextAvailableAt = typeof agentLevelAt === "number" && Number.isFinite(agentLevelAt) ? agentLevelAt : void 0;
|
|
5432
|
+
if (!credentialKey && agentLevelNextAvailableAt === void 0) return null;
|
|
5433
|
+
const env = options.env;
|
|
5434
|
+
const now = Date.now();
|
|
5435
|
+
const entry = credentialKey ? await readCredentialEntry(credentialKey, env, now).catch(() => void 0) : void 0;
|
|
5436
|
+
const entryAt = entry?.nextAvailableAt;
|
|
5437
|
+
const effectiveNextAvailableAt = typeof entryAt === "number" ? mergeAvailabilityDeadline(agentLevelNextAvailableAt, entryAt) : agentLevelNextAvailableAt;
|
|
5438
|
+
if (typeof effectiveNextAvailableAt !== "number") return null;
|
|
5439
|
+
const gateDecision = resolveCooldownGate(
|
|
5440
|
+
{ nextAvailableAt: effectiveNextAvailableAt, lastProbeAt: entry?.lastProbeAt },
|
|
5441
|
+
now
|
|
5442
|
+
);
|
|
5443
|
+
if (gateDecision === "probe" && credentialKey) {
|
|
5444
|
+
await recordCredentialProbe(credentialKey, env, now).catch(() => void 0);
|
|
5445
|
+
return null;
|
|
5446
|
+
}
|
|
5447
|
+
if (gateDecision !== "blocked") return null;
|
|
5448
|
+
options.output.write(
|
|
5449
|
+
`[nolo] Agent ${options.agentName || options.agentKey} is temporarily unavailable (429 cooldown) until ${new Date(Number(effectiveNextAvailableAt)).toISOString()}.
|
|
5450
|
+
Dispatch aborted before reaching the server. Pick another agent via listAgents, or retry after the cooldown.
|
|
5451
|
+
`
|
|
5452
|
+
);
|
|
5453
|
+
return { exitCode: 1 };
|
|
5454
|
+
}
|
|
6161
5455
|
async function runAgentTurn(options) {
|
|
6162
5456
|
const authToken = resolveAuthToken2(options.env);
|
|
6163
5457
|
const runtimeMode = resolveRequestedRuntimeMode(options);
|
|
@@ -6222,26 +5516,50 @@ async function runAgentTurn(options) {
|
|
|
6222
5516
|
);
|
|
6223
5517
|
return { exitCode: 1 };
|
|
6224
5518
|
}
|
|
5519
|
+
const localBlock = await checkLocalAvailabilityBeforeHttpDispatch(options);
|
|
5520
|
+
if (localBlock) {
|
|
5521
|
+
return { exitCode: localBlock.exitCode };
|
|
5522
|
+
}
|
|
6225
5523
|
return runHttpAgentTurn(options, authToken);
|
|
6226
5524
|
}
|
|
6227
5525
|
|
|
6228
5526
|
// packages/cli/agentRunCommand.ts
|
|
6229
5527
|
import * as nodeFs from "node:fs";
|
|
6230
|
-
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
6231
|
-
import { join as join2 } from "node:path";
|
|
6232
5528
|
|
|
6233
5529
|
// packages/cli/client/autoModelRouter.ts
|
|
6234
5530
|
var CLI_AUTO_ROUTE_AGENT_KEY = BUILTIN_NOLO_AGENT_KEY;
|
|
6235
5531
|
|
|
5532
|
+
// packages/agent-runtime/agentsMd.ts
|
|
5533
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5534
|
+
import { join } from "node:path";
|
|
5535
|
+
var AGENTS_MD_MAX_BYTES = 8192;
|
|
5536
|
+
var AGENTS_MD_CANDIDATES = ["AGENTS.md", "CLAUDE.md"];
|
|
5537
|
+
function readAgentsMdLayerFromDisk(cwd) {
|
|
5538
|
+
for (const name of AGENTS_MD_CANDIDATES) {
|
|
5539
|
+
const filePath = join(cwd, name);
|
|
5540
|
+
if (!existsSync(filePath)) continue;
|
|
5541
|
+
try {
|
|
5542
|
+
let content = readFileSync(filePath, "utf8").trim();
|
|
5543
|
+
if (!content) continue;
|
|
5544
|
+
if (Buffer.byteLength(content, "utf8") > AGENTS_MD_MAX_BYTES) {
|
|
5545
|
+
content = Buffer.from(content, "utf8").subarray(0, AGENTS_MD_MAX_BYTES).toString("utf8") + "\n\n<!-- AGENTS.md truncated -->";
|
|
5546
|
+
}
|
|
5547
|
+
return buildAgentsMdLayer(content, name);
|
|
5548
|
+
} catch {
|
|
5549
|
+
}
|
|
5550
|
+
}
|
|
5551
|
+
return null;
|
|
5552
|
+
}
|
|
5553
|
+
|
|
6236
5554
|
// packages/cli/agentRunPrompts.ts
|
|
6237
|
-
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
6238
|
-
import { dirname, extname, isAbsolute, join, relative as relativePath, resolve, sep } from "node:path";
|
|
5555
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync } from "node:fs";
|
|
5556
|
+
import { dirname, extname, isAbsolute, join as join2, relative as relativePath, resolve, sep } from "node:path";
|
|
6239
5557
|
function workflowRefToCandidatePath(cwd, ref) {
|
|
6240
5558
|
const normalized = ref.trim();
|
|
6241
5559
|
if (!normalized) return "";
|
|
6242
5560
|
if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
|
|
6243
5561
|
const directPath = resolve(cwd, normalized);
|
|
6244
|
-
if (
|
|
5562
|
+
if (existsSync2(directPath)) return directPath;
|
|
6245
5563
|
}
|
|
6246
5564
|
const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
|
|
6247
5565
|
return resolve(cwd, "docs", "workflows", `${fileName}.md`);
|
|
@@ -6254,21 +5572,21 @@ function skillRefToCandidatePath(cwd, ref) {
|
|
|
6254
5572
|
if (!normalized) return "";
|
|
6255
5573
|
if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
|
|
6256
5574
|
const directPath = resolve(cwd, normalized);
|
|
6257
|
-
if (
|
|
5575
|
+
if (existsSync2(directPath)) return directPath;
|
|
6258
5576
|
}
|
|
6259
5577
|
const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
|
|
6260
5578
|
for (const dir of SKILL_SEARCH_DIRS) {
|
|
6261
5579
|
const skillMdPath = resolve(cwd, dir, fileName, "SKILL.md");
|
|
6262
|
-
if (
|
|
5580
|
+
if (existsSync2(skillMdPath)) return skillMdPath;
|
|
6263
5581
|
}
|
|
6264
5582
|
return resolve(cwd, ".agents", "skills", fileName, "SKILL.md");
|
|
6265
5583
|
}
|
|
6266
5584
|
async function resolveWorkflowReference(ref, cwd = process.cwd()) {
|
|
6267
5585
|
const path = workflowRefToCandidatePath(cwd, ref);
|
|
6268
|
-
if (!path || !
|
|
5586
|
+
if (!path || !existsSync2(path)) {
|
|
6269
5587
|
throw new Error(`Workflow reference not found: ${ref}`);
|
|
6270
5588
|
}
|
|
6271
|
-
const markdown =
|
|
5589
|
+
const markdown = readFileSync2(path, "utf8");
|
|
6272
5590
|
const parsed = parseSkillDocProtocol(markdown);
|
|
6273
5591
|
return {
|
|
6274
5592
|
ref,
|
|
@@ -6285,8 +5603,8 @@ function inlineRelativeRefs(body, skillDir) {
|
|
|
6285
5603
|
const absPath = resolve(skillDir, cleaned);
|
|
6286
5604
|
const relative = relativePath(normalizedSkillDir, absPath);
|
|
6287
5605
|
if (relative.startsWith("..") || isAbsolute(relative)) return match;
|
|
6288
|
-
if (!
|
|
6289
|
-
const refContent =
|
|
5606
|
+
if (!existsSync2(absPath) || !absPath.endsWith(".md")) return match;
|
|
5607
|
+
const refContent = readFileSync2(absPath, "utf8");
|
|
6290
5608
|
return `
|
|
6291
5609
|
|
|
6292
5610
|
### ${label}
|
|
@@ -6297,8 +5615,8 @@ ${refContent}
|
|
|
6297
5615
|
});
|
|
6298
5616
|
}
|
|
6299
5617
|
function listSkillScripts(skillDir) {
|
|
6300
|
-
const scriptsDir =
|
|
6301
|
-
if (!
|
|
5618
|
+
const scriptsDir = join2(skillDir, "scripts");
|
|
5619
|
+
if (!existsSync2(scriptsDir) || !statSync(scriptsDir).isDirectory()) return null;
|
|
6302
5620
|
const entries = readdirSync(scriptsDir).filter((e) => !e.startsWith("."));
|
|
6303
5621
|
if (entries.length === 0) return null;
|
|
6304
5622
|
return [
|
|
@@ -6325,10 +5643,10 @@ async function resolveSkillReference(ref, options = {}) {
|
|
|
6325
5643
|
} else {
|
|
6326
5644
|
const cwd = options.cwd ?? process.cwd();
|
|
6327
5645
|
const path = skillRefToCandidatePath(cwd, ref);
|
|
6328
|
-
if (!path || !
|
|
5646
|
+
if (!path || !existsSync2(path)) {
|
|
6329
5647
|
throw new Error(`Skill reference not found: ${ref}`);
|
|
6330
5648
|
}
|
|
6331
|
-
markdown =
|
|
5649
|
+
markdown = readFileSync2(path, "utf8");
|
|
6332
5650
|
filePath = path;
|
|
6333
5651
|
skillDir = dirname(path);
|
|
6334
5652
|
}
|
|
@@ -6433,8 +5751,8 @@ function prependSubjectDialogMarker(message, subjectDialogKey) {
|
|
|
6433
5751
|
function normalizeCliImageInput(input) {
|
|
6434
5752
|
if (/^(https?:|data:|file:)/i.test(input)) return input;
|
|
6435
5753
|
const absolutePath = resolve(input);
|
|
6436
|
-
if (!
|
|
6437
|
-
const base64 =
|
|
5754
|
+
if (!existsSync2(absolutePath)) return input;
|
|
5755
|
+
const base64 = readFileSync2(absolutePath).toString("base64");
|
|
6438
5756
|
return `data:${imageMimeTypeForPath(absolutePath)};base64,${base64}`;
|
|
6439
5757
|
}
|
|
6440
5758
|
function imageMimeTypeForPath(path) {
|
|
@@ -6627,16 +5945,16 @@ var buildCjkTokens = (text) => {
|
|
|
6627
5945
|
}
|
|
6628
5946
|
return tokens;
|
|
6629
5947
|
};
|
|
6630
|
-
var
|
|
5948
|
+
var tokenize = (text) => {
|
|
6631
5949
|
const normalized = text.toLowerCase();
|
|
6632
5950
|
const wordTokens = normalized.split(/[\s,.;:!?()[\]{}"'`,。!?:;、]+/).map((token) => token.trim()).filter((token) => token.length >= 2);
|
|
6633
5951
|
return [...wordTokens, ...buildCjkTokens(normalized)];
|
|
6634
5952
|
};
|
|
6635
5953
|
var keywordScore = (query, item) => {
|
|
6636
|
-
const queryTokens = new Set(
|
|
5954
|
+
const queryTokens = new Set(tokenize(query));
|
|
6637
5955
|
if (queryTokens.size === 0) return 0;
|
|
6638
5956
|
const haystack = /* @__PURE__ */ new Set([
|
|
6639
|
-
...
|
|
5957
|
+
...tokenize(item.content),
|
|
6640
5958
|
...(item.tags ?? []).map((tag) => tag.toLowerCase()),
|
|
6641
5959
|
item.patternKey?.toLowerCase() ?? ""
|
|
6642
5960
|
]);
|
|
@@ -6938,6 +6256,21 @@ var resolveCliMemory = async (input) => {
|
|
|
6938
6256
|
function resolvePositiveMs(value, fallback) {
|
|
6939
6257
|
return parsePositiveFiniteNumberOrFallback(value, fallback);
|
|
6940
6258
|
}
|
|
6259
|
+
function resolveRunOutcome(input) {
|
|
6260
|
+
switch (input.kind) {
|
|
6261
|
+
case "stall":
|
|
6262
|
+
return { status: "failed", exitCode: 1 };
|
|
6263
|
+
case "timeout":
|
|
6264
|
+
return { status: "timeout", exitCode: 124 };
|
|
6265
|
+
case "result": {
|
|
6266
|
+
const failed = input.isStalledOrTruncated || input.exitCode !== 0;
|
|
6267
|
+
if (!failed) {
|
|
6268
|
+
return { status: "done", exitCode: 0 };
|
|
6269
|
+
}
|
|
6270
|
+
return { status: "failed", exitCode: input.exitCode !== 0 ? input.exitCode : 1 };
|
|
6271
|
+
}
|
|
6272
|
+
}
|
|
6273
|
+
}
|
|
6941
6274
|
async function resolveAgentRunAgentKey(args) {
|
|
6942
6275
|
if (!args.agentInput.trim() || args.agentInput.startsWith("agent-")) {
|
|
6943
6276
|
return void 0;
|
|
@@ -6973,11 +6306,14 @@ async function runAgentRunCommand(args, deps) {
|
|
|
6973
6306
|
deps.stallTimeoutMs ?? env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS,
|
|
6974
6307
|
5 * 6e4
|
|
6975
6308
|
);
|
|
6309
|
+
const stallEnvExplicitlySet = typeof env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS === "string" && env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS.trim().length > 0;
|
|
6310
|
+
const armStallWatchdog = hasRegistry || stallEnvExplicitlySet;
|
|
6311
|
+
const armTimeoutWatchdog = typeof parsed.timeoutMs === "number" && parsed.timeoutMs > 0;
|
|
6976
6312
|
let timedOut = false;
|
|
6977
6313
|
let stalled = false;
|
|
6978
6314
|
let timeoutTimer;
|
|
6979
6315
|
let stallTimer;
|
|
6980
|
-
const activityTracker =
|
|
6316
|
+
const activityTracker = armStallWatchdog ? createRunActivityTracker(childRunId ?? "__foreground__", {
|
|
6981
6317
|
env,
|
|
6982
6318
|
homedir: deps.homedir,
|
|
6983
6319
|
fs: deps.fs,
|
|
@@ -6990,7 +6326,7 @@ async function runAgentRunCommand(args, deps) {
|
|
|
6990
6326
|
activityTracker?.dispose();
|
|
6991
6327
|
};
|
|
6992
6328
|
let rejectOnWatchdogFailure;
|
|
6993
|
-
const watchdogFailure =
|
|
6329
|
+
const watchdogFailure = armStallWatchdog || armTimeoutWatchdog ? new Promise((_, reject) => {
|
|
6994
6330
|
rejectOnWatchdogFailure = reject;
|
|
6995
6331
|
}) : void 0;
|
|
6996
6332
|
const raceWithWatchdog = (work) => watchdogFailure ? Promise.race([work, watchdogFailure]) : work;
|
|
@@ -7000,7 +6336,15 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7000
6336
|
} catch {
|
|
7001
6337
|
}
|
|
7002
6338
|
};
|
|
7003
|
-
|
|
6339
|
+
const finalizeWatchdogOutcome = (outcome, note) => {
|
|
6340
|
+
if (!hasRegistry) return;
|
|
6341
|
+
(deps.finalizeRunRecord ?? finalizeRunRecord)(
|
|
6342
|
+
childRunId,
|
|
6343
|
+
{ status: outcome.status, exitCode: outcome.exitCode, note },
|
|
6344
|
+
{ env, homedir: deps.homedir, fs: deps.fs, now: deps.now }
|
|
6345
|
+
);
|
|
6346
|
+
};
|
|
6347
|
+
if (armStallWatchdog) {
|
|
7004
6348
|
stallTimer = setInterval(() => {
|
|
7005
6349
|
if (timedOut || stalled) return;
|
|
7006
6350
|
const activity = activityTracker?.getActivity();
|
|
@@ -7018,31 +6362,25 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7018
6362
|
const note = `stalled: no progress for ${stallTimeoutMs}ms`;
|
|
7019
6363
|
output.write(`[nolo] local run ${note}
|
|
7020
6364
|
`);
|
|
7021
|
-
(
|
|
7022
|
-
|
|
7023
|
-
{ status: "failed", note },
|
|
7024
|
-
{ env, homedir: deps.homedir, fs: deps.fs, now: deps.now }
|
|
7025
|
-
);
|
|
6365
|
+
const outcome = resolveRunOutcome({ kind: "stall" });
|
|
6366
|
+
finalizeWatchdogOutcome(outcome, note);
|
|
7026
6367
|
rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
|
|
7027
|
-
exitFromWatchdog(
|
|
6368
|
+
exitFromWatchdog(outcome.exitCode);
|
|
7028
6369
|
}
|
|
7029
6370
|
}, Math.min(stallTimeoutMs, 1e4));
|
|
7030
|
-
|
|
7031
|
-
|
|
7032
|
-
|
|
7033
|
-
|
|
7034
|
-
|
|
7035
|
-
|
|
6371
|
+
}
|
|
6372
|
+
if (armTimeoutWatchdog) {
|
|
6373
|
+
timeoutTimer = setTimeout(() => {
|
|
6374
|
+
timedOut = true;
|
|
6375
|
+
clearWatchdogs();
|
|
6376
|
+
const note = `timed out after ${parsed.timeoutMs}ms`;
|
|
6377
|
+
output.write(`[nolo] local run ${note}
|
|
7036
6378
|
`);
|
|
7037
|
-
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
|
|
7043
|
-
exitFromWatchdog(124);
|
|
7044
|
-
}, parsed.timeoutMs);
|
|
7045
|
-
}
|
|
6379
|
+
const outcome = resolveRunOutcome({ kind: "timeout" });
|
|
6380
|
+
finalizeWatchdogOutcome(outcome, note);
|
|
6381
|
+
rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
|
|
6382
|
+
exitFromWatchdog(outcome.exitCode);
|
|
6383
|
+
}, parsed.timeoutMs);
|
|
7046
6384
|
}
|
|
7047
6385
|
const wantsFallbackSuggestions = parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0;
|
|
7048
6386
|
const rawAgentInput = resolveRawAgentInput(args, deps.commandPath) ?? parsed.agentKey;
|
|
@@ -7197,22 +6535,8 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7197
6535
|
let memoryOverlayLayer = null;
|
|
7198
6536
|
let memoryUseGuidanceLayer = null;
|
|
7199
6537
|
if (!isSubtask) {
|
|
7200
|
-
const
|
|
7201
|
-
|
|
7202
|
-
const agentsMdPath = join2(cliCwd, name);
|
|
7203
|
-
if (existsSync2(agentsMdPath)) {
|
|
7204
|
-
try {
|
|
7205
|
-
let mdContent = readFileSync2(agentsMdPath, "utf8").trim();
|
|
7206
|
-
if (!mdContent) continue;
|
|
7207
|
-
if (Buffer.byteLength(mdContent, "utf8") > AGENTS_MD_MAX) {
|
|
7208
|
-
mdContent = Buffer.from(mdContent, "utf8").subarray(0, AGENTS_MD_MAX).toString("utf8") + "\n\n<!-- AGENTS.md truncated -->";
|
|
7209
|
-
}
|
|
7210
|
-
scopedLayers.push(buildAgentsMdLayer(mdContent, name));
|
|
7211
|
-
break;
|
|
7212
|
-
} catch {
|
|
7213
|
-
}
|
|
7214
|
-
}
|
|
7215
|
-
}
|
|
6538
|
+
const agentsMdLayer = readAgentsMdLayerFromDisk(cliCwd);
|
|
6539
|
+
if (agentsMdLayer) scopedLayers.push(agentsMdLayer);
|
|
7216
6540
|
skillContentBlocks.push(...buildSkillContextBlocks(skillReferences));
|
|
7217
6541
|
scopedLayers.push(buildSkillDiscoveryContextLayer(cliCwd));
|
|
7218
6542
|
if (!deps.memoryRecallDisabled) {
|
|
@@ -7403,12 +6727,16 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7403
6727
|
if (typeof childRunId === "string" && childRunId.length > 0) {
|
|
7404
6728
|
const isStalledOrTruncated = result.emptyAssistantFallbackReason === "length_truncated" || result.emptyAssistantFallbackReason === "stream_truncated" || result.emptyAssistantFallbackReason === "repetition_loop" || result.emptyAssistantFallbackReason === "stagnant_tool_calls";
|
|
7405
6729
|
const truncationNote = isStalledOrTruncated ? { note: `empty assistant output: ${result.emptyAssistantFallbackReason}` } : {};
|
|
7406
|
-
const
|
|
6730
|
+
const outcome = resolveRunOutcome({
|
|
6731
|
+
kind: "result",
|
|
6732
|
+
exitCode: result.exitCode,
|
|
6733
|
+
isStalledOrTruncated
|
|
6734
|
+
});
|
|
7407
6735
|
await (deps.finalizeRunRecord ?? finalizeRunRecord)(
|
|
7408
6736
|
childRunId,
|
|
7409
6737
|
{
|
|
7410
|
-
status:
|
|
7411
|
-
exitCode:
|
|
6738
|
+
status: outcome.status,
|
|
6739
|
+
exitCode: outcome.exitCode,
|
|
7412
6740
|
dialogId: result.dialogId,
|
|
7413
6741
|
...truncationNote
|
|
7414
6742
|
},
|
|
@@ -7480,8 +6808,6 @@ export {
|
|
|
7480
6808
|
getActiveThemeMode,
|
|
7481
6809
|
setActiveThemeMode,
|
|
7482
6810
|
setActiveBrightness,
|
|
7483
|
-
getActiveDensity,
|
|
7484
|
-
setActiveDensity,
|
|
7485
6811
|
detectSystemBrightnessFromEnv,
|
|
7486
6812
|
resolveTuiBrightness,
|
|
7487
6813
|
resolveTuiThemeMode,
|
|
@@ -7494,8 +6820,9 @@ export {
|
|
|
7494
6820
|
themeText,
|
|
7495
6821
|
tuiRenderThemeFingerprint,
|
|
7496
6822
|
setMathRenderingEnabled,
|
|
6823
|
+
polishBreathInsertsBlankBetween,
|
|
7497
6824
|
formatAssistantDisplay,
|
|
7498
|
-
|
|
6825
|
+
TUI_TREE_MARKER,
|
|
7499
6826
|
COLLAPSED_PASTE_PLACEHOLDER_RE,
|
|
7500
6827
|
shouldCollapsePaste,
|
|
7501
6828
|
createCollapsedPasteStore,
|
|
@@ -7507,6 +6834,7 @@ export {
|
|
|
7507
6834
|
expandRangeToCollapsedPasteChips,
|
|
7508
6835
|
findCollapsedPasteSpanAt,
|
|
7509
6836
|
runAgentTurn,
|
|
6837
|
+
readAgentsMdLayerFromDisk,
|
|
7510
6838
|
resolveWorkflowReference,
|
|
7511
6839
|
resolveSkillReference,
|
|
7512
6840
|
buildSkillContextBlocks,
|
|
@@ -7514,6 +6842,7 @@ export {
|
|
|
7514
6842
|
normalizeCliImageInput,
|
|
7515
6843
|
inspectLocalRunWorkspace,
|
|
7516
6844
|
resolveCliMemory,
|
|
6845
|
+
resolveRunOutcome,
|
|
7517
6846
|
runAgentRunCommand,
|
|
7518
6847
|
isBalanceExhaustedError
|
|
7519
6848
|
};
|