@kubb/cli 5.11.4 → 5.11.6

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 (100) hide show
  1. package/dist/{Telemetry-Be1nltUh.cjs → Telemetry-Be3hIy6_.cjs} +2 -42
  2. package/dist/Telemetry-Be3hIy6_.cjs.map +1 -0
  3. package/dist/{Telemetry-CwaVQsvD.js → Telemetry-CfJAUDnh.js} +3 -31
  4. package/dist/Telemetry-CfJAUDnh.js.map +1 -0
  5. package/dist/{background-CQPyCSn0.js → background-BBpH2jmk.js} +7 -5
  6. package/dist/background-BBpH2jmk.js.map +1 -0
  7. package/dist/{background-mKdZ5HRx.cjs → background-BW-e9FCX.cjs} +5 -4
  8. package/dist/background-BW-e9FCX.cjs.map +1 -0
  9. package/dist/{background-aTbwrgui.js → background-DS2zOde-.js} +1 -1
  10. package/dist/config-Bh00Hwpw.js +132 -0
  11. package/dist/config-Bh00Hwpw.js.map +1 -0
  12. package/dist/config-D63Gum4F.cjs +169 -0
  13. package/dist/config-D63Gum4F.cjs.map +1 -0
  14. package/dist/config-iVdOcpro.js +1 -0
  15. package/dist/credentials-CZK6zPLv.js.map +1 -1
  16. package/dist/credentials-DDaKqtJn.cjs.map +1 -1
  17. package/dist/errors-Cl69p_vI.cjs +43 -0
  18. package/dist/errors-Cl69p_vI.cjs.map +1 -0
  19. package/dist/errors-DmC83ALX.js +32 -0
  20. package/dist/errors-DmC83ALX.js.map +1 -0
  21. package/dist/index.cjs +872 -307
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.js +863 -298
  24. package/dist/index.js.map +1 -1
  25. package/dist/registry-BlKLO4ft.cjs +272 -0
  26. package/dist/registry-BlKLO4ft.cjs.map +1 -0
  27. package/dist/registry-CgQYxUju.js +200 -0
  28. package/dist/registry-CgQYxUju.js.map +1 -0
  29. package/dist/reporters-Dl8lrJZG.js +817 -0
  30. package/dist/reporters-Dl8lrJZG.js.map +1 -0
  31. package/dist/reporters-TkCgd4dS.cjs +829 -0
  32. package/dist/reporters-TkCgd4dS.cjs.map +1 -0
  33. package/dist/{run-YHth5Afz.js → run-BJn0RSW2.js} +170 -76
  34. package/dist/run-BJn0RSW2.js.map +1 -0
  35. package/dist/{run-BWRmQxtE.cjs → run-BszyZwY3.cjs} +176 -82
  36. package/dist/run-BszyZwY3.cjs.map +1 -0
  37. package/dist/{run-Bczs5vbI.cjs → run-BtVKUjdK.cjs} +4 -3
  38. package/dist/{run-Bczs5vbI.cjs.map → run-BtVKUjdK.cjs.map} +1 -1
  39. package/dist/run-CFf0yxyY.cjs +94 -0
  40. package/dist/run-CFf0yxyY.cjs.map +1 -0
  41. package/dist/run-D_dD7xHp.js +93 -0
  42. package/dist/run-D_dD7xHp.js.map +1 -0
  43. package/dist/run-DsJJCzQD.js +1 -0
  44. package/dist/{run-B6VxJ_VM.js → run-KuzAqsjg.js} +3 -2
  45. package/dist/{run-B6VxJ_VM.js.map → run-KuzAqsjg.js.map} +1 -1
  46. package/dist/run-TrjCNL8e.cjs +227 -0
  47. package/dist/run-TrjCNL8e.cjs.map +1 -0
  48. package/dist/run-wkN1irUo.js +224 -0
  49. package/dist/run-wkN1irUo.js.map +1 -0
  50. package/dist/{snapshot-Cilp10vE.js → snapshot-CdGwHH15.js} +49 -62
  51. package/dist/snapshot-CdGwHH15.js.map +1 -0
  52. package/dist/{snapshot-D_rXnnMH.cjs → snapshot-u4L8mh4Y.cjs} +51 -64
  53. package/dist/snapshot-u4L8mh4Y.cjs.map +1 -0
  54. package/dist/status-DHPeR3bq.js +77 -0
  55. package/dist/status-DHPeR3bq.js.map +1 -0
  56. package/dist/status-dpSvxxtN.cjs +78 -0
  57. package/dist/status-dpSvxxtN.cjs.map +1 -0
  58. package/dist/studioWorker.js +2 -2
  59. package/dist/summary-6-rotl2L.cjs +46 -0
  60. package/dist/summary-6-rotl2L.cjs.map +1 -0
  61. package/dist/summary-DkSLti6f.js +41 -0
  62. package/dist/summary-DkSLti6f.js.map +1 -0
  63. package/dist/text-CMP4M19Z.js +239 -0
  64. package/dist/text-CMP4M19Z.js.map +1 -0
  65. package/dist/text-CknhKMvM.cjs +341 -0
  66. package/dist/text-CknhKMvM.cjs.map +1 -0
  67. package/dist/utils-CnjEJIdZ.js +612 -0
  68. package/dist/utils-CnjEJIdZ.js.map +1 -0
  69. package/dist/utils-DpKrXR2t.cjs +727 -0
  70. package/dist/utils-DpKrXR2t.cjs.map +1 -0
  71. package/package.json +7 -7
  72. package/dist/Telemetry-Be1nltUh.cjs.map +0 -1
  73. package/dist/Telemetry-CwaVQsvD.js.map +0 -1
  74. package/dist/background-CQPyCSn0.js.map +0 -1
  75. package/dist/background-mKdZ5HRx.cjs.map +0 -1
  76. package/dist/config-B56ZuVhi.js +0 -95
  77. package/dist/config-B56ZuVhi.js.map +0 -1
  78. package/dist/config-Cs4N79Fm.cjs +0 -113
  79. package/dist/config-Cs4N79Fm.cjs.map +0 -1
  80. package/dist/output-HgzJqkSF.cjs +0 -1076
  81. package/dist/output-HgzJqkSF.cjs.map +0 -1
  82. package/dist/output-PhkPtNP7.js +0 -937
  83. package/dist/output-PhkPtNP7.js.map +0 -1
  84. package/dist/registry-DYUhC7rH.js +0 -115
  85. package/dist/registry-DYUhC7rH.js.map +0 -1
  86. package/dist/registry-tk-v78fd.cjs +0 -157
  87. package/dist/registry-tk-v78fd.cjs.map +0 -1
  88. package/dist/run-AfjIBtiL.js +0 -39
  89. package/dist/run-AfjIBtiL.js.map +0 -1
  90. package/dist/run-BWRmQxtE.cjs.map +0 -1
  91. package/dist/run-B_Gr9TJ4.cjs +0 -345
  92. package/dist/run-B_Gr9TJ4.cjs.map +0 -1
  93. package/dist/run-CwrI0wRy.js +0 -1
  94. package/dist/run-DDoJGjWT.cjs +0 -40
  95. package/dist/run-DDoJGjWT.cjs.map +0 -1
  96. package/dist/run-SYKj8-Q5.js +0 -343
  97. package/dist/run-SYKj8-Q5.js.map +0 -1
  98. package/dist/run-YHth5Afz.js.map +0 -1
  99. package/dist/snapshot-Cilp10vE.js.map +0 -1
  100. package/dist/snapshot-D_rXnnMH.cjs.map +0 -1
@@ -1,31 +1,16 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
2
- const require_Telemetry = require("./Telemetry-Be1nltUh.cjs");
3
- const require_output = require("./output-HgzJqkSF.cjs");
4
- const require_config = require("./config-Cs4N79Fm.cjs");
5
- const require_run = require("./run-BWRmQxtE.cjs");
2
+ const require_Telemetry = require("./Telemetry-Be3hIy6_.cjs");
3
+ const require_utils = require("./utils-DpKrXR2t.cjs");
4
+ const require_text = require("./text-CknhKMvM.cjs");
5
+ const require_reporters = require("./reporters-TkCgd4dS.cjs");
6
+ const require_run = require("./run-BszyZwY3.cjs");
6
7
  let node_util = require("node:util");
7
8
  let node_process = require("node:process");
8
9
  node_process = require_rolldown_runtime.__toESM(node_process, 1);
9
- let node_fs_promises = require("node:fs/promises");
10
10
  let node_path = require("node:path");
11
11
  let node_fs = require("node:fs");
12
12
  let _kubb_core = require("@kubb/core");
13
13
  let _kubb_studio = require("@kubb/studio");
14
- //#region ../../internals/utils/src/fs.ts
15
- /**
16
- * Reads the file at `path` as a UTF-8 string.
17
- * Uses `Bun.file().text()` when running under Bun, `fs.readFile` otherwise.
18
- *
19
- * @example
20
- * ```ts
21
- * const source = await read('./src/Pet.ts')
22
- * ```
23
- */
24
- async function read(path) {
25
- if (require_Telemetry.runtime.isBun) return Bun.file(path).text();
26
- return (0, node_fs_promises.readFile)(path, { encoding: "utf8" });
27
- }
28
- //#endregion
29
14
  //#region src/runners/studio/ci.ts
30
15
  function readGithubPullRequest(eventPath) {
31
16
  if (!eventPath) return;
@@ -101,7 +86,7 @@ function detectCi(env = node_process.default.env) {
101
86
  * Walks up from `directory` to the first package.json with a name and a version.
102
87
  */
103
88
  async function findPackageJson(directory) {
104
- const packageJson = JSON.parse(await read((0, node_path.join)(directory, "package.json")).catch(() => "{}"));
89
+ const packageJson = JSON.parse(await require_utils.read((0, node_path.join)(directory, "package.json")).catch(() => "{}"));
105
90
  if (packageJson.name && packageJson.version) return {
106
91
  name: packageJson.name,
107
92
  version: packageJson.version
@@ -115,27 +100,6 @@ async function findPackageJson(directory) {
115
100
  });
116
101
  return findPackageJson(parent);
117
102
  }
118
- /** Reads package.json only for whichever of name/version --name and --version did not supply. */
119
- async function resolvePackageMetadata(options) {
120
- if (options.name && options.packageVersion) return {
121
- name: options.name,
122
- version: options.packageVersion
123
- };
124
- const found = await findPackageJson(node_process.default.cwd());
125
- return {
126
- name: options.name ?? found.name,
127
- version: options.packageVersion ?? found.version
128
- };
129
- }
130
- function resolveToken(options) {
131
- const token = options.token ?? node_process.default.env.KUBB_TOKEN;
132
- if (!token) throw new _kubb_core.Diagnostics.Error({
133
- code: _kubb_core.Diagnostics.code.unknown,
134
- severity: "error",
135
- message: "An organization CI API key is required. Pass --token or set KUBB_TOKEN."
136
- });
137
- return token;
138
- }
139
103
  function resolveCiIdentity(options) {
140
104
  const detected = detectCi();
141
105
  const ci = options.id ? {
@@ -163,11 +127,13 @@ function absoluteUrl(studioUrl, path) {
163
127
  function toResult({ studioUrl, snapshot, ci }) {
164
128
  return {
165
129
  id: snapshot.id,
130
+ number: snapshot.number,
166
131
  name: snapshot.name,
167
132
  version: snapshot.version,
168
133
  integrity: snapshot.integrity,
169
134
  url: absoluteUrl(studioUrl, snapshot.url),
170
135
  snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),
136
+ webUrl: snapshot.webUrl ? absoluteUrl(studioUrl, snapshot.webUrl) : void 0,
171
137
  expiresAt: snapshot.expiresAt,
172
138
  agentUrl: absoluteUrl(studioUrl, `/agents/${snapshot.agent.slug ?? snapshot.agent.id}`),
173
139
  changes: snapshot.changes,
@@ -180,49 +146,69 @@ function toResult({ studioUrl, snapshot, ci }) {
180
146
  /** How many files differ, `against` what. */
181
147
  function describeChanges(changes, against) {
182
148
  const { added, changed, removed } = changes;
183
- return added.length + changed.length + removed.length ? `${added.length} added, ${changed.length} changed, ${removed.length} removed ${against}` : `No changes ${against}`;
149
+ const parts = [
150
+ added.length && `+${require_text.pluralize(added.length, "file")}`,
151
+ changed.length && `~${changed.length} changed`,
152
+ removed.length && `-${removed.length} removed`
153
+ ].filter(Boolean);
154
+ return parts.length ? `${parts.join(" ")} ${against}` : `No changes ${against}`;
184
155
  }
185
156
  /** One summary line: how many files changed, and since which run. */
186
157
  function formatChanges(changes) {
187
158
  if (!changes.base) return "First snapshot";
188
- return describeChanges(changes, `since ${changes.base.commit?.slice(0, 7) ?? changes.base.createdAt}`);
159
+ const { number, commit, createdAt } = changes.base;
160
+ return describeChanges(changes, `vs ${number ? `#${number}` : commit?.slice(0, 7) ?? createdAt}`);
189
161
  }
190
162
  /** One summary line: how the snapshot differs from the base branch's latest one. */
191
163
  function formatBranchChanges(changes) {
192
- if (changes.base) return describeChanges(changes, `against ${changes.branch}`);
164
+ if (changes.base) return describeChanges(changes, `vs ${changes.branch}`);
193
165
  return changes.baseFound ? `No snapshot of ${changes.branch} for this package yet` : `No snapshot of ${changes.branch} to compare with`;
194
166
  }
195
167
  function printSummary(result) {
196
- require_output.logBlock([
197
- `${(0, node_util.styleText)("dim", "Package".padEnd(10))} ${result.name ?? "(unnamed)"}@${result.version ?? "0.0.0"}`,
198
- `${(0, node_util.styleText)("dim", "Tarball".padEnd(10))} ${(0, node_util.styleText)("cyan", result.url)}`,
199
- `${(0, node_util.styleText)("dim", "Agent".padEnd(10))} ${result.agentUrl}`,
200
- ...result.branchChanges ? [`${(0, node_util.styleText)("dim", "Branch".padEnd(10))} ${formatBranchChanges(result.branchChanges)}`] : [],
201
- ...result.changes ? [`${(0, node_util.styleText)("dim", "Changes".padEnd(10))} ${formatChanges(result.changes)}`] : [],
202
- `${(0, node_util.styleText)("dim", "Expires".padEnd(10))} ${result.expiresAt}`
203
- ]);
168
+ const row = (label, value) => ` ${(0, node_util.styleText)("dim", label.padEnd(7))} ${value}`;
169
+ console.log([
170
+ "",
171
+ ...result.webUrl ? [row("View", (0, node_util.styleText)("cyan", result.webUrl))] : [],
172
+ ...result.changes ? [row("Diff", formatChanges(result.changes))] : [],
173
+ ...result.branchChanges ? [row("Branch", formatBranchChanges(result.branchChanges))] : [],
174
+ row("Use", `npm i ${result.url}`),
175
+ row("Expires", result.expiresAt.slice(0, 10))
176
+ ].join("\n"));
204
177
  }
205
178
  /**
206
179
  * Generates the project, packs it, and publishes it to Kubb Studio in one request, under the CI
207
180
  * agent the run's identity names.
208
181
  */
209
182
  async function snapshot(options) {
210
- const token = resolveToken(options);
211
- const { config } = await require_run.loadConfigs(options);
183
+ const token = options.token ?? node_process.default.env.KUBB_TOKEN;
184
+ if (!token) throw new _kubb_core.Diagnostics.Error({
185
+ code: _kubb_core.Diagnostics.code.unknown,
186
+ severity: "error",
187
+ message: "An organization CI API key is required. Pass --token or set KUBB_TOKEN."
188
+ });
189
+ const config = (await require_run.loadConfigs(options)).configs[0];
212
190
  const ci = resolveCiIdentity(options);
213
- const { name, version: packageVersion } = await resolvePackageMetadata(options);
191
+ const { name, version: packageVersion } = options.name && options.packageVersion ? {
192
+ name: options.name,
193
+ version: options.packageVersion
194
+ } : await findPackageJson(node_process.default.cwd()).then((found) => ({
195
+ name: options.name ?? found.name,
196
+ version: options.packageVersion ?? found.version
197
+ }));
214
198
  const logLevel = _kubb_core.logLevel[options.logLevel ?? "info"];
215
199
  const write = options.json ? (line) => console.error(line) : (line) => console.log(line);
216
200
  const hooks = new _kubb_core.Hookable();
217
- require_config.setupReporters(hooks, {
218
- logLevel,
201
+ require_reporters.setupReporters(hooks, {
202
+ logLevel: logLevel > _kubb_core.logLevel.info ? logLevel : _kubb_core.logLevel.silent,
219
203
  reporters: [_kubb_core.cliReporter],
220
- logger: require_output.createPlainLogger(write)
204
+ writer: require_text.createPlainWriter(write)
221
205
  });
222
206
  const step = (message) => {
223
207
  if (logLevel > _kubb_core.logLevel.silent) write(message);
224
208
  };
225
- step("Generating the snapshot");
209
+ hooks.hook("kubb:generation:end", ({ filesCreated = 0, status, hrStart }) => {
210
+ if (status !== "failed" && hrStart) step(`✓ Generated ${require_text.pluralize(filesCreated, "file")} in ${require_Telemetry.formatMs(require_Telemetry.getElapsedMs(hrStart))}`);
211
+ });
226
212
  try {
227
213
  const published = await (0, _kubb_studio.createSnapshot)({
228
214
  studioUrl: options.studioUrl,
@@ -241,11 +227,12 @@ async function snapshot(options) {
241
227
  snapshot: published,
242
228
  ci
243
229
  });
244
- step("Snapshot published");
230
+ step(`✓ Packed ${result.name ?? name}@${result.version ?? packageVersion}`);
231
+ step(`✓ Published snapshot ${result.number ? `#${result.number}` : result.id} for ${ci.name}${ci.commit ? `@${ci.commit.slice(0, 7)}` : ""}`);
245
232
  if (options.json) console.log(JSON.stringify(result));
246
- if (!options.json) printSummary(result);
233
+ else printSummary(result);
247
234
  } catch (error) {
248
- step("Snapshot failed");
235
+ step("✖ Snapshot failed");
249
236
  throw error;
250
237
  }
251
238
  }
@@ -261,4 +248,4 @@ const runner = ({ values }) => require_run.runStudio(values, (options) => snapsh
261
248
  //#endregion
262
249
  exports.runner = runner;
263
250
 
264
- //# sourceMappingURL=snapshot-D_rXnnMH.cjs.map
251
+ //# sourceMappingURL=snapshot-u4L8mh4Y.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-u4L8mh4Y.cjs","names":["readFileSync","process","read","join","dirname","Diagnostics","process","pluralize","styleText","loadConfigs","logLevelMap","Hookable","cliReporter","createPlainWriter","formatMs","getElapsedMs","createSnapshot","runStudio"],"sources":["../src/runners/studio/ci.ts","../src/runners/studio/snapshot.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport process from 'node:process'\n\n/**\n * Stable identity for the CI agent a snapshot run registers or reuses.\n */\nexport type CiContext = {\n /**\n * Fed into the machine token, so the same merge or pull request reuses one agent.\n */\n id: string\n /**\n * Agent display name shown in Studio.\n */\n name: string\n /** The commit this run builds, so the next snapshot can diff against it. */\n commit?: string\n /** The branch a pull request merges into, and the `id` runs on that branch register under. */\n base?: { branch: string; id: string }\n}\n\ntype GithubPullRequest = { number: number; head?: { sha?: string }; base?: { ref?: string } }\n\nfunction readGithubPullRequest(eventPath: string | undefined): GithubPullRequest | undefined {\n if (!eventPath) {\n return undefined\n }\n\n try {\n const event = JSON.parse(readFileSync(eventPath, 'utf8')) as { pull_request?: GithubPullRequest }\n return event.pull_request?.number ? event.pull_request : undefined\n } catch {\n return undefined\n }\n}\n\n/** Reproduces GitLab's `CI_COMMIT_REF_SLUG` for a branch it gives no slug of, like a merge request's target. */\nexport function gitlabRefSlug(ref: string): string {\n return ref\n .toLowerCase()\n .replace(/[^a-z0-9]/gu, '-')\n .slice(0, 63)\n .replace(/^-+|-+$/g, '')\n}\n\n/**\n * Detects the CI provider from its environment variables and derives a stable identity from it.\n * The GitHub row reproduces `gh:<repositoryId>:<prNumber>`, the identity `kubb-labs/action` has\n * always registered agents under, so an existing repository keeps reusing its agent.\n */\nexport function detectCi(env: Record<string, string | undefined> = process.env): CiContext | null {\n if (env.GITHUB_ACTIONS) {\n const pullRequest = readGithubPullRequest(env.GITHUB_EVENT_PATH)\n const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? ''\n const branch = env.GITHUB_REF?.startsWith('refs/heads/') ? env.GITHUB_REF.slice('refs/heads/'.length) : undefined\n // A branch run is scoped by its ref, which a pull request number never collides with.\n const scope = pullRequest?.number ?? (branch ? `refs/heads/${branch}` : env.GITHUB_RUN_ID) ?? ''\n const baseBranch = pullRequest?.base?.ref\n\n return {\n id: `gh:${repositoryId}:${scope}`,\n name: `${env.GITHUB_REPOSITORY ?? 'github'}#${pullRequest?.number ?? branch ?? scope}`,\n // The head commit, not the merge commit a pull request run checks out.\n commit: pullRequest?.head?.sha ?? env.GITHUB_SHA,\n base: baseBranch ? { branch: baseBranch, id: `gh:${repositoryId}:refs/heads/${baseBranch}` } : undefined,\n }\n }\n\n if (env.GITLAB_CI) {\n const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? ''\n const baseBranch = env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME\n\n return {\n id: `gl:${env.CI_PROJECT_ID ?? ''}:${scope}`,\n name: `${env.CI_PROJECT_PATH ?? 'gitlab'}#${scope}`,\n commit: env.CI_MERGE_REQUEST_SOURCE_BRANCH_SHA || env.CI_COMMIT_SHA,\n base: baseBranch ? { branch: baseBranch, id: `gl:${env.CI_PROJECT_ID ?? ''}:${gitlabRefSlug(baseBranch)}` } : undefined,\n }\n }\n\n if (env.BITBUCKET_BUILD_NUMBER) {\n const scope = env.BITBUCKET_PR_ID ?? env.BITBUCKET_BRANCH ?? ''\n\n return { id: `bb:${env.BITBUCKET_REPO_UUID ?? ''}:${scope}`, name: `${env.BITBUCKET_REPO_FULL_NAME ?? 'bitbucket'}#${scope}`, commit: env.BITBUCKET_COMMIT }\n }\n\n if (env.CIRCLECI) {\n // Owner-qualified: two projects with the same name under different CircleCI orgs must not\n // collide on one agent, since registering it purges the other project's live sessions.\n const owner = env.CIRCLE_PROJECT_USERNAME ?? ''\n const project = env.CIRCLE_PROJECT_REPONAME ?? 'circleci'\n const scope = env.CIRCLE_PR_NUMBER ?? env.CIRCLE_BRANCH ?? ''\n\n return { id: `circle:${owner}:${project}:${scope}`, name: `${owner ? `${owner}/` : ''}${project}#${scope}`, commit: env.CIRCLE_SHA1 }\n }\n\n return null\n}\n","import { dirname, join } from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport { formatMs, getElapsedMs, read } from '@internals/utils'\nimport { cliReporter, Diagnostics, Hookable, type KubbHooks, logLevel as logLevelMap } from '@kubb/core'\nimport { createSnapshot } from '@kubb/studio'\nimport type { BranchSnapshotChanges, PublishedSnapshot, SnapshotChanges } from '@kubb/studio/protocol'\nimport { pluralize } from '../../ui/text.ts'\nimport { createPlainWriter } from '../../loggers/plainWriter.ts'\nimport setupReporters from '../../loggers/reporters.ts'\nimport { type CiContext, detectCi } from './ci.ts'\nimport { loadConfigs, runStudio, type SnapshotOptions } from './run.ts'\nimport type { command } from '../../commands/studio/snapshot.ts'\nimport type { CommandRunner } from 'gunshi'\n\n/**\n * Walks up from `directory` to the first package.json with a name and a version.\n */\nasync function findPackageJson(directory: string): Promise<{ name: string; version: string }> {\n const packageJson = JSON.parse(await read(join(directory, 'package.json')).catch(() => '{}')) as Partial<{ name: string; version: string }>\n if (packageJson.name && packageJson.version) return { name: packageJson.name, version: packageJson.version }\n\n const parent = dirname(directory)\n if (parent === directory)\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `No package.json with a name and a version found above ${process.cwd()}`,\n help: 'Pass `--name` and `--version`, or run from a package with a package.json.',\n })\n\n return findPackageJson(parent)\n}\n\nfunction resolveCiIdentity(options: SnapshotOptions): CiContext {\n const detected = detectCi()\n // A custom --id drops the detected base, since runs on that branch may use a custom id too.\n const ci = options.id ? { id: options.id, name: detected?.name ?? options.id, commit: detected?.commit } : detected\n\n if (!ci) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.',\n })\n }\n\n // An explicit --base-id may not name a branch, so it labels the comparison itself.\n const base = options.baseId ? { branch: options.baseId, id: options.baseId } : ci.base\n\n return { ...ci, base: base?.id === ci.id ? undefined : base }\n}\n\nfunction absoluteUrl(studioUrl: string, path: string): string {\n return new URL(path, `${studioUrl}/`).toString()\n}\n\ntype SnapshotResult = {\n id: string\n /** Sequence number on the CI agent, when Studio sends one. */\n number?: number\n name: string | null\n version: string | null\n integrity: string | null\n url: string\n snapshotIdUrl: string\n /** Studio page of the snapshot, when Studio sends one. */\n webUrl?: string\n expiresAt: string\n agentUrl: string\n /** What changed since the previous snapshot of this package on this agent. */\n changes?: SnapshotChanges\n /** What differs from the latest snapshot of the base branch, named by `branch`. */\n branchChanges?: BranchSnapshotChanges & { branch: string }\n}\n\nfunction toResult({ studioUrl, snapshot, ci }: { studioUrl: string; snapshot: PublishedSnapshot; ci: CiContext }): SnapshotResult {\n return {\n id: snapshot.id,\n number: snapshot.number,\n name: snapshot.name,\n version: snapshot.version,\n integrity: snapshot.integrity,\n url: absoluteUrl(studioUrl, snapshot.url),\n snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),\n webUrl: snapshot.webUrl ? absoluteUrl(studioUrl, snapshot.webUrl) : undefined,\n expiresAt: snapshot.expiresAt,\n agentUrl: absoluteUrl(studioUrl, `/agents/${snapshot.agent.slug ?? snapshot.agent.id}`),\n changes: snapshot.changes,\n branchChanges: snapshot.branchChanges && ci.base ? { ...snapshot.branchChanges, branch: ci.base.branch } : undefined,\n }\n}\n\n/** How many files differ, `against` what. */\nfunction describeChanges(changes: SnapshotChanges, against: string): string {\n const { added, changed, removed } = changes\n const parts = [\n added.length && `+${pluralize(added.length, 'file')}`,\n changed.length && `~${changed.length} changed`,\n removed.length && `-${removed.length} removed`,\n ].filter(Boolean)\n\n return parts.length ? `${parts.join(' ')} ${against}` : `No changes ${against}`\n}\n\n/** One summary line: how many files changed, and since which run. */\nexport function formatChanges(changes: SnapshotChanges): string {\n if (!changes.base) {\n return 'First snapshot'\n }\n const { number, commit, createdAt } = changes.base\n\n return describeChanges(changes, `vs ${number ? `#${number}` : (commit?.slice(0, 7) ?? createdAt)}`)\n}\n\n/** One summary line: how the snapshot differs from the base branch's latest one. */\nexport function formatBranchChanges(changes: BranchSnapshotChanges & { branch: string }): string {\n if (changes.base) return describeChanges(changes, `vs ${changes.branch}`)\n\n return changes.baseFound ? `No snapshot of ${changes.branch} for this package yet` : `No snapshot of ${changes.branch} to compare with`\n}\n\nfunction printSummary(result: SnapshotResult): void {\n const row = (label: string, value: string) => ` ${styleText('dim', label.padEnd(7))} ${value}`\n\n console.log(\n [\n '',\n ...(result.webUrl ? [row('View', styleText('cyan', result.webUrl))] : []),\n ...(result.changes ? [row('Diff', formatChanges(result.changes))] : []),\n ...(result.branchChanges ? [row('Branch', formatBranchChanges(result.branchChanges))] : []),\n row('Use', `npm i ${result.url}`),\n row('Expires', result.expiresAt.slice(0, 10)),\n ].join('\\n'),\n )\n}\n\n/**\n * Generates the project, packs it, and publishes it to Kubb Studio in one request, under the CI\n * agent the run's identity names.\n */\nexport async function snapshot(options: SnapshotOptions): Promise<void> {\n const token = options.token ?? process.env.KUBB_TOKEN\n if (!token) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'An organization CI API key is required. Pass --token or set KUBB_TOKEN.',\n })\n }\n // A snapshot publishes the first entry.\n const config = (await loadConfigs(options)).configs[0]!\n const ci = resolveCiIdentity(options)\n // package.json is read only for whichever of name/version --name and --version did not supply.\n const { name, version: packageVersion } =\n options.name && options.packageVersion\n ? { name: options.name, version: options.packageVersion }\n : await findPackageJson(process.cwd()).then((found) => ({ name: options.name ?? found.name, version: options.packageVersion ?? found.version }))\n const logLevel = logLevelMap[options.logLevel ?? 'info']\n\n const write = options.json ? (line: string) => console.error(line) : (line: string) => console.log(line)\n const hooks = new Hookable<KubbHooks>()\n // The steps below are the CI log; the run's own per-file output only shows when asked for with --log-level verbose.\n setupReporters(hooks, { logLevel: logLevel > logLevelMap.info ? logLevel : logLevelMap.silent, reporters: [cliReporter], writer: createPlainWriter(write) })\n const step = (message: string) => {\n if (logLevel > logLevelMap.silent) {\n write(message)\n }\n }\n\n hooks.hook('kubb:generation:end', ({ filesCreated = 0, status, hrStart }) => {\n if (status !== 'failed' && hrStart) step(`✓ Generated ${pluralize(filesCreated, 'file')} in ${formatMs(getElapsedMs(hrStart))}`)\n })\n\n try {\n const published = await createSnapshot({\n studioUrl: options.studioUrl,\n apiKey: token,\n config,\n hooks,\n id: ci.id,\n name: ci.name,\n packageName: name,\n version: packageVersion,\n commit: ci.commit,\n baseId: ci.base?.id,\n })\n const result = toResult({ studioUrl: options.studioUrl, snapshot: published, ci })\n\n step(`✓ Packed ${result.name ?? name}@${result.version ?? packageVersion}`)\n step(`✓ Published snapshot ${result.number ? `#${result.number}` : result.id} for ${ci.name}${ci.commit ? `@${ci.commit.slice(0, 7)}` : ''}`)\n\n if (options.json) console.log(JSON.stringify(result))\n else printSummary(result)\n } catch (error) {\n step('✖ Snapshot failed')\n throw error\n }\n}\n\nexport const runner: CommandRunner<{ args: typeof command.args; extensions: {} }> = ({ values }) =>\n runStudio(\n values,\n (options) =>\n snapshot({\n ...options,\n token: values.token,\n id: values.id,\n baseId: values.baseId,\n name: values.name,\n packageVersion: values.packageVersion,\n json: values.json,\n }),\n { json: values.json },\n )\n"],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import "./rolldown-runtime-CRm0XQPb.js";
2
+ import { r as formatPermissionRows } from "./run-BJn0RSW2.js";
3
+ import { _ as isPathInside } from "./utils-CnjEJIdZ.js";
4
+ import { stripVTControlCharacters, styleText } from "node:util";
5
+ import { homedir } from "node:os";
6
+ import path from "node:path";
7
+ //#region src/runners/studio/status.ts
8
+ /** How long a worker has run, such as `2h 14m`, `5m` or `40s`. */
9
+ function formatUptime(ms) {
10
+ const minutes = Math.floor(ms / 6e4);
11
+ if (minutes < 1) return `${Math.max(0, Math.floor(ms / 1e3))}s`;
12
+ if (minutes < 60) return `${minutes}m`;
13
+ return `${Math.floor(minutes / 60)}h ${minutes % 60}m`;
14
+ }
15
+ const tilde = (file) => isPathInside(file, homedir()) ? `~${file.slice(homedir().length)}` : file;
16
+ /**
17
+ * The `kubb studio status` table: one row per topic, each ending with the command that changes it.
18
+ */
19
+ function formatStatus({ studioUrl, credentials, worker, project, logPath, now = Date.now() }) {
20
+ const pairing = (() => {
21
+ if (!credentials) return {
22
+ value: `${styleText("red", "✖")} not paired`,
23
+ command: "kubb studio login"
24
+ };
25
+ const name = `${credentials.agentSlug || credentials.agentId}${credentials.organizationSlug ? ` · org ${credentials.organizationSlug}` : ""}`;
26
+ if (credentials.studioUrl !== studioUrl) return {
27
+ value: `${styleText("yellow", "!")} ${name} · ${credentials.studioUrl}`,
28
+ command: "kubb studio login"
29
+ };
30
+ return {
31
+ value: `${styleText("green", "✓")} ${name}`,
32
+ command: "kubb studio logout"
33
+ };
34
+ })();
35
+ const uptime = worker.startedAt ? ` · up ${formatUptime(now - worker.startedAt)}` : "";
36
+ const workerRow = worker.running ? {
37
+ value: `${styleText("green", "●")} ${worker.state} · PID ${worker.pid}${uptime}`,
38
+ command: "kubb studio stop"
39
+ } : {
40
+ value: `${styleText("dim", "○")} ${worker.state}`,
41
+ command: "kubb studio start"
42
+ };
43
+ const remembered = credentials?.projects?.[project];
44
+ const permissions = remembered ? formatPermissionRows(remembered) : [styleText("dim", "not chosen yet")];
45
+ const rows = [
46
+ {
47
+ label: "Pairing",
48
+ ...pairing
49
+ },
50
+ {
51
+ label: "Worker",
52
+ ...workerRow
53
+ },
54
+ {
55
+ label: "Project",
56
+ value: `${path.basename(project)} · ${tilde(project)}`
57
+ },
58
+ ...permissions.map((value, index) => ({
59
+ label: index === 0 ? "Permissions" : "",
60
+ value,
61
+ command: !remembered && index === 0 ? "kubb studio connect" : void 0
62
+ })),
63
+ {
64
+ label: "Logs",
65
+ value: tilde(logPath)
66
+ }
67
+ ];
68
+ const width = Math.max(...rows.filter((row) => row.command).map((row) => stripVTControlCharacters(row.value).length));
69
+ return rows.map(({ label, value, command }) => {
70
+ const line = ` ${label.padEnd(11)} ${value}`;
71
+ return command ? `${line}${" ".repeat(width - stripVTControlCharacters(value).length + 3)}${styleText("dim", command)}` : line;
72
+ });
73
+ }
74
+ //#endregion
75
+ export { formatStatus };
76
+
77
+ //# sourceMappingURL=status-DHPeR3bq.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-DHPeR3bq.js","names":[],"sources":["../src/runners/studio/status.ts"],"sourcesContent":["import { homedir } from 'node:os'\nimport path from 'node:path'\nimport { stripVTControlCharacters, styleText } from 'node:util'\nimport { isPathInside } from '@internals/utils'\nimport type { Credentials } from './credentials.ts'\nimport { formatPermissionRows, type WorkerState } from './run.ts'\n\ntype StatusInput = {\n studioUrl: string\n credentials: Credentials | null\n worker: { running: boolean; state: WorkerState; pid?: number; startedAt?: number }\n project: string\n logPath: string\n now?: number\n}\n\n/** How long a worker has run, such as `2h 14m`, `5m` or `40s`. */\nexport function formatUptime(ms: number): string {\n const minutes = Math.floor(ms / 60_000)\n if (minutes < 1) return `${Math.max(0, Math.floor(ms / 1000))}s`\n if (minutes < 60) return `${minutes}m`\n\n return `${Math.floor(minutes / 60)}h ${minutes % 60}m`\n}\n\nconst tilde = (file: string) => (isPathInside(file, homedir()) ? `~${file.slice(homedir().length)}` : file)\n\n/**\n * The `kubb studio status` table: one row per topic, each ending with the command that changes it.\n */\nexport function formatStatus({ studioUrl, credentials, worker, project, logPath, now = Date.now() }: StatusInput): Array<string> {\n const pairing = (() => {\n if (!credentials) return { value: `${styleText('red', '✖')} not paired`, command: 'kubb studio login' }\n const name = `${credentials.agentSlug || credentials.agentId}${credentials.organizationSlug ? ` · org ${credentials.organizationSlug}` : ''}`\n if (credentials.studioUrl !== studioUrl) return { value: `${styleText('yellow', '!')} ${name} · ${credentials.studioUrl}`, command: 'kubb studio login' }\n return { value: `${styleText('green', '✓')} ${name}`, command: 'kubb studio logout' }\n })()\n const uptime = worker.startedAt ? ` · up ${formatUptime(now - worker.startedAt)}` : ''\n const workerRow = worker.running\n ? { value: `${styleText('green', '●')} ${worker.state} · PID ${worker.pid}${uptime}`, command: 'kubb studio stop' }\n : { value: `${styleText('dim', '○')} ${worker.state}`, command: 'kubb studio start' }\n const remembered = credentials?.projects?.[project]\n const permissions = remembered ? formatPermissionRows(remembered) : [styleText('dim', 'not chosen yet')]\n\n const rows: Array<{ label: string; value: string; command?: string }> = [\n { label: 'Pairing', ...pairing },\n { label: 'Worker', ...workerRow },\n { label: 'Project', value: `${path.basename(project)} · ${tilde(project)}` },\n ...permissions.map((value, index) => ({\n label: index === 0 ? 'Permissions' : '',\n value,\n command: !remembered && index === 0 ? 'kubb studio connect' : undefined,\n })),\n { label: 'Logs', value: tilde(logPath) },\n ]\n const width = Math.max(...rows.filter((row) => row.command).map((row) => stripVTControlCharacters(row.value).length))\n\n return rows.map(({ label, value, command }) => {\n const line = ` ${label.padEnd(11)} ${value}`\n return command ? `${line}${' '.repeat(width - stripVTControlCharacters(value).length + 3)}${styleText('dim', command)}` : line\n })\n}\n"],"mappings":";;;;;;;;AAiBA,SAAgB,aAAa,IAAoB;CAC/C,MAAM,UAAU,KAAK,MAAM,KAAK,GAAM;CACtC,IAAI,UAAU,GAAG,OAAO,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,GAAI,CAAC,EAAE;CAC9D,IAAI,UAAU,IAAI,OAAO,GAAG,QAAQ;CAEpC,OAAO,GAAG,KAAK,MAAM,UAAU,EAAE,EAAE,IAAI,UAAU,GAAG;AACtD;AAEA,MAAM,SAAS,SAAkB,aAAa,MAAM,QAAQ,CAAC,IAAI,IAAI,KAAK,MAAM,QAAQ,CAAC,CAAC,MAAM,MAAM;;;;AAKtG,SAAgB,aAAa,EAAE,WAAW,aAAa,QAAQ,SAAS,SAAS,MAAM,KAAK,IAAI,KAAiC;CAC/H,MAAM,iBAAiB;EACrB,IAAI,CAAC,aAAa,OAAO;GAAE,OAAO,GAAG,UAAU,OAAO,GAAG,EAAE;GAAc,SAAS;EAAoB;EACtG,MAAM,OAAO,GAAG,YAAY,aAAa,YAAY,UAAU,YAAY,mBAAmB,UAAU,YAAY,qBAAqB;EACzI,IAAI,YAAY,cAAc,WAAW,OAAO;GAAE,OAAO,GAAG,UAAU,UAAU,GAAG,EAAE,GAAG,KAAK,KAAK,YAAY;GAAa,SAAS;EAAoB;EACxJ,OAAO;GAAE,OAAO,GAAG,UAAU,SAAS,GAAG,EAAE,GAAG;GAAQ,SAAS;EAAqB;CACtF,EAAA,CAAG;CACH,MAAM,SAAS,OAAO,YAAY,SAAS,aAAa,MAAM,OAAO,SAAS,MAAM;CACpF,MAAM,YAAY,OAAO,UACrB;EAAE,OAAO,GAAG,UAAU,SAAS,GAAG,EAAE,GAAG,OAAO,MAAM,SAAS,OAAO,MAAM;EAAU,SAAS;CAAmB,IAChH;EAAE,OAAO,GAAG,UAAU,OAAO,GAAG,EAAE,GAAG,OAAO;EAAS,SAAS;CAAoB;CACtF,MAAM,aAAa,aAAa,WAAW;CAC3C,MAAM,cAAc,aAAa,qBAAqB,UAAU,IAAI,CAAC,UAAU,OAAO,gBAAgB,CAAC;CAEvG,MAAM,OAAkE;EACtE;GAAE,OAAO;GAAW,GAAG;EAAQ;EAC/B;GAAE,OAAO;GAAU,GAAG;EAAU;EAChC;GAAE,OAAO;GAAW,OAAO,GAAG,KAAK,SAAS,OAAO,EAAE,KAAK,MAAM,OAAO;EAAI;EAC3E,GAAG,YAAY,KAAK,OAAO,WAAW;GACpC,OAAO,UAAU,IAAI,gBAAgB;GACrC;GACA,SAAS,CAAC,cAAc,UAAU,IAAI,wBAAwB,KAAA;EAChE,EAAE;EACF;GAAE,OAAO;GAAQ,OAAO,MAAM,OAAO;EAAE;CACzC;CACA,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,QAAQ,QAAQ,IAAI,OAAO,CAAC,CAAC,KAAK,QAAQ,yBAAyB,IAAI,KAAK,CAAC,CAAC,MAAM,CAAC;CAEpH,OAAO,KAAK,KAAK,EAAE,OAAO,OAAO,cAAc;EAC7C,MAAM,OAAO,KAAK,MAAM,OAAO,EAAE,EAAE,IAAI;EACvC,OAAO,UAAU,GAAG,OAAO,IAAI,OAAO,QAAQ,yBAAyB,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,UAAU,OAAO,OAAO,MAAM;CAC5H,CAAC;AACH"}
@@ -0,0 +1,78 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
2
+ const require_utils = require("./utils-DpKrXR2t.cjs");
3
+ const require_run = require("./run-BszyZwY3.cjs");
4
+ let node_util = require("node:util");
5
+ let node_os = require("node:os");
6
+ let node_path = require("node:path");
7
+ node_path = require_rolldown_runtime.__toESM(node_path, 1);
8
+ //#region src/runners/studio/status.ts
9
+ /** How long a worker has run, such as `2h 14m`, `5m` or `40s`. */
10
+ function formatUptime(ms) {
11
+ const minutes = Math.floor(ms / 6e4);
12
+ if (minutes < 1) return `${Math.max(0, Math.floor(ms / 1e3))}s`;
13
+ if (minutes < 60) return `${minutes}m`;
14
+ return `${Math.floor(minutes / 60)}h ${minutes % 60}m`;
15
+ }
16
+ const tilde = (file) => require_utils.isPathInside(file, (0, node_os.homedir)()) ? `~${file.slice((0, node_os.homedir)().length)}` : file;
17
+ /**
18
+ * The `kubb studio status` table: one row per topic, each ending with the command that changes it.
19
+ */
20
+ function formatStatus({ studioUrl, credentials, worker, project, logPath, now = Date.now() }) {
21
+ const pairing = (() => {
22
+ if (!credentials) return {
23
+ value: `${(0, node_util.styleText)("red", "✖")} not paired`,
24
+ command: "kubb studio login"
25
+ };
26
+ const name = `${credentials.agentSlug || credentials.agentId}${credentials.organizationSlug ? ` · org ${credentials.organizationSlug}` : ""}`;
27
+ if (credentials.studioUrl !== studioUrl) return {
28
+ value: `${(0, node_util.styleText)("yellow", "!")} ${name} · ${credentials.studioUrl}`,
29
+ command: "kubb studio login"
30
+ };
31
+ return {
32
+ value: `${(0, node_util.styleText)("green", "✓")} ${name}`,
33
+ command: "kubb studio logout"
34
+ };
35
+ })();
36
+ const uptime = worker.startedAt ? ` · up ${formatUptime(now - worker.startedAt)}` : "";
37
+ const workerRow = worker.running ? {
38
+ value: `${(0, node_util.styleText)("green", "●")} ${worker.state} · PID ${worker.pid}${uptime}`,
39
+ command: "kubb studio stop"
40
+ } : {
41
+ value: `${(0, node_util.styleText)("dim", "○")} ${worker.state}`,
42
+ command: "kubb studio start"
43
+ };
44
+ const remembered = credentials?.projects?.[project];
45
+ const permissions = remembered ? require_run.formatPermissionRows(remembered) : [(0, node_util.styleText)("dim", "not chosen yet")];
46
+ const rows = [
47
+ {
48
+ label: "Pairing",
49
+ ...pairing
50
+ },
51
+ {
52
+ label: "Worker",
53
+ ...workerRow
54
+ },
55
+ {
56
+ label: "Project",
57
+ value: `${node_path.default.basename(project)} · ${tilde(project)}`
58
+ },
59
+ ...permissions.map((value, index) => ({
60
+ label: index === 0 ? "Permissions" : "",
61
+ value,
62
+ command: !remembered && index === 0 ? "kubb studio connect" : void 0
63
+ })),
64
+ {
65
+ label: "Logs",
66
+ value: tilde(logPath)
67
+ }
68
+ ];
69
+ const width = Math.max(...rows.filter((row) => row.command).map((row) => (0, node_util.stripVTControlCharacters)(row.value).length));
70
+ return rows.map(({ label, value, command }) => {
71
+ const line = ` ${label.padEnd(11)} ${value}`;
72
+ return command ? `${line}${" ".repeat(width - (0, node_util.stripVTControlCharacters)(value).length + 3)}${(0, node_util.styleText)("dim", command)}` : line;
73
+ });
74
+ }
75
+ //#endregion
76
+ exports.formatStatus = formatStatus;
77
+
78
+ //# sourceMappingURL=status-dpSvxxtN.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-dpSvxxtN.cjs","names":["isPathInside","homedir","styleText","formatPermissionRows","path","stripVTControlCharacters"],"sources":["../src/runners/studio/status.ts"],"sourcesContent":["import { homedir } from 'node:os'\nimport path from 'node:path'\nimport { stripVTControlCharacters, styleText } from 'node:util'\nimport { isPathInside } from '@internals/utils'\nimport type { Credentials } from './credentials.ts'\nimport { formatPermissionRows, type WorkerState } from './run.ts'\n\ntype StatusInput = {\n studioUrl: string\n credentials: Credentials | null\n worker: { running: boolean; state: WorkerState; pid?: number; startedAt?: number }\n project: string\n logPath: string\n now?: number\n}\n\n/** How long a worker has run, such as `2h 14m`, `5m` or `40s`. */\nexport function formatUptime(ms: number): string {\n const minutes = Math.floor(ms / 60_000)\n if (minutes < 1) return `${Math.max(0, Math.floor(ms / 1000))}s`\n if (minutes < 60) return `${minutes}m`\n\n return `${Math.floor(minutes / 60)}h ${minutes % 60}m`\n}\n\nconst tilde = (file: string) => (isPathInside(file, homedir()) ? `~${file.slice(homedir().length)}` : file)\n\n/**\n * The `kubb studio status` table: one row per topic, each ending with the command that changes it.\n */\nexport function formatStatus({ studioUrl, credentials, worker, project, logPath, now = Date.now() }: StatusInput): Array<string> {\n const pairing = (() => {\n if (!credentials) return { value: `${styleText('red', '✖')} not paired`, command: 'kubb studio login' }\n const name = `${credentials.agentSlug || credentials.agentId}${credentials.organizationSlug ? ` · org ${credentials.organizationSlug}` : ''}`\n if (credentials.studioUrl !== studioUrl) return { value: `${styleText('yellow', '!')} ${name} · ${credentials.studioUrl}`, command: 'kubb studio login' }\n return { value: `${styleText('green', '✓')} ${name}`, command: 'kubb studio logout' }\n })()\n const uptime = worker.startedAt ? ` · up ${formatUptime(now - worker.startedAt)}` : ''\n const workerRow = worker.running\n ? { value: `${styleText('green', '●')} ${worker.state} · PID ${worker.pid}${uptime}`, command: 'kubb studio stop' }\n : { value: `${styleText('dim', '○')} ${worker.state}`, command: 'kubb studio start' }\n const remembered = credentials?.projects?.[project]\n const permissions = remembered ? formatPermissionRows(remembered) : [styleText('dim', 'not chosen yet')]\n\n const rows: Array<{ label: string; value: string; command?: string }> = [\n { label: 'Pairing', ...pairing },\n { label: 'Worker', ...workerRow },\n { label: 'Project', value: `${path.basename(project)} · ${tilde(project)}` },\n ...permissions.map((value, index) => ({\n label: index === 0 ? 'Permissions' : '',\n value,\n command: !remembered && index === 0 ? 'kubb studio connect' : undefined,\n })),\n { label: 'Logs', value: tilde(logPath) },\n ]\n const width = Math.max(...rows.filter((row) => row.command).map((row) => stripVTControlCharacters(row.value).length))\n\n return rows.map(({ label, value, command }) => {\n const line = ` ${label.padEnd(11)} ${value}`\n return command ? `${line}${' '.repeat(width - stripVTControlCharacters(value).length + 3)}${styleText('dim', command)}` : line\n })\n}\n"],"mappings":";;;;;;;;;AAiBA,SAAgB,aAAa,IAAoB;CAC/C,MAAM,UAAU,KAAK,MAAM,KAAK,GAAM;CACtC,IAAI,UAAU,GAAG,OAAO,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,GAAI,CAAC,EAAE;CAC9D,IAAI,UAAU,IAAI,OAAO,GAAG,QAAQ;CAEpC,OAAO,GAAG,KAAK,MAAM,UAAU,EAAE,EAAE,IAAI,UAAU,GAAG;AACtD;AAEA,MAAM,SAAS,SAAkBA,cAAAA,aAAa,OAAA,GAAMC,QAAAA,QAAAA,CAAQ,CAAC,IAAI,IAAI,KAAK,OAAA,GAAMA,QAAAA,QAAAA,CAAQ,CAAC,CAAC,MAAM,MAAM;;;;AAKtG,SAAgB,aAAa,EAAE,WAAW,aAAa,QAAQ,SAAS,SAAS,MAAM,KAAK,IAAI,KAAiC;CAC/H,MAAM,iBAAiB;EACrB,IAAI,CAAC,aAAa,OAAO;GAAE,OAAO,IAAA,GAAGC,UAAAA,UAAAA,CAAU,OAAO,GAAG,EAAE;GAAc,SAAS;EAAoB;EACtG,MAAM,OAAO,GAAG,YAAY,aAAa,YAAY,UAAU,YAAY,mBAAmB,UAAU,YAAY,qBAAqB;EACzI,IAAI,YAAY,cAAc,WAAW,OAAO;GAAE,OAAO,IAAA,GAAGA,UAAAA,UAAAA,CAAU,UAAU,GAAG,EAAE,GAAG,KAAK,KAAK,YAAY;GAAa,SAAS;EAAoB;EACxJ,OAAO;GAAE,OAAO,IAAA,GAAGA,UAAAA,UAAAA,CAAU,SAAS,GAAG,EAAE,GAAG;GAAQ,SAAS;EAAqB;CACtF,EAAA,CAAG;CACH,MAAM,SAAS,OAAO,YAAY,SAAS,aAAa,MAAM,OAAO,SAAS,MAAM;CACpF,MAAM,YAAY,OAAO,UACrB;EAAE,OAAO,IAAA,GAAGA,UAAAA,UAAAA,CAAU,SAAS,GAAG,EAAE,GAAG,OAAO,MAAM,SAAS,OAAO,MAAM;EAAU,SAAS;CAAmB,IAChH;EAAE,OAAO,IAAA,GAAGA,UAAAA,UAAAA,CAAU,OAAO,GAAG,EAAE,GAAG,OAAO;EAAS,SAAS;CAAoB;CACtF,MAAM,aAAa,aAAa,WAAW;CAC3C,MAAM,cAAc,aAAaC,YAAAA,qBAAqB,UAAU,IAAI,EAAA,GAACD,UAAAA,UAAAA,CAAU,OAAO,gBAAgB,CAAC;CAEvG,MAAM,OAAkE;EACtE;GAAE,OAAO;GAAW,GAAG;EAAQ;EAC/B;GAAE,OAAO;GAAU,GAAG;EAAU;EAChC;GAAE,OAAO;GAAW,OAAO,GAAGE,UAAAA,QAAK,SAAS,OAAO,EAAE,KAAK,MAAM,OAAO;EAAI;EAC3E,GAAG,YAAY,KAAK,OAAO,WAAW;GACpC,OAAO,UAAU,IAAI,gBAAgB;GACrC;GACA,SAAS,CAAC,cAAc,UAAU,IAAI,wBAAwB,KAAA;EAChE,EAAE;EACF;GAAE,OAAO;GAAQ,OAAO,MAAM,OAAO;EAAE;CACzC;CACA,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,QAAQ,QAAQ,IAAI,OAAO,CAAC,CAAC,KAAK,SAAA,GAAQC,UAAAA,yBAAAA,CAAyB,IAAI,KAAK,CAAC,CAAC,MAAM,CAAC;CAEpH,OAAO,KAAK,KAAK,EAAE,OAAO,OAAO,cAAc;EAC7C,MAAM,OAAO,KAAK,MAAM,OAAO,EAAE,EAAE,IAAI;EACvC,OAAO,UAAU,GAAG,OAAO,IAAI,OAAO,SAAA,GAAQA,UAAAA,yBAAAA,CAAyB,KAAK,CAAC,CAAC,SAAS,CAAC,KAAA,GAAIH,UAAAA,UAAAA,CAAU,OAAO,OAAO,MAAM;CAC5H,CAAC;AACH"}
@@ -1,6 +1,6 @@
1
1
  import "./rolldown-runtime-CRm0XQPb.js";
2
- import { t as connect } from "./run-YHth5Afz.js";
3
- import { r as serveWorker, t as getWorkerLogPath } from "./background-CQPyCSn0.js";
2
+ import { t as connect } from "./run-BJn0RSW2.js";
3
+ import { r as serveWorker, t as getWorkerLogPath } from "./background-BBpH2jmk.js";
4
4
  import { format } from "node:util";
5
5
  import { appendFileSync, statSync, writeFileSync } from "node:fs";
6
6
  //#region src/runners/studio/worker.ts
@@ -0,0 +1,46 @@
1
+ require("./rolldown-runtime-CPE0t6oh.cjs");
2
+ const require_Telemetry = require("./Telemetry-Be3hIy6_.cjs");
3
+ const require_text = require("./text-CknhKMvM.cjs");
4
+ let node_util = require("node:util");
5
+ //#region src/ui/summary.ts
6
+ /**
7
+ * Finishes a command with its outcome and duration before the labeled details.
8
+ * A command with prompts closes its existing block; validation writes a standalone summary.
9
+ */
10
+ function logCommandSummary({ title, status, hrStart, lines, block = false }) {
11
+ const summary = [
12
+ `${(0, node_util.styleText)({
13
+ success: "green",
14
+ failed: "red",
15
+ warning: "yellow",
16
+ planned: "cyan",
17
+ canceled: "dim"
18
+ }[status], `${{
19
+ success: "✓",
20
+ failed: "✗",
21
+ warning: "!",
22
+ planned: "◇",
23
+ canceled: "○"
24
+ }[status]} ${title}`)} ${(0, node_util.styleText)("dim", require_Telemetry.formatMs(require_Telemetry.getElapsedMs(hrStart)))}`,
25
+ "",
26
+ ...lines
27
+ ].join("\n");
28
+ if (block) {
29
+ require_text.logOutro(summary);
30
+ return;
31
+ }
32
+ if (status === "failed") {
33
+ console.error(summary);
34
+ return;
35
+ }
36
+ console.log(summary);
37
+ }
38
+ //#endregion
39
+ Object.defineProperty(exports, "logCommandSummary", {
40
+ enumerable: true,
41
+ get: function() {
42
+ return logCommandSummary;
43
+ }
44
+ });
45
+
46
+ //# sourceMappingURL=summary-6-rotl2L.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary-6-rotl2L.cjs","names":["styleText","formatMs","getElapsedMs"],"sources":["../src/ui/summary.ts"],"sourcesContent":["import { styleText } from 'node:util'\nimport { formatMs, getElapsedMs } from '@internals/utils'\nimport { logOutro } from './intro.ts'\n\n/**\n * Finishes a command with its outcome and duration before the labeled details.\n * A command with prompts closes its existing block; validation writes a standalone summary.\n */\nexport function logCommandSummary({\n title,\n status,\n hrStart,\n lines,\n block = false,\n}: {\n title: string\n status: 'success' | 'failed' | 'warning' | 'planned' | 'canceled'\n hrStart: [number, number]\n lines: ReadonlyArray<string>\n block?: boolean\n}): void {\n const colors = { success: 'green', failed: 'red', warning: 'yellow', planned: 'cyan', canceled: 'dim' } as const\n const symbols = { success: '✓', failed: '✗', warning: '!', planned: '◇', canceled: '○' } as const\n const summary = [`${styleText(colors[status], `${symbols[status]} ${title}`)} ${styleText('dim', formatMs(getElapsedMs(hrStart)))}`, '', ...lines].join('\\n')\n if (block) {\n logOutro(summary)\n return\n }\n if (status === 'failed') {\n console.error(summary)\n return\n }\n console.log(summary)\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,kBAAkB,EAChC,OACA,QACA,SACA,OACA,QAAQ,SAOD;CAGP,MAAM,UAAU;EAAC,IAAA,GAAGA,UAAAA,UAAAA,CAAU;GAFb,SAAS;GAAS,QAAQ;GAAO,SAAS;GAAU,SAAS;GAAQ,UAAU;EAE7D,EAAE,SAAS,GAAG;GAD/B,SAAS;GAAK,QAAQ;GAAK,SAAS;GAAK,SAAS;GAAK,UAAU;EAC5B,EAAE,QAAQ,GAAG,OAAO,EAAE,KAAA,GAAIA,UAAAA,UAAAA,CAAU,OAAOC,kBAAAA,SAASC,kBAAAA,aAAa,OAAO,CAAC,CAAC;EAAK;EAAI,GAAG;CAAK,CAAC,CAAC,KAAK,IAAI;CAC7J,IAAI,OAAO;EACT,aAAA,SAAS,OAAO;EAChB;CACF;CACA,IAAI,WAAW,UAAU;EACvB,QAAQ,MAAM,OAAO;EACrB;CACF;CACA,QAAQ,IAAI,OAAO;AACrB"}
@@ -0,0 +1,41 @@
1
+ import "./rolldown-runtime-CRm0XQPb.js";
2
+ import { a as getElapsedMs, i as formatMs } from "./Telemetry-CfJAUDnh.js";
3
+ import { a as logOutro } from "./text-CMP4M19Z.js";
4
+ import { styleText } from "node:util";
5
+ //#region src/ui/summary.ts
6
+ /**
7
+ * Finishes a command with its outcome and duration before the labeled details.
8
+ * A command with prompts closes its existing block; validation writes a standalone summary.
9
+ */
10
+ function logCommandSummary({ title, status, hrStart, lines, block = false }) {
11
+ const summary = [
12
+ `${styleText({
13
+ success: "green",
14
+ failed: "red",
15
+ warning: "yellow",
16
+ planned: "cyan",
17
+ canceled: "dim"
18
+ }[status], `${{
19
+ success: "✓",
20
+ failed: "✗",
21
+ warning: "!",
22
+ planned: "◇",
23
+ canceled: "○"
24
+ }[status]} ${title}`)} ${styleText("dim", formatMs(getElapsedMs(hrStart)))}`,
25
+ "",
26
+ ...lines
27
+ ].join("\n");
28
+ if (block) {
29
+ logOutro(summary);
30
+ return;
31
+ }
32
+ if (status === "failed") {
33
+ console.error(summary);
34
+ return;
35
+ }
36
+ console.log(summary);
37
+ }
38
+ //#endregion
39
+ export { logCommandSummary as t };
40
+
41
+ //# sourceMappingURL=summary-DkSLti6f.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary-DkSLti6f.js","names":[],"sources":["../src/ui/summary.ts"],"sourcesContent":["import { styleText } from 'node:util'\nimport { formatMs, getElapsedMs } from '@internals/utils'\nimport { logOutro } from './intro.ts'\n\n/**\n * Finishes a command with its outcome and duration before the labeled details.\n * A command with prompts closes its existing block; validation writes a standalone summary.\n */\nexport function logCommandSummary({\n title,\n status,\n hrStart,\n lines,\n block = false,\n}: {\n title: string\n status: 'success' | 'failed' | 'warning' | 'planned' | 'canceled'\n hrStart: [number, number]\n lines: ReadonlyArray<string>\n block?: boolean\n}): void {\n const colors = { success: 'green', failed: 'red', warning: 'yellow', planned: 'cyan', canceled: 'dim' } as const\n const symbols = { success: '✓', failed: '✗', warning: '!', planned: '◇', canceled: '○' } as const\n const summary = [`${styleText(colors[status], `${symbols[status]} ${title}`)} ${styleText('dim', formatMs(getElapsedMs(hrStart)))}`, '', ...lines].join('\\n')\n if (block) {\n logOutro(summary)\n return\n }\n if (status === 'failed') {\n console.error(summary)\n return\n }\n console.log(summary)\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,kBAAkB,EAChC,OACA,QACA,SACA,OACA,QAAQ,SAOD;CAGP,MAAM,UAAU;EAAC,GAAG,UAAU;GAFb,SAAS;GAAS,QAAQ;GAAO,SAAS;GAAU,SAAS;GAAQ,UAAU;EAE7D,EAAE,SAAS,GAAG;GAD/B,SAAS;GAAK,QAAQ;GAAK,SAAS;GAAK,SAAS;GAAK,UAAU;EAC5B,EAAE,QAAQ,GAAG,OAAO,EAAE,IAAI,UAAU,OAAO,SAAS,aAAa,OAAO,CAAC,CAAC;EAAK;EAAI,GAAG;CAAK,CAAC,CAAC,KAAK,IAAI;CAC7J,IAAI,OAAO;EACT,SAAS,OAAO;EAChB;CACF;CACA,IAAI,WAAW,UAAU;EACvB,QAAQ,MAAM,OAAO;EACrB;CACF;CACA,QAAQ,IAAI,OAAO;AACrB"}