create-ai-mvp 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +67 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +251 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/core/create-next-app.d.ts +9 -0
  7. package/dist/core/create-next-app.d.ts.map +1 -0
  8. package/dist/core/create-next-app.js +26 -0
  9. package/dist/core/create-next-app.js.map +1 -0
  10. package/dist/core/files.d.ts +9 -0
  11. package/dist/core/files.d.ts.map +1 -0
  12. package/dist/core/files.js +57 -0
  13. package/dist/core/files.js.map +1 -0
  14. package/dist/core/package-manager.d.ts +23 -0
  15. package/dist/core/package-manager.d.ts.map +1 -0
  16. package/dist/core/package-manager.js +89 -0
  17. package/dist/core/package-manager.js.map +1 -0
  18. package/dist/core/runner.d.ts +7 -0
  19. package/dist/core/runner.d.ts.map +1 -0
  20. package/dist/core/runner.js +17 -0
  21. package/dist/core/runner.js.map +1 -0
  22. package/dist/index.d.ts +8 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +93 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/integrations/agents.d.ts +8 -0
  27. package/dist/integrations/agents.d.ts.map +1 -0
  28. package/dist/integrations/agents.js +15 -0
  29. package/dist/integrations/agents.js.map +1 -0
  30. package/dist/integrations/ai-sdk.d.ts +12 -0
  31. package/dist/integrations/ai-sdk.d.ts.map +1 -0
  32. package/dist/integrations/ai-sdk.js +23 -0
  33. package/dist/integrations/ai-sdk.js.map +1 -0
  34. package/dist/integrations/shadcn.d.ts +11 -0
  35. package/dist/integrations/shadcn.d.ts.map +1 -0
  36. package/dist/integrations/shadcn.js +26 -0
  37. package/dist/integrations/shadcn.js.map +1 -0
  38. package/dist/templates/agents.d.ts +4 -0
  39. package/dist/templates/agents.d.ts.map +1 -0
  40. package/dist/templates/agents.js +47 -0
  41. package/dist/templates/agents.js.map +1 -0
  42. package/dist/templates/ai.d.ts +9 -0
  43. package/dist/templates/ai.d.ts.map +1 -0
  44. package/dist/templates/ai.js +77 -0
  45. package/dist/templates/ai.js.map +1 -0
  46. package/dist/types.d.ts +22 -0
  47. package/dist/types.d.ts.map +1 -0
  48. package/dist/types.js +4 -0
  49. package/dist/types.js.map +1 -0
  50. package/package.json +46 -0
package/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # create-ai-mvp
2
+
3
+ Create a Next.js AI SaaS MVP in minutes.
4
+
5
+ ## Requirements
6
+
7
+ - Node.js >= 20
8
+ - Internet access for `npx` and package installation
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ npm install
14
+ npm run build
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```bash
20
+ node dist/cli.js <project-name>
21
+ ```
22
+
23
+ ### Options
24
+
25
+ - `--pm <npm|pnpm|yarn|bun>`
26
+ - `--yes`
27
+ - `--with-shadcn`
28
+ - `--without-shadcn`
29
+ - `--agents <cursor,codex,claude,antigravity>`
30
+ - `--with-ai`
31
+ - `--without-ai`
32
+ - `--providers <openai,anthropic,google>`
33
+
34
+ ## Examples
35
+
36
+ ```bash
37
+ # Default prompts
38
+ node dist/cli.js my-app
39
+
40
+ # Fully non-interactive defaults
41
+ node dist/cli.js my-app --yes
42
+
43
+ # AI SDK with OpenAI + Anthropic
44
+ node dist/cli.js my-app --yes --with-ai --providers openai,anthropic
45
+
46
+ # Skip shadcn and AI
47
+ node dist/cli.js my-app --yes --without-shadcn --without-ai
48
+ ```
49
+
50
+ ## Included in v0.1
51
+
52
+ - Next.js project generation via `create-next-app@latest` with `--yes`
53
+ - Optional `shadcn/ui` install (`button`, `input`, `card`)
54
+ - Optional AI agent files:
55
+ - `.cursorrules`
56
+ - `CODEX.md`
57
+ - `CLAUDE.md`
58
+ - `.antigravity.md`
59
+ - Optional AI SDK integration:
60
+ - `lib/ai.ts`
61
+ - `.env.local.example`
62
+
63
+ ## Out of Scope for v0.1
64
+
65
+ - Skills integration
66
+ - Supabase setup
67
+ - GitHub repo provisioning
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,251 @@
1
+ #!/usr/bin/env node
2
+ import { basename, resolve } from "node:path";
3
+ import { checkbox, confirm } from "@inquirer/prompts";
4
+ import chalk from "chalk";
5
+ import { Command } from "commander";
6
+ import { createNextApp } from "./core/create-next-app.js";
7
+ import { getDevCommand, isPackageManager } from "./core/package-manager.js";
8
+ import { resolvePackageManager } from "./index.js";
9
+ import { setupAgents } from "./integrations/agents.js";
10
+ import { setupAI } from "./integrations/ai-sdk.js";
11
+ import { installShadcn } from "./integrations/shadcn.js";
12
+ import { AGENTS, AI_PROVIDERS, PACKAGE_MANAGERS } from "./types.js";
13
+ function parseCsv(input) {
14
+ if (!input)
15
+ return [];
16
+ return input
17
+ .split(",")
18
+ .map((item) => item.trim())
19
+ .filter((item) => item.length > 0);
20
+ }
21
+ function uniqueValues(values) {
22
+ return Array.from(new Set(values));
23
+ }
24
+ function validateValues(values, allowed, label) {
25
+ const unknown = values.filter((value) => !allowed.includes(value));
26
+ if (unknown.length > 0) {
27
+ throw new Error(`Invalid ${label}: ${unknown.join(", ")}. Allowed values: ${allowed.join(", ")}`);
28
+ }
29
+ return values;
30
+ }
31
+ function printSummary(results) {
32
+ console.log(chalk.bold("\nSummary"));
33
+ for (const step of results) {
34
+ const prefix = step.status === "completed"
35
+ ? chalk.green("[DONE]")
36
+ : step.status === "skipped"
37
+ ? chalk.yellow("[SKIP]")
38
+ : chalk.red("[FAIL]");
39
+ const detail = step.detail ? ` - ${step.detail}` : "";
40
+ console.log(`${prefix} ${step.name}${detail}`);
41
+ }
42
+ }
43
+ async function resolveWithShadcn(options) {
44
+ if (options.withShadcn && options.withoutShadcn) {
45
+ throw new Error("Cannot use --with-shadcn and --without-shadcn together.");
46
+ }
47
+ if (options.withShadcn)
48
+ return true;
49
+ if (options.withoutShadcn)
50
+ return false;
51
+ if (options.yes)
52
+ return true;
53
+ return confirm({
54
+ message: "Install shadcn/ui?",
55
+ default: true
56
+ });
57
+ }
58
+ async function resolveAgents(options) {
59
+ if (options.agents) {
60
+ const selected = validateValues(uniqueValues(parseCsv(options.agents)), AGENTS, "agents");
61
+ return selected;
62
+ }
63
+ if (options.yes)
64
+ return ["codex"];
65
+ const selected = await checkbox({
66
+ message: "Select AI coding agents",
67
+ choices: AGENTS.map((agent) => ({
68
+ name: agent,
69
+ value: agent,
70
+ checked: agent === "codex"
71
+ }))
72
+ });
73
+ return selected;
74
+ }
75
+ async function resolveWithAI(options) {
76
+ if (options.withAi && options.withoutAi) {
77
+ throw new Error("Cannot use --with-ai and --without-ai together.");
78
+ }
79
+ if (options.providers && options.withoutAi) {
80
+ throw new Error("Cannot use --providers with --without-ai.");
81
+ }
82
+ if (options.withAi || options.providers)
83
+ return true;
84
+ if (options.withoutAi)
85
+ return false;
86
+ if (options.yes)
87
+ return false;
88
+ return confirm({
89
+ message: "Add LLM integration?",
90
+ default: false
91
+ });
92
+ }
93
+ async function resolveProviders(options, withAI) {
94
+ if (!withAI)
95
+ return [];
96
+ if (options.providers) {
97
+ const selected = validateValues(uniqueValues(parseCsv(options.providers)), AI_PROVIDERS, "providers");
98
+ if (selected.length === 0) {
99
+ throw new Error("At least one provider is required when --with-ai is enabled.");
100
+ }
101
+ return selected;
102
+ }
103
+ if (options.yes)
104
+ return ["openai"];
105
+ const selected = await checkbox({
106
+ message: "Select LLM providers",
107
+ choices: AI_PROVIDERS.map((provider) => ({
108
+ name: provider,
109
+ value: provider,
110
+ checked: provider === "openai"
111
+ })),
112
+ validate: (values) => values.length > 0 ? true : "Select at least one provider when AI integration is enabled."
113
+ });
114
+ return selected;
115
+ }
116
+ async function main() {
117
+ const program = new Command();
118
+ program
119
+ .name("create-ai-mvp")
120
+ .description("Generate a Next.js AI SaaS MVP quickly")
121
+ .argument("<project-name>", "project directory name")
122
+ .option("--pm <pm>", "package manager (npm|pnpm|yarn|bun)")
123
+ .option("--yes", "accept defaults and skip prompts")
124
+ .option("--with-shadcn", "install shadcn/ui")
125
+ .option("--without-shadcn", "skip shadcn/ui")
126
+ .option("--agents <agents>", "comma-separated agents: cursor,codex,claude,antigravity")
127
+ .option("--with-ai", "enable AI SDK integration")
128
+ .option("--without-ai", "skip AI SDK integration")
129
+ .option("--providers <providers>", "comma-separated providers: openai,anthropic,google")
130
+ .showHelpAfterError("(add --help for usage)")
131
+ .parse(process.argv);
132
+ const cliOptions = program.opts();
133
+ const projectName = program.args[0];
134
+ if (!projectName || projectName.trim().length === 0) {
135
+ throw new Error("Project name is required.");
136
+ }
137
+ let overridePm;
138
+ if (cliOptions.pm) {
139
+ if (!isPackageManager(cliOptions.pm)) {
140
+ throw new Error(`Invalid --pm value: ${cliOptions.pm}. Allowed values: ${PACKAGE_MANAGERS.join(", ")}`);
141
+ }
142
+ overridePm = cliOptions.pm;
143
+ }
144
+ const detectedPm = await resolvePackageManager(overridePm, process.cwd());
145
+ const projectPath = resolve(process.cwd(), projectName);
146
+ const results = [];
147
+ console.log(chalk.bold(`\ncreate-ai-mvp`));
148
+ console.log(`project: ${projectName}`);
149
+ console.log(`package manager: ${detectedPm.packageManager} (${detectedPm.source})`);
150
+ try {
151
+ console.log(chalk.cyan(`\n[1/4] Creating Next.js project (${projectName})`));
152
+ await createNextApp({
153
+ projectName,
154
+ packageManager: detectedPm.packageManager,
155
+ cwd: process.cwd()
156
+ });
157
+ results.push({ name: "Next.js project", status: "completed" });
158
+ }
159
+ catch (error) {
160
+ const detail = error instanceof Error ? error.message : String(error);
161
+ results.push({ name: "Next.js project", status: "failed", detail });
162
+ printSummary(results);
163
+ throw new Error(detail);
164
+ }
165
+ const withShadcn = await resolveWithShadcn(cliOptions);
166
+ console.log(`shadcn: ${withShadcn ? "enabled" : "disabled"}`);
167
+ if (withShadcn) {
168
+ try {
169
+ console.log(chalk.cyan(`[2/4] Installing shadcn/ui`));
170
+ const shadcnResult = await installShadcn({
171
+ projectPath,
172
+ packageManager: detectedPm.packageManager
173
+ });
174
+ const detail = shadcnResult.failed.length > 0
175
+ ? `added: ${shadcnResult.added.join(", ")}; failed: ${shadcnResult.failed.join(", ")}`
176
+ : `added: ${shadcnResult.added.join(", ")}`;
177
+ results.push({ name: "shadcn/ui", status: "completed", detail });
178
+ }
179
+ catch (error) {
180
+ const detail = error instanceof Error ? error.message : String(error);
181
+ results.push({ name: "shadcn/ui", status: "failed", detail });
182
+ printSummary(results);
183
+ throw new Error(detail);
184
+ }
185
+ }
186
+ else {
187
+ results.push({ name: "shadcn/ui", status: "skipped", detail: "disabled by option" });
188
+ }
189
+ const agents = await resolveAgents(cliOptions);
190
+ console.log(`agents: ${agents.length > 0 ? agents.join(", ") : "none"}`);
191
+ if (agents.length > 0) {
192
+ try {
193
+ console.log(chalk.cyan(`[3/4] Writing AI agent context files`));
194
+ const files = await setupAgents({
195
+ projectPath,
196
+ projectName: basename(projectPath),
197
+ agents
198
+ });
199
+ results.push({ name: "AI agent files", status: "completed", detail: files.join(", ") });
200
+ }
201
+ catch (error) {
202
+ const detail = error instanceof Error ? error.message : String(error);
203
+ results.push({ name: "AI agent files", status: "failed", detail });
204
+ printSummary(results);
205
+ throw new Error(detail);
206
+ }
207
+ }
208
+ else {
209
+ results.push({ name: "AI agent files", status: "skipped", detail: "no agents selected" });
210
+ }
211
+ const withAI = await resolveWithAI(cliOptions);
212
+ let providers = [];
213
+ if (withAI) {
214
+ providers = await resolveProviders(cliOptions, true);
215
+ }
216
+ console.log(`ai sdk: ${withAI ? `enabled (${providers.join(", ")})` : "disabled"}`);
217
+ if (withAI) {
218
+ try {
219
+ console.log(chalk.cyan(`[4/4] Adding AI SDK integration`));
220
+ const aiResult = await setupAI({
221
+ projectPath,
222
+ packageManager: detectedPm.packageManager,
223
+ providers
224
+ });
225
+ results.push({
226
+ name: "AI SDK",
227
+ status: "completed",
228
+ detail: `packages: ${aiResult.installedPackages.join(", ")}`
229
+ });
230
+ }
231
+ catch (error) {
232
+ const detail = error instanceof Error ? error.message : String(error);
233
+ results.push({ name: "AI SDK", status: "failed", detail });
234
+ printSummary(results);
235
+ throw new Error(detail);
236
+ }
237
+ }
238
+ else {
239
+ results.push({ name: "AI SDK", status: "skipped", detail: "disabled by option" });
240
+ }
241
+ printSummary(results);
242
+ console.log(chalk.bold("\nNext steps"));
243
+ console.log(`cd ${basename(projectPath)}`);
244
+ console.log(getDevCommand(detectedPm.packageManager));
245
+ }
246
+ main().catch((error) => {
247
+ const message = error instanceof Error ? error.message : String(error);
248
+ console.error(chalk.red(`\nError: ${message}`));
249
+ process.exitCode = 1;
250
+ });
251
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { PackageManager } from "../types.js";
2
+ export interface CreateNextAppOptions {
3
+ projectName: string;
4
+ packageManager: PackageManager;
5
+ cwd?: string;
6
+ }
7
+ export declare function buildCreateNextAppArgs(projectName: string, packageManager: PackageManager): string[];
8
+ export declare function createNextApp(options: CreateNextAppOptions): Promise<string>;
9
+ //# sourceMappingURL=create-next-app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-next-app.d.ts","sourceRoot":"","sources":["../../src/core/create-next-app.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,cAAc,GAC7B,MAAM,EAAE,CAcV;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAOlF"}
@@ -0,0 +1,26 @@
1
+ import { join, resolve } from "node:path";
2
+ import { runCommand } from "./runner.js";
3
+ export function buildCreateNextAppArgs(projectName, packageManager) {
4
+ return [
5
+ "create-next-app@latest",
6
+ projectName,
7
+ "--typescript",
8
+ "--tailwind",
9
+ "--app",
10
+ "--eslint",
11
+ "--no-src-dir",
12
+ "--import-alias",
13
+ "@/*",
14
+ `--use-${packageManager}`,
15
+ "--yes"
16
+ ];
17
+ }
18
+ export async function createNextApp(options) {
19
+ const cwd = options.cwd ?? process.cwd();
20
+ const projectPath = resolve(cwd, options.projectName);
21
+ await runCommand("npx", buildCreateNextAppArgs(options.projectName, options.packageManager), {
22
+ cwd
23
+ });
24
+ return join(projectPath);
25
+ }
26
+ //# sourceMappingURL=create-next-app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-next-app.js","sourceRoot":"","sources":["../../src/core/create-next-app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQzC,MAAM,UAAU,sBAAsB,CACpC,WAAmB,EACnB,cAA8B;IAE9B,OAAO;QACL,wBAAwB;QACxB,WAAW;QACX,cAAc;QACd,YAAY;QACZ,OAAO;QACP,UAAU;QACV,cAAc;QACd,gBAAgB;QAChB,KAAK;QACL,SAAS,cAAc,EAAE;QACzB,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA6B;IAC/D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACtD,MAAM,UAAU,CAAC,KAAK,EAAE,sBAAsB,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,cAAc,CAAC,EAAE;QAC3F,GAAG;KACJ,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare function ensureDirForFile(filePath: string): Promise<void>;
2
+ export declare function exists(filePath: string): Promise<boolean>;
3
+ export declare function writeWithBackup(filePath: string, content: string): Promise<void>;
4
+ export declare function upsertEnvEntries(filePath: string, entries: Array<{
5
+ key: string;
6
+ value: string;
7
+ comment?: string;
8
+ }>): Promise<void>;
9
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/core/files.ts"],"names":[],"mappings":"AAGA,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED,wBAAsB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAatF;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAC/D,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
@@ -0,0 +1,57 @@
1
+ import { mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+ export async function ensureDirForFile(filePath) {
4
+ await mkdir(dirname(filePath), { recursive: true });
5
+ }
6
+ export async function exists(filePath) {
7
+ try {
8
+ await stat(filePath);
9
+ return true;
10
+ }
11
+ catch {
12
+ return false;
13
+ }
14
+ }
15
+ export async function writeWithBackup(filePath, content) {
16
+ await ensureDirForFile(filePath);
17
+ if (await exists(filePath)) {
18
+ const backupPath = `${filePath}.bak`;
19
+ if (await exists(backupPath)) {
20
+ await writeFile(backupPath, await readFile(filePath, "utf8"), "utf8");
21
+ }
22
+ else {
23
+ await rename(filePath, backupPath);
24
+ }
25
+ }
26
+ await writeFile(filePath, content, "utf8");
27
+ }
28
+ export async function upsertEnvEntries(filePath, entries) {
29
+ await ensureDirForFile(filePath);
30
+ const currentText = (await exists(filePath)) ? await readFile(filePath, "utf8") : "";
31
+ const currentLines = currentText.length > 0 ? currentText.split(/\r?\n/) : [];
32
+ const existingKeys = new Set();
33
+ for (const line of currentLines) {
34
+ const trimmed = line.trim();
35
+ if (!trimmed || trimmed.startsWith("#") || !trimmed.includes("="))
36
+ continue;
37
+ const [key] = trimmed.split("=");
38
+ if (key)
39
+ existingKeys.add(key);
40
+ }
41
+ const appended = [];
42
+ for (const entry of entries) {
43
+ if (existingKeys.has(entry.key))
44
+ continue;
45
+ if (entry.comment) {
46
+ appended.push(``, `# ${entry.comment}`);
47
+ }
48
+ appended.push(`${entry.key}=${entry.value}`);
49
+ existingKeys.add(entry.key);
50
+ }
51
+ if (appended.length === 0)
52
+ return;
53
+ const prefix = currentText.length > 0 ? `${currentText.replace(/\s*$/, "")}\n` : "";
54
+ const merged = `${prefix}${appended.join("\n")}\n`;
55
+ await writeFile(filePath, merged, "utf8");
56
+ }
57
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/core/files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type PackageManager } from "../types.js";
2
+ export interface DetectPackageManagerOptions {
3
+ override?: PackageManager;
4
+ cwd?: string;
5
+ env?: NodeJS.ProcessEnv;
6
+ }
7
+ export interface DetectedPackageManager {
8
+ packageManager: PackageManager;
9
+ source: "override" | "user-agent" | "lockfile" | "default";
10
+ }
11
+ export declare function isPackageManager(value: string): value is PackageManager;
12
+ export declare function parsePackageManagerFromUserAgent(userAgent: string | undefined): PackageManager | undefined;
13
+ export declare function detectPackageManagerFromLockfile(cwd: string): Promise<PackageManager | undefined>;
14
+ export declare function detectPackageManager(options?: DetectPackageManagerOptions): Promise<DetectedPackageManager>;
15
+ export interface PackageInstallCommand {
16
+ command: string;
17
+ args: string[];
18
+ }
19
+ export declare function getInstallCommand(packageManager: PackageManager, packages: string[], options?: {
20
+ dev?: boolean;
21
+ }): PackageInstallCommand;
22
+ export declare function getDevCommand(packageManager: PackageManager): string;
23
+ //# sourceMappingURL=package-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../../src/core/package-manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AASpE,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,UAAU,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;CAC5D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,cAAc,CAEvE;AAED,wBAAgB,gCAAgC,CAC9C,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,cAAc,GAAG,SAAS,CAS5B;AAED,wBAAsB,gCAAgC,CACpD,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAWrC;AAED,wBAAsB,oBAAoB,CACxC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,sBAAsB,CAAC,CAkBjC;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9B,qBAAqB,CAyBvB;AAED,wBAAgB,aAAa,CAAC,cAAc,EAAE,cAAc,GAAG,MAAM,CAWpE"}
@@ -0,0 +1,89 @@
1
+ import { access } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { PACKAGE_MANAGERS } from "../types.js";
4
+ const LOCKFILE_TO_PM = [
5
+ { lockfile: "pnpm-lock.yaml", packageManager: "pnpm" },
6
+ { lockfile: "yarn.lock", packageManager: "yarn" },
7
+ { lockfile: "package-lock.json", packageManager: "npm" },
8
+ { lockfile: "bun.lockb", packageManager: "bun" }
9
+ ];
10
+ export function isPackageManager(value) {
11
+ return PACKAGE_MANAGERS.includes(value);
12
+ }
13
+ export function parsePackageManagerFromUserAgent(userAgent) {
14
+ if (!userAgent)
15
+ return undefined;
16
+ const match = userAgent.match(/(pnpm|yarn|npm|bun)\//);
17
+ if (!match)
18
+ return undefined;
19
+ const detected = match[1];
20
+ if (!detected)
21
+ return undefined;
22
+ return isPackageManager(detected) ? detected : undefined;
23
+ }
24
+ export async function detectPackageManagerFromLockfile(cwd) {
25
+ for (const candidate of LOCKFILE_TO_PM) {
26
+ try {
27
+ await access(join(cwd, candidate.lockfile));
28
+ return candidate.packageManager;
29
+ }
30
+ catch {
31
+ // Ignore missing lockfiles.
32
+ }
33
+ }
34
+ return undefined;
35
+ }
36
+ export async function detectPackageManager(options = {}) {
37
+ if (options.override) {
38
+ return { packageManager: options.override, source: "override" };
39
+ }
40
+ const env = options.env ?? process.env;
41
+ const cwd = options.cwd ?? process.cwd();
42
+ const fromUserAgent = parsePackageManagerFromUserAgent(env.npm_config_user_agent);
43
+ if (fromUserAgent) {
44
+ return { packageManager: fromUserAgent, source: "user-agent" };
45
+ }
46
+ const fromLockfile = await detectPackageManagerFromLockfile(cwd);
47
+ if (fromLockfile) {
48
+ return { packageManager: fromLockfile, source: "lockfile" };
49
+ }
50
+ return { packageManager: "npm", source: "default" };
51
+ }
52
+ export function getInstallCommand(packageManager, packages, options = {}) {
53
+ const dev = options.dev ?? false;
54
+ switch (packageManager) {
55
+ case "npm":
56
+ return {
57
+ command: "npm",
58
+ args: ["install", ...(dev ? ["-D"] : []), ...packages]
59
+ };
60
+ case "pnpm":
61
+ return {
62
+ command: "pnpm",
63
+ args: ["add", ...(dev ? ["-D"] : []), ...packages]
64
+ };
65
+ case "yarn":
66
+ return {
67
+ command: "yarn",
68
+ args: ["add", ...(dev ? ["-D"] : []), ...packages]
69
+ };
70
+ case "bun":
71
+ return {
72
+ command: "bun",
73
+ args: ["add", ...(dev ? ["-d"] : []), ...packages]
74
+ };
75
+ }
76
+ }
77
+ export function getDevCommand(packageManager) {
78
+ switch (packageManager) {
79
+ case "npm":
80
+ return "npm run dev";
81
+ case "pnpm":
82
+ return "pnpm dev";
83
+ case "yarn":
84
+ return "yarn dev";
85
+ case "bun":
86
+ return "bun run dev";
87
+ }
88
+ }
89
+ //# sourceMappingURL=package-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../../src/core/package-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface RunCommandOptions {
2
+ cwd?: string;
3
+ env?: NodeJS.ProcessEnv;
4
+ stdio?: "inherit" | "pipe";
5
+ }
6
+ export declare function runCommand(command: string, args: string[], options?: RunCommandOptions): Promise<void>;
7
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/core/runner.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAC5B;AAED,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAcf"}
@@ -0,0 +1,17 @@
1
+ import { execa } from "execa";
2
+ export async function runCommand(command, args, options = {}) {
3
+ const stdio = options.stdio ?? "inherit";
4
+ try {
5
+ await execa(command, args, {
6
+ cwd: options.cwd,
7
+ env: options.env,
8
+ stdio
9
+ });
10
+ }
11
+ catch (error) {
12
+ const failed = error;
13
+ const reason = failed.stderr || failed.shortMessage || failed.message || "Unknown error";
14
+ throw new Error(`Command failed: ${[command, ...args].join(" ")}\n${reason}`);
15
+ }
16
+ }
17
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/core/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAQ9B,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,OAAe,EACf,IAAc,EACd,UAA6B,EAAE;IAE/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACzB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,KAAqE,CAAC;QACrF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,OAAO,IAAI,eAAe,CAAC;QACzF,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;IAChF,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type DetectedPackageManager } from "./core/package-manager.js";
2
+ import type { ScaffoldOptions, StepResult } from "./types.js";
3
+ export interface ResolvedOptions extends ScaffoldOptions {
4
+ detectedPackageManager: DetectedPackageManager;
5
+ }
6
+ export declare function resolvePackageManager(override: ScaffoldOptions["packageManager"] | undefined, cwd?: string): Promise<DetectedPackageManager>;
7
+ export declare function runScaffold(options: ScaffoldOptions, cwd?: string): Promise<StepResult[]>;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,sBAAsB,EAAwB,MAAM,2BAA2B,CAAC;AAC9F,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK9D,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,sBAAsB,EAAE,sBAAsB,CAAC;CAChD;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,eAAe,CAAC,gBAAgB,CAAC,GAAG,SAAS,EACvD,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,sBAAsB,CAAC,CAEjC;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,SAAgB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAgFtG"}
package/dist/index.js ADDED
@@ -0,0 +1,93 @@
1
+ import { basename, resolve } from "node:path";
2
+ import chalk from "chalk";
3
+ import { createNextApp } from "./core/create-next-app.js";
4
+ import { detectPackageManager } from "./core/package-manager.js";
5
+ import { installShadcn } from "./integrations/shadcn.js";
6
+ import { setupAgents } from "./integrations/agents.js";
7
+ import { setupAI } from "./integrations/ai-sdk.js";
8
+ export async function resolvePackageManager(override, cwd) {
9
+ return detectPackageManager({ override, cwd });
10
+ }
11
+ export async function runScaffold(options, cwd = process.cwd()) {
12
+ const results = [];
13
+ const projectPath = resolve(cwd, options.projectName);
14
+ try {
15
+ console.log(chalk.cyan(`\n[1/4] Creating Next.js project (${options.projectName})`));
16
+ await createNextApp({
17
+ projectName: options.projectName,
18
+ packageManager: options.packageManager,
19
+ cwd
20
+ });
21
+ results.push({ name: "Next.js project", status: "completed" });
22
+ }
23
+ catch (error) {
24
+ const detail = error instanceof Error ? error.message : String(error);
25
+ results.push({ name: "Next.js project", status: "failed", detail });
26
+ throw Object.assign(new Error(detail), { results });
27
+ }
28
+ if (options.withShadcn) {
29
+ try {
30
+ console.log(chalk.cyan(`[2/4] Installing shadcn/ui`));
31
+ const shadcnResult = await installShadcn({
32
+ projectPath,
33
+ packageManager: options.packageManager
34
+ });
35
+ const detail = shadcnResult.failed.length > 0
36
+ ? `added: ${shadcnResult.added.join(", ")}; failed: ${shadcnResult.failed.join(", ")}`
37
+ : `added: ${shadcnResult.added.join(", ")}`;
38
+ results.push({ name: "shadcn/ui", status: "completed", detail });
39
+ }
40
+ catch (error) {
41
+ const detail = error instanceof Error ? error.message : String(error);
42
+ results.push({ name: "shadcn/ui", status: "failed", detail });
43
+ throw Object.assign(new Error(detail), { results });
44
+ }
45
+ }
46
+ else {
47
+ results.push({ name: "shadcn/ui", status: "skipped", detail: "disabled by option" });
48
+ }
49
+ if (options.agents.length > 0) {
50
+ try {
51
+ console.log(chalk.cyan(`[3/4] Writing AI agent context files`));
52
+ const files = await setupAgents({
53
+ projectPath,
54
+ projectName: basename(projectPath),
55
+ agents: options.agents
56
+ });
57
+ results.push({ name: "AI agent files", status: "completed", detail: files.join(", ") });
58
+ }
59
+ catch (error) {
60
+ const detail = error instanceof Error ? error.message : String(error);
61
+ results.push({ name: "AI agent files", status: "failed", detail });
62
+ throw Object.assign(new Error(detail), { results });
63
+ }
64
+ }
65
+ else {
66
+ results.push({ name: "AI agent files", status: "skipped", detail: "no agents selected" });
67
+ }
68
+ if (options.withAI) {
69
+ try {
70
+ console.log(chalk.cyan(`[4/4] Adding AI SDK integration`));
71
+ const aiResult = await setupAI({
72
+ projectPath,
73
+ packageManager: options.packageManager,
74
+ providers: options.providers
75
+ });
76
+ results.push({
77
+ name: "AI SDK",
78
+ status: "completed",
79
+ detail: `packages: ${aiResult.installedPackages.join(", ")}`
80
+ });
81
+ }
82
+ catch (error) {
83
+ const detail = error instanceof Error ? error.message : String(error);
84
+ results.push({ name: "AI SDK", status: "failed", detail });
85
+ throw Object.assign(new Error(detail), { results });
86
+ }
87
+ }
88
+ else {
89
+ results.push({ name: "AI SDK", status: "skipped", detail: "disabled by option" });
90
+ }
91
+ return results;
92
+ }
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Agent } from "../types.js";
2
+ export interface SetupAgentsOptions {
3
+ projectPath: string;
4
+ projectName: string;
5
+ agents: Agent[];
6
+ }
7
+ export declare function setupAgents(options: SetupAgentsOptions): Promise<string[]>;
8
+ //# sourceMappingURL=agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/integrations/agents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAIzC,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAYhF"}
@@ -0,0 +1,15 @@
1
+ import { join } from "node:path";
2
+ import { writeWithBackup } from "../core/files.js";
3
+ import { AGENT_FILE_MAP, renderAgentTemplate } from "../templates/agents.js";
4
+ export async function setupAgents(options) {
5
+ const writtenFiles = [];
6
+ for (const agent of options.agents) {
7
+ const target = AGENT_FILE_MAP[agent];
8
+ const outputPath = join(options.projectPath, target);
9
+ const content = renderAgentTemplate(agent, options.projectName);
10
+ await writeWithBackup(outputPath, `${content}\n`);
11
+ writtenFiles.push(target);
12
+ }
13
+ return writtenFiles;
14
+ }
15
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/integrations/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAQ7E,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA2B;IAC3D,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QAChE,MAAM,eAAe,CAAC,UAAU,EAAE,GAAG,OAAO,IAAI,CAAC,CAAC;QAClD,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { AIProvider, PackageManager } from "../types.js";
2
+ export interface SetupAIOptions {
3
+ projectPath: string;
4
+ packageManager: PackageManager;
5
+ providers: AIProvider[];
6
+ }
7
+ export interface SetupAIResult {
8
+ installedPackages: string[];
9
+ writtenFiles: string[];
10
+ }
11
+ export declare function setupAI(options: SetupAIOptions): Promise<SetupAIResult>;
12
+ //# sourceMappingURL=ai-sdk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk.d.ts","sourceRoot":"","sources":["../../src/integrations/ai-sdk.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAM9D,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,UAAU,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAoB7E"}
@@ -0,0 +1,23 @@
1
+ import { join } from "node:path";
2
+ import { ensureDirForFile, upsertEnvEntries, writeWithBackup } from "../core/files.js";
3
+ import { getInstallCommand } from "../core/package-manager.js";
4
+ import { runCommand } from "../core/runner.js";
5
+ import { getAIPackages, getProviderEnvEntries, renderAiModule } from "../templates/ai.js";
6
+ export async function setupAI(options) {
7
+ if (options.providers.length === 0) {
8
+ throw new Error("At least one AI provider is required when --with-ai is enabled.");
9
+ }
10
+ const packages = getAIPackages(options.providers);
11
+ const install = getInstallCommand(options.packageManager, packages);
12
+ await runCommand(install.command, install.args, { cwd: options.projectPath });
13
+ const aiModulePath = join(options.projectPath, "lib", "ai.ts");
14
+ await ensureDirForFile(aiModulePath);
15
+ await writeWithBackup(aiModulePath, `${renderAiModule(options.providers)}\n`);
16
+ const envPath = join(options.projectPath, ".env.local.example");
17
+ await upsertEnvEntries(envPath, getProviderEnvEntries(options.providers));
18
+ return {
19
+ installedPackages: packages,
20
+ writtenFiles: ["lib/ai.ts", ".env.local.example"]
21
+ };
22
+ }
23
+ //# sourceMappingURL=ai-sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk.js","sourceRoot":"","sources":["../../src/integrations/ai-sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAa1F,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAuB;IACnD,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACpE,MAAM,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAE9E,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC/D,MAAM,gBAAgB,CAAC,YAAY,CAAC,CAAC;IACrC,MAAM,eAAe,CAAC,YAAY,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAE9E,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;IAChE,MAAM,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAE1E,OAAO;QACL,iBAAiB,EAAE,QAAQ;QAC3B,YAAY,EAAE,CAAC,WAAW,EAAE,oBAAoB,CAAC;KAClD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { PackageManager } from "../types.js";
2
+ export interface InstallShadcnOptions {
3
+ projectPath: string;
4
+ packageManager: PackageManager;
5
+ }
6
+ export interface InstallShadcnResult {
7
+ added: string[];
8
+ failed: string[];
9
+ }
10
+ export declare function installShadcn(options: InstallShadcnOptions): Promise<InstallShadcnResult>;
11
+ //# sourceMappingURL=shadcn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shadcn.d.ts","sourceRoot":"","sources":["../../src/integrations/shadcn.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAgC/F"}
@@ -0,0 +1,26 @@
1
+ import ora from "ora";
2
+ import { runCommand } from "../core/runner.js";
3
+ const DEFAULT_COMPONENTS = ["button", "input", "card"];
4
+ export async function installShadcn(options) {
5
+ const spinner = ora("Installing shadcn/ui").start();
6
+ await runCommand("npx", ["shadcn@latest", "init", "-y", "-d", "--no-src-dir", "--cwd", options.projectPath], { cwd: options.projectPath });
7
+ spinner.text = "Adding default shadcn components";
8
+ const result = { added: [], failed: [] };
9
+ for (const component of DEFAULT_COMPONENTS) {
10
+ try {
11
+ await runCommand("npx", ["shadcn@latest", "add", component, "-y", "--cwd", options.projectPath], { cwd: options.projectPath });
12
+ result.added.push(component);
13
+ }
14
+ catch {
15
+ result.failed.push(component);
16
+ }
17
+ }
18
+ if (result.failed.length > 0) {
19
+ spinner.warn(`shadcn installed with warnings (failed: ${result.failed.join(", ")})`);
20
+ }
21
+ else {
22
+ spinner.succeed("shadcn/ui installed");
23
+ }
24
+ return result;
25
+ }
26
+ //# sourceMappingURL=shadcn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shadcn.js","sourceRoot":"","sources":["../../src/integrations/shadcn.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,kBAAkB,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAYvD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA6B;IAC/D,MAAM,OAAO,GAAG,GAAG,CAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,CAAC;IAEpD,MAAM,UAAU,CACd,KAAK,EACL,CAAC,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,EACnF,EAAE,GAAG,EAAE,OAAO,CAAC,WAAW,EAAE,CAC7B,CAAC;IAEF,OAAO,CAAC,IAAI,GAAG,kCAAkC,CAAC;IAElD,MAAM,MAAM,GAAwB,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC9D,KAAK,MAAM,SAAS,IAAI,kBAAkB,EAAE,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,UAAU,CACd,KAAK,EACL,CAAC,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,EACvE,EAAE,GAAG,EAAE,OAAO,CAAC,WAAW,EAAE,CAC7B,CAAC;YACF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,2CAA2C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvF,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Agent } from "../types.js";
2
+ export declare const AGENT_FILE_MAP: Record<Agent, string>;
3
+ export declare function renderAgentTemplate(agent: Agent, projectName: string): string;
4
+ //# sourceMappingURL=agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/templates/agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAKhD,CAAC;AA8BF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAa7E"}
@@ -0,0 +1,47 @@
1
+ export const AGENT_FILE_MAP = {
2
+ cursor: ".cursorrules",
3
+ codex: "CODEX.md",
4
+ claude: "CLAUDE.md",
5
+ antigravity: ".antigravity.md"
6
+ };
7
+ function baseTemplate(projectName) {
8
+ return [
9
+ `Project: ${projectName}`,
10
+ ``,
11
+ `## Stack`,
12
+ `- Next.js (App Router)`,
13
+ `- TypeScript`,
14
+ `- Tailwind CSS`,
15
+ ``,
16
+ `## Folder Guide`,
17
+ `- app/: routes and layouts`,
18
+ `- components/: reusable UI`,
19
+ `- lib/: shared utilities and integrations`,
20
+ ``,
21
+ `## Conventions`,
22
+ `- Prefer Server Components by default`,
23
+ `- Keep files focused and composable`,
24
+ `- Use strict TypeScript types; avoid any`,
25
+ `- Keep side effects isolated`,
26
+ ``,
27
+ `## PR Checklist`,
28
+ `- Types and lint pass`,
29
+ `- No secrets in code or commits`,
30
+ `- Clear error handling for network/file operations`,
31
+ `- Update docs when behavior changes`
32
+ ].join("\n");
33
+ }
34
+ export function renderAgentTemplate(agent, projectName) {
35
+ const common = baseTemplate(projectName);
36
+ switch (agent) {
37
+ case "cursor":
38
+ return [`# Cursor Rules`, ``, common].join("\n");
39
+ case "codex":
40
+ return [`# Codex Context`, ``, common].join("\n");
41
+ case "claude":
42
+ return [`# Claude Context`, ``, common].join("\n");
43
+ case "antigravity":
44
+ return [`# Antigravity Context`, ``, common].join("\n");
45
+ }
46
+ }
47
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/templates/agents.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAA0B;IACnD,MAAM,EAAE,cAAc;IACtB,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,WAAW;IACnB,WAAW,EAAE,iBAAiB;CAC/B,CAAC;AAEF,SAAS,YAAY,CAAC,WAAmB;IACvC,OAAO;QACL,YAAY,WAAW,EAAE;QACzB,EAAE;QACF,UAAU;QACV,wBAAwB;QACxB,cAAc;QACd,gBAAgB;QAChB,EAAE;QACF,iBAAiB;QACjB,4BAA4B;QAC5B,4BAA4B;QAC5B,2CAA2C;QAC3C,EAAE;QACF,gBAAgB;QAChB,uCAAuC;QACvC,qCAAqC;QACrC,0CAA0C;QAC1C,8BAA8B;QAC9B,EAAE;QACF,iBAAiB;QACjB,uBAAuB;QACvB,iCAAiC;QACjC,oDAAoD;QACpD,qCAAqC;KACtC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAY,EAAE,WAAmB;IACnE,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IAEzC,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,QAAQ;YACX,OAAO,CAAC,gBAAgB,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,KAAK,OAAO;YACV,OAAO,CAAC,iBAAiB,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,KAAK,QAAQ;YACX,OAAO,CAAC,kBAAkB,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,KAAK,aAAa;YAChB,OAAO,CAAC,uBAAuB,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { AIProvider } from "../types.js";
2
+ export declare function getAIPackages(providers: AIProvider[]): string[];
3
+ export declare function getProviderEnvEntries(providers: AIProvider[]): Array<{
4
+ key: string;
5
+ value: string;
6
+ comment?: string;
7
+ }>;
8
+ export declare function renderAiModule(providers: AIProvider[]): string;
9
+ //# sourceMappingURL=ai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/templates/ai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAkC9C,wBAAgB,aAAa,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,CAG/D;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,UAAU,EAAE,GACtB,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAWzD;AAaD,wBAAgB,cAAc,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,CA+B9D"}
@@ -0,0 +1,77 @@
1
+ const PROVIDER_CONFIG = {
2
+ openai: {
3
+ packageName: "@ai-sdk/openai",
4
+ importName: "openai",
5
+ envApiKey: "OPENAI_API_KEY",
6
+ envModel: "OPENAI_MODEL",
7
+ modelFactory: "openai"
8
+ },
9
+ anthropic: {
10
+ packageName: "@ai-sdk/anthropic",
11
+ importName: "anthropic",
12
+ envApiKey: "ANTHROPIC_API_KEY",
13
+ envModel: "ANTHROPIC_MODEL",
14
+ modelFactory: "anthropic"
15
+ },
16
+ google: {
17
+ packageName: "@ai-sdk/google",
18
+ importName: "google",
19
+ envApiKey: "GOOGLE_GENERATIVE_AI_API_KEY",
20
+ envModel: "GOOGLE_MODEL",
21
+ modelFactory: "google"
22
+ }
23
+ };
24
+ export function getAIPackages(providers) {
25
+ const unique = new Set(providers);
26
+ return ["ai", ...Array.from(unique).map((provider) => PROVIDER_CONFIG[provider].packageName)];
27
+ }
28
+ export function getProviderEnvEntries(providers) {
29
+ const entries = [];
30
+ const unique = new Set(providers);
31
+ for (const provider of unique) {
32
+ const config = PROVIDER_CONFIG[provider];
33
+ entries.push({ key: config.envApiKey, value: "", comment: providerLabel(provider) });
34
+ entries.push({ key: config.envModel, value: "", comment: `${providerLabel(provider)} model id` });
35
+ }
36
+ return entries;
37
+ }
38
+ function providerLabel(provider) {
39
+ switch (provider) {
40
+ case "openai":
41
+ return "OpenAI";
42
+ case "anthropic":
43
+ return "Anthropic";
44
+ case "google":
45
+ return "Google";
46
+ }
47
+ }
48
+ export function renderAiModule(providers) {
49
+ const selected = Array.from(new Set(providers));
50
+ const imports = selected
51
+ .map((provider) => {
52
+ const config = PROVIDER_CONFIG[provider];
53
+ return `import { ${config.importName} } from "${config.packageName}";`;
54
+ })
55
+ .join("\n");
56
+ const providerMapEntries = selected
57
+ .map((provider) => {
58
+ const config = PROVIDER_CONFIG[provider];
59
+ return ` ${provider}: (modelId: string) => ${config.modelFactory}(modelId),`;
60
+ })
61
+ .join("\n");
62
+ const providerType = selected.map((provider) => `"${provider}"`).join(" | ");
63
+ return [
64
+ imports,
65
+ ``,
66
+ `export type AIProvider = ${providerType};`,
67
+ ``,
68
+ `const providerFactories: Record<AIProvider, (modelId: string) => unknown> = {`,
69
+ providerMapEntries,
70
+ `};`,
71
+ ``,
72
+ `export function getModel(provider: AIProvider, modelId: string) {`,
73
+ ` return providerFactories[provider](modelId);`,
74
+ `}`
75
+ ].join("\n");
76
+ }
77
+ //# sourceMappingURL=ai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/templates/ai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export declare const PACKAGE_MANAGERS: readonly ["npm", "pnpm", "yarn", "bun"];
2
+ export declare const AGENTS: readonly ["cursor", "codex", "claude", "antigravity"];
3
+ export declare const AI_PROVIDERS: readonly ["openai", "anthropic", "google"];
4
+ export type PackageManager = (typeof PACKAGE_MANAGERS)[number];
5
+ export type Agent = (typeof AGENTS)[number];
6
+ export type AIProvider = (typeof AI_PROVIDERS)[number];
7
+ export interface ScaffoldOptions {
8
+ projectName: string;
9
+ packageManager: PackageManager;
10
+ withShadcn: boolean;
11
+ agents: Agent[];
12
+ withAI: boolean;
13
+ providers: AIProvider[];
14
+ yes: boolean;
15
+ }
16
+ export type StepStatus = "completed" | "skipped" | "failed";
17
+ export interface StepResult {
18
+ name: string;
19
+ status: StepStatus;
20
+ detail?: string;
21
+ }
22
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,yCAA0C,CAAC;AACxE,eAAO,MAAM,MAAM,uDAAwD,CAAC;AAC5E,eAAO,MAAM,YAAY,4CAA6C,CAAC;AAEvE,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC/D,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAC5C,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,GAAG,EAAE,OAAO,CAAC;CACd;AAED,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
package/dist/types.js ADDED
@@ -0,0 +1,4 @@
1
+ export const PACKAGE_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
2
+ export const AGENTS = ["cursor", "codex", "claude", "antigravity"];
3
+ export const AI_PROVIDERS = ["openai", "anthropic", "google"];
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAU,CAAC;AACxE,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAU,CAAC;AAC5E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAU,CAAC"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "create-ai-mvp",
3
+ "version": "0.1.1",
4
+ "description": "CLI to scaffold a Next.js AI SaaS MVP in minutes",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-ai-mvp": "dist/cli.js"
8
+ },
9
+ "main": "dist/cli.js",
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc -p tsconfig.json",
17
+ "dev": "tsx src/cli.ts",
18
+ "test": "vitest run",
19
+ "test:watch": "vitest"
20
+ },
21
+ "keywords": [
22
+ "cli",
23
+ "nextjs",
24
+ "scaffold",
25
+ "ai",
26
+ "mvp"
27
+ ],
28
+ "author": "",
29
+ "license": "MIT",
30
+ "engines": {
31
+ "node": ">=20"
32
+ },
33
+ "dependencies": {
34
+ "@inquirer/prompts": "^7.9.0",
35
+ "chalk": "^5.6.2",
36
+ "commander": "^14.0.1",
37
+ "execa": "^9.6.0",
38
+ "ora": "^9.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "@types/node": "^24.3.0",
42
+ "tsx": "^4.20.5",
43
+ "typescript": "^5.9.2",
44
+ "vitest": "^3.2.4"
45
+ }
46
+ }