create-better-t-stack 3.40.4 → 3.40.5

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 { i as SchemaNameSchema, l as create, m as getSchemaResult, s as add, u as createBtsCli, v as types_exports, y as getLatestCLIVersion } from "./src-CpGAduw0.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-E3yd8mxg.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";
@@ -79,7 +79,7 @@ function getStackGuidance() {
79
79
  "For project creation, build a full explicit config before calling bts_plan_project.",
80
80
  "Always call bts_plan_project before bts_create_project.",
81
81
  "Only call bts_create_project after the plan succeeds and matches the user's intent.",
82
- "Use bts_plan_addons before bts_add_addons for existing projects."
82
+ "Use bts_plan_addons before bts_add_addons when adding addons or scaffolding a workspace package in an existing project."
83
83
  ],
84
84
  createContract: {
85
85
  requiresExplicitFields: [
@@ -224,12 +224,12 @@ function createBtsMcpServer() {
224
224
  }
225
225
  });
226
226
  server.registerTool("bts_plan_addons", {
227
- title: "Plan Better T Stack Addons",
228
- description: "Validate and preview addon installation for an existing Better T Stack project without writing files. Always use this before bts_add_addons when the addon set or nested options are uncertain.",
227
+ title: "Plan Better T Stack Project Additions",
228
+ description: "Validate and preview addon installation or workspace package scaffolding for an existing Better T Stack project without writing files. Always use this before bts_add_addons.",
229
229
  inputSchema: types_exports.AddInputSchema,
230
230
  outputSchema: ToolResponseSchema,
231
231
  annotations: {
232
- title: "Plan Better T Stack Addons",
232
+ title: "Plan Better T Stack Project Additions",
233
233
  readOnlyHint: true,
234
234
  destructiveHint: false,
235
235
  idempotentHint: true,
@@ -241,19 +241,19 @@ function createBtsMcpServer() {
241
241
  ...input,
242
242
  dryRun: true
243
243
  });
244
- if (!result?.success) return formatToolError(result?.error ?? "Failed to plan addon installation");
244
+ if (!result?.success) return formatToolError(result?.error ?? "Failed to plan project additions");
245
245
  return formatToolSuccess(result);
246
246
  } catch (error) {
247
247
  return formatToolError(error);
248
248
  }
249
249
  });
250
250
  server.registerTool("bts_add_addons", {
251
- title: "Add Better T Stack Addons",
252
- description: "Install addons into an existing Better T Stack project using the same silent flow as add-json. Call this only after bts_plan_addons succeeds and the planned changes match the user's intent.",
251
+ title: "Apply Better T Stack Project Additions",
252
+ description: "Install addons or scaffold a workspace package in an existing Better T Stack project using the same silent flow as add-json. Call this only after bts_plan_addons succeeds and the planned changes match the user's intent.",
253
253
  inputSchema: types_exports.AddInputSchema,
254
254
  outputSchema: ToolResponseSchema,
255
255
  annotations: {
256
- title: "Add Better T Stack Addons",
256
+ title: "Apply Better T Stack Project Additions",
257
257
  destructiveHint: true,
258
258
  idempotentHint: false,
259
259
  openWorldHint: true
@@ -261,7 +261,7 @@ function createBtsMcpServer() {
261
261
  }, async (input) => {
262
262
  try {
263
263
  const result = await add(input);
264
- if (!result?.success) return formatToolError(result?.error ?? "Failed to add addons");
264
+ if (!result?.success) return formatToolError(result?.error ?? "Failed to update project");
265
265
  return formatToolSuccess(result);
266
266
  } catch (error) {
267
267
  return formatToolError(error);
package/dist/index.d.mts CHANGED
@@ -153,6 +153,7 @@ interface AddResult {
153
153
  projectDir: string;
154
154
  dryRun?: boolean;
155
155
  plannedFileCount?: number;
156
+ addedPackage?: string;
156
157
  error?: string;
157
158
  }
158
159
  //#endregion
@@ -349,6 +350,7 @@ declare const router: import("@trpc/server").TRPCBuiltRouter<{
349
350
  add: import("@trpc/server").TRPCMutationProcedure<{
350
351
  input: {
351
352
  addons?: ("none" | "pwa" | "tauri" | "electrobun" | "starlight" | "biome" | "lefthook" | "husky" | "mcp" | "turborepo" | "nx" | "vite-plus" | "fumadocs" | "ultracite" | "oxlint" | "opentui" | "wxt" | "skills" | "evlog")[] | undefined;
353
+ package?: string | undefined;
352
354
  install?: boolean | undefined;
353
355
  packageManager?: "bun" | "npm" | "pnpm" | undefined;
354
356
  projectDir?: string | undefined;
@@ -360,6 +362,7 @@ declare const router: import("@trpc/server").TRPCBuiltRouter<{
360
362
  addJson: import("@trpc/server").TRPCMutationProcedure<{
361
363
  input: {
362
364
  addons?: ("none" | "pwa" | "tauri" | "electrobun" | "starlight" | "biome" | "lefthook" | "husky" | "mcp" | "turborepo" | "nx" | "vite-plus" | "fumadocs" | "ultracite" | "oxlint" | "opentui" | "wxt" | "skills" | "evlog")[] | undefined;
365
+ package?: string | undefined;
363
366
  addonOptions?: {
364
367
  wxt?: {
365
368
  template: "svelte" | "solid" | "vanilla" | "vue" | "react";
@@ -473,9 +476,9 @@ declare function builder(): Promise<void>;
473
476
  * ```
474
477
  */
475
478
  declare function createVirtual(options: Partial<Omit<types_d_exports.ProjectConfig, "projectDir" | "relativePath">>): Promise<Result$1<VirtualFileTree$1, GeneratorError$1>>;
476
- type AddOptions = Pick<types_d_exports.AddInput, "addons" | "addonOptions" | "install" | "packageManager" | "projectDir" | "dryRun">;
479
+ type AddOptions = Pick<types_d_exports.AddInput, "addons" | "addonOptions" | "package" | "install" | "packageManager" | "projectDir" | "dryRun">;
477
480
  /**
478
- * Programmatic API to add addons to an existing Better-T-Stack project.
481
+ * Programmatic API to add addons or a workspace package to an existing Better-T-Stack project.
479
482
  *
480
483
  * @example
481
484
  * ```typescript
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
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-CpGAduw0.mjs";
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-E3yd8mxg.mjs";
3
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 };
@@ -4653,6 +4653,68 @@ const TASK_RUNNER_ADDONS = [
4653
4653
  "nx",
4654
4654
  "vite-plus"
4655
4655
  ];
4656
+ const fileExistsErrorSchema = z.object({ code: z.literal("EEXIST") });
4657
+ const configPackageScopeSchema = z.object({ name: z.string().regex(/^@[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?\/config$/) }).transform(({ name }) => name.slice(0, -7));
4658
+ const rootTypescriptVersionSchema = z.object({ devDependencies: z.object({ typescript: z.string().min(1) }) }).transform(({ devDependencies }) => devDependencies.typescript);
4659
+ function isFileExistsError(cause) {
4660
+ return fileExistsErrorSchema.safeParse(cause).success;
4661
+ }
4662
+ async function reserveWorkspacePackage(projectDir, packageName) {
4663
+ const packageDir = path.join(projectDir, "packages", packageName);
4664
+ return Result.tryPromise({
4665
+ try: async () => {
4666
+ await fs.mkdir(packageDir);
4667
+ return packageDir;
4668
+ },
4669
+ catch: (cause) => new CLIError({
4670
+ message: isFileExistsError(cause) ? `Workspace package already exists: packages/${packageName}` : `Failed to reserve workspace package: packages/${packageName}`,
4671
+ cause
4672
+ })
4673
+ });
4674
+ }
4675
+ async function addWorkspacePackage(vfs, projectDir, packageName, packageManager) {
4676
+ const packageDir = path.join(projectDir, "packages", packageName);
4677
+ if (await fs.pathExists(packageDir)) return Result.err(new CLIError({ message: `Workspace package already exists: packages/${packageName}` }));
4678
+ const configPackagePath = path.join(projectDir, "packages", "config", "package.json");
4679
+ const packageScopeResult = await Result.tryPromise({
4680
+ try: async () => configPackageScopeSchema.parse(await fs.readJson(configPackagePath)),
4681
+ catch: (cause) => new CLIError({
4682
+ message: "Cannot determine the workspace package scope. Expected packages/config/package.json to have a name like @my-app/config.",
4683
+ cause
4684
+ })
4685
+ });
4686
+ if (packageScopeResult.isErr()) return Result.err(packageScopeResult.error);
4687
+ const typescriptVersionResult = await Result.tryPromise({
4688
+ try: async () => rootTypescriptVersionSchema.parse(await fs.readJson(path.join(projectDir, "package.json"))),
4689
+ catch: (cause) => new CLIError({
4690
+ message: "Cannot determine the TypeScript version. Expected package.json to declare devDependencies.typescript.",
4691
+ cause
4692
+ })
4693
+ });
4694
+ if (typescriptVersionResult.isErr()) return Result.err(typescriptVersionResult.error);
4695
+ const packageScope = packageScopeResult.value;
4696
+ const fullPackageName = `${packageScope}/${packageName}`;
4697
+ if (fullPackageName.length > 214) return Result.err(new CLIError({ message: "Workspace package name must not exceed 214 characters including its scope." }));
4698
+ const packagePath = `packages/${packageName}`;
4699
+ vfs.writeFile(`${packagePath}/package.json`, `${JSON.stringify({
4700
+ name: fullPackageName,
4701
+ version: "0.0.0",
4702
+ private: true,
4703
+ type: "module",
4704
+ exports: { ".": "./src/index.ts" },
4705
+ scripts: { "check-types": "tsc --noEmit" },
4706
+ devDependencies: {
4707
+ [`${packageScope}/config`]: packageManager === "npm" ? "*" : "workspace:*",
4708
+ typescript: typescriptVersionResult.value
4709
+ }
4710
+ }, null, 2)}\n`);
4711
+ vfs.writeFile(`${packagePath}/tsconfig.json`, `${JSON.stringify({
4712
+ extends: `${packageScope}/config/tsconfig.base.json`,
4713
+ include: ["src/**/*.ts"]
4714
+ }, null, 2)}\n`);
4715
+ vfs.writeFile(`${packagePath}/src/index.ts`, "export {};\n");
4716
+ return Result.ok(void 0);
4717
+ }
4656
4718
  function mergeAddonOptions(existingAddonOptions, nextAddonOptions) {
4657
4719
  if (!existingAddonOptions && !nextAddonOptions) return;
4658
4720
  const mergeOption = (existing, next) => {
@@ -4738,7 +4800,7 @@ async function addHandlerInternal(input) {
4738
4800
  let addonsToAdd;
4739
4801
  if (input.addons && input.addons.length > 0) {
4740
4802
  addonsToAdd = input.addons.filter((addon) => addon !== "none" && !existingConfig.addons.includes(addon));
4741
- if (addonsToAdd.length === 0) {
4803
+ if (addonsToAdd.length === 0 && !input.package) {
4742
4804
  if (!isSilent()) {
4743
4805
  log.warn(pc.yellow("Nothing to add — those addons are already installed"));
4744
4806
  outro(pc.dim("Project unchanged"));
@@ -4749,7 +4811,8 @@ async function addHandlerInternal(input) {
4749
4811
  projectDir
4750
4812
  });
4751
4813
  }
4752
- } else if (isSilent()) return Result.err(new CLIError({ message: "Addons are required in silent mode. Provide them via add() or add-json." }));
4814
+ } else if (input.package) addonsToAdd = [];
4815
+ else if (isSilent()) return Result.err(new CLIError({ message: "Addons or a package are required in silent mode." }));
4753
4816
  else {
4754
4817
  const promptResult = await Result.tryPromise({
4755
4818
  try: () => getAddonsToAdd(existingConfig),
@@ -4776,7 +4839,10 @@ async function addHandlerInternal(input) {
4776
4839
  const updatedAddons = [...existingConfig.addons, ...addonsToAdd];
4777
4840
  const addonsValidationResult = validateAddonsAgainstConfig(updatedAddons, existingConfig);
4778
4841
  if (addonsValidationResult.isErr()) return Result.err(new CLIError({ message: addonsValidationResult.error.message }));
4779
- if (!isSilent()) log.info(`${pc.dim("Adding")} ${pc.cyan(formatConfigValue(addonsToAdd))}`);
4842
+ if (!isSilent()) {
4843
+ const additions = [addonsToAdd.length > 0 ? formatConfigValue(addonsToAdd) : void 0, input.package ? `package ${input.package}` : void 0].filter(Boolean);
4844
+ log.info(`${pc.dim("Adding")} ${pc.cyan(additions.join(" and "))}`);
4845
+ }
4780
4846
  const mergedAddonOptions = mergeAddonOptions(existingConfig.addonOptions, input.addonOptions);
4781
4847
  const config = {
4782
4848
  projectName: existingConfig.projectName,
@@ -4804,33 +4870,41 @@ async function addHandlerInternal(input) {
4804
4870
  ...config,
4805
4871
  addons: updatedAddons
4806
4872
  };
4807
- const requirementsResult = await checkLocalRequirements(updatedConfig);
4808
- if (requirementsResult.isErr()) return Result.err(requirementsResult.error);
4809
- if (!isSilent()) for (const warning of requirementsResult.value.warnings) log.warn(pc.yellow(warning));
4810
- if (!isSilent()) log.info(pc.dim("Preparing addon files…"));
4873
+ if (addonsToAdd.length > 0) {
4874
+ const requirementsResult = await checkLocalRequirements(updatedConfig);
4875
+ if (requirementsResult.isErr()) return Result.err(requirementsResult.error);
4876
+ if (!isSilent()) for (const warning of requirementsResult.value.warnings) log.warn(pc.yellow(warning));
4877
+ }
4878
+ if (!isSilent()) log.info(pc.dim("Preparing files…"));
4811
4879
  const vfs = new VirtualFileSystem();
4812
- for (const pkgPath of ADD_PACKAGE_JSON_PATHS) {
4813
- const fullPath = path.join(projectDir, pkgPath);
4814
- if (await fs.pathExists(fullPath)) {
4815
- const content = await fs.readFile(fullPath, "utf-8");
4816
- vfs.writeFile(pkgPath, content);
4880
+ if (input.package) {
4881
+ const packageResult = await addWorkspacePackage(vfs, projectDir, input.package, existingConfig.packageManager);
4882
+ if (packageResult.isErr()) return Result.err(packageResult.error);
4883
+ }
4884
+ if (addonsToAdd.length > 0) {
4885
+ for (const pkgPath of ADD_PACKAGE_JSON_PATHS) {
4886
+ const fullPath = path.join(projectDir, pkgPath);
4887
+ if (await fs.pathExists(fullPath)) {
4888
+ const content = await fs.readFile(fullPath, "utf-8");
4889
+ vfs.writeFile(pkgPath, content);
4890
+ }
4817
4891
  }
4818
- }
4819
- for (const filePath of ADD_TEXT_FILE_PATHS) {
4820
- const fullPath = path.join(projectDir, filePath);
4821
- if (await fs.pathExists(fullPath)) {
4822
- const content = await fs.readFile(fullPath, "utf-8");
4823
- vfs.writeFile(filePath, content);
4892
+ for (const filePath of ADD_TEXT_FILE_PATHS) {
4893
+ const fullPath = path.join(projectDir, filePath);
4894
+ if (await fs.pathExists(fullPath)) {
4895
+ const content = await fs.readFile(fullPath, "utf-8");
4896
+ vfs.writeFile(filePath, content);
4897
+ }
4824
4898
  }
4899
+ await processAddonTemplates(vfs, EMBEDDED_TEMPLATES, config);
4900
+ processAddonsDeps(vfs, config);
4901
+ if (addonsToAdd.includes("turborepo")) processTurboConfig(vfs, updatedConfig);
4902
+ if (addonsToAdd.includes("nx")) processNxConfig(vfs, updatedConfig);
4903
+ if (addonsToAdd.includes("vite-plus")) processVitePlusConfig(vfs, updatedConfig);
4904
+ if (updatedAddons.some((addon) => TASK_RUNNER_ADDONS.includes(addon))) processPackageConfigs(vfs, updatedConfig);
4905
+ if (updatedAddons.includes("vite-plus")) updateViteConfigImportsForVitePlus(vfs);
4906
+ if (shouldRefreshLefthook(addonsToAdd, updatedAddons)) refreshLefthookTemplate(vfs, updatedConfig);
4825
4907
  }
4826
- await processAddonTemplates(vfs, EMBEDDED_TEMPLATES, config);
4827
- processAddonsDeps(vfs, config);
4828
- if (addonsToAdd.includes("turborepo")) processTurboConfig(vfs, updatedConfig);
4829
- if (addonsToAdd.includes("nx")) processNxConfig(vfs, updatedConfig);
4830
- if (addonsToAdd.includes("vite-plus")) processVitePlusConfig(vfs, updatedConfig);
4831
- if (updatedAddons.some((addon) => TASK_RUNNER_ADDONS.includes(addon))) processPackageConfigs(vfs, updatedConfig);
4832
- if (updatedAddons.includes("vite-plus")) updateViteConfigImportsForVitePlus(vfs);
4833
- if (shouldRefreshLefthook(addonsToAdd, updatedAddons)) refreshLefthookTemplate(vfs, updatedConfig);
4834
4908
  const tree = {
4835
4909
  root: vfs.toTree(""),
4836
4910
  fileCount: vfs.getFileCount(),
@@ -4840,7 +4914,7 @@ async function addHandlerInternal(input) {
4840
4914
  if (input.dryRun) {
4841
4915
  if (!isSilent()) {
4842
4916
  log.success(pc.green("Dry run passed · no files written"));
4843
- log.message(pc.dim(`${vfs.getFileCount()} addon files planned`));
4917
+ log.message(pc.dim(`${vfs.getFileCount()} files planned`));
4844
4918
  outro(pc.dim("Project unchanged"));
4845
4919
  }
4846
4920
  return Result.ok({
@@ -4848,17 +4922,41 @@ async function addHandlerInternal(input) {
4848
4922
  addedAddons: addonsToAdd,
4849
4923
  projectDir,
4850
4924
  dryRun: true,
4851
- plannedFileCount: vfs.getFileCount()
4925
+ plannedFileCount: vfs.getFileCount(),
4926
+ addedPackage: input.package
4852
4927
  });
4853
4928
  }
4929
+ let reservedPackageDir;
4930
+ if (input.package) {
4931
+ const reservationResult = await reserveWorkspacePackage(projectDir, input.package);
4932
+ if (reservationResult.isErr()) return Result.err(reservationResult.error);
4933
+ reservedPackageDir = reservationResult.value;
4934
+ }
4854
4935
  const writeResult = await writeTree(tree, projectDir);
4855
- if (writeResult.isErr()) return Result.err(new CLIError({ message: `Failed to write addon files: ${writeResult.error.message}` }));
4856
- if (vfs.getFileCount() > 0 && !isSilent()) log.info(pc.dim(`Wrote ${vfs.getFileCount()} addon files`));
4936
+ if (writeResult.isErr()) {
4937
+ if (reservedPackageDir && input.package) {
4938
+ const cleanupResult = await Result.tryPromise({
4939
+ try: () => fs.remove(reservedPackageDir),
4940
+ catch: (cause) => new CLIError({
4941
+ message: `Failed to clean up incomplete workspace package: packages/${input.package}`,
4942
+ cause
4943
+ })
4944
+ });
4945
+ if (cleanupResult.isErr()) return Result.err(new CLIError({
4946
+ message: `Failed to write files: ${writeResult.error.message}. ${cleanupResult.error.message}`,
4947
+ cause: cleanupResult.error
4948
+ }));
4949
+ }
4950
+ return Result.err(new CLIError({ message: `Failed to write files: ${writeResult.error.message}` }));
4951
+ }
4952
+ if (vfs.getFileCount() > 0 && !isSilent()) log.info(pc.dim(`Wrote ${vfs.getFileCount()} files`));
4857
4953
  const setupResult = await Result.tryPromise({
4858
- try: () => setupAddons({
4859
- ...config,
4860
- addons: getSetupAddons(addonsToAdd, updatedAddons)
4861
- }),
4954
+ try: async () => {
4955
+ if (addonsToAdd.length > 0) await setupAddons({
4956
+ ...config,
4957
+ addons: getSetupAddons(addonsToAdd, updatedAddons)
4958
+ });
4959
+ },
4862
4960
  catch: (cause) => {
4863
4961
  if (UserCancelledError.is(cause)) return cause;
4864
4962
  return new CLIError({
@@ -4868,7 +4966,7 @@ async function addHandlerInternal(input) {
4868
4966
  }
4869
4967
  });
4870
4968
  if (setupResult.isErr()) return Result.err(setupResult.error);
4871
- await updateBtsConfig(projectDir, {
4969
+ if (addonsToAdd.length > 0) await updateBtsConfig(projectDir, {
4872
4970
  addons: updatedAddons,
4873
4971
  addonOptions: updatedConfig.addonOptions
4874
4972
  });
@@ -4877,7 +4975,8 @@ async function addHandlerInternal(input) {
4877
4975
  packageManager: config.packageManager
4878
4976
  });
4879
4977
  if (!isSilent()) {
4880
- log.success(pc.green(`Added ${formatConfigValue(addonsToAdd)}`));
4978
+ const additions = [addonsToAdd.length > 0 ? formatConfigValue(addonsToAdd) : void 0, input.package ? `package ${input.package}` : void 0].filter(Boolean);
4979
+ log.success(pc.green(`Added ${additions.join(" and ")}`));
4881
4980
  if (!input.install) {
4882
4981
  const installCommand = config.packageManager === "npm" ? "npm install" : `${config.packageManager} install`;
4883
4982
  log.message(`${pc.dim("Next step")}\n${pc.cyan(installCommand)}`);
@@ -4888,7 +4987,8 @@ async function addHandlerInternal(input) {
4888
4987
  success: true,
4889
4988
  addedAddons: addonsToAdd,
4890
4989
  projectDir,
4891
- plannedFileCount: vfs.getFileCount()
4990
+ plannedFileCount: vfs.getFileCount(),
4991
+ addedPackage: input.package
4892
4992
  });
4893
4993
  }
4894
4994
  //#endregion
@@ -9168,8 +9268,9 @@ const router = t.router({
9168
9268
  sponsors: t.procedure.meta({ description: "Show Better-T-Stack sponsors" }).mutation(() => showSponsorsCommand()),
9169
9269
  docs: t.procedure.meta({ description: "Open Better-T-Stack documentation" }).mutation(() => openDocsCommand()),
9170
9270
  builder: t.procedure.meta({ description: "Open the web-based stack builder" }).mutation(() => openBuilderCommand()),
9171
- add: t.procedure.meta({ description: "Add addons to an existing Better-T-Stack project" }).input(z.object({
9271
+ add: t.procedure.meta({ description: "Add addons or a workspace package to an existing Better-T-Stack project" }).input(z.object({
9172
9272
  addons: z.array(types_exports.AddonsSchema).optional().describe("Addons to add"),
9273
+ package: types_exports.WorkspacePackageNameSchema.optional(),
9173
9274
  install: z.boolean().optional().default(false).describe("Install dependencies after adding"),
9174
9275
  packageManager: types_exports.PackageManagerSchema.optional().describe("Package manager to use"),
9175
9276
  projectDir: z.string().optional().describe("Project directory (defaults to current)"),
@@ -9178,7 +9279,7 @@ const router = t.router({
9178
9279
  await addHandler(input);
9179
9280
  }),
9180
9281
  addJson: t.procedure.meta({
9181
- description: "Add addons from a raw JSON payload (agent-friendly)",
9282
+ description: "Add addons or a workspace package from a raw JSON payload (agent-friendly)",
9182
9283
  jsonInput: "always"
9183
9284
  }).input(types_exports.AddInputSchema).mutation(async ({ input }) => {
9184
9285
  const result = await addHandler(input, { silent: true });
@@ -9342,7 +9443,7 @@ async function createVirtual(options) {
9342
9443
  });
9343
9444
  }
9344
9445
  /**
9345
- * Programmatic API to add addons to an existing Better-T-Stack project.
9446
+ * Programmatic API to add addons or a workspace package to an existing Better-T-Stack project.
9346
9447
  *
9347
9448
  * @example
9348
9449
  * ```typescript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-t-stack",
3
- "version": "3.40.4",
3
+ "version": "3.40.5",
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.4",
73
- "@better-t-stack/types": "^3.40.4",
72
+ "@better-t-stack/template-generator": "^3.40.5",
73
+ "@better-t-stack/types": "^3.40.5",
74
74
  "@clack/core": "^1.4.3",
75
75
  "@clack/prompts": "^1.7.0",
76
76
  "@modelcontextprotocol/sdk": "1.30.0",