@bolloon/bolloon-agent 0.4.4 → 0.4.5

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 (201) 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 +90 -90
  9. package/dist/agents/skill-organizer.js +19 -19
  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 +24 -24
  19. package/dist/bootstrap/memory-compressor.js +13 -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/context-compaction/auto-compact.js +7 -7
  54. package/dist/electron/config.js.map +1 -0
  55. package/dist/electron/dialogs.js.map +1 -0
  56. package/dist/electron/first-run.js +54 -54
  57. package/dist/electron/first-run.js.map +1 -0
  58. package/dist/electron/ipc.js.map +1 -0
  59. package/dist/electron/logger.js.map +1 -0
  60. package/dist/electron/main.js.map +1 -0
  61. package/dist/electron/menu.js.map +1 -0
  62. package/dist/electron/paths.js.map +1 -0
  63. package/dist/electron/server.js.map +1 -0
  64. package/dist/electron/tray.js.map +1 -0
  65. package/dist/electron/window.js.map +1 -0
  66. package/dist/electron-build/electron/first-run.js +54 -54
  67. package/dist/electron-preload.js.map +1 -1
  68. package/dist/electron.js.map +1 -1
  69. package/dist/index.js +112 -112
  70. package/dist/llm/llm-judgment-client.js +102 -102
  71. package/dist/llm/pi-ai.js +48 -48
  72. package/dist/llm/system-prompt/layers/channel/human-async.md +41 -41
  73. package/dist/llm/system-prompt/layers/channel/local.md +14 -14
  74. package/dist/llm/system-prompt/layers/channel/p2p-agent.md +18 -18
  75. package/dist/llm/system-prompt/layers/channel/p2p-peer-sync.md +51 -51
  76. package/dist/llm/system-prompt/layers/channel/p2p-proactive.md +43 -43
  77. package/dist/llm/system-prompt/layers/channel/p2p-visitor.md +19 -19
  78. package/dist/llm/system-prompt/layers/channel/session-handoff.md +61 -61
  79. package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -89
  80. package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -21
  81. package/dist/llm/system-prompt/layers/core/external-engagement.md +73 -73
  82. package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -15
  83. package/dist/llm/system-prompt/layers/core/identity.md +48 -48
  84. package/dist/llm/system-prompt/layers/core/knowledge.md +17 -17
  85. package/dist/llm/system-prompt/layers/core/memory_system.md +12 -12
  86. package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -28
  87. package/dist/llm/system-prompt/layers/core/refusal.md +37 -37
  88. package/dist/llm/system-prompt/layers/core/tone.md +31 -31
  89. package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -13
  90. package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -41
  91. package/dist/llm/system-prompt/layers/role/architect.md +20 -20
  92. package/dist/llm/system-prompt/layers/role/expert.md +19 -19
  93. package/dist/llm/system-prompt/layers/role/implementer.md +15 -15
  94. package/dist/llm/system-prompt/layers/role/security.md +15 -15
  95. package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -72
  96. package/dist/llm/system-prompt/layers/tool/bash.md +25 -25
  97. package/dist/llm/system-prompt/layers/tool/goal_handoff.md +77 -77
  98. package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -171
  99. package/dist/llm/system-prompt/layers/tool/image_search.md +70 -70
  100. package/dist/llm/system-prompt/layers/tool/manifest.md +89 -89
  101. package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -53
  102. package/dist/llm/system-prompt/layers/tool/p2p_request.md +61 -61
  103. package/dist/llm/system-prompt/layers/tool/web_search.md +83 -83
  104. package/dist/llm/tool-manifest/ask_user_input.js +1 -1
  105. package/dist/llm/tool-manifest/bash.js +3 -3
  106. package/dist/llm/tool-manifest/create_file.js +4 -4
  107. package/dist/llm/tool-manifest/fetch_sports_data.js +3 -3
  108. package/dist/llm/tool-manifest/image_search.js +2 -2
  109. package/dist/llm/tool-manifest/index.js +59 -0
  110. package/dist/llm/tool-manifest/mcp.js +2 -2
  111. package/dist/llm/tool-manifest/message_compose.js +3 -3
  112. package/dist/llm/tool-manifest/places.js +2 -2
  113. package/dist/llm/tool-manifest/present_files.js +1 -1
  114. package/dist/llm/tool-manifest/recipe.js +2 -2
  115. package/dist/llm/tool-manifest/str_replace.js +5 -5
  116. package/dist/llm/tool-manifest/view.js +3 -3
  117. package/dist/llm/tool-manifest/weather.js +4 -4
  118. package/dist/llm/tool-manifest/web.js +4 -4
  119. package/dist/pi-ecosystem-judgment/causal-judge.js +51 -51
  120. package/dist/pi-ecosystem-judgment/distill-prompt.js +42 -42
  121. package/dist/pi-ecosystem-judgment/distillation.js +14 -14
  122. package/dist/pi-ecosystem-judgment/human-value-store.js +1 -1
  123. package/dist/pi-ecosystem-judgment/monitor-gate.js +28 -28
  124. package/dist/pi-ecosystem-judgment/value-injection.js +102 -102
  125. package/dist/pi-ecosystem-mcp/index.js +146 -5
  126. package/dist/security/context-router-tool.js +15 -15
  127. package/dist/utils/auto-update.js.map +1 -0
  128. package/dist/web/api-config.html +779 -779
  129. package/dist/web/client-hearth.js +10 -10
  130. package/dist/web/client.js.map +7 -0
  131. package/dist/web/components/wallet-viem.mjs +118 -118
  132. package/dist/web/edge-auth-client.js +120 -0
  133. package/dist/web/index.html +472 -472
  134. package/dist/web/manifest.json +20 -20
  135. package/dist/web/server.js +34 -67
  136. package/dist/web/style.css +4946 -4946
  137. package/package.json +195 -195
  138. package/scripts/build-cli.js +215 -215
  139. package/scripts/build-web.ts +130 -130
  140. package/scripts/postinstall.js +152 -152
  141. package/bin/bolloon.js +0 -157
  142. package/dist/pi-ecosystem-colony/index.js +0 -365
  143. package/dist/social/ant-colony/AdaptiveHeartbeat.js +0 -101
  144. package/dist/social/ant-colony/PheromoneEngine.js +0 -227
  145. package/dist/social/ant-colony/index.js +0 -6
  146. package/dist/social/ant-colony/types.js +0 -24
  147. package/dist/storage/trajectory.js +0 -101
  148. package/dist/test/ai-judgment-test.js +0 -80
  149. package/dist/test/bollharness-integration.test.js +0 -318
  150. package/dist/test/channel-agent-multi-dialogue.js +0 -205
  151. package/dist/test/channel-heartbeat-agent-test.js +0 -201
  152. package/dist/test/constraint-layer.test.js +0 -164
  153. package/dist/test/diap-identity-test.js +0 -172
  154. package/dist/test/diap-quick-test.js +0 -62
  155. package/dist/test/global-shared-context.test.js +0 -315
  156. package/dist/test/harness-judgment-injection.test.js +0 -246
  157. package/dist/test/harness-workflow-integrator-test.js +0 -228
  158. package/dist/test/human-value-store.test.js +0 -243
  159. package/dist/test/hybrid-integration-test.js +0 -118
  160. package/dist/test/hybrid-messenger-verify.js +0 -55
  161. package/dist/test/iroh-bistream-debug.js +0 -38
  162. package/dist/test/iroh-communication.test.js +0 -66
  163. package/dist/test/iroh-debug-test.js +0 -57
  164. package/dist/test/iroh-diap-test.js +0 -71
  165. package/dist/test/iroh-direct-connect.js +0 -55
  166. package/dist/test/iroh-e2e-fixed.js +0 -89
  167. package/dist/test/iroh-e2e-same-process.js +0 -63
  168. package/dist/test/iroh-e2e.js +0 -66
  169. package/dist/test/iroh-final-e2e.js +0 -72
  170. package/dist/test/iroh-relay-test.js +0 -37
  171. package/dist/test/iroh-simple-test.js +0 -41
  172. package/dist/test/iroh-transport-verify.js +0 -54
  173. package/dist/test/iroh-transport.test.js +0 -37
  174. package/dist/test/iroh-two-nodes.js +0 -70
  175. package/dist/test/iroh-verify.js +0 -44
  176. package/dist/test/judgment-decision.test.js +0 -219
  177. package/dist/test/llm-judgment-integration.test.js +0 -220
  178. package/dist/test/p2p-agent-complex-dialogue.js +0 -385
  179. package/dist/test/p2p-agent-dialogue.js +0 -341
  180. package/dist/test/p2p-agent-full-bidirectional.js +0 -510
  181. package/dist/test/p2p-agent-harness-flow.js +0 -437
  182. package/dist/test/p2p-agent-harness-single.js +0 -143
  183. package/dist/test/p2p-ai-dialogue-test.js +0 -318
  184. package/dist/test/p2p-cid-connect-test.js +0 -195
  185. package/dist/test/p2p-connect-receiver.js +0 -69
  186. package/dist/test/p2p-doc-transfer.js +0 -110
  187. package/dist/test/p2p-identity-page-test.js +0 -77
  188. package/dist/test/p2p-iroh-test.js +0 -171
  189. package/dist/test/p2p-minimal-test.js +0 -241
  190. package/dist/test/p2p-node-1.js +0 -148
  191. package/dist/test/p2p-node-2.js +0 -148
  192. package/dist/test/p2p-server.js +0 -281
  193. package/dist/test/p2p-two-nodes-test.js +0 -438
  194. package/dist/test/pi-sdk.test.js +0 -44
  195. package/dist/test/set-persona.js +0 -40
  196. package/dist/test/simple.test.js +0 -9
  197. package/dist/test/storage-integration.test.js +0 -150
  198. package/dist/test/subagent-manager.test.js +0 -276
  199. package/dist/test/test-gate-flow.test.js +0 -81
  200. package/dist/test/workflow-engine.test.js +0 -87
  201. 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
  }
@@ -2397,19 +2397,19 @@ export async function createWebServer(port = 3000, options = {}) {
2397
2397
  .map((p) => `- ${p.name || p.publicKey.slice(0, 8)} (pk=${p.publicKey.slice(0, 12)}…): 渠道[${p.channels.map((c) => c.name).join(', ') || '无'}]`)
2398
2398
  .join('\n');
2399
2399
  const goalDesc = ctx.goal ? `当前目标: ${ctx.goal.description} (已发起 ${ctx.goal.initiationsUsed}/${ctx.goal.maxInitiations}, 有效回复 ${ctx.goal.effectfulReplies}/${ctx.goal.effectThreshold})` : '当前无明确目标';
2400
- const prompt = `你是智能体「${ctx.self.name || '本地智能体'}」。你通过 P2P 网络认识以下其他智能体:
2401
- ${peerLines}
2402
-
2403
- ${goalDesc}
2404
-
2405
- 规则:
2406
- 1. 社交是为了达成上述目标, 不是闲聊。只在你有真正有价值的信息要分享/询问、且能推进目标时才主动发起。
2407
- 2. 不要重复最近已经聊过的话题, 不要每条心跳都发消息, 保持克制。
2408
- 3. 如果目标已经通过已有交流达成 (或你认为无需再聊), 输出 {"initiate": false, "goalAchieved": true}。
2409
- 4. 如果决定发起, 选一个最合适的目标渠道 (用对方渠道的真实 id)。
2410
-
2411
- 现在是否要主动联系其中某个智能体? 只输出一个 JSON 对象, 不要任何其他文字:
2412
- {"initiate": true 或 false, "goalAchieved": true 或 false, "targetPeerPublicKey": "对方 pk", "targetChannelId": "对方渠道 id", "message": "你要说的话"}
2400
+ const prompt = `你是智能体「${ctx.self.name || '本地智能体'}」。你通过 P2P 网络认识以下其他智能体:
2401
+ ${peerLines}
2402
+
2403
+ ${goalDesc}
2404
+
2405
+ 规则:
2406
+ 1. 社交是为了达成上述目标, 不是闲聊。只在你有真正有价值的信息要分享/询问、且能推进目标时才主动发起。
2407
+ 2. 不要重复最近已经聊过的话题, 不要每条心跳都发消息, 保持克制。
2408
+ 3. 如果目标已经通过已有交流达成 (或你认为无需再聊), 输出 {"initiate": false, "goalAchieved": true}。
2409
+ 4. 如果决定发起, 选一个最合适的目标渠道 (用对方渠道的真实 id)。
2410
+
2411
+ 现在是否要主动联系其中某个智能体? 只输出一个 JSON 对象, 不要任何其他文字:
2412
+ {"initiate": true 或 false, "goalAchieved": true 或 false, "targetPeerPublicKey": "对方 pk", "targetChannelId": "对方渠道 id", "message": "你要说的话"}
2413
2413
  若不想发起, 输出 {"initiate": false}。`;
2414
2414
  const raw = await agent.promptStream(prompt, () => { }, undefined, local.id);
2415
2415
  const m = raw.match(/\{[\s\S]*\}/);
@@ -2845,39 +2845,32 @@ ${goalDesc}
2845
2845
  });
2846
2846
  // ========== 登录框架 (2026-08-09) — GitHub/Google/邮箱/手机号, 仅骨架 ==========
2847
2847
  // 所有登录方式最终都归属到用户 DID (右下角唯一身份).
2848
+ // 2026-08-12: 登录配置托管到 Cloudflare 边缘 (Workers+KV), 本地 accounts.json 仅作降级 fallback.
2848
2849
  // 真实 OAuth / 验证码后续接入, 这里先做: 记录账号 + 绑定用户 DID + 提供状态查询.
2849
2850
  const ACCOUNTS_FILE = `${process.env.HOME || '/tmp'}/.bolloon/accounts.json`;
2850
- async function loadAccounts() {
2851
- try {
2852
- const { readFile } = await import('fs/promises');
2853
- const parsed = JSON.parse(await readFile(ACCOUNTS_FILE, 'utf-8'));
2854
- return Array.isArray(parsed) ? parsed : [];
2855
- }
2856
- catch {
2857
- return [];
2858
- }
2859
- }
2860
- async function saveAccounts(accs) {
2861
- const { mkdir, writeFile } = await import('fs/promises');
2862
- await mkdir(`${process.env.HOME || '/tmp'}/.bolloon`, { recursive: true });
2863
- await writeFile(ACCOUNTS_FILE, JSON.stringify(accs, null, 2), { mode: 0o600 });
2864
- }
2851
+ const EDGE_AUTH_URL = process.env.BOLLOON_EDGE_AUTH_URL || 'http://127.0.0.1:8788';
2852
+ const { EdgeAuthClient } = await import('./edge-auth-client.js');
2853
+ const edgeAuth = new EdgeAuthClient({
2854
+ baseUrl: EDGE_AUTH_URL,
2855
+ timeoutMs: 4000,
2856
+ fallbackFile: ACCOUNTS_FILE,
2857
+ log: (m) => { try {
2858
+ console.log(m);
2859
+ }
2860
+ catch { /* noop */ } },
2861
+ });
2862
+ async function loadAccounts() { return edgeAuth.loadAccounts(); }
2865
2863
  // GET /api/auth/status — 当前用户 DID + 已绑定账号列表
2866
2864
  app.get('/api/auth/status', async (_req, res) => {
2867
2865
  try {
2868
2866
  const identity = await loadOrCreateUserIdentity();
2869
- const accs = await loadAccounts();
2867
+ const accounts = await loadAccounts();
2870
2868
  res.json({
2871
2869
  did: identity.did,
2872
2870
  didShort: identity.didShort,
2873
2871
  name: identity.name,
2874
- // 只返回脱敏视图 (不含 token)
2875
- accounts: accs.map((a) => ({
2876
- provider: a.provider,
2877
- identifier: a.identifier || a.email || a.username || '',
2878
- loggedAt: a.loggedAt,
2879
- skeleton: !!a.skeleton,
2880
- })),
2872
+ // 只返回脱敏视图 (不含 token), 来源: 边缘 KV (worker 不可达时本地 fallback)
2873
+ accounts,
2881
2874
  });
2882
2875
  }
2883
2876
  catch (err) {
@@ -2899,31 +2892,9 @@ ${goalDesc}
2899
2892
  return res.status(400).json({ error: `${prov === 'email' ? '邮箱' : '手机号'}必填` });
2900
2893
  }
2901
2894
  const identity = await loadOrCreateUserIdentity();
2902
- const accs = await loadAccounts();
2903
2895
  const idStr = String(identifier || '').trim();
2904
- const existing = accs.find((a) => a.provider === prov && (!idStr || a.identifier === idStr || a.email === idStr));
2905
- const now = new Date().toISOString();
2906
- if (existing) {
2907
- // 已绑定 → 更新归属 DID + 时间
2908
- existing.ownerDid = identity.did;
2909
- existing.loggedAt = now;
2910
- existing.skeleton = true;
2911
- }
2912
- else {
2913
- accs.push({
2914
- provider: prov,
2915
- identifier: idStr || '',
2916
- email: prov === 'email' ? idStr : '',
2917
- phone: prov === 'phone' ? idStr : '',
2918
- username: idStr || '',
2919
- token: '', // 真实 OAuth 后填
2920
- ownerDid: identity.did, // 归属用户唯一 DID
2921
- loggedAt: now,
2922
- skeleton: true, // 骨架标记: 未做真实 OAuth/验证码
2923
- });
2924
- }
2925
- await saveAccounts(accs);
2926
- console.log(`[auth] 登录骨架: ${prov}${idStr ? ' ' + idStr : ''} → 归属 DID ${identity.did.substring(0, 20)}...`);
2896
+ const result = await edgeAuth.login({ provider: prov, identifier: idStr, ownerDid: identity.did });
2897
+ console.log(`[auth] 登录骨架: ${prov}${idStr ? ' ' + idStr : ''} → 归属 DID ${identity.did.substring(0, 20)}...${result.degraded ? ' (本地 fallback)' : ' (边缘)'}`);
2927
2898
  res.json({
2928
2899
  ok: true,
2929
2900
  provider: prov,
@@ -2931,6 +2902,7 @@ ${goalDesc}
2931
2902
  ownerDid: identity.did,
2932
2903
  skeleton: true,
2933
2904
  message: `${prov} 登录骨架已记录 (归属用户 DID), 真实 OAuth/验证码后续接入`,
2905
+ storage: result.degraded ? 'local' : 'edge',
2934
2906
  });
2935
2907
  }
2936
2908
  catch (err) {
@@ -2942,13 +2914,8 @@ ${goalDesc}
2942
2914
  try {
2943
2915
  const { provider } = req.body || {};
2944
2916
  const prov = String(provider || '').trim().toLowerCase();
2945
- const accs = await loadAccounts();
2946
- const before = accs.length;
2947
- const remaining = accs.filter((a) => a.provider !== prov);
2948
- if (remaining.length === before)
2949
- return res.status(404).json({ error: `未绑定 ${prov} 账号` });
2950
- await saveAccounts(remaining);
2951
- res.json({ ok: true, provider: prov });
2917
+ const result = await edgeAuth.logout({ provider: prov });
2918
+ res.json({ ok: true, provider: prov, storage: result.degraded ? 'local' : 'edge' });
2952
2919
  }
2953
2920
  catch (err) {
2954
2921
  res.status(500).json({ error: err.message });