# SpecVerse

[![Smoke](https://github.com/SpecVerse/specverse-self/actions/workflows/smoke.yml/badge.svg)](https://github.com/SpecVerse/specverse-self/actions/workflows/smoke.yml)
[![npm](https://img.shields.io/npm/v/@specverse/self.svg)](https://www.npmjs.com/package/@specverse/self)

**Define Once, Implement Anywhere.**

SpecVerse is a declarative specification language for defining business domains, models, and systems. Write a `.specly` specification, and the engine generates the complete application — backend, frontend, CLI, documentation, diagrams, and tools.

This repository is the **self-specification** — SpecVerse specifying and implementing itself. It's the production release.

## How It Works

```
921-line self-spec  -->  [4 engine packages]  -->  465+ generated files
                                                    ├── Fastify REST API
                                                    ├── Prisma + SQLite
                                                    ├── React frontend (DevShell)
                                                    ├── 9-command CLI (commander)
                                                    ├── VSCode extension
                                                    ├── MCP server
                                                    └── 12+ Mermaid diagrams
```

## Engine Packages

Published to npm under the `@specverse` scope. The toolchain uses subpath exports:

| Package | Version | Purpose |
|---------|---------|---------|
| `@specverse/self` | `5.21.10` | Production CLI + templates + self-specification |
| `@specverse/types` | `5.4.2` | AST types, engine interfaces, shared spec-rules + step-matching types |
| `@specverse/entities` | `5.7.5` | Entity modules (11 types, 9 facets), schema composition |
| `@specverse/engines` | `6.97.14` | Toolchain — `./parser`, `./inference`, `./realize`, `./generators`, `./ai`, `./registry`, `./bundles` |
| `@specverse/runtime` | `5.12.25` | Framework-agnostic view walker, React + Tailwind adapters, test-harness |
| `@specverse/assets` | `1.25.1` | Pure content — prompts, examples, learning materials (no JS) |

> Versions reflect the latest published to real npm. See `CLAUDE.md` for in-flight version landscape and what's new in each minor.

## Quick Start

```bash
# Install globally
npm install -g @specverse/self

# Verify the install works end-to-end (60-90s, no flags or args needed)
spv smoke

# Initialize a new project (copies a template skeleton).
#   spv init my-app                          # default template (Category+Item
#                                            # canonical spec, ReactAppRuntime)
#   spv init my-app --template full-stack    # rich User/Project/Task demo
#   spv init my-app --template backend-only  # standalone API
#   spv init my-app --template frontend-only # standalone SPA
#   spv init my-app --static                 # ReactAppStarter — generated
#                                            # frontend is a fully standalone
#                                            # starter kit (no @specverse/runtime
#                                            # dep; editable source).
spv init my-app

# Generate the full application from the spec
cd my-app
spv realize all specs/main.specly -m manifests/implementation.yaml -o generated/code

# Build and run
cd generated/code
npm install && npm run db:setup
npm run dev
```

### `spv smoke` — verify your install

Anywhere you can run `npm install -g @specverse/self`, you can run
`spv smoke` to confirm the toolchain works end-to-end:

```bash
npm install -g @specverse/self && spv smoke
```

It spins up a throwaway project from the default template, realizes
it, starts a backend, hits a CRUD round-trip, and tears down. If it
prints `New-user smoke test passed ✅` you're good. If it doesn't,
the failing step + backend logs are printed in place — open an issue
with that output.

A separate `npm run smoke:static` exercises the ReactAppStarter path
(`spv init --static`) end-to-end: generates the standalone frontend,
builds it with vite, and verifies belongsTo FK round-trips.

This works in any environment with Node 18+: a fresh laptop, a blank
GitHub Codespace, a Docker container, a cloud shell.

### `npm run setup-variants` — drive every flag combo locally

For interactive testing of all the `spv init` options simultaneously:

```bash
npm run setup-variants
```

Preps six side-by-side projects under `tests/variants/`:

| Variant | `spv init` invocation | Ports |
|---|---|---|
| v-default | *(no flags)* — Category+Item canonical spec | BE 3010, FE 5180 |
| v-default-static | `--static` — ReactAppStarter | BE 3011, FE 5181 |
| v-fullstack | `--template full-stack` — rich demo | BE 3012, FE 5182 |
| v-fullstack-static | `--template full-stack --static` | BE 3013, FE 5183 |
| v-backend | `--template backend-only` | BE 3014 |
| v-frontend | `--template frontend-only` | FE 5184 → v-default's BE |

Each variant gets its own `.env` (unique ports) and `run-dev.sh`
helper, so you can boot all six simultaneously without collisions.
The output dir is gitignored — regenerate whenever.

## `init` vs `realize` — two different commands

**Important distinction** that surprises new users:

- **`spv init <name> --template <t>`** — copies a *skeleton* from `templates/<t>/` into a new directory. The skeleton contains specs, manifests, CLAUDE.md, package.json — but **no generated code**. It's a starting point.
- **`spv realize all ...`** — calls the engines to generate `generated/code/` fresh from the current skeleton's spec and manifest. This is where the backend, frontend, CLI, VSCode extension, MCP server, diagrams etc. are actually produced.

The templates are live skeletons, not pre-baked projects. Every `spv realize` regenerates from scratch using whatever engine version is installed.

Available templates:

- **`default`** (implicit) — backend + frontend monorepo scaffold. Spec is the canonical `Category + Item` starter (shared with app-demo's Server Manager "new spec" action) — small enough to read in 30 seconds, rich enough to exercise the generated-UI rules (lifecycle dropdowns, belongsTo FK dropdowns, FK resolution in list/detail/dashboard).
- **`full-stack`** — same monorepo scaffold, but with the rich `User / Project / Task` demo spec (lifecycles, relationships, behaviors, events). Useful when demoing everything SpecVerse can do from one spec.
- **`backend-only`** — standalone Fastify + Prisma API. No frontend generated.
- **`frontend-only`** — standalone React SPA against an external API. No backend generated.

All four templates compile end-to-end with zero TypeScript errors and zero `npm audit` vulnerabilities.

**`--static`** is an orthogonal flag that works with any template: it pre-swaps the manifest so `spv realize` emits a **ReactAppStarter** frontend (fully standalone, editable source, no `@specverse/runtime` dep) instead of the default **ReactAppRuntime** (slim shell that loads views at runtime). Pick ReactAppStarter when you want to fork and customize the generated React; pick ReactAppRuntime when you want a thin generated surface you can regenerate freely without clobbering edits.

## Repository Structure

```
specverse-self/
├── specs/
│   └── main.specly              # The self-specification (921 lines, 5 components)
├── manifests/
│   └── implementation.yaml      # Fastify + Prisma + SQLite + React + Commander.js
├── templates/                   # Skeletons used by `spv init`
│   ├── default/                 # Default — monorepo scaffold; spec loaded at
│   │                            # init time from engines' canonical default
│   ├── full-stack/              # Monorepo scaffold + rich User/Project/Task demo
│   ├── backend-only/            # Standalone Fastify+Prisma, no UI
│   └── frontend-only/           # Standalone React SPA, external API
├── bootstrap/
│   └── cli/                     # Frozen bootstrap CLI (promoted from generated/code)
├── generated/
│   └── code/                    # Current realize output (465+ files)
│       ├── backend/             # Fastify + Prisma, generated CLI, guards.ts
│       ├── frontend/             # React app (slim via @specverse/runtime)
│       └── tools/               # MCP server, VSCode extension
├── examples/                    # 54 composed examples from entity modules
├── scripts/
│   ├── compose-examples.mjs     # Compose examples from entity modules
│   └── indexing/                # Cross-repo content comparison tools
└── docs/
    ├── GOLDEN-RULES.md          # 41 permanent guiding principles
    ├── guides/                  # Architecture, entity, engine guides
    └── RELEASE-AUDIT-ACTIONS.md # 53 audit items, all resolved
```

## Self-Specification Components

| Component | Models | Purpose |
|-----------|-------:|---------|
| SpecLanguage | 27 | The language itself — Specification, Component, Model, Controller, Service, Event, View, Deployment |
| BuildSystem | 11 | Entity modules, convention grammars, inference rules, schema fragments |
| ToolsSupport | 7 | VSCode extension, MCP server (generated via distributions entity type) |
| AISupport | 2 | AI orchestrator, workflows |
| CLI | 9 commands | validate, infer, realize, init, gen, dev, cache, ai, session |

## CURVED Operations

SpecVerse uses **CURVED**, not CRUD:

- **C**reate — instantiate a new entity
- **U**pdate — modify existing entity (full replace)
- **R**etrieve — fetch one or many
- **V**alidate — check business rules without persisting
- **E**volve — lifecycle state transitions (draft → open → closed)
- **D**elete — remove (soft or hard)

Custom actions sit alongside CURVED as `POST /resource/:id/<actionName>`. Generated controllers publish typed events (`${Model}Created`/`Updated`/`Deleted`/`Evolved`) for every CURVED operation that mutates state.

## Attribute Category System

Every attribute is tagged at parse time with one of three categories so consumers don't fall back on name-based heuristics:

- **`business`** — user-facing domain data (title, price, status)
- **`metadata`** — synthetic/system fields (id, createdAt, updatedAt, version)
- **`relationship`** — foreign-key scalars for belongsTo relations

Forms hide `metadata` by default. List views colour-code `relationship` columns blue and `lifecycle` columns purple. This is set by `AttributeProcessor`/`ModelProcessor` during parse and flows through inference → YAML → realize without needing to re-classify.

## AI Behavior Generation

Service operations and custom actions that can't be matched to a convention are handed to Claude via `engines/src/ai/behavior-ai-service.ts`. Each unmatched step becomes a pure TypeScript function emitted into `behaviors/<ControllerName>.ai.ts` and imported back into the controller at realize time. Prompts live under `generated/code/prompts/core/standard/v9/`; the current active set is **v9**.

Outputs are cached in `.specverse/ai-cache/` keyed on `sha256(step + model + operation + inputs + promptVersion)` so re-running `realize` with unchanged steps is free.

## Key Principles

See [GOLDEN-RULES.md](docs/GOLDEN-RULES.md) for the full 41 rules. Highlights:

- **R8**: Fix generators, never hand-edit generated output
- **R11**: Let engines handle their own initialization
- **R12**: Adding an entity type = 3 changes only
- **R18**: No version numbers in code identifiers
- **R24**: CURVED not CRUD
- **R25**: Engines live in specverse-engines, CLI orchestration separate
- **R31**: Bootstrap promote cycle is frozen — edit engine → realize self → test → promote

## Related Repositories

| Repo | Purpose |
|------|---------|
| [specverse-engines](https://github.com/SpecVerse/specverse-engines) | 4 engine packages (types, entities, engines, runtime) — source of truth for all engine code |
| [specverse-app-demo](https://github.com/SpecVerse/specverse-app-demo) | Dynamic runtime demo — interprets spec at runtime (complement to the static generation in this repo) |
| [specverse-lang-doc](https://github.com/SpecVerse/specverse-lang-doc) | Docusaurus documentation site |

## License

MIT
