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
@@ -1,30 +1,63 @@
1
- import { RuntimeDirectDriver } from './runtime-direct-driver.js';
1
+ import type { PluginLogger } from '../../openclaw-sdk.js';
2
+ import type {
3
+ WorkflowManager,
4
+ WorkflowHandle,
5
+ SubagentWorkflowSpec,
6
+ WorkflowMetadata,
7
+ WorkflowDebugSummary,
8
+ EmpathyObserverPayload,
9
+ EmpathyResult,
10
+ WorkflowResultContext,
11
+ WorkflowPersistContext,
12
+ } from './types.js';
13
+ import { RuntimeDirectDriver, type RunParams } from './runtime-direct-driver.js';
2
14
  import { WorkflowStore } from './workflow-store.js';
3
15
  import { isSubagentRuntimeAvailable } from '../../utils/subagent-probe.js';
4
16
  import { WorkspaceContext } from '../../core/workspace-context.js';
5
17
  import { trackFriction } from '../../core/session-tracker.js';
18
+
6
19
  const WORKFLOW_SESSION_PREFIX = 'agent:main:subagent:workflow-';
20
+
7
21
  const DEFAULT_TIMEOUT_MS = 30_000;
8
22
  const DEFAULT_TTL_MS = 5 * 60 * 1000;
9
- export class EmpathyObserverWorkflowManager {
10
- store;
11
- driver;
12
- logger;
13
- workspaceDir;
14
- activeWorkflows = new Map();
15
- completedWorkflows = new Map();
16
- workflowSpecs = new Map();
17
- constructor(opts) {
23
+
24
+ export interface EmpathyObserverWorkflowOptions {
25
+ workspaceDir: string;
26
+ logger: PluginLogger;
27
+ subagent: RuntimeDirectDriver['subagent'];
28
+ }
29
+
30
+ export class EmpathyObserverWorkflowManager implements WorkflowManager {
31
+ private readonly store: WorkflowStore;
32
+ private readonly driver: RuntimeDirectDriver;
33
+ private readonly logger: PluginLogger;
34
+ private readonly workspaceDir: string;
35
+
36
+ private activeWorkflows = new Map<string, NodeJS.Timeout>();
37
+ private completedWorkflows = new Map<string, number>();
38
+ private workflowSpecs = new Map<string, SubagentWorkflowSpec<unknown>>();
39
+
40
+ constructor(opts: EmpathyObserverWorkflowOptions) {
18
41
  this.workspaceDir = opts.workspaceDir;
19
42
  this.logger = opts.logger;
20
43
  this.store = new WorkflowStore({ workspaceDir: opts.workspaceDir });
21
44
  this.driver = new RuntimeDirectDriver({ subagent: opts.subagent, logger: opts.logger });
22
45
  }
23
- async startWorkflow(spec, options) {
46
+
47
+ async startWorkflow<TResult>(
48
+ spec: SubagentWorkflowSpec<TResult>,
49
+ options: {
50
+ parentSessionId: string;
51
+ workspaceDir?: string;
52
+ taskInput: unknown;
53
+ metadata?: Record<string, unknown>;
54
+ }
55
+ ): Promise<WorkflowHandle> {
24
56
  const workflowId = this.generateWorkflowId();
25
57
  const childSessionKey = this.buildChildSessionKey(options.parentSessionId);
26
58
  const now = Date.now();
27
- const metadata = {
59
+
60
+ const metadata: WorkflowMetadata = {
28
61
  parentSessionId: options.parentSessionId,
29
62
  workspaceDir: options.workspaceDir,
30
63
  taskInput: options.taskInput,
@@ -32,22 +65,28 @@ export class EmpathyObserverWorkflowManager {
32
65
  workflowType: spec.workflowType,
33
66
  ...options.metadata,
34
67
  };
68
+
35
69
  this.logger.info(`[PD:EmpathyObserverWorkflow] Starting workflow: workflowId=${workflowId}, type=${spec.workflowType}`);
70
+
36
71
  // Surface degrade: skip boot sessions (they run outside gateway request context)
37
72
  if (options.parentSessionId.startsWith('boot-')) {
38
73
  this.logger.info(`[PD:EmpathyObserverWorkflow] Skipping workflow: boot session (gateway request context unavailable)`);
39
74
  throw new Error(`EmpathyObserverWorkflowManager: cannot start workflow for boot session`);
40
75
  }
76
+
41
77
  // Surface degrade: check subagent runtime availability before calling run()
42
78
  if (!isSubagentRuntimeAvailable(this.driver.getSubagent())) {
43
79
  this.logger.info(`[PD:EmpathyObserverWorkflow] Skipping workflow: subagent runtime unavailable`);
44
80
  throw new Error(`EmpathyObserverWorkflowManager: subagent runtime unavailable`);
45
81
  }
82
+
46
83
  if (spec.transport !== 'runtime_direct') {
47
84
  throw new Error(`EmpathyObserverWorkflowManager only supports runtime_direct transport`);
48
85
  }
86
+
49
87
  const runParams = this.buildRunParams(spec, options, childSessionKey);
50
88
  const runResult = await this.driver.run(runParams);
89
+
51
90
  this.store.createWorkflow({
52
91
  workflow_id: workflowId,
53
92
  workflow_type: spec.workflowType,
@@ -61,8 +100,10 @@ export class EmpathyObserverWorkflowManager {
61
100
  metadata_json: JSON.stringify(metadata),
62
101
  });
63
102
  this.store.recordEvent(workflowId, 'spawned', null, 'active', 'subagent spawned', { runId: runResult.runId });
64
- this.workflowSpecs.set(workflowId, spec);
103
+ this.workflowSpecs.set(workflowId, spec as SubagentWorkflowSpec<unknown>);
104
+
65
105
  this.scheduleWaitPoll(workflowId, spec.timeoutMs ?? DEFAULT_TIMEOUT_MS, runResult.runId);
106
+
66
107
  return {
67
108
  workflowId,
68
109
  childSessionKey,
@@ -70,7 +111,17 @@ export class EmpathyObserverWorkflowManager {
70
111
  state: 'active',
71
112
  };
72
113
  }
73
- buildRunParams(spec, options, childSessionKey) {
114
+
115
+ private buildRunParams<TResult>(
116
+ spec: SubagentWorkflowSpec<TResult>,
117
+ options: {
118
+ parentSessionId: string;
119
+ workspaceDir?: string;
120
+ taskInput: unknown;
121
+ metadata?: Record<string, unknown>;
122
+ },
123
+ childSessionKey: string
124
+ ): RunParams {
74
125
  const message = spec.buildPrompt(options.taskInput, {
75
126
  parentSessionId: options.parentSessionId,
76
127
  workspaceDir: options.workspaceDir,
@@ -79,16 +130,20 @@ export class EmpathyObserverWorkflowManager {
79
130
  workflowType: spec.workflowType,
80
131
  ...(options.metadata ?? {}),
81
132
  });
133
+
82
134
  return {
83
135
  sessionKey: childSessionKey,
84
136
  message,
85
137
  lane: 'subagent',
86
138
  deliver: false,
87
- idempotencyKey: `${options.parentSessionId}:${Date.now()}`,
139
+ idempotencyKey: options.parentSessionId
140
+ ? `${options.parentSessionId}:${Date.now()}`
141
+ : `pd:${childSessionKey}:${Date.now()}`,
88
142
  expectsCompletionMessage: true,
89
143
  };
90
144
  }
91
- static buildEmpathyPrompt(userMessage) {
145
+
146
+ static buildEmpathyPrompt(userMessage: string): string {
92
147
  return [
93
148
  'You are an empathy observer.',
94
149
  'Analyze ONLY the user message and return strict JSON (no markdown):',
@@ -96,92 +151,122 @@ export class EmpathyObserverWorkflowManager {
96
151
  `User message: ${JSON.stringify(userMessage.trim())}`,
97
152
  ].join('\n');
98
153
  }
99
- scheduleWaitPoll(workflowId, timeoutMs, runId) {
154
+
155
+ private scheduleWaitPoll(
156
+ workflowId: string,
157
+ timeoutMs: number,
158
+ runId: string
159
+ ): void {
100
160
  const effectiveTimeoutMs = timeoutMs ?? DEFAULT_TIMEOUT_MS;
161
+
101
162
  const timeout = setTimeout(async () => {
102
163
  try {
103
164
  const result = await this.driver.wait({ runId, timeoutMs: effectiveTimeoutMs });
104
165
  await this.notifyWaitResult(workflowId, result.status, result.error);
105
- }
106
- catch (error) {
166
+ } catch (error) {
107
167
  this.logger.error(`[PD:EmpathyObserverWorkflow] Wait poll failed: ${String(error)}`);
108
168
  await this.notifyWaitResult(workflowId, 'error', String(error));
109
169
  }
110
170
  }, 100);
171
+
111
172
  this.activeWorkflows.set(workflowId, timeout);
112
173
  }
113
- async notifyWaitResult(workflowId, status, error) {
174
+
175
+ async notifyWaitResult(
176
+ workflowId: string,
177
+ status: 'ok' | 'error' | 'timeout',
178
+ error?: string
179
+ ): Promise<void> {
114
180
  const workflow = this.store.getWorkflow(workflowId);
115
181
  if (!workflow) {
116
182
  this.logger.warn(`[PD:EmpathyObserverWorkflow] notifyWaitResult: workflow not found: ${workflowId}`);
117
183
  return;
118
184
  }
185
+
119
186
  if (workflow.state === 'completed' || workflow.state === 'terminal_error' || workflow.state === 'expired') {
120
187
  this.logger.info(`[PD:EmpathyObserverWorkflow] notifyWaitResult: ignoring terminal workflow: ${workflowId}, state=${workflow.state}`);
121
188
  return;
122
189
  }
190
+
123
191
  this.logger.info(`[PD:EmpathyObserverWorkflow] notifyWaitResult: workflowId=${workflowId}, status=${status}`);
192
+
124
193
  const previousState = workflow.state;
125
194
  this.store.updateWorkflowState(workflowId, 'wait_result');
126
195
  this.store.recordEvent(workflowId, 'wait_result', previousState, 'wait_result', `wait completed: ${status}`, { error });
196
+
127
197
  const spec = this.workflowSpecs.get(workflowId);
128
198
  const shouldFinalize = spec ? spec.shouldFinalizeOnWaitStatus(status) : status === 'ok';
199
+
129
200
  if (shouldFinalize) {
130
201
  await this.finalizeOnce(workflowId);
131
- }
132
- else {
202
+ } else {
133
203
  this.store.updateWorkflowState(workflowId, 'terminal_error');
134
204
  this.store.recordEvent(workflowId, 'finalize_skipped', 'wait_result', 'terminal_error', `wait status: ${status}`, { error });
135
205
  }
136
206
  }
137
- async notifyLifecycleEvent(workflowId, event, data) {
207
+
208
+ async notifyLifecycleEvent(
209
+ workflowId: string,
210
+ event: 'subagent_spawned' | 'subagent_ended',
211
+ data?: { outcome?: 'ok' | 'error' | 'timeout' | 'killed' | 'reset' | 'deleted'; error?: string }
212
+ ): Promise<void> {
138
213
  this.logger.info(`[PD:EmpathyObserverWorkflow] notifyLifecycleEvent: workflowId=${workflowId}, event=${event}`);
214
+
139
215
  if (event === 'subagent_ended' && data?.outcome) {
140
216
  await this.notifyWaitResult(workflowId, data.outcome === 'ok' ? 'ok' : data.outcome === 'error' ? 'error' : 'timeout', data.error);
141
217
  }
142
218
  }
143
- async finalizeOnce(workflowId) {
219
+
220
+ async finalizeOnce(workflowId: string): Promise<void> {
144
221
  const workflow = this.store.getWorkflow(workflowId);
145
222
  if (!workflow) {
146
223
  this.logger.warn(`[PD:EmpathyObserverWorkflow] finalizeOnce: workflow not found: ${workflowId}`);
147
224
  return;
148
225
  }
226
+
149
227
  const spec = this.workflowSpecs.get(workflowId);
150
228
  if (!spec) {
151
229
  throw new Error(`Workflow spec not registered for ${workflowId}`);
152
230
  }
231
+
153
232
  if (this.isCompleted(workflowId)) {
154
233
  this.logger.info(`[PD:EmpathyObserverWorkflow] finalizeOnce: already completed: ${workflowId}`);
155
234
  return;
156
235
  }
236
+
157
237
  this.logger.info(`[PD:EmpathyObserverWorkflow] Finalizing workflow: ${workflowId}`);
238
+
158
239
  this.store.updateWorkflowState(workflowId, 'finalizing');
240
+
159
241
  try {
160
242
  const result = await this.driver.getResult({ sessionKey: workflow.child_session_key, limit: 20 });
161
- const metadata = JSON.parse(workflow.metadata_json);
243
+
244
+ const metadata = JSON.parse(workflow.metadata_json) as WorkflowMetadata;
162
245
  const parsed = await spec.parseResult({
163
246
  messages: result.messages,
164
247
  assistantTexts: result.assistantTexts,
165
248
  metadata,
166
249
  waitStatus: 'ok',
167
250
  });
251
+
168
252
  if (!parsed) {
169
253
  this.store.updateWorkflowState(workflowId, 'terminal_error');
170
254
  this.store.recordEvent(workflowId, 'parse_failed', 'finalizing', 'terminal_error', 'spec.parseResult returned null', {});
171
255
  return;
172
256
  }
257
+
173
258
  await spec.persistResult({
174
259
  result: parsed,
175
260
  metadata,
176
261
  workspaceDir: this.workspaceDir,
177
262
  });
178
263
  this.store.recordEvent(workflowId, 'persisted', 'finalizing', 'finalizing', 'result persisted', {});
264
+
179
265
  if (spec.shouldDeleteSessionAfterFinalize && workflow.run_id) {
180
266
  try {
181
267
  await this.driver.cleanup({ sessionKey: workflow.child_session_key });
182
268
  this.store.updateCleanupState(workflowId, 'completed');
183
- }
184
- catch (cleanupError) {
269
+ } catch (cleanupError) {
185
270
  this.logger.error(`[PD:EmpathyObserverWorkflow] cleanup failed after persistence: ${String(cleanupError)}`);
186
271
  this.store.updateCleanupState(workflowId, 'failed');
187
272
  this.store.updateWorkflowState(workflowId, 'cleanup_pending');
@@ -190,51 +275,74 @@ export class EmpathyObserverWorkflowManager {
190
275
  return;
191
276
  }
192
277
  }
278
+
193
279
  this.store.updateWorkflowState(workflowId, 'completed');
194
280
  this.store.recordEvent(workflowId, 'finalized', 'finalizing', 'completed', 'success', {});
195
281
  this.markCompleted(workflowId);
196
- }
197
- catch (error) {
282
+
283
+ } catch (error) {
198
284
  this.logger.error(`[PD:EmpathyObserverWorkflow] finalizeOnce failed: ${String(error)}`);
199
285
  this.store.updateWorkflowState(workflowId, 'terminal_error');
200
286
  this.store.recordEvent(workflowId, 'finalize_error', 'finalizing', 'terminal_error', String(error), {});
201
287
  throw error;
202
288
  }
203
289
  }
204
- async sweepExpiredWorkflows(maxAgeMs = DEFAULT_TTL_MS) {
290
+
291
+ async sweepExpiredWorkflows(maxAgeMs = DEFAULT_TTL_MS): Promise<number> {
205
292
  const expired = this.store.getExpiredWorkflows(maxAgeMs);
293
+
206
294
  this.logger.info(`[PD:EmpathyObserverWorkflow] sweepExpiredWorkflows: found ${expired.length} expired`);
295
+
207
296
  for (const workflow of expired) {
208
297
  try {
209
298
  this.logger.info(`[PD:EmpathyObserverWorkflow] Sweeping expired workflow: ${workflow.workflow_id}`);
299
+
210
300
  await this.driver.cleanup({ sessionKey: workflow.child_session_key });
211
301
  this.store.updateCleanupState(workflow.workflow_id, 'completed');
212
302
  this.store.updateWorkflowState(workflow.workflow_id, 'expired');
213
303
  this.store.recordEvent(workflow.workflow_id, 'swept', workflow.state, 'expired', 'TTL expired', {});
214
- }
215
- catch (error) {
304
+
305
+ } catch (error) {
216
306
  this.logger.error(`[PD:EmpathyObserverWorkflow] Sweep cleanup failed for ${workflow.workflow_id}: ${String(error)}`);
217
307
  this.store.updateCleanupState(workflow.workflow_id, 'failed');
218
308
  }
219
309
  }
310
+
311
+ // Clean up memory Maps to prevent leaks
312
+ const cutoff = Date.now() - 60_000; // 1 minute dedup window
313
+ for (const [id, timestamp] of this.completedWorkflows) {
314
+ if (timestamp < cutoff) {
315
+ this.completedWorkflows.delete(id);
316
+ }
317
+ }
318
+ for (const [id, timeout] of this.activeWorkflows) {
319
+ const wf = this.store.getWorkflow(id);
320
+ if (!wf || wf.state === 'expired' || wf.state === 'completed' || wf.state === 'terminal_error') {
321
+ clearTimeout(timeout);
322
+ this.activeWorkflows.delete(id);
323
+ }
324
+ }
325
+
220
326
  return expired.length;
221
327
  }
222
- async getWorkflowDebugSummary(workflowId, eventLimit = 10) {
328
+
329
+ async getWorkflowDebugSummary(workflowId: string, eventLimit = 10): Promise<WorkflowDebugSummary | null> {
223
330
  const workflow = this.store.getWorkflow(workflowId);
224
- if (!workflow)
225
- return null;
226
- const metadata = JSON.parse(workflow.metadata_json);
331
+ if (!workflow) return null;
332
+
333
+ const metadata = JSON.parse(workflow.metadata_json) as WorkflowMetadata;
227
334
  const recentEvents = this.store
228
335
  .getEvents(workflowId)
229
336
  .slice(-eventLimit)
230
337
  .map((event) => ({
231
- eventType: event.event_type,
232
- fromState: event.from_state,
233
- toState: event.to_state,
234
- reason: event.reason,
235
- createdAt: event.created_at,
236
- payload: JSON.parse(event.payload_json || '{}'),
237
- }));
338
+ eventType: event.event_type,
339
+ fromState: event.from_state,
340
+ toState: event.to_state,
341
+ reason: event.reason,
342
+ createdAt: event.created_at,
343
+ payload: JSON.parse(event.payload_json || '{}') as Record<string, unknown>,
344
+ }));
345
+
238
346
  return {
239
347
  workflowId: workflow.workflow_id,
240
348
  workflowType: workflow.workflow_type,
@@ -249,78 +357,82 @@ export class EmpathyObserverWorkflowManager {
249
357
  recentEvents,
250
358
  };
251
359
  }
252
- generateWorkflowId() {
360
+
361
+ private generateWorkflowId(): string {
253
362
  return `wf_${Date.now()}_${Math.random().toString(36).substring(2, 10)}`;
254
363
  }
255
- buildChildSessionKey(parentSessionId) {
364
+
365
+ private buildChildSessionKey(parentSessionId: string): string {
256
366
  const safeParentSessionId = parentSessionId
257
367
  .replace(/[^a-zA-Z0-9_-]/g, '_')
258
368
  .substring(0, 64);
259
369
  const timestamp = Date.now();
260
370
  return `${WORKFLOW_SESSION_PREFIX}${safeParentSessionId}-${timestamp}`;
261
371
  }
262
- extractAssistantText(messages, assistantTexts) {
372
+
373
+ private extractAssistantText(messages: unknown[], assistantTexts?: string[]): string {
263
374
  if (assistantTexts && assistantTexts.length > 0) {
264
375
  return assistantTexts[assistantTexts.length - 1] || '';
265
376
  }
377
+
266
378
  for (let i = messages.length - 1; i >= 0; i--) {
267
- const msg = messages[i];
268
- if (msg?.role !== 'assistant')
269
- continue;
270
- if (typeof msg.content === 'string')
271
- return msg.content;
379
+ const msg = messages[i] as { role?: string; content?: unknown };
380
+ if (msg?.role !== 'assistant') continue;
381
+ if (typeof msg.content === 'string') return msg.content;
272
382
  if (Array.isArray(msg.content)) {
273
383
  const txt = msg.content
274
- .filter((part) => part?.type === 'text' && typeof part.text === 'string')
275
- .map((part) => part.text)
384
+ .filter((part: any) => part?.type === 'text' && typeof part.text === 'string')
385
+ .map((part: any) => part.text)
276
386
  .join('\n');
277
- if (txt)
278
- return txt;
387
+ if (txt) return txt;
279
388
  }
280
389
  }
390
+
281
391
  return '';
282
392
  }
283
- parseEmpathyPayload(rawText) {
284
- if (!rawText?.trim())
285
- return null;
393
+
394
+ parseEmpathyPayload(rawText: string): EmpathyObserverPayload | null {
395
+ if (!rawText?.trim()) return null;
396
+
286
397
  try {
287
- return JSON.parse(rawText.trim());
288
- }
289
- catch {
398
+ return JSON.parse(rawText.trim()) as EmpathyObserverPayload;
399
+ } catch {
290
400
  const match = rawText.match(/\{[\s\S]*\}/);
291
401
  if (!match) {
292
402
  this.logger.warn('[PD:EmpathyObserverWorkflow] Observer payload is not valid JSON');
293
403
  return null;
294
404
  }
295
405
  try {
296
- return JSON.parse(match[0]);
297
- }
298
- catch {
406
+ return JSON.parse(match[0]) as EmpathyObserverPayload;
407
+ } catch {
299
408
  this.logger.warn('[PD:EmpathyObserverWorkflow] Failed to parse observer JSON payload');
300
409
  return null;
301
410
  }
302
411
  }
303
412
  }
304
- isCompleted(workflowId) {
413
+
414
+ private isCompleted(workflowId: string): boolean {
305
415
  const timestamp = this.completedWorkflows.get(workflowId);
306
- if (!timestamp)
307
- return false;
416
+ if (!timestamp) return false;
308
417
  if (Date.now() - timestamp > 5 * 60 * 1000) {
309
418
  this.completedWorkflows.delete(workflowId);
310
419
  return false;
311
420
  }
312
421
  return true;
313
422
  }
314
- markCompleted(workflowId) {
423
+
424
+ private markCompleted(workflowId: string): void {
315
425
  this.completedWorkflows.set(workflowId, Date.now());
316
426
  this.workflowSpecs.delete(workflowId);
427
+
317
428
  const timeout = this.activeWorkflows.get(workflowId);
318
429
  if (timeout) {
319
430
  clearTimeout(timeout);
320
431
  this.activeWorkflows.delete(workflowId);
321
432
  }
322
433
  }
323
- dispose() {
434
+
435
+ dispose(): void {
324
436
  for (const timeout of this.activeWorkflows.values()) {
325
437
  clearTimeout(timeout);
326
438
  }
@@ -328,93 +440,91 @@ export class EmpathyObserverWorkflowManager {
328
440
  this.store.dispose();
329
441
  }
330
442
  }
331
- export function createEmpathyObserverWorkflowManager(opts) {
443
+
444
+ export function createEmpathyObserverWorkflowManager(
445
+ opts: EmpathyObserverWorkflowOptions
446
+ ): EmpathyObserverWorkflowManager {
332
447
  return new EmpathyObserverWorkflowManager(opts);
333
448
  }
449
+
334
450
  /**
335
451
  * Extract raw assistant text from messages or assistantTexts array.
336
452
  */
337
- function extractAssistantTextForSpec(messages, assistantTexts) {
453
+ function extractAssistantTextForSpec(messages: unknown[], assistantTexts?: string[]): string {
338
454
  if (assistantTexts && assistantTexts.length > 0) {
339
455
  return assistantTexts[assistantTexts.length - 1] || '';
340
456
  }
341
457
  for (let i = messages.length - 1; i >= 0; i--) {
342
- const msg = messages[i];
343
- if (msg?.role !== 'assistant')
344
- continue;
345
- if (typeof msg.content === 'string')
346
- return msg.content;
458
+ const msg = messages[i] as { role?: string; content?: unknown };
459
+ if (msg?.role !== 'assistant') continue;
460
+ if (typeof msg.content === 'string') return msg.content;
347
461
  if (Array.isArray(msg.content)) {
348
462
  const txt = msg.content
349
- .filter((part) => part?.type === 'text' && typeof part.text === 'string')
350
- .map((part) => part.text)
463
+ .filter((part: any) => part?.type === 'text' && typeof part.text === 'string')
464
+ .map((part: any) => part.text)
351
465
  .join('\n');
352
- if (txt)
353
- return txt;
466
+ if (txt) return txt;
354
467
  }
355
468
  }
356
469
  return '';
357
470
  }
471
+
358
472
  /**
359
473
  * Parse empathy observer JSON payload from raw text.
360
474
  */
361
- function parseEmpathyPayloadForSpec(rawText) {
362
- if (!rawText?.trim())
363
- return null;
475
+ function parseEmpathyPayloadForSpec(rawText: string): EmpathyObserverPayload | null {
476
+ if (!rawText?.trim()) return null;
364
477
  try {
365
- return JSON.parse(rawText.trim());
366
- }
367
- catch {
478
+ return JSON.parse(rawText.trim()) as EmpathyObserverPayload;
479
+ } catch {
368
480
  const match = rawText.match(/\{[\s\S]*\}/);
369
- if (!match)
370
- return null;
481
+ if (!match) return null;
371
482
  try {
372
- return JSON.parse(match[0]);
373
- }
374
- catch {
483
+ return JSON.parse(match[0]) as EmpathyObserverPayload;
484
+ } catch {
375
485
  return null;
376
486
  }
377
487
  }
378
488
  }
489
+
379
490
  /**
380
491
  * Normalize severity to valid enum.
381
492
  */
382
- function normalizeSeverityForSpec(severity) {
383
- if (severity === 'severe')
384
- return 'severe';
385
- if (severity === 'moderate')
386
- return 'moderate';
493
+ function normalizeSeverityForSpec(severity: string | undefined): 'mild' | 'moderate' | 'severe' {
494
+ if (severity === 'severe') return 'severe';
495
+ if (severity === 'moderate') return 'moderate';
387
496
  return 'mild';
388
497
  }
498
+
389
499
  /**
390
500
  * Normalize confidence to [0, 1] range.
391
501
  */
392
- function normalizeConfidenceForSpec(value) {
393
- if (!Number.isFinite(value))
394
- return 1;
502
+ function normalizeConfidenceForSpec(value: number | undefined): number {
503
+ if (!Number.isFinite(value)) return 1;
395
504
  return Math.max(0, Math.min(1, Number(value)));
396
505
  }
506
+
397
507
  /**
398
508
  * Calculate pain score from severity using config.
399
509
  */
400
- function scoreFromSeverityForSpec(severity, wctx) {
401
- if (severity === 'severe')
402
- return Number(wctx.config.get('empathy_engine.penalties.severe') ?? 40);
403
- if (severity === 'moderate')
404
- return Number(wctx.config.get('empathy_engine.penalties.moderate') ?? 25);
510
+ function scoreFromSeverityForSpec(severity: string | undefined, wctx: WorkspaceContext): number {
511
+ if (severity === 'severe') return Number(wctx.config.get('empathy_engine.penalties.severe') ?? 40);
512
+ if (severity === 'moderate') return Number(wctx.config.get('empathy_engine.penalties.moderate') ?? 25);
405
513
  return Number(wctx.config.get('empathy_engine.penalties.mild') ?? 10);
406
514
  }
515
+
407
516
  /**
408
517
  * EmpathyObserver workflow specification.
409
518
  * This spec drives EmpathyObserverWorkflowManager for the empathy observer workflow.
410
519
  */
411
- export const empathyObserverWorkflowSpec = {
520
+ export const empathyObserverWorkflowSpec: SubagentWorkflowSpec<EmpathyResult> = {
412
521
  workflowType: 'empathy-observer',
413
522
  transport: 'runtime_direct',
414
523
  timeoutMs: 30_000,
415
524
  ttlMs: 300_000,
416
525
  shouldDeleteSessionAfterFinalize: true,
417
- buildPrompt(taskInput, _metadata) {
526
+
527
+ buildPrompt(taskInput: unknown, _metadata: WorkflowMetadata): string {
418
528
  const userMessage = String(taskInput).trim();
419
529
  return [
420
530
  'You are an empathy observer.',
@@ -423,11 +533,12 @@ export const empathyObserverWorkflowSpec = {
423
533
  `User message: ${JSON.stringify(userMessage)}`,
424
534
  ].join('\n');
425
535
  },
426
- async parseResult(ctx) {
536
+
537
+ async parseResult(ctx: WorkflowResultContext): Promise<EmpathyResult | null> {
427
538
  const rawText = extractAssistantTextForSpec(ctx.messages, ctx.assistantTexts);
428
539
  const payload = parseEmpathyPayloadForSpec(rawText);
429
- if (!payload)
430
- return null;
540
+ if (!payload) return null;
541
+
431
542
  return {
432
543
  damageDetected: payload.damageDetected ?? false,
433
544
  severity: normalizeSeverityForSpec(payload.severity),
@@ -436,13 +547,22 @@ export const empathyObserverWorkflowSpec = {
436
547
  painScore: 0,
437
548
  };
438
549
  },
439
- async persistResult(ctx) {
550
+
551
+ async persistResult(ctx: WorkflowPersistContext<EmpathyResult>): Promise<void> {
440
552
  const { result, metadata, workspaceDir } = ctx;
441
- if (!result.damageDetected)
442
- return;
553
+ if (!result.damageDetected) return;
554
+
443
555
  const wctx = WorkspaceContext.fromHookContext({ workspaceDir });
444
556
  const painScore = scoreFromSeverityForSpec(result.severity, wctx);
445
- trackFriction(metadata.parentSessionId, painScore, `observer_empathy_${result.severity}`, workspaceDir, { source: 'user_empathy' });
557
+
558
+ trackFriction(
559
+ metadata.parentSessionId,
560
+ painScore,
561
+ `observer_empathy_${result.severity}`,
562
+ workspaceDir,
563
+ { source: 'user_empathy' }
564
+ );
565
+
446
566
  const eventId = `emp_obs_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
447
567
  wctx.eventLog.recordPainSignal(metadata.parentSessionId, {
448
568
  score: painScore,
@@ -454,11 +574,12 @@ export const empathyObserverWorkflowSpec = {
454
574
  confidence: result.confidence,
455
575
  detection_mode: 'structured',
456
576
  deduped: false,
457
- trigger_text_excerpt: '',
577
+ trigger_text_excerpt: String(metadata.taskInput ?? '').substring(0, 120),
458
578
  raw_score: painScore,
459
579
  calibrated_score: painScore,
460
580
  eventId,
461
581
  });
582
+
462
583
  try {
463
584
  wctx.trajectory?.recordPainEvent?.({
464
585
  sessionId: metadata.parentSessionId,
@@ -468,13 +589,15 @@ export const empathyObserverWorkflowSpec = {
468
589
  severity: result.severity,
469
590
  origin: 'system_infer',
470
591
  confidence: result.confidence,
592
+ // Use runtime check instead of type assertion
593
+ text: typeof metadata.taskInput === 'string' ? metadata.taskInput : undefined,
471
594
  });
472
- }
473
- catch (error) {
595
+ } catch (error) {
474
596
  console.warn(`[PD:EmpathyObserverWorkflow] Failed to persist trajectory: ${String(error)}`);
475
597
  }
476
598
  },
477
- shouldFinalizeOnWaitStatus(status) {
599
+
600
+ shouldFinalizeOnWaitStatus(status: 'ok' | 'error' | 'timeout'): boolean {
478
601
  return status === 'ok';
479
602
  },
480
603
  };