Install
$ agentstack add skill-rashidee-co2-skills-specgen-node-cli-web ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Self-Hosted Node.js CLI Web Application Specification Generator
This skill generates a comprehensive specification document (Markdown) that serves as a blueprint for building a lightweight Node.js web application that is installed via npm install -g , started via start, and accessed at http://IP:PORT. The spec is intended to be followed by a developer or coding agent to produce a fully functional, publishable package.
The specification does NOT generate code. It produces a detailed, opinionated technical document describing every layer of the application — from the pnpm workspace layout to the publish pipeline to the forced-password-change middleware — so that implementation becomes a mechanical exercise.
Architecture model (non-negotiable): Single-process, local-first. One Node process serves both the REST API and the embedded pre-built web UI. All state lives on the user's machine. There is no hosted backend. The web app is compiled to static assets at publish time; end users never run a build.
Technology Stack
Core Stack (Always Included)
These are the fixed versions the spec targets. Do not deviate unless the user explicitly requests different versions.
| Layer | Technology | Version Constraint | |---|---|---| | Runtime | Node.js | 22 LTS (engines.node: ">=22") | | Package manager (dev) | pnpm workspaces | >=9 | | Language | TypeScript | ^5.6, strict mode mandatory | | CLI framework | commander | ^12 | | Web framework | Hono (@hono/node-server) | ^4 | | Frontend | React + Vite (built SPA, embedded) | React ^19, Vite ^6 | | Styling | Tailwind CSS | ^4 | | Components | shadcn/ui (vendored) | latest | | Validation | Zod | ^3 | | ORM | Drizzle ORM + drizzle-kit | ^0.36 / ^0.28 | | Database | SQLite via better-sqlite3 | ^11 | | Auth | Hand-rolled sessions — node:crypto only | n/a | | CLI/package build | tsup | ^8 | | Lint + format | Biome | ^1.9 | | Tests | Vitest + Playwright | ^2 / ^1.48 | | Terminal output | picocolors | ^1 |
> Why Hono: framework-agnostic single-process embedding, ~14 kB core, first-class > TypeScript inference, and serve-static for shipping the built SPA from inside the > installed package.
Explicitly Excluded
The generated spec must NOT include any of the following — where the coding agent's general habits conflict with this list, this list wins:
- Next.js — cannot be packaged as a global binary
- Express — Hono supersedes it
- Better Auth or any auth framework — no self-serve signup exists in this model
- Any database server (PostgreSQL, MySQL, MongoDB, Redis, ...)
- Docker — distribution is npm; daemonization is the OS's job
- Email flows, self-serve registration, OAuth/social login, JWTs — see auth rules
- CORS middleware — the UI is same-origin by construction
Optional Integration Versions
Include in the version table only when the corresponding integration is selected (see Determining Optional Components).
| Component | Version | When Selected | |---|---|---| | @tanstack/react-table | 8.x | DataGrid = yes | | recharts | 2.x | Charts = yes | | react-day-picker + date-fns | 9.x / 4.x | DatePickers = yes | | @tiptap/react + @tiptap/starter-kit | 2.x | RichText = yes | | env-paths | 3.x | Optional helper for the data directory (may resolve manually instead) |
New runtime dependencies beyond these require explicit human approval — the published tarball SHOULD stay under 5 MB excluding better-sqlite3.
Monorepo Structure (development)
The spec targets this fixed pnpm workspace layout. Package responsibilities are strict:
project-root/
├── pnpm-workspace.yaml
├── CLAUDE.md
├── biome.json
├── packages/
│ ├── core/ # shared: Zod schemas, types, constants
│ │ └── src/
│ │ ├── schemas/ # one file per domain (user.ts, session.ts, ...)
│ │ └── index.ts
│ ├── server/ # Hono app + Drizzle + auth
│ │ ├── drizzle/ # generated SQL migrations (committed, shipped)
│ │ ├── src/
│ │ │ ├── app.ts # Hono app factory (routes + middleware)
│ │ │ ├── db/
│ │ │ │ ├── schema.ts
│ │ │ │ ├── index.ts # connection factory (takes data dir path)
│ │ │ │ └── bootstrap.ts # first-run: migrate + create default admin
│ │ │ ├── auth/ # sessions, password hashing, middleware
│ │ │ ├── features// # routes.ts, service.ts, schema.ts, __tests__/
│ │ │ └── lib/ # logger, env/config
│ │ └── vitest.config.ts
│ ├── web/ # React SPA (Vite)
│ │ ├── src/
│ │ │ ├── routes/ # login, force-change-password, users, settings,
│ │ │ ├── components/ui/ # shadcn vendored
│ │ │ └── lib/api.ts # typed fetch client (hono/client RPC)
│ │ └── vite.config.ts
│ └── cli/ # THE published package
│ ├── package.json # name: , bin, files: ["dist","static","drizzle"]
│ ├── src/
│ │ ├── index.ts # #!/usr/bin/env node — commander program
│ │ └── commands/ # start.ts, status.ts, reset-admin.ts,
│ └── tsup.config.ts
└── e2e/ # Playwright against a started instance
Publish pipeline (the critical mechanic): packages/cli is the only published artifact. Its build step (1) tsup-bundles the CLI + server into dist/ with better-sqlite3 marked external — it is a native module and must remain a real dependency, (2) runs vite build in packages/web and copies the output to cli/static/, (3) copies server/drizzle/ migrations into the package. The published package is therefore self-contained: bundle + static UI + migrations.
Structural rules: feature-folder colocation, no barrel files, `.
When the Skill Triggers
Generate the spec when the user provides an application name and version that corresponds to one of the custom applications defined in CLAUDE.md. The skill reads all required inputs from the project's context files — no interactive Q&A is needed for the core inputs.
The user invokes this skill by specifying the target application and version, for example:
/specgen-node-cli-web my_tool v1.0.0/specgen-node-cli-web my_tool v1.0.0 module:Inventory/specgen-node-cli-web "My Tool" v1.0.0
The skill then locates the matching context folder and reads all input files automatically.
Version Gate
Before starting any work, resolve the application folder first (see Input Resolution below), then check CHANGELOG.md in the application folder (/CHANGELOG.md):
- If
/CHANGELOG.mddoes not exist, skip this check (first-ever execution for this application). - If
/CHANGELOG.mdexists, scan all## vX.Y.Zheadings and determine the highest version using semantic versioning comparison. - Compare the requested version against the highest version:
- If requested version >= highest version: proceed normally.
- If requested version **/CHANGELOG.md. Execution rejected."` Do NOT proceed with any work.
Input Resolution
This skill uses standardized input resolution. Provide:
| Argument | Required | Example | Description | |----------|----------|---------|-------------| | ` | Yes | my_tool | Application name to locate the context folder | | | Yes | v1.0.0 | Version to scope processing | | module: | No | module:Inventory` | Limit generation to a single module |
Application Folder Resolution
The application name is matched against root-level application folders:
- Strip any leading
_prefix from folder names (e.g.,1_my_tool→my_tool) - Match case-insensitively against the provided application name
- Accept snake_case, kebab-case, or title-case input (all match the same folder)
- If no match found, list available applications and stop
Auto-Resolved Paths
| File | Resolved Path | |------|---------------| | PRD.md | /context/PRD.md | | Module Models | /context/model/ | | HTML Mockups | /context/mockup/ | | Output (specification) | /context/specification/ |
Version Filtering
When a version is provided, only include user stories, NFRs, and constraints from versions ` is provided:
- Only generate the
SPEC.mdfor that specific module - Other existing module spec files remain untouched
SPECIFICATION.md(root) gets a partial update — only that module's entry in the TOC
is added or updated; all other TOC entries are preserved as-is
- The mandatory
user-management/SPEC.mdis regenerated only when the filtered module
IS the user management module
Gathering Input
The specification is driven by six input sources read from the project's context files. The skill does NOT ask the user for auth, ports, or optional component choices — it determines these automatically from the context.
Input 1: Application Name (from CLAUDE.md)
From CLAUDE.md (already loaded in context), locate the target application under the Custom Applications section. Extract:
- Application name: The section heading (e.g., "Home Inventory", "Team Board")
- Application description: The description paragraph below the heading
- Dependencies: The "Depends on" list — a self-hosted local-first app normally has
none; any external service dependency becomes an optional HTTP integration in the spec
The application name is used to derive:
- Package name / binary name: kebab-case (e.g.,
home-inventory) — the npm package
name, the bin entry, AND the per-platform data directory name
- App title: Title-case, used in the SPA `` and topbar
- Env var prefix: SCREAMING_SNAKE of the binary name is NOT used — the CLI env vars
are always APP_PORT, APP_HOST, APP_DATA_DIR
Input 2: User Stories (from PRD.md)
Read /context/PRD.md. This file contains all user stories organized by module. Extract:
- System modules: Modules under
# System Module(e.g., Authentication, User
Management). These map onto the mandatory auth/user-management blueprint — merge their IDs into its traceability rather than generating a competing design.
- Business modules: Modules under
# Business Module. Each becomes a server feature
folder (server/src/features//), a set of SPA routes, and a /SPEC.md.
- CLI-facing stories: Stories describing terminal interactions (e.g., "start the app
from my terminal", "reset the admin password offline") map to CLI commands.
Important: Items with strikethrough (~~text~~) are deprecated — do NOT include them as active requirements. List them in the "Removed / Replaced" subsection of the traceability table. Track the [v1.0.x] version tag for each item and carry it through to the generated specification's traceability section.
Input 3: Non-Functional Requirements (from PRD.md)
Each module's ### Non Functional Requirement section informs:
- Pagination, filtering, and list-size decisions (Hono query params + SPA table setup)
- Validation rules (character limits, formats) → Zod schemas in
core/ - Performance constraints (response budgets, LAN access expectations)
- Security posture beyond the mandatory auth baseline
Input 4: Constraints (from PRD.md)
Each module's ### Constraint section defines hard boundaries:
- Status enum values → Drizzle
text({ enum })columns + shared Zod enums - Business rules → service-layer invariants with tests
- Access control (e.g., "only ADMIN can ...") → route guard configuration
Input 5: Module Model (from model/ folder)
Read /context/model/MODEL.md first as the index, then the individual module model files (e.g., model/inventory/model.md + schemas.json). The module model maps to:
- Drizzle table definitions in
server/src/db/schema.ts(field-for-field, not placeholder) - Zod schemas in
core/src/schemas/.ts - Service method signatures and route request/response DTOs
- Generated SQL migrations shipped in
server/drizzle/
This skill expects relational models (modelgen-relational) since the datastore is SQLite. If only a NoSQL model exists, flatten document structures into relational tables and note the mapping decisions in the spec.
Input 6: HTML Mockup Screens (from mockup/ folder)
Read /context/mockup/MOCKUP.html first as the index, then the HTML files organized by role in subfolders. The mockups map to:
- React page components in
web/src/routes/(one per screen) - shadcn/ui component selections (Table vs Cards, Dialog vs Sheet, etc.)
- Navigation structure and per-role menu items
- Tailwind v4 design tokens (colors, font, radius extracted from mockup CSS)
Role folders inform access control, NOT URL paths. mockup/admin/users.html means the route requires the admin role — the URL is /users, never /admin/users. If no mockups exist for the mandatory auth screens (login, force-change-password, users, settings), spec them from the auth blueprint anyway — they are not optional.
PRD.md Extended Sections
Before determining optional components, check PRD.md for the following extended sections:
Architecture Principle Extraction
If PRD.md contains an # Architecture Principle section, extract patterns that affect decisions — but remember this skill's architecture model is fixed. Principles like "container based deployment" or "microservices" CONFLICT with the single-process local-first model; surface the conflict to the user instead of silently complying. Compatible principles (e.g., "offline-first", "no external services") are cited in the spec's overview.
Design System Extraction
If PRD.md contains a # Design System section with a file reference, resolve and read it, then map design tokens into the Tailwind v4 CSS-first theme (@theme block in the SPA's global CSS) and shadcn/ui CSS variables. If absent, derive tokens from the mockup CSS (existing behavior).
High Level Process Flow Extraction
If PRD.md contains a # High Level Process Flow section, flows inform service-method sequencing, status enums surfaced in list filters, and the Playwright E2E scenario order. If absent, derive flow from user stories only.
Determining Optional Components
The mandatory baseline (CLI contract, data directory, bootstrap, auth and user lifecycle) is never optional. Beyond it, the skill determines optional components by analyzing PRD.md NFRs, constraints, and mockups:
| Content Pattern | Component Selection | |---|---| | NFRs mention "sortable columns", "bulk select", "export CSV", grids | DataGrid = yes (TanStack Table, shadcn Data Table) | | NFRs mention "chart", "graph", "statistics", "dashboard metrics" | Charts = yes (Recharts) | | NFRs mention "date picker", "date range", "calendar" | DatePickers = yes (react-day-picker) | | User stories mention "rich text", "WYSIWYG", "formatted content" | RichText = yes (Tiptap) | | User stories mention uploading files/images | FileStorage = yes (files under /files/, streamed by a Hono route — never inside the install dir) | | NFRs mention periodic/background work ("every hour", "auto-prune", "scheduled") | InProcessJobs = yes (setInterval in the server process; no external queue, no daemon) | | CLAUDE.md dependencies or NFRs reference an external REST API | HttpIntegration = yes (native fetch, config-driven base URL in config.json) | | PRD.md defines CLI commands beyond start/status/reset-admin | ExtraCommands = yes (list them) |
Summary of Determination
After analyzing all inputs, produce a determination summary before generating the spec. Present it to the user for confirmation:
Mandatory baseline: CLI (start/status/reset-admin) + data dir + bootstrap + scrypt session auth
Optional Component Determination:
- DataGrid: yes (from PRD.md → NFR mentions sortable item list with bulk delete)
- Charts: no
- DatePickers: yes (from PRD.md → purchase date field)
- RichText:
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [rashidee](https://github.com/rashidee)
- **Source:** [rashidee/co2-skills](https://github.com/rashidee/co2-skills)
- **License:** MIT
- **Homepage:** https://compound-context.com/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.