@halecraft/verify 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -6
- package/bin/verify.mjs +111 -135
- package/dist/index.d.ts +133 -7
- package/dist/index.js +373 -86
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -58,6 +58,13 @@ pnpm exec verify
|
|
|
58
58
|
# Run specific task
|
|
59
59
|
pnpm exec verify format
|
|
60
60
|
|
|
61
|
+
# Run nested task with full path
|
|
62
|
+
pnpm exec verify types:tsc
|
|
63
|
+
|
|
64
|
+
# Run nested task with shortcut (if unambiguous)
|
|
65
|
+
pnpm exec verify tsc
|
|
66
|
+
# → Resolving "tsc" to "types:tsc"
|
|
67
|
+
|
|
61
68
|
# Run with verbose output
|
|
62
69
|
pnpm exec verify --verbose
|
|
63
70
|
|
|
@@ -87,11 +94,10 @@ interface VerificationNode {
|
|
|
87
94
|
name?: string;
|
|
88
95
|
|
|
89
96
|
// Command to run (leaf nodes only)
|
|
90
|
-
// Supports: string, object with cmd/args/cwd
|
|
97
|
+
// Supports: string, object with cmd/args/cwd/timeout
|
|
91
98
|
run?:
|
|
92
99
|
| string
|
|
93
|
-
| { cmd: string; args: string[]; cwd?: string }
|
|
94
|
-
| [string, string[]];
|
|
100
|
+
| { cmd: string; args: string[]; cwd?: string; timeout?: number };
|
|
95
101
|
|
|
96
102
|
// Child tasks (for grouping)
|
|
97
103
|
children?: VerificationNode[];
|
|
@@ -105,6 +111,9 @@ interface VerificationNode {
|
|
|
105
111
|
// Tasks that must pass for this task's failure to be reported
|
|
106
112
|
reportingDependsOn?: string[];
|
|
107
113
|
|
|
114
|
+
// Timeout in milliseconds (for string commands)
|
|
115
|
+
timeout?: number;
|
|
116
|
+
|
|
108
117
|
// Custom success message template (optional)
|
|
109
118
|
successLabel?: string;
|
|
110
119
|
|
|
@@ -222,6 +231,39 @@ Control how child tasks are executed:
|
|
|
222
231
|
- `sequential`: Run tasks one after another
|
|
223
232
|
- `fail-fast`: Run sequentially, stop on first failure
|
|
224
233
|
|
|
234
|
+
### Command Timeouts
|
|
235
|
+
|
|
236
|
+
Prevent hung processes by setting a timeout (in milliseconds):
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
import { defineConfig } from "@halecraft/verify";
|
|
240
|
+
|
|
241
|
+
export default defineConfig({
|
|
242
|
+
tasks: [
|
|
243
|
+
// String command with timeout
|
|
244
|
+
{ key: "test", run: "vitest run", timeout: 60000 }, // 60 seconds
|
|
245
|
+
|
|
246
|
+
// Object command with timeout
|
|
247
|
+
{
|
|
248
|
+
key: "build",
|
|
249
|
+
run: {
|
|
250
|
+
cmd: "tsup",
|
|
251
|
+
args: [],
|
|
252
|
+
timeout: 120000, // 2 minutes
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
When a command exceeds its timeout:
|
|
260
|
+
|
|
261
|
+
- The process is killed with `SIGTERM` (including child processes)
|
|
262
|
+
- The task is marked as failed with `timedOut: true`
|
|
263
|
+
- The summary shows: `task: timed out after 60000ms`
|
|
264
|
+
|
|
265
|
+
**Note:** For object commands, the `timeout` on the command takes precedence over the node-level `timeout`.
|
|
266
|
+
|
|
225
267
|
## CLI Options
|
|
226
268
|
|
|
227
269
|
```
|
|
@@ -243,6 +285,50 @@ Options:
|
|
|
243
285
|
--help, -h Show this help message
|
|
244
286
|
```
|
|
245
287
|
|
|
288
|
+
### Exit Codes
|
|
289
|
+
|
|
290
|
+
- `0` - All tasks passed
|
|
291
|
+
- `1` - Some tasks failed
|
|
292
|
+
- `2` - Configuration/usage error (invalid task name, missing config)
|
|
293
|
+
|
|
294
|
+
### Task Name Validation
|
|
295
|
+
|
|
296
|
+
Verify validates task names before running any tasks. If you specify a task that doesn't exist, you'll get a helpful error:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
$ verify test
|
|
300
|
+
Error: Task "test" not found.
|
|
301
|
+
|
|
302
|
+
Did you mean "types:tsc"?
|
|
303
|
+
|
|
304
|
+
Available tasks:
|
|
305
|
+
format
|
|
306
|
+
logic
|
|
307
|
+
types
|
|
308
|
+
types:tsc
|
|
309
|
+
types:tsgo
|
|
310
|
+
build
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**Child task shortcuts:** You can use just the child key if it's unambiguous:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
$ verify tsc
|
|
317
|
+
→ Resolving "tsc" to "types:tsc"
|
|
318
|
+
✓ verified types:tsc
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
If the shortcut is ambiguous (multiple tasks have the same child key), you'll get an error listing the options:
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
$ verify test # if both unit:test and e2e:test exist
|
|
325
|
+
Error: Task "test" is ambiguous.
|
|
326
|
+
|
|
327
|
+
Matches multiple tasks:
|
|
328
|
+
unit:test
|
|
329
|
+
e2e:test
|
|
330
|
+
```
|
|
331
|
+
|
|
246
332
|
## Programmatic API
|
|
247
333
|
|
|
248
334
|
```typescript
|
|
@@ -293,6 +379,7 @@ interface TaskResult {
|
|
|
293
379
|
summaryLine: string; // Parsed summary
|
|
294
380
|
suppressed?: boolean; // True if output was suppressed
|
|
295
381
|
suppressedBy?: string; // Path of dependency that caused suppression
|
|
382
|
+
timedOut?: boolean; // True if task exceeded its timeout
|
|
296
383
|
children?: TaskResult[]; // Child results (for group nodes)
|
|
297
384
|
}
|
|
298
385
|
```
|
|
@@ -301,14 +388,38 @@ interface TaskResult {
|
|
|
301
388
|
|
|
302
389
|
Built-in parsers for common tools:
|
|
303
390
|
|
|
304
|
-
- **vitest** - Vitest test runner
|
|
305
|
-
- **tsc** - TypeScript compiler
|
|
306
|
-
- **biome** - Biome linter/formatter
|
|
391
|
+
- **vitest** - Vitest/Jest test runner
|
|
392
|
+
- **tsc** - TypeScript compiler (tsc/tsgo)
|
|
393
|
+
- **biome** - Biome/ESLint linter/formatter
|
|
307
394
|
- **gotest** - Go test runner
|
|
308
395
|
- **generic** - Fallback for unknown tools
|
|
309
396
|
|
|
310
397
|
Parsers automatically extract metrics (passed/failed counts, duration) and provide concise summaries.
|
|
311
398
|
|
|
399
|
+
### Parser ID Constants
|
|
400
|
+
|
|
401
|
+
Use `parsers` for type-safe parser references instead of magic strings:
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
import { defineConfig, parsers } from "@halecraft/verify";
|
|
405
|
+
|
|
406
|
+
export default defineConfig({
|
|
407
|
+
tasks: [
|
|
408
|
+
{ key: "test", run: "vitest run", parser: parsers.vitest },
|
|
409
|
+
{ key: "types", run: "tsc --noEmit", parser: parsers.tsc },
|
|
410
|
+
{ key: "lint", run: "biome check .", parser: parsers.biome },
|
|
411
|
+
],
|
|
412
|
+
});
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
Available constants:
|
|
416
|
+
|
|
417
|
+
- `parsers.vitest` - `"vitest"`
|
|
418
|
+
- `parsers.tsc` - `"tsc"`
|
|
419
|
+
- `parsers.biome` - `"biome"`
|
|
420
|
+
- `parsers.gotest` - `"gotest"`
|
|
421
|
+
- `parsers.generic` - `"generic"`
|
|
422
|
+
|
|
312
423
|
## License
|
|
313
424
|
|
|
314
425
|
MIT
|
package/bin/verify.mjs
CHANGED
|
@@ -1,140 +1,109 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
for (let i = 0; i < args.length; i++) {
|
|
25
|
-
const arg = args[i]
|
|
26
|
-
|
|
27
|
-
if (arg === "--json") {
|
|
28
|
-
options.json = true
|
|
29
|
-
} else if (arg === "--verbose" || arg === "-v") {
|
|
30
|
-
options.verbose = true
|
|
31
|
-
} else if (arg === "--quiet" || arg === "-q") {
|
|
32
|
-
options.quiet = true
|
|
33
|
-
} else if (arg === "--help" || arg === "-h") {
|
|
34
|
-
options.help = true
|
|
35
|
-
} else if (arg === "--init") {
|
|
36
|
-
options.init = true
|
|
37
|
-
} else if (arg === "--force") {
|
|
38
|
-
options.force = true
|
|
39
|
-
} else if (arg === "--yes" || arg === "-y") {
|
|
40
|
-
options.yes = true
|
|
41
|
-
} else if (arg === "--top-level" || arg === "-t") {
|
|
42
|
-
options.topLevelOnly = true
|
|
43
|
-
} else if (arg === "--no-tty") {
|
|
44
|
-
options.noTty = true
|
|
45
|
-
} else if (arg.startsWith("--logs=")) {
|
|
46
|
-
options.logs = arg.slice(7)
|
|
47
|
-
} else if (arg === "--logs") {
|
|
48
|
-
options.logs = args[++i]
|
|
49
|
-
} else if (arg.startsWith("--config=")) {
|
|
50
|
-
options.config = arg.slice(9)
|
|
51
|
-
} else if (arg === "--config" || arg === "-c") {
|
|
52
|
-
options.config = args[++i]
|
|
53
|
-
} else if (arg.startsWith("--filter=")) {
|
|
54
|
-
options.filter.push(arg.slice(9))
|
|
55
|
-
} else if (arg === "--filter" || arg === "-f") {
|
|
56
|
-
options.filter.push(args[++i])
|
|
57
|
-
} else if (!arg.startsWith("-")) {
|
|
58
|
-
// Positional argument treated as filter
|
|
59
|
-
options.filter.push(arg)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return options
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Print help message
|
|
68
|
-
*/
|
|
69
|
-
function printHelp() {
|
|
70
|
-
console.log(`
|
|
71
|
-
@halecraft/verify - Hierarchical verification runner
|
|
72
|
-
|
|
73
|
-
Usage:
|
|
74
|
-
verify [options] [filter...]
|
|
75
|
-
|
|
76
|
-
Options:
|
|
77
|
-
--json Output results as JSON
|
|
78
|
-
--verbose, -v Show all task output
|
|
79
|
-
--quiet, -q Show only final result
|
|
80
|
-
--top-level, -t Show only top-level tasks (hide descendants)
|
|
81
|
-
--no-tty Force sequential output (disable live dashboard)
|
|
82
|
-
--logs=MODE Log verbosity: all, failed, none (default: failed)
|
|
83
|
-
--config, -c PATH Path to config file (or output path for --init)
|
|
84
|
-
--filter, -f PATH Filter to specific task paths
|
|
85
|
-
--init Initialize a new verify.config.ts file
|
|
86
|
-
--force Overwrite existing config file (with --init)
|
|
87
|
-
--yes, -y Skip interactive prompts, auto-accept detected tasks
|
|
88
|
-
--help, -h Show this help message
|
|
89
|
-
|
|
90
|
-
Examples:
|
|
91
|
-
verify Run all verifications
|
|
92
|
-
verify logic Run only 'logic' tasks
|
|
93
|
-
verify logic:ts Run only 'logic:ts' task
|
|
94
|
-
verify --top-level Show only top-level tasks
|
|
95
|
-
verify --json Output JSON for CI
|
|
96
|
-
verify --logs=all Show all output
|
|
97
|
-
verify --init Create config interactively
|
|
98
|
-
verify --init -y Create config with all detected tasks
|
|
99
|
-
verify --init --force Overwrite existing config
|
|
100
|
-
|
|
101
|
-
Config:
|
|
102
|
-
Create a verify.config.ts file in your project root:
|
|
103
|
-
|
|
104
|
-
import { defineConfig } from '@halecraft/verify'
|
|
105
|
-
|
|
106
|
-
export default defineConfig({
|
|
107
|
-
tasks: [
|
|
108
|
-
{ key: 'format', run: 'pnpm verify:format' },
|
|
109
|
-
{ key: 'types', run: 'pnpm verify:types' },
|
|
110
|
-
{
|
|
111
|
-
key: 'logic',
|
|
112
|
-
children: [
|
|
113
|
-
{ key: 'ts', run: 'vitest run' },
|
|
114
|
-
{ key: 'go', run: 'go test ./...' },
|
|
115
|
-
],
|
|
3
|
+
import { cli } from "cleye"
|
|
4
|
+
import {
|
|
5
|
+
AmbiguousTaskError,
|
|
6
|
+
runInit,
|
|
7
|
+
TaskNotFoundError,
|
|
8
|
+
verifyFromConfig,
|
|
9
|
+
} from "../dist/index.js"
|
|
10
|
+
|
|
11
|
+
const argv = cli(
|
|
12
|
+
{
|
|
13
|
+
name: "verify",
|
|
14
|
+
version: "1.0.0",
|
|
15
|
+
description: "Hierarchical verification runner with parallel execution",
|
|
16
|
+
|
|
17
|
+
flags: {
|
|
18
|
+
json: {
|
|
19
|
+
type: Boolean,
|
|
20
|
+
description: "Output results as JSON",
|
|
21
|
+
default: false,
|
|
116
22
|
},
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
23
|
+
verbose: {
|
|
24
|
+
type: Boolean,
|
|
25
|
+
alias: "v",
|
|
26
|
+
description: "Show all task output",
|
|
27
|
+
default: false,
|
|
28
|
+
},
|
|
29
|
+
quiet: {
|
|
30
|
+
type: Boolean,
|
|
31
|
+
alias: "q",
|
|
32
|
+
description: "Show only final result",
|
|
33
|
+
default: false,
|
|
34
|
+
},
|
|
35
|
+
topLevel: {
|
|
36
|
+
type: Boolean,
|
|
37
|
+
alias: "t",
|
|
38
|
+
description: "Show only top-level tasks (hide descendants)",
|
|
39
|
+
default: false,
|
|
40
|
+
},
|
|
41
|
+
noTty: {
|
|
42
|
+
type: Boolean,
|
|
43
|
+
description: "Force sequential output (disable live dashboard)",
|
|
44
|
+
default: false,
|
|
45
|
+
},
|
|
46
|
+
logs: {
|
|
47
|
+
type: String,
|
|
48
|
+
description: "Log verbosity: all, failed, none (default: failed)",
|
|
49
|
+
},
|
|
50
|
+
config: {
|
|
51
|
+
type: String,
|
|
52
|
+
alias: "c",
|
|
53
|
+
description: "Path to config file (or output path for --init)",
|
|
54
|
+
},
|
|
55
|
+
filter: {
|
|
56
|
+
type: [String],
|
|
57
|
+
alias: "f",
|
|
58
|
+
description: "Filter to specific task paths",
|
|
59
|
+
default: [],
|
|
60
|
+
},
|
|
61
|
+
init: {
|
|
62
|
+
type: Boolean,
|
|
63
|
+
description: "Initialize a new verify.config.ts file",
|
|
64
|
+
default: false,
|
|
65
|
+
},
|
|
66
|
+
force: {
|
|
67
|
+
type: Boolean,
|
|
68
|
+
description: "Overwrite existing config file (with --init)",
|
|
69
|
+
default: false,
|
|
70
|
+
},
|
|
71
|
+
yes: {
|
|
72
|
+
type: Boolean,
|
|
73
|
+
alias: "y",
|
|
74
|
+
description: "Skip interactive prompts, auto-accept detected tasks",
|
|
75
|
+
default: false,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
help: {
|
|
80
|
+
examples: [
|
|
81
|
+
"verify Run all verifications",
|
|
82
|
+
"verify logic Run only 'logic' tasks",
|
|
83
|
+
"verify logic:ts Run only 'logic:ts' task",
|
|
84
|
+
"verify --top-level Show only top-level tasks",
|
|
85
|
+
"verify --json Output JSON for CI",
|
|
86
|
+
"verify --logs=all Show all output",
|
|
87
|
+
"verify --init Create config interactively",
|
|
88
|
+
"verify --init -y Create config with all detected tasks",
|
|
89
|
+
"verify --init --force Overwrite existing config",
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
undefined,
|
|
94
|
+
undefined,
|
|
95
|
+
)
|
|
121
96
|
|
|
122
97
|
async function main() {
|
|
123
|
-
const
|
|
124
|
-
const options = parseArgs(args)
|
|
125
|
-
|
|
126
|
-
if (options.help) {
|
|
127
|
-
printHelp()
|
|
128
|
-
process.exit(0)
|
|
129
|
-
}
|
|
98
|
+
const { flags, _ } = argv
|
|
130
99
|
|
|
131
100
|
// Handle --init command
|
|
132
|
-
if (
|
|
101
|
+
if (flags.init) {
|
|
133
102
|
try {
|
|
134
103
|
const result = await runInit({
|
|
135
|
-
config:
|
|
136
|
-
force:
|
|
137
|
-
yes:
|
|
104
|
+
config: flags.config,
|
|
105
|
+
force: flags.force,
|
|
106
|
+
yes: flags.yes,
|
|
138
107
|
cwd: process.cwd(),
|
|
139
108
|
})
|
|
140
109
|
process.exit(result.success ? 0 : 1)
|
|
@@ -148,22 +117,29 @@ async function main() {
|
|
|
148
117
|
}
|
|
149
118
|
}
|
|
150
119
|
|
|
120
|
+
// Combine --filter flags with positional arguments
|
|
121
|
+
const allFilters = [...flags.filter, ..._]
|
|
122
|
+
|
|
151
123
|
// Build verify options
|
|
152
124
|
const verifyOptions = {
|
|
153
|
-
format:
|
|
125
|
+
format: flags.json ? "json" : "human",
|
|
154
126
|
logs:
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
noTty: options.noTty,
|
|
127
|
+
flags.logs ?? (flags.verbose ? "all" : flags.quiet ? "none" : "failed"),
|
|
128
|
+
filter: allFilters.length > 0 ? allFilters : undefined,
|
|
129
|
+
cwd: flags.config,
|
|
130
|
+
topLevelOnly: flags.topLevel,
|
|
131
|
+
noTty: flags.noTty,
|
|
161
132
|
}
|
|
162
133
|
|
|
163
134
|
try {
|
|
164
135
|
const result = await verifyFromConfig(process.cwd(), verifyOptions)
|
|
165
136
|
process.exit(result.ok ? 0 : 1)
|
|
166
137
|
} catch (error) {
|
|
138
|
+
// Handle task not found / ambiguous task errors with exit code 2
|
|
139
|
+
if (error instanceof TaskNotFoundError || error instanceof AmbiguousTaskError) {
|
|
140
|
+
console.error(`Error: ${error.message}`)
|
|
141
|
+
process.exit(2)
|
|
142
|
+
}
|
|
167
143
|
if (error instanceof Error) {
|
|
168
144
|
console.error(`Error: ${error.message}`)
|
|
169
145
|
} else {
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ interface VerificationCommand {
|
|
|
10
10
|
cwd?: string;
|
|
11
11
|
/** Environment variables to set */
|
|
12
12
|
env?: Record<string, string>;
|
|
13
|
+
/** Timeout in milliseconds (process killed with SIGTERM if exceeded) */
|
|
14
|
+
timeout?: number;
|
|
13
15
|
}
|
|
14
16
|
/**
|
|
15
17
|
* Result from parsing command output
|
|
@@ -48,8 +50,8 @@ interface VerificationNode {
|
|
|
48
50
|
key: string;
|
|
49
51
|
/** Human-readable name */
|
|
50
52
|
name?: string;
|
|
51
|
-
/** Command to run (leaf nodes only) */
|
|
52
|
-
run?: VerificationCommand | string
|
|
53
|
+
/** Command to run (leaf nodes only) - string commands are executed via shell */
|
|
54
|
+
run?: VerificationCommand | string;
|
|
53
55
|
/** Child verification nodes */
|
|
54
56
|
children?: VerificationNode[];
|
|
55
57
|
/** Execution strategy for children (default: parallel) */
|
|
@@ -66,6 +68,12 @@ interface VerificationNode {
|
|
|
66
68
|
* Can specify task keys (e.g., "format") or full paths (e.g., "types:tsc").
|
|
67
69
|
*/
|
|
68
70
|
reportingDependsOn?: string[];
|
|
71
|
+
/**
|
|
72
|
+
* Timeout in milliseconds for string commands.
|
|
73
|
+
* Process is killed with SIGTERM if exceeded.
|
|
74
|
+
* For VerificationCommand objects, use the timeout field on the command itself.
|
|
75
|
+
*/
|
|
76
|
+
timeout?: number;
|
|
69
77
|
}
|
|
70
78
|
/**
|
|
71
79
|
* Options for the verification runner
|
|
@@ -140,6 +148,11 @@ interface TaskResult {
|
|
|
140
148
|
* Only set when suppressed is true.
|
|
141
149
|
*/
|
|
142
150
|
suppressedBy?: string;
|
|
151
|
+
/**
|
|
152
|
+
* Whether this task was terminated due to timeout.
|
|
153
|
+
* Only set when the task exceeded its configured timeout.
|
|
154
|
+
*/
|
|
155
|
+
timedOut?: boolean;
|
|
143
156
|
}
|
|
144
157
|
/**
|
|
145
158
|
* Overall verification run result
|
|
@@ -157,6 +170,17 @@ interface VerifyResult {
|
|
|
157
170
|
tasks: TaskResult[];
|
|
158
171
|
}
|
|
159
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Error thrown when config validation fails
|
|
175
|
+
*/
|
|
176
|
+
declare class ConfigError extends Error {
|
|
177
|
+
readonly configPath?: string | undefined;
|
|
178
|
+
constructor(message: string, configPath?: string | undefined);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Validate a config object and return typed result
|
|
182
|
+
*/
|
|
183
|
+
declare function validateConfig(value: unknown, configPath?: string): VerifyConfig;
|
|
160
184
|
/**
|
|
161
185
|
* Helper function for defining config with type inference
|
|
162
186
|
*/
|
|
@@ -209,6 +233,53 @@ declare function discoverPackages(rootDir: string, options?: PackageDiscoveryOpt
|
|
|
209
233
|
*/
|
|
210
234
|
declare function hasPackageChanged(_packagePath: string, _baseBranch?: string): Promise<boolean>;
|
|
211
235
|
|
|
236
|
+
/**
|
|
237
|
+
* Result of resolving a filter to a valid task path
|
|
238
|
+
*/
|
|
239
|
+
interface ResolvedFilter {
|
|
240
|
+
/** The original filter string provided by the user */
|
|
241
|
+
original: string;
|
|
242
|
+
/** The resolved full task path */
|
|
243
|
+
resolved: string;
|
|
244
|
+
/** Whether this was resolved via child shortcut (e.g., "tsc" → "types:tsc") */
|
|
245
|
+
wasShortcut: boolean;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Error thrown when a task filter doesn't match any existing task
|
|
249
|
+
*/
|
|
250
|
+
declare class TaskNotFoundError extends Error {
|
|
251
|
+
readonly filter: string;
|
|
252
|
+
readonly suggestion: string | undefined;
|
|
253
|
+
readonly availableTasks: string[];
|
|
254
|
+
readonly exitCode = 2;
|
|
255
|
+
constructor(filter: string, suggestion: string | undefined, availableTasks: string[]);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Error thrown when a task filter matches multiple tasks ambiguously
|
|
259
|
+
*/
|
|
260
|
+
declare class AmbiguousTaskError extends Error {
|
|
261
|
+
readonly filter: string;
|
|
262
|
+
readonly matches: string[];
|
|
263
|
+
readonly exitCode = 2;
|
|
264
|
+
constructor(filter: string, matches: string[]);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Find the single best suggestion using Levenshtein distance.
|
|
268
|
+
* Returns undefined if no good match (distance > threshold).
|
|
269
|
+
*/
|
|
270
|
+
declare function findBestSuggestion(availablePaths: string[], invalidFilter: string): string | undefined;
|
|
271
|
+
/**
|
|
272
|
+
* Resolve and validate all filters before running any tasks.
|
|
273
|
+
* Fails fast on first invalid filter.
|
|
274
|
+
*
|
|
275
|
+
* @param nodes - The verification task tree
|
|
276
|
+
* @param filters - User-provided filter strings
|
|
277
|
+
* @returns Array of resolved filters
|
|
278
|
+
* @throws TaskNotFoundError if a filter doesn't match any task
|
|
279
|
+
* @throws AmbiguousTaskError if a filter matches multiple tasks
|
|
280
|
+
*/
|
|
281
|
+
declare function resolveFilters(nodes: VerificationNode[], filters: string[]): ResolvedFilter[];
|
|
282
|
+
|
|
212
283
|
/**
|
|
213
284
|
* A detected task candidate from package.json
|
|
214
285
|
*/
|
|
@@ -308,6 +379,35 @@ declare const tscParser: OutputParser;
|
|
|
308
379
|
*/
|
|
309
380
|
declare const vitestParser: OutputParser;
|
|
310
381
|
|
|
382
|
+
/**
|
|
383
|
+
* Parser ID constants for type-safe parser references.
|
|
384
|
+
* Use these instead of magic strings when specifying parsers in config.
|
|
385
|
+
*
|
|
386
|
+
* @example
|
|
387
|
+
* ```typescript
|
|
388
|
+
* import { parsers } from "@halecraft/verify"
|
|
389
|
+
*
|
|
390
|
+
* export default defineConfig({
|
|
391
|
+
* tasks: [
|
|
392
|
+
* { key: "test", run: "vitest run", parser: parsers.vitest },
|
|
393
|
+
* ],
|
|
394
|
+
* })
|
|
395
|
+
* ```
|
|
396
|
+
*/
|
|
397
|
+
declare const parsers: {
|
|
398
|
+
/** Vitest/Jest test runner output parser */
|
|
399
|
+
readonly vitest: "vitest";
|
|
400
|
+
/** TypeScript compiler (tsc/tsgo) output parser */
|
|
401
|
+
readonly tsc: "tsc";
|
|
402
|
+
/** Biome/ESLint linter output parser */
|
|
403
|
+
readonly biome: "biome";
|
|
404
|
+
/** Go test runner output parser */
|
|
405
|
+
readonly gotest: "gotest";
|
|
406
|
+
/** Generic fallback parser */
|
|
407
|
+
readonly generic: "generic";
|
|
408
|
+
};
|
|
409
|
+
/** Type for valid parser IDs */
|
|
410
|
+
type ParserId = (typeof parsers)[keyof typeof parsers];
|
|
311
411
|
/**
|
|
312
412
|
* Registry for output parsers
|
|
313
413
|
*/
|
|
@@ -325,7 +425,7 @@ declare class ParserRegistry {
|
|
|
325
425
|
/**
|
|
326
426
|
* Auto-detect parser based on command
|
|
327
427
|
*/
|
|
328
|
-
detectParser(cmd: string):
|
|
428
|
+
detectParser(cmd: string): ParserId;
|
|
329
429
|
/**
|
|
330
430
|
* Parse output using the specified or auto-detected parser
|
|
331
431
|
*/
|
|
@@ -387,9 +487,9 @@ declare abstract class BaseReporter implements Reporter {
|
|
|
387
487
|
*/
|
|
388
488
|
protected getTaskDepth(path: string): number;
|
|
389
489
|
/**
|
|
390
|
-
*
|
|
490
|
+
* Collect task depths from verification tree using walkNodes
|
|
391
491
|
*/
|
|
392
|
-
protected collectTaskDepths(nodes: VerificationNode[]
|
|
492
|
+
protected collectTaskDepths(nodes: VerificationNode[]): void;
|
|
393
493
|
/**
|
|
394
494
|
* Extract summary from task result
|
|
395
495
|
*/
|
|
@@ -426,7 +526,7 @@ declare class LiveDashboardReporter extends BaseReporter {
|
|
|
426
526
|
*/
|
|
427
527
|
onStart(tasks: VerificationNode[]): void;
|
|
428
528
|
/**
|
|
429
|
-
*
|
|
529
|
+
* Collect tasks from verification tree using walkNodes
|
|
430
530
|
*/
|
|
431
531
|
private collectTasks;
|
|
432
532
|
/**
|
|
@@ -520,6 +620,32 @@ declare class VerificationRunner {
|
|
|
520
620
|
private runNode;
|
|
521
621
|
}
|
|
522
622
|
|
|
623
|
+
/**
|
|
624
|
+
* Path separator used in task paths
|
|
625
|
+
*/
|
|
626
|
+
declare const PATH_SEPARATOR = ":";
|
|
627
|
+
/**
|
|
628
|
+
* Build a task path from parent path and key
|
|
629
|
+
*/
|
|
630
|
+
declare function buildTaskPath(parentPath: string, key: string): string;
|
|
631
|
+
/**
|
|
632
|
+
* Visitor function called for each node during tree traversal
|
|
633
|
+
*/
|
|
634
|
+
type NodeVisitor = (node: VerificationNode, path: string, depth: number) => void;
|
|
635
|
+
/**
|
|
636
|
+
* Walk all nodes in a verification tree in depth-first order
|
|
637
|
+
*
|
|
638
|
+
* @param nodes - The nodes to walk
|
|
639
|
+
* @param visitor - Function called for each node with (node, path, depth)
|
|
640
|
+
* @param parentPath - Parent path prefix (used for recursion)
|
|
641
|
+
* @param depth - Current depth (used for recursion)
|
|
642
|
+
*/
|
|
643
|
+
declare function walkNodes(nodes: VerificationNode[], visitor: NodeVisitor, parentPath?: string, depth?: number): void;
|
|
644
|
+
/**
|
|
645
|
+
* Collect all task paths from a verification tree
|
|
646
|
+
*/
|
|
647
|
+
declare function collectPaths(nodes: VerificationNode[]): string[];
|
|
648
|
+
|
|
523
649
|
/**
|
|
524
650
|
* Run verification with the given config and options
|
|
525
651
|
*/
|
|
@@ -529,4 +655,4 @@ declare function verify(config: VerifyConfig, cliOptions?: Partial<VerifyOptions
|
|
|
529
655
|
*/
|
|
530
656
|
declare function verifyFromConfig(cwd?: string, cliOptions?: Partial<VerifyOptions>): Promise<VerifyResult>;
|
|
531
657
|
|
|
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 };
|
|
658
|
+
export { AmbiguousTaskError, ConfigError, type DetectedTask, type DiscoveredPackage, type ExecutionStrategy, type InitOptions, type InitResult, JSONReporter, LiveDashboardReporter, type NodeVisitor, type OutputFormat, type OutputParser, PATH_SEPARATOR, type PackageDiscoveryOptions, type ParsedResult, type ParserId, ParserRegistry, QuietReporter, type Reporter, type ResolvedFilter, type RunnerCallbacks, SequentialReporter, SequentialReporter as TTYReporter, TaskNotFoundError, type TaskResult, type VerificationCommand, type VerificationNode, VerificationRunner, type VerifyConfig, type VerifyOptions, type VerifyResult, biomeParser, buildTaskPath, collectPaths, createReporter, defaultRegistry, defineConfig, defineTask, detectTasks, discoverPackages, findBestSuggestion, findConfigFile, generateConfigContent, genericParser, gotestParser, hasPackageChanged, loadConfig, loadConfigFromCwd, mergeOptions, parsers, resolveFilters, runInit, tscParser, validateConfig, verify, verifyFromConfig, vitestParser, walkNodes };
|