create-kubojs 0.4.1 → 0.5.0
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 +14 -10
- package/dist/cli.mjs +3 -2
- package/dist/index.mjs +1 -1
- package/dist/{src-L3WKWfns.mjs → src-QAuuh4xm.mjs} +96 -74
- package/package.json +4 -4
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.
|
|
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
|
-
-
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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-QAuuh4xm.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:
|
|
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
|
|
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-QAuuh4xm.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 };
|
|
@@ -4022,33 +4022,40 @@ async function getDeploymentChoice(deployment, _runtime, backend, frontend = [],
|
|
|
4022
4022
|
}
|
|
4023
4023
|
//#endregion
|
|
4024
4024
|
//#region src/prompts/config-prompts.ts
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4025
|
+
/** Prompts need a TTY on stdin; without one (CI, pipes, agents) they never resolve. */
|
|
4026
|
+
function canPromptForInput(stdin = process.stdin) {
|
|
4027
|
+
return stdin.isTTY === true;
|
|
4028
|
+
}
|
|
4029
|
+
async function gatherConfig(flags, projectName, projectDir, relativePath, stdin = process.stdin) {
|
|
4030
|
+
if (isSilent() || !canPromptForInput(stdin)) {
|
|
4031
|
+
if (!isSilent()) log.info(pc.yellow("No interactive terminal detected; using defaults for options not passed as flags."));
|
|
4032
|
+
return {
|
|
4033
|
+
projectName,
|
|
4034
|
+
projectDir,
|
|
4035
|
+
relativePath,
|
|
4036
|
+
addonOptions: flags.addonOptions,
|
|
4037
|
+
dbSetupOptions: flags.dbSetupOptions,
|
|
4038
|
+
frontend: flags.frontend ?? [...DEFAULT_CONFIG.frontend],
|
|
4039
|
+
backend: flags.backend ?? DEFAULT_CONFIG.backend,
|
|
4040
|
+
runtime: flags.runtime ?? DEFAULT_CONFIG.runtime,
|
|
4041
|
+
database: flags.database ?? DEFAULT_CONFIG.database,
|
|
4042
|
+
orm: flags.orm ?? DEFAULT_CONFIG.orm,
|
|
4043
|
+
auth: flags.auth ?? DEFAULT_CONFIG.auth,
|
|
4044
|
+
payments: flags.payments ?? DEFAULT_CONFIG.payments,
|
|
4045
|
+
observability: flags.observability ?? DEFAULT_CONFIG.observability,
|
|
4046
|
+
communication: normalizeCommunication$2(flags.communication ?? DEFAULT_CONFIG.communication),
|
|
4047
|
+
addons: flags.addons ?? [...DEFAULT_CONFIG.addons],
|
|
4048
|
+
examples: flags.examples ?? [...DEFAULT_CONFIG.examples],
|
|
4049
|
+
testing: flags.testing ?? [...DEFAULT_CONFIG.testing],
|
|
4050
|
+
git: flags.git ?? DEFAULT_CONFIG.git,
|
|
4051
|
+
packageManager: flags.packageManager ?? DEFAULT_CONFIG.packageManager,
|
|
4052
|
+
install: flags.install ?? DEFAULT_CONFIG.install,
|
|
4053
|
+
dbSetup: flags.dbSetup ?? DEFAULT_CONFIG.dbSetup,
|
|
4054
|
+
api: flags.api ?? DEFAULT_CONFIG.api,
|
|
4055
|
+
webDeploy: flags.webDeploy ?? DEFAULT_CONFIG.webDeploy,
|
|
4056
|
+
serverDeploy: flags.serverDeploy ?? DEFAULT_CONFIG.serverDeploy
|
|
4057
|
+
};
|
|
4058
|
+
}
|
|
4052
4059
|
const result = await navigableGroup({
|
|
4053
4060
|
frontend: ({ previousAnswer }) => getFrontendChoice(flags.frontend, flags.backend, flags.auth, previousAnswer),
|
|
4054
4061
|
backend: ({ results, previousAnswer }) => getBackendFrameworkChoice(flags.backend, results.frontend, previousAnswer),
|
|
@@ -4175,51 +4182,17 @@ async function getProjectName(initialName) {
|
|
|
4175
4182
|
return projectPath;
|
|
4176
4183
|
}
|
|
4177
4184
|
//#endregion
|
|
4178
|
-
//#region src/utils/telemetry.ts
|
|
4179
|
-
/**
|
|
4180
|
-
* Returns true if telemetry/analytics should be enabled, false otherwise.
|
|
4181
|
-
*
|
|
4182
|
-
* - If BTS_TELEMETRY_DISABLED is present and "1", disables analytics.
|
|
4183
|
-
* - Otherwise, BTS_TELEMETRY: "0" disables, "1" enables (default: enabled).
|
|
4184
|
-
*/
|
|
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";
|
|
4190
|
-
return true;
|
|
4191
|
-
}
|
|
4192
|
-
//#endregion
|
|
4193
4185
|
//#region src/utils/analytics.ts
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
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 : ""
|
|
4219
|
-
}),
|
|
4220
|
-
catch: () => void 0
|
|
4221
|
-
});
|
|
4186
|
+
let telemetrySource = "cli";
|
|
4187
|
+
/** Set once per process by entry points that are not the interactive terminal (e.g. MCP). */
|
|
4188
|
+
function setTelemetrySource(source) {
|
|
4189
|
+
telemetrySource = source;
|
|
4190
|
+
}
|
|
4191
|
+
/** The JS API (`create()`) reports as "api" unless an entry point (e.g. MCP) already set a source. */
|
|
4192
|
+
function markProgrammaticTelemetrySource() {
|
|
4193
|
+
if (telemetrySource === "cli") telemetrySource = "api";
|
|
4222
4194
|
}
|
|
4195
|
+
async function trackCreateEvent(event, disableAnalytics = false) {}
|
|
4223
4196
|
//#endregion
|
|
4224
4197
|
//#region src/utils/display-config.ts
|
|
4225
4198
|
function displayConfig(config) {
|
|
@@ -6583,10 +6556,26 @@ async function createProjectHandler(input, options = {}) {
|
|
|
6583
6556
|
const startTime = Date.now();
|
|
6584
6557
|
const timeScaffolded = (/* @__PURE__ */ new Date()).toISOString();
|
|
6585
6558
|
const result = await createProjectHandlerInternal(input, startTime, timeScaffolded);
|
|
6586
|
-
|
|
6559
|
+
const mode = getTelemetryMode(input);
|
|
6560
|
+
if (result.isOk()) {
|
|
6561
|
+
if (!input.dryRun) await trackCreateEvent({
|
|
6562
|
+
outcome: "success",
|
|
6563
|
+
mode,
|
|
6564
|
+
durationMs: result.value.elapsedTimeMs,
|
|
6565
|
+
config: result.value.projectConfig
|
|
6566
|
+
}, input.disableAnalytics);
|
|
6567
|
+
return result.value;
|
|
6568
|
+
}
|
|
6587
6569
|
const error = result.error;
|
|
6588
6570
|
const elapsedTimeMs = Date.now() - startTime;
|
|
6589
|
-
|
|
6571
|
+
const cancelled = UserCancelledError.is(error);
|
|
6572
|
+
if (!input.dryRun) await trackCreateEvent({
|
|
6573
|
+
outcome: cancelled ? "cancelled" : "failure",
|
|
6574
|
+
mode,
|
|
6575
|
+
durationMs: elapsedTimeMs,
|
|
6576
|
+
errorCategory: cancelled ? void 0 : getErrorCategory(error)
|
|
6577
|
+
}, input.disableAnalytics);
|
|
6578
|
+
if (cancelled) {
|
|
6590
6579
|
if (isSilent()) return createEmptyResult(timeScaffolded, elapsedTimeMs, error.message);
|
|
6591
6580
|
return;
|
|
6592
6581
|
}
|
|
@@ -6595,6 +6584,38 @@ async function createProjectHandler(input, options = {}) {
|
|
|
6595
6584
|
process.exit(1);
|
|
6596
6585
|
});
|
|
6597
6586
|
}
|
|
6587
|
+
/** Stack-selecting flags; their presence means the user chose the stack via flags, not prompts. */
|
|
6588
|
+
const STACK_FLAG_KEYS = [
|
|
6589
|
+
"database",
|
|
6590
|
+
"orm",
|
|
6591
|
+
"backend",
|
|
6592
|
+
"runtime",
|
|
6593
|
+
"frontend",
|
|
6594
|
+
"api",
|
|
6595
|
+
"auth",
|
|
6596
|
+
"payments",
|
|
6597
|
+
"addons",
|
|
6598
|
+
"examples",
|
|
6599
|
+
"dbSetup",
|
|
6600
|
+
"webDeploy",
|
|
6601
|
+
"serverDeploy"
|
|
6602
|
+
];
|
|
6603
|
+
function getTelemetryMode(input) {
|
|
6604
|
+
if (input.template && input.template !== "none") return "template";
|
|
6605
|
+
if (input.yes) return "yes";
|
|
6606
|
+
if (isSilent() || STACK_FLAG_KEYS.some((key) => input[key] !== void 0)) return "flags";
|
|
6607
|
+
return "interactive";
|
|
6608
|
+
}
|
|
6609
|
+
function getTag(value) {
|
|
6610
|
+
if (typeof value !== "object" || value === null || !("_tag" in value)) return void 0;
|
|
6611
|
+
return typeof value._tag === "string" ? value._tag : void 0;
|
|
6612
|
+
}
|
|
6613
|
+
/** Error class names only (e.g. `CLIError:ValidationError`), never messages or paths. */
|
|
6614
|
+
function getErrorCategory(error) {
|
|
6615
|
+
const tag = getTag(error) ?? "UnknownError";
|
|
6616
|
+
const causeTag = "cause" in error ? getTag(error.cause) : void 0;
|
|
6617
|
+
return causeTag ? `${tag}:${causeTag}` : tag;
|
|
6618
|
+
}
|
|
6598
6619
|
async function createProjectHandlerInternal(input, startTime, timeScaffolded) {
|
|
6599
6620
|
return Result.gen(async function* () {
|
|
6600
6621
|
if (!isSilent() && input.renderTitle !== false) renderTitle();
|
|
@@ -6760,7 +6781,6 @@ async function createProjectHandlerInternal(input, startTime, timeScaffolded) {
|
|
|
6760
6781
|
dbSetupOptions: effectiveDbSetupOptions
|
|
6761
6782
|
}));
|
|
6762
6783
|
if (!isSilent()) log.success(cliColors.bright(`You can reproduce this setup with the following command:\n${reproducibleCommand}`));
|
|
6763
|
-
await trackProjectCreation(config, input.disableAnalytics);
|
|
6764
6784
|
const historyResult = await addToHistory(config, reproducibleCommand);
|
|
6765
6785
|
if (historyResult.isErr() && !isSilent()) log.warn(pc.yellow(historyResult.error.message));
|
|
6766
6786
|
const elapsedTimeMs = Date.now() - startTime;
|
|
@@ -6952,6 +6972,7 @@ const router = t.router({
|
|
|
6952
6972
|
description: "Create a project from a raw JSON payload (agent-friendly)",
|
|
6953
6973
|
jsonInput: true
|
|
6954
6974
|
}).input(types_exports.CreateInputSchema).mutation(async ({ input }) => {
|
|
6975
|
+
setTelemetrySource("json");
|
|
6955
6976
|
const result = await createProjectHandler(input, { silent: true });
|
|
6956
6977
|
if (!result) throw new UserCancelledError({ message: "Operation cancelled" });
|
|
6957
6978
|
if (!result.success) throw new CLIError({ message: result.error || "Unknown error occurred" });
|
|
@@ -7019,6 +7040,7 @@ function createBtsCli() {
|
|
|
7019
7040
|
* ```
|
|
7020
7041
|
*/
|
|
7021
7042
|
async function create(projectName, options) {
|
|
7043
|
+
markProgrammaticTelemetrySource();
|
|
7022
7044
|
const input = {
|
|
7023
7045
|
...options,
|
|
7024
7046
|
projectName,
|
|
@@ -7154,4 +7176,4 @@ async function add(options = {}) {
|
|
|
7154
7176
|
return addHandler(options, { silent: true });
|
|
7155
7177
|
}
|
|
7156
7178
|
//#endregion
|
|
7157
|
-
export {
|
|
7179
|
+
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.
|
|
3
|
+
"version": "0.5.0",
|
|
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.
|
|
77
|
-
"@kubojs/types": "^0.
|
|
76
|
+
"@kubojs/template-generator": "^0.5.0",
|
|
77
|
+
"@kubojs/types": "^0.5.0",
|
|
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": "
|
|
96
|
+
"zod": "~4.4.3"
|
|
97
97
|
},
|
|
98
98
|
"devDependencies": {
|
|
99
99
|
"@types/bun": "^1.3.14",
|