anhedral 0.8.6 → 0.9.0

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 (125) hide show
  1. package/README.md +141 -38
  2. package/assets/anhedral-cli-init-technical.svg +15 -15
  3. package/assets/anhedral-cli-init.svg +16 -16
  4. package/dist/access.d.ts +10 -0
  5. package/dist/access.js +93 -0
  6. package/dist/auth-schema-snapshot.d.ts +346 -0
  7. package/dist/auth-schema-snapshot.js +347 -0
  8. package/dist/auth-schema.d.ts +1 -0
  9. package/dist/auth-schema.js +57 -0
  10. package/dist/bin.js +345 -39
  11. package/dist/bounded-file.d.ts +2 -0
  12. package/dist/bounded-file.js +30 -0
  13. package/dist/capabilities.d.ts +24 -42
  14. package/dist/capabilities.js +73 -75
  15. package/dist/cloudflare.d.ts +14 -0
  16. package/dist/cloudflare.js +66 -0
  17. package/dist/command.js +12 -3
  18. package/dist/delivery.d.ts +118 -0
  19. package/dist/delivery.js +611 -0
  20. package/dist/dependencies.d.ts +24 -3
  21. package/dist/dependencies.js +112 -74
  22. package/dist/dependency-order.d.ts +2 -0
  23. package/dist/dependency-order.js +24 -0
  24. package/dist/index.d.ts +18 -3
  25. package/dist/index.js +12 -2
  26. package/dist/managed-hosting.d.ts +49 -0
  27. package/dist/managed-hosting.js +373 -0
  28. package/dist/management.d.ts +3 -0
  29. package/dist/management.js +47 -0
  30. package/dist/platforms/desktop.d.ts +2 -2
  31. package/dist/platforms/desktop.js +25 -15
  32. package/dist/platforms/extension.d.ts +2 -2
  33. package/dist/platforms/extension.js +104 -66
  34. package/dist/platforms/mobile.d.ts +2 -2
  35. package/dist/platforms/mobile.js +13 -7
  36. package/dist/pnpm-policy.d.ts +0 -2
  37. package/dist/pnpm-policy.js +18 -13
  38. package/dist/project-state.d.ts +28 -0
  39. package/dist/project-state.js +226 -0
  40. package/dist/provider-readiness.d.ts +30 -0
  41. package/dist/provider-readiness.js +87 -0
  42. package/dist/provision.d.ts +46 -0
  43. package/dist/provision.js +197 -0
  44. package/dist/readiness.d.ts +4 -2
  45. package/dist/readiness.js +81 -14
  46. package/dist/registry/add.d.ts +22 -0
  47. package/dist/registry/add.js +198 -0
  48. package/dist/registry/bootstrap.d.ts +2 -0
  49. package/dist/registry/bootstrap.js +14 -0
  50. package/dist/registry/commands.d.ts +2 -0
  51. package/dist/registry/commands.js +99 -0
  52. package/dist/registry/context.d.ts +3 -0
  53. package/dist/registry/context.js +21 -0
  54. package/dist/registry/options.d.ts +2 -0
  55. package/dist/registry/options.js +65 -0
  56. package/dist/registry/receipt.d.ts +3 -0
  57. package/dist/registry/receipt.js +73 -0
  58. package/dist/registry/remote.d.ts +25 -0
  59. package/dist/registry/remote.js +168 -0
  60. package/dist/registry/resolve.d.ts +10 -0
  61. package/dist/registry/resolve.js +98 -0
  62. package/dist/registry/types.d.ts +64 -0
  63. package/dist/registry/usage.d.ts +1 -0
  64. package/dist/registry/usage.js +38 -0
  65. package/dist/render.d.ts +0 -4
  66. package/dist/render.js +3 -16
  67. package/dist/repository.d.ts +24 -0
  68. package/dist/repository.js +96 -0
  69. package/dist/scaffold/api.d.ts +2 -0
  70. package/dist/scaffold/api.js +13 -0
  71. package/dist/scaffold/auth.d.ts +3 -0
  72. package/dist/scaffold/auth.js +95 -0
  73. package/dist/scaffold/bootstrap.d.ts +2 -0
  74. package/dist/scaffold/bootstrap.js +34 -0
  75. package/dist/scaffold/compose.d.ts +4 -0
  76. package/dist/scaffold/compose.js +34 -0
  77. package/dist/scaffold/database.d.ts +2 -0
  78. package/dist/scaffold/database.js +43 -0
  79. package/dist/scaffold/documentation.d.ts +3 -0
  80. package/dist/scaffold/documentation.js +91 -0
  81. package/dist/scaffold/environment.d.ts +2 -0
  82. package/dist/scaffold/environment.js +5 -0
  83. package/dist/scaffold/files.d.ts +25 -0
  84. package/dist/scaffold/files.js +108 -0
  85. package/dist/scaffold/integrations.d.ts +3 -0
  86. package/dist/scaffold/integrations.js +7 -0
  87. package/dist/scaffold/services.d.ts +5 -0
  88. package/dist/scaffold/services.js +84 -0
  89. package/dist/scaffold/web.d.ts +2 -0
  90. package/dist/scaffold/web.js +102 -0
  91. package/dist/scaffold/workspace.d.ts +3 -0
  92. package/dist/scaffold/workspace.js +150 -0
  93. package/dist/security-backports.js +7 -2
  94. package/dist/stack-registry.d.ts +80 -0
  95. package/dist/stack-registry.js +424 -0
  96. package/dist/standard.d.ts +6 -19
  97. package/dist/standard.js +46 -653
  98. package/dist/transaction.js +47 -56
  99. package/dist/util.js +12 -2
  100. package/dist/vercel.d.ts +98 -0
  101. package/dist/vercel.js +796 -0
  102. package/dist/version.d.ts +1 -1
  103. package/dist/version.js +1 -1
  104. package/dist/vinext.d.ts +1 -0
  105. package/dist/vinext.js +83 -0
  106. package/dist/workspace-graph.d.ts +7 -0
  107. package/dist/workspace-graph.js +73 -0
  108. package/docs/application-stack-standard.md +76 -91
  109. package/docs/delivery-workflow.md +83 -0
  110. package/docs/managed-hosting-architecture.md +87 -0
  111. package/docs/sponsorships.md +25 -0
  112. package/package.json +23 -29
  113. package/dist/evidence-validation.d.ts +0 -2
  114. package/dist/evidence-validation.js +0 -18
  115. package/dist/foundation.d.ts +0 -6
  116. package/dist/foundation.js +0 -49
  117. package/dist/progress-view.d.ts +0 -57
  118. package/dist/progress-view.js +0 -69
  119. package/dist/progress.d.ts +0 -95
  120. package/dist/progress.js +0 -327
  121. package/dist/project.d.ts +0 -5
  122. package/dist/standard-products.d.ts +0 -2
  123. package/dist/standard-products.js +0 -6
  124. /package/assets/{images/svg/logo-white-subtract.svg → anhedral-mark.svg} +0 -0
  125. /package/dist/{project.js → registry/types.js} +0 -0
@@ -0,0 +1,102 @@
1
+ import { STACK_DEPENDENCIES } from '../dependencies.js';
2
+ import { existsSync, readFileSync, readdirSync, rmSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { configureVinext } from '../vinext.js';
5
+ import { json, put, readJson, patchPackage, workerConfig } from './files.js';
6
+ function cleanWorkspaceManifest(root, directory) {
7
+ const manifestPath = `${directory}/package.json`;
8
+ if (!existsSync(path.join(root, manifestPath)))
9
+ return;
10
+ const manifest = readJson(root, manifestPath);
11
+ const sources = [];
12
+ const collect = (folder) => {
13
+ for (const entry of readdirSync(folder, { withFileTypes: true })) {
14
+ if (['node_modules', '.next', '.open-next', '.git'].includes(entry.name))
15
+ continue;
16
+ const file = path.join(folder, entry.name);
17
+ if (entry.isDirectory())
18
+ collect(file);
19
+ else if (/\.(tsx?|m?js|css)$/.test(entry.name))
20
+ sources.push(readFileSync(file, 'utf8'));
21
+ }
22
+ };
23
+ collect(path.join(root, directory));
24
+ for (const name of ['lucide-react', 'zod', 'next-themes']) {
25
+ if (!sources.some((source) => source.includes(`"${name}`) || source.includes(`'${name}`)))
26
+ delete manifest.dependencies?.[name];
27
+ }
28
+ if (directory === 'packages/ui') {
29
+ if (!sources.some((source) => source.includes('@turbo/gen')) &&
30
+ !Object.values(manifest.scripts ?? {}).some((script) => String(script).includes('turbo gen')))
31
+ delete manifest.devDependencies?.['@turbo/gen'];
32
+ manifest.devDependencies = {
33
+ ...manifest.devDependencies,
34
+ 'postcss-load-config': STACK_DEPENDENCIES['postcss-load-config'],
35
+ };
36
+ if (manifest.dependencies?.shadcn) {
37
+ manifest.devDependencies.shadcn = manifest.dependencies.shadcn;
38
+ delete manifest.dependencies.shadcn;
39
+ }
40
+ }
41
+ json(root, manifestPath, manifest);
42
+ }
43
+ function cleanShadcnStarter(root) {
44
+ for (const directory of ['apps/web', 'packages/ui'])
45
+ cleanWorkspaceManifest(root, directory);
46
+ const themePath = 'apps/web/components/theme-provider.tsx';
47
+ if (existsSync(path.join(root, themePath))) {
48
+ const source = readFileSync(path.join(root, themePath), 'utf8');
49
+ // Preserve the upstream keyboard behavior while reducing branching in its guards.
50
+ put(root, themePath, source
51
+ .replace(/target.tagName === "INPUT" \|\|\s*target.tagName === "TEXTAREA" \|\|\s*target.tagName === "SELECT"/, '["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName)')
52
+ .replace(/if \(event.defaultPrevented \|\| event.repeat\) \{\s*return\s*\}\s*if \(event.metaKey \|\| event.ctrlKey \|\| event.altKey\) \{\s*return\s*\}\s*if \(event.key.toLowerCase\(\) !== "d"\) \{\s*return\s*\}\s*if \(isTypingTarget\(event.target\)\) \{\s*return\s*\}/, 'if ([event.defaultPrevented, event.repeat, event.metaKey, event.ctrlKey, event.altKey, event.key.toLowerCase() !== "d", isTypingTarget(event.target)].some(Boolean)) { return }'));
53
+ }
54
+ }
55
+ export function scaffoldWeb({ root, options, bindings, runtimeApp, has }) {
56
+ cleanShadcnStarter(root);
57
+ put(root, 'apps/web/eslint.config.js', 'import { nextJsConfig } from "@workspace/eslint-config/next-js";\nexport default [...nextJsConfig, { ignores: [".open-next/**", ".wrangler/**", "cloudflare-env.d.ts"] }];\n');
58
+ patchPackage(root, 'apps/web/package.json', {
59
+ scripts: { typecheck: 'tsc --noEmit', lint: 'eslint . --max-warnings 0' },
60
+ });
61
+ if (has('vinext')) {
62
+ configureVinext(root, `${options.name}-web`, runtimeApp === 'web' ? bindings : {});
63
+ }
64
+ else if (options.hosting === 'cloudflare') {
65
+ patchPackage(root, 'apps/web/package.json', {
66
+ dependencies: {
67
+ '@opennextjs/cloudflare': STACK_DEPENDENCIES['@opennextjs/cloudflare'],
68
+ next: '16.3.8',
69
+ },
70
+ devDependencies: { wrangler: STACK_DEPENDENCIES['wrangler'] },
71
+ scripts: {
72
+ preview: 'opennextjs-cloudflare build && opennextjs-cloudflare preview',
73
+ deploy: 'opennextjs-cloudflare build && opennextjs-cloudflare deploy',
74
+ 'build:worker': 'opennextjs-cloudflare build',
75
+ 'cf:typegen': 'wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts',
76
+ },
77
+ });
78
+ json(root, 'apps/web/wrangler.jsonc', {
79
+ ...workerConfig(`${options.name}-web`),
80
+ compatibility_flags: ['nodejs_compat', 'global_fetch_strictly_public'],
81
+ main: '.open-next/worker.js',
82
+ assets: { directory: '.open-next/assets', binding: 'ASSETS' },
83
+ services: [{ binding: 'WORKER_SELF_REFERENCE', service: `${options.name}-web` }],
84
+ ...(runtimeApp === 'web' ? bindings : {}),
85
+ });
86
+ const nextConfig = ['next.config.ts', 'next.config.mjs', 'next.config.js'].find((file) => existsSync(path.join(root, 'apps/web', file)));
87
+ if (nextConfig) {
88
+ const source = readFileSync(path.join(root, 'apps/web', nextConfig), 'utf8');
89
+ put(root, `apps/web/${nextConfig}`, `import { initOpenNextCloudflareForDev } from '@opennextjs/cloudflare';\n${source}\ninitOpenNextCloudflareForDev();\n`);
90
+ }
91
+ put(root, 'apps/web/open-next.config.ts', 'import { defineCloudflareConfig } from "@opennextjs/cloudflare";\nexport default defineCloudflareConfig();\n');
92
+ put(root, 'apps/web/public/_headers', '/_next/static/*\n Cache-Control: public,max-age=31536000,immutable\n');
93
+ put(root, 'apps/web/.dev.vars.example', 'NEXTJS_ENV=development\n');
94
+ }
95
+ else {
96
+ patchPackage(root, 'apps/web/package.json', { dependencies: { next: '16.4.0' } });
97
+ put(root, 'apps/web/next.config.ts', 'import type { NextConfig } from "next";\nconst config: NextConfig = { transpilePackages: ["@workspace/ui"], cacheComponents: true, partialPrefetching: true };\nexport default config;\n');
98
+ for (const file of ['next.config.js', 'next.config.mjs'])
99
+ rmSync(path.join(root, 'apps/web', file), { force: true });
100
+ json(root, 'apps/web/vercel.json', { framework: 'nextjs' });
101
+ }
102
+ }
@@ -0,0 +1,3 @@
1
+ import type { ResolvedStackRegistry } from '../registry/resolve.js';
2
+ import type { StandardOptions } from '../registry/types.js';
3
+ export declare function writeStandardRoot(root: string, options: StandardOptions, registry: ResolvedStackRegistry, updating?: boolean): void;
@@ -0,0 +1,150 @@
1
+ import { STACK_DEPENDENCIES } from '../dependencies.js';
2
+ import { setPnpmPolicy } from '../pnpm-policy.js';
3
+ import { writeSecurityBackports } from '../security-backports.js';
4
+ import { BOOTSTRAP_COMMAND } from '../registry/bootstrap.js';
5
+ import { appendGitignore } from '../util.js';
6
+ import { PACKAGE_MANAGER } from '../dependencies.js';
7
+ import { createSetupPlan } from '../capabilities.js';
8
+ import { json, put, readJson, patchPackage, } from './files.js';
9
+ import { writeSetupDocumentation, workerBuildSuffix } from './documentation.js';
10
+ import { writeEnvironmentExample } from './environment.js';
11
+ export function writeStandardRoot(root, options, registry, updating = false) {
12
+ const has = (value) => options.products.includes(value);
13
+ const existing = readJson(root, 'package.json');
14
+ const securityOverrides = {
15
+ ...(has('wxt') ? { '@wxt-dev/module-react>@vitejs/plugin-react': '5.2.0' } : {}),
16
+ ...(has('next') || has('vinext') ? { 'sharp@<0.35.5': '0.35.5' } : {}),
17
+ 'source-map-js@<1.2.2': '1.2.2',
18
+ ...(has('next') && options.hosting === 'cloudflare'
19
+ ? { 'glob@>=10.2.0 <10.5.0': '10.5.0', 'glob@>=11.0.0 <11.1.0': '11.1.0' }
20
+ : {}),
21
+ ...(has('wxt')
22
+ ? { 'shell-quote@<1.12.0': '1.12.0', 'tmp@<0.2.7': '0.2.7', 'adm-zip@<0.6.1': '0.6.1' }
23
+ : {}),
24
+ 'baseline-browser-mapping@<2.11.0': '2.11.27',
25
+ 'browserslist@<4.28.7': '4.29.3',
26
+ ...(((has('next') || has('vinext')) && options.hosting === 'cloudflare') ||
27
+ has('hono') ||
28
+ has('electron') ||
29
+ has('wxt')
30
+ ? { 'esbuild@<0.25.0': '0.25.12' }
31
+ : {}),
32
+ 'brace-expansion@<2': '1.1.21',
33
+ 'brace-expansion@>=2 <3': '2.1.7',
34
+ 'brace-expansion@>=3 <4': '3.0.9',
35
+ 'brace-expansion@>=4 <5.0.12': '5.0.12',
36
+ };
37
+ patchPackage(root, 'package.json', {
38
+ name: options.name,
39
+ private: true,
40
+ packageManager: PACKAGE_MANAGER,
41
+ engines: { node: '>=22.13.0' },
42
+ scripts: {
43
+ dev: 'turbo dev',
44
+ build: 'turbo build',
45
+ ...((has('next') || has('vinext')) && options.hosting === 'cloudflare'
46
+ ? { 'build:worker': 'pnpm --dir apps/web run build:worker' }
47
+ : {}),
48
+ lint: 'turbo lint',
49
+ typecheck: 'turbo typecheck',
50
+ test: 'turbo test',
51
+ audit: 'node scripts/audit.mjs',
52
+ 'audit:full': 'fallow --fail-on-issues',
53
+ 'audit:deps': 'node scripts/security/audit-deps.mjs',
54
+ check: `pnpm lint && pnpm typecheck && pnpm run audit && pnpm audit:deps && pnpm test && pnpm build${workerBuildSuffix(options)}`,
55
+ },
56
+ devDependencies: { fallow: STACK_DEPENDENCIES['fallow'] },
57
+ // Upstream starter lockfiles can retain vulnerable transitive versions. Keep fixes within compatible majors.
58
+ pnpm: { ...existing.pnpm, overrides: { ...existing.pnpm?.overrides, ...securityOverrides } },
59
+ });
60
+ put(root, 'scripts/audit.mjs', `import { spawnSync } from 'node:child_process';
61
+ const base = process.env.AUDIT_BASE;
62
+ const hasBase = base || ['origin/main', 'main'].find((ref) => spawnSync('git', ['rev-parse', '--verify', ref], { stdio: 'ignore' }).status === 0);
63
+ const args = hasBase ? ['exec', 'fallow', 'audit', '--base', hasBase] : ['exec', 'fallow', '--fail-on-issues'];
64
+ const entry = process.env.npm_execpath;
65
+ if (!entry) throw new Error('Run this check through pnpm run audit.');
66
+ const result = spawnSync(process.execPath, [entry, ...args], { stdio: 'inherit', shell: false });
67
+ if (result.error) throw result.error;
68
+ process.exitCode = result.status ?? 1;
69
+ `);
70
+ json(root, '.fallowrc.json', {
71
+ ...(has('electron') ? { entry: ['apps/desktop/src/main/preload.cts'] } : {}),
72
+ // Expo web export and NativeWind load these runtime dependencies dynamically.
73
+ ...(has('expo')
74
+ ? {
75
+ ignoreDependencies: [
76
+ 'react-native-web',
77
+ 'react-native-css-interop',
78
+ 'react-native-reanimated',
79
+ 'react-native-worklets',
80
+ ],
81
+ }
82
+ : {}),
83
+ ignorePatterns: [
84
+ '**/next-env.d.ts',
85
+ '**/.next/**',
86
+ '**/.open-next/**',
87
+ '**/.wrangler/**',
88
+ '**/dist/**',
89
+ '**/worker-configuration.d.ts',
90
+ '**/cloudflare-env.d.ts',
91
+ ],
92
+ });
93
+ const turbo = readJson(root, 'turbo.json');
94
+ turbo.globalEnv = [...new Set(registry.items.flatMap((item) => item.environment))].sort();
95
+ turbo.tasks = {
96
+ ...turbo.tasks,
97
+ dev: { ...turbo.tasks.dev, cache: false, persistent: true },
98
+ lint: { ...turbo.tasks.lint, dependsOn: ['^lint'] },
99
+ typecheck: { ...turbo.tasks.typecheck, dependsOn: ['^typecheck'] },
100
+ test: { dependsOn: ['^build'], outputs: ['coverage/**'] },
101
+ build: {
102
+ ...turbo.tasks.build,
103
+ dependsOn: [...new Set(['^build', ...(turbo.tasks.build?.dependsOn ?? [])])],
104
+ outputs: ['.next/**', '!.next/cache/**', '.open-next/**', 'dist/**', '.output/**'],
105
+ },
106
+ };
107
+ json(root, 'turbo.json', turbo);
108
+ setPnpmPolicy(root, {
109
+ allowBuilds: undefined,
110
+ onlyBuiltDependencies: [
111
+ 'esbuild',
112
+ 'sharp',
113
+ 'unrs-resolver',
114
+ 'workerd',
115
+ ...(has('electron') ? ['electron'] : []),
116
+ ],
117
+ });
118
+ writeSecurityBackports(root);
119
+ appendGitignore(root, [
120
+ 'node_modules/',
121
+ '.open-next/',
122
+ '.wrangler/',
123
+ '.dev.vars',
124
+ '.dev.vars.*',
125
+ '!.dev.vars.example',
126
+ '.env',
127
+ '.env.*',
128
+ '!.env.example',
129
+ '.fallow/',
130
+ '.anhedral/',
131
+ ]);
132
+ writeEnvironmentExample(root, registry);
133
+ json(root, 'anhedral.standard.json', {
134
+ schemaVersion: 1,
135
+ standard: 'anhedral-application-stack',
136
+ products: options.products,
137
+ hosting: has('next') || has('vinext') ? options.hosting : null,
138
+ bootstrap: updating
139
+ ? readJson(root, 'anhedral.standard.json').bootstrap
140
+ : {
141
+ command: BOOTSTRAP_COMMAND.join(' '),
142
+ upstreamPackageManager: existing.packageManager,
143
+ },
144
+ status: 'starter',
145
+ resourcesProvisioned: false,
146
+ });
147
+ json(root, 'anhedral.setup.json', createSetupPlan({ ...options, dryRun: false }, registry));
148
+ if (!updating)
149
+ writeSetupDocumentation(root, options);
150
+ }
@@ -16,6 +16,11 @@ export function configureSecurityBackports(root) {
16
16
  });
17
17
  if (!entries.length)
18
18
  return false;
19
- mergePnpmPatches(root, Object.fromEntries(entries.map(({ name, version, patch }) => [`${name}@${version}`, `scripts/security/${patch}`])));
20
- return true;
19
+ const workspaceFile = path.join(root, 'pnpm-workspace.yaml');
20
+ const before = readFileSync(workspaceFile, 'utf8');
21
+ mergePnpmPatches(root, Object.fromEntries(entries.map(({ name, version, patch }) => [
22
+ `${name}@${version}`,
23
+ `scripts/security/${patch}`,
24
+ ])));
25
+ return readFileSync(workspaceFile, 'utf8') !== before;
21
26
  }
@@ -0,0 +1,80 @@
1
+ import type { ItemDefinition, StackRegistryItem, RecipeContext } from './registry/types.js';
2
+ /** Every product owns its source recipe, setup requirements and composition policy here. */
3
+ declare const PRODUCT_ITEMS: {
4
+ vinext: ItemDefinition;
5
+ next: ItemDefinition;
6
+ expo: ItemDefinition;
7
+ electron: ItemDefinition;
8
+ wxt: ItemDefinition;
9
+ hono: ItemDefinition;
10
+ neon: ItemDefinition;
11
+ d1: ItemDefinition;
12
+ 'local-data': ItemDefinition;
13
+ clerk: ItemDefinition;
14
+ 'better-auth': ItemDefinition;
15
+ r2: ItemDefinition;
16
+ kv: ItemDefinition;
17
+ realtime: ItemDefinition;
18
+ queues: ItemDefinition;
19
+ cron: ItemDefinition;
20
+ workflows: ItemDefinition;
21
+ openai: ItemDefinition;
22
+ 'ai-sdk': ItemDefinition;
23
+ 'workers-ai': ItemDefinition;
24
+ resend: ItemDefinition;
25
+ stripe: ItemDefinition;
26
+ revenuecat: ItemDefinition;
27
+ sentry: ItemDefinition;
28
+ basin: ItemDefinition;
29
+ posthog: ItemDefinition;
30
+ styling: ItemDefinition;
31
+ };
32
+ export type StandardProduct = keyof typeof PRODUCT_ITEMS;
33
+ export declare const STANDARD_PRODUCTS: readonly ("realtime" | "electron" | "wxt" | "expo" | "next" | "vinext" | "hono" | "neon" | "better-auth" | "queues" | "workflows" | "d1" | "local-data" | "clerk" | "r2" | "kv" | "cron" | "openai" | "ai-sdk" | "workers-ai" | "resend" | "stripe" | "revenuecat" | "sentry" | "basin" | "posthog" | "styling")[];
34
+ declare const DEFINITIONS: {
35
+ vinext: ItemDefinition;
36
+ next: ItemDefinition;
37
+ expo: ItemDefinition;
38
+ electron: ItemDefinition;
39
+ wxt: ItemDefinition;
40
+ hono: ItemDefinition;
41
+ neon: ItemDefinition;
42
+ d1: ItemDefinition;
43
+ 'local-data': ItemDefinition;
44
+ clerk: ItemDefinition;
45
+ 'better-auth': ItemDefinition;
46
+ r2: ItemDefinition;
47
+ kv: ItemDefinition;
48
+ realtime: ItemDefinition;
49
+ queues: ItemDefinition;
50
+ cron: ItemDefinition;
51
+ workflows: ItemDefinition;
52
+ openai: ItemDefinition;
53
+ 'ai-sdk': ItemDefinition;
54
+ 'workers-ai': ItemDefinition;
55
+ resend: ItemDefinition;
56
+ stripe: ItemDefinition;
57
+ revenuecat: ItemDefinition;
58
+ sentry: ItemDefinition;
59
+ basin: ItemDefinition;
60
+ posthog: ItemDefinition;
61
+ styling: ItemDefinition;
62
+ workspace: ItemDefinition;
63
+ typescript: ItemDefinition;
64
+ eslint: ItemDefinition;
65
+ ui: ItemDefinition;
66
+ };
67
+ export type StackItemId = keyof typeof DEFINITIONS;
68
+ export declare function getStackDefinition(name: string): ItemDefinition;
69
+ export declare function getStackItem(name: string): StackRegistryItem;
70
+ export declare const STACK_ITEMS: Record<"realtime" | "electron" | "eslint" | "typescript" | "wxt" | "expo" | "next" | "vinext" | "hono" | "neon" | "better-auth" | "queues" | "workflows" | "workspace" | "ui" | "d1" | "local-data" | "clerk" | "r2" | "kv" | "cron" | "openai" | "ai-sdk" | "workers-ai" | "resend" | "stripe" | "revenuecat" | "sentry" | "basin" | "posthog" | "styling", StackRegistryItem>;
71
+ export declare const STACK_REGISTRY: {
72
+ schemaVersion: number;
73
+ name: string;
74
+ cliVersion: string;
75
+ items: StackRegistryItem[];
76
+ };
77
+ export declare function installStackItem(item: StackRegistryItem, context: RecipeContext): void | Promise<void>;
78
+ /** Validate authored definitions during build, before shipping either catalog. */
79
+ export declare function validateStackCatalog(): void;
80
+ export {};