@bolloon/bolloon-agent 0.1.36 → 0.1.37

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 (530) hide show
  1. package/dist/web/client.js +2861 -3746
  2. package/dist/web/components/p2p/index.js +226 -264
  3. package/dist/web/ui/message-renderer.js +323 -434
  4. package/dist/web/ui/step-timeline.js +255 -351
  5. package/package.json +2 -2
  6. package/.auto-evolve-calls +0 -1
  7. package/.last-auto-evolve-baseline +0 -1
  8. package/.playwright-mcp/page-2026-06-16T07-51-45-706Z.yml +0 -130
  9. package/.playwright-mcp/page-2026-06-16T07-56-44-116Z.yml +0 -131
  10. package/Bolloon.md +0 -144
  11. package/Dive-into/CITATION.cff +0 -17
  12. package/Dive-into/LICENSE +0 -25
  13. package/Dive-into/README.md +0 -598
  14. package/Dive-into/README_zh.md +0 -599
  15. package/Dive-into/assets/context.png +0 -0
  16. package/Dive-into/assets/extensibility.png +0 -0
  17. package/Dive-into/assets/iteration.png +0 -0
  18. package/Dive-into/assets/layered_architecture.png +0 -0
  19. package/Dive-into/assets/main_structure.png +0 -0
  20. package/Dive-into/assets/permission.png +0 -0
  21. package/Dive-into/assets/session_compact.png +0 -0
  22. package/Dive-into/assets/subagent.png +0 -0
  23. package/Dive-into/paper/Dive_into_Claude_Code.pdf +0 -0
  24. package/dist/agents/constraint-layer.js.map +0 -1
  25. package/dist/agents/pi-sdk.js.map +0 -1
  26. package/dist/agents/workflow-engine.js.map +0 -1
  27. package/dist/bollharness/src/index.js +0 -5
  28. package/dist/bollharness/src/scripts/checks/check_adr_plan_numbering.js +0 -6
  29. package/dist/bollharness/src/scripts/checks/check_api_types.js +0 -45
  30. package/dist/bollharness/src/scripts/checks/check_artifact_link.js +0 -146
  31. package/dist/bollharness/src/scripts/checks/check_bridge_deps.js +0 -6
  32. package/dist/bollharness/src/scripts/checks/check_bugfix_binding.js +0 -6
  33. package/dist/bollharness/src/scripts/checks/check_bugfix_binding_ci.js +0 -6
  34. package/dist/bollharness/src/scripts/checks/check_doc_file_references.js +0 -6
  35. package/dist/bollharness/src/scripts/checks/check_doc_freshness.js +0 -135
  36. package/dist/bollharness/src/scripts/checks/check_doc_links.js +0 -31
  37. package/dist/bollharness/src/scripts/checks/check_file_existence_claims.js +0 -6
  38. package/dist/bollharness/src/scripts/checks/check_fragment_integrity.js +0 -34
  39. package/dist/bollharness/src/scripts/checks/check_hook_installed.js +0 -63
  40. package/dist/bollharness/src/scripts/checks/check_issue_closure.js +0 -41
  41. package/dist/bollharness/src/scripts/checks/check_mcp_parity.js +0 -6
  42. package/dist/bollharness/src/scripts/checks/check_security.js +0 -48
  43. package/dist/bollharness/src/scripts/checks/check_skill_parity.js +0 -6
  44. package/dist/bollharness/src/scripts/checks/check_versions.js +0 -6
  45. package/dist/bollharness/src/scripts/checks/finding.js +0 -13
  46. package/dist/bollharness/src/scripts/checks/next_decision_number.js +0 -20
  47. package/dist/bollharness/src/scripts/checks/regenerate_magic_docs.js +0 -6
  48. package/dist/bollharness/src/scripts/ci/detect_rebaseline_triggers.js +0 -8
  49. package/dist/bollharness/src/scripts/ci/scan_subprocess_cfg.js +0 -8
  50. package/dist/bollharness/src/scripts/ci/scan_verify_artifacts.js +0 -8
  51. package/dist/bollharness/src/scripts/ci/scan_yaml_schema.js +0 -8
  52. package/dist/bollharness/src/scripts/context_router.js +0 -67
  53. package/dist/bollharness/src/scripts/deploy-guard.js +0 -157
  54. package/dist/bollharness/src/scripts/guard-feedback.js +0 -192
  55. package/dist/bollharness/src/scripts/guard_router.js +0 -158
  56. package/dist/bollharness/src/scripts/hooks/_hook_output.js +0 -6
  57. package/dist/bollharness/src/scripts/hooks/auto-python3.js +0 -6
  58. package/dist/bollharness/src/scripts/hooks/deploy-progress-on-session-end.js +0 -6
  59. package/dist/bollharness/src/scripts/hooks/failure-analyzer.js +0 -6
  60. package/dist/bollharness/src/scripts/hooks/gate-judgment-inject.js +0 -92
  61. package/dist/bollharness/src/scripts/hooks/gate-transition-judgment.js +0 -63
  62. package/dist/bollharness/src/scripts/hooks/inbox-ack.js +0 -6
  63. package/dist/bollharness/src/scripts/hooks/inbox-inject-on-start.js +0 -6
  64. package/dist/bollharness/src/scripts/hooks/inbox-validate.js +0 -6
  65. package/dist/bollharness/src/scripts/hooks/inbox-write-ledger.js +0 -6
  66. package/dist/bollharness/src/scripts/hooks/initializer-agent.js +0 -6
  67. package/dist/bollharness/src/scripts/hooks/loop-detection.js +0 -73
  68. package/dist/bollharness/src/scripts/hooks/owner-guard.js +0 -6
  69. package/dist/bollharness/src/scripts/hooks/precompact.js +0 -6
  70. package/dist/bollharness/src/scripts/hooks/review-agent-gatekeeper.js +0 -6
  71. package/dist/bollharness/src/scripts/hooks/risk-tracker.js +0 -108
  72. package/dist/bollharness/src/scripts/hooks/sanitize-on-read.js +0 -6
  73. package/dist/bollharness/src/scripts/hooks/session-reflection.js +0 -7
  74. package/dist/bollharness/src/scripts/hooks/session-start-magic-docs.js +0 -7
  75. package/dist/bollharness/src/scripts/hooks/session-start-reset-risk.js +0 -7
  76. package/dist/bollharness/src/scripts/hooks/session-start-toolkit-reminder.js +0 -7
  77. package/dist/bollharness/src/scripts/hooks/stop-evaluator.js +0 -157
  78. package/dist/bollharness/src/scripts/hooks/tool-call-counter.js +0 -6
  79. package/dist/bollharness/src/scripts/hooks/trace-analyzer.js +0 -10
  80. package/dist/bollharness/src/scripts/install/install-trust-token.js +0 -7
  81. package/dist/bollharness/src/scripts/install/multi_project_registry.js +0 -9
  82. package/dist/bollharness/src/scripts/install/phase2_auto.js +0 -21
  83. package/dist/bollharness/src/scripts/install/pre_commit_installer.js +0 -6
  84. package/dist/bollharness/src/scripts/install/tier_selector.js +0 -7
  85. package/dist/bollharness/src/scripts/install/transcript_miner.js +0 -7
  86. package/dist/bollharness/src/scripts/lib/claim_patterns.js +0 -10
  87. package/dist/bollharness/src/scripts/lib/sanitize_patterns.js +0 -12
  88. package/dist/bollharness/src/scripts/sanitize.js +0 -6
  89. package/dist/bollharness-integration/context-router-judgment.js.map +0 -1
  90. package/dist/bollharness-integration/context-router.js.map +0 -1
  91. package/dist/bollharness-integration/gate-state-machine.js.map +0 -1
  92. package/dist/bollharness-integration/gate-transition-hooks.js.map +0 -1
  93. package/dist/bollharness-integration/guard-checker.js.map +0 -1
  94. package/dist/bollharness-integration/index.js.map +0 -1
  95. package/dist/bollharness-integration/integration.js.map +0 -1
  96. package/dist/bollharness-integration/llm/pi-ai.d.ts +0 -60
  97. package/dist/bollharness-integration/pi-ecosystem-colony/index.d.ts +0 -153
  98. package/dist/bollharness-integration/pi-ecosystem-goals/index.d.ts +0 -136
  99. package/dist/bollharness-integration/pi-ecosystem-judgment/decision.d.ts +0 -117
  100. package/dist/bollharness-integration/pi-ecosystem-judgment/distillation.d.ts +0 -78
  101. package/dist/bollharness-integration/pi-ecosystem-judgment/index.d.ts +0 -139
  102. package/dist/bollharness-integration/pi-ecosystem-mcp/index.d.ts +0 -127
  103. package/dist/bollharness-integration/pi-ecosystem-subagents/index.d.ts +0 -95
  104. package/dist/bollharness-integration/skill-adapter.js.map +0 -1
  105. package/dist/constraint-runtime/src/_archive_helper.js +0 -9
  106. package/dist/constraint-runtime/src/agent/coordinator.js +0 -48
  107. package/dist/constraint-runtime/src/agent/index.js +0 -1
  108. package/dist/constraint-runtime/src/assistant/index.js +0 -12
  109. package/dist/constraint-runtime/src/bootstrap/index.js +0 -12
  110. package/dist/constraint-runtime/src/bootstrap_graph.js +0 -13
  111. package/dist/constraint-runtime/src/bridge/index.js +0 -12
  112. package/dist/constraint-runtime/src/buddy/index.js +0 -12
  113. package/dist/constraint-runtime/src/cli/index.js +0 -12
  114. package/dist/constraint-runtime/src/command_graph.js +0 -10
  115. package/dist/constraint-runtime/src/commands.js +0 -60
  116. package/dist/constraint-runtime/src/components/index.js +0 -12
  117. package/dist/constraint-runtime/src/constants/index.js +0 -12
  118. package/dist/constraint-runtime/src/constraint/budget.js +0 -22
  119. package/dist/constraint-runtime/src/constraint/budget.js.map +0 -1
  120. package/dist/constraint-runtime/src/constraint/index.js +0 -2
  121. package/dist/constraint-runtime/src/constraint/permission.js +0 -20
  122. package/dist/constraint-runtime/src/constraint/permission.js.map +0 -1
  123. package/dist/constraint-runtime/src/context.js +0 -30
  124. package/dist/constraint-runtime/src/coordinator/index.js +0 -12
  125. package/dist/constraint-runtime/src/cost_hook.js +0 -4
  126. package/dist/constraint-runtime/src/cost_tracker.js +0 -8
  127. package/dist/constraint-runtime/src/deferred_init.js +0 -10
  128. package/dist/constraint-runtime/src/direct_modes.js +0 -6
  129. package/dist/constraint-runtime/src/dynamic-tool-loader.js +0 -85
  130. package/dist/constraint-runtime/src/entrypoints/index.js +0 -12
  131. package/dist/constraint-runtime/src/execution_registry.js +0 -44
  132. package/dist/constraint-runtime/src/history.js +0 -9
  133. package/dist/constraint-runtime/src/hooks/index.js +0 -12
  134. package/dist/constraint-runtime/src/index.js +0 -26
  135. package/dist/constraint-runtime/src/ink.js +0 -4
  136. package/dist/constraint-runtime/src/keybindings/index.js +0 -12
  137. package/dist/constraint-runtime/src/memdir/index.js +0 -12
  138. package/dist/constraint-runtime/src/migrations/index.js +0 -12
  139. package/dist/constraint-runtime/src/models.js +0 -1
  140. package/dist/constraint-runtime/src/models.js.map +0 -1
  141. package/dist/constraint-runtime/src/moreright/index.js +0 -12
  142. package/dist/constraint-runtime/src/native_ts/index.js +0 -12
  143. package/dist/constraint-runtime/src/output_styles/index.js +0 -12
  144. package/dist/constraint-runtime/src/parity_audit.js +0 -12
  145. package/dist/constraint-runtime/src/plugins/index.js +0 -12
  146. package/dist/constraint-runtime/src/port_manifest.js +0 -11
  147. package/dist/constraint-runtime/src/prefetch.js +0 -9
  148. package/dist/constraint-runtime/src/query.js +0 -1
  149. package/dist/constraint-runtime/src/remote/index.js +0 -12
  150. package/dist/constraint-runtime/src/remote_runtime.js +0 -9
  151. package/dist/constraint-runtime/src/runtime/index.js +0 -1
  152. package/dist/constraint-runtime/src/runtime/session.js +0 -35
  153. package/dist/constraint-runtime/src/schemas/index.js +0 -12
  154. package/dist/constraint-runtime/src/screens/index.js +0 -12
  155. package/dist/constraint-runtime/src/server/index.js +0 -12
  156. package/dist/constraint-runtime/src/services/index.js +0 -12
  157. package/dist/constraint-runtime/src/session_store.js +0 -22
  158. package/dist/constraint-runtime/src/setup.js +0 -30
  159. package/dist/constraint-runtime/src/skills/index.js +0 -1
  160. package/dist/constraint-runtime/src/skills/skill-registry.js +0 -28
  161. package/dist/constraint-runtime/src/state/index.js +0 -12
  162. package/dist/constraint-runtime/src/system_init.js +0 -20
  163. package/dist/constraint-runtime/src/thinking/engine.js +0 -42
  164. package/dist/constraint-runtime/src/thinking/index.js +0 -1
  165. package/dist/constraint-runtime/src/tool_pool.js +0 -8
  166. package/dist/constraint-runtime/src/tools/OpenCLI/execAdapter.js +0 -7
  167. package/dist/constraint-runtime/src/tools/OpenCLI/listAdapters.js +0 -7
  168. package/dist/constraint-runtime/src/tools/OpenCLI/runCommand.js +0 -7
  169. package/dist/constraint-runtime/src/tools/PolymarketSDK/cancelOrder.js +0 -6
  170. package/dist/constraint-runtime/src/tools/PolymarketSDK/createOrder.js +0 -6
  171. package/dist/constraint-runtime/src/tools/PolymarketSDK/getMarket.js +0 -5
  172. package/dist/constraint-runtime/src/tools/PolymarketSDK/getOrders.js +0 -6
  173. package/dist/constraint-runtime/src/tools/PolymarketSDK/listMarkets.js +0 -4
  174. package/dist/constraint-runtime/src/tools/SafeSDK/confirmTransaction.js +0 -6
  175. package/dist/constraint-runtime/src/tools/SafeSDK/createTransaction.js +0 -8
  176. package/dist/constraint-runtime/src/tools/SafeSDK/deploySafe.js +0 -6
  177. package/dist/constraint-runtime/src/tools/SafeSDK/executeTransaction.js +0 -6
  178. package/dist/constraint-runtime/src/tools/SafeSDK/getBalance.js +0 -6
  179. package/dist/constraint-runtime/src/tools/SafeSDK/getPendingTransactions.js +0 -6
  180. package/dist/constraint-runtime/src/tools/SafeSDK/proposeTransaction.js +0 -6
  181. package/dist/constraint-runtime/src/tools/WalletTools/autoPay.js +0 -29
  182. package/dist/constraint-runtime/src/tools/WalletTools/createWallet.js +0 -10
  183. package/dist/constraint-runtime/src/tools/WalletTools/getBalance.js +0 -13
  184. package/dist/constraint-runtime/src/tools/WalletTools/importWallet.js +0 -22
  185. package/dist/constraint-runtime/src/tools/WalletTools/sendTransaction.js +0 -25
  186. package/dist/constraint-runtime/src/tools/WalletTools/signMessage.js +0 -10
  187. package/dist/constraint-runtime/src/tools/WalletTools/transferToken.js +0 -25
  188. package/dist/constraint-runtime/src/tools.js +0 -80
  189. package/dist/constraint-runtime/src/transcript.js +0 -19
  190. package/dist/constraint-runtime/src/types/index.js +0 -12
  191. package/dist/constraint-runtime/src/upstream_proxy/index.js +0 -12
  192. package/dist/constraint-runtime/src/utils/index.js +0 -12
  193. package/dist/constraint-runtime/src/vim/index.js +0 -12
  194. package/dist/constraint-runtime/src/voice/index.js +0 -12
  195. package/dist/constraints/index.js.map +0 -1
  196. package/dist/documents/reader.js.map +0 -1
  197. package/dist/llm/config-store.js.map +0 -1
  198. package/dist/llm/pi-ai.js.map +0 -1
  199. package/dist/network/agent-network.js.map +0 -1
  200. package/dist/network/iroh-integration.js.map +0 -1
  201. package/dist/network/iroh-transport.js.map +0 -1
  202. package/dist/network/p2p.js.map +0 -1
  203. package/dist/network/storage/adapters/json-adapter.js.map +0 -1
  204. package/dist/pi-ecosystem-colony/index.js.map +0 -1
  205. package/dist/pi-ecosystem-goals/index.js.map +0 -1
  206. package/dist/pi-ecosystem-judgment/decision.js.map +0 -1
  207. package/dist/pi-ecosystem-judgment/distillation.js.map +0 -1
  208. package/dist/pi-ecosystem-judgment/human-value-store.js.map +0 -1
  209. package/dist/pi-ecosystem-judgment/index.js.map +0 -1
  210. package/dist/pi-ecosystem-judgment/value-injection.js.map +0 -1
  211. package/dist/pi-ecosystem-mcp/index.js.map +0 -1
  212. package/dist/pi-ecosystem-subagents/index.js.map +0 -1
  213. package/dist/social/ant-colony/AdaptiveHeartbeat.js.map +0 -1
  214. package/dist/social/ant-colony/PheromoneEngine.js.map +0 -1
  215. package/dist/social/ant-colony/types.js.map +0 -1
  216. package/dist/social/channels/ChannelManager.js.map +0 -1
  217. package/dist/social/channels/DiapChannelBridge.js.map +0 -1
  218. package/dist/social/channels/InterestMatcher.js.map +0 -1
  219. package/dist/social/channels/types.js.map +0 -1
  220. package/dist/social/global-shared-context.js.map +0 -1
  221. package/dist/social/heartbeat.js.map +0 -1
  222. package/dist/web/components/p2p/P2PModal.js +0 -188
  223. package/dist/web/components/p2p/p2p-modal.js +0 -657
  224. package/dist/web/components/p2p/p2p-tools.js +0 -248
  225. package/lefthook.yml +0 -33
  226. package/scripts/auto-evolve-loop.ts +0 -481
  227. package/scripts/auto-evolve-oneshot.sh +0 -155
  228. package/scripts/auto-evolve-snapshot.sh +0 -136
  229. package/scripts/build-cli.js +0 -216
  230. package/scripts/build-web.ts +0 -116
  231. package/scripts/detect-schema-changes.sh +0 -48
  232. package/scripts/diff-reviewer.ts +0 -159
  233. package/scripts/postinstall.js +0 -153
  234. package/scripts/validate-system-prompt.ts +0 -142
  235. package/scripts/weekly-report.ts +0 -364
  236. package/src/agents/agent-manifest-protocol.ts +0 -117
  237. package/src/agents/constraint-layer.ts +0 -309
  238. package/src/agents/iroh-secret.ts +0 -32
  239. package/src/agents/p2p-chat-tools.ts +0 -383
  240. package/src/agents/p2p-document-tools.ts +0 -347
  241. package/src/agents/permission-mode.ts +0 -127
  242. package/src/agents/pi-sdk.ts +0 -2895
  243. package/src/agents/pre-tool-validator.ts +0 -213
  244. package/src/agents/protocol.ts +0 -398
  245. package/src/agents/shell-guard.ts +0 -417
  246. package/src/agents/shell-tool.ts +0 -103
  247. package/src/agents/skill-loader.ts +0 -202
  248. package/src/agents/subagent-manager.ts +0 -553
  249. package/src/agents/workflow-engine.ts +0 -332
  250. package/src/agents/workflow-pivot-loop.ts +0 -766
  251. package/src/bollharness/.sanitize-report.json +0 -13
  252. package/src/bollharness/CLAUDE.md +0 -73
  253. package/src/bollharness/LICENSE +0 -21
  254. package/src/bollharness/README.md +0 -143
  255. package/src/bollharness/README.zh-CN.md +0 -131
  256. package/src/bollharness/package.json +0 -20
  257. package/src/bollharness/reference/SOURCE-COMMIT.txt +0 -3
  258. package/src/bollharness/reference/boll-reference/scripts/hooks/.sanitize-report.json +0 -12
  259. package/src/bollharness/reference/boll-reference/scripts/hooks/find-boll-root.sh +0 -27
  260. package/src/bollharness/reference/boll-reference/scripts/hooks/precompact.sh +0 -57
  261. package/src/bollharness/reference/boll-reference/scripts/hooks/stop-evaluator.md +0 -57
  262. package/src/bollharness/schemas/metrics-jsonl-allowlist.json +0 -67
  263. package/src/bollharness/scripts/checks/next_decision_number.sh +0 -48
  264. package/src/bollharness/scripts/ci/count-components.sh +0 -65
  265. package/src/bollharness/scripts/context-fragments/artifact-linkage.md +0 -14
  266. package/src/bollharness/scripts/context-fragments/auth-consumers.md +0 -17
  267. package/src/bollharness/scripts/context-fragments/bridge-constitution.md +0 -13
  268. package/src/bollharness/scripts/context-fragments/catalyst-distributed.md +0 -18
  269. package/src/bollharness/scripts/context-fragments/closure-checklist.md +0 -13
  270. package/src/bollharness/scripts/context-fragments/contract-consumers.md +0 -15
  271. package/src/bollharness/scripts/context-fragments/db-shared-structures.md +0 -15
  272. package/src/bollharness/scripts/context-fragments/fixed-three-layers.md +0 -19
  273. package/src/bollharness/scripts/context-fragments/general-dev-principles.md +0 -11
  274. package/src/bollharness/scripts/context-fragments/issue-first.md +0 -8
  275. package/src/bollharness/scripts/context-fragments/mcp-parity.md +0 -16
  276. package/src/bollharness/scripts/context-fragments/pi-agent-operations.md +0 -108
  277. package/src/bollharness/scripts/context-fragments/protocol-consumers.md +0 -15
  278. package/src/bollharness/scripts/context-fragments/run-events-consumers.md +0 -15
  279. package/src/bollharness/scripts/context-fragments/scene-fidelity.md +0 -13
  280. package/src/bollharness/scripts/context-fragments/truth-source-hierarchy.md +0 -15
  281. package/src/bollharness/scripts/context-fragments/two-language.md +0 -15
  282. package/src/bollharness/scripts/context-fragments/version-sources.md +0 -14
  283. package/src/bollharness/scripts/hooks/find-project-root.sh +0 -47
  284. package/src/bollharness/scripts/hooks/inbox-poll.sh +0 -78
  285. package/src/bollharness/scripts/hooks/precompact.sh +0 -56
  286. package/src/bollharness/scripts/hooks/stop-evaluator.md +0 -83
  287. package/src/bollharness/scripts/sync-from-upstream.sh +0 -281
  288. package/src/bollharness/src/index.ts +0 -5
  289. package/src/bollharness/src/scripts/checks/check_adr_plan_numbering.ts +0 -11
  290. package/src/bollharness/src/scripts/checks/check_api_types.ts +0 -52
  291. package/src/bollharness/src/scripts/checks/check_artifact_link.ts +0 -156
  292. package/src/bollharness/src/scripts/checks/check_bridge_deps.ts +0 -11
  293. package/src/bollharness/src/scripts/checks/check_bugfix_binding.ts +0 -11
  294. package/src/bollharness/src/scripts/checks/check_bugfix_binding_ci.ts +0 -11
  295. package/src/bollharness/src/scripts/checks/check_doc_file_references.ts +0 -11
  296. package/src/bollharness/src/scripts/checks/check_doc_freshness.ts +0 -141
  297. package/src/bollharness/src/scripts/checks/check_doc_links.ts +0 -36
  298. package/src/bollharness/src/scripts/checks/check_file_existence_claims.ts +0 -11
  299. package/src/bollharness/src/scripts/checks/check_fragment_integrity.ts +0 -40
  300. package/src/bollharness/src/scripts/checks/check_hook_installed.ts +0 -70
  301. package/src/bollharness/src/scripts/checks/check_issue_closure.ts +0 -51
  302. package/src/bollharness/src/scripts/checks/check_mcp_parity.ts +0 -11
  303. package/src/bollharness/src/scripts/checks/check_security.ts +0 -54
  304. package/src/bollharness/src/scripts/checks/check_skill_parity.ts +0 -11
  305. package/src/bollharness/src/scripts/checks/check_versions.ts +0 -11
  306. package/src/bollharness/src/scripts/checks/finding.ts +0 -35
  307. package/src/bollharness/src/scripts/checks/next_decision_number.ts +0 -24
  308. package/src/bollharness/src/scripts/checks/regenerate_magic_docs.ts +0 -11
  309. package/src/bollharness/src/scripts/ci/detect_rebaseline_triggers.ts +0 -14
  310. package/src/bollharness/src/scripts/ci/scan_subprocess_cfg.ts +0 -14
  311. package/src/bollharness/src/scripts/ci/scan_verify_artifacts.ts +0 -14
  312. package/src/bollharness/src/scripts/ci/scan_yaml_schema.ts +0 -14
  313. package/src/bollharness/src/scripts/context_router.ts +0 -76
  314. package/src/bollharness/src/scripts/deploy-guard.ts +0 -182
  315. package/src/bollharness/src/scripts/guard-feedback.ts +0 -215
  316. package/src/bollharness/src/scripts/guard_router.ts +0 -194
  317. package/src/bollharness/src/scripts/hooks/_hook_output.js +0 -3
  318. package/src/bollharness/src/scripts/hooks/_hook_output.ts +0 -11
  319. package/src/bollharness/src/scripts/hooks/auto-python3.ts +0 -10
  320. package/src/bollharness/src/scripts/hooks/deploy-progress-on-session-end.ts +0 -10
  321. package/src/bollharness/src/scripts/hooks/failure-analyzer.ts +0 -10
  322. package/src/bollharness/src/scripts/hooks/gate-judgment-inject.ts +0 -111
  323. package/src/bollharness/src/scripts/hooks/gate-transition-judgment.ts +0 -74
  324. package/src/bollharness/src/scripts/hooks/inbox-ack.ts +0 -10
  325. package/src/bollharness/src/scripts/hooks/inbox-inject-on-start.ts +0 -10
  326. package/src/bollharness/src/scripts/hooks/inbox-validate.ts +0 -10
  327. package/src/bollharness/src/scripts/hooks/inbox-write-ledger.ts +0 -10
  328. package/src/bollharness/src/scripts/hooks/initializer-agent.ts +0 -10
  329. package/src/bollharness/src/scripts/hooks/loop-detection.ts +0 -83
  330. package/src/bollharness/src/scripts/hooks/owner-guard.ts +0 -10
  331. package/src/bollharness/src/scripts/hooks/precompact.ts +0 -10
  332. package/src/bollharness/src/scripts/hooks/review-agent-gatekeeper.ts +0 -10
  333. package/src/bollharness/src/scripts/hooks/risk-tracker.ts +0 -121
  334. package/src/bollharness/src/scripts/hooks/sanitize-on-read.ts +0 -10
  335. package/src/bollharness/src/scripts/hooks/session-reflection.ts +0 -12
  336. package/src/bollharness/src/scripts/hooks/session-start-magic-docs.ts +0 -12
  337. package/src/bollharness/src/scripts/hooks/session-start-reset-risk.ts +0 -12
  338. package/src/bollharness/src/scripts/hooks/session-start-toolkit-reminder.ts +0 -12
  339. package/src/bollharness/src/scripts/hooks/stop-evaluator.ts +0 -164
  340. package/src/bollharness/src/scripts/hooks/tool-call-counter.ts +0 -10
  341. package/src/bollharness/src/scripts/hooks/trace-analyzer.ts +0 -14
  342. package/src/bollharness/src/scripts/install/install-trust-token.ts +0 -13
  343. package/src/bollharness/src/scripts/install/multi_project_registry.ts +0 -13
  344. package/src/bollharness/src/scripts/install/phase2_auto.ts +0 -28
  345. package/src/bollharness/src/scripts/install/pre_commit_installer.ts +0 -10
  346. package/src/bollharness/src/scripts/install/tier_selector.ts +0 -10
  347. package/src/bollharness/src/scripts/install/transcript_miner.ts +0 -13
  348. package/src/bollharness/src/scripts/lib/claim_patterns.ts +0 -11
  349. package/src/bollharness/src/scripts/lib/sanitize_patterns.ts +0 -13
  350. package/src/bollharness/src/scripts/sanitize.ts +0 -9
  351. package/src/bollharness/templates/persona/default.json +0 -19
  352. package/src/bollharness/templates/scaffold/.gitignore.append +0 -16
  353. package/src/bollharness/templates/scaffold/CLAUDE.md +0 -89
  354. package/src/bollharness-integration/channel-judgment-engine.ts +0 -634
  355. package/src/bollharness-integration/context-chain-router.ts +0 -474
  356. package/src/bollharness-integration/context-router-judgment.ts +0 -339
  357. package/src/bollharness-integration/context-router.ts +0 -583
  358. package/src/bollharness-integration/gate-state-machine.ts +0 -444
  359. package/src/bollharness-integration/gate-transition-hooks.ts +0 -137
  360. package/src/bollharness-integration/guard-checker.ts +0 -451
  361. package/src/bollharness-integration/index.ts +0 -195
  362. package/src/bollharness-integration/integration.ts +0 -538
  363. package/src/bollharness-integration/judgment-prompts.yaml +0 -535
  364. package/src/bollharness-integration/llm-judgment-engine.ts +0 -712
  365. package/src/bollharness-integration/skill-adapter.ts +0 -646
  366. package/src/bootstrap/bootstrap.ts +0 -135
  367. package/src/bootstrap/context-collector.ts +0 -371
  368. package/src/bootstrap/context-hierarchy.ts +0 -283
  369. package/src/bootstrap/lifecycle-hooks.ts +0 -289
  370. package/src/bootstrap/project-context.ts +0 -171
  371. package/src/cli/interface.ts +0 -211
  372. package/src/cli-entry.ts +0 -304
  373. package/src/constraints/index.ts +0 -6
  374. package/src/context-compaction/auto-compact.ts +0 -153
  375. package/src/context-compaction/budget-gate.ts +0 -32
  376. package/src/context-compaction/budget-reduce.ts +0 -37
  377. package/src/context-compaction/context-collapse.ts +0 -72
  378. package/src/context-compaction/index.ts +0 -24
  379. package/src/context-compaction/microcompact.ts +0 -54
  380. package/src/context-compaction/pipeline.ts +0 -133
  381. package/src/context-compaction/snip.ts +0 -51
  382. package/src/context-compaction/token-estimator.ts +0 -36
  383. package/src/context-compaction/types.ts +0 -99
  384. package/src/documents/reader.ts +0 -85
  385. package/src/documents/store.ts +0 -252
  386. package/src/electron-preload.ts +0 -25
  387. package/src/electron.ts +0 -200
  388. package/src/heartbeat/DaemonManager.ts +0 -283
  389. package/src/heartbeat/HealthMonitor.ts +0 -317
  390. package/src/heartbeat/StartupVerifier.ts +0 -223
  391. package/src/heartbeat/Watchdog.ts +0 -208
  392. package/src/heartbeat/index.ts +0 -109
  393. package/src/heartbeat/self-improve-bus.ts +0 -110
  394. package/src/heartbeat/types.ts +0 -82
  395. package/src/index.ts +0 -1724
  396. package/src/llm/audio-config-store.ts +0 -246
  397. package/src/llm/config-store.ts +0 -400
  398. package/src/llm/llm-judgment-client.ts +0 -471
  399. package/src/llm/pi-ai.ts +0 -653
  400. package/src/llm/system-prompt/health.ts +0 -159
  401. package/src/llm/system-prompt/layers/channel/local.md +0 -14
  402. package/src/llm/system-prompt/layers/channel/p2p-agent.md +0 -18
  403. package/src/llm/system-prompt/layers/channel/p2p-visitor.md +0 -19
  404. package/src/llm/system-prompt/layers/core/artifacts_storage.md +0 -89
  405. package/src/llm/system-prompt/layers/core/evenhandedness.md +0 -21
  406. package/src/llm/system-prompt/layers/core/hibs_reminders.md +0 -15
  407. package/src/llm/system-prompt/layers/core/identity.md +0 -37
  408. package/src/llm/system-prompt/layers/core/knowledge.md +0 -17
  409. package/src/llm/system-prompt/layers/core/memory_system.md +0 -12
  410. package/src/llm/system-prompt/layers/core/network_filesystem.md +0 -28
  411. package/src/llm/system-prompt/layers/core/refusal.md +0 -37
  412. package/src/llm/system-prompt/layers/core/tone.md +0 -31
  413. package/src/llm/system-prompt/layers/core/tools.thin.md +0 -13
  414. package/src/llm/system-prompt/layers/core/wellbeing.md +0 -41
  415. package/src/llm/system-prompt/layers/role/architect.md +0 -20
  416. package/src/llm/system-prompt/layers/role/expert.md +0 -19
  417. package/src/llm/system-prompt/layers/role/implementer.md +0 -15
  418. package/src/llm/system-prompt/layers/role/security.md +0 -15
  419. package/src/llm/system-prompt/layers/tool/artifacts.md +0 -72
  420. package/src/llm/system-prompt/layers/tool/bash.md +0 -25
  421. package/src/llm/system-prompt/layers/tool/hibs_api.md +0 -171
  422. package/src/llm/system-prompt/layers/tool/image_search.md +0 -70
  423. package/src/llm/system-prompt/layers/tool/manifest.md +0 -89
  424. package/src/llm/system-prompt/layers/tool/mcp_apps.md +0 -53
  425. package/src/llm/system-prompt/layers/tool/web_search.md +0 -83
  426. package/src/llm/system-prompt/registry.ts +0 -325
  427. package/src/llm/system-prompt/strip-hibsml.ts +0 -52
  428. package/src/llm/tool-manifest/ask_user_input.ts +0 -37
  429. package/src/llm/tool-manifest/bash.ts +0 -25
  430. package/src/llm/tool-manifest/create_file.ts +0 -26
  431. package/src/llm/tool-manifest/fetch_sports_data.ts +0 -28
  432. package/src/llm/tool-manifest/image_search.ts +0 -26
  433. package/src/llm/tool-manifest/index.ts +0 -88
  434. package/src/llm/tool-manifest/mcp.ts +0 -46
  435. package/src/llm/tool-manifest/message_compose.ts +0 -33
  436. package/src/llm/tool-manifest/places.ts +0 -86
  437. package/src/llm/tool-manifest/present_files.ts +0 -23
  438. package/src/llm/tool-manifest/recipe.ts +0 -42
  439. package/src/llm/tool-manifest/recommend_apps.ts +0 -25
  440. package/src/llm/tool-manifest/str_replace.ts +0 -29
  441. package/src/llm/tool-manifest/types.ts +0 -52
  442. package/src/llm/tool-manifest/view.ts +0 -26
  443. package/src/llm/tool-manifest/weather.ts +0 -29
  444. package/src/llm/tool-manifest/web.ts +0 -54
  445. package/src/llm/video-config-store.ts +0 -257
  446. package/src/network/agent-network.ts +0 -800
  447. package/src/network/hybrid-messenger.ts +0 -199
  448. package/src/network/iroh-bootstrap.ts +0 -57
  449. package/src/network/iroh-discovery.ts +0 -208
  450. package/src/network/iroh-integration.ts +0 -158
  451. package/src/network/iroh-transport.ts +0 -637
  452. package/src/network/known-peers.ts +0 -102
  453. package/src/network/p2p-direct.ts +0 -262
  454. package/src/network/p2p-secret.ts +0 -153
  455. package/src/network/p2p.ts +0 -964
  456. package/src/network/source-intent-broadcaster.ts +0 -242
  457. package/src/network/source-intent.ts +0 -167
  458. package/src/network/storage/adapters/json-adapter.ts +0 -454
  459. package/src/network/storage/index.ts +0 -203
  460. package/src/network/storage/types.ts +0 -166
  461. package/src/security/builtin-guards.ts +0 -162
  462. package/src/security/context-router-tool.ts +0 -122
  463. package/src/security/input-scanner.ts +0 -287
  464. package/src/security/react-harness.ts +0 -177
  465. package/src/security/tool-gate.ts +0 -294
  466. package/src/social/ant-colony/index.js +0 -19
  467. package/src/social/channels/ChannelManager.ts +0 -485
  468. package/src/social/channels/DiapChannelBridge.ts +0 -501
  469. package/src/social/channels/InterestMatcher.ts +0 -189
  470. package/src/social/channels/agent-workflow-config.json +0 -214
  471. package/src/social/channels/agent-workflow-config.yaml +0 -334
  472. package/src/social/channels/channel-agent-session.ts +0 -407
  473. package/src/social/channels/channel-heartbeat-agent.ts +0 -622
  474. package/src/social/channels/diap-doc-parser.ts +0 -282
  475. package/src/social/channels/harness-workflow-integrator.ts +0 -594
  476. package/src/social/channels/index.ts +0 -22
  477. package/src/social/channels/types.ts +0 -115
  478. package/src/social/global-shared-context.ts +0 -506
  479. package/src/social/heartbeat.ts +0 -1057
  480. package/src/social/persona/enhanced-persona.ts +0 -359
  481. package/src/types.d.ts +0 -12
  482. package/src/utils/auto-evolve-policy.ts +0 -138
  483. package/src/utils/auto-update.ts +0 -482
  484. package/src/utils/clamp.ts +0 -5
  485. package/src/web/agent-delegate-server.ts +0 -148
  486. package/src/web/api-config.html +0 -520
  487. package/src/web/client.js +0 -2352
  488. package/src/web/client.ts +0 -4326
  489. package/src/web/components/p2p/P2PModal.tsx +0 -416
  490. package/src/web/components/p2p/index.ts +0 -566
  491. package/src/web/components/p2p/index.tsx +0 -297
  492. package/src/web/components/p2p/p2p-connection.ts +0 -338
  493. package/src/web/components/p2p/p2p-identity.ts +0 -92
  494. package/src/web/components/p2p/p2p-manager.ts +0 -147
  495. package/src/web/components/p2p/p2p-messages.ts +0 -219
  496. package/src/web/components/p2p/p2p-modal.ts +0 -685
  497. package/src/web/components/p2p/p2p-store-memory.ts +0 -162
  498. package/src/web/components/p2p/p2p-tools.ts +0 -315
  499. package/src/web/components/p2p/types.ts +0 -170
  500. package/src/web/components/wallet-viem.mjs +0 -118
  501. package/src/web/design.md +0 -99
  502. package/src/web/icons/apple-touch-icon.png +0 -0
  503. package/src/web/icons/favicon-16x16.png +0 -0
  504. package/src/web/icons/favicon-192x192.png +0 -0
  505. package/src/web/icons/favicon-32x32.png +0 -0
  506. package/src/web/icons/favicon-48x48.png +0 -0
  507. package/src/web/icons/favicon-512x512.png +0 -0
  508. package/src/web/icons/favicon.icns +0 -0
  509. package/src/web/icons/favicon.ico +0 -0
  510. package/src/web/icons/icon.png +0 -0
  511. package/src/web/icons/image.png +0 -0
  512. package/src/web/index.html +0 -373
  513. package/src/web/iroh-delegate-transport.ts +0 -139
  514. package/src/web/manifest.json +0 -21
  515. package/src/web/server.ts +0 -5731
  516. package/src/web/style.css +0 -4737
  517. package/src/web/ui/message-renderer.ts +0 -540
  518. package/src/web/ui/step-timeline.ts +0 -394
  519. package/staging/auto-evolve/clean-001/.review-verdict +0 -9
  520. package/staging/auto-evolve/clean-001/clean-001.patch +0 -14
  521. package/staging/auto-evolve/e2e-001/.patch-id +0 -1
  522. package/staging/auto-evolve/e2e-001/.review-verdict +0 -12
  523. package/staging/auto-evolve/e2e-001/e2e-001.patch +0 -11
  524. package/staging/auto-evolve/test-bad/.review-verdict +0 -12
  525. package/staging/auto-evolve/test-bad/test-bad.patch +0 -11
  526. package/test-results/.last-run.json +0 -6
  527. package/test-results/src-test-web-loop-status-b-5734c-atus-bar-/346/230/276/347/244/272-spinner-/344/270/215/346/230/276/347/244/272/345/276/252/347/216/257/350/256/241/346/225/260/error-context.md +0 -285
  528. package/tsconfig.cli.json +0 -16
  529. package/tsconfig.electron.json +0 -20
  530. package/tsconfig.json +0 -18
@@ -1,463 +1,352 @@
1
- /**
2
- * message-renderer.ts — 对话显示 UI (2026-06-15 从 client.js 拆出, .js → .ts)
3
- *
4
- * 职责 (单一):
5
- * - 把 user / AI 内容渲染成 DOM 气泡 (含 marked.parse 渲染)
6
- * - 处理流式 token 累积 (textNode 增量, O(1), 不重排)
7
- * - finalize 流式消息为正式 AI 气泡
8
- * - 折叠 think / environment_details 块
9
- * - 复制 / 重新回答 / 蒸馏为判断 按钮
10
- * - 挂载 step-timeline (2026-06-15) 步骤状态条到每条 AI 消息内
11
- *
12
- * 状态 (本模块私有):
13
- * - streamingMessageEl / streamingTextNode / streamingText
14
- * - lastUserCommand / lastAiContent (去重)
15
- *
16
- * 依赖 (import):
17
- * - 浏览器 API (document, marked, fetch, navigator)
18
- * - ./step-timeline (4 状态步骤条模块)
19
- *
20
- * 不依赖 (零业务 import, 防循环):
21
- * - 不 import client.js
22
- * - 不 import 任何业务模块
23
- *
24
- * 输入 (从 client.js 调用):
25
- * - addMessage(content, type, save, container, usedIds, ctx)
26
- * - handleStreamTokenEvent({ streamType, content }, ctx)
27
- * - finalizeTimelineAsMessage(ctx)
28
- * - handleStepEvent({ type: 'step_start'|'step_done'|'step_error', ... }, ctx)
29
- * - escapeHtml(s)
30
- * - getMessagesContainerForCurrent(currentChannelId, messagesContainers, messagesEl)
31
- *
32
- * 输出 (DOM):
33
- * - .message / .bubble / .think-container / .env-container
34
- * - .message-streaming (流式期间, finalize 时移除)
35
- * - .message-actions (复制/重新回答/蒸馏按钮)
36
- * - .used-judgments-link (P0.5 反向引用)
37
- * - .step-timeline (气泡内步骤状态条, 由 ./step-timeline 渲染)
38
- */
39
- // ---------------------------------------------------------------------------
40
- // 类型定义
41
- // ---------------------------------------------------------------------------
42
- import { mountStepTimeline, pushStepToTimeline, migrateStepTimeline, getStepTimeline, } from './step-timeline.js';
43
- // ---------------------------------------------------------------------------
44
- // 模块私有状态
45
- // ---------------------------------------------------------------------------
1
+ import {
2
+ mountStepTimeline,
3
+ pushStepToTimeline,
4
+ migrateStepTimeline,
5
+ getStepTimeline
6
+ } from "./step-timeline.js";
46
7
  let streamingMessageEl = null;
47
8
  let streamingTextNode = null;
48
- let streamingText = '';
49
- let lastUserCommand = '';
50
- let lastAiContent = '';
51
- // 滚动限频 (60ms 16fps, 减 reflow)
9
+ let streamingText = "";
10
+ let lastUserCommand = "";
11
+ let lastAiContent = "";
52
12
  let scrollToBottomTimer = null;
53
13
  function scheduleScrollToBottom(container) {
54
- if (!container)
55
- return;
56
- if (scrollToBottomTimer)
57
- return;
58
- scrollToBottomTimer = setTimeout(() => {
59
- container.scrollTop = container.scrollHeight;
60
- scrollToBottomTimer = null;
61
- }, 60);
14
+ if (!container) return;
15
+ if (scrollToBottomTimer) return;
16
+ scrollToBottomTimer = setTimeout(() => {
17
+ container.scrollTop = container.scrollHeight;
18
+ scrollToBottomTimer = null;
19
+ }, 60);
62
20
  }
63
- // ---------------------------------------------------------------------------
64
- // 容器选择 (主入口或 per-channel 容器)
65
- // ---------------------------------------------------------------------------
66
- export function getMessagesContainerForCurrent(currentChannelId, messagesContainers, messagesEl) {
67
- if (currentChannelId && messagesContainers.get(currentChannelId)) {
68
- return messagesContainers.get(currentChannelId) || null;
69
- }
70
- return messagesEl;
21
+ function getMessagesContainerForCurrent(currentChannelId, messagesContainers, messagesEl) {
22
+ if (currentChannelId && messagesContainers.get(currentChannelId)) {
23
+ return messagesContainers.get(currentChannelId) || null;
24
+ }
25
+ return messagesEl;
71
26
  }
72
- // ---------------------------------------------------------------------------
73
- // HTML escape ( think / env 折叠块用)
74
- // ---------------------------------------------------------------------------
75
- export function escapeHtml(s) {
76
- return String(s ?? '').replace(/[&<>"']/g, (c) => ({
77
- '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;'
78
- }[c]));
27
+ function escapeHtml(s) {
28
+ return String(s ?? "").replace(/[&<>"']/g, (c) => ({
29
+ "&": "&amp;",
30
+ "<": "&lt;",
31
+ ">": "&gt;",
32
+ '"': "&quot;",
33
+ "'": "&#39;"
34
+ })[c]);
79
35
  }
80
- // ---------------------------------------------------------------------------
81
- // 主入口: 渲染一条消息气泡 (user / ai / system)
82
- // ---------------------------------------------------------------------------
83
- export function addMessage(content, type, save = true, container, usedJudgmentIds = [], ctx = { messagesEl: null, messagesContainers: new Map(), currentChannelId: null }) {
84
- const messagesEl = ctx.messagesEl || (typeof document !== 'undefined' ? document.getElementById('messages') : null);
85
- const messagesContainers = ctx.messagesContainers || new Map();
86
- const currentChannelId = ctx.currentChannelId;
87
- const msgContainer = container || getMessagesContainerForCurrent(currentChannelId, messagesContainers, messagesEl);
88
- // 内存保护: 单个 channel 容器超过 200 条, 旧会话加载时淘汰最旧
89
- if (!save && msgContainer && msgContainer.children.length > 200) {
90
- const toRemove = msgContainer.children.length - 200;
91
- for (let i = 0; i < toRemove; i++) {
92
- const first = msgContainer.firstElementChild;
93
- if (first)
94
- msgContainer.removeChild(first);
95
- }
96
- }
97
- // 去重 (save=true 时)
98
- if (save) {
99
- const lastContent = type === 'user' ? lastUserCommand : lastAiContent;
100
- if (lastContent && content === lastContent) {
101
- console.log(`[addMessage] 跳过重复的 ${type} 消息`);
102
- return;
103
- }
104
- if (type === 'user')
105
- lastUserCommand = content;
106
- else
107
- lastAiContent = content;
108
- }
109
- const div = document.createElement('div');
110
- div.className = `message message-${type}`;
111
- // 清理: 移除 tool_call 标记
112
- let cleanContent = content
113
- .replace(/\[TOOL_CALL\][\s\S]*?\[\/TOOL_CALL\]/g, '')
114
- .replace(/TOOL_CALL[\s\S]*?\/TOOL_CALL/g, '')
115
- .replace(/<tool_call>[\s\S]*?<\/tool_call>/gi, '')
116
- .replace(/\{\s*"tool":[\s\S]*?\}/g, '')
117
- .replace(/\{\s*tool\s*=>\s*["'][^"']+["']\s*(?:,\s*args\s*=>\s*\{[\s\S]*?\})?\s*\}/g, '')
118
- .replace(/\[Function[^\]]*\]\s*/g, '')
119
- .trim();
120
- // think 折叠
121
- const thinkMatch = cleanContent.match(/<think>([\s\S]*?)<\/think>/);
122
- let mainContent = cleanContent;
123
- let thinkContainer = null;
124
- if (thinkMatch) {
125
- const thinkContent = thinkMatch[1].trim();
126
- mainContent = cleanContent.replace(/<think>[\s\S]*?<\/think>/, '').trim();
127
- thinkContainer = buildThinkContainer(thinkContent);
128
- }
129
- // environment_details 折叠 + 身份头
130
- const envMatch = mainContent.match(/^(.+?)\n<environment_details>([\s\S]*?)<\/environment_details>\n([\s\S]*)$/);
131
- if (envMatch) {
132
- const identity = envMatch[1].trim();
133
- const envDetails = envMatch[2].trim();
134
- const messageBody = envMatch[3].trim();
135
- const header = document.createElement('div');
136
- header.className = 'message-header';
137
- header.textContent = identity;
138
- div.appendChild(header);
139
- div.appendChild(buildEnvContainer(envDetails));
140
- if (thinkContainer)
141
- div.appendChild(thinkContainer);
142
- if (messageBody)
143
- div.appendChild(buildBubble(messageBody, type));
144
- }
145
- else if (cleanContent) {
146
- if (thinkContainer)
147
- div.appendChild(thinkContainer);
148
- div.appendChild(buildBubble(cleanContent, type));
149
- }
150
- else {
151
- return; // 空内容, 不上屏
152
- }
153
- // 纯文本用于复制按钮
154
- const rawContent = cleanContent
155
- .replace(/<[^>]+>/g, '')
156
- .replace(/&lt;/g, '<')
157
- .replace(/&gt;/g, '>')
158
- .replace(/&amp;/g, '&')
159
- .replace(/&nbsp;/g, ' ');
160
- // 时间
161
- const time = document.createElement('div');
162
- time.className = 'time';
163
- time.textContent = new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
164
- // AI 消息操作按钮
165
- if (type === 'ai') {
166
- div.appendChild(buildMessageActions(div, rawContent, ctx));
36
+ function addMessage(content, type, save = true, container, usedJudgmentIds = [], ctx = { messagesEl: null, messagesContainers: /* @__PURE__ */ new Map(), currentChannelId: null }) {
37
+ const messagesEl = ctx.messagesEl || (typeof document !== "undefined" ? document.getElementById("messages") : null);
38
+ const messagesContainers = ctx.messagesContainers || /* @__PURE__ */ new Map();
39
+ const currentChannelId = ctx.currentChannelId;
40
+ const msgContainer = container || getMessagesContainerForCurrent(currentChannelId, messagesContainers, messagesEl);
41
+ if (!save && msgContainer && msgContainer.children.length > 200) {
42
+ const toRemove = msgContainer.children.length - 200;
43
+ for (let i = 0; i < toRemove; i++) {
44
+ const first = msgContainer.firstElementChild;
45
+ if (first) msgContainer.removeChild(first);
167
46
  }
168
- // P0.5 反向引用
169
- if (type === 'ai' && Array.isArray(usedJudgmentIds) && usedJudgmentIds.length > 0) {
170
- const link = document.createElement('a');
171
- link.className = 'used-judgments-link';
172
- link.textContent = `📎 参考 ${usedJudgmentIds.length} 条原则`;
173
- link.onclick = (e) => {
174
- e.preventDefault();
175
- if (typeof ctx.openJudgmentsModalWithFilter === 'function') {
176
- ctx.openJudgmentsModalWithFilter(usedJudgmentIds);
177
- }
178
- };
179
- div.appendChild(link);
180
- }
181
- // 2026-06-15: 每条 AI 消息挂一个空 step-timeline 占位 (用户决策)
182
- // 后续 step_start/step_done 事件会通过 handleStepEvent 推入
183
- if (type === 'ai' && msgContainer) {
184
- mountStepTimeline(div, currentChannelId);
185
- }
186
- div.appendChild(time);
187
- if (msgContainer) {
188
- msgContainer.appendChild(div);
189
- scheduleScrollToBottom(msgContainer);
47
+ }
48
+ if (save) {
49
+ const lastContent = type === "user" ? lastUserCommand : lastAiContent;
50
+ if (lastContent && content === lastContent) {
51
+ console.log(`[addMessage] \u8DF3\u8FC7\u91CD\u590D\u7684 ${type} \u6D88\u606F`);
52
+ return;
190
53
  }
54
+ if (type === "user") lastUserCommand = content;
55
+ else lastAiContent = content;
56
+ }
57
+ const div = document.createElement("div");
58
+ div.className = `message message-${type}`;
59
+ let cleanContent = content.replace(/\[TOOL_CALL\][\s\S]*?\[\/TOOL_CALL\]/g, "").replace(/TOOL_CALL[\s\S]*?\/TOOL_CALL/g, "").replace(/<tool_call>[\s\S]*?<\/tool_call>/gi, "").replace(/\{\s*"tool":[\s\S]*?\}/g, "").replace(/\{\s*tool\s*=>\s*["'][^"']+["']\s*(?:,\s*args\s*=>\s*\{[\s\S]*?\})?\s*\}/g, "").replace(/\[Function[^\]]*\]\s*/g, "").trim();
60
+ const thinkMatch = cleanContent.match(/<think>([\s\S]*?)<\/think>/);
61
+ let mainContent = cleanContent;
62
+ let thinkContainer = null;
63
+ if (thinkMatch) {
64
+ const thinkContent = thinkMatch[1].trim();
65
+ mainContent = cleanContent.replace(/<think>[\s\S]*?<\/think>/, "").trim();
66
+ thinkContainer = buildThinkContainer(thinkContent);
67
+ }
68
+ const envMatch = mainContent.match(/^(.+?)\n<environment_details>([\s\S]*?)<\/environment_details>\n([\s\S]*)$/);
69
+ if (envMatch) {
70
+ const identity = envMatch[1].trim();
71
+ const envDetails = envMatch[2].trim();
72
+ const messageBody = envMatch[3].trim();
73
+ const header = document.createElement("div");
74
+ header.className = "message-header";
75
+ header.textContent = identity;
76
+ div.appendChild(header);
77
+ div.appendChild(buildEnvContainer(envDetails));
78
+ if (thinkContainer) div.appendChild(thinkContainer);
79
+ if (messageBody) div.appendChild(buildBubble(messageBody, type));
80
+ } else if (cleanContent) {
81
+ if (thinkContainer) div.appendChild(thinkContainer);
82
+ div.appendChild(buildBubble(cleanContent, type));
83
+ } else {
84
+ return;
85
+ }
86
+ const rawContent = cleanContent.replace(/<[^>]+>/g, "").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&").replace(/&nbsp;/g, " ");
87
+ const time = document.createElement("div");
88
+ time.className = "time";
89
+ time.textContent = (/* @__PURE__ */ new Date()).toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" });
90
+ if (type === "ai") {
91
+ div.appendChild(buildMessageActions(div, rawContent, ctx));
92
+ }
93
+ if (type === "ai" && Array.isArray(usedJudgmentIds) && usedJudgmentIds.length > 0) {
94
+ const link = document.createElement("a");
95
+ link.className = "used-judgments-link";
96
+ link.textContent = `\u{1F4CE} \u53C2\u8003 ${usedJudgmentIds.length} \u6761\u539F\u5219`;
97
+ link.onclick = (e) => {
98
+ e.preventDefault();
99
+ if (typeof ctx.openJudgmentsModalWithFilter === "function") {
100
+ ctx.openJudgmentsModalWithFilter(usedJudgmentIds);
101
+ }
102
+ };
103
+ div.appendChild(link);
104
+ }
105
+ if (type === "ai" && msgContainer) {
106
+ mountStepTimeline(div, currentChannelId);
107
+ }
108
+ div.appendChild(time);
109
+ if (msgContainer) {
110
+ msgContainer.appendChild(div);
111
+ scheduleScrollToBottom(msgContainer);
112
+ }
191
113
  }
192
- // ---------------------------------------------------------------------------
193
- // 私有: think 折叠块
194
- // ---------------------------------------------------------------------------
195
114
  function buildThinkContainer(thinkContent) {
196
- const container = document.createElement('div');
197
- container.className = 'think-container';
198
- const toggle = document.createElement('div');
199
- toggle.className = 'think-toggle';
200
- toggle.innerHTML = '💭 思考过程 <span class="think-arrow">▸</span>';
201
- toggle.onclick = function () {
202
- const details = container.querySelector('.think-content');
203
- const arrow = toggle.querySelector('.think-arrow');
204
- if (!details || !arrow)
205
- return;
206
- if (details.style.display === 'none') {
207
- details.style.display = 'block';
208
- arrow.textContent = '▾';
209
- }
210
- else {
211
- details.style.display = 'none';
212
- arrow.textContent = '▸';
213
- }
214
- };
215
- const content = document.createElement('div');
216
- content.className = 'think-content';
217
- content.style.display = 'none';
218
- content.innerHTML = `<pre>${escapeHtml(thinkContent)}</pre>`;
219
- container.appendChild(toggle);
220
- container.appendChild(content);
221
- return container;
115
+ const container = document.createElement("div");
116
+ container.className = "think-container";
117
+ const toggle = document.createElement("div");
118
+ toggle.className = "think-toggle";
119
+ toggle.innerHTML = '\u{1F4AD} \u601D\u8003\u8FC7\u7A0B <span class="think-arrow">\u25B8</span>';
120
+ toggle.onclick = function() {
121
+ const details = container.querySelector(".think-content");
122
+ const arrow = toggle.querySelector(".think-arrow");
123
+ if (!details || !arrow) return;
124
+ if (details.style.display === "none") {
125
+ details.style.display = "block";
126
+ arrow.textContent = "\u25BE";
127
+ } else {
128
+ details.style.display = "none";
129
+ arrow.textContent = "\u25B8";
130
+ }
131
+ };
132
+ const content = document.createElement("div");
133
+ content.className = "think-content";
134
+ content.style.display = "none";
135
+ content.innerHTML = `<pre>${escapeHtml(thinkContent)}</pre>`;
136
+ container.appendChild(toggle);
137
+ container.appendChild(content);
138
+ return container;
222
139
  }
223
- // ---------------------------------------------------------------------------
224
- // 私有: environment_details 折叠块
225
- // ---------------------------------------------------------------------------
226
140
  function buildEnvContainer(envDetails) {
227
- const container = document.createElement('div');
228
- container.className = 'env-container';
229
- const toggle = document.createElement('div');
230
- toggle.className = 'env-toggle';
231
- toggle.innerHTML = '⚙️ 环境信息 <span class="env-arrow">▸</span>';
232
- toggle.onclick = function () {
233
- const details = container.querySelector('.environment-details');
234
- const arrow = toggle.querySelector('.env-arrow');
235
- if (!details || !arrow)
236
- return;
237
- if (details.style.display === 'none') {
238
- details.style.display = 'block';
239
- arrow.textContent = '▾';
240
- }
241
- else {
242
- details.style.display = 'none';
243
- arrow.textContent = '▸';
244
- }
245
- };
246
- const content = document.createElement('div');
247
- content.className = 'environment-details';
248
- content.style.display = 'none';
249
- content.innerHTML = `<pre>${escapeHtml(envDetails)}</pre>`;
250
- container.appendChild(toggle);
251
- container.appendChild(content);
252
- return container;
141
+ const container = document.createElement("div");
142
+ container.className = "env-container";
143
+ const toggle = document.createElement("div");
144
+ toggle.className = "env-toggle";
145
+ toggle.innerHTML = '\u2699\uFE0F \u73AF\u5883\u4FE1\u606F <span class="env-arrow">\u25B8</span>';
146
+ toggle.onclick = function() {
147
+ const details = container.querySelector(".environment-details");
148
+ const arrow = toggle.querySelector(".env-arrow");
149
+ if (!details || !arrow) return;
150
+ if (details.style.display === "none") {
151
+ details.style.display = "block";
152
+ arrow.textContent = "\u25BE";
153
+ } else {
154
+ details.style.display = "none";
155
+ arrow.textContent = "\u25B8";
156
+ }
157
+ };
158
+ const content = document.createElement("div");
159
+ content.className = "environment-details";
160
+ content.style.display = "none";
161
+ content.innerHTML = `<pre>${escapeHtml(envDetails)}</pre>`;
162
+ container.appendChild(toggle);
163
+ container.appendChild(content);
164
+ return container;
253
165
  }
254
- // ---------------------------------------------------------------------------
255
- // 私有: 气泡 (marked.parse 渲染)
256
- // ---------------------------------------------------------------------------
257
166
  function buildBubble(text, type) {
258
- const bubble = document.createElement('div');
259
- bubble.className = `bubble bubble-${type}`;
260
- // 安全降级: CDN 加载失败时 marked 是 escape 版本, 这里不需要二次 escape
261
- // window.marked ts 类型上不一定有, any 兜底
262
- const marked = window.marked;
263
- bubble.innerHTML = marked ? marked.parse(text) : escapeHtml(text);
264
- return bubble;
167
+ const bubble = document.createElement("div");
168
+ bubble.className = `bubble bubble-${type}`;
169
+ const marked = window.marked;
170
+ bubble.innerHTML = marked ? marked.parse(text) : escapeHtml(text);
171
+ return bubble;
265
172
  }
266
- // ---------------------------------------------------------------------------
267
- // 私有: 消息操作按钮 (复制 / 重新回答 / 蒸馏为判断)
268
- // ---------------------------------------------------------------------------
269
173
  function buildMessageActions(div, rawContent, ctx) {
270
- const actions = document.createElement('div');
271
- actions.className = 'message-actions';
272
- // 复制
273
- const copyBtn = document.createElement('button');
274
- copyBtn.className = 'action-btn copy-btn';
275
- copyBtn.innerHTML = copyIcon() + ' 复制';
276
- copyBtn.title = '复制消息';
277
- copyBtn.onclick = () => {
278
- navigator.clipboard.writeText(rawContent).then(() => {
279
- copyBtn.innerHTML = checkIcon() + ' 已复制';
280
- setTimeout(() => { copyBtn.innerHTML = copyIcon() + ' 复制'; }, 2000);
281
- });
282
- };
283
- actions.appendChild(copyBtn);
284
- // 蒸馏为判断
285
- const saveJudgmentBtn = document.createElement('button');
286
- saveJudgmentBtn.className = 'action-btn save-as-judgment';
287
- saveJudgmentBtn.title = 'AI 蒸馏为 30-80 字判断力 + 自动演化对齐';
288
- saveJudgmentBtn.setAttribute('data-decision', rawContent.substring(0, 800));
289
- if (ctx.currentChannelId)
290
- saveJudgmentBtn.setAttribute('data-channel-id', ctx.currentChannelId);
291
- saveJudgmentBtn.innerHTML = shieldIcon() + ' 蒸馏为判断';
292
- actions.appendChild(saveJudgmentBtn);
293
- // 重新回答
294
- const regenBtn = document.createElement('button');
295
- regenBtn.className = 'action-btn regenerate-btn';
296
- regenBtn.innerHTML = refreshIcon(false) + ' 重新回答';
297
- regenBtn.title = '重新生成回复';
298
- regenBtn.onclick = () => {
299
- regenBtn.innerHTML = refreshIcon(true) + ' 生成中...';
300
- regenBtn.disabled = true;
301
- const messages = div.parentElement?.querySelectorAll('.message') || [];
302
- let lastUserMsg = '';
303
- for (let i = messages.length - 1; i >= 0; i--) {
304
- const msg = messages[i];
305
- if (msg.classList.contains('message-user')) {
306
- const bubble = msg.querySelector('.bubble');
307
- if (bubble) {
308
- lastUserMsg = bubble.textContent || bubble.innerText || '';
309
- break;
310
- }
311
- }
174
+ const actions = document.createElement("div");
175
+ actions.className = "message-actions";
176
+ const copyBtn = document.createElement("button");
177
+ copyBtn.className = "action-btn copy-btn";
178
+ copyBtn.innerHTML = copyIcon() + " \u590D\u5236";
179
+ copyBtn.title = "\u590D\u5236\u6D88\u606F";
180
+ copyBtn.onclick = () => {
181
+ navigator.clipboard.writeText(rawContent).then(() => {
182
+ copyBtn.innerHTML = checkIcon() + " \u5DF2\u590D\u5236";
183
+ setTimeout(() => {
184
+ copyBtn.innerHTML = copyIcon() + " \u590D\u5236";
185
+ }, 2e3);
186
+ });
187
+ };
188
+ actions.appendChild(copyBtn);
189
+ const saveJudgmentBtn = document.createElement("button");
190
+ saveJudgmentBtn.className = "action-btn save-as-judgment";
191
+ saveJudgmentBtn.title = "AI \u84B8\u998F\u4E3A 30-80 \u5B57\u5224\u65AD\u529B + \u81EA\u52A8\u6F14\u5316\u5BF9\u9F50";
192
+ saveJudgmentBtn.setAttribute("data-decision", rawContent.substring(0, 800));
193
+ if (ctx.currentChannelId) saveJudgmentBtn.setAttribute("data-channel-id", ctx.currentChannelId);
194
+ saveJudgmentBtn.innerHTML = shieldIcon() + " \u84B8\u998F\u4E3A\u5224\u65AD";
195
+ actions.appendChild(saveJudgmentBtn);
196
+ const regenBtn = document.createElement("button");
197
+ regenBtn.className = "action-btn regenerate-btn";
198
+ regenBtn.innerHTML = refreshIcon(false) + " \u91CD\u65B0\u56DE\u7B54";
199
+ regenBtn.title = "\u91CD\u65B0\u751F\u6210\u56DE\u590D";
200
+ regenBtn.onclick = () => {
201
+ regenBtn.innerHTML = refreshIcon(true) + " \u751F\u6210\u4E2D...";
202
+ regenBtn.disabled = true;
203
+ const messages = div.parentElement?.querySelectorAll(".message") || [];
204
+ let lastUserMsg = "";
205
+ for (let i = messages.length - 1; i >= 0; i--) {
206
+ const msg = messages[i];
207
+ if (msg.classList.contains("message-user")) {
208
+ const bubble = msg.querySelector(".bubble");
209
+ if (bubble) {
210
+ lastUserMsg = bubble.textContent || bubble.innerText || "";
211
+ break;
312
212
  }
313
- fetch('/regenerate', {
314
- method: 'POST',
315
- headers: { 'Content-Type': 'application/json' },
316
- body: JSON.stringify({ channelId: ctx.currentChannelId, userMessage: lastUserMsg })
317
- }).then(res => {
318
- if (!res.ok)
319
- throw new Error('regenerate failed');
320
- }).catch(err => {
321
- console.error('重新生成失败:', err);
322
- regenBtn.innerHTML = refreshIcon(false) + ' 失败';
323
- setTimeout(() => {
324
- regenBtn.innerHTML = refreshIcon(false) + ' 重新回答';
325
- regenBtn.disabled = false;
326
- }, 2000);
327
- });
328
- };
329
- actions.appendChild(regenBtn);
330
- return actions;
213
+ }
214
+ }
215
+ fetch("/regenerate", {
216
+ method: "POST",
217
+ headers: { "Content-Type": "application/json" },
218
+ body: JSON.stringify({ channelId: ctx.currentChannelId, userMessage: lastUserMsg })
219
+ }).then((res) => {
220
+ if (!res.ok) throw new Error("regenerate failed");
221
+ }).catch((err) => {
222
+ console.error("\u91CD\u65B0\u751F\u6210\u5931\u8D25:", err);
223
+ regenBtn.innerHTML = refreshIcon(false) + " \u5931\u8D25";
224
+ setTimeout(() => {
225
+ regenBtn.innerHTML = refreshIcon(false) + " \u91CD\u65B0\u56DE\u7B54";
226
+ regenBtn.disabled = false;
227
+ }, 2e3);
228
+ });
229
+ };
230
+ actions.appendChild(regenBtn);
231
+ return actions;
331
232
  }
332
- function copyIcon() { return '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>'; }
333
- function checkIcon() { return '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"></polyline></svg>'; }
334
- function shieldIcon() { return '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L4 6v6c0 5 3.5 9.5 8 10 4.5-.5 8-5 8-10V6l-8-4z"></path><path d="M9 12l2 2 4-4"></path></svg>'; }
335
- function refreshIcon(spin = false) { const cls = spin ? ' class="spin"' : ''; return `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"${cls}><path d="M21 2v6h-6M3 12a9 9 0 0 1 15-6.7L21 8M3 22v-6h6M21 12a9 9 0 0 1-15 6.7L3 16"></path></svg>`; }
336
- // ---------------------------------------------------------------------------
337
- // 流式 token 处理 (textNode 增量, 不重排)
338
- // ---------------------------------------------------------------------------
339
- export function handleStreamTokenEvent(data, ctx = { messagesEl: null, messagesContainers: new Map(), currentChannelId: null }) {
340
- const messagesEl = ctx.messagesEl || (typeof document !== 'undefined' ? document.getElementById('messages') : null);
341
- const messagesContainers = ctx.messagesContainers || new Map();
342
- const currentChannelId = ctx.currentChannelId;
343
- const container = getMessagesContainerForCurrent(currentChannelId, messagesContainers, messagesEl);
344
- if (!container)
345
- return;
346
- const delta = data.content || '';
347
- if (!delta)
348
- return;
349
- if (!streamingMessageEl || !streamingMessageEl.isConnected) {
350
- // 新建流式消息
351
- streamingMessageEl = document.createElement('div');
352
- streamingMessageEl.className = 'message message-ai message-streaming';
353
- streamingTextNode = document.createTextNode('');
354
- streamingMessageEl.appendChild(streamingTextNode);
355
- streamingText = '';
356
- // 2026-06-15: 流式期间也挂一个空 step-timeline 占位 — step_start/done/error 事件
357
- // 走 handleStepEvent, getStepTimeline 找到这个流式元素内的 timeline 推入
358
- mountStepTimeline(streamingMessageEl, currentChannelId);
359
- container.appendChild(streamingMessageEl);
360
- // B-3: 首个 token 来时切状态到 streaming (蓝徽), 提示用户 panel 在工作
361
- if (typeof ctx.setTimelineState === 'function') {
362
- ctx.setTimelineState('streaming');
363
- }
364
- scheduleScrollToBottom(container);
233
+ function copyIcon() {
234
+ return '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>';
235
+ }
236
+ function checkIcon() {
237
+ return '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"></polyline></svg>';
238
+ }
239
+ function shieldIcon() {
240
+ return '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L4 6v6c0 5 3.5 9.5 8 10 4.5-.5 8-5 8-10V6l-8-4z"></path><path d="M9 12l2 2 4-4"></path></svg>';
241
+ }
242
+ function refreshIcon(spin = false) {
243
+ const cls = spin ? ' class="spin"' : "";
244
+ return `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"${cls}><path d="M21 2v6h-6M3 12a9 9 0 0 1 15-6.7L21 8M3 22v-6h6M21 12a9 9 0 0 1-15 6.7L3 16"></path></svg>`;
245
+ }
246
+ function handleStreamTokenEvent(data, ctx = { messagesEl: null, messagesContainers: /* @__PURE__ */ new Map(), currentChannelId: null }) {
247
+ const messagesEl = ctx.messagesEl || (typeof document !== "undefined" ? document.getElementById("messages") : null);
248
+ const messagesContainers = ctx.messagesContainers || /* @__PURE__ */ new Map();
249
+ const currentChannelId = ctx.currentChannelId;
250
+ const container = getMessagesContainerForCurrent(currentChannelId, messagesContainers, messagesEl);
251
+ if (!container) return;
252
+ const delta = data.content || "";
253
+ if (!delta) return;
254
+ if (!streamingMessageEl || !streamingMessageEl.isConnected) {
255
+ streamingMessageEl = document.createElement("div");
256
+ streamingMessageEl.className = "message message-ai message-streaming";
257
+ streamingTextNode = document.createTextNode("");
258
+ streamingMessageEl.appendChild(streamingTextNode);
259
+ streamingText = "";
260
+ mountStepTimeline(streamingMessageEl, currentChannelId);
261
+ container.appendChild(streamingMessageEl);
262
+ if (typeof ctx.setTimelineState === "function") {
263
+ ctx.setTimelineState("streaming");
365
264
  }
366
- if (streamingTextNode)
367
- streamingTextNode.appendData(delta);
368
- streamingText += delta;
369
265
  scheduleScrollToBottom(container);
266
+ }
267
+ if (streamingTextNode) streamingTextNode.appendData(delta);
268
+ streamingText += delta;
269
+ scheduleScrollToBottom(container);
370
270
  }
371
- // ---------------------------------------------------------------------------
372
- // 流式消息 finalize (done 事件): 移除流式元素, addMessage marked.parse
373
- // ---------------------------------------------------------------------------
374
- export function finalizeTimelineAsMessage(ctx = { messagesEl: null, messagesContainers: new Map(), currentChannelId: null }) {
375
- const messagesEl = ctx.messagesEl || (typeof document !== 'undefined' ? document.getElementById('messages') : null);
376
- const messagesContainers = ctx.messagesContainers || new Map();
377
- const currentChannelId = ctx.currentChannelId;
378
- const container = getMessagesContainerForCurrent(currentChannelId, messagesContainers, messagesEl);
379
- if (streamingText.trim().length > 0) {
380
- // 2026-06-15: finalize 时把 streaming 内的 step-timeline 整体搬到新建的正式 AI message 内
381
- // addMessage 会建一个新 timeline 占位, 先记下 streaming 的引用, addMessage 后再迁移
382
- // 避免节点从 0 重渲 (10+ 步的任务, 重渲闪烁会很厉害)
383
- const oldStreamingEl = streamingMessageEl;
384
- if (oldStreamingEl && oldStreamingEl.parentNode) {
385
- oldStreamingEl.parentNode.removeChild(oldStreamingEl);
386
- }
387
- addMessage(streamingText, 'ai', true, container, ctx.lastUsedJudgmentIds || [], ctx);
388
- if (oldStreamingEl && container) {
389
- // 找刚 addMessage 创建的最后一条 ai message
390
- const newAiMsg = container.querySelector('.message-ai:last-of-type');
391
- if (newAiMsg && newAiMsg !== oldStreamingEl) {
392
- migrateStepTimeline(oldStreamingEl, newAiMsg);
393
- }
394
- }
271
+ function finalizeTimelineAsMessage(ctx = { messagesEl: null, messagesContainers: /* @__PURE__ */ new Map(), currentChannelId: null }) {
272
+ const messagesEl = ctx.messagesEl || (typeof document !== "undefined" ? document.getElementById("messages") : null);
273
+ const messagesContainers = ctx.messagesContainers || /* @__PURE__ */ new Map();
274
+ const currentChannelId = ctx.currentChannelId;
275
+ const container = getMessagesContainerForCurrent(currentChannelId, messagesContainers, messagesEl);
276
+ if (streamingText.trim().length > 0) {
277
+ const oldStreamingEl = streamingMessageEl;
278
+ if (oldStreamingEl && oldStreamingEl.parentNode) {
279
+ oldStreamingEl.parentNode.removeChild(oldStreamingEl);
395
280
  }
396
- // 重置流式状态
397
- streamingMessageEl = null;
398
- streamingTextNode = null;
399
- streamingText = '';
400
- // B-3: finalize 时切 done 状态 (绿徽), hide 延迟由 client.js 的 hideTimelinePanel 统一管
401
- if (typeof ctx.setTimelineState === 'function') {
402
- ctx.setTimelineState('done');
281
+ addMessage(streamingText, "ai", true, container, ctx.lastUsedJudgmentIds || [], ctx);
282
+ if (oldStreamingEl && container) {
283
+ const newAiMsg = container.querySelector(".message-ai:last-of-type");
284
+ if (newAiMsg && newAiMsg !== oldStreamingEl) {
285
+ migrateStepTimeline(oldStreamingEl, newAiMsg);
286
+ }
403
287
  }
288
+ }
289
+ streamingMessageEl = null;
290
+ streamingTextNode = null;
291
+ streamingText = "";
292
+ if (typeof ctx.setTimelineState === "function") {
293
+ ctx.setTimelineState("done");
294
+ }
404
295
  }
405
- export function handleStepEvent(data, ctx = { messagesEl: null, messagesContainers: new Map(), currentChannelId: null }) {
406
- const messagesEl = ctx.messagesEl || (typeof document !== 'undefined' ? document.getElementById('messages') : null);
407
- const messagesContainers = ctx.messagesContainers || new Map();
408
- const currentChannelId = ctx.currentChannelId;
409
- const container = getMessagesContainerForCurrent(currentChannelId, messagesContainers, messagesEl);
410
- if (!container)
411
- return;
412
- if (!data || !data.type)
413
- return;
414
- // 1. 优先用正在流式的元素 (流式期间能即时看到)
415
- let target = streamingMessageEl && streamingMessageEl.isConnected
416
- ? streamingMessageEl
417
- : null;
418
- // 2. 否则用最后一条 AI message
419
- if (!target) {
420
- const aiMsgs = container.querySelectorAll('.message-ai');
421
- if (aiMsgs.length === 0)
422
- return;
423
- target = aiMsgs[aiMsgs.length - 1];
424
- }
425
- if (!target)
426
- return;
427
- const timeline = getStepTimeline(target);
428
- if (!timeline)
429
- return;
430
- pushStepToTimeline(timeline, data.type, {
431
- tool: data.tool || 'unknown',
432
- args: data.args,
433
- success: data.success,
434
- output: data.output,
435
- error: data.error,
436
- });
296
+ function handleStepEvent(data, ctx = { messagesEl: null, messagesContainers: /* @__PURE__ */ new Map(), currentChannelId: null }) {
297
+ const messagesEl = ctx.messagesEl || (typeof document !== "undefined" ? document.getElementById("messages") : null);
298
+ const messagesContainers = ctx.messagesContainers || /* @__PURE__ */ new Map();
299
+ const currentChannelId = ctx.currentChannelId;
300
+ const container = getMessagesContainerForCurrent(currentChannelId, messagesContainers, messagesEl);
301
+ if (!container) return;
302
+ if (!data || !data.type) return;
303
+ let target = streamingMessageEl && streamingMessageEl.isConnected ? streamingMessageEl : null;
304
+ if (!target) {
305
+ const aiMsgs = container.querySelectorAll(".message-ai");
306
+ if (aiMsgs.length === 0) return;
307
+ target = aiMsgs[aiMsgs.length - 1];
308
+ }
309
+ if (!target) return;
310
+ const timeline = getStepTimeline(target);
311
+ if (!timeline) return;
312
+ pushStepToTimeline(timeline, data.type, {
313
+ tool: data.tool || "unknown",
314
+ args: data.args,
315
+ success: data.success,
316
+ output: data.output,
317
+ error: data.error
318
+ });
437
319
  }
438
- // ---------------------------------------------------------------------------
439
- // 重置模块状态 (切频道时调用)
440
- // ---------------------------------------------------------------------------
441
- export function resetRendererState() {
442
- streamingMessageEl = null;
443
- streamingTextNode = null;
444
- streamingText = '';
445
- lastUserCommand = '';
446
- lastAiContent = '';
447
- if (scrollToBottomTimer) {
448
- clearTimeout(scrollToBottomTimer);
449
- scrollToBottomTimer = null;
450
- }
320
+ function resetRendererState() {
321
+ streamingMessageEl = null;
322
+ streamingTextNode = null;
323
+ streamingText = "";
324
+ lastUserCommand = "";
325
+ lastAiContent = "";
326
+ if (scrollToBottomTimer) {
327
+ clearTimeout(scrollToBottomTimer);
328
+ scrollToBottomTimer = null;
329
+ }
451
330
  }
452
- export const MessageRenderer = {
453
- addMessage,
454
- handleStreamTokenEvent,
455
- finalizeTimelineAsMessage,
456
- handleStepEvent,
457
- escapeHtml,
458
- getMessagesContainerForCurrent,
459
- resetRendererState,
331
+ const MessageRenderer = {
332
+ addMessage,
333
+ handleStreamTokenEvent,
334
+ finalizeTimelineAsMessage,
335
+ handleStepEvent,
336
+ escapeHtml,
337
+ getMessagesContainerForCurrent,
338
+ resetRendererState
460
339
  };
461
- if (typeof window !== 'undefined') {
462
- window.MR = MessageRenderer;
340
+ if (typeof window !== "undefined") {
341
+ window.MR = MessageRenderer;
463
342
  }
343
+ export {
344
+ MessageRenderer,
345
+ addMessage,
346
+ escapeHtml,
347
+ finalizeTimelineAsMessage,
348
+ getMessagesContainerForCurrent,
349
+ handleStepEvent,
350
+ handleStreamTokenEvent,
351
+ resetRendererState
352
+ };