@bolloon/bolloon-agent 0.2.12 → 0.2.13

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 (284) hide show
  1. package/README.md +495 -467
  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/bin/ipfs +0 -0
  6. package/dist/agents/agent-manifest-protocol.js +52 -0
  7. package/dist/agents/chat-segmenter.js +298 -0
  8. package/dist/agents/constraint-layer.js +19 -19
  9. package/dist/agents/judgment-protocol.js +479 -0
  10. package/dist/agents/parse-tool-call.js +304 -0
  11. package/dist/agents/peer-manifest-loader.js +210 -0
  12. package/dist/agents/pi-sdk-session-factory.js +110 -0
  13. package/dist/agents/pi-sdk-session-manager.js +297 -0
  14. package/dist/agents/pi-sdk-tools.js +1288 -0
  15. package/dist/agents/pi-sdk-types.js +13 -0
  16. package/dist/agents/pi-sdk.js +553 -1306
  17. package/dist/agents/react-loop.js +120 -0
  18. package/dist/agents/session-store.js +171 -0
  19. package/dist/agents/shell-guard.js +2 -2
  20. package/dist/agents/tool-registry.js +136 -0
  21. package/dist/agents/workflow-pivot-loop.js +200 -22
  22. package/dist/bollharness/src/scripts/context_router.js +7 -0
  23. package/dist/bollharness/src/scripts/deploy-guard.js +8 -8
  24. package/dist/bollharness-integration/context-router-judgment.js +4 -4
  25. package/dist/bollharness-integration/context-router.js +292 -292
  26. package/dist/bollharness-integration/gate-state-machine.js +26 -13
  27. package/dist/bollharness-integration/integration.js +71 -0
  28. package/dist/bollharness-integration/llm-judgment-engine.js +134 -134
  29. package/dist/bollharness-integration/skill-adapter.js +57 -127
  30. package/dist/bootstrap/chat-archiver.js +276 -0
  31. package/dist/bootstrap/context-collector.js +6 -3
  32. package/dist/bootstrap/event-log.js +160 -0
  33. package/dist/bootstrap/lifecycle-hooks.js +15 -1
  34. package/dist/bootstrap/memory-compressor.js +170 -0
  35. package/dist/bootstrap/persona-loader.js +94 -0
  36. package/dist/bootstrap/project-state.js +159 -0
  37. package/dist/bootstrap/remote-mirror.js +97 -0
  38. package/dist/bootstrap/session-window.js +121 -0
  39. package/dist/bootstrap/vector-index.js +248 -0
  40. package/dist/cli/loading-tui.js +40 -0
  41. package/dist/cli-entry.js +41 -37
  42. package/dist/context-compaction/auto-compact.js +7 -7
  43. package/dist/electron/config.js +21 -0
  44. package/dist/electron/config.js.map +1 -0
  45. package/dist/electron/dialogs.js +108 -0
  46. package/dist/electron/dialogs.js.map +1 -0
  47. package/dist/electron/first-run.js +170 -0
  48. package/dist/electron/first-run.js.map +1 -0
  49. package/dist/electron/ipc.js +20 -0
  50. package/dist/electron/ipc.js.map +1 -0
  51. package/dist/electron/logger.js +114 -0
  52. package/dist/electron/logger.js.map +1 -0
  53. package/dist/electron/main.js +63 -0
  54. package/dist/electron/main.js.map +1 -0
  55. package/dist/electron/menu.js +145 -0
  56. package/dist/electron/menu.js.map +1 -0
  57. package/dist/electron/paths.js +75 -0
  58. package/dist/electron/paths.js.map +1 -0
  59. package/dist/electron/server.js +119 -0
  60. package/dist/electron/server.js.map +1 -0
  61. package/dist/electron/tray.js +111 -0
  62. package/dist/electron/tray.js.map +1 -0
  63. package/dist/electron/window.js +111 -0
  64. package/dist/electron/window.js.map +1 -0
  65. package/dist/electron-preload.js +26 -6
  66. package/dist/electron-preload.js.map +1 -1
  67. package/dist/electron.js +6 -168
  68. package/dist/electron.js.map +1 -1
  69. package/dist/index.js +323 -266
  70. package/dist/llm/config-store.js +24 -8
  71. package/dist/llm/llm-judgment-client.js +102 -102
  72. package/dist/llm/pi-ai.js +137 -85
  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-visitor.md +19 -19
  76. package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -89
  77. package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -21
  78. package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -15
  79. package/dist/llm/system-prompt/layers/core/identity.md +37 -37
  80. package/dist/llm/system-prompt/layers/core/knowledge.md +17 -17
  81. package/dist/llm/system-prompt/layers/core/memory_system.md +12 -12
  82. package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -28
  83. package/dist/llm/system-prompt/layers/core/refusal.md +37 -37
  84. package/dist/llm/system-prompt/layers/core/tone.md +31 -31
  85. package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -13
  86. package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -41
  87. package/dist/llm/system-prompt/layers/role/architect.md +20 -20
  88. package/dist/llm/system-prompt/layers/role/expert.md +19 -19
  89. package/dist/llm/system-prompt/layers/role/implementer.md +15 -15
  90. package/dist/llm/system-prompt/layers/role/security.md +15 -15
  91. package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -72
  92. package/dist/llm/system-prompt/layers/tool/bash.md +25 -25
  93. package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -171
  94. package/dist/llm/system-prompt/layers/tool/image_search.md +70 -70
  95. package/dist/llm/system-prompt/layers/tool/manifest.md +89 -89
  96. package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -53
  97. package/dist/llm/system-prompt/layers/tool/web_search.md +83 -83
  98. package/dist/llm/tool-manifest/ask_user_input.js +1 -1
  99. package/dist/llm/tool-manifest/bash.js +3 -3
  100. package/dist/llm/tool-manifest/create_file.js +4 -4
  101. package/dist/llm/tool-manifest/fetch_sports_data.js +3 -3
  102. package/dist/llm/tool-manifest/image_search.js +2 -2
  103. package/dist/llm/tool-manifest/mcp.js +2 -2
  104. package/dist/llm/tool-manifest/message_compose.js +3 -3
  105. package/dist/llm/tool-manifest/places.js +2 -2
  106. package/dist/llm/tool-manifest/present_files.js +1 -1
  107. package/dist/llm/tool-manifest/recipe.js +2 -2
  108. package/dist/llm/tool-manifest/str_replace.js +5 -5
  109. package/dist/llm/tool-manifest/view.js +3 -3
  110. package/dist/llm/tool-manifest/weather.js +4 -4
  111. package/dist/llm/tool-manifest/web.js +4 -4
  112. package/dist/network/local-inbox-bus.js +73 -0
  113. package/dist/network/p2p-outbox.js +161 -0
  114. package/dist/network/peer-fs.js +420 -0
  115. package/dist/network/peer-resource-bridge.js +216 -0
  116. package/dist/pi-ecosystem-judgment/causal-judge.js +51 -51
  117. package/dist/pi-ecosystem-judgment/cleanup.js +126 -0
  118. package/dist/pi-ecosystem-judgment/distill-prompt.js +42 -42
  119. package/dist/pi-ecosystem-judgment/distillation.js +14 -14
  120. package/dist/pi-ecosystem-judgment/human-value-store.js +45 -11
  121. package/dist/pi-ecosystem-judgment/monitor-gate.js +28 -28
  122. package/dist/pi-ecosystem-judgment/value-injection.js +102 -102
  123. package/dist/security/context-router-tool.js +15 -15
  124. package/dist/security/tool-gate.js +11 -0
  125. package/dist/web/api-config.html +520 -520
  126. package/dist/web/client-loop-status.js +220 -0
  127. package/dist/web/client.js +22 -5
  128. package/dist/web/client.js.map +7 -0
  129. package/dist/web/components/wallet-viem.mjs +118 -118
  130. package/dist/web/index.html +375 -375
  131. package/dist/web/input-validator.js +103 -0
  132. package/dist/web/manifest.json +20 -20
  133. package/dist/web/routes-judgments.js +738 -0
  134. package/dist/web/routes-llm-config.js +279 -0
  135. package/dist/web/routes-tasks.js +222 -0
  136. package/dist/web/server-sse.js +121 -0
  137. package/dist/web/server-storage.js +154 -0
  138. package/dist/web/server-types.js +15 -0
  139. package/dist/web/server-v3-p2p.js +224 -0
  140. package/dist/web/server.js +1070 -1307
  141. package/dist/web/style.css +4742 -4742
  142. package/dist/web/util/safe-name.js +32 -0
  143. package/package.json +162 -160
  144. package/scripts/build-cli.js +215 -215
  145. package/scripts/build-web.ts +130 -130
  146. package/scripts/postinstall.js +152 -152
  147. package/bin/bolloon.js +0 -157
  148. package/dist/constraint-runtime/src/_archive_helper.js +0 -9
  149. package/dist/constraint-runtime/src/agent/coordinator.js +0 -48
  150. package/dist/constraint-runtime/src/agent/index.js +0 -1
  151. package/dist/constraint-runtime/src/assistant/index.js +0 -12
  152. package/dist/constraint-runtime/src/bootstrap/index.js +0 -12
  153. package/dist/constraint-runtime/src/bootstrap_graph.js +0 -13
  154. package/dist/constraint-runtime/src/bridge/index.js +0 -12
  155. package/dist/constraint-runtime/src/buddy/index.js +0 -12
  156. package/dist/constraint-runtime/src/cli/index.js +0 -12
  157. package/dist/constraint-runtime/src/command_graph.js +0 -10
  158. package/dist/constraint-runtime/src/commands.js +0 -60
  159. package/dist/constraint-runtime/src/components/index.js +0 -12
  160. package/dist/constraint-runtime/src/constants/index.js +0 -12
  161. package/dist/constraint-runtime/src/constraint/budget.js +0 -22
  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/context.js +0 -30
  165. package/dist/constraint-runtime/src/coordinator/index.js +0 -12
  166. package/dist/constraint-runtime/src/cost_hook.js +0 -4
  167. package/dist/constraint-runtime/src/cost_tracker.js +0 -8
  168. package/dist/constraint-runtime/src/deferred_init.js +0 -10
  169. package/dist/constraint-runtime/src/direct_modes.js +0 -6
  170. package/dist/constraint-runtime/src/dynamic-tool-loader.js +0 -85
  171. package/dist/constraint-runtime/src/entrypoints/index.js +0 -12
  172. package/dist/constraint-runtime/src/execution_registry.js +0 -44
  173. package/dist/constraint-runtime/src/history.js +0 -9
  174. package/dist/constraint-runtime/src/hooks/index.js +0 -12
  175. package/dist/constraint-runtime/src/index.js +0 -26
  176. package/dist/constraint-runtime/src/ink.js +0 -4
  177. package/dist/constraint-runtime/src/keybindings/index.js +0 -12
  178. package/dist/constraint-runtime/src/memdir/index.js +0 -12
  179. package/dist/constraint-runtime/src/migrations/index.js +0 -12
  180. package/dist/constraint-runtime/src/models.js +0 -1
  181. package/dist/constraint-runtime/src/moreright/index.js +0 -12
  182. package/dist/constraint-runtime/src/native_ts/index.js +0 -12
  183. package/dist/constraint-runtime/src/output_styles/index.js +0 -12
  184. package/dist/constraint-runtime/src/parity_audit.js +0 -12
  185. package/dist/constraint-runtime/src/plugins/index.js +0 -12
  186. package/dist/constraint-runtime/src/port_manifest.js +0 -11
  187. package/dist/constraint-runtime/src/prefetch.js +0 -9
  188. package/dist/constraint-runtime/src/query.js +0 -1
  189. package/dist/constraint-runtime/src/remote/index.js +0 -12
  190. package/dist/constraint-runtime/src/remote_runtime.js +0 -9
  191. package/dist/constraint-runtime/src/runtime/index.js +0 -1
  192. package/dist/constraint-runtime/src/runtime/session.js +0 -35
  193. package/dist/constraint-runtime/src/schemas/index.js +0 -12
  194. package/dist/constraint-runtime/src/screens/index.js +0 -12
  195. package/dist/constraint-runtime/src/server/index.js +0 -12
  196. package/dist/constraint-runtime/src/services/index.js +0 -12
  197. package/dist/constraint-runtime/src/session_store.js +0 -22
  198. package/dist/constraint-runtime/src/setup.js +0 -30
  199. package/dist/constraint-runtime/src/skills/index.js +0 -1
  200. package/dist/constraint-runtime/src/skills/skill-registry.js +0 -28
  201. package/dist/constraint-runtime/src/state/index.js +0 -12
  202. package/dist/constraint-runtime/src/system_init.js +0 -20
  203. package/dist/constraint-runtime/src/thinking/engine.js +0 -42
  204. package/dist/constraint-runtime/src/thinking/index.js +0 -1
  205. package/dist/constraint-runtime/src/tool_pool.js +0 -8
  206. package/dist/constraint-runtime/src/tools/OpenCLI/execAdapter.js +0 -7
  207. package/dist/constraint-runtime/src/tools/OpenCLI/listAdapters.js +0 -7
  208. package/dist/constraint-runtime/src/tools/OpenCLI/runCommand.js +0 -7
  209. package/dist/constraint-runtime/src/tools/SafeSDK/confirmTransaction.js +0 -6
  210. package/dist/constraint-runtime/src/tools/SafeSDK/createTransaction.js +0 -8
  211. package/dist/constraint-runtime/src/tools/SafeSDK/executeTransaction.js +0 -6
  212. package/dist/constraint-runtime/src/tools/SafeSDK/getBalance.js +0 -6
  213. package/dist/constraint-runtime/src/tools/SafeSDK/getPendingTransactions.js +0 -6
  214. package/dist/constraint-runtime/src/tools/SafeSDK/proposeTransaction.js +0 -6
  215. package/dist/constraint-runtime/src/tools.js +0 -80
  216. package/dist/constraint-runtime/src/transcript.js +0 -19
  217. package/dist/constraint-runtime/src/types/index.js +0 -12
  218. package/dist/constraint-runtime/src/upstream_proxy/index.js +0 -12
  219. package/dist/constraint-runtime/src/utils/index.js +0 -12
  220. package/dist/constraint-runtime/src/vim/index.js +0 -12
  221. package/dist/constraint-runtime/src/voice/index.js +0 -12
  222. package/dist/constraint-runtime/tests/agent.test.js +0 -16
  223. package/dist/constraint-runtime/tests/constraint.test.js +0 -41
  224. package/dist/constraint-runtime/tests/skill.test.js +0 -19
  225. package/dist/constraint-runtime/tests/thinking.test.js +0 -22
  226. package/dist/pi-ecosystem-colony/index.js +0 -365
  227. package/dist/social/ant-colony/AdaptiveHeartbeat.js +0 -101
  228. package/dist/social/ant-colony/PheromoneEngine.js +0 -227
  229. package/dist/social/ant-colony/index.js +0 -6
  230. package/dist/social/ant-colony/types.js +0 -24
  231. package/dist/test/ai-judgment-test.js +0 -80
  232. package/dist/test/bollharness-integration.test.js +0 -318
  233. package/dist/test/channel-agent-multi-dialogue.js +0 -205
  234. package/dist/test/channel-heartbeat-agent-test.js +0 -201
  235. package/dist/test/constraint-layer.test.js +0 -164
  236. package/dist/test/diap-identity-test.js +0 -172
  237. package/dist/test/diap-quick-test.js +0 -62
  238. package/dist/test/global-shared-context.test.js +0 -315
  239. package/dist/test/harness-judgment-injection.test.js +0 -246
  240. package/dist/test/harness-workflow-integrator-test.js +0 -228
  241. package/dist/test/human-value-store.test.js +0 -243
  242. package/dist/test/hybrid-integration-test.js +0 -118
  243. package/dist/test/hybrid-messenger-verify.js +0 -55
  244. package/dist/test/iroh-bistream-debug.js +0 -38
  245. package/dist/test/iroh-communication.test.js +0 -66
  246. package/dist/test/iroh-debug-test.js +0 -57
  247. package/dist/test/iroh-diap-test.js +0 -71
  248. package/dist/test/iroh-direct-connect.js +0 -55
  249. package/dist/test/iroh-e2e-fixed.js +0 -89
  250. package/dist/test/iroh-e2e-same-process.js +0 -63
  251. package/dist/test/iroh-e2e.js +0 -66
  252. package/dist/test/iroh-final-e2e.js +0 -72
  253. package/dist/test/iroh-relay-test.js +0 -37
  254. package/dist/test/iroh-simple-test.js +0 -41
  255. package/dist/test/iroh-transport-verify.js +0 -54
  256. package/dist/test/iroh-transport.test.js +0 -37
  257. package/dist/test/iroh-two-nodes.js +0 -70
  258. package/dist/test/iroh-verify.js +0 -44
  259. package/dist/test/judgment-decision.test.js +0 -219
  260. package/dist/test/llm-judgment-integration.test.js +0 -220
  261. package/dist/test/p2p-agent-complex-dialogue.js +0 -385
  262. package/dist/test/p2p-agent-dialogue.js +0 -341
  263. package/dist/test/p2p-agent-full-bidirectional.js +0 -510
  264. package/dist/test/p2p-agent-harness-flow.js +0 -437
  265. package/dist/test/p2p-agent-harness-single.js +0 -143
  266. package/dist/test/p2p-ai-dialogue-test.js +0 -318
  267. package/dist/test/p2p-cid-connect-test.js +0 -195
  268. package/dist/test/p2p-connect-receiver.js +0 -69
  269. package/dist/test/p2p-doc-transfer.js +0 -110
  270. package/dist/test/p2p-identity-page-test.js +0 -77
  271. package/dist/test/p2p-iroh-test.js +0 -171
  272. package/dist/test/p2p-minimal-test.js +0 -241
  273. package/dist/test/p2p-node-1.js +0 -148
  274. package/dist/test/p2p-node-2.js +0 -148
  275. package/dist/test/p2p-server.js +0 -281
  276. package/dist/test/p2p-two-nodes-test.js +0 -438
  277. package/dist/test/pi-sdk.test.js +0 -44
  278. package/dist/test/set-persona.js +0 -40
  279. package/dist/test/simple.test.js +0 -9
  280. package/dist/test/storage-integration.test.js +0 -150
  281. package/dist/test/subagent-manager.test.js +0 -276
  282. package/dist/test/test-gate-flow.test.js +0 -81
  283. package/dist/test/workflow-engine.test.js +0 -87
  284. package/dist/test/workflow-pivot-loop.test.js +0 -246
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.hasSeenFirstRun = hasSeenFirstRun;
37
+ exports.markFirstRunSeen = markFirstRunSeen;
38
+ exports.showFirstRunOverlay = showFirstRunOverlay;
39
+ exports.registerFirstRunIpc = registerFirstRunIpc;
40
+ exports.maybeShowFirstRun = maybeShowFirstRun;
41
+ /**
42
+ * 首启检测 + 引导浮层
43
+ *
44
+ * 标记文件写在 userData (不是 ~/.bolloon/), 卸载 app 自然清掉
45
+ * 引导窗是父主窗的 modal, frame=false, 透明背景; 关闭时标记写入
46
+ */
47
+ const electron_1 = require("electron");
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ const paths_1 = require("./paths");
51
+ const logger_1 = require("./logger");
52
+ const OVERLAY_HTML = `
53
+ <!DOCTYPE html>
54
+ <html>
55
+ <head>
56
+ <meta charset="utf-8" />
57
+ <style>
58
+ :root { color-scheme: light dark; }
59
+ body {
60
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
61
+ margin: 0; padding: 32px 28px;
62
+ background: rgba(245,245,247,0.97);
63
+ color: #1d1d1f;
64
+ height: 100vh; box-sizing: border-box;
65
+ }
66
+ @media (prefers-color-scheme: dark) {
67
+ body { background: rgba(28,28,30,0.97); color: #f5f5f7; }
68
+ }
69
+ h1 { font-size: 18px; margin: 0 0 14px; font-weight: 600; }
70
+ p { font-size: 13px; line-height: 1.55; margin: 8px 0; }
71
+ code {
72
+ font-family: ui-monospace, "SF Mono", Menlo, monospace;
73
+ font-size: 12px; padding: 1px 5px;
74
+ background: rgba(0,0,0,0.06); border-radius: 3px;
75
+ }
76
+ @media (prefers-color-scheme: dark) {
77
+ code { background: rgba(255,255,255,0.08); }
78
+ }
79
+ .btn {
80
+ display: inline-block; margin-top: 18px; padding: 8px 18px;
81
+ background: #007aff; color: #fff; border: none; border-radius: 6px;
82
+ font-size: 13px; font-weight: 500; cursor: pointer;
83
+ }
84
+ .btn:hover { background: #0066d6; }
85
+ ul { padding-left: 20px; }
86
+ li { font-size: 13px; line-height: 1.7; }
87
+ </style>
88
+ </head>
89
+ <body>
90
+ <h1>欢迎使用 Bolloon Agent</h1>
91
+ <p>你的数据存放在本地, 不上传:</p>
92
+ <ul>
93
+ <li>配置 / 频道 / P2P 密钥: <code id="data"></code></li>
94
+ <li>运行日志: <code id="logs"></code></li>
95
+ </ul>
96
+ <p>所有数据在卸载后仍保留 — 想清理就手动删除 ~/.bolloon/。</p>
97
+ <button class="btn" id="ok">知道了</button>
98
+ <script>
99
+ const ok = document.getElementById('ok');
100
+ ok.addEventListener('click', () => window.electronAPI.markFirstRunSeen());
101
+ document.getElementById('data').textContent = window.electronAPI.getDataPathSync?.() || '';
102
+ document.getElementById('logs').textContent = window.electronAPI.getLogsPathSync?.() || '';
103
+ </script>
104
+ </body>
105
+ </html>
106
+ `;
107
+ function hasSeenFirstRun() {
108
+ try {
109
+ return fs.existsSync((0, paths_1.firstRunFlagPath)());
110
+ }
111
+ catch {
112
+ return false;
113
+ }
114
+ }
115
+ function markFirstRunSeen() {
116
+ try {
117
+ fs.mkdirSync(path.dirname((0, paths_1.firstRunFlagPath)()), { recursive: true });
118
+ fs.writeFileSync((0, paths_1.firstRunFlagPath)(), new Date().toISOString());
119
+ }
120
+ catch (err) {
121
+ (0, logger_1.log)(`写入首启标记失败: ${err.message}`, 'warn');
122
+ }
123
+ }
124
+ function showFirstRunOverlay(parent) {
125
+ return new Promise((resolve) => {
126
+ const overlay = new electron_1.BrowserWindow({
127
+ parent,
128
+ modal: true,
129
+ frame: false,
130
+ transparent: true,
131
+ width: 520,
132
+ height: 360,
133
+ resizable: false,
134
+ movable: false,
135
+ minimizable: false,
136
+ maximizable: false,
137
+ title: 'Welcome',
138
+ });
139
+ const dataUrl = 'data:text/html;charset=utf-8,' + encodeURIComponent(OVERLAY_HTML);
140
+ overlay.loadURL(dataUrl);
141
+ // 一次性的 IPC handler, 关闭后清掉避免累积
142
+ const handler = () => {
143
+ markFirstRunSeen();
144
+ overlay.close();
145
+ };
146
+ electron_1.ipcMain.once('first-run:ack', handler);
147
+ overlay.on('closed', () => {
148
+ electron_1.ipcMain.removeListener('first-run:ack', handler);
149
+ resolve();
150
+ });
151
+ });
152
+ }
153
+ /** 注册 IPC handlers (给 preload 桥用) */
154
+ function registerFirstRunIpc() {
155
+ electron_1.ipcMain.handle('first-run:seen', () => hasSeenFirstRun());
156
+ electron_1.ipcMain.handle('first-run:mark-seen', () => { markFirstRunSeen(); });
157
+ // 同步值 (不用 ipcRenderer.invoke 的 await) — 用 exposeInMainWorld 的 sync getter 更顺
158
+ electron_1.ipcMain.handle('first-run:data-dir', () => (0, paths_1.dataDir)());
159
+ electron_1.ipcMain.handle('first-run:logs-dir', () => (0, paths_1.logsDir)());
160
+ (0, logger_1.log)('first-run IPC handlers registered');
161
+ }
162
+ /** 包装 — 决定要不要弹 overlay */
163
+ async function maybeShowFirstRun(parent) {
164
+ if (hasSeenFirstRun())
165
+ return;
166
+ (0, logger_1.log)('首启 — 弹出引导');
167
+ await showFirstRunOverlay(parent);
168
+ electron_1.app.addRecentDocument((0, paths_1.firstRunFlagPath)()); // 跟踪最近文档, 让 user 知道有这文件
169
+ }
170
+ //# sourceMappingURL=first-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"first-run.js","sourceRoot":"","sources":["../../src/electron/first-run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerCoreIpc = registerCoreIpc;
4
+ /**
5
+ * IPC handler 集中注册 — version / userData path / open-external (legacy 3 个)
6
+ * dialog/fs 的注册在 dialogs.ts; updater 的注册在 updater.ts
7
+ */
8
+ const electron_1 = require("electron");
9
+ const paths_1 = require("./paths");
10
+ const logger_1 = require("./logger");
11
+ function registerCoreIpc() {
12
+ electron_1.ipcMain.handle('get-version', () => electron_1.app.getVersion());
13
+ electron_1.ipcMain.handle('get-user-data-path', () => (0, paths_1.userDataDir)());
14
+ electron_1.ipcMain.handle('get-data-path', () => (0, paths_1.dataDir)()); // 跟 userData 分开, 渲染层要用
15
+ electron_1.ipcMain.handle('open-external', async (_event, url) => {
16
+ await electron_1.shell.openExternal(url);
17
+ });
18
+ (0, logger_1.log)('core IPC handlers registered');
19
+ }
20
+ //# sourceMappingURL=ipc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipc.js","sourceRoot":"","sources":["../../src/electron/ipc.ts"],"names":[],"mappings":";;AAQA,0CAWC;AAnBD;;;GAGG;AACH,uCAA+C;AAC/C,mCAA+C;AAC/C,qCAA+B;AAE/B,SAAgB,eAAe;IAC7B,kBAAO,CAAC,MAAM,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,cAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IAEtD,kBAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,IAAA,mBAAW,GAAE,CAAC,CAAC;IAC1D,kBAAO,CAAC,MAAM,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,IAAA,eAAO,GAAE,CAAC,CAAC,CAAC,uBAAuB;IAEzE,kBAAO,CAAC,MAAM,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,GAAW,EAAE,EAAE;QAC5D,MAAM,gBAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,IAAA,YAAG,EAAC,8BAA8B,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.log = log;
37
+ /**
38
+ * 简单 logger: 写日志到 <userData>/logs/bolloon.log, size-based 轮转
39
+ * (5MB 上限, 保留 .1 .2 .3 共 3 个备份 → ~20MB 上限)
40
+ *
41
+ * 同步写是因为 Electron 主进程日志量小, 同步 append 简单可靠, 不丢日志.
42
+ * 量大的会话级 jsonl 走自己路径 (lifecycle-hooks 等), 跟本 logger 无关.
43
+ */
44
+ const fs = __importStar(require("fs"));
45
+ const paths_1 = require("./paths");
46
+ const MAX_BYTES = 5 * 1024 * 1024;
47
+ const MAX_BACKUPS = 3; // 保留 bolloon.log.1 .2 .3
48
+ let currentSize = 0;
49
+ let initialized = false;
50
+ function ensureLogFile() {
51
+ if (initialized)
52
+ return;
53
+ initialized = true;
54
+ try {
55
+ fs.mkdirSync((0, paths_1.logsDir)(), { recursive: true });
56
+ try {
57
+ currentSize = fs.statSync((0, paths_1.mainLogPath)()).size;
58
+ }
59
+ catch {
60
+ currentSize = 0;
61
+ }
62
+ }
63
+ catch (err) {
64
+ // 失败也无所谓, log() 内部会 swallow
65
+ currentSize = 0;
66
+ console.error('[logger] ensureLogFile failed:', err);
67
+ }
68
+ }
69
+ function rotate() {
70
+ const logPath = (0, paths_1.mainLogPath)();
71
+ for (let i = MAX_BACKUPS; i >= 1; i--) {
72
+ const src = `${logPath}.${i}`;
73
+ const dst = `${logPath}.${i + 1}`;
74
+ if (i === MAX_BACKUPS) {
75
+ try {
76
+ fs.unlinkSync(src);
77
+ }
78
+ catch { /* missing ok */ }
79
+ }
80
+ else {
81
+ try {
82
+ fs.renameSync(src, dst);
83
+ }
84
+ catch { /* missing ok */ }
85
+ }
86
+ }
87
+ try {
88
+ fs.renameSync(logPath, `${logPath}.1`);
89
+ }
90
+ catch { /* missing ok */ }
91
+ currentSize = 0;
92
+ }
93
+ function log(message, level = 'info') {
94
+ ensureLogFile();
95
+ const ts = new Date().toISOString();
96
+ const line = `[${ts}] [${level}] ${message}\n`;
97
+ if (currentSize + line.length > MAX_BYTES)
98
+ rotate();
99
+ try {
100
+ fs.appendFileSync((0, paths_1.mainLogPath)(), line);
101
+ currentSize += line.length;
102
+ }
103
+ catch (err) {
104
+ // 写不进就 console, 不要再递归 log
105
+ console.error('[logger] appendFileSync failed:', err);
106
+ }
107
+ if (level === 'error')
108
+ console.error(line.trimEnd());
109
+ else if (level === 'warn')
110
+ console.warn(line.trimEnd());
111
+ else
112
+ console.log(line.trimEnd());
113
+ }
114
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/electron/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Electron 主进程 lifecycle 入口
5
+ * 单实例锁 → whenReady → createMainWindow → cleanup on quit
6
+ * 启动时: 装 menu / tray / IPC handlers / 首启引导
7
+ */
8
+ const electron_1 = require("electron");
9
+ const logger_1 = require("./logger");
10
+ const window_1 = require("./window");
11
+ const server_1 = require("./server");
12
+ const menu_1 = require("./menu");
13
+ const tray_1 = require("./tray");
14
+ const ipc_1 = require("./ipc");
15
+ const dialogs_1 = require("./dialogs");
16
+ const first_run_1 = require("./first-run");
17
+ (0, logger_1.log)('Bolloon Electron 启动');
18
+ // 单实例锁
19
+ const gotTheLock = electron_1.app.requestSingleInstanceLock();
20
+ if (!gotTheLock) {
21
+ (0, logger_1.log)('已有实例在运行,退出');
22
+ electron_1.app.quit();
23
+ }
24
+ electron_1.app.on('second-instance', () => {
25
+ (0, window_1.focusMainWindow)();
26
+ });
27
+ electron_1.app.whenReady().then(async () => {
28
+ (0, logger_1.log)('Electron 准备好');
29
+ (0, ipc_1.registerCoreIpc)();
30
+ (0, dialogs_1.registerDialogIpc)();
31
+ (0, first_run_1.registerFirstRunIpc)();
32
+ (0, menu_1.installAppMenu)(window_1.getMainWindow);
33
+ (0, tray_1.createTray)(window_1.getMainWindow);
34
+ await (0, window_1.createMainWindow)();
35
+ // 首启引导 (在主窗口就绪后弹, 不阻塞 UI)
36
+ const win = (0, window_1.getMainWindow)();
37
+ if (win) {
38
+ win.webContents.once('did-finish-load', () => {
39
+ void (0, first_run_1.maybeShowFirstRun)(win);
40
+ });
41
+ }
42
+ electron_1.app.on('activate', async () => {
43
+ // macOS: dock 图标被点击且没有窗口时, 重开
44
+ if (electron_1.BrowserWindow.getAllWindows().length === 0) {
45
+ await (0, window_1.createMainWindow)();
46
+ }
47
+ });
48
+ });
49
+ electron_1.app.on('window-all-closed', () => {
50
+ (0, logger_1.log)('所有窗口已关闭');
51
+ (0, tray_1.destroyTray)();
52
+ (0, server_1.killWebServer)();
53
+ if (process.platform !== 'darwin') {
54
+ electron_1.app.quit();
55
+ }
56
+ });
57
+ electron_1.app.on('before-quit', () => {
58
+ (0, logger_1.log)('应用即将退出');
59
+ (0, tray_1.destroyTray)();
60
+ (0, server_1.killWebServer)();
61
+ });
62
+ (0, logger_1.log)('主进程初始化完成');
63
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/electron/main.ts"],"names":[],"mappings":";;AAAA;;;;GAIG;AACH,uCAA8C;AAC9C,qCAA+B;AAC/B,qCAA4E;AAC5E,qCAAyC;AACzC,iCAAwC;AACxC,iCAAiD;AACjD,+BAAwC;AACxC,uCAA8C;AAC9C,2CAAqE;AAErE,IAAA,YAAG,EAAC,qBAAqB,CAAC,CAAC;AAE3B,OAAO;AACP,MAAM,UAAU,GAAG,cAAG,CAAC,yBAAyB,EAAE,CAAC;AACnD,IAAI,CAAC,UAAU,EAAE,CAAC;IAChB,IAAA,YAAG,EAAC,YAAY,CAAC,CAAC;IAClB,cAAG,CAAC,IAAI,EAAE,CAAC;AACb,CAAC;AAED,cAAG,CAAC,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC7B,IAAA,wBAAe,GAAE,CAAC;AACpB,CAAC,CAAC,CAAC;AAEH,cAAG,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;IAC9B,IAAA,YAAG,EAAC,cAAc,CAAC,CAAC;IACpB,IAAA,qBAAe,GAAE,CAAC;IAClB,IAAA,2BAAiB,GAAE,CAAC;IACpB,IAAA,+BAAmB,GAAE,CAAC;IACtB,IAAA,qBAAc,EAAC,sBAAa,CAAC,CAAC;IAC9B,IAAA,iBAAU,EAAC,sBAAa,CAAC,CAAC;IAE1B,MAAM,IAAA,yBAAgB,GAAE,CAAC;IAEzB,0BAA0B;IAC1B,MAAM,GAAG,GAAG,IAAA,sBAAa,GAAE,CAAC;IAC5B,IAAI,GAAG,EAAE,CAAC;QACR,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,EAAE;YAC3C,KAAK,IAAA,6BAAiB,EAAC,GAAG,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,cAAG,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;QAC5B,8BAA8B;QAC9B,IAAI,wBAAa,CAAC,aAAa,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAA,yBAAgB,GAAE,CAAC;QAC3B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,cAAG,CAAC,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;IAC/B,IAAA,YAAG,EAAC,SAAS,CAAC,CAAC;IACf,IAAA,kBAAW,GAAE,CAAC;IACd,IAAA,sBAAa,GAAE,CAAC;IAChB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,cAAG,CAAC,IAAI,EAAE,CAAC;IACb,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,cAAG,CAAC,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;IACzB,IAAA,YAAG,EAAC,QAAQ,CAAC,CAAC;IACd,IAAA,kBAAW,GAAE,CAAC;IACd,IAAA,sBAAa,GAAE,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,IAAA,YAAG,EAAC,UAAU,CAAC,CAAC"}
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildAppMenu = buildAppMenu;
4
+ exports.installAppMenu = installAppMenu;
5
+ /**
6
+ * 应用菜单 — macOS 标准 + File/Edit/View/Window/Help 自定义项
7
+ * "Open Data Folder" 等会跨平台显示 (mac 也会出现, 不会冲突)
8
+ */
9
+ const electron_1 = require("electron");
10
+ const paths_1 = require("./paths");
11
+ const logger_1 = require("./logger");
12
+ function openDataFolder() {
13
+ electron_1.shell.openPath((0, paths_1.dataDir)()).catch((e) => (0, logger_1.log)(`open data folder 失败: ${e.message}`, 'error'));
14
+ }
15
+ function openLogsFolder() {
16
+ electron_1.shell.openPath((0, paths_1.logsDir)()).catch((e) => (0, logger_1.log)(`open logs folder 失败: ${e.message}`, 'error'));
17
+ }
18
+ function openExternal(url) {
19
+ electron_1.shell.openExternal(url).catch((e) => (0, logger_1.log)(`openExternal 失败: ${e.message}`, 'error'));
20
+ }
21
+ function buildAppMenu(getMainWindow) {
22
+ const isMac = process.platform === 'darwin';
23
+ const win = getMainWindow();
24
+ const appMenu = {
25
+ label: electron_1.app.getName(),
26
+ submenu: [
27
+ { role: 'about' },
28
+ { type: 'separator' },
29
+ { role: 'services' },
30
+ { type: 'separator' },
31
+ { role: 'hide' },
32
+ { role: 'hideOthers' },
33
+ { role: 'unhide' },
34
+ { type: 'separator' },
35
+ { role: 'quit' },
36
+ ],
37
+ };
38
+ const fileMenu = {
39
+ label: 'File',
40
+ submenu: [
41
+ {
42
+ label: 'Open Data Folder',
43
+ accelerator: 'CmdOrCtrl+Shift+D',
44
+ click: () => openDataFolder(),
45
+ },
46
+ {
47
+ label: 'Open Logs Folder',
48
+ accelerator: 'CmdOrCtrl+Shift+L',
49
+ click: () => openLogsFolder(),
50
+ },
51
+ { type: 'separator' },
52
+ isMac ? { role: 'close' } : { role: 'quit' },
53
+ ],
54
+ };
55
+ const editMenu = {
56
+ label: 'Edit',
57
+ submenu: [
58
+ { role: 'undo' },
59
+ { role: 'redo' },
60
+ { type: 'separator' },
61
+ { role: 'cut' },
62
+ { role: 'copy' },
63
+ { role: 'paste' },
64
+ { role: 'selectAll' },
65
+ ],
66
+ };
67
+ const viewMenu = {
68
+ label: 'View',
69
+ submenu: [
70
+ {
71
+ label: 'Reload',
72
+ accelerator: 'CmdOrCtrl+R',
73
+ click: () => win?.webContents.reload(),
74
+ },
75
+ {
76
+ label: 'Force Reload',
77
+ accelerator: 'CmdOrCtrl+Shift+R',
78
+ click: () => win?.webContents.reloadIgnoringCache(),
79
+ },
80
+ {
81
+ label: 'Toggle DevTools',
82
+ accelerator: isMac ? 'Alt+Cmd+I' : 'Ctrl+Shift+I',
83
+ click: () => win?.webContents.toggleDevTools(),
84
+ },
85
+ { type: 'separator' },
86
+ { role: 'resetZoom' },
87
+ { role: 'zoomIn' },
88
+ { role: 'zoomOut' },
89
+ { type: 'separator' },
90
+ { role: 'togglefullscreen' },
91
+ ],
92
+ };
93
+ const windowMenu = {
94
+ label: 'Window',
95
+ submenu: [
96
+ { role: 'minimize' },
97
+ { role: 'zoom' },
98
+ ...(isMac
99
+ ? [{ type: 'separator' }, { role: 'front' }]
100
+ : [{ role: 'close' }]),
101
+ ],
102
+ };
103
+ const helpMenu = {
104
+ role: 'help',
105
+ submenu: [
106
+ {
107
+ label: 'GitHub Repository',
108
+ click: () => openExternal('https://github.com/bolloon/bolloon'),
109
+ },
110
+ {
111
+ label: 'Report Issue',
112
+ click: () => openExternal('https://github.com/bolloon/bolloon/issues'),
113
+ },
114
+ { type: 'separator' },
115
+ {
116
+ label: 'About Bolloon Agent',
117
+ click: () => {
118
+ // 简单 about — 用 dialog 暂代 (避免再造 HTML 窗口)
119
+ // 真实 about panel 在 macOS 是 app.role 触发的, 我们走菜单项即可
120
+ const { dialog } = require('electron');
121
+ dialog.showMessageBox({
122
+ type: 'info',
123
+ title: 'About Bolloon Agent',
124
+ message: `Bolloon Agent v${electron_1.app.getVersion()}`,
125
+ detail: `P2P AI Document Agent\nData: ${(0, paths_1.dataDir)()}\nLogs: ${(0, paths_1.logsDir)()}`,
126
+ buttons: ['OK'],
127
+ }).catch(() => { });
128
+ },
129
+ },
130
+ ],
131
+ };
132
+ const template = [
133
+ ...(isMac ? [appMenu] : []),
134
+ fileMenu,
135
+ editMenu,
136
+ viewMenu,
137
+ windowMenu,
138
+ helpMenu,
139
+ ];
140
+ return electron_1.Menu.buildFromTemplate(template);
141
+ }
142
+ function installAppMenu(getMainWindow) {
143
+ electron_1.Menu.setApplicationMenu(buildAppMenu(getMainWindow));
144
+ }
145
+ //# sourceMappingURL=menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/electron/menu.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.dataDir = dataDir;
37
+ exports.userDataDir = userDataDir;
38
+ exports.logsDir = logsDir;
39
+ exports.mainLogPath = mainLogPath;
40
+ exports.firstRunFlagPath = firstRunFlagPath;
41
+ exports.buildResourcesDir = buildResourcesDir;
42
+ /**
43
+ * 路径常量 — 单一来源, 避免散落各处
44
+ *
45
+ * dataDir: 用户数据 (LLM config / P2P secret / 频道 JSON 等) — 故意保持在 ~/.bolloon/
46
+ * 与 CLI 共用, 卸载 app 不删数据. 不要改这个路径, 不要做 userData 重定向.
47
+ * userDataDir: Electron 的 app.getPath('userData'), 用来放日志 / 临时 / 锁文件
48
+ * logsDir: userData 下的 logs/ 子目录
49
+ */
50
+ const electron_1 = require("electron");
51
+ const os = __importStar(require("os"));
52
+ const path = __importStar(require("path"));
53
+ function dataDir() {
54
+ return path.join(os.homedir(), '.bolloon');
55
+ }
56
+ function userDataDir() {
57
+ return electron_1.app.getPath('userData');
58
+ }
59
+ function logsDir() {
60
+ return path.join(userDataDir(), 'logs');
61
+ }
62
+ function mainLogPath() {
63
+ return path.join(logsDir(), 'bolloon.log');
64
+ }
65
+ function firstRunFlagPath() {
66
+ return path.join(userDataDir(), '.bolloon-first-run-seen');
67
+ }
68
+ /** 资源目录: packaged 下是 process.resourcesPath/build, dev 下是 repo/build/ */
69
+ function buildResourcesDir() {
70
+ if (electron_1.app.isPackaged) {
71
+ return path.join(process.resourcesPath, 'build');
72
+ }
73
+ return path.join(electron_1.app.getAppPath(), 'build');
74
+ }
75
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/electron/paths.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,0BAEC;AAED,kCAEC;AAED,0BAEC;AAED,kCAEC;AAED,4CAEC;AAGD,8CAKC;AAtCD;;;;;;;GAOG;AACH,uCAA+B;AAC/B,uCAAyB;AACzB,2CAA6B;AAE7B,SAAgB,OAAO;IACrB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAC7C,CAAC;AAED,SAAgB,WAAW;IACzB,OAAO,cAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AACjC,CAAC;AAED,SAAgB,OAAO;IACrB,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED,SAAgB,WAAW;IACzB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AAC7C,CAAC;AAED,SAAgB,gBAAgB;IAC9B,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,yBAAyB,CAAC,CAAC;AAC7D,CAAC;AAED,wEAAwE;AACxE,SAAgB,iBAAiB;IAC/B,IAAI,cAAG,CAAC,UAAU,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,cAAG,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC"}