@bolloon/bolloon-agent 0.6.4 → 0.6.6

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 (173) hide show
  1. package/dist/agents/chain/chain-settlement.js +0 -1
  2. package/dist/agents/chat-segmenter.js +4 -16
  3. package/dist/agents/contacts/human-directory.js +155 -0
  4. package/dist/agents/contacts/tools.js +79 -0
  5. package/dist/agents/experience-review.js +0 -3
  6. package/dist/agents/goal-flywheel/goal-change.js +3 -4
  7. package/dist/agents/goal-resume.js +0 -4
  8. package/dist/agents/intent-classifier.js +1 -1
  9. package/dist/agents/iteration-budget.js +12 -0
  10. package/dist/agents/knowledge-organizer.js +0 -2
  11. package/dist/agents/lesson-to-skill.js +0 -1
  12. package/dist/agents/loop-review.js +2 -2
  13. package/dist/agents/memory-store.js +359 -0
  14. package/dist/agents/opportunity-inbox.js +147 -0
  15. package/dist/agents/opportunity-match.js +48 -7
  16. package/dist/agents/opportunity-web-search.js +222 -0
  17. package/dist/agents/p2p-chat-tools.js +1 -2
  18. package/dist/agents/parse-tool-call.js +9 -22
  19. package/dist/agents/pi-harness.js +1 -2
  20. package/dist/agents/pi-sdk-tools.js +180 -5
  21. package/dist/agents/pi-sdk.js +143 -9
  22. package/dist/agents/process-runner.js +28 -9
  23. package/dist/agents/react-loop.js +9 -17
  24. package/dist/agents/runner-resolver.js +4 -3
  25. package/dist/agents/skill-loader.js +22 -15
  26. package/dist/agents/skills-manager.js +1 -25
  27. package/dist/agents/workflow-pivot-loop.js +152 -61
  28. package/dist/agents/world-watcher.js +30 -1
  29. package/dist/bootstrap/context-collector.js +2 -4
  30. package/dist/bootstrap/context-hierarchy.js +13 -1
  31. package/dist/cli/ink-app.js +44 -17
  32. package/dist/cli/intent-command.js +22 -12
  33. package/dist/cli/loading-tui.js +8 -2
  34. package/dist/cli/log-gate.js +40 -8
  35. package/dist/cli/mention-data.js +1 -0
  36. package/dist/cli/reply-hygiene.js +22 -0
  37. package/dist/cli/trace-line.js +61 -2
  38. package/dist/electron-build/agents/agent-gateway.js.map +1 -1
  39. package/dist/electron-build/agents/chain/chain-indexer.js.map +1 -1
  40. package/dist/electron-build/agents/chain/chain-settlement.js +0 -1
  41. package/dist/electron-build/agents/chain/chain-settlement.js.map +1 -1
  42. package/dist/electron-build/agents/contacts/chain.js.map +1 -1
  43. package/dist/electron-build/agents/contacts/human-directory.js +204 -0
  44. package/dist/electron-build/agents/contacts/human-directory.js.map +1 -0
  45. package/dist/electron-build/agents/contacts/policy.js.map +1 -1
  46. package/dist/electron-build/agents/contacts/tools.js +112 -0
  47. package/dist/electron-build/agents/contacts/tools.js.map +1 -1
  48. package/dist/electron-build/agents/experience-review.js +0 -3
  49. package/dist/electron-build/agents/experience-review.js.map +1 -1
  50. package/dist/electron-build/agents/external-events.js.map +1 -1
  51. package/dist/electron-build/agents/goal-flywheel/goal-change.js +3 -4
  52. package/dist/electron-build/agents/goal-flywheel/goal-change.js.map +1 -1
  53. package/dist/electron-build/agents/goal-flywheel-wiring.js.map +1 -1
  54. package/dist/electron-build/agents/goal-resume.js +0 -4
  55. package/dist/electron-build/agents/goal-resume.js.map +1 -1
  56. package/dist/electron-build/agents/intent-classifier.js +1 -1
  57. package/dist/electron-build/agents/lesson-to-skill.js +0 -1
  58. package/dist/electron-build/agents/lesson-to-skill.js.map +1 -1
  59. package/dist/electron-build/agents/loop-review.js +2 -2
  60. package/dist/electron-build/agents/loop-review.js.map +1 -1
  61. package/dist/electron-build/agents/memory-recall.js.map +1 -1
  62. package/dist/electron-build/agents/memory-store.js +404 -0
  63. package/dist/electron-build/agents/memory-store.js.map +1 -0
  64. package/dist/electron-build/agents/parse-tool-call.js +9 -22
  65. package/dist/electron-build/agents/parse-tool-call.js.map +1 -1
  66. package/dist/electron-build/agents/pi-harness.js +1 -2
  67. package/dist/electron-build/agents/pi-harness.js.map +1 -1
  68. package/dist/electron-build/agents/pi-sdk-tools.js +180 -5
  69. package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -1
  70. package/dist/electron-build/agents/pi-sdk.js +143 -9
  71. package/dist/electron-build/agents/pi-sdk.js.map +1 -1
  72. package/dist/electron-build/agents/pre-tool-validator.js.map +1 -1
  73. package/dist/electron-build/agents/process-runner.js +28 -9
  74. package/dist/electron-build/agents/process-runner.js.map +1 -1
  75. package/dist/electron-build/agents/runner-resolver.js +4 -3
  76. package/dist/electron-build/agents/runner-resolver.js.map +1 -1
  77. package/dist/electron-build/agents/skill-loader.js +22 -16
  78. package/dist/electron-build/agents/skill-loader.js.map +1 -1
  79. package/dist/electron-build/agents/skill-supervisor-link.js.map +1 -1
  80. package/dist/electron-build/agents/skills-manager.js +0 -24
  81. package/dist/electron-build/agents/skills-manager.js.map +1 -1
  82. package/dist/electron-build/agents/task/task-runner.js.map +1 -1
  83. package/dist/electron-build/agents/workflow-engine.js.map +1 -1
  84. package/dist/electron-build/agents/workflow-pivot-loop.js +155 -62
  85. package/dist/electron-build/agents/workflow-pivot-loop.js.map +1 -1
  86. package/dist/electron-build/agents/x402/goal-run-bridge.js.map +1 -1
  87. package/dist/electron-build/bollharness-integration/gate-state-machine.js.map +1 -1
  88. package/dist/electron-build/bootstrap/context-collector.js +2 -4
  89. package/dist/electron-build/bootstrap/context-collector.js.map +1 -1
  90. package/dist/electron-build/bootstrap/context-hierarchy.js +13 -1
  91. package/dist/electron-build/bootstrap/context-hierarchy.js.map +1 -1
  92. package/dist/electron-build/electron-preload.js.map +1 -1
  93. package/dist/electron-build/external-engines/delegate.js.map +1 -1
  94. package/dist/electron-build/kernel/channel-actor.js +31 -2
  95. package/dist/electron-build/kernel/channel-actor.js.map +1 -1
  96. package/dist/electron-build/kernel/model-runtime.js +8 -1
  97. package/dist/electron-build/kernel/model-runtime.js.map +1 -1
  98. package/dist/electron-build/llm/config-store.js +20 -0
  99. package/dist/electron-build/llm/config-store.js.map +1 -1
  100. package/dist/electron-build/llm/embedding-adapter.js +75 -0
  101. package/dist/electron-build/llm/embedding-adapter.js.map +1 -0
  102. package/dist/electron-build/llm/pi-ai.js +96 -35
  103. package/dist/electron-build/llm/pi-ai.js.map +1 -1
  104. package/dist/electron-build/network/agent-network.js.map +1 -1
  105. package/dist/electron-build/orbitdb/memory-sync.js +76 -0
  106. package/dist/electron-build/orbitdb/memory-sync.js.map +1 -0
  107. package/dist/electron-build/pi-ecosystem-judgment/adaptive-scan.js.map +1 -1
  108. package/dist/electron-build/security/tool-gate.js +2 -0
  109. package/dist/electron-build/security/tool-gate.js.map +1 -1
  110. package/dist/electron-build/setup/setup-store.js +34 -6
  111. package/dist/electron-build/setup/setup-store.js.map +1 -1
  112. package/dist/electron-build/social/heartbeat.js +18 -5
  113. package/dist/electron-build/social/heartbeat.js.map +1 -1
  114. package/dist/electron-build/utils/update-manager.js.map +1 -1
  115. package/dist/index.js +250 -12
  116. package/dist/ios/bolloon-web.json +3 -3
  117. package/dist/ios/client.js +150 -113
  118. package/dist/ios/icons/icon-1400x1400.png +0 -0
  119. package/dist/ios/icons/icon-1400x1400.webp +0 -0
  120. package/dist/ios/index.html +106 -107
  121. package/dist/ios/mobile-agent.js +346 -45
  122. package/dist/ios/mobile-core.js +7303 -4590
  123. package/dist/ios/mobile-harness.js +1004 -0
  124. package/dist/ios/mobile-orbitdb.js +194 -0
  125. package/dist/ios/mobile-persona.js +80 -0
  126. package/dist/ios/mobile-privacy.js +2 -3
  127. package/dist/ios/mobile.css +286 -21
  128. package/dist/ios/mobile.html +106 -107
  129. package/dist/ios/mobile.js +300 -132
  130. package/dist/ios/routes-world.js +58 -1
  131. package/dist/ios/server.js +3 -1
  132. package/dist/ios/style.css +49 -2
  133. package/dist/ios/sw.js +1 -1
  134. package/dist/ios/ui/message-renderer.js +4 -18
  135. package/dist/ios/ui/step-timeline.js +14 -1
  136. package/dist/kernel/channel-actor.js +30 -2
  137. package/dist/kernel/gate-scan.js +1 -1
  138. package/dist/kernel/index.js +33 -0
  139. package/dist/kernel/model-runtime.js +8 -1
  140. package/dist/kernel/plan.js +3 -3
  141. package/dist/kernel/roster.js +3 -3
  142. package/dist/llm/config-store.js +20 -0
  143. package/dist/llm/embedding-adapter.js +69 -0
  144. package/dist/llm/pi-ai.js +94 -34
  145. package/dist/orbitdb/memory-sync.js +70 -0
  146. package/dist/pi-ecosystem-judgment/adaptive-scan.js +1 -1
  147. package/dist/security/tool-gate.js +2 -0
  148. package/dist/setup/setup-store.js +34 -6
  149. package/dist/social/heartbeat.js +18 -5
  150. package/dist/web/bolloon-web.json +3 -3
  151. package/dist/web/client.js +150 -113
  152. package/dist/web/icons/icon-1400x1400.png +0 -0
  153. package/dist/web/icons/icon-1400x1400.webp +0 -0
  154. package/dist/web/index.html +52 -59
  155. package/dist/web/mobile-agent.js +351 -45
  156. package/dist/web/mobile-contacts.js +0 -4
  157. package/dist/web/mobile-core.js +7430 -4590
  158. package/dist/web/mobile-harness.js +1004 -0
  159. package/dist/web/mobile-orbitdb.js +194 -0
  160. package/dist/web/mobile-persona.js +80 -0
  161. package/dist/web/mobile-privacy.js +2 -3
  162. package/dist/web/mobile.css +286 -21
  163. package/dist/web/mobile.html +121 -107
  164. package/dist/web/mobile.js +409 -136
  165. package/dist/web/routes-contacts.js +94 -1
  166. package/dist/web/routes-world.js +58 -1
  167. package/dist/web/server.js +4 -2
  168. package/dist/web/style.css +49 -2
  169. package/dist/web/sw.js +1 -1
  170. package/dist/web/ui/message-renderer.js +4 -18
  171. package/dist/web/ui/step-timeline.js +14 -1
  172. package/package.json +3 -2
  173. package/scripts/build-web.ts +16 -1
@@ -0,0 +1,70 @@
1
+ /**
2
+ * memory-sync.ts — 记忆条目级 OrbitDB 复制 (P3, decentralized-memory-design §2.6)
3
+ *
4
+ * 在现有 CID 快照(整快照)之上加「条目级同步」:
5
+ * - 保存: MemoryEntry.id (sha256) 作为经内容寻址的 key
6
+ * - 存储: CIDDatabase type='memory', metadata 带 entryId + entryUpdatedAt
7
+ * - 复制: OrbitDB pubsub 自动 (既有机制)
8
+ * - 冲突: 同 entryId 冲突 → updatedAt 大者胜 (LWW), 平手比 content hash
9
+ *
10
+ * 诚实边界 (写死):
11
+ * - 条目级复制依赖 OrbitDB 网络就绪 (getCIDDatabase 初始化); 网络不可用 /
12
+ * 初始化失败 → 静默跳过 (本地记忆仍是权威, 复制是增强不是阻塞)
13
+ * - 本模块不建新 store, 复用既有 bolloon-cid-store (type='memory')
14
+ * - 跨机器真同步需双节点 (设计文档 §5 已记「跨机读群未验证」, P3 只保证
15
+ * 条目可被 CID 化 + 可恢复; 真双节点验证是 P3b)
16
+ */
17
+ import { getCIDDatabase } from './cid-database.js';
18
+ /** 条目 → CID 记录的 metadata 常量键 */
19
+ const META_ENTRY_ID = 'entryId';
20
+ const META_ENTRY_UPDATED = 'entryUpdatedAt';
21
+ /** 从 CID 记录还原 MemoryEntry (metadata 无 entryId 的旧记录 → null) */
22
+ export function entryFromRecord(rec) {
23
+ if (!rec)
24
+ return null;
25
+ const meta = rec.metadata || {};
26
+ if (!meta[META_ENTRY_ID])
27
+ return null;
28
+ const e = rec.content;
29
+ if (!e || typeof e !== 'object' || !e.id || !e.agentId)
30
+ return null;
31
+ return e;
32
+ }
33
+ /**
34
+ * 同步入口: 把一条 MemoryEntry 写入 OrbitDB (条目级)。
35
+ * 失败静默 (本地记忆不受影响), 返回 CID 或 null。
36
+ */
37
+ export async function syncMemoryEntryToOrbit(entry, db = getCIDDatabase()) {
38
+ try {
39
+ const rec = await db.save({
40
+ agentId: entry.agentId,
41
+ type: 'memory',
42
+ content: entry,
43
+ metadata: {
44
+ [META_ENTRY_ID]: entry.id,
45
+ [META_ENTRY_UPDATED]: entry.updatedAt,
46
+ kind: 'memory-entry',
47
+ },
48
+ });
49
+ return rec.id;
50
+ }
51
+ catch {
52
+ return null; // 网络/初始化失败静默 — 本地记忆仍权威
53
+ }
54
+ }
55
+ /**
56
+ * 拉取远端条目: 列出该 agent 的全部 memory type 记录, 还原成 MemoryEntry。
57
+ * 仅返回「本地没有 或 远端 updatedAt 更新」的条目 (LWW)。
58
+ * 不写本地 — 由调用方决定如何合并。
59
+ */
60
+ export async function fetchRemoteEntries(agentId, db = getCIDDatabase()) {
61
+ try {
62
+ const recs = await db.list({ agentId, type: 'memory' });
63
+ return recs
64
+ .map((r) => entryFromRecord(r))
65
+ .filter((e) => e !== null);
66
+ }
67
+ catch {
68
+ return [];
69
+ }
70
+ }
@@ -18,7 +18,7 @@
18
18
  import * as fs from 'fs/promises';
19
19
  import * as os from 'os';
20
20
  import * as path from 'path';
21
- import { loadAllJudgments } from './human-value-store.js';
21
+ import { loadAllJudgments, } from './human-value-store.js';
22
22
  // 用 getter 函数而非模块顶层 const: process.env.HOME 在测试 beforeAll 才设,
23
23
  // 模块顶层求值时还是真 home. 运行时求值才能正确响应测试 fixture.
24
24
  // 跨平台: 优先 process.env.HOME (测试可控), 然后 os.homedir() (Windows 上读 USERPROFILE).
@@ -70,6 +70,8 @@ const TOOL_WHITELIST = new Set([
70
70
  'ui_save_component', 'ui_load_component',
71
71
  // 2026-08-12: Kanban 看板工具 (Hermes kanban_db → OrbitDB, src/orbitdb/kanban-store.ts)
72
72
  'kanban_create', 'kanban_list', 'kanban_get', 'kanban_claim', 'kanban_complete', 'kanban_status',
73
+ // 2026-10-14: 结构化记忆工具 (src/agents/memory-store.ts, P0)
74
+ 'memory_save', 'memory_recall',
73
75
  // 2026-08-07: Bolloon 自身配置读写 (bolloon-config.json, agent 有修改自身配置权限)
74
76
  'bolloon_config_get', 'bolloon_config_set',
75
77
  // 2026-09-13: 下一代工具集 (人机问答 / 精确补丁 / 代码执行 / 桌面操作 / 技能分享 / 浏览器)
@@ -257,18 +257,36 @@ export async function evaluateSetup(opts = {}) {
257
257
  checks.credentialPresent = hasKey;
258
258
  checks.providerUsable = providerSelected && credentialOk;
259
259
  checks.modelPresent = modelOk;
260
- // 3) 连通性 (24h 有效期)
260
+ // 3) 连通性 (2026-10-13 重构: 结论有效期 = 「测过 + 配置没变」, 不再只看墙钟 24h)
261
+ // - 旧逻辑: 24h 墙钟一到就过期, 即使 provider/key/baseUrl/model 一个没动 → 用户隔天启动必见
262
+ // 「未就绪」, 被迫重测 (体验债: 配置没变重测无意义, 且评估会把 connectivityOk 覆盖成 false 落盘,
263
+ // 于是「测过」这个事实被销毁, 更修不回来)。
264
+ // - 新语义: connectivityAt 存在(测过) 且 配置指纹一致(配置没变) ⇒ 结论仍有效; 只有配置真变了才重测。
261
265
  const connAt = checks.connectivityAt ? Date.parse(checks.connectivityAt) : 0;
262
- const connFresh = !!connAt && now - connAt < ttl;
266
+ const hadConnTest = !!connAt;
267
+ // 配置指纹: 当前配置 vs 上次通过时的配置 —— 相同则连通性结论仍有效 (provider/key/baseUrl/model 都没变)
268
+ let configUnchanged = false;
269
+ try {
270
+ const { hash: curHash } = await hashConfigFiles(bolloonHome);
271
+ configUnchanged = !!prev.configHash && prev.configHash === curHash;
272
+ }
273
+ catch {
274
+ configUnchanged = false;
275
+ }
263
276
  let connectivityOk = false;
264
- if (checks.connectivityOk && connFresh)
277
+ if (hadConnTest && configUnchanged) {
278
+ // 测过 + 配置没变 ⇒ 结论有效 (即使墙钟过了 24h)
265
279
  connectivityOk = true;
266
- else if (checks.connectivityOk && !connFresh) {
267
- reasons.push('连通性结果已过期 (>24h) → 需要重新测试');
280
+ checks.connectivityOk = true; // 救回被旧逻辑覆盖的 false
281
+ }
282
+ else if (hadConnTest && !configUnchanged) {
283
+ // 测过但配置变了 (或 configHash 缺失) ⇒ 需要重测
284
+ connectivityOk = false;
268
285
  checks.connectivityOk = false;
286
+ reasons.push('LLM 配置已变化 → 需要重新测试连通性');
269
287
  }
270
288
  if (!connectivityOk)
271
- why.basic.push(connAt && !connFresh ? '连通性结果过期 (需重测)' : '还没做过连通性测试');
289
+ why.basic.push(hadConnTest && !configUnchanged ? '配置变化, 连通性需重测' : '还没做过连通性测试');
272
290
  // 4) 运行时 (真实: initMinimax + session; 不是"singleton 存在")
273
291
  let runtimeOk = checks.runtimeInitialized === true;
274
292
  if (!opts.light) {
@@ -545,6 +563,16 @@ export async function recordSetupStage(stage, patch = {}, bolloonHome = resolveB
545
563
  lastError: undefined,
546
564
  updatedAt: new Date().toISOString(),
547
565
  };
566
+ // 2026-10-13 重构: 补算并落盘配置指纹 —— 与 evaluateSetup (413-414) 同一逻辑。
567
+ // 之前只有 evaluateSetup 落 configHash; 直写路径 (onboard 连通性成功 / 测试模拟) 缺 hash ⇒
568
+ // 连通性判定 (「测过且配置没变 → 结论有效」) 在非 evaluateSetup 路径下永远 configUnchanged=false。
569
+ // 行为不变 (configHash 仍是同一文件的 sha256), 只是所有写 state 的路径都带上指纹。
570
+ try {
571
+ const fp = await hashConfigFiles(bolloonHome);
572
+ state.configHash = fp.hash;
573
+ state.configVersion = fp.version;
574
+ }
575
+ catch { /* hash 计算失败不阻塞记录 */ }
548
576
  await writeSetupState(state, bolloonHome);
549
577
  return state;
550
578
  }
@@ -260,6 +260,9 @@ export class SocialHeartbeat {
260
260
  currentPeerDids = new Set();
261
261
  greetingMessage;
262
262
  ownIpfsCid;
263
+ // 2026-10-12: IPFS/IPNS 发布失败只提示一次 (本地没跑节点时每次心跳刷 warn)
264
+ _ipfsPublishWarned = false;
265
+ _ipnsPublishWarned = false;
263
266
  // 蚁群组件
264
267
  pheromoneEngine = null;
265
268
  adaptiveHeartbeat = null;
@@ -393,7 +396,7 @@ export class SocialHeartbeat {
393
396
  return;
394
397
  try {
395
398
  const { IpfsClient } = await import('@diap/sdk');
396
- const ipfs = new IpfsClient('http://127.0.0.1:5001', null);
399
+ const ipfs = new IpfsClient('http://127.0.0.1:5001', 'http://127.0.0.1:8080');
397
400
  console.log(`[Heartbeat] 从 IPNS 加载 persona: ${this.config.ownIpnsName}`);
398
401
  const cid = await ipfs.resolveIpns(this.config.ownIpnsName);
399
402
  if (cid) {
@@ -524,7 +527,7 @@ export class SocialHeartbeat {
524
527
  return;
525
528
  try {
526
529
  const { IpfsClient } = await import('@diap/sdk');
527
- const ipfs = new IpfsClient('http://127.0.0.1:5001', null);
530
+ const ipfs = new IpfsClient('http://127.0.0.1:5001', 'http://127.0.0.1:8080');
528
531
  const doc = {
529
532
  name: persona.name,
530
533
  description: persona.description,
@@ -541,6 +544,9 @@ export class SocialHeartbeat {
541
544
  const content = JSON.stringify(doc);
542
545
  const result = await ipfs.upload(content);
543
546
  const cid = typeof result === 'string' ? result : result?.cid;
547
+ // 2026-10-12 (leo: 「IPFS 发布失败刷屏 27 行」): 本地没跑 IPFS 节点时每次心跳都 warn。
548
+ // 成功一次就重置提示标志 —— 节点恢复后重新可提示。
549
+ this._ipfsPublishWarned = false;
544
550
  if (cid && cid !== this.ownIpfsCid) {
545
551
  this.ownIpfsCid = cid;
546
552
  console.log(`[Heartbeat] Persona 发布到 IPFS: ${cid}`);
@@ -550,13 +556,20 @@ export class SocialHeartbeat {
550
556
  console.log(`[Heartbeat] Persona 发布到 IPNS: ${this.config.ownIpnsName}`);
551
557
  }
552
558
  catch (err) {
553
- console.warn(`[Heartbeat] IPNS 发布失败:`, err);
559
+ if (!this._ipnsPublishWarned) {
560
+ this._ipnsPublishWarned = true;
561
+ console.warn('[Heartbeat] IPNS 发布失败:', err);
562
+ }
554
563
  }
555
564
  }
556
565
  }
557
566
  }
558
567
  catch (err) {
559
- console.warn('[Heartbeat] IPFS 发布失败:', err);
568
+ // 只提示第一次 (配置缺失 / 节点未跑是常态, 不该每个心跳刷一条)
569
+ if (!this._ipfsPublishWarned) {
570
+ this._ipfsPublishWarned = true;
571
+ console.warn('[Heartbeat] IPFS 发布失败:', err);
572
+ }
560
573
  }
561
574
  }
562
575
  async discoverPeers() {
@@ -652,7 +665,7 @@ export class SocialHeartbeat {
652
665
  return;
653
666
  try {
654
667
  const { IpfsClient } = await import('@diap/sdk');
655
- const ipfs = new IpfsClient('http://127.0.0.1:5001', null);
668
+ const ipfs = new IpfsClient('http://127.0.0.1:5001', 'http://127.0.0.1:8080');
656
669
  const cid = await ipfs.resolveIpns(agent.ipnsName);
657
670
  if (cid) {
658
671
  agent.cid = cid;
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "schema": "bolloon-mobile-web/1",
3
- "version": "0.6.4",
3
+ "version": "0.6.6",
4
4
  "channel": "stable",
5
5
  "build": "stable",
6
- "commit": "0dfa01104a71ed0351be8402a6b85efaf909df19",
7
- "builtAt": "2026-10-05T10:49:06.717Z",
6
+ "commit": "f2668fa9e6cc17c9868356b581a15d8cef867a3b",
7
+ "builtAt": "2026-10-15T10:28:08.907Z",
8
8
  "layer": "web",
9
9
  "note": "web 资源层构建戳 (手机端 OTA 的身份第 ③ 级回退; 装机后以 OTA state.json 为准)"
10
10
  }