name: shell-conventions description: Guides writing and updating bash scripts, CLI wrappers, and Node.js-based helper scripts. Use this when modifying scripts in the scripts/ folder, writing release utilities, or executing command-line processes. Do NOT use for standard Commander CLI commands inside src/commands/ or test files.
Shell Conventions and Coding Guidelines
Critical
- Portability and Strict Mode: All bash scripts must use
#!/usr/bin/env bashas their shebang (never#!/bin/bashor#!/bin/sh) and immediately enable strict mode withset -euo pipefail. - TypeScript ESM Imports: Any TypeScript scripts executed in the scripts context (such as tsdown compiled files) must use ESM imports with explicit
.jsextensions (e.g.import { x } from './x.js';). - No Unsafe Evaluations: Avoid using
evalor executing raw string interpolations in bash or Node'schild_process.exec. Use safe argument arrays or library execution helpers likeunrunwhere appropriate.
Instructions
- Set Up the Script Environment:
- Create the target shell script in the
scripts/directory. - Add the strict mode header:
#!/usr/bin/env bash set -euo pipefail - Verify that the script has execute permissions (
chmod +x scripts/filename.sh).
- Create the target shell script in the
- Resolve Paths Relativistically:
- Determine the script directory relative to the project root to ensure robustness regardless of execution directory:
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" - Verify that all relative paths used in commands (e.g.,
pnpm run,vitest) are correctly absolute or relative toPROJECT_ROOT.
- Determine the script directory relative to the project root to ensure robustness regardless of execution directory:
- Handle Arguments and Flags Safely:
- Use standard parameter expansion for default values to prevent "unbound variable" errors under
set -u:ENV_TARGET="${1:-dev}" - Verify behavior by executing the script with and without arguments.
- Use standard parameter expansion for default values to prevent "unbound variable" errors under
- Implement Clean Up Traps:
- Use shell
trapdefinitions to clean up temporary files or background processes on exit:TMP_DIR=$(mktemp -d) cleanup() { rm -rf "$TMP_DIR" } trap cleanup EXIT - Verify cleanup by sending a SIGINT (Ctrl+C) or causing a deliberate command failure, ensuring the cleanup routine runs.
- Use shell
Examples
Example 1: Creating a test wrapper script
User says: "I want a script to run specific Vitest suites with coverage" Actions taken:
- Create
scripts/run-coverage.shwith the following contents:#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" cd "$PROJECT_ROOT" SUITE="${1:-scoring}" echo "Running Vitest coverage for suite: $SUITE" npx vitest run --coverage "tests/$SUITE" - Run
chmod +x scripts/run-coverage.sh. - Verify execution by running
./scripts/run-coverage.sh scoring. Result: An executable, portable shell wrapper that follows strict execution principles.
Common Issues
- Error: "...: unbound variable":
- Fix: You are accessing a parameter or environment variable that is not set. Provide a fallback default value using
${VAR:-default}or check if it is set first.
- Fix: You are accessing a parameter or environment variable that is not set. Provide a fallback default value using
- Error: "No such file or directory" when referencing paths:
- Fix: Ensure you are changing directory to the project root or utilizing an absolute script directory calculation (e.g.
cd "$(dirname "${BASH_SOURCE[0]}")").
- Fix: Ensure you are changing directory to the project root or utilizing an absolute script directory calculation (e.g.
- Error: ESM Module resolution failure in TS script runner:
- Fix: Check imports in scripts. In TypeScript scripts running under node, imports must contain explicit
.jsextensions, even when importing a.tsfile.
- Fix: Check imports in scripts. In TypeScript scripts running under node, imports must contain explicit
Related skills
Next.js App Router Expert
Development
A skill that turns Claude into a Next.js App Router expert.
Claude CodeCursoradvanced
890
234
3,226
README Generator
Development
Creates professional and comprehensive README.md files for your projects.
claudeCursorWindsurfbeginner
259
72
1,129
API Documentation Writer
Development
Generates comprehensive API documentation in OpenAPI/Swagger format.
claudeCursorWindsurfintermediate
156
44
999