anhedral 0.1.1 → 0.1.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # anhedral
2
2
 
3
- Opinionated init CLI for product teams shipping with Next.js, Expo, Fastify, Drizzle, Neon, Clerk, Stripe, RevenueCat, and Cloudflare R2.
3
+ Opinionated init CLI for product teams shipping one stable stack: Expo + React Native Reusables, Fastify, WXT, Drizzle, Neon, Clerk, RevenueCat + Stripe, Cloudflare R2/CDN, and Vercel.
4
4
 
5
5
  ## Requirements
6
6
 
@@ -12,39 +12,139 @@ Opinionated init CLI for product teams shipping with Next.js, Expo, Fastify, Dri
12
12
  Run the latest published CLI directly without installing it globally:
13
13
 
14
14
  ```sh
15
- pnpm dlx anhedral@latest init next
16
- pnpm dlx anhedral@latest init next-fullstack
17
- pnpm dlx anhedral@latest init expo-fullstack
18
- pnpm dlx anhedral@latest init backend
15
+ pnpm dlx anhedral@latest init
19
16
  ```
20
17
 
21
18
  ```sh
22
- npx anhedral@latest init next
23
- npx anhedral@latest init next-fullstack
24
- npx anhedral@latest init expo-fullstack
25
- npx anhedral@latest init backend
19
+ npx anhedral@latest init
20
+ ```
21
+
22
+ Use `--skip-install` when you want deterministic file generation without running dependency installation during init:
23
+
24
+ ```sh
25
+ pnpm dlx anhedral@latest init --skip-install
26
+ pnpm install
26
27
  ```
27
28
 
28
29
  Global install also works:
29
30
 
30
31
  ```sh
31
32
  pnpm add -g anhedral@latest
32
- anhedral init next
33
+ anhedral init
33
34
  ```
34
35
 
35
36
  ```sh
36
37
  npm install -g anhedral@latest
37
- anhedral init next
38
+ anhedral init
39
+ ```
40
+
41
+ ## Stack
42
+
43
+ `init` generates the only supported stack:
44
+
45
+ - Expo + React Native Reusables frontend
46
+ - Fastify backend
47
+ - WXT extension
48
+ - Neon + Drizzle
49
+ - Cloudflare R2/CDN
50
+ - Clerk auth
51
+ - RevenueCat + Stripe
52
+ - Vercel deploy
53
+
54
+ The scaffold is a pnpm workspace with `apps/*` and `packages/*`. 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.
57
+
58
+ ## Vercel Deployment
59
+
60
+ The generated workspace is one Git repository with two Vercel projects:
61
+
62
+ - `apps/frontend`: Expo web build. Build command: `pnpm build:web`. Output directory: `dist`.
63
+ - `apps/api`: Fastify API. Build command: `pnpm build`. Requests rewrite to `api/index.ts`.
64
+
65
+ The `apps/frontend` source is also the EAS source for iOS and Android builds; Vercel only deploys its web export.
66
+
67
+ Import the same repository twice in Vercel and set each project Root Directory to the app path above. Enable source access outside the app root so `packages/*` workspace dependencies are available during builds.
68
+
69
+ Vercel deployments are Git-driven. After both projects are connected, pushes and pull requests deploy the Expo web app and Fastify API automatically from GitHub commits.
70
+
71
+ ## Native App Deployment
72
+
73
+ Use `apps/frontend` as the Expo project root for iOS and Android. Vercel only deploys the web export from this app; native builds go through EAS.
74
+
75
+ ```sh
76
+ cd apps/frontend
77
+ pnpm dlx eas-cli@latest login
78
+ pnpm dlx eas-cli@latest init
79
+ pnpm dlx eas-cli@latest build:configure
80
+ ```
81
+
82
+ Build commands:
83
+
84
+ ```sh
85
+ # Android
86
+ pnpm dlx eas-cli@latest build --platform android --profile production
87
+
88
+ # iOS
89
+ pnpm dlx eas-cli@latest build --platform ios --profile production
90
+
91
+ # Both platforms
92
+ pnpm dlx eas-cli@latest build --platform all --profile production
93
+ ```
94
+
95
+ Submit latest successful builds to the stores:
96
+
97
+ ```sh
98
+ # Google Play
99
+ pnpm dlx eas-cli@latest submit --platform android --latest --profile production
100
+
101
+ # App Store Connect / TestFlight
102
+ pnpm dlx eas-cli@latest submit --platform ios --latest --profile production
103
+
104
+ # Both platforms
105
+ pnpm dlx eas-cli@latest submit --platform all --latest --profile production
106
+ ```
107
+
108
+ One-step build and submit:
109
+
110
+ ```sh
111
+ pnpm dlx eas-cli@latest build --platform android --profile production --auto-submit
112
+ pnpm dlx eas-cli@latest build --platform ios --profile production --auto-submit
113
+ pnpm dlx eas-cli@latest build --platform all --profile production --auto-submit
114
+ ```
115
+
116
+ Useful release checks:
117
+
118
+ ```sh
119
+ pnpm dlx eas-cli@latest build:list
120
+ pnpm dlx eas-cli@latest build:version:get --platform all --profile production
121
+ pnpm dlx eas-cli@latest credentials
122
+ ```
123
+
124
+ ## Extension Release
125
+
126
+ The WXT extension is built from `apps/extension`. It is not deployed by Vercel.
127
+
128
+ ```sh
129
+ cd apps/extension
130
+ pnpm build
131
+ pnpm zip
38
132
  ```
39
133
 
40
- ## Stacks
134
+ The Chrome ZIP is generated under `.output/`. Upload that ZIP in the Chrome Web Store Developer Dashboard:
41
135
 
42
- - `next`: Next.js App Router for the fastest web-only SaaS path.
43
- - `next-fullstack`: Next.js frontend plus Fastify backend for clearer service boundaries.
44
- - `expo-fullstack`: Expo app plus Fastify backend for mobile-first or multi-client products.
45
- - `backend`: Fastify-only API foundation for headless products and integrations.
136
+ 1. Open the Chrome Web Store Developer Dashboard.
137
+ 2. Create the item the first time, or open the existing extension item.
138
+ 3. Upload the generated Chrome ZIP.
139
+ 4. Complete or update the store listing, screenshots, privacy practices, permissions justification, and distribution settings.
140
+ 5. Submit the item for review.
46
141
 
47
- Each scaffold writes a `stack.json` file with the selected architecture and generated outputs.
142
+ For automated store submissions later, WXT supports:
143
+
144
+ ```sh
145
+ pnpm wxt submit init
146
+ pnpm wxt submit
147
+ ```
48
148
 
49
149
  ## Local Development
50
150
 
@@ -58,43 +158,53 @@ pnpm test:all
58
158
 
59
159
  This package is published once to the npm registry. `pnpm`, `npm`, `yarn`, and `bun` users all install that same published package.
60
160
 
61
- Manual local publish still works:
161
+ 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.
162
+
163
+ Recommended release flow:
62
164
 
63
165
  ```sh
64
- pnpm build
65
- pnpm test:all
66
- npm publish
166
+ git push origin main
67
167
  ```
68
168
 
69
- GitHub Actions release automation is also configured in `.github/workflows/release.yml`.
169
+ Release publishing is handled by:
70
170
 
71
- Recommended release flow:
171
+ - `.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.
172
+ - `.github/workflows/release.yml`: manual retry workflow for publishing the current checked-out package version.
173
+
174
+ 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.
175
+
176
+ Manual local publish is still available as an emergency fallback:
72
177
 
73
178
  ```sh
74
179
  pnpm release:check
75
- npm version patch
76
- git push --follow-tags
180
+ npm publish --provenance=false --ignore-scripts
77
181
  ```
78
182
 
79
- The release workflow will publish on tags like `v0.1.1`. For npm trusted publishing, configure the package on npmjs.com to trust the `release.yml` workflow in `anhedral/anhedral-init`.
80
-
81
183
  ## Maintenance
82
184
 
83
- This repo is now maintained in two lanes:
185
+ This repo is maintained in two lanes:
84
186
 
85
- - `stable`: the default user-facing toolchain, pinned to known-good upstream CLI versions in `src/toolchain.ts`.
187
+ - `stable`: the default user-facing toolchain, pinned to known-good upstream CLI and package versions in `src/dependencies.ts`.
86
188
  - `latest`: an early-warning lane that tracks upstream scaffold tools without pinning, so breakage is detected before it reaches the default path.
87
189
 
88
- The practical rule is simple: detect drift on `latest`, verify it, then promote the pinned `stable` versions only after the e2e matrix passes.
190
+ 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.
191
+
192
+ ### Dependency policy
193
+
194
+ - Runtime dependency versions for generated projects live in `src/dependencies.ts`.
195
+ - Generated package manifests and install commands must read from that manifest.
196
+ - Avoid raw `@latest` and caret ranges in generated output unless a package manager or platform command explicitly requires it.
197
+ - `pnpm dlx anhedral@latest init` means the newest published Anhedral CLI. The generated project should still be reproducible for that exact Anhedral version.
198
+ - `stack.json` records the dependency manifest so support and debugging can identify exactly what was generated.
89
199
 
90
200
  ### Recommended automation
91
201
 
92
- - Renovate is configured in `renovate.json` to keep this repo's own dependencies current.
202
+ - Renovate is configured in `renovate.json` to keep this repo's own dependencies and generated dependency manifest current.
93
203
  - GitHub Actions CI runs on pushes and pull requests in `.github/workflows/ci.yml`.
94
204
  - Weekly toolchain drift checks run in `.github/workflows/toolchain-drift.yml` for both `stable` and `latest`.
95
- - Tagged releases publish through `.github/workflows/release.yml`.
96
- - Stable toolchain pins in `src/toolchain.ts` are annotated so Renovate can open PRs when upstream scaffold CLIs publish updates.
97
- - `prepublishOnly` stays strict. Every publish still runs `pnpm test:all`.
205
+ - Automatic releases publish through `.github/workflows/release-on-main.yml`; `.github/workflows/release.yml` is for manual retry only.
206
+ - Stable dependency pins in `src/dependencies.ts` are annotated so Renovate can open PRs when upstream packages and scaffold CLIs publish updates.
207
+ - `prepublishOnly` stays strict for manual local publishing. GitHub Actions skips npm lifecycle scripts during publish after running `pnpm release:check`.
98
208
 
99
209
  ### Upgrade workflow
100
210
 
@@ -113,7 +223,7 @@ If you want to validate upstream scaffold drift manually, use the explicit lates
113
223
  pnpm test:e2e:latest
114
224
  ```
115
225
 
116
- When a toolchain pin PR passes and the generated outputs look good, update the `verifiedAt` date in `src/toolchain.ts` and release normally.
226
+ When a dependency pin PR passes and the generated outputs look good, update the `VERIFIED_AT` date in `src/dependencies.ts` and release normally.
117
227
 
118
228
  ### Release policy
119
229
 
package/dist/cli.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { InitOptions } from './scaffold.js';
2
+ export declare const USAGE = "\nanhedral init [--toolchain <latest|stable>] [--skip-install]\n\nCommands:\n anhedral init\n Expo + React Native Reusables, Fastify, WXT extension, Neon + Drizzle, Cloudflare R2/CDN, Clerk, RevenueCat + Stripe, Vercel\n";
3
+ export type ParsedFlags = {
4
+ toolchain?: string;
5
+ skipInstall?: boolean;
6
+ };
7
+ export declare function parseCli(args: string[]): ParsedFlags;
8
+ export declare function deriveProjectName(cwd: string): string;
9
+ export declare function deriveDisplayName(cwd: string): string;
10
+ export declare function buildOptions(flags: ParsedFlags): InitOptions;
package/dist/cli.js ADDED
@@ -0,0 +1,67 @@
1
+ import path from 'node:path';
2
+ import { env } from 'node:process';
3
+ import { TOOLCHAIN_CHANNELS, resolveToolchainChannel } from './toolchain.js';
4
+ export const USAGE = `
5
+ anhedral init [--toolchain <latest|stable>] [--skip-install]
6
+
7
+ Commands:
8
+ anhedral init
9
+ Expo + React Native Reusables, Fastify, WXT extension, Neon + Drizzle, Cloudflare R2/CDN, Clerk, RevenueCat + Stripe, Vercel
10
+ `;
11
+ export function parseCli(args) {
12
+ const flags = {};
13
+ for (let index = 0; index < args.length; index += 1) {
14
+ const token = args[index];
15
+ if (!token.startsWith('--')) {
16
+ throw new Error(`Unexpected argument: ${token}. Use flags: --toolchain, --skip-install`);
17
+ }
18
+ if (token === '--skip-install') {
19
+ flags.skipInstall = true;
20
+ continue;
21
+ }
22
+ if (token === '--toolchain') {
23
+ const value = args[index + 1];
24
+ if (!value || value.startsWith('--')) {
25
+ throw new Error('Missing value for --toolchain');
26
+ }
27
+ flags.toolchain = value;
28
+ index += 1;
29
+ continue;
30
+ }
31
+ throw new Error(`Unknown flag: ${token}`);
32
+ }
33
+ return flags;
34
+ }
35
+ export function deriveProjectName(cwd) {
36
+ const base = path.basename(cwd);
37
+ const sanitized = base
38
+ .trim()
39
+ .toLowerCase()
40
+ .replace(/[^a-z0-9_-]+/g, '-')
41
+ .replace(/^-+|-+$/g, '');
42
+ return sanitized || 'anhedral-app';
43
+ }
44
+ export function deriveDisplayName(cwd) {
45
+ const base = path.basename(cwd).trim();
46
+ return base || 'Anhedral App';
47
+ }
48
+ export function buildOptions(flags) {
49
+ const cwd = process.cwd();
50
+ const projectName = deriveProjectName(cwd);
51
+ const displayName = deriveDisplayName(cwd);
52
+ if (flags.toolchain != null && !TOOLCHAIN_CHANNELS.includes(flags.toolchain)) {
53
+ throw new Error(`--toolchain must be one of: ${TOOLCHAIN_CHANNELS.join(', ')}`);
54
+ }
55
+ return {
56
+ projectName,
57
+ displayName,
58
+ auth: 'clerk',
59
+ payments: 'revenuecat_stripe',
60
+ db: 'neon',
61
+ orm: 'drizzle',
62
+ storage: 'r2',
63
+ api: 'fastify',
64
+ skipInstall: flags.skipInstall === true || env.ANHEDRAL_SKIP_INSTALL === '1',
65
+ toolchainChannel: resolveToolchainChannel(flags.toolchain ?? env.ANHEDRAL_TOOLCHAIN),
66
+ };
67
+ }
@@ -1,12 +1,7 @@
1
- import type { InitMode } from './scaffold.js';
2
- import { type ToolchainSpec } from './toolchain.js';
3
1
  export type ScaffoldCommand = {
4
2
  cmd: string;
5
- stdinInput?: string;
6
- skippable?: boolean;
3
+ command: string;
4
+ args: string[];
7
5
  };
8
- export declare function getDefaultWebInitCommand(toolchain: ToolchainSpec, projectName: string): ScaffoldCommand;
9
- export declare function getDefaultWebDependencyCommands(): ScaffoldCommand[];
10
- export declare function getHeadlessInstallCommands(): ScaffoldCommand[];
11
6
  export declare function getBackendInstallCommands(): ScaffoldCommand[];
12
- export declare function getSkillCommands(mode: InitMode): string[];
7
+ export declare function getSkillCommands(): string[];
package/dist/commands.js CHANGED
@@ -1,74 +1,24 @@
1
- import { toolPackageRef } from './toolchain.js';
2
- const TYPESCRIPT_VERSION = '5.9.3';
3
- const NODE_TYPES_VERSION = '25.5.0';
4
- export function getDefaultWebInitCommand(toolchain, projectName) {
5
- return {
6
- cmd: [
7
- 'pnpm',
8
- 'dlx',
9
- toolPackageRef('shadcn', toolchain.shadcn),
10
- 'init',
11
- '-t',
12
- 'next',
13
- '-n',
14
- projectName,
15
- '-d',
16
- '-y',
17
- '--css-variables',
18
- ].join(' '),
19
- };
20
- }
21
- export function getDefaultWebDependencyCommands() {
22
- return [
23
- {
24
- cmd: 'pnpm add @clerk/nextjs drizzle-orm @neondatabase/serverless stripe @aws-sdk/client-s3 @aws-sdk/lib-storage @aws-sdk/s3-request-presigner',
25
- skippable: true,
26
- },
27
- {
28
- cmd: 'pnpm add -D babel-plugin-react-compiler drizzle-kit tsx dotenv',
29
- skippable: true,
30
- },
31
- ];
32
- }
33
- export function getHeadlessInstallCommands() {
1
+ import { BACKEND_DEPENDENCIES, withVersions } from './dependencies.js';
2
+ export function getBackendInstallCommands() {
3
+ const dependencies = withVersions(BACKEND_DEPENDENCIES.dependencies ?? {});
4
+ const devDependencies = withVersions(BACKEND_DEPENDENCIES.devDependencies ?? {});
34
5
  return [
35
6
  {
36
- cmd: 'pnpm add fastify @fastify/cors better-auth drizzle-orm @neondatabase/serverless @aws-sdk/client-s3 @aws-sdk/lib-storage @aws-sdk/s3-request-presigner dotenv',
37
- skippable: true,
7
+ cmd: `pnpm add ${dependencies.join(' ')}`,
8
+ command: 'pnpm',
9
+ args: ['add', ...dependencies],
38
10
  },
39
11
  {
40
- cmd: `pnpm add -D typescript@${TYPESCRIPT_VERSION} tsx @types/node@${NODE_TYPES_VERSION} drizzle-kit`,
41
- skippable: true,
12
+ cmd: `pnpm add -D ${devDependencies.join(' ')}`,
13
+ command: 'pnpm',
14
+ args: ['add', '-D', ...devDependencies],
42
15
  },
43
16
  ];
44
17
  }
45
- export function getBackendInstallCommands() {
18
+ export function getSkillCommands() {
46
19
  return [
47
- {
48
- cmd: 'pnpm add fastify fastify-plugin @fastify/cors @fastify/env @fastify/compress @fastify/helmet @fastify/rate-limit @fastify/swagger @fastify/swagger-ui @fastify/multipart @clerk/fastify @neondatabase/serverless drizzle-orm @aws-sdk/client-s3 @aws-sdk/lib-storage @aws-sdk/s3-request-presigner dotenv',
49
- },
50
- {
51
- cmd: 'pnpm add -D typescript@5.9.3 tsx @types/node@25.5.0 drizzle-kit vitest @vitest/coverage-v8 @vercel/node eslint@9.39.4 @eslint/js@9.39.4 globals typescript-eslint pino-pretty',
52
- },
20
+ 'pnpm dlx skills add https://github.com/clerk/skills --skill clerk-custom-ui',
21
+ 'pnpm dlx skills add https://github.com/revenuecat/revenuecat-skill --skill revenuecat',
22
+ 'pnpm dlx skills add https://github.com/stripe/ai --skill stripe-best-practices',
53
23
  ];
54
24
  }
55
- export function getSkillCommands(mode) {
56
- switch (mode) {
57
- case 'next':
58
- case 'next-fullstack':
59
- return [
60
- 'pnpm dlx skills add https://github.com/clerk/skills --skill clerk-custom-ui',
61
- 'pnpm dlx skills add https://github.com/stripe/ai --skill stripe-best-practices',
62
- ];
63
- case 'expo-fullstack':
64
- return [
65
- 'pnpm dlx skills add https://github.com/clerk/skills --skill clerk-custom-ui',
66
- 'pnpm dlx skills add https://github.com/revenuecat/revenuecat-skill --skill revenuecat',
67
- 'pnpm dlx skills add https://github.com/stripe/ai --skill stripe-best-practices',
68
- ];
69
- case 'backend':
70
- return [
71
- 'pnpm dlx skills add https://github.com/better-auth/skills --skill better-auth-best-practices',
72
- ];
73
- }
74
- }
@@ -0,0 +1,35 @@
1
+ export declare const PACKAGE_MANAGER = "pnpm@10.15.1";
2
+ export type DependencyMap = Record<string, string>;
3
+ export type DependencyGroup = {
4
+ dependencies?: DependencyMap;
5
+ devDependencies?: DependencyMap;
6
+ };
7
+ export declare const VERIFIED_AT = "2026-04-26";
8
+ export declare const TOOLCHAIN_DEPENDENCIES: {
9
+ readonly shadcn: "4.5.0";
10
+ readonly reactNativeReusables: "0.7.1";
11
+ readonly wxt: "0.20.25";
12
+ };
13
+ export declare const ROOT_DEPENDENCIES: DependencyGroup;
14
+ export declare const SHARED_DB_DEPENDENCIES: DependencyGroup;
15
+ export declare const SHARED_PACKAGE_DEPENDENCIES: DependencyGroup;
16
+ export declare const API_CLIENT_DEPENDENCIES: DependencyGroup;
17
+ export declare const BACKEND_DEPENDENCIES: DependencyGroup;
18
+ export declare const EXTENSION_DEPENDENCIES: DependencyGroup;
19
+ export declare const FRONTEND_ADDON_DEPENDENCIES: DependencyMap;
20
+ export declare function withVersions(dependencies: DependencyMap): string[];
21
+ export declare function dependencyManifest(): {
22
+ verifiedAt: string;
23
+ packageManager: string;
24
+ toolchain: {
25
+ readonly shadcn: "4.5.0";
26
+ readonly reactNativeReusables: "0.7.1";
27
+ readonly wxt: "0.20.25";
28
+ };
29
+ root: DependencyGroup;
30
+ sharedDb: DependencyGroup;
31
+ sharedPackages: DependencyGroup;
32
+ backend: DependencyGroup;
33
+ extension: DependencyGroup;
34
+ frontendAddons: DependencyMap;
35
+ };
@@ -0,0 +1,175 @@
1
+ export const PACKAGE_MANAGER = 'pnpm@10.15.1';
2
+ export const VERIFIED_AT = '2026-04-26';
3
+ export const TOOLCHAIN_DEPENDENCIES = {
4
+ // renovate: datasource=npm depName=shadcn
5
+ shadcn: '4.5.0',
6
+ // renovate: datasource=npm depName=@react-native-reusables/cli
7
+ reactNativeReusables: '0.7.1',
8
+ // renovate: datasource=npm depName=wxt
9
+ wxt: '0.20.25',
10
+ };
11
+ export const ROOT_DEPENDENCIES = {
12
+ devDependencies: {
13
+ // renovate: datasource=npm depName=turbo
14
+ turbo: '2.8.0',
15
+ },
16
+ };
17
+ export const SHARED_DB_DEPENDENCIES = {
18
+ dependencies: {
19
+ // renovate: datasource=npm depName=@neondatabase/serverless
20
+ '@neondatabase/serverless': '1.0.2',
21
+ // renovate: datasource=npm depName=drizzle-orm
22
+ 'drizzle-orm': '0.44.7',
23
+ // renovate: datasource=npm depName=dotenv
24
+ dotenv: '17.2.3',
25
+ },
26
+ devDependencies: {
27
+ // renovate: datasource=npm depName=drizzle-kit
28
+ 'drizzle-kit': '0.31.7',
29
+ // renovate: datasource=npm depName=tsx
30
+ tsx: '4.20.6',
31
+ // renovate: datasource=npm depName=typescript
32
+ typescript: '5.9.3',
33
+ // renovate: datasource=npm depName=@types/node
34
+ '@types/node': '25.6.0',
35
+ },
36
+ };
37
+ export const SHARED_PACKAGE_DEPENDENCIES = {
38
+ devDependencies: {
39
+ // renovate: datasource=npm depName=typescript
40
+ typescript: '5.9.3',
41
+ },
42
+ };
43
+ export const API_CLIENT_DEPENDENCIES = {
44
+ dependencies: {
45
+ '@anhedral/config': 'workspace:*',
46
+ '@anhedral/types': 'workspace:*',
47
+ },
48
+ ...SHARED_PACKAGE_DEPENDENCIES,
49
+ };
50
+ export const BACKEND_DEPENDENCIES = {
51
+ dependencies: {
52
+ '@anhedral/db': 'workspace:*',
53
+ // renovate: datasource=npm depName=fastify
54
+ fastify: '5.6.2',
55
+ // renovate: datasource=npm depName=fastify-plugin
56
+ 'fastify-plugin': '5.1.0',
57
+ // renovate: datasource=npm depName=@fastify/cors
58
+ '@fastify/cors': '11.1.0',
59
+ // renovate: datasource=npm depName=@fastify/env
60
+ '@fastify/env': '5.0.3',
61
+ // renovate: datasource=npm depName=@fastify/compress
62
+ '@fastify/compress': '8.3.0',
63
+ // renovate: datasource=npm depName=@fastify/helmet
64
+ '@fastify/helmet': '13.0.2',
65
+ // renovate: datasource=npm depName=@fastify/rate-limit
66
+ '@fastify/rate-limit': '10.3.0',
67
+ // renovate: datasource=npm depName=@fastify/swagger
68
+ '@fastify/swagger': '9.6.1',
69
+ // renovate: datasource=npm depName=@fastify/swagger-ui
70
+ '@fastify/swagger-ui': '5.2.3',
71
+ // renovate: datasource=npm depName=@fastify/multipart
72
+ '@fastify/multipart': '9.3.0',
73
+ // renovate: datasource=npm depName=@clerk/fastify
74
+ '@clerk/fastify': '3.1.26',
75
+ '@neondatabase/serverless': SHARED_DB_DEPENDENCIES.dependencies['@neondatabase/serverless'],
76
+ 'drizzle-orm': SHARED_DB_DEPENDENCIES.dependencies['drizzle-orm'],
77
+ // renovate: datasource=npm depName=@aws-sdk/client-s3
78
+ '@aws-sdk/client-s3': '3.1047.0',
79
+ // renovate: datasource=npm depName=@aws-sdk/lib-storage
80
+ '@aws-sdk/lib-storage': '3.1047.0',
81
+ // renovate: datasource=npm depName=@aws-sdk/s3-request-presigner
82
+ '@aws-sdk/s3-request-presigner': '3.1047.0',
83
+ dotenv: SHARED_DB_DEPENDENCIES.dependencies.dotenv,
84
+ },
85
+ devDependencies: {
86
+ typescript: SHARED_DB_DEPENDENCIES.devDependencies.typescript,
87
+ tsx: SHARED_DB_DEPENDENCIES.devDependencies.tsx,
88
+ '@types/node': SHARED_DB_DEPENDENCIES.devDependencies['@types/node'],
89
+ 'drizzle-kit': SHARED_DB_DEPENDENCIES.devDependencies['drizzle-kit'],
90
+ // renovate: datasource=npm depName=vitest
91
+ vitest: '4.0.16',
92
+ // renovate: datasource=npm depName=@vitest/coverage-v8
93
+ '@vitest/coverage-v8': '4.0.16',
94
+ // renovate: datasource=npm depName=@vercel/node
95
+ '@vercel/node': '5.5.13',
96
+ // renovate: datasource=npm depName=eslint
97
+ eslint: '9.39.2',
98
+ // renovate: datasource=npm depName=@eslint/js
99
+ '@eslint/js': '9.39.2',
100
+ // renovate: datasource=npm depName=globals
101
+ globals: '16.5.0',
102
+ // renovate: datasource=npm depName=typescript-eslint
103
+ 'typescript-eslint': '8.49.0',
104
+ // renovate: datasource=npm depName=pino-pretty
105
+ 'pino-pretty': '13.1.3',
106
+ },
107
+ };
108
+ export const EXTENSION_DEPENDENCIES = {
109
+ dependencies: {
110
+ '@anhedral/api-client': 'workspace:*',
111
+ // renovate: datasource=npm depName=@clerk/chrome-extension
112
+ '@clerk/chrome-extension': '3.1.25',
113
+ // renovate: datasource=npm depName=react
114
+ react: '19.2.3',
115
+ // renovate: datasource=npm depName=react-dom
116
+ 'react-dom': '19.2.3',
117
+ // renovate: datasource=npm depName=clsx
118
+ clsx: '2.1.1',
119
+ // renovate: datasource=npm depName=tailwind-merge
120
+ 'tailwind-merge': '3.4.0',
121
+ // renovate: datasource=npm depName=class-variance-authority
122
+ 'class-variance-authority': '0.7.1',
123
+ // renovate: datasource=npm depName=lucide-react
124
+ 'lucide-react': '0.562.0',
125
+ },
126
+ devDependencies: {
127
+ // renovate: datasource=npm depName=@types/chrome
128
+ '@types/chrome': '0.1.9',
129
+ // renovate: datasource=npm depName=@types/react
130
+ '@types/react': '19.2.7',
131
+ // renovate: datasource=npm depName=@types/react-dom
132
+ '@types/react-dom': '19.2.3',
133
+ // renovate: datasource=npm depName=@wxt-dev/module-react
134
+ '@wxt-dev/module-react': '1.1.5',
135
+ // renovate: datasource=npm depName=autoprefixer
136
+ autoprefixer: '10.4.23',
137
+ // renovate: datasource=npm depName=postcss
138
+ postcss: '8.5.6',
139
+ // renovate: datasource=npm depName=tailwindcss
140
+ tailwindcss: '3.4.19',
141
+ typescript: SHARED_DB_DEPENDENCIES.devDependencies.typescript,
142
+ wxt: TOOLCHAIN_DEPENDENCIES.wxt,
143
+ },
144
+ };
145
+ export const FRONTEND_ADDON_DEPENDENCIES = {
146
+ '@anhedral/api-client': 'workspace:*',
147
+ // renovate: datasource=npm depName=@clerk/clerk-expo
148
+ '@clerk/clerk-expo': '2.19.31',
149
+ // renovate: datasource=npm depName=react-native-purchases
150
+ 'react-native-purchases': '10.1.1',
151
+ // renovate: datasource=npm depName=react-native-purchases-ui
152
+ 'react-native-purchases-ui': '10.1.1',
153
+ // renovate: datasource=npm depName=@revenuecat/purchases-js
154
+ '@revenuecat/purchases-js': '1.11.1',
155
+ };
156
+ export function withVersions(dependencies) {
157
+ return Object.entries(dependencies).map(([name, version]) => {
158
+ if (version === 'workspace:*')
159
+ return `${name}@workspace:*`;
160
+ return `${name}@${version}`;
161
+ });
162
+ }
163
+ export function dependencyManifest() {
164
+ return {
165
+ verifiedAt: VERIFIED_AT,
166
+ packageManager: PACKAGE_MANAGER,
167
+ toolchain: TOOLCHAIN_DEPENDENCIES,
168
+ root: ROOT_DEPENDENCIES,
169
+ sharedDb: SHARED_DB_DEPENDENCIES,
170
+ sharedPackages: SHARED_PACKAGE_DEPENDENCIES,
171
+ backend: BACKEND_DEPENDENCIES,
172
+ extension: EXTENSION_DEPENDENCIES,
173
+ frontendAddons: FRONTEND_ADDON_DEPENDENCIES,
174
+ };
175
+ }