@chemx/starter-kit 26.10.8-344 → 26.10.10-75

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 (805) hide show
  1. package/AGENTS.md +135 -32
  2. package/README.md +253 -199
  3. package/blueprints/atoms/a-button.svelte +11 -9
  4. package/blueprints/atoms/a-button.vue +2 -1
  5. package/blueprints/molecule-capsule/m-chemx-badge/m-chemx-badge.svelte +8 -4
  6. package/blueprints/molecule-capsule/m-chemx-badge/m-chemx-badge.tsx +8 -4
  7. package/blueprints/molecule-capsule/m-chemx-badge/m-chemx-badge.vue +8 -4
  8. package/blueprints/molecule-capsule/m-sample-card.svelte +2 -1
  9. package/blueprints/molecule-capsule/m-sample-card.tsx +2 -1
  10. package/blueprints/molecule-capsule/m-sample-card.vue +4 -2
  11. package/blueprints/workflows/chemx-audit.yml +15 -46
  12. package/cli/agent-json.js +40 -0
  13. package/cli/apply-edits.js +195 -0
  14. package/cli/audit/ai-slop-detector.js +62 -35
  15. package/cli/audit/ast-passes.js +52 -0
  16. package/cli/audit/ast-visitors.js +142 -83
  17. package/cli/audit/audit-plain.js +26 -0
  18. package/cli/audit/audit-summary.js +16 -3
  19. package/cli/audit/autofix-content.js +122 -0
  20. package/cli/audit/autofix.js +74 -159
  21. package/cli/audit/budget-rules.js +84 -0
  22. package/cli/audit/catch-predicates.js +51 -0
  23. package/cli/audit/chemx-dir.js +76 -0
  24. package/cli/audit/clone-detector.js +4 -2
  25. package/cli/audit/comment-regions.js +83 -0
  26. package/cli/audit/coverage.js +48 -0
  27. package/cli/audit/csharp-analyzer.js +47 -22
  28. package/cli/audit/discussion-store.js +9 -4
  29. package/cli/audit/extended-text-patterns.js +104 -54
  30. package/cli/audit/extended-visitors.js +26 -12
  31. package/cli/audit/feed.d.ts +77 -0
  32. package/cli/audit/feed.js +146 -0
  33. package/cli/audit/gate-delta.js +91 -0
  34. package/cli/audit/gate-verdict.js +25 -3
  35. package/cli/audit/history.d.ts +14 -2
  36. package/cli/audit/history.js +89 -101
  37. package/cli/audit/hook-shape-validator.js +18 -9
  38. package/cli/audit/lexicon-predicates.js +125 -0
  39. package/cli/audit/lifecycle-predicates.js +106 -0
  40. package/cli/audit/line-budgets.js +154 -0
  41. package/cli/audit/metrics.js +56 -37
  42. package/cli/audit/mutable-ref-predicate.js +54 -0
  43. package/cli/audit/parseable-code.js +11 -0
  44. package/cli/audit/pattern-detector.js +56 -28
  45. package/cli/audit/project-figures.js +28 -0
  46. package/cli/audit/prompt-rule-lines.js +46 -0
  47. package/cli/audit/prompts.js +74 -46
  48. package/cli/audit/prop-surface.js +74 -0
  49. package/cli/audit/ratchet.js +112 -23
  50. package/cli/audit/render-depth.js +79 -0
  51. package/cli/audit/reporter-banner.js +7 -4
  52. package/cli/audit/reporter-grades.js +52 -34
  53. package/cli/audit/reporter-grouping.js +10 -5
  54. package/cli/audit/reporter-markdown.js +16 -8
  55. package/cli/audit/reporter-sections.js +31 -16
  56. package/cli/audit/reporter-summary.js +28 -16
  57. package/cli/audit/reporter-utils.js +54 -30
  58. package/cli/audit/roadmap.js +20 -15
  59. package/cli/audit/rule-overrides.js +78 -0
  60. package/cli/audit/rule-pillars.js +43 -0
  61. package/cli/audit/rule-revisions.js +42 -0
  62. package/cli/audit/rules-helpers.js +13 -63
  63. package/cli/audit/rules-predicates.d.ts +1 -0
  64. package/cli/audit/rules-predicates.js +84 -64
  65. package/cli/audit/rules-registry.js +94 -10
  66. package/cli/audit/rules.js +92 -171
  67. package/cli/audit/shallow-catch-csharp.js +49 -0
  68. package/cli/audit/shallow-catch-escalation.js +157 -0
  69. package/cli/audit/shallow-catch-reads.js +116 -0
  70. package/cli/audit/social-gh.js +18 -9
  71. package/cli/audit/social-git.js +82 -40
  72. package/cli/audit/social-http.js +17 -9
  73. package/cli/audit/social-publisher.js +14 -7
  74. package/cli/audit/social.js +39 -30
  75. package/cli/audit/staged-delta.js +67 -0
  76. package/cli/audit/status-file.js +67 -0
  77. package/cli/audit/structural-weight-evaluator.js +17 -29
  78. package/cli/audit/structural-weight.js +30 -13
  79. package/cli/audit/suppressions.js +130 -0
  80. package/cli/audit/template-rules.js +82 -0
  81. package/cli/audit/types.d.ts +24 -1
  82. package/cli/audit-engine.js +128 -0
  83. package/cli/audit-preflight-git.js +15 -1
  84. package/cli/audit-preflight.js +6 -4
  85. package/cli/audit-scan.js +180 -0
  86. package/cli/audit-scope.js +31 -14
  87. package/cli/audit.js +6 -201
  88. package/cli/babel-lazy.js +41 -0
  89. package/cli/badge.js +9 -6
  90. package/cli/banner.js +37 -0
  91. package/cli/build/child-registry.js +57 -0
  92. package/cli/build/executor.js +122 -48
  93. package/cli/build.js +75 -25
  94. package/cli/cli-args.js +107 -0
  95. package/cli/columnar.js +6 -3
  96. package/cli/commands/cmd-audit-each.js +164 -0
  97. package/cli/commands/cmd-audit-feed.js +78 -0
  98. package/cli/commands/cmd-audit.js +136 -57
  99. package/cli/commands/cmd-batch.js +60 -0
  100. package/cli/commands/cmd-check.js +74 -0
  101. package/cli/commands/cmd-project.js +18 -9
  102. package/cli/commands/cmd-router.js +148 -32
  103. package/cli/commands/cmd-show.js +56 -0
  104. package/cli/commands/cmd-staged-delta.js +27 -0
  105. package/cli/commands/cmd-wrappers-files.js +77 -0
  106. package/cli/commands/cmd-wrappers-git.js +122 -0
  107. package/cli/commands/cmd-wrappers-json.js +101 -0
  108. package/cli/commands/cmd-wrappers.js +7 -322
  109. package/cli/commands/unknown-flags.js +228 -0
  110. package/cli/commands-schema-badge.js +73 -0
  111. package/cli/commands-schema-commit.js +21 -0
  112. package/cli/commands-schema-edit.js +106 -0
  113. package/cli/commands-schema-host.js +65 -0
  114. package/cli/commands-schema-ops.js +127 -0
  115. package/cli/commands-schema-patterns.js +69 -0
  116. package/cli/commands-schema-report.js +18 -0
  117. package/cli/commands-schema-search.js +121 -0
  118. package/cli/commands-schema-setup.js +30 -0
  119. package/cli/commands-schema-verify.js +89 -0
  120. package/cli/commands-schema-wrappers.js +131 -0
  121. package/cli/commands-schema.js +26 -408
  122. package/cli/comment-ranges.js +108 -0
  123. package/cli/commit/commit-args.js +73 -0
  124. package/cli/commit/commit-cli.js +25 -0
  125. package/cli/commit/commit-facts.js +49 -0
  126. package/cli/commit/commit-git.js +98 -0
  127. package/cli/commit/commit-index.js +35 -0
  128. package/cli/commit/commit-message.js +52 -0
  129. package/cli/commit/commit-record.js +68 -0
  130. package/cli/commit/commit-run.js +160 -0
  131. package/cli/commit/commit-validate.js +62 -0
  132. package/cli/config/index.js +54 -8
  133. package/cli/config/loader.js +77 -8
  134. package/cli/config/profiles.js +7 -0
  135. package/cli/conflicts-cli.js +118 -0
  136. package/cli/conflicts.js +104 -0
  137. package/cli/create.js +11 -6
  138. package/cli/db-project-stamp.js +124 -0
  139. package/cli/docs-check/command-tree.js +27 -0
  140. package/cli/docs-check/extract.js +151 -0
  141. package/cli/docs-check/resolve.js +85 -0
  142. package/cli/docs-check/run.js +88 -0
  143. package/cli/doctor/check-env.js +43 -0
  144. package/cli/doctor/check-host.js +115 -0
  145. package/cli/doctor/check-index.js +93 -0
  146. package/cli/doctor/check-mcp.js +78 -0
  147. package/cli/doctor/doctor-cli.js +60 -0
  148. package/cli/doctor/kit-locate.js +40 -0
  149. package/cli/doctor/proc-scan.js +66 -0
  150. package/cli/edit-atomic.js +75 -0
  151. package/cli/edit-diff.js +98 -0
  152. package/cli/edit-guardrails.js +77 -0
  153. package/cli/edit-locks.js +128 -0
  154. package/cli/embeddings/vectorizer.js +9 -5
  155. package/cli/errors/catcher.js +45 -52
  156. package/cli/errors/formatter.js +14 -10
  157. package/cli/errors/policy.js +26 -0
  158. package/cli/errors/publisher.js +5 -1
  159. package/cli/errors/report-output.js +67 -0
  160. package/cli/errors/sanitizer.js +52 -3
  161. package/cli/errors/storage.js +17 -5
  162. package/cli/explode-importers.js +102 -0
  163. package/cli/explode-path-args.js +115 -0
  164. package/cli/explode-plan.js +153 -0
  165. package/cli/explode-prologue.js +43 -0
  166. package/cli/explode-relocate.js +73 -0
  167. package/cli/exploder.js +205 -193
  168. package/cli/forge/anchors.js +50 -0
  169. package/cli/forge/audit-forge.js +58 -0
  170. package/cli/forge/binding-walk.js +84 -0
  171. package/cli/forge/bindings.js +238 -0
  172. package/cli/forge/blueprint-cli.js +153 -0
  173. package/cli/forge/blueprint-context.js +69 -0
  174. package/cli/forge/blueprint-members.js +82 -0
  175. package/cli/forge/blueprint-store.js +106 -0
  176. package/cli/forge/blueprint-target.js +44 -0
  177. package/cli/forge/blueprint.js +276 -0
  178. package/cli/forge/body-end-cache.js +34 -0
  179. package/cli/forge/body-ends.js +86 -0
  180. package/cli/forge/canon-inline.js +342 -0
  181. package/cli/forge/canon-logic.js +106 -0
  182. package/cli/forge/canon-nodes.js +270 -0
  183. package/cli/forge/canon-print.js +120 -0
  184. package/cli/forge/canonicalize.js +49 -0
  185. package/cli/forge/conventions.js +51 -0
  186. package/cli/forge/drift.js +120 -0
  187. package/cli/forge/exclusions.js +21 -0
  188. package/cli/forge/exits.js +76 -0
  189. package/cli/forge/facets.js +86 -0
  190. package/cli/forge/file-units.js +53 -0
  191. package/cli/forge/fingerprint-file.js +52 -0
  192. package/cli/forge/fingerprint-session.js +215 -0
  193. package/cli/forge/fingerprint-sync.js +74 -0
  194. package/cli/forge/fingerprint-visitors.js +66 -0
  195. package/cli/forge/fixtures/heal/a7-dry-run.diff.txt +179 -0
  196. package/cli/forge/fixtures/heal/cli/commit/commit-facts.js.txt +49 -0
  197. package/cli/forge/fixtures/heal/cli/doctor/check-host.js.txt +117 -0
  198. package/cli/forge/fixtures/heal/cli/doctor/kit-locate.js.txt +42 -0
  199. package/cli/forge/fixtures/heal/cli/hooks/guard-paths.js.txt +80 -0
  200. package/cli/forge/fixtures/heal/cli/hooks/project-status.js.txt +62 -0
  201. package/cli/forge/fixtures/heal/cli/main.js.txt +169 -0
  202. package/cli/forge/fixtures/heal/cli/mcp/context.js.txt +81 -0
  203. package/cli/forge/fixtures/heal/cli/mcp/installer-report.js.txt +47 -0
  204. package/cli/forge/fixtures/heal/cli/path-scope.js.txt +169 -0
  205. package/cli/forge/fixtures/heal/cli/project-detector.js.txt +364 -0
  206. package/cli/forge/fixtures/heal/cli/project-markers.js.txt +42 -0
  207. package/cli/forge/fixtures/heal/cli/team/coordination-root.js.txt +161 -0
  208. package/cli/forge/fixtures/heal/cli/team/usage-reader.js.txt +109 -0
  209. package/cli/forge/fixtures/heal/cli/test-slots.js.txt +129 -0
  210. package/cli/forge/fixtures/social-gh.js.txt +131 -0
  211. package/cli/forge/fixtures/team-flags.js.txt +214 -0
  212. package/cli/forge/fold.js +199 -0
  213. package/cli/forge/forge-groups.js +200 -0
  214. package/cli/forge/forge-report.js +73 -0
  215. package/cli/forge/fuzz/binding-hook.js +36 -0
  216. package/cli/forge/fuzz/choices.js +40 -0
  217. package/cli/forge/fuzz/classes.js +41 -0
  218. package/cli/forge/fuzz/coverage.js +26 -0
  219. package/cli/forge/fuzz/gen-alias.js +61 -0
  220. package/cli/forge/fuzz/gen-control.js +73 -0
  221. package/cli/forge/fuzz/gen-kit.js +75 -0
  222. package/cli/forge/fuzz/gen-logic.js +77 -0
  223. package/cli/forge/fuzz/gen-mixed.js +204 -0
  224. package/cli/forge/fuzz/gen-modules.js +80 -0
  225. package/cli/forge/fuzz/gen-objects.js +92 -0
  226. package/cli/forge/fuzz/gen-scope.js +131 -0
  227. package/cli/forge/fuzz/gen-templates.js +87 -0
  228. package/cli/forge/fuzz/harness.js +314 -0
  229. package/cli/forge/fuzz/pair-check.js +115 -0
  230. package/cli/forge/fuzz/resolve.js +32 -0
  231. package/cli/forge/fuzz/run.js +121 -0
  232. package/cli/forge/fuzz/sandbox.js +108 -0
  233. package/cli/forge/fuzz/seeds.js +119 -0
  234. package/cli/forge/fuzz/slow-shard.js +60 -0
  235. package/cli/forge/fuzz/template-oracle.js +148 -0
  236. package/cli/forge/fuzz/transpile.js +61 -0
  237. package/cli/forge/gates.js +115 -0
  238. package/cli/forge/group-shape.js +137 -0
  239. package/cli/forge/group-store.js +160 -0
  240. package/cli/forge/group.js +280 -0
  241. package/cli/forge/gt-sandbox.js +83 -0
  242. package/cli/forge/gt-scaffold.js +110 -0
  243. package/cli/forge/hash-labels.js +117 -0
  244. package/cli/forge/hash.js +119 -0
  245. package/cli/forge/heal-apply.js +170 -0
  246. package/cli/forge/heal-cli.js +132 -0
  247. package/cli/forge/heal-leases.js +52 -0
  248. package/cli/forge/heal-locate.js +70 -0
  249. package/cli/forge/heal-match.js +208 -0
  250. package/cli/forge/heal-ops.js +197 -0
  251. package/cli/forge/heal-plan.js +143 -0
  252. package/cli/forge/heal-sandbox.js +126 -0
  253. package/cli/forge/heal-specs.js +80 -0
  254. package/cli/forge/heal-store.js +80 -0
  255. package/cli/forge/heal-text.js +60 -0
  256. package/cli/forge/heal-typecheck.js +108 -0
  257. package/cli/forge/heal-undo.js +74 -0
  258. package/cli/forge/heal-verify.js +148 -0
  259. package/cli/forge/hole-kinds.js +126 -0
  260. package/cli/forge/inline-mode.js +6 -0
  261. package/cli/forge/inline-on.setup.js +4 -0
  262. package/cli/forge/lgg-stage.js +125 -0
  263. package/cli/forge/lgg.js +197 -0
  264. package/cli/forge/library-match.js +74 -0
  265. package/cli/forge/murmur.js +86 -0
  266. package/cli/forge/naming.js +101 -0
  267. package/cli/forge/pattern-schema-ddl.js +157 -0
  268. package/cli/forge/placement.js +165 -0
  269. package/cli/forge/rank.js +174 -0
  270. package/cli/forge/refine.js +93 -0
  271. package/cli/forge/rejected-members.js +92 -0
  272. package/cli/forge/rejects.js +77 -0
  273. package/cli/forge/root-shapes.js +84 -0
  274. package/cli/forge/run-cache.js +145 -0
  275. package/cli/forge/sibling-blocks.js +41 -0
  276. package/cli/forge/siblings.js +140 -0
  277. package/cli/forge/store.js +180 -0
  278. package/cli/forge/template-normalize.js +209 -0
  279. package/cli/forge/template-roles.js +86 -0
  280. package/cli/forge/template-units.js +148 -0
  281. package/cli/forge/templates.js +42 -0
  282. package/cli/forge/unify-step.js +65 -0
  283. package/cli/forge/unit-floor.js +74 -0
  284. package/cli/forge/unit-hash.js +229 -0
  285. package/cli/forge/unit-trees.js +153 -0
  286. package/cli/forge/units.js +261 -0
  287. package/cli/forge/windows.js +129 -0
  288. package/cli/friction/friction-cli.js +71 -0
  289. package/cli/friction/friction-export.js +54 -0
  290. package/cli/friction/friction-log.js +54 -0
  291. package/cli/friction/usage-classify.js +56 -0
  292. package/cli/friction/usage-report.js +86 -0
  293. package/cli/friction/wrong-call.js +12 -0
  294. package/cli/fs-json.js +17 -0
  295. package/cli/generator-compact.js +55 -0
  296. package/cli/generator-help.js +16 -15
  297. package/cli/generator-indexer.js +2 -1
  298. package/cli/generator-jig-cli.js +11 -7
  299. package/cli/generator-jig.js +38 -33
  300. package/cli/generator-templates/archetypes/index.js +30 -13
  301. package/cli/generator-templates/archetypes/vector-matcher.js +8 -4
  302. package/cli/generator-templates/compact.js +4 -2
  303. package/cli/generator-templates/controller-converters.js +23 -14
  304. package/cli/generator-templates/controller.js +10 -5
  305. package/cli/generator-templates/hooks.js +4 -2
  306. package/cli/generator-templates/naming.js +2 -1
  307. package/cli/generator-templates/react.js +2 -1
  308. package/cli/generator-templates/specs.js +4 -2
  309. package/cli/generator-templates/svelte.js +4 -2
  310. package/cli/generator-templates/types.js +6 -3
  311. package/cli/generator-templates/views.js +4 -2
  312. package/cli/generator-templates/vue.js +4 -2
  313. package/cli/generator-writes.js +24 -0
  314. package/cli/generator.d.ts +1 -1
  315. package/cli/generator.js +86 -127
  316. package/cli/git-file-listing.js +69 -0
  317. package/cli/help-args.js +18 -0
  318. package/cli/help.d.ts +7 -3
  319. package/cli/help.js +94 -149
  320. package/cli/hooks/bypass-log.js +44 -0
  321. package/cli/hooks/claude-post-edit.js +79 -0
  322. package/cli/hooks/claude-pre-tool.js +178 -0
  323. package/cli/hooks/claude-settings-merge.js +101 -0
  324. package/cli/hooks/dispatch-identity.js +125 -0
  325. package/cli/hooks/entry.js +181 -0
  326. package/cli/hooks/foreign-identity.js +60 -0
  327. package/cli/hooks/guard-args.js +55 -0
  328. package/cli/hooks/guard-cases.js +94 -0
  329. package/cli/hooks/guard-config.js +43 -0
  330. package/cli/hooks/guard-invocation.js +106 -0
  331. package/cli/hooks/guard-paths.js +80 -0
  332. package/cli/hooks/guard-route.js +211 -0
  333. package/cli/hooks/guard-rules-nudge.js +37 -0
  334. package/cli/hooks/guard-rules-reads.js +66 -0
  335. package/cli/hooks/guard-rules-shell.js +239 -0
  336. package/cli/hooks/guard-rules.js +114 -0
  337. package/cli/hooks/hook-commands.js +21 -0
  338. package/cli/hooks/install-hooks-apply.js +36 -0
  339. package/cli/hooks/install-hooks-cli.js +100 -0
  340. package/cli/hooks/install-hooks-config.js +48 -0
  341. package/cli/hooks/install-hooks-pins.js +66 -0
  342. package/cli/hooks/install-hooks-plan.js +56 -0
  343. package/cli/hooks/install-hooks-status.js +7 -0
  344. package/cli/hooks/interpreter-writes.js +195 -0
  345. package/cli/hooks/launcher.js +60 -0
  346. package/cli/hooks/mcp-json-merge.js +39 -0
  347. package/cli/hooks/native-edit-lock.js +40 -0
  348. package/cli/hooks/native-tool-policy.js +152 -0
  349. package/cli/hooks/out-of-band-edits.js +141 -0
  350. package/cli/hooks/post-edit-scope.js +43 -0
  351. package/cli/hooks/project-status.js +59 -0
  352. package/cli/hooks/repo-membership.js +32 -0
  353. package/cli/hooks/run-hook.js +79 -0
  354. package/cli/hooks/session-identity.js +153 -0
  355. package/cli/hooks/session-start.js +50 -0
  356. package/cli/hooks/shell-lexer-readers.js +76 -0
  357. package/cli/hooks/shell-lexer-state.js +59 -0
  358. package/cli/hooks/shell-lexer.js +110 -0
  359. package/cli/hooks/shell-parse.js +232 -0
  360. package/cli/hooks/statusline.js +27 -0
  361. package/cli/hooks/xatoms-hints.js +38 -0
  362. package/cli/host-protocol.js +109 -0
  363. package/cli/host-shims.js +9 -8
  364. package/cli/index-admission.js +41 -0
  365. package/cli/index-freshness.js +83 -0
  366. package/cli/index-row-check.js +58 -0
  367. package/cli/index.js +52 -150
  368. package/cli/installer-templates.js +67 -75
  369. package/cli/installer.d.ts +16 -1
  370. package/cli/installer.js +159 -58
  371. package/cli/languages.js +8 -4
  372. package/cli/lattice-directives.js +24 -0
  373. package/cli/lattice-payload.js +34 -0
  374. package/cli/{tesseract-state.js → lattice-state.js} +8 -4
  375. package/cli/lease-view.js +48 -0
  376. package/cli/library/entry-fp.js +42 -0
  377. package/cli/library/entry-schema.js +90 -0
  378. package/cli/library/library-tasks.js +25 -0
  379. package/cli/library/registry.js +56 -0
  380. package/cli/library/reverify.js +56 -0
  381. package/cli/library/verify-checks.js +89 -0
  382. package/cli/library/verify.js +81 -0
  383. package/cli/license-config.js +124 -0
  384. package/cli/license.js +168 -135
  385. package/cli/line-count.js +23 -0
  386. package/cli/literal-replace.js +107 -0
  387. package/cli/main.js +166 -0
  388. package/cli/mcp/antigravity.js +11 -9
  389. package/cli/mcp/batch.js +59 -0
  390. package/cli/mcp/call-args.js +75 -0
  391. package/cli/mcp/call-effects.js +57 -0
  392. package/cli/mcp/call-scope.js +70 -62
  393. package/cli/mcp/context.js +81 -0
  394. package/cli/mcp/envelope.js +62 -0
  395. package/cli/mcp/fingerprint.js +26 -0
  396. package/cli/mcp/fresh-entry.js +34 -0
  397. package/cli/mcp/fresh-protocol.js +37 -0
  398. package/cli/mcp/fresh-runner.js +40 -0
  399. package/cli/mcp/help.js +53 -0
  400. package/cli/mcp/index.js +9 -5
  401. package/cli/mcp/inflight.js +47 -0
  402. package/cli/mcp/installer-jsonc.js +64 -0
  403. package/cli/mcp/installer-package.js +54 -0
  404. package/cli/mcp/installer-report.js +47 -0
  405. package/cli/mcp/installer-write.js +117 -0
  406. package/cli/mcp/installer.js +88 -187
  407. package/cli/mcp/manifests-analysis.js +156 -0
  408. package/cli/mcp/manifests-runners.js +48 -0
  409. package/cli/mcp/manifests-team.js +100 -0
  410. package/cli/mcp/manifests.js +69 -309
  411. package/cli/mcp/offload-worker.js +11 -0
  412. package/cli/mcp/offload.js +18 -0
  413. package/cli/mcp/patterns-cli.js +76 -0
  414. package/cli/mcp/patterns-forge-cli.js +120 -0
  415. package/cli/mcp/prompts.js +13 -10
  416. package/cli/mcp/resources.js +8 -35
  417. package/cli/mcp/roots.js +46 -0
  418. package/cli/mcp/scorecard-worker.js +7 -0
  419. package/cli/mcp/scorecard.js +42 -0
  420. package/cli/mcp/server-info.js +28 -0
  421. package/cli/mcp/server.js +91 -291
  422. package/cli/mcp/spec-harness.js +62 -0
  423. package/cli/mcp/stale-exec.js +48 -0
  424. package/cli/mcp/staleness.js +26 -0
  425. package/cli/mcp/stdio.js +141 -0
  426. package/cli/mcp/tool-call.js +73 -0
  427. package/cli/mcp/tools-audit-feed.js +33 -0
  428. package/cli/mcp/tools-audit.js +13 -7
  429. package/cli/mcp/tools-generate.js +3 -3
  430. package/cli/mcp/tools-lazy.js +39 -0
  431. package/cli/mcp/tools-patch.js +93 -21
  432. package/cli/mcp/tools-patterns.js +6 -3
  433. package/cli/mcp/tools-project.js +8 -4
  434. package/cli/mcp/tools-q-modes.js +15 -14
  435. package/cli/mcp/tools-q.js +94 -33
  436. package/cli/mcp/tools-read.js +30 -80
  437. package/cli/mcp/tools-team-feed.js +10 -8
  438. package/cli/mcp/tools-team-locks.js +22 -10
  439. package/cli/mcp/tools-team-mailbox.js +8 -7
  440. package/cli/mcp/tools-team-tasks.js +125 -38
  441. package/cli/mcp/tools-team.js +14 -7
  442. package/cli/mcp/tools-verify.js +44 -15
  443. package/cli/mcp/tools-write.js +11 -16
  444. package/cli/mcp/tools.js +202 -68
  445. package/cli/mcp/worker-run.js +24 -0
  446. package/cli/missing-imports.js +52 -0
  447. package/cli/mutation-args.js +96 -0
  448. package/cli/mutators.js +164 -61
  449. package/cli/navigator-actions.js +19 -13
  450. package/cli/navigator-banner-helpers.js +1 -26
  451. package/cli/navigator-banner.js +5 -3
  452. package/cli/navigator-conversion.js +23 -12
  453. package/cli/navigator-grades.js +70 -35
  454. package/cli/navigator-guide.js +13 -11
  455. package/cli/navigator-menu.js +80 -166
  456. package/cli/navigator-paged.js +15 -8
  457. package/cli/navigator-sections.js +32 -0
  458. package/cli/navigator-share.js +53 -39
  459. package/cli/navigator.d.ts +25 -5
  460. package/cli/navigator.js +14 -41
  461. package/cli/network-policy.js +72 -0
  462. package/cli/network-recorder.fixture.mjs +35 -0
  463. package/cli/outline/ast-outline.js +120 -0
  464. package/cli/outline/style-outline.js +42 -0
  465. package/cli/outline/vue-outline.js +88 -0
  466. package/cli/patcher-cli.js +255 -0
  467. package/cli/patcher.d.ts +55 -24
  468. package/cli/patcher.js +167 -358
  469. package/cli/path-scope.js +78 -22
  470. package/cli/patterns/fixtures/gt/A1.txt +109 -0
  471. package/cli/patterns/fixtures/gt/A10.txt +13 -0
  472. package/cli/patterns/fixtures/gt/A11.txt +10 -0
  473. package/cli/patterns/fixtures/gt/A12.txt +29 -0
  474. package/cli/patterns/fixtures/gt/A13.txt +39 -0
  475. package/cli/patterns/fixtures/gt/A14.txt +45 -0
  476. package/cli/patterns/fixtures/gt/A15.txt +70 -0
  477. package/cli/patterns/fixtures/gt/A16.txt +59 -0
  478. package/cli/patterns/fixtures/gt/A17.txt +29 -0
  479. package/cli/patterns/fixtures/gt/A18.txt +9 -0
  480. package/cli/patterns/fixtures/gt/A19.txt +29 -0
  481. package/cli/patterns/fixtures/gt/A2.txt +28 -0
  482. package/cli/patterns/fixtures/gt/A20.txt +83 -0
  483. package/cli/patterns/fixtures/gt/A21.txt +138 -0
  484. package/cli/patterns/fixtures/gt/A22.txt +32 -0
  485. package/cli/patterns/fixtures/gt/A23.txt +37 -0
  486. package/cli/patterns/fixtures/gt/A24.txt +67 -0
  487. package/cli/patterns/fixtures/gt/A25.txt +41 -0
  488. package/cli/patterns/fixtures/gt/A26.txt +29 -0
  489. package/cli/patterns/fixtures/gt/A3.txt +17 -0
  490. package/cli/patterns/fixtures/gt/A4.txt +44 -0
  491. package/cli/patterns/fixtures/gt/A5.txt +32 -0
  492. package/cli/patterns/fixtures/gt/A6.txt +15 -0
  493. package/cli/patterns/fixtures/gt/A7.txt +79 -0
  494. package/cli/patterns/fixtures/gt/A8.txt +41 -0
  495. package/cli/patterns/fixtures/gt/A9.txt +42 -0
  496. package/cli/patterns/fixtures/gt/B1.txt +11 -0
  497. package/cli/patterns/fixtures/gt/B10.txt +41 -0
  498. package/cli/patterns/fixtures/gt/B11.txt +7 -0
  499. package/cli/patterns/fixtures/gt/B2.txt +19 -0
  500. package/cli/patterns/fixtures/gt/B3.txt +70 -0
  501. package/cli/patterns/fixtures/gt/B4.txt +55 -0
  502. package/cli/patterns/fixtures/gt/B5.txt +21 -0
  503. package/cli/patterns/fixtures/gt/B6.txt +15 -0
  504. package/cli/patterns/fixtures/gt/B7.txt +24 -0
  505. package/cli/patterns/fixtures/gt/B8.txt +40 -0
  506. package/cli/patterns/fixtures/gt/B9.txt +18 -0
  507. package/cli/patterns/fixtures/gt/C1.txt +26 -0
  508. package/cli/patterns/fixtures/gt/C2.txt +33 -0
  509. package/cli/patterns/fixtures/gt/C3.txt +26 -0
  510. package/cli/patterns/fixtures/gt/C4.txt +7 -0
  511. package/cli/patterns/fixtures/gt/C5.txt +29 -0
  512. package/cli/patterns/fixtures/gt/C6.txt +7 -0
  513. package/cli/patterns/fixtures/gt/C7.txt +18 -0
  514. package/cli/patterns/fixtures/gt/labels.json +1837 -0
  515. package/cli/patterns/gt-build.js +55 -0
  516. package/cli/patterns/gt-locations.js +76 -0
  517. package/cli/patterns/gt-resolve.js +66 -0
  518. package/cli/patterns/gt-score-cli.js +80 -0
  519. package/cli/patterns/gt-score.js +188 -0
  520. package/cli/patterns/gt-text.js +79 -0
  521. package/cli/pillars-wizard.js +53 -24
  522. package/cli/pillars-write-guard.js +4 -1
  523. package/cli/postinstall.js +22 -19
  524. package/cli/project-detector.js +60 -35
  525. package/cli/project-markers.js +42 -0
  526. package/cli/project-scope.js +20 -0
  527. package/cli/read-revision.js +70 -0
  528. package/cli/reader-cards-gate.js +29 -0
  529. package/cli/reader-cards.js +153 -0
  530. package/cli/reader-cli.js +45 -18
  531. package/cli/reader-format.js +48 -0
  532. package/cli/reader-logic.js +128 -250
  533. package/cli/reader.js +210 -221
  534. package/cli/request-context.js +9 -0
  535. package/cli/result-status.js +23 -0
  536. package/cli/rules.js +81 -0
  537. package/cli/scaffold.js +80 -51
  538. package/cli/scan-ignore.js +12 -0
  539. package/cli/search-args.js +102 -0
  540. package/cli/search-ast-module.js +103 -0
  541. package/cli/search-ast.js +75 -112
  542. package/cli/search-commands-blast.js +70 -0
  543. package/cli/search-commands-graph.js +57 -105
  544. package/cli/search-commands-hazards.js +105 -0
  545. package/cli/search-commands-literal.js +102 -0
  546. package/cli/search-commands-semantic.js +39 -27
  547. package/cli/search-commands.js +93 -186
  548. package/cli/search-db.js +52 -252
  549. package/cli/search-debug.js +13 -0
  550. package/cli/search-graph-edges.js +112 -0
  551. package/cli/search-index-meta.js +66 -0
  552. package/cli/search-index-write.js +153 -0
  553. package/cli/search-literal-files.js +64 -0
  554. package/cli/search-literal.js +150 -0
  555. package/cli/search-output.js +88 -0
  556. package/cli/search-queries-graph.js +120 -193
  557. package/cli/search-queries-semantic.js +41 -14
  558. package/cli/search-queries-similar.js +2 -1
  559. package/cli/search-queries.js +46 -21
  560. package/cli/search-query-view.js +67 -0
  561. package/cli/search-rank.js +54 -0
  562. package/cli/search-replace-blocks.js +120 -0
  563. package/cli/search-resolve.js +52 -0
  564. package/cli/search-root.js +78 -0
  565. package/cli/search-scan.js +102 -0
  566. package/cli/search-schema-ddl.js +172 -0
  567. package/cli/search-schema.js +135 -220
  568. package/cli/search-session.js +11 -0
  569. package/cli/search-sync-paths.js +78 -0
  570. package/cli/search-sync-plan.js +63 -0
  571. package/cli/search-sync-rows.js +96 -0
  572. package/cli/search-sync.js +128 -0
  573. package/cli/search-tokenizer.js +8 -4
  574. package/cli/search.d.ts +26 -5
  575. package/cli/search.js +156 -410
  576. package/cli/sfc/component-resolver.js +96 -0
  577. package/cli/sfc/import-coverage.js +24 -0
  578. package/cli/sfc/module-aliases.js +102 -0
  579. package/cli/sfc/script-asts.js +51 -0
  580. package/cli/sfc/sfc-metadata.js +104 -0
  581. package/cli/sfc/sfc-parse.js +101 -0
  582. package/cli/sfc/svelte-parse.js +46 -0
  583. package/cli/sfc/template-walk.js +78 -0
  584. package/cli/sfc-scripts.js +60 -0
  585. package/cli/share-consent.js +49 -0
  586. package/cli/share-outcome.js +57 -0
  587. package/cli/silence-warnings.js +2 -1
  588. package/cli/source-parse.js +130 -0
  589. package/cli/spec-isolated-home.js +17 -0
  590. package/cli/spec-support/import-trace.mjs +22 -0
  591. package/cli/spec-support/run-cli.js +58 -0
  592. package/cli/sqlite-memory.js +47 -0
  593. package/cli/status-command.js +107 -0
  594. package/cli/symbol-locator.js +121 -0
  595. package/cli/team/agent-identity.js +58 -0
  596. package/cli/team/audit-run-adoption.js +117 -0
  597. package/cli/team/audit-run-bypass.js +177 -0
  598. package/cli/team/audit-run-calls.js +108 -0
  599. package/cli/team/audit-run-db.js +181 -0
  600. package/cli/team/audit-run-identity.js +80 -0
  601. package/cli/team/audit-run-invocations.js +130 -0
  602. package/cli/team/audit-run-protocol.js +258 -0
  603. package/cli/team/audit-run-render.js +107 -0
  604. package/cli/team/audit-run-shas.js +179 -0
  605. package/cli/team/audit-run.js +203 -0
  606. package/cli/team/claim-ignore-deps.js +16 -0
  607. package/cli/team/coordination-busy.js +164 -0
  608. package/cli/team/coordination-db.js +85 -0
  609. package/cli/team/coordination-fixture.js +53 -0
  610. package/cli/team/coordination-repos.js +72 -0
  611. package/cli/team/coordination-root.js +161 -0
  612. package/cli/team/coordination-target.js +114 -0
  613. package/cli/team/dispatch-templates/dispatch-v1.js +228 -0
  614. package/cli/team/edit-shas.js +45 -0
  615. package/cli/team/lease-activity.js +130 -0
  616. package/cli/team/lease-cap.js +67 -0
  617. package/cli/team/lease-contention.js +30 -0
  618. package/cli/team/lease-key.js +46 -0
  619. package/cli/team/lease-lapse.js +83 -0
  620. package/cli/team/lease-reacquire.js +99 -0
  621. package/cli/team/lease-renew.js +97 -0
  622. package/cli/team/lease-roots.js +30 -0
  623. package/cli/team/lease-waiter-notice.js +48 -0
  624. package/cli/team/staged-leases.js +64 -0
  625. package/cli/team/task-completion-output.js +78 -0
  626. package/cli/team/task-detail-sections.js +86 -0
  627. package/cli/team/task-list-view.js +10 -1
  628. package/cli/team/task-ref.js +73 -0
  629. package/cli/team/task-target.js +53 -0
  630. package/cli/team/task-tier.js +17 -0
  631. package/cli/team/team-brief.js +78 -0
  632. package/cli/team/team-commands-board.js +118 -0
  633. package/cli/team/team-commands-dispatch.js +85 -0
  634. package/cli/team/team-commands-lock-staged.js +87 -0
  635. package/cli/team/team-commands-lock-views.js +144 -0
  636. package/cli/team/team-commands-lock.js +115 -26
  637. package/cli/team/team-commands-migrate.js +171 -0
  638. package/cli/team/team-commands-profile.js +44 -0
  639. package/cli/team/team-commands-repo.js +114 -0
  640. package/cli/team/team-commands-task.js +312 -0
  641. package/cli/team/team-commands-tokens.js +57 -0
  642. package/cli/team/team-commands-triage.js +43 -0
  643. package/cli/team/team-commands-vds.js +2 -1
  644. package/cli/team/team-commands.js +108 -463
  645. package/cli/team/team-db-agents.js +12 -6
  646. package/cli/team/team-db-feed.js +25 -13
  647. package/cli/team/team-db-lock-promotion.js +95 -51
  648. package/cli/team/team-db-locks.js +167 -35
  649. package/cli/team/team-db-mailbox.js +15 -8
  650. package/cli/team/team-db-readonly.js +76 -0
  651. package/cli/team/team-db-task-helpers.js +68 -19
  652. package/cli/team/team-db-tasks.js +21 -9
  653. package/cli/team/team-db-transaction.js +20 -5
  654. package/cli/team/team-db.js +11 -4
  655. package/cli/team/team-dispatch-batches.js +271 -0
  656. package/cli/team/team-dispatch-prompts.js +152 -0
  657. package/cli/team/team-dispatch-render.js +154 -0
  658. package/cli/team/team-dispatch-run-cli.js +154 -0
  659. package/cli/team/team-dispatch-runs.js +155 -0
  660. package/cli/team/team-dispatch-script.js +67 -0
  661. package/cli/team/team-dispatch-select.js +220 -0
  662. package/cli/team/team-dispatch-v2-fixture.js +62 -0
  663. package/cli/team/team-dispatch-v2.js +207 -0
  664. package/cli/team/team-dispatch.js +229 -0
  665. package/cli/team/team-dispatcher-authority.js +43 -0
  666. package/cli/team/team-flags.js +222 -48
  667. package/cli/team/team-format.js +80 -26
  668. package/cli/team/team-handoff-hint.js +9 -0
  669. package/cli/team/team-migrate-agents.js +52 -0
  670. package/cli/team/team-migrate-apply.js +178 -0
  671. package/cli/team/team-migrate-junk.js +55 -0
  672. package/cli/team/team-migrate-metadata.js +80 -0
  673. package/cli/team/team-migrate-paths.js +50 -0
  674. package/cli/team/team-migrate-plan.js +85 -0
  675. package/cli/team/team-migrate-report.js +89 -0
  676. package/cli/team/team-migrate-tables.js +85 -0
  677. package/cli/team/team-migrate.js +193 -0
  678. package/cli/team/team-needs.js +99 -0
  679. package/cli/team/team-profile-format.js +126 -0
  680. package/cli/team/team-profile.js +144 -0
  681. package/cli/team/team-projects-coordinator.js +54 -33
  682. package/cli/team/team-projects-format.js +8 -4
  683. package/cli/team/team-projects-memory.js +6 -3
  684. package/cli/team/team-projects.js +2 -1
  685. package/cli/team/team-release-train.js +2 -1
  686. package/cli/team/team-route.js +132 -0
  687. package/cli/team/team-schema-repo.js +48 -0
  688. package/cli/team/team-schema-usage.js +25 -0
  689. package/cli/team/team-schema-vds.js +7 -3
  690. package/cli/team/team-schema.js +24 -4
  691. package/cli/team/team-task-close.js +132 -0
  692. package/cli/team/team-task-guard.js +24 -0
  693. package/cli/team/team-task-handoff.js +122 -0
  694. package/cli/team/team-task-ownership.js +74 -0
  695. package/cli/team/team-task-rules.js +21 -0
  696. package/cli/team/team-task-uncommitted.js +49 -0
  697. package/cli/team/team-telemetry.js +44 -32
  698. package/cli/team/team-tokens.js +4 -1
  699. package/cli/team/team-triage-generate.js +212 -0
  700. package/cli/team/team-triage-log.js +11 -0
  701. package/cli/team/team-triage-verify.js +153 -0
  702. package/cli/team/team-triage.js +92 -339
  703. package/cli/team/team-vds.js +2 -1
  704. package/cli/team/usage-compute.js +70 -0
  705. package/cli/team/usage-pricing.js +62 -0
  706. package/cli/team/usage-reader.js +106 -0
  707. package/cli/team/usage-render.js +72 -0
  708. package/cli/team/usage-store.js +56 -0
  709. package/cli/team/usage-transcript.js +127 -0
  710. package/cli/team/write-lock-guard.js +48 -0
  711. package/cli/telemetry/call-ledger.js +264 -0
  712. package/cli/telemetry/call-schema.js +53 -0
  713. package/cli/telemetry/savings-dbs.js +111 -0
  714. package/cli/telemetry/savings-render.js +68 -0
  715. package/cli/telemetry/savings-report.js +101 -0
  716. package/cli/telemetry/savings-routing.js +66 -0
  717. package/cli/telemetry/savings-tooling.js +140 -0
  718. package/cli/terminal.js +38 -40
  719. package/cli/tesseract-manifesto.js +2 -17
  720. package/cli/tesseract.js +8 -21
  721. package/cli/test-audit.js +218 -0
  722. package/cli/test-changes.js +60 -0
  723. package/cli/test-command.js +201 -0
  724. package/cli/test-depth.js +43 -0
  725. package/cli/test-failures.js +170 -0
  726. package/cli/test-graph-open.js +150 -0
  727. package/cli/test-graph.js +188 -0
  728. package/cli/test-lanes.js +117 -0
  729. package/cli/test-output.js +155 -0
  730. package/cli/test-paths.js +51 -0
  731. package/cli/test-profile.js +64 -0
  732. package/cli/test-report.js +112 -0
  733. package/cli/test-run.js +53 -0
  734. package/cli/test-scope.js +55 -0
  735. package/cli/test-select.js +107 -0
  736. package/cli/test-slots.js +276 -0
  737. package/cli/test-workers.js +45 -0
  738. package/cli/test-workspace.js +83 -0
  739. package/cli/theme.js +6 -3
  740. package/cli/timers.js +6 -0
  741. package/cli/trend.js +10 -5
  742. package/cli/tsconfig-shape.js +20 -0
  743. package/cli/tty-banner.js +11 -0
  744. package/cli/typecheck-audit.js +146 -0
  745. package/cli/typecheck-command.js +94 -0
  746. package/cli/typecheck-sandbox.js +93 -0
  747. package/cli/ui-actions-codebase.js +20 -7
  748. package/cli/ui-actions-helpers.js +9 -0
  749. package/cli/ui-actions-studio.js +11 -7
  750. package/cli/ui-actions-tasks.js +3 -2
  751. package/cli/ui-actions-vds.js +2 -1
  752. package/cli/ui-actions.js +4 -2
  753. package/cli/ui-attention.js +28 -12
  754. package/cli/ui-auth-hosts.js +46 -0
  755. package/cli/ui-auth.js +89 -0
  756. package/cli/ui-client-cert.js +2 -1
  757. package/cli/ui-client-filetree.js +2 -2
  758. package/cli/ui-db-studio.js +23 -33
  759. package/cli/ui-dev-watcher.js +2 -1
  760. package/cli/ui-forum-data.js +45 -46
  761. package/cli/ui-forum-topics.js +6 -3
  762. package/cli/ui-fresh-index.js +11 -0
  763. package/cli/ui-handlers.js +6 -6
  764. package/cli/ui-html.js +6 -12
  765. package/cli/ui-index.html +3 -3
  766. package/cli/ui-route-helpers.js +10 -0
  767. package/cli/ui-server-routes.js +15 -17
  768. package/cli/ui-server.js +49 -50
  769. package/cli/ui-sql-guard.js +76 -0
  770. package/cli/ui-sql-mask.js +61 -0
  771. package/cli/ui-sse.js +5 -4
  772. package/cli/ui-template-filetree.js +4 -4
  773. package/cli/ui-template-kanban.js +4 -7
  774. package/cli/verify-changed.js +43 -0
  775. package/cli/verify-helpers.js +21 -207
  776. package/cli/verify-lint.js +54 -20
  777. package/cli/verify-report.js +117 -0
  778. package/cli/verify-steps.js +71 -0
  779. package/cli/verify.js +111 -372
  780. package/cli/wait-command.js +147 -0
  781. package/cli/workspace-run.js +153 -0
  782. package/cli/workspace.js +147 -0
  783. package/cli/write-append.js +28 -0
  784. package/library/node-js/is-path-inside/entry.json +57 -0
  785. package/library/node-js/is-path-inside/negative/path-scope.js.txt +13 -0
  786. package/library/node-js/is-path-inside/piece.js +15 -0
  787. package/library/node-js/is-path-inside/piece.spec.js +38 -0
  788. package/library/node-js/read-json-or/entry.json +70 -0
  789. package/library/node-js/read-json-or/negative/ratchet.js.txt +14 -0
  790. package/library/node-js/read-json-or/negative/workspace.js.txt +8 -0
  791. package/library/node-js/read-json-or/piece.js +17 -0
  792. package/library/node-js/read-json-or/piece.spec.js +36 -0
  793. package/library/vue-ts/nullable-timer-handle/ambient.d.ts +5 -0
  794. package/library/vue-ts/nullable-timer-handle/entry.json +84 -0
  795. package/library/vue-ts/nullable-timer-handle/negative/const-alias.ts.txt +17 -0
  796. package/library/vue-ts/nullable-timer-handle/negative/inline-guard.ts.txt +15 -0
  797. package/library/vue-ts/nullable-timer-handle/piece.spec.js +48 -0
  798. package/library/vue-ts/nullable-timer-handle/piece.ts +41 -0
  799. package/package.json +9 -3
  800. package/scripts/check-framework-generation.mjs +32 -12
  801. package/scripts/direct-run.mjs +9 -0
  802. package/scripts/pre-commit.sh +48 -74
  803. package/scripts/publish-both.mjs +24 -16
  804. package/scripts/publish-summary.mjs +14 -0
  805. package/scripts/postinstall.mjs +0 -27
@@ -1,5 +1,11 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
+ import { resolveSafePath } from '../path-scope.js';
4
+ import { applyEdits } from '../apply-edits.js';
5
+ import { autofixContent } from './autofix-content.js';
6
+ import { STATUS, inconclusive } from '../result-status.js';
7
+
8
+ export { autofixContent } from './autofix-content.js';
3
9
 
4
10
  const IGNORED_DIRS = new Set([
5
11
  'node_modules',
@@ -9,183 +15,92 @@ const IGNORED_DIRS = new Set([
9
15
  '.git',
10
16
  '.next',
11
17
  '.turbo',
12
- '.cache'
18
+ '.cache',
19
+ '.chemx',
20
+ '.claude'
13
21
  ]);
14
22
 
15
- const FIXABLE_EXTENSIONS = new Set(['.tsx', '.ts', '.jsx', '.js', '.vue', '.md', '.scss', '.css']);
16
-
17
- const RESIDUE_PATTERNS = [
18
- ['hope this', 'helps'].join(' '),
19
- ['feel free', 'to tweak'].join(' '),
20
- ['let me know', 'if you need'].join(' '),
21
- ['as an ai', 'language model'].join(' ')
22
- ];
23
-
24
- const RESIDUE_REGEX = new RegExp(`\\b(?:${RESIDUE_PATTERNS.join('|')})\\b`, 'i');
25
- const PREAMBLE_REGEX = /\b(?:here(?:'s| is) the (?:complete|updated|refactored|full) (?:code|implementation|file|component|version))\b/i;
26
- const TRUNCATION_REGEX = /^\s*\/\/\s*\.\.\.\s*(?:existing|rest of|remaining)\s+(?:code|implementation|logic|imports)/i;
27
- const MARKDOWN_FENCE_REGEX = /^\s*```(?:typescript|javascript|tsx|jsx|vue|js|ts|html|css|scss)?\s*$/;
28
-
29
- export const autofixContent = (content, options = {}) => {
30
- const allowedRules = options.rules ? new Set(options.rules) : null;
31
- const shouldFix = (rule) => !allowedRules || allowedRules.has(rule);
32
-
33
- const lines = content.split('\n');
34
- const fixes = [];
35
- const resultLines = [];
36
-
37
- for (let i = 0; i < lines.length; i++) {
38
- let line = lines[i];
39
- const lineNumber = i + 1;
40
- let shouldDropLine = false;
41
-
42
- // 1. Leaked markdown fence removal
43
- if (shouldFix('AI_SLOP_CONVERSATIONAL_ARTIFACT') && MARKDOWN_FENCE_REGEX.test(line)) {
44
- fixes.push({
45
- line: lineNumber,
46
- rule: 'AI_SLOP_CONVERSATIONAL_ARTIFACT',
47
- action: 'Removed leaked markdown code fence'
48
- });
49
- shouldDropLine = true;
50
- }
51
-
52
- // 2. Pure conversational preamble or residue comment removal
53
- if (!shouldDropLine && shouldFix('AI_SLOP_CONVERSATIONAL_ARTIFACT')) {
54
- const isComment = /^\s*(?:\/\/|\/\*|<!--)/.test(line);
55
- if (isComment && (PREAMBLE_REGEX.test(line) || RESIDUE_REGEX.test(line))) {
56
- fixes.push({
57
- line: lineNumber,
58
- rule: 'AI_SLOP_CONVERSATIONAL_ARTIFACT',
59
- action: 'Removed AI conversational residue comment'
60
- });
61
- shouldDropLine = true;
62
- }
63
- }
23
+ // Markdown is deliberately absent: fences and prose are content there, not AI residue.
24
+ export const FIXABLE_EXTENSIONS = new Set(['.tsx', '.ts', '.jsx', '.js', '.mjs', '.cjs', '.vue', '.svelte', '.scss', '.css']);
64
25
 
65
- // 3. AI lazy placeholder comment removal
66
- const hasLazyTruncation = TRUNCATION_REGEX.test(line);
67
- const isLazyTruncationEligible = !shouldDropLine && shouldFix('AI_SLOP_LAZY_PLACEHOLDER');
68
- if (isLazyTruncationEligible && hasLazyTruncation) {
69
- fixes.push({
70
- line: lineNumber,
71
- rule: 'AI_SLOP_LAZY_PLACEHOLDER',
72
- action: 'Removed lazy AI truncation placeholder comment'
73
- });
74
- shouldDropLine = true;
75
- }
26
+ const isFixable = (filePath) => FIXABLE_EXTENSIONS.has(path.extname(filePath).toLowerCase());
76
27
 
77
- const hasEmDash = line.includes('\u2014');
78
- const isEmDashEligible = !shouldDropLine && shouldFix('TYPOGRAPHY_EM_DASH');
79
- if (isEmDashEligible && hasEmDash) {
80
- line = line.replace(/\u2014/g, '-');
81
- fixes.push({
82
- line: lineNumber,
83
- rule: 'TYPOGRAPHY_EM_DASH',
84
- action: 'Replaced em dash with standard hyphen'
85
- });
86
- }
87
-
88
- const hasTimeoutMacro = /setTimeout\([^,]+,\s*0\)/.test(line);
89
- const isTimeoutEligible = !shouldDropLine && shouldFix('MACRO_TASK_OVER_MICRO_TASK');
90
- if (isTimeoutEligible && hasTimeoutMacro) {
91
- line = line.replace(/setTimeout\(([^,]+),\s*0\)/g, 'queueMicrotask($1)');
92
- fixes.push({
93
- line: lineNumber,
94
- rule: 'MACRO_TASK_OVER_MICRO_TASK',
95
- action: 'Replaced setTimeout(fn, 0) with queueMicrotask(fn)'
96
- });
97
- }
98
-
99
- if (!shouldDropLine) {
100
- resultLines.push(line);
101
- }
102
- }
103
-
104
- return {
105
- fixedContent: resultLines.join('\n'),
106
- fixes
107
- };
108
- };
109
-
110
- const collectFiles = (targetPath, baseDir) => {
111
- const stat = fs.statSync(targetPath);
112
- if (stat.isFile()) {
113
- return [targetPath];
114
- }
28
+ const collectFiles = (targetPath) => {
29
+ const isFile = fs.statSync(targetPath).isFile();
30
+ if (isFile) return isFixable(targetPath) ? [targetPath] : [];
115
31
 
116
32
  let files = [];
117
- const entries = fs.readdirSync(targetPath, { withFileTypes: true });
118
- for (const entry of entries) {
119
- if (IGNORED_DIRS.has(entry.name)) continue;
33
+ for (const entry of fs.readdirSync(targetPath, { withFileTypes: true })) {
34
+ const isIgnored = IGNORED_DIRS.has(entry.name);
35
+ if (isIgnored) continue;
120
36
  const fullPath = path.join(targetPath, entry.name);
121
- if (entry.isDirectory()) {
122
- files = files.concat(collectFiles(fullPath, baseDir));
123
- } else if (FIXABLE_EXTENSIONS.has(path.extname(entry.name))) {
124
- files.push(fullPath);
125
- }
37
+ const isDirectory = entry.isDirectory();
38
+ const isFixableFile = !isDirectory && isFixable(entry.name);
39
+ if (isDirectory) files = files.concat(collectFiles(fullPath));
40
+ else if (isFixableFile) files.push(fullPath);
126
41
  }
127
42
  return files;
128
43
  };
129
44
 
45
+ // No fixable file was looked at: that proves nothing, so it is inconclusive (exit 3), never a green check.
46
+ const NOTHING_CHECKED = inconclusive('NO_FILES_CHECKED');
47
+
48
+ const excludedReason = (filePath) => {
49
+ const ext = path.extname(filePath).toLowerCase() || 'extensionless';
50
+ return `${ext} files are not autofix targets (fixable: ${[...FIXABLE_EXTENSIONS].join(' ')}); nothing was checked`;
51
+ };
52
+
53
+ /**
54
+ * Applies token-aware mechanical fixes to a file or directory, through applyEdits
55
+ * (parse check, declaration-loss check, team locks, atomic writes, one rollback-able batch).
56
+ *
57
+ * @param {string} targetPath File or directory (default 'src').
58
+ * @param {object} [options] { cwd, dryRun, rules, agentId }
59
+ * @returns {object} status (pass, or inconclusive when no fixable file was checked), the uncapped
60
+ * fix list, suggestions, skipped files, and the diff on a dry run.
61
+ */
130
62
  export const runAutofix = (targetPath, options = {}) => {
131
63
  const cwd = options.cwd || process.cwd();
132
- const resolvedTarget = path.resolve(cwd, targetPath || 'src');
64
+ const target = targetPath || 'src';
133
65
  const dryRun = Boolean(options.dryRun);
134
-
135
- if (!fs.existsSync(resolvedTarget)) {
136
- return {
137
- target: targetPath || 'src',
138
- dryRun,
139
- filesScanned: 0,
140
- filesChanged: 0,
141
- totalFixes: 0,
142
- fixes: []
143
- };
144
- }
145
-
146
- const files = collectFiles(resolvedTarget, cwd);
147
- const allFixes = [];
148
- let filesChanged = 0;
149
-
66
+ const resolvedTarget = resolveSafePath(target, cwd);
67
+ const root = fs.realpathSync(cwd);
68
+ const empty = { ...NOTHING_CHECKED, target, dryRun, filesScanned: 0, filesChanged: 0, totalFixes: 0, fixes: [], suggestions: [], skipped: [] };
69
+ const isMissing = !fs.existsSync(resolvedTarget);
70
+ if (isMissing) return { ...empty, skipped: [{ file: target, reason: 'target does not exist; nothing was checked' }] };
71
+ const isExcludedFile = fs.statSync(resolvedTarget).isFile() && !isFixable(resolvedTarget);
72
+ if (isExcludedFile) return { ...empty, skipped: [{ file: path.relative(root, resolvedTarget), reason: excludedReason(resolvedTarget) }] };
73
+
74
+ const files = collectFiles(resolvedTarget);
75
+ const fixes = [];
76
+ const suggestions = [];
77
+ const skipped = [];
78
+ const edits = [];
150
79
  for (const filePath of files) {
151
- const relPath = path.relative(cwd, filePath);
152
- const originalContent = fs.readFileSync(filePath, 'utf-8');
153
- const { fixedContent, fixes } = autofixContent(originalContent, options);
154
-
155
- if (fixes.length > 0) {
156
- filesChanged += 1;
157
- for (const fix of fixes) {
158
- allFixes.push({
159
- file: relPath,
160
- line: fix.line,
161
- rule: fix.rule,
162
- action: fix.action
163
- });
164
- }
165
-
166
- if (!dryRun) {
167
- fs.writeFileSync(filePath, fixedContent, 'utf-8');
168
- }
169
- }
80
+ const file = path.relative(root, filePath);
81
+ const original = fs.readFileSync(filePath, 'utf-8');
82
+ const result = autofixContent(original, { ...options, filePath });
83
+ const isSkipped = Boolean(result.skipped);
84
+ if (isSkipped) skipped.push({ file, reason: result.skipped });
85
+ result.suggestions.forEach((s) => suggestions.push({ file, ...s }));
86
+ const isChanged = result.fixes.length > 0 && result.fixedContent !== original;
87
+ if (!isChanged) continue;
88
+ result.fixes.forEach((f) => fixes.push({ file, line: f.line, rule: f.rule, action: f.action }));
89
+ edits.push({ path: filePath, content: result.fixedContent });
170
90
  }
171
91
 
172
- // Token optimization: cap fixes list to top 15 samples if very large
173
- const MAX_REPORTED_FIXES = 15;
174
- const isCapped = allFixes.length > MAX_REPORTED_FIXES;
175
- const reportedFixes = isCapped ? allFixes.slice(0, MAX_REPORTED_FIXES) : allFixes;
176
-
177
- const result = {
178
- target: targetPath || 'src',
92
+ const applied = edits.length > 0 ? applyEdits(edits, { cwd, dryRun, agentId: options.agentId }) : null;
93
+ const isNothingChecked = files.length === 0;
94
+ return {
95
+ ...(isNothingChecked ? NOTHING_CHECKED : { status: STATUS.PASS }),
96
+ target,
179
97
  dryRun,
180
98
  filesScanned: files.length,
181
- filesChanged,
182
- totalFixes: allFixes.length,
183
- fixes: reportedFixes
99
+ filesChanged: edits.length,
100
+ totalFixes: fixes.length,
101
+ fixes,
102
+ suggestions,
103
+ skipped,
104
+ ...(dryRun && applied ? { diff: applied.diff } : {})
184
105
  };
185
-
186
- if (isCapped) {
187
- result.omittedFixesCount = allFixes.length - MAX_REPORTED_FIXES;
188
- }
189
-
190
- return result;
191
106
  };
@@ -0,0 +1,84 @@
1
+ /**
2
+ * LINE_BUDGET_FILE, LINE_BUDGET_MOLECULE and VIEW_MONOLITH from the one budget
3
+ * policy in line-budgets.js (finding line-budget-chaos).
4
+ */
5
+ import { PILLARS } from './rules-registry.js';
6
+ import {
7
+ countLines,
8
+ getLineBudgets,
9
+ resolveFileTier,
10
+ isViewMarkupFile,
11
+ classifyFileSize
12
+ } from './line-budgets.js';
13
+
14
+ const fileViolation = (relativePath, rule, severity, hazard, directive) => ({
15
+ filePath: relativePath,
16
+ line: 1,
17
+ column: 1,
18
+ hazard,
19
+ rule,
20
+ severity,
21
+ pillar: PILLARS.PILLAR_1,
22
+ directive
23
+ });
24
+
25
+ const FILE_SEVERITY_BY_CLASS = Object.freeze({
26
+ extreme: { severity: 'CRITICAL', limitKey: 'critical', label: 'Extreme monolith hazard' },
27
+ severe: { severity: 'HIGH', limitKey: 'high', label: 'Severe monolith hazard' },
28
+ warning: { severity: 'MEDIUM', limitKey: 'warn', label: 'Monolith line budget warning' }
29
+ });
30
+
31
+ const resolveFileSeverity = (lineCount, budget) => {
32
+ const { severity, limitKey, label } = FILE_SEVERITY_BY_CLASS[classifyFileSize(lineCount, budget)];
33
+ return { severity, limit: budget[limitKey], label };
34
+ };
35
+
36
+ const resolveMoleculeSeverity = (lineCount, limit) => {
37
+ const isCriticalMolecule = lineCount >= limit * 5;
38
+ if (isCriticalMolecule) return 'CRITICAL';
39
+ const isHighMolecule = lineCount >= limit * 2.5;
40
+ if (isHighMolecule) return 'HIGH';
41
+ return 'MEDIUM';
42
+ };
43
+
44
+ const resolveTemplateLines = (content, sfc) => {
45
+ const template = sfc?.template;
46
+ if (template) return template.endLine - template.startLine + 1;
47
+ return countLines(content);
48
+ };
49
+
50
+ /**
51
+ * @param {{ content: string, relativePath: string, config?: object, sfc?: object|null, hasHighComplexity?: boolean }} input
52
+ */
53
+ export const checkLineBudgets = ({ content, relativePath, config = {}, sfc = null, hasHighComplexity = false }) => {
54
+ const budgets = getLineBudgets(config);
55
+ const lineCount = countLines(content);
56
+ const tier = resolveFileTier(relativePath, config);
57
+
58
+ const isFileMonolith = classifyFileSize(lineCount, budgets.file) !== null;
59
+ if (isFileMonolith) {
60
+ const { severity, limit, label } = resolveFileSeverity(lineCount, budgets.file);
61
+ return [fileViolation(relativePath, 'LINE_BUDGET_FILE', severity, `${label} (${lineCount} > ${limit} lines)`,
62
+ 'Decompose monolith into domain capsules and molecules (Directive 1.A)')];
63
+ }
64
+
65
+ const isOverMoleculeBudget = tier === 'molecule' && lineCount > budgets.molecule;
66
+ const isMoleculeEnforced = budgets.isMoleculeHardCap || hasHighComplexity;
67
+ const isMoleculeViolation = Boolean(isOverMoleculeBudget && isMoleculeEnforced);
68
+ if (isMoleculeViolation) {
69
+ const severity = resolveMoleculeSeverity(lineCount, budgets.molecule);
70
+ return [fileViolation(relativePath, 'LINE_BUDGET_MOLECULE', severity, `Molecule capsule over budget (${lineCount} > ${budgets.molecule} lines, ${budgets.profile})`,
71
+ 'Split molecule into focused sub-molecules or extract state to a composable (Directive 1.C)')];
72
+ }
73
+
74
+ const isViewEntry = tier === 'view' && isViewMarkupFile(relativePath);
75
+ const templateLines = isViewEntry ? resolveTemplateLines(content, sfc) : 0;
76
+ const isViewMonolith = templateLines > budgets.viewTemplate.warn;
77
+ if (isViewMonolith) {
78
+ const isSevere = templateLines >= budgets.viewTemplate.critical;
79
+ return [fileViolation(relativePath, 'VIEW_MONOLITH', isSevere ? 'CRITICAL' : 'MEDIUM',
80
+ `View template over budget (${templateLines} > ${budgets.viewTemplate.warn} lines)`,
81
+ 'Refactor top-level view to a 10 to 20 line Table of Contents (Directive 1.B)')];
82
+ }
83
+ return [];
84
+ };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Catch-clause handling predicates for ERROR_SWALLOWED_EXCEPTION (Directive 2.H).
3
+ * A catch is handled when it throws, returns a value, calls anything (logger,
4
+ * notifier, handler), or assigns state that outlives the catch (error state,
5
+ * a fallback value, a member of an outer object).
6
+ */
7
+ import * as t from '@babel/types';
8
+
9
+ const isMeaningfulStatement = (stmt) => !t.isEmptyStatement(stmt);
10
+
11
+ export const isEmptyCatchBody = (catchNode) => {
12
+ const body = catchNode.body?.body || [];
13
+ return !body.some(isMeaningfulStatement);
14
+ };
15
+
16
+ const isOuterBindingTarget = (left, catchPath) => {
17
+ const isMember = t.isMemberExpression(left) || t.isOptionalMemberExpression(left);
18
+ if (isMember) return true;
19
+ if (!t.isIdentifier(left)) return false;
20
+ const binding = catchPath.scope.getBinding(left.name);
21
+ if (!binding) return true;
22
+ const isDeclaredInsideCatch = Boolean(binding.path.findParent((p) => p === catchPath));
23
+ return !isDeclaredInsideCatch;
24
+ };
25
+
26
+ /** True when the catch body neither propagates, reports, nor records the failure. */
27
+ export const isSwallowedCatch = (astPath) => {
28
+ if (isEmptyCatchBody(astPath.node)) return true;
29
+
30
+ let hasActiveHandling = false;
31
+ const markHandled = () => { hasActiveHandling = true; };
32
+ astPath.traverse({
33
+ ThrowStatement: markHandled,
34
+ CallExpression: markHandled,
35
+ OptionalCallExpression: markHandled,
36
+ NewExpression: markHandled,
37
+ ReturnStatement(retPath) {
38
+ const hasValue = retPath.node.argument !== null;
39
+ if (hasValue) markHandled();
40
+ },
41
+ AssignmentExpression(assignPath) {
42
+ const isOuterTarget = isOuterBindingTarget(assignPath.node.left, astPath);
43
+ if (isOuterTarget) markHandled();
44
+ },
45
+ Function(fnPath) {
46
+ fnPath.skip();
47
+ }
48
+ });
49
+
50
+ return !hasActiveHandling;
51
+ };
@@ -0,0 +1,76 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { isSqliteMemoryTarget, isLinkedWorktreeRoot } from '../sqlite-memory.js';
4
+ import { hasProjectMarker, isForbiddenRoot, forbiddenRootRefusal } from '../project-markers.js';
5
+
6
+ // Locates (and creates) the .chemx directory that holds history and the index db.
7
+ // The walk prefers an existing ancestor .chemx, but stops at the first project marker (.git,
8
+ // package.json, .chemxrc; a linked worktree has a .git file): each package and each checkout keeps
9
+ // its own index instead of sharing a parent's. It never climbs into the OS temp dir, its ancestors
10
+ // or the filesystem root, and never answers one of them (#2570): a stray /tmp/.chemx is ignored.
11
+ const isIndexBoundary = (dir) => isLinkedWorktreeRoot(fs, path, dir) || hasProjectMarker(dir);
12
+
13
+ // Throws for a forbidden root: callers would otherwise create a db at /tmp or /.
14
+ const refuseForbidden = (dir) => {
15
+ const refusal = forbiddenRootRefusal(dir);
16
+ if (refusal) throw new Error(refusal);
17
+ return dir;
18
+ };
19
+
20
+ export const findChemxDir = (startDir = process.cwd()) => {
21
+ const hasCustomRoot = Boolean(process.env.CHEMX_PROJECT_ROOT);
22
+ if (hasCustomRoot) {
23
+ return path.join(refuseForbidden(path.resolve(process.env.CHEMX_PROJECT_ROOT)), '.chemx');
24
+ }
25
+
26
+ let current = path.resolve(startDir);
27
+ while (!isForbiddenRoot(current)) {
28
+ const candidate = path.join(current, '.chemx');
29
+ const hasExistingChemx = fs.existsSync(candidate);
30
+ if (hasExistingChemx) {
31
+ return candidate;
32
+ }
33
+ if (isIndexBoundary(current)) return candidate;
34
+ current = path.dirname(current);
35
+ }
36
+
37
+ return path.join(refuseForbidden(path.resolve(startDir)), '.chemx');
38
+ };
39
+
40
+ export const ensureChemxDir = (cwd = process.cwd()) => {
41
+ const isMemoryTarget = isSqliteMemoryTarget(cwd);
42
+ if (isMemoryTarget) {
43
+ throw new Error(`ensureChemxDir: "${cwd}" is an in-memory SQLite target, not a directory`);
44
+ }
45
+ const dir = findChemxDir(cwd);
46
+ try {
47
+ const isDirMissing = !fs.existsSync(dir);
48
+ if (isDirMissing) {
49
+ fs.mkdirSync(dir, { recursive: true });
50
+ }
51
+ } catch {
52
+ return dir;
53
+ }
54
+
55
+ // Ensure .chemx is gitignored if git repo exists
56
+ const targetParent = path.dirname(dir);
57
+ const gitDir = path.resolve(targetParent, '.git');
58
+ const hasGit = fs.existsSync(gitDir);
59
+ if (hasGit) {
60
+ const gitignorePath = path.resolve(targetParent, '.gitignore');
61
+ try {
62
+ const hasGitignore = fs.existsSync(gitignorePath);
63
+ let content = hasGitignore ? fs.readFileSync(gitignorePath, 'utf-8') : '';
64
+ const hasChemxEntry = content.includes('.chemx');
65
+ if (!hasChemxEntry) {
66
+ const hasTrailingNewline = content.endsWith('\n') || content.length === 0;
67
+ const trailingNewline = hasTrailingNewline ? '' : '\n';
68
+ fs.appendFileSync(gitignorePath, `${trailingNewline}# Chemical X local telemetry & audit history\n.chemx/\n`, 'utf-8');
69
+ }
70
+ } catch {
71
+ return dir;
72
+ }
73
+ }
74
+
75
+ return dir;
76
+ };
@@ -2,7 +2,8 @@ import path from 'node:path';
2
2
  import { deserializeVector, cosineSimilarity } from '../embeddings/vectorizer.js';
3
3
 
4
4
  const isSpecOrTest = (filePath) => {
5
- if (!filePath || typeof filePath !== 'string') return false;
5
+ const isInvalidPath = !filePath || typeof filePath !== 'string';
6
+ if (isInvalidPath) return false;
6
7
  return filePath.includes('.spec.') || filePath.includes('.test.') || filePath.includes('__tests__');
7
8
  };
8
9
 
@@ -10,7 +11,8 @@ export const detectSemanticClones = (db, options = {}) => {
10
11
  const isValidDb = Boolean(db);
11
12
  if (!isValidDb) return { count: 0, threshold: 0.85, pairs: [] };
12
13
 
13
- const threshold = typeof options.threshold === 'number' ? options.threshold : 0.85;
14
+ const hasNumericThreshold = typeof options.threshold === 'number';
15
+ const threshold = hasNumericThreshold ? options.threshold : 0.85;
14
16
  const limit = options.limit || 50;
15
17
 
16
18
  const rows = db.prepare(
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Where comments sit on a source line, outside string literals, so a `chemx-allow:` marker
3
+ * quoted in a string never counts as an annotation. One pass per line; the state carries an
4
+ * open block comment and an open template literal into the next line.
5
+ *
6
+ * Known gaps (they err towards flagging): a lone apostrophe in markup text or a quote inside
7
+ * a regex literal opens a string for the rest of that line, and C# verbatim strings are read
8
+ * with backslash escapes.
9
+ */
10
+ const BLOCK_OPENERS = [['/*', '*/'], ['<!--', '-->']];
11
+ const QUOTES = new Set(['"', "'", '`']);
12
+ const BACKSLASH = '\\';
13
+ const CARRIED_QUOTE = '`';
14
+
15
+ export const INITIAL_SCAN_STATE = Object.freeze({ inBlock: false, blockCloser: null, quote: null });
16
+
17
+ const findBlockOpener = (line, index) => BLOCK_OPENERS.find(([opener]) => line.startsWith(opener, index));
18
+
19
+ const isHashComment = (line, index) => line[index] === '#' && (index === 0 || /\s/.test(line[index - 1]));
20
+
21
+ const isLineCommentStart = (line, index) => line.startsWith('//', index) || isHashComment(line, index);
22
+
23
+ // Index just past the string that is open at index (quote already consumed), or -1 when it
24
+ // runs past the end of the line.
25
+ const skipString = (line, index, quote) => {
26
+ let cursor = index;
27
+ while (cursor < line.length) {
28
+ const char = line[cursor];
29
+ const isEscape = char === BACKSLASH;
30
+ const isClosingQuote = char === quote;
31
+ if (isClosingQuote) return cursor + 1;
32
+ cursor += isEscape ? 2 : 1;
33
+ }
34
+ return -1;
35
+ };
36
+
37
+ /**
38
+ * Comment regions on one line as [start, end) column pairs, and the state for the next line.
39
+ */
40
+ export const scanCommentRegions = (line, state = INITIAL_SCAN_STATE) => {
41
+ const regions = [];
42
+ let { inBlock, blockCloser, quote } = state;
43
+ let regionStart = 0;
44
+ let index = 0;
45
+ while (index < line.length) {
46
+ if (inBlock) {
47
+ const closeAt = line.indexOf(blockCloser, index);
48
+ const isStillOpen = closeAt === -1;
49
+ if (isStillOpen) break;
50
+ regions.push([regionStart, closeAt + blockCloser.length]);
51
+ index = closeAt + blockCloser.length;
52
+ inBlock = false;
53
+ continue;
54
+ }
55
+ if (quote) {
56
+ const afterString = skipString(line, index, quote);
57
+ const isUnterminated = afterString === -1;
58
+ if (isUnterminated) break;
59
+ quote = null;
60
+ index = afterString;
61
+ continue;
62
+ }
63
+ if (isLineCommentStart(line, index)) {
64
+ regions.push([index, line.length]);
65
+ index = line.length;
66
+ break;
67
+ }
68
+ const block = findBlockOpener(line, index);
69
+ if (block) {
70
+ inBlock = true;
71
+ blockCloser = block[1];
72
+ regionStart = index;
73
+ index += block[0].length;
74
+ continue;
75
+ }
76
+ const isQuote = QUOTES.has(line[index]);
77
+ if (isQuote) quote = line[index];
78
+ index += 1;
79
+ }
80
+ if (inBlock) regions.push([regionStart, line.length]);
81
+ const carriedQuote = quote === CARRIED_QUOTE ? quote : null;
82
+ return { regions, state: { inBlock, blockCloser: inBlock ? blockCloser : null, quote: carriedQuote } };
83
+ };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Audit coverage: how much of each scanned file the AST rules actually saw. A file
3
+ * that only got line-level text checks (unsupported language, --fast, parse error,
4
+ * an SFC template that failed to parse) is reported as partial so a low hazard
5
+ * count is never presented as a confident pass.
6
+ */
7
+ export const COVERAGE_KINDS = Object.freeze({
8
+ AST: 'ast',
9
+ TEXT_ONLY: 'text-only',
10
+ PARSE_ERROR: 'parse-error',
11
+ EMPTY: 'empty'
12
+ });
13
+
14
+ export const createCoverageCollector = () => ({ files: [] });
15
+
16
+ /** Records one file. `sfc` is { scriptBlocks, hasTemplate, isTemplateParsed } for .vue files. */
17
+ export const recordFileCoverage = (collector, { relativePath, kind, sfc = null }) => {
18
+ if (!collector) return;
19
+ collector.files.push({ relativePath, kind, sfc });
20
+ };
21
+
22
+ const isPartialEntry = (entry) => {
23
+ const isAstless = entry.kind !== COVERAGE_KINDS.AST && entry.kind !== COVERAGE_KINDS.EMPTY;
24
+ const hasUnparsedTemplate = Boolean(entry.sfc?.hasTemplate) && !entry.sfc?.isTemplateParsed;
25
+ return isAstless || hasUnparsedTemplate;
26
+ };
27
+
28
+ export const summarizeCoverage = (collector) => {
29
+ const entries = collector?.files ?? [];
30
+ const countKind = (kind) => entries.filter((e) => e.kind === kind).length;
31
+ const sfcEntries = entries.filter((e) => e.sfc);
32
+ const partialFiles = entries.filter(isPartialEntry).map((e) => e.relativePath);
33
+ const astFiles = countKind(COVERAGE_KINDS.AST);
34
+ return {
35
+ files: entries.length,
36
+ astParsed: astFiles,
37
+ textOnly: countKind(COVERAGE_KINDS.TEXT_ONLY),
38
+ parseErrors: countKind(COVERAGE_KINDS.PARSE_ERROR),
39
+ astPct: entries.length > 0 ? Math.round((astFiles / entries.length) * 100) : 100,
40
+ sfc: {
41
+ files: sfcEntries.length,
42
+ scriptBlocks: sfcEntries.reduce((sum, e) => sum + (e.sfc.scriptBlocks ?? 0), 0),
43
+ templatesParsed: sfcEntries.filter((e) => e.sfc.isTemplateParsed).length
44
+ },
45
+ isPartial: partialFiles.length > 0,
46
+ partialFiles: partialFiles.slice(0, 20)
47
+ };
48
+ };