deno-scripting
Guidelines for developing standalone Deno CLI scripts using TypeScript for troubleshooting, diagnostics, batch processing, and automation. Use when creating CLI tools, data processing scripts, reports, migration utilities, or any standalone TypeScript script running on Deno.
What this skill does
# Deno CLI Scripting
You are an expert in Deno and TypeScript development with deep knowledge of
building standalone CLI scripts, batch processing tools, and diagnostic
utilities using Deno's native TypeScript support and built-in tooling.
## TypeScript General Guidelines
### Basic Principles
- Use English for all code and documentation
- Always declare types for variables and functions (parameters and return
values)
- Avoid using `any` type - create necessary types instead
- Use JSDoc to document public classes and methods
- Write concise, maintainable, and technically accurate code
- Use functional and declarative programming patterns
- No configuration needed - Deno runs TypeScript natively
### Nomenclature
- Use PascalCase for types and interfaces
- Use camelCase for variables, functions, and methods
- Use kebab-case for file and directory names
- Use UPPERCASE for environment variables
- Use descriptive variable names with auxiliary verbs: `isLoading`, `hasError`,
`canDelete`
- Start each function with a verb
### Functions
- Write short functions with a single purpose
- Use arrow functions for simple operations and consistency
- Use async/await for asynchronous operations
- Prefer the RO-RO pattern (Receive Object, Return Object) for multiple
parameters
### Types and Interfaces
- Prefer `type` over `interface` for object shapes in scripts
- Avoid enums; use const objects with `as const`
- Use Zod for runtime validation when needed
- Use `readonly` for immutable properties
### Type Organization
**Guide**: For projects with multiple scripts sharing types, organize types in a
dedicated directory.
#### When to Use Separate Type Files
| Project Size | Recommendation |
| ----------------------------- | ----------------------------------- |
| Single script | Keep types inline in the script |
| 2-3 scripts with shared types | Create `types/index.ts` |
| Larger projects | Create `types/` with multiple files |
#### Directory Structure
```
project/
├── main.ts # Config, utilities, re-exports types
├── types/
│ └── index.ts # All shared type definitions
└── scripts/
├── script-a.ts # Imports types from main.ts or types/
└── script-b.ts
```
#### Type File Pattern
```typescript
// types/index.ts
/**
* Shared Type Definitions
*
* Domain types used across multiple scripts.
*/
// =============================================================================
// Domain Types
// =============================================================================
/** User record from database */
export type User = {
readonly id: string;
readonly name: string;
readonly email: string;
};
/** User with computed fields */
export type UserWithBalance = User & {
readonly balance: string;
};
// =============================================================================
// API Response Types
// =============================================================================
export type ApiResponse<T> = {
readonly success: boolean;
readonly data?: T;
readonly error?: string;
};
// =============================================================================
// Script-Specific Types (export for reuse)
// =============================================================================
/** Result of a batch operation */
export type BatchResult<T> =
| { success: true; data: T }
| { success: false; error: string };
```
#### Re-exporting from main.ts
```typescript
// main.ts
import "@std/dotenv/load";
// Re-export all types for convenient imports
export type {
ApiResponse,
BatchResult,
User,
UserWithBalance,
} from "./types/index.ts";
// ... rest of main.ts (config, utilities)
```
#### Importing in Scripts
```typescript
// scripts/process-users.ts
import {
type BatchResult,
config,
type User,
type UserWithBalance,
} from "../main.ts";
// Script-specific types can stay inline if not shared
type ProcessingStats = {
total: number;
processed: number;
failed: number;
};
```
#### Type Naming Conventions
| Type Category | Naming Pattern | Example |
| --------------- | ----------------- | ----------------------------- |
| Domain entities | PascalCase noun | `User`, `Transaction` |
| With additions | `EntityWithX` | `UserWithBalance` |
| API responses | `EntityResponse` | `TransactionResponse` |
| State objects | `EntityState` | `AirdropState` |
| Results | `OperationResult` | `SubmitResult`, `FetchResult` |
| Status enums | `EntityStatus` | `TransactionStatus` |
---
## Questions to Ask First
Before implementing, clarify these with the user to determine which patterns to
apply:
1. **Input format**: "What is the input format - JSON file, CSV file, or text
file with one item per line?"
2. **Output format**: "Should the output be JSON, CSV, or both? Do you need a
human-readable summary?"
3. **Environment**: "Will this run against staging/testnet or
production/mainnet? Do you need environment switching?"
4. **Batch processing**: "How many items should be processed in parallel per
batch? (default: 50)"
5. **Resumability**: "Should the script be resumable if interrupted? (saves
state after each operation)"
6. **Dry run**: "Do you want a --dry-run flag to preview without making
changes?"
---
## Guides
The following sections are **templates and patterns** to apply based on the
user's answers above. Adapt them to the specific use case.
---
## Project Structure
```
project/
├── deno.json # Configuration, tasks, and imports
├── .env # Environment variables (gitignored)
├── .env.example # Environment variables template
├── main.ts # Shared configuration and utilities
└── scripts/
├── <script-name>.ts # Script files
└── ...
```
## deno.json Configuration
```json
{
"tasks": {
"check": "deno fmt --check && deno check scripts/*.ts",
"<task-name>": "deno run --allow-net --allow-read --allow-write --allow-env scripts/<script-name>.ts"
},
"imports": {
"@std/cli": "jsr:@std/cli@1",
"@std/dotenv": "jsr:@std/[email protected]"
}
}
```
**Add imports based on needs:**
```bash
# Always needed
deno add jsr:@std/dotenv
# If using CLI arguments
deno add jsr:@std/cli
# If reading/writing CSV
deno add jsr:@std/csv
```
## Quality Checks
Always run before committing:
```bash
deno fmt
deno check scripts/*.ts
# Or use task
deno task check
```
## Environment Configuration
**Guide**: Always use `@std/dotenv` for environment variables. Never hardcode
secrets.
```typescript
// main.ts
import "@std/dotenv/load";
// Environment selection (if user needs staging/production switching)
export const ENV = Deno.env.get("ENV") || "production";
export const isStaging = ENV === "staging";
// Validation helper
const assertEnv = (name: string): string => {
const value = Deno.env.get(name);
if (!value) {
console.error(`Error: ${name} environment variable is required`);
Deno.exit(1);
}
return value;
};
// Load required env vars
export const API_KEY = assertEnv("API_KEY");
// Environment-aware URLs (if needed)
export const API_BASE = isStaging
? "https://staging.api.example.com"
: "https://api.example.com";
// Environment-aware file naming (if user needs environment switching)
export const getInputFile = (baseName: string): string =>
isStaging ? `./${baseName}.staging.json` : `./${baseName}.production.json`;
export const getOutputFile = (baseName: string): string =>
isStaging ? `./${baseName}.staging.json` : `./${baseName}.production.json`;
```
**.env.example:**
```
ENV="production"
API_KEY="your_api_key_here"
```
## Script Structure
**Guide**: Use arrow functions throughout. Organize with clear sections.
```typescript
import "@std/dotenv/load";
import { parseArgs } fromRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.