create-nene 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,39 +21,47 @@ pnpm create nene
21
21
  npm create nene@latest my-app
22
22
  ```
23
23
 
24
- ## Templates
25
-
26
- - **default** - Full-stack setup with frontend and backend
27
- - **minimal** - Minimal setup for quick prototyping
28
-
29
24
  ## Options
30
25
 
31
26
  ```
32
27
  Usage: create-nene [project-name] [options]
33
28
 
34
29
  Options:
35
- -t, --template <template> Template to use (default, minimal)
36
- --typescript Use TypeScript (default: true)
37
- --no-typescript Do not use TypeScript
38
- --eslint Use ESLint (default: true)
39
- --no-eslint Do not use ESLint
40
- -V, --version Output the version number
41
- -h, --help Display help for command
30
+ -V, --version Output the version number
31
+ -h, --help Display help for command
42
32
  ```
43
33
 
34
+ During setup, you will be prompted to select a package manager (pnpm, npm, or yarn).
35
+
44
36
  ## What's Inside
45
37
 
46
- A newly created project includes:
38
+ A newly created project is a full-stack monorepo with the following structure:
47
39
 
48
40
  ```
49
41
  my-app/
50
- ├── src/
51
- │ ├── app/ # Frontend pages and layouts
52
- │ └── server/ # Backend API and services
53
- ├── public/ # Static assets
54
- ├── package.json
55
- ├── tsconfig.json
56
- └── README.md
42
+ ├── apps/
43
+ │ ├── web/ # Next.js 16 frontend (port 3000)
44
+ └── src/app/ # Pages and layouts
45
+ │ └── api/ # NestJS 11 backend (port 4000)
46
+ │ └── src/ # Controllers, modules, services
47
+ ├── packages/
48
+ └── shared/ # Shared types, DTOs, constants
49
+ │ └── src/
50
+ │ ├── types/ # TypeScript types and DTOs
51
+ │ └── constants/ # Shared constants (API routes, etc.)
52
+ ├── docs/ # AI-friendly documentation
53
+ │ ├── API.md # API endpoint reference
54
+ │ ├── overview/
55
+ │ │ └── ARCHITECTURE.md # Project architecture
56
+ │ ├── kanban/ # Task management (TODO/DOING/DONE)
57
+ │ └── pages/ # Page documentation
58
+ ├── scripts/
59
+ │ └── dev.sh # Development server startup script
60
+ ├── .cursor/
61
+ │ └── rules/ # Cursor AI agent rules
62
+ ├── turbo.json # Turborepo configuration
63
+ ├── pnpm-workspace.yaml # pnpm workspace configuration
64
+ └── package.json
57
65
  ```
58
66
 
59
67
  ## License
package/dist/index.js CHANGED
@@ -144,6 +144,23 @@ function updateSubPackageNames(projectPath, projectName) {
144
144
  fs.writeFileSync(filePath, content);
145
145
  }
146
146
  }
147
+ const agentRuleFiles = [
148
+ path.join(projectPath, "AI_CONTEXT.md"),
149
+ path.join(projectPath, "CLAUDE.md"),
150
+ path.join(projectPath, "AGENTS.md"),
151
+ path.join(projectPath, ".github", "copilot-instructions.md"),
152
+ path.join(projectPath, "apps", "web", "CLAUDE.md"),
153
+ path.join(projectPath, "apps", "web", "AGENTS.md"),
154
+ path.join(projectPath, "apps", "api", "CLAUDE.md"),
155
+ path.join(projectPath, "apps", "api", "AGENTS.md")
156
+ ];
157
+ for (const filePath of agentRuleFiles) {
158
+ if (fs.existsSync(filePath)) {
159
+ let content = fs.readFileSync(filePath, "utf-8");
160
+ content = content.replace(/@app\/shared/g, `@${projectName}/shared`);
161
+ fs.writeFileSync(filePath, content);
162
+ }
163
+ }
147
164
  const rootPkgPath = path.join(projectPath, "package.json");
148
165
  if (fs.existsSync(rootPkgPath)) {
149
166
  let content = fs.readFileSync(rootPkgPath, "utf-8");
@@ -294,7 +311,11 @@ Failed to build shared package. Run '${packageManager === "npm" ? "npm run build
294
311
  console.log(` ${pc.cyan("apps/api")} - NestJS backend (port 4000)`);
295
312
  console.log(` ${pc.cyan("packages/shared")} - Shared types and constants`);
296
313
  console.log(` ${pc.cyan("docs/")} - Project documentation`);
314
+ console.log(` ${pc.cyan("AI_CONTEXT.md")} - Universal AI context (single source of truth)`);
297
315
  console.log(` ${pc.cyan(".cursor/rules/")} - Cursor AI agent rules`);
316
+ console.log(` ${pc.cyan(".github/")} - GitHub Copilot instructions`);
317
+ console.log(` ${pc.cyan("CLAUDE.md")} - Claude Code agent rules`);
318
+ console.log(` ${pc.cyan("AGENTS.md")} - OpenAI Codex agent rules`);
298
319
  console.log();
299
320
  console.log("Next steps:");
300
321
  console.log();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { program } from \"commander\";\nimport prompts from \"prompts\";\nimport pc from \"picocolors\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { execSync } from \"node:child_process\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\ninterface ProjectOptions {\n projectName: string;\n packageManager: \"npm\" | \"yarn\" | \"pnpm\";\n}\n\nfunction validateProjectName(name: string): boolean {\n const validNameRegex =\n /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/;\n return validNameRegex.test(name);\n}\n\nfunction detectPackageManager(): \"npm\" | \"yarn\" | \"pnpm\" {\n const userAgent = process.env.npm_config_user_agent;\n if (userAgent) {\n if (userAgent.startsWith(\"yarn\")) return \"yarn\";\n if (userAgent.startsWith(\"pnpm\")) return \"pnpm\";\n }\n return \"pnpm\"; // Default to pnpm for monorepo\n}\n\nfunction isCommandAvailable(command: string): boolean {\n try {\n execSync(`${command} --version`, { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction ensurePackageManager(packageManager: \"npm\" | \"yarn\" | \"pnpm\"): boolean {\n if (isCommandAvailable(packageManager)) {\n return true;\n }\n\n console.log(\n pc.yellow(`\\n${packageManager} is not installed. Attempting to install...`)\n );\n\n // Try corepack first (built-in to Node.js 16.9+)\n if (isCommandAvailable(\"corepack\")) {\n try {\n console.log(pc.dim(` Using corepack to enable ${packageManager}...`));\n execSync(`corepack enable ${packageManager}`, { stdio: \"inherit\" });\n if (isCommandAvailable(packageManager)) {\n console.log(pc.green(` ✓ ${packageManager} installed via corepack\\n`));\n return true;\n }\n } catch {\n // corepack failed, try next method\n }\n }\n\n // Fallback: install via npm\n if (packageManager !== \"npm\" && isCommandAvailable(\"npm\")) {\n try {\n console.log(pc.dim(` Installing ${packageManager} globally via npm...`));\n execSync(`npm install -g ${packageManager}`, { stdio: \"inherit\" });\n if (isCommandAvailable(packageManager)) {\n console.log(pc.green(`\\n ✓ ${packageManager} installed via npm\\n`));\n return true;\n }\n } catch {\n // npm global install failed (possibly permission issue)\n }\n }\n\n // All methods failed\n console.log(\n pc.red(`\\n ✗ Failed to install ${packageManager} automatically.`)\n );\n console.log(\n pc.yellow(` Please install it manually:\\n`)\n );\n\n if (packageManager === \"pnpm\") {\n console.log(pc.dim(\" npm install -g pnpm\"));\n console.log(pc.dim(\" # or\"));\n console.log(pc.dim(\" corepack enable pnpm\"));\n console.log(pc.dim(\" # or\"));\n console.log(pc.dim(\" curl -fsSL https://get.pnpm.io/install.sh | sh -\"));\n } else if (packageManager === \"yarn\") {\n console.log(pc.dim(\" npm install -g yarn\"));\n console.log(pc.dim(\" # or\"));\n console.log(pc.dim(\" corepack enable yarn\"));\n }\n console.log();\n\n return false;\n}\n\nfunction copyDir(src: string, dest: string): void {\n fs.mkdirSync(dest, { recursive: true });\n const entries = fs.readdirSync(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const destPath = path.join(dest, entry.name);\n\n if (entry.isDirectory()) {\n copyDir(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n}\n\nfunction getTemplateDir(): string {\n // In development, templates are relative to src\n // In production (dist), templates are at the package root\n const devPath = path.resolve(__dirname, \"..\", \"templates\", \"default\");\n const prodPath = path.resolve(__dirname, \"..\", \"..\", \"templates\", \"default\");\n\n if (fs.existsSync(devPath)) return devPath;\n if (fs.existsSync(prodPath)) return prodPath;\n\n throw new Error(\"Template not found\");\n}\n\nfunction updatePackageJson(projectPath: string, projectName: string): void {\n const pkgPath = path.join(projectPath, \"package.json\");\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n pkg.name = projectName;\n fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n}\n\nfunction updateSubPackageNames(projectPath: string, projectName: string): void {\n // Update apps/web package.json\n const webPkgPath = path.join(projectPath, \"apps\", \"web\", \"package.json\");\n if (fs.existsSync(webPkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(webPkgPath, \"utf-8\"));\n pkg.name = `@${projectName}/web`;\n // Update shared package reference\n if (pkg.dependencies?.[\"@app/shared\"]) {\n pkg.dependencies[`@${projectName}/shared`] = pkg.dependencies[\"@app/shared\"];\n delete pkg.dependencies[\"@app/shared\"];\n }\n fs.writeFileSync(webPkgPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n }\n\n // Update apps/api package.json\n const apiPkgPath = path.join(projectPath, \"apps\", \"api\", \"package.json\");\n if (fs.existsSync(apiPkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(apiPkgPath, \"utf-8\"));\n pkg.name = `@${projectName}/api`;\n // Update shared package reference\n if (pkg.dependencies?.[\"@app/shared\"]) {\n pkg.dependencies[`@${projectName}/shared`] = pkg.dependencies[\"@app/shared\"];\n delete pkg.dependencies[\"@app/shared\"];\n }\n fs.writeFileSync(apiPkgPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n }\n\n // Update packages/shared package.json\n const sharedPkgPath = path.join(projectPath, \"packages\", \"shared\", \"package.json\");\n if (fs.existsSync(sharedPkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(sharedPkgPath, \"utf-8\"));\n pkg.name = `@${projectName}/shared`;\n fs.writeFileSync(sharedPkgPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n }\n\n // Update import statements in apps/web/src/app/page.tsx\n const pagePath = path.join(projectPath, \"apps\", \"web\", \"src\", \"app\", \"page.tsx\");\n if (fs.existsSync(pagePath)) {\n let content = fs.readFileSync(pagePath, \"utf-8\");\n content = content.replace(/@app\\/shared/g, `@${projectName}/shared`);\n fs.writeFileSync(pagePath, content);\n }\n\n // Update cursor rules to use correct package names\n const cursorRulesDir = path.join(projectPath, \".cursor\", \"rules\");\n if (fs.existsSync(cursorRulesDir)) {\n const ruleFiles = fs.readdirSync(cursorRulesDir);\n for (const file of ruleFiles) {\n const filePath = path.join(cursorRulesDir, file);\n let content = fs.readFileSync(filePath, \"utf-8\");\n content = content.replace(/@app\\/shared/g, `@${projectName}/shared`);\n fs.writeFileSync(filePath, content);\n }\n }\n\n // Update turbo.json filter names\n const rootPkgPath = path.join(projectPath, \"package.json\");\n if (fs.existsSync(rootPkgPath)) {\n let content = fs.readFileSync(rootPkgPath, \"utf-8\");\n content = content.replace(/@app\\/web/g, `@${projectName}/web`);\n content = content.replace(/@app\\/api/g, `@${projectName}/api`);\n fs.writeFileSync(rootPkgPath, content);\n }\n}\n\nfunction renameGitignore(projectPath: string): void {\n const gitignorePath = path.join(projectPath, \"_gitignore\");\n const targetPath = path.join(projectPath, \".gitignore\");\n if (fs.existsSync(gitignorePath)) {\n fs.renameSync(gitignorePath, targetPath);\n }\n}\n\nasync function promptForOptions(projectName?: string): Promise<ProjectOptions> {\n const defaultProjectName = projectName || \"my-nene-app\";\n\n const response = await prompts(\n [\n {\n type: projectName ? null : \"text\",\n name: \"projectName\",\n message: \"Project name:\",\n initial: defaultProjectName,\n validate: (value: string) => {\n if (!value) return \"Project name is required\";\n if (!validateProjectName(value)) {\n return \"Invalid project name. Use lowercase letters, numbers, and hyphens only.\";\n }\n return true;\n },\n },\n {\n type: \"select\",\n name: \"packageManager\",\n message: \"Select a package manager:\",\n choices: [\n {\n title: isCommandAvailable(\"pnpm\")\n ? \"pnpm (recommended)\"\n : \"pnpm (recommended, will be installed)\",\n value: \"pnpm\",\n },\n {\n title: isCommandAvailable(\"npm\")\n ? \"npm\"\n : \"npm (not found)\",\n value: \"npm\",\n },\n {\n title: isCommandAvailable(\"yarn\")\n ? \"yarn\"\n : \"yarn (will be installed)\",\n value: \"yarn\",\n },\n ],\n initial: 0,\n },\n ],\n {\n onCancel: () => {\n console.log(pc.red(\"\\nOperation cancelled.\"));\n process.exit(0);\n },\n }\n );\n\n return {\n projectName: projectName || response.projectName,\n packageManager: response.packageManager,\n };\n}\n\nasync function createProject(options: ProjectOptions): Promise<void> {\n const { projectName, packageManager } = options;\n const projectPath = path.resolve(process.cwd(), projectName);\n\n // Check if directory exists\n if (fs.existsSync(projectPath)) {\n const { overwrite } = await prompts({\n type: \"confirm\",\n name: \"overwrite\",\n message: `Directory \"${projectName}\" already exists. Overwrite?`,\n initial: false,\n });\n\n if (!overwrite) {\n console.log(pc.red(\"Operation cancelled.\"));\n process.exit(0);\n }\n\n fs.rmSync(projectPath, { recursive: true, force: true });\n }\n\n console.log();\n console.log(\n pc.cyan(`Creating a new nene.js monorepo in ${pc.bold(projectPath)}`)\n );\n console.log();\n\n // Copy template\n const templateDir = getTemplateDir();\n copyDir(templateDir, projectPath);\n\n // Rename _gitignore to .gitignore\n renameGitignore(projectPath);\n\n // Update package.json with project name\n updatePackageJson(projectPath, projectName);\n\n // Update sub-package names\n updateSubPackageNames(projectPath, projectName);\n\n // Ensure package manager is available\n const pmReady = ensurePackageManager(packageManager);\n\n if (!pmReady) {\n console.log(\n pc.yellow(\n `Skipping dependency installation. After installing ${packageManager}, run:`\n )\n );\n console.log(pc.dim(` cd ${projectName}`));\n console.log(pc.dim(` ${packageManager === \"npm\" ? \"npm install\" : packageManager === \"yarn\" ? \"yarn\" : \"pnpm install\"}`));\n console.log(pc.dim(` cd packages/shared && ${packageManager === \"npm\" ? \"npm run build\" : `${packageManager} build`}`));\n console.log();\n } else {\n // Install dependencies\n console.log(pc.cyan(\"Installing dependencies...\"));\n console.log();\n\n const installCmd = {\n npm: \"npm install\",\n yarn: \"yarn\",\n pnpm: \"pnpm install\",\n }[packageManager];\n\n try {\n execSync(installCmd, {\n cwd: projectPath,\n stdio: \"inherit\",\n });\n } catch {\n console.log(\n pc.yellow(\n \"\\nFailed to install dependencies. You can install them manually.\"\n )\n );\n }\n\n // Build shared package first\n console.log();\n console.log(pc.cyan(\"Building shared package...\"));\n\n try {\n const buildCmd = packageManager === \"npm\" ? \"npm run build\" : `${packageManager} build`;\n execSync(buildCmd, {\n cwd: path.join(projectPath, \"packages\", \"shared\"),\n stdio: \"inherit\",\n });\n } catch {\n console.log(\n pc.yellow(\n `\\nFailed to build shared package. Run '${packageManager === \"npm\" ? \"npm run build\" : `${packageManager} build`}' in packages/shared manually.`\n )\n );\n }\n }\n\n // Success message\n console.log();\n console.log(\n pc.green(\"Success!\") + ` Created ${pc.bold(projectName)} at ${projectPath}`\n );\n console.log();\n console.log(\"Project structure:\");\n console.log();\n console.log(` ${pc.cyan(\"apps/web\")} - Next.js frontend (port 3000)`);\n console.log(` ${pc.cyan(\"apps/api\")} - NestJS backend (port 4000)`);\n console.log(` ${pc.cyan(\"packages/shared\")} - Shared types and constants`);\n console.log(` ${pc.cyan(\"docs/\")} - Project documentation`);\n console.log(` ${pc.cyan(\".cursor/rules/\")} - Cursor AI agent rules`);\n console.log();\n console.log(\"Next steps:\");\n console.log();\n console.log(` ${pc.cyan(\"cd\")} ${projectName}`);\n console.log(\n ` ${pc.cyan(packageManager === \"npm\" ? \"npm run\" : packageManager)} dev`\n );\n console.log();\n console.log(\"This will start both the frontend (port 3000) and backend (port 4000).\");\n console.log();\n console.log(\"Happy coding!\");\n console.log();\n}\n\nexport async function main(): Promise<void> {\n program\n .name(\"create-nene\")\n .description(\"Create a new nene.js monorepo with Next.js and NestJS\")\n .version(\"0.2.0\")\n .argument(\"[project-name]\", \"Name of the project\")\n .action(async (projectName: string | undefined) => {\n console.log();\n console.log(\n pc.bold(pc.cyan(\" nene.js \") + \"- The AI-native full-stack framework\")\n );\n console.log(pc.dim(\" Next.js + NestJS monorepo for AI-assisted development\"));\n console.log();\n\n const options = await promptForOptions(projectName);\n await createProject(options);\n });\n\n await program.parseAsync(process.argv);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { program } from \"commander\";\nimport prompts from \"prompts\";\nimport pc from \"picocolors\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { execSync } from \"node:child_process\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\ninterface ProjectOptions {\n projectName: string;\n packageManager: \"npm\" | \"yarn\" | \"pnpm\";\n}\n\nfunction validateProjectName(name: string): boolean {\n const validNameRegex =\n /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/;\n return validNameRegex.test(name);\n}\n\nfunction detectPackageManager(): \"npm\" | \"yarn\" | \"pnpm\" {\n const userAgent = process.env.npm_config_user_agent;\n if (userAgent) {\n if (userAgent.startsWith(\"yarn\")) return \"yarn\";\n if (userAgent.startsWith(\"pnpm\")) return \"pnpm\";\n }\n return \"pnpm\"; // Default to pnpm for monorepo\n}\n\nfunction isCommandAvailable(command: string): boolean {\n try {\n execSync(`${command} --version`, { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction ensurePackageManager(packageManager: \"npm\" | \"yarn\" | \"pnpm\"): boolean {\n if (isCommandAvailable(packageManager)) {\n return true;\n }\n\n console.log(\n pc.yellow(`\\n${packageManager} is not installed. Attempting to install...`)\n );\n\n // Try corepack first (built-in to Node.js 16.9+)\n if (isCommandAvailable(\"corepack\")) {\n try {\n console.log(pc.dim(` Using corepack to enable ${packageManager}...`));\n execSync(`corepack enable ${packageManager}`, { stdio: \"inherit\" });\n if (isCommandAvailable(packageManager)) {\n console.log(pc.green(` ✓ ${packageManager} installed via corepack\\n`));\n return true;\n }\n } catch {\n // corepack failed, try next method\n }\n }\n\n // Fallback: install via npm\n if (packageManager !== \"npm\" && isCommandAvailable(\"npm\")) {\n try {\n console.log(pc.dim(` Installing ${packageManager} globally via npm...`));\n execSync(`npm install -g ${packageManager}`, { stdio: \"inherit\" });\n if (isCommandAvailable(packageManager)) {\n console.log(pc.green(`\\n ✓ ${packageManager} installed via npm\\n`));\n return true;\n }\n } catch {\n // npm global install failed (possibly permission issue)\n }\n }\n\n // All methods failed\n console.log(\n pc.red(`\\n ✗ Failed to install ${packageManager} automatically.`)\n );\n console.log(\n pc.yellow(` Please install it manually:\\n`)\n );\n\n if (packageManager === \"pnpm\") {\n console.log(pc.dim(\" npm install -g pnpm\"));\n console.log(pc.dim(\" # or\"));\n console.log(pc.dim(\" corepack enable pnpm\"));\n console.log(pc.dim(\" # or\"));\n console.log(pc.dim(\" curl -fsSL https://get.pnpm.io/install.sh | sh -\"));\n } else if (packageManager === \"yarn\") {\n console.log(pc.dim(\" npm install -g yarn\"));\n console.log(pc.dim(\" # or\"));\n console.log(pc.dim(\" corepack enable yarn\"));\n }\n console.log();\n\n return false;\n}\n\nfunction copyDir(src: string, dest: string): void {\n fs.mkdirSync(dest, { recursive: true });\n const entries = fs.readdirSync(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const destPath = path.join(dest, entry.name);\n\n if (entry.isDirectory()) {\n copyDir(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n}\n\nfunction getTemplateDir(): string {\n // In development, templates are relative to src\n // In production (dist), templates are at the package root\n const devPath = path.resolve(__dirname, \"..\", \"templates\", \"default\");\n const prodPath = path.resolve(__dirname, \"..\", \"..\", \"templates\", \"default\");\n\n if (fs.existsSync(devPath)) return devPath;\n if (fs.existsSync(prodPath)) return prodPath;\n\n throw new Error(\"Template not found\");\n}\n\nfunction updatePackageJson(projectPath: string, projectName: string): void {\n const pkgPath = path.join(projectPath, \"package.json\");\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n pkg.name = projectName;\n fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n}\n\nfunction updateSubPackageNames(projectPath: string, projectName: string): void {\n // Update apps/web package.json\n const webPkgPath = path.join(projectPath, \"apps\", \"web\", \"package.json\");\n if (fs.existsSync(webPkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(webPkgPath, \"utf-8\"));\n pkg.name = `@${projectName}/web`;\n // Update shared package reference\n if (pkg.dependencies?.[\"@app/shared\"]) {\n pkg.dependencies[`@${projectName}/shared`] = pkg.dependencies[\"@app/shared\"];\n delete pkg.dependencies[\"@app/shared\"];\n }\n fs.writeFileSync(webPkgPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n }\n\n // Update apps/api package.json\n const apiPkgPath = path.join(projectPath, \"apps\", \"api\", \"package.json\");\n if (fs.existsSync(apiPkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(apiPkgPath, \"utf-8\"));\n pkg.name = `@${projectName}/api`;\n // Update shared package reference\n if (pkg.dependencies?.[\"@app/shared\"]) {\n pkg.dependencies[`@${projectName}/shared`] = pkg.dependencies[\"@app/shared\"];\n delete pkg.dependencies[\"@app/shared\"];\n }\n fs.writeFileSync(apiPkgPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n }\n\n // Update packages/shared package.json\n const sharedPkgPath = path.join(projectPath, \"packages\", \"shared\", \"package.json\");\n if (fs.existsSync(sharedPkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(sharedPkgPath, \"utf-8\"));\n pkg.name = `@${projectName}/shared`;\n fs.writeFileSync(sharedPkgPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n }\n\n // Update import statements in apps/web/src/app/page.tsx\n const pagePath = path.join(projectPath, \"apps\", \"web\", \"src\", \"app\", \"page.tsx\");\n if (fs.existsSync(pagePath)) {\n let content = fs.readFileSync(pagePath, \"utf-8\");\n content = content.replace(/@app\\/shared/g, `@${projectName}/shared`);\n fs.writeFileSync(pagePath, content);\n }\n\n // Update cursor rules to use correct package names\n const cursorRulesDir = path.join(projectPath, \".cursor\", \"rules\");\n if (fs.existsSync(cursorRulesDir)) {\n const ruleFiles = fs.readdirSync(cursorRulesDir);\n for (const file of ruleFiles) {\n const filePath = path.join(cursorRulesDir, file);\n let content = fs.readFileSync(filePath, \"utf-8\");\n content = content.replace(/@app\\/shared/g, `@${projectName}/shared`);\n fs.writeFileSync(filePath, content);\n }\n }\n\n // Update agent rule files to use correct package names\n const agentRuleFiles = [\n path.join(projectPath, \"AI_CONTEXT.md\"),\n path.join(projectPath, \"CLAUDE.md\"),\n path.join(projectPath, \"AGENTS.md\"),\n path.join(projectPath, \".github\", \"copilot-instructions.md\"),\n path.join(projectPath, \"apps\", \"web\", \"CLAUDE.md\"),\n path.join(projectPath, \"apps\", \"web\", \"AGENTS.md\"),\n path.join(projectPath, \"apps\", \"api\", \"CLAUDE.md\"),\n path.join(projectPath, \"apps\", \"api\", \"AGENTS.md\"),\n ];\n for (const filePath of agentRuleFiles) {\n if (fs.existsSync(filePath)) {\n let content = fs.readFileSync(filePath, \"utf-8\");\n content = content.replace(/@app\\/shared/g, `@${projectName}/shared`);\n fs.writeFileSync(filePath, content);\n }\n }\n\n // Update turbo.json filter names\n const rootPkgPath = path.join(projectPath, \"package.json\");\n if (fs.existsSync(rootPkgPath)) {\n let content = fs.readFileSync(rootPkgPath, \"utf-8\");\n content = content.replace(/@app\\/web/g, `@${projectName}/web`);\n content = content.replace(/@app\\/api/g, `@${projectName}/api`);\n fs.writeFileSync(rootPkgPath, content);\n }\n}\n\nfunction renameGitignore(projectPath: string): void {\n const gitignorePath = path.join(projectPath, \"_gitignore\");\n const targetPath = path.join(projectPath, \".gitignore\");\n if (fs.existsSync(gitignorePath)) {\n fs.renameSync(gitignorePath, targetPath);\n }\n}\n\nasync function promptForOptions(projectName?: string): Promise<ProjectOptions> {\n const defaultProjectName = projectName || \"my-nene-app\";\n\n const response = await prompts(\n [\n {\n type: projectName ? null : \"text\",\n name: \"projectName\",\n message: \"Project name:\",\n initial: defaultProjectName,\n validate: (value: string) => {\n if (!value) return \"Project name is required\";\n if (!validateProjectName(value)) {\n return \"Invalid project name. Use lowercase letters, numbers, and hyphens only.\";\n }\n return true;\n },\n },\n {\n type: \"select\",\n name: \"packageManager\",\n message: \"Select a package manager:\",\n choices: [\n {\n title: isCommandAvailable(\"pnpm\")\n ? \"pnpm (recommended)\"\n : \"pnpm (recommended, will be installed)\",\n value: \"pnpm\",\n },\n {\n title: isCommandAvailable(\"npm\")\n ? \"npm\"\n : \"npm (not found)\",\n value: \"npm\",\n },\n {\n title: isCommandAvailable(\"yarn\")\n ? \"yarn\"\n : \"yarn (will be installed)\",\n value: \"yarn\",\n },\n ],\n initial: 0,\n },\n ],\n {\n onCancel: () => {\n console.log(pc.red(\"\\nOperation cancelled.\"));\n process.exit(0);\n },\n }\n );\n\n return {\n projectName: projectName || response.projectName,\n packageManager: response.packageManager,\n };\n}\n\nasync function createProject(options: ProjectOptions): Promise<void> {\n const { projectName, packageManager } = options;\n const projectPath = path.resolve(process.cwd(), projectName);\n\n // Check if directory exists\n if (fs.existsSync(projectPath)) {\n const { overwrite } = await prompts({\n type: \"confirm\",\n name: \"overwrite\",\n message: `Directory \"${projectName}\" already exists. Overwrite?`,\n initial: false,\n });\n\n if (!overwrite) {\n console.log(pc.red(\"Operation cancelled.\"));\n process.exit(0);\n }\n\n fs.rmSync(projectPath, { recursive: true, force: true });\n }\n\n console.log();\n console.log(\n pc.cyan(`Creating a new nene.js monorepo in ${pc.bold(projectPath)}`)\n );\n console.log();\n\n // Copy template\n const templateDir = getTemplateDir();\n copyDir(templateDir, projectPath);\n\n // Rename _gitignore to .gitignore\n renameGitignore(projectPath);\n\n // Update package.json with project name\n updatePackageJson(projectPath, projectName);\n\n // Update sub-package names\n updateSubPackageNames(projectPath, projectName);\n\n // Ensure package manager is available\n const pmReady = ensurePackageManager(packageManager);\n\n if (!pmReady) {\n console.log(\n pc.yellow(\n `Skipping dependency installation. After installing ${packageManager}, run:`\n )\n );\n console.log(pc.dim(` cd ${projectName}`));\n console.log(pc.dim(` ${packageManager === \"npm\" ? \"npm install\" : packageManager === \"yarn\" ? \"yarn\" : \"pnpm install\"}`));\n console.log(pc.dim(` cd packages/shared && ${packageManager === \"npm\" ? \"npm run build\" : `${packageManager} build`}`));\n console.log();\n } else {\n // Install dependencies\n console.log(pc.cyan(\"Installing dependencies...\"));\n console.log();\n\n const installCmd = {\n npm: \"npm install\",\n yarn: \"yarn\",\n pnpm: \"pnpm install\",\n }[packageManager];\n\n try {\n execSync(installCmd, {\n cwd: projectPath,\n stdio: \"inherit\",\n });\n } catch {\n console.log(\n pc.yellow(\n \"\\nFailed to install dependencies. You can install them manually.\"\n )\n );\n }\n\n // Build shared package first\n console.log();\n console.log(pc.cyan(\"Building shared package...\"));\n\n try {\n const buildCmd = packageManager === \"npm\" ? \"npm run build\" : `${packageManager} build`;\n execSync(buildCmd, {\n cwd: path.join(projectPath, \"packages\", \"shared\"),\n stdio: \"inherit\",\n });\n } catch {\n console.log(\n pc.yellow(\n `\\nFailed to build shared package. Run '${packageManager === \"npm\" ? \"npm run build\" : `${packageManager} build`}' in packages/shared manually.`\n )\n );\n }\n }\n\n // Success message\n console.log();\n console.log(\n pc.green(\"Success!\") + ` Created ${pc.bold(projectName)} at ${projectPath}`\n );\n console.log();\n console.log(\"Project structure:\");\n console.log();\n console.log(` ${pc.cyan(\"apps/web\")} - Next.js frontend (port 3000)`);\n console.log(` ${pc.cyan(\"apps/api\")} - NestJS backend (port 4000)`);\n console.log(` ${pc.cyan(\"packages/shared\")} - Shared types and constants`);\n console.log(` ${pc.cyan(\"docs/\")} - Project documentation`);\n console.log(` ${pc.cyan(\"AI_CONTEXT.md\")} - Universal AI context (single source of truth)`);\n console.log(` ${pc.cyan(\".cursor/rules/\")} - Cursor AI agent rules`);\n console.log(` ${pc.cyan(\".github/\")} - GitHub Copilot instructions`);\n console.log(` ${pc.cyan(\"CLAUDE.md\")} - Claude Code agent rules`);\n console.log(` ${pc.cyan(\"AGENTS.md\")} - OpenAI Codex agent rules`);\n console.log();\n console.log(\"Next steps:\");\n console.log();\n console.log(` ${pc.cyan(\"cd\")} ${projectName}`);\n console.log(\n ` ${pc.cyan(packageManager === \"npm\" ? \"npm run\" : packageManager)} dev`\n );\n console.log();\n console.log(\"This will start both the frontend (port 3000) and backend (port 4000).\");\n console.log();\n console.log(\"Happy coding!\");\n console.log();\n}\n\nexport async function main(): Promise<void> {\n program\n .name(\"create-nene\")\n .description(\"Create a new nene.js monorepo with Next.js and NestJS\")\n .version(\"0.2.0\")\n .argument(\"[project-name]\", \"Name of the project\")\n .action(async (projectName: string | undefined) => {\n console.log();\n console.log(\n pc.bold(pc.cyan(\" nene.js \") + \"- The AI-native full-stack framework\")\n );\n console.log(pc.dim(\" Next.js + NestJS monorepo for AI-assisted development\"));\n console.log();\n\n const options = await promptForOptions(projectName);\n await createProject(options);\n });\n\n await program.parseAsync(process.argv);\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nene",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Create a new nene.js project with a single command",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,7 +8,7 @@ alwaysApply: true
8
8
  ## Project Structure
9
9
 
10
10
  This is a full-stack monorepo:
11
- - `apps/web/` - Next.js 15 frontend (port 3000)
11
+ - `apps/web/` - Next.js 16 frontend (port 3000)
12
12
  - `apps/api/` - NestJS 11 backend (port 4000)
13
13
  - `packages/shared/` - Shared types, DTOs, constants
14
14
 
@@ -0,0 +1,12 @@
1
+ # GitHub Copilot Instructions
2
+
3
+ > See `AI_CONTEXT.md` in the project root for full project context, structure, and patterns.
4
+
5
+ ## Key Rules
6
+
7
+ - **NEVER duplicate types.** Always import from `@app/shared`.
8
+ - Read `docs/overview/ARCHITECTURE.md` before making structural changes.
9
+ - Read `docs/kanban/README.md` for current task priorities.
10
+ - Update `docs/API.md` when adding/modifying endpoints.
11
+ - Move completed tasks in `docs/kanban/` (DOING -> DONE).
12
+ - Run `pnpm build` to verify shared package changes work.
@@ -0,0 +1,12 @@
1
+ # Codex Rules
2
+
3
+ > See `AI_CONTEXT.md` for full project context, structure, and patterns.
4
+
5
+ ## Key Rules
6
+
7
+ - **NEVER duplicate types.** Always import from `@app/shared`.
8
+ - Read `docs/overview/ARCHITECTURE.md` before making structural changes.
9
+ - Read `docs/kanban/README.md` for current task priorities.
10
+ - Update `docs/API.md` when adding/modifying endpoints.
11
+ - Move completed tasks in `docs/kanban/` (DOING -> DONE).
12
+ - Run `pnpm build` to verify shared package changes work.
@@ -0,0 +1,115 @@
1
+ # AI Context
2
+
3
+ > Universal project context for any AI coding agent. This is the single source of truth for understanding this project.
4
+
5
+ ## Project Structure
6
+
7
+ ```
8
+ ├── apps/
9
+ │ ├── web/ # Next.js 16 frontend (port 3000)
10
+ │ │ ├── src/app/ # App Router pages
11
+ │ │ └── src/ # Components, hooks, utils
12
+ │ └── api/ # NestJS 11 backend (port 4000)
13
+ │ └── src/ # Modules, controllers, services
14
+ ├── packages/
15
+ │ └── shared/ # Shared types, DTOs, constants (@app/shared)
16
+ ├── docs/ # AI-friendly documentation
17
+ │ ├── overview/
18
+ │ │ └── ARCHITECTURE.md # Full architecture details
19
+ │ ├── API.md # API endpoint reference
20
+ │ └── kanban/ # Task management (TODO/DOING/DONE)
21
+ ```
22
+
23
+ ## Tech Stack
24
+
25
+ | Layer | Technology | Version |
26
+ |-------|-----------|---------|
27
+ | Frontend | Next.js (App Router) | 16 |
28
+ | UI | React | 19 |
29
+ | Styling | Tailwind CSS | 4 |
30
+ | Backend | NestJS | 11 |
31
+ | Validation | class-validator | 0.14 |
32
+ | Build | Turborepo | 2 |
33
+ | Package Manager | pnpm | 10 |
34
+ | Language | TypeScript | 5 |
35
+
36
+ ## Design Patterns
37
+
38
+ ### Type Sharing (Critical Rule)
39
+
40
+ **NEVER duplicate types.** Types are defined once in `@app/shared` and imported by both apps:
41
+
42
+ ```typescript
43
+ // GOOD - import from shared
44
+ import { User, CreateUserDto } from '@app/shared';
45
+
46
+ // BAD - duplicating types
47
+ interface User { id: string; ... }
48
+ ```
49
+
50
+ ### Shared DTOs with Validation
51
+
52
+ ```typescript
53
+ import { IsEmail, IsString, MinLength } from 'class-validator';
54
+
55
+ export class CreateUserDto {
56
+ @IsEmail()
57
+ email: string;
58
+
59
+ @IsString()
60
+ @MinLength(8)
61
+ password: string;
62
+ }
63
+ ```
64
+
65
+ ### API Route Constants
66
+
67
+ ```typescript
68
+ import { API_ROUTES } from '@app/shared';
69
+ ```
70
+
71
+ ### NestJS Module Pattern
72
+
73
+ ```
74
+ apps/api/src/{feature}/
75
+ ├── {feature}.module.ts
76
+ ├── {feature}.controller.ts
77
+ ├── {feature}.service.ts
78
+ └── dto/
79
+ ```
80
+
81
+ ### Next.js Component Pattern
82
+
83
+ - Default: Server Component (no directive needed)
84
+ - Client Component: add `'use client'` at top
85
+ - API calls use `NEXT_PUBLIC_API_URL` env var + shared route constants
86
+
87
+ ## Quick Commands
88
+
89
+ ```bash
90
+ pnpm dev # Run all apps
91
+ pnpm dev:web # Run frontend only
92
+ pnpm dev:api # Run backend only
93
+ pnpm build # Build all
94
+ pnpm --filter @app/shared build # Rebuild shared package after changes
95
+ ```
96
+
97
+ ## Before Making Changes
98
+
99
+ 1. Read `docs/overview/ARCHITECTURE.md` for current patterns.
100
+ 2. Read `docs/API.md` for existing endpoints.
101
+ 3. Read `docs/kanban/README.md` for task priorities.
102
+
103
+ ## After Making Changes
104
+
105
+ 1. Update `docs/API.md` when adding/modifying endpoints.
106
+ 2. Move completed tasks in `docs/kanban/` (DOING -> DONE).
107
+ 3. Run `pnpm build` to verify shared package changes work.
108
+ 4. If you edited `apps/web/**`, verify: `curl -s -o /dev/null -w "%{http_code}" http://localhost:3000`
109
+ 5. If you edited `apps/api/**`, verify: `curl -s -o /dev/null -w "%{http_code}" http://localhost:4000/api/health`
110
+
111
+ ## Common Errors
112
+
113
+ - **"Cannot find module './XXX.js'"** in Next.js: Stale webpack cache. Run `rm -rf apps/web/.next` and restart.
114
+ - **Port already in use**: Check with `lsof -i :3000` or `lsof -i :4000`.
115
+ - **Shared package not found**: Rebuild with `pnpm --filter @app/shared build`.
@@ -0,0 +1,12 @@
1
+ # Claude Code Rules
2
+
3
+ > See `AI_CONTEXT.md` for full project context, structure, and patterns.
4
+
5
+ ## Key Rules
6
+
7
+ - **NEVER duplicate types.** Always import from `@app/shared`.
8
+ - Read `docs/overview/ARCHITECTURE.md` before making structural changes.
9
+ - Read `docs/kanban/README.md` for current task priorities.
10
+ - Update `docs/API.md` when adding/modifying endpoints.
11
+ - Move completed tasks in `docs/kanban/` (DOING -> DONE).
12
+ - Run `pnpm build` to verify shared package changes work.
@@ -10,7 +10,12 @@ A full-stack monorepo with Next.js frontend and NestJS backend.
10
10
  │ └── api/ # NestJS backend (port 4000)
11
11
  ├── packages/
12
12
  │ └── shared/ # Shared types, DTOs, utilities
13
- └── docs/ # Project documentation
13
+ ├── docs/ # Project documentation
14
+ ├── AI_CONTEXT.md # Universal AI context (single source of truth)
15
+ ├── .cursor/rules/ # Cursor AI agent rules
16
+ ├── .github/ # GitHub Copilot instructions
17
+ ├── CLAUDE.md # Claude Code agent rules
18
+ └── AGENTS.md # OpenAI Codex agent rules
14
19
  ```
15
20
 
16
21
  ## Getting Started
@@ -54,7 +59,21 @@ pnpm build
54
59
 
55
60
  ## Tech Stack
56
61
 
57
- - **Frontend**: Next.js 15, React 19, Tailwind CSS
62
+ - **Frontend**: Next.js 16, React 19, Tailwind CSS
58
63
  - **Backend**: NestJS 11, class-validator
59
64
  - **Shared**: TypeScript, shared types and DTOs
60
65
  - **Tooling**: Turborepo, pnpm workspaces
66
+
67
+ ## AI Agent Support
68
+
69
+ This project includes built-in configuration for AI coding assistants:
70
+
71
+ | Tool | Config File |
72
+ |------|------------|
73
+ | Any AI Agent | `AI_CONTEXT.md` (universal context) |
74
+ | Cursor | `.cursor/rules/*.mdc` |
75
+ | GitHub Copilot | `.github/copilot-instructions.md` |
76
+ | Claude Code | `CLAUDE.md` |
77
+ | OpenAI Codex | `AGENTS.md` |
78
+
79
+ `AI_CONTEXT.md` is the single source of truth. Tool-specific files are lightweight pointers that reference it.
@@ -0,0 +1,11 @@
1
+ # Backend (NestJS) - Codex Rules
2
+
3
+ > See `AI_CONTEXT.md` in the project root for full project context.
4
+
5
+ ## Backend-Specific Rules
6
+
7
+ - Follow the NestJS module pattern: `{feature}.module.ts`, `{feature}.controller.ts`, `{feature}.service.ts`.
8
+ - Use class-validator with shared DTOs from `@app/shared`.
9
+ - Use `@nestjs/config` for environment variables.
10
+ - Update `docs/API.md` when adding or modifying endpoints.
11
+ - Rebuild shared package after changes: `pnpm --filter @app/shared build`
@@ -0,0 +1,11 @@
1
+ # Backend (NestJS) - Claude Code Rules
2
+
3
+ > See `AI_CONTEXT.md` in the project root for full project context.
4
+
5
+ ## Backend-Specific Rules
6
+
7
+ - Follow the NestJS module pattern: `{feature}.module.ts`, `{feature}.controller.ts`, `{feature}.service.ts`.
8
+ - Use class-validator with shared DTOs from `@app/shared`.
9
+ - Use `@nestjs/config` for environment variables.
10
+ - Update `docs/API.md` when adding or modifying endpoints.
11
+ - Rebuild shared package after changes: `pnpm --filter @app/shared build`
@@ -0,0 +1,23 @@
1
+ # Frontend (Next.js) - Codex Rules
2
+
3
+ > See `AI_CONTEXT.md` in the project root for full project context.
4
+
5
+ ## Frontend-Specific Rules
6
+
7
+ - Default components are Server Components (no directive needed).
8
+ - Add `'use client'` at top for interactive components.
9
+ - Use Tailwind CSS for styling. Follow mobile-first responsive design.
10
+ - Import API routes from `@app/shared`: `import { API_ROUTES } from '@app/shared';`
11
+
12
+ ## Post-Edit Verification (REQUIRED)
13
+
14
+ After every edit to `apps/web/**`, verify the app still works:
15
+
16
+ ```bash
17
+ curl -s -o /dev/null -w "%{http_code}" http://localhost:3000
18
+ ```
19
+
20
+ ## Troubleshooting
21
+
22
+ - `Cannot find module './NNN.js'`: Run `rm -rf apps/web/.next` then restart dev server.
23
+ - `Invalid hook call`: Add `'use client'` directive or restructure.
@@ -0,0 +1,23 @@
1
+ # Frontend (Next.js) - Claude Code Rules
2
+
3
+ > See `AI_CONTEXT.md` in the project root for full project context.
4
+
5
+ ## Frontend-Specific Rules
6
+
7
+ - Default components are Server Components (no directive needed).
8
+ - Add `'use client'` at top for interactive components.
9
+ - Use Tailwind CSS for styling. Follow mobile-first responsive design.
10
+ - Import API routes from `@app/shared`: `import { API_ROUTES } from '@app/shared';`
11
+
12
+ ## Post-Edit Verification (REQUIRED)
13
+
14
+ After every edit to `apps/web/**`, verify the app still works:
15
+
16
+ ```bash
17
+ curl -s -o /dev/null -w "%{http_code}" http://localhost:3000
18
+ ```
19
+
20
+ ## Troubleshooting
21
+
22
+ - `Cannot find module './NNN.js'`: Run `rm -rf apps/web/.next` then restart dev server.
23
+ - `Invalid hook call`: Add `'use client'` directive or restructure.
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@app/shared": "workspace:*",
13
- "next": "^15.0.0",
13
+ "next": "^16.0.0",
14
14
  "react": "^19.0.0",
15
15
  "react-dom": "^19.0.0"
16
16
  },
@@ -20,7 +20,7 @@
20
20
  "@types/react-dom": "^19.0.0",
21
21
  "autoprefixer": "^10.4.20",
22
22
  "eslint": "^9.0.0",
23
- "eslint-config-next": "^15.0.0",
23
+ "eslint-config-next": "^16.0.0",
24
24
  "postcss": "^8.4.49",
25
25
  "tailwindcss": "^3.4.15",
26
26
  "typescript": "^5.7.0"
@@ -5,7 +5,7 @@ This document describes the architecture of this project for AI agents and devel
5
5
  ## Overview
6
6
 
7
7
  This is a full-stack monorepo with:
8
- - **Frontend**: Next.js 15 with React 19
8
+ - **Frontend**: Next.js 16 with React 19
9
9
  - **Backend**: NestJS 11 with class-validator
10
10
  - **Shared**: TypeScript types and constants
11
11