nolo-cli 0.211.0 → 0.213.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/{_executeModel-VVQEOY3D.js → _executeModel-CUJLCFWR.js} +57 -54
  2. package/{action-U235TV4P.js → action-DF5UYSJF.js} +4 -4
  3. package/{addContentAction-7C76J7ST.js → addContentAction-WERAONNY.js} +9 -9
  4. package/{addDialogAgentAction-KTYANUEC.js → addDialogAgentAction-7VI7YRML.js} +16 -13
  5. package/{agentDeleteCommand-WHRU6VDJ.js → agentDeleteCommand-XJORXPGU.js} +80 -76
  6. package/{agentEmailCommands-ALLHXPW3.js → agentEmailCommands-XTYYFR6Z.js} +85 -80
  7. package/{agentListCommands-POKMEKMS.js → agentListCommands-OBLRBLHS.js} +237 -115
  8. package/{agentMachineCommands-WJLZLBPI.js → agentMachineCommands-5FMT3OT5.js} +33 -31
  9. package/{agentProviderCommands-MN3ABDME.js → agentProviderCommands-Q5O33MED.js} +33 -4
  10. package/{agentRecordCommands-OULZW3KM.js → agentRecordCommands-ZQ7SVYGG.js} +75 -70
  11. package/{agentRunCommand-ZNG4LGNQ.js → agentRunCommand-WS7IGO2W.js} +77 -73
  12. package/{agentRunControl-AF7BMR22.js → agentRunControl-TAMHJQSR.js} +8 -7
  13. package/{agentRuntimeLocal-YMUHFV5M.js → agentRuntimeLocal-SOO2OPJG.js} +30 -27
  14. package/{agentSlice-WNGUIMQZ.js → agentSlice-CHR6KOZN.js} +13 -13
  15. package/{appDeleteCommands-6MXPLAVF.js → appDeleteCommands-GUP6P5YE.js} +34 -32
  16. package/{appDeployCommands-ERRSVASW.js → appDeployCommands-MH2FX4O5.js} +34 -32
  17. package/{appDeployStatusCommands-ULICISLI.js → appDeployStatusCommands-SUHN3HPJ.js} +34 -32
  18. package/{appGetCommands-WYYYWROF.js → appGetCommands-YWDEX6Z4.js} +34 -32
  19. package/{appListCommands-DFCUCRCV.js → appListCommands-ZQVMLPAY.js} +34 -32
  20. package/{authCommand-ZJMWXFMA.js → authCommand-PWX2ZNUP.js} +15 -15
  21. package/{authCommands-WK6E42L2.js → authCommands-HV3EAU3V.js} +2 -2
  22. package/{builtinSkillRegistry-HH75G5J3.js → builtinSkillRegistry-2QETTQPM.js} +5 -4
  23. package/{chromeOpsCommands-HEN5AX2J.js → chromeOpsCommands-DIVM2K3T.js} +1 -1
  24. package/{chunk-TRZP7JZ7.js → chunk-2QHFH3DR.js} +1 -0
  25. package/{chunk-XE4Q46FF.js → chunk-3CGG2PAL.js} +1 -1
  26. package/{chunk-YUXQAVRD.js → chunk-3UKL3HPD.js} +251 -14
  27. package/{chunk-BSISWVB4.js → chunk-4I7ERB7F.js} +1 -1
  28. package/{chunk-5ORJGHTL.js → chunk-4T2WNOY7.js} +6 -6
  29. package/{chunk-W5VC7F7V.js → chunk-5MQRBSMW.js} +84 -91
  30. package/{chunk-YLTLB5A7.js → chunk-6DWMYIUY.js} +7 -6
  31. package/chunk-6VLJ6YA7.js +11751 -0
  32. package/{chunk-KSTEXKL6.js → chunk-75XIDFBW.js} +4 -3
  33. package/{chunk-BTYQAODF.js → chunk-7BT37FK3.js} +196 -308
  34. package/{chunk-27E2CBBY.js → chunk-7OCO4TDT.js} +1 -1
  35. package/{chunk-V3M6IXQI.js → chunk-7QTZCMKL.js} +335 -131
  36. package/chunk-7RFNTILS.js +2213 -0
  37. package/{chunk-NHQKWPLP.js → chunk-7Y4YTDQF.js} +25 -23
  38. package/{chunk-CKAHAVMK.js → chunk-A7TFUNZO.js} +35 -25
  39. package/{chunk-PJNFNEJE.js → chunk-ALQ3657A.js} +28 -2
  40. package/{chunk-NV572QM3.js → chunk-BBJ22CLB.js} +15 -15
  41. package/chunk-CJEIOP3E.js +0 -0
  42. package/{chunk-4WCEC56C.js → chunk-COFEN36Z.js} +2 -2
  43. package/{chunk-25OB36GU.js → chunk-CRHOO2ZR.js} +4 -4
  44. package/{chunk-NTSRCTUX.js → chunk-CTPXME7U.js} +2 -2
  45. package/{chunk-TPCDYNJK.js → chunk-EHGEOAHI.js} +3 -3
  46. package/{chunk-Y2WUYX4I.js → chunk-EHSZD5OI.js} +1 -1
  47. package/{chunk-SU3QL7YG.js → chunk-FUGMREBO.js} +2 -2
  48. package/{chunk-UMEGDH6A.js → chunk-FW6YHHLI.js} +8 -8
  49. package/chunk-FY7F4Q6X.js +127 -0
  50. package/{chunk-25M2K6OA.js → chunk-G2BQWAVT.js} +3 -3
  51. package/chunk-G7MLNNEX.js +84 -0
  52. package/{chunk-DQLB4NQ3.js → chunk-GPVRUGGY.js} +2 -2
  53. package/{chunk-RQ22OZD7.js → chunk-H2TJUNCH.js} +1 -1
  54. package/{chunk-XPHZK3PJ.js → chunk-H4UOTUOX.js} +165 -51
  55. package/{chunk-CVCRAO6Q.js → chunk-H5HF7TJA.js} +9 -7
  56. package/{chunk-OP7PTBAJ.js → chunk-H7PPIYWP.js} +9 -9
  57. package/{chunk-QQM464AL.js → chunk-HPFCI4SK.js} +3 -3
  58. package/chunk-HRMJUN5J.js +26 -0
  59. package/{chunk-WI6OGHXJ.js → chunk-HSVBJRF4.js} +5 -5
  60. package/{chunk-RYWO5AKN.js → chunk-HUBHAQK2.js} +10 -10
  61. package/{chunk-LKDF3ATR.js → chunk-INUFILG6.js} +1 -1
  62. package/{chunk-NXCGNS4N.js → chunk-IXNGOHV5.js} +2 -2
  63. package/{chunk-ET2CWLIJ.js → chunk-J2NHJ7WX.js} +4 -4
  64. package/{chunk-ECX3NKRD.js → chunk-JY5NGFFH.js} +11 -0
  65. package/chunk-KC4XDTT3.js +227 -0
  66. package/{chunk-ADBWFYJD.js → chunk-KFLT5KAD.js} +9 -9
  67. package/{chunk-PLYWH7XM.js → chunk-KIM6CLW5.js} +7 -7
  68. package/{chunk-7IYBN7IA.js → chunk-LLRPJECG.js} +22 -13
  69. package/{chunk-3J3U3KXB.js → chunk-MDB67IWP.js} +5 -5
  70. package/chunk-MMA3LZ3W.js +105 -0
  71. package/{chunk-XDMGY5IU.js → chunk-MOIJOHA5.js} +227 -11
  72. package/{chunk-NLT32XBZ.js → chunk-NJLL224W.js} +2 -2
  73. package/{chunk-JBOUVTZX.js → chunk-NOKUNJON.js} +15 -4
  74. package/{chunk-C2XZM3K4.js → chunk-NSAPDIN2.js} +12 -27
  75. package/{chunk-PAFTGNWA.js → chunk-O2TZF4AI.js} +2 -2
  76. package/{chunk-UIOEHFF6.js → chunk-OQHIVPG4.js} +1 -0
  77. package/{chunk-TCTSYFDM.js → chunk-OQPKUBPB.js} +19 -6
  78. package/{chunk-X4F26D5K.js → chunk-P5L7CXOC.js} +58 -33
  79. package/{chunk-OXME3PEE.js → chunk-PCLE46CE.js} +1 -1
  80. package/{chunk-UCPAVEQB.js → chunk-PYRUW7XN.js} +1 -1
  81. package/{chunk-YXOBCDNW.js → chunk-QG4AOSON.js} +12 -49
  82. package/{chunk-RXCCWVA2.js → chunk-QHPRUL4O.js} +3 -3
  83. package/{chunk-I5PBXF7O.js → chunk-R5O4QAWG.js} +1 -1
  84. package/{chunk-HD3WR3TD.js → chunk-RLBNLZVC.js} +1 -1
  85. package/{chunk-SN5XE6GQ.js → chunk-RPQXPZZF.js} +4 -4
  86. package/{chunk-ZOO3WJIE.js → chunk-RSHTSUEG.js} +948 -108
  87. package/{chunk-6HVBI6TI.js → chunk-RZOV7OMV.js} +12 -229
  88. package/{chunk-D2MDMY2M.js → chunk-SVYO6AO7.js} +7 -1
  89. package/{chunk-IIHY4ZAI.js → chunk-TAKB25RM.js} +8 -4
  90. package/{chunk-ZN5AH4BY.js → chunk-TX5EYMGT.js} +6 -6
  91. package/{chunk-CKOO42G5.js → chunk-UHJGXRJ4.js} +4 -4
  92. package/{chunk-M4NTDZG3.js → chunk-UYD5HQ6T.js} +857 -295
  93. package/{chunk-WTKYP6QO.js → chunk-V5Y3R6BT.js} +114 -6
  94. package/{chunk-3RQVYR4B.js → chunk-VNYYOX3V.js} +59 -20
  95. package/{chunk-4LEGTOSR.js → chunk-VO4WSAVP.js} +3 -3
  96. package/{chunk-LNYHAKBP.js → chunk-W4S457LU.js} +1 -1
  97. package/{chunk-RIALQUSF.js → chunk-WMTBPBMP.js} +6 -6
  98. package/chunk-WPORQFYN.js +74 -0
  99. package/{chunk-Y6M7KJOA.js → chunk-WRYQ35LQ.js} +5 -5
  100. package/{chunk-YKFP6UGT.js → chunk-WYDI6TGM.js} +17 -17
  101. package/{chunk-SCYQJPGA.js → chunk-X7SDOJUM.js} +147 -20
  102. package/chunk-XFYFMTOM.js +92 -0
  103. package/{chunk-LT3EAHJY.js → chunk-XHQC4PXX.js} +65 -49
  104. package/{chunk-2WZXXAQD.js → chunk-YB3YZK56.js} +67 -1
  105. package/{chunk-JKW6LERJ.js → chunk-YJAFKXMU.js} +14 -14
  106. package/{chunk-GSQNH63I.js → chunk-YTF4WH7J.js} +3 -19
  107. package/{chunk-DA7CTWT4.js → chunk-YWSEPJ7C.js} +5 -5
  108. package/{chunk-3V2QMRNN.js → chunk-ZL5RAEEB.js} +3 -3
  109. package/{chunk-NEZGPBL7.js → chunk-ZNWI6OVT.js} +2 -2
  110. package/{chunk-MBS6CTZB.js → chunk-ZXOUUDCG.js} +266 -2014
  111. package/cliAgentConfigHelpers-WJBZQTLW.js +41 -0
  112. package/{commandRegistry-FI2IOQ3U.js → commandRegistry-W63CYRZJ.js} +91 -87
  113. package/{contentThunks-5LKNNDGY.js → contentThunks-U7PL5MQD.js} +27 -26
  114. package/{cooldownCommands-YXLWOXWR.js → cooldownCommands-TIGUHXTD.js} +3 -3
  115. package/{createAgentAutomationAction-TI4QG4CY.js → createAgentAutomationAction-OLBQDD6R.js} +27 -26
  116. package/{createDialogAction-TJ3JKLO4.js → createDialogAction-SVH6B3SB.js} +29 -28
  117. package/{createPageAction-GKXT6WEH.js → createPageAction-F4DIWZ2Z.js} +29 -28
  118. package/{dbSlice-LPMZ2DGJ.js → dbSlice-BVH2YZPQ.js} +8 -8
  119. package/{deleteFile-EPUQHKPA.js → deleteFile-5YOEKV4U.js} +4 -4
  120. package/{dialogCommands-IWPXIZ5P.js → dialogCommands-KHIEPY3M.js} +38 -36
  121. package/{dialogSlice-ZWNNS7GZ.js → dialogSlice-ZCTDV2PZ.js} +25 -24
  122. package/{dialogUsageCommand-ZCPPHPJ5.js → dialogUsageCommand-7KCPYGHG.js} +1 -1
  123. package/{docCreateCommands-HFSPKJSI.js → docCreateCommands-DPMZI7G5.js} +32 -30
  124. package/{docDeleteCommands-CRL62POH.js → docDeleteCommands-IRQQLUBT.js} +34 -33
  125. package/{docReadCommands-QOTOX3XW.js → docReadCommands-LK37XH6L.js} +32 -30
  126. package/{docStore-WYLRB7ED.js → docStore-V2KECILA.js} +11 -11
  127. package/{docUpdateCommands-7BMH4MCA.js → docUpdateCommands-O6T3HJHH.js} +32 -30
  128. package/{fetchMessages-YY4SATNR.js → fetchMessages-NR4KNQLO.js} +3 -3
  129. package/{getPricing-OQXBJ6VZ.js → getPricing-2MNMXEVG.js} +3 -3
  130. package/{handleSendMessageAction-P27YP2DQ.js → handleSendMessageAction-2PE25WM3.js} +49 -47
  131. package/hostCredentialCreate-S233UMAP.js +357 -0
  132. package/index.js +7 -7
  133. package/{keys-P4ZDOVJW.js → keys-BEGDOTRL.js} +3 -1
  134. package/{localDialogRead-5VCMQQZF.js → localDialogRead-7NNDVVF7.js} +1 -1
  135. package/{localRuntimeAdapter-GP6ZSSO3.js → localRuntimeAdapter-KY6WXNBR.js} +82 -75
  136. package/{machineCommands-6Z6H4BFX.js → machineCommands-Q6HA3IXF.js} +74 -69
  137. package/{machineWsRunDispatch-F2ZIXMYM.js → machineWsRunDispatch-WWJQ6WR3.js} +74 -69
  138. package/{memberThunks-YSEFJF47.js → memberThunks-7EDJADWU.js} +9 -9
  139. package/package.json +1 -1
  140. package/{projectArchive-PIGEOX3D.js → projectArchive-DRTDIMEV.js} +29 -28
  141. package/{providerPresetApply-ZYMLQA46.js → providerPresetApply-YXGV6NXB.js} +4 -4
  142. package/{providerRegistry-E34XWDLJ.js → providerRegistry-S6UL6UNA.js} +4 -4
  143. package/{read-DIIQBOOO.js → read-4V2RMG7N.js} +4 -4
  144. package/{readDocTool-HXYGOEA7.js → readDocTool-BH6ATGQO.js} +1 -1
  145. package/{readlineWorkspace-UG25G7KC.js → readlineWorkspace-2W4WRCOU.js} +437 -217
  146. package/{removeDialogAgentAction-ALJDUJ2E.js → removeDialogAgentAction-LYAZGNKW.js} +18 -15
  147. package/{runAgentClientLoop-IO5F7TCZ.js → runAgentClientLoop-J2VQBS2Z.js} +55 -52
  148. package/{runtimeDoctorCommands-PGAA47G5.js → runtimeDoctorCommands-QAI3MBKQ.js} +6 -6
  149. package/{secretCommands-ZCZ4KVET.js → secretCommands-LXDWOLZ6.js} +4 -4
  150. package/{setDialogExtraReferencesAction-O3SVMD5A.js → setDialogExtraReferencesAction-OCRPGPYH.js} +11 -11
  151. package/{setPrimaryDialogAgentAction-HE7RVFFF.js → setPrimaryDialogAgentAction-HFJDQIBU.js} +19 -16
  152. package/{settingThunks-BWWJQG4L.js → settingThunks-RAMHMTGM.js} +13 -12
  153. package/{spaceCommands-UAELIFEI.js → spaceCommands-KVJZVKVO.js} +32 -31
  154. package/{streamAgentChatTurn-VUKZQYJR.js → streamAgentChatTurn-GHBMJJ6S.js} +63 -60
  155. package/{switchDialogAgentAction-3VZS7SOS.js → switchDialogAgentAction-EBRMW3RA.js} +16 -13
  156. package/{tools-VRXJAVYI.js → tools-EWKCPKMS.js} +49 -46
  157. package/{tuiSummaryLlmCaller-TGCHZLSW.js → tuiSummaryLlmCaller-ALQYUUWB.js} +48 -19
  158. package/{updateCommands-Q6CYAEYJ.js → updateCommands-ZQYU6SCI.js} +5 -3
  159. package/{updateDialogTitleAction-MULWCJCW.js → updateDialogTitleAction-5GGMBTDF.js} +40 -72
  160. package/usageCommand-F4IPVMIZ.js +32 -0
  161. package/usageRebuildCommand-HAW2AD5N.js +626 -0
  162. package/{windowsSelfUpdate-XSQVF2GK.js → windowsSelfUpdate-257DV2T6.js} +2 -2
  163. package/{workloadLifecycle-4BEQHMSD.js → workloadLifecycle-4C42SVBD.js} +1 -0
  164. package/chunk-4LCOCOR5.js +0 -50
  165. package/chunk-7AUQ3WCW.js +0 -51
  166. package/chunk-ZRAU6T47.js +0 -56
  167. package/{agentFavoriteCommands-GAFEXKKP.js → agentFavoriteCommands-EDK743YA.js} +1 -1
  168. package/{agentGrantCommands-V5FOQKFD.js → agentGrantCommands-RQWK2TEV.js} +1 -1
  169. package/{agentPullCommand-2JMJP5BS.js → agentPullCommand-6EM3URVK.js} +1 -1
  170. package/{chunk-A2ZMIRLN.js → chunk-INN4LTAJ.js} +5 -5
  171. package/{chunk-PV6JJAUB.js → chunk-TCZHTTUU.js} +8 -8
  172. package/{chunk-AKE53VMW.js → chunk-ZCWRMUWT.js} +0 -0
  173. package/{tableCommands-D7WR4QSM.js → tableCommands-MP6VFSVT.js} +3 -3
@@ -1,8 +1,3 @@
1
- import {
2
- DEVIN_CONNECT_URL,
3
- parseSseDataLineJson,
4
- parseSseDataLineObject
5
- } from "./chunk-NTSRCTUX.js";
6
1
  import {
7
2
  applyChatCompletionDelta,
8
3
  applyResponsesToolEvent,
@@ -11,7 +6,12 @@ import {
11
6
  flushChatCompletionStream,
12
7
  providerHttpFailure,
13
8
  throwIfChatCompletionStreamFailed
14
- } from "./chunk-TCTSYFDM.js";
9
+ } from "./chunk-OQPKUBPB.js";
10
+ import {
11
+ DEVIN_CONNECT_URL,
12
+ parseSseDataLineJson,
13
+ parseSseDataLineObject
14
+ } from "./chunk-CTPXME7U.js";
15
15
  import {
16
16
  readSseFrames
17
17
  } from "./chunk-HNUWUO75.js";
@@ -29,7 +29,7 @@ import {
29
29
  import {
30
30
  hasImageInRuntimeMessages,
31
31
  stripImagePartsFromMessages
32
- } from "./chunk-LNYHAKBP.js";
32
+ } from "./chunk-W4S457LU.js";
33
33
  import {
34
34
  applyShapingCounts,
35
35
  attachProjectionFacts,
@@ -66,7 +66,7 @@ import {
66
66
  hashStablePrefixContent,
67
67
  resolveResponseGuidelines,
68
68
  resolveToolGuidedSections
69
- } from "./chunk-W5VC7F7V.js";
69
+ } from "./chunk-5MQRBSMW.js";
70
70
  import {
71
71
  classifyUnparsableToolArgs,
72
72
  collectStablePromptPrefix,
@@ -90,7 +90,7 @@ import {
90
90
  toOpenAiCompatibleMessages,
91
91
  toResponsesTools,
92
92
  transferDowngradedToolTurnOrigin
93
- } from "./chunk-CVCRAO6Q.js";
93
+ } from "./chunk-H5HF7TJA.js";
94
94
  import {
95
95
  TOOL_HAD_IMAGES,
96
96
  TOOL_IMAGES,
@@ -111,7 +111,6 @@ import {
111
111
  DEFAULT_SUBTASK_MAX_TOOL_CALLS,
112
112
  DEFAULT_SUBTASK_MAX_WALL_CLOCK_MS,
113
113
  NOLO_WORKSPACE_TOOL_NAMES,
114
- applyToolSurfaceConstraints,
115
114
  buildDialogReadEnvelope,
116
115
  buildNoloWorkspaceCommandArgs,
117
116
  buildNoloWorkspaceOpenAiTools,
@@ -123,16 +122,20 @@ import {
123
122
  parseNoloWorkspaceToolArguments,
124
123
  readTextStreamUpToChars,
125
124
  resolveNoloDialogInput
126
- } from "./chunk-6HVBI6TI.js";
125
+ } from "./chunk-RZOV7OMV.js";
126
+ import {
127
+ applyToolSurfaceConstraints
128
+ } from "./chunk-KC4XDTT3.js";
127
129
  import {
128
130
  clipToolText,
131
+ planContextUsage,
129
132
  resolveHistoricalToolContentCap,
130
133
  resolveToolOutputProfile
131
- } from "./chunk-2WZXXAQD.js";
134
+ } from "./chunk-YB3YZK56.js";
132
135
  import {
133
136
  resolveAgentImageInputSupport,
134
137
  resolveToolImagePolicy
135
- } from "./chunk-DA7CTWT4.js";
138
+ } from "./chunk-YWSEPJ7C.js";
136
139
  import {
137
140
  buildDialogFallbackTitleFromUserInput
138
141
  } from "./chunk-2MBTWINN.js";
@@ -147,25 +150,22 @@ import {
147
150
  resolveEmptyAssistantFallbackMessage,
148
151
  resolveEmptyAssistantOutcome,
149
152
  resolveTruncatedReasoningTailLog
150
- } from "./chunk-WTKYP6QO.js";
153
+ } from "./chunk-V5Y3R6BT.js";
151
154
  import {
152
155
  COMPACTION_SUMMARY_SCHEMA_VERSION,
153
156
  COMPACTION_SUMMARY_SYSTEM_PROMPT,
154
- TOOL_RESULT_TRUNCATE_CHARS,
157
+ buildBoundedCompactionRequest,
155
158
  buildCompactionMetricsFromPlan,
156
- buildCompactionUserContent,
157
- computeSummaryInputTokenCap,
158
159
  computeSummarySourceMetadata,
159
160
  formatCompactionMetricsLog,
160
- formatFileOperationsFromMessages,
161
- formatMessagesForSummaryWithTruncation,
161
+ getMessageTokenCount,
162
162
  getModelContextWindow,
163
163
  planCompression,
164
- planContextUsage,
165
164
  resolveCompressionTriggerRatio,
165
+ resolveEffectiveCompactionBudgets,
166
166
  sha256Hex,
167
167
  truncateToolOutputForContext
168
- } from "./chunk-BTYQAODF.js";
168
+ } from "./chunk-7BT37FK3.js";
169
169
  import {
170
170
  createProviderCallTimingTracker,
171
171
  finalizeProviderCallTiming,
@@ -176,6 +176,9 @@ import {
176
176
  import {
177
177
  clipCompactText
178
178
  } from "./chunk-5MMAK75Q.js";
179
+ import {
180
+ assertCredentialRef
181
+ } from "./chunk-OQHIVPG4.js";
179
182
  import {
180
183
  asRecordOrEmpty
181
184
  } from "./chunk-KX6YBIHG.js";
@@ -191,7 +194,7 @@ import {
191
194
  import {
192
195
  canonicalizeToolName,
193
196
  canonicalizeToolNames
194
- } from "./chunk-AKE53VMW.js";
197
+ } from "./chunk-ZCWRMUWT.js";
195
198
  import {
196
199
  buildInteractiveCommandBlockedResult,
197
200
  buildProcessTaskResultCapsule,
@@ -214,26 +217,29 @@ import {
214
217
  spillToolOutput,
215
218
  toProcessTaskView,
216
219
  truncateToolOutput
217
- } from "./chunk-XPHZK3PJ.js";
220
+ } from "./chunk-H4UOTUOX.js";
218
221
  import {
219
222
  estimateTokenCount
220
223
  } from "./chunk-PSCNXBYA.js";
221
- import {
222
- resolveNoloStateDir
223
- } from "./chunk-6UBGXX2W.js";
224
224
  import {
225
225
  buildProviderAuthHeaders,
226
226
  buildProviderExecutionPlan
227
- } from "./chunk-PV6JJAUB.js";
227
+ } from "./chunk-TCZHTTUU.js";
228
228
  import {
229
229
  toErrorMessage
230
230
  } from "./chunk-HNMXYYJR.js";
231
231
  import {
232
232
  isRecord
233
233
  } from "./chunk-KUG52IAP.js";
234
+ import {
235
+ asTrimmedLowercaseString
236
+ } from "./chunk-QSJ3HFEF.js";
234
237
  import {
235
238
  normalizeServerOrigin
236
239
  } from "./chunk-CF7PE763.js";
240
+ import {
241
+ resolveNoloStateDir
242
+ } from "./chunk-6UBGXX2W.js";
237
243
  import {
238
244
  dialogMessageKey,
239
245
  dialogMessageRange
@@ -250,9 +256,6 @@ import {
250
256
  import {
251
257
  asOptionalTrimmedString
252
258
  } from "./chunk-G3SUCT4W.js";
253
- import {
254
- asTrimmedLowercaseString
255
- } from "./chunk-QSJ3HFEF.js";
256
259
  import {
257
260
  __export
258
261
  } from "./chunk-4VNS5WPM.js";
@@ -13243,6 +13246,14 @@ var SECRET_PATTERNS = [
13243
13246
  placeholder: "[REDACTED:API_KEY]",
13244
13247
  regex: /\bsk-[a-zA-Z0-9_\-]{24,}\b/g
13245
13248
  },
13249
+ // 3b. BigModel / 智谱(GLM)API Key:32 位 hex + "." + 16 位字母数字
13250
+ // (2026-11 实证:这类 key 没有任何可辨识前缀,此前漏在清洗与入路隔离之外,
13251
+ // 用户贴进对话后明文直接进了 prompt / 历史 / 工具日志。)
13252
+ {
13253
+ kind: "BIGMODEL_KEY",
13254
+ placeholder: "[REDACTED:BIGMODEL_KEY]",
13255
+ regex: /\b[0-9a-fA-F]{32}\.[A-Za-z0-9]{16}\b/g
13256
+ },
13246
13257
  // 4. GitHub 访问令牌 (ghp_..., gho_..., github_pat_...)
13247
13258
  {
13248
13259
  kind: "GITHUB_TOKEN",
@@ -13278,9 +13289,11 @@ var QUICK_PROBE_SUBSTRINGS = [
13278
13289
  "PASSWD",
13279
13290
  "SECRET_KEY"
13280
13291
  ];
13292
+ var UNPREFIXED_PROBE_REGEX = /\b[0-9a-fA-F]{32}\.[A-Za-z0-9]{16}\b/;
13281
13293
  function hasPotentialSecrets(text2) {
13282
13294
  if (typeof text2 !== "string" || text2.length === 0) return false;
13283
- return QUICK_PROBE_SUBSTRINGS.some((probe) => text2.includes(probe));
13295
+ if (QUICK_PROBE_SUBSTRINGS.some((probe) => text2.includes(probe))) return true;
13296
+ return UNPREFIXED_PROBE_REGEX.test(text2);
13284
13297
  }
13285
13298
  function scrubSecrets(text2) {
13286
13299
  if (typeof text2 !== "string" || text2.length === 0) {
@@ -14481,41 +14494,86 @@ function buildDestructiveShellBlockedError(reason, request3) {
14481
14494
  error.permissionRequest = request3;
14482
14495
  return error;
14483
14496
  }
14497
+ var KEY_SHAPED_VALUE = /(?:^|[\s"'=])(?:sk-ant-[A-Za-z0-9_\-]{20,}|sk-[A-Za-z0-9_\-]{24,}|gh[pousr]_[A-Za-z0-9]{30,}|github_pat_[A-Za-z0-9_]{40,}|[0-9a-fA-F]{32}\.[A-Za-z0-9]{16})(?=$|[\s"'])/;
14498
+ var CREDENTIAL_REF_IN_TEXT = /(?:vault-cred-[A-Za-z0-9]+|\$nolo_cred:)/;
14499
+ function inspectCommandCredentialUse(command) {
14500
+ const text2 = typeof command === "string" ? command : "";
14501
+ if (!text2) return { hasCredential: false, hasRawSecret: false };
14502
+ const hasRef = CREDENTIAL_REF_IN_TEXT.test(text2);
14503
+ const hasRawSecret = KEY_SHAPED_VALUE.test(text2);
14504
+ return { hasCredential: hasRef || hasRawSecret, hasRawSecret };
14505
+ }
14506
+ function buildCredentialUsePermissionRequest(command) {
14507
+ return {
14508
+ id: "permission-shell-credential-use",
14509
+ tool: "execShell",
14510
+ action: "shell_command_credential_use",
14511
+ title: "\u786E\u8BA4\u5728\u547D\u4EE4\u4E2D\u4F7F\u7528\u51ED\u636E",
14512
+ body: "\u8BE5\u547D\u4EE4\u5F15\u7528\u4E86\u51ED\u636E\uFF08API key \u6216 vault \u5F15\u7528\uFF09\u3002\u786E\u8BA4\u540E\u7531\u672C\u673A\u53D7\u63A7\u901A\u9053\u53D6\u7528\uFF1B\u660E\u6587\u4E0D\u4F1A\u5199\u8FDB\u547D\u4EE4\u5386\u53F2\u6216\u8BB0\u5F55\u3002",
14513
+ ...command ? { command } : {},
14514
+ suggestedRule: {
14515
+ scope: "once",
14516
+ pattern: { capability: "credential_use", target: "shell_command" }
14517
+ }
14518
+ };
14519
+ }
14520
+ function buildCredentialUseBlockedError(reason, command) {
14521
+ const error = buildDestructiveShellBlockedError(
14522
+ reason,
14523
+ buildCredentialUsePermissionRequest(command)
14524
+ );
14525
+ error.code = "credential_use_requires_confirmation";
14526
+ return error;
14527
+ }
14484
14528
  async function evaluateExecShellDestructiveGuard(input, ctx) {
14485
14529
  const guardEnabled = ctx.enableDestructiveShellGuard !== false;
14486
14530
  if (!guardEnabled || ctx.confirmed) {
14487
- return;
14531
+ return null;
14488
14532
  }
14489
14533
  const rawCommand = resolveShellCommandArg(
14490
14534
  typeof input === "object" && input !== null ? input : { command: input }
14491
14535
  );
14492
14536
  const extraInput = typeof input === "object" && input !== null ? input.input : void 0;
14493
- if (!isDestructiveShellCommand({ command: rawCommand, input: extraInput })) {
14494
- return;
14495
- }
14537
+ const destructive = isDestructiveShellCommand({ command: rawCommand, input: extraInput });
14496
14538
  const displayCommand = toDisplayCommand(rawCommand);
14497
- const request3 = buildDestructiveShellPermissionRequest(displayCommand);
14539
+ const credentialUse = inspectCommandCredentialUse(displayCommand).hasCredential || typeof extraInput === "string" && inspectCommandCredentialUse(extraInput).hasCredential;
14540
+ if (!destructive && !credentialUse) {
14541
+ return null;
14542
+ }
14543
+ const request3 = destructive ? buildDestructiveShellPermissionRequest(displayCommand) : buildCredentialUsePermissionRequest(displayCommand);
14498
14544
  if (!ctx.confirmDestructiveAction) {
14545
+ if (credentialUse) {
14546
+ throw buildCredentialUseBlockedError(
14547
+ "shell command carrying credentials blocked: no confirmation channel available",
14548
+ displayCommand
14549
+ );
14550
+ }
14499
14551
  if (ctx.blockDestructiveWithoutConfirmation) {
14500
14552
  throw buildDestructiveShellBlockedError(
14501
14553
  "destructive shell command blocked: no confirmation channel available",
14502
14554
  request3
14503
14555
  );
14504
14556
  }
14505
- return;
14557
+ return null;
14506
14558
  }
14507
- const confirmed = await ctx.confirmDestructiveAction(request3);
14508
- if (!confirmed) {
14559
+ const decision = await ctx.confirmDestructiveAction(request3);
14560
+ const approved = typeof decision === "boolean" ? decision : decision?.approved === true;
14561
+ if (!approved) {
14509
14562
  throw buildDestructiveShellBlockedError(
14510
14563
  "destructive shell command blocked: user declined confirmation",
14511
14564
  request3
14512
14565
  );
14513
14566
  }
14567
+ if (typeof decision === "object" && decision?.hostResult) {
14568
+ return decision.hostResult;
14569
+ }
14570
+ return null;
14514
14571
  }
14515
14572
  async function evaluateCapabilityPolicy(capability, normalizedInput, ctx) {
14516
14573
  if (capability.name === "execShell") {
14517
- await evaluateExecShellDestructiveGuard(normalizedInput, ctx);
14574
+ return await evaluateExecShellDestructiveGuard(normalizedInput, ctx);
14518
14575
  }
14576
+ return null;
14519
14577
  }
14520
14578
 
14521
14579
  // packages/agent-runtime/capabilities/execShellCapability.ts
@@ -14890,7 +14948,10 @@ async function invokeCapability(capabilityOrName, input, ctx = {}) {
14890
14948
  const binding = authority && capability.name === "execShell" ? execShellExecutionBinding(normalizedInput, ctx) : void 0;
14891
14949
  const signal = ctx.abortSignal;
14892
14950
  const confirm = ctx.confirmDestructiveAction;
14893
- await evaluateCapabilityPolicy(capability, normalizedInput, ctx);
14951
+ const hostExecutedResult = await evaluateCapabilityPolicy(capability, normalizedInput, ctx);
14952
+ if (hostExecutedResult) {
14953
+ return hostExecutedResult;
14954
+ }
14894
14955
  if (ctx.onInvoke) {
14895
14956
  await ctx.onInvoke(capability.name, normalizedInput);
14896
14957
  }
@@ -14974,14 +15035,14 @@ var configuredConcurrency = Number(process.env.NOLO_VISUAL_RENDERER_CONCURRENCY
14974
15035
  var renderSlots = new VisualRenderSemaphore(Number.isFinite(configuredConcurrency) ? Math.max(1, Math.min(2, Math.floor(configuredConcurrency))) : 2);
14975
15036
  var require2 = createRequire(import.meta.url);
14976
15037
  function visualRendererCapability() {
14977
- if (process.env.NOLO_VISUAL_RENDERER_DISABLED === "1") return { available: false, reason: "Platform renderer disabled by NOLO_VISUAL_RENDERER_DISABLED=1 on this runtime host." };
15038
+ if (process.env.NOLO_VISUAL_RENDERER_DISABLED === "1") return { available: false, reasonCode: "disabled", reason: "Platform renderer disabled by NOLO_VISUAL_RENDERER_DISABLED=1 on this runtime host." };
14978
15039
  try {
14979
15040
  const { chromium } = require2("playwright");
14980
15041
  const executablePath = [chromium.executablePath(), resolveExecutableOnPath("google-chrome"), resolveExecutableOnPath("chromium"), resolveExecutableOnPath("chromium-browser")].find((path) => !!path && existsSync(path));
14981
- if (!executablePath) return { available: false, reason: "No Chromium renderer installed. Install Playwright Chromium (playwright install chromium) or system Chromium/Google Chrome on the runtime host." };
15042
+ if (!executablePath) return { available: false, reasonCode: "missing-browser", reason: "No Chromium renderer installed. Install Playwright Chromium (playwright install chromium) or system Chromium/Google Chrome on the runtime host." };
14982
15043
  return { available: true, chromium, executablePath };
14983
15044
  } catch {
14984
- return { available: false, reason: "Platform renderer unavailable: install the platform Playwright dependency and Chromium on the runtime host (not a workspace npm script)." };
15045
+ return { available: false, reasonCode: "dependency-unavailable", reason: "Platform renderer unavailable: install the platform Playwright dependency and Chromium on the runtime host (not a workspace npm script)." };
14985
15046
  }
14986
15047
  }
14987
15048
  async function renderVisualPage(args2) {
@@ -15494,8 +15555,11 @@ function readProcessOwner(runtimeContext) {
15494
15555
  if (!dialogId) return null;
15495
15556
  const turnId = asNonEmptyString(runtimeContext.turnId);
15496
15557
  const ownerId = asNonEmptyString(runtimeContext.ownerId);
15558
+ const getDepth = runtimeContext.getProcessCausalDepth;
15559
+ const depth = typeof getDepth === "function" ? getDepth() : runtimeContext.processCausalDepth;
15497
15560
  return {
15498
15561
  dialogId,
15562
+ ...typeof depth === "number" && Number.isSafeInteger(depth) && depth >= 0 ? { processCausalDepth: depth } : {},
15499
15563
  ...turnId ? { turnId } : {},
15500
15564
  ...ownerId ? { ownerId } : {}
15501
15565
  };
@@ -18290,7 +18354,10 @@ async function runExecShellGates(args2) {
18290
18354
  parsedInput = { command: parsedInput };
18291
18355
  }
18292
18356
  }
18293
- await evaluateExecShellDestructiveGuard(parsedInput, opts);
18357
+ const hostExecutedResult = await evaluateExecShellDestructiveGuard(parsedInput, opts);
18358
+ if (hostExecutedResult) {
18359
+ return { kind: "handled", result: hostExecutedResult };
18360
+ }
18294
18361
  opts.confirmed = true;
18295
18362
  return { kind: "pass", opts };
18296
18363
  }
@@ -18569,7 +18636,10 @@ async function executeToolCall(args2) {
18569
18636
  `${toolName} confirmation`
18570
18637
  );
18571
18638
  const gateResult = replacement?.metadata?.actionGateResult;
18572
- if (replacement !== void 0 && isCompletedActionGateResult(gateResult)) {
18639
+ const hostExecuted = replacement?.metadata?.hostExecuted === true;
18640
+ if (replacement !== void 0 && hostExecuted) {
18641
+ toolResult = replacement;
18642
+ } else if (replacement !== void 0 && isCompletedActionGateResult(gateResult)) {
18573
18643
  writeSession.approved = true;
18574
18644
  } else {
18575
18645
  toolResult = replacement ?? {
@@ -18850,6 +18920,7 @@ function toPlanCompressionMessages(history) {
18850
18920
  id: typeof message.id === "string" && message.id.length > 0 ? message.id : `local-${index}`,
18851
18921
  role: message.role,
18852
18922
  content: message.content ?? "",
18923
+ ...typeof message.tool_call_id === "string" ? { tool_call_id: message.tool_call_id } : {},
18853
18924
  ...Array.isArray(message.tool_calls) ? { tool_calls: message.tool_calls } : {}
18854
18925
  }));
18855
18926
  }
@@ -18867,9 +18938,10 @@ function hashSummarySourceSlice(history, summarizedBeforeId) {
18867
18938
  const found = findSummaryAnchorIndex(bridged, summarizedBeforeId);
18868
18939
  if (found === -1) return void 0;
18869
18940
  const slice = bridged.slice(0, found + 1).map((message, index) => ({
18870
- ...message,
18871
18941
  id: `local-${index}`,
18872
- content: message.content ?? ""
18942
+ role: message.role,
18943
+ content: message.content ?? "",
18944
+ ...Array.isArray(message.tool_calls) ? { tool_calls: message.tool_calls } : {}
18873
18945
  }));
18874
18946
  return sha256Hex(JSON.stringify(slice));
18875
18947
  }
@@ -18907,22 +18979,22 @@ function projectHistoryWithSummary(args2) {
18907
18979
  if (found !== -1) startIndex = found + 1;
18908
18980
  }
18909
18981
  const projected = args2.history.slice(startIndex);
18910
- const summaryMsg = args2.summary.trim().length > 0 ? [buildLocalSummaryHistoryMessage(args2.summary)] : [];
18911
- return [...summaryMsg, ...projected];
18912
- }
18913
- var COLD_RESUME_IDLE_MS = 60 * 60 * 1e3;
18914
- function isColdResume(history, nowMs) {
18915
- for (let i = history.length - 1; i >= 0; i -= 1) {
18916
- const at = history[i]?.createdAt;
18917
- if (typeof at === "number" && Number.isFinite(at)) {
18918
- return nowMs - at > COLD_RESUME_IDLE_MS;
18982
+ let latestUser = -1;
18983
+ for (let i = args2.history.length - 1; i >= 0; i--) {
18984
+ if (args2.history[i].role === "user") {
18985
+ latestUser = i;
18986
+ break;
18919
18987
  }
18920
18988
  }
18921
- return false;
18989
+ const preservedUser = latestUser >= 0 && latestUser < startIndex ? [args2.history[latestUser]] : [];
18990
+ const summaryMsg = args2.summary.trim().length > 0 ? [buildLocalSummaryHistoryMessage(args2.summary)] : [];
18991
+ return [...summaryMsg, ...preservedUser, ...projected];
18922
18992
  }
18993
+ var COLD_RESUME_IDLE_MS = 60 * 60 * 1e3;
18923
18994
  async function runSummaryFallback(fallback, content, options) {
18924
18995
  try {
18925
18996
  const text2 = await fallback(content, options);
18997
+ if (text2 === null) return { summary: null, error: "no summary" };
18926
18998
  if (typeof text2 !== "string") return { summary: null, error: "non-string output" };
18927
18999
  const trimmed = text2.trim();
18928
19000
  return trimmed.length > 0 ? { summary: trimmed } : { summary: null, error: "empty summary" };
@@ -19017,13 +19089,12 @@ async function maybeAutoCompactLocalHistory(args2) {
19017
19089
  const planAnchorId = summarizedBeforeId && /^local-(0|[1-9]\d*)$/.test(summarizedBeforeId) && legacyAnchorIndex >= 0 ? bridged[legacyAnchorIndex].id : summarizedBeforeId;
19018
19090
  const contextWindow = typeof args2.contextWindow === "number" && Number.isFinite(args2.contextWindow) && args2.contextWindow > 0 ? args2.contextWindow : getModelContextWindow(args2.model ?? "");
19019
19091
  const allMsgs = toPlanCompressionMessages(history);
19020
- const coldResume = isColdResume(history, args2.now?.() ?? Date.now());
19021
19092
  const plan = planCompression({
19022
19093
  allMsgs,
19023
19094
  summarizedBeforeId: planAnchorId,
19024
19095
  summary: existingSummary,
19025
19096
  contextWindow,
19026
- ...coldResume ? { coldResume: true, reason: "cold_resume" } : {},
19097
+ preserveLatestUserByProjection: true,
19027
19098
  ...args2.realContextUsagePercent !== void 0 ? { realContextUsagePercent: args2.realContextUsagePercent } : {}
19028
19099
  });
19029
19100
  const projectExisting = () => {
@@ -19078,6 +19149,21 @@ async function maybeAutoCompactLocalHistory(args2) {
19078
19149
  }
19079
19150
  };
19080
19151
  }
19152
+ const msgsToCompress = plan.msgsToCompress;
19153
+ const bounded3 = buildBoundedCompactionRequest({
19154
+ msgsToCompress,
19155
+ previousSummary: existingSummary,
19156
+ contextWindow,
19157
+ canonicalizeToolName
19158
+ });
19159
+ if (bounded3.status === "blocked") {
19160
+ const detail = `bounded compaction blocked: ${bounded3.reason}`;
19161
+ console.warn(`[localLoop] ${detail}`);
19162
+ return {
19163
+ ...projectExisting(),
19164
+ decision: { outcome: "skipped", skipReason: "bounded-request-blocked", detail }
19165
+ };
19166
+ }
19081
19167
  emitPhase({ kind: "compaction-start" });
19082
19168
  const compactionAttemptId = randomUUID();
19083
19169
  let compactionT0 = Date.now();
@@ -19118,23 +19204,9 @@ async function maybeAutoCompactLocalHistory(args2) {
19118
19204
  if (args2.abortSignal?.aborted) {
19119
19205
  throw Object.assign(new Error("auto-compaction aborted"), { compactionReason: "aborted" });
19120
19206
  }
19121
- const msgsToCompress = plan.msgsToCompress;
19122
- const messagesText = formatMessagesForSummaryWithTruncation(
19123
- msgsToCompress,
19124
- TOOL_RESULT_TRUNCATE_CHARS,
19125
- computeSummaryInputTokenCap(contextWindow)
19126
- );
19127
- const fileOpsText = formatFileOperationsFromMessages(
19128
- msgsToCompress,
19129
- canonicalizeToolName
19130
- );
19131
- const promptContent = buildCompactionUserContent({
19132
- previousSummary: existingSummary,
19133
- messagesText,
19134
- fileOpsText
19135
- });
19207
+ const promptContent = bounded3.promptContent;
19136
19208
  emitPhase({ kind: "waiting-provider" });
19137
- compactionInputSource = messagesText;
19209
+ compactionInputSource = promptContent;
19138
19210
  compactionPrevSummarySource = existingSummary;
19139
19211
  compactionT0 = Date.now();
19140
19212
  const timeoutMs = typeof args2.timeoutMs === "number" && Number.isFinite(args2.timeoutMs) && args2.timeoutMs > 0 ? args2.timeoutMs : void 0;
@@ -19151,7 +19223,7 @@ async function maybeAutoCompactLocalHistory(args2) {
19151
19223
  // 服务端 x-request-id 可对上,用于关联请求级证据。不进 prompt/摘要/持久化。
19152
19224
  requestId: compactionAttemptId,
19153
19225
  // Room for factual handoff, exact commands and file operations.
19154
- max_tokens: 8192,
19226
+ max_tokens: bounded3.outputTokenBudget,
19155
19227
  reasoning_effort: "low"
19156
19228
  }
19157
19229
  ).then(
@@ -19195,7 +19267,8 @@ async function maybeAutoCompactLocalHistory(args2) {
19195
19267
  {
19196
19268
  signal: args2.abortSignal,
19197
19269
  deadlineMs: Date.now() + 3e4,
19198
- attemptId: compactionAttemptId
19270
+ attemptId: compactionAttemptId,
19271
+ maxOutputTokens: bounded3.outputTokenBudget
19199
19272
  }
19200
19273
  );
19201
19274
  fallbackElapsedMs = Date.now() - fallbackT0;
@@ -19243,15 +19316,69 @@ async function maybeAutoCompactLocalHistory(args2) {
19243
19316
  fallbackElapsedMs
19244
19317
  });
19245
19318
  }
19319
+ const metricsReason = invalidSummary ? "invalid_summary" : "context_budget";
19320
+ const metrics = buildCompactionMetricsFromPlan({
19321
+ reason: metricsReason,
19322
+ previousSummary: existingSummary,
19323
+ plan: {
19324
+ msgsToCompress: bounded3.coveredMessages,
19325
+ msgsToKeep: [...msgsToCompress.slice(bounded3.coveredMessages.length), ...plan.msgsToKeep]
19326
+ },
19327
+ newSummary,
19328
+ summaryUsage: result4?.usage
19329
+ });
19330
+ const projectedHistory = projectHistoryWithSummary({
19331
+ history,
19332
+ summary: newSummary,
19333
+ summarizedBeforeId: bounded3.summarizedBeforeId
19334
+ });
19335
+ const projectedMessages = toPlanCompressionMessages(projectedHistory);
19336
+ const projectedTokens = projectedMessages.reduce((sum2, message) => sum2 + getMessageTokenCount(message), 0);
19337
+ const projectedRetained = projectedMessages.slice(1);
19338
+ metrics.retainedTokens = projectedRetained.reduce((sum2, message) => sum2 + getMessageTokenCount(message), 0);
19339
+ metrics.retainedCount = projectedRetained.length;
19340
+ const { effectiveHistoryBudget } = resolveEffectiveCompactionBudgets({
19341
+ contextWindow,
19342
+ triggerRatio: plan.diagnostics.triggerRatio,
19343
+ historyBudget: plan.diagnostics.historyBudget,
19344
+ rawMessageBudget: plan.diagnostics.historyBudget,
19345
+ summaryTokens: 0
19346
+ });
19347
+ const withinSafetyBudget = projectedTokens <= effectiveHistoryBudget;
19348
+ if (!withinSafetyBudget) {
19349
+ console.warn("[localLoop] compaction projection remains above safety budget", {
19350
+ projectedTokens,
19351
+ effectiveHistoryBudget
19352
+ });
19353
+ }
19354
+ const oldProjection = projectExisting();
19355
+ const beforeProjectedTokens = toPlanCompressionMessages(oldProjection.history).reduce((sum2, message) => sum2 + getMessageTokenCount(message), 0);
19356
+ const historyBudget = plan.diagnostics.historyBudget;
19357
+ if (projectedTokens >= beforeProjectedTokens || projectedTokens >= historyBudget) {
19358
+ const failureMessage = `compaction candidate rejected: ${projectedTokens >= beforeProjectedTokens ? "no token reduction" : "above history budget"} (before=${beforeProjectedTokens}, after=${projectedTokens}, budget=${historyBudget})`;
19359
+ console.warn(`[localLoop] ${failureMessage}`);
19360
+ recordCompactionFailure(dialogId, args2.now?.() ?? Date.now());
19361
+ logCompactionTiming("empty", {});
19362
+ emitPhase({ kind: "compaction-end" });
19363
+ return {
19364
+ ...oldProjection,
19365
+ failureMessage,
19366
+ ...result4?.usage ? { usage: result4.usage } : {},
19367
+ decision: { outcome: "skipped", skipReason: "unsafe-projection", detail: failureMessage }
19368
+ };
19369
+ }
19246
19370
  const sourceMeta = await computeSummarySourceMetadata(
19247
19371
  toPlanCompressionMessages(history),
19248
- plan.newSummarizedBeforeId
19372
+ bounded3.summarizedBeforeId
19249
19373
  );
19374
+ if (args2.abortSignal?.aborted) {
19375
+ throw Object.assign(new Error("auto-compaction aborted"), { compactionReason: "aborted" });
19376
+ }
19250
19377
  const saveT0 = Date.now();
19251
19378
  await adapter.saveDialogSummary({
19252
19379
  dialogId,
19253
19380
  summary: newSummary,
19254
- summarizedBeforeId: plan.newSummarizedBeforeId,
19381
+ summarizedBeforeId: bounded3.summarizedBeforeId,
19255
19382
  // 内容寻址失效检测:存锚点切片哈希与长度,供下轮载入校验。
19256
19383
  sourceHash: sourceMeta?.sourceHash,
19257
19384
  sourceCount: sourceMeta?.sourceCount ?? 0,
@@ -19263,14 +19390,6 @@ async function maybeAutoCompactLocalHistory(args2) {
19263
19390
  )
19264
19391
  });
19265
19392
  saveElapsedMs = Date.now() - saveT0;
19266
- const metricsReason = invalidSummary ? "invalid_summary" : coldResume ? "cold_resume" : "context_budget";
19267
- const metrics = buildCompactionMetricsFromPlan({
19268
- reason: metricsReason,
19269
- previousSummary: existingSummary,
19270
- plan,
19271
- newSummary,
19272
- summaryUsage: result4?.usage
19273
- });
19274
19393
  console.log(formatCompactionMetricsLog(metrics));
19275
19394
  logCompactionTiming("success", {
19276
19395
  model: result4?.model ?? args2.model ?? null,
@@ -19278,21 +19397,18 @@ async function maybeAutoCompactLocalHistory(args2) {
19278
19397
  });
19279
19398
  emitPhase({ kind: "compaction-end" });
19280
19399
  return {
19281
- history: projectHistoryWithSummary({
19282
- history,
19283
- summary: newSummary,
19284
- summarizedBeforeId: plan.newSummarizedBeforeId
19285
- }),
19400
+ history: projectedHistory,
19286
19401
  compressed: true,
19287
19402
  summaryGenerated: true,
19288
19403
  reason: metricsReason,
19289
- beforeTokens: metrics.previousSummaryTokens + metrics.compressedTokens,
19290
- afterTokens: metrics.newSummaryTokens + metrics.retainedTokens,
19404
+ beforeTokens: beforeProjectedTokens,
19405
+ afterTokens: projectedTokens,
19406
+ withinSafetyBudget,
19291
19407
  ...result4?.usage ? { usage: result4.usage } : {},
19292
19408
  metrics,
19293
19409
  decision: {
19294
19410
  outcome: "compressed",
19295
- trigger: invalidSummary ? "invalid-summary" : coldResume ? "cold-resume" : plan.diagnostics?.triggeredByRealUsage ? "real-usage" : "estimate",
19411
+ trigger: invalidSummary ? "invalid-summary" : plan.diagnostics?.triggeredByRealUsage ? "real-usage" : "estimate",
19296
19412
  ...plan.diagnostics ? {
19297
19413
  estimatedTokens: plan.diagnostics.totalUsed,
19298
19414
  historyBudget: plan.diagnostics.historyBudget,
@@ -19330,7 +19446,7 @@ function emitCompactionPhaseEvent(boundary, phase, scope3) {
19330
19446
  function emitCompactionObservationEvent(boundary, compacted) {
19331
19447
  const decision = compacted.decision;
19332
19448
  if (decision?.outcome === "skipped") {
19333
- const isProtectionGap = decision.skipReason === "adapter-missing-summary-methods" || decision.skipReason === "load-summary-failed";
19449
+ const isProtectionGap = decision.skipReason === "bounded-request-blocked" || decision.skipReason === "unsafe-projection" || decision.skipReason === "adapter-missing-summary-methods" || decision.skipReason === "load-summary-failed";
19334
19450
  const approachingBudget = decision.skipReason === "below-trigger" && typeof decision.estimatedTokens === "number" && typeof decision.historyBudget === "number" && decision.historyBudget > 0 && decision.estimatedTokens >= decision.historyBudget * 0.5;
19335
19451
  if (!isProtectionGap && !approachingBudget) return;
19336
19452
  }
@@ -19338,10 +19454,11 @@ function emitCompactionObservationEvent(boundary, compacted) {
19338
19454
  kind: "compaction",
19339
19455
  atMs: Date.now(),
19340
19456
  ...compacted.reason ? { reason: compacted.reason } : {},
19457
+ ...compacted.withinSafetyBudget === false ? { detail: "Estimated projected history remains above the compaction safety budget" } : {},
19341
19458
  summaryGenerated: compacted.summaryGenerated,
19342
19459
  compressed: compacted.compressed,
19343
19460
  ...compacted.failureMessage ? { failed: true, detail: compacted.failureMessage } : {},
19344
- ...decision?.outcome === "skipped" ? { skipped: true, skipReason: decision.skipReason } : {},
19461
+ ...decision?.outcome === "skipped" ? { skipped: true, skipReason: decision.skipReason, ...decision.detail ? { detail: decision.detail } : {} } : {},
19345
19462
  ...decision && "trigger" in decision && decision.trigger ? { trigger: decision.trigger } : {},
19346
19463
  ...decision && "estimatedTokens" in decision && decision.estimatedTokens !== void 0 ? { estimatedTokens: decision.estimatedTokens } : {},
19347
19464
  ...decision && "historyBudget" in decision && decision.historyBudget !== void 0 ? { historyBudget: decision.historyBudget } : {},
@@ -19972,13 +20089,23 @@ async function runLocalAgentTurn(input) {
19972
20089
  }
19973
20090
  return resolvedProvider;
19974
20091
  };
20092
+ let resolvedSummaryProvider;
20093
+ const resolveSummaryProviderOnce = async () => {
20094
+ if (!resolvedSummaryProvider) {
20095
+ resolvedSummaryProvider = await input.adapter.resolveProvider(agentConfig, {
20096
+ toolNames: [],
20097
+ prompt: ""
20098
+ });
20099
+ }
20100
+ return resolvedSummaryProvider;
20101
+ };
19975
20102
  const contextWindow = resolveAgentContextWindow(agentConfig);
19976
20103
  const compressionTriggerRatio = resolveCompressionTriggerRatio(contextWindow);
19977
20104
  const compaction = createTurnCompactionController({
19978
20105
  adapter: input.adapter,
19979
20106
  continueDialogId: input.continueDialogId,
19980
20107
  model: agentConfig.model,
19981
- resolveProvider: resolveProviderOnce,
20108
+ resolveProvider: resolveSummaryProviderOnce,
19982
20109
  contextWindow,
19983
20110
  compressionTriggerRatio,
19984
20111
  abortSignal: input.abortSignal,
@@ -20115,6 +20242,7 @@ async function runLocalAgentTurn(input) {
20115
20242
  };
20116
20243
  const newDialogTelemetryKey = `new:${crypto.randomUUID()}`;
20117
20244
  let roundBudgetWarningInjected = false;
20245
+ let subtaskToolBudgetWarningInjected = false;
20118
20246
  const roundWarningThreshold = input.roundBudgetWarningThreshold ?? DEFAULT_ROUND_BUDGET_WARNING_THRESHOLD;
20119
20247
  while (true) {
20120
20248
  partialContent = "";
@@ -20126,6 +20254,10 @@ async function runLocalAgentTurn(input) {
20126
20254
  transcript.push({ role: "user", content: prompt });
20127
20255
  roundBudgetWarningInjected = true;
20128
20256
  }
20257
+ if (subtaskBudgetTracker && !subtaskToolBudgetWarningInjected && subtaskBudgetTracker.toolCallsExecuted > 0 && subtaskBudgetTracker.remainingToolCalls() > 0 && subtaskBudgetTracker.remainingToolCalls() <= Math.max(1, Math.ceil(subtaskBudgetTracker.limits.maxToolCalls * 0.1))) {
20258
+ transcript.push({ role: "user", content: `\u5B50\u4EFB\u52A1\u5DE5\u5177\u9884\u7B97\u5373\u5C06\u7528\u5C3D\uFF08\u5269\u4F59 ${subtaskBudgetTracker.remainingToolCalls()} \u6B21\uFF09\u3002\u8BF7\u4F18\u5148\u6536\u5C3E\u5E76\u7ED9\u51FA\u53EF\u8BFB\u7684\u9636\u6BB5\u7ED3\u679C\u3002` });
20259
+ subtaskToolBudgetWarningInjected = true;
20260
+ }
20129
20261
  const preparedMessages = prepareMessagesForProviderCall(transcript.working());
20130
20262
  if (!supportsImages && hasImageInRuntimeMessages(preparedMessages.messages) && !imageDowngradeEmitted) {
20131
20263
  emitLoopEvent(observationBoundary, {
@@ -20490,12 +20622,98 @@ ${reasoningTailLog}
20490
20622
  } catch (error) {
20491
20623
  loopError = error;
20492
20624
  }
20625
+ const finalBudgetExhaustion = budgetExhaustion;
20626
+ let budgetWrapupFailure;
20627
+ let budgetWrapupSucceeded = false;
20628
+ if (!loopError && finalBudgetExhaustion && subtaskBudgetTracker && finalBudgetExhaustion.limit === "max-tool-calls" && !input.abortSignal?.aborted && subtaskBudgetTracker.elapsedMs() < subtaskBudgetTracker.limits.maxWallClockMs) {
20629
+ const remainingMs = subtaskBudgetTracker.limits.maxWallClockMs - subtaskBudgetTracker.elapsedMs();
20630
+ const timeoutMs = Math.min(3e4, remainingMs);
20631
+ const controller = new AbortController();
20632
+ let rejectCancelled = () => {
20633
+ };
20634
+ const cancelled = new Promise((_, reject) => {
20635
+ rejectCancelled = reject;
20636
+ });
20637
+ const onAbort = () => {
20638
+ controller.abort();
20639
+ rejectCancelled(buildAbortedError());
20640
+ };
20641
+ input.abortSignal?.addEventListener("abort", onAbort, { once: true });
20642
+ if (input.abortSignal?.aborted) onAbort();
20643
+ let timer;
20644
+ let wrapRequestStarted = false;
20645
+ let wrapUsageCaptured = false;
20646
+ let wrapOutcomeReceived = false;
20647
+ try {
20648
+ const deadline = new Promise((_, reject) => {
20649
+ timer = setTimeout(() => {
20650
+ controller.abort();
20651
+ reject(new Error("budget wrap-up timed out"));
20652
+ }, timeoutMs);
20653
+ });
20654
+ const work = async () => {
20655
+ const wrapProvider = await input.adapter.resolveProvider(agentConfig, { toolNames: [], prompt: "", textOnly: true });
20656
+ if (!wrapProvider.textOnly) throw new Error(`host ${input.adapter.host} does not support isolated text-only provider`);
20657
+ if (controller.signal.aborted || input.abortSignal?.aborted || subtaskBudgetTracker.elapsedMs() >= subtaskBudgetTracker.limits.maxWallClockMs) throw new Error("budget wrap-up cancelled or deadline reached");
20658
+ const wrapMessages = [
20659
+ ...filterImagePartsFromMessages(prepareMessagesForProviderCall(transcript.working()).messages, supportsImages),
20660
+ { role: "user", content: "\u5DE5\u5177\u9884\u7B97\u5DF2\u8017\u5C3D\u3002\u4E0D\u8981\u8C03\u7528\u5DE5\u5177\uFF1B\u4EC5\u57FA\u4E8E\u5DF2\u5B8C\u6210\u5185\u5BB9\uFF0C\u7B80\u8FF0\u7ED3\u679C\u3001\u8BC1\u636E\u4E0E\u672A\u5B8C\u6210\u4E8B\u9879\u3002" }
20661
+ ];
20662
+ const startedAt = Date.now();
20663
+ const telemetry2 = buildRequestTelemetry({ dialogKey: input.continueDialogId || `budget:${crypto.randomUUID()}`, messages: wrapMessages, toolsHash: safeToolNamesHash([]) });
20664
+ wrapRequestStarted = true;
20665
+ const summary2 = await runCompleteWithTimeout({
20666
+ provider: wrapProvider,
20667
+ messages: wrapMessages,
20668
+ options: { max_tokens: 1024, noRetries: true, timeoutMs, signal: controller.signal, ...input.continueDialogId ? { dialogId: input.continueDialogId } : {} },
20669
+ timeoutMs,
20670
+ round,
20671
+ input,
20672
+ boundary: observationBoundary,
20673
+ providerName: agentConfig.provider,
20674
+ model: wrapProvider.model
20675
+ });
20676
+ return { summary: summary2, telemetry: finalizeCallTelemetry(telemetry2, summary2, round, startedAt) };
20677
+ };
20678
+ const { summary, telemetry } = await Promise.race([work(), deadline, cancelled]);
20679
+ wrapOutcomeReceived = true;
20680
+ usageLedger.recordProviderCall({ usage: summary.usage, model: summary.model, provider: summary.provider, telemetry });
20681
+ wrapUsageCaptured = Boolean(summary.usage);
20682
+ if (summary.tool_calls?.length || summary.output?.some((block) => block.type === "toolCall")) throw new Error("text-only provider returned a tool call");
20683
+ if (summary.error || typeof summary.content !== "string" || !summary.content.trim()) throw new Error("text-only provider returned no usable summary");
20684
+ if (input.abortSignal?.aborted) throw buildAbortedError();
20685
+ result4 = { ...result4, content: summary.content.trim().slice(0, 12e3) };
20686
+ budgetWrapupSucceeded = true;
20687
+ } catch (error) {
20688
+ if (input.abortSignal?.aborted) {
20689
+ const aborted = buildAbortedError();
20690
+ if (wrapRequestStarted && !wrapUsageCaptured) {
20691
+ aborted.message += "\uFF08\u65E0\u5DE5\u5177\u603B\u7ED3\u8BF7\u6C42\u53EF\u80FD\u5DF2\u8BA1\u8D39\uFF0C\u672A\u8FD4\u56DE\u7684\u7528\u91CF\u672A\u77E5\uFF09";
20692
+ aborted.usageUnavailable = true;
20693
+ }
20694
+ loopError = aborted;
20695
+ } else {
20696
+ const detail = error instanceof Error ? error.message : "unknown error";
20697
+ budgetWrapupFailure = scrubSecrets(detail).cleaned.slice(0, 300);
20698
+ if (wrapRequestStarted && !wrapOutcomeReceived) budgetWrapupFailure += "\uFF1B\u8BF7\u6C42\u53EF\u80FD\u5DF2\u8BA1\u8D39\uFF0C\u672A\u8FD4\u56DE\u7684\u7528\u91CF\u672A\u77E5";
20699
+ }
20700
+ } finally {
20701
+ if (timer) clearTimeout(timer);
20702
+ controller.abort();
20703
+ input.abortSignal?.removeEventListener("abort", onAbort);
20704
+ }
20705
+ }
20706
+ if (!loopError && input.abortSignal?.aborted) loopError = buildAbortedError();
20493
20707
  if (budgetExhaustion) {
20708
+ if (!budgetWrapupSucceeded && !budgetWrapupFailure) {
20709
+ budgetWrapupFailure = input.abortSignal?.aborted ? "\u7528\u6237\u5DF2\u53D6\u6D88" : "\u5899\u949F\u9884\u7B97\u5DF2\u8017\u5C3D\uFF0C\u672A\u53D1\u8D77\u603B\u7ED3\u8BF7\u6C42";
20710
+ }
20494
20711
  const previousContent = typeof result4?.content === "string" ? result4.content.trim() : "";
20495
20712
  result4 = {
20496
20713
  ...result4,
20497
20714
  content: [
20498
20715
  previousContent,
20716
+ ...budgetWrapupFailure ? [`\u65E0\u5DE5\u5177\u603B\u7ED3\u672A\u5B8C\u6210\uFF08${budgetWrapupFailure}\uFF09\uFF1B\u4EE5\u4E0B\u662F\u4FDD\u7559\u7684\u5DF2\u6709\u5185\u5BB9\u548C\u9884\u7B97\u72B6\u6001\u3002`] : [],
20499
20717
  buildSubtaskBudgetExhaustedContent({
20500
20718
  exhaustion: budgetExhaustion,
20501
20719
  roundsCompleted: round,
@@ -21141,7 +21359,7 @@ async function executeOpenAiCompatibleChatCompletion(args2) {
21141
21359
  terminalIfEnabled(isAbortError(error) ? "aborted" : "network-error");
21142
21360
  throw error;
21143
21361
  }
21144
- if (res.status === 401 && args2.resolveApiKey) {
21362
+ if (res.status === 401 && args2.resolveApiKey && !args2.noRetries) {
21145
21363
  const refreshed = await args2.resolveApiKey({ force: true });
21146
21364
  if (refreshed && refreshed !== apiKey) {
21147
21365
  diagnosticCall?.httpResult(diagnosticAttempt, {
@@ -21287,7 +21505,193 @@ async function resolveOpenAiCompatibleProviderConfig(args2) {
21287
21505
  };
21288
21506
  }
21289
21507
 
21508
+ // packages/agent-runtime/macOsKeychainCredentialBroker.ts
21509
+ import { spawn as spawn2 } from "node:child_process";
21510
+ var MACOS_KEYCHAIN_SERVICE_PREFIX = "nolo.credentials.keys";
21511
+ var MACOS_KEYCHAIN_ACCOUNT = "api-key";
21512
+ var SECURITY_ITEM_NOT_FOUND_EXIT = 44;
21513
+ var DEFAULT_SECURITY_BIN = "/usr/bin/security";
21514
+ function safeCredentialRef(ref) {
21515
+ try {
21516
+ return assertCredentialRef(ref);
21517
+ } catch {
21518
+ throw new Error("invalid_ref");
21519
+ }
21520
+ }
21521
+ function credentialRefToMacOsKeychainService(ref, servicePrefix = MACOS_KEYCHAIN_SERVICE_PREFIX) {
21522
+ const safe = safeCredentialRef(ref);
21523
+ const hex = Buffer.from(safe, "utf8").toString("hex");
21524
+ if (!hex) {
21525
+ throw new Error("invalid_ref");
21526
+ }
21527
+ return `${servicePrefix}.${hex}`;
21528
+ }
21529
+ function rethrowBrokerError(op, _error) {
21530
+ throw new Error(`credential_broker_${op}_failed`);
21531
+ }
21532
+ function createDefaultSecurityRunner(securityBin = DEFAULT_SECURITY_BIN) {
21533
+ return function defaultSecurityRunner(input) {
21534
+ return new Promise((resolve6) => {
21535
+ let settled = false;
21536
+ const finish = (result4) => {
21537
+ if (settled) return;
21538
+ settled = true;
21539
+ resolve6(result4);
21540
+ };
21541
+ let child;
21542
+ try {
21543
+ child = spawn2(securityBin, input.args, {
21544
+ stdio: ["pipe", "pipe", "pipe"]
21545
+ });
21546
+ } catch {
21547
+ finish({ exitCode: -1, stdout: "", stderr: "" });
21548
+ return;
21549
+ }
21550
+ let stdout = "";
21551
+ let stderr = "";
21552
+ child.stdout?.setEncoding("utf8");
21553
+ child.stderr?.setEncoding("utf8");
21554
+ child.stdout?.on("data", (chunk) => {
21555
+ stdout += chunk;
21556
+ });
21557
+ child.stderr?.on("data", (chunk) => {
21558
+ stderr += chunk;
21559
+ });
21560
+ child.on("error", () => {
21561
+ finish({ exitCode: -1, stdout: "", stderr: "" });
21562
+ });
21563
+ child.on("close", (code) => {
21564
+ finish({
21565
+ exitCode: typeof code === "number" ? code : -1,
21566
+ stdout,
21567
+ stderr
21568
+ });
21569
+ });
21570
+ if (input.stdin !== void 0) {
21571
+ child.stdin?.write(input.stdin);
21572
+ }
21573
+ child.stdin?.end();
21574
+ });
21575
+ };
21576
+ }
21577
+ function createMacOsKeychainCredentialBroker(options = {}) {
21578
+ const runner = options.runner ?? createDefaultSecurityRunner(options.securityBin);
21579
+ const servicePrefix = options.servicePrefix ?? MACOS_KEYCHAIN_SERVICE_PREFIX;
21580
+ const account = options.account ?? MACOS_KEYCHAIN_ACCOUNT;
21581
+ const serviceFor = (ref) => credentialRefToMacOsKeychainService(ref, servicePrefix);
21582
+ return {
21583
+ async get(ref) {
21584
+ const safeRef = safeCredentialRef(ref);
21585
+ const service4 = serviceFor(safeRef);
21586
+ let result4;
21587
+ try {
21588
+ result4 = await runner({
21589
+ args: [
21590
+ "find-generic-password",
21591
+ "-a",
21592
+ account,
21593
+ "-s",
21594
+ service4,
21595
+ "-w"
21596
+ ]
21597
+ });
21598
+ } catch (error) {
21599
+ rethrowBrokerError("get", error);
21600
+ }
21601
+ if (result4.exitCode === SECURITY_ITEM_NOT_FOUND_EXIT) {
21602
+ return null;
21603
+ }
21604
+ if (result4.exitCode !== 0) {
21605
+ rethrowBrokerError("get");
21606
+ }
21607
+ const secret = result4.stdout.replace(/\n$/, "");
21608
+ return secret.length > 0 ? secret : null;
21609
+ },
21610
+ async put(ref, secret) {
21611
+ const safeRef = safeCredentialRef(ref);
21612
+ const value = asTrimmedString(secret);
21613
+ if (!value) {
21614
+ throw new Error("Cannot store an empty credential secret.");
21615
+ }
21616
+ const service4 = serviceFor(safeRef);
21617
+ const stdin = `${value}
21618
+ ${value}
21619
+ `;
21620
+ let result4;
21621
+ try {
21622
+ result4 = await runner({
21623
+ args: [
21624
+ "add-generic-password",
21625
+ "-a",
21626
+ account,
21627
+ "-s",
21628
+ service4,
21629
+ "-U",
21630
+ "-w"
21631
+ ],
21632
+ stdin
21633
+ });
21634
+ } catch (error) {
21635
+ rethrowBrokerError("put", error);
21636
+ }
21637
+ if (result4.exitCode !== 0) {
21638
+ rethrowBrokerError("put");
21639
+ }
21640
+ },
21641
+ async delete(ref) {
21642
+ const safeRef = safeCredentialRef(ref);
21643
+ const service4 = serviceFor(safeRef);
21644
+ let result4;
21645
+ try {
21646
+ result4 = await runner({
21647
+ args: [
21648
+ "delete-generic-password",
21649
+ "-a",
21650
+ account,
21651
+ "-s",
21652
+ service4
21653
+ ]
21654
+ });
21655
+ } catch (error) {
21656
+ rethrowBrokerError("delete", error);
21657
+ }
21658
+ if (result4.exitCode === 0 || result4.exitCode === SECURITY_ITEM_NOT_FOUND_EXIT) {
21659
+ return;
21660
+ }
21661
+ rethrowBrokerError("delete");
21662
+ },
21663
+ async has(ref) {
21664
+ const safeRef = safeCredentialRef(ref);
21665
+ const service4 = serviceFor(safeRef);
21666
+ let result4;
21667
+ try {
21668
+ result4 = await runner({
21669
+ args: [
21670
+ "find-generic-password",
21671
+ "-a",
21672
+ account,
21673
+ "-s",
21674
+ service4
21675
+ ]
21676
+ });
21677
+ } catch (error) {
21678
+ rethrowBrokerError("has", error);
21679
+ }
21680
+ if (result4.exitCode === SECURITY_ITEM_NOT_FOUND_EXIT) {
21681
+ return false;
21682
+ }
21683
+ if (result4.exitCode !== 0) {
21684
+ rethrowBrokerError("has");
21685
+ }
21686
+ return true;
21687
+ }
21688
+ };
21689
+ }
21690
+
21290
21691
  // packages/agent-runtime/windowsCredentialManagerBroker.ts
21692
+ import { spawn as spawn3 } from "node:child_process";
21693
+ var WINDOWS_CREDENTIAL_TARGET_PREFIX = "nolo.credentials.keys";
21694
+ var WIN_ERROR_NOT_FOUND = 1168;
21291
21695
  var WINDOWS_CREDENTIAL_MANAGER_SCRIPT = `
21292
21696
  $ErrorActionPreference = 'Stop'
21293
21697
  try {
@@ -21410,6 +21814,419 @@ public class NoloCredNative {
21410
21814
  exit 1
21411
21815
  }
21412
21816
  `.trim();
21817
+ function safeCredentialRef2(ref) {
21818
+ try {
21819
+ return assertCredentialRef(ref);
21820
+ } catch {
21821
+ throw new Error("invalid_ref");
21822
+ }
21823
+ }
21824
+ function credentialRefToWindowsCredentialTarget(ref, targetPrefix = WINDOWS_CREDENTIAL_TARGET_PREFIX) {
21825
+ const safe = safeCredentialRef2(ref);
21826
+ const hex = Buffer.from(safe, "utf8").toString("hex");
21827
+ if (!hex) {
21828
+ throw new Error("invalid_ref");
21829
+ }
21830
+ return `${targetPrefix}.${hex}`;
21831
+ }
21832
+ function rethrowBrokerError2(op, _error) {
21833
+ throw new Error(`credential_broker_${op}_failed`);
21834
+ }
21835
+ function buildWindowsCredentialPowerShellArgs(script = WINDOWS_CREDENTIAL_MANAGER_SCRIPT) {
21836
+ const encoded = Buffer.from(script, "utf16le").toString("base64");
21837
+ return [
21838
+ "-NoProfile",
21839
+ "-NonInteractive",
21840
+ "-ExecutionPolicy",
21841
+ "Bypass",
21842
+ "-EncodedCommand",
21843
+ encoded
21844
+ ];
21845
+ }
21846
+ function requestStdin(payload) {
21847
+ return JSON.stringify(payload);
21848
+ }
21849
+ function parseGetSecretFromStdout(stdout) {
21850
+ const trimmed = asTrimmedString(stdout);
21851
+ if (!trimmed) {
21852
+ rethrowBrokerError2("get");
21853
+ }
21854
+ let parsed;
21855
+ try {
21856
+ parsed = JSON.parse(trimmed);
21857
+ } catch {
21858
+ rethrowBrokerError2("get");
21859
+ }
21860
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed) || typeof parsed.secret !== "string") {
21861
+ rethrowBrokerError2("get");
21862
+ }
21863
+ return parsed.secret;
21864
+ }
21865
+ function spawnShell(bin, args2, stdin) {
21866
+ return new Promise((resolve6) => {
21867
+ let settled = false;
21868
+ const finish = (result4) => {
21869
+ if (settled) return;
21870
+ settled = true;
21871
+ resolve6(result4);
21872
+ };
21873
+ let child;
21874
+ try {
21875
+ child = spawn3(bin, args2, {
21876
+ stdio: ["pipe", "pipe", "pipe"],
21877
+ windowsHide: true
21878
+ });
21879
+ } catch {
21880
+ finish({ exitCode: -1, stdout: "", stderr: "" });
21881
+ return;
21882
+ }
21883
+ let stdout = "";
21884
+ let stderr = "";
21885
+ child.stdout?.setEncoding("utf8");
21886
+ child.stderr?.setEncoding("utf8");
21887
+ child.stdout?.on("data", (chunk) => {
21888
+ stdout += chunk;
21889
+ });
21890
+ child.stderr?.on("data", (chunk) => {
21891
+ stderr += chunk;
21892
+ });
21893
+ child.on("error", () => {
21894
+ finish({ exitCode: -1, stdout: "", stderr: "" });
21895
+ });
21896
+ child.on("close", (code) => {
21897
+ finish({
21898
+ exitCode: typeof code === "number" ? code : -1,
21899
+ stdout,
21900
+ stderr
21901
+ });
21902
+ });
21903
+ if (stdin !== void 0) {
21904
+ child.stdin?.write(stdin);
21905
+ }
21906
+ child.stdin?.end();
21907
+ });
21908
+ }
21909
+ function createDefaultWindowsCredentialRunner(shellBin) {
21910
+ let resolvedBin = shellBin ?? null;
21911
+ return async function defaultWindowsCredentialRunner(input) {
21912
+ if (resolvedBin) {
21913
+ return spawnShell(resolvedBin, input.args, input.stdin);
21914
+ }
21915
+ const first = await spawnShell("powershell.exe", input.args, input.stdin);
21916
+ if (first.exitCode !== -1) {
21917
+ resolvedBin = "powershell.exe";
21918
+ return first;
21919
+ }
21920
+ const second = await spawnShell("pwsh", input.args, input.stdin);
21921
+ if (second.exitCode !== -1) {
21922
+ resolvedBin = "pwsh";
21923
+ }
21924
+ return second;
21925
+ };
21926
+ }
21927
+ function createWindowsCredentialManagerBroker(options = {}) {
21928
+ const runner = options.runner ?? createDefaultWindowsCredentialRunner(options.shellBin);
21929
+ const targetPrefix = options.targetPrefix ?? WINDOWS_CREDENTIAL_TARGET_PREFIX;
21930
+ const targetFor = (ref) => credentialRefToWindowsCredentialTarget(ref, targetPrefix);
21931
+ const staticArgs = buildWindowsCredentialPowerShellArgs();
21932
+ return {
21933
+ async get(ref) {
21934
+ const safeRef = safeCredentialRef2(ref);
21935
+ const target = targetFor(safeRef);
21936
+ let result4;
21937
+ try {
21938
+ result4 = await runner({
21939
+ args: staticArgs,
21940
+ stdin: requestStdin({ op: "get", target })
21941
+ });
21942
+ } catch (error) {
21943
+ rethrowBrokerError2("get", error);
21944
+ }
21945
+ if (result4.exitCode === WIN_ERROR_NOT_FOUND) {
21946
+ return null;
21947
+ }
21948
+ if (result4.exitCode !== 0) {
21949
+ rethrowBrokerError2("get");
21950
+ }
21951
+ const secret = parseGetSecretFromStdout(result4.stdout);
21952
+ return secret.length > 0 ? secret : null;
21953
+ },
21954
+ async put(ref, secret) {
21955
+ const safeRef = safeCredentialRef2(ref);
21956
+ const value = asTrimmedString(secret);
21957
+ if (!value) {
21958
+ throw new Error("Cannot store an empty credential secret.");
21959
+ }
21960
+ const target = targetFor(safeRef);
21961
+ let result4;
21962
+ try {
21963
+ result4 = await runner({
21964
+ args: staticArgs,
21965
+ stdin: requestStdin({ op: "put", target, secret: value })
21966
+ });
21967
+ } catch (error) {
21968
+ rethrowBrokerError2("put", error);
21969
+ }
21970
+ if (result4.exitCode !== 0) {
21971
+ rethrowBrokerError2("put");
21972
+ }
21973
+ },
21974
+ async delete(ref) {
21975
+ const safeRef = safeCredentialRef2(ref);
21976
+ const target = targetFor(safeRef);
21977
+ let result4;
21978
+ try {
21979
+ result4 = await runner({
21980
+ args: staticArgs,
21981
+ stdin: requestStdin({ op: "delete", target })
21982
+ });
21983
+ } catch (error) {
21984
+ rethrowBrokerError2("delete", error);
21985
+ }
21986
+ if (result4.exitCode === 0 || result4.exitCode === WIN_ERROR_NOT_FOUND) {
21987
+ return;
21988
+ }
21989
+ rethrowBrokerError2("delete");
21990
+ },
21991
+ async has(ref) {
21992
+ const safeRef = safeCredentialRef2(ref);
21993
+ const target = targetFor(safeRef);
21994
+ let result4;
21995
+ try {
21996
+ result4 = await runner({
21997
+ args: staticArgs,
21998
+ stdin: requestStdin({ op: "has", target })
21999
+ });
22000
+ } catch (error) {
22001
+ rethrowBrokerError2("has", error);
22002
+ }
22003
+ if (result4.exitCode === WIN_ERROR_NOT_FOUND) {
22004
+ return false;
22005
+ }
22006
+ if (result4.exitCode !== 0) {
22007
+ rethrowBrokerError2("has");
22008
+ }
22009
+ return true;
22010
+ }
22011
+ };
22012
+ }
22013
+
22014
+ // packages/agent-runtime/linuxSecretServiceCredentialBroker.ts
22015
+ import { spawn as spawn4 } from "node:child_process";
22016
+ var LINUX_SECRET_SERVICE_ATTRIBUTE = "nolo-credential";
22017
+ var SECRET_TOOL_NO_MATCH_EXIT = 1;
22018
+ var DEFAULT_SECRET_TOOL_BIN = "secret-tool";
22019
+ function safeCredentialRef3(ref) {
22020
+ try {
22021
+ return assertCredentialRef(ref);
22022
+ } catch {
22023
+ throw new Error("invalid_ref");
22024
+ }
22025
+ }
22026
+ function brokerFailure(op) {
22027
+ throw new Error(`credential_broker_${op}_failed`);
22028
+ }
22029
+ function createDefaultSecretToolRunner(secretToolBin = DEFAULT_SECRET_TOOL_BIN) {
22030
+ return (input) => new Promise((resolve6) => {
22031
+ let stdout = "";
22032
+ let stderr = "";
22033
+ let settled = false;
22034
+ const finish = (result4) => {
22035
+ if (settled) return;
22036
+ settled = true;
22037
+ resolve6(result4);
22038
+ };
22039
+ let child;
22040
+ try {
22041
+ child = spawn4(secretToolBin, input.args, {
22042
+ stdio: ["pipe", "pipe", "pipe"]
22043
+ });
22044
+ } catch {
22045
+ finish({ exitCode: -1, stdout: "", stderr: "" });
22046
+ return;
22047
+ }
22048
+ child.stdout?.on("data", (chunk) => {
22049
+ stdout += chunk;
22050
+ });
22051
+ child.stderr?.on("data", (chunk) => {
22052
+ stderr += chunk;
22053
+ });
22054
+ child.on("error", () => {
22055
+ finish({ exitCode: -1, stdout: "", stderr: "" });
22056
+ });
22057
+ child.on("close", (code) => {
22058
+ finish({
22059
+ exitCode: typeof code === "number" ? code : -1,
22060
+ stdout,
22061
+ stderr
22062
+ });
22063
+ });
22064
+ if (input.stdin !== void 0) {
22065
+ child.stdin?.write(input.stdin);
22066
+ }
22067
+ child.stdin?.end();
22068
+ });
22069
+ }
22070
+ function createLinuxSecretServiceCredentialBroker(options = {}) {
22071
+ const runner = options.runner ?? createDefaultSecretToolRunner(options.secretToolBin);
22072
+ const attribute = options.attribute ?? LINUX_SECRET_SERVICE_ATTRIBUTE;
22073
+ const attrArgs = (ref) => [attribute, ref];
22074
+ const lookup3 = async (ref) => {
22075
+ try {
22076
+ return await runner({ args: ["lookup", ...attrArgs(ref)] });
22077
+ } catch {
22078
+ brokerFailure("get");
22079
+ }
22080
+ };
22081
+ return {
22082
+ async get(ref) {
22083
+ const safeRef = safeCredentialRef3(ref);
22084
+ const result4 = await lookup3(safeRef);
22085
+ if (result4.exitCode === SECRET_TOOL_NO_MATCH_EXIT) return null;
22086
+ if (result4.exitCode !== 0) brokerFailure("get");
22087
+ const secret = result4.stdout.replace(/\n$/, "");
22088
+ return secret.length > 0 ? secret : null;
22089
+ },
22090
+ async put(ref, secret) {
22091
+ const safeRef = safeCredentialRef3(ref);
22092
+ const value = asTrimmedString(secret);
22093
+ if (!value) {
22094
+ throw new Error("Cannot store an empty credential secret.");
22095
+ }
22096
+ const args2 = [
22097
+ "store",
22098
+ `--label=nolo-credential:${safeRef}`,
22099
+ ...attrArgs(safeRef)
22100
+ ];
22101
+ if (value.includes("\n") || args2.some((arg) => arg.includes(value))) {
22102
+ brokerFailure("put");
22103
+ }
22104
+ let result4;
22105
+ try {
22106
+ result4 = await runner({ args: args2, stdin: value });
22107
+ } catch {
22108
+ brokerFailure("put");
22109
+ }
22110
+ if (result4.exitCode !== 0) brokerFailure("put");
22111
+ },
22112
+ async delete(ref) {
22113
+ const safeRef = safeCredentialRef3(ref);
22114
+ let result4;
22115
+ try {
22116
+ result4 = await runner({ args: ["clear", ...attrArgs(safeRef)] });
22117
+ } catch {
22118
+ brokerFailure("delete");
22119
+ }
22120
+ if (result4.exitCode === 0 || result4.exitCode === SECRET_TOOL_NO_MATCH_EXIT) {
22121
+ return;
22122
+ }
22123
+ brokerFailure("delete");
22124
+ },
22125
+ async has(ref) {
22126
+ const safeRef = safeCredentialRef3(ref);
22127
+ const result4 = await lookup3(safeRef);
22128
+ if (result4.exitCode === SECRET_TOOL_NO_MATCH_EXIT) return false;
22129
+ if (result4.exitCode !== 0) brokerFailure("has");
22130
+ return true;
22131
+ }
22132
+ };
22133
+ }
22134
+
22135
+ // packages/agent-runtime/desktopHostCredentialBroker.ts
22136
+ function createClosedCredentialBroker(code = "credential_store_unavailable") {
22137
+ const fail9 = () => {
22138
+ throw new Error(code);
22139
+ };
22140
+ return {
22141
+ get: fail9,
22142
+ put: fail9,
22143
+ delete: fail9,
22144
+ has: () => false
22145
+ };
22146
+ }
22147
+ function createHostCredentialBrokerChain(args2) {
22148
+ const { strict, session, legacy, notifySessionFallback, notifyLegacyHit } = args2;
22149
+ const legacyNoticed = /* @__PURE__ */ new Set();
22150
+ let sessionNotified = false;
22151
+ const noticeSession = () => {
22152
+ if (sessionNotified || !notifySessionFallback) return;
22153
+ sessionNotified = true;
22154
+ try {
22155
+ notifySessionFallback();
22156
+ } catch {
22157
+ }
22158
+ };
22159
+ return {
22160
+ async get(ref) {
22161
+ try {
22162
+ const strictValue = await strict.get(ref);
22163
+ if (strictValue !== null && strictValue !== void 0) return strictValue;
22164
+ } catch {
22165
+ }
22166
+ const sessionValue = await session.get(ref);
22167
+ if (sessionValue !== null && sessionValue !== void 0) return sessionValue;
22168
+ if (!legacy) return null;
22169
+ const legacyValue = await legacy.get(ref);
22170
+ if (legacyValue !== null && legacyValue !== void 0) {
22171
+ if (notifyLegacyHit && !legacyNoticed.has(ref)) {
22172
+ legacyNoticed.add(ref);
22173
+ try {
22174
+ notifyLegacyHit(ref);
22175
+ } catch {
22176
+ }
22177
+ }
22178
+ return legacyValue;
22179
+ }
22180
+ return null;
22181
+ },
22182
+ async put(ref, secret) {
22183
+ try {
22184
+ await strict.put(ref, secret);
22185
+ if (await strict.has(ref)) return;
22186
+ } catch {
22187
+ }
22188
+ await session.put(ref, secret);
22189
+ noticeSession();
22190
+ },
22191
+ async delete(ref) {
22192
+ try {
22193
+ await strict.delete(ref);
22194
+ } catch {
22195
+ }
22196
+ try {
22197
+ await session.delete(ref);
22198
+ } catch {
22199
+ }
22200
+ if (legacy) await legacy.delete(ref);
22201
+ },
22202
+ async has(ref) {
22203
+ try {
22204
+ if (await strict.has(ref)) return true;
22205
+ } catch {
22206
+ }
22207
+ if (await session.has(ref)) return true;
22208
+ return legacy ? await legacy.has(ref) : false;
22209
+ }
22210
+ };
22211
+ }
22212
+ function createStrictHostCredentialBroker(options = {}) {
22213
+ const platform = options.platform ?? process.platform;
22214
+ const env = options.env ?? process.env;
22215
+ const override = String(env.NOLO_DESKTOP_CREDENTIAL_STORE ?? "").trim().toLowerCase();
22216
+ if (override === "file") {
22217
+ return createClosedCredentialBroker("credential_store_file_not_allowed");
22218
+ }
22219
+ if (platform === "darwin" || override === "keychain") {
22220
+ return options.keychainBroker ?? (options.createKeychainBroker ?? (() => createMacOsKeychainCredentialBroker()))();
22221
+ }
22222
+ if (platform === "win32" || override === "credman") {
22223
+ return options.windowsCredentialBroker ?? (options.createWindowsCredentialBroker ?? (() => createWindowsCredentialManagerBroker()))();
22224
+ }
22225
+ if (platform === "linux" || override === "secret-service") {
22226
+ return options.linuxSecretServiceBroker ?? (options.createLinuxSecretServiceBroker ?? (() => createLinuxSecretServiceCredentialBroker()))();
22227
+ }
22228
+ return createClosedCredentialBroker("credential_store_unsupported");
22229
+ }
21413
22230
 
21414
22231
  // packages/agent-runtime/dialogMessageRecord.ts
21415
22232
  function dialogMessageRecordToAgentRuntimeMessage(record2) {
@@ -21767,9 +22584,23 @@ async function fetchHybridRemoteRecord(args2) {
21767
22584
  ...args2.signal ? { signal: args2.signal } : {}
21768
22585
  }
21769
22586
  );
21770
- if (!response.ok) return null;
21771
- const payload = await response.json().catch(() => null);
21772
- return normalizeHybridRecord(args2.dbKey, payload?.data ?? payload, args2.server);
22587
+ if (!response.ok) {
22588
+ if (response.status !== 404) args2.onUnavailable?.();
22589
+ return null;
22590
+ }
22591
+ let payload;
22592
+ try {
22593
+ payload = await response.json();
22594
+ } catch {
22595
+ args2.onUnavailable?.();
22596
+ return null;
22597
+ }
22598
+ const record2 = payload && typeof payload === "object" && "data" in payload ? payload.data : payload;
22599
+ if (record2 !== null && (!record2 || typeof record2 !== "object" || Array.isArray(record2))) {
22600
+ args2.onUnavailable?.();
22601
+ return null;
22602
+ }
22603
+ return normalizeHybridRecord(args2.dbKey, record2, args2.server);
21773
22604
  }
21774
22605
  function shouldCacheHybridRemoteRecord(remoteRecord, localRecord) {
21775
22606
  if (!remoteRecord || typeof remoteRecord !== "object") return false;
@@ -21798,7 +22629,10 @@ function createHybridRecordStore(deps) {
21798
22629
  deps.fallbackServers
21799
22630
  )) {
21800
22631
  const remainingMs = fallbackDeadlineMs === null ? null : fallbackDeadlineMs - Date.now();
21801
- if (remainingMs !== null && remainingMs <= 0) break;
22632
+ if (remainingMs !== null && remainingMs <= 0) {
22633
+ options?.onRemoteUnavailable?.();
22634
+ break;
22635
+ }
21802
22636
  let remoteRecord = null;
21803
22637
  try {
21804
22638
  remoteRecord = await fetchHybridRemoteRecord({
@@ -21806,9 +22640,11 @@ function createHybridRecordStore(deps) {
21806
22640
  server,
21807
22641
  authToken: deps.authToken,
21808
22642
  fetchImpl,
22643
+ onUnavailable: options?.onRemoteUnavailable,
21809
22644
  ...remainingMs !== null ? { signal: AbortSignal.timeout(remainingMs) } : {}
21810
22645
  });
21811
22646
  } catch {
22647
+ options?.onRemoteUnavailable?.();
21812
22648
  continue;
21813
22649
  }
21814
22650
  if (!remoteRecord) continue;
@@ -21861,11 +22697,11 @@ async function readNoloProcessStream(readable) {
21861
22697
  async function runNoloWorkspaceCliTool(call, args2) {
21862
22698
  const cliArgs = buildNoloWorkspaceCommandArgs(call);
21863
22699
  const bunSpawn = globalThis.Bun?.spawn;
21864
- const spawn2 = args2.spawn ?? (typeof bunSpawn === "function" ? bunSpawn : nodeSpawnFallback);
22700
+ const spawn5 = args2.spawn ?? (typeof bunSpawn === "function" ? bunSpawn : nodeSpawnFallback);
21865
22701
  const execPath = args2.processExecPath ?? process.execPath;
21866
22702
  const entrypoint = args2.cliEntrypoint;
21867
22703
  const cmd = entrypoint && entrypoint !== execPath ? [execPath, entrypoint, ...cliArgs] : [execPath, ...cliArgs];
21868
- const proc = spawn2({
22704
+ const proc = spawn5({
21869
22705
  cmd,
21870
22706
  stdout: "pipe",
21871
22707
  stderr: "pipe",
@@ -21980,7 +22816,7 @@ function buildLoadSkillExecutor(args2) {
21980
22816
  const { resolveSkillByName } = await import("./skillDiscovery-XKHROSH2.js");
21981
22817
  const resolved = resolveSkillByName(args2.cwd, name);
21982
22818
  if (!resolved) {
21983
- const { resolveBuiltinSkillByName } = await import("./builtinSkillRegistry-HH75G5J3.js");
22819
+ const { resolveBuiltinSkillByName } = await import("./builtinSkillRegistry-2QETTQPM.js");
21984
22820
  const builtin = resolveBuiltinSkillByName(name);
21985
22821
  if (builtin) {
21986
22822
  return {
@@ -22039,7 +22875,7 @@ async function loadPreciseSkill(cwd, parsed) {
22039
22875
  if (!nonEmpty(parsed.slug) || has2("projectBinding") || has2("relativePath")) {
22040
22876
  return reject("builtin requires only an exact slug.");
22041
22877
  }
22042
- const { listBuiltinSkills } = await import("./builtinSkillRegistry-HH75G5J3.js");
22878
+ const { listBuiltinSkills } = await import("./builtinSkillRegistry-2QETTQPM.js");
22043
22879
  const builtin = listBuiltinSkills().find((entry) => entry.slug === parsed.slug);
22044
22880
  if (!builtin) return reject("builtin slug not found.");
22045
22881
  return {
@@ -22742,16 +23578,20 @@ function verifyOwnerRouteAck(headers, expectedRequestId) {
22742
23578
  }
22743
23579
 
22744
23580
  export {
23581
+ createHostCredentialBrokerChain,
23582
+ createStrictHostCredentialBroker,
22745
23583
  readCommandActionGatePayload,
22746
23584
  readActionGate,
22747
23585
  Option_exports,
22748
23586
  Duration_exports,
22749
23587
  Exit_exports,
22750
23588
  Effect_exports,
23589
+ scrubSecrets,
22751
23590
  isDestructiveShellCommand,
22752
23591
  evaluateShellCommandPolicy,
22753
23592
  filterRetainedLedgerRecords,
22754
23593
  isLineRangeCovered,
23594
+ runTaskStop,
22755
23595
  WORKSPACE_TOOL_NAMES,
22756
23596
  buildLocalWorkspaceToolset,
22757
23597
  buildLocalWorkspacePolicyToolNames,