@bolloon/bolloon-agent 0.1.0 → 0.1.2

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 (581) hide show
  1. package/bin/bolloon-cli.cjs +157 -0
  2. package/bin/bolloon-daemon.sh +207 -0
  3. package/bin/bolloon.cmd +11 -0
  4. package/dist/agents/constraint-layer.js +10 -15
  5. package/dist/agents/pi-sdk.js +433 -106
  6. package/dist/agents/protocol.js +82 -1
  7. package/dist/agents/subagent-manager.js +2 -2
  8. package/dist/agents/workflow-engine.js +15 -20
  9. package/dist/agents/workflow-pivot-loop.js +541 -0
  10. package/dist/bollharness/src/index.js +5 -0
  11. package/dist/bollharness/src/scripts/checks/check_adr_plan_numbering.js +6 -0
  12. package/dist/bollharness/src/scripts/checks/check_api_types.js +45 -0
  13. package/dist/bollharness/src/scripts/checks/check_artifact_link.js +146 -0
  14. package/dist/bollharness/src/scripts/checks/check_bridge_deps.js +6 -0
  15. package/dist/bollharness/src/scripts/checks/check_bugfix_binding.js +6 -0
  16. package/dist/bollharness/src/scripts/checks/check_bugfix_binding_ci.js +6 -0
  17. package/dist/bollharness/src/scripts/checks/check_doc_file_references.js +6 -0
  18. package/dist/bollharness/src/scripts/checks/check_doc_freshness.js +135 -0
  19. package/dist/bollharness/src/scripts/checks/check_doc_links.js +31 -0
  20. package/dist/bollharness/src/scripts/checks/check_file_existence_claims.js +6 -0
  21. package/dist/bollharness/src/scripts/checks/check_fragment_integrity.js +34 -0
  22. package/dist/bollharness/src/scripts/checks/check_hook_installed.js +63 -0
  23. package/dist/bollharness/src/scripts/checks/check_issue_closure.js +41 -0
  24. package/dist/bollharness/src/scripts/checks/check_mcp_parity.js +6 -0
  25. package/dist/bollharness/src/scripts/checks/check_security.js +48 -0
  26. package/dist/bollharness/src/scripts/checks/check_skill_parity.js +6 -0
  27. package/dist/bollharness/src/scripts/checks/check_versions.js +6 -0
  28. package/dist/bollharness/src/scripts/checks/finding.js +13 -0
  29. package/dist/bollharness/src/scripts/checks/next_decision_number.js +20 -0
  30. package/dist/bollharness/src/scripts/checks/regenerate_magic_docs.js +6 -0
  31. package/dist/bollharness/src/scripts/ci/detect_rebaseline_triggers.js +8 -0
  32. package/dist/bollharness/src/scripts/ci/scan_subprocess_cfg.js +8 -0
  33. package/dist/bollharness/src/scripts/ci/scan_verify_artifacts.js +8 -0
  34. package/dist/bollharness/src/scripts/ci/scan_yaml_schema.js +8 -0
  35. package/dist/bollharness/src/scripts/context_router.js +67 -0
  36. package/dist/bollharness/src/scripts/deploy-guard.js +157 -0
  37. package/dist/bollharness/src/scripts/guard-feedback.js +192 -0
  38. package/dist/bollharness/src/scripts/guard_router.js +158 -0
  39. package/dist/bollharness/src/scripts/hooks/_hook_output.js +6 -0
  40. package/dist/bollharness/src/scripts/hooks/auto-python3.js +6 -0
  41. package/dist/bollharness/src/scripts/hooks/deploy-progress-on-session-end.js +6 -0
  42. package/dist/bollharness/src/scripts/hooks/failure-analyzer.js +6 -0
  43. package/dist/bollharness/src/scripts/hooks/gate-judgment-inject.js +92 -0
  44. package/dist/bollharness/src/scripts/hooks/gate-transition-judgment.js +63 -0
  45. package/dist/bollharness/src/scripts/hooks/inbox-ack.js +6 -0
  46. package/dist/bollharness/src/scripts/hooks/inbox-inject-on-start.js +6 -0
  47. package/dist/bollharness/src/scripts/hooks/inbox-validate.js +6 -0
  48. package/dist/bollharness/src/scripts/hooks/inbox-write-ledger.js +6 -0
  49. package/dist/bollharness/src/scripts/hooks/initializer-agent.js +6 -0
  50. package/dist/bollharness/src/scripts/hooks/loop-detection.js +73 -0
  51. package/dist/bollharness/src/scripts/hooks/owner-guard.js +6 -0
  52. package/dist/bollharness/src/scripts/hooks/precompact.js +6 -0
  53. package/dist/bollharness/src/scripts/hooks/review-agent-gatekeeper.js +6 -0
  54. package/dist/bollharness/src/scripts/hooks/risk-tracker.js +108 -0
  55. package/dist/bollharness/src/scripts/hooks/sanitize-on-read.js +6 -0
  56. package/dist/bollharness/src/scripts/hooks/session-reflection.js +7 -0
  57. package/dist/bollharness/src/scripts/hooks/session-start-magic-docs.js +7 -0
  58. package/dist/bollharness/src/scripts/hooks/session-start-reset-risk.js +7 -0
  59. package/dist/bollharness/src/scripts/hooks/session-start-toolkit-reminder.js +7 -0
  60. package/dist/bollharness/src/scripts/hooks/stop-evaluator.js +157 -0
  61. package/dist/bollharness/src/scripts/hooks/tool-call-counter.js +6 -0
  62. package/dist/bollharness/src/scripts/hooks/trace-analyzer.js +10 -0
  63. package/dist/bollharness/src/scripts/install/install-trust-token.js +7 -0
  64. package/dist/bollharness/src/scripts/install/multi_project_registry.js +9 -0
  65. package/dist/bollharness/src/scripts/install/phase2_auto.js +21 -0
  66. package/dist/bollharness/src/scripts/install/pre_commit_installer.js +6 -0
  67. package/dist/bollharness/src/scripts/install/tier_selector.js +7 -0
  68. package/dist/bollharness/src/scripts/install/transcript_miner.js +7 -0
  69. package/dist/bollharness/src/scripts/lib/claim_patterns.js +10 -0
  70. package/dist/bollharness/src/scripts/lib/sanitize_patterns.js +12 -0
  71. package/dist/bollharness/src/scripts/sanitize.js +6 -0
  72. package/dist/bollharness-integration/channel-judgment-engine.js +530 -0
  73. package/dist/bollharness-integration/context-chain-router.js +383 -0
  74. package/dist/bollharness-integration/context-router-judgment.js +13 -21
  75. package/dist/bollharness-integration/context-router.js +22 -64
  76. package/dist/bollharness-integration/gate-state-machine.js +14 -19
  77. package/dist/bollharness-integration/gate-transition-hooks.js +16 -61
  78. package/dist/bollharness-integration/guard-checker.js +21 -68
  79. package/dist/bollharness-integration/index.js +14 -124
  80. package/dist/bollharness-integration/integration.js +13 -20
  81. package/dist/bollharness-integration/llm-judgment-engine.js +569 -0
  82. package/dist/bollharness-integration/skill-adapter.js +18 -64
  83. package/dist/cli-entry.js +261 -0
  84. package/dist/constraint-runtime/src/commands.js +17 -7
  85. package/dist/constraint-runtime/src/constraint/budget.js +1 -6
  86. package/dist/constraint-runtime/src/constraint/permission.js +1 -6
  87. package/dist/constraint-runtime/src/models.js +1 -3
  88. package/dist/constraint-runtime/src/tools.js +17 -7
  89. package/dist/constraints/index.js +1 -7
  90. package/dist/documents/reader.js +8 -49
  91. package/dist/heartbeat/DaemonManager.js +242 -0
  92. package/dist/heartbeat/HealthMonitor.js +285 -0
  93. package/dist/heartbeat/StartupVerifier.js +205 -0
  94. package/dist/heartbeat/Watchdog.js +168 -0
  95. package/dist/heartbeat/index.js +84 -0
  96. package/dist/heartbeat/types.js +5 -0
  97. package/dist/index.js +381 -28
  98. package/dist/llm/config-store.js +31 -57
  99. package/dist/llm/llm-judgment-client.js +389 -0
  100. package/dist/llm/pi-ai.js +9 -52
  101. package/dist/network/agent-network.js +46 -90
  102. package/dist/network/hybrid-messenger.js +125 -0
  103. package/dist/network/iroh-bootstrap.js +38 -0
  104. package/dist/network/iroh-discovery.js +145 -0
  105. package/dist/network/iroh-integration.js +9 -16
  106. package/dist/network/iroh-transport.js +10 -48
  107. package/dist/network/p2p.js +23 -62
  108. package/dist/network/storage/adapters/json-adapter.js +4 -42
  109. package/dist/network/storage/index.js +147 -0
  110. package/dist/network/storage/types.js +14 -0
  111. package/dist/pi-ecosystem/index.js +233 -0
  112. package/dist/pi-ecosystem-colony/index.js +29 -90
  113. package/dist/pi-ecosystem-goals/index.js +20 -74
  114. package/dist/pi-ecosystem-judgment/decision.js +29 -47
  115. package/dist/pi-ecosystem-judgment/distillation.js +16 -29
  116. package/dist/pi-ecosystem-judgment/human-value-store.js +13 -60
  117. package/dist/pi-ecosystem-judgment/index.js +21 -74
  118. package/dist/pi-ecosystem-judgment/value-injection.js +26 -72
  119. package/dist/pi-ecosystem-mcp/index.js +24 -78
  120. package/dist/pi-ecosystem-subagents/index.js +20 -69
  121. package/dist/social/ant-colony/AdaptiveHeartbeat.js +3 -8
  122. package/dist/social/ant-colony/PheromoneEngine.js +11 -49
  123. package/dist/social/ant-colony/index.js +6 -0
  124. package/dist/social/ant-colony/types.js +4 -8
  125. package/dist/social/channels/ChannelManager.js +8 -46
  126. package/dist/social/channels/DiapChannelBridge.js +9 -47
  127. package/dist/social/channels/InterestMatcher.js +2 -7
  128. package/dist/social/channels/channel-agent-session.js +309 -0
  129. package/dist/social/channels/channel-heartbeat-agent.js +494 -0
  130. package/dist/social/channels/diap-doc-parser.js +204 -0
  131. package/dist/social/channels/harness-workflow-integrator.js +446 -0
  132. package/dist/social/channels/index.js +9 -0
  133. package/dist/social/channels/types.js +3 -7
  134. package/dist/social/global-shared-context.js +6 -47
  135. package/dist/social/heartbeat.js +29 -72
  136. package/dist/social/persona/enhanced-persona.js +299 -0
  137. package/dist/web/client.js +302 -136
  138. package/dist/web/components/p2p/index.js +159 -9
  139. package/dist/web/components/p2p/p2p-connection.js +136 -0
  140. package/dist/web/components/p2p/p2p-manager.js +24 -0
  141. package/dist/web/components/p2p/p2p-store-memory.js +1 -1
  142. package/dist/web/components/p2p/types.js +7 -0
  143. package/dist/web/index.html +5 -0
  144. package/dist/web/style.css +118 -0
  145. package/package.json +12 -6
  146. package/scripts/build-cli.js +206 -0
  147. package/scripts/postinstall.js +153 -0
  148. package/src/agents/pi-sdk.ts +347 -28
  149. package/src/agents/protocol.ts +95 -1
  150. package/src/agents/workflow-pivot-loop.ts +674 -0
  151. package/src/bollharness/scripts/context-fragments/pi-agent-operations.md +34 -0
  152. package/src/cli-entry.ts +304 -0
  153. package/src/heartbeat/DaemonManager.ts +283 -0
  154. package/src/heartbeat/HealthMonitor.ts +316 -0
  155. package/src/heartbeat/StartupVerifier.ts +223 -0
  156. package/src/heartbeat/Watchdog.ts +198 -0
  157. package/src/heartbeat/index.ts +108 -0
  158. package/src/heartbeat/types.ts +82 -0
  159. package/src/llm/config-store.ts +23 -5
  160. package/src/network/iroh-transport.ts +3 -3
  161. package/src/web/client.js +302 -136
  162. package/src/web/components/p2p/P2PModal.tsx +91 -3
  163. package/src/web/components/p2p/index.ts +171 -9
  164. package/src/web/components/p2p/p2p-connection.ts +153 -1
  165. package/src/web/components/p2p/p2p-manager.ts +39 -1
  166. package/src/web/components/p2p/p2p-store-memory.ts +1 -1
  167. package/src/web/components/p2p/p2p-tools.ts +315 -0
  168. package/src/web/components/p2p/types.ts +58 -0
  169. package/src/web/index.html +5 -0
  170. package/src/web/server.ts +353 -36
  171. package/src/web/style.css +118 -0
  172. package/tsconfig.cli.json +16 -0
  173. package/tsconfig.electron.json +1 -1
  174. package/tsconfig.json +1 -2
  175. package/dist/constraint-runtime/tests/agent.test.js +0 -16
  176. package/dist/constraint-runtime/tests/constraint.test.js +0 -41
  177. package/dist/constraint-runtime/tests/skill.test.js +0 -19
  178. package/dist/constraint-runtime/tests/thinking.test.js +0 -22
  179. package/dist/electron-preload.js +0 -15
  180. package/dist/electron-preload.js.map +0 -1
  181. package/dist/electron.js +0 -206
  182. package/dist/electron.js.map +0 -1
  183. package/dist/test/constraint-layer.test.js +0 -164
  184. package/dist/test/global-shared-context.test.js +0 -315
  185. package/dist/test/pi-sdk.test.js +0 -47
  186. package/dist/test/set-persona.test.js +0 -38
  187. package/dist/test/subagent-manager.test.js +0 -276
  188. package/dist/test/workflow-engine.test.js +0 -87
  189. package/dist/web/server.js +0 -1647
  190. package/dist/web/server.js.map +0 -1
  191. package/dist/workflows/collaboration.js +0 -374
  192. package/dist/workflows/index.js +0 -54
  193. package/docs/agent-communication.md +0 -333
  194. package/docs/plans/2026-05-15-document-agent-design.md +0 -479
  195. package/docs/plans/2026-05-15-document-agent-implementation-plan.md +0 -792
  196. package/docs/plans/2026-05-16-chat-ui-design.md +0 -86
  197. package/docs/plans/2026-05-16-constraint-runtime-design.md +0 -106
  198. package/docs/plans/2026-05-16-constraint-runtime-implementation.md +0 -441
  199. package/docs//346/225/260/345/255/246/350/276/205/345/212/251/346/231/272/350/203/275/344/275/223-/346/240/270/345/277/203/346/225/210/346/236/234/345/256/232/344/271/211.md +0 -287
  200. package/src/bollharness/.boll/CLAUDE.md.template +0 -34
  201. package/src/bollharness/.boll/MANIFEST.yaml +0 -213
  202. package/src/bollharness/.boll/active-review-agents/.gitkeep +0 -0
  203. package/src/bollharness/.boll/agents/review-base.yaml +0 -108
  204. package/src/bollharness/.boll/deploy-allowlist.yaml +0 -38
  205. package/src/bollharness/.boll/inbox/schema/message-v1.json +0 -99
  206. package/src/bollharness/.boll/install-staging/.gitkeep +0 -0
  207. package/src/bollharness/.boll/issue-adapter.yaml +0 -31
  208. package/src/bollharness/.boll/plugins/boll-mode-toolkit/contracts/mode-contract.md +0 -85
  209. package/src/bollharness/.boll/plugins/boll-review-toolkit/contracts/evidence-packet-schema.json +0 -102
  210. package/src/bollharness/.boll/plugins/boll-review-toolkit/contracts/review-contract.yaml +0 -247
  211. package/src/bollharness/.boll/rules/backend-routes.md +0 -31
  212. package/src/bollharness/.boll/rules/closure-semantics.md +0 -30
  213. package/src/bollharness/.boll/rules/env-vars.md +0 -32
  214. package/src/bollharness/.boll/rules/hanis-protocol.md +0 -145
  215. package/src/bollharness/.boll/rules/repo-structure.md +0 -42
  216. package/src/bollharness/.boll/rules/review-agent-isolation.md +0 -73
  217. package/src/bollharness/.boll/rules/source-of-truth.md +0 -33
  218. package/src/bollharness/.boll/settings.json +0 -180
  219. package/src/bollharness/.boll/settings.json.template +0 -31
  220. package/src/bollharness/.boll/skills/arch/SKILL.md +0 -372
  221. package/src/bollharness/.boll/skills/bug-pipeline/SKILL.md +0 -168
  222. package/src/bollharness/.boll/skills/bug-triage/SKILL.md +0 -161
  223. package/src/bollharness/.boll/skills/context-chains/SKILL.md +0 -250
  224. package/src/bollharness/.boll/skills/context-chains/context-chain-index.md +0 -48
  225. package/src/bollharness/.boll/skills/context-chains/work-type-extractors/code_change_extractor.ts +0 -142
  226. package/src/bollharness/.boll/skills/context-chains/work-type-extractors/debugging_extractor.ts +0 -126
  227. package/src/bollharness/.boll/skills/context-chains/work-type-extractors/design_extractor.ts +0 -148
  228. package/src/bollharness/.boll/skills/context-chains/work-type-extractors/planning_extractor.ts +0 -162
  229. package/src/bollharness/.boll/skills/context-chains/work-type-extractors/question_extractor.ts +0 -116
  230. package/src/bollharness/.boll/skills/context-chains/work-type-extractors/review_extractor.ts +0 -136
  231. package/src/bollharness/.boll/skills/crystal-learn/SKILL.md +0 -93
  232. package/src/bollharness/.boll/skills/crystal-learn/invariants/INV-0.md +0 -34
  233. package/src/bollharness/.boll/skills/crystal-learn/invariants/INV-1.md +0 -34
  234. package/src/bollharness/.boll/skills/crystal-learn/invariants/INV-2.md +0 -35
  235. package/src/bollharness/.boll/skills/crystal-learn/invariants/INV-3.md +0 -34
  236. package/src/bollharness/.boll/skills/crystal-learn/invariants/INV-4.md +0 -43
  237. package/src/bollharness/.boll/skills/crystal-learn/invariants/INV-5.md +0 -34
  238. package/src/bollharness/.boll/skills/crystal-learn/invariants/INV-6.md +0 -37
  239. package/src/bollharness/.boll/skills/crystal-learn/invariants/INV-7.md +0 -46
  240. package/src/bollharness/.boll/skills/guardian-fixer/PROMPT.md +0 -415
  241. package/src/bollharness/.boll/skills/guardian-fixer/SKILL.md +0 -320
  242. package/src/bollharness/.boll/skills/harness-dev/SKILL.md +0 -93
  243. package/src/bollharness/.boll/skills/harness-dev/examples/README.md +0 -227
  244. package/src/bollharness/.boll/skills/harness-dev-handoff/SKILL.md +0 -165
  245. package/src/bollharness/.boll/skills/harness-eng/SKILL.md +0 -110
  246. package/src/bollharness/.boll/skills/harness-eng-test/SKILL.md +0 -79
  247. package/src/bollharness/.boll/skills/harness-lab/SKILL.md +0 -170
  248. package/src/bollharness/.boll/skills/harness-ops/SKILL.md +0 -57
  249. package/src/bollharness/.boll/skills/harness-voice/SKILL.md +0 -183
  250. package/src/bollharness/.boll/skills/judgment/SKILL.md +0 -115
  251. package/src/bollharness/.boll/skills/lead/SKILL.md +0 -245
  252. package/src/bollharness/.boll/skills/lead/install-wow-harness.md +0 -77
  253. package/src/bollharness/.boll/skills/lead/ref-review-sop.md +0 -91
  254. package/src/bollharness/.boll/skills/lead/ref-stages.md +0 -129
  255. package/src/bollharness/.boll/skills/skill-discovery/SKILL.md +0 -169
  256. package/src/bollharness/.boll/skills/task-arch/SKILL.md +0 -106
  257. package/src/bollharness/.boll/skills/toolkit/SKILL.md +0 -57
  258. package/src/bollharness/.boll/tasks/.gitkeep +0 -0
  259. package/src/bollharness/.boll/toolkit-index.yaml +0 -112
  260. package/src/bollharness/.claude/agents/review-base.yaml +0 -108
  261. package/src/bollharness/.claude/plugins/boll-mode-toolkit/.claude-plugin/plugin.json +0 -44
  262. package/src/bollharness/.claude/plugins/boll-review-toolkit/.claude-plugin/plugin.json +0 -24
  263. package/src/bollharness/.claude/plugins/boll-review-toolkit/contracts/evidence-packet-schema.json +0 -102
  264. package/src/bollharness/.claude/plugins/boll-review-toolkit/contracts/review-contract.yaml +0 -247
  265. package/src/bollharness/.claude/settings.json +0 -157
  266. package/src/bollharness/.claude/skills/arch/SKILL.md +0 -64
  267. package/src/bollharness/.claude/skills/crystal-learn/SKILL.md +0 -93
  268. package/src/bollharness/.claude/skills/guardian-fixer/PROMPT.md +0 -44
  269. package/src/bollharness/.claude/skills/guardian-fixer/SKILL.md +0 -324
  270. package/src/bollharness/.claude/skills/harness-dev/SKILL.md +0 -93
  271. package/src/bollharness/.claude/skills/harness-dev/examples/README.md +0 -17
  272. package/src/bollharness/.claude/skills/harness-dev-handoff/SKILL.md +0 -165
  273. package/src/bollharness/.claude/skills/harness-eng/SKILL.md +0 -183
  274. package/src/bollharness/.claude/skills/harness-eng-test/SKILL.md +0 -57
  275. package/src/bollharness/.claude/skills/harness-ops/SKILL.md +0 -57
  276. package/src/bollharness/.claude/skills/harness-voice/SKILL.md +0 -84
  277. package/src/bollharness/.claude/skills/lead/INDEX.md +0 -28
  278. package/src/bollharness/.claude/skills/lead/SKILL.md +0 -24
  279. package/src/bollharness/.claude/skills/lead/install-wow-harness.md +0 -77
  280. package/src/bollharness/.claude/skills/lead/ref-review-sop.md +0 -48
  281. package/src/bollharness/.claude/skills/lead/ref-stages.md +0 -58
  282. package/src/bollharness/.claude/skills/plan-lock/SKILL.md +0 -74
  283. package/src/bollharness/.claude/skills/skill-discovery/SKILL.md +0 -120
  284. package/src/bollharness/.claude/skills/task-arch/SKILL.md +0 -106
  285. package/src/bollharness/.claude/skills/toolkit/SKILL.md +0 -57
  286. package/src/bollharness/.claude/skills/toolkit/list.sh +0 -92
  287. package/src/bollharness/.githooks/pre-commit +0 -21
  288. package/src/bollharness/.github/workflows/ci.yml +0 -88
  289. package/src/bollharness/docs/decisions/ADR-030-guard-signal-protocol-and-governance-reload.md +0 -1076
  290. package/src/bollharness/docs/decisions/ADR-038-harness-optimization-strategy.md +0 -2039
  291. package/src/bollharness/docs/decisions/ADR-041-codex-claude-code-division-of-labor.md +0 -128
  292. package/src/bollharness/docs/decisions/ADR-H1-crystal-learn-revival.md +0 -188
  293. package/src/bollharness/docs/decisions/ADR-H2-identity-isolation.md +0 -183
  294. package/src/bollharness/docs/decisions/ADR-H3-memory-scope.md +0 -133
  295. package/src/bollharness/docs/decisions/ADR-H4-prompt-governance.md +0 -146
  296. package/src/bollharness/docs/decisions/ADR-H5-gate-quantization.md +0 -212
  297. package/src/bollharness/docs/decisions/ADR-H6-state-file-health.md +0 -211
  298. package/src/bollharness/docs/decisions/ADR-H8-issue-and-doc-compliance.md +0 -202
  299. package/src/bollharness/docs/decisions/ADR-H9-mailbox.md +0 -231
  300. package/src/bollharness/docs/decisions/PLAN-H1-crystal-learn-revival.md +0 -270
  301. package/src/bollharness/docs/decisions/PLAN-H2-identity-isolation.md +0 -291
  302. package/src/bollharness/docs/decisions/PLAN-H3-memory-scope.md +0 -228
  303. package/src/bollharness/docs/decisions/PLAN-H4-prompt-governance.md +0 -227
  304. package/src/bollharness/docs/decisions/PLAN-H5-gate-quantization.md +0 -239
  305. package/src/bollharness/docs/decisions/PLAN-H6-state-file-health.md +0 -325
  306. package/src/bollharness/docs/decisions/PLAN-H8-issue-and-doc-compliance.md +0 -242
  307. package/src/bollharness/docs/decisions/PLAN-H9-mailbox.md +0 -378
  308. package/src/bollharness/docs/launch-article-en.md +0 -276
  309. package/src/bollharness/docs/launch-article-zh.md +0 -305
  310. package/src/bollharness/docs/practice.html +0 -356
  311. package/src/bollharness/docs/practice.md +0 -82
  312. package/src/bollharness/docs/research/round-1/README.md +0 -11
  313. package/src/bollharness/docs/research/round-2/README.md +0 -11
  314. package/src/bollharness/docs/research/round-3/README.md +0 -11
  315. package/src/bollharness/docs/research/round-4/README.md +0 -11
  316. package/src/bollharness/docs/research/round-5/README.md +0 -11
  317. package/src/bollharness/docs/research/round-6/README.md +0 -11
  318. package/src/bollharness/package-lock.json +0 -48
  319. package/src/bollharness/reference/boll-reference/.claude/rules/backend-routes.md +0 -268
  320. package/src/bollharness/reference/boll-reference/.claude/rules/bridge.md +0 -20
  321. package/src/bollharness/reference/boll-reference/.claude/rules/closure-semantics.md +0 -30
  322. package/src/bollharness/reference/boll-reference/.claude/rules/coaching.md +0 -13
  323. package/src/bollharness/reference/boll-reference/.claude/rules/env-vars.md +0 -50
  324. package/src/bollharness/reference/boll-reference/.claude/rules/hackathon.md +0 -12
  325. package/src/bollharness/reference/boll-reference/.claude/rules/repo-structure.md +0 -184
  326. package/src/bollharness/reference/boll-reference/.claude/rules/review-agent-isolation.md +0 -112
  327. package/src/bollharness/reference/boll-reference/.claude/rules/scenes.md +0 -12
  328. package/src/bollharness/reference/boll-reference/.claude/skills/arch/SKILL.md +0 -551
  329. package/src/bollharness/reference/boll-reference/.claude/skills/boll-animation/SKILL.md +0 -26
  330. package/src/bollharness/reference/boll-reference/.claude/skills/boll-bridge/SKILL.md +0 -227
  331. package/src/bollharness/reference/boll-reference/.claude/skills/boll-bridge/agents/openai.yaml +0 -4
  332. package/src/bollharness/reference/boll-reference/.claude/skills/boll-bridge/references/bridge-failure-taxonomy.md +0 -142
  333. package/src/bollharness/reference/boll-reference/.claude/skills/boll-bridge/references/bridge-validation-ladder.md +0 -107
  334. package/src/bollharness/reference/boll-reference/.claude/skills/boll-crystal/SKILL.md +0 -893
  335. package/src/bollharness/reference/boll-reference/.claude/skills/boll-crystal-learn/SKILL.md +0 -89
  336. package/src/bollharness/reference/boll-reference/.claude/skills/boll-dev/SKILL.md +0 -93
  337. package/src/bollharness/reference/boll-reference/.claude/skills/boll-dev/examples/README.md +0 -209
  338. package/src/bollharness/reference/boll-reference/.claude/skills/boll-dev-handoff/SKILL.md +0 -165
  339. package/src/bollharness/reference/boll-reference/.claude/skills/boll-eng/SKILL.md +0 -110
  340. package/src/bollharness/reference/boll-reference/.claude/skills/boll-eng-frontend/SKILL.md +0 -203
  341. package/src/bollharness/reference/boll-reference/.claude/skills/boll-eng-hdc/SKILL.md +0 -27
  342. package/src/bollharness/reference/boll-reference/.claude/skills/boll-eng-orchestrator/SKILL.md +0 -28
  343. package/src/bollharness/reference/boll-reference/.claude/skills/boll-eng-prompt/SKILL.md +0 -27
  344. package/src/bollharness/reference/boll-reference/.claude/skills/boll-eng-test/SKILL.md +0 -79
  345. package/src/bollharness/reference/boll-reference/.claude/skills/boll-lab/SKILL.md +0 -372
  346. package/src/bollharness/reference/boll-reference/.claude/skills/boll-run/SKILL.md +0 -437
  347. package/src/bollharness/reference/boll-reference/.claude/skills/boll-ux-appstore/SKILL.md +0 -27
  348. package/src/bollharness/reference/boll-reference/.claude/skills/boll-voice/SKILL.md +0 -442
  349. package/src/bollharness/reference/boll-reference/.claude/skills/guardian-fixer/PROMPT.md +0 -421
  350. package/src/bollharness/reference/boll-reference/.claude/skills/guardian-fixer/SKILL.md +0 -326
  351. package/src/bollharness/reference/boll-reference/.claude/skills/lead/SKILL.md +0 -155
  352. package/src/bollharness/reference/boll-reference/.claude/skills/lead/ref-review-sop.md +0 -91
  353. package/src/bollharness/reference/boll-reference/.claude/skills/lead/ref-stages.md +0 -129
  354. package/src/bollharness/reference/boll-reference/.claude/skills/nature-designer/output/skill-map-preview.png +0 -0
  355. package/src/bollharness/reference/boll-reference/.claude/skills/nature-designer/output/skill-map-v2.png +0 -0
  356. package/src/bollharness/reference/boll-reference/.claude/skills/nature-designer/output/skill-map-v3.png +0 -0
  357. package/src/bollharness/reference/boll-reference/.claude/skills/nature-designer/output/skill-map-v4.png +0 -0
  358. package/src/bollharness/reference/boll-reference/.claude/skills/plan-lock/SKILL.md +0 -425
  359. package/src/bollharness/reference/boll-reference/.claude/skills/plan-lock/ref-three-checks.md +0 -62
  360. package/src/bollharness/reference/boll-reference/.claude/skills/plan-lock/ref-wp-templates.md +0 -78
  361. package/src/bollharness/reference/boll-reference/.claude/skills/task-arch/SKILL.md +0 -76
  362. package/src/bollharness/reference/boll-reference/.claude/skills/vibedevteam-graph/SKILL.md +0 -57
  363. package/src/bollharness/reference/boll-reference/.claude/skills/vibedevteam-graph/beads-graph.sh +0 -153
  364. package/src/bollharness/reference/boll-reference/.claude/skills/vibedevteam-init/SKILL.md +0 -52
  365. package/src/bollharness/reference/boll-reference/.claude/skills/vibedevteam-init/beads-auto-link.sh +0 -76
  366. package/src/bollharness/reference/boll-reference/.claude/skills/vibedevteam-sync/SKILL.md +0 -50
  367. package/src/bollharness/reference/boll-reference/.claude/skills/vibedevteam-sync/beads-sync-proj.sh +0 -108
  368. package/src/bollharness/reference/boll-reference/docs/architecture/AGENT-PROFILE.md +0 -151
  369. package/src/bollharness/reference/boll-reference/docs/architecture/COST-STRUCTURE.md +0 -56
  370. package/src/bollharness/reference/boll-reference/docs/architecture/INDEX.md +0 -76
  371. package/src/bollharness/reference/boll-reference/docs/architecture/MODULE1-INTENT-FIELD.md +0 -116
  372. package/src/bollharness/reference/boll-reference/docs/architecture/MODULE2-CRYSTALLIZATION.md +0 -200
  373. package/src/bollharness/reference/boll-reference/docs/architecture/PRINCIPLES.md +0 -84
  374. package/src/bollharness/reference/boll-reference/docs/architecture/PROTOCOL-CORE.md +0 -209
  375. package/src/bollharness/reference/boll-reference/docs/architecture/VISION.md +0 -181
  376. package/src/bollharness/reference/boll-reference/docs/architecture/discussions/D-01-MARKET-SCENE-PROTOCOL.md +0 -754
  377. package/src/bollharness/templates/scaffold/.boll/guard/.gitkeep +0 -0
  378. package/src/bollharness/templates/scaffold/.boll/metrics/.gitkeep +0 -0
  379. package/src/bollharness/templates/scaffold/.boll/state/.gitkeep +0 -0
  380. package/src/bollharness/templates/scaffold/docs/INDEX.md +0 -3
  381. package/src/bollharness/templates/scaffold/docs/decisions/ADR_TEMPLATE.md +0 -38
  382. package/src/bollharness/templates/scaffold/docs/decisions/PLAN_TEMPLATE.md +0 -45
  383. package/src/bollharness/templates/scaffold/docs/decisions/tasks/.gitkeep +0 -2
  384. package/src/bollharness/templates/scaffold/docs/issues/.gitkeep +0 -0
  385. package/src/bollharness/templates/scaffold/docs/issues/GUARD_ISSUE_TEMPLATE.md +0 -35
  386. package/src/bollharness/templates/scaffold/docs/issues/ISSUE_TEMPLATE.md +0 -51
  387. package/src/bollharness/tsconfig.json +0 -26
  388. package/src/constraint-runtime/package-lock.json +0 -48
  389. package/src/constraint-runtime/package.json +0 -34
  390. package/src/constraint-runtime/src/_archive_helper.ts +0 -16
  391. package/src/constraint-runtime/src/agent/coordinator.ts +0 -71
  392. package/src/constraint-runtime/src/agent/index.ts +0 -1
  393. package/src/constraint-runtime/src/assistant/index.ts +0 -15
  394. package/src/constraint-runtime/src/bootstrap/index.ts +0 -15
  395. package/src/constraint-runtime/src/bootstrap_graph.ts +0 -17
  396. package/src/constraint-runtime/src/bridge/index.ts +0 -15
  397. package/src/constraint-runtime/src/buddy/index.ts +0 -15
  398. package/src/constraint-runtime/src/cli/index.ts +0 -15
  399. package/src/constraint-runtime/src/command_graph.ts +0 -20
  400. package/src/constraint-runtime/src/commands.ts +0 -83
  401. package/src/constraint-runtime/src/components/index.ts +0 -15
  402. package/src/constraint-runtime/src/constants/index.ts +0 -15
  403. package/src/constraint-runtime/src/constraint/budget.ts +0 -25
  404. package/src/constraint-runtime/src/constraint/index.ts +0 -3
  405. package/src/constraint-runtime/src/constraint/permission.ts +0 -28
  406. package/src/constraint-runtime/src/context.ts +0 -45
  407. package/src/constraint-runtime/src/coordinator/index.ts +0 -15
  408. package/src/constraint-runtime/src/cost_hook.ts +0 -6
  409. package/src/constraint-runtime/src/cost_tracker.ts +0 -9
  410. package/src/constraint-runtime/src/deferred_init.ts +0 -18
  411. package/src/constraint-runtime/src/direct_modes.ts +0 -13
  412. package/src/constraint-runtime/src/dynamic-tool-loader.ts +0 -115
  413. package/src/constraint-runtime/src/entrypoints/index.ts +0 -15
  414. package/src/constraint-runtime/src/execution_registry.ts +0 -41
  415. package/src/constraint-runtime/src/history.ts +0 -16
  416. package/src/constraint-runtime/src/hooks/index.ts +0 -15
  417. package/src/constraint-runtime/src/index.ts +0 -28
  418. package/src/constraint-runtime/src/ink.ts +0 -4
  419. package/src/constraint-runtime/src/keybindings/index.ts +0 -15
  420. package/src/constraint-runtime/src/memdir/index.ts +0 -15
  421. package/src/constraint-runtime/src/migrations/index.ts +0 -15
  422. package/src/constraint-runtime/src/models.ts +0 -49
  423. package/src/constraint-runtime/src/moreright/index.ts +0 -15
  424. package/src/constraint-runtime/src/native_ts/index.ts +0 -15
  425. package/src/constraint-runtime/src/output_styles/index.ts +0 -15
  426. package/src/constraint-runtime/src/parity_audit.ts +0 -23
  427. package/src/constraint-runtime/src/plugins/index.ts +0 -15
  428. package/src/constraint-runtime/src/port_manifest.ts +0 -20
  429. package/src/constraint-runtime/src/prefetch.ts +0 -17
  430. package/src/constraint-runtime/src/query.ts +0 -7
  431. package/src/constraint-runtime/src/reference_data/archive_surface_snapshot.json +0 -63
  432. package/src/constraint-runtime/src/reference_data/commands_snapshot.json +0 -1037
  433. package/src/constraint-runtime/src/reference_data/subsystems/OpenCLI.json +0 -10
  434. package/src/constraint-runtime/src/reference_data/subsystems/PolymarketSDK.json +0 -12
  435. package/src/constraint-runtime/src/reference_data/subsystems/SafeSDK.json +0 -14
  436. package/src/constraint-runtime/src/reference_data/subsystems/assistant.json +0 -8
  437. package/src/constraint-runtime/src/reference_data/subsystems/bootstrap.json +0 -8
  438. package/src/constraint-runtime/src/reference_data/subsystems/bridge.json +0 -32
  439. package/src/constraint-runtime/src/reference_data/subsystems/buddy.json +0 -13
  440. package/src/constraint-runtime/src/reference_data/subsystems/cli.json +0 -26
  441. package/src/constraint-runtime/src/reference_data/subsystems/components.json +0 -32
  442. package/src/constraint-runtime/src/reference_data/subsystems/constants.json +0 -28
  443. package/src/constraint-runtime/src/reference_data/subsystems/coordinator.json +0 -8
  444. package/src/constraint-runtime/src/reference_data/subsystems/entrypoints.json +0 -15
  445. package/src/constraint-runtime/src/reference_data/subsystems/hooks.json +0 -32
  446. package/src/constraint-runtime/src/reference_data/subsystems/keybindings.json +0 -21
  447. package/src/constraint-runtime/src/reference_data/subsystems/memdir.json +0 -15
  448. package/src/constraint-runtime/src/reference_data/subsystems/migrations.json +0 -18
  449. package/src/constraint-runtime/src/reference_data/subsystems/moreright.json +0 -8
  450. package/src/constraint-runtime/src/reference_data/subsystems/native_ts.json +0 -11
  451. package/src/constraint-runtime/src/reference_data/subsystems/outputStyles.json +0 -8
  452. package/src/constraint-runtime/src/reference_data/subsystems/plugins.json +0 -9
  453. package/src/constraint-runtime/src/reference_data/subsystems/remote.json +0 -11
  454. package/src/constraint-runtime/src/reference_data/subsystems/schemas.json +0 -8
  455. package/src/constraint-runtime/src/reference_data/subsystems/screens.json +0 -10
  456. package/src/constraint-runtime/src/reference_data/subsystems/server.json +0 -10
  457. package/src/constraint-runtime/src/reference_data/subsystems/services.json +0 -32
  458. package/src/constraint-runtime/src/reference_data/subsystems/skills.json +0 -27
  459. package/src/constraint-runtime/src/reference_data/subsystems/state.json +0 -13
  460. package/src/constraint-runtime/src/reference_data/subsystems/types.json +0 -18
  461. package/src/constraint-runtime/src/reference_data/subsystems/upstreamproxy.json +0 -9
  462. package/src/constraint-runtime/src/reference_data/subsystems/utils.json +0 -32
  463. package/src/constraint-runtime/src/reference_data/subsystems/vim.json +0 -12
  464. package/src/constraint-runtime/src/reference_data/subsystems/voice.json +0 -8
  465. package/src/constraint-runtime/src/reference_data/tools_snapshot.json +0 -1042
  466. package/src/constraint-runtime/src/remote/index.ts +0 -15
  467. package/src/constraint-runtime/src/remote_runtime.ts +0 -17
  468. package/src/constraint-runtime/src/runtime/index.ts +0 -1
  469. package/src/constraint-runtime/src/runtime/session.ts +0 -42
  470. package/src/constraint-runtime/src/schemas/index.ts +0 -15
  471. package/src/constraint-runtime/src/screens/index.ts +0 -15
  472. package/src/constraint-runtime/src/server/index.ts +0 -15
  473. package/src/constraint-runtime/src/services/index.ts +0 -15
  474. package/src/constraint-runtime/src/session_store.ts +0 -32
  475. package/src/constraint-runtime/src/setup.ts +0 -50
  476. package/src/constraint-runtime/src/skills/index.ts +0 -1
  477. package/src/constraint-runtime/src/skills/skill-registry.ts +0 -40
  478. package/src/constraint-runtime/src/state/index.ts +0 -15
  479. package/src/constraint-runtime/src/system_init.ts +0 -21
  480. package/src/constraint-runtime/src/thinking/engine.ts +0 -61
  481. package/src/constraint-runtime/src/thinking/index.ts +0 -1
  482. package/src/constraint-runtime/src/tool_pool.ts +0 -20
  483. package/src/constraint-runtime/src/tools/OpenCLI/execAdapter.ts +0 -12
  484. package/src/constraint-runtime/src/tools/OpenCLI/listAdapters.ts +0 -12
  485. package/src/constraint-runtime/src/tools/OpenCLI/runCommand.ts +0 -13
  486. package/src/constraint-runtime/src/tools/PolymarketSDK/cancelOrder.ts +0 -10
  487. package/src/constraint-runtime/src/tools/PolymarketSDK/createOrder.ts +0 -13
  488. package/src/constraint-runtime/src/tools/PolymarketSDK/getMarket.ts +0 -14
  489. package/src/constraint-runtime/src/tools/PolymarketSDK/getOrders.ts +0 -10
  490. package/src/constraint-runtime/src/tools/PolymarketSDK/listMarkets.ts +0 -24
  491. package/src/constraint-runtime/src/tools/SafeSDK/confirmTransaction.ts +0 -13
  492. package/src/constraint-runtime/src/tools/SafeSDK/createTransaction.ts +0 -23
  493. package/src/constraint-runtime/src/tools/SafeSDK/deploySafe.ts +0 -12
  494. package/src/constraint-runtime/src/tools/SafeSDK/executeTransaction.ts +0 -12
  495. package/src/constraint-runtime/src/tools/SafeSDK/getBalance.ts +0 -10
  496. package/src/constraint-runtime/src/tools/SafeSDK/getPendingTransactions.ts +0 -10
  497. package/src/constraint-runtime/src/tools/SafeSDK/proposeTransaction.ts +0 -14
  498. package/src/constraint-runtime/src/tools/WalletTools/autoPay.ts +0 -58
  499. package/src/constraint-runtime/src/tools/WalletTools/createWallet.ts +0 -19
  500. package/src/constraint-runtime/src/tools/WalletTools/getBalance.ts +0 -28
  501. package/src/constraint-runtime/src/tools/WalletTools/importWallet.ts +0 -34
  502. package/src/constraint-runtime/src/tools/WalletTools/sendTransaction.ts +0 -50
  503. package/src/constraint-runtime/src/tools/WalletTools/signMessage.ts +0 -23
  504. package/src/constraint-runtime/src/tools/WalletTools/transferToken.ts +0 -49
  505. package/src/constraint-runtime/src/tools.ts +0 -100
  506. package/src/constraint-runtime/src/transcript.ts +0 -23
  507. package/src/constraint-runtime/src/types/index.ts +0 -15
  508. package/src/constraint-runtime/src/upstream_proxy/index.ts +0 -15
  509. package/src/constraint-runtime/src/utils/index.ts +0 -15
  510. package/src/constraint-runtime/src/vim/index.ts +0 -15
  511. package/src/constraint-runtime/src/voice/index.ts +0 -15
  512. package/src/constraint-runtime/tests/agent.test.ts +0 -20
  513. package/src/constraint-runtime/tests/constraint.test.ts +0 -47
  514. package/src/constraint-runtime/tests/skill.test.ts +0 -23
  515. package/src/constraint-runtime/tests/thinking.test.ts +0 -28
  516. package/src/constraint-runtime/tsconfig.json +0 -13
  517. package/src/pi-ecosystem/index.ts +0 -453
  518. package/src/pi-ecosystem-colony/index.ts +0 -482
  519. package/src/pi-ecosystem-goals/index.ts +0 -585
  520. package/src/pi-ecosystem-judgment/decision.ts +0 -431
  521. package/src/pi-ecosystem-judgment/distillation.ts +0 -398
  522. package/src/pi-ecosystem-judgment/human-value-store.ts +0 -580
  523. package/src/pi-ecosystem-judgment/index.ts +0 -678
  524. package/src/pi-ecosystem-judgment/value-injection.ts +0 -744
  525. package/src/pi-ecosystem-mcp/index.ts +0 -427
  526. package/src/pi-ecosystem-subagents/index.ts +0 -408
  527. package/src/test/ai-judgment-test.ts +0 -92
  528. package/src/test/bollharness-integration.test.ts +0 -398
  529. package/src/test/channel-agent-multi-dialogue.ts +0 -265
  530. package/src/test/channel-heartbeat-agent-test.ts +0 -244
  531. package/src/test/constraint-layer.test.ts +0 -191
  532. package/src/test/diap-identity-test.ts +0 -222
  533. package/src/test/diap-quick-test.ts +0 -73
  534. package/src/test/global-shared-context.test.ts +0 -393
  535. package/src/test/harness-judgment-injection.test.ts +0 -353
  536. package/src/test/harness-workflow-integrator-test.ts +0 -285
  537. package/src/test/human-value-store.test.ts +0 -316
  538. package/src/test/hybrid-integration-test.ts +0 -126
  539. package/src/test/hybrid-messenger-verify.ts +0 -68
  540. package/src/test/iroh-bistream-debug.ts +0 -50
  541. package/src/test/iroh-communication.test.ts +0 -81
  542. package/src/test/iroh-debug-test.ts +0 -69
  543. package/src/test/iroh-diap-test.ts +0 -90
  544. package/src/test/iroh-direct-connect.ts +0 -65
  545. package/src/test/iroh-e2e-fixed.ts +0 -106
  546. package/src/test/iroh-e2e-same-process.ts +0 -83
  547. package/src/test/iroh-e2e.ts +0 -83
  548. package/src/test/iroh-final-e2e.ts +0 -84
  549. package/src/test/iroh-relay-test.ts +0 -46
  550. package/src/test/iroh-simple-test.ts +0 -49
  551. package/src/test/iroh-transport-verify.ts +0 -60
  552. package/src/test/iroh-transport.test.ts +0 -47
  553. package/src/test/iroh-two-nodes.ts +0 -87
  554. package/src/test/iroh-verify.ts +0 -55
  555. package/src/test/judgment-decision.test.ts +0 -373
  556. package/src/test/llm-judgment-integration.test.ts +0 -257
  557. package/src/test/p2p-agent-complex-dialogue.ts +0 -490
  558. package/src/test/p2p-agent-dialogue.ts +0 -423
  559. package/src/test/p2p-agent-full-bidirectional.ts +0 -686
  560. package/src/test/p2p-agent-harness-flow.ts +0 -562
  561. package/src/test/p2p-agent-harness-single.ts +0 -175
  562. package/src/test/p2p-ai-dialogue-test.ts +0 -374
  563. package/src/test/p2p-cid-connect-test.ts +0 -245
  564. package/src/test/p2p-connect-receiver.ts +0 -85
  565. package/src/test/p2p-iroh-test.ts +0 -214
  566. package/src/test/p2p-minimal-test.ts +0 -264
  567. package/src/test/p2p-node-1.ts +0 -172
  568. package/src/test/p2p-node-2.ts +0 -172
  569. package/src/test/p2p-server.ts +0 -335
  570. package/src/test/p2p-two-nodes-test.ts +0 -542
  571. package/src/test/pi-sdk.test.ts +0 -47
  572. package/src/test/set-persona.ts +0 -56
  573. package/src/test/simple.test.ts +0 -11
  574. package/src/test/storage-integration.test.ts +0 -191
  575. package/src/test/subagent-manager.test.ts +0 -392
  576. package/src/test/test-gate-flow.test.ts +0 -92
  577. package/src/test/workflow-engine.test.ts +0 -101
  578. package/src/workflows/collaboration.ts +0 -455
  579. package/src/workflows/index.ts +0 -64
  580. package/vitest.config.ts +0 -12
  581. package//346/203/263/346/263/225.md +0 -79
@@ -10,16 +10,20 @@ const newChannelInput = document.getElementById('new-channel-input');
10
10
  const channelNameEl = document.getElementById('channel-name');
11
11
  const loadSessionBtn = document.getElementById('load-session-btn');
12
12
  const sessionFileInput = document.getElementById('session-file-input');
13
+ const newSessionBtn = document.getElementById('new-session-btn');
13
14
 
14
- let eventSource = null;
15
+ let eventSources = new Map(); // channelId -> EventSource
15
16
  let currentChannelId = null;
16
17
  let currentAgentId = '';
17
18
  let channels = [];
18
19
  let isSidebarCollapsed = false;
19
- let reconnectAttempts = 0;
20
- let reconnectTimer = null; // 改进: 跟踪重连定时器
20
+ let reconnectAttempts = new Map(); // channelId -> attempts
21
+ let reconnectTimers = new Map(); // channelId -> timer
21
22
  let lastUserCommand = ''; // 防止用户消息重复显示
22
23
  let lastAiContent = ''; // 防止 AI 消息重复显示
24
+ let messagesContainers = new Map(); // channelId -> messages container div
25
+ let sessionMessages = new Map(); // channelId:sessionId -> messages array
26
+ let currentSessionId = null; // 当前显示的 session ID
23
27
 
24
28
  function generateId() {
25
29
  return crypto.randomUUID();
@@ -149,6 +153,57 @@ async function deleteChannel(channelId, e) {
149
153
  }
150
154
  }
151
155
 
156
+ async function createNewSession() {
157
+ if (!currentChannelId) {
158
+ console.log('[新会话] 没有选中的频道');
159
+ return;
160
+ }
161
+ try {
162
+ // 保存当前 session 的消息
163
+ const channel = channels.find(c => c.id === currentChannelId);
164
+ if (channel && currentSessionId) {
165
+ const container = messagesContainers.get(currentChannelId);
166
+ if (container) {
167
+ const messages = Array.from(container.querySelectorAll('.message')).map(msg => ({
168
+ type: msg.classList.contains('message-user') ? 'user' : 'ai',
169
+ content: msg.querySelector('.message-content')?.textContent || ''
170
+ }));
171
+ sessionMessages.set(`${currentChannelId}:${currentSessionId}`, messages);
172
+ console.log('[新会话] 保存旧 session 消息:', messages.length);
173
+ }
174
+ }
175
+
176
+ const res = await fetch(`/channels/${currentChannelId}/sessions`, {
177
+ method: 'POST'
178
+ });
179
+ const data = await res.json();
180
+ console.log('[新会话] 创建成功:', data);
181
+
182
+ // 更新本地频道数据
183
+ if (channel) {
184
+ if (!channel.sessions) channel.sessions = [];
185
+ channel.sessions.push(data.session);
186
+ channel.currentSessionId = data.currentSessionId;
187
+ }
188
+
189
+ // 切换到新 session
190
+ const oldSessionId = currentSessionId;
191
+ currentSessionId = data.currentSessionId;
192
+
193
+ // 清空容器并加载新 session
194
+ const container = messagesContainers.get(currentChannelId);
195
+ if (container) {
196
+ container.innerHTML = '';
197
+ showChannelView(currentChannelId);
198
+ addMessage('你好!新会话已开始,有什么我可以帮你的吗?', 'ai', false, container);
199
+ }
200
+
201
+ console.log('[新会话] 已切换到:', data.currentSessionId);
202
+ } catch (err) {
203
+ console.error('Failed to create new session:', err);
204
+ }
205
+ }
206
+
152
207
  function renderChannels() {
153
208
  if (!channelList) return;
154
209
  channelList.innerHTML = '';
@@ -184,73 +239,131 @@ function renderCollapsedChannels() {
184
239
  return;
185
240
  }
186
241
 
242
+ function ensureMessageContainer(channelId) {
243
+ if (!messagesContainers.has(channelId)) {
244
+ const container = document.createElement('div');
245
+ container.className = 'channel-messages';
246
+ container.id = `channel-messages-${channelId}`;
247
+ container.style.display = 'none';
248
+ messagesEl.appendChild(container);
249
+ messagesContainers.set(channelId, container);
250
+ }
251
+ return messagesContainers.get(channelId);
252
+ }
253
+
254
+ function showChannelView(channelId) {
255
+ // Hide all channel message containers
256
+ messagesContainers.forEach((container, cid) => {
257
+ container.style.display = 'none';
258
+ });
259
+ // Show the selected channel's container
260
+ const container = messagesContainers.get(channelId);
261
+ if (container) {
262
+ container.style.display = 'block';
263
+ }
264
+ // Update messagesEl reference for functions that use it directly
265
+ messagesEl.innerHTML = '';
266
+ if (container) {
267
+ messagesEl.appendChild(container);
268
+ }
269
+ }
270
+
187
271
  async function selectChannel(channelId) {
188
272
  console.log('[selectChannel] 开始切换到:', channelId);
189
273
 
274
+ // 保存当前 session 的消息
275
+ if (currentChannelId && currentSessionId) {
276
+ const container = messagesContainers.get(currentChannelId);
277
+ if (container) {
278
+ const messages = Array.from(container.querySelectorAll('.message')).map(msg => ({
279
+ type: msg.classList.contains('message-user') ? 'user' : 'ai',
280
+ content: msg.querySelector('.message-content')?.textContent || ''
281
+ }));
282
+ if (messages.length > 0) {
283
+ sessionMessages.set(`${currentChannelId}:${currentSessionId}`, messages);
284
+ console.log('[selectChannel] 保存 session 消息:', messages.length);
285
+ }
286
+ }
287
+ }
288
+
190
289
  // 立即更新当前频道 ID
191
290
  currentChannelId = channelId;
192
- reconnectAttempts = 0;
291
+ reconnectAttempts.set(channelId, 0);
193
292
 
194
- // 找到当前频道
293
+ // 找到当前频道和 session
195
294
  const channel = channels.find(c => c.id === channelId);
196
- if (channel && channelNameEl) {
197
- channelNameEl.textContent = channel.name;
198
- console.log('[selectChannel] 频道:', channel.name, 'DID:', channel.did || '');
295
+ if (channel) {
296
+ if (channelNameEl) channelNameEl.textContent = channel.name;
297
+ currentSessionId = channel.currentSessionId || 'default';
298
+ console.log('[selectChannel] 频道:', channel.name, 'session:', currentSessionId);
199
299
  }
200
300
 
201
301
  renderChannels();
202
302
 
203
- // 关闭旧 SSE 连接
204
- if (eventSource) {
205
- console.log('[selectChannel] 关闭旧 SSE 连接');
206
- eventSource.close();
207
- eventSource = null;
303
+ // 确保该频道有消息容器
304
+ const container = ensureMessageContainer(channelId);
305
+
306
+ // 切换到该频道的视图
307
+ showChannelView(channelId);
308
+
309
+ // 如果还没有 SSE 连接,建立连接
310
+ if (!eventSources.has(channelId)) {
311
+ console.log('[selectChannel] 建立 SSE 连接');
312
+ connect(channelId);
208
313
  }
209
314
 
210
- // 清空消息区域
211
- messagesEl.innerHTML = '';
315
+ // 检查是否有保存的 session 消息
316
+ const sessionKey = `${channelId}:${currentSessionId}`;
317
+ const savedMessages = sessionMessages.get(sessionKey);
212
318
 
213
- // 加载 session
214
- try {
215
- const res = await fetch(`/sessions/${channelId}`);
216
- const session = await res.json();
217
- if (session.messages && session.messages.length > 0) {
218
- session.messages.forEach(msg => {
219
- addMessage(msg.content, msg.type, false);
220
- });
221
- } else {
222
- addMessage('你好!我是 Bolloon Agent。有什么我可以帮你的吗?', 'ai', false);
319
+ if (savedMessages && savedMessages.length > 0) {
320
+ console.log('[selectChannel] 加载已保存的 session 消息:', savedMessages.length);
321
+ container.innerHTML = '';
322
+ savedMessages.forEach(msg => {
323
+ addMessage(msg.content, msg.type, false, container);
324
+ });
325
+ } else if (container.innerHTML.trim() === '') {
326
+ // 如果容器是空的,加载 session
327
+ try {
328
+ const res = await fetch(`/sessions/${channelId}`);
329
+ const session = await res.json();
330
+ if (session.messages && session.messages.length > 0) {
331
+ session.messages.forEach(msg => {
332
+ addMessage(msg.content, msg.type, false, container);
333
+ });
334
+ } else {
335
+ addMessage('你好!我是 Bolloon Agent。有什么我可以帮你的吗?', 'ai', false, container);
336
+ }
337
+ } catch (err) {
338
+ console.error('[selectChannel] 加载 session 失败:', err);
339
+ addMessage('你好!我是 Bolloon Agent。有什么我可以帮你的吗?', 'ai', false, container);
223
340
  }
224
- } catch (err) {
225
- console.error('[selectChannel] 加载 session 失败:', err);
226
- addMessage('你好!我是 Bolloon Agent。有什么我可以帮你的吗?', 'ai', false);
227
341
  }
228
-
229
- // 建立新 SSE 连接
230
- console.log('[selectChannel] 建立 SSE 连接');
231
- connect();
232
342
  }
233
343
 
234
344
  async function loadSession(channelId) {
345
+ const container = messagesContainers.get(channelId);
346
+ if (!container) return;
235
347
  try {
236
348
  const res = await fetch(`/sessions/${channelId}`);
237
349
  const session = await res.json();
238
- messagesEl.innerHTML = '';
350
+ container.innerHTML = '';
239
351
  if (session.messages && session.messages.length > 0) {
240
352
  session.messages.forEach(msg => {
241
- addMessage(msg.content, msg.type, false);
353
+ addMessage(msg.content, msg.type, false, container);
242
354
  });
243
355
  } else {
244
- addMessage('你好!我是 Bolloon Agent。有什么我可以帮你的吗?', 'ai', false);
356
+ addMessage('你好!我是 Bolloon Agent。有什么我可以帮你的吗?', 'ai', false, container);
245
357
  }
246
358
  } catch (err) {
247
359
  console.error('Failed to load session:', err);
248
- messagesEl.innerHTML = '';
249
- addMessage('你好!我是 Bolloon Agent。有什么我可以帮你的吗?', 'ai', false);
360
+ container.innerHTML = '';
361
+ addMessage('你好!我是 Bolloon Agent。有什么我可以帮你的吗?', 'ai', false, container);
250
362
  }
251
363
  }
252
364
 
253
- function addMessage(content, type, save = true) {
365
+ function addMessage(content, type, save = true, container) {
366
+ const msgContainer = container || messagesContainers.get(currentChannelId) || messagesEl;
254
367
  // 去重:只有 save=true 时(来自 SSE)才去重,save=false 时(来自 session 加载)直接显示
255
368
  if (save) {
256
369
  const lastContent = type === 'user' ? lastUserCommand : lastAiContent;
@@ -459,19 +572,20 @@ function addMessage(content, type, save = true) {
459
572
  }
460
573
 
461
574
  div.appendChild(time);
462
- messagesEl.appendChild(div);
575
+ msgContainer.appendChild(div);
463
576
 
464
- messagesEl.scrollTop = messagesEl.scrollHeight;
577
+ msgContainer.scrollTop = msgContainer.scrollHeight;
465
578
  }
466
579
 
467
- function showTyping() {
580
+ function showTyping(container) {
581
+ const msgContainer = container || messagesContainers.get(currentChannelId) || messagesEl;
468
582
  hideTyping();
469
583
  const div = document.createElement('div');
470
584
  div.className = 'message message-ai';
471
585
  div.id = 'typing';
472
586
  div.innerHTML = '<div class="typing"><div class="typing-spinner"></div><span class="typing-text">思考中...</span></div>';
473
- messagesEl.appendChild(div);
474
- messagesEl.scrollTop = messagesEl.scrollHeight;
587
+ msgContainer.appendChild(div);
588
+ msgContainer.scrollTop = msgContainer.scrollHeight;
475
589
  }
476
590
 
477
591
  function hideTyping() {
@@ -482,7 +596,8 @@ function hideTyping() {
482
596
 
483
597
  let streamingMessageEl = null;
484
598
 
485
- function showStreaming() {
599
+ function showStreaming(container) {
600
+ const msgContainer = container || messagesContainers.get(currentChannelId) || messagesEl;
486
601
  hideStreaming();
487
602
  streamingMessageEl = document.createElement('div');
488
603
  streamingMessageEl.className = 'message message-ai';
@@ -490,8 +605,8 @@ function showStreaming() {
490
605
  const bubble = document.createElement('div');
491
606
  bubble.className = 'bubble bubble-ai streaming-content';
492
607
  streamingMessageEl.appendChild(bubble);
493
- messagesEl.appendChild(streamingMessageEl);
494
- messagesEl.scrollTop = messagesEl.scrollHeight;
608
+ msgContainer.appendChild(streamingMessageEl);
609
+ msgContainer.scrollTop = msgContainer.scrollHeight;
495
610
  }
496
611
 
497
612
  function hideStreaming() {
@@ -501,47 +616,57 @@ function hideStreaming() {
501
616
  }
502
617
  }
503
618
 
504
- function updateStreamingContent(content) {
619
+ function updateStreamingContent(content, container) {
620
+ const msgContainer = container || messagesContainers.get(currentChannelId) || messagesEl;
505
621
  if (streamingMessageEl) {
506
622
  const bubble = streamingMessageEl.querySelector('.streaming-content');
507
623
  if (bubble) {
508
624
  bubble.textContent = content;
509
- messagesEl.scrollTop = messagesEl.scrollHeight;
625
+ msgContainer.scrollTop = msgContainer.scrollHeight;
510
626
  }
511
627
  }
512
628
  }
513
629
 
514
- function handleStreamEvent(data) {
630
+ function handleStreamEvent(data, container) {
631
+ const msgContainer = container || messagesContainers.get(currentChannelId) || messagesEl;
632
+ // 始终确保有工作流显示区域
633
+ if (!workflowDisplayEl) {
634
+ workflowDisplayEl = createWorkflowDisplay();
635
+ msgContainer.appendChild(workflowDisplayEl);
636
+ }
637
+
515
638
  if (data.streamType === 'thinking') {
516
- showStreaming();
517
- updateStreamingContent(data.content || '思考中...');
639
+ showStreaming(msgContainer);
640
+ updateStreamingContent(data.content || '思考中...', msgContainer);
518
641
  } else if (data.streamType === 'token') {
519
- showStreaming();
642
+ showStreaming(msgContainer);
520
643
  const current = streamingMessageEl?.querySelector('.streaming-content')?.textContent || '';
521
- updateStreamingContent(current + data.content);
644
+ updateStreamingContent(current + data.content, msgContainer);
522
645
  }
523
646
  }
524
647
 
525
- function handleStatusEvent(data) {
648
+ function handleStatusEvent(data, container) {
649
+ const msgContainer = container || messagesContainers.get(currentChannelId) || messagesEl;
526
650
  // 检查是否是工具调用结果
527
651
  const content = data.content || '';
528
652
  const isJsonResult = content.startsWith('{') && content.includes('"success"');
529
653
 
530
654
  if (isJsonResult) {
531
655
  // 工具结果:折叠显示
532
- showToolResult(data.tool, content);
656
+ showToolResult(data.tool, content, msgContainer);
533
657
  } else {
534
658
  // 普通状态:流式显示
535
- showStreaming();
659
+ showStreaming(msgContainer);
536
660
  const icon = data.tool ? `🔧 ${data.tool}: ` : '';
537
- updateStreamingContent(icon + data.content);
661
+ updateStreamingContent(icon + data.content, msgContainer);
538
662
  }
539
663
  }
540
664
 
541
665
  // 显示工具调用结果(折叠)
542
666
  let toolResultContainer = null;
543
667
 
544
- function showToolResult(toolName, resultJson) {
668
+ function showToolResult(toolName, resultJson, container) {
669
+ const msgContainer = container || messagesContainers.get(currentChannelId) || messagesEl;
545
670
  // 清理之前的流式显示
546
671
  hideStreaming();
547
672
 
@@ -549,7 +674,7 @@ function showToolResult(toolName, resultJson) {
549
674
  if (!toolResultContainer) {
550
675
  toolResultContainer = document.createElement('div');
551
676
  toolResultContainer.className = 'tool-results-container';
552
- messagesEl.appendChild(toolResultContainer);
677
+ msgContainer.appendChild(toolResultContainer);
553
678
  }
554
679
 
555
680
  // 尝试解析并格式化 JSON
@@ -584,7 +709,7 @@ function showToolResult(toolName, resultJson) {
584
709
  resultEl.appendChild(headerEl);
585
710
  resultEl.appendChild(contentEl);
586
711
  toolResultContainer.appendChild(resultEl);
587
- messagesEl.scrollTop = messagesEl.scrollHeight;
712
+ msgContainer.scrollTop = msgContainer.scrollHeight;
588
713
  }
589
714
 
590
715
  // 格式化工具结果为易读格式
@@ -635,13 +760,14 @@ function createWorkflowDisplay() {
635
760
  return container;
636
761
  }
637
762
 
638
- function handleTaskStatusEvent(data) {
763
+ function handleTaskStatusEvent(data, container) {
764
+ const msgContainer = container || messagesContainers.get(currentChannelId) || messagesEl;
639
765
  console.log('[工作流] 任务状态:', data);
640
766
 
641
767
  // 获取或创建工作流显示区域
642
768
  if (!workflowDisplayEl) {
643
769
  workflowDisplayEl = createWorkflowDisplay();
644
- messagesEl.appendChild(workflowDisplayEl);
770
+ msgContainer.appendChild(workflowDisplayEl);
645
771
  }
646
772
 
647
773
  const stepsList = workflowDisplayEl.querySelector('.workflow-steps-list');
@@ -685,35 +811,58 @@ function handleTaskStatusEvent(data) {
685
811
  }
686
812
  }
687
813
 
688
- function handleWorkflowStepEvent(data) {
814
+ function handleWorkflowStepEvent(data, container) {
815
+ const msgContainer = container || messagesContainers.get(currentChannelId) || messagesEl;
689
816
  console.log('[工作流] 步骤:', data);
817
+ console.log('[工作流] 步骤标签:', data.step, '内容:', data.content?.substring(0, 80));
690
818
 
819
+ // 获取或创建工作流显示区域
691
820
  if (!workflowDisplayEl) {
692
821
  workflowDisplayEl = createWorkflowDisplay();
693
- messagesEl.appendChild(workflowDisplayEl);
822
+ msgContainer.appendChild(workflowDisplayEl);
694
823
  }
695
824
 
696
825
  const streamsDiv = workflowDisplayEl.querySelector('.workflow-streams');
826
+ const header = workflowDisplayEl.querySelector('.workflow-header');
827
+
828
+ // 更新工作流标题
829
+ if (data.step && data.step !== '系统' && data.step !== '状态') {
830
+ header.querySelector('.workflow-title').textContent = `执行: ${data.step}`;
831
+ }
697
832
 
698
833
  // 如果有步骤标签,显示步骤信息
699
- if (data.step) {
834
+ if (data.step && data.content) {
700
835
  const stepEl = document.createElement('div');
701
836
  stepEl.className = 'workflow-step-stream';
837
+
838
+ // 根据内容类型选择不同样式
839
+ const isError = data.content.includes('❌') || data.content.includes('错误');
840
+ const isSuccess = data.content.includes('✅') || data.content.includes('成功');
841
+ const isLoop = data.content.includes('🔄') || data.content.includes('循环');
842
+
843
+ let icon = '🔧';
844
+ if (isError) icon = '❌';
845
+ else if (isSuccess) icon = '✅';
846
+ else if (isLoop) icon = '🔄';
847
+
702
848
  stepEl.innerHTML = `
703
- <div class="step-label">🔧 ${data.step}</div>
704
- <div class="step-content">${data.content || ''}</div>
849
+ <div class="step-label">${icon} ${data.step}</div>
850
+ <div class="step-content">${data.content}</div>
705
851
  `;
706
852
  streamsDiv.appendChild(stepEl);
707
- messagesEl.scrollTop = messagesEl.scrollHeight;
853
+
854
+ // 自动滚动
855
+ msgContainer.scrollTop = msgContainer.scrollHeight;
708
856
  }
709
857
  }
710
858
 
711
- function handleWorkflowLoopEvent(data) {
859
+ function handleWorkflowLoopEvent(data, container) {
860
+ const msgContainer = container || messagesContainers.get(currentChannelId) || messagesEl;
712
861
  console.log('[工作流] 循环:', data);
713
862
 
714
863
  if (!workflowDisplayEl) {
715
864
  workflowDisplayEl = createWorkflowDisplay();
716
- messagesEl.appendChild(workflowDisplayEl);
865
+ msgContainer.appendChild(workflowDisplayEl);
717
866
  }
718
867
 
719
868
  const loopCount = workflowDisplayEl.querySelector('.workflow-loop-count');
@@ -738,16 +887,17 @@ function handleWorkflowLoopEvent(data) {
738
887
  <div class="loop-content">${data.content}</div>
739
888
  `;
740
889
  streamsDiv.appendChild(loopEl);
741
- messagesEl.scrollTop = messagesEl.scrollHeight;
890
+ msgContainer.scrollTop = msgContainer.scrollHeight;
742
891
  }
743
892
  }
744
893
 
745
894
  // 用户命令可视化 - 当用户发送命令时调用
746
895
  let userCommandDisplayEl = null;
747
896
 
748
- function showUserCommand(command) {
897
+ function showUserCommand(command, container) {
898
+ const msgContainer = container || messagesContainers.get(currentChannelId) || messagesEl;
749
899
  // 先移除之前的消息中的 user bubble(如果有重复的话)
750
- const existingUserBubbles = messagesEl.querySelectorAll('.message-user');
900
+ const existingUserBubbles = msgContainer.querySelectorAll('.message-user');
751
901
  existingUserBubbles.forEach(el => el.remove());
752
902
 
753
903
  // 移除之前的命令显示
@@ -769,100 +919,110 @@ function showUserCommand(command) {
769
919
 
770
920
  // 在工作流显示之前插入
771
921
  if (workflowDisplayEl) {
772
- messagesEl.insertBefore(userCommandDisplayEl, workflowDisplayEl);
922
+ msgContainer.insertBefore(userCommandDisplayEl, workflowDisplayEl);
773
923
  } else {
774
- messagesEl.appendChild(userCommandDisplayEl);
924
+ msgContainer.appendChild(userCommandDisplayEl);
775
925
  }
776
926
 
777
- messagesEl.scrollTop = messagesEl.scrollHeight;
927
+ msgContainer.scrollTop = msgContainer.scrollHeight;
778
928
  }
779
929
 
780
- function connect() {
781
- // 清除旧的重连定时器
782
- if (reconnectTimer) {
783
- clearTimeout(reconnectTimer);
784
- reconnectTimer = null;
930
+ function connect(channelId) {
931
+ const targetChannelId = channelId || currentChannelId;
932
+ if (!targetChannelId) return;
933
+
934
+ // 清除该频道的重连定时器
935
+ if (reconnectTimers.has(targetChannelId)) {
936
+ clearTimeout(reconnectTimers.get(targetChannelId));
937
+ reconnectTimers.delete(targetChannelId);
785
938
  }
786
939
 
787
- // 关闭已有连接
788
- if (eventSource) {
789
- eventSource.close();
790
- eventSource = null;
940
+ // 关闭该频道的旧连接
941
+ if (eventSources.has(targetChannelId)) {
942
+ eventSources.get(targetChannelId).close();
943
+ eventSources.delete(targetChannelId);
791
944
  }
792
945
 
793
- const sseUrl = currentChannelId ? `/events?channelId=${encodeURIComponent(currentChannelId)}` : '/events';
946
+ const sseUrl = `/events?channelId=${encodeURIComponent(targetChannelId)}`;
794
947
  console.log('[connect] 创建 SSE 连接:', sseUrl);
795
948
 
796
- eventSource = new EventSource(sseUrl);
949
+ const eventSource = new EventSource(sseUrl);
950
+ eventSources.set(targetChannelId, eventSource);
951
+
952
+ if (!reconnectAttempts.has(targetChannelId)) {
953
+ reconnectAttempts.set(targetChannelId, 0);
954
+ }
797
955
 
798
956
  eventSource.onopen = () => {
799
- console.log('[SSE] 已连接');
800
- reconnectAttempts = 0;
957
+ console.log('[SSE] 已连接 channelId:', targetChannelId);
958
+ reconnectAttempts.set(targetChannelId, 0);
801
959
  };
802
960
 
803
961
  eventSource.onerror = () => {
804
- console.error('[SSE] 连接错误');
962
+ console.error('[SSE] 连接错误 channelId:', targetChannelId);
805
963
  eventSource.close();
806
- eventSource = null;
807
- reconnectAttempts++;
808
- // 清除旧的重连定时器
809
- if (reconnectTimer) clearTimeout(reconnectTimer);
810
- reconnectTimer = setTimeout(connect, Math.min(5000 * reconnectAttempts, 30000));
964
+ eventSources.delete(targetChannelId);
965
+ const attempts = (reconnectAttempts.get(targetChannelId) || 0) + 1;
966
+ reconnectAttempts.set(targetChannelId, attempts);
967
+ const timer = setTimeout(() => connect(targetChannelId), Math.min(5000 * attempts, 30000));
968
+ reconnectTimers.set(targetChannelId, timer);
811
969
  };
812
970
 
813
971
  eventSource.onmessage = (e) => {
814
972
  try {
815
973
  const data = JSON.parse(e.data);
816
- console.log('[SSE] 收到消息:', data.type, 'channelId:', data.channelId);
974
+ const msgChannelId = data.channelId || targetChannelId;
975
+ console.log('[SSE] 收到消息:', data.type, 'channelId:', msgChannelId);
817
976
 
818
- // 只处理当前频道的消息
819
- if (data.channelId && data.channelId !== currentChannelId) {
820
- console.log('[SSE] 忽略非当前频道消息');
977
+ // 路由消息到正确的频道(即使该频道不是当前视图)
978
+ if (msgChannelId !== targetChannelId) {
979
+ console.log('[SSE] 忽略非目标频道消息');
821
980
  return;
822
981
  }
823
982
 
983
+ // 使用正确的消息容器
984
+ const container = messagesContainers.get(msgChannelId) || messagesEl;
985
+
824
986
  if (data.type === 'user') {
825
- showUserCommand(data.content); // 用户命令可视化(已包含 message-user)
826
- // 不再调用 addMessage,避免重复
987
+ showUserCommand(data.content, container);
827
988
  } else if (data.type === 'ai') {
828
- addMessage(data.content, 'ai');
829
- } else if (data.type === 'stream') {
830
- handleStreamEvent(data);
831
- } else if (data.type === 'regenerating') {
832
- // 开始重新生成,清除最后一个 AI 消息
833
- const messages = messagesEl.querySelectorAll('.message-ai');
834
- if (messages.length > 0) {
835
- const lastAiMsg = messages[messages.length - 1];
836
- lastAiMsg.remove();
837
- }
838
- showTyping();
839
- } else if (data.type === 'status') {
840
- handleStatusEvent(data);
841
- } else if (data.type === 'done') {
842
- hideTyping();
843
- } else if (data.type === 'renamed') {
844
- const channel = channels.find(c => c.id === data.channelId);
845
- if (channel) {
846
- channel.name = data.newName;
847
- renderChannels();
848
- if (currentChannelId === data.channelId && channelNameEl) {
849
- channelNameEl.textContent = data.newName;
850
- }
989
+ addMessage(data.content, 'ai', true, container);
990
+ } else if (data.type === 'stream') {
991
+ handleStreamEvent(data, container);
992
+ } else if (data.type === 'regenerating') {
993
+ const messages = container.querySelectorAll('.message-ai');
994
+ if (messages.length > 0) {
995
+ const lastAiMsg = messages[messages.length - 1];
996
+ lastAiMsg.remove();
997
+ }
998
+ showTyping(container);
999
+ } else if (data.type === 'status') {
1000
+ handleStatusEvent(data, container);
1001
+ } else if (data.type === 'done') {
1002
+ hideTyping();
1003
+ } else if (data.type === 'renamed') {
1004
+ const channel = channels.find(c => c.id === data.channelId);
1005
+ if (channel) {
1006
+ channel.name = data.newName;
1007
+ renderChannels();
1008
+ if (currentChannelId === data.channelId && channelNameEl) {
1009
+ channelNameEl.textContent = data.newName;
851
1010
  }
852
- } else if (data.type === 'error') {
853
- hideTyping();
854
- addMessage('错误: ' + data.content, 'ai');
855
- } else if (data.type === 'task_status') {
856
- handleTaskStatusEvent(data);
857
- } else if (data.type === 'workflow_step') {
858
- handleWorkflowStepEvent(data);
859
- } else if (data.type === 'workflow_loop') {
860
- handleWorkflowLoopEvent(data);
861
1011
  }
862
- } catch (parseErr) {
863
- console.error('[SSE] 解析错误', parseErr);
1012
+ } else if (data.type === 'error') {
1013
+ hideTyping();
1014
+ addMessage('错误: ' + data.content, 'ai', true, container);
1015
+ } else if (data.type === 'task_status') {
1016
+ handleTaskStatusEvent(data, container);
1017
+ } else if (data.type === 'workflow_step') {
1018
+ handleWorkflowStepEvent(data, container);
1019
+ } else if (data.type === 'workflow_loop') {
1020
+ handleWorkflowLoopEvent(data, container);
864
1021
  }
865
- };
1022
+ } catch (parseErr) {
1023
+ console.error('[SSE] 解析错误', parseErr);
1024
+ }
1025
+ };
866
1026
  }
867
1027
 
868
1028
  async function sendMessage() {
@@ -965,6 +1125,12 @@ if (newChannelBtn) {
965
1125
  });
966
1126
  }
967
1127
 
1128
+ if (newSessionBtn) {
1129
+ newSessionBtn.addEventListener('click', () => {
1130
+ createNewSession();
1131
+ });
1132
+ }
1133
+
968
1134
  if (newChannelInput) {
969
1135
  newChannelInput.addEventListener('keydown', (e) => {
970
1136
  if (e.key === 'Enter') {