anhedral 0.4.1 → 0.4.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/CONTRIBUTING.md +4 -0
  3. package/README.md +68 -55
  4. package/SKILL.md +107 -12
  5. package/dist/architecture/index.d.ts +2 -2
  6. package/dist/architecture/index.js +1 -1
  7. package/dist/architecture/modules.d.ts +5 -1
  8. package/dist/architecture/modules.js +4 -1
  9. package/dist/bin.js +113 -84
  10. package/dist/cli.d.ts +7 -7
  11. package/dist/cli.js +62 -16
  12. package/dist/dependencies.d.ts +1 -0
  13. package/dist/dependencies.js +11 -8
  14. package/dist/index.d.ts +2 -2
  15. package/dist/index.js +1 -1
  16. package/dist/project.d.ts +30 -0
  17. package/dist/project.js +1 -0
  18. package/dist/prompts.d.ts +4 -3
  19. package/dist/prompts.js +29 -7
  20. package/dist/scaffold.d.ts +12 -24
  21. package/dist/scaffold.js +330 -123
  22. package/dist/templates/api.d.ts +1 -1
  23. package/dist/templates/api.js +67 -2
  24. package/dist/templates/assets-private-proxy.d.ts +1 -1
  25. package/dist/templates/desktop.d.ts +1 -1
  26. package/dist/templates/desktop.js +189 -36
  27. package/dist/templates/electron-updater.d.ts +1 -1
  28. package/dist/templates/electron-updater.js +1 -1
  29. package/dist/templates/extension.d.ts +1 -1
  30. package/dist/templates/extension.js +138 -14
  31. package/dist/templates/first-run.d.ts +2 -0
  32. package/dist/templates/first-run.js +167 -0
  33. package/dist/templates/mobile.d.ts +1 -1
  34. package/dist/templates/mobile.js +158 -17
  35. package/dist/templates/shared.d.ts +1 -1
  36. package/dist/templates/shared.js +64 -7
  37. package/dist/templates/web.d.ts +1 -1
  38. package/dist/templates/web.js +185 -28
  39. package/dist/version.d.ts +1 -1
  40. package/dist/version.js +1 -1
  41. package/docs/NORTHSTAR.md +114 -0
  42. package/docs/conventions.md +6 -4
  43. package/docs/engineering-principles.md +88 -0
  44. package/docs/output-tree-contract.md +16 -5
  45. package/docs/references/manual-scaffolding.md +22 -4
  46. package/docs/references/provisioning.md +434 -77
  47. package/package.json +3 -1
package/CHANGELOG.md CHANGED
@@ -6,6 +6,52 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 0.4.2 - 2026-07-23
10
+
11
+ ### Added
12
+
13
+ - Add idempotent `pnpm first-run` setup plus a secret-safe `pnpm ready` gate with
14
+ human and JSON output, required/optional variable awareness, and truthful exit
15
+ status.
16
+ - Generate a working items feature across Drizzle, Zod contracts, Fastify
17
+ routes, the shared API client, and idiomatic Next.js, Expo, Electron, and WXT
18
+ interfaces for every selected client.
19
+ - Add explicit `--all`, automatic Git initialization for `new`, dependency-resolution previews, confirmation, exact generated lifecycle scripts, UI-provider command previews, and actionable `doctor` recommendations.
20
+ - Add a published DX north star that defines measurable discovery, creation,
21
+ configuration, development, extension, diagnosis, upgrade, and shipping
22
+ journeys.
23
+
24
+ ### Changed
25
+
26
+ - Default interactive creation to a focused web app with optional capabilities while preserving the complete-stack default for noninteractive compatibility.
27
+ - Replace deprecated Turborepo development commands, make cache outputs package-specific, and let typechecks depend on upstream typechecks instead of builds.
28
+ - Track bundled UI primitives in the project manifest and make generated onboarding, deployment, provider, and source-location guidance selection-aware.
29
+ - Include status, generator version, project root, resolved modules, and next
30
+ steps in machine-readable plans; make human lifecycle output concise unless a
31
+ dry-run or verbose path listing is requested.
32
+
33
+ ### Fixed
34
+
35
+ - Allow Next.js client API factories to render safely during production prerendering while preserving HTTPS enforcement for non-loopback production endpoints.
36
+ - Make generated lifecycle commands reproducible even though Anhedral is intentionally not installed in application dependencies.
37
+ - Forward arguments through generated pnpm lifecycle scripts without inserting a literal `--` that the Anhedral or provider CLI would reject.
38
+ - Treat generated Clerk placeholder keys as unconfigured on every client instead
39
+ of mounting providers with knowingly invalid values.
40
+ - Keep Electron starter features synchronized with Clerk sign-in changes instead
41
+ of treating an opened account dialog as an authenticated session.
42
+ - Put reviewed database migration generation, Git staging, verification, and
43
+ application in one consistent onboarding order.
44
+ - Detect required environment variables that were deleted from an existing
45
+ package-local configuration file.
46
+
47
+ ### Security
48
+
49
+ - Scope generated starter-item reads and writes to the authenticated Clerk user
50
+ whenever authentication is selected.
51
+ - Reject local home-directory paths and email addresses in source and packed
52
+ release artifacts while continuing to allow documentation placeholders and
53
+ public GitHub noreply contributor identities.
54
+
9
55
  ## 0.4.1 - 2026-07-22
10
56
 
11
57
  ### Added
package/CONTRIBUTING.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Contributing
2
2
 
3
+ Changes should follow the repository's
4
+ [engineering principles](docs/engineering-principles.md): explicit behavior,
5
+ one source of truth, narrow namespaces, visible failures, and focused tests.
6
+
3
7
  ## Local setup
4
8
 
5
9
  Anhedral requires Node.js 20.19+ or 22.12+ and pnpm 10.34.5.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Anhedral
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/anhedral.svg)](https://www.npmjs.com/package/anhedral)
4
- [![node](https://img.shields.io/node/v/anhedral.svg)](https://www.npmjs.com/package/anhedral)
4
+ [![Node.js ^20.19.0 or >=22.12.0](https://img.shields.io/badge/Node.js-%5E20.19.0%20%7C%7C%20%3E%3D22.12.0-339933?logo=nodedotjs&logoColor=white)](https://nodejs.org/)
5
5
 
6
6
  Anhedral generates a complete, production-oriented TypeScript stack whose source code stays understandable and customizable.
7
7
 
@@ -15,6 +15,9 @@ Anhedral generates a complete, production-oriented TypeScript stack whose source
15
15
 
16
16
  Anhedral is not a new programming language and generated applications do not run inside a proprietary application framework. It assembles well-documented tools, connects their difficult integration boundaries, and leaves developers with ordinary Next.js, Expo Router, Fastify, Drizzle, Electron, and WXT projects.
17
17
 
18
+ The measurable product and developer-experience contract is documented in the
19
+ [Anhedral DX north star](docs/NORTHSTAR.md).
20
+
18
21
  Anhedral is open source under the [Apache License 2.0](LICENSE). You may use,
19
22
  modify, and distribute it subject to that license, including its notice and
20
23
  redistribution requirements. Generated applications remain ordinary project
@@ -44,21 +47,33 @@ release submissions. Paste secrets directly into the instructed uncommitted
44
47
 
45
48
  ## Create an application directly
46
49
 
47
- Create the complete stack:
50
+ In an interactive terminal, start Anhedral and choose the surfaces and
51
+ capabilities you need:
48
52
 
49
53
  ```sh
50
54
  pnpm dlx anhedral@latest new my-product
51
55
  cd my-product
52
56
  ```
53
57
 
58
+ The suggested selection is a focused web app, and Anhedral shows the complete
59
+ resolved stack before it writes anything. To explicitly create every supported
60
+ surface and capability, use:
61
+
62
+ ```sh
63
+ pnpm dlx anhedral@latest new my-product --all
64
+ ```
65
+
54
66
  The generated `README.md` contains the exact next steps for the selected stack.
55
- For the complete stack, copy the package-local environment examples, configure
56
- the selected managed providers—including a Neon `DATABASE_URL`—and create the
57
- reviewed initial migration before running `pnpm dev`. Anhedral intentionally
58
- does not generate a local Postgres substitute or pretend that production
59
- provider credentials already exist.
67
+ Run `pnpm first-run` to create missing local environment files without
68
+ overwriting anything, then use `pnpm ready` for a secret-safe readiness check.
69
+ For the complete stack, configure the selected managed providers—including a
70
+ Neon `DATABASE_URL`—and create the reviewed initial migration before running
71
+ `pnpm dev`. Anhedral intentionally does not generate a local Postgres substitute
72
+ or pretend that production provider credentials already exist.
60
73
 
61
- With no module flags, `new` includes every supported application surface and backend capability. Generate a focused stack by naming only what the product needs:
74
+ In noninteractive environments, no module flags retain the complete-stack
75
+ default for compatibility. Prefer `--all` when that is your intent, or name
76
+ only what the product needs:
62
77
 
63
78
  ```sh
64
79
  pnpm dlx anhedral@latest new my-product --web --api --db --auth
@@ -106,47 +121,40 @@ Whole directories are omitted when their module is not selected. Generated docum
106
121
 
107
122
  ## Developer experience
108
123
 
109
- Developers use each tool normally:
110
-
111
- ```tsx
112
- // apps/web/app/projects/page.tsx
113
- import { ProjectList } from '@/components/projects/project-list';
124
+ Database-backed client stacks include a working `items` feature on day one. It
125
+ connects the Drizzle table, Zod request/response contracts, Fastify list/create
126
+ routes, typed client calls, and an idiomatic UI for every selected surface. Use
127
+ it to verify the stack, then rename or replace these ordinary user-owned files
128
+ with the product idea:
114
129
 
115
- export default function ProjectsPage() {
116
- return <ProjectList />;
117
- }
130
+ ```text
131
+ packages/db/src/app-schema.ts
132
+ packages/contracts/src/app.ts
133
+ apps/api/src/routes/app.ts
134
+ packages/api-client/src/app.ts
135
+ apps/web/components/item-list.tsx
136
+ apps/mobile/components/item-list.tsx
137
+ apps/desktop/src/renderer/components/item-list.tsx
138
+ apps/extension/src/components/item-list.tsx
118
139
  ```
119
140
 
141
+ Only paths for selected clients are generated. Shared contracts and API calls
142
+ stay consistent while presentation follows Next.js, React Native, Electron, or
143
+ browser-extension conventions.
144
+
120
145
  ```ts
121
146
  // packages/contracts/src/app.ts
122
147
  import { z } from 'zod';
123
148
 
124
- export const ProjectSchema = z.object({ id: z.string(), name: z.string() });
125
- export const ProjectListSchema = z.array(ProjectSchema);
126
- ```
127
-
128
- ```ts
129
- // packages/db/src/app-schema.ts
130
- import { pgTable, text } from 'drizzle-orm/pg-core';
131
-
132
- export const projects = pgTable('projects', {
133
- id: text('id').primaryKey(),
134
- name: text('name').notNull(),
149
+ export const ItemSchema = z.object({
150
+ id: z.string().uuid(),
151
+ name: z.string(),
152
+ createdAt: z.string().datetime(),
135
153
  });
154
+ export const ItemListSchema = z.array(ItemSchema);
136
155
  ```
137
156
 
138
- ```ts
139
- // apps/api/src/routes/app.ts
140
- import type { FastifyPluginAsync } from 'fastify';
141
- import { db } from '@shared/db';
142
- import { projects } from '@shared/db/schema';
143
-
144
- export const appRoutes: FastifyPluginAsync = async (app) => {
145
- app.get('/projects', async () => db.select().from(projects));
146
- };
147
- ```
148
-
149
- The convention is a conventional vertical flow, not an Anhedral DSL:
157
+ The flow is a normal TypeScript architecture, not an Anhedral DSL:
150
158
 
151
159
  ```text
152
160
  contracts -> database/service -> Fastify route -> typed API client -> frontend
@@ -183,29 +191,32 @@ Anhedral does **not** generate or require local Postgres. Database-enabled proje
183
191
  ```text
184
192
  anhedral new <directory> [modules...] Generate a new readable workspace
185
193
  anhedral init [modules...] Generate in the current empty directory
186
- anhedral add <module...> Add connected stack capabilities
187
- anhedral ui add <component...> Add source-owned UI components
188
- anhedral upgrade Transactionally upgrade a supported project
189
- anhedral doctor Check ownership and generator drift
194
+ anhedral new <directory> --all Explicitly select the complete stack
195
+ pnpm anhedral:add <module...> Add connected stack capabilities
196
+ pnpm anhedral:ui <component...> Add source-owned UI components
197
+ pnpm anhedral:upgrade Transactionally upgrade a supported project
198
+ pnpm anhedral:doctor Check ownership and generator drift
190
199
  ```
191
200
 
192
201
  Useful examples:
193
202
 
194
203
  ```sh
195
- anhedral add storage --dry-run
196
- anhedral add desktop extension
197
- anhedral add electron-updater
198
- anhedral ui add button dialog
199
- anhedral ui add data-table --target web --dry-run
200
- anhedral upgrade --dry-run
201
- anhedral doctor --json
204
+ pnpm anhedral:add storage --dry-run
205
+ pnpm anhedral:add desktop extension
206
+ pnpm anhedral:add electron-updater
207
+ pnpm anhedral:ui button dialog
208
+ pnpm anhedral:ui data-table --target web --dry-run
209
+ pnpm anhedral:upgrade --dry-run
210
+ pnpm anhedral:doctor --json
202
211
  ```
203
212
 
204
- `--dry-run` builds the complete plan without changing the project. `--json` emits machine-readable output. `--verbose` streams child-tool diagnostics.
213
+ `--dry-run` builds the structural plan without changing the project. For `ui add`, it also shows the exact provider command; registry-generated file paths are resolved only when the plan is applied. `--json` emits machine-readable output. `--verbose` streams child-tool diagnostics.
205
214
 
206
215
  Application lifecycle commands remain visible in the generated root `package.json`:
207
216
 
208
217
  ```sh
218
+ pnpm first-run
219
+ pnpm ready
209
220
  pnpm dev
210
221
  pnpm dev:all
211
222
  pnpm dev:web
@@ -229,18 +240,18 @@ Anhedral owns initial assembly and safe structural additions. It does not own pr
229
240
 
230
241
  - `README.md`, `PRODUCTION.md`, application features, pages, routes, services, and domain code are developer-owned.
231
242
  - Root workspace configuration is mergeable.
232
- - Integration substrate is recorded in `anhedral.json`; `anhedral add` refuses to overwrite modified managed files.
243
+ - Integration substrate is recorded in `anhedral.json`; `pnpm anhedral:add` refuses to overwrite modified managed files.
233
244
  - UI components are copied into the application so developers can edit them normally.
234
245
  - Provider integrations use ordinary SDKs and configuration files with no hidden control plane.
235
246
 
236
247
  Before a structural change:
237
248
 
238
249
  ```sh
239
- anhedral doctor
240
- anhedral add <module> --dry-run
250
+ pnpm anhedral:doctor
251
+ pnpm anhedral:add <module> --dry-run
241
252
  ```
242
253
 
243
- When `doctor` reports that a project was generated by a supported older release, run `anhedral upgrade --dry-run`, inspect the plan, and then run `anhedral upgrade`. Version 0.4 supports transactional upgrades from 0.3 projects while preserving user-owned extension seams. If a 0.3 project changed a file that was generator-managed, the upgrade stops instead of overwriting it. Preserve the change in source control, restore that managed file to its recorded 0.3 content, run the upgrade, and then move the product behavior into the new user-owned `app.ts`, `app-schema.ts`, page, component, or `app-window.ts` seam.
254
+ When `doctor` reports that a project was generated by a supported older release, run `pnpm anhedral:upgrade --dry-run`, inspect the plan, and then run `pnpm anhedral:upgrade`. Version 0.4 supports transactional upgrades from 0.3 projects while preserving user-owned extension seams. If a 0.3 project changed a file that was generator-managed, the upgrade stops instead of overwriting it. Preserve the change in source control, restore that managed file to its recorded 0.3 content, run the upgrade, and then move the product behavior into the new user-owned `app.ts`, `app-schema.ts`, page, component, or `app-window.ts` seam.
244
255
 
245
256
  ## Documentation contract
246
257
 
@@ -256,6 +267,8 @@ The generator's exact output contract is documented in [docs/output-tree-contrac
256
267
 
257
268
  The complete lifecycle, runtime, cloud, command, and coding-agent topology is in
258
269
  the [Anhedral master stack map](docs/master-stack-map.md).
270
+ The repository's implementation policy is the
271
+ [Zen of Anhedral](docs/engineering-principles.md).
259
272
 
260
273
  ## Module dependency rules
261
274
 
package/SKILL.md CHANGED
@@ -11,7 +11,70 @@ For every new project or provisioning request, begin by asking for the project
11
11
  name and whether the user already owns a custom domain for it. Do not run init
12
12
  or create provider resources until those answers establish canonical names.
13
13
 
14
- Use Node.js 20.19+ or 22.12+ and pnpm. `new` creates a destination directory; `init` works in an empty current directory where `.git`, `.gitignore`, and `.DS_Store` are allowed.
14
+ `new` creates a destination directory; `init` works in an empty current
15
+ directory where `.git`, `.gitignore`, and `.DS_Store` are allowed.
16
+
17
+ ## Bootstrap a blank workstation
18
+
19
+ Do not assume Node.js, npm, pnpm, Git, a browser, provider CLIs, or native build
20
+ tools are installed. After collecting the project name and domain status, audit
21
+ the workstation before generation:
22
+
23
+ ```sh
24
+ node --version
25
+ npm --version
26
+ pnpm --version
27
+ git --version
28
+ ```
29
+
30
+ For a new installation, recommend the current Node.js 24 LTS release. The
31
+ generator itself accepts `^20.19.0 || >=22.12.0`, but mobile projects require
32
+ `^22.13.0 || ^24.3.0 || >=25`; Node.js 24 LTS is the single supported choice
33
+ that covers every Anhedral module without using an end-of-life line.
34
+
35
+ If Node.js is absent, use Computer Use to open `https://nodejs.org/en/download`,
36
+ select the current Node.js 24 LTS installer for the user's operating system and
37
+ architecture, and stop for the user at the installer, administrator-password,
38
+ or operating-system approval boundary. npm is bundled with Node.js and may be
39
+ used to install pnpm, but npm is not the package manager for a generated
40
+ workspace. Installing the public Anhedral package does not require an npm
41
+ account or `npm login`.
42
+
43
+ Install the exact pnpm release recorded by this generator's
44
+ `package.json#packageManager` (currently `pnpm@10.34.5`):
45
+
46
+ ```sh
47
+ npm install --global pnpm@10.34.5
48
+ ```
49
+
50
+ Ask before a global or administrator-level installation. Verify the four
51
+ commands above again after installation. Install Git with the operating-system
52
+ package manager or official installer when it is missing; stop for UAC,
53
+ administrator credentials, Xcode Command Line Tools approval, or a license
54
+ prompt. Configure the user's real Git name and email only after asking what
55
+ identity they want commits to use.
56
+
57
+ A modern browser is required for OAuth device flows and provider dashboards.
58
+ No global Vercel, Neon, Wrangler, EAS, shadcn, or Anhedral installation is
59
+ required: generated scripts invoke reviewed CLI versions through `pnpm dlx`.
60
+ GitHub CLI is recommended for repository creation. Clerk CLI and Ably CLI are
61
+ optional supplemental control planes; use them only after the corresponding
62
+ module is selected, record the resolved version, and do not run `clerk init`
63
+ inside an Anhedral project because the integration source already exists.
64
+
65
+ Native tools are conditional:
66
+
67
+ - EAS cloud builds do not require local Xcode or Android Studio.
68
+ - Local iOS builds and manual App Store uploads require macOS and Xcode.
69
+ - Local Android builds/emulators require Android Studio and a compatible JDK.
70
+ - Signed Electron releases must be built on each target OS; macOS notarization
71
+ needs Xcode tooling and Apple credentials, while Windows distribution needs
72
+ an organization-owned code-signing certificate and Windows runner.
73
+ - Extension development requires a Chromium browser; store publication does
74
+ not require another build CLI beyond the generated WXT scripts.
75
+
76
+ Anhedral intentionally requires neither Docker nor local Postgres. Database
77
+ modules use managed Neon.
15
78
 
16
79
  ## Choose the construction path
17
80
 
@@ -38,7 +101,10 @@ native-subscriptions -> mobile + billing
38
101
  electron-updater -> desktop
39
102
  ```
40
103
 
41
- With no module flags, generate the full stack.
104
+ With no module flags in an interactive terminal, Anhedral prompts and suggests
105
+ a focused web app. In a noninteractive environment, no flags retain the full
106
+ stack for compatibility. Use `--all` when the complete stack is intentional,
107
+ or pass explicit modules for reproducible automation.
42
108
 
43
109
  ## Master stack map
44
110
 
@@ -78,10 +144,12 @@ domain, provider-order, and verification gates.
78
144
  The lead agent must:
79
145
 
80
146
  1. Ask for project name and existing/custom-domain status first.
81
- 2. Discover whether Computer Use/browser control and subagents are available.
82
- 3. Resolve modules and show the user canonical project/resource names.
83
- 4. Run the explicit CLI command, then read the generated `PRODUCTION.md`.
84
- 5. Provision only selected providers, pausing for sign-in, MFA, secret
147
+ 2. Audit and bootstrap the workstation, then discover whether Computer
148
+ Use/browser control and subagents are available.
149
+ 3. Resolve modules, required accounts, and canonical project/resource names.
150
+ 4. Run the explicit CLI command, then read the generated `PRODUCTION.md`,
151
+ `anhedral.json`, root scripts, and package-local environment examples.
152
+ 5. Provision only selected providers in dependency order, pausing for sign-in, MFA, secret
85
153
  generation, purchases, and final submissions exactly as the reference says.
86
154
  6. Keep secrets out of chat and tool output; have the user paste them directly
87
155
  into uncommitted environment files and protected provider fields.
@@ -92,8 +160,15 @@ The lead agent must:
92
160
  ```sh
93
161
  pnpm dlx anhedral@latest new my-product
94
162
  cd my-product
163
+ pnpm first-run
164
+ pnpm ready
95
165
  ```
96
166
 
167
+ `first-run` creates only missing package-local environment files and never
168
+ overwrites existing configuration. `ready` reports missing filenames and
169
+ required variable names without printing values; resolve every blocker before
170
+ starting affected services.
171
+
97
172
  Prefer explicit modules when the user requests a smaller stack:
98
173
 
99
174
  ```sh
@@ -131,7 +206,7 @@ Use the native source conventions:
131
206
  - Product client-safe HTTP methods belong in `packages/api-client/src/app.ts`.
132
207
  - Product Drizzle tables belong in `packages/db/src/app-schema.ts`; generate and review SQL migrations.
133
208
 
134
- Implement an end-to-end feature as `contracts -> database/service -> route -> API client -> frontend`. Frontends may import contracts and client-safe packages, never API services, database connections, or server environments. This stack uses managed Neon and intentionally has no local Postgres service.
209
+ Implement an end-to-end feature as `contracts -> database/service -> route -> API client -> frontend`. The generated `items` feature demonstrates that same path on every selected client—Next.js, Expo, Electron, and WXT—using one contract and API client with platform-native UI. Frontends may import contracts and client-safe packages, never API services, database connections, or server environments. This stack uses managed Neon and intentionally has no local Postgres service.
135
210
 
136
211
  ## Add modules safely
137
212
 
@@ -152,6 +227,13 @@ Require the manifest generator version to match the running CLI. Regenerate proj
152
227
 
153
228
  Do not rewrite a generated project's README or custom workflows while adding modules. Preserve custom package fields and mergeable root configuration.
154
229
 
230
+ `README.md` and `PRODUCTION.md` are user-owned and are not regenerated by
231
+ `anhedral add`. After adding modules, do not assume those two files describe the
232
+ new provider set. Reconcile them against `anhedral.json`, the managed project
233
+ `SKILL.md`, root `package.json` scripts, and every package-local `.env.example`;
234
+ then update the user-owned documentation explicitly with the developer's
235
+ approval.
236
+
155
237
  For manual projects without a trustworthy schema-v5 `anhedral.json`, add modules with the manual reference instead. Never fabricate manifest ownership records, template provenance, UI installation records, or hashes. A manually authored workspace is valid as an application workspace but is not CLI-managed until it has been regenerated by a matching Anhedral version.
156
238
 
157
239
  ## Add UI components
@@ -181,16 +263,20 @@ Explain that warnings can represent mergeable or user-owned drift, while modifie
181
263
 
182
264
  ## Configure the generated project
183
265
 
184
- Copy environment examples, fill only selected provider values, install, and verify:
266
+ Create only missing local environment files, fill selected provider values, and
267
+ verify readiness:
185
268
 
186
269
  ```sh
187
- cp apps/api/.env.example apps/api/.env
188
- cp packages/db/.env.example packages/db/.env
189
270
  pnpm install
271
+ pnpm first-run
272
+ pnpm ready
190
273
  pnpm verify
191
274
  ```
192
275
 
193
- Copy only examples that exist for the selected surfaces. Client packages use package-local runtime files (for example, copy `apps/web/.env.example` to `apps/web/.env.local` and `apps/desktop/.env.example` to `apps/desktop/.env`); the root `.env.example` is an inventory, not a runtime environment file.
276
+ `first-run` copies only examples that exist for selected surfaces and never
277
+ overwrites an existing file. Client packages use package-local runtime files
278
+ (for example, `apps/web/.env.local` and `apps/desktop/.env`); the root
279
+ `.env.example` is an inventory, not a runtime environment file.
194
280
 
195
281
  Common selected keys are:
196
282
 
@@ -218,6 +304,15 @@ Treat the root `vercel.json` as the only Vercel Services configuration. It uses
218
304
 
219
305
  For billing, keep Neon authoritative: RevenueCat reconciliation writes the subscription revision and realtime outbox atomically, Ably carries only per-user invalidations, and every client refetches the entitlement. Schedule the authenticated outbox flush every five minutes and verify purchase, webhook, reconnect, and foreground recovery paths.
220
306
 
307
+ The generated billing substrate does not implement Stripe Checkout, Stripe
308
+ webhooks, or a web purchase screen. RevenueCat's Test Store can exercise the
309
+ entitlement flow without Apple, Google, or Stripe accounts. Native purchases
310
+ require `native-subscriptions` plus Apple/Google store setup. If the user wants
311
+ web subscriptions through RevenueCat Billing or a manual Stripe integration,
312
+ treat that as an explicit product feature with additional account, checkout,
313
+ webhook, tax, and customer-portal work; do not claim the generated billing
314
+ module already completed it.
315
+
221
316
  Use `apps/mobile` for EAS, `pnpm desktop:build` for a current-host Electron artifact, matching platform-specific desktop scripts in CI, and `pnpm extension:zip` for the WXT archive.
222
317
 
223
318
  For `electron-updater`, provision the generated private R2 bucket and
@@ -227,7 +322,7 @@ platform and publish artifacts before mutable channel metadata.
227
322
 
228
323
  For storage, generate `apps/assets-private-proxy` plus `cloudflare/r2-cors.template.json` and keep the R2 bucket private. The Worker must be named `assets-private-proxy`, bind the normalized `<project>-assets` bucket as `ASSETS`, disable `workers.dev`, and own `assets.<domain>` as a Worker Custom Domain. Presigned uploads continue on the R2 S3 API hostname. Root every key below `R2_PREFIX=storage`; expose only `storage/confirmed/` through the Worker and reject staging plus `generation-inputs`. Authenticated private reads must verify upload ownership and return a presigned GET URL bounded by `R2_PROXY_READ_URL_TTL_SECONDS`.
229
324
 
230
- When explaining domains, distinguish DNS delegation from registrar transfer. A GoDaddy registration can use Cloudflare authoritative nameservers immediately; transferring registration/billing to Cloudflare Registrar is optional and subject to eligibility locks. Keep Vercel app/API A or CNAME records DNS-only in Cloudflare, while Worker Custom Domains stay Cloudflare-managed and proxied.
325
+ When explaining domains, distinguish DNS delegation from registrar transfer. A domain can use Cloudflare authoritative nameservers while remaining with its current registrar; transferring registration/billing to Cloudflare Registrar is optional and subject to eligibility locks. Keep Vercel app/API A or CNAME records DNS-only in Cloudflare, while Worker Custom Domains stay Cloudflare-managed and proxied.
231
326
 
232
327
  ## Verify outcomes
233
328
 
@@ -1,5 +1,5 @@
1
- export { DEFAULT_MODULE_DEFINITIONS, DEFAULT_MODULE_REGISTRY, MODULE_IDS, ModuleRegistryError, ModuleResolutionError, createModuleRegistry, isModuleId, resolveModules, } from './modules.js';
2
- export type { DependencyEdge, ModuleDefinition, ModuleId, ModuleKind, ModuleRegistry, ModuleRegistryErrorCode, ModuleResolution, ModuleResolutionErrorCode, } from './modules.js';
1
+ export { APP_MODULES, DEFAULT_MODULE_DEFINITIONS, DEFAULT_MODULE_REGISTRY, FEATURE_MODULES, MODULE_IDS, ModuleRegistryError, ModuleResolutionError, createModuleRegistry, isModuleId, resolveModules, } from './modules.js';
2
+ export type { AppModule, DependencyEdge, FeatureModule, ModuleDefinition, ModuleId, ModuleKind, ModuleRegistry, ModuleRegistryErrorCode, ModuleResolution, ModuleResolutionErrorCode, } from './modules.js';
3
3
  export { FILE_OWNERSHIP_CLASSES, PlanBuildError, buildGenerationPlan, hashContent, isFileOwnershipClass, isSha256, normalizePlanPath, writePolicyForOwnership, } from './plan.js';
4
4
  export type { BuildGenerationPlanInput, FileOwner, FileOwnershipClass, FileWritePolicy, GenerationOperation, GenerationPlan, ModulePlanContribution, PlanBuildErrorCode, PlanFileInput, PlannedFile, } from './plan.js';
5
5
  export { MANIFEST_SCHEMA_VERSION, ManifestValidationError, createManifest, readManifest, serializeManifest, } from './manifest.js';
@@ -1,4 +1,4 @@
1
- export { DEFAULT_MODULE_DEFINITIONS, DEFAULT_MODULE_REGISTRY, MODULE_IDS, ModuleRegistryError, ModuleResolutionError, createModuleRegistry, isModuleId, resolveModules, } from './modules.js';
1
+ export { APP_MODULES, DEFAULT_MODULE_DEFINITIONS, DEFAULT_MODULE_REGISTRY, FEATURE_MODULES, MODULE_IDS, ModuleRegistryError, ModuleResolutionError, createModuleRegistry, isModuleId, resolveModules, } from './modules.js';
2
2
  export { FILE_OWNERSHIP_CLASSES, PlanBuildError, buildGenerationPlan, hashContent, isFileOwnershipClass, isSha256, normalizePlanPath, writePolicyForOwnership, } from './plan.js';
3
3
  export { MANIFEST_SCHEMA_VERSION, ManifestValidationError, createManifest, readManifest, serializeManifest, } from './manifest.js';
4
4
  export { TEMPLATE_IDS, isTemplateId, templateIdsForModules, } from './templates.js';
@@ -1,4 +1,8 @@
1
+ export declare const APP_MODULES: readonly ["web", "mobile", "api", "desktop", "extension"];
2
+ export declare const FEATURE_MODULES: readonly ["db", "auth", "billing", "storage", "native-subscriptions", "electron-updater"];
1
3
  export declare const MODULE_IDS: readonly ["web", "mobile", "api", "desktop", "extension", "db", "auth", "billing", "storage", "native-subscriptions", "electron-updater"];
4
+ export type AppModule = (typeof APP_MODULES)[number];
5
+ export type FeatureModule = (typeof FEATURE_MODULES)[number];
2
6
  export type ModuleId = (typeof MODULE_IDS)[number];
3
7
  export type ModuleKind = 'app' | 'feature';
4
8
  export type ModuleDefinition = {
@@ -33,5 +37,5 @@ export declare class ModuleResolutionError extends Error {
33
37
  export declare function isModuleId(value: unknown): value is ModuleId;
34
38
  export declare function createModuleRegistry(definitions: readonly ModuleDefinition[]): ModuleRegistry;
35
39
  export declare const DEFAULT_MODULE_DEFINITIONS: readonly ModuleDefinition[];
36
- export declare const DEFAULT_MODULE_REGISTRY: Readonly<Record<"electron-updater" | "auth" | "billing" | "storage" | "api" | "desktop" | "web" | "mobile" | "extension" | "db" | "native-subscriptions", ModuleDefinition>>;
40
+ export declare const DEFAULT_MODULE_REGISTRY: Readonly<Record<"electron-updater" | "web" | "mobile" | "desktop" | "extension" | "auth" | "billing" | "storage" | "api" | "db" | "native-subscriptions", ModuleDefinition>>;
37
41
  export declare function resolveModules(requested: readonly string[], registry?: ModuleRegistry): ModuleResolution;
@@ -1,9 +1,11 @@
1
- export const MODULE_IDS = [
1
+ export const APP_MODULES = [
2
2
  'web',
3
3
  'mobile',
4
4
  'api',
5
5
  'desktop',
6
6
  'extension',
7
+ ];
8
+ export const FEATURE_MODULES = [
7
9
  'db',
8
10
  'auth',
9
11
  'billing',
@@ -11,6 +13,7 @@ export const MODULE_IDS = [
11
13
  'native-subscriptions',
12
14
  'electron-updater',
13
15
  ];
16
+ export const MODULE_IDS = [...APP_MODULES, ...FEATURE_MODULES];
14
17
  export class ModuleRegistryError extends Error {
15
18
  code;
16
19
  modules;