@kubb/cli 5.9.2 → 5.9.4

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.
Files changed (108) hide show
  1. package/dist/Telemetry-ByFeVTz5.cjs +314 -0
  2. package/dist/Telemetry-ByFeVTz5.cjs.map +1 -0
  3. package/dist/Telemetry-E_BBHmnT.js +259 -0
  4. package/dist/Telemetry-E_BBHmnT.js.map +1 -0
  5. package/dist/background-CZ2nVKwB.js +1 -0
  6. package/dist/{background-Bh4FDWa3.cjs → background-DdUVvDwi.cjs} +7 -6
  7. package/dist/{background-Bh4FDWa3.cjs.map → background-DdUVvDwi.cjs.map} +1 -1
  8. package/dist/{background-B0YbkZ0s.js → background-H30JH70B.js} +3 -2
  9. package/dist/{background-B0YbkZ0s.js.map → background-H30JH70B.js.map} +1 -1
  10. package/dist/{reporters-B4rZOlo8.cjs → config-Ck2JHe5r.cjs} +36 -4
  11. package/dist/config-Ck2JHe5r.cjs.map +1 -0
  12. package/dist/{reporters-H21Jvrff.js → config-DxePdyxe.js} +29 -3
  13. package/dist/config-DxePdyxe.js.map +1 -0
  14. package/dist/credentials-C8tjAhTo.js +1 -0
  15. package/dist/credentials-CZK6zPLv.js +62 -0
  16. package/dist/credentials-CZK6zPLv.js.map +1 -0
  17. package/dist/credentials-DDaKqtJn.cjs +113 -0
  18. package/dist/credentials-DDaKqtJn.cjs.map +1 -0
  19. package/dist/index.cjs +702 -207
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.js +697 -206
  22. package/dist/index.js.map +1 -1
  23. package/dist/{output-BnK0scpX.cjs → output-Cd3Kmvo0.cjs} +141 -66
  24. package/dist/output-Cd3Kmvo0.cjs.map +1 -0
  25. package/dist/{output-qFt4vV7K.js → output-DS5hyqwL.js} +173 -129
  26. package/dist/output-DS5hyqwL.js.map +1 -0
  27. package/dist/{registry-B7BvdrGE.js → registry-CSXUuuCy.js} +2 -2
  28. package/dist/{registry-B7BvdrGE.js.map → registry-CSXUuuCy.js.map} +1 -1
  29. package/dist/{registry-DER9aRyg.cjs → registry-CrvQxnxy.cjs} +6 -6
  30. package/dist/{registry-DER9aRyg.cjs.map → registry-CrvQxnxy.cjs.map} +1 -1
  31. package/dist/rolldown-runtime-CPE0t6oh.cjs +53 -0
  32. package/dist/{run-BcMMYk7G.js → run-BPD5Vaon.js} +5 -7
  33. package/dist/{run-BcMMYk7G.js.map → run-BPD5Vaon.js.map} +1 -1
  34. package/dist/{run-e8gMz1M_.cjs → run-C0Tfrddq.cjs} +5 -6
  35. package/dist/{run-e8gMz1M_.cjs.map → run-C0Tfrddq.cjs.map} +1 -1
  36. package/dist/{run-fg0ycsS_.cjs → run-CbN00IHp.cjs} +16 -18
  37. package/dist/{run-fg0ycsS_.cjs.map → run-CbN00IHp.cjs.map} +1 -1
  38. package/dist/{run-KLPSFEv-.js → run-CecrPSop.js} +2 -3
  39. package/dist/{run-KLPSFEv-.js.map → run-CecrPSop.js.map} +1 -1
  40. package/dist/{run-BCswmM8Q.js → run-Ck04_W4q.js} +2 -3
  41. package/dist/{run-BCswmM8Q.js.map → run-Ck04_W4q.js.map} +1 -1
  42. package/dist/{run-BQQhNg8I.js → run-DcP1czVQ.js} +25 -84
  43. package/dist/run-DcP1czVQ.js.map +1 -0
  44. package/dist/{run-D8EJ2hKI.cjs → run-Dyc52IzX.cjs} +5 -6
  45. package/dist/{run-D8EJ2hKI.cjs.map → run-Dyc52IzX.cjs.map} +1 -1
  46. package/dist/{run-C8dyBAPb.cjs → run-QqLDhthl.cjs} +46 -158
  47. package/dist/run-QqLDhthl.cjs.map +1 -0
  48. package/dist/run-WkXSXG2V.js +1 -0
  49. package/dist/{snapshot-B45A4RfA.cjs → snapshot-NGLcfG6E.cjs} +17 -26
  50. package/dist/snapshot-NGLcfG6E.cjs.map +1 -0
  51. package/dist/{snapshot-C0WaZZiF.js → snapshot-iEjgROga.js} +15 -24
  52. package/dist/snapshot-iEjgROga.js.map +1 -0
  53. package/dist/studioWorker.js +2 -2
  54. package/package.json +7 -8
  55. package/dist/Telemetry-B_C4MVJd.cjs +0 -231
  56. package/dist/Telemetry-B_C4MVJd.cjs.map +0 -1
  57. package/dist/Telemetry-DER8LIO5.js +0 -207
  58. package/dist/Telemetry-DER8LIO5.js.map +0 -1
  59. package/dist/agent-BPIqnEl2.js +0 -59
  60. package/dist/agent-BPIqnEl2.js.map +0 -1
  61. package/dist/agent-DElUuYuy.cjs +0 -120
  62. package/dist/agent-DElUuYuy.cjs.map +0 -1
  63. package/dist/background-DSKoOwcG.js +0 -1
  64. package/dist/commands-BegVe5Mt.js +0 -81
  65. package/dist/commands-BegVe5Mt.js.map +0 -1
  66. package/dist/commands-hXDwA0zn.cjs +0 -87
  67. package/dist/commands-hXDwA0zn.cjs.map +0 -1
  68. package/dist/config-B6UIKcl1.js +0 -117
  69. package/dist/config-B6UIKcl1.js.map +0 -1
  70. package/dist/config-Bo9ro7vg.cjs +0 -129
  71. package/dist/config-Bo9ro7vg.cjs.map +0 -1
  72. package/dist/constants-Cii4HX64.js +0 -12
  73. package/dist/constants-Cii4HX64.js.map +0 -1
  74. package/dist/constants-Df449N47.cjs +0 -29
  75. package/dist/constants-Df449N47.cjs.map +0 -1
  76. package/dist/errors-BdA8M78q.cjs +0 -43
  77. package/dist/errors-BdA8M78q.cjs.map +0 -1
  78. package/dist/errors-DmC83ALX.js +0 -32
  79. package/dist/errors-DmC83ALX.js.map +0 -1
  80. package/dist/output-BnK0scpX.cjs.map +0 -1
  81. package/dist/output-qFt4vV7K.js.map +0 -1
  82. package/dist/reporters-B4rZOlo8.cjs.map +0 -1
  83. package/dist/reporters-H21Jvrff.js.map +0 -1
  84. package/dist/run-89YfZJuo.cjs +0 -67
  85. package/dist/run-89YfZJuo.cjs.map +0 -1
  86. package/dist/run-8HrdMihy.js +0 -1
  87. package/dist/run-BQQhNg8I.js.map +0 -1
  88. package/dist/run-BYff_byB.js +0 -71
  89. package/dist/run-BYff_byB.js.map +0 -1
  90. package/dist/run-C8dyBAPb.cjs.map +0 -1
  91. package/dist/run-CJHsZZB8.js +0 -178
  92. package/dist/run-CJHsZZB8.js.map +0 -1
  93. package/dist/run-Ca_OX3WZ.js +0 -105
  94. package/dist/run-Ca_OX3WZ.js.map +0 -1
  95. package/dist/run-Ct6kzKpg.cjs +0 -109
  96. package/dist/run-Ct6kzKpg.cjs.map +0 -1
  97. package/dist/run-DL2wLwBZ.cjs +0 -182
  98. package/dist/run-DL2wLwBZ.cjs.map +0 -1
  99. package/dist/run-Dej-hm91.js +0 -65
  100. package/dist/run-Dej-hm91.js.map +0 -1
  101. package/dist/run-DpAMfkm5.cjs +0 -72
  102. package/dist/run-DpAMfkm5.cjs.map +0 -1
  103. package/dist/snapshot-B45A4RfA.cjs.map +0 -1
  104. package/dist/snapshot-C0WaZZiF.js.map +0 -1
  105. package/dist/utils-BHW8kA8P.js +0 -83
  106. package/dist/utils-BHW8kA8P.js.map +0 -1
  107. package/dist/utils-BzQ46pgd.cjs +0 -109
  108. package/dist/utils-BzQ46pgd.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"run-BCswmM8Q.js","names":[],"sources":["../src/runners/validate/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { toError } from '@internals/utils'\nimport { trackRun } from '../../Telemetry.ts'\n\ntype ValidateOptions = {\n /**\n * Path or URL to the OpenAPI/Swagger file to validate.\n */\n input: string\n}\n\n/**\n * Validates an OpenAPI/Swagger file at `input` using `@kubb/adapter-oas`.\n * Exits the process with code 1 on validation failure or missing dependency.\n */\nexport async function run({ input }: ValidateOptions): Promise<void> {\n const report = trackRun({ command: 'validate', hrStart: process.hrtime() })\n\n try {\n const { adapterOas } = await import('@kubb/adapter-oas')\n\n await adapterOas().validate(input, { throwOnError: true })\n await report({ status: 'success' })\n\n console.log('✅ Validation success')\n } catch (error) {\n await report({ status: 'failed' })\n if (error instanceof Error && /@kubb\\/adapter-oas/.test(error.message)) {\n console.error(styleText('red', 'The @kubb/adapter-oas package is not installed.'))\n console.error('')\n console.error('Install it with:')\n console.error(styleText('cyan', ' npm install @kubb/adapter-oas'))\n console.error(styleText('cyan', ' # or'))\n console.error(styleText('cyan', ' pnpm install @kubb/adapter-oas'))\n console.error('')\n }\n console.error('❌ Validation failed')\n console.error(toError(error).message)\n\n process.exit(1)\n }\n}\n"],"mappings":";;;;;;;;;;AAgBA,eAAsB,IAAI,EAAE,SAAyC;CACnE,MAAM,SAAS,SAAS;EAAE,SAAS;EAAY,SAAS,QAAQ,OAAO;CAAE,CAAC;CAE1E,IAAI;EACF,MAAM,EAAE,eAAe,MAAM,OAAO;EAEpC,MAAM,WAAW,CAAC,CAAC,SAAS,OAAO,EAAE,cAAc,KAAK,CAAC;EACzD,MAAM,OAAO,EAAE,QAAQ,UAAU,CAAC;EAElC,QAAQ,IAAI,sBAAsB;CACpC,SAAS,OAAO;EACd,MAAM,OAAO,EAAE,QAAQ,SAAS,CAAC;EACjC,IAAI,iBAAiB,SAAS,qBAAqB,KAAK,MAAM,OAAO,GAAG;GACtE,QAAQ,MAAM,UAAU,OAAO,iDAAiD,CAAC;GACjF,QAAQ,MAAM,EAAE;GAChB,QAAQ,MAAM,kBAAkB;GAChC,QAAQ,MAAM,UAAU,QAAQ,iCAAiC,CAAC;GAClE,QAAQ,MAAM,UAAU,QAAQ,QAAQ,CAAC;GACzC,QAAQ,MAAM,UAAU,QAAQ,kCAAkC,CAAC;GACnE,QAAQ,MAAM,EAAE;EAClB;EACA,QAAQ,MAAM,qBAAqB;EACnC,QAAQ,MAAM,QAAQ,KAAK,CAAC,CAAC,OAAO;EAEpC,QAAQ,KAAK,CAAC;CAChB;AACF"}
1
+ {"version":3,"file":"run-Ck04_W4q.js","names":[],"sources":["../src/runners/validate/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { toError } from '@internals/utils'\nimport { trackRun } from '../../Telemetry.ts'\n\ntype ValidateOptions = {\n /**\n * Path or URL to the OpenAPI/Swagger file to validate.\n */\n input: string\n}\n\n/**\n * Validates an OpenAPI/Swagger file at `input` using `@kubb/adapter-oas`.\n * Exits the process with code 1 on validation failure or missing dependency.\n */\nexport async function run({ input }: ValidateOptions): Promise<void> {\n const report = trackRun({ command: 'validate', hrStart: process.hrtime() })\n\n try {\n const { adapterOas } = await import('@kubb/adapter-oas')\n\n await adapterOas().validate(input, { throwOnError: true })\n await report({ status: 'success' })\n\n console.log('✅ Validation success')\n } catch (error) {\n await report({ status: 'failed' })\n if (error instanceof Error && /@kubb\\/adapter-oas/.test(error.message)) {\n console.error(styleText('red', 'The @kubb/adapter-oas package is not installed.'))\n console.error('')\n console.error('Install it with:')\n console.error(styleText('cyan', ' npm install @kubb/adapter-oas'))\n console.error(styleText('cyan', ' # or'))\n console.error(styleText('cyan', ' pnpm install @kubb/adapter-oas'))\n console.error('')\n }\n console.error('❌ Validation failed')\n console.error(toError(error).message)\n\n process.exit(1)\n }\n}\n"],"mappings":";;;;;;;;;AAgBA,eAAsB,IAAI,EAAE,SAAyC;CACnE,MAAM,SAAS,SAAS;EAAE,SAAS;EAAY,SAAS,QAAQ,OAAO;CAAE,CAAC;CAE1E,IAAI;EACF,MAAM,EAAE,eAAe,MAAM,OAAO;EAEpC,MAAM,WAAW,CAAC,CAAC,SAAS,OAAO,EAAE,cAAc,KAAK,CAAC;EACzD,MAAM,OAAO,EAAE,QAAQ,UAAU,CAAC;EAElC,QAAQ,IAAI,sBAAsB;CACpC,SAAS,OAAO;EACd,MAAM,OAAO,EAAE,QAAQ,SAAS,CAAC;EACjC,IAAI,iBAAiB,SAAS,qBAAqB,KAAK,MAAM,OAAO,GAAG;GACtE,QAAQ,MAAM,UAAU,OAAO,iDAAiD,CAAC;GACjF,QAAQ,MAAM,EAAE;GAChB,QAAQ,MAAM,kBAAkB;GAChC,QAAQ,MAAM,UAAU,QAAQ,iCAAiC,CAAC;GAClE,QAAQ,MAAM,UAAU,QAAQ,QAAQ,CAAC;GACzC,QAAQ,MAAM,UAAU,QAAQ,kCAAkC,CAAC;GACnE,QAAQ,MAAM,EAAE;EAClB;EACA,QAAQ,MAAM,qBAAqB;EACnC,QAAQ,MAAM,QAAQ,KAAK,CAAC,CAAC,OAAO;EAEpC,QAAQ,KAAK,CAAC;CAChB;AACF"}
@@ -1,19 +1,15 @@
1
1
  import "./rolldown-runtime-CRm0XQPb.js";
2
- import { n as toError } from "./errors-DmC83ALX.js";
3
- import { i as isCIEnvironment } from "./agent-BPIqnEl2.js";
4
- import { n as trackRun, r as version } from "./Telemetry-DER8LIO5.js";
5
- import { t as KUBB_CONFIG_FILENAME } from "./constants-Cii4HX64.js";
6
- import { n as getConfigs } from "./config-B6UIKcl1.js";
7
- import { g as plainLogger, o as logIntro, p as canUseTTY, r as logBlock, s as logOutro, t as createSpinner, u as logTip } from "./output-qFt4vV7K.js";
8
- import { n as setupReporters } from "./reporters-H21Jvrff.js";
2
+ import { l as toError, n as trackRun, r as version, s as isCIEnvironment } from "./Telemetry-E_BBHmnT.js";
3
+ import { b as KUBB_CONFIG_FILENAME, g as canUseTTY, o as logIntro, p as plainLogger, r as logBlock, s as logOutro, t as createSpinner, u as logTip } from "./output-DS5hyqwL.js";
4
+ import { a as readCredentials, n as getCredentialsPath, o as writeCredentials, r as getMachineId, t as clearCredentials } from "./credentials-CZK6zPLv.js";
5
+ import { r as setupReporters, t as getConfigs } from "./config-DxePdyxe.js";
9
6
  import { styleText } from "node:util";
10
- import { hash, randomBytes } from "node:crypto";
11
7
  import { hostname } from "node:os";
12
8
  import process from "node:process";
13
9
  import { x } from "tinyexec";
14
10
  import path from "node:path";
15
- import { Hookable, cliReporter, kubbStorage, logLevel, resolveKubbDir } from "@kubb/core";
16
11
  import * as prompts from "@clack/prompts";
12
+ import { Hookable, cliReporter, logLevel } from "@kubb/core";
17
13
  import { InvalidAgentTokenError, PairingCanceledError, connectAgent, defaultStudioUrl, pairAgent } from "@kubb/studio";
18
14
  //#region ../../internals/utils/src/openInBrowser.ts
19
15
  const ignore = () => {};
@@ -34,76 +30,7 @@ function openInBrowser(target) {
34
30
  x(process.platform === "darwin" ? "open" : "xdg-open", [target]).then(ignore, ignore);
35
31
  }
36
32
  //#endregion
37
- //#region src/runners/studio/credentials.ts
38
- const projectBase = (project = process.cwd()) => path.join("projects", hash("sha256", project));
39
- /**
40
- * Root for the credential and machine identity of the current project, inside `KUBB_HOME`.
41
- *
42
- * Studio agents are project connections, so two projects on one machine must not share the same
43
- * persisted token or machine secret.
44
- */
45
- function getProjectKubbHome(project = process.cwd()) {
46
- return resolveKubbDir(projectBase(project));
47
- }
48
- const projectStorage = () => kubbStorage({ base: projectBase() });
49
- const CREDENTIALS_FILENAME = "credentials.json";
50
- /**
51
- * Absolute path of the stored credential, so callers can name it in output without rebuilding it.
52
- */
53
- function getCredentialsPath() {
54
- return path.join(getProjectKubbHome(), CREDENTIALS_FILENAME);
55
- }
56
- /**
57
- * Reads the stored credential, or null when this machine has not paired yet or the file is
58
- * unreadable or corrupt. A bad file is treated as "not paired" so `kubb studio login` can
59
- * overwrite it rather than the CLI dying on it.
60
- */
61
- async function readCredentials() {
62
- const stored = await projectStorage().getItem(CREDENTIALS_FILENAME).catch(() => null);
63
- return typeof stored?.token === "string" && stored.token !== "" ? stored : null;
64
- }
65
- /**
66
- * Writes the credential into the project folder, which only its owner can open.
67
- */
68
- async function writeCredentials(credentials) {
69
- await projectStorage().setItem(CREDENTIALS_FILENAME, credentials);
70
- }
71
- /**
72
- * Forgets the stored credential. Succeeds when there was nothing to forget.
73
- */
74
- async function clearCredentials() {
75
- await projectStorage().removeItem(CREDENTIALS_FILENAME);
76
- }
77
- /**
78
- * Reads this project's machine secret, creating it on first use. Pairing sends its hash, so pairing
79
- * the same project again rotates one agent's token instead of creating a second agent. It lives
80
- * apart from the credential, which {@link clearCredentials} deletes.
81
- */
82
- async function getMachineId() {
83
- const storage = projectStorage();
84
- const stored = await storage.getItem("machine-secret").catch(() => null);
85
- if (typeof stored === "string" && stored.trim()) return stored.trim();
86
- const secret = randomBytes(32).toString("hex");
87
- await storage.setItem("machine-secret", secret);
88
- return secret;
89
- }
90
- //#endregion
91
33
  //#region src/runners/studio/run.ts
92
- function createStudioOptions(values) {
93
- return {
94
- version,
95
- configPath: values.config,
96
- studioUrl: values.url ?? defaultStudioUrl,
97
- permission: {
98
- allowRead: values.allowRead,
99
- allowWrite: values.allowWrite,
100
- allowConfigEdit: values.allowConfigEdit,
101
- allowExec: values.allowExec
102
- },
103
- autoOpen: values.open ?? true,
104
- logLevel: values.logLevel
105
- };
106
- }
107
34
  /**
108
35
  * Pairs this machine with Studio and stores the resulting token.
109
36
  *
@@ -280,7 +207,7 @@ async function connect(options, context = {}) {
280
207
  }
281
208
  try {
282
209
  if (!context.prepared) {
283
- const { getWorkerStatus } = await import("./background-DSKoOwcG.js");
210
+ const { getWorkerStatus } = await import("./background-CZ2nVKwB.js");
284
211
  if ((await getWorkerStatus()).running) throw new Error("This project is running in the background. Run `kubb studio stop` first.");
285
212
  }
286
213
  const prepared = context.prepared ?? await prepareConnection(options, signal);
@@ -340,9 +267,23 @@ async function connect(options, context = {}) {
340
267
  }
341
268
  }
342
269
  /**
343
- * Runs a Studio command with shared setup and telemetry reporting.
270
+ * Runs a Studio command from its parsed flags: builds the {@link StudioOptions}, prints the intro,
271
+ * and reports the run to telemetry. A failure is printed and sets the exit code instead of throwing.
344
272
  */
345
- async function run({ options, action, block = false, json = false }) {
273
+ async function runStudio(values, action, { block = false, json = false } = {}) {
274
+ const options = {
275
+ version,
276
+ configPath: values.config,
277
+ studioUrl: values.url ?? defaultStudioUrl,
278
+ permission: {
279
+ allowRead: values.allowRead ?? false,
280
+ allowWrite: values.allowWrite ?? false,
281
+ allowConfigEdit: values.allowConfigEdit ?? false,
282
+ allowExec: values.allowExec ?? false
283
+ },
284
+ autoOpen: values.open ?? true,
285
+ logLevel: values.logLevel
286
+ };
346
287
  const report = trackRun({
347
288
  command: "studio",
348
289
  hrStart: process.hrtime()
@@ -352,7 +293,7 @@ async function run({ options, action, block = false, json = false }) {
352
293
  warning: styleText("yellow", "This feature is still under development, use with caution"),
353
294
  block
354
295
  });
355
- await action();
296
+ await action(options);
356
297
  await report({ status: "success" });
357
298
  } catch (error) {
358
299
  await report({ status: "failed" });
@@ -361,6 +302,6 @@ async function run({ options, action, block = false, json = false }) {
361
302
  }
362
303
  }
363
304
  //#endregion
364
- export { login as a, clearCredentials as c, loadConfigs as i, getProjectKubbHome as l, createStudioOptions as n, prepareConnection as o, formatPermissionRows as r, run as s, connect as t, readCredentials as u };
305
+ export { prepareConnection as a, login as i, formatPermissionRows as n, resolvePermissions as o, loadConfigs as r, runStudio as s, connect as t };
365
306
 
366
- //# sourceMappingURL=run-BQQhNg8I.js.map
307
+ //# sourceMappingURL=run-DcP1czVQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-DcP1czVQ.js","names":["logLevelMap"],"sources":["../../../internals/utils/src/openInBrowser.ts","../src/runners/studio/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { x } from 'tinyexec'\nimport { isCIEnvironment } from './isCIEnvironment.ts'\n\nconst ignore = () => {}\n\n/**\n * Opens a URL or local file in the default browser, unless running in CI.\n */\nexport function openInBrowser(target: string): void {\n if (isCIEnvironment()) return\n\n if (process.platform === 'win32') {\n x('cmd', ['/c', 'start', '', target]).then(ignore, ignore)\n return\n }\n x(process.platform === 'darwin' ? 'open' : 'xdg-open', [target]).then(ignore, ignore)\n}\n","import { hostname } from 'node:os'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport * as prompts from '@clack/prompts'\nimport { KUBB_CONFIG_FILENAME } from '@internals/shared'\nimport { isCIEnvironment, openInBrowser, toError } from '@internals/utils'\nimport type { CLIOptions, Config } from '@kubb/core'\nimport { cliReporter, Hookable, type KubbHooks, logLevel as logLevelMap } from '@kubb/core'\nimport { connectAgent, defaultStudioUrl, InvalidAgentTokenError, pairAgent, PairingCanceledError } from '@kubb/studio'\nimport { trackRun } from '../../Telemetry.ts'\nimport { plainLogger } from '../../loggers/plainLogger.ts'\nimport setupReporters from '../../loggers/reporters.ts'\nimport { createSpinner, logBlock, logIntro, logOutro, logTip } from '../../loggers/output.ts'\nimport { canUseTTY } from '../../utils/env.ts'\nimport { getConfigs } from '../../config.ts'\nimport { clearCredentials, type Credentials, getCredentialsPath, getMachineId, readCredentials, writeCredentials } from './credentials.ts'\nimport { version } from '../../../package.json'\n\ntype Permission = 'allowRead' | 'allowWrite' | 'allowConfigEdit' | 'allowExec'\n\nexport type StudioOptions = {\n /**\n * Current `@kubb/cli` version, reported to Studio and used for the telemetry payload.\n */\n version: string\n configPath?: string\n /**\n * Base URL of the Studio instance, for a self-hosted deployment. Resolved before it reaches here,\n * since stored credentials are bound to it.\n */\n studioUrl: string\n /**\n * What Studio may do in this project. Each flag grants outright; the rest are asked once per\n * project through {@link resolvePermissions}.\n */\n permission: Record<Permission, boolean>\n /**\n * Whether to open the approval page in a browser during pairing.\n */\n autoOpen: boolean\n logLevel?: CLIOptions['logLevel']\n}\n\nexport type SnapshotOptions = Pick<StudioOptions, 'configPath' | 'studioUrl' | 'logLevel'> & {\n /**\n * Organization CI API key. Falls back to `KUBB_TOKEN`.\n */\n token?: string\n /**\n * Stable identity for the CI agent. Falls back to CI auto-detection.\n */\n id?: string\n /** Identity of another CI agent to also compare with. Falls back to CI auto-detection. */\n baseId?: string\n /**\n * Package name for the generated tarball. Falls back to the nearest package.json.\n */\n name?: string\n /**\n * Package version for the generated tarball. Falls back to the nearest package.json.\n */\n packageVersion?: string\n /**\n * Print the result as one JSON object instead of a summary.\n */\n json?: boolean\n}\n\n/** The flags a `kubb studio` subcommand parsed; each one is optional since a subcommand declares only the flags it uses. */\nexport type StudioValues = {\n config?: string\n url?: string\n allowRead?: boolean\n allowWrite?: boolean\n allowConfigEdit?: boolean\n allowExec?: boolean\n open?: boolean\n logLevel?: CLIOptions['logLevel']\n}\n\ntype LoginOptions = {\n /**\n * Aborting this cancels an in-flight pairing request or poll and rejects with\n * {@link PairingCanceledError}. Wired to `kubb studio`'s shutdown signal, so Ctrl+C during\n * pairing cancels it instead of leaving the poll running.\n */\n signal?: AbortSignal\n /**\n * Credentials from before this login. When the fresh pairing resolves to the same agent on the\n * same Studio, its saved project permissions carry forward instead of being asked again.\n * Left out for an explicitly requested `kubb studio login`, which always starts clean.\n */\n previousCredentials?: Credentials | null\n}\n\n/**\n * Pairs this machine with Studio and stores the resulting token.\n *\n * The CLI holds a code and the browser approves it, rather than the user copying a token out of\n * the UI. The token comes back over the CLI's own HTTPS POST, so it never lands in a URL, a\n * server log, or a `Referer` header.\n */\nexport async function login({ studioUrl, autoOpen }: StudioOptions, { signal, previousCredentials }: LoginOptions = {}): Promise<Credentials> {\n const spinner = createSpinner()\n // The spinner only starts once a code is shown.\n let waiting = false\n\n try {\n const { token, agent } = await pairAgent({\n studioUrl,\n type: 'cli',\n name: path.basename(process.cwd()),\n hostname: hostname(),\n machineId: await getMachineId(),\n signal,\n onCode: (session) => {\n console.log(`\\nOpen ${styleText('cyan', session.verification_uri)} and approve the code ${styleText('bold', session.user_code)}`)\n\n if (autoOpen) {\n openInBrowser(session.verification_uri_complete)\n }\n\n spinner.start('Waiting for approval')\n waiting = true\n },\n onRetry: (error) => spinner.message(`Could not reach Kubb Studio, retrying: ${error.message}`),\n })\n spinner.stop(`Paired as ${agent.name}`)\n\n const keepsIdentity = previousCredentials?.studioUrl === studioUrl && previousCredentials.agentId === agent.id\n const credentials: Credentials = {\n studioUrl,\n token,\n agentId: agent.id,\n agentSlug: agent.slug,\n ...(keepsIdentity && previousCredentials?.projects ? { projects: previousCredentials.projects } : {}),\n }\n await writeCredentials(credentials)\n\n console.log(`Credentials stored in ${getCredentialsPath()}`)\n\n return credentials\n } catch (error) {\n if (waiting) {\n spinner.stop(error instanceof PairingCanceledError ? 'Pairing canceled' : 'Pairing failed')\n }\n throw error\n }\n}\n\n/**\n * What each permission is asked as, in the order the questions appear.\n */\nconst PERMISSIONS: ReadonlyArray<{\n key: Permission\n /**\n * Short label for status output and the connect summary.\n */\n label: string\n question: (project: string, configPath: string) => string\n}> = [\n {\n key: 'allowRead',\n label: 'read generated files',\n question: () => 'Let Kubb Studio read the files a generation produced?',\n },\n { key: 'allowWrite', label: 'write generated files', question: (project) => `Let Kubb Studio write generated files into ${project}?` },\n {\n key: 'allowConfigEdit',\n label: 'edit kubb.config.ts',\n question: (_project, configPath) => `Let Kubb Studio change plugin options in ${configPath}?`,\n },\n {\n key: 'allowExec',\n label: 'run formatter, linter, postGenerate',\n question: () => 'Let Kubb Studio run the formatter, the linter, and output.postGenerate?',\n },\n]\n\n/**\n * One row per permission, for the connect banner and `kubb studio status`. A list rather than a\n * joined line: four labels this long read as one run-on sentence side by side.\n */\nexport function formatPermissionRows(granted: Record<Permission, boolean>): Array<string> {\n return PERMISSIONS.map(({ key, label }) => `${granted[key] ? styleText('green', '✔') : styleText('red', '✘')} ${label}`)\n}\n\n/**\n * Resolves Studio permissions for the current project.\n * Flags win, saved answers are reused, and new answers are stored unless `persist` is false.\n */\nexport async function resolvePermissions(\n options: StudioOptions,\n credentials: Credentials,\n configPath: string = KUBB_CONFIG_FILENAME,\n /**\n * Stores new answers in `~/.kubb/credentials.json`.\n * Pass `false` for `KUBB_AGENT_TOKEN` sessions so a temporary token is not written back to disk.\n */\n persist = true,\n): Promise<Record<Permission, boolean>> {\n const project = process.cwd()\n const remembered = credentials.projects?.[project]\n const granted: Record<Permission, boolean> = { allowRead: false, allowWrite: false, allowConfigEdit: false, allowExec: false }\n const answers: Partial<Record<Permission, boolean>> = {}\n prompts.updateSettings({ withGuide: true })\n\n for (const { key, question } of PERMISSIONS) {\n if (options.permission[key] || typeof remembered?.[key] === 'boolean') {\n granted[key] = options.permission[key] || remembered?.[key] === true\n continue\n }\n\n if (isCIEnvironment() || !canUseTTY()) {\n granted[key] = false\n continue\n }\n\n granted[key] = (await prompts.confirm({ message: question(project, configPath), initialValue: false })) === true\n answers[key] = granted[key]\n }\n if (persist && Object.keys(answers).length) {\n await writeCredentials({\n ...credentials,\n projects: { ...credentials.projects, [project]: { ...remembered, ...answers } },\n })\n }\n\n return granted\n}\n\n/**\n * Loads the project's Kubb config the same way `kubb generate` does.\n * Returns the first config.\n */\nexport async function loadConfigs(options: Pick<StudioOptions, 'configPath' | 'logLevel'>): Promise<{ configPath: string; config: Config }> {\n const { configPath, configs } = await getConfigs({ configPath: options.configPath, logLevel: options.logLevel })\n const [config] = configs\n\n if (!config) {\n throw new Error('Config not defined, create a kubb.config.ts or pass it with --config')\n }\n\n // `getConfigs` resolves this to an absolute path. Relativized here, once, so the permission\n // prompt and the path Studio receives over the wire both show the project-relative form instead\n // of leaking the local filesystem layout.\n return { configPath: path.relative(process.cwd(), configPath) || configPath, config }\n}\n\n/**\n * Why a rejected token could not be recovered automatically: it came from `KUBB_AGENT_TOKEN`, no\n * browser is available to re-pair with, or the token this run already re-paired for was rejected\n * again.\n */\ntype RejectedTokenReason = 'envToken' | 'nonInteractive' | 'reauthExhausted'\n\n/**\n * Explains a rejected token to the operator. Builds the error and nothing else, so each caller\n * decides what happens to the credentials.\n */\nfunction explainRejectedToken(error: InvalidAgentTokenError, reason: RejectedTokenReason): Error {\n if (reason === 'envToken') {\n return new Error(`${error.message} Pair again and update KUBB_AGENT_TOKEN.`)\n }\n\n if (reason === 'reauthExhausted') {\n return new Error(`${error.message} Studio rejected the newly approved token too. Run \\`kubb studio login\\` and try again.`)\n }\n\n return new Error(`${error.message} Run \\`kubb studio login\\` to pair again.`)\n}\n\nexport type PreparedConnection = {\n configPath: string\n credentials: Credentials\n permissions: StudioOptions['permission']\n}\n\n/** Validates the project and resolves pairing and permissions before starting its worker. */\nexport async function prepareConnection(options: StudioOptions, signal?: AbortSignal): Promise<PreparedConnection> {\n const { configPath } = await loadConfigs(options)\n const envToken = process.env.KUBB_AGENT_TOKEN\n const stored = envToken ? null : await readCredentials()\n const credentials = await (async () => {\n if (envToken) return { studioUrl: options.studioUrl, token: envToken, agentId: '', agentSlug: '' }\n if (stored?.studioUrl === options.studioUrl) return stored\n if (isCIEnvironment()) {\n throw new Error(`Not paired with ${options.studioUrl}. Set KUBB_AGENT_TOKEN, or run \\`kubb studio login\\` on a machine with a browser.`)\n }\n return login(options, { signal })\n })()\n const permissions = await resolvePermissions(options, credentials, configPath, !envToken)\n return { configPath, credentials, permissions }\n}\n\nexport type WorkerState = 'starting' | 'connected' | 'reconnecting' | 'authentication required' | 'stopped'\n\n/** Runs the same project connection in the foreground or in a background worker. */\nexport async function connect(\n options: StudioOptions,\n context: {\n prepared?: PreparedConnection\n signal?: AbortSignal\n onState?: (state: WorkerState) => void | Promise<void>\n } = {},\n): Promise<void> {\n const shutdown = new AbortController()\n const signal = context.signal ?? shutdown.signal\n const stop = () => shutdown.abort()\n const events = process as unknown as NodeJS.EventEmitter\n if (!context.signal) {\n events.once('SIGINT', stop)\n events.once('SIGTERM', stop)\n }\n try {\n if (!context.prepared) {\n const { getWorkerStatus } = await import('./background.ts')\n const worker = await getWorkerStatus()\n if (worker.running) throw new Error('This project is running in the background. Run `kubb studio stop` first.')\n }\n const prepared = context.prepared ?? (await prepareConnection(options, signal))\n let { credentials, permissions } = prepared\n const { configPath } = prepared\n let hinted = false\n // Set by a fresh pairing until it connects, so a token rejected right after approval fails the run instead of looping.\n let pairedAgain = false\n\n // The background worker writes to a log file, so it gets the plain logger rather than the\n // animated one. The logger also covers the `studio:*` events and each generation run.\n const hooks = new Hookable<KubbHooks>()\n setupReporters(hooks, {\n logLevel: logLevelMap[options.logLevel ?? 'info'],\n reporters: [cliReporter],\n ...(context.onState ? { logger: plainLogger } : {}),\n })\n hooks.hook('studio:connected', async () => {\n pairedAgain = false\n await context.onState?.('connected')\n if (hinted || context.onState || options.logLevel === 'silent') return\n hinted = true\n logBlock(styleText('dim', 'Press Ctrl+C to disconnect'))\n logTip()\n })\n hooks.hook('studio:reconnecting', () => context.onState?.('reconnecting'))\n\n for (;;) {\n try {\n await connectAgent({\n token: credentials.token,\n studioUrl: options.studioUrl,\n configPath,\n version: options.version,\n root: process.cwd(),\n permissions,\n loadConfig: async () => (await loadConfigs(options)).config,\n hooks,\n signal,\n })\n break\n } catch (error) {\n if (!(error instanceof InvalidAgentTokenError)) throw error\n await context.onState?.('authentication required')\n if (process.env.KUBB_AGENT_TOKEN) throw explainRejectedToken(error, 'envToken')\n await clearCredentials()\n if (pairedAgain) throw explainRejectedToken(error, 'reauthExhausted')\n if (context.onState || isCIEnvironment() || !canUseTTY()) throw explainRejectedToken(error, 'nonInteractive')\n\n console.log(styleText('yellow', `${error.message} Pairing again...`))\n credentials = await login(options, { signal, previousCredentials: credentials })\n pairedAgain = true\n permissions = await resolvePermissions(options, credentials, configPath)\n }\n }\n if (!context.onState && signal.aborted && options.logLevel !== 'silent') logOutro('Disconnected')\n } catch (error) {\n if (!(error instanceof PairingCanceledError)) throw error\n } finally {\n events.off('SIGINT', stop)\n events.off('SIGTERM', stop)\n }\n}\n\n/**\n * Runs a Studio command from its parsed flags: builds the {@link StudioOptions}, prints the intro,\n * and reports the run to telemetry. A failure is printed and sets the exit code instead of throwing.\n */\nexport async function runStudio(\n values: StudioValues,\n action: (options: StudioOptions) => Promise<unknown>,\n { block = false, json = false }: { block?: boolean; json?: boolean } = {},\n): Promise<void> {\n const options: StudioOptions = {\n version,\n configPath: values.config,\n studioUrl: values.url ?? defaultStudioUrl,\n permission: {\n allowRead: values.allowRead ?? false,\n allowWrite: values.allowWrite ?? false,\n allowConfigEdit: values.allowConfigEdit ?? false,\n allowExec: values.allowExec ?? false,\n },\n autoOpen: values.open ?? true,\n logLevel: values.logLevel,\n }\n const report = trackRun({ command: 'studio', hrStart: process.hrtime() })\n\n try {\n if (options.logLevel !== 'silent' && !json) {\n logIntro({\n warning: styleText('yellow', 'This feature is still under development, use with caution'),\n block,\n })\n }\n\n await action(options)\n\n await report({ status: 'success' })\n } catch (error) {\n await report({ status: 'failed' })\n console.error(toError(error).message)\n process.exitCode = 1\n }\n}\n"],"mappings":"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"}
@@ -1,9 +1,8 @@
1
- const require_agent = require("./agent-DElUuYuy.cjs");
2
- const require_errors = require("./errors-BdA8M78q.cjs");
3
- const require_Telemetry = require("./Telemetry-B_C4MVJd.cjs");
1
+ const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
2
+ const require_Telemetry = require("./Telemetry-ByFeVTz5.cjs");
4
3
  let node_util = require("node:util");
5
4
  let node_process = require("node:process");
6
- node_process = require_agent.__toESM(node_process, 1);
5
+ node_process = require_rolldown_runtime.__toESM(node_process, 1);
7
6
  //#region src/runners/mcp/run.ts
8
7
  /**
9
8
  * Starts the `@kubb/mcp` server over stdio and reports the outcome to telemetry.
@@ -21,11 +20,11 @@ async function run() {
21
20
  await report({ status: "success" });
22
21
  } catch (error) {
23
22
  await report({ status: "failed" });
24
- console.error(require_errors.toError(error).message);
23
+ console.error(require_Telemetry.toError(error).message);
25
24
  node_process.default.exitCode = 1;
26
25
  }
27
26
  }
28
27
  //#endregion
29
28
  exports.run = run;
30
29
 
31
- //# sourceMappingURL=run-D8EJ2hKI.cjs.map
30
+ //# sourceMappingURL=run-Dyc52IzX.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-D8EJ2hKI.cjs","names":["trackRun","process","styleText","toError"],"sources":["../src/runners/mcp/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { toError } from '@internals/utils'\nimport type * as McpModule from '@kubb/mcp'\nimport { trackRun } from '../../Telemetry.ts'\n\n/**\n * Starts the `@kubb/mcp` server over stdio and reports the outcome to telemetry.\n */\nexport async function run(): Promise<void> {\n const { run: startMcpServer } = (await import('@kubb/mcp')) as typeof McpModule\n\n const report = trackRun({ command: 'mcp', hrStart: process.hrtime() })\n\n try {\n // The MCP stdio transport owns stdout: anything else written there corrupts the JSON-RPC stream.\n console.error(styleText('cyan', '⏳ Starting MCP server...'))\n console.warn(styleText('yellow', 'This feature is still under development, use with caution'))\n await startMcpServer()\n await report({ status: 'success' })\n } catch (error) {\n await report({ status: 'failed' })\n console.error(toError(error).message)\n process.exitCode = 1\n }\n}\n"],"mappings":";;;;;;;;;;AASA,eAAsB,MAAqB;CACzC,MAAM,EAAE,KAAK,mBAAoB,MAAM,OAAO;CAE9C,MAAM,SAASA,kBAAAA,SAAS;EAAE,SAAS;EAAO,SAASC,aAAAA,QAAQ,OAAO;CAAE,CAAC;CAErE,IAAI;EAEF,QAAQ,OAAA,GAAMC,UAAAA,UAAAA,CAAU,QAAQ,0BAA0B,CAAC;EAC3D,QAAQ,MAAA,GAAKA,UAAAA,UAAAA,CAAU,UAAU,2DAA2D,CAAC;EAC7F,MAAM,eAAe;EACrB,MAAM,OAAO,EAAE,QAAQ,UAAU,CAAC;CACpC,SAAS,OAAO;EACd,MAAM,OAAO,EAAE,QAAQ,SAAS,CAAC;EACjC,QAAQ,MAAMC,eAAAA,QAAQ,KAAK,CAAC,CAAC,OAAO;EACpC,aAAA,QAAA,WAAmB;CACrB;AACF"}
1
+ {"version":3,"file":"run-Dyc52IzX.cjs","names":["trackRun","process","styleText","toError"],"sources":["../src/runners/mcp/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { toError } from '@internals/utils'\nimport type * as McpModule from '@kubb/mcp'\nimport { trackRun } from '../../Telemetry.ts'\n\n/**\n * Starts the `@kubb/mcp` server over stdio and reports the outcome to telemetry.\n */\nexport async function run(): Promise<void> {\n const { run: startMcpServer } = (await import('@kubb/mcp')) as typeof McpModule\n\n const report = trackRun({ command: 'mcp', hrStart: process.hrtime() })\n\n try {\n // The MCP stdio transport owns stdout: anything else written there corrupts the JSON-RPC stream.\n console.error(styleText('cyan', '⏳ Starting MCP server...'))\n console.warn(styleText('yellow', 'This feature is still under development, use with caution'))\n await startMcpServer()\n await report({ status: 'success' })\n } catch (error) {\n await report({ status: 'failed' })\n console.error(toError(error).message)\n process.exitCode = 1\n }\n}\n"],"mappings":";;;;;;;;;AASA,eAAsB,MAAqB;CACzC,MAAM,EAAE,KAAK,mBAAoB,MAAM,OAAO;CAE9C,MAAM,SAASA,kBAAAA,SAAS;EAAE,SAAS;EAAO,SAASC,aAAAA,QAAQ,OAAO;CAAE,CAAC;CAErE,IAAI;EAEF,QAAQ,OAAA,GAAMC,UAAAA,UAAAA,CAAU,QAAQ,0BAA0B,CAAC;EAC3D,QAAQ,MAAA,GAAKA,UAAAA,UAAAA,CAAU,UAAU,2DAA2D,CAAC;EAC7F,MAAM,eAAe;EACrB,MAAM,OAAO,EAAE,QAAQ,UAAU,CAAC;CACpC,SAAS,OAAO;EACd,MAAM,OAAO,EAAE,QAAQ,SAAS,CAAC;EACjC,QAAQ,MAAMC,kBAAAA,QAAQ,KAAK,CAAC,CAAC,OAAO;EACpC,aAAA,QAAA,WAAmB;CACrB;AACF"}
@@ -1,20 +1,17 @@
1
- const require_agent = require("./agent-DElUuYuy.cjs");
2
- const require_errors = require("./errors-BdA8M78q.cjs");
3
- const require_Telemetry = require("./Telemetry-B_C4MVJd.cjs");
4
- const require_constants = require("./constants-Df449N47.cjs");
5
- const require_config = require("./config-Bo9ro7vg.cjs");
6
- const require_output = require("./output-BnK0scpX.cjs");
7
- const require_reporters = require("./reporters-B4rZOlo8.cjs");
1
+ const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
2
+ const require_Telemetry = require("./Telemetry-ByFeVTz5.cjs");
3
+ const require_output = require("./output-Cd3Kmvo0.cjs");
4
+ const require_config = require("./config-Ck2JHe5r.cjs");
5
+ const require_credentials = require("./credentials-DDaKqtJn.cjs");
8
6
  let node_util = require("node:util");
9
- let node_crypto = require("node:crypto");
10
7
  let node_os = require("node:os");
11
8
  let node_process = require("node:process");
12
- node_process = require_agent.__toESM(node_process, 1);
9
+ node_process = require_rolldown_runtime.__toESM(node_process, 1);
13
10
  let tinyexec = require("tinyexec");
14
11
  let node_path = require("node:path");
15
- node_path = require_agent.__toESM(node_path, 1);
12
+ node_path = require_rolldown_runtime.__toESM(node_path, 1);
16
13
  let _clack_prompts = require("@clack/prompts");
17
- _clack_prompts = require_agent.__toESM(_clack_prompts, 1);
14
+ _clack_prompts = require_rolldown_runtime.__toESM(_clack_prompts, 1);
18
15
  let _kubb_core = require("@kubb/core");
19
16
  let _kubb_studio = require("@kubb/studio");
20
17
  //#region ../../internals/utils/src/openInBrowser.ts
@@ -23,7 +20,7 @@ const ignore = () => {};
23
20
  * Opens a URL or local file in the default browser, unless running in CI.
24
21
  */
25
22
  function openInBrowser(target) {
26
- if (require_agent.isCIEnvironment()) return;
23
+ if (require_Telemetry.isCIEnvironment()) return;
27
24
  if (node_process.default.platform === "win32") {
28
25
  (0, tinyexec.x)("cmd", [
29
26
  "/c",
@@ -36,76 +33,7 @@ function openInBrowser(target) {
36
33
  (0, tinyexec.x)(node_process.default.platform === "darwin" ? "open" : "xdg-open", [target]).then(ignore, ignore);
37
34
  }
38
35
  //#endregion
39
- //#region src/runners/studio/credentials.ts
40
- const projectBase = (project = node_process.default.cwd()) => node_path.default.join("projects", (0, node_crypto.hash)("sha256", project));
41
- /**
42
- * Root for the credential and machine identity of the current project, inside `KUBB_HOME`.
43
- *
44
- * Studio agents are project connections, so two projects on one machine must not share the same
45
- * persisted token or machine secret.
46
- */
47
- function getProjectKubbHome(project = node_process.default.cwd()) {
48
- return (0, _kubb_core.resolveKubbDir)(projectBase(project));
49
- }
50
- const projectStorage = () => (0, _kubb_core.kubbStorage)({ base: projectBase() });
51
- const CREDENTIALS_FILENAME = "credentials.json";
52
- /**
53
- * Absolute path of the stored credential, so callers can name it in output without rebuilding it.
54
- */
55
- function getCredentialsPath() {
56
- return node_path.default.join(getProjectKubbHome(), CREDENTIALS_FILENAME);
57
- }
58
- /**
59
- * Reads the stored credential, or null when this machine has not paired yet or the file is
60
- * unreadable or corrupt. A bad file is treated as "not paired" so `kubb studio login` can
61
- * overwrite it rather than the CLI dying on it.
62
- */
63
- async function readCredentials() {
64
- const stored = await projectStorage().getItem(CREDENTIALS_FILENAME).catch(() => null);
65
- return typeof stored?.token === "string" && stored.token !== "" ? stored : null;
66
- }
67
- /**
68
- * Writes the credential into the project folder, which only its owner can open.
69
- */
70
- async function writeCredentials(credentials) {
71
- await projectStorage().setItem(CREDENTIALS_FILENAME, credentials);
72
- }
73
- /**
74
- * Forgets the stored credential. Succeeds when there was nothing to forget.
75
- */
76
- async function clearCredentials() {
77
- await projectStorage().removeItem(CREDENTIALS_FILENAME);
78
- }
79
- /**
80
- * Reads this project's machine secret, creating it on first use. Pairing sends its hash, so pairing
81
- * the same project again rotates one agent's token instead of creating a second agent. It lives
82
- * apart from the credential, which {@link clearCredentials} deletes.
83
- */
84
- async function getMachineId() {
85
- const storage = projectStorage();
86
- const stored = await storage.getItem("machine-secret").catch(() => null);
87
- if (typeof stored === "string" && stored.trim()) return stored.trim();
88
- const secret = (0, node_crypto.randomBytes)(32).toString("hex");
89
- await storage.setItem("machine-secret", secret);
90
- return secret;
91
- }
92
- //#endregion
93
36
  //#region src/runners/studio/run.ts
94
- function createStudioOptions(values) {
95
- return {
96
- version: require_Telemetry.version,
97
- configPath: values.config,
98
- studioUrl: values.url ?? _kubb_studio.defaultStudioUrl,
99
- permission: {
100
- allowRead: values.allowRead,
101
- allowWrite: values.allowWrite,
102
- allowConfigEdit: values.allowConfigEdit,
103
- allowExec: values.allowExec
104
- },
105
- autoOpen: values.open ?? true,
106
- logLevel: values.logLevel
107
- };
108
- }
109
37
  /**
110
38
  * Pairs this machine with Studio and stores the resulting token.
111
39
  *
@@ -122,7 +50,7 @@ async function login({ studioUrl, autoOpen }, { signal, previousCredentials } =
122
50
  type: "cli",
123
51
  name: node_path.default.basename(node_process.default.cwd()),
124
52
  hostname: (0, node_os.hostname)(),
125
- machineId: await getMachineId(),
53
+ machineId: await require_credentials.getMachineId(),
126
54
  signal,
127
55
  onCode: (session) => {
128
56
  console.log(`\nOpen ${(0, node_util.styleText)("cyan", session.verification_uri)} and approve the code ${(0, node_util.styleText)("bold", session.user_code)}`);
@@ -141,8 +69,8 @@ async function login({ studioUrl, autoOpen }, { signal, previousCredentials } =
141
69
  agentSlug: agent.slug,
142
70
  ...keepsIdentity && previousCredentials?.projects ? { projects: previousCredentials.projects } : {}
143
71
  };
144
- await writeCredentials(credentials);
145
- console.log(`Credentials stored in ${getCredentialsPath()}`);
72
+ await require_credentials.writeCredentials(credentials);
73
+ console.log(`Credentials stored in ${require_credentials.getCredentialsPath()}`);
146
74
  return credentials;
147
75
  } catch (error) {
148
76
  if (waiting) spinner.stop(error instanceof _kubb_studio.PairingCanceledError ? "Pairing canceled" : "Pairing failed");
@@ -185,7 +113,7 @@ function formatPermissionRows(granted) {
185
113
  * Resolves Studio permissions for the current project.
186
114
  * Flags win, saved answers are reused, and new answers are stored unless `persist` is false.
187
115
  */
188
- async function resolvePermissions(options, credentials, configPath = require_constants.KUBB_CONFIG_FILENAME, persist = true) {
116
+ async function resolvePermissions(options, credentials, configPath = require_output.KUBB_CONFIG_FILENAME, persist = true) {
189
117
  const project = node_process.default.cwd();
190
118
  const remembered = credentials.projects?.[project];
191
119
  const granted = {
@@ -201,7 +129,7 @@ async function resolvePermissions(options, credentials, configPath = require_con
201
129
  granted[key] = options.permission[key] || remembered?.[key] === true;
202
130
  continue;
203
131
  }
204
- if (require_agent.isCIEnvironment() || !require_output.canUseTTY()) {
132
+ if (require_Telemetry.isCIEnvironment() || !require_output.canUseTTY()) {
205
133
  granted[key] = false;
206
134
  continue;
207
135
  }
@@ -211,7 +139,7 @@ async function resolvePermissions(options, credentials, configPath = require_con
211
139
  }) === true;
212
140
  answers[key] = granted[key];
213
141
  }
214
- if (persist && Object.keys(answers).length) await writeCredentials({
142
+ if (persist && Object.keys(answers).length) await require_credentials.writeCredentials({
215
143
  ...credentials,
216
144
  projects: {
217
145
  ...credentials.projects,
@@ -252,7 +180,7 @@ function explainRejectedToken(error, reason) {
252
180
  async function prepareConnection(options, signal) {
253
181
  const { configPath } = await loadConfigs(options);
254
182
  const envToken = node_process.default.env.KUBB_AGENT_TOKEN;
255
- const stored = envToken ? null : await readCredentials();
183
+ const stored = envToken ? null : await require_credentials.readCredentials();
256
184
  const credentials = await (async () => {
257
185
  if (envToken) return {
258
186
  studioUrl: options.studioUrl,
@@ -261,7 +189,7 @@ async function prepareConnection(options, signal) {
261
189
  agentSlug: ""
262
190
  };
263
191
  if (stored?.studioUrl === options.studioUrl) return stored;
264
- if (require_agent.isCIEnvironment()) throw new Error(`Not paired with ${options.studioUrl}. Set KUBB_AGENT_TOKEN, or run \`kubb studio login\` on a machine with a browser.`);
192
+ if (require_Telemetry.isCIEnvironment()) throw new Error(`Not paired with ${options.studioUrl}. Set KUBB_AGENT_TOKEN, or run \`kubb studio login\` on a machine with a browser.`);
265
193
  return login(options, { signal });
266
194
  })();
267
195
  return {
@@ -282,7 +210,7 @@ async function connect(options, context = {}) {
282
210
  }
283
211
  try {
284
212
  if (!context.prepared) {
285
- const { getWorkerStatus } = await Promise.resolve().then(() => require("./background-Bh4FDWa3.cjs"));
213
+ const { getWorkerStatus } = await Promise.resolve().then(() => require("./background-DdUVvDwi.cjs"));
286
214
  if ((await getWorkerStatus()).running) throw new Error("This project is running in the background. Run `kubb studio stop` first.");
287
215
  }
288
216
  const prepared = context.prepared ?? await prepareConnection(options, signal);
@@ -291,7 +219,7 @@ async function connect(options, context = {}) {
291
219
  let hinted = false;
292
220
  let pairedAgain = false;
293
221
  const hooks = new _kubb_core.Hookable();
294
- require_reporters.setupReporters(hooks, {
222
+ require_config.setupReporters(hooks, {
295
223
  logLevel: _kubb_core.logLevel[options.logLevel ?? "info"],
296
224
  reporters: [_kubb_core.cliReporter],
297
225
  ...context.onState ? { logger: require_output.plainLogger } : {}
@@ -322,9 +250,9 @@ async function connect(options, context = {}) {
322
250
  if (!(error instanceof _kubb_studio.InvalidAgentTokenError)) throw error;
323
251
  await context.onState?.("authentication required");
324
252
  if (node_process.default.env.KUBB_AGENT_TOKEN) throw explainRejectedToken(error, "envToken");
325
- await clearCredentials();
253
+ await require_credentials.clearCredentials();
326
254
  if (pairedAgain) throw explainRejectedToken(error, "reauthExhausted");
327
- if (context.onState || require_agent.isCIEnvironment() || !require_output.canUseTTY()) throw explainRejectedToken(error, "nonInteractive");
255
+ if (context.onState || require_Telemetry.isCIEnvironment() || !require_output.canUseTTY()) throw explainRejectedToken(error, "nonInteractive");
328
256
  console.log((0, node_util.styleText)("yellow", `${error.message} Pairing again...`));
329
257
  credentials = await login(options, {
330
258
  signal,
@@ -342,9 +270,23 @@ async function connect(options, context = {}) {
342
270
  }
343
271
  }
344
272
  /**
345
- * Runs a Studio command with shared setup and telemetry reporting.
273
+ * Runs a Studio command from its parsed flags: builds the {@link StudioOptions}, prints the intro,
274
+ * and reports the run to telemetry. A failure is printed and sets the exit code instead of throwing.
346
275
  */
347
- async function run({ options, action, block = false, json = false }) {
276
+ async function runStudio(values, action, { block = false, json = false } = {}) {
277
+ const options = {
278
+ version: require_Telemetry.version,
279
+ configPath: values.config,
280
+ studioUrl: values.url ?? _kubb_studio.defaultStudioUrl,
281
+ permission: {
282
+ allowRead: values.allowRead ?? false,
283
+ allowWrite: values.allowWrite ?? false,
284
+ allowConfigEdit: values.allowConfigEdit ?? false,
285
+ allowExec: values.allowExec ?? false
286
+ },
287
+ autoOpen: values.open ?? true,
288
+ logLevel: values.logLevel
289
+ };
348
290
  const report = require_Telemetry.trackRun({
349
291
  command: "studio",
350
292
  hrStart: node_process.default.hrtime()
@@ -354,74 +296,20 @@ async function run({ options, action, block = false, json = false }) {
354
296
  warning: (0, node_util.styleText)("yellow", "This feature is still under development, use with caution"),
355
297
  block
356
298
  });
357
- await action();
299
+ await action(options);
358
300
  await report({ status: "success" });
359
301
  } catch (error) {
360
302
  await report({ status: "failed" });
361
- console.error(require_errors.toError(error).message);
303
+ console.error(require_Telemetry.toError(error).message);
362
304
  node_process.default.exitCode = 1;
363
305
  }
364
306
  }
365
307
  //#endregion
366
- Object.defineProperty(exports, "clearCredentials", {
367
- enumerable: true,
368
- get: function() {
369
- return clearCredentials;
370
- }
371
- });
372
- Object.defineProperty(exports, "connect", {
373
- enumerable: true,
374
- get: function() {
375
- return connect;
376
- }
377
- });
378
- Object.defineProperty(exports, "createStudioOptions", {
379
- enumerable: true,
380
- get: function() {
381
- return createStudioOptions;
382
- }
383
- });
384
- Object.defineProperty(exports, "formatPermissionRows", {
385
- enumerable: true,
386
- get: function() {
387
- return formatPermissionRows;
388
- }
389
- });
390
- Object.defineProperty(exports, "getProjectKubbHome", {
391
- enumerable: true,
392
- get: function() {
393
- return getProjectKubbHome;
394
- }
395
- });
396
- Object.defineProperty(exports, "loadConfigs", {
397
- enumerable: true,
398
- get: function() {
399
- return loadConfigs;
400
- }
401
- });
402
- Object.defineProperty(exports, "login", {
403
- enumerable: true,
404
- get: function() {
405
- return login;
406
- }
407
- });
408
- Object.defineProperty(exports, "prepareConnection", {
409
- enumerable: true,
410
- get: function() {
411
- return prepareConnection;
412
- }
413
- });
414
- Object.defineProperty(exports, "readCredentials", {
415
- enumerable: true,
416
- get: function() {
417
- return readCredentials;
418
- }
419
- });
420
- Object.defineProperty(exports, "run", {
421
- enumerable: true,
422
- get: function() {
423
- return run;
424
- }
425
- });
308
+ exports.connect = connect;
309
+ exports.formatPermissionRows = formatPermissionRows;
310
+ exports.loadConfigs = loadConfigs;
311
+ exports.login = login;
312
+ exports.prepareConnection = prepareConnection;
313
+ exports.runStudio = runStudio;
426
314
 
427
- //# sourceMappingURL=run-C8dyBAPb.cjs.map
315
+ //# sourceMappingURL=run-QqLDhthl.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-QqLDhthl.cjs","names":["isCIEnvironment","process","createSpinner","pairAgent","path","process","hostname","getMachineId","styleText","writeCredentials","getCredentialsPath","PairingCanceledError","KUBB_CONFIG_FILENAME","isCIEnvironment","canUseTTY","prompts","getConfigs","readCredentials","Hookable","logLevelMap","cliReporter","plainLogger","connectAgent","InvalidAgentTokenError","clearCredentials","defaultStudioUrl","trackRun","toError"],"sources":["../../../internals/utils/src/openInBrowser.ts","../src/runners/studio/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { x } from 'tinyexec'\nimport { isCIEnvironment } from './isCIEnvironment.ts'\n\nconst ignore = () => {}\n\n/**\n * Opens a URL or local file in the default browser, unless running in CI.\n */\nexport function openInBrowser(target: string): void {\n if (isCIEnvironment()) return\n\n if (process.platform === 'win32') {\n x('cmd', ['/c', 'start', '', target]).then(ignore, ignore)\n return\n }\n x(process.platform === 'darwin' ? 'open' : 'xdg-open', [target]).then(ignore, ignore)\n}\n","import { hostname } from 'node:os'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport * as prompts from '@clack/prompts'\nimport { KUBB_CONFIG_FILENAME } from '@internals/shared'\nimport { isCIEnvironment, openInBrowser, toError } from '@internals/utils'\nimport type { CLIOptions, Config } from '@kubb/core'\nimport { cliReporter, Hookable, type KubbHooks, logLevel as logLevelMap } from '@kubb/core'\nimport { connectAgent, defaultStudioUrl, InvalidAgentTokenError, pairAgent, PairingCanceledError } from '@kubb/studio'\nimport { trackRun } from '../../Telemetry.ts'\nimport { plainLogger } from '../../loggers/plainLogger.ts'\nimport setupReporters from '../../loggers/reporters.ts'\nimport { createSpinner, logBlock, logIntro, logOutro, logTip } from '../../loggers/output.ts'\nimport { canUseTTY } from '../../utils/env.ts'\nimport { getConfigs } from '../../config.ts'\nimport { clearCredentials, type Credentials, getCredentialsPath, getMachineId, readCredentials, writeCredentials } from './credentials.ts'\nimport { version } from '../../../package.json'\n\ntype Permission = 'allowRead' | 'allowWrite' | 'allowConfigEdit' | 'allowExec'\n\nexport type StudioOptions = {\n /**\n * Current `@kubb/cli` version, reported to Studio and used for the telemetry payload.\n */\n version: string\n configPath?: string\n /**\n * Base URL of the Studio instance, for a self-hosted deployment. Resolved before it reaches here,\n * since stored credentials are bound to it.\n */\n studioUrl: string\n /**\n * What Studio may do in this project. Each flag grants outright; the rest are asked once per\n * project through {@link resolvePermissions}.\n */\n permission: Record<Permission, boolean>\n /**\n * Whether to open the approval page in a browser during pairing.\n */\n autoOpen: boolean\n logLevel?: CLIOptions['logLevel']\n}\n\nexport type SnapshotOptions = Pick<StudioOptions, 'configPath' | 'studioUrl' | 'logLevel'> & {\n /**\n * Organization CI API key. Falls back to `KUBB_TOKEN`.\n */\n token?: string\n /**\n * Stable identity for the CI agent. Falls back to CI auto-detection.\n */\n id?: string\n /** Identity of another CI agent to also compare with. Falls back to CI auto-detection. */\n baseId?: string\n /**\n * Package name for the generated tarball. Falls back to the nearest package.json.\n */\n name?: string\n /**\n * Package version for the generated tarball. Falls back to the nearest package.json.\n */\n packageVersion?: string\n /**\n * Print the result as one JSON object instead of a summary.\n */\n json?: boolean\n}\n\n/** The flags a `kubb studio` subcommand parsed; each one is optional since a subcommand declares only the flags it uses. */\nexport type StudioValues = {\n config?: string\n url?: string\n allowRead?: boolean\n allowWrite?: boolean\n allowConfigEdit?: boolean\n allowExec?: boolean\n open?: boolean\n logLevel?: CLIOptions['logLevel']\n}\n\ntype LoginOptions = {\n /**\n * Aborting this cancels an in-flight pairing request or poll and rejects with\n * {@link PairingCanceledError}. Wired to `kubb studio`'s shutdown signal, so Ctrl+C during\n * pairing cancels it instead of leaving the poll running.\n */\n signal?: AbortSignal\n /**\n * Credentials from before this login. When the fresh pairing resolves to the same agent on the\n * same Studio, its saved project permissions carry forward instead of being asked again.\n * Left out for an explicitly requested `kubb studio login`, which always starts clean.\n */\n previousCredentials?: Credentials | null\n}\n\n/**\n * Pairs this machine with Studio and stores the resulting token.\n *\n * The CLI holds a code and the browser approves it, rather than the user copying a token out of\n * the UI. The token comes back over the CLI's own HTTPS POST, so it never lands in a URL, a\n * server log, or a `Referer` header.\n */\nexport async function login({ studioUrl, autoOpen }: StudioOptions, { signal, previousCredentials }: LoginOptions = {}): Promise<Credentials> {\n const spinner = createSpinner()\n // The spinner only starts once a code is shown.\n let waiting = false\n\n try {\n const { token, agent } = await pairAgent({\n studioUrl,\n type: 'cli',\n name: path.basename(process.cwd()),\n hostname: hostname(),\n machineId: await getMachineId(),\n signal,\n onCode: (session) => {\n console.log(`\\nOpen ${styleText('cyan', session.verification_uri)} and approve the code ${styleText('bold', session.user_code)}`)\n\n if (autoOpen) {\n openInBrowser(session.verification_uri_complete)\n }\n\n spinner.start('Waiting for approval')\n waiting = true\n },\n onRetry: (error) => spinner.message(`Could not reach Kubb Studio, retrying: ${error.message}`),\n })\n spinner.stop(`Paired as ${agent.name}`)\n\n const keepsIdentity = previousCredentials?.studioUrl === studioUrl && previousCredentials.agentId === agent.id\n const credentials: Credentials = {\n studioUrl,\n token,\n agentId: agent.id,\n agentSlug: agent.slug,\n ...(keepsIdentity && previousCredentials?.projects ? { projects: previousCredentials.projects } : {}),\n }\n await writeCredentials(credentials)\n\n console.log(`Credentials stored in ${getCredentialsPath()}`)\n\n return credentials\n } catch (error) {\n if (waiting) {\n spinner.stop(error instanceof PairingCanceledError ? 'Pairing canceled' : 'Pairing failed')\n }\n throw error\n }\n}\n\n/**\n * What each permission is asked as, in the order the questions appear.\n */\nconst PERMISSIONS: ReadonlyArray<{\n key: Permission\n /**\n * Short label for status output and the connect summary.\n */\n label: string\n question: (project: string, configPath: string) => string\n}> = [\n {\n key: 'allowRead',\n label: 'read generated files',\n question: () => 'Let Kubb Studio read the files a generation produced?',\n },\n { key: 'allowWrite', label: 'write generated files', question: (project) => `Let Kubb Studio write generated files into ${project}?` },\n {\n key: 'allowConfigEdit',\n label: 'edit kubb.config.ts',\n question: (_project, configPath) => `Let Kubb Studio change plugin options in ${configPath}?`,\n },\n {\n key: 'allowExec',\n label: 'run formatter, linter, postGenerate',\n question: () => 'Let Kubb Studio run the formatter, the linter, and output.postGenerate?',\n },\n]\n\n/**\n * One row per permission, for the connect banner and `kubb studio status`. A list rather than a\n * joined line: four labels this long read as one run-on sentence side by side.\n */\nexport function formatPermissionRows(granted: Record<Permission, boolean>): Array<string> {\n return PERMISSIONS.map(({ key, label }) => `${granted[key] ? styleText('green', '✔') : styleText('red', '✘')} ${label}`)\n}\n\n/**\n * Resolves Studio permissions for the current project.\n * Flags win, saved answers are reused, and new answers are stored unless `persist` is false.\n */\nexport async function resolvePermissions(\n options: StudioOptions,\n credentials: Credentials,\n configPath: string = KUBB_CONFIG_FILENAME,\n /**\n * Stores new answers in `~/.kubb/credentials.json`.\n * Pass `false` for `KUBB_AGENT_TOKEN` sessions so a temporary token is not written back to disk.\n */\n persist = true,\n): Promise<Record<Permission, boolean>> {\n const project = process.cwd()\n const remembered = credentials.projects?.[project]\n const granted: Record<Permission, boolean> = { allowRead: false, allowWrite: false, allowConfigEdit: false, allowExec: false }\n const answers: Partial<Record<Permission, boolean>> = {}\n prompts.updateSettings({ withGuide: true })\n\n for (const { key, question } of PERMISSIONS) {\n if (options.permission[key] || typeof remembered?.[key] === 'boolean') {\n granted[key] = options.permission[key] || remembered?.[key] === true\n continue\n }\n\n if (isCIEnvironment() || !canUseTTY()) {\n granted[key] = false\n continue\n }\n\n granted[key] = (await prompts.confirm({ message: question(project, configPath), initialValue: false })) === true\n answers[key] = granted[key]\n }\n if (persist && Object.keys(answers).length) {\n await writeCredentials({\n ...credentials,\n projects: { ...credentials.projects, [project]: { ...remembered, ...answers } },\n })\n }\n\n return granted\n}\n\n/**\n * Loads the project's Kubb config the same way `kubb generate` does.\n * Returns the first config.\n */\nexport async function loadConfigs(options: Pick<StudioOptions, 'configPath' | 'logLevel'>): Promise<{ configPath: string; config: Config }> {\n const { configPath, configs } = await getConfigs({ configPath: options.configPath, logLevel: options.logLevel })\n const [config] = configs\n\n if (!config) {\n throw new Error('Config not defined, create a kubb.config.ts or pass it with --config')\n }\n\n // `getConfigs` resolves this to an absolute path. Relativized here, once, so the permission\n // prompt and the path Studio receives over the wire both show the project-relative form instead\n // of leaking the local filesystem layout.\n return { configPath: path.relative(process.cwd(), configPath) || configPath, config }\n}\n\n/**\n * Why a rejected token could not be recovered automatically: it came from `KUBB_AGENT_TOKEN`, no\n * browser is available to re-pair with, or the token this run already re-paired for was rejected\n * again.\n */\ntype RejectedTokenReason = 'envToken' | 'nonInteractive' | 'reauthExhausted'\n\n/**\n * Explains a rejected token to the operator. Builds the error and nothing else, so each caller\n * decides what happens to the credentials.\n */\nfunction explainRejectedToken(error: InvalidAgentTokenError, reason: RejectedTokenReason): Error {\n if (reason === 'envToken') {\n return new Error(`${error.message} Pair again and update KUBB_AGENT_TOKEN.`)\n }\n\n if (reason === 'reauthExhausted') {\n return new Error(`${error.message} Studio rejected the newly approved token too. Run \\`kubb studio login\\` and try again.`)\n }\n\n return new Error(`${error.message} Run \\`kubb studio login\\` to pair again.`)\n}\n\nexport type PreparedConnection = {\n configPath: string\n credentials: Credentials\n permissions: StudioOptions['permission']\n}\n\n/** Validates the project and resolves pairing and permissions before starting its worker. */\nexport async function prepareConnection(options: StudioOptions, signal?: AbortSignal): Promise<PreparedConnection> {\n const { configPath } = await loadConfigs(options)\n const envToken = process.env.KUBB_AGENT_TOKEN\n const stored = envToken ? null : await readCredentials()\n const credentials = await (async () => {\n if (envToken) return { studioUrl: options.studioUrl, token: envToken, agentId: '', agentSlug: '' }\n if (stored?.studioUrl === options.studioUrl) return stored\n if (isCIEnvironment()) {\n throw new Error(`Not paired with ${options.studioUrl}. Set KUBB_AGENT_TOKEN, or run \\`kubb studio login\\` on a machine with a browser.`)\n }\n return login(options, { signal })\n })()\n const permissions = await resolvePermissions(options, credentials, configPath, !envToken)\n return { configPath, credentials, permissions }\n}\n\nexport type WorkerState = 'starting' | 'connected' | 'reconnecting' | 'authentication required' | 'stopped'\n\n/** Runs the same project connection in the foreground or in a background worker. */\nexport async function connect(\n options: StudioOptions,\n context: {\n prepared?: PreparedConnection\n signal?: AbortSignal\n onState?: (state: WorkerState) => void | Promise<void>\n } = {},\n): Promise<void> {\n const shutdown = new AbortController()\n const signal = context.signal ?? shutdown.signal\n const stop = () => shutdown.abort()\n const events = process as unknown as NodeJS.EventEmitter\n if (!context.signal) {\n events.once('SIGINT', stop)\n events.once('SIGTERM', stop)\n }\n try {\n if (!context.prepared) {\n const { getWorkerStatus } = await import('./background.ts')\n const worker = await getWorkerStatus()\n if (worker.running) throw new Error('This project is running in the background. Run `kubb studio stop` first.')\n }\n const prepared = context.prepared ?? (await prepareConnection(options, signal))\n let { credentials, permissions } = prepared\n const { configPath } = prepared\n let hinted = false\n // Set by a fresh pairing until it connects, so a token rejected right after approval fails the run instead of looping.\n let pairedAgain = false\n\n // The background worker writes to a log file, so it gets the plain logger rather than the\n // animated one. The logger also covers the `studio:*` events and each generation run.\n const hooks = new Hookable<KubbHooks>()\n setupReporters(hooks, {\n logLevel: logLevelMap[options.logLevel ?? 'info'],\n reporters: [cliReporter],\n ...(context.onState ? { logger: plainLogger } : {}),\n })\n hooks.hook('studio:connected', async () => {\n pairedAgain = false\n await context.onState?.('connected')\n if (hinted || context.onState || options.logLevel === 'silent') return\n hinted = true\n logBlock(styleText('dim', 'Press Ctrl+C to disconnect'))\n logTip()\n })\n hooks.hook('studio:reconnecting', () => context.onState?.('reconnecting'))\n\n for (;;) {\n try {\n await connectAgent({\n token: credentials.token,\n studioUrl: options.studioUrl,\n configPath,\n version: options.version,\n root: process.cwd(),\n permissions,\n loadConfig: async () => (await loadConfigs(options)).config,\n hooks,\n signal,\n })\n break\n } catch (error) {\n if (!(error instanceof InvalidAgentTokenError)) throw error\n await context.onState?.('authentication required')\n if (process.env.KUBB_AGENT_TOKEN) throw explainRejectedToken(error, 'envToken')\n await clearCredentials()\n if (pairedAgain) throw explainRejectedToken(error, 'reauthExhausted')\n if (context.onState || isCIEnvironment() || !canUseTTY()) throw explainRejectedToken(error, 'nonInteractive')\n\n console.log(styleText('yellow', `${error.message} Pairing again...`))\n credentials = await login(options, { signal, previousCredentials: credentials })\n pairedAgain = true\n permissions = await resolvePermissions(options, credentials, configPath)\n }\n }\n if (!context.onState && signal.aborted && options.logLevel !== 'silent') logOutro('Disconnected')\n } catch (error) {\n if (!(error instanceof PairingCanceledError)) throw error\n } finally {\n events.off('SIGINT', stop)\n events.off('SIGTERM', stop)\n }\n}\n\n/**\n * Runs a Studio command from its parsed flags: builds the {@link StudioOptions}, prints the intro,\n * and reports the run to telemetry. A failure is printed and sets the exit code instead of throwing.\n */\nexport async function runStudio(\n values: StudioValues,\n action: (options: StudioOptions) => Promise<unknown>,\n { block = false, json = false }: { block?: boolean; json?: boolean } = {},\n): Promise<void> {\n const options: StudioOptions = {\n version,\n configPath: values.config,\n studioUrl: values.url ?? defaultStudioUrl,\n permission: {\n allowRead: values.allowRead ?? false,\n allowWrite: values.allowWrite ?? false,\n allowConfigEdit: values.allowConfigEdit ?? false,\n allowExec: values.allowExec ?? false,\n },\n autoOpen: values.open ?? true,\n logLevel: values.logLevel,\n }\n const report = trackRun({ command: 'studio', hrStart: process.hrtime() })\n\n try {\n if (options.logLevel !== 'silent' && !json) {\n logIntro({\n warning: styleText('yellow', 'This feature is still under development, use with caution'),\n block,\n })\n }\n\n await action(options)\n\n await report({ status: 'success' })\n } catch (error) {\n await report({ status: 'failed' })\n console.error(toError(error).message)\n process.exitCode = 1\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { t as connect, n as formatPermissionRows, i as login, s as runStudio } from "./run-DcP1czVQ.js";