@xsynaptic/astro-scripts 0.1.0 → 0.2.0

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,9 @@ 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 -s`, or pnpm's own banner lines land in the stream.
32
+
33
+ `withAstroModules` and `withAstroContent` load `astro` and `vite` only when called, and need a content store written by `astro sync`.
28
34
 
29
35
  ## License
30
36
 
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
+ text?: 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,13 @@ 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 {
94
164
  name: string;
95
165
  }
96
166
  //#endregion
97
167
  //#region src/workspace.d.ts
98
168
  export declare function findWorkspaceRoot(startDir?: string): string;
99
169
  //#endregion
100
- export type { Command, CommandContext, OutputMode };
170
+ export type { Command, CommandContext, ContentEntry, OutputEvent, OutputMode };
101
171
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,8 +1,65 @@
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
+ name = "UserError";
9
+ };
10
+ function isUserError(error) {
11
+ return error instanceof Error && error.name === "UserError";
12
+ }
13
+ //#endregion
14
+ //#region src/astro.ts
15
+ const configFilenames = [
16
+ "astro.config.mjs",
17
+ "astro.config.js",
18
+ "astro.config.ts",
19
+ "astro.config.mts"
20
+ ];
21
+ function findAstroRoot(startDir = process.cwd()) {
22
+ let current = path.resolve(startDir);
23
+ while (current !== path.dirname(current)) {
24
+ if (configFilenames.some((filename) => existsSync(path.join(current, filename)))) return current;
25
+ current = path.dirname(current);
26
+ }
27
+ throw new UserError(`Could not locate an Astro config above ${startDir}`);
28
+ }
29
+ async function getCollectionEntries({ getCollection }, collections) {
30
+ const flattened = (await Promise.all(collections.map((collection) => getCollection(collection)))).flat();
31
+ if (flattened.length === 0) throw new UserError(`No entries found in: ${collections.join(", ")}. Run \`astro sync\` to write the content store.`);
32
+ return flattened;
33
+ }
34
+ async function withAstroModules(callback) {
35
+ const root = findAstroRoot();
36
+ const [{ getViteConfig }, { createLogger, createServer, createServerModuleRunner }] = await Promise.all([import("astro/config"), import("vite")]);
37
+ const server = await createServer({
38
+ ...await getViteConfig({}, {
39
+ logLevel: "silent",
40
+ root
41
+ })({
42
+ command: "serve",
43
+ mode: "development"
44
+ }),
45
+ customLogger: createLogger("silent"),
46
+ logLevel: "silent",
47
+ server: {
48
+ hmr: false,
49
+ middlewareMode: true,
50
+ ws: false
51
+ }
52
+ });
53
+ try {
54
+ return await callback(createServerModuleRunner(server.environments.ssr));
55
+ } finally {
56
+ await server.close();
57
+ }
58
+ }
59
+ async function withAstroContent(callback) {
60
+ return withAstroModules(async (runner) => callback(await runner.import("astro:content")));
61
+ }
62
+ //#endregion
6
63
  //#region src/output/reporter-json.ts
7
64
  const throttleMs = 1e3;
8
65
  function strip(text) {
@@ -190,25 +247,27 @@ function formatEnd(event, palette) {
190
247
  const progressIntervalMs = 1e4;
191
248
  function createPlainReporter({ stderr, stdout }, now = Date.now) {
192
249
  const statuses = /* @__PURE__ */ new Map();
193
- let activeId;
250
+ const openIds = [];
194
251
  function writeLine(line) {
195
252
  stderr.write(`${stripVTControlCharacters(line)}\n`);
196
253
  }
197
254
  function closeStatus(id) {
198
255
  statuses.delete(id);
199
- if (activeId === id) activeId = void 0;
256
+ openIds.splice(openIds.indexOf(id), 1);
200
257
  }
201
258
  return { emit(event) {
202
259
  switch (event.type) {
203
- case "data":
204
- stdout.write(`${formatData(event.value)}\n`);
260
+ case "data": {
261
+ const line = event.text === void 0 ? formatData(event.value) : stripVTControlCharacters(event.text);
262
+ stdout.write(`${line}\n`);
205
263
  break;
264
+ }
206
265
  case "end": {
266
+ const activeId = openIds.at(-1);
207
267
  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
- }
268
+ if (active && event.status !== "ok") writeLine(`${getStateSymbol("fail", plainPalette)} ${active.text}`);
269
+ statuses.clear();
270
+ openIds.length = 0;
212
271
  for (const line of formatEnd(event, plainPalette)) writeLine(line);
213
272
  break;
214
273
  }
@@ -233,7 +292,7 @@ function createPlainReporter({ stderr, stdout }, now = Date.now) {
233
292
  lastPrint: now(),
234
293
  text
235
294
  });
236
- activeId = id;
295
+ openIds.push(id);
237
296
  writeLine(text);
238
297
  break;
239
298
  }
@@ -253,32 +312,42 @@ function createPlainReporter({ stderr, stdout }, now = Date.now) {
253
312
  }
254
313
  //#endregion
255
314
  //#region src/output/reporter-pretty.ts
315
+ function isTerminal(stream) {
316
+ return "isTTY" in stream && stream.isTTY === true;
317
+ }
256
318
  function createPrettyReporter({ stderr, stdout }) {
257
319
  const spinners = /* @__PURE__ */ new Map();
258
- let activeId;
320
+ const openIds = [];
259
321
  function getActiveSpinner() {
322
+ const activeId = openIds.at(-1);
260
323
  return activeId === void 0 ? void 0 : spinners.get(activeId);
261
324
  }
262
- function writeLine(line) {
325
+ function writeAround(stream, line) {
263
326
  const active = getActiveSpinner();
264
327
  if (!active?.isSpinning) {
265
- stderr.write(`${line}\n`);
328
+ stream.write(`${line}\n`);
266
329
  return;
267
330
  }
268
331
  active.clear();
269
- stderr.write(`${line}\n`);
332
+ stream.write(`${line}\n`);
270
333
  active.render();
271
334
  }
335
+ function writeLine(line) {
336
+ writeAround(stderr, line);
337
+ }
272
338
  function endSpinner(id, state, text) {
273
339
  const spinner = spinners.get(id);
274
340
  if (!spinner) return;
341
+ const wasActive = openIds.at(-1) === id;
275
342
  if (state === "stop") spinner.stop();
276
343
  else spinner.stopAndPersist({
277
344
  symbol: getStateSymbol(state, chalk),
278
345
  text
279
346
  });
280
347
  spinners.delete(id);
281
- if (activeId === id) activeId = void 0;
348
+ openIds.splice(openIds.indexOf(id), 1);
349
+ const outer = getActiveSpinner();
350
+ if (wasActive && outer?.isEnabled) outer.start();
282
351
  }
283
352
  function onStatus({ id, state, text }) {
284
353
  if (state === "start") {
@@ -288,7 +357,7 @@ function createPrettyReporter({ stderr, stdout }) {
288
357
  stream: stderr,
289
358
  text
290
359
  }).start());
291
- activeId = id;
360
+ openIds.push(id);
292
361
  return;
293
362
  }
294
363
  if (state === "update") {
@@ -300,15 +369,25 @@ function createPrettyReporter({ stderr, stdout }) {
300
369
  }
301
370
  return { emit(event) {
302
371
  switch (event.type) {
303
- case "data":
304
- stdout.write(`${formatData(event.value)}\n`);
372
+ case "data": {
373
+ const line = event.text ?? formatData(event.value);
374
+ if (isTerminal(stdout)) writeAround(stdout, line);
375
+ else stdout.write(`${line}\n`);
305
376
  break;
377
+ }
306
378
  case "end": {
379
+ const activeId = openIds.at(-1);
307
380
  const active = getActiveSpinner();
308
- if (active && activeId !== void 0 && event.status !== "ok") endSpinner(activeId, "fail", active.text);
381
+ if (active && activeId !== void 0 && event.status !== "ok") {
382
+ spinners.delete(activeId);
383
+ active.stopAndPersist({
384
+ symbol: getStateSymbol("fail", chalk),
385
+ text: active.text
386
+ });
387
+ }
309
388
  for (const spinner of spinners.values()) spinner.stop();
310
389
  spinners.clear();
311
- activeId = void 0;
390
+ openIds.length = 0;
312
391
  for (const line of formatEnd(event, chalk)) writeLine(line);
313
392
  break;
314
393
  }
@@ -339,6 +418,7 @@ const outputModes = /* @__PURE__ */ new Set([
339
418
  ]);
340
419
  let currentMode;
341
420
  let currentReporter;
421
+ let capturingReporter;
342
422
  let nextStatusId = 1;
343
423
  function isOutputMode(value) {
344
424
  return outputModes.has(value);
@@ -366,9 +446,28 @@ function getOutputMode() {
366
446
  return currentMode;
367
447
  }
368
448
  function emit(event) {
449
+ if (capturingReporter) {
450
+ capturingReporter.emit(event);
451
+ return;
452
+ }
369
453
  if (currentReporter === void 0) currentReporter = createReporter(getOutputMode());
370
454
  currentReporter.emit(event);
371
455
  }
456
+ async function captureOutput(task) {
457
+ const events = [];
458
+ const previous = capturingReporter;
459
+ capturingReporter = { emit(event) {
460
+ events.push(event);
461
+ } };
462
+ try {
463
+ return {
464
+ events,
465
+ result: await task()
466
+ };
467
+ } finally {
468
+ capturingReporter = previous;
469
+ }
470
+ }
372
471
  function emitMessage(level, text) {
373
472
  emit({
374
473
  level,
@@ -377,8 +476,12 @@ function emitMessage(level, text) {
377
476
  });
378
477
  }
379
478
  const log = {
380
- data(value) {
381
- emit({
479
+ data(value, format) {
480
+ emit(format ? {
481
+ text: format(value),
482
+ type: "data",
483
+ value
484
+ } : {
382
485
  type: "data",
383
486
  value
384
487
  });
@@ -461,14 +564,6 @@ function createStatus(text) {
461
564
  return startStatus(text).status;
462
565
  }
463
566
  //#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
567
  //#region src/workspace.ts
473
568
  function findWorkspaceRoot(startDir = process.cwd()) {
474
569
  let current = path.resolve(startDir);
@@ -476,7 +571,7 @@ function findWorkspaceRoot(startDir = process.cwd()) {
476
571
  if (existsSync(path.join(current, "pnpm-workspace.yaml"))) return current;
477
572
  current = path.dirname(current);
478
573
  }
479
- throw new Error(`Could not locate pnpm-workspace.yaml above ${startDir}`);
574
+ throw new UserError(`Could not locate pnpm-workspace.yaml above ${startDir}`);
480
575
  }
481
576
  //#endregion
482
577
  //#region src/command.ts
@@ -492,7 +587,7 @@ const builtInOptions = [["json", {
492
587
  }]];
493
588
  function parseNumberOption(value, name) {
494
589
  const parsed = Number(value);
495
- if (value.trim() === "" || !Number.isFinite(parsed)) throw new Refusal(`--${name} expects a number, got "${value}"`);
590
+ if (value.trim() === "" || !Number.isFinite(parsed)) throw new UserError(`--${name} expects a number, got "${value}"`);
496
591
  return parsed;
497
592
  }
498
593
  function getUsage(command, usagePrefix) {
@@ -537,8 +632,16 @@ function describeError(error) {
537
632
  detail: "See --help",
538
633
  message: error.message
539
634
  };
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)}`}` };
635
+ if (isUserError(error)) return { message: error.message };
636
+ if (isChildProcessFailure(error)) {
637
+ const message = `Child process ${error.signal ? `was killed by ${error.signal}` : `exited with code ${String(error.exitCode)}`}`;
638
+ const stderr = typeof error.stderr === "string" ? error.stderr.trimEnd() : "";
639
+ if (stderr === "") return { message };
640
+ return {
641
+ detail: stderr.split("\n").slice(-20).join("\n"),
642
+ message
643
+ };
644
+ }
542
645
  if (!(error instanceof Error)) return { message: String(error) };
543
646
  const stack = error.stack?.split("\n").slice(1).join("\n");
544
647
  return stack ? {
@@ -573,7 +676,7 @@ function selectOutput(isJson) {
573
676
  return;
574
677
  }
575
678
  const requested = process.env.SCRIPTS_OUTPUT;
576
- if (requested && !isOutputMode(requested)) throw new Refusal(`SCRIPTS_OUTPUT must be pretty, plain or json, got "${requested}"`);
679
+ if (requested && !isOutputMode(requested)) throw new UserError(`SCRIPTS_OUTPUT must be pretty, plain or json, got "${requested}"`);
577
680
  }
578
681
  function createCommandRunner(runnerOptions = {}) {
579
682
  const { context: createContext, usagePrefix = "pnpm" } = runnerOptions;
@@ -606,6 +709,7 @@ function createCommandRunner(runnerOptions = {}) {
606
709
  }
607
710
  process.on("SIGINT", onInterrupt);
608
711
  process.on("SIGTERM", onInterrupt);
712
+ let hasStarted = false;
609
713
  try {
610
714
  const { positionals, values } = parseCommandArgs(command);
611
715
  if (values.help) {
@@ -617,6 +721,7 @@ function createCommandRunner(runnerOptions = {}) {
617
721
  title: command.title,
618
722
  type: "start"
619
723
  });
724
+ hasStarted = true;
620
725
  const rootPath = findWorkspaceRoot();
621
726
  const context = createContext ? await createContext({ rootPath }) : {};
622
727
  await command.run({
@@ -634,6 +739,10 @@ function createCommandRunner(runnerOptions = {}) {
634
739
  type: "end"
635
740
  });
636
741
  } catch (error) {
742
+ if (!hasStarted && getOutputMode() === "json") emit({
743
+ title: command.title,
744
+ type: "start"
745
+ });
637
746
  const report = getFailureReport(error, {
638
747
  interrupted: command.interrupted,
639
748
  isAborted: controller.signal.aborted
@@ -751,6 +860,6 @@ async function withSpinner(text, task, describe) {
751
860
  }
752
861
  }
753
862
  //#endregion
754
- export { Refusal, createCommandRunner, createProgress, createStatus, findWorkspaceRoot, formatBytes, formatCount, formatDuration, formatError, getOutputMode, log, parseNumberOption, withSpinner, withStatus };
863
+ export { UserError, captureOutput, createCommandRunner, createProgress, createStatus, findAstroRoot, findWorkspaceRoot, formatBytes, formatCount, formatDuration, formatError, getCollectionEntries, getOutputMode, log, parseNumberOption, withAstroContent, withAstroModules, withSpinner, withStatus };
755
864
 
756
865
  //# 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\toverride name = 'UserError';\n}\n\nexport function isUserError(error: unknown): error is Error {\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(` ${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\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.text === undefined\n\t\t\t\t\t\t\t? formatData(event.value)\n\t\t\t\t\t\t\t: stripVTControlCharacters(event.text);\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.text ?? 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 ? { text: 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)) 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\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 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\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.0",
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"}