mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
feat(cli): update ruler addon with more mcp
This commit is contained in:
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
@@ -19,6 +19,8 @@ dist/
|
|||||||
.alchemy
|
.alchemy
|
||||||
/.next/
|
/.next/
|
||||||
.vercel
|
.vercel
|
||||||
|
prisma/generated/
|
||||||
|
|
||||||
|
|
||||||
# deps
|
# deps
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|||||||
Reference in New Issue
Block a user