Configure Deno Commands
This skill ensures a standardized development interface using Deno tasks and scripts.
Context
This skill can be invoked:
- Standalone: When a user wants to fix or update their Deno commands.
- From init: During project initialization to set up the standard interface.
Standard Interface
The project must support these commands in deno.json:
deno task check: Comprehensive verification (build, lint, fmt, static analysis, tests).
deno task test: Run all tests or a specific test if a path is provided.
deno task dev: Run in development mode with watch mode.
deno task prod: Run in production mode.
Rules & Constraints
- Idempotency: Check existing
scripts/ and deno.json tasks before creating. Do not overwrite existing scripts unless user confirms.
- Scripts Location: All complex logic must reside in
.ts files within the scripts/ directory.
- Task Definitions:
deno.json should point to these scripts.
- Standard Interface Compliance: The
check.ts script must implement the full verification checklist.
- Exit Codes: Scripts must return non-zero exit codes on failure to break CI/CD and agent workflows.
- No External Dependencies: Generated scripts must only use Deno built-in APIs and
@std/ stdlib. No cliffy, no npm packages.
- Parallel Execution: Independent checks (fmt, lint, test, type-check) MUST run in parallel, not sequentially.
- Sequential Prerequisites: If the project has build/codegen steps whose output is needed by subsequent checks, those steps MUST complete before parallel checks start.
- Buffered Output: Each parallel command's stdout/stderr MUST be buffered (piped, not inherited) to prevent interleaving.
- Real-Time Progress: Print a status line when each command starts and when it finishes (pass/fail).
- Output Ordering: After all checks complete, print buffered output of passed checks first, then ALL failed checks at the end — for easy debugging.
- No Output Loss: ALL stdout and stderr from every check MUST be printed regardless of success/failure. Print buffered output with
console.log or await Deno.stdout.write(...) — an unawaited Deno.stdout.write followed by Deno.exit(1) can exit before the bytes are flushed, and the failing check's output is exactly the part that is lost (2026-09-06: a generated check.ts did this and failed the no-output-loss item).
- Subprocess Spawn Safety (fork-loop prevention): Any
.ts file under scripts/ that calls Deno.Command, Deno.run, or otherwise spawns a subprocess at module top level MUST wrap the spawn in if (import.meta.main) { … }. Reason: deno test -A scripts/ walks the directory and imports every file to discover Deno.test(…) calls. Importing a file with an unguarded top-level Deno.Command("deno", ["test", "-A", …]) immediately spawns another deno test, which imports the same file again — recursive fork-bomb that exhausts the host within seconds. This pattern crashed the dev host on 2026-05-09 (multiple WindowServer kernel panics).
- Prefer inline
deno.json tasks over wrapper scripts: If a task is a single command (deno test -A, deno run --watch -A src/main.ts), declare it directly in deno.json "tasks". Generate a scripts/<name>.ts file ONLY for orchestration that needs Deno-script logic (e.g. parallel runs, conditional sequencing, output buffering). scripts/check.ts qualifies; scripts/test.ts and scripts/dev.ts do not — they should be inline tasks. When the user explicitly asks for a scripts/test.ts wrapper, apply rule 13 AND require an explicit path argument (do NOT call deno test -A without a path from inside scripts/ — that triggers the recursion above).
Workflow
- Analyze: Check existing
deno.json and scripts/.
- Scaffold Scripts: Create
scripts/check.ts if missing. The script must satisfy all Rules & Constraints above (parallel execution, buffered output, failed-last ordering, no external deps).
- Configure Tasks: Update
deno.json tasks to reference the scripts.
- Verify: Run
deno task check to ensure everything works.
Examples
deno.json tasks (preferred — inline tasks for single-command operations)
{
"tasks": {
"check": "deno run -A scripts/check.ts",
"test": "deno test -A",
"dev": "deno run --watch -A src/main.ts",
"prod": "deno run -A src/main.ts"
}
}
scripts/test.ts (only when user explicitly asks for a wrapper)
#!/usr/bin/env -S deno run -A
// Guard against re-entry: `deno test -A scripts/` would otherwise import
// this file, execute the spawn at top level, and cause a recursive
// fork-bomb (rule 13 in SKILL.md).
if (import.meta.main) {
const path = Deno.args[0];
if (!path) {
console.error("usage: scripts/test.ts <path> (passing no path triggers recursion)");
Deno.exit(2);
}
const { code } = await new Deno.Command("deno", {
args: ["test", "-A", path],
}).spawn().status;
Deno.exit(code);
}
Verification
1---2name: configure-deno-commands3description: Configure and maintain Deno development commands (check, test, dev, prod). Use when the user wants to set up or update the standard command interface in deno.json and scripts/ directory.4---56# Configure Deno Commands78This skill ensures a standardized development interface using Deno tasks and scripts.910## Context1112This skill can be invoked:13- **Standalone**: When a user wants to fix or update their Deno commands.14- **From init**: During project initialization to set up the standard interface.1516## Standard Interface1718The project must support these commands in `deno.json`:1920- `deno task check`: Comprehensive verification (build, lint, fmt, static analysis, tests).21- `deno task test`: Run all tests or a specific test if a path is provided.22- `deno task dev`: Run in development mode with watch mode.23- `deno task prod`: Run in production mode.2425## Rules & Constraints26271. **Idempotency**: Check existing `scripts/` and `deno.json` tasks before creating. Do not overwrite existing scripts unless user confirms.282. **Scripts Location**: All complex logic must reside in `.ts` files within the `scripts/` directory.293. **Task Definitions**: `deno.json` should point to these scripts.304. **Standard Interface Compliance**: The `check.ts` script must implement the full verification checklist.315. **Exit Codes**: Scripts must return non-zero exit codes on failure to break CI/CD and agent workflows.326. **No External Dependencies**: Generated scripts must only use Deno built-in APIs and `@std/` stdlib. No cliffy, no npm packages.337. **Parallel Execution**: Independent checks (fmt, lint, test, type-check) MUST run in parallel, not sequentially.348. **Sequential Prerequisites**: If the project has build/codegen steps whose output is needed by subsequent checks, those steps MUST complete before parallel checks start.359. **Buffered Output**: Each parallel command's stdout/stderr MUST be buffered (piped, not inherited) to prevent interleaving.3610. **Real-Time Progress**: Print a status line when each command starts and when it finishes (pass/fail).3711. **Output Ordering**: After all checks complete, print buffered output of passed checks first, then ALL failed checks at the end — for easy debugging.3812. **No Output Loss**: ALL stdout and stderr from every check MUST be printed regardless of success/failure. Print buffered output with `console.log` or `await Deno.stdout.write(...)` — an unawaited `Deno.stdout.write` followed by `Deno.exit(1)` can exit before the bytes are flushed, and the failing check's output is exactly the part that is lost (2026-09-06: a generated `check.ts` did this and failed the no-output-loss item).3913. **Subprocess Spawn Safety (fork-loop prevention)**: Any `.ts` file under `scripts/` that calls `Deno.Command`, `Deno.run`, or otherwise spawns a subprocess at module top level MUST wrap the spawn in `if (import.meta.main) { … }`. Reason: `deno test -A scripts/` walks the directory and **imports every file** to discover `Deno.test(…)` calls. Importing a file with an unguarded top-level `Deno.Command("deno", ["test", "-A", …])` immediately spawns another `deno test`, which imports the same file again — recursive fork-bomb that exhausts the host within seconds. This pattern crashed the dev host on 2026-05-09 (multiple WindowServer kernel panics).4014. **Prefer inline `deno.json` tasks over wrapper scripts**: If a task is a single command (`deno test -A`, `deno run --watch -A src/main.ts`), declare it directly in `deno.json` `"tasks"`. Generate a `scripts/<name>.ts` file ONLY for orchestration that needs Deno-script logic (e.g. parallel runs, conditional sequencing, output buffering). `scripts/check.ts` qualifies; `scripts/test.ts` and `scripts/dev.ts` do not — they should be inline tasks. When the user explicitly asks for a `scripts/test.ts` wrapper, apply rule 13 AND require an explicit path argument (do NOT call `deno test -A` without a path from inside `scripts/` — that triggers the recursion above).4142## Workflow43441. **Analyze**: Check existing `deno.json` and `scripts/`.452. **Scaffold Scripts**: Create `scripts/check.ts` if missing. The script must satisfy all Rules & Constraints above (parallel execution, buffered output, failed-last ordering, no external deps).463. **Configure Tasks**: Update `deno.json` tasks to reference the scripts.474. **Verify**: Run `deno task check` to ensure everything works.4849## Examples5051### deno.json tasks (preferred — inline tasks for single-command operations)52```json53{54 "tasks": {55 "check": "deno run -A scripts/check.ts",56 "test": "deno test -A",57 "dev": "deno run --watch -A src/main.ts",58 "prod": "deno run -A src/main.ts"59 }60}61```6263### scripts/test.ts (only when user explicitly asks for a wrapper)64```ts65#!/usr/bin/env -S deno run -A66// Guard against re-entry: `deno test -A scripts/` would otherwise import67// this file, execute the spawn at top level, and cause a recursive68// fork-bomb (rule 13 in SKILL.md).69if (import.meta.main) {70 const path = Deno.args[0];71 if (!path) {72 console.error("usage: scripts/test.ts <path> (passing no path triggers recursion)");73 Deno.exit(2);74 }75 const { code } = await new Deno.Command("deno", {76 args: ["test", "-A", path],77 }).spawn().status;78 Deno.exit(code);79}80```8182## Verification8384- [ ] `scripts/check.ts` exists and is executable.85- [ ] `deno.json` contains all standard tasks.86- [ ] `deno task check` passes cleanly.