@halecraft/verify 1.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.
@@ -0,0 +1,532 @@
1
+ /**
2
+ * Command to execute for verification
3
+ */
4
+ interface VerificationCommand {
5
+ /** The command/binary to run */
6
+ cmd: string;
7
+ /** Arguments to pass to the command */
8
+ args: string[];
9
+ /** Working directory (defaults to cwd) */
10
+ cwd?: string;
11
+ /** Environment variables to set */
12
+ env?: Record<string, string>;
13
+ }
14
+ /**
15
+ * Result from parsing command output
16
+ */
17
+ interface ParsedResult {
18
+ /** One-line summary for display */
19
+ summary: string;
20
+ /** Optional metrics extracted from output */
21
+ metrics?: {
22
+ passed?: number;
23
+ failed?: number;
24
+ total?: number;
25
+ duration?: string;
26
+ errors?: number;
27
+ warnings?: number;
28
+ };
29
+ }
30
+ /**
31
+ * Output parser interface
32
+ */
33
+ interface OutputParser {
34
+ /** Unique identifier for this parser */
35
+ id: string;
36
+ /** Parse command output and return structured result */
37
+ parse(output: string, exitCode: number): ParsedResult | null;
38
+ }
39
+ /**
40
+ * Execution strategy for child nodes
41
+ */
42
+ type ExecutionStrategy = "parallel" | "sequential" | "fail-fast";
43
+ /**
44
+ * A node in the verification tree
45
+ */
46
+ interface VerificationNode {
47
+ /** Unique key for this node (used in CLI filtering) */
48
+ key: string;
49
+ /** Human-readable name */
50
+ name?: string;
51
+ /** Command to run (leaf nodes only) */
52
+ run?: VerificationCommand | string | [string, string[]];
53
+ /** Child verification nodes */
54
+ children?: VerificationNode[];
55
+ /** Execution strategy for children (default: parallel) */
56
+ strategy?: ExecutionStrategy;
57
+ /** Parser ID to use for output (auto-detected if not specified) */
58
+ parser?: string;
59
+ /** Success message template */
60
+ successLabel?: string;
61
+ /** Failure message template */
62
+ failureLabel?: string;
63
+ /**
64
+ * Tasks that must pass for this task's failure to be reported.
65
+ * If any dependency fails, this task's failure output is suppressed.
66
+ * Can specify task keys (e.g., "format") or full paths (e.g., "types:tsc").
67
+ */
68
+ reportingDependsOn?: string[];
69
+ }
70
+ /**
71
+ * Options for the verification runner
72
+ */
73
+ interface VerifyOptions {
74
+ /** Log verbosity: all, failed, none */
75
+ logs?: "all" | "failed" | "none";
76
+ /** Output format */
77
+ format?: "human" | "json";
78
+ /** Filter to specific task paths (e.g., "logic:ts") */
79
+ filter?: string[];
80
+ /** Working directory */
81
+ cwd?: string;
82
+ /** Disable colors */
83
+ noColor?: boolean;
84
+ /** Show only top-level tasks (hide descendants) */
85
+ topLevelOnly?: boolean;
86
+ /** Force sequential output (disable live dashboard) */
87
+ noTty?: boolean;
88
+ }
89
+ /**
90
+ * Package discovery options for monorepos
91
+ */
92
+ interface PackageDiscoveryOptions {
93
+ /** Glob patterns for package directories */
94
+ patterns?: string[];
95
+ /** Filter to specific packages */
96
+ filter?: string[];
97
+ /** Include packages that have changed (git-aware) */
98
+ changed?: boolean;
99
+ }
100
+ /**
101
+ * Root configuration for verify
102
+ */
103
+ interface VerifyConfig {
104
+ /** Root verification tasks */
105
+ tasks: VerificationNode[];
106
+ /** Monorepo package discovery options */
107
+ packages?: PackageDiscoveryOptions;
108
+ /** Default options */
109
+ options?: VerifyOptions;
110
+ }
111
+ /**
112
+ * Result of a single verification task
113
+ */
114
+ interface TaskResult {
115
+ /** Task key */
116
+ key: string;
117
+ /** Full path in tree (e.g., "logic:ts") */
118
+ path: string;
119
+ /** Whether the task passed */
120
+ ok: boolean;
121
+ /** Exit code */
122
+ code: number;
123
+ /** Duration in milliseconds */
124
+ durationMs: number;
125
+ /** Raw output */
126
+ output: string;
127
+ /** Parsed summary line */
128
+ summaryLine: string;
129
+ /** Parsed metrics */
130
+ metrics?: ParsedResult["metrics"];
131
+ /** Child results (for group nodes) */
132
+ children?: TaskResult[];
133
+ /**
134
+ * Whether this task's failure output was suppressed due to a dependency failure.
135
+ * The task still ran and failed, but its output is hidden to reduce noise.
136
+ */
137
+ suppressed?: boolean;
138
+ /**
139
+ * The path of the dependency task that caused this task to be suppressed.
140
+ * Only set when suppressed is true.
141
+ */
142
+ suppressedBy?: string;
143
+ }
144
+ /**
145
+ * Overall verification run result
146
+ */
147
+ interface VerifyResult {
148
+ /** Whether all tasks passed */
149
+ ok: boolean;
150
+ /** ISO timestamp when run started */
151
+ startedAt: string;
152
+ /** ISO timestamp when run finished */
153
+ finishedAt: string;
154
+ /** Total duration in milliseconds */
155
+ durationMs: number;
156
+ /** Individual task results */
157
+ tasks: TaskResult[];
158
+ }
159
+
160
+ /**
161
+ * Helper function for defining config with type inference
162
+ */
163
+ declare function defineConfig(config: VerifyConfig): VerifyConfig;
164
+ /**
165
+ * Helper function for defining a single verification task
166
+ */
167
+ declare function defineTask(task: VerificationNode): VerificationNode;
168
+ /**
169
+ * Find config file in directory
170
+ */
171
+ declare function findConfigFile(cwd: string): string | null;
172
+ /**
173
+ * Load config from file
174
+ */
175
+ declare function loadConfig(configPath: string): Promise<VerifyConfig | null>;
176
+ /**
177
+ * Load config from cwd or specified path
178
+ */
179
+ declare function loadConfigFromCwd(cwd: string, configPath?: string): Promise<VerifyConfig | null>;
180
+ /**
181
+ * Merge options with defaults.
182
+ *
183
+ * NOTE: The `satisfies AllKeys<VerifyOptions>` ensures this function handles
184
+ * all properties of VerifyOptions. If you add a new option to VerifyOptions,
185
+ * TypeScript will error here until you add it to the return object.
186
+ */
187
+ declare function mergeOptions(configOptions?: VerifyOptions, cliOptions?: Partial<VerifyOptions>): VerifyOptions;
188
+
189
+ /**
190
+ * Discovered package with its config
191
+ */
192
+ interface DiscoveredPackage {
193
+ /** Package name from package.json */
194
+ name: string;
195
+ /** Relative path from root */
196
+ path: string;
197
+ /** Absolute path */
198
+ absolutePath: string;
199
+ /** Loaded verify config (if exists) */
200
+ config: VerifyConfig | null;
201
+ }
202
+ /**
203
+ * Discover packages in a monorepo
204
+ */
205
+ declare function discoverPackages(rootDir: string, options?: PackageDiscoveryOptions): Promise<DiscoveredPackage[]>;
206
+ /**
207
+ * Check if a package has changed (git-aware)
208
+ * This is a placeholder - full implementation would use git diff
209
+ */
210
+ declare function hasPackageChanged(_packagePath: string, _baseBranch?: string): Promise<boolean>;
211
+
212
+ /**
213
+ * A detected task candidate from package.json
214
+ */
215
+ interface DetectedTask {
216
+ /** Suggested key for the task */
217
+ key: string;
218
+ /** Human-readable name */
219
+ name: string;
220
+ /** The npm script name that was detected */
221
+ scriptName: string;
222
+ /** The command to run (optimized direct path when possible) */
223
+ command: string;
224
+ /** Category for grouping (format, types, logic, build) */
225
+ category: "format" | "types" | "logic" | "build" | "other";
226
+ /** Parser to use for this task */
227
+ parser?: string;
228
+ /**
229
+ * Tasks that must pass for this task's failure to be reported.
230
+ * Auto-populated based on category (types/logic/build depend on format).
231
+ */
232
+ reportingDependsOn?: string[];
233
+ }
234
+ /**
235
+ * Detect tasks with proper package manager commands
236
+ * Uses optimized direct paths when possible, falls back to package manager
237
+ */
238
+ declare function detectTasks(cwd: string): DetectedTask[];
239
+
240
+ /**
241
+ * Output format for the generated config
242
+ */
243
+ type OutputFormat = "ts" | "mts" | "js" | "mjs";
244
+ /**
245
+ * Generate config content from selected tasks
246
+ */
247
+ declare function generateConfigContent(tasks: DetectedTask[], format: OutputFormat): string;
248
+
249
+ /**
250
+ * Options for the init command
251
+ */
252
+ interface InitOptions {
253
+ /** Custom config output path */
254
+ config?: string;
255
+ /** Force overwrite existing file */
256
+ force: boolean;
257
+ /** Skip interactive prompts */
258
+ yes: boolean;
259
+ /** Working directory */
260
+ cwd: string;
261
+ }
262
+ /**
263
+ * Result of the init command
264
+ */
265
+ interface InitResult {
266
+ /** Whether init succeeded */
267
+ success: boolean;
268
+ /** Path to the created config file (if successful) */
269
+ configPath?: string;
270
+ /** Error message (if failed) */
271
+ error?: string;
272
+ }
273
+ /**
274
+ * Run the init command
275
+ */
276
+ declare function runInit(options: InitOptions): Promise<InitResult>;
277
+
278
+ /**
279
+ * Parser for Biome linter/formatter output
280
+ * Extracts issue counts and file counts from biome check output
281
+ */
282
+ declare const biomeParser: OutputParser;
283
+
284
+ /**
285
+ * Generic fallback parser - just reports exit code
286
+ * This parser always returns a result (never null)
287
+ */
288
+ declare const genericParser: {
289
+ readonly id: "generic";
290
+ readonly parse: (_output: string, exitCode: number) => ParsedResult;
291
+ };
292
+
293
+ /**
294
+ * Parser for Go test output
295
+ * Counts packages passed/failed from go test output
296
+ */
297
+ declare const gotestParser: OutputParser;
298
+
299
+ /**
300
+ * Parser for TypeScript compiler (tsc/tsgo) output
301
+ * Counts type errors and extracts diagnostics info
302
+ */
303
+ declare const tscParser: OutputParser;
304
+
305
+ /**
306
+ * Parser for vitest output
307
+ * Extracts test counts from vitest summary
308
+ */
309
+ declare const vitestParser: OutputParser;
310
+
311
+ /**
312
+ * Registry for output parsers
313
+ */
314
+ declare class ParserRegistry {
315
+ private parsers;
316
+ constructor();
317
+ /**
318
+ * Register a custom parser
319
+ */
320
+ register(parser: OutputParser): void;
321
+ /**
322
+ * Get a parser by ID
323
+ */
324
+ get(id: string): OutputParser | undefined;
325
+ /**
326
+ * Auto-detect parser based on command
327
+ */
328
+ detectParser(cmd: string): string;
329
+ /**
330
+ * Parse output using the specified or auto-detected parser
331
+ */
332
+ parse(output: string, exitCode: number, parserId?: string, cmd?: string): ParsedResult;
333
+ }
334
+ declare const defaultRegistry: ParserRegistry;
335
+
336
+ /**
337
+ * Reporter interface
338
+ */
339
+ interface Reporter {
340
+ /** Called before any tasks start - initialize display */
341
+ onStart?(tasks: VerificationNode[]): void;
342
+ /** Called when a task starts */
343
+ onTaskStart(path: string, key: string): void;
344
+ /** Called when a task completes */
345
+ onTaskComplete(result: TaskResult): void;
346
+ /** Called when all tasks complete - cleanup display */
347
+ onFinish?(): void;
348
+ /** Called to output task logs */
349
+ outputLogs(results: TaskResult[], logsMode: "all" | "failed" | "none"): void;
350
+ /** Called to output final summary */
351
+ outputSummary(result: VerifyResult): void;
352
+ }
353
+ /**
354
+ * Base Reporter - common functionality for all reporters
355
+ */
356
+ declare abstract class BaseReporter implements Reporter {
357
+ protected colorEnabled: boolean;
358
+ protected stream: NodeJS.WriteStream;
359
+ protected taskDepths: Map<string, number>;
360
+ constructor(options?: VerifyOptions);
361
+ /**
362
+ * Apply ANSI color code to string (if colors enabled)
363
+ */
364
+ protected c(code: string, s: string): string;
365
+ /**
366
+ * Get success mark (✓ or OK)
367
+ */
368
+ protected okMark(): string;
369
+ /**
370
+ * Get failure mark (✗ or FAIL)
371
+ */
372
+ protected failMark(): string;
373
+ /**
374
+ * Get suppressed mark (⊘ or SUPPRESSED)
375
+ */
376
+ protected suppressedMark(): string;
377
+ /**
378
+ * Get arrow symbol (→ or ->)
379
+ */
380
+ protected arrow(): string;
381
+ /**
382
+ * Get indentation string for a given depth
383
+ */
384
+ protected getIndent(depth: number): string;
385
+ /**
386
+ * Get task depth from path
387
+ */
388
+ protected getTaskDepth(path: string): number;
389
+ /**
390
+ * Recursively collect task depths from verification tree
391
+ */
392
+ protected collectTaskDepths(nodes: VerificationNode[], parentPath: string, depth: number): void;
393
+ /**
394
+ * Extract summary from task result
395
+ */
396
+ protected extractSummary(result: TaskResult): string;
397
+ /**
398
+ * Flatten nested task results into a single array
399
+ */
400
+ protected flattenResults(results: TaskResult[]): TaskResult[];
401
+ /**
402
+ * Output task logs
403
+ */
404
+ outputLogs(results: TaskResult[], logsMode: "all" | "failed" | "none"): void;
405
+ /**
406
+ * Output final summary
407
+ */
408
+ outputSummary(result: VerifyResult): void;
409
+ abstract onStart(tasks: VerificationNode[]): void;
410
+ abstract onTaskStart(path: string, key: string): void;
411
+ abstract onTaskComplete(result: TaskResult): void;
412
+ abstract onFinish(): void;
413
+ }
414
+ /**
415
+ * Live Dashboard Reporter - animated in-place updates for TTY
416
+ */
417
+ declare class LiveDashboardReporter extends BaseReporter {
418
+ private topLevelOnly;
419
+ private tasks;
420
+ private taskOrder;
421
+ private spinner;
422
+ private lineCount;
423
+ constructor(options?: VerifyOptions);
424
+ /**
425
+ * Initialize task list from verification nodes
426
+ */
427
+ onStart(tasks: VerificationNode[]): void;
428
+ /**
429
+ * Recursively collect tasks from verification tree
430
+ */
431
+ private collectTasks;
432
+ /**
433
+ * Get display key - shows :key for nested, key for root
434
+ */
435
+ private getDisplayKey;
436
+ /**
437
+ * Check if task should be displayed based on topLevelOnly flag
438
+ */
439
+ private shouldDisplay;
440
+ /**
441
+ * Format a single task line
442
+ */
443
+ private formatLine;
444
+ /**
445
+ * Redraw all visible task lines
446
+ */
447
+ private redraw;
448
+ onTaskStart(path: string, _key: string): void;
449
+ onTaskComplete(result: TaskResult): void;
450
+ onFinish(): void;
451
+ }
452
+ /**
453
+ * Sequential Reporter - line-by-line output for non-TTY
454
+ * No indentation since parallel execution means output order doesn't reflect hierarchy
455
+ */
456
+ declare class SequentialReporter extends BaseReporter {
457
+ private topLevelOnly;
458
+ constructor(options?: VerifyOptions);
459
+ onStart(tasks: VerificationNode[]): void;
460
+ /**
461
+ * Check if task should be displayed based on topLevelOnly flag
462
+ */
463
+ private shouldDisplay;
464
+ onTaskStart(path: string, _key: string): void;
465
+ onTaskComplete(result: TaskResult): void;
466
+ onFinish(): void;
467
+ }
468
+ /**
469
+ * JSON Reporter - machine-readable output
470
+ */
471
+ declare class JSONReporter implements Reporter {
472
+ onStart(_tasks: VerificationNode[]): void;
473
+ onTaskStart(_path: string, _key: string): void;
474
+ onTaskComplete(_result: TaskResult): void;
475
+ onFinish(): void;
476
+ outputLogs(_results: TaskResult[], _logsMode: "all" | "failed" | "none"): void;
477
+ outputSummary(result: VerifyResult): void;
478
+ private serializeTasks;
479
+ }
480
+ /**
481
+ * Quiet Reporter - minimal output (summary only)
482
+ */
483
+ declare class QuietReporter extends BaseReporter {
484
+ onStart(_tasks: VerificationNode[]): void;
485
+ onTaskStart(_path: string, _key: string): void;
486
+ onTaskComplete(_result: TaskResult): void;
487
+ onFinish(): void;
488
+ outputLogs(_results: TaskResult[], _logsMode: "all" | "failed" | "none"): void;
489
+ outputSummary(result: VerifyResult): void;
490
+ }
491
+ /**
492
+ * Create appropriate reporter based on options
493
+ */
494
+ declare function createReporter(options: VerifyOptions): Reporter;
495
+
496
+ interface RunnerCallbacks {
497
+ onTaskStart?: (path: string, key: string) => void;
498
+ onTaskComplete?: (result: TaskResult) => void;
499
+ }
500
+ /**
501
+ * Verification runner
502
+ */
503
+ declare class VerificationRunner {
504
+ private registry;
505
+ private options;
506
+ private callbacks;
507
+ private dependencyTracker;
508
+ constructor(options?: VerifyOptions, registry?: ParserRegistry, callbacks?: RunnerCallbacks);
509
+ /**
510
+ * Run all verification tasks
511
+ */
512
+ run(tasks: VerificationNode[]): Promise<VerifyResult>;
513
+ /**
514
+ * Run a list of nodes with the appropriate strategy
515
+ */
516
+ private runNodes;
517
+ /**
518
+ * Run a single node (leaf or group)
519
+ */
520
+ private runNode;
521
+ }
522
+
523
+ /**
524
+ * Run verification with the given config and options
525
+ */
526
+ declare function verify(config: VerifyConfig, cliOptions?: Partial<VerifyOptions>): Promise<VerifyResult>;
527
+ /**
528
+ * Run verification from config file in cwd
529
+ */
530
+ declare function verifyFromConfig(cwd?: string, cliOptions?: Partial<VerifyOptions>): Promise<VerifyResult>;
531
+
532
+ export { type DetectedTask, type DiscoveredPackage, type ExecutionStrategy, type InitOptions, type InitResult, JSONReporter, LiveDashboardReporter, type OutputFormat, type OutputParser, type PackageDiscoveryOptions, type ParsedResult, ParserRegistry, QuietReporter, type Reporter, type RunnerCallbacks, SequentialReporter, SequentialReporter as TTYReporter, type TaskResult, type VerificationCommand, type VerificationNode, VerificationRunner, type VerifyConfig, type VerifyOptions, type VerifyResult, biomeParser, createReporter, defaultRegistry, defineConfig, defineTask, detectTasks, discoverPackages, findConfigFile, generateConfigContent, genericParser, gotestParser, hasPackageChanged, loadConfig, loadConfigFromCwd, mergeOptions, runInit, tscParser, verify, verifyFromConfig, vitestParser };