# Specgen Node Cli Web

> >

- **Type:** Skill
- **Install:** `agentstack add skill-rashidee-co2-skills-specgen-node-cli-web`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [rashidee](https://agentstack.voostack.com/s/rashidee)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [rashidee](https://github.com/rashidee)
- **Source:** https://github.com/rashidee/co2-skills/tree/main/skills/specgen-node-cli-web
- **Website:** https://compound-context.com/

## Install

```sh
agentstack add skill-rashidee-co2-skills-specgen-node-cli-web
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## 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`):

1. If `/CHANGELOG.md` does not exist, skip this check (first-ever execution for this application).
2. If `/CHANGELOG.md` exists, scan all `## vX.Y.Z` headings and determine the **highest version** using semantic versioning comparison.
3. 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:
1. Strip any leading `_` prefix from folder names (e.g., `1_my_tool` → `my_tool`)
2. Match case-insensitively against the provided application name
3. Accept snake_case, kebab-case, or title-case input (all match the same folder)
4. 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.md` for 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.md` is 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.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-rashidee-co2-skills-specgen-node-cli-web
- Seller: https://agentstack.voostack.com/s/rashidee
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
