1 ---
2 name: validation
3 description: Register shell commands as named validation steps (like CI checks) that can be triggered and monitored to verify code quality.
4 ---
5
6 # Validation Skill
7
8 Set up named validation commands (lint, test, typecheck, etc.) that act as repeatable CI-style checks for the project, then run and monitor them.
9
10 ## When to Use
11
12 - After building new functionality or making significant changes
13 - When setting up a project's quality gates for the first time
14 - When the validation command for a check needs to change (e.g., new test framework)
15 - To run validation commands and check their results
16 - To monitor the status of ongoing or past validation runs
17
18 ## When NOT to Use
19
20 - For one-off test runs — use the shell directly
21 - For deploy workflows — use the deployment skill
22
23 ## Available Functions
24
25 ### setValidationCommand(name, command)
26
27 Create or update a named validation command. If a validation with the same name already exists, it is silently updated (upsert behavior).
28
29 **Parameters:**
30
31 | Parameter | Type | Description |
32 |-----------|--------|-------------------------------------------------------|
33 | `name` | string | Short lowercase identifier (e.g., `lint`, `test`) |
34 | `command` | string | Shell command to run for this validation |
35
36 **Returns:** `{ success: true, name: string, command: string }`
37
38 **Example:**
39
40 ```javascript
41 await setValidationCommand({ name: "lint", command: "npm run lint" });
42 await setValidationCommand({ name: "test", command: "npm test" });
43 ```
44
45 ### clearValidationCommand(name)
46
47 Remove a previously registered validation command.
48
49 **Parameters:**
50
51 | Parameter | Type | Description |
52 |-----------|--------|--------------------------------------------------|
53 | `name` | string | Name of the validation command to remove |
54
55 **Returns:** `{ success: true, name: string }`
56
57 **Example:**
58
59 ```javascript
60 await clearValidationCommand({ name: "lint" });
61 ```
62
63 ### getValidationCommands()
64
65 List all registered validation commands.
66
67 **Parameters:** None
68
69 **Returns:** `{ workflows: [{ name: string, tasks: [...], ... }] }`
70
71 **Example:**
72
73 ```javascript
74 const commands = await getValidationCommands();
75 ```
76
77 ### startValidationRun(commandIds)
78
79 Start a validation run that executes one or more registered validation commands.
80
81 **Parameters:**
82
83 | Parameter | Type | Description |
84 |--------------|----------|------------------------------------------------------|
85 | `commandIds` | string[] | List of validation command IDs to run |
86
87 **Returns:**
88
89 ```json
90 {
91 "runId": "run-abc123",
92 "status": "FAILED",
93 "commands": [
94 {
95 "commandId": "lint",
96 "shell": "npm run lint",
97 "status": "FAILED",
98 "exitCode": 1,
99 "errorMessage": "Exited with: 1",
100 "executionId": "exec-1",
101 "durationMs": 3200,
102 "logFilePath": "/tmp/validation/lint.log"
103 },
104 {
105 "commandId": "test",
106 "shell": "npm test",
107 "status": "PASSED",
108 "exitCode": 0,
109 "errorMessage": "",
110 "executionId": "exec-2",
111 "durationMs": 5100,
112 "logFilePath": "/tmp/validation/test.log"
113 }
114 ],
115 "durationMs": 8300,
116 "errorMessage": "",
117 "runSummary": "- `npm run lint` FAILED (exit code 1): ESLint reported ..."
118 }
119 ```
120
121 - `status` is one of: `"RUNNING"`, `"PASSED"`, `"FAILED"`, `"STOPPED"`, `"ERROR"`, `"TIMED_OUT"`
122 - `runSummary` is an LLM-generated breakdown of the results with log line citations. Use it to understand what failed without reading full logs.
123 - Each command includes `logFilePath` pointing to the full output log.
124
125 **Example:**
126
127 ```javascript
128 await setValidationCommand({ name: "lint", command: "npm run lint" });
129 await setValidationCommand({ name: "test", command: "npm test" });
130 const run = await startValidationRun({ commandIds: ["lint", "test"] });
131
132 if (run.status !== "PASSED") {
133 // run.runSummary explains what failed and cites log lines
134 console.log(run.runSummary);
135
136 // Inspect individual commands
137 for (const cmd of run.commands) {
138 if (cmd.status !== "PASSED") {
139 console.log(`${cmd.shell} failed (exit ${cmd.exitCode}): ${cmd.errorMessage}`);
140 console.log(`Full log: ${cmd.logFilePath}`);
141 }
142 }
143 }
144 ```
145
146 ### stopValidationRun(runId, graceful?)
147
148 Stop a running validation run.
149
150 **Parameters:**
151
152 | Parameter | Type | Description |
153 |------------|---------|---------------------------------------------------|
154 | `runId` | string | ID of the validation run to stop |
155 | `graceful` | boolean | Whether to stop gracefully (default: `true`) |
156
157 **Returns:** `{ success: true, runId: string }`
158
159 **Example:**
160
161 ```javascript
162 await stopValidationRun({ runId: "run-abc123" });
163 await stopValidationRun({ runId: "run-abc123", graceful: false });
164 ```
165
166 ### getValidationRun(runId)
167
168 Get the status and details of a specific validation run, including per-command results.
169
170 **Parameters:**
171
172 | Parameter | Type | Description |
173 |-----------|--------|--------------------------------------------------|
174 | `runId` | string | ID of the validation run to retrieve |
175
176 **Returns:** `{ validationRun: { id, status, startedAt, durationMs, commands: [...] } }`
177
178 **Example:**
179
180 ```javascript
181 const run = await getValidationRun({ runId: "run-abc123" });
182 // run.validationRun.status is one of: "RUNNING", "PASSED", "FAILED", "STOPPED", "ERROR"
183 ```
184
185 ### getValidationRuns()
186
187 Get all validation runs.
188
189 **Parameters:** None
190
191 **Returns:** `{ validationRuns: [{ id, status, startedAt, durationMs, commands: [...] }] }`
192
193 **Example:**
194
195 ```javascript
196 const runs = await getValidationRuns();
197 ```
198
199 ## Conventional Names and Commands
200
201 Use short, lowercase names. Here are common conventions by stack:
202
203 | Name | Node.js | Python | Go |
204 |-------------|----------------------|---------------------------|---------------------|
205 | `lint` | `npm run lint` | `ruff check .` | `golangci-lint run` |
206 | `test` | `npm test` | `pytest` | `go test ./...` |
207 | `typecheck` | `npx tsc --noEmit --incremental` | `mypy .` | `go vet ./...` |
208 | `format` | `npx prettier --check .` | `ruff format --check .` | `gofmt -l .` |
209
210 ## Example Workflow
211
212 After implementing a feature in a Node.js project:
213
214 ```javascript
215 // Set up validation commands for the project
216 await setValidationCommand({ name: "lint", command: "npm run lint" });
217 await setValidationCommand({ name: "test", command: "npm test" });
218 await setValidationCommand({ name: "typecheck", command: "npx tsc --noEmit --incremental" });
219
220 // Run all validations (blocks until complete)
221 const run = await startValidationRun({ commandIds: ["lint", "test", "typecheck"] });
222
223 if (run.status !== "PASSED") {
224 // runSummary explains failures with log line citations
225 console.log(run.runSummary);
226
227 for (const cmd of run.commands) {
228 if (cmd.status !== "PASSED") {
229 console.log(`${cmd.shell} failed (exit ${cmd.exitCode}): ${cmd.errorMessage}`);
230 console.log(`Full log: ${cmd.logFilePath}`);
231 }
232 }
233 }
234
235 // Or fetch it again later by ID
236 const result = await getValidationRun({ runId: run.runId });
237 ```