@bolloon/bolloon-agent 0.3.43 → 0.3.45

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 (215) hide show
  1. package/README.md +135 -135
  2. package/bin/bolloon-cli.cjs +183 -183
  3. package/bin/bolloon-daemon.sh +207 -0
  4. package/bin/bolloon.cjs +0 -0
  5. package/dist/agents/constraint-layer.js +19 -19
  6. package/dist/agents/judgment-protocol.js +14 -14
  7. package/dist/agents/pi-sdk-types.js +12 -12
  8. package/dist/agents/pi-sdk.js +148 -89
  9. package/dist/agents/skill-writer.js +19 -0
  10. package/dist/agents/workflow-pivot-loop.js +2 -2
  11. package/dist/bollharness/src/scripts/deploy-guard.js +8 -8
  12. package/dist/bollharness-integration/context-router-judgment.js +4 -4
  13. package/dist/bollharness-integration/context-router.js +292 -292
  14. package/dist/bollharness-integration/gate-state-machine.js +13 -13
  15. package/dist/bollharness-integration/llm-judgment-engine.js +134 -134
  16. package/dist/bollharness-integration/skill-adapter.js +21 -21
  17. package/dist/bootstrap/chat-archiver.js +14 -14
  18. package/dist/bootstrap/context-os.js +21 -21
  19. package/dist/bootstrap/memory-compressor.js +29 -13
  20. package/dist/cli-entry.js +36 -36
  21. package/dist/constraint-runtime/reference_data/archive_surface_snapshot.json +63 -0
  22. package/dist/constraint-runtime/reference_data/commands_snapshot.json +1037 -0
  23. package/dist/constraint-runtime/reference_data/subsystems/assistant.json +8 -0
  24. package/dist/constraint-runtime/reference_data/subsystems/bootstrap.json +8 -0
  25. package/dist/constraint-runtime/reference_data/subsystems/bridge.json +32 -0
  26. package/dist/constraint-runtime/reference_data/subsystems/buddy.json +13 -0
  27. package/dist/constraint-runtime/reference_data/subsystems/cli.json +26 -0
  28. package/dist/constraint-runtime/reference_data/subsystems/components.json +32 -0
  29. package/dist/constraint-runtime/reference_data/subsystems/constants.json +28 -0
  30. package/dist/constraint-runtime/reference_data/subsystems/coordinator.json +8 -0
  31. package/dist/constraint-runtime/reference_data/subsystems/entrypoints.json +15 -0
  32. package/dist/constraint-runtime/reference_data/subsystems/hooks.json +32 -0
  33. package/dist/constraint-runtime/reference_data/subsystems/keybindings.json +21 -0
  34. package/dist/constraint-runtime/reference_data/subsystems/memdir.json +15 -0
  35. package/dist/constraint-runtime/reference_data/subsystems/migrations.json +18 -0
  36. package/dist/constraint-runtime/reference_data/subsystems/moreright.json +8 -0
  37. package/dist/constraint-runtime/reference_data/subsystems/native_ts.json +11 -0
  38. package/dist/constraint-runtime/reference_data/subsystems/outputStyles.json +8 -0
  39. package/dist/constraint-runtime/reference_data/subsystems/plugins.json +9 -0
  40. package/dist/constraint-runtime/reference_data/subsystems/remote.json +11 -0
  41. package/dist/constraint-runtime/reference_data/subsystems/schemas.json +8 -0
  42. package/dist/constraint-runtime/reference_data/subsystems/screens.json +10 -0
  43. package/dist/constraint-runtime/reference_data/subsystems/server.json +10 -0
  44. package/dist/constraint-runtime/reference_data/subsystems/services.json +32 -0
  45. package/dist/constraint-runtime/reference_data/subsystems/skills.json +27 -0
  46. package/dist/constraint-runtime/reference_data/subsystems/state.json +13 -0
  47. package/dist/constraint-runtime/reference_data/subsystems/types.json +18 -0
  48. package/dist/constraint-runtime/reference_data/subsystems/upstreamproxy.json +9 -0
  49. package/dist/constraint-runtime/reference_data/subsystems/utils.json +32 -0
  50. package/dist/constraint-runtime/reference_data/subsystems/vim.json +12 -0
  51. package/dist/constraint-runtime/reference_data/subsystems/voice.json +8 -0
  52. package/dist/constraint-runtime/reference_data/tools_snapshot.json +922 -0
  53. package/dist/constraint-runtime/setup.js +1 -1
  54. package/dist/constraint-runtime/tools/PolymarketSDK/cancelOrder.d.ts +13 -3
  55. package/dist/constraint-runtime/tools/PolymarketSDK/cancelOrder.js +16 -4
  56. package/dist/constraint-runtime/tools/PolymarketSDK/clobShared.d.ts +50 -0
  57. package/dist/constraint-runtime/tools/PolymarketSDK/clobShared.js +78 -0
  58. package/dist/constraint-runtime/tools/PolymarketSDK/createOrder.d.ts +24 -3
  59. package/dist/constraint-runtime/tools/PolymarketSDK/createOrder.js +31 -4
  60. package/dist/constraint-runtime/tools/PolymarketSDK/getMarket.d.ts +1 -0
  61. package/dist/constraint-runtime/tools/PolymarketSDK/getMarket.js +14 -3
  62. package/dist/constraint-runtime/tools/PolymarketSDK/getOrders.d.ts +11 -2
  63. package/dist/constraint-runtime/tools/PolymarketSDK/getOrders.js +23 -4
  64. package/dist/constraint-runtime/tools/PolymarketSDK/listMarkets.d.ts +4 -0
  65. package/dist/constraint-runtime/tools/PolymarketSDK/listMarkets.js +22 -2
  66. package/dist/context-compaction/auto-compact.js +7 -7
  67. package/dist/electron/config.js.map +1 -0
  68. package/dist/electron/dialogs.js.map +1 -0
  69. package/dist/electron/first-run.js +54 -54
  70. package/dist/electron/first-run.js.map +1 -0
  71. package/dist/electron/ipc.js.map +1 -0
  72. package/dist/electron/logger.js.map +1 -0
  73. package/dist/electron/main.js.map +1 -0
  74. package/dist/electron/menu.js.map +1 -0
  75. package/dist/electron/paths.js.map +1 -0
  76. package/dist/electron/server.js.map +1 -0
  77. package/dist/electron/tray.js.map +1 -0
  78. package/dist/electron/window.js.map +1 -0
  79. package/dist/electron-build/electron/first-run.js +54 -54
  80. package/dist/electron-preload.js.map +1 -1
  81. package/dist/electron.js.map +1 -1
  82. package/dist/index.js +113 -113
  83. package/dist/llm/llm-judgment-client.js +102 -102
  84. package/dist/llm/pi-ai.js +48 -48
  85. package/dist/llm/system-prompt/layers/channel/human-async.md +41 -41
  86. package/dist/llm/system-prompt/layers/channel/local.md +14 -14
  87. package/dist/llm/system-prompt/layers/channel/p2p-agent.md +18 -18
  88. package/dist/llm/system-prompt/layers/channel/p2p-peer-sync.md +51 -51
  89. package/dist/llm/system-prompt/layers/channel/p2p-proactive.md +43 -43
  90. package/dist/llm/system-prompt/layers/channel/p2p-visitor.md +19 -19
  91. package/dist/llm/system-prompt/layers/channel/session-handoff.md +61 -61
  92. package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -89
  93. package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -21
  94. package/dist/llm/system-prompt/layers/core/external-engagement.md +73 -73
  95. package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -15
  96. package/dist/llm/system-prompt/layers/core/identity.md +48 -48
  97. package/dist/llm/system-prompt/layers/core/knowledge.md +17 -17
  98. package/dist/llm/system-prompt/layers/core/memory_system.md +12 -12
  99. package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -28
  100. package/dist/llm/system-prompt/layers/core/refusal.md +37 -37
  101. package/dist/llm/system-prompt/layers/core/tone.md +31 -31
  102. package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -13
  103. package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -41
  104. package/dist/llm/system-prompt/layers/role/architect.md +20 -20
  105. package/dist/llm/system-prompt/layers/role/expert.md +19 -19
  106. package/dist/llm/system-prompt/layers/role/implementer.md +15 -15
  107. package/dist/llm/system-prompt/layers/role/security.md +15 -15
  108. package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -72
  109. package/dist/llm/system-prompt/layers/tool/bash.md +25 -25
  110. package/dist/llm/system-prompt/layers/tool/goal_handoff.md +77 -77
  111. package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -171
  112. package/dist/llm/system-prompt/layers/tool/image_search.md +70 -70
  113. package/dist/llm/system-prompt/layers/tool/manifest.md +89 -89
  114. package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -53
  115. package/dist/llm/system-prompt/layers/tool/p2p_request.md +61 -61
  116. package/dist/llm/system-prompt/layers/tool/web_search.md +83 -83
  117. package/dist/llm/tool-manifest/ask_user_input.js +1 -1
  118. package/dist/llm/tool-manifest/bash.js +3 -3
  119. package/dist/llm/tool-manifest/create_file.js +4 -4
  120. package/dist/llm/tool-manifest/fetch_sports_data.js +3 -3
  121. package/dist/llm/tool-manifest/image_search.js +2 -2
  122. package/dist/llm/tool-manifest/index.js +59 -0
  123. package/dist/llm/tool-manifest/mcp.js +2 -2
  124. package/dist/llm/tool-manifest/message_compose.js +3 -3
  125. package/dist/llm/tool-manifest/places.js +2 -2
  126. package/dist/llm/tool-manifest/present_files.js +1 -1
  127. package/dist/llm/tool-manifest/recipe.js +2 -2
  128. package/dist/llm/tool-manifest/str_replace.js +5 -5
  129. package/dist/llm/tool-manifest/view.js +3 -3
  130. package/dist/llm/tool-manifest/weather.js +4 -4
  131. package/dist/llm/tool-manifest/web.js +4 -4
  132. package/dist/orbitdb/cid-database.js +41 -0
  133. package/dist/orbitdb/did-catalog-replication.js +199 -0
  134. package/dist/orbitdb/trajectory-store.js +150 -0
  135. package/dist/pi-ecosystem-judgment/causal-judge.js +51 -51
  136. package/dist/pi-ecosystem-judgment/distill-prompt.js +42 -42
  137. package/dist/pi-ecosystem-judgment/distillation.js +14 -14
  138. package/dist/pi-ecosystem-judgment/monitor-gate.js +28 -28
  139. package/dist/pi-ecosystem-judgment/value-injection.js +102 -102
  140. package/dist/security/context-router-tool.js +15 -15
  141. package/dist/storage/did-catalog-bridge.js +271 -0
  142. package/dist/storage/did-catalog.js +231 -0
  143. package/dist/utils/auto-update.js.map +1 -0
  144. package/dist/web/api-config.html +779 -779
  145. package/dist/web/client-hearth.js +10 -10
  146. package/dist/web/client.js.map +7 -0
  147. package/dist/web/components/wallet-viem.mjs +118 -118
  148. package/dist/web/index.html +424 -424
  149. package/dist/web/manifest.json +20 -20
  150. package/dist/web/server.js +240 -13
  151. package/dist/web/style.css +4914 -4914
  152. package/package.json +193 -193
  153. package/scripts/build-cli.js +215 -215
  154. package/scripts/build-web.ts +130 -130
  155. package/scripts/postinstall.js +152 -152
  156. package/bin/bolloon.js +0 -157
  157. package/dist/pi-ecosystem-colony/index.js +0 -365
  158. package/dist/social/ant-colony/AdaptiveHeartbeat.js +0 -101
  159. package/dist/social/ant-colony/PheromoneEngine.js +0 -227
  160. package/dist/social/ant-colony/index.js +0 -6
  161. package/dist/social/ant-colony/types.js +0 -24
  162. package/dist/test/ai-judgment-test.js +0 -80
  163. package/dist/test/bollharness-integration.test.js +0 -318
  164. package/dist/test/channel-agent-multi-dialogue.js +0 -205
  165. package/dist/test/channel-heartbeat-agent-test.js +0 -201
  166. package/dist/test/constraint-layer.test.js +0 -164
  167. package/dist/test/diap-identity-test.js +0 -172
  168. package/dist/test/diap-quick-test.js +0 -62
  169. package/dist/test/global-shared-context.test.js +0 -315
  170. package/dist/test/harness-judgment-injection.test.js +0 -246
  171. package/dist/test/harness-workflow-integrator-test.js +0 -228
  172. package/dist/test/human-value-store.test.js +0 -243
  173. package/dist/test/hybrid-integration-test.js +0 -118
  174. package/dist/test/hybrid-messenger-verify.js +0 -55
  175. package/dist/test/iroh-bistream-debug.js +0 -38
  176. package/dist/test/iroh-communication.test.js +0 -66
  177. package/dist/test/iroh-debug-test.js +0 -57
  178. package/dist/test/iroh-diap-test.js +0 -71
  179. package/dist/test/iroh-direct-connect.js +0 -55
  180. package/dist/test/iroh-e2e-fixed.js +0 -89
  181. package/dist/test/iroh-e2e-same-process.js +0 -63
  182. package/dist/test/iroh-e2e.js +0 -66
  183. package/dist/test/iroh-final-e2e.js +0 -72
  184. package/dist/test/iroh-relay-test.js +0 -37
  185. package/dist/test/iroh-simple-test.js +0 -41
  186. package/dist/test/iroh-transport-verify.js +0 -54
  187. package/dist/test/iroh-transport.test.js +0 -37
  188. package/dist/test/iroh-two-nodes.js +0 -70
  189. package/dist/test/iroh-verify.js +0 -44
  190. package/dist/test/judgment-decision.test.js +0 -219
  191. package/dist/test/llm-judgment-integration.test.js +0 -220
  192. package/dist/test/p2p-agent-complex-dialogue.js +0 -385
  193. package/dist/test/p2p-agent-dialogue.js +0 -341
  194. package/dist/test/p2p-agent-full-bidirectional.js +0 -510
  195. package/dist/test/p2p-agent-harness-flow.js +0 -437
  196. package/dist/test/p2p-agent-harness-single.js +0 -143
  197. package/dist/test/p2p-ai-dialogue-test.js +0 -318
  198. package/dist/test/p2p-cid-connect-test.js +0 -195
  199. package/dist/test/p2p-connect-receiver.js +0 -69
  200. package/dist/test/p2p-doc-transfer.js +0 -110
  201. package/dist/test/p2p-identity-page-test.js +0 -77
  202. package/dist/test/p2p-iroh-test.js +0 -171
  203. package/dist/test/p2p-minimal-test.js +0 -241
  204. package/dist/test/p2p-node-1.js +0 -148
  205. package/dist/test/p2p-node-2.js +0 -148
  206. package/dist/test/p2p-server.js +0 -281
  207. package/dist/test/p2p-two-nodes-test.js +0 -438
  208. package/dist/test/pi-sdk.test.js +0 -44
  209. package/dist/test/set-persona.js +0 -40
  210. package/dist/test/simple.test.js +0 -9
  211. package/dist/test/storage-integration.test.js +0 -150
  212. package/dist/test/subagent-manager.test.js +0 -276
  213. package/dist/test/test-gate-flow.test.js +0 -81
  214. package/dist/test/workflow-engine.test.js +0 -87
  215. package/dist/test/workflow-pivot-loop.test.js +0 -246
@@ -1,21 +1,21 @@
1
- {
2
- "name": "Bolloon Agent",
3
- "short_name": "Bolloon",
4
- "description": "AI Agent with Claude API integration",
5
- "start_url": "/",
6
- "display": "standalone",
7
- "background_color": "#1a1a2e",
8
- "theme_color": "#1a1a2e",
9
- "icons": [
10
- {
11
- "src": "/icons/favicon-192x192.png",
12
- "sizes": "192x192",
13
- "type": "image/png"
14
- },
15
- {
16
- "src": "/icons/favicon-512x512.png",
17
- "sizes": "512x512",
18
- "type": "image/png"
19
- }
20
- ]
1
+ {
2
+ "name": "Bolloon Agent",
3
+ "short_name": "Bolloon",
4
+ "description": "AI Agent with Claude API integration",
5
+ "start_url": "/",
6
+ "display": "standalone",
7
+ "background_color": "#1a1a2e",
8
+ "theme_color": "#1a1a2e",
9
+ "icons": [
10
+ {
11
+ "src": "/icons/favicon-192x192.png",
12
+ "sizes": "192x192",
13
+ "type": "image/png"
14
+ },
15
+ {
16
+ "src": "/icons/favicon-512x512.png",
17
+ "sizes": "512x512",
18
+ "type": "image/png"
19
+ }
20
+ ]
21
21
  }
@@ -1669,6 +1669,40 @@ export async function createWebServer(port = 3000, options = {}) {
1669
1669
  console.warn('[mcp] 初始化失败 (非致命):', e?.message?.slice(0, 120));
1670
1670
  }
1671
1671
  })();
1672
+ // 2026-08-08: DID 目录启动接入 — 回填既有磁盘数据 + 启动 OrbitDB 自动复制.
1673
+ // fire-and-forget: 不阻塞启动; 失败静默 (catalog 是增强层, 原磁盘路径永远可用).
1674
+ (async () => {
1675
+ try {
1676
+ const { openUserCatalog, backfillDidCatalog } = await import('../storage/did-catalog-bridge.js');
1677
+ const cat = await openUserCatalog();
1678
+ if (!cat) {
1679
+ console.log('[did-catalog] 未生成用户 DID, 跳过回填 (首次启动会由 /api/user/identity 生成)');
1680
+ return;
1681
+ }
1682
+ const r = await backfillDidCatalog(cat);
1683
+ const total = r.reduce((a, x) => a + x.added, 0);
1684
+ console.log(`[did-catalog] 启动回填完成: ${total} 行新写入 (${r.map(x => `${x.table}=${x.added}+${x.skipped}跳过`).join(', ')})`);
1685
+ }
1686
+ catch (e) {
1687
+ console.warn('[did-catalog] 启动回填失败 (非致命):', e?.message?.slice(0, 120));
1688
+ }
1689
+ })();
1690
+ // 2026-08-08: DID 目录 → OrbitDB 自动复制 (WAL 事件流驱动跨设备合并).
1691
+ // 懒启动: 等 identity 就绪后再开; 失败静默 (离线时 catalog 照常工作).
1692
+ (async () => {
1693
+ try {
1694
+ const identity = await loadOrCreateUserIdentity();
1695
+ if (!identity.did)
1696
+ return;
1697
+ const { startDidCatalogReplication } = await import('../orbitdb/did-catalog-replication.js');
1698
+ const rep = await startDidCatalogReplication(identity.did, { intervalMs: 30_000 });
1699
+ console.log(`[did-catalog] OrbitDB 自动复制已启动: store=${rep.storeName} address=${String(rep.storeAddress).slice(0, 48)}...`);
1700
+ globalThis.__didCatalogReplication = rep;
1701
+ }
1702
+ catch (e) {
1703
+ console.warn('[did-catalog] OrbitDB 复制启动失败 (非致命, 稍后可用 API 重试):', e?.message?.slice(0, 120));
1704
+ }
1705
+ })();
1672
1706
  // 重置旧的 agent session,确保使用新的 LLM 配置
1673
1707
  const { resetAgentSession } = await import('../agents/pi-sdk.js');
1674
1708
  resetAgentSession();
@@ -2313,19 +2347,19 @@ export async function createWebServer(port = 3000, options = {}) {
2313
2347
  .map((p) => `- ${p.name || p.publicKey.slice(0, 8)} (pk=${p.publicKey.slice(0, 12)}…): 渠道[${p.channels.map((c) => c.name).join(', ') || '无'}]`)
2314
2348
  .join('\n');
2315
2349
  const goalDesc = ctx.goal ? `当前目标: ${ctx.goal.description} (已发起 ${ctx.goal.initiationsUsed}/${ctx.goal.maxInitiations}, 有效回复 ${ctx.goal.effectfulReplies}/${ctx.goal.effectThreshold})` : '当前无明确目标';
2316
- const prompt = `你是智能体「${ctx.self.name || '本地智能体'}」。你通过 P2P 网络认识以下其他智能体:
2317
- ${peerLines}
2318
-
2319
- ${goalDesc}
2320
-
2321
- 规则:
2322
- 1. 社交是为了达成上述目标, 不是闲聊。只在你有真正有价值的信息要分享/询问、且能推进目标时才主动发起。
2323
- 2. 不要重复最近已经聊过的话题, 不要每条心跳都发消息, 保持克制。
2324
- 3. 如果目标已经通过已有交流达成 (或你认为无需再聊), 输出 {"initiate": false, "goalAchieved": true}。
2325
- 4. 如果决定发起, 选一个最合适的目标渠道 (用对方渠道的真实 id)。
2326
-
2327
- 现在是否要主动联系其中某个智能体? 只输出一个 JSON 对象, 不要任何其他文字:
2328
- {"initiate": true 或 false, "goalAchieved": true 或 false, "targetPeerPublicKey": "对方 pk", "targetChannelId": "对方渠道 id", "message": "你要说的话"}
2350
+ const prompt = `你是智能体「${ctx.self.name || '本地智能体'}」。你通过 P2P 网络认识以下其他智能体:
2351
+ ${peerLines}
2352
+
2353
+ ${goalDesc}
2354
+
2355
+ 规则:
2356
+ 1. 社交是为了达成上述目标, 不是闲聊。只在你有真正有价值的信息要分享/询问、且能推进目标时才主动发起。
2357
+ 2. 不要重复最近已经聊过的话题, 不要每条心跳都发消息, 保持克制。
2358
+ 3. 如果目标已经通过已有交流达成 (或你认为无需再聊), 输出 {"initiate": false, "goalAchieved": true}。
2359
+ 4. 如果决定发起, 选一个最合适的目标渠道 (用对方渠道的真实 id)。
2360
+
2361
+ 现在是否要主动联系其中某个智能体? 只输出一个 JSON 对象, 不要任何其他文字:
2362
+ {"initiate": true 或 false, "goalAchieved": true 或 false, "targetPeerPublicKey": "对方 pk", "targetChannelId": "对方渠道 id", "message": "你要说的话"}
2329
2363
  若不想发起, 输出 {"initiate": false}。`;
2330
2364
  const raw = await agent.promptStream(prompt, () => { }, undefined, local.id);
2331
2365
  const m = raw.match(/\{[\s\S]*\}/);
@@ -2759,6 +2793,163 @@ ${goalDesc}
2759
2793
  res.status(500).json({ error: err.message });
2760
2794
  }
2761
2795
  });
2796
+ // 2026-08-08: DID 目录 (Postgres 式) — 以用户 DID 为主键, 绑定 memory/persona/skills/on_policy/context_os 等表
2797
+ app.get('/api/did-catalog/:table', async (req, res) => {
2798
+ try {
2799
+ const table = String(req.params.table || '');
2800
+ const { registryOpen, ALL_TABLES } = await import('../storage/did-catalog.js');
2801
+ if (!ALL_TABLES.includes(table)) {
2802
+ return res.status(400).json({ error: `未知表: ${table}`, tables: ALL_TABLES });
2803
+ }
2804
+ const identity = await loadOrCreateUserIdentity();
2805
+ if (!identity.did)
2806
+ return res.status(404).json({ error: '未生成用户 DID' });
2807
+ const cat = await registryOpen(identity.did);
2808
+ const rows = cat.all(table).map(({ key, row }) => ({ key, data: row.data, updatedAt: row.updatedAt, deviceId: row.deviceId }));
2809
+ res.json({ did: identity.did, table, rows, deviceId: cat.deviceId });
2810
+ }
2811
+ catch (err) {
2812
+ res.status(500).json({ error: err.message });
2813
+ }
2814
+ });
2815
+ // 写入 DID 目录单行 (以用户 DID 为分区主键) — 供插件/工具把各类数据绑定到用户
2816
+ app.post('/api/did-catalog/:table', async (req, res) => {
2817
+ try {
2818
+ const table = String(req.params.table || '');
2819
+ const { key, data } = req.body || {};
2820
+ const { registryOpen, ALL_TABLES } = await import('../storage/did-catalog.js');
2821
+ if (!ALL_TABLES.includes(table)) {
2822
+ return res.status(400).json({ error: `未知表: ${table}`, tables: ALL_TABLES });
2823
+ }
2824
+ if (!key)
2825
+ return res.status(400).json({ error: 'key 必填' });
2826
+ const identity = await loadOrCreateUserIdentity();
2827
+ if (!identity.did)
2828
+ return res.status(404).json({ error: '未生成用户 DID' });
2829
+ const cat = await registryOpen(identity.did);
2830
+ const ev = await cat.upsert(table, String(key), (data && typeof data === 'object' ? data : {}));
2831
+ res.json({ ok: true, did: identity.did, table, key, seq: ev.seq, deviceId: cat.deviceId });
2832
+ }
2833
+ catch (err) {
2834
+ res.status(500).json({ error: err.message });
2835
+ }
2836
+ });
2837
+ // 拉取某台的 WAL → 多设备同步合并
2838
+ app.post('/api/did-catalog/sync', async (req, res) => {
2839
+ try {
2840
+ const { events } = req.body || {};
2841
+ if (!Array.isArray(events))
2842
+ return res.status(400).json({ error: 'events 必填数组' });
2843
+ const identity = await loadOrCreateUserIdentity();
2844
+ if (!identity.did)
2845
+ return res.status(404).json({ error: '未生成用户 DID' });
2846
+ const { registryOpen } = await import('../storage/did-catalog.js');
2847
+ const cat = await registryOpen(identity.did);
2848
+ const r = cat.syncRemote(events);
2849
+ res.json({ ok: true, did: identity.did, applied: r.applied, merged: r.merged });
2850
+ }
2851
+ catch (err) {
2852
+ res.status(500).json({ error: err.message });
2853
+ }
2854
+ });
2855
+ // 手动触发启动回填 (既有磁盘数据 → DID 目录表, 幂等)
2856
+ app.post('/api/did-catalog/backfill', async (_req, res) => {
2857
+ try {
2858
+ const identity = await loadOrCreateUserIdentity();
2859
+ if (!identity.did)
2860
+ return res.status(404).json({ error: '未生成用户 DID' });
2861
+ const { openUserCatalog, backfillDidCatalog } = await import('../storage/did-catalog-bridge.js');
2862
+ const cat = await openUserCatalog();
2863
+ if (!cat)
2864
+ return res.status(404).json({ error: '目录未打开' });
2865
+ const r = await backfillDidCatalog(cat);
2866
+ res.json({ ok: true, did: identity.did, tables: r });
2867
+ }
2868
+ catch (err) {
2869
+ res.status(500).json({ error: err.message });
2870
+ }
2871
+ });
2872
+ // OrbitDB 复制状态 / 启动 (自动复制失败后的手动入口)
2873
+ app.get('/api/did-catalog/replication', async (_req, res) => {
2874
+ try {
2875
+ const identity = await loadOrCreateUserIdentity();
2876
+ if (!identity.did)
2877
+ return res.status(404).json({ error: '未生成用户 DID' });
2878
+ const rep = globalThis.__didCatalogReplication;
2879
+ if (!rep)
2880
+ return res.json({ ok: false, did: identity.did, running: false });
2881
+ const { publishPending, syncNow } = rep;
2882
+ const published = await publishPending();
2883
+ const synced = await syncNow();
2884
+ res.json({
2885
+ ok: true, did: identity.did, running: true,
2886
+ storeName: rep.storeName, storeAddress: rep.storeAddress,
2887
+ stats: rep.stats, publishedNow: published, syncedNow: synced,
2888
+ });
2889
+ }
2890
+ catch (err) {
2891
+ res.status(500).json({ error: err.message });
2892
+ }
2893
+ });
2894
+ app.post('/api/did-catalog/replication/start', async (_req, res) => {
2895
+ try {
2896
+ const identity = await loadOrCreateUserIdentity();
2897
+ if (!identity.did)
2898
+ return res.status(404).json({ error: '未生成用户 DID' });
2899
+ if (globalThis.__didCatalogReplication) {
2900
+ return res.json({ ok: true, did: identity.did, running: true, storeAddress: globalThis.__didCatalogReplication.storeAddress });
2901
+ }
2902
+ const { startDidCatalogReplication } = await import('../orbitdb/did-catalog-replication.js');
2903
+ const rep = await startDidCatalogReplication(identity.did, { intervalMs: 30_000 });
2904
+ globalThis.__didCatalogReplication = rep;
2905
+ res.json({ ok: true, did: identity.did, running: true, storeName: rep.storeName, storeAddress: rep.storeAddress });
2906
+ }
2907
+ catch (err) {
2908
+ res.status(500).json({ error: err.message });
2909
+ }
2910
+ });
2911
+ // 智能体运行轨迹 (trajectory): 列表 + 单条 (落盘 ~/.bolloon/trajectories/)
2912
+ app.get('/api/trajectories', async (_req, res) => {
2913
+ try {
2914
+ const { listTrajectories } = await import('../orbitdb/trajectory-store.js');
2915
+ const list = await listTrajectories();
2916
+ const summary = [];
2917
+ for (const { runId, file } of list) {
2918
+ try {
2919
+ const { loadTrajectory } = await import('../orbitdb/trajectory-store.js');
2920
+ const run = await loadTrajectory(runId);
2921
+ summary.push({
2922
+ runId, file,
2923
+ agentId: run?.agentId, channelId: run?.channelId,
2924
+ startedAt: run?.startedAt, endedAt: run?.endedAt,
2925
+ durationMs: run?.durationMs, status: run?.status,
2926
+ input: run?.input?.slice(0, 120), reply: run?.reply?.slice(0, 120),
2927
+ steps: run?.steps?.length ?? 0,
2928
+ });
2929
+ }
2930
+ catch { /* 单条失败跳过 */ }
2931
+ }
2932
+ res.json({ ok: true, count: list.length, runs: summary });
2933
+ }
2934
+ catch (err) {
2935
+ res.status(500).json({ error: err.message });
2936
+ }
2937
+ });
2938
+ app.get('/api/trajectories/:runId', async (req, res) => {
2939
+ try {
2940
+ const { loadTrajectory } = await import('../orbitdb/trajectory-store.js');
2941
+ const runId = String(req.params.runId || '');
2942
+ if (!runId)
2943
+ return res.status(400).json({ error: 'runId 必填' });
2944
+ const run = await loadTrajectory(runId);
2945
+ if (!run)
2946
+ return res.status(404).json({ error: `轨迹不存在: ${runId}` });
2947
+ res.json({ ok: true, run });
2948
+ }
2949
+ catch (err) {
2950
+ res.status(500).json({ error: err.message });
2951
+ }
2952
+ });
2762
2953
  // 2026-07-01 (v0.2.6): 前后端分离核心 — 后端切 LLM 输出为结构化 segments
2763
2954
  // - POST /api/segment-reply { reply, knownTools }
2764
2955
  // - 返回 ChatSegment[] (think / text / env_details / tool_call / final)
@@ -3360,6 +3551,26 @@ ${goalDesc}
3360
3551
  const memBlock = summariesToRead.map(s => s.trim().slice(-1500)).join('\n\n---\n\n');
3361
3552
  contextHint += `[系统上下文] 动态状态层 · chat-worksite (上次做到哪 — 本 channel 历史记忆, 来自 memory-compressor 摘要, 引用而非复述):\n${memBlock.slice(-2500)}\n\n`;
3362
3553
  }
3554
+ else {
3555
+ // 2026-08-08 (DID 目录读侧): 磁盘无摘要时, 回退读 DID 目录 memory 表 (跨设备同步来的记忆)
3556
+ try {
3557
+ const { openUserCatalog, catalogMemoryRows } = await import('../storage/did-catalog-bridge.js');
3558
+ const cat = await openUserCatalog();
3559
+ if (cat) {
3560
+ const rows = catalogMemoryRows(cat, agentId);
3561
+ if (rows.length > 0) {
3562
+ const memBlock = rows.slice(0, 2)
3563
+ .map(({ row }) => String(row.data.summary || '').slice(-1500))
3564
+ .filter(Boolean)
3565
+ .join('\n\n---\n\n');
3566
+ if (memBlock) {
3567
+ contextHint += `[系统上下文] 动态状态层 · chat-worksite (DID 目录同步记忆, 引用而非复述):\n${memBlock.slice(-2500)}\n\n`;
3568
+ }
3569
+ }
3570
+ }
3571
+ }
3572
+ catch { /* 目录读失败静默 */ }
3573
+ }
3363
3574
  }
3364
3575
  }
3365
3576
  catch (memErr) {
@@ -6567,6 +6778,22 @@ ${goalDesc}
6567
6778
  const success = writePolicy(newPolicy);
6568
6779
  if (success) {
6569
6780
  auditShellCall('allowed', 'api:PUT:/api/self-improve/policy', [], `人类用户更新策略`);
6781
+ // 2026-08-08: 策略版本写入 DID 目录 (on-policy 以用户 did 绑定)
6782
+ try {
6783
+ const identity = await loadOrCreateUserIdentity();
6784
+ if (identity.did) {
6785
+ const { registryOpen } = await import('../storage/did-catalog.js');
6786
+ const cat = await registryOpen(identity.did);
6787
+ await cat.upsert('on_policy', `pol-${newPolicy.version || 0}`, {
6788
+ version: newPolicy.version || 0,
6789
+ policy: JSON.parse(JSON.stringify(newPolicy)),
6790
+ updatedAt: Date.now(),
6791
+ });
6792
+ }
6793
+ }
6794
+ catch (e) {
6795
+ console.warn('[did-catalog] 记录 on-policy 失败(非致命):', e?.message);
6796
+ }
6570
6797
  res.json({ ok: true, message: '策略已更新, 60 秒内生效' });
6571
6798
  }
6572
6799
  else {