@xsynaptic/astro-scripts 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,8 +7,12 @@ pnpm add @xsynaptic/astro-scripts
7
7
  ```
8
8
 
9
9
  ```ts
10
- import { createCommandRunner, log } from '@xsynaptic/astro-scripts';
11
- import { getCollectionEntries, withAstroContent } from '@xsynaptic/astro-scripts/astro';
10
+ import {
11
+ createCommandRunner,
12
+ getCollectionEntries,
13
+ log,
14
+ withAstroContent,
15
+ } from '@xsynaptic/astro-scripts';
12
16
 
13
17
  const { runCommand } = createCommandRunner();
14
18
 
@@ -24,7 +28,15 @@ await runCommand({
24
28
  });
25
29
  ```
26
30
 
27
- Output renders `pretty` on a TTY, `plain` elsewhere, and NDJSON with `--json`; `SCRIPTS_OUTPUT` overrides the choice. The `/astro` entry needs `astro` and `vite` installed and a content store written by `astro sync`.
31
+ Output renders `pretty` on a TTY, `plain` elsewhere, and NDJSON with `--json`; `SCRIPTS_OUTPUT` overrides the choice. Run a `--json` command through `pnpm --silent`, or pnpm's own lines land in the stream.
32
+
33
+ Throw `UserError` for an expected failure: the run ends with its message and optional `detail`, and no stack. The runner matches it by `name === 'UserError'` and reads `detail` when it is a string, so a library can throw its own class of that name without depending on this package:
34
+
35
+ ```ts
36
+ throw new UserError('Caddy did not reload', { detail: stderrTail });
37
+ ```
38
+
39
+ `withAstroModules` and `withAstroContent` load `astro` and `vite` only when called, and need a content store written by `astro sync`.
28
40
 
29
41
  ## License
30
42
 
package/dist/index.d.mts CHANGED
@@ -1,4 +1,22 @@
1
1
  import { ParseArgsOptionDescriptor, parseArgs } from "node:util";
2
+ import * as AstroContentModule from "astro:content";
3
+ import { CollectionEntry, CollectionKey } from "astro:content";
4
+ import { ModuleRunner } from "vite/module-runner";
5
+ //#region src/astro.d.ts
6
+ type AstroContent = typeof AstroContentModule;
7
+ interface ContentEntry {
8
+ body?: string | undefined;
9
+ collection: string;
10
+ data: Record<string, unknown>;
11
+ digest?: number | string | undefined;
12
+ filePath?: string | undefined;
13
+ id: string;
14
+ }
15
+ export declare function findAstroRoot(startDir?: string): string;
16
+ export declare function getCollectionEntries<C extends CollectionKey>({ getCollection }: AstroContent, collections: Array<C>): Promise<Array<CollectionEntry<C>>>;
17
+ export declare function withAstroModules<T>(callback: (runner: ModuleRunner) => Promise<T>): Promise<T>;
18
+ export declare function withAstroContent<T>(callback: (content: AstroContent) => Promise<T>): Promise<T>;
19
+ //#endregion
2
20
  //#region src/command.d.ts
3
21
  type CommandOption = ParseArgsOptionDescriptor & {
4
22
  description: string;
@@ -48,15 +66,67 @@ export declare function formatCount(count: number): string;
48
66
  export declare function formatBytes(bytes: number): string;
49
67
  export declare function formatError(error: unknown): string;
50
68
  export declare function formatDuration(milliseconds: number): string;
69
+ interface ProgressSnapshot {
70
+ done: number;
71
+ label: string;
72
+ note?: string;
73
+ perSecond?: number;
74
+ total: number;
75
+ }
51
76
  //#endregion
52
77
  //#region src/output/events.d.ts
78
+ type MessageLevel = 'detail' | 'error' | 'info' | 'step' | 'success' | 'title' | 'warn';
79
+ type StatusState = 'fail' | 'start' | 'stop' | 'succeed' | 'update' | 'warn';
80
+ type EndStatus = 'failed' | 'interrupted' | 'ok';
53
81
  type SummaryRow = [label: string, value: number | string];
82
+ interface StartEvent {
83
+ title: string;
84
+ type: 'start';
85
+ }
86
+ interface MessageEvent {
87
+ level: MessageLevel;
88
+ text: string;
89
+ type: 'message';
90
+ }
91
+ interface StatusEvent {
92
+ id: number;
93
+ state: StatusState;
94
+ text: string;
95
+ type: 'status';
96
+ }
97
+ interface ProgressEvent extends ProgressSnapshot {
98
+ id: number;
99
+ type: 'progress';
100
+ }
101
+ interface SummaryEvent {
102
+ rows: Array<SummaryRow>;
103
+ type: 'summary';
104
+ }
105
+ interface DataEvent {
106
+ render?: () => string;
107
+ type: 'data';
108
+ value: unknown;
109
+ }
110
+ interface EndEvent {
111
+ detail?: string;
112
+ durationMs: number;
113
+ exitCode: number;
114
+ forced?: true;
115
+ message?: string;
116
+ status: EndStatus;
117
+ type: 'end';
118
+ }
119
+ type OutputEvent = DataEvent | EndEvent | MessageEvent | ProgressEvent | StartEvent | StatusEvent | SummaryEvent;
54
120
  //#endregion
55
121
  //#region src/output/output.d.ts
56
122
  type OutputMode = 'json' | 'plain' | 'pretty';
57
123
  export declare function getOutputMode(): OutputMode;
124
+ export declare function captureOutput<Result>(task: () => Promise<Result> | Result): Promise<{
125
+ events: OutputEvent[];
126
+ result: Awaited<Result>;
127
+ }>;
58
128
  export declare const log: {
59
- data(value: unknown): void;
129
+ data<Value>(value: Value, format?: (value: Value) => string): void;
60
130
  detail(text: string): void;
61
131
  error(text: string): void;
62
132
  info(text: string): void;
@@ -89,13 +159,17 @@ export declare function createProgress({ label, note, total }: ProgressOptions):
89
159
  export declare function withStatus<Result>(text: string, task: () => Promise<Result>): Promise<Result>;
90
160
  export declare function withSpinner<Result>(text: string, task: () => Promise<Result>, describe?: (result: Result) => string): Promise<Result>;
91
161
  //#endregion
92
- //#region src/refusal.d.ts
93
- export declare class Refusal extends Error {
162
+ //#region src/user-error.d.ts
163
+ export declare class UserError extends Error {
164
+ detail?: string;
94
165
  name: string;
166
+ constructor(message: string, options?: ErrorOptions & {
167
+ detail?: string;
168
+ });
95
169
  }
96
170
  //#endregion
97
171
  //#region src/workspace.d.ts
98
172
  export declare function findWorkspaceRoot(startDir?: string): string;
99
173
  //#endregion
100
- export type { Command, CommandContext, OutputMode };
174
+ export type { Command, CommandContext, ContentEntry, OutputEvent, OutputMode };
101
175
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,8 +1,70 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
1
3
  import chalk from "chalk";
2
4
  import { parseArgs, stripVTControlCharacters } from "node:util";
3
5
  import ora from "ora";
4
- import { existsSync } from "node:fs";
5
- import path from "node:path";
6
+ //#region src/user-error.ts
7
+ var UserError = class extends Error {
8
+ detail;
9
+ name = "UserError";
10
+ constructor(message, options) {
11
+ super(message, options);
12
+ if (options?.detail !== void 0) this.detail = options.detail;
13
+ }
14
+ };
15
+ function isUserError(error) {
16
+ return error instanceof Error && error.name === "UserError";
17
+ }
18
+ //#endregion
19
+ //#region src/astro.ts
20
+ const configFilenames = [
21
+ "astro.config.mjs",
22
+ "astro.config.js",
23
+ "astro.config.ts",
24
+ "astro.config.mts"
25
+ ];
26
+ function findAstroRoot(startDir = process.cwd()) {
27
+ let current = path.resolve(startDir);
28
+ while (current !== path.dirname(current)) {
29
+ if (configFilenames.some((filename) => existsSync(path.join(current, filename)))) return current;
30
+ current = path.dirname(current);
31
+ }
32
+ throw new UserError(`Could not locate an Astro config above ${startDir}`);
33
+ }
34
+ async function getCollectionEntries({ getCollection }, collections) {
35
+ const flattened = (await Promise.all(collections.map((collection) => getCollection(collection)))).flat();
36
+ if (flattened.length === 0) throw new UserError(`No entries found in: ${collections.join(", ")}. Run \`astro sync\` to write the content store.`);
37
+ return flattened;
38
+ }
39
+ async function withAstroModules(callback) {
40
+ const root = findAstroRoot();
41
+ const [{ getViteConfig }, { createLogger, createServer, createServerModuleRunner }] = await Promise.all([import("astro/config"), import("vite")]);
42
+ const server = await createServer({
43
+ ...await getViteConfig({}, {
44
+ logLevel: "silent",
45
+ root
46
+ })({
47
+ command: "serve",
48
+ mode: "development"
49
+ }),
50
+ customLogger: createLogger("silent"),
51
+ logLevel: "silent",
52
+ server: {
53
+ hmr: false,
54
+ middlewareMode: true,
55
+ ws: false
56
+ }
57
+ });
58
+ try {
59
+ return await callback(createServerModuleRunner(server.environments.ssr));
60
+ } finally {
61
+ await server.close();
62
+ }
63
+ }
64
+ async function withAstroContent(callback) {
65
+ return withAstroModules(async (runner) => callback(await runner.import("astro:content")));
66
+ }
67
+ //#endregion
6
68
  //#region src/output/reporter-json.ts
7
69
  const throttleMs = 1e3;
8
70
  function strip(text) {
@@ -159,7 +221,7 @@ function getStateSymbol(state, palette) {
159
221
  }
160
222
  function formatMessage(level, text, palette) {
161
223
  switch (level) {
162
- case "detail": return palette.gray(` ${text}`);
224
+ case "detail": return palette.gray(text.split("\n").map((line) => ` ${line}`).join("\n"));
163
225
  case "error": return `${getStateSymbol("fail", palette)} ${palette.red(text)}`;
164
226
  case "info": return text;
165
227
  case "step": return palette.blue(text);
@@ -190,25 +252,27 @@ function formatEnd(event, palette) {
190
252
  const progressIntervalMs = 1e4;
191
253
  function createPlainReporter({ stderr, stdout }, now = Date.now) {
192
254
  const statuses = /* @__PURE__ */ new Map();
193
- let activeId;
255
+ const openIds = [];
194
256
  function writeLine(line) {
195
257
  stderr.write(`${stripVTControlCharacters(line)}\n`);
196
258
  }
197
259
  function closeStatus(id) {
198
260
  statuses.delete(id);
199
- if (activeId === id) activeId = void 0;
261
+ openIds.splice(openIds.indexOf(id), 1);
200
262
  }
201
263
  return { emit(event) {
202
264
  switch (event.type) {
203
- case "data":
204
- stdout.write(`${formatData(event.value)}\n`);
265
+ case "data": {
266
+ const line = event.render === void 0 ? formatData(event.value) : stripVTControlCharacters(event.render());
267
+ stdout.write(`${line}\n`);
205
268
  break;
269
+ }
206
270
  case "end": {
271
+ const activeId = openIds.at(-1);
207
272
  const active = activeId === void 0 ? void 0 : statuses.get(activeId);
208
- if (active && activeId !== void 0 && event.status !== "ok") {
209
- writeLine(`${getStateSymbol("fail", plainPalette)} ${active.text}`);
210
- closeStatus(activeId);
211
- }
273
+ if (active && event.status !== "ok") writeLine(`${getStateSymbol("fail", plainPalette)} ${active.text}`);
274
+ statuses.clear();
275
+ openIds.length = 0;
212
276
  for (const line of formatEnd(event, plainPalette)) writeLine(line);
213
277
  break;
214
278
  }
@@ -233,7 +297,7 @@ function createPlainReporter({ stderr, stdout }, now = Date.now) {
233
297
  lastPrint: now(),
234
298
  text
235
299
  });
236
- activeId = id;
300
+ openIds.push(id);
237
301
  writeLine(text);
238
302
  break;
239
303
  }
@@ -253,32 +317,42 @@ function createPlainReporter({ stderr, stdout }, now = Date.now) {
253
317
  }
254
318
  //#endregion
255
319
  //#region src/output/reporter-pretty.ts
320
+ function isTerminal(stream) {
321
+ return "isTTY" in stream && stream.isTTY === true;
322
+ }
256
323
  function createPrettyReporter({ stderr, stdout }) {
257
324
  const spinners = /* @__PURE__ */ new Map();
258
- let activeId;
325
+ const openIds = [];
259
326
  function getActiveSpinner() {
327
+ const activeId = openIds.at(-1);
260
328
  return activeId === void 0 ? void 0 : spinners.get(activeId);
261
329
  }
262
- function writeLine(line) {
330
+ function writeAround(stream, line) {
263
331
  const active = getActiveSpinner();
264
332
  if (!active?.isSpinning) {
265
- stderr.write(`${line}\n`);
333
+ stream.write(`${line}\n`);
266
334
  return;
267
335
  }
268
336
  active.clear();
269
- stderr.write(`${line}\n`);
337
+ stream.write(`${line}\n`);
270
338
  active.render();
271
339
  }
340
+ function writeLine(line) {
341
+ writeAround(stderr, line);
342
+ }
272
343
  function endSpinner(id, state, text) {
273
344
  const spinner = spinners.get(id);
274
345
  if (!spinner) return;
346
+ const wasActive = openIds.at(-1) === id;
275
347
  if (state === "stop") spinner.stop();
276
348
  else spinner.stopAndPersist({
277
349
  symbol: getStateSymbol(state, chalk),
278
350
  text
279
351
  });
280
352
  spinners.delete(id);
281
- if (activeId === id) activeId = void 0;
353
+ openIds.splice(openIds.indexOf(id), 1);
354
+ const outer = getActiveSpinner();
355
+ if (wasActive && outer?.isEnabled) outer.start();
282
356
  }
283
357
  function onStatus({ id, state, text }) {
284
358
  if (state === "start") {
@@ -288,7 +362,7 @@ function createPrettyReporter({ stderr, stdout }) {
288
362
  stream: stderr,
289
363
  text
290
364
  }).start());
291
- activeId = id;
365
+ openIds.push(id);
292
366
  return;
293
367
  }
294
368
  if (state === "update") {
@@ -300,15 +374,25 @@ function createPrettyReporter({ stderr, stdout }) {
300
374
  }
301
375
  return { emit(event) {
302
376
  switch (event.type) {
303
- case "data":
304
- stdout.write(`${formatData(event.value)}\n`);
377
+ case "data": {
378
+ const line = event.render?.() ?? formatData(event.value);
379
+ if (isTerminal(stdout)) writeAround(stdout, line);
380
+ else stdout.write(`${line}\n`);
305
381
  break;
382
+ }
306
383
  case "end": {
384
+ const activeId = openIds.at(-1);
307
385
  const active = getActiveSpinner();
308
- if (active && activeId !== void 0 && event.status !== "ok") endSpinner(activeId, "fail", active.text);
386
+ if (active && activeId !== void 0 && event.status !== "ok") {
387
+ spinners.delete(activeId);
388
+ active.stopAndPersist({
389
+ symbol: getStateSymbol("fail", chalk),
390
+ text: active.text
391
+ });
392
+ }
309
393
  for (const spinner of spinners.values()) spinner.stop();
310
394
  spinners.clear();
311
- activeId = void 0;
395
+ openIds.length = 0;
312
396
  for (const line of formatEnd(event, chalk)) writeLine(line);
313
397
  break;
314
398
  }
@@ -339,6 +423,7 @@ const outputModes = /* @__PURE__ */ new Set([
339
423
  ]);
340
424
  let currentMode;
341
425
  let currentReporter;
426
+ let capturingReporter;
342
427
  let nextStatusId = 1;
343
428
  function isOutputMode(value) {
344
429
  return outputModes.has(value);
@@ -366,9 +451,28 @@ function getOutputMode() {
366
451
  return currentMode;
367
452
  }
368
453
  function emit(event) {
454
+ if (capturingReporter) {
455
+ capturingReporter.emit(event);
456
+ return;
457
+ }
369
458
  if (currentReporter === void 0) currentReporter = createReporter(getOutputMode());
370
459
  currentReporter.emit(event);
371
460
  }
461
+ async function captureOutput(task) {
462
+ const events = [];
463
+ const previous = capturingReporter;
464
+ capturingReporter = { emit(event) {
465
+ events.push(event);
466
+ } };
467
+ try {
468
+ return {
469
+ events,
470
+ result: await task()
471
+ };
472
+ } finally {
473
+ capturingReporter = previous;
474
+ }
475
+ }
372
476
  function emitMessage(level, text) {
373
477
  emit({
374
478
  level,
@@ -377,8 +481,12 @@ function emitMessage(level, text) {
377
481
  });
378
482
  }
379
483
  const log = {
380
- data(value) {
381
- emit({
484
+ data(value, format) {
485
+ emit(format ? {
486
+ render: () => format(value),
487
+ type: "data",
488
+ value
489
+ } : {
382
490
  type: "data",
383
491
  value
384
492
  });
@@ -461,14 +569,6 @@ function createStatus(text) {
461
569
  return startStatus(text).status;
462
570
  }
463
571
  //#endregion
464
- //#region src/refusal.ts
465
- var Refusal = class extends Error {
466
- name = "Refusal";
467
- };
468
- function isRefusal(error) {
469
- return error instanceof Error && error.name === "Refusal";
470
- }
471
- //#endregion
472
572
  //#region src/workspace.ts
473
573
  function findWorkspaceRoot(startDir = process.cwd()) {
474
574
  let current = path.resolve(startDir);
@@ -476,7 +576,7 @@ function findWorkspaceRoot(startDir = process.cwd()) {
476
576
  if (existsSync(path.join(current, "pnpm-workspace.yaml"))) return current;
477
577
  current = path.dirname(current);
478
578
  }
479
- throw new Error(`Could not locate pnpm-workspace.yaml above ${startDir}`);
579
+ throw new UserError(`Could not locate pnpm-workspace.yaml above ${startDir}`);
480
580
  }
481
581
  //#endregion
482
582
  //#region src/command.ts
@@ -492,7 +592,7 @@ const builtInOptions = [["json", {
492
592
  }]];
493
593
  function parseNumberOption(value, name) {
494
594
  const parsed = Number(value);
495
- if (value.trim() === "" || !Number.isFinite(parsed)) throw new Refusal(`--${name} expects a number, got "${value}"`);
595
+ if (value.trim() === "" || !Number.isFinite(parsed)) throw new UserError(`--${name} expects a number, got "${value}"`);
496
596
  return parsed;
497
597
  }
498
598
  function getUsage(command, usagePrefix) {
@@ -537,8 +637,22 @@ function describeError(error) {
537
637
  detail: "See --help",
538
638
  message: error.message
539
639
  };
540
- if (isRefusal(error)) return { message: error.message };
541
- if (isChildProcessFailure(error)) return { message: `Child process ${error.signal ? `was killed by ${error.signal}` : `exited with code ${String(error.exitCode)}`}` };
640
+ if (isUserError(error)) {
641
+ const { detail, message } = error;
642
+ return typeof detail === "string" && detail !== "" ? {
643
+ detail,
644
+ message
645
+ } : { message };
646
+ }
647
+ if (isChildProcessFailure(error)) {
648
+ const message = `Child process ${error.signal ? `was killed by ${error.signal}` : `exited with code ${String(error.exitCode)}`}`;
649
+ const stderr = typeof error.stderr === "string" ? error.stderr.trimEnd() : "";
650
+ if (stderr === "") return { message };
651
+ return {
652
+ detail: stderr.split("\n").slice(-20).join("\n"),
653
+ message
654
+ };
655
+ }
542
656
  if (!(error instanceof Error)) return { message: String(error) };
543
657
  const stack = error.stack?.split("\n").slice(1).join("\n");
544
658
  return stack ? {
@@ -573,7 +687,7 @@ function selectOutput(isJson) {
573
687
  return;
574
688
  }
575
689
  const requested = process.env.SCRIPTS_OUTPUT;
576
- if (requested && !isOutputMode(requested)) throw new Refusal(`SCRIPTS_OUTPUT must be pretty, plain or json, got "${requested}"`);
690
+ if (requested && !isOutputMode(requested)) throw new UserError(`SCRIPTS_OUTPUT must be pretty, plain or json, got "${requested}"`);
577
691
  }
578
692
  function createCommandRunner(runnerOptions = {}) {
579
693
  const { context: createContext, usagePrefix = "pnpm" } = runnerOptions;
@@ -584,7 +698,9 @@ function createCommandRunner(runnerOptions = {}) {
584
698
  const controller = new AbortController();
585
699
  const startTime = Date.now();
586
700
  let interruptTime;
587
- const isJson = process.argv.slice(2).includes("--json");
701
+ const args = process.argv.slice(2);
702
+ const separator = args.indexOf("--");
703
+ const isJson = (separator === -1 ? args : args.slice(0, separator)).includes("--json");
588
704
  configureOutput(isJson ? "json" : void 0, command.name);
589
705
  function onInterrupt() {
590
706
  if (interruptTime === void 0) {
@@ -606,6 +722,7 @@ function createCommandRunner(runnerOptions = {}) {
606
722
  }
607
723
  process.on("SIGINT", onInterrupt);
608
724
  process.on("SIGTERM", onInterrupt);
725
+ let hasStarted = false;
609
726
  try {
610
727
  const { positionals, values } = parseCommandArgs(command);
611
728
  if (values.help) {
@@ -617,6 +734,7 @@ function createCommandRunner(runnerOptions = {}) {
617
734
  title: command.title,
618
735
  type: "start"
619
736
  });
737
+ hasStarted = true;
620
738
  const rootPath = findWorkspaceRoot();
621
739
  const context = createContext ? await createContext({ rootPath }) : {};
622
740
  await command.run({
@@ -634,6 +752,10 @@ function createCommandRunner(runnerOptions = {}) {
634
752
  type: "end"
635
753
  });
636
754
  } catch (error) {
755
+ if (!hasStarted && getOutputMode() === "json") emit({
756
+ title: command.title,
757
+ type: "start"
758
+ });
637
759
  const report = getFailureReport(error, {
638
760
  interrupted: command.interrupted,
639
761
  isAborted: controller.signal.aborted
@@ -751,6 +873,6 @@ async function withSpinner(text, task, describe) {
751
873
  }
752
874
  }
753
875
  //#endregion
754
- export { Refusal, createCommandRunner, createProgress, createStatus, findWorkspaceRoot, formatBytes, formatCount, formatDuration, formatError, getOutputMode, log, parseNumberOption, withSpinner, withStatus };
876
+ export { UserError, captureOutput, createCommandRunner, createProgress, createStatus, findAstroRoot, findWorkspaceRoot, formatBytes, formatCount, formatDuration, formatError, getCollectionEntries, getOutputMode, log, parseNumberOption, withAstroContent, withAstroModules, withSpinner, withStatus };
755
877
 
756
878
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/output/reporter-json.ts","../src/output/format.ts","../src/output/human-format.ts","../src/output/reporter-plain.ts","../src/output/reporter-pretty.ts","../src/output/output.ts","../src/refusal.ts","../src/workspace.ts","../src/command.ts","../src/output/progress.ts"],"sourcesContent":["import { stripVTControlCharacters } from 'node:util';\n\nimport type { OutputEvent, Reporter, ReporterStreams } from './events.js';\n\ntype ProgressEvent = Extract<OutputEvent, { type: 'progress' }>;\n\ninterface JsonReporterOptions {\n\tcommand?: string | undefined;\n\tnow?: () => number;\n}\n\ninterface Throttle {\n\tlastSent: number;\n\tpending?: ProgressEvent;\n}\n\nconst throttleMs = 1000;\n\nfunction strip(text: string): string;\nfunction strip(text: string | undefined): string | undefined;\nfunction strip(text: string | undefined) {\n\treturn text === undefined ? undefined : stripVTControlCharacters(text);\n}\n\nfunction stripEvent(event: OutputEvent): OutputEvent {\n\tswitch (event.type) {\n\t\tcase 'data': {\n\t\t\treturn event;\n\t\t}\n\t\tcase 'end': {\n\t\t\tconst { detail, message, ...rest } = event;\n\n\t\t\treturn {\n\t\t\t\t...rest,\n\t\t\t\t...(detail === undefined ? {} : { detail: strip(detail) }),\n\t\t\t\t...(message === undefined ? {} : { message: strip(message) }),\n\t\t\t};\n\t\t}\n\t\tcase 'message':\n\t\tcase 'status': {\n\t\t\treturn { ...event, text: strip(event.text) };\n\t\t}\n\t\tcase 'progress': {\n\t\t\tconst { note, ...rest } = event;\n\n\t\t\treturn { ...rest, label: strip(event.label), ...(note ? { note: strip(note) } : {}) };\n\t\t}\n\t\tcase 'start': {\n\t\t\treturn { ...event, title: strip(event.title) };\n\t\t}\n\t\tcase 'summary': {\n\t\t\treturn {\n\t\t\t\t...event,\n\t\t\t\trows: event.rows.map(([label, value]) => [\n\t\t\t\t\tstrip(label),\n\t\t\t\t\ttypeof value === 'string' ? strip(value) : value,\n\t\t\t\t]),\n\t\t\t};\n\t\t}\n\t}\n}\n\nexport function createJsonReporter(\n\t{ stderr, stdout }: ReporterStreams,\n\t{ command, now = Date.now }: JsonReporterOptions = {},\n): Reporter {\n\tconst progressThrottles = new Map<number, Throttle>();\n\tconst updateThrottles = new Map<number, Throttle>();\n\n\tfunction write(event: OutputEvent) {\n\t\tconst { type, ...payload } = stripEvent(event);\n\t\tconst envelope = { command, time: new Date(now()).toISOString() };\n\n\t\tstderr.write(`${JSON.stringify({ type, ...envelope, ...payload })}\\n`);\n\t}\n\n\tfunction isDue(throttles: Map<number, Throttle>, id: number) {\n\t\tconst time = now();\n\t\tconst throttle = throttles.get(id);\n\n\t\tif (throttle && time - throttle.lastSent < throttleMs) return false;\n\n\t\tthrottles.set(id, { lastSent: time });\n\n\t\treturn true;\n\t}\n\n\treturn {\n\t\temit(event) {\n\t\t\tif (event.type === 'data') {\n\t\t\t\tstdout.write(`${JSON.stringify(event.value)}\\n`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'progress') {\n\t\t\t\tif (isDue(progressThrottles, event.id)) {\n\t\t\t\t\twrite(event);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst throttle = progressThrottles.get(event.id);\n\n\t\t\t\tif (throttle) throttle.pending = event;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'status' && event.state === 'update') {\n\t\t\t\tif (isDue(updateThrottles, event.id)) write(event);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'status' && event.state !== 'start') {\n\t\t\t\tconst pending = progressThrottles.get(event.id)?.pending;\n\n\t\t\t\tif (pending) write(pending);\n\n\t\t\t\tprogressThrottles.delete(event.id);\n\t\t\t\tupdateThrottles.delete(event.id);\n\t\t\t}\n\n\t\t\twrite(event);\n\t\t},\n\t};\n}\n","const countFormat = new Intl.NumberFormat('en-CA');\n\nconst byteUnits = ['B', 'kB', 'MB', 'GB', 'TB'] as const;\n\nexport function formatCount(count: number) {\n\treturn countFormat.format(count);\n}\n\nexport function formatBytes(bytes: number) {\n\tlet value = bytes;\n\tlet unitIndex = 0;\n\n\twhile (value >= 1000 && unitIndex < byteUnits.length - 1) {\n\t\tvalue /= 1000;\n\t\tunitIndex += 1;\n\t}\n\n\tconst unit = byteUnits[unitIndex] ?? 'B';\n\n\treturn unitIndex === 0 ? `${String(value)} ${unit}` : `${value.toFixed(1)} ${unit}`;\n}\n\nexport function formatError(error: unknown) {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nexport function formatDuration(milliseconds: number) {\n\tconst seconds = milliseconds / 1000;\n\n\tif (seconds < 60) return `${seconds.toFixed(1)}s`;\n\n\tconst totalSeconds = Math.round(seconds);\n\tconst minutes = Math.floor(totalSeconds / 60);\n\tconst remainder = totalSeconds % 60;\n\n\treturn `${String(minutes)}m ${String(remainder).padStart(2, '0')}s`;\n}\n\nfunction formatRate(perSecond: number) {\n\treturn perSecond >= 10 ? formatCount(Math.round(perSecond)) : perSecond.toFixed(1);\n}\n\nexport interface ProgressSnapshot {\n\tdone: number;\n\tlabel: string;\n\tnote?: string;\n\tperSecond?: number;\n\ttotal: number;\n}\n\nexport function formatProgressText({ done, label, note, perSecond, total }: ProgressSnapshot) {\n\tconst percent = total === 0 ? 100 : Math.floor((done / total) * 100);\n\tconst parts = [`${label} ${formatCount(done)} / ${formatCount(total)} (${String(percent)}%)`];\n\tconst remaining = total - done;\n\n\tif (perSecond !== undefined && perSecond > 0) {\n\t\tparts.push(`${formatRate(perSecond)}/s`);\n\n\t\tif (remaining > 0) parts.push(`~${formatDuration((remaining / perSecond) * 1000)} left`);\n\t}\n\n\tif (note) parts.push(note);\n\n\treturn parts.join(' · ');\n}\n","import type { MessageLevel, OutputEvent, StatusState, SummaryRow } from './events.js';\n\nimport { formatCount, formatDuration } from './format.js';\n\ntype Paint = (text: string) => string;\n\nexport interface Palette {\n\tblue: Paint;\n\tgray: Paint;\n\tgreen: Paint;\n\tmagenta: Paint;\n\tred: Paint;\n\tyellow: Paint;\n}\n\ntype EndEvent = Extract<OutputEvent, { type: 'end' }>;\n\ntype TerminalState = Exclude<StatusState, 'start' | 'stop' | 'update'>;\n\nfunction unpainted(text: string) {\n\treturn text;\n}\n\nexport const plainPalette: Palette = {\n\tblue: unpainted,\n\tgray: unpainted,\n\tgreen: unpainted,\n\tmagenta: unpainted,\n\tred: unpainted,\n\tyellow: unpainted,\n};\n\nexport function getStateSymbol(state: TerminalState, palette: Palette) {\n\tif (state === 'succeed') return palette.green('✓');\n\tif (state === 'fail') return palette.red('✗');\n\n\treturn palette.yellow('⚠');\n}\n\nexport function formatMessage(level: MessageLevel, text: string, palette: Palette) {\n\tswitch (level) {\n\t\tcase 'detail': {\n\t\t\treturn palette.gray(` ${text}`);\n\t\t}\n\t\tcase 'error': {\n\t\t\treturn `${getStateSymbol('fail', palette)} ${palette.red(text)}`;\n\t\t}\n\t\tcase 'info': {\n\t\t\treturn text;\n\t\t}\n\t\tcase 'step': {\n\t\t\treturn palette.blue(text);\n\t\t}\n\t\tcase 'success': {\n\t\t\treturn `${getStateSymbol('succeed', palette)} ${text}`;\n\t\t}\n\t\tcase 'title': {\n\t\t\treturn palette.magenta(`=== ${text} ===`);\n\t\t}\n\t\tcase 'warn': {\n\t\t\treturn `${getStateSymbol('warn', palette)} ${palette.yellow(text)}`;\n\t\t}\n\t}\n}\n\nexport function formatSummaryRows(rows: Array<SummaryRow>, palette: Palette) {\n\tconst width = Math.max(...rows.map(([label]) => label.length)) + 2;\n\n\treturn rows.map(([label, value]) => {\n\t\tconst formatted = typeof value === 'number' ? formatCount(value) : value;\n\n\t\treturn ` ${palette.gray(`${label}:`.padEnd(width))}${formatted}`;\n\t});\n}\n\nexport function formatData(value: unknown) {\n\treturn typeof value === 'string' ? value : JSON.stringify(value, undefined, 2);\n}\n\nexport function formatEnd(event: EndEvent, palette: Palette) {\n\tif (event.status === 'ok') {\n\t\treturn [formatMessage('detail', `Finished in ${formatDuration(event.durationMs)}`, palette)];\n\t}\n\n\tconst level = event.status === 'failed' || event.forced ? 'error' : 'warn';\n\tconst lines = event.message === undefined ? [] : [formatMessage(level, event.message, palette)];\n\n\tif (event.detail) lines.push(formatMessage('detail', event.detail, palette));\n\n\treturn lines;\n}\n","import { stripVTControlCharacters } from 'node:util';\n\nimport type { Reporter, ReporterStreams } from './events.js';\n\nimport { formatProgressText } from './format.js';\nimport {\n\tformatData,\n\tformatEnd,\n\tformatMessage,\n\tformatSummaryRows,\n\tgetStateSymbol,\n\tplainPalette,\n} from './human-format.js';\n\ninterface OpenStatus {\n\tlastPrint: number;\n\ttext: string;\n}\n\nconst progressIntervalMs = 10_000;\n\nexport function createPlainReporter(\n\t{ stderr, stdout }: ReporterStreams,\n\tnow: () => number = Date.now,\n): Reporter {\n\tconst statuses = new Map<number, OpenStatus>();\n\tlet activeId: number | undefined;\n\n\tfunction writeLine(line: string) {\n\t\tstderr.write(`${stripVTControlCharacters(line)}\\n`);\n\t}\n\n\tfunction closeStatus(id: number) {\n\t\tstatuses.delete(id);\n\n\t\tif (activeId === id) activeId = undefined;\n\t}\n\n\treturn {\n\t\temit(event) {\n\t\t\tswitch (event.type) {\n\t\t\t\tcase 'data': {\n\t\t\t\t\tstdout.write(`${formatData(event.value)}\\n`);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'end': {\n\t\t\t\t\tconst active = activeId === undefined ? undefined : statuses.get(activeId);\n\n\t\t\t\t\tif (active && activeId !== undefined && event.status !== 'ok') {\n\t\t\t\t\t\twriteLine(`${getStateSymbol('fail', plainPalette)} ${active.text}`);\n\t\t\t\t\t\tcloseStatus(activeId);\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (const line of formatEnd(event, plainPalette)) writeLine(line);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'message': {\n\t\t\t\t\twriteLine(formatMessage(event.level, event.text, plainPalette));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'progress': {\n\t\t\t\t\tconst status = statuses.get(event.id);\n\t\t\t\t\tconst time = now();\n\n\t\t\t\t\tif (!status || time - status.lastPrint < progressIntervalMs) break;\n\n\t\t\t\t\tstatus.lastPrint = time;\n\t\t\t\t\twriteLine(formatProgressText(event));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'start': {\n\t\t\t\t\twriteLine(formatMessage('title', event.title, plainPalette));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'status': {\n\t\t\t\t\tconst { id, state, text } = event;\n\n\t\t\t\t\tif (state === 'start') {\n\t\t\t\t\t\tstatuses.set(id, { lastPrint: now(), text });\n\t\t\t\t\t\tactiveId = id;\n\t\t\t\t\t\twriteLine(text);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst status = statuses.get(id);\n\n\t\t\t\t\tif (!status) break;\n\n\t\t\t\t\tif (state === 'update') {\n\t\t\t\t\t\tstatus.text = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (state !== 'stop') writeLine(`${getStateSymbol(state, plainPalette)} ${text}`);\n\n\t\t\t\t\tcloseStatus(id);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'summary': {\n\t\t\t\t\tfor (const line of formatSummaryRows(event.rows, plainPalette)) writeLine(line);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n","import type { Ora } from 'ora';\n\nimport chalk from 'chalk';\nimport ora from 'ora';\n\nimport type { OutputEvent, Reporter, ReporterStreams, StatusState } from './events.js';\n\nimport { formatProgressText } from './format.js';\nimport {\n\tformatData,\n\tformatEnd,\n\tformatMessage,\n\tformatSummaryRows,\n\tgetStateSymbol,\n} from './human-format.js';\n\ntype StatusEvent = Extract<OutputEvent, { type: 'status' }>;\n\nexport function createPrettyReporter({ stderr, stdout }: ReporterStreams): Reporter {\n\tconst spinners = new Map<number, Ora>();\n\tlet activeId: number | undefined;\n\n\tfunction getActiveSpinner() {\n\t\treturn activeId === undefined ? undefined : spinners.get(activeId);\n\t}\n\n\tfunction writeLine(line: string) {\n\t\tconst active = getActiveSpinner();\n\n\t\tif (!active?.isSpinning) {\n\t\t\tstderr.write(`${line}\\n`);\n\t\t\treturn;\n\t\t}\n\n\t\tactive.clear();\n\t\tstderr.write(`${line}\\n`);\n\t\tactive.render();\n\t}\n\n\tfunction endSpinner(id: number, state: Exclude<StatusState, 'start' | 'update'>, text: string) {\n\t\tconst spinner = spinners.get(id);\n\n\t\tif (!spinner) return;\n\n\t\tif (state === 'stop') {\n\t\t\tspinner.stop();\n\t\t} else {\n\t\t\tspinner.stopAndPersist({ symbol: getStateSymbol(state, chalk), text });\n\t\t}\n\n\t\tspinners.delete(id);\n\n\t\tif (activeId === id) activeId = undefined;\n\t}\n\n\tfunction onStatus({ id, state, text }: StatusEvent) {\n\t\tif (state === 'start') {\n\t\t\tgetActiveSpinner()?.stop();\n\t\t\t// Stdin stays cooked so the terminal still signals the whole process group on Ctrl-C, child processes included\n\t\t\tspinners.set(id, ora({ discardStdin: false, stream: stderr, text }).start());\n\t\t\tactiveId = id;\n\t\t\treturn;\n\t\t}\n\n\t\tif (state === 'update') {\n\t\t\tconst spinner = spinners.get(id);\n\n\t\t\tif (spinner) spinner.text = text;\n\t\t\treturn;\n\t\t}\n\n\t\tendSpinner(id, state, text);\n\t}\n\n\treturn {\n\t\temit(event) {\n\t\t\tswitch (event.type) {\n\t\t\t\tcase 'data': {\n\t\t\t\t\tstdout.write(`${formatData(event.value)}\\n`);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'end': {\n\t\t\t\t\tconst active = getActiveSpinner();\n\n\t\t\t\t\tif (active && activeId !== undefined && event.status !== 'ok') {\n\t\t\t\t\t\tendSpinner(activeId, 'fail', active.text);\n\t\t\t\t\t}\n\n\t\t\t\t\t// An open spinner's render interval keeps the process alive\n\t\t\t\t\tfor (const spinner of spinners.values()) spinner.stop();\n\n\t\t\t\t\tspinners.clear();\n\t\t\t\t\tactiveId = undefined;\n\n\t\t\t\t\tfor (const line of formatEnd(event, chalk)) writeLine(line);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'message': {\n\t\t\t\t\twriteLine(formatMessage(event.level, event.text, chalk));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'progress': {\n\t\t\t\t\tconst spinner = spinners.get(event.id);\n\n\t\t\t\t\tif (spinner) spinner.text = formatProgressText(event);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'start': {\n\t\t\t\t\twriteLine(formatMessage('title', event.title, chalk));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'status': {\n\t\t\t\t\tonStatus(event);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'summary': {\n\t\t\t\t\tfor (const line of formatSummaryRows(event.rows, chalk)) writeLine(line);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n","import type { MessageLevel, OutputEvent, Reporter, SummaryRow } from './events.js';\n\nimport { createJsonReporter } from './reporter-json.js';\nimport { createPlainReporter } from './reporter-plain.js';\nimport { createPrettyReporter } from './reporter-pretty.js';\n\nexport type OutputMode = 'json' | 'plain' | 'pretty';\n\nconst outputModes = new Set<unknown>(['json', 'plain', 'pretty'] satisfies Array<OutputMode>);\n\nlet currentMode: OutputMode | undefined;\nlet currentReporter: Reporter | undefined;\nlet nextStatusId = 1;\n\nexport function isOutputMode(value: unknown): value is OutputMode {\n\treturn outputModes.has(value);\n}\n\nfunction detectOutputMode(): OutputMode {\n\tconst requested = process.env.SCRIPTS_OUTPUT;\n\n\tif (isOutputMode(requested)) return requested;\n\n\treturn process.stderr.isTTY ? 'pretty' : 'plain';\n}\n\nfunction createReporter(mode: OutputMode, command?: string) {\n\tconst streams = { stderr: process.stderr, stdout: process.stdout };\n\n\tif (mode === 'json') return createJsonReporter(streams, { command });\n\tif (mode === 'plain') return createPlainReporter(streams);\n\n\treturn createPrettyReporter(streams);\n}\n\nexport function configureOutput(mode: OutputMode = detectOutputMode(), command?: string) {\n\tcurrentMode = mode;\n\tcurrentReporter = createReporter(mode, command);\n}\n\nexport function getOutputMode() {\n\tif (currentMode === undefined) currentMode = detectOutputMode();\n\n\treturn currentMode;\n}\n\nexport function emit(event: OutputEvent) {\n\tif (currentReporter === undefined) currentReporter = createReporter(getOutputMode());\n\n\tcurrentReporter.emit(event);\n}\n\nfunction emitMessage(level: MessageLevel, text: string) {\n\temit({ level, text, type: 'message' });\n}\n\nexport const log = {\n\tdata(value: unknown) {\n\t\temit({ type: 'data', value });\n\t},\n\tdetail(text: string) {\n\t\temitMessage('detail', text);\n\t},\n\terror(text: string) {\n\t\temitMessage('error', text);\n\t},\n\tinfo(text: string) {\n\t\temitMessage('info', text);\n\t},\n\tstep(text: string) {\n\t\temitMessage('step', text);\n\t},\n\tsuccess(text: string) {\n\t\temitMessage('success', text);\n\t},\n\tsummary(rows: Array<SummaryRow>) {\n\t\temit({ rows, type: 'summary' });\n\t},\n\ttitle(text: string) {\n\t\temitMessage('title', text);\n\t},\n\twarn(text: string) {\n\t\temitMessage('warn', text);\n\t},\n};\n\nexport function startStatus(initialText: string) {\n\tconst id = nextStatusId;\n\tlet text = initialText;\n\n\tnextStatusId += 1;\n\temit({ id, state: 'start', text, type: 'status' });\n\n\tfunction finish(state: 'fail' | 'stop' | 'succeed' | 'warn', finalText?: string) {\n\t\ttext = finalText ?? text;\n\t\temit({ id, state, text, type: 'status' });\n\t}\n\n\tconst status = {\n\t\tfail(finalText?: string) {\n\t\t\tfinish('fail', finalText);\n\t\t},\n\t\tstop() {\n\t\t\tfinish('stop');\n\t\t},\n\t\tsucceed(finalText?: string) {\n\t\t\tfinish('succeed', finalText);\n\t\t},\n\t\tupdate(nextText: string) {\n\t\t\ttext = nextText;\n\t\t\temit({ id, state: 'update', text, type: 'status' });\n\t\t},\n\t\twarn(finalText?: string) {\n\t\t\tfinish('warn', finalText);\n\t\t},\n\t};\n\n\treturn { id, status };\n}\n\nexport function createStatus(text: string) {\n\treturn startStatus(text).status;\n}\n","// Matched by `name`, so a library's own `Refusal` class reports the same way\nexport class Refusal extends Error {\n\toverride name = 'Refusal';\n}\n\nexport function isRefusal(error: unknown): error is Error {\n\treturn error instanceof Error && error.name === 'Refusal';\n}\n","import { existsSync } from 'node:fs';\nimport path from 'node:path';\n\nexport function findWorkspaceRoot(startDir = process.cwd()) {\n\tlet current = path.resolve(startDir);\n\n\twhile (current !== path.dirname(current)) {\n\t\tif (existsSync(path.join(current, 'pnpm-workspace.yaml'))) return current;\n\n\t\tcurrent = path.dirname(current);\n\t}\n\n\tthrow new Error(`Could not locate pnpm-workspace.yaml above ${startDir}`);\n}\n","import type { ParseArgsOptionDescriptor } from 'node:util';\n\nimport chalk from 'chalk';\nimport { parseArgs } from 'node:util';\n\nimport { configureOutput, emit, isOutputMode, log } from './output/output.js';\nimport { isRefusal, Refusal } from './refusal.js';\nimport { findWorkspaceRoot } from './workspace.js';\n\ntype CommandOption = ParseArgsOptionDescriptor & { description: string };\n\ntype CommandOptions = Record<string, CommandOption>;\n\ninterface CommandPositional {\n\tdescription: string;\n\tname: string;\n}\n\ntype ParsedValues<Options extends CommandOptions> = ReturnType<\n\ttypeof parseArgs<{ allowPositionals: true; options: Options; strict: true }>\n>['values'];\n\ninterface CommandDescription {\n\tname: string;\n\toptions?: CommandOptions;\n\tpositional?: CommandPositional;\n\tsummary: string;\n\ttitle: string;\n}\n\nexport interface CommandContext<Options extends CommandOptions> {\n\tpositionals: Array<string>;\n\trootPath: string;\n\tsignal: AbortSignal;\n\tvalues: ParsedValues<Options>;\n}\n\nexport interface Command<Options extends CommandOptions, Context> extends CommandDescription {\n\tinterrupted?: string;\n\toptions?: Options;\n\trun: (context: CommandContext<Options> & Context) => Promise<void> | void;\n}\n\ninterface CommandRunnerOptions<Context> {\n\tcontext?: (base: { rootPath: string }) => Context | Promise<Context>;\n\tusagePrefix?: string;\n}\n\ninterface ChildProcessFailure extends Error {\n\texitCode: null | number | undefined;\n\tsignal: null | string | undefined;\n}\n\ninterface FailureReport {\n\tdetail?: string;\n\texitCode: number;\n\tisInterrupted: boolean;\n\tmessage: string;\n}\n\nconst interruptedExitCode = 130;\nconst interruptBurstMs = 1000;\n\nconst jsonOption = {\n\tdescription: 'Print output as JSON lines',\n\ttype: 'boolean',\n} as const satisfies CommandOption;\n\nconst helpOption = {\n\tdescription: 'Show this help',\n\tshort: 'h',\n\ttype: 'boolean',\n} as const satisfies CommandOption;\n\nconst builtInOptions: Array<[string, CommandOption]> = [\n\t['json', jsonOption],\n\t['help', helpOption],\n];\n\nexport function parseNumberOption(value: string, name: string) {\n\tconst parsed = Number(value);\n\n\tif (value.trim() === '' || !Number.isFinite(parsed))\n\t\tthrow new Refusal(`--${name} expects a number, got \"${value}\"`);\n\n\treturn parsed;\n}\n\nfunction getUsage(command: CommandDescription, usagePrefix: string) {\n\tconst positional = command.positional ? ` [${command.positional.name}]` : '';\n\n\treturn `${usagePrefix} ${command.name}${positional} [options]`;\n}\n\nfunction getOptionLabel(name: string, option: CommandOption) {\n\tconst flag = option.short ? `-${option.short}, --${name}` : ` --${name}`;\n\n\treturn option.type === 'string' ? `${flag} <value>` : flag;\n}\n\nfunction getOptionDescription(option: CommandOption) {\n\tconst { default: defaultValue, description } = option;\n\n\tif (defaultValue === undefined || defaultValue === false) return description;\n\tif (Array.isArray(defaultValue) && defaultValue.length === 0) return description;\n\n\treturn `${description} (default: ${String(defaultValue)})`;\n}\n\nexport function formatHelp(command: CommandDescription, usagePrefix = 'pnpm') {\n\tconst options = [...Object.entries(command.options ?? {}), ...builtInOptions];\n\tconst rows: Array<[string, string]> = options.map(([name, option]) => [\n\t\tgetOptionLabel(name, option),\n\t\tgetOptionDescription(option),\n\t]);\n\n\tif (command.positional) {\n\t\trows.unshift([command.positional.name, command.positional.description]);\n\t}\n\n\tconst width = Math.max(...rows.map(([label]) => label.length)) + 2;\n\n\treturn [\n\t\tchalk.magenta(command.title),\n\t\tcommand.summary,\n\t\t'',\n\t\t`Usage: ${getUsage(command, usagePrefix)}`,\n\t\t'',\n\t\t...rows.map(([label, description]) => ` ${label.padEnd(width)}${chalk.gray(description)}`),\n\t].join('\\n');\n}\n\nfunction isParseError(error: unknown): error is Error {\n\treturn (\n\t\terror instanceof Error &&\n\t\t'code' in error &&\n\t\ttypeof error.code === 'string' &&\n\t\terror.code.startsWith('ERR_PARSE_ARGS_')\n\t);\n}\n\n// Matched by shape, which covers zx's `ProcessOutput` and execa's `ExecaError` alike\nfunction isChildProcessFailure(error: unknown): error is ChildProcessFailure {\n\treturn error instanceof Error && 'exitCode' in error && 'signal' in error;\n}\n\nfunction isInterruption(error: unknown, isAborted: boolean) {\n\tif (isAborted) return true;\n\n\treturn (\n\t\tisChildProcessFailure(error) &&\n\t\t(error.exitCode === interruptedExitCode || error.signal === 'SIGINT')\n\t);\n}\n\nfunction describeError(error: unknown): Pick<FailureReport, 'detail' | 'message'> {\n\tif (isParseError(error)) return { detail: 'See --help', message: error.message };\n\n\tif (isRefusal(error)) return { message: error.message };\n\n\tif (isChildProcessFailure(error)) {\n\t\tconst reason = error.signal\n\t\t\t? `was killed by ${error.signal}`\n\t\t\t: `exited with code ${String(error.exitCode)}`;\n\n\t\treturn { message: `Child process ${reason}` };\n\t}\n\n\tif (!(error instanceof Error)) return { message: String(error) };\n\n\tconst stack = error.stack?.split('\\n').slice(1).join('\\n');\n\n\treturn stack ? { detail: stack, message: error.message } : { message: error.message };\n}\n\nexport function getFailureReport(\n\terror: unknown,\n\t{ interrupted, isAborted }: { interrupted?: string | undefined; isAborted: boolean },\n): FailureReport {\n\tif (isInterruption(error, isAborted)) {\n\t\treturn {\n\t\t\texitCode: interruptedExitCode,\n\t\t\tisInterrupted: true,\n\t\t\tmessage: interrupted ? `Interrupted; ${interrupted}` : 'Interrupted',\n\t\t};\n\t}\n\n\treturn { exitCode: 1, isInterrupted: false, ...describeError(error) };\n}\n\nfunction parseCommandArgs(command: CommandDescription) {\n\tconst options = [...Object.entries(command.options ?? {}), ...builtInOptions];\n\n\treturn parseArgs({\n\t\tallowPositionals: command.positional !== undefined,\n\t\targs: process.argv.slice(2),\n\t\toptions: Object.fromEntries(\n\t\t\toptions.map(([name, { description: _description, ...descriptor }]) => [name, descriptor]),\n\t\t),\n\t\tstrict: true,\n\t});\n}\n\nfunction selectOutput(isJson: boolean) {\n\tif (isJson) {\n\t\t// Nested commands inherit this and join one stream\n\t\tprocess.env.SCRIPTS_OUTPUT = 'json';\n\t\treturn;\n\t}\n\n\tconst requested = process.env.SCRIPTS_OUTPUT;\n\n\tif (requested && !isOutputMode(requested)) {\n\t\tthrow new Refusal(`SCRIPTS_OUTPUT must be pretty, plain or json, got \"${requested}\"`);\n\t}\n}\n\nexport function createCommandRunner<Context extends object = object>(\n\trunnerOptions: CommandRunnerOptions<Context> = {},\n) {\n\tconst { context: createContext, usagePrefix = 'pnpm' } = runnerOptions;\n\n\tfunction defineCommand<const Options extends CommandOptions>(command: Command<Options, Context>) {\n\t\treturn command;\n\t}\n\n\tasync function runCommand<const Options extends CommandOptions>(\n\t\tcommand: Command<Options, Context>,\n\t) {\n\t\tconst controller = new AbortController();\n\t\tconst startTime = Date.now();\n\t\tlet interruptTime: number | undefined;\n\t\t// Read before parsing, so a parse error in a `--json` run still reports as JSON\n\t\tconst isJson = process.argv.slice(2).includes('--json');\n\n\t\tconfigureOutput(isJson ? 'json' : undefined, command.name);\n\n\t\t// One Ctrl-C arrives as a burst: the terminal's SIGINT, pnpm's forwarded copy, and a SIGTERM per nested pnpm\n\t\tfunction onInterrupt() {\n\t\t\tif (interruptTime === undefined) {\n\t\t\t\tinterruptTime = Date.now();\n\t\t\t\tcontroller.abort();\n\t\t\t\tlog.warn('Stopping; press Ctrl-C again to force quit');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (Date.now() - interruptTime < interruptBurstMs) return;\n\n\t\t\temit({\n\t\t\t\tdurationMs: Date.now() - startTime,\n\t\t\t\texitCode: interruptedExitCode,\n\t\t\t\tforced: true,\n\t\t\t\tmessage: 'Force quit',\n\t\t\t\tstatus: 'interrupted',\n\t\t\t\ttype: 'end',\n\t\t\t});\n\t\t\t// eslint-disable-next-line unicorn/no-process-exit -- a second Ctrl-C must quit even while the command still holds the event loop\n\t\t\tprocess.exit(interruptedExitCode);\n\t\t}\n\n\t\tprocess.on('SIGINT', onInterrupt);\n\t\tprocess.on('SIGTERM', onInterrupt);\n\n\t\ttry {\n\t\t\tconst { positionals, values } = parseCommandArgs(command);\n\n\t\t\tif (values.help) {\n\t\t\t\tprocess.stdout.write(`${formatHelp(command, usagePrefix)}\\n`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tselectOutput(isJson);\n\t\t\temit({ title: command.title, type: 'start' });\n\n\t\t\tconst rootPath = findWorkspaceRoot();\n\t\t\t// `Context` is only left at its empty default when no factory is given\n\t\t\tconst context = createContext ? await createContext({ rootPath }) : ({} as Context);\n\n\t\t\tawait command.run({\n\t\t\t\t...context,\n\t\t\t\tpositionals,\n\t\t\t\trootPath,\n\t\t\t\tsignal: controller.signal,\n\t\t\t\tvalues: values as ParsedValues<Options>,\n\t\t\t});\n\n\t\t\t// A command that honours the signal by returning early was still interrupted\n\t\t\tcontroller.signal.throwIfAborted();\n\n\t\t\temit({ durationMs: Date.now() - startTime, exitCode: 0, status: 'ok', type: 'end' });\n\t\t} catch (error) {\n\t\t\tconst report = getFailureReport(error, {\n\t\t\t\tinterrupted: command.interrupted,\n\t\t\t\tisAborted: controller.signal.aborted,\n\t\t\t});\n\n\t\t\temit({\n\t\t\t\t...(report.detail === undefined ? {} : { detail: report.detail }),\n\t\t\t\tdurationMs: Date.now() - startTime,\n\t\t\t\texitCode: report.exitCode,\n\t\t\t\tmessage: report.message,\n\t\t\t\tstatus: report.isInterrupted ? 'interrupted' : 'failed',\n\t\t\t\ttype: 'end',\n\t\t\t});\n\n\t\t\tprocess.exitCode = report.exitCode;\n\t\t} finally {\n\t\t\tprocess.off('SIGINT', onInterrupt);\n\t\t\tprocess.off('SIGTERM', onInterrupt);\n\t\t}\n\t}\n\n\treturn { defineCommand, runCommand };\n}\n","import type { ProgressSnapshot } from './format.js';\n\nimport { formatProgressText } from './format.js';\nimport { createStatus, emit, startStatus } from './output.js';\n\ninterface ProgressOptions {\n\tlabel: string;\n\tnote?: () => string;\n\ttotal: number;\n}\n\ninterface RateSample {\n\tcount: number;\n\ttime: number;\n}\n\nconst renderIntervalMs = 100;\nconst rateWindowMs = 10_000;\n\nexport function createRateWindow(windowMs = rateWindowMs) {\n\tconst samples: Array<RateSample> = [];\n\n\treturn {\n\t\tadd(count: number, time: number) {\n\t\t\tsamples.push({ count, time });\n\n\t\t\twhile (samples.length > 2 && time - (samples[0]?.time ?? time) > windowMs) samples.shift();\n\t\t},\n\t\tperSecond() {\n\t\t\tconst first = samples.at(0);\n\t\t\tconst last = samples.at(-1);\n\n\t\t\tif (!first || !last || last.time <= first.time) return;\n\n\t\t\treturn ((last.count - first.count) * 1000) / (last.time - first.time);\n\t\t},\n\t};\n}\n\nexport function createProgress({ label, note, total }: ProgressOptions) {\n\tconst rateWindow = createRateWindow();\n\tconst startTime = Date.now();\n\tlet done = 0;\n\tlet lastRender = 0;\n\n\trateWindow.add(0, startTime);\n\n\tfunction getSnapshot(): ProgressSnapshot {\n\t\tconst noteText = note?.();\n\t\tconst perSecond = rateWindow.perSecond();\n\n\t\treturn {\n\t\t\tdone,\n\t\t\tlabel,\n\t\t\ttotal,\n\t\t\t...(noteText ? { note: noteText } : {}),\n\t\t\t...(perSecond === undefined ? {} : { perSecond }),\n\t\t};\n\t}\n\n\tconst { id, status } = startStatus(formatProgressText(getSnapshot()));\n\n\tfunction render() {\n\t\tconst now = Date.now();\n\n\t\tif (now - lastRender < renderIntervalMs) return;\n\n\t\tlastRender = now;\n\t\trateWindow.add(done, now);\n\t\temit({ id, type: 'progress', ...getSnapshot() });\n\t}\n\n\tfunction finish(state: 'fail' | 'succeed' | 'warn', text?: string) {\n\t\tconst snapshot = getSnapshot();\n\n\t\temit({ id, type: 'progress', ...snapshot });\n\t\tstatus[state](text ?? formatProgressText(snapshot));\n\t}\n\n\treturn {\n\t\tfail(text?: string) {\n\t\t\tfinish('fail', text);\n\t\t},\n\t\tsucceed(text?: string) {\n\t\t\tfinish('succeed', text);\n\t\t},\n\t\ttick(count = 1) {\n\t\t\tdone += count;\n\t\t\trender();\n\t\t},\n\t\twarn(text?: string) {\n\t\t\tfinish('warn', text);\n\t\t},\n\t};\n}\n\n// A failure leaves the status open for `runCommand` to mark as failed\nexport async function withStatus<Result>(text: string, task: () => Promise<Result>) {\n\tconst status = createStatus(text);\n\tconst result = await task();\n\n\tstatus.stop();\n\n\treturn result;\n}\n\nexport async function withSpinner<Result>(\n\ttext: string,\n\ttask: () => Promise<Result>,\n\tdescribe?: (result: Result) => string,\n) {\n\tconst status = createStatus(text);\n\n\ttry {\n\t\tconst result = await task();\n\n\t\tstatus.succeed(describe?.(result) ?? text);\n\n\t\treturn result;\n\t} catch (error) {\n\t\tstatus.fail(text);\n\t\tthrow error;\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/user-error.ts","../src/astro.ts","../src/output/reporter-json.ts","../src/output/format.ts","../src/output/human-format.ts","../src/output/reporter-plain.ts","../src/output/reporter-pretty.ts","../src/output/output.ts","../src/workspace.ts","../src/command.ts","../src/output/progress.ts"],"sourcesContent":["// Matched by `name`, so a library's own `UserError` class reports the same way\nexport class UserError extends Error {\n\tdetail?: string;\n\toverride name = 'UserError';\n\n\tconstructor(message: string, options?: ErrorOptions & { detail?: string }) {\n\t\tsuper(message, options);\n\n\t\tif (options?.detail !== undefined) this.detail = options.detail;\n\t}\n}\n\nexport function isUserError(error: unknown): error is Error & { detail?: unknown } {\n\treturn error instanceof Error && error.name === 'UserError';\n}\n","import type * as AstroContentModule from 'astro:content';\nimport type { CollectionEntry, CollectionKey } from 'astro:content';\nimport type { ModuleRunner } from 'vite/module-runner';\n\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\n\nimport { UserError } from './user-error.js';\n\ntype AstroContent = typeof AstroContentModule;\n\n// Mirrors Astro's own `configPaths`; it does not accept the CommonJS variants\nconst configFilenames = [\n\t'astro.config.mjs',\n\t'astro.config.js',\n\t'astro.config.ts',\n\t'astro.config.mts',\n];\n\n// Every `CollectionEntry` must satisfy this\nexport interface ContentEntry {\n\tbody?: string | undefined;\n\tcollection: string;\n\tdata: Record<string, unknown>;\n\t// Astro widens this to `string | number`; file-based collections only ever write a string\n\tdigest?: number | string | undefined;\n\tfilePath?: string | undefined;\n\tid: string;\n}\n\nexport function findAstroRoot(startDir = process.cwd()) {\n\tlet current = path.resolve(startDir);\n\n\twhile (current !== path.dirname(current)) {\n\t\tconst hasConfig = configFilenames.some((filename) => existsSync(path.join(current, filename)));\n\n\t\tif (hasConfig) return current;\n\n\t\tcurrent = path.dirname(current);\n\t}\n\n\tthrow new UserError(`Could not locate an Astro config above ${startDir}`);\n}\n\n// Annotated so the declaration keeps the consumer's `CollectionEntry`; inferred, it bakes in the unsynced `any`\nexport async function getCollectionEntries<C extends CollectionKey>(\n\t{ getCollection }: AstroContent,\n\tcollections: Array<C>,\n): Promise<Array<CollectionEntry<C>>> {\n\tconst entries = await Promise.all(\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- unsynced here, `getCollection` is the stub's `any`; a consumer's is typed\n\t\tcollections.map((collection) => getCollection(collection)),\n\t);\n\tconst flattened = entries.flat();\n\n\tif (flattened.length === 0) {\n\t\tthrow new UserError(\n\t\t\t`No entries found in: ${collections.join(', ')}. Run \\`astro sync\\` to write the content store.`,\n\t\t);\n\t}\n\n\treturn flattened;\n}\n\nexport async function withAstroModules<T>(callback: (runner: ModuleRunner) => Promise<T>) {\n\t// An unrooted config resolves against `process.cwd()`, finds none, and reads every collection back empty\n\tconst root = findAstroRoot();\n\tconst [{ getViteConfig }, { createLogger, createServer, createServerModuleRunner }] =\n\t\tawait Promise.all([import('astro/config'), import('vite')]);\n\n\tconst config = await getViteConfig(\n\t\t{},\n\t\t{ logLevel: 'silent', root },\n\t)({\n\t\tcommand: 'serve',\n\t\tmode: 'development',\n\t});\n\n\tconst server = await createServer({\n\t\t...config,\n\t\t// Astro's config sets a `customLogger` that writes to stdout and ignores `logLevel`\n\t\tcustomLogger: createLogger('silent'),\n\t\tlogLevel: 'silent',\n\t\tserver: { hmr: false, middlewareMode: true, ws: false },\n\t});\n\n\ttry {\n\t\treturn await callback(createServerModuleRunner(server.environments.ssr));\n\t} finally {\n\t\t// The process hangs on the open server otherwise\n\t\tawait server.close();\n\t}\n}\n\nexport async function withAstroContent<T>(callback: (content: AstroContent) => Promise<T>) {\n\treturn withAstroModules(async (runner) =>\n\t\tcallback(await runner.import<AstroContent>('astro:content')),\n\t);\n}\n","import { stripVTControlCharacters } from 'node:util';\n\nimport type { OutputEvent, Reporter, ReporterStreams } from './events.js';\n\ntype ProgressEvent = Extract<OutputEvent, { type: 'progress' }>;\n\ninterface JsonReporterOptions {\n\tcommand?: string | undefined;\n\tnow?: () => number;\n}\n\ninterface Throttle {\n\tlastSent: number;\n\tpending?: ProgressEvent;\n}\n\nconst throttleMs = 1000;\n\nfunction strip(text: string): string;\nfunction strip(text: string | undefined): string | undefined;\nfunction strip(text: string | undefined) {\n\treturn text === undefined ? undefined : stripVTControlCharacters(text);\n}\n\nfunction stripEvent(event: OutputEvent): OutputEvent {\n\tswitch (event.type) {\n\t\tcase 'data': {\n\t\t\treturn event;\n\t\t}\n\t\tcase 'end': {\n\t\t\tconst { detail, message, ...rest } = event;\n\n\t\t\treturn {\n\t\t\t\t...rest,\n\t\t\t\t...(detail === undefined ? {} : { detail: strip(detail) }),\n\t\t\t\t...(message === undefined ? {} : { message: strip(message) }),\n\t\t\t};\n\t\t}\n\t\tcase 'message':\n\t\tcase 'status': {\n\t\t\treturn { ...event, text: strip(event.text) };\n\t\t}\n\t\tcase 'progress': {\n\t\t\tconst { note, ...rest } = event;\n\n\t\t\treturn { ...rest, label: strip(event.label), ...(note ? { note: strip(note) } : {}) };\n\t\t}\n\t\tcase 'start': {\n\t\t\treturn { ...event, title: strip(event.title) };\n\t\t}\n\t\tcase 'summary': {\n\t\t\treturn {\n\t\t\t\t...event,\n\t\t\t\trows: event.rows.map(([label, value]) => [\n\t\t\t\t\tstrip(label),\n\t\t\t\t\ttypeof value === 'string' ? strip(value) : value,\n\t\t\t\t]),\n\t\t\t};\n\t\t}\n\t}\n}\n\nexport function createJsonReporter(\n\t{ stderr, stdout }: ReporterStreams,\n\t{ command, now = Date.now }: JsonReporterOptions = {},\n): Reporter {\n\tconst progressThrottles = new Map<number, Throttle>();\n\tconst updateThrottles = new Map<number, Throttle>();\n\n\tfunction write(event: OutputEvent) {\n\t\tconst { type, ...payload } = stripEvent(event);\n\t\tconst envelope = { command, time: new Date(now()).toISOString() };\n\n\t\tstderr.write(`${JSON.stringify({ type, ...envelope, ...payload })}\\n`);\n\t}\n\n\tfunction isDue(throttles: Map<number, Throttle>, id: number) {\n\t\tconst time = now();\n\t\tconst throttle = throttles.get(id);\n\n\t\tif (throttle && time - throttle.lastSent < throttleMs) return false;\n\n\t\tthrottles.set(id, { lastSent: time });\n\n\t\treturn true;\n\t}\n\n\treturn {\n\t\temit(event) {\n\t\t\tif (event.type === 'data') {\n\t\t\t\tstdout.write(`${JSON.stringify(event.value)}\\n`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'progress') {\n\t\t\t\tif (isDue(progressThrottles, event.id)) {\n\t\t\t\t\twrite(event);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst throttle = progressThrottles.get(event.id);\n\n\t\t\t\tif (throttle) throttle.pending = event;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'status' && event.state === 'update') {\n\t\t\t\tif (isDue(updateThrottles, event.id)) write(event);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'status' && event.state !== 'start') {\n\t\t\t\tconst pending = progressThrottles.get(event.id)?.pending;\n\n\t\t\t\tif (pending) write(pending);\n\n\t\t\t\tprogressThrottles.delete(event.id);\n\t\t\t\tupdateThrottles.delete(event.id);\n\t\t\t}\n\n\t\t\twrite(event);\n\t\t},\n\t};\n}\n","const countFormat = new Intl.NumberFormat('en-CA');\n\nconst byteUnits = ['B', 'kB', 'MB', 'GB', 'TB'] as const;\n\nexport function formatCount(count: number) {\n\treturn countFormat.format(count);\n}\n\nexport function formatBytes(bytes: number) {\n\tlet value = bytes;\n\tlet unitIndex = 0;\n\n\twhile (value >= 1000 && unitIndex < byteUnits.length - 1) {\n\t\tvalue /= 1000;\n\t\tunitIndex += 1;\n\t}\n\n\tconst unit = byteUnits[unitIndex] ?? 'B';\n\n\treturn unitIndex === 0 ? `${String(value)} ${unit}` : `${value.toFixed(1)} ${unit}`;\n}\n\nexport function formatError(error: unknown) {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nexport function formatDuration(milliseconds: number) {\n\tconst seconds = milliseconds / 1000;\n\n\tif (seconds < 60) return `${seconds.toFixed(1)}s`;\n\n\tconst totalSeconds = Math.round(seconds);\n\tconst minutes = Math.floor(totalSeconds / 60);\n\tconst remainder = totalSeconds % 60;\n\n\treturn `${String(minutes)}m ${String(remainder).padStart(2, '0')}s`;\n}\n\nfunction formatRate(perSecond: number) {\n\treturn perSecond >= 10 ? formatCount(Math.round(perSecond)) : perSecond.toFixed(1);\n}\n\nexport interface ProgressSnapshot {\n\tdone: number;\n\tlabel: string;\n\tnote?: string;\n\tperSecond?: number;\n\ttotal: number;\n}\n\nexport function formatProgressText({ done, label, note, perSecond, total }: ProgressSnapshot) {\n\tconst percent = total === 0 ? 100 : Math.floor((done / total) * 100);\n\tconst parts = [`${label} ${formatCount(done)} / ${formatCount(total)} (${String(percent)}%)`];\n\tconst remaining = total - done;\n\n\tif (perSecond !== undefined && perSecond > 0) {\n\t\tparts.push(`${formatRate(perSecond)}/s`);\n\n\t\tif (remaining > 0) parts.push(`~${formatDuration((remaining / perSecond) * 1000)} left`);\n\t}\n\n\tif (note) parts.push(note);\n\n\treturn parts.join(' · ');\n}\n","import type { MessageLevel, OutputEvent, StatusState, SummaryRow } from './events.js';\n\nimport { formatCount, formatDuration } from './format.js';\n\ntype Paint = (text: string) => string;\n\nexport interface Palette {\n\tblue: Paint;\n\tgray: Paint;\n\tgreen: Paint;\n\tmagenta: Paint;\n\tred: Paint;\n\tyellow: Paint;\n}\n\ntype EndEvent = Extract<OutputEvent, { type: 'end' }>;\n\ntype TerminalState = Exclude<StatusState, 'start' | 'stop' | 'update'>;\n\nfunction unpainted(text: string) {\n\treturn text;\n}\n\nexport const plainPalette: Palette = {\n\tblue: unpainted,\n\tgray: unpainted,\n\tgreen: unpainted,\n\tmagenta: unpainted,\n\tred: unpainted,\n\tyellow: unpainted,\n};\n\nexport function getStateSymbol(state: TerminalState, palette: Palette) {\n\tif (state === 'succeed') return palette.green('✓');\n\tif (state === 'fail') return palette.red('✗');\n\n\treturn palette.yellow('⚠');\n}\n\nexport function formatMessage(level: MessageLevel, text: string, palette: Palette) {\n\tswitch (level) {\n\t\tcase 'detail': {\n\t\t\treturn palette.gray(\n\t\t\t\ttext\n\t\t\t\t\t.split('\\n')\n\t\t\t\t\t.map((line) => ` ${line}`)\n\t\t\t\t\t.join('\\n'),\n\t\t\t);\n\t\t}\n\t\tcase 'error': {\n\t\t\treturn `${getStateSymbol('fail', palette)} ${palette.red(text)}`;\n\t\t}\n\t\tcase 'info': {\n\t\t\treturn text;\n\t\t}\n\t\tcase 'step': {\n\t\t\treturn palette.blue(text);\n\t\t}\n\t\tcase 'success': {\n\t\t\treturn `${getStateSymbol('succeed', palette)} ${text}`;\n\t\t}\n\t\tcase 'title': {\n\t\t\treturn palette.magenta(`=== ${text} ===`);\n\t\t}\n\t\tcase 'warn': {\n\t\t\treturn `${getStateSymbol('warn', palette)} ${palette.yellow(text)}`;\n\t\t}\n\t}\n}\n\nexport function formatSummaryRows(rows: Array<SummaryRow>, palette: Palette) {\n\tconst width = Math.max(...rows.map(([label]) => label.length)) + 2;\n\n\treturn rows.map(([label, value]) => {\n\t\tconst formatted = typeof value === 'number' ? formatCount(value) : value;\n\n\t\treturn ` ${palette.gray(`${label}:`.padEnd(width))}${formatted}`;\n\t});\n}\n\nexport function formatData(value: unknown) {\n\treturn typeof value === 'string' ? value : JSON.stringify(value, undefined, 2);\n}\n\nexport function formatEnd(event: EndEvent, palette: Palette) {\n\tif (event.status === 'ok') {\n\t\treturn [formatMessage('detail', `Finished in ${formatDuration(event.durationMs)}`, palette)];\n\t}\n\n\tconst level = event.status === 'failed' || event.forced ? 'error' : 'warn';\n\tconst lines = event.message === undefined ? [] : [formatMessage(level, event.message, palette)];\n\n\tif (event.detail) lines.push(formatMessage('detail', event.detail, palette));\n\n\treturn lines;\n}\n","import { stripVTControlCharacters } from 'node:util';\n\nimport type { Reporter, ReporterStreams } from './events.js';\n\nimport { formatProgressText } from './format.js';\nimport {\n\tformatData,\n\tformatEnd,\n\tformatMessage,\n\tformatSummaryRows,\n\tgetStateSymbol,\n\tplainPalette,\n} from './human-format.js';\n\ninterface OpenStatus {\n\tlastPrint: number;\n\ttext: string;\n}\n\nconst progressIntervalMs = 10_000;\n\nexport function createPlainReporter(\n\t{ stderr, stdout }: ReporterStreams,\n\tnow: () => number = Date.now,\n): Reporter {\n\tconst statuses = new Map<number, OpenStatus>();\n\tconst openIds: Array<number> = [];\n\n\tfunction writeLine(line: string) {\n\t\tstderr.write(`${stripVTControlCharacters(line)}\\n`);\n\t}\n\n\tfunction closeStatus(id: number) {\n\t\tstatuses.delete(id);\n\t\topenIds.splice(openIds.indexOf(id), 1);\n\t}\n\n\treturn {\n\t\temit(event) {\n\t\t\tswitch (event.type) {\n\t\t\t\tcase 'data': {\n\t\t\t\t\tconst line =\n\t\t\t\t\t\tevent.render === undefined\n\t\t\t\t\t\t\t? formatData(event.value)\n\t\t\t\t\t\t\t: stripVTControlCharacters(event.render());\n\n\t\t\t\t\tstdout.write(`${line}\\n`);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'end': {\n\t\t\t\t\tconst activeId = openIds.at(-1);\n\t\t\t\t\tconst active = activeId === undefined ? undefined : statuses.get(activeId);\n\n\t\t\t\t\tif (active && event.status !== 'ok') {\n\t\t\t\t\t\twriteLine(`${getStateSymbol('fail', plainPalette)} ${active.text}`);\n\t\t\t\t\t}\n\n\t\t\t\t\tstatuses.clear();\n\t\t\t\t\topenIds.length = 0;\n\n\t\t\t\t\tfor (const line of formatEnd(event, plainPalette)) writeLine(line);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'message': {\n\t\t\t\t\twriteLine(formatMessage(event.level, event.text, plainPalette));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'progress': {\n\t\t\t\t\tconst status = statuses.get(event.id);\n\t\t\t\t\tconst time = now();\n\n\t\t\t\t\tif (!status || time - status.lastPrint < progressIntervalMs) break;\n\n\t\t\t\t\tstatus.lastPrint = time;\n\t\t\t\t\twriteLine(formatProgressText(event));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'start': {\n\t\t\t\t\twriteLine(formatMessage('title', event.title, plainPalette));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'status': {\n\t\t\t\t\tconst { id, state, text } = event;\n\n\t\t\t\t\tif (state === 'start') {\n\t\t\t\t\t\tstatuses.set(id, { lastPrint: now(), text });\n\t\t\t\t\t\topenIds.push(id);\n\t\t\t\t\t\twriteLine(text);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst status = statuses.get(id);\n\n\t\t\t\t\tif (!status) break;\n\n\t\t\t\t\tif (state === 'update') {\n\t\t\t\t\t\tstatus.text = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (state !== 'stop') writeLine(`${getStateSymbol(state, plainPalette)} ${text}`);\n\n\t\t\t\t\tcloseStatus(id);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'summary': {\n\t\t\t\t\tfor (const line of formatSummaryRows(event.rows, plainPalette)) writeLine(line);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n","import type { Ora } from 'ora';\n\nimport chalk from 'chalk';\nimport ora from 'ora';\n\nimport type { OutputEvent, Reporter, ReporterStreams, StatusState } from './events.js';\n\nimport { formatProgressText } from './format.js';\nimport {\n\tformatData,\n\tformatEnd,\n\tformatMessage,\n\tformatSummaryRows,\n\tgetStateSymbol,\n} from './human-format.js';\n\ntype StatusEvent = Extract<OutputEvent, { type: 'status' }>;\n\nfunction isTerminal(stream: NodeJS.WritableStream) {\n\treturn 'isTTY' in stream && stream.isTTY === true;\n}\n\nexport function createPrettyReporter({ stderr, stdout }: ReporterStreams): Reporter {\n\tconst spinners = new Map<number, Ora>();\n\tconst openIds: Array<number> = [];\n\n\tfunction getActiveSpinner() {\n\t\tconst activeId = openIds.at(-1);\n\n\t\treturn activeId === undefined ? undefined : spinners.get(activeId);\n\t}\n\n\tfunction writeAround(stream: NodeJS.WritableStream, line: string) {\n\t\tconst active = getActiveSpinner();\n\n\t\tif (!active?.isSpinning) {\n\t\t\tstream.write(`${line}\\n`);\n\t\t\treturn;\n\t\t}\n\n\t\tactive.clear();\n\t\tstream.write(`${line}\\n`);\n\t\tactive.render();\n\t}\n\n\tfunction writeLine(line: string) {\n\t\twriteAround(stderr, line);\n\t}\n\n\tfunction endSpinner(id: number, state: Exclude<StatusState, 'start' | 'update'>, text: string) {\n\t\tconst spinner = spinners.get(id);\n\n\t\tif (!spinner) return;\n\n\t\tconst wasActive = openIds.at(-1) === id;\n\n\t\tif (state === 'stop') {\n\t\t\tspinner.stop();\n\t\t} else {\n\t\t\tspinner.stopAndPersist({ symbol: getStateSymbol(state, chalk), text });\n\t\t}\n\n\t\tspinners.delete(id);\n\t\topenIds.splice(openIds.indexOf(id), 1);\n\n\t\tconst outer = getActiveSpinner();\n\n\t\tif (wasActive && outer?.isEnabled) outer.start();\n\t}\n\n\tfunction onStatus({ id, state, text }: StatusEvent) {\n\t\tif (state === 'start') {\n\t\t\tgetActiveSpinner()?.stop();\n\t\t\t// Stdin stays cooked so the terminal still signals the whole process group on Ctrl-C, child processes included\n\t\t\tspinners.set(id, ora({ discardStdin: false, stream: stderr, text }).start());\n\t\t\topenIds.push(id);\n\t\t\treturn;\n\t\t}\n\n\t\tif (state === 'update') {\n\t\t\tconst spinner = spinners.get(id);\n\n\t\t\tif (spinner) spinner.text = text;\n\t\t\treturn;\n\t\t}\n\n\t\tendSpinner(id, state, text);\n\t}\n\n\treturn {\n\t\temit(event) {\n\t\t\tswitch (event.type) {\n\t\t\t\tcase 'data': {\n\t\t\t\t\tconst line = event.render?.() ?? formatData(event.value);\n\n\t\t\t\t\tif (isTerminal(stdout)) {\n\t\t\t\t\t\twriteAround(stdout, line);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstdout.write(`${line}\\n`);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'end': {\n\t\t\t\t\tconst activeId = openIds.at(-1);\n\t\t\t\t\tconst active = getActiveSpinner();\n\n\t\t\t\t\tif (active && activeId !== undefined && event.status !== 'ok') {\n\t\t\t\t\t\tspinners.delete(activeId);\n\t\t\t\t\t\tactive.stopAndPersist({ symbol: getStateSymbol('fail', chalk), text: active.text });\n\t\t\t\t\t}\n\n\t\t\t\t\t// An open spinner's render interval keeps the process alive\n\t\t\t\t\tfor (const spinner of spinners.values()) spinner.stop();\n\n\t\t\t\t\tspinners.clear();\n\t\t\t\t\topenIds.length = 0;\n\n\t\t\t\t\tfor (const line of formatEnd(event, chalk)) writeLine(line);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'message': {\n\t\t\t\t\twriteLine(formatMessage(event.level, event.text, chalk));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'progress': {\n\t\t\t\t\tconst spinner = spinners.get(event.id);\n\n\t\t\t\t\tif (spinner) spinner.text = formatProgressText(event);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'start': {\n\t\t\t\t\twriteLine(formatMessage('title', event.title, chalk));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'status': {\n\t\t\t\t\tonStatus(event);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'summary': {\n\t\t\t\t\tfor (const line of formatSummaryRows(event.rows, chalk)) writeLine(line);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n","import type { MessageLevel, OutputEvent, Reporter, SummaryRow } from './events.js';\n\nimport { createJsonReporter } from './reporter-json.js';\nimport { createPlainReporter } from './reporter-plain.js';\nimport { createPrettyReporter } from './reporter-pretty.js';\n\nexport type OutputMode = 'json' | 'plain' | 'pretty';\n\nconst outputModes = new Set<unknown>(['json', 'plain', 'pretty'] satisfies Array<OutputMode>);\n\nlet currentMode: OutputMode | undefined;\nlet currentReporter: Reporter | undefined;\nlet capturingReporter: Reporter | undefined;\nlet nextStatusId = 1;\n\nexport function isOutputMode(value: unknown): value is OutputMode {\n\treturn outputModes.has(value);\n}\n\nfunction detectOutputMode(): OutputMode {\n\tconst requested = process.env.SCRIPTS_OUTPUT;\n\n\tif (isOutputMode(requested)) return requested;\n\n\treturn process.stderr.isTTY ? 'pretty' : 'plain';\n}\n\nfunction createReporter(mode: OutputMode, command?: string) {\n\tconst streams = { stderr: process.stderr, stdout: process.stdout };\n\n\tif (mode === 'json') return createJsonReporter(streams, { command });\n\tif (mode === 'plain') return createPlainReporter(streams);\n\n\treturn createPrettyReporter(streams);\n}\n\nexport function configureOutput(mode: OutputMode = detectOutputMode(), command?: string) {\n\tcurrentMode = mode;\n\tcurrentReporter = createReporter(mode, command);\n}\n\nexport function getOutputMode() {\n\tif (currentMode === undefined) currentMode = detectOutputMode();\n\n\treturn currentMode;\n}\n\nexport function emit(event: OutputEvent) {\n\tif (capturingReporter) {\n\t\tcapturingReporter.emit(event);\n\t\treturn;\n\t}\n\n\tif (currentReporter === undefined) currentReporter = createReporter(getOutputMode());\n\n\tcurrentReporter.emit(event);\n}\n\nexport async function captureOutput<Result>(task: () => Promise<Result> | Result) {\n\tconst events: Array<OutputEvent> = [];\n\tconst previous = capturingReporter;\n\n\tcapturingReporter = {\n\t\temit(event) {\n\t\t\tevents.push(event);\n\t\t},\n\t};\n\n\ttry {\n\t\tconst result = await task();\n\n\t\treturn { events, result };\n\t} finally {\n\t\tcapturingReporter = previous;\n\t}\n}\n\nfunction emitMessage(level: MessageLevel, text: string) {\n\temit({ level, text, type: 'message' });\n}\n\nexport const log = {\n\tdata<Value>(value: Value, format?: (value: Value) => string) {\n\t\temit(format ? { render: () => format(value), type: 'data', value } : { type: 'data', value });\n\t},\n\tdetail(text: string) {\n\t\temitMessage('detail', text);\n\t},\n\terror(text: string) {\n\t\temitMessage('error', text);\n\t},\n\tinfo(text: string) {\n\t\temitMessage('info', text);\n\t},\n\tstep(text: string) {\n\t\temitMessage('step', text);\n\t},\n\tsuccess(text: string) {\n\t\temitMessage('success', text);\n\t},\n\tsummary(rows: Array<SummaryRow>) {\n\t\temit({ rows, type: 'summary' });\n\t},\n\ttitle(text: string) {\n\t\temitMessage('title', text);\n\t},\n\twarn(text: string) {\n\t\temitMessage('warn', text);\n\t},\n};\n\nexport function startStatus(initialText: string) {\n\tconst id = nextStatusId;\n\tlet text = initialText;\n\n\tnextStatusId += 1;\n\temit({ id, state: 'start', text, type: 'status' });\n\n\tfunction finish(state: 'fail' | 'stop' | 'succeed' | 'warn', finalText?: string) {\n\t\ttext = finalText ?? text;\n\t\temit({ id, state, text, type: 'status' });\n\t}\n\n\tconst status = {\n\t\tfail(finalText?: string) {\n\t\t\tfinish('fail', finalText);\n\t\t},\n\t\tstop() {\n\t\t\tfinish('stop');\n\t\t},\n\t\tsucceed(finalText?: string) {\n\t\t\tfinish('succeed', finalText);\n\t\t},\n\t\tupdate(nextText: string) {\n\t\t\ttext = nextText;\n\t\t\temit({ id, state: 'update', text, type: 'status' });\n\t\t},\n\t\twarn(finalText?: string) {\n\t\t\tfinish('warn', finalText);\n\t\t},\n\t};\n\n\treturn { id, status };\n}\n\nexport function createStatus(text: string) {\n\treturn startStatus(text).status;\n}\n","import { existsSync } from 'node:fs';\nimport path from 'node:path';\n\nimport { UserError } from './user-error.js';\n\nexport function findWorkspaceRoot(startDir = process.cwd()) {\n\tlet current = path.resolve(startDir);\n\n\twhile (current !== path.dirname(current)) {\n\t\tif (existsSync(path.join(current, 'pnpm-workspace.yaml'))) return current;\n\n\t\tcurrent = path.dirname(current);\n\t}\n\n\tthrow new UserError(`Could not locate pnpm-workspace.yaml above ${startDir}`);\n}\n","import type { ParseArgsOptionDescriptor } from 'node:util';\n\nimport chalk from 'chalk';\nimport { parseArgs } from 'node:util';\n\nimport { configureOutput, emit, getOutputMode, isOutputMode, log } from './output/output.js';\nimport { isUserError, UserError } from './user-error.js';\nimport { findWorkspaceRoot } from './workspace.js';\n\ntype CommandOption = ParseArgsOptionDescriptor & { description: string };\n\ntype CommandOptions = Record<string, CommandOption>;\n\ninterface CommandPositional {\n\tdescription: string;\n\tname: string;\n}\n\ntype ParsedValues<Options extends CommandOptions> = ReturnType<\n\ttypeof parseArgs<{ allowPositionals: true; options: Options; strict: true }>\n>['values'];\n\ninterface CommandDescription {\n\tname: string;\n\toptions?: CommandOptions;\n\tpositional?: CommandPositional;\n\tsummary: string;\n\ttitle: string;\n}\n\nexport interface CommandContext<Options extends CommandOptions> {\n\tpositionals: Array<string>;\n\trootPath: string;\n\tsignal: AbortSignal;\n\tvalues: ParsedValues<Options>;\n}\n\nexport interface Command<Options extends CommandOptions, Context> extends CommandDescription {\n\tinterrupted?: string;\n\toptions?: Options;\n\trun: (context: CommandContext<Options> & Context) => Promise<void> | void;\n}\n\ninterface CommandRunnerOptions<Context> {\n\tcontext?: (base: { rootPath: string }) => Context | Promise<Context>;\n\tusagePrefix?: string;\n}\n\ninterface ChildProcessFailure extends Error {\n\texitCode: null | number | undefined;\n\tsignal: null | string | undefined;\n\tstderr?: unknown;\n}\n\ninterface FailureReport {\n\tdetail?: string;\n\texitCode: number;\n\tisInterrupted: boolean;\n\tmessage: string;\n}\n\nconst interruptedExitCode = 130;\nconst interruptBurstMs = 1000;\nconst stderrTailLines = 20;\n\nconst jsonOption = {\n\tdescription: 'Print output as JSON lines',\n\ttype: 'boolean',\n} as const satisfies CommandOption;\n\nconst helpOption = {\n\tdescription: 'Show this help',\n\tshort: 'h',\n\ttype: 'boolean',\n} as const satisfies CommandOption;\n\nconst builtInOptions: Array<[string, CommandOption]> = [\n\t['json', jsonOption],\n\t['help', helpOption],\n];\n\nexport function parseNumberOption(value: string, name: string) {\n\tconst parsed = Number(value);\n\n\tif (value.trim() === '' || !Number.isFinite(parsed))\n\t\tthrow new UserError(`--${name} expects a number, got \"${value}\"`);\n\n\treturn parsed;\n}\n\nfunction getUsage(command: CommandDescription, usagePrefix: string) {\n\tconst positional = command.positional ? ` [${command.positional.name}]` : '';\n\n\treturn `${usagePrefix} ${command.name}${positional} [options]`;\n}\n\nfunction getOptionLabel(name: string, option: CommandOption) {\n\tconst flag = option.short ? `-${option.short}, --${name}` : ` --${name}`;\n\n\treturn option.type === 'string' ? `${flag} <value>` : flag;\n}\n\nfunction getOptionDescription(option: CommandOption) {\n\tconst { default: defaultValue, description } = option;\n\n\tif (defaultValue === undefined || defaultValue === false) return description;\n\tif (Array.isArray(defaultValue) && defaultValue.length === 0) return description;\n\n\treturn `${description} (default: ${String(defaultValue)})`;\n}\n\nexport function formatHelp(command: CommandDescription, usagePrefix = 'pnpm') {\n\tconst options = [...Object.entries(command.options ?? {}), ...builtInOptions];\n\tconst rows: Array<[string, string]> = options.map(([name, option]) => [\n\t\tgetOptionLabel(name, option),\n\t\tgetOptionDescription(option),\n\t]);\n\n\tif (command.positional) {\n\t\trows.unshift([command.positional.name, command.positional.description]);\n\t}\n\n\tconst width = Math.max(...rows.map(([label]) => label.length)) + 2;\n\n\treturn [\n\t\tchalk.magenta(command.title),\n\t\tcommand.summary,\n\t\t'',\n\t\t`Usage: ${getUsage(command, usagePrefix)}`,\n\t\t'',\n\t\t...rows.map(([label, description]) => ` ${label.padEnd(width)}${chalk.gray(description)}`),\n\t].join('\\n');\n}\n\nfunction isParseError(error: unknown): error is Error {\n\treturn (\n\t\terror instanceof Error &&\n\t\t'code' in error &&\n\t\ttypeof error.code === 'string' &&\n\t\terror.code.startsWith('ERR_PARSE_ARGS_')\n\t);\n}\n\n// Matched by shape, which covers zx's `ProcessOutput` and execa's `ExecaError` alike\nfunction isChildProcessFailure(error: unknown): error is ChildProcessFailure {\n\treturn error instanceof Error && 'exitCode' in error && 'signal' in error;\n}\n\nfunction isInterruption(error: unknown, isAborted: boolean) {\n\tif (isAborted) return true;\n\n\treturn (\n\t\tisChildProcessFailure(error) &&\n\t\t(error.exitCode === interruptedExitCode || error.signal === 'SIGINT')\n\t);\n}\n\nfunction describeError(error: unknown): Pick<FailureReport, 'detail' | 'message'> {\n\tif (isParseError(error)) return { detail: 'See --help', message: error.message };\n\n\tif (isUserError(error)) {\n\t\tconst { detail, message } = error;\n\n\t\treturn typeof detail === 'string' && detail !== '' ? { detail, message } : { message };\n\t}\n\n\tif (isChildProcessFailure(error)) {\n\t\tconst reason = error.signal\n\t\t\t? `was killed by ${error.signal}`\n\t\t\t: `exited with code ${String(error.exitCode)}`;\n\n\t\tconst message = `Child process ${reason}`;\n\t\tconst stderr = typeof error.stderr === 'string' ? error.stderr.trimEnd() : '';\n\n\t\tif (stderr === '') return { message };\n\n\t\treturn { detail: stderr.split('\\n').slice(-stderrTailLines).join('\\n'), message };\n\t}\n\n\tif (!(error instanceof Error)) return { message: String(error) };\n\n\tconst stack = error.stack?.split('\\n').slice(1).join('\\n');\n\n\treturn stack ? { detail: stack, message: error.message } : { message: error.message };\n}\n\nexport function getFailureReport(\n\terror: unknown,\n\t{ interrupted, isAborted }: { interrupted?: string | undefined; isAborted: boolean },\n): FailureReport {\n\tif (isInterruption(error, isAborted)) {\n\t\treturn {\n\t\t\texitCode: interruptedExitCode,\n\t\t\tisInterrupted: true,\n\t\t\tmessage: interrupted ? `Interrupted; ${interrupted}` : 'Interrupted',\n\t\t};\n\t}\n\n\treturn { exitCode: 1, isInterrupted: false, ...describeError(error) };\n}\n\nfunction parseCommandArgs(command: CommandDescription) {\n\tconst options = [...Object.entries(command.options ?? {}), ...builtInOptions];\n\n\treturn parseArgs({\n\t\tallowPositionals: command.positional !== undefined,\n\t\targs: process.argv.slice(2),\n\t\toptions: Object.fromEntries(\n\t\t\toptions.map(([name, { description: _description, ...descriptor }]) => [name, descriptor]),\n\t\t),\n\t\tstrict: true,\n\t});\n}\n\nfunction selectOutput(isJson: boolean) {\n\tif (isJson) {\n\t\t// Nested commands inherit this and join one stream\n\t\tprocess.env.SCRIPTS_OUTPUT = 'json';\n\t\treturn;\n\t}\n\n\tconst requested = process.env.SCRIPTS_OUTPUT;\n\n\tif (requested && !isOutputMode(requested)) {\n\t\tthrow new UserError(`SCRIPTS_OUTPUT must be pretty, plain or json, got \"${requested}\"`);\n\t}\n}\n\nexport function createCommandRunner<Context extends object = object>(\n\trunnerOptions: CommandRunnerOptions<Context> = {},\n) {\n\tconst { context: createContext, usagePrefix = 'pnpm' } = runnerOptions;\n\n\tfunction defineCommand<const Options extends CommandOptions>(command: Command<Options, Context>) {\n\t\treturn command;\n\t}\n\n\tasync function runCommand<const Options extends CommandOptions>(\n\t\tcommand: Command<Options, Context>,\n\t) {\n\t\tconst controller = new AbortController();\n\t\tconst startTime = Date.now();\n\t\tlet interruptTime: number | undefined;\n\t\t// Read before parsing, so a parse error in a `--json` run still reports as JSON\n\t\tconst args = process.argv.slice(2);\n\t\tconst separator = args.indexOf('--');\n\t\tconst isJson = (separator === -1 ? args : args.slice(0, separator)).includes('--json');\n\n\t\tconfigureOutput(isJson ? 'json' : undefined, command.name);\n\n\t\t// One Ctrl-C arrives as a burst: the terminal's SIGINT, pnpm's forwarded copy, and a SIGTERM per nested pnpm\n\t\tfunction onInterrupt() {\n\t\t\tif (interruptTime === undefined) {\n\t\t\t\tinterruptTime = Date.now();\n\t\t\t\tcontroller.abort();\n\t\t\t\tlog.warn('Stopping; press Ctrl-C again to force quit');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (Date.now() - interruptTime < interruptBurstMs) return;\n\n\t\t\temit({\n\t\t\t\tdurationMs: Date.now() - startTime,\n\t\t\t\texitCode: interruptedExitCode,\n\t\t\t\tforced: true,\n\t\t\t\tmessage: 'Force quit',\n\t\t\t\tstatus: 'interrupted',\n\t\t\t\ttype: 'end',\n\t\t\t});\n\t\t\t// eslint-disable-next-line unicorn/no-process-exit -- a second Ctrl-C must quit even while the command still holds the event loop\n\t\t\tprocess.exit(interruptedExitCode);\n\t\t}\n\n\t\tprocess.on('SIGINT', onInterrupt);\n\t\tprocess.on('SIGTERM', onInterrupt);\n\n\t\tlet hasStarted = false;\n\n\t\ttry {\n\t\t\tconst { positionals, values } = parseCommandArgs(command);\n\n\t\t\tif (values.help) {\n\t\t\t\tprocess.stdout.write(`${formatHelp(command, usagePrefix)}\\n`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tselectOutput(isJson);\n\t\t\temit({ title: command.title, type: 'start' });\n\t\t\thasStarted = true;\n\n\t\t\tconst rootPath = findWorkspaceRoot();\n\t\t\t// `Context` is only left at its empty default when no factory is given\n\t\t\tconst context = createContext ? await createContext({ rootPath }) : ({} as Context);\n\n\t\t\tawait command.run({\n\t\t\t\t...context,\n\t\t\t\tpositionals,\n\t\t\t\trootPath,\n\t\t\t\tsignal: controller.signal,\n\t\t\t\tvalues: values as ParsedValues<Options>,\n\t\t\t});\n\n\t\t\t// A command that honours the signal by returning early was still interrupted\n\t\t\tcontroller.signal.throwIfAborted();\n\n\t\t\temit({ durationMs: Date.now() - startTime, exitCode: 0, status: 'ok', type: 'end' });\n\t\t} catch (error) {\n\t\t\tif (!hasStarted && getOutputMode() === 'json') emit({ title: command.title, type: 'start' });\n\n\t\t\tconst report = getFailureReport(error, {\n\t\t\t\tinterrupted: command.interrupted,\n\t\t\t\tisAborted: controller.signal.aborted,\n\t\t\t});\n\n\t\t\temit({\n\t\t\t\t...(report.detail === undefined ? {} : { detail: report.detail }),\n\t\t\t\tdurationMs: Date.now() - startTime,\n\t\t\t\texitCode: report.exitCode,\n\t\t\t\tmessage: report.message,\n\t\t\t\tstatus: report.isInterrupted ? 'interrupted' : 'failed',\n\t\t\t\ttype: 'end',\n\t\t\t});\n\n\t\t\tprocess.exitCode = report.exitCode;\n\t\t} finally {\n\t\t\tprocess.off('SIGINT', onInterrupt);\n\t\t\tprocess.off('SIGTERM', onInterrupt);\n\t\t}\n\t}\n\n\treturn { defineCommand, runCommand };\n}\n","import type { ProgressSnapshot } from './format.js';\n\nimport { formatProgressText } from './format.js';\nimport { createStatus, emit, startStatus } from './output.js';\n\ninterface ProgressOptions {\n\tlabel: string;\n\tnote?: () => string;\n\ttotal: number;\n}\n\ninterface RateSample {\n\tcount: number;\n\ttime: number;\n}\n\nconst renderIntervalMs = 100;\nconst rateWindowMs = 10_000;\n\nexport function createRateWindow(windowMs = rateWindowMs) {\n\tconst samples: Array<RateSample> = [];\n\n\treturn {\n\t\tadd(count: number, time: number) {\n\t\t\tsamples.push({ count, time });\n\n\t\t\twhile (samples.length > 2 && time - (samples[0]?.time ?? time) > windowMs) samples.shift();\n\t\t},\n\t\tperSecond() {\n\t\t\tconst first = samples.at(0);\n\t\t\tconst last = samples.at(-1);\n\n\t\t\tif (!first || !last || last.time <= first.time) return;\n\n\t\t\treturn ((last.count - first.count) * 1000) / (last.time - first.time);\n\t\t},\n\t};\n}\n\nexport function createProgress({ label, note, total }: ProgressOptions) {\n\tconst rateWindow = createRateWindow();\n\tconst startTime = Date.now();\n\tlet done = 0;\n\tlet lastRender = 0;\n\n\trateWindow.add(0, startTime);\n\n\tfunction getSnapshot(): ProgressSnapshot {\n\t\tconst noteText = note?.();\n\t\tconst perSecond = rateWindow.perSecond();\n\n\t\treturn {\n\t\t\tdone,\n\t\t\tlabel,\n\t\t\ttotal,\n\t\t\t...(noteText ? { note: noteText } : {}),\n\t\t\t...(perSecond === undefined ? {} : { perSecond }),\n\t\t};\n\t}\n\n\tconst { id, status } = startStatus(formatProgressText(getSnapshot()));\n\n\tfunction render() {\n\t\tconst now = Date.now();\n\n\t\tif (now - lastRender < renderIntervalMs) return;\n\n\t\tlastRender = now;\n\t\trateWindow.add(done, now);\n\t\temit({ id, type: 'progress', ...getSnapshot() });\n\t}\n\n\tfunction finish(state: 'fail' | 'succeed' | 'warn', text?: string) {\n\t\tconst snapshot = getSnapshot();\n\n\t\temit({ id, type: 'progress', ...snapshot });\n\t\tstatus[state](text ?? formatProgressText(snapshot));\n\t}\n\n\treturn {\n\t\tfail(text?: string) {\n\t\t\tfinish('fail', text);\n\t\t},\n\t\tsucceed(text?: string) {\n\t\t\tfinish('succeed', text);\n\t\t},\n\t\ttick(count = 1) {\n\t\t\tdone += count;\n\t\t\trender();\n\t\t},\n\t\twarn(text?: string) {\n\t\t\tfinish('warn', text);\n\t\t},\n\t};\n}\n\n// A failure leaves the status open for `runCommand` to mark as failed\nexport async function withStatus<Result>(text: string, task: () => Promise<Result>) {\n\tconst status = createStatus(text);\n\tconst result = await task();\n\n\tstatus.stop();\n\n\treturn result;\n}\n\nexport async function withSpinner<Result>(\n\ttext: string,\n\ttask: () => Promise<Result>,\n\tdescribe?: (result: Result) => string,\n) {\n\tconst status = createStatus(text);\n\n\ttry {\n\t\tconst result = await task();\n\n\t\tstatus.succeed(describe?.(result) ?? text);\n\n\t\treturn result;\n\t} catch (error) {\n\t\tstatus.fail(text);\n\t\tthrow error;\n\t}\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsynaptic/astro-scripts",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Plumbing for an Astro project's scripts package: a command runner, output with interchangeable reporters, and a bridge into Astro's content layer",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -28,10 +28,6 @@
28
28
  ".": {
29
29
  "types": "./dist/index.d.mts",
30
30
  "import": "./dist/index.mjs"
31
- },
32
- "./astro": {
33
- "types": "./dist/astro.d.mts",
34
- "import": "./dist/astro.mjs"
35
31
  }
36
32
  },
37
33
  "files": [
package/dist/astro.d.mts DELETED
@@ -1,20 +0,0 @@
1
- import * as AstroContentModule from "astro:content";
2
- import { CollectionEntry, CollectionKey } from "astro:content";
3
- import { ModuleRunner } from "vite/module-runner";
4
- //#region src/astro.d.ts
5
- type AstroContent = typeof AstroContentModule;
6
- export interface ContentEntry {
7
- body?: string | undefined;
8
- collection: string;
9
- data: Record<string, unknown>;
10
- digest?: number | string | undefined;
11
- filePath?: string | undefined;
12
- id: string;
13
- }
14
- export declare function findAstroRoot(startDir?: string): string;
15
- export declare function getCollectionEntries<C extends CollectionKey>({ getCollection }: AstroContent, collections: Array<C>): Promise<Array<CollectionEntry<C>>>;
16
- export declare function withAstroModules<T>(callback: (runner: ModuleRunner) => Promise<T>): Promise<T>;
17
- export declare function withAstroContent<T>(callback: (content: AstroContent) => Promise<T>): Promise<T>;
18
- //#endregion
19
- export {};
20
- //# sourceMappingURL=astro.d.mts.map
package/dist/astro.mjs DELETED
@@ -1,56 +0,0 @@
1
- import { existsSync } from "node:fs";
2
- import path from "node:path";
3
- import { getViteConfig } from "astro/config";
4
- import { createLogger, createServer, createServerModuleRunner } from "vite";
5
- //#region src/astro.ts
6
- const configFilenames = [
7
- "astro.config.mjs",
8
- "astro.config.js",
9
- "astro.config.ts",
10
- "astro.config.mts"
11
- ];
12
- function findAstroRoot(startDir = process.cwd()) {
13
- let current = path.resolve(startDir);
14
- while (current !== path.dirname(current)) {
15
- if (configFilenames.some((filename) => existsSync(path.join(current, filename)))) return current;
16
- current = path.dirname(current);
17
- }
18
- throw new Error(`Could not locate an Astro config above ${startDir}`);
19
- }
20
- async function getCollectionEntries({ getCollection }, collections) {
21
- const flattened = (await Promise.all(collections.map((collection) => getCollection(collection)))).flat();
22
- if (flattened.length === 0) throw new Error(`No entries found in: ${collections.join(", ")}. Run \`astro sync\` to write the content store.`);
23
- return flattened;
24
- }
25
- async function withAstroModules(callback) {
26
- const root = findAstroRoot();
27
- const config = await getViteConfig({}, {
28
- logLevel: "silent",
29
- root
30
- })({
31
- command: "serve",
32
- mode: "development"
33
- });
34
- const server = await createServer({
35
- ...config,
36
- customLogger: createLogger("silent"),
37
- logLevel: "silent",
38
- server: {
39
- hmr: false,
40
- middlewareMode: true,
41
- ws: false
42
- }
43
- });
44
- try {
45
- return await callback(createServerModuleRunner(server.environments.ssr));
46
- } finally {
47
- await server.close();
48
- }
49
- }
50
- async function withAstroContent(callback) {
51
- return withAstroModules(async (runner) => callback(await runner.import("astro:content")));
52
- }
53
- //#endregion
54
- export { findAstroRoot, getCollectionEntries, withAstroContent, withAstroModules };
55
-
56
- //# sourceMappingURL=astro.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"astro.mjs","names":[],"sources":["../src/astro.ts"],"sourcesContent":["import type * as AstroContentModule from 'astro:content';\nimport type { CollectionEntry, CollectionKey } from 'astro:content';\nimport type { ModuleRunner } from 'vite/module-runner';\n\nimport { getViteConfig } from 'astro/config';\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { createLogger, createServer, createServerModuleRunner } from 'vite';\n\ntype AstroContent = typeof AstroContentModule;\n\n// Mirrors Astro's own `configPaths`; it does not accept the CommonJS variants\nconst configFilenames = [\n\t'astro.config.mjs',\n\t'astro.config.js',\n\t'astro.config.ts',\n\t'astro.config.mts',\n];\n\n// Every `CollectionEntry` must satisfy this\nexport interface ContentEntry {\n\tbody?: string | undefined;\n\tcollection: string;\n\tdata: Record<string, unknown>;\n\t// Astro widens this to `string | number`; file-based collections only ever write a string\n\tdigest?: number | string | undefined;\n\tfilePath?: string | undefined;\n\tid: string;\n}\n\nexport function findAstroRoot(startDir = process.cwd()) {\n\tlet current = path.resolve(startDir);\n\n\twhile (current !== path.dirname(current)) {\n\t\tconst hasConfig = configFilenames.some((filename) => existsSync(path.join(current, filename)));\n\n\t\tif (hasConfig) return current;\n\n\t\tcurrent = path.dirname(current);\n\t}\n\n\tthrow new Error(`Could not locate an Astro config above ${startDir}`);\n}\n\n// Annotated so the declaration keeps the consumer's `CollectionEntry`; inferred, it bakes in the unsynced `any`\nexport async function getCollectionEntries<C extends CollectionKey>(\n\t{ getCollection }: AstroContent,\n\tcollections: Array<C>,\n): Promise<Array<CollectionEntry<C>>> {\n\tconst entries = await Promise.all(\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- unsynced here, `getCollection` is the stub's `any`; a consumer's is typed\n\t\tcollections.map((collection) => getCollection(collection)),\n\t);\n\tconst flattened = entries.flat();\n\n\tif (flattened.length === 0) {\n\t\tthrow new Error(\n\t\t\t`No entries found in: ${collections.join(', ')}. Run \\`astro sync\\` to write the content store.`,\n\t\t);\n\t}\n\n\treturn flattened;\n}\n\nexport async function withAstroModules<T>(callback: (runner: ModuleRunner) => Promise<T>) {\n\t// An unrooted config resolves against `process.cwd()`, finds none, and reads every collection back empty\n\tconst root = findAstroRoot();\n\n\tconst config = await getViteConfig(\n\t\t{},\n\t\t{ logLevel: 'silent', root },\n\t)({\n\t\tcommand: 'serve',\n\t\tmode: 'development',\n\t});\n\n\tconst server = await createServer({\n\t\t...config,\n\t\t// Astro's config sets a `customLogger` that writes to stdout and ignores `logLevel`\n\t\tcustomLogger: createLogger('silent'),\n\t\tlogLevel: 'silent',\n\t\tserver: { hmr: false, middlewareMode: true, ws: false },\n\t});\n\n\ttry {\n\t\treturn await callback(createServerModuleRunner(server.environments.ssr));\n\t} finally {\n\t\t// The process hangs on the open server otherwise\n\t\tawait server.close();\n\t}\n}\n\nexport async function withAstroContent<T>(callback: (content: AstroContent) => Promise<T>) {\n\treturn withAstroModules(async (runner) =>\n\t\tcallback(await runner.import<AstroContent>('astro:content')),\n\t);\n}\n"],"mappings":";;;;;AAYA,MAAM,kBAAkB;CACvB;CACA;CACA;CACA;AACD;AAaA,SAAgB,cAAc,WAAW,QAAQ,IAAI,GAAG;CACvD,IAAI,UAAU,KAAK,QAAQ,QAAQ;CAEnC,OAAO,YAAY,KAAK,QAAQ,OAAO,GAAG;EAGzC,IAFkB,gBAAgB,MAAM,aAAa,WAAW,KAAK,KAAK,SAAS,QAAQ,CAAC,CAEhF,GAAG,OAAO;EAEtB,UAAU,KAAK,QAAQ,OAAO;CAC/B;CAEA,MAAM,IAAI,MAAM,0CAA0C,UAAU;AACrE;AAGA,eAAsB,qBACrB,EAAE,iBACF,aACqC;CAKrC,MAAM,aAAY,MAJI,QAAQ,IAE7B,YAAY,KAAK,eAAe,cAAc,UAAU,CAAC,CAC1D,EAAA,CAC0B,KAAK;CAE/B,IAAI,UAAU,WAAW,GACxB,MAAM,IAAI,MACT,wBAAwB,YAAY,KAAK,IAAI,EAAE,iDAChD;CAGD,OAAO;AACR;AAEA,eAAsB,iBAAoB,UAAgD;CAEzF,MAAM,OAAO,cAAc;CAE3B,MAAM,SAAS,MAAM,cACpB,CAAC,GACD;EAAE,UAAU;EAAU;CAAK,CAC5B,CAAC,CAAC;EACD,SAAS;EACT,MAAM;CACP,CAAC;CAED,MAAM,SAAS,MAAM,aAAa;EACjC,GAAG;EAEH,cAAc,aAAa,QAAQ;EACnC,UAAU;EACV,QAAQ;GAAE,KAAK;GAAO,gBAAgB;GAAM,IAAI;EAAM;CACvD,CAAC;CAED,IAAI;EACH,OAAO,MAAM,SAAS,yBAAyB,OAAO,aAAa,GAAG,CAAC;CACxE,UAAU;EAET,MAAM,OAAO,MAAM;CACpB;AACD;AAEA,eAAsB,iBAAoB,UAAiD;CAC1F,OAAO,iBAAiB,OAAO,WAC9B,SAAS,MAAM,OAAO,OAAqB,eAAe,CAAC,CAC5D;AACD"}