@bolloon/bolloon-agent 0.4.27 → 0.4.29

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 (443) hide show
  1. package/bin/bolloon.cjs +18 -148
  2. package/bin/bolloon.cmd +6 -3
  3. package/dist/agents/execution-supervisor.js +21 -0
  4. package/dist/agents/pi-sdk-tools.js +3 -1
  5. package/dist/agents/pi-sdk.js +4 -1
  6. package/dist/agents/task/local-seller.js +149 -0
  7. package/dist/agents/task/report-card.js +146 -0
  8. package/dist/agents/task/resource-advisor.js +182 -0
  9. package/dist/agents/task/task-budget.js +103 -0
  10. package/dist/agents/task/task-runner.js +618 -0
  11. package/dist/agents/x402/goal-run-bridge.js +10 -6
  12. package/dist/agents/x402/resource-contract.js +12 -1
  13. package/dist/cli/update-commands.js +349 -0
  14. package/dist/cli-entry.js +133 -53
  15. package/dist/electron-build/agents/agent-gateway.js +169 -0
  16. package/dist/electron-build/agents/agent-gateway.js.map +1 -0
  17. package/dist/electron-build/agents/agent-identity-store.js +212 -0
  18. package/dist/electron-build/agents/agent-identity-store.js.map +1 -0
  19. package/dist/electron-build/agents/agent-identity.js +196 -0
  20. package/dist/electron-build/agents/agent-identity.js.map +1 -0
  21. package/dist/electron-build/agents/agent-manifest-protocol.js +151 -0
  22. package/dist/electron-build/agents/agent-manifest-protocol.js.map +1 -0
  23. package/dist/electron-build/agents/agent-registry.js +217 -0
  24. package/dist/electron-build/agents/agent-registry.js.map +1 -0
  25. package/dist/electron-build/agents/agent-reputation.js +60 -0
  26. package/dist/electron-build/agents/agent-reputation.js.map +1 -0
  27. package/dist/electron-build/agents/agent-service-client.js +186 -0
  28. package/dist/electron-build/agents/agent-service-client.js.map +1 -0
  29. package/dist/electron-build/agents/browser-cdp.js +765 -0
  30. package/dist/electron-build/agents/browser-cdp.js.map +1 -0
  31. package/dist/electron-build/agents/computer-use.js +341 -0
  32. package/dist/electron-build/agents/computer-use.js.map +1 -0
  33. package/dist/electron-build/agents/constraint-layer.js +210 -0
  34. package/dist/electron-build/agents/constraint-layer.js.map +1 -0
  35. package/dist/electron-build/agents/decision-store.js +292 -0
  36. package/dist/electron-build/agents/decision-store.js.map +1 -0
  37. package/dist/electron-build/agents/deny-pipeline.js +125 -0
  38. package/dist/electron-build/agents/deny-pipeline.js.map +1 -0
  39. package/dist/electron-build/agents/economic-policy.js +172 -0
  40. package/dist/electron-build/agents/economic-policy.js.map +1 -0
  41. package/dist/electron-build/agents/error-classifier.js +125 -0
  42. package/dist/electron-build/agents/error-classifier.js.map +1 -0
  43. package/dist/electron-build/agents/execution-supervisor.js +539 -0
  44. package/dist/electron-build/agents/execution-supervisor.js.map +1 -0
  45. package/dist/electron-build/agents/external-events.js +171 -0
  46. package/dist/electron-build/agents/external-events.js.map +1 -0
  47. package/dist/electron-build/agents/gateway-join.js +315 -0
  48. package/dist/electron-build/agents/gateway-join.js.map +1 -0
  49. package/dist/electron-build/agents/gateway-network.js +505 -0
  50. package/dist/electron-build/agents/gateway-network.js.map +1 -0
  51. package/dist/electron-build/agents/goal-criteria.js +133 -0
  52. package/dist/electron-build/agents/goal-criteria.js.map +1 -0
  53. package/dist/electron-build/agents/goal-resume.js +364 -0
  54. package/dist/electron-build/agents/goal-resume.js.map +1 -0
  55. package/dist/electron-build/agents/goal-store.js +587 -0
  56. package/dist/electron-build/agents/goal-store.js.map +1 -0
  57. package/dist/electron-build/agents/intent-classifier.js +104 -0
  58. package/dist/electron-build/agents/intent-classifier.js.map +1 -0
  59. package/dist/electron-build/agents/iroh-secret.js +70 -0
  60. package/dist/electron-build/agents/iroh-secret.js.map +1 -0
  61. package/dist/electron-build/agents/loop-review.js +101 -0
  62. package/dist/electron-build/agents/loop-review.js.map +1 -0
  63. package/dist/electron-build/agents/memory-recall.js +154 -0
  64. package/dist/electron-build/agents/memory-recall.js.map +1 -0
  65. package/dist/electron-build/agents/p2p-document-tools.js +328 -0
  66. package/dist/electron-build/agents/p2p-document-tools.js.map +1 -0
  67. package/dist/electron-build/agents/parse-tool-call.js +564 -0
  68. package/dist/electron-build/agents/parse-tool-call.js.map +1 -0
  69. package/dist/electron-build/agents/patch-tool.js +205 -0
  70. package/dist/electron-build/agents/patch-tool.js.map +1 -0
  71. package/dist/electron-build/agents/payment-approval.js +183 -0
  72. package/dist/electron-build/agents/payment-approval.js.map +1 -0
  73. package/dist/electron-build/agents/payment-gate.js +139 -0
  74. package/dist/electron-build/agents/payment-gate.js.map +1 -0
  75. package/dist/electron-build/agents/permission-mode.js +124 -0
  76. package/dist/electron-build/agents/permission-mode.js.map +1 -0
  77. package/dist/electron-build/agents/pi-harness.js +268 -0
  78. package/dist/electron-build/agents/pi-harness.js.map +1 -0
  79. package/dist/electron-build/agents/pi-sdk-session-factory.js +117 -0
  80. package/dist/electron-build/agents/pi-sdk-session-factory.js.map +1 -0
  81. package/dist/electron-build/agents/pi-sdk-session-manager.js +335 -0
  82. package/dist/electron-build/agents/pi-sdk-session-manager.js.map +1 -0
  83. package/dist/electron-build/agents/pi-sdk-tools.js +4042 -0
  84. package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -0
  85. package/dist/electron-build/agents/pi-sdk-types.js +17 -0
  86. package/dist/electron-build/agents/pi-sdk-types.js.map +1 -0
  87. package/dist/electron-build/agents/pi-sdk.js +3325 -0
  88. package/dist/electron-build/agents/pi-sdk.js.map +1 -0
  89. package/dist/electron-build/agents/plan-store.js +212 -0
  90. package/dist/electron-build/agents/plan-store.js.map +1 -0
  91. package/dist/electron-build/agents/pre-tool-validator.js +200 -0
  92. package/dist/electron-build/agents/pre-tool-validator.js.map +1 -0
  93. package/dist/electron-build/agents/process-runner.js +148 -0
  94. package/dist/electron-build/agents/process-runner.js.map +1 -0
  95. package/dist/electron-build/agents/react-loop.js +131 -0
  96. package/dist/electron-build/agents/react-loop.js.map +1 -0
  97. package/dist/electron-build/agents/resource-store.js +180 -0
  98. package/dist/electron-build/agents/resource-store.js.map +1 -0
  99. package/dist/electron-build/agents/resource-token.js +118 -0
  100. package/dist/electron-build/agents/resource-token.js.map +1 -0
  101. package/dist/electron-build/agents/resource-wallet.js +84 -0
  102. package/dist/electron-build/agents/resource-wallet.js.map +1 -0
  103. package/dist/electron-build/agents/run-store.js +854 -0
  104. package/dist/electron-build/agents/run-store.js.map +1 -0
  105. package/dist/electron-build/agents/runner-resolver.js +267 -0
  106. package/dist/electron-build/agents/runner-resolver.js.map +1 -0
  107. package/dist/electron-build/agents/session-store.js +294 -0
  108. package/dist/electron-build/agents/session-store.js.map +1 -0
  109. package/dist/electron-build/agents/shell-guard.js +465 -0
  110. package/dist/electron-build/agents/shell-guard.js.map +1 -0
  111. package/dist/electron-build/agents/shell-tool.js +102 -0
  112. package/dist/electron-build/agents/shell-tool.js.map +1 -0
  113. package/dist/electron-build/agents/skill-loader.js +216 -0
  114. package/dist/electron-build/agents/skill-loader.js.map +1 -0
  115. package/dist/electron-build/agents/skill-readiness.js +174 -0
  116. package/dist/electron-build/agents/skill-readiness.js.map +1 -0
  117. package/dist/electron-build/agents/skill-share.js +394 -0
  118. package/dist/electron-build/agents/skill-share.js.map +1 -0
  119. package/dist/electron-build/agents/skill-supervisor-link.js +75 -0
  120. package/dist/electron-build/agents/skill-supervisor-link.js.map +1 -0
  121. package/dist/electron-build/agents/skill-writer.js +347 -0
  122. package/dist/electron-build/agents/skill-writer.js.map +1 -0
  123. package/dist/electron-build/agents/skills-manager.js +763 -0
  124. package/dist/electron-build/agents/skills-manager.js.map +1 -0
  125. package/dist/electron-build/agents/supervisor-host.js +294 -0
  126. package/dist/electron-build/agents/supervisor-host.js.map +1 -0
  127. package/dist/electron-build/agents/task/local-seller.js +188 -0
  128. package/dist/electron-build/agents/task/local-seller.js.map +1 -0
  129. package/dist/electron-build/agents/task/report-card.js +152 -0
  130. package/dist/electron-build/agents/task/report-card.js.map +1 -0
  131. package/dist/electron-build/agents/task/resource-advisor.js +222 -0
  132. package/dist/electron-build/agents/task/resource-advisor.js.map +1 -0
  133. package/dist/electron-build/agents/task/task-budget.js +111 -0
  134. package/dist/electron-build/agents/task/task-budget.js.map +1 -0
  135. package/dist/electron-build/agents/task/task-runner.js +670 -0
  136. package/dist/electron-build/agents/task/task-runner.js.map +1 -0
  137. package/dist/electron-build/agents/task-state.js +266 -0
  138. package/dist/electron-build/agents/task-state.js.map +1 -0
  139. package/dist/electron-build/agents/tool-registry.js +141 -0
  140. package/dist/electron-build/agents/tool-registry.js.map +1 -0
  141. package/dist/electron-build/agents/treasury-bridge.js +165 -0
  142. package/dist/electron-build/agents/treasury-bridge.js.map +1 -0
  143. package/dist/electron-build/agents/user-questions.js +223 -0
  144. package/dist/electron-build/agents/user-questions.js.map +1 -0
  145. package/dist/electron-build/agents/verify-recipe.js +90 -0
  146. package/dist/electron-build/agents/verify-recipe.js.map +1 -0
  147. package/dist/electron-build/agents/workflow-engine.js +222 -0
  148. package/dist/electron-build/agents/workflow-engine.js.map +1 -0
  149. package/dist/electron-build/agents/workflow-pivot-loop.js +988 -0
  150. package/dist/electron-build/agents/workflow-pivot-loop.js.map +1 -0
  151. package/dist/electron-build/agents/write-staging.js +133 -0
  152. package/dist/electron-build/agents/write-staging.js.map +1 -0
  153. package/dist/electron-build/agents/x402/goal-run-bridge.js +115 -0
  154. package/dist/electron-build/agents/x402/goal-run-bridge.js.map +1 -0
  155. package/dist/electron-build/agents/x402/milestone-settlement.js +163 -0
  156. package/dist/electron-build/agents/x402/milestone-settlement.js.map +1 -0
  157. package/dist/electron-build/agents/x402/paid-info-protocol.js +274 -0
  158. package/dist/electron-build/agents/x402/paid-info-protocol.js.map +1 -0
  159. package/dist/electron-build/agents/x402/paid-info-store.js +409 -0
  160. package/dist/electron-build/agents/x402/paid-info-store.js.map +1 -0
  161. package/dist/electron-build/agents/x402/paid-info-tools.js +346 -0
  162. package/dist/electron-build/agents/x402/paid-info-tools.js.map +1 -0
  163. package/dist/electron-build/agents/x402/payment-recovery.js +330 -0
  164. package/dist/electron-build/agents/x402/payment-recovery.js.map +1 -0
  165. package/dist/electron-build/agents/x402/resource-contract.js +533 -0
  166. package/dist/electron-build/agents/x402/resource-contract.js.map +1 -0
  167. package/dist/electron-build/agents/x402/settlement-state.js +432 -0
  168. package/dist/electron-build/agents/x402/settlement-state.js.map +1 -0
  169. package/dist/electron-build/agents/x402/trade.js +294 -0
  170. package/dist/electron-build/agents/x402/trade.js.map +1 -0
  171. package/dist/electron-build/agents/x402/transaction-protocol.js +109 -0
  172. package/dist/electron-build/agents/x402/transaction-protocol.js.map +1 -0
  173. package/dist/electron-build/agents/x402/transaction-store.js +404 -0
  174. package/dist/electron-build/agents/x402/transaction-store.js.map +1 -0
  175. package/dist/electron-build/agents/x402/x402Pay.js +377 -0
  176. package/dist/electron-build/agents/x402/x402Pay.js.map +1 -0
  177. package/dist/electron-build/bollharness-integration/context-router-judgment.js +269 -0
  178. package/dist/electron-build/bollharness-integration/context-router-judgment.js.map +1 -0
  179. package/dist/electron-build/bollharness-integration/context-router.js +584 -0
  180. package/dist/electron-build/bollharness-integration/context-router.js.map +1 -0
  181. package/dist/electron-build/bollharness-integration/gate-state-machine.js +362 -0
  182. package/dist/electron-build/bollharness-integration/gate-state-machine.js.map +1 -0
  183. package/dist/electron-build/bollharness-integration/gate-transition-hooks.js +136 -0
  184. package/dist/electron-build/bollharness-integration/gate-transition-hooks.js.map +1 -0
  185. package/dist/electron-build/bollharness-integration/guard-checker.js +400 -0
  186. package/dist/electron-build/bollharness-integration/guard-checker.js.map +1 -0
  187. package/dist/electron-build/bollharness-integration/index.js +123 -0
  188. package/dist/electron-build/bollharness-integration/index.js.map +1 -0
  189. package/dist/electron-build/bollharness-integration/integration.js +531 -0
  190. package/dist/electron-build/bollharness-integration/integration.js.map +1 -0
  191. package/dist/electron-build/bollharness-integration/skill-adapter.js +608 -0
  192. package/dist/electron-build/bollharness-integration/skill-adapter.js.map +1 -0
  193. package/dist/electron-build/bootstrap/bootstrap.js +173 -0
  194. package/dist/electron-build/bootstrap/bootstrap.js.map +1 -0
  195. package/dist/electron-build/bootstrap/context-collector.js +358 -0
  196. package/dist/electron-build/bootstrap/context-collector.js.map +1 -0
  197. package/dist/electron-build/bootstrap/context-hierarchy.js +262 -0
  198. package/dist/electron-build/bootstrap/context-hierarchy.js.map +1 -0
  199. package/dist/electron-build/bootstrap/context-manager.js +211 -0
  200. package/dist/electron-build/bootstrap/context-manager.js.map +1 -0
  201. package/dist/electron-build/bootstrap/context-os.js +277 -0
  202. package/dist/electron-build/bootstrap/context-os.js.map +1 -0
  203. package/dist/electron-build/bootstrap/event-log.js +203 -0
  204. package/dist/electron-build/bootstrap/event-log.js.map +1 -0
  205. package/dist/electron-build/bootstrap/exhaust-scrubber.js +277 -0
  206. package/dist/electron-build/bootstrap/exhaust-scrubber.js.map +1 -0
  207. package/dist/electron-build/bootstrap/lifecycle-hooks.js +282 -0
  208. package/dist/electron-build/bootstrap/lifecycle-hooks.js.map +1 -0
  209. package/dist/electron-build/bootstrap/memory-compressor.js +377 -0
  210. package/dist/electron-build/bootstrap/memory-compressor.js.map +1 -0
  211. package/dist/electron-build/bootstrap/persona-loader.js +219 -0
  212. package/dist/electron-build/bootstrap/persona-loader.js.map +1 -0
  213. package/dist/electron-build/bootstrap/project-context.js +162 -0
  214. package/dist/electron-build/bootstrap/project-context.js.map +1 -0
  215. package/dist/electron-build/bootstrap/project-state.js +205 -0
  216. package/dist/electron-build/bootstrap/project-state.js.map +1 -0
  217. package/dist/electron-build/bootstrap/session-window.js +162 -0
  218. package/dist/electron-build/bootstrap/session-window.js.map +1 -0
  219. package/dist/electron-build/bootstrap/vector-index.js +291 -0
  220. package/dist/electron-build/bootstrap/vector-index.js.map +1 -0
  221. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/cancelOrder.js +22 -0
  222. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/cancelOrder.js.map +1 -0
  223. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/clobShared.js +86 -0
  224. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/clobShared.js.map +1 -0
  225. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/createOrder.js +37 -0
  226. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/createOrder.js.map +1 -0
  227. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/getMarket.js +20 -0
  228. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/getMarket.js.map +1 -0
  229. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/getOrders.js +29 -0
  230. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/getOrders.js.map +1 -0
  231. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/listMarkets.js +28 -0
  232. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/listMarkets.js.map +1 -0
  233. package/dist/electron-build/constraint-runtime/src/tools/SafeSDK/deploySafe.js +10 -0
  234. package/dist/electron-build/constraint-runtime/src/tools/SafeSDK/deploySafe.js.map +1 -0
  235. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/autoPay.js +68 -0
  236. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/autoPay.js.map +1 -0
  237. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/createWallet.js +14 -0
  238. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/createWallet.js.map +1 -0
  239. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/getBalance.js +17 -0
  240. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/getBalance.js.map +1 -0
  241. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/importWallet.js +59 -0
  242. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/importWallet.js.map +1 -0
  243. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/sendTransaction.js +29 -0
  244. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/sendTransaction.js.map +1 -0
  245. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/signMessage.js +14 -0
  246. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/signMessage.js.map +1 -0
  247. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/transferToken.js +29 -0
  248. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/transferToken.js.map +1 -0
  249. package/dist/electron-build/constraints/index.js +11 -0
  250. package/dist/electron-build/constraints/index.js.map +1 -0
  251. package/dist/electron-build/context-compaction/auto-compact.js +182 -0
  252. package/dist/electron-build/context-compaction/auto-compact.js.map +1 -0
  253. package/dist/electron-build/context-compaction/budget-gate.js +32 -0
  254. package/dist/electron-build/context-compaction/budget-gate.js.map +1 -0
  255. package/dist/electron-build/context-compaction/budget-reduce.js +39 -0
  256. package/dist/electron-build/context-compaction/budget-reduce.js.map +1 -0
  257. package/dist/electron-build/context-compaction/context-collapse.js +71 -0
  258. package/dist/electron-build/context-compaction/context-collapse.js.map +1 -0
  259. package/dist/electron-build/context-compaction/index.js +38 -0
  260. package/dist/electron-build/context-compaction/index.js.map +1 -0
  261. package/dist/electron-build/context-compaction/microcompact.js +55 -0
  262. package/dist/electron-build/context-compaction/microcompact.js.map +1 -0
  263. package/dist/electron-build/context-compaction/pipeline.js +128 -0
  264. package/dist/electron-build/context-compaction/pipeline.js.map +1 -0
  265. package/dist/electron-build/context-compaction/snip.js +50 -0
  266. package/dist/electron-build/context-compaction/snip.js.map +1 -0
  267. package/dist/electron-build/context-compaction/token-estimator.js +40 -0
  268. package/dist/electron-build/context-compaction/token-estimator.js.map +1 -0
  269. package/dist/electron-build/context-compaction/types.js +21 -0
  270. package/dist/electron-build/context-compaction/types.js.map +1 -0
  271. package/dist/electron-build/cron/tick-lock.js +247 -0
  272. package/dist/electron-build/cron/tick-lock.js.map +1 -0
  273. package/dist/electron-build/documents/reader.js +131 -0
  274. package/dist/electron-build/documents/reader.js.map +1 -0
  275. package/dist/electron-build/documents/store.js +220 -0
  276. package/dist/electron-build/documents/store.js.map +1 -0
  277. package/dist/electron-build/external-engines/delegate-handle.js +76 -0
  278. package/dist/electron-build/external-engines/delegate-handle.js.map +1 -0
  279. package/dist/electron-build/external-engines/delegate.js +225 -0
  280. package/dist/electron-build/external-engines/delegate.js.map +1 -0
  281. package/dist/electron-build/external-engines/discovery.js +448 -0
  282. package/dist/electron-build/external-engines/discovery.js.map +1 -0
  283. package/dist/electron-build/external-engines/types.js +13 -0
  284. package/dist/electron-build/external-engines/types.js.map +1 -0
  285. package/dist/electron-build/hooks/hooks-engine.js +367 -0
  286. package/dist/electron-build/hooks/hooks-engine.js.map +1 -0
  287. package/dist/electron-build/judgeness/reflect.js +100 -0
  288. package/dist/electron-build/judgeness/reflect.js.map +1 -0
  289. package/dist/electron-build/judgeness/store.js +536 -0
  290. package/dist/electron-build/judgeness/store.js.map +1 -0
  291. package/dist/electron-build/judgeness/types.js +21 -0
  292. package/dist/electron-build/judgeness/types.js.map +1 -0
  293. package/dist/electron-build/llm/config-store.js +551 -0
  294. package/dist/electron-build/llm/config-store.js.map +1 -0
  295. package/dist/electron-build/llm/error-lessons.js +76 -0
  296. package/dist/electron-build/llm/error-lessons.js.map +1 -0
  297. package/dist/electron-build/llm/pi-ai.js +830 -0
  298. package/dist/electron-build/llm/pi-ai.js.map +1 -0
  299. package/dist/electron-build/llm/system-prompt/registry.js +318 -0
  300. package/dist/electron-build/llm/system-prompt/registry.js.map +1 -0
  301. package/dist/electron-build/llm/system-prompt/strip-hibsml.js +55 -0
  302. package/dist/electron-build/llm/system-prompt/strip-hibsml.js.map +1 -0
  303. package/dist/electron-build/locales/en.js +32 -0
  304. package/dist/electron-build/locales/en.js.map +1 -0
  305. package/dist/electron-build/locales/zh.js +30 -0
  306. package/dist/electron-build/locales/zh.js.map +1 -0
  307. package/dist/electron-build/lsp/lsp-manager.js +327 -0
  308. package/dist/electron-build/lsp/lsp-manager.js.map +1 -0
  309. package/dist/electron-build/lsp/lsp-tools.js +226 -0
  310. package/dist/electron-build/lsp/lsp-tools.js.map +1 -0
  311. package/dist/electron-build/migration/external-agent-migrator.js +451 -0
  312. package/dist/electron-build/migration/external-agent-migrator.js.map +1 -0
  313. package/dist/electron-build/network/agent-network.js +775 -0
  314. package/dist/electron-build/network/agent-network.js.map +1 -0
  315. package/dist/electron-build/network/goal-event-bridge.js +62 -0
  316. package/dist/electron-build/network/goal-event-bridge.js.map +1 -0
  317. package/dist/electron-build/network/iroh-integration.js +117 -0
  318. package/dist/electron-build/network/iroh-integration.js.map +1 -0
  319. package/dist/electron-build/network/iroh-transport.js +550 -0
  320. package/dist/electron-build/network/iroh-transport.js.map +1 -0
  321. package/dist/electron-build/network/p2p.js +1103 -0
  322. package/dist/electron-build/network/p2p.js.map +1 -0
  323. package/dist/electron-build/network/storage/adapters/json-adapter.js +416 -0
  324. package/dist/electron-build/network/storage/adapters/json-adapter.js.map +1 -0
  325. package/dist/electron-build/network/storage/types.js +18 -0
  326. package/dist/electron-build/network/storage/types.js.map +1 -0
  327. package/dist/electron-build/orbitdb/agent-tools.js +402 -0
  328. package/dist/electron-build/orbitdb/agent-tools.js.map +1 -0
  329. package/dist/electron-build/orbitdb/cid-database.js +284 -0
  330. package/dist/electron-build/orbitdb/cid-database.js.map +1 -0
  331. package/dist/electron-build/orbitdb/context-store.js +99 -0
  332. package/dist/electron-build/orbitdb/context-store.js.map +1 -0
  333. package/dist/electron-build/orbitdb/ipfs-node.js +120 -0
  334. package/dist/electron-build/orbitdb/ipfs-node.js.map +1 -0
  335. package/dist/electron-build/orbitdb/kanban-store.js +299 -0
  336. package/dist/electron-build/orbitdb/kanban-store.js.map +1 -0
  337. package/dist/electron-build/orbitdb/task-store.js +155 -0
  338. package/dist/electron-build/orbitdb/task-store.js.map +1 -0
  339. package/dist/electron-build/orbitdb/trajectory-store.js +194 -0
  340. package/dist/electron-build/orbitdb/trajectory-store.js.map +1 -0
  341. package/dist/electron-build/orbitdb/ui-cid.js +77 -0
  342. package/dist/electron-build/orbitdb/ui-cid.js.map +1 -0
  343. package/dist/electron-build/pi-ecosystem-a2ui/index.js +89 -0
  344. package/dist/electron-build/pi-ecosystem-a2ui/index.js.map +1 -0
  345. package/dist/electron-build/pi-ecosystem-goals/index.js +512 -0
  346. package/dist/electron-build/pi-ecosystem-goals/index.js.map +1 -0
  347. package/dist/electron-build/pi-ecosystem-judgment/adaptive-scan.js +325 -0
  348. package/dist/electron-build/pi-ecosystem-judgment/adaptive-scan.js.map +1 -0
  349. package/dist/electron-build/pi-ecosystem-judgment/causal-judge.js +492 -0
  350. package/dist/electron-build/pi-ecosystem-judgment/causal-judge.js.map +1 -0
  351. package/dist/electron-build/pi-ecosystem-judgment/cleanup.js +167 -0
  352. package/dist/electron-build/pi-ecosystem-judgment/cleanup.js.map +1 -0
  353. package/dist/electron-build/pi-ecosystem-judgment/decision.js +321 -0
  354. package/dist/electron-build/pi-ecosystem-judgment/decision.js.map +1 -0
  355. package/dist/electron-build/pi-ecosystem-judgment/detect-hook.js +175 -0
  356. package/dist/electron-build/pi-ecosystem-judgment/detect-hook.js.map +1 -0
  357. package/dist/electron-build/pi-ecosystem-judgment/distill-prompt.js +232 -0
  358. package/dist/electron-build/pi-ecosystem-judgment/distill-prompt.js.map +1 -0
  359. package/dist/electron-build/pi-ecosystem-judgment/distillation.js +304 -0
  360. package/dist/electron-build/pi-ecosystem-judgment/distillation.js.map +1 -0
  361. package/dist/electron-build/pi-ecosystem-judgment/evolve-judgment.js +176 -0
  362. package/dist/electron-build/pi-ecosystem-judgment/evolve-judgment.js.map +1 -0
  363. package/dist/electron-build/pi-ecosystem-judgment/human-value-pipeline.js +65 -0
  364. package/dist/electron-build/pi-ecosystem-judgment/human-value-pipeline.js.map +1 -0
  365. package/dist/electron-build/pi-ecosystem-judgment/human-value-store.js +808 -0
  366. package/dist/electron-build/pi-ecosystem-judgment/human-value-store.js.map +1 -0
  367. package/dist/electron-build/pi-ecosystem-judgment/index.js +508 -0
  368. package/dist/electron-build/pi-ecosystem-judgment/index.js.map +1 -0
  369. package/dist/electron-build/pi-ecosystem-judgment/injection-gate.js +334 -0
  370. package/dist/electron-build/pi-ecosystem-judgment/injection-gate.js.map +1 -0
  371. package/dist/electron-build/pi-ecosystem-judgment/monitor-gate.js +228 -0
  372. package/dist/electron-build/pi-ecosystem-judgment/monitor-gate.js.map +1 -0
  373. package/dist/electron-build/pi-ecosystem-judgment/value-injection.js +598 -0
  374. package/dist/electron-build/pi-ecosystem-judgment/value-injection.js.map +1 -0
  375. package/dist/electron-build/pi-ecosystem-mcp/index.js +643 -0
  376. package/dist/electron-build/pi-ecosystem-mcp/index.js.map +1 -0
  377. package/dist/electron-build/pi-ecosystem-mcp/ui-tools.js +116 -0
  378. package/dist/electron-build/pi-ecosystem-mcp/ui-tools.js.map +1 -0
  379. package/dist/electron-build/pi-ecosystem-subagents/index.js +352 -0
  380. package/dist/electron-build/pi-ecosystem-subagents/index.js.map +1 -0
  381. package/dist/electron-build/security/builtin-guards.js +133 -0
  382. package/dist/electron-build/security/builtin-guards.js.map +1 -0
  383. package/dist/electron-build/security/context-router-tool.js +111 -0
  384. package/dist/electron-build/security/context-router-tool.js.map +1 -0
  385. package/dist/electron-build/security/input-scanner.js +263 -0
  386. package/dist/electron-build/security/input-scanner.js.map +1 -0
  387. package/dist/electron-build/security/react-harness.js +148 -0
  388. package/dist/electron-build/security/react-harness.js.map +1 -0
  389. package/dist/electron-build/security/tool-gate.js +287 -0
  390. package/dist/electron-build/security/tool-gate.js.map +1 -0
  391. package/dist/electron-build/setup/setup-store.js +648 -0
  392. package/dist/electron-build/setup/setup-store.js.map +1 -0
  393. package/dist/electron-build/social/channels/ChannelManager.js +444 -0
  394. package/dist/electron-build/social/channels/ChannelManager.js.map +1 -0
  395. package/dist/electron-build/social/channels/DiapChannelBridge.js +451 -0
  396. package/dist/electron-build/social/channels/DiapChannelBridge.js.map +1 -0
  397. package/dist/electron-build/social/channels/InterestMatcher.js +135 -0
  398. package/dist/electron-build/social/channels/InterestMatcher.js.map +1 -0
  399. package/dist/electron-build/social/channels/types.js +21 -0
  400. package/dist/electron-build/social/channels/types.js.map +1 -0
  401. package/dist/electron-build/social/global-shared-context.js +368 -0
  402. package/dist/electron-build/social/global-shared-context.js.map +1 -0
  403. package/dist/electron-build/social/heartbeat.js +882 -0
  404. package/dist/electron-build/social/heartbeat.js.map +1 -0
  405. package/dist/electron-build/storage/did-catalog-bridge.js +314 -0
  406. package/dist/electron-build/storage/did-catalog-bridge.js.map +1 -0
  407. package/dist/electron-build/storage/did-catalog.js +272 -0
  408. package/dist/electron-build/storage/did-catalog.js.map +1 -0
  409. package/dist/electron-build/utils/auto-update.js +140 -558
  410. package/dist/electron-build/utils/auto-update.js.map +1 -1
  411. package/dist/electron-build/utils/module-context.js +98 -0
  412. package/dist/electron-build/utils/module-context.js.map +1 -0
  413. package/dist/electron-build/utils/runtime-bootstrap.js +745 -0
  414. package/dist/electron-build/utils/runtime-bootstrap.js.map +1 -0
  415. package/dist/electron-build/utils/update-manager.js +770 -0
  416. package/dist/electron-build/utils/update-manager.js.map +1 -0
  417. package/dist/electron-build/utils/update-state.js +406 -0
  418. package/dist/electron-build/utils/update-state.js.map +1 -0
  419. package/dist/electron-build/utils/version-info.js +562 -0
  420. package/dist/electron-build/utils/version-info.js.map +1 -0
  421. package/dist/electron-build/web/i18n.js +146 -0
  422. package/dist/electron-build/web/i18n.js.map +1 -0
  423. package/dist/electron-build/web/routes-x402-info.js +232 -0
  424. package/dist/electron-build/web/routes-x402-info.js.map +1 -0
  425. package/dist/electron-build/web/server-storage.js +390 -0
  426. package/dist/electron-build/web/server-storage.js.map +1 -0
  427. package/dist/electron-build/web/server-types.js +52 -0
  428. package/dist/electron-build/web/server-types.js.map +1 -0
  429. package/dist/electron-build/web/task-deps.js +41 -0
  430. package/dist/electron-build/web/task-deps.js.map +1 -0
  431. package/dist/index.js +28 -27
  432. package/dist/llm/system-prompt/registry.js +6 -3
  433. package/dist/utils/auto-update.js +138 -525
  434. package/dist/utils/module-context.js +59 -0
  435. package/dist/utils/runtime-bootstrap.js +682 -0
  436. package/dist/utils/update-cli.js +82 -0
  437. package/dist/utils/update-health.js +401 -0
  438. package/dist/utils/update-manager.js +716 -0
  439. package/dist/utils/update-state.js +353 -0
  440. package/dist/utils/version-info.js +510 -0
  441. package/package.json +1 -1
  442. package/scripts/build-cli.js +32 -151
  443. package/scripts/postinstall.js +153 -76
@@ -0,0 +1,770 @@
1
+ "use strict";
2
+ /**
3
+ * update-manager.ts — 更新系统的**唯一决策者** (Phase 2/4/5, 2026-09-19)
4
+ *
5
+ * 职责只有三件 (不多做):
6
+ * ① 识别当前安装 (`detectInstallation`)
7
+ * ② 查询目标版本 (npm registry, 唯一稳定渠道)
8
+ * ③ 形成更新计划 (`buildUpdatePlan`) / 执行更新 (`applyUpdate`)
9
+ *
10
+ * 它**不**直接改用户配置, **不**默认自动安装, **不**碰 `~/.bolloon` 的用户数据
11
+ * (goals / runs / transactions / skills / config 一律不动)。
12
+ *
13
+ * 渠道决定 (2026-09-19, 冻结): **npm 是唯一稳定发行渠道**; GitHub 只作为源码与发布记录。
14
+ * 因此安装脚本不再优先查 GitHub Releases, 版本解析也只有一份 (本模块)。
15
+ *
16
+ * 与计划的刻意偏差 (如实记录, 见 docs/wiki/update-protocol.md §5):
17
+ * "安装到临时位置 → 原子切换" 落成 **"临时位置下载并校验 tarball → 交给 npm 完成替换 → 验证可启动 → 失败回滚"**。
18
+ * 理由: 手工把整棵 node_modules (949 个包) 复制/切换一遍, 比 npm 自己的替换更危险也更容易半更新;
19
+ * 真正要保的性质 ("不能删掉旧版本后才发现新版本起不来") 由**切换后验证 + 失败回滚**保证, 这两步是真跑的。
20
+ */
21
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ var desc = Object.getOwnPropertyDescriptor(m, k);
24
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
25
+ desc = { enumerable: true, get: function() { return m[k]; } };
26
+ }
27
+ Object.defineProperty(o, k2, desc);
28
+ }) : (function(o, m, k, k2) {
29
+ if (k2 === undefined) k2 = k;
30
+ o[k2] = m[k];
31
+ }));
32
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
33
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
34
+ }) : function(o, v) {
35
+ o["default"] = v;
36
+ });
37
+ var __importStar = (this && this.__importStar) || (function () {
38
+ var ownKeys = function(o) {
39
+ ownKeys = Object.getOwnPropertyNames || function (o) {
40
+ var ar = [];
41
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
42
+ return ar;
43
+ };
44
+ return ownKeys(o);
45
+ };
46
+ return function (mod) {
47
+ if (mod && mod.__esModule) return mod;
48
+ var result = {};
49
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
50
+ __setModuleDefault(result, mod);
51
+ return result;
52
+ };
53
+ })();
54
+ Object.defineProperty(exports, "__esModule", { value: true });
55
+ exports.NPM_FETCH_RETRY_FLAGS = exports.IN_FLIGHT_STAGES = exports.MIN_FREE_BYTES = void 0;
56
+ exports.parseJsonFromStdout = parseJsonFromStdout;
57
+ exports.parseVersion = parseVersion;
58
+ exports.compareVersions = compareVersions;
59
+ exports.isKnownVersion = isKnownVersion;
60
+ exports.classifyRegistryError = classifyRegistryError;
61
+ exports.queryRegistryDoc = queryRegistryDoc;
62
+ exports.checkForUpdate = checkForUpdate;
63
+ exports.freeBytesAt = freeBytesAt;
64
+ exports.buildUpdatePlan = buildUpdatePlan;
65
+ exports.renderUpdatePlan = renderUpdatePlan;
66
+ exports.validateStagedPackage = validateStagedPackage;
67
+ exports.installedVersionOnDisk = installedVersionOnDisk;
68
+ exports.applyUpdate = applyUpdate;
69
+ exports.readUpdateStatus = readUpdateStatus;
70
+ exports.readHistory = readHistory;
71
+ exports.renderHistory = renderHistory;
72
+ exports.updateSummaryFor = updateSummaryFor;
73
+ const os = __importStar(require("os"));
74
+ const path = __importStar(require("path"));
75
+ const fs = __importStar(require("fs"));
76
+ const fsp = __importStar(require("fs/promises"));
77
+ const https = __importStar(require("https"));
78
+ const http = __importStar(require("http"));
79
+ const child_process_1 = require("child_process");
80
+ const version_info_js_1 = require("./version-info.js");
81
+ const update_state_js_1 = require("./update-state.js");
82
+ // ── 版本比较 (唯一一份) ─────────────────────────────────────────────────────
83
+ /**
84
+ * 从子进程 stdout 里取 JSON —— **不要**按"行首是否 { "过滤:
85
+ * `JSON.stringify(x, null, 2)` 是**多行**的, 只留第一行 `{` 会解析失败
86
+ * (真跑抓到过: 更新后验证永远判失败 → 每次都"回滚").
87
+ */
88
+ function parseJsonFromStdout(stdout) {
89
+ const s = String(stdout || '');
90
+ const start = s.indexOf('{');
91
+ if (start < 0)
92
+ return null;
93
+ try {
94
+ return JSON.parse(s.slice(start));
95
+ }
96
+ catch {
97
+ // 尾部可能有非 JSON 输出: 退一步只取到最后一个 }
98
+ const end = s.lastIndexOf('}');
99
+ if (end > start) {
100
+ try {
101
+ return JSON.parse(s.slice(start, end + 1));
102
+ }
103
+ catch {
104
+ return null;
105
+ }
106
+ }
107
+ return null;
108
+ }
109
+ }
110
+ function parseVersion(v) {
111
+ const clean = String(v || '').trim().replace(/^v/, '').split('-')[0];
112
+ const parts = clean.split('.').map((p) => parseInt(p.replace(/\D.*$/, ''), 10));
113
+ return parts.map((n) => (Number.isFinite(n) ? n : 0));
114
+ }
115
+ /** -1 = a<b, 0 = 相等, 1 = a>b (只比数值段, 忽略预发布标签) */
116
+ function compareVersions(a, b) {
117
+ const pa = parseVersion(a);
118
+ const pb = parseVersion(b);
119
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
120
+ const x = pa[i] ?? 0;
121
+ const y = pb[i] ?? 0;
122
+ if (x < y)
123
+ return -1;
124
+ if (x > y)
125
+ return 1;
126
+ }
127
+ return 0;
128
+ }
129
+ function isKnownVersion(v) {
130
+ return !!v && v !== 'unknown' && /^\d/.test(String(v).trim().replace(/^v/, ''));
131
+ }
132
+ function httpGetJson(url, timeoutMs = 10000) {
133
+ return new Promise((resolve, reject) => {
134
+ const client = url.startsWith('https') ? https : http;
135
+ const req = client.get(url, { timeout: timeoutMs, headers: { Accept: 'application/json' } }, (res) => {
136
+ let data = '';
137
+ res.on('data', (c) => { data += c; });
138
+ res.on('end', () => resolve({ status: res.statusCode || 0, body: data }));
139
+ });
140
+ req.on('error', reject);
141
+ req.on('timeout', () => { req.destroy(new Error('timeout')); });
142
+ });
143
+ }
144
+ const OFFLINE_CODES = new Set(['ENOTFOUND', 'EAI_AGAIN', 'ECONNREFUSED', 'ECONNRESET', 'ETIMEDOUT', 'EHOSTUNREACH', 'ENETUNREACH', 'ENETDOWN', 'EAI_FAIL', 'UND_ERR_CONNECT_TIMEOUT']);
145
+ /** 网络类错误 → offline; 其它 (HTTP 5xx / 解析失败 / 包不存在) → registry_unavailable。 */
146
+ function classifyRegistryError(err, httpStatus) {
147
+ const code = String(err?.code || '');
148
+ if (OFFLINE_CODES.has(code) || /timeout|timed out|ENOTFOUND|getaddrinfo|network|socket hang up|超时/i.test(String(err?.message || ''))) {
149
+ return { kind: 'offline', detail: `${code || err?.message || '网络不可达'}` };
150
+ }
151
+ if (httpStatus && httpStatus >= 500)
152
+ return { kind: 'registry_unavailable', detail: `registry 返回 HTTP ${httpStatus}` };
153
+ if (httpStatus === 404)
154
+ return { kind: 'registry_unavailable', detail: `registry 上没有 ${version_info_js_1.PKG_NAME} (HTTP 404)` };
155
+ if (httpStatus && httpStatus >= 400)
156
+ return { kind: 'registry_unavailable', detail: `registry 返回 HTTP ${httpStatus}` };
157
+ return { kind: 'registry_unavailable', detail: code || err?.message || '未知错误' };
158
+ }
159
+ async function queryRegistryDoc(pkg = version_info_js_1.PKG_NAME, timeoutMs = 10000) {
160
+ const url = `${version_info_js_1.NPM_REGISTRY_BASE}/${encodeURIComponent(pkg).replace('%40', '@')}`;
161
+ try {
162
+ const { status, body } = await httpGetJson(url, timeoutMs);
163
+ if (status < 200 || status >= 300)
164
+ return { ok: false, ...classifyRegistryError(null, status) };
165
+ let raw;
166
+ try {
167
+ raw = JSON.parse(body);
168
+ }
169
+ catch (e) {
170
+ return { ok: false, kind: 'registry_unavailable', detail: 'registry 返回了无法解析的内容' };
171
+ }
172
+ const distTags = (raw?.['dist-tags'] || {});
173
+ const versions = Object.keys(raw?.versions || {});
174
+ if (!distTags.latest && versions.length === 0) {
175
+ return { ok: false, kind: 'registry_unavailable', detail: 'registry 上没有可用版本' };
176
+ }
177
+ const gitHeads = {};
178
+ for (const v of versions) {
179
+ const gh = raw.versions[v]?.gitHead;
180
+ if (typeof gh === 'string' && gh)
181
+ gitHeads[v] = gh;
182
+ }
183
+ return { ok: true, doc: { latest: distTags.latest || versions[versions.length - 1], distTags, versions, gitHeads } };
184
+ }
185
+ catch (e) {
186
+ return { ok: false, ...classifyRegistryError(e) };
187
+ }
188
+ }
189
+ /**
190
+ * 检查更新。**这是唯一的检查入口** —— CLI / 启动后台 / Python 检查器 / 安装脚本都走它。
191
+ *
192
+ * 结论优先级 (刻意定死, 防"模糊行为"):
193
+ * 1. 读不到本地版本 → local_version_unknown (绝不默认 0.0.0 后继续)
194
+ * 2. 安装方式不支持自动更新 → unsupported_installation (仍会带出 latestVersion)
195
+ * 3. 显式跳过 / 节流 → check_skipped (结论来自缓存)
196
+ * 4. 网络不可达 → offline (绝不显示"已是最新")
197
+ * 5. registry 不可用 / 包不存在 → registry_unavailable
198
+ * 6. latest > current → update_available
199
+ * 7. 否则 → up_to_date
200
+ */
201
+ async function checkForUpdate(opts = {}) {
202
+ const home = opts.home ?? (await Promise.resolve().then(() => __importStar(require('../setup/setup-store.js')))).resolveBolloonHome();
203
+ const prefs = await (0, update_state_js_1.readUpdatePrefs)({ home, env: opts.env });
204
+ const channel = (0, version_info_js_1.resolveUpdateChannel)(opts.channel || prefs.channel);
205
+ const install = opts.installation || (0, version_info_js_1.detectInstallation)({ home });
206
+ const pkg = (0, version_info_js_1.readPackageAt)(install.packageRoot);
207
+ const current = isKnownVersion(pkg?.version) ? String(pkg?.version) : 'unknown';
208
+ const now = new Date().toISOString();
209
+ const state = await (0, update_state_js_1.readUpdateState)(home);
210
+ const persist = opts.persist !== false;
211
+ const base = {
212
+ currentVersion: current,
213
+ channel,
214
+ source: install.updateSource,
215
+ installMethod: install.method,
216
+ checkedAt: now,
217
+ fromCache: false,
218
+ };
219
+ const commit = async (r) => {
220
+ if (persist) {
221
+ await (0, update_state_js_1.writeUpdateState)({
222
+ currentVersion: r.currentVersion,
223
+ latestVersion: r.latestVersion,
224
+ channel: r.channel,
225
+ installMethod: r.installMethod,
226
+ installDir: install.installDir,
227
+ entryPath: install.entryPath,
228
+ nodeVersion: process.version.replace(/^v/, ''),
229
+ platform: os.platform(),
230
+ arch: os.arch(),
231
+ lastCheckAt: r.checkedAt,
232
+ lastCheckStatus: r.status,
233
+ lastCheckReason: r.reason,
234
+ }, home);
235
+ }
236
+ return r;
237
+ };
238
+ // 1. 本地版本读不到 —— 不猜
239
+ if (!isKnownVersion(current)) {
240
+ return commit({ ...base, status: 'local_version_unknown', latestVersion: null, reason: `读不到 ${install.packageRoot}/package.json 的版本` });
241
+ }
242
+ // 3. 显式跳过 / 节流
243
+ const throttled = !opts.force && state.lastCheckAt
244
+ ? (Date.now() - Date.parse(state.lastCheckAt)) < prefs.checkIntervalHours * 3600_000
245
+ : false;
246
+ const useCache = !!opts.offline || throttled;
247
+ if (useCache && state.lastCheckStatus) {
248
+ // 语义: 本次**没有真的检查** → 结论就是 check_skipped, 上次的结论原样带出来
249
+ // (绝不把缓存里的 update_available/up_to_date 冒充成"刚查出来的")
250
+ const cached = state.lastCheckStatus;
251
+ const r = await commit({
252
+ ...base, fromCache: true,
253
+ status: 'check_skipped',
254
+ cachedStatus: cached,
255
+ latestVersion: state.latestVersion,
256
+ reason: opts.offline
257
+ ? `离线模式: 使用缓存结论 (${cached})`
258
+ : `距上次检查不足 ${prefs.checkIntervalHours}h, 使用缓存结论 (${cached})`,
259
+ checkedAt: state.lastCheckAt || now,
260
+ });
261
+ if (persist)
262
+ await (0, update_state_js_1.writeUpdateState)({ lastCheckReason: r.reason }, home);
263
+ return r;
264
+ }
265
+ // 2. 安装方式不支持自动更新 —— 仍把 latest / 可回滚性带出来, 但结论就是"不支持"
266
+ const registry = opts.registry || await queryRegistryDoc(version_info_js_1.PKG_NAME);
267
+ const latest = registry.ok ? (registry.doc.distTags[(0, version_info_js_1.distTagForChannel)(channel)] || registry.doc.latest) : null;
268
+ const targetPublishedOf = (v) => v && registry.ok ? registry.doc.versions.includes(v) : undefined;
269
+ const rollbackSupportedOf = registry.ok ? registry.doc.versions.includes(current) : undefined;
270
+ if (install.method === 'development' || install.method === 'unknown' || install.method === 'release-binary') {
271
+ return commit({
272
+ ...base, status: 'unsupported_installation', latestVersion: latest,
273
+ reason: `${install.reason}; 这种安装方式不支持自动更新`,
274
+ targetPublished: targetPublishedOf(latest),
275
+ rollbackSupported: rollbackSupportedOf,
276
+ });
277
+ }
278
+ // 4/5. registry 拿不到 —— 绝不显示"已是最新"
279
+ if (!registry.ok) {
280
+ return commit({
281
+ ...base,
282
+ status: registry.kind === 'offline' ? 'offline' : 'registry_unavailable',
283
+ latestVersion: null,
284
+ reason: registry.detail,
285
+ });
286
+ }
287
+ const targetPublished = !!latest && registry.doc.versions.includes(latest);
288
+ const rollbackSupported = rollbackSupportedOf === true;
289
+ // 6/7. 比较
290
+ if (latest && compareVersions(current, latest) < 0) {
291
+ return commit({
292
+ ...base, status: 'update_available', latestVersion: latest, targetPublished, rollbackSupported,
293
+ reason: `当前 ${current} → 目标 ${latest}`,
294
+ });
295
+ }
296
+ return commit({ ...base, status: 'up_to_date', latestVersion: latest, targetPublished, rollbackSupported });
297
+ }
298
+ const WILL_NOT_TOUCH = [
299
+ '~/.bolloon/config.json',
300
+ '~/.bolloon/goals/',
301
+ '~/.bolloon/runs/',
302
+ '~/.bolloon/transactions/',
303
+ '~/.bolloon/skills/',
304
+ '~/.bolloon/sessions/',
305
+ '~/.bolloon/identity/',
306
+ ];
307
+ /** 磁盘余量 (字节)。statfs 不可用时返回 null (不假装知道)。 */
308
+ function freeBytesAt(dir) {
309
+ try {
310
+ const st = fs.statfsSync?.(dir);
311
+ if (!st)
312
+ return null;
313
+ return Number(st.bavail) * Number(st.bsize);
314
+ }
315
+ catch {
316
+ return null;
317
+ }
318
+ }
319
+ exports.MIN_FREE_BYTES = 300 * 1024 * 1024;
320
+ /** 安装类风险: 与"机器上有没有在跑的任务"无关, 任何计划都要评估 (测试也不许跳过)。 */
321
+ async function collectInstallRisk(install) {
322
+ const out = [];
323
+ out.push({
324
+ id: 'install_method', label: '安装方式支持自动更新', ok: install.method === 'npm-global', blocking: true,
325
+ detail: install.method === 'npm-global'
326
+ ? `npm 全局安装 (${install.installDir})`
327
+ : `${install.method}: ${install.reason} (请用对应方式更新: git pull + npm run build:all / 项目的包管理)`,
328
+ });
329
+ out.push({
330
+ id: 'install_dir_writable', label: '安装目录可写', ok: install.writable, blocking: true,
331
+ detail: install.writable ? install.installDir : `${install.installDir} 不可写 (需要 sudo 或改 npm prefix)`,
332
+ });
333
+ const free = freeBytesAt(install.installDir);
334
+ out.push({
335
+ id: 'disk_space', label: '磁盘空间充足', ok: free === null ? true : free >= exports.MIN_FREE_BYTES,
336
+ blocking: free === null ? false : free < exports.MIN_FREE_BYTES,
337
+ detail: free === null ? '无法读取磁盘余量 (跳过)' : `${(free / 1024 / 1024 / 1024).toFixed(2)} GiB 可用 (需 ≥ ${(exports.MIN_FREE_BYTES / 1024 / 1024).toFixed(0)} MiB)`,
338
+ });
339
+ const lock = (0, update_state_js_1.readUpdateLock)();
340
+ out.push({
341
+ id: 'update_lock', label: '没有其它更新进程', ok: !lock || (0, update_state_js_1.lockIsStale)(lock), blocking: !!lock && !(0, update_state_js_1.lockIsStale)(lock),
342
+ detail: !lock ? '无更新锁'
343
+ : (0, update_state_js_1.lockIsStale)(lock) ? `存在陈旧锁 (pid ${lock.pid}, ${lock.at}) — 可回收`
344
+ : `另一个更新进程持有锁 (pid ${lock.pid}, ${lock.at})`,
345
+ });
346
+ return out;
347
+ }
348
+ /** 负载类风险: Supervisor / Goal / Run / 支付 (非阻塞提醒, 但会把默认策略变成"等 Run 结束")。 */
349
+ async function collectWorkloadRisk() {
350
+ const out = [];
351
+ try {
352
+ const { supervisorStatePath } = await Promise.resolve().then(() => __importStar(require('../agents/supervisor-host.js')));
353
+ let sup = null;
354
+ try {
355
+ sup = JSON.parse(await fsp.readFile(supervisorStatePath(), 'utf8'));
356
+ }
357
+ catch {
358
+ sup = null;
359
+ }
360
+ const alive = sup && typeof sup.pid === 'number' ? (() => { try {
361
+ process.kill(sup.pid, 0);
362
+ return true;
363
+ }
364
+ catch (e) {
365
+ return e?.code === 'EPERM';
366
+ } })() : false;
367
+ const running = !!sup && alive && !sup.stoppedAt;
368
+ out.push({
369
+ id: 'supervisor_running', label: 'Supervisor 未在运行', ok: !running, blocking: false, advisory: true,
370
+ detail: running ? `Supervisor 正在运行 (pid ${sup.pid}, owner ${sup.owner}, 最近 tick ${sup.lastTickAt || '未知'})` : '无运行中的 Supervisor 宿主',
371
+ });
372
+ }
373
+ catch {
374
+ out.push({ id: 'supervisor_running', label: 'Supervisor 未在运行', ok: true, blocking: false, advisory: true, detail: '无法读取 supervisor.json (按未运行处理)' });
375
+ }
376
+ try {
377
+ const { listGoals } = await Promise.resolve().then(() => __importStar(require('../agents/goal-store.js')));
378
+ const goals = await listGoals({ status: ['open', 'active', 'recovering', 'retry_wait', 'awaiting_external', 'stalled'], limit: 50 });
379
+ out.push({
380
+ id: 'active_goals', label: '没有进行中的 Goal', ok: goals.length === 0, blocking: false, advisory: true,
381
+ detail: goals.length === 0 ? '无进行中 Goal' : `${goals.length} 个未收尾 Goal (${goals.slice(0, 3).map((g) => `${g.goalId}:${g.status}`).join(', ')}${goals.length > 3 ? ', …' : ''})`,
382
+ });
383
+ }
384
+ catch {
385
+ out.push({ id: 'active_goals', label: '没有进行中的 Goal', ok: true, blocking: false, advisory: true, detail: '无法读取 goals (按无处理)' });
386
+ }
387
+ try {
388
+ const { listRuns } = await Promise.resolve().then(() => __importStar(require('../agents/run-store.js')));
389
+ const runs = await listRuns({ status: ['queued', 'running', 'recovering', 'paused', 'awaiting_external', 'interrupted', 'stalled'], limit: 50 });
390
+ out.push({
391
+ id: 'active_runs', label: '没有进行中的 Run', ok: runs.length === 0, blocking: false, advisory: true,
392
+ detail: runs.length === 0 ? '无进行中 Run' : `${runs.length} 个未收尾 Run (${runs.slice(0, 3).map((r) => `${r.runId}:${r.status}`).join(', ')}${runs.length > 3 ? ', …' : ''})`,
393
+ });
394
+ }
395
+ catch {
396
+ out.push({ id: 'active_runs', label: '没有进行中的 Run', ok: true, blocking: false, advisory: true, detail: '无法读取 runs (按无处理)' });
397
+ }
398
+ try {
399
+ const { pendingTransactions } = await Promise.resolve().then(() => __importStar(require('../agents/x402/transaction-store.js')));
400
+ const pend = await pendingTransactions();
401
+ const paying = pend.filter((t) => ['paying', 'payment_required'].includes(t.status));
402
+ out.push({
403
+ id: 'payment_in_flight', label: '没有支付中的交易', ok: paying.length === 0, blocking: false, advisory: true,
404
+ detail: paying.length === 0
405
+ ? (pend.length ? `${pend.length} 笔待收尾交易 (无支付中, 可继续)` : '无待收尾交易')
406
+ : `${paying.length} 笔支付中/待付交易 (${paying.slice(0, 3).map((t) => t.id || t.transactionId).join(', ')}) — 更新前应先对账`,
407
+ });
408
+ }
409
+ catch {
410
+ out.push({ id: 'payment_in_flight', label: '没有支付中的交易', ok: true, blocking: false, advisory: true, detail: '无法读取 transactions (按无处理)' });
411
+ }
412
+ return out;
413
+ }
414
+ async function buildUpdatePlan(opts = {}) {
415
+ const home = opts.home ?? (await Promise.resolve().then(() => __importStar(require('../setup/setup-store.js')))).resolveBolloonHome();
416
+ const install = opts.installation || (0, version_info_js_1.detectInstallation)({ home });
417
+ const check = await checkForUpdate({ ...opts, home, persist: false, installation: install });
418
+ const risk = [
419
+ ...await collectInstallRisk(install),
420
+ ...(opts.workloadRiskOverride || await collectWorkloadRisk()),
421
+ ];
422
+ // registry 侧风险项来自检查结论
423
+ risk.push({
424
+ id: 'registry_reachable',
425
+ label: 'registry 可达',
426
+ ok: check.status !== 'offline' && check.status !== 'registry_unavailable',
427
+ blocking: check.status === 'offline' || check.status === 'registry_unavailable' || check.status === 'local_version_unknown',
428
+ detail: check.status === 'offline' ? `离线: ${check.reason}`
429
+ : check.status === 'registry_unavailable' ? `registry 不可用: ${check.reason}`
430
+ : 'npm registry 可达',
431
+ });
432
+ risk.push({
433
+ id: 'target_published',
434
+ label: '目标版本真实存在',
435
+ ok: check.targetPublished !== false,
436
+ blocking: !!check.latestVersion && check.targetPublished === false,
437
+ detail: check.targetPublished === false
438
+ ? `registry 上没有 ${version_info_js_1.PKG_NAME}@${check.latestVersion} — 不执行更新`
439
+ : check.targetPublished === true ? `已确认 ${check.latestVersion} 可下载` : '未检查 (离线)',
440
+ });
441
+ risk.push({
442
+ id: 'rollback_supported',
443
+ label: '当前版本可回滚',
444
+ ok: check.rollbackSupported !== false,
445
+ blocking: false,
446
+ detail: check.rollbackSupported === false
447
+ ? `registry 上找不到当前版本 ${check.currentVersion} — 更新失败将无法用 npm 回滚`
448
+ : check.rollbackSupported === true ? `registry 上存在 ${check.currentVersion} (可回滚)` : '未检查 (离线)',
449
+ });
450
+ const blockers = risk.filter((r) => !r.ok && r.blocking).map((r) => `${r.label}: ${r.detail}`);
451
+ const advisories = risk.filter((r) => !r.ok && !r.blocking).map((r) => `${r.label}: ${r.detail}`);
452
+ const target = check.latestVersion && compareVersions(check.currentVersion, check.latestVersion) < 0
453
+ ? check.latestVersion
454
+ : null;
455
+ return {
456
+ ok: blockers.length === 0 && !!target,
457
+ currentVersion: check.currentVersion,
458
+ targetVersion: target,
459
+ channel: check.channel,
460
+ installMethod: check.installMethod,
461
+ source: check.source,
462
+ installDir: install.installDir,
463
+ needsRestart: !!target,
464
+ willUpdate: target && install.method === 'npm-global' ? [version_info_js_1.PKG_NAME, version_info_js_1.CONSTRAINT_PKG_NAME] : [],
465
+ willNotTouch: WILL_NOT_TOUCH,
466
+ risk, blockers, advisories,
467
+ strategies: ['now', 'wait', 'cancel'],
468
+ defaultStrategy: advisories.length > 0 ? 'wait' : 'now',
469
+ check,
470
+ };
471
+ }
472
+ function renderUpdatePlan(plan) {
473
+ const L = [];
474
+ L.push(`当前版本: ${plan.currentVersion}`);
475
+ L.push(`目标版本: ${plan.targetVersion || '(无可用更新)'}`);
476
+ L.push(`安装方式: ${plan.installMethod}`);
477
+ L.push(`更新通道: ${plan.channel} (来源: ${plan.source})`);
478
+ L.push(`安装目录: ${plan.installDir}`);
479
+ L.push('');
480
+ L.push('将更新:');
481
+ if (plan.willUpdate.length === 0)
482
+ L.push(' (无 — 当前没有可执行的更新)');
483
+ for (const p of plan.willUpdate)
484
+ L.push(` ${p}`);
485
+ L.push('');
486
+ L.push('不会修改:');
487
+ for (const p of plan.willNotTouch)
488
+ L.push(` ${p}`);
489
+ L.push('');
490
+ L.push(`需要重启: ${plan.needsRestart ? '是' : '否'}`);
491
+ L.push(`风险检查: ${plan.blockers.length === 0 ? '通过' : `未通过 (${plan.blockers.length} 项阻塞)`}`);
492
+ for (const r of plan.risk)
493
+ L.push(` ${r.ok ? '✓' : r.blocking ? '✗' : '!'} ${r.label}: ${r.detail}`);
494
+ if (plan.blockers.length) {
495
+ L.push('');
496
+ L.push('阻塞项 (修好才能更新):');
497
+ for (const b of plan.blockers)
498
+ L.push(` - ${b}`);
499
+ }
500
+ if (plan.advisories.length) {
501
+ L.push('');
502
+ L.push('提醒 (不阻塞, 但建议先处理):');
503
+ for (const a of plan.advisories)
504
+ L.push(` - ${a}`);
505
+ L.push(` 建议策略: 等当前 Run 结束后更新 (bolloon update --now --wait)`);
506
+ }
507
+ L.push('');
508
+ L.push('可选: 立即更新 (bolloon update --now) / 等当前 Run 结束 (bolloon update --now --wait) / 取消');
509
+ L.push(`默认: ${plan.defaultStrategy === 'wait' ? '等待当前 Run 结束后更新' : '立即更新'}`);
510
+ return L.join('\n');
511
+ }
512
+ /** 进行中的阶段 (落盘时看到它 = 上次更新被中断; 与 update-state 的 IN_FLIGHT_RUN_STATUSES 同义) */
513
+ exports.IN_FLIGHT_STAGES = ['planned', 'downloading', 'staged', 'switching', 'verifying'];
514
+ /** npm 默认只重试 2 次/10s —— 真网络抖动会让一次干净安装失败 (本机 ECONNRESET 实测)。 */
515
+ exports.NPM_FETCH_RETRY_FLAGS = [
516
+ '--fetch-retries=5', '--fetch-retry-mintimeout=10000', '--fetch-retry-maxtimeout=120000',
517
+ ];
518
+ function defaultRunNpm(args, cwd) {
519
+ const finalArgs = args[0] === 'pack' || args[0] === 'install' ? [...args, ...exports.NPM_FETCH_RETRY_FLAGS] : args;
520
+ const r = (0, child_process_1.spawnSync)('npm', finalArgs, { cwd, encoding: 'utf-8', timeout: 900_000, maxBuffer: 32 * 1024 * 1024 });
521
+ return { code: r.status ?? 1, stdout: r.stdout || '', stderr: r.stderr || '' };
522
+ }
523
+ /** 校验一个解压后的包目录: 版本对得上 + 入口存在。 */
524
+ function validateStagedPackage(dir, target) {
525
+ const pkg = (0, version_info_js_1.readPackageAt)(dir);
526
+ if (!pkg)
527
+ return { ok: false, detail: `${dir}/package.json 读不到` };
528
+ if (pkg.version !== target)
529
+ return { ok: false, detail: `临时目录版本 ${pkg.version} ≠ 目标 ${target}` };
530
+ const entry = path.join(dir, 'dist', 'cli-entry.js');
531
+ if (!fs.existsSync(entry))
532
+ return { ok: false, detail: '包内缺少 dist/cli-entry.js' };
533
+ return { ok: true, detail: `版本 ${pkg.version} + 入口存在` };
534
+ }
535
+ /** 读"磁盘上真的装了什么版本" (不看进程内存), 供切换后验证。 */
536
+ function installedVersionOnDisk(installRoot) {
537
+ return (0, version_info_js_1.readPackageAt)(installRoot)?.version ?? null;
538
+ }
539
+ /**
540
+ * 执行更新。
541
+ *
542
+ * 流水线: 计划(检查+锁) → 下载 tarball 到临时目录并校验 → 切换(npm 替换) → 验证 → 成功/回滚。
543
+ * 任何一步失败: 清理临时目录、保留旧版本、写失败原因、释放锁、用户继续用旧版本。
544
+ */
545
+ async function applyUpdate(opts = {}) {
546
+ const started = Date.now();
547
+ const home = opts.home ?? (await Promise.resolve().then(() => __importStar(require('../setup/setup-store.js')))).resolveBolloonHome();
548
+ const install = opts.installation || (0, version_info_js_1.detectInstallation)({ home });
549
+ /** 落盘"进行中"的阶段 —— 这样进程被 SIGKILL 时盘上会留下证据 (doctor 报"上次更新异常中断") */
550
+ const markInFlight = async (s, detail) => {
551
+ if (!exports.IN_FLIGHT_STAGES.includes(s))
552
+ return;
553
+ try {
554
+ await (0, update_state_js_1.writeUpdateState)({
555
+ lastUpdate: { at: new Date().toISOString(), from, to, status: s, reason: detail },
556
+ }, home);
557
+ }
558
+ catch { /* 阶段留痕写失败不能影响更新本身 */ }
559
+ };
560
+ /**
561
+ * 报阶段 —— **必须 await**: 先在盘上落下"进行中"的阶段, 再去做那件危险的事
562
+ * (否则进程在写状态之前被杀, 盘上就没有"上次更新中断"的证据)。
563
+ */
564
+ const stage = async (s, detail) => {
565
+ try {
566
+ opts.onStage?.(s, detail);
567
+ }
568
+ catch { /* 回调失败不影响流程 */ }
569
+ await markInFlight(s, detail);
570
+ };
571
+ const plan = await buildUpdatePlan({
572
+ home, env: opts.env, force: true, installation: install, registry: opts.registry,
573
+ workloadRiskOverride: opts.workloadRiskOverride,
574
+ });
575
+ const from = plan.currentVersion;
576
+ const to = plan.targetVersion || plan.currentVersion;
577
+ const record = async (r, historyStatus) => {
578
+ const rec = { at: new Date().toISOString(), from: r.from, to: r.to, status: historyStatus, durationMs: r.durationMs, reason: r.reason };
579
+ // 记账失败**不能**把"更新其实成功了"变成向上抛异常 (真被测试 teardown 竞态抓到过:
580
+ // HOME 在写到一半时消失 → rename ENOENT)。失败就如实记进 reason, 结果照常返回。
581
+ try {
582
+ await (0, update_state_js_1.appendUpdateHistory)(rec, home);
583
+ await (0, update_state_js_1.writeUpdateState)({
584
+ lastUpdate: rec,
585
+ lastFailure: r.ok ? null : { at: rec.at, stage: r.failedAt || r.stage, reason: r.reason || '未知原因' },
586
+ needsRestart: r.ok ? r.needsRestart : false,
587
+ currentVersion: r.from,
588
+ }, home);
589
+ }
590
+ catch (e) {
591
+ const note = `状态记录写入失败: ${e?.message || e}`;
592
+ return { ...r, reason: r.reason ? `${r.reason}; ${note}` : note };
593
+ }
594
+ return r;
595
+ };
596
+ if (!plan.targetVersion) {
597
+ await stage('blocked', '没有可执行的更新');
598
+ return record({ stage: 'blocked', ok: false, from, to, durationMs: Date.now() - started, reason: plan.blockers[0] || '已是最新, 无需更新', needsRestart: false }, 'blocked');
599
+ }
600
+ if (plan.blockers.length > 0) {
601
+ await stage('blocked', plan.blockers.join('; '));
602
+ return record({ stage: 'blocked', ok: false, from, to, durationMs: Date.now() - started, reason: `阻塞: ${plan.blockers.join('; ')}`, needsRestart: false }, 'blocked');
603
+ }
604
+ if (opts.strategy === 'wait' && plan.advisories.length > 0) {
605
+ await stage('blocked', '按策略等待当前 Run 结束');
606
+ const reason = `等待当前 Run 结束后更新 (${plan.advisories.length} 项提醒); 待收尾后重新执行 bolloon update --now`;
607
+ await (0, update_state_js_1.appendUpdateHistory)({ at: new Date().toISOString(), from, to, status: 'planned', reason }, home);
608
+ return { stage: 'blocked', ok: false, from, to, durationMs: Date.now() - started, reason, needsRestart: false };
609
+ }
610
+ // 锁 (第二个进程不许同时更新)
611
+ const lock = await (0, update_state_js_1.acquireUpdateLock)({ home, reason: `${from} → ${to}` });
612
+ if (!lock.ok) {
613
+ const held = lock.heldBy;
614
+ await stage('blocked', `已有更新进程 (pid ${held?.pid})`);
615
+ return record({ stage: 'blocked', ok: false, from, to, durationMs: Date.now() - started, reason: `已有更新进程持有锁 (pid ${held?.pid}, ${held?.at})`, needsRestart: false }, 'blocked');
616
+ }
617
+ const tmpRoot = await fsp.mkdtemp(path.join(os.tmpdir(), 'bolloon-update-'));
618
+ const runNpm = opts.runNpm || defaultRunNpm;
619
+ let stagedTarball = null;
620
+ try {
621
+ // 1. 下载 tarball 到临时目录 (不动现有安装)
622
+ await stage('downloading', `npm pack ${version_info_js_1.PKG_NAME}@${to}`);
623
+ const packed = runNpm(['pack', `${version_info_js_1.PKG_NAME}@${to}`, '--pack-destination', tmpRoot, '--loglevel=error'], tmpRoot);
624
+ if (packed.code !== 0) {
625
+ throw Object.assign(new Error(`下载 ${version_info_js_1.PKG_NAME}@${to} 失败: ${(packed.stderr || packed.stdout).trim().slice(0, 400)}`), { stage: 'downloading' });
626
+ }
627
+ const tarballs = (await fsp.readdir(tmpRoot)).filter((f) => f.endsWith('.tgz'));
628
+ if (tarballs.length === 0)
629
+ throw Object.assign(new Error('npm pack 没有产出 tarball'), { stage: 'downloading' });
630
+ stagedTarball = path.join(tmpRoot, tarballs[0]);
631
+ // 2. 解压 + 校验包内容 (版本 + 入口)
632
+ await stage('staged', `解压并校验 ${path.basename(stagedTarball)}`);
633
+ const extractDir = path.join(tmpRoot, 'extract');
634
+ await fsp.mkdir(extractDir, { recursive: true });
635
+ const tar = (0, child_process_1.spawnSync)('tar', ['-xzf', stagedTarball, '-C', extractDir], { encoding: 'utf-8', timeout: 120_000 });
636
+ if (tar.status !== 0)
637
+ throw Object.assign(new Error(`解压失败: ${(tar.stderr || '').slice(0, 300)}`), { stage: 'staged' });
638
+ const stagedCheck = validateStagedPackage(path.join(extractDir, 'package'), to);
639
+ if (!stagedCheck.ok)
640
+ throw Object.assign(new Error(`目标包校验失败: ${stagedCheck.detail}`), { stage: 'staged' });
641
+ // 3. 切换 (npm 完成替换; 旧版本在替换成功前不会消失)
642
+ await stage('switching', `npm install -g ${version_info_js_1.PKG_NAME}@${to}`);
643
+ const installed = runNpm(['install', '-g', `${version_info_js_1.PKG_NAME}@${to}`, '--no-fund', '--no-audit', '--loglevel=error'], os.tmpdir());
644
+ if (installed.code !== 0) {
645
+ throw Object.assign(new Error(`npm 安装失败: ${(installed.stderr || installed.stdout).trim().slice(0, 400)}`), { stage: 'switching' });
646
+ }
647
+ // 4. 验证: 磁盘版本 + 新入口真能启动 + 健康检查
648
+ await stage('verifying', '核对磁盘版本并试启新入口');
649
+ const verify = opts.verifyInstall || defaultVerifyInstall;
650
+ const ok = await verify(to, home);
651
+ if (!ok)
652
+ throw Object.assign(new Error(`切换后验证失败: 新版本 ${to} 未能正确启动`), { stage: 'verifying' });
653
+ await stage('succeeded', `已更新到 ${to}`);
654
+ const out = {
655
+ stage: 'succeeded', ok: true, from, to, durationMs: Date.now() - started, needsRestart: true, stagedTarball,
656
+ };
657
+ await record(out, 'succeeded');
658
+ return out;
659
+ }
660
+ catch (e) {
661
+ const failureStage = e?.stage || 'failed';
662
+ const reason = e?.message || String(e);
663
+ await stage(failureStage, reason);
664
+ // 失败处理: 保留旧版本 → 能回滚就回滚 → 写原因 → 释放锁
665
+ let finalStage = 'failed';
666
+ let finalReason = reason;
667
+ try {
668
+ const nowVersion = installedVersionOnDisk(install.packageRoot);
669
+ if (install.method === 'npm-global' && nowVersion && nowVersion !== from && nowVersion !== to) {
670
+ await stage('rolled_back', `检测到半更新 (磁盘版本 ${nowVersion}), 回滚到 ${from}`);
671
+ const rb = runNpm(['install', '-g', `${version_info_js_1.PKG_NAME}@${from}`, '--no-fund', '--no-audit', '--loglevel=error'], os.tmpdir());
672
+ const after = installedVersionOnDisk(install.packageRoot);
673
+ if (rb.code === 0 && after === from) {
674
+ finalStage = 'rolled_back';
675
+ finalReason = `${reason}; 已回滚到 ${from}`;
676
+ }
677
+ else {
678
+ finalReason = `${reason}; 回滚也未成功 (磁盘版本 ${after || 'unknown'}) — 请手动: npm install -g ${version_info_js_1.PKG_NAME}@${from}`;
679
+ }
680
+ }
681
+ else if (nowVersion === to && failureStage === 'verifying') {
682
+ // 装上了但验证没过: 保留新版本但如实报失败, 并给出回滚指令
683
+ finalReason = `${reason}; 磁盘版本已是 ${to}, 如需回退: npm install -g ${version_info_js_1.PKG_NAME}@${from}`;
684
+ }
685
+ }
686
+ catch (e2) {
687
+ finalReason = `${reason}; 回滚过程出错: ${e2?.message || e2}`;
688
+ }
689
+ const out = {
690
+ stage: finalStage, failedAt: failureStage, ok: false, from, to, durationMs: Date.now() - started,
691
+ reason: finalReason, needsRestart: false, stagedTarball,
692
+ };
693
+ await record(out, finalStage === 'rolled_back' ? 'rolled_back' : 'failed');
694
+ return out;
695
+ }
696
+ finally {
697
+ // 临时目录清理 (成功/失败都清)
698
+ try {
699
+ await fsp.rm(tmpRoot, { recursive: true, force: true });
700
+ }
701
+ catch { /* 忽略 */ }
702
+ await (0, update_state_js_1.releaseUpdateLock)(home);
703
+ }
704
+ }
705
+ async function defaultVerifyInstall(target, home) {
706
+ const install = (0, version_info_js_1.detectInstallation)({ home });
707
+ const onDisk = installedVersionOnDisk(install.packageRoot);
708
+ if (onDisk !== target)
709
+ return false;
710
+ const entry = path.join(install.packageRoot, 'dist', 'cli-entry.js');
711
+ if (!fs.existsSync(entry))
712
+ return false;
713
+ const r = (0, child_process_1.spawnSync)(process.execPath, [entry, '--version', '--json'], { encoding: 'utf-8', timeout: 120_000, maxBuffer: 8 * 1024 * 1024 });
714
+ if (r.status !== 0)
715
+ return false;
716
+ const parsed = parseJsonFromStdout(String(r.stdout || ''));
717
+ return parsed?.packageVersion === target;
718
+ }
719
+ async function readUpdateStatus(opts = {}) {
720
+ const home = opts.home ?? (await Promise.resolve().then(() => __importStar(require('../setup/setup-store.js')))).resolveBolloonHome();
721
+ const st = await (0, update_state_js_1.readUpdateState)(home);
722
+ const prefs = await (0, update_state_js_1.readUpdatePrefs)({ home, env: opts.env });
723
+ const lock = (0, update_state_js_1.readUpdateLock)(home);
724
+ const install = (0, version_info_js_1.detectInstallation)({ home });
725
+ const pkg = (0, version_info_js_1.readPackageAt)(install.packageRoot);
726
+ return {
727
+ currentVersion: isKnownVersion(pkg?.version) ? String(pkg?.version) : st.currentVersion,
728
+ latestVersion: st.latestVersion,
729
+ channel: prefs.channel,
730
+ installMethod: install.method,
731
+ installDir: install.installDir,
732
+ entryPath: install.entryPath,
733
+ lastCheckAt: st.lastCheckAt,
734
+ lastCheckStatus: st.lastCheckStatus,
735
+ lastCheckReason: st.lastCheckReason,
736
+ lastUpdate: st.lastUpdate,
737
+ lastFailure: st.lastFailure,
738
+ needsRestart: st.needsRestart,
739
+ prefs,
740
+ lock: lock ? { ...lock, stale: (0, update_state_js_1.lockIsStale)(lock) } : null,
741
+ };
742
+ }
743
+ async function readHistory(limit = 10, home) {
744
+ const h = home ?? (await Promise.resolve().then(() => __importStar(require('../setup/setup-store.js')))).resolveBolloonHome();
745
+ return (0, update_state_js_1.readUpdateHistory)(limit, h);
746
+ }
747
+ function renderHistory(records) {
748
+ if (records.length === 0)
749
+ return '没有更新历史记录。';
750
+ const L = ['时间 · 当前版本 → 目标版本 · 结果 · 耗时 · 原因'];
751
+ for (const r of records) {
752
+ const ms = r.durationMs != null ? `${(r.durationMs / 1000).toFixed(1)}s` : '-';
753
+ L.push(`${r.at} · ${r.from} → ${r.to} · ${r.status} · ${ms}${r.reason ? ` · ${r.reason}` : ''}`);
754
+ }
755
+ return L.join('\n');
756
+ }
757
+ /** 启动后台检查用的摘要 (供 --version 显示)。 */
758
+ async function updateSummaryFor(home) {
759
+ const h = home ?? (await Promise.resolve().then(() => __importStar(require('../setup/setup-store.js')))).resolveBolloonHome();
760
+ const st = await (0, update_state_js_1.readUpdateState)(h);
761
+ return {
762
+ lastCheckAt: st.lastCheckAt,
763
+ lastCheckStatus: st.lastCheckStatus,
764
+ lastCheckReason: st.lastCheckReason,
765
+ latestVersion: st.latestVersion,
766
+ lastUpdate: st.lastUpdate ? { at: st.lastUpdate.at, from: st.lastUpdate.from, to: st.lastUpdate.to, status: st.lastUpdate.status, reason: st.lastUpdate.reason } : null,
767
+ needsRestart: st.needsRestart,
768
+ };
769
+ }
770
+ //# sourceMappingURL=update-manager.js.map