diff --git a/apps/cli/package.json b/apps/cli/package.json index 7f59008..f320b63 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -1,88 +1,88 @@ { - "name": "create-better-t-stack", - "version": "2.41.3", - "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations", - "type": "module", - "license": "MIT", - "author": "Aman Varshney", - "bin": { - "create-better-t-stack": "dist/cli.js" - }, - "files": [ - "templates", - "dist" - ], - "keywords": [ - "better-t-stack", - "typescript", - "boilerplate", - "starter", - "cli", - "turborepo", - "trpc", - "better-auth", - "monorepo", - "fullstack", - "type-safety", - "react", - "react-native", - "expo", - "hono", - "elysia", - "drizzle", - "prisma", - "tanstack", - "tailwind", - "shadcn", - "pwa", - "tauri", - "biome" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/AmanVarshney01/create-better-t-stack.git", - "directory": "apps/cli" - }, - "publishConfig": { - "access": "public" - }, - "homepage": "https://better-t-stack.dev/", - "scripts": { - "build": "tsdown", - "dev": "tsdown --watch", - "check-types": "tsc --noEmit", - "check": "biome check --write .", - "test": "bun run build && vitest run", - "test:ui": "bun run build && vitest --ui", - "test:with-build": "bun run build && WITH_BUILD=1 vitest --ui", - "prepublishOnly": "npm run build" - }, - "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js" - } - }, - "dependencies": { - "@clack/prompts": "^1.0.0-alpha.4", - "consola": "^3.4.2", - "execa": "^9.6.0", - "fs-extra": "^11.3.1", - "gradient-string": "^3.0.0", - "handlebars": "^4.7.8", - "jsonc-parser": "^3.3.1", - "picocolors": "^1.1.1", - "tinyglobby": "^0.2.15", - "trpc-cli": "^0.10.2", - "ts-morph": "^27.0.0", - "zod": "^4.1.5" - }, - "devDependencies": { - "@types/fs-extra": "^11.0.4", - "@types/node": "^24.3.1", - "@vitest/ui": "^3.2.4", - "tsdown": "^0.14.2", - "typescript": "^5.9.2", - "vitest": "^3.2.4" - } + "name": "create-better-t-stack", + "version": "2.41.3", + "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations", + "type": "module", + "license": "MIT", + "author": "Aman Varshney", + "bin": { + "create-better-t-stack": "dist/cli.js" + }, + "files": [ + "templates", + "dist" + ], + "keywords": [ + "better-t-stack", + "typescript", + "boilerplate", + "starter", + "cli", + "turborepo", + "trpc", + "better-auth", + "monorepo", + "fullstack", + "type-safety", + "react", + "react-native", + "expo", + "hono", + "elysia", + "drizzle", + "prisma", + "tanstack", + "tailwind", + "shadcn", + "pwa", + "tauri", + "biome" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/AmanVarshney01/create-better-t-stack.git", + "directory": "apps/cli" + }, + "publishConfig": { + "access": "public" + }, + "homepage": "https://better-t-stack.dev/", + "scripts": { + "build": "tsdown", + "dev": "tsdown --watch", + "check-types": "tsc --noEmit", + "check": "biome check --write .", + "test": "bun run build && vitest run", + "test:ui": "bun run build && vitest --ui", + "test:with-build": "bun run build && WITH_BUILD=1 vitest --ui", + "prepublishOnly": "npm run build" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "dependencies": { + "@clack/prompts": "^1.0.0-alpha.4", + "consola": "^3.4.2", + "execa": "^9.6.0", + "fs-extra": "^11.3.1", + "gradient-string": "^3.0.0", + "handlebars": "^4.7.8", + "jsonc-parser": "^3.3.1", + "picocolors": "^1.1.1", + "tinyglobby": "^0.2.15", + "trpc-cli": "^0.10.2", + "ts-morph": "^27.0.0", + "zod": "^4.1.5" + }, + "devDependencies": { + "@types/fs-extra": "^11.0.4", + "@types/node": "^24.3.1", + "@vitest/ui": "^3.2.4", + "tsdown": "^0.14.2", + "typescript": "^5.9.2", + "vitest": "^3.2.4" + } } diff --git a/apps/cli/src/helpers/addons/addons-setup.ts b/apps/cli/src/helpers/addons/addons-setup.ts index 819c567..9791b98 100644 --- a/apps/cli/src/helpers/addons/addons-setup.ts +++ b/apps/cli/src/helpers/addons/addons-setup.ts @@ -7,7 +7,7 @@ import type { Frontend, PackageManager, ProjectConfig } from "../../types"; import { addPackageDependency } from "../../utils/add-package-deps"; import { getPackageExecutionCommand } from "../../utils/package-runner"; import { setupFumadocs } from "./fumadocs-setup"; -import { setupVibeRules } from "./ruler-setup"; +import { setupRuler } from "./ruler-setup"; import { setupStarlight } from "./starlight-setup"; import { setupTauri } from "./tauri-setup"; import { setupUltracite } from "./ultracite-setup"; @@ -88,7 +88,7 @@ ${pc.cyan("Docs:")} ${pc.underline("https://turborepo.com/docs")} } if (addons.includes("ruler")) { - await setupVibeRules(config); + await setupRuler(config); } if (addons.includes("fumadocs")) { await setupFumadocs(config); diff --git a/apps/cli/src/helpers/addons/ruler-setup.ts b/apps/cli/src/helpers/addons/ruler-setup.ts index b92cf4d..4bb03fa 100644 --- a/apps/cli/src/helpers/addons/ruler-setup.ts +++ b/apps/cli/src/helpers/addons/ruler-setup.ts @@ -8,74 +8,54 @@ import { import { execa } from "execa"; import fs from "fs-extra"; import pc from "picocolors"; -import { PKG_ROOT } from "../../constants"; import type { ProjectConfig } from "../../types"; import { exitCancelled } from "../../utils/errors"; import { getPackageExecutionCommand } from "../../utils/package-runner"; -import { processAndCopyFiles } from "../core/template-manager"; -export async function setupVibeRules(config: ProjectConfig) { +export async function setupRuler(config: ProjectConfig) { const { packageManager, projectDir } = config; try { log.info("Setting up Ruler..."); const rulerDir = path.join(projectDir, ".ruler"); - const rulerTemplateDir = path.join( - PKG_ROOT, - "templates", - "addons", - "ruler", - ".ruler", - ); if (!(await fs.pathExists(rulerDir))) { - if (await fs.pathExists(rulerTemplateDir)) { - await processAndCopyFiles("**/*", rulerTemplateDir, rulerDir, config); - } else { - log.error(pc.red("Ruler template directory not found")); - return; - } + log.error( + pc.red( + "Ruler template directory not found. Please ensure ruler addon is properly installed.", + ), + ); + return; } const EDITORS = { - cursor: { - label: "Cursor", - }, - windsurf: { - label: "Windsurf", - }, + amp: { label: "AMP" }, + copilot: { label: "GitHub Copilot" }, claude: { label: "Claude Code" }, - copilot: { - label: "GitHub Copilot", - }, - "gemini-cli": { label: "Gemini CLI" }, codex: { label: "OpenAI Codex CLI" }, - jules: { label: "Jules" }, + cursor: { label: "Cursor" }, + windsurf: { label: "Windsurf" }, cline: { label: "Cline" }, aider: { label: "Aider" }, firebase: { label: "Firebase Studio" }, - openhands: { label: "Open Hands" }, + "gemini-cli": { label: "Gemini CLI" }, junie: { label: "Junie" }, - augmentcode: { - label: "AugmentCode", - }, - kilocode: { - label: "Kilo Code", - }, + kilocode: { label: "Kilo Code" }, opencode: { label: "OpenCode" }, + crush: { label: "Crush" }, + zed: { label: "Zed" }, + qwen: { label: "Qwen" }, } as const; - const selectedEditors = await autocompleteMultiselect( - { - message: "Select AI assistants for Ruler", - options: Object.entries(EDITORS).map(([key, v]) => ({ - value: key as keyof typeof EDITORS, - label: v.label, - })), - required: false, - }, - ); + const selectedEditors = await autocompleteMultiselect({ + message: "Select AI assistants for Ruler", + options: Object.entries(EDITORS).map(([key, v]) => ({ + value: key, + label: v.label, + })), + required: false, + }); if (isCancel(selectedEditors)) return exitCancelled("Operation cancelled"); diff --git a/apps/cli/src/helpers/core/template-manager.ts b/apps/cli/src/helpers/core/template-manager.ts index 02c13ce..f6f8334 100644 --- a/apps/cli/src/helpers/core/template-manager.ts +++ b/apps/cli/src/helpers/core/template-manager.ts @@ -620,8 +620,6 @@ export async function setupAddonsTemplate( for (const addon of context.addons) { if (addon === "none") continue; - if (addon === "ruler") continue; - let addonSrcDir = path.join(PKG_ROOT, `templates/addons/${addon}`); let addonDestDir = projectDir; diff --git a/apps/cli/templates/addons/ruler/.ruler/mcp.json.hbs b/apps/cli/templates/addons/ruler/.ruler/mcp.json.hbs deleted file mode 100644 index d38c313..0000000 --- a/apps/cli/templates/addons/ruler/.ruler/mcp.json.hbs +++ /dev/null @@ -1,18 +0,0 @@ -{ - "mcpServers": { - "context7": { - "type": "stdio", - "command": "npx", - "args": ["-y", "@upstash/context7-mcp"] - }{{#if (or (eq runtime "workers") (eq webDeploy "wrangler"))}}, - "cloudflare": { - "command": "npx", - "args": ["mcp-remote", "https://docs.mcp.cloudflare.com/sse"] - }{{/if}}{{#if (eq backend "convex")}}, - "convex": { - "command": "npx", - "args": ["-y", "convex@latest", "mcp", "start"] - } - {{/if}} - } -} \ No newline at end of file diff --git a/apps/cli/templates/addons/ruler/.ruler/ruler.toml.hbs b/apps/cli/templates/addons/ruler/.ruler/ruler.toml.hbs index 3a738e5..37c4a28 100644 --- a/apps/cli/templates/addons/ruler/.ruler/ruler.toml.hbs +++ b/apps/cli/templates/addons/ruler/.ruler/ruler.toml.hbs @@ -2,4 +2,63 @@ # See https://okigu.com/ruler for documentation. # Default agents to run when --agents is not specified -default_agents = [] \ No newline at end of file +default_agents = [] + +# --- Global MCP Server Configuration --- +[mcp] +# Enable/disable MCP propagation globally (default: true) +enabled = true +# Global merge strategy: 'merge' or 'overwrite' (default: 'merge') +merge_strategy = "merge" + +# --- MCP Server Definitions --- +[mcp_servers.context7] +command = "npx" +args = ["-y", "@upstash/context7-mcp"] + +{{#if (or (eq runtime "workers") (eq webDeploy "wrangler"))}} +[mcp_servers.cloudflare] +command = "npx" +args = ["mcp-remote", "https://docs.mcp.cloudflare.com/sse"] +{{/if}} + +{{#if (eq backend "convex")}} +[mcp_servers.convex] +command = "npx" +args = ["-y", "convex@latest", "mcp", "start"] +{{/if}} + +{{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start") (includes frontend "next"))}} +[mcp_servers.shadcn] +command = "npx" +args = ["shadcn@latest", "mcp"] +{{/if}} + +{{#if (eq dbSetup "planetscale")}} +[mcp_servers.planetscale] +command = "pscale" +args = ["mcp", "server"] +{{/if}} + +{{#if (eq dbSetup "prisma-postgres")}} +[mcp_servers.prisma] +command = "npx" +args = ["-y", "prisma", "mcp"] +{{/if}} + +{{#if (eq dbSetup "neon")}} +[mcp_servers.neon] +command = "npx" +args = ["-y", "mcp-remote@latest", "https://mcp.neon.tech/mcp"] +{{/if}} + +{{#if (eq dbSetup "mongodb-atlas")}} +[mcp_servers.mongodb] +command = "npx" +args = ["-y", "mongodb-mcp-server", "--connectionString", "mongodb://localhost:27017/myDatabase", "--readOnly"] +{{/if}} + +# --- Global .gitignore Configuration --- +[gitignore] +# Enable/disable automatic .gitignore updates (default: true) +enabled = true \ No newline at end of file diff --git a/apps/cli/templates/backend/server/server-base/_gitignore b/apps/cli/templates/backend/server/server-base/_gitignore index 2ed07fc..fafd02d 100644 --- a/apps/cli/templates/backend/server/server-base/_gitignore +++ b/apps/cli/templates/backend/server/server-base/_gitignore @@ -19,6 +19,8 @@ dist/ .alchemy /.next/ .vercel +prisma/generated/ + # deps node_modules/