@miller-tech/uap 1.221.0 → 2.0.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 (238) hide show
  1. package/README.md +19 -9
  2. package/config/exl3-profiles/qwen38-27b-exl3.env +68 -0
  3. package/config/llama-profiles/qwen38-27b-dflash2.env +6 -1
  4. package/dist/.tsbuildinfo +1 -1
  5. package/dist/benchmarks/paired/adapter.d.ts +15 -0
  6. package/dist/benchmarks/paired/adapter.d.ts.map +1 -1
  7. package/dist/benchmarks/paired/adapter.js +22 -1
  8. package/dist/benchmarks/paired/adapter.js.map +1 -1
  9. package/dist/bin/cli.js +20 -24
  10. package/dist/bin/cli.js.map +1 -1
  11. package/dist/cli/deliver.d.ts +34 -0
  12. package/dist/cli/deliver.d.ts.map +1 -1
  13. package/dist/cli/deliver.js +147 -20
  14. package/dist/cli/deliver.js.map +1 -1
  15. package/dist/cli/guided-setup.d.ts.map +1 -1
  16. package/dist/cli/guided-setup.js +15 -0
  17. package/dist/cli/guided-setup.js.map +1 -1
  18. package/dist/cli/init.d.ts.map +1 -1
  19. package/dist/cli/init.js +3 -0
  20. package/dist/cli/init.js.map +1 -1
  21. package/dist/cli/plan.d.ts.map +1 -1
  22. package/dist/cli/plan.js +8 -2
  23. package/dist/cli/plan.js.map +1 -1
  24. package/dist/cli/policy.d.ts.map +1 -1
  25. package/dist/cli/policy.js +104 -2
  26. package/dist/cli/policy.js.map +1 -1
  27. package/dist/cli/quality.d.ts +11 -0
  28. package/dist/cli/quality.d.ts.map +1 -0
  29. package/dist/cli/quality.js +213 -0
  30. package/dist/cli/quality.js.map +1 -0
  31. package/dist/cli/wizard-config.d.ts.map +1 -1
  32. package/dist/cli/wizard-config.js +19 -9
  33. package/dist/cli/wizard-config.js.map +1 -1
  34. package/dist/cli/worktree.d.ts.map +1 -1
  35. package/dist/cli/worktree.js +8 -1
  36. package/dist/cli/worktree.js.map +1 -1
  37. package/dist/dashboard/savings.d.ts +1 -4
  38. package/dist/dashboard/savings.d.ts.map +1 -1
  39. package/dist/dashboard/savings.js +2 -52
  40. package/dist/dashboard/savings.js.map +1 -1
  41. package/dist/delivery/acceptance-judge.d.ts +10 -0
  42. package/dist/delivery/acceptance-judge.d.ts.map +1 -1
  43. package/dist/delivery/acceptance-judge.js +45 -3
  44. package/dist/delivery/acceptance-judge.js.map +1 -1
  45. package/dist/delivery/agentic-executor.d.ts +12 -1
  46. package/dist/delivery/agentic-executor.d.ts.map +1 -1
  47. package/dist/delivery/agentic-executor.js +25 -5
  48. package/dist/delivery/agentic-executor.js.map +1 -1
  49. package/dist/delivery/bash-sweep.d.ts +12 -0
  50. package/dist/delivery/bash-sweep.d.ts.map +1 -1
  51. package/dist/delivery/bash-sweep.js +8 -1
  52. package/dist/delivery/bash-sweep.js.map +1 -1
  53. package/dist/delivery/convergence-loop.d.ts.map +1 -1
  54. package/dist/delivery/convergence-loop.js +6 -4
  55. package/dist/delivery/convergence-loop.js.map +1 -1
  56. package/dist/delivery/execution-gate.d.ts +1 -1
  57. package/dist/delivery/execution-gate.d.ts.map +1 -1
  58. package/dist/delivery/execution-gate.js +248 -5
  59. package/dist/delivery/execution-gate.js.map +1 -1
  60. package/dist/delivery/snapshot.d.ts +16 -0
  61. package/dist/delivery/snapshot.d.ts.map +1 -1
  62. package/dist/delivery/snapshot.js +113 -2
  63. package/dist/delivery/snapshot.js.map +1 -1
  64. package/dist/delivery/user-validation.d.ts.map +1 -1
  65. package/dist/delivery/user-validation.js +55 -10
  66. package/dist/delivery/user-validation.js.map +1 -1
  67. package/dist/delivery/verifier-ladder.d.ts +24 -0
  68. package/dist/delivery/verifier-ladder.d.ts.map +1 -1
  69. package/dist/delivery/verifier-ladder.js +119 -2
  70. package/dist/delivery/verifier-ladder.js.map +1 -1
  71. package/dist/delivery/visual-gate.d.ts +24 -0
  72. package/dist/delivery/visual-gate.d.ts.map +1 -1
  73. package/dist/delivery/visual-gate.js +70 -9
  74. package/dist/delivery/visual-gate.js.map +1 -1
  75. package/dist/generators/claude-md.js +17 -4
  76. package/dist/generators/claude-md.js.map +1 -1
  77. package/dist/policies/liveness.d.ts +105 -0
  78. package/dist/policies/liveness.d.ts.map +1 -0
  79. package/dist/policies/liveness.js +251 -0
  80. package/dist/policies/liveness.js.map +1 -0
  81. package/dist/policies/policy-memory.d.ts.map +1 -1
  82. package/dist/policies/policy-memory.js +3 -4
  83. package/dist/policies/policy-memory.js.map +1 -1
  84. package/dist/quality/baseline.d.ts +29 -0
  85. package/dist/quality/baseline.d.ts.map +1 -0
  86. package/dist/quality/baseline.js +79 -0
  87. package/dist/quality/baseline.js.map +1 -0
  88. package/dist/quality/complexity.d.ts +38 -0
  89. package/dist/quality/complexity.d.ts.map +1 -0
  90. package/dist/quality/complexity.js +239 -0
  91. package/dist/quality/complexity.js.map +1 -0
  92. package/dist/quality/config.d.ts +40 -0
  93. package/dist/quality/config.d.ts.map +1 -0
  94. package/dist/quality/config.js +77 -0
  95. package/dist/quality/config.js.map +1 -0
  96. package/dist/quality/crap.d.ts +11 -0
  97. package/dist/quality/crap.d.ts.map +1 -0
  98. package/dist/quality/crap.js +54 -0
  99. package/dist/quality/crap.js.map +1 -0
  100. package/dist/quality/languages.d.ts +25 -0
  101. package/dist/quality/languages.d.ts.map +1 -0
  102. package/dist/quality/languages.js +150 -0
  103. package/dist/quality/languages.js.map +1 -0
  104. package/dist/quality/report.d.ts +38 -0
  105. package/dist/quality/report.d.ts.map +1 -0
  106. package/dist/quality/report.js +251 -0
  107. package/dist/quality/report.js.map +1 -0
  108. package/dist/quality/scanner.d.ts +32 -0
  109. package/dist/quality/scanner.d.ts.map +1 -0
  110. package/dist/quality/scanner.js +127 -0
  111. package/dist/quality/scanner.js.map +1 -0
  112. package/dist/quality/tools.d.ts +28 -0
  113. package/dist/quality/tools.d.ts.map +1 -0
  114. package/dist/quality/tools.js +189 -0
  115. package/dist/quality/tools.js.map +1 -0
  116. package/dist/types/config.d.ts +148 -0
  117. package/dist/types/config.d.ts.map +1 -1
  118. package/dist/types/config.js +35 -0
  119. package/dist/types/config.js.map +1 -1
  120. package/docs/ATTRIBUTION.md +0 -1
  121. package/docs/INDEX.md +38 -4
  122. package/docs/analysis/MARKET_POSITION.md +179 -0
  123. package/docs/architecture/OVERVIEW.md +82 -18
  124. package/docs/architecture/PROTOCOL.md +1 -1
  125. package/docs/benchmarks/PAIRED_FINDINGS.md +106 -0
  126. package/docs/benchmarks/PAIRED_HARNESS.md +16 -0
  127. package/docs/benchmarks/README.md +59 -0
  128. package/docs/design/UAP_REACTOR.md +0 -1
  129. package/docs/getting-started/INSTALLATION.md +1 -1
  130. package/docs/guides/AUTOMATIC.md +0 -14
  131. package/docs/guides/AUTOMATIC_FEATURES.md +1 -9
  132. package/docs/guides/COORDINATION.md +1 -1
  133. package/docs/guides/DELIVERY_PIPELINE.md +5 -0
  134. package/docs/guides/DEPLOY_BATCHING.md +1 -1
  135. package/docs/guides/DROIDS_AND_SKILLS.md +1 -1
  136. package/docs/guides/LOCAL_MODELS.md +6 -1
  137. package/docs/guides/MCP_ROUTER.md +1 -1
  138. package/docs/guides/MEMORY.md +1 -1
  139. package/docs/guides/MULTI_MODEL.md +1 -1
  140. package/docs/guides/ORCHESTRATOR.md +1 -1
  141. package/docs/guides/POLICIES.md +19 -3
  142. package/docs/guides/QWEN38_EXL3.md +114 -0
  143. package/docs/guides/WORKTREE_WORKFLOW.md +45 -1
  144. package/docs/integrations/MCP_ROUTER.md +1 -4
  145. package/docs/plans/deliver-hardening-plan-2026-07-13.md +173 -0
  146. package/docs/plans/deliver-hardening-review-response-2026-07-13.md +180 -0
  147. package/docs/plans/k3-uap-uplift-validation.md +216 -0
  148. package/docs/plans/qwen38-uap-retest-plan.md +196 -0
  149. package/docs/reference/API.md +1 -1
  150. package/docs/reference/CLI.md +49 -14
  151. package/docs/reference/COMPARISON.md +248 -0
  152. package/docs/reference/CONFIGURATION.md +1 -3
  153. package/docs/reference/DATABASE_SCHEMA.md +1 -1
  154. package/docs/reference/FEATURES.md +3 -3
  155. package/docs/reference/PATTERNS.md +1 -1
  156. package/docs/reference/PLATFORMS.md +1 -1
  157. package/package.json +2 -2
  158. package/scripts/maintenance/update-skills.py +0 -22
  159. package/scripts/maintenance/verify-compliance.sh +3 -3
  160. package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
  161. package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-312.pyc +0 -0
  162. package/src/policies/enforcers/adr_guard.py +0 -0
  163. package/src/policies/enforcers/bearer_lockdown.py +0 -0
  164. package/src/policies/enforcers/branch_freshness.py +0 -0
  165. package/src/policies/enforcers/design_token_gate.py +0 -0
  166. package/src/policies/enforcers/enforcement_self_protect.py +70 -0
  167. package/src/policies/enforcers/expert_review_required.py +22 -0
  168. package/src/policies/enforcers/iac_plan_destruction_check.py +0 -0
  169. package/src/policies/enforcers/quality_metrics_gate.py +447 -0
  170. package/src/policies/enforcers/ship_loop_gate.py +0 -0
  171. package/src/policies/enforcers/validate_plan_on_change.py +0 -0
  172. package/src/policies/enforcers/visual_verification.py +0 -0
  173. package/src/policies/enforcers/workdir_scope.py +0 -0
  174. package/src/policies/schemas/policies/expert-review-required.md +9 -1
  175. package/src/policies/schemas/policies/quality-metrics-gate.md +74 -0
  176. package/templates/CLAUDE.template.md +1 -1
  177. package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
  178. package/templates/hooks/pre-tool-use-bash.sh +50 -3
  179. package/templates/hooks/pre-tool-use-edit-write.sh +31 -0
  180. package/templates/hooks/session-start.sh +15 -0
  181. package/templates/hooks/uap-policy-gate.sh +187 -5
  182. package/templates/stryker.config.json +14 -0
  183. package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
  184. package/tools/agents/scripts/anthropic_proxy.py +254 -28
  185. package/tools/agents/tests/run_acceptance.py +0 -0
  186. package/tools/agents/tests/test_client_disconnect.py +0 -0
  187. package/tools/agents/tests/test_cycle_break_exploration.py +0 -0
  188. package/tools/agents/tests/test_deferral_break.py +0 -0
  189. package/tools/agents/tests/test_delivery_enforcement_all_langs.py +0 -0
  190. package/tools/agents/tests/test_delivery_enforcement_exemptions.py +0 -0
  191. package/tools/agents/tests/test_delivery_enforcement_filepath.py +0 -0
  192. package/tools/agents/tests/test_delivery_enforcement_web_and_bash.py +0 -0
  193. package/tools/agents/tests/test_delivery_enforcement_worktree.py +0 -0
  194. package/tools/agents/tests/test_delivery_enforcement_write_complexity.py +0 -0
  195. package/tools/agents/tests/test_disconnect_watcher.py +0 -0
  196. package/tools/agents/tests/test_doubling_break.py +0 -0
  197. package/tools/agents/tests/test_empty_maxtokens_recovery.py +0 -0
  198. package/tools/agents/tests/test_empty_tool_loop_break.py +0 -0
  199. package/tools/agents/tests/test_enforcement_self_protect.py +90 -0
  200. package/tools/agents/tests/test_enforcer_escape_hatches.py +0 -0
  201. package/tools/agents/tests/test_error_loop_break.py +0 -0
  202. package/tools/agents/tests/test_expert_review_pr_scope.py +13 -5
  203. package/tools/agents/tests/test_fastpath_config.py +0 -0
  204. package/tools/agents/tests/test_finalize_suppression.py +0 -0
  205. package/tools/agents/tests/test_gate_evidence.py +0 -0
  206. package/tools/agents/tests/test_gate_failclosed_indirection.py +0 -0
  207. package/tools/agents/tests/test_gate_integrity.py +0 -0
  208. package/tools/agents/tests/test_live_deliver_kill.py +0 -0
  209. package/tools/agents/tests/test_malformed_unclosed_think.py +0 -0
  210. package/tools/agents/tests/test_mandate_beats_recon.py +0 -0
  211. package/tools/agents/tests/test_mandate_deliver.py +0 -0
  212. package/tools/agents/tests/test_non_stream_resp_log.py +0 -0
  213. package/tools/agents/tests/test_output_token_ceilings.py +0 -0
  214. package/tools/agents/tests/test_overflow_truncate_count_tokens.py +0 -0
  215. package/tools/agents/tests/test_path_containment.py +0 -0
  216. package/tools/agents/tests/test_path_normalizer_hardened.py +0 -0
  217. package/tools/agents/tests/test_repeat_call_guard.py +0 -0
  218. package/tools/agents/tests/test_repeat_guard.py +0 -0
  219. package/tools/agents/tests/test_session_admission.py +0 -0
  220. package/tools/agents/tests/test_stream_heartbeat.py +0 -0
  221. package/tools/agents/tests/test_stream_thinking_deltas.py +405 -0
  222. package/tools/agents/tests/test_stuck_break_hard.py +0 -0
  223. package/tools/agents/tests/test_stuck_break_reattach.py +0 -0
  224. package/tools/agents/tests/test_turn_count_breaker_periodic.py +0 -0
  225. package/tools/agents/tests/test_upstream_chokepoint.py +0 -0
  226. package/tools/agents/tests/test_upstream_model_aliases.py +0 -0
  227. package/tools/agents/tests/test_validate_plan_gate.py +0 -0
  228. package/tools/agents/tests/test_vision_passthrough.py +0 -0
  229. package/tools/agents/tests/test_workdir_scope_enforcer.py +0 -0
  230. package/dist/cli/rtk.d.ts +0 -34
  231. package/dist/cli/rtk.d.ts.map +0 -1
  232. package/dist/cli/rtk.js +0 -401
  233. package/dist/cli/rtk.js.map +0 -1
  234. package/docs/integrations/RTK.md +0 -113
  235. package/scripts/setup/install-rtk.sh +0 -184
  236. package/src/policies/enforcers/rtk_wrap.py +0 -205
  237. package/src/policies/schemas/policies/rtk-wrap.md +0 -50
  238. package/tools/agents/tests/test_rtk_wrap.py +0 -151
@@ -0,0 +1,38 @@
1
+ import { QualityConfig } from './config.js';
2
+ import { Violation, MetricId } from './scanner.js';
3
+ import { ToolStatus } from './tools.js';
4
+ export interface QualityReport {
5
+ root: string;
6
+ filesScanned: number;
7
+ violations: Violation[];
8
+ blocking: Violation[];
9
+ grandfathered: Violation[];
10
+ improved: Array<{
11
+ violation: Violation;
12
+ baselineValue: number;
13
+ }>;
14
+ /** Metrics skipped because their tool/data source is unavailable. */
15
+ skipped: Array<{
16
+ metric: string;
17
+ reason: string;
18
+ }>;
19
+ tools: ToolStatus[];
20
+ pass: boolean;
21
+ baselinePresent: boolean;
22
+ }
23
+ /** Recursively collect scannable source files under root/src (or root). */
24
+ export declare function collectSourceFiles(root: string, config: QualityConfig): string[];
25
+ /** Files changed vs the upstream base PLUS staged/unstaged/untracked work —
26
+ * a per-commit gate that only sees committed diffs would miss the commit's
27
+ * actual content. */
28
+ export declare function changedFiles(root: string, config: QualityConfig): string[];
29
+ export interface ReportOptions {
30
+ /** Explicit relative file list; default: full scan of collectSourceFiles. */
31
+ files?: string[];
32
+ /** Skip external tools even when installed (fast path / tests). */
33
+ builtinOnly?: boolean;
34
+ }
35
+ /** Build the full quality report for a set of files. */
36
+ export declare function buildReport(root: string, config: QualityConfig, options?: ReportOptions): QualityReport;
37
+ export type { MetricId };
38
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/quality/report.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAkC,QAAQ,EAAE,MAAM,cAAc,CAAC;AAInF,OAAO,EACL,UAAU,EACX,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,aAAa,EAAE,SAAS,EAAE,CAAC;IAC3B,QAAQ,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,SAAS,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,qEAAqE;IACrE,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,EAAE,CA6BhF;AAED;;qBAEqB;AACrB,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,EAAE,CA6B1E;AAED,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,mEAAmE;IACnE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAkJD,wDAAwD;AACxD,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE,aAAkB,GAC1B,aAAa,CA4Bf;AAED,YAAY,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Quality report orchestration: collect files, run every available metric,
3
+ * merge external-tool numbers over built-in heuristics, compute CRAP from
4
+ * coverage, and split violations into blocking vs grandfathered via the
5
+ * ratchet baseline.
6
+ */
7
+ import { existsSync, readFileSync, readdirSync, statSync } from 'fs';
8
+ import { join, relative } from 'path';
9
+ import { execSync } from 'child_process';
10
+ import { isScannableSource, scanContent } from './scanner.js';
11
+ import { analyzeComplexity } from './complexity.js';
12
+ import { languageForFile } from './languages.js';
13
+ import { crapScore, coverageFor, loadCoverageSummary } from './crap.js';
14
+ import { jscpdViolations, lizardViolations, probeTools, rcaViolations, } from './tools.js';
15
+ import { loadBaseline, ratchet } from './baseline.js';
16
+ /** Recursively collect scannable source files under root/src (or root). */
17
+ export function collectSourceFiles(root, config) {
18
+ const seeds = ['src', 'tools', 'scripts', 'web'].filter((d) => existsSync(join(root, d)));
19
+ const dirs = seeds.length > 0 ? seeds : ['.'];
20
+ const out = [];
21
+ const walk = (dir) => {
22
+ let entries;
23
+ try {
24
+ entries = readdirSync(dir);
25
+ }
26
+ catch {
27
+ return;
28
+ }
29
+ for (const name of entries) {
30
+ const p = join(dir, name);
31
+ let st;
32
+ try {
33
+ st = statSync(p);
34
+ }
35
+ catch {
36
+ continue;
37
+ }
38
+ if (st.isDirectory()) {
39
+ if (!config.excludeDirs.includes(name))
40
+ walk(p);
41
+ continue;
42
+ }
43
+ const rel = relative(root, p).replace(/\\/g, '/');
44
+ if (isScannableSource(rel, config))
45
+ out.push(rel);
46
+ }
47
+ };
48
+ for (const d of dirs)
49
+ walk(join(root, d));
50
+ return out.sort();
51
+ }
52
+ /** Files changed vs the upstream base PLUS staged/unstaged/untracked work —
53
+ * a per-commit gate that only sees committed diffs would miss the commit's
54
+ * actual content. */
55
+ export function changedFiles(root, config) {
56
+ const found = new Set();
57
+ const tryGit = (args) => {
58
+ try {
59
+ const out = execSync(`git ${args}`, { cwd: root, encoding: 'utf-8', timeout: 10_000 });
60
+ for (const l of out.split('\n')) {
61
+ const f = l.trim();
62
+ if (f)
63
+ found.add(f);
64
+ }
65
+ return true;
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ };
71
+ let baseResolved = false;
72
+ for (const base of ['origin/master', 'origin/main', 'master', 'main']) {
73
+ if (tryGit(`diff --name-only ${base}...HEAD`)) {
74
+ baseResolved = true;
75
+ break;
76
+ }
77
+ }
78
+ // Uncommitted work: staged, unstaged, and untracked source files.
79
+ tryGit('diff --name-only --cached');
80
+ tryGit('diff --name-only');
81
+ tryGit('ls-files --others --exclude-standard');
82
+ if (!baseResolved && found.size === 0) {
83
+ console.error('quality: no upstream base resolvable and no working-tree changes — scanning nothing');
84
+ }
85
+ return [...found].filter((f) => isScannableSource(f, config)).sort();
86
+ }
87
+ /** Stage 1: the always-available built-in scan. */
88
+ function builtinScan(root, files, config) {
89
+ const out = [];
90
+ for (const f of files) {
91
+ let content = '';
92
+ try {
93
+ content = readFileSync(join(root, f), 'utf-8');
94
+ }
95
+ catch {
96
+ continue;
97
+ }
98
+ out.push(...scanContent(f, content, config));
99
+ }
100
+ return out;
101
+ }
102
+ function hasTool(tools, name) {
103
+ return tools.some((t) => t.name === name && t.available);
104
+ }
105
+ /** Stage 2a: lizard's authoritative cyclomatic/NLOC numbers replace the
106
+ * built-in ones when lizard is installed. */
107
+ function applyLizard(violations, files, root, config, options, skipped) {
108
+ if (options.builtinOnly)
109
+ return violations;
110
+ if (!hasTool(probeCached(options), 'lizard')) {
111
+ skipped.push({ metric: 'cyclomatic(authoritative)', reason: 'lizard not installed — built-in heuristic used' });
112
+ return violations;
113
+ }
114
+ const lv = lizardViolations(files.map((f) => join(root, f)), root, config);
115
+ if (!lv)
116
+ return violations;
117
+ return [...violations.filter((v) => v.metric !== 'cyclomatic' && v.metric !== 'locPerFile'), ...lv];
118
+ }
119
+ /** Stage 2b: rust-code-analysis cognitive/Halstead replaces built-in
120
+ * cognitive when installed. */
121
+ function applyRca(violations, files, root, config, options, skipped) {
122
+ if (options.builtinOnly)
123
+ return violations;
124
+ if (!hasTool(probeCached(options), 'rust-code-analysis')) {
125
+ skipped.push({ metric: 'halsteadDifficulty', reason: 'rust-code-analysis not installed' });
126
+ return violations;
127
+ }
128
+ const rv = rcaViolations(files.map((f) => join(root, f)), root, config);
129
+ if (!rv)
130
+ return violations;
131
+ return [...violations.filter((v) => v.metric !== 'cognitive'), ...rv];
132
+ }
133
+ /** Stage 3: coverage deficit + per-function CRAP, from vitest's
134
+ * coverage/coverage-summary.json. */
135
+ function coverageStage(root, files, config, skipped) {
136
+ const coverage = loadCoverageSummary(root);
137
+ if (!coverage) {
138
+ skipped.push({ metric: 'coverage', reason: 'no coverage/coverage-summary.json (run npm run test:coverage)' });
139
+ skipped.push({ metric: 'crap', reason: 'needs coverage data' });
140
+ return [];
141
+ }
142
+ const t = config.thresholds;
143
+ const out = [];
144
+ for (const f of files) {
145
+ const cov = coverageFor(coverage, root, f);
146
+ if (cov === null)
147
+ continue;
148
+ if (cov * 100 < t.minCoveragePct) {
149
+ // The ratchet treats HIGHER value as worse, but coverage is better
150
+ // when higher — store the DEFICIT (threshold − pct) so a coverage
151
+ // regression ratchets up and an improvement ratchets down, like
152
+ // every other metric.
153
+ const deficit = Math.round((t.minCoveragePct - cov * 100) * 10) / 10;
154
+ out.push({
155
+ file: f,
156
+ metric: 'coverage',
157
+ value: deficit,
158
+ threshold: t.minCoveragePct,
159
+ signature: `${f}::coverage::<file>`,
160
+ message: `${f}: ${(cov * 100).toFixed(1)}% line coverage below min ${t.minCoveragePct}% (deficit ${deficit})`,
161
+ });
162
+ }
163
+ out.push(...crapViolations(root, f, cov, t.maxCrap));
164
+ }
165
+ return out;
166
+ }
167
+ /** CRAP per function: file coverage × function complexity. */
168
+ function crapViolations(root, f, cov, maxCrap) {
169
+ const lang = languageForFile(f);
170
+ if (!lang)
171
+ return [];
172
+ let content = '';
173
+ try {
174
+ content = readFileSync(join(root, f), 'utf-8');
175
+ }
176
+ catch {
177
+ return [];
178
+ }
179
+ const out = [];
180
+ for (const fn of analyzeComplexity(content, lang).functions) {
181
+ const score = crapScore(fn.cyclomatic, cov);
182
+ if (score > maxCrap) {
183
+ out.push({
184
+ file: f,
185
+ metric: 'crap',
186
+ value: Math.round(score * 10) / 10,
187
+ threshold: maxCrap,
188
+ signature: `${f}::crap::${fn.name}@${fn.line}`,
189
+ message: `${f}:${fn.line} ${fn.name}() CRAP ${score.toFixed(1)} (cc=${fn.cyclomatic}, cov=${(cov * 100).toFixed(0)}%) exceeds max ${maxCrap}`,
190
+ });
191
+ }
192
+ }
193
+ return out;
194
+ }
195
+ /** Stage 4: jscpd duplication. */
196
+ function duplicationStage(root, config, options, skipped) {
197
+ if (options.builtinOnly)
198
+ return [];
199
+ if (!hasTool(probeCached(options), 'jscpd')) {
200
+ skipped.push({ metric: 'duplicateBlocks', reason: 'jscpd not installed' });
201
+ return [];
202
+ }
203
+ return jscpdViolations(root, config) ?? [];
204
+ }
205
+ /** Stage 5: note metrics that are report-only or have no available tool. */
206
+ function noteUnavailable(options, skipped) {
207
+ if (options.builtinOnly)
208
+ return;
209
+ if (!hasTool(probeCached(options), 'knip') && !hasTool(probeCached(options), 'vulture')) {
210
+ skipped.push({ metric: 'deadCode', reason: 'knip/vulture not installed' });
211
+ }
212
+ skipped.push({ metric: 'survivingMutants', reason: 'run `uap quality mutate` (changed-files incremental)' });
213
+ }
214
+ /** Probe tools once per report; stage helpers read the cached list. */
215
+ const probeCache = new WeakMap();
216
+ function probeCached(options) {
217
+ let t = probeCache.get(options);
218
+ if (!t) {
219
+ t = options.builtinOnly ? [] : probeTools();
220
+ probeCache.set(options, t);
221
+ }
222
+ return t;
223
+ }
224
+ /** Build the full quality report for a set of files. */
225
+ export function buildReport(root, config, options = {}) {
226
+ const files = options.files ?? collectSourceFiles(root, config);
227
+ const skipped = [];
228
+ const tools = probeCached(options);
229
+ let violations = builtinScan(root, files, config);
230
+ violations = applyLizard(violations, files, root, config, options, skipped);
231
+ violations = applyRca(violations, files, root, config, options, skipped);
232
+ violations.push(...coverageStage(root, files, config, skipped));
233
+ violations.push(...duplicationStage(root, config, options, skipped));
234
+ noteUnavailable(options, skipped);
235
+ // Ratchet against the baseline.
236
+ const baseline = loadBaseline(root);
237
+ const r = ratchet(violations, baseline);
238
+ return {
239
+ root,
240
+ filesScanned: files.length,
241
+ violations,
242
+ blocking: r.blocking,
243
+ grandfathered: r.grandfathered,
244
+ improved: r.improved,
245
+ skipped,
246
+ tools,
247
+ pass: r.blocking.length === 0,
248
+ baselinePresent: baseline !== null,
249
+ };
250
+ }
251
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/quality/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { QualityConfig } from './config.js';
2
+ export type MetricId = 'cyclomatic' | 'cognitive' | 'halsteadDifficulty' | 'locPerFile' | 'coverage' | 'crap' | 'survivingMutants' | 'duplicateBlocks' | 'deadCode' | 'anyTypes';
3
+ export interface Violation {
4
+ file: string;
5
+ metric: MetricId;
6
+ /** Measured value (count, complexity, or percent depending on metric). */
7
+ value: number;
8
+ /** Configured threshold that was crossed. */
9
+ threshold: number;
10
+ /**
11
+ * Stable identity for baseline ratcheting: file + metric + the function or
12
+ * site the violation belongs to. Function renames intentionally re-identify
13
+ * a violation (a renamed complex function is reviewed as if new).
14
+ */
15
+ signature: string;
16
+ message: string;
17
+ }
18
+ /** Count explicit any/unknown usages in one file's content. */
19
+ export declare function countAnyTypes(content: string, file: string): {
20
+ count: number;
21
+ lines: number[];
22
+ };
23
+ /**
24
+ * Scan one file's content for the always-available metrics:
25
+ * LOC/file, per-function cyclomatic + cognitive complexity, any-types.
26
+ * Halstead/CRAP/coverage/mutation/duplication/dead-code need external data
27
+ * and are merged later by report.ts.
28
+ */
29
+ export declare function scanContent(file: string, content: string, config: QualityConfig): Violation[];
30
+ /** True when `file` is a scannable source path under the config's rules. */
31
+ export declare function isScannableSource(file: string, config: QualityConfig): boolean;
32
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/quality/scanner.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI5C,MAAM,MAAM,QAAQ,GAChB,YAAY,GACZ,WAAW,GACX,oBAAoB,GACpB,YAAY,GACZ,UAAU,GACV,MAAM,GACN,kBAAkB,GAClB,iBAAiB,GACjB,UAAU,GACV,UAAU,CAAC;AAEf,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,CAAC;IACjB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAyBD,+DAA+D;AAC/D,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAkB/F;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,SAAS,EAAE,CAuD7F;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAQ9E"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * File scanner: turns source content into metric violations.
3
+ *
4
+ * Pure (no I/O beyond what callers hand it) so the CLI, the proxy enforcer's
5
+ * TS-side parity tests, and future callers all share one code path. External
6
+ * tool overrides (lizard numbers, jscpd clones, coverage) are merged in by
7
+ * report.ts — this module is the always-available built-in layer.
8
+ */
9
+ import { extname } from 'path';
10
+ import { languageForFile, stripNoise } from './languages.js';
11
+ import { analyzeComplexity } from './complexity.js';
12
+ /** Explicit any/unknown usage patterns, per language family. Built from
13
+ * strings (not regex literals) on purpose: string contents are stripped
14
+ * before scanning, so this file does not trip the gate over its own
15
+ * patterns. */
16
+ const ANY_PATTERNS = [
17
+ // `: any`, `as any`, `<any>`, `Array<any>`, `Record<string, unknown>`, …
18
+ {
19
+ langs: ['typescript'],
20
+ re: new RegExp(':\\s*any\\b|:\\s*unknown\\b|\\bas\\s+any\\b|<any>|<unknown>|Array<\\s*any\\s*>', 'g'),
21
+ label: 'explicit any/unknown',
22
+ },
23
+ {
24
+ langs: ['javascript'],
25
+ re: new RegExp('/\\*\\s*@type\\s*\\{[^}]*\\b(?:any|unknown)\\b[^}]*\\}\\s*\\*/', 'g'),
26
+ label: 'JSDoc any/unknown',
27
+ },
28
+ {
29
+ langs: ['python'],
30
+ re: new RegExp(':\\s*Any\\b|->\\s*Any\\b|cast\\(\\s*Any\\b', 'g'),
31
+ label: 'typing.Any',
32
+ },
33
+ ];
34
+ /** Count explicit any/unknown usages in one file's content. */
35
+ export function countAnyTypes(content, file) {
36
+ const lang = languageForFile(file);
37
+ if (!lang)
38
+ return { count: 0, lines: [] };
39
+ const stripped = stripNoise(content, lang.commentStyle);
40
+ const lines = stripped.split('\n');
41
+ const hits = [];
42
+ for (const pat of ANY_PATTERNS) {
43
+ if (!pat.langs.includes(lang.name))
44
+ continue;
45
+ for (let i = 0; i < lines.length; i++) {
46
+ pat.re.lastIndex = 0;
47
+ let m;
48
+ while ((m = pat.re.exec(lines[i])) !== null) {
49
+ hits.push(i + 1);
50
+ if (m[0].length === 0)
51
+ pat.re.lastIndex++; // safety for zero-width
52
+ }
53
+ }
54
+ }
55
+ return { count: hits.length, lines: [...new Set(hits)].sort((a, b) => a - b) };
56
+ }
57
+ /**
58
+ * Scan one file's content for the always-available metrics:
59
+ * LOC/file, per-function cyclomatic + cognitive complexity, any-types.
60
+ * Halstead/CRAP/coverage/mutation/duplication/dead-code need external data
61
+ * and are merged later by report.ts.
62
+ */
63
+ export function scanContent(file, content, config) {
64
+ const lang = languageForFile(file);
65
+ if (!lang)
66
+ return [];
67
+ const t = config.thresholds;
68
+ const out = [];
69
+ const { functions, loc } = analyzeComplexity(content, lang);
70
+ if (loc > t.maxLocPerFile) {
71
+ out.push({
72
+ file,
73
+ metric: 'locPerFile',
74
+ value: loc,
75
+ threshold: t.maxLocPerFile,
76
+ signature: `${file}::locPerFile::<file>`,
77
+ message: `${file}: ${loc} LOC exceeds max ${t.maxLocPerFile}`,
78
+ });
79
+ }
80
+ for (const fn of functions) {
81
+ if (fn.cyclomatic > t.maxCyclomatic) {
82
+ out.push({
83
+ file,
84
+ metric: 'cyclomatic',
85
+ value: fn.cyclomatic,
86
+ threshold: t.maxCyclomatic,
87
+ signature: `${file}::cyclomatic::${fn.name}@${fn.line}`,
88
+ message: `${file}:${fn.line} ${fn.name}() cyclomatic ${fn.cyclomatic} exceeds max ${t.maxCyclomatic}`,
89
+ });
90
+ }
91
+ if (fn.cognitive > t.maxCognitive) {
92
+ out.push({
93
+ file,
94
+ metric: 'cognitive',
95
+ value: fn.cognitive,
96
+ threshold: t.maxCognitive,
97
+ signature: `${file}::cognitive::${fn.name}@${fn.line}`,
98
+ message: `${file}:${fn.line} ${fn.name}() cognitive ${fn.cognitive} exceeds max ${t.maxCognitive}`,
99
+ });
100
+ }
101
+ }
102
+ const anyResult = countAnyTypes(content, file);
103
+ if (anyResult.count > t.maxAnyTypes) {
104
+ out.push({
105
+ file,
106
+ metric: 'anyTypes',
107
+ value: anyResult.count,
108
+ threshold: t.maxAnyTypes,
109
+ signature: `${file}::anyTypes::<file>`,
110
+ message: `${file}: ${anyResult.count} explicit any/unknown usage(s) (lines ${anyResult.lines.slice(0, 8).join(',')}) exceed max ${t.maxAnyTypes}`,
111
+ });
112
+ }
113
+ return out;
114
+ }
115
+ /** True when `file` is a scannable source path under the config's rules. */
116
+ export function isScannableSource(file, config) {
117
+ const norm = file.replace(/\\/g, '/');
118
+ const ext = extname(norm).toLowerCase();
119
+ if (!config.sourceExts.includes(ext))
120
+ return false;
121
+ for (const dir of config.excludeDirs) {
122
+ if (norm.includes(`/${dir}/`) || norm.startsWith(`${dir}/`))
123
+ return false;
124
+ }
125
+ return true;
126
+ }
127
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/quality/scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AA8BpD;;;eAGe;AACf,MAAM,YAAY,GAA0D;IAC1E,yEAAyE;IACzE;QACE,KAAK,EAAE,CAAC,YAAY,CAAC;QACrB,EAAE,EAAE,IAAI,MAAM,CAAC,gFAAgF,EAAE,GAAG,CAAC;QACrG,KAAK,EAAE,sBAAsB;KAC9B;IACD;QACE,KAAK,EAAE,CAAC,YAAY,CAAC;QACrB,EAAE,EAAE,IAAI,MAAM,CAAC,gEAAgE,EAAE,GAAG,CAAC;QACrF,KAAK,EAAE,mBAAmB;KAC3B;IACD;QACE,KAAK,EAAE,CAAC,QAAQ,CAAC;QACjB,EAAE,EAAE,IAAI,MAAM,CAAC,4CAA4C,EAAE,GAAG,CAAC;QACjE,KAAK,EAAE,YAAY;KACpB;CACF,CAAC;AAEF,+DAA+D;AAC/D,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,IAAY;IACzD,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC1C,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,GAAG,CAAC,EAAE,CAAC,SAAS,GAAG,CAAC,CAAC;YACrB,IAAI,CAAyB,CAAC;YAC9B,OAAO,CAAC,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC5C,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBACjB,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC;oBAAE,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,wBAAwB;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;AACjF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,OAAe,EAAE,MAAqB;IAC9E,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC;IAC5B,MAAM,GAAG,GAAgB,EAAE,CAAC;IAE5B,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAE5D,IAAI,GAAG,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC;QAC1B,GAAG,CAAC,IAAI,CAAC;YACP,IAAI;YACJ,MAAM,EAAE,YAAY;YACpB,KAAK,EAAE,GAAG;YACV,SAAS,EAAE,CAAC,CAAC,aAAa;YAC1B,SAAS,EAAE,GAAG,IAAI,sBAAsB;YACxC,OAAO,EAAE,GAAG,IAAI,KAAK,GAAG,oBAAoB,CAAC,CAAC,aAAa,EAAE;SAC9D,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,IAAI,EAAE,CAAC,UAAU,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC;YACpC,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI;gBACJ,MAAM,EAAE,YAAY;gBACpB,KAAK,EAAE,EAAE,CAAC,UAAU;gBACpB,SAAS,EAAE,CAAC,CAAC,aAAa;gBAC1B,SAAS,EAAE,GAAG,IAAI,iBAAiB,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE;gBACvD,OAAO,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,iBAAiB,EAAE,CAAC,UAAU,gBAAgB,CAAC,CAAC,aAAa,EAAE;aACtG,CAAC,CAAC;QACL,CAAC;QACD,IAAI,EAAE,CAAC,SAAS,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC;YAClC,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI;gBACJ,MAAM,EAAE,WAAW;gBACnB,KAAK,EAAE,EAAE,CAAC,SAAS;gBACnB,SAAS,EAAE,CAAC,CAAC,YAAY;gBACzB,SAAS,EAAE,GAAG,IAAI,gBAAgB,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE;gBACtD,OAAO,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,gBAAgB,EAAE,CAAC,SAAS,gBAAgB,CAAC,CAAC,YAAY,EAAE;aACnG,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC/C,IAAI,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QACpC,GAAG,CAAC,IAAI,CAAC;YACP,IAAI;YACJ,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,SAAS,CAAC,KAAK;YACtB,SAAS,EAAE,CAAC,CAAC,WAAW;YACxB,SAAS,EAAE,GAAG,IAAI,oBAAoB;YACtC,OAAO,EAAE,GAAG,IAAI,KAAK,SAAS,CAAC,KAAK,yCAAyC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,WAAW,EAAE;SAClJ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,MAAqB;IACnE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACnD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IAC5E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { Violation } from './scanner.js';
2
+ import { QualityConfig } from './config.js';
3
+ export declare function toolAvailable(name: string): boolean;
4
+ export interface ToolStatus {
5
+ name: string;
6
+ available: boolean;
7
+ provides: string[];
8
+ }
9
+ /** Probe every optional tool the gate can use. */
10
+ export declare function probeTools(): ToolStatus[];
11
+ /**
12
+ * Run lizard over the given files; returns cyclomatic violations using
13
+ * lizard's authoritative CC numbers. Null when lizard is absent.
14
+ */
15
+ export declare function lizardViolations(files: string[], root: string, config: QualityConfig): Violation[] | null;
16
+ /**
17
+ * Run rust-code-analysis over the given files; returns cognitive-complexity
18
+ * and Halstead-difficulty violations. Null when the tool is absent.
19
+ */
20
+ export declare function rcaViolations(files: string[], root: string, config: QualityConfig): Violation[] | null;
21
+ /**
22
+ * Run jscpd duplication detection. Returns one violation per clone pair over
23
+ * the threshold count. Null when jscpd is absent or the run produced no fresh
24
+ * report (a failed/timed-out run must never re-read a STALE report and block
25
+ * on clones that no longer exist).
26
+ */
27
+ export declare function jscpdViolations(root: string, config: QualityConfig): Violation[] | null;
28
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/quality/tools.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,aAAa,EAAqB,MAAM,aAAa,CAAC;AAE/D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,kDAAkD;AAClD,wBAAgB,UAAU,IAAI,UAAU,EAAE,CASzC;AAuDD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,aAAa,GACpB,SAAS,EAAE,GAAG,IAAI,CAepB;AA8DD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,aAAa,GACpB,SAAS,EAAE,GAAG,IAAI,CAgBpB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,SAAS,EAAE,GAAG,IAAI,CAoCvF"}