nolo-cli 0.157.0-alpha.1 → 0.158.0-alpha.1

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 (126) hide show
  1. package/{_executeModel-5WS2PA62.js → _executeModel-6BMU3URY.js} +35 -35
  2. package/{accountResolver-7RYB4D2P.js → accountResolver-55EDKEIK.js} +1 -1
  3. package/{action-ZJYUBXFC.js → action-GPPJC5TI.js} +4 -4
  4. package/{addContentAction-TVHB4526.js → addContentAction-BI6RDRTQ.js} +7 -7
  5. package/{addDialogAgentAction-FDPBU6K6.js → addDialogAgentAction-4RJYUSIK.js} +6 -6
  6. package/{agentDeleteCommand-Q6M4F3U6.js → agentDeleteCommand-Q2XWGBC2.js} +42 -42
  7. package/{agentEmailCommands-FNH6FEHS.js → agentEmailCommands-XFBE2A3F.js} +44 -44
  8. package/{agentListCommands-JUNMFS6E.js → agentListCommands-OROMT4P3.js} +12 -12
  9. package/{agentMachineCommands-VNLDEKNT.js → agentMachineCommands-ULK5YKKJ.js} +11 -10
  10. package/{agentProviderCommands-X2HQE6HY.js → agentProviderCommands-MKG2OOEY.js} +2 -2
  11. package/{agentRecordCommands-47XXRVPI.js → agentRecordCommands-3VHBLS6P.js} +42 -42
  12. package/{agentRunCommand-QEXFJUXQ.js → agentRunCommand-LCIMEAQY.js} +44 -43
  13. package/{agentRuntimeLocal-O5GDAFTN.js → agentRuntimeLocal-NPJS2QDP.js} +5 -5
  14. package/{agentSlice-E3XS5FTQ.js → agentSlice-VRAPG6CH.js} +7 -7
  15. package/{appDeleteCommands-C2J5RQ3I.js → appDeleteCommands-AZ3KS4HK.js} +10 -10
  16. package/{appDeployCommands-3YRK7PSU.js → appDeployCommands-BTV22ICJ.js} +10 -10
  17. package/{appDeployStatusCommands-FPAX7MOK.js → appDeployStatusCommands-JSW3HPIW.js} +10 -10
  18. package/{appGetCommands-XAC2V766.js → appGetCommands-5KTTFIMV.js} +10 -10
  19. package/{appListCommands-ZJL2W5O7.js → appListCommands-3BJPAE2U.js} +10 -10
  20. package/{authCommand-J3XILHWW.js → authCommand-NIV3DKPF.js} +7 -287
  21. package/{authCommands-77CHYBGF.js → authCommands-AMNIAKEG.js} +2 -2
  22. package/{builtinSkillRegistry-A6VSPJEJ.js → builtinSkillRegistry-H3AY27TR.js} +1 -1
  23. package/{chromeCommands-OBBNJCLS.js → chromeCommands-IY4NVSXZ.js} +17 -10
  24. package/{chunk-SW4S4XYB.js → chunk-2AB2HA4M.js} +84 -34
  25. package/{chunk-VSOWPETY.js → chunk-2BKUVRC5.js} +7 -7
  26. package/{chunk-Z6KQDSZW.js → chunk-2SGAI64X.js} +2 -2
  27. package/{chunk-KOB75UNU.js → chunk-2SOS7OSQ.js} +18 -2
  28. package/{chunk-C5VPAHIU.js → chunk-32ZKZET7.js} +1 -1
  29. package/{chunk-XPWGOTBQ.js → chunk-3L2WKC3W.js} +1 -8
  30. package/{chunk-PEO24UB5.js → chunk-3TBHZPNG.js} +33 -6
  31. package/{chunk-YBNHPX4S.js → chunk-4RJJDA57.js} +1 -1
  32. package/{chunk-X5SUT4CN.js → chunk-4UOEOHY3.js} +6 -6
  33. package/{chunk-UUPR3TD7.js → chunk-7RF4O6AT.js} +1 -3
  34. package/{chunk-FPWT3RH2.js → chunk-AJ4V34SG.js} +10 -10
  35. package/{chunk-2GGXHQIW.js → chunk-BLVSFYQ3.js} +4 -2
  36. package/{chunk-SKPPKHD3.js → chunk-BYQOCH75.js} +2 -2
  37. package/{chunk-UTIMX333.js → chunk-C3OK72G3.js} +1 -1
  38. package/{chunk-ZWG3C7VI.js → chunk-C6FY7HWI.js} +35 -0
  39. package/{chunk-RUNKPFM5.js → chunk-CDWHHLK5.js} +12 -8
  40. package/{chunk-ROPSATAB.js → chunk-CON6SI7N.js} +1 -1
  41. package/{chunk-4Z245KOA.js → chunk-DC3SZCRR.js} +6 -2
  42. package/{chunk-OH2M7WEU.js → chunk-EQGFFDNA.js} +3 -3
  43. package/{chunk-ANJTRG52.js → chunk-G2WP7VPD.js} +0 -37
  44. package/{chunk-7A4LJCDR.js → chunk-G476FQ7Q.js} +4 -4
  45. package/{chunk-DW7MGLMG.js → chunk-GAVUTXM5.js} +21 -17
  46. package/{chunk-PSJWPSKS.js → chunk-HB4XPBC7.js} +0 -32
  47. package/{chunk-6MJNEXUU.js → chunk-HGDKT2D6.js} +4 -0
  48. package/{chunk-EM3YOZJ4.js → chunk-ICRRXBRN.js} +3 -3
  49. package/{chunk-7KYVUFDG.js → chunk-IE5PXKVU.js} +1 -263
  50. package/{chunk-T6CBQ6BN.js → chunk-INFHX73M.js} +1 -1
  51. package/{chunk-CE7PIHQD.js → chunk-IRTOYSA2.js} +3 -3
  52. package/{chunk-WZ6OU4NX.js → chunk-J2ATF74A.js} +2 -2
  53. package/{chunk-TJ2VPCBE.js → chunk-JPJGMOIM.js} +2 -2
  54. package/{chunk-I2ZMGXXF.js → chunk-KFHREHUQ.js} +1 -1
  55. package/{chunk-7GC3EKUG.js → chunk-KKKHAF3P.js} +2 -2
  56. package/{chunk-KX6LPG7W.js → chunk-KLA62VVE.js} +1 -1
  57. package/{chunk-TYND6RDQ.js → chunk-LV4LV2B4.js} +72 -1
  58. package/{chunk-TZTWMGE3.js → chunk-M2P3OGXZ.js} +3 -3
  59. package/{chunk-CBHGZRCE.js → chunk-MYOH447Z.js} +1 -1
  60. package/{chunk-6MPAEODB.js → chunk-NDZOXXIM.js} +17 -3
  61. package/{chunk-MVJVF4ED.js → chunk-NKPAHRMA.js} +7 -6
  62. package/{chunk-ZD2BLOY6.js → chunk-O4ZERG3M.js} +3 -3
  63. package/{chunk-36OMEXXR.js → chunk-OON4OBWI.js} +1 -1
  64. package/{chunk-SEJ5OS6F.js → chunk-PXYBUFDB.js} +4 -0
  65. package/{chunk-G47IPDOK.js → chunk-QPY264HO.js} +1 -1
  66. package/{chunk-TNIX77YM.js → chunk-R5GO3YZP.js} +34 -1
  67. package/{chunk-EJU23ST5.js → chunk-S72LMV7T.js} +670 -627
  68. package/{chunk-D4OWHT5Y.js → chunk-SPKLALBU.js} +2 -2
  69. package/{chunk-FDT27L7S.js → chunk-UCLSOLX4.js} +7 -5
  70. package/{chunk-B2EGWZJG.js → chunk-UFYBYB26.js} +1 -1
  71. package/{chunk-3XZKV7QQ.js → chunk-US6MKPE7.js} +1 -1
  72. package/{chunk-VAZHH6FO.js → chunk-VDEVDGEM.js} +18 -12
  73. package/{chunk-HXHSTRGH.js → chunk-VYNMQ6HW.js} +0 -27
  74. package/{chunk-7BSQK2UC.js → chunk-WRCZXJ4N.js} +2 -2
  75. package/{chunk-H4KACZMG.js → chunk-WTFRBJT5.js} +261 -126
  76. package/{chunk-QDA4Y5O6.js → chunk-WXFZ4P6O.js} +18 -14
  77. package/chunk-Y5GCAMGP.js +9 -0
  78. package/{chunk-SCJD2PNK.js → chunk-YPG7TUQD.js} +3 -3
  79. package/{chunk-XFKZ3MCV.js → chunk-YTXQ2U2X.js} +221 -65
  80. package/{chunk-ZEHTARJA.js → chunk-ZBXIKCZ4.js} +38 -92
  81. package/{chunk-HKT6QXP3.js → chunk-ZEY4NJRE.js} +2 -2
  82. package/{chunk-HP6O6LTV.js → chunk-ZVQHBIWV.js} +6 -6
  83. package/{commandRegistry-OUBQIF62.js → commandRegistry-D6JTVYKG.js} +73 -81
  84. package/{contentThunks-B3FRQGP7.js → contentThunks-DYQO4CTI.js} +14 -13
  85. package/{createAgentAutomationAction-T2YFJ6MY.js → createAgentAutomationAction-LW26KIBP.js} +14 -13
  86. package/{createDialogAction-2NFGFBXW.js → createDialogAction-VLLBRD52.js} +15 -14
  87. package/{createPageAction-LDAVZDN7.js → createPageAction-PDACOLI6.js} +14 -13
  88. package/{dbSlice-5QGKMQLO.js → dbSlice-DC2J53RC.js} +6 -6
  89. package/{deleteFile-EW6QNRRT.js → deleteFile-KYWEMNFX.js} +4 -4
  90. package/{dialogCommands-ZLBEAQHE.js → dialogCommands-F3Y4KCPZ.js} +12 -11
  91. package/{dialogSlice-64S3J6CP.js → dialogSlice-ERMZYMS6.js} +13 -12
  92. package/{docCreateCommands-XOG5BBFQ.js → docCreateCommands-YMWZLW64.js} +8 -8
  93. package/{docDeleteCommands-NCW3BBRX.js → docDeleteCommands-6KJ3ESK4.js} +9 -9
  94. package/{docReadCommands-OT7X44Y3.js → docReadCommands-YQGFVLWI.js} +8 -8
  95. package/{docStore-NIP7OO4I.js → docStore-HXKI6W5D.js} +7 -7
  96. package/{docUpdateCommands-JW7OWW2J.js → docUpdateCommands-QLSGXUEX.js} +8 -8
  97. package/{handleSendMessageAction-TOKA7ED7.js → handleSendMessageAction-2XCOZPXY.js} +25 -24
  98. package/index.js +6 -6
  99. package/{localRuntimeAdapter-EQM6LFYC.js → localRuntimeAdapter-VOFUPXNF.js} +42 -40
  100. package/{machineCommands-WJ7FZ67T.js → machineCommands-IN5O7CIO.js} +46 -44
  101. package/{machineWsRunDispatch-BQT4DEA2.js → machineWsRunDispatch-TH3GMSR3.js} +41 -41
  102. package/{memberThunks-KRV5YXOB.js → memberThunks-2DWKLE6W.js} +7 -7
  103. package/package.json +1 -1
  104. package/{profileConfig-ZGOFORWV.js → profileConfig-KN3N2BLF.js} +7 -1
  105. package/{providerPresetApply-CRZFMQD5.js → providerPresetApply-GSJI4JBJ.js} +1 -1
  106. package/{providerRegistry-7IS43D3X.js → providerRegistry-TSSTPGWF.js} +1 -1
  107. package/{read-5KAZHHDM.js → read-L7QEJETH.js} +4 -4
  108. package/{readDocTool-5QO34OSX.js → readDocTool-QELXV2GW.js} +1 -1
  109. package/{readlineWorkspace-JHJSU5DS.js → readlineWorkspace-EIEQUTEZ.js} +317 -104
  110. package/{removeDialogAgentAction-6X63HMI3.js → removeDialogAgentAction-376XSUP2.js} +8 -8
  111. package/{runAgentClientLoop-5QIGEALK.js → runAgentClientLoop-3KHKKBZI.js} +39 -34
  112. package/{secretCommands-ZXZRLR3R.js → secretCommands-DNY56NSU.js} +11 -1
  113. package/{setDialogExtraReferencesAction-4MAYKKYW.js → setDialogExtraReferencesAction-QBDSH63D.js} +7 -7
  114. package/{setPrimaryDialogAgentAction-EGBAMREH.js → setPrimaryDialogAgentAction-537QFGW3.js} +8 -8
  115. package/settingThunks-4Z43ZSAT.js +923 -0
  116. package/{spaceCommands-ZWDPTURU.js → spaceCommands-T5Z4U7HP.js} +8 -8
  117. package/{streamAgentChatTurn-456DWXNY.js → streamAgentChatTurn-DMXXSEVX.js} +39 -39
  118. package/{switchDialogAgentAction-YBKTD6DO.js → switchDialogAgentAction-CSO6AKRL.js} +6 -6
  119. package/{tableCommands-U3QDY4L6.js → tableCommands-LBH3QPPO.js} +1 -1
  120. package/{toolApiClient-7WSJJJBV.js → toolApiClient-HGNO53TC.js} +2 -2
  121. package/{tools-IWNXKK4Y.js → tools-RMT7NAMC.js} +29 -28
  122. package/{updateCommands-NQXAGFM7.js → updateCommands-LXZLG44Y.js} +2 -2
  123. package/{updateDialogTitleAction-SX53FZWO.js → updateDialogTitleAction-Z4WNUH6Y.js} +14 -13
  124. package/{workloadLifecycle-36DXRZKU.js → workloadLifecycle-6O6PMISX.js} +2 -2
  125. package/chunk-W4S6OTSC.js +0 -35
  126. package/settingThunks-FTDRZNSJ.js +0 -1371
@@ -13,7 +13,7 @@ import {
13
13
  listRemoteAgents,
14
14
  listRemoteAgentsAcrossServers,
15
15
  normalizeListedAgent
16
- } from "./chunk-EM3YOZJ4.js";
16
+ } from "./chunk-ICRRXBRN.js";
17
17
  import {
18
18
  refreshSubscriptionQuotas
19
19
  } from "./chunk-U4STABYN.js";
@@ -38,7 +38,6 @@ import {
38
38
  dimCliText,
39
39
  displayWidth,
40
40
  emitTerminalProgramStatus,
41
- estimateMessagesTokens,
42
41
  expandRangeToCollapsedPasteChips,
43
42
  findCollapsedPasteSpanAt,
44
43
  fitAnsiLine,
@@ -47,7 +46,6 @@ import {
47
46
  formatTokenCount,
48
47
  getActiveThemeMode,
49
48
  getActiveThemeName,
50
- historyTokensBeforeLatestAssistant,
51
49
  isBalanceExhaustedError,
52
50
  isRunResultStalledOrTruncated,
53
51
  padOrTruncateToWidth,
@@ -91,9 +89,9 @@ import {
91
89
  wrapTextToLines,
92
90
  wrapTranscriptLine,
93
91
  wrapTranscriptLineWithLayout
94
- } from "./chunk-ZEHTARJA.js";
92
+ } from "./chunk-ZBXIKCZ4.js";
95
93
  import "./chunk-6QDYSCPW.js";
96
- import "./chunk-KOB75UNU.js";
94
+ import "./chunk-2SOS7OSQ.js";
97
95
  import {
98
96
  getReadableCliDb
99
97
  } from "./chunk-P5QACQDK.js";
@@ -103,8 +101,8 @@ import {
103
101
  createCliLocalRuntimeAdapter,
104
102
  createOriginShellGrant,
105
103
  readTimestamp
106
- } from "./chunk-EJU23ST5.js";
107
- import "./chunk-7KYVUFDG.js";
104
+ } from "./chunk-S72LMV7T.js";
105
+ import "./chunk-IE5PXKVU.js";
108
106
  import "./chunk-6MXDOUMH.js";
109
107
  import {
110
108
  dailyWelcomeTip,
@@ -112,11 +110,11 @@ import {
112
110
  parseCliLocale,
113
111
  setCliLocale,
114
112
  t
115
- } from "./chunk-SW4S4XYB.js";
113
+ } from "./chunk-2AB2HA4M.js";
116
114
  import {
117
115
  defaultOpenBrowser,
118
116
  saveTokenLogin
119
- } from "./chunk-36OMEXXR.js";
117
+ } from "./chunk-OON4OBWI.js";
120
118
  import "./chunk-TY3TIUJK.js";
121
119
  import {
122
120
  isHiddenFromDialogList,
@@ -124,19 +122,20 @@ import {
124
122
  normalizeDialogRecord,
125
123
  readDialogSnapshot,
126
124
  sortDialogs
127
- } from "./chunk-FDT27L7S.js";
125
+ } from "./chunk-UCLSOLX4.js";
128
126
  import "./chunk-ID4G2MAR.js";
129
127
  import {
130
128
  listUserRecordsFromServers,
131
129
  readLiveDbRecordAfterTombstoneMerge
132
- } from "./chunk-G47IPDOK.js";
130
+ } from "./chunk-QPY264HO.js";
131
+ import "./chunk-Y5GCAMGP.js";
133
132
  import {
134
133
  deleteDbRecord,
135
134
  queryUserRecords,
136
135
  readDbRecord
137
- } from "./chunk-HKT6QXP3.js";
136
+ } from "./chunk-ZEY4NJRE.js";
138
137
  import "./chunk-VP3BINY7.js";
139
- import "./chunk-UUPR3TD7.js";
138
+ import "./chunk-7RF4O6AT.js";
140
139
  import {
141
140
  NOLO_DEFAULT_AGENT_KEY,
142
141
  resolveCliAgentKeyInput
@@ -145,30 +144,27 @@ import "./chunk-VL5KOY2C.js";
145
144
  import "./chunk-S73EPYNC.js";
146
145
  import "./chunk-ZEZC7IIM.js";
147
146
  import "./chunk-VIWDGTDA.js";
148
- import "./chunk-6MJNEXUU.js";
147
+ import "./chunk-HGDKT2D6.js";
149
148
  import "./chunk-BU2YQBV4.js";
150
149
  import "./chunk-BMQ2MJUK.js";
151
150
  import "./chunk-IPAW7XLD.js";
152
151
  import "./chunk-ATNTHIZI.js";
153
- import "./chunk-T6CBQ6BN.js";
152
+ import "./chunk-INFHX73M.js";
154
153
  import "./chunk-JEXVIMYZ.js";
155
154
  import {
156
155
  prepareTools
157
- } from "./chunk-SKPPKHD3.js";
158
- import {
159
- buildResponseGuidelines
160
- } from "./chunk-W4S6OTSC.js";
156
+ } from "./chunk-BYQOCH75.js";
161
157
  import "./chunk-HS7MLR74.js";
162
- import "./chunk-XFKZ3MCV.js";
163
- import "./chunk-KX6LPG7W.js";
164
- import "./chunk-I2ZMGXXF.js";
158
+ import "./chunk-YTXQ2U2X.js";
159
+ import "./chunk-KLA62VVE.js";
160
+ import "./chunk-KFHREHUQ.js";
165
161
  import "./chunk-OXME3PEE.js";
166
- import "./chunk-RUNKPFM5.js";
162
+ import "./chunk-CDWHHLK5.js";
167
163
  import "./chunk-NF64D32W.js";
168
- import "./chunk-XPWGOTBQ.js";
169
- import "./chunk-HXHSTRGH.js";
170
- import "./chunk-CBHGZRCE.js";
171
- import "./chunk-3XZKV7QQ.js";
164
+ import "./chunk-3L2WKC3W.js";
165
+ import "./chunk-VYNMQ6HW.js";
166
+ import "./chunk-MYOH447Z.js";
167
+ import "./chunk-US6MKPE7.js";
172
168
  import "./chunk-YANF2RR4.js";
173
169
  import "./chunk-VIDPVFP3.js";
174
170
  import "./chunk-5MM7NNO6.js";
@@ -176,44 +172,47 @@ import "./chunk-IA7TRNNR.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";
175
+ import "./chunk-EQGFFDNA.js";
176
+ import "./chunk-J2ATF74A.js";
177
+ import "./chunk-G476FQ7Q.js";
178
+ import "./chunk-CON6SI7N.js";
179
+ import "./chunk-YPG7TUQD.js";
180
+ import "./chunk-VDEVDGEM.js";
181
+ import {
182
+ estimateMessagesTokens,
183
+ historyTokensBeforeLatestAssistant
184
+ } from "./chunk-WTFRBJT5.js";
186
185
  import "./chunk-523DITKR.js";
187
186
  import "./chunk-UKZX3NHN.js";
188
187
  import "./chunk-OFFL4DCR.js";
189
188
  import "./chunk-QYPE3TS3.js";
190
- import "./chunk-X5SUT4CN.js";
189
+ import "./chunk-4UOEOHY3.js";
191
190
  import "./chunk-4JH2UMJR.js";
192
191
  import "./chunk-ZJ7UHBJS.js";
193
192
  import "./chunk-BYXBJQAS.js";
194
- import "./chunk-CE7PIHQD.js";
193
+ import "./chunk-IRTOYSA2.js";
195
194
  import "./chunk-5RGU3J7P.js";
196
195
  import "./chunk-OWYYDMGJ.js";
197
196
  import "./chunk-ZRAU6T47.js";
198
197
  import "./chunk-4LCOCOR5.js";
199
198
  import "./chunk-YDH3FDFQ.js";
200
- import "./chunk-C5VPAHIU.js";
199
+ import "./chunk-32ZKZET7.js";
201
200
  import "./chunk-XI7DGLUK.js";
202
- import "./chunk-TZTWMGE3.js";
201
+ import "./chunk-M2P3OGXZ.js";
203
202
  import "./chunk-UAD2WT54.js";
204
- import "./chunk-HP6O6LTV.js";
203
+ import "./chunk-ZVQHBIWV.js";
205
204
  import "./chunk-3PVYUPXK.js";
206
- import "./chunk-6MPAEODB.js";
207
- import "./chunk-D4OWHT5Y.js";
208
- import "./chunk-Z6KQDSZW.js";
205
+ import "./chunk-NDZOXXIM.js";
206
+ import "./chunk-SPKLALBU.js";
207
+ import "./chunk-2SGAI64X.js";
209
208
  import "./chunk-UEILX4EV.js";
210
- import "./chunk-7BSQK2UC.js";
209
+ import "./chunk-WRCZXJ4N.js";
211
210
  import "./chunk-6Q7UTJKR.js";
212
211
  import "./chunk-QQ56R7KS.js";
213
212
  import "./chunk-OW765XBU.js";
214
- import "./chunk-SEJ5OS6F.js";
213
+ import "./chunk-PXYBUFDB.js";
215
214
  import "./chunk-D2MDMY2M.js";
216
- import "./chunk-4Z245KOA.js";
215
+ import "./chunk-DC3SZCRR.js";
217
216
  import {
218
217
  expandEnabledPacks
219
218
  } from "./chunk-JZX2XLKC.js";
@@ -226,28 +225,30 @@ import {
226
225
  formatToolOverflowMarker,
227
226
  getProcessRegistry,
228
227
  readCommandActionGatePayload
229
- } from "./chunk-PEO24UB5.js";
228
+ } from "./chunk-3TBHZPNG.js";
230
229
  import "./chunk-3C2QLERX.js";
231
230
  import "./chunk-ZNFJWEN4.js";
232
231
  import "./chunk-L6EQV5OC.js";
233
232
  import "./chunk-HNUWUO75.js";
234
233
  import "./chunk-CHOZJMJS.js";
235
234
  import "./chunk-PWTNI4N7.js";
236
- import "./chunk-ANJTRG52.js";
237
- import "./chunk-5ZUL4CUO.js";
235
+ import "./chunk-G2WP7VPD.js";
238
236
  import "./chunk-IYBIRCQV.js";
239
237
  import "./chunk-G6OOUQWJ.js";
240
238
  import "./chunk-56GBUMO5.js";
241
239
  import "./chunk-WJZOQR2J.js";
242
240
  import {
241
+ CREDENTIAL_HYGIENE_RULE,
243
242
  DELETE_SAFETY_RED_LINE,
243
+ DISPATCH_BACKEND_POLICY,
244
244
  PARALLEL_DISPATCH_DEFAULT_RULE,
245
245
  PLATFORM_RISK_CONTROL_RULE,
246
246
  buildConsultationModeBlock,
247
247
  buildIdentityBlock,
248
248
  buildRuntimeGuidanceBlocks,
249
+ resolveResponseGuidelines,
249
250
  resolveToolGuidedSections
250
- } from "./chunk-TYND6RDQ.js";
251
+ } from "./chunk-LV4LV2B4.js";
251
252
  import "./chunk-6TF64IF2.js";
252
253
  import "./chunk-QLQ573SU.js";
253
254
  import {
@@ -257,7 +258,8 @@ import "./chunk-2MBTWINN.js";
257
258
  import {
258
259
  extractReferenceKeysFromMessage,
259
260
  normalizeUsage
260
- } from "./chunk-ZWG3C7VI.js";
261
+ } from "./chunk-C6FY7HWI.js";
262
+ import "./chunk-5ZUL4CUO.js";
261
263
  import {
262
264
  DEFAULT_CONTEXT_WINDOW,
263
265
  buildCompactionMetricsFromPlan,
@@ -298,7 +300,7 @@ import {
298
300
  import "./chunk-5EMSBTQ6.js";
299
301
  import "./chunk-I42VC5KR.js";
300
302
  import "./chunk-U6VC4MU4.js";
301
- import "./chunk-PSJWPSKS.js";
303
+ import "./chunk-HB4XPBC7.js";
302
304
  import "./chunk-JGRPBIZZ.js";
303
305
  import "./chunk-WWC7I6TA.js";
304
306
  import {
@@ -348,7 +350,7 @@ import {
348
350
  import {
349
351
  checkForCliUpdate,
350
352
  runSelfUpdateDetailed
351
- } from "./chunk-YBNHPX4S.js";
353
+ } from "./chunk-4RJJDA57.js";
352
354
  import {
353
355
  parseUserIdFromAuthToken,
354
356
  resolveAuthToken,
@@ -367,15 +369,18 @@ import {
367
369
  asOptionalTrimmedString
368
370
  } from "./chunk-G3SUCT4W.js";
369
371
  import {
372
+ PERMISSION_GRANT_KINDS,
370
373
  getAgentSelectionAuditPath,
371
374
  getDefaultProfileConfigPath,
372
375
  getProfileTokens,
373
376
  loadProfileConfig,
377
+ permissionGrantList,
374
378
  readLastAgentSelectionAudit,
375
379
  saveProfileAgentSelection,
376
380
  saveProfileLocale,
381
+ saveProfilePermissionGrant,
377
382
  saveProfileTokens
378
- } from "./chunk-TNIX77YM.js";
383
+ } from "./chunk-R5GO3YZP.js";
379
384
  import {
380
385
  readPipeText,
381
386
  resolveDefaultSpawn,
@@ -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
@@ -7786,7 +7853,7 @@ function estimateToolSchemas(toolNames) {
7786
7853
  const platformTools = platformNames.length > 0 ? prepareTools([...platformNames]) : [];
7787
7854
  return estimateTokenCount(JSON.stringify([...workspaceTools, ...platformTools]));
7788
7855
  }
7789
- function estimateDefaultCliContextTokens(opts = {}) {
7856
+ function buildCliEstimateSystemText(opts = {}) {
7790
7857
  const cwd = opts.cwd?.trim() || process.cwd();
7791
7858
  const model = opts.model?.trim() || BUILTIN_NOLO_AGENT_MODEL;
7792
7859
  const agentName = opts.agentName?.trim() || BUILTIN_NOLO_AGENT_NAME;
@@ -7801,10 +7868,15 @@ function estimateDefaultCliContextTokens(opts = {}) {
7801
7868
  ]);
7802
7869
  const guidance = buildRuntimeGuidanceBlocks(toolNames);
7803
7870
  const toolSections = resolveToolGuidedSections(toolNames);
7871
+ const responseGuidelines = resolveResponseGuidelines(
7872
+ opts.responseViewport ?? "unknown"
7873
+ );
7804
7874
  const systemParts = [
7805
7875
  // 与实际装配线一致:删除安全红线是系统提示词的最顶层块。
7806
7876
  DELETE_SAFETY_RED_LINE,
7877
+ CREDENTIAL_HYGIENE_RULE,
7807
7878
  PARALLEL_DISPATCH_DEFAULT_RULE,
7879
+ DISPATCH_BACKEND_POLICY,
7808
7880
  PLATFORM_RISK_CONTROL_RULE,
7809
7881
  buildConsultationModeBlock(),
7810
7882
  prompt,
@@ -7818,17 +7890,27 @@ function estimateDefaultCliContextTokens(opts = {}) {
7818
7890
  guidance.contextLayerContract,
7819
7891
  guidance.emailRegistrationWorkflow,
7820
7892
  ...Object.values(toolSections),
7893
+ responseGuidelines.behavior,
7894
+ responseGuidelines.presentation,
7821
7895
  readAgentsMd(cwd),
7822
7896
  buildSkillDiscoveryContextBlock(cwd) ?? ""
7823
7897
  ];
7824
- const systemTokens = estimateTokenCount(
7825
- systemParts.filter((part) => part?.trim()).join("\n\n")
7826
- );
7898
+ return systemParts.filter((part) => part?.trim()).join("\n\n");
7899
+ }
7900
+ function estimateDefaultCliContextTokens(opts = {}) {
7901
+ const toolNames = canonicalizeToolNames([
7902
+ ...canonicalizeToolNames(expandEnabledPacks([...DEFAULT_CLI_PACKS], [])),
7903
+ ...DEFAULT_CLI_PLATFORM_TOOLS
7904
+ ]);
7905
+ const systemTokens = estimateTokenCount(buildCliEstimateSystemText(opts));
7827
7906
  const toolTokens = estimateToolSchemas(toolNames);
7828
7907
  const historyTokens = opts.messages && opts.messages.length > 0 ? estimateMessagesTokens(opts.messages) : opts.historyText ? estimateTokenCount(opts.historyText) : 0;
7829
7908
  return Math.max(0, systemTokens + toolTokens + historyTokens);
7830
7909
  }
7831
7910
 
7911
+ // packages/cli/tui/responseViewport.ts
7912
+ var TUI_RESPONSE_VIEWPORT = "narrow";
7913
+
7832
7914
  // packages/cli/tui/sessionDispatch.ts
7833
7915
  import { ulid } from "ulid";
7834
7916
 
@@ -7880,6 +7962,14 @@ function resolveStatusLineCredits(state) {
7880
7962
  }
7881
7963
  return (base ?? 0) + (session ?? 0) + (live ?? 0);
7882
7964
  }
7965
+ function renderPermissionGrantChip(state) {
7966
+ const local = state.permissionGrants?.local === true;
7967
+ const remote = state.permissionGrants?.remote === true;
7968
+ if (local && remote) return "\u23F5 auto";
7969
+ if (local) return "\u23F5 local";
7970
+ if (remote) return "\u23F5 remote";
7971
+ return null;
7972
+ }
7883
7973
  function renderStatusLine(state, maxWidth) {
7884
7974
  const colorEnabled = resolveCliColorEnabled();
7885
7975
  const sep = themeText(" \xB7 ", "chrome", colorEnabled);
@@ -7907,8 +7997,9 @@ function renderStatusLine(state, maxWidth) {
7907
7997
  if (pendingProcessCount > 0) {
7908
7998
  parts.push(themeText(`\u21AA ${pendingProcessCount} pending`, "info", colorEnabled));
7909
7999
  }
7910
- if (state.autoConfirm === true) {
7911
- parts.push(themeText("\u23F5 auto", "warning", colorEnabled));
8000
+ const grantChip = renderPermissionGrantChip(state);
8001
+ if (grantChip) {
8002
+ parts.push(themeText(grantChip, "warning", colorEnabled));
7912
8003
  }
7913
8004
  let surface = colorEnabled ? surfaceBackgroundSequence() : "";
7914
8005
  let padWidth = surface ? 2 : 0;
@@ -7986,7 +8077,7 @@ function renderStatusLine(state, maxWidth) {
7986
8077
  }
7987
8078
  if (widthOf(visibleParts) > maxWidth) {
7988
8079
  const budget = maxWidth - padWidth;
7989
- const autoMark = state.autoConfirm === true ? themeText("\u23F5", "warning", colorEnabled) : "";
8080
+ const autoMark = renderPermissionGrantChip(state) ? themeText("\u23F5", "warning", colorEnabled) : "";
7990
8081
  const gitCounts = state.gitStatus ? themeText(
7991
8082
  `\u2442${state.gitStatus.modified > 0 ? `*${state.gitStatus.modified}` : ""}${state.gitStatus.untracked > 0 ? `?${state.gitStatus.untracked}` : ""}`,
7992
8083
  "warning",
@@ -8284,15 +8375,27 @@ function createInitialTuiState(env = process.env) {
8284
8375
  userLanguage: asOptionalTrimmedString(env.NOLO_LANG),
8285
8376
  gitStatus: void 0,
8286
8377
  thinkingDisplay: resolveThinkingDisplayMode(env),
8378
+ // 持久化的授权桶落成 NOLO_PERMISSION_GRANTS(如 "local,remote");
8379
+ // 缺失即两桶都未授权(逐次询问)。
8380
+ permissionGrants: parsePermissionGrants(env.NOLO_PERMISSION_GRANTS),
8287
8381
  contextWindow: resolveAgentContextWindow({ agentKey, agentName }),
8288
8382
  estimatedContextTokens: estimateDefaultCliContextTokens({
8289
8383
  cwd,
8290
8384
  agentKey,
8291
8385
  userLanguage: asOptionalTrimmedString(env.NOLO_LANG),
8386
+ responseViewport: TUI_RESPONSE_VIEWPORT,
8292
8387
  ...resolveAgentModelIdentity({ agentKey, agentName })
8293
8388
  })
8294
8389
  };
8295
8390
  }
8391
+ function parsePermissionGrants(raw) {
8392
+ const grants = {};
8393
+ for (const part of (raw ?? "").split(",")) {
8394
+ const kind = part.trim().toLowerCase();
8395
+ if (kind === "local" || kind === "remote") grants[kind] = true;
8396
+ }
8397
+ return grants;
8398
+ }
8296
8399
  function applyAgentSwitch(state, target, historyTurns) {
8297
8400
  const contextWindow = resolveAgentContextWindow({
8298
8401
  agentKey: target.key,
@@ -8311,6 +8414,7 @@ function applyAgentSwitch(state, target, historyTurns) {
8311
8414
  agentName: target.name,
8312
8415
  model: target.model,
8313
8416
  userLanguage: state.userLanguage,
8417
+ responseViewport: TUI_RESPONSE_VIEWPORT,
8314
8418
  messages: historyTurns
8315
8419
  })
8316
8420
  },
@@ -8491,30 +8595,56 @@ ${t("cdUsage")}`
8491
8595
  };
8492
8596
  }
8493
8597
  case "/auto": {
8494
- const normalizedArg = asTrimmedLowercaseString(argText);
8495
- if (!normalizedArg) {
8598
+ const words = asTrimmedLowercaseString(argText).split(/\s+/).filter(Boolean);
8599
+ const grants = state.permissionGrants ?? {};
8600
+ const stateLine = () => t(
8601
+ "autoStateLine",
8602
+ grants.local === true ? t("autoStateOnPersisted") : t("autoStateOff"),
8603
+ grants.remote === true ? t("autoStateOnPersisted") : t("autoStateOff")
8604
+ );
8605
+ const applyKinds = (kinds, on) => {
8606
+ const next = { ...grants };
8607
+ for (const kind of kinds) {
8608
+ if (on) next[kind] = true;
8609
+ else delete next[kind];
8610
+ }
8611
+ return { ...state, permissionGrants: next };
8612
+ };
8613
+ if (words.length === 0) {
8614
+ return { nextState: state, output: `${stateLine()}
8615
+ ${t("autoUsage")}` };
8616
+ }
8617
+ const [scope, action] = words;
8618
+ if (scope === "reset") {
8496
8619
  return {
8497
- nextState: state,
8498
- output: `${t("autoCurrent", state.autoConfirm ? "on" : "off")}
8499
- ${t("autoUsage")}`
8620
+ nextState: applyKinds(["local", "remote"], false),
8621
+ output: t("autoReset")
8500
8622
  };
8501
8623
  }
8502
- if (normalizedArg === "on") {
8624
+ if (scope === "on" || scope === "off") {
8625
+ const on = scope === "on";
8503
8626
  return {
8504
- nextState: { ...state, autoConfirm: true },
8505
- output: t("autoOn")
8627
+ nextState: applyKinds(["local", "remote"], on),
8628
+ output: t(
8629
+ on ? "autoGrantOn" : "autoGrantOff",
8630
+ `${t("autoKindLocal")} + ${t("autoKindRemote")}`,
8631
+ on ? "/auto off" : "/auto on"
8632
+ )
8506
8633
  };
8507
8634
  }
8508
- if (normalizedArg === "off") {
8635
+ if ((scope === "local" || scope === "remote") && (action === "on" || action === "off")) {
8636
+ const on = action === "on";
8509
8637
  return {
8510
- nextState: { ...state, autoConfirm: false },
8511
- output: t("autoOff")
8638
+ nextState: applyKinds([scope], on),
8639
+ output: t(
8640
+ on ? "autoGrantOn" : "autoGrantOff",
8641
+ scope === "local" ? t("autoKindLocal") : t("autoKindRemote"),
8642
+ `/auto ${scope} ${on ? "off" : "on"}`
8643
+ )
8512
8644
  };
8513
8645
  }
8514
- return {
8515
- nextState: state,
8516
- output: t("autoUsage")
8517
- };
8646
+ return { nextState: state, output: `${stateLine()}
8647
+ ${t("autoUsage")}` };
8518
8648
  }
8519
8649
  case "/tasks":
8520
8650
  case "/jobs":
@@ -8683,6 +8813,7 @@ ${t("autoUsage")}`
8683
8813
  cwd: state.cwd,
8684
8814
  agentKey: state.agentKey,
8685
8815
  userLanguage: locale,
8816
+ responseViewport: TUI_RESPONSE_VIEWPORT,
8686
8817
  messages: historyTurns,
8687
8818
  ...resolveAgentModelIdentity({
8688
8819
  agentKey: state.agentKey,
@@ -8957,6 +9088,7 @@ function applyAgentSwitchState(state, target, messages) {
8957
9088
  agentName: target.name,
8958
9089
  model: target.model,
8959
9090
  userLanguage: state.userLanguage,
9091
+ responseViewport: TUI_RESPONSE_VIEWPORT,
8960
9092
  messages
8961
9093
  }),
8962
9094
  turnTokens: void 0,
@@ -11738,10 +11870,6 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
11738
11870
  // 宿主环境层(session-scope 稳定前缀):快速注入当前系统发行版、架构与桌面环境
11739
11871
  buildHostEnvironmentLayer()
11740
11872
  ];
11741
- const responseGuidelinesBlock = {
11742
- content: buildResponseGuidelines(true),
11743
- cacheScope: "session"
11744
- };
11745
11873
  let memoryPromptBlock = state.cachedMemoryOverlay;
11746
11874
  if (options.abortSignal?.aborted) {
11747
11875
  throw options.abortSignal.reason ?? new DOMException("Aborted", "AbortError");
@@ -11772,7 +11900,6 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
11772
11900
  }] : [];
11773
11901
  const contextBlockScopes = partitionScopedBlocks([
11774
11902
  ...renderTurnContextBlocksWithScope(layers),
11775
- responseGuidelinesBlock,
11776
11903
  ...renderTurnContextBlocksWithScope([memoryUseGuidanceLayer]),
11777
11904
  // Attached skill bodies are already self-contained sections built by
11778
11905
  // buildSkillContextBlocks; they stay turn-scope because the user can
@@ -11804,6 +11931,10 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
11804
11931
  ...options.onToolExecutionLocation ? { onToolExecutionLocation: options.onToolExecutionLocation } : {},
11805
11932
  ...state.agentKey === DEFAULT_TUI_AGENT_KEY && env.NOLO_AUTO_ROUTE !== "0" ? { dialogAgentMode: "auto" } : { dialogAgentMode: "fixed" },
11806
11933
  runtimeMode: state.runtimeMode,
11934
+ // TUI 是窄屏终端:只声明展示能力,不自拼准则文本。行为段与窄屏排版段
11935
+ // 都由 localLoop(local 线的最终装配边界)经 resolveResponseGuidelines 注入。
11936
+ // 若该轮走远端 server 线,local 线不参与装配,此字段被忽略(server 线自己注入行为段)。
11937
+ responseViewport: TUI_RESPONSE_VIEWPORT,
11807
11938
  // `/lang` updates the in-memory TUI state immediately. Pass that state
11808
11939
  // explicitly so the next real turn cannot keep using the workspace's
11809
11940
  // launch-time NOLO_LANG value while the estimator already uses the new one.
@@ -12131,6 +12262,7 @@ async function resolveActionGate(gate, deps) {
12131
12262
  request: asConfirmPermissionRequest(gate),
12132
12263
  input: deps.input,
12133
12264
  output: deps.output,
12265
+ onApprove: deps.onApprove,
12134
12266
  ...anchor
12135
12267
  })
12136
12268
  );
@@ -12219,7 +12351,7 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
12219
12351
  };
12220
12352
  emitStatus({ state: "working" });
12221
12353
  const gateHandlerWithStatus = async (gate) => {
12222
- if (ctx.state.autoConfirm && isAutoConfirmableFileWriteGate(gate)) {
12354
+ if (ctx.state.permissionGrants?.local === true && isAutoConfirmableFileWriteGate(gate)) {
12223
12355
  return await actionGateHandler(gate);
12224
12356
  }
12225
12357
  emitStatusUnlessForceStopped({
@@ -12233,7 +12365,7 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
12233
12365
  }
12234
12366
  };
12235
12367
  const confirmDestructiveActionWithStatus = confirmDestructiveAction && ctx.output.isTTY === true ? async (request) => {
12236
- if (ctx.state.autoConfirm) return await confirmDestructiveAction(request);
12368
+ if (ctx.state.permissionGrants?.local === true) return await confirmDestructiveAction(request);
12237
12369
  emitStatusUnlessForceStopped({ state: "blocked", kind: "permission" });
12238
12370
  try {
12239
12371
  return await confirmDestructiveAction(request);
@@ -12266,6 +12398,7 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
12266
12398
  agentKey: ctx.state.agentKey,
12267
12399
  agentName: ctx.state.agentName,
12268
12400
  userLanguage: ctx.state.userLanguage,
12401
+ responseViewport: TUI_RESPONSE_VIEWPORT,
12269
12402
  messages: ctx.history.turns,
12270
12403
  ...resolveAgentModelIdentity({
12271
12404
  agentKey: ctx.state.agentKey,
@@ -12488,6 +12621,7 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
12488
12621
  agentKey: ctx.state.agentKey,
12489
12622
  agentName: ctx.state.agentName,
12490
12623
  userLanguage: ctx.state.userLanguage,
12624
+ responseViewport: TUI_RESPONSE_VIEWPORT,
12491
12625
  messages: ctx.history.turns
12492
12626
  }),
12493
12627
  lastAuthorityTurnCount: void 0,
@@ -14063,6 +14197,12 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
14063
14197
  const previousState = host.state;
14064
14198
  const previousAgentKey = host.state.agentKey;
14065
14199
  host.state = result.nextState;
14200
+ if (previousState.permissionGrants?.remote === true && host.state.permissionGrants?.remote !== true) {
14201
+ host.revokeRemoteShellGrants?.();
14202
+ }
14203
+ if (!persistPermissionGrantChanges(previousState.permissionGrants, host.state.permissionGrants)) {
14204
+ emitCommandOutput(t("autoPersistFailed"));
14205
+ }
14066
14206
  const command = line.trim().split(/\s+/)[0];
14067
14207
  if ((command === "/agent" || command === "/switch") && result.nextState !== previousState) {
14068
14208
  clearCliLocalRuntimePreparedAgentCache();
@@ -14122,6 +14262,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
14122
14262
  cwd: host.state.cwd,
14123
14263
  agentKey: host.state.agentKey,
14124
14264
  userLanguage: host.state.userLanguage,
14265
+ responseViewport: TUI_RESPONSE_VIEWPORT,
14125
14266
  ...resolveAgentModelIdentity({
14126
14267
  agentKey: host.state.agentKey,
14127
14268
  agentName: host.state.agentName
@@ -14223,6 +14364,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
14223
14364
  cwd: host.state.cwd,
14224
14365
  agentKey: host.state.agentKey,
14225
14366
  userLanguage: host.state.userLanguage,
14367
+ responseViewport: TUI_RESPONSE_VIEWPORT,
14226
14368
  messages: [
14227
14369
  ...compactResult.summary ? [{ role: "system", content: compactResult.summary }] : [],
14228
14370
  ...compactResult.compactedMessageCount > 0 ? host.history.turns.slice(compactResult.compactedMessageCount) : compactResult.summaryGenerated ? [] : host.history.turns
@@ -14355,6 +14497,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
14355
14497
  agentName: pickResult.name,
14356
14498
  model: pickResult.model,
14357
14499
  userLanguage: host.state.userLanguage,
14500
+ responseViewport: TUI_RESPONSE_VIEWPORT,
14358
14501
  messages: host.history.turns
14359
14502
  }),
14360
14503
  turnTokens: void 0,
@@ -14493,6 +14636,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
14493
14636
  agentKey: host.state.agentKey,
14494
14637
  agentName: host.state.agentName,
14495
14638
  userLanguage: host.state.userLanguage,
14639
+ responseViewport: TUI_RESPONSE_VIEWPORT,
14496
14640
  messages: history.turns,
14497
14641
  ...resolveAgentModelIdentity({
14498
14642
  agentKey: host.state.agentKey,
@@ -14973,6 +15117,19 @@ async function runTuiWorkspace(options) {
14973
15117
  output.write(pinnedAgentNotice);
14974
15118
  initialBannerLineCount += pinnedAgentNotice.split("\n").length - 1;
14975
15119
  }
15120
+ const startupGrantKinds = permissionGrantList(state.permissionGrants);
15121
+ if (startupGrantKinds.length > 0) {
15122
+ output.write(
15123
+ `${t(
15124
+ "autoPersistedStartup",
15125
+ startupGrantKinds.map(
15126
+ (kind) => kind === "local" ? t("autoKindLocal") : t("autoKindRemote")
15127
+ ).join(" + ")
15128
+ )}
15129
+
15130
+ `
15131
+ );
15132
+ }
14976
15133
  let lastSentTitle = null;
14977
15134
  const syncWindowTitle = () => {
14978
15135
  if (!output.isTTY) return;
@@ -15294,6 +15451,16 @@ async function runTuiWorkspace(options) {
15294
15451
  renderHistoryToOutput();
15295
15452
  if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
15296
15453
  };
15454
+ const grantEnablerDeps = {
15455
+ getGrants: () => state.permissionGrants,
15456
+ setGrants: (next) => {
15457
+ state = { ...state, permissionGrants: next };
15458
+ },
15459
+ scheduleRender,
15460
+ onPersistFailed: () => emitCommandOutput(t("autoPersistFailed"))
15461
+ };
15462
+ const approveLocalConfirms = createPermissionGrantEnabler("local", grantEnablerDeps);
15463
+ const approveRemoteShell = createPermissionGrantEnabler("remote", grantEnablerDeps);
15297
15464
  const applyClipboardPasteResult = (outcome, source) => {
15298
15465
  const colorEnabled = resolveCliColorEnabled();
15299
15466
  if (outcome.kind === "image") {
@@ -15351,24 +15518,29 @@ async function runTuiWorkspace(options) {
15351
15518
  id: `child-shell-${crypto.randomUUID()}`,
15352
15519
  tool: "execShell",
15353
15520
  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}`,
15521
+ title: t("shellPerCall.title"),
15522
+ body: t(
15523
+ "shellPerCall.body",
15524
+ request.runId,
15525
+ request.agentKey,
15526
+ request.ownerUserId,
15527
+ request.deviceId,
15528
+ request.workspaceRoot,
15529
+ request.permissionNotice
15530
+ ),
15361
15531
  command: request.command
15362
15532
  },
15363
15533
  signal,
15364
15534
  fullCommand: true,
15365
15535
  input,
15366
15536
  output,
15537
+ onApprove: createSnapshotGuardedApproval("remote", () => state.permissionGrants, approveRemoteShell),
15367
15538
  ...anchor
15368
15539
  }));
15369
- }), () => state.autoConfirm === true);
15540
+ }), () => state.permissionGrants?.remote === true);
15370
15541
  const sessionShellGrant = createOriginShellGrant({
15371
15542
  confirm: async (request) => {
15543
+ if (state.permissionGrants?.remote === true) return true;
15372
15544
  return await runWithInputRequiredAttention(
15373
15545
  { output, env: effectiveEnv },
15374
15546
  () => dialogHost.run(
@@ -15394,12 +15566,18 @@ ${request.permissionNotice}`,
15394
15566
  },
15395
15567
  input,
15396
15568
  output,
15569
+ onApprove: createSnapshotGuardedApproval("remote", () => state.permissionGrants, approveRemoteShell),
15397
15570
  ...anchor
15398
15571
  })
15399
15572
  )
15400
15573
  );
15401
15574
  }
15402
15575
  });
15576
+ const shellGrantForTurns = {
15577
+ isGranted: () => state.permissionGrants?.remote === true || sessionShellGrant.isGranted(),
15578
+ requestGrant: (request) => sessionShellGrant.requestGrant(request),
15579
+ revoke: () => sessionShellGrant.revoke()
15580
+ };
15403
15581
  let turnIdentity = 0;
15404
15582
  const turnCtx = {
15405
15583
  get state() {
@@ -15468,7 +15646,7 @@ ${request.permissionNotice}`,
15468
15646
  },
15469
15647
  // 分享 OAuth agent 的 shell 会话授权(块 D):会话级单例透传给 turn
15470
15648
  // 执行路径;撤销经 /shell-revoke 或设置面板调 sessionShellGrant.revoke()。
15471
- shellGrant: sessionShellGrant,
15649
+ shellGrant: shellGrantForTurns,
15472
15650
  shellApprovalSession: childShellApprovals.session,
15473
15651
  // 运行位置展示(块 D):owner-required 场景 adapter 回调一次;渲染一行
15474
15652
  // 「工具在 <deviceName>(<deviceId>) · workspace <root> · status: <s>」。
@@ -15544,6 +15722,10 @@ ${request.permissionNotice}`,
15544
15722
  get fixedInput() {
15545
15723
  return fixedInput;
15546
15724
  },
15725
+ revokeRemoteShellGrants: () => {
15726
+ sessionShellGrant.revoke();
15727
+ childShellApprovals.revoke();
15728
+ },
15547
15729
  history,
15548
15730
  pasteStore,
15549
15731
  dialogHost,
@@ -15570,6 +15752,14 @@ ${request.permissionNotice}`,
15570
15752
  const wasGranted = sessionShellGrant.isGranted();
15571
15753
  sessionShellGrant.revoke();
15572
15754
  childShellApprovals.revoke();
15755
+ if (state.permissionGrants?.remote === true) {
15756
+ const nextGrants = { ...state.permissionGrants };
15757
+ delete nextGrants.remote;
15758
+ state = { ...state, permissionGrants: nextGrants };
15759
+ if (!persistPermissionGrantChanges({ remote: true }, nextGrants)) {
15760
+ emitCommandOutput(t("autoPersistFailed"));
15761
+ }
15762
+ }
15573
15763
  emitCommandOutput(
15574
15764
  wasGranted ? t("shellGrant.revoked") : t("shellGrant.revokeNone"),
15575
15765
  "/shell-revoke"
@@ -15693,7 +15883,7 @@ ${request.permissionNotice}`,
15693
15883
  };
15694
15884
  const buildInteractiveTurnHandlers = () => {
15695
15885
  const actionGateHandler = async (gate) => {
15696
- if (state.autoConfirm && isAutoConfirmableFileWriteGate(gate)) {
15886
+ if (state.permissionGrants?.local === true && isAutoConfirmableFileWriteGate(gate)) {
15697
15887
  return buildGateConfirmedResult(gate);
15698
15888
  }
15699
15889
  return await runWithInputRequiredAttention(
@@ -15708,12 +15898,13 @@ ${request.permissionNotice}`,
15708
15898
  },
15709
15899
  pauseComposer: () => fixedInput.pause(),
15710
15900
  resumeComposerFromSubprocess: () => fixedInput.resumeFromSubprocess(),
15711
- resumeComposerFromDialog: () => fixedInput.resumeFromDialog()
15901
+ resumeComposerFromDialog: () => fixedInput.resumeFromDialog(),
15902
+ onApprove: createSnapshotGuardedApproval("local", () => state.permissionGrants, approveLocalConfirms)
15712
15903
  })
15713
15904
  );
15714
15905
  };
15715
15906
  const confirmDestructiveAction = async (request) => {
15716
- if (state.autoConfirm) return true;
15907
+ if (state.permissionGrants?.local === true) return true;
15717
15908
  return await runWithInputRequiredAttention(
15718
15909
  { output, env: effectiveEnv },
15719
15910
  () => dialogHost.run(
@@ -15721,6 +15912,7 @@ ${request.permissionNotice}`,
15721
15912
  request,
15722
15913
  input,
15723
15914
  output,
15915
+ onApprove: createSnapshotGuardedApproval("local", () => state.permissionGrants, approveLocalConfirms),
15724
15916
  ...anchor
15725
15917
  })
15726
15918
  )
@@ -15988,6 +16180,15 @@ ${err.message}` : ""}`
15988
16180
  const wasGranted = sessionShellGrant.isGranted();
15989
16181
  sessionShellGrant.revoke();
15990
16182
  childShellApprovals.revoke();
16183
+ if (state.permissionGrants?.remote === true) {
16184
+ const nextGrants = { ...state.permissionGrants };
16185
+ delete nextGrants.remote;
16186
+ state = { ...state, permissionGrants: nextGrants };
16187
+ if (!persistPermissionGrantChanges({ remote: true }, nextGrants)) {
16188
+ output.write(`[nolo] ${t("autoPersistFailed")}
16189
+ `);
16190
+ }
16191
+ }
15991
16192
  emitCommandOutput(
15992
16193
  wasGranted ? t("shellGrant.revoked") : t("shellGrant.revokeNone"),
15993
16194
  "/shell-revoke"
@@ -16056,8 +16257,19 @@ ${err.message}` : ""}`
16056
16257
  "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
16258
  );
16058
16259
  } else {
16260
+ const grantsBefore = state.permissionGrants;
16059
16261
  state = res.nextState;
16262
+ if (grantsBefore?.remote === true && state.permissionGrants?.remote !== true) {
16263
+ sessionShellGrant.revoke();
16264
+ childShellApprovals.revoke();
16265
+ }
16060
16266
  let msg = res.output;
16267
+ if (!persistPermissionGrantChanges(grantsBefore, state.permissionGrants)) {
16268
+ output.write(`[nolo] ${t("autoPersistFailed")}
16269
+ `);
16270
+ } else if (state.permissionGrants !== grantsBefore) {
16271
+ scheduleRender();
16272
+ }
16061
16273
  if (busySlashCommand === "/switch" && persistExplicitAgentSwitch(beforeAgentKey)) {
16062
16274
  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
16275
  msg = msg ? `${msg}
@@ -16444,10 +16656,10 @@ ${merged}` : merged;
16444
16656
  (gate) => (
16445
16657
  // /auto on 同款短路,见上方交互路径的 actionGateHandler 注释:
16446
16658
  // 只放行 file_write 的 confirm gate,handoff/input 类仍要求真人操作。
16447
- state.autoConfirm && isAutoConfirmableFileWriteGate(gate) ? Promise.resolve(buildGateConfirmedResult(gate)) : waitForActionGate(rl, input, output, gate, spawnRunner)
16659
+ state.permissionGrants?.local === true && isAutoConfirmableFileWriteGate(gate) ? Promise.resolve(buildGateConfirmedResult(gate)) : waitForActionGate(rl, input, output, gate, spawnRunner)
16448
16660
  ),
16449
16661
  async (request) => {
16450
- if (state.autoConfirm) return true;
16662
+ if (state.permissionGrants?.local === true) return true;
16451
16663
  if (!isInteractiveInput(input)) {
16452
16664
  return false;
16453
16665
  }
@@ -16458,6 +16670,7 @@ ${merged}` : merged;
16458
16670
  request,
16459
16671
  input,
16460
16672
  output,
16673
+ onApprove: createSnapshotGuardedApproval("local", () => state.permissionGrants, approveLocalConfirms),
16461
16674
  ...anchor
16462
16675
  })
16463
16676
  );