principles-disciple 1.8.0 → 1.8.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 (460) hide show
  1. package/ADVANCED_CONFIG_ZH.md +97 -0
  2. package/AGENT_INSTALL.md +173 -0
  3. package/AGENT_INSTALL_EN.md +173 -0
  4. package/INSTALL.md +256 -0
  5. package/SKILL.md +63 -0
  6. package/docs/COMMAND_REFERENCE.md +76 -0
  7. package/docs/COMMAND_REFERENCE_EN.md +79 -0
  8. package/esbuild.config.js +75 -0
  9. package/openclaw.plugin.json +6 -1
  10. package/package.json +13 -15
  11. package/scripts/build-web.mjs +46 -0
  12. package/scripts/install-dependencies.cjs +47 -0
  13. package/scripts/sync-plugin.mjs +802 -0
  14. package/scripts/verify-build.mjs +109 -0
  15. package/src/agents/nocturnal-dreamer.md +152 -0
  16. package/src/agents/nocturnal-philosopher.md +138 -0
  17. package/src/agents/nocturnal-reflector.md +126 -0
  18. package/src/agents/nocturnal-scribe.md +164 -0
  19. package/src/commands/capabilities.ts +85 -0
  20. package/{dist/commands/context.js → src/commands/context.ts} +78 -38
  21. package/src/commands/evolution-status.ts +146 -0
  22. package/src/commands/export.ts +111 -0
  23. package/src/commands/focus.ts +533 -0
  24. package/src/commands/nocturnal-review.ts +311 -0
  25. package/src/commands/nocturnal-rollout.ts +763 -0
  26. package/src/commands/nocturnal-train.ts +1002 -0
  27. package/{dist/commands/pain.js → src/commands/pain.ts} +68 -49
  28. package/src/commands/principle-rollback.ts +27 -0
  29. package/{dist/commands/rollback.js → src/commands/rollback.ts} +44 -12
  30. package/src/commands/samples.ts +60 -0
  31. package/src/commands/strategy.ts +38 -0
  32. package/{dist/commands/thinking-os.js → src/commands/thinking-os.ts} +59 -36
  33. package/src/commands/workflow-debug.ts +128 -0
  34. package/{dist/config/defaults/runtime.js → src/config/defaults/runtime.ts} +12 -5
  35. package/src/config/errors.ts +163 -0
  36. package/{dist/config/index.d.ts → src/config/index.ts} +2 -1
  37. package/src/constants/diagnostician.ts +66 -0
  38. package/src/constants/tools.ts +62 -0
  39. package/src/core/adaptive-thresholds.ts +476 -0
  40. package/{dist/core/config-service.js → src/core/config-service.ts} +7 -4
  41. package/{dist/core/config.js → src/core/config.ts} +158 -46
  42. package/src/core/control-ui-db.ts +435 -0
  43. package/{dist/core/detection-funnel.js → src/core/detection-funnel.ts} +36 -21
  44. package/{dist/core/detection-service.js → src/core/detection-service.ts} +7 -4
  45. package/{dist/core/dictionary-service.js → src/core/dictionary-service.ts} +7 -4
  46. package/{dist/core/dictionary.js → src/core/dictionary.ts} +57 -34
  47. package/src/core/empathy-keyword-matcher.ts +327 -0
  48. package/src/core/empathy-types.ts +218 -0
  49. package/src/core/event-log.ts +544 -0
  50. package/src/core/evolution-engine.ts +612 -0
  51. package/src/core/evolution-logger.ts +353 -0
  52. package/src/core/evolution-migration.ts +77 -0
  53. package/src/core/evolution-reducer.ts +731 -0
  54. package/src/core/evolution-types.ts +456 -0
  55. package/src/core/external-training-contract.ts +527 -0
  56. package/src/core/focus-history.ts +1458 -0
  57. package/src/core/hygiene/tracker.ts +117 -0
  58. package/{dist/core/init.js → src/core/init.ts} +39 -26
  59. package/src/core/local-worker-routing.ts +617 -0
  60. package/{dist/core/migration.js → src/core/migration.ts} +18 -11
  61. package/src/core/model-deployment-registry.ts +722 -0
  62. package/src/core/model-training-registry.ts +813 -0
  63. package/src/core/nocturnal-arbiter.ts +706 -0
  64. package/src/core/nocturnal-candidate-scoring.ts +392 -0
  65. package/src/core/nocturnal-compliance.ts +1075 -0
  66. package/src/core/nocturnal-dataset.ts +668 -0
  67. package/src/core/nocturnal-executability.ts +428 -0
  68. package/src/core/nocturnal-export.ts +390 -0
  69. package/{dist/core/nocturnal-paths.js → src/core/nocturnal-paths.ts} +49 -23
  70. package/src/core/nocturnal-trajectory-extractor.ts +484 -0
  71. package/src/core/nocturnal-trinity.ts +1384 -0
  72. package/src/core/pain.ts +122 -0
  73. package/{dist/core/path-resolver.js → src/core/path-resolver.ts} +157 -36
  74. package/{dist/core/paths.js → src/core/paths.ts} +13 -4
  75. package/src/core/principle-training-state.ts +450 -0
  76. package/src/core/profile.ts +226 -0
  77. package/src/core/promotion-gate.ts +822 -0
  78. package/{dist/core/risk-calculator.js → src/core/risk-calculator.ts} +42 -16
  79. package/{dist/core/session-tracker.js → src/core/session-tracker.ts} +185 -63
  80. package/src/core/shadow-observation-registry.ts +534 -0
  81. package/{dist/core/system-logger.js → src/core/system-logger.ts} +9 -5
  82. package/src/core/thinking-models.ts +217 -0
  83. package/src/core/training-program.ts +630 -0
  84. package/src/core/trajectory-types.ts +243 -0
  85. package/src/core/trajectory.ts +1673 -0
  86. package/{dist/core/workspace-context.js → src/core/workspace-context.ts} +57 -32
  87. package/src/hooks/bash-risk.ts +171 -0
  88. package/src/hooks/edit-verification.ts +295 -0
  89. package/src/hooks/gate-block-helper.ts +160 -0
  90. package/src/hooks/gate.ts +210 -0
  91. package/src/hooks/gfi-gate.ts +177 -0
  92. package/src/hooks/lifecycle.ts +326 -0
  93. package/{dist/hooks/llm.js → src/hooks/llm.ts} +166 -139
  94. package/src/hooks/message-sanitize.ts +45 -0
  95. package/src/hooks/pain.ts +384 -0
  96. package/src/hooks/progressive-trust-gate.ts +174 -0
  97. package/src/hooks/prompt.ts +920 -0
  98. package/src/hooks/subagent.ts +207 -0
  99. package/src/hooks/thinking-checkpoint.ts +73 -0
  100. package/src/hooks/trajectory-collector.ts +290 -0
  101. package/src/http/principles-console-route.ts +716 -0
  102. package/src/i18n/commands.ts +117 -0
  103. package/src/index.ts +694 -0
  104. package/src/service/central-database.ts +831 -0
  105. package/src/service/control-ui-query-service.ts +888 -0
  106. package/src/service/evolution-query-service.ts +405 -0
  107. package/src/service/evolution-worker.ts +1646 -0
  108. package/src/service/health-query-service.ts +836 -0
  109. package/{dist/service/nocturnal-runtime.js → src/service/nocturnal-runtime.ts} +263 -36
  110. package/src/service/nocturnal-service.ts +1015 -0
  111. package/src/service/nocturnal-target-selector.ts +532 -0
  112. package/src/service/phase3-input-filter.ts +237 -0
  113. package/src/service/runtime-summary-service.ts +757 -0
  114. package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +513 -0
  115. package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +603 -0
  116. package/src/service/subagent-workflow/index.ts +51 -0
  117. package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +856 -0
  118. package/src/service/subagent-workflow/runtime-direct-driver.ts +166 -0
  119. package/src/service/subagent-workflow/types.ts +378 -0
  120. package/src/service/subagent-workflow/workflow-store.ts +328 -0
  121. package/src/service/trajectory-service.ts +15 -0
  122. package/{dist/tools/critique-prompt.js → src/tools/critique-prompt.ts} +25 -8
  123. package/src/tools/deep-reflect.ts +349 -0
  124. package/{dist/tools/model-index.js → src/tools/model-index.ts} +33 -17
  125. package/src/types/event-types.ts +453 -0
  126. package/src/types/hygiene-types.ts +31 -0
  127. package/src/types/principle-tree-schema.ts +244 -0
  128. package/src/types/runtime-summary.ts +49 -0
  129. package/src/types.ts +74 -0
  130. package/src/utils/file-lock.ts +391 -0
  131. package/{dist/utils/glob-match.js → src/utils/glob-match.ts} +21 -20
  132. package/{dist/utils/hashing.js → src/utils/hashing.ts} +6 -4
  133. package/src/utils/io.ts +110 -0
  134. package/{dist/utils/nlp.js → src/utils/nlp.ts} +19 -12
  135. package/{dist/utils/plugin-logger.js → src/utils/plugin-logger.ts} +33 -8
  136. package/src/utils/subagent-probe.ts +94 -0
  137. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +70 -1
  138. package/templates/pain_settings.json +2 -1
  139. package/tests/README.md +120 -0
  140. package/tests/build-artifacts.test.ts +111 -0
  141. package/tests/commands/evolution-status.test.ts +222 -0
  142. package/tests/commands/evolver.test.ts +22 -0
  143. package/tests/commands/export.test.ts +78 -0
  144. package/tests/commands/nocturnal-review.test.ts +448 -0
  145. package/tests/commands/nocturnal-train.test.ts +97 -0
  146. package/tests/commands/pain.test.ts +108 -0
  147. package/tests/commands/samples.test.ts +65 -0
  148. package/tests/commands/strategy.test.ts +34 -0
  149. package/tests/commands/thinking-os.test.ts +88 -0
  150. package/tests/core/adaptive-thresholds.test.ts +261 -0
  151. package/tests/core/config-service.test.ts +89 -0
  152. package/tests/core/config.test.ts +90 -0
  153. package/tests/core/control-ui-db.test.ts +75 -0
  154. package/tests/core/core-template-guidance.test.ts +21 -0
  155. package/tests/core/detection-funnel.test.ts +63 -0
  156. package/tests/core/detection-service.test.ts +50 -0
  157. package/tests/core/dictionary-service.test.ts +116 -0
  158. package/tests/core/dictionary.test.ts +168 -0
  159. package/tests/core/empathy-keyword-matcher.test.ts +209 -0
  160. package/tests/core/event-log.test.ts +181 -0
  161. package/tests/core/evolution-e2e.test.ts +58 -0
  162. package/tests/core/evolution-engine-gate-integration.test.ts +543 -0
  163. package/tests/core/evolution-engine.test.ts +562 -0
  164. package/tests/core/evolution-logger.test.ts +148 -0
  165. package/tests/core/evolution-migration.test.ts +50 -0
  166. package/tests/core/evolution-paths.test.ts +21 -0
  167. package/tests/core/evolution-reducer.detector-metadata.test.ts +602 -0
  168. package/tests/core/evolution-reducer.test.ts +180 -0
  169. package/tests/core/evolution-types-loop.test.ts +48 -0
  170. package/tests/core/evolution-user-stories.e2e.test.ts +249 -0
  171. package/tests/core/external-training-contract.test.ts +463 -0
  172. package/tests/core/focus-history.test.ts +682 -0
  173. package/tests/core/init-flatten.test.ts +69 -0
  174. package/tests/core/init-refactor.test.ts +87 -0
  175. package/tests/core/init-v1.3.test.ts +46 -0
  176. package/tests/core/init.test.ts +190 -0
  177. package/tests/core/local-worker-routing.test.ts +757 -0
  178. package/tests/core/migration.test.ts +84 -0
  179. package/tests/core/model-deployment-registry.test.ts +845 -0
  180. package/tests/core/model-training-registry.test.ts +889 -0
  181. package/tests/core/nocturnal-arbiter.test.ts +494 -0
  182. package/tests/core/nocturnal-candidate-scoring.test.ts +400 -0
  183. package/tests/core/nocturnal-compliance.test.ts +646 -0
  184. package/tests/core/nocturnal-dataset.test.ts +892 -0
  185. package/tests/core/nocturnal-executability.test.ts +357 -0
  186. package/tests/core/nocturnal-export.test.ts +462 -0
  187. package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +428 -0
  188. package/tests/core/nocturnal-trajectory-extractor.test.ts +634 -0
  189. package/tests/core/nocturnal-trinity.test.ts +953 -0
  190. package/tests/core/pain.test.ts +33 -0
  191. package/tests/core/path-resolver.test.ts +57 -0
  192. package/tests/core/paths-refactor.test.ts +42 -0
  193. package/tests/core/phase7-rollout-integration.test.ts +477 -0
  194. package/tests/core/principle-training-state.test.ts +712 -0
  195. package/tests/core/profile.test.ts +56 -0
  196. package/tests/core/promotion-gate.test.ts +556 -0
  197. package/tests/core/risk-calculator.test.ts +168 -0
  198. package/tests/core/session-tracker.test.ts +191 -0
  199. package/tests/core/training-program.test.ts +472 -0
  200. package/tests/core/trajectory.test.ts +265 -0
  201. package/tests/core/workspace-context-factory.test.ts +18 -0
  202. package/tests/core/workspace-context.test.ts +134 -0
  203. package/tests/fixtures/nocturnal-reviewed-subset.json +183 -0
  204. package/tests/fixtures/production-compatibility.test.ts +147 -0
  205. package/tests/fixtures/production-mock-generator.ts +282 -0
  206. package/tests/hooks/bash-risk-integration.test.ts +137 -0
  207. package/tests/hooks/bash-risk.test.ts +81 -0
  208. package/tests/hooks/edit-verification.test.ts +678 -0
  209. package/tests/hooks/gate-edit-verification-p1.test.ts +632 -0
  210. package/tests/hooks/gate-edit-verification.test.ts +435 -0
  211. package/tests/hooks/gate-pipeline-integration.test.ts +404 -0
  212. package/tests/hooks/gate.test.ts +271 -0
  213. package/tests/hooks/gfi-gate-unit.test.ts +422 -0
  214. package/tests/hooks/gfi-gate.test.ts +669 -0
  215. package/tests/hooks/lifecycle.test.ts +248 -0
  216. package/tests/hooks/llm.test.ts +308 -0
  217. package/tests/hooks/message-sanitize.test.ts +36 -0
  218. package/tests/hooks/pain.test.ts +141 -0
  219. package/tests/hooks/progressive-trust-gate.test.ts +277 -0
  220. package/tests/hooks/prompt.test.ts +1411 -0
  221. package/tests/hooks/subagent.test.ts +467 -0
  222. package/tests/hooks/thinking-gate.test.ts +313 -0
  223. package/tests/http/principles-console-route.test.ts +140 -0
  224. package/tests/hygiene-tracker.test.ts +77 -0
  225. package/tests/index.integration.test.ts +179 -0
  226. package/tests/index.shadow-routing.integration.test.ts +140 -0
  227. package/tests/index.test.ts +9 -0
  228. package/tests/integration/empathy-workflow-integration.test.ts +627 -0
  229. package/tests/service/control-ui-query-service.test.ts +121 -0
  230. package/tests/service/empathy-observer-workflow-manager.test.ts +176 -0
  231. package/tests/service/evolution-worker.test.ts +585 -0
  232. package/tests/service/nocturnal-runtime.test.ts +470 -0
  233. package/tests/service/nocturnal-service.test.ts +577 -0
  234. package/tests/service/nocturnal-target-selector.test.ts +615 -0
  235. package/tests/service/nocturnal-workflow-manager.test.ts +439 -0
  236. package/tests/service/phase3-input-filter.test.ts +289 -0
  237. package/tests/service/runtime-summary-service.test.ts +919 -0
  238. package/tests/task-compliance.test.ts +166 -0
  239. package/tests/test-utils.ts +48 -0
  240. package/tests/tools/critique-prompt.test.ts +260 -0
  241. package/tests/tools/deep-reflect.test.ts +232 -0
  242. package/tests/tools/model-index.test.ts +246 -0
  243. package/tests/ui/app.test.tsx +114 -0
  244. package/tests/utils/file-lock.test.ts +407 -0
  245. package/tests/utils/hashing.test.ts +32 -0
  246. package/tests/utils/io.test.ts +39 -0
  247. package/tests/utils/nlp.test.ts +53 -0
  248. package/tests/utils/plugin-logger.test.ts +156 -0
  249. package/tsconfig.json +16 -0
  250. package/tsconfig.tsbuildinfo +1 -0
  251. package/ui/src/App.tsx +45 -0
  252. package/ui/src/api.ts +216 -0
  253. package/ui/src/charts.tsx +586 -0
  254. package/ui/src/components/ErrorState.tsx +6 -0
  255. package/ui/src/components/Loading.tsx +13 -0
  256. package/ui/src/components/ProtectedRoute.tsx +12 -0
  257. package/ui/src/components/Shell.tsx +91 -0
  258. package/ui/src/components/WorkspaceConfig.tsx +146 -0
  259. package/ui/src/components/index.ts +5 -0
  260. package/ui/src/context/auth.tsx +80 -0
  261. package/ui/src/context/theme.tsx +66 -0
  262. package/ui/src/hooks/useAutoRefresh.ts +39 -0
  263. package/ui/src/i18n/ui.ts +363 -0
  264. package/ui/src/main.tsx +16 -0
  265. package/ui/src/pages/EvolutionPage.tsx +352 -0
  266. package/ui/src/pages/FeedbackPage.tsx +140 -0
  267. package/ui/src/pages/GateMonitorPage.tsx +136 -0
  268. package/ui/src/pages/LoginPage.tsx +88 -0
  269. package/ui/src/pages/OverviewPage.tsx +238 -0
  270. package/ui/src/pages/SamplesPage.tsx +174 -0
  271. package/ui/src/pages/ThinkingModelsPage.tsx +127 -0
  272. package/ui/src/styles.css +1661 -0
  273. package/ui/src/types.ts +368 -0
  274. package/ui/src/utils/format.ts +15 -0
  275. package/vitest.config.ts +23 -0
  276. package/dist/commands/capabilities.d.ts +0 -3
  277. package/dist/commands/capabilities.js +0 -73
  278. package/dist/commands/context.d.ts +0 -5
  279. package/dist/commands/evolution-status.d.ts +0 -4
  280. package/dist/commands/evolution-status.js +0 -117
  281. package/dist/commands/evolver.d.ts +0 -9
  282. package/dist/commands/evolver.js +0 -26
  283. package/dist/commands/export.d.ts +0 -2
  284. package/dist/commands/export.js +0 -98
  285. package/dist/commands/focus.d.ts +0 -14
  286. package/dist/commands/focus.js +0 -457
  287. package/dist/commands/nocturnal-review.d.ts +0 -24
  288. package/dist/commands/nocturnal-review.js +0 -265
  289. package/dist/commands/nocturnal-rollout.d.ts +0 -27
  290. package/dist/commands/nocturnal-rollout.js +0 -671
  291. package/dist/commands/nocturnal-train.d.ts +0 -25
  292. package/dist/commands/nocturnal-train.js +0 -919
  293. package/dist/commands/pain.d.ts +0 -5
  294. package/dist/commands/principle-rollback.d.ts +0 -4
  295. package/dist/commands/principle-rollback.js +0 -22
  296. package/dist/commands/rollback.d.ts +0 -19
  297. package/dist/commands/samples.d.ts +0 -2
  298. package/dist/commands/samples.js +0 -55
  299. package/dist/commands/strategy.d.ts +0 -3
  300. package/dist/commands/strategy.js +0 -29
  301. package/dist/commands/thinking-os.d.ts +0 -2
  302. package/dist/config/defaults/runtime.d.ts +0 -40
  303. package/dist/config/errors.d.ts +0 -84
  304. package/dist/config/errors.js +0 -94
  305. package/dist/config/index.js +0 -7
  306. package/dist/constants/diagnostician.d.ts +0 -12
  307. package/dist/constants/diagnostician.js +0 -56
  308. package/dist/constants/tools.d.ts +0 -17
  309. package/dist/constants/tools.js +0 -54
  310. package/dist/core/adaptive-thresholds.d.ts +0 -186
  311. package/dist/core/adaptive-thresholds.js +0 -300
  312. package/dist/core/config-service.d.ts +0 -15
  313. package/dist/core/config.d.ts +0 -127
  314. package/dist/core/control-ui-db.d.ts +0 -95
  315. package/dist/core/control-ui-db.js +0 -292
  316. package/dist/core/detection-funnel.d.ts +0 -33
  317. package/dist/core/detection-service.d.ts +0 -15
  318. package/dist/core/dictionary-service.d.ts +0 -15
  319. package/dist/core/dictionary.d.ts +0 -38
  320. package/dist/core/event-log.d.ts +0 -82
  321. package/dist/core/event-log.js +0 -463
  322. package/dist/core/evolution-engine.d.ts +0 -118
  323. package/dist/core/evolution-engine.js +0 -464
  324. package/dist/core/evolution-logger.d.ts +0 -137
  325. package/dist/core/evolution-logger.js +0 -256
  326. package/dist/core/evolution-migration.d.ts +0 -5
  327. package/dist/core/evolution-migration.js +0 -65
  328. package/dist/core/evolution-reducer.d.ts +0 -98
  329. package/dist/core/evolution-reducer.js +0 -465
  330. package/dist/core/evolution-types.d.ts +0 -287
  331. package/dist/core/evolution-types.js +0 -78
  332. package/dist/core/external-training-contract.d.ts +0 -276
  333. package/dist/core/external-training-contract.js +0 -269
  334. package/dist/core/focus-history.d.ts +0 -210
  335. package/dist/core/focus-history.js +0 -1185
  336. package/dist/core/hygiene/tracker.d.ts +0 -22
  337. package/dist/core/hygiene/tracker.js +0 -106
  338. package/dist/core/init.d.ts +0 -12
  339. package/dist/core/local-worker-routing.d.ts +0 -175
  340. package/dist/core/local-worker-routing.js +0 -525
  341. package/dist/core/migration.d.ts +0 -6
  342. package/dist/core/model-deployment-registry.d.ts +0 -218
  343. package/dist/core/model-deployment-registry.js +0 -503
  344. package/dist/core/model-training-registry.d.ts +0 -295
  345. package/dist/core/model-training-registry.js +0 -475
  346. package/dist/core/nocturnal-arbiter.d.ts +0 -159
  347. package/dist/core/nocturnal-arbiter.js +0 -534
  348. package/dist/core/nocturnal-candidate-scoring.d.ts +0 -137
  349. package/dist/core/nocturnal-candidate-scoring.js +0 -266
  350. package/dist/core/nocturnal-compliance.d.ts +0 -175
  351. package/dist/core/nocturnal-compliance.js +0 -824
  352. package/dist/core/nocturnal-dataset.d.ts +0 -224
  353. package/dist/core/nocturnal-dataset.js +0 -443
  354. package/dist/core/nocturnal-executability.d.ts +0 -85
  355. package/dist/core/nocturnal-executability.js +0 -331
  356. package/dist/core/nocturnal-export.d.ts +0 -124
  357. package/dist/core/nocturnal-export.js +0 -275
  358. package/dist/core/nocturnal-paths.d.ts +0 -124
  359. package/dist/core/nocturnal-trajectory-extractor.d.ts +0 -242
  360. package/dist/core/nocturnal-trajectory-extractor.js +0 -307
  361. package/dist/core/nocturnal-trinity.d.ts +0 -311
  362. package/dist/core/nocturnal-trinity.js +0 -880
  363. package/dist/core/pain.d.ts +0 -4
  364. package/dist/core/pain.js +0 -70
  365. package/dist/core/path-resolver.d.ts +0 -46
  366. package/dist/core/paths.d.ts +0 -65
  367. package/dist/core/principle-training-state.d.ts +0 -121
  368. package/dist/core/principle-training-state.js +0 -321
  369. package/dist/core/profile.d.ts +0 -62
  370. package/dist/core/profile.js +0 -210
  371. package/dist/core/promotion-gate.d.ts +0 -238
  372. package/dist/core/promotion-gate.js +0 -529
  373. package/dist/core/risk-calculator.d.ts +0 -22
  374. package/dist/core/session-tracker.d.ts +0 -99
  375. package/dist/core/shadow-observation-registry.d.ts +0 -217
  376. package/dist/core/shadow-observation-registry.js +0 -308
  377. package/dist/core/system-logger.d.ts +0 -8
  378. package/dist/core/thinking-models.d.ts +0 -38
  379. package/dist/core/thinking-models.js +0 -170
  380. package/dist/core/training-program.d.ts +0 -233
  381. package/dist/core/training-program.js +0 -433
  382. package/dist/core/trajectory.d.ts +0 -411
  383. package/dist/core/trajectory.js +0 -1307
  384. package/dist/core/workspace-context.d.ts +0 -71
  385. package/dist/hooks/bash-risk.d.ts +0 -57
  386. package/dist/hooks/bash-risk.js +0 -137
  387. package/dist/hooks/edit-verification.d.ts +0 -62
  388. package/dist/hooks/edit-verification.js +0 -256
  389. package/dist/hooks/gate-block-helper.d.ts +0 -44
  390. package/dist/hooks/gate-block-helper.js +0 -119
  391. package/dist/hooks/gate.d.ts +0 -24
  392. package/dist/hooks/gate.js +0 -173
  393. package/dist/hooks/gfi-gate.d.ts +0 -40
  394. package/dist/hooks/gfi-gate.js +0 -113
  395. package/dist/hooks/lifecycle.d.ts +0 -5
  396. package/dist/hooks/lifecycle.js +0 -284
  397. package/dist/hooks/llm.d.ts +0 -12
  398. package/dist/hooks/message-sanitize.d.ts +0 -3
  399. package/dist/hooks/message-sanitize.js +0 -37
  400. package/dist/hooks/pain.d.ts +0 -5
  401. package/dist/hooks/pain.js +0 -301
  402. package/dist/hooks/progressive-trust-gate.d.ts +0 -51
  403. package/dist/hooks/progressive-trust-gate.js +0 -89
  404. package/dist/hooks/prompt.d.ts +0 -47
  405. package/dist/hooks/prompt.js +0 -884
  406. package/dist/hooks/subagent.d.ts +0 -10
  407. package/dist/hooks/subagent.js +0 -387
  408. package/dist/hooks/thinking-checkpoint.d.ts +0 -37
  409. package/dist/hooks/thinking-checkpoint.js +0 -51
  410. package/dist/hooks/trajectory-collector.d.ts +0 -32
  411. package/dist/hooks/trajectory-collector.js +0 -256
  412. package/dist/http/principles-console-route.d.ts +0 -9
  413. package/dist/http/principles-console-route.js +0 -567
  414. package/dist/i18n/commands.d.ts +0 -26
  415. package/dist/i18n/commands.js +0 -116
  416. package/dist/index.d.ts +0 -7
  417. package/dist/index.js +0 -581
  418. package/dist/service/central-database.d.ts +0 -104
  419. package/dist/service/central-database.js +0 -649
  420. package/dist/service/control-ui-query-service.d.ts +0 -221
  421. package/dist/service/control-ui-query-service.js +0 -543
  422. package/dist/service/empathy-observer-manager.d.ts +0 -52
  423. package/dist/service/empathy-observer-manager.js +0 -229
  424. package/dist/service/evolution-query-service.d.ts +0 -155
  425. package/dist/service/evolution-query-service.js +0 -258
  426. package/dist/service/evolution-worker.d.ts +0 -101
  427. package/dist/service/evolution-worker.js +0 -974
  428. package/dist/service/nocturnal-runtime.d.ts +0 -183
  429. package/dist/service/nocturnal-service.d.ts +0 -163
  430. package/dist/service/nocturnal-service.js +0 -787
  431. package/dist/service/nocturnal-target-selector.d.ts +0 -145
  432. package/dist/service/nocturnal-target-selector.js +0 -315
  433. package/dist/service/phase3-input-filter.d.ts +0 -73
  434. package/dist/service/phase3-input-filter.js +0 -172
  435. package/dist/service/runtime-summary-service.d.ts +0 -122
  436. package/dist/service/runtime-summary-service.js +0 -485
  437. package/dist/service/trajectory-service.d.ts +0 -2
  438. package/dist/service/trajectory-service.js +0 -15
  439. package/dist/tools/critique-prompt.d.ts +0 -14
  440. package/dist/tools/deep-reflect.d.ts +0 -39
  441. package/dist/tools/deep-reflect.js +0 -350
  442. package/dist/tools/model-index.d.ts +0 -9
  443. package/dist/types/event-types.d.ts +0 -306
  444. package/dist/types/event-types.js +0 -106
  445. package/dist/types/hygiene-types.d.ts +0 -20
  446. package/dist/types/hygiene-types.js +0 -12
  447. package/dist/types/runtime-summary.d.ts +0 -47
  448. package/dist/types/runtime-summary.js +0 -1
  449. package/dist/types.d.ts +0 -50
  450. package/dist/types.js +0 -22
  451. package/dist/utils/file-lock.d.ts +0 -71
  452. package/dist/utils/file-lock.js +0 -309
  453. package/dist/utils/glob-match.d.ts +0 -28
  454. package/dist/utils/hashing.d.ts +0 -9
  455. package/dist/utils/io.d.ts +0 -6
  456. package/dist/utils/io.js +0 -106
  457. package/dist/utils/nlp.d.ts +0 -9
  458. package/dist/utils/plugin-logger.d.ts +0 -39
  459. package/dist/utils/subagent-probe.d.ts +0 -34
  460. package/dist/utils/subagent-probe.js +0 -81
@@ -0,0 +1,207 @@
1
+ import type { PluginHookSubagentEndedEvent, PluginHookSubagentContext, PluginLogger, OpenClawPluginApi } from '../openclaw-sdk.js';
2
+ import * as fs from 'fs';
3
+ import { writePainFlag } from '../core/pain.js';
4
+ import { WorkspaceContext } from '../core/workspace-context.js';
5
+ // No longer needed — diagnostician runs via HEARTBEAT, not subagent
6
+ import { recordEvolutionSuccess } from '../core/evolution-engine.js';
7
+ import { WorkflowStore } from '../service/subagent-workflow/workflow-store.js';
8
+ import { EmpathyObserverWorkflowManager } from '../service/subagent-workflow/empathy-observer-workflow-manager.js';
9
+ import { DeepReflectWorkflowManager } from '../service/subagent-workflow/deep-reflect-workflow-manager.js';
10
+ import type { WorkflowManager } from '../service/subagent-workflow/types.js';
11
+
12
+ /**
13
+ * Factory to create the appropriate WorkflowManager by workflow_type string.
14
+ * Used by the subagent_ended hook to dispatch lifecycle recovery to the right manager.
15
+ */
16
+ function createWorkflowManagerForType(
17
+ workflowType: string,
18
+ workspaceDir: string,
19
+ logger: HookLogger,
20
+ subagent: NonNullable<OpenClawPluginApi['runtime']>['subagent'],
21
+ ): WorkflowManager | null {
22
+ const loggerAdapter: PluginLogger = {
23
+ info: (m: string) => logger.info(String(m)),
24
+ warn: (m: string) => logger.warn(String(m)),
25
+ error: (m: string) => logger.error(String(m)),
26
+ debug: () => {},
27
+ } as unknown as PluginLogger;
28
+
29
+ switch (workflowType) {
30
+ case 'empathy-observer':
31
+ return new EmpathyObserverWorkflowManager({
32
+ workspaceDir,
33
+ logger: loggerAdapter,
34
+ subagent,
35
+ });
36
+ case 'deep-reflect':
37
+ return new DeepReflectWorkflowManager({
38
+ workspaceDir,
39
+ logger: loggerAdapter,
40
+ subagent,
41
+ });
42
+ default:
43
+ return null;
44
+ }
45
+ }
46
+
47
+ const HELPER_WORKFLOW_SESSION_PREFIX = 'agent:main:subagent:workflow-';
48
+
49
+ type HookLogger = Pick<PluginLogger, 'info' | 'warn' | 'error'>;
50
+
51
+ // Cleanup expired retry entries periodically
52
+
53
+ function emitSubagentPainEvent(
54
+ wctx: WorkspaceContext,
55
+ payload: {
56
+ source: string;
57
+ reason: string;
58
+ score: number;
59
+ sessionId?: string;
60
+ agentId?: string;
61
+ },
62
+ logger: HookLogger
63
+ ): void {
64
+ try {
65
+ wctx.evolutionReducer.emitSync({
66
+ ts: new Date().toISOString(),
67
+ type: 'pain_detected',
68
+ data: {
69
+ painId: `pain_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`,
70
+ painType: 'subagent_error',
71
+ source: payload.source,
72
+ reason: payload.reason,
73
+ score: payload.score,
74
+ sessionId: payload.sessionId,
75
+ agentId: payload.agentId,
76
+ },
77
+ });
78
+ } catch (e) {
79
+ logger.warn(`[PD:Subagent] failed to emit evolution event: ${String(e)}`);
80
+ }
81
+ }
82
+
83
+
84
+ function extractAgentIdFromSessionKey(sessionKey: string | undefined): string | undefined {
85
+ // sessionKey format: "agent:{agentId}:{type}:{uuid}" or "agent:{agentId}:{uuid}"
86
+ if (!sessionKey) return undefined;
87
+ const match = sessionKey.match(/^agent:([^:]+):/);
88
+ return match ? match[1] : undefined;
89
+ }
90
+
91
+
92
+
93
+
94
+
95
+ type SubagentEndedHookContext = PluginHookSubagentContext & {
96
+ api?: OpenClawPluginApi;
97
+ workspaceDir?: string;
98
+ sessionId?: string;
99
+ agentId?: string;
100
+ };
101
+
102
+ export async function handleSubagentEnded(
103
+ event: PluginHookSubagentEndedEvent,
104
+ ctx: SubagentEndedHookContext
105
+ ): Promise<void> {
106
+ const { outcome, targetSessionKey } = event;
107
+ const workspaceDir = ctx.workspaceDir;
108
+
109
+ if (!workspaceDir) return;
110
+
111
+ const wctx = WorkspaceContext.fromHookContext(ctx);
112
+ const logger: HookLogger = ctx.api?.logger ?? console;
113
+ // ── Helper Workflow Lifecycle Notification ──
114
+ // When a helper workflow's subagent ends, notify the workflow manager
115
+ // so that it can trigger fallback recovery (notifyWaitResult → finalizeOnce)
116
+ if (targetSessionKey?.startsWith(HELPER_WORKFLOW_SESSION_PREFIX)) {
117
+ try {
118
+ const store = new WorkflowStore({ workspaceDir });
119
+ const workflow = store.getWorkflowByChildSession(targetSessionKey);
120
+ if (workflow && workflow.state !== 'completed' && workflow.state !== 'terminal_error' && workflow.state !== 'expired') {
121
+ logger.info(`[PD:Subagent] Helper workflow lifecycle event: workflowId=${workflow.workflow_id}, workflowType=${workflow.workflow_type}, outcome=${outcome}`);
122
+
123
+ const mappedOutcome = outcome === 'deleted' ? 'deleted' :
124
+ outcome === 'killed' ? 'killed' :
125
+ outcome === 'reset' ? 'reset' :
126
+ outcome === 'error' ? 'error' :
127
+ outcome === 'timeout' ? 'timeout' : 'ok';
128
+
129
+ // Call notifyLifecycleEvent on the appropriate manager so it
130
+ // triggers notifyWaitResult → finalizeOnce / terminal transition.
131
+ const subagentRuntime = ctx.api?.runtime?.subagent;
132
+ if (subagentRuntime) {
133
+ const mgr = createWorkflowManagerForType(workflow.workflow_type, workspaceDir, logger, subagentRuntime);
134
+ if (mgr) {
135
+ await mgr.notifyLifecycleEvent(workflow.workflow_id, 'subagent_ended', { outcome: mappedOutcome });
136
+ mgr.dispose();
137
+ } else {
138
+ logger.warn(`[PD:Subagent] Unknown workflow type ${workflow.workflow_type} — falling back to store-only event`);
139
+ store.recordEvent(workflow.workflow_id, 'subagent_ended', workflow.state, workflow.state, `subagent ended with outcome: ${outcome}`, { outcome: mappedOutcome });
140
+ }
141
+ } else {
142
+ logger.warn(`[PD:Subagent] Subagent runtime not available — cannot notify manager, falling back to store event`);
143
+ store.recordEvent(workflow.workflow_id, 'subagent_ended', workflow.state, workflow.state, `subagent ended with outcome: ${outcome}`, { outcome: mappedOutcome });
144
+ }
145
+ store.dispose();
146
+ return;
147
+ }
148
+ store.dispose();
149
+ } catch (e) {
150
+ logger.warn(`[PD:Subagent] Failed to notify helper workflow lifecycle: ${String(e)}`);
151
+ }
152
+ }
153
+
154
+ const config = wctx.config;
155
+
156
+ // ── Outcome-based EP and Pain Signal handling ──
157
+ // OpenClaw v2026.3.23 fixes: timeout may be false positive (fast-finishing workers)
158
+ // Only penalize actual errors, not timeout/killed/reset
159
+
160
+ if (outcome === 'error') {
161
+ // Only actual errors trigger penalty
162
+ const scoreSettings = config.get('scores');
163
+ const score = scoreSettings.subagent_error_penalty;
164
+ const reason = `Subagent session ${targetSessionKey} ended with error`;
165
+
166
+ writePainFlag(workspaceDir, {
167
+ source: `subagent_error`,
168
+ score: String(score),
169
+ time: new Date().toISOString(),
170
+ reason,
171
+ is_risky: 'true',
172
+ session_id: ctx.sessionId || '',
173
+ agent_id: ctx.agentId || extractAgentIdFromSessionKey(targetSessionKey) || '',
174
+ });
175
+
176
+ emitSubagentPainEvent(wctx, {
177
+ source: `subagent_error`,
178
+ reason,
179
+ score,
180
+ sessionId: ctx.sessionId,
181
+ agentId: ctx.agentId || extractAgentIdFromSessionKey(targetSessionKey),
182
+ }, logger);
183
+ }
184
+
185
+ if (outcome === 'timeout') {
186
+ // OpenClaw v2026.3.23 fix: timeout may be false positive
187
+ // Fast-finishing workers are no longer incorrectly reported as timed out
188
+ // Do not penalize - the task may have actually succeeded
189
+ logger.warn(`[PD:Subagent] Session ${targetSessionKey} timed out - not penalizing (OpenClaw fix applied)`);
190
+ }
191
+
192
+ if (outcome === 'killed' || outcome === 'reset') {
193
+ // User-initiated termination or system reset - not an agent failure
194
+ logger.info(`[PD:Subagent] Session ${targetSessionKey} ended with ${outcome} - no penalty (user/system action)`);
195
+ }
196
+
197
+ if (outcome === 'ok' || outcome === 'deleted') {
198
+ recordEvolutionSuccess(workspaceDir, 'subagent', {
199
+ sessionId: ctx.sessionId,
200
+ reason: 'subagent_success',
201
+ });
202
+ }
203
+
204
+ // ── End of subagent_ended handling ──
205
+ // Note: Diagnostician runs via HEARTBEAT (main session LLM), not as a subagent.
206
+ // Principle creation happens in evolution-worker.ts marker detection path.
207
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Thinking Checkpoint Module
3
+ *
4
+ * Enforces P-10 deep reflection requirement for high-risk tool operations.
5
+ *
6
+ * **Responsibilities:**
7
+ * - Check if high-risk tools have recent deep thinking (T-01 through T-10)
8
+ * - Block high-risk operations without preceding deep reflection
9
+ * - Configurable time window for thinking validity (default 5 minutes)
10
+ * - Provide clear guidance on required action (deep_reflect tool usage)
11
+ *
12
+ * **Configuration:**
13
+ * - Thinking checkpoint settings from profile.thinking_checkpoint
14
+ * - Window duration for thinking validity
15
+ * - High-risk tool list
16
+ */
17
+
18
+ import { hasRecentThinking } from '../core/session-tracker.js';
19
+ import type { PluginHookBeforeToolCallEvent, PluginHookBeforeToolCallResult } from '../openclaw-sdk.js';
20
+ import {
21
+ THINKING_CHECKPOINT_WINDOW_MS,
22
+ THINKING_CHECKPOINT_DEFAULT_HIGH_RISK_TOOLS
23
+ } from '../config/index.js';
24
+
25
+ export interface ThinkingCheckpointConfig {
26
+ enabled?: boolean;
27
+ window_ms?: number;
28
+ high_risk_tools?: string[];
29
+ }
30
+
31
+ /**
32
+ * Checks if a tool call requires a recent deep thinking checkpoint.
33
+ *
34
+ * This enforces P-10 (Thinking OS Checkpoint) - high-risk operations must
35
+ * be preceded by deep reflection within the configured time window.
36
+ *
37
+ * @param event - The before_tool_call event
38
+ * @param config - Thinking checkpoint configuration from profile
39
+ * @param sessionId - Current session ID
40
+ * @param logger - Optional logger for info messages
41
+ * @returns Block result if thinking required, undefined otherwise
42
+ */
43
+ export function checkThinkingCheckpoint(
44
+ event: PluginHookBeforeToolCallEvent,
45
+ config: ThinkingCheckpointConfig,
46
+ sessionId: string | undefined,
47
+ logger?: { info?: (message: string) => void }
48
+ ): PluginHookBeforeToolCallResult | undefined {
49
+ const enabled = config.enabled ?? false;
50
+ const windowMs = config.window_ms ?? THINKING_CHECKPOINT_WINDOW_MS;
51
+ const highRiskTools = config.high_risk_tools ?? [...THINKING_CHECKPOINT_DEFAULT_HIGH_RISK_TOOLS];
52
+
53
+ if (!enabled || !sessionId) {
54
+ return undefined;
55
+ }
56
+
57
+ const isHighRisk = highRiskTools.includes(event.toolName);
58
+ if (!isHighRisk) {
59
+ return undefined;
60
+ }
61
+
62
+ const hasThinking = hasRecentThinking(sessionId, windowMs);
63
+ if (!hasThinking) {
64
+ logger?.info?.(`[PD:THINKING_GATE] High-risk tool "${event.toolName}" called without recent deep thinking`);
65
+
66
+ return {
67
+ block: true,
68
+ blockReason: `[Thinking OS Checkpoint] 高风险操作 "${event.toolName}" 需要先进行深度思考。\n\n请先使用 deep_reflect 工具分析当前情况,然后再尝试此操作。\n\n这是强制性检查点,目的是确保决策质量。\n\n提示:调用 deep_reflect 后,${Math.round(windowMs/60000)}分钟内的操作将自动放行。\n\n可在PROFILE.json中设置 thinking_checkpoint.enabled: false 来禁用此检查。`,
69
+ };
70
+ }
71
+
72
+ return undefined;
73
+ }
@@ -0,0 +1,290 @@
1
+ /**
2
+ * Trajectory Collector - 行为进化引擎 Phase 0 数据收集
3
+ *
4
+ * 收集工具调用和 LLM 输出到 memory/trajectories/ 目录
5
+ * 用于分析工具使用模式、识别原则应用案例、评估行为质量
6
+ */
7
+
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ import type {
11
+ PluginHookAfterToolCallEvent,
12
+ PluginHookToolContext,
13
+ PluginHookLlmOutputEvent,
14
+ PluginHookAgentContext,
15
+ PluginHookBeforeMessageWriteEvent
16
+ } from '../openclaw-sdk.js';
17
+
18
+ const TRAJECTORY_DIR = 'memory/trajectories/';
19
+
20
+ // 敏感字段匹配正则
21
+ const SENSITIVE_KEY_PATTERN = /password|token|authorization|secret|api[_-]?key|credential|cookie|session/i;
22
+
23
+ // 最大字符串长度
24
+ const MAX_STRING_LENGTH = 1000;
25
+ const MAX_RESULT_LENGTH = 500;
26
+
27
+ /**
28
+ * 递归脱敏处理:遍历对象/数组,移除敏感字段值
29
+ */
30
+ function scrubSensitive(obj: unknown, depth = 0): unknown {
31
+ // 防止无限递归
32
+ if (depth > 10) return '[MAX_DEPTH]';
33
+
34
+ // 处理 null/undefined
35
+ if (obj == null) return obj;
36
+
37
+ // 处理基本类型
38
+ if (typeof obj !== 'object') {
39
+ if (typeof obj === 'string' && obj.length > MAX_STRING_LENGTH) {
40
+ return obj.slice(0, MAX_STRING_LENGTH) + '...[truncated]';
41
+ }
42
+ return obj;
43
+ }
44
+
45
+ // 处理数组
46
+ if (Array.isArray(obj)) {
47
+ return obj.map(item => scrubSensitive(item, depth + 1));
48
+ }
49
+
50
+ // 处理对象
51
+ const result: Record<string, unknown> = {};
52
+ for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {
53
+ if (SENSITIVE_KEY_PATTERN.test(key)) {
54
+ result[key] = '[REDACTED]';
55
+ } else {
56
+ result[key] = scrubSensitive(value, depth + 1);
57
+ }
58
+ }
59
+ return result;
60
+ }
61
+
62
+ /**
63
+ * 异步写入队列 - 确保有序、非阻塞写入
64
+ */
65
+ class AsyncWriteQueue {
66
+ private queue: Array<() => Promise<void>> = [];
67
+ private processing = false;
68
+
69
+ async enqueue(task: () => Promise<void>): Promise<void> {
70
+ this.queue.push(task);
71
+ if (!this.processing) {
72
+ this.processNext();
73
+ }
74
+ }
75
+
76
+ private async processNext(): Promise<void> {
77
+ if (this.queue.length === 0) {
78
+ this.processing = false;
79
+ return;
80
+ }
81
+
82
+ this.processing = true;
83
+ const task = this.queue.shift();
84
+
85
+ try {
86
+ await task!();
87
+ } catch {
88
+ // Silently fail - trajectory collection should not block main functionality
89
+ }
90
+
91
+ // 处理下一个任务
92
+ this.processNext();
93
+ }
94
+ }
95
+
96
+ // 全局写入队列实例
97
+ const writeQueue = new AsyncWriteQueue();
98
+
99
+ // 目录缓存(避免重复检查)
100
+ const dirCache = new Map<string, boolean>();
101
+
102
+ /**
103
+ * 确保轨迹目录存在(异步)
104
+ */
105
+ async function ensureTrajectoryDirAsync(workspaceDir: string): Promise<string> {
106
+ const dir = path.join(workspaceDir, TRAJECTORY_DIR);
107
+
108
+ if (dirCache.get(dir)) {
109
+ return dir;
110
+ }
111
+
112
+ try {
113
+ await fs.promises.mkdir(dir, { recursive: true });
114
+ dirCache.set(dir, true);
115
+ } catch {
116
+ // 目录可能已存在,忽略错误
117
+ dirCache.set(dir, true);
118
+ }
119
+
120
+ return dir;
121
+ }
122
+
123
+ /**
124
+ * 获取今日轨迹文件名
125
+ */
126
+ function getTodayFilename(): string {
127
+ const now = new Date();
128
+ const year = now.getUTCFullYear();
129
+ const month = String(now.getUTCMonth() + 1).padStart(2, '0');
130
+ return `${year}-${month}-${String(now.getUTCDate()).padStart(2, '0')}.jsonl`;
131
+ }
132
+
133
+ /**
134
+ * 写入轨迹记录(JSON Lines 格式)- 异步版本
135
+ */
136
+ function writeTrajectoryRecord(workspaceDir: string, record: object): void {
137
+ const line = JSON.stringify(record) + '\n';
138
+
139
+ writeQueue.enqueue(async () => {
140
+ const dir = await ensureTrajectoryDirAsync(workspaceDir);
141
+ const filepath = path.join(dir, getTodayFilename());
142
+ await fs.promises.appendFile(filepath, line, 'utf8');
143
+ });
144
+ }
145
+
146
+ /**
147
+ * 工具调用完成后的处理
148
+ * 记录:工具名、参数、结果、错误、执行时间
149
+ */
150
+ export function handleAfterToolCall(
151
+ event: PluginHookAfterToolCallEvent,
152
+ ctx: PluginHookToolContext & { workspaceDir?: string }
153
+ ): void {
154
+ const workspaceDir = ctx.workspaceDir;
155
+ if (!workspaceDir) return;
156
+
157
+ // 递归脱敏处理所有字段
158
+ const sanitizedParams = scrubSensitive(event.params);
159
+ const sanitizedResult = event.result == null
160
+ ? null
161
+ : String(scrubSensitive(event.result)).slice(0, MAX_RESULT_LENGTH);
162
+ const sanitizedError = event.error == null
163
+ ? null
164
+ : String(scrubSensitive(event.error));
165
+
166
+ writeTrajectoryRecord(workspaceDir, {
167
+ type: 'tool_call',
168
+ timestamp: new Date().toISOString(),
169
+ sessionId: ctx.sessionId || 'unknown',
170
+ toolName: event.toolName,
171
+ params: sanitizedParams,
172
+ result: sanitizedResult,
173
+ error: sanitizedError,
174
+ durationMs: event.durationMs,
175
+ success: !event.error,
176
+ runId: event.runId || null,
177
+ toolCallId: event.toolCallId || null
178
+ });
179
+ }
180
+
181
+ /**
182
+ * LLM 输出处理
183
+ * 记录:provider、model、输出长度、token 使用量
184
+ */
185
+ export function handleLlmOutput(
186
+ event: PluginHookLlmOutputEvent,
187
+ ctx: PluginHookAgentContext & { workspaceDir?: string }
188
+ ): void {
189
+ const workspaceDir = ctx.workspaceDir;
190
+ if (!workspaceDir) return;
191
+
192
+ const totalTextLength = event.assistantTexts?.reduce((sum, text) => sum + (text?.length || 0), 0) || 0;
193
+
194
+ writeTrajectoryRecord(workspaceDir, {
195
+ type: 'llm_output',
196
+ timestamp: new Date().toISOString(),
197
+ sessionId: ctx.sessionId || 'unknown',
198
+ provider: event.provider,
199
+ model: event.model,
200
+ textLength: totalTextLength,
201
+ outputCount: event.assistantTexts?.length || 0,
202
+ usage: event.usage ? scrubSensitive(event.usage) : null
203
+ });
204
+ }
205
+
206
+ /**
207
+ * 消息写入前的处理
208
+ * 记录:用户/助手消息内容
209
+ */
210
+ export function handleBeforeMessageWrite(
211
+ event: PluginHookBeforeMessageWriteEvent,
212
+ ctx: PluginHookAgentContext & { workspaceDir?: string }
213
+ ): void {
214
+ const workspaceDir = ctx.workspaceDir;
215
+ if (!workspaceDir) return;
216
+
217
+ const msg = event.message;
218
+ if (!msg || !msg.role) return;
219
+
220
+ // 只记录 user 和 assistant 消息
221
+ if (msg.role !== 'user' && msg.role !== 'assistant') return;
222
+
223
+ // 提取文本内容
224
+ let content = '';
225
+ if (typeof msg.content === 'string') {
226
+ content = msg.content;
227
+ } else if (Array.isArray(msg.content)) {
228
+ content = msg.content
229
+ .filter((part: any) => part?.type === 'text')
230
+ .map((part: any) => part.text)
231
+ .join('\n');
232
+ }
233
+
234
+ // 脱敏处理内容预览
235
+ const sanitizedPreview = scrubSensitive(content.slice(0, 200));
236
+
237
+ writeTrajectoryRecord(workspaceDir, {
238
+ type: 'message',
239
+ timestamp: new Date().toISOString(),
240
+ sessionId: event.sessionKey || 'unknown',
241
+ role: msg.role,
242
+ contentLength: content.length,
243
+ contentPreview: typeof sanitizedPreview === 'string' ? sanitizedPreview : '[sanitized]',
244
+ agentId: event.agentId || null
245
+ });
246
+ }
247
+
248
+ /**
249
+ * 脱敏处理:移除敏感参数(保留旧函数签名以兼容)
250
+ * @deprecated 使用 scrubSensitive 替代
251
+ */
252
+ function sanitizeParams(params: Record<string, any>): Record<string, any> {
253
+ return scrubSensitive(params) as Record<string, any>;
254
+ }
255
+
256
+ /**
257
+ * 轨迹汇总统计(供 cron 任务调用)
258
+ */
259
+ export function computeTrajectoryStats(workspaceDir: string): object {
260
+ const dir = path.join(workspaceDir, TRAJECTORY_DIR);
261
+ const todayFile = path.join(dir, getTodayFilename());
262
+
263
+ if (!fs.existsSync(todayFile)) {
264
+ return { date: getTodayFilename(), totalRecords: 0, toolCalls: 0, llmOutputs: 0, messages: 0 };
265
+ }
266
+
267
+ const content = fs.readFileSync(todayFile, 'utf8');
268
+ const lines = content.split('\n').filter(line => line.trim());
269
+
270
+ const toolCalls = lines.filter(line => {
271
+ try { return JSON.parse(line).type === 'tool_call'; } catch { return false; }
272
+ }).length;
273
+
274
+ const llmOutputs = lines.filter(line => {
275
+ try { return JSON.parse(line).type === 'llm_output'; } catch { return false; }
276
+ }).length;
277
+
278
+ const messages = lines.filter(line => {
279
+ try { return JSON.parse(line).type === 'message'; } catch { return false; }
280
+ }).length;
281
+
282
+ return {
283
+ date: getTodayFilename(),
284
+ totalRecords: lines.length,
285
+ toolCalls,
286
+ llmOutputs,
287
+ messages,
288
+ generatedAt: new Date().toISOString()
289
+ };
290
+ }