principles-disciple 1.8.0 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (460) hide show
  1. package/ADVANCED_CONFIG_ZH.md +97 -0
  2. package/AGENT_INSTALL.md +173 -0
  3. package/AGENT_INSTALL_EN.md +173 -0
  4. package/INSTALL.md +256 -0
  5. package/SKILL.md +63 -0
  6. package/docs/COMMAND_REFERENCE.md +76 -0
  7. package/docs/COMMAND_REFERENCE_EN.md +79 -0
  8. package/esbuild.config.js +75 -0
  9. package/openclaw.plugin.json +6 -1
  10. package/package.json +13 -15
  11. package/scripts/build-web.mjs +46 -0
  12. package/scripts/install-dependencies.cjs +47 -0
  13. package/scripts/sync-plugin.mjs +802 -0
  14. package/scripts/verify-build.mjs +109 -0
  15. package/src/agents/nocturnal-dreamer.md +152 -0
  16. package/src/agents/nocturnal-philosopher.md +138 -0
  17. package/src/agents/nocturnal-reflector.md +126 -0
  18. package/src/agents/nocturnal-scribe.md +164 -0
  19. package/src/commands/capabilities.ts +85 -0
  20. package/{dist/commands/context.js → src/commands/context.ts} +78 -38
  21. package/src/commands/evolution-status.ts +146 -0
  22. package/src/commands/export.ts +111 -0
  23. package/src/commands/focus.ts +533 -0
  24. package/src/commands/nocturnal-review.ts +311 -0
  25. package/src/commands/nocturnal-rollout.ts +763 -0
  26. package/src/commands/nocturnal-train.ts +1002 -0
  27. package/{dist/commands/pain.js → src/commands/pain.ts} +68 -49
  28. package/src/commands/principle-rollback.ts +27 -0
  29. package/{dist/commands/rollback.js → src/commands/rollback.ts} +44 -12
  30. package/src/commands/samples.ts +60 -0
  31. package/src/commands/strategy.ts +38 -0
  32. package/{dist/commands/thinking-os.js → src/commands/thinking-os.ts} +59 -36
  33. package/src/commands/workflow-debug.ts +128 -0
  34. package/{dist/config/defaults/runtime.js → src/config/defaults/runtime.ts} +12 -5
  35. package/src/config/errors.ts +163 -0
  36. package/{dist/config/index.d.ts → src/config/index.ts} +2 -1
  37. package/src/constants/diagnostician.ts +66 -0
  38. package/src/constants/tools.ts +62 -0
  39. package/src/core/adaptive-thresholds.ts +476 -0
  40. package/{dist/core/config-service.js → src/core/config-service.ts} +7 -4
  41. package/{dist/core/config.js → src/core/config.ts} +158 -46
  42. package/src/core/control-ui-db.ts +435 -0
  43. package/{dist/core/detection-funnel.js → src/core/detection-funnel.ts} +36 -21
  44. package/{dist/core/detection-service.js → src/core/detection-service.ts} +7 -4
  45. package/{dist/core/dictionary-service.js → src/core/dictionary-service.ts} +7 -4
  46. package/{dist/core/dictionary.js → src/core/dictionary.ts} +57 -34
  47. package/src/core/empathy-keyword-matcher.ts +327 -0
  48. package/src/core/empathy-types.ts +218 -0
  49. package/src/core/event-log.ts +544 -0
  50. package/src/core/evolution-engine.ts +612 -0
  51. package/src/core/evolution-logger.ts +353 -0
  52. package/src/core/evolution-migration.ts +77 -0
  53. package/src/core/evolution-reducer.ts +731 -0
  54. package/src/core/evolution-types.ts +456 -0
  55. package/src/core/external-training-contract.ts +527 -0
  56. package/src/core/focus-history.ts +1458 -0
  57. package/src/core/hygiene/tracker.ts +117 -0
  58. package/{dist/core/init.js → src/core/init.ts} +39 -26
  59. package/src/core/local-worker-routing.ts +617 -0
  60. package/{dist/core/migration.js → src/core/migration.ts} +18 -11
  61. package/src/core/model-deployment-registry.ts +722 -0
  62. package/src/core/model-training-registry.ts +813 -0
  63. package/src/core/nocturnal-arbiter.ts +706 -0
  64. package/src/core/nocturnal-candidate-scoring.ts +392 -0
  65. package/src/core/nocturnal-compliance.ts +1075 -0
  66. package/src/core/nocturnal-dataset.ts +668 -0
  67. package/src/core/nocturnal-executability.ts +428 -0
  68. package/src/core/nocturnal-export.ts +390 -0
  69. package/{dist/core/nocturnal-paths.js → src/core/nocturnal-paths.ts} +49 -23
  70. package/src/core/nocturnal-trajectory-extractor.ts +484 -0
  71. package/src/core/nocturnal-trinity.ts +1384 -0
  72. package/src/core/pain.ts +122 -0
  73. package/{dist/core/path-resolver.js → src/core/path-resolver.ts} +157 -36
  74. package/{dist/core/paths.js → src/core/paths.ts} +13 -4
  75. package/src/core/principle-training-state.ts +450 -0
  76. package/src/core/profile.ts +226 -0
  77. package/src/core/promotion-gate.ts +822 -0
  78. package/{dist/core/risk-calculator.js → src/core/risk-calculator.ts} +42 -16
  79. package/{dist/core/session-tracker.js → src/core/session-tracker.ts} +185 -63
  80. package/src/core/shadow-observation-registry.ts +534 -0
  81. package/{dist/core/system-logger.js → src/core/system-logger.ts} +9 -5
  82. package/src/core/thinking-models.ts +217 -0
  83. package/src/core/training-program.ts +630 -0
  84. package/src/core/trajectory-types.ts +243 -0
  85. package/src/core/trajectory.ts +1673 -0
  86. package/{dist/core/workspace-context.js → src/core/workspace-context.ts} +57 -32
  87. package/src/hooks/bash-risk.ts +171 -0
  88. package/src/hooks/edit-verification.ts +295 -0
  89. package/src/hooks/gate-block-helper.ts +160 -0
  90. package/src/hooks/gate.ts +210 -0
  91. package/src/hooks/gfi-gate.ts +177 -0
  92. package/src/hooks/lifecycle.ts +326 -0
  93. package/{dist/hooks/llm.js → src/hooks/llm.ts} +166 -139
  94. package/src/hooks/message-sanitize.ts +45 -0
  95. package/src/hooks/pain.ts +384 -0
  96. package/src/hooks/progressive-trust-gate.ts +174 -0
  97. package/src/hooks/prompt.ts +920 -0
  98. package/src/hooks/subagent.ts +207 -0
  99. package/src/hooks/thinking-checkpoint.ts +73 -0
  100. package/src/hooks/trajectory-collector.ts +290 -0
  101. package/src/http/principles-console-route.ts +716 -0
  102. package/src/i18n/commands.ts +117 -0
  103. package/src/index.ts +694 -0
  104. package/src/service/central-database.ts +831 -0
  105. package/src/service/control-ui-query-service.ts +888 -0
  106. package/src/service/evolution-query-service.ts +405 -0
  107. package/src/service/evolution-worker.ts +1646 -0
  108. package/src/service/health-query-service.ts +836 -0
  109. package/{dist/service/nocturnal-runtime.js → src/service/nocturnal-runtime.ts} +263 -36
  110. package/src/service/nocturnal-service.ts +1015 -0
  111. package/src/service/nocturnal-target-selector.ts +532 -0
  112. package/src/service/phase3-input-filter.ts +237 -0
  113. package/src/service/runtime-summary-service.ts +757 -0
  114. package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +513 -0
  115. package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +603 -0
  116. package/src/service/subagent-workflow/index.ts +51 -0
  117. package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +856 -0
  118. package/src/service/subagent-workflow/runtime-direct-driver.ts +166 -0
  119. package/src/service/subagent-workflow/types.ts +378 -0
  120. package/src/service/subagent-workflow/workflow-store.ts +328 -0
  121. package/src/service/trajectory-service.ts +15 -0
  122. package/{dist/tools/critique-prompt.js → src/tools/critique-prompt.ts} +25 -8
  123. package/src/tools/deep-reflect.ts +349 -0
  124. package/{dist/tools/model-index.js → src/tools/model-index.ts} +33 -17
  125. package/src/types/event-types.ts +453 -0
  126. package/src/types/hygiene-types.ts +31 -0
  127. package/src/types/principle-tree-schema.ts +244 -0
  128. package/src/types/runtime-summary.ts +49 -0
  129. package/src/types.ts +74 -0
  130. package/src/utils/file-lock.ts +391 -0
  131. package/{dist/utils/glob-match.js → src/utils/glob-match.ts} +21 -20
  132. package/{dist/utils/hashing.js → src/utils/hashing.ts} +6 -4
  133. package/src/utils/io.ts +110 -0
  134. package/{dist/utils/nlp.js → src/utils/nlp.ts} +19 -12
  135. package/{dist/utils/plugin-logger.js → src/utils/plugin-logger.ts} +33 -8
  136. package/src/utils/subagent-probe.ts +94 -0
  137. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +70 -1
  138. package/templates/pain_settings.json +2 -1
  139. package/tests/README.md +120 -0
  140. package/tests/build-artifacts.test.ts +111 -0
  141. package/tests/commands/evolution-status.test.ts +222 -0
  142. package/tests/commands/evolver.test.ts +22 -0
  143. package/tests/commands/export.test.ts +78 -0
  144. package/tests/commands/nocturnal-review.test.ts +448 -0
  145. package/tests/commands/nocturnal-train.test.ts +97 -0
  146. package/tests/commands/pain.test.ts +108 -0
  147. package/tests/commands/samples.test.ts +65 -0
  148. package/tests/commands/strategy.test.ts +34 -0
  149. package/tests/commands/thinking-os.test.ts +88 -0
  150. package/tests/core/adaptive-thresholds.test.ts +261 -0
  151. package/tests/core/config-service.test.ts +89 -0
  152. package/tests/core/config.test.ts +90 -0
  153. package/tests/core/control-ui-db.test.ts +75 -0
  154. package/tests/core/core-template-guidance.test.ts +21 -0
  155. package/tests/core/detection-funnel.test.ts +63 -0
  156. package/tests/core/detection-service.test.ts +50 -0
  157. package/tests/core/dictionary-service.test.ts +116 -0
  158. package/tests/core/dictionary.test.ts +168 -0
  159. package/tests/core/empathy-keyword-matcher.test.ts +209 -0
  160. package/tests/core/event-log.test.ts +181 -0
  161. package/tests/core/evolution-e2e.test.ts +58 -0
  162. package/tests/core/evolution-engine-gate-integration.test.ts +543 -0
  163. package/tests/core/evolution-engine.test.ts +562 -0
  164. package/tests/core/evolution-logger.test.ts +148 -0
  165. package/tests/core/evolution-migration.test.ts +50 -0
  166. package/tests/core/evolution-paths.test.ts +21 -0
  167. package/tests/core/evolution-reducer.detector-metadata.test.ts +602 -0
  168. package/tests/core/evolution-reducer.test.ts +180 -0
  169. package/tests/core/evolution-types-loop.test.ts +48 -0
  170. package/tests/core/evolution-user-stories.e2e.test.ts +249 -0
  171. package/tests/core/external-training-contract.test.ts +463 -0
  172. package/tests/core/focus-history.test.ts +682 -0
  173. package/tests/core/init-flatten.test.ts +69 -0
  174. package/tests/core/init-refactor.test.ts +87 -0
  175. package/tests/core/init-v1.3.test.ts +46 -0
  176. package/tests/core/init.test.ts +190 -0
  177. package/tests/core/local-worker-routing.test.ts +757 -0
  178. package/tests/core/migration.test.ts +84 -0
  179. package/tests/core/model-deployment-registry.test.ts +845 -0
  180. package/tests/core/model-training-registry.test.ts +889 -0
  181. package/tests/core/nocturnal-arbiter.test.ts +494 -0
  182. package/tests/core/nocturnal-candidate-scoring.test.ts +400 -0
  183. package/tests/core/nocturnal-compliance.test.ts +646 -0
  184. package/tests/core/nocturnal-dataset.test.ts +892 -0
  185. package/tests/core/nocturnal-executability.test.ts +357 -0
  186. package/tests/core/nocturnal-export.test.ts +462 -0
  187. package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +428 -0
  188. package/tests/core/nocturnal-trajectory-extractor.test.ts +634 -0
  189. package/tests/core/nocturnal-trinity.test.ts +953 -0
  190. package/tests/core/pain.test.ts +33 -0
  191. package/tests/core/path-resolver.test.ts +57 -0
  192. package/tests/core/paths-refactor.test.ts +42 -0
  193. package/tests/core/phase7-rollout-integration.test.ts +477 -0
  194. package/tests/core/principle-training-state.test.ts +712 -0
  195. package/tests/core/profile.test.ts +56 -0
  196. package/tests/core/promotion-gate.test.ts +556 -0
  197. package/tests/core/risk-calculator.test.ts +168 -0
  198. package/tests/core/session-tracker.test.ts +191 -0
  199. package/tests/core/training-program.test.ts +472 -0
  200. package/tests/core/trajectory.test.ts +265 -0
  201. package/tests/core/workspace-context-factory.test.ts +18 -0
  202. package/tests/core/workspace-context.test.ts +134 -0
  203. package/tests/fixtures/nocturnal-reviewed-subset.json +183 -0
  204. package/tests/fixtures/production-compatibility.test.ts +147 -0
  205. package/tests/fixtures/production-mock-generator.ts +282 -0
  206. package/tests/hooks/bash-risk-integration.test.ts +137 -0
  207. package/tests/hooks/bash-risk.test.ts +81 -0
  208. package/tests/hooks/edit-verification.test.ts +678 -0
  209. package/tests/hooks/gate-edit-verification-p1.test.ts +632 -0
  210. package/tests/hooks/gate-edit-verification.test.ts +435 -0
  211. package/tests/hooks/gate-pipeline-integration.test.ts +404 -0
  212. package/tests/hooks/gate.test.ts +271 -0
  213. package/tests/hooks/gfi-gate-unit.test.ts +422 -0
  214. package/tests/hooks/gfi-gate.test.ts +669 -0
  215. package/tests/hooks/lifecycle.test.ts +248 -0
  216. package/tests/hooks/llm.test.ts +308 -0
  217. package/tests/hooks/message-sanitize.test.ts +36 -0
  218. package/tests/hooks/pain.test.ts +141 -0
  219. package/tests/hooks/progressive-trust-gate.test.ts +277 -0
  220. package/tests/hooks/prompt.test.ts +1411 -0
  221. package/tests/hooks/subagent.test.ts +467 -0
  222. package/tests/hooks/thinking-gate.test.ts +313 -0
  223. package/tests/http/principles-console-route.test.ts +140 -0
  224. package/tests/hygiene-tracker.test.ts +77 -0
  225. package/tests/index.integration.test.ts +179 -0
  226. package/tests/index.shadow-routing.integration.test.ts +140 -0
  227. package/tests/index.test.ts +9 -0
  228. package/tests/integration/empathy-workflow-integration.test.ts +627 -0
  229. package/tests/service/control-ui-query-service.test.ts +121 -0
  230. package/tests/service/empathy-observer-workflow-manager.test.ts +176 -0
  231. package/tests/service/evolution-worker.test.ts +585 -0
  232. package/tests/service/nocturnal-runtime.test.ts +470 -0
  233. package/tests/service/nocturnal-service.test.ts +577 -0
  234. package/tests/service/nocturnal-target-selector.test.ts +615 -0
  235. package/tests/service/nocturnal-workflow-manager.test.ts +439 -0
  236. package/tests/service/phase3-input-filter.test.ts +289 -0
  237. package/tests/service/runtime-summary-service.test.ts +919 -0
  238. package/tests/task-compliance.test.ts +166 -0
  239. package/tests/test-utils.ts +48 -0
  240. package/tests/tools/critique-prompt.test.ts +260 -0
  241. package/tests/tools/deep-reflect.test.ts +232 -0
  242. package/tests/tools/model-index.test.ts +246 -0
  243. package/tests/ui/app.test.tsx +114 -0
  244. package/tests/utils/file-lock.test.ts +407 -0
  245. package/tests/utils/hashing.test.ts +32 -0
  246. package/tests/utils/io.test.ts +39 -0
  247. package/tests/utils/nlp.test.ts +53 -0
  248. package/tests/utils/plugin-logger.test.ts +156 -0
  249. package/tsconfig.json +16 -0
  250. package/tsconfig.tsbuildinfo +1 -0
  251. package/ui/src/App.tsx +45 -0
  252. package/ui/src/api.ts +216 -0
  253. package/ui/src/charts.tsx +586 -0
  254. package/ui/src/components/ErrorState.tsx +6 -0
  255. package/ui/src/components/Loading.tsx +13 -0
  256. package/ui/src/components/ProtectedRoute.tsx +12 -0
  257. package/ui/src/components/Shell.tsx +91 -0
  258. package/ui/src/components/WorkspaceConfig.tsx +146 -0
  259. package/ui/src/components/index.ts +5 -0
  260. package/ui/src/context/auth.tsx +80 -0
  261. package/ui/src/context/theme.tsx +66 -0
  262. package/ui/src/hooks/useAutoRefresh.ts +39 -0
  263. package/ui/src/i18n/ui.ts +363 -0
  264. package/ui/src/main.tsx +16 -0
  265. package/ui/src/pages/EvolutionPage.tsx +352 -0
  266. package/ui/src/pages/FeedbackPage.tsx +140 -0
  267. package/ui/src/pages/GateMonitorPage.tsx +136 -0
  268. package/ui/src/pages/LoginPage.tsx +88 -0
  269. package/ui/src/pages/OverviewPage.tsx +238 -0
  270. package/ui/src/pages/SamplesPage.tsx +174 -0
  271. package/ui/src/pages/ThinkingModelsPage.tsx +127 -0
  272. package/ui/src/styles.css +1661 -0
  273. package/ui/src/types.ts +368 -0
  274. package/ui/src/utils/format.ts +15 -0
  275. package/vitest.config.ts +23 -0
  276. package/dist/commands/capabilities.d.ts +0 -3
  277. package/dist/commands/capabilities.js +0 -73
  278. package/dist/commands/context.d.ts +0 -5
  279. package/dist/commands/evolution-status.d.ts +0 -4
  280. package/dist/commands/evolution-status.js +0 -117
  281. package/dist/commands/evolver.d.ts +0 -9
  282. package/dist/commands/evolver.js +0 -26
  283. package/dist/commands/export.d.ts +0 -2
  284. package/dist/commands/export.js +0 -98
  285. package/dist/commands/focus.d.ts +0 -14
  286. package/dist/commands/focus.js +0 -457
  287. package/dist/commands/nocturnal-review.d.ts +0 -24
  288. package/dist/commands/nocturnal-review.js +0 -265
  289. package/dist/commands/nocturnal-rollout.d.ts +0 -27
  290. package/dist/commands/nocturnal-rollout.js +0 -671
  291. package/dist/commands/nocturnal-train.d.ts +0 -25
  292. package/dist/commands/nocturnal-train.js +0 -919
  293. package/dist/commands/pain.d.ts +0 -5
  294. package/dist/commands/principle-rollback.d.ts +0 -4
  295. package/dist/commands/principle-rollback.js +0 -22
  296. package/dist/commands/rollback.d.ts +0 -19
  297. package/dist/commands/samples.d.ts +0 -2
  298. package/dist/commands/samples.js +0 -55
  299. package/dist/commands/strategy.d.ts +0 -3
  300. package/dist/commands/strategy.js +0 -29
  301. package/dist/commands/thinking-os.d.ts +0 -2
  302. package/dist/config/defaults/runtime.d.ts +0 -40
  303. package/dist/config/errors.d.ts +0 -84
  304. package/dist/config/errors.js +0 -94
  305. package/dist/config/index.js +0 -7
  306. package/dist/constants/diagnostician.d.ts +0 -12
  307. package/dist/constants/diagnostician.js +0 -56
  308. package/dist/constants/tools.d.ts +0 -17
  309. package/dist/constants/tools.js +0 -54
  310. package/dist/core/adaptive-thresholds.d.ts +0 -186
  311. package/dist/core/adaptive-thresholds.js +0 -300
  312. package/dist/core/config-service.d.ts +0 -15
  313. package/dist/core/config.d.ts +0 -127
  314. package/dist/core/control-ui-db.d.ts +0 -95
  315. package/dist/core/control-ui-db.js +0 -292
  316. package/dist/core/detection-funnel.d.ts +0 -33
  317. package/dist/core/detection-service.d.ts +0 -15
  318. package/dist/core/dictionary-service.d.ts +0 -15
  319. package/dist/core/dictionary.d.ts +0 -38
  320. package/dist/core/event-log.d.ts +0 -82
  321. package/dist/core/event-log.js +0 -463
  322. package/dist/core/evolution-engine.d.ts +0 -118
  323. package/dist/core/evolution-engine.js +0 -464
  324. package/dist/core/evolution-logger.d.ts +0 -137
  325. package/dist/core/evolution-logger.js +0 -256
  326. package/dist/core/evolution-migration.d.ts +0 -5
  327. package/dist/core/evolution-migration.js +0 -65
  328. package/dist/core/evolution-reducer.d.ts +0 -98
  329. package/dist/core/evolution-reducer.js +0 -465
  330. package/dist/core/evolution-types.d.ts +0 -287
  331. package/dist/core/evolution-types.js +0 -78
  332. package/dist/core/external-training-contract.d.ts +0 -276
  333. package/dist/core/external-training-contract.js +0 -269
  334. package/dist/core/focus-history.d.ts +0 -210
  335. package/dist/core/focus-history.js +0 -1185
  336. package/dist/core/hygiene/tracker.d.ts +0 -22
  337. package/dist/core/hygiene/tracker.js +0 -106
  338. package/dist/core/init.d.ts +0 -12
  339. package/dist/core/local-worker-routing.d.ts +0 -175
  340. package/dist/core/local-worker-routing.js +0 -525
  341. package/dist/core/migration.d.ts +0 -6
  342. package/dist/core/model-deployment-registry.d.ts +0 -218
  343. package/dist/core/model-deployment-registry.js +0 -503
  344. package/dist/core/model-training-registry.d.ts +0 -295
  345. package/dist/core/model-training-registry.js +0 -475
  346. package/dist/core/nocturnal-arbiter.d.ts +0 -159
  347. package/dist/core/nocturnal-arbiter.js +0 -534
  348. package/dist/core/nocturnal-candidate-scoring.d.ts +0 -137
  349. package/dist/core/nocturnal-candidate-scoring.js +0 -266
  350. package/dist/core/nocturnal-compliance.d.ts +0 -175
  351. package/dist/core/nocturnal-compliance.js +0 -824
  352. package/dist/core/nocturnal-dataset.d.ts +0 -224
  353. package/dist/core/nocturnal-dataset.js +0 -443
  354. package/dist/core/nocturnal-executability.d.ts +0 -85
  355. package/dist/core/nocturnal-executability.js +0 -331
  356. package/dist/core/nocturnal-export.d.ts +0 -124
  357. package/dist/core/nocturnal-export.js +0 -275
  358. package/dist/core/nocturnal-paths.d.ts +0 -124
  359. package/dist/core/nocturnal-trajectory-extractor.d.ts +0 -242
  360. package/dist/core/nocturnal-trajectory-extractor.js +0 -307
  361. package/dist/core/nocturnal-trinity.d.ts +0 -311
  362. package/dist/core/nocturnal-trinity.js +0 -880
  363. package/dist/core/pain.d.ts +0 -4
  364. package/dist/core/pain.js +0 -70
  365. package/dist/core/path-resolver.d.ts +0 -46
  366. package/dist/core/paths.d.ts +0 -65
  367. package/dist/core/principle-training-state.d.ts +0 -121
  368. package/dist/core/principle-training-state.js +0 -321
  369. package/dist/core/profile.d.ts +0 -62
  370. package/dist/core/profile.js +0 -210
  371. package/dist/core/promotion-gate.d.ts +0 -238
  372. package/dist/core/promotion-gate.js +0 -529
  373. package/dist/core/risk-calculator.d.ts +0 -22
  374. package/dist/core/session-tracker.d.ts +0 -99
  375. package/dist/core/shadow-observation-registry.d.ts +0 -217
  376. package/dist/core/shadow-observation-registry.js +0 -308
  377. package/dist/core/system-logger.d.ts +0 -8
  378. package/dist/core/thinking-models.d.ts +0 -38
  379. package/dist/core/thinking-models.js +0 -170
  380. package/dist/core/training-program.d.ts +0 -233
  381. package/dist/core/training-program.js +0 -433
  382. package/dist/core/trajectory.d.ts +0 -411
  383. package/dist/core/trajectory.js +0 -1307
  384. package/dist/core/workspace-context.d.ts +0 -71
  385. package/dist/hooks/bash-risk.d.ts +0 -57
  386. package/dist/hooks/bash-risk.js +0 -137
  387. package/dist/hooks/edit-verification.d.ts +0 -62
  388. package/dist/hooks/edit-verification.js +0 -256
  389. package/dist/hooks/gate-block-helper.d.ts +0 -44
  390. package/dist/hooks/gate-block-helper.js +0 -119
  391. package/dist/hooks/gate.d.ts +0 -24
  392. package/dist/hooks/gate.js +0 -173
  393. package/dist/hooks/gfi-gate.d.ts +0 -40
  394. package/dist/hooks/gfi-gate.js +0 -113
  395. package/dist/hooks/lifecycle.d.ts +0 -5
  396. package/dist/hooks/lifecycle.js +0 -284
  397. package/dist/hooks/llm.d.ts +0 -12
  398. package/dist/hooks/message-sanitize.d.ts +0 -3
  399. package/dist/hooks/message-sanitize.js +0 -37
  400. package/dist/hooks/pain.d.ts +0 -5
  401. package/dist/hooks/pain.js +0 -301
  402. package/dist/hooks/progressive-trust-gate.d.ts +0 -51
  403. package/dist/hooks/progressive-trust-gate.js +0 -89
  404. package/dist/hooks/prompt.d.ts +0 -47
  405. package/dist/hooks/prompt.js +0 -884
  406. package/dist/hooks/subagent.d.ts +0 -10
  407. package/dist/hooks/subagent.js +0 -387
  408. package/dist/hooks/thinking-checkpoint.d.ts +0 -37
  409. package/dist/hooks/thinking-checkpoint.js +0 -51
  410. package/dist/hooks/trajectory-collector.d.ts +0 -32
  411. package/dist/hooks/trajectory-collector.js +0 -256
  412. package/dist/http/principles-console-route.d.ts +0 -9
  413. package/dist/http/principles-console-route.js +0 -567
  414. package/dist/i18n/commands.d.ts +0 -26
  415. package/dist/i18n/commands.js +0 -116
  416. package/dist/index.d.ts +0 -7
  417. package/dist/index.js +0 -581
  418. package/dist/service/central-database.d.ts +0 -104
  419. package/dist/service/central-database.js +0 -649
  420. package/dist/service/control-ui-query-service.d.ts +0 -221
  421. package/dist/service/control-ui-query-service.js +0 -543
  422. package/dist/service/empathy-observer-manager.d.ts +0 -52
  423. package/dist/service/empathy-observer-manager.js +0 -229
  424. package/dist/service/evolution-query-service.d.ts +0 -155
  425. package/dist/service/evolution-query-service.js +0 -258
  426. package/dist/service/evolution-worker.d.ts +0 -101
  427. package/dist/service/evolution-worker.js +0 -974
  428. package/dist/service/nocturnal-runtime.d.ts +0 -183
  429. package/dist/service/nocturnal-service.d.ts +0 -163
  430. package/dist/service/nocturnal-service.js +0 -787
  431. package/dist/service/nocturnal-target-selector.d.ts +0 -145
  432. package/dist/service/nocturnal-target-selector.js +0 -315
  433. package/dist/service/phase3-input-filter.d.ts +0 -73
  434. package/dist/service/phase3-input-filter.js +0 -172
  435. package/dist/service/runtime-summary-service.d.ts +0 -122
  436. package/dist/service/runtime-summary-service.js +0 -485
  437. package/dist/service/trajectory-service.d.ts +0 -2
  438. package/dist/service/trajectory-service.js +0 -15
  439. package/dist/tools/critique-prompt.d.ts +0 -14
  440. package/dist/tools/deep-reflect.d.ts +0 -39
  441. package/dist/tools/deep-reflect.js +0 -350
  442. package/dist/tools/model-index.d.ts +0 -9
  443. package/dist/types/event-types.d.ts +0 -306
  444. package/dist/types/event-types.js +0 -106
  445. package/dist/types/hygiene-types.d.ts +0 -20
  446. package/dist/types/hygiene-types.js +0 -12
  447. package/dist/types/runtime-summary.d.ts +0 -47
  448. package/dist/types/runtime-summary.js +0 -1
  449. package/dist/types.d.ts +0 -50
  450. package/dist/types.js +0 -22
  451. package/dist/utils/file-lock.d.ts +0 -71
  452. package/dist/utils/file-lock.js +0 -309
  453. package/dist/utils/glob-match.d.ts +0 -28
  454. package/dist/utils/hashing.d.ts +0 -9
  455. package/dist/utils/io.d.ts +0 -6
  456. package/dist/utils/io.js +0 -106
  457. package/dist/utils/nlp.d.ts +0 -9
  458. package/dist/utils/plugin-logger.d.ts +0 -39
  459. package/dist/utils/subagent-probe.d.ts +0 -34
  460. package/dist/utils/subagent-probe.js +0 -81
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Gate Block Helper - Single Authoritative Block Persistence
3
+ *
4
+ * PURPOSE: Provide ONE authoritative implementation for gate block persistence.
5
+ *
6
+ * All gate modules (progressive-trust-gate, gfi-gate, etc.) must use this
7
+ * helper to ensure consistent block tracking, event logging, and retry behavior.
8
+ *
9
+ * This eliminates the "multi-truth source" problem where different modules
10
+ * had their own block persistence implementations.
11
+ */
12
+
13
+ import { trackBlock } from '../core/session-tracker.js';
14
+ import type { WorkspaceContext } from '../core/workspace-context.js';
15
+ import type { PluginHookBeforeToolCallResult } from '../openclaw-sdk.js';
16
+ import {
17
+ TRAJECTORY_GATE_BLOCK_RETRY_DELAY_MS,
18
+ TRAJECTORY_GATE_BLOCK_MAX_RETRIES
19
+ } from '../config/index.js';
20
+
21
+ /**
22
+ * Block context containing all information needed for block persistence
23
+ */
24
+ export interface BlockContext {
25
+ filePath: string;
26
+ reason: string;
27
+ toolName: string;
28
+ sessionId?: string;
29
+ /** Source module that triggered the block (for audit trail) */
30
+ blockSource?: string;
31
+ }
32
+
33
+ /**
34
+ * Single authoritative block helper.
35
+ *
36
+ * Responsibilities:
37
+ * 1. Call trackBlock() for session-level GFI tracking
38
+ * 2. Record to EventLog for operator visibility
39
+ * 3. Record to trajectory for analytics
40
+ * 4. Handle retry logic for trajectory persistence failures
41
+ * 5. Generate consistent operator-facing block message
42
+ *
43
+ * @param wctx - Workspace context
44
+ * @param blockCtx - Block context with file, reason, tool info
45
+ * @param logger - Logger instance
46
+ * @returns PluginHookBeforeToolCallResult with block=true
47
+ */
48
+ export function recordGateBlockAndReturn(
49
+ wctx: WorkspaceContext,
50
+ blockCtx: BlockContext,
51
+ logger: { warn?: (message: string) => void; error?: (message: string) => void; info?: (message: string) => void }
52
+ ): PluginHookBeforeToolCallResult {
53
+ const { filePath, reason, toolName, sessionId, blockSource } = blockCtx;
54
+
55
+ // Default logger if not provided
56
+ const logWarn = (msg: string) => logger.warn?.(msg);
57
+ const logError = (msg: string) => logger.error?.(msg);
58
+
59
+ // Log the block event
60
+ const sourceTag = blockSource ? `[${blockSource}]` : '';
61
+ logError(`[PD_GATE]${sourceTag} BLOCKED: ${filePath}. Reason: ${reason}`);
62
+
63
+ // 1. Track block for session-level GFI calculation
64
+ if (sessionId) {
65
+ trackBlock(sessionId);
66
+ }
67
+
68
+ // 2. Prepare trajectory payload
69
+ const trajectoryPayload = {
70
+ sessionId: sessionId ?? null,
71
+ toolName,
72
+ filePath,
73
+ reason,
74
+ blockSource: blockSource ?? 'gate',
75
+ };
76
+
77
+ // 3. Record to EventLog (primary persistence)
78
+ try {
79
+ wctx.eventLog.recordGateBlock(sessionId, {
80
+ toolName,
81
+ filePath,
82
+ reason,
83
+ blockSource: blockSource ?? 'gate',
84
+ });
85
+ } catch (error: unknown) {
86
+ logWarn(`[PD_GATE] Failed to record gate block event: ${String(error)}`);
87
+ }
88
+
89
+ // 4. Record to trajectory (secondary persistence with retry)
90
+ try {
91
+ wctx.trajectory?.recordGateBlock?.(trajectoryPayload);
92
+ } catch (error: unknown) {
93
+ logWarn(`[PD_GATE] Failed to record trajectory gate block: ${String(error)}`);
94
+ scheduleTrajectoryGateBlockRetry(wctx, trajectoryPayload, 1, logWarn, logError);
95
+ }
96
+
97
+ // 5. Return consistent block result with operator guidance
98
+ return {
99
+ block: true,
100
+ blockReason: `[Principles Disciple] Security Gate Blocked this action.
101
+ File: ${filePath}
102
+ Reason: ${reason}
103
+
104
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
105
+ 📋 How to unblock this operation:
106
+
107
+ 1. Use the plan-script skill to create a PLAN.md:
108
+ → Invoke: skill:plan-script
109
+
110
+ 2. Fill in the plan with:
111
+ - Target Files: ${filePath}
112
+ - Steps: What you want to do (be specific)
113
+ - Metrics: How to verify success
114
+ - Active Mental Models: Select 2 relevant models from .principles/THINKING_OS.md
115
+ - Rollback: How to restore if it fails
116
+
117
+ 3. After completing the plan, set STATUS: READY in PLAN.md
118
+
119
+ 4. Retry the operation
120
+
121
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
122
+ This is a mandatory security gate. The operation was blocked because the modification exceeds the allowed threshold for your current evolution tier.
123
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`,
124
+ };
125
+ }
126
+
127
+ /**
128
+ * Schedule retry for trajectory gate block persistence.
129
+ *
130
+ * Uses exponential backoff with max retries.
131
+ * Failures are logged but do not affect the runtime block decision.
132
+ */
133
+ function scheduleTrajectoryGateBlockRetry(
134
+ wctx: WorkspaceContext,
135
+ payload: {
136
+ sessionId: string | null;
137
+ toolName: string;
138
+ filePath: string;
139
+ reason: string;
140
+ blockSource?: string;
141
+ },
142
+ attempt: number,
143
+ logWarn: (message: string) => void,
144
+ logError: (message: string) => void
145
+ ): void {
146
+ if (attempt > TRAJECTORY_GATE_BLOCK_MAX_RETRIES) {
147
+ logError(`[PD_GATE] Failed to persist trajectory gate block after ${TRAJECTORY_GATE_BLOCK_MAX_RETRIES} retries: ${payload.toolName} ${payload.filePath}`);
148
+ return;
149
+ }
150
+
151
+ setTimeout(() => {
152
+ try {
153
+ wctx.trajectory?.recordGateBlock?.(payload);
154
+ logWarn(`[PD_GATE] Trajectory gate block persisted on retry ${attempt}`);
155
+ } catch (error: unknown) {
156
+ logWarn(`[PD_GATE] Retrying trajectory gate block persistence (attempt ${attempt + 1}): ${String(error)}`);
157
+ scheduleTrajectoryGateBlockRetry(wctx, payload, attempt + 1, logWarn, logError);
158
+ }
159
+ }, TRAJECTORY_GATE_BLOCK_RETRY_DELAY_MS * attempt);
160
+ }
@@ -0,0 +1,210 @@
1
+ /**
2
+ * Security Gate Hook - Orchestration Layer
3
+ *
4
+ * HOOK CHAIN PRIORITY (short-circuits on first block):
5
+ *
6
+ * 1. Early Return: Skip if not write/bash/agent tool or no workspace
7
+ * 2. Thinking OS Checkpoint (P-10): Deep reflection enforcement
8
+ * 3. GFI Gate: Fatigue index-based blocking
9
+ * 4. Bash Mutation Detection: Heuristic for bash file modifications
10
+ * 5. Progressive Gate: EP tier-based access control
11
+ * 6. Edit Verification (P-03): Exact/fuzzy match for edit operations
12
+ *
13
+ * IMPORTANT: This is the SINGLE AUTHORITATIVE orchestration path.
14
+ * All policy modules (gfi-gate, progressive-trust-gate) use the shared
15
+ * `recordGateBlockAndReturn` helper to ensure consistent block persistence.
16
+ *
17
+ * Zero-width character detection is handled in bash-risk.ts.
18
+ */
19
+
20
+ import * as fs from 'fs';
21
+ import * as path from 'path';
22
+ import { isRisky, normalizePath, planStatus as getPlanStatus } from '../utils/io.js';
23
+ import { normalizeProfile } from '../core/profile.js';
24
+ import { estimateLineChanges } from '../core/risk-calculator.js';
25
+ import { WorkspaceContext } from '../core/workspace-context.js';
26
+ import { checkThinkingCheckpoint } from './thinking-checkpoint.js';
27
+ import { handleEditVerification } from './edit-verification.js';
28
+ import { checkGfiGate } from './gfi-gate.js';
29
+ import { checkProgressiveTrustGate } from './progressive-trust-gate.js';
30
+ import { recordGateBlockAndReturn } from './gate-block-helper.js';
31
+ import type { PluginHookBeforeToolCallEvent, PluginHookToolContext, PluginHookBeforeToolCallResult } from '../openclaw-sdk.js';
32
+ import {
33
+ AGENT_TOOLS,
34
+ BASH_TOOLS_SET,
35
+ WRITE_TOOLS,
36
+ } from '../constants/tools.js';
37
+
38
+ export function handleBeforeToolCall(
39
+ event: PluginHookBeforeToolCallEvent,
40
+ ctx: PluginHookToolContext & { workspaceDir?: string; pluginConfig?: Record<string, unknown>; logger?: any }
41
+ ): PluginHookBeforeToolCallResult | void {
42
+ const logger = ctx.logger || console;
43
+
44
+ // 1. Identify tool type
45
+ const isBash = BASH_TOOLS_SET.has(event.toolName);
46
+ const isWriteTool = WRITE_TOOLS.has(event.toolName);
47
+ const isAgentTool = AGENT_TOOLS.has(event.toolName);
48
+
49
+ if (!ctx.workspaceDir || (!isWriteTool && !isBash && !isAgentTool)) {
50
+ return;
51
+ }
52
+
53
+ const wctx = WorkspaceContext.fromHookContext(ctx);
54
+
55
+ // 2. Load Profile
56
+ const profilePath = wctx.resolve('PROFILE');
57
+ let profile = {
58
+ risk_paths: [] as string[],
59
+ gate: { require_plan_for_risk_paths: true },
60
+ progressive_gate: {
61
+ enabled: true,
62
+ plan_approvals: {
63
+ enabled: false,
64
+ max_lines_override: -1,
65
+ allowed_patterns: [] as string[],
66
+ allowed_operations: [] as string[],
67
+ }
68
+ },
69
+ edit_verification: {
70
+ enabled: true,
71
+ max_file_size_bytes: 10 * 1024 * 1024,
72
+ fuzzy_match_enabled: true,
73
+ fuzzy_match_threshold: 0.8,
74
+ skip_large_file_action: 'warn' as 'warn' | 'block',
75
+ },
76
+ thinking_checkpoint: {
77
+ enabled: false, // Default OFF
78
+ window_ms: 5 * 60 * 1000,
79
+ high_risk_tools: ['run_shell_command', 'delete_file', 'move_file'],
80
+ }
81
+ };
82
+
83
+ if (fs.existsSync(profilePath)) {
84
+ try {
85
+ const rawProfile = JSON.parse(fs.readFileSync(profilePath, 'utf8'));
86
+ profile = normalizeProfile(rawProfile);
87
+ } catch (e) {
88
+ logger?.error?.(`[PD_GATE] Failed to parse PROFILE.json: ${String(e)}`);
89
+ }
90
+ }
91
+
92
+ // ─────────────────────────────────────────────────────────────────────────────
93
+ // POLICY STEP 1: Thinking OS Checkpoint (P-10)
94
+ // ─────────────────────────────────────────────────────────────────────────────
95
+ // Only enforced when thinking_checkpoint.enabled = true in PROFILE.json
96
+ const thinkingResult = checkThinkingCheckpoint(
97
+ event,
98
+ profile.thinking_checkpoint || {},
99
+ ctx.sessionId,
100
+ logger
101
+ );
102
+ if (thinkingResult) {
103
+ return thinkingResult;
104
+ }
105
+
106
+ // ─────────────────────────────────────────────────────────────────────────────
107
+ // POLICY STEP 2: GFI Gate - Hard Intercept
108
+ // ─────────────────────────────────────────────────────────────────────────────
109
+ // 根据 GFI (疲劳指数) 精细化拦截工具调用
110
+ // 注意:TIER 0 (只读工具) 已在早期过滤中放行,此处不检查
111
+ const gfiGateConfig = wctx.config.get('gfi_gate');
112
+ const gfiResult = checkGfiGate(event, wctx, ctx.sessionId, gfiGateConfig, logger);
113
+ if (gfiResult) {
114
+ return gfiResult;
115
+ }
116
+
117
+ // Merge pluginConfig (OpenClaw UI settings)
118
+ const configRiskPaths = (ctx.pluginConfig?.riskPaths as string[] | undefined) ?? [];
119
+ if (configRiskPaths.length > 0) {
120
+ profile.risk_paths = [...new Set([...profile.risk_paths, ...configRiskPaths])];
121
+ }
122
+
123
+ // 3. Resolve the target file path
124
+ let filePath = event.params.file_path || event.params.path || event.params.file || event.params.target;
125
+
126
+ // Heuristic for bash mutation detection
127
+ if (isBash && !filePath) {
128
+ const command = String(event.params.command || event.params.args || "");
129
+ const mutationMatch = command.match(/(?:>|>>|sed\s+-i|rm|mv|mkdir|touch|cp)\s+(?:-[a-zA-Z]+\s+)*([^\s;&|<>]+)/);
130
+
131
+ if (mutationMatch) {
132
+ filePath = mutationMatch[1];
133
+ } else {
134
+ const hasRiskPath = profile.risk_paths.some(rp => command.includes(rp));
135
+ const isMutation = /(?:>|>>|sed|rm|mv|mkdir|touch|cp|npm|yarn|pnpm|pip|cargo)/.test(command);
136
+
137
+ if (hasRiskPath && isMutation) {
138
+ filePath = command;
139
+ } else {
140
+ return;
141
+ }
142
+ }
143
+ }
144
+
145
+ if (typeof filePath !== 'string') return;
146
+
147
+ const relPath = normalizePath(filePath, ctx.workspaceDir);
148
+ const risky = (isBash && filePath.includes(' '))
149
+ ? profile.risk_paths.some(rp => filePath.includes(rp))
150
+ : isRisky(relPath, profile.risk_paths);
151
+
152
+ // ─────────────────────────────────────────────────────────────────────────────
153
+ // POLICY STEP 3: Progressive Trust Gate (Stage 1-4 access control)
154
+ // ─────────────────────────────────────────────────────────────────────────────
155
+ // IMPORTANT: This step does NOT return early on allow.
156
+ // We must continue to edit verification for ALL allowed operations.
157
+ if (profile.progressive_gate?.enabled) {
158
+ const lineChanges = estimateLineChanges({ toolName: event.toolName, params: event.params });
159
+ const progressiveGateResult = checkProgressiveTrustGate(
160
+ event,
161
+ wctx,
162
+ relPath,
163
+ risky,
164
+ lineChanges,
165
+ logger,
166
+ ctx,
167
+ profile
168
+ );
169
+ if (progressiveGateResult) {
170
+ return progressiveGateResult;
171
+ }
172
+ // NOTE: Do NOT return here! Continue to edit verification.
173
+ // All allowed operations (regardless of EP tier) should still run edit verification.
174
+ } else {
175
+ // FALLBACK: Legacy Gate Logic (when progressive gate is disabled)
176
+ if (risky && profile.gate?.require_plan_for_risk_paths) {
177
+ const planStatus = getPlanStatus(ctx.workspaceDir);
178
+ if (planStatus !== 'READY') {
179
+ return recordGateBlockAndReturn(wctx, {
180
+ filePath: relPath,
181
+ reason: `No READY plan found in PLAN.md.`,
182
+ toolName: event.toolName,
183
+ sessionId: ctx.sessionId,
184
+ blockSource: 'gate-legacy',
185
+ }, logger);
186
+ }
187
+ }
188
+ }
189
+
190
+ // ─────────────────────────────────────────────────────────────────────────────
191
+ // POLICY STEP 4: Edit Tool Verification (P-03)
192
+ // ─────────────────────────────────────────────────────────────────────────────
193
+ // This MUST run after all other gate checks for ALL tools.
194
+ // Edit verification ensures oldText matches the actual file content.
195
+ if (event.toolName === 'edit' && profile.edit_verification?.enabled !== false) {
196
+ const verifyResult = handleEditVerification(event, wctx, ctx, {
197
+ enabled: profile.edit_verification.enabled,
198
+ max_file_size_bytes: profile.edit_verification.max_file_size_bytes,
199
+ fuzzy_match_enabled: profile.edit_verification.fuzzy_match_enabled,
200
+ fuzzy_match_threshold: profile.edit_verification.fuzzy_match_threshold,
201
+ skip_large_file_action: profile.edit_verification.skip_large_file_action as 'warn' | 'block' | undefined,
202
+ });
203
+ if (verifyResult) {
204
+ return verifyResult; // Block or modify params
205
+ }
206
+ }
207
+
208
+ // All checks passed - allow the operation
209
+ return;
210
+ }
@@ -0,0 +1,177 @@
1
+ /**
2
+ * GFI Gate Module
3
+ *
4
+ * Handles Fatigue Index (GFI) based tool blocking with TIER 0-3 classification.
5
+ *
6
+ * **Responsibilities:**
7
+ * - Calculate dynamic GFI thresholds based on EP tier and line changes
8
+ * - Apply tier-based tool blocking:
9
+ * - TIER 0: Read-only tools (never blocked)
10
+ * - TIER 1: Low-risk writes (blocked when GFI >= low_risk_block threshold)
11
+ * - TIER 2: High-risk operations (blocked when GFI >= high_risk_block threshold)
12
+ * - TIER 3: Bash commands (content-dependent blocking)
13
+ * - Prevent subagent spawn at critically high GFI (>=90)
14
+ *
15
+ * **Configuration:**
16
+ * - GFI thresholds from config.gfi_gate
17
+ * - EP tier multipliers for dynamic threshold calculation
18
+ * - Large change adjustments
19
+ *
20
+ * **Block Persistence:**
21
+ * - Uses shared `recordGateBlockAndReturn` from gate-block-helper.ts
22
+ * - Ensures single authoritative block persistence path
23
+ */
24
+
25
+ import { getSession } from '../core/session-tracker.js';
26
+ import { estimateLineChanges } from '../core/risk-calculator.js';
27
+ import { analyzeBashCommand, calculateDynamicThreshold, type DynamicThresholdConfig } from './bash-risk.js';
28
+ import { BASH_TOOLS_SET, HIGH_RISK_TOOLS, LOW_RISK_WRITE_TOOLS, AGENT_TOOLS } from '../constants/tools.js';
29
+ import { AGENT_SPAWN_GFI_THRESHOLD } from '../config/index.js';
30
+ import { recordGateBlockAndReturn } from './gate-block-helper.js';
31
+ import { getEvolutionEngine } from '../core/evolution-engine.js';
32
+ import type { WorkspaceContext } from '../core/workspace-context.js';
33
+ import type { PluginHookBeforeToolCallEvent, PluginHookBeforeToolCallResult } from '../openclaw-sdk.js';
34
+
35
+ export interface GfiGateConfig {
36
+ enabled?: boolean;
37
+ thresholds?: {
38
+ low_risk_block?: number;
39
+ high_risk_block?: number;
40
+ };
41
+ large_change_lines?: number;
42
+ ep_tier_multipliers?: Record<string, number>;
43
+ bash_safe_patterns?: string[];
44
+ bash_dangerous_patterns?: string[];
45
+ }
46
+
47
+ /**
48
+ * Internal helper to call the shared block helper with gfi-gate source tag.
49
+ */
50
+ function block(
51
+ wctx: WorkspaceContext,
52
+ filePath: string,
53
+ reason: string,
54
+ toolName: string,
55
+ sessionId: string | undefined,
56
+ logger?: { info?: (message: string) => void; warn?: (message: string) => void; error?: (message: string) => void }
57
+ ): PluginHookBeforeToolCallResult {
58
+ return recordGateBlockAndReturn(wctx, {
59
+ filePath,
60
+ reason,
61
+ toolName,
62
+ sessionId,
63
+ blockSource: 'gfi-gate',
64
+ }, logger || { warn: () => {}, error: () => {} });
65
+ }
66
+
67
+ export function checkGfiGate(
68
+ event: PluginHookBeforeToolCallEvent,
69
+ wctx: WorkspaceContext,
70
+ sessionId: string | undefined,
71
+ config: GfiGateConfig,
72
+ logger?: { info?: (message: string) => void; warn?: (message: string) => void }
73
+ ): PluginHookBeforeToolCallResult | undefined {
74
+ if (!config || config.enabled === false || !sessionId) {
75
+ return undefined;
76
+ }
77
+
78
+ const session = getSession(sessionId);
79
+ const currentGfi = session?.currentGfi || 0;
80
+
81
+ const getEpTier = (): number => {
82
+ return getEvolutionEngine(wctx.workspaceDir).getTier();
83
+ };
84
+
85
+ // TIER 3: Bash commands
86
+ if (BASH_TOOLS_SET.has(event.toolName)) {
87
+ const command = String(event.params.command || event.params.args || '');
88
+ const bashRisk = analyzeBashCommand(
89
+ command,
90
+ config.bash_safe_patterns || [],
91
+ config.bash_dangerous_patterns || [],
92
+ logger
93
+ );
94
+
95
+ if (bashRisk === 'dangerous') {
96
+ logger?.warn?.(`[PD:GFI_GATE] Dangerous bash command blocked: ${command.substring(0, 50)}...`);
97
+ return block(wctx, command.substring(0, 100), `危险命令被拦截。检测到危险命令模式,需要确认执行意图。`, event.toolName, sessionId, logger);
98
+ }
99
+
100
+ if (bashRisk === 'safe') {
101
+ return undefined;
102
+ }
103
+
104
+ // normal bash - check GFI threshold
105
+ const tier = getEpTier();
106
+ const baseThreshold = config.thresholds?.low_risk_block || 70;
107
+ const dynamicThreshold = calculateDynamicThreshold(
108
+ baseThreshold,
109
+ tier,
110
+ 0,
111
+ {
112
+ large_change_lines: config.large_change_lines || 50,
113
+ ep_tier_multipliers: config.ep_tier_multipliers || { '1': 0.5, '2': 0.75, '3': 1.0, '4': 1.5, '5': 2.0 },
114
+ }
115
+ );
116
+
117
+ if (currentGfi >= dynamicThreshold) {
118
+ logger?.warn?.(`[PD:GFI_GATE] Bash blocked by GFI: ${currentGfi} >= ${dynamicThreshold}`);
119
+ return block(wctx, command.substring(0, 100), `疲劳指数过高 (GFI: ${currentGfi}/${dynamicThreshold})。系统进入保护模式。`, event.toolName, sessionId, logger);
120
+ }
121
+
122
+ return undefined;
123
+ }
124
+
125
+ // TIER 2: High-risk tools
126
+ if (HIGH_RISK_TOOLS.has(event.toolName)) {
127
+ const tier = getEpTier();
128
+ const baseThreshold = config.thresholds?.high_risk_block || 40;
129
+ const dynamicThreshold = calculateDynamicThreshold(
130
+ baseThreshold,
131
+ tier,
132
+ 0,
133
+ {
134
+ large_change_lines: config.large_change_lines || 50,
135
+ ep_tier_multipliers: config.ep_tier_multipliers || { '1': 0.5, '2': 0.75, '3': 1.0, '4': 1.5, '5': 2.0 },
136
+ }
137
+ );
138
+
139
+ if (currentGfi >= dynamicThreshold) {
140
+ const filePath = event.params.file_path || event.params.path || event.params.file || event.params.target || 'unknown';
141
+ logger?.warn?.(`[PD:GFI_GATE] High-risk tool "${event.toolName}" blocked by GFI: ${currentGfi} >= ${dynamicThreshold}`);
142
+ return block(wctx, filePath, `高风险操作被拦截。GFI: ${currentGfi}/${dynamicThreshold}。高风险工具需要更低的阈值。`, event.toolName, sessionId, logger);
143
+ }
144
+ }
145
+
146
+ // TIER 1: Low-risk write tools
147
+ if (LOW_RISK_WRITE_TOOLS.has(event.toolName)) {
148
+ const tier = getEpTier();
149
+ const lineChanges = estimateLineChanges({ toolName: event.toolName, params: event.params });
150
+ const baseThreshold = config.thresholds?.low_risk_block || 70;
151
+ const dynamicThreshold = calculateDynamicThreshold(
152
+ baseThreshold,
153
+ tier,
154
+ lineChanges,
155
+ {
156
+ large_change_lines: config.large_change_lines || 50,
157
+ ep_tier_multipliers: config.ep_tier_multipliers || { '1': 0.5, '2': 0.75, '3': 1.0, '4': 1.5, '5': 2.0 },
158
+ }
159
+ );
160
+
161
+ if (currentGfi >= dynamicThreshold) {
162
+ const filePath = event.params.file_path || event.params.path || event.params.file || event.params.target || 'unknown';
163
+ logger?.warn?.(`[PD:GFI_GATE] Low-risk tool "${event.toolName}" blocked by GFI: ${currentGfi} >= ${dynamicThreshold}`);
164
+ return block(wctx, filePath, `疲劳指数过高 (GFI: ${currentGfi}/${dynamicThreshold})。系统进入保护模式。`, event.toolName, sessionId, logger);
165
+ }
166
+ }
167
+
168
+ // AGENT_TOOLS: Block subagent spawn when GFI is critically high
169
+ if (AGENT_TOOLS.has(event.toolName)) {
170
+ if (currentGfi >= AGENT_SPAWN_GFI_THRESHOLD) {
171
+ logger?.warn?.(`[PD:GFI_GATE] Agent tool "${event.toolName}" blocked by GFI: ${currentGfi} >= ${AGENT_SPAWN_GFI_THRESHOLD}`);
172
+ return block(wctx, 'subagent-spawn', `疲劳指数过高,禁止派生子智能体。GFI: ${currentGfi}/${AGENT_SPAWN_GFI_THRESHOLD}`, event.toolName, sessionId, logger);
173
+ }
174
+ }
175
+
176
+ return undefined;
177
+ }