@dommaker/harness 0.19.0 → 1.1.0

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 (398) hide show
  1. package/CHANGELOG.md +22 -9
  2. package/bin/harness.js +136 -557
  3. package/dist/cli/commands/check.d.ts.map +1 -1
  4. package/dist/cli/commands/check.js +2 -13
  5. package/dist/cli/commands/check.js.map +1 -1
  6. package/dist/cli/commands/definitions.d.ts +90 -0
  7. package/dist/cli/commands/definitions.d.ts.map +1 -0
  8. package/dist/cli/commands/definitions.js +519 -0
  9. package/dist/cli/commands/definitions.js.map +1 -0
  10. package/dist/cli/commands/knowledge.js.map +1 -1
  11. package/dist/cli/commands/sync-docs/agents-syncer.d.ts.map +1 -1
  12. package/dist/cli/commands/sync-docs/agents-syncer.js +25 -4
  13. package/dist/cli/commands/sync-docs/agents-syncer.js.map +1 -1
  14. package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts +3 -25
  15. package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts.map +1 -1
  16. package/dist/cli/commands/sync-docs/capabilities-syncer.js +3 -93
  17. package/dist/cli/commands/sync-docs/capabilities-syncer.js.map +1 -1
  18. package/dist/cli/commands/sync-docs/index.d.ts +1 -1
  19. package/dist/cli/commands/sync-docs/index.d.ts.map +1 -1
  20. package/dist/cli/commands/sync-docs/index.js +4 -4
  21. package/dist/cli/commands/sync-docs/index.js.map +1 -1
  22. package/dist/completion-checkers/classify.d.ts +23 -0
  23. package/dist/completion-checkers/classify.d.ts.map +1 -0
  24. package/dist/completion-checkers/classify.js +37 -0
  25. package/dist/completion-checkers/classify.js.map +1 -0
  26. package/dist/completion-checkers/contract-presence.d.ts +12 -0
  27. package/dist/completion-checkers/contract-presence.d.ts.map +1 -0
  28. package/dist/completion-checkers/contract-presence.js +36 -0
  29. package/dist/completion-checkers/contract-presence.js.map +1 -0
  30. package/dist/completion-checkers/glob-match.d.ts +13 -0
  31. package/dist/completion-checkers/glob-match.d.ts.map +1 -0
  32. package/dist/completion-checkers/glob-match.js +58 -0
  33. package/dist/completion-checkers/glob-match.js.map +1 -0
  34. package/dist/completion-checkers/index.d.ts +19 -0
  35. package/dist/completion-checkers/index.d.ts.map +1 -0
  36. package/dist/completion-checkers/index.js +47 -0
  37. package/dist/completion-checkers/index.js.map +1 -0
  38. package/dist/completion-checkers/phase-format.d.ts +15 -0
  39. package/dist/completion-checkers/phase-format.d.ts.map +1 -0
  40. package/dist/completion-checkers/phase-format.js +42 -0
  41. package/dist/completion-checkers/phase-format.js.map +1 -0
  42. package/dist/completion-checkers/tdd-chain.d.ts +16 -0
  43. package/dist/completion-checkers/tdd-chain.d.ts.map +1 -0
  44. package/dist/completion-checkers/tdd-chain.js +57 -0
  45. package/dist/completion-checkers/tdd-chain.js.map +1 -0
  46. package/dist/completion-checkers/types.d.ts +77 -0
  47. package/dist/completion-checkers/types.d.ts.map +1 -0
  48. package/dist/completion-checkers/types.js +10 -0
  49. package/dist/completion-checkers/types.js.map +1 -0
  50. package/dist/context/index.d.ts +1 -5
  51. package/dist/context/index.d.ts.map +1 -1
  52. package/dist/context/index.js +1 -5
  53. package/dist/context/index.js.map +1 -1
  54. package/dist/context/knowledge-injector.d.ts +3 -3
  55. package/dist/context/knowledge-injector.d.ts.map +1 -1
  56. package/dist/context/knowledge-injector.js +1 -1
  57. package/dist/context/session-manager.d.ts +1 -12
  58. package/dist/context/session-manager.d.ts.map +1 -1
  59. package/dist/context/session-manager.js +0 -63
  60. package/dist/context/session-manager.js.map +1 -1
  61. package/dist/context/types.d.ts +1 -39
  62. package/dist/context/types.d.ts.map +1 -1
  63. package/dist/context/types.js +2 -15
  64. package/dist/context/types.js.map +1 -1
  65. package/dist/core/constraints/agent-prompt-renderer.d.ts +1 -1
  66. package/dist/core/constraints/agent-prompt-renderer.js +1 -1
  67. package/dist/core/constraints/capabilities-parser.d.ts +17 -2
  68. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
  69. package/dist/core/constraints/capabilities-parser.js +84 -2
  70. package/dist/core/constraints/capabilities-parser.js.map +1 -1
  71. package/dist/core/constraints/checker.d.ts +3 -17
  72. package/dist/core/constraints/checker.d.ts.map +1 -1
  73. package/dist/core/constraints/checker.js +7 -47
  74. package/dist/core/constraints/checker.js.map +1 -1
  75. package/dist/core/constraints/definitions.d.ts +0 -7
  76. package/dist/core/constraints/definitions.d.ts.map +1 -1
  77. package/dist/core/constraints/definitions.js +1 -8
  78. package/dist/core/constraints/definitions.js.map +1 -1
  79. package/dist/core/constraints/doc-freshness/runner.d.ts +0 -2
  80. package/dist/core/constraints/doc-freshness/runner.d.ts.map +1 -1
  81. package/dist/core/constraints/doc-freshness/runner.js.map +1 -1
  82. package/dist/core/constraints/index.d.ts +1 -1
  83. package/dist/core/constraints/index.d.ts.map +1 -1
  84. package/dist/core/constraints/index.js +2 -3
  85. package/dist/core/constraints/index.js.map +1 -1
  86. package/dist/core/constraints/interceptor.d.ts.map +1 -1
  87. package/dist/core/constraints/interceptor.js +1 -5
  88. package/dist/core/constraints/interceptor.js.map +1 -1
  89. package/dist/core/effective-constraints.d.ts.map +1 -1
  90. package/dist/core/effective-constraints.js +0 -1
  91. package/dist/core/effective-constraints.js.map +1 -1
  92. package/dist/core/project-config-loader.d.ts.map +1 -1
  93. package/dist/core/project-config-loader.js +1 -8
  94. package/dist/core/project-config-loader.js.map +1 -1
  95. package/dist/dashboard/stats.d.ts.map +1 -1
  96. package/dist/dashboard/stats.js.map +1 -1
  97. package/dist/dashboard/types.d.ts +2 -2
  98. package/dist/dashboard/types.d.ts.map +1 -1
  99. package/dist/failure/constraint-handler.d.ts.map +1 -1
  100. package/dist/failure/constraint-handler.js +0 -2
  101. package/dist/failure/constraint-handler.js.map +1 -1
  102. package/dist/gates/acceptance.d.ts +9 -1
  103. package/dist/gates/acceptance.d.ts.map +1 -1
  104. package/dist/gates/acceptance.js +21 -0
  105. package/dist/gates/acceptance.js.map +1 -1
  106. package/dist/gates/checker-gate.d.ts +23 -0
  107. package/dist/gates/checker-gate.d.ts.map +1 -0
  108. package/dist/gates/checker-gate.js +53 -0
  109. package/dist/gates/checker-gate.js.map +1 -0
  110. package/dist/gates/command.d.ts +9 -2
  111. package/dist/gates/command.d.ts.map +1 -1
  112. package/dist/gates/command.js +10 -0
  113. package/dist/gates/command.js.map +1 -1
  114. package/dist/gates/contract.d.ts +8 -2
  115. package/dist/gates/contract.d.ts.map +1 -1
  116. package/dist/gates/contract.js +9 -0
  117. package/dist/gates/contract.js.map +1 -1
  118. package/dist/gates/decision.d.ts +17 -0
  119. package/dist/gates/decision.d.ts.map +1 -0
  120. package/dist/gates/decision.js +25 -0
  121. package/dist/gates/decision.js.map +1 -0
  122. package/dist/gates/definitions.d.ts +63 -0
  123. package/dist/gates/definitions.d.ts.map +1 -0
  124. package/dist/gates/definitions.js +160 -0
  125. package/dist/gates/definitions.js.map +1 -0
  126. package/dist/gates/effective-gates.d.ts +30 -0
  127. package/dist/gates/effective-gates.d.ts.map +1 -0
  128. package/dist/gates/effective-gates.js +85 -0
  129. package/dist/gates/effective-gates.js.map +1 -0
  130. package/dist/gates/index.d.ts +25 -1
  131. package/dist/gates/index.d.ts.map +1 -1
  132. package/dist/gates/index.js +37 -1
  133. package/dist/gates/index.js.map +1 -1
  134. package/dist/gates/performance.d.ts +8 -2
  135. package/dist/gates/performance.d.ts.map +1 -1
  136. package/dist/gates/performance.js +9 -0
  137. package/dist/gates/performance.js.map +1 -1
  138. package/dist/gates/registry.d.ts +32 -0
  139. package/dist/gates/registry.d.ts.map +1 -0
  140. package/dist/gates/registry.js +90 -0
  141. package/dist/gates/registry.js.map +1 -0
  142. package/dist/gates/review.d.ts +8 -2
  143. package/dist/gates/review.d.ts.map +1 -1
  144. package/dist/gates/review.js +9 -0
  145. package/dist/gates/review.js.map +1 -1
  146. package/dist/gates/runner.d.ts +30 -0
  147. package/dist/gates/runner.d.ts.map +1 -0
  148. package/dist/gates/runner.js +38 -0
  149. package/dist/gates/runner.js.map +1 -0
  150. package/dist/gates/security.d.ts +8 -2
  151. package/dist/gates/security.d.ts.map +1 -1
  152. package/dist/gates/security.js +9 -0
  153. package/dist/gates/security.js.map +1 -1
  154. package/dist/gates/types.d.ts +41 -1
  155. package/dist/gates/types.d.ts.map +1 -1
  156. package/dist/hooks/bootstrap.d.ts.map +1 -1
  157. package/dist/hooks/bootstrap.js +0 -2
  158. package/dist/hooks/bootstrap.js.map +1 -1
  159. package/dist/hooks/config.d.ts +26 -0
  160. package/dist/hooks/config.d.ts.map +1 -0
  161. package/dist/hooks/config.js +30 -0
  162. package/dist/hooks/config.js.map +1 -0
  163. package/dist/hooks/index.d.ts +2 -1
  164. package/dist/hooks/index.d.ts.map +1 -1
  165. package/dist/hooks/index.js +4 -1
  166. package/dist/hooks/index.js.map +1 -1
  167. package/dist/hooks/registry.d.ts +18 -1
  168. package/dist/hooks/registry.d.ts.map +1 -1
  169. package/dist/hooks/registry.js +45 -0
  170. package/dist/hooks/registry.js.map +1 -1
  171. package/dist/hooks/types.d.ts +20 -0
  172. package/dist/hooks/types.d.ts.map +1 -1
  173. package/dist/index.d.ts +5 -8
  174. package/dist/index.d.ts.map +1 -1
  175. package/dist/index.js +11 -20
  176. package/dist/index.js.map +1 -1
  177. package/dist/knowledge/import.d.ts +2 -2
  178. package/dist/knowledge/import.d.ts.map +1 -1
  179. package/dist/knowledge/ingest.js.map +1 -1
  180. package/dist/knowledge/lifecycle-hooks.d.ts +2 -2
  181. package/dist/knowledge/lifecycle-hooks.d.ts.map +1 -1
  182. package/dist/knowledge/types.d.ts +5 -7
  183. package/dist/knowledge/types.d.ts.map +1 -1
  184. package/dist/knowledge/types.js +1 -1
  185. package/dist/knowledge/types.js.map +1 -1
  186. package/dist/monitoring/constraint-doctor.d.ts +4 -22
  187. package/dist/monitoring/constraint-doctor.d.ts.map +1 -1
  188. package/dist/monitoring/constraint-doctor.js +7 -94
  189. package/dist/monitoring/constraint-doctor.js.map +1 -1
  190. package/dist/presets/standard.d.ts +1 -1
  191. package/dist/presets/standard.d.ts.map +1 -1
  192. package/dist/presets/standard.js +1 -2
  193. package/dist/presets/standard.js.map +1 -1
  194. package/dist/pretool-use-hook.d.ts +16 -0
  195. package/dist/pretool-use-hook.d.ts.map +1 -0
  196. package/dist/pretool-use-hook.js +68 -0
  197. package/dist/pretool-use-hook.js.map +1 -0
  198. package/dist/spec/annotation-checker.d.ts.map +1 -1
  199. package/dist/spec/annotation-checker.js +6 -26
  200. package/dist/spec/annotation-checker.js.map +1 -1
  201. package/dist/tools/index.d.ts +0 -4
  202. package/dist/tools/index.d.ts.map +1 -1
  203. package/dist/tools/index.js +0 -4
  204. package/dist/tools/index.js.map +1 -1
  205. package/dist/types/constraint.d.ts +1 -12
  206. package/dist/types/constraint.d.ts.map +1 -1
  207. package/dist/types/constraint.js +0 -3
  208. package/dist/types/constraint.js.map +1 -1
  209. package/dist/types/project-config.d.ts +0 -2
  210. package/dist/types/project-config.d.ts.map +1 -1
  211. package/dist/utils/file-walk.d.ts +2 -2
  212. package/dist/utils/file-walk.js +2 -2
  213. package/package.json +6 -1
  214. package/src/CONTEXT.md +15 -0
  215. package/src/__tests__/checker-extra.test.ts +2 -59
  216. package/src/__tests__/constraint-doctor.test.ts +1 -140
  217. package/src/__tests__/constraint-handler.test.ts +0 -4
  218. package/src/__tests__/pretool-use-hook.test.ts +82 -0
  219. package/src/__tests__/project-config-loader-extra.test.ts +0 -20
  220. package/src/__tests__/project-config-loader.test.ts +0 -1
  221. package/src/cli/commands/CONTEXT.md +15 -7
  222. package/src/cli/commands/__tests__/check-drift.test.ts +0 -3
  223. package/src/cli/commands/__tests__/check-skip-output.test.ts +0 -5
  224. package/src/cli/commands/__tests__/check.test.ts +7 -75
  225. package/src/cli/commands/__tests__/registry.test.ts +201 -0
  226. package/src/cli/commands/__tests__/sync-docs-agents.test.ts +55 -0
  227. package/src/cli/commands/check.ts +2 -14
  228. package/src/cli/commands/definitions.ts +593 -0
  229. package/src/cli/commands/knowledge.ts +3 -3
  230. package/src/cli/commands/sync-docs/agents-syncer.ts +26 -6
  231. package/src/cli/commands/sync-docs/capabilities-syncer.ts +4 -110
  232. package/src/cli/commands/sync-docs/index.ts +8 -5
  233. package/src/completion-checkers/CONTEXT.md +25 -0
  234. package/src/completion-checkers/__tests__/contract-presence.test.ts +44 -0
  235. package/src/completion-checkers/__tests__/phase-format.test.ts +60 -0
  236. package/src/completion-checkers/__tests__/tdd-chain.test.ts +99 -0
  237. package/src/completion-checkers/classify.ts +47 -0
  238. package/src/completion-checkers/contract-presence.ts +40 -0
  239. package/src/completion-checkers/glob-match.ts +54 -0
  240. package/src/completion-checkers/index.ts +19 -0
  241. package/src/completion-checkers/phase-format.ts +48 -0
  242. package/src/completion-checkers/tdd-chain.ts +63 -0
  243. package/src/completion-checkers/types.ts +84 -0
  244. package/src/context/CONTEXT.md +2 -7
  245. package/src/context/__tests__/session-manager.test.ts +0 -91
  246. package/src/context/index.ts +1 -5
  247. package/src/context/knowledge-injector.ts +3 -3
  248. package/src/context/session-manager.ts +0 -74
  249. package/src/context/types.ts +2 -63
  250. package/src/core/constraints/__tests__/interceptor.test.ts +0 -2
  251. package/src/core/constraints/agent-prompt-renderer.ts +1 -1
  252. package/src/core/constraints/capabilities-parser.ts +95 -2
  253. package/src/core/constraints/checker.ts +8 -53
  254. package/src/core/constraints/definitions.ts +0 -8
  255. package/src/core/constraints/doc-freshness/runner.ts +1 -2
  256. package/src/core/constraints/index.ts +1 -2
  257. package/src/core/constraints/interceptor.ts +1 -6
  258. package/src/core/effective-constraints.ts +0 -1
  259. package/src/core/project-config-loader.ts +1 -7
  260. package/src/dashboard/stats.ts +2 -2
  261. package/src/dashboard/types.ts +2 -2
  262. package/src/failure/constraint-handler.ts +0 -2
  263. package/src/gates/CONTEXT.md +16 -13
  264. package/src/gates/__tests__/checker-gate.test.ts +45 -0
  265. package/src/gates/__tests__/contract.test.ts +73 -0
  266. package/src/gates/__tests__/effective-gates.test.ts +82 -0
  267. package/src/gates/__tests__/gate-interface.test.ts +202 -0
  268. package/src/gates/__tests__/registry.test.ts +87 -0
  269. package/src/gates/__tests__/runner.test.ts +81 -0
  270. package/src/gates/acceptance.ts +24 -1
  271. package/src/gates/checker-gate.ts +54 -0
  272. package/src/gates/command.ts +13 -2
  273. package/src/gates/contract.ts +12 -2
  274. package/src/gates/decision.ts +27 -0
  275. package/src/gates/definitions.ts +207 -0
  276. package/src/gates/effective-gates.ts +106 -0
  277. package/src/gates/index.ts +38 -0
  278. package/src/gates/performance.ts +12 -2
  279. package/src/gates/registry.ts +107 -0
  280. package/src/gates/review.ts +12 -2
  281. package/src/gates/runner.ts +57 -0
  282. package/src/gates/security.ts +12 -2
  283. package/src/gates/types.ts +48 -1
  284. package/src/hooks/CONTEXT.md +12 -2
  285. package/src/hooks/__tests__/bootstrap.test.ts +0 -1
  286. package/src/hooks/__tests__/config.test.ts +19 -0
  287. package/src/hooks/__tests__/pipeline.test.ts +79 -0
  288. package/src/hooks/__tests__/registry.test.ts +67 -0
  289. package/src/hooks/bootstrap.ts +0 -2
  290. package/src/hooks/config.ts +29 -0
  291. package/src/hooks/index.ts +2 -1
  292. package/src/hooks/registry.ts +60 -1
  293. package/src/hooks/types.ts +21 -0
  294. package/src/index.ts +11 -21
  295. package/src/knowledge/import.ts +3 -3
  296. package/src/knowledge/ingest.ts +4 -4
  297. package/src/knowledge/lifecycle-hooks.ts +3 -3
  298. package/src/knowledge/types.ts +5 -8
  299. package/src/monitoring/constraint-doctor.ts +7 -106
  300. package/src/presets/__tests__/standard.test.ts +0 -2
  301. package/src/presets/standard.ts +1 -2
  302. package/src/pretool-use-hook.ts +68 -0
  303. package/src/spec/__tests__/annotation-checker.test.ts +9 -3
  304. package/src/spec/annotation-checker.ts +7 -29
  305. package/src/tools/CONTEXT.md +7 -14
  306. package/src/tools/index.ts +0 -4
  307. package/src/types/constraint.ts +1 -14
  308. package/src/types/project-config.ts +0 -3
  309. package/src/utils/file-walk.ts +2 -2
  310. package/dist/architecture/constraint-engine.d.ts +0 -67
  311. package/dist/architecture/constraint-engine.d.ts.map +0 -1
  312. package/dist/architecture/constraint-engine.js +0 -295
  313. package/dist/architecture/constraint-engine.js.map +0 -1
  314. package/dist/architecture/cross-project-checker.d.ts +0 -54
  315. package/dist/architecture/cross-project-checker.d.ts.map +0 -1
  316. package/dist/architecture/cross-project-checker.js +0 -467
  317. package/dist/architecture/cross-project-checker.js.map +0 -1
  318. package/dist/cli/commands/index.d.ts +0 -30
  319. package/dist/cli/commands/index.d.ts.map +0 -1
  320. package/dist/cli/commands/index.js +0 -91
  321. package/dist/cli/commands/index.js.map +0 -1
  322. package/dist/context/file-budget.d.ts +0 -40
  323. package/dist/context/file-budget.d.ts.map +0 -1
  324. package/dist/context/file-budget.js +0 -147
  325. package/dist/context/file-budget.js.map +0 -1
  326. package/dist/context/progressive-loader.d.ts +0 -109
  327. package/dist/context/progressive-loader.d.ts.map +0 -1
  328. package/dist/context/progressive-loader.js +0 -166
  329. package/dist/context/progressive-loader.js.map +0 -1
  330. package/dist/context/token-pipeline.d.ts +0 -55
  331. package/dist/context/token-pipeline.d.ts.map +0 -1
  332. package/dist/context/token-pipeline.js +0 -220
  333. package/dist/context/token-pipeline.js.map +0 -1
  334. package/dist/context/tool-output-budget.d.ts +0 -59
  335. package/dist/context/tool-output-budget.d.ts.map +0 -1
  336. package/dist/context/tool-output-budget.js +0 -177
  337. package/dist/context/tool-output-budget.js.map +0 -1
  338. package/dist/core/constraints/default-executors.d.ts +0 -10
  339. package/dist/core/constraints/default-executors.d.ts.map +0 -1
  340. package/dist/core/constraints/default-executors.js +0 -120
  341. package/dist/core/constraints/default-executors.js.map +0 -1
  342. package/dist/llm/adapter.d.ts +0 -36
  343. package/dist/llm/adapter.d.ts.map +0 -1
  344. package/dist/llm/adapter.js +0 -118
  345. package/dist/llm/adapter.js.map +0 -1
  346. package/dist/llm/index.d.ts +0 -3
  347. package/dist/llm/index.d.ts.map +0 -1
  348. package/dist/llm/index.js +0 -19
  349. package/dist/llm/index.js.map +0 -1
  350. package/dist/llm/types.d.ts +0 -62
  351. package/dist/llm/types.d.ts.map +0 -1
  352. package/dist/llm/types.js +0 -8
  353. package/dist/llm/types.js.map +0 -1
  354. package/dist/tools/core/index.d.ts +0 -13
  355. package/dist/tools/core/index.d.ts.map +0 -1
  356. package/dist/tools/core/index.js +0 -198
  357. package/dist/tools/core/index.js.map +0 -1
  358. package/dist/tools/loader.d.ts +0 -21
  359. package/dist/tools/loader.d.ts.map +0 -1
  360. package/dist/tools/loader.js +0 -199
  361. package/dist/tools/loader.js.map +0 -1
  362. package/dist/tools/registry.d.ts +0 -59
  363. package/dist/tools/registry.d.ts.map +0 -1
  364. package/dist/tools/registry.js +0 -115
  365. package/dist/tools/registry.js.map +0 -1
  366. package/dist/tools/types.d.ts +0 -38
  367. package/dist/tools/types.d.ts.map +0 -1
  368. package/dist/tools/types.js +0 -6
  369. package/dist/tools/types.js.map +0 -1
  370. package/src/__tests__/architecture-engine.test.ts +0 -619
  371. package/src/__tests__/context/progressive-loader.test.ts +0 -131
  372. package/src/__tests__/cross-project-checker.test.ts +0 -318
  373. package/src/architecture/CONTEXT.md +0 -22
  374. package/src/architecture/constraint-engine.ts +0 -351
  375. package/src/architecture/cross-project-checker.ts +0 -545
  376. package/src/cli/commands/index.ts +0 -30
  377. package/src/context/__tests__/file-budget.test.ts +0 -142
  378. package/src/context/__tests__/progressive-loader.test.ts +0 -264
  379. package/src/context/__tests__/token-pipeline.test.ts +0 -178
  380. package/src/context/__tests__/tool-output-budget.test.ts +0 -95
  381. package/src/context/file-budget.ts +0 -142
  382. package/src/context/progressive-loader.ts +0 -260
  383. package/src/context/token-pipeline.ts +0 -265
  384. package/src/context/tool-output-budget.ts +0 -178
  385. package/src/core/constraints/__tests__/default-executors.test.ts +0 -57
  386. package/src/core/constraints/default-executors.ts +0 -92
  387. package/src/llm/CONTEXT.md +0 -21
  388. package/src/llm/__tests__/adapter.test.ts +0 -172
  389. package/src/llm/adapter.ts +0 -149
  390. package/src/llm/index.ts +0 -2
  391. package/src/llm/types.ts +0 -81
  392. package/src/tools/__tests__/loader.test.ts +0 -252
  393. package/src/tools/__tests__/registry.test.ts +0 -157
  394. package/src/tools/core/__tests__/core.test.ts +0 -122
  395. package/src/tools/core/index.ts +0 -201
  396. package/src/tools/loader.ts +0 -216
  397. package/src/tools/registry.ts +0 -128
  398. package/src/tools/types.ts +0 -46
@@ -1,142 +0,0 @@
1
- /**
2
- * 文件读取预算
3
- *
4
- * 按行数、字节数、Token 数三重限制读取文件
5
- * 超限时生成 continuationHint 提示 offset
6
- */
7
-
8
- import * as fs from 'fs';
9
- import { TokenEstimator } from './token-budget';
10
- import type { FileBudgetConfig } from './types';
11
- import { DEFAULT_FILE_BUDGET } from './types';
12
-
13
- export interface FileCheckResult {
14
- allowed: boolean;
15
- reason?: string;
16
- lineCount?: number;
17
- byteCount?: number;
18
- }
19
-
20
- export interface FileReadResult {
21
- content: string;
22
- truncated: boolean;
23
- linesRead: number;
24
- bytesRead: number;
25
- tokensEstimate: number;
26
- continuationHint?: string;
27
- }
28
-
29
- export class FileBudget {
30
- private config: FileBudgetConfig;
31
-
32
- constructor(config?: Partial<FileBudgetConfig>) {
33
- this.config = { ...DEFAULT_FILE_BUDGET, ...config };
34
- }
35
-
36
- /**
37
- * 检查文件是否在预算内(stat 检查)
38
- */
39
- checkFile(filePath: string): FileCheckResult {
40
- try {
41
- const stat = fs.statSync(filePath);
42
-
43
- if (stat.size > this.config.maxBytes) {
44
- return {
45
- allowed: false,
46
- reason: `文件大小 ${(stat.size / 1024).toFixed(1)}KB 超过限制 ${(this.config.maxBytes / 1024).toFixed(1)}KB`,
47
- byteCount: stat.size,
48
- };
49
- }
50
-
51
- return { allowed: true, byteCount: stat.size };
52
- } catch (error) {
53
- return {
54
- allowed: false,
55
- reason: `无法读取文件: ${(error as Error).message}`,
56
- };
57
- }
58
- }
59
-
60
- /**
61
- * 按预算读取文件
62
- *
63
- * 三重限制:行数 → 字节数 → Token 数
64
- */
65
- readWithBudget(filePath: string, config?: Partial<FileBudgetConfig>): FileReadResult {
66
- const effectiveConfig = { ...this.config, ...config };
67
-
68
- try {
69
- const content = fs.readFileSync(filePath, 'utf-8');
70
- const lines = content.split('\n');
71
-
72
- let truncated = false;
73
- let selectedLines = lines;
74
- let continuationHint: string | undefined;
75
-
76
- // 限制 1: 行数
77
- if (lines.length > effectiveConfig.maxLines) {
78
- selectedLines = lines.slice(0, effectiveConfig.maxLines);
79
- truncated = true;
80
-
81
- if (effectiveConfig.continuationHint) {
82
- continuationHint = `文件被截断。已读取 ${effectiveConfig.maxLines} 行,共 ${lines.length} 行。使用 offset=${effectiveConfig.maxLines} 继续读取。`;
83
- }
84
- }
85
-
86
- let result = selectedLines.join('\n');
87
-
88
- // 限制 2: 字节数
89
- const byteCount = Buffer.byteLength(result, 'utf-8');
90
- if (byteCount > effectiveConfig.maxBytes) {
91
- const encoder = new TextEncoder();
92
- const bytes = encoder.encode(result);
93
- const truncatedBytes = bytes.slice(0, effectiveConfig.maxBytes);
94
- result = new TextDecoder().decode(truncatedBytes);
95
- truncated = true;
96
-
97
- if (!continuationHint && effectiveConfig.continuationHint) {
98
- continuationHint = `文件内容被截断。已读取 ${effectiveConfig.maxBytes} 字节。`;
99
- }
100
- }
101
-
102
- // 限制 3: Token 数
103
- const tokensEstimate = TokenEstimator.estimateText(result);
104
- if (tokensEstimate > effectiveConfig.maxTokenEstimate) {
105
- // 按比例截断
106
- const ratio = effectiveConfig.maxTokenEstimate / tokensEstimate;
107
- const charLimit = Math.floor(result.length * ratio);
108
- result = result.slice(0, charLimit);
109
- truncated = true;
110
-
111
- if (!continuationHint && effectiveConfig.continuationHint) {
112
- continuationHint = `文件内容被截断。已读取约 ${effectiveConfig.maxTokenEstimate} tokens。`;
113
- }
114
- }
115
-
116
- return {
117
- content: result,
118
- truncated,
119
- linesRead: selectedLines.length,
120
- bytesRead: Buffer.byteLength(result, 'utf-8'),
121
- tokensEstimate: TokenEstimator.estimateText(result),
122
- continuationHint,
123
- };
124
- } catch (error) {
125
- return {
126
- content: '',
127
- truncated: false,
128
- linesRead: 0,
129
- bytesRead: 0,
130
- tokensEstimate: 0,
131
- continuationHint: `无法读取文件: ${(error as Error).message}`,
132
- };
133
- }
134
- }
135
-
136
- /**
137
- * 获取当前配置
138
- */
139
- getConfig(): FileBudgetConfig {
140
- return { ...this.config };
141
- }
142
- }
@@ -1,260 +0,0 @@
1
- import { delay } from '../utils/exec';
2
-
3
- /**
4
- * @spec HZ-002
5
- * @implements HZ-002-C1
6
- * @acceptance AC-001-1, AC-001-4
7
- *
8
- * Progressive Content Loader
9
- *
10
- * 通用内容分片加载能力
11
- * - 支持大数据集分片加载
12
- * - 支持 Token 预算管理
13
- * - 零业务逻辑,可被任意系统使用
14
- */
15
-
16
- export interface ChunkLoadOptions<T = any> {
17
- /** 每片大小 */
18
- chunkSize: number;
19
- /** 每片加载回调 */
20
- onChunk?: (chunk: T[], index: number) => Promise<void> | void;
21
- /** 进度回调 (loaded, total) */
22
- onProgress?: (loaded: number, total: number) => void;
23
- /** 是否并行加载 */
24
- parallel?: boolean;
25
- /** 延迟(毫秒),用于节流 */
26
- delay?: number;
27
- }
28
-
29
- export interface TokenBudgetOptions<T = any> {
30
- /** Token 预算 */
31
- budget: number;
32
- /** Token 估算函数 */
33
- estimator: (item: T) => number;
34
- /** 预算超限策略 */
35
- onBudgetExceeded?: 'truncate' | 'error' | 'skip';
36
- /** 最小保留项数(即使超预算) */
37
- minItems?: number;
38
- }
39
-
40
- export interface LoadResult<T> {
41
- /** 加载的项 */
42
- items: T[];
43
- /** 实际消耗的 Token */
44
- tokensUsed: number;
45
- /** 是否被截断 */
46
- truncated: boolean;
47
- /** 跳过的项数 */
48
- skipped: number;
49
- }
50
-
51
- /**
52
- * 渐进式内容加载器
53
- *
54
- * 提供通用的内容分片加载和 Token 预算管理能力
55
- */
56
- export class ProgressiveLoader {
57
- /**
58
- * 分片加载
59
- *
60
- * 将大数据集分片加载,避免一次性加载全部内容
61
- *
62
- * @example
63
- * ```typescript
64
- * const loader = new ProgressiveLoader();
65
- * const largeData = Array.from({ length: 1000 }, (_, i) => ({ id: i }));
66
- *
67
- * await loader.loadInChunks(largeData, {
68
- * chunkSize: 100,
69
- * onChunk: async (chunk, index) => {
70
- * console.log(`Loaded chunk ${index}: ${chunk.length} items`);
71
- * },
72
- * onProgress: (loaded, total) => {
73
- * console.log(`Progress: ${loaded}/${total}`);
74
- * }
75
- * });
76
- * ```
77
- */
78
- async loadInChunks<T>(
79
- items: T[],
80
- options: ChunkLoadOptions<T>
81
- ): Promise<void> {
82
- const { chunkSize, onChunk, onProgress, parallel = false, delay: throttleDelay = 0 } = options;
83
- const total = items.length;
84
- const chunks: T[][] = [];
85
-
86
- // 分片
87
- for (let i = 0; i < total; i += chunkSize) {
88
- chunks.push(items.slice(i, i + chunkSize));
89
- }
90
-
91
- // 加载
92
- if (parallel) {
93
- // 并行加载
94
- await Promise.all(
95
- chunks.map(async (chunk, index) => {
96
- if (throttleDelay > 0) {
97
- await delay(throttleDelay * index);
98
- }
99
- await this.processChunk(chunk, index, onChunk, onProgress, total);
100
- })
101
- );
102
- } else {
103
- // 串行加载
104
- for (let i = 0; i < chunks.length; i++) {
105
- if (throttleDelay > 0 && i > 0) {
106
- await delay(throttleDelay);
107
- }
108
- await this.processChunk(chunks[i], i, onChunk, onProgress, total);
109
- }
110
- }
111
- }
112
-
113
- /**
114
- * Token 预算加载
115
- *
116
- * 在 Token 预算范围内加载内容,超预算时按策略处理
117
- *
118
- * @example
119
- * ```typescript
120
- * const loader = new ProgressiveLoader();
121
- * const items = [
122
- * { content: 'short text' },
123
- * { content: 'long text '.repeat(100) }
124
- * ];
125
- *
126
- * const result = await loader.loadWithBudget(items, {
127
- * budget: 1000,
128
- * estimator: (item) => item.content.length,
129
- * onBudgetExceeded: 'truncate'
130
- * });
131
- *
132
- * console.log(`Loaded ${result.items.length} items, used ${result.tokensUsed} tokens`);
133
- * ```
134
- */
135
- async loadWithBudget<T>(
136
- items: T[],
137
- options: TokenBudgetOptions<T>
138
- ): Promise<LoadResult<T>> {
139
- const {
140
- budget,
141
- estimator,
142
- onBudgetExceeded = 'truncate',
143
- minItems = 1
144
- } = options;
145
-
146
- const result: LoadResult<T> = {
147
- items: [],
148
- tokensUsed: 0,
149
- truncated: false,
150
- skipped: 0
151
- };
152
-
153
- let currentBudget = budget;
154
-
155
- for (const item of items) {
156
- const itemTokens = estimator(item);
157
-
158
- // 检查预算
159
- if (itemTokens > currentBudget) {
160
- // 预算超限
161
- if (result.items.length >= minItems) {
162
- // 已达到最小项数,按策略处理
163
- switch (onBudgetExceeded) {
164
- case 'truncate':
165
- result.truncated = true;
166
- return result;
167
- case 'error':
168
- throw new Error(
169
- `Token budget exceeded: need ${itemTokens}, remaining ${currentBudget}`
170
- );
171
- case 'skip':
172
- result.skipped++;
173
- continue;
174
- }
175
- }
176
- // 未达到最小项数,强制添加(可能超预算)
177
- }
178
-
179
- // 添加项
180
- result.items.push(item);
181
- result.tokensUsed += itemTokens;
182
- currentBudget -= itemTokens;
183
- }
184
-
185
- return result;
186
- }
187
-
188
- /**
189
- * 创建流式加载器
190
- *
191
- * 支持大文件/大内容的流式分片加载
192
- */
193
- async *createStream<T>(
194
- source: AsyncIterable<T>,
195
- chunkSize: number
196
- ): AsyncIterable<T[]> {
197
- let chunk: T[] = [];
198
-
199
- for await (const item of source) {
200
- chunk.push(item);
201
-
202
- if (chunk.length >= chunkSize) {
203
- yield chunk;
204
- chunk = [];
205
- }
206
- }
207
-
208
- // yield remaining items
209
- if (chunk.length > 0) {
210
- yield chunk;
211
- }
212
- }
213
-
214
- /**
215
- * 批量处理(带并发控制)
216
- */
217
- async processBatch<T, R>(
218
- items: T[],
219
- processor: (item: T) => Promise<R>,
220
- concurrency: number = 5
221
- ): Promise<R[]> {
222
- const results = new Array<R>(items.length);
223
- let nextIndex = 0;
224
-
225
- const worker = async (): Promise<void> => {
226
- while (nextIndex < items.length) {
227
- const index = nextIndex++;
228
- results[index] = await processor(items[index]);
229
- }
230
- };
231
-
232
- const workers = Array.from(
233
- { length: Math.min(concurrency, items.length) },
234
- () => worker()
235
- );
236
- await Promise.all(workers);
237
- return results;
238
- }
239
-
240
- private async processChunk<T>(
241
- chunk: T[],
242
- index: number,
243
- onChunk: ((chunk: T[], index: number) => Promise<void> | void) | undefined,
244
- onProgress: ((loaded: number, total: number) => void) | undefined,
245
- total: number
246
- ): Promise<void> {
247
- if (onChunk) {
248
- await onChunk(chunk, index);
249
- }
250
-
251
- if (onProgress) {
252
- const loaded = Math.min((index + 1) * chunk.length, total);
253
- onProgress(loaded, total);
254
- }
255
- }
256
-
257
- }
258
-
259
- // 默认实例
260
- export const progressiveLoader = new ProgressiveLoader();
@@ -1,265 +0,0 @@
1
- /**
2
- * Token 流水线
3
- *
4
- * 五步:收集 → 排序 → 压缩 → 预算 → 组装
5
- * 每次 LLM 调用前运行
6
- */
7
-
8
- import { TokenEstimator, TokenBudget } from './token-budget';
9
- import type {
10
- ContextSource,
11
- TokenBudgetAllocation,
12
- PipelineInput,
13
- PipelineOutput,
14
- ContextUsageSnapshot,
15
- } from './types';
16
-
17
- interface CollectedGroup {
18
- priority: number;
19
- sources: ContextSource[];
20
- }
21
-
22
- export class TokenPipeline {
23
- /**
24
- * 完整流水线:收集 → 排序 → 压缩 → 预算 → 组装
25
- */
26
- run(input: PipelineInput): PipelineOutput {
27
- const { sources, budget } = input;
28
-
29
- // Step 1: 收集 — 按 priority 分组
30
- const collected = this.collect(sources);
31
-
32
- // Step 2: 排序 — 按 P1→P6 排序
33
- const sorted = this.sort(collected);
34
-
35
- // Step 3: 压缩 — 对 P3-P5 应用预算裁剪
36
- const { compressed, dropped } = this.compress(sorted, budget);
37
-
38
- // Step 4: 预算 — 按分配裁剪
39
- const budgeted = this.applyBudget(compressed, budget);
40
-
41
- // Step 5: 组装 — 拼装最终 prompt
42
- const prompt = this.assemble(budgeted);
43
-
44
- // 生成快照
45
- const snapshot = this.buildSnapshot(budgeted, dropped);
46
-
47
- return { prompt, snapshot, dropped };
48
- }
49
-
50
- /**
51
- * Step 1: 收集 — 从 sources 按 priority 分组
52
- */
53
- collect(sources: ContextSource[]): CollectedGroup[] {
54
- const groups = new Map<number, ContextSource[]>();
55
-
56
- for (const source of sources) {
57
- const existing = groups.get(source.priority) || [];
58
- existing.push(source);
59
- groups.set(source.priority, existing);
60
- }
61
-
62
- return Array.from(groups.entries())
63
- .map(([priority, sources]) => ({ priority, sources }))
64
- .sort((a, b) => a.priority - b.priority);
65
- }
66
-
67
- /**
68
- * Step 2: 排序 — 按 P1→P6,组内保持原序
69
- */
70
- sort(groups: CollectedGroup[]): ContextSource[] {
71
- const sorted: ContextSource[] = [];
72
-
73
- for (const group of groups) {
74
- sorted.push(...group.sources);
75
- }
76
-
77
- return sorted;
78
- }
79
-
80
- /**
81
- * Step 3: 压缩 — 对 P3-P5 应用 token 预算裁剪
82
- *
83
- * P1(系统提示词)和 P6(用户消息)不压缩
84
- * P2(工具定义)按需懒加载,这里不处理
85
- */
86
- compress(sorted: ContextSource[], budget: TokenBudgetAllocation): {
87
- compressed: ContextSource[];
88
- dropped: Array<{ type: string; id: string; reason: string }>;
89
- } {
90
- const compressed: ContextSource[] = [];
91
- const dropped: Array<{ type: string; id: string; reason: string }> = [];
92
-
93
- // 各段预算
94
- const budgetMap: Record<number, number> = {
95
- 1: budget.systemPrompt,
96
- 2: budget.toolDefinitions,
97
- 3: budget.knowledge,
98
- 4: budget.notes,
99
- 5: budget.history,
100
- 6: Infinity, // 用户消息不限
101
- };
102
-
103
- // 按优先级分组处理
104
- const byPriority = new Map<number, ContextSource[]>();
105
- for (const item of sorted) {
106
- const existing = byPriority.get(item.priority) || [];
107
- existing.push(item);
108
- byPriority.set(item.priority, existing);
109
- }
110
-
111
- for (const [priority, items] of byPriority) {
112
- const sectionBudget = budgetMap[priority] || budget.history;
113
-
114
- if (priority === 1 || priority === 6) {
115
- // P1/P6 不压缩
116
- compressed.push(...items);
117
- continue;
118
- }
119
-
120
- // 按 token 预算裁剪
121
- let usedTokens = 0;
122
- for (const item of items) {
123
- const tokens = TokenEstimator.estimateText(item.content);
124
-
125
- if (usedTokens + tokens <= sectionBudget) {
126
- compressed.push(item);
127
- usedTokens += tokens;
128
- } else {
129
- // 尝试截断
130
- const remaining = sectionBudget - usedTokens;
131
- if (remaining > 50) {
132
- const ratio = remaining / tokens;
133
- const truncatedContent = item.content.slice(0, Math.floor(item.content.length * ratio));
134
- compressed.push({ ...item, content: truncatedContent });
135
- dropped.push({
136
- type: item.type,
137
- id: item.id,
138
- reason: `截断: ${tokens} → ${Math.floor(tokens * ratio)} tokens`,
139
- });
140
- } else {
141
- dropped.push({
142
- type: item.type,
143
- id: item.id,
144
- reason: `超出预算: 需要 ${tokens} tokens,剩余 ${remaining}`,
145
- });
146
- }
147
- usedTokens += tokens; // 仍然计入已用
148
- }
149
- }
150
- }
151
-
152
- return { compressed, dropped };
153
- }
154
-
155
- /**
156
- * Step 4: 预算 — 按 TokenBudgetAllocation 分配各段
157
- */
158
- applyBudget(compressed: ContextSource[], budget: TokenBudgetAllocation): ContextSource[] {
159
- const tokenBudget = new TokenBudget(budget.total);
160
- const result: ContextSource[] = [];
161
-
162
- for (const item of compressed) {
163
- const tokens = TokenEstimator.estimateText(item.content);
164
-
165
- if (tokenBudget.canAfford(tokens)) {
166
- tokenBudget.consume(tokens);
167
- result.push(item);
168
- } else if (item.priority === 1 || item.priority === 6) {
169
- // P1/P6 强制保留
170
- tokenBudget.forceConsume(tokens);
171
- result.push(item);
172
- }
173
- // 其他优先级的超预算项被丢弃
174
- }
175
-
176
- return result;
177
- }
178
-
179
- /**
180
- * Step 5: 组装 — 拼装最终 prompt
181
- *
182
- * P1 开头 + P6 结尾,中间 P2-P5
183
- */
184
- assemble(budgeted: ContextSource[]): string {
185
- const sections: Record<number, string[]> = {
186
- 1: [], 2: [], 3: [], 4: [], 5: [], 6: [],
187
- };
188
-
189
- for (const item of budgeted) {
190
- sections[item.priority] = sections[item.priority] || [];
191
- sections[item.priority].push(item.content);
192
- }
193
-
194
- const parts: string[] = [];
195
-
196
- // P1: 系统提示词(开头)
197
- if (sections[1].length > 0) {
198
- parts.push(sections[1].join('\n'));
199
- }
200
-
201
- // P2-P5: 中间部分
202
- for (const priority of [2, 3, 4, 5]) {
203
- if (sections[priority].length > 0) {
204
- parts.push(sections[priority].join('\n'));
205
- }
206
- }
207
-
208
- // P6: 用户消息(结尾)
209
- if (sections[6].length > 0) {
210
- parts.push(sections[6].join('\n'));
211
- }
212
-
213
- return parts.join('\n\n');
214
- }
215
-
216
- /**
217
- * 构建上下文使用快照
218
- */
219
- private buildSnapshot(budgeted: ContextSource[], dropped: Array<{ type: string; id: string; reason: string }>): ContextUsageSnapshot {
220
- const breakdown = {
221
- systemPrompt: 0,
222
- messages: 0,
223
- toolOutputs: 0,
224
- knowledge: 0,
225
- other: 0,
226
- };
227
-
228
- for (const item of budgeted) {
229
- const tokens = TokenEstimator.estimateText(item.content);
230
-
231
- switch (item.type) {
232
- case 'system_prompt':
233
- breakdown.systemPrompt += tokens;
234
- break;
235
- case 'user_message':
236
- case 'session_event':
237
- breakdown.messages += tokens;
238
- break;
239
- case 'tool_output':
240
- case 'tool_definition':
241
- breakdown.toolOutputs += tokens;
242
- break;
243
- case 'knowledge':
244
- breakdown.knowledge += tokens;
245
- break;
246
- default:
247
- breakdown.other += tokens;
248
- }
249
- }
250
-
251
- return {
252
- timestamp: new Date().toISOString(),
253
- totalTokens: breakdown.systemPrompt + breakdown.messages + breakdown.toolOutputs + breakdown.knowledge + breakdown.other,
254
- breakdown,
255
- truncatedItems: dropped.filter(d => d.reason.startsWith('截断')).map(d => ({
256
- type: d.type,
257
- id: d.id,
258
- originalTokens: 0,
259
- keptTokens: 0,
260
- })),
261
- offloadedItems: [],
262
- compactionTriggered: false,
263
- };
264
- }
265
- }