@bolloon/bolloon-agent 0.4.28 → 0.4.30

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 (473) hide show
  1. package/bin/bolloon.cjs +18 -148
  2. package/bin/bolloon.cmd +6 -3
  3. package/dist/agents/contacts/chain.js +579 -0
  4. package/dist/agents/contacts/cli.js +158 -0
  5. package/dist/agents/contacts/consent.js +124 -0
  6. package/dist/agents/contacts/grant-payload.js +45 -0
  7. package/dist/agents/contacts/grants.js +451 -0
  8. package/dist/agents/contacts/policy.js +264 -0
  9. package/dist/agents/contacts/preview-types.js +6 -0
  10. package/dist/agents/contacts/providers.js +341 -0
  11. package/dist/agents/contacts/store.js +326 -0
  12. package/dist/agents/contacts/tools.js +154 -0
  13. package/dist/agents/contacts/types.js +148 -0
  14. package/dist/agents/pi-sdk-tools.js +3 -1
  15. package/dist/agents/pi-sdk.js +14 -1
  16. package/dist/cli/update-commands.js +349 -0
  17. package/dist/cli-entry.js +41 -55
  18. package/dist/electron-build/agents/agent-gateway.js +169 -0
  19. package/dist/electron-build/agents/agent-gateway.js.map +1 -0
  20. package/dist/electron-build/agents/agent-identity-store.js +212 -0
  21. package/dist/electron-build/agents/agent-identity-store.js.map +1 -0
  22. package/dist/electron-build/agents/agent-identity.js +196 -0
  23. package/dist/electron-build/agents/agent-identity.js.map +1 -0
  24. package/dist/electron-build/agents/agent-manifest-protocol.js +151 -0
  25. package/dist/electron-build/agents/agent-manifest-protocol.js.map +1 -0
  26. package/dist/electron-build/agents/agent-registry.js +217 -0
  27. package/dist/electron-build/agents/agent-registry.js.map +1 -0
  28. package/dist/electron-build/agents/agent-reputation.js +60 -0
  29. package/dist/electron-build/agents/agent-reputation.js.map +1 -0
  30. package/dist/electron-build/agents/agent-service-client.js +186 -0
  31. package/dist/electron-build/agents/agent-service-client.js.map +1 -0
  32. package/dist/electron-build/agents/browser-cdp.js +765 -0
  33. package/dist/electron-build/agents/browser-cdp.js.map +1 -0
  34. package/dist/electron-build/agents/computer-use.js +341 -0
  35. package/dist/electron-build/agents/computer-use.js.map +1 -0
  36. package/dist/electron-build/agents/constraint-layer.js +210 -0
  37. package/dist/electron-build/agents/constraint-layer.js.map +1 -0
  38. package/dist/electron-build/agents/contacts/chain.js +619 -0
  39. package/dist/electron-build/agents/contacts/chain.js.map +1 -0
  40. package/dist/electron-build/agents/contacts/consent.js +163 -0
  41. package/dist/electron-build/agents/contacts/consent.js.map +1 -0
  42. package/dist/electron-build/agents/contacts/grant-payload.js +52 -0
  43. package/dist/electron-build/agents/contacts/grant-payload.js.map +1 -0
  44. package/dist/electron-build/agents/contacts/grants.js +500 -0
  45. package/dist/electron-build/agents/contacts/grants.js.map +1 -0
  46. package/dist/electron-build/agents/contacts/policy.js +271 -0
  47. package/dist/electron-build/agents/contacts/policy.js.map +1 -0
  48. package/dist/electron-build/agents/contacts/preview-types.js +8 -0
  49. package/dist/electron-build/agents/contacts/preview-types.js.map +1 -0
  50. package/dist/electron-build/agents/contacts/providers.js +384 -0
  51. package/dist/electron-build/agents/contacts/providers.js.map +1 -0
  52. package/dist/electron-build/agents/contacts/store.js +370 -0
  53. package/dist/electron-build/agents/contacts/store.js.map +1 -0
  54. package/dist/electron-build/agents/contacts/tools.js +159 -0
  55. package/dist/electron-build/agents/contacts/tools.js.map +1 -0
  56. package/dist/electron-build/agents/contacts/types.js +166 -0
  57. package/dist/electron-build/agents/contacts/types.js.map +1 -0
  58. package/dist/electron-build/agents/decision-store.js +292 -0
  59. package/dist/electron-build/agents/decision-store.js.map +1 -0
  60. package/dist/electron-build/agents/deny-pipeline.js +125 -0
  61. package/dist/electron-build/agents/deny-pipeline.js.map +1 -0
  62. package/dist/electron-build/agents/economic-policy.js +172 -0
  63. package/dist/electron-build/agents/economic-policy.js.map +1 -0
  64. package/dist/electron-build/agents/error-classifier.js +125 -0
  65. package/dist/electron-build/agents/error-classifier.js.map +1 -0
  66. package/dist/electron-build/agents/execution-supervisor.js +539 -0
  67. package/dist/electron-build/agents/execution-supervisor.js.map +1 -0
  68. package/dist/electron-build/agents/external-events.js +171 -0
  69. package/dist/electron-build/agents/external-events.js.map +1 -0
  70. package/dist/electron-build/agents/gateway-join.js +315 -0
  71. package/dist/electron-build/agents/gateway-join.js.map +1 -0
  72. package/dist/electron-build/agents/gateway-network.js +505 -0
  73. package/dist/electron-build/agents/gateway-network.js.map +1 -0
  74. package/dist/electron-build/agents/goal-criteria.js +133 -0
  75. package/dist/electron-build/agents/goal-criteria.js.map +1 -0
  76. package/dist/electron-build/agents/goal-resume.js +364 -0
  77. package/dist/electron-build/agents/goal-resume.js.map +1 -0
  78. package/dist/electron-build/agents/goal-store.js +587 -0
  79. package/dist/electron-build/agents/goal-store.js.map +1 -0
  80. package/dist/electron-build/agents/intent-classifier.js +104 -0
  81. package/dist/electron-build/agents/intent-classifier.js.map +1 -0
  82. package/dist/electron-build/agents/iroh-secret.js +70 -0
  83. package/dist/electron-build/agents/iroh-secret.js.map +1 -0
  84. package/dist/electron-build/agents/loop-review.js +101 -0
  85. package/dist/electron-build/agents/loop-review.js.map +1 -0
  86. package/dist/electron-build/agents/memory-recall.js +154 -0
  87. package/dist/electron-build/agents/memory-recall.js.map +1 -0
  88. package/dist/electron-build/agents/p2p-document-tools.js +328 -0
  89. package/dist/electron-build/agents/p2p-document-tools.js.map +1 -0
  90. package/dist/electron-build/agents/parse-tool-call.js +564 -0
  91. package/dist/electron-build/agents/parse-tool-call.js.map +1 -0
  92. package/dist/electron-build/agents/patch-tool.js +205 -0
  93. package/dist/electron-build/agents/patch-tool.js.map +1 -0
  94. package/dist/electron-build/agents/payment-approval.js +183 -0
  95. package/dist/electron-build/agents/payment-approval.js.map +1 -0
  96. package/dist/electron-build/agents/payment-gate.js +139 -0
  97. package/dist/electron-build/agents/payment-gate.js.map +1 -0
  98. package/dist/electron-build/agents/permission-mode.js +124 -0
  99. package/dist/electron-build/agents/permission-mode.js.map +1 -0
  100. package/dist/electron-build/agents/pi-harness.js +268 -0
  101. package/dist/electron-build/agents/pi-harness.js.map +1 -0
  102. package/dist/electron-build/agents/pi-sdk-session-factory.js +117 -0
  103. package/dist/electron-build/agents/pi-sdk-session-factory.js.map +1 -0
  104. package/dist/electron-build/agents/pi-sdk-session-manager.js +335 -0
  105. package/dist/electron-build/agents/pi-sdk-session-manager.js.map +1 -0
  106. package/dist/electron-build/agents/pi-sdk-tools.js +4042 -0
  107. package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -0
  108. package/dist/electron-build/agents/pi-sdk-types.js +17 -0
  109. package/dist/electron-build/agents/pi-sdk-types.js.map +1 -0
  110. package/dist/electron-build/agents/pi-sdk.js +3335 -0
  111. package/dist/electron-build/agents/pi-sdk.js.map +1 -0
  112. package/dist/electron-build/agents/plan-store.js +212 -0
  113. package/dist/electron-build/agents/plan-store.js.map +1 -0
  114. package/dist/electron-build/agents/pre-tool-validator.js +200 -0
  115. package/dist/electron-build/agents/pre-tool-validator.js.map +1 -0
  116. package/dist/electron-build/agents/process-runner.js +148 -0
  117. package/dist/electron-build/agents/process-runner.js.map +1 -0
  118. package/dist/electron-build/agents/react-loop.js +131 -0
  119. package/dist/electron-build/agents/react-loop.js.map +1 -0
  120. package/dist/electron-build/agents/resource-store.js +180 -0
  121. package/dist/electron-build/agents/resource-store.js.map +1 -0
  122. package/dist/electron-build/agents/resource-token.js +118 -0
  123. package/dist/electron-build/agents/resource-token.js.map +1 -0
  124. package/dist/electron-build/agents/resource-wallet.js +84 -0
  125. package/dist/electron-build/agents/resource-wallet.js.map +1 -0
  126. package/dist/electron-build/agents/run-store.js +854 -0
  127. package/dist/electron-build/agents/run-store.js.map +1 -0
  128. package/dist/electron-build/agents/runner-resolver.js +267 -0
  129. package/dist/electron-build/agents/runner-resolver.js.map +1 -0
  130. package/dist/electron-build/agents/session-store.js +294 -0
  131. package/dist/electron-build/agents/session-store.js.map +1 -0
  132. package/dist/electron-build/agents/shell-guard.js +465 -0
  133. package/dist/electron-build/agents/shell-guard.js.map +1 -0
  134. package/dist/electron-build/agents/shell-tool.js +102 -0
  135. package/dist/electron-build/agents/shell-tool.js.map +1 -0
  136. package/dist/electron-build/agents/skill-loader.js +216 -0
  137. package/dist/electron-build/agents/skill-loader.js.map +1 -0
  138. package/dist/electron-build/agents/skill-readiness.js +174 -0
  139. package/dist/electron-build/agents/skill-readiness.js.map +1 -0
  140. package/dist/electron-build/agents/skill-share.js +394 -0
  141. package/dist/electron-build/agents/skill-share.js.map +1 -0
  142. package/dist/electron-build/agents/skill-supervisor-link.js +75 -0
  143. package/dist/electron-build/agents/skill-supervisor-link.js.map +1 -0
  144. package/dist/electron-build/agents/skill-writer.js +347 -0
  145. package/dist/electron-build/agents/skill-writer.js.map +1 -0
  146. package/dist/electron-build/agents/skills-manager.js +763 -0
  147. package/dist/electron-build/agents/skills-manager.js.map +1 -0
  148. package/dist/electron-build/agents/supervisor-host.js +294 -0
  149. package/dist/electron-build/agents/supervisor-host.js.map +1 -0
  150. package/dist/electron-build/agents/task/local-seller.js +188 -0
  151. package/dist/electron-build/agents/task/local-seller.js.map +1 -0
  152. package/dist/electron-build/agents/task/report-card.js +152 -0
  153. package/dist/electron-build/agents/task/report-card.js.map +1 -0
  154. package/dist/electron-build/agents/task/resource-advisor.js +222 -0
  155. package/dist/electron-build/agents/task/resource-advisor.js.map +1 -0
  156. package/dist/electron-build/agents/task/task-budget.js +111 -0
  157. package/dist/electron-build/agents/task/task-budget.js.map +1 -0
  158. package/dist/electron-build/agents/task/task-runner.js +670 -0
  159. package/dist/electron-build/agents/task/task-runner.js.map +1 -0
  160. package/dist/electron-build/agents/task-state.js +266 -0
  161. package/dist/electron-build/agents/task-state.js.map +1 -0
  162. package/dist/electron-build/agents/tool-registry.js +141 -0
  163. package/dist/electron-build/agents/tool-registry.js.map +1 -0
  164. package/dist/electron-build/agents/treasury-bridge.js +165 -0
  165. package/dist/electron-build/agents/treasury-bridge.js.map +1 -0
  166. package/dist/electron-build/agents/user-questions.js +223 -0
  167. package/dist/electron-build/agents/user-questions.js.map +1 -0
  168. package/dist/electron-build/agents/verify-recipe.js +90 -0
  169. package/dist/electron-build/agents/verify-recipe.js.map +1 -0
  170. package/dist/electron-build/agents/workflow-engine.js +222 -0
  171. package/dist/electron-build/agents/workflow-engine.js.map +1 -0
  172. package/dist/electron-build/agents/workflow-pivot-loop.js +988 -0
  173. package/dist/electron-build/agents/workflow-pivot-loop.js.map +1 -0
  174. package/dist/electron-build/agents/write-staging.js +133 -0
  175. package/dist/electron-build/agents/write-staging.js.map +1 -0
  176. package/dist/electron-build/agents/x402/goal-run-bridge.js +115 -0
  177. package/dist/electron-build/agents/x402/goal-run-bridge.js.map +1 -0
  178. package/dist/electron-build/agents/x402/milestone-settlement.js +163 -0
  179. package/dist/electron-build/agents/x402/milestone-settlement.js.map +1 -0
  180. package/dist/electron-build/agents/x402/paid-info-protocol.js +274 -0
  181. package/dist/electron-build/agents/x402/paid-info-protocol.js.map +1 -0
  182. package/dist/electron-build/agents/x402/paid-info-store.js +409 -0
  183. package/dist/electron-build/agents/x402/paid-info-store.js.map +1 -0
  184. package/dist/electron-build/agents/x402/paid-info-tools.js +346 -0
  185. package/dist/electron-build/agents/x402/paid-info-tools.js.map +1 -0
  186. package/dist/electron-build/agents/x402/payment-recovery.js +330 -0
  187. package/dist/electron-build/agents/x402/payment-recovery.js.map +1 -0
  188. package/dist/electron-build/agents/x402/resource-contract.js +533 -0
  189. package/dist/electron-build/agents/x402/resource-contract.js.map +1 -0
  190. package/dist/electron-build/agents/x402/settlement-state.js +432 -0
  191. package/dist/electron-build/agents/x402/settlement-state.js.map +1 -0
  192. package/dist/electron-build/agents/x402/trade.js +294 -0
  193. package/dist/electron-build/agents/x402/trade.js.map +1 -0
  194. package/dist/electron-build/agents/x402/transaction-protocol.js +109 -0
  195. package/dist/electron-build/agents/x402/transaction-protocol.js.map +1 -0
  196. package/dist/electron-build/agents/x402/transaction-store.js +404 -0
  197. package/dist/electron-build/agents/x402/transaction-store.js.map +1 -0
  198. package/dist/electron-build/agents/x402/x402Pay.js +377 -0
  199. package/dist/electron-build/agents/x402/x402Pay.js.map +1 -0
  200. package/dist/electron-build/bollharness-integration/context-router-judgment.js +269 -0
  201. package/dist/electron-build/bollharness-integration/context-router-judgment.js.map +1 -0
  202. package/dist/electron-build/bollharness-integration/context-router.js +584 -0
  203. package/dist/electron-build/bollharness-integration/context-router.js.map +1 -0
  204. package/dist/electron-build/bollharness-integration/gate-state-machine.js +362 -0
  205. package/dist/electron-build/bollharness-integration/gate-state-machine.js.map +1 -0
  206. package/dist/electron-build/bollharness-integration/gate-transition-hooks.js +136 -0
  207. package/dist/electron-build/bollharness-integration/gate-transition-hooks.js.map +1 -0
  208. package/dist/electron-build/bollharness-integration/guard-checker.js +400 -0
  209. package/dist/electron-build/bollharness-integration/guard-checker.js.map +1 -0
  210. package/dist/electron-build/bollharness-integration/index.js +123 -0
  211. package/dist/electron-build/bollharness-integration/index.js.map +1 -0
  212. package/dist/electron-build/bollharness-integration/integration.js +531 -0
  213. package/dist/electron-build/bollharness-integration/integration.js.map +1 -0
  214. package/dist/electron-build/bollharness-integration/skill-adapter.js +608 -0
  215. package/dist/electron-build/bollharness-integration/skill-adapter.js.map +1 -0
  216. package/dist/electron-build/bootstrap/bootstrap.js +173 -0
  217. package/dist/electron-build/bootstrap/bootstrap.js.map +1 -0
  218. package/dist/electron-build/bootstrap/context-collector.js +358 -0
  219. package/dist/electron-build/bootstrap/context-collector.js.map +1 -0
  220. package/dist/electron-build/bootstrap/context-hierarchy.js +262 -0
  221. package/dist/electron-build/bootstrap/context-hierarchy.js.map +1 -0
  222. package/dist/electron-build/bootstrap/context-manager.js +211 -0
  223. package/dist/electron-build/bootstrap/context-manager.js.map +1 -0
  224. package/dist/electron-build/bootstrap/context-os.js +277 -0
  225. package/dist/electron-build/bootstrap/context-os.js.map +1 -0
  226. package/dist/electron-build/bootstrap/event-log.js +203 -0
  227. package/dist/electron-build/bootstrap/event-log.js.map +1 -0
  228. package/dist/electron-build/bootstrap/exhaust-scrubber.js +277 -0
  229. package/dist/electron-build/bootstrap/exhaust-scrubber.js.map +1 -0
  230. package/dist/electron-build/bootstrap/lifecycle-hooks.js +282 -0
  231. package/dist/electron-build/bootstrap/lifecycle-hooks.js.map +1 -0
  232. package/dist/electron-build/bootstrap/memory-compressor.js +377 -0
  233. package/dist/electron-build/bootstrap/memory-compressor.js.map +1 -0
  234. package/dist/electron-build/bootstrap/persona-loader.js +219 -0
  235. package/dist/electron-build/bootstrap/persona-loader.js.map +1 -0
  236. package/dist/electron-build/bootstrap/project-context.js +162 -0
  237. package/dist/electron-build/bootstrap/project-context.js.map +1 -0
  238. package/dist/electron-build/bootstrap/project-state.js +205 -0
  239. package/dist/electron-build/bootstrap/project-state.js.map +1 -0
  240. package/dist/electron-build/bootstrap/session-window.js +162 -0
  241. package/dist/electron-build/bootstrap/session-window.js.map +1 -0
  242. package/dist/electron-build/bootstrap/vector-index.js +291 -0
  243. package/dist/electron-build/bootstrap/vector-index.js.map +1 -0
  244. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/cancelOrder.js +22 -0
  245. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/cancelOrder.js.map +1 -0
  246. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/clobShared.js +86 -0
  247. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/clobShared.js.map +1 -0
  248. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/createOrder.js +37 -0
  249. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/createOrder.js.map +1 -0
  250. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/getMarket.js +20 -0
  251. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/getMarket.js.map +1 -0
  252. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/getOrders.js +29 -0
  253. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/getOrders.js.map +1 -0
  254. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/listMarkets.js +28 -0
  255. package/dist/electron-build/constraint-runtime/src/tools/PolymarketSDK/listMarkets.js.map +1 -0
  256. package/dist/electron-build/constraint-runtime/src/tools/SafeSDK/deploySafe.js +10 -0
  257. package/dist/electron-build/constraint-runtime/src/tools/SafeSDK/deploySafe.js.map +1 -0
  258. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/autoPay.js +68 -0
  259. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/autoPay.js.map +1 -0
  260. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/createWallet.js +14 -0
  261. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/createWallet.js.map +1 -0
  262. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/getBalance.js +17 -0
  263. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/getBalance.js.map +1 -0
  264. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/importWallet.js +59 -0
  265. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/importWallet.js.map +1 -0
  266. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/sendTransaction.js +29 -0
  267. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/sendTransaction.js.map +1 -0
  268. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/signMessage.js +14 -0
  269. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/signMessage.js.map +1 -0
  270. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/transferToken.js +29 -0
  271. package/dist/electron-build/constraint-runtime/src/tools/WalletTools/transferToken.js.map +1 -0
  272. package/dist/electron-build/constraints/index.js +11 -0
  273. package/dist/electron-build/constraints/index.js.map +1 -0
  274. package/dist/electron-build/context-compaction/auto-compact.js +182 -0
  275. package/dist/electron-build/context-compaction/auto-compact.js.map +1 -0
  276. package/dist/electron-build/context-compaction/budget-gate.js +32 -0
  277. package/dist/electron-build/context-compaction/budget-gate.js.map +1 -0
  278. package/dist/electron-build/context-compaction/budget-reduce.js +39 -0
  279. package/dist/electron-build/context-compaction/budget-reduce.js.map +1 -0
  280. package/dist/electron-build/context-compaction/context-collapse.js +71 -0
  281. package/dist/electron-build/context-compaction/context-collapse.js.map +1 -0
  282. package/dist/electron-build/context-compaction/index.js +38 -0
  283. package/dist/electron-build/context-compaction/index.js.map +1 -0
  284. package/dist/electron-build/context-compaction/microcompact.js +55 -0
  285. package/dist/electron-build/context-compaction/microcompact.js.map +1 -0
  286. package/dist/electron-build/context-compaction/pipeline.js +128 -0
  287. package/dist/electron-build/context-compaction/pipeline.js.map +1 -0
  288. package/dist/electron-build/context-compaction/snip.js +50 -0
  289. package/dist/electron-build/context-compaction/snip.js.map +1 -0
  290. package/dist/electron-build/context-compaction/token-estimator.js +40 -0
  291. package/dist/electron-build/context-compaction/token-estimator.js.map +1 -0
  292. package/dist/electron-build/context-compaction/types.js +21 -0
  293. package/dist/electron-build/context-compaction/types.js.map +1 -0
  294. package/dist/electron-build/cron/tick-lock.js +247 -0
  295. package/dist/electron-build/cron/tick-lock.js.map +1 -0
  296. package/dist/electron-build/documents/reader.js +131 -0
  297. package/dist/electron-build/documents/reader.js.map +1 -0
  298. package/dist/electron-build/documents/store.js +220 -0
  299. package/dist/electron-build/documents/store.js.map +1 -0
  300. package/dist/electron-build/external-engines/delegate-handle.js +76 -0
  301. package/dist/electron-build/external-engines/delegate-handle.js.map +1 -0
  302. package/dist/electron-build/external-engines/delegate.js +225 -0
  303. package/dist/electron-build/external-engines/delegate.js.map +1 -0
  304. package/dist/electron-build/external-engines/discovery.js +448 -0
  305. package/dist/electron-build/external-engines/discovery.js.map +1 -0
  306. package/dist/electron-build/external-engines/types.js +13 -0
  307. package/dist/electron-build/external-engines/types.js.map +1 -0
  308. package/dist/electron-build/hooks/hooks-engine.js +367 -0
  309. package/dist/electron-build/hooks/hooks-engine.js.map +1 -0
  310. package/dist/electron-build/judgeness/reflect.js +100 -0
  311. package/dist/electron-build/judgeness/reflect.js.map +1 -0
  312. package/dist/electron-build/judgeness/store.js +536 -0
  313. package/dist/electron-build/judgeness/store.js.map +1 -0
  314. package/dist/electron-build/judgeness/types.js +21 -0
  315. package/dist/electron-build/judgeness/types.js.map +1 -0
  316. package/dist/electron-build/llm/config-store.js +551 -0
  317. package/dist/electron-build/llm/config-store.js.map +1 -0
  318. package/dist/electron-build/llm/error-lessons.js +76 -0
  319. package/dist/electron-build/llm/error-lessons.js.map +1 -0
  320. package/dist/electron-build/llm/pi-ai.js +830 -0
  321. package/dist/electron-build/llm/pi-ai.js.map +1 -0
  322. package/dist/electron-build/llm/system-prompt/registry.js +318 -0
  323. package/dist/electron-build/llm/system-prompt/registry.js.map +1 -0
  324. package/dist/electron-build/llm/system-prompt/strip-hibsml.js +55 -0
  325. package/dist/electron-build/llm/system-prompt/strip-hibsml.js.map +1 -0
  326. package/dist/electron-build/locales/en.js +32 -0
  327. package/dist/electron-build/locales/en.js.map +1 -0
  328. package/dist/electron-build/locales/zh.js +30 -0
  329. package/dist/electron-build/locales/zh.js.map +1 -0
  330. package/dist/electron-build/lsp/lsp-manager.js +327 -0
  331. package/dist/electron-build/lsp/lsp-manager.js.map +1 -0
  332. package/dist/electron-build/lsp/lsp-tools.js +226 -0
  333. package/dist/electron-build/lsp/lsp-tools.js.map +1 -0
  334. package/dist/electron-build/migration/external-agent-migrator.js +451 -0
  335. package/dist/electron-build/migration/external-agent-migrator.js.map +1 -0
  336. package/dist/electron-build/network/agent-network.js +775 -0
  337. package/dist/electron-build/network/agent-network.js.map +1 -0
  338. package/dist/electron-build/network/goal-event-bridge.js +62 -0
  339. package/dist/electron-build/network/goal-event-bridge.js.map +1 -0
  340. package/dist/electron-build/network/iroh-integration.js +117 -0
  341. package/dist/electron-build/network/iroh-integration.js.map +1 -0
  342. package/dist/electron-build/network/iroh-transport.js +550 -0
  343. package/dist/electron-build/network/iroh-transport.js.map +1 -0
  344. package/dist/electron-build/network/p2p.js +1103 -0
  345. package/dist/electron-build/network/p2p.js.map +1 -0
  346. package/dist/electron-build/network/storage/adapters/json-adapter.js +416 -0
  347. package/dist/electron-build/network/storage/adapters/json-adapter.js.map +1 -0
  348. package/dist/electron-build/network/storage/types.js +18 -0
  349. package/dist/electron-build/network/storage/types.js.map +1 -0
  350. package/dist/electron-build/orbitdb/agent-tools.js +402 -0
  351. package/dist/electron-build/orbitdb/agent-tools.js.map +1 -0
  352. package/dist/electron-build/orbitdb/cid-database.js +284 -0
  353. package/dist/electron-build/orbitdb/cid-database.js.map +1 -0
  354. package/dist/electron-build/orbitdb/context-store.js +99 -0
  355. package/dist/electron-build/orbitdb/context-store.js.map +1 -0
  356. package/dist/electron-build/orbitdb/ipfs-node.js +120 -0
  357. package/dist/electron-build/orbitdb/ipfs-node.js.map +1 -0
  358. package/dist/electron-build/orbitdb/kanban-store.js +299 -0
  359. package/dist/electron-build/orbitdb/kanban-store.js.map +1 -0
  360. package/dist/electron-build/orbitdb/task-store.js +155 -0
  361. package/dist/electron-build/orbitdb/task-store.js.map +1 -0
  362. package/dist/electron-build/orbitdb/trajectory-store.js +194 -0
  363. package/dist/electron-build/orbitdb/trajectory-store.js.map +1 -0
  364. package/dist/electron-build/orbitdb/ui-cid.js +77 -0
  365. package/dist/electron-build/orbitdb/ui-cid.js.map +1 -0
  366. package/dist/electron-build/pi-ecosystem-a2ui/index.js +89 -0
  367. package/dist/electron-build/pi-ecosystem-a2ui/index.js.map +1 -0
  368. package/dist/electron-build/pi-ecosystem-goals/index.js +512 -0
  369. package/dist/electron-build/pi-ecosystem-goals/index.js.map +1 -0
  370. package/dist/electron-build/pi-ecosystem-judgment/adaptive-scan.js +325 -0
  371. package/dist/electron-build/pi-ecosystem-judgment/adaptive-scan.js.map +1 -0
  372. package/dist/electron-build/pi-ecosystem-judgment/causal-judge.js +492 -0
  373. package/dist/electron-build/pi-ecosystem-judgment/causal-judge.js.map +1 -0
  374. package/dist/electron-build/pi-ecosystem-judgment/cleanup.js +167 -0
  375. package/dist/electron-build/pi-ecosystem-judgment/cleanup.js.map +1 -0
  376. package/dist/electron-build/pi-ecosystem-judgment/decision.js +321 -0
  377. package/dist/electron-build/pi-ecosystem-judgment/decision.js.map +1 -0
  378. package/dist/electron-build/pi-ecosystem-judgment/detect-hook.js +175 -0
  379. package/dist/electron-build/pi-ecosystem-judgment/detect-hook.js.map +1 -0
  380. package/dist/electron-build/pi-ecosystem-judgment/distill-prompt.js +232 -0
  381. package/dist/electron-build/pi-ecosystem-judgment/distill-prompt.js.map +1 -0
  382. package/dist/electron-build/pi-ecosystem-judgment/distillation.js +304 -0
  383. package/dist/electron-build/pi-ecosystem-judgment/distillation.js.map +1 -0
  384. package/dist/electron-build/pi-ecosystem-judgment/evolve-judgment.js +176 -0
  385. package/dist/electron-build/pi-ecosystem-judgment/evolve-judgment.js.map +1 -0
  386. package/dist/electron-build/pi-ecosystem-judgment/human-value-pipeline.js +65 -0
  387. package/dist/electron-build/pi-ecosystem-judgment/human-value-pipeline.js.map +1 -0
  388. package/dist/electron-build/pi-ecosystem-judgment/human-value-store.js +808 -0
  389. package/dist/electron-build/pi-ecosystem-judgment/human-value-store.js.map +1 -0
  390. package/dist/electron-build/pi-ecosystem-judgment/index.js +508 -0
  391. package/dist/electron-build/pi-ecosystem-judgment/index.js.map +1 -0
  392. package/dist/electron-build/pi-ecosystem-judgment/injection-gate.js +334 -0
  393. package/dist/electron-build/pi-ecosystem-judgment/injection-gate.js.map +1 -0
  394. package/dist/electron-build/pi-ecosystem-judgment/monitor-gate.js +228 -0
  395. package/dist/electron-build/pi-ecosystem-judgment/monitor-gate.js.map +1 -0
  396. package/dist/electron-build/pi-ecosystem-judgment/value-injection.js +598 -0
  397. package/dist/electron-build/pi-ecosystem-judgment/value-injection.js.map +1 -0
  398. package/dist/electron-build/pi-ecosystem-mcp/index.js +643 -0
  399. package/dist/electron-build/pi-ecosystem-mcp/index.js.map +1 -0
  400. package/dist/electron-build/pi-ecosystem-mcp/ui-tools.js +116 -0
  401. package/dist/electron-build/pi-ecosystem-mcp/ui-tools.js.map +1 -0
  402. package/dist/electron-build/pi-ecosystem-subagents/index.js +352 -0
  403. package/dist/electron-build/pi-ecosystem-subagents/index.js.map +1 -0
  404. package/dist/electron-build/security/builtin-guards.js +133 -0
  405. package/dist/electron-build/security/builtin-guards.js.map +1 -0
  406. package/dist/electron-build/security/context-router-tool.js +111 -0
  407. package/dist/electron-build/security/context-router-tool.js.map +1 -0
  408. package/dist/electron-build/security/input-scanner.js +263 -0
  409. package/dist/electron-build/security/input-scanner.js.map +1 -0
  410. package/dist/electron-build/security/react-harness.js +148 -0
  411. package/dist/electron-build/security/react-harness.js.map +1 -0
  412. package/dist/electron-build/security/tool-gate.js +291 -0
  413. package/dist/electron-build/security/tool-gate.js.map +1 -0
  414. package/dist/electron-build/setup/setup-store.js +648 -0
  415. package/dist/electron-build/setup/setup-store.js.map +1 -0
  416. package/dist/electron-build/social/channels/ChannelManager.js +444 -0
  417. package/dist/electron-build/social/channels/ChannelManager.js.map +1 -0
  418. package/dist/electron-build/social/channels/DiapChannelBridge.js +451 -0
  419. package/dist/electron-build/social/channels/DiapChannelBridge.js.map +1 -0
  420. package/dist/electron-build/social/channels/InterestMatcher.js +135 -0
  421. package/dist/electron-build/social/channels/InterestMatcher.js.map +1 -0
  422. package/dist/electron-build/social/channels/types.js +21 -0
  423. package/dist/electron-build/social/channels/types.js.map +1 -0
  424. package/dist/electron-build/social/global-shared-context.js +368 -0
  425. package/dist/electron-build/social/global-shared-context.js.map +1 -0
  426. package/dist/electron-build/social/heartbeat.js +882 -0
  427. package/dist/electron-build/social/heartbeat.js.map +1 -0
  428. package/dist/electron-build/storage/did-catalog-bridge.js +314 -0
  429. package/dist/electron-build/storage/did-catalog-bridge.js.map +1 -0
  430. package/dist/electron-build/storage/did-catalog.js +272 -0
  431. package/dist/electron-build/storage/did-catalog.js.map +1 -0
  432. package/dist/electron-build/utils/auto-update.js +140 -558
  433. package/dist/electron-build/utils/auto-update.js.map +1 -1
  434. package/dist/electron-build/utils/module-context.js +98 -0
  435. package/dist/electron-build/utils/module-context.js.map +1 -0
  436. package/dist/electron-build/utils/runtime-bootstrap.js +745 -0
  437. package/dist/electron-build/utils/runtime-bootstrap.js.map +1 -0
  438. package/dist/electron-build/utils/update-manager.js +770 -0
  439. package/dist/electron-build/utils/update-manager.js.map +1 -0
  440. package/dist/electron-build/utils/update-state.js +406 -0
  441. package/dist/electron-build/utils/update-state.js.map +1 -0
  442. package/dist/electron-build/utils/version-info.js +562 -0
  443. package/dist/electron-build/utils/version-info.js.map +1 -0
  444. package/dist/electron-build/web/i18n.js +146 -0
  445. package/dist/electron-build/web/i18n.js.map +1 -0
  446. package/dist/electron-build/web/routes-x402-info.js +232 -0
  447. package/dist/electron-build/web/routes-x402-info.js.map +1 -0
  448. package/dist/electron-build/web/server-storage.js +390 -0
  449. package/dist/electron-build/web/server-storage.js.map +1 -0
  450. package/dist/electron-build/web/server-types.js +52 -0
  451. package/dist/electron-build/web/server-types.js.map +1 -0
  452. package/dist/electron-build/web/task-deps.js +41 -0
  453. package/dist/electron-build/web/task-deps.js.map +1 -0
  454. package/dist/index.js +58 -27
  455. package/dist/llm/system-prompt/registry.js +6 -3
  456. package/dist/security/tool-gate.js +4 -0
  457. package/dist/utils/auto-update.js +138 -525
  458. package/dist/utils/module-context.js +59 -0
  459. package/dist/utils/runtime-bootstrap.js +682 -0
  460. package/dist/utils/update-cli.js +82 -0
  461. package/dist/utils/update-health.js +401 -0
  462. package/dist/utils/update-manager.js +716 -0
  463. package/dist/utils/update-state.js +353 -0
  464. package/dist/utils/version-info.js +510 -0
  465. package/dist/web/mobile-contacts.js +329 -0
  466. package/dist/web/mobile-core.js +481 -15
  467. package/dist/web/mobile.html +32 -0
  468. package/dist/web/mobile.js +139 -0
  469. package/dist/web/routes-contacts.js +420 -0
  470. package/dist/web/server.js +5 -0
  471. package/package.json +1 -1
  472. package/scripts/build-cli.js +32 -151
  473. package/scripts/postinstall.js +153 -76
@@ -71270,7 +71270,7 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
71270
71270
  i = this._head + i & this._capacityMask;
71271
71271
  return this._list[i];
71272
71272
  };
71273
- Denque2.prototype.get = function get2(i) {
71273
+ Denque2.prototype.get = function get3(i) {
71274
71274
  return this.peekAt(i);
71275
71275
  };
71276
71276
  Denque2.prototype.peek = function peek() {
@@ -103541,7 +103541,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
103541
103541
  }
103542
103542
  }
103543
103543
  }
103544
- function get(source, path) {
103544
+ function get2(source, path) {
103545
103545
  let node2 = source;
103546
103546
  for (const [index, key] of path.entries()) {
103547
103547
  node2 = node2[key];
@@ -103597,7 +103597,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
103597
103597
  return tree(this.value, []);
103598
103598
  }
103599
103599
  get(path = "/") {
103600
- return get(this.value, path.split("/").filter(Boolean));
103600
+ return get2(this.value, path.split("/").filter(Boolean));
103601
103601
  }
103602
103602
  };
103603
103603
  }
@@ -119947,46 +119947,46 @@ ${values.join("\n")}` : `${blockName} :`;
119947
119947
  var len;
119948
119948
  revLookup["-".charCodeAt(0)] = 62;
119949
119949
  revLookup["_".charCodeAt(0)] = 63;
119950
- function getLens(b64) {
119951
- var len2 = b64.length;
119950
+ function getLens(b642) {
119951
+ var len2 = b642.length;
119952
119952
  if (len2 % 4 > 0) {
119953
119953
  throw new Error("Invalid string. Length must be a multiple of 4");
119954
119954
  }
119955
- var validLen = b64.indexOf("=");
119955
+ var validLen = b642.indexOf("=");
119956
119956
  if (validLen === -1) validLen = len2;
119957
119957
  var placeHoldersLen = validLen === len2 ? 0 : 4 - validLen % 4;
119958
119958
  return [validLen, placeHoldersLen];
119959
119959
  }
119960
- function byteLength2(b64) {
119961
- var lens = getLens(b64);
119960
+ function byteLength2(b642) {
119961
+ var lens = getLens(b642);
119962
119962
  var validLen = lens[0];
119963
119963
  var placeHoldersLen = lens[1];
119964
119964
  return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
119965
119965
  }
119966
- function _byteLength(b64, validLen, placeHoldersLen) {
119966
+ function _byteLength(b642, validLen, placeHoldersLen) {
119967
119967
  return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
119968
119968
  }
119969
- function toByteArray(b64) {
119969
+ function toByteArray(b642) {
119970
119970
  var tmp;
119971
- var lens = getLens(b64);
119971
+ var lens = getLens(b642);
119972
119972
  var validLen = lens[0];
119973
119973
  var placeHoldersLen = lens[1];
119974
- var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));
119974
+ var arr = new Arr(_byteLength(b642, validLen, placeHoldersLen));
119975
119975
  var curByte = 0;
119976
119976
  var len2 = placeHoldersLen > 0 ? validLen - 4 : validLen;
119977
119977
  var i2;
119978
119978
  for (i2 = 0; i2 < len2; i2 += 4) {
119979
- tmp = revLookup[b64.charCodeAt(i2)] << 18 | revLookup[b64.charCodeAt(i2 + 1)] << 12 | revLookup[b64.charCodeAt(i2 + 2)] << 6 | revLookup[b64.charCodeAt(i2 + 3)];
119979
+ tmp = revLookup[b642.charCodeAt(i2)] << 18 | revLookup[b642.charCodeAt(i2 + 1)] << 12 | revLookup[b642.charCodeAt(i2 + 2)] << 6 | revLookup[b642.charCodeAt(i2 + 3)];
119980
119980
  arr[curByte++] = tmp >> 16 & 255;
119981
119981
  arr[curByte++] = tmp >> 8 & 255;
119982
119982
  arr[curByte++] = tmp & 255;
119983
119983
  }
119984
119984
  if (placeHoldersLen === 2) {
119985
- tmp = revLookup[b64.charCodeAt(i2)] << 2 | revLookup[b64.charCodeAt(i2 + 1)] >> 4;
119985
+ tmp = revLookup[b642.charCodeAt(i2)] << 2 | revLookup[b642.charCodeAt(i2 + 1)] >> 4;
119986
119986
  arr[curByte++] = tmp & 255;
119987
119987
  }
119988
119988
  if (placeHoldersLen === 1) {
119989
- tmp = revLookup[b64.charCodeAt(i2)] << 10 | revLookup[b64.charCodeAt(i2 + 1)] << 4 | revLookup[b64.charCodeAt(i2 + 2)] >> 2;
119989
+ tmp = revLookup[b642.charCodeAt(i2)] << 10 | revLookup[b642.charCodeAt(i2 + 1)] << 4 | revLookup[b642.charCodeAt(i2 + 2)] >> 2;
119990
119990
  arr[curByte++] = tmp >> 8 & 255;
119991
119991
  arr[curByte++] = tmp & 255;
119992
119992
  }
@@ -162923,6 +162923,365 @@ ${error.stack}` : head;
162923
162923
  return result;
162924
162924
  }
162925
162925
 
162926
+ // src/agents/contacts/grant-payload.ts
162927
+ function canonicalGrantPayload(g) {
162928
+ return JSON.stringify({
162929
+ grantId: g.grantId,
162930
+ identityId: g.identityId,
162931
+ ownerDid: g.ownerDid,
162932
+ level: g.level,
162933
+ channels: g.channels,
162934
+ contactScope: g.contactScope,
162935
+ taskScope: g.taskScope,
162936
+ contentScope: g.contentScope,
162937
+ replyWakeAllowed: g.replyWakeAllowed,
162938
+ autoSend: g.autoSend,
162939
+ sensitiveContentAllowed: g.sensitiveContentAllowed,
162940
+ newRecipientAllowed: g.newRecipientAllowed,
162941
+ grantedAt: g.grantedAt,
162942
+ grantedBy: g.grantedBy,
162943
+ grantedVia: g.grantedVia,
162944
+ deviceIds: [...g.deviceIds].sort(),
162945
+ status: g.status,
162946
+ revokedAt: g.revokedAt || "",
162947
+ grantVersion: g.grantVersion
162948
+ });
162949
+ }
162950
+ function canonicalRevocationPayload(r) {
162951
+ return JSON.stringify({ grantId: r.grantId, grantVersion: r.grantVersion, revokedAt: r.revokedAt, by: r.by });
162952
+ }
162953
+ function presetForChoice(choice) {
162954
+ const base6 = { channels: "both", replyWakeAllowed: true, autoSend: true, newRecipientAllowed: false };
162955
+ switch (choice) {
162956
+ case "task_once":
162957
+ return { ...base6, level: "task_once", contactScope: "verified_contacts", taskScope: "current_goal", contentScope: "normal", autoSend: false, sensitiveContentAllowed: false };
162958
+ case "persistent":
162959
+ return { ...base6, level: "persistent", contactScope: "verified_contacts", taskScope: "all_future_goals", contentScope: "normal", sensitiveContentAllowed: false };
162960
+ case "full_contact_access":
162961
+ return { ...base6, level: "full_contact_access", contactScope: "all_contacts", taskScope: "all_future_goals", contentScope: "sensitive", sensitiveContentAllowed: true };
162962
+ }
162963
+ }
162964
+
162965
+ // src/web/mobile-contacts.ts
162966
+ var K_DEVICE = "bolloon.contacts.device.v1";
162967
+ var K_QUEUE = "bolloon.contacts.queue.v1";
162968
+ var K_CAPS = "bolloon.contacts.capabilities.v1";
162969
+ var cryptoOf = (c) => c || globalThis.crypto || null;
162970
+ function ed25519Available(c) {
162971
+ const cobj = cryptoOf(c);
162972
+ if (!cobj?.subtle) return false;
162973
+ try {
162974
+ const alg = { name: "Ed25519" };
162975
+ return typeof cobj.subtle.importKey === "function" && !!alg;
162976
+ } catch {
162977
+ return false;
162978
+ }
162979
+ }
162980
+ function bytesOf(s2) {
162981
+ const src4 = new TextEncoder().encode(s2);
162982
+ const out = new Uint8Array(new ArrayBuffer(src4.byteLength));
162983
+ out.set(src4);
162984
+ return out;
162985
+ }
162986
+ function b64(buf) {
162987
+ const arr = new Uint8Array(buf);
162988
+ let out = "";
162989
+ for (let i = 0; i < arr.length; i++) out += String.fromCharCode(arr[i]);
162990
+ return btoa(out);
162991
+ }
162992
+ function pemFromSpki(spki) {
162993
+ const b = b64(spki).replace(/(.{64})/g, "$1\n").trim();
162994
+ return `-----BEGIN PUBLIC KEY-----
162995
+ ${b}
162996
+ -----END PUBLIC KEY-----
162997
+ `;
162998
+ }
162999
+ async function sha256Hex(c, text) {
163000
+ const d2 = await c.subtle.digest("SHA-256", bytesOf(text));
163001
+ return [...new Uint8Array(d2)].map((x) => x.toString(16).padStart(2, "0")).join("");
163002
+ }
163003
+ async function loadOrCreateDeviceKey(storage2, c) {
163004
+ const cobj = cryptoOf(c);
163005
+ if (!cobj?.subtle) throw new Error("device_signing_unavailable: \u672C\u673A\u6CA1\u6709 WebCrypto");
163006
+ const raw = storage2.getItem(K_DEVICE);
163007
+ if (raw) {
163008
+ try {
163009
+ const parsed = JSON.parse(raw);
163010
+ if (parsed?.privateKeyJwk && parsed?.publicKeyPem && parsed?.deviceId) return parsed;
163011
+ } catch {
163012
+ }
163013
+ }
163014
+ let pair;
163015
+ try {
163016
+ pair = await cobj.subtle.generateKey({ name: "Ed25519" }, true, ["sign", "verify"]);
163017
+ } catch (err2) {
163018
+ throw new Error(`device_signing_unavailable: ${String(err2?.message || err2)}`);
163019
+ }
163020
+ const publicKeyPem = pemFromSpki(await cobj.subtle.exportKey("spki", pair.publicKey));
163021
+ const privateKeyJwk = await cobj.subtle.exportKey("jwk", pair.privateKey);
163022
+ const deviceId = `dev-${(await sha256Hex(cobj, publicKeyPem)).slice(0, 12)}`;
163023
+ const material = { deviceId, publicKeyPem, privateKeyJwk };
163024
+ storage2.setItem(K_DEVICE, JSON.stringify(material));
163025
+ return material;
163026
+ }
163027
+ async function importPrivate(storage2, c) {
163028
+ const k = await loadOrCreateDeviceKey(storage2, c);
163029
+ return c.subtle.importKey("jwk", k.privateKeyJwk, { name: "Ed25519" }, false, ["sign"]);
163030
+ }
163031
+ async function signGrantOnDevice(grant, storage2, c) {
163032
+ const cobj = cryptoOf(c);
163033
+ const key = await importPrivate(storage2, cobj);
163034
+ const payload = canonicalGrantPayload(grant);
163035
+ const sig = await cobj.subtle.sign({ name: "Ed25519" }, key, bytesOf(payload));
163036
+ const dev = await loadOrCreateDeviceKey(storage2, cobj);
163037
+ return { deviceId: dev.deviceId, alg: "ed25519", payloadHash: await sha256Hex(cobj, payload), sig: b64(sig) };
163038
+ }
163039
+ async function signRevocationOnDevice(rev, storage2, c) {
163040
+ const cobj = cryptoOf(c);
163041
+ const key = await importPrivate(storage2, cobj);
163042
+ const payload = canonicalRevocationPayload(rev);
163043
+ const sig = await cobj.subtle.sign({ name: "Ed25519" }, key, bytesOf(payload));
163044
+ const dev = await loadOrCreateDeviceKey(storage2, cobj);
163045
+ return { deviceId: dev.deviceId, alg: "ed25519", payloadHash: await sha256Hex(cobj, payload), sig: b64(sig) };
163046
+ }
163047
+ async function post(base6, path, body, f) {
163048
+ const res = await f(`${String(base6).replace(/\/+$/, "")}${path}`, {
163049
+ method: "POST",
163050
+ headers: { "Content-Type": "application/json" },
163051
+ body: JSON.stringify(body ?? {})
163052
+ });
163053
+ let json = null;
163054
+ try {
163055
+ json = await res.json();
163056
+ } catch {
163057
+ }
163058
+ return { status: res.status, json };
163059
+ }
163060
+ async function get(base6, path, f) {
163061
+ const res = await f(`${String(base6).replace(/\/+$/, "")}${path}`);
163062
+ let json = null;
163063
+ try {
163064
+ json = await res.json();
163065
+ } catch {
163066
+ }
163067
+ return { status: res.status, json };
163068
+ }
163069
+ async function registerDeviceOnDesktop(base6, storage2, opts = {}) {
163070
+ const f = opts.fetchImpl || fetch;
163071
+ const dev = await loadOrCreateDeviceKey(storage2, opts.cryptoObj);
163072
+ const r = await post(base6, "/api/contacts/devices", { deviceId: dev.deviceId, publicKeyPem: dev.publicKeyPem, label: opts.label || "\u624B\u673A" }, f);
163073
+ if (r.status !== 200 || !r.json?.ok) return { ok: false, error: `\u684C\u9762\u672A\u63A5\u53D7\u8BBE\u5907\u767B\u8BB0: ${r.json?.error || r.status}`, data: dev };
163074
+ return { ok: true, data: dev };
163075
+ }
163076
+ function saveCapabilityCopy(storage2, items) {
163077
+ const clean8 = (items || []).map((c) => ({
163078
+ contactId: String(c.contactId || ""),
163079
+ kind: c.kind,
163080
+ displayValue: String(c.displayValue || ""),
163081
+ verificationStatus: String(c.verificationStatus || ""),
163082
+ capabilities: [...c.capabilities || []],
163083
+ provider: c.provider ? String(c.provider) : void 0,
163084
+ state: c.state ? String(c.state) : void 0
163085
+ }));
163086
+ storage2.setItem(K_CAPS, JSON.stringify(clean8));
163087
+ }
163088
+ function loadCapabilityCopy(storage2) {
163089
+ try {
163090
+ const v = JSON.parse(storage2.getItem(K_CAPS) || "[]");
163091
+ return Array.isArray(v) ? v : [];
163092
+ } catch {
163093
+ return [];
163094
+ }
163095
+ }
163096
+ function pendingQueue(storage2) {
163097
+ try {
163098
+ const v = JSON.parse(storage2.getItem(K_QUEUE) || "[]");
163099
+ return Array.isArray(v) ? v : [];
163100
+ } catch {
163101
+ return [];
163102
+ }
163103
+ }
163104
+ function setQueue(storage2, q) {
163105
+ storage2.setItem(K_QUEUE, JSON.stringify(q.slice(-20)));
163106
+ }
163107
+ async function flushQueuedGrants(base6, storage2, opts = {}) {
163108
+ const f = opts.fetchImpl || fetch;
163109
+ const q = pendingQueue(storage2);
163110
+ const keep = [];
163111
+ const results = [];
163112
+ let sent = 0, failed = 0;
163113
+ for (const item of q) {
163114
+ try {
163115
+ const r = await post(base6, "/api/contacts/grants/sync", { grant: { ...item.grant, signature: item.signature } }, f);
163116
+ if (r.status === 200 && r.json?.ok) {
163117
+ sent++;
163118
+ results.push({ grantId: item.grant.grantId, ok: true });
163119
+ continue;
163120
+ }
163121
+ failed++;
163122
+ keep.push(item);
163123
+ results.push({ grantId: item.grant.grantId, ok: false, error: r.json?.code || r.status });
163124
+ } catch {
163125
+ failed++;
163126
+ keep.push(item);
163127
+ results.push({ grantId: item.grant.grantId, ok: false, error: "network" });
163128
+ }
163129
+ }
163130
+ setQueue(storage2, keep);
163131
+ return { sent, failed, results };
163132
+ }
163133
+ async function authorizeFromPhone(input) {
163134
+ const c = cryptoOf(input.cryptoObj);
163135
+ if (!ed25519Available(c || void 0)) {
163136
+ return { ok: false, error: "device_signing_unavailable: \u672C\u673A WebView \u4E0D\u652F\u6301 Ed25519 \u8BBE\u5907\u7B7E\u540D \u2014\u2014 \u8BF7\u5728\u684C\u9762\u7AEF\u6388\u6743 (\u6216\u5347\u7EA7\u7CFB\u7EDF WebView)" };
163137
+ }
163138
+ const dev = await loadOrCreateDeviceKey(input.storage, c);
163139
+ const preset = presetForChoice(input.choice);
163140
+ const grant = {
163141
+ grantId: `gr-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
163142
+ identityId: input.identityId || `sid-phone-${dev.deviceId.slice(-6)}`,
163143
+ ownerDid: input.ownerDid,
163144
+ ...preset,
163145
+ grantedAt: (/* @__PURE__ */ new Date()).toISOString(),
163146
+ grantedBy: input.grantedBy || "leo",
163147
+ grantedVia: "mobile",
163148
+ deviceIds: [dev.deviceId],
163149
+ status: "active",
163150
+ grantVersion: 1
163151
+ };
163152
+ const signature = await signGrantOnDevice(grant, input.storage, c);
163153
+ const f = input.fetchImpl || fetch;
163154
+ const reg = await registerDeviceOnDesktop(input.base, input.storage, { fetchImpl: f, cryptoObj: c }).catch(() => ({ ok: false }));
163155
+ if (!reg.ok) {
163156
+ const q2 = pendingQueue(input.storage);
163157
+ q2.push({ grant, signature, queuedAt: (/* @__PURE__ */ new Date()).toISOString() });
163158
+ setQueue(input.storage, q2);
163159
+ return {
163160
+ ok: false,
163161
+ queued: true,
163162
+ error: `\u684C\u9762\u6682\u4E0D\u53EF\u8FBE \u2192 \u6388\u6743\u5DF2\u5B58\u5728\u624B\u673A, \u5F85\u684C\u9762\u5728\u7EBF\u65F6\u81EA\u52A8\u540C\u6B65 (${reg.error || "offline"})`,
163163
+ data: { grantId: grant.grantId, level: grant.level, signature },
163164
+ note: "\u684C\u9762\u4E0D\u5728\u7EBF\u65F6\u4E0D\u5047\u88C5\u5DF2\u751F\u6548: \u6388\u6743\u5728\u672C\u5730\u961F\u5217\u91CC, \u684C\u9762\u4E00\u4E0A\u7EBF\u5C31\u8865\u540C\u6B65"
163165
+ };
163166
+ }
163167
+ const r = await post(input.base, "/api/contacts/grants/sync", { grant: { ...grant, signature } }, f);
163168
+ if (r.status === 200 && r.json?.ok) {
163169
+ return { ok: true, data: { grantId: grant.grantId, level: grant.level, signature }, note: "\u684C\u9762\u5DF2\u9A8C\u7B7E\u63A5\u53D7" };
163170
+ }
163171
+ const q = pendingQueue(input.storage);
163172
+ q.push({ grant, signature, queuedAt: (/* @__PURE__ */ new Date()).toISOString() });
163173
+ setQueue(input.storage, q);
163174
+ return {
163175
+ ok: false,
163176
+ queued: true,
163177
+ error: `\u684C\u9762\u62D2\u7EDD/\u672A\u63A5\u53D7: ${r.json?.code || r.json?.reason || r.status}`,
163178
+ data: { grantId: grant.grantId, level: grant.level, signature },
163179
+ note: "\u5DF2\u4FDD\u5B58\u5728\u624B\u673A\u672C\u5730\u961F\u5217 (\u4E0D\u4F1A\u56E0\u4E3A\u5931\u8D25\u5C31\u5F53\u6210\u5DF2\u6388\u6743)"
163180
+ };
163181
+ }
163182
+ async function revokeFromPhone(opts) {
163183
+ const c = cryptoOf(opts.cryptoObj);
163184
+ if (!ed25519Available(c || void 0)) return { ok: false, error: "device_signing_unavailable: \u672C\u673A\u4E0D\u652F\u6301\u8BBE\u5907\u7B7E\u540D, \u64A4\u9500\u9700\u5728\u684C\u9762\u7AEF\u8FDB\u884C" };
163185
+ const revokedAt = (/* @__PURE__ */ new Date()).toISOString();
163186
+ const payload = { grantId: opts.grantId, grantVersion: opts.version || 1, revokedAt, by: "mobile" };
163187
+ const signature = await signRevocationOnDevice(payload, opts.storage, c);
163188
+ const f = opts.fetchImpl || fetch;
163189
+ const r = await post(opts.base, "/api/contacts/grants/revoke-sync", { grantId: opts.grantId, by: "mobile", reason: opts.reason, version: payload.grantVersion, revokedAt, signature }, f);
163190
+ if (r.status === 200 && r.json?.ok) return { ok: true, data: { grantId: opts.grantId }, note: "\u684C\u9762\u5DF2\u9A8C\u7B7E\u5E76\u7ACB\u5373\u5931\u6548" };
163191
+ return { ok: false, error: `\u64A4\u9500\u672A\u9001\u8FBE: ${r.json?.code || r.json?.error || r.status}`, note: "\u684C\u9762\u4E0D\u5728\u7EBF\u65F6\u64A4\u9500**\u4E0D\u4F1A**\u88AB\u5F53\u4F5C\u5DF2\u5B8C\u6210 \u2014\u2014 \u8BF7\u5728\u684C\u9762\u5728\u7EBF\u540E\u91CD\u8BD5 (\u6216\u684C\u9762\u7AEF\u64A4\u9500)" };
163192
+ }
163193
+ async function loadFromDesktop(base6, storage2, opts = {}) {
163194
+ const f = opts.fetchImpl || fetch;
163195
+ if (!base6) {
163196
+ const caps = loadCapabilityCopy(storage2);
163197
+ return {
163198
+ ok: false,
163199
+ error: "desktop_offline",
163200
+ data: { contacts: caps, grants: [], effective: "\u684C\u9762\u4E0D\u5728\u7EBF (\u663E\u793A\u624B\u673A\u672C\u5730\u526F\u672C)", approvals: [], waiting: [] },
163201
+ note: "\u4EE5\u4E0B\u662F\u4F60\u624B\u673A\u4E0A\u4FDD\u5B58\u7684\u80FD\u529B\u526F\u672C (\u4E0D\u662F\u684C\u9762\u5B9E\u65F6\u72B6\u6001)"
163202
+ };
163203
+ }
163204
+ try {
163205
+ const a = await get(base6, "/api/contacts", f);
163206
+ const b = await get(base6, "/api/contacts/grants", f);
163207
+ if (a.status !== 200 && b.status !== 200) return { ok: false, error: `desktop_http_${a.status || b.status}` };
163208
+ const view = {
163209
+ contacts: a.json?.contacts || [],
163210
+ grants: b.json?.grants || [],
163211
+ effective: b.json?.effective || "",
163212
+ approvals: a.json?.approvals || [],
163213
+ waiting: a.json?.waiting || []
163214
+ };
163215
+ saveCapabilityCopy(storage2, (view.contacts || []).filter((c) => c.capabilities?.includes("send")).map((c) => ({
163216
+ contactId: c.contactId,
163217
+ kind: c.kind,
163218
+ displayValue: c.displayValue,
163219
+ verificationStatus: c.status,
163220
+ capabilities: c.capabilities,
163221
+ provider: c.provider,
163222
+ state: c.status
163223
+ })));
163224
+ return { ok: true, data: view };
163225
+ } catch (err2) {
163226
+ const caps = loadCapabilityCopy(storage2);
163227
+ return {
163228
+ ok: false,
163229
+ error: "desktop_offline",
163230
+ data: { contacts: caps, grants: [], effective: "\u684C\u9762\u4E0D\u5728\u7EBF (\u663E\u793A\u624B\u673A\u672C\u5730\u526F\u672C)", approvals: [], waiting: [] },
163231
+ note: `\u8FDE\u4E0D\u4E0A\u684C\u9762 (${String(err2?.message || err2).slice(0, 60)}) \u2014\u2014 \u663E\u793A\u672C\u5730\u526F\u672C`
163232
+ };
163233
+ }
163234
+ }
163235
+ async function bindFromPhone(base6, opts, storage2, f) {
163236
+ const impl = f || fetch;
163237
+ if (!base6) return { ok: false, error: "desktop_offline: \u7ED1\u5B9A\u9700\u8981\u684C\u9762\u7AEF\u5728\u7EBF (\u684C\u9762\u8D1F\u8D23\u843D\u76D8\u4E0E\u9A8C\u8BC1\u7801\u901A\u9053)" };
163238
+ const r = await post(base6, "/api/contacts/bind", { kind: opts.kind, value: opts.value, region: opts.region }, impl);
163239
+ if (r.status === 200 && r.json?.ok) return { ok: true, data: r.json };
163240
+ return { ok: false, error: r.json?.error || `HTTP ${r.status}` };
163241
+ }
163242
+ async function verifyFromPhone(base6, opts, storage2, f) {
163243
+ const impl = f || fetch;
163244
+ if (!base6) return { ok: false, error: "desktop_offline: \u9A8C\u8BC1\u9700\u8981\u684C\u9762\u7AEF\u5728\u7EBF" };
163245
+ const r = await post(base6, "/api/contacts/verify", { contactId: opts.contactId, challengeId: opts.challengeId, code: opts.code }, impl);
163246
+ if (r.status === 200 && r.json?.ok) return { ok: true, data: r.json };
163247
+ return { ok: false, error: r.json?.error || `HTTP ${r.status}` };
163248
+ }
163249
+ async function decideApprovalFromPhone(base6, opts, f) {
163250
+ const impl = f || fetch;
163251
+ if (!base6) return { ok: false, error: "desktop_offline: \u6279\u51C6\u9700\u8981\u684C\u9762\u7AEF\u5728\u7EBF (\u624B\u673A\u4E0D\u5728\u7EBF\u65F6\u4E0D\u4F1A\u5047\u88C5\u5DF2\u6279\u51C6)" };
163252
+ const r = await post(base6, `/api/contacts/approvals/${encodeURIComponent(opts.consentId)}/${opts.action}`, { by: "leo", via: "mobile", body: opts.body, reason: opts.reason }, impl);
163253
+ if (r.status === 200 && r.json?.ok) return { ok: true, data: r.json };
163254
+ return { ok: false, error: r.json?.error || `HTTP ${r.status}` };
163255
+ }
163256
+ function buildPhoneCard(view, opts) {
163257
+ return {
163258
+ title: "\u8BA9 Bolloon \u4EE3\u8868\u4F60\u8054\u7CFB\u5916\u90E8\u7684\u4EBA",
163259
+ effective: view?.effective || opts.offline || "\u672A\u77E5",
163260
+ contacts: (view?.contacts || []).map((c) => ({
163261
+ displayValue: c.displayValue || "",
163262
+ kind: c.kind || "",
163263
+ state: c.status || c.verificationStatus || "",
163264
+ label: c.capabilities?.includes("send") ? "\u53EF\u8054\u7CFB" : "\u4E0D\u53EF\u8054\u7CFB"
163265
+ })),
163266
+ approvals: (view?.approvals || []).map((a) => ({
163267
+ consentId: a.consentId,
163268
+ contactName: a.contactName,
163269
+ channel: a.channel,
163270
+ subject: a.subject,
163271
+ bodyPreview: a.bodyPreview || "",
163272
+ reason: a.reason,
163273
+ reallySent: !!a.reallySent
163274
+ })),
163275
+ choices: [
163276
+ { id: "task_once", label: "\u4EC5\u672C\u6B21\u4EFB\u52A1" },
163277
+ { id: "persistent", label: "\u957F\u671F\u4F7F\u7528 (\u63A8\u8350)" },
163278
+ { id: "full_contact_access", label: "\u5B8C\u5168\u6388\u6743\u8054\u7CFB\u65B9\u5F0F\u80FD\u529B" }
163279
+ ],
163280
+ willNotGet: ["\u8BFB\u53D6\u5168\u90E8\u90AE\u7BB1", "\u8BFB\u53D6\u901A\u8BAF\u5F55", "\u7FA4\u53D1\u6D88\u606F", "\u81EA\u52A8\u652F\u4ED8/\u8F6C\u8D26", "\u4EE3\u8868\u4F60\u7B7E\u7F72\u5408\u540C", "\u62FF\u5230\u624B\u673A\u53F7/\u90AE\u7BB1\u660E\u6587"],
163281
+ deviceSigning: opts.deviceSigning
163282
+ };
163283
+ }
163284
+
162926
163285
  // src/web/mobile-core.ts
162927
163286
  var busHandlers = /* @__PURE__ */ new Set();
162928
163287
  function busBroadcast(msg) {
@@ -163033,6 +163392,8 @@ ${error.stack}` : head;
163033
163392
  if (p === "/api/peers") return () => core.peers.list();
163034
163393
  if (p === "/api/mcp/tools") return () => core.mcp.tools();
163035
163394
  if (p === "/api/skills") return () => core.skills.list();
163395
+ if (p === "/api/contacts") return () => core.contacts.view();
163396
+ if (p === "/api/contacts/grants") return () => core.contacts.grants();
163036
163397
  if (p === "/api/auth/status") return () => core.identity.status();
163037
163398
  if (p === "/api/payments/pending") return () => core.payments.pending();
163038
163399
  if (p === "/api/llm-config") return () => core.data.getLlmConfig();
@@ -163786,6 +164147,111 @@ ${error.stack}` : head;
163786
164147
  return mobileGatewayTool2(String(name10 || ""), args || {});
163787
164148
  }
163788
164149
  },
164150
+ /**
164151
+ * 联系方式与持久授权 (2026-09-19, Phase 5/10)
164152
+ * 手机负责: 输入 · OTP 确认 · 生物识别/系统确认 · 展示待发内容 · 批准高风险联系 · **签名长期授权**
164153
+ * 桌面负责: 落盘 · 执行 · 等待回复 · 证据
164154
+ * 铁律: 明文不进手机存储 (只存 capability 副本), 桌面离线不假装成功, 不支持 Ed25519 就明说。
164155
+ */
164156
+ contacts: {
164157
+ /** 本机是否能做设备签名 (老 WebView 可能没有 Ed25519) */
164158
+ deviceSigning() {
164159
+ return ed25519Available();
164160
+ },
164161
+ /** 桌面 HTTP 地址 (拿不到 → null, 不猜) */
164162
+ async desktopBase() {
164163
+ try {
164164
+ const u = await core.desktop?.url?.();
164165
+ const raw = u && typeof u === "object" ? u.url || u.baseUrl || "" : u;
164166
+ const s2 = String(raw || "").replace(/\/+$/, "");
164167
+ return s2 || null;
164168
+ } catch {
164169
+ return null;
164170
+ }
164171
+ },
164172
+ /** 手机端本地存储 (只放: 设备私钥 JWK / capability 副本 / 离线队列) */
164173
+ storage() {
164174
+ try {
164175
+ if (typeof localStorage !== "undefined") return localStorage;
164176
+ } catch {
164177
+ }
164178
+ const mem2 = /* @__PURE__ */ new Map();
164179
+ return { getItem: (k) => mem2.has(k) ? mem2.get(k) : null, setItem: (k, v) => {
164180
+ mem2.set(k, v);
164181
+ }, removeItem: (k) => {
164182
+ mem2.delete(k);
164183
+ } };
164184
+ },
164185
+ /** 从桌面读脱敏视图 (桌面离线 → 退回本地 capability 副本并标注) */
164186
+ async view() {
164187
+ const base6 = await core.contacts.desktopBase();
164188
+ const r = await loadFromDesktop(base6, core.contacts.storage());
164189
+ return { ...r.data || { contacts: [], grants: [], effective: "", approvals: [], waiting: [] }, offline: !r.ok, note: r.note, error: r.error };
164190
+ },
164191
+ async grants() {
164192
+ const v = await core.contacts.view();
164193
+ return { grants: v.grants || [], effective: v.effective || "", offline: v.offline };
164194
+ },
164195
+ /** 手机端摘要卡 (给 UI 直接渲染) */
164196
+ async card() {
164197
+ const base6 = await core.contacts.desktopBase();
164198
+ const r = await loadFromDesktop(base6, core.contacts.storage());
164199
+ return buildPhoneCard(r.data || null, { deviceSigning: ed25519Available(), offline: r.error });
164200
+ },
164201
+ /** 确认授权 (三个选项之一) → 设备签名 → 桌面验签; 桌面离线则进本地队列 */
164202
+ async authorize(choice, ownerDid) {
164203
+ const base6 = await core.contacts.desktopBase();
164204
+ let did = ownerDid;
164205
+ if (!did) {
164206
+ try {
164207
+ const st = await core.identity?.status?.();
164208
+ did = st?.did;
164209
+ } catch {
164210
+ }
164211
+ }
164212
+ return authorizeFromPhone({
164213
+ base: base6 || "",
164214
+ choice,
164215
+ ownerDid: did || "did:bolln:local",
164216
+ storage: core.contacts.storage(),
164217
+ grantedBy: "leo"
164218
+ });
164219
+ },
164220
+ /** 手机撤销 (带签名; 桌面离线不假装已撤销) */
164221
+ async revoke(grantId, reason) {
164222
+ const base6 = await core.contacts.desktopBase();
164223
+ if (!base6) return { ok: false, error: "desktop_offline: \u64A4\u9500\u9700\u8981\u684C\u9762\u5728\u7EBF" };
164224
+ return revokeFromPhone({ base: base6, grantId, reason, storage: core.contacts.storage(), version: Date.now() });
164225
+ },
164226
+ async bind(kind, value2, region) {
164227
+ const base6 = await core.contacts.desktopBase();
164228
+ return bindFromPhone(base6, { kind, value: value2, region }, core.contacts.storage());
164229
+ },
164230
+ async verify(contactId, challengeId, code10) {
164231
+ const base6 = await core.contacts.desktopBase();
164232
+ return verifyFromPhone(base6, { contactId, challengeId, code: code10 }, core.contacts.storage());
164233
+ },
164234
+ /** 手机上批准/拒绝高风险联系 (展示待发内容后) */
164235
+ async decide(consentId, action, opts = {}) {
164236
+ const base6 = await core.contacts.desktopBase();
164237
+ return decideApprovalFromPhone(base6, { consentId, action, ...opts });
164238
+ },
164239
+ /** 桌面回来后补同步排队中的授权 */
164240
+ async flushQueue() {
164241
+ const base6 = await core.contacts.desktopBase();
164242
+ if (!base6) return { sent: 0, failed: pendingQueue(core.contacts.storage()).length, results: [] };
164243
+ return flushQueuedGrants(base6, core.contacts.storage());
164244
+ },
164245
+ queue() {
164246
+ return pendingQueue(core.contacts.storage());
164247
+ },
164248
+ capabilities() {
164249
+ return loadCapabilityCopy(core.contacts.storage());
164250
+ },
164251
+ device() {
164252
+ return loadOrCreateDeviceKey(core.contacts.storage());
164253
+ }
164254
+ },
163789
164255
  skills: {
163790
164256
  async list() {
163791
164257
  const s2 = await Promise.resolve().then(() => (init_mobile_sync(), mobile_sync_exports));
@@ -121,6 +121,7 @@
121
121
  <div class="list-item" id="item-settings"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><path d="M4 7.5h6M14 7.5h6M4 16.5h9M17 16.5h3"/><circle cx="12" cy="7.5" r="2.2"/><circle cx="15" cy="16.5" r="2.2"/></svg></span><span>设置</span><span class="list-arrow">›</span></div>
122
122
  <div class="list-item" id="item-wallet"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><rect x="3" y="6.5" width="18" height="12" rx="3"/><path d="M3 10.5h18"/><circle cx="16.8" cy="14.5" r="1.3" fill="currentColor" stroke="none"/></svg></span><span>钱包</span><span class="list-arrow">›</span></div>
123
123
  <div class="list-item" id="item-judgments"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><path d="M11 3.5l1.8 4.7 4.7 1.8-4.7 1.8L11 16.5l-1.8-4.7L4.5 10l4.7-1.8z"/><path d="M18.5 16l.6 1.6 1.6.6-1.6.6-.6 1.6-.6-1.6-1.6-.6 1.6-.6z"/></svg></span><span>判断力 API</span><span class="list-arrow">›</span></div>
124
+ <div class="list-item" id="item-contacts"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><rect x="3.5" y="5.5" width="17" height="13" rx="2.5"/><path d="M3.5 9h17"/><circle cx="8.5" cy="14" r="1.6"/><path d="M12 13h5M12 15.5h3"/></svg></span><span>联系方式与授权</span><span class="list-arrow" id="contacts-arrow">›</span></div>
124
125
  <div class="list-item" id="item-login"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><rect x="4.5" y="10.5" width="15" height="9.5" rx="2.5"/><path d="M8 10.5V7.5a4 4 0 0 1 8 0v3"/></svg></span><span id="login-label">登录</span><span class="list-arrow">›</span></div>
125
126
  <div class="list-item" id="item-logout"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><path d="M14.5 4.5h3.5a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2h-3.5"/><path d="M10 8.5l-3.5 3.5L10 15.5M6.5 12h8"/></svg></span><span>注销</span></div>
126
127
  </div>
@@ -235,3 +236,34 @@ if ('serviceWorker' in navigator) {
235
236
  </script>
236
237
  </body>
237
238
  </html>
239
+
240
+ <!-- 联系方式与持久授权 (2026-09-19): 手机确认一次, Agent 长期自动使用 -->
241
+ <div class="sheet" id="contacts-sheet" hidden>
242
+ <div class="sheet-inner">
243
+ <div class="sheet-title">联系方式与授权</div>
244
+ <div class="sheet-text" id="contacts-effective">加载中...</div>
245
+ <div class="sheet-text" id="contacts-signing" style="font-size:12px;color:var(--text-secondary)"></div>
246
+
247
+ <div id="contacts-approvals"></div>
248
+
249
+ <div class="sheet-title" style="margin-top:10px">我的联系方式</div>
250
+ <div id="contacts-list"><div class="sheet-text">加载中...</div></div>
251
+
252
+ <div style="margin-top:10px">
253
+ <input id="contacts-value" placeholder="手机号 (+86...) 或 邮箱" style="width:100%;padding:10px 12px;border-radius:10px;border:1px solid var(--border);background:transparent;color:var(--text);font-size:14px" />
254
+ <div style="display:flex;gap:8px;margin-top:8px">
255
+ <button class="sheet-choice" id="contacts-bind" style="flex:1">绑定并发送验证码</button>
256
+ </div>
257
+ <input id="contacts-code" placeholder="收到的验证码" inputmode="numeric" style="width:100%;margin-top:8px;padding:10px 12px;border-radius:10px;border:1px solid var(--border);background:transparent;color:var(--text);font-size:14px" />
258
+ <button class="sheet-choice" id="contacts-verify" style="margin-top:8px;width:100%">验证</button>
259
+ </div>
260
+
261
+ <div class="sheet-title" style="margin-top:12px">让 Bolloon 代表你联系外部的人</div>
262
+ <div class="sheet-text" id="contacts-willnot" style="font-size:12px"></div>
263
+ <div class="sheet-inner-choices" id="contacts-choices" style="margin-top:8px"></div>
264
+ <div class="sheet-inner-choices">
265
+ <button class="sheet-choice" id="contacts-revoke-all">撤销全部授权</button>
266
+ <button class="sheet-choice sheet-cancel" id="contacts-close">关闭</button>
267
+ </div>
268
+ </div>
269
+ </div>