create-better-t-stack 3.41.1 → 3.41.2
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 +1 -1
- package/dist/cli.mjs +13 -51
- package/dist/index.d.mts +0 -3
- package/dist/index.mjs +1 -1
- package/dist/{src-pRksmzD7.mjs → src-CCnlcJnd.mjs} +26 -123
- package/package.json +3 -3
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,
|
|
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 {
|
|
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-CCnlcJnd.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
|
-
},
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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
|
-
}
|
|
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
|
-
},
|
|
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
|
-
}
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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">;
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as
|
|
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-CCnlcJnd.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
|
-
*
|
|
1760
|
-
* not to the Convex project dataset
|
|
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:
|
|
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:
|
|
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
|
}
|
|
@@ -4921,9 +4888,8 @@ async function addHandler(input, options = {}) {
|
|
|
4921
4888
|
silent,
|
|
4922
4889
|
mode
|
|
4923
4890
|
}, async () => {
|
|
4924
|
-
const startTime = Date.now();
|
|
4925
4891
|
const result = await addHandlerInternal(input);
|
|
4926
|
-
await reportAddOutcome(input, result
|
|
4892
|
+
await reportAddOutcome(input, result);
|
|
4927
4893
|
if (result.isOk()) return result.value;
|
|
4928
4894
|
const error = result.error;
|
|
4929
4895
|
if (UserCancelledError.is(error)) {
|
|
@@ -4945,36 +4911,13 @@ async function addHandler(input, options = {}) {
|
|
|
4945
4911
|
process.exit(1);
|
|
4946
4912
|
});
|
|
4947
4913
|
}
|
|
4948
|
-
async function reportAddOutcome(input, result
|
|
4949
|
-
|
|
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
|
-
}
|
|
4914
|
+
async function reportAddOutcome(input, result) {
|
|
4915
|
+
if (result.isOk()) return;
|
|
4960
4916
|
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
|
-
});
|
|
4917
|
+
if (UserCancelledError.is(error)) return;
|
|
4975
4918
|
await reportDiagnostic("cli_failed", {
|
|
4976
4919
|
command: "add",
|
|
4977
|
-
mode,
|
|
4920
|
+
mode: resolveInvocationMode(false),
|
|
4978
4921
|
stage: failureStage(error),
|
|
4979
4922
|
error: errorClass(error),
|
|
4980
4923
|
reason: scrubReason(error),
|
|
@@ -6278,11 +6221,8 @@ async function gatherConfig(flags, projectName, projectDir, relativePath, option
|
|
|
6278
6221
|
]
|
|
6279
6222
|
}
|
|
6280
6223
|
],
|
|
6281
|
-
onCancel: (
|
|
6282
|
-
throw new UserCancelledError({
|
|
6283
|
-
message: "Operation cancelled",
|
|
6284
|
-
prompt
|
|
6285
|
-
});
|
|
6224
|
+
onCancel: () => {
|
|
6225
|
+
throw new UserCancelledError({ message: "Operation cancelled" });
|
|
6286
6226
|
}
|
|
6287
6227
|
});
|
|
6288
6228
|
return {
|
|
@@ -6367,10 +6307,7 @@ async function getProjectName(initialName) {
|
|
|
6367
6307
|
}
|
|
6368
6308
|
}
|
|
6369
6309
|
});
|
|
6370
|
-
if (isCancel(response)) throw new UserCancelledError({
|
|
6371
|
-
message: "Operation cancelled.",
|
|
6372
|
-
prompt: "projectName"
|
|
6373
|
-
});
|
|
6310
|
+
if (isCancel(response)) throw new UserCancelledError({ message: "Operation cancelled." });
|
|
6374
6311
|
projectPath = response || defaultName;
|
|
6375
6312
|
isValid = true;
|
|
6376
6313
|
}
|
|
@@ -8964,7 +8901,6 @@ async function createProject(options, cliInput) {
|
|
|
8964
8901
|
return Result.gen(async function* () {
|
|
8965
8902
|
const projectDir = options.projectDir;
|
|
8966
8903
|
const isConvex = options.backend === "convex";
|
|
8967
|
-
const scaffoldStartTime = Date.now();
|
|
8968
8904
|
yield* Result.await(Result.tryPromise({
|
|
8969
8905
|
try: () => fs.ensureDir(projectDir),
|
|
8970
8906
|
catch: (e) => new ProjectCreationError({
|
|
@@ -9006,15 +8942,10 @@ async function createProject(options, cliInput) {
|
|
|
9006
8942
|
}));
|
|
9007
8943
|
yield* Result.await(formatProject(projectDir));
|
|
9008
8944
|
if (!isSilent()) log.success("Project scaffolded");
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
projectDir,
|
|
9014
|
-
packageManager: options.packageManager
|
|
9015
|
-
}));
|
|
9016
|
-
await reportSlowStage("create", "install", Date.now() - installStartTime, options.packageManager);
|
|
9017
|
-
}
|
|
8945
|
+
if (options.install) yield* Result.await(installDependencies({
|
|
8946
|
+
projectDir,
|
|
8947
|
+
packageManager: options.packageManager
|
|
8948
|
+
}));
|
|
9018
8949
|
yield* Result.await(initializeGit(projectDir, options.git));
|
|
9019
8950
|
if (!isSilent()) await displayPostInstallInstructions({
|
|
9020
8951
|
...options,
|
|
@@ -9094,22 +9025,14 @@ async function executeCreateProjectHandler(input, options) {
|
|
|
9094
9025
|
};
|
|
9095
9026
|
});
|
|
9096
9027
|
}
|
|
9097
|
-
/**
|
|
9028
|
+
/** Failure diagnostics, which the success-only project event cannot show; awaited so it beats process.exit. */
|
|
9098
9029
|
async function reportCreateOutcome(input, result) {
|
|
9099
|
-
const mode = resolveInvocationMode(input.yes);
|
|
9100
9030
|
if (result.isOk()) return;
|
|
9101
9031
|
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
|
-
}
|
|
9032
|
+
if (UserCancelledError.is(error)) return;
|
|
9110
9033
|
await reportDiagnostic("cli_failed", {
|
|
9111
9034
|
command: "create",
|
|
9112
|
-
mode,
|
|
9035
|
+
mode: resolveInvocationMode(input.yes),
|
|
9113
9036
|
stage: failureStage(error),
|
|
9114
9037
|
error: errorClass(error),
|
|
9115
9038
|
reason: scrubReason(error),
|
|
@@ -9499,9 +9422,9 @@ const router = t.router({
|
|
|
9499
9422
|
return result;
|
|
9500
9423
|
}),
|
|
9501
9424
|
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(() =>
|
|
9503
|
-
docs: t.procedure.meta({ description: "Open Better-T-Stack documentation" }).mutation(() =>
|
|
9504
|
-
builder: t.procedure.meta({ description: "Open the web-based stack builder" }).mutation(() =>
|
|
9425
|
+
sponsors: t.procedure.meta({ description: "Show Better-T-Stack sponsors" }).mutation(() => showSponsorsCommand()),
|
|
9426
|
+
docs: t.procedure.meta({ description: "Open Better-T-Stack documentation" }).mutation(() => openDocsCommand()),
|
|
9427
|
+
builder: t.procedure.meta({ description: "Open the web-based stack builder" }).mutation(() => openBuilderCommand()),
|
|
9505
9428
|
add: t.procedure.meta({ description: "Add addons or a workspace package to an existing Better-T-Stack project" }).input(z.object({
|
|
9506
9429
|
addons: z.array(types_exports.AddonsSchema).optional().describe("Addons to add"),
|
|
9507
9430
|
package: types_exports.WorkspacePackageNameSchema.optional(),
|
|
@@ -9529,29 +9452,9 @@ const router = t.router({
|
|
|
9529
9452
|
clear: z.boolean().optional().default(false).describe("Clear all history"),
|
|
9530
9453
|
json: z.boolean().optional().default(false).describe("Output as JSON")
|
|
9531
9454
|
})).mutation(async ({ input }) => {
|
|
9532
|
-
await
|
|
9455
|
+
await historyHandler(input);
|
|
9533
9456
|
})
|
|
9534
9457
|
});
|
|
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
9458
|
function createBtsCli() {
|
|
9556
9459
|
return createCli({
|
|
9557
9460
|
router,
|
|
@@ -9738,4 +9641,4 @@ async function add(options = {}) {
|
|
|
9738
9641
|
};
|
|
9739
9642
|
}
|
|
9740
9643
|
//#endregion
|
|
9741
|
-
export {
|
|
9644
|
+
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.
|
|
3
|
+
"version": "3.41.2",
|
|
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.
|
|
73
|
-
"@better-t-stack/types": "^3.41.
|
|
72
|
+
"@better-t-stack/template-generator": "^3.41.2",
|
|
73
|
+
"@better-t-stack/types": "^3.41.2",
|
|
74
74
|
"@clack/core": "^1.4.3",
|
|
75
75
|
"@clack/prompts": "^1.7.0",
|
|
76
76
|
"@modelcontextprotocol/server": "2.0.0",
|