principles-disciple 1.8.1 → 1.8.3

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 (508) 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 +4 -4
  10. package/package.json +11 -13
  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} +175 -62
  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} +160 -80
  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} +235 -79
  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/{dist/service/subagent-workflow/empathy-observer-workflow-manager.js → src/service/subagent-workflow/empathy-observer-workflow-manager.ts} +240 -117
  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/{dist/service/subagent-workflow/types.d.ts → src/service/subagent-workflow/types.ts} +137 -18
  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/en/skills/ai-sprint-orchestration/EXAMPLES.md +63 -0
  138. package/templates/langs/en/skills/ai-sprint-orchestration/REFERENCE.md +136 -0
  139. package/templates/langs/en/skills/ai-sprint-orchestration/SKILL.md +67 -0
  140. package/templates/langs/en/skills/ai-sprint-orchestration/references/agent-registry.json +214 -0
  141. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +107 -0
  142. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +107 -0
  143. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +105 -0
  144. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +108 -0
  145. package/templates/langs/en/skills/ai-sprint-orchestration/references/workflow-v1-acceptance-checklist.md +58 -0
  146. package/templates/langs/en/skills/ai-sprint-orchestration/references/workflow-v1.4-work-unit-handoff.md +190 -0
  147. package/templates/langs/en/skills/ai-sprint-orchestration/runtime/.gitignore +2 -0
  148. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/archive.mjs +310 -0
  149. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/contract-enforcement.mjs +683 -0
  150. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/decision.mjs +604 -0
  151. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/state-store.mjs +32 -0
  152. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/task-specs.mjs +707 -0
  153. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/run.mjs +3419 -0
  154. package/templates/langs/zh/skills/ai-sprint-orchestration/EXAMPLES.md +63 -0
  155. package/templates/langs/zh/skills/ai-sprint-orchestration/REFERENCE.md +136 -0
  156. package/templates/langs/zh/skills/ai-sprint-orchestration/SKILL.md +67 -0
  157. package/templates/langs/zh/skills/ai-sprint-orchestration/references/agent-registry.json +214 -0
  158. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +107 -0
  159. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +107 -0
  160. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +105 -0
  161. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +108 -0
  162. package/templates/langs/zh/skills/ai-sprint-orchestration/references/workflow-v1-acceptance-checklist.md +58 -0
  163. package/templates/langs/zh/skills/ai-sprint-orchestration/references/workflow-v1.4-work-unit-handoff.md +190 -0
  164. package/templates/langs/zh/skills/ai-sprint-orchestration/runtime/.gitignore +2 -0
  165. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/archive.mjs +310 -0
  166. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/contract-enforcement.mjs +683 -0
  167. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/decision.mjs +604 -0
  168. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/state-store.mjs +32 -0
  169. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/task-specs.mjs +707 -0
  170. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/run.mjs +3419 -0
  171. package/templates/langs/zh/skills/ai-sprint-orchestration/test/archive.test.mjs +230 -0
  172. package/templates/langs/zh/skills/ai-sprint-orchestration/test/contract-enforcement.test.mjs +672 -0
  173. package/templates/langs/zh/skills/ai-sprint-orchestration/test/decision.test.mjs +1321 -0
  174. package/templates/langs/zh/skills/ai-sprint-orchestration/test/run.test.mjs +1419 -0
  175. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +70 -1
  176. package/templates/pain_settings.json +2 -1
  177. package/tests/README.md +120 -0
  178. package/tests/build-artifacts.test.ts +111 -0
  179. package/tests/commands/evolution-status.test.ts +222 -0
  180. package/tests/commands/evolver.test.ts +22 -0
  181. package/tests/commands/export.test.ts +78 -0
  182. package/tests/commands/nocturnal-review.test.ts +448 -0
  183. package/tests/commands/nocturnal-train.test.ts +97 -0
  184. package/tests/commands/pain.test.ts +108 -0
  185. package/tests/commands/samples.test.ts +65 -0
  186. package/tests/commands/strategy.test.ts +34 -0
  187. package/tests/commands/thinking-os.test.ts +88 -0
  188. package/tests/core/adaptive-thresholds.test.ts +261 -0
  189. package/tests/core/config-service.test.ts +89 -0
  190. package/tests/core/config.test.ts +90 -0
  191. package/tests/core/control-ui-db.test.ts +75 -0
  192. package/tests/core/core-template-guidance.test.ts +21 -0
  193. package/tests/core/detection-funnel.test.ts +63 -0
  194. package/tests/core/detection-service.test.ts +50 -0
  195. package/tests/core/dictionary-service.test.ts +116 -0
  196. package/tests/core/dictionary.test.ts +168 -0
  197. package/tests/core/empathy-keyword-matcher.test.ts +209 -0
  198. package/tests/core/event-log.test.ts +181 -0
  199. package/tests/core/evolution-e2e.test.ts +58 -0
  200. package/tests/core/evolution-engine-gate-integration.test.ts +543 -0
  201. package/tests/core/evolution-engine.test.ts +562 -0
  202. package/tests/core/evolution-logger.test.ts +148 -0
  203. package/tests/core/evolution-migration.test.ts +50 -0
  204. package/tests/core/evolution-paths.test.ts +21 -0
  205. package/tests/core/evolution-reducer.detector-metadata.test.ts +602 -0
  206. package/tests/core/evolution-reducer.test.ts +180 -0
  207. package/tests/core/evolution-types-loop.test.ts +48 -0
  208. package/tests/core/evolution-user-stories.e2e.test.ts +249 -0
  209. package/tests/core/external-training-contract.test.ts +463 -0
  210. package/tests/core/focus-history.test.ts +682 -0
  211. package/tests/core/init-flatten.test.ts +69 -0
  212. package/tests/core/init-refactor.test.ts +87 -0
  213. package/tests/core/init-v1.3.test.ts +46 -0
  214. package/tests/core/init.test.ts +190 -0
  215. package/tests/core/local-worker-routing.test.ts +757 -0
  216. package/tests/core/migration.test.ts +84 -0
  217. package/tests/core/model-deployment-registry.test.ts +845 -0
  218. package/tests/core/model-training-registry.test.ts +889 -0
  219. package/tests/core/nocturnal-arbiter.test.ts +494 -0
  220. package/tests/core/nocturnal-candidate-scoring.test.ts +400 -0
  221. package/tests/core/nocturnal-compliance.test.ts +646 -0
  222. package/tests/core/nocturnal-dataset.test.ts +892 -0
  223. package/tests/core/nocturnal-executability.test.ts +357 -0
  224. package/tests/core/nocturnal-export.test.ts +462 -0
  225. package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +428 -0
  226. package/tests/core/nocturnal-trajectory-extractor.test.ts +634 -0
  227. package/tests/core/nocturnal-trinity.test.ts +953 -0
  228. package/tests/core/pain.test.ts +33 -0
  229. package/tests/core/path-resolver.test.ts +57 -0
  230. package/tests/core/paths-refactor.test.ts +42 -0
  231. package/tests/core/phase7-rollout-integration.test.ts +477 -0
  232. package/tests/core/principle-training-state.test.ts +712 -0
  233. package/tests/core/profile.test.ts +56 -0
  234. package/tests/core/promotion-gate.test.ts +556 -0
  235. package/tests/core/risk-calculator.test.ts +168 -0
  236. package/tests/core/session-tracker.test.ts +191 -0
  237. package/tests/core/training-program.test.ts +472 -0
  238. package/tests/core/trajectory.test.ts +265 -0
  239. package/tests/core/workspace-context-factory.test.ts +18 -0
  240. package/tests/core/workspace-context.test.ts +134 -0
  241. package/tests/fixtures/nocturnal-reviewed-subset.json +183 -0
  242. package/tests/fixtures/production-compatibility.test.ts +147 -0
  243. package/tests/fixtures/production-mock-generator.ts +282 -0
  244. package/tests/hooks/bash-risk-integration.test.ts +137 -0
  245. package/tests/hooks/bash-risk.test.ts +81 -0
  246. package/tests/hooks/edit-verification.test.ts +678 -0
  247. package/tests/hooks/gate-edit-verification-p1.test.ts +632 -0
  248. package/tests/hooks/gate-edit-verification.test.ts +435 -0
  249. package/tests/hooks/gate-pipeline-integration.test.ts +404 -0
  250. package/tests/hooks/gate.test.ts +271 -0
  251. package/tests/hooks/gfi-gate-unit.test.ts +422 -0
  252. package/tests/hooks/gfi-gate.test.ts +669 -0
  253. package/tests/hooks/lifecycle.test.ts +248 -0
  254. package/tests/hooks/llm.test.ts +308 -0
  255. package/tests/hooks/message-sanitize.test.ts +36 -0
  256. package/tests/hooks/pain.test.ts +141 -0
  257. package/tests/hooks/progressive-trust-gate.test.ts +277 -0
  258. package/tests/hooks/prompt.test.ts +1411 -0
  259. package/tests/hooks/subagent.test.ts +467 -0
  260. package/tests/hooks/thinking-gate.test.ts +313 -0
  261. package/tests/http/principles-console-route.test.ts +140 -0
  262. package/tests/hygiene-tracker.test.ts +77 -0
  263. package/tests/index.integration.test.ts +179 -0
  264. package/tests/index.shadow-routing.integration.test.ts +140 -0
  265. package/tests/index.test.ts +9 -0
  266. package/tests/integration/empathy-workflow-integration.test.ts +627 -0
  267. package/tests/service/control-ui-query-service.test.ts +121 -0
  268. package/tests/service/empathy-observer-workflow-manager.test.ts +176 -0
  269. package/tests/service/evolution-worker.test.ts +585 -0
  270. package/tests/service/nocturnal-runtime.test.ts +470 -0
  271. package/tests/service/nocturnal-service.test.ts +577 -0
  272. package/tests/service/nocturnal-target-selector.test.ts +615 -0
  273. package/tests/service/nocturnal-workflow-manager.test.ts +439 -0
  274. package/tests/service/phase3-input-filter.test.ts +289 -0
  275. package/tests/service/runtime-summary-service.test.ts +919 -0
  276. package/tests/task-compliance.test.ts +166 -0
  277. package/tests/test-utils.ts +48 -0
  278. package/tests/tools/critique-prompt.test.ts +260 -0
  279. package/tests/tools/deep-reflect.test.ts +232 -0
  280. package/tests/tools/model-index.test.ts +246 -0
  281. package/tests/ui/app.test.tsx +114 -0
  282. package/tests/utils/file-lock.test.ts +407 -0
  283. package/tests/utils/hashing.test.ts +32 -0
  284. package/tests/utils/io.test.ts +39 -0
  285. package/tests/utils/nlp.test.ts +53 -0
  286. package/tests/utils/plugin-logger.test.ts +156 -0
  287. package/tsconfig.json +16 -0
  288. package/tsconfig.tsbuildinfo +1 -0
  289. package/ui/src/App.tsx +45 -0
  290. package/ui/src/api.ts +216 -0
  291. package/ui/src/charts.tsx +586 -0
  292. package/ui/src/components/ErrorState.tsx +6 -0
  293. package/ui/src/components/Loading.tsx +13 -0
  294. package/ui/src/components/ProtectedRoute.tsx +12 -0
  295. package/ui/src/components/Shell.tsx +91 -0
  296. package/ui/src/components/WorkspaceConfig.tsx +146 -0
  297. package/ui/src/components/index.ts +5 -0
  298. package/ui/src/context/auth.tsx +80 -0
  299. package/ui/src/context/theme.tsx +66 -0
  300. package/ui/src/hooks/useAutoRefresh.ts +39 -0
  301. package/ui/src/i18n/ui.ts +363 -0
  302. package/ui/src/main.tsx +16 -0
  303. package/ui/src/pages/EvolutionPage.tsx +352 -0
  304. package/ui/src/pages/FeedbackPage.tsx +140 -0
  305. package/ui/src/pages/GateMonitorPage.tsx +136 -0
  306. package/ui/src/pages/LoginPage.tsx +88 -0
  307. package/ui/src/pages/OverviewPage.tsx +238 -0
  308. package/ui/src/pages/SamplesPage.tsx +174 -0
  309. package/ui/src/pages/ThinkingModelsPage.tsx +127 -0
  310. package/ui/src/styles.css +1661 -0
  311. package/ui/src/types.ts +368 -0
  312. package/ui/src/utils/format.ts +15 -0
  313. package/vitest.config.ts +23 -0
  314. package/dist/commands/capabilities.d.ts +0 -3
  315. package/dist/commands/capabilities.js +0 -73
  316. package/dist/commands/context.d.ts +0 -5
  317. package/dist/commands/evolution-status.d.ts +0 -4
  318. package/dist/commands/evolution-status.js +0 -117
  319. package/dist/commands/evolver.d.ts +0 -9
  320. package/dist/commands/evolver.js +0 -26
  321. package/dist/commands/export.d.ts +0 -2
  322. package/dist/commands/export.js +0 -98
  323. package/dist/commands/focus.d.ts +0 -14
  324. package/dist/commands/focus.js +0 -457
  325. package/dist/commands/nocturnal-review.d.ts +0 -24
  326. package/dist/commands/nocturnal-review.js +0 -265
  327. package/dist/commands/nocturnal-rollout.d.ts +0 -27
  328. package/dist/commands/nocturnal-rollout.js +0 -671
  329. package/dist/commands/nocturnal-train.d.ts +0 -25
  330. package/dist/commands/nocturnal-train.js +0 -919
  331. package/dist/commands/pain.d.ts +0 -5
  332. package/dist/commands/principle-rollback.d.ts +0 -4
  333. package/dist/commands/principle-rollback.js +0 -22
  334. package/dist/commands/rollback.d.ts +0 -19
  335. package/dist/commands/samples.d.ts +0 -2
  336. package/dist/commands/samples.js +0 -55
  337. package/dist/commands/strategy.d.ts +0 -3
  338. package/dist/commands/strategy.js +0 -29
  339. package/dist/commands/thinking-os.d.ts +0 -2
  340. package/dist/config/defaults/runtime.d.ts +0 -40
  341. package/dist/config/errors.d.ts +0 -84
  342. package/dist/config/errors.js +0 -94
  343. package/dist/config/index.js +0 -7
  344. package/dist/constants/diagnostician.d.ts +0 -12
  345. package/dist/constants/diagnostician.js +0 -56
  346. package/dist/constants/tools.d.ts +0 -17
  347. package/dist/constants/tools.js +0 -54
  348. package/dist/core/adaptive-thresholds.d.ts +0 -186
  349. package/dist/core/adaptive-thresholds.js +0 -300
  350. package/dist/core/config-service.d.ts +0 -15
  351. package/dist/core/config.d.ts +0 -129
  352. package/dist/core/control-ui-db.d.ts +0 -95
  353. package/dist/core/control-ui-db.js +0 -292
  354. package/dist/core/detection-funnel.d.ts +0 -33
  355. package/dist/core/detection-service.d.ts +0 -15
  356. package/dist/core/dictionary-service.d.ts +0 -15
  357. package/dist/core/dictionary.d.ts +0 -38
  358. package/dist/core/event-log.d.ts +0 -82
  359. package/dist/core/event-log.js +0 -463
  360. package/dist/core/evolution-engine.d.ts +0 -118
  361. package/dist/core/evolution-engine.js +0 -464
  362. package/dist/core/evolution-logger.d.ts +0 -137
  363. package/dist/core/evolution-logger.js +0 -256
  364. package/dist/core/evolution-migration.d.ts +0 -5
  365. package/dist/core/evolution-migration.js +0 -65
  366. package/dist/core/evolution-reducer.d.ts +0 -98
  367. package/dist/core/evolution-reducer.js +0 -465
  368. package/dist/core/evolution-types.d.ts +0 -287
  369. package/dist/core/evolution-types.js +0 -78
  370. package/dist/core/external-training-contract.d.ts +0 -276
  371. package/dist/core/external-training-contract.js +0 -269
  372. package/dist/core/focus-history.d.ts +0 -210
  373. package/dist/core/focus-history.js +0 -1185
  374. package/dist/core/hygiene/tracker.d.ts +0 -22
  375. package/dist/core/hygiene/tracker.js +0 -106
  376. package/dist/core/init.d.ts +0 -12
  377. package/dist/core/local-worker-routing.d.ts +0 -175
  378. package/dist/core/local-worker-routing.js +0 -525
  379. package/dist/core/migration.d.ts +0 -6
  380. package/dist/core/model-deployment-registry.d.ts +0 -218
  381. package/dist/core/model-deployment-registry.js +0 -503
  382. package/dist/core/model-training-registry.d.ts +0 -295
  383. package/dist/core/model-training-registry.js +0 -475
  384. package/dist/core/nocturnal-arbiter.d.ts +0 -159
  385. package/dist/core/nocturnal-arbiter.js +0 -534
  386. package/dist/core/nocturnal-candidate-scoring.d.ts +0 -137
  387. package/dist/core/nocturnal-candidate-scoring.js +0 -266
  388. package/dist/core/nocturnal-compliance.d.ts +0 -175
  389. package/dist/core/nocturnal-compliance.js +0 -824
  390. package/dist/core/nocturnal-dataset.d.ts +0 -224
  391. package/dist/core/nocturnal-dataset.js +0 -443
  392. package/dist/core/nocturnal-executability.d.ts +0 -85
  393. package/dist/core/nocturnal-executability.js +0 -331
  394. package/dist/core/nocturnal-export.d.ts +0 -124
  395. package/dist/core/nocturnal-export.js +0 -275
  396. package/dist/core/nocturnal-paths.d.ts +0 -124
  397. package/dist/core/nocturnal-trajectory-extractor.d.ts +0 -242
  398. package/dist/core/nocturnal-trajectory-extractor.js +0 -307
  399. package/dist/core/nocturnal-trinity.d.ts +0 -311
  400. package/dist/core/nocturnal-trinity.js +0 -880
  401. package/dist/core/pain.d.ts +0 -4
  402. package/dist/core/pain.js +0 -70
  403. package/dist/core/path-resolver.d.ts +0 -46
  404. package/dist/core/paths.d.ts +0 -65
  405. package/dist/core/principle-training-state.d.ts +0 -121
  406. package/dist/core/principle-training-state.js +0 -321
  407. package/dist/core/profile.d.ts +0 -62
  408. package/dist/core/profile.js +0 -210
  409. package/dist/core/promotion-gate.d.ts +0 -238
  410. package/dist/core/promotion-gate.js +0 -529
  411. package/dist/core/risk-calculator.d.ts +0 -22
  412. package/dist/core/session-tracker.d.ts +0 -101
  413. package/dist/core/shadow-observation-registry.d.ts +0 -217
  414. package/dist/core/shadow-observation-registry.js +0 -308
  415. package/dist/core/system-logger.d.ts +0 -8
  416. package/dist/core/thinking-models.d.ts +0 -38
  417. package/dist/core/thinking-models.js +0 -170
  418. package/dist/core/training-program.d.ts +0 -233
  419. package/dist/core/training-program.js +0 -433
  420. package/dist/core/trajectory.d.ts +0 -411
  421. package/dist/core/trajectory.js +0 -1307
  422. package/dist/core/workspace-context.d.ts +0 -71
  423. package/dist/hooks/bash-risk.d.ts +0 -57
  424. package/dist/hooks/bash-risk.js +0 -137
  425. package/dist/hooks/edit-verification.d.ts +0 -62
  426. package/dist/hooks/edit-verification.js +0 -256
  427. package/dist/hooks/gate-block-helper.d.ts +0 -44
  428. package/dist/hooks/gate-block-helper.js +0 -119
  429. package/dist/hooks/gate.d.ts +0 -24
  430. package/dist/hooks/gate.js +0 -173
  431. package/dist/hooks/gfi-gate.d.ts +0 -40
  432. package/dist/hooks/gfi-gate.js +0 -113
  433. package/dist/hooks/lifecycle.d.ts +0 -5
  434. package/dist/hooks/lifecycle.js +0 -284
  435. package/dist/hooks/llm.d.ts +0 -13
  436. package/dist/hooks/message-sanitize.d.ts +0 -3
  437. package/dist/hooks/message-sanitize.js +0 -37
  438. package/dist/hooks/pain.d.ts +0 -5
  439. package/dist/hooks/pain.js +0 -301
  440. package/dist/hooks/progressive-trust-gate.d.ts +0 -52
  441. package/dist/hooks/progressive-trust-gate.js +0 -134
  442. package/dist/hooks/prompt.d.ts +0 -49
  443. package/dist/hooks/prompt.js +0 -905
  444. package/dist/hooks/subagent.d.ts +0 -10
  445. package/dist/hooks/subagent.js +0 -387
  446. package/dist/hooks/thinking-checkpoint.d.ts +0 -37
  447. package/dist/hooks/thinking-checkpoint.js +0 -51
  448. package/dist/hooks/trajectory-collector.d.ts +0 -32
  449. package/dist/hooks/trajectory-collector.js +0 -256
  450. package/dist/http/principles-console-route.d.ts +0 -9
  451. package/dist/http/principles-console-route.js +0 -681
  452. package/dist/i18n/commands.d.ts +0 -26
  453. package/dist/i18n/commands.js +0 -116
  454. package/dist/index.d.ts +0 -7
  455. package/dist/index.js +0 -581
  456. package/dist/service/central-database.d.ts +0 -104
  457. package/dist/service/central-database.js +0 -649
  458. package/dist/service/control-ui-query-service.d.ts +0 -221
  459. package/dist/service/control-ui-query-service.js +0 -543
  460. package/dist/service/empathy-observer-manager.d.ts +0 -88
  461. package/dist/service/empathy-observer-manager.js +0 -414
  462. package/dist/service/evolution-query-service.d.ts +0 -155
  463. package/dist/service/evolution-query-service.js +0 -258
  464. package/dist/service/evolution-worker.d.ts +0 -101
  465. package/dist/service/evolution-worker.js +0 -975
  466. package/dist/service/health-query-service.d.ts +0 -170
  467. package/dist/service/health-query-service.js +0 -662
  468. package/dist/service/nocturnal-runtime.d.ts +0 -183
  469. package/dist/service/nocturnal-service.d.ts +0 -163
  470. package/dist/service/nocturnal-service.js +0 -787
  471. package/dist/service/nocturnal-target-selector.d.ts +0 -145
  472. package/dist/service/nocturnal-target-selector.js +0 -315
  473. package/dist/service/phase3-input-filter.d.ts +0 -73
  474. package/dist/service/phase3-input-filter.js +0 -172
  475. package/dist/service/runtime-summary-service.d.ts +0 -122
  476. package/dist/service/runtime-summary-service.js +0 -485
  477. package/dist/service/subagent-workflow/empathy-observer-workflow-manager.d.ts +0 -48
  478. package/dist/service/subagent-workflow/index.d.ts +0 -4
  479. package/dist/service/subagent-workflow/index.js +0 -3
  480. package/dist/service/subagent-workflow/runtime-direct-driver.d.ts +0 -77
  481. package/dist/service/subagent-workflow/runtime-direct-driver.js +0 -75
  482. package/dist/service/subagent-workflow/types.js +0 -11
  483. package/dist/service/subagent-workflow/workflow-store.d.ts +0 -26
  484. package/dist/service/subagent-workflow/workflow-store.js +0 -165
  485. package/dist/service/trajectory-service.d.ts +0 -2
  486. package/dist/service/trajectory-service.js +0 -15
  487. package/dist/tools/critique-prompt.d.ts +0 -14
  488. package/dist/tools/deep-reflect.d.ts +0 -39
  489. package/dist/tools/deep-reflect.js +0 -350
  490. package/dist/tools/model-index.d.ts +0 -9
  491. package/dist/types/event-types.d.ts +0 -306
  492. package/dist/types/event-types.js +0 -106
  493. package/dist/types/hygiene-types.d.ts +0 -20
  494. package/dist/types/hygiene-types.js +0 -12
  495. package/dist/types/runtime-summary.d.ts +0 -47
  496. package/dist/types/runtime-summary.js +0 -1
  497. package/dist/types.d.ts +0 -50
  498. package/dist/types.js +0 -22
  499. package/dist/utils/file-lock.d.ts +0 -71
  500. package/dist/utils/file-lock.js +0 -309
  501. package/dist/utils/glob-match.d.ts +0 -28
  502. package/dist/utils/hashing.d.ts +0 -9
  503. package/dist/utils/io.d.ts +0 -6
  504. package/dist/utils/io.js +0 -106
  505. package/dist/utils/nlp.d.ts +0 -9
  506. package/dist/utils/plugin-logger.d.ts +0 -39
  507. package/dist/utils/subagent-probe.d.ts +0 -34
  508. 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
+ }