@bolloon/bolloon-agent 0.1.35 → 0.1.37

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 (502) hide show
  1. package/README.md +1 -1
  2. package/dist/agents/p2p-chat-tools.js +6 -6
  3. package/dist/agents/permission-mode.js +115 -0
  4. package/dist/agents/pi-sdk.js +435 -25
  5. package/dist/agents/pre-tool-validator.js +194 -0
  6. package/dist/agents/workflow-pivot-loop.js +113 -12
  7. package/dist/bollharness-integration/context-router.js +2 -2
  8. package/dist/bollharness-integration/guard-checker.js +1 -1
  9. package/dist/bootstrap/bootstrap.js +3 -0
  10. package/dist/bootstrap/context-collector.js +17 -1
  11. package/dist/bootstrap/context-hierarchy.js +218 -0
  12. package/dist/bootstrap/lifecycle-hooks.js +86 -24
  13. package/dist/bootstrap/project-context.js +10 -3
  14. package/dist/context-compaction/auto-compact.js +144 -0
  15. package/dist/context-compaction/budget-gate.js +28 -0
  16. package/dist/context-compaction/budget-reduce.js +35 -0
  17. package/dist/context-compaction/context-collapse.js +66 -0
  18. package/dist/context-compaction/index.js +21 -0
  19. package/dist/context-compaction/microcompact.js +51 -0
  20. package/dist/context-compaction/pipeline.js +123 -0
  21. package/dist/context-compaction/snip.js +45 -0
  22. package/dist/context-compaction/token-estimator.js +35 -0
  23. package/dist/context-compaction/types.js +19 -0
  24. package/dist/heartbeat/HealthMonitor.js +3 -2
  25. package/dist/index.js +38 -2
  26. package/dist/llm/llm-judgment-client.js +32 -30
  27. package/dist/llm/pi-ai.js +103 -16
  28. package/dist/llm/system-prompt/health.js +129 -0
  29. package/dist/llm/system-prompt/registry.js +246 -0
  30. package/dist/llm/system-prompt/strip-hibsml.js +51 -0
  31. package/dist/llm/tool-manifest/ask_user_input.js +35 -0
  32. package/dist/llm/tool-manifest/bash.js +23 -0
  33. package/dist/llm/tool-manifest/create_file.js +24 -0
  34. package/dist/llm/tool-manifest/fetch_sports_data.js +26 -0
  35. package/dist/llm/tool-manifest/image_search.js +24 -0
  36. package/dist/llm/tool-manifest/index.js +69 -0
  37. package/dist/llm/tool-manifest/mcp.js +43 -0
  38. package/dist/llm/tool-manifest/message_compose.js +31 -0
  39. package/dist/llm/tool-manifest/places.js +83 -0
  40. package/dist/llm/tool-manifest/present_files.js +21 -0
  41. package/dist/llm/tool-manifest/recipe.js +40 -0
  42. package/dist/llm/tool-manifest/recommend_apps.js +23 -0
  43. package/dist/llm/tool-manifest/str_replace.js +27 -0
  44. package/dist/llm/tool-manifest/types.js +7 -0
  45. package/dist/llm/tool-manifest/view.js +24 -0
  46. package/dist/llm/tool-manifest/weather.js +27 -0
  47. package/dist/llm/tool-manifest/web.js +51 -0
  48. package/dist/network/p2p-direct.js +23 -0
  49. package/dist/network/source-intent-broadcaster.js +203 -0
  50. package/dist/network/source-intent.js +100 -0
  51. package/dist/pi-ecosystem-judgment/adaptive-scan.js +48 -0
  52. package/dist/pi-ecosystem-judgment/injection-gate.js +54 -12
  53. package/dist/pi-ecosystem-judgment/value-injection.js +8 -2
  54. package/dist/security/context-router-tool.js +1 -1
  55. package/dist/security/input-scanner.js +223 -0
  56. package/dist/web/client.js +3089 -4458
  57. package/dist/web/index.html +58 -67
  58. package/dist/web/server.js +299 -117
  59. package/dist/web/style.css +531 -249
  60. package/dist/web/ui/message-renderer.js +352 -0
  61. package/dist/web/ui/step-timeline.js +279 -0
  62. package/package.json +2 -2
  63. package/.auto-evolve-calls +0 -1
  64. package/.last-auto-evolve-baseline +0 -1
  65. package/Bolloon.md +0 -103
  66. package/dist/agents/constraint-layer.js.map +0 -1
  67. package/dist/agents/pi-sdk.js.map +0 -1
  68. package/dist/agents/workflow-engine.js.map +0 -1
  69. package/dist/bollharness/src/index.js +0 -5
  70. package/dist/bollharness/src/scripts/checks/check_adr_plan_numbering.js +0 -6
  71. package/dist/bollharness/src/scripts/checks/check_api_types.js +0 -45
  72. package/dist/bollharness/src/scripts/checks/check_artifact_link.js +0 -146
  73. package/dist/bollharness/src/scripts/checks/check_bridge_deps.js +0 -6
  74. package/dist/bollharness/src/scripts/checks/check_bugfix_binding.js +0 -6
  75. package/dist/bollharness/src/scripts/checks/check_bugfix_binding_ci.js +0 -6
  76. package/dist/bollharness/src/scripts/checks/check_doc_file_references.js +0 -6
  77. package/dist/bollharness/src/scripts/checks/check_doc_freshness.js +0 -135
  78. package/dist/bollharness/src/scripts/checks/check_doc_links.js +0 -31
  79. package/dist/bollharness/src/scripts/checks/check_file_existence_claims.js +0 -6
  80. package/dist/bollharness/src/scripts/checks/check_fragment_integrity.js +0 -34
  81. package/dist/bollharness/src/scripts/checks/check_hook_installed.js +0 -63
  82. package/dist/bollharness/src/scripts/checks/check_issue_closure.js +0 -41
  83. package/dist/bollharness/src/scripts/checks/check_mcp_parity.js +0 -6
  84. package/dist/bollharness/src/scripts/checks/check_security.js +0 -48
  85. package/dist/bollharness/src/scripts/checks/check_skill_parity.js +0 -6
  86. package/dist/bollharness/src/scripts/checks/check_versions.js +0 -6
  87. package/dist/bollharness/src/scripts/checks/finding.js +0 -13
  88. package/dist/bollharness/src/scripts/checks/next_decision_number.js +0 -20
  89. package/dist/bollharness/src/scripts/checks/regenerate_magic_docs.js +0 -6
  90. package/dist/bollharness/src/scripts/ci/detect_rebaseline_triggers.js +0 -8
  91. package/dist/bollharness/src/scripts/ci/scan_subprocess_cfg.js +0 -8
  92. package/dist/bollharness/src/scripts/ci/scan_verify_artifacts.js +0 -8
  93. package/dist/bollharness/src/scripts/ci/scan_yaml_schema.js +0 -8
  94. package/dist/bollharness/src/scripts/context_router.js +0 -67
  95. package/dist/bollharness/src/scripts/deploy-guard.js +0 -157
  96. package/dist/bollharness/src/scripts/guard-feedback.js +0 -192
  97. package/dist/bollharness/src/scripts/guard_router.js +0 -158
  98. package/dist/bollharness/src/scripts/hooks/_hook_output.js +0 -6
  99. package/dist/bollharness/src/scripts/hooks/auto-python3.js +0 -6
  100. package/dist/bollharness/src/scripts/hooks/deploy-progress-on-session-end.js +0 -6
  101. package/dist/bollharness/src/scripts/hooks/failure-analyzer.js +0 -6
  102. package/dist/bollharness/src/scripts/hooks/gate-judgment-inject.js +0 -92
  103. package/dist/bollharness/src/scripts/hooks/gate-transition-judgment.js +0 -63
  104. package/dist/bollharness/src/scripts/hooks/inbox-ack.js +0 -6
  105. package/dist/bollharness/src/scripts/hooks/inbox-inject-on-start.js +0 -6
  106. package/dist/bollharness/src/scripts/hooks/inbox-validate.js +0 -6
  107. package/dist/bollharness/src/scripts/hooks/inbox-write-ledger.js +0 -6
  108. package/dist/bollharness/src/scripts/hooks/initializer-agent.js +0 -6
  109. package/dist/bollharness/src/scripts/hooks/loop-detection.js +0 -73
  110. package/dist/bollharness/src/scripts/hooks/owner-guard.js +0 -6
  111. package/dist/bollharness/src/scripts/hooks/precompact.js +0 -6
  112. package/dist/bollharness/src/scripts/hooks/review-agent-gatekeeper.js +0 -6
  113. package/dist/bollharness/src/scripts/hooks/risk-tracker.js +0 -108
  114. package/dist/bollharness/src/scripts/hooks/sanitize-on-read.js +0 -6
  115. package/dist/bollharness/src/scripts/hooks/session-reflection.js +0 -7
  116. package/dist/bollharness/src/scripts/hooks/session-start-magic-docs.js +0 -7
  117. package/dist/bollharness/src/scripts/hooks/session-start-reset-risk.js +0 -7
  118. package/dist/bollharness/src/scripts/hooks/session-start-toolkit-reminder.js +0 -7
  119. package/dist/bollharness/src/scripts/hooks/stop-evaluator.js +0 -157
  120. package/dist/bollharness/src/scripts/hooks/tool-call-counter.js +0 -6
  121. package/dist/bollharness/src/scripts/hooks/trace-analyzer.js +0 -10
  122. package/dist/bollharness/src/scripts/install/install-trust-token.js +0 -7
  123. package/dist/bollharness/src/scripts/install/multi_project_registry.js +0 -9
  124. package/dist/bollharness/src/scripts/install/phase2_auto.js +0 -21
  125. package/dist/bollharness/src/scripts/install/pre_commit_installer.js +0 -6
  126. package/dist/bollharness/src/scripts/install/tier_selector.js +0 -7
  127. package/dist/bollharness/src/scripts/install/transcript_miner.js +0 -7
  128. package/dist/bollharness/src/scripts/lib/claim_patterns.js +0 -10
  129. package/dist/bollharness/src/scripts/lib/sanitize_patterns.js +0 -12
  130. package/dist/bollharness/src/scripts/sanitize.js +0 -6
  131. package/dist/bollharness-integration/context-router-judgment.js.map +0 -1
  132. package/dist/bollharness-integration/context-router.js.map +0 -1
  133. package/dist/bollharness-integration/gate-state-machine.js.map +0 -1
  134. package/dist/bollharness-integration/gate-transition-hooks.js.map +0 -1
  135. package/dist/bollharness-integration/guard-checker.js.map +0 -1
  136. package/dist/bollharness-integration/index.js.map +0 -1
  137. package/dist/bollharness-integration/integration.js.map +0 -1
  138. package/dist/bollharness-integration/llm/pi-ai.d.ts +0 -60
  139. package/dist/bollharness-integration/pi-ecosystem-colony/index.d.ts +0 -153
  140. package/dist/bollharness-integration/pi-ecosystem-goals/index.d.ts +0 -136
  141. package/dist/bollharness-integration/pi-ecosystem-judgment/decision.d.ts +0 -117
  142. package/dist/bollharness-integration/pi-ecosystem-judgment/distillation.d.ts +0 -78
  143. package/dist/bollharness-integration/pi-ecosystem-judgment/index.d.ts +0 -139
  144. package/dist/bollharness-integration/pi-ecosystem-mcp/index.d.ts +0 -127
  145. package/dist/bollharness-integration/pi-ecosystem-subagents/index.d.ts +0 -95
  146. package/dist/bollharness-integration/skill-adapter.js.map +0 -1
  147. package/dist/constraint-runtime/src/_archive_helper.js +0 -9
  148. package/dist/constraint-runtime/src/agent/coordinator.js +0 -48
  149. package/dist/constraint-runtime/src/agent/index.js +0 -1
  150. package/dist/constraint-runtime/src/assistant/index.js +0 -12
  151. package/dist/constraint-runtime/src/bootstrap/index.js +0 -12
  152. package/dist/constraint-runtime/src/bootstrap_graph.js +0 -13
  153. package/dist/constraint-runtime/src/bridge/index.js +0 -12
  154. package/dist/constraint-runtime/src/buddy/index.js +0 -12
  155. package/dist/constraint-runtime/src/cli/index.js +0 -12
  156. package/dist/constraint-runtime/src/command_graph.js +0 -10
  157. package/dist/constraint-runtime/src/commands.js +0 -60
  158. package/dist/constraint-runtime/src/components/index.js +0 -12
  159. package/dist/constraint-runtime/src/constants/index.js +0 -12
  160. package/dist/constraint-runtime/src/constraint/budget.js +0 -22
  161. package/dist/constraint-runtime/src/constraint/budget.js.map +0 -1
  162. package/dist/constraint-runtime/src/constraint/index.js +0 -2
  163. package/dist/constraint-runtime/src/constraint/permission.js +0 -20
  164. package/dist/constraint-runtime/src/constraint/permission.js.map +0 -1
  165. package/dist/constraint-runtime/src/context.js +0 -30
  166. package/dist/constraint-runtime/src/coordinator/index.js +0 -12
  167. package/dist/constraint-runtime/src/cost_hook.js +0 -4
  168. package/dist/constraint-runtime/src/cost_tracker.js +0 -8
  169. package/dist/constraint-runtime/src/deferred_init.js +0 -10
  170. package/dist/constraint-runtime/src/direct_modes.js +0 -6
  171. package/dist/constraint-runtime/src/dynamic-tool-loader.js +0 -85
  172. package/dist/constraint-runtime/src/entrypoints/index.js +0 -12
  173. package/dist/constraint-runtime/src/execution_registry.js +0 -44
  174. package/dist/constraint-runtime/src/history.js +0 -9
  175. package/dist/constraint-runtime/src/hooks/index.js +0 -12
  176. package/dist/constraint-runtime/src/index.js +0 -26
  177. package/dist/constraint-runtime/src/ink.js +0 -4
  178. package/dist/constraint-runtime/src/keybindings/index.js +0 -12
  179. package/dist/constraint-runtime/src/memdir/index.js +0 -12
  180. package/dist/constraint-runtime/src/migrations/index.js +0 -12
  181. package/dist/constraint-runtime/src/models.js +0 -1
  182. package/dist/constraint-runtime/src/models.js.map +0 -1
  183. package/dist/constraint-runtime/src/moreright/index.js +0 -12
  184. package/dist/constraint-runtime/src/native_ts/index.js +0 -12
  185. package/dist/constraint-runtime/src/output_styles/index.js +0 -12
  186. package/dist/constraint-runtime/src/parity_audit.js +0 -12
  187. package/dist/constraint-runtime/src/plugins/index.js +0 -12
  188. package/dist/constraint-runtime/src/port_manifest.js +0 -11
  189. package/dist/constraint-runtime/src/prefetch.js +0 -9
  190. package/dist/constraint-runtime/src/query.js +0 -1
  191. package/dist/constraint-runtime/src/remote/index.js +0 -12
  192. package/dist/constraint-runtime/src/remote_runtime.js +0 -9
  193. package/dist/constraint-runtime/src/runtime/index.js +0 -1
  194. package/dist/constraint-runtime/src/runtime/session.js +0 -35
  195. package/dist/constraint-runtime/src/schemas/index.js +0 -12
  196. package/dist/constraint-runtime/src/screens/index.js +0 -12
  197. package/dist/constraint-runtime/src/server/index.js +0 -12
  198. package/dist/constraint-runtime/src/services/index.js +0 -12
  199. package/dist/constraint-runtime/src/session_store.js +0 -22
  200. package/dist/constraint-runtime/src/setup.js +0 -30
  201. package/dist/constraint-runtime/src/skills/index.js +0 -1
  202. package/dist/constraint-runtime/src/skills/skill-registry.js +0 -28
  203. package/dist/constraint-runtime/src/state/index.js +0 -12
  204. package/dist/constraint-runtime/src/system_init.js +0 -20
  205. package/dist/constraint-runtime/src/thinking/engine.js +0 -42
  206. package/dist/constraint-runtime/src/thinking/index.js +0 -1
  207. package/dist/constraint-runtime/src/tool_pool.js +0 -8
  208. package/dist/constraint-runtime/src/tools/OpenCLI/execAdapter.js +0 -7
  209. package/dist/constraint-runtime/src/tools/OpenCLI/listAdapters.js +0 -7
  210. package/dist/constraint-runtime/src/tools/OpenCLI/runCommand.js +0 -7
  211. package/dist/constraint-runtime/src/tools/PolymarketSDK/cancelOrder.js +0 -6
  212. package/dist/constraint-runtime/src/tools/PolymarketSDK/createOrder.js +0 -6
  213. package/dist/constraint-runtime/src/tools/PolymarketSDK/getMarket.js +0 -5
  214. package/dist/constraint-runtime/src/tools/PolymarketSDK/getOrders.js +0 -6
  215. package/dist/constraint-runtime/src/tools/PolymarketSDK/listMarkets.js +0 -4
  216. package/dist/constraint-runtime/src/tools/SafeSDK/confirmTransaction.js +0 -6
  217. package/dist/constraint-runtime/src/tools/SafeSDK/createTransaction.js +0 -8
  218. package/dist/constraint-runtime/src/tools/SafeSDK/deploySafe.js +0 -6
  219. package/dist/constraint-runtime/src/tools/SafeSDK/executeTransaction.js +0 -6
  220. package/dist/constraint-runtime/src/tools/SafeSDK/getBalance.js +0 -6
  221. package/dist/constraint-runtime/src/tools/SafeSDK/getPendingTransactions.js +0 -6
  222. package/dist/constraint-runtime/src/tools/SafeSDK/proposeTransaction.js +0 -6
  223. package/dist/constraint-runtime/src/tools/WalletTools/autoPay.js +0 -29
  224. package/dist/constraint-runtime/src/tools/WalletTools/createWallet.js +0 -10
  225. package/dist/constraint-runtime/src/tools/WalletTools/getBalance.js +0 -13
  226. package/dist/constraint-runtime/src/tools/WalletTools/importWallet.js +0 -22
  227. package/dist/constraint-runtime/src/tools/WalletTools/sendTransaction.js +0 -25
  228. package/dist/constraint-runtime/src/tools/WalletTools/signMessage.js +0 -10
  229. package/dist/constraint-runtime/src/tools/WalletTools/transferToken.js +0 -25
  230. package/dist/constraint-runtime/src/tools.js +0 -80
  231. package/dist/constraint-runtime/src/transcript.js +0 -19
  232. package/dist/constraint-runtime/src/types/index.js +0 -12
  233. package/dist/constraint-runtime/src/upstream_proxy/index.js +0 -12
  234. package/dist/constraint-runtime/src/utils/index.js +0 -12
  235. package/dist/constraint-runtime/src/vim/index.js +0 -12
  236. package/dist/constraint-runtime/src/voice/index.js +0 -12
  237. package/dist/constraints/index.js.map +0 -1
  238. package/dist/documents/reader.js.map +0 -1
  239. package/dist/llm/config-store.js.map +0 -1
  240. package/dist/llm/pi-ai.js.map +0 -1
  241. package/dist/network/agent-network.js.map +0 -1
  242. package/dist/network/iroh-integration.js.map +0 -1
  243. package/dist/network/iroh-transport.js.map +0 -1
  244. package/dist/network/p2p.js.map +0 -1
  245. package/dist/network/storage/adapters/json-adapter.js.map +0 -1
  246. package/dist/pi-ecosystem-colony/index.js.map +0 -1
  247. package/dist/pi-ecosystem-goals/index.js.map +0 -1
  248. package/dist/pi-ecosystem-judgment/decision.js.map +0 -1
  249. package/dist/pi-ecosystem-judgment/distillation.js.map +0 -1
  250. package/dist/pi-ecosystem-judgment/human-value-store.js.map +0 -1
  251. package/dist/pi-ecosystem-judgment/index.js.map +0 -1
  252. package/dist/pi-ecosystem-judgment/value-injection.js.map +0 -1
  253. package/dist/pi-ecosystem-mcp/index.js.map +0 -1
  254. package/dist/pi-ecosystem-subagents/index.js.map +0 -1
  255. package/dist/social/ant-colony/AdaptiveHeartbeat.js.map +0 -1
  256. package/dist/social/ant-colony/PheromoneEngine.js.map +0 -1
  257. package/dist/social/ant-colony/types.js.map +0 -1
  258. package/dist/social/channels/ChannelManager.js.map +0 -1
  259. package/dist/social/channels/DiapChannelBridge.js.map +0 -1
  260. package/dist/social/channels/InterestMatcher.js.map +0 -1
  261. package/dist/social/channels/types.js.map +0 -1
  262. package/dist/social/global-shared-context.js.map +0 -1
  263. package/dist/social/heartbeat.js.map +0 -1
  264. package/lefthook.yml +0 -29
  265. package/scripts/auto-evolve-loop.ts +0 -376
  266. package/scripts/auto-evolve-oneshot.sh +0 -155
  267. package/scripts/auto-evolve-snapshot.sh +0 -136
  268. package/scripts/build-cli.js +0 -216
  269. package/scripts/build-web.ts +0 -82
  270. package/scripts/detect-schema-changes.sh +0 -48
  271. package/scripts/diff-reviewer.ts +0 -159
  272. package/scripts/postinstall.js +0 -153
  273. package/scripts/weekly-report.ts +0 -364
  274. package/src/agents/agent-manifest-protocol.ts +0 -117
  275. package/src/agents/constraint-layer.ts +0 -309
  276. package/src/agents/iroh-secret.ts +0 -32
  277. package/src/agents/p2p-chat-tools.ts +0 -383
  278. package/src/agents/p2p-document-tools.ts +0 -347
  279. package/src/agents/pi-sdk.ts +0 -2462
  280. package/src/agents/protocol.ts +0 -398
  281. package/src/agents/shell-guard.ts +0 -417
  282. package/src/agents/shell-tool.ts +0 -103
  283. package/src/agents/skill-loader.ts +0 -202
  284. package/src/agents/subagent-manager.ts +0 -553
  285. package/src/agents/workflow-engine.ts +0 -332
  286. package/src/agents/workflow-pivot-loop.ts +0 -675
  287. package/src/bollharness/.sanitize-report.json +0 -13
  288. package/src/bollharness/CLAUDE.md +0 -73
  289. package/src/bollharness/LICENSE +0 -21
  290. package/src/bollharness/README.md +0 -143
  291. package/src/bollharness/README.zh-CN.md +0 -131
  292. package/src/bollharness/package.json +0 -20
  293. package/src/bollharness/reference/SOURCE-COMMIT.txt +0 -3
  294. package/src/bollharness/reference/boll-reference/scripts/hooks/.sanitize-report.json +0 -12
  295. package/src/bollharness/reference/boll-reference/scripts/hooks/find-boll-root.sh +0 -27
  296. package/src/bollharness/reference/boll-reference/scripts/hooks/precompact.sh +0 -57
  297. package/src/bollharness/reference/boll-reference/scripts/hooks/stop-evaluator.md +0 -57
  298. package/src/bollharness/schemas/metrics-jsonl-allowlist.json +0 -67
  299. package/src/bollharness/scripts/checks/next_decision_number.sh +0 -48
  300. package/src/bollharness/scripts/ci/count-components.sh +0 -65
  301. package/src/bollharness/scripts/context-fragments/artifact-linkage.md +0 -14
  302. package/src/bollharness/scripts/context-fragments/auth-consumers.md +0 -17
  303. package/src/bollharness/scripts/context-fragments/bridge-constitution.md +0 -13
  304. package/src/bollharness/scripts/context-fragments/catalyst-distributed.md +0 -18
  305. package/src/bollharness/scripts/context-fragments/closure-checklist.md +0 -13
  306. package/src/bollharness/scripts/context-fragments/contract-consumers.md +0 -15
  307. package/src/bollharness/scripts/context-fragments/db-shared-structures.md +0 -15
  308. package/src/bollharness/scripts/context-fragments/fixed-three-layers.md +0 -19
  309. package/src/bollharness/scripts/context-fragments/general-dev-principles.md +0 -11
  310. package/src/bollharness/scripts/context-fragments/issue-first.md +0 -8
  311. package/src/bollharness/scripts/context-fragments/mcp-parity.md +0 -16
  312. package/src/bollharness/scripts/context-fragments/pi-agent-operations.md +0 -108
  313. package/src/bollharness/scripts/context-fragments/protocol-consumers.md +0 -15
  314. package/src/bollharness/scripts/context-fragments/run-events-consumers.md +0 -15
  315. package/src/bollharness/scripts/context-fragments/scene-fidelity.md +0 -13
  316. package/src/bollharness/scripts/context-fragments/truth-source-hierarchy.md +0 -15
  317. package/src/bollharness/scripts/context-fragments/two-language.md +0 -15
  318. package/src/bollharness/scripts/context-fragments/version-sources.md +0 -14
  319. package/src/bollharness/scripts/hooks/find-project-root.sh +0 -47
  320. package/src/bollharness/scripts/hooks/inbox-poll.sh +0 -78
  321. package/src/bollharness/scripts/hooks/precompact.sh +0 -56
  322. package/src/bollharness/scripts/hooks/stop-evaluator.md +0 -83
  323. package/src/bollharness/scripts/sync-from-upstream.sh +0 -281
  324. package/src/bollharness/src/index.ts +0 -5
  325. package/src/bollharness/src/scripts/checks/check_adr_plan_numbering.ts +0 -11
  326. package/src/bollharness/src/scripts/checks/check_api_types.ts +0 -52
  327. package/src/bollharness/src/scripts/checks/check_artifact_link.ts +0 -156
  328. package/src/bollharness/src/scripts/checks/check_bridge_deps.ts +0 -11
  329. package/src/bollharness/src/scripts/checks/check_bugfix_binding.ts +0 -11
  330. package/src/bollharness/src/scripts/checks/check_bugfix_binding_ci.ts +0 -11
  331. package/src/bollharness/src/scripts/checks/check_doc_file_references.ts +0 -11
  332. package/src/bollharness/src/scripts/checks/check_doc_freshness.ts +0 -141
  333. package/src/bollharness/src/scripts/checks/check_doc_links.ts +0 -36
  334. package/src/bollharness/src/scripts/checks/check_file_existence_claims.ts +0 -11
  335. package/src/bollharness/src/scripts/checks/check_fragment_integrity.ts +0 -40
  336. package/src/bollharness/src/scripts/checks/check_hook_installed.ts +0 -70
  337. package/src/bollharness/src/scripts/checks/check_issue_closure.ts +0 -51
  338. package/src/bollharness/src/scripts/checks/check_mcp_parity.ts +0 -11
  339. package/src/bollharness/src/scripts/checks/check_security.ts +0 -54
  340. package/src/bollharness/src/scripts/checks/check_skill_parity.ts +0 -11
  341. package/src/bollharness/src/scripts/checks/check_versions.ts +0 -11
  342. package/src/bollharness/src/scripts/checks/finding.ts +0 -35
  343. package/src/bollharness/src/scripts/checks/next_decision_number.ts +0 -24
  344. package/src/bollharness/src/scripts/checks/regenerate_magic_docs.ts +0 -11
  345. package/src/bollharness/src/scripts/ci/detect_rebaseline_triggers.ts +0 -14
  346. package/src/bollharness/src/scripts/ci/scan_subprocess_cfg.ts +0 -14
  347. package/src/bollharness/src/scripts/ci/scan_verify_artifacts.ts +0 -14
  348. package/src/bollharness/src/scripts/ci/scan_yaml_schema.ts +0 -14
  349. package/src/bollharness/src/scripts/context_router.ts +0 -76
  350. package/src/bollharness/src/scripts/deploy-guard.ts +0 -182
  351. package/src/bollharness/src/scripts/guard-feedback.ts +0 -215
  352. package/src/bollharness/src/scripts/guard_router.ts +0 -194
  353. package/src/bollharness/src/scripts/hooks/_hook_output.js +0 -3
  354. package/src/bollharness/src/scripts/hooks/_hook_output.ts +0 -11
  355. package/src/bollharness/src/scripts/hooks/auto-python3.ts +0 -10
  356. package/src/bollharness/src/scripts/hooks/deploy-progress-on-session-end.ts +0 -10
  357. package/src/bollharness/src/scripts/hooks/failure-analyzer.ts +0 -10
  358. package/src/bollharness/src/scripts/hooks/gate-judgment-inject.ts +0 -111
  359. package/src/bollharness/src/scripts/hooks/gate-transition-judgment.ts +0 -74
  360. package/src/bollharness/src/scripts/hooks/inbox-ack.ts +0 -10
  361. package/src/bollharness/src/scripts/hooks/inbox-inject-on-start.ts +0 -10
  362. package/src/bollharness/src/scripts/hooks/inbox-validate.ts +0 -10
  363. package/src/bollharness/src/scripts/hooks/inbox-write-ledger.ts +0 -10
  364. package/src/bollharness/src/scripts/hooks/initializer-agent.ts +0 -10
  365. package/src/bollharness/src/scripts/hooks/loop-detection.ts +0 -83
  366. package/src/bollharness/src/scripts/hooks/owner-guard.ts +0 -10
  367. package/src/bollharness/src/scripts/hooks/precompact.ts +0 -10
  368. package/src/bollharness/src/scripts/hooks/review-agent-gatekeeper.ts +0 -10
  369. package/src/bollharness/src/scripts/hooks/risk-tracker.ts +0 -121
  370. package/src/bollharness/src/scripts/hooks/sanitize-on-read.ts +0 -10
  371. package/src/bollharness/src/scripts/hooks/session-reflection.ts +0 -12
  372. package/src/bollharness/src/scripts/hooks/session-start-magic-docs.ts +0 -12
  373. package/src/bollharness/src/scripts/hooks/session-start-reset-risk.ts +0 -12
  374. package/src/bollharness/src/scripts/hooks/session-start-toolkit-reminder.ts +0 -12
  375. package/src/bollharness/src/scripts/hooks/stop-evaluator.ts +0 -164
  376. package/src/bollharness/src/scripts/hooks/tool-call-counter.ts +0 -10
  377. package/src/bollharness/src/scripts/hooks/trace-analyzer.ts +0 -14
  378. package/src/bollharness/src/scripts/install/install-trust-token.ts +0 -13
  379. package/src/bollharness/src/scripts/install/multi_project_registry.ts +0 -13
  380. package/src/bollharness/src/scripts/install/phase2_auto.ts +0 -28
  381. package/src/bollharness/src/scripts/install/pre_commit_installer.ts +0 -10
  382. package/src/bollharness/src/scripts/install/tier_selector.ts +0 -10
  383. package/src/bollharness/src/scripts/install/transcript_miner.ts +0 -13
  384. package/src/bollharness/src/scripts/lib/claim_patterns.ts +0 -11
  385. package/src/bollharness/src/scripts/lib/sanitize_patterns.ts +0 -13
  386. package/src/bollharness/src/scripts/sanitize.ts +0 -9
  387. package/src/bollharness/templates/persona/default.json +0 -19
  388. package/src/bollharness/templates/scaffold/.gitignore.append +0 -16
  389. package/src/bollharness/templates/scaffold/CLAUDE.md +0 -89
  390. package/src/bollharness-integration/channel-judgment-engine.ts +0 -634
  391. package/src/bollharness-integration/context-chain-router.ts +0 -474
  392. package/src/bollharness-integration/context-router-judgment.ts +0 -339
  393. package/src/bollharness-integration/context-router.ts +0 -583
  394. package/src/bollharness-integration/gate-state-machine.ts +0 -444
  395. package/src/bollharness-integration/gate-transition-hooks.ts +0 -137
  396. package/src/bollharness-integration/guard-checker.ts +0 -451
  397. package/src/bollharness-integration/index.ts +0 -195
  398. package/src/bollharness-integration/integration.ts +0 -538
  399. package/src/bollharness-integration/judgment-prompts.yaml +0 -535
  400. package/src/bollharness-integration/llm-judgment-engine.ts +0 -712
  401. package/src/bollharness-integration/skill-adapter.ts +0 -646
  402. package/src/bootstrap/bootstrap.ts +0 -132
  403. package/src/bootstrap/context-collector.ts +0 -342
  404. package/src/bootstrap/lifecycle-hooks.ts +0 -176
  405. package/src/bootstrap/project-context.ts +0 -163
  406. package/src/cli/interface.ts +0 -211
  407. package/src/cli-entry.ts +0 -304
  408. package/src/constraints/index.ts +0 -6
  409. package/src/documents/reader.ts +0 -85
  410. package/src/documents/store.ts +0 -252
  411. package/src/electron-preload.ts +0 -25
  412. package/src/electron.ts +0 -200
  413. package/src/heartbeat/DaemonManager.ts +0 -283
  414. package/src/heartbeat/HealthMonitor.ts +0 -316
  415. package/src/heartbeat/StartupVerifier.ts +0 -223
  416. package/src/heartbeat/Watchdog.ts +0 -208
  417. package/src/heartbeat/index.ts +0 -109
  418. package/src/heartbeat/self-improve-bus.ts +0 -110
  419. package/src/heartbeat/types.ts +0 -82
  420. package/src/index.ts +0 -1690
  421. package/src/llm/audio-config-store.ts +0 -246
  422. package/src/llm/config-store.ts +0 -400
  423. package/src/llm/llm-judgment-client.ts +0 -470
  424. package/src/llm/pi-ai.ts +0 -558
  425. package/src/llm/video-config-store.ts +0 -257
  426. package/src/network/agent-network.ts +0 -800
  427. package/src/network/hybrid-messenger.ts +0 -199
  428. package/src/network/iroh-bootstrap.ts +0 -57
  429. package/src/network/iroh-discovery.ts +0 -208
  430. package/src/network/iroh-integration.ts +0 -158
  431. package/src/network/iroh-transport.ts +0 -637
  432. package/src/network/known-peers.ts +0 -102
  433. package/src/network/p2p-direct.ts +0 -240
  434. package/src/network/p2p-secret.ts +0 -153
  435. package/src/network/p2p.ts +0 -964
  436. package/src/network/storage/adapters/json-adapter.ts +0 -454
  437. package/src/network/storage/index.ts +0 -203
  438. package/src/network/storage/types.ts +0 -166
  439. package/src/security/builtin-guards.ts +0 -162
  440. package/src/security/context-router-tool.ts +0 -122
  441. package/src/security/react-harness.ts +0 -177
  442. package/src/security/tool-gate.ts +0 -294
  443. package/src/social/ant-colony/index.js +0 -19
  444. package/src/social/channels/ChannelManager.ts +0 -485
  445. package/src/social/channels/DiapChannelBridge.ts +0 -501
  446. package/src/social/channels/InterestMatcher.ts +0 -189
  447. package/src/social/channels/agent-workflow-config.json +0 -214
  448. package/src/social/channels/agent-workflow-config.yaml +0 -334
  449. package/src/social/channels/channel-agent-session.ts +0 -407
  450. package/src/social/channels/channel-heartbeat-agent.ts +0 -622
  451. package/src/social/channels/diap-doc-parser.ts +0 -282
  452. package/src/social/channels/harness-workflow-integrator.ts +0 -594
  453. package/src/social/channels/index.ts +0 -22
  454. package/src/social/channels/types.ts +0 -115
  455. package/src/social/global-shared-context.ts +0 -506
  456. package/src/social/heartbeat.ts +0 -1057
  457. package/src/social/persona/enhanced-persona.ts +0 -359
  458. package/src/types.d.ts +0 -12
  459. package/src/utils/auto-evolve-policy.ts +0 -138
  460. package/src/utils/auto-update.ts +0 -482
  461. package/src/utils/clamp.ts +0 -5
  462. package/src/web/agent-delegate-server.ts +0 -148
  463. package/src/web/api-config.html +0 -520
  464. package/src/web/client.js +0 -4898
  465. package/src/web/components/p2p/P2PModal.tsx +0 -416
  466. package/src/web/components/p2p/index.ts +0 -566
  467. package/src/web/components/p2p/index.tsx +0 -297
  468. package/src/web/components/p2p/p2p-connection.ts +0 -338
  469. package/src/web/components/p2p/p2p-identity.ts +0 -92
  470. package/src/web/components/p2p/p2p-manager.ts +0 -147
  471. package/src/web/components/p2p/p2p-messages.ts +0 -219
  472. package/src/web/components/p2p/p2p-modal.ts +0 -685
  473. package/src/web/components/p2p/p2p-store-memory.ts +0 -162
  474. package/src/web/components/p2p/p2p-tools.ts +0 -315
  475. package/src/web/components/p2p/types.ts +0 -170
  476. package/src/web/components/wallet-viem.mjs +0 -118
  477. package/src/web/design.md +0 -99
  478. package/src/web/icons/apple-touch-icon.png +0 -0
  479. package/src/web/icons/favicon-16x16.png +0 -0
  480. package/src/web/icons/favicon-192x192.png +0 -0
  481. package/src/web/icons/favicon-32x32.png +0 -0
  482. package/src/web/icons/favicon-48x48.png +0 -0
  483. package/src/web/icons/favicon-512x512.png +0 -0
  484. package/src/web/icons/favicon.icns +0 -0
  485. package/src/web/icons/favicon.ico +0 -0
  486. package/src/web/icons/icon.png +0 -0
  487. package/src/web/icons/image.png +0 -0
  488. package/src/web/index.html +0 -382
  489. package/src/web/iroh-delegate-transport.ts +0 -139
  490. package/src/web/manifest.json +0 -21
  491. package/src/web/server.ts +0 -5571
  492. package/src/web/style.css +0 -4455
  493. package/staging/auto-evolve/clean-001/.review-verdict +0 -9
  494. package/staging/auto-evolve/clean-001/clean-001.patch +0 -14
  495. package/staging/auto-evolve/e2e-001/.patch-id +0 -1
  496. package/staging/auto-evolve/e2e-001/.review-verdict +0 -12
  497. package/staging/auto-evolve/e2e-001/e2e-001.patch +0 -11
  498. package/staging/auto-evolve/test-bad/.review-verdict +0 -12
  499. package/staging/auto-evolve/test-bad/test-bad.patch +0 -11
  500. package/tsconfig.cli.json +0 -16
  501. package/tsconfig.electron.json +0 -20
  502. package/tsconfig.json +0 -18
@@ -1,964 +0,0 @@
1
- import { createLibp2p } from 'libp2p';
2
- import { tcp } from '@libp2p/tcp';
3
- import { multiaddr as createMultiaddr } from '@multiformats/multiaddr';
4
- import { circuitRelayTransport } from '@libp2p/circuit-relay-v2';
5
- import { autoNAT } from '@libp2p/autonat';
6
- import { uPnPNAT } from '@libp2p/upnp-nat';
7
- import * as fs from 'fs/promises';
8
- import * as path from 'path';
9
-
10
- const PEER_STORE_PATH = path.join(process.env.HOME || '/tmp', '.bolloon', 'peer-store.json');
11
- const RECONNECT_DELAY_MS = 5000;
12
- const MAX_RECONNECT_ATTEMPTS = 3;
13
-
14
- export interface PersistentPeerInfo {
15
- peerId: string;
16
- multiaddrs: string[];
17
- did?: string;
18
- lastConnected?: number;
19
- lastAttempt?: number;
20
- name?: string;
21
- relayAddr?: string;
22
- canRelay?: boolean;
23
- }
24
-
25
- export interface P2PNode {
26
- peerId: string;
27
- multiaddrs: string[];
28
- relayAddr?: string;
29
- }
30
-
31
- export interface NatStatus {
32
- reachable: boolean;
33
- type?: 'public' | 'cone' | 'symmetric' | 'unknown';
34
- externalAddr?: string;
35
- }
36
-
37
- export interface PendingRequest {
38
- id: string;
39
- type: string;
40
- payload: string;
41
- timestamp: number;
42
- resolve: (response: Uint8Array) => void;
43
- reject: (error: Error) => void;
44
- timeout: ReturnType<typeof setTimeout>;
45
- }
46
-
47
- export interface PendingRequestInfo {
48
- requestId: string;
49
- type: string;
50
- payload: string;
51
- fromPeerId: string;
52
- did?: string;
53
- timestamp: number;
54
- }
55
-
56
- export interface ResponseHandler {
57
- (payload: string, from: string, did?: string): void;
58
- }
59
-
60
- export class RequestResponseManager {
61
- private pendingRequests: Map<string, PendingRequest> = new Map();
62
- private responseHandlers: Map<string, ResponseHandler> = new Map();
63
- private requestTimeoutMs: number = 30000;
64
- private cleanupInterval: ReturnType<typeof setInterval> | null = null;
65
-
66
- constructor() {
67
- this.startCleanup();
68
- }
69
-
70
- private startCleanup(): void {
71
- this.cleanupInterval = setInterval(() => {
72
- const now = Date.now();
73
- for (const [id, request] of this.pendingRequests) {
74
- if (now - request.timestamp > this.requestTimeoutMs) {
75
- clearTimeout(request.timeout);
76
- request.reject(new Error(`Request ${id} timed out`));
77
- this.pendingRequests.delete(id);
78
- }
79
- }
80
- }, 10000);
81
- }
82
-
83
- async sendRequest(
84
- peerId: string,
85
- type: string,
86
- payload: string,
87
- sendFn: (peerId: string, data: Uint8Array) => Promise<void>,
88
- onResponse?: (peerId: string) => Promise<Uint8Array | null>
89
- ): Promise<Uint8Array | null> {
90
- const requestId = crypto.randomUUID();
91
- const data = new TextEncoder().encode(
92
- `REQ:${requestId}|${type}:${payload}`
93
- );
94
-
95
- return new Promise((resolve, reject) => {
96
- const timeout = setTimeout(() => {
97
- this.pendingRequests.delete(requestId);
98
- reject(new Error(`Request ${requestId} timed out after ${this.requestTimeoutMs}ms`));
99
- }, this.requestTimeoutMs);
100
-
101
- this.pendingRequests.set(requestId, {
102
- id: requestId,
103
- type,
104
- payload,
105
- timestamp: Date.now(),
106
- resolve,
107
- reject,
108
- timeout
109
- });
110
-
111
- sendFn(peerId, data).catch(err => {
112
- clearTimeout(timeout);
113
- this.pendingRequests.delete(requestId);
114
- reject(err);
115
- });
116
- });
117
- }
118
-
119
- handleResponse(requestId: string, responseData: Uint8Array): void {
120
- const request = this.pendingRequests.get(requestId);
121
- if (request) {
122
- clearTimeout(request.timeout);
123
- request.resolve(responseData);
124
- this.pendingRequests.delete(requestId);
125
- }
126
- }
127
-
128
- registerResponseHandler(type: string, handler: ResponseHandler): void {
129
- this.responseHandlers.set(type, handler);
130
- }
131
-
132
- getResponseHandler(type: string): ResponseHandler | undefined {
133
- return this.responseHandlers.get(type);
134
- }
135
-
136
- setRequestTimeout(ms: number): void {
137
- this.requestTimeoutMs = ms;
138
- }
139
-
140
- getPendingCount(): number {
141
- return this.pendingRequests.size;
142
- }
143
-
144
- shutdown(): void {
145
- if (this.cleanupInterval) {
146
- clearInterval(this.cleanupInterval);
147
- }
148
- for (const request of this.pendingRequests.values()) {
149
- clearTimeout(request.timeout);
150
- request.reject(new Error('Shutting down'));
151
- }
152
- this.pendingRequests.clear();
153
- }
154
- }
155
-
156
- export class P2PNetwork {
157
- private node: any = null;
158
- private messageHandlers: Map<string, (msg: Uint8Array, from: string, did?: string) => void> = new Map();
159
- private offlineMessages: Map<string, Uint8Array[]> = new Map();
160
- private persistentPeers: Map<string, PersistentPeerInfo> = new Map();
161
- private reconnectTimers: Map<string, ReturnType<typeof setTimeout>> = new Map();
162
- private ownDid: string | null = null;
163
- private peerStorePath: string;
164
- private natStatus: NatStatus = { reachable: false };
165
- private relayServerAddr: string | null = null;
166
- private requestResponseManager: RequestResponseManager = new RequestResponseManager();
167
- private pendingResponseHandlers: Map<string, (response: string, from: string) => void> = new Map();
168
- private pendingRequests: Map<string, PendingRequestInfo> = new Map();
169
- private requestTimeoutMs: number = 30000;
170
-
171
- // 新增: 消息存储层
172
- private messageStore: any = null;
173
- private offlineDeliveryInterval: ReturnType<typeof setInterval> | null = null;
174
-
175
- constructor() {
176
- this.peerStorePath = PEER_STORE_PATH;
177
- }
178
-
179
- async enablePersistence(): Promise<void> {
180
- try {
181
- const { JsonMessageStore } = await import('./storage/adapters/json-adapter.js');
182
- const baseDir = path.join(process.env.HOME || '/tmp', '.bolloon', 'messages-libp2p');
183
- this.messageStore = new JsonMessageStore({ baseDir });
184
- await this.messageStore.initialize();
185
- this.startOfflineDeliveryLoop();
186
- console.log('[P2P] Persistence enabled');
187
- } catch (e) {
188
- console.warn('[P2P] Failed to enable persistence:', e);
189
- }
190
- }
191
-
192
- private startOfflineDeliveryLoop(): void {
193
- if (!this.messageStore) return;
194
-
195
- this.offlineDeliveryInterval = setInterval(async () => {
196
- for (const peerId of this.getPeers()) {
197
- const offlineMsgs = await this.messageStore.getOfflineMessages(peerId);
198
-
199
- for (const msg of offlineMsgs) {
200
- if (msg.retryCount >= 10) {
201
- await this.messageStore.dequeueOfflineMessage(msg.id);
202
- continue;
203
- }
204
-
205
- try {
206
- const payload = Uint8Array.from(atob(msg.payload), c => c.charCodeAt(0));
207
- const success = await this.sendMessageDirect(peerId, msg.type, payload);
208
-
209
- if (success) {
210
- await this.messageStore.dequeueOfflineMessage(msg.id);
211
- console.log(`[P2P] Delivered offline message to ${peerId.substring(0, 12)}...`);
212
- }
213
- } catch {
214
- await this.messageStore.incrementOfflineRetry(msg.id);
215
- }
216
- }
217
- }
218
- }, 5000);
219
- }
220
-
221
- private async sendMessageDirect(peerId: string, type: string, payload: string | Uint8Array): Promise<boolean> {
222
- if (!this.node) return false;
223
-
224
- try {
225
- const data = typeof payload === 'string'
226
- ? new TextEncoder().encode(`${type}:${payload}`)
227
- : payload;
228
-
229
- const ma = createMultiaddr(`/p2p/${peerId}`);
230
- const { stream } = await this.node.dialProtocol(ma, '/agent/message');
231
- stream.send(data);
232
- return true;
233
- } catch {
234
- return false;
235
- }
236
- }
237
-
238
- async createNode(config?: {
239
- bootstrapPeers?: string[];
240
- ownDid?: string;
241
- enableRelay?: boolean;
242
- enableAutoNat?: boolean;
243
- enableUPnP?: boolean;
244
- relayPeers?: string[];
245
- }): Promise<P2PNode> {
246
- this.ownDid = config?.ownDid || null;
247
- const enableRelay = config?.enableRelay ?? true;
248
- const enableAutoNat = config?.enableAutoNat ?? true;
249
- const enableUPnP = config?.enableUPnP ?? true;
250
-
251
- const transports = [tcp()];
252
- const services: any = {};
253
-
254
- if (enableRelay) {
255
- try {
256
- const relayTransport = circuitRelayTransport();
257
- transports.push(relayTransport as any);
258
- } catch (e) {
259
- console.warn(`[P2P] Failed to add circuit relay transport:`, e);
260
- }
261
- }
262
-
263
- if (enableAutoNat) {
264
- try {
265
- services.autonat = autoNAT();
266
- } catch (e) {
267
- console.warn(`[P2P] Failed to setup AutoNAT:`, e);
268
- }
269
- }
270
-
271
- if (enableUPnP) {
272
- try {
273
- services.upnpNAT = uPnPNAT();
274
- } catch (e) {
275
- console.warn(`[P2P] Failed to setup UPnP:`, e);
276
- }
277
- }
278
-
279
- this.node = await createLibp2p({
280
- addresses: {
281
- listen: ['/ip4/0.0.0.0/tcp/0']
282
- },
283
- transports,
284
- services
285
- });
286
-
287
- this.node.addEventListener('peer-relay-registry', (evt: any) => {
288
- if (evt.detail?.relayAddr) {
289
- this.relayServerAddr = evt.detail.relayAddr;
290
- console.log(`[P2P] Relay address available: ${this.relayServerAddr}`);
291
- }
292
- });
293
-
294
- await this.node.start();
295
-
296
- const peerId = this.node.peerId.toString();
297
- const multiaddrs = this.node.getMultiaddrs().map((addr: any) => addr.toString());
298
-
299
- if (config?.relayPeers && config.relayPeers.length > 0) {
300
- for (const relayAddr of config.relayPeers) {
301
- try {
302
- const ma = createMultiaddr(relayAddr);
303
- await this.node.dial(ma);
304
- console.log(`[P2P] Connected to relay peer: ${relayAddr}`);
305
- } catch (e) {
306
- console.warn(`[P2P] Failed to connect to relay peer ${relayAddr}:`, e);
307
- }
308
- }
309
- }
310
-
311
- await this.loadPersistentPeers();
312
-
313
- if (config?.bootstrapPeers) {
314
- await this.connectToBootstrapPeers(config.bootstrapPeers);
315
- }
316
-
317
- await this.reconnectPersistentPeers();
318
-
319
- this.checkNatStatus();
320
-
321
- this.setupMessageHandler();
322
-
323
- return {
324
- peerId,
325
- multiaddrs,
326
- relayAddr: this.relayServerAddr || undefined
327
- };
328
- }
329
-
330
- private async checkNatStatus(): Promise<void> {
331
- if (!this.node) return;
332
-
333
- try {
334
- const connections = this.node.getConnections();
335
- if (connections.length > 0) {
336
- for (const conn of connections) {
337
- const addr = conn.remoteAddr?.toString();
338
- if (addr && addr.includes('127.0.0.1')) continue;
339
- this.natStatus = {
340
- reachable: true,
341
- type: 'unknown',
342
- externalAddr: addr
343
- };
344
- console.log(`[P2P] NAT status: reachable, external address: ${addr}`);
345
- break;
346
- }
347
- }
348
- } catch (e) {
349
- console.warn(`[P2P] NAT status check failed:`, e);
350
- }
351
- }
352
-
353
- getNatStatus(): NatStatus {
354
- return this.natStatus;
355
- }
356
-
357
- getRelayAddress(): string | null {
358
- return this.relayServerAddr;
359
- }
360
-
361
- async createRelayReservation(): Promise<string | null> {
362
- if (!this.node) return null;
363
-
364
- try {
365
- const relayService = this.node.services.get('circuit-relay');
366
- if (!relayService) {
367
- console.log(`[P2P] Circuit relay service not available`);
368
- return null;
369
- }
370
-
371
- const reservation = await relayService.reserve();
372
- if (reservation) {
373
- this.relayServerAddr = `/p2p/${this.node.peerId.toString()}/p2p-circuit`;
374
- console.log(`[P2P] Created relay reservation: ${this.relayServerAddr}`);
375
- return this.relayServerAddr;
376
- }
377
- } catch (e) {
378
- console.warn(`[P2P] Failed to create relay reservation:`, e);
379
- }
380
- return null;
381
- }
382
-
383
- async dialViaRelay(relayAddr: string, targetPeerId: string): Promise<boolean> {
384
- if (!this.node) return false;
385
-
386
- try {
387
- const ma = createMultiaddr(`${relayAddr}/p2p/${targetPeerId}`);
388
- await this.node.dial(ma);
389
- console.log(`[P2P] Dialed ${targetPeerId} via relay ${relayAddr}`);
390
- return true;
391
- } catch (e) {
392
- console.warn(`[P2P] Failed to dial via relay:`, e);
393
- return false;
394
- }
395
- }
396
-
397
- private async loadPersistentPeers(): Promise<void> {
398
- try {
399
- const data = await fs.readFile(this.peerStorePath, 'utf-8');
400
- const peers: PersistentPeerInfo[] = JSON.parse(data);
401
- for (const peer of peers) {
402
- this.persistentPeers.set(peer.peerId, peer);
403
- }
404
- console.log(`[P2P] Loaded ${peers.length} persistent peers`);
405
- } catch {
406
- console.log(`[P2P] No existing peer store found, starting fresh`);
407
- }
408
- }
409
-
410
- private async savePersistentPeers(): Promise<void> {
411
- try {
412
- const dir = path.dirname(this.peerStorePath);
413
- await fs.mkdir(dir, { recursive: true });
414
- const peers = Array.from(this.persistentPeers.values());
415
- await fs.writeFile(this.peerStorePath, JSON.stringify(peers, null, 2));
416
- } catch (e) {
417
- console.warn(`[P2P] Failed to save peer store:`, e);
418
- }
419
- }
420
-
421
- addPersistentPeer(peerInfo: PersistentPeerInfo): void {
422
- peerInfo.lastConnected = Date.now();
423
- this.persistentPeers.set(peerInfo.peerId, peerInfo);
424
- this.savePersistentPeers();
425
- }
426
-
427
- removePersistentPeer(peerId: string): void {
428
- this.persistentPeers.delete(peerId);
429
- this.savePersistentPeers();
430
- }
431
-
432
- getPersistentPeers(): PersistentPeerInfo[] {
433
- return Array.from(this.persistentPeers.values());
434
- }
435
-
436
- private async reconnectPersistentPeers(): Promise<void> {
437
- const now = Date.now();
438
- for (const [peerId, peerInfo] of this.persistentPeers) {
439
- if (peerInfo.lastAttempt && now - peerInfo.lastAttempt < RECONNECT_DELAY_MS) {
440
- continue;
441
- }
442
- if (peerInfo.multiaddrs && peerInfo.multiaddrs.length > 0) {
443
- await this.attemptReconnect(peerId, peerInfo);
444
- }
445
- }
446
- }
447
-
448
- private async attemptReconnect(peerId: string, peerInfo: PersistentPeerInfo, attempt = 0): Promise<void> {
449
- if (!this.node) return;
450
-
451
- try {
452
- const hasConn = this.node.getConnections?.(peerInfo.peerId);
453
- if (hasConn && hasConn.length > 0) {
454
- console.log(`[P2P] Already connected to ${peerId}`);
455
- await this.deliverOfflineMessages(peerId);
456
- return;
457
- }
458
- } catch {}
459
-
460
- console.log(`[P2P] Reconnecting to ${peerId} (attempt ${attempt + 1})...`);
461
-
462
- for (const addr of peerInfo.multiaddrs) {
463
- try {
464
- const ma = createMultiaddr(addr);
465
- await this.node.dial(ma);
466
- peerInfo.lastConnected = Date.now();
467
- peerInfo.lastAttempt = undefined;
468
- this.persistentPeers.set(peerId, peerInfo);
469
- await this.savePersistentPeers();
470
- console.log(`[P2P] Reconnected to ${peerId} at ${addr}`);
471
- await this.deliverOfflineMessages(peerId);
472
- return;
473
- } catch (e) {
474
- console.warn(`[P2P] Failed to reconnect to ${addr}:`, e);
475
- }
476
- }
477
-
478
- peerInfo.lastAttempt = Date.now();
479
- this.persistentPeers.set(peerId, peerInfo);
480
-
481
- if (attempt < MAX_RECONNECT_ATTEMPTS - 1) {
482
- const timer = setTimeout(() => {
483
- this.reconnectTimers.delete(peerId);
484
- this.attemptReconnect(peerId, peerInfo, attempt + 1);
485
- }, RECONNECT_DELAY_MS * (attempt + 1));
486
- this.reconnectTimers.set(peerId, timer);
487
- }
488
- }
489
-
490
- private async deliverOfflineMessages(peerId: string): Promise<void> {
491
- const messages = this.offlineMessages.get(peerId) || [];
492
- this.offlineMessages.delete(peerId);
493
-
494
- for (const data of messages) {
495
- try {
496
- await this.sendRawMessage(peerId, data);
497
- } catch (e) {
498
- console.warn(`[P2P] Failed to deliver offline message to ${peerId}:`, e);
499
- }
500
- }
501
-
502
- if (messages.length > 0) {
503
- console.log(`[P2P] Delivered ${messages.length} offline messages to ${peerId}`);
504
- }
505
- }
506
-
507
- private async connectToBootstrapPeers(peers: string[]): Promise<void> {
508
- if (!this.node) return;
509
-
510
- for (const addr of peers) {
511
- try {
512
- const ma = createMultiaddr(addr);
513
- await this.node.dial(ma);
514
- console.log(`[P2P] Connected to bootstrap peer: ${addr}`);
515
- const peerId = (ma as any).getPeerId?.() || (ma as any).peerId;
516
- if (peerId) {
517
- this.addPersistentPeer({ peerId, multiaddrs: [addr] });
518
- }
519
- } catch (e) {
520
- console.warn(`[P2P] Failed to connect to bootstrap peer ${addr}:`, e);
521
- }
522
- }
523
- }
524
-
525
- private setupMessageHandler(): void {
526
- if (!this.node) return;
527
-
528
- const network = this;
529
-
530
- this.node.handle('/agent/message', async ({ stream, connection }: any) => {
531
- try {
532
- const chunks: Uint8Array[] = [];
533
- for await (const chunk of stream) {
534
- chunks.push(chunk instanceof Uint8Array ? chunk : chunk.subarray());
535
- }
536
-
537
- const data = new Uint8Array(chunks.reduce((acc, c) => acc + c.length, 0));
538
- let offset = 0;
539
- for (const chunk of chunks) {
540
- data.set(chunk, offset);
541
- offset += chunk.length;
542
- }
543
-
544
- const fromPeerId = connection.remotePeer.toString();
545
- const messageStr = new TextDecoder().decode(data);
546
- const colonIdx = messageStr.indexOf(':');
547
- const didMarker = 'DID:';
548
- let did: string | undefined;
549
- let type = 'message';
550
- let payload = '';
551
- let requestId: string | undefined = undefined;
552
-
553
- if (messageStr.startsWith(didMarker)) {
554
- const didEndIdx = messageStr.indexOf('|');
555
- if (didEndIdx > 0) {
556
- did = messageStr.substring(didMarker.length, didEndIdx);
557
- const afterDid = messageStr.substring(didEndIdx + 1);
558
- const payloadColonIdx = afterDid.indexOf(':');
559
- if (payloadColonIdx > 0) {
560
- type = afterDid.substring(0, payloadColonIdx);
561
- payload = afterDid.substring(payloadColonIdx + 1);
562
- } else {
563
- type = afterDid;
564
- payload = '';
565
- }
566
- } else {
567
- type = 'message';
568
- payload = messageStr.substring(didMarker.length);
569
- }
570
- } else if (messageStr.startsWith('REQ:')) {
571
- // Request message format: REQ:<requestId>|<optional DID>|type:payload
572
- const reqMatch = messageStr.match(/^REQ:([^|]+)\|(.*)$/);
573
- if (reqMatch) {
574
- requestId = reqMatch[1];
575
- const afterReq = reqMatch[2];
576
- // Check if it has DID prefix
577
- if (afterReq.startsWith('DID:')) {
578
- const didEndIdx = afterReq.indexOf('|');
579
- if (didEndIdx > 0) {
580
- did = afterReq.substring(4, didEndIdx);
581
- const afterDid = afterReq.substring(didEndIdx + 1);
582
- const payloadColonIdx = afterDid.indexOf(':');
583
- if (payloadColonIdx > 0) {
584
- type = afterDid.substring(0, payloadColonIdx);
585
- payload = afterDid.substring(payloadColonIdx + 1);
586
- } else {
587
- type = afterDid;
588
- payload = '';
589
- }
590
- }
591
- } else {
592
- const payloadColonIdx = afterReq.indexOf(':');
593
- if (payloadColonIdx > 0) {
594
- type = afterReq.substring(0, payloadColonIdx);
595
- payload = afterReq.substring(payloadColonIdx + 1);
596
- } else {
597
- type = afterReq;
598
- payload = '';
599
- }
600
- }
601
- } else {
602
- type = 'message';
603
- payload = messageStr.substring(4);
604
- }
605
- } else if (messageStr.startsWith('RESP:')) {
606
- // Response message format: RESP:<requestId>|type:payload
607
- const respMatch = messageStr.match(/^RESP:([^|]+)\|(.*)$/);
608
- if (respMatch) {
609
- requestId = respMatch[1];
610
- const afterResp = respMatch[2];
611
- const payloadColonIdx = afterResp.indexOf(':');
612
- if (payloadColonIdx > 0) {
613
- type = afterResp.substring(0, payloadColonIdx);
614
- payload = afterResp.substring(payloadColonIdx + 1);
615
- } else {
616
- type = afterResp;
617
- payload = '';
618
- }
619
- } else {
620
- type = 'response';
621
- payload = messageStr.substring(5);
622
- }
623
- } else {
624
- type = colonIdx > 0 ? messageStr.substring(0, colonIdx) : messageStr;
625
- payload = colonIdx > 0 ? messageStr.substring(colonIdx + 1) : '';
626
- }
627
-
628
- if (!network.persistentPeers.has(fromPeerId)) {
629
- network.addPersistentPeer({
630
- peerId: fromPeerId,
631
- multiaddrs: connection.remoteAddr ? [connection.remoteAddr.toString()] : [],
632
- did
633
- });
634
- } else {
635
- const existing = network.persistentPeers.get(fromPeerId)!;
636
- if (did && !existing.did) {
637
- existing.did = did;
638
- network.persistentPeers.set(fromPeerId, existing);
639
- network.savePersistentPeers();
640
- }
641
- }
642
-
643
- const handler = network.messageHandlers.get(type);
644
- if (handler) {
645
- handler(data, fromPeerId, did);
646
- } else if (type === 'RESP' && requestId) {
647
- // Handle response message - resolve the pending request
648
- const pending = network.pendingResponses.get(requestId);
649
- if (pending) {
650
- clearTimeout(pending.timeout);
651
- pending.resolve(payload);
652
- network.pendingResponses.delete(requestId);
653
- } else {
654
- console.log(`[P2P] Response for unknown request ${requestId}`);
655
- }
656
- } else if (type === 'REQ' && requestId) {
657
- // Handle request message - store for later response
658
- network.storePendingRequest(requestId, { type: payload.split(':')[0] || 'request', payload, fromPeerId, did });
659
- } else {
660
- network.storeOfflineMessage(fromPeerId, data);
661
- }
662
- } catch (e) {
663
- console.error(`[P2P] Message handler error:`, e);
664
- }
665
- });
666
- }
667
-
668
- private async sendRawMessage(peerId: string, data: Uint8Array): Promise<void> {
669
- if (!this.node) throw new Error('Node not initialized');
670
-
671
- const ma = createMultiaddr(`/p2p/${peerId}`);
672
- const { stream } = await this.node.dialProtocol(ma, '/agent/message');
673
- stream.send(data);
674
- }
675
-
676
- private storeOfflineMessage(peerId: string, data: Uint8Array): void {
677
- const messages = this.offlineMessages.get(peerId) || [];
678
- messages.push(data);
679
- this.offlineMessages.set(peerId, messages);
680
- console.log(`[P2P] Stored offline message for ${peerId}, total: ${messages.length}`);
681
- }
682
-
683
- getOfflineMessages(peerId: string): Uint8Array[] {
684
- const messages = this.offlineMessages.get(peerId) || [];
685
- this.offlineMessages.delete(peerId);
686
- return messages;
687
- }
688
-
689
- private storePendingRequest(requestId: string, info: Omit<PendingRequestInfo, 'requestId' | 'timestamp'>): void {
690
- this.pendingRequests.set(requestId, {
691
- ...info,
692
- requestId,
693
- timestamp: Date.now()
694
- });
695
- console.log(`[P2P] Stored pending request ${requestId} from ${info.fromPeerId}`);
696
- }
697
-
698
- getPendingRequest(requestId: string): PendingRequestInfo | undefined {
699
- return this.pendingRequests.get(requestId);
700
- }
701
-
702
- removePendingRequest(requestId: string): void {
703
- this.pendingRequests.delete(requestId);
704
- }
705
-
706
- getPendingRequests(): PendingRequestInfo[] {
707
- return Array.from(this.pendingRequests.values());
708
- }
709
-
710
- onMessage(type: string, handler: (msg: Uint8Array, from: string, did?: string) => void): void {
711
- this.messageHandlers.set(type, handler);
712
- }
713
-
714
- /**
715
- * Send a message and wait for a response (request-response pattern)
716
- */
717
- async sendRequest(
718
- peerId: string,
719
- type: string,
720
- payload: string,
721
- timeoutMs: number = 30000
722
- ): Promise<string | null> {
723
- if (!this.node) {
724
- throw new Error('Node not initialized');
725
- }
726
-
727
- const requestId = crypto.randomUUID();
728
-
729
- let data: Uint8Array;
730
- if (this.ownDid) {
731
- data = new TextEncoder().encode(`REQ:${requestId}|DID:${this.ownDid}|${type}:${payload}`);
732
- } else {
733
- data = new TextEncoder().encode(`REQ:${requestId}|${type}:${payload}`);
734
- }
735
-
736
- return new Promise((resolve, reject) => {
737
- const timeout = setTimeout(() => {
738
- this.pendingResponses.delete(requestId);
739
- reject(new Error(`Request to ${peerId} timed out after ${timeoutMs}ms`));
740
- }, timeoutMs);
741
-
742
- // Store the pending response handler
743
- this.pendingResponses.set(requestId, {
744
- resolve: (response: string) => {
745
- clearTimeout(timeout);
746
- resolve(response);
747
- },
748
- reject: (err: Error) => {
749
- clearTimeout(timeout);
750
- reject(err);
751
- },
752
- timeout
753
- });
754
-
755
- this.sendRawMessage(peerId, data).catch(err => {
756
- clearTimeout(timeout);
757
- this.pendingResponses.delete(requestId);
758
- reject(err);
759
- });
760
- });
761
- }
762
-
763
- private pendingResponses: Map<string, {
764
- resolve: (response: string) => void;
765
- reject: (error: Error) => void;
766
- timeout: ReturnType<typeof setTimeout>;
767
- }> = new Map();
768
-
769
- /**
770
- * Register a handler for responses (used by the receiving side)
771
- */
772
- onResponse(type: string, handler: (payload: string, from: string, did?: string, requestId?: string) => void): void {
773
- // Store as pendingResponseHandlers-shaped wrapper. Extra args (did, requestId) are not
774
- // available in pendingResponseHandlers signature, so ignore them when invoked.
775
- this.pendingResponseHandlers.set(type, (responseData: string, from: string) => {
776
- handler(responseData, from, undefined, undefined);
777
- });
778
- }
779
-
780
- /**
781
- * Send a response back to a peer
782
- */
783
- async sendResponse(peerId: string, requestId: string, type: string, responsePayload: string): Promise<void> {
784
- if (!this.node) {
785
- throw new Error('Node not initialized');
786
- }
787
-
788
- const data = new TextEncoder().encode(`RESP:${requestId}|${type}:${responsePayload}`);
789
-
790
- try {
791
- await this.sendRawMessage(peerId, data);
792
- } catch (e) {
793
- console.warn(`[P2P] Failed to send response to ${peerId}:`, e);
794
- throw e;
795
- }
796
- }
797
-
798
- /**
799
- * Handle incoming request messages and route to appropriate handlers
800
- */
801
- private handleRequest(type: string, payload: string, requestId: string, fromPeerId: string, did?: string): void {
802
- const handler = this.messageHandlers.get(type);
803
- if (handler) {
804
- // Forward raw payload; callers register with onMessage() and adapt as needed.
805
- handler(new TextEncoder().encode(payload), fromPeerId, did);
806
- }
807
-
808
- // Check if there's a response handler registered
809
- const responseHandler = this.pendingResponseHandlers.get(type);
810
- if (responseHandler) {
811
- responseHandler(payload, fromPeerId);
812
- }
813
- }
814
-
815
- /**
816
- * Register a pending response handler for a specific message type
817
- */
818
- registerResponseHandler(type: string, handler: (response: string, from: string) => void): void {
819
- this.pendingResponseHandlers.set(type, handler);
820
- }
821
-
822
- async sendMessage(peerId: string, type: string, payload: string): Promise<void> {
823
- if (!this.node) throw new Error('Node not initialized');
824
-
825
- let data: Uint8Array;
826
- if (this.ownDid) {
827
- data = new TextEncoder().encode(`DID:${this.ownDid}|${type}:${payload}`);
828
- } else {
829
- data = new TextEncoder().encode(`${type}:${payload}`);
830
- }
831
-
832
- try {
833
- await this.sendRawMessage(peerId, data);
834
- } catch (e) {
835
- console.warn(`[P2P] Failed to send to ${peerId}, storing offline`);
836
- this.storeOfflineMessage(peerId, data);
837
- this.scheduleReconnect(peerId);
838
-
839
- // 如果有持久化存储,也存入离线队列
840
- if (this.messageStore) {
841
- const payloadBase64 = btoa(String.fromCharCode(...data));
842
- this.messageStore.enqueueOfflineMessage({
843
- targetNodeId: peerId,
844
- type,
845
- payload: payloadBase64,
846
- createdAt: Date.now(),
847
- transport: 'libp2p',
848
- retryCount: 0,
849
- });
850
- }
851
- }
852
- }
853
-
854
- private scheduleReconnect(peerId: string): void {
855
- if (this.reconnectTimers.has(peerId)) return;
856
-
857
- const peerInfo = this.persistentPeers.get(peerId);
858
- if (!peerInfo || !peerInfo.multiaddrs || peerInfo.multiaddrs.length === 0) {
859
- console.log(`[P2P] No stored addresses for ${peerId}, cannot reconnect`);
860
- return;
861
- }
862
-
863
- console.log(`[P2P] Scheduling reconnect for ${peerId} in ${RECONNECT_DELAY_MS}ms`);
864
- const timer = setTimeout(() => {
865
- this.reconnectTimers.delete(peerId);
866
- if (this.node) {
867
- this.attemptReconnect(peerId, peerInfo);
868
- }
869
- }, RECONNECT_DELAY_MS);
870
- this.reconnectTimers.set(peerId, timer);
871
- }
872
-
873
- async broadcast(type: string, payload: string): Promise<void> {
874
- if (!this.node) throw new Error('Node not initialized');
875
-
876
- const peers = this.node.getPeers();
877
- let data: Uint8Array;
878
- if (this.ownDid) {
879
- data = new TextEncoder().encode(`DID:${this.ownDid}|${type}:${payload}`);
880
- } else {
881
- data = new TextEncoder().encode(`${type}:${payload}`);
882
- }
883
-
884
- for (const peer of peers) {
885
- const peerIdStr = peer.toString();
886
- try {
887
- await this.sendRawMessage(peerIdStr, data);
888
- } catch (e) {
889
- console.warn(`[P2P] Failed to broadcast to ${peerIdStr}:`, e);
890
- this.scheduleReconnect(peerIdStr);
891
- }
892
- }
893
- }
894
-
895
- getPeers(): string[] {
896
- if (!this.node) return [];
897
- return this.node.getPeers().map((p: any) => p.toString());
898
- }
899
-
900
- getConnectedPeers(): { peerId: string; did?: string; name?: string }[] {
901
- if (!this.node) return [];
902
- const result: { peerId: string; did?: string; name?: string }[] = [];
903
- for (const peer of this.node.getPeers()) {
904
- const peerIdStr = peer.toString();
905
- const peerInfo = this.persistentPeers.get(peerIdStr);
906
- result.push({
907
- peerId: peerIdStr,
908
- did: peerInfo?.did,
909
- name: peerInfo?.name
910
- });
911
- }
912
- return result;
913
- }
914
-
915
- setOwnDid(did: string): void {
916
- this.ownDid = did;
917
- }
918
-
919
- getNode(): any {
920
- return this.node;
921
- }
922
-
923
- async shutdown(): Promise<void> {
924
- for (const timer of this.reconnectTimers.values()) {
925
- clearTimeout(timer);
926
- }
927
- this.reconnectTimers.clear();
928
-
929
- if (this.offlineDeliveryInterval) {
930
- clearInterval(this.offlineDeliveryInterval);
931
- }
932
-
933
- if (this.messageStore) {
934
- await this.messageStore.shutdown();
935
- this.messageStore = null;
936
- }
937
-
938
- if (this.node) {
939
- await this.node.stop();
940
- }
941
- }
942
-
943
- /**
944
- * 获取消息历史
945
- */
946
- async getMessageHistory(options?: {
947
- direction?: 'sent' | 'received';
948
- type?: string;
949
- limit?: number;
950
- }): Promise<any[]> {
951
- if (!this.messageStore) return [];
952
- return this.messageStore.getMessages(options);
953
- }
954
-
955
- /**
956
- * 获取待投递消息数量
957
- */
958
- async getPendingOfflineCount(): Promise<number> {
959
- if (!this.messageStore) return 0;
960
- return this.messageStore.getPendingOfflineCount();
961
- }
962
- }
963
-
964
- export const p2pNetwork = new P2PNetwork();