create-better-t-stack 3.41.1 → 3.41.3

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
@@ -130,7 +130,7 @@ This CLI collects anonymous usage data to help improve the tool. The data collec
130
130
  - Platform (OS)
131
131
  - How the CLI was driven (prompts, flags, `--yes`, JSON, the programmatic API, or the MCP server)
132
132
 
133
- Separately, a small number of anonymous diagnostic events are sent for failures (stage and error class, never full messages or paths), cancelled prompts, other commands such as `add` and `history`, slow runs, and MCP tool usage. See the [analytics documentation](https://better-t-stack.dev/docs/analytics) for the exact list.
133
+ Separately, one anonymous failure event is sent when a scaffold breaks (stage and error class, never full messages or paths). See the [analytics documentation](https://better-t-stack.dev/docs/analytics) for details.
134
134
 
135
135
  **Telemetry is enabled by default in published versions** to help us understand usage patterns and improve the tool.
136
136
 
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { A as setProcessMode, S as getLatestCLIVersion, b as scrubReason, i as SchemaNameSchema, l as create, m as getSchemaResult, s as add, u as createBtsCli, v as durationBucket, x as types_exports, y as reportDiagnostic } from "./src-pRksmzD7.mjs";
2
+ import { D as setProcessMode, i as SchemaNameSchema, l as create, m as getSchemaResult, s as add, u as createBtsCli, v as types_exports, y as getLatestCLIVersion } from "./src-BhgA6H5Y.mjs";
3
3
  import z from "zod";
4
4
  import { McpServer } from "@modelcontextprotocol/server";
5
5
  import { serveStdio } from "@modelcontextprotocol/server/stdio";
@@ -58,44 +58,6 @@ function formatToolError(cause) {
58
58
  isError: true
59
59
  };
60
60
  }
61
- const reportedSessions = /* @__PURE__ */ new WeakSet();
62
- /** One session event per connection, sent when the client identity is first known. */
63
- function reportMcpSession(server) {
64
- if (reportedSessions.has(server)) return;
65
- reportedSessions.add(server);
66
- const client = server.server.getClientVersion();
67
- reportDiagnostic("mcp_session", {
68
- client: client?.name ?? "unknown",
69
- clientVersion: client?.version ?? "unknown"
70
- });
71
- }
72
- /**
73
- * Times every tool call and reports the outcome. Diagnostics are fire-and-forget here
74
- * because the server process is long-lived and must not add latency to tool results.
75
- */
76
- function instrumentTool(server, tool, handler, isOptedOut) {
77
- return async (...args) => {
78
- if (isOptedOut?.(...args)) return handler(...args);
79
- reportMcpSession(server);
80
- const startTime = Date.now();
81
- const result = await handler(...args);
82
- const ok = !("isError" in result);
83
- reportDiagnostic("mcp_tool", {
84
- tool,
85
- ok,
86
- duration: durationBucket(Date.now() - startTime)
87
- });
88
- if (!ok) reportDiagnostic("mcp_tool_error", {
89
- tool,
90
- error: "ToolError",
91
- reason: scrubReason(result.structuredContent.error)
92
- });
93
- return result;
94
- };
95
- }
96
- function isCreateOptedOut(input) {
97
- return input.disableAnalytics === true;
98
- }
99
61
  function getProjectToolAnnotations() {
100
62
  return {
101
63
  destructiveHint: true,
@@ -185,13 +147,13 @@ function createBtsMcpServer() {
185
147
  idempotentHint: true,
186
148
  openWorldHint: false
187
149
  }
188
- }, instrumentTool(server, "bts_get_stack_guidance", async () => {
150
+ }, async () => {
189
151
  try {
190
152
  return formatToolSuccess(getStackGuidance());
191
153
  } catch (error) {
192
154
  return formatToolError(error);
193
155
  }
194
- }));
156
+ });
195
157
  server.registerTool("bts_get_schema", {
196
158
  title: "Get Better T Stack Schemas",
197
159
  description: "Inspect Better T Stack CLI and input schemas so agents can plan valid create/add requests. Use this together with bts_get_stack_guidance before creating a project if any part of the request is ambiguous.",
@@ -204,13 +166,13 @@ function createBtsMcpServer() {
204
166
  idempotentHint: true,
205
167
  openWorldHint: false
206
168
  }
207
- }, instrumentTool(server, "bts_get_schema", async ({ name }) => {
169
+ }, async ({ name }) => {
208
170
  try {
209
171
  return formatToolSuccess(getSchemaResult(name ?? "all"));
210
172
  } catch (error) {
211
173
  return formatToolError(error);
212
174
  }
213
- }));
175
+ });
214
176
  server.registerTool("bts_plan_project", {
215
177
  title: "Plan Better T Stack Project",
216
178
  description: "Validate and preview a Better T Stack project creation without writing files or provisioning resources. Always use this before bts_create_project. This tool requires an explicit full stack config rather than a partial payload with inferred defaults.",
@@ -223,7 +185,7 @@ function createBtsMcpServer() {
223
185
  idempotentHint: true,
224
186
  openWorldHint: false
225
187
  }
226
- }, instrumentTool(server, "bts_plan_project", async (input) => {
188
+ }, async (input) => {
227
189
  try {
228
190
  const result = await create(input.projectName, {
229
191
  ...input,
@@ -242,7 +204,7 @@ function createBtsMcpServer() {
242
204
  } catch (error) {
243
205
  return formatToolError(error);
244
206
  }
245
- }, isCreateOptedOut));
207
+ });
246
208
  server.registerTool("bts_create_project", {
247
209
  title: "Create Better T Stack Project",
248
210
  description: "Create a Better T Stack project on disk using the same silent programmatic flow as the CLI JSON API. Call this only after bts_plan_project succeeds and the plan clearly matches the user's intent. This tool requires an explicit full stack config.",
@@ -252,7 +214,7 @@ function createBtsMcpServer() {
252
214
  title: "Create Better T Stack Project",
253
215
  ...getProjectToolAnnotations()
254
216
  }
255
- }, instrumentTool(server, "bts_create_project", async (input) => {
217
+ }, async (input) => {
256
218
  try {
257
219
  if (input.install) return formatToolError(getMcpInstallTimeoutMessage(input.packageManager));
258
220
  const result = await create(input.projectName, {
@@ -264,7 +226,7 @@ function createBtsMcpServer() {
264
226
  } catch (error) {
265
227
  return formatToolError(error);
266
228
  }
267
- }, isCreateOptedOut));
229
+ });
268
230
  server.registerTool("bts_plan_addons", {
269
231
  title: "Plan Better T Stack Project Additions",
270
232
  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.",
@@ -277,7 +239,7 @@ function createBtsMcpServer() {
277
239
  idempotentHint: true,
278
240
  openWorldHint: false
279
241
  }
280
- }, instrumentTool(server, "bts_plan_addons", async (input) => {
242
+ }, async (input) => {
281
243
  try {
282
244
  const result = await add({
283
245
  ...input,
@@ -288,7 +250,7 @@ function createBtsMcpServer() {
288
250
  } catch (error) {
289
251
  return formatToolError(error);
290
252
  }
291
- }));
253
+ });
292
254
  server.registerTool("bts_add_addons", {
293
255
  title: "Apply Better T Stack Project Additions",
294
256
  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.",
@@ -300,7 +262,7 @@ function createBtsMcpServer() {
300
262
  idempotentHint: false,
301
263
  openWorldHint: true
302
264
  }
303
- }, instrumentTool(server, "bts_add_addons", async (input) => {
265
+ }, async (input) => {
304
266
  try {
305
267
  const result = await add(input);
306
268
  if (!result?.success) return formatToolError(result?.error ?? "Failed to update project");
@@ -308,7 +270,7 @@ function createBtsMcpServer() {
308
270
  } catch (error) {
309
271
  return formatToolError(error);
310
272
  }
311
- }));
273
+ });
312
274
  return server;
313
275
  }
314
276
  function startBtsMcpServer() {
package/dist/index.d.mts CHANGED
@@ -12,12 +12,9 @@ declare const UserCancelledError_base: import("better-result").TaggedErrorClass<
12
12
  */
13
13
  declare class UserCancelledError extends UserCancelledError_base<{
14
14
  message: string;
15
- /** Name of the prompt that was open when the user cancelled, when known. */
16
- prompt?: string;
17
15
  }> {
18
16
  constructor(args?: {
19
17
  message?: string;
20
- prompt?: string;
21
18
  });
22
19
  }
23
20
  declare const CLIError_base: import("better-result").TaggedErrorClass<"CLIError">;
@@ -358,6 +355,7 @@ declare const router: import("@trpc/server").TRPCBuiltRouter<{
358
355
  packageManager?: "bun" | "npm" | "pnpm" | undefined;
359
356
  projectDir?: string | undefined;
360
357
  dryRun?: boolean | undefined;
358
+ disableAnalytics?: boolean | undefined;
361
359
  };
362
360
  output: void;
363
361
  meta: TrpcCliMeta;
@@ -407,6 +405,7 @@ declare const router: import("@trpc/server").TRPCBuiltRouter<{
407
405
  install?: boolean | undefined;
408
406
  packageManager?: "bun" | "npm" | "pnpm" | undefined;
409
407
  dryRun?: boolean | undefined;
408
+ disableAnalytics?: boolean | undefined;
410
409
  };
411
410
  output: AddResult;
412
411
  meta: TrpcCliMeta;
@@ -479,7 +478,7 @@ declare function builder(): Promise<void>;
479
478
  * ```
480
479
  */
481
480
  declare function createVirtual(options: Partial<Omit<types_d_exports.ProjectConfig, "projectDir" | "relativePath">>): Promise<Result$1<VirtualFileTree$1, GeneratorError$1>>;
482
- type AddOptions = Pick<types_d_exports.AddInput, "addons" | "addonOptions" | "package" | "install" | "packageManager" | "projectDir" | "dryRun">;
481
+ type AddOptions = Pick<types_d_exports.AddInput, "addons" | "addonOptions" | "package" | "install" | "packageManager" | "projectDir" | "dryRun" | "disableAnalytics">;
483
482
  /**
484
483
  * Programmatic API to add addons or a workspace package to an existing Better-T-Stack project.
485
484
  *
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { C as CLIError, D as ProjectCreationError, E as DirectoryConflictError, O as UserCancelledError, T as DatabaseSetupError, _ as ProjectLauncherSchema, a as TEMPLATE_COUNT, c as builder, d as createVirtual, f as docs, g as sponsors, h as router, i as SchemaNameSchema, k as ValidationError, 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 CompatibilityError } from "./src-pRksmzD7.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-BhgA6H5Y.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 };
@@ -377,10 +377,7 @@ const cliConsola = {
377
377
  */
378
378
  var UserCancelledError = class extends TaggedError("UserCancelledError") {
379
379
  constructor(args) {
380
- super({
381
- message: args?.message ?? "Operation cancelled",
382
- prompt: args?.prompt
383
- });
380
+ super({ message: args?.message ?? "Operation cancelled" });
384
381
  }
385
382
  };
386
383
  /**
@@ -1756,9 +1753,8 @@ function isTelemetryEnabled() {
1756
1753
  //#endregion
1757
1754
  //#region src/utils/diagnostics.ts
1758
1755
  /**
1759
- * Diagnostic events go to the self-hosted Umami instance (a separate "CLI" website),
1760
- * not to the Convex project dataset. They cover what the project-creation event
1761
- * cannot: failures, cancellations, non-create commands, slow stages, and MCP usage.
1756
+ * Failure diagnostics go to the self-hosted Umami instance (a separate "CLI" website),
1757
+ * not to the Convex project dataset, which only records successful creations.
1762
1758
  * Everything is a no-op until UMAMI_CLI_WEBSITE_ID is baked in at build time.
1763
1759
  */
1764
1760
  const UMAMI_HOST_URL = "https://umami.amanv.cloud";
@@ -1766,17 +1762,6 @@ const UMAMI_CLI_WEBSITE_ID = "e658611d-dbcc-4d3a-bc4e-182b9f5b0d5d";
1766
1762
  const SEND_TIMEOUT_MS$1 = 3e3;
1767
1763
  const MAX_STRING_LENGTH = 500;
1768
1764
  const MAX_REASON_LENGTH = 160;
1769
- const DURATION_BUCKETS = [
1770
- [1e3, "<1s"],
1771
- [5e3, "1-5s"],
1772
- [15e3, "5-15s"],
1773
- [6e4, "15-60s"],
1774
- [3e5, "1-5m"]
1775
- ];
1776
- function durationBucket(elapsedMs) {
1777
- for (const [limit, label] of DURATION_BUCKETS) if (elapsedMs < limit) return label;
1778
- return ">5m";
1779
- }
1780
1765
  /** Class name of the failure, which is stable and never carries user content. */
1781
1766
  function errorClass(cause) {
1782
1767
  if (cause instanceof Error) return cause.name || cause.constructor.name || "Error";
@@ -1794,7 +1779,7 @@ function failureStage(cause) {
1794
1779
  }
1795
1780
  /**
1796
1781
  * First line of an error message with anything that could identify a machine or
1797
- * project replaced by placeholders: file paths, URLs, emails, and quoted names.
1782
+ * project replaced by placeholders: quoted names, URLs, emails, and paths.
1798
1783
  */
1799
1784
  function scrubReason(cause) {
1800
1785
  const scrubbed = ((cause instanceof Error ? cause.message : String(cause)).split(/\r?\n/, 1)[0] ?? "").replaceAll(/(["'`])(?:(?!\1).)*\1/g, "<name>").replaceAll(/https?:\/\/[^\s)\]"'>]+/gi, "<url>").replaceAll(/[\w.+-]+@[\w-]+\.[\w.-]+/g, "<email>").replaceAll(/(?:[a-zA-Z]:)?(?:[\\/][\w.@+ -]+)+[\\/][\w.@+-]+(?:[ \w.@+-]*\.\w+)?/g, "<path>").replaceAll(/\S*[\\/]\S*/g, "<path>").replaceAll(/\s+/g, " ").trim();
@@ -1807,11 +1792,6 @@ function clampValue(value) {
1807
1792
  function isDiagnosticsEnabled() {
1808
1793
  return Boolean(UMAMI_HOST_URL) && Boolean(UMAMI_CLI_WEBSITE_ID) && isTelemetryEnabled() && !getContext().analyticsDisabled;
1809
1794
  }
1810
- function eventUrl(name, data) {
1811
- if (name.startsWith("mcp_")) return "/mcp";
1812
- const command = data.command;
1813
- return command === void 0 ? `/${name}` : `/${String(command)}`;
1814
- }
1815
1795
  function buildDiagnosticPayload(name, data) {
1816
1796
  const eventData = {};
1817
1797
  for (const [key, value] of Object.entries(data)) if (value !== void 0) eventData[key] = clampValue(value);
@@ -1820,7 +1800,7 @@ function buildDiagnosticPayload(name, data) {
1820
1800
  payload: {
1821
1801
  website: UMAMI_CLI_WEBSITE_ID,
1822
1802
  hostname: "cli",
1823
- url: eventUrl(name, eventData),
1803
+ url: `/${data.command}`,
1824
1804
  title: name,
1825
1805
  name,
1826
1806
  data: eventData
@@ -1846,16 +1826,6 @@ async function reportDiagnostic(name, data) {
1846
1826
  catch: () => void 0
1847
1827
  });
1848
1828
  }
1849
- /** Reports a stage only when it crossed the slow threshold, so the event is a signal. */
1850
- async function reportSlowStage(command, stage, elapsedMs, packageManager) {
1851
- if (elapsedMs < 6e4) return;
1852
- await reportDiagnostic("cli_slow", {
1853
- command,
1854
- stage,
1855
- duration: durationBucket(elapsedMs),
1856
- packageManager
1857
- });
1858
- }
1859
1829
  //#endregion
1860
1830
  //#region src/utils/input-hardening.ts
1861
1831
  function hasControlCharacters(value) {
@@ -2731,10 +2701,7 @@ async function navigableGroup(prompts, opts) {
2731
2701
  if (isCancel$1(result)) {
2732
2702
  if (opts?.onCancel) {
2733
2703
  results[name] = "canceled";
2734
- opts.onCancel({
2735
- results,
2736
- prompt: String(name)
2737
- });
2704
+ opts.onCancel({ results });
2738
2705
  }
2739
2706
  return results;
2740
2707
  }
@@ -4919,11 +4886,11 @@ async function addHandler(input, options = {}) {
4919
4886
  const { silent = false, mode } = options;
4920
4887
  return runWithContextAsync({
4921
4888
  silent,
4922
- mode
4889
+ mode,
4890
+ analyticsDisabled: input.disableAnalytics
4923
4891
  }, async () => {
4924
- const startTime = Date.now();
4925
4892
  const result = await addHandlerInternal(input);
4926
- await reportAddOutcome(input, result, Date.now() - startTime);
4893
+ await reportAddOutcome(input, result);
4927
4894
  if (result.isOk()) return result.value;
4928
4895
  const error = result.error;
4929
4896
  if (UserCancelledError.is(error)) {
@@ -4945,36 +4912,13 @@ async function addHandler(input, options = {}) {
4945
4912
  process.exit(1);
4946
4913
  });
4947
4914
  }
4948
- async function reportAddOutcome(input, result, elapsedMs) {
4949
- const mode = resolveInvocationMode(false);
4950
- const duration = durationBucket(elapsedMs);
4951
- if (result.isOk()) {
4952
- await reportDiagnostic("cli_command", {
4953
- command: "add",
4954
- mode,
4955
- ok: true,
4956
- duration
4957
- });
4958
- return;
4959
- }
4915
+ async function reportAddOutcome(input, result) {
4916
+ if (result.isOk()) return;
4960
4917
  const error = result.error;
4961
- if (UserCancelledError.is(error)) {
4962
- await reportDiagnostic("cli_cancelled", {
4963
- command: "add",
4964
- mode,
4965
- prompt: error.prompt ?? "unknown"
4966
- });
4967
- return;
4968
- }
4969
- await reportDiagnostic("cli_command", {
4970
- command: "add",
4971
- mode,
4972
- ok: false,
4973
- duration
4974
- });
4918
+ if (UserCancelledError.is(error)) return;
4975
4919
  await reportDiagnostic("cli_failed", {
4976
4920
  command: "add",
4977
- mode,
4921
+ mode: resolveInvocationMode(false),
4978
4922
  stage: failureStage(error),
4979
4923
  error: errorClass(error),
4980
4924
  reason: scrubReason(error),
@@ -6278,11 +6222,8 @@ async function gatherConfig(flags, projectName, projectDir, relativePath, option
6278
6222
  ]
6279
6223
  }
6280
6224
  ],
6281
- onCancel: ({ prompt }) => {
6282
- throw new UserCancelledError({
6283
- message: "Operation cancelled",
6284
- prompt
6285
- });
6225
+ onCancel: () => {
6226
+ throw new UserCancelledError({ message: "Operation cancelled" });
6286
6227
  }
6287
6228
  });
6288
6229
  return {
@@ -6367,10 +6308,7 @@ async function getProjectName(initialName) {
6367
6308
  }
6368
6309
  }
6369
6310
  });
6370
- if (isCancel(response)) throw new UserCancelledError({
6371
- message: "Operation cancelled.",
6372
- prompt: "projectName"
6373
- });
6311
+ if (isCancel(response)) throw new UserCancelledError({ message: "Operation cancelled." });
6374
6312
  projectPath = response || defaultName;
6375
6313
  isValid = true;
6376
6314
  }
@@ -8964,7 +8902,6 @@ async function createProject(options, cliInput) {
8964
8902
  return Result.gen(async function* () {
8965
8903
  const projectDir = options.projectDir;
8966
8904
  const isConvex = options.backend === "convex";
8967
- const scaffoldStartTime = Date.now();
8968
8905
  yield* Result.await(Result.tryPromise({
8969
8906
  try: () => fs.ensureDir(projectDir),
8970
8907
  catch: (e) => new ProjectCreationError({
@@ -9006,15 +8943,10 @@ async function createProject(options, cliInput) {
9006
8943
  }));
9007
8944
  yield* Result.await(formatProject(projectDir));
9008
8945
  if (!isSilent()) log.success("Project scaffolded");
9009
- await reportSlowStage("create", "scaffold", Date.now() - scaffoldStartTime, options.packageManager);
9010
- if (options.install) {
9011
- const installStartTime = Date.now();
9012
- yield* Result.await(installDependencies({
9013
- projectDir,
9014
- packageManager: options.packageManager
9015
- }));
9016
- await reportSlowStage("create", "install", Date.now() - installStartTime, options.packageManager);
9017
- }
8946
+ if (options.install) yield* Result.await(installDependencies({
8947
+ projectDir,
8948
+ packageManager: options.packageManager
8949
+ }));
9018
8950
  yield* Result.await(initializeGit(projectDir, options.git));
9019
8951
  if (!isSilent()) await displayPostInstallInstructions({
9020
8952
  ...options,
@@ -9094,22 +9026,14 @@ async function executeCreateProjectHandler(input, options) {
9094
9026
  };
9095
9027
  });
9096
9028
  }
9097
- /** Diagnostics for what the success-only project event cannot show; awaited so it beats process.exit. */
9029
+ /** Failure diagnostics, which the success-only project event cannot show; awaited so it beats process.exit. */
9098
9030
  async function reportCreateOutcome(input, result) {
9099
- const mode = resolveInvocationMode(input.yes);
9100
9031
  if (result.isOk()) return;
9101
9032
  const error = result.error;
9102
- if (UserCancelledError.is(error)) {
9103
- await reportDiagnostic("cli_cancelled", {
9104
- command: "create",
9105
- mode,
9106
- prompt: error.prompt ?? "unknown"
9107
- });
9108
- return;
9109
- }
9033
+ if (UserCancelledError.is(error)) return;
9110
9034
  await reportDiagnostic("cli_failed", {
9111
9035
  command: "create",
9112
- mode,
9036
+ mode: resolveInvocationMode(input.yes),
9113
9037
  stage: failureStage(error),
9114
9038
  error: errorClass(error),
9115
9039
  reason: scrubReason(error),
@@ -9499,16 +9423,17 @@ const router = t.router({
9499
9423
  return result;
9500
9424
  }),
9501
9425
  schema: t.procedure.meta({ description: "Show runtime CLI and input schemas as JSON" }).input(z.object({ name: SchemaNameSchema.describe("Schema name to inspect") })).query(({ input }) => getSchemaResult(input.name)),
9502
- sponsors: t.procedure.meta({ description: "Show Better-T-Stack sponsors" }).mutation(() => trackCommand("sponsors", () => showSponsorsCommand())),
9503
- docs: t.procedure.meta({ description: "Open Better-T-Stack documentation" }).mutation(() => trackCommand("docs", () => openDocsCommand())),
9504
- builder: t.procedure.meta({ description: "Open the web-based stack builder" }).mutation(() => trackCommand("builder", () => openBuilderCommand())),
9426
+ sponsors: t.procedure.meta({ description: "Show Better-T-Stack sponsors" }).mutation(() => showSponsorsCommand()),
9427
+ docs: t.procedure.meta({ description: "Open Better-T-Stack documentation" }).mutation(() => openDocsCommand()),
9428
+ builder: t.procedure.meta({ description: "Open the web-based stack builder" }).mutation(() => openBuilderCommand()),
9505
9429
  add: t.procedure.meta({ description: "Add addons or a workspace package to an existing Better-T-Stack project" }).input(z.object({
9506
9430
  addons: z.array(types_exports.AddonsSchema).optional().describe("Addons to add"),
9507
9431
  package: types_exports.WorkspacePackageNameSchema.optional(),
9508
9432
  install: z.boolean().optional().default(false).describe("Install dependencies after adding"),
9509
9433
  packageManager: types_exports.PackageManagerSchema.optional().describe("Package manager to use"),
9510
9434
  projectDir: z.string().optional().describe("Project directory (defaults to current)"),
9511
- dryRun: z.boolean().optional().default(false).describe("Preview addon changes without writing files")
9435
+ dryRun: z.boolean().optional().default(false).describe("Preview addon changes without writing files"),
9436
+ disableAnalytics: z.boolean().optional().default(false).describe("Disable analytics")
9512
9437
  })).mutation(async ({ input }) => {
9513
9438
  await addHandler(input);
9514
9439
  }),
@@ -9529,29 +9454,9 @@ const router = t.router({
9529
9454
  clear: z.boolean().optional().default(false).describe("Clear all history"),
9530
9455
  json: z.boolean().optional().default(false).describe("Output as JSON")
9531
9456
  })).mutation(async ({ input }) => {
9532
- await trackCommand("history", () => historyHandler(input), (ok) => ok);
9457
+ await historyHandler(input);
9533
9458
  })
9534
9459
  });
9535
- /** Usage diagnostics for commands that have no project event of their own. */
9536
- async function trackCommand(command, run, isOk = () => true) {
9537
- const startTime = Date.now();
9538
- try {
9539
- const value = await run();
9540
- await reportDiagnostic("cli_command", {
9541
- command,
9542
- ok: isOk(value),
9543
- duration: durationBucket(Date.now() - startTime)
9544
- });
9545
- return value;
9546
- } catch (cause) {
9547
- await reportDiagnostic("cli_command", {
9548
- command,
9549
- ok: false,
9550
- duration: durationBucket(Date.now() - startTime)
9551
- });
9552
- throw cause;
9553
- }
9554
- }
9555
9460
  function createBtsCli() {
9556
9461
  return createCli({
9557
9462
  router,
@@ -9738,4 +9643,4 @@ async function add(options = {}) {
9738
9643
  };
9739
9644
  }
9740
9645
  //#endregion
9741
- export { setProcessMode as A, CLIError as C, ProjectCreationError as D, DirectoryConflictError as E, UserCancelledError as O, getLatestCLIVersion as S, DatabaseSetupError as T, ProjectLauncherSchema as _, TEMPLATE_COUNT as a, scrubReason as b, builder as c, createVirtual as d, docs as f, sponsors as g, router as h, SchemaNameSchema as i, ValidationError as k, 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, durationBucket as v, CompatibilityError as w, types_exports as x, reportDiagnostic as y };
9646
+ export { DirectoryConflictError as C, setProcessMode as D, 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.41.1",
3
+ "version": "3.41.3",
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.41.1",
73
- "@better-t-stack/types": "^3.41.1",
72
+ "@better-t-stack/template-generator": "^3.41.3",
73
+ "@better-t-stack/types": "^3.41.3",
74
74
  "@clack/core": "^1.4.3",
75
75
  "@clack/prompts": "^1.7.0",
76
76
  "@modelcontextprotocol/server": "2.0.0",