nolo-cli 0.153.0-alpha.1 → 0.153.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 (152) hide show
  1. package/{_executeModel-4KHFMQT4.js → _executeModel-NID5KIUZ.js} +46 -48
  2. package/{accountResolver-7RYB4D2P.js → accountResolver-55EDKEIK.js} +1 -1
  3. package/{action-SXJD5N5R.js → action-GPPJC5TI.js} +4 -4
  4. package/{addContentAction-ZV774PHH.js → addContentAction-BI6RDRTQ.js} +8 -8
  5. package/{addDialogAgentAction-A6SMKAGH.js → addDialogAgentAction-4RJYUSIK.js} +7 -7
  6. package/{agentDeleteCommand-EKFV5FC7.js → agentDeleteCommand-6HYGISLC.js} +59 -60
  7. package/{agentEmailCommands-MNV3MUH5.js → agentEmailCommands-Q7UW4SRL.js} +61 -62
  8. package/{agentListCommands-E6FYKXC3.js → agentListCommands-MM5OLPBY.js} +23 -23
  9. package/{agentMachineCommands-2GFUU7GF.js → agentMachineCommands-V5TSZ2QN.js} +22 -21
  10. package/{agentProviderCommands-HL6MBLCL.js → agentProviderCommands-MKG2OOEY.js} +2 -2
  11. package/{agentRecordCommands-LPHHTEPM.js → agentRecordCommands-P2YXZEWY.js} +59 -60
  12. package/{agentRunCommand-JSPW7W32.js → agentRunCommand-B2MBD56K.js} +61 -61
  13. package/{agentRunControl-IFM7IGMG.js → agentRunControl-2C5GM3BW.js} +5 -5
  14. package/{agentRuntimeLocal-ARS4TV77.js → agentRuntimeLocal-RJKTDWNN.js} +16 -16
  15. package/{agentSlice-IP4DZNNV.js → agentSlice-636W6M5A.js} +8 -8
  16. package/{appDeleteCommands-JHTLKQSX.js → appDeleteCommands-7EOM274T.js} +21 -21
  17. package/{appDeployCommands-5V26M2KA.js → appDeployCommands-2I3QYJ5G.js} +21 -21
  18. package/{appDeployStatusCommands-SBSPS627.js → appDeployStatusCommands-LEML7FPR.js} +21 -21
  19. package/{appGetCommands-NKPD2L45.js → appGetCommands-ZQSVHGQM.js} +21 -21
  20. package/{appListCommands-ZOGRZFYY.js → appListCommands-BVA7XKQO.js} +21 -21
  21. package/{authCommand-QYN47CQD.js → authCommand-NIV3DKPF.js} +13 -293
  22. package/{authCommands-77CHYBGF.js → authCommands-AMNIAKEG.js} +2 -2
  23. package/{builtinSkillRegistry-TDQ6JB2E.js → builtinSkillRegistry-H3AY27TR.js} +3 -3
  24. package/{chromeCommands-OBBNJCLS.js → chromeCommands-IY4NVSXZ.js} +17 -10
  25. package/{chunk-SW4S4XYB.js → chunk-2AB2HA4M.js} +84 -34
  26. package/{chunk-4PXHOOFA.js → chunk-2MTE2PEH.js} +3 -3
  27. package/{chunk-4YRTZIVN.js → chunk-2SGAI64X.js} +2 -2
  28. package/{chunk-QFEW2ULV.js → chunk-32ZKZET7.js} +1 -1
  29. package/{chunk-GQV5KHJU.js → chunk-3C2QLERX.js} +1 -1
  30. package/{chunk-XPWGOTBQ.js → chunk-3L2WKC3W.js} +1 -8
  31. package/{chunk-WD4XYDYC.js → chunk-3WIXU4XO.js} +224 -1
  32. package/{chunk-6LIKQYG4.js → chunk-42QZQ6QG.js} +21 -23
  33. package/{chunk-YBNHPX4S.js → chunk-4RJJDA57.js} +1 -1
  34. package/{chunk-PFBIXTFB.js → chunk-6CTXMBXD.js} +56 -30
  35. package/{chunk-HL3O3PCQ.js → chunk-6TF64IF2.js} +2 -2
  36. package/{chunk-PMYAE4OZ.js → chunk-7HVMGI5M.js} +3 -3
  37. package/{chunk-BNDETALN.js → chunk-7NSQJKGA.js} +45 -13
  38. package/{chunk-UUPR3TD7.js → chunk-7RF4O6AT.js} +1 -3
  39. package/{chunk-HSJPKBLC.js → chunk-ANJTRG52.js} +2 -2
  40. package/{chunk-2GGXHQIW.js → chunk-BLVSFYQ3.js} +4 -2
  41. package/{chunk-ISQL4V7C.js → chunk-C3OK72G3.js} +1 -1
  42. package/{chunk-CHCS6XPJ.js → chunk-CGFNDIKK.js} +65 -0
  43. package/{chunk-5MM7NNO6.js → chunk-CNWKLQRL.js} +8 -3
  44. package/{chunk-F32Z66T4.js → chunk-CON6SI7N.js} +1 -1
  45. package/{chunk-AHYBQP3M.js → chunk-CQFBGOKS.js} +3 -3
  46. package/{chunk-HIQ4GF53.js → chunk-DC3SZCRR.js} +7 -3
  47. package/{chunk-RVWMAFIT.js → chunk-FYYSDHVQ.js} +1 -1
  48. package/{chunk-TYYRSFBG.js → chunk-HB4XPBC7.js} +3 -35
  49. package/{chunk-6MJNEXUU.js → chunk-HGDKT2D6.js} +4 -0
  50. package/{chunk-KMM2X7LP.js → chunk-HHNNUPAB.js} +3 -3
  51. package/{chunk-JWTSWUPS.js → chunk-HSPGMGTN.js} +7 -6
  52. package/{chunk-UBUH2TCC.js → chunk-I2RMFLLH.js} +2 -2
  53. package/{chunk-VJXHL6MH.js → chunk-ICRRXBRN.js} +3 -3
  54. package/{chunk-XS47QOFV.js → chunk-IE5PXKVU.js} +2 -264
  55. package/{chunk-T5BHHWA5.js → chunk-IJVJUAHF.js} +7 -7
  56. package/{chunk-KFHQQ3NO.js → chunk-INFHX73M.js} +1 -1
  57. package/{chunk-XRUSXPCQ.js → chunk-IPAW7XLD.js} +57 -4
  58. package/{chunk-PLSVXHSA.js → chunk-IRTOYSA2.js} +3 -3
  59. package/{chunk-RQ6E3G5L.js → chunk-IUMO3L46.js} +18 -2
  60. package/{chunk-GCKHQECX.js → chunk-IYBIRCQV.js} +1 -1
  61. package/{chunk-ILU2NPWY.js → chunk-J2ATF74A.js} +2 -2
  62. package/{chunk-XZNCX52W.js → chunk-JGRPBIZZ.js} +1 -1
  63. package/{chunk-E2AKSW7L.js → chunk-JPJGMOIM.js} +2 -2
  64. package/{chunk-44WXLHFI.js → chunk-K43ZF2C3.js} +1 -1
  65. package/{chunk-I2ZMGXXF.js → chunk-KFHREHUQ.js} +1 -1
  66. package/{chunk-MZHOLWW5.js → chunk-KKQAAL57.js} +3 -3
  67. package/{chunk-JKMLSTZK.js → chunk-KLA62VVE.js} +3 -3
  68. package/{chunk-EHFS4XZO.js → chunk-KXFN2UYT.js} +12 -8
  69. package/{chunk-DYYMIUN4.js → chunk-L6EQV5OC.js} +4 -4
  70. package/{chunk-EZVK3N5L.js → chunk-LOEO7LRC.js} +56 -0
  71. package/{chunk-EDX5XSJM.js → chunk-M2P3OGXZ.js} +3 -3
  72. package/{chunk-LC23WBCU.js → chunk-M3KPY3TH.js} +6 -6
  73. package/{chunk-YVLQXTUB.js → chunk-MM3662RS.js} +1 -1
  74. package/{chunk-CBHGZRCE.js → chunk-MYOH447Z.js} +1 -1
  75. package/{chunk-A4MW3YZL.js → chunk-NDZOXXIM.js} +18 -4
  76. package/{chunk-I5V3V2H4.js → chunk-OAVSTXC7.js} +37 -25
  77. package/{chunk-36OMEXXR.js → chunk-OON4OBWI.js} +1 -1
  78. package/{chunk-VNP54NZL.js → chunk-P42RHYS3.js} +14 -14
  79. package/chunk-PLQYH5XK.js +2685 -0
  80. package/{chunk-SEJ5OS6F.js → chunk-PXYBUFDB.js} +4 -0
  81. package/{chunk-USHQX6VT.js → chunk-QPY264HO.js} +1 -1
  82. package/{chunk-XCA6HQGS.js → chunk-QQ72PAGR.js} +5 -5
  83. package/{chunk-TNIX77YM.js → chunk-R5GO3YZP.js} +34 -1
  84. package/{chunk-AIZE5TDM.js → chunk-SPKLALBU.js} +2 -2
  85. package/{chunk-PPU323UE.js → chunk-SRGKEBQ6.js} +184 -67
  86. package/{chunk-64PFYIAY.js → chunk-STAG2AHQ.js} +677 -640
  87. package/{chunk-K2AER7RX.js → chunk-SUKSWFLP.js} +2 -2
  88. package/{chunk-I4SN4NUQ.js → chunk-TRW43TSC.js} +1 -1
  89. package/{chunk-D2QN6CTI.js → chunk-UCLSOLX4.js} +8 -6
  90. package/{chunk-TYJ5XFEA.js → chunk-UFYBYB26.js} +1 -1
  91. package/{chunk-SCMHQUMK.js → chunk-US6MKPE7.js} +1 -1
  92. package/{chunk-ZIWPQEFU.js → chunk-VYNMQ6HW.js} +1 -28
  93. package/{chunk-IJERIUXS.js → chunk-WRCZXJ4N.js} +6 -3
  94. package/chunk-Y5GCAMGP.js +9 -0
  95. package/{chunk-XTWDF6RU.js → chunk-Y5NUMYMH.js} +21 -17
  96. package/{chunk-GKXCHNTE.js → chunk-Y6ORVLSS.js} +1 -1
  97. package/{chunk-RSHPU4PD.js → chunk-YANF2RR4.js} +2 -2
  98. package/{chunk-EYWJT7A2.js → chunk-YPG7TUQD.js} +3 -3
  99. package/{chunk-ZF6526IQ.js → chunk-ZEY4NJRE.js} +2 -2
  100. package/{chunk-74RAWNQN.js → chunk-ZVQHBIWV.js} +6 -6
  101. package/{chunk-DTODXBHK.js → chunk-ZWG3C7VI.js} +2 -2
  102. package/{commandRegistry-VBALU4Q4.js → commandRegistry-6MVZTG5Y.js} +79 -87
  103. package/{contentThunks-HPY2QNWZ.js → contentThunks-F7XJS5WV.js} +21 -21
  104. package/{createAgentAutomationAction-6ADGPGY6.js → createAgentAutomationAction-Z2AW4ZPK.js} +21 -21
  105. package/{createDialogAction-6ABMSEW2.js → createDialogAction-PWG7C7VG.js} +22 -22
  106. package/{createPageAction-OC4NNRPC.js → createPageAction-2L5Q2KOB.js} +22 -23
  107. package/{dbSlice-J37OGIXH.js → dbSlice-DC2J53RC.js} +7 -7
  108. package/{deleteFile-6JWDDRVP.js → deleteFile-KYWEMNFX.js} +4 -4
  109. package/{dialogCommands-EIGBRSQP.js → dialogCommands-MUFYPVMP.js} +24 -23
  110. package/{dialogSlice-SI45KJOH.js → dialogSlice-G5EIKHJA.js} +20 -20
  111. package/{docCreateCommands-3JDBBMU5.js → docCreateCommands-OPWOKG62.js} +19 -19
  112. package/{docDeleteCommands-5M6C7UUB.js → docDeleteCommands-IBV3WMKI.js} +20 -20
  113. package/{docReadCommands-DUB57F6V.js → docReadCommands-LVALHMLZ.js} +19 -19
  114. package/{docStore-L43MDEK4.js → docStore-CUFUJQGC.js} +8 -8
  115. package/{docUpdateCommands-WF7MAMPK.js → docUpdateCommands-Z5OUEAK7.js} +19 -19
  116. package/{getPricing-FKK3F5EJ.js → getPricing-TX35D7PI.js} +3 -3
  117. package/{handleSendMessageAction-BSMU7SVS.js → handleSendMessageAction-26HUY2ZV.js} +34 -34
  118. package/index.js +7 -7
  119. package/{localRuntimeAdapter-N5PDR26F.js → localRuntimeAdapter-SV22ZUP3.js} +59 -58
  120. package/{machineCommands-TMXJKZCE.js → machineCommands-2G5ESGDC.js} +63 -62
  121. package/{machineWsRunDispatch-25H63KEH.js → machineWsRunDispatch-NXKGHYPP.js} +58 -59
  122. package/{memberThunks-66DH6ABQ.js → memberThunks-2DWKLE6W.js} +8 -8
  123. package/{models-LAS4B2B5.js → models-PZQC7VV4.js} +2 -2
  124. package/package.json +4 -2
  125. package/{profileConfig-ZGOFORWV.js → profileConfig-KN3N2BLF.js} +7 -1
  126. package/{providerPresetApply-MY66I6NT.js → providerPresetApply-GSJI4JBJ.js} +6 -6
  127. package/{providerRegistry-QOE2FT57.js → providerRegistry-TSSTPGWF.js} +6 -6
  128. package/{read-DC4NUGN6.js → read-L7QEJETH.js} +5 -5
  129. package/{readDocTool-NCJ5NT25.js → readDocTool-QELXV2GW.js} +1 -1
  130. package/{readlineWorkspace-BS7WVCL2.js → readlineWorkspace-AYCWJVXF.js} +334 -123
  131. package/{removeDialogAgentAction-E2H3OZU6.js → removeDialogAgentAction-376XSUP2.js} +9 -9
  132. package/{runAgentClientLoop-BVKRI4SY.js → runAgentClientLoop-SJQUUBEC.js} +50 -47
  133. package/{runtimeDoctorCommands-GIOGC5SC.js → runtimeDoctorCommands-56NWKNON.js} +5 -5
  134. package/{secretCommands-ZXZRLR3R.js → secretCommands-DNY56NSU.js} +11 -1
  135. package/{setDialogExtraReferencesAction-SITRPMYU.js → setDialogExtraReferencesAction-QBDSH63D.js} +8 -8
  136. package/{setPrimaryDialogAgentAction-U7N45TGC.js → setPrimaryDialogAgentAction-537QFGW3.js} +9 -9
  137. package/settingThunks-4Z43ZSAT.js +923 -0
  138. package/{spaceCommands-5EWREUWS.js → spaceCommands-AWIIP7J5.js} +19 -19
  139. package/{streamAgentChatTurn-B4VFUV52.js → streamAgentChatTurn-OITCT4FF.js} +55 -106
  140. package/{switchDialogAgentAction-OMGBD3N2.js → switchDialogAgentAction-CSO6AKRL.js} +7 -7
  141. package/{tableCommands-U3QDY4L6.js → tableCommands-LBH3QPPO.js} +1 -1
  142. package/{toolApiClient-7WSJJJBV.js → toolApiClient-HGNO53TC.js} +2 -2
  143. package/{tools-5WYAUKMK.js → tools-KH4MMAFG.js} +39 -40
  144. package/{tuiSummaryLlmCaller-PPU7YDBG.js → tuiSummaryLlmCaller-KLK6K3Q3.js} +8 -8
  145. package/{updateCommands-NQXAGFM7.js → updateCommands-LXZLG44Y.js} +2 -2
  146. package/{updateDialogTitleAction-YJHDKHFX.js → updateDialogTitleAction-PDJUW7Z7.js} +22 -22
  147. package/{workloadLifecycle-36DXRZKU.js → workloadLifecycle-6O6PMISX.js} +2 -2
  148. package/chunk-IA7TRNNR.js +0 -11
  149. package/chunk-OFVFQYIE.js +0 -7012
  150. package/chunk-W4S6OTSC.js +0 -35
  151. package/clipboardy-GCO3GT3I.js +0 -11793
  152. package/settingThunks-Y7SVJOMZ.js +0 -1371
@@ -1,13 +1,11 @@
1
1
  import {
2
2
  anthropicRefresh,
3
3
  cursorRefresh,
4
- getWorkBuddyHeaders,
5
4
  refreshAntigravityOAuthToken,
6
5
  refreshOpenAiCodexToken,
7
6
  resolveServerSyncConfig,
8
- workbuddyRefresh,
9
7
  xaiRefresh
10
- } from "./chunk-XS47QOFV.js";
8
+ } from "./chunk-IE5PXKVU.js";
11
9
  import {
12
10
  clearCredentialAvailability,
13
11
  markCredentialUnavailable,
@@ -18,14 +16,14 @@ import {
18
16
  import {
19
17
  agentRunCardLabels,
20
18
  t
21
- } from "./chunk-SW4S4XYB.js";
19
+ } from "./chunk-2AB2HA4M.js";
22
20
  import {
23
21
  defaultLoopbackRequest
24
22
  } from "./chunk-VP3BINY7.js";
25
23
  import {
26
24
  OAUTH_PROVIDER_REFS,
27
25
  buildLocalAgentLookupKeys
28
- } from "./chunk-UUPR3TD7.js";
26
+ } from "./chunk-7RF4O6AT.js";
29
27
  import {
30
28
  LOCAL_CODEX_AGENT_ID,
31
29
  LOCAL_CODEX_AGENT_KEY,
@@ -41,10 +39,14 @@ import {
41
39
  isCursorOAuthAgent
42
40
  } from "./chunk-VIWDGTDA.js";
43
41
  import {
42
+ SANDBOX_HELPER_PATH,
43
+ SANDBOX_OUTPUT_LIMITS,
44
44
  SANDBOX_WORKSPACE_ROOT,
45
45
  buildSandboxHelperUploadArgv,
46
- dockerExecutionToolNames
47
- } from "./chunk-6MJNEXUU.js";
46
+ buildWorkspaceHelperSource,
47
+ dockerExecutionToolNames,
48
+ parseToolOutput
49
+ } from "./chunk-HGDKT2D6.js";
48
50
  import {
49
51
  createChromeConnectorClientResolver,
50
52
  createVerifiedChromeConnectorClient,
@@ -52,17 +54,17 @@ import {
52
54
  } from "./chunk-BU2YQBV4.js";
53
55
  import {
54
56
  applyPublicAgentCatalogOverride
55
- } from "./chunk-XRUSXPCQ.js";
57
+ } from "./chunk-IPAW7XLD.js";
56
58
  import {
57
59
  buildCliPrompt
58
60
  } from "./chunk-ATNTHIZI.js";
59
61
  import {
60
62
  inferCaptureIntent
61
- } from "./chunk-KFHQQ3NO.js";
63
+ } from "./chunk-INFHX73M.js";
62
64
  import {
63
65
  inlineImageUrlsForCustomProvider,
64
66
  prepareTools
65
- } from "./chunk-MZHOLWW5.js";
67
+ } from "./chunk-KKQAAL57.js";
66
68
  import {
67
69
  getServerProviderSecret
68
70
  } from "./chunk-HS7MLR74.js";
@@ -84,18 +86,18 @@ import {
84
86
  resolveCliLocalRuntimeKeyCapability,
85
87
  resolveCliLocalSpawnDispatch,
86
88
  resolveStartAgentRunCwd
87
- } from "./chunk-PPU323UE.js";
89
+ } from "./chunk-SRGKEBQ6.js";
88
90
  import {
89
91
  deriveCredentialGroup,
90
92
  deriveCustomProviderCredentialGroup
91
- } from "./chunk-JKMLSTZK.js";
93
+ } from "./chunk-KLA62VVE.js";
92
94
  import {
93
95
  fetchWithTransientRetry,
94
96
  isTransientFetchError
95
- } from "./chunk-I2ZMGXXF.js";
97
+ } from "./chunk-KFHREHUQ.js";
96
98
  import {
97
99
  resolveAgentRequiredPackIds
98
- } from "./chunk-EHFS4XZO.js";
100
+ } from "./chunk-KXFN2UYT.js";
99
101
  import {
100
102
  applyBuiltinAgentRuntimeOverride,
101
103
  applyTokenUsageToDayStats,
@@ -104,17 +106,17 @@ import {
104
106
  resolveBuiltinPlatformAgentConfig,
105
107
  runKeyed,
106
108
  validateAskChoiceInput
107
- } from "./chunk-PFBIXTFB.js";
109
+ } from "./chunk-6CTXMBXD.js";
110
+ import {
111
+ isOAuthApiKeyRef
112
+ } from "./chunk-UKZX3NHN.js";
108
113
  import {
109
114
  BUILTIN_DIALOG_LLM_CHAT_FALLBACK_MODEL,
110
115
  BUILTIN_TITLE_LLM_CONFIG
111
116
  } from "./chunk-523DITKR.js";
112
- import {
113
- isOAuthApiKeyRef
114
- } from "./chunk-UKZX3NHN.js";
115
117
  import {
116
118
  fetchServerSyncedCredential
117
- } from "./chunk-LC23WBCU.js";
119
+ } from "./chunk-M3KPY3TH.js";
118
120
  import {
119
121
  isTombstoneRecord
120
122
  } from "./chunk-D2MDMY2M.js";
@@ -171,7 +173,7 @@ import {
171
173
  runExecShellGates,
172
174
  validateConfiguredRootExecutionLease,
173
175
  verifyOwnerRouteAck
174
- } from "./chunk-BNDETALN.js";
176
+ } from "./chunk-7NSQJKGA.js";
175
177
  import {
176
178
  accumulateGeminiChunks,
177
179
  buildGeminiGenerateContentRequest,
@@ -183,7 +185,7 @@ import {
183
185
  resolveAntigravityFinishReason,
184
186
  resolveGeminiModelQuirks,
185
187
  shouldUseGeminiNativeToolRoute
186
- } from "./chunk-GQV5KHJU.js";
188
+ } from "./chunk-3C2QLERX.js";
187
189
  import {
188
190
  PlatformStreamInterruptedError,
189
191
  buildPlatformChatCompletionRequest,
@@ -194,27 +196,27 @@ import {
194
196
  readPlatformChatSseCompletion,
195
197
  resolvePlatformChatProviderConfig,
196
198
  shouldUsePlatformChatProvider
197
- } from "./chunk-DYYMIUN4.js";
199
+ } from "./chunk-L6EQV5OC.js";
198
200
  import {
199
201
  readSseDataValues,
200
202
  readSseFrames
201
203
  } from "./chunk-HNUWUO75.js";
202
204
  import {
203
205
  resolveAgentRuntimeConfigFromRecord
204
- } from "./chunk-HSJPKBLC.js";
206
+ } from "./chunk-ANJTRG52.js";
205
207
  import {
206
208
  isDevinOAuthAgent
207
209
  } from "./chunk-5ZUL4CUO.js";
208
210
  import {
209
211
  resolveHistoricalToolContentCap
210
- } from "./chunk-GCKHQECX.js";
212
+ } from "./chunk-IYBIRCQV.js";
211
213
  import {
212
214
  collectStablePromptPrefix,
213
215
  convertMessagesToResponsesInput,
214
216
  findAgentStatePairingIssues,
215
217
  stablePromptCacheKey,
216
218
  toResponsesTools
217
- } from "./chunk-HL3O3PCQ.js";
219
+ } from "./chunk-6TF64IF2.js";
218
220
  import {
219
221
  buildNoloWorkspaceOpenAiTools,
220
222
  parseNoloWorkspaceToolArguments,
@@ -232,14 +234,14 @@ import {
232
234
  } from "./chunk-2MBTWINN.js";
233
235
  import {
234
236
  normalizeUsage
235
- } from "./chunk-DTODXBHK.js";
237
+ } from "./chunk-ZWG3C7VI.js";
236
238
  import {
237
239
  createProviderCallTimingTracker,
238
240
  finalizeProviderCallTiming,
239
241
  observeMeaningfulProviderResponse,
240
242
  observeMeaningfulProviderResponseAt,
241
243
  withProviderCallTimingFields
242
- } from "./chunk-4PXHOOFA.js";
244
+ } from "./chunk-2MTE2PEH.js";
243
245
  import {
244
246
  clipCompactText
245
247
  } from "./chunk-5MMAK75Q.js";
@@ -269,7 +271,7 @@ import {
269
271
  } from "./chunk-NYYFIKHI.js";
270
272
  import {
271
273
  isSystemBuiltinTrustedAgentKey
272
- } from "./chunk-EZVK3N5L.js";
274
+ } from "./chunk-LOEO7LRC.js";
273
275
  import {
274
276
  createTokenKey,
275
277
  createTokenStatsKey,
@@ -280,7 +282,7 @@ import {
280
282
  } from "./chunk-5EMSBTQ6.js";
281
283
  import {
282
284
  isAntigravityOAuthAgent
283
- } from "./chunk-XZNCX52W.js";
285
+ } from "./chunk-JGRPBIZZ.js";
284
286
  import {
285
287
  ackRunRecord,
286
288
  appendRunQueue,
@@ -301,7 +303,7 @@ import {
301
303
  terminateRunProcess,
302
304
  transitionRunToTerminal,
303
305
  withQueueLock
304
- } from "./chunk-YVLQXTUB.js";
306
+ } from "./chunk-MM3662RS.js";
305
307
  import {
306
308
  TASK_PREVIEW_MAX,
307
309
  formatListRunsCard,
@@ -321,12 +323,12 @@ import {
321
323
  import {
322
324
  buildProviderSessionHeaders,
323
325
  resolvePlatformAuthToken
324
- } from "./chunk-K2AER7RX.js";
326
+ } from "./chunk-SUKSWFLP.js";
325
327
  import {
326
328
  anthropicOAuthModelMaxOutputTokens,
327
329
  findModelConfig,
328
330
  isAdaptiveThinkingModelId
329
- } from "./chunk-I4SN4NUQ.js";
331
+ } from "./chunk-TRW43TSC.js";
330
332
  import {
331
333
  CLI_PROVIDER_VALUES,
332
334
  isCliProvider
@@ -3301,447 +3303,6 @@ var resolveDevinTransport = async (ctx) => {
3301
3303
  return null;
3302
3304
  };
3303
3305
 
3304
- // packages/agent-runtime/workbuddyRequestAdapter.ts
3305
- var DEFAULT_SYSTEM = "You are a helpful assistant.";
3306
- var SAFE_NAME = /^[A-Za-z0-9_-]{1,64}$/;
3307
- function record(value) {
3308
- return value !== null && typeof value === "object" && !Array.isArray(value);
3309
- }
3310
- function safeName(name, reserved) {
3311
- const stem = name.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 48) || "tool";
3312
- let candidate = stem;
3313
- if (reserved.has(candidate)) {
3314
- let suffix = 1;
3315
- do
3316
- candidate = `${stem.slice(0, 64 - String(suffix).length - 1)}_${suffix++}`;
3317
- while (reserved.has(candidate));
3318
- }
3319
- reserved.add(candidate);
3320
- return candidate;
3321
- }
3322
- function adaptSchema(schema, path) {
3323
- if (!record(schema)) throw new TypeError(`${path} must be a JSON Schema object`);
3324
- if (schema.type !== "object" && schema.type !== "array" && schema.type !== "string" && schema.type !== "number" && schema.type !== "integer" && schema.type !== "boolean" && schema.type !== "null" && schema.type !== void 0) throw new TypeError(`${path}.type is unsupported`);
3325
- if (schema.properties !== void 0) {
3326
- if (!record(schema.properties)) throw new TypeError(`${path}.properties must be an object`);
3327
- for (const [key, value] of Object.entries(schema.properties)) adaptSchema(value, `${path}.properties.${key}`);
3328
- }
3329
- for (const key of ["items", "additionalProperties", "not", "if", "then", "else"]) {
3330
- const value = schema[key];
3331
- if (value === false || value === true) continue;
3332
- if (record(value)) adaptSchema(value, `${path}.${key}`);
3333
- else if (Array.isArray(value)) value.forEach((item, i) => adaptSchema(item, `${path}.${key}[${i}]`));
3334
- }
3335
- for (const key of ["oneOf", "anyOf", "allOf", "prefixItems"]) {
3336
- if (schema[key] !== void 0) {
3337
- if (!Array.isArray(schema[key])) throw new TypeError(`${path}.${key} must be an array`);
3338
- schema[key].forEach((item, i) => adaptSchema(item, `${path}.${key}[${i}]`));
3339
- }
3340
- }
3341
- }
3342
- function adaptWorkBuddyRequest(body) {
3343
- const adapted = structuredClone(body);
3344
- const originalNames = /* @__PURE__ */ Object.create(null);
3345
- const safeToOriginal = /* @__PURE__ */ new Map();
3346
- const tools = adapted.tools;
3347
- if (tools !== void 0 && !Array.isArray(tools)) throw new TypeError("tools must be an array");
3348
- const reserved = /* @__PURE__ */ new Set();
3349
- for (const tool of tools ?? []) {
3350
- if (!record(tool) || !record(tool.function) || typeof tool.function.name !== "string") throw new TypeError("Each tool must have a named function");
3351
- if (SAFE_NAME.test(tool.function.name)) reserved.add(tool.function.name);
3352
- }
3353
- for (const tool of tools ?? []) {
3354
- const fn = tool.function;
3355
- const original = fn.name;
3356
- if (!SAFE_NAME.test(original)) {
3357
- const safe = safeName(original, reserved);
3358
- Object.defineProperty(originalNames, safe, { value: original, enumerable: true, configurable: true, writable: true });
3359
- safeToOriginal.set(safe, original);
3360
- fn.name = safe;
3361
- }
3362
- if (fn.parameters !== void 0) {
3363
- if (!record(fn.parameters)) throw new TypeError(`Tool ${original} parameters must be a JSON Schema object`);
3364
- adaptSchema(fn.parameters, `Tool ${original} parameters`);
3365
- if (fn.parameters.type !== "object") throw new TypeError(`Tool ${original} parameters root must be type object`);
3366
- }
3367
- }
3368
- const safeFor = (name) => typeof name === "string" ? [...safeToOriginal].find(([, original]) => original === name)?.[0] : void 0;
3369
- if (Array.isArray(adapted.messages)) {
3370
- for (const message of adapted.messages) {
3371
- if (!record(message)) continue;
3372
- if (message.role === "developer") message.role = "system";
3373
- if (Array.isArray(message.tool_calls)) for (const call of message.tool_calls) {
3374
- if (record(call) && record(call.function)) call.function.name = safeFor(call.function.name) ?? call.function.name;
3375
- }
3376
- if (message.role === "tool") message.name = safeFor(message.name) ?? message.name;
3377
- }
3378
- if (!adapted.messages.some((message) => record(message) && message.role === "system")) adapted.messages.unshift({ role: "system", content: DEFAULT_SYSTEM });
3379
- } else adapted.messages = [{ role: "system", content: DEFAULT_SYSTEM }];
3380
- const choice = adapted.tool_choice;
3381
- if (choice === "none") delete adapted.tools;
3382
- else if (record(choice) && record(choice.function)) choice.function.name = safeFor(choice.function.name) ?? choice.function.name;
3383
- else if (typeof choice === "string" && !["auto", "required", "none"].includes(choice)) adapted.tool_choice = { type: "function", function: { name: safeFor(choice) ?? choice } };
3384
- if (adapted.max_completion_tokens !== void 0) {
3385
- if (adapted.max_tokens === void 0) adapted.max_tokens = adapted.max_completion_tokens;
3386
- delete adapted.max_completion_tokens;
3387
- }
3388
- adapted.stream = true;
3389
- return { body: adapted, originalNames };
3390
- }
3391
- function restoreWorkBuddyToolNames(payload, originalNames) {
3392
- const copy = structuredClone(payload);
3393
- if (!record(copy) || !Array.isArray(copy.choices)) return copy;
3394
- for (const choice of copy.choices) for (const part of [choice?.delta, choice?.message]) {
3395
- if (!record(part) || !Array.isArray(part.tool_calls)) continue;
3396
- for (const call of part.tool_calls) {
3397
- if (!record(call) || !record(call.function) || typeof call.function.name !== "string") continue;
3398
- if (Object.prototype.hasOwnProperty.call(originalNames, call.function.name)) call.function.name = originalNames[call.function.name];
3399
- }
3400
- }
3401
- return copy;
3402
- }
3403
-
3404
- // packages/cli/client/providerResolution/workbuddyTransport.ts
3405
- var WORKBUDDY_ENDPOINTS = {
3406
- workbuddy: "https://copilot.tencent.com/v2/chat/completions",
3407
- "workbuddy-ai": "https://www.workbuddy.ai/v2/chat/completions"
3408
- };
3409
- function resolveWorkBuddySite(agentConfig) {
3410
- const ref = agentConfig.apiKeyRef?.trim().toLowerCase();
3411
- const prov = agentConfig.provider?.trim().toLowerCase();
3412
- if (ref === "workbuddy-ai" || ref?.startsWith(["api-key", "workbuddy-ai"].join(":")) || prov === "workbuddy-ai") {
3413
- return "workbuddy-ai";
3414
- }
3415
- if (ref === "workbuddy" || ref?.startsWith(["api-key", "workbuddy"].join(":")) || prov === "workbuddy") {
3416
- return "workbuddy";
3417
- }
3418
- return null;
3419
- }
3420
- function record2(value) {
3421
- return typeof value === "object" && value !== null && !Array.isArray(value);
3422
- }
3423
- var QUOTA_EXCEEDED_MESSAGE = "WorkBuddy \u989D\u5EA6\u4E0D\u8DB3 (14018)\uFF1AWorkBuddy \u975E\u65E0\u9650\u514D\u8D39\u670D\u52A1\uFF0C\u5F53\u524D\u8D26\u53F7\u989D\u5EA6\u5DF2\u8017\u5C3D\u3002";
3424
- function wrapWorkBuddySseResponse(response, names) {
3425
- if (!response.body) return response;
3426
- const decoder = new TextDecoder("utf-8");
3427
- const encoder = new TextEncoder();
3428
- let pending = "";
3429
- let lines = [];
3430
- const fragments = /* @__PURE__ */ new Map();
3431
- const processEvent = () => {
3432
- const dataLines = lines.filter((line) => line.startsWith("data:")).map((line) => line.slice(5).replace(/^ /, ""));
3433
- const data = dataLines.join("\n");
3434
- if (!data || data === "[DONE]") {
3435
- const result = lines.join("\n") + "\n\n";
3436
- lines = [];
3437
- return result;
3438
- }
3439
- let payload;
3440
- try {
3441
- payload = JSON.parse(data);
3442
- } catch {
3443
- const result = lines.join("\n") + "\n\n";
3444
- lines = [];
3445
- return result;
3446
- }
3447
- if (record2(payload)) {
3448
- if (payload.code === 14018 || payload.errcode === 14018 || record2(payload.error) && payload.error.code === 14018) {
3449
- throw new Error(QUOTA_EXCEEDED_MESSAGE);
3450
- }
3451
- const choices = Array.isArray(payload.choices) ? payload.choices : [];
3452
- for (const choice of choices) {
3453
- if (!record2(choice)) continue;
3454
- const delta = record2(choice.delta) ? choice.delta : void 0;
3455
- const toolCalls = delta && Array.isArray(delta.tool_calls) ? delta.tool_calls : [];
3456
- for (const call of toolCalls) {
3457
- if (!record2(call) || !record2(call.function) || typeof call.function.name !== "string") {
3458
- continue;
3459
- }
3460
- const key = `${choice.index ?? 0}:${call.index ?? 0}`;
3461
- const accumulated = (fragments.get(key) ?? "") + call.function.name;
3462
- if (Object.prototype.hasOwnProperty.call(names, accumulated)) {
3463
- call.function.name = accumulated;
3464
- fragments.delete(key);
3465
- } else if (Object.keys(names).some((safe) => safe.startsWith(accumulated))) {
3466
- fragments.set(key, accumulated);
3467
- call.function.name = "";
3468
- } else {
3469
- call.function.name = accumulated;
3470
- fragments.delete(key);
3471
- }
3472
- }
3473
- }
3474
- }
3475
- const restored = restoreWorkBuddyToolNames(payload, names);
3476
- const nonDataFields = lines.filter((line) => !line.startsWith("data:"));
3477
- lines = [];
3478
- return [...nonDataFields, `data: ${JSON.stringify(restored)}`, "", ""].join(
3479
- "\n"
3480
- );
3481
- };
3482
- const drain = (final) => {
3483
- let output = "";
3484
- while (true) {
3485
- const match = /[\r\n]/.exec(pending);
3486
- if (!match) break;
3487
- const i = match.index;
3488
- if (!final && pending[i] === "\r" && i === pending.length - 1) break;
3489
- const line = pending.slice(0, i);
3490
- pending = pending.slice(
3491
- i + (pending[i] === "\r" && pending[i + 1] === "\n" ? 2 : 1)
3492
- );
3493
- if (line === "") {
3494
- output += processEvent();
3495
- } else {
3496
- lines.push(line);
3497
- }
3498
- }
3499
- if (final) {
3500
- if (pending) {
3501
- lines.push(pending);
3502
- pending = "";
3503
- }
3504
- if (lines.length > 0) {
3505
- output += processEvent();
3506
- }
3507
- }
3508
- return output;
3509
- };
3510
- const transformStream = new TransformStream({
3511
- transform: (chunk, controller) => {
3512
- pending += decoder.decode(chunk, { stream: true });
3513
- const output = drain(false);
3514
- if (output) controller.enqueue(encoder.encode(output));
3515
- },
3516
- flush: (controller) => {
3517
- pending += decoder.decode();
3518
- const output = drain(true);
3519
- if (output) controller.enqueue(encoder.encode(output));
3520
- }
3521
- });
3522
- const body = response.body.pipeThrough(transformStream);
3523
- const headers = new Headers(response.headers);
3524
- headers.delete("content-length");
3525
- headers.delete("content-encoding");
3526
- return new Response(body, {
3527
- status: response.status,
3528
- statusText: response.statusText,
3529
- headers
3530
- });
3531
- }
3532
- async function wrapWorkBuddyJsonResponse(response, names) {
3533
- const rawText = await response.text();
3534
- let json;
3535
- try {
3536
- json = JSON.parse(rawText);
3537
- } catch {
3538
- return new Response(rawText, {
3539
- status: response.status,
3540
- statusText: response.statusText,
3541
- headers: response.headers
3542
- });
3543
- }
3544
- if (record2(json) && (json.code === 14018 || json.errcode === 14018 || record2(json.error) && json.error.code === 14018 || rawText.includes("14018"))) {
3545
- throw new Error(QUOTA_EXCEEDED_MESSAGE);
3546
- }
3547
- const restored = restoreWorkBuddyToolNames(json, names);
3548
- return new Response(JSON.stringify(restored), {
3549
- status: response.status,
3550
- statusText: response.statusText,
3551
- headers: response.headers
3552
- });
3553
- }
3554
- var resolveWorkbuddyTransport = async (ctx) => {
3555
- const {
3556
- agentConfig,
3557
- deps,
3558
- fetchImpl,
3559
- additionalToolNames,
3560
- buildProviderOpenAiTools,
3561
- recordLocalAvailability,
3562
- apiKeyRefResolver
3563
- } = ctx;
3564
- const site = resolveWorkBuddySite(agentConfig);
3565
- if (!site) return null;
3566
- const fixedEndpoint = WORKBUDDY_ENDPOINTS[site];
3567
- if (agentConfig.customProviderUrl) {
3568
- const trimmedUrl = agentConfig.customProviderUrl.trim();
3569
- if (trimmedUrl && trimmedUrl !== fixedEndpoint) {
3570
- throw new Error(
3571
- `Custom provider URL "${trimmedUrl}" is forbidden for WorkBuddy (${site}). Requests must only target ${fixedEndpoint}.`
3572
- );
3573
- }
3574
- }
3575
- const rawRef = asTrimmedLowercaseString(agentConfig.apiKeyRef);
3576
- const isApiKeyRef = rawRef.startsWith("api-key:");
3577
- const providerRef = isApiKeyRef ? rawRef : site;
3578
- const initialToken = await apiKeyRefResolver(providerRef);
3579
- if (!initialToken) {
3580
- throw new Error(
3581
- `OAuth credential for "${site}" not found locally. Run \`nolo auth ${site}\`.`
3582
- );
3583
- }
3584
- const legacyCredentialMigration = { enableLegacyMigration: true };
3585
- let currentCredential = readOAuthCredential(
3586
- site,
3587
- void 0,
3588
- legacyCredentialMigration
3589
- );
3590
- if (!currentCredential || !currentCredential.accessToken) {
3591
- throw new Error(
3592
- `OAuth credential for "${site}" not found locally. Run \`nolo auth ${site}\`.`
3593
- );
3594
- }
3595
- const uid = typeof currentCredential.metadata?.uid === "string" && currentCredential.metadata.uid.trim() || typeof currentCredential.accountId === "string" && currentCredential.accountId.trim() || "";
3596
- if (!uid) {
3597
- throw new Error(
3598
- `WorkBuddy credential for "${site}" is missing uid. Re-run \`nolo auth ${site}\`.`
3599
- );
3600
- }
3601
- if (currentCredential.accessToken !== initialToken) {
3602
- currentCredential = { ...currentCredential, accessToken: initialToken };
3603
- }
3604
- const { requestedToolNames, tools } = resolveProviderOpenAiToolBundle(
3605
- agentConfig,
3606
- deps.env,
3607
- buildProviderOpenAiTools,
3608
- additionalToolNames
3609
- );
3610
- const resolveRequestApiKey = async ({
3611
- force
3612
- }) => {
3613
- if (isApiKeyRef && force) {
3614
- return currentCredential.accessToken;
3615
- }
3616
- const before = readOAuthCredential(
3617
- site,
3618
- void 0,
3619
- legacyCredentialMigration
3620
- );
3621
- if (before) {
3622
- currentCredential = before;
3623
- }
3624
- if (!force) {
3625
- return currentCredential.accessToken;
3626
- }
3627
- const refreshedToken = await apiKeyRefResolver(providerRef, {
3628
- force: true
3629
- });
3630
- const after = readOAuthCredential(
3631
- site,
3632
- void 0,
3633
- legacyCredentialMigration
3634
- );
3635
- if (after) {
3636
- currentCredential = after;
3637
- }
3638
- if (refreshedToken && currentCredential.accessToken !== refreshedToken) {
3639
- currentCredential = {
3640
- ...currentCredential,
3641
- accessToken: refreshedToken
3642
- };
3643
- }
3644
- return refreshedToken ?? currentCredential.accessToken;
3645
- };
3646
- const wrappedFetch = async (inputUrl, init) => {
3647
- const targetUrl = typeof inputUrl === "string" ? inputUrl : inputUrl instanceof URL ? inputUrl.toString() : inputUrl.url;
3648
- if (targetUrl !== fixedEndpoint) {
3649
- throw new Error(
3650
- `WorkBuddy request blocked: target URL "${targetUrl}" does not match fixed endpoint "${fixedEndpoint}". Token will not be sent.`
3651
- );
3652
- }
3653
- let originalNames = {};
3654
- let body = init?.body;
3655
- if (typeof body === "string") {
3656
- try {
3657
- const parsed = JSON.parse(body);
3658
- const adapted = adaptWorkBuddyRequest(parsed);
3659
- originalNames = adapted.originalNames;
3660
- body = JSON.stringify(adapted.body);
3661
- } catch {
3662
- }
3663
- }
3664
- const wbHeaders = getWorkBuddyHeaders(currentCredential);
3665
- const mergedHeaders = new Headers(init?.headers);
3666
- for (const [key, value] of Object.entries(wbHeaders)) {
3667
- mergedHeaders.set(key, value);
3668
- }
3669
- mergedHeaders.set("Content-Type", "application/json");
3670
- const upstreamRes = await fetchImpl(fixedEndpoint, {
3671
- ...init,
3672
- body,
3673
- headers: mergedHeaders,
3674
- redirect: "error"
3675
- });
3676
- if (upstreamRes.status === 401) {
3677
- return upstreamRes;
3678
- }
3679
- if (!upstreamRes.ok) {
3680
- const clone = upstreamRes.clone();
3681
- const errorText = await clone.text().catch(() => "");
3682
- if (errorText.includes("14018")) {
3683
- throw new Error(QUOTA_EXCEEDED_MESSAGE);
3684
- }
3685
- return upstreamRes;
3686
- }
3687
- const contentType = upstreamRes.headers.get("content-type") ?? "";
3688
- if (contentType.includes("text/event-stream")) {
3689
- return wrapWorkBuddySseResponse(upstreamRes, originalNames);
3690
- } else {
3691
- return wrapWorkBuddyJsonResponse(upstreamRes, originalNames);
3692
- }
3693
- };
3694
- return {
3695
- model: agentConfig.model || "gpt-4o",
3696
- complete: async (messages, options) => {
3697
- logLocalRuntimeDiagnostic("provider.request.start", {
3698
- agentKey: agentConfig.key,
3699
- transport: "workbuddy",
3700
- model: agentConfig.model ?? "gpt-4o",
3701
- messageCount: messages.length,
3702
- toolCount: tools.length,
3703
- requestedToolNames,
3704
- openAiToolNames: summarizeOpenAiToolNames(tools),
3705
- stream: true
3706
- });
3707
- try {
3708
- const result = await executeOpenAiCompatibleChatCompletion({
3709
- providerConfig: {
3710
- endpoint: fixedEndpoint,
3711
- apiKey: currentCredential.accessToken,
3712
- model: agentConfig.model || "gpt-4o",
3713
- provider: site
3714
- },
3715
- messages,
3716
- tools,
3717
- fetchImpl: wrappedFetch,
3718
- stream: true,
3719
- sessionId: asOptionalTrimmedString(options?.dialogId) ?? asOptionalTrimmedString(agentConfig.key),
3720
- onTextDelta: options?.onTextDelta,
3721
- onReasoningDelta: options?.onReasoningDelta,
3722
- onHttpResult: ({ status, body }) => recordLocalAvailability(status, body),
3723
- resolveApiKey: resolveRequestApiKey
3724
- });
3725
- await recordLocalAvailability(200);
3726
- logLocalRuntimeDiagnostic("provider.request.result", {
3727
- agentKey: agentConfig.key,
3728
- transport: "workbuddy",
3729
- ok: true,
3730
- contentChars: result.content.length,
3731
- toolCallCount: result.tool_calls?.length ?? 0
3732
- });
3733
- return result;
3734
- } catch (error) {
3735
- const message = error instanceof Error ? error.message : String(error);
3736
- if (message.includes("14018")) {
3737
- throw new Error(QUOTA_EXCEEDED_MESSAGE);
3738
- }
3739
- throw error;
3740
- }
3741
- }
3742
- };
3743
- };
3744
-
3745
3306
  // packages/cli/client/providerResolution/directOpenAiCompatibleTransport.ts
3746
3307
  var resolveDirectOpenAiCompatibleTransport = async (ctx) => {
3747
3308
  const { agentConfig, deps, fetchImpl, loopbackRequest, additionalToolNames, buildProviderOpenAiTools, recordLocalAvailability, apiKeyRefResolver, credentialBroker, syncFetcher, serverUrl, authToken } = ctx;
@@ -4385,7 +3946,6 @@ var TRANSPORTS = [
4385
3946
  resolveCodexOAuthTransport,
4386
3947
  resolveCursorTransport,
4387
3948
  resolveDevinTransport,
4388
- resolveWorkbuddyTransport,
4389
3949
  resolveGeminiNativeToolTransport,
4390
3950
  // 三条 custom native wire(gemini / openai-responses / anthropic-messages)由
4391
3951
  // 这一个 resolver 按目录 `nativeProtocol` 分派:三种 wire 互斥(一个模型的
@@ -4556,11 +4116,11 @@ function withProviderStreamRetry(provider, deps) {
4556
4116
 
4557
4117
  // packages/cli/client/cliRemoteDialogSync.ts
4558
4118
  function prepareRemoteDialogEvidenceRecord(key, value) {
4559
- const record3 = isRecord(value) ? { ...value } : {};
4560
- if (key.includes("-msg-") && typeof record3.type !== "string") {
4561
- record3.type = "msg";
4119
+ const record = isRecord(value) ? { ...value } : {};
4120
+ if (key.includes("-msg-") && typeof record.type !== "string") {
4121
+ record.type = "msg";
4562
4122
  }
4563
- return record3;
4123
+ return record;
4564
4124
  }
4565
4125
  function normalizeRemoteSubjectRef(value) {
4566
4126
  if (!isRecord(value)) return null;
@@ -4852,13 +4412,13 @@ function resolveBuiltinLocalCliAgentConfig(agentRef, userId) {
4852
4412
  }
4853
4413
  async function readAgentFromStore(args) {
4854
4414
  for (const key of buildLocalAgentLookupKeys(args)) {
4855
- const record3 = await args.store.read(key);
4856
- if (!record3 || typeof record3 !== "object") continue;
4415
+ const record = await args.store.read(key);
4416
+ if (!record || typeof record !== "object") continue;
4857
4417
  return applyBuiltinAgentRuntimeOverride(
4858
4418
  args.agentRef,
4859
4419
  resolveAgentRuntimeConfigFromRecord(
4860
4420
  key,
4861
- applyPublicAgentCatalogOverride(record3)
4421
+ applyPublicAgentCatalogOverride(record)
4862
4422
  )
4863
4423
  );
4864
4424
  }
@@ -4893,8 +4453,8 @@ async function readDialogMessages(args) {
4893
4453
  function createChildShellApprovalHostResolver(args) {
4894
4454
  return async (agentKey) => {
4895
4455
  const config = await args.readAgentConfig(agentKey);
4896
- const record3 = config?.rawRecord;
4897
- const ownerUserId = asOptionalTrimmedString(record3?.userId) ?? asOptionalTrimmedString(record3?.ownerUserId);
4456
+ const record = config?.rawRecord;
4457
+ const ownerUserId = asOptionalTrimmedString(record?.userId) ?? asOptionalTrimmedString(record?.ownerUserId);
4898
4458
  if (!ownerUserId) return void 0;
4899
4459
  const deviceId = asOptionalTrimmedString(await args.resolveDeviceId());
4900
4460
  if (!deviceId) return void 0;
@@ -5161,8 +4721,8 @@ function describeIssues(issues) {
5161
4721
  function asNonEmptyString(value) {
5162
4722
  return typeof value === "string" && value.trim().length > 0 ? value : null;
5163
4723
  }
5164
- function resolveCreatedAtMs(record3) {
5165
- const raw = record3.createdAt;
4724
+ function resolveCreatedAtMs(record) {
4725
+ const raw = record.createdAt;
5166
4726
  const ms = typeof raw === "number" ? raw : typeof raw === "string" ? Date.parse(raw) : Number.NaN;
5167
4727
  return Number.isFinite(ms) ? ms : null;
5168
4728
  }
@@ -5222,18 +4782,18 @@ function analyzeRemoteDialogRecords(args) {
5222
4782
  }
5223
4783
  seenIds.add(messageId);
5224
4784
  const key = dialogMessageKey(args.dialogId, messageId);
5225
- const record3 = {
4785
+ const record = {
5226
4786
  ...raw,
5227
4787
  id: messageId,
5228
4788
  dbKey: key,
5229
4789
  ...asNonEmptyString(raw.dialogId) ? {} : { dialogId: args.dialogId }
5230
4790
  };
5231
- const message = dialogMessageRecordToAgentRuntimeMessage(record3);
4791
+ const message = dialogMessageRecordToAgentRuntimeMessage(record);
5232
4792
  if (!message) {
5233
4793
  issues.push({ code: "unconvertible-record", detail: `${role} index ${index}` });
5234
4794
  continue;
5235
4795
  }
5236
- entries.push({ key, messageId, record: record3, message });
4796
+ entries.push({ key, messageId, record, message });
5237
4797
  }
5238
4798
  const messages = entries.map((entry) => entry.message);
5239
4799
  for (const detail of findAgentStatePairingIssues(messages)) {
@@ -5507,14 +5067,27 @@ function buildServerPlatformToolExecutors(args) {
5507
5067
  }
5508
5068
  const body = {
5509
5069
  query: parsed.query,
5510
- numResults: parsed.numResults ?? 5,
5511
- useAutoprompt: parsed.useAutoprompt ?? true,
5512
- type: parsed.type ?? "neural",
5513
- // Model schema uses `includeContent` (boolean); the Exa API
5514
- // expects `contents: { text: true }`. Mirror exaSearchFunc's
5515
- // conversion so CLI proxy results match web behavior.
5516
- contents: parsed.includeContent !== false ? { text: true } : void 0
5070
+ ...parsed.numResults !== void 0 ? { numResults: parsed.numResults } : {}
5517
5071
  };
5072
+ if (typeof parsed.intent === "string" && parsed.intent) {
5073
+ body.intent = parsed.intent;
5074
+ }
5075
+ if (typeof parsed.category === "string" && parsed.category) {
5076
+ body.category = parsed.category;
5077
+ }
5078
+ if (typeof parsed.timeRange === "string" && parsed.timeRange) {
5079
+ body.timeRange = parsed.timeRange;
5080
+ }
5081
+ if (Array.isArray(parsed.includeDomains) && parsed.includeDomains.length > 0) {
5082
+ body.includeDomains = parsed.includeDomains;
5083
+ }
5084
+ if (Array.isArray(parsed.excludeDomains) && parsed.excludeDomains.length > 0) {
5085
+ body.excludeDomains = parsed.excludeDomains;
5086
+ }
5087
+ if (typeof parsed.includeContent === "boolean") {
5088
+ body.includeContent = parsed.includeContent;
5089
+ }
5090
+ if (call?.origin) body.origin = call.origin;
5518
5091
  const content = await postServer("/api/exa-search", body);
5519
5092
  return {
5520
5093
  content,
@@ -6094,9 +5667,9 @@ var boundedOutputPage = (items, total, offset, budget = 8 * 1024) => {
6094
5667
  return { items, hasMore: offset + items.length < total, nextOffset: offset + items.length };
6095
5668
  };
6096
5669
  var resolveNowMs = (deps) => typeof deps.nowMs === "function" ? deps.nowMs() : Date.now();
6097
- function buildProgressField(record3, nowMs) {
6098
- const activity = record3.activity;
6099
- if (!activity || isAgentRunTerminalStatus(record3.status)) return {};
5670
+ function buildProgressField(record, nowMs) {
5671
+ const activity = record.activity;
5672
+ if (!activity || isAgentRunTerminalStatus(record.status)) return {};
6100
5673
  const lastEventAt = Date.parse(activity.lastEventAt ?? "");
6101
5674
  const inFlight = activity.inFlight;
6102
5675
  const progress = {
@@ -6193,15 +5766,15 @@ async function assertCredentialFanoutAllowed(deps, args) {
6193
5766
  }
6194
5767
  const { batchId, parentDialogId } = args;
6195
5768
  if (!batchId && !parentDialogId) return candidateGroup;
6196
- const active = queryRunRecords({ limit: 500 }, deps).runs.filter((record3) => {
6197
- if (isRunTerminalStatus(record3.status)) return false;
6198
- if (batchId && record3.batchId === batchId) return true;
6199
- if (parentDialogId && record3.parentDialogId === parentDialogId) return true;
5769
+ const active = queryRunRecords({ limit: 500 }, deps).runs.filter((record) => {
5770
+ if (isRunTerminalStatus(record.status)) return false;
5771
+ if (batchId && record.batchId === batchId) return true;
5772
+ if (parentDialogId && record.parentDialogId === parentDialogId) return true;
6200
5773
  return false;
6201
- }).map((record3) => ({
6202
- runId: record3.runId,
6203
- agentKey: record3.agentKey,
6204
- credentialGroup: record3.credentialGroup
5774
+ }).map((record) => ({
5775
+ runId: record.runId,
5776
+ agentKey: record.agentKey,
5777
+ credentialGroup: record.credentialGroup
6205
5778
  }));
6206
5779
  if (active.length === 0) return candidateGroup;
6207
5780
  const verdict = checkCredentialFanout({
@@ -6438,16 +6011,16 @@ function createCliControlAgentRunExecutor(deps = {}) {
6438
6011
  },
6439
6012
  deps
6440
6013
  );
6441
- const runs = records.map((record4) => {
6014
+ const runs = records.map((record2) => {
6442
6015
  return {
6443
- runId: record4.runId,
6444
- status: record4.status,
6445
- agentKey: record4.agentKey,
6446
- ...record4.agentName ? { agentName: record4.agentName.slice(0, 120) } : {},
6447
- ...typeof record4.title === "string" ? { title: record4.title.slice(0, 160) } : {},
6448
- ...record4.batchId ? { batchId: record4.batchId } : {},
6449
- pid: record4.pid ?? null,
6450
- startedAt: record4.startedAt
6016
+ runId: record2.runId,
6017
+ status: record2.status,
6018
+ agentKey: record2.agentKey,
6019
+ ...record2.agentName ? { agentName: record2.agentName.slice(0, 120) } : {},
6020
+ ...typeof record2.title === "string" ? { title: record2.title.slice(0, 160) } : {},
6021
+ ...record2.batchId ? { batchId: record2.batchId } : {},
6022
+ pid: record2.pid ?? null,
6023
+ startedAt: record2.startedAt
6451
6024
  };
6452
6025
  });
6453
6026
  const outputBudgetBytes = 8 * 1024;
@@ -6533,15 +6106,15 @@ function createCliControlAgentRunExecutor(deps = {}) {
6533
6106
  if (!args.runId) throw new Error(t("agentRunTool.appendMissingRunId"));
6534
6107
  const userInput = typeof args.userInput === "string" ? args.userInput.trim() : "";
6535
6108
  if (!userInput) throw new Error(t("agentRunTool.appendMissingUserInput"));
6536
- const record4 = findRunRecord(String(args.runId), deps);
6537
- if (!record4) {
6109
+ const record2 = findRunRecord(String(args.runId), deps);
6110
+ if (!record2) {
6538
6111
  const labels2 = agentRunCardLabels();
6539
6112
  return {
6540
6113
  content: JSON.stringify({ runId: args.runId, found: false }),
6541
6114
  metadata: { displayData: formatNotFoundRunCard(labels2) }
6542
6115
  };
6543
6116
  }
6544
- let reconciled2 = checkStaleRun(record4.runId, deps) ?? record4;
6117
+ let reconciled2 = checkStaleRun(record2.runId, deps) ?? record2;
6545
6118
  if (!isAgentRunTerminalStatus(reconciled2.status)) {
6546
6119
  if (!reconciled2.queuePath) {
6547
6120
  throw new Error(t("agentRunTool.appendQueueUnsupported"));
@@ -6621,8 +6194,8 @@ function createCliControlAgentRunExecutor(deps = {}) {
6621
6194
  throw new Error(t("agentRunTool.unknownAction", String(action)));
6622
6195
  }
6623
6196
  if (!args.runId) throw new Error(t("agentRunTool.missingRunId", String(action)));
6624
- const record3 = findRunRecord(String(args.runId), deps);
6625
- if (!record3) {
6197
+ const record = findRunRecord(String(args.runId), deps);
6198
+ if (!record) {
6626
6199
  const labels2 = agentRunCardLabels();
6627
6200
  return {
6628
6201
  content: JSON.stringify({ runId: args.runId, found: false }),
@@ -6630,15 +6203,15 @@ function createCliControlAgentRunExecutor(deps = {}) {
6630
6203
  };
6631
6204
  }
6632
6205
  if (action === "status") {
6633
- const reconciled2 = checkStaleRun(record3.runId, deps) ?? record3;
6634
- const logTail = tailLines > 0 ? tailFile(record3.logPath, tailLines, resolveFs(deps)) : void 0;
6206
+ const reconciled2 = checkStaleRun(record.runId, deps) ?? record;
6207
+ const logTail = tailLines > 0 ? tailFile(record.logPath, tailLines, resolveFs(deps)) : void 0;
6635
6208
  return buildRunStatusPayload(reconciled2, deps, { logTail });
6636
6209
  }
6637
6210
  if (action === "wait") {
6638
6211
  const timeoutMs = typeof args.timeoutMs === "number" && args.timeoutMs > 0 ? args.timeoutMs : DEFAULT_WAIT_TIMEOUT_MS;
6639
6212
  let claimToken = null;
6640
6213
  const result = await waitForRunTerminal({
6641
- read: () => checkStaleRun(record3.runId, deps) ?? record3,
6214
+ read: () => checkStaleRun(record.runId, deps) ?? record,
6642
6215
  isTerminal: (state) => isAgentRunTerminalStatus(state.status),
6643
6216
  pollIntervalMs: WAIT_POLL_INTERVAL_MS,
6644
6217
  timeoutMs,
@@ -6646,28 +6219,28 @@ function createCliControlAgentRunExecutor(deps = {}) {
6646
6219
  sleep: deps.sleep,
6647
6220
  claim: {
6648
6221
  acquire: () => {
6649
- claimToken = claimRunRecord(record3.runId, { ...deps, ttlMs: timeoutMs + ACK_LEASE_GRACE_MS });
6222
+ claimToken = claimRunRecord(record.runId, { ...deps, ttlMs: timeoutMs + ACK_LEASE_GRACE_MS });
6650
6223
  return claimToken;
6651
6224
  },
6652
6225
  commit: (token) => {
6653
- if (token) commitRunRecordClaim(record3.runId, token, deps);
6654
- else ackRunRecord(record3.runId, deps);
6226
+ if (token) commitRunRecordClaim(record.runId, token, deps);
6227
+ else ackRunRecord(record.runId, deps);
6655
6228
  },
6656
6229
  release: (token) => {
6657
- if (token) releaseRunRecordAck(record3.runId, token, deps);
6230
+ if (token) releaseRunRecordAck(record.runId, token, deps);
6658
6231
  }
6659
6232
  }
6660
6233
  });
6661
6234
  if (result.kind === "aborted") throw new Error(t("agentRunTool.waitAborted"));
6662
6235
  if (result.kind === "failed") throw result.error;
6663
6236
  if (result.kind === "timeout") {
6664
- const reconciled2 = result.lastState ?? record3;
6237
+ const reconciled2 = result.lastState ?? record;
6665
6238
  const nowMs = resolveNowMs(deps);
6666
6239
  return { content: JSON.stringify({ runId: reconciled2.runId, found: true, status: "timeout", runStatus: reconciled2.status, pid: reconciled2.pid ?? null, agentKey: reconciled2.agentKey, ...reconciled2.agentName ? { agentName: reconciled2.agentName } : {}, startedAt: reconciled2.startedAt, waitedMs: result.waitedMs, timeoutMs, ...buildProgressField(reconciled2, nowMs) }), metadata: { displayData: t("agentRunWaitTimeout", String(Math.round(result.waitedMs / 1e3))) } };
6667
6240
  }
6668
6241
  return buildRunStatusPayload(result.state, deps);
6669
6242
  }
6670
- const reconciled = checkStaleRun(record3.runId, deps) ?? record3;
6243
+ const reconciled = checkStaleRun(record.runId, deps) ?? record;
6671
6244
  if (isAgentRunTerminalStatus(reconciled.status)) {
6672
6245
  const labels2 = agentRunCardLabels();
6673
6246
  return {
@@ -6686,13 +6259,13 @@ function createCliControlAgentRunExecutor(deps = {}) {
6686
6259
  if (!confirmed) {
6687
6260
  return {
6688
6261
  content: JSON.stringify({
6689
- runId: record3.runId,
6262
+ runId: record.runId,
6690
6263
  found: true,
6691
6264
  status: reconciled.status,
6692
6265
  stopConfirmed: false
6693
6266
  }),
6694
6267
  metadata: {
6695
- displayData: t("agentRunStopFailedAlive", String(record3.pid))
6268
+ displayData: t("agentRunStopFailedAlive", String(record.pid))
6696
6269
  }
6697
6270
  };
6698
6271
  }
@@ -7160,12 +6733,10 @@ var REFRESH_BY_PROVIDER = {
7160
6733
  antigravity: refreshAntigravityOAuthToken,
7161
6734
  xai: xaiRefresh,
7162
6735
  claude: anthropicRefresh,
7163
- cursor: cursorRefresh,
7164
- workbuddy: workbuddyRefresh,
7165
- "workbuddy-ai": workbuddyRefresh
6736
+ cursor: cursorRefresh
7166
6737
  };
7167
6738
  function isOAuthProvider(value) {
7168
- return value === "chatgpt" || value === "xai" || value === "antigravity" || value === "claude" || value === "cursor" || value === "devin" || value === "workbuddy" || value === "workbuddy-ai";
6739
+ return value === "chatgpt" || value === "xai" || value === "antigravity" || value === "claude" || value === "cursor" || value === "devin";
7169
6740
  }
7170
6741
  function createOAuthApiKeyRefResolver(options = {}) {
7171
6742
  const pullServerAccessToken = options.pullServerAccessToken ?? createServerAccessTokenPuller({
@@ -7212,10 +6783,10 @@ function encodeFailure(error, stderr) {
7212
6783
  function readStreams(output) {
7213
6784
  if (typeof output === "string") return { stdout: output, stderr: "" };
7214
6785
  if (!output || typeof output !== "object") return { stdout: "", stderr: "" };
7215
- const record3 = output;
6786
+ const record = output;
7216
6787
  return {
7217
- stdout: typeof record3.stdout === "string" ? record3.stdout : "",
7218
- stderr: typeof record3.stderr === "string" ? record3.stderr : ""
6788
+ stdout: typeof record.stdout === "string" ? record.stdout : "",
6789
+ stderr: typeof record.stderr === "string" ? record.stderr : ""
7219
6790
  };
7220
6791
  }
7221
6792
  function describeMessage(error) {
@@ -8622,8 +8193,8 @@ async function createLocalDockerWorkload(args) {
8622
8193
  }
8623
8194
  const createLifecycle = args.createLifecycle ?? (async () => {
8624
8195
  const [{ DockerWorkloadLifecycle, createDockerBindingAuthorizer }, accounts] = await Promise.all([
8625
- import("./workloadLifecycle-36DXRZKU.js"),
8626
- import("./accountResolver-7RYB4D2P.js")
8196
+ import("./workloadLifecycle-6O6PMISX.js"),
8197
+ import("./accountResolver-55EDKEIK.js")
8627
8198
  ]);
8628
8199
  const resolveAccount = args.resolveAccount ?? accounts.createDockerAccountResolver({
8629
8200
  env: args.env,
@@ -8640,7 +8211,28 @@ async function createLocalDockerWorkload(args) {
8640
8211
  resolveAccount
8641
8212
  });
8642
8213
  });
8643
- const lifecycle = await createLifecycle();
8214
+ const phaseLogEnabled = () => {
8215
+ const env = args.env;
8216
+ return env.NOLO_DEBUG === "1" || env.NOLO_CLI_DEBUG_DETAIL === "1";
8217
+ };
8218
+ const phaseLog = (event, payload) => {
8219
+ if (!phaseLogEnabled()) return;
8220
+ console.warn(`[docker-workload-phase] ${event}`, payload);
8221
+ };
8222
+ const phase = async (name, operation) => {
8223
+ const startedAt = Date.now();
8224
+ phaseLog("start", { phase: name, runId: args.runId });
8225
+ try {
8226
+ const result = await operation();
8227
+ phaseLog("complete", { phase: name, runId: args.runId, elapsedMs: Date.now() - startedAt });
8228
+ return result;
8229
+ } catch (error) {
8230
+ const safeError = error && typeof error === "object" ? error : {};
8231
+ phaseLog("failed", { phase: name, runId: args.runId, elapsedMs: Date.now() - startedAt, errorCode: typeof safeError.code === "string" ? safeError.code : void 0, errorName: typeof safeError.name === "string" ? safeError.name : void 0 });
8232
+ throw error;
8233
+ }
8234
+ };
8235
+ const lifecycle = await phase("create-lifecycle", () => createLifecycle());
8644
8236
  const grant = {
8645
8237
  version: 1,
8646
8238
  grantId: `grant-${args.runId}`,
@@ -8658,25 +8250,29 @@ async function createLocalDockerWorkload(args) {
8658
8250
  }
8659
8251
  };
8660
8252
  const workspaceRoot = args.workspaceRoot ?? process.cwd();
8253
+ const workspaceMode = args.workspaceMode ?? "git";
8661
8254
  const prepareDelivery = args.prepareWorkspaceDelivery ?? prepareHostWorkspaceDelivery;
8662
8255
  const applyDelivery = args.applyWorkspaceDelivery ?? applyDockerWorkspaceDelivery;
8663
8256
  let deliveryApplied = false;
8664
8257
  const deliverWorkspace = async (runtime) => {
8665
8258
  if (deliveryApplied) return;
8666
8259
  deliveryApplied = true;
8667
- const prepared = prepareDelivery({ workspaceRoot });
8668
- if (!prepared.ok) {
8669
- throw new LocalWorkspaceDeliveryError(
8670
- prepared.code,
8671
- `${prepared.message}\uFF08\u5BBF\u4E3B\u4FA7\u6295\u9001\u51C6\u5907\u5931\u8D25\uFF0C\u672C run \u62D2\u7EDD\u8FDB\u5165\u5DE5\u5177\u5FAA\u73AF\uFF09`
8672
- );
8673
- }
8260
+ const prepared = await phase("host-archive", () => {
8261
+ const result = prepareDelivery({ workspaceRoot });
8262
+ if (!result.ok) {
8263
+ throw new LocalWorkspaceDeliveryError(
8264
+ result.code,
8265
+ `${result.message}\uFF08\u5BBF\u4E3B\u4FA7\u6295\u9001\u51C6\u5907\u5931\u8D25\uFF0C\u672C run \u62D2\u7EDD\u8FDB\u5165\u5DE5\u5177\u5FAA\u73AF\uFF09`
8266
+ );
8267
+ }
8268
+ return result;
8269
+ });
8674
8270
  if (args.signal?.aborted) {
8675
8271
  await prepared.cleanup();
8676
8272
  throw new LocalWorkspaceDeliveryError("delivery_cancelled", "run \u5DF2\u53D6\u6D88\uFF0C\u653E\u5F03\u5DE5\u4F5C\u533A\u6295\u9001\u3002");
8677
8273
  }
8678
8274
  try {
8679
- await applyDelivery(runtime, prepared.selection);
8275
+ await phase("delivery", () => applyDelivery(runtime, prepared.selection));
8680
8276
  } catch (error) {
8681
8277
  const code = isDockerWorkspaceDeliveryError(error) ? error.code : "delivery_failed";
8682
8278
  throw new LocalWorkspaceDeliveryError(
@@ -8725,11 +8321,39 @@ async function createLocalDockerWorkload(args) {
8725
8321
  },
8726
8322
  async (workload2, runtime) => {
8727
8323
  if (runtime) {
8728
- const uploaded = await runtime.exec(buildSandboxHelperUploadArgv());
8729
- if (!uploaded.ok) throw new Error("docker_helper_upload_failed");
8730
- await deliverWorkspace(runtime);
8324
+ await phase("sandbox-helper-upload", async () => {
8325
+ const uploaded = await runtime.exec(buildSandboxHelperUploadArgv());
8326
+ if (!uploaded.ok) {
8327
+ throw Object.assign(new Error("docker_helper_upload_failed"), { code: "docker_helper_upload_failed" });
8328
+ }
8329
+ });
8330
+ if (workspaceMode === "git") {
8331
+ await deliverWorkspace(runtime);
8332
+ } else {
8333
+ await phase("empty-workspace-root", async () => {
8334
+ const root = await runtime.exec([
8335
+ "bash",
8336
+ "-lc",
8337
+ `mkdir -p '${SANDBOX_WORKSPACE_ROOT}' && test -d '${SANDBOX_WORKSPACE_ROOT}' && test -w '${SANDBOX_WORKSPACE_ROOT}'`
8338
+ ]);
8339
+ if (!root.ok) {
8340
+ throw Object.assign(new Error("docker_empty_workspace_root_failed"), { code: "docker_empty_workspace_root_failed" });
8341
+ }
8342
+ const gitInstall = await runtime.exec(buildInstallGitArgv());
8343
+ if (!gitInstall.ok) {
8344
+ throw Object.assign(
8345
+ new Error(`docker_empty_workspace_git_install_failed (exit ${gitInstall.exitCode})`),
8346
+ { code: "docker_empty_workspace_git_install_failed" }
8347
+ );
8348
+ }
8349
+ const gitProbe = await runtime.exec(["bash", "-lc", "command -v git"]);
8350
+ if (!gitProbe.ok) {
8351
+ throw Object.assign(new Error("docker_empty_workspace_git_missing"), { code: "docker_empty_workspace_git_missing" });
8352
+ }
8353
+ });
8354
+ }
8731
8355
  }
8732
- resolveReady(workload2);
8356
+ await phase("ready", () => resolveReady(workload2));
8733
8357
  await waitForReleaseOrAbort();
8734
8358
  return void 0;
8735
8359
  }
@@ -8786,6 +8410,7 @@ async function createLocalDockerWorkload(args) {
8786
8410
  var INSTABOX_BACKEND_ID = "instabox";
8787
8411
  var INSTABOX_DEFAULT_BASE_URL = "https://api.instabox.sh/v1";
8788
8412
  var INSTABOX_MAX_EXEC_SECONDS = 600;
8413
+ var INSTABOX_MAX_STDIN_BYTES = 1024 * 1024;
8789
8414
  var SAFE_MESSAGE3 = {
8790
8415
  "instabox_invalid_config": "Rejected: instabox backend needs an apiKey and a templateId",
8791
8416
  "instabox_invalid_ticket": "Rejected: execution ticket cannot be satisfied by the instabox backend",
@@ -8951,9 +8576,9 @@ var InstaboxBackend = class {
8951
8576
  `create HTTP ${created.status}${created.transportError ? ` ${created.transportError}` : ""}`
8952
8577
  );
8953
8578
  }
8954
- const record3 = asRecord(created.payload);
8955
- const machineId = readString2(record3?.machineId);
8956
- const operationId = readString2(record3?.id);
8579
+ const record = asRecord(created.payload);
8580
+ const machineId = readString2(record?.machineId);
8581
+ const operationId = readString2(record?.id);
8957
8582
  if (!machineId || !operationId) {
8958
8583
  throw new InstaboxBackendError(
8959
8584
  "instabox_create_failed",
@@ -9019,12 +8644,7 @@ var InstaboxBackend = class {
9019
8644
  "argv must be a non-empty array"
9020
8645
  );
9021
8646
  }
9022
- if (request.stdin !== void 0) {
9023
- throw new InstaboxBackendError(
9024
- "instabox_unsupported_request",
9025
- "instabox exec has no stdin channel"
9026
- );
9027
- }
8647
+ const stdin = this.#resolveStdin(request.stdin);
9028
8648
  const timeoutSeconds = this.#resolveExecTimeoutSeconds(request.timeoutMs);
9029
8649
  const cmd = this.#buildCommand(request);
9030
8650
  const executionId = `${entry.machineId}:${this.#now().toString(36)}`;
@@ -9033,7 +8653,7 @@ var InstaboxBackend = class {
9033
8653
  const response = await this.#call({
9034
8654
  method: "POST",
9035
8655
  path: `/machines/${encodeURIComponent(entry.machineId)}/exec`,
9036
- body: { cmd, timeoutSeconds }
8656
+ body: { cmd, timeoutSeconds, ...stdin === void 0 ? {} : { stdin } }
9037
8657
  });
9038
8658
  if (!isSuccess(response.status)) {
9039
8659
  throw new InstaboxBackendError(
@@ -9161,6 +8781,27 @@ var InstaboxBackend = class {
9161
8781
  }
9162
8782
  return entry;
9163
8783
  }
8784
+ /**
8785
+ * stdin 直通校验:`undefined` = 请求里没提供(body 里也不加字段,保持原报文兼容);
8786
+ * 字符串(含空串)在 1 MiB / UTF-8 字节以内原样透传;其他类型或超限立即拒绝,
8787
+ * 错误文案只带上限数字,**绝不回显输入内容**。
8788
+ */
8789
+ #resolveStdin(stdin) {
8790
+ if (stdin === void 0) return void 0;
8791
+ if (typeof stdin !== "string") {
8792
+ throw new InstaboxBackendError(
8793
+ "instabox_unsupported_request",
8794
+ "stdin must be a string"
8795
+ );
8796
+ }
8797
+ if (utf8ByteLengthExceeds(stdin, INSTABOX_MAX_STDIN_BYTES)) {
8798
+ throw new InstaboxBackendError(
8799
+ "instabox_unsupported_request",
8800
+ `stdin exceeds the ${INSTABOX_MAX_STDIN_BYTES} byte limit`
8801
+ );
8802
+ }
8803
+ return stdin;
8804
+ }
9164
8805
  #resolveExecTimeoutSeconds(timeoutMs) {
9165
8806
  const boundMs = INSTABOX_MAX_EXEC_SECONDS * 1e3;
9166
8807
  if (timeoutMs === void 0) return this.#execTimeoutSeconds;
@@ -9178,7 +8819,7 @@ var InstaboxBackend = class {
9178
8819
  }
9179
8820
  return clampExecSeconds(Math.ceil(timeoutMs / 1e3));
9180
8821
  }
9181
- /** cwd / env 用 `cd` + 赋值前缀表达(Instabox exec 只有 cmd 一个入口)。 */
8822
+ /** cwd / env 仍用 `cd` + 赋值前缀表达(exec body 只多一个可选 stdin,不承载 cwd/env)。 */
9182
8823
  #buildCommand(request) {
9183
8824
  const script = argvToInstaboxCommand(request.argv);
9184
8825
  const segments = [];
@@ -9236,15 +8877,15 @@ var InstaboxBackend = class {
9236
8877
  path: `/machines/${encodeURIComponent(machineId)}/usage`
9237
8878
  });
9238
8879
  if (!isSuccess(response.status)) return null;
9239
- const record3 = asRecord(response.payload);
9240
- const runningSeconds = readFiniteNumber(record3?.runningSeconds);
8880
+ const record = asRecord(response.payload);
8881
+ const runningSeconds = readFiniteNumber(record?.runningSeconds);
9241
8882
  if (runningSeconds === null) return null;
9242
8883
  const sample = { runningSeconds };
9243
- const vcpuSeconds = readFiniteNumber(record3?.vcpuSeconds);
8884
+ const vcpuSeconds = readFiniteNumber(record?.vcpuSeconds);
9244
8885
  if (vcpuSeconds !== null) sample.vcpuSeconds = vcpuSeconds;
9245
- const memGiBSeconds = readFiniteNumber(record3?.memGiBSeconds);
8886
+ const memGiBSeconds = readFiniteNumber(record?.memGiBSeconds);
9246
8887
  if (memGiBSeconds !== null) sample.memGiBSeconds = memGiBSeconds;
9247
- const diskGiBSeconds = readFiniteNumber(record3?.diskGiBSeconds);
8888
+ const diskGiBSeconds = readFiniteNumber(record?.diskGiBSeconds);
9248
8889
  if (diskGiBSeconds !== null) sample.diskGiBSeconds = diskGiBSeconds;
9249
8890
  return sample;
9250
8891
  }
@@ -9264,13 +8905,13 @@ var InstaboxBackend = class {
9264
8905
  path: `/operations/${encodeURIComponent(args.operationId)}?wait=${this.#operationWaitSeconds}s`
9265
8906
  });
9266
8907
  lastStatus = response.status;
9267
- const record3 = isSuccess(response.status) ? asRecord(response.payload) : null;
9268
- const state = readString2(record3?.state);
8908
+ const record = isSuccess(response.status) ? asRecord(response.payload) : null;
8909
+ const state = readString2(record?.state);
9269
8910
  if (state === "succeeded") return;
9270
8911
  if (state === "failed") {
9271
8912
  throw new InstaboxBackendError(
9272
8913
  args.failCode,
9273
- `operation ${args.operationId} failed${readString2(record3?.error) ? `: ${readString2(record3?.error)}` : ""}`,
8914
+ `operation ${args.operationId} failed${readString2(record?.error) ? `: ${readString2(record?.error)}` : ""}`,
9274
8915
  args.cleanupPendingOnFailure
9275
8916
  );
9276
8917
  }
@@ -9294,6 +8935,10 @@ function truncateOutput(value, limitChars) {
9294
8935
  if (value.length <= limitChars) return value;
9295
8936
  return `${value.slice(0, limitChars)}\u2026[truncated ${value.length - limitChars} chars]`;
9296
8937
  }
8938
+ function utf8ByteLengthExceeds(value, limit) {
8939
+ if (value.length > limit) return true;
8940
+ return new TextEncoder().encode(value).length > limit;
8941
+ }
9297
8942
  function createInstaboxExecutionBackend(options) {
9298
8943
  return new InstaboxBackend(options);
9299
8944
  }
@@ -9308,6 +8953,213 @@ function asExecutionBackend(backend) {
9308
8953
  };
9309
8954
  }
9310
8955
 
8956
+ // packages/cli/client/localInstaboxFileBridge.ts
8957
+ var INSTABOX_HELPER_PATH = SANDBOX_HELPER_PATH;
8958
+ var INSTABOX_WORKSPACE_ROOT = "/data/home";
8959
+ var INSTABOX_FILE_TOOL_NAMES = [
8960
+ "readFile",
8961
+ "writeFile",
8962
+ "editFile",
8963
+ "globFiles"
8964
+ ];
8965
+ var PROBE_FILE_NAME = "nolo-bridge-probe";
8966
+ function escapeForShell(value) {
8967
+ const cleaned = String(value).replace(/[^A-Za-z0-9._-]/g, "-").slice(0, 40);
8968
+ return cleaned || "run";
8969
+ }
8970
+ var PROBE_FILE_CONTENT = "nolo-bridge-ok";
8971
+ function posixQuote(value) {
8972
+ return `'${String(value).replace(/'/g, `'\\''`)}'`;
8973
+ }
8974
+ function buildInstaboxHelperSource(root) {
8975
+ const source = buildWorkspaceHelperSource();
8976
+ const rootLiteral = /const ROOT = "[^"]*";/;
8977
+ if (!rootLiteral.test(source)) {
8978
+ throw new Error("instabox_helper_root_patch_failed");
8979
+ }
8980
+ if (!root.startsWith("/") || root.includes('"') || root.includes("\\")) {
8981
+ throw new Error("instabox_invalid_workspace_root");
8982
+ }
8983
+ return source.replace(rootLiteral, `const ROOT = "${root}";`);
8984
+ }
8985
+ function buildInstaboxBridgeBootstrapScript(root, probeId) {
8986
+ let helperPayload;
8987
+ if (!root.startsWith("/") || root.includes('"') || root.includes("\\")) {
8988
+ return `printf 'NOLO_BRIDGE_REASON=root_unavailable
8989
+ '`;
8990
+ }
8991
+ try {
8992
+ helperPayload = Buffer.from(buildInstaboxHelperSource(root), "utf8").toString("base64");
8993
+ } catch (error) {
8994
+ return `printf 'NOLO_BRIDGE_REASON=helper_source_invalid
8995
+ '`;
8996
+ }
8997
+ const dir = INSTABOX_HELPER_PATH.slice(0, INSTABOX_HELPER_PATH.lastIndexOf("/"));
8998
+ return [
8999
+ `root=${posixQuote(root)}`,
9000
+ `mkdir -p "$root" 2>/dev/null || true`,
9001
+ `if [ ! -w "$root" ]; then printf 'NOLO_BRIDGE_REASON=root_unavailable\\n'; exit 0; fi`,
9002
+ `printf 'NOLO_BRIDGE_ROOT=%s\\n' "$root"`,
9003
+ "rt=''",
9004
+ `for cand in bun node; do if command -v "$cand" >/dev/null 2>&1; then rt="$cand"; break; fi; done`,
9005
+ `printf 'NOLO_BRIDGE_RUNTIME=%s\\n' "\${rt:-none}"`,
9006
+ `if [ -z "$rt" ]; then printf 'NOLO_BRIDGE_REASON=runtime_missing\\n'; exit 0; fi`,
9007
+ `mkdir -p ${posixQuote(dir)} 2>/dev/null || true`,
9008
+ `if ! printf %s ${posixQuote(helperPayload)} | base64 -d > ${posixQuote(INSTABOX_HELPER_PATH)}; then printf 'NOLO_BRIDGE_REASON=upload_failed\\n'; exit 0; fi`,
9009
+ `chmod 0644 ${posixQuote(INSTABOX_HELPER_PATH)} 2>/dev/null || true`,
9010
+ // 探针文件名带本次 run 的唯一 id:**只创建自己的**,绝不覆盖/删除同名既有文件
9011
+ `probe=$root/${escapeForShell(probeId)}-${PROBE_FILE_NAME}`,
9012
+ `if [ -e "$probe" ]; then printf 'NOLO_BRIDGE_REASON=probe_failed\\n'; exit 0; fi`,
9013
+ `printf %s ${posixQuote(PROBE_FILE_CONTENT)} > "$probe" || { printf 'NOLO_BRIDGE_REASON=upload_failed\\n'; exit 0; }`,
9014
+ `printf 'NOLO_BRIDGE_PROBE=%s\\n' "$probe"`,
9015
+ `printf 'NOLO_BRIDGE_UPLOAD=ok\\n'`
9016
+ ].join("\n");
9017
+ }
9018
+ function parseInstaboxBootstrapOutput(stdout) {
9019
+ let root = null;
9020
+ let probePath = null;
9021
+ let runtime = null;
9022
+ let reason;
9023
+ let uploadOk = false;
9024
+ for (const rawLine of stdout.split(String.fromCharCode(10))) {
9025
+ const line = rawLine.trim();
9026
+ if (line.startsWith("NOLO_BRIDGE_ROOT=")) {
9027
+ const value = line.slice("NOLO_BRIDGE_ROOT=".length).trim();
9028
+ root = value.startsWith("/") ? value : null;
9029
+ } else if (line.startsWith("NOLO_BRIDGE_RUNTIME=")) {
9030
+ const value = line.slice("NOLO_BRIDGE_RUNTIME=".length).trim();
9031
+ runtime = value === "bun" || value === "node" ? value : null;
9032
+ } else if (line.startsWith("NOLO_BRIDGE_UPLOAD=")) {
9033
+ uploadOk = line.slice("NOLO_BRIDGE_UPLOAD=".length).trim() === "ok";
9034
+ } else if (line.startsWith("NOLO_BRIDGE_PROBE=")) {
9035
+ const value = line.slice("NOLO_BRIDGE_PROBE=".length).trim();
9036
+ probePath = value.startsWith("/") ? value : null;
9037
+ } else if (line.startsWith("NOLO_BRIDGE_REASON=")) {
9038
+ const value = line.slice("NOLO_BRIDGE_REASON=".length).trim();
9039
+ reason = value === "runtime_missing" || value === "root_unavailable" || value === "upload_failed" || value === "probe_failed" || value === "root_mismatch" || value === "helper_source_invalid" ? value : "probe_failed";
9040
+ }
9041
+ }
9042
+ if (!root) return { root: null, runtime: null, probePath: null, reason: reason ?? "root_unavailable" };
9043
+ if (!runtime) return { root, runtime: null, probePath, reason: reason ?? "runtime_missing" };
9044
+ if (!uploadOk) return { root, runtime, probePath, reason: reason ?? "upload_failed" };
9045
+ if (!probePath) return { root, runtime, probePath: null, reason: reason ?? "probe_failed" };
9046
+ return { root, runtime, probePath };
9047
+ }
9048
+ function resolveInstaboxPath(root, input) {
9049
+ if (typeof input !== "string" || !input.trim() || input.includes("\0")) {
9050
+ return { ok: false, error: "invalid_path" };
9051
+ }
9052
+ const normalizedRoot = root.endsWith("/") ? root.slice(0, -1) : root;
9053
+ const isAbs = input.startsWith("/");
9054
+ if (isAbs && input !== normalizedRoot && !input.startsWith(`${normalizedRoot}/`)) {
9055
+ return { ok: false, error: "path_outside_workspace" };
9056
+ }
9057
+ const resolved = isAbs ? posixNormalize(input) : posixNormalize(`${normalizedRoot}/${input}`);
9058
+ if (resolved !== normalizedRoot && !resolved.startsWith(`${normalizedRoot}/`)) {
9059
+ return { ok: false, error: "path_escape" };
9060
+ }
9061
+ return { ok: true, path: resolved };
9062
+ }
9063
+ function posixNormalize(input) {
9064
+ const parts = [];
9065
+ for (const segment of input.split("/")) {
9066
+ if (!segment || segment === ".") continue;
9067
+ if (segment === "..") {
9068
+ parts.pop();
9069
+ continue;
9070
+ }
9071
+ parts.push(segment);
9072
+ }
9073
+ return `/${parts.join("/")}`;
9074
+ }
9075
+ function buildInstaboxToolArgv(toolName, args, bridge) {
9076
+ const validated = {};
9077
+ let op;
9078
+ switch (toolName) {
9079
+ case "readFile": {
9080
+ const res = resolveInstaboxPath(bridge.root, String(args.path ?? ""));
9081
+ if (!res.ok) return { ok: false, error: res.error };
9082
+ op = "readFile";
9083
+ validated.path = res.path;
9084
+ if (typeof args.lines === "string") validated.lines = args.lines;
9085
+ break;
9086
+ }
9087
+ case "writeFile": {
9088
+ if (typeof args.content !== "string") return { ok: false, error: "missing_content" };
9089
+ if (Buffer.byteLength(args.content, "utf-8") > SANDBOX_OUTPUT_LIMITS.maxContentBytes) {
9090
+ return { ok: false, error: "content_too_large" };
9091
+ }
9092
+ const res = resolveInstaboxPath(bridge.root, String(args.path ?? ""));
9093
+ if (!res.ok) return { ok: false, error: res.error };
9094
+ op = "writeFile";
9095
+ validated.path = res.path;
9096
+ validated.content = args.content;
9097
+ break;
9098
+ }
9099
+ case "editFile": {
9100
+ if (typeof args.oldText !== "string" || typeof args.newText !== "string") {
9101
+ return { ok: false, error: "missing_edit_text" };
9102
+ }
9103
+ if (args.oldText === args.newText) return { ok: false, error: "edit_text_identical" };
9104
+ if (Buffer.byteLength(args.newText, "utf-8") > SANDBOX_OUTPUT_LIMITS.maxContentBytes) {
9105
+ return { ok: false, error: "content_too_large" };
9106
+ }
9107
+ const res = resolveInstaboxPath(bridge.root, String(args.path ?? ""));
9108
+ if (!res.ok) return { ok: false, error: res.error };
9109
+ op = "editFile";
9110
+ validated.path = res.path;
9111
+ validated.oldText = args.oldText;
9112
+ validated.newText = args.newText;
9113
+ break;
9114
+ }
9115
+ case "globFiles":
9116
+ case "glob": {
9117
+ if (typeof args.pattern !== "string" || !args.pattern.trim()) {
9118
+ return { ok: false, error: "missing_pattern" };
9119
+ }
9120
+ op = "glob";
9121
+ validated.pattern = args.pattern;
9122
+ if (typeof args.path === "string" && args.path.trim()) {
9123
+ const res = resolveInstaboxPath(bridge.root, args.path);
9124
+ if (!res.ok) return { ok: false, error: res.error };
9125
+ validated.path = res.path;
9126
+ }
9127
+ break;
9128
+ }
9129
+ default:
9130
+ return { ok: false, error: "unsupported_tool" };
9131
+ }
9132
+ const payload = Buffer.from(JSON.stringify({ op, args: validated }), "utf-8").toString("base64");
9133
+ if (payload.length > SANDBOX_OUTPUT_LIMITS.maxArgvBytes) {
9134
+ return { ok: false, error: "content_too_large" };
9135
+ }
9136
+ return { ok: true, argv: [bridge.runtime, INSTABOX_HELPER_PATH, payload] };
9137
+ }
9138
+ function buildInstaboxBridgeProbeRequest(bridge, probePath) {
9139
+ const payload = Buffer.from(
9140
+ JSON.stringify({ op: "readFile", args: { path: probePath } }),
9141
+ "utf-8"
9142
+ ).toString("base64");
9143
+ return { kind: "command", argv: [bridge.runtime, INSTABOX_HELPER_PATH, payload] };
9144
+ }
9145
+ function readInstaboxProbeResult(stdout) {
9146
+ if (typeof stdout !== "string") return { ready: false, reason: "probe_failed" };
9147
+ const text = stdout.trim();
9148
+ if (!text) return { ready: false, reason: "probe_failed" };
9149
+ if (text.includes('"ok":false') || text.includes("'ok':false")) {
9150
+ return { ready: false, reason: "probe_failed" };
9151
+ }
9152
+ if (text.includes(PROBE_FILE_CONTENT)) return { ready: true };
9153
+ const parsed = parseToolOutput(text);
9154
+ if (!parsed.ok) return { ready: false, reason: "probe_failed" };
9155
+ const value = parsed.value;
9156
+ return typeof value === "object" && value !== null && typeof value.content === "string" && value.content.includes(PROBE_FILE_CONTENT) ? { ready: true } : { ready: false, reason: "probe_failed" };
9157
+ }
9158
+ function describeInstaboxBridgeUnavailable(bridge) {
9159
+ const detail = bridge.reason === "runtime_missing" ? "Instabox \u6A21\u677F\u5185\u65E2\u6CA1\u6709 bun \u4E5F\u6CA1\u6709 node\uFF0C\u5BB9\u5668\u5185 helper \u65E0\u6CD5\u6267\u884C" : bridge.reason === "root_unavailable" ? "Instabox \u5BB9\u5668\u5185\u65E0\u6CD5\u521B\u5EFA\u53EF\u5199\u5DE5\u4F5C\u76EE\u5F55" : bridge.reason === "upload_failed" ? "\u5BB9\u5668\u5185 helper \u4E0A\u4F20\u5931\u8D25" : bridge.reason === "root_mismatch" ? "\u5BB9\u5668\u5185\u56FA\u5B9A\u5DE5\u4F5C\u76EE\u5F55\u4E0E helper ROOT \u4E0D\u4E00\u81F4" : bridge.reason === "helper_source_invalid" ? "\u5171\u4EAB helper \u6E90\u7801\u5F62\u72B6\u53D8\u5316\uFF0C\u65E0\u6CD5\u5B89\u5168\u6539\u5199 ROOT" : "\u5BB9\u5668\u5185 helper \u63A2\u9488\u8BFB\u56DE\u5931\u8D25";
9160
+ return `instabox \u6587\u4EF6\u5DE5\u5177 bridge \u672A\u5C31\u7EEA\uFF08${bridge.reason ?? "probe_failed"}\uFF09\uFF1A${detail}\uFF1B\u6587\u4EF6\u5DE5\u5177\u5DF2\u663E\u5F0F\u62D2\u7EDD\uFF0C\u7EDD\u4E0D\u56DE\u843D\u5BBF\u4E3B\u6267\u884C\uFF08execShell \u4ECD\u53EF\u7528\uFF09\u3002`;
9161
+ }
9162
+
9311
9163
  // packages/cli/client/localInstaboxWorkload.ts
9312
9164
  var LOCAL_INSTABOX_BACKEND_ID = INSTABOX_BACKEND_ID;
9313
9165
  function resolveInstaboxApiKey(env) {
@@ -9328,6 +9180,35 @@ function assertInstaboxPrerequisites(env) {
9328
9180
  }
9329
9181
  return apiKey;
9330
9182
  }
9183
+ function resolveInstaboxWorkspaceRoot(env) {
9184
+ const override = env.INSTABOX_WORKSPACE_ROOT?.trim();
9185
+ if (override && override.startsWith("/") && !override.includes('"')) return override;
9186
+ return INSTABOX_WORKSPACE_ROOT;
9187
+ }
9188
+ function posixQuote2(value) {
9189
+ return `'${String(value).replace(/'/g, `'\\''`)}'`;
9190
+ }
9191
+ async function prepareFileBridge(execDirect, root, probeId) {
9192
+ const bootstrapStdout = await execDirect({
9193
+ kind: "command",
9194
+ argv: ["bash", "-lc", buildInstaboxBridgeBootstrapScript(root, probeId)]
9195
+ });
9196
+ const parsed = parseInstaboxBootstrapOutput(bootstrapStdout);
9197
+ if (!parsed.root || !parsed.runtime || !parsed.probePath || parsed.reason) {
9198
+ return {
9199
+ root: parsed.root,
9200
+ runtime: parsed.runtime,
9201
+ ready: false,
9202
+ reason: parsed.reason ?? "probe_failed"
9203
+ };
9204
+ }
9205
+ const pinned = { root: parsed.root, runtime: parsed.runtime };
9206
+ const probeStdout = await execDirect(
9207
+ buildInstaboxBridgeProbeRequest(pinned, parsed.probePath)
9208
+ );
9209
+ const verdict = readInstaboxProbeResult(probeStdout);
9210
+ return verdict.ready ? { root: pinned.root, runtime: pinned.runtime, ready: true } : { root: pinned.root, runtime: pinned.runtime, ready: false, reason: verdict.reason ?? "probe_failed" };
9211
+ }
9331
9212
  async function createLocalInstaboxWorkload(args) {
9332
9213
  if (args.runtimeKey.trim() !== "instabox") {
9333
9214
  throw new LocalRuntimeKeyUnsupportedError(
@@ -9342,6 +9223,7 @@ async function createLocalInstaboxWorkload(args) {
9342
9223
  templateId: args.templateId ?? args.env.INSTABOX_TEMPLATE_ID?.trim() ?? "universal"
9343
9224
  })
9344
9225
  );
9226
+ const workspaceRoot = resolveInstaboxWorkspaceRoot(args.env);
9345
9227
  const ticket = {
9346
9228
  version: 1,
9347
9229
  ticketId: `ticket-${args.runId}`,
@@ -9351,12 +9233,14 @@ async function createLocalInstaboxWorkload(args) {
9351
9233
  callerUserId: args.authenticatedCaller || "local-caller",
9352
9234
  executionClass: "session",
9353
9235
  target: { kind: "server" },
9354
- toolNames: [EXECUTION_SHELL_TOOL],
9236
+ // 本 workload 真的会执行这些工具(shell + 容器内结构化文件工具),授权声明必须一致
9237
+ toolNames: [EXECUTION_SHELL_TOOL, ...INSTABOX_FILE_TOOL_NAMES],
9355
9238
  filesystem: {
9356
- readScope: "none",
9357
- readableRoots: [],
9358
- writeScope: "none",
9359
- writableRoots: []
9239
+ // 钉住的固定工作目录:读写范围都声明成它,不写 "none" 再偷偷写文件
9240
+ readScope: "configured-roots",
9241
+ readableRoots: [workspaceRoot],
9242
+ writeScope: "configured-roots",
9243
+ writableRoots: [workspaceRoot]
9360
9244
  },
9361
9245
  shellAllowed: true,
9362
9246
  requestedIsolation: "container",
@@ -9371,37 +9255,118 @@ async function createLocalInstaboxWorkload(args) {
9371
9255
  `runtimeKey \u6307\u5411 instabox\uFF0C\u4F46\u4E91\u6C99\u76D2\u521D\u59CB\u5316\u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}\u3002${instaboxFailureHint}`
9372
9256
  );
9373
9257
  }
9258
+ let releaseState = "active";
9259
+ let releasePromise = null;
9260
+ const releaseBackend = () => {
9261
+ if (releaseState === "released") return Promise.resolve();
9262
+ if (releasePromise) return releasePromise;
9263
+ releaseState = "releasing";
9264
+ let attempt;
9265
+ try {
9266
+ attempt = Promise.resolve(backend.release(lease, "completed"));
9267
+ } catch (error) {
9268
+ attempt = Promise.reject(error);
9269
+ }
9270
+ releasePromise = attempt.then(
9271
+ () => {
9272
+ releaseState = "released";
9273
+ },
9274
+ (error) => {
9275
+ releaseState = "cleanup_pending";
9276
+ throw error;
9277
+ }
9278
+ ).finally(() => {
9279
+ releasePromise = null;
9280
+ });
9281
+ return releasePromise;
9282
+ };
9283
+ const describeReleaseFailure = (error) => {
9284
+ const record = error;
9285
+ const cleanupPending = record?.cleanupPending === true || record?.code === "instabox_cleanup_pending";
9286
+ const detail = error instanceof Error ? error.message : String(error);
9287
+ return cleanupPending ? `\u4E14\u673A\u5668\u5220\u9664\u672A\u786E\u8BA4\uFF1Acleanup_pending\uFF08${detail}\uFF09\u2014\u2014\u4E91\u7AEF\u53EF\u80FD\u4ECD\u6709\u5B58\u6D3B\u673A\u5668\uFF0C\u4E0D\u5F97\u5F53\u4F5C\u5DF2\u6E05\u7406\uFF0C\u9700\u4EBA\u5DE5\u6838\u5BF9\u540E\u5220\u9664` : `\u4E14 release \u4E5F\u5931\u8D25\uFF08${detail}\uFF09`;
9288
+ };
9289
+ const execDirect = async (request) => {
9290
+ const result = await backend.execute(lease, request);
9291
+ const streams = result.output;
9292
+ const stdout = typeof streams?.stdout === "string" ? streams.stdout : "";
9293
+ const stderr = typeof streams?.stderr === "string" ? streams.stderr : "";
9294
+ if (result.ok === false) {
9295
+ throw new Error(`instabox \u5BB9\u5668\u5185\u6267\u884C\u5931\u8D25\uFF1A${stderr || `exit_code:${result.exitCode ?? "unknown"}`}`);
9296
+ }
9297
+ return stdout;
9298
+ };
9299
+ let bridge;
9300
+ try {
9301
+ bridge = await prepareFileBridge(execDirect, workspaceRoot, args.runId);
9302
+ } catch (error) {
9303
+ let cleanupNote = "\u672C\u6B21 lease \u5DF2\u91CA\u653E";
9304
+ try {
9305
+ await releaseBackend();
9306
+ } catch (releaseError) {
9307
+ cleanupNote = describeReleaseFailure(releaseError);
9308
+ }
9309
+ throw new LocalRuntimeKeyUnsupportedError(
9310
+ "instabox_bridge_bootstrap_failed",
9311
+ `runtimeKey \u6307\u5411 instabox\uFF0C\u4F46\u5BB9\u5668\u5185\u6587\u4EF6\u5DE5\u5177\u6865 bootstrap \u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}\uFF1B${cleanupNote}\u3002${instaboxFailureHint}`
9312
+ );
9313
+ }
9374
9314
  const rawChannel = createExecutionChannel({
9375
9315
  backend,
9376
9316
  lease,
9377
- timeoutMs: 10 * 60 * 1e3
9317
+ timeoutMs: 10 * 60 * 1e3,
9318
+ ...bridge.ready && bridge.root && bridge.runtime ? {
9319
+ helper: {
9320
+ path: INSTABOX_HELPER_PATH,
9321
+ buildArgv: (toolName, toolArgs) => buildInstaboxToolArgv(toolName, toolArgs, {
9322
+ root: bridge.root,
9323
+ runtime: bridge.runtime
9324
+ })
9325
+ }
9326
+ } : {}
9378
9327
  });
9379
- let released = false;
9380
9328
  const release = async () => {
9381
- if (released) return;
9382
- released = true;
9383
- try {
9384
- await backend.release(lease, "completed");
9385
- } catch {
9386
- }
9329
+ await releaseBackend();
9387
9330
  };
9388
9331
  const channel = async (toolName, toolArgs, signal) => {
9389
- if (released) {
9332
+ if (releaseState !== "active") {
9390
9333
  throw new Error(
9391
- "instabox workload \u5DF2\u91CA\u653E\uFF1A\u672C run \u7684 lease \u5DF2\u5931\u6548\uFF0C\u62D2\u7EDD\u5728\u5BBF\u4E3B\u6267\u884C\u5DE5\u5177"
9334
+ releaseState === "cleanup_pending" ? "instabox workload cleanup_pending\uFF1A\u4E0A\u4E00\u6B21\u6E05\u7406\u672A\u786E\u8BA4\uFF0Clease \u72B6\u6001\u4E0D\u53EF\u4FE1\uFF0C\u62D2\u7EDD\u6267\u884C\u5DE5\u5177" : "instabox workload \u5DF2\u91CA\u653E\uFF1A\u672C run \u7684 lease \u5DF2\u5931\u6548\uFF0C\u62D2\u7EDD\u5728\u5BBF\u4E3B\u6267\u884C\u5DE5\u5177"
9392
9335
  );
9393
9336
  }
9394
9337
  if (toolName === "execShell") {
9338
+ const command = typeof toolArgs.command === "string" ? toolArgs.command : void 0;
9339
+ if (bridge.root && command !== void 0) {
9340
+ return await rawChannel(EXECUTION_SHELL_TOOL, {
9341
+ ...toolArgs,
9342
+ command: `cd ${posixQuote2(bridge.root)} && ${command}`
9343
+ }, signal);
9344
+ }
9395
9345
  return await rawChannel(EXECUTION_SHELL_TOOL, toolArgs, signal);
9396
9346
  }
9347
+ if (INSTABOX_FILE_TOOL_NAMES.includes(toolName)) {
9348
+ if (!bridge.ready) {
9349
+ throw new Error(describeInstaboxBridgeUnavailable(bridge));
9350
+ }
9351
+ const output = await rawChannel(toolName, toolArgs, signal);
9352
+ const parsed = parseToolOutput(output);
9353
+ if (!parsed.ok) {
9354
+ return JSON.stringify({ ok: false, error: parsed.error, workloadLocation: "instabox" });
9355
+ }
9356
+ const value = parsed.value;
9357
+ const payload = typeof value === "object" && value !== null ? { ok: true, ...value, value, workloadLocation: "instabox" } : { ok: true, value, workloadLocation: "instabox" };
9358
+ return JSON.stringify(payload);
9359
+ }
9397
9360
  throw new Error(
9398
- `instabox workload \u6682\u65E0\u6587\u4EF6\u5DE5\u5177 bridge\uFF08\u4EC5\u652F\u6301 execShell \u8FDC\u7A0B\u547D\u4EE4\uFF09\uFF1B\u5DE5\u5177 "${toolName}" \u62D2\u7EDD\u5728\u5BBF\u4E3B\u6267\u884C\u3002`
9361
+ `instabox workload \u6682\u4E0D\u652F\u6301\u5DE5\u5177 "${toolName}"\uFF08\u672C\u5757\u53EA\u6865\u63A5 readFile/writeFile/editFile/globFiles\uFF09\uFF1B\u62D2\u7EDD\u5728\u5BBF\u4E3B\u6267\u884C\u3002`
9399
9362
  );
9400
9363
  };
9401
9364
  return {
9402
9365
  backendId: LOCAL_INSTABOX_BACKEND_ID,
9403
9366
  runId: args.runId,
9404
9367
  channel,
9368
+ workspaceRoot: bridge.root,
9369
+ fileBridge: bridge,
9405
9370
  release
9406
9371
  };
9407
9372
  }
@@ -9608,12 +9573,12 @@ function parseExecShellChannelOutput(raw) {
9608
9573
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
9609
9574
  return { stdout: text, exitCode: 0, ...isTruncated(text) ? { truncated: true } : {} };
9610
9575
  }
9611
- const record3 = parsed;
9612
- const output = record3.output && typeof record3.output === "object" ? record3.output : void 0;
9613
- const stdout = firstString(output?.stdout, record3.stdout, record3.output, record3.content) ?? "";
9614
- const truncated = record3.truncated === true || output?.truncated === true || isTruncated(stdout) || isTruncated(firstString(output?.stderr, record3.stderr) ?? "");
9615
- const explicitFailure = record3.ok === false || typeof record3.error === "string";
9616
- const rawExit = record3.exitCode ?? record3.exit_code;
9576
+ const record = parsed;
9577
+ const output = record.output && typeof record.output === "object" ? record.output : void 0;
9578
+ const stdout = firstString(output?.stdout, record.stdout, record.output, record.content) ?? "";
9579
+ const truncated = record.truncated === true || output?.truncated === true || isTruncated(stdout) || isTruncated(firstString(output?.stderr, record.stderr) ?? "");
9580
+ const explicitFailure = record.ok === false || typeof record.error === "string";
9581
+ const rawExit = record.exitCode ?? record.exit_code;
9617
9582
  const exitCode = typeof rawExit === "number" ? rawExit : explicitFailure ? 1 : 0;
9618
9583
  if (explicitFailure && stdout.trim() === "") return { stdout: "", exitCode: exitCode === 0 ? 1 : exitCode, ...truncated ? { truncated: true } : {} };
9619
9584
  return { stdout, exitCode, ...truncated ? { truncated: true } : {} };
@@ -9661,9 +9626,9 @@ async function exportRunDiffArtifact(args) {
9661
9626
  return null;
9662
9627
  }
9663
9628
  if (args.writeAudit) {
9664
- const record3 = { runId: args.runId, kind: "diff", key, ref };
9629
+ const record = { runId: args.runId, kind: "diff", key, ref };
9665
9630
  try {
9666
- await args.writeAudit(record3);
9631
+ await args.writeAudit(record);
9667
9632
  } catch (error) {
9668
9633
  warn(`run \u7EC8\u6001\u5BFC\u51FA\u5BA1\u8BA1\u5199\u5165\u5931\u8D25\uFF08\u4E0D\u5F71\u54CD run \u7ED3\u679C\uFF09\uFF1A${describeError2(error)}`);
9669
9634
  }
@@ -9740,8 +9705,8 @@ async function exportRunWorktreeDiffArtifacts(args) {
9740
9705
  }
9741
9706
  return summary;
9742
9707
  }
9743
- function serializeRunArtifactAudit(record3) {
9744
- return `${JSON.stringify(record3, null, 2)}
9708
+ function serializeRunArtifactAudit(record) {
9709
+ return `${JSON.stringify(record, null, 2)}
9745
9710
  `;
9746
9711
  }
9747
9712
 
@@ -10306,9 +10271,9 @@ async function writeLocalTokenRecord(args) {
10306
10271
  function extractLastProviderInputTokens(input) {
10307
10272
  if (input.usageRecords && input.usageRecords.length > 0) {
10308
10273
  for (let i = input.usageRecords.length - 1; i >= 0; i--) {
10309
- const record3 = input.usageRecords[i];
10310
- if (!record3?.usage) continue;
10311
- const normalized = normalizeUsage(record3.usage);
10274
+ const record = input.usageRecords[i];
10275
+ if (!record?.usage) continue;
10276
+ const normalized = normalizeUsage(record.usage);
10312
10277
  if (normalized.input_tokens > 0) {
10313
10278
  return normalized.input_tokens;
10314
10279
  }
@@ -10491,21 +10456,21 @@ function resolveCliDialogRecordKey(userId, dialogId) {
10491
10456
  }
10492
10457
  async function loadCliDialogSummary(args) {
10493
10458
  const dialogKey = resolveCliDialogRecordKey(args.userId, args.dialogId);
10494
- const record3 = await args.store.read(dialogKey);
10495
- if (!record3 || typeof record3 !== "object") return null;
10496
- const summary = typeof record3.summary === "string" ? record3.summary.trim() : "";
10459
+ const record = await args.store.read(dialogKey);
10460
+ if (!record || typeof record !== "object") return null;
10461
+ const summary = typeof record.summary === "string" ? record.summary.trim() : "";
10497
10462
  if (!summary) return null;
10498
- const summarizedBeforeId = record3.summarizedBeforeId;
10499
- const sourceHash = record3.sourceHash;
10500
- const sourceCount = record3.sourceCount;
10501
- const schemaVersion = record3.schemaVersion;
10463
+ const summarizedBeforeId = record.summarizedBeforeId;
10464
+ const sourceHash = record.sourceHash;
10465
+ const sourceCount = record.sourceCount;
10466
+ const schemaVersion = record.schemaVersion;
10502
10467
  return {
10503
10468
  summary,
10504
10469
  ...typeof summarizedBeforeId === "string" && summarizedBeforeId ? { summarizedBeforeId } : {},
10505
10470
  ...typeof sourceHash === "string" && sourceHash ? { sourceHash } : {},
10506
10471
  ...typeof sourceCount === "number" && sourceCount > 0 ? { sourceCount } : {},
10507
- ..."schemaVersion" in record3 ? { schemaVersion } : {},
10508
- ...Array.isArray(record3.referenceKeys) ? { referenceKeys: record3.referenceKeys.filter((key) => typeof key === "string") } : {}
10472
+ ..."schemaVersion" in record ? { schemaVersion } : {},
10473
+ ...Array.isArray(record.referenceKeys) ? { referenceKeys: record.referenceKeys.filter((key) => typeof key === "string") } : {}
10509
10474
  };
10510
10475
  }
10511
10476
  async function saveCliDialogSummary(args) {
@@ -10534,9 +10499,9 @@ async function saveCliDialogSummary(args) {
10534
10499
  }
10535
10500
  async function loadCliDialogLastContextUsage(args) {
10536
10501
  const dialogKey = resolveCliDialogRecordKey(args.userId, args.dialogId);
10537
- const record3 = await args.store.read(dialogKey, { remote: false });
10538
- if (!record3 || typeof record3 !== "object") return null;
10539
- const lastInputTokens = record3.lastInputTokens;
10502
+ const record = await args.store.read(dialogKey, { remote: false });
10503
+ if (!record || typeof record !== "object") return null;
10504
+ const lastInputTokens = record.lastInputTokens;
10540
10505
  if (typeof lastInputTokens === "number" && Number.isFinite(lastInputTokens) && lastInputTokens > 0) {
10541
10506
  return { inputTokens: lastInputTokens };
10542
10507
  }
@@ -10553,6 +10518,36 @@ function parseTitleUpdatedAtMs(existingDialog) {
10553
10518
  }
10554
10519
 
10555
10520
  // packages/cli/client/localRuntimeAdapter.ts
10521
+ var LOCAL_INSTABOX_TOOL_NAMES = [
10522
+ EXECUTION_SHELL_TOOL,
10523
+ ...INSTABOX_FILE_TOOL_NAMES
10524
+ ];
10525
+ function resolveLocalInstaboxToolRoute(args) {
10526
+ const toolName = normalizeLocalToolName(args.toolName);
10527
+ if (!LOCAL_INSTABOX_TOOL_NAMES.includes(toolName)) {
10528
+ return WORKSPACE_TOOL_NAMES.includes(toolName) ? {
10529
+ action: "reject",
10530
+ toolName,
10531
+ reason: `instabox workload \u4E0D\u652F\u6301\u5DE5\u4F5C\u533A\u5DE5\u5177 "${toolName}"\uFF08instabox \u5DE5\u5177\u9762\uFF1A${LOCAL_INSTABOX_TOOL_NAMES.join(", ")}\uFF09\uFF1B\u62D2\u7EDD\u56DE\u843D\u5230\u5BBF\u4E3B\u6267\u884C`
10532
+ } : { action: "passthrough", toolName };
10533
+ }
10534
+ const agentToolNames = (args.agentToolNames ?? []).map(
10535
+ normalizeLocalToolName
10536
+ );
10537
+ const deniedBySurfaceOrPolicy = !agentToolNames.includes(toolName) || !resolveLocalToolPolicy({
10538
+ env: args.env ?? {},
10539
+ agentToolNames,
10540
+ toolName
10541
+ }).allowed;
10542
+ if (deniedBySurfaceOrPolicy) {
10543
+ return {
10544
+ action: "reject",
10545
+ toolName,
10546
+ reason: `${toolName} is outside the run tool surface / policy \u2014 instabox workload \u4E0D\u662F\u7ED5\u8FC7 deny \u7684\u901A\u9053\uFF1B\u62D2\u7EDD\u5728\u5BBF\u4E3B\u6267\u884C\u5DE5\u4F5C\u533A\u5DE5\u5177`
10547
+ };
10548
+ }
10549
+ return { action: "intercept", toolName };
10550
+ }
10556
10551
  var currentMetaFile = fileURLToPath(import.meta.url);
10557
10552
  var isJsBundle = extname(currentMetaFile) === ".js";
10558
10553
  var SOURCE_CLI_DIR = isJsBundle ? dirname4(currentMetaFile) : dirname4(dirname4(currentMetaFile));
@@ -10592,13 +10587,13 @@ async function recordLocalAvailabilityForAgent(args) {
10592
10587
  );
10593
10588
  return typeof entry?.nextAvailableAt === "number" ? entry.nextAvailableAt : action.nextAvailableAt;
10594
10589
  }
10595
- const record3 = current;
10596
- if (action.kind === "clear" && !("nextAvailableAt" in record3)) return void 0;
10597
- const next = { ...record3 };
10590
+ const record = current;
10591
+ if (action.kind === "clear" && !("nextAvailableAt" in record)) return void 0;
10592
+ const next = { ...record };
10598
10593
  let effectiveNextAvailableAt;
10599
10594
  if (action.kind === "mark") {
10600
10595
  const merged = mergeAvailabilityDeadline(
10601
- record3.nextAvailableAt,
10596
+ record.nextAvailableAt,
10602
10597
  action.nextAvailableAt
10603
10598
  );
10604
10599
  next.nextAvailableAt = merged;
@@ -10640,13 +10635,13 @@ function createCliLocalRuntimeAdapter(deps) {
10640
10635
  const additionalToolNames = deps.pastedTextStore ? ["readPastedText"] : [];
10641
10636
  const resolveAgentCredentialGroup = async (agentRef) => {
10642
10637
  try {
10643
- const record3 = await readAgentFromStore({
10638
+ const record = await readAgentFromStore({
10644
10639
  agentRef,
10645
10640
  store: await getOrCreateSharedStore(deps),
10646
10641
  userId
10647
10642
  });
10648
- if (!record3 || typeof record3 !== "object") return void 0;
10649
- const rec = record3;
10643
+ if (!record || typeof record !== "object") return void 0;
10644
+ const rec = record;
10650
10645
  const existing = typeof rec.credentialGroup === "string" && rec.credentialGroup.trim() ? rec.credentialGroup.trim() : void 0;
10651
10646
  if (existing) return existing;
10652
10647
  const ref = typeof rec.apiKeyRef === "string" && rec.apiKeyRef.trim() ? rec.apiKeyRef : typeof rec.credentialRef === "string" && rec.credentialRef.trim() ? rec.credentialRef : void 0;
@@ -10660,13 +10655,13 @@ function createCliLocalRuntimeAdapter(deps) {
10660
10655
  };
10661
10656
  const resolveAgentDisplayName = async (agentRef) => {
10662
10657
  try {
10663
- const record3 = await readAgentFromStore({
10658
+ const record = await readAgentFromStore({
10664
10659
  agentRef,
10665
10660
  store: await getOrCreateSharedStore(deps),
10666
10661
  userId
10667
10662
  });
10668
- if (!record3 || typeof record3 !== "object") return void 0;
10669
- const name = record3.name;
10663
+ if (!record || typeof record !== "object") return void 0;
10664
+ const name = record.name;
10670
10665
  return typeof name === "string" && name.trim() ? name.trim() : void 0;
10671
10666
  } catch {
10672
10667
  return void 0;
@@ -10674,12 +10669,12 @@ function createCliLocalRuntimeAdapter(deps) {
10674
10669
  };
10675
10670
  const resolveAgentRuntimeBindingMachineId = async (agentRef) => {
10676
10671
  try {
10677
- const record3 = await readAgentFromStore({
10672
+ const record = await readAgentFromStore({
10678
10673
  agentRef,
10679
10674
  store: await getOrCreateSharedStore(deps),
10680
10675
  userId
10681
10676
  });
10682
- const rec = record3;
10677
+ const rec = record;
10683
10678
  const binding = asRecordOrEmpty(rec?.runtimeBinding);
10684
10679
  return asOptionalTrimmedString(binding.machineId);
10685
10680
  } catch {
@@ -10723,16 +10718,24 @@ function createCliLocalRuntimeAdapter(deps) {
10723
10718
  authenticatedCaller: resolveLocalUserId(deps.env),
10724
10719
  agentKey: "cli-local-run",
10725
10720
  env: deps.env,
10726
- workspaceRoot
10721
+ workspaceRoot,
10722
+ ...deps.dockerWorkspaceMode ? { workspaceMode: deps.dockerWorkspaceMode } : {}
10727
10723
  }))();
10728
10724
  return dockerWorkloadLoad;
10729
10725
  };
10730
10726
  const instaboxRuntimeEnabled = runtimeKey === "instabox";
10731
10727
  let instaboxWorkloadLoad = null;
10732
10728
  let instaboxWorkloadReleased = false;
10729
+ let instaboxReleasePending = false;
10730
+ let instaboxReleasePromise = null;
10733
10731
  const createInstaboxWorkload = deps.createLocalInstaboxWorkload ?? createLocalInstaboxWorkload;
10734
10732
  const loadLocalInstaboxWorkload = () => {
10735
10733
  if (!instaboxRuntimeEnabled) return Promise.resolve(null);
10734
+ if (instaboxReleasePending) {
10735
+ return Promise.reject(
10736
+ new Error("instabox workload cleanup_pending\uFF1Alease cleanup \u5C1A\u672A\u786E\u8BA4\uFF0C\u62D2\u7EDD\u6267\u884C\u5DE5\u5177")
10737
+ );
10738
+ }
10736
10739
  if (instaboxWorkloadReleased) {
10737
10740
  return Promise.reject(
10738
10741
  new Error(
@@ -10759,7 +10762,7 @@ function createCliLocalRuntimeAdapter(deps) {
10759
10762
  const recordRunExecutionIsolation = async () => {
10760
10763
  try {
10761
10764
  const { writeFileSync: writeFileSync4, mkdirSync: mkdirSync4 } = await import("node:fs");
10762
- const { resolveRunsDir } = await import("./agentRunControl-IFM7IGMG.js");
10765
+ const { resolveRunsDir } = await import("./agentRunControl-2C5GM3BW.js");
10763
10766
  const fact = resolveLocalRunExecutionIsolationFact({
10764
10767
  // F1:显式点名宿主执行的 run 在审计里必须与 docker 沙盒区分开
10765
10768
  // (reason: host-explicit-writes vs docker-workload)。
@@ -10791,7 +10794,7 @@ function createCliLocalRuntimeAdapter(deps) {
10791
10794
  dockerWorkloadReleased = true;
10792
10795
  dockerWorkloadLoad = null;
10793
10796
  if (loaded) {
10794
- const { resolveRunsDir } = await import("./agentRunControl-IFM7IGMG.js");
10797
+ const { resolveRunsDir } = await import("./agentRunControl-2C5GM3BW.js");
10795
10798
  const exportRunDiff = deps.exportDockerRunDiffArtifact ?? exportDockerRunDiffArtifact;
10796
10799
  const warn = (message) => process.stderr.write(`[nolo] ${message}
10797
10800
  `);
@@ -10814,13 +10817,34 @@ function createCliLocalRuntimeAdapter(deps) {
10814
10817
  const loadLocalSandboxWorkload = () => localSandboxLoad ??= createSandboxWorkload({ workspaceRoot }).catch(
10815
10818
  () => null
10816
10819
  );
10817
- const releaseLocalInstaboxWorkload = async () => {
10818
- const loaded = instaboxWorkloadLoad ? await instaboxWorkloadLoad.catch(() => null) : null;
10819
- instaboxWorkloadReleased = true;
10820
- instaboxWorkloadLoad = null;
10821
- if (loaded) {
10822
- await loaded.release().catch(() => void 0);
10823
- }
10820
+ const releaseLocalInstaboxWorkload = () => {
10821
+ if (instaboxReleasePromise) return instaboxReleasePromise;
10822
+ const attempt = (async () => {
10823
+ const loaded = instaboxWorkloadLoad ? await instaboxWorkloadLoad.catch(() => null) : null;
10824
+ if (!loaded) {
10825
+ instaboxWorkloadReleased = true;
10826
+ instaboxWorkloadLoad = null;
10827
+ return;
10828
+ }
10829
+ try {
10830
+ await loaded.release();
10831
+ instaboxWorkloadReleased = true;
10832
+ instaboxReleasePending = false;
10833
+ instaboxWorkloadLoad = null;
10834
+ } catch (error) {
10835
+ instaboxReleasePending = true;
10836
+ const record = error;
10837
+ const code = record?.code === "instabox_cleanup_pending" || record?.cleanupPending === true ? "cleanup_pending" : "release_failed";
10838
+ process.stderr.write(`[nolo] instabox_release_${code}
10839
+ `);
10840
+ throw error;
10841
+ }
10842
+ })();
10843
+ instaboxReleasePromise = attempt;
10844
+ void attempt.finally(() => {
10845
+ if (instaboxReleasePromise === attempt) instaboxReleasePromise = null;
10846
+ }).catch(() => void 0);
10847
+ return attempt;
10824
10848
  };
10825
10849
  const releaseLocalSandboxWorkload = async () => {
10826
10850
  await releaseLocalDockerWorkload();
@@ -11297,18 +11321,30 @@ function createCliLocalRuntimeAdapter(deps) {
11297
11321
  }
11298
11322
  }
11299
11323
  if (instaboxRuntimeEnabled) {
11300
- const instaboxHandle = await loadLocalInstaboxWorkload();
11301
- if (instaboxHandle) {
11302
- const instaboxToolName = normalizeLocalToolName(call.name);
11324
+ const instaboxRoute = resolveLocalInstaboxToolRoute({
11325
+ toolName: call.name,
11326
+ env: deps.env,
11327
+ agentToolNames: activeAgentToolNames
11328
+ });
11329
+ if (instaboxRoute.action === "reject") {
11330
+ throw new Error(instaboxRoute.reason);
11331
+ }
11332
+ if (instaboxRoute.action === "intercept") {
11333
+ const instaboxHandle = await loadLocalInstaboxWorkload();
11334
+ if (!instaboxHandle) {
11335
+ throw new Error(
11336
+ `instabox workload \u4E0D\u53EF\u7528\uFF08\u65E0 handle\uFF09\uFF1A\u62D2\u7EDD\u5728\u5BBF\u4E3B\u6267\u884C\u5DE5\u4F5C\u533A\u5DE5\u5177 "${instaboxRoute.toolName}"`
11337
+ );
11338
+ }
11303
11339
  const instaboxArgs = parseToolArgumentsObject(injectedCall.arguments) ?? {};
11304
11340
  const instaboxOutput = await instaboxHandle.channel(
11305
- instaboxToolName,
11341
+ instaboxRoute.toolName,
11306
11342
  instaboxArgs,
11307
11343
  opts?.abortSignal
11308
11344
  );
11309
11345
  if (typeof instaboxOutput !== "string") {
11310
11346
  throw new Error(
11311
- `instabox workload \u672A\u8FD4\u56DE\u7ED3\u679C\uFF08tool=${instaboxToolName}\uFF09\uFF1A\u62D2\u7EDD\u56DE\u843D\u5230\u5BBF\u4E3B\u6267\u884C`
11347
+ `instabox workload \u672A\u8FD4\u56DE\u7ED3\u679C\uFF08tool=${instaboxRoute.toolName}\uFF09\uFF1A\u62D2\u7EDD\u56DE\u843D\u5230\u5BBF\u4E3B\u6267\u884C`
11312
11348
  );
11313
11349
  }
11314
11350
  return { content: instaboxOutput };
@@ -11506,6 +11542,7 @@ export {
11506
11542
  loadCliDialogSummary,
11507
11543
  saveCliDialogSummary,
11508
11544
  loadCliDialogLastContextUsage,
11545
+ resolveLocalInstaboxToolRoute,
11509
11546
  recordLocalAvailabilityForAgent,
11510
11547
  setCliAutoCompactionSummaryFallback,
11511
11548
  getCliAutoCompactionSummaryFallback,