create-better-t-stack 3.40.0 → 3.40.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/README.md CHANGED
@@ -78,6 +78,7 @@ Options:
78
78
  --package-manager <pm> Package manager (npm, pnpm, bun)
79
79
  --install Install dependencies
80
80
  --no-install Skip installing dependencies
81
+ --open <target> Open in an editor, IDE, or coding agent after creation
81
82
  --db-setup <setup> Database setup (turso, d1, neon, supabase, prisma-postgres, planetscale, mongodb-atlas, docker, none)
82
83
  --web-deploy <setup> Web deployment (cloudflare, docker, vercel, none)
83
84
  --server-deploy <setup> Server deployment (cloudflare, docker, vercel, none)
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { _ as types_exports, i as SchemaNameSchema, l as create, m as getSchemaResult, s as add, u as createBtsCli, v as getLatestCLIVersion } from "./src-DjuxSWWY.mjs";
2
+ import { i as SchemaNameSchema, l as create, m as getSchemaResult, s as add, u as createBtsCli, v as types_exports, y as getLatestCLIVersion } from "./src-DBE8djc0.mjs";
3
3
  import z from "zod";
4
4
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
5
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
package/dist/index.d.mts CHANGED
@@ -96,6 +96,39 @@ declare class DatabaseSetupError extends DatabaseSetupError_base<{
96
96
  });
97
97
  }
98
98
  //#endregion
99
+ //#region src/utils/project-launcher.d.ts
100
+ declare const ProjectLauncherSchema: z.ZodEnum<{
101
+ none: "none";
102
+ cursor: "cursor";
103
+ vscode: "vscode";
104
+ "vscode-insiders": "vscode-insiders";
105
+ zed: "zed";
106
+ windsurf: "windsurf";
107
+ vscodium: "vscodium";
108
+ webstorm: "webstorm";
109
+ "intellij-idea": "intellij-idea";
110
+ "sublime-text": "sublime-text";
111
+ neovim: "neovim";
112
+ "codex-app": "codex-app";
113
+ codex: "codex";
114
+ "claude-code": "claude-code";
115
+ opencode: "opencode";
116
+ pi: "pi";
117
+ "gemini-cli": "gemini-cli";
118
+ "github-copilot": "github-copilot";
119
+ "kiro-cli": "kiro-cli";
120
+ droid: "droid";
121
+ goose: "goose";
122
+ cline: "cline";
123
+ continue: "continue";
124
+ amp: "amp";
125
+ aider: "aider";
126
+ "qwen-code": "qwen-code";
127
+ crush: "crush";
128
+ "cursor-agent": "cursor-agent";
129
+ }>;
130
+ type ProjectLauncher = z.infer<typeof ProjectLauncherSchema>;
131
+ //#endregion
99
132
  //#region src/helpers/core/command-handlers.d.ts
100
133
  /**
101
134
  * Result type for project creation
@@ -175,6 +208,7 @@ declare const router: import("@trpc/server").TRPCBuiltRouter<{
175
208
  git?: boolean | undefined;
176
209
  packageManager?: "bun" | "npm" | "pnpm" | undefined;
177
210
  install?: boolean | undefined;
211
+ open?: "none" | "cursor" | "vscode" | "vscode-insiders" | "zed" | "windsurf" | "vscodium" | "webstorm" | "intellij-idea" | "sublime-text" | "neovim" | "codex-app" | "codex" | "claude-code" | "opencode" | "pi" | "gemini-cli" | "github-copilot" | "kiro-cli" | "droid" | "goose" | "cline" | "continue" | "amp" | "aider" | "qwen-code" | "crush" | "cursor-agent" | undefined;
178
212
  dbSetup?: "none" | "turso" | "neon" | "prisma-postgres" | "planetscale" | "mongodb-atlas" | "supabase" | "d1" | "docker" | undefined;
179
213
  backend?: "none" | "hono" | "express" | "fastify" | "elysia" | "convex" | "self" | undefined;
180
214
  runtime?: "none" | "bun" | "node" | "workers" | undefined;
@@ -231,11 +265,11 @@ declare const router: import("@trpc/server").TRPCBuiltRouter<{
231
265
  mcp?: {
232
266
  scope?: "project" | "global" | undefined;
233
267
  servers?: ("nx" | "better-auth" | "clerk" | "polar" | "neon" | "planetscale" | "supabase" | "convex" | "better-t-stack" | "context7" | "cloudflare-docs" | "shadcn" | "next-devtools" | "nuxt-docs" | "nuxt-ui-docs" | "svelte-docs" | "astro-docs" | "expo")[] | undefined;
234
- agents?: ("antigravity" | "cline" | "cline-cli" | "cursor" | "claude-code" | "codex" | "opencode" | "gemini-cli" | "github-copilot-cli" | "grok-build" | "mcporter" | "vscode" | "windsurf" | "zed" | "claude-desktop" | "goose")[] | undefined;
268
+ agents?: ("cursor" | "vscode" | "zed" | "windsurf" | "codex" | "claude-code" | "opencode" | "gemini-cli" | "goose" | "cline" | "antigravity" | "cline-cli" | "github-copilot-cli" | "grok-build" | "mcporter" | "claude-desktop")[] | undefined;
235
269
  } | undefined;
236
270
  skills?: {
237
271
  scope?: "project" | "global" | undefined;
238
- agents?: ("antigravity" | "cline" | "cursor" | "claude-code" | "codex" | "opencode" | "gemini-cli" | "windsurf" | "zed" | "goose" | "universal" | "adal" | "aider-desk" | "amp" | "antigravity-cli" | "astrbot" | "augment" | "autohand-code" | "bob" | "codearts-agent" | "codebuddy" | "codemaker" | "codestudio" | "command-code" | "continue" | "cortex" | "crush" | "deepagents" | "devin" | "dexto" | "droid" | "eve" | "firebender" | "forgecode" | "github-copilot" | "grok" | "hermes-agent" | "iflow-cli" | "inference-sh" | "jazz" | "junie" | "kilo" | "kimchi" | "kimi-code-cli" | "kiro-cli" | "kode" | "lingma" | "loaf" | "mcpjam" | "mistral-vibe" | "moxby" | "mux" | "neovate" | "ona" | "clawdbot" | "openclaw" | "openhands" | "pi" | "pochi" | "promptscript" | "qoder" | "qoder-cn" | "qwen-code" | "reasonix" | "replit" | "roo" | "rovodev" | "tabnine-cli" | "terramind" | "tinycloud" | "trae" | "trae-cn" | "warp" | "zcode" | "zencoder" | "zenflow")[] | undefined;
272
+ agents?: ("cursor" | "zed" | "windsurf" | "codex" | "claude-code" | "opencode" | "pi" | "gemini-cli" | "github-copilot" | "kiro-cli" | "droid" | "goose" | "cline" | "continue" | "amp" | "qwen-code" | "crush" | "antigravity" | "universal" | "adal" | "aider-desk" | "antigravity-cli" | "astrbot" | "augment" | "autohand-code" | "bob" | "codearts-agent" | "codebuddy" | "codemaker" | "codestudio" | "command-code" | "cortex" | "deepagents" | "devin" | "dexto" | "eve" | "firebender" | "forgecode" | "grok" | "hermes-agent" | "iflow-cli" | "inference-sh" | "jazz" | "junie" | "kilo" | "kimchi" | "kimi-code-cli" | "kode" | "lingma" | "loaf" | "mcpjam" | "mistral-vibe" | "moxby" | "mux" | "neovate" | "ona" | "clawdbot" | "openclaw" | "openhands" | "pochi" | "promptscript" | "qoder" | "qoder-cn" | "reasonix" | "replit" | "roo" | "rovodev" | "tabnine-cli" | "terramind" | "tinycloud" | "trae" | "trae-cn" | "warp" | "zcode" | "zencoder" | "zenflow")[] | undefined;
239
273
  selections?: {
240
274
  source: "vercel-labs/agent-skills" | "vercel/ai" | "vercel/turborepo" | "yusukebe/hono-skill" | "vercel-labs/next-skills" | "nuxt/ui" | "heroui-inc/heroui" | "shadcn/ui" | "better-auth/skills" | "clerk/skills" | "neondatabase/agent-skills" | "supabase/agent-skills" | "planetscale/database-skills" | "expo/skills" | "prisma/skills" | "elysiajs/skills" | "waynesutton/convexskills" | "msmps/opentui-skill" | "haydenbleasel/ultracite" | "https://www.evlog.dev";
241
275
  skills: string[];
@@ -243,8 +277,8 @@ declare const router: import("@trpc/server").TRPCBuiltRouter<{
243
277
  } | undefined;
244
278
  ultracite?: {
245
279
  linter?: "biome" | "oxlint" | undefined;
246
- editors?: ("void" | "antigravity" | "cursor" | "vscode" | "windsurf" | "zed" | "bob" | "codebuddy" | "trae" | "kiro")[] | undefined;
247
- agents?: ("vercel" | "cline" | "codex" | "opencode" | "goose" | "universal" | "adal" | "amp" | "bob" | "continue" | "crush" | "deepagents" | "devin" | "droid" | "firebender" | "junie" | "mcpjam" | "mistral-vibe" | "mux" | "ona" | "openclaw" | "pi" | "qoder" | "replit" | "warp" | "zencoder" | "claude" | "jules" | "lovable" | "snowflake-cortex" | "kimi-cli" | "copilot" | "aider" | "firebase-studio" | "open-hands" | "gemini" | "augmentcode" | "kilo-code" | "roo-code" | "qwen" | "amazon-q-cli" | "cursor-cli")[] | undefined;
280
+ editors?: ("void" | "cursor" | "vscode" | "zed" | "windsurf" | "antigravity" | "bob" | "codebuddy" | "trae" | "kiro")[] | undefined;
281
+ agents?: ("codex" | "opencode" | "pi" | "droid" | "goose" | "cline" | "continue" | "amp" | "aider" | "crush" | "vercel" | "universal" | "adal" | "bob" | "deepagents" | "devin" | "firebender" | "junie" | "mcpjam" | "mistral-vibe" | "mux" | "ona" | "openclaw" | "qoder" | "replit" | "warp" | "zencoder" | "claude" | "jules" | "lovable" | "snowflake-cortex" | "kimi-cli" | "copilot" | "firebase-studio" | "open-hands" | "gemini" | "augmentcode" | "kilo-code" | "roo-code" | "qwen" | "amazon-q-cli" | "cursor-cli")[] | undefined;
248
282
  hooks?: ("cursor" | "windsurf" | "codebuddy" | "claude" | "copilot")[] | undefined;
249
283
  } | undefined;
250
284
  } | undefined;
@@ -342,11 +376,11 @@ declare const router: import("@trpc/server").TRPCBuiltRouter<{
342
376
  mcp?: {
343
377
  scope?: "project" | "global" | undefined;
344
378
  servers?: ("nx" | "better-auth" | "clerk" | "polar" | "neon" | "planetscale" | "supabase" | "convex" | "better-t-stack" | "context7" | "cloudflare-docs" | "shadcn" | "next-devtools" | "nuxt-docs" | "nuxt-ui-docs" | "svelte-docs" | "astro-docs" | "expo")[] | undefined;
345
- agents?: ("antigravity" | "cline" | "cline-cli" | "cursor" | "claude-code" | "codex" | "opencode" | "gemini-cli" | "github-copilot-cli" | "grok-build" | "mcporter" | "vscode" | "windsurf" | "zed" | "claude-desktop" | "goose")[] | undefined;
379
+ agents?: ("cursor" | "vscode" | "zed" | "windsurf" | "codex" | "claude-code" | "opencode" | "gemini-cli" | "goose" | "cline" | "antigravity" | "cline-cli" | "github-copilot-cli" | "grok-build" | "mcporter" | "claude-desktop")[] | undefined;
346
380
  } | undefined;
347
381
  skills?: {
348
382
  scope?: "project" | "global" | undefined;
349
- agents?: ("antigravity" | "cline" | "cursor" | "claude-code" | "codex" | "opencode" | "gemini-cli" | "windsurf" | "zed" | "goose" | "universal" | "adal" | "aider-desk" | "amp" | "antigravity-cli" | "astrbot" | "augment" | "autohand-code" | "bob" | "codearts-agent" | "codebuddy" | "codemaker" | "codestudio" | "command-code" | "continue" | "cortex" | "crush" | "deepagents" | "devin" | "dexto" | "droid" | "eve" | "firebender" | "forgecode" | "github-copilot" | "grok" | "hermes-agent" | "iflow-cli" | "inference-sh" | "jazz" | "junie" | "kilo" | "kimchi" | "kimi-code-cli" | "kiro-cli" | "kode" | "lingma" | "loaf" | "mcpjam" | "mistral-vibe" | "moxby" | "mux" | "neovate" | "ona" | "clawdbot" | "openclaw" | "openhands" | "pi" | "pochi" | "promptscript" | "qoder" | "qoder-cn" | "qwen-code" | "reasonix" | "replit" | "roo" | "rovodev" | "tabnine-cli" | "terramind" | "tinycloud" | "trae" | "trae-cn" | "warp" | "zcode" | "zencoder" | "zenflow")[] | undefined;
383
+ agents?: ("cursor" | "zed" | "windsurf" | "codex" | "claude-code" | "opencode" | "pi" | "gemini-cli" | "github-copilot" | "kiro-cli" | "droid" | "goose" | "cline" | "continue" | "amp" | "qwen-code" | "crush" | "antigravity" | "universal" | "adal" | "aider-desk" | "antigravity-cli" | "astrbot" | "augment" | "autohand-code" | "bob" | "codearts-agent" | "codebuddy" | "codemaker" | "codestudio" | "command-code" | "cortex" | "deepagents" | "devin" | "dexto" | "eve" | "firebender" | "forgecode" | "grok" | "hermes-agent" | "iflow-cli" | "inference-sh" | "jazz" | "junie" | "kilo" | "kimchi" | "kimi-code-cli" | "kode" | "lingma" | "loaf" | "mcpjam" | "mistral-vibe" | "moxby" | "mux" | "neovate" | "ona" | "clawdbot" | "openclaw" | "openhands" | "pochi" | "promptscript" | "qoder" | "qoder-cn" | "reasonix" | "replit" | "roo" | "rovodev" | "tabnine-cli" | "terramind" | "tinycloud" | "trae" | "trae-cn" | "warp" | "zcode" | "zencoder" | "zenflow")[] | undefined;
350
384
  selections?: {
351
385
  source: "vercel-labs/agent-skills" | "vercel/ai" | "vercel/turborepo" | "yusukebe/hono-skill" | "vercel-labs/next-skills" | "nuxt/ui" | "heroui-inc/heroui" | "shadcn/ui" | "better-auth/skills" | "clerk/skills" | "neondatabase/agent-skills" | "supabase/agent-skills" | "planetscale/database-skills" | "expo/skills" | "prisma/skills" | "elysiajs/skills" | "waynesutton/convexskills" | "msmps/opentui-skill" | "haydenbleasel/ultracite" | "https://www.evlog.dev";
352
386
  skills: string[];
@@ -354,8 +388,8 @@ declare const router: import("@trpc/server").TRPCBuiltRouter<{
354
388
  } | undefined;
355
389
  ultracite?: {
356
390
  linter?: "biome" | "oxlint" | undefined;
357
- editors?: ("void" | "antigravity" | "cursor" | "vscode" | "windsurf" | "zed" | "bob" | "codebuddy" | "trae" | "kiro")[] | undefined;
358
- agents?: ("vercel" | "cline" | "codex" | "opencode" | "goose" | "universal" | "adal" | "amp" | "bob" | "continue" | "crush" | "deepagents" | "devin" | "droid" | "firebender" | "junie" | "mcpjam" | "mistral-vibe" | "mux" | "ona" | "openclaw" | "pi" | "qoder" | "replit" | "warp" | "zencoder" | "claude" | "jules" | "lovable" | "snowflake-cortex" | "kimi-cli" | "copilot" | "aider" | "firebase-studio" | "open-hands" | "gemini" | "augmentcode" | "kilo-code" | "roo-code" | "qwen" | "amazon-q-cli" | "cursor-cli")[] | undefined;
391
+ editors?: ("void" | "cursor" | "vscode" | "zed" | "windsurf" | "antigravity" | "bob" | "codebuddy" | "trae" | "kiro")[] | undefined;
392
+ agents?: ("codex" | "opencode" | "pi" | "droid" | "goose" | "cline" | "continue" | "amp" | "aider" | "crush" | "vercel" | "universal" | "adal" | "bob" | "deepagents" | "devin" | "firebender" | "junie" | "mcpjam" | "mistral-vibe" | "mux" | "ona" | "openclaw" | "qoder" | "replit" | "warp" | "zencoder" | "claude" | "jules" | "lovable" | "snowflake-cortex" | "kimi-cli" | "copilot" | "firebase-studio" | "open-hands" | "gemini" | "augmentcode" | "kilo-code" | "roo-code" | "qwen" | "amazon-q-cli" | "cursor-cli")[] | undefined;
359
393
  hooks?: ("cursor" | "windsurf" | "codebuddy" | "claude" | "copilot")[] | undefined;
360
394
  } | undefined;
361
395
  } | undefined;
@@ -478,4 +512,4 @@ type Runtime = import__better_t_stack_types.Runtime;
478
512
  type ServerDeploy = import__better_t_stack_types.ServerDeploy;
479
513
  type Template = import__better_t_stack_types.Template;
480
514
  type WebDeploy = import__better_t_stack_types.WebDeploy;
481
- export { type API, AddOptions, type AddResult, type AddonOptions, type Addons, type Auth, type Backend, type BetterTStackConfig, CLIError, CompatibilityError, CreateError, type CreateInput, type Database, type DatabaseSetup, DatabaseSetupError, type DbSetupOptions, type DirectoryConflict, DirectoryConflictError, EMBEDDED_TEMPLATES, type Examples, type Frontend, GeneratorError, type GeneratorOptions, type InitResult, type ORM, type PackageManager, type Payments, type ProjectConfig, ProjectCreationError, Result, type Runtime, SchemaName, SchemaNameSchema, type ServerDeploy, TEMPLATE_COUNT, type Template, UserCancelledError, ValidationError, type VirtualDirectory, type VirtualFile, VirtualFileSystem, type VirtualFileTree, type VirtualNode, type WebDeploy, add, builder, create, createBtsCli, createVirtual, docs, generate, getSchemaResult, router, sponsors };
515
+ export { type API, AddOptions, type AddResult, type AddonOptions, type Addons, type Auth, type Backend, type BetterTStackConfig, CLIError, CompatibilityError, CreateError, type CreateInput, type Database, type DatabaseSetup, DatabaseSetupError, type DbSetupOptions, type DirectoryConflict, DirectoryConflictError, EMBEDDED_TEMPLATES, type Examples, type Frontend, GeneratorError, type GeneratorOptions, type InitResult, type ORM, type PackageManager, type Payments, type ProjectConfig, ProjectCreationError, type ProjectLauncher, ProjectLauncherSchema, Result, type Runtime, SchemaName, SchemaNameSchema, type ServerDeploy, TEMPLATE_COUNT, type Template, UserCancelledError, ValidationError, type VirtualDirectory, type VirtualFile, VirtualFileSystem, type VirtualFileTree, type VirtualNode, type WebDeploy, add, builder, create, createBtsCli, createVirtual, docs, generate, getSchemaResult, router, sponsors };
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { C as ProjectCreationError, S as DirectoryConflictError, T as ValidationError, a as TEMPLATE_COUNT, b as CompatibilityError, c as builder, d as createVirtual, f as docs, g as sponsors, h as router, i as SchemaNameSchema, l as create, m as getSchemaResult, n as GeneratorError, o as VirtualFileSystem, p as generate, r as Result, s as add, t as EMBEDDED_TEMPLATES, u as createBtsCli, w as UserCancelledError, x as DatabaseSetupError, y as CLIError } from "./src-DjuxSWWY.mjs";
3
- export { CLIError, CompatibilityError, DatabaseSetupError, DirectoryConflictError, EMBEDDED_TEMPLATES, GeneratorError, ProjectCreationError, Result, SchemaNameSchema, TEMPLATE_COUNT, UserCancelledError, ValidationError, VirtualFileSystem, add, builder, create, createBtsCli, createVirtual, docs, generate, getSchemaResult, router, sponsors };
2
+ import { C as DirectoryConflictError, E as ValidationError, S as DatabaseSetupError, T as UserCancelledError, _ as ProjectLauncherSchema, a as TEMPLATE_COUNT, b as CLIError, c as builder, d as createVirtual, f as docs, g as sponsors, h as router, i as SchemaNameSchema, l as create, m as getSchemaResult, n as GeneratorError, o as VirtualFileSystem, p as generate, r as Result, s as add, t as EMBEDDED_TEMPLATES, u as createBtsCli, w as ProjectCreationError, x as CompatibilityError } from "./src-DBE8djc0.mjs";
3
+ export { CLIError, CompatibilityError, DatabaseSetupError, DirectoryConflictError, EMBEDDED_TEMPLATES, GeneratorError, ProjectCreationError, ProjectLauncherSchema, Result, SchemaNameSchema, TEMPLATE_COUNT, UserCancelledError, ValidationError, VirtualFileSystem, add, builder, create, createBtsCli, createVirtual, docs, generate, getSchemaResult, router, sponsors };
@@ -6313,6 +6313,321 @@ async function findAvailableIncrementedPath(currentPathInput) {
6313
6313
  }
6314
6314
  }
6315
6315
  //#endregion
6316
+ //#region src/utils/command-exists.ts
6317
+ async function commandExists(command) {
6318
+ const result = await Result.tryPromise({
6319
+ try: async () => {
6320
+ if (process.platform === "win32") return (await $({ reject: false })`where ${command}`).exitCode === 0;
6321
+ return (await $({ reject: false })`which ${command}`).exitCode === 0;
6322
+ },
6323
+ catch: () => false
6324
+ });
6325
+ return result.isOk() ? result.value : false;
6326
+ }
6327
+ //#endregion
6328
+ //#region src/utils/project-launcher.ts
6329
+ const ProjectLauncherSchema = z.enum([
6330
+ "cursor",
6331
+ "vscode",
6332
+ "vscode-insiders",
6333
+ "zed",
6334
+ "windsurf",
6335
+ "vscodium",
6336
+ "webstorm",
6337
+ "intellij-idea",
6338
+ "sublime-text",
6339
+ "neovim",
6340
+ "codex-app",
6341
+ "codex",
6342
+ "claude-code",
6343
+ "opencode",
6344
+ "pi",
6345
+ "gemini-cli",
6346
+ "github-copilot",
6347
+ "kiro-cli",
6348
+ "droid",
6349
+ "goose",
6350
+ "cline",
6351
+ "continue",
6352
+ "amp",
6353
+ "aider",
6354
+ "qwen-code",
6355
+ "crush",
6356
+ "cursor-agent",
6357
+ "none"
6358
+ ]).describe("Editor, IDE, or coding agent to open after creating the project");
6359
+ const PROJECT_LAUNCHERS = [
6360
+ {
6361
+ id: "cursor",
6362
+ label: "Cursor",
6363
+ kind: "editor",
6364
+ commands: ["cursor"],
6365
+ args: (projectDir) => [projectDir]
6366
+ },
6367
+ {
6368
+ id: "vscode",
6369
+ label: "Visual Studio Code",
6370
+ kind: "editor",
6371
+ commands: ["code"],
6372
+ args: (projectDir) => [projectDir]
6373
+ },
6374
+ {
6375
+ id: "vscode-insiders",
6376
+ label: "Visual Studio Code Insiders",
6377
+ kind: "editor",
6378
+ commands: ["code-insiders"],
6379
+ args: (projectDir) => [projectDir]
6380
+ },
6381
+ {
6382
+ id: "zed",
6383
+ label: "Zed",
6384
+ kind: "editor",
6385
+ commands: ["zed", "zeditor"],
6386
+ args: (projectDir) => [projectDir]
6387
+ },
6388
+ {
6389
+ id: "windsurf",
6390
+ label: "Windsurf",
6391
+ kind: "editor",
6392
+ commands: ["windsurf"],
6393
+ args: (projectDir) => [projectDir]
6394
+ },
6395
+ {
6396
+ id: "vscodium",
6397
+ label: "VSCodium",
6398
+ kind: "editor",
6399
+ commands: ["codium"],
6400
+ args: (projectDir) => [projectDir]
6401
+ },
6402
+ {
6403
+ id: "webstorm",
6404
+ label: "JetBrains WebStorm",
6405
+ kind: "editor",
6406
+ commands: [
6407
+ "webstorm",
6408
+ "webstorm64.exe",
6409
+ "webstorm.bat",
6410
+ "webstorm.sh"
6411
+ ],
6412
+ args: (projectDir) => [projectDir]
6413
+ },
6414
+ {
6415
+ id: "intellij-idea",
6416
+ label: "JetBrains IntelliJ IDEA",
6417
+ kind: "editor",
6418
+ commands: [
6419
+ "idea",
6420
+ "intellij-idea",
6421
+ "idea64.exe",
6422
+ "idea.bat",
6423
+ "idea.sh"
6424
+ ],
6425
+ args: (projectDir) => [projectDir]
6426
+ },
6427
+ {
6428
+ id: "sublime-text",
6429
+ label: "Sublime Text",
6430
+ kind: "editor",
6431
+ commands: ["subl"],
6432
+ args: (projectDir) => [projectDir]
6433
+ },
6434
+ {
6435
+ id: "neovim",
6436
+ label: "Neovim",
6437
+ kind: "editor",
6438
+ commands: ["nvim"],
6439
+ args: () => ["."],
6440
+ cwd: (projectDir) => projectDir
6441
+ },
6442
+ {
6443
+ id: "codex-app",
6444
+ label: "Codex app",
6445
+ kind: "agent",
6446
+ commands: ["codex"],
6447
+ args: (projectDir) => ["app", projectDir],
6448
+ platforms: ["darwin"]
6449
+ },
6450
+ {
6451
+ id: "codex",
6452
+ label: "Codex CLI",
6453
+ kind: "agent",
6454
+ commands: ["codex"],
6455
+ cwd: (projectDir) => projectDir
6456
+ },
6457
+ {
6458
+ id: "claude-code",
6459
+ label: "Claude Code",
6460
+ kind: "agent",
6461
+ commands: ["claude"],
6462
+ cwd: (projectDir) => projectDir
6463
+ },
6464
+ {
6465
+ id: "opencode",
6466
+ label: "OpenCode",
6467
+ kind: "agent",
6468
+ commands: ["opencode"],
6469
+ cwd: (projectDir) => projectDir
6470
+ },
6471
+ {
6472
+ id: "pi",
6473
+ label: "Pi",
6474
+ kind: "agent",
6475
+ commands: ["pi"],
6476
+ cwd: (projectDir) => projectDir
6477
+ },
6478
+ {
6479
+ id: "gemini-cli",
6480
+ label: "Gemini CLI",
6481
+ kind: "agent",
6482
+ commands: ["gemini"],
6483
+ cwd: (projectDir) => projectDir
6484
+ },
6485
+ {
6486
+ id: "github-copilot",
6487
+ label: "GitHub Copilot CLI",
6488
+ kind: "agent",
6489
+ commands: ["copilot"],
6490
+ cwd: (projectDir) => projectDir
6491
+ },
6492
+ {
6493
+ id: "kiro-cli",
6494
+ label: "Kiro CLI",
6495
+ kind: "agent",
6496
+ commands: ["kiro-cli"],
6497
+ cwd: (projectDir) => projectDir
6498
+ },
6499
+ {
6500
+ id: "droid",
6501
+ label: "Factory Droid",
6502
+ kind: "agent",
6503
+ commands: ["droid"],
6504
+ cwd: (projectDir) => projectDir
6505
+ },
6506
+ {
6507
+ id: "goose",
6508
+ label: "goose",
6509
+ kind: "agent",
6510
+ commands: ["goose"],
6511
+ args: () => ["session"],
6512
+ cwd: (projectDir) => projectDir
6513
+ },
6514
+ {
6515
+ id: "cline",
6516
+ label: "Cline CLI",
6517
+ kind: "agent",
6518
+ commands: ["cline"],
6519
+ cwd: (projectDir) => projectDir,
6520
+ platforms: ["darwin", "linux"]
6521
+ },
6522
+ {
6523
+ id: "continue",
6524
+ label: "Continue CLI",
6525
+ kind: "agent",
6526
+ commands: ["cn"],
6527
+ cwd: (projectDir) => projectDir
6528
+ },
6529
+ {
6530
+ id: "amp",
6531
+ label: "Amp",
6532
+ kind: "agent",
6533
+ commands: ["amp"],
6534
+ cwd: (projectDir) => projectDir
6535
+ },
6536
+ {
6537
+ id: "aider",
6538
+ label: "Aider",
6539
+ kind: "agent",
6540
+ commands: ["aider"],
6541
+ cwd: (projectDir) => projectDir
6542
+ },
6543
+ {
6544
+ id: "qwen-code",
6545
+ label: "Qwen Code",
6546
+ kind: "agent",
6547
+ commands: ["qwen"],
6548
+ cwd: (projectDir) => projectDir
6549
+ },
6550
+ {
6551
+ id: "crush",
6552
+ label: "Crush",
6553
+ kind: "agent",
6554
+ commands: ["crush"],
6555
+ cwd: (projectDir) => projectDir
6556
+ },
6557
+ {
6558
+ id: "cursor-agent",
6559
+ label: "Cursor Agent",
6560
+ kind: "agent",
6561
+ commands: ["cursor-agent"],
6562
+ cwd: (projectDir) => projectDir
6563
+ }
6564
+ ];
6565
+ async function detectProjectLaunchers(projectDir, detectCommand = commandExists, platform = process.platform) {
6566
+ const supportedDefinitions = PROJECT_LAUNCHERS.filter(({ platforms }) => platforms === void 0 || platforms.includes(platform));
6567
+ const commands = [...new Set(supportedDefinitions.flatMap(({ commands }) => commands))];
6568
+ const detectedCommands = new Map(await Promise.all(commands.map(async (command) => [command, await detectCommand(command)])));
6569
+ return supportedDefinitions.flatMap((launcher) => {
6570
+ const command = launcher.commands.find((candidate) => detectedCommands.get(candidate));
6571
+ if (!command) return [];
6572
+ return [{
6573
+ id: launcher.id,
6574
+ label: launcher.label,
6575
+ kind: launcher.kind,
6576
+ command,
6577
+ args: launcher.args?.(projectDir) ?? [],
6578
+ cwd: launcher.cwd?.(projectDir)
6579
+ }];
6580
+ });
6581
+ }
6582
+ async function getProjectLauncherChoice(requestedLauncher, projectDir, options = {}) {
6583
+ if (requestedLauncher === "none") return Result.ok(void 0);
6584
+ if (!requestedLauncher && options.prompt === false) return Result.ok(void 0);
6585
+ const availableLaunchers = await detectProjectLaunchers(projectDir, options.detectCommand, options.platform);
6586
+ if (requestedLauncher) {
6587
+ const launcher = availableLaunchers.find(({ id }) => id === requestedLauncher);
6588
+ if (launcher) return Result.ok(launcher);
6589
+ const definition = PROJECT_LAUNCHERS.find(({ id }) => id === requestedLauncher);
6590
+ return Result.err(new CLIError({ message: `${definition?.label ?? requestedLauncher} is not installed or its command is not available in PATH.` }));
6591
+ }
6592
+ if (availableLaunchers.length === 0) return Result.ok(void 0);
6593
+ setIsFirstPrompt(true);
6594
+ try {
6595
+ const selected = await navigableSelect({
6596
+ message: "Open project with?",
6597
+ options: [...availableLaunchers.map(({ id, label, kind }) => ({
6598
+ value: id,
6599
+ label,
6600
+ hint: kind === "editor" ? "editor / IDE" : "coding agent"
6601
+ })), {
6602
+ value: "none",
6603
+ label: "Not now"
6604
+ }],
6605
+ initialValue: "none",
6606
+ maxItems: 12
6607
+ });
6608
+ if (isCancel$1(selected) || selected === "none") return Result.ok(void 0);
6609
+ return Result.ok(availableLaunchers.find(({ id }) => id === selected));
6610
+ } finally {
6611
+ setIsFirstPrompt(false);
6612
+ }
6613
+ }
6614
+ const runCommand = async (command, args, options) => {
6615
+ await execa(command, args, options);
6616
+ };
6617
+ async function launchProject(launcher, options = {}) {
6618
+ if (options.skipExternalCommands ?? shouldSkipExternalCommands()) return Result.ok(void 0);
6619
+ return Result.tryPromise({
6620
+ try: () => (options.runner ?? runCommand)(launcher.command, launcher.args, {
6621
+ cwd: launcher.cwd,
6622
+ stdio: launcher.cwd ? "inherit" : "ignore"
6623
+ }),
6624
+ catch: (cause) => new CLIError({
6625
+ message: `Could not open the project with ${launcher.label}.`,
6626
+ cause
6627
+ })
6628
+ });
6629
+ }
6630
+ //#endregion
6316
6631
  //#region src/utils/project-name-validation.ts
6317
6632
  function validateProjectName(name) {
6318
6633
  const hardeningResult = validateAgentSafePathInput(name, "projectName");
@@ -6668,18 +6983,6 @@ function getDatabaseUrl(database, projectName) {
6668
6983
  }
6669
6984
  }
6670
6985
  //#endregion
6671
- //#region src/utils/command-exists.ts
6672
- async function commandExists(command) {
6673
- const result = await Result.tryPromise({
6674
- try: async () => {
6675
- if (process.platform === "win32") return (await $({ reject: false })`where ${command}`).exitCode === 0;
6676
- return (await $({ reject: false })`which ${command}`).exitCode === 0;
6677
- },
6678
- catch: () => false
6679
- });
6680
- return result.isOk() ? result.value : false;
6681
- }
6682
- //#endregion
6683
6986
  //#region src/helpers/database-providers/mongodb-atlas-setup.ts
6684
6987
  async function checkAtlasCLI() {
6685
6988
  const exists = await commandExists("atlas");
@@ -8629,10 +8932,20 @@ async function createProjectHandlerInternal(input, startTime, timeScaffolded) {
8629
8932
  const historyCommand = getCliSubcommandCommand("history", config.packageManager);
8630
8933
  log.message(`${pc.dim("Setup saved to history")}\n${pc.cyan(historyCommand)}`);
8631
8934
  }
8935
+ let projectLauncher;
8936
+ if (!isSilent()) {
8937
+ const launcherResult = await getProjectLauncherChoice(input.open, config.projectDir, { prompt: !input.yes && process.env.CI === void 0 && process.stdin.isTTY === true && process.stdout.isTTY === true });
8938
+ if (launcherResult.isErr()) log.warn(pc.yellow(launcherResult.error.message));
8939
+ else projectLauncher = launcherResult.value;
8940
+ }
8632
8941
  const elapsedTimeMs = Date.now() - startTime;
8633
8942
  if (!isSilent()) {
8634
8943
  const elapsedTimeInSeconds = (elapsedTimeMs / 1e3).toFixed(1);
8635
8944
  outro(pc.magenta(`Project ready in ${pc.bold(`${elapsedTimeInSeconds}s`)}`));
8945
+ if (projectLauncher) {
8946
+ const launchResult = await launchProject(projectLauncher);
8947
+ if (launchResult.isErr()) log.warn(pc.yellow(launchResult.error.message));
8948
+ }
8636
8949
  }
8637
8950
  return Result.ok({
8638
8951
  success: true,
@@ -8787,6 +9100,7 @@ const router = t.router({
8787
9100
  git: z.boolean().optional(),
8788
9101
  packageManager: types_exports.PackageManagerSchema.optional(),
8789
9102
  install: z.boolean().optional(),
9103
+ open: ProjectLauncherSchema.optional(),
8790
9104
  dbSetup: types_exports.DatabaseSetupSchema.optional(),
8791
9105
  backend: types_exports.BackendSchema.optional(),
8792
9106
  runtime: types_exports.RuntimeSchema.optional(),
@@ -9025,4 +9339,4 @@ async function add(options = {}) {
9025
9339
  };
9026
9340
  }
9027
9341
  //#endregion
9028
- export { ProjectCreationError as C, DirectoryConflictError as S, ValidationError as T, types_exports as _, TEMPLATE_COUNT as a, CompatibilityError as b, builder as c, createVirtual as d, docs as f, sponsors as g, router as h, SchemaNameSchema as i, create as l, getSchemaResult as m, GeneratorError$1 as n, VirtualFileSystem$1 as o, generate$1 as p, Result$1 as r, add as s, EMBEDDED_TEMPLATES$1 as t, createBtsCli as u, getLatestCLIVersion as v, UserCancelledError as w, DatabaseSetupError as x, CLIError as y };
9342
+ export { DirectoryConflictError as C, ValidationError as E, DatabaseSetupError as S, UserCancelledError as T, ProjectLauncherSchema as _, TEMPLATE_COUNT as a, CLIError as b, builder as c, createVirtual as d, docs as f, sponsors as g, router as h, SchemaNameSchema as i, create as l, getSchemaResult as m, GeneratorError$1 as n, VirtualFileSystem$1 as o, generate$1 as p, Result$1 as r, add as s, EMBEDDED_TEMPLATES$1 as t, createBtsCli as u, types_exports as v, ProjectCreationError as w, CompatibilityError as x, getLatestCLIVersion as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-t-stack",
3
- "version": "3.40.0",
3
+ "version": "3.40.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",
@@ -69,8 +69,8 @@
69
69
  "prepublishOnly": "npm run build"
70
70
  },
71
71
  "dependencies": {
72
- "@better-t-stack/template-generator": "^3.40.0",
73
- "@better-t-stack/types": "^3.40.0",
72
+ "@better-t-stack/template-generator": "^3.40.1",
73
+ "@better-t-stack/types": "^3.40.1",
74
74
  "@clack/core": "^1.4.3",
75
75
  "@clack/prompts": "^1.7.0",
76
76
  "@modelcontextprotocol/sdk": "1.30.0",