npm package: @manifesto-ai/codegen
Description: Manifesto Codegen - Plugin-based code generation from DomainSchema
Author: eggplantiny
Latest version: 0.2.5

# @manifesto-ai/codegen

> **Codegen** generates canonical domain facade types from a Manifesto DomainSchema through a deterministic plugin pipeline.

---

## What is Codegen?

Codegen transforms a DomainSchema into type-safe code artifacts. It runs plugins sequentially, each producing file patches that are validated, collision-checked, and flushed to disk.

In the Manifesto architecture:

```
DomainSchema -> CODEGEN -> Generated Files
                  |
           Plugin pipeline
           (deterministic, no runtime deps)
```

---

## What Codegen Does

| Responsibility | Description |
|----------------|-------------|
| Generate canonical domain facades | DomainSchema -> `<domain>.domain.ts` with `state` / `computed` / `actions` |
| Generate legacy TS/Zod artifacts | Optional low-level `types.ts` / `base.ts` output |
| Generate Zod schemas | DomainSchema types -> Zod validators with type annotations |
| Plugin pipeline | Run plugins sequentially with shared artifacts |
| Path safety | Validate and normalize output file paths |
| Collision detection | Prevent multiple plugins from writing to the same file |
| Deterministic output | Same schema always produces identical files |

---

## What Codegen Does NOT Do

| NOT Responsible For | Who Is |
|--------------------|--------|
| Define schemas | SDK / Compiler (DomainSchema authoring) |
| Runtime validation | Application code using generated Zod schemas |
| Bundling or compilation | Build tools (tsc, esbuild, etc.) |
| Schema versioning | `@manifesto-ai/core` |

---

## Installation

```bash
pnpm add @manifesto-ai/codegen
# or
npm install @manifesto-ai/codegen
```

**Peer dependency:** `@manifesto-ai/core` must be installed separately.

---

## Quick Example

```typescript
import { generate, createDomainPlugin } from "@manifesto-ai/codegen";
import type { DomainSchema } from "@manifesto-ai/core";

const schema: DomainSchema = { /* your domain schema */ };

const result = await generate({
  schema,
  outDir: "./generated",
  sourceId: "src/domain/hello.mel",
  plugins: [createDomainPlugin()],
});

// result.files -> [{ path: "src/domain/hello.domain.ts", content: "..." }]
// result.diagnostics -> [] (empty = no warnings or errors)
```

For compiler-driven emission during dev or build, inject Codegen explicitly into the compiler plugin:

```typescript
import { defineConfig } from "vite";
import { melPlugin } from "@manifesto-ai/compiler/vite";
import { createCompilerCodegen } from "@manifesto-ai/codegen";

export default defineConfig({
  plugins: [
    melPlugin({
      codegen: {
        emit: createCompilerCodegen(),
        timing: "transform",
      },
    }),
  ],
});
```

This produces a canonical domain facade:

**src/domain/hello.domain.ts**
```typescript
export interface HelloDomain {
  readonly state: {
    counter: number
    hello: string
  }
  readonly computed: {
    canDecrement: boolean
    doubled: number
  }
  readonly actions: {
    decrement: () => void
    increment: () => void
  }
}
```

Legacy `createTsPlugin()` and `createZodPlugin()` remain available, but are deprecated in favor of `createDomainPlugin()`.

> See [GUIDE.md](docs/GUIDE.md) for the full tutorial.

---

## API Reference

### Main Exports

```typescript
// Entry point
function generate(options: GenerateOptions): Promise<GenerateResult>;
function createCompilerCodegen(options?: CompilerCodegenOptions): CompilerCodegenEmitter;

// Built-in plugins
function createDomainPlugin(options?: DomainPluginOptions): CodegenPlugin;
/** @deprecated */
function createTsPlugin(options?: TsPluginOptions): CodegenPlugin;
/** @deprecated */
function createZodPlugin(options?: ZodPluginOptions): CodegenPlugin;

// Key types
type GenerateOptions = {
  schema: DomainSchema;
  outDir: string;
  plugins: CodegenPlugin[];
  sourceId?: string;   // Embedded in @generated header
  stamp?: boolean;     // Add timestamp to header (breaks determinism)
};

type GenerateResult = {
  files: Array<{ path: string; content: string }>;
  artifacts: Record<string, unknown>;
  diagnostics: Diagnostic[];
};

type CompilerCodegenOptions = {
  outDir?: string;      // Default: "."
  plugins?: CodegenPlugin[]; // Default: [createDomainPlugin()]
  stamp?: boolean;
};

type CodegenPlugin = {
  name: string;
  generate(ctx: CodegenContext): CodegenOutput;
};
```

> See [SPEC-v0.1.1.md](docs/SPEC-v0.1.1.md) for complete API reference.

---

## Core Concepts

### Plugin Pipeline

Plugins run in array order. Each plugin receives a context containing the schema and artifacts from all previous plugins. The canonical domain plugin is self-contained; the legacy TS plugin publishes type names and the legacy Zod plugin reads them to generate type-annotated schemas.

### Artifacts

Plugins communicate through artifacts -- a namespaced key-value store. Plugin _i_ sees frozen artifacts from plugins 0..i-1. This enables cross-plugin coordination without coupling.

### Deterministic Output

Same DomainSchema always produces byte-identical output files. Fields and types are lexicographically sorted. No timestamps are included by default.

---

## Relationship with Other Packages

```
@manifesto-ai/core -> CODEGEN -> Generated .ts files
```

| Relationship | Package | How |
|--------------|---------|-----|
| Depends on | `@manifesto-ai/core` | Reads DomainSchema, TypeDefinition, TypeSpec |
| Used by | Build scripts / compiler plugin | Called during dev or build to generate type-safe code |

---

## When to Use Codegen

Use Codegen when:
- You want a canonical `<domain>.domain.ts` facade for `createManifesto<T>()`
- You want type-safe TypeScript interfaces from your DomainSchema
- You want Zod runtime validators that match your schema types
- You need deterministic, reproducible code generation in CI
- You are building a custom plugin for additional output formats

For schema authoring, see [`@manifesto-ai/core`](../core/).

---

## Documentation

| Document | Purpose |
|----------|---------|
| [GUIDE.md](docs/GUIDE.md) | Step-by-step usage guide |
| [SPEC-v0.1.1.md](docs/SPEC-v0.1.1.md) | Complete specification |
| [ADR-CODEGEN-001.md](docs/ADR-CODEGEN-001.md) | Architecture decisions |
| [VERSION-INDEX.md](docs/VERSION-INDEX.md) | Version tracking |

---

## License

[MIT](../../LICENSE)