create-better-t-stack 3.14.0 → 3.14.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.
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { o as createBtsCli } from "./src-BRi63IDG.mjs";
2
+ import { o as createBtsCli } from "./src-CSz9J82Z.mjs";
3
3
 
4
4
  //#region src/cli.ts
5
5
  createBtsCli().run();
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { a as create, c as docs, d as sponsors, i as builder, l as generateVirtualProject, n as TEMPLATE_COUNT, o as createBtsCli, r as VirtualFileSystem, s as createVirtual, t as EMBEDDED_TEMPLATES, u as router } from "./src-BRi63IDG.mjs";
2
+ import { a as create, c as docs, d as sponsors, i as builder, l as generateVirtualProject, n as TEMPLATE_COUNT, o as createBtsCli, r as VirtualFileSystem, s as createVirtual, t as EMBEDDED_TEMPLATES, u as router } from "./src-CSz9J82Z.mjs";
3
3
 
4
4
  export { EMBEDDED_TEMPLATES, TEMPLATE_COUNT, VirtualFileSystem, builder, create, createBtsCli, createVirtual, docs, generateVirtualProject, router, sponsors };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as __reExport } from "./chunk-DPg_XC7m.mjs";
3
- import { cancel, confirm, group, intro, isCancel, log, multiselect, outro, select, spinner, text } from "@clack/prompts";
3
+ import { autocompleteMultiselect, cancel, confirm, group, intro, isCancel, log, multiselect, outro, select, spinner, text } from "@clack/prompts";
4
4
  import { createRouterClient, os } from "@orpc/server";
5
5
  import pc from "picocolors";
6
6
  import { createCli } from "trpc-cli";
@@ -2149,6 +2149,21 @@ const addPackageDependency = async (opts) => {
2149
2149
  //#endregion
2150
2150
  //#region src/utils/package-runner.ts
2151
2151
  /**
2152
+ * Returns the appropriate command for running a package without installing it globally,
2153
+ * based on the selected package manager.
2154
+ *
2155
+ * @param packageManager - The selected package manager (e.g., 'npm', 'yarn', 'pnpm', 'bun').
2156
+ * @param commandWithArgs - The command to run, including arguments (e.g., "prisma generate --schema=./prisma/schema.prisma").
2157
+ * @returns The full command string (e.g., "npx prisma generate --schema=./prisma/schema.prisma").
2158
+ */
2159
+ function getPackageExecutionCommand(packageManager, commandWithArgs) {
2160
+ switch (packageManager) {
2161
+ case "pnpm": return `pnpm dlx ${commandWithArgs}`;
2162
+ case "bun": return `bunx ${commandWithArgs}`;
2163
+ default: return `npx ${commandWithArgs}`;
2164
+ }
2165
+ }
2166
+ /**
2152
2167
  * Returns the command and arguments as an array for use with execa's $ template syntax.
2153
2168
  * This avoids the need for shell: true and provides better escaping.
2154
2169
  *
@@ -2286,6 +2301,97 @@ async function setupOxlint(projectDir, packageManager) {
2286
2301
  s.stop("oxlint and oxfmt initialized successfully!");
2287
2302
  }
2288
2303
 
2304
+ //#endregion
2305
+ //#region src/helpers/addons/ruler-setup.ts
2306
+ async function setupRuler(config) {
2307
+ const { packageManager, projectDir } = config;
2308
+ try {
2309
+ log.info("Setting up Ruler...");
2310
+ const rulerDir = path.join(projectDir, ".ruler");
2311
+ if (!await fs.pathExists(rulerDir)) {
2312
+ log.error(pc.red("Ruler template directory not found. Please ensure ruler addon is properly installed."));
2313
+ return;
2314
+ }
2315
+ const selectedEditors = await autocompleteMultiselect({
2316
+ message: "Select AI assistants for Ruler",
2317
+ options: Object.entries({
2318
+ agentsmd: { label: "Agents.md" },
2319
+ aider: { label: "Aider" },
2320
+ amazonqcli: { label: "Amazon Q CLI" },
2321
+ amp: { label: "AMP" },
2322
+ antigravity: { label: "Antigravity" },
2323
+ augmentcode: { label: "AugmentCode" },
2324
+ claude: { label: "Claude Code" },
2325
+ cline: { label: "Cline" },
2326
+ codex: { label: "OpenAI Codex CLI" },
2327
+ copilot: { label: "GitHub Copilot" },
2328
+ crush: { label: "Crush" },
2329
+ cursor: { label: "Cursor" },
2330
+ firebase: { label: "Firebase Studio" },
2331
+ firebender: { label: "Firebender" },
2332
+ "gemini-cli": { label: "Gemini CLI" },
2333
+ goose: { label: "Goose" },
2334
+ jules: { label: "Jules" },
2335
+ junie: { label: "Junie" },
2336
+ kilocode: { label: "Kilo Code" },
2337
+ kiro: { label: "Kiro" },
2338
+ mistral: { label: "Mistral" },
2339
+ opencode: { label: "OpenCode" },
2340
+ openhands: { label: "Open Hands" },
2341
+ qwen: { label: "Qwen" },
2342
+ roo: { label: "RooCode" },
2343
+ trae: { label: "Trae AI" },
2344
+ warp: { label: "Warp" },
2345
+ windsurf: { label: "Windsurf" },
2346
+ zed: { label: "Zed" }
2347
+ }).map(([key, v]) => ({
2348
+ value: key,
2349
+ label: v.label
2350
+ })),
2351
+ required: false
2352
+ });
2353
+ if (isCancel(selectedEditors)) return exitCancelled("Operation cancelled");
2354
+ if (selectedEditors.length === 0) {
2355
+ log.info("No AI assistants selected. To apply rules later, run:");
2356
+ log.info(pc.cyan(`${getPackageExecutionCommand(packageManager, "@intellectronica/ruler@latest apply --local-only")}`));
2357
+ return;
2358
+ }
2359
+ const configFile = path.join(rulerDir, "ruler.toml");
2360
+ let updatedConfig = await fs.readFile(configFile, "utf-8");
2361
+ const defaultAgentsLine = `default_agents = [${selectedEditors.map((editor) => `"${editor}"`).join(", ")}]`;
2362
+ updatedConfig = updatedConfig.replace(/default_agents = \[\]/, defaultAgentsLine);
2363
+ await fs.writeFile(configFile, updatedConfig);
2364
+ await addRulerScriptToPackageJson(projectDir, packageManager);
2365
+ const s = spinner();
2366
+ s.start("Applying rules with Ruler...");
2367
+ try {
2368
+ const rulerApplyArgs = getPackageExecutionArgs(packageManager, `@intellectronica/ruler@latest apply --agents ${selectedEditors.join(",")} --local-only`);
2369
+ await $({
2370
+ cwd: projectDir,
2371
+ env: { CI: "true" }
2372
+ })`${rulerApplyArgs}`;
2373
+ s.stop("Applied rules with Ruler");
2374
+ } catch {
2375
+ s.stop(pc.red("Failed to apply rules"));
2376
+ }
2377
+ } catch (error) {
2378
+ log.error(pc.red("Failed to set up Ruler"));
2379
+ if (error instanceof Error) console.error(pc.red(error.message));
2380
+ }
2381
+ }
2382
+ async function addRulerScriptToPackageJson(projectDir, packageManager) {
2383
+ const rootPackageJsonPath = path.join(projectDir, "package.json");
2384
+ if (!await fs.pathExists(rootPackageJsonPath)) {
2385
+ log.warn("Root package.json not found, skipping ruler:apply script addition");
2386
+ return;
2387
+ }
2388
+ const packageJson = await fs.readJson(rootPackageJsonPath);
2389
+ if (!packageJson.scripts) packageJson.scripts = {};
2390
+ const rulerApplyCommand = getPackageExecutionCommand(packageManager, "@intellectronica/ruler@latest apply --local-only");
2391
+ packageJson.scripts["ruler:apply"] = rulerApplyCommand;
2392
+ await fs.writeJson(rootPackageJsonPath, packageJson, { spaces: 2 });
2393
+ }
2394
+
2289
2395
  //#endregion
2290
2396
  //#region src/helpers/addons/starlight-setup.ts
2291
2397
  async function setupStarlight(config) {
@@ -2632,6 +2738,7 @@ async function setupAddons(config) {
2632
2738
  if (addons.includes("opentui")) await setupTui(config);
2633
2739
  if (addons.includes("wxt")) await setupWxt(config);
2634
2740
  if (hasUltracite) await setupUltracite(config, hasHusky);
2741
+ if (addons.includes("ruler")) await setupRuler(config);
2635
2742
  }
2636
2743
  async function setupBiome(projectDir) {
2637
2744
  await addPackageDependency({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-t-stack",
3
- "version": "3.14.0",
3
+ "version": "3.14.1",
4
4
  "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
5
5
  "keywords": [
6
6
  "better-auth",
@@ -70,8 +70,8 @@
70
70
  "prepublishOnly": "npm run build"
71
71
  },
72
72
  "dependencies": {
73
- "@better-t-stack/template-generator": "^3.14.0",
74
- "@better-t-stack/types": "^3.14.0",
73
+ "@better-t-stack/template-generator": "^3.14.1",
74
+ "@better-t-stack/types": "^3.14.1",
75
75
  "@clack/core": "^0.5.0",
76
76
  "@clack/prompts": "^1.0.0-alpha.8",
77
77
  "@orpc/server": "^1.13.0",