nolo-cli 0.19.0 → 0.24.0-alpha.13
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/README.md +9 -18
- package/{_executeModel-X5PCIZN6.js → _executeModel-ZPNYAEFW.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-5ZV4433K.js} +27 -26
- package/{agentEmailCommands-2QJDGRMB.js → agentEmailCommands-Z7KOYDVQ.js} +57 -55
- package/{agentListCommands-6VEPTKBI.js → agentListCommands-UQUXJYUN.js} +30 -26
- package/{agentMachineCommands-NVVHNWYI.js → agentMachineCommands-53O6P6L5.js} +25 -24
- package/{agentRecordCommands-4GGRDMD4.js → agentRecordCommands-ZRYNBSSS.js} +52 -50
- package/{agentRunCommand-XOLQNKBZ.js → agentRunCommand-B73MKVOG.js} +55 -54
- package/{agentRunControl-Y5AFH5PQ.js → agentRunControl-SNUKXN6J.js} +6 -2
- package/{agentRuntimeLocal-7WYWCGL4.js → agentRuntimeLocal-GVNERRKQ.js} +21 -18
- package/{agentSlice-EAXPGEYV.js → agentSlice-OJBHIL34.js} +5 -5
- package/{appDeleteCommands-77KR2RJ4.js → appDeleteCommands-23Z3Z6KE.js} +23 -22
- package/{appDeployCommands-K7CAHGBI.js → appDeployCommands-3MFAR4Z7.js} +23 -22
- package/{appDeployStatusCommands-4OEKLTBT.js → appDeployStatusCommands-JHU6GSN4.js} +23 -22
- package/{appGetCommands-VM2WDLAZ.js → appGetCommands-24J55H2Y.js} +23 -22
- package/{appListCommands-GX6BBA6U.js → appListCommands-HE5KP3PH.js} +23 -22
- package/{authCommand-DY6UUL6O.js → authCommand-KGRK6MNU.js} +12 -13
- package/{authCommands-XTBV7OFZ.js → authCommands-JSOG2H4E.js} +4 -5
- package/{chunk-OWOHNGCN.js → chunk-2MBTWINN.js} +42 -3
- package/{chunk-MVQ4TBSD.js → chunk-54VHTARN.js} +1 -1
- package/{chunk-RQN4SEKL.js → chunk-5DWZ46RJ.js} +1 -1
- package/{chunk-VYHDJEQD.js → chunk-5EDKWSQN.js} +136 -78
- package/{chunk-Z4NR32XR.js → chunk-5RGU3J7P.js} +13 -0
- package/{chunk-7BUYEZ6U.js → chunk-7H3UTGPM.js} +12 -72
- package/{chunk-3ZX7PERL.js → chunk-AAWJ5S3G.js} +20 -7
- package/{chunk-SCTYAHYK.js → chunk-ADE6577S.js} +237 -142
- package/{chunk-PJSV3IZ5.js → chunk-AOPOTHFK.js} +1 -1
- package/{chunk-3ND52WIL.js → chunk-ATWUOTJP.js} +180 -24
- package/{chunk-SWDPIPOY.js → chunk-AZW5AHMW.js} +1 -1
- package/chunk-CF7S2RYZ.js +376 -0
- package/{chunk-L4F3I4SR.js → chunk-CV6BM7LU.js} +4 -6
- package/{chunk-G5U6LDLG.js → chunk-CWTT2NZ6.js} +6 -6
- package/{chunk-MKA6QE5E.js → chunk-CZHE6LLV.js} +135 -55
- package/{chunk-KFEVY3ST.js → chunk-D34RI6NI.js} +18 -8
- package/{chunk-XRZJGPFI.js → chunk-FON47ACC.js} +4 -4
- package/{chunk-K6EUAOW3.js → chunk-FXFGNOT2.js} +67 -1
- package/{chunk-LLWKHDG4.js → chunk-G36SUBHA.js} +14 -6
- package/{chunk-REA4JLBH.js → chunk-GD23ZX7Z.js} +7 -6
- package/{chunk-ROWQEJRP.js → chunk-GE6IWA5N.js} +12 -4
- package/{chunk-EDV7EBOI.js → chunk-GGB6MPHD.js} +2155 -1503
- package/{chunk-IYEXFJPC.js → chunk-GNGOZMU2.js} +64 -57
- package/{chunk-4T5F7YZQ.js → chunk-I6RJGORZ.js} +1 -1
- package/{chunk-DFCFMCY6.js → chunk-J2WT5CEO.js} +2 -2
- package/{chunk-AHCY2S2I.js → chunk-JJ2WUBFN.js} +1 -1
- package/{chunk-UGUW3FHG.js → chunk-JMSCXQUG.js} +2 -2
- package/{chunk-VDXCXCXH.js → chunk-KURQBS7S.js} +1 -1
- package/{chunk-FQZZLA3C.js → chunk-KXKQO4Q6.js} +17 -0
- package/{chunk-3Q7WHGCB.js → chunk-L65QKSVJ.js} +1 -1
- package/{chunk-UAIVG4J6.js → chunk-LEHTC2FI.js} +1 -8
- package/{chunk-UBHAWFQ6.js → chunk-LLDGWLML.js} +42 -19
- package/{chunk-JLA4FXYC.js → chunk-MALVZUYL.js} +1 -1
- package/{chunk-N54HIJVJ.js → chunk-MCXQNEJ3.js} +101 -9
- 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-ELT65PZW.js → chunk-OXLLFZNF.js} +1 -1
- package/{chunk-YGW4G5W5.js → chunk-P3RZ6DHN.js} +133 -25
- package/{chunk-5MIDPSSK.js → chunk-PB7G5MAM.js} +3 -3
- package/{chunk-HEGV7BH3.js → chunk-PMCKFQYC.js} +1 -1
- package/{chunk-23FZYPLC.js → chunk-PTKI7TIN.js} +911 -1064
- package/{chunk-MHSGJW4Z.js → chunk-PXPISYEH.js} +44 -14
- package/{chunk-I2ZJKTG5.js → chunk-PY7VGC5M.js} +29 -10
- package/{chunk-PIZYJVHQ.js → chunk-RM464B7I.js} +4 -4
- package/{chunk-XHG22OEX.js → chunk-ROJI6DRT.js} +2 -2
- package/{chunk-VNAEBGDK.js → chunk-RZNYL4LW.js} +123 -26
- package/{chunk-RVOUXDFU.js → chunk-S6KVFOUG.js} +6 -34
- package/{chunk-BV4VEE3W.js → chunk-S7AV3NCK.js} +277 -357
- package/{chunk-R35XMF6F.js → chunk-SIUEKVK4.js} +484 -67
- package/{chunk-B5TOXZAK.js → chunk-SIZQB7BD.js} +1 -1
- package/{chunk-DFFIZ25G.js → chunk-SLOGKB7M.js} +4 -1
- package/{chunk-MPVYDS7I.js → chunk-TLYHUIWF.js} +3 -3
- package/{chunk-HWW2M4SN.js → chunk-TNM27YZ7.js} +5 -4
- package/{chunk-OK6YSWLH.js → chunk-TWA4L7J7.js} +1 -1
- package/chunk-UZ6XXCVR.js +50 -0
- package/{chunk-DKZFOK24.js → chunk-WCP5FDTF.js} +16 -304
- package/{chunk-TRT4I4UD.js → chunk-WSQLK2KR.js} +2 -2
- package/{chunk-FXUSIQC2.js → chunk-XNZJVYFS.js} +1 -1
- package/{chunk-V3ED5AWK.js → chunk-YJY7HODU.js} +27 -16
- package/chunk-YYLHWIW6.js +48 -0
- package/{chunk-CZ6NYQTV.js → chunk-ZFL3LTU7.js} +2 -2
- 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-PO62NUR7.js} +19 -18
- package/{createDialogAction-RB55KCLO.js → createDialogAction-ORFRYI3C.js} +22 -20
- package/{createPageAction-Y7343GLU.js → createPageAction-XWVMNTYH.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-XTJHROXM.js} +24 -23
- package/{dialogSlice-UQAXF23P.js → dialogSlice-DJXC53YW.js} +24 -18
- package/{docCreateCommands-I2EWZGCI.js → docCreateCommands-T2XRVXYS.js} +24 -27
- package/{docDeleteCommands-IZ45UZKG.js → docDeleteCommands-L7RXFXY3.js} +25 -24
- package/{docReadCommands-R6Z4QJYU.js → docReadCommands-M5PYNADQ.js} +24 -23
- package/{docStore-5HOJ4D7D.js → docStore-6LKLLFDW.js} +20 -19
- package/{docUpdateCommands-2LRBKQPY.js → docUpdateCommands-OA5EGPLQ.js} +24 -27
- package/{fetchMessages-BMGVZVSE.js → fetchMessages-W4IKHPCS.js} +2 -3
- package/{getPricing-G7DLAST6.js → getPricing-6C3C47Y4.js} +3 -3
- package/{handleSendMessageAction-Q4HY35WX.js → handleSendMessageAction-ILFGZTN5.js} +23 -20
- package/index.js +74 -74
- package/{localDialogRead-4H3QJFLW.js → localDialogRead-JXTAHW2E.js} +2 -2
- package/{machineCommands-PKBPQKTY.js → machineCommands-AKAQGPAO.js} +59 -57
- package/{machineWsRunDispatch-UZAW4OXJ.js → machineWsRunDispatch-RSBERM64.js} +51 -49
- package/{models-DJFSJ7SW.js → models-ILWKIX2Y.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-TUH3SFHO.js} +937 -430
- package/{removeDialogAgentAction-OAGA2G3U.js → removeDialogAgentAction-QCFGIUIH.js} +8 -7
- package/{runAgentClientLoop-NBPIKJ6J.js → runAgentClientLoop-C3QB2EXV.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-SXYOFGUJ.js} +25 -24
- package/{spaceSlice-ZXLLG3CR.js → spaceSlice-6BHMRP5O.js} +21 -18
- package/{streamAgentChatTurn-L3YW6LSB.js → streamAgentChatTurn-GF5W5OIP.js} +140 -98
- package/switchDialogAgentAction-4OAC6QRN.js +61 -0
- package/{tableCommands-BEQAGE4I.js → tableCommands-QSZILI7I.js} +1 -1
- package/{toolApiClient-QI3YBNWB.js → toolApiClient-ISM4ZQX4.js} +2 -2
- package/{tools-ECGXR5QF.js → tools-KBCLJ43G.js} +36 -33
- package/{tuiSummaryLlmCaller-OMSCNHXA.js → tuiSummaryLlmCaller-ARIMGILF.js} +6 -6
- package/{updateCommands-XTW55TOT.js → updateCommands-AK2RDOFR.js} +8 -2
- package/{updateDialogTitleAction-HQ2EUDFT.js → updateDialogTitleAction-LMHZUY4Q.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-YJY7HODU.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-S7AV3NCK.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-TNM27YZ7.js";
|
|
72
|
+
import "./chunk-ID4G2MAR.js";
|
|
79
73
|
import {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
} from "./chunk-DFCFMCY6.js";
|
|
74
|
+
listUserRecordsFromServers,
|
|
75
|
+
readLiveDbRecordAfterTombstoneMerge
|
|
76
|
+
} from "./chunk-PMCKFQYC.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-PTKI7TIN.js";
|
|
85
|
+
import "./chunk-TWA4L7J7.js";
|
|
86
|
+
import {
|
|
87
|
+
getReadableCliDb
|
|
88
|
+
} from "./chunk-WFHXMLHZ.js";
|
|
89
|
+
import {
|
|
90
|
+
deleteDbRecord,
|
|
91
|
+
queryUserRecords,
|
|
92
|
+
readDbRecord
|
|
93
|
+
} from "./chunk-J2WT5CEO.js";
|
|
94
|
+
import "./chunk-AZW5AHMW.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-ZFL3LTU7.js";
|
|
105
|
+
import "./chunk-XNZJVYFS.js";
|
|
106
|
+
import "./chunk-GGB6MPHD.js";
|
|
109
107
|
import "./chunk-RQSOAMPJ.js";
|
|
110
|
-
import "./chunk-
|
|
108
|
+
import "./chunk-I6RJGORZ.js";
|
|
109
|
+
import "./chunk-AAWJ5S3G.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-CWTT2NZ6.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-GNGOZMU2.js";
|
|
127
119
|
import {
|
|
128
120
|
extractReferenceKeysFromMessage
|
|
129
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-ADE6577S.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-GD23ZX7Z.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-SIUEKVK4.js";
|
|
152
148
|
import "./chunk-ZNFJWEN4.js";
|
|
153
|
-
import "./chunk-
|
|
149
|
+
import "./chunk-MCXQNEJ3.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-P3RZ6DHN.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-PXPISYEH.js";
|
|
165
|
+
import "./chunk-WCP5FDTF.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-PY7VGC5M.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-LEHTC2FI.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,22 @@ 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 {
|
|
214
|
+
checkForCliUpdate,
|
|
221
215
|
runSelfUpdate
|
|
222
|
-
} from "./chunk-
|
|
216
|
+
} from "./chunk-FXFGNOT2.js";
|
|
223
217
|
import {
|
|
224
218
|
saveProfileAgentSelection,
|
|
225
219
|
saveProfileLocale
|
|
226
|
-
} from "./chunk-
|
|
220
|
+
} from "./chunk-GE6IWA5N.js";
|
|
227
221
|
import {
|
|
228
222
|
readPipeText,
|
|
229
223
|
spawnProcess
|
|
@@ -237,27 +231,31 @@ import {
|
|
|
237
231
|
import {
|
|
238
232
|
DEFAULT_NOLO_SERVER_URL
|
|
239
233
|
} from "./chunk-OLZBQWZU.js";
|
|
240
|
-
import "./chunk-
|
|
241
|
-
import "./chunk-
|
|
242
|
-
import "./chunk-
|
|
243
|
-
import "./chunk-
|
|
234
|
+
import "./chunk-G36SUBHA.js";
|
|
235
|
+
import "./chunk-CZHE6LLV.js";
|
|
236
|
+
import "./chunk-JMSCXQUG.js";
|
|
237
|
+
import "./chunk-S6KVFOUG.js";
|
|
244
238
|
import "./chunk-Y5GCAMGP.js";
|
|
239
|
+
import "./chunk-UZ6XXCVR.js";
|
|
245
240
|
import "./chunk-KX6YBIHG.js";
|
|
246
|
-
import "./chunk-
|
|
247
|
-
import "./chunk-
|
|
241
|
+
import "./chunk-OXLLFZNF.js";
|
|
242
|
+
import "./chunk-FON47ACC.js";
|
|
243
|
+
import "./chunk-NRY4GCKJ.js";
|
|
248
244
|
import "./chunk-WWC7I6TA.js";
|
|
249
245
|
import "./chunk-SKDNBYZK.js";
|
|
250
246
|
import "./chunk-I42VC5KR.js";
|
|
251
247
|
import {
|
|
252
248
|
asTrimmedLowercaseString
|
|
253
249
|
} from "./chunk-QSJ3HFEF.js";
|
|
254
|
-
import "./chunk-
|
|
255
|
-
import "./chunk-3ND52WIL.js";
|
|
250
|
+
import "./chunk-ATWUOTJP.js";
|
|
256
251
|
import "./chunk-XMLRJUU5.js";
|
|
257
252
|
import "./chunk-R5V5G73M.js";
|
|
258
253
|
import "./chunk-GBRG75BQ.js";
|
|
259
254
|
import "./chunk-3EUW3WEO.js";
|
|
260
255
|
import "./chunk-U6VC4MU4.js";
|
|
256
|
+
import {
|
|
257
|
+
extractCustomId
|
|
258
|
+
} from "./chunk-SLOGKB7M.js";
|
|
261
259
|
import "./chunk-KUG52IAP.js";
|
|
262
260
|
import "./chunk-LCBAMY2M.js";
|
|
263
261
|
import "./chunk-4SN6J65J.js";
|
|
@@ -526,6 +524,7 @@ async function compactDialog(options) {
|
|
|
526
524
|
dialogKey
|
|
527
525
|
);
|
|
528
526
|
let summaryGenerated = false;
|
|
527
|
+
let compactedMessageCount = 0;
|
|
529
528
|
if (options.summaryLlmCaller) {
|
|
530
529
|
const allMsgs = await readDialogMessages(
|
|
531
530
|
fetchImpl,
|
|
@@ -580,6 +579,7 @@ async function compactDialog(options) {
|
|
|
580
579
|
current.compressionCount = compressionCount + 1;
|
|
581
580
|
current.referenceKeys = Array.from(extractedKeys);
|
|
582
581
|
summaryGenerated = true;
|
|
582
|
+
compactedMessageCount = plan.compressCount;
|
|
583
583
|
console.log(
|
|
584
584
|
`[nolo] compact: compressed ${plan.compressCount} messages into summary (len: ${newSummary.trim().length})`
|
|
585
585
|
);
|
|
@@ -602,7 +602,8 @@ async function compactDialog(options) {
|
|
|
602
602
|
dialogId: extractCustomId(next.dbKey),
|
|
603
603
|
dialogKey: next.dbKey,
|
|
604
604
|
spaceId: typeof next.spaceId === "string" ? next.spaceId : void 0,
|
|
605
|
-
summaryGenerated
|
|
605
|
+
summaryGenerated,
|
|
606
|
+
compactedMessageCount
|
|
606
607
|
};
|
|
607
608
|
}
|
|
608
609
|
|
|
@@ -612,7 +613,7 @@ var DIALOG_CHECKED = "\u25C9";
|
|
|
612
613
|
var DIALOG_UNCHECKED = "\u25CB";
|
|
613
614
|
function renderDialogTitle(title, colorEnabled = resolveCliColorEnabled()) {
|
|
614
615
|
if (!colorEnabled) return title;
|
|
615
|
-
return
|
|
616
|
+
return `${themeColorSequence("accent")}${title}\x1B[0m`;
|
|
616
617
|
}
|
|
617
618
|
function renderDialogRow(args, colorEnabled = resolveCliColorEnabled()) {
|
|
618
619
|
const marker = args.focused ? DIALOG_CURSOR : " ";
|
|
@@ -620,7 +621,7 @@ function renderDialogRow(args, colorEnabled = resolveCliColorEnabled()) {
|
|
|
620
621
|
const detail = args.detail ? ` ${themeText(args.detail, "muted", colorEnabled)}` : "";
|
|
621
622
|
const row = `${marker} ${checkbox}${args.label}${detail}`;
|
|
622
623
|
if (!args.focused || !colorEnabled) return row;
|
|
623
|
-
return `${surfaceBackgroundSequence()}${themeColorSequence("accent")}
|
|
624
|
+
return `${surfaceBackgroundSequence()}${themeColorSequence("accent")}${row}\x1B[0m`;
|
|
624
625
|
}
|
|
625
626
|
function renderDialogOverflow(text, colorEnabled = resolveCliColorEnabled()) {
|
|
626
627
|
return themeText(` ${text}`, "chrome", colorEnabled);
|
|
@@ -1328,7 +1329,7 @@ function renderTabBar(questions, activeIndex, colorEnabled) {
|
|
|
1328
1329
|
const tabs = questions.map((q, i) => {
|
|
1329
1330
|
const label = `Q${i + 1}`;
|
|
1330
1331
|
if (i === activeIndex) {
|
|
1331
|
-
return colorEnabled ? `${themeColorSequence("accent")}
|
|
1332
|
+
return colorEnabled ? `${themeColorSequence("accent")} ${label} \x1B[0m` : `[${label}]`;
|
|
1332
1333
|
}
|
|
1333
1334
|
return colorEnabled ? themeText(` ${label} `, "muted", colorEnabled) : ` ${label} `;
|
|
1334
1335
|
});
|
|
@@ -1395,7 +1396,7 @@ function renderAskChoiceFrame(state) {
|
|
|
1395
1396
|
const plainRow = `${plainPrefix}${qs.otherText}`;
|
|
1396
1397
|
if (focused && colorEnabled) {
|
|
1397
1398
|
lines.push(
|
|
1398
|
-
|
|
1399
|
+
`${themeColorSequence("accent")}${plainRow}\x1B[0m`
|
|
1399
1400
|
);
|
|
1400
1401
|
} else {
|
|
1401
1402
|
lines.push(plainRow);
|
|
@@ -2159,6 +2160,7 @@ function createRunRegistryPoller(deps) {
|
|
|
2159
2160
|
return;
|
|
2160
2161
|
}
|
|
2161
2162
|
const alive = /* @__PURE__ */ new Set();
|
|
2163
|
+
const polled = [];
|
|
2162
2164
|
for (const run of active) {
|
|
2163
2165
|
alive.add(run.runId);
|
|
2164
2166
|
let record;
|
|
@@ -2172,6 +2174,7 @@ function createRunRegistryPoller(deps) {
|
|
|
2172
2174
|
continue;
|
|
2173
2175
|
}
|
|
2174
2176
|
if (!record) continue;
|
|
2177
|
+
polled.push(record);
|
|
2175
2178
|
const snapshot = snapshotFromRunRecord(record, at);
|
|
2176
2179
|
const mark = fingerprint(snapshot);
|
|
2177
2180
|
if (lastEmitted.get(run.runId) === mark) continue;
|
|
@@ -2184,6 +2187,12 @@ function createRunRegistryPoller(deps) {
|
|
|
2184
2187
|
for (const runId of [...lastReconciledAt.keys()]) {
|
|
2185
2188
|
if (!alive.has(runId)) lastReconciledAt.delete(runId);
|
|
2186
2189
|
}
|
|
2190
|
+
if (polled.length > 0 && deps.onRecordsPolled) {
|
|
2191
|
+
try {
|
|
2192
|
+
deps.onRecordsPolled(polled);
|
|
2193
|
+
} catch {
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2187
2196
|
};
|
|
2188
2197
|
return {
|
|
2189
2198
|
ensureRunning() {
|
|
@@ -2199,6 +2208,163 @@ function createRunRegistryPoller(deps) {
|
|
|
2199
2208
|
};
|
|
2200
2209
|
}
|
|
2201
2210
|
|
|
2211
|
+
// packages/core/chat/internalTurnEvent.ts
|
|
2212
|
+
function normalizeRunCompletionShape(record) {
|
|
2213
|
+
const runId = String(record.runId ?? record.id ?? "");
|
|
2214
|
+
const agentKey = String(record.agentKey ?? record.agent ?? "");
|
|
2215
|
+
const status = String(record.status ?? "done");
|
|
2216
|
+
const counters = record.activity?.counters;
|
|
2217
|
+
return {
|
|
2218
|
+
runId,
|
|
2219
|
+
agentKey,
|
|
2220
|
+
...typeof record.agentName === "string" ? { agentName: record.agentName } : {},
|
|
2221
|
+
status,
|
|
2222
|
+
...typeof record.exitCode === "number" ? { exitCode: record.exitCode } : {},
|
|
2223
|
+
...typeof record.parentDialogId === "string" ? { parentDialogId: record.parentDialogId } : {},
|
|
2224
|
+
...typeof record.dialogId === "string" ? { dialogId: record.dialogId } : {},
|
|
2225
|
+
...typeof record.ephemeral === "boolean" ? { ephemeral: record.ephemeral } : {},
|
|
2226
|
+
...record.startedAt !== void 0 ? { startedAt: record.startedAt } : {},
|
|
2227
|
+
...record.endedAt !== void 0 ? { endedAt: record.endedAt } : {},
|
|
2228
|
+
...typeof record.note === "string" ? { note: record.note } : {},
|
|
2229
|
+
...typeof record.error === "string" ? { error: record.error } : {},
|
|
2230
|
+
...typeof record.ack === "boolean" ? { ack: record.ack } : {},
|
|
2231
|
+
...counters ? {
|
|
2232
|
+
activity: {
|
|
2233
|
+
counters: {
|
|
2234
|
+
toolCalls: typeof counters.toolCalls === "number" ? counters.toolCalls : 0,
|
|
2235
|
+
llmCalls: typeof counters.llmCalls === "number" ? counters.llmCalls : 0,
|
|
2236
|
+
fileEdits: typeof counters.fileEdits === "number" ? counters.fileEdits : 0
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
} : {}
|
|
2240
|
+
};
|
|
2241
|
+
}
|
|
2242
|
+
function createTurnRequest(input) {
|
|
2243
|
+
if (typeof input === "string") {
|
|
2244
|
+
return {
|
|
2245
|
+
event: { kind: "user", text: input },
|
|
2246
|
+
text: input
|
|
2247
|
+
};
|
|
2248
|
+
}
|
|
2249
|
+
if ("event" in input && typeof input.event === "object" && typeof input.text === "string") {
|
|
2250
|
+
return input;
|
|
2251
|
+
}
|
|
2252
|
+
const event = input;
|
|
2253
|
+
return {
|
|
2254
|
+
event,
|
|
2255
|
+
text: event.text
|
|
2256
|
+
};
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
// packages/cli/tui/runCompletionWatcher.ts
|
|
2260
|
+
var WAKE_NOTE_MAX_CHARS = 300;
|
|
2261
|
+
function createRunCompletionWatcher(deps) {
|
|
2262
|
+
const now = deps.now ?? (() => Date.now());
|
|
2263
|
+
const createdAt = now();
|
|
2264
|
+
const lastStatusByRunId = /* @__PURE__ */ new Map();
|
|
2265
|
+
const notifiedRunIds = /* @__PURE__ */ new Set();
|
|
2266
|
+
const describeRun = (record) => {
|
|
2267
|
+
const lines = [
|
|
2268
|
+
`runId: ${record.runId}`,
|
|
2269
|
+
`agent: ${resolveRunLabel(record)}`,
|
|
2270
|
+
`status: ${record.status}`
|
|
2271
|
+
];
|
|
2272
|
+
if (typeof record.exitCode === "number") {
|
|
2273
|
+
lines.push(`exitCode: ${record.exitCode}`);
|
|
2274
|
+
}
|
|
2275
|
+
if (record.dialogId) {
|
|
2276
|
+
lines.push(`childDialogId: ${record.dialogId}`);
|
|
2277
|
+
} else if (record.ephemeral) {
|
|
2278
|
+
lines.push(`ephemeral: true (no persisted child dialog)`);
|
|
2279
|
+
} else {
|
|
2280
|
+
lines.push(`childDialogId: missing (result unpersisted or ephemeral)`);
|
|
2281
|
+
}
|
|
2282
|
+
const duration = formatRunAge(
|
|
2283
|
+
{
|
|
2284
|
+
startedAt: readTimestamp(record.startedAt),
|
|
2285
|
+
finishedAt: readTimestamp(record.endedAt ?? record.finishedAt)
|
|
2286
|
+
},
|
|
2287
|
+
now()
|
|
2288
|
+
);
|
|
2289
|
+
if (duration) lines.push(`duration: ${duration}`);
|
|
2290
|
+
const recordError = "error" in record && typeof record.error === "string" ? record.error : void 0;
|
|
2291
|
+
const note = typeof record.note === "string" ? clipText(record.note, WAKE_NOTE_MAX_CHARS) : typeof recordError === "string" ? clipText(recordError, WAKE_NOTE_MAX_CHARS) : "";
|
|
2292
|
+
if (note) lines.push(`note: ${note}`);
|
|
2293
|
+
const counters = record.activity?.counters;
|
|
2294
|
+
if (counters && typeof counters.toolCalls === "number" && typeof counters.llmCalls === "number" && typeof counters.fileEdits === "number") {
|
|
2295
|
+
lines.push(
|
|
2296
|
+
`activity: ${counters.toolCalls} tool calls \xB7 ${counters.llmCalls} llm calls \xB7 ${counters.fileEdits} edits`
|
|
2297
|
+
);
|
|
2298
|
+
}
|
|
2299
|
+
return lines;
|
|
2300
|
+
};
|
|
2301
|
+
const buildWakeMessage = (finished) => {
|
|
2302
|
+
const lines = [
|
|
2303
|
+
`\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`
|
|
2304
|
+
];
|
|
2305
|
+
for (const record of finished) {
|
|
2306
|
+
lines.push("", ...describeRun(record));
|
|
2307
|
+
}
|
|
2308
|
+
lines.push(
|
|
2309
|
+
"",
|
|
2310
|
+
'\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'
|
|
2311
|
+
);
|
|
2312
|
+
return lines.join("\n");
|
|
2313
|
+
};
|
|
2314
|
+
return {
|
|
2315
|
+
observe(records) {
|
|
2316
|
+
const finished = [];
|
|
2317
|
+
const currentDialogId = deps.getCurrentDialogId();
|
|
2318
|
+
for (const rawRecord of records) {
|
|
2319
|
+
try {
|
|
2320
|
+
if (!rawRecord || typeof rawRecord.runId !== "string" || !rawRecord.runId) continue;
|
|
2321
|
+
const record = rawRecord;
|
|
2322
|
+
if (notifiedRunIds.has(record.runId)) continue;
|
|
2323
|
+
if (record.ack === true) {
|
|
2324
|
+
notifiedRunIds.add(record.runId);
|
|
2325
|
+
continue;
|
|
2326
|
+
}
|
|
2327
|
+
const status = record.status;
|
|
2328
|
+
if (typeof status !== "string") continue;
|
|
2329
|
+
if (record.parentDialogId !== currentDialogId) continue;
|
|
2330
|
+
const previous = lastStatusByRunId.get(record.runId);
|
|
2331
|
+
lastStatusByRunId.set(record.runId, status);
|
|
2332
|
+
if (!isAgentRunTerminalStatus(status)) continue;
|
|
2333
|
+
if (previous === void 0) {
|
|
2334
|
+
const startedMs = readTimestamp(record.startedAt);
|
|
2335
|
+
if (startedMs === void 0 || startedMs < createdAt) continue;
|
|
2336
|
+
} else if (isAgentRunTerminalStatus(previous)) {
|
|
2337
|
+
continue;
|
|
2338
|
+
}
|
|
2339
|
+
notifiedRunIds.add(record.runId);
|
|
2340
|
+
finished.push(record);
|
|
2341
|
+
} catch {
|
|
2342
|
+
continue;
|
|
2343
|
+
}
|
|
2344
|
+
}
|
|
2345
|
+
if (finished.length === 0) return;
|
|
2346
|
+
const shapes = finished.map((r) => normalizeRunCompletionShape(r));
|
|
2347
|
+
const summaryText = buildWakeMessage(finished);
|
|
2348
|
+
const event = {
|
|
2349
|
+
kind: "child-run-completed",
|
|
2350
|
+
runs: shapes,
|
|
2351
|
+
text: summaryText
|
|
2352
|
+
};
|
|
2353
|
+
deps.onWake(event);
|
|
2354
|
+
},
|
|
2355
|
+
markAcknowledged(runId) {
|
|
2356
|
+
if (runId) notifiedRunIds.add(runId);
|
|
2357
|
+
},
|
|
2358
|
+
isAcknowledged(runId) {
|
|
2359
|
+
return Boolean(runId && notifiedRunIds.has(runId));
|
|
2360
|
+
},
|
|
2361
|
+
dispose() {
|
|
2362
|
+
lastStatusByRunId.clear();
|
|
2363
|
+
notifiedRunIds.clear();
|
|
2364
|
+
}
|
|
2365
|
+
};
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2202
2368
|
// packages/ai/agent/utils/sortUtils.ts
|
|
2203
2369
|
function sortAgentsFavoriteOwnedPublic(items) {
|
|
2204
2370
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -2245,7 +2411,7 @@ function sortAgentsFavoriteOwnedPublic(items) {
|
|
|
2245
2411
|
}
|
|
2246
2412
|
|
|
2247
2413
|
// packages/cli/tui/agentCatalog.ts
|
|
2248
|
-
var DEFAULT_TUI_AGENT_KEY =
|
|
2414
|
+
var DEFAULT_TUI_AGENT_KEY = NOLO_DEFAULT_AGENT_KEY;
|
|
2249
2415
|
function formatAgentSourceLabel(entry) {
|
|
2250
2416
|
if (entry.kind === "platform" || entry.apiSource === "platform") return t("agentSourcePlatform");
|
|
2251
2417
|
if (entry.apiSource === "cli") {
|
|
@@ -2261,13 +2427,6 @@ var PLATFORM_AGENTS = [
|
|
|
2261
2427
|
model: "-",
|
|
2262
2428
|
kind: "platform",
|
|
2263
2429
|
description: "one assistant that routes work across your agents and data"
|
|
2264
|
-
},
|
|
2265
|
-
{
|
|
2266
|
-
name: "app-builder",
|
|
2267
|
-
key: "agent-pub-01APPBUILDER00000001YAII3I",
|
|
2268
|
-
model: "-",
|
|
2269
|
-
kind: "platform",
|
|
2270
|
-
description: "builds web apps, tools, charts, and product prototypes"
|
|
2271
2430
|
}
|
|
2272
2431
|
];
|
|
2273
2432
|
var AUTO_ROUTE_CATALOG_ENTRY = {
|
|
@@ -2316,7 +2475,7 @@ function mergeCatalogEntries(currentKey, platformAgents, privateAgents, favorite
|
|
|
2316
2475
|
}
|
|
2317
2476
|
const sortablePrivate = privateAgents.map((entry) => ({
|
|
2318
2477
|
key: entry.key,
|
|
2319
|
-
favoritedAt: favoritedAtByKey[entry.key],
|
|
2478
|
+
...favoritedAtByKey[entry.key] !== void 0 ? { favoritedAt: favoritedAtByKey[entry.key] } : {},
|
|
2320
2479
|
isOwned: true,
|
|
2321
2480
|
updatedAt: entry.updatedAt ?? 0
|
|
2322
2481
|
}));
|
|
@@ -2384,9 +2543,15 @@ function refreshAgentCatalogInBackground(args, env, cacheKey) {
|
|
|
2384
2543
|
agentCatalogRefreshInFlight = null;
|
|
2385
2544
|
});
|
|
2386
2545
|
}
|
|
2546
|
+
async function prefillCatalogFromLocalDb(_args) {
|
|
2547
|
+
}
|
|
2387
2548
|
function prefetchAgentCatalog(args) {
|
|
2388
|
-
void
|
|
2389
|
-
|
|
2549
|
+
void (async () => {
|
|
2550
|
+
await prefillCatalogFromLocalDb({ env: args.env, getDb: args.getDb }).catch(() => {
|
|
2551
|
+
});
|
|
2552
|
+
void loadAgentCatalog({ ...args, currentKey: "" }).catch(() => {
|
|
2553
|
+
});
|
|
2554
|
+
})();
|
|
2390
2555
|
}
|
|
2391
2556
|
async function fetchRawCatalogData(args, env) {
|
|
2392
2557
|
const fetchImpl = args.fetchImpl ?? fetch;
|
|
@@ -2398,7 +2563,7 @@ async function fetchRawCatalogData(args, env) {
|
|
|
2398
2563
|
}
|
|
2399
2564
|
const serverUrl = resolveServerUrl(env);
|
|
2400
2565
|
const serverUrls = resolveServerCandidates([], env, serverUrl);
|
|
2401
|
-
let
|
|
2566
|
+
let listedAgents = [];
|
|
2402
2567
|
const favoritesPromise = listFavoriteAgentIdsAcrossServers({
|
|
2403
2568
|
authToken,
|
|
2404
2569
|
fetchImpl,
|
|
@@ -2412,15 +2577,14 @@ async function fetchRawCatalogData(args, env) {
|
|
|
2412
2577
|
serverUrls,
|
|
2413
2578
|
userId
|
|
2414
2579
|
});
|
|
2415
|
-
|
|
2580
|
+
listedAgents = remoteResult.agents;
|
|
2416
2581
|
} catch {
|
|
2417
2582
|
try {
|
|
2418
2583
|
const db = await getReadableCliDb({ write: () => {
|
|
2419
2584
|
} });
|
|
2420
|
-
|
|
2421
|
-
privateAgents = cached.map(listedAgentToCatalogEntry);
|
|
2585
|
+
listedAgents = await listLocalCachedAgents({ db, userId });
|
|
2422
2586
|
} catch {
|
|
2423
|
-
|
|
2587
|
+
listedAgents = await listRemoteAgents({
|
|
2424
2588
|
authToken,
|
|
2425
2589
|
fallbackFetchImpl,
|
|
2426
2590
|
fetchImpl,
|
|
@@ -2428,10 +2592,47 @@ async function fetchRawCatalogData(args, env) {
|
|
|
2428
2592
|
userId,
|
|
2429
2593
|
queryUserRecords,
|
|
2430
2594
|
readDbRecord
|
|
2431
|
-
})
|
|
2595
|
+
});
|
|
2432
2596
|
}
|
|
2433
2597
|
}
|
|
2598
|
+
const privateAgents = listedAgents.map(listedAgentToCatalogEntry);
|
|
2434
2599
|
const favoritedAtByKey = await favoritesPromise;
|
|
2600
|
+
for (const agent of listedAgents) {
|
|
2601
|
+
const favoritedAt = [agent.privateKey, agent.publicKey, agent.id].map((key) => favoritedAtByKey[key]).find((value) => value !== void 0);
|
|
2602
|
+
if (favoritedAt !== void 0) favoritedAtByKey[agent.privateKey] = favoritedAt;
|
|
2603
|
+
}
|
|
2604
|
+
const existingKeys = /* @__PURE__ */ new Set();
|
|
2605
|
+
for (const agent of listedAgents) {
|
|
2606
|
+
existingKeys.add(agent.privateKey);
|
|
2607
|
+
existingKeys.add(agent.publicKey);
|
|
2608
|
+
existingKeys.add(agent.id);
|
|
2609
|
+
}
|
|
2610
|
+
await Promise.all(
|
|
2611
|
+
Object.keys(favoritedAtByKey).map(async (favKey) => {
|
|
2612
|
+
if (existingKeys.has(favKey)) return;
|
|
2613
|
+
try {
|
|
2614
|
+
const favRead = await readLiveDbRecordAfterTombstoneMerge({
|
|
2615
|
+
authToken,
|
|
2616
|
+
dbKey: favKey,
|
|
2617
|
+
fallbackFetchImpl,
|
|
2618
|
+
fetchImpl,
|
|
2619
|
+
serverUrls
|
|
2620
|
+
});
|
|
2621
|
+
const record = favRead.record;
|
|
2622
|
+
if (!record || record.type && record.type !== "agent") return;
|
|
2623
|
+
const norm = normalizeListedAgent(record);
|
|
2624
|
+
if (!norm) return;
|
|
2625
|
+
if (existingKeys.has(norm.privateKey) || existingKeys.has(norm.publicKey) || existingKeys.has(norm.id)) {
|
|
2626
|
+
return;
|
|
2627
|
+
}
|
|
2628
|
+
existingKeys.add(norm.privateKey);
|
|
2629
|
+
existingKeys.add(norm.publicKey);
|
|
2630
|
+
existingKeys.add(norm.id);
|
|
2631
|
+
privateAgents.push(listedAgentToCatalogEntry(norm));
|
|
2632
|
+
} catch {
|
|
2633
|
+
}
|
|
2634
|
+
})
|
|
2635
|
+
);
|
|
2435
2636
|
return { privateAgents, favoritedAtByKey };
|
|
2436
2637
|
}
|
|
2437
2638
|
function renderAgentCatalogList(entries, currentKey) {
|
|
@@ -3096,8 +3297,17 @@ function renderWelcome(state, frame = 0, maxFrames = 0, columns) {
|
|
|
3096
3297
|
const widestSceneCol = sceneArt.split("\n").reduce((max, line) => Math.max(max, displayWidth(stripAnsi(line))), 0);
|
|
3097
3298
|
if (columns < widestSceneCol) sceneArt = "";
|
|
3098
3299
|
}
|
|
3099
|
-
const versionLine = colorEnabled ?
|
|
3100
|
-
const
|
|
3300
|
+
const versionLine = colorEnabled ? `${themeColorSequence("accent")}nolo\x1B[0m ${state.cliVersion ?? ""} | server ${state.serverUrl}`.replace(" |", " |") : `nolo ${state.cliVersion ?? ""} | server ${state.serverUrl}`.replace(" |", " |");
|
|
3301
|
+
const updateLine = state.updateAvailable ? themeText(
|
|
3302
|
+
t(
|
|
3303
|
+
"updateAvailable",
|
|
3304
|
+
state.updateAvailable.latestVersion,
|
|
3305
|
+
state.cliVersion ?? t("versionUnknown")
|
|
3306
|
+
),
|
|
3307
|
+
"accent",
|
|
3308
|
+
colorEnabled
|
|
3309
|
+
) : null;
|
|
3310
|
+
const body = sceneArt ? [sceneArt, versionLine, ...updateLine ? [updateLine] : [], t("welcomeHint"), ""] : [versionLine, ...updateLine ? [updateLine] : [], t("welcomeHint"), ""];
|
|
3101
3311
|
return body.join("\n");
|
|
3102
3312
|
}
|
|
3103
3313
|
function renderPrompt(_state) {
|
|
@@ -3760,7 +3970,16 @@ function handleTuiInput(input, state) {
|
|
|
3760
3970
|
};
|
|
3761
3971
|
}
|
|
3762
3972
|
return {
|
|
3763
|
-
nextState:
|
|
3973
|
+
nextState: {
|
|
3974
|
+
...state,
|
|
3975
|
+
dialogId: void 0,
|
|
3976
|
+
dialogKey: void 0,
|
|
3977
|
+
dialogLabel: t("newDialog"),
|
|
3978
|
+
attachedDocs: [],
|
|
3979
|
+
attachedSkills: [],
|
|
3980
|
+
attachedImages: [],
|
|
3981
|
+
turnTokens: void 0
|
|
3982
|
+
},
|
|
3764
3983
|
output: t("clearingDialog"),
|
|
3765
3984
|
action: { type: "clear", dialogId: state.dialogId }
|
|
3766
3985
|
};
|
|
@@ -4127,52 +4346,65 @@ var initialChatQueueState = {
|
|
|
4127
4346
|
function reduceChatQueue(state, event) {
|
|
4128
4347
|
switch (event.type) {
|
|
4129
4348
|
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
|
-
}
|
|
4349
|
+
if (state.running && state.lastDrainError === null) return state;
|
|
4350
|
+
return {
|
|
4351
|
+
...state,
|
|
4352
|
+
running: true,
|
|
4353
|
+
lastDrainError: null
|
|
4354
|
+
};
|
|
4355
|
+
case "turn-end":
|
|
4142
4356
|
return {
|
|
4143
4357
|
...state,
|
|
4144
4358
|
running: false,
|
|
4145
|
-
|
|
4359
|
+
queue: event.aborted ? [] : state.queue,
|
|
4360
|
+
lastDrainError: !event.ok && !event.aborted ? "previous turn failed" : state.lastDrainError
|
|
4146
4361
|
};
|
|
4147
|
-
}
|
|
4148
4362
|
case "enqueue": {
|
|
4149
|
-
const
|
|
4150
|
-
if (!text)
|
|
4151
|
-
|
|
4363
|
+
const req = createTurnRequest(event.text);
|
|
4364
|
+
if (!req.text.trim() && req.event.kind === "user") {
|
|
4365
|
+
return state;
|
|
4366
|
+
}
|
|
4367
|
+
return {
|
|
4368
|
+
...state,
|
|
4369
|
+
queue: [...state.queue, req]
|
|
4370
|
+
};
|
|
4152
4371
|
}
|
|
4153
|
-
case "dequeue":
|
|
4372
|
+
case "dequeue":
|
|
4154
4373
|
if (state.queue.length === 0) return state;
|
|
4155
|
-
return {
|
|
4156
|
-
|
|
4374
|
+
return {
|
|
4375
|
+
...state,
|
|
4376
|
+
queue: state.queue.slice(1)
|
|
4377
|
+
};
|
|
4157
4378
|
case "clear":
|
|
4158
|
-
if (state.queue.length === 0 &&
|
|
4159
|
-
return {
|
|
4379
|
+
if (state.queue.length === 0 && state.lastDrainError === null) return state;
|
|
4380
|
+
return {
|
|
4381
|
+
...state,
|
|
4382
|
+
queue: [],
|
|
4383
|
+
lastDrainError: null
|
|
4384
|
+
};
|
|
4160
4385
|
case "pause-drain":
|
|
4161
4386
|
if (state.drainPaused) return state;
|
|
4162
|
-
return {
|
|
4387
|
+
return {
|
|
4388
|
+
...state,
|
|
4389
|
+
drainPaused: true
|
|
4390
|
+
};
|
|
4163
4391
|
case "resume-drain":
|
|
4164
4392
|
if (!state.drainPaused) return state;
|
|
4165
|
-
return {
|
|
4393
|
+
return {
|
|
4394
|
+
...state,
|
|
4395
|
+
drainPaused: false
|
|
4396
|
+
};
|
|
4166
4397
|
case "drain-error":
|
|
4167
|
-
return {
|
|
4168
|
-
|
|
4169
|
-
|
|
4398
|
+
return {
|
|
4399
|
+
...state,
|
|
4400
|
+
lastDrainError: event.message || null
|
|
4401
|
+
};
|
|
4402
|
+
default:
|
|
4170
4403
|
return state;
|
|
4171
|
-
}
|
|
4172
4404
|
}
|
|
4173
4405
|
}
|
|
4174
|
-
function shouldDrainAfterTurnEnd(state,
|
|
4175
|
-
return !state.running && !state.drainPaused && state.queue.length > 0
|
|
4406
|
+
function shouldDrainAfterTurnEnd(state, cleanTurnEnd) {
|
|
4407
|
+
return cleanTurnEnd && !state.running && !state.drainPaused && state.queue.length > 0;
|
|
4176
4408
|
}
|
|
4177
4409
|
function applyChatQueueEvent(state, event) {
|
|
4178
4410
|
const prevQueueLen = state.queue.length;
|
|
@@ -4191,7 +4423,8 @@ function applyChatQueueEvent(state, event) {
|
|
|
4191
4423
|
}
|
|
4192
4424
|
if (event.type === "turn-end" && !event.aborted && event.ok) {
|
|
4193
4425
|
if (shouldDrainAfterTurnEnd(next, true)) {
|
|
4194
|
-
|
|
4426
|
+
const head = next.queue[0];
|
|
4427
|
+
outgoing.push({ type: "drain-ready", text: head.text, request: head });
|
|
4195
4428
|
}
|
|
4196
4429
|
}
|
|
4197
4430
|
return { state: next, outgoing };
|
|
@@ -4273,7 +4506,8 @@ function projectChatQueueStatus({
|
|
|
4273
4506
|
}) {
|
|
4274
4507
|
const preview = [];
|
|
4275
4508
|
for (let i = 0; i < Math.min(maxPreview, state.queue.length); i++) {
|
|
4276
|
-
const
|
|
4509
|
+
const item = state.queue[i];
|
|
4510
|
+
const text = typeof item === "string" ? item : item?.text ?? "";
|
|
4277
4511
|
preview.push(text.length > previewCharLimit ? text.slice(0, previewCharLimit) + "\u2026" : text);
|
|
4278
4512
|
}
|
|
4279
4513
|
let composerPlaceholderKey = "default";
|
|
@@ -4312,10 +4546,19 @@ function createChatQueueTuiBinding(runTurn) {
|
|
|
4312
4546
|
isCompactDialogSlashCommand: (s) => s === "/compact"
|
|
4313
4547
|
});
|
|
4314
4548
|
};
|
|
4315
|
-
const enqueue = (
|
|
4316
|
-
runtime.send({ type: "enqueue", text });
|
|
4549
|
+
const enqueue = (input) => {
|
|
4550
|
+
runtime.send({ type: "enqueue", text: input });
|
|
4317
4551
|
return projectChatQueueStatus({ state: runtime.getState() });
|
|
4318
4552
|
};
|
|
4553
|
+
const enqueueAndMaybeRun = async (input) => {
|
|
4554
|
+
enqueue(input);
|
|
4555
|
+
const status = runtime.getState();
|
|
4556
|
+
if (!status.running && !status.drainPaused) {
|
|
4557
|
+
await notifyTurnEnd({ ok: true, aborted: false });
|
|
4558
|
+
return true;
|
|
4559
|
+
}
|
|
4560
|
+
return false;
|
|
4561
|
+
};
|
|
4319
4562
|
const notifyTurnStart = () => {
|
|
4320
4563
|
runtime.send({ type: "turn-start" });
|
|
4321
4564
|
};
|
|
@@ -4338,23 +4581,22 @@ function createChatQueueTuiBinding(runTurn) {
|
|
|
4338
4581
|
while (true) {
|
|
4339
4582
|
const status = runtime.getState();
|
|
4340
4583
|
if (!status.running && !status.drainPaused && status.queue.length > 0 && lastOk) {
|
|
4341
|
-
const
|
|
4584
|
+
const req = status.queue[0];
|
|
4342
4585
|
runtime.send({ type: "turn-start" });
|
|
4343
4586
|
runtime.send({ type: "dequeue" });
|
|
4344
4587
|
let turnOutcome;
|
|
4345
4588
|
try {
|
|
4346
|
-
turnOutcome = await runTurn(
|
|
4589
|
+
turnOutcome = await runTurn(req);
|
|
4347
4590
|
} catch {
|
|
4348
4591
|
turnOutcome = { ok: false, aborted: false };
|
|
4349
4592
|
}
|
|
4350
|
-
const
|
|
4351
|
-
|
|
4352
|
-
|
|
4593
|
+
const consumed = consumePreempt(turnOutcome);
|
|
4594
|
+
const effectiveTurnOutcome = consumed.outcome;
|
|
4595
|
+
runtime.send({ type: "turn-end", ...effectiveTurnOutcome });
|
|
4596
|
+
if (consumed.mode === "stop") {
|
|
4353
4597
|
runtime.send({ type: "drain-error", message: "" });
|
|
4354
4598
|
}
|
|
4355
|
-
lastOk =
|
|
4356
|
-
if (cascadeOutcome.aborted) break;
|
|
4357
|
-
if (!lastOk) break;
|
|
4599
|
+
lastOk = effectiveTurnOutcome.ok && !effectiveTurnOutcome.aborted;
|
|
4358
4600
|
} else {
|
|
4359
4601
|
break;
|
|
4360
4602
|
}
|
|
@@ -4362,11 +4604,11 @@ function createChatQueueTuiBinding(runTurn) {
|
|
|
4362
4604
|
};
|
|
4363
4605
|
const drainHeadForManualTurn = () => {
|
|
4364
4606
|
const status = runtime.getState();
|
|
4365
|
-
if (status.running || status.
|
|
4366
|
-
const
|
|
4607
|
+
if (status.running || status.queue.length === 0) return null;
|
|
4608
|
+
const head = status.queue[0];
|
|
4367
4609
|
runtime.send({ type: "turn-start" });
|
|
4368
4610
|
runtime.send({ type: "dequeue" });
|
|
4369
|
-
return
|
|
4611
|
+
return head;
|
|
4370
4612
|
};
|
|
4371
4613
|
const preemptForDrain = () => {
|
|
4372
4614
|
const status = runtime.getState();
|
|
@@ -4383,7 +4625,7 @@ function createChatQueueTuiBinding(runTurn) {
|
|
|
4383
4625
|
const snapshotAndClearQueue = () => {
|
|
4384
4626
|
const status = runtime.getState();
|
|
4385
4627
|
if (status.queue.length === 0) return null;
|
|
4386
|
-
const merged = status.queue.join("\n");
|
|
4628
|
+
const merged = status.queue.map((req) => req.text).join("\n");
|
|
4387
4629
|
runtime.send({ type: "clear" });
|
|
4388
4630
|
return merged;
|
|
4389
4631
|
};
|
|
@@ -4398,6 +4640,7 @@ function createChatQueueTuiBinding(runTurn) {
|
|
|
4398
4640
|
return {
|
|
4399
4641
|
resolveSubmit,
|
|
4400
4642
|
enqueue,
|
|
4643
|
+
enqueueAndMaybeRun,
|
|
4401
4644
|
notifyTurnStart,
|
|
4402
4645
|
notifyTurnEnd,
|
|
4403
4646
|
drainHeadForManualTurn,
|
|
@@ -4411,9 +4654,22 @@ function createChatQueueTuiBinding(runTurn) {
|
|
|
4411
4654
|
};
|
|
4412
4655
|
}
|
|
4413
4656
|
|
|
4657
|
+
// packages/cli/tui/terminalNotification.ts
|
|
4658
|
+
function shouldEmitTerminalBell(decision) {
|
|
4659
|
+
return !decision.wasAborted && !decision.streamInterrupted && decision.exitCode === 0 && decision.interactive;
|
|
4660
|
+
}
|
|
4661
|
+
function emitTerminalBell(output) {
|
|
4662
|
+
try {
|
|
4663
|
+
output.write("\x07");
|
|
4664
|
+
} catch {
|
|
4665
|
+
}
|
|
4666
|
+
}
|
|
4667
|
+
|
|
4414
4668
|
// packages/cli/tui/tuiHistory.ts
|
|
4415
4669
|
var MAX_TUI_HISTORY_TURNS = 500;
|
|
4416
4670
|
var turnLineCache = /* @__PURE__ */ new WeakMap();
|
|
4671
|
+
var turnLineCountCache = /* @__PURE__ */ new WeakMap();
|
|
4672
|
+
var renderCacheMissCount = 0;
|
|
4417
4673
|
function createTurnHistory() {
|
|
4418
4674
|
return {
|
|
4419
4675
|
turns: [],
|
|
@@ -4432,6 +4688,7 @@ function startTurn(history, role) {
|
|
|
4432
4688
|
}
|
|
4433
4689
|
history.currentRole = role;
|
|
4434
4690
|
history.currentContent = "";
|
|
4691
|
+
resetStreamingTurnCache();
|
|
4435
4692
|
}
|
|
4436
4693
|
function appendToCurrentTurn(history, chunk) {
|
|
4437
4694
|
history.currentContent += chunk;
|
|
@@ -4444,6 +4701,7 @@ function finalizeCurrentTurn(history) {
|
|
|
4444
4701
|
});
|
|
4445
4702
|
history.currentRole = null;
|
|
4446
4703
|
history.currentContent = "";
|
|
4704
|
+
resetStreamingTurnCache();
|
|
4447
4705
|
if (history.turns.length > MAX_TUI_HISTORY_TURNS) {
|
|
4448
4706
|
history.turns = history.turns.slice(history.turns.length - MAX_TUI_HISTORY_TURNS);
|
|
4449
4707
|
}
|
|
@@ -4467,23 +4725,33 @@ function styleAssistantTurn(content, colorEnabled) {
|
|
|
4467
4725
|
});
|
|
4468
4726
|
return styledLines.join("\n");
|
|
4469
4727
|
}
|
|
4728
|
+
function fillUserBubbleRow(row, surfaceSeq, contentWidth) {
|
|
4729
|
+
const visible = visibleWidth(row);
|
|
4730
|
+
if (visible > contentWidth) {
|
|
4731
|
+
const truncated = truncateAnsi(row, contentWidth);
|
|
4732
|
+
const padAfter = Math.max(0, contentWidth - visibleWidth(truncated));
|
|
4733
|
+
return `${surfaceSeq}${truncated}${" ".repeat(padAfter)}\x1B[0m`;
|
|
4734
|
+
}
|
|
4735
|
+
return renderSurfaceLine({ text: row, surface: surfaceSeq, padTo: contentWidth });
|
|
4736
|
+
}
|
|
4470
4737
|
function renderTurnBlock(role, content, contentWidth, colorEnabled) {
|
|
4738
|
+
content = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4471
4739
|
const lines = [];
|
|
4472
4740
|
if (role === "user") {
|
|
4473
4741
|
const logicalLines = content.split("\n");
|
|
4474
4742
|
const accentSeq = colorEnabled ? themeColorSequence("accent") : "";
|
|
4475
|
-
const
|
|
4743
|
+
const firstPrefix = colorEnabled ? `${accentSeq}\x1B[1m\u2503 ` : "\u2503 ";
|
|
4744
|
+
const multilinePrefix = colorEnabled ? `${accentSeq}\x1B[1m\u2503 ` : "\u2503 ";
|
|
4745
|
+
const hangingIndent = colorEnabled ? `${accentSeq}\x1B[1m\u2503 ` : "\u2503 ";
|
|
4746
|
+
const surfaceSeq = colorEnabled ? userSurfaceBackgroundSequence() : "";
|
|
4476
4747
|
for (let i = 0; i < logicalLines.length; i++) {
|
|
4477
4748
|
const line = logicalLines[i];
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
styledLine = `${prefix}${line}`;
|
|
4485
|
-
}
|
|
4486
|
-
lines.push(...wrapTranscriptLine(styledLine, contentWidth, " "));
|
|
4749
|
+
const prefix = i === 0 ? firstPrefix : multilinePrefix;
|
|
4750
|
+
const styledLine = `${prefix}${line}`;
|
|
4751
|
+
const rows = wrapTranscriptLine(styledLine, contentWidth, hangingIndent);
|
|
4752
|
+
lines.push(
|
|
4753
|
+
...surfaceSeq ? rows.map((row) => fillUserBubbleRow(row, surfaceSeq, contentWidth)) : rows
|
|
4754
|
+
);
|
|
4487
4755
|
}
|
|
4488
4756
|
} else {
|
|
4489
4757
|
const styledEntry = styleAssistantTurn(content, colorEnabled);
|
|
@@ -4493,57 +4761,184 @@ function renderTurnBlock(role, content, contentWidth, colorEnabled) {
|
|
|
4493
4761
|
}
|
|
4494
4762
|
return lines;
|
|
4495
4763
|
}
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4764
|
+
var streamingTurnCache = null;
|
|
4765
|
+
function resetStreamingTurnCache() {
|
|
4766
|
+
streamingTurnCache = null;
|
|
4767
|
+
}
|
|
4768
|
+
function renderPrefixTurnBlock(role, content, contentWidth, colorEnabled) {
|
|
4769
|
+
content = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4770
|
+
if (role === "user") {
|
|
4771
|
+
return renderTurnBlock(role, content, contentWidth, colorEnabled);
|
|
4500
4772
|
}
|
|
4773
|
+
const highlighted = colorEnabled ? formatAssistantDisplay(content, { trimEdges: false }) : stripAnsi(formatAssistantDisplay(content, { trimEdges: false }));
|
|
4774
|
+
const rawLines = highlighted.split("\n");
|
|
4775
|
+
const styledLines = rawLines.map((line, idx) => {
|
|
4776
|
+
if (idx === 0 && !line.startsWith("[nolo]")) {
|
|
4777
|
+
const anchorPrefix = colorEnabled ? `${themeColorSequence("chrome")}\u25C8\x1B[39m ` : "\u25C8 ";
|
|
4778
|
+
return `${anchorPrefix}${line}`;
|
|
4779
|
+
}
|
|
4780
|
+
return line.startsWith("[nolo]") && colorEnabled ? themeText(line, "chrome", true) : line;
|
|
4781
|
+
});
|
|
4501
4782
|
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"));
|
|
4783
|
+
for (const logicalLine of styledLines) {
|
|
4784
|
+
lines.push(...wrapTranscriptLine(logicalLine, contentWidth));
|
|
4506
4785
|
}
|
|
4507
4786
|
return lines;
|
|
4508
4787
|
}
|
|
4509
|
-
function
|
|
4510
|
-
|
|
4788
|
+
function renderTailTurnBlock(role, content, contentWidth, colorEnabled) {
|
|
4789
|
+
content = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4790
|
+
const lines = [];
|
|
4791
|
+
if (role === "user") {
|
|
4792
|
+
const surfaceSeq = colorEnabled ? userSurfaceBackgroundSequence() : "";
|
|
4793
|
+
const accentSeq = colorEnabled ? themeColorSequence("accent") : "";
|
|
4794
|
+
const multilinePrefix = colorEnabled ? `${accentSeq}\x1B[1m\u2503 ` : "\u2503 ";
|
|
4795
|
+
const hangingIndent = colorEnabled ? `${accentSeq}\x1B[1m\u2503 ` : "\u2503 ";
|
|
4796
|
+
for (const rawLine of content.split("\n")) {
|
|
4797
|
+
const styledLine = `${multilinePrefix}${rawLine}`;
|
|
4798
|
+
const rows = wrapTranscriptLine(styledLine, contentWidth, hangingIndent);
|
|
4799
|
+
lines.push(
|
|
4800
|
+
...surfaceSeq ? rows.map((row) => fillUserBubbleRow(row, surfaceSeq, contentWidth)) : rows
|
|
4801
|
+
);
|
|
4802
|
+
}
|
|
4803
|
+
} else {
|
|
4804
|
+
const highlighted = colorEnabled ? formatAssistantDisplay(content) : stripAnsi(formatAssistantDisplay(content));
|
|
4805
|
+
const rawLines = highlighted.split("\n");
|
|
4806
|
+
const styledLines = rawLines.map((line) => {
|
|
4807
|
+
return line.startsWith("[nolo]") && colorEnabled ? themeText(line, "chrome", true) : line;
|
|
4808
|
+
});
|
|
4809
|
+
for (const logicalLine of styledLines) {
|
|
4810
|
+
lines.push(...wrapTranscriptLine(logicalLine, contentWidth));
|
|
4811
|
+
}
|
|
4812
|
+
}
|
|
4813
|
+
return lines;
|
|
4814
|
+
}
|
|
4815
|
+
function getStreamingTurnLines(role, content, contentWidth, colorEnabled, density, surface) {
|
|
4816
|
+
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)))) {
|
|
4817
|
+
streamingTurnCache = null;
|
|
4818
|
+
}
|
|
4819
|
+
if (!streamingTurnCache) {
|
|
4820
|
+
streamingTurnCache = {
|
|
4821
|
+
role,
|
|
4822
|
+
contentWidth,
|
|
4823
|
+
colorEnabled,
|
|
4824
|
+
density,
|
|
4825
|
+
surface,
|
|
4826
|
+
fullContent: content,
|
|
4827
|
+
prefixLength: 0,
|
|
4828
|
+
prefixLines: []
|
|
4829
|
+
};
|
|
4830
|
+
}
|
|
4831
|
+
if (content.length > streamingTurnCache.fullContent.length) {
|
|
4832
|
+
let searchPos = streamingTurnCache.prefixLength;
|
|
4833
|
+
let candidateCut = -1;
|
|
4834
|
+
while (true) {
|
|
4835
|
+
const idx = content.indexOf("\n\n", searchPos);
|
|
4836
|
+
if (idx === -1) break;
|
|
4837
|
+
const cut = idx + 1;
|
|
4838
|
+
searchPos = idx + 2;
|
|
4839
|
+
const prefixSub = content.slice(0, cut);
|
|
4840
|
+
const fenceCount = (prefixSub.match(/^```/gm) || []).length;
|
|
4841
|
+
if (fenceCount % 2 === 0) {
|
|
4842
|
+
candidateCut = cut;
|
|
4843
|
+
break;
|
|
4844
|
+
}
|
|
4845
|
+
}
|
|
4846
|
+
if (candidateCut > streamingTurnCache.prefixLength) {
|
|
4847
|
+
const candidatePrefix = content.slice(0, candidateCut);
|
|
4848
|
+
const candidateTail = content.slice(candidateCut);
|
|
4849
|
+
const candPrefixLines = renderPrefixTurnBlock(role, candidatePrefix, contentWidth, colorEnabled);
|
|
4850
|
+
const candTailLines = renderTailTurnBlock(role, candidateTail, contentWidth, colorEnabled);
|
|
4851
|
+
const candCombined = [...candPrefixLines, ...candTailLines];
|
|
4852
|
+
const fullCheckLines = renderTurnBlock(role, content, contentWidth, colorEnabled);
|
|
4853
|
+
if (JSON.stringify(candCombined) === JSON.stringify(fullCheckLines)) {
|
|
4854
|
+
streamingTurnCache.prefixLength = candidateCut;
|
|
4855
|
+
streamingTurnCache.prefixLines = candPrefixLines;
|
|
4856
|
+
streamingTurnCache.fullContent = content;
|
|
4857
|
+
} else {
|
|
4858
|
+
streamingTurnCache.fullContent = content;
|
|
4859
|
+
}
|
|
4860
|
+
} else {
|
|
4861
|
+
streamingTurnCache.fullContent = content;
|
|
4862
|
+
}
|
|
4863
|
+
}
|
|
4864
|
+
if (streamingTurnCache.prefixLength === 0) {
|
|
4865
|
+
return renderTurnBlock(role, content, contentWidth, colorEnabled);
|
|
4866
|
+
}
|
|
4867
|
+
const tailContent = content.slice(streamingTurnCache.prefixLength);
|
|
4868
|
+
const tailLines = renderTailTurnBlock(role, tailContent, contentWidth, colorEnabled);
|
|
4869
|
+
return [...streamingTurnCache.prefixLines, ...tailLines];
|
|
4870
|
+
}
|
|
4871
|
+
var assistantPlainLinesCache = /* @__PURE__ */ new Map();
|
|
4872
|
+
function getAssistantPlainLines(content) {
|
|
4873
|
+
let plainLines = assistantPlainLinesCache.get(content);
|
|
4874
|
+
if (plainLines !== void 0) {
|
|
4875
|
+
return plainLines;
|
|
4876
|
+
}
|
|
4877
|
+
if (!/[\r\x00#|\-*_~`>+\[\]()•☐☑]|\b\d+\./.test(content)) {
|
|
4878
|
+
plainLines = content.trim().split("\n");
|
|
4879
|
+
} else {
|
|
4880
|
+
plainLines = stripAnsi(formatAssistantDisplay(content)).split("\n");
|
|
4881
|
+
}
|
|
4882
|
+
if (assistantPlainLinesCache.size > 2e3) {
|
|
4883
|
+
const firstKey = assistantPlainLinesCache.keys().next().value;
|
|
4884
|
+
if (firstKey !== void 0) assistantPlainLinesCache.delete(firstKey);
|
|
4885
|
+
}
|
|
4886
|
+
assistantPlainLinesCache.set(content, plainLines);
|
|
4887
|
+
return plainLines;
|
|
4888
|
+
}
|
|
4889
|
+
function countTurnLines(role, content, contentWidth) {
|
|
4890
|
+
content = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4891
|
+
let count = 0;
|
|
4892
|
+
if (role === "user") {
|
|
4893
|
+
for (const line of content.split("\n")) {
|
|
4894
|
+
count += wrapTranscriptLine(`\u2503 ${line}`, contentWidth, "\u2503 ").length;
|
|
4895
|
+
}
|
|
4896
|
+
} else {
|
|
4897
|
+
const plainLines = getAssistantPlainLines(content);
|
|
4898
|
+
for (let i = 0; i < plainLines.length; i++) {
|
|
4899
|
+
const line = plainLines[i];
|
|
4900
|
+
const wrapped = i === 0 && !line.startsWith("[nolo]") ? wrapTranscriptLine(`\u25C8 ${line}`, contentWidth) : wrapTranscriptLine(line, contentWidth);
|
|
4901
|
+
count += wrapped.length;
|
|
4902
|
+
}
|
|
4903
|
+
}
|
|
4904
|
+
return count;
|
|
4905
|
+
}
|
|
4906
|
+
function buildTurnOffsets(history, contentWidth) {
|
|
4511
4907
|
const density = getActiveDensity();
|
|
4512
|
-
const
|
|
4908
|
+
const entries = [];
|
|
4909
|
+
let offset = 0;
|
|
4513
4910
|
for (let i = 0; i < history.turns.length; i++) {
|
|
4514
4911
|
const turn = history.turns[i];
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
if (cached && cached.width === contentWidth
|
|
4520
|
-
|
|
4912
|
+
const separatorAbove = density === "spacious" && (i > 0 || turn.role === "user") ? 1 : 0;
|
|
4913
|
+
offset += separatorAbove;
|
|
4914
|
+
const cached = turnLineCountCache.get(turn);
|
|
4915
|
+
let lineCount;
|
|
4916
|
+
if (cached && cached.width === contentWidth) {
|
|
4917
|
+
lineCount = cached.count;
|
|
4521
4918
|
} else {
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
width: contentWidth,
|
|
4525
|
-
color: colorEnabled,
|
|
4526
|
-
density,
|
|
4527
|
-
lines
|
|
4528
|
-
});
|
|
4529
|
-
wrapped.push(...lines);
|
|
4919
|
+
lineCount = countTurnLines(turn.role, turn.content, contentWidth);
|
|
4920
|
+
turnLineCountCache.set(turn, { width: contentWidth, count: lineCount });
|
|
4530
4921
|
}
|
|
4922
|
+
entries.push({ startRow: offset, lineCount, separatorAbove });
|
|
4923
|
+
offset += lineCount;
|
|
4531
4924
|
}
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
contentWidth,
|
|
4542
|
-
colorEnabled
|
|
4543
|
-
)
|
|
4544
|
-
);
|
|
4925
|
+
return { entries, totalLines: offset };
|
|
4926
|
+
}
|
|
4927
|
+
function currentTurnSeparator(history, density) {
|
|
4928
|
+
return density === "spacious" && (history.turns.length > 0 || history.currentRole === "user") ? 1 : 0;
|
|
4929
|
+
}
|
|
4930
|
+
function buildCopyViewLines(history) {
|
|
4931
|
+
const turns = [...history.turns];
|
|
4932
|
+
if (history.currentRole !== null) {
|
|
4933
|
+
turns.push({ role: history.currentRole, content: history.currentContent });
|
|
4545
4934
|
}
|
|
4546
|
-
|
|
4935
|
+
const lines = [];
|
|
4936
|
+
for (const [index, turn] of turns.entries()) {
|
|
4937
|
+
if (index > 0) lines.push("");
|
|
4938
|
+
const normalized = stripAnsi(turn.content).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4939
|
+
lines.push(...normalized.split("\n"));
|
|
4940
|
+
}
|
|
4941
|
+
return lines;
|
|
4547
4942
|
}
|
|
4548
4943
|
function renderHistory(output, history, inputLines) {
|
|
4549
4944
|
const tty = output;
|
|
@@ -4552,8 +4947,28 @@ function renderHistory(output, history, inputLines) {
|
|
|
4552
4947
|
const columns = tty.columns ?? 80;
|
|
4553
4948
|
const visibleHeight = Math.max(1, rows - inputLines);
|
|
4554
4949
|
const contentWidth = Math.max(1, columns - 1);
|
|
4555
|
-
const
|
|
4556
|
-
const
|
|
4950
|
+
const colorEnabled = resolveCliColorEnabled();
|
|
4951
|
+
const density = getActiveDensity();
|
|
4952
|
+
const surface = colorEnabled ? userSurfaceBackgroundSequence() : "";
|
|
4953
|
+
const { entries, totalLines: finalizedLines } = buildTurnOffsets(
|
|
4954
|
+
history,
|
|
4955
|
+
contentWidth
|
|
4956
|
+
);
|
|
4957
|
+
let totalLines = finalizedLines;
|
|
4958
|
+
let currentStart = -1;
|
|
4959
|
+
let currentLines = [];
|
|
4960
|
+
if (history.currentRole !== null && history.currentContent) {
|
|
4961
|
+
currentLines = getStreamingTurnLines(
|
|
4962
|
+
history.currentRole,
|
|
4963
|
+
history.currentContent,
|
|
4964
|
+
contentWidth,
|
|
4965
|
+
colorEnabled,
|
|
4966
|
+
density,
|
|
4967
|
+
surface
|
|
4968
|
+
);
|
|
4969
|
+
currentStart = finalizedLines + currentTurnSeparator(history, density);
|
|
4970
|
+
totalLines = currentStart + currentLines.length;
|
|
4971
|
+
}
|
|
4557
4972
|
if (history.followBottom) {
|
|
4558
4973
|
history.scrollTop = Math.max(0, totalLines - visibleHeight);
|
|
4559
4974
|
} else {
|
|
@@ -4564,19 +4979,71 @@ function renderHistory(output, history, inputLines) {
|
|
|
4564
4979
|
}
|
|
4565
4980
|
history.hasMoreAbove = history.scrollTop > 0;
|
|
4566
4981
|
history.hasMoreBelow = history.scrollTop + visibleHeight < totalLines;
|
|
4567
|
-
const
|
|
4568
|
-
const
|
|
4569
|
-
const visibleLines =
|
|
4982
|
+
const winStart = history.scrollTop;
|
|
4983
|
+
const winEnd = Math.min(totalLines, winStart + visibleHeight);
|
|
4984
|
+
const visibleLines = new Array(visibleHeight).fill("");
|
|
4985
|
+
for (let i = 0; i < entries.length; i++) {
|
|
4986
|
+
const entry = entries[i];
|
|
4987
|
+
if (entry.separatorAbove > 0) {
|
|
4988
|
+
const sepRow = entry.startRow - 1;
|
|
4989
|
+
if (sepRow >= winStart && sepRow < winEnd) {
|
|
4990
|
+
visibleLines[sepRow - winStart] = "";
|
|
4991
|
+
}
|
|
4992
|
+
}
|
|
4993
|
+
const turnStart = entry.startRow;
|
|
4994
|
+
const turnEnd = turnStart + entry.lineCount;
|
|
4995
|
+
if (turnEnd <= winStart || turnStart >= winEnd) continue;
|
|
4996
|
+
const turn = history.turns[i];
|
|
4997
|
+
const cached = turnLineCache.get(turn);
|
|
4998
|
+
let lines;
|
|
4999
|
+
if (cached && cached.width === contentWidth && cached.color === colorEnabled && cached.density === density && cached.surface === surface) {
|
|
5000
|
+
lines = cached.lines;
|
|
5001
|
+
} else {
|
|
5002
|
+
renderCacheMissCount += 1;
|
|
5003
|
+
lines = renderTurnBlock(turn.role, turn.content, contentWidth, colorEnabled);
|
|
5004
|
+
turnLineCache.set(turn, {
|
|
5005
|
+
width: contentWidth,
|
|
5006
|
+
color: colorEnabled,
|
|
5007
|
+
density,
|
|
5008
|
+
surface,
|
|
5009
|
+
lines
|
|
5010
|
+
});
|
|
5011
|
+
}
|
|
5012
|
+
const interStart = Math.max(turnStart, winStart);
|
|
5013
|
+
const interEnd = Math.min(turnEnd, winEnd);
|
|
5014
|
+
for (let r = interStart; r < interEnd; r++) {
|
|
5015
|
+
visibleLines[r - winStart] = lines[r - turnStart] ?? "";
|
|
5016
|
+
}
|
|
5017
|
+
}
|
|
5018
|
+
if (currentStart >= 0) {
|
|
5019
|
+
const separatorAbove = currentTurnSeparator(history, density);
|
|
5020
|
+
if (separatorAbove > 0) {
|
|
5021
|
+
const sepRow = currentStart - 1;
|
|
5022
|
+
if (sepRow >= winStart && sepRow < winEnd) {
|
|
5023
|
+
visibleLines[sepRow - winStart] = "";
|
|
5024
|
+
}
|
|
5025
|
+
}
|
|
5026
|
+
const currentEnd = currentStart + currentLines.length;
|
|
5027
|
+
if (currentEnd > winStart && currentStart < winEnd) {
|
|
5028
|
+
const interStart = Math.max(currentStart, winStart);
|
|
5029
|
+
const interEnd = Math.min(currentEnd, winEnd);
|
|
5030
|
+
for (let r = interStart; r < interEnd; r++) {
|
|
5031
|
+
visibleLines[r - winStart] = currentLines[r - currentStart] ?? "";
|
|
5032
|
+
}
|
|
5033
|
+
}
|
|
5034
|
+
}
|
|
4570
5035
|
let frame = "";
|
|
4571
5036
|
for (let i = 0; i < visibleHeight; i++) {
|
|
4572
5037
|
const line = visibleLines[i] ?? "";
|
|
4573
5038
|
const padded = padOrTruncateToWidth(line, contentWidth);
|
|
4574
5039
|
const thumb = renderScrollbarRow(i, visibleHeight, totalLines, history.scrollTop);
|
|
5040
|
+
const scrollbarPrefix = colorEnabled ? themeColorSequence("chrome") : "";
|
|
5041
|
+
const scrollbarSuffix = colorEnabled ? "\x1B[39m" : "";
|
|
4575
5042
|
frame += `\x1B[${i + 1};1H`;
|
|
4576
5043
|
frame += "\x1B[2K";
|
|
4577
5044
|
frame += padded;
|
|
4578
5045
|
frame += `\x1B[${columns}G`;
|
|
4579
|
-
frame += thumb
|
|
5046
|
+
frame += `${scrollbarPrefix}${thumb}${scrollbarSuffix}`;
|
|
4580
5047
|
}
|
|
4581
5048
|
const mainBottom = Math.max(1, rows - inputLines);
|
|
4582
5049
|
frame += `\x1B[${mainBottom};1H`;
|
|
@@ -4603,7 +5070,11 @@ function applyScrollAction(history, action, output, inputLines) {
|
|
|
4603
5070
|
const columns = tty.columns ?? 80;
|
|
4604
5071
|
const visibleHeight = Math.max(1, rows - inputLines);
|
|
4605
5072
|
const contentWidth = Math.max(1, columns - 1);
|
|
4606
|
-
const totalLines =
|
|
5073
|
+
const { totalLines: finalizedLines } = buildTurnOffsets(history, contentWidth);
|
|
5074
|
+
let totalLines = finalizedLines;
|
|
5075
|
+
if (history.currentRole !== null && history.currentContent) {
|
|
5076
|
+
totalLines += currentTurnSeparator(history, getActiveDensity()) + countTurnLines(history.currentRole, history.currentContent, contentWidth);
|
|
5077
|
+
}
|
|
4607
5078
|
const maxScrollTop = Math.max(0, totalLines - visibleHeight);
|
|
4608
5079
|
history.followBottom = false;
|
|
4609
5080
|
switch (action) {
|
|
@@ -5211,70 +5682,21 @@ ${content}`;
|
|
|
5211
5682
|
return null;
|
|
5212
5683
|
}
|
|
5213
5684
|
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
5685
|
async function runAgentChat(scriptDir, state, message, env, output, agentRunner = runAgentTurn, options = {}) {
|
|
5261
5686
|
let effectiveAgentKey = state.agentKey;
|
|
5262
5687
|
let effectiveAgentName = state.agentName;
|
|
5263
5688
|
const continueId = state.dialogId;
|
|
5264
5689
|
const cachedRoute = continueId ? autoRouteByDialog.get(continueId) : void 0;
|
|
5690
|
+
const hasImages = options.imageUrls && options.imageUrls.length > 0;
|
|
5265
5691
|
if (cachedRoute && !options.explicitAgentSwitch) {
|
|
5266
5692
|
effectiveAgentKey = cachedRoute.agentKey;
|
|
5267
5693
|
effectiveAgentName = cachedRoute.agentName;
|
|
5268
5694
|
} else if (!continueId && env.NOLO_AUTO_ROUTE !== "0" && state.agentKey === DEFAULT_TUI_AGENT_KEY) {
|
|
5269
|
-
const
|
|
5270
|
-
const route = authToken ? await classifyCliAutoRoute(message, {
|
|
5695
|
+
const route = classifyCliAutoRoute(message, {
|
|
5271
5696
|
serverUrl: state.serverUrl,
|
|
5272
|
-
authToken
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
tier: resolveCliAutoFallbackTier(message),
|
|
5276
|
-
classified: false
|
|
5277
|
-
};
|
|
5697
|
+
authToken: resolvePlatformAuthToken(env),
|
|
5698
|
+
hasImages
|
|
5699
|
+
});
|
|
5278
5700
|
effectiveAgentKey = route.agentKey;
|
|
5279
5701
|
effectiveAgentName = `auto\u2192${route.tier}`;
|
|
5280
5702
|
if (effectiveAgentKey !== state.agentKey) {
|
|
@@ -5285,7 +5707,6 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
|
|
|
5285
5707
|
);
|
|
5286
5708
|
}
|
|
5287
5709
|
}
|
|
5288
|
-
const hasImages = options.imageUrls && options.imageUrls.length > 0;
|
|
5289
5710
|
const userSelectedAgent = state.agentKey !== DEFAULT_TUI_AGENT_KEY;
|
|
5290
5711
|
const visionProbeKey = hasImages && userSelectedAgent ? state.agentKey : effectiveAgentKey;
|
|
5291
5712
|
if (hasImages && effectiveAgentKey !== CLI_IMAGE_AGENT_KEY) {
|
|
@@ -5398,18 +5819,22 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
|
|
|
5398
5819
|
// inside a TUI turn are stamped with the current conversation. Previously
|
|
5399
5820
|
// this factory only existed when pasted text was present, which meant a
|
|
5400
5821
|
// plain (no-paste) turn had no injection point for parentDialogId and the
|
|
5401
|
-
// run-
|
|
5822
|
+
// run-completion watcher could never attribute runs spawned this turn.
|
|
5402
5823
|
...options.pastedTextStore?.items.size ? { pastedTextStore: options.pastedTextStore } : {},
|
|
5403
5824
|
localRuntimeAdapterFactory: (factoryEnv, factoryOptions) => createCliLocalRuntimeAdapter({
|
|
5404
5825
|
env: factoryEnv,
|
|
5405
5826
|
cwd: factoryOptions?.cwd ?? state.cwd,
|
|
5406
5827
|
...options.pastedTextStore ? { pastedTextStore: options.pastedTextStore } : {},
|
|
5407
5828
|
// Stamp spawned background runs with the current TUI dialog so the
|
|
5408
|
-
// run-
|
|
5829
|
+
// run-completion watcher can attribute terminal-state wakes to this
|
|
5830
|
+
// conversation.
|
|
5409
5831
|
...state.dialogId ? { parentDialogId: state.dialogId } : {},
|
|
5410
5832
|
...options.activityReporter ? { activityReporter: options.activityReporter } : {}
|
|
5411
5833
|
}),
|
|
5412
5834
|
...options.activityReporter ? { activityReporter: options.activityReporter } : {},
|
|
5835
|
+
// 转发 dock 订阅:runAgentTurn 的输出层靠它判断「有面板」从而抑制
|
|
5836
|
+
// transcript 的进展卡片;dock 本身也靠它接收模型轮询带回来的快照。
|
|
5837
|
+
...options.onAgentRunStatus ? { onAgentRunStatus: options.onAgentRunStatus } : {},
|
|
5413
5838
|
...skillAllowedTools !== void 0 ? { allowedToolNames: skillAllowedTools } : {},
|
|
5414
5839
|
...contextBlockScopes.length > 0 ? { contextBlockScopes } : {}
|
|
5415
5840
|
});
|
|
@@ -5514,17 +5939,23 @@ function waitForActionGate(rl, input, output, gate, spawnRunner) {
|
|
|
5514
5939
|
});
|
|
5515
5940
|
});
|
|
5516
5941
|
}
|
|
5517
|
-
function persistAgentSelection(state, env) {
|
|
5942
|
+
function persistAgentSelection(state, env, saveSelection = saveProfileAgentSelection) {
|
|
5943
|
+
const isAuto = state.agentKey === DEFAULT_TUI_AGENT_KEY && state.agentName.trim().toLowerCase() === "auto";
|
|
5518
5944
|
try {
|
|
5519
|
-
|
|
5520
|
-
agentKey: state.agentKey,
|
|
5521
|
-
agentName: state.agentName
|
|
5945
|
+
saveSelection({
|
|
5946
|
+
agentKey: isAuto ? "" : state.agentKey,
|
|
5947
|
+
agentName: isAuto ? "" : state.agentName
|
|
5522
5948
|
});
|
|
5523
5949
|
} catch {
|
|
5524
5950
|
}
|
|
5525
5951
|
if (env) {
|
|
5526
|
-
|
|
5527
|
-
|
|
5952
|
+
if (isAuto) {
|
|
5953
|
+
delete env.NOLO_AGENT;
|
|
5954
|
+
delete env.NOLO_AGENT_NAME;
|
|
5955
|
+
} else {
|
|
5956
|
+
env.NOLO_AGENT = state.agentKey;
|
|
5957
|
+
env.NOLO_AGENT_NAME = state.agentName;
|
|
5958
|
+
}
|
|
5528
5959
|
}
|
|
5529
5960
|
}
|
|
5530
5961
|
function isInteractiveInput(input) {
|
|
@@ -5658,7 +6089,9 @@ async function startTuiWorkspace(options) {
|
|
|
5658
6089
|
setActiveTerminalBaseHex(detected.hex);
|
|
5659
6090
|
}
|
|
5660
6091
|
const bannerColumns = output.columns;
|
|
5661
|
-
|
|
6092
|
+
const initialWelcome = renderWelcome(state, 0, 0, bannerColumns);
|
|
6093
|
+
output.write(initialWelcome);
|
|
6094
|
+
const initialBannerLineCount = initialWelcome.split("\n").length;
|
|
5662
6095
|
let lastSentTitle = null;
|
|
5663
6096
|
const syncWindowTitle = () => {
|
|
5664
6097
|
if (!output.isTTY) return;
|
|
@@ -5696,12 +6129,20 @@ async function startTuiWorkspace(options) {
|
|
|
5696
6129
|
}
|
|
5697
6130
|
});
|
|
5698
6131
|
const activityReporter = (label) => activityIndicator.report(label);
|
|
5699
|
-
|
|
6132
|
+
let runWakeHandler = null;
|
|
6133
|
+
const runCompletionWatcher = createRunCompletionWatcher({
|
|
6134
|
+
getCurrentDialogId: () => state.dialogId ?? null,
|
|
6135
|
+
onWake: (text) => runWakeHandler?.(text)
|
|
6136
|
+
});
|
|
5700
6137
|
const runRegistryPoller = createRunRegistryPoller({
|
|
5701
6138
|
getDockedRuns: () => activityIndicator.getAgentRuns(),
|
|
5702
6139
|
update: (snapshot) => activityIndicator.updateAgentRun(snapshot),
|
|
5703
|
-
|
|
5704
|
-
|
|
6140
|
+
// 显式传 env:resolveNoloHome 只认传入 env 的 NOLO_HOME,不传则永远读
|
|
6141
|
+
// ~/.nolo——设了 NOLO_HOME 的环境(dev、测试)会读错目录。run 记录读取
|
|
6142
|
+
// 与 reconcile 的调用点也是同样写法。
|
|
6143
|
+
readRecord: (runId) => readRunRecord(runId, { env: process.env }),
|
|
6144
|
+
reconcile: (runId) => checkStaleRun(runId, { env: process.env }),
|
|
6145
|
+
onRecordsPolled: (records) => runCompletionWatcher.observe(records)
|
|
5705
6146
|
});
|
|
5706
6147
|
let explicitAgentSwitch = false;
|
|
5707
6148
|
let copyViewExitResolver = null;
|
|
@@ -5762,6 +6203,41 @@ async function startTuiWorkspace(options) {
|
|
|
5762
6203
|
scheduleRender();
|
|
5763
6204
|
});
|
|
5764
6205
|
};
|
|
6206
|
+
const repaintBanner = () => {
|
|
6207
|
+
if (!output.isTTY) return;
|
|
6208
|
+
if (fixedInput.isPaused()) return;
|
|
6209
|
+
if (modalOwnsKeyboard) return;
|
|
6210
|
+
const currentColumns = output.columns ?? 80;
|
|
6211
|
+
const welcome = renderWelcome(state, 0, 0, currentColumns);
|
|
6212
|
+
const lines = welcome.split("\n");
|
|
6213
|
+
const safeWidth = Math.max(1, currentColumns);
|
|
6214
|
+
const safeLines = lines.map((line) => padOrTruncateToWidth(line, safeWidth));
|
|
6215
|
+
const clearLines = Math.max(initialBannerLineCount, safeLines.length);
|
|
6216
|
+
output.write("\x1B[?2026h\x1B[?25l");
|
|
6217
|
+
try {
|
|
6218
|
+
let frame = "";
|
|
6219
|
+
for (let i = 0; i < clearLines; i++) frame += `\x1B[${i + 1};1H\x1B[2K`;
|
|
6220
|
+
safeLines.forEach((line, i) => {
|
|
6221
|
+
frame += `\x1B[${i + 1};1H${line}`;
|
|
6222
|
+
});
|
|
6223
|
+
output.write(frame);
|
|
6224
|
+
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
6225
|
+
} finally {
|
|
6226
|
+
output.write("\x1B[?25h\x1B[?2026l");
|
|
6227
|
+
}
|
|
6228
|
+
};
|
|
6229
|
+
void checkForCliUpdate(state.cliVersion, state.serverUrl, {
|
|
6230
|
+
fetchImpl,
|
|
6231
|
+
env: options.env ?? process.env
|
|
6232
|
+
}).then((updateAvailable) => {
|
|
6233
|
+
if (sessionEnded || !updateAvailable) return;
|
|
6234
|
+
state = { ...state, updateAvailable };
|
|
6235
|
+
if (history.turns.length === 0 && history.currentRole === null) {
|
|
6236
|
+
repaintBanner();
|
|
6237
|
+
} else {
|
|
6238
|
+
scheduleRender();
|
|
6239
|
+
}
|
|
6240
|
+
});
|
|
5765
6241
|
let syncingLayout = false;
|
|
5766
6242
|
const renderHistoryToOutput = () => {
|
|
5767
6243
|
if (fixedInput.isPaused()) return;
|
|
@@ -5864,11 +6340,17 @@ async function startTuiWorkspace(options) {
|
|
|
5864
6340
|
void maybeAutoRefreshTheme();
|
|
5865
6341
|
}, AUTO_THEME_POLL_MS);
|
|
5866
6342
|
}
|
|
5867
|
-
const runOneAgentTurn = async (
|
|
6343
|
+
const runOneAgentTurn = async (inputMsg, imageUrls, actionGateHandler, confirmDestructiveAction) => {
|
|
6344
|
+
const req = createTurnRequest(inputMsg);
|
|
6345
|
+
if (req.event.kind === "child-run-completed") {
|
|
6346
|
+
for (const r of req.event.runs) {
|
|
6347
|
+
runCompletionWatcher.markAcknowledged(r.runId);
|
|
6348
|
+
}
|
|
6349
|
+
}
|
|
6350
|
+
const message = req.text;
|
|
5868
6351
|
forcedStop = false;
|
|
5869
6352
|
turnEpoch += 1;
|
|
5870
6353
|
const myEpoch = turnEpoch;
|
|
5871
|
-
const turnParentDialogId = state.dialogId;
|
|
5872
6354
|
history.followBottom = true;
|
|
5873
6355
|
startTurn(history, "user");
|
|
5874
6356
|
appendToCurrentTurn(history, message);
|
|
@@ -5879,12 +6361,12 @@ async function startTuiWorkspace(options) {
|
|
|
5879
6361
|
const agentOutput = isInteractiveInput(input) ? createHistoryOutputStream(history, () => {
|
|
5880
6362
|
scheduleRender();
|
|
5881
6363
|
}) : output;
|
|
5882
|
-
const requestUserChoice = isInteractiveInput(input) && dialogHost ? async (
|
|
6364
|
+
const requestUserChoice = isInteractiveInput(input) && dialogHost ? async (req2) => {
|
|
5883
6365
|
modalOwnsKeyboard = true;
|
|
5884
6366
|
try {
|
|
5885
6367
|
return await dialogHost.run(
|
|
5886
6368
|
(anchor) => runAskChoiceDialog({
|
|
5887
|
-
request:
|
|
6369
|
+
request: req2,
|
|
5888
6370
|
input,
|
|
5889
6371
|
output,
|
|
5890
6372
|
...anchor
|
|
@@ -5934,7 +6416,8 @@ async function startTuiWorkspace(options) {
|
|
|
5934
6416
|
...runResult.dialogId ? {
|
|
5935
6417
|
dialogId: runResult.dialogId,
|
|
5936
6418
|
dialogKey: nextDialogKey,
|
|
5937
|
-
dialogLabel: runResult.title || runResult.dialogId
|
|
6419
|
+
dialogLabel: runResult.title || runResult.dialogId,
|
|
6420
|
+
...runResult.title ? { dialogTitle: runResult.title } : {}
|
|
5938
6421
|
} : {},
|
|
5939
6422
|
...runResult.turnTokens ? { turnTokens: runResult.turnTokens } : {}
|
|
5940
6423
|
};
|
|
@@ -5943,6 +6426,14 @@ async function startTuiWorkspace(options) {
|
|
|
5943
6426
|
}
|
|
5944
6427
|
const wasAborted = activeTurnAbort.signal.aborted;
|
|
5945
6428
|
activeTurnAbort = null;
|
|
6429
|
+
if (shouldEmitTerminalBell({
|
|
6430
|
+
wasAborted,
|
|
6431
|
+
streamInterrupted: runResult.streamInterrupted,
|
|
6432
|
+
exitCode: runResult.exitCode,
|
|
6433
|
+
interactive: isInteractiveInput(input)
|
|
6434
|
+
})) {
|
|
6435
|
+
emitTerminalBell(output);
|
|
6436
|
+
}
|
|
5946
6437
|
explicitAgentSwitch = false;
|
|
5947
6438
|
if (isInteractiveInput(input)) {
|
|
5948
6439
|
finalizeCurrentTurn(history);
|
|
@@ -5964,7 +6455,8 @@ async function startTuiWorkspace(options) {
|
|
|
5964
6455
|
...runResult.dialogId ? {
|
|
5965
6456
|
dialogId: runResult.dialogId,
|
|
5966
6457
|
dialogKey: nextDialogKey,
|
|
5967
|
-
dialogLabel: runResult.title || runResult.dialogId
|
|
6458
|
+
dialogLabel: runResult.title || runResult.dialogId,
|
|
6459
|
+
...runResult.title ? { dialogTitle: runResult.title } : {}
|
|
5968
6460
|
} : {},
|
|
5969
6461
|
...runResult.turnTokens ? { turnTokens: runResult.turnTokens } : {},
|
|
5970
6462
|
...runResult.contextWindow ? { contextWindow: runResult.contextWindow } : {},
|
|
@@ -5985,14 +6477,6 @@ async function startTuiWorkspace(options) {
|
|
|
5985
6477
|
emitCommandOutput(t("dialogNotSavedHint"));
|
|
5986
6478
|
}
|
|
5987
6479
|
}
|
|
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
6480
|
return { ok: !wasAborted, aborted: wasAborted };
|
|
5997
6481
|
} finally {
|
|
5998
6482
|
activityIndicator.stop();
|
|
@@ -6027,6 +6511,17 @@ ${overlayText}`);
|
|
|
6027
6511
|
renderHistoryToOutput();
|
|
6028
6512
|
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
6029
6513
|
};
|
|
6514
|
+
const persistExplicitAgentSwitch = (previousAgentKey) => {
|
|
6515
|
+
if (state.agentKey === previousAgentKey) return false;
|
|
6516
|
+
if (state.dialogId) autoRouteByDialog.delete(state.dialogId);
|
|
6517
|
+
explicitAgentSwitch = true;
|
|
6518
|
+
persistAgentSelection(
|
|
6519
|
+
state,
|
|
6520
|
+
options.env ?? process.env,
|
|
6521
|
+
options.saveAgentSelection
|
|
6522
|
+
);
|
|
6523
|
+
return true;
|
|
6524
|
+
};
|
|
6030
6525
|
const runSubmittedLine = async (line, actionGateHandler, confirmDestructiveAction) => {
|
|
6031
6526
|
if (!line.trim()) return false;
|
|
6032
6527
|
const result = handleTuiInput(line, state);
|
|
@@ -6045,9 +6540,7 @@ ${overlayText}`);
|
|
|
6045
6540
|
emitCommandOutput(result.output);
|
|
6046
6541
|
}
|
|
6047
6542
|
if (state.agentKey !== previousAgentKey) {
|
|
6048
|
-
|
|
6049
|
-
explicitAgentSwitch = true;
|
|
6050
|
-
persistAgentSelection(state, options.env ?? process.env);
|
|
6543
|
+
persistExplicitAgentSwitch(previousAgentKey);
|
|
6051
6544
|
}
|
|
6052
6545
|
if (result.action?.type === "exit") return true;
|
|
6053
6546
|
if (result.action?.type === "clear") {
|
|
@@ -6098,6 +6591,7 @@ ${overlayText}`);
|
|
|
6098
6591
|
if (result.action?.type === "compact") {
|
|
6099
6592
|
const runner = options.compactRunner ?? compactDialog;
|
|
6100
6593
|
const authToken = resolvePlatformAuthToken(options.env ?? {});
|
|
6594
|
+
const compactStart = Date.now();
|
|
6101
6595
|
try {
|
|
6102
6596
|
const compactResult = await runner({
|
|
6103
6597
|
serverUrl: state.serverUrl,
|
|
@@ -6105,20 +6599,45 @@ ${overlayText}`);
|
|
|
6105
6599
|
dialogId: result.action.dialogId,
|
|
6106
6600
|
summaryLlmCaller: options.summaryLlmCaller
|
|
6107
6601
|
});
|
|
6602
|
+
const elapsedSec = ((Date.now() - compactStart) / 1e3).toFixed(1);
|
|
6108
6603
|
state = {
|
|
6109
6604
|
...state,
|
|
6110
6605
|
dialogId: compactResult.dialogId,
|
|
6111
6606
|
dialogKey: compactResult.dialogKey,
|
|
6112
|
-
dialogLabel: compactResult.dialogId
|
|
6607
|
+
dialogLabel: compactResult.dialogId,
|
|
6608
|
+
dialogTitle: state.dialogTitle,
|
|
6609
|
+
// Compact forks into a fresh dialog that only inherits the summary,
|
|
6610
|
+
// not the full message history. Drop usage-derived context so the
|
|
6611
|
+
// composer chip falls back to the default CLI surface estimate and
|
|
6612
|
+
// the context percentage visibly drops. Mirrors the /clear reset.
|
|
6613
|
+
turnTokens: void 0,
|
|
6614
|
+
estimatedContextTokens: estimateDefaultCliContextTokens({
|
|
6615
|
+
cwd: state.cwd,
|
|
6616
|
+
agentKey: state.agentKey,
|
|
6617
|
+
agentName: state.agentKey === DEFAULT_TUI_AGENT_KEY && (options.env ?? process.env).NOLO_AUTO_ROUTE !== "0" ? "DeepSeek V4 Flash" : state.agentName,
|
|
6618
|
+
model: state.agentKey === DEFAULT_TUI_AGENT_KEY && (options.env ?? process.env).NOLO_AUTO_ROUTE !== "0" ? "deepseek-v4-flash" : void 0
|
|
6619
|
+
})
|
|
6113
6620
|
};
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6621
|
+
const elapsed = `${elapsedSec}s`;
|
|
6622
|
+
const message = compactResult.summaryGenerated ? compactResult.compactedMessageCount > 0 ? t(
|
|
6623
|
+
"compactSuccessWithCount",
|
|
6624
|
+
result.action.dialogId,
|
|
6625
|
+
compactResult.dialogId,
|
|
6626
|
+
elapsed,
|
|
6627
|
+
String(compactResult.compactedMessageCount)
|
|
6628
|
+
) : t(
|
|
6629
|
+
"compactSuccess",
|
|
6630
|
+
result.action.dialogId,
|
|
6631
|
+
compactResult.dialogId,
|
|
6632
|
+
elapsed
|
|
6633
|
+
) : t(
|
|
6634
|
+
"compactForked",
|
|
6635
|
+
result.action.dialogId,
|
|
6636
|
+
compactResult.dialogId,
|
|
6637
|
+
elapsed
|
|
6121
6638
|
);
|
|
6639
|
+
output.write(`${message}
|
|
6640
|
+
`);
|
|
6122
6641
|
} catch (error) {
|
|
6123
6642
|
output.write(
|
|
6124
6643
|
`[nolo] Compact failed: ${toErrorMessage(error)}
|
|
@@ -6282,6 +6801,7 @@ ${overlayText}`);
|
|
|
6282
6801
|
dialogId: pickResult.dialog.id,
|
|
6283
6802
|
dialogKey: pickResult.dialog.dbKey,
|
|
6284
6803
|
dialogLabel: pickResult.dialog.title || pickResult.dialog.id,
|
|
6804
|
+
dialogTitle: pickResult.dialog.title,
|
|
6285
6805
|
turnTokens: void 0
|
|
6286
6806
|
};
|
|
6287
6807
|
clearCollapsedPasteStore(pasteStore);
|
|
@@ -6418,12 +6938,6 @@ ${err.message}` : ""}`
|
|
|
6418
6938
|
resolveCliColorEnabled()
|
|
6419
6939
|
);
|
|
6420
6940
|
}
|
|
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
6941
|
return base;
|
|
6428
6942
|
},
|
|
6429
6943
|
getActivityLines: () => activityIndicator.getActivityLines(resolveCliColorEnabled()),
|
|
@@ -6476,6 +6990,7 @@ ${err.message}` : ""}`
|
|
|
6476
6990
|
autoThemeTimer = null;
|
|
6477
6991
|
}
|
|
6478
6992
|
runRegistryPoller.dispose();
|
|
6993
|
+
runCompletionWatcher.dispose();
|
|
6479
6994
|
activityIndicator.dispose();
|
|
6480
6995
|
resolveDone?.();
|
|
6481
6996
|
clearCollapsedPasteStore(pasteStore);
|
|
@@ -6486,6 +7001,83 @@ ${err.message}` : ""}`
|
|
|
6486
7001
|
output.write("\x1B[?25h\x1B[?2026l");
|
|
6487
7002
|
input.setRawMode?.(false);
|
|
6488
7003
|
};
|
|
7004
|
+
const buildInteractiveTurnHandlers = () => {
|
|
7005
|
+
const actionGateHandler = async (gate) => {
|
|
7006
|
+
modalOwnsKeyboard = true;
|
|
7007
|
+
try {
|
|
7008
|
+
return await waitForRawActionGate(input, output, gate, spawnRunner, {
|
|
7009
|
+
beforeSubprocess: () => fixedInput.pause(),
|
|
7010
|
+
afterSubprocess: () => fixedInput.resumeFromSubprocess(),
|
|
7011
|
+
registerToken: (handler) => {
|
|
7012
|
+
rawActionGateTokenHandler = handler;
|
|
7013
|
+
}
|
|
7014
|
+
});
|
|
7015
|
+
} finally {
|
|
7016
|
+
modalOwnsKeyboard = false;
|
|
7017
|
+
}
|
|
7018
|
+
};
|
|
7019
|
+
const confirmDestructiveAction = async (request) => {
|
|
7020
|
+
modalOwnsKeyboard = true;
|
|
7021
|
+
try {
|
|
7022
|
+
return await dialogHost.run(
|
|
7023
|
+
(anchor) => runConfirmDialog({
|
|
7024
|
+
request,
|
|
7025
|
+
input,
|
|
7026
|
+
output,
|
|
7027
|
+
...anchor
|
|
7028
|
+
})
|
|
7029
|
+
);
|
|
7030
|
+
} finally {
|
|
7031
|
+
modalOwnsKeyboard = false;
|
|
7032
|
+
}
|
|
7033
|
+
};
|
|
7034
|
+
return { actionGateHandler, confirmDestructiveAction };
|
|
7035
|
+
};
|
|
7036
|
+
const runIdleTextTurn = async (inputMsg) => {
|
|
7037
|
+
const req = createTurnRequest(inputMsg);
|
|
7038
|
+
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
7039
|
+
const binding = ensureChatQueueBinding(actionGateHandler, confirmDestructiveAction);
|
|
7040
|
+
binding.notifyTurnStart();
|
|
7041
|
+
busy = true;
|
|
7042
|
+
fixedInput.enterOutputMode(req.text);
|
|
7043
|
+
try {
|
|
7044
|
+
const outcome = await runOneAgentTurn(
|
|
7045
|
+
req,
|
|
7046
|
+
[],
|
|
7047
|
+
actionGateHandler,
|
|
7048
|
+
confirmDestructiveAction
|
|
7049
|
+
);
|
|
7050
|
+
await binding.notifyTurnEnd(outcome);
|
|
7051
|
+
} catch (err) {
|
|
7052
|
+
await binding.notifyTurnEnd({ ok: false, aborted: false });
|
|
7053
|
+
emitCommandOutput(
|
|
7054
|
+
`${t("turnFailed")}${err instanceof Error && err.message ? `
|
|
7055
|
+
${err.message}` : ""}`
|
|
7056
|
+
);
|
|
7057
|
+
} finally {
|
|
7058
|
+
busy = false;
|
|
7059
|
+
}
|
|
7060
|
+
refreshGitStatus();
|
|
7061
|
+
flushPendingRender();
|
|
7062
|
+
fixedInput.exitOutputMode(buffer, cursorPos);
|
|
7063
|
+
};
|
|
7064
|
+
runWakeHandler = (event) => {
|
|
7065
|
+
if (done) return;
|
|
7066
|
+
if (busy || fixedInput.isPaused() || copyViewExitResolver) {
|
|
7067
|
+
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
7068
|
+
ensureChatQueueBinding(actionGateHandler, confirmDestructiveAction).enqueue(event);
|
|
7069
|
+
if (fixedInput.active && !fixedInput.isPaused()) {
|
|
7070
|
+
fixedInput.repaint(buffer, cursorPos);
|
|
7071
|
+
}
|
|
7072
|
+
return;
|
|
7073
|
+
}
|
|
7074
|
+
void runIdleTextTurn(event).catch((err) => {
|
|
7075
|
+
emitCommandOutput(
|
|
7076
|
+
`${t("turnFailed")}${err instanceof Error && err.message ? `
|
|
7077
|
+
${err.message}` : ""}`
|
|
7078
|
+
);
|
|
7079
|
+
});
|
|
7080
|
+
};
|
|
6489
7081
|
const handleInputToken = async (sequence) => {
|
|
6490
7082
|
if (done) return;
|
|
6491
7083
|
if (copyViewExitResolver) {
|
|
@@ -6619,18 +7211,41 @@ ${merged}` : merged;
|
|
|
6619
7211
|
if (busyLock) {
|
|
6620
7212
|
const trimmedText = submittedText.trim();
|
|
6621
7213
|
const busySlashCommand = trimmedText.split(/\s+/)[0]?.toLowerCase();
|
|
6622
|
-
const isBusyLocalSlash = busySlashCommand === "/context" || busySlashCommand === "/ctx" || busySlashCommand === "/switch";
|
|
7214
|
+
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
7215
|
if (isBusyLocalSlash) {
|
|
7216
|
+
releaseCollapsedPasteReferences(submittedText, pasteStore);
|
|
7217
|
+
buffer = "";
|
|
7218
|
+
cursorPos = 0;
|
|
7219
|
+
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
6624
7220
|
const beforeAgentKey = state.agentKey;
|
|
6625
7221
|
const res = handleTuiInput(submittedText, state);
|
|
6626
|
-
if (res.action) {
|
|
7222
|
+
if (res.action?.type === "theme-refresh") {
|
|
7223
|
+
state = res.nextState;
|
|
7224
|
+
const detected2 = await detectTerminalBackground({
|
|
7225
|
+
stdin: input,
|
|
7226
|
+
stdout: output,
|
|
7227
|
+
allowSystemFallback: true
|
|
7228
|
+
});
|
|
7229
|
+
let refreshMsg = "";
|
|
7230
|
+
if (detected2 && applyDetectedBackground(detected2)) {
|
|
7231
|
+
refreshMsg = t("themeRefreshed", detected2.brightness);
|
|
7232
|
+
} else if (detected2) {
|
|
7233
|
+
refreshMsg = t("themeRefreshed", detected2.brightness);
|
|
7234
|
+
} else {
|
|
7235
|
+
refreshMsg = t("themeRefreshFailed");
|
|
7236
|
+
}
|
|
7237
|
+
if (refreshMsg) {
|
|
7238
|
+
output.write(`${refreshMsg}
|
|
7239
|
+
`);
|
|
7240
|
+
}
|
|
7241
|
+
} else if (res.action) {
|
|
6627
7242
|
output.write(
|
|
6628
7243
|
"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
7244
|
);
|
|
6630
7245
|
} else {
|
|
6631
7246
|
state = res.nextState;
|
|
6632
7247
|
let msg = res.output;
|
|
6633
|
-
if (busySlashCommand === "/switch" &&
|
|
7248
|
+
if (busySlashCommand === "/switch" && persistExplicitAgentSwitch(beforeAgentKey)) {
|
|
6634
7249
|
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
7250
|
msg = msg ? `${msg}
|
|
6636
7251
|
${hint}` : hint;
|
|
@@ -6640,43 +7255,10 @@ ${hint}` : hint;
|
|
|
6640
7255
|
`);
|
|
6641
7256
|
}
|
|
6642
7257
|
}
|
|
6643
|
-
releaseCollapsedPasteReferences(submittedText, pasteStore);
|
|
6644
|
-
buffer = "";
|
|
6645
|
-
cursorPos = 0;
|
|
6646
|
-
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
6647
7258
|
return;
|
|
6648
7259
|
}
|
|
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
|
-
);
|
|
7260
|
+
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
7261
|
+
const binding = ensureChatQueueBinding(actionGateHandler, confirmDestructiveAction);
|
|
6680
7262
|
const decision = binding.resolveSubmit({
|
|
6681
7263
|
text: submittedText,
|
|
6682
7264
|
isRunning: true
|
|
@@ -6693,62 +7275,13 @@ ${hint}` : hint;
|
|
|
6693
7275
|
return;
|
|
6694
7276
|
}
|
|
6695
7277
|
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
|
-
};
|
|
7278
|
+
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
6725
7279
|
const manualBinding = ensureChatQueueBinding(actionGateHandler, confirmDestructiveAction);
|
|
6726
7280
|
const drainedText = manualBinding.drainHeadForManualTurn();
|
|
6727
7281
|
if (drainedText !== null) {
|
|
6728
|
-
busy = true;
|
|
6729
7282
|
buffer = "";
|
|
6730
7283
|
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);
|
|
7284
|
+
await runIdleTextTurn(drainedText);
|
|
6752
7285
|
return;
|
|
6753
7286
|
}
|
|
6754
7287
|
}
|
|
@@ -6758,37 +7291,11 @@ ${err.message}` : ""}`
|
|
|
6758
7291
|
fixedInput.enterOutputMode(submittedText);
|
|
6759
7292
|
let shouldExit = false;
|
|
6760
7293
|
try {
|
|
7294
|
+
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
6761
7295
|
shouldExit = await runSubmittedLine(
|
|
6762
7296
|
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
|
-
}
|
|
7297
|
+
actionGateHandler,
|
|
7298
|
+
confirmDestructiveAction
|
|
6792
7299
|
);
|
|
6793
7300
|
} finally {
|
|
6794
7301
|
busy = false;
|
|
@@ -6862,6 +7369,7 @@ ${renderStatusLine(state)}
|
|
|
6862
7369
|
output.write(`[nolo] ${t("persistentProcessesLeft", String(persistentCount))}
|
|
6863
7370
|
`);
|
|
6864
7371
|
}
|
|
7372
|
+
sessionEnded = true;
|
|
6865
7373
|
rl.close();
|
|
6866
7374
|
}
|
|
6867
7375
|
}
|
|
@@ -6871,7 +7379,6 @@ export {
|
|
|
6871
7379
|
applyOutputChunkToCurrentTurn,
|
|
6872
7380
|
applyScrollAction,
|
|
6873
7381
|
applyTerminalOutputToText,
|
|
6874
|
-
buildTuiRunOverlay,
|
|
6875
7382
|
buildWindowTitle,
|
|
6876
7383
|
countPhysicalLines,
|
|
6877
7384
|
createFixedInput,
|