@aotter/mantle 0.1.3 → 0.1.5-alpha.1

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.
Files changed (105) hide show
  1. package/README.md +20 -20
  2. package/dist/cli/generate-cloudflare.d.ts +7 -0
  3. package/dist/cli/generate-cloudflare.d.ts.map +1 -0
  4. package/dist/cli/generate-cloudflare.js +123 -0
  5. package/dist/cli/generate-cloudflare.js.map +1 -0
  6. package/dist/cli/generate-project.d.ts +25 -0
  7. package/dist/cli/generate-project.d.ts.map +1 -0
  8. package/dist/cli/generate-project.js +282 -0
  9. package/dist/cli/generate-project.js.map +1 -0
  10. package/dist/cli/generate-sites.d.ts +8 -0
  11. package/dist/cli/generate-sites.d.ts.map +1 -0
  12. package/dist/cli/generate-sites.js +273 -0
  13. package/dist/cli/generate-sites.js.map +1 -0
  14. package/dist/cli/generate.d.ts.map +1 -1
  15. package/dist/cli/generate.js +121 -10
  16. package/dist/cli/generate.js.map +1 -1
  17. package/dist/cli/main.d.ts +1 -1
  18. package/dist/cli/main.d.ts.map +1 -1
  19. package/dist/cli/main.js +11 -11
  20. package/dist/cli/skills.js +1 -1
  21. package/dist/cli/skills.js.map +1 -1
  22. package/docs/adr/0001-four-atom-manifest-model.md +3 -2
  23. package/docs/adr/0013-agent-provisioned-consumer-projects.md +4 -4
  24. package/docs/adr/0016-site-semantic-layer.md +5 -4
  25. package/docs/adr/0018-core-starters-repository-boundary.md +1 -1
  26. package/docs/adr/0021-retire-starter-scaffolding.md +1 -1
  27. package/docs/adr/0026-progressive-generate.md +36 -0
  28. package/docs/adr/0027-scheduled-procedure-triggers.md +31 -0
  29. package/docs/adr/0028-schema-ttl-expiry.md +33 -0
  30. package/docs/adr/README.md +7 -4
  31. package/docs/agent-prompts.md +41 -78
  32. package/docs/assets/mantle-admin-developer.png +0 -0
  33. package/docs/examples/README.md +1 -1
  34. package/docs/examples/host-chatgpt-sites/README.md +29 -12
  35. package/docs/examples/host-chatgpt-sites/drizzle/0003_store_instance_id.sql +1 -0
  36. package/docs/examples/host-chatgpt-sites/drizzle/0004_mantle.sql +10 -0
  37. package/docs/examples/host-chatgpt-sites/drizzle/0005_mantle.sql +24 -0
  38. package/docs/examples/host-chatgpt-sites/drizzle/meta/_journal.json +1 -1
  39. package/docs/examples/host-chatgpt-sites/drizzle/meta/mantle-state.json +60 -0
  40. package/docs/examples/host-chatgpt-sites/package.json +1 -1
  41. package/docs/examples/host-chatgpt-sites/public/site.css +1 -1
  42. package/docs/examples/host-chatgpt-sites/scripts/build.mjs +2 -1
  43. package/docs/examples/host-chatgpt-sites/scripts/check.mjs +2 -0
  44. package/docs/examples/host-chatgpt-sites/scripts/migration.mjs +42 -8
  45. package/docs/examples/host-chatgpt-sites/src/chatgpt-auth.ts +9 -6
  46. package/docs/examples/host-chatgpt-sites/src/index.ts +1 -1
  47. package/docs/examples/host-chatgpt-sites/src/web.ts +1 -1
  48. package/docs/examples/host-local-admin-otp/package.json +2 -2
  49. package/docs/examples/host-minimal-worker/README.md +5 -5
  50. package/docs/examples/host-minimal-worker/package.json +2 -2
  51. package/docs/handbook/{sites → chatgpt-sites}/equipment-checkout.md +1 -1
  52. package/docs/handbook/chatgpt-sites/generated-app.md +84 -0
  53. package/docs/handbook/{sites → chatgpt-sites}/index.md +35 -13
  54. package/docs/handbook/cloudflare/authentication.md +19 -2
  55. package/docs/handbook/cloudflare/bindings.md +4 -11
  56. package/docs/handbook/cloudflare/chatgpt-sites.md +6 -6
  57. package/docs/handbook/cloudflare/conventional-worker.md +7 -3
  58. package/docs/handbook/cloudflare/deploy-and-operate.md +4 -3
  59. package/docs/handbook/cloudflare/media-r2.md +2 -2
  60. package/docs/handbook/concepts/four-atoms.md +1 -1
  61. package/docs/handbook/concepts/lifecycle-and-locales.md +1 -1
  62. package/docs/handbook/concepts/mcp-and-agents.md +24 -4
  63. package/docs/handbook/concepts/procedures-and-triggers.md +1 -1
  64. package/docs/handbook/concepts/runtime-and-adapters.md +8 -1
  65. package/docs/handbook/concepts/views.md +1 -1
  66. package/docs/handbook/guides/agent-setup.md +8 -7
  67. package/docs/handbook/navigation.json +7 -6
  68. package/docs/handbook/reference/diagnostics.md +5 -0
  69. package/docs/handbook/reference/procedure.md +52 -1
  70. package/docs/handbook/reference/schema.md +27 -1
  71. package/docs/handbook/reference/surface.md +3 -3
  72. package/docs/handbook/reference/trigger.md +21 -1
  73. package/docs/handbook/releases/index.md +81 -1
  74. package/docs/handbook/start/overview.md +6 -3
  75. package/docs/handbook/start/project-and-cli.md +103 -119
  76. package/docs/handbook/start/quickstart-admin.md +6 -4
  77. package/docs/handbook/start/quickstart-worker.md +17 -11
  78. package/docs/release-process.md +3 -2
  79. package/docs/sealed-pipeline-ownership.md +1 -1
  80. package/docs/skills/develop/SKILL.md +258 -0
  81. package/docs/skills/integrate/SKILL.md +60 -0
  82. package/docs/skills/media-gc/SKILL.md +85 -0
  83. package/docs/skills/plugin/SKILL.md +132 -0
  84. package/docs/skills/provision/SKILL.md +194 -0
  85. package/docs/skills/theme/SKILL.md +77 -0
  86. package/docs/skills/update/SKILL.md +51 -0
  87. package/docs/spec-only-host-adoption.md +1 -1
  88. package/package.json +19 -18
  89. package/skills/README.md +28 -21
  90. package/skills/develop/SKILL.md +16 -8
  91. package/skills/install/SKILL.md +103 -128
  92. package/skills/integrate/SKILL.md +60 -0
  93. package/skills/media-gc/SKILL.md +2 -2
  94. package/skills/plugin/SKILL.md +2 -2
  95. package/skills/provision/SKILL.md +3 -3
  96. package/skills/theme/SKILL.md +2 -2
  97. package/skills/update/SKILL.md +2 -2
  98. package/templates/chatgpt-sites/auth.ts +66 -0
  99. package/templates/chatgpt-sites/build.mjs +14 -0
  100. package/templates/chatgpt-sites/env.ts +1 -0
  101. package/templates/chatgpt-sites/mcp.ts +48 -0
  102. package/templates/chatgpt-sites/public-mcp.ts +29 -0
  103. package/templates/chatgpt-sites/smoke-local.mjs +20 -0
  104. package/skills/.keep +0 -0
  105. /package/docs/handbook/{sites → chatgpt-sites}/host-reference.md +0 -0
package/README.md CHANGED
@@ -9,19 +9,18 @@ where agents write config and the runtime carries the complexity.
9
9
 
10
10
  ## Install
11
11
 
12
- Cold start for a new application is the install skill, not a bare npm add:
12
+ An agent can install the small bootstrap skill:
13
13
 
14
14
  ```sh
15
- npx skills add aotter/mantle --skill install
15
+ npx skills add aotter/mantle
16
16
  ```
17
17
 
18
- To depend on this package in an existing project, pin the exact version
19
- from `package.json` (currently `0.1.3`):
18
+ For a new application, resolve one published stable version and install it
19
+ exactly. `mantle generate` will declare matching selected packages:
20
20
 
21
21
  ```bash
22
- npm install @aotter/mantle
23
- # or
24
- pnpm add @aotter/mantle
22
+ MANTLE_VERSION=$(npm view @aotter/mantle@latest version)
23
+ npm install --save-exact "@aotter/mantle@$MANTLE_VERSION"
25
24
  ```
26
25
 
27
26
  ## What's inside
@@ -67,11 +66,13 @@ pnpm exec mantle-harness indexes --require-public
67
66
  pnpm exec mantle-harness http --base-url http://127.0.0.1:8787 --route page=/en/example
68
67
  ```
69
68
 
70
- `mantle generate` validates and compiles `./manifests/`, then writes one typed
71
- `.mantle/generated/mantle.ts` module. When `@aotter/mantle-admin-ui` is
72
- installed, it also syncs the Admin SPA to `public/_mantle/admin/` (excluding
73
- `server.*` package exports). Core-only installs skip that copy. It performs no
74
- skill sync, package update, styling, provisioning, or deployment.
69
+ `mantle generate --host cf` or `--host chatgpt-sites` assembles a new blank
70
+ app with Spec, Runtime, API, MCP, Admin and Web by default. Use `--features`
71
+ to select a smaller set, including host-free Spec-only. The first run declares
72
+ matching optional dependencies; install them, then rerun. In an existing
73
+ direct-authored app, `generate` keeps its compile behavior: validate
74
+ `./manifests/` and write `.mantle/generated/mantle.ts`. Selected Admin syncs
75
+ its prebuilt SPA to `public/_mantle/admin/`. Generation does not deploy.
75
76
  The same pure emitter is available from `@aotter/mantle/codegen` when a host
76
77
  wants to own parsing and filesystem IO. TypeScript-authored manifests can pass
77
78
  their already-compiled `plan` directly:
@@ -104,11 +105,10 @@ does not cache or retry. Dynamic and platform hosts can keep their own lifecycle
104
105
  use generated `bindMantle(runtime)`, or skip code generation and call
105
106
  `runtime.executeView({ view: "published-notes" })` directly.
106
107
 
107
- Author the application directly using [the installed guide](docs/handbook/start/project-and-cli.md).
108
- Admin is opt-in; use [local Admin OTP](docs/handbook/start/quickstart-admin.md)
109
- only when humans need a console.
110
- The CLI has no scaffold/type picker; missing manifests fail without creating
111
- an application or a visitor home page.
108
+ Start with [Project layout and CLI](docs/handbook/start/project-and-cli.md).
109
+ The [local Admin OTP](docs/handbook/start/quickstart-admin.md) tutorial remains
110
+ for apps that own their Worker entry. Generated apps start with an editable
111
+ blank home and no invented business Schema.
112
112
 
113
113
  `mantle skills` copies every skill the installed package marks
114
114
  `projection: project` in its front matter into matching
@@ -205,7 +205,7 @@ internals or rebuilding Mantle's adapters.
205
205
  Cold start from GitHub or a marketplace host:
206
206
 
207
207
  ```sh
208
- npx skills add aotter/mantle --skill install
208
+ npx skills add aotter/mantle
209
209
  ```
210
210
 
211
211
  That skill interviews, pins this package, then uses the CLI and the
@@ -223,7 +223,7 @@ Install the Mantle Core skill bundle before authoring or maintaining a
223
223
  consumer application. The canonical command is:
224
224
 
225
225
  ```sh
226
- npx skills add aotter/mantle --skill install
226
+ npx skills add aotter/mantle
227
227
  ```
228
228
 
229
229
  Claude Code and Codex can install the plugin, then run that skill:
@@ -242,7 +242,7 @@ Cursor and VS Code Copilot can auto-discover the GitHub repo through
242
242
  `.cursor-plugin/plugin.json` and `.copilot-plugin/plugin.json` after the repo
243
243
  is cloned or opened. Still start from the `npx skills add` sentence (or open
244
244
  `skills/install/SKILL.md`). Untagged `aotter/mantle` resolves to `main`, which
245
- only advances at a release, so it is always the latest published version. Add
245
+ can contain a source-only hotfix ahead of the latest npm release. Add
246
246
  `@vX.Y.Z` only to reproduce an older project; never point a consumer at
247
247
  `develop` or another moving branch.
248
248
 
@@ -0,0 +1,7 @@
1
+ import { type ProjectSelection } from "./generate-project.js";
2
+ /** Prepare all paths before the caller commits any project files. */
3
+ export declare function prepareCloudflare(root: string, output: string, selection: ProjectSelection, fresh: boolean): Promise<{
4
+ readonly stale: boolean;
5
+ readonly commit: () => Promise<void>;
6
+ }>;
7
+ //# sourceMappingURL=generate-cloudflare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-cloudflare.d.ts","sourceRoot":"","sources":["../../src/cli/generate-cloudflare.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAInF,qEAAqE;AACrE,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAC1H,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC,CAAC,CAuFD"}
@@ -0,0 +1,123 @@
1
+ import { appendFile, lstat, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { basename, dirname, join, relative, resolve, sep } from "node:path";
3
+ import { assertInsideProject } from "./generate-project.js";
4
+ /** Prepare all paths before the caller commits any project files. */
5
+ export async function prepareCloudflare(root, output, selection, fresh) {
6
+ const selected = (feature) => selection.features.includes(feature);
7
+ const name = basename(root).toLowerCase().replace(/[^a-z0-9-]/g, "-")
8
+ .replace(/^-+|-+$/g, "").slice(0, 63).replace(/-+$/g, "") || "mantle-app";
9
+ const worker = resolve(root, output, "worker.ts");
10
+ const fromIndex = importPath(join(root, "src/index.ts"), worker);
11
+ const toHandlers = importPath(worker, join(root, "src/handlers.ts"));
12
+ const toHome = importPath(worker, join(root, "src/home.ts"));
13
+ if (!selected("admin")) {
14
+ const adminAssets = join(root, "public/_mantle/admin");
15
+ await assertInsideProject(root, adminAssets);
16
+ const present = await lstat(adminAssets).then(() => true, (error) => {
17
+ if (error.code === "ENOENT")
18
+ return false;
19
+ throw error;
20
+ });
21
+ if (present)
22
+ throw new Error("Unselected Admin assets already exist; remove them deliberately before generating this reduced composition.");
23
+ }
24
+ const files = [
25
+ { path: worker, content: workerSource(selection, toHandlers, toHome), owned: true },
26
+ { path: "src/index.ts", content: `export { default } from "${fromIndex}";\n`, owned: false },
27
+ { path: "src/handlers.ts", content: 'import type { AnyHandler } from "@aotter/mantle/runtime";\n\nexport const handlers: Record<string, AnyHandler> = {};\n', owned: false },
28
+ { path: "tsconfig.json", content: `${JSON.stringify({ compilerOptions: {
29
+ target: "ES2022", module: "NodeNext", moduleResolution: "NodeNext", strict: true,
30
+ noEmit: true, skipLibCheck: true, types: ["@cloudflare/workers-types"],
31
+ }, include: ["src/**/*.ts", `${relative(root, resolve(root, output)).split(sep).join("/") || "."}/**/*.ts`] }, null, 2)}\n`, owned: false },
32
+ ];
33
+ const wrangler = await Promise.all(["wrangler.jsonc", "wrangler.json", "wrangler.toml"].map(async (path) => ({
34
+ path, text: await readFile(join(root, path), "utf8").catch((error) => {
35
+ if (error.code === "ENOENT")
36
+ return null;
37
+ throw error;
38
+ }),
39
+ })));
40
+ const presentWrangler = wrangler.filter((file) => file.text !== null);
41
+ if (presentWrangler.length > 1)
42
+ throw new Error(`Multiple Wrangler configs found: ${presentWrangler.map((file) => file.path).join(", ")}. Choose one before generating.`);
43
+ const existingWrangler = presentWrangler[0];
44
+ if (!existingWrangler) {
45
+ files.push({ path: "wrangler.jsonc", content: `${JSON.stringify({
46
+ $schema: "node_modules/wrangler/config-schema.json", name, main: "src/index.ts",
47
+ compatibility_date: "2026-09-08", compatibility_flags: ["nodejs_compat", "global_fetch_strictly_public"],
48
+ ...(selected("admin") ? { assets: { directory: "./public", binding: "ASSETS" } } : {}),
49
+ d1_databases: [{ binding: "DB", database_name: name }],
50
+ }, null, 2)}\n`, owned: false });
51
+ }
52
+ if (selected("admin"))
53
+ files.push({ path: ".dev.vars.example", content: "# Copy to .dev.vars for local Admin OTP. Never deploy these values.\nMANTLE_AUTH_MODE=local-otp\nPUBLIC_ORIGIN=http://127.0.0.1:8787\nADMIN_EMAIL=you@example.com\nBETTER_AUTH_SECRET=replace-with-a-random-32-byte-secret\n", owned: false });
54
+ if (selected("web"))
55
+ files.push({
56
+ path: "src/home.ts", owned: false,
57
+ content: 'export function home(): Response {\n return new Response(`<!doctype html><html lang="en"><meta charset="utf-8"><title>Mantle</title><body><main></main></body></html>`, { headers: { "content-type": "text/html; charset=utf-8" } });\n}\n',
58
+ });
59
+ const ignorePath = join(root, ".gitignore");
60
+ await assertInsideProject(root, ignorePath);
61
+ const gitignore = await readFile(ignorePath, "utf8").catch((error) => {
62
+ if (error.code === "ENOENT")
63
+ return null;
64
+ throw error;
65
+ });
66
+ const ignoreMissing = !gitignore?.split(/\r?\n/).includes(".dev.vars");
67
+ let stale = ignoreMissing;
68
+ const writes = [];
69
+ for (const file of files) {
70
+ const path = resolve(root, file.path);
71
+ await assertInsideProject(root, path);
72
+ const current = await readFile(path, "utf8").catch((error) => {
73
+ if (error.code === "ENOENT")
74
+ return null;
75
+ throw error;
76
+ });
77
+ if (current !== null && file.owned && !current.startsWith("// Generated by `mantle generate`")) {
78
+ throw new Error(`Generated output would replace a user-owned file: ${path}`);
79
+ }
80
+ if ((current === null && (file.owned || fresh || ["src/index.ts", "src/handlers.ts", "src/home.ts", "tsconfig.json", "wrangler.jsonc"].includes(file.path))) ||
81
+ (file.owned && current !== file.content)) {
82
+ stale = true;
83
+ writes.push(file);
84
+ }
85
+ }
86
+ return {
87
+ stale,
88
+ commit: async () => {
89
+ for (const file of writes) {
90
+ const path = resolve(root, file.path);
91
+ await mkdir(dirname(path), { recursive: true });
92
+ await writeFile(path, file.content, { flag: file.owned ? "w" : "wx" });
93
+ }
94
+ if (ignoreMissing) {
95
+ if (gitignore === null)
96
+ await writeFile(ignorePath, "node_modules/\n.wrangler/\n.dev.vars\n", { flag: "wx" });
97
+ else
98
+ await appendFile(ignorePath, `${gitignore.endsWith("\n") ? "" : "\n"}.dev.vars\n`);
99
+ }
100
+ },
101
+ };
102
+ }
103
+ function workerSource(selection, toHandlers, toHome) {
104
+ const has = (feature) => selection.features.includes(feature);
105
+ const auth = has("admin");
106
+ return `// Generated by \`mantle generate\`. Edit src/home.ts and src/handlers.ts instead.\n` +
107
+ `import { createMantleWorker${auth ? ", createAuth, createConventionalAuth, ConsoleEmailSender" : ""}, type MantleCloudflareEnv } from "@aotter/mantle/cloudflare";\n` +
108
+ `import { plan } from "./mantle.js";\n` +
109
+ `import { handlers } from "${toHandlers}";\n` +
110
+ (has("web") ? `import { home } from "${toHome}";\n` : "") +
111
+ `\ntype Env = MantleCloudflareEnv & { readonly ADMIN_EMAIL?: string };\n` +
112
+ (auth ? `const sender = new ConsoleEmailSender();\n` : "") +
113
+ `\nexport default createMantleWorker<Env>({\n plan,\n handlers,\n` +
114
+ ` surfaces: { api: ${has("api")}, mcp: ${has("mcp")}, admin: ${has("admin")} },\n` +
115
+ (has("web") ? ` frontend: () => home(),\n` : "") +
116
+ (auth ? ` auth: (env) => {\n if (env.MANTLE_AUTH_MODE !== "local-otp") return createConventionalAuth(env);\n const origin = env.PUBLIC_ORIGIN;\n let local = false;\n try { const url = new URL(origin ?? ""); local = url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname); } catch { /* fail closed */ }\n if (!origin || !local || !env.ADMIN_EMAIL || !env.BETTER_AUTH_SECRET) return createConventionalAuth(env);\n return createAuth({\n database: env.DB, baseURL: origin, secret: env.BETTER_AUTH_SECRET,\n methods: [{ kind: "email-otp", sender }],\n bootstrapOwner: { match: "email", value: env.ADMIN_EMAIL },\n oauthProvider: {\n loginPage: "/admin/sign-in", consentPage: "/oauth/consent",\n scopes: ["mcp"], mcpResource: \`\${origin.replace(/\\/+$/, "")}/mcp\`,\n allowDynamicClientRegistration: true, allowUnauthenticatedClientRegistration: true,\n clientRegistrationDefaultScopes: ["mcp"], clientRegistrationAllowedScopes: ["mcp"],\n },\n });\n },\n` : "") +
117
+ `});\n`;
118
+ }
119
+ function importPath(from, to) {
120
+ const path = relative(dirname(from), to).split(sep).join("/").replace(/\.ts$/, ".js");
121
+ return path.startsWith(".") ? path : `./${path}`;
122
+ }
123
+ //# sourceMappingURL=generate-cloudflare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-cloudflare.js","sourceRoot":"","sources":["../../src/cli/generate-cloudflare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export declare const FEATURES: readonly ["spec", "runtime", "api", "mcp", "admin", "web"];
2
+ export type Feature = typeof FEATURES[number];
3
+ export type Host = "cf" | "chatgpt-sites";
4
+ export interface ProjectSelection {
5
+ readonly version: 1;
6
+ readonly host: Host | null;
7
+ readonly features: readonly Feature[];
8
+ readonly output?: string;
9
+ }
10
+ export interface ProjectOptions {
11
+ readonly root: string;
12
+ readonly host?: string;
13
+ readonly features?: string;
14
+ readonly check: boolean;
15
+ readonly output: string;
16
+ }
17
+ export interface ProjectDecision {
18
+ readonly mode: "legacy" | "project";
19
+ readonly selection?: ProjectSelection;
20
+ readonly incomplete: boolean;
21
+ readonly commit?: () => Promise<void>;
22
+ }
23
+ export declare function prepareProject(options: ProjectOptions): Promise<ProjectDecision>;
24
+ export declare function assertInsideProject(root: string, path: string): Promise<void>;
25
+ //# sourceMappingURL=generate-project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-project.d.ts","sourceRoot":"","sources":["../../src/cli/generate-project.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,QAAQ,4DAA6D,CAAC;AACnF,MAAM,MAAM,OAAO,GAAG,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC9C,MAAM,MAAM,IAAI,GAAG,IAAI,GAAG,eAAe,CAAC;AAC1C,MAAM,WAAW,gBAAgB;IAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE;AACtJ,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAcD,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAiHtF;AAmFD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBnF"}
@@ -0,0 +1,282 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { lstat, mkdir, readFile, readdir, realpath, rename, rm, writeFile } from "node:fs/promises";
3
+ import { basename, dirname, join, relative, resolve, sep } from "node:path";
4
+ import { stderr, stdin, stdout } from "node:process";
5
+ import { createInterface } from "node:readline/promises";
6
+ import { prepareCloudflare } from "./generate-cloudflare.js";
7
+ export const FEATURES = ["spec", "runtime", "api", "mcp", "admin", "web"];
8
+ const CONFIG = "mantle.config.json";
9
+ const FULL = FEATURES;
10
+ const DEPENDS = {
11
+ spec: [], runtime: ["spec"], api: ["runtime"], mcp: ["runtime"], admin: ["runtime", "api", "mcp"], web: ["runtime"],
12
+ };
13
+ const BOOTSTRAP = new Set([
14
+ ".git", ".gitignore", ".agent", ".agents", ".claude", ".codex", ".cursor", ".gemini", ".opencode", ".windsurf",
15
+ ".vscode", ".idea", ".skills", "skills", "node_modules", "package.json",
16
+ "package-lock.json", "pnpm-lock.yaml", "yarn.lock", "bun.lock", "bun.lockb", "skills-lock.json", "README.md", "AGENTS.md",
17
+ ".DS_Store", ".npmrc", ".yarnrc.yml", ".yarn", ".nvmrc", "CLAUDE.md", "LICENSE", ".editorconfig",
18
+ ]);
19
+ export async function prepareProject(options) {
20
+ const root = await realpath(options.root);
21
+ const configPath = join(root, CONFIG);
22
+ const saved = await readFile(configPath, "utf8").catch((error) => {
23
+ if (error.code === "ENOENT")
24
+ return null;
25
+ throw error;
26
+ });
27
+ const evidence = (await readdir(root)).filter((name) => !BOOTSTRAP.has(name) && name !== CONFIG);
28
+ if (saved === null && evidence.length) {
29
+ if (options.host || options.features)
30
+ throw new Error(`Existing application (${evidence.join(", ")}) uses direct authoring; generate a new application separately or integrate Mantle with the installed integration skill.`);
31
+ stdout.write(`Legacy compile mode: existing application files ${evidence.join(", ")}.\n`);
32
+ return { mode: "legacy", incomplete: false };
33
+ }
34
+ const selection = saved !== null ? parseSelection(saved) : await chooseSelection(options);
35
+ if (saved !== null && options.output !== ".mantle/generated" && options.output !== (selection.output ?? ".mantle/generated")) {
36
+ throw new Error("Changing a saved generated output directory is not supported; use the saved output path.");
37
+ }
38
+ if (saved !== null && (options.host !== undefined || options.features !== undefined)) {
39
+ const requested = await chooseSelection(options, selection);
40
+ if (JSON.stringify(requested) !== JSON.stringify(selection)) {
41
+ throw new Error("Changing a saved host or feature list is not supported in v1; plan a deliberate application migration.");
42
+ }
43
+ }
44
+ stdout.write(`Generated project mode: ${selection.host ?? "host-free"}; features ${selection.features.join(", ")}${saved !== null ? " (saved)" : " (new)"}.\n`);
45
+ const packagePath = join(root, "package.json");
46
+ const existingPackage = await readFile(packagePath, "utf8").catch((error) => {
47
+ if (error.code === "ENOENT")
48
+ return null;
49
+ throw error;
50
+ });
51
+ const pkg = existingPackage ? JSON.parse(existingPackage) : {
52
+ name: basename(root).toLowerCase().replace(/[^a-z0-9._-]/g, "-").replace(/^[._-]+/, "") || "app", private: true, type: "module",
53
+ };
54
+ if (!pkg || typeof pkg !== "object" || Array.isArray(pkg) ||
55
+ [pkg.dependencies, pkg.devDependencies, pkg.scripts].some((value) => value !== undefined &&
56
+ (!value || typeof value !== "object" || Array.isArray(value)))) {
57
+ throw new Error("package.json must contain an object with object-valued dependencies and scripts.");
58
+ }
59
+ if (pkg.type !== undefined && pkg.type !== "module") {
60
+ throw new Error("Generated applications require package.json type=module; preserve CommonJS applications in legacy compile mode.");
61
+ }
62
+ const addModuleType = pkg.type === undefined;
63
+ const version = JSON.parse(await readFile(new URL("../../package.json", import.meta.url), "utf8")).version;
64
+ const required = requiredPackages(selection, version);
65
+ const dependencies = { ...(pkg.dependencies ?? {}) };
66
+ const devDependencies = { ...(pkg.devDependencies ?? {}) };
67
+ let packageChanged = existingPackage === null || addModuleType;
68
+ for (const [name, expected] of Object.entries(required)) {
69
+ const actual = dependencies[name] ?? devDependencies[name];
70
+ if (actual && name.startsWith("@aotter/") && actual !== expected) {
71
+ throw new Error(`package.json declares ${name}@${actual}; expected exact ${expected}. Review this conflict before generating.`);
72
+ }
73
+ if (!actual) {
74
+ if (["wrangler", "typescript", "@cloudflare/workers-types", "esbuild"].includes(name))
75
+ devDependencies[name] = expected;
76
+ else
77
+ dependencies[name] = expected;
78
+ packageChanged = true;
79
+ }
80
+ }
81
+ const scripts = { ...(pkg.scripts ?? {}) };
82
+ const requiredScripts = { generate: "mantle generate", "generate:check": "mantle generate --check",
83
+ ...(selection.host === "cf" ? { dev: "wrangler dev --local --ip 127.0.0.1 --port 8787", deploy: "wrangler deploy", typecheck: "tsc --noEmit", build: "mantle generate && tsc --noEmit" } : {}),
84
+ ...(selection.host === "chatgpt-sites" ? { dev: "wrangler dev --local --ip 127.0.0.1 --port 4174", typecheck: "tsc --noEmit", build: "node scripts/build.mjs",
85
+ ...(selection.features.includes("admin") ? { "smoke:local": "node scripts/smoke-local.mjs" } : {}) } : {}) };
86
+ for (const [name, expected] of Object.entries(requiredScripts)) {
87
+ if (scripts[name] && scripts[name] !== expected) {
88
+ if (name === "generate" || name === "generate:check")
89
+ throw new Error(`package.json scripts.${name} conflicts with generated command ${expected}.`);
90
+ continue;
91
+ }
92
+ if (!scripts[name]) {
93
+ scripts[name] = expected;
94
+ packageChanged = true;
95
+ }
96
+ }
97
+ const lockfiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock", "bun.lockb"].filter((name) => existsSync(join(root, name)));
98
+ if (lockfiles.length > 1)
99
+ throw new Error(`Multiple package-manager lockfiles found: ${lockfiles.join(", ")}. Choose one before generating.`);
100
+ await assertInsideProject(root, packagePath);
101
+ await assertInsideProject(root, configPath);
102
+ const outputDir = selection.output ?? options.output;
103
+ const output = resolve(root, outputDir, "mantle.ts");
104
+ await assertInsideProject(root, output);
105
+ const existingOutput = await readFile(output, "utf8").catch((error) => {
106
+ if (error.code === "ENOENT")
107
+ return null;
108
+ throw error;
109
+ });
110
+ if (existingOutput !== null && !existingOutput.startsWith("// Generated by `mantle generate`")) {
111
+ throw new Error(`Generated output would replace a user-owned file: ${output}`);
112
+ }
113
+ if (selection.features.includes("admin")) {
114
+ const admin = resolve(root, "public/_mantle/admin");
115
+ await assertInsideProject(root, admin);
116
+ if (saved === null && existsSync(admin)) {
117
+ throw new Error(`Admin asset target already exists and cannot be verified as generated: ${admin}`);
118
+ }
119
+ }
120
+ const cloudflare = selection.host === "cf" ? await prepareCloudflare(root, outputDir, selection, saved === null) : null;
121
+ const nextPackage = packageChanged ? `${JSON.stringify({ ...pkg, type: "module", scripts, dependencies,
122
+ ...(Object.keys(devDependencies).length ? { devDependencies } : {}),
123
+ }, null, 2)}\n` : existingPackage;
124
+ const nextConfig = `${JSON.stringify(selection, null, 2)}\n`;
125
+ const drift = saved === null || existingPackage !== nextPackage || Boolean(cloudflare?.stale);
126
+ if (options.check) {
127
+ if (drift)
128
+ stderr.write("Project config or package declarations are stale.\n");
129
+ const missing = missingPackages(root, required);
130
+ if (missing.length)
131
+ stderr.write(`Selected packages are missing or mismatched: ${missing.join(", ")}.\n`);
132
+ return { mode: "project", selection, incomplete: drift || missing.length > 0 };
133
+ }
134
+ const missing = missingPackages(root, required);
135
+ const install = lockfiles[0] === "pnpm-lock.yaml" ? "pnpm install" : lockfiles[0] === "yarn.lock" ? "yarn install" : lockfiles[0]?.startsWith("bun") ? "bun install" : "npm install";
136
+ return {
137
+ mode: "project", selection, incomplete: missing.length > 0,
138
+ commit: async () => {
139
+ if (existingPackage !== nextPackage)
140
+ await atomicWrite(packagePath, nextPackage);
141
+ if (saved === null)
142
+ await atomicWrite(configPath, nextConfig);
143
+ await cloudflare?.commit();
144
+ if (missing.length)
145
+ stdout.write(`Install selected packages with ${install}, then run mantle generate again. Missing or mismatched: ${missing.join(", ")}.\n`);
146
+ },
147
+ };
148
+ }
149
+ async function chooseSelection(options, saved) {
150
+ const selected = options.features === undefined ? saved?.features ?? FULL : options.features.split(",").map((value) => value.trim());
151
+ if (!selected.length || selected.some((value) => !FEATURES.includes(value))) {
152
+ throw new Error(`--features accepts only ${FEATURES.join(", ")}; got ${options.features ?? ""}.`);
153
+ }
154
+ const closure = new Set();
155
+ const add = (feature) => { for (const dep of DEPENDS[feature])
156
+ add(dep); closure.add(feature); };
157
+ for (const feature of selected)
158
+ add(feature);
159
+ const features = FEATURES.filter((feature) => closure.has(feature));
160
+ let host = options.host ?? (features.length === 1 ? null : saved?.host ?? null);
161
+ if (host && host !== "cf" && host !== "chatgpt-sites")
162
+ throw new Error(`--host must be cf or chatgpt-sites; got ${host}.`);
163
+ if (features.some((feature) => feature !== "spec") && !host) {
164
+ if (options.check || !stdin.isTTY)
165
+ throw new Error("Host required for selected features; pass --host cf or --host chatgpt-sites.");
166
+ const prompt = createInterface({ input: stdin, output: stdout });
167
+ try {
168
+ host = (await prompt.question("Host (cf/chatgpt-sites): ")).trim();
169
+ }
170
+ finally {
171
+ prompt.close();
172
+ }
173
+ if (host !== "cf" && host !== "chatgpt-sites")
174
+ throw new Error("Host must be cf or chatgpt-sites.");
175
+ }
176
+ if (features.length === 1 && host)
177
+ throw new Error("Spec-only generation is host-free; omit --host.");
178
+ return { version: 1, host: host, features,
179
+ ...(options.output !== ".mantle/generated" ? { output: options.output } : saved?.output ? { output: saved.output } : {}) };
180
+ }
181
+ function parseSelection(source) {
182
+ const value = JSON.parse(source);
183
+ if (!value || value.version !== 1 || !Array.isArray(value.features) ||
184
+ value.features.some((feature) => !FEATURES.includes(feature)) ||
185
+ (value.host !== null && value.host !== "cf" && value.host !== "chatgpt-sites") ||
186
+ (value.output !== undefined && (typeof value.output !== "string" || !value.output.trim()))) {
187
+ throw new Error("Invalid mantle.config.json selection.");
188
+ }
189
+ const selected = new Set(value.features);
190
+ if (!selected.has("spec") || value.features.length !== selected.size ||
191
+ FEATURES.filter((feature) => selected.has(feature)).join(",") !== value.features.join(",") ||
192
+ value.features.some((feature) => DEPENDS[feature].some((dependency) => !selected.has(dependency))) ||
193
+ (value.features.length === 1) !== (value.host === null)) {
194
+ throw new Error("mantle.config.json has an invalid feature closure or host.");
195
+ }
196
+ return { version: 1, host: value.host, features: value.features,
197
+ ...(value.output ? { output: value.output } : {}) };
198
+ }
199
+ function requiredPackages(selection, version) {
200
+ const required = { "@aotter/mantle": version, zod: "^4.5.0" };
201
+ if (selection.host)
202
+ required["@aotter/mantle-cloudflare"] = version;
203
+ if (selection.features.includes("admin")) {
204
+ required["@aotter/mantle-admin"] = version;
205
+ required["@aotter/mantle-admin-ui"] = version;
206
+ }
207
+ if (selection.features.includes("web"))
208
+ required["@aotter/mantle-web"] = version;
209
+ if (selection.host) {
210
+ // The current Cloudflare adapter declares these peers even in reduced compositions.
211
+ required["better-auth"] = "1.7.2";
212
+ required["hono"] = "^4.12.0";
213
+ required["aws4fetch"] = "^1.0.20";
214
+ }
215
+ if (selection.host === "cf" && selection.features.includes("admin"))
216
+ required["@aotter/mantle-auth"] = version;
217
+ if (selection.host === "cf" || selection.host === "chatgpt-sites") {
218
+ required.wrangler = "4.129.0";
219
+ required.typescript = "^6.0.3";
220
+ required["@cloudflare/workers-types"] = "5.20260904.1";
221
+ }
222
+ if (selection.host === "chatgpt-sites")
223
+ required.esbuild = "^0.28.0";
224
+ return required;
225
+ }
226
+ function missingPackages(root, required) {
227
+ return Object.entries(required).filter(([name, expected]) => {
228
+ let path = null;
229
+ for (let parent = root;; parent = dirname(parent)) {
230
+ const candidate = join(parent, "node_modules", name, "package.json");
231
+ if (existsSync(candidate)) {
232
+ path = candidate;
233
+ break;
234
+ }
235
+ if (dirname(parent) === parent)
236
+ break;
237
+ }
238
+ if (!path)
239
+ return true;
240
+ if (!name.startsWith("@aotter/"))
241
+ return false;
242
+ try {
243
+ return JSON.parse(readFileSync(path, "utf8")).version !== expected;
244
+ }
245
+ catch {
246
+ return true;
247
+ }
248
+ }).map(([name]) => name);
249
+ }
250
+ export async function assertInsideProject(root, path) {
251
+ const project = await realpath(root);
252
+ let parent = resolve(path);
253
+ while (true) {
254
+ try {
255
+ if ((await lstat(parent)).isSymbolicLink())
256
+ throw new Error(`Generated path uses a symlink: ${parent}`);
257
+ break;
258
+ }
259
+ catch (error) {
260
+ if (error.code !== "ENOENT")
261
+ throw error;
262
+ parent = dirname(parent);
263
+ }
264
+ }
265
+ const target = await realpath(parent);
266
+ const difference = relative(project, target);
267
+ if (difference === ".." || difference.startsWith(`..${sep}`) || resolve(path) === project) {
268
+ throw new Error(`Generated path escapes project: ${path}`);
269
+ }
270
+ }
271
+ async function atomicWrite(path, value) {
272
+ await mkdir(dirname(path), { recursive: true });
273
+ const temporary = `${path}.${process.pid}.tmp`;
274
+ try {
275
+ await writeFile(temporary, value, { flag: "wx" });
276
+ await rename(temporary, path);
277
+ }
278
+ finally {
279
+ await rm(temporary, { force: true });
280
+ }
281
+ }
282
+ //# sourceMappingURL=generate-project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-project.js","sourceRoot":"","sources":["../../src/cli/generate-project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { SchemaManifest } from "@aotter/mantle-spec";
2
+ import { type ProjectSelection } from "./generate-project.js";
3
+ export declare function prepareSites(root: string, output: string, selection: ProjectSelection, schemas: readonly SchemaManifest[], check: boolean, reviewUniqueIndexes?: boolean): Promise<{
4
+ readonly stale: boolean;
5
+ readonly report?: string;
6
+ readonly commit: () => Promise<void>;
7
+ }>;
8
+ //# sourceMappingURL=generate-sites.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-sites.d.ts","sourceRoot":"","sources":["../../src/cli/generate-sites.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAWnF,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,OAAO,EAAE,SAAS,cAAc,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,mBAAmB,UAAQ,GAAG,OAAO,CAAC;IACtL,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC,CAAC,CAqFD"}