principles-disciple 1.8.1 → 1.8.2

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