configure-deno-commands
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.
SKILL.mdplugins/flowai/skills/configure-deno-commands/SKILL.md
GitHubConfigure 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/anddeno.jsontasks before creating. Do not overwrite existing scripts unless user confirms. - Scripts Location: All complex logic must reside in
.tsfiles within thescripts/directory. - Task Definitions:
deno.jsonshould point to these scripts. - Standard Interface Compliance: The
check.tsscript 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.logorawait Deno.stdout.write(...)— an unawaitedDeno.stdout.writefollowed byDeno.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 generatedcheck.tsdid this and failed the no-output-loss item). - Subprocess Spawn Safety (fork-loop prevention): Any
.tsfile underscripts/that callsDeno.Command,Deno.run, or otherwise spawns a subprocess at module top level MUST wrap the spawn inif (import.meta.main) { … }. Reason:deno test -A scripts/walks the directory and imports every file to discoverDeno.test(…)calls. Importing a file with an unguarded top-levelDeno.Command("deno", ["test", "-A", …])immediately spawns anotherdeno 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.jsontasks over wrapper scripts: If a task is a single command (deno test -A,deno run --watch -A src/main.ts), declare it directly indeno.json"tasks". Generate ascripts/<name>.tsfile ONLY for orchestration that needs Deno-script logic (e.g. parallel runs, conditional sequencing, output buffering).scripts/check.tsqualifies;scripts/test.tsandscripts/dev.tsdo not — they should be inline tasks. When the user explicitly asks for ascripts/test.tswrapper, apply rule 13 AND require an explicit path argument (do NOT calldeno test -Awithout a path from insidescripts/— that triggers the recursion above).
Workflow
- Analyze: Check existing
deno.jsonandscripts/. - Scaffold Scripts: Create
scripts/check.tsif missing. The script must satisfy all Rules & Constraints above (parallel execution, buffered output, failed-last ordering, no external deps). - Configure Tasks: Update
deno.jsontasks to reference the scripts. - Verify: Run
deno task checkto 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
-
scripts/check.tsexists and is executable. -
deno.jsoncontains all standard tasks. -
deno task checkpasses cleanly.