@angriff36/manifest 2.18.0 → 2.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/manifest/projections/nextjs/generator.d.ts.map +1 -1
- package/dist/manifest/projections/nextjs/generator.js +15 -0
- package/dist/manifest/projections/nextjs/generator.js.map +1 -1
- package/dist/manifest/projections/react-query/generator.d.ts.map +1 -1
- package/dist/manifest/projections/react-query/generator.js +12 -0
- package/dist/manifest/projections/react-query/generator.js.map +1 -1
- package/dist/manifest/version.d.ts +1 -1
- package/dist/manifest/version.js +1 -1
- package/docs/README.md +95 -0
- package/docs/spec/README.md +130 -0
- package/docs/spec/registry/README.md +37 -0
- package/package.json +37 -35
- package/packages/cli/README.md +522 -0
- package/packages/cli/package.json +36 -0
- package/packages/lsp-server/bin/manifest-lsp.js +3 -3
- package/packages/lsp-server/package.json +28 -0
- package/packages/mcp-server/package.json +27 -0
- package/LICENSE +0 -21
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Manifest IR Registries
|
|
2
|
+
|
|
3
|
+
This directory contains the JSON schemas for the machine-readable registries
|
|
4
|
+
Manifest emits from compiled IR:
|
|
5
|
+
|
|
6
|
+
- `commands.schema.json` — the **command registry**. One entry per
|
|
7
|
+
entity+command pair, listing the policies, guards, emits, and effect kinds
|
|
8
|
+
visible at compile time. Downstream consumers (CI gates, audit tooling,
|
|
9
|
+
IDE integrations) treat this as the authoritative inventory of governed
|
|
10
|
+
commands.
|
|
11
|
+
|
|
12
|
+
- `entities.schema.json` — the **governed-entity registry**. One entry per
|
|
13
|
+
entity, classifying it (governed / read_only_projection / infrastructure /
|
|
14
|
+
bypass_allowed / unknown_nonconforming), recording whether it is tenant-
|
|
15
|
+
scoped, and listing the commands it owns.
|
|
16
|
+
|
|
17
|
+
- `bypasses.schema.json` — the **approved-bypass registry**. Hand-curated by
|
|
18
|
+
repo owners; validated by `manifest audit-bypasses`. Fields cover the
|
|
19
|
+
evidence any responsible governance review needs: entity, path, reason,
|
|
20
|
+
why-runtime-not-required, tenant boundary, owner, approval and review
|
|
21
|
+
dates.
|
|
22
|
+
|
|
23
|
+
## Stability
|
|
24
|
+
|
|
25
|
+
The schemas are versioned via the `compilerVersion` and `irHash` fields on
|
|
26
|
+
the emitted JSON. Breaking changes to the schemas MUST bump the manifest
|
|
27
|
+
compiler's major version (per `docs/spec/semantics.md` change protocol).
|
|
28
|
+
|
|
29
|
+
## Authority
|
|
30
|
+
|
|
31
|
+
Authority for what these registries mean lives in:
|
|
32
|
+
- `docs/spec/semantics.md` § "Governance Primitive Surface"
|
|
33
|
+
- `docs/spec/adapters.md` (canonical dispatcher, audit sink, outbox store)
|
|
34
|
+
|
|
35
|
+
The schemas in this directory are the machine-readable contract; the spec
|
|
36
|
+
text is the human-readable contract. Downstream governance integrations
|
|
37
|
+
(see `docs/integrations/`) consume these schemas but do not author them.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angriff36/manifest",
|
|
3
|
-
"version": "2.18.
|
|
3
|
+
"version": "2.18.2",
|
|
4
4
|
"description": "A formal domain modeling language with a deterministic reference runtime: define entities, commands, guards, policies, and events that compile to an executable IR, with projections to Next.js, Prisma, Convex, and more.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsl",
|
|
@@ -223,7 +223,8 @@
|
|
|
223
223
|
"./package.json": "./package.json"
|
|
224
224
|
},
|
|
225
225
|
"publishConfig": {
|
|
226
|
-
"access": "public"
|
|
226
|
+
"access": "public",
|
|
227
|
+
"registry": "https://registry.npmjs.org/"
|
|
227
228
|
},
|
|
228
229
|
"bin": {
|
|
229
230
|
"manifest": "./packages/cli/dist/index.js",
|
|
@@ -253,6 +254,39 @@
|
|
|
253
254
|
"type": "git",
|
|
254
255
|
"url": "https://github.com/Angriff36/Manifest.git"
|
|
255
256
|
},
|
|
257
|
+
"scripts": {
|
|
258
|
+
"version": "node scripts/sync-version.mjs && git add src/manifest/version.ts",
|
|
259
|
+
"dev": "vite",
|
|
260
|
+
"build": "pnpm run build:lib && vite build",
|
|
261
|
+
"build:lib": "tsc -p tsconfig.lib.json",
|
|
262
|
+
"build:app": "vite build",
|
|
263
|
+
"lint": "eslint .",
|
|
264
|
+
"check:cycles": "dpdm -T --no-tree --no-warning --exit-code circular:1 src/manifest/runtime-engine.ts src/manifest/compiler.ts",
|
|
265
|
+
"preview": "vite preview",
|
|
266
|
+
"typecheck": "tsc --noEmit -p tsconfig.app.json && tsc --noEmit -p tsconfig.lib.json && tsc --noEmit -p tsconfig.node.json && pnpm --filter @manifest/cli --filter @manifest/mcp-server --filter @manifest/lsp-server run typecheck",
|
|
267
|
+
"test": "vitest run",
|
|
268
|
+
"test:postgres": "vitest run src/manifest/audit/sinks/postgres.live.test.ts src/manifest/outbox/stores/postgres.live.test.ts --fileParallelism=false",
|
|
269
|
+
"test:watch": "vitest",
|
|
270
|
+
"bench": "vitest bench --reporter=verbose",
|
|
271
|
+
"docs:check:metadata": "node scripts/check-doc-metadata.mjs",
|
|
272
|
+
"docs:check:links": "node scripts/check-doc-links.mjs",
|
|
273
|
+
"docs:check:spec-integrity": "node scripts/check-spec-integrity.mjs",
|
|
274
|
+
"docs:check": "pnpm run docs:check:metadata && pnpm run docs:check:links && pnpm run docs:check:spec-integrity",
|
|
275
|
+
"docs:dev": "cd docs-site && mintlify dev",
|
|
276
|
+
"verify:docs": "pnpm run docs:check && pnpm test",
|
|
277
|
+
"verify:docs:quick": "pnpm run docs:check",
|
|
278
|
+
"conformance:regen": "tsx scripts/regen-conformance.ts",
|
|
279
|
+
"init": "node scripts/init.mjs",
|
|
280
|
+
"manifest": "tsx ./packages/cli/src/index.ts",
|
|
281
|
+
"manifest:init": "tsx ./packages/cli/src/index.ts init",
|
|
282
|
+
"manifest:compile": "tsx ./packages/cli/src/index.ts compile",
|
|
283
|
+
"manifest:generate": "tsx ./packages/cli/src/index.ts generate",
|
|
284
|
+
"manifest:build": "tsx ./packages/cli/src/index.ts build",
|
|
285
|
+
"manifest:validate": "tsx ./packages/cli/src/index.ts validate",
|
|
286
|
+
"wasm:build": "asc assembly/index.ts --target release --outFile src/manifest/wasm/manifest-runtime.wasm --optimize --runtime stub --exportRuntime",
|
|
287
|
+
"wasm:build:debug": "asc assembly/index.ts --target debug --outFile src/manifest/wasm/manifest-runtime-debug.wasm",
|
|
288
|
+
"prepublishOnly": "pnpm run build:lib && pnpm --filter @manifest/cli --filter @manifest/mcp-server --filter @manifest/lsp-server run build"
|
|
289
|
+
},
|
|
256
290
|
"dependencies": {
|
|
257
291
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
258
292
|
"@msgpack/msgpack": "^3.0.0",
|
|
@@ -320,37 +354,5 @@
|
|
|
320
354
|
"typescript-eslint": "^8.3.0",
|
|
321
355
|
"vite": "^5.4.2",
|
|
322
356
|
"vitest": "^4.0.18"
|
|
323
|
-
},
|
|
324
|
-
"scripts": {
|
|
325
|
-
"version": "node scripts/sync-version.mjs && git add src/manifest/version.ts",
|
|
326
|
-
"dev": "vite",
|
|
327
|
-
"build": "pnpm run build:lib && vite build",
|
|
328
|
-
"build:lib": "tsc -p tsconfig.lib.json",
|
|
329
|
-
"build:app": "vite build",
|
|
330
|
-
"lint": "eslint .",
|
|
331
|
-
"check:cycles": "dpdm -T --no-tree --no-warning --exit-code circular:1 src/manifest/runtime-engine.ts src/manifest/compiler.ts",
|
|
332
|
-
"preview": "vite preview",
|
|
333
|
-
"typecheck": "tsc --noEmit -p tsconfig.app.json && tsc --noEmit -p tsconfig.lib.json && tsc --noEmit -p tsconfig.node.json && pnpm --filter @manifest/cli --filter @manifest/mcp-server --filter @manifest/lsp-server run typecheck",
|
|
334
|
-
"test": "vitest run",
|
|
335
|
-
"test:postgres": "vitest run src/manifest/audit/sinks/postgres.live.test.ts src/manifest/outbox/stores/postgres.live.test.ts --fileParallelism=false",
|
|
336
|
-
"test:watch": "vitest",
|
|
337
|
-
"bench": "vitest bench --reporter=verbose",
|
|
338
|
-
"docs:check:metadata": "node scripts/check-doc-metadata.mjs",
|
|
339
|
-
"docs:check:links": "node scripts/check-doc-links.mjs",
|
|
340
|
-
"docs:check:spec-integrity": "node scripts/check-spec-integrity.mjs",
|
|
341
|
-
"docs:check": "pnpm run docs:check:metadata && pnpm run docs:check:links && pnpm run docs:check:spec-integrity",
|
|
342
|
-
"docs:dev": "cd docs-site && mintlify dev",
|
|
343
|
-
"verify:docs": "pnpm run docs:check && pnpm test",
|
|
344
|
-
"verify:docs:quick": "pnpm run docs:check",
|
|
345
|
-
"conformance:regen": "tsx scripts/regen-conformance.ts",
|
|
346
|
-
"init": "node scripts/init.mjs",
|
|
347
|
-
"manifest": "tsx ./packages/cli/src/index.ts",
|
|
348
|
-
"manifest:init": "tsx ./packages/cli/src/index.ts init",
|
|
349
|
-
"manifest:compile": "tsx ./packages/cli/src/index.ts compile",
|
|
350
|
-
"manifest:generate": "tsx ./packages/cli/src/index.ts generate",
|
|
351
|
-
"manifest:build": "tsx ./packages/cli/src/index.ts build",
|
|
352
|
-
"manifest:validate": "tsx ./packages/cli/src/index.ts validate",
|
|
353
|
-
"wasm:build": "asc assembly/index.ts --target release --outFile src/manifest/wasm/manifest-runtime.wasm --optimize --runtime stub --exportRuntime",
|
|
354
|
-
"wasm:build:debug": "asc assembly/index.ts --target debug --outFile src/manifest/wasm/manifest-runtime-debug.wasm"
|
|
355
357
|
}
|
|
356
|
-
}
|
|
358
|
+
}
|
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
# Manifest CLI
|
|
2
|
+
|
|
3
|
+
Command-line interface for the Manifest language. Compile, generate, and validate Manifest code.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Add to your project
|
|
9
|
+
npm install -D @manifest/cli
|
|
10
|
+
|
|
11
|
+
# Or use directly from the Manifest repo
|
|
12
|
+
npm run manifest --help
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### Option 1: Interactive Setup (Recommended)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Initialize with config file (asks questions)
|
|
21
|
+
manifest init
|
|
22
|
+
|
|
23
|
+
# Then use config defaults
|
|
24
|
+
manifest build
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Option 2: Direct Commands
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Compile manifest to IR
|
|
31
|
+
manifest compile modules/recipe.manifest --output ir/
|
|
32
|
+
|
|
33
|
+
# Generate Next.js routes from IR
|
|
34
|
+
manifest generate ir/recipe.ir.json --projection nextjs --output app/api/
|
|
35
|
+
|
|
36
|
+
# One-step: compile + generate
|
|
37
|
+
manifest build modules/recipe.manifest --projection nextjs --output app/api/
|
|
38
|
+
|
|
39
|
+
# Validate IR against schema
|
|
40
|
+
manifest validate ir/
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Commands
|
|
44
|
+
|
|
45
|
+
### `manifest init`
|
|
46
|
+
|
|
47
|
+
Initialize Manifest configuration for your project (interactive).
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Interactive setup
|
|
51
|
+
manifest init
|
|
52
|
+
|
|
53
|
+
# Overwrite existing config
|
|
54
|
+
manifest init --force
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Questions asked:**
|
|
58
|
+
- Framework: Next.js, Remix, Vite, Other
|
|
59
|
+
- Auth provider: Clerk, NextAuth, Custom, None
|
|
60
|
+
- Workspace: Are you using pnpm/yarn workspaces?
|
|
61
|
+
- Workspace prefix: `@repo/` (if using workspaces)
|
|
62
|
+
- Import paths: database, runtime, response helpers
|
|
63
|
+
- Output directory: Where should generated routes go?
|
|
64
|
+
- Tenant filtering: Include multi-tenant filtering?
|
|
65
|
+
- Soft-delete filtering: Include soft-delete filtering?
|
|
66
|
+
|
|
67
|
+
**Creates:** `manifest.config.yaml`
|
|
68
|
+
|
|
69
|
+
**Example config:**
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
# manifest.config.yaml
|
|
73
|
+
# No $schema URL: `manifest config validate` uses the schema bundled with the
|
|
74
|
+
# package, not a remote URL. For editor IntelliSense, map the bundled schema in
|
|
75
|
+
# .vscode/settings.json (yaml.schemas) instead.
|
|
76
|
+
|
|
77
|
+
src: modules/**/*.manifest
|
|
78
|
+
output: ir/
|
|
79
|
+
|
|
80
|
+
projections:
|
|
81
|
+
nextjs:
|
|
82
|
+
output: app/api/
|
|
83
|
+
options:
|
|
84
|
+
authProvider: clerk
|
|
85
|
+
authImportPath: @/lib/auth
|
|
86
|
+
databaseImportPath: @/lib/database
|
|
87
|
+
runtimeImportPath: @/lib/manifest-runtime
|
|
88
|
+
responseImportPath: @/lib/manifest-response
|
|
89
|
+
includeTenantFilter: true
|
|
90
|
+
includeSoftDeleteFilter: true
|
|
91
|
+
tenantIdProperty: tenantId
|
|
92
|
+
deletedAtProperty: deletedAt
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Workspace example (capsule-pro):**
|
|
96
|
+
|
|
97
|
+
```yaml
|
|
98
|
+
# manifest.config.yaml
|
|
99
|
+
projections:
|
|
100
|
+
nextjs:
|
|
101
|
+
output: apps/api/app/api/
|
|
102
|
+
options:
|
|
103
|
+
authProvider: clerk
|
|
104
|
+
authImportPath: @repo/auth/server
|
|
105
|
+
databaseImportPath: @repo/database
|
|
106
|
+
runtimeImportPath: @repo/manifest/runtime
|
|
107
|
+
responseImportPath: @repo/manifest/response
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### `manifest compile [source]`
|
|
111
|
+
|
|
112
|
+
Compile `.manifest` source files to IR (Intermediate Representation).
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Compile single file (uses config output dir if set)
|
|
116
|
+
manifest compile modules/recipe.manifest
|
|
117
|
+
|
|
118
|
+
# Compile all .manifest files
|
|
119
|
+
manifest compile --glob "modules/**/*.manifest"
|
|
120
|
+
|
|
121
|
+
# Compile all .manifest files
|
|
122
|
+
manifest compile --glob "modules/**/*.manifest" --output ir/
|
|
123
|
+
|
|
124
|
+
# Include diagnostics in output
|
|
125
|
+
manifest compile modules/recipe.manifest --output ir/ --diagnostics
|
|
126
|
+
|
|
127
|
+
# Use default settings (finds all .manifest files)
|
|
128
|
+
manifest compile
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Options:**
|
|
132
|
+
- `-o, --output <path>` - Output directory or file path (default: `ir/`)
|
|
133
|
+
- `-g, --glob <pattern>` - Glob pattern for multiple files
|
|
134
|
+
- `-d, --diagnostics` - Include diagnostics in output
|
|
135
|
+
- `--pretty` - Pretty-print JSON output (default: true)
|
|
136
|
+
|
|
137
|
+
### `manifest generate <ir>`
|
|
138
|
+
|
|
139
|
+
Generate code from IR using a projection.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Uses config defaults if manifest.config.yaml exists
|
|
143
|
+
manifest generate ir/recipe.ir.json
|
|
144
|
+
|
|
145
|
+
# Override specific options
|
|
146
|
+
manifest generate ir/recipe.ir.json --output apps/api/app/api/
|
|
147
|
+
|
|
148
|
+
# Generate specific surface
|
|
149
|
+
manifest generate ir/recipe.ir.json --surface types --output generated/types.ts
|
|
150
|
+
manifest generate ir/recipe.ir.json --surface client --output generated/client.ts
|
|
151
|
+
|
|
152
|
+
# Generate for directory of IR files
|
|
153
|
+
manifest generate ir/
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Options:**
|
|
157
|
+
- `-p, --projection <name>` - Projection name: `nextjs`, `ts.types`, `ts.client` (default: `nextjs`)
|
|
158
|
+
- `-s, --surface <name>` - Surface: `route`, `command`, `types`, `client`, `all` (default: `all`)
|
|
159
|
+
- `-o, --output <path>` - Output directory (uses config if set)
|
|
160
|
+
- `--auth <provider>` - Auth provider or import path (uses config if set)
|
|
161
|
+
- `--database <path>` - Database import path (uses config if set)
|
|
162
|
+
- `--runtime <path>` - Runtime import path (uses config if set)
|
|
163
|
+
- `--response <path>` - Response helpers import path (uses config if set)
|
|
164
|
+
|
|
165
|
+
### `manifest build [source]`
|
|
166
|
+
|
|
167
|
+
Compile `.manifest` to IR and generate code in one step.
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Uses all config defaults (recommended after manifest init)
|
|
171
|
+
manifest build modules/recipe.manifest
|
|
172
|
+
|
|
173
|
+
# Override output directory
|
|
174
|
+
manifest build modules/recipe.manifest --code-output apps/api/app/api/
|
|
175
|
+
|
|
176
|
+
# Multiple files
|
|
177
|
+
manifest build "modules/**/*.manifest"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Options:**
|
|
181
|
+
- `-p, --projection <name>` - Projection name (default: `nextjs`)
|
|
182
|
+
- `-s, --surface <name>` - Projection surface (default: `all`)
|
|
183
|
+
- `--ir-output <path>` - IR output directory (uses config if set)
|
|
184
|
+
- `--code-output <path>` - Generated code output directory (uses config if set)
|
|
185
|
+
- `-g, --glob <pattern>` - Glob pattern for multiple files
|
|
186
|
+
- `--auth <provider>` - Auth provider or import path (uses config if set)
|
|
187
|
+
- `--database <path>` - Database import path (uses config if set)
|
|
188
|
+
- `--runtime <path>` - Runtime import path (uses config if set)
|
|
189
|
+
- `--response <path>` - Response helpers import path (uses config if set)
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## How Config Works
|
|
194
|
+
|
|
195
|
+
When you run `manifest init`, it creates `manifest.config.yaml` with your project settings.
|
|
196
|
+
|
|
197
|
+
**After that, all commands use the config:**
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# After manifest init, just run:
|
|
201
|
+
manifest build
|
|
202
|
+
|
|
203
|
+
# Same as:
|
|
204
|
+
manifest build modules/ \
|
|
205
|
+
--ir-output ir/ \
|
|
206
|
+
--code-output apps/api/app/api/ \
|
|
207
|
+
--auth @repo/auth/server \
|
|
208
|
+
--database @repo/database \
|
|
209
|
+
--runtime @repo/manifest/runtime \
|
|
210
|
+
--response @repo/manifest/response
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**CLI option priority:**
|
|
214
|
+
1. Command-line flags (highest priority)
|
|
215
|
+
2. Config file values
|
|
216
|
+
3. Built-in defaults (lowest priority)
|
|
217
|
+
|
|
218
|
+
### `manifest validate [ir]`
|
|
219
|
+
|
|
220
|
+
Validate IR against the schema.
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
# Validate all IR files
|
|
224
|
+
manifest validate ir/
|
|
225
|
+
|
|
226
|
+
# Validate specific file
|
|
227
|
+
manifest validate ir/recipe.ir.json
|
|
228
|
+
|
|
229
|
+
# Strict mode (warnings fail validation)
|
|
230
|
+
manifest validate ir/ --strict
|
|
231
|
+
|
|
232
|
+
# Custom schema
|
|
233
|
+
manifest validate ir/ --schema custom-schema.json
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**Options:**
|
|
237
|
+
- `--schema <path>` - Schema path (default: `docs/spec/ir/ir-v1.schema.json`)
|
|
238
|
+
- `--strict` - Fail on warnings
|
|
239
|
+
|
|
240
|
+
## Package Scripts
|
|
241
|
+
|
|
242
|
+
Add to your `package.json`:
|
|
243
|
+
|
|
244
|
+
```json
|
|
245
|
+
{
|
|
246
|
+
"scripts": {
|
|
247
|
+
"manifest": "manifest",
|
|
248
|
+
"manifest:build": "manifest build modules/**/*.manifest --projection nextjs --output app/api/",
|
|
249
|
+
"manifest:validate": "manifest validate ir/",
|
|
250
|
+
"dev": "vite",
|
|
251
|
+
"build": "npm run manifest:build && vite build"
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Integration with Capsule-Pro
|
|
257
|
+
|
|
258
|
+
### Directory Structure
|
|
259
|
+
|
|
260
|
+
Capsule-pro uses a monorepo with multiple Next.js apps:
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
capsule-pro/
|
|
264
|
+
├── apps/
|
|
265
|
+
│ ├── app/ ← Main Next.js app
|
|
266
|
+
│ │ └── app/
|
|
267
|
+
│ │ └── api/ ← Routes go here
|
|
268
|
+
│ └── api/ ← API Next.js app
|
|
269
|
+
│ └── app/
|
|
270
|
+
│ └── api/ ← Routes go here
|
|
271
|
+
└── modules/
|
|
272
|
+
└── *.manifest ← Your Manifest source files
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### 1. Install dependencies
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
npm install -D @manifest/cli
|
|
279
|
+
npm install @supabase/supabase-js
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### 2. Workspace packages (already exist)
|
|
283
|
+
|
|
284
|
+
Capsule-pro already has the required packages:
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
// packages/database - Prisma client
|
|
288
|
+
// packages/auth - Auth utilities
|
|
289
|
+
// packages/manifest - Manifest runtime wrapper
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**You don't need to create these** - they already exist as workspace packages.
|
|
293
|
+
|
|
294
|
+
### 3. Define your Manifest source
|
|
295
|
+
|
|
296
|
+
```manifest
|
|
297
|
+
// modules/recipe.manifest
|
|
298
|
+
entity Recipe {
|
|
299
|
+
property required id: string
|
|
300
|
+
property required name: string
|
|
301
|
+
property category: string?
|
|
302
|
+
|
|
303
|
+
command create(name: string, category?: string) {
|
|
304
|
+
guard user.role == "chef"
|
|
305
|
+
mutate id = generateId()
|
|
306
|
+
mutate name = name
|
|
307
|
+
mutate category = category
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
store Recipe in postgres
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### 4. Generate routes (with correct workspace imports)
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# From capsule-pro root - using workspace imports
|
|
318
|
+
manifest build modules/recipe.manifest \
|
|
319
|
+
--output apps/api/app/api/ \
|
|
320
|
+
--database @repo/database \
|
|
321
|
+
--runtime @repo/manifest/runtime \
|
|
322
|
+
--auth @repo/auth/server
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
This creates:
|
|
326
|
+
- `ir/recipe.ir.json` - Compiled IR
|
|
327
|
+
- `apps/api/app/api/recipe/route.ts` - Generated API routes
|
|
328
|
+
|
|
329
|
+
### 5. Generated route example
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
// apps/api/app/api/recipe/route.ts (GENERATED - DO NOT EDIT)
|
|
333
|
+
import { NextRequest } from "next/server";
|
|
334
|
+
import { database } from "@repo/database"; // ← Workspace import
|
|
335
|
+
import { manifestSuccessResponse, manifestErrorResponse } from "@repo/manifest/response";
|
|
336
|
+
import { createRuntime } from "@repo/manifest/runtime";
|
|
337
|
+
import { auth } from "@repo/auth/server"; // ← Workspace import
|
|
338
|
+
|
|
339
|
+
export async function GET(request: NextRequest) {
|
|
340
|
+
// ... generated code
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export async function POST(request: NextRequest) {
|
|
344
|
+
// ... generated code
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Scripts for package.json
|
|
349
|
+
|
|
350
|
+
```json
|
|
351
|
+
{
|
|
352
|
+
"scripts": {
|
|
353
|
+
"manifest:build": "manifest build modules/**/*.manifest --output apps/api/app/api/ --database @repo/database --runtime @repo/manifest/runtime --auth @repo/auth/server",
|
|
354
|
+
"manifest:build:app": "manifest build modules/**/*.manifest --output apps/app/app/api/ --database @repo/database --runtime @repo/manifest/runtime --auth @repo/auth/server",
|
|
355
|
+
"manifest:validate": "manifest validate ir/"
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Projections
|
|
361
|
+
|
|
362
|
+
### Next.js Projection
|
|
363
|
+
|
|
364
|
+
Surfaces:
|
|
365
|
+
- **route** - Entity GET routes (list, retrieve)
|
|
366
|
+
- **command** - Command POST routes (create, update, delete)
|
|
367
|
+
- **types** - TypeScript type definitions
|
|
368
|
+
- **client** - Client SDK functions
|
|
369
|
+
|
|
370
|
+
Example:
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
# Generate GET routes for entities
|
|
374
|
+
manifest generate ir/ --surface route --output app/api/
|
|
375
|
+
|
|
376
|
+
# Generate POST routes for commands
|
|
377
|
+
manifest generate ir/ --surface command --output app/api/
|
|
378
|
+
|
|
379
|
+
# Generate TypeScript types
|
|
380
|
+
manifest generate ir/ --surface types --output generated/types.ts
|
|
381
|
+
|
|
382
|
+
# Generate client SDK
|
|
383
|
+
manifest generate ir/ --surface client --output generated/client.ts
|
|
384
|
+
|
|
385
|
+
# Generate all surfaces
|
|
386
|
+
manifest generate ir/ --surface all --output generated/
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## Configuration
|
|
390
|
+
|
|
391
|
+
Create `manifest.config.yaml` in your project root:
|
|
392
|
+
|
|
393
|
+
```yaml
|
|
394
|
+
# Project configuration
|
|
395
|
+
src: "modules/**/*.manifest"
|
|
396
|
+
output: "ir/"
|
|
397
|
+
|
|
398
|
+
projections:
|
|
399
|
+
nextjs:
|
|
400
|
+
output: "app/api/"
|
|
401
|
+
options:
|
|
402
|
+
authProvider: "clerk"
|
|
403
|
+
databaseImportPath: "@/lib/database"
|
|
404
|
+
runtimeImportPath: "@/lib/manifest-runtime"
|
|
405
|
+
responseImportPath: "@/lib/manifest-response"
|
|
406
|
+
includeTenantFilter: true
|
|
407
|
+
tenantIdProperty: "tenantId"
|
|
408
|
+
deletedAtProperty: "deletedAt"
|
|
409
|
+
|
|
410
|
+
dev:
|
|
411
|
+
port: 5173
|
|
412
|
+
watch: true
|
|
413
|
+
|
|
414
|
+
test:
|
|
415
|
+
coverage: true
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
## Examples
|
|
419
|
+
|
|
420
|
+
See `docs/examples/` for complete examples:
|
|
421
|
+
- Recipe API
|
|
422
|
+
- Task management
|
|
423
|
+
- Multi-tenant SaaS
|
|
424
|
+
- Event sourcing
|
|
425
|
+
|
|
426
|
+
## Troubleshooting
|
|
427
|
+
|
|
428
|
+
### Windows: `manifest` exits `0` with no output
|
|
429
|
+
|
|
430
|
+
If CLI commands return exit `0` with no output on Windows (especially with pnpm shims), verify from your project root:
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
pnpm exec manifest --help
|
|
434
|
+
node .\node_modules\@manifest\runtime\packages\cli\dist\index.js --help
|
|
435
|
+
.\node_modules\.bin\manifest.cmd --help
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Expected result: each command prints the Manifest help text.
|
|
439
|
+
|
|
440
|
+
Root cause (fixed in `0.3.10`): direct-run detection compared unresolved normalized paths, which could differ across `node_modules` shim paths and `.pnpm` real targets.
|
|
441
|
+
|
|
442
|
+
Implementation summary:
|
|
443
|
+
- CLI now compares normalized **realpaths** for module and argv entrypoint.
|
|
444
|
+
- On Windows, comparison is case-insensitive.
|
|
445
|
+
- If argv realpath cannot be resolved, fallback bin-context checks allow execution (`manifest`/`index.js` path hints, ESM main-equivalent check).
|
|
446
|
+
|
|
447
|
+
Note on `init --force`:
|
|
448
|
+
- `manifest init --force` is interactive and requires terminal input.
|
|
449
|
+
- In non-interactive/headless shells, it may wait for prompts or exit without rewriting config.
|
|
450
|
+
|
|
451
|
+
### `TypeError: Cannot read properties of undefined (reading 'output')` in `manifest compile`
|
|
452
|
+
|
|
453
|
+
If `pnpm exec manifest compile` fails at `packages/cli/dist/index.js` around line `48`, you are likely on a build with duplicate Commander argument declarations.
|
|
454
|
+
|
|
455
|
+
Fixed behavior:
|
|
456
|
+
- Command signatures no longer duplicate args in both `.command(...)` and `.argument(...)`.
|
|
457
|
+
- Action handlers use safe option defaults (`options = {}`).
|
|
458
|
+
- Config access remains null-safe (`config?.output`, `config?.projections?...`).
|
|
459
|
+
|
|
460
|
+
Quick check:
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
pnpm exec manifest --help
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Expected command shapes:
|
|
467
|
+
- `compile [options] [source]`
|
|
468
|
+
- `generate [options] <ir>`
|
|
469
|
+
- `build [options] [source]`
|
|
470
|
+
- `validate [options] [ir]`
|
|
471
|
+
|
|
472
|
+
### `Cannot find module .../dist/manifest/parser` during `manifest compile`
|
|
473
|
+
|
|
474
|
+
If compile starts and then fails with:
|
|
475
|
+
|
|
476
|
+
```text
|
|
477
|
+
Cannot find module .../dist/manifest/parser imported from .../dist/manifest/ir-compiler.js
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
you are on a runtime build where ESM relative imports were emitted without `.js` extensions.
|
|
481
|
+
|
|
482
|
+
Fixed behavior:
|
|
483
|
+
- Runtime ESM imports now use explicit `.js` extensions (for example `./parser.js`, `./lexer.js`, `./ir-cache.js`, `./version.js`).
|
|
484
|
+
- Projection registry/builtins exports/imports were also aligned to `.js` specifiers for Node ESM resolution.
|
|
485
|
+
|
|
486
|
+
Validation command:
|
|
487
|
+
|
|
488
|
+
```bash
|
|
489
|
+
pnpm exec manifest compile
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
Expected result: compile runs across discovered manifests without module-resolution errors.
|
|
493
|
+
|
|
494
|
+
### "Cannot find module '@manifest/compiler'"
|
|
495
|
+
|
|
496
|
+
Make sure you're running from the Manifest repo or have installed the dependencies:
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
cd packages/cli
|
|
500
|
+
npm install
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### "No .manifest files found"
|
|
504
|
+
|
|
505
|
+
Create a `.manifest` file or specify the source:
|
|
506
|
+
|
|
507
|
+
```bash
|
|
508
|
+
manifest compile path/to/your/file.manifest
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### Generated routes don't work
|
|
512
|
+
|
|
513
|
+
Check your lib files are set up correctly:
|
|
514
|
+
- `lib/manifest-runtime.ts`
|
|
515
|
+
- `lib/database.ts`
|
|
516
|
+
- `lib/manifest-response.ts`
|
|
517
|
+
|
|
518
|
+
## Related Documentation
|
|
519
|
+
|
|
520
|
+
- **[Usage Patterns Guide](../../docs/guides/usage-patterns.md)** - Projections vs embedded runtime
|
|
521
|
+
- **[Next.js Projection README](../../src/manifest/projections/nextjs/README.md)** - Projection details
|
|
522
|
+
- **[Language Semantics](../../docs/spec/semantics.md)** - How Manifest works
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@manifest/cli",
|
|
3
|
+
"version": "2.0.2",
|
|
4
|
+
"description": "CLI for the Manifest language",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"manifest": "./bin/manifest.js"
|
|
8
|
+
},
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./src/index.ts"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"watch": "tsc --watch",
|
|
15
|
+
"typecheck": "tsc --noEmit"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@angriff36/manifest": "workspace:*",
|
|
19
|
+
"ajv": "^8.18.0",
|
|
20
|
+
"chalk": "^5.3.0",
|
|
21
|
+
"commander": "^12.1.0",
|
|
22
|
+
"fast-glob": "^3.3.2",
|
|
23
|
+
"glob": "^10.3.12",
|
|
24
|
+
"inquirer": "^9.2.0",
|
|
25
|
+
"jiti": "^2.4.2",
|
|
26
|
+
"js-yaml": "^4.1.0",
|
|
27
|
+
"ora": "^8.0.1"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/inquirer": "^9.0.6",
|
|
31
|
+
"@types/js-yaml": "^4.0.9",
|
|
32
|
+
"@types/node": "latest",
|
|
33
|
+
"typescript": "^5.5.3",
|
|
34
|
+
"vitest": "latest"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { start } from '../dist/index.js';
|
|
3
|
-
start();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { start } from '../dist/index.js';
|
|
3
|
+
start();
|