@coderook/cli 0.34.2 → 0.34.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.
@@ -25,12 +25,10 @@ exports.commandHooks = commandHooks;
25
25
  const node_process_1 = __importDefault(require("node:process"));
26
26
  const promises_1 = require("node:readline/promises");
27
27
  const api_js_1 = require("./api.js");
28
+ const config_js_1 = require("./config.js");
28
29
  const project_commands_js_1 = require("./project_commands.js");
29
- const dim = (value) => `${value}`;
30
- const bold = (value) => `${value}`;
31
- const red = (value) => `${value}`;
32
- const green = (value) => `${value}`;
33
- const accent = (value) => `${value}`;
30
+ const tracks_js_1 = require("../../cbx/src/core/tracks.js");
31
+ const colour_js_1 = require("./colour.js");
34
32
  function bytes(value) {
35
33
  if (value >= 1024 ** 3)
36
34
  return `${(value / 1024 ** 3).toFixed(2)} GB`;
@@ -47,7 +45,7 @@ async function commandIssues(parsed) {
47
45
  return 1;
48
46
  const title = parsed.flags.get("new");
49
47
  if (title === true) {
50
- console.error(red('What is it about? Try: --new "Crash on export"'));
48
+ console.error((0, colour_js_1.red)('What is it about? Try: --new "Crash on export"'));
51
49
  return 1;
52
50
  }
53
51
  if (typeof title === "string" && title.trim()) {
@@ -77,7 +75,7 @@ async function commandIssues(parsed) {
77
75
  const all = await (0, api_js_1.versions)(project.id);
78
76
  const found = all.find((one) => String(one.sequence) === wanted);
79
77
  if (!found) {
80
- console.error(red(`${project.name} has no version ${about.trim()}.`));
78
+ console.error((0, colour_js_1.red)(`${project.name} has no version ${about.trim()}.`));
81
79
  return 1;
82
80
  }
83
81
  versionId = found.id;
@@ -88,24 +86,24 @@ async function commandIssues(parsed) {
88
86
  labels,
89
87
  ...(versionId ? { versionId } : {}),
90
88
  });
91
- console.log(green(`Opened issue #${created.number} on ${project.name}.`));
89
+ console.log((0, colour_js_1.green)(`Opened issue #${created.number} on ${project.name}.`));
92
90
  if (labels.length)
93
- console.log(dim(` labelled ${labels.join(", ")}`));
91
+ console.log((0, colour_js_1.dim)(` labelled ${labels.join(", ")}`));
94
92
  if (versionId)
95
- console.log(dim(` about v${about}`));
93
+ console.log((0, colour_js_1.dim)(` about v${about}`));
96
94
  return 0;
97
95
  }
98
96
  const found = await (0, api_js_1.issues)(project.id);
99
97
  if (!found.issues.length) {
100
- console.log(dim("No issues on this project."));
98
+ console.log((0, colour_js_1.dim)("No issues on this project."));
101
99
  return 0;
102
100
  }
103
- console.log(`${bold(project.name)} ${dim(`${found.openCount} open, ${found.closedCount} closed`)}`);
101
+ console.log(`${(0, colour_js_1.bold)(project.name)} ${(0, colour_js_1.dim)(`${found.openCount} open, ${found.closedCount} closed`)}`);
104
102
  for (const issue of found.issues) {
105
- const state = issue.state === "open" ? accent("open") : dim("closed");
106
- console.log(` ${dim(`#${issue.number}`).padEnd(14)} ${state.padEnd(16)} ${issue.title}`);
103
+ const state = issue.state === "open" ? (0, colour_js_1.accent)("open") : (0, colour_js_1.dim)("closed");
104
+ console.log(` ${(0, colour_js_1.dim)(`#${issue.number}`).padEnd(14)} ${state.padEnd(16)} ${issue.title}`);
107
105
  if (issue.labels.length)
108
- console.log(` ${dim(issue.labels.join(", "))}`);
106
+ console.log(` ${(0, colour_js_1.dim)(issue.labels.join(", "))}`);
109
107
  }
110
108
  return 0;
111
109
  }
@@ -123,7 +121,7 @@ async function commandIssues(parsed) {
123
121
  async function commandRelease(parsed) {
124
122
  const name = parsed.positional[0];
125
123
  if (!name) {
126
- console.error(red("Name the release: cbx release v1.0"));
124
+ console.error((0, colour_js_1.red)("Name the release: cbx release v1.0"));
127
125
  return 1;
128
126
  }
129
127
  const project = await (0, project_commands_js_1.resolveProject)(parsed.positional[1]);
@@ -131,21 +129,35 @@ async function commandRelease(parsed) {
131
129
  return 1;
132
130
  const all = await (0, api_js_1.versions)(project.id);
133
131
  if (!all.length) {
134
- console.error(red("This project has no versions to release."));
132
+ console.error((0, colour_js_1.red)("This project has no versions to release."));
135
133
  return 1;
136
134
  }
137
135
  /*
138
- The newest version unless one is named. A release usually means "what I
139
- have just finished", and asking for the number every time would make the
140
- common case the awkward one.
136
+ The head of the line unless a version is named: a release usually means
137
+ "what I have just finished", and asking for the number every time would
138
+ make the common case the awkward one.
139
+
140
+ The head, not the newest number. They differ after `cbx undo`: the line
141
+ goes back to v2 and v3 stays in the history, passed over. Taking the
142
+ newest released exactly the save that was just undone. The line is this
143
+ folder's own when it is linked to this project, otherwise the project's
144
+ default; the newest number is only the answer for a project with no lines.
141
145
  */
142
146
  const wanted = parsed.flags.get("version");
143
- const target = typeof wanted === "string"
144
- ? all.find((version) => String(version.sequence) === wanted.replace(/^v/i, ""))
145
- /* The newest by number rather than by position in the list. */
146
- : all.reduce((newest, one) => (one.sequence > newest.sequence ? one : newest));
147
+ let target;
148
+ if (typeof wanted === "string") {
149
+ target = all.find((version) => String(version.sequence) === wanted.replace(/^v/i, ""));
150
+ }
151
+ else {
152
+ const link = await (0, config_js_1.readLink)(node_process_1.default.cwd());
153
+ const lineName = (link?.repositoryId === project.id ? link.track : undefined) ?? project.defaultBranch ?? "main";
154
+ const line = (await new tracks_js_1.Tracks(config_js_1.credentials).list(project.id)).find((candidate) => candidate.kind === "line" && candidate.name === lineName);
155
+ target =
156
+ (line?.headVersionId && all.find((version) => version.id === line.headVersionId)) ||
157
+ all.reduce((newest, one) => (one.sequence > newest.sequence ? one : newest));
158
+ }
147
159
  if (!target) {
148
- console.error(red(`This project has no version ${String(wanted)}.`));
160
+ console.error((0, colour_js_1.red)(`This project has no version ${String(wanted)}.`));
149
161
  return 1;
150
162
  }
151
163
  const notes = parsed.flags.get("notes");
@@ -153,11 +165,11 @@ async function commandRelease(parsed) {
153
165
  await (0, api_js_1.markRelease)(project.id, target.id, name, typeof notes === "string" ? notes : null);
154
166
  }
155
167
  catch (error) {
156
- console.error(red(error instanceof Error ? error.message : String(error)));
168
+ console.error((0, colour_js_1.red)(error instanceof Error ? error.message : String(error)));
157
169
  return 1;
158
170
  }
159
- console.log(`${green("Released")} ${bold(name)} ${dim("at")} v${target.sequence}` +
160
- `${dim(" — ")}${target.message.split("\n")[0].slice(0, 48)}`);
171
+ console.log(`${(0, colour_js_1.green)("Released")} ${(0, colour_js_1.bold)(name)} ${(0, colour_js_1.dim)("at")} v${target.sequence}` +
172
+ `${(0, colour_js_1.dim)(" — ")}${target.message.split("\n")[0].slice(0, 48)}`);
161
173
  return 0;
162
174
  }
163
175
  async function commandReleases(parsed) {
@@ -166,55 +178,92 @@ async function commandReleases(parsed) {
166
178
  return 1;
167
179
  const published = await (0, api_js_1.releases)(project.id);
168
180
  if (!published.length) {
169
- console.log(dim("Nothing has been released from this project."));
181
+ console.log((0, colour_js_1.dim)("Nothing has been released from this project."));
170
182
  return 0;
171
183
  }
172
- console.log(bold(project.name));
184
+ console.log((0, colour_js_1.bold)(project.name));
173
185
  for (const release of published) {
174
186
  const when = release.releasedAt
175
187
  ? new Date(release.releasedAt).toLocaleDateString()
176
188
  : "";
177
- console.log(` ${accent(`v${release.sequence}`).padEnd(16)} ` +
189
+ console.log(` ${(0, colour_js_1.accent)(`v${release.sequence}`).padEnd(16)} ` +
178
190
  `${(release.name || "—").padEnd(28)} ${when.padEnd(14)} ` +
179
191
  `${release.assets.length} files`);
180
192
  const firstLine = release.notes.split("\n")[0];
181
193
  if (firstLine)
182
- console.log(` ${dim(firstLine)}`);
194
+ console.log(` ${(0, colour_js_1.dim)(firstLine)}`);
183
195
  }
184
196
  return 0;
185
197
  }
186
198
  /** Who can reach a project, and who has been asked. */
187
199
  async function commandCollaborators(parsed) {
200
+ /*
201
+ Accepting comes first: whoever is joining has no project of theirs to
202
+ name yet. The link is the one from the email, or the one the sender was
203
+ shown; only the token in it matters.
204
+ */
205
+ const link = parsed.flags.get("accept");
206
+ if (link === true) {
207
+ console.error((0, colour_js_1.red)("Which invite? Try: cbx people --accept <link from the invite>"));
208
+ return 1;
209
+ }
210
+ if (typeof link === "string" && link.trim()) {
211
+ let token = link.trim();
212
+ try {
213
+ token = new URL(token).searchParams.get("invite") ?? token;
214
+ }
215
+ catch {
216
+ /* Not a link: taken as the token itself. */
217
+ }
218
+ const joined = await (0, api_js_1.acceptInvite)(token);
219
+ console.log((0, colour_js_1.green)(`You've joined the project as ${joined.role}.`));
220
+ console.log((0, colour_js_1.dim)(" Fetch it with cbx clone <project>; cbx projects lists what you can reach."));
221
+ return 0;
222
+ }
188
223
  const project = await (0, project_commands_js_1.resolveProject)(parsed.positional[0]);
189
224
  if (!project)
190
225
  return 1;
191
226
  const email = parsed.flags.get("invite");
192
227
  if (email === true) {
193
- console.error(red("Whose address? Try: --invite someone@example.com"));
228
+ console.error((0, colour_js_1.red)("Whose address? Try: --invite someone@example.com"));
194
229
  return 1;
195
230
  }
196
231
  if (typeof email === "string" && email.trim()) {
197
- const role = parsed.flags.get("role");
198
- await (0, api_js_1.invite)(project.id, {
199
- email: email.trim(),
200
- role: typeof role === "string" ? role : "member",
201
- });
202
- console.log(green(`Invited ${email.trim()} to ${project.name}.`));
232
+ /*
233
+ The service knows three roles. The old default, "member", was not one
234
+ of them, so every invite without --role was refused.
235
+ */
236
+ const flag = parsed.flags.get("role");
237
+ const role = typeof flag === "string" ? flag.trim().toLowerCase() : "write";
238
+ if (!["write", "read", "admin"].includes(role)) {
239
+ console.error((0, colour_js_1.red)(`"${role}" is not a role. Use write, read or admin.`));
240
+ return 1;
241
+ }
242
+ const sent = await (0, api_js_1.invite)(project.id, { email: email.trim(), role });
243
+ console.log((0, colour_js_1.green)(`Invited ${email.trim()} to ${project.name}.`));
244
+ /*
245
+ The email can go astray, so the link is handed to the person who sent
246
+ it too. It only works once someone is signed in as that address.
247
+ */
248
+ if (sent.inviteUrl) {
249
+ console.log((0, colour_js_1.dim)(" If the email doesn't arrive, send them this link instead:"));
250
+ console.log(` ${sent.inviteUrl}`);
251
+ }
203
252
  return 0;
204
253
  }
205
254
  const people = await (0, api_js_1.collaborators)(project.id);
206
- console.log(bold(project.name));
255
+ console.log((0, colour_js_1.bold)(project.name));
207
256
  if (!people.collaborators.length) {
208
- console.log(dim(" Nobody else has access."));
257
+ console.log((0, colour_js_1.dim)(" Nobody else has access."));
209
258
  }
210
259
  for (const person of people.collaborators) {
211
- console.log(` ${(person.displayName || person.email).padEnd(28)} ${dim(person.role)}`);
260
+ console.log(` ${(person.displayName || person.email).padEnd(28)} ${(0, colour_js_1.dim)(person.role)}`);
212
261
  }
213
262
  if (people.invites.length) {
214
263
  console.log("");
215
- console.log(dim(" Waiting on a reply"));
264
+ console.log((0, colour_js_1.dim)(" Waiting on a reply"));
216
265
  for (const pending of people.invites) {
217
- console.log(` ${pending.email.padEnd(28)} ${dim(pending.role)}`);
266
+ console.log(` ${pending.email.padEnd(28)} ${(0, colour_js_1.dim)(pending.role)}`);
218
267
  }
219
268
  }
220
269
  return 0;
@@ -229,7 +278,7 @@ async function commandWatch(parsed) {
229
278
  const level = parsed.flags.get("level");
230
279
  if (typeof level === "string") {
231
280
  if (!WATCH_LEVELS.includes(level)) {
232
- console.error(red(`Level must be one of: ${WATCH_LEVELS.join(", ")}`));
281
+ console.error((0, colour_js_1.red)(`Level must be one of: ${WATCH_LEVELS.join(", ")}`));
233
282
  return 1;
234
283
  }
235
284
  change.level = level;
@@ -239,16 +288,16 @@ async function commandWatch(parsed) {
239
288
  }
240
289
  if (Object.keys(change).length) {
241
290
  await (0, api_js_1.setWatch)(project.id, change);
242
- console.log(green(`Updated what reaches you about ${project.name}.`));
291
+ console.log((0, colour_js_1.green)(`Updated what reaches you about ${project.name}.`));
243
292
  }
244
293
  const settings = await (0, api_js_1.watch)(project.id);
245
294
  console.log("");
246
- console.log(bold(project.name));
247
- console.log(` Level ${accent(settings.level)}`);
295
+ console.log((0, colour_js_1.bold)(project.name));
296
+ console.log(` Level ${(0, colour_js_1.accent)(settings.level)}`);
248
297
  console.log(` In the app ${settings.inApp ? "yes" : "no"}`);
249
298
  console.log(` Daily email ${settings.emailDigest ? "yes" : "no"}`);
250
299
  console.log("");
251
- console.log(dim(` Levels: ${WATCH_LEVELS.join(", ")}`));
300
+ console.log((0, colour_js_1.dim)(` Levels: ${WATCH_LEVELS.join(", ")}`));
252
301
  return 0;
253
302
  }
254
303
  /** The automations a project has, and how they have been going. */
@@ -270,14 +319,14 @@ async function commandWorkflows(parsed) {
270
319
  const wanted = ship !== undefined;
271
320
  const named = wanted ? ship : stop;
272
321
  if (typeof named !== "string" || !named.trim()) {
273
- console.error(red("Which action?") + dim(` cbx actions ${wanted ? "--ship" : "--no-ship"} "Build"`));
322
+ console.error((0, colour_js_1.red)("Which action?") + (0, colour_js_1.dim)(` cbx actions ${wanted ? "--ship" : "--no-ship"} "Build"`));
274
323
  return 1;
275
324
  }
276
325
  const target = found.find((workflow) => workflow.name.toLowerCase() === named.trim().toLowerCase());
277
326
  if (!target) {
278
- console.error(red(`${project.name} has no action called ${named.trim()}.`));
327
+ console.error((0, colour_js_1.red)(`${project.name} has no action called ${named.trim()}.`));
279
328
  if (found.length) {
280
- console.error(dim(` It has: ${found.map((one) => one.name).join(", ")}`));
329
+ console.error((0, colour_js_1.dim)(` It has: ${found.map((one) => one.name).join(", ")}`));
281
330
  }
282
331
  return 1;
283
332
  }
@@ -288,21 +337,21 @@ async function commandWorkflows(parsed) {
288
337
  then never produced a download would be indistinguishable from the
289
338
  feature being broken.
290
339
  */
291
- console.error(red(`${target.name} keeps no files, so it has nothing to ship.`));
292
- console.error(dim(" Give it something to keep on the Actions screen first, e.g. dist/*.exe"));
340
+ console.error((0, colour_js_1.red)(`${target.name} keeps no files, so it has nothing to ship.`));
341
+ console.error((0, colour_js_1.dim)(" Give it something to keep on the Actions screen first, e.g. dist/*.exe"));
293
342
  return 1;
294
343
  }
295
344
  try {
296
345
  await (0, api_js_1.changeWorkflow)(project.id, target.id, { attachArtifacts: wanted });
297
346
  }
298
347
  catch (error) {
299
- console.error(red(error instanceof Error ? error.message : String(error)));
348
+ console.error((0, colour_js_1.red)(error instanceof Error ? error.message : String(error)));
300
349
  return 1;
301
350
  }
302
351
  target.attachArtifacts = wanted;
303
352
  console.log(wanted
304
- ? green(`${target.name} will attach what it builds to the version it ran against.`)
305
- : green(`${target.name} will keep its files without attaching them.`));
353
+ ? (0, colour_js_1.green)(`${target.name} will attach what it builds to the version it ran against.`)
354
+ : (0, colour_js_1.green)(`${target.name} will keep its files without attaching them.`));
306
355
  if (wanted) {
307
356
  /*
308
357
  Said plainly, because attaching is publishing. An attachment on a
@@ -310,7 +359,7 @@ async function commandWorkflows(parsed) {
310
359
  this on for a workflow that builds an internal tool deserves to hear
311
360
  that before the next run rather than after it.
312
361
  */
313
- console.log(dim(" Anything it attaches to a public version is public the moment it lands."));
362
+ console.log((0, colour_js_1.dim)(" Anything it attaches to a public version is public the moment it lands."));
314
363
  }
315
364
  console.log("");
316
365
  }
@@ -329,14 +378,14 @@ async function commandWorkflows(parsed) {
329
378
  if (named === undefined)
330
379
  continue;
331
380
  if (typeof named !== "string" || !named.trim()) {
332
- console.error(red("Which action?") + dim(` cbx actions --${flag} "Tests"`));
381
+ console.error((0, colour_js_1.red)("Which action?") + (0, colour_js_1.dim)(` cbx actions --${flag} "Tests"`));
333
382
  return 1;
334
383
  }
335
384
  const target = found.find((workflow) => workflow.name.toLowerCase() === named.trim().toLowerCase());
336
385
  if (!target) {
337
- console.error(red(`${project.name} has no action called ${named.trim()}.`));
386
+ console.error((0, colour_js_1.red)(`${project.name} has no action called ${named.trim()}.`));
338
387
  if (found.length) {
339
- console.error(dim(` It has: ${found.map((one) => one.name).join(", ")}`));
388
+ console.error((0, colour_js_1.dim)(` It has: ${found.map((one) => one.name).join(", ")}`));
340
389
  }
341
390
  return 1;
342
391
  }
@@ -344,32 +393,32 @@ async function commandWorkflows(parsed) {
344
393
  await (0, api_js_1.changeWorkflow)(project.id, target.id, { trigger });
345
394
  }
346
395
  catch (error) {
347
- console.error(red(error instanceof Error ? error.message : String(error)));
396
+ console.error((0, colour_js_1.red)(error instanceof Error ? error.message : String(error)));
348
397
  return 1;
349
398
  }
350
399
  target.trigger = trigger;
351
- console.log(green(`${target.name} ${meaning}.`));
400
+ console.log((0, colour_js_1.green)(`${target.name} ${meaning}.`));
352
401
  if (trigger === "merge_opened") {
353
- console.log(dim(" Its result becomes a required check on the proposal."));
402
+ console.log((0, colour_js_1.dim)(" Its result becomes a required check on the proposal."));
354
403
  }
355
404
  console.log("");
356
405
  }
357
406
  if (!found.length) {
358
- console.log(dim("No actions on this project."));
407
+ console.log((0, colour_js_1.dim)("No actions on this project."));
359
408
  return 0;
360
409
  }
361
- console.log(bold(project.name));
410
+ console.log((0, colour_js_1.bold)(project.name));
362
411
  for (const workflow of found) {
363
412
  const health = workflow.runs
364
413
  ? `${workflow.passing}/${workflow.runs} passing`
365
414
  : "never run";
366
- console.log(` ${workflow.name.padEnd(24)} ${dim(workflow.trigger).padEnd(20)} ` +
367
- `${dim(workflow.runsOn).padEnd(18)} ${health}`);
368
- console.log(` ${dim(workflow.command)}`);
415
+ console.log(` ${workflow.name.padEnd(24)} ${(0, colour_js_1.dim)(workflow.trigger).padEnd(20)} ` +
416
+ `${(0, colour_js_1.dim)(workflow.runsOn).padEnd(18)} ${health}`);
417
+ console.log(` ${(0, colour_js_1.dim)(workflow.command)}`);
369
418
  if (workflow.artifactPaths.length) {
370
- console.log(` ${dim("keeps")} ${dim(workflow.artifactPaths.join(", "))}` +
419
+ console.log(` ${(0, colour_js_1.dim)("keeps")} ${(0, colour_js_1.dim)(workflow.artifactPaths.join(", "))}` +
371
420
  (workflow.attachArtifacts
372
- ? ` ${accent("→ downloads on the version")}`
421
+ ? ` ${(0, colour_js_1.accent)("→ downloads on the version")}`
373
422
  : ""));
374
423
  }
375
424
  }
@@ -379,12 +428,12 @@ const RUN_STATES = ["queued", "running", "passed", "failed", "cancelled"];
379
428
  /** Colour a status the way somebody scanning the list would want it. */
380
429
  function statusText(status) {
381
430
  if (status === "passed")
382
- return green(status);
431
+ return (0, colour_js_1.green)(status);
383
432
  if (status === "failed" || status === "cancelled")
384
- return red(status);
433
+ return (0, colour_js_1.red)(status);
385
434
  if (status === "running")
386
- return accent(status);
387
- return dim(status);
435
+ return (0, colour_js_1.accent)(status);
436
+ return (0, colour_js_1.dim)(status);
388
437
  }
389
438
  function elapsed(ms) {
390
439
  if (ms === null)
@@ -408,33 +457,33 @@ async function commandRuns(parsed) {
408
457
  return 1;
409
458
  const status = parsed.flags.get("status");
410
459
  if (typeof status === "string" && !RUN_STATES.includes(status)) {
411
- console.error(red(`Status must be one of: ${RUN_STATES.join(", ")}`));
460
+ console.error((0, colour_js_1.red)(`Status must be one of: ${RUN_STATES.join(", ")}`));
412
461
  return 1;
413
462
  }
414
463
  const found = await (0, api_js_1.runs)(project.id, {
415
464
  status: typeof status === "string" ? status : undefined,
416
465
  });
417
466
  if (!found.length) {
418
- console.log(dim("Nothing has run on this project."));
467
+ console.log((0, colour_js_1.dim)("Nothing has run on this project."));
419
468
  return 0;
420
469
  }
421
- console.log(bold(project.name));
470
+ console.log((0, colour_js_1.bold)(project.name));
422
471
  for (const run of found) {
423
472
  const when = run.startedAt
424
473
  ? new Date(run.startedAt).toLocaleString()
425
- : dim("not started");
426
- console.log(` ${accent(`#${run.number}`).padEnd(15)} ${statusText(run.status).padEnd(20)} ` +
427
- `${run.workflow.padEnd(24)} ${elapsed(run.durationMs).padEnd(9)} ${dim(when)}`);
474
+ : (0, colour_js_1.dim)("not started");
475
+ console.log(` ${(0, colour_js_1.accent)(`#${run.number}`).padEnd(15)} ${statusText(run.status).padEnd(20)} ` +
476
+ `${run.workflow.padEnd(24)} ${elapsed(run.durationMs).padEnd(9)} ${(0, colour_js_1.dim)(when)}`);
428
477
  const aside = [
429
478
  run.version === null ? "" : `v${run.version}`,
430
479
  run.claimedBy ?? "",
431
480
  run.summary,
432
481
  ].filter(Boolean);
433
482
  if (aside.length)
434
- console.log(` ${dim(aside.join(" · "))}`);
483
+ console.log(` ${(0, colour_js_1.dim)(aside.join(" · "))}`);
435
484
  }
436
485
  console.log("");
437
- console.log(dim(" Read one with: cbx logs <number>"));
486
+ console.log((0, colour_js_1.dim)(" Read one with: cbx logs <number>"));
438
487
  return 0;
439
488
  }
440
489
  /**
@@ -446,12 +495,12 @@ async function commandRuns(parsed) {
446
495
  async function commandLogs(parsed) {
447
496
  const asked = parsed.positional[0];
448
497
  if (!asked) {
449
- console.error(red("Which run? Try: cbx logs 12"));
498
+ console.error((0, colour_js_1.red)("Which run? Try: cbx logs 12"));
450
499
  return 1;
451
500
  }
452
501
  const number = Number(asked.replace(/^#/, ""));
453
502
  if (!Number.isInteger(number) || number < 1) {
454
- console.error(red(`"${asked}" is not a run number.`));
503
+ console.error((0, colour_js_1.red)(`"${asked}" is not a run number.`));
455
504
  return 1;
456
505
  }
457
506
  const project = await (0, project_commands_js_1.resolveProject)(parsed.positional[1]);
@@ -460,28 +509,28 @@ async function commandLogs(parsed) {
460
509
  const found = await (0, api_js_1.runs)(project.id);
461
510
  const run = found.find((one) => one.number === number);
462
511
  if (!run) {
463
- console.error(red(`${project.name} has no run #${number}.`));
512
+ console.error((0, colour_js_1.red)(`${project.name} has no run #${number}.`));
464
513
  if (found.length) {
465
- console.error(dim(` The most recent is #${found[0]?.number}.`));
514
+ console.error((0, colour_js_1.dim)(` The most recent is #${found[0]?.number}.`));
466
515
  }
467
516
  return 1;
468
517
  }
469
518
  const lines = await (0, api_js_1.runLogs)(project.id, run.id);
470
- console.log(`${accent(`#${run.number}`)} ${bold(run.workflow)} — ${statusText(run.status)}` +
471
- `${run.summary ? ` · ${dim(run.summary)}` : ""}`);
519
+ console.log(`${(0, colour_js_1.accent)(`#${run.number}`)} ${(0, colour_js_1.bold)(run.workflow)} — ${statusText(run.status)}` +
520
+ `${run.summary ? ` · ${(0, colour_js_1.dim)(run.summary)}` : ""}`);
472
521
  if (!lines.length) {
473
522
  /*
474
523
  Told apart deliberately. A queued run has printed nothing yet, which is
475
524
  normal; a finished run that printed nothing is a workflow whose command
476
525
  said nothing, which is worth knowing.
477
526
  */
478
- console.log(dim(run.status === "queued"
527
+ console.log((0, colour_js_1.dim)(run.status === "queued"
479
528
  ? " Nothing yet; this run has not been picked up."
480
529
  : " This run recorded no output."));
481
530
  return 0;
482
531
  }
483
532
  for (const line of lines) {
484
- console.log(line.stream === "stderr" ? red(line.line) : line.line);
533
+ console.log(line.stream === "stderr" ? (0, colour_js_1.red)(line.line) : line.line);
485
534
  }
486
535
  return run.status === "failed" ? 1 : 0;
487
536
  }
@@ -490,22 +539,22 @@ async function commandTokens(parsed) {
490
539
  const revoke = parsed.flags.get("revoke");
491
540
  if (typeof revoke === "string" && revoke.trim()) {
492
541
  await (0, api_js_1.revokeToken)(revoke.trim());
493
- console.log(green("Revoked. Anything using it stops working now."));
542
+ console.log((0, colour_js_1.green)("Revoked. Anything using it stops working now."));
494
543
  return 0;
495
544
  }
496
545
  const found = await (0, api_js_1.tokens)();
497
546
  if (!found.length) {
498
- console.log(dim("No personal access tokens on this account."));
547
+ console.log((0, colour_js_1.dim)("No personal access tokens on this account."));
499
548
  return 0;
500
549
  }
501
550
  for (const token of found) {
502
551
  const used = token.lastUsedAt
503
552
  ? new Date(token.lastUsedAt).toLocaleDateString()
504
553
  : "never used";
505
- console.log(` ${token.name.padEnd(26)} ${used.padEnd(16)} ${dim(token.id)}`);
554
+ console.log(` ${token.name.padEnd(26)} ${used.padEnd(16)} ${(0, colour_js_1.dim)(token.id)}`);
506
555
  }
507
556
  console.log("");
508
- console.log(dim(" Revoke one with: cbx tokens --revoke <id>"));
557
+ console.log((0, colour_js_1.dim)(" Revoke one with: cbx tokens --revoke <id>"));
509
558
  return 0;
510
559
  }
511
560
  /**
@@ -520,9 +569,9 @@ async function commandDelete(parsed) {
520
569
  if (!project)
521
570
  return 1;
522
571
  if (parsed.flags.get("yes") !== true) {
523
- console.log(`This deletes ${bold(project.name)} — ${project.versionCount} versions, ` +
572
+ console.log(`This deletes ${(0, colour_js_1.bold)(project.name)} — ${project.versionCount} versions, ` +
524
573
  `${bytes(project.storedBytes)}.`);
525
- console.log(dim("It is kept for 30 days before the storage is reclaimed."));
574
+ console.log((0, colour_js_1.dim)("It is kept for 30 days before the storage is reclaimed."));
526
575
  const prompt = (0, promises_1.createInterface)({
527
576
  input: node_process_1.default.stdin,
528
577
  output: node_process_1.default.stdout,
@@ -531,12 +580,12 @@ async function commandDelete(parsed) {
531
580
  prompt.close();
532
581
  const answer = typed.trim();
533
582
  if (answer !== project.slug && answer !== project.name) {
534
- console.error(red("That did not match. Nothing was deleted."));
583
+ console.error((0, colour_js_1.red)("That did not match. Nothing was deleted."));
535
584
  return 1;
536
585
  }
537
586
  }
538
587
  await (0, api_js_1.deleteProject)(project.id);
539
- console.log(green(`Deleted ${project.name}.`));
588
+ console.log((0, colour_js_1.green)(`Deleted ${project.name}.`));
540
589
  return 0;
541
590
  }
542
591
  /**
@@ -556,7 +605,7 @@ async function commandHooks(parsed) {
556
605
  const adding = parsed.flags.get("add");
557
606
  if (adding !== undefined) {
558
607
  if (typeof adding !== "string" || !adding.trim()) {
559
- console.error(red("Which address?") + dim(" cbx hooks --add https://example.com/hook"));
608
+ console.error((0, colour_js_1.red)("Which address?") + (0, colour_js_1.dim)(" cbx hooks --add https://example.com/hook"));
560
609
  return 1;
561
610
  }
562
611
  const url = adding.trim();
@@ -566,7 +615,7 @@ async function commandHooks(parsed) {
566
615
  payload about a private project, and http would put it on the wire in
567
616
  the clear — worth saying before the round trip rather than after.
568
617
  */
569
- console.error(red("A webhook address has to be https."));
618
+ console.error((0, colour_js_1.red)("A webhook address has to be https."));
570
619
  return 1;
571
620
  }
572
621
  const named = parsed.flags.get("events");
@@ -575,7 +624,7 @@ async function commandHooks(parsed) {
575
624
  : [];
576
625
  try {
577
626
  const made = await (0, api_js_1.addWebhook)(project.id, url, events);
578
- console.log(green(`${project.name} will notify ${url}.`));
627
+ console.log((0, colour_js_1.green)(`${project.name} will notify ${url}.`));
579
628
  console.log("");
580
629
  /*
581
630
  Printed once because it exists once. The service generates it and no
@@ -583,16 +632,16 @@ async function commandHooks(parsed) {
583
632
  write it down — and saying so is the difference between a person
584
633
  copying it and a person losing it.
585
634
  */
586
- console.log(` ${bold("Signing secret")} ${made.secret}`);
587
- console.log(dim(" Written once and never again. Use it to check the signature on"));
588
- console.log(dim(" what arrives, so nobody else can post to your endpoint."));
635
+ console.log(` ${(0, colour_js_1.bold)("Signing secret")} ${made.secret}`);
636
+ console.log((0, colour_js_1.dim)(" Written once and never again. Use it to check the signature on"));
637
+ console.log((0, colour_js_1.dim)(" what arrives, so nobody else can post to your endpoint."));
589
638
  if (events.length)
590
- console.log(dim(` Sending: ${events.join(", ")}`));
639
+ console.log((0, colour_js_1.dim)(` Sending: ${events.join(", ")}`));
591
640
  else
592
- console.log(dim(" Sending: everything this project announces"));
641
+ console.log((0, colour_js_1.dim)(" Sending: everything this project announces"));
593
642
  }
594
643
  catch (error) {
595
- console.error(red(error instanceof Error ? error.message : String(error)));
644
+ console.error((0, colour_js_1.red)(error instanceof Error ? error.message : String(error)));
596
645
  return 1;
597
646
  }
598
647
  return 0;
@@ -600,26 +649,26 @@ async function commandHooks(parsed) {
600
649
  const removing = parsed.flags.get("remove");
601
650
  if (removing !== undefined) {
602
651
  if (typeof removing !== "string" || !removing.trim()) {
603
- console.error(red("Which one?") + dim(" cbx hooks --remove <id>"));
652
+ console.error((0, colour_js_1.red)("Which one?") + (0, colour_js_1.dim)(" cbx hooks --remove <id>"));
604
653
  return 1;
605
654
  }
606
655
  const wanted = removing.trim();
607
656
  const found = (await (0, api_js_1.webhooks)(project.id)).find((one) => one.id === wanted || one.url === wanted);
608
657
  if (!found) {
609
- console.error(red(`${project.name} has no webhook called ${wanted}.`));
658
+ console.error((0, colour_js_1.red)(`${project.name} has no webhook called ${wanted}.`));
610
659
  return 1;
611
660
  }
612
661
  await (0, api_js_1.removeWebhook)(project.id, found.id);
613
- console.log(green(`${found.url} will not be notified any more.`));
662
+ console.log((0, colour_js_1.green)(`${found.url} will not be notified any more.`));
614
663
  return 0;
615
664
  }
616
665
  const found = await (0, api_js_1.webhooks)(project.id);
617
666
  if (!found.length) {
618
- console.log(dim("This project notifies nothing."));
619
- console.log(dim(" cbx hooks --add https://example.com/coderook"));
667
+ console.log((0, colour_js_1.dim)("This project notifies nothing."));
668
+ console.log((0, colour_js_1.dim)(" cbx hooks --add https://example.com/coderook"));
620
669
  return 0;
621
670
  }
622
- console.log(bold(project.name));
671
+ console.log((0, colour_js_1.bold)(project.name));
623
672
  for (const hook of found) {
624
673
  /*
625
674
  A run of failures shown rather than hidden. A webhook that has been
@@ -627,15 +676,15 @@ async function commandHooks(parsed) {
627
676
  checks the receiving end, which is the wrong place to find out.
628
677
  */
629
678
  const health = !hook.active
630
- ? red("off")
679
+ ? (0, colour_js_1.red)("off")
631
680
  : hook.consecutiveFailures
632
- ? red(`${hook.consecutiveFailures} failed in a row`)
681
+ ? (0, colour_js_1.red)(`${hook.consecutiveFailures} failed in a row`)
633
682
  : hook.lastDeliveredAt
634
- ? green("delivering")
635
- : dim("nothing sent yet");
683
+ ? (0, colour_js_1.green)("delivering")
684
+ : (0, colour_js_1.dim)("nothing sent yet");
636
685
  console.log(` ${hook.url}`);
637
- console.log(` ${dim(hook.id)} ${health}` +
638
- (hook.events.length ? ` ${dim(hook.events.join(", "))}` : ` ${dim("everything")}`));
686
+ console.log(` ${(0, colour_js_1.dim)(hook.id)} ${health}` +
687
+ (hook.events.length ? ` ${(0, colour_js_1.dim)(hook.events.join(", "))}` : ` ${(0, colour_js_1.dim)("everything")}`));
639
688
  }
640
689
  return 0;
641
690
  }