feat(cli): update ruler addon with more mcp

This commit is contained in:
Aman Varshney
2025-09-09 05:44:55 +05:30
parent 2f9eb1faca
commit d059d7de1d
7 changed files with 174 additions and 153 deletions

View File

@@ -1,88 +1,88 @@
{ {
"name": "create-better-t-stack", "name": "create-better-t-stack",
"version": "2.41.3", "version": "2.41.3",
"description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations", "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",
"author": "Aman Varshney", "author": "Aman Varshney",
"bin": { "bin": {
"create-better-t-stack": "dist/cli.js" "create-better-t-stack": "dist/cli.js"
}, },
"files": [ "files": [
"templates", "templates",
"dist" "dist"
], ],
"keywords": [ "keywords": [
"better-t-stack", "better-t-stack",
"typescript", "typescript",
"boilerplate", "boilerplate",
"starter", "starter",
"cli", "cli",
"turborepo", "turborepo",
"trpc", "trpc",
"better-auth", "better-auth",
"monorepo", "monorepo",
"fullstack", "fullstack",
"type-safety", "type-safety",
"react", "react",
"react-native", "react-native",
"expo", "expo",
"hono", "hono",
"elysia", "elysia",
"drizzle", "drizzle",
"prisma", "prisma",
"tanstack", "tanstack",
"tailwind", "tailwind",
"shadcn", "shadcn",
"pwa", "pwa",
"tauri", "tauri",
"biome" "biome"
], ],
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/AmanVarshney01/create-better-t-stack.git", "url": "git+https://github.com/AmanVarshney01/create-better-t-stack.git",
"directory": "apps/cli" "directory": "apps/cli"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
"homepage": "https://better-t-stack.dev/", "homepage": "https://better-t-stack.dev/",
"scripts": { "scripts": {
"build": "tsdown", "build": "tsdown",
"dev": "tsdown --watch", "dev": "tsdown --watch",
"check-types": "tsc --noEmit", "check-types": "tsc --noEmit",
"check": "biome check --write .", "check": "biome check --write .",
"test": "bun run build && vitest run", "test": "bun run build && vitest run",
"test:ui": "bun run build && vitest --ui", "test:ui": "bun run build && vitest --ui",
"test:with-build": "bun run build && WITH_BUILD=1 vitest --ui", "test:with-build": "bun run build && WITH_BUILD=1 vitest --ui",
"prepublishOnly": "npm run build" "prepublishOnly": "npm run build"
}, },
"exports": { "exports": {
".": { ".": {
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"import": "./dist/index.js" "import": "./dist/index.js"
} }
}, },
"dependencies": { "dependencies": {
"@clack/prompts": "^1.0.0-alpha.4", "@clack/prompts": "^1.0.0-alpha.4",
"consola": "^3.4.2", "consola": "^3.4.2",
"execa": "^9.6.0", "execa": "^9.6.0",
"fs-extra": "^11.3.1", "fs-extra": "^11.3.1",
"gradient-string": "^3.0.0", "gradient-string": "^3.0.0",
"handlebars": "^4.7.8", "handlebars": "^4.7.8",
"jsonc-parser": "^3.3.1", "jsonc-parser": "^3.3.1",
"picocolors": "^1.1.1", "picocolors": "^1.1.1",
"tinyglobby": "^0.2.15", "tinyglobby": "^0.2.15",
"trpc-cli": "^0.10.2", "trpc-cli": "^0.10.2",
"ts-morph": "^27.0.0", "ts-morph": "^27.0.0",
"zod": "^4.1.5" "zod": "^4.1.5"
}, },
"devDependencies": { "devDependencies": {
"@types/fs-extra": "^11.0.4", "@types/fs-extra": "^11.0.4",
"@types/node": "^24.3.1", "@types/node": "^24.3.1",
"@vitest/ui": "^3.2.4", "@vitest/ui": "^3.2.4",
"tsdown": "^0.14.2", "tsdown": "^0.14.2",
"typescript": "^5.9.2", "typescript": "^5.9.2",
"vitest": "^3.2.4" "vitest": "^3.2.4"
} }
} }

View File

@@ -7,7 +7,7 @@ import type { Frontend, PackageManager, ProjectConfig } from "../../types";
import { addPackageDependency } from "../../utils/add-package-deps"; import { addPackageDependency } from "../../utils/add-package-deps";
import { getPackageExecutionCommand } from "../../utils/package-runner"; import { getPackageExecutionCommand } from "../../utils/package-runner";
import { setupFumadocs } from "./fumadocs-setup"; import { setupFumadocs } from "./fumadocs-setup";
import { setupVibeRules } from "./ruler-setup"; import { setupRuler } from "./ruler-setup";
import { setupStarlight } from "./starlight-setup"; import { setupStarlight } from "./starlight-setup";
import { setupTauri } from "./tauri-setup"; import { setupTauri } from "./tauri-setup";
import { setupUltracite } from "./ultracite-setup"; import { setupUltracite } from "./ultracite-setup";
@@ -88,7 +88,7 @@ ${pc.cyan("Docs:")} ${pc.underline("https://turborepo.com/docs")}
} }
if (addons.includes("ruler")) { if (addons.includes("ruler")) {
await setupVibeRules(config); await setupRuler(config);
} }
if (addons.includes("fumadocs")) { if (addons.includes("fumadocs")) {
await setupFumadocs(config); await setupFumadocs(config);

View File

@@ -8,74 +8,54 @@ import {
import { execa } from "execa"; import { execa } from "execa";
import fs from "fs-extra"; import fs from "fs-extra";
import pc from "picocolors"; import pc from "picocolors";
import { PKG_ROOT } from "../../constants";
import type { ProjectConfig } from "../../types"; import type { ProjectConfig } from "../../types";
import { exitCancelled } from "../../utils/errors"; import { exitCancelled } from "../../utils/errors";
import { getPackageExecutionCommand } from "../../utils/package-runner"; 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; const { packageManager, projectDir } = config;
try { try {
log.info("Setting up Ruler..."); log.info("Setting up Ruler...");
const rulerDir = path.join(projectDir, ".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(rulerDir))) {
if (await fs.pathExists(rulerTemplateDir)) { log.error(
await processAndCopyFiles("**/*", rulerTemplateDir, rulerDir, config); pc.red(
} else { "Ruler template directory not found. Please ensure ruler addon is properly installed.",
log.error(pc.red("Ruler template directory not found")); ),
return; );
} return;
} }
const EDITORS = { const EDITORS = {
cursor: { amp: { label: "AMP" },
label: "Cursor", copilot: { label: "GitHub Copilot" },
},
windsurf: {
label: "Windsurf",
},
claude: { label: "Claude Code" }, claude: { label: "Claude Code" },
copilot: {
label: "GitHub Copilot",
},
"gemini-cli": { label: "Gemini CLI" },
codex: { label: "OpenAI Codex CLI" }, codex: { label: "OpenAI Codex CLI" },
jules: { label: "Jules" }, cursor: { label: "Cursor" },
windsurf: { label: "Windsurf" },
cline: { label: "Cline" }, cline: { label: "Cline" },
aider: { label: "Aider" }, aider: { label: "Aider" },
firebase: { label: "Firebase Studio" }, firebase: { label: "Firebase Studio" },
openhands: { label: "Open Hands" }, "gemini-cli": { label: "Gemini CLI" },
junie: { label: "Junie" }, junie: { label: "Junie" },
augmentcode: { kilocode: { label: "Kilo Code" },
label: "AugmentCode",
},
kilocode: {
label: "Kilo Code",
},
opencode: { label: "OpenCode" }, opencode: { label: "OpenCode" },
crush: { label: "Crush" },
zed: { label: "Zed" },
qwen: { label: "Qwen" },
} as const; } as const;
const selectedEditors = await autocompleteMultiselect<keyof typeof EDITORS>( const selectedEditors = await autocompleteMultiselect({
{ message: "Select AI assistants for Ruler",
message: "Select AI assistants for Ruler", options: Object.entries(EDITORS).map(([key, v]) => ({
options: Object.entries(EDITORS).map(([key, v]) => ({ value: key,
value: key as keyof typeof EDITORS, label: v.label,
label: v.label, })),
})), required: false,
required: false, });
},
);
if (isCancel(selectedEditors)) return exitCancelled("Operation cancelled"); if (isCancel(selectedEditors)) return exitCancelled("Operation cancelled");

View File

@@ -620,8 +620,6 @@ export async function setupAddonsTemplate(
for (const addon of context.addons) { for (const addon of context.addons) {
if (addon === "none") continue; if (addon === "none") continue;
if (addon === "ruler") continue;
let addonSrcDir = path.join(PKG_ROOT, `templates/addons/${addon}`); let addonSrcDir = path.join(PKG_ROOT, `templates/addons/${addon}`);
let addonDestDir = projectDir; let addonDestDir = projectDir;

View File

@@ -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}}
}
}

View File

@@ -3,3 +3,62 @@
# Default agents to run when --agents is not specified # Default agents to run when --agents is not specified
default_agents = [] 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

View File

@@ -19,6 +19,8 @@ dist/
.alchemy .alchemy
/.next/ /.next/
.vercel .vercel
prisma/generated/
# deps # deps
node_modules/ node_modules/