nolo-cli 0.19.0 → 0.24.0-alpha.7
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-X5PCIZN6.js → _executeModel-ARCMGGMY.js} +46 -44
- package/{action-LT7BRFLK.js → action-5MNAXR5B.js} +7 -6
- package/{addContentAction-PL3KKBDH.js → addContentAction-UNSYTVTB.js} +5 -5
- package/{addDialogAgentAction-FCMSKYAF.js → addDialogAgentAction-LJGNP2AO.js} +5 -5
- package/{agentDeleteCommand-2BZDQV36.js → agentDeleteCommand-C5PIEBMZ.js} +27 -26
- package/{agentEmailCommands-2QJDGRMB.js → agentEmailCommands-QTGQ3ZAD.js} +57 -55
- package/{agentListCommands-6VEPTKBI.js → agentListCommands-LRHBS3A5.js} +30 -26
- package/{agentMachineCommands-NVVHNWYI.js → agentMachineCommands-4PXIT4BP.js} +25 -24
- package/{agentRecordCommands-4GGRDMD4.js → agentRecordCommands-ZZPTYTYR.js} +52 -50
- package/{agentRunCommand-XOLQNKBZ.js → agentRunCommand-7ZTPZNUX.js} +55 -54
- package/{agentRunControl-Y5AFH5PQ.js → agentRunControl-SNUKXN6J.js} +6 -2
- package/{agentRuntimeLocal-7WYWCGL4.js → agentRuntimeLocal-QOYY5UV2.js} +19 -18
- package/{agentSlice-EAXPGEYV.js → agentSlice-J3W3RX2I.js} +5 -5
- package/{appDeleteCommands-77KR2RJ4.js → appDeleteCommands-7NS46XDH.js} +23 -22
- package/{appDeployCommands-K7CAHGBI.js → appDeployCommands-RSRNQ67U.js} +23 -22
- package/{appDeployStatusCommands-4OEKLTBT.js → appDeployStatusCommands-EF4RSGC6.js} +23 -22
- package/{appGetCommands-VM2WDLAZ.js → appGetCommands-YA7JWYUX.js} +23 -22
- package/{appListCommands-GX6BBA6U.js → appListCommands-WM2ON6JW.js} +23 -22
- package/{authCommand-DY6UUL6O.js → authCommand-HJP7FURK.js} +12 -13
- package/{authCommands-XTBV7OFZ.js → authCommands-NYZM2B2I.js} +4 -5
- package/{chunk-MKA6QE5E.js → chunk-2IPEVBUO.js} +126 -68
- package/{chunk-OWOHNGCN.js → chunk-2MBTWINN.js} +42 -3
- package/{chunk-K6EUAOW3.js → chunk-35RYGII3.js} +1 -1
- package/{chunk-TRT4I4UD.js → chunk-4POUK2BV.js} +2 -2
- package/{chunk-LLWKHDG4.js → chunk-4ULSC37S.js} +1 -3
- package/{chunk-EDV7EBOI.js → chunk-4ZH6GUJF.js} +2151 -1500
- package/{chunk-MVQ4TBSD.js → chunk-54VHTARN.js} +1 -1
- package/{chunk-L4F3I4SR.js → chunk-5HQQ4LUU.js} +4 -6
- package/{chunk-Z4NR32XR.js → chunk-5RGU3J7P.js} +13 -0
- package/{chunk-7BUYEZ6U.js → chunk-7H3UTGPM.js} +12 -72
- package/{chunk-RQN4SEKL.js → chunk-7W6GFNJL.js} +1 -1
- package/{chunk-HEGV7BH3.js → chunk-AQZCWJOG.js} +1 -1
- package/{chunk-3ND52WIL.js → chunk-ATWUOTJP.js} +180 -24
- package/chunk-CF7S2RYZ.js +376 -0
- package/{chunk-I2ZJKTG5.js → chunk-CGVRC2TB.js} +7 -7
- package/{chunk-UAIVG4J6.js → chunk-CHSCAUZN.js} +1 -8
- package/{chunk-KFEVY3ST.js → chunk-D34RI6NI.js} +18 -8
- package/{chunk-ROWQEJRP.js → chunk-DXJS7VSG.js} +3 -2
- package/{chunk-MHSGJW4Z.js → chunk-EHOYZRTI.js} +44 -14
- package/{chunk-XRZJGPFI.js → chunk-FON47ACC.js} +4 -4
- package/{chunk-SCTYAHYK.js → chunk-H2NAWOLH.js} +217 -141
- package/{chunk-MPVYDS7I.js → chunk-H6ODMJR3.js} +3 -3
- package/{chunk-R35XMF6F.js → chunk-H73ZV2GL.js} +352 -30
- package/{chunk-4T5F7YZQ.js → chunk-I6RJGORZ.js} +1 -1
- package/{chunk-OK6YSWLH.js → chunk-IICW77GI.js} +1 -1
- package/{chunk-VDXCXCXH.js → chunk-IUDMBCXC.js} +1 -1
- package/{chunk-AHCY2S2I.js → chunk-JADNODCQ.js} +1 -1
- package/{chunk-DFCFMCY6.js → chunk-JBLY6HQP.js} +2 -2
- package/{chunk-UGUW3FHG.js → chunk-JMSCXQUG.js} +2 -2
- package/{chunk-N54HIJVJ.js → chunk-KFUCLS7Z.js} +101 -9
- package/{chunk-FQZZLA3C.js → chunk-KXKQO4Q6.js} +17 -0
- package/{chunk-3Q7WHGCB.js → chunk-L65QKSVJ.js} +1 -1
- package/{chunk-3ZX7PERL.js → chunk-LALVWNE4.js} +20 -7
- package/{chunk-PJSV3IZ5.js → chunk-M3TMVJKG.js} +1 -1
- package/{chunk-REA4JLBH.js → chunk-M5OZCOBV.js} +7 -6
- package/{chunk-JLA4FXYC.js → chunk-MALVZUYL.js} +1 -1
- package/{chunk-GFUIQ4RY.js → chunk-MXFQHRSS.js} +1 -1
- package/{chunk-LSFAWXKC.js → chunk-N7J63Q6C.js} +1 -0
- package/{chunk-6Y7A3OQQ.js → chunk-NRY4GCKJ.js} +2 -0
- package/{chunk-G5U6LDLG.js → chunk-NVHPMDSZ.js} +6 -6
- package/{chunk-23FZYPLC.js → chunk-OJFYT3ZQ.js} +842 -1060
- package/{chunk-ELT65PZW.js → chunk-OXLLFZNF.js} +1 -1
- package/{chunk-CZ6NYQTV.js → chunk-P4QWLZGU.js} +2 -2
- package/{chunk-5MIDPSSK.js → chunk-PB7G5MAM.js} +3 -3
- package/{chunk-HWW2M4SN.js → chunk-QLVWFXZQ.js} +5 -4
- package/{chunk-VYHDJEQD.js → chunk-QNLLGS37.js} +136 -78
- package/{chunk-XHG22OEX.js → chunk-ROJI6DRT.js} +2 -2
- package/{chunk-BV4VEE3W.js → chunk-ROYOKSX4.js} +243 -354
- package/{chunk-VNAEBGDK.js → chunk-RZNYL4LW.js} +123 -26
- package/{chunk-RVOUXDFU.js → chunk-S6KVFOUG.js} +6 -34
- package/{chunk-V3ED5AWK.js → chunk-S77SCVBU.js} +27 -16
- package/{chunk-UBHAWFQ6.js → chunk-S7RWIPDI.js} +42 -19
- package/{chunk-B5TOXZAK.js → chunk-SIZQB7BD.js} +1 -1
- package/{chunk-DFFIZ25G.js → chunk-SLOGKB7M.js} +4 -1
- package/{chunk-FXUSIQC2.js → chunk-SROR5TSM.js} +1 -1
- package/{chunk-PIZYJVHQ.js → chunk-TN4YHAI3.js} +4 -4
- package/{chunk-IYEXFJPC.js → chunk-TW35GDNW.js} +64 -57
- package/chunk-UZ6XXCVR.js +50 -0
- package/{chunk-DKZFOK24.js → chunk-UZH44DWK.js} +7 -288
- package/{chunk-YGW4G5W5.js → chunk-X546QUDT.js} +61 -12
- package/chunk-YYLHWIW6.js +48 -0
- package/{chunk-SWDPIPOY.js → chunk-ZGVW7MSZ.js} +1 -1
- package/{chunk-34WPV75U.js → chunk-ZUXIXYJI.js} +1 -1
- package/{chunk-VC6OZXO5.js → chunk-ZWJOGMKH.js} +2 -26
- package/{cliExecutor-DNE7TCC4.js → cliExecutor-K3F7DMRO.js} +2 -2
- package/{codingSkills-36KN5NQT.js → codingSkills-EN6Z6G6U.js} +4 -4
- package/{createAgentAutomationAction-GNFF524X.js → createAgentAutomationAction-MKQWN4VQ.js} +19 -18
- package/{createDialogAction-RB55KCLO.js → createDialogAction-YWIZPLFS.js} +22 -20
- package/{createPageAction-Y7343GLU.js → createPageAction-74TTEIPC.js} +20 -19
- package/{db-W3O47YGF.js → db-W5UHK4P3.js} +150 -0
- package/{dbSlice-CGSRFJN3.js → dbSlice-5BKDURDL.js} +4 -4
- package/{dialogCommands-IAZK6YHQ.js → dialogCommands-MJIP32FL.js} +24 -23
- package/{dialogSlice-UQAXF23P.js → dialogSlice-KLLVH4WI.js} +24 -18
- package/{docCreateCommands-I2EWZGCI.js → docCreateCommands-5DN472U6.js} +24 -27
- package/{docDeleteCommands-IZ45UZKG.js → docDeleteCommands-HE76LBN4.js} +25 -24
- package/{docReadCommands-R6Z4QJYU.js → docReadCommands-XVGZSCBS.js} +24 -23
- package/{docStore-5HOJ4D7D.js → docStore-SPH3D6BT.js} +20 -19
- package/{docUpdateCommands-2LRBKQPY.js → docUpdateCommands-P7IAWUAD.js} +24 -27
- package/{fetchMessages-BMGVZVSE.js → fetchMessages-W4IKHPCS.js} +2 -3
- package/{getPricing-G7DLAST6.js → getPricing-WENPBVWH.js} +3 -3
- package/{handleSendMessageAction-Q4HY35WX.js → handleSendMessageAction-ZU6WJVL7.js} +23 -20
- package/index.js +74 -74
- package/{localDialogRead-4H3QJFLW.js → localDialogRead-JXTAHW2E.js} +2 -2
- package/{machineCommands-PKBPQKTY.js → machineCommands-NI76PVHK.js} +59 -57
- package/{machineWsRunDispatch-UZAW4OXJ.js → machineWsRunDispatch-W3G6NJVQ.js} +51 -49
- package/{models-DJFSJ7SW.js → models-DB27UAE3.js} +2 -2
- package/package.json +1 -1
- package/{read-3FMPZPER.js → read-F3L3T2WJ.js} +2 -1
- package/{readDocTool-VSYHKK3V.js → readDocTool-FOHWVA4R.js} +1 -1
- package/{readlineWorkspace-Y2RDOFZG.js → readlineWorkspace-BDH4G477.js} +880 -425
- package/{removeDialogAgentAction-OAGA2G3U.js → removeDialogAgentAction-QCFGIUIH.js} +8 -7
- package/{runAgentClientLoop-NBPIKJ6J.js → runAgentClientLoop-ZPKMXCM5.js} +45 -38
- package/{setDialogExtraReferencesAction-JZEXA5SL.js → setDialogExtraReferencesAction-DK4CKERU.js} +5 -5
- package/{setPrimaryDialogAgentAction-4ZUQQKDG.js → setPrimaryDialogAgentAction-SJSO6N27.js} +8 -7
- package/{settingSlice-7MNKHZ6R.js → settingSlice-XNM5AFPU.js} +6 -5
- package/{spaceCommands-DHCZ7J5I.js → spaceCommands-3GGBJRQR.js} +25 -24
- package/{spaceSlice-ZXLLG3CR.js → spaceSlice-47Z6XLFQ.js} +21 -18
- package/{streamAgentChatTurn-L3YW6LSB.js → streamAgentChatTurn-VT5K5JSD.js} +140 -98
- package/switchDialogAgentAction-4OAC6QRN.js +61 -0
- package/{tableCommands-BEQAGE4I.js → tableCommands-HEQYT2KP.js} +1 -1
- package/{toolApiClient-QI3YBNWB.js → toolApiClient-ISM4ZQX4.js} +2 -2
- package/{tools-ECGXR5QF.js → tools-L7RCHAPT.js} +36 -33
- package/{tuiSummaryLlmCaller-OMSCNHXA.js → tuiSummaryLlmCaller-3DYOLTVN.js} +6 -6
- package/{updateCommands-XTW55TOT.js → updateCommands-HTCOBXCA.js} +2 -2
- package/{updateDialogTitleAction-HQ2EUDFT.js → updateDialogTitleAction-KMPVPQ4A.js} +28 -27
- package/chunk-DL6EPNIK.js +0 -50
- package/chunk-V5R4NZP2.js +0 -78
- package/chunk-X4Q4UZEY.js +0 -26
- package/queryRunOverlay-O4LOMMPO.js +0 -161
- package/runOverlayPresentation-ZO4VCWEU.js +0 -11
- package/types-ZSTJ7MPR.js +0 -7
- package/{chunk-X7W4TNB4.js → chunk-CMKUBIGW.js} +3 -3
- package/{runtimeDoctorCommands-E2OUORHK.js → runtimeDoctorCommands-HSU632DY.js} +3 -3
|
@@ -3,23 +3,9 @@ import {
|
|
|
3
3
|
normalizeDialogRecord,
|
|
4
4
|
readDialogSnapshot,
|
|
5
5
|
sortDialogs
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import {
|
|
8
|
-
listFavoriteAgentIdsAcrossServers,
|
|
9
|
-
listLocalCachedAgents,
|
|
10
|
-
listRemoteAgents,
|
|
11
|
-
listRemoteAgentsAcrossServers
|
|
12
|
-
} from "./chunk-HWW2M4SN.js";
|
|
13
|
-
import "./chunk-ID4G2MAR.js";
|
|
14
|
-
import {
|
|
15
|
-
listUserRecordsFromServers
|
|
16
|
-
} from "./chunk-HEGV7BH3.js";
|
|
17
|
-
import {
|
|
18
|
-
buildOverlayPresentation
|
|
19
|
-
} from "./chunk-V5R4NZP2.js";
|
|
6
|
+
} from "./chunk-S77SCVBU.js";
|
|
20
7
|
import {
|
|
21
8
|
ANSI_ESCAPE_REGEX,
|
|
22
|
-
CLI_AUTO_TIER_AGENT_KEYS,
|
|
23
9
|
CLI_AUTO_TIER_AGENT_KEY_TABLE,
|
|
24
10
|
CLI_IMAGE_AGENT_KEY,
|
|
25
11
|
COLLAPSED_PASTE_PLACEHOLDER_RE,
|
|
@@ -45,14 +31,15 @@ import {
|
|
|
45
31
|
getActiveDensity,
|
|
46
32
|
getActiveThemeName,
|
|
47
33
|
isBalanceExhaustedError,
|
|
34
|
+
isQuotaExhaustedError,
|
|
48
35
|
normalizeToolDisplayMode,
|
|
49
36
|
padOrTruncateToWidth,
|
|
50
37
|
releaseCollapsedPaste,
|
|
51
38
|
releaseCollapsedPasteReferences,
|
|
39
|
+
renderSurfaceLine,
|
|
52
40
|
renderTokenStatus,
|
|
53
41
|
replaceCollapsedPastesWithReferences,
|
|
54
42
|
resolveAgentContextWindow,
|
|
55
|
-
resolveCliAutoFallbackTier,
|
|
56
43
|
resolveCliColorEnabled,
|
|
57
44
|
resolveSkillReference,
|
|
58
45
|
resolveTuiBrightness,
|
|
@@ -68,141 +55,143 @@ import {
|
|
|
68
55
|
themeColorSequence,
|
|
69
56
|
themeText,
|
|
70
57
|
truncateAnsi,
|
|
58
|
+
userSurfaceBackgroundSequence,
|
|
71
59
|
visibleWidth,
|
|
72
60
|
wrapTextToLines,
|
|
73
61
|
wrapTranscriptLine
|
|
74
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-ROYOKSX4.js";
|
|
75
63
|
import "./chunk-DZ3XJVET.js";
|
|
64
|
+
import "./chunk-6HYVJV7B.js";
|
|
76
65
|
import {
|
|
77
|
-
|
|
78
|
-
|
|
66
|
+
listFavoriteAgentIdsAcrossServers,
|
|
67
|
+
listLocalCachedAgents,
|
|
68
|
+
listRemoteAgents,
|
|
69
|
+
listRemoteAgentsAcrossServers,
|
|
70
|
+
normalizeListedAgent
|
|
71
|
+
} from "./chunk-QLVWFXZQ.js";
|
|
72
|
+
import "./chunk-ID4G2MAR.js";
|
|
79
73
|
import {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
} from "./chunk-DFCFMCY6.js";
|
|
74
|
+
listUserRecordsFromServers,
|
|
75
|
+
readLiveDbRecordAfterTombstoneMerge
|
|
76
|
+
} from "./chunk-AQZCWJOG.js";
|
|
84
77
|
import {
|
|
85
78
|
createCliLocalRuntimeAdapter,
|
|
86
79
|
initCliLocale,
|
|
87
|
-
isQuotaExhaustedError,
|
|
88
80
|
parseCliLocale,
|
|
89
81
|
readTimestamp,
|
|
90
82
|
setCliLocale,
|
|
91
83
|
t
|
|
92
|
-
} from "./chunk-
|
|
93
|
-
import "./chunk-
|
|
94
|
-
import
|
|
84
|
+
} from "./chunk-OJFYT3ZQ.js";
|
|
85
|
+
import "./chunk-IICW77GI.js";
|
|
86
|
+
import {
|
|
87
|
+
getReadableCliDb
|
|
88
|
+
} from "./chunk-WFHXMLHZ.js";
|
|
89
|
+
import {
|
|
90
|
+
deleteDbRecord,
|
|
91
|
+
queryUserRecords,
|
|
92
|
+
readDbRecord
|
|
93
|
+
} from "./chunk-JBLY6HQP.js";
|
|
94
|
+
import "./chunk-ZGVW7MSZ.js";
|
|
95
95
|
import {
|
|
96
|
+
NOLO_DEFAULT_AGENT_KEY,
|
|
96
97
|
resolveCliAgentKeyInput
|
|
97
98
|
} from "./chunk-VHBWHNVT.js";
|
|
98
99
|
import "./chunk-LTRXGFMS.js";
|
|
99
|
-
import "./chunk-
|
|
100
|
-
import "./chunk-6HYVJV7B.js";
|
|
100
|
+
import "./chunk-54VHTARN.js";
|
|
101
101
|
import "./chunk-JEXVIMYZ.js";
|
|
102
102
|
import {
|
|
103
103
|
prepareTools
|
|
104
|
-
} from "./chunk-
|
|
105
|
-
import "./chunk-
|
|
106
|
-
import
|
|
107
|
-
expandEnabledPacks
|
|
108
|
-
} from "./chunk-EDV7EBOI.js";
|
|
104
|
+
} from "./chunk-P4QWLZGU.js";
|
|
105
|
+
import "./chunk-SROR5TSM.js";
|
|
106
|
+
import "./chunk-4ZH6GUJF.js";
|
|
109
107
|
import "./chunk-RQSOAMPJ.js";
|
|
110
|
-
import "./chunk-
|
|
108
|
+
import "./chunk-I6RJGORZ.js";
|
|
109
|
+
import "./chunk-LALVWNE4.js";
|
|
111
110
|
import "./chunk-KQHGZWSV.js";
|
|
112
|
-
import "./chunk-4T5F7YZQ.js";
|
|
113
111
|
import "./chunk-3LY4F7SV.js";
|
|
114
112
|
import "./chunk-VF4K2QE6.js";
|
|
115
|
-
import "./chunk-
|
|
116
|
-
import
|
|
117
|
-
initialRunOverlayState,
|
|
118
|
-
reduceRunOverlay
|
|
119
|
-
} from "./chunk-DL6EPNIK.js";
|
|
120
|
-
import "./chunk-OWOHNGCN.js";
|
|
121
|
-
import "./chunk-JLA4FXYC.js";
|
|
113
|
+
import "./chunk-NVHPMDSZ.js";
|
|
114
|
+
import "./chunk-MALVZUYL.js";
|
|
122
115
|
import "./chunk-VP4WJWKW.js";
|
|
123
116
|
import "./chunk-63W5N6P3.js";
|
|
124
117
|
import "./chunk-WJRJDX2W.js";
|
|
125
|
-
import "./chunk-
|
|
126
|
-
import "./chunk-IYEXFJPC.js";
|
|
118
|
+
import "./chunk-TW35GDNW.js";
|
|
127
119
|
import {
|
|
128
120
|
extractReferenceKeysFromMessage
|
|
129
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-H2NAWOLH.js";
|
|
130
122
|
import {
|
|
131
123
|
buildBuiltinSummaryContent
|
|
132
124
|
} from "./chunk-XOIF2TNF.js";
|
|
133
|
-
import "./chunk-B5TOXZAK.js";
|
|
134
125
|
import "./chunk-MRC4Q34M.js";
|
|
135
|
-
import "./chunk-
|
|
126
|
+
import "./chunk-SIZQB7BD.js";
|
|
127
|
+
import "./chunk-M5OZCOBV.js";
|
|
128
|
+
import "./chunk-YYLHWIW6.js";
|
|
136
129
|
import "./chunk-CWMSB67P.js";
|
|
137
|
-
import "./chunk-
|
|
138
|
-
import "./chunk-
|
|
130
|
+
import "./chunk-ROJI6DRT.js";
|
|
131
|
+
import "./chunk-5RGU3J7P.js";
|
|
139
132
|
import "./chunk-M76ECQRD.js";
|
|
140
|
-
import "./chunk-
|
|
133
|
+
import "./chunk-L65QKSVJ.js";
|
|
141
134
|
import {
|
|
142
135
|
buildSkillDiscoveryContextBlock
|
|
143
136
|
} from "./chunk-7OBMZCRD.js";
|
|
144
|
-
import "./chunk-
|
|
145
|
-
import
|
|
137
|
+
import "./chunk-7H3UTGPM.js";
|
|
138
|
+
import {
|
|
139
|
+
expandEnabledPacks
|
|
140
|
+
} from "./chunk-CF7S2RYZ.js";
|
|
141
|
+
import "./chunk-ZWJOGMKH.js";
|
|
146
142
|
import "./chunk-WZSRQNQG.js";
|
|
147
143
|
import {
|
|
148
144
|
buildLocalWorkspaceOpenAiTools,
|
|
149
145
|
buildLocalWorkspaceToolset,
|
|
150
146
|
getProcessRegistry
|
|
151
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-H73ZV2GL.js";
|
|
152
148
|
import "./chunk-ZNFJWEN4.js";
|
|
153
|
-
import "./chunk-
|
|
149
|
+
import "./chunk-KFUCLS7Z.js";
|
|
154
150
|
import "./chunk-OIQPORYI.js";
|
|
155
151
|
import {
|
|
156
152
|
readCommandActionGatePayload,
|
|
157
153
|
resolveAgentImageInputSupport
|
|
158
|
-
} from "./chunk-
|
|
159
|
-
import "./chunk-
|
|
154
|
+
} from "./chunk-X546QUDT.js";
|
|
155
|
+
import "./chunk-N7J63Q6C.js";
|
|
160
156
|
import {
|
|
161
157
|
buildCurrentTimeBlock,
|
|
162
158
|
buildIdentityBlock,
|
|
163
159
|
buildRuntimeGuidanceBlocks
|
|
164
|
-
} from "./chunk-
|
|
165
|
-
import "./chunk-
|
|
160
|
+
} from "./chunk-ZUXIXYJI.js";
|
|
161
|
+
import "./chunk-D34RI6NI.js";
|
|
166
162
|
import {
|
|
167
163
|
resolvePlatformAuthToken
|
|
168
|
-
} from "./chunk-
|
|
169
|
-
import "./chunk-
|
|
164
|
+
} from "./chunk-EHOYZRTI.js";
|
|
165
|
+
import "./chunk-UZH44DWK.js";
|
|
166
|
+
import "./chunk-2MBTWINN.js";
|
|
170
167
|
import {
|
|
171
168
|
DEFAULT_CONTEXT_WINDOW,
|
|
172
169
|
estimateTokenCount,
|
|
173
170
|
getModelContextWindow,
|
|
174
171
|
planCompression,
|
|
175
172
|
serializeMessageContent
|
|
176
|
-
} from "./chunk-
|
|
173
|
+
} from "./chunk-CGVRC2TB.js";
|
|
177
174
|
import {
|
|
178
175
|
clipCompactText
|
|
179
176
|
} from "./chunk-5MMAK75Q.js";
|
|
180
177
|
import "./chunk-5CS33IBL.js";
|
|
181
178
|
import "./chunk-JZPBVBIY.js";
|
|
182
|
-
import "./chunk-
|
|
179
|
+
import "./chunk-CHSCAUZN.js";
|
|
183
180
|
import "./chunk-ZHXJ6M7T.js";
|
|
184
|
-
import {
|
|
185
|
-
toErrorMessage
|
|
186
|
-
} from "./chunk-HNMXYYJR.js";
|
|
187
|
-
import "./chunk-ELT65PZW.js";
|
|
188
181
|
import "./chunk-AL2V7U3E.js";
|
|
189
182
|
import "./chunk-4PWB7JRR.js";
|
|
190
183
|
import {
|
|
191
184
|
canonicalizeToolNames
|
|
192
185
|
} from "./chunk-ZZ2MH7LE.js";
|
|
193
|
-
import "./chunk-
|
|
194
|
-
import {
|
|
195
|
-
extractCustomId
|
|
196
|
-
} from "./chunk-DFFIZ25G.js";
|
|
186
|
+
import "./chunk-PB7G5MAM.js";
|
|
197
187
|
import "./chunk-3ASDTTEI.js";
|
|
198
188
|
import {
|
|
199
189
|
compactWhitespace
|
|
200
190
|
} from "./chunk-DWLEOOGR.js";
|
|
201
191
|
import {
|
|
202
192
|
checkStaleRun,
|
|
203
|
-
queryRunRecords,
|
|
204
193
|
readRunRecord
|
|
205
|
-
} from "./chunk-
|
|
194
|
+
} from "./chunk-RZNYL4LW.js";
|
|
206
195
|
import {
|
|
207
196
|
clipText,
|
|
208
197
|
formatDuration,
|
|
@@ -213,17 +202,21 @@ import {
|
|
|
213
202
|
resolveRunLabel,
|
|
214
203
|
runShowsLogTail,
|
|
215
204
|
shortRunId
|
|
216
|
-
} from "./chunk-
|
|
217
|
-
import "./chunk-
|
|
218
|
-
import "./chunk-ATNTHIZI.js";
|
|
205
|
+
} from "./chunk-KXKQO4Q6.js";
|
|
206
|
+
import "./chunk-CMKUBIGW.js";
|
|
219
207
|
import "./chunk-JBTJAPUF.js";
|
|
208
|
+
import "./chunk-ATNTHIZI.js";
|
|
209
|
+
import "./chunk-LM6IYQ3F.js";
|
|
210
|
+
import {
|
|
211
|
+
toErrorMessage
|
|
212
|
+
} from "./chunk-HNMXYYJR.js";
|
|
220
213
|
import {
|
|
221
214
|
runSelfUpdate
|
|
222
|
-
} from "./chunk-
|
|
215
|
+
} from "./chunk-35RYGII3.js";
|
|
223
216
|
import {
|
|
224
217
|
saveProfileAgentSelection,
|
|
225
218
|
saveProfileLocale
|
|
226
|
-
} from "./chunk-
|
|
219
|
+
} from "./chunk-DXJS7VSG.js";
|
|
227
220
|
import {
|
|
228
221
|
readPipeText,
|
|
229
222
|
spawnProcess
|
|
@@ -237,27 +230,31 @@ import {
|
|
|
237
230
|
import {
|
|
238
231
|
DEFAULT_NOLO_SERVER_URL
|
|
239
232
|
} from "./chunk-OLZBQWZU.js";
|
|
240
|
-
import "./chunk-
|
|
241
|
-
import "./chunk-
|
|
242
|
-
import "./chunk-
|
|
243
|
-
import "./chunk-
|
|
233
|
+
import "./chunk-4ULSC37S.js";
|
|
234
|
+
import "./chunk-2IPEVBUO.js";
|
|
235
|
+
import "./chunk-JMSCXQUG.js";
|
|
236
|
+
import "./chunk-S6KVFOUG.js";
|
|
244
237
|
import "./chunk-Y5GCAMGP.js";
|
|
238
|
+
import "./chunk-UZ6XXCVR.js";
|
|
245
239
|
import "./chunk-KX6YBIHG.js";
|
|
246
|
-
import "./chunk-
|
|
247
|
-
import "./chunk-
|
|
240
|
+
import "./chunk-OXLLFZNF.js";
|
|
241
|
+
import "./chunk-FON47ACC.js";
|
|
242
|
+
import "./chunk-NRY4GCKJ.js";
|
|
248
243
|
import "./chunk-WWC7I6TA.js";
|
|
249
244
|
import "./chunk-SKDNBYZK.js";
|
|
250
245
|
import "./chunk-I42VC5KR.js";
|
|
251
246
|
import {
|
|
252
247
|
asTrimmedLowercaseString
|
|
253
248
|
} from "./chunk-QSJ3HFEF.js";
|
|
254
|
-
import "./chunk-
|
|
255
|
-
import "./chunk-3ND52WIL.js";
|
|
249
|
+
import "./chunk-ATWUOTJP.js";
|
|
256
250
|
import "./chunk-XMLRJUU5.js";
|
|
257
251
|
import "./chunk-R5V5G73M.js";
|
|
258
252
|
import "./chunk-GBRG75BQ.js";
|
|
259
253
|
import "./chunk-3EUW3WEO.js";
|
|
260
254
|
import "./chunk-U6VC4MU4.js";
|
|
255
|
+
import {
|
|
256
|
+
extractCustomId
|
|
257
|
+
} from "./chunk-SLOGKB7M.js";
|
|
261
258
|
import "./chunk-KUG52IAP.js";
|
|
262
259
|
import "./chunk-LCBAMY2M.js";
|
|
263
260
|
import "./chunk-4SN6J65J.js";
|
|
@@ -526,6 +523,7 @@ async function compactDialog(options) {
|
|
|
526
523
|
dialogKey
|
|
527
524
|
);
|
|
528
525
|
let summaryGenerated = false;
|
|
526
|
+
let compactedMessageCount = 0;
|
|
529
527
|
if (options.summaryLlmCaller) {
|
|
530
528
|
const allMsgs = await readDialogMessages(
|
|
531
529
|
fetchImpl,
|
|
@@ -580,6 +578,7 @@ async function compactDialog(options) {
|
|
|
580
578
|
current.compressionCount = compressionCount + 1;
|
|
581
579
|
current.referenceKeys = Array.from(extractedKeys);
|
|
582
580
|
summaryGenerated = true;
|
|
581
|
+
compactedMessageCount = plan.compressCount;
|
|
583
582
|
console.log(
|
|
584
583
|
`[nolo] compact: compressed ${plan.compressCount} messages into summary (len: ${newSummary.trim().length})`
|
|
585
584
|
);
|
|
@@ -602,7 +601,8 @@ async function compactDialog(options) {
|
|
|
602
601
|
dialogId: extractCustomId(next.dbKey),
|
|
603
602
|
dialogKey: next.dbKey,
|
|
604
603
|
spaceId: typeof next.spaceId === "string" ? next.spaceId : void 0,
|
|
605
|
-
summaryGenerated
|
|
604
|
+
summaryGenerated,
|
|
605
|
+
compactedMessageCount
|
|
606
606
|
};
|
|
607
607
|
}
|
|
608
608
|
|
|
@@ -612,7 +612,7 @@ var DIALOG_CHECKED = "\u25C9";
|
|
|
612
612
|
var DIALOG_UNCHECKED = "\u25CB";
|
|
613
613
|
function renderDialogTitle(title, colorEnabled = resolveCliColorEnabled()) {
|
|
614
614
|
if (!colorEnabled) return title;
|
|
615
|
-
return
|
|
615
|
+
return `${themeColorSequence("accent")}${title}\x1B[0m`;
|
|
616
616
|
}
|
|
617
617
|
function renderDialogRow(args, colorEnabled = resolveCliColorEnabled()) {
|
|
618
618
|
const marker = args.focused ? DIALOG_CURSOR : " ";
|
|
@@ -620,7 +620,7 @@ function renderDialogRow(args, colorEnabled = resolveCliColorEnabled()) {
|
|
|
620
620
|
const detail = args.detail ? ` ${themeText(args.detail, "muted", colorEnabled)}` : "";
|
|
621
621
|
const row = `${marker} ${checkbox}${args.label}${detail}`;
|
|
622
622
|
if (!args.focused || !colorEnabled) return row;
|
|
623
|
-
return `${surfaceBackgroundSequence()}${themeColorSequence("accent")}
|
|
623
|
+
return `${surfaceBackgroundSequence()}${themeColorSequence("accent")}${row}\x1B[0m`;
|
|
624
624
|
}
|
|
625
625
|
function renderDialogOverflow(text, colorEnabled = resolveCliColorEnabled()) {
|
|
626
626
|
return themeText(` ${text}`, "chrome", colorEnabled);
|
|
@@ -1328,7 +1328,7 @@ function renderTabBar(questions, activeIndex, colorEnabled) {
|
|
|
1328
1328
|
const tabs = questions.map((q, i) => {
|
|
1329
1329
|
const label = `Q${i + 1}`;
|
|
1330
1330
|
if (i === activeIndex) {
|
|
1331
|
-
return colorEnabled ? `${themeColorSequence("accent")}
|
|
1331
|
+
return colorEnabled ? `${themeColorSequence("accent")} ${label} \x1B[0m` : `[${label}]`;
|
|
1332
1332
|
}
|
|
1333
1333
|
return colorEnabled ? themeText(` ${label} `, "muted", colorEnabled) : ` ${label} `;
|
|
1334
1334
|
});
|
|
@@ -1395,7 +1395,7 @@ function renderAskChoiceFrame(state) {
|
|
|
1395
1395
|
const plainRow = `${plainPrefix}${qs.otherText}`;
|
|
1396
1396
|
if (focused && colorEnabled) {
|
|
1397
1397
|
lines.push(
|
|
1398
|
-
|
|
1398
|
+
`${themeColorSequence("accent")}${plainRow}\x1B[0m`
|
|
1399
1399
|
);
|
|
1400
1400
|
} else {
|
|
1401
1401
|
lines.push(plainRow);
|
|
@@ -2159,6 +2159,7 @@ function createRunRegistryPoller(deps) {
|
|
|
2159
2159
|
return;
|
|
2160
2160
|
}
|
|
2161
2161
|
const alive = /* @__PURE__ */ new Set();
|
|
2162
|
+
const polled = [];
|
|
2162
2163
|
for (const run of active) {
|
|
2163
2164
|
alive.add(run.runId);
|
|
2164
2165
|
let record;
|
|
@@ -2172,6 +2173,7 @@ function createRunRegistryPoller(deps) {
|
|
|
2172
2173
|
continue;
|
|
2173
2174
|
}
|
|
2174
2175
|
if (!record) continue;
|
|
2176
|
+
polled.push(record);
|
|
2175
2177
|
const snapshot = snapshotFromRunRecord(record, at);
|
|
2176
2178
|
const mark = fingerprint(snapshot);
|
|
2177
2179
|
if (lastEmitted.get(run.runId) === mark) continue;
|
|
@@ -2184,6 +2186,12 @@ function createRunRegistryPoller(deps) {
|
|
|
2184
2186
|
for (const runId of [...lastReconciledAt.keys()]) {
|
|
2185
2187
|
if (!alive.has(runId)) lastReconciledAt.delete(runId);
|
|
2186
2188
|
}
|
|
2189
|
+
if (polled.length > 0 && deps.onRecordsPolled) {
|
|
2190
|
+
try {
|
|
2191
|
+
deps.onRecordsPolled(polled);
|
|
2192
|
+
} catch {
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2187
2195
|
};
|
|
2188
2196
|
return {
|
|
2189
2197
|
ensureRunning() {
|
|
@@ -2199,6 +2207,163 @@ function createRunRegistryPoller(deps) {
|
|
|
2199
2207
|
};
|
|
2200
2208
|
}
|
|
2201
2209
|
|
|
2210
|
+
// packages/core/chat/internalTurnEvent.ts
|
|
2211
|
+
function normalizeRunCompletionShape(record) {
|
|
2212
|
+
const runId = String(record.runId ?? record.id ?? "");
|
|
2213
|
+
const agentKey = String(record.agentKey ?? record.agent ?? "");
|
|
2214
|
+
const status = String(record.status ?? "done");
|
|
2215
|
+
const counters = record.activity?.counters;
|
|
2216
|
+
return {
|
|
2217
|
+
runId,
|
|
2218
|
+
agentKey,
|
|
2219
|
+
...typeof record.agentName === "string" ? { agentName: record.agentName } : {},
|
|
2220
|
+
status,
|
|
2221
|
+
...typeof record.exitCode === "number" ? { exitCode: record.exitCode } : {},
|
|
2222
|
+
...typeof record.parentDialogId === "string" ? { parentDialogId: record.parentDialogId } : {},
|
|
2223
|
+
...typeof record.dialogId === "string" ? { dialogId: record.dialogId } : {},
|
|
2224
|
+
...typeof record.ephemeral === "boolean" ? { ephemeral: record.ephemeral } : {},
|
|
2225
|
+
...record.startedAt !== void 0 ? { startedAt: record.startedAt } : {},
|
|
2226
|
+
...record.endedAt !== void 0 ? { endedAt: record.endedAt } : {},
|
|
2227
|
+
...typeof record.note === "string" ? { note: record.note } : {},
|
|
2228
|
+
...typeof record.error === "string" ? { error: record.error } : {},
|
|
2229
|
+
...typeof record.ack === "boolean" ? { ack: record.ack } : {},
|
|
2230
|
+
...counters ? {
|
|
2231
|
+
activity: {
|
|
2232
|
+
counters: {
|
|
2233
|
+
toolCalls: typeof counters.toolCalls === "number" ? counters.toolCalls : 0,
|
|
2234
|
+
llmCalls: typeof counters.llmCalls === "number" ? counters.llmCalls : 0,
|
|
2235
|
+
fileEdits: typeof counters.fileEdits === "number" ? counters.fileEdits : 0
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
} : {}
|
|
2239
|
+
};
|
|
2240
|
+
}
|
|
2241
|
+
function createTurnRequest(input) {
|
|
2242
|
+
if (typeof input === "string") {
|
|
2243
|
+
return {
|
|
2244
|
+
event: { kind: "user", text: input },
|
|
2245
|
+
text: input
|
|
2246
|
+
};
|
|
2247
|
+
}
|
|
2248
|
+
if ("event" in input && typeof input.event === "object" && typeof input.text === "string") {
|
|
2249
|
+
return input;
|
|
2250
|
+
}
|
|
2251
|
+
const event = input;
|
|
2252
|
+
return {
|
|
2253
|
+
event,
|
|
2254
|
+
text: event.text
|
|
2255
|
+
};
|
|
2256
|
+
}
|
|
2257
|
+
|
|
2258
|
+
// packages/cli/tui/runCompletionWatcher.ts
|
|
2259
|
+
var WAKE_NOTE_MAX_CHARS = 300;
|
|
2260
|
+
function createRunCompletionWatcher(deps) {
|
|
2261
|
+
const now = deps.now ?? (() => Date.now());
|
|
2262
|
+
const createdAt = now();
|
|
2263
|
+
const lastStatusByRunId = /* @__PURE__ */ new Map();
|
|
2264
|
+
const notifiedRunIds = /* @__PURE__ */ new Set();
|
|
2265
|
+
const describeRun = (record) => {
|
|
2266
|
+
const lines = [
|
|
2267
|
+
`runId: ${record.runId}`,
|
|
2268
|
+
`agent: ${resolveRunLabel(record)}`,
|
|
2269
|
+
`status: ${record.status}`
|
|
2270
|
+
];
|
|
2271
|
+
if (typeof record.exitCode === "number") {
|
|
2272
|
+
lines.push(`exitCode: ${record.exitCode}`);
|
|
2273
|
+
}
|
|
2274
|
+
if (record.dialogId) {
|
|
2275
|
+
lines.push(`childDialogId: ${record.dialogId}`);
|
|
2276
|
+
} else if (record.ephemeral) {
|
|
2277
|
+
lines.push(`ephemeral: true (no persisted child dialog)`);
|
|
2278
|
+
} else {
|
|
2279
|
+
lines.push(`childDialogId: missing (result unpersisted or ephemeral)`);
|
|
2280
|
+
}
|
|
2281
|
+
const duration = formatRunAge(
|
|
2282
|
+
{
|
|
2283
|
+
startedAt: readTimestamp(record.startedAt),
|
|
2284
|
+
finishedAt: readTimestamp(record.endedAt ?? record.finishedAt)
|
|
2285
|
+
},
|
|
2286
|
+
now()
|
|
2287
|
+
);
|
|
2288
|
+
if (duration) lines.push(`duration: ${duration}`);
|
|
2289
|
+
const recordError = "error" in record && typeof record.error === "string" ? record.error : void 0;
|
|
2290
|
+
const note = typeof record.note === "string" ? clipText(record.note, WAKE_NOTE_MAX_CHARS) : typeof recordError === "string" ? clipText(recordError, WAKE_NOTE_MAX_CHARS) : "";
|
|
2291
|
+
if (note) lines.push(`note: ${note}`);
|
|
2292
|
+
const counters = record.activity?.counters;
|
|
2293
|
+
if (counters && typeof counters.toolCalls === "number" && typeof counters.llmCalls === "number" && typeof counters.fileEdits === "number") {
|
|
2294
|
+
lines.push(
|
|
2295
|
+
`activity: ${counters.toolCalls} tool calls \xB7 ${counters.llmCalls} llm calls \xB7 ${counters.fileEdits} edits`
|
|
2296
|
+
);
|
|
2297
|
+
}
|
|
2298
|
+
return lines;
|
|
2299
|
+
};
|
|
2300
|
+
const buildWakeMessage = (finished) => {
|
|
2301
|
+
const lines = [
|
|
2302
|
+
`\u3010\u540E\u53F0 run \u7EC8\u6001\u901A\u77E5\u3011\u4F60\u6D3E\u51FA\u7684 ${finished.length} \u6761\u540E\u53F0 run \u5DF2\u5230\u8FBE\u7EC8\u6001\uFF1A`
|
|
2303
|
+
];
|
|
2304
|
+
for (const record of finished) {
|
|
2305
|
+
lines.push("", ...describeRun(record));
|
|
2306
|
+
}
|
|
2307
|
+
lines.push(
|
|
2308
|
+
"",
|
|
2309
|
+
'\u4EE5\u4E0A\u662F\u4F60\u901A\u8FC7 startAgentRun \u6D3E\u51FA\u7684\u540E\u53F0 run \u7684\u7EC8\u6001\u901A\u77E5\uFF08\u7CFB\u7EDF\u5185\u90E8\u4E8B\u4EF6\uFF0C\u4E0D\u662F\u7528\u6237\u6D88\u606F\uFF09\u3002\u8BF7\u9605\u8BFB\u4E0A\u9762\u7684\u6458\u8981\u5E76\u81EA\u5DF1\u51B3\u5B9A\u4E0B\u4E00\u6B65\uFF1A\u6C47\u603B\u7ED3\u679C\u3001\u7EE7\u7EED\u540E\u7EED\u5DE5\u4F5C\u3001\u6216\u5411\u7528\u6237\u6C47\u62A5\u7ED3\u8BBA\u3002\u9700\u8981\u5B8C\u6574\u8F93\u51FA\u65F6\u7528 controlAgentRun(action:"status", runId, tailLines:30) \u62C9\u53D6\u5BF9\u5E94 run \u7684\u65E5\u5FD7\u3002'
|
|
2310
|
+
);
|
|
2311
|
+
return lines.join("\n");
|
|
2312
|
+
};
|
|
2313
|
+
return {
|
|
2314
|
+
observe(records) {
|
|
2315
|
+
const finished = [];
|
|
2316
|
+
const currentDialogId = deps.getCurrentDialogId();
|
|
2317
|
+
for (const rawRecord of records) {
|
|
2318
|
+
try {
|
|
2319
|
+
if (!rawRecord || typeof rawRecord.runId !== "string" || !rawRecord.runId) continue;
|
|
2320
|
+
const record = rawRecord;
|
|
2321
|
+
if (notifiedRunIds.has(record.runId)) continue;
|
|
2322
|
+
if (record.ack === true) {
|
|
2323
|
+
notifiedRunIds.add(record.runId);
|
|
2324
|
+
continue;
|
|
2325
|
+
}
|
|
2326
|
+
const status = record.status;
|
|
2327
|
+
if (typeof status !== "string") continue;
|
|
2328
|
+
if (record.parentDialogId !== currentDialogId) continue;
|
|
2329
|
+
const previous = lastStatusByRunId.get(record.runId);
|
|
2330
|
+
lastStatusByRunId.set(record.runId, status);
|
|
2331
|
+
if (!isAgentRunTerminalStatus(status)) continue;
|
|
2332
|
+
if (previous === void 0) {
|
|
2333
|
+
const startedMs = readTimestamp(record.startedAt);
|
|
2334
|
+
if (startedMs === void 0 || startedMs < createdAt) continue;
|
|
2335
|
+
} else if (isAgentRunTerminalStatus(previous)) {
|
|
2336
|
+
continue;
|
|
2337
|
+
}
|
|
2338
|
+
notifiedRunIds.add(record.runId);
|
|
2339
|
+
finished.push(record);
|
|
2340
|
+
} catch {
|
|
2341
|
+
continue;
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
if (finished.length === 0) return;
|
|
2345
|
+
const shapes = finished.map((r) => normalizeRunCompletionShape(r));
|
|
2346
|
+
const summaryText = buildWakeMessage(finished);
|
|
2347
|
+
const event = {
|
|
2348
|
+
kind: "child-run-completed",
|
|
2349
|
+
runs: shapes,
|
|
2350
|
+
text: summaryText
|
|
2351
|
+
};
|
|
2352
|
+
deps.onWake(event);
|
|
2353
|
+
},
|
|
2354
|
+
markAcknowledged(runId) {
|
|
2355
|
+
if (runId) notifiedRunIds.add(runId);
|
|
2356
|
+
},
|
|
2357
|
+
isAcknowledged(runId) {
|
|
2358
|
+
return Boolean(runId && notifiedRunIds.has(runId));
|
|
2359
|
+
},
|
|
2360
|
+
dispose() {
|
|
2361
|
+
lastStatusByRunId.clear();
|
|
2362
|
+
notifiedRunIds.clear();
|
|
2363
|
+
}
|
|
2364
|
+
};
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2202
2367
|
// packages/ai/agent/utils/sortUtils.ts
|
|
2203
2368
|
function sortAgentsFavoriteOwnedPublic(items) {
|
|
2204
2369
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -2245,7 +2410,7 @@ function sortAgentsFavoriteOwnedPublic(items) {
|
|
|
2245
2410
|
}
|
|
2246
2411
|
|
|
2247
2412
|
// packages/cli/tui/agentCatalog.ts
|
|
2248
|
-
var DEFAULT_TUI_AGENT_KEY =
|
|
2413
|
+
var DEFAULT_TUI_AGENT_KEY = NOLO_DEFAULT_AGENT_KEY;
|
|
2249
2414
|
function formatAgentSourceLabel(entry) {
|
|
2250
2415
|
if (entry.kind === "platform" || entry.apiSource === "platform") return t("agentSourcePlatform");
|
|
2251
2416
|
if (entry.apiSource === "cli") {
|
|
@@ -2300,7 +2465,7 @@ function listedAgentToCatalogEntry(agent) {
|
|
|
2300
2465
|
...agent.cliProvider ? { cliProvider: agent.cliProvider } : {}
|
|
2301
2466
|
};
|
|
2302
2467
|
}
|
|
2303
|
-
function mergeCatalogEntries(currentKey,
|
|
2468
|
+
function mergeCatalogEntries(currentKey, privateAgents, favoritedAtByKey = {}) {
|
|
2304
2469
|
const seen = /* @__PURE__ */ new Set();
|
|
2305
2470
|
const merged = [];
|
|
2306
2471
|
const push = (entry) => {
|
|
@@ -2309,12 +2474,9 @@ function mergeCatalogEntries(currentKey, platformAgents, privateAgents, favorite
|
|
|
2309
2474
|
const favoritedAt = favoritedAtByKey[entry.key];
|
|
2310
2475
|
merged.push(favoritedAt ? { ...entry, favoritedAt } : entry);
|
|
2311
2476
|
};
|
|
2312
|
-
const current =
|
|
2477
|
+
const current = privateAgents.find((entry) => entry.key === currentKey) ?? null;
|
|
2313
2478
|
if (current) push(current);
|
|
2314
|
-
|
|
2315
|
-
if (entry.key !== currentKey) push(entry);
|
|
2316
|
-
}
|
|
2317
|
-
const sortablePrivate = privateAgents.map((entry) => ({
|
|
2479
|
+
const sortablePrivate = privateAgents.filter((entry) => favoritedAtByKey[entry.key] !== void 0).map((entry) => ({
|
|
2318
2480
|
key: entry.key,
|
|
2319
2481
|
favoritedAt: favoritedAtByKey[entry.key],
|
|
2320
2482
|
isOwned: true,
|
|
@@ -2322,7 +2484,7 @@ function mergeCatalogEntries(currentKey, platformAgents, privateAgents, favorite
|
|
|
2322
2484
|
}));
|
|
2323
2485
|
const sortedKeys = sortAgentsFavoriteOwnedPublic(sortablePrivate);
|
|
2324
2486
|
const sortedKeyOrder = new Map(sortedKeys.map((item, i) => [item.key, i]));
|
|
2325
|
-
const sortedPrivate = [
|
|
2487
|
+
const sortedPrivate = privateAgents.filter((entry) => favoritedAtByKey[entry.key] !== void 0).sort(
|
|
2326
2488
|
(a, b) => (sortedKeyOrder.get(a.key) ?? 0) - (sortedKeyOrder.get(b.key) ?? 0)
|
|
2327
2489
|
);
|
|
2328
2490
|
for (const entry of sortedPrivate) {
|
|
@@ -2362,7 +2524,6 @@ async function loadAgentCatalog(args) {
|
|
|
2362
2524
|
}
|
|
2363
2525
|
const entries = mergeCatalogEntries(
|
|
2364
2526
|
args.currentKey,
|
|
2365
|
-
resolveCatalogPlatformAgents(env),
|
|
2366
2527
|
rawData.privateAgents,
|
|
2367
2528
|
rawData.favoritedAtByKey
|
|
2368
2529
|
);
|
|
@@ -2374,7 +2535,6 @@ function refreshAgentCatalogInBackground(args, env, cacheKey) {
|
|
|
2374
2535
|
agentCatalogRefreshInFlight = fetchRawCatalogData(args, env).then((rawData) => {
|
|
2375
2536
|
const entries = mergeCatalogEntries(
|
|
2376
2537
|
args.currentKey,
|
|
2377
|
-
resolveCatalogPlatformAgents(env),
|
|
2378
2538
|
rawData.privateAgents,
|
|
2379
2539
|
rawData.favoritedAtByKey
|
|
2380
2540
|
);
|
|
@@ -2384,9 +2544,15 @@ function refreshAgentCatalogInBackground(args, env, cacheKey) {
|
|
|
2384
2544
|
agentCatalogRefreshInFlight = null;
|
|
2385
2545
|
});
|
|
2386
2546
|
}
|
|
2547
|
+
async function prefillCatalogFromLocalDb(_args) {
|
|
2548
|
+
}
|
|
2387
2549
|
function prefetchAgentCatalog(args) {
|
|
2388
|
-
void
|
|
2389
|
-
|
|
2550
|
+
void (async () => {
|
|
2551
|
+
await prefillCatalogFromLocalDb({ env: args.env, getDb: args.getDb }).catch(() => {
|
|
2552
|
+
});
|
|
2553
|
+
void loadAgentCatalog({ ...args, currentKey: "" }).catch(() => {
|
|
2554
|
+
});
|
|
2555
|
+
})();
|
|
2390
2556
|
}
|
|
2391
2557
|
async function fetchRawCatalogData(args, env) {
|
|
2392
2558
|
const fetchImpl = args.fetchImpl ?? fetch;
|
|
@@ -2398,7 +2564,7 @@ async function fetchRawCatalogData(args, env) {
|
|
|
2398
2564
|
}
|
|
2399
2565
|
const serverUrl = resolveServerUrl(env);
|
|
2400
2566
|
const serverUrls = resolveServerCandidates([], env, serverUrl);
|
|
2401
|
-
let
|
|
2567
|
+
let listedAgents = [];
|
|
2402
2568
|
const favoritesPromise = listFavoriteAgentIdsAcrossServers({
|
|
2403
2569
|
authToken,
|
|
2404
2570
|
fetchImpl,
|
|
@@ -2412,15 +2578,14 @@ async function fetchRawCatalogData(args, env) {
|
|
|
2412
2578
|
serverUrls,
|
|
2413
2579
|
userId
|
|
2414
2580
|
});
|
|
2415
|
-
|
|
2581
|
+
listedAgents = remoteResult.agents;
|
|
2416
2582
|
} catch {
|
|
2417
2583
|
try {
|
|
2418
2584
|
const db = await getReadableCliDb({ write: () => {
|
|
2419
2585
|
} });
|
|
2420
|
-
|
|
2421
|
-
privateAgents = cached.map(listedAgentToCatalogEntry);
|
|
2586
|
+
listedAgents = await listLocalCachedAgents({ db, userId });
|
|
2422
2587
|
} catch {
|
|
2423
|
-
|
|
2588
|
+
listedAgents = await listRemoteAgents({
|
|
2424
2589
|
authToken,
|
|
2425
2590
|
fallbackFetchImpl,
|
|
2426
2591
|
fetchImpl,
|
|
@@ -2428,10 +2593,47 @@ async function fetchRawCatalogData(args, env) {
|
|
|
2428
2593
|
userId,
|
|
2429
2594
|
queryUserRecords,
|
|
2430
2595
|
readDbRecord
|
|
2431
|
-
})
|
|
2596
|
+
});
|
|
2432
2597
|
}
|
|
2433
2598
|
}
|
|
2599
|
+
const privateAgents = listedAgents.map(listedAgentToCatalogEntry);
|
|
2434
2600
|
const favoritedAtByKey = await favoritesPromise;
|
|
2601
|
+
for (const agent of listedAgents) {
|
|
2602
|
+
const favoritedAt = [agent.privateKey, agent.publicKey, agent.id].map((key) => favoritedAtByKey[key]).find((value) => value !== void 0);
|
|
2603
|
+
if (favoritedAt !== void 0) favoritedAtByKey[agent.privateKey] = favoritedAt;
|
|
2604
|
+
}
|
|
2605
|
+
const existingKeys = /* @__PURE__ */ new Set();
|
|
2606
|
+
for (const agent of listedAgents) {
|
|
2607
|
+
existingKeys.add(agent.privateKey);
|
|
2608
|
+
existingKeys.add(agent.publicKey);
|
|
2609
|
+
existingKeys.add(agent.id);
|
|
2610
|
+
}
|
|
2611
|
+
await Promise.all(
|
|
2612
|
+
Object.keys(favoritedAtByKey).map(async (favKey) => {
|
|
2613
|
+
if (existingKeys.has(favKey)) return;
|
|
2614
|
+
try {
|
|
2615
|
+
const favRead = await readLiveDbRecordAfterTombstoneMerge({
|
|
2616
|
+
authToken,
|
|
2617
|
+
dbKey: favKey,
|
|
2618
|
+
fallbackFetchImpl,
|
|
2619
|
+
fetchImpl,
|
|
2620
|
+
serverUrls
|
|
2621
|
+
});
|
|
2622
|
+
const record = favRead.record;
|
|
2623
|
+
if (!record || record.type && record.type !== "agent") return;
|
|
2624
|
+
const norm = normalizeListedAgent(record);
|
|
2625
|
+
if (!norm) return;
|
|
2626
|
+
if (existingKeys.has(norm.privateKey) || existingKeys.has(norm.publicKey) || existingKeys.has(norm.id)) {
|
|
2627
|
+
return;
|
|
2628
|
+
}
|
|
2629
|
+
existingKeys.add(norm.privateKey);
|
|
2630
|
+
existingKeys.add(norm.publicKey);
|
|
2631
|
+
existingKeys.add(norm.id);
|
|
2632
|
+
privateAgents.push(listedAgentToCatalogEntry(norm));
|
|
2633
|
+
} catch {
|
|
2634
|
+
}
|
|
2635
|
+
})
|
|
2636
|
+
);
|
|
2435
2637
|
return { privateAgents, favoritedAtByKey };
|
|
2436
2638
|
}
|
|
2437
2639
|
function renderAgentCatalogList(entries, currentKey) {
|
|
@@ -3096,7 +3298,7 @@ function renderWelcome(state, frame = 0, maxFrames = 0, columns) {
|
|
|
3096
3298
|
const widestSceneCol = sceneArt.split("\n").reduce((max, line) => Math.max(max, displayWidth(stripAnsi(line))), 0);
|
|
3097
3299
|
if (columns < widestSceneCol) sceneArt = "";
|
|
3098
3300
|
}
|
|
3099
|
-
const versionLine = colorEnabled ?
|
|
3301
|
+
const versionLine = colorEnabled ? `${themeColorSequence("accent")}nolo\x1B[0m ${state.cliVersion ?? ""} | server ${state.serverUrl}`.replace(" |", " |") : `nolo ${state.cliVersion ?? ""} | server ${state.serverUrl}`.replace(" |", " |");
|
|
3100
3302
|
const body = sceneArt ? [sceneArt, versionLine, t("welcomeHint"), ""] : [versionLine, t("welcomeHint"), ""];
|
|
3101
3303
|
return body.join("\n");
|
|
3102
3304
|
}
|
|
@@ -3760,7 +3962,16 @@ function handleTuiInput(input, state) {
|
|
|
3760
3962
|
};
|
|
3761
3963
|
}
|
|
3762
3964
|
return {
|
|
3763
|
-
nextState:
|
|
3965
|
+
nextState: {
|
|
3966
|
+
...state,
|
|
3967
|
+
dialogId: void 0,
|
|
3968
|
+
dialogKey: void 0,
|
|
3969
|
+
dialogLabel: t("newDialog"),
|
|
3970
|
+
attachedDocs: [],
|
|
3971
|
+
attachedSkills: [],
|
|
3972
|
+
attachedImages: [],
|
|
3973
|
+
turnTokens: void 0
|
|
3974
|
+
},
|
|
3764
3975
|
output: t("clearingDialog"),
|
|
3765
3976
|
action: { type: "clear", dialogId: state.dialogId }
|
|
3766
3977
|
};
|
|
@@ -4127,52 +4338,65 @@ var initialChatQueueState = {
|
|
|
4127
4338
|
function reduceChatQueue(state, event) {
|
|
4128
4339
|
switch (event.type) {
|
|
4129
4340
|
case "turn-start":
|
|
4130
|
-
if (state.running) return state;
|
|
4131
|
-
return {
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
running: false,
|
|
4138
|
-
queue: [],
|
|
4139
|
-
lastDrainError: null
|
|
4140
|
-
};
|
|
4141
|
-
}
|
|
4341
|
+
if (state.running && state.lastDrainError === null) return state;
|
|
4342
|
+
return {
|
|
4343
|
+
...state,
|
|
4344
|
+
running: true,
|
|
4345
|
+
lastDrainError: null
|
|
4346
|
+
};
|
|
4347
|
+
case "turn-end":
|
|
4142
4348
|
return {
|
|
4143
4349
|
...state,
|
|
4144
4350
|
running: false,
|
|
4145
|
-
|
|
4351
|
+
queue: event.aborted ? [] : state.queue,
|
|
4352
|
+
lastDrainError: !event.ok && !event.aborted ? "previous turn failed" : state.lastDrainError
|
|
4146
4353
|
};
|
|
4147
|
-
}
|
|
4148
4354
|
case "enqueue": {
|
|
4149
|
-
const
|
|
4150
|
-
if (!text)
|
|
4151
|
-
|
|
4355
|
+
const req = createTurnRequest(event.text);
|
|
4356
|
+
if (!req.text.trim() && req.event.kind === "user") {
|
|
4357
|
+
return state;
|
|
4358
|
+
}
|
|
4359
|
+
return {
|
|
4360
|
+
...state,
|
|
4361
|
+
queue: [...state.queue, req]
|
|
4362
|
+
};
|
|
4152
4363
|
}
|
|
4153
|
-
case "dequeue":
|
|
4364
|
+
case "dequeue":
|
|
4154
4365
|
if (state.queue.length === 0) return state;
|
|
4155
|
-
return {
|
|
4156
|
-
|
|
4366
|
+
return {
|
|
4367
|
+
...state,
|
|
4368
|
+
queue: state.queue.slice(1)
|
|
4369
|
+
};
|
|
4157
4370
|
case "clear":
|
|
4158
|
-
if (state.queue.length === 0 &&
|
|
4159
|
-
return {
|
|
4371
|
+
if (state.queue.length === 0 && state.lastDrainError === null) return state;
|
|
4372
|
+
return {
|
|
4373
|
+
...state,
|
|
4374
|
+
queue: [],
|
|
4375
|
+
lastDrainError: null
|
|
4376
|
+
};
|
|
4160
4377
|
case "pause-drain":
|
|
4161
4378
|
if (state.drainPaused) return state;
|
|
4162
|
-
return {
|
|
4379
|
+
return {
|
|
4380
|
+
...state,
|
|
4381
|
+
drainPaused: true
|
|
4382
|
+
};
|
|
4163
4383
|
case "resume-drain":
|
|
4164
4384
|
if (!state.drainPaused) return state;
|
|
4165
|
-
return {
|
|
4385
|
+
return {
|
|
4386
|
+
...state,
|
|
4387
|
+
drainPaused: false
|
|
4388
|
+
};
|
|
4166
4389
|
case "drain-error":
|
|
4167
|
-
return {
|
|
4168
|
-
|
|
4169
|
-
|
|
4390
|
+
return {
|
|
4391
|
+
...state,
|
|
4392
|
+
lastDrainError: event.message || null
|
|
4393
|
+
};
|
|
4394
|
+
default:
|
|
4170
4395
|
return state;
|
|
4171
|
-
}
|
|
4172
4396
|
}
|
|
4173
4397
|
}
|
|
4174
|
-
function shouldDrainAfterTurnEnd(state,
|
|
4175
|
-
return !state.running && !state.drainPaused && state.queue.length > 0
|
|
4398
|
+
function shouldDrainAfterTurnEnd(state, cleanTurnEnd) {
|
|
4399
|
+
return cleanTurnEnd && !state.running && !state.drainPaused && state.queue.length > 0;
|
|
4176
4400
|
}
|
|
4177
4401
|
function applyChatQueueEvent(state, event) {
|
|
4178
4402
|
const prevQueueLen = state.queue.length;
|
|
@@ -4191,7 +4415,8 @@ function applyChatQueueEvent(state, event) {
|
|
|
4191
4415
|
}
|
|
4192
4416
|
if (event.type === "turn-end" && !event.aborted && event.ok) {
|
|
4193
4417
|
if (shouldDrainAfterTurnEnd(next, true)) {
|
|
4194
|
-
|
|
4418
|
+
const head = next.queue[0];
|
|
4419
|
+
outgoing.push({ type: "drain-ready", text: head.text, request: head });
|
|
4195
4420
|
}
|
|
4196
4421
|
}
|
|
4197
4422
|
return { state: next, outgoing };
|
|
@@ -4273,7 +4498,8 @@ function projectChatQueueStatus({
|
|
|
4273
4498
|
}) {
|
|
4274
4499
|
const preview = [];
|
|
4275
4500
|
for (let i = 0; i < Math.min(maxPreview, state.queue.length); i++) {
|
|
4276
|
-
const
|
|
4501
|
+
const item = state.queue[i];
|
|
4502
|
+
const text = typeof item === "string" ? item : item?.text ?? "";
|
|
4277
4503
|
preview.push(text.length > previewCharLimit ? text.slice(0, previewCharLimit) + "\u2026" : text);
|
|
4278
4504
|
}
|
|
4279
4505
|
let composerPlaceholderKey = "default";
|
|
@@ -4312,10 +4538,19 @@ function createChatQueueTuiBinding(runTurn) {
|
|
|
4312
4538
|
isCompactDialogSlashCommand: (s) => s === "/compact"
|
|
4313
4539
|
});
|
|
4314
4540
|
};
|
|
4315
|
-
const enqueue = (
|
|
4316
|
-
runtime.send({ type: "enqueue", text });
|
|
4541
|
+
const enqueue = (input) => {
|
|
4542
|
+
runtime.send({ type: "enqueue", text: input });
|
|
4317
4543
|
return projectChatQueueStatus({ state: runtime.getState() });
|
|
4318
4544
|
};
|
|
4545
|
+
const enqueueAndMaybeRun = async (input) => {
|
|
4546
|
+
enqueue(input);
|
|
4547
|
+
const status = runtime.getState();
|
|
4548
|
+
if (!status.running && !status.drainPaused) {
|
|
4549
|
+
await notifyTurnEnd({ ok: true, aborted: false });
|
|
4550
|
+
return true;
|
|
4551
|
+
}
|
|
4552
|
+
return false;
|
|
4553
|
+
};
|
|
4319
4554
|
const notifyTurnStart = () => {
|
|
4320
4555
|
runtime.send({ type: "turn-start" });
|
|
4321
4556
|
};
|
|
@@ -4338,23 +4573,22 @@ function createChatQueueTuiBinding(runTurn) {
|
|
|
4338
4573
|
while (true) {
|
|
4339
4574
|
const status = runtime.getState();
|
|
4340
4575
|
if (!status.running && !status.drainPaused && status.queue.length > 0 && lastOk) {
|
|
4341
|
-
const
|
|
4576
|
+
const req = status.queue[0];
|
|
4342
4577
|
runtime.send({ type: "turn-start" });
|
|
4343
4578
|
runtime.send({ type: "dequeue" });
|
|
4344
4579
|
let turnOutcome;
|
|
4345
4580
|
try {
|
|
4346
|
-
turnOutcome = await runTurn(
|
|
4581
|
+
turnOutcome = await runTurn(req);
|
|
4347
4582
|
} catch {
|
|
4348
4583
|
turnOutcome = { ok: false, aborted: false };
|
|
4349
4584
|
}
|
|
4350
|
-
const
|
|
4351
|
-
|
|
4352
|
-
|
|
4585
|
+
const consumed = consumePreempt(turnOutcome);
|
|
4586
|
+
const effectiveTurnOutcome = consumed.outcome;
|
|
4587
|
+
runtime.send({ type: "turn-end", ...effectiveTurnOutcome });
|
|
4588
|
+
if (consumed.mode === "stop") {
|
|
4353
4589
|
runtime.send({ type: "drain-error", message: "" });
|
|
4354
4590
|
}
|
|
4355
|
-
lastOk =
|
|
4356
|
-
if (cascadeOutcome.aborted) break;
|
|
4357
|
-
if (!lastOk) break;
|
|
4591
|
+
lastOk = effectiveTurnOutcome.ok && !effectiveTurnOutcome.aborted;
|
|
4358
4592
|
} else {
|
|
4359
4593
|
break;
|
|
4360
4594
|
}
|
|
@@ -4362,11 +4596,11 @@ function createChatQueueTuiBinding(runTurn) {
|
|
|
4362
4596
|
};
|
|
4363
4597
|
const drainHeadForManualTurn = () => {
|
|
4364
4598
|
const status = runtime.getState();
|
|
4365
|
-
if (status.running || status.
|
|
4366
|
-
const
|
|
4599
|
+
if (status.running || status.queue.length === 0) return null;
|
|
4600
|
+
const head = status.queue[0];
|
|
4367
4601
|
runtime.send({ type: "turn-start" });
|
|
4368
4602
|
runtime.send({ type: "dequeue" });
|
|
4369
|
-
return
|
|
4603
|
+
return head;
|
|
4370
4604
|
};
|
|
4371
4605
|
const preemptForDrain = () => {
|
|
4372
4606
|
const status = runtime.getState();
|
|
@@ -4383,7 +4617,7 @@ function createChatQueueTuiBinding(runTurn) {
|
|
|
4383
4617
|
const snapshotAndClearQueue = () => {
|
|
4384
4618
|
const status = runtime.getState();
|
|
4385
4619
|
if (status.queue.length === 0) return null;
|
|
4386
|
-
const merged = status.queue.join("\n");
|
|
4620
|
+
const merged = status.queue.map((req) => req.text).join("\n");
|
|
4387
4621
|
runtime.send({ type: "clear" });
|
|
4388
4622
|
return merged;
|
|
4389
4623
|
};
|
|
@@ -4398,6 +4632,7 @@ function createChatQueueTuiBinding(runTurn) {
|
|
|
4398
4632
|
return {
|
|
4399
4633
|
resolveSubmit,
|
|
4400
4634
|
enqueue,
|
|
4635
|
+
enqueueAndMaybeRun,
|
|
4401
4636
|
notifyTurnStart,
|
|
4402
4637
|
notifyTurnEnd,
|
|
4403
4638
|
drainHeadForManualTurn,
|
|
@@ -4411,9 +4646,22 @@ function createChatQueueTuiBinding(runTurn) {
|
|
|
4411
4646
|
};
|
|
4412
4647
|
}
|
|
4413
4648
|
|
|
4649
|
+
// packages/cli/tui/terminalNotification.ts
|
|
4650
|
+
function shouldEmitTerminalBell(decision) {
|
|
4651
|
+
return !decision.wasAborted && !decision.streamInterrupted && decision.exitCode === 0 && decision.interactive;
|
|
4652
|
+
}
|
|
4653
|
+
function emitTerminalBell(output) {
|
|
4654
|
+
try {
|
|
4655
|
+
output.write("\x07");
|
|
4656
|
+
} catch {
|
|
4657
|
+
}
|
|
4658
|
+
}
|
|
4659
|
+
|
|
4414
4660
|
// packages/cli/tui/tuiHistory.ts
|
|
4415
4661
|
var MAX_TUI_HISTORY_TURNS = 500;
|
|
4416
4662
|
var turnLineCache = /* @__PURE__ */ new WeakMap();
|
|
4663
|
+
var turnLineCountCache = /* @__PURE__ */ new WeakMap();
|
|
4664
|
+
var renderCacheMissCount = 0;
|
|
4417
4665
|
function createTurnHistory() {
|
|
4418
4666
|
return {
|
|
4419
4667
|
turns: [],
|
|
@@ -4432,6 +4680,7 @@ function startTurn(history, role) {
|
|
|
4432
4680
|
}
|
|
4433
4681
|
history.currentRole = role;
|
|
4434
4682
|
history.currentContent = "";
|
|
4683
|
+
resetStreamingTurnCache();
|
|
4435
4684
|
}
|
|
4436
4685
|
function appendToCurrentTurn(history, chunk) {
|
|
4437
4686
|
history.currentContent += chunk;
|
|
@@ -4444,6 +4693,7 @@ function finalizeCurrentTurn(history) {
|
|
|
4444
4693
|
});
|
|
4445
4694
|
history.currentRole = null;
|
|
4446
4695
|
history.currentContent = "";
|
|
4696
|
+
resetStreamingTurnCache();
|
|
4447
4697
|
if (history.turns.length > MAX_TUI_HISTORY_TURNS) {
|
|
4448
4698
|
history.turns = history.turns.slice(history.turns.length - MAX_TUI_HISTORY_TURNS);
|
|
4449
4699
|
}
|
|
@@ -4467,23 +4717,33 @@ function styleAssistantTurn(content, colorEnabled) {
|
|
|
4467
4717
|
});
|
|
4468
4718
|
return styledLines.join("\n");
|
|
4469
4719
|
}
|
|
4720
|
+
function fillUserBubbleRow(row, surfaceSeq, contentWidth) {
|
|
4721
|
+
const visible = visibleWidth(row);
|
|
4722
|
+
if (visible > contentWidth) {
|
|
4723
|
+
const truncated = truncateAnsi(row, contentWidth);
|
|
4724
|
+
const padAfter = Math.max(0, contentWidth - visibleWidth(truncated));
|
|
4725
|
+
return `${surfaceSeq}${truncated}${" ".repeat(padAfter)}\x1B[0m`;
|
|
4726
|
+
}
|
|
4727
|
+
return renderSurfaceLine({ text: row, surface: surfaceSeq, padTo: contentWidth });
|
|
4728
|
+
}
|
|
4470
4729
|
function renderTurnBlock(role, content, contentWidth, colorEnabled) {
|
|
4730
|
+
content = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4471
4731
|
const lines = [];
|
|
4472
4732
|
if (role === "user") {
|
|
4473
4733
|
const logicalLines = content.split("\n");
|
|
4474
4734
|
const accentSeq = colorEnabled ? themeColorSequence("accent") : "";
|
|
4475
|
-
const
|
|
4735
|
+
const firstPrefix = colorEnabled ? `${accentSeq}\x1B[1m\u2503 ` : "\u2503 ";
|
|
4736
|
+
const multilinePrefix = colorEnabled ? `${accentSeq}\x1B[1m\u2503 ` : "\u2503 ";
|
|
4737
|
+
const hangingIndent = colorEnabled ? `${accentSeq}\x1B[1m\u2503 ` : "\u2503 ";
|
|
4738
|
+
const surfaceSeq = colorEnabled ? userSurfaceBackgroundSequence() : "";
|
|
4476
4739
|
for (let i = 0; i < logicalLines.length; i++) {
|
|
4477
4740
|
const line = logicalLines[i];
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
styledLine = `${prefix}${line}`;
|
|
4485
|
-
}
|
|
4486
|
-
lines.push(...wrapTranscriptLine(styledLine, contentWidth, " "));
|
|
4741
|
+
const prefix = i === 0 ? firstPrefix : multilinePrefix;
|
|
4742
|
+
const styledLine = `${prefix}${line}`;
|
|
4743
|
+
const rows = wrapTranscriptLine(styledLine, contentWidth, hangingIndent);
|
|
4744
|
+
lines.push(
|
|
4745
|
+
...surfaceSeq ? rows.map((row) => fillUserBubbleRow(row, surfaceSeq, contentWidth)) : rows
|
|
4746
|
+
);
|
|
4487
4747
|
}
|
|
4488
4748
|
} else {
|
|
4489
4749
|
const styledEntry = styleAssistantTurn(content, colorEnabled);
|
|
@@ -4493,57 +4753,184 @@ function renderTurnBlock(role, content, contentWidth, colorEnabled) {
|
|
|
4493
4753
|
}
|
|
4494
4754
|
return lines;
|
|
4495
4755
|
}
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4756
|
+
var streamingTurnCache = null;
|
|
4757
|
+
function resetStreamingTurnCache() {
|
|
4758
|
+
streamingTurnCache = null;
|
|
4759
|
+
}
|
|
4760
|
+
function renderPrefixTurnBlock(role, content, contentWidth, colorEnabled) {
|
|
4761
|
+
content = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4762
|
+
if (role === "user") {
|
|
4763
|
+
return renderTurnBlock(role, content, contentWidth, colorEnabled);
|
|
4500
4764
|
}
|
|
4765
|
+
const highlighted = colorEnabled ? formatAssistantDisplay(content, { trimEdges: false }) : stripAnsi(formatAssistantDisplay(content, { trimEdges: false }));
|
|
4766
|
+
const rawLines = highlighted.split("\n");
|
|
4767
|
+
const styledLines = rawLines.map((line, idx) => {
|
|
4768
|
+
if (idx === 0 && !line.startsWith("[nolo]")) {
|
|
4769
|
+
const anchorPrefix = colorEnabled ? `${themeColorSequence("chrome")}\u25C8\x1B[39m ` : "\u25C8 ";
|
|
4770
|
+
return `${anchorPrefix}${line}`;
|
|
4771
|
+
}
|
|
4772
|
+
return line.startsWith("[nolo]") && colorEnabled ? themeText(line, "chrome", true) : line;
|
|
4773
|
+
});
|
|
4501
4774
|
const lines = [];
|
|
4502
|
-
for (const
|
|
4503
|
-
|
|
4504
|
-
const normalized = stripAnsi(turn.content).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4505
|
-
lines.push(...normalized.split("\n"));
|
|
4775
|
+
for (const logicalLine of styledLines) {
|
|
4776
|
+
lines.push(...wrapTranscriptLine(logicalLine, contentWidth));
|
|
4506
4777
|
}
|
|
4507
4778
|
return lines;
|
|
4508
4779
|
}
|
|
4509
|
-
function
|
|
4510
|
-
|
|
4780
|
+
function renderTailTurnBlock(role, content, contentWidth, colorEnabled) {
|
|
4781
|
+
content = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4782
|
+
const lines = [];
|
|
4783
|
+
if (role === "user") {
|
|
4784
|
+
const surfaceSeq = colorEnabled ? userSurfaceBackgroundSequence() : "";
|
|
4785
|
+
const accentSeq = colorEnabled ? themeColorSequence("accent") : "";
|
|
4786
|
+
const multilinePrefix = colorEnabled ? `${accentSeq}\x1B[1m\u2503 ` : "\u2503 ";
|
|
4787
|
+
const hangingIndent = colorEnabled ? `${accentSeq}\x1B[1m\u2503 ` : "\u2503 ";
|
|
4788
|
+
for (const rawLine of content.split("\n")) {
|
|
4789
|
+
const styledLine = `${multilinePrefix}${rawLine}`;
|
|
4790
|
+
const rows = wrapTranscriptLine(styledLine, contentWidth, hangingIndent);
|
|
4791
|
+
lines.push(
|
|
4792
|
+
...surfaceSeq ? rows.map((row) => fillUserBubbleRow(row, surfaceSeq, contentWidth)) : rows
|
|
4793
|
+
);
|
|
4794
|
+
}
|
|
4795
|
+
} else {
|
|
4796
|
+
const highlighted = colorEnabled ? formatAssistantDisplay(content) : stripAnsi(formatAssistantDisplay(content));
|
|
4797
|
+
const rawLines = highlighted.split("\n");
|
|
4798
|
+
const styledLines = rawLines.map((line) => {
|
|
4799
|
+
return line.startsWith("[nolo]") && colorEnabled ? themeText(line, "chrome", true) : line;
|
|
4800
|
+
});
|
|
4801
|
+
for (const logicalLine of styledLines) {
|
|
4802
|
+
lines.push(...wrapTranscriptLine(logicalLine, contentWidth));
|
|
4803
|
+
}
|
|
4804
|
+
}
|
|
4805
|
+
return lines;
|
|
4806
|
+
}
|
|
4807
|
+
function getStreamingTurnLines(role, content, contentWidth, colorEnabled, density, surface) {
|
|
4808
|
+
if (streamingTurnCache && (streamingTurnCache.role !== role || streamingTurnCache.contentWidth !== contentWidth || streamingTurnCache.colorEnabled !== colorEnabled || streamingTurnCache.density !== density || streamingTurnCache.surface !== surface || !content.startsWith(streamingTurnCache.fullContent.slice(0, streamingTurnCache.prefixLength)))) {
|
|
4809
|
+
streamingTurnCache = null;
|
|
4810
|
+
}
|
|
4811
|
+
if (!streamingTurnCache) {
|
|
4812
|
+
streamingTurnCache = {
|
|
4813
|
+
role,
|
|
4814
|
+
contentWidth,
|
|
4815
|
+
colorEnabled,
|
|
4816
|
+
density,
|
|
4817
|
+
surface,
|
|
4818
|
+
fullContent: content,
|
|
4819
|
+
prefixLength: 0,
|
|
4820
|
+
prefixLines: []
|
|
4821
|
+
};
|
|
4822
|
+
}
|
|
4823
|
+
if (content.length > streamingTurnCache.fullContent.length) {
|
|
4824
|
+
let searchPos = streamingTurnCache.prefixLength;
|
|
4825
|
+
let candidateCut = -1;
|
|
4826
|
+
while (true) {
|
|
4827
|
+
const idx = content.indexOf("\n\n", searchPos);
|
|
4828
|
+
if (idx === -1) break;
|
|
4829
|
+
const cut = idx + 1;
|
|
4830
|
+
searchPos = idx + 2;
|
|
4831
|
+
const prefixSub = content.slice(0, cut);
|
|
4832
|
+
const fenceCount = (prefixSub.match(/^```/gm) || []).length;
|
|
4833
|
+
if (fenceCount % 2 === 0) {
|
|
4834
|
+
candidateCut = cut;
|
|
4835
|
+
break;
|
|
4836
|
+
}
|
|
4837
|
+
}
|
|
4838
|
+
if (candidateCut > streamingTurnCache.prefixLength) {
|
|
4839
|
+
const candidatePrefix = content.slice(0, candidateCut);
|
|
4840
|
+
const candidateTail = content.slice(candidateCut);
|
|
4841
|
+
const candPrefixLines = renderPrefixTurnBlock(role, candidatePrefix, contentWidth, colorEnabled);
|
|
4842
|
+
const candTailLines = renderTailTurnBlock(role, candidateTail, contentWidth, colorEnabled);
|
|
4843
|
+
const candCombined = [...candPrefixLines, ...candTailLines];
|
|
4844
|
+
const fullCheckLines = renderTurnBlock(role, content, contentWidth, colorEnabled);
|
|
4845
|
+
if (JSON.stringify(candCombined) === JSON.stringify(fullCheckLines)) {
|
|
4846
|
+
streamingTurnCache.prefixLength = candidateCut;
|
|
4847
|
+
streamingTurnCache.prefixLines = candPrefixLines;
|
|
4848
|
+
streamingTurnCache.fullContent = content;
|
|
4849
|
+
} else {
|
|
4850
|
+
streamingTurnCache.fullContent = content;
|
|
4851
|
+
}
|
|
4852
|
+
} else {
|
|
4853
|
+
streamingTurnCache.fullContent = content;
|
|
4854
|
+
}
|
|
4855
|
+
}
|
|
4856
|
+
if (streamingTurnCache.prefixLength === 0) {
|
|
4857
|
+
return renderTurnBlock(role, content, contentWidth, colorEnabled);
|
|
4858
|
+
}
|
|
4859
|
+
const tailContent = content.slice(streamingTurnCache.prefixLength);
|
|
4860
|
+
const tailLines = renderTailTurnBlock(role, tailContent, contentWidth, colorEnabled);
|
|
4861
|
+
return [...streamingTurnCache.prefixLines, ...tailLines];
|
|
4862
|
+
}
|
|
4863
|
+
var assistantPlainLinesCache = /* @__PURE__ */ new Map();
|
|
4864
|
+
function getAssistantPlainLines(content) {
|
|
4865
|
+
let plainLines = assistantPlainLinesCache.get(content);
|
|
4866
|
+
if (plainLines !== void 0) {
|
|
4867
|
+
return plainLines;
|
|
4868
|
+
}
|
|
4869
|
+
if (!/[\r\x00#|\-*_~`>+\[\]()•☐☑]|\b\d+\./.test(content)) {
|
|
4870
|
+
plainLines = content.trim().split("\n");
|
|
4871
|
+
} else {
|
|
4872
|
+
plainLines = stripAnsi(formatAssistantDisplay(content)).split("\n");
|
|
4873
|
+
}
|
|
4874
|
+
if (assistantPlainLinesCache.size > 2e3) {
|
|
4875
|
+
const firstKey = assistantPlainLinesCache.keys().next().value;
|
|
4876
|
+
if (firstKey !== void 0) assistantPlainLinesCache.delete(firstKey);
|
|
4877
|
+
}
|
|
4878
|
+
assistantPlainLinesCache.set(content, plainLines);
|
|
4879
|
+
return plainLines;
|
|
4880
|
+
}
|
|
4881
|
+
function countTurnLines(role, content, contentWidth) {
|
|
4882
|
+
content = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4883
|
+
let count = 0;
|
|
4884
|
+
if (role === "user") {
|
|
4885
|
+
for (const line of content.split("\n")) {
|
|
4886
|
+
count += wrapTranscriptLine(`\u2503 ${line}`, contentWidth, "\u2503 ").length;
|
|
4887
|
+
}
|
|
4888
|
+
} else {
|
|
4889
|
+
const plainLines = getAssistantPlainLines(content);
|
|
4890
|
+
for (let i = 0; i < plainLines.length; i++) {
|
|
4891
|
+
const line = plainLines[i];
|
|
4892
|
+
const wrapped = i === 0 && !line.startsWith("[nolo]") ? wrapTranscriptLine(`\u25C8 ${line}`, contentWidth) : wrapTranscriptLine(line, contentWidth);
|
|
4893
|
+
count += wrapped.length;
|
|
4894
|
+
}
|
|
4895
|
+
}
|
|
4896
|
+
return count;
|
|
4897
|
+
}
|
|
4898
|
+
function buildTurnOffsets(history, contentWidth) {
|
|
4511
4899
|
const density = getActiveDensity();
|
|
4512
|
-
const
|
|
4900
|
+
const entries = [];
|
|
4901
|
+
let offset = 0;
|
|
4513
4902
|
for (let i = 0; i < history.turns.length; i++) {
|
|
4514
4903
|
const turn = history.turns[i];
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
if (cached && cached.width === contentWidth
|
|
4520
|
-
|
|
4904
|
+
const separatorAbove = density === "spacious" && (i > 0 || turn.role === "user") ? 1 : 0;
|
|
4905
|
+
offset += separatorAbove;
|
|
4906
|
+
const cached = turnLineCountCache.get(turn);
|
|
4907
|
+
let lineCount;
|
|
4908
|
+
if (cached && cached.width === contentWidth) {
|
|
4909
|
+
lineCount = cached.count;
|
|
4521
4910
|
} else {
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
width: contentWidth,
|
|
4525
|
-
color: colorEnabled,
|
|
4526
|
-
density,
|
|
4527
|
-
lines
|
|
4528
|
-
});
|
|
4529
|
-
wrapped.push(...lines);
|
|
4911
|
+
lineCount = countTurnLines(turn.role, turn.content, contentWidth);
|
|
4912
|
+
turnLineCountCache.set(turn, { width: contentWidth, count: lineCount });
|
|
4530
4913
|
}
|
|
4914
|
+
entries.push({ startRow: offset, lineCount, separatorAbove });
|
|
4915
|
+
offset += lineCount;
|
|
4531
4916
|
}
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
);
|
|
4917
|
+
return { entries, totalLines: offset };
|
|
4918
|
+
}
|
|
4919
|
+
function currentTurnSeparator(history, density) {
|
|
4920
|
+
return density === "spacious" && (history.turns.length > 0 || history.currentRole === "user") ? 1 : 0;
|
|
4921
|
+
}
|
|
4922
|
+
function buildCopyViewLines(history) {
|
|
4923
|
+
const turns = [...history.turns];
|
|
4924
|
+
if (history.currentRole !== null) {
|
|
4925
|
+
turns.push({ role: history.currentRole, content: history.currentContent });
|
|
4926
|
+
}
|
|
4927
|
+
const lines = [];
|
|
4928
|
+
for (const [index, turn] of turns.entries()) {
|
|
4929
|
+
if (index > 0) lines.push("");
|
|
4930
|
+
const normalized = stripAnsi(turn.content).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4931
|
+
lines.push(...normalized.split("\n"));
|
|
4545
4932
|
}
|
|
4546
|
-
return
|
|
4933
|
+
return lines;
|
|
4547
4934
|
}
|
|
4548
4935
|
function renderHistory(output, history, inputLines) {
|
|
4549
4936
|
const tty = output;
|
|
@@ -4552,8 +4939,28 @@ function renderHistory(output, history, inputLines) {
|
|
|
4552
4939
|
const columns = tty.columns ?? 80;
|
|
4553
4940
|
const visibleHeight = Math.max(1, rows - inputLines);
|
|
4554
4941
|
const contentWidth = Math.max(1, columns - 1);
|
|
4555
|
-
const
|
|
4556
|
-
const
|
|
4942
|
+
const colorEnabled = resolveCliColorEnabled();
|
|
4943
|
+
const density = getActiveDensity();
|
|
4944
|
+
const surface = colorEnabled ? userSurfaceBackgroundSequence() : "";
|
|
4945
|
+
const { entries, totalLines: finalizedLines } = buildTurnOffsets(
|
|
4946
|
+
history,
|
|
4947
|
+
contentWidth
|
|
4948
|
+
);
|
|
4949
|
+
let totalLines = finalizedLines;
|
|
4950
|
+
let currentStart = -1;
|
|
4951
|
+
let currentLines = [];
|
|
4952
|
+
if (history.currentRole !== null && history.currentContent) {
|
|
4953
|
+
currentLines = getStreamingTurnLines(
|
|
4954
|
+
history.currentRole,
|
|
4955
|
+
history.currentContent,
|
|
4956
|
+
contentWidth,
|
|
4957
|
+
colorEnabled,
|
|
4958
|
+
density,
|
|
4959
|
+
surface
|
|
4960
|
+
);
|
|
4961
|
+
currentStart = finalizedLines + currentTurnSeparator(history, density);
|
|
4962
|
+
totalLines = currentStart + currentLines.length;
|
|
4963
|
+
}
|
|
4557
4964
|
if (history.followBottom) {
|
|
4558
4965
|
history.scrollTop = Math.max(0, totalLines - visibleHeight);
|
|
4559
4966
|
} else {
|
|
@@ -4564,19 +4971,71 @@ function renderHistory(output, history, inputLines) {
|
|
|
4564
4971
|
}
|
|
4565
4972
|
history.hasMoreAbove = history.scrollTop > 0;
|
|
4566
4973
|
history.hasMoreBelow = history.scrollTop + visibleHeight < totalLines;
|
|
4567
|
-
const
|
|
4568
|
-
const
|
|
4569
|
-
const visibleLines =
|
|
4974
|
+
const winStart = history.scrollTop;
|
|
4975
|
+
const winEnd = Math.min(totalLines, winStart + visibleHeight);
|
|
4976
|
+
const visibleLines = new Array(visibleHeight).fill("");
|
|
4977
|
+
for (let i = 0; i < entries.length; i++) {
|
|
4978
|
+
const entry = entries[i];
|
|
4979
|
+
if (entry.separatorAbove > 0) {
|
|
4980
|
+
const sepRow = entry.startRow - 1;
|
|
4981
|
+
if (sepRow >= winStart && sepRow < winEnd) {
|
|
4982
|
+
visibleLines[sepRow - winStart] = "";
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4985
|
+
const turnStart = entry.startRow;
|
|
4986
|
+
const turnEnd = turnStart + entry.lineCount;
|
|
4987
|
+
if (turnEnd <= winStart || turnStart >= winEnd) continue;
|
|
4988
|
+
const turn = history.turns[i];
|
|
4989
|
+
const cached = turnLineCache.get(turn);
|
|
4990
|
+
let lines;
|
|
4991
|
+
if (cached && cached.width === contentWidth && cached.color === colorEnabled && cached.density === density && cached.surface === surface) {
|
|
4992
|
+
lines = cached.lines;
|
|
4993
|
+
} else {
|
|
4994
|
+
renderCacheMissCount += 1;
|
|
4995
|
+
lines = renderTurnBlock(turn.role, turn.content, contentWidth, colorEnabled);
|
|
4996
|
+
turnLineCache.set(turn, {
|
|
4997
|
+
width: contentWidth,
|
|
4998
|
+
color: colorEnabled,
|
|
4999
|
+
density,
|
|
5000
|
+
surface,
|
|
5001
|
+
lines
|
|
5002
|
+
});
|
|
5003
|
+
}
|
|
5004
|
+
const interStart = Math.max(turnStart, winStart);
|
|
5005
|
+
const interEnd = Math.min(turnEnd, winEnd);
|
|
5006
|
+
for (let r = interStart; r < interEnd; r++) {
|
|
5007
|
+
visibleLines[r - winStart] = lines[r - turnStart] ?? "";
|
|
5008
|
+
}
|
|
5009
|
+
}
|
|
5010
|
+
if (currentStart >= 0) {
|
|
5011
|
+
const separatorAbove = currentTurnSeparator(history, density);
|
|
5012
|
+
if (separatorAbove > 0) {
|
|
5013
|
+
const sepRow = currentStart - 1;
|
|
5014
|
+
if (sepRow >= winStart && sepRow < winEnd) {
|
|
5015
|
+
visibleLines[sepRow - winStart] = "";
|
|
5016
|
+
}
|
|
5017
|
+
}
|
|
5018
|
+
const currentEnd = currentStart + currentLines.length;
|
|
5019
|
+
if (currentEnd > winStart && currentStart < winEnd) {
|
|
5020
|
+
const interStart = Math.max(currentStart, winStart);
|
|
5021
|
+
const interEnd = Math.min(currentEnd, winEnd);
|
|
5022
|
+
for (let r = interStart; r < interEnd; r++) {
|
|
5023
|
+
visibleLines[r - winStart] = currentLines[r - currentStart] ?? "";
|
|
5024
|
+
}
|
|
5025
|
+
}
|
|
5026
|
+
}
|
|
4570
5027
|
let frame = "";
|
|
4571
5028
|
for (let i = 0; i < visibleHeight; i++) {
|
|
4572
5029
|
const line = visibleLines[i] ?? "";
|
|
4573
5030
|
const padded = padOrTruncateToWidth(line, contentWidth);
|
|
4574
5031
|
const thumb = renderScrollbarRow(i, visibleHeight, totalLines, history.scrollTop);
|
|
5032
|
+
const scrollbarPrefix = colorEnabled ? themeColorSequence("chrome") : "";
|
|
5033
|
+
const scrollbarSuffix = colorEnabled ? "\x1B[39m" : "";
|
|
4575
5034
|
frame += `\x1B[${i + 1};1H`;
|
|
4576
5035
|
frame += "\x1B[2K";
|
|
4577
5036
|
frame += padded;
|
|
4578
5037
|
frame += `\x1B[${columns}G`;
|
|
4579
|
-
frame += thumb
|
|
5038
|
+
frame += `${scrollbarPrefix}${thumb}${scrollbarSuffix}`;
|
|
4580
5039
|
}
|
|
4581
5040
|
const mainBottom = Math.max(1, rows - inputLines);
|
|
4582
5041
|
frame += `\x1B[${mainBottom};1H`;
|
|
@@ -4603,7 +5062,11 @@ function applyScrollAction(history, action, output, inputLines) {
|
|
|
4603
5062
|
const columns = tty.columns ?? 80;
|
|
4604
5063
|
const visibleHeight = Math.max(1, rows - inputLines);
|
|
4605
5064
|
const contentWidth = Math.max(1, columns - 1);
|
|
4606
|
-
const totalLines =
|
|
5065
|
+
const { totalLines: finalizedLines } = buildTurnOffsets(history, contentWidth);
|
|
5066
|
+
let totalLines = finalizedLines;
|
|
5067
|
+
if (history.currentRole !== null && history.currentContent) {
|
|
5068
|
+
totalLines += currentTurnSeparator(history, getActiveDensity()) + countTurnLines(history.currentRole, history.currentContent, contentWidth);
|
|
5069
|
+
}
|
|
4607
5070
|
const maxScrollTop = Math.max(0, totalLines - visibleHeight);
|
|
4608
5071
|
history.followBottom = false;
|
|
4609
5072
|
switch (action) {
|
|
@@ -5211,70 +5674,21 @@ ${content}`;
|
|
|
5211
5674
|
return null;
|
|
5212
5675
|
}
|
|
5213
5676
|
var autoRouteByDialog = /* @__PURE__ */ new Map();
|
|
5214
|
-
function toOverlayStatus(status) {
|
|
5215
|
-
switch (status) {
|
|
5216
|
-
case "running":
|
|
5217
|
-
return "running";
|
|
5218
|
-
case "done":
|
|
5219
|
-
return "done";
|
|
5220
|
-
case "failed":
|
|
5221
|
-
case "timeout":
|
|
5222
|
-
case "killed":
|
|
5223
|
-
return "failed";
|
|
5224
|
-
case "orphaned":
|
|
5225
|
-
return "orphaned";
|
|
5226
|
-
default:
|
|
5227
|
-
return "running";
|
|
5228
|
-
}
|
|
5229
|
-
}
|
|
5230
|
-
function buildTuiRunOverlay(parentDialogId, reported) {
|
|
5231
|
-
if (!parentDialogId) return null;
|
|
5232
|
-
let runs;
|
|
5233
|
-
try {
|
|
5234
|
-
runs = queryRunRecords({ parentDialogId }, { env: process.env }).runs;
|
|
5235
|
-
} catch {
|
|
5236
|
-
return null;
|
|
5237
|
-
}
|
|
5238
|
-
if (runs.length === 0) return null;
|
|
5239
|
-
if (reported) {
|
|
5240
|
-
runs = runs.filter((run) => reported.get(run.runId) !== run.status);
|
|
5241
|
-
for (const run of runs) reported.set(run.runId, run.status);
|
|
5242
|
-
if (runs.length === 0) return null;
|
|
5243
|
-
}
|
|
5244
|
-
let overlay = initialRunOverlayState;
|
|
5245
|
-
for (const run of runs) {
|
|
5246
|
-
overlay = reduceRunOverlay(overlay, {
|
|
5247
|
-
type: "run-state-chg",
|
|
5248
|
-
runId: run.runId,
|
|
5249
|
-
info: {
|
|
5250
|
-
name: run.agentName ?? run.agentKey ?? run.runId,
|
|
5251
|
-
status: toOverlayStatus(run.status),
|
|
5252
|
-
batchId: run.batchId,
|
|
5253
|
-
parentDialogId: run.parentDialogId,
|
|
5254
|
-
...run.status === "failed" && run.note ? { errorMessage: run.note } : {}
|
|
5255
|
-
}
|
|
5256
|
-
});
|
|
5257
|
-
}
|
|
5258
|
-
return buildOverlayPresentation(overlay);
|
|
5259
|
-
}
|
|
5260
5677
|
async function runAgentChat(scriptDir, state, message, env, output, agentRunner = runAgentTurn, options = {}) {
|
|
5261
5678
|
let effectiveAgentKey = state.agentKey;
|
|
5262
5679
|
let effectiveAgentName = state.agentName;
|
|
5263
5680
|
const continueId = state.dialogId;
|
|
5264
5681
|
const cachedRoute = continueId ? autoRouteByDialog.get(continueId) : void 0;
|
|
5682
|
+
const hasImages = options.imageUrls && options.imageUrls.length > 0;
|
|
5265
5683
|
if (cachedRoute && !options.explicitAgentSwitch) {
|
|
5266
5684
|
effectiveAgentKey = cachedRoute.agentKey;
|
|
5267
5685
|
effectiveAgentName = cachedRoute.agentName;
|
|
5268
5686
|
} else if (!continueId && env.NOLO_AUTO_ROUTE !== "0" && state.agentKey === DEFAULT_TUI_AGENT_KEY) {
|
|
5269
|
-
const
|
|
5270
|
-
const route = authToken ? await classifyCliAutoRoute(message, {
|
|
5687
|
+
const route = classifyCliAutoRoute(message, {
|
|
5271
5688
|
serverUrl: state.serverUrl,
|
|
5272
|
-
authToken
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
tier: resolveCliAutoFallbackTier(message),
|
|
5276
|
-
classified: false
|
|
5277
|
-
};
|
|
5689
|
+
authToken: resolvePlatformAuthToken(env),
|
|
5690
|
+
hasImages
|
|
5691
|
+
});
|
|
5278
5692
|
effectiveAgentKey = route.agentKey;
|
|
5279
5693
|
effectiveAgentName = `auto\u2192${route.tier}`;
|
|
5280
5694
|
if (effectiveAgentKey !== state.agentKey) {
|
|
@@ -5285,7 +5699,6 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
|
|
|
5285
5699
|
);
|
|
5286
5700
|
}
|
|
5287
5701
|
}
|
|
5288
|
-
const hasImages = options.imageUrls && options.imageUrls.length > 0;
|
|
5289
5702
|
const userSelectedAgent = state.agentKey !== DEFAULT_TUI_AGENT_KEY;
|
|
5290
5703
|
const visionProbeKey = hasImages && userSelectedAgent ? state.agentKey : effectiveAgentKey;
|
|
5291
5704
|
if (hasImages && effectiveAgentKey !== CLI_IMAGE_AGENT_KEY) {
|
|
@@ -5398,18 +5811,22 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
|
|
|
5398
5811
|
// inside a TUI turn are stamped with the current conversation. Previously
|
|
5399
5812
|
// this factory only existed when pasted text was present, which meant a
|
|
5400
5813
|
// plain (no-paste) turn had no injection point for parentDialogId and the
|
|
5401
|
-
// run-
|
|
5814
|
+
// run-completion watcher could never attribute runs spawned this turn.
|
|
5402
5815
|
...options.pastedTextStore?.items.size ? { pastedTextStore: options.pastedTextStore } : {},
|
|
5403
5816
|
localRuntimeAdapterFactory: (factoryEnv, factoryOptions) => createCliLocalRuntimeAdapter({
|
|
5404
5817
|
env: factoryEnv,
|
|
5405
5818
|
cwd: factoryOptions?.cwd ?? state.cwd,
|
|
5406
5819
|
...options.pastedTextStore ? { pastedTextStore: options.pastedTextStore } : {},
|
|
5407
5820
|
// Stamp spawned background runs with the current TUI dialog so the
|
|
5408
|
-
// run-
|
|
5821
|
+
// run-completion watcher can attribute terminal-state wakes to this
|
|
5822
|
+
// conversation.
|
|
5409
5823
|
...state.dialogId ? { parentDialogId: state.dialogId } : {},
|
|
5410
5824
|
...options.activityReporter ? { activityReporter: options.activityReporter } : {}
|
|
5411
5825
|
}),
|
|
5412
5826
|
...options.activityReporter ? { activityReporter: options.activityReporter } : {},
|
|
5827
|
+
// 转发 dock 订阅:runAgentTurn 的输出层靠它判断「有面板」从而抑制
|
|
5828
|
+
// transcript 的进展卡片;dock 本身也靠它接收模型轮询带回来的快照。
|
|
5829
|
+
...options.onAgentRunStatus ? { onAgentRunStatus: options.onAgentRunStatus } : {},
|
|
5413
5830
|
...skillAllowedTools !== void 0 ? { allowedToolNames: skillAllowedTools } : {},
|
|
5414
5831
|
...contextBlockScopes.length > 0 ? { contextBlockScopes } : {}
|
|
5415
5832
|
});
|
|
@@ -5514,9 +5931,9 @@ function waitForActionGate(rl, input, output, gate, spawnRunner) {
|
|
|
5514
5931
|
});
|
|
5515
5932
|
});
|
|
5516
5933
|
}
|
|
5517
|
-
function persistAgentSelection(state, env) {
|
|
5934
|
+
function persistAgentSelection(state, env, saveSelection = saveProfileAgentSelection) {
|
|
5518
5935
|
try {
|
|
5519
|
-
|
|
5936
|
+
saveSelection({
|
|
5520
5937
|
agentKey: state.agentKey,
|
|
5521
5938
|
agentName: state.agentName
|
|
5522
5939
|
});
|
|
@@ -5696,12 +6113,20 @@ async function startTuiWorkspace(options) {
|
|
|
5696
6113
|
}
|
|
5697
6114
|
});
|
|
5698
6115
|
const activityReporter = (label) => activityIndicator.report(label);
|
|
5699
|
-
|
|
6116
|
+
let runWakeHandler = null;
|
|
6117
|
+
const runCompletionWatcher = createRunCompletionWatcher({
|
|
6118
|
+
getCurrentDialogId: () => state.dialogId ?? null,
|
|
6119
|
+
onWake: (text) => runWakeHandler?.(text)
|
|
6120
|
+
});
|
|
5700
6121
|
const runRegistryPoller = createRunRegistryPoller({
|
|
5701
6122
|
getDockedRuns: () => activityIndicator.getAgentRuns(),
|
|
5702
6123
|
update: (snapshot) => activityIndicator.updateAgentRun(snapshot),
|
|
5703
|
-
|
|
5704
|
-
|
|
6124
|
+
// 显式传 env:resolveNoloHome 只认传入 env 的 NOLO_HOME,不传则永远读
|
|
6125
|
+
// ~/.nolo——设了 NOLO_HOME 的环境(dev、测试)会读错目录。run 记录读取
|
|
6126
|
+
// 与 reconcile 的调用点也是同样写法。
|
|
6127
|
+
readRecord: (runId) => readRunRecord(runId, { env: process.env }),
|
|
6128
|
+
reconcile: (runId) => checkStaleRun(runId, { env: process.env }),
|
|
6129
|
+
onRecordsPolled: (records) => runCompletionWatcher.observe(records)
|
|
5705
6130
|
});
|
|
5706
6131
|
let explicitAgentSwitch = false;
|
|
5707
6132
|
let copyViewExitResolver = null;
|
|
@@ -5864,11 +6289,17 @@ async function startTuiWorkspace(options) {
|
|
|
5864
6289
|
void maybeAutoRefreshTheme();
|
|
5865
6290
|
}, AUTO_THEME_POLL_MS);
|
|
5866
6291
|
}
|
|
5867
|
-
const runOneAgentTurn = async (
|
|
6292
|
+
const runOneAgentTurn = async (inputMsg, imageUrls, actionGateHandler, confirmDestructiveAction) => {
|
|
6293
|
+
const req = createTurnRequest(inputMsg);
|
|
6294
|
+
if (req.event.kind === "child-run-completed") {
|
|
6295
|
+
for (const r of req.event.runs) {
|
|
6296
|
+
runCompletionWatcher.markAcknowledged(r.runId);
|
|
6297
|
+
}
|
|
6298
|
+
}
|
|
6299
|
+
const message = req.text;
|
|
5868
6300
|
forcedStop = false;
|
|
5869
6301
|
turnEpoch += 1;
|
|
5870
6302
|
const myEpoch = turnEpoch;
|
|
5871
|
-
const turnParentDialogId = state.dialogId;
|
|
5872
6303
|
history.followBottom = true;
|
|
5873
6304
|
startTurn(history, "user");
|
|
5874
6305
|
appendToCurrentTurn(history, message);
|
|
@@ -5879,12 +6310,12 @@ async function startTuiWorkspace(options) {
|
|
|
5879
6310
|
const agentOutput = isInteractiveInput(input) ? createHistoryOutputStream(history, () => {
|
|
5880
6311
|
scheduleRender();
|
|
5881
6312
|
}) : output;
|
|
5882
|
-
const requestUserChoice = isInteractiveInput(input) && dialogHost ? async (
|
|
6313
|
+
const requestUserChoice = isInteractiveInput(input) && dialogHost ? async (req2) => {
|
|
5883
6314
|
modalOwnsKeyboard = true;
|
|
5884
6315
|
try {
|
|
5885
6316
|
return await dialogHost.run(
|
|
5886
6317
|
(anchor) => runAskChoiceDialog({
|
|
5887
|
-
request:
|
|
6318
|
+
request: req2,
|
|
5888
6319
|
input,
|
|
5889
6320
|
output,
|
|
5890
6321
|
...anchor
|
|
@@ -5934,7 +6365,8 @@ async function startTuiWorkspace(options) {
|
|
|
5934
6365
|
...runResult.dialogId ? {
|
|
5935
6366
|
dialogId: runResult.dialogId,
|
|
5936
6367
|
dialogKey: nextDialogKey,
|
|
5937
|
-
dialogLabel: runResult.title || runResult.dialogId
|
|
6368
|
+
dialogLabel: runResult.title || runResult.dialogId,
|
|
6369
|
+
...runResult.title ? { dialogTitle: runResult.title } : {}
|
|
5938
6370
|
} : {},
|
|
5939
6371
|
...runResult.turnTokens ? { turnTokens: runResult.turnTokens } : {}
|
|
5940
6372
|
};
|
|
@@ -5943,6 +6375,14 @@ async function startTuiWorkspace(options) {
|
|
|
5943
6375
|
}
|
|
5944
6376
|
const wasAborted = activeTurnAbort.signal.aborted;
|
|
5945
6377
|
activeTurnAbort = null;
|
|
6378
|
+
if (shouldEmitTerminalBell({
|
|
6379
|
+
wasAborted,
|
|
6380
|
+
streamInterrupted: runResult.streamInterrupted,
|
|
6381
|
+
exitCode: runResult.exitCode,
|
|
6382
|
+
interactive: isInteractiveInput(input)
|
|
6383
|
+
})) {
|
|
6384
|
+
emitTerminalBell(output);
|
|
6385
|
+
}
|
|
5946
6386
|
explicitAgentSwitch = false;
|
|
5947
6387
|
if (isInteractiveInput(input)) {
|
|
5948
6388
|
finalizeCurrentTurn(history);
|
|
@@ -5964,7 +6404,8 @@ async function startTuiWorkspace(options) {
|
|
|
5964
6404
|
...runResult.dialogId ? {
|
|
5965
6405
|
dialogId: runResult.dialogId,
|
|
5966
6406
|
dialogKey: nextDialogKey,
|
|
5967
|
-
dialogLabel: runResult.title || runResult.dialogId
|
|
6407
|
+
dialogLabel: runResult.title || runResult.dialogId,
|
|
6408
|
+
...runResult.title ? { dialogTitle: runResult.title } : {}
|
|
5968
6409
|
} : {},
|
|
5969
6410
|
...runResult.turnTokens ? { turnTokens: runResult.turnTokens } : {},
|
|
5970
6411
|
...runResult.contextWindow ? { contextWindow: runResult.contextWindow } : {},
|
|
@@ -5985,14 +6426,6 @@ async function startTuiWorkspace(options) {
|
|
|
5985
6426
|
emitCommandOutput(t("dialogNotSavedHint"));
|
|
5986
6427
|
}
|
|
5987
6428
|
}
|
|
5988
|
-
if (!wasAborted) {
|
|
5989
|
-
const overlayText = buildTuiRunOverlay(turnParentDialogId, reportedRunStatuses);
|
|
5990
|
-
if (overlayText) {
|
|
5991
|
-
emitCommandOutput(`
|
|
5992
|
-
\u4F60\u7684 run \u8FDB\u5C55\uFF1A
|
|
5993
|
-
${overlayText}`);
|
|
5994
|
-
}
|
|
5995
|
-
}
|
|
5996
6429
|
return { ok: !wasAborted, aborted: wasAborted };
|
|
5997
6430
|
} finally {
|
|
5998
6431
|
activityIndicator.stop();
|
|
@@ -6027,6 +6460,17 @@ ${overlayText}`);
|
|
|
6027
6460
|
renderHistoryToOutput();
|
|
6028
6461
|
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
6029
6462
|
};
|
|
6463
|
+
const persistExplicitAgentSwitch = (previousAgentKey) => {
|
|
6464
|
+
if (state.agentKey === previousAgentKey) return false;
|
|
6465
|
+
if (state.dialogId) autoRouteByDialog.delete(state.dialogId);
|
|
6466
|
+
explicitAgentSwitch = true;
|
|
6467
|
+
persistAgentSelection(
|
|
6468
|
+
state,
|
|
6469
|
+
options.env ?? process.env,
|
|
6470
|
+
options.saveAgentSelection
|
|
6471
|
+
);
|
|
6472
|
+
return true;
|
|
6473
|
+
};
|
|
6030
6474
|
const runSubmittedLine = async (line, actionGateHandler, confirmDestructiveAction) => {
|
|
6031
6475
|
if (!line.trim()) return false;
|
|
6032
6476
|
const result = handleTuiInput(line, state);
|
|
@@ -6045,9 +6489,7 @@ ${overlayText}`);
|
|
|
6045
6489
|
emitCommandOutput(result.output);
|
|
6046
6490
|
}
|
|
6047
6491
|
if (state.agentKey !== previousAgentKey) {
|
|
6048
|
-
|
|
6049
|
-
explicitAgentSwitch = true;
|
|
6050
|
-
persistAgentSelection(state, options.env ?? process.env);
|
|
6492
|
+
persistExplicitAgentSwitch(previousAgentKey);
|
|
6051
6493
|
}
|
|
6052
6494
|
if (result.action?.type === "exit") return true;
|
|
6053
6495
|
if (result.action?.type === "clear") {
|
|
@@ -6098,6 +6540,7 @@ ${overlayText}`);
|
|
|
6098
6540
|
if (result.action?.type === "compact") {
|
|
6099
6541
|
const runner = options.compactRunner ?? compactDialog;
|
|
6100
6542
|
const authToken = resolvePlatformAuthToken(options.env ?? {});
|
|
6543
|
+
const compactStart = Date.now();
|
|
6101
6544
|
try {
|
|
6102
6545
|
const compactResult = await runner({
|
|
6103
6546
|
serverUrl: state.serverUrl,
|
|
@@ -6105,20 +6548,45 @@ ${overlayText}`);
|
|
|
6105
6548
|
dialogId: result.action.dialogId,
|
|
6106
6549
|
summaryLlmCaller: options.summaryLlmCaller
|
|
6107
6550
|
});
|
|
6551
|
+
const elapsedSec = ((Date.now() - compactStart) / 1e3).toFixed(1);
|
|
6108
6552
|
state = {
|
|
6109
6553
|
...state,
|
|
6110
6554
|
dialogId: compactResult.dialogId,
|
|
6111
6555
|
dialogKey: compactResult.dialogKey,
|
|
6112
|
-
dialogLabel: compactResult.dialogId
|
|
6556
|
+
dialogLabel: compactResult.dialogId,
|
|
6557
|
+
dialogTitle: state.dialogTitle,
|
|
6558
|
+
// Compact forks into a fresh dialog that only inherits the summary,
|
|
6559
|
+
// not the full message history. Drop usage-derived context so the
|
|
6560
|
+
// composer chip falls back to the default CLI surface estimate and
|
|
6561
|
+
// the context percentage visibly drops. Mirrors the /clear reset.
|
|
6562
|
+
turnTokens: void 0,
|
|
6563
|
+
estimatedContextTokens: estimateDefaultCliContextTokens({
|
|
6564
|
+
cwd: state.cwd,
|
|
6565
|
+
agentKey: state.agentKey,
|
|
6566
|
+
agentName: state.agentKey === DEFAULT_TUI_AGENT_KEY && (options.env ?? process.env).NOLO_AUTO_ROUTE !== "0" ? "DeepSeek V4 Flash" : state.agentName,
|
|
6567
|
+
model: state.agentKey === DEFAULT_TUI_AGENT_KEY && (options.env ?? process.env).NOLO_AUTO_ROUTE !== "0" ? "deepseek-v4-flash" : void 0
|
|
6568
|
+
})
|
|
6113
6569
|
};
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6570
|
+
const elapsed = `${elapsedSec}s`;
|
|
6571
|
+
const message = compactResult.summaryGenerated ? compactResult.compactedMessageCount > 0 ? t(
|
|
6572
|
+
"compactSuccessWithCount",
|
|
6573
|
+
result.action.dialogId,
|
|
6574
|
+
compactResult.dialogId,
|
|
6575
|
+
elapsed,
|
|
6576
|
+
String(compactResult.compactedMessageCount)
|
|
6577
|
+
) : t(
|
|
6578
|
+
"compactSuccess",
|
|
6579
|
+
result.action.dialogId,
|
|
6580
|
+
compactResult.dialogId,
|
|
6581
|
+
elapsed
|
|
6582
|
+
) : t(
|
|
6583
|
+
"compactForked",
|
|
6584
|
+
result.action.dialogId,
|
|
6585
|
+
compactResult.dialogId,
|
|
6586
|
+
elapsed
|
|
6121
6587
|
);
|
|
6588
|
+
output.write(`${message}
|
|
6589
|
+
`);
|
|
6122
6590
|
} catch (error) {
|
|
6123
6591
|
output.write(
|
|
6124
6592
|
`[nolo] Compact failed: ${toErrorMessage(error)}
|
|
@@ -6282,6 +6750,7 @@ ${overlayText}`);
|
|
|
6282
6750
|
dialogId: pickResult.dialog.id,
|
|
6283
6751
|
dialogKey: pickResult.dialog.dbKey,
|
|
6284
6752
|
dialogLabel: pickResult.dialog.title || pickResult.dialog.id,
|
|
6753
|
+
dialogTitle: pickResult.dialog.title,
|
|
6285
6754
|
turnTokens: void 0
|
|
6286
6755
|
};
|
|
6287
6756
|
clearCollapsedPasteStore(pasteStore);
|
|
@@ -6418,12 +6887,6 @@ ${err.message}` : ""}`
|
|
|
6418
6887
|
resolveCliColorEnabled()
|
|
6419
6888
|
);
|
|
6420
6889
|
}
|
|
6421
|
-
if (history.hasMoreAbove || history.hasMoreBelow) {
|
|
6422
|
-
const scrollHints = [];
|
|
6423
|
-
if (history.hasMoreAbove) scrollHints.push("\u25B2 PgUp");
|
|
6424
|
-
if (history.hasMoreBelow) scrollHints.push("\u25BC PgDn");
|
|
6425
|
-
base += dimCliText(` \xB7 \u2195 ${scrollHints.join("/")}`, resolveCliColorEnabled());
|
|
6426
|
-
}
|
|
6427
6890
|
return base;
|
|
6428
6891
|
},
|
|
6429
6892
|
getActivityLines: () => activityIndicator.getActivityLines(resolveCliColorEnabled()),
|
|
@@ -6476,6 +6939,7 @@ ${err.message}` : ""}`
|
|
|
6476
6939
|
autoThemeTimer = null;
|
|
6477
6940
|
}
|
|
6478
6941
|
runRegistryPoller.dispose();
|
|
6942
|
+
runCompletionWatcher.dispose();
|
|
6479
6943
|
activityIndicator.dispose();
|
|
6480
6944
|
resolveDone?.();
|
|
6481
6945
|
clearCollapsedPasteStore(pasteStore);
|
|
@@ -6486,6 +6950,83 @@ ${err.message}` : ""}`
|
|
|
6486
6950
|
output.write("\x1B[?25h\x1B[?2026l");
|
|
6487
6951
|
input.setRawMode?.(false);
|
|
6488
6952
|
};
|
|
6953
|
+
const buildInteractiveTurnHandlers = () => {
|
|
6954
|
+
const actionGateHandler = async (gate) => {
|
|
6955
|
+
modalOwnsKeyboard = true;
|
|
6956
|
+
try {
|
|
6957
|
+
return await waitForRawActionGate(input, output, gate, spawnRunner, {
|
|
6958
|
+
beforeSubprocess: () => fixedInput.pause(),
|
|
6959
|
+
afterSubprocess: () => fixedInput.resumeFromSubprocess(),
|
|
6960
|
+
registerToken: (handler) => {
|
|
6961
|
+
rawActionGateTokenHandler = handler;
|
|
6962
|
+
}
|
|
6963
|
+
});
|
|
6964
|
+
} finally {
|
|
6965
|
+
modalOwnsKeyboard = false;
|
|
6966
|
+
}
|
|
6967
|
+
};
|
|
6968
|
+
const confirmDestructiveAction = async (request) => {
|
|
6969
|
+
modalOwnsKeyboard = true;
|
|
6970
|
+
try {
|
|
6971
|
+
return await dialogHost.run(
|
|
6972
|
+
(anchor) => runConfirmDialog({
|
|
6973
|
+
request,
|
|
6974
|
+
input,
|
|
6975
|
+
output,
|
|
6976
|
+
...anchor
|
|
6977
|
+
})
|
|
6978
|
+
);
|
|
6979
|
+
} finally {
|
|
6980
|
+
modalOwnsKeyboard = false;
|
|
6981
|
+
}
|
|
6982
|
+
};
|
|
6983
|
+
return { actionGateHandler, confirmDestructiveAction };
|
|
6984
|
+
};
|
|
6985
|
+
const runIdleTextTurn = async (inputMsg) => {
|
|
6986
|
+
const req = createTurnRequest(inputMsg);
|
|
6987
|
+
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
6988
|
+
const binding = ensureChatQueueBinding(actionGateHandler, confirmDestructiveAction);
|
|
6989
|
+
binding.notifyTurnStart();
|
|
6990
|
+
busy = true;
|
|
6991
|
+
fixedInput.enterOutputMode(req.text);
|
|
6992
|
+
try {
|
|
6993
|
+
const outcome = await runOneAgentTurn(
|
|
6994
|
+
req,
|
|
6995
|
+
[],
|
|
6996
|
+
actionGateHandler,
|
|
6997
|
+
confirmDestructiveAction
|
|
6998
|
+
);
|
|
6999
|
+
await binding.notifyTurnEnd(outcome);
|
|
7000
|
+
} catch (err) {
|
|
7001
|
+
await binding.notifyTurnEnd({ ok: false, aborted: false });
|
|
7002
|
+
emitCommandOutput(
|
|
7003
|
+
`${t("turnFailed")}${err instanceof Error && err.message ? `
|
|
7004
|
+
${err.message}` : ""}`
|
|
7005
|
+
);
|
|
7006
|
+
} finally {
|
|
7007
|
+
busy = false;
|
|
7008
|
+
}
|
|
7009
|
+
refreshGitStatus();
|
|
7010
|
+
flushPendingRender();
|
|
7011
|
+
fixedInput.exitOutputMode(buffer, cursorPos);
|
|
7012
|
+
};
|
|
7013
|
+
runWakeHandler = (event) => {
|
|
7014
|
+
if (done) return;
|
|
7015
|
+
if (busy || fixedInput.isPaused() || copyViewExitResolver) {
|
|
7016
|
+
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
7017
|
+
ensureChatQueueBinding(actionGateHandler, confirmDestructiveAction).enqueue(event);
|
|
7018
|
+
if (fixedInput.active && !fixedInput.isPaused()) {
|
|
7019
|
+
fixedInput.repaint(buffer, cursorPos);
|
|
7020
|
+
}
|
|
7021
|
+
return;
|
|
7022
|
+
}
|
|
7023
|
+
void runIdleTextTurn(event).catch((err) => {
|
|
7024
|
+
emitCommandOutput(
|
|
7025
|
+
`${t("turnFailed")}${err instanceof Error && err.message ? `
|
|
7026
|
+
${err.message}` : ""}`
|
|
7027
|
+
);
|
|
7028
|
+
});
|
|
7029
|
+
};
|
|
6489
7030
|
const handleInputToken = async (sequence) => {
|
|
6490
7031
|
if (done) return;
|
|
6491
7032
|
if (copyViewExitResolver) {
|
|
@@ -6619,18 +7160,41 @@ ${merged}` : merged;
|
|
|
6619
7160
|
if (busyLock) {
|
|
6620
7161
|
const trimmedText = submittedText.trim();
|
|
6621
7162
|
const busySlashCommand = trimmedText.split(/\s+/)[0]?.toLowerCase();
|
|
6622
|
-
const isBusyLocalSlash = busySlashCommand === "/context" || busySlashCommand === "/ctx" || busySlashCommand === "/switch";
|
|
7163
|
+
const isBusyLocalSlash = busySlashCommand === "/context" || busySlashCommand === "/ctx" || busySlashCommand === "/switch" || busySlashCommand === "/theme" || busySlashCommand === "/density" || busySlashCommand === "/runtime" || busySlashCommand === "/tools" || busySlashCommand === "/tasks" || busySlashCommand === "/jobs" || busySlashCommand === "/procs" || busySlashCommand === "/agents" || busySlashCommand === "/doc" || busySlashCommand === "/skill" || busySlashCommand === "/customize" || busySlashCommand === "/login" || busySlashCommand === "/profile" || busySlashCommand === "/version";
|
|
6623
7164
|
if (isBusyLocalSlash) {
|
|
7165
|
+
releaseCollapsedPasteReferences(submittedText, pasteStore);
|
|
7166
|
+
buffer = "";
|
|
7167
|
+
cursorPos = 0;
|
|
7168
|
+
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
6624
7169
|
const beforeAgentKey = state.agentKey;
|
|
6625
7170
|
const res = handleTuiInput(submittedText, state);
|
|
6626
|
-
if (res.action) {
|
|
7171
|
+
if (res.action?.type === "theme-refresh") {
|
|
7172
|
+
state = res.nextState;
|
|
7173
|
+
const detected2 = await detectTerminalBackground({
|
|
7174
|
+
stdin: input,
|
|
7175
|
+
stdout: output,
|
|
7176
|
+
allowSystemFallback: true
|
|
7177
|
+
});
|
|
7178
|
+
let refreshMsg = "";
|
|
7179
|
+
if (detected2 && applyDetectedBackground(detected2)) {
|
|
7180
|
+
refreshMsg = t("themeRefreshed", detected2.brightness);
|
|
7181
|
+
} else if (detected2) {
|
|
7182
|
+
refreshMsg = t("themeRefreshed", detected2.brightness);
|
|
7183
|
+
} else {
|
|
7184
|
+
refreshMsg = t("themeRefreshFailed");
|
|
7185
|
+
}
|
|
7186
|
+
if (refreshMsg) {
|
|
7187
|
+
output.write(`${refreshMsg}
|
|
7188
|
+
`);
|
|
7189
|
+
}
|
|
7190
|
+
} else if (res.action) {
|
|
6627
7191
|
output.write(
|
|
6628
7192
|
"Model picker isn't available while a reply is running. Use `/switch <name>` to switch now (takes effect on the next turn), or wait for the reply to finish.\n"
|
|
6629
7193
|
);
|
|
6630
7194
|
} else {
|
|
6631
7195
|
state = res.nextState;
|
|
6632
7196
|
let msg = res.output;
|
|
6633
|
-
if (busySlashCommand === "/switch" &&
|
|
7197
|
+
if (busySlashCommand === "/switch" && persistExplicitAgentSwitch(beforeAgentKey)) {
|
|
6634
7198
|
const hint = "Note: the new model takes effect on the next turn. Switching models may consume more tokens because the conversation context is re-sent to the new model.";
|
|
6635
7199
|
msg = msg ? `${msg}
|
|
6636
7200
|
${hint}` : hint;
|
|
@@ -6640,43 +7204,10 @@ ${hint}` : hint;
|
|
|
6640
7204
|
`);
|
|
6641
7205
|
}
|
|
6642
7206
|
}
|
|
6643
|
-
releaseCollapsedPasteReferences(submittedText, pasteStore);
|
|
6644
|
-
buffer = "";
|
|
6645
|
-
cursorPos = 0;
|
|
6646
|
-
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
6647
7207
|
return;
|
|
6648
7208
|
}
|
|
6649
|
-
const
|
|
6650
|
-
|
|
6651
|
-
modalOwnsKeyboard = true;
|
|
6652
|
-
try {
|
|
6653
|
-
return await waitForRawActionGate(input, output, gate, spawnRunner, {
|
|
6654
|
-
beforeSubprocess: () => fixedInput.pause(),
|
|
6655
|
-
afterSubprocess: () => fixedInput.resumeFromSubprocess(),
|
|
6656
|
-
registerToken: (handler) => {
|
|
6657
|
-
rawActionGateTokenHandler = handler;
|
|
6658
|
-
}
|
|
6659
|
-
});
|
|
6660
|
-
} finally {
|
|
6661
|
-
modalOwnsKeyboard = false;
|
|
6662
|
-
}
|
|
6663
|
-
},
|
|
6664
|
-
async (request) => {
|
|
6665
|
-
modalOwnsKeyboard = true;
|
|
6666
|
-
try {
|
|
6667
|
-
return await dialogHost.run(
|
|
6668
|
-
(anchor) => runConfirmDialog({
|
|
6669
|
-
request,
|
|
6670
|
-
input,
|
|
6671
|
-
output,
|
|
6672
|
-
...anchor
|
|
6673
|
-
})
|
|
6674
|
-
);
|
|
6675
|
-
} finally {
|
|
6676
|
-
modalOwnsKeyboard = false;
|
|
6677
|
-
}
|
|
6678
|
-
}
|
|
6679
|
-
);
|
|
7209
|
+
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
7210
|
+
const binding = ensureChatQueueBinding(actionGateHandler, confirmDestructiveAction);
|
|
6680
7211
|
const decision = binding.resolveSubmit({
|
|
6681
7212
|
text: submittedText,
|
|
6682
7213
|
isRunning: true
|
|
@@ -6693,62 +7224,13 @@ ${hint}` : hint;
|
|
|
6693
7224
|
return;
|
|
6694
7225
|
}
|
|
6695
7226
|
if (!submittedText.trim() && chatQueueBinding && chatQueueBinding.queueLength() > 0) {
|
|
6696
|
-
const actionGateHandler =
|
|
6697
|
-
modalOwnsKeyboard = true;
|
|
6698
|
-
try {
|
|
6699
|
-
return await waitForRawActionGate(input, output, gate, spawnRunner, {
|
|
6700
|
-
beforeSubprocess: () => fixedInput.pause(),
|
|
6701
|
-
afterSubprocess: () => fixedInput.resumeFromSubprocess(),
|
|
6702
|
-
registerToken: (handler) => {
|
|
6703
|
-
rawActionGateTokenHandler = handler;
|
|
6704
|
-
}
|
|
6705
|
-
});
|
|
6706
|
-
} finally {
|
|
6707
|
-
modalOwnsKeyboard = false;
|
|
6708
|
-
}
|
|
6709
|
-
};
|
|
6710
|
-
const confirmDestructiveAction = async (request) => {
|
|
6711
|
-
modalOwnsKeyboard = true;
|
|
6712
|
-
try {
|
|
6713
|
-
return await dialogHost.run(
|
|
6714
|
-
(anchor) => runConfirmDialog({
|
|
6715
|
-
request,
|
|
6716
|
-
input,
|
|
6717
|
-
output,
|
|
6718
|
-
...anchor
|
|
6719
|
-
})
|
|
6720
|
-
);
|
|
6721
|
-
} finally {
|
|
6722
|
-
modalOwnsKeyboard = false;
|
|
6723
|
-
}
|
|
6724
|
-
};
|
|
7227
|
+
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
6725
7228
|
const manualBinding = ensureChatQueueBinding(actionGateHandler, confirmDestructiveAction);
|
|
6726
7229
|
const drainedText = manualBinding.drainHeadForManualTurn();
|
|
6727
7230
|
if (drainedText !== null) {
|
|
6728
|
-
busy = true;
|
|
6729
7231
|
buffer = "";
|
|
6730
7232
|
cursorPos = 0;
|
|
6731
|
-
|
|
6732
|
-
try {
|
|
6733
|
-
const outcome = await runOneAgentTurn(
|
|
6734
|
-
drainedText,
|
|
6735
|
-
[],
|
|
6736
|
-
actionGateHandler,
|
|
6737
|
-
confirmDestructiveAction
|
|
6738
|
-
);
|
|
6739
|
-
await manualBinding.notifyTurnEnd(outcome);
|
|
6740
|
-
} catch (err) {
|
|
6741
|
-
await manualBinding.notifyTurnEnd({ ok: false, aborted: false });
|
|
6742
|
-
emitCommandOutput(
|
|
6743
|
-
`${t("turnFailed")}${err instanceof Error && err.message ? `
|
|
6744
|
-
${err.message}` : ""}`
|
|
6745
|
-
);
|
|
6746
|
-
} finally {
|
|
6747
|
-
busy = false;
|
|
6748
|
-
}
|
|
6749
|
-
refreshGitStatus();
|
|
6750
|
-
flushPendingRender();
|
|
6751
|
-
fixedInput.exitOutputMode(buffer, cursorPos);
|
|
7233
|
+
await runIdleTextTurn(drainedText);
|
|
6752
7234
|
return;
|
|
6753
7235
|
}
|
|
6754
7236
|
}
|
|
@@ -6758,37 +7240,11 @@ ${err.message}` : ""}`
|
|
|
6758
7240
|
fixedInput.enterOutputMode(submittedText);
|
|
6759
7241
|
let shouldExit = false;
|
|
6760
7242
|
try {
|
|
7243
|
+
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
6761
7244
|
shouldExit = await runSubmittedLine(
|
|
6762
7245
|
submittedText,
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
try {
|
|
6766
|
-
return await waitForRawActionGate(input, output, gate, spawnRunner, {
|
|
6767
|
-
beforeSubprocess: () => fixedInput.pause(),
|
|
6768
|
-
afterSubprocess: () => fixedInput.resumeFromSubprocess(),
|
|
6769
|
-
registerToken: (handler) => {
|
|
6770
|
-
rawActionGateTokenHandler = handler;
|
|
6771
|
-
}
|
|
6772
|
-
});
|
|
6773
|
-
} finally {
|
|
6774
|
-
modalOwnsKeyboard = false;
|
|
6775
|
-
}
|
|
6776
|
-
},
|
|
6777
|
-
async (request) => {
|
|
6778
|
-
modalOwnsKeyboard = true;
|
|
6779
|
-
try {
|
|
6780
|
-
return await dialogHost.run(
|
|
6781
|
-
(anchor) => runConfirmDialog({
|
|
6782
|
-
request,
|
|
6783
|
-
input,
|
|
6784
|
-
output,
|
|
6785
|
-
...anchor
|
|
6786
|
-
})
|
|
6787
|
-
);
|
|
6788
|
-
} finally {
|
|
6789
|
-
modalOwnsKeyboard = false;
|
|
6790
|
-
}
|
|
6791
|
-
}
|
|
7246
|
+
actionGateHandler,
|
|
7247
|
+
confirmDestructiveAction
|
|
6792
7248
|
);
|
|
6793
7249
|
} finally {
|
|
6794
7250
|
busy = false;
|
|
@@ -6871,7 +7327,6 @@ export {
|
|
|
6871
7327
|
applyOutputChunkToCurrentTurn,
|
|
6872
7328
|
applyScrollAction,
|
|
6873
7329
|
applyTerminalOutputToText,
|
|
6874
|
-
buildTuiRunOverlay,
|
|
6875
7330
|
buildWindowTitle,
|
|
6876
7331
|
countPhysicalLines,
|
|
6877
7332
|
createFixedInput,
|