create-kubojs 0.4.1 → 0.5.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
@@ -104,27 +104,31 @@ For MCP project creation, prefer `install: false`. Long dependency installs can
104
104
 
105
105
  ## Telemetry
106
106
 
107
- This CLI collects anonymous usage data to help improve the tool. The data collected includes:
107
+ This CLI collects anonymous usage data to help improve the tool. Each `create` run (except `--dry-run`) sends one event with:
108
108
 
109
- - Configuration options selected
110
- - CLI version
111
- - Node.js version
112
- - Platform (OS)
109
+ - Selected stack options (only when the project is created)
110
+ - Outcome (`success`, `failure`, `cancelled`), duration and, on failure, the error class name (never the message)
111
+ - How the CLI was invoked (`cli`, `json`, `mcp`, `api`) and how the stack was chosen (`interactive`, `flags`, `yes`, `template`)
112
+ - CLI version, Node.js version, platform, whether it runs in CI, and the coding agent detected from environment markers (e.g. `claude-code`, `cursor`, `codex`)
113
+ - A random anonymous install ID stored in the kubojs config directory (`telemetry.json`), used to count unique installs
113
114
 
114
- **Telemetry is enabled by default in published versions** to help us understand usage patterns and improve the tool.
115
+ Project names, paths, file contents, error messages and environment variable values are never sent. See https://kubojs.dev/docs/analytics.
115
116
 
116
117
  ### Disabling Telemetry
117
118
 
118
- You can disable telemetry by setting the `BTS_TELEMETRY_DISABLED` environment variable:
119
-
120
119
  ```bash
121
120
  # Disable telemetry for a single run
122
- BTS_TELEMETRY_DISABLED=1 npx kubojs
121
+ KUBO_TELEMETRY_DISABLED=1 npx kubojs
122
+
123
+ # DO_NOT_TRACK is also honored
124
+ DO_NOT_TRACK=1 npx kubojs
123
125
 
124
126
  # Disable telemetry globally in your shell profile (.bashrc, .zshrc, etc.)
125
- export BTS_TELEMETRY_DISABLED=1
127
+ export KUBO_TELEMETRY_DISABLED=1
126
128
  ```
127
129
 
130
+ The legacy `BTS_TELEMETRY_DISABLED=1` variable still works.
131
+
128
132
  ## Examples
129
133
 
130
134
  Create a project with default configuration:
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { _ as getLatestCLIVersion, g as types_exports, i as SchemaNameSchema, l as create, m as getSchemaResult, s as add, u as createBtsCli } from "./src-L3WKWfns.mjs";
2
+ import { _ as types_exports, g as setTelemetrySource, i as SchemaNameSchema, l as create, m as getSchemaResult, s as add, u as createBtsCli, v as getLatestCLIVersion } from "./src-DdCJmpnU.mjs";
3
3
  import z from "zod";
4
4
  import { format } from "node:util";
5
5
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -353,7 +353,7 @@ function createBtsMcpServer() {
353
353
  if (input.install) return formatToolError(getMcpInstallTimeoutMessage(input.packageManager));
354
354
  const result = await create(input.projectName, {
355
355
  ...input,
356
- disableAnalytics: true
356
+ disableAnalytics: false
357
357
  });
358
358
  if (result.isErr()) return formatToolError(result.error);
359
359
  return formatToolSuccess(result.value);
@@ -408,6 +408,7 @@ function createBtsMcpServer() {
408
408
  return server;
409
409
  }
410
410
  async function startBtsMcpServer() {
411
+ setTelemetrySource("mcp");
411
412
  const server = createBtsMcpServer();
412
413
  const transport = new StdioServerTransport();
413
414
  await server.connect(transport);
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { C as UserCancelledError, S as ProjectCreationError, a as TEMPLATE_COUNT, b as DatabaseSetupError, c as builder, d as createVirtual, f as docs, 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, v as CLIError, w as ValidationError, x as DirectoryConflictError, y as CompatibilityError } from "./src-L3WKWfns.mjs";
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, 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-DdCJmpnU.mjs";
3
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 };
@@ -21,6 +21,7 @@ import { writeSelected, writeTree } from "@kubojs/template-generator/fs-writer";
21
21
  import { ConfirmPrompt, GroupMultiSelectPrompt, MultiSelectPrompt, SelectPrompt, TextPrompt, isCancel as isCancel$1, isCancel as isCancel$2 } from "@clack/core";
22
22
  import { createJiti } from "jiti";
23
23
  import { parse } from "jsonc-parser";
24
+ import { randomUUID } from "node:crypto";
24
25
  import os from "node:os";
25
26
  import { format } from "oxfmt";
26
27
  import { Generator, configSchema } from "@tanstack/router-generator";
@@ -4022,33 +4023,40 @@ async function getDeploymentChoice(deployment, _runtime, backend, frontend = [],
4022
4023
  }
4023
4024
  //#endregion
4024
4025
  //#region src/prompts/config-prompts.ts
4025
- async function gatherConfig(flags, projectName, projectDir, relativePath) {
4026
- if (isSilent()) return {
4027
- projectName,
4028
- projectDir,
4029
- relativePath,
4030
- addonOptions: flags.addonOptions,
4031
- dbSetupOptions: flags.dbSetupOptions,
4032
- frontend: flags.frontend ?? [...DEFAULT_CONFIG.frontend],
4033
- backend: flags.backend ?? DEFAULT_CONFIG.backend,
4034
- runtime: flags.runtime ?? DEFAULT_CONFIG.runtime,
4035
- database: flags.database ?? DEFAULT_CONFIG.database,
4036
- orm: flags.orm ?? DEFAULT_CONFIG.orm,
4037
- auth: flags.auth ?? DEFAULT_CONFIG.auth,
4038
- payments: flags.payments ?? DEFAULT_CONFIG.payments,
4039
- observability: flags.observability ?? DEFAULT_CONFIG.observability,
4040
- communication: normalizeCommunication$2(flags.communication ?? DEFAULT_CONFIG.communication),
4041
- addons: flags.addons ?? [...DEFAULT_CONFIG.addons],
4042
- examples: flags.examples ?? [...DEFAULT_CONFIG.examples],
4043
- testing: flags.testing ?? [...DEFAULT_CONFIG.testing],
4044
- git: flags.git ?? DEFAULT_CONFIG.git,
4045
- packageManager: flags.packageManager ?? DEFAULT_CONFIG.packageManager,
4046
- install: flags.install ?? DEFAULT_CONFIG.install,
4047
- dbSetup: flags.dbSetup ?? DEFAULT_CONFIG.dbSetup,
4048
- api: flags.api ?? DEFAULT_CONFIG.api,
4049
- webDeploy: flags.webDeploy ?? DEFAULT_CONFIG.webDeploy,
4050
- serverDeploy: flags.serverDeploy ?? DEFAULT_CONFIG.serverDeploy
4051
- };
4026
+ /** Prompts need a TTY on stdin; without one (CI, pipes, agents) they never resolve. */
4027
+ function canPromptForInput(stdin = process.stdin) {
4028
+ return stdin.isTTY === true;
4029
+ }
4030
+ async function gatherConfig(flags, projectName, projectDir, relativePath, stdin = process.stdin) {
4031
+ if (isSilent() || !canPromptForInput(stdin)) {
4032
+ if (!isSilent()) log.info(pc.yellow("No interactive terminal detected; using defaults for options not passed as flags."));
4033
+ return {
4034
+ projectName,
4035
+ projectDir,
4036
+ relativePath,
4037
+ addonOptions: flags.addonOptions,
4038
+ dbSetupOptions: flags.dbSetupOptions,
4039
+ frontend: flags.frontend ?? [...DEFAULT_CONFIG.frontend],
4040
+ backend: flags.backend ?? DEFAULT_CONFIG.backend,
4041
+ runtime: flags.runtime ?? DEFAULT_CONFIG.runtime,
4042
+ database: flags.database ?? DEFAULT_CONFIG.database,
4043
+ orm: flags.orm ?? DEFAULT_CONFIG.orm,
4044
+ auth: flags.auth ?? DEFAULT_CONFIG.auth,
4045
+ payments: flags.payments ?? DEFAULT_CONFIG.payments,
4046
+ observability: flags.observability ?? DEFAULT_CONFIG.observability,
4047
+ communication: normalizeCommunication$2(flags.communication ?? DEFAULT_CONFIG.communication),
4048
+ addons: flags.addons ?? [...DEFAULT_CONFIG.addons],
4049
+ examples: flags.examples ?? [...DEFAULT_CONFIG.examples],
4050
+ testing: flags.testing ?? [...DEFAULT_CONFIG.testing],
4051
+ git: flags.git ?? DEFAULT_CONFIG.git,
4052
+ packageManager: flags.packageManager ?? DEFAULT_CONFIG.packageManager,
4053
+ install: flags.install ?? DEFAULT_CONFIG.install,
4054
+ dbSetup: flags.dbSetup ?? DEFAULT_CONFIG.dbSetup,
4055
+ api: flags.api ?? DEFAULT_CONFIG.api,
4056
+ webDeploy: flags.webDeploy ?? DEFAULT_CONFIG.webDeploy,
4057
+ serverDeploy: flags.serverDeploy ?? DEFAULT_CONFIG.serverDeploy
4058
+ };
4059
+ }
4052
4060
  const result = await navigableGroup({
4053
4061
  frontend: ({ previousAnswer }) => getFrontendChoice(flags.frontend, flags.backend, flags.auth, previousAnswer),
4054
4062
  backend: ({ results, previousAnswer }) => getBackendFrameworkChoice(flags.backend, results.frontend, previousAnswer),
@@ -4176,50 +4184,162 @@ async function getProjectName(initialName) {
4176
4184
  }
4177
4185
  //#endregion
4178
4186
  //#region src/utils/telemetry.ts
4187
+ const TRUTHY = new Set([
4188
+ "1",
4189
+ "true",
4190
+ "yes"
4191
+ ]);
4192
+ function isTruthy(value) {
4193
+ return value !== void 0 && TRUTHY.has(value.toLowerCase());
4194
+ }
4179
4195
  /**
4180
4196
  * Returns true if telemetry/analytics should be enabled, false otherwise.
4181
4197
  *
4182
- * - If BTS_TELEMETRY_DISABLED is present and "1", disables analytics.
4183
- * - Otherwise, BTS_TELEMETRY: "0" disables, "1" enables (default: enabled).
4198
+ * Opt-out, checked in order:
4199
+ * - `KUBO_TELEMETRY_DISABLED=1` disables.
4200
+ * - `DO_NOT_TRACK=1` disables (https://consoledonottrack.com).
4201
+ * - Legacy `BTS_TELEMETRY_DISABLED=1` disables; legacy `BTS_TELEMETRY=0` disables.
4202
+ * - Otherwise enabled.
4184
4203
  */
4185
- function isTelemetryEnabled() {
4186
- const BTS_TELEMETRY_DISABLED = process.env.BTS_TELEMETRY_DISABLED;
4187
- const BTS_TELEMETRY = "0";
4188
- if (BTS_TELEMETRY_DISABLED !== void 0) return BTS_TELEMETRY_DISABLED !== "1";
4189
- if (BTS_TELEMETRY !== void 0) return BTS_TELEMETRY === "1";
4204
+ function isTelemetryEnabled(env = process.env) {
4205
+ if (isTruthy(env.KUBO_TELEMETRY_DISABLED)) return false;
4206
+ if (isTruthy(env.DO_NOT_TRACK)) return false;
4207
+ if (env.BTS_TELEMETRY_DISABLED !== void 0) return env.BTS_TELEMETRY_DISABLED !== "1";
4208
+ if (env.BTS_TELEMETRY !== void 0) return env.BTS_TELEMETRY === "1";
4190
4209
  return true;
4191
4210
  }
4211
+ /** Coding agents we can recognize from the environment they set for child processes. */
4212
+ const AGENT_ENV_MARKERS = [
4213
+ ["claude-code", "CLAUDECODE"],
4214
+ ["cursor", "CURSOR_AGENT"],
4215
+ ["cursor", "CURSOR_TRACE_ID"],
4216
+ ["codex", "CODEX_SANDBOX"],
4217
+ ["codex", "CODEX_MANAGED_BY_NPM"],
4218
+ ["gemini-cli", "GEMINI_CLI"],
4219
+ ["opencode", "OPENCODE"],
4220
+ ["amp", "AMP_CURRENT_THREAD_ID"],
4221
+ ["cline", "CLINE_ACTIVE"],
4222
+ ["replit", "REPL_ID"]
4223
+ ];
4224
+ function detectAgent(env = process.env) {
4225
+ const match = AGENT_ENV_MARKERS.find(([, envVar]) => Boolean(env[envVar]));
4226
+ if (match) return match[0];
4227
+ return env.AI_AGENT ? "other" : void 0;
4228
+ }
4229
+ function isCI(env = process.env) {
4230
+ return isTruthy(env.CI) || Boolean(env.GITHUB_ACTIONS || env.GITLAB_CI || env.BUILDKITE || env.CIRCLECI);
4231
+ }
4192
4232
  //#endregion
4193
4233
  //#region src/utils/analytics.ts
4194
- async function sendConvexEvent(payload) {}
4195
- async function trackProjectCreation(config, disableAnalytics = false) {
4196
- if (!isTelemetryEnabled() || disableAnalytics) return;
4197
- const { database, orm, backend, runtime, frontend, addons, examples, auth, payments, git, packageManager, install, dbSetup, api, webDeploy, serverDeploy } = config;
4234
+ const CONVEX_INGEST_URL = "https://moonlit-seal-677.convex.site/api/analytics/ingest";
4235
+ const SEND_TIMEOUT_MS = 2e3;
4236
+ const TELEMETRY_FILE = "telemetry.json";
4237
+ const TELEMETRY_DOCS_URL = "https://kubojs.dev/docs/analytics";
4238
+ let telemetrySource = "cli";
4239
+ /** Set once per process by entry points that are not the interactive terminal (e.g. MCP). */
4240
+ function setTelemetrySource(source) {
4241
+ telemetrySource = source;
4242
+ }
4243
+ /** The JS API (`create()`) reports as "api" unless an entry point (e.g. MCP) already set a source. */
4244
+ function markProgrammaticTelemetrySource() {
4245
+ if (telemetrySource === "cli") telemetrySource = "api";
4246
+ }
4247
+ function getTelemetryFilePath() {
4248
+ return path.join(envPaths("kubojs", { suffix: "" }).config, TELEMETRY_FILE);
4249
+ }
4250
+ function isTelemetryState(value) {
4251
+ return typeof value === "object" && value !== null && "installId" in value && typeof value.installId === "string" && "noticeShown" in value && typeof value.noticeShown === "boolean";
4252
+ }
4253
+ /**
4254
+ * Reads the anonymous install id (a random UUID, not derived from the machine or user),
4255
+ * creating it on first use. Returns undefined if the config dir is not writable.
4256
+ */
4257
+ async function loadTelemetryState() {
4258
+ const filePath = getTelemetryFilePath();
4259
+ const existing = await Result.tryPromise({
4260
+ try: async () => fs.readJson(filePath),
4261
+ catch: () => void 0
4262
+ });
4263
+ if (existing.isOk() && isTelemetryState(existing.value)) return existing.value;
4264
+ const state = {
4265
+ installId: randomUUID(),
4266
+ noticeShown: false
4267
+ };
4268
+ return (await Result.tryPromise({
4269
+ try: async () => {
4270
+ await fs.ensureDir(path.dirname(filePath));
4271
+ await fs.writeJson(filePath, state, { spaces: 2 });
4272
+ },
4273
+ catch: () => void 0
4274
+ })).isOk() ? state : void 0;
4275
+ }
4276
+ async function markNoticeShown(state) {
4198
4277
  await Result.tryPromise({
4199
- try: () => sendConvexEvent({
4200
- database,
4201
- orm,
4202
- backend,
4203
- runtime,
4204
- frontend,
4205
- addons,
4206
- examples,
4207
- auth,
4208
- payments,
4209
- git,
4210
- packageManager,
4211
- install,
4212
- dbSetup,
4213
- api,
4214
- webDeploy,
4215
- serverDeploy,
4216
- cli_version: getLatestCLIVersion(),
4217
- node_version: typeof process !== "undefined" ? process.version : "",
4218
- platform: typeof process !== "undefined" ? process.platform : ""
4278
+ try: () => fs.writeJson(getTelemetryFilePath(), {
4279
+ ...state,
4280
+ noticeShown: true
4281
+ }, { spaces: 2 }),
4282
+ catch: () => void 0
4283
+ });
4284
+ }
4285
+ function showTelemetryNotice() {
4286
+ log.info(pc.dim(`kubojs collects anonymous usage data (stack choices, CLI version, OS) to guide development.
4287
+ No project names, paths or personal data. Opt out with KUBO_TELEMETRY_DISABLED=1.
4288
+ Details: ${TELEMETRY_DOCS_URL}`));
4289
+ }
4290
+ async function sendConvexEvent(payload) {
4291
+ await Result.tryPromise({
4292
+ try: () => fetch(CONVEX_INGEST_URL, {
4293
+ method: "POST",
4294
+ headers: { "Content-Type": "application/json" },
4295
+ body: JSON.stringify(payload),
4296
+ signal: AbortSignal.timeout(SEND_TIMEOUT_MS)
4219
4297
  }),
4220
4298
  catch: () => void 0
4221
4299
  });
4222
4300
  }
4301
+ function getStackPayload(config) {
4302
+ return {
4303
+ database: config.database,
4304
+ orm: config.orm,
4305
+ backend: config.backend,
4306
+ runtime: config.runtime,
4307
+ frontend: config.frontend,
4308
+ addons: config.addons,
4309
+ examples: config.examples,
4310
+ auth: config.auth,
4311
+ payments: config.payments,
4312
+ git: config.git,
4313
+ packageManager: config.packageManager,
4314
+ install: config.install,
4315
+ dbSetup: config.dbSetup,
4316
+ api: config.api,
4317
+ webDeploy: config.webDeploy,
4318
+ serverDeploy: config.serverDeploy
4319
+ };
4320
+ }
4321
+ async function trackCreateEvent(event, disableAnalytics = false) {
4322
+ if (!isTelemetryEnabled() || disableAnalytics) return;
4323
+ const state = await loadTelemetryState();
4324
+ if (state && !state.noticeShown && !isSilent()) {
4325
+ showTelemetryNotice();
4326
+ await markNoticeShown(state);
4327
+ }
4328
+ await sendConvexEvent({
4329
+ ...event.config ? getStackPayload(event.config) : {},
4330
+ install_id: state?.installId,
4331
+ source: telemetrySource,
4332
+ mode: event.mode,
4333
+ agent: detectAgent(),
4334
+ ci: isCI(),
4335
+ outcome: event.outcome,
4336
+ error_category: event.errorCategory,
4337
+ duration_ms: event.durationMs,
4338
+ cli_version: getLatestCLIVersion(),
4339
+ node_version: process.version,
4340
+ platform: process.platform
4341
+ });
4342
+ }
4223
4343
  //#endregion
4224
4344
  //#region src/utils/display-config.ts
4225
4345
  function displayConfig(config) {
@@ -6583,10 +6703,26 @@ async function createProjectHandler(input, options = {}) {
6583
6703
  const startTime = Date.now();
6584
6704
  const timeScaffolded = (/* @__PURE__ */ new Date()).toISOString();
6585
6705
  const result = await createProjectHandlerInternal(input, startTime, timeScaffolded);
6586
- if (result.isOk()) return result.value;
6706
+ const mode = getTelemetryMode(input);
6707
+ if (result.isOk()) {
6708
+ if (!input.dryRun) await trackCreateEvent({
6709
+ outcome: "success",
6710
+ mode,
6711
+ durationMs: result.value.elapsedTimeMs,
6712
+ config: result.value.projectConfig
6713
+ }, input.disableAnalytics);
6714
+ return result.value;
6715
+ }
6587
6716
  const error = result.error;
6588
6717
  const elapsedTimeMs = Date.now() - startTime;
6589
- if (UserCancelledError.is(error)) {
6718
+ const cancelled = UserCancelledError.is(error);
6719
+ if (!input.dryRun) await trackCreateEvent({
6720
+ outcome: cancelled ? "cancelled" : "failure",
6721
+ mode,
6722
+ durationMs: elapsedTimeMs,
6723
+ errorCategory: cancelled ? void 0 : getErrorCategory(error)
6724
+ }, input.disableAnalytics);
6725
+ if (cancelled) {
6590
6726
  if (isSilent()) return createEmptyResult(timeScaffolded, elapsedTimeMs, error.message);
6591
6727
  return;
6592
6728
  }
@@ -6595,6 +6731,38 @@ async function createProjectHandler(input, options = {}) {
6595
6731
  process.exit(1);
6596
6732
  });
6597
6733
  }
6734
+ /** Stack-selecting flags; their presence means the user chose the stack via flags, not prompts. */
6735
+ const STACK_FLAG_KEYS = [
6736
+ "database",
6737
+ "orm",
6738
+ "backend",
6739
+ "runtime",
6740
+ "frontend",
6741
+ "api",
6742
+ "auth",
6743
+ "payments",
6744
+ "addons",
6745
+ "examples",
6746
+ "dbSetup",
6747
+ "webDeploy",
6748
+ "serverDeploy"
6749
+ ];
6750
+ function getTelemetryMode(input) {
6751
+ if (input.template && input.template !== "none") return "template";
6752
+ if (input.yes) return "yes";
6753
+ if (isSilent() || STACK_FLAG_KEYS.some((key) => input[key] !== void 0)) return "flags";
6754
+ return "interactive";
6755
+ }
6756
+ function getTag(value) {
6757
+ if (typeof value !== "object" || value === null || !("_tag" in value)) return void 0;
6758
+ return typeof value._tag === "string" ? value._tag : void 0;
6759
+ }
6760
+ /** Error class names only (e.g. `CLIError:ValidationError`), never messages or paths. */
6761
+ function getErrorCategory(error) {
6762
+ const tag = getTag(error) ?? "UnknownError";
6763
+ const causeTag = "cause" in error ? getTag(error.cause) : void 0;
6764
+ return causeTag ? `${tag}:${causeTag}` : tag;
6765
+ }
6598
6766
  async function createProjectHandlerInternal(input, startTime, timeScaffolded) {
6599
6767
  return Result.gen(async function* () {
6600
6768
  if (!isSilent() && input.renderTitle !== false) renderTitle();
@@ -6760,7 +6928,6 @@ async function createProjectHandlerInternal(input, startTime, timeScaffolded) {
6760
6928
  dbSetupOptions: effectiveDbSetupOptions
6761
6929
  }));
6762
6930
  if (!isSilent()) log.success(cliColors.bright(`You can reproduce this setup with the following command:\n${reproducibleCommand}`));
6763
- await trackProjectCreation(config, input.disableAnalytics);
6764
6931
  const historyResult = await addToHistory(config, reproducibleCommand);
6765
6932
  if (historyResult.isErr() && !isSilent()) log.warn(pc.yellow(historyResult.error.message));
6766
6933
  const elapsedTimeMs = Date.now() - startTime;
@@ -6952,6 +7119,7 @@ const router = t.router({
6952
7119
  description: "Create a project from a raw JSON payload (agent-friendly)",
6953
7120
  jsonInput: true
6954
7121
  }).input(types_exports.CreateInputSchema).mutation(async ({ input }) => {
7122
+ setTelemetrySource("json");
6955
7123
  const result = await createProjectHandler(input, { silent: true });
6956
7124
  if (!result) throw new UserCancelledError({ message: "Operation cancelled" });
6957
7125
  if (!result.success) throw new CLIError({ message: result.error || "Unknown error occurred" });
@@ -7019,6 +7187,7 @@ function createBtsCli() {
7019
7187
  * ```
7020
7188
  */
7021
7189
  async function create(projectName, options) {
7190
+ markProgrammaticTelemetrySource();
7022
7191
  const input = {
7023
7192
  ...options,
7024
7193
  projectName,
@@ -7154,4 +7323,4 @@ async function add(options = {}) {
7154
7323
  return addHandler(options, { silent: true });
7155
7324
  }
7156
7325
  //#endregion
7157
- export { UserCancelledError as C, ProjectCreationError as S, getLatestCLIVersion as _, TEMPLATE_COUNT as a, DatabaseSetupError as b, builder as c, createVirtual as d, docs as f, types_exports 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, CLIError as v, ValidationError as w, DirectoryConflictError as x, CompatibilityError as y };
7326
+ 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, setTelemetrySource 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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-kubojs",
3
- "version": "0.4.1",
3
+ "version": "0.5.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",
@@ -73,8 +73,8 @@
73
73
  "dependencies": {
74
74
  "@clack/core": "^1.4.1",
75
75
  "@clack/prompts": "^1.5.1",
76
- "@kubojs/template-generator": "^0.4.1",
77
- "@kubojs/types": "^0.4.1",
76
+ "@kubojs/template-generator": "^0.5.1",
77
+ "@kubojs/types": "^0.5.1",
78
78
  "@modelcontextprotocol/sdk": "1.29.0",
79
79
  "@tanstack/router-generator": "1.167.28",
80
80
  "@trpc/server": "^11.17.0",
@@ -93,7 +93,7 @@
93
93
  "trpc-cli": "^0.14.1",
94
94
  "ts-morph": "^28.0.0",
95
95
  "yaml": "^2.9.0",
96
- "zod": "^4.4.3"
96
+ "zod": "~4.4.3"
97
97
  },
98
98
  "devDependencies": {
99
99
  "@types/bun": "^1.3.14",