@veraxhq/verax 0.3.0 → 0.4.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 (191) hide show
  1. package/README.md +28 -20
  2. package/bin/verax.js +11 -18
  3. package/package.json +28 -7
  4. package/src/cli/commands/baseline.js +1 -2
  5. package/src/cli/commands/default.js +72 -81
  6. package/src/cli/commands/doctor.js +29 -0
  7. package/src/cli/commands/ga.js +3 -0
  8. package/src/cli/commands/gates.js +1 -1
  9. package/src/cli/commands/inspect.js +6 -133
  10. package/src/cli/commands/release-check.js +2 -0
  11. package/src/cli/commands/run.js +74 -246
  12. package/src/cli/commands/security-check.js +2 -1
  13. package/src/cli/commands/truth.js +0 -1
  14. package/src/cli/entry.js +82 -309
  15. package/src/cli/util/angular-component-extractor.js +2 -2
  16. package/src/cli/util/angular-navigation-detector.js +2 -2
  17. package/src/cli/util/ast-interactive-detector.js +4 -6
  18. package/src/cli/util/ast-network-detector.js +3 -3
  19. package/src/cli/util/ast-promise-extractor.js +581 -0
  20. package/src/cli/util/ast-usestate-detector.js +3 -3
  21. package/src/cli/util/atomic-write.js +12 -1
  22. package/src/cli/util/console-reporter.js +72 -0
  23. package/src/cli/util/detection-engine.js +105 -41
  24. package/src/cli/util/determinism-runner.js +2 -1
  25. package/src/cli/util/determinism-writer.js +1 -1
  26. package/src/cli/util/digest-engine.js +359 -0
  27. package/src/cli/util/dom-diff.js +226 -0
  28. package/src/cli/util/env-url.js +0 -4
  29. package/src/cli/util/evidence-engine.js +287 -0
  30. package/src/cli/util/expectation-extractor.js +217 -367
  31. package/src/cli/util/findings-writer.js +19 -126
  32. package/src/cli/util/framework-detector.js +572 -0
  33. package/src/cli/util/idgen.js +1 -1
  34. package/src/cli/util/interaction-planner.js +529 -0
  35. package/src/cli/util/learn-writer.js +2 -2
  36. package/src/cli/util/ledger-writer.js +110 -0
  37. package/src/cli/util/monorepo-resolver.js +162 -0
  38. package/src/cli/util/observation-engine.js +127 -278
  39. package/src/cli/util/observe-writer.js +2 -2
  40. package/src/cli/util/paths.js +12 -3
  41. package/src/cli/util/project-discovery.js +284 -3
  42. package/src/cli/util/project-writer.js +2 -2
  43. package/src/cli/util/run-id.js +23 -27
  44. package/src/cli/util/run-result.js +778 -0
  45. package/src/cli/util/selector-resolver.js +235 -0
  46. package/src/cli/util/summary-writer.js +2 -1
  47. package/src/cli/util/svelte-navigation-detector.js +3 -3
  48. package/src/cli/util/svelte-sfc-extractor.js +0 -1
  49. package/src/cli/util/svelte-state-detector.js +1 -2
  50. package/src/cli/util/trust-activation-integration.js +496 -0
  51. package/src/cli/util/trust-activation-wrapper.js +85 -0
  52. package/src/cli/util/trust-integration-hooks.js +164 -0
  53. package/src/cli/util/types.js +153 -0
  54. package/src/cli/util/url-validation.js +40 -0
  55. package/src/cli/util/vue-navigation-detector.js +4 -3
  56. package/src/cli/util/vue-sfc-extractor.js +1 -2
  57. package/src/cli/util/vue-state-detector.js +1 -1
  58. package/src/types/fs-augment.d.ts +23 -0
  59. package/src/types/global.d.ts +137 -0
  60. package/src/types/internal-types.d.ts +35 -0
  61. package/src/verax/cli/finding-explainer.js +3 -56
  62. package/src/verax/cli/init.js +4 -18
  63. package/src/verax/core/action-classifier.js +4 -3
  64. package/src/verax/core/artifacts/registry.js +0 -15
  65. package/src/verax/core/artifacts/verifier.js +18 -8
  66. package/src/verax/core/baseline/baseline.snapshot.js +2 -0
  67. package/src/verax/core/capabilities/gates.js +7 -1
  68. package/src/verax/core/confidence/confidence-compute.js +14 -7
  69. package/src/verax/core/confidence/confidence.loader.js +1 -0
  70. package/src/verax/core/confidence-engine-refactor.js +8 -3
  71. package/src/verax/core/confidence-engine.js +162 -23
  72. package/src/verax/core/contracts/types.js +1 -0
  73. package/src/verax/core/contracts/validators.js +79 -4
  74. package/src/verax/core/decision-snapshot.js +3 -30
  75. package/src/verax/core/decisions/decision.trace.js +2 -0
  76. package/src/verax/core/determinism/contract-writer.js +2 -2
  77. package/src/verax/core/determinism/contract.js +1 -1
  78. package/src/verax/core/determinism/diff.js +42 -1
  79. package/src/verax/core/determinism/engine.js +7 -6
  80. package/src/verax/core/determinism/finding-identity.js +3 -2
  81. package/src/verax/core/determinism/normalize.js +32 -4
  82. package/src/verax/core/determinism/report-writer.js +1 -0
  83. package/src/verax/core/determinism/run-fingerprint.js +7 -2
  84. package/src/verax/core/dynamic-route-intelligence.js +8 -7
  85. package/src/verax/core/evidence/evidence-capture-service.js +1 -0
  86. package/src/verax/core/evidence/evidence-intent-ledger.js +2 -1
  87. package/src/verax/core/evidence-builder.js +2 -2
  88. package/src/verax/core/execution-mode-context.js +1 -1
  89. package/src/verax/core/execution-mode-detector.js +5 -3
  90. package/src/verax/core/failures/exit-codes.js +39 -37
  91. package/src/verax/core/failures/failure-summary.js +1 -1
  92. package/src/verax/core/failures/failure.factory.js +3 -3
  93. package/src/verax/core/failures/failure.ledger.js +3 -2
  94. package/src/verax/core/ga/ga.artifact.js +1 -1
  95. package/src/verax/core/ga/ga.contract.js +3 -2
  96. package/src/verax/core/ga/ga.enforcer.js +1 -0
  97. package/src/verax/core/guardrails/policy.loader.js +1 -0
  98. package/src/verax/core/guardrails/truth-reconciliation.js +1 -1
  99. package/src/verax/core/guardrails-engine.js +2 -2
  100. package/src/verax/core/incremental-store.js +1 -0
  101. package/src/verax/core/integrity/budget.js +138 -0
  102. package/src/verax/core/integrity/determinism.js +342 -0
  103. package/src/verax/core/integrity/integrity.js +208 -0
  104. package/src/verax/core/integrity/poisoning.js +108 -0
  105. package/src/verax/core/integrity/transaction.js +140 -0
  106. package/src/verax/core/observe/run-timeline.js +2 -0
  107. package/src/verax/core/perf/perf.report.js +2 -0
  108. package/src/verax/core/pipeline-tracker.js +5 -0
  109. package/src/verax/core/release/provenance.builder.js +73 -214
  110. package/src/verax/core/release/release.enforcer.js +14 -9
  111. package/src/verax/core/release/reproducibility.check.js +1 -0
  112. package/src/verax/core/release/sbom.builder.js +32 -23
  113. package/src/verax/core/replay-validator.js +2 -0
  114. package/src/verax/core/replay.js +4 -0
  115. package/src/verax/core/report/cross-index.js +6 -3
  116. package/src/verax/core/report/human-summary.js +141 -1
  117. package/src/verax/core/route-intelligence.js +4 -3
  118. package/src/verax/core/run-id.js +6 -3
  119. package/src/verax/core/run-manifest.js +4 -3
  120. package/src/verax/core/security/secrets.scan.js +10 -7
  121. package/src/verax/core/security/security.enforcer.js +4 -0
  122. package/src/verax/core/security/supplychain.policy.js +9 -1
  123. package/src/verax/core/security/vuln.scan.js +2 -2
  124. package/src/verax/core/truth/truth.certificate.js +3 -1
  125. package/src/verax/core/ui-feedback-intelligence.js +12 -46
  126. package/src/verax/detect/conditional-ui-silent-failure.js +84 -0
  127. package/src/verax/detect/confidence-engine.js +100 -660
  128. package/src/verax/detect/confidence-helper.js +1 -0
  129. package/src/verax/detect/detection-engine.js +1 -18
  130. package/src/verax/detect/dynamic-route-findings.js +17 -14
  131. package/src/verax/detect/expectation-chain-detector.js +1 -1
  132. package/src/verax/detect/expectation-model.js +3 -5
  133. package/src/verax/detect/failure-cause-inference.js +293 -0
  134. package/src/verax/detect/findings-writer.js +126 -166
  135. package/src/verax/detect/flow-detector.js +2 -2
  136. package/src/verax/detect/form-silent-failure.js +98 -0
  137. package/src/verax/detect/index.js +51 -234
  138. package/src/verax/detect/invariants-enforcer.js +147 -0
  139. package/src/verax/detect/journey-stall-detector.js +4 -4
  140. package/src/verax/detect/navigation-silent-failure.js +82 -0
  141. package/src/verax/detect/problem-aggregator.js +361 -0
  142. package/src/verax/detect/route-findings.js +7 -6
  143. package/src/verax/detect/summary-writer.js +477 -0
  144. package/src/verax/detect/test-failure-cause-inference.js +314 -0
  145. package/src/verax/detect/ui-feedback-findings.js +18 -18
  146. package/src/verax/detect/verdict-engine.js +3 -57
  147. package/src/verax/detect/view-switch-correlator.js +2 -2
  148. package/src/verax/flow/flow-engine.js +2 -1
  149. package/src/verax/flow/flow-spec.js +0 -6
  150. package/src/verax/index.js +48 -412
  151. package/src/verax/intel/ts-program.js +1 -0
  152. package/src/verax/intel/vue-navigation-extractor.js +3 -0
  153. package/src/verax/learn/action-contract-extractor.js +67 -682
  154. package/src/verax/learn/ast-contract-extractor.js +1 -1
  155. package/src/verax/learn/flow-extractor.js +1 -0
  156. package/src/verax/learn/project-detector.js +5 -0
  157. package/src/verax/learn/react-router-extractor.js +2 -0
  158. package/src/verax/learn/route-validator.js +1 -4
  159. package/src/verax/learn/source-instrumenter.js +1 -0
  160. package/src/verax/learn/state-extractor.js +2 -1
  161. package/src/verax/learn/static-extractor.js +1 -0
  162. package/src/verax/observe/coverage-gaps.js +132 -0
  163. package/src/verax/observe/expectation-handler.js +126 -0
  164. package/src/verax/observe/incremental-skip.js +46 -0
  165. package/src/verax/observe/index.js +735 -84
  166. package/src/verax/observe/interaction-executor.js +192 -0
  167. package/src/verax/observe/interaction-runner.js +782 -530
  168. package/src/verax/observe/network-firewall.js +86 -0
  169. package/src/verax/observe/observation-builder.js +169 -0
  170. package/src/verax/observe/observe-context.js +1 -1
  171. package/src/verax/observe/observe-helpers.js +2 -1
  172. package/src/verax/observe/observe-runner.js +28 -24
  173. package/src/verax/observe/observers/budget-observer.js +3 -3
  174. package/src/verax/observe/observers/console-observer.js +4 -4
  175. package/src/verax/observe/observers/coverage-observer.js +4 -4
  176. package/src/verax/observe/observers/interaction-observer.js +3 -3
  177. package/src/verax/observe/observers/navigation-observer.js +4 -4
  178. package/src/verax/observe/observers/network-observer.js +4 -4
  179. package/src/verax/observe/observers/safety-observer.js +1 -1
  180. package/src/verax/observe/observers/ui-feedback-observer.js +4 -4
  181. package/src/verax/observe/page-traversal.js +138 -0
  182. package/src/verax/observe/snapshot-ops.js +94 -0
  183. package/src/verax/observe/ui-signal-sensor.js +2 -148
  184. package/src/verax/scan-summary-writer.js +10 -42
  185. package/src/verax/shared/artifact-manager.js +30 -13
  186. package/src/verax/shared/caching.js +1 -0
  187. package/src/verax/shared/expectation-tracker.js +1 -0
  188. package/src/verax/shared/zip-artifacts.js +6 -0
  189. package/src/verax/core/confidence-engine.js.backup +0 -471
  190. package/src/verax/shared/config-loader.js +0 -169
  191. /package/src/verax/shared/{expectation-proof.js → expectation-validation.js} +0 -0
package/src/cli/entry.js CHANGED
@@ -3,13 +3,7 @@
3
3
  /**
4
4
  * VERAX CLI Entry Point
5
5
  *
6
- * PHASE 21.6.1: Two-Phase CLI Bootstrap
7
- *
8
- * Phase A: Raw argv parsing with zero side effects
9
- * Phase B: Dispatch - inspection commands bypass execution bootstrap
10
- *
11
6
  * Commands:
12
- * - verax (smart default with URL detection/prompting)
13
7
  * - verax run --url <url> (strict, non-interactive)
14
8
  * - verax inspect <runPath> (read and display run summary)
15
9
  *
@@ -18,324 +12,121 @@
18
12
  * - 2: internal crash
19
13
  * - 64: invalid CLI usage
20
14
  * - 65: invalid input data
15
+ *
16
+ * DESIGN: Lazy imports for heavy modules
17
+ * --version and --help are fast and don't load Playwright or observation-engine
18
+ * Heavy modules are only loaded when running actual commands (run, inspect, doctor)
21
19
  */
22
20
 
23
21
  import { fileURLToPath } from 'url';
24
22
  import { dirname, resolve } from 'path';
25
23
  import { readFileSync } from 'fs';
26
- import { defaultCommand } from './commands/default.js';
27
- import { runCommand } from './commands/run.js';
28
- import { inspectCommand } from './commands/inspect.js';
29
- import { doctorCommand } from './commands/doctor.js';
30
- import { gatesCommand } from './commands/gates.js';
31
- import { gaCommand } from './commands/ga.js';
32
- import { releaseCheckCommand } from './commands/release-check.js';
33
- import { securityCheckCommand } from './commands/security-check.js';
34
- import { baselineCommand } from './commands/baseline.js';
35
- import { truthCommand } from './commands/truth.js';
36
24
  import { getExitCode, UsageError } from './util/errors.js';
37
- import { getSourceCodeRequirementBanner } from '../verax/core/product-definition.js';
38
- import { enableInspectionMode, disableInspectionMode } from './util/bootstrap-guard.js';
39
25
 
40
26
  const __filename = fileURLToPath(import.meta.url);
41
27
  const __dirname = dirname(__filename);
42
28
 
43
- /**
44
- * PHASE 21.6.1: CLI Self-Identification
45
- * Prints diagnostic information to identify which binary is executed
46
- */
47
- function printCLIIdentity(args) {
48
- const verbose = args.includes('--verbose');
49
- const debugCli = process.env.VERAX_DEBUG_CLI === '1';
50
-
51
- if (!verbose && !debugCli) {
52
- return;
53
- }
54
-
55
- console.error('=== VERAX CLI IDENTITY ===');
56
- console.error(`process.argv[1]: ${process.argv[1]}`);
57
- console.error(`__filename: ${__filename}`);
58
-
59
- try {
60
- const pkgPath = resolve(__dirname, '../../package.json');
61
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
62
- console.error(`package.json version: ${pkg.version}`);
63
- console.error(`package.json location: ${pkgPath}`);
64
- } catch (error) {
65
- console.error(`Failed to read package.json: ${error.message}`);
66
- }
67
-
68
- console.error('========================');
29
+ // Lazy loaders for heavy modules (loaded only when needed)
30
+ async function loadRunCommand() {
31
+ const mod = await import('./commands/run.js');
32
+ return mod.runCommand;
33
+ }
34
+
35
+ async function loadInspectCommand() {
36
+ const mod = await import('./commands/inspect.js');
37
+ return mod.inspectCommand;
38
+ }
39
+
40
+ async function loadDoctorCommand() {
41
+ const mod = await import('./commands/doctor.js');
42
+ return mod.doctorCommand;
69
43
  }
70
44
 
71
45
  // Read package.json for version
72
46
  function getVersion() {
73
47
  try {
74
48
  const pkgPath = resolve(__dirname, '../../package.json');
75
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
49
+ // @ts-expect-error - readFileSync with encoding returns string
50
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
76
51
  return pkg.version;
77
52
  } catch {
78
53
  return 'unknown';
79
54
  }
80
55
  }
81
56
 
82
- /**
83
- * PHASE A: Raw argv parsing with zero side effects
84
- *
85
- * @param {string[]} args - Raw command line arguments
86
- * @returns {Object} Parsed command structure
87
- */
88
- function parseCommand(args) {
89
- // Handle --version (no side effects)
90
- if (args.includes('--version') || args.includes('-v')) {
91
- return { type: 'version' };
92
- }
93
-
94
- // Handle explicit --help (no side effects)
95
- if (args.includes('--help') || args.includes('-h')) {
96
- return { type: 'help' };
97
- }
98
-
99
- // If no args, default to smart mode
100
- if (args.length === 0) {
101
- return { type: 'default', options: {} };
102
- }
103
-
104
- const command = args[0];
105
-
106
- // Inspection commands (must bypass execution bootstrap)
107
- if (command === 'inspect') {
108
- if (args.length < 2) {
109
- throw new UsageError('inspect command requires a run path argument');
110
- }
111
- return {
112
- type: 'inspect',
113
- runPath: args[1],
114
- json: args.includes('--json'),
115
- timeline: args.includes('--timeline'),
116
- decisions: args.includes('--decisions'),
117
- failures: args.includes('--failures'),
118
- performance: args.includes('--performance'),
119
- evidence: args.includes('--evidence')
120
- };
121
- }
122
-
123
- if (command === 'gates') {
124
- return {
125
- type: 'gates',
126
- json: args.includes('--json'),
127
- verbose: args.includes('--verbose')
128
- };
129
- }
130
-
131
- if (command === 'ga') {
132
- return {
133
- type: 'ga',
134
- runId: parseArg(args, '--run-id'),
135
- json: args.includes('--json')
136
- };
137
- }
138
-
139
- if (command === 'release:check' || command === 'release-check') {
140
- return {
141
- type: 'release:check',
142
- json: args.includes('--json')
143
- };
144
- }
145
-
146
- if (command === 'security:check' || command === 'security-check') {
147
- return {
148
- type: 'security:check',
149
- json: args.includes('--json')
150
- };
151
- }
152
-
153
- if (command === 'baseline') {
154
- return {
155
- type: 'baseline',
156
- json: args.includes('--json')
157
- };
158
- }
159
-
160
- if (command === 'truth') {
161
- return {
162
- type: 'truth',
163
- runId: parseArg(args, '--run-id'),
164
- json: args.includes('--json')
165
- };
166
- }
167
-
168
- if (command === 'doctor') {
169
- const allowedFlags = new Set(['--json']);
170
- const extraFlags = args.slice(1).filter((a) => a.startsWith('-') && !allowedFlags.has(a));
171
- return {
172
- type: 'doctor',
173
- json: args.includes('--json'),
174
- extraFlags
175
- };
176
- }
57
+ async function main() {
58
+ const args = process.argv.slice(2);
177
59
 
178
- // Execution commands
179
- if (command === 'run') {
180
- const url = parseArg(args, '--url');
181
- const fixture = parseArg(args, '--fixture');
182
- if (!url && !fixture) {
183
- throw new UsageError('run command requires --url <url> or --fixture <fixture> argument');
60
+ try {
61
+ // Handle --version
62
+ if (args.includes('--version') || args.includes('-v')) {
63
+ console.log(`verax ${getVersion()}`);
64
+ process.exit(0);
184
65
  }
185
- return {
186
- type: 'run',
187
- url,
188
- fixture,
189
- src: parseArg(args, '--src') || '.',
190
- out: parseArg(args, '--out') || '.verax',
191
- json: args.includes('--json'),
192
- verbose: args.includes('--verbose'),
193
- determinism: args.includes('--determinism'),
194
- determinismRuns: args.includes('--determinism') ? parseInt(parseArg(args, '--determinism-runs') || '2', 10) : 0
195
- };
196
- }
197
-
198
- if (command === 'help' || command === '--help' || command === '-h') {
199
- return { type: 'help' };
200
- }
201
-
202
- // Default command: smart scanning mode
203
- return {
204
- type: 'default',
205
- options: {
206
- url: parseArg(args, '--url'),
207
- src: parseArg(args, '--src') || '.',
208
- out: parseArg(args, '--out') || '.verax',
209
- json: args.includes('--json'),
210
- verbose: args.includes('--verbose')
66
+
67
+ // Handle explicit --help
68
+ if (args.includes('--help') || args.includes('-h')) {
69
+ showHelp();
70
+ process.exit(0);
211
71
  }
212
- };
213
- }
214
-
215
- /**
216
- * PHASE B: Dispatch with isolation enforcement
217
- *
218
- * @param {Object} parsed - Parsed command from Phase A
219
- */
220
- async function dispatch(parsed) {
221
- try {
222
- // Inspection commands: enable guard mode
223
- const isInspectionCommand = ['inspect', 'gates', 'ga', 'doctor', 'release:check', 'security:check', 'baseline', 'truth'].includes(parsed.type);
224
72
 
225
- if (isInspectionCommand) {
226
- enableInspectionMode();
73
+ // If no args, show help (no interactive mode)
74
+ if (args.length === 0) {
75
+ showHelp();
76
+ process.exit(64);
227
77
  }
228
78
 
229
- try {
230
- switch (parsed.type) {
231
- case 'version':
232
- console.log(`verax ${getVersion()}`);
233
- process.exit(0);
234
- break;
235
-
236
- case 'help':
237
- showHelp();
238
- process.exit(0);
239
- break;
240
-
241
- case 'inspect':
242
- await inspectCommand(parsed.runPath, {
243
- json: parsed.json,
244
- timeline: parsed.timeline,
245
- decisions: parsed.decisions,
246
- failures: parsed.failures,
247
- performance: parsed.performance,
248
- evidence: parsed.evidence
249
- });
250
- process.exit(0);
251
- break;
252
-
253
- case 'gates':
254
- await gatesCommand({ json: parsed.json, verbose: parsed.verbose });
255
- // gatesCommand handles exit code internally
256
- return;
257
-
258
- case 'ga':
259
- await gaCommand({ runId: parsed.runId, json: parsed.json });
260
- // gaCommand handles exit code internally
261
- return;
262
-
263
- case 'release:check':
264
- await releaseCheckCommand({ json: parsed.json });
265
- // releaseCheckCommand handles exit code internally
266
- return;
267
-
268
- case 'security:check':
269
- await securityCheckCommand({ json: parsed.json });
270
- // securityCheckCommand handles exit code internally
271
- return;
272
-
273
- case 'baseline':
274
- await baselineCommand(process.cwd(), { json: parsed.json });
275
- process.exit(0);
276
- break;
277
-
278
- case 'truth':
279
- await truthCommand(process.cwd(), { json: parsed.json, runId: parsed.runId });
280
- process.exit(0);
281
- break;
282
-
283
- case 'doctor':
284
- await doctorCommand({ json: parsed.json, extraFlags: parsed.extraFlags });
285
- process.exit(0);
286
- break;
287
-
288
- case 'run':
289
- await runCommand({
290
- url: parsed.url,
291
- fixture: parsed.fixture,
292
- src: parsed.src,
293
- out: parsed.out,
294
- json: parsed.json,
295
- verbose: parsed.verbose,
296
- determinism: parsed.determinism,
297
- determinismRuns: parsed.determinismRuns
298
- });
299
- process.exit(0);
300
- break;
301
-
302
- case 'default':
303
- await defaultCommand(parsed.options);
304
- process.exit(0);
305
- break;
306
-
307
- default:
308
- throw new UsageError(`Unknown command: ${parsed.type}`);
79
+ const command = args[0];
80
+
81
+ // Handle 'run' command
82
+ if (command === 'run') {
83
+ const url = parseArg(args, '--url');
84
+ const src = parseArg(args, '--src') || '.';
85
+ const out = parseArg(args, '--out') || '.verax';
86
+ const json = args.includes('--json');
87
+ const verbose = args.includes('--verbose');
88
+
89
+ if (!url) {
90
+ throw new UsageError('run command requires --url <url> argument');
309
91
  }
310
- } finally {
311
- if (isInspectionCommand) {
312
- disableInspectionMode();
92
+
93
+ const runCommand = await loadRunCommand();
94
+ await runCommand({ url, src, out, json, verbose });
95
+ process.exit(0);
96
+ }
97
+
98
+ // Handle 'inspect' command
99
+ if (command === 'inspect') {
100
+ if (args.length < 2) {
101
+ throw new UsageError('inspect command requires a run path argument');
313
102
  }
103
+
104
+ const runPath = args[1];
105
+ const json = args.includes('--json');
106
+
107
+ const inspectCommand = await loadInspectCommand();
108
+ await inspectCommand(runPath, { json });
109
+ process.exit(0);
314
110
  }
315
- } catch (error) {
316
- // Print error message
317
- if (error.message) {
318
- console.error(`Error: ${error.message}`);
111
+
112
+ // Handle 'doctor' command
113
+ if (command === 'doctor') {
114
+ const allowedFlags = new Set(['--json']);
115
+ const extraFlags = args.slice(1).filter((a) => a.startsWith('-') && !allowedFlags.has(a));
116
+ const json = args.includes('--json');
117
+ const doctorCommand = await loadDoctorCommand();
118
+ await doctorCommand({ json, extraFlags });
119
+ process.exit(0);
319
120
  }
320
121
 
321
- // Get exit code
322
- const exitCode = getExitCode(error);
323
- process.exit(exitCode);
324
- }
325
- }
326
-
327
- async function main() {
328
- const args = process.argv.slice(2);
329
-
330
- // PHASE 21.6.1: Print CLI identity for debugging
331
- printCLIIdentity(args);
332
-
333
- try {
334
- // PHASE A: Parse command (zero side effects)
335
- const parsed = parseCommand(args);
122
+ // Handle 'help' command
123
+ if (command === 'help' || command === '--help' || command === '-h') {
124
+ showHelp();
125
+ process.exit(0);
126
+ }
336
127
 
337
- // PHASE B: Dispatch with isolation enforcement
338
- await dispatch(parsed);
128
+ // Interactive mode removed
129
+ throw new UsageError('Interactive mode is disabled. Use: verax run --url <url>');
339
130
  } catch (error) {
340
131
  // Print error message
341
132
  if (error.message) {
@@ -350,41 +141,23 @@ async function main() {
350
141
 
351
142
  function showHelp() {
352
143
  const version = getVersion();
353
- const banner = getSourceCodeRequirementBanner();
354
144
  console.log(`
355
145
  verax ${version}
356
146
  VERAX — Silent failure detection for websites
357
147
 
358
- ${banner}
359
- Canonical product contract: docs/README.md
360
-
361
148
  USAGE:
362
- verax [options] Smart mode (detects/prompts for URL)
363
149
  verax run --url <url> [options] Strict mode (non-interactive, CI-friendly)
364
150
  verax inspect <runPath> [--json] Inspect an existing run
365
- verax inspect <runPath> --timeline Show chronological timeline
366
- verax inspect <runPath> --decisions Show decision trace
367
- verax inspect <runPath> --failures Show failure ledger
368
- verax inspect <runPath> --performance Show performance metrics
369
- verax inspect <runPath> --evidence Show evidence cross-index
370
151
  verax doctor [--json] Diagnose local environment
371
- verax gates [--json] [--verbose] Evaluate capability gates (PHASE 19)
372
- verax ga [--run-id <id>] [--json] Evaluate GA readiness (PHASE 21.6)
373
- verax release:check [--json] Check release readiness (PHASE 21.7)
374
- verax security:check [--json] Check security baseline (PHASE 21.8)
375
- verax baseline [--json] Show baseline hash and drift status (PHASE 21.11)
376
- verax truth [--run-id <id>] [--json] Show truth certificate (PHASE 21.11)
377
152
  verax --version Show version
378
153
  verax --help Show this help
379
154
 
380
155
  OPTIONS:
381
156
  --url <url> Target URL to scan
382
- --src <path> Source directory (default: .) — required; URL-only scans are blocked
157
+ --src <path> Source directory (default: .)
383
158
  --out <path> Output directory for artifacts (default: .verax)
384
159
  --json Output as JSON lines (progress events)
385
160
  --verbose Verbose output
386
- --determinism Run determinism check (executes scan multiple times and compares results)
387
- --determinism-runs <N> Number of runs for determinism check (default: 2)
388
161
  --help Show this help
389
162
  --version Show version
390
163
 
@@ -27,7 +27,7 @@ export function extractAngularComponent(content, filePath, projectRoot) {
27
27
  const decoratorMatch = content.match(decoratorRegex);
28
28
 
29
29
  if (decoratorMatch) {
30
- const decoratorContent = decoratorMatch[0];
30
+ const _decoratorContent = decoratorMatch[0];
31
31
  const decoratorConfig = decoratorMatch[1];
32
32
  const beforeDecorator = content.substring(0, decoratorMatch.index);
33
33
  const decoratorStartLine = (beforeDecorator.match(/\n/g) || []).length + 1;
@@ -89,7 +89,7 @@ export function extractAngularComponent(content, filePath, projectRoot) {
89
89
  * @returns {string} Resolved template path
90
90
  */
91
91
  function resolveTemplatePath(templateUrl, componentPath, projectRoot) {
92
- const { join, dirname, resolve } = require('path');
92
+ const { join: _join, dirname, resolve } = require('path');
93
93
 
94
94
  if (templateUrl.startsWith('./') || templateUrl.startsWith('../')) {
95
95
  // Relative path
@@ -7,7 +7,7 @@
7
7
  * - ActivatedRoute navigation
8
8
  */
9
9
 
10
- import { extractAngularComponent, extractTemplateBindings, mapTemplateHandlersToClass } from './angular-component-extractor.js';
10
+ import { extractAngularComponent, extractTemplateBindings, mapTemplateHandlersToClass } from './angular-component-extractor.js'; // eslint-disable-line no-unused-vars
11
11
  import { parse } from '@babel/parser';
12
12
  import traverse from '@babel/traverse';
13
13
  import { readFileSync, existsSync } from 'fs';
@@ -37,7 +37,7 @@ export function detectAngularNavigation(filePath, content, projectRoot) {
37
37
  }
38
38
 
39
39
  if (templateContent) {
40
- const templateBindings = extractTemplateBindings(templateContent);
40
+ const _templateBindings = extractTemplateBindings(templateContent);
41
41
 
42
42
  // Extract routerLink directives
43
43
  const routerLinkRegex = /routerLink\s*=\s*["']([^"']+)["']/g;
@@ -23,11 +23,11 @@ const traverse = _traverse.default || _traverse;
23
23
  /**
24
24
  * Detect interactive elements without href and their navigation promises
25
25
  * @param {string} content - File content
26
- * @param {string} filePath - Absolute file path
27
- * @param {string} relPath - Relative path from source root
26
+ * @param {string} _filePath - Absolute file path (unused)
27
+ * @param {string} _relPath - Relative path from source root (unused)
28
28
  * @returns {Array} Array of interactive element detections with navigation promises
29
29
  */
30
- export function detectInteractiveElementsAST(content, filePath, relPath) {
30
+ export function detectInteractiveElementsAST(content, _filePath, _relPath) {
31
31
  const detections = [];
32
32
  const lines = content.split('\n');
33
33
 
@@ -183,8 +183,6 @@ export function detectInteractiveElementsAST(content, filePath, relPath) {
183
183
  handlerLoc = handlerSource.loc;
184
184
  } else if (handlerSource.expression?.loc) {
185
185
  handlerLoc = handlerSource.expression.loc;
186
- } else if (handlerSource.type === 'JSXExpressionContainer' && handlerSource.expression?.loc) {
187
- handlerLoc = handlerSource.expression.loc;
188
186
  }
189
187
  }
190
188
  const astSource = handlerSource ? extractASTSource(handlerSource, lines, handlerLoc) : null;
@@ -411,7 +409,7 @@ function extractStringValue(node) {
411
409
  /**
412
410
  * Extract selector hint from JSX element
413
411
  */
414
- function extractSelectorHint(node, path) {
412
+ function extractSelectorHint(node, _path) {
415
413
  let selector = node.name.name || '';
416
414
 
417
415
  // Check for id attribute
@@ -23,11 +23,11 @@ const traverse = _traverse.default || _traverse;
23
23
  /**
24
24
  * Detect network calls in source code using AST parsing
25
25
  * @param {string} content - File content
26
- * @param {string} filePath - Absolute file path
27
- * @param {string} relPath - Relative path from source root
26
+ * @param {string} _filePath - Absolute file path (unused)
27
+ * @param {string} _relPath - Relative path from source root (unused)
28
28
  * @returns {Array} Array of detected network calls with metadata including AST source
29
29
  */
30
- export function detectNetworkCallsAST(content, filePath, relPath) {
30
+ export function detectNetworkCallsAST(content, _filePath, _relPath) {
31
31
  const detections = [];
32
32
  const lines = content.split('\n');
33
33