nolo-cli 0.157.0-alpha.1 → 0.157.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/{_executeModel-5WS2PA62.js → _executeModel-ZIQHOREX.js} +55 -55
  2. package/{accountResolver-7RYB4D2P.js → accountResolver-55EDKEIK.js} +1 -1
  3. package/{action-ZJYUBXFC.js → action-GPPJC5TI.js} +5 -5
  4. package/{addContentAction-TVHB4526.js → addContentAction-XJQEJ4XW.js} +8 -8
  5. package/{addDialogAgentAction-FDPBU6K6.js → addDialogAgentAction-5WZX5CAY.js} +7 -7
  6. package/{agentDeleteCommand-Q6M4F3U6.js → agentDeleteCommand-LQSOJEXY.js} +75 -76
  7. package/{agentEmailCommands-FNH6FEHS.js → agentEmailCommands-HTPKXONW.js} +78 -79
  8. package/{agentListCommands-JUNMFS6E.js → agentListCommands-GOCGOQUB.js} +36 -36
  9. package/{agentMachineCommands-VNLDEKNT.js → agentMachineCommands-T7DAZG77.js} +35 -32
  10. package/{agentProviderCommands-X2HQE6HY.js → agentProviderCommands-CXBHNONN.js} +5 -5
  11. package/{agentPullCommand-FA43RBRU.js → agentPullCommand-GXXEDOSA.js} +4 -4
  12. package/{agentRecordCommands-47XXRVPI.js → agentRecordCommands-HSW3RJ4H.js} +72 -73
  13. package/{agentRunCommand-QEXFJUXQ.js → agentRunCommand-TIRJ57DK.js} +75 -75
  14. package/{agentRunControl-2C5GM3BW.js → agentRunControl-QWFFIAQY.js} +9 -7
  15. package/{agentRuntimeLocal-O5GDAFTN.js → agentRuntimeLocal-J6I63NZC.js} +21 -19
  16. package/{agentSlice-E3XS5FTQ.js → agentSlice-JNM3HF3V.js} +8 -8
  17. package/{appDeleteCommands-C2J5RQ3I.js → appDeleteCommands-KKLAK2UR.js} +31 -29
  18. package/{appDeployCommands-3YRK7PSU.js → appDeployCommands-PXWK4FAX.js} +31 -29
  19. package/{appDeployStatusCommands-FPAX7MOK.js → appDeployStatusCommands-3NGWDZTX.js} +31 -29
  20. package/{appGetCommands-XAC2V766.js → appGetCommands-APWYPEO3.js} +31 -29
  21. package/{appListCommands-ZJL2W5O7.js → appListCommands-OP7IRALO.js} +31 -29
  22. package/{authCommand-J3XILHWW.js → authCommand-3Z52KJID.js} +22 -302
  23. package/{authCommands-77CHYBGF.js → authCommands-QOCKVPX3.js} +5 -5
  24. package/{builtinSkillRegistry-A6VSPJEJ.js → builtinSkillRegistry-LJV7FHNI.js} +4 -4
  25. package/{chromeCommands-OBBNJCLS.js → chromeCommands-IY4NVSXZ.js} +17 -10
  26. package/{chunk-SW4S4XYB.js → chunk-2AB2HA4M.js} +84 -34
  27. package/{chunk-C5VPAHIU.js → chunk-32ZKZET7.js} +1 -1
  28. package/{chunk-XPWGOTBQ.js → chunk-3L2WKC3W.js} +1 -8
  29. package/{chunk-3XZKV7QQ.js → chunk-3L5MSPWX.js} +1 -1
  30. package/{chunk-QLQ573SU.js → chunk-3M52COK5.js} +120 -0
  31. package/{chunk-VSOWPETY.js → chunk-4226O6F7.js} +10 -10
  32. package/{chunk-Z6KQDSZW.js → chunk-43OFVLWJ.js} +6 -6
  33. package/{chunk-TJ2VPCBE.js → chunk-4JCAW7TO.js} +2 -2
  34. package/{chunk-6TF64IF2.js → chunk-4L4K6YR7.js} +16 -2
  35. package/{chunk-PEO24UB5.js → chunk-5E5VB7PS.js} +324 -57
  36. package/{chunk-ZD2BLOY6.js → chunk-5EDQTOUR.js} +7 -7
  37. package/{chunk-HKT6QXP3.js → chunk-5IKRTRRR.js} +5 -5
  38. package/{chunk-P5QACQDK.js → chunk-62TBKWTV.js} +1 -1
  39. package/{chunk-TRW43TSC.js → chunk-6EQD4AQL.js} +41 -1
  40. package/{chunk-YLMMECCH.js → chunk-6XIE5ZGI.js} +1 -1
  41. package/{chunk-OH2M7WEU.js → chunk-6Y3ETA2Y.js} +3 -3
  42. package/{chunk-7A4LJCDR.js → chunk-B3ZIFOFI.js} +5 -5
  43. package/{chunk-WZ6OU4NX.js → chunk-BAWAKW7X.js} +2 -2
  44. package/{chunk-UUPR3TD7.js → chunk-BL4HFN6L.js} +2 -4
  45. package/{chunk-2GGXHQIW.js → chunk-BLVSFYQ3.js} +4 -2
  46. package/{chunk-HP6O6LTV.js → chunk-CDLP56BS.js} +9 -9
  47. package/{chunk-UTIMX333.js → chunk-DJ2BOPJY.js} +1 -1
  48. package/{chunk-36OMEXXR.js → chunk-DLV3H464.js} +8 -8
  49. package/{chunk-CE7PIHQD.js → chunk-ESMZW5PE.js} +3 -3
  50. package/{chunk-PSJWPSKS.js → chunk-EWO77ZGF.js} +9 -43
  51. package/{chunk-ZWG3C7VI.js → chunk-F3SOW2EU.js} +81 -1
  52. package/{chunk-FY4SDK2E.js → chunk-FDLDMJTM.js} +1 -1
  53. package/{chunk-KOB75UNU.js → chunk-FHG46N5C.js} +53 -4
  54. package/{chunk-7KYVUFDG.js → chunk-G3VYRPTV.js} +5 -267
  55. package/{chunk-DW7MGLMG.js → chunk-GGUTTH6C.js} +35 -207
  56. package/{chunk-6MJNEXUU.js → chunk-HGDKT2D6.js} +4 -0
  57. package/{chunk-B2EGWZJG.js → chunk-I7S63QUU.js} +1 -1
  58. package/{chunk-ROPSATAB.js → chunk-IF7V3CBU.js} +1 -1
  59. package/chunk-IKOKYBYJ.js +2685 -0
  60. package/{chunk-T6CBQ6BN.js → chunk-INFHX73M.js} +1 -1
  61. package/{chunk-YBNHPX4S.js → chunk-IW64YHXL.js} +155 -31
  62. package/{chunk-K43ZF2C3.js → chunk-JPPQ3GUO.js} +1 -1
  63. package/{chunk-TZTWMGE3.js → chunk-JWEXJ573.js} +3 -3
  64. package/{chunk-RUNKPFM5.js → chunk-K6Y5T4GE.js} +12 -8
  65. package/{chunk-MVJVF4ED.js → chunk-KESKU5BG.js} +18 -17
  66. package/{chunk-I2ZMGXXF.js → chunk-KFHREHUQ.js} +1 -1
  67. package/{chunk-3C2QLERX.js → chunk-KMDDG73K.js} +1 -1
  68. package/{chunk-5MM7NNO6.js → chunk-KSTEXKL6.js} +78 -39
  69. package/{chunk-EM3YOZJ4.js → chunk-L2JMH4I5.js} +3 -3
  70. package/{chunk-MM3662RS.js → chunk-LPO6AMQU.js} +780 -64
  71. package/{chunk-D4OWHT5Y.js → chunk-MAYW6V3E.js} +2 -2
  72. package/{chunk-IPAW7XLD.js → chunk-MFVOJ6KF.js} +2 -2
  73. package/{chunk-FDT27L7S.js → chunk-MLEANT7D.js} +19 -17
  74. package/{chunk-7GC3EKUG.js → chunk-MMSQTZCJ.js} +3 -3
  75. package/{chunk-XFKZ3MCV.js → chunk-MR3ITQEV.js} +344 -88
  76. package/{chunk-CBHGZRCE.js → chunk-MYOH447Z.js} +1 -1
  77. package/{chunk-6MPAEODB.js → chunk-NHEWV5FD.js} +17 -3
  78. package/{chunk-ZEHTARJA.js → chunk-NLFTBC6S.js} +321 -150
  79. package/{chunk-SKPPKHD3.js → chunk-OLUKIUX6.js} +2 -2
  80. package/{chunk-SUKSWFLP.js → chunk-PIG2IUVZ.js} +1 -1
  81. package/{chunk-SEJ5OS6F.js → chunk-PXYBUFDB.js} +4 -0
  82. package/{chunk-2MTE2PEH.js → chunk-QA2C5NKI.js} +5 -739
  83. package/{chunk-L6EQV5OC.js → chunk-QXZH5UDF.js} +3 -3
  84. package/{chunk-TNIX77YM.js → chunk-R5GO3YZP.js} +34 -1
  85. package/{chunk-X5SUT4CN.js → chunk-R7GCGOGZ.js} +6 -6
  86. package/{chunk-4Z245KOA.js → chunk-SH3XD4E2.js} +8 -4
  87. package/{chunk-JGRPBIZZ.js → chunk-SQX235S2.js} +1 -1
  88. package/chunk-TT644UJD.js +188 -0
  89. package/{chunk-IYBIRCQV.js → chunk-U34KT53V.js} +29 -11
  90. package/{chunk-ANJTRG52.js → chunk-ULQAD7ZY.js} +18 -43
  91. package/{chunk-QDA4Y5O6.js → chunk-UVYSBQ2M.js} +21 -17
  92. package/{chunk-I2RMFLLH.js → chunk-V7PCFWX3.js} +1 -1
  93. package/{chunk-HXHSTRGH.js → chunk-VYNMQ6HW.js} +0 -27
  94. package/{chunk-G47IPDOK.js → chunk-W7FGZRLK.js} +1 -1
  95. package/{chunk-7BSQK2UC.js → chunk-WRCZXJ4N.js} +2 -2
  96. package/{chunk-KX6LPG7W.js → chunk-WYJTNSVL.js} +9 -9
  97. package/{chunk-H4KACZMG.js → chunk-XZIW3Q5B.js} +271 -138
  98. package/chunk-Y5GCAMGP.js +9 -0
  99. package/{chunk-JZX2XLKC.js → chunk-YCRROBDY.js} +1 -1
  100. package/{chunk-FPWT3RH2.js → chunk-YN5DT4JS.js} +22 -22
  101. package/{chunk-SCJD2PNK.js → chunk-YPG7TUQD.js} +3 -3
  102. package/{chunk-EJU23ST5.js → chunk-ZKVS36H3.js} +5069 -3730
  103. package/{chunk-YANF2RR4.js → chunk-ZPKUJROL.js} +1 -1
  104. package/{chunk-TYND6RDQ.js → chunk-ZZDVBZOP.js} +74 -3
  105. package/{commandRegistry-OUBQIF62.js → commandRegistry-DR2RPWK6.js} +88 -96
  106. package/{contentThunks-B3FRQGP7.js → contentThunks-CSJDJDEJ.js} +21 -21
  107. package/{createAgentAutomationAction-T2YFJ6MY.js → createAgentAutomationAction-ISEUEQSY.js} +21 -21
  108. package/{createDialogAction-2NFGFBXW.js → createDialogAction-HUCFOZY3.js} +25 -25
  109. package/{createPageAction-LDAVZDN7.js → createPageAction-DT5CYXCL.js} +24 -25
  110. package/{dbSlice-5QGKMQLO.js → dbSlice-6PVPY44C.js} +7 -7
  111. package/{deleteFile-EW6QNRRT.js → deleteFile-YM6NDPAR.js} +5 -5
  112. package/{dialogCommands-ZLBEAQHE.js → dialogCommands-3W6AIUXT.js} +35 -32
  113. package/{dialogSlice-64S3J6CP.js → dialogSlice-WJEEPG4W.js} +20 -20
  114. package/{dist-NJC2W7I4.js → dist-Q2JSMAKA.js} +7 -361
  115. package/{docCreateCommands-XOG5BBFQ.js → docCreateCommands-KQHQNLRX.js} +32 -30
  116. package/{docDeleteCommands-NCW3BBRX.js → docDeleteCommands-O3DWFX2W.js} +33 -31
  117. package/{docReadCommands-OT7X44Y3.js → docReadCommands-2U2BUONC.js} +32 -30
  118. package/{docStore-NIP7OO4I.js → docStore-7JPYT25V.js} +8 -8
  119. package/{docUpdateCommands-JW7OWW2J.js → docUpdateCommands-MF3C52XI.js} +32 -30
  120. package/{getPricing-TX35D7PI.js → getPricing-XQ3N3RBP.js} +2 -2
  121. package/{handleSendMessageAction-TOKA7ED7.js → handleSendMessageAction-BV5FMID4.js} +43 -39
  122. package/index.js +8 -8
  123. package/{localRuntimeAdapter-EQM6LFYC.js → localRuntimeAdapter-6FBEJJ4D.js} +70 -69
  124. package/{localRuntimeAuthority-JDAD7CB6.js → localRuntimeAuthority-BPN5OAQG.js} +2 -2
  125. package/{localRuntimeDb-CVC62PM5.js → localRuntimeDb-QIVAXMUL.js} +1 -1
  126. package/{machineCommands-WJ7FZ67T.js → machineCommands-WCAFDI5N.js} +80 -79
  127. package/{machineWsRunDispatch-BQT4DEA2.js → machineWsRunDispatch-ZF6BBQ3X.js} +70 -71
  128. package/{memberThunks-KRV5YXOB.js → memberThunks-AZINUM4S.js} +10 -10
  129. package/package.json +6 -2
  130. package/{profileConfig-ZGOFORWV.js → profileConfig-KN3N2BLF.js} +7 -1
  131. package/{providerPresetApply-CRZFMQD5.js → providerPresetApply-PKUOHQJT.js} +5 -5
  132. package/{providerRegistry-7IS43D3X.js → providerRegistry-HNQLIFN2.js} +5 -5
  133. package/{read-5KAZHHDM.js → read-7JPIWRBQ.js} +5 -5
  134. package/{readDocTool-5QO34OSX.js → readDocTool-AAQTB2Y3.js} +1 -1
  135. package/{readlineWorkspace-JHJSU5DS.js → readlineWorkspace-I5MHMEUE.js} +375 -200
  136. package/{removeDialogAgentAction-6X63HMI3.js → removeDialogAgentAction-RMVRILLK.js} +9 -9
  137. package/{runAgentClientLoop-5QIGEALK.js → runAgentClientLoop-TSNSRQEP.js} +59 -54
  138. package/{runtimeDoctorCommands-56NWKNON.js → runtimeDoctorCommands-MMCP4B4U.js} +12 -12
  139. package/{secretCommands-ZXZRLR3R.js → secretCommands-DNY56NSU.js} +11 -1
  140. package/{setDialogExtraReferencesAction-4MAYKKYW.js → setDialogExtraReferencesAction-L3V7JTMG.js} +8 -8
  141. package/{setPrimaryDialogAgentAction-EGBAMREH.js → setPrimaryDialogAgentAction-X52JQGTJ.js} +9 -9
  142. package/settingThunks-N6XFWPOU.js +923 -0
  143. package/{spaceCommands-ZWDPTURU.js → spaceCommands-NDPGHDMD.js} +29 -27
  144. package/{streamAgentChatTurn-456DWXNY.js → streamAgentChatTurn-RJLDV4WZ.js} +154 -95
  145. package/{switchDialogAgentAction-YBKTD6DO.js → switchDialogAgentAction-ZJ5CGU7J.js} +7 -7
  146. package/{tableCommands-U3QDY4L6.js → tableCommands-IVC5S7Y3.js} +11 -11
  147. package/{toolApiClient-7WSJJJBV.js → toolApiClient-HGNO53TC.js} +2 -2
  148. package/{tools-IWNXKK4Y.js → tools-X6QNIYFJ.js} +43 -44
  149. package/{tuiSummaryLlmCaller-KLK6K3Q3.js → tuiSummaryLlmCaller-FESHBDTT.js} +7 -7
  150. package/{updateCommands-NQXAGFM7.js → updateCommands-FJHGWD3Q.js} +5 -3
  151. package/{updateDialogTitleAction-SX53FZWO.js → updateDialogTitleAction-6LURCTMG.js} +21 -21
  152. package/{workloadLifecycle-36DXRZKU.js → workloadLifecycle-6O6PMISX.js} +2 -2
  153. package/chunk-IA7TRNNR.js +0 -11
  154. package/chunk-UKZX3NHN.js +0 -48
  155. package/chunk-VAZHH6FO.js +0 -7012
  156. package/chunk-W4S6OTSC.js +0 -35
  157. package/clipboardy-GCO3GT3I.js +0 -11793
  158. package/settingThunks-FTDRZNSJ.js +0 -1371
  159. package/{agentGrantCommands-HOJ3JBBQ.js → agentGrantCommands-5DPHYEKP.js} +3 -3
  160. package/{chromeOpsCommands-3Z34RKSE.js → chromeOpsCommands-GZVVK7HU.js} +4 -4
  161. package/{chunk-XETG4RIX.js → chunk-AETZ7AD6.js} +4 -4
  162. package/{chunk-2IXDJNZI.js → chunk-GAGGEA7D.js} +3 -3
  163. package/{memoryCommands-CUNBFRVS.js → memoryCommands-ZS3VQJAL.js} +3 -3
  164. package/{offlineMarxistsAgentCommand-2QTHJCHV.js → offlineMarxistsAgentCommand-3GLX4QQY.js} +3 -3
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveAuthGuidanceState
3
- } from "./chunk-K43ZF2C3.js";
3
+ } from "./chunk-JPPQ3GUO.js";
4
4
  import {
5
5
  fetchCiStatus,
6
6
  summarizeLatest
@@ -13,7 +13,7 @@ import {
13
13
  listRemoteAgents,
14
14
  listRemoteAgentsAcrossServers,
15
15
  normalizeListedAgent
16
- } from "./chunk-EM3YOZJ4.js";
16
+ } from "./chunk-L2JMH4I5.js";
17
17
  import {
18
18
  refreshSubscriptionQuotas
19
19
  } from "./chunk-U4STABYN.js";
@@ -34,11 +34,11 @@ import {
34
34
  computeBaselineContextTokens,
35
35
  countPhysicalLines,
36
36
  createCollapsedPasteStore,
37
+ createIdleHeapReleaser,
37
38
  detectSystemBrightnessFromEnv,
38
39
  dimCliText,
39
40
  displayWidth,
40
41
  emitTerminalProgramStatus,
41
- estimateMessagesTokens,
42
42
  expandRangeToCollapsedPasteChips,
43
43
  findCollapsedPasteSpanAt,
44
44
  fitAnsiLine,
@@ -47,7 +47,6 @@ import {
47
47
  formatTokenCount,
48
48
  getActiveThemeMode,
49
49
  getActiveThemeName,
50
- historyTokensBeforeLatestAssistant,
51
50
  isBalanceExhaustedError,
52
51
  isRunResultStalledOrTruncated,
53
52
  padOrTruncateToWidth,
@@ -91,20 +90,20 @@ import {
91
90
  wrapTextToLines,
92
91
  wrapTranscriptLine,
93
92
  wrapTranscriptLineWithLayout
94
- } from "./chunk-ZEHTARJA.js";
93
+ } from "./chunk-NLFTBC6S.js";
95
94
  import "./chunk-6QDYSCPW.js";
96
- import "./chunk-KOB75UNU.js";
95
+ import "./chunk-FHG46N5C.js";
97
96
  import {
98
97
  getReadableCliDb
99
- } from "./chunk-P5QACQDK.js";
98
+ } from "./chunk-62TBKWTV.js";
100
99
  import {
101
100
  RUN_WAKE_CHANNEL_ENV,
102
101
  clearCliLocalRuntimePreparedAgentCache,
103
102
  createCliLocalRuntimeAdapter,
104
103
  createOriginShellGrant,
105
104
  readTimestamp
106
- } from "./chunk-EJU23ST5.js";
107
- import "./chunk-7KYVUFDG.js";
105
+ } from "./chunk-ZKVS36H3.js";
106
+ import "./chunk-G3VYRPTV.js";
108
107
  import "./chunk-6MXDOUMH.js";
109
108
  import {
110
109
  dailyWelcomeTip,
@@ -112,11 +111,11 @@ import {
112
111
  parseCliLocale,
113
112
  setCliLocale,
114
113
  t
115
- } from "./chunk-SW4S4XYB.js";
114
+ } from "./chunk-2AB2HA4M.js";
116
115
  import {
117
116
  defaultOpenBrowser,
118
117
  saveTokenLogin
119
- } from "./chunk-36OMEXXR.js";
118
+ } from "./chunk-DLV3H464.js";
120
119
  import "./chunk-TY3TIUJK.js";
121
120
  import {
122
121
  isHiddenFromDialogList,
@@ -124,19 +123,20 @@ import {
124
123
  normalizeDialogRecord,
125
124
  readDialogSnapshot,
126
125
  sortDialogs
127
- } from "./chunk-FDT27L7S.js";
126
+ } from "./chunk-MLEANT7D.js";
128
127
  import "./chunk-ID4G2MAR.js";
129
128
  import {
130
129
  listUserRecordsFromServers,
131
130
  readLiveDbRecordAfterTombstoneMerge
132
- } from "./chunk-G47IPDOK.js";
131
+ } from "./chunk-W7FGZRLK.js";
132
+ import "./chunk-Y5GCAMGP.js";
133
133
  import {
134
134
  deleteDbRecord,
135
135
  queryUserRecords,
136
136
  readDbRecord
137
- } from "./chunk-HKT6QXP3.js";
137
+ } from "./chunk-5IKRTRRR.js";
138
138
  import "./chunk-VP3BINY7.js";
139
- import "./chunk-UUPR3TD7.js";
139
+ import "./chunk-BL4HFN6L.js";
140
140
  import {
141
141
  NOLO_DEFAULT_AGENT_KEY,
142
142
  resolveCliAgentKeyInput
@@ -145,119 +145,126 @@ import "./chunk-VL5KOY2C.js";
145
145
  import "./chunk-S73EPYNC.js";
146
146
  import "./chunk-ZEZC7IIM.js";
147
147
  import "./chunk-VIWDGTDA.js";
148
- import "./chunk-6MJNEXUU.js";
148
+ import "./chunk-HGDKT2D6.js";
149
149
  import "./chunk-BU2YQBV4.js";
150
150
  import "./chunk-BMQ2MJUK.js";
151
- import "./chunk-IPAW7XLD.js";
151
+ import "./chunk-MFVOJ6KF.js";
152
152
  import "./chunk-ATNTHIZI.js";
153
- import "./chunk-T6CBQ6BN.js";
153
+ import "./chunk-INFHX73M.js";
154
154
  import "./chunk-JEXVIMYZ.js";
155
155
  import {
156
156
  prepareTools
157
- } from "./chunk-SKPPKHD3.js";
158
- import {
159
- buildResponseGuidelines
160
- } from "./chunk-W4S6OTSC.js";
157
+ } from "./chunk-OLUKIUX6.js";
161
158
  import "./chunk-HS7MLR74.js";
162
- import "./chunk-XFKZ3MCV.js";
163
- import "./chunk-KX6LPG7W.js";
164
- import "./chunk-I2ZMGXXF.js";
159
+ import "./chunk-MR3ITQEV.js";
160
+ import "./chunk-WYJTNSVL.js";
161
+ import "./chunk-KFHREHUQ.js";
165
162
  import "./chunk-OXME3PEE.js";
166
- import "./chunk-RUNKPFM5.js";
163
+ import "./chunk-K6Y5T4GE.js";
167
164
  import "./chunk-NF64D32W.js";
168
- import "./chunk-XPWGOTBQ.js";
169
- import "./chunk-HXHSTRGH.js";
170
- import "./chunk-CBHGZRCE.js";
171
- import "./chunk-3XZKV7QQ.js";
172
- import "./chunk-YANF2RR4.js";
165
+ import "./chunk-3L2WKC3W.js";
166
+ import "./chunk-VYNMQ6HW.js";
167
+ import "./chunk-MYOH447Z.js";
168
+ import "./chunk-3L5MSPWX.js";
169
+ import "./chunk-ZPKUJROL.js";
173
170
  import "./chunk-VIDPVFP3.js";
174
- import "./chunk-5MM7NNO6.js";
175
- import "./chunk-IA7TRNNR.js";
171
+ import "./chunk-KSTEXKL6.js";
176
172
  import "./chunk-AGIM7IMJ.js";
177
173
  import "./chunk-63W5N6P3.js";
178
174
  import "./chunk-VF4K2QE6.js";
179
- import "./chunk-OH2M7WEU.js";
180
- import "./chunk-WZ6OU4NX.js";
181
- import "./chunk-7A4LJCDR.js";
182
- import "./chunk-ROPSATAB.js";
183
- import "./chunk-SCJD2PNK.js";
184
- import "./chunk-VAZHH6FO.js";
185
- import "./chunk-H4KACZMG.js";
186
- import "./chunk-523DITKR.js";
187
- import "./chunk-UKZX3NHN.js";
175
+ import "./chunk-6Y3ETA2Y.js";
176
+ import "./chunk-BAWAKW7X.js";
177
+ import "./chunk-B3ZIFOFI.js";
178
+ import "./chunk-IF7V3CBU.js";
179
+ import "./chunk-YPG7TUQD.js";
180
+ import "./chunk-IKOKYBYJ.js";
181
+ import {
182
+ estimateMessagesTokens,
183
+ historyTokensBeforeLatestAssistant
184
+ } from "./chunk-XZIW3Q5B.js";
188
185
  import "./chunk-OFFL4DCR.js";
186
+ import "./chunk-523DITKR.js";
189
187
  import "./chunk-QYPE3TS3.js";
190
- import "./chunk-X5SUT4CN.js";
188
+ import "./chunk-R7GCGOGZ.js";
191
189
  import "./chunk-4JH2UMJR.js";
192
190
  import "./chunk-ZJ7UHBJS.js";
193
191
  import "./chunk-BYXBJQAS.js";
194
- import "./chunk-CE7PIHQD.js";
192
+ import "./chunk-ESMZW5PE.js";
195
193
  import "./chunk-5RGU3J7P.js";
196
194
  import "./chunk-OWYYDMGJ.js";
197
195
  import "./chunk-ZRAU6T47.js";
198
196
  import "./chunk-4LCOCOR5.js";
199
197
  import "./chunk-YDH3FDFQ.js";
200
- import "./chunk-C5VPAHIU.js";
198
+ import "./chunk-32ZKZET7.js";
201
199
  import "./chunk-XI7DGLUK.js";
202
- import "./chunk-TZTWMGE3.js";
200
+ import "./chunk-JWEXJ573.js";
203
201
  import "./chunk-UAD2WT54.js";
204
- import "./chunk-HP6O6LTV.js";
202
+ import "./chunk-CDLP56BS.js";
205
203
  import "./chunk-3PVYUPXK.js";
206
- import "./chunk-6MPAEODB.js";
207
- import "./chunk-D4OWHT5Y.js";
208
- import "./chunk-Z6KQDSZW.js";
204
+ import "./chunk-NHEWV5FD.js";
205
+ import "./chunk-MAYW6V3E.js";
206
+ import "./chunk-43OFVLWJ.js";
209
207
  import "./chunk-UEILX4EV.js";
210
- import "./chunk-7BSQK2UC.js";
208
+ import "./chunk-WRCZXJ4N.js";
211
209
  import "./chunk-6Q7UTJKR.js";
212
210
  import "./chunk-QQ56R7KS.js";
213
211
  import "./chunk-OW765XBU.js";
214
- import "./chunk-SEJ5OS6F.js";
212
+ import "./chunk-PXYBUFDB.js";
215
213
  import "./chunk-D2MDMY2M.js";
216
- import "./chunk-4Z245KOA.js";
214
+ import {
215
+ buildSkillDiscoveryContextBlock,
216
+ buildSkillDiscoveryContextLayer
217
+ } from "./chunk-AU7AXHUL.js";
218
+ import "./chunk-SH3XD4E2.js";
217
219
  import {
218
220
  expandEnabledPacks
219
- } from "./chunk-JZX2XLKC.js";
221
+ } from "./chunk-YCRROBDY.js";
220
222
  import "./chunk-EUGTFFO6.js";
221
- import "./chunk-XETG4RIX.js";
223
+ import "./chunk-AETZ7AD6.js";
222
224
  import "./chunk-Y6ORVLSS.js";
225
+ import "./chunk-KHCLMKZZ.js";
223
226
  import {
224
227
  buildLocalWorkspaceOpenAiTools,
225
228
  buildLocalWorkspaceToolset,
226
229
  formatToolOverflowMarker,
227
230
  getProcessRegistry,
228
231
  readCommandActionGatePayload
229
- } from "./chunk-PEO24UB5.js";
230
- import "./chunk-3C2QLERX.js";
232
+ } from "./chunk-5E5VB7PS.js";
233
+ import "./chunk-KMDDG73K.js";
231
234
  import "./chunk-ZNFJWEN4.js";
232
- import "./chunk-L6EQV5OC.js";
235
+ import "./chunk-QXZH5UDF.js";
233
236
  import "./chunk-HNUWUO75.js";
234
237
  import "./chunk-CHOZJMJS.js";
235
238
  import "./chunk-PWTNI4N7.js";
236
- import "./chunk-ANJTRG52.js";
237
- import "./chunk-5ZUL4CUO.js";
238
- import "./chunk-IYBIRCQV.js";
239
+ import "./chunk-ULQAD7ZY.js";
240
+ import "./chunk-U34KT53V.js";
239
241
  import "./chunk-G6OOUQWJ.js";
240
242
  import "./chunk-56GBUMO5.js";
241
243
  import "./chunk-WJZOQR2J.js";
242
244
  import {
245
+ CREDENTIAL_HYGIENE_RULE,
243
246
  DELETE_SAFETY_RED_LINE,
247
+ DISPATCH_BACKEND_POLICY,
244
248
  PARALLEL_DISPATCH_DEFAULT_RULE,
245
249
  PLATFORM_RISK_CONTROL_RULE,
246
250
  buildConsultationModeBlock,
247
251
  buildIdentityBlock,
248
252
  buildRuntimeGuidanceBlocks,
253
+ resolveResponseGuidelines,
249
254
  resolveToolGuidedSections
250
- } from "./chunk-TYND6RDQ.js";
251
- import "./chunk-6TF64IF2.js";
252
- import "./chunk-QLQ573SU.js";
255
+ } from "./chunk-ZZDVBZOP.js";
256
+ import "./chunk-4L4K6YR7.js";
257
+ import "./chunk-3M52COK5.js";
253
258
  import {
254
259
  isQuotaExhaustedError
255
260
  } from "./chunk-3MZAGMYY.js";
261
+ import "./chunk-TT644UJD.js";
256
262
  import "./chunk-2MBTWINN.js";
257
263
  import {
258
264
  extractReferenceKeysFromMessage,
259
265
  normalizeUsage
260
- } from "./chunk-ZWG3C7VI.js";
266
+ } from "./chunk-F3SOW2EU.js";
267
+ import "./chunk-5ZUL4CUO.js";
261
268
  import {
262
269
  DEFAULT_CONTEXT_WINDOW,
263
270
  buildCompactionMetricsFromPlan,
@@ -269,7 +276,7 @@ import {
269
276
  getModelContextWindow,
270
277
  planCompression,
271
278
  serializeMessageContent
272
- } from "./chunk-2MTE2PEH.js";
279
+ } from "./chunk-QA2C5NKI.js";
273
280
  import {
274
281
  clipCompactText
275
282
  } from "./chunk-5MMAK75Q.js";
@@ -280,6 +287,15 @@ import "./chunk-LIQJTQRN.js";
280
287
  import "./chunk-UHTDNB5Y.js";
281
288
  import "./chunk-KX6YBIHG.js";
282
289
  import "./chunk-7DPNBQSV.js";
290
+ import {
291
+ buildMemoryOverlayLayer,
292
+ buildMemoryUseGuidanceLayer,
293
+ partitionScopedBlocks,
294
+ renderTurnContextBlocksWithScope
295
+ } from "./chunk-VEA7H5FG.js";
296
+ import {
297
+ buildUserResponseLanguageContext
298
+ } from "./chunk-4VJAC32I.js";
283
299
  import {
284
300
  canonicalizeToolNames
285
301
  } from "./chunk-5EBLANFT.js";
@@ -298,16 +314,13 @@ import {
298
314
  import "./chunk-5EMSBTQ6.js";
299
315
  import "./chunk-I42VC5KR.js";
300
316
  import "./chunk-U6VC4MU4.js";
301
- import "./chunk-PSJWPSKS.js";
302
- import "./chunk-JGRPBIZZ.js";
303
- import "./chunk-WWC7I6TA.js";
304
317
  import {
305
318
  backfillRunRecordParentDialog,
306
319
  checkStaleRun,
307
320
  isRunRecordClaimed,
308
321
  listRunRecords,
309
322
  readRunRecord
310
- } from "./chunk-MM3662RS.js";
323
+ } from "./chunk-LPO6AMQU.js";
311
324
  import {
312
325
  clipText,
313
326
  formatDuration,
@@ -321,24 +334,11 @@ import {
321
334
  import {
322
335
  estimateTokenCount
323
336
  } from "./chunk-PSCNXBYA.js";
324
- import {
325
- resolvePlatformAuthToken
326
- } from "./chunk-SUKSWFLP.js";
327
- import "./chunk-I2RMFLLH.js";
328
- import "./chunk-TRW43TSC.js";
329
- import "./chunk-5BHQICF2.js";
330
- import {
331
- isRecord
332
- } from "./chunk-KUG52IAP.js";
333
- import "./chunk-3EUW3WEO.js";
334
- import "./chunk-2IXDJNZI.js";
337
+ import "./chunk-GAGGEA7D.js";
335
338
  import "./chunk-NMFV26UG.js";
336
339
  import "./chunk-EXAJ6DCR.js";
337
340
  import "./chunk-AWVFQMOV.js";
338
- import {
339
- toErrorMessage
340
- } from "./chunk-HNMXYYJR.js";
341
- import "./chunk-FY4SDK2E.js";
341
+ import "./chunk-FDLDMJTM.js";
342
342
  import "./chunk-GLKOYSRU.js";
343
343
  import {
344
344
  getDiagnostics,
@@ -348,7 +348,7 @@ import {
348
348
  import {
349
349
  checkForCliUpdate,
350
350
  runSelfUpdateDetailed
351
- } from "./chunk-YBNHPX4S.js";
351
+ } from "./chunk-IW64YHXL.js";
352
352
  import {
353
353
  parseUserIdFromAuthToken,
354
354
  resolveAuthToken,
@@ -359,48 +359,53 @@ import {
359
359
  DEFAULT_NOLO_SERVER_URL
360
360
  } from "./chunk-OLZBQWZU.js";
361
361
  import "./chunk-LCBAMY2M.js";
362
- import "./chunk-4SN6J65J.js";
363
- import {
364
- normalizeServerOrigin
365
- } from "./chunk-CF7PE763.js";
366
- import {
367
- asOptionalTrimmedString
368
- } from "./chunk-G3SUCT4W.js";
369
362
  import {
363
+ PERMISSION_GRANT_KINDS,
370
364
  getAgentSelectionAuditPath,
371
365
  getDefaultProfileConfigPath,
372
366
  getProfileTokens,
373
367
  loadProfileConfig,
368
+ permissionGrantList,
374
369
  readLastAgentSelectionAudit,
375
370
  saveProfileAgentSelection,
376
371
  saveProfileLocale,
372
+ saveProfilePermissionGrant,
377
373
  saveProfileTokens
378
- } from "./chunk-TNIX77YM.js";
374
+ } from "./chunk-R5GO3YZP.js";
379
375
  import {
380
376
  readPipeText,
381
377
  resolveDefaultSpawn,
382
378
  spawnProcess
383
379
  } from "./chunk-Y6ROFCZO.js";
384
380
  import "./chunk-FYYSDHVQ.js";
381
+ import "./chunk-EWO77ZGF.js";
382
+ import "./chunk-SQX235S2.js";
383
+ import "./chunk-WWC7I6TA.js";
384
+ import {
385
+ resolvePlatformAuthToken
386
+ } from "./chunk-PIG2IUVZ.js";
387
+ import "./chunk-V7PCFWX3.js";
388
+ import "./chunk-6EQD4AQL.js";
389
+ import "./chunk-5BHQICF2.js";
390
+ import {
391
+ isRecord
392
+ } from "./chunk-KUG52IAP.js";
393
+ import "./chunk-3EUW3WEO.js";
394
+ import {
395
+ toErrorMessage
396
+ } from "./chunk-HNMXYYJR.js";
397
+ import "./chunk-4SN6J65J.js";
398
+ import {
399
+ normalizeServerOrigin
400
+ } from "./chunk-CF7PE763.js";
401
+ import {
402
+ asOptionalTrimmedString
403
+ } from "./chunk-G3SUCT4W.js";
385
404
  import "./chunk-CGFNDIKK.js";
386
405
  import {
387
406
  asTrimmedLowercaseString
388
407
  } from "./chunk-QSJ3HFEF.js";
389
408
  import "./chunk-ZWQUWF6W.js";
390
- import {
391
- buildSkillDiscoveryContextBlock,
392
- buildSkillDiscoveryContextLayer
393
- } from "./chunk-AU7AXHUL.js";
394
- import "./chunk-KHCLMKZZ.js";
395
- import {
396
- buildMemoryOverlayLayer,
397
- buildMemoryUseGuidanceLayer,
398
- partitionScopedBlocks,
399
- renderTurnContextBlocksWithScope
400
- } from "./chunk-VEA7H5FG.js";
401
- import {
402
- buildUserResponseLanguageContext
403
- } from "./chunk-4VJAC32I.js";
404
409
  import "./chunk-4VNS5WPM.js";
405
410
 
406
411
  // packages/cli/tui/shellApprovalSession.ts
@@ -450,6 +455,44 @@ import { createInterface } from "node:readline";
450
455
  import { PassThrough } from "node:stream";
451
456
  import { stdin as defaultInput, stdout as defaultOutput } from "node:process";
452
457
 
458
+ // packages/cli/tui/permissionGrantPersist.ts
459
+ function createPermissionGrantEnabler(kind, deps) {
460
+ return () => {
461
+ deps.setGrants({ ...deps.getGrants() ?? {}, [kind]: true });
462
+ let saved = null;
463
+ try {
464
+ saved = saveProfilePermissionGrant(kind, true);
465
+ } catch {
466
+ saved = null;
467
+ }
468
+ deps.scheduleRender();
469
+ if (!saved) deps.onPersistFailed();
470
+ };
471
+ }
472
+ function persistPermissionGrantChanges(before, after) {
473
+ const changed = PERMISSION_GRANT_KINDS.filter(
474
+ (kind) => before?.[kind] === true !== (after?.[kind] === true)
475
+ );
476
+ let allSaved = true;
477
+ for (const kind of changed) {
478
+ let saved = null;
479
+ try {
480
+ saved = saveProfilePermissionGrant(kind, after?.[kind] === true);
481
+ } catch {
482
+ saved = null;
483
+ }
484
+ if (!saved) allSaved = false;
485
+ }
486
+ return allSaved;
487
+ }
488
+ function createSnapshotGuardedApproval(kind, getGrants, approve) {
489
+ const snapshot = getGrants()?.[kind] === true;
490
+ return () => {
491
+ if (getGrants()?.[kind] === true !== snapshot) return;
492
+ approve();
493
+ };
494
+ }
495
+
453
496
  // packages/core/crypto.ts
454
497
  import nacl from "tweetnacl";
455
498
 
@@ -672,6 +715,7 @@ var SSR_SNAPSHOT = Object.freeze({
672
715
  });
673
716
  var AccountSessionCore = class {
674
717
  snapshot;
718
+ sessionGeneration = 0;
675
719
  tokenByUserId = /* @__PURE__ */ new Map();
676
720
  listeners = /* @__PURE__ */ new Set();
677
721
  constructor(initial) {
@@ -681,6 +725,7 @@ var AccountSessionCore = class {
681
725
  const parsedActive = rawActiveToken ? parseUserToken(rawActiveToken) : null;
682
726
  const hasValidPair = typeof rawActiveId === "string" && rawActiveId.length > 0 && parsedActive !== null && parsedActive.userId === rawActiveId && accounts.some((account) => account.userId === rawActiveId);
683
727
  this.snapshot = {
728
+ sessionGeneration: this.sessionGeneration,
684
729
  accounts,
685
730
  activeAccountId: hasValidPair ? rawActiveId : null,
686
731
  activeToken: hasValidPair ? rawActiveToken : null,
@@ -708,8 +753,11 @@ var AccountSessionCore = class {
708
753
  listener();
709
754
  }
710
755
  }
711
- setSnapshot(next) {
712
- this.snapshot = next;
756
+ setSnapshot(next, forceAdvanceSession = false) {
757
+ if (forceAdvanceSession || next.activeAccountId !== this.snapshot.activeAccountId || next.activeToken !== this.snapshot.activeToken) {
758
+ this.sessionGeneration += 1;
759
+ }
760
+ this.snapshot = { ...next, sessionGeneration: this.sessionGeneration };
713
761
  this.emit();
714
762
  }
715
763
  initializeFromTokens(tokens, preferredActiveAccountId) {
@@ -786,7 +834,7 @@ var AccountSessionCore = class {
786
834
  activeToken: token,
787
835
  initialized: true,
788
836
  transition: "idle"
789
- });
837
+ }, true);
790
838
  return true;
791
839
  }
792
840
  completeTransition() {
@@ -3518,14 +3566,26 @@ async function runConfirmDialog(args) {
3518
3566
  value: false
3519
3567
  }
3520
3568
  ];
3569
+ const rejectIndex = items.length - 1;
3521
3570
  let titleText = args.request.title;
3522
3571
  let bodyText = args.request.body;
3572
+ let localRunClass = false;
3523
3573
  if (args.request.action === "destructive_shell_command") {
3524
3574
  titleText = t("dialogConfirmTitle");
3525
3575
  bodyText = t("dialogConfirmBody");
3576
+ localRunClass = true;
3526
3577
  } else if (args.request.action === "external_file_access") {
3527
3578
  titleText = t("dialogConfirmExternalFileTitle");
3528
3579
  bodyText = t("dialogConfirmExternalFileBody");
3580
+ localRunClass = true;
3581
+ } else if (args.request.action === "file_write") {
3582
+ titleText = t("dialogConfirmFileWriteTitle");
3583
+ bodyText = t("dialogConfirmFileWriteBody");
3584
+ localRunClass = true;
3585
+ }
3586
+ if (localRunClass && bodyText && args.onApprove) {
3587
+ bodyText = `${bodyText}
3588
+ ${t("dialogConfirmRememberLocal")}`;
3529
3589
  }
3530
3590
  const terminalWidth = typeof output.columns === "number" && output.columns > 0 ? output.columns : FALLBACK_TERMINAL_WIDTH;
3531
3591
  const titleLines = [
@@ -3539,14 +3599,14 @@ async function runConfirmDialog(args) {
3539
3599
  const result = await runSelectDialog({
3540
3600
  items,
3541
3601
  signal: args.signal,
3542
- initialIndex: 1,
3602
+ initialIndex: rejectIndex,
3543
3603
  titleLines,
3544
3604
  input,
3545
3605
  output,
3546
- // Fixed by the modal-ownership spec: this two-item gate never owns the
3547
- // wheel — "transcript" routes wheel/page events to the workspace history,
3606
+ // Fixed by the modal-ownership spec: this gate never owns the wheel —
3607
+ // "transcript" routes wheel/page events to the workspace history,
3548
3608
  // and when no transcript callback exists (standalone runs) the event is
3549
- // simply dropped. The wheel must never flip Allow/Cancel.
3609
+ // simply dropped. The wheel must never flip Approve/Reject.
3550
3610
  inputPolicy: { wheel: "transcript", pageKeys: "transcript" },
3551
3611
  onTranscriptScroll: args.onTranscriptScroll,
3552
3612
  mouseEnabled: args.mouseEnabled,
@@ -3559,7 +3619,14 @@ async function runConfirmDialog(args) {
3559
3619
  if (result.kind === "cancelled") {
3560
3620
  return false;
3561
3621
  }
3562
- return result.item.value;
3622
+ const chosen = result.item;
3623
+ if (chosen.value === true && args.onApprove) {
3624
+ try {
3625
+ args.onApprove();
3626
+ } catch {
3627
+ }
3628
+ }
3629
+ return chosen.value;
3563
3630
  }
3564
3631
 
3565
3632
  // packages/cli/tui/terminalNotification.ts
@@ -4856,44 +4923,6 @@ function createRunRegistryPoller(deps) {
4856
4923
  };
4857
4924
  }
4858
4925
 
4859
- // packages/cli/tui/idleHeapRelease.ts
4860
- var IDLE_HEAP_RELEASE_DELAY_MS = 2e3;
4861
- function createIdleHeapReleaser(options = {}) {
4862
- const env = options.env ?? process.env;
4863
- const bun = "bun" in options ? options.bun : globalThis.Bun;
4864
- const disabled = env.NOLO_TUI_IDLE_HEAP_RELEASE === "0" || typeof bun?.gc !== "function" || typeof bun?.shrink !== "function";
4865
- if (disabled) return { schedule() {
4866
- }, cancel() {
4867
- } };
4868
- const delayMs = options.delayMs ?? IDLE_HEAP_RELEASE_DELAY_MS;
4869
- const setTimer = options.setTimer ?? ((fn, ms) => {
4870
- const handle = setTimeout(fn, ms);
4871
- handle.unref?.();
4872
- return handle;
4873
- });
4874
- const clearTimer = options.clearTimer ?? ((handle) => clearTimeout(handle));
4875
- let pending = null;
4876
- const release = () => {
4877
- pending = null;
4878
- try {
4879
- bun.gc(true);
4880
- bun.shrink();
4881
- } catch {
4882
- }
4883
- };
4884
- return {
4885
- schedule() {
4886
- if (pending !== null) clearTimer(pending);
4887
- pending = setTimer(release, delayMs);
4888
- },
4889
- cancel() {
4890
- if (pending === null) return;
4891
- clearTimer(pending);
4892
- pending = null;
4893
- }
4894
- };
4895
- }
4896
-
4897
4926
  // packages/core/chat/internalTurnEvent.ts
4898
4927
  function normalizeRunCompletionShape(record) {
4899
4928
  const runId = String(record.runId ?? record.id ?? "");
@@ -5727,7 +5756,7 @@ async function loadSharp(customLoader) {
5727
5756
  return "default" in loaded && loaded.default ? loaded.default : loaded;
5728
5757
  }
5729
5758
  if (!cachedSharp) {
5730
- const mod = await import("./dist-NJC2W7I4.js");
5759
+ const mod = await import("./dist-Q2JSMAKA.js");
5731
5760
  cachedSharp = mod.default ?? mod;
5732
5761
  }
5733
5762
  return cachedSharp;
@@ -7786,7 +7815,7 @@ function estimateToolSchemas(toolNames) {
7786
7815
  const platformTools = platformNames.length > 0 ? prepareTools([...platformNames]) : [];
7787
7816
  return estimateTokenCount(JSON.stringify([...workspaceTools, ...platformTools]));
7788
7817
  }
7789
- function estimateDefaultCliContextTokens(opts = {}) {
7818
+ function buildCliEstimateSystemText(opts = {}) {
7790
7819
  const cwd = opts.cwd?.trim() || process.cwd();
7791
7820
  const model = opts.model?.trim() || BUILTIN_NOLO_AGENT_MODEL;
7792
7821
  const agentName = opts.agentName?.trim() || BUILTIN_NOLO_AGENT_NAME;
@@ -7801,10 +7830,15 @@ function estimateDefaultCliContextTokens(opts = {}) {
7801
7830
  ]);
7802
7831
  const guidance = buildRuntimeGuidanceBlocks(toolNames);
7803
7832
  const toolSections = resolveToolGuidedSections(toolNames);
7833
+ const responseGuidelines = resolveResponseGuidelines(
7834
+ opts.responseViewport ?? "unknown"
7835
+ );
7804
7836
  const systemParts = [
7805
7837
  // 与实际装配线一致:删除安全红线是系统提示词的最顶层块。
7806
7838
  DELETE_SAFETY_RED_LINE,
7839
+ CREDENTIAL_HYGIENE_RULE,
7807
7840
  PARALLEL_DISPATCH_DEFAULT_RULE,
7841
+ DISPATCH_BACKEND_POLICY,
7808
7842
  PLATFORM_RISK_CONTROL_RULE,
7809
7843
  buildConsultationModeBlock(),
7810
7844
  prompt,
@@ -7818,17 +7852,27 @@ function estimateDefaultCliContextTokens(opts = {}) {
7818
7852
  guidance.contextLayerContract,
7819
7853
  guidance.emailRegistrationWorkflow,
7820
7854
  ...Object.values(toolSections),
7855
+ responseGuidelines.behavior,
7856
+ responseGuidelines.presentation,
7821
7857
  readAgentsMd(cwd),
7822
7858
  buildSkillDiscoveryContextBlock(cwd) ?? ""
7823
7859
  ];
7824
- const systemTokens = estimateTokenCount(
7825
- systemParts.filter((part) => part?.trim()).join("\n\n")
7826
- );
7860
+ return systemParts.filter((part) => part?.trim()).join("\n\n");
7861
+ }
7862
+ function estimateDefaultCliContextTokens(opts = {}) {
7863
+ const toolNames = canonicalizeToolNames([
7864
+ ...canonicalizeToolNames(expandEnabledPacks([...DEFAULT_CLI_PACKS], [])),
7865
+ ...DEFAULT_CLI_PLATFORM_TOOLS
7866
+ ]);
7867
+ const systemTokens = estimateTokenCount(buildCliEstimateSystemText(opts));
7827
7868
  const toolTokens = estimateToolSchemas(toolNames);
7828
7869
  const historyTokens = opts.messages && opts.messages.length > 0 ? estimateMessagesTokens(opts.messages) : opts.historyText ? estimateTokenCount(opts.historyText) : 0;
7829
7870
  return Math.max(0, systemTokens + toolTokens + historyTokens);
7830
7871
  }
7831
7872
 
7873
+ // packages/cli/tui/responseViewport.ts
7874
+ var TUI_RESPONSE_VIEWPORT = "narrow";
7875
+
7832
7876
  // packages/cli/tui/sessionDispatch.ts
7833
7877
  import { ulid } from "ulid";
7834
7878
 
@@ -7880,6 +7924,14 @@ function resolveStatusLineCredits(state) {
7880
7924
  }
7881
7925
  return (base ?? 0) + (session ?? 0) + (live ?? 0);
7882
7926
  }
7927
+ function renderPermissionGrantChip(state) {
7928
+ const local = state.permissionGrants?.local === true;
7929
+ const remote = state.permissionGrants?.remote === true;
7930
+ if (local && remote) return "\u23F5 auto";
7931
+ if (local) return "\u23F5 local";
7932
+ if (remote) return "\u23F5 remote";
7933
+ return null;
7934
+ }
7883
7935
  function renderStatusLine(state, maxWidth) {
7884
7936
  const colorEnabled = resolveCliColorEnabled();
7885
7937
  const sep = themeText(" \xB7 ", "chrome", colorEnabled);
@@ -7907,8 +7959,9 @@ function renderStatusLine(state, maxWidth) {
7907
7959
  if (pendingProcessCount > 0) {
7908
7960
  parts.push(themeText(`\u21AA ${pendingProcessCount} pending`, "info", colorEnabled));
7909
7961
  }
7910
- if (state.autoConfirm === true) {
7911
- parts.push(themeText("\u23F5 auto", "warning", colorEnabled));
7962
+ const grantChip = renderPermissionGrantChip(state);
7963
+ if (grantChip) {
7964
+ parts.push(themeText(grantChip, "warning", colorEnabled));
7912
7965
  }
7913
7966
  let surface = colorEnabled ? surfaceBackgroundSequence() : "";
7914
7967
  let padWidth = surface ? 2 : 0;
@@ -7986,7 +8039,7 @@ function renderStatusLine(state, maxWidth) {
7986
8039
  }
7987
8040
  if (widthOf(visibleParts) > maxWidth) {
7988
8041
  const budget = maxWidth - padWidth;
7989
- const autoMark = state.autoConfirm === true ? themeText("\u23F5", "warning", colorEnabled) : "";
8042
+ const autoMark = renderPermissionGrantChip(state) ? themeText("\u23F5", "warning", colorEnabled) : "";
7990
8043
  const gitCounts = state.gitStatus ? themeText(
7991
8044
  `\u2442${state.gitStatus.modified > 0 ? `*${state.gitStatus.modified}` : ""}${state.gitStatus.untracked > 0 ? `?${state.gitStatus.untracked}` : ""}`,
7992
8045
  "warning",
@@ -8284,15 +8337,27 @@ function createInitialTuiState(env = process.env) {
8284
8337
  userLanguage: asOptionalTrimmedString(env.NOLO_LANG),
8285
8338
  gitStatus: void 0,
8286
8339
  thinkingDisplay: resolveThinkingDisplayMode(env),
8340
+ // 持久化的授权桶落成 NOLO_PERMISSION_GRANTS(如 "local,remote");
8341
+ // 缺失即两桶都未授权(逐次询问)。
8342
+ permissionGrants: parsePermissionGrants(env.NOLO_PERMISSION_GRANTS),
8287
8343
  contextWindow: resolveAgentContextWindow({ agentKey, agentName }),
8288
8344
  estimatedContextTokens: estimateDefaultCliContextTokens({
8289
8345
  cwd,
8290
8346
  agentKey,
8291
8347
  userLanguage: asOptionalTrimmedString(env.NOLO_LANG),
8348
+ responseViewport: TUI_RESPONSE_VIEWPORT,
8292
8349
  ...resolveAgentModelIdentity({ agentKey, agentName })
8293
8350
  })
8294
8351
  };
8295
8352
  }
8353
+ function parsePermissionGrants(raw) {
8354
+ const grants = {};
8355
+ for (const part of (raw ?? "").split(",")) {
8356
+ const kind = part.trim().toLowerCase();
8357
+ if (kind === "local" || kind === "remote") grants[kind] = true;
8358
+ }
8359
+ return grants;
8360
+ }
8296
8361
  function applyAgentSwitch(state, target, historyTurns) {
8297
8362
  const contextWindow = resolveAgentContextWindow({
8298
8363
  agentKey: target.key,
@@ -8311,6 +8376,7 @@ function applyAgentSwitch(state, target, historyTurns) {
8311
8376
  agentName: target.name,
8312
8377
  model: target.model,
8313
8378
  userLanguage: state.userLanguage,
8379
+ responseViewport: TUI_RESPONSE_VIEWPORT,
8314
8380
  messages: historyTurns
8315
8381
  })
8316
8382
  },
@@ -8491,30 +8557,56 @@ ${t("cdUsage")}`
8491
8557
  };
8492
8558
  }
8493
8559
  case "/auto": {
8494
- const normalizedArg = asTrimmedLowercaseString(argText);
8495
- if (!normalizedArg) {
8560
+ const words = asTrimmedLowercaseString(argText).split(/\s+/).filter(Boolean);
8561
+ const grants = state.permissionGrants ?? {};
8562
+ const stateLine = () => t(
8563
+ "autoStateLine",
8564
+ grants.local === true ? t("autoStateOnPersisted") : t("autoStateOff"),
8565
+ grants.remote === true ? t("autoStateOnPersisted") : t("autoStateOff")
8566
+ );
8567
+ const applyKinds = (kinds, on) => {
8568
+ const next = { ...grants };
8569
+ for (const kind of kinds) {
8570
+ if (on) next[kind] = true;
8571
+ else delete next[kind];
8572
+ }
8573
+ return { ...state, permissionGrants: next };
8574
+ };
8575
+ if (words.length === 0) {
8576
+ return { nextState: state, output: `${stateLine()}
8577
+ ${t("autoUsage")}` };
8578
+ }
8579
+ const [scope, action] = words;
8580
+ if (scope === "reset") {
8496
8581
  return {
8497
- nextState: state,
8498
- output: `${t("autoCurrent", state.autoConfirm ? "on" : "off")}
8499
- ${t("autoUsage")}`
8582
+ nextState: applyKinds(["local", "remote"], false),
8583
+ output: t("autoReset")
8500
8584
  };
8501
8585
  }
8502
- if (normalizedArg === "on") {
8586
+ if (scope === "on" || scope === "off") {
8587
+ const on = scope === "on";
8503
8588
  return {
8504
- nextState: { ...state, autoConfirm: true },
8505
- output: t("autoOn")
8589
+ nextState: applyKinds(["local", "remote"], on),
8590
+ output: t(
8591
+ on ? "autoGrantOn" : "autoGrantOff",
8592
+ `${t("autoKindLocal")} + ${t("autoKindRemote")}`,
8593
+ on ? "/auto off" : "/auto on"
8594
+ )
8506
8595
  };
8507
8596
  }
8508
- if (normalizedArg === "off") {
8597
+ if ((scope === "local" || scope === "remote") && (action === "on" || action === "off")) {
8598
+ const on = action === "on";
8509
8599
  return {
8510
- nextState: { ...state, autoConfirm: false },
8511
- output: t("autoOff")
8600
+ nextState: applyKinds([scope], on),
8601
+ output: t(
8602
+ on ? "autoGrantOn" : "autoGrantOff",
8603
+ scope === "local" ? t("autoKindLocal") : t("autoKindRemote"),
8604
+ `/auto ${scope} ${on ? "off" : "on"}`
8605
+ )
8512
8606
  };
8513
8607
  }
8514
- return {
8515
- nextState: state,
8516
- output: t("autoUsage")
8517
- };
8608
+ return { nextState: state, output: `${stateLine()}
8609
+ ${t("autoUsage")}` };
8518
8610
  }
8519
8611
  case "/tasks":
8520
8612
  case "/jobs":
@@ -8683,6 +8775,7 @@ ${t("autoUsage")}`
8683
8775
  cwd: state.cwd,
8684
8776
  agentKey: state.agentKey,
8685
8777
  userLanguage: locale,
8778
+ responseViewport: TUI_RESPONSE_VIEWPORT,
8686
8779
  messages: historyTurns,
8687
8780
  ...resolveAgentModelIdentity({
8688
8781
  agentKey: state.agentKey,
@@ -8957,6 +9050,7 @@ function applyAgentSwitchState(state, target, messages) {
8957
9050
  agentName: target.name,
8958
9051
  model: target.model,
8959
9052
  userLanguage: state.userLanguage,
9053
+ responseViewport: TUI_RESPONSE_VIEWPORT,
8960
9054
  messages
8961
9055
  }),
8962
9056
  turnTokens: void 0,
@@ -11738,10 +11832,6 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
11738
11832
  // 宿主环境层(session-scope 稳定前缀):快速注入当前系统发行版、架构与桌面环境
11739
11833
  buildHostEnvironmentLayer()
11740
11834
  ];
11741
- const responseGuidelinesBlock = {
11742
- content: buildResponseGuidelines(true),
11743
- cacheScope: "session"
11744
- };
11745
11835
  let memoryPromptBlock = state.cachedMemoryOverlay;
11746
11836
  if (options.abortSignal?.aborted) {
11747
11837
  throw options.abortSignal.reason ?? new DOMException("Aborted", "AbortError");
@@ -11772,7 +11862,6 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
11772
11862
  }] : [];
11773
11863
  const contextBlockScopes = partitionScopedBlocks([
11774
11864
  ...renderTurnContextBlocksWithScope(layers),
11775
- responseGuidelinesBlock,
11776
11865
  ...renderTurnContextBlocksWithScope([memoryUseGuidanceLayer]),
11777
11866
  // Attached skill bodies are already self-contained sections built by
11778
11867
  // buildSkillContextBlocks; they stay turn-scope because the user can
@@ -11804,6 +11893,10 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
11804
11893
  ...options.onToolExecutionLocation ? { onToolExecutionLocation: options.onToolExecutionLocation } : {},
11805
11894
  ...state.agentKey === DEFAULT_TUI_AGENT_KEY && env.NOLO_AUTO_ROUTE !== "0" ? { dialogAgentMode: "auto" } : { dialogAgentMode: "fixed" },
11806
11895
  runtimeMode: state.runtimeMode,
11896
+ // TUI 是窄屏终端:只声明展示能力,不自拼准则文本。行为段与窄屏排版段
11897
+ // 都由 localLoop(local 线的最终装配边界)经 resolveResponseGuidelines 注入。
11898
+ // 若该轮走远端 server 线,local 线不参与装配,此字段被忽略(server 线自己注入行为段)。
11899
+ responseViewport: TUI_RESPONSE_VIEWPORT,
11807
11900
  // `/lang` updates the in-memory TUI state immediately. Pass that state
11808
11901
  // explicitly so the next real turn cannot keep using the workspace's
11809
11902
  // launch-time NOLO_LANG value while the estimator already uses the new one.
@@ -12131,6 +12224,7 @@ async function resolveActionGate(gate, deps) {
12131
12224
  request: asConfirmPermissionRequest(gate),
12132
12225
  input: deps.input,
12133
12226
  output: deps.output,
12227
+ onApprove: deps.onApprove,
12134
12228
  ...anchor
12135
12229
  })
12136
12230
  );
@@ -12219,7 +12313,7 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
12219
12313
  };
12220
12314
  emitStatus({ state: "working" });
12221
12315
  const gateHandlerWithStatus = async (gate) => {
12222
- if (ctx.state.autoConfirm && isAutoConfirmableFileWriteGate(gate)) {
12316
+ if (ctx.state.permissionGrants?.local === true && isAutoConfirmableFileWriteGate(gate)) {
12223
12317
  return await actionGateHandler(gate);
12224
12318
  }
12225
12319
  emitStatusUnlessForceStopped({
@@ -12233,7 +12327,7 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
12233
12327
  }
12234
12328
  };
12235
12329
  const confirmDestructiveActionWithStatus = confirmDestructiveAction && ctx.output.isTTY === true ? async (request) => {
12236
- if (ctx.state.autoConfirm) return await confirmDestructiveAction(request);
12330
+ if (ctx.state.permissionGrants?.local === true) return await confirmDestructiveAction(request);
12237
12331
  emitStatusUnlessForceStopped({ state: "blocked", kind: "permission" });
12238
12332
  try {
12239
12333
  return await confirmDestructiveAction(request);
@@ -12266,6 +12360,7 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
12266
12360
  agentKey: ctx.state.agentKey,
12267
12361
  agentName: ctx.state.agentName,
12268
12362
  userLanguage: ctx.state.userLanguage,
12363
+ responseViewport: TUI_RESPONSE_VIEWPORT,
12269
12364
  messages: ctx.history.turns,
12270
12365
  ...resolveAgentModelIdentity({
12271
12366
  agentKey: ctx.state.agentKey,
@@ -12488,6 +12583,7 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
12488
12583
  agentKey: ctx.state.agentKey,
12489
12584
  agentName: ctx.state.agentName,
12490
12585
  userLanguage: ctx.state.userLanguage,
12586
+ responseViewport: TUI_RESPONSE_VIEWPORT,
12491
12587
  messages: ctx.history.turns
12492
12588
  }),
12493
12589
  lastAuthorityTurnCount: void 0,
@@ -14063,6 +14159,12 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
14063
14159
  const previousState = host.state;
14064
14160
  const previousAgentKey = host.state.agentKey;
14065
14161
  host.state = result.nextState;
14162
+ if (previousState.permissionGrants?.remote === true && host.state.permissionGrants?.remote !== true) {
14163
+ host.revokeRemoteShellGrants?.();
14164
+ }
14165
+ if (!persistPermissionGrantChanges(previousState.permissionGrants, host.state.permissionGrants)) {
14166
+ emitCommandOutput(t("autoPersistFailed"));
14167
+ }
14066
14168
  const command = line.trim().split(/\s+/)[0];
14067
14169
  if ((command === "/agent" || command === "/switch") && result.nextState !== previousState) {
14068
14170
  clearCliLocalRuntimePreparedAgentCache();
@@ -14122,6 +14224,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
14122
14224
  cwd: host.state.cwd,
14123
14225
  agentKey: host.state.agentKey,
14124
14226
  userLanguage: host.state.userLanguage,
14227
+ responseViewport: TUI_RESPONSE_VIEWPORT,
14125
14228
  ...resolveAgentModelIdentity({
14126
14229
  agentKey: host.state.agentKey,
14127
14230
  agentName: host.state.agentName
@@ -14223,6 +14326,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
14223
14326
  cwd: host.state.cwd,
14224
14327
  agentKey: host.state.agentKey,
14225
14328
  userLanguage: host.state.userLanguage,
14329
+ responseViewport: TUI_RESPONSE_VIEWPORT,
14226
14330
  messages: [
14227
14331
  ...compactResult.summary ? [{ role: "system", content: compactResult.summary }] : [],
14228
14332
  ...compactResult.compactedMessageCount > 0 ? host.history.turns.slice(compactResult.compactedMessageCount) : compactResult.summaryGenerated ? [] : host.history.turns
@@ -14355,6 +14459,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
14355
14459
  agentName: pickResult.name,
14356
14460
  model: pickResult.model,
14357
14461
  userLanguage: host.state.userLanguage,
14462
+ responseViewport: TUI_RESPONSE_VIEWPORT,
14358
14463
  messages: host.history.turns
14359
14464
  }),
14360
14465
  turnTokens: void 0,
@@ -14493,6 +14598,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
14493
14598
  agentKey: host.state.agentKey,
14494
14599
  agentName: host.state.agentName,
14495
14600
  userLanguage: host.state.userLanguage,
14601
+ responseViewport: TUI_RESPONSE_VIEWPORT,
14496
14602
  messages: history.turns,
14497
14603
  ...resolveAgentModelIdentity({
14498
14604
  agentKey: host.state.agentKey,
@@ -14903,7 +15009,7 @@ async function runTuiWorkspace(options) {
14903
15009
  await options.clipboardWriter(text);
14904
15010
  } : (text) => writeClipboard(text, {
14905
15011
  systemWrite: async (t2) => {
14906
- const { default: clipboard } = await import("./clipboardy-GCO3GT3I.js");
15012
+ const { default: clipboard } = await import("clipboardy");
14907
15013
  await clipboard.write(t2);
14908
15014
  },
14909
15015
  output,
@@ -14915,7 +15021,7 @@ async function runTuiWorkspace(options) {
14915
15021
  transport: isRemoteSession(runtimeEnv) ? isInteractiveInput(input) ? "osc52" : "unavailable" : "system"
14916
15022
  });
14917
15023
  const readClipboardText = options.clipboardReader ?? (async () => {
14918
- const { default: clipboard } = await import("./clipboardy-GCO3GT3I.js");
15024
+ const { default: clipboard } = await import("clipboardy");
14919
15025
  return await clipboard.read();
14920
15026
  });
14921
15027
  const readImage = options.clipboardImageReader ?? readClipboardImage;
@@ -14973,6 +15079,19 @@ async function runTuiWorkspace(options) {
14973
15079
  output.write(pinnedAgentNotice);
14974
15080
  initialBannerLineCount += pinnedAgentNotice.split("\n").length - 1;
14975
15081
  }
15082
+ const startupGrantKinds = permissionGrantList(state.permissionGrants);
15083
+ if (startupGrantKinds.length > 0) {
15084
+ output.write(
15085
+ `${t(
15086
+ "autoPersistedStartup",
15087
+ startupGrantKinds.map(
15088
+ (kind) => kind === "local" ? t("autoKindLocal") : t("autoKindRemote")
15089
+ ).join(" + ")
15090
+ )}
15091
+
15092
+ `
15093
+ );
15094
+ }
14976
15095
  let lastSentTitle = null;
14977
15096
  const syncWindowTitle = () => {
14978
15097
  if (!output.isTTY) return;
@@ -15294,6 +15413,16 @@ async function runTuiWorkspace(options) {
15294
15413
  renderHistoryToOutput();
15295
15414
  if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
15296
15415
  };
15416
+ const grantEnablerDeps = {
15417
+ getGrants: () => state.permissionGrants,
15418
+ setGrants: (next) => {
15419
+ state = { ...state, permissionGrants: next };
15420
+ },
15421
+ scheduleRender,
15422
+ onPersistFailed: () => emitCommandOutput(t("autoPersistFailed"))
15423
+ };
15424
+ const approveLocalConfirms = createPermissionGrantEnabler("local", grantEnablerDeps);
15425
+ const approveRemoteShell = createPermissionGrantEnabler("remote", grantEnablerDeps);
15297
15426
  const applyClipboardPasteResult = (outcome, source) => {
15298
15427
  const colorEnabled = resolveCliColorEnabled();
15299
15428
  if (outcome.kind === "image") {
@@ -15351,24 +15480,29 @@ async function runTuiWorkspace(options) {
15351
15480
  id: `child-shell-${crypto.randomUUID()}`,
15352
15481
  tool: "execShell",
15353
15482
  action: "shell-per-call",
15354
- title: "Background shell \u2014 approve this command once?",
15355
- body: `Run: ${request.runId}
15356
- Agent: ${request.agentKey}
15357
- Owner: ${request.ownerUserId}
15358
- Device: ${request.deviceId}
15359
- Workspace: ${request.workspaceRoot}
15360
- ${request.permissionNotice}`,
15483
+ title: t("shellPerCall.title"),
15484
+ body: t(
15485
+ "shellPerCall.body",
15486
+ request.runId,
15487
+ request.agentKey,
15488
+ request.ownerUserId,
15489
+ request.deviceId,
15490
+ request.workspaceRoot,
15491
+ request.permissionNotice
15492
+ ),
15361
15493
  command: request.command
15362
15494
  },
15363
15495
  signal,
15364
15496
  fullCommand: true,
15365
15497
  input,
15366
15498
  output,
15499
+ onApprove: createSnapshotGuardedApproval("remote", () => state.permissionGrants, approveRemoteShell),
15367
15500
  ...anchor
15368
15501
  }));
15369
- }), () => state.autoConfirm === true);
15502
+ }), () => state.permissionGrants?.remote === true);
15370
15503
  const sessionShellGrant = createOriginShellGrant({
15371
15504
  confirm: async (request) => {
15505
+ if (state.permissionGrants?.remote === true) return true;
15372
15506
  return await runWithInputRequiredAttention(
15373
15507
  { output, env: effectiveEnv },
15374
15508
  () => dialogHost.run(
@@ -15394,12 +15528,18 @@ ${request.permissionNotice}`,
15394
15528
  },
15395
15529
  input,
15396
15530
  output,
15531
+ onApprove: createSnapshotGuardedApproval("remote", () => state.permissionGrants, approveRemoteShell),
15397
15532
  ...anchor
15398
15533
  })
15399
15534
  )
15400
15535
  );
15401
15536
  }
15402
15537
  });
15538
+ const shellGrantForTurns = {
15539
+ isGranted: () => state.permissionGrants?.remote === true || sessionShellGrant.isGranted(),
15540
+ requestGrant: (request) => sessionShellGrant.requestGrant(request),
15541
+ revoke: () => sessionShellGrant.revoke()
15542
+ };
15403
15543
  let turnIdentity = 0;
15404
15544
  const turnCtx = {
15405
15545
  get state() {
@@ -15468,7 +15608,7 @@ ${request.permissionNotice}`,
15468
15608
  },
15469
15609
  // 分享 OAuth agent 的 shell 会话授权(块 D):会话级单例透传给 turn
15470
15610
  // 执行路径;撤销经 /shell-revoke 或设置面板调 sessionShellGrant.revoke()。
15471
- shellGrant: sessionShellGrant,
15611
+ shellGrant: shellGrantForTurns,
15472
15612
  shellApprovalSession: childShellApprovals.session,
15473
15613
  // 运行位置展示(块 D):owner-required 场景 adapter 回调一次;渲染一行
15474
15614
  // 「工具在 <deviceName>(<deviceId>) · workspace <root> · status: <s>」。
@@ -15544,6 +15684,10 @@ ${request.permissionNotice}`,
15544
15684
  get fixedInput() {
15545
15685
  return fixedInput;
15546
15686
  },
15687
+ revokeRemoteShellGrants: () => {
15688
+ sessionShellGrant.revoke();
15689
+ childShellApprovals.revoke();
15690
+ },
15547
15691
  history,
15548
15692
  pasteStore,
15549
15693
  dialogHost,
@@ -15570,6 +15714,14 @@ ${request.permissionNotice}`,
15570
15714
  const wasGranted = sessionShellGrant.isGranted();
15571
15715
  sessionShellGrant.revoke();
15572
15716
  childShellApprovals.revoke();
15717
+ if (state.permissionGrants?.remote === true) {
15718
+ const nextGrants = { ...state.permissionGrants };
15719
+ delete nextGrants.remote;
15720
+ state = { ...state, permissionGrants: nextGrants };
15721
+ if (!persistPermissionGrantChanges({ remote: true }, nextGrants)) {
15722
+ emitCommandOutput(t("autoPersistFailed"));
15723
+ }
15724
+ }
15573
15725
  emitCommandOutput(
15574
15726
  wasGranted ? t("shellGrant.revoked") : t("shellGrant.revokeNone"),
15575
15727
  "/shell-revoke"
@@ -15693,7 +15845,7 @@ ${request.permissionNotice}`,
15693
15845
  };
15694
15846
  const buildInteractiveTurnHandlers = () => {
15695
15847
  const actionGateHandler = async (gate) => {
15696
- if (state.autoConfirm && isAutoConfirmableFileWriteGate(gate)) {
15848
+ if (state.permissionGrants?.local === true && isAutoConfirmableFileWriteGate(gate)) {
15697
15849
  return buildGateConfirmedResult(gate);
15698
15850
  }
15699
15851
  return await runWithInputRequiredAttention(
@@ -15708,12 +15860,13 @@ ${request.permissionNotice}`,
15708
15860
  },
15709
15861
  pauseComposer: () => fixedInput.pause(),
15710
15862
  resumeComposerFromSubprocess: () => fixedInput.resumeFromSubprocess(),
15711
- resumeComposerFromDialog: () => fixedInput.resumeFromDialog()
15863
+ resumeComposerFromDialog: () => fixedInput.resumeFromDialog(),
15864
+ onApprove: createSnapshotGuardedApproval("local", () => state.permissionGrants, approveLocalConfirms)
15712
15865
  })
15713
15866
  );
15714
15867
  };
15715
15868
  const confirmDestructiveAction = async (request) => {
15716
- if (state.autoConfirm) return true;
15869
+ if (state.permissionGrants?.local === true) return true;
15717
15870
  return await runWithInputRequiredAttention(
15718
15871
  { output, env: effectiveEnv },
15719
15872
  () => dialogHost.run(
@@ -15721,6 +15874,7 @@ ${request.permissionNotice}`,
15721
15874
  request,
15722
15875
  input,
15723
15876
  output,
15877
+ onApprove: createSnapshotGuardedApproval("local", () => state.permissionGrants, approveLocalConfirms),
15724
15878
  ...anchor
15725
15879
  })
15726
15880
  )
@@ -15988,6 +16142,15 @@ ${err.message}` : ""}`
15988
16142
  const wasGranted = sessionShellGrant.isGranted();
15989
16143
  sessionShellGrant.revoke();
15990
16144
  childShellApprovals.revoke();
16145
+ if (state.permissionGrants?.remote === true) {
16146
+ const nextGrants = { ...state.permissionGrants };
16147
+ delete nextGrants.remote;
16148
+ state = { ...state, permissionGrants: nextGrants };
16149
+ if (!persistPermissionGrantChanges({ remote: true }, nextGrants)) {
16150
+ output.write(`[nolo] ${t("autoPersistFailed")}
16151
+ `);
16152
+ }
16153
+ }
15991
16154
  emitCommandOutput(
15992
16155
  wasGranted ? t("shellGrant.revoked") : t("shellGrant.revokeNone"),
15993
16156
  "/shell-revoke"
@@ -16056,8 +16219,19 @@ ${err.message}` : ""}`
16056
16219
  "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"
16057
16220
  );
16058
16221
  } else {
16222
+ const grantsBefore = state.permissionGrants;
16059
16223
  state = res.nextState;
16224
+ if (grantsBefore?.remote === true && state.permissionGrants?.remote !== true) {
16225
+ sessionShellGrant.revoke();
16226
+ childShellApprovals.revoke();
16227
+ }
16060
16228
  let msg = res.output;
16229
+ if (!persistPermissionGrantChanges(grantsBefore, state.permissionGrants)) {
16230
+ output.write(`[nolo] ${t("autoPersistFailed")}
16231
+ `);
16232
+ } else if (state.permissionGrants !== grantsBefore) {
16233
+ scheduleRender();
16234
+ }
16061
16235
  if (busySlashCommand === "/switch" && persistExplicitAgentSwitch(beforeAgentKey)) {
16062
16236
  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.";
16063
16237
  msg = msg ? `${msg}
@@ -16444,10 +16618,10 @@ ${merged}` : merged;
16444
16618
  (gate) => (
16445
16619
  // /auto on 同款短路,见上方交互路径的 actionGateHandler 注释:
16446
16620
  // 只放行 file_write 的 confirm gate,handoff/input 类仍要求真人操作。
16447
- state.autoConfirm && isAutoConfirmableFileWriteGate(gate) ? Promise.resolve(buildGateConfirmedResult(gate)) : waitForActionGate(rl, input, output, gate, spawnRunner)
16621
+ state.permissionGrants?.local === true && isAutoConfirmableFileWriteGate(gate) ? Promise.resolve(buildGateConfirmedResult(gate)) : waitForActionGate(rl, input, output, gate, spawnRunner)
16448
16622
  ),
16449
16623
  async (request) => {
16450
- if (state.autoConfirm) return true;
16624
+ if (state.permissionGrants?.local === true) return true;
16451
16625
  if (!isInteractiveInput(input)) {
16452
16626
  return false;
16453
16627
  }
@@ -16458,6 +16632,7 @@ ${merged}` : merged;
16458
16632
  request,
16459
16633
  input,
16460
16634
  output,
16635
+ onApprove: createSnapshotGuardedApproval("local", () => state.permissionGrants, approveLocalConfirms),
16461
16636
  ...anchor
16462
16637
  })
16463
16638
  );