anhedral 0.1.5 → 0.1.7
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/README.md +98 -146
- package/dist/scaffold.js +145 -79
- package/dist/templates/backend.js +4 -222
- package/dist/templates/frontend.js +117 -411
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,74 +1,92 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Anhedral
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/anhedral)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+
[](https://www.npmjs.com/package/anhedral)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
One command to start a production-shaped Expo, Fastify, and Chrome extension application.
|
|
6
8
|
|
|
7
|
-
-
|
|
8
|
-
- `pnpm` available on your machine
|
|
9
|
+
Anhedral is an opinionated init CLI for teams that want one stable full-stack architecture instead of a menu of half-finished choices. It generates a single pnpm monorepo with an Expo app for web/iOS/Android, a Fastify API, a WXT Chrome extension, shared packages, and deployment-ready structure for Vercel, EAS, and the Chrome Web Store.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+

|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
## Quick Start
|
|
13
14
|
|
|
14
15
|
```sh
|
|
15
16
|
pnpm dlx anhedral@latest init
|
|
16
17
|
```
|
|
17
18
|
|
|
19
|
+
Or with npm:
|
|
20
|
+
|
|
18
21
|
```sh
|
|
19
22
|
npx anhedral@latest init
|
|
20
23
|
```
|
|
21
24
|
|
|
22
|
-
Use `--skip-install` when you want deterministic file generation
|
|
25
|
+
Use `--skip-install` when you want deterministic file generation before installing dependencies:
|
|
23
26
|
|
|
24
27
|
```sh
|
|
25
28
|
pnpm dlx anhedral@latest init --skip-install
|
|
26
29
|
pnpm install
|
|
27
30
|
```
|
|
28
31
|
|
|
29
|
-
|
|
32
|
+
## What It Generates
|
|
30
33
|
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
```txt
|
|
35
|
+
.
|
|
36
|
+
├─ Frontend/ Expo + React Native Reusables app
|
|
37
|
+
├─ Backend/ Fastify API
|
|
38
|
+
├─ Extension/ WXT Chrome extension
|
|
39
|
+
├─ packages/
|
|
40
|
+
│ ├─ api-client/ shared typed API client
|
|
41
|
+
│ ├─ config/ shared config helpers
|
|
42
|
+
│ ├─ db/ Drizzle schema, Neon client, migrations
|
|
43
|
+
│ └─ types/ shared TypeScript types
|
|
44
|
+
├─ PRODUCTION.md deployment checklist
|
|
45
|
+
├─ turbo.json workspace task graph
|
|
46
|
+
└─ package.json root scripts
|
|
34
47
|
```
|
|
35
48
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
49
|
+
The generated app is intentionally one repository. Deploy the same Git repo as two Vercel projects:
|
|
50
|
+
|
|
51
|
+
- `Frontend`: Expo web export, built with `pnpm build:web`, output to `dist`
|
|
52
|
+
- `Backend`: Fastify API, built with `pnpm build`, entrypoint at `src/index.ts`
|
|
53
|
+
|
|
54
|
+
The same `Frontend` source is used for native iOS and Android builds through EAS. The `Extension` source builds a WXT Chrome extension ZIP for the Chrome Web Store.
|
|
40
55
|
|
|
41
56
|
## Stack
|
|
42
57
|
|
|
43
|
-
|
|
58
|
+
Anhedral supports one carefully maintained stack:
|
|
44
59
|
|
|
45
60
|
- Expo + React Native Reusables frontend
|
|
46
61
|
- Fastify backend
|
|
47
|
-
- WXT extension
|
|
62
|
+
- WXT Chrome extension
|
|
48
63
|
- Neon + Drizzle
|
|
49
64
|
- Cloudflare R2/CDN
|
|
50
65
|
- Clerk auth
|
|
51
66
|
- RevenueCat + Stripe
|
|
52
|
-
- Vercel
|
|
53
|
-
|
|
54
|
-
The scaffold is a pnpm workspace with top-level `Frontend`, `Backend`, `Extension`, and `packages/*` folders. Shared code such as the Drizzle schema lives under `packages/db` so apps do not need separate database schemas.
|
|
55
|
-
|
|
56
|
-
Each scaffold writes a `stack.json` file with the selected architecture, generated outputs, and the verified dependency manifest used for that run.
|
|
67
|
+
- Vercel deployment
|
|
68
|
+
- pnpm workspaces + Turborepo
|
|
57
69
|
|
|
58
|
-
|
|
70
|
+
The goal is stability. The generated project avoids framework sprawl, duplicate schemas, and separate frontend/backend/extension repositories.
|
|
59
71
|
|
|
60
|
-
|
|
72
|
+
## Local Development
|
|
61
73
|
|
|
62
|
-
|
|
63
|
-
- `Backend`: Fastify API. Build command: `pnpm build`. Vercel detects `src/index.ts` as the Fastify entrypoint.
|
|
74
|
+
From the generated project root:
|
|
64
75
|
|
|
65
|
-
|
|
76
|
+
```sh
|
|
77
|
+
pnpm install
|
|
78
|
+
pnpm dev
|
|
79
|
+
```
|
|
66
80
|
|
|
67
|
-
|
|
81
|
+
Run one surface at a time:
|
|
68
82
|
|
|
69
|
-
|
|
83
|
+
```sh
|
|
84
|
+
pnpm dev:frontend
|
|
85
|
+
pnpm dev:backend
|
|
86
|
+
pnpm dev:extension
|
|
87
|
+
```
|
|
70
88
|
|
|
71
|
-
|
|
89
|
+
Verify before deployment:
|
|
72
90
|
|
|
73
91
|
```sh
|
|
74
92
|
pnpm verify
|
|
@@ -77,86 +95,71 @@ pnpm verify:backend
|
|
|
77
95
|
pnpm verify:extension
|
|
78
96
|
```
|
|
79
97
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
Use `Frontend` as the Expo project root for iOS and Android. Vercel only deploys the web export from this app; native builds go through EAS.
|
|
98
|
+
Database workflow:
|
|
83
99
|
|
|
84
100
|
```sh
|
|
85
|
-
|
|
86
|
-
pnpm
|
|
87
|
-
pnpm dlx eas-cli@latest init
|
|
101
|
+
pnpm db:generate
|
|
102
|
+
pnpm db:migrate
|
|
88
103
|
```
|
|
89
104
|
|
|
90
|
-
|
|
105
|
+
## Provider Setup
|
|
91
106
|
|
|
92
|
-
|
|
107
|
+
Generated projects include placeholder env values so the repository can be inspected before accounts are provisioned. Real auth, billing, uploads, native builds, and extension sign-in require provider keys.
|
|
93
108
|
|
|
94
|
-
|
|
95
|
-
# Android
|
|
96
|
-
pnpm dlx eas-cli@latest build --platform android --profile production
|
|
109
|
+
The generated `README.md` and `PRODUCTION.md` explain where every key belongs:
|
|
97
110
|
|
|
98
|
-
|
|
99
|
-
|
|
111
|
+
- Neon: `DATABASE_URL`
|
|
112
|
+
- Clerk: `EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY`, `CLERK_PUBLISHABLE_KEY`, `CLERK_SECRET_KEY`, `VITE_CLERK_PUBLISHABLE_KEY`
|
|
113
|
+
- RevenueCat + Stripe: `EXPO_PUBLIC_RC_*`, `RC_SECRET_API_KEY`, `RC_WEBHOOK_SECRET`
|
|
114
|
+
- Cloudflare R2/CDN: `R2_ACCOUNT_ID`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `R2_BUCKET`
|
|
115
|
+
- Vercel: two projects from the same Git repository, rooted at `Frontend` and `Backend`
|
|
116
|
+
- EAS: native iOS and Android builds from `Frontend`
|
|
117
|
+
- Chrome Web Store: WXT ZIP upload from `Extension/.output`
|
|
100
118
|
|
|
101
|
-
|
|
102
|
-
pnpm dlx eas-cli@latest build --platform all --profile production
|
|
103
|
-
```
|
|
119
|
+
## Deployment
|
|
104
120
|
|
|
105
|
-
|
|
121
|
+
### Vercel
|
|
106
122
|
|
|
107
|
-
|
|
108
|
-
# Google Play
|
|
109
|
-
pnpm dlx eas-cli@latest submit --platform android --latest --profile production
|
|
123
|
+
Import the same GitHub repository twice:
|
|
110
124
|
|
|
111
|
-
|
|
112
|
-
|
|
125
|
+
| Project | Root Directory | Build Command | Output |
|
|
126
|
+
| --- | --- | --- | --- |
|
|
127
|
+
| Frontend | `Frontend` | `pnpm build:web` | `dist` |
|
|
128
|
+
| Backend | `Backend` | `pnpm build` | Fastify entrypoint |
|
|
113
129
|
|
|
114
|
-
|
|
115
|
-
pnpm dlx eas-cli@latest submit --platform all --latest --profile production
|
|
116
|
-
```
|
|
130
|
+
Enable Vercel access to source files outside each project root so workspace packages under `packages/*` resolve during builds.
|
|
117
131
|
|
|
118
|
-
|
|
132
|
+
### EAS
|
|
133
|
+
|
|
134
|
+
Use `Frontend` as the Expo project root:
|
|
119
135
|
|
|
120
136
|
```sh
|
|
121
|
-
|
|
122
|
-
pnpm dlx eas-cli@latest
|
|
123
|
-
pnpm dlx eas-cli@latest
|
|
137
|
+
cd Frontend
|
|
138
|
+
pnpm dlx eas-cli@latest login
|
|
139
|
+
pnpm dlx eas-cli@latest init
|
|
140
|
+
pnpm dlx eas-cli@latest build --platform all --profile production
|
|
141
|
+
pnpm dlx eas-cli@latest submit --platform all --latest --profile production
|
|
124
142
|
```
|
|
125
143
|
|
|
126
|
-
|
|
144
|
+
### Chrome Extension
|
|
127
145
|
|
|
128
146
|
```sh
|
|
129
|
-
pnpm
|
|
130
|
-
pnpm dlx eas-cli@latest build:version:get --platform all --profile production
|
|
131
|
-
pnpm dlx eas-cli@latest credentials
|
|
147
|
+
pnpm extension:zip
|
|
132
148
|
```
|
|
133
149
|
|
|
134
|
-
|
|
150
|
+
Upload `Extension/.output/*-chrome.zip` to the Chrome Web Store Developer Dashboard.
|
|
135
151
|
|
|
136
|
-
|
|
152
|
+
## Dependency Policy
|
|
137
153
|
|
|
138
|
-
|
|
139
|
-
cd Extension
|
|
140
|
-
pnpm build
|
|
141
|
-
pnpm zip
|
|
142
|
-
```
|
|
154
|
+
`pnpm dlx anhedral@latest init` gives users the latest published Anhedral CLI, but generated projects use the dependency manifest verified for that release.
|
|
143
155
|
|
|
144
|
-
|
|
156
|
+
Runtime dependency versions live in `src/dependencies.ts`. Generated projects also receive a `stack.json` file recording the exact stack and dependency manifest used for that init run.
|
|
145
157
|
|
|
146
|
-
|
|
147
|
-
2. Create the item the first time, or open the existing extension item.
|
|
148
|
-
3. Upload the generated Chrome ZIP.
|
|
149
|
-
4. Complete or update the store listing, screenshots, privacy practices, permissions justification, and distribution settings.
|
|
150
|
-
5. Submit the item for review.
|
|
158
|
+
This keeps generated apps reproducible while still allowing Anhedral itself to move forward quickly through verified releases.
|
|
151
159
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
```sh
|
|
155
|
-
pnpm wxt submit init
|
|
156
|
-
pnpm wxt submit
|
|
157
|
-
```
|
|
160
|
+
## Development
|
|
158
161
|
|
|
159
|
-
|
|
162
|
+
Work on the CLI locally:
|
|
160
163
|
|
|
161
164
|
```sh
|
|
162
165
|
pnpm install
|
|
@@ -164,80 +167,29 @@ pnpm build
|
|
|
164
167
|
pnpm test:all
|
|
165
168
|
```
|
|
166
169
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
This package is published once to the npm registry. `pnpm`, `npm`, `yarn`, and `bun` users all install that same published package.
|
|
170
|
-
|
|
171
|
-
Official releases are automatic on merges to `main`. GitHub Actions bumps the patch version, runs the release checks once, creates a release commit and tag, and publishes that version to npm.
|
|
172
|
-
|
|
173
|
-
Recommended release flow:
|
|
170
|
+
Refresh the checked-in demo output:
|
|
174
171
|
|
|
175
172
|
```sh
|
|
176
|
-
|
|
173
|
+
pnpm demo:refresh
|
|
177
174
|
```
|
|
178
175
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
- `.github/workflows/release-on-main.yml`: runs on pushes to `main`, bumps `package.json`, verifies the repo, pushes a `v*.*.*` tag, and publishes to npm.
|
|
182
|
-
- `.github/workflows/release.yml`: manual retry workflow for publishing the current checked-out package version.
|
|
183
|
-
|
|
184
|
-
The repository is private, so npm provenance publishing is not supported. GitHub Actions publishes with `--provenance=false` and skips npm lifecycle scripts because `pnpm release:check` has already run. Configure an npm automation token as `NPM_TOKEN` in the `npm` GitHub environment or repository secrets.
|
|
185
|
-
|
|
186
|
-
Manual local publish is still available as an emergency fallback:
|
|
176
|
+
Validate upstream scaffold drift:
|
|
187
177
|
|
|
188
178
|
```sh
|
|
189
|
-
pnpm
|
|
190
|
-
npm publish --provenance=false --ignore-scripts
|
|
179
|
+
pnpm test:e2e:latest
|
|
191
180
|
```
|
|
192
181
|
|
|
193
|
-
##
|
|
182
|
+
## Release
|
|
194
183
|
|
|
195
|
-
|
|
184
|
+
Official releases are automatic on merges to `main`. The release workflow bumps the patch version, runs the release checks, creates a release commit and tag, and publishes to npm.
|
|
196
185
|
|
|
197
|
-
|
|
198
|
-
- `latest`: an early-warning lane that tracks upstream scaffold tools without pinning, so breakage is detected before it reaches the default path.
|
|
199
|
-
|
|
200
|
-
The practical rule is simple: users get the latest verified Anhedral release, not uncontrolled registry drift at init time. Detect drift on `latest`, verify it, then promote the pinned dependency manifest only after the e2e matrix passes.
|
|
201
|
-
|
|
202
|
-
### Dependency policy
|
|
203
|
-
|
|
204
|
-
- Runtime dependency versions for generated projects live in `src/dependencies.ts`.
|
|
205
|
-
- Generated package manifests and install commands must read from that manifest.
|
|
206
|
-
- Avoid raw `@latest` and caret ranges in generated output unless a package manager or platform command explicitly requires it.
|
|
207
|
-
- `pnpm dlx anhedral@latest init` means the newest published Anhedral CLI. The generated project should still be reproducible for that exact Anhedral version.
|
|
208
|
-
- `stack.json` records the dependency manifest so support and debugging can identify exactly what was generated.
|
|
209
|
-
|
|
210
|
-
### Recommended automation
|
|
211
|
-
|
|
212
|
-
- Renovate is configured in `renovate.json` to keep this repo's own dependencies and generated dependency manifest current.
|
|
213
|
-
- GitHub Actions CI runs on pushes and pull requests in `.github/workflows/ci.yml`.
|
|
214
|
-
- Weekly toolchain drift checks run in `.github/workflows/toolchain-drift.yml` for both `stable` and `latest`.
|
|
215
|
-
- Automatic releases publish through `.github/workflows/release-on-main.yml`; `.github/workflows/release.yml` is for manual retry only.
|
|
216
|
-
- Stable dependency pins in `src/dependencies.ts` are annotated so Renovate can open PRs when upstream packages and scaffold CLIs publish updates.
|
|
217
|
-
- `prepublishOnly` stays strict for manual local publishing. GitHub Actions skips npm lifecycle scripts during publish after running `pnpm release:check`.
|
|
218
|
-
|
|
219
|
-
### Upgrade workflow
|
|
220
|
-
|
|
221
|
-
Use this sequence when Renovate opens a dependency or toolchain PR:
|
|
186
|
+
Manual fallback:
|
|
222
187
|
|
|
223
188
|
```sh
|
|
224
|
-
pnpm
|
|
225
|
-
|
|
226
|
-
pnpm test:e2e
|
|
227
|
-
npm pack --dry-run
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
If you want to validate upstream scaffold drift manually, use the explicit latest-lane script:
|
|
231
|
-
|
|
232
|
-
```sh
|
|
233
|
-
pnpm test:e2e:latest
|
|
189
|
+
pnpm release:check
|
|
190
|
+
npm publish --provenance=false --ignore-scripts
|
|
234
191
|
```
|
|
235
192
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
### Release policy
|
|
193
|
+
## License
|
|
239
194
|
|
|
240
|
-
|
|
241
|
-
- Publish `minor` releases for new stacks, new flags, or new generated capabilities.
|
|
242
|
-
- Publish `major` releases for breaking CLI changes or incompatible generated-project structure changes.
|
|
243
|
-
- Never publish from a dirty worktree.
|
|
195
|
+
MIT
|