@plexus-ms/cli 0.1.0 → 0.3.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.
Files changed (3) hide show
  1. package/LICENSE +674 -0
  2. package/dist/plx.js +2719 -1885
  3. package/package.json +10 -11
package/dist/plx.js CHANGED
@@ -38,171 +38,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
38
38
  mod
39
39
  ));
40
40
 
41
- // ../../node_modules/.pnpm/cli-width@4.1.0/node_modules/cli-width/index.js
42
- var require_cli_width = __commonJS({
43
- "../../node_modules/.pnpm/cli-width@4.1.0/node_modules/cli-width/index.js"(exports, module) {
44
- "use strict";
45
- module.exports = cliWidth2;
46
- function normalizeOpts(options) {
47
- const defaultOpts = {
48
- defaultWidth: 0,
49
- output: process.stdout,
50
- tty: __require("tty")
51
- };
52
- if (!options) {
53
- return defaultOpts;
54
- }
55
- Object.keys(defaultOpts).forEach(function(key) {
56
- if (!options[key]) {
57
- options[key] = defaultOpts[key];
58
- }
59
- });
60
- return options;
61
- }
62
- function cliWidth2(options) {
63
- const opts = normalizeOpts(options);
64
- if (opts.output.getWindowSize) {
65
- return opts.output.getWindowSize()[0] || opts.defaultWidth;
66
- }
67
- if (opts.tty.getWindowSize) {
68
- return opts.tty.getWindowSize()[1] || opts.defaultWidth;
69
- }
70
- if (opts.output.columns) {
71
- return opts.output.columns;
72
- }
73
- if (process.env.CLI_WIDTH) {
74
- const width = parseInt(process.env.CLI_WIDTH, 10);
75
- if (!isNaN(width) && width !== 0) {
76
- return width;
77
- }
78
- }
79
- return opts.defaultWidth;
80
- }
81
- }
82
- });
83
-
84
- // ../../node_modules/.pnpm/mute-stream@3.0.0/node_modules/mute-stream/lib/index.js
85
- var require_lib = __commonJS({
86
- "../../node_modules/.pnpm/mute-stream@3.0.0/node_modules/mute-stream/lib/index.js"(exports, module) {
87
- var Stream = __require("stream");
88
- var MuteStream2 = class extends Stream {
89
- #isTTY = null;
90
- constructor(opts = {}) {
91
- super(opts);
92
- this.writable = this.readable = true;
93
- this.muted = false;
94
- this.on("pipe", this._onpipe);
95
- this.replace = opts.replace;
96
- this._prompt = opts.prompt || null;
97
- this._hadControl = false;
98
- }
99
- #destSrc(key, def) {
100
- if (this._dest) {
101
- return this._dest[key];
102
- }
103
- if (this._src) {
104
- return this._src[key];
105
- }
106
- return def;
107
- }
108
- #proxy(method, ...args) {
109
- if (typeof this._dest?.[method] === "function") {
110
- this._dest[method](...args);
111
- }
112
- if (typeof this._src?.[method] === "function") {
113
- this._src[method](...args);
114
- }
115
- }
116
- get isTTY() {
117
- if (this.#isTTY !== null) {
118
- return this.#isTTY;
119
- }
120
- return this.#destSrc("isTTY", false);
121
- }
122
- // basically just get replace the getter/setter with a regular value
123
- set isTTY(val) {
124
- this.#isTTY = val;
125
- }
126
- get rows() {
127
- return this.#destSrc("rows");
128
- }
129
- get columns() {
130
- return this.#destSrc("columns");
131
- }
132
- mute() {
133
- this.muted = true;
134
- }
135
- unmute() {
136
- this.muted = false;
137
- }
138
- _onpipe(src) {
139
- this._src = src;
140
- }
141
- pipe(dest, options) {
142
- this._dest = dest;
143
- return super.pipe(dest, options);
144
- }
145
- pause() {
146
- if (this._src) {
147
- return this._src.pause();
148
- }
149
- }
150
- resume() {
151
- if (this._src) {
152
- return this._src.resume();
153
- }
154
- }
155
- write(c) {
156
- if (this.muted) {
157
- if (!this.replace) {
158
- return true;
159
- }
160
- if (c.match(/^\u001b/)) {
161
- if (c.indexOf(this._prompt) === 0) {
162
- c = c.slice(this._prompt.length);
163
- c = c.replace(/./g, this.replace);
164
- c = this._prompt + c;
165
- }
166
- this._hadControl = true;
167
- return this.emit("data", c);
168
- } else {
169
- if (this._prompt && this._hadControl && c.indexOf(this._prompt) === 0) {
170
- this._hadControl = false;
171
- this.emit("data", this._prompt);
172
- c = c.slice(this._prompt.length);
173
- }
174
- c = c.toString().replace(/./g, this.replace);
175
- }
176
- }
177
- this.emit("data", c);
178
- }
179
- end(c) {
180
- if (this.muted) {
181
- if (c && this.replace) {
182
- c = c.toString().replace(/./g, this.replace);
183
- } else {
184
- c = null;
185
- }
186
- }
187
- if (c) {
188
- this.emit("data", c);
189
- }
190
- this.emit("end");
191
- }
192
- destroy(...args) {
193
- return this.#proxy("destroy", ...args);
194
- }
195
- destroySoon(...args) {
196
- return this.#proxy("destroySoon", ...args);
197
- }
198
- close(...args) {
199
- return this.#proxy("close", ...args);
200
- }
201
- };
202
- module.exports = MuteStream2;
203
- }
204
- });
205
-
206
41
  // ../../node_modules/.pnpm/yaml@2.9.1/node_modules/yaml/dist/nodes/identity.js
207
42
  var require_identity = __commonJS({
208
43
  "../../node_modules/.pnpm/yaml@2.9.1/node_modules/yaml/dist/nodes/identity.js"(exports) {
@@ -6517,15 +6352,15 @@ var require_parser = __commonJS({
6517
6352
  var node_process = __require("process");
6518
6353
  var cst = require_cst();
6519
6354
  var lexer = require_lexer();
6520
- function includesToken(list, type) {
6521
- for (let i = 0; i < list.length; ++i)
6522
- if (list[i].type === type)
6355
+ function includesToken(list2, type) {
6356
+ for (let i = 0; i < list2.length; ++i)
6357
+ if (list2[i].type === type)
6523
6358
  return true;
6524
6359
  return false;
6525
6360
  }
6526
- function findNonEmptyIndex(list) {
6527
- for (let i = 0; i < list.length; ++i) {
6528
- switch (list[i].type) {
6361
+ function findNonEmptyIndex(list2) {
6362
+ for (let i = 0; i < list2.length; ++i) {
6363
+ switch (list2[i].type) {
6529
6364
  case "space":
6530
6365
  case "comment":
6531
6366
  case "newline":
@@ -7533,1836 +7368,2736 @@ var require_dist = __commonJS({
7533
7368
  }
7534
7369
  });
7535
7370
 
7536
- // src/program.ts
7537
- import { createRequire } from "node:module";
7538
-
7539
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/key.js
7540
- var keybindings = ["emacs", "vim"];
7541
- var keybindingLookup = new Set(keybindings);
7542
- function isKeybinding(value) {
7543
- return keybindingLookup.has(value);
7544
- }
7545
- function getDefaultKeybindings() {
7546
- const env = process.env["INQUIRER_KEYBINDINGS"];
7547
- if (!env)
7548
- return [];
7549
- return Array.from(new Set(env.toLowerCase().split(/[\s,]+/).filter(isKeybinding)));
7550
- }
7551
- var isTabKey = (key) => key.name === "tab";
7552
- var isEnterKey = (key) => key.name === "enter" || key.name === "return";
7553
-
7554
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/errors.js
7555
- var AbortPromptError = class extends Error {
7556
- name = "AbortPromptError";
7557
- message = "Prompt was aborted";
7558
- constructor(options) {
7559
- super();
7560
- this.cause = options?.cause;
7371
+ // ../../node_modules/.pnpm/cli-width@4.1.0/node_modules/cli-width/index.js
7372
+ var require_cli_width = __commonJS({
7373
+ "../../node_modules/.pnpm/cli-width@4.1.0/node_modules/cli-width/index.js"(exports, module) {
7374
+ "use strict";
7375
+ module.exports = cliWidth2;
7376
+ function normalizeOpts(options) {
7377
+ const defaultOpts = {
7378
+ defaultWidth: 0,
7379
+ output: process.stdout,
7380
+ tty: __require("tty")
7381
+ };
7382
+ if (!options) {
7383
+ return defaultOpts;
7384
+ }
7385
+ Object.keys(defaultOpts).forEach(function(key) {
7386
+ if (!options[key]) {
7387
+ options[key] = defaultOpts[key];
7388
+ }
7389
+ });
7390
+ return options;
7391
+ }
7392
+ function cliWidth2(options) {
7393
+ const opts = normalizeOpts(options);
7394
+ if (opts.output.getWindowSize) {
7395
+ return opts.output.getWindowSize()[0] || opts.defaultWidth;
7396
+ }
7397
+ if (opts.tty.getWindowSize) {
7398
+ return opts.tty.getWindowSize()[1] || opts.defaultWidth;
7399
+ }
7400
+ if (opts.output.columns) {
7401
+ return opts.output.columns;
7402
+ }
7403
+ if (process.env.CLI_WIDTH) {
7404
+ const width = parseInt(process.env.CLI_WIDTH, 10);
7405
+ if (!isNaN(width) && width !== 0) {
7406
+ return width;
7407
+ }
7408
+ }
7409
+ return opts.defaultWidth;
7410
+ }
7561
7411
  }
7562
- };
7563
- var CancelPromptError = class extends Error {
7564
- name = "CancelPromptError";
7565
- message = "Prompt was canceled";
7566
- };
7567
- var ExitPromptError = class extends Error {
7568
- name = "ExitPromptError";
7569
- };
7570
- var HookError = class extends Error {
7571
- name = "HookError";
7572
- };
7573
- var ValidationError = class extends Error {
7574
- name = "ValidationError";
7575
- };
7576
-
7577
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/use-state.js
7578
- import { AsyncResource as AsyncResource2 } from "node:async_hooks";
7412
+ });
7579
7413
 
7580
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/hook-engine.js
7581
- import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
7582
- var hookStorage = new AsyncLocalStorage();
7583
- function createStore(rl) {
7584
- const store = {
7585
- rl,
7586
- hooks: [],
7587
- hooksCleanup: [],
7588
- hooksEffect: [],
7589
- index: 0,
7590
- handleChange() {
7591
- }
7592
- };
7593
- return store;
7594
- }
7595
- function withHooks(rl, cb) {
7596
- const store = createStore(rl);
7597
- function cycle(render2) {
7598
- store.handleChange = () => {
7599
- store.index = 0;
7600
- render2();
7414
+ // ../../node_modules/.pnpm/mute-stream@3.0.0/node_modules/mute-stream/lib/index.js
7415
+ var require_lib = __commonJS({
7416
+ "../../node_modules/.pnpm/mute-stream@3.0.0/node_modules/mute-stream/lib/index.js"(exports, module) {
7417
+ var Stream = __require("stream");
7418
+ var MuteStream2 = class extends Stream {
7419
+ #isTTY = null;
7420
+ constructor(opts = {}) {
7421
+ super(opts);
7422
+ this.writable = this.readable = true;
7423
+ this.muted = false;
7424
+ this.on("pipe", this._onpipe);
7425
+ this.replace = opts.replace;
7426
+ this._prompt = opts.prompt || null;
7427
+ this._hadControl = false;
7428
+ }
7429
+ #destSrc(key, def) {
7430
+ if (this._dest) {
7431
+ return this._dest[key];
7432
+ }
7433
+ if (this._src) {
7434
+ return this._src[key];
7435
+ }
7436
+ return def;
7437
+ }
7438
+ #proxy(method, ...args) {
7439
+ if (typeof this._dest?.[method] === "function") {
7440
+ this._dest[method](...args);
7441
+ }
7442
+ if (typeof this._src?.[method] === "function") {
7443
+ this._src[method](...args);
7444
+ }
7445
+ }
7446
+ get isTTY() {
7447
+ if (this.#isTTY !== null) {
7448
+ return this.#isTTY;
7449
+ }
7450
+ return this.#destSrc("isTTY", false);
7451
+ }
7452
+ // basically just get replace the getter/setter with a regular value
7453
+ set isTTY(val) {
7454
+ this.#isTTY = val;
7455
+ }
7456
+ get rows() {
7457
+ return this.#destSrc("rows");
7458
+ }
7459
+ get columns() {
7460
+ return this.#destSrc("columns");
7461
+ }
7462
+ mute() {
7463
+ this.muted = true;
7464
+ }
7465
+ unmute() {
7466
+ this.muted = false;
7467
+ }
7468
+ _onpipe(src) {
7469
+ this._src = src;
7470
+ }
7471
+ pipe(dest, options) {
7472
+ this._dest = dest;
7473
+ return super.pipe(dest, options);
7474
+ }
7475
+ pause() {
7476
+ if (this._src) {
7477
+ return this._src.pause();
7478
+ }
7479
+ }
7480
+ resume() {
7481
+ if (this._src) {
7482
+ return this._src.resume();
7483
+ }
7484
+ }
7485
+ write(c) {
7486
+ if (this.muted) {
7487
+ if (!this.replace) {
7488
+ return true;
7489
+ }
7490
+ if (c.match(/^\u001b/)) {
7491
+ if (c.indexOf(this._prompt) === 0) {
7492
+ c = c.slice(this._prompt.length);
7493
+ c = c.replace(/./g, this.replace);
7494
+ c = this._prompt + c;
7495
+ }
7496
+ this._hadControl = true;
7497
+ return this.emit("data", c);
7498
+ } else {
7499
+ if (this._prompt && this._hadControl && c.indexOf(this._prompt) === 0) {
7500
+ this._hadControl = false;
7501
+ this.emit("data", this._prompt);
7502
+ c = c.slice(this._prompt.length);
7503
+ }
7504
+ c = c.toString().replace(/./g, this.replace);
7505
+ }
7506
+ }
7507
+ this.emit("data", c);
7508
+ }
7509
+ end(c) {
7510
+ if (this.muted) {
7511
+ if (c && this.replace) {
7512
+ c = c.toString().replace(/./g, this.replace);
7513
+ } else {
7514
+ c = null;
7515
+ }
7516
+ }
7517
+ if (c) {
7518
+ this.emit("data", c);
7519
+ }
7520
+ this.emit("end");
7521
+ }
7522
+ destroy(...args) {
7523
+ return this.#proxy("destroy", ...args);
7524
+ }
7525
+ destroySoon(...args) {
7526
+ return this.#proxy("destroySoon", ...args);
7527
+ }
7528
+ close(...args) {
7529
+ return this.#proxy("close", ...args);
7530
+ }
7601
7531
  };
7602
- store.handleChange();
7532
+ module.exports = MuteStream2;
7603
7533
  }
7604
- return hookStorage.run(store, () => cb(cycle));
7534
+ });
7535
+
7536
+ // ../lib/dist/frontmatter.js
7537
+ function frontmatterLines(lines) {
7538
+ if (lines[0] !== "---")
7539
+ return void 0;
7540
+ const end = lines.findIndex((l, i) => i > 0 && l === "---");
7541
+ return end === -1 ? void 0 : { start: 1, end };
7605
7542
  }
7606
- function getStore() {
7607
- const store = hookStorage.getStore();
7608
- if (!store) {
7609
- throw new HookError("[Inquirer] Hook functions can only be called from within a prompt");
7543
+ function setFrontmatterField(text, key, value, options = {}) {
7544
+ const lines = text.split("\n");
7545
+ const fm = frontmatterLines(lines);
7546
+ if (!fm)
7547
+ throw new Error("no frontmatter: expected a `---` block at the top");
7548
+ const line = `${key}: ${value}`;
7549
+ const isKey = (l) => l.startsWith(`${key}:`);
7550
+ const existing = lines.findIndex((l, i) => i >= fm.start && i < fm.end && isKey(l));
7551
+ if (existing !== -1) {
7552
+ lines[existing] = line;
7553
+ } else {
7554
+ const anchor = options.after ? lines.findIndex((l, i) => i >= fm.start && i < fm.end && l.startsWith(`${options.after}:`)) : -1;
7555
+ lines.splice(anchor === -1 ? fm.end : anchor + 1, 0, line);
7610
7556
  }
7611
- return store;
7557
+ return lines.join("\n");
7612
7558
  }
7613
- function readline() {
7614
- return getStore().rl;
7559
+ function frontmatterField(text, key) {
7560
+ const lines = text.split("\n");
7561
+ const fm = frontmatterLines(lines);
7562
+ if (!fm)
7563
+ return void 0;
7564
+ const line = lines.slice(fm.start, fm.end).find((l) => l.startsWith(`${key}:`));
7565
+ return line?.slice(key.length + 1).trim();
7615
7566
  }
7616
- function withUpdates(fn) {
7617
- const wrapped = (...args) => {
7618
- const store = getStore();
7619
- let shouldUpdate = false;
7620
- const oldHandleChange = store.handleChange;
7621
- store.handleChange = () => {
7622
- shouldUpdate = true;
7623
- };
7624
- const returnValue = fn(...args);
7625
- if (shouldUpdate) {
7626
- oldHandleChange();
7567
+
7568
+ // ../lib/dist/bookkeeping.js
7569
+ var bumpGalaxyVersion = (text, train) => text.replace(/^(version: )\d+\.\d+\.\d+/m, `$1${train}`);
7570
+ function bumpCollectionPin(text, train) {
7571
+ const lines = text.split("\n");
7572
+ const start = lines.findIndex((l) => l.includes("plexus-ms/platform.git"));
7573
+ if (start === -1)
7574
+ return text;
7575
+ for (let i = start; i < lines.length; i++) {
7576
+ const m = /^(\s*version: )v?[\d.]+$/.exec(lines[i] ?? "");
7577
+ if (m) {
7578
+ lines[i] = `${m[1]}${train}`;
7579
+ break;
7627
7580
  }
7628
- store.handleChange = oldHandleChange;
7629
- return returnValue;
7630
- };
7631
- return AsyncResource.bind(wrapped);
7581
+ }
7582
+ return lines.join("\n");
7632
7583
  }
7633
- function withPointer(cb) {
7634
- const store = getStore();
7635
- const { index } = store;
7636
- const pointer = {
7637
- get() {
7638
- return store.hooks[index];
7639
- },
7640
- set(value) {
7641
- store.hooks[index] = value;
7642
- },
7643
- initialized: index in store.hooks
7584
+ var WORKFLOW_REF = "plexus-ms/ci-cd/.github/workflows/";
7585
+ var bumpWorkflowRefs = (text, train) => text.replace(/(plexus-ms\/ci-cd\/\.github\/workflows\/[A-Za-z0-9._-]+)@v?[0-9.]+/g, `$1@${train}`);
7586
+ var stampStandard = (text, train, today2) => setFrontmatterField(setFrontmatterField(text, "version", train), "timestamp", today2);
7587
+ var stampChanged = (text, train) => setFrontmatterField(text, "changed", train, { after: "binds" });
7588
+ var hasConflictMarkers = (text) => /^<<<<<<< /m.test(text);
7589
+ var hasUnmergedEntries = (porcelain) => /^(UU|AA|DU|UD)/m.test(porcelain);
7590
+ function syncMarker(marker, commit) {
7591
+ if (hasConflictMarkers(marker))
7592
+ return marker;
7593
+ return setFrontmatterField(marker, "plexus", commit);
7594
+ }
7595
+ function today(now = /* @__PURE__ */ new Date()) {
7596
+ const pad = (n) => String(n).padStart(2, "0");
7597
+ return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
7598
+ }
7599
+
7600
+ // ../lib/dist/catalog.js
7601
+ import { join } from "node:path";
7602
+
7603
+ // ../lib/dist/marker.js
7604
+ var import_yaml = __toESM(require_dist(), 1);
7605
+ var MARKER_FILE = "PLEXUS.md";
7606
+ function parseMarker(text) {
7607
+ const { data, body: body2 } = splitFrontmatter(text);
7608
+ const plexus = data.plexus;
7609
+ const modules = data.modules;
7610
+ if (typeof plexus !== "string" && typeof plexus !== "number")
7611
+ throw new Error("marker: `plexus` must be a version");
7612
+ if (!Array.isArray(modules) || !modules.every((m) => typeof m === "string"))
7613
+ throw new Error("marker: `modules` must be a list of module codes");
7614
+ return { plexus: String(plexus), modules, body: body2 };
7615
+ }
7616
+ function splitFrontmatter(text) {
7617
+ const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)([\s\S]*)$/.exec(text);
7618
+ if (!match)
7619
+ throw new Error("no frontmatter: expected a `---` block at the top");
7620
+ const data = (0, import_yaml.parse)(match[1] ?? "");
7621
+ if (data === null || typeof data !== "object" || Array.isArray(data))
7622
+ throw new Error("frontmatter is not a mapping");
7623
+ return { data, body: match[2] ?? "" };
7624
+ }
7625
+
7626
+ // ../lib/dist/catalog.js
7627
+ var CATALOG_DIRS = { contracts: "contract", approaches: "approach" };
7628
+ function parseModule(text, kind) {
7629
+ const { data } = splitFrontmatter(text);
7630
+ if (typeof data.code !== "string")
7631
+ return void 0;
7632
+ return {
7633
+ code: data.code,
7634
+ kind,
7635
+ maturity: String(data.maturity ?? ""),
7636
+ binds: String(data.binds ?? ""),
7637
+ changed: data.changed === void 0 ? void 0 : String(data.changed),
7638
+ depends: codes(data.depends),
7639
+ consumes: codes(data.consumes)
7644
7640
  };
7645
- const returnValue = cb(pointer);
7646
- store.index++;
7647
- return returnValue;
7648
7641
  }
7649
- function handleChange() {
7650
- getStore().handleChange();
7642
+ function codes(value) {
7643
+ return Array.isArray(value) ? value.map(String) : [];
7651
7644
  }
7652
- var effectScheduler = {
7653
- queue(cb) {
7654
- const store = getStore();
7655
- const { index } = store;
7656
- store.hooksEffect.push(() => {
7657
- store.hooksCleanup[index]?.();
7658
- const cleanFn = cb(readline());
7659
- if (cleanFn != null && typeof cleanFn !== "function") {
7660
- throw new ValidationError("useEffect return value must be a cleanup function or nothing.");
7661
- }
7662
- store.hooksCleanup[index] = cleanFn;
7663
- });
7664
- },
7665
- run() {
7666
- const store = getStore();
7667
- withUpdates(() => {
7668
- store.hooksEffect.forEach((effect) => {
7669
- effect();
7670
- });
7671
- store.hooksEffect.length = 0;
7672
- })();
7673
- },
7674
- clearAll() {
7675
- const store = getStore();
7676
- store.hooksCleanup.forEach((cleanFn) => {
7677
- cleanFn?.();
7678
- });
7679
- store.hooksEffect.length = 0;
7680
- store.hooksCleanup.length = 0;
7645
+ async function readCatalog(ctx, compendium) {
7646
+ const catalog = /* @__PURE__ */ new Map();
7647
+ for (const [dir, kind] of Object.entries(CATALOG_DIRS)) {
7648
+ const entries = await ctx.readDir(join(compendium, dir));
7649
+ for (const e of entries.filter((e2) => !e2.directory && e2.name.endsWith(".md") && e2.name !== "index.md").sort()) {
7650
+ const module = parseModule(await ctx.readFile(join(compendium, dir, e.name)), kind);
7651
+ if (module)
7652
+ catalog.set(module.code, module);
7653
+ }
7681
7654
  }
7682
- };
7655
+ return catalog;
7656
+ }
7683
7657
 
7684
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/use-state.js
7685
- function isFactory(value) {
7686
- return typeof value === "function";
7658
+ // ../lib/dist/consumers.js
7659
+ import { relative } from "node:path";
7660
+ function expectedBranch(declaration) {
7661
+ if (!declaration)
7662
+ return void 0;
7663
+ if (declaration.modules.includes("PLX-Platform"))
7664
+ return "main";
7665
+ if (declaration.modules.includes("PLX-Repo"))
7666
+ return "develop";
7667
+ return void 0;
7687
7668
  }
7688
- function isReducer(value) {
7689
- return typeof value === "function";
7669
+ var presetSource = (preset) => `gh:plexus-ms/${preset}`;
7670
+ async function findConsumers(ctx, root, presets) {
7671
+ const sources = new Map(presets.map((p) => [presetSource(p), p]));
7672
+ const consumers = /* @__PURE__ */ new Map();
7673
+ const orphans = [];
7674
+ const visit = (dir, repo, inTemplate) => {
7675
+ const here = dir.git ? dir : repo;
7676
+ const template = inTemplate || Boolean(dir.template);
7677
+ const preset = dir.copier?.src ? sources.get(dir.copier.src) : void 0;
7678
+ if (preset && !template) {
7679
+ const site = { path: dir.path, rel: relative(root.path, dir.path) || ".", preset };
7680
+ if (!here)
7681
+ orphans.push(site);
7682
+ else {
7683
+ let consumer = consumers.get(here.path);
7684
+ if (!consumer) {
7685
+ consumer = {
7686
+ path: here.path,
7687
+ rel: relative(root.path, here.path) || ".",
7688
+ branch: here.git?.branch ?? "?",
7689
+ expected: expectedBranch(here.declaration),
7690
+ sites: []
7691
+ };
7692
+ consumers.set(here.path, consumer);
7693
+ }
7694
+ consumer.sites.push(site);
7695
+ }
7696
+ }
7697
+ for (const child of dir.children)
7698
+ visit(child, here, template);
7699
+ };
7700
+ visit(root, void 0, false);
7701
+ for (const site of orphans)
7702
+ ctx.say(`\u26A0 ${site.rel}: not inside a git repo \u2014 skipped`);
7703
+ for (const c of consumers.values()) {
7704
+ if (c.expected && c.branch !== c.expected) {
7705
+ c.skipped = `on '${c.branch}', expected '${c.expected}'`;
7706
+ continue;
7707
+ }
7708
+ const tracked = (await ctx.read("git", ["status", "--porcelain", "--untracked-files=no"], { cwd: c.path })).trim();
7709
+ if (tracked !== "")
7710
+ c.skipped = "has uncommitted changes";
7711
+ }
7712
+ return [...consumers.values()];
7690
7713
  }
7691
- function useState(defaultValue) {
7692
- return withPointer((pointer) => {
7693
- const setState = AsyncResource2.bind(function setState2(newValue) {
7694
- const currentValue = pointer.get();
7695
- const nextValue = isReducer(newValue) ? newValue(currentValue) : newValue;
7696
- if (!Object.is(currentValue, nextValue)) {
7697
- pointer.set(nextValue);
7698
- handleChange();
7699
- }
7700
- });
7701
- if (pointer.initialized) {
7702
- return [pointer.get(), setState];
7703
- }
7704
- const value = isFactory(defaultValue) ? defaultValue() : defaultValue;
7705
- pointer.set(value);
7706
- return [value, setState];
7707
- });
7714
+
7715
+ // ../lib/dist/io.js
7716
+ import { spawn } from "node:child_process";
7717
+ import { readdir, readFile, writeFile } from "node:fs/promises";
7718
+ var ExecError = class extends Error {
7719
+ command;
7720
+ code;
7721
+ stderr;
7722
+ constructor(command, code, stderr) {
7723
+ super(`${command} exited with ${code ?? "signal"}${stderr ? `
7724
+ ${stderr.trimEnd()}` : ""}`);
7725
+ this.command = command;
7726
+ this.code = code;
7727
+ this.stderr = stderr;
7728
+ }
7729
+ };
7730
+ var isInteractive = () => process.stdin.isTTY === true && process.stderr.isTTY === true;
7731
+ function realIo(prompt) {
7732
+ return {
7733
+ stdout: process.stdout,
7734
+ stderr: process.stderr,
7735
+ prompt: prompt && isInteractive() ? prompt : void 0,
7736
+ exec: (command, args, options = {}) => new Promise((resolve6, reject) => {
7737
+ const child = spawn(command, args, {
7738
+ cwd: options.cwd,
7739
+ env: options.env,
7740
+ stdio: [
7741
+ options.input !== void 0 ? "pipe" : options.inherit ? "inherit" : "ignore",
7742
+ options.inherit ? "inherit" : "pipe",
7743
+ "pipe"
7744
+ ]
7745
+ });
7746
+ let stdout = "";
7747
+ let stderr = "";
7748
+ child.stdout?.on("data", (chunk) => {
7749
+ stdout += chunk;
7750
+ });
7751
+ child.stderr?.on("data", (chunk) => {
7752
+ stderr += chunk;
7753
+ if (options.inherit)
7754
+ process.stderr.write(chunk);
7755
+ });
7756
+ child.on("error", reject);
7757
+ child.on("close", (code) => {
7758
+ if (code === 0)
7759
+ resolve6(stdout);
7760
+ else
7761
+ reject(new ExecError(render(command, args), code, stderr));
7762
+ });
7763
+ if (options.input !== void 0)
7764
+ child.stdin?.end(options.input);
7765
+ }),
7766
+ readFile: (path3) => readFile(path3, "utf8"),
7767
+ writeFile: (path3, content) => writeFile(path3, content),
7768
+ readDir: async (path3) => (await readdir(path3, { withFileTypes: true })).map((e) => ({ name: e.name, directory: e.isDirectory() }))
7769
+ };
7770
+ }
7771
+ function render(command, args) {
7772
+ return [command, ...args].map(quote).join(" ");
7773
+ }
7774
+ function quote(arg) {
7775
+ return /^[\w./:@%+=,-]+$/.test(arg) ? arg : `'${arg.replaceAll("'", "'\\''")}'`;
7708
7776
  }
7709
7777
 
7710
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/use-effect.js
7711
- function useEffect(cb, depArray) {
7712
- withPointer((pointer) => {
7713
- const oldDeps = pointer.get();
7714
- const hasChanged = !Array.isArray(oldDeps) || depArray.some((dep, i) => !Object.is(dep, oldDeps[i]));
7715
- if (hasChanged) {
7716
- effectScheduler.queue(cb);
7778
+ // ../lib/dist/plan.js
7779
+ var run = (command, args = [], options = {}) => ({
7780
+ kind: "run",
7781
+ command,
7782
+ args,
7783
+ ...options
7784
+ });
7785
+ var write = (path3, content) => ({ kind: "write", path: path3, content });
7786
+ function describe(step) {
7787
+ switch (step.kind) {
7788
+ case "run":
7789
+ return `$ ${step.cwd ? `(cd ${step.cwd} && ` : ""}${render(step.command, step.args)}${step.cwd ? ")" : ""}`;
7790
+ case "ssh":
7791
+ return `$ ${render("ssh", [step.host, "bash", "-s"])} <<'EOF'`;
7792
+ case "write":
7793
+ return `> ${step.path} (${Buffer.byteLength(step.content)} bytes)`;
7794
+ }
7795
+ }
7796
+ function body(step) {
7797
+ switch (step.kind) {
7798
+ case "run":
7799
+ return step.input;
7800
+ case "ssh":
7801
+ return `${step.script.trimEnd()}
7802
+ EOF`;
7803
+ case "write":
7804
+ return step.content;
7805
+ }
7806
+ }
7807
+
7808
+ // ../lib/dist/context.js
7809
+ var Context = class {
7810
+ dryRun;
7811
+ verbose;
7812
+ quiet;
7813
+ yes;
7814
+ json;
7815
+ io;
7816
+ constructor(options, io = realIo()) {
7817
+ this.io = io;
7818
+ this.dryRun = options.dryRun ?? false;
7819
+ this.quiet = options.quiet ?? false;
7820
+ this.verbose = this.quiet ? -1 : options.verbose ?? 0;
7821
+ this.yes = options.yes ?? false;
7822
+ this.json = options.json ?? false;
7823
+ }
7824
+ // --- narration (stderr) ---------------------------------------------------
7825
+ /** One line, if the verbosity allows the level (0 normal, 1 verbose, 2 debug). */
7826
+ say(line, level = 0) {
7827
+ if (this.verbose >= level)
7828
+ this.io.stderr.write(`${line}
7829
+ `);
7830
+ }
7831
+ /** A final outcome line, `✓ ...` or `✗ ...`; shown even under --quiet. */
7832
+ done(line, ok = true) {
7833
+ this.io.stderr.write(`${ok ? "\u2713" : "\u2717"} ${line}
7834
+ `);
7835
+ }
7836
+ // --- results (stdout) -----------------------------------------------------
7837
+ /**
7838
+ * The command's product. `data` is what --json prints; `human` renders it
7839
+ * otherwise (default: strings as they are, arrays one item per line).
7840
+ */
7841
+ result(data, human = renderHuman) {
7842
+ const text = this.json ? JSON.stringify(data, null, 2) : human(data);
7843
+ this.io.stdout.write(text.endsWith("\n") ? text : `${text}
7844
+ `);
7845
+ }
7846
+ // --- reads: always performed ---------------------------------------------
7847
+ /** Run a command for its output. Changes nothing; narrated only when verbose. */
7848
+ read(command, args = [], options = {}) {
7849
+ this.say(`? ${describe({ kind: "run", command, args, ...options })}`, 1);
7850
+ return this.io.exec(command, args, options);
7851
+ }
7852
+ readFile(path3) {
7853
+ this.say(`? read ${path3}`, 1);
7854
+ return this.io.readFile(path3);
7855
+ }
7856
+ readDir(path3) {
7857
+ this.say(`? list ${path3}`, 2);
7858
+ return this.io.readDir(path3);
7859
+ }
7860
+ // --- effects: narrated always, performed unless --dry-run -----------------
7861
+ /**
7862
+ * Ask before applying. `--yes` and `--dry-run` answer yes; off a terminal
7863
+ * without `--yes` the answer is an error, never a hang.
7864
+ */
7865
+ async confirm(question) {
7866
+ if (this.yes || this.dryRun) {
7867
+ this.say(`? ${question} yes (${this.yes ? "--yes" : "--dry-run"})`, 1);
7868
+ return true;
7717
7869
  }
7718
- pointer.set(depArray);
7719
- });
7870
+ if (!this.io.prompt)
7871
+ throw new Error(`cannot ask "${question}" without a terminal; pass --yes`);
7872
+ return this.io.prompt(question);
7873
+ }
7874
+ /** Narrate and perform each step in order; the first failure stops the run. */
7875
+ async apply(plan) {
7876
+ for (const step of plan) {
7877
+ this.say(`${this.dryRun ? "[dry-run] " : ""}${describe(step)}`);
7878
+ const input = body(step);
7879
+ if (input !== void 0)
7880
+ this.say(indent(input), step.kind === "write" ? 2 : 1);
7881
+ if (!this.dryRun)
7882
+ await this.perform(step);
7883
+ }
7884
+ }
7885
+ /**
7886
+ * Perform a step on scratch state, whatever the mode: the one exception to
7887
+ * "a dry run performs no effect", for a preview that has to run a tool
7888
+ * against a throwaway copy to be honest. Resolves with the output of a run.
7889
+ */
7890
+ stage(step) {
7891
+ this.say(`? ${describe(step)}`, 1);
7892
+ const input = body(step);
7893
+ if (input !== void 0)
7894
+ this.say(indent(input), 2);
7895
+ return this.perform(step);
7896
+ }
7897
+ async perform(step) {
7898
+ const inherit = this.verbose >= 2 || step.kind === "run" && step.interactive === true;
7899
+ switch (step.kind) {
7900
+ case "run":
7901
+ return this.io.exec(step.command, step.args, { cwd: step.cwd, input: step.input, inherit });
7902
+ case "ssh":
7903
+ return this.io.exec("ssh", [step.host, "bash", "-s"], { input: step.script, inherit });
7904
+ case "write":
7905
+ await this.io.writeFile(step.path, step.content);
7906
+ return void 0;
7907
+ }
7908
+ }
7909
+ };
7910
+ function renderHuman(data) {
7911
+ if (typeof data === "string")
7912
+ return data;
7913
+ if (Array.isArray(data))
7914
+ return data.map(String).join("\n");
7915
+ return JSON.stringify(data, null, 2);
7916
+ }
7917
+ function indent(text) {
7918
+ return text.trimEnd().split("\n").map((l) => ` ${l}`).join("\n");
7720
7919
  }
7721
7920
 
7722
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/theme.js
7723
- import { styleText } from "node:util";
7921
+ // ../lib/dist/copier.js
7922
+ var import_yaml2 = __toESM(require_dist(), 1);
7923
+ var ANSWERS_FILE = ".copier-answers.yml";
7924
+ var TEMPLATE_FILES = ["copier.yml", "copier.yaml"];
7925
+ function parseAnswers(text) {
7926
+ const data = (0, import_yaml2.parse)(text);
7927
+ if (data === null || typeof data !== "object" || Array.isArray(data))
7928
+ throw new Error("answers file is not a mapping");
7929
+ const { _commit, _src_path, ...answers } = data;
7930
+ return {
7931
+ commit: _commit === void 0 ? void 0 : String(_commit),
7932
+ src: _src_path === void 0 ? void 0 : String(_src_path),
7933
+ answers
7934
+ };
7935
+ }
7724
7936
 
7725
- // ../../node_modules/.pnpm/@inquirer+figures@2.0.9/node_modules/@inquirer/figures/dist/index.js
7726
- import process2 from "node:process";
7727
- function isUnicodeSupported() {
7728
- if (!process2.platform.startsWith("win")) {
7729
- return process2.env["TERM"] !== "linux";
7937
+ // ../lib/dist/doctor.js
7938
+ import { relative as relative2 } from "node:path";
7939
+ function diagnose(root, catalog) {
7940
+ const units = collect(root, []);
7941
+ const declarations = units.map((u) => diagnoseUnit(u, units, catalog, root.path));
7942
+ return { declarations, stale: declarations.filter((d) => d.findings.length > 0).length };
7943
+ }
7944
+ function collect(dir, ancestors, parent) {
7945
+ const here = dir.declaration || dir.problems?.some((p) => p.startsWith("PLEXUS.md")) ? [{ dir, ancestors, parent }] : [];
7946
+ const below = dir.declaration ? [...ancestors, dir] : ancestors;
7947
+ return [...here, ...dir.children.flatMap((c) => collect(c, below, dir))];
7948
+ }
7949
+ function diagnoseUnit(unit, units, catalog, root) {
7950
+ const { dir } = unit;
7951
+ const path3 = relative2(root, dir.path) || ".";
7952
+ const problem = dir.problems?.find((p) => p.startsWith("PLEXUS.md"));
7953
+ if (!dir.declaration)
7954
+ return { path: path3, modules: [], findings: [problem?.replace(/^PLEXUS\.md: /, "") ?? "unreadable marker"] };
7955
+ const { plexus, modules } = dir.declaration;
7956
+ const context = new Set(contextOf(unit, units).flatMap((d) => d.declaration?.modules ?? []));
7957
+ const findings = [];
7958
+ for (const code of modules) {
7959
+ const module = catalog.get(code);
7960
+ if (!module) {
7961
+ findings.push(`declares ${code}, which no module carries`);
7962
+ continue;
7963
+ }
7964
+ if (module.changed && compareTrains(module.changed, plexus) > 0)
7965
+ findings.push(`${code} changed in ${module.changed}, declared at ${plexus}`);
7966
+ for (const dep of module.depends)
7967
+ if (!modules.includes(dep) && !context.has(dep))
7968
+ findings.push(`${code} depends on ${dep}, declared neither here nor by an enclosing or contained declaration`);
7730
7969
  }
7731
- return Boolean(process2.env["CI"]) || // CI environments generally support unicode
7732
- Boolean(process2.env["WT_SESSION"]) || // Windows Terminal
7733
- Boolean(process2.env["TERMINUS_SUBLIME"]) || // Terminus (<0.2.27)
7734
- process2.env["ConEmuTask"] === "{cmd::Cmder}" || // ConEmu and cmder
7735
- process2.env["TERM_PROGRAM"] === "Terminus-Sublime" || process2.env["TERM_PROGRAM"] === "vscode" || process2.env["TERM"] === "xterm-256color" || process2.env["TERM"] === "alacritty" || process2.env["TERMINAL_EMULATOR"] === "JetBrains-JediTerm";
7970
+ return { path: path3, plexus, modules, findings };
7971
+ }
7972
+ function contextOf(unit, units) {
7973
+ const { dir, ancestors } = unit;
7974
+ const context = [...ancestors, ...descendants(dir)];
7975
+ const repo = ancestors[0] ?? dir;
7976
+ const repoParent = units.find((u) => u.dir === repo)?.parent;
7977
+ const siblings = repoParent?.children.filter((c) => c !== repo && c.declaration) ?? [];
7978
+ const isTenancy = (d) => d.declaration?.modules.includes("PLX-Tenancy") ?? false;
7979
+ context.push(...siblings.filter(isTenancy));
7980
+ if (isTenancy(dir))
7981
+ context.push(...siblings);
7982
+ return context;
7983
+ }
7984
+ function descendants(dir) {
7985
+ return dir.children.flatMap((c) => [...c.declaration ? [c] : [], ...descendants(c)]);
7986
+ }
7987
+ function compareTrains(a, b) {
7988
+ const nums = (v) => v.split(".").slice(0, 3).map((p) => Number.parseInt(p, 10) || 0);
7989
+ const [x, y] = [nums(a), nums(b)];
7990
+ for (let i = 0; i < 3; i++)
7991
+ if ((x[i] ?? 0) !== (y[i] ?? 0))
7992
+ return (x[i] ?? 0) > (y[i] ?? 0) ? 1 : -1;
7993
+ return 0;
7736
7994
  }
7737
- var common = {
7738
- circleQuestionMark: "(?)",
7739
- questionMarkPrefix: "(?)",
7740
- square: "\u2588",
7741
- squareDarkShade: "\u2593",
7742
- squareMediumShade: "\u2592",
7743
- squareLightShade: "\u2591",
7744
- squareTop: "\u2580",
7745
- squareBottom: "\u2584",
7746
- squareLeft: "\u258C",
7747
- squareRight: "\u2590",
7748
- squareCenter: "\u25A0",
7749
- bullet: "\u25CF",
7750
- dot: "\u2024",
7751
- ellipsis: "\u2026",
7752
- pointerSmall: "\u203A",
7753
- triangleUp: "\u25B2",
7754
- triangleUpSmall: "\u25B4",
7755
- triangleDown: "\u25BC",
7756
- triangleDownSmall: "\u25BE",
7757
- triangleLeftSmall: "\u25C2",
7758
- triangleRightSmall: "\u25B8",
7759
- home: "\u2302",
7760
- heart: "\u2665",
7761
- musicNote: "\u266A",
7762
- musicNoteBeamed: "\u266B",
7763
- arrowUp: "\u2191",
7764
- arrowDown: "\u2193",
7765
- arrowLeft: "\u2190",
7766
- arrowRight: "\u2192",
7767
- arrowLeftRight: "\u2194",
7768
- arrowUpDown: "\u2195",
7769
- almostEqual: "\u2248",
7770
- notEqual: "\u2260",
7771
- lessOrEqual: "\u2264",
7772
- greaterOrEqual: "\u2265",
7773
- identical: "\u2261",
7774
- infinity: "\u221E",
7775
- subscriptZero: "\u2080",
7776
- subscriptOne: "\u2081",
7777
- subscriptTwo: "\u2082",
7778
- subscriptThree: "\u2083",
7779
- subscriptFour: "\u2084",
7780
- subscriptFive: "\u2085",
7781
- subscriptSix: "\u2086",
7782
- subscriptSeven: "\u2087",
7783
- subscriptEight: "\u2088",
7784
- subscriptNine: "\u2089",
7785
- oneHalf: "\xBD",
7786
- oneThird: "\u2153",
7787
- oneQuarter: "\xBC",
7788
- oneFifth: "\u2155",
7789
- oneSixth: "\u2159",
7790
- oneEighth: "\u215B",
7791
- twoThirds: "\u2154",
7792
- twoFifths: "\u2156",
7793
- threeQuarters: "\xBE",
7794
- threeFifths: "\u2157",
7795
- threeEighths: "\u215C",
7796
- fourFifths: "\u2158",
7797
- fiveSixths: "\u215A",
7798
- fiveEighths: "\u215D",
7799
- sevenEighths: "\u215E",
7800
- line: "\u2500",
7801
- lineBold: "\u2501",
7802
- lineDouble: "\u2550",
7803
- lineDashed0: "\u2504",
7804
- lineDashed1: "\u2505",
7805
- lineDashed2: "\u2508",
7806
- lineDashed3: "\u2509",
7807
- lineDashed4: "\u254C",
7808
- lineDashed5: "\u254D",
7809
- lineDashed6: "\u2574",
7810
- lineDashed7: "\u2576",
7811
- lineDashed8: "\u2578",
7812
- lineDashed9: "\u257A",
7813
- lineDashed10: "\u257C",
7814
- lineDashed11: "\u257E",
7815
- lineDashed12: "\u2212",
7816
- lineDashed13: "\u2013",
7817
- lineDashed14: "\u2010",
7818
- lineDashed15: "\u2043",
7819
- lineVertical: "\u2502",
7820
- lineVerticalBold: "\u2503",
7821
- lineVerticalDouble: "\u2551",
7822
- lineVerticalDashed0: "\u2506",
7823
- lineVerticalDashed1: "\u2507",
7824
- lineVerticalDashed2: "\u250A",
7825
- lineVerticalDashed3: "\u250B",
7826
- lineVerticalDashed4: "\u254E",
7827
- lineVerticalDashed5: "\u254F",
7828
- lineVerticalDashed6: "\u2575",
7829
- lineVerticalDashed7: "\u2577",
7830
- lineVerticalDashed8: "\u2579",
7831
- lineVerticalDashed9: "\u257B",
7832
- lineVerticalDashed10: "\u257D",
7833
- lineVerticalDashed11: "\u257F",
7834
- lineDownLeft: "\u2510",
7835
- lineDownLeftArc: "\u256E",
7836
- lineDownBoldLeftBold: "\u2513",
7837
- lineDownBoldLeft: "\u2512",
7838
- lineDownLeftBold: "\u2511",
7839
- lineDownDoubleLeftDouble: "\u2557",
7840
- lineDownDoubleLeft: "\u2556",
7841
- lineDownLeftDouble: "\u2555",
7842
- lineDownRight: "\u250C",
7843
- lineDownRightArc: "\u256D",
7844
- lineDownBoldRightBold: "\u250F",
7845
- lineDownBoldRight: "\u250E",
7846
- lineDownRightBold: "\u250D",
7847
- lineDownDoubleRightDouble: "\u2554",
7848
- lineDownDoubleRight: "\u2553",
7849
- lineDownRightDouble: "\u2552",
7850
- lineUpLeft: "\u2518",
7851
- lineUpLeftArc: "\u256F",
7852
- lineUpBoldLeftBold: "\u251B",
7853
- lineUpBoldLeft: "\u251A",
7854
- lineUpLeftBold: "\u2519",
7855
- lineUpDoubleLeftDouble: "\u255D",
7856
- lineUpDoubleLeft: "\u255C",
7857
- lineUpLeftDouble: "\u255B",
7858
- lineUpRight: "\u2514",
7859
- lineUpRightArc: "\u2570",
7860
- lineUpBoldRightBold: "\u2517",
7861
- lineUpBoldRight: "\u2516",
7862
- lineUpRightBold: "\u2515",
7863
- lineUpDoubleRightDouble: "\u255A",
7864
- lineUpDoubleRight: "\u2559",
7865
- lineUpRightDouble: "\u2558",
7866
- lineUpDownLeft: "\u2524",
7867
- lineUpBoldDownBoldLeftBold: "\u252B",
7868
- lineUpBoldDownBoldLeft: "\u2528",
7869
- lineUpDownLeftBold: "\u2525",
7870
- lineUpBoldDownLeftBold: "\u2529",
7871
- lineUpDownBoldLeftBold: "\u252A",
7872
- lineUpDownBoldLeft: "\u2527",
7873
- lineUpBoldDownLeft: "\u2526",
7874
- lineUpDoubleDownDoubleLeftDouble: "\u2563",
7875
- lineUpDoubleDownDoubleLeft: "\u2562",
7876
- lineUpDownLeftDouble: "\u2561",
7877
- lineUpDownRight: "\u251C",
7878
- lineUpBoldDownBoldRightBold: "\u2523",
7879
- lineUpBoldDownBoldRight: "\u2520",
7880
- lineUpDownRightBold: "\u251D",
7881
- lineUpBoldDownRightBold: "\u2521",
7882
- lineUpDownBoldRightBold: "\u2522",
7883
- lineUpDownBoldRight: "\u251F",
7884
- lineUpBoldDownRight: "\u251E",
7885
- lineUpDoubleDownDoubleRightDouble: "\u2560",
7886
- lineUpDoubleDownDoubleRight: "\u255F",
7887
- lineUpDownRightDouble: "\u255E",
7888
- lineDownLeftRight: "\u252C",
7889
- lineDownBoldLeftBoldRightBold: "\u2533",
7890
- lineDownLeftBoldRightBold: "\u252F",
7891
- lineDownBoldLeftRight: "\u2530",
7892
- lineDownBoldLeftBoldRight: "\u2531",
7893
- lineDownBoldLeftRightBold: "\u2532",
7894
- lineDownLeftRightBold: "\u252E",
7895
- lineDownLeftBoldRight: "\u252D",
7896
- lineDownDoubleLeftDoubleRightDouble: "\u2566",
7897
- lineDownDoubleLeftRight: "\u2565",
7898
- lineDownLeftDoubleRightDouble: "\u2564",
7899
- lineUpLeftRight: "\u2534",
7900
- lineUpBoldLeftBoldRightBold: "\u253B",
7901
- lineUpLeftBoldRightBold: "\u2537",
7902
- lineUpBoldLeftRight: "\u2538",
7903
- lineUpBoldLeftBoldRight: "\u2539",
7904
- lineUpBoldLeftRightBold: "\u253A",
7905
- lineUpLeftRightBold: "\u2536",
7906
- lineUpLeftBoldRight: "\u2535",
7907
- lineUpDoubleLeftDoubleRightDouble: "\u2569",
7908
- lineUpDoubleLeftRight: "\u2568",
7909
- lineUpLeftDoubleRightDouble: "\u2567",
7910
- lineUpDownLeftRight: "\u253C",
7911
- lineUpBoldDownBoldLeftBoldRightBold: "\u254B",
7912
- lineUpDownBoldLeftBoldRightBold: "\u2548",
7913
- lineUpBoldDownLeftBoldRightBold: "\u2547",
7914
- lineUpBoldDownBoldLeftRightBold: "\u254A",
7915
- lineUpBoldDownBoldLeftBoldRight: "\u2549",
7916
- lineUpBoldDownLeftRight: "\u2540",
7917
- lineUpDownBoldLeftRight: "\u2541",
7918
- lineUpDownLeftBoldRight: "\u253D",
7919
- lineUpDownLeftRightBold: "\u253E",
7920
- lineUpBoldDownBoldLeftRight: "\u2542",
7921
- lineUpDownLeftBoldRightBold: "\u253F",
7922
- lineUpBoldDownLeftBoldRight: "\u2543",
7923
- lineUpBoldDownLeftRightBold: "\u2544",
7924
- lineUpDownBoldLeftBoldRight: "\u2545",
7925
- lineUpDownBoldLeftRightBold: "\u2546",
7926
- lineUpDoubleDownDoubleLeftDoubleRightDouble: "\u256C",
7927
- lineUpDoubleDownDoubleLeftRight: "\u256B",
7928
- lineUpDownLeftDoubleRightDouble: "\u256A",
7929
- lineCross: "\u2573",
7930
- lineBackslash: "\u2572",
7931
- lineSlash: "\u2571"
7932
- };
7933
- var specialMainSymbols = {
7934
- tick: "\u2714",
7935
- info: "\u2139",
7936
- warning: "\u26A0",
7937
- cross: "\u2718",
7938
- squareSmall: "\u25FB",
7939
- squareSmallFilled: "\u25FC",
7940
- circle: "\u25EF",
7941
- circleFilled: "\u25C9",
7942
- circleDotted: "\u25CC",
7943
- circleDouble: "\u25CE",
7944
- circleCircle: "\u24DE",
7945
- circleCross: "\u24E7",
7946
- circlePipe: "\u24BE",
7947
- radioOn: "\u25C9",
7948
- radioOff: "\u25EF",
7949
- checkboxOn: "\u2612",
7950
- checkboxOff: "\u2610",
7951
- checkboxCircleOn: "\u24E7",
7952
- checkboxCircleOff: "\u24BE",
7953
- pointer: "\u276F",
7954
- triangleUpOutline: "\u25B3",
7955
- triangleLeft: "\u25C0",
7956
- triangleRight: "\u25B6",
7957
- lozenge: "\u25C6",
7958
- lozengeOutline: "\u25C7",
7959
- hamburger: "\u2630",
7960
- smiley: "\u32E1",
7961
- mustache: "\u0DF4",
7962
- star: "\u2605",
7963
- play: "\u25B6",
7964
- nodejs: "\u2B22",
7965
- oneSeventh: "\u2150",
7966
- oneNinth: "\u2151",
7967
- oneTenth: "\u2152"
7968
- };
7969
- var specialFallbackSymbols = {
7970
- tick: "\u221A",
7971
- info: "i",
7972
- warning: "\u203C",
7973
- cross: "\xD7",
7974
- squareSmall: "\u25A1",
7975
- squareSmallFilled: "\u25A0",
7976
- circle: "( )",
7977
- circleFilled: "(*)",
7978
- circleDotted: "( )",
7979
- circleDouble: "( )",
7980
- circleCircle: "(\u25CB)",
7981
- circleCross: "(\xD7)",
7982
- circlePipe: "(\u2502)",
7983
- radioOn: "(*)",
7984
- radioOff: "( )",
7985
- checkboxOn: "[\xD7]",
7986
- checkboxOff: "[ ]",
7987
- checkboxCircleOn: "(\xD7)",
7988
- checkboxCircleOff: "( )",
7989
- pointer: ">",
7990
- triangleUpOutline: "\u2206",
7991
- triangleLeft: "\u25C4",
7992
- triangleRight: "\u25BA",
7993
- lozenge: "\u2666",
7994
- lozengeOutline: "\u25CA",
7995
- hamburger: "\u2261",
7996
- smiley: "\u263A",
7997
- mustache: "\u250C\u2500\u2510",
7998
- star: "\u2736",
7999
- play: "\u25BA",
8000
- nodejs: "\u2666",
8001
- oneSeventh: "1/7",
8002
- oneNinth: "1/9",
8003
- oneTenth: "1/10"
8004
- };
8005
- var mainSymbols = {
8006
- ...common,
8007
- ...specialMainSymbols
8008
- };
8009
- var fallbackSymbols = {
8010
- ...common,
8011
- ...specialFallbackSymbols
8012
- };
8013
- var shouldUseMain = isUnicodeSupported();
8014
- var figures = shouldUseMain ? mainSymbols : fallbackSymbols;
8015
- var dist_default = figures;
8016
- var replacements = Object.entries(specialMainSymbols);
8017
-
8018
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/theme.js
8019
- var defaultTheme = {
8020
- prefix: {
8021
- idle: styleText("blue", "?"),
8022
- done: styleText("green", dist_default.tick)
8023
- },
8024
- spinner: {
8025
- interval: 80,
8026
- frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"].map((frame) => styleText("yellow", frame))
8027
- },
8028
- keybindings: [],
8029
- style: {
8030
- answer: (text) => styleText("cyan", text),
8031
- message: (text) => styleText("bold", text),
8032
- error: (text) => styleText("red", `> ${text}`),
8033
- defaultAnswer: (text) => styleText("dim", `(${text})`),
8034
- help: (text) => styleText("dim", text),
8035
- highlight: (text) => styleText("cyan", text),
8036
- key: (text) => styleText("cyan", styleText("bold", `<${text}>`))
8037
- }
8038
- };
8039
- function getDefaultTheme() {
8040
- return {
8041
- ...defaultTheme,
8042
- keybindings: getDefaultKeybindings()
8043
- };
8044
- }
8045
-
8046
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/make-theme.js
8047
- function isPlainObject(value) {
8048
- if (typeof value !== "object" || value === null)
8049
- return false;
8050
- let proto = value;
8051
- while (Object.getPrototypeOf(proto) !== null) {
8052
- proto = Object.getPrototypeOf(proto);
8053
- }
8054
- return Object.getPrototypeOf(value) === proto;
8055
- }
8056
- function deepMerge(...objects) {
8057
- const output = {};
8058
- for (const obj of objects) {
8059
- for (const [key, value] of Object.entries(obj)) {
8060
- const prevValue = output[key];
8061
- output[key] = isPlainObject(prevValue) && isPlainObject(value) ? deepMerge(prevValue, value) : value;
8062
- }
8063
- }
8064
- return output;
8065
- }
8066
- function makeTheme(...themes) {
8067
- const themesToMerge = [
8068
- getDefaultTheme(),
8069
- ...themes.filter((theme) => theme != null)
8070
- ];
8071
- return deepMerge(...themesToMerge);
8072
- }
8073
-
8074
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/use-prefix.js
8075
- function usePrefix({ status = "idle", theme }) {
8076
- const [showLoader, setShowLoader] = useState(false);
8077
- const [tick, setTick] = useState(0);
8078
- const { prefix, spinner } = makeTheme(theme);
8079
- useEffect(() => {
8080
- if (status === "loading") {
8081
- let tickInterval;
8082
- let inc = -1;
8083
- const delayTimeout = setTimeout(() => {
8084
- setShowLoader(true);
8085
- tickInterval = setInterval(() => {
8086
- inc = inc + 1;
8087
- setTick(inc % spinner.frames.length);
8088
- }, spinner.interval);
8089
- }, 300);
8090
- return () => {
8091
- clearTimeout(delayTimeout);
8092
- clearInterval(tickInterval);
8093
- };
8094
- } else {
8095
- setShowLoader(false);
8096
- }
8097
- }, [status]);
8098
- if (showLoader) {
8099
- return spinner.frames[tick];
8100
- }
8101
- const iconName = status === "loading" ? "idle" : status;
8102
- return typeof prefix === "string" ? prefix : prefix[iconName] ?? prefix["idle"];
8103
- }
8104
-
8105
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/use-ref.js
8106
- function useRef(val) {
8107
- return useState({ current: val })[0];
8108
- }
8109
-
8110
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/use-keypress.js
8111
- function useKeypress(userHandler) {
8112
- const signal = useRef(userHandler);
8113
- signal.current = userHandler;
8114
- useEffect((rl) => {
8115
- let ignore = false;
8116
- const handler = withUpdates((_input, event) => {
8117
- if (ignore)
8118
- return;
8119
- void signal.current(event, rl);
8120
- });
8121
- rl.input.on("keypress", handler);
8122
- return () => {
8123
- ignore = true;
8124
- rl.input.removeListener("keypress", handler);
8125
- };
8126
- }, []);
8127
- }
8128
-
8129
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/utils.js
8130
- var import_cli_width = __toESM(require_cli_width(), 1);
8131
-
8132
- // ../../node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/utils.js
8133
- var getCodePointsLength = /* @__PURE__ */ (() => {
8134
- const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
8135
- return (input) => {
8136
- let surrogatePairsNr = 0;
8137
- SURROGATE_PAIR_RE.lastIndex = 0;
8138
- while (SURROGATE_PAIR_RE.test(input)) {
8139
- surrogatePairsNr += 1;
8140
- }
8141
- return input.length - surrogatePairsNr;
8142
- };
8143
- })();
8144
- var isFullWidth = (x) => {
8145
- return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
8146
- };
8147
- var isWideNotCJKTNotEmoji = (x) => {
8148
- return x === 8987 || x === 9001 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
8149
- };
8150
-
8151
- // ../../node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/index.js
8152
- var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
8153
- var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
8154
- var CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
8155
- var TAB_RE = /\t{1,1000}/y;
8156
- var EMOJI_RE = new RegExp("[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*", "yu");
8157
- var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
8158
- var MODIFIER_RE = new RegExp("\\p{M}+", "gu");
8159
- var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
8160
- var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
8161
- const LIMIT = truncationOptions.limit ?? Infinity;
8162
- const ELLIPSIS = truncationOptions.ellipsis ?? "";
8163
- const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
8164
- const ANSI_WIDTH = 0;
8165
- const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
8166
- const TAB_WIDTH = widthOptions.tabWidth ?? 8;
8167
- const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
8168
- const FULL_WIDTH_WIDTH = 2;
8169
- const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
8170
- const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
8171
- const PARSE_BLOCKS = [
8172
- [LATIN_RE, REGULAR_WIDTH],
8173
- [ANSI_RE, ANSI_WIDTH],
8174
- [CONTROL_RE, CONTROL_WIDTH],
8175
- [TAB_RE, TAB_WIDTH],
8176
- [EMOJI_RE, EMOJI_WIDTH],
8177
- [CJKT_WIDE_RE, WIDE_WIDTH]
8178
- ];
8179
- let indexPrev = 0;
8180
- let index = 0;
8181
- let length = input.length;
8182
- let lengthExtra = 0;
8183
- let truncationEnabled = false;
8184
- let truncationIndex = length;
8185
- let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
8186
- let unmatchedStart = 0;
8187
- let unmatchedEnd = 0;
8188
- let width = 0;
8189
- let widthExtra = 0;
8190
- outer: while (true) {
8191
- if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
8192
- const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
8193
- lengthExtra = 0;
8194
- for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
8195
- const codePoint = char.codePointAt(0) || 0;
8196
- if (isFullWidth(codePoint)) {
8197
- widthExtra = FULL_WIDTH_WIDTH;
8198
- } else if (isWideNotCJKTNotEmoji(codePoint)) {
8199
- widthExtra = WIDE_WIDTH;
8200
- } else {
8201
- widthExtra = REGULAR_WIDTH;
8202
- }
8203
- if (width + widthExtra > truncationLimit) {
8204
- truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
8205
- }
8206
- if (width + widthExtra > LIMIT) {
8207
- truncationEnabled = true;
8208
- break outer;
8209
- }
8210
- lengthExtra += char.length;
8211
- width += widthExtra;
8212
- }
8213
- unmatchedStart = unmatchedEnd = 0;
8214
- }
8215
- if (index >= length) {
8216
- break outer;
8217
- }
8218
- for (let i = 0, l = PARSE_BLOCKS.length; i < l; i++) {
8219
- const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
8220
- BLOCK_RE.lastIndex = index;
8221
- if (BLOCK_RE.test(input)) {
8222
- lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
8223
- widthExtra = lengthExtra * BLOCK_WIDTH;
8224
- if (width + widthExtra > truncationLimit) {
8225
- truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
8226
- }
8227
- if (width + widthExtra > LIMIT) {
8228
- truncationEnabled = true;
8229
- break outer;
8230
- }
8231
- width += widthExtra;
8232
- unmatchedStart = indexPrev;
8233
- unmatchedEnd = index;
8234
- index = indexPrev = BLOCK_RE.lastIndex;
8235
- continue outer;
8236
- }
8237
- }
8238
- index += 1;
8239
- }
8240
- return {
8241
- width: truncationEnabled ? truncationLimit : width,
8242
- index: truncationEnabled ? truncationIndex : length,
8243
- truncated: truncationEnabled,
8244
- ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
8245
- };
8246
- };
8247
- var dist_default2 = getStringTruncatedWidth;
8248
-
8249
- // ../../node_modules/.pnpm/fast-string-width@3.0.2/node_modules/fast-string-width/dist/index.js
8250
- var NO_TRUNCATION2 = {
8251
- limit: Infinity,
8252
- ellipsis: "",
8253
- ellipsisWidth: 0
8254
- };
8255
- var fastStringWidth = (input, options = {}) => {
8256
- return dist_default2(input, NO_TRUNCATION2, options).width;
8257
- };
8258
- var dist_default3 = fastStringWidth;
8259
7995
 
8260
- // ../../node_modules/.pnpm/fast-wrap-ansi@0.2.2/node_modules/fast-wrap-ansi/lib/main.js
8261
- var ESC = "\x1B";
8262
- var CSI = "\x9B";
8263
- var END_CODE = 39;
8264
- var ANSI_ESCAPE_BELL = "\x07";
8265
- var ANSI_CSI = "[";
8266
- var ANSI_OSC = "]";
8267
- var ANSI_SGR_TERMINATOR = "m";
8268
- var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
8269
- var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
8270
- var getClosingCode = (openingCode) => {
8271
- if (openingCode >= 30 && openingCode <= 37)
8272
- return 39;
8273
- if (openingCode >= 90 && openingCode <= 97)
8274
- return 39;
8275
- if (openingCode >= 40 && openingCode <= 47)
8276
- return 49;
8277
- if (openingCode >= 100 && openingCode <= 107)
8278
- return 49;
8279
- if (openingCode === 1 || openingCode === 2)
8280
- return 22;
8281
- if (openingCode === 3)
8282
- return 23;
8283
- if (openingCode === 4)
8284
- return 24;
8285
- if (openingCode === 7)
8286
- return 27;
8287
- if (openingCode === 8)
8288
- return 28;
8289
- if (openingCode === 9)
8290
- return 29;
8291
- if (openingCode === 0)
8292
- return 0;
7996
+ // ../lib/dist/model.js
7997
+ function kindOf(declaration) {
7998
+ const has = (code) => declaration.modules.includes(code);
7999
+ if (has("PLX-App"))
8000
+ return "app";
8001
+ if (has("PLX-Platform"))
8002
+ return "platform";
8003
+ if (has("PLX-Repo"))
8004
+ return "repo";
8293
8005
  return void 0;
8294
- };
8295
- var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
8296
- var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
8297
- var wrapWord = (rows, word, columns) => {
8298
- const characters = word[Symbol.iterator]();
8299
- let isInsideEscape = false;
8300
- let isInsideLinkEscape = false;
8301
- let lastRow = rows.at(-1);
8302
- let visible = lastRow === void 0 ? 0 : dist_default3(lastRow);
8303
- let currentCharacter = characters.next();
8304
- let nextCharacter = characters.next();
8305
- let rawCharacterIndex = 0;
8306
- while (!currentCharacter.done) {
8307
- const character = currentCharacter.value;
8308
- const characterLength = dist_default3(character);
8309
- if (visible + characterLength <= columns) {
8310
- rows[rows.length - 1] += character;
8311
- } else {
8312
- rows.push(character);
8313
- visible = 0;
8314
- }
8315
- if (character === ESC || character === CSI) {
8316
- isInsideEscape = true;
8317
- isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
8318
- }
8319
- if (isInsideEscape) {
8320
- if (isInsideLinkEscape) {
8321
- if (character === ANSI_ESCAPE_BELL) {
8322
- isInsideEscape = false;
8323
- isInsideLinkEscape = false;
8324
- }
8325
- } else if (character === ANSI_SGR_TERMINATOR) {
8326
- isInsideEscape = false;
8327
- }
8328
- } else {
8329
- visible += characterLength;
8330
- if (visible === columns && !nextCharacter.done) {
8331
- rows.push("");
8332
- visible = 0;
8333
- }
8334
- }
8335
- currentCharacter = nextCharacter;
8336
- nextCharacter = characters.next();
8337
- rawCharacterIndex += character.length;
8006
+ }
8007
+ function shortRemote(url) {
8008
+ const bare = url.replace(/\.git$/, "").replace(/\/$/, "");
8009
+ const m = /^(?:git@github\.com:|github\.com:|ssh:\/\/git@github\.com\/|https?:\/\/github\.com\/)(.+)$/.exec(bare);
8010
+ return m ? `gh:${m[1]}` : bare;
8011
+ }
8012
+ function isNotable(dir) {
8013
+ return Boolean(dir.git || dir.template || dir.copier || dir.declaration || dir.problems?.length);
8014
+ }
8015
+
8016
+ // ../lib/dist/overview.js
8017
+ import { join as join2 } from "node:path";
8018
+ var PRUNED = /* @__PURE__ */ new Set([
8019
+ "node_modules",
8020
+ ".hg",
8021
+ ".svn",
8022
+ ".next",
8023
+ ".nuxt",
8024
+ ".turbo",
8025
+ ".svelte-kit",
8026
+ "dist",
8027
+ "build",
8028
+ "out",
8029
+ ".output",
8030
+ ".venv",
8031
+ "venv",
8032
+ "__pycache__",
8033
+ "target",
8034
+ ".cache",
8035
+ ".pnpm-store",
8036
+ "coverage",
8037
+ "vendor",
8038
+ ".terraform",
8039
+ ".gradle"
8040
+ ]);
8041
+ function overview(ctx, root, options = {}) {
8042
+ return walk(ctx, root, root.replace(/\/+$/, "").split("/").pop() || root, { git: true, ...options });
8043
+ }
8044
+ async function walk(ctx, path3, name, options) {
8045
+ const entries = await ctx.readDir(path3);
8046
+ const files = new Set(entries.filter((e) => !e.directory).map((e) => e.name));
8047
+ const names = new Set(entries.map((e) => e.name));
8048
+ const dir = { name, path: path3, children: [] };
8049
+ if (names.has(".git") && options.git)
8050
+ dir.git = await gitFacet(ctx, path3);
8051
+ if (TEMPLATE_FILES.some((f) => files.has(f)))
8052
+ dir.template = options.git ? await templateFacet(ctx, path3) : {};
8053
+ if (files.has(ANSWERS_FILE)) {
8054
+ await facet(ctx, dir, ANSWERS_FILE, (text) => {
8055
+ dir.copier = parseAnswers(text);
8056
+ });
8338
8057
  }
8339
- lastRow = rows.at(-1);
8340
- if (!visible && lastRow !== void 0 && lastRow.length && rows.length > 1) {
8341
- rows[rows.length - 2] += rows.pop();
8058
+ if (files.has(MARKER_FILE)) {
8059
+ await facet(ctx, dir, MARKER_FILE, (text) => {
8060
+ dir.declaration = parseMarker(text);
8061
+ });
8342
8062
  }
8343
- };
8344
- var stringVisibleTrimSpacesRight = (string) => {
8345
- const words = string.split(" ");
8346
- let last = words.length;
8347
- while (last) {
8348
- if (dist_default3(words[last - 1])) {
8063
+ const subdirs = entries.filter((e) => e.directory && e.name !== ".git" && !PRUNED.has(e.name)).map((e) => e.name).sort();
8064
+ for (const sub of subdirs) {
8065
+ const child = await walk(ctx, join2(path3, sub), sub, options);
8066
+ if (isNotable(child) || child.children.length > 0)
8067
+ dir.children.push(child);
8068
+ }
8069
+ return dir;
8070
+ }
8071
+ async function facet(ctx, dir, file, read) {
8072
+ try {
8073
+ read(await ctx.readFile(join2(dir.path, file)));
8074
+ } catch (error) {
8075
+ dir.problems ??= [];
8076
+ dir.problems.push(`${file}: ${error instanceof Error ? error.message : String(error)}`);
8077
+ }
8078
+ }
8079
+ async function git(ctx, cwd, args) {
8080
+ try {
8081
+ const out = (await ctx.read("git", args, { cwd })).trim();
8082
+ return out === "" ? void 0 : out;
8083
+ } catch {
8084
+ return void 0;
8085
+ }
8086
+ }
8087
+ async function gitFacet(ctx, cwd) {
8088
+ const branch = await git(ctx, cwd, ["symbolic-ref", "--short", "-q", "HEAD"]) ?? await git(ctx, cwd, ["rev-parse", "--short", "HEAD"]) ?? "?";
8089
+ const dirty = await git(ctx, cwd, ["status", "--porcelain"]) !== void 0;
8090
+ const remote = await git(ctx, cwd, ["remote", "get-url", "origin"]);
8091
+ let defaultRef = await git(ctx, cwd, ["symbolic-ref", "--short", "-q", "refs/remotes/origin/HEAD"]);
8092
+ for (const b of ["main", "master"]) {
8093
+ if (defaultRef)
8349
8094
  break;
8350
- }
8351
- last--;
8095
+ if (await git(ctx, cwd, ["rev-parse", "--verify", "-q", `refs/heads/${b}`]))
8096
+ defaultRef = b;
8352
8097
  }
8353
- if (last === words.length) {
8354
- return string;
8098
+ const tag = defaultRef ? await git(ctx, cwd, ["describe", "--tags", "--abbrev=0", defaultRef]) : void 0;
8099
+ const facet2 = { branch, dirty };
8100
+ if (tag)
8101
+ facet2.tag = tag;
8102
+ if (remote)
8103
+ facet2.remote = shortRemote(remote);
8104
+ return facet2;
8105
+ }
8106
+ async function templateFacet(ctx, cwd) {
8107
+ const tag = await git(ctx, cwd, ["describe", "--tags", "--abbrev=0"]) ?? (await git(ctx, cwd, ["tag", "--list", "--sort=-v:refname"]))?.split("\n")[0];
8108
+ return tag ? { tag } : {};
8109
+ }
8110
+
8111
+ // ../lib/dist/propagate.js
8112
+ import { join as join4, relative as relative3 } from "node:path";
8113
+
8114
+ // ../lib/dist/train.js
8115
+ import { join as join3 } from "node:path";
8116
+ var TRAIN_REPOS = [
8117
+ "platform",
8118
+ "ci-cd",
8119
+ "preset-repo-web",
8120
+ "preset-app-nextjs",
8121
+ "preset-repo-platform",
8122
+ "compendium"
8123
+ ];
8124
+ var UPSTREAM = "plexus-ms";
8125
+ var isTrainVersion = (v) => /^\d+\.\d+\.\d+$/.test(v);
8126
+ function nextMinor(version2) {
8127
+ const [major = "0", minor = "0"] = version2.split(".");
8128
+ return `${major}.${Number(minor) + 1}.0`;
8129
+ }
8130
+ function latestTag(tags) {
8131
+ return tags.filter((t) => /^v?\d/.test(t)).sort((a, b) => compareTrains(a.replace(/^v/, ""), b.replace(/^v/, ""))).at(-1);
8132
+ }
8133
+ async function readTrain(ctx, upstream) {
8134
+ const repos = [];
8135
+ const all = /* @__PURE__ */ new Set();
8136
+ for (const name of TRAIN_REPOS) {
8137
+ const path3 = join3(upstream, name);
8138
+ try {
8139
+ await ctx.read("git", ["rev-parse", "--git-dir"], { cwd: path3 });
8140
+ } catch {
8141
+ throw new Error(`${path3} is not a git repo`);
8142
+ }
8143
+ try {
8144
+ await ctx.read("git", ["fetch", "origin", "--tags", "--quiet"], { cwd: path3 });
8145
+ } catch {
8146
+ throw new Error(`${name}: fetch from origin failed`);
8147
+ }
8148
+ const tags = (await ctx.read("git", ["tag", "--list", "v*", "[0-9]*"], { cwd: path3 })).split("\n").filter(Boolean);
8149
+ for (const t of tags)
8150
+ all.add(t.replace(/^v/, ""));
8151
+ const tag = latestTag(tags);
8152
+ const range = tag ? `${tag}..HEAD` : "HEAD";
8153
+ const pending = (await ctx.read("git", ["log", "--oneline", range], { cwd: path3 })).split("\n").filter(Boolean);
8154
+ repos.push({ name, path: path3, tag, latest: tag?.replace(/^v/, ""), pending });
8155
+ }
8156
+ const latest = repos.map((r) => r.latest);
8157
+ return { repos, last: latestTag([...all]), skew: latest.some((l) => l !== latest[0]) };
8158
+ }
8159
+ async function preflightRelease(ctx, train) {
8160
+ for (const { name, path: path3 } of train.repos) {
8161
+ const branch = (await ctx.read("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd: path3 })).trim();
8162
+ if (branch !== "main")
8163
+ throw new Error(`${name} is on '${branch}', trains cut from main`);
8164
+ if ((await ctx.read("git", ["status", "--porcelain"], { cwd: path3 })).trim() !== "")
8165
+ throw new Error(`${name} has uncommitted changes \u2014 commit first`);
8166
+ const behind = (await ctx.read("git", ["rev-list", "--count", "main..origin/main"], { cwd: path3 })).trim();
8167
+ if (behind !== "0")
8168
+ throw new Error(`${name} is ${behind} commit(s) behind origin/main \u2014 pull first, or the tag lands on a stale commit`);
8355
8169
  }
8356
- return words.slice(0, last).join(" ") + words.slice(last).join("");
8170
+ }
8171
+ function resolveVersion(train, explicit, propagateOnly) {
8172
+ if (explicit !== void 0 && !isTrainVersion(explicit))
8173
+ throw new UsageError(`'${explicit}' is not plain semver (X.Y.Z, no v)`);
8174
+ if (propagateOnly) {
8175
+ const v = explicit ?? train.last;
8176
+ if (!v)
8177
+ throw new Error("no train version found to propagate");
8178
+ return v;
8179
+ }
8180
+ if (explicit)
8181
+ return explicit;
8182
+ if (train.skew) {
8183
+ const report = train.repos.map((r) => ` ${r.name}: ${r.latest ?? "none"}`).join("\n");
8184
+ throw new Error(`the train repos' latest tags disagree:
8185
+ ${report}
8186
+ pass the version explicitly (--train ${train.last}) to finish the half-tagged train, or a higher one to start a new one`);
8187
+ }
8188
+ return train.last ? nextMinor(train.last) : "0.1.0";
8189
+ }
8190
+ var UsageError = class extends Error {
8357
8191
  };
8358
- var exec = (string, columns, options = {}) => {
8359
- if (options.trim !== false && string.trim() === "") {
8360
- return "";
8361
- }
8362
- let returnValue = "";
8363
- let escapeCode;
8364
- let escapeUrl;
8365
- const words = string.split(" ");
8366
- let rows = [""];
8367
- let rowLength = 0;
8368
- for (let index = 0; index < words.length; index++) {
8369
- const word = words[index];
8370
- if (options.trim !== false) {
8371
- const row = rows.at(-1) ?? "";
8372
- const trimmed = row.trimStart();
8373
- if (row.length !== trimmed.length) {
8374
- rows[rows.length - 1] = trimmed;
8375
- rowLength = dist_default3(trimmed);
8376
- }
8192
+
8193
+ // ../lib/dist/propagate.js
8194
+ var isClean = (s) => s.conflicted.length === 0 && s.failed.length === 0 && s.skipped.length === 0;
8195
+ var PREVIEW_BASE = "ship-base";
8196
+ async function propagate(ctx, workspace, train) {
8197
+ const summary = { train, preview: ctx.dryRun, clean: [], conflicted: [], failed: [], skipped: [] };
8198
+ const upstream = join4(workspace, UPSTREAM);
8199
+ const tree = await overview(ctx, workspace);
8200
+ const upstreamDir = tree.children.find((c) => c.path === upstream);
8201
+ const presets = TRAIN_REPOS.filter((r) => upstreamDir?.children.some((c) => c.name === r && c.template));
8202
+ const consumers = await findConsumers(ctx, tree, presets);
8203
+ for (const c of consumers) {
8204
+ if (!c.skipped)
8205
+ continue;
8206
+ ctx.say(`\u26A0 ${c.rel}: ${c.skipped} \u2014 skipped (fix it, then re-run propagate)`);
8207
+ summary.skipped.push({ path: c.rel, reason: c.skipped });
8208
+ }
8209
+ const active = consumers.filter((c) => !c.skipped);
8210
+ const scratch = ctx.dryRun ? (await ctx.stage(run("mktemp", ["-d"])))?.trim() : void 0;
8211
+ const clones = /* @__PURE__ */ new Map();
8212
+ const cloneOf = async (consumer) => {
8213
+ let clone = clones.get(consumer.path);
8214
+ if (!clone) {
8215
+ clone = join4(scratch ?? "", consumer.rel);
8216
+ await ctx.stage(run("git", ["clone", "--quiet", consumer.path, clone]));
8217
+ await ctx.stage(run("git", ["tag", PREVIEW_BASE], { cwd: clone }));
8218
+ clones.set(consumer.path, clone);
8219
+ }
8220
+ return clone;
8221
+ };
8222
+ const previewCommit = (clone, message) => ctx.stage(run("git", ["add", "-A"], { cwd: clone })).then(() => ctx.stage(run("git", [
8223
+ "-c",
8224
+ "commit.gpgsign=false",
8225
+ "-c",
8226
+ "user.name=plx",
8227
+ "-c",
8228
+ "user.email=plx@localhost",
8229
+ "commit",
8230
+ "--quiet",
8231
+ "--no-verify",
8232
+ "--allow-empty",
8233
+ "-m",
8234
+ message
8235
+ ], { cwd: clone })));
8236
+ try {
8237
+ for (const preset of presets) {
8238
+ const sites = active.flatMap((c) => c.sites.filter((s) => s.preset === preset).map((s) => [c, s]));
8239
+ if (sites.length === 0)
8240
+ ctx.say(`\u2022 no consumers of ${presetSource(preset)} found under ${workspace}`);
8241
+ for (const [consumer, site] of sites)
8242
+ await updateSite(ctx, consumer, site, join4(upstream, preset), summary, cloneOf, previewCommit);
8243
+ }
8244
+ await refreshLockfiles(ctx, active, summary, clones);
8245
+ await bumpConsumerRefs(ctx, consumers, train);
8246
+ } finally {
8247
+ if (scratch)
8248
+ await ctx.stage(run("rm", ["-rf", scratch]));
8249
+ }
8250
+ return summary;
8251
+ }
8252
+ async function updateSite(ctx, consumer, site, localPreset, summary, cloneOf, previewCommit) {
8253
+ let repo = consumer.path;
8254
+ let target = site.path;
8255
+ try {
8256
+ if (ctx.dryRun) {
8257
+ ctx.say(`\u2192 ${site.rel}: copier update (preview from ${localPreset}@main)`);
8258
+ repo = await cloneOf(consumer);
8259
+ target = join4(repo, relative3(consumer.path, site.path));
8260
+ const answers = await ctx.readFile(join4(site.path, ANSWERS_FILE));
8261
+ await ctx.stage(write(join4(target, ANSWERS_FILE), answers.replace(/^_src_path: .*$/m, `_src_path: ${localPreset}`)));
8262
+ await previewCommit(repo, `plx preview: ${site.rel} reads ${localPreset} from the local checkout`);
8263
+ await ctx.stage(run("copier", ["update", "--skip-answered", "--trust", "--defaults", "--skip-tasks", "--vcs-ref", "main"], {
8264
+ cwd: target
8265
+ }));
8266
+ } else {
8267
+ ctx.say(`\u2192 ${site.rel}: copier update`);
8268
+ const args = ["update", "--skip-answered", "--trust", ...ctx.yes ? ["--defaults"] : []];
8269
+ await ctx.apply([run("copier", args, { cwd: target, interactive: true })]);
8377
8270
  }
8378
- if (index !== 0) {
8379
- if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
8380
- rows.push("");
8381
- rowLength = 0;
8382
- }
8383
- if (rowLength || options.trim === false) {
8384
- rows[rows.length - 1] += " ";
8385
- rowLength++;
8386
- }
8271
+ } catch (error) {
8272
+ ctx.say(` \u2717 FAILED \u2014 copier update exited nonzero${detail(error)}`);
8273
+ summary.failed.push(site.rel);
8274
+ return;
8275
+ }
8276
+ const status = await ctx.read("git", ["status", "--porcelain"], { cwd: repo });
8277
+ let conflict = hasUnmergedEntries(status);
8278
+ const changed = (await ctx.read("git", ["diff", "--name-only"], { cwd: repo })).split("\n").filter(Boolean);
8279
+ for (const f of changed) {
8280
+ const text = await ctx.readFile(join4(repo, f)).catch(() => "");
8281
+ if (hasConflictMarkers(text))
8282
+ conflict = true;
8283
+ }
8284
+ await syncSiteMarker(ctx, site, target);
8285
+ if (conflict) {
8286
+ ctx.say(" \u2717 CONFLICTS \u2014 resolve the <<<<<<< markers, then git add:");
8287
+ summary.conflicted.push(site.rel);
8288
+ } else {
8289
+ ctx.say(" \u2713 merged clean:");
8290
+ summary.clean.push(site.rel);
8291
+ }
8292
+ for (const line of status.split("\n").filter(Boolean))
8293
+ ctx.say(` ${line}`);
8294
+ if (ctx.dryRun)
8295
+ await previewCommit(repo, `plx preview: ${site.rel} updated`);
8296
+ }
8297
+ async function syncSiteMarker(ctx, site, target) {
8298
+ const marker = await ctx.readFile(join4(target, MARKER_FILE)).catch(() => void 0);
8299
+ if (marker === void 0)
8300
+ return;
8301
+ const { commit } = parseAnswers(await ctx.readFile(join4(target, ANSWERS_FILE)));
8302
+ if (!commit)
8303
+ return;
8304
+ const synced = syncMarker(marker, commit);
8305
+ if (synced === marker)
8306
+ return;
8307
+ ctx.say(` marker: plexus \u2192 ${commit} in ${site.rel}/${MARKER_FILE}`);
8308
+ const step = write(join4(target, MARKER_FILE), synced);
8309
+ if (ctx.dryRun)
8310
+ await ctx.stage(step);
8311
+ else
8312
+ await ctx.apply([step]);
8313
+ }
8314
+ async function refreshLockfiles(ctx, consumers, summary, clones) {
8315
+ const manifests = ["*package.json", "pnpm-workspace.yaml"];
8316
+ for (const c of consumers) {
8317
+ if (await ctx.readFile(join4(c.path, "pnpm-workspace.yaml")).catch(() => void 0) === void 0)
8318
+ continue;
8319
+ const repo = ctx.dryRun ? clones.get(c.path) : c.path;
8320
+ if (!repo)
8321
+ continue;
8322
+ const range = ctx.dryRun ? [PREVIEW_BASE] : [];
8323
+ const unchanged = await ctx.read("git", ["diff", "--quiet", ...range, "--", ...manifests], { cwd: repo }).then(() => true).catch(() => false);
8324
+ if (unchanged)
8325
+ continue;
8326
+ ctx.say(`\u2192 ${c.rel}: pnpm install (manifests changed)`);
8327
+ try {
8328
+ await ctx.apply([run("mise", ["exec", "--", "pnpm", "install", "--reporter=silent"], { cwd: c.path })]);
8329
+ } catch (error) {
8330
+ ctx.say(` \u2717 pnpm install failed${detail(error)}`);
8331
+ summary.failed.push(`${c.rel}/pnpm-lock.yaml`);
8387
8332
  }
8388
- const wordLength = dist_default3(word);
8389
- if (options.hard && wordLength > columns) {
8390
- const remainingColumns = columns - rowLength;
8391
- const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
8392
- const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
8393
- if (breaksStartingNextLine < breaksStartingThisLine) {
8394
- rows.push("");
8395
- }
8396
- wrapWord(rows, word, columns);
8397
- rowLength = dist_default3(rows.at(-1) ?? "");
8333
+ }
8334
+ }
8335
+ async function bumpConsumerRefs(ctx, consumers, train) {
8336
+ for (const c of consumers) {
8337
+ const dir = join4(c.path, ".github", "workflows");
8338
+ const entries = await ctx.readDir(dir).catch(() => []);
8339
+ const files = entries.filter((e) => !e.directory && /\.ya?ml$/.test(e.name)).map((e) => e.name).sort();
8340
+ if (files.length === 0)
8341
+ continue;
8342
+ if (c.skipped) {
8343
+ ctx.say(`\u26A0 ${c.rel}: workflow refs not bumped (skipped above)`);
8398
8344
  continue;
8399
8345
  }
8400
- if (rowLength + wordLength > columns && rowLength && wordLength) {
8401
- if (options.wordWrap === false && rowLength < columns) {
8402
- wrapWord(rows, word, columns);
8403
- rowLength = dist_default3(rows.at(-1) ?? "");
8346
+ for (const f of files) {
8347
+ const text = await ctx.readFile(join4(dir, f));
8348
+ if (!text.includes(WORKFLOW_REF))
8404
8349
  continue;
8405
- }
8406
- rows.push("");
8407
- rowLength = 0;
8350
+ const bumped = bumpWorkflowRefs(text, train);
8351
+ if (bumped === text)
8352
+ continue;
8353
+ ctx.say(`\u2192 ${c.rel}: ${f} ci-cd refs \u2192 @${train}`);
8354
+ await ctx.apply([write(join4(dir, f), bumped)]);
8408
8355
  }
8409
- if (rowLength + wordLength > columns && options.wordWrap === false) {
8410
- wrapWord(rows, word, columns);
8411
- rowLength = dist_default3(rows.at(-1) ?? "");
8356
+ }
8357
+ }
8358
+ var detail = (error) => {
8359
+ const message = error instanceof Error ? error.message : String(error);
8360
+ const last = message.trim().split("\n").at(-1) ?? "";
8361
+ return last && !/exited with/.test(last) ? `: ${last}` : "";
8362
+ };
8363
+
8364
+ // ../lib/dist/requirements.js
8365
+ import { join as join5 } from "node:path";
8366
+ var KEYWORD = /MUST|SHOULD|MAY/;
8367
+ var hasKeyword = (line) => KEYWORD.test(line.replace(/MUSTs|SHOULDs|MAYs/g, ""));
8368
+ var list = (value) => value.replace(/^\s*\[/, "").replace(/\].*$/, "").split(",").map((s) => s.trim()).filter(Boolean);
8369
+ function scanPage(text, name, mode) {
8370
+ const scan = { defects: [], requirements: [], depends: [], consumes: [] };
8371
+ const lines = text.split("\n");
8372
+ const defect = (n, msg) => scan.defects.push(`\u2717 ${name}: line ${n + 1}: ${msg}`);
8373
+ let i = 0;
8374
+ if (lines[0] === "---") {
8375
+ for (i = 1; i < lines.length && lines[i] !== "---"; i++) {
8376
+ const line = lines[i] ?? "";
8377
+ const [key = "", ...rest] = line.split(/\s+/);
8378
+ const value = rest.join(" ");
8379
+ if (key === "maturity:")
8380
+ scan.maturity = rest[0];
8381
+ else if (key === "code:")
8382
+ scan.code = rest[0];
8383
+ else if (key === "binds:")
8384
+ scan.binds = rest[0];
8385
+ else if (key === "depends:")
8386
+ scan.depends = list(value);
8387
+ else if (key === "consumes:")
8388
+ scan.consumes = list(value);
8389
+ else if (key === "kind:")
8390
+ defect(i, "kind is the folder, contracts/ or approaches/, not a field");
8391
+ }
8392
+ i++;
8393
+ }
8394
+ let inCode = false;
8395
+ let maintaining = false;
8396
+ let started = false;
8397
+ let section = "";
8398
+ for (; i < lines.length; i++) {
8399
+ const line = lines[i] ?? "";
8400
+ if (line.startsWith("```")) {
8401
+ inCode = !inCode;
8412
8402
  continue;
8413
8403
  }
8414
- rows[rows.length - 1] += word;
8415
- rowLength += wordLength;
8416
- }
8417
- if (options.trim !== false) {
8418
- rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
8419
- }
8420
- const preString = rows.join("\n");
8421
- let inSurrogate = false;
8422
- for (let i = 0; i < preString.length; i++) {
8423
- const character = preString[i];
8424
- returnValue += character;
8425
- if (!inSurrogate) {
8426
- inSurrogate = character >= "\uD800" && character <= "\uDBFF";
8427
- if (inSurrogate) {
8428
- continue;
8429
- }
8430
- } else {
8431
- inSurrogate = false;
8404
+ if (inCode)
8405
+ continue;
8406
+ if (line === "## Maintaining") {
8407
+ maintaining = true;
8408
+ section = "";
8409
+ continue;
8432
8410
  }
8433
- if (character === ESC || character === CSI) {
8434
- GROUP_REGEX.lastIndex = i + 1;
8435
- const groupsResult = GROUP_REGEX.exec(preString);
8436
- const groups = groupsResult?.groups;
8437
- if (groups?.code !== void 0) {
8438
- const code = Number.parseFloat(groups.code);
8439
- escapeCode = code === END_CODE ? void 0 : code;
8440
- } else if (groups?.uri !== void 0) {
8441
- escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
8442
- }
8411
+ const heading = /^#+ § (\S+)/.exec(line);
8412
+ if (heading) {
8413
+ if (maintaining)
8414
+ defect(i, "numbered section after Maintaining");
8415
+ section = heading[1] ?? "";
8416
+ started = true;
8417
+ continue;
8443
8418
  }
8444
- if (preString[i + 1] === "\n") {
8445
- if (escapeUrl) {
8446
- returnValue += wrapAnsiHyperlink("");
8447
- }
8448
- const closingCode = escapeCode ? getClosingCode(escapeCode) : void 0;
8449
- if (escapeCode && closingCode) {
8450
- returnValue += wrapAnsiCode(closingCode);
8451
- }
8452
- } else if (character === "\n") {
8453
- if (escapeCode && getClosingCode(escapeCode)) {
8454
- returnValue += wrapAnsiCode(escapeCode);
8455
- }
8456
- if (escapeUrl) {
8457
- returnValue += wrapAnsiHyperlink(escapeUrl);
8458
- }
8419
+ if (line.startsWith("> - ")) {
8420
+ if (mode === "map")
8421
+ defect(i, `requirement in the map: ${line}`);
8422
+ else if (scan.maturity !== "standard")
8423
+ defect(i, `requirement in a module at ${scan.maturity} maturity: ${line}`);
8424
+ else if (maintaining)
8425
+ defect(i, `requirement under Maintaining: ${line}`);
8426
+ else if (!started)
8427
+ defect(i, "requirement before the first \xA7 heading");
8428
+ else
8429
+ scan.requirements.push(`\xA7 ${section} ${line.slice(4)}`);
8430
+ continue;
8431
+ }
8432
+ if (line.startsWith(">")) {
8433
+ defect(i, 'blockquote line is not a "> - " requirement bullet');
8434
+ continue;
8435
+ }
8436
+ if (hasKeyword(line))
8437
+ defect(i, `BCP 14 keyword outside a requirement: ${line}`);
8438
+ }
8439
+ if (mode === "module") {
8440
+ const { maturity = "", binds = "", code = "" } = scan;
8441
+ const n = text.endsWith("\n") ? lines.length - 1 : lines.length;
8442
+ if (!/^(note|candidate|standard)$/.test(maturity))
8443
+ defect(n - 1, `maturity must be note, candidate or standard, not "${maturity}"`);
8444
+ if (!/^(repo|app|host|organisation)$/.test(binds))
8445
+ defect(n - 1, `binds must be repo, app, host or organisation, not "${binds}"`);
8446
+ if (maturity === "note" && code !== "")
8447
+ defect(n - 1, "a note carries no code");
8448
+ if (maturity !== "note" && !/^PLX-[A-Z][A-Za-z]+$/.test(code))
8449
+ defect(n - 1, `code must be PLX- plus one capitalised word, not "${code}"`);
8450
+ }
8451
+ return scan;
8452
+ }
8453
+ var extractRequirements = (text) => scanPage(text, "", "module").requirements;
8454
+ var MAP_PAGE = "essentials/standard.md";
8455
+ async function modulePages(ctx, compendium) {
8456
+ const pages = [];
8457
+ for (const dir of Object.keys(CATALOG_DIRS)) {
8458
+ const entries = await ctx.readDir(join5(compendium, dir));
8459
+ for (const e of entries.filter((e2) => !e2.directory && e2.name.endsWith(".md") && e2.name !== "index.md").sort())
8460
+ pages.push(`${dir}/${e.name}`);
8461
+ }
8462
+ return pages;
8463
+ }
8464
+ async function checkCompendium(ctx, compendium) {
8465
+ const defects = [];
8466
+ defects.push(...scanPage(await ctx.readFile(join5(compendium, MAP_PAGE)), MAP_PAGE, "map").defects);
8467
+ const pages = await modulePages(ctx, compendium);
8468
+ const scans = /* @__PURE__ */ new Map();
8469
+ for (const page of pages) {
8470
+ const scan = scanPage(await ctx.readFile(join5(compendium, page)), page, "module");
8471
+ defects.push(...scan.defects);
8472
+ scans.set(page, scan);
8473
+ }
8474
+ const byCode = /* @__PURE__ */ new Map();
8475
+ for (const [page, s] of scans)
8476
+ if (s.code)
8477
+ byCode.set(s.code, [...byCode.get(s.code) ?? [], page]);
8478
+ for (const [code, where] of byCode)
8479
+ if (where.length > 1)
8480
+ defects.push(`\u2717 duplicate module code: ${code}`);
8481
+ for (const s of scans.values())
8482
+ for (const dep of s.depends)
8483
+ if (!byCode.has(dep))
8484
+ defects.push(`\u2717 unknown module in depends: ${dep}`);
8485
+ const kindOf2 = (page) => page.startsWith("contracts/") ? "contract" : "approach";
8486
+ const side = (binds2) => binds2 === "repo" || binds2 === "app" ? "dev" : "ops";
8487
+ const kinds = new Map([...byCode].map(([code, [page = ""]]) => [code, kindOf2(page)]));
8488
+ const binds = new Map([...byCode].map(([code, [page = ""]]) => [code, scans.get(page)?.binds ?? ""]));
8489
+ for (const [page, s] of scans) {
8490
+ const m = s.code ?? page.replace(/.*\//, "");
8491
+ const kind = kindOf2(page);
8492
+ for (const c of s.consumes) {
8493
+ if (kind === "contract")
8494
+ defects.push(`\u2717 ${m} is a contract and consumes ${c}; a contract has no other side to consume`);
8495
+ else if (kinds.has(c) && kinds.get(c) !== "contract")
8496
+ defects.push(`\u2717 ${m} consumes ${c}, which is an approach; only a contract is consumed across a seam`);
8497
+ else if (!kinds.has(c))
8498
+ defects.push(`\u2717 ${m} consumes unknown module ${c}`);
8499
+ }
8500
+ for (const d of s.depends) {
8501
+ if (!kinds.has(d))
8502
+ continue;
8503
+ if (kind === "contract" && kinds.get(d) !== "contract")
8504
+ defects.push(`\u2717 ${m} is a contract and depends on the approach ${d}`);
8505
+ if (side(s.binds ?? "") !== side(binds.get(d) ?? "") && kinds.get(d) !== "contract")
8506
+ defects.push(`\u2717 ${m} (${s.binds}) depends on ${d} (${binds.get(d)}) across the dev/ops seam; only a contract may be depended on across a seam`);
8459
8507
  }
8460
8508
  }
8461
- return returnValue;
8462
- };
8463
- var CRLF_OR_LF = /\r?\n/;
8464
- function wrapAnsi(string, columns, options) {
8465
- return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join("\n");
8509
+ return {
8510
+ defects,
8511
+ contracts: pages.filter((p) => p.startsWith("contracts/")).length,
8512
+ approaches: pages.filter((p) => p.startsWith("approaches/")).length
8513
+ };
8466
8514
  }
8467
8515
 
8468
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/utils.js
8469
- function breakLines(content, width) {
8470
- return content.split("\n").flatMap((line) => wrapAnsi(line, width, { trim: false, wordWrap: false }).split("\n").map((str) => str.trimEnd())).join("\n");
8516
+ // ../lib/dist/ship.js
8517
+ import { join as join6 } from "node:path";
8518
+ async function ship(ctx, options) {
8519
+ const upstream = join6(options.workspace, UPSTREAM);
8520
+ const propagateOnly = options.propagateOnly ?? false;
8521
+ const train = await readTrain(ctx, upstream);
8522
+ if (!propagateOnly)
8523
+ await preflightRelease(ctx, train);
8524
+ const next = resolveVersion(train, options.train, propagateOnly);
8525
+ if (!propagateOnly)
8526
+ await release(ctx, train, next, options.today ?? today());
8527
+ const summary = await propagate(ctx, options.workspace, next);
8528
+ return { ...summary, released: !propagateOnly };
8471
8529
  }
8472
- function readlineWidth() {
8473
- return (0, import_cli_width.default)({ defaultWidth: 80, output: readline().output });
8530
+ async function release(ctx, train, next, today2) {
8531
+ ctx.say(`\u2192 train ${train.last ?? "none"} \u2192 ${next}`);
8532
+ for (const repo of train.repos) {
8533
+ if (repo.pending.length === 0)
8534
+ ctx.say(` ${repo.name}: no changes since ${repo.latest} \u2014 tag only`);
8535
+ else {
8536
+ ctx.say(` ${repo.name} (since ${repo.latest ?? "the beginning"}):`);
8537
+ for (const line of repo.pending)
8538
+ ctx.say(` ${line}`);
8539
+ }
8540
+ }
8541
+ if (!await ctx.confirm(`tag all ${train.repos.length} repos as ${next} and push?`))
8542
+ throw new Error("aborted");
8543
+ try {
8544
+ const plan = await planBookkeeping(ctx, train, next, today2);
8545
+ await ctx.apply(plan);
8546
+ for (const repo of train.repos) {
8547
+ const tagged = await ctx.read("git", ["rev-parse", "-q", "--verify", `refs/tags/${next}`], { cwd: repo.path }).then(() => true).catch(() => false);
8548
+ if (tagged)
8549
+ ctx.say(`\u2022 ${repo.name}: already tagged ${next}`);
8550
+ else
8551
+ await ctx.apply([run("git", ["tag", "-a", next, "-m", `train ${next}`], { cwd: repo.path })]);
8552
+ await ctx.apply([run("git", ["push", "origin", "main", next], { cwd: repo.path })]);
8553
+ }
8554
+ } catch (error) {
8555
+ const message = error instanceof Error ? error.message : String(error);
8556
+ throw new Error(`${message}
8557
+ \u2717 ship stopped during the release; re-run with --train ${next} to finish it (tagged repos are skipped)`);
8558
+ }
8559
+ }
8560
+ async function planBookkeeping(ctx, train, next, today2) {
8561
+ const plan = [];
8562
+ const touched = /* @__PURE__ */ new Set();
8563
+ const repo = (name) => {
8564
+ const r = train.repos.find((r2) => r2.name === name);
8565
+ if (!r)
8566
+ throw new Error(`${name} is not a train repo`);
8567
+ return r;
8568
+ };
8569
+ const edit = async (r, rel, what, transform) => {
8570
+ const path3 = join6(r.path, rel);
8571
+ const text = await ctx.readFile(path3).catch(() => void 0);
8572
+ if (text === void 0)
8573
+ return;
8574
+ const edited = transform(text);
8575
+ if (edited === text)
8576
+ return;
8577
+ ctx.say(` ${r.name}: ${rel}: ${what}`);
8578
+ plan.push(write(path3, edited));
8579
+ touched.add(r);
8580
+ };
8581
+ await edit(repo("platform"), "ansible/galaxy.yml", `version \u2192 ${next}`, (t) => bumpGalaxyVersion(t, next));
8582
+ await edit(repo("preset-repo-platform"), "template/requirements.yml", `plexus.platform pin \u2192 ${next}`, (t) => bumpCollectionPin(t, next));
8583
+ for (const r of train.repos) {
8584
+ const files = await ctx.read("git", ["grep", "-l", WORKFLOW_REF, "--", "*.yml", "*.yaml", "*.jinja"], { cwd: r.path }).catch(() => "");
8585
+ for (const f of files.split("\n").filter(Boolean))
8586
+ await edit(r, f, `ci-cd refs \u2192 @${next}`, (t) => bumpWorkflowRefs(t, next));
8587
+ }
8588
+ const comp = repo("compendium");
8589
+ await edit(comp, MAP_PAGE, `version \u2192 ${next}, timestamp \u2192 ${today2}`, (t) => stampStandard(t, next, today2));
8590
+ for (const page of await modulePages(ctx, comp.path)) {
8591
+ const text = await ctx.readFile(join6(comp.path, page));
8592
+ if (frontmatterField(text, "maturity") !== "standard")
8593
+ continue;
8594
+ const previous = comp.tag ? await ctx.read("git", ["show", `${comp.tag}:${page}`], { cwd: comp.path }).catch(() => "") : "";
8595
+ if (extractRequirements(text).join("\n") === extractRequirements(previous).join("\n"))
8596
+ continue;
8597
+ await edit(comp, page, `requirements changed since ${comp.latest ?? "the beginning"} \u2192 changed: ${next}`, (t) => stampChanged(t, next));
8598
+ }
8599
+ for (const r of train.repos) {
8600
+ if (!touched.has(r))
8601
+ continue;
8602
+ plan.push(run("git", ["add", "-A"], { cwd: r.path }));
8603
+ plan.push(run("git", ["commit", "--quiet", "-m", `chore: train ${next} bookkeeping`], { cwd: r.path }));
8604
+ }
8605
+ return plan;
8474
8606
  }
8475
8607
 
8476
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/create-prompt.js
8477
- import * as readline2 from "node:readline";
8478
- import { AsyncResource as AsyncResource3 } from "node:async_hooks";
8608
+ // src/program.ts
8609
+ import { createRequire } from "node:module";
8479
8610
 
8480
- // ../../node_modules/.pnpm/@inquirer+type@4.2.0_@types+node@26.1.2/node_modules/@inquirer/type/dist/utils.js
8481
- function withResolver() {
8482
- let resolve2;
8483
- let reject;
8484
- const promise = new Promise((res, rej) => {
8485
- resolve2 = res;
8486
- reject = rej;
8487
- });
8488
- return { promise, resolve: resolve2, reject };
8611
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/key.js
8612
+ var keybindings = ["emacs", "vim"];
8613
+ var keybindingLookup = new Set(keybindings);
8614
+ function isKeybinding(value) {
8615
+ return keybindingLookup.has(value);
8616
+ }
8617
+ function getDefaultKeybindings() {
8618
+ const env = process.env["INQUIRER_KEYBINDINGS"];
8619
+ if (!env)
8620
+ return [];
8621
+ return Array.from(new Set(env.toLowerCase().split(/[\s,]+/).filter(isKeybinding)));
8489
8622
  }
8623
+ var isTabKey = (key) => key.name === "tab";
8624
+ var isEnterKey = (key) => key.name === "enter" || key.name === "return";
8490
8625
 
8491
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/create-prompt.js
8492
- var import_mute_stream = __toESM(require_lib(), 1);
8626
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/errors.js
8627
+ var AbortPromptError = class extends Error {
8628
+ name = "AbortPromptError";
8629
+ message = "Prompt was aborted";
8630
+ constructor(options) {
8631
+ super();
8632
+ this.cause = options?.cause;
8633
+ }
8634
+ };
8635
+ var CancelPromptError = class extends Error {
8636
+ name = "CancelPromptError";
8637
+ message = "Prompt was canceled";
8638
+ };
8639
+ var ExitPromptError = class extends Error {
8640
+ name = "ExitPromptError";
8641
+ };
8642
+ var HookError = class extends Error {
8643
+ name = "HookError";
8644
+ };
8645
+ var ValidationError = class extends Error {
8646
+ name = "ValidationError";
8647
+ };
8648
+
8649
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/use-state.js
8650
+ import { AsyncResource as AsyncResource2 } from "node:async_hooks";
8651
+
8652
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/hook-engine.js
8653
+ import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
8654
+ var hookStorage = new AsyncLocalStorage();
8655
+ function createStore(rl) {
8656
+ const store = {
8657
+ rl,
8658
+ hooks: [],
8659
+ hooksCleanup: [],
8660
+ hooksEffect: [],
8661
+ index: 0,
8662
+ handleChange() {
8663
+ }
8664
+ };
8665
+ return store;
8666
+ }
8667
+ function withHooks(rl, cb) {
8668
+ const store = createStore(rl);
8669
+ function cycle(render2) {
8670
+ store.handleChange = () => {
8671
+ store.index = 0;
8672
+ render2();
8673
+ };
8674
+ store.handleChange();
8675
+ }
8676
+ return hookStorage.run(store, () => cb(cycle));
8677
+ }
8678
+ function getStore() {
8679
+ const store = hookStorage.getStore();
8680
+ if (!store) {
8681
+ throw new HookError("[Inquirer] Hook functions can only be called from within a prompt");
8682
+ }
8683
+ return store;
8684
+ }
8685
+ function readline() {
8686
+ return getStore().rl;
8687
+ }
8688
+ function withUpdates(fn) {
8689
+ const wrapped = (...args) => {
8690
+ const store = getStore();
8691
+ let shouldUpdate = false;
8692
+ const oldHandleChange = store.handleChange;
8693
+ store.handleChange = () => {
8694
+ shouldUpdate = true;
8695
+ };
8696
+ const returnValue = fn(...args);
8697
+ if (shouldUpdate) {
8698
+ oldHandleChange();
8699
+ }
8700
+ store.handleChange = oldHandleChange;
8701
+ return returnValue;
8702
+ };
8703
+ return AsyncResource.bind(wrapped);
8704
+ }
8705
+ function withPointer(cb) {
8706
+ const store = getStore();
8707
+ const { index } = store;
8708
+ const pointer = {
8709
+ get() {
8710
+ return store.hooks[index];
8711
+ },
8712
+ set(value) {
8713
+ store.hooks[index] = value;
8714
+ },
8715
+ initialized: index in store.hooks
8716
+ };
8717
+ const returnValue = cb(pointer);
8718
+ store.index++;
8719
+ return returnValue;
8720
+ }
8721
+ function handleChange() {
8722
+ getStore().handleChange();
8723
+ }
8724
+ var effectScheduler = {
8725
+ queue(cb) {
8726
+ const store = getStore();
8727
+ const { index } = store;
8728
+ store.hooksEffect.push(() => {
8729
+ store.hooksCleanup[index]?.();
8730
+ const cleanFn = cb(readline());
8731
+ if (cleanFn != null && typeof cleanFn !== "function") {
8732
+ throw new ValidationError("useEffect return value must be a cleanup function or nothing.");
8733
+ }
8734
+ store.hooksCleanup[index] = cleanFn;
8735
+ });
8736
+ },
8737
+ run() {
8738
+ const store = getStore();
8739
+ withUpdates(() => {
8740
+ store.hooksEffect.forEach((effect) => {
8741
+ effect();
8742
+ });
8743
+ store.hooksEffect.length = 0;
8744
+ })();
8745
+ },
8746
+ clearAll() {
8747
+ const store = getStore();
8748
+ store.hooksCleanup.forEach((cleanFn) => {
8749
+ cleanFn?.();
8750
+ });
8751
+ store.hooksEffect.length = 0;
8752
+ store.hooksCleanup.length = 0;
8753
+ }
8754
+ };
8493
8755
 
8494
- // ../../node_modules/.pnpm/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/signals.js
8495
- var signals = [];
8496
- signals.push("SIGHUP", "SIGINT", "SIGTERM");
8497
- if (process.platform !== "win32") {
8498
- signals.push(
8499
- "SIGALRM",
8500
- "SIGABRT",
8501
- "SIGVTALRM",
8502
- "SIGXCPU",
8503
- "SIGXFSZ",
8504
- "SIGUSR2",
8505
- "SIGTRAP",
8506
- "SIGSYS",
8507
- "SIGQUIT",
8508
- "SIGIOT"
8509
- // should detect profiler and enable/disable accordingly.
8510
- // see #21
8511
- // 'SIGPROF'
8512
- );
8756
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/use-state.js
8757
+ function isFactory(value) {
8758
+ return typeof value === "function";
8513
8759
  }
8514
- if (process.platform === "linux") {
8515
- signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
8760
+ function isReducer(value) {
8761
+ return typeof value === "function";
8516
8762
  }
8517
-
8518
- // ../../node_modules/.pnpm/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/index.js
8519
- var processOk = (process5) => !!process5 && typeof process5 === "object" && typeof process5.removeListener === "function" && typeof process5.emit === "function" && typeof process5.reallyExit === "function" && typeof process5.listeners === "function" && typeof process5.kill === "function" && typeof process5.pid === "number" && typeof process5.on === "function";
8520
- var kExitEmitter = /* @__PURE__ */ Symbol.for("signal-exit emitter");
8521
- var global = globalThis;
8522
- var ObjectDefineProperty = Object.defineProperty.bind(Object);
8523
- var Emitter = class {
8524
- emitted = {
8525
- afterExit: false,
8526
- exit: false
8527
- };
8528
- listeners = {
8529
- afterExit: [],
8530
- exit: []
8531
- };
8532
- count = 0;
8533
- id = Math.random();
8534
- constructor() {
8535
- if (global[kExitEmitter]) {
8536
- return global[kExitEmitter];
8537
- }
8538
- ObjectDefineProperty(global, kExitEmitter, {
8539
- value: this,
8540
- writable: false,
8541
- enumerable: false,
8542
- configurable: false
8763
+ function useState(defaultValue) {
8764
+ return withPointer((pointer) => {
8765
+ const setState = AsyncResource2.bind(function setState2(newValue) {
8766
+ const currentValue = pointer.get();
8767
+ const nextValue = isReducer(newValue) ? newValue(currentValue) : newValue;
8768
+ if (!Object.is(currentValue, nextValue)) {
8769
+ pointer.set(nextValue);
8770
+ handleChange();
8771
+ }
8543
8772
  });
8544
- }
8545
- on(ev, fn) {
8546
- this.listeners[ev].push(fn);
8547
- }
8548
- removeListener(ev, fn) {
8549
- const list = this.listeners[ev];
8550
- const i = list.indexOf(fn);
8551
- if (i === -1) {
8552
- return;
8553
- }
8554
- if (i === 0 && list.length === 1) {
8555
- list.length = 0;
8556
- } else {
8557
- list.splice(i, 1);
8558
- }
8559
- }
8560
- emit(ev, code, signal) {
8561
- if (this.emitted[ev]) {
8562
- return false;
8563
- }
8564
- this.emitted[ev] = true;
8565
- let ret = false;
8566
- for (const fn of this.listeners[ev]) {
8567
- ret = fn(code, signal) === true || ret;
8773
+ if (pointer.initialized) {
8774
+ return [pointer.get(), setState];
8568
8775
  }
8569
- if (ev === "exit") {
8570
- ret = this.emit("afterExit", code, signal) || ret;
8776
+ const value = isFactory(defaultValue) ? defaultValue() : defaultValue;
8777
+ pointer.set(value);
8778
+ return [value, setState];
8779
+ });
8780
+ }
8781
+
8782
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/use-effect.js
8783
+ function useEffect(cb, depArray) {
8784
+ withPointer((pointer) => {
8785
+ const oldDeps = pointer.get();
8786
+ const hasChanged = !Array.isArray(oldDeps) || depArray.some((dep, i) => !Object.is(dep, oldDeps[i]));
8787
+ if (hasChanged) {
8788
+ effectScheduler.queue(cb);
8571
8789
  }
8572
- return ret;
8790
+ pointer.set(depArray);
8791
+ });
8792
+ }
8793
+
8794
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/theme.js
8795
+ import { styleText } from "node:util";
8796
+
8797
+ // ../../node_modules/.pnpm/@inquirer+figures@2.0.9/node_modules/@inquirer/figures/dist/index.js
8798
+ import process2 from "node:process";
8799
+ function isUnicodeSupported() {
8800
+ if (!process2.platform.startsWith("win")) {
8801
+ return process2.env["TERM"] !== "linux";
8573
8802
  }
8803
+ return Boolean(process2.env["CI"]) || // CI environments generally support unicode
8804
+ Boolean(process2.env["WT_SESSION"]) || // Windows Terminal
8805
+ Boolean(process2.env["TERMINUS_SUBLIME"]) || // Terminus (<0.2.27)
8806
+ process2.env["ConEmuTask"] === "{cmd::Cmder}" || // ConEmu and cmder
8807
+ process2.env["TERM_PROGRAM"] === "Terminus-Sublime" || process2.env["TERM_PROGRAM"] === "vscode" || process2.env["TERM"] === "xterm-256color" || process2.env["TERM"] === "alacritty" || process2.env["TERMINAL_EMULATOR"] === "JetBrains-JediTerm";
8808
+ }
8809
+ var common = {
8810
+ circleQuestionMark: "(?)",
8811
+ questionMarkPrefix: "(?)",
8812
+ square: "\u2588",
8813
+ squareDarkShade: "\u2593",
8814
+ squareMediumShade: "\u2592",
8815
+ squareLightShade: "\u2591",
8816
+ squareTop: "\u2580",
8817
+ squareBottom: "\u2584",
8818
+ squareLeft: "\u258C",
8819
+ squareRight: "\u2590",
8820
+ squareCenter: "\u25A0",
8821
+ bullet: "\u25CF",
8822
+ dot: "\u2024",
8823
+ ellipsis: "\u2026",
8824
+ pointerSmall: "\u203A",
8825
+ triangleUp: "\u25B2",
8826
+ triangleUpSmall: "\u25B4",
8827
+ triangleDown: "\u25BC",
8828
+ triangleDownSmall: "\u25BE",
8829
+ triangleLeftSmall: "\u25C2",
8830
+ triangleRightSmall: "\u25B8",
8831
+ home: "\u2302",
8832
+ heart: "\u2665",
8833
+ musicNote: "\u266A",
8834
+ musicNoteBeamed: "\u266B",
8835
+ arrowUp: "\u2191",
8836
+ arrowDown: "\u2193",
8837
+ arrowLeft: "\u2190",
8838
+ arrowRight: "\u2192",
8839
+ arrowLeftRight: "\u2194",
8840
+ arrowUpDown: "\u2195",
8841
+ almostEqual: "\u2248",
8842
+ notEqual: "\u2260",
8843
+ lessOrEqual: "\u2264",
8844
+ greaterOrEqual: "\u2265",
8845
+ identical: "\u2261",
8846
+ infinity: "\u221E",
8847
+ subscriptZero: "\u2080",
8848
+ subscriptOne: "\u2081",
8849
+ subscriptTwo: "\u2082",
8850
+ subscriptThree: "\u2083",
8851
+ subscriptFour: "\u2084",
8852
+ subscriptFive: "\u2085",
8853
+ subscriptSix: "\u2086",
8854
+ subscriptSeven: "\u2087",
8855
+ subscriptEight: "\u2088",
8856
+ subscriptNine: "\u2089",
8857
+ oneHalf: "\xBD",
8858
+ oneThird: "\u2153",
8859
+ oneQuarter: "\xBC",
8860
+ oneFifth: "\u2155",
8861
+ oneSixth: "\u2159",
8862
+ oneEighth: "\u215B",
8863
+ twoThirds: "\u2154",
8864
+ twoFifths: "\u2156",
8865
+ threeQuarters: "\xBE",
8866
+ threeFifths: "\u2157",
8867
+ threeEighths: "\u215C",
8868
+ fourFifths: "\u2158",
8869
+ fiveSixths: "\u215A",
8870
+ fiveEighths: "\u215D",
8871
+ sevenEighths: "\u215E",
8872
+ line: "\u2500",
8873
+ lineBold: "\u2501",
8874
+ lineDouble: "\u2550",
8875
+ lineDashed0: "\u2504",
8876
+ lineDashed1: "\u2505",
8877
+ lineDashed2: "\u2508",
8878
+ lineDashed3: "\u2509",
8879
+ lineDashed4: "\u254C",
8880
+ lineDashed5: "\u254D",
8881
+ lineDashed6: "\u2574",
8882
+ lineDashed7: "\u2576",
8883
+ lineDashed8: "\u2578",
8884
+ lineDashed9: "\u257A",
8885
+ lineDashed10: "\u257C",
8886
+ lineDashed11: "\u257E",
8887
+ lineDashed12: "\u2212",
8888
+ lineDashed13: "\u2013",
8889
+ lineDashed14: "\u2010",
8890
+ lineDashed15: "\u2043",
8891
+ lineVertical: "\u2502",
8892
+ lineVerticalBold: "\u2503",
8893
+ lineVerticalDouble: "\u2551",
8894
+ lineVerticalDashed0: "\u2506",
8895
+ lineVerticalDashed1: "\u2507",
8896
+ lineVerticalDashed2: "\u250A",
8897
+ lineVerticalDashed3: "\u250B",
8898
+ lineVerticalDashed4: "\u254E",
8899
+ lineVerticalDashed5: "\u254F",
8900
+ lineVerticalDashed6: "\u2575",
8901
+ lineVerticalDashed7: "\u2577",
8902
+ lineVerticalDashed8: "\u2579",
8903
+ lineVerticalDashed9: "\u257B",
8904
+ lineVerticalDashed10: "\u257D",
8905
+ lineVerticalDashed11: "\u257F",
8906
+ lineDownLeft: "\u2510",
8907
+ lineDownLeftArc: "\u256E",
8908
+ lineDownBoldLeftBold: "\u2513",
8909
+ lineDownBoldLeft: "\u2512",
8910
+ lineDownLeftBold: "\u2511",
8911
+ lineDownDoubleLeftDouble: "\u2557",
8912
+ lineDownDoubleLeft: "\u2556",
8913
+ lineDownLeftDouble: "\u2555",
8914
+ lineDownRight: "\u250C",
8915
+ lineDownRightArc: "\u256D",
8916
+ lineDownBoldRightBold: "\u250F",
8917
+ lineDownBoldRight: "\u250E",
8918
+ lineDownRightBold: "\u250D",
8919
+ lineDownDoubleRightDouble: "\u2554",
8920
+ lineDownDoubleRight: "\u2553",
8921
+ lineDownRightDouble: "\u2552",
8922
+ lineUpLeft: "\u2518",
8923
+ lineUpLeftArc: "\u256F",
8924
+ lineUpBoldLeftBold: "\u251B",
8925
+ lineUpBoldLeft: "\u251A",
8926
+ lineUpLeftBold: "\u2519",
8927
+ lineUpDoubleLeftDouble: "\u255D",
8928
+ lineUpDoubleLeft: "\u255C",
8929
+ lineUpLeftDouble: "\u255B",
8930
+ lineUpRight: "\u2514",
8931
+ lineUpRightArc: "\u2570",
8932
+ lineUpBoldRightBold: "\u2517",
8933
+ lineUpBoldRight: "\u2516",
8934
+ lineUpRightBold: "\u2515",
8935
+ lineUpDoubleRightDouble: "\u255A",
8936
+ lineUpDoubleRight: "\u2559",
8937
+ lineUpRightDouble: "\u2558",
8938
+ lineUpDownLeft: "\u2524",
8939
+ lineUpBoldDownBoldLeftBold: "\u252B",
8940
+ lineUpBoldDownBoldLeft: "\u2528",
8941
+ lineUpDownLeftBold: "\u2525",
8942
+ lineUpBoldDownLeftBold: "\u2529",
8943
+ lineUpDownBoldLeftBold: "\u252A",
8944
+ lineUpDownBoldLeft: "\u2527",
8945
+ lineUpBoldDownLeft: "\u2526",
8946
+ lineUpDoubleDownDoubleLeftDouble: "\u2563",
8947
+ lineUpDoubleDownDoubleLeft: "\u2562",
8948
+ lineUpDownLeftDouble: "\u2561",
8949
+ lineUpDownRight: "\u251C",
8950
+ lineUpBoldDownBoldRightBold: "\u2523",
8951
+ lineUpBoldDownBoldRight: "\u2520",
8952
+ lineUpDownRightBold: "\u251D",
8953
+ lineUpBoldDownRightBold: "\u2521",
8954
+ lineUpDownBoldRightBold: "\u2522",
8955
+ lineUpDownBoldRight: "\u251F",
8956
+ lineUpBoldDownRight: "\u251E",
8957
+ lineUpDoubleDownDoubleRightDouble: "\u2560",
8958
+ lineUpDoubleDownDoubleRight: "\u255F",
8959
+ lineUpDownRightDouble: "\u255E",
8960
+ lineDownLeftRight: "\u252C",
8961
+ lineDownBoldLeftBoldRightBold: "\u2533",
8962
+ lineDownLeftBoldRightBold: "\u252F",
8963
+ lineDownBoldLeftRight: "\u2530",
8964
+ lineDownBoldLeftBoldRight: "\u2531",
8965
+ lineDownBoldLeftRightBold: "\u2532",
8966
+ lineDownLeftRightBold: "\u252E",
8967
+ lineDownLeftBoldRight: "\u252D",
8968
+ lineDownDoubleLeftDoubleRightDouble: "\u2566",
8969
+ lineDownDoubleLeftRight: "\u2565",
8970
+ lineDownLeftDoubleRightDouble: "\u2564",
8971
+ lineUpLeftRight: "\u2534",
8972
+ lineUpBoldLeftBoldRightBold: "\u253B",
8973
+ lineUpLeftBoldRightBold: "\u2537",
8974
+ lineUpBoldLeftRight: "\u2538",
8975
+ lineUpBoldLeftBoldRight: "\u2539",
8976
+ lineUpBoldLeftRightBold: "\u253A",
8977
+ lineUpLeftRightBold: "\u2536",
8978
+ lineUpLeftBoldRight: "\u2535",
8979
+ lineUpDoubleLeftDoubleRightDouble: "\u2569",
8980
+ lineUpDoubleLeftRight: "\u2568",
8981
+ lineUpLeftDoubleRightDouble: "\u2567",
8982
+ lineUpDownLeftRight: "\u253C",
8983
+ lineUpBoldDownBoldLeftBoldRightBold: "\u254B",
8984
+ lineUpDownBoldLeftBoldRightBold: "\u2548",
8985
+ lineUpBoldDownLeftBoldRightBold: "\u2547",
8986
+ lineUpBoldDownBoldLeftRightBold: "\u254A",
8987
+ lineUpBoldDownBoldLeftBoldRight: "\u2549",
8988
+ lineUpBoldDownLeftRight: "\u2540",
8989
+ lineUpDownBoldLeftRight: "\u2541",
8990
+ lineUpDownLeftBoldRight: "\u253D",
8991
+ lineUpDownLeftRightBold: "\u253E",
8992
+ lineUpBoldDownBoldLeftRight: "\u2542",
8993
+ lineUpDownLeftBoldRightBold: "\u253F",
8994
+ lineUpBoldDownLeftBoldRight: "\u2543",
8995
+ lineUpBoldDownLeftRightBold: "\u2544",
8996
+ lineUpDownBoldLeftBoldRight: "\u2545",
8997
+ lineUpDownBoldLeftRightBold: "\u2546",
8998
+ lineUpDoubleDownDoubleLeftDoubleRightDouble: "\u256C",
8999
+ lineUpDoubleDownDoubleLeftRight: "\u256B",
9000
+ lineUpDownLeftDoubleRightDouble: "\u256A",
9001
+ lineCross: "\u2573",
9002
+ lineBackslash: "\u2572",
9003
+ lineSlash: "\u2571"
8574
9004
  };
8575
- var SignalExitBase = class {
9005
+ var specialMainSymbols = {
9006
+ tick: "\u2714",
9007
+ info: "\u2139",
9008
+ warning: "\u26A0",
9009
+ cross: "\u2718",
9010
+ squareSmall: "\u25FB",
9011
+ squareSmallFilled: "\u25FC",
9012
+ circle: "\u25EF",
9013
+ circleFilled: "\u25C9",
9014
+ circleDotted: "\u25CC",
9015
+ circleDouble: "\u25CE",
9016
+ circleCircle: "\u24DE",
9017
+ circleCross: "\u24E7",
9018
+ circlePipe: "\u24BE",
9019
+ radioOn: "\u25C9",
9020
+ radioOff: "\u25EF",
9021
+ checkboxOn: "\u2612",
9022
+ checkboxOff: "\u2610",
9023
+ checkboxCircleOn: "\u24E7",
9024
+ checkboxCircleOff: "\u24BE",
9025
+ pointer: "\u276F",
9026
+ triangleUpOutline: "\u25B3",
9027
+ triangleLeft: "\u25C0",
9028
+ triangleRight: "\u25B6",
9029
+ lozenge: "\u25C6",
9030
+ lozengeOutline: "\u25C7",
9031
+ hamburger: "\u2630",
9032
+ smiley: "\u32E1",
9033
+ mustache: "\u0DF4",
9034
+ star: "\u2605",
9035
+ play: "\u25B6",
9036
+ nodejs: "\u2B22",
9037
+ oneSeventh: "\u2150",
9038
+ oneNinth: "\u2151",
9039
+ oneTenth: "\u2152"
8576
9040
  };
8577
- var signalExitWrap = (handler) => {
8578
- return {
8579
- onExit(cb, opts) {
8580
- return handler.onExit(cb, opts);
8581
- },
8582
- load() {
8583
- return handler.load();
8584
- },
8585
- unload() {
8586
- return handler.unload();
8587
- }
8588
- };
9041
+ var specialFallbackSymbols = {
9042
+ tick: "\u221A",
9043
+ info: "i",
9044
+ warning: "\u203C",
9045
+ cross: "\xD7",
9046
+ squareSmall: "\u25A1",
9047
+ squareSmallFilled: "\u25A0",
9048
+ circle: "( )",
9049
+ circleFilled: "(*)",
9050
+ circleDotted: "( )",
9051
+ circleDouble: "( )",
9052
+ circleCircle: "(\u25CB)",
9053
+ circleCross: "(\xD7)",
9054
+ circlePipe: "(\u2502)",
9055
+ radioOn: "(*)",
9056
+ radioOff: "( )",
9057
+ checkboxOn: "[\xD7]",
9058
+ checkboxOff: "[ ]",
9059
+ checkboxCircleOn: "(\xD7)",
9060
+ checkboxCircleOff: "( )",
9061
+ pointer: ">",
9062
+ triangleUpOutline: "\u2206",
9063
+ triangleLeft: "\u25C4",
9064
+ triangleRight: "\u25BA",
9065
+ lozenge: "\u2666",
9066
+ lozengeOutline: "\u25CA",
9067
+ hamburger: "\u2261",
9068
+ smiley: "\u263A",
9069
+ mustache: "\u250C\u2500\u2510",
9070
+ star: "\u2736",
9071
+ play: "\u25BA",
9072
+ nodejs: "\u2666",
9073
+ oneSeventh: "1/7",
9074
+ oneNinth: "1/9",
9075
+ oneTenth: "1/10"
8589
9076
  };
8590
- var SignalExitFallback = class extends SignalExitBase {
8591
- onExit() {
8592
- return () => {
8593
- };
8594
- }
8595
- load() {
8596
- }
8597
- unload() {
8598
- }
9077
+ var mainSymbols = {
9078
+ ...common,
9079
+ ...specialMainSymbols
8599
9080
  };
8600
- var SignalExit = class extends SignalExitBase {
8601
- // "SIGHUP" throws an `ENOSYS` error on Windows,
8602
- // so use a supported signal instead
8603
- /* c8 ignore start */
8604
- #hupSig = process3.platform === "win32" ? "SIGINT" : "SIGHUP";
8605
- /* c8 ignore stop */
8606
- #emitter = new Emitter();
8607
- #process;
8608
- #originalProcessEmit;
8609
- #originalProcessReallyExit;
8610
- #sigListeners = {};
8611
- #loaded = false;
8612
- constructor(process5) {
8613
- super();
8614
- this.#process = process5;
8615
- this.#sigListeners = {};
8616
- for (const sig of signals) {
8617
- this.#sigListeners[sig] = () => {
8618
- const listeners = this.#process.listeners(sig);
8619
- let { count } = this.#emitter;
8620
- const p = process5;
8621
- if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") {
8622
- count += p.__signal_exit_emitter__.count;
8623
- }
8624
- if (listeners.length === count) {
8625
- this.unload();
8626
- const ret = this.#emitter.emit("exit", null, sig);
8627
- const s = sig === "SIGHUP" ? this.#hupSig : sig;
8628
- if (!ret)
8629
- process5.kill(process5.pid, s);
8630
- }
8631
- };
8632
- }
8633
- this.#originalProcessReallyExit = process5.reallyExit;
8634
- this.#originalProcessEmit = process5.emit;
8635
- }
8636
- onExit(cb, opts) {
8637
- if (!processOk(this.#process)) {
8638
- return () => {
8639
- };
8640
- }
8641
- if (this.#loaded === false) {
8642
- this.load();
8643
- }
8644
- const ev = opts?.alwaysLast ? "afterExit" : "exit";
8645
- this.#emitter.on(ev, cb);
8646
- return () => {
8647
- this.#emitter.removeListener(ev, cb);
8648
- if (this.#emitter.listeners["exit"].length === 0 && this.#emitter.listeners["afterExit"].length === 0) {
8649
- this.unload();
8650
- }
8651
- };
8652
- }
8653
- load() {
8654
- if (this.#loaded) {
8655
- return;
8656
- }
8657
- this.#loaded = true;
8658
- this.#emitter.count += 1;
8659
- for (const sig of signals) {
8660
- try {
8661
- const fn = this.#sigListeners[sig];
8662
- if (fn)
8663
- this.#process.on(sig, fn);
8664
- } catch (_) {
8665
- }
8666
- }
8667
- this.#process.emit = (ev, ...a) => {
8668
- return this.#processEmit(ev, ...a);
8669
- };
8670
- this.#process.reallyExit = (code) => {
8671
- return this.#processReallyExit(code);
8672
- };
8673
- }
8674
- unload() {
8675
- if (!this.#loaded) {
8676
- return;
8677
- }
8678
- this.#loaded = false;
8679
- signals.forEach((sig) => {
8680
- const listener = this.#sigListeners[sig];
8681
- if (!listener) {
8682
- throw new Error("Listener not defined for signal: " + sig);
8683
- }
8684
- try {
8685
- this.#process.removeListener(sig, listener);
8686
- } catch (_) {
8687
- }
8688
- });
8689
- this.#process.emit = this.#originalProcessEmit;
8690
- this.#process.reallyExit = this.#originalProcessReallyExit;
8691
- this.#emitter.count -= 1;
9081
+ var fallbackSymbols = {
9082
+ ...common,
9083
+ ...specialFallbackSymbols
9084
+ };
9085
+ var shouldUseMain = isUnicodeSupported();
9086
+ var figures = shouldUseMain ? mainSymbols : fallbackSymbols;
9087
+ var dist_default = figures;
9088
+ var replacements = Object.entries(specialMainSymbols);
9089
+
9090
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/theme.js
9091
+ var defaultTheme = {
9092
+ prefix: {
9093
+ idle: styleText("blue", "?"),
9094
+ done: styleText("green", dist_default.tick)
9095
+ },
9096
+ spinner: {
9097
+ interval: 80,
9098
+ frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"].map((frame) => styleText("yellow", frame))
9099
+ },
9100
+ keybindings: [],
9101
+ style: {
9102
+ answer: (text) => styleText("cyan", text),
9103
+ message: (text) => styleText("bold", text),
9104
+ error: (text) => styleText("red", `> ${text}`),
9105
+ defaultAnswer: (text) => styleText("dim", `(${text})`),
9106
+ help: (text) => styleText("dim", text),
9107
+ highlight: (text) => styleText("cyan", text),
9108
+ key: (text) => styleText("cyan", styleText("bold", `<${text}>`))
8692
9109
  }
8693
- #processReallyExit(code) {
8694
- if (!processOk(this.#process)) {
8695
- return 0;
9110
+ };
9111
+ function getDefaultTheme() {
9112
+ return {
9113
+ ...defaultTheme,
9114
+ keybindings: getDefaultKeybindings()
9115
+ };
9116
+ }
9117
+
9118
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/make-theme.js
9119
+ function isPlainObject(value) {
9120
+ if (typeof value !== "object" || value === null)
9121
+ return false;
9122
+ let proto = value;
9123
+ while (Object.getPrototypeOf(proto) !== null) {
9124
+ proto = Object.getPrototypeOf(proto);
9125
+ }
9126
+ return Object.getPrototypeOf(value) === proto;
9127
+ }
9128
+ function deepMerge(...objects) {
9129
+ const output = {};
9130
+ for (const obj of objects) {
9131
+ for (const [key, value] of Object.entries(obj)) {
9132
+ const prevValue = output[key];
9133
+ output[key] = isPlainObject(prevValue) && isPlainObject(value) ? deepMerge(prevValue, value) : value;
8696
9134
  }
8697
- this.#process.exitCode = code || 0;
8698
- this.#emitter.emit("exit", this.#process.exitCode, null);
8699
- return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);
8700
9135
  }
8701
- #processEmit(ev, ...args) {
8702
- const og = this.#originalProcessEmit;
8703
- if (ev === "exit" && processOk(this.#process)) {
8704
- if (typeof args[0] === "number") {
8705
- this.#process.exitCode = args[0];
8706
- }
8707
- const ret = og.call(this.#process, ev, ...args);
8708
- this.#emitter.emit("exit", this.#process.exitCode, null);
8709
- return ret;
9136
+ return output;
9137
+ }
9138
+ function makeTheme(...themes) {
9139
+ const themesToMerge = [
9140
+ getDefaultTheme(),
9141
+ ...themes.filter((theme) => theme != null)
9142
+ ];
9143
+ return deepMerge(...themesToMerge);
9144
+ }
9145
+
9146
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/use-prefix.js
9147
+ function usePrefix({ status = "idle", theme }) {
9148
+ const [showLoader, setShowLoader] = useState(false);
9149
+ const [tick, setTick] = useState(0);
9150
+ const { prefix, spinner } = makeTheme(theme);
9151
+ useEffect(() => {
9152
+ if (status === "loading") {
9153
+ let tickInterval;
9154
+ let inc = -1;
9155
+ const delayTimeout = setTimeout(() => {
9156
+ setShowLoader(true);
9157
+ tickInterval = setInterval(() => {
9158
+ inc = inc + 1;
9159
+ setTick(inc % spinner.frames.length);
9160
+ }, spinner.interval);
9161
+ }, 300);
9162
+ return () => {
9163
+ clearTimeout(delayTimeout);
9164
+ clearInterval(tickInterval);
9165
+ };
8710
9166
  } else {
8711
- return og.call(this.#process, ev, ...args);
9167
+ setShowLoader(false);
8712
9168
  }
9169
+ }, [status]);
9170
+ if (showLoader) {
9171
+ return spinner.frames[tick];
8713
9172
  }
8714
- };
8715
- var process3 = globalThis.process;
8716
- var {
8717
- /**
8718
- * Called when the process is exiting, whether via signal, explicit
8719
- * exit, or running out of stuff to do.
8720
- *
8721
- * If the global process object is not suitable for instrumentation,
8722
- * then this will be a no-op.
8723
- *
8724
- * Returns a function that may be used to unload signal-exit.
8725
- */
8726
- onExit,
8727
- /**
8728
- * Load the listeners. Likely you never need to call this, unless
8729
- * doing a rather deep integration with signal-exit functionality.
8730
- * Mostly exposed for the benefit of testing.
8731
- *
8732
- * @internal
8733
- */
8734
- load,
8735
- /**
8736
- * Unload the listeners. Likely you never need to call this, unless
8737
- * doing a rather deep integration with signal-exit functionality.
8738
- * Mostly exposed for the benefit of testing.
8739
- *
8740
- * @internal
8741
- */
8742
- unload
8743
- } = signalExitWrap(processOk(process3) ? new SignalExit(process3) : new SignalExitFallback());
9173
+ const iconName = status === "loading" ? "idle" : status;
9174
+ return typeof prefix === "string" ? prefix : prefix[iconName] ?? prefix["idle"];
9175
+ }
8744
9176
 
8745
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/screen-manager.js
8746
- import { stripVTControlCharacters } from "node:util";
9177
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/use-ref.js
9178
+ function useRef(val) {
9179
+ return useState({ current: val })[0];
9180
+ }
8747
9181
 
8748
- // ../../node_modules/.pnpm/@inquirer+ansi@2.0.9/node_modules/@inquirer/ansi/dist/index.js
8749
- var ESC2 = "\x1B[";
8750
- var cursorLeft = ESC2 + "G";
8751
- var cursorHide = ESC2 + "?25l";
8752
- var cursorShow = ESC2 + "?25h";
8753
- var cursorUp = (rows = 1) => rows > 0 ? `${ESC2}${rows}A` : "";
8754
- var cursorDown = (rows = 1) => rows > 0 ? `${ESC2}${rows}B` : "";
8755
- var cursorTo = (x, y) => {
8756
- if (typeof y === "number" && !Number.isNaN(y)) {
8757
- return `${ESC2}${y + 1};${x + 1}H`;
8758
- }
8759
- return `${ESC2}${x + 1}G`;
8760
- };
8761
- var eraseLine = ESC2 + "2K";
8762
- var eraseLines = (lines) => lines > 0 ? (eraseLine + cursorUp(1)).repeat(lines - 1) + eraseLine + cursorLeft : "";
9182
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/use-keypress.js
9183
+ function useKeypress(userHandler) {
9184
+ const signal = useRef(userHandler);
9185
+ signal.current = userHandler;
9186
+ useEffect((rl) => {
9187
+ let ignore = false;
9188
+ const handler = withUpdates((_input, event) => {
9189
+ if (ignore)
9190
+ return;
9191
+ void signal.current(event, rl);
9192
+ });
9193
+ rl.input.on("keypress", handler);
9194
+ return () => {
9195
+ ignore = true;
9196
+ rl.input.removeListener("keypress", handler);
9197
+ };
9198
+ }, []);
9199
+ }
8763
9200
 
8764
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/screen-manager.js
8765
- var height = (content) => content.split("\n").length;
8766
- var lastLine = (content) => content.split("\n").pop() ?? "";
8767
- var ScreenManager = class {
8768
- // These variables are keeping information to allow correct prompt re-rendering
8769
- height = 0;
8770
- extraLinesUnderPrompt = 0;
8771
- cursorPos;
8772
- rl;
8773
- constructor(rl) {
8774
- this.rl = rl;
8775
- this.cursorPos = rl.getCursorPos();
8776
- }
8777
- write(content) {
8778
- this.rl.output.unmute();
8779
- this.rl.output.write(content);
8780
- this.rl.output.mute();
8781
- }
8782
- render(content, bottomContent = "") {
8783
- const promptLine = lastLine(content);
8784
- const rawPromptLine = stripVTControlCharacters(promptLine);
8785
- let prompt = rawPromptLine;
8786
- if (this.rl.line.length > 0) {
8787
- prompt = prompt.slice(0, -this.rl.line.length);
9201
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/utils.js
9202
+ var import_cli_width = __toESM(require_cli_width(), 1);
9203
+
9204
+ // ../../node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/utils.js
9205
+ var getCodePointsLength = /* @__PURE__ */ (() => {
9206
+ const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
9207
+ return (input) => {
9208
+ let surrogatePairsNr = 0;
9209
+ SURROGATE_PAIR_RE.lastIndex = 0;
9210
+ while (SURROGATE_PAIR_RE.test(input)) {
9211
+ surrogatePairsNr += 1;
8788
9212
  }
8789
- this.rl.setPrompt(prompt);
8790
- this.cursorPos = this.rl.getCursorPos();
8791
- const width = readlineWidth();
8792
- content = breakLines(content, width);
8793
- bottomContent = breakLines(bottomContent, width);
8794
- if (rawPromptLine.length % width === 0) {
8795
- content += "\n";
9213
+ return input.length - surrogatePairsNr;
9214
+ };
9215
+ })();
9216
+ var isFullWidth = (x) => {
9217
+ return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
9218
+ };
9219
+ var isWideNotCJKTNotEmoji = (x) => {
9220
+ return x === 8987 || x === 9001 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
9221
+ };
9222
+
9223
+ // ../../node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/index.js
9224
+ var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
9225
+ var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
9226
+ var CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
9227
+ var TAB_RE = /\t{1,1000}/y;
9228
+ var EMOJI_RE = new RegExp("[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*", "yu");
9229
+ var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
9230
+ var MODIFIER_RE = new RegExp("\\p{M}+", "gu");
9231
+ var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
9232
+ var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
9233
+ const LIMIT = truncationOptions.limit ?? Infinity;
9234
+ const ELLIPSIS = truncationOptions.ellipsis ?? "";
9235
+ const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
9236
+ const ANSI_WIDTH = 0;
9237
+ const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
9238
+ const TAB_WIDTH = widthOptions.tabWidth ?? 8;
9239
+ const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
9240
+ const FULL_WIDTH_WIDTH = 2;
9241
+ const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
9242
+ const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
9243
+ const PARSE_BLOCKS = [
9244
+ [LATIN_RE, REGULAR_WIDTH],
9245
+ [ANSI_RE, ANSI_WIDTH],
9246
+ [CONTROL_RE, CONTROL_WIDTH],
9247
+ [TAB_RE, TAB_WIDTH],
9248
+ [EMOJI_RE, EMOJI_WIDTH],
9249
+ [CJKT_WIDE_RE, WIDE_WIDTH]
9250
+ ];
9251
+ let indexPrev = 0;
9252
+ let index = 0;
9253
+ let length = input.length;
9254
+ let lengthExtra = 0;
9255
+ let truncationEnabled = false;
9256
+ let truncationIndex = length;
9257
+ let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
9258
+ let unmatchedStart = 0;
9259
+ let unmatchedEnd = 0;
9260
+ let width = 0;
9261
+ let widthExtra = 0;
9262
+ outer: while (true) {
9263
+ if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
9264
+ const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
9265
+ lengthExtra = 0;
9266
+ for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
9267
+ const codePoint = char.codePointAt(0) || 0;
9268
+ if (isFullWidth(codePoint)) {
9269
+ widthExtra = FULL_WIDTH_WIDTH;
9270
+ } else if (isWideNotCJKTNotEmoji(codePoint)) {
9271
+ widthExtra = WIDE_WIDTH;
9272
+ } else {
9273
+ widthExtra = REGULAR_WIDTH;
9274
+ }
9275
+ if (width + widthExtra > truncationLimit) {
9276
+ truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
9277
+ }
9278
+ if (width + widthExtra > LIMIT) {
9279
+ truncationEnabled = true;
9280
+ break outer;
9281
+ }
9282
+ lengthExtra += char.length;
9283
+ width += widthExtra;
9284
+ }
9285
+ unmatchedStart = unmatchedEnd = 0;
8796
9286
  }
8797
- let output = content + (bottomContent ? "\n" + bottomContent : "");
8798
- const promptLineUpDiff = Math.floor(rawPromptLine.length / width) - this.cursorPos.rows;
8799
- const bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0);
8800
- if (bottomContentHeight > 0)
8801
- output += cursorUp(bottomContentHeight);
8802
- output += cursorTo(this.cursorPos.cols);
8803
- this.write(cursorDown(this.extraLinesUnderPrompt) + eraseLines(this.height) + output);
8804
- this.extraLinesUnderPrompt = bottomContentHeight;
8805
- this.height = height(output);
8806
- }
8807
- checkCursorPos() {
8808
- const cursorPos = this.rl.getCursorPos();
8809
- if (cursorPos.cols !== this.cursorPos.cols) {
8810
- this.write(cursorTo(cursorPos.cols));
8811
- this.cursorPos = cursorPos;
9287
+ if (index >= length) {
9288
+ break outer;
8812
9289
  }
8813
- }
8814
- done({ clearContent }) {
8815
- this.rl.setPrompt("");
8816
- let output = cursorDown(this.extraLinesUnderPrompt);
8817
- output += clearContent ? eraseLines(this.height) : "\n";
8818
- output += cursorLeft;
8819
- output += cursorShow;
8820
- this.write(output);
8821
- this.rl.close();
8822
- }
8823
- };
8824
-
8825
- // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.1.2/node_modules/@inquirer/core/dist/lib/create-prompt.js
8826
- import path from "node:path";
8827
- var nativeSetImmediate = globalThis.setImmediate;
8828
- var nativeClearImmediate = globalThis.clearImmediate;
8829
- function listenTo(target, event, listener) {
8830
- if ("on" in target) {
8831
- target.on(event, listener);
8832
- return () => target.removeListener(event, listener);
8833
- }
8834
- target.addEventListener(event, listener);
8835
- return () => target.removeEventListener(event, listener);
8836
- }
8837
- function getCallSites() {
8838
- const savedPrepareStackTrace = Error.prepareStackTrace;
8839
- let result = [];
8840
- try {
8841
- Error.prepareStackTrace = (_, callSites) => {
8842
- const callSitesWithoutCurrent = callSites.slice(1);
8843
- result = callSitesWithoutCurrent;
8844
- return callSitesWithoutCurrent;
8845
- };
8846
- new Error().stack;
8847
- } catch {
8848
- return result;
8849
- }
8850
- Error.prepareStackTrace = savedPrepareStackTrace;
8851
- return result;
8852
- }
8853
- function createPrompt(view) {
8854
- const callSites = getCallSites();
8855
- const prompt = (config, context = {}) => {
8856
- const { input = process.stdin, signal } = context;
8857
- const cleanups = /* @__PURE__ */ new Set();
8858
- const output = new import_mute_stream.default();
8859
- output.pipe(context.output ?? process.stdout);
8860
- const rl = readline2.createInterface({
8861
- terminal: true,
8862
- input,
8863
- output
8864
- });
8865
- output.mute();
8866
- const screen = new ScreenManager(rl);
8867
- const { promise, resolve: resolve2, reject } = withResolver();
8868
- return withHooks(rl, (cycle) => {
8869
- const clearEffects = AsyncResource3.bind(() => effectScheduler.clearAll());
8870
- const settlePrompt = (settle) => {
8871
- try {
8872
- clearEffects();
8873
- settle();
8874
- } catch (error) {
8875
- reject(error);
9290
+ for (let i = 0, l = PARSE_BLOCKS.length; i < l; i++) {
9291
+ const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
9292
+ BLOCK_RE.lastIndex = index;
9293
+ if (BLOCK_RE.test(input)) {
9294
+ lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
9295
+ widthExtra = lengthExtra * BLOCK_WIDTH;
9296
+ if (width + widthExtra > truncationLimit) {
9297
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
8876
9298
  }
8877
- };
8878
- const resolvePrompt = (value) => settlePrompt(() => resolve2(value));
8879
- const rejectPrompt = (error) => settlePrompt(() => reject(error));
8880
- const promptPromise = Object.assign(promise.finally(() => {
8881
- cleanups.forEach((cleanup) => cleanup());
8882
- screen.done({ clearContent: Boolean(context.clearPromptOnDone) });
8883
- output.end();
8884
- }).then(() => promise), { cancel: () => rejectPrompt(new CancelPromptError()) });
8885
- if (signal) {
8886
- const abort = () => rejectPrompt(new AbortPromptError({ cause: signal.reason }));
8887
- if (signal.aborted) {
8888
- abort();
8889
- return promptPromise;
9299
+ if (width + widthExtra > LIMIT) {
9300
+ truncationEnabled = true;
9301
+ break outer;
8890
9302
  }
8891
- cleanups.add(listenTo(signal, "abort", abort));
8892
- }
8893
- cleanups.add(onExit((code, signal2) => {
8894
- rejectPrompt(new ExitPromptError(`User force closed the prompt with ${code} ${signal2}`));
8895
- }));
8896
- cleanups.add(listenTo(rl, "SIGINT", () => rejectPrompt(new ExitPromptError(`User force closed the prompt with SIGINT`))));
8897
- cleanups.add(listenTo(rl, "close", clearEffects));
8898
- const startCycle = () => {
8899
- cleanups.add(listenTo(rl.input, "keypress", () => screen.checkCursorPos()));
8900
- let pendingDone = null;
8901
- cycle(() => {
8902
- let effectsSettled = false;
8903
- try {
8904
- const nextView = view(config, (value) => {
8905
- if (effectsSettled) {
8906
- resolvePrompt(value);
8907
- } else {
8908
- pendingDone = { value };
8909
- }
8910
- });
8911
- if (nextView === void 0) {
8912
- let callerFilename = callSites[1]?.getFileName();
8913
- if (callerFilename && !callerFilename.startsWith("file://")) {
8914
- callerFilename = path.resolve(callerFilename);
8915
- }
8916
- throw new Error(`Prompt functions must return a string.
8917
- at ${callerFilename}`);
8918
- }
8919
- const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
8920
- screen.render(content, bottomContent);
8921
- effectScheduler.run();
8922
- } catch (error) {
8923
- rejectPrompt(error);
8924
- }
8925
- effectsSettled = true;
8926
- if (pendingDone !== null) {
8927
- const { value } = pendingDone;
8928
- pendingDone = null;
8929
- resolvePrompt(value);
8930
- }
8931
- });
8932
- };
8933
- if ("readableFlowing" in input) {
8934
- const immediate = nativeSetImmediate(startCycle);
8935
- cleanups.add(() => nativeClearImmediate(immediate));
8936
- } else {
8937
- startCycle();
9303
+ width += widthExtra;
9304
+ unmatchedStart = indexPrev;
9305
+ unmatchedEnd = index;
9306
+ index = indexPrev = BLOCK_RE.lastIndex;
9307
+ continue outer;
8938
9308
  }
8939
- return promptPromise;
8940
- });
9309
+ }
9310
+ index += 1;
9311
+ }
9312
+ return {
9313
+ width: truncationEnabled ? truncationLimit : width,
9314
+ index: truncationEnabled ? truncationIndex : length,
9315
+ truncated: truncationEnabled,
9316
+ ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
8941
9317
  };
8942
- return prompt;
8943
- }
9318
+ };
9319
+ var dist_default2 = getStringTruncatedWidth;
8944
9320
 
8945
- // ../../node_modules/.pnpm/@inquirer+confirm@6.3.4_@types+node@26.1.2/node_modules/@inquirer/confirm/dist/index.js
8946
- import { styleText as styleText2 } from "node:util";
8947
- var confirmTheme = {
8948
- keywords: {
8949
- yes: "Yes",
8950
- no: "No",
8951
- error: ({ yes, no }) => `You must answer with "${yes}" or "${no}"`
8952
- },
8953
- style: {
8954
- confirmDefault: (text) => {
8955
- const first = text[0] ?? "";
8956
- if (first.toLowerCase() === first.toUpperCase()) {
8957
- return styleText2("cyan", text);
9321
+ // ../../node_modules/.pnpm/fast-string-width@3.0.2/node_modules/fast-string-width/dist/index.js
9322
+ var NO_TRUNCATION2 = {
9323
+ limit: Infinity,
9324
+ ellipsis: "",
9325
+ ellipsisWidth: 0
9326
+ };
9327
+ var fastStringWidth = (input, options = {}) => {
9328
+ return dist_default2(input, NO_TRUNCATION2, options).width;
9329
+ };
9330
+ var dist_default3 = fastStringWidth;
9331
+
9332
+ // ../../node_modules/.pnpm/fast-wrap-ansi@0.2.2/node_modules/fast-wrap-ansi/lib/main.js
9333
+ var ESC = "\x1B";
9334
+ var CSI = "\x9B";
9335
+ var END_CODE = 39;
9336
+ var ANSI_ESCAPE_BELL = "\x07";
9337
+ var ANSI_CSI = "[";
9338
+ var ANSI_OSC = "]";
9339
+ var ANSI_SGR_TERMINATOR = "m";
9340
+ var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
9341
+ var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
9342
+ var getClosingCode = (openingCode) => {
9343
+ if (openingCode >= 30 && openingCode <= 37)
9344
+ return 39;
9345
+ if (openingCode >= 90 && openingCode <= 97)
9346
+ return 39;
9347
+ if (openingCode >= 40 && openingCode <= 47)
9348
+ return 49;
9349
+ if (openingCode >= 100 && openingCode <= 107)
9350
+ return 49;
9351
+ if (openingCode === 1 || openingCode === 2)
9352
+ return 22;
9353
+ if (openingCode === 3)
9354
+ return 23;
9355
+ if (openingCode === 4)
9356
+ return 24;
9357
+ if (openingCode === 7)
9358
+ return 27;
9359
+ if (openingCode === 8)
9360
+ return 28;
9361
+ if (openingCode === 9)
9362
+ return 29;
9363
+ if (openingCode === 0)
9364
+ return 0;
9365
+ return void 0;
9366
+ };
9367
+ var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
9368
+ var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
9369
+ var wrapWord = (rows, word, columns) => {
9370
+ const characters = word[Symbol.iterator]();
9371
+ let isInsideEscape = false;
9372
+ let isInsideLinkEscape = false;
9373
+ let lastRow = rows.at(-1);
9374
+ let visible = lastRow === void 0 ? 0 : dist_default3(lastRow);
9375
+ let currentCharacter = characters.next();
9376
+ let nextCharacter = characters.next();
9377
+ let rawCharacterIndex = 0;
9378
+ while (!currentCharacter.done) {
9379
+ const character = currentCharacter.value;
9380
+ const characterLength = dist_default3(character);
9381
+ if (visible + characterLength <= columns) {
9382
+ rows[rows.length - 1] += character;
9383
+ } else {
9384
+ rows.push(character);
9385
+ visible = 0;
9386
+ }
9387
+ if (character === ESC || character === CSI) {
9388
+ isInsideEscape = true;
9389
+ isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
9390
+ }
9391
+ if (isInsideEscape) {
9392
+ if (isInsideLinkEscape) {
9393
+ if (character === ANSI_ESCAPE_BELL) {
9394
+ isInsideEscape = false;
9395
+ isInsideLinkEscape = false;
9396
+ }
9397
+ } else if (character === ANSI_SGR_TERMINATOR) {
9398
+ isInsideEscape = false;
9399
+ }
9400
+ } else {
9401
+ visible += characterLength;
9402
+ if (visible === columns && !nextCharacter.done) {
9403
+ rows.push("");
9404
+ visible = 0;
8958
9405
  }
8959
- return first.toUpperCase() + text.slice(1);
8960
9406
  }
9407
+ currentCharacter = nextCharacter;
9408
+ nextCharacter = characters.next();
9409
+ rawCharacterIndex += character.length;
9410
+ }
9411
+ lastRow = rows.at(-1);
9412
+ if (!visible && lastRow !== void 0 && lastRow.length && rows.length > 1) {
9413
+ rows[rows.length - 2] += rows.pop();
8961
9414
  }
8962
9415
  };
8963
- var dist_default4 = createPrompt((config, done) => {
8964
- const [status, setStatus] = useState("idle");
8965
- const [value, setValue] = useState("");
8966
- const [errorMsg, setError] = useState();
8967
- const theme = makeTheme(confirmTheme, config.theme);
8968
- const prefix = usePrefix({ status, theme });
8969
- const { yes, no } = theme.keywords;
8970
- const yesHint = (yes[0] ?? "").toLowerCase();
8971
- const noHint = (no[0] ?? "").toLowerCase();
8972
- const hint = config.default === false ? `${yesHint}/${theme.style.confirmDefault(noHint)}` : `${theme.style.confirmDefault(yesHint)}/${noHint}`;
8973
- function boolToString(value2) {
8974
- return value2 ? yes : no;
9416
+ var stringVisibleTrimSpacesRight = (string) => {
9417
+ const words = string.split(" ");
9418
+ let last = words.length;
9419
+ while (last) {
9420
+ if (dist_default3(words[last - 1])) {
9421
+ break;
9422
+ }
9423
+ last--;
8975
9424
  }
8976
- const { transformer = boolToString } = config;
8977
- function getBooleanValue(value2) {
8978
- const v = value2.trim().toLowerCase();
8979
- if (v === "")
8980
- return config.default !== false;
8981
- if (yes.toLowerCase().startsWith(v))
8982
- return true;
8983
- if (no.toLowerCase().startsWith(v))
8984
- return false;
8985
- if ("yes".startsWith(v))
8986
- return true;
8987
- if ("no".startsWith(v))
8988
- return false;
8989
- return void 0;
9425
+ if (last === words.length) {
9426
+ return string;
8990
9427
  }
8991
- useKeypress((key, rl) => {
8992
- if (status !== "idle")
8993
- return;
8994
- if (isEnterKey(key)) {
8995
- const answer = getBooleanValue(value);
8996
- if (answer === void 0) {
8997
- rl.write(value);
8998
- setError(theme.keywords.error({ yes, no }));
8999
- return;
9428
+ return words.slice(0, last).join(" ") + words.slice(last).join("");
9429
+ };
9430
+ var exec = (string, columns, options = {}) => {
9431
+ if (options.trim !== false && string.trim() === "") {
9432
+ return "";
9433
+ }
9434
+ let returnValue = "";
9435
+ let escapeCode;
9436
+ let escapeUrl;
9437
+ const words = string.split(" ");
9438
+ let rows = [""];
9439
+ let rowLength = 0;
9440
+ for (let index = 0; index < words.length; index++) {
9441
+ const word = words[index];
9442
+ if (options.trim !== false) {
9443
+ const row = rows.at(-1) ?? "";
9444
+ const trimmed = row.trimStart();
9445
+ if (row.length !== trimmed.length) {
9446
+ rows[rows.length - 1] = trimmed;
9447
+ rowLength = dist_default3(trimmed);
9000
9448
  }
9001
- setValue(transformer(answer));
9002
- setStatus("done");
9003
- done(answer);
9004
- } else if (isTabKey(key)) {
9005
- const answer = boolToString(!(getBooleanValue(value) ?? config.default !== false));
9006
- rl.clearLine(0);
9007
- rl.write(answer);
9008
- setValue(answer);
9009
- } else {
9010
- setValue(rl.line);
9011
- setError(void 0);
9012
9449
  }
9013
- });
9014
- let formattedValue = value;
9015
- let defaultValue = "";
9016
- if (status === "done") {
9017
- formattedValue = theme.style.answer(value);
9018
- } else {
9019
- defaultValue = ` ${theme.style.defaultAnswer(hint)}`;
9450
+ if (index !== 0) {
9451
+ if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
9452
+ rows.push("");
9453
+ rowLength = 0;
9454
+ }
9455
+ if (rowLength || options.trim === false) {
9456
+ rows[rows.length - 1] += " ";
9457
+ rowLength++;
9458
+ }
9459
+ }
9460
+ const wordLength = dist_default3(word);
9461
+ if (options.hard && wordLength > columns) {
9462
+ const remainingColumns = columns - rowLength;
9463
+ const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
9464
+ const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
9465
+ if (breaksStartingNextLine < breaksStartingThisLine) {
9466
+ rows.push("");
9467
+ }
9468
+ wrapWord(rows, word, columns);
9469
+ rowLength = dist_default3(rows.at(-1) ?? "");
9470
+ continue;
9471
+ }
9472
+ if (rowLength + wordLength > columns && rowLength && wordLength) {
9473
+ if (options.wordWrap === false && rowLength < columns) {
9474
+ wrapWord(rows, word, columns);
9475
+ rowLength = dist_default3(rows.at(-1) ?? "");
9476
+ continue;
9477
+ }
9478
+ rows.push("");
9479
+ rowLength = 0;
9480
+ }
9481
+ if (rowLength + wordLength > columns && options.wordWrap === false) {
9482
+ wrapWord(rows, word, columns);
9483
+ rowLength = dist_default3(rows.at(-1) ?? "");
9484
+ continue;
9485
+ }
9486
+ rows[rows.length - 1] += word;
9487
+ rowLength += wordLength;
9020
9488
  }
9021
- const message = theme.style.message(config.message, status);
9022
- let error = "";
9023
- if (errorMsg) {
9024
- error = theme.style.error(errorMsg);
9489
+ if (options.trim !== false) {
9490
+ rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
9025
9491
  }
9026
- return [`${prefix} ${message}${defaultValue} ${formattedValue}`, error];
9027
- });
9028
-
9029
- // ../lib/dist/io.js
9030
- import { spawn } from "node:child_process";
9031
- import { readdir, readFile, writeFile } from "node:fs/promises";
9032
- var ExecError = class extends Error {
9033
- command;
9034
- code;
9035
- stderr;
9036
- constructor(command, code, stderr) {
9037
- super(`${command} exited with ${code ?? "signal"}${stderr ? `
9038
- ${stderr.trimEnd()}` : ""}`);
9039
- this.command = command;
9040
- this.code = code;
9041
- this.stderr = stderr;
9492
+ const preString = rows.join("\n");
9493
+ let inSurrogate = false;
9494
+ for (let i = 0; i < preString.length; i++) {
9495
+ const character = preString[i];
9496
+ returnValue += character;
9497
+ if (!inSurrogate) {
9498
+ inSurrogate = character >= "\uD800" && character <= "\uDBFF";
9499
+ if (inSurrogate) {
9500
+ continue;
9501
+ }
9502
+ } else {
9503
+ inSurrogate = false;
9504
+ }
9505
+ if (character === ESC || character === CSI) {
9506
+ GROUP_REGEX.lastIndex = i + 1;
9507
+ const groupsResult = GROUP_REGEX.exec(preString);
9508
+ const groups = groupsResult?.groups;
9509
+ if (groups?.code !== void 0) {
9510
+ const code = Number.parseFloat(groups.code);
9511
+ escapeCode = code === END_CODE ? void 0 : code;
9512
+ } else if (groups?.uri !== void 0) {
9513
+ escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
9514
+ }
9515
+ }
9516
+ if (preString[i + 1] === "\n") {
9517
+ if (escapeUrl) {
9518
+ returnValue += wrapAnsiHyperlink("");
9519
+ }
9520
+ const closingCode = escapeCode ? getClosingCode(escapeCode) : void 0;
9521
+ if (escapeCode && closingCode) {
9522
+ returnValue += wrapAnsiCode(closingCode);
9523
+ }
9524
+ } else if (character === "\n") {
9525
+ if (escapeCode && getClosingCode(escapeCode)) {
9526
+ returnValue += wrapAnsiCode(escapeCode);
9527
+ }
9528
+ if (escapeUrl) {
9529
+ returnValue += wrapAnsiHyperlink(escapeUrl);
9530
+ }
9531
+ }
9042
9532
  }
9533
+ return returnValue;
9043
9534
  };
9044
- var isInteractive = () => process.stdin.isTTY === true && process.stderr.isTTY === true;
9045
- function realIo(prompt) {
9046
- return {
9047
- stdout: process.stdout,
9048
- stderr: process.stderr,
9049
- prompt: prompt && isInteractive() ? prompt : void 0,
9050
- exec: (command, args, options = {}) => new Promise((resolve2, reject) => {
9051
- const child = spawn(command, args, {
9052
- cwd: options.cwd,
9053
- env: options.env,
9054
- stdio: [options.input === void 0 ? "ignore" : "pipe", options.inherit ? "inherit" : "pipe", "pipe"]
9055
- });
9056
- let stdout = "";
9057
- let stderr = "";
9058
- child.stdout?.on("data", (chunk) => {
9059
- stdout += chunk;
9060
- });
9061
- child.stderr?.on("data", (chunk) => {
9062
- stderr += chunk;
9063
- if (options.inherit)
9064
- process.stderr.write(chunk);
9065
- });
9066
- child.on("error", reject);
9067
- child.on("close", (code) => {
9068
- if (code === 0)
9069
- resolve2(stdout);
9070
- else
9071
- reject(new ExecError(render(command, args), code, stderr));
9072
- });
9073
- if (options.input !== void 0)
9074
- child.stdin?.end(options.input);
9075
- }),
9076
- readFile: (path3) => readFile(path3, "utf8"),
9077
- writeFile: (path3, content) => writeFile(path3, content),
9078
- readDir: async (path3) => (await readdir(path3, { withFileTypes: true })).map((e) => ({ name: e.name, directory: e.isDirectory() }))
9079
- };
9535
+ var CRLF_OR_LF = /\r?\n/;
9536
+ function wrapAnsi(string, columns, options) {
9537
+ return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join("\n");
9538
+ }
9539
+
9540
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/utils.js
9541
+ function breakLines(content, width) {
9542
+ return content.split("\n").flatMap((line) => wrapAnsi(line, width, { trim: false, wordWrap: false }).split("\n").map((str) => str.trimEnd())).join("\n");
9543
+ }
9544
+ function readlineWidth() {
9545
+ return (0, import_cli_width.default)({ defaultWidth: 80, output: readline().output });
9546
+ }
9547
+
9548
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/create-prompt.js
9549
+ import * as readline2 from "node:readline";
9550
+ import { AsyncResource as AsyncResource3 } from "node:async_hooks";
9551
+
9552
+ // ../../node_modules/.pnpm/@inquirer+type@4.2.0_@types+node@26.6.5/node_modules/@inquirer/type/dist/utils.js
9553
+ function withResolver() {
9554
+ let resolve6;
9555
+ let reject;
9556
+ const promise = new Promise((res, rej) => {
9557
+ resolve6 = res;
9558
+ reject = rej;
9559
+ });
9560
+ return { promise, resolve: resolve6, reject };
9080
9561
  }
9081
- function render(command, args) {
9082
- return [command, ...args].map(quote).join(" ");
9562
+
9563
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/create-prompt.js
9564
+ var import_mute_stream = __toESM(require_lib(), 1);
9565
+
9566
+ // ../../node_modules/.pnpm/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/signals.js
9567
+ var signals = [];
9568
+ signals.push("SIGHUP", "SIGINT", "SIGTERM");
9569
+ if (process.platform !== "win32") {
9570
+ signals.push(
9571
+ "SIGALRM",
9572
+ "SIGABRT",
9573
+ "SIGVTALRM",
9574
+ "SIGXCPU",
9575
+ "SIGXFSZ",
9576
+ "SIGUSR2",
9577
+ "SIGTRAP",
9578
+ "SIGSYS",
9579
+ "SIGQUIT",
9580
+ "SIGIOT"
9581
+ // should detect profiler and enable/disable accordingly.
9582
+ // see #21
9583
+ // 'SIGPROF'
9584
+ );
9083
9585
  }
9084
- function quote(arg) {
9085
- return /^[\w./:@%+=,-]+$/.test(arg) ? arg : `'${arg.replaceAll("'", "'\\''")}'`;
9586
+ if (process.platform === "linux") {
9587
+ signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
9086
9588
  }
9087
9589
 
9088
- // ../lib/dist/plan.js
9089
- function describe(step) {
9090
- switch (step.kind) {
9091
- case "run":
9092
- return `$ ${step.cwd ? `(cd ${step.cwd} && ` : ""}${render(step.command, step.args)}${step.cwd ? ")" : ""}`;
9093
- case "ssh":
9094
- return `$ ${render("ssh", [step.host, "bash", "-s"])} <<'EOF'`;
9095
- case "write":
9096
- return `> ${step.path} (${Buffer.byteLength(step.content)} bytes)`;
9590
+ // ../../node_modules/.pnpm/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/index.js
9591
+ var processOk = (process5) => !!process5 && typeof process5 === "object" && typeof process5.removeListener === "function" && typeof process5.emit === "function" && typeof process5.reallyExit === "function" && typeof process5.listeners === "function" && typeof process5.kill === "function" && typeof process5.pid === "number" && typeof process5.on === "function";
9592
+ var kExitEmitter = /* @__PURE__ */ Symbol.for("signal-exit emitter");
9593
+ var global = globalThis;
9594
+ var ObjectDefineProperty = Object.defineProperty.bind(Object);
9595
+ var Emitter = class {
9596
+ emitted = {
9597
+ afterExit: false,
9598
+ exit: false
9599
+ };
9600
+ listeners = {
9601
+ afterExit: [],
9602
+ exit: []
9603
+ };
9604
+ count = 0;
9605
+ id = Math.random();
9606
+ constructor() {
9607
+ if (global[kExitEmitter]) {
9608
+ return global[kExitEmitter];
9609
+ }
9610
+ ObjectDefineProperty(global, kExitEmitter, {
9611
+ value: this,
9612
+ writable: false,
9613
+ enumerable: false,
9614
+ configurable: false
9615
+ });
9097
9616
  }
9098
- }
9099
- function body(step) {
9100
- switch (step.kind) {
9101
- case "run":
9102
- return step.input;
9103
- case "ssh":
9104
- return `${step.script.trimEnd()}
9105
- EOF`;
9106
- case "write":
9107
- return step.content;
9617
+ on(ev, fn) {
9618
+ this.listeners[ev].push(fn);
9108
9619
  }
9109
- }
9110
-
9111
- // ../lib/dist/context.js
9112
- var Context = class {
9113
- dryRun;
9114
- verbose;
9115
- quiet;
9116
- yes;
9117
- json;
9118
- io;
9119
- constructor(options, io = realIo()) {
9120
- this.io = io;
9121
- this.dryRun = options.dryRun ?? false;
9122
- this.quiet = options.quiet ?? false;
9123
- this.verbose = this.quiet ? -1 : options.verbose ?? 0;
9124
- this.yes = options.yes ?? false;
9125
- this.json = options.json ?? false;
9620
+ removeListener(ev, fn) {
9621
+ const list2 = this.listeners[ev];
9622
+ const i = list2.indexOf(fn);
9623
+ if (i === -1) {
9624
+ return;
9625
+ }
9626
+ if (i === 0 && list2.length === 1) {
9627
+ list2.length = 0;
9628
+ } else {
9629
+ list2.splice(i, 1);
9630
+ }
9126
9631
  }
9127
- // --- narration (stderr) ---------------------------------------------------
9128
- /** One line, if the verbosity allows the level (0 normal, 1 verbose, 2 debug). */
9129
- say(line, level = 0) {
9130
- if (this.verbose >= level)
9131
- this.io.stderr.write(`${line}
9132
- `);
9632
+ emit(ev, code, signal) {
9633
+ if (this.emitted[ev]) {
9634
+ return false;
9635
+ }
9636
+ this.emitted[ev] = true;
9637
+ let ret = false;
9638
+ for (const fn of this.listeners[ev]) {
9639
+ ret = fn(code, signal) === true || ret;
9640
+ }
9641
+ if (ev === "exit") {
9642
+ ret = this.emit("afterExit", code, signal) || ret;
9643
+ }
9644
+ return ret;
9133
9645
  }
9134
- /** A final outcome line, `✓ ...` or `✗ ...`; shown even under --quiet. */
9135
- done(line, ok = true) {
9136
- this.io.stderr.write(`${ok ? "\u2713" : "\u2717"} ${line}
9137
- `);
9646
+ };
9647
+ var SignalExitBase = class {
9648
+ };
9649
+ var signalExitWrap = (handler) => {
9650
+ return {
9651
+ onExit(cb, opts) {
9652
+ return handler.onExit(cb, opts);
9653
+ },
9654
+ load() {
9655
+ return handler.load();
9656
+ },
9657
+ unload() {
9658
+ return handler.unload();
9659
+ }
9660
+ };
9661
+ };
9662
+ var SignalExitFallback = class extends SignalExitBase {
9663
+ onExit() {
9664
+ return () => {
9665
+ };
9138
9666
  }
9139
- // --- results (stdout) -----------------------------------------------------
9140
- /**
9141
- * The command's product. `data` is what --json prints; `human` renders it
9142
- * otherwise (default: strings as they are, arrays one item per line).
9143
- */
9144
- result(data, human = renderHuman) {
9145
- const text = this.json ? JSON.stringify(data, null, 2) : human(data);
9146
- this.io.stdout.write(text.endsWith("\n") ? text : `${text}
9147
- `);
9667
+ load() {
9148
9668
  }
9149
- // --- reads: always performed ---------------------------------------------
9150
- /** Run a command for its output. Changes nothing; narrated only when verbose. */
9151
- read(command, args = [], options = {}) {
9152
- this.say(`? ${describe({ kind: "run", command, args, ...options })}`, 1);
9153
- return this.io.exec(command, args, options);
9669
+ unload() {
9154
9670
  }
9155
- readFile(path3) {
9156
- this.say(`? read ${path3}`, 1);
9157
- return this.io.readFile(path3);
9671
+ };
9672
+ var SignalExit = class extends SignalExitBase {
9673
+ // "SIGHUP" throws an `ENOSYS` error on Windows,
9674
+ // so use a supported signal instead
9675
+ /* c8 ignore start */
9676
+ #hupSig = process3.platform === "win32" ? "SIGINT" : "SIGHUP";
9677
+ /* c8 ignore stop */
9678
+ #emitter = new Emitter();
9679
+ #process;
9680
+ #originalProcessEmit;
9681
+ #originalProcessReallyExit;
9682
+ #sigListeners = {};
9683
+ #loaded = false;
9684
+ constructor(process5) {
9685
+ super();
9686
+ this.#process = process5;
9687
+ this.#sigListeners = {};
9688
+ for (const sig of signals) {
9689
+ this.#sigListeners[sig] = () => {
9690
+ const listeners = this.#process.listeners(sig);
9691
+ let { count } = this.#emitter;
9692
+ const p = process5;
9693
+ if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") {
9694
+ count += p.__signal_exit_emitter__.count;
9695
+ }
9696
+ if (listeners.length === count) {
9697
+ this.unload();
9698
+ const ret = this.#emitter.emit("exit", null, sig);
9699
+ const s = sig === "SIGHUP" ? this.#hupSig : sig;
9700
+ if (!ret)
9701
+ process5.kill(process5.pid, s);
9702
+ }
9703
+ };
9704
+ }
9705
+ this.#originalProcessReallyExit = process5.reallyExit;
9706
+ this.#originalProcessEmit = process5.emit;
9158
9707
  }
9159
- readDir(path3) {
9160
- this.say(`? list ${path3}`, 2);
9161
- return this.io.readDir(path3);
9708
+ onExit(cb, opts) {
9709
+ if (!processOk(this.#process)) {
9710
+ return () => {
9711
+ };
9712
+ }
9713
+ if (this.#loaded === false) {
9714
+ this.load();
9715
+ }
9716
+ const ev = opts?.alwaysLast ? "afterExit" : "exit";
9717
+ this.#emitter.on(ev, cb);
9718
+ return () => {
9719
+ this.#emitter.removeListener(ev, cb);
9720
+ if (this.#emitter.listeners["exit"].length === 0 && this.#emitter.listeners["afterExit"].length === 0) {
9721
+ this.unload();
9722
+ }
9723
+ };
9162
9724
  }
9163
- // --- effects: narrated always, performed unless --dry-run -----------------
9164
- /**
9165
- * Ask before applying. `--yes` and `--dry-run` answer yes; off a terminal
9166
- * without `--yes` the answer is an error, never a hang.
9167
- */
9168
- async confirm(question) {
9169
- if (this.yes || this.dryRun) {
9170
- this.say(`? ${question} yes (${this.yes ? "--yes" : "--dry-run"})`, 1);
9171
- return true;
9725
+ load() {
9726
+ if (this.#loaded) {
9727
+ return;
9172
9728
  }
9173
- if (!this.io.prompt)
9174
- throw new Error(`cannot ask "${question}" without a terminal; pass --yes`);
9175
- return this.io.prompt(question);
9729
+ this.#loaded = true;
9730
+ this.#emitter.count += 1;
9731
+ for (const sig of signals) {
9732
+ try {
9733
+ const fn = this.#sigListeners[sig];
9734
+ if (fn)
9735
+ this.#process.on(sig, fn);
9736
+ } catch (_) {
9737
+ }
9738
+ }
9739
+ this.#process.emit = (ev, ...a) => {
9740
+ return this.#processEmit(ev, ...a);
9741
+ };
9742
+ this.#process.reallyExit = (code) => {
9743
+ return this.#processReallyExit(code);
9744
+ };
9745
+ }
9746
+ unload() {
9747
+ if (!this.#loaded) {
9748
+ return;
9749
+ }
9750
+ this.#loaded = false;
9751
+ signals.forEach((sig) => {
9752
+ const listener = this.#sigListeners[sig];
9753
+ if (!listener) {
9754
+ throw new Error("Listener not defined for signal: " + sig);
9755
+ }
9756
+ try {
9757
+ this.#process.removeListener(sig, listener);
9758
+ } catch (_) {
9759
+ }
9760
+ });
9761
+ this.#process.emit = this.#originalProcessEmit;
9762
+ this.#process.reallyExit = this.#originalProcessReallyExit;
9763
+ this.#emitter.count -= 1;
9176
9764
  }
9177
- /** Narrate and perform each step in order; the first failure stops the run. */
9178
- async apply(plan) {
9179
- for (const step of plan) {
9180
- this.say(`${this.dryRun ? "[dry-run] " : ""}${describe(step)}`);
9181
- const input = body(step);
9182
- if (input !== void 0)
9183
- this.say(indent(input), step.kind === "write" ? 2 : 1);
9184
- if (!this.dryRun)
9185
- await this.perform(step);
9765
+ #processReallyExit(code) {
9766
+ if (!processOk(this.#process)) {
9767
+ return 0;
9186
9768
  }
9769
+ this.#process.exitCode = code || 0;
9770
+ this.#emitter.emit("exit", this.#process.exitCode, null);
9771
+ return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);
9187
9772
  }
9188
- perform(step) {
9189
- const inherit = this.verbose >= 2;
9190
- switch (step.kind) {
9191
- case "run":
9192
- return this.io.exec(step.command, step.args, { cwd: step.cwd, input: step.input, inherit });
9193
- case "ssh":
9194
- return this.io.exec("ssh", [step.host, "bash", "-s"], { input: step.script, inherit });
9195
- case "write":
9196
- return this.io.writeFile(step.path, step.content);
9773
+ #processEmit(ev, ...args) {
9774
+ const og = this.#originalProcessEmit;
9775
+ if (ev === "exit" && processOk(this.#process)) {
9776
+ if (typeof args[0] === "number") {
9777
+ this.#process.exitCode = args[0];
9778
+ }
9779
+ const ret = og.call(this.#process, ev, ...args);
9780
+ this.#emitter.emit("exit", this.#process.exitCode, null);
9781
+ return ret;
9782
+ } else {
9783
+ return og.call(this.#process, ev, ...args);
9197
9784
  }
9198
9785
  }
9199
9786
  };
9200
- function renderHuman(data) {
9201
- if (typeof data === "string")
9202
- return data;
9203
- if (Array.isArray(data))
9204
- return data.map(String).join("\n");
9205
- return JSON.stringify(data, null, 2);
9206
- }
9207
- function indent(text) {
9208
- return text.trimEnd().split("\n").map((l) => ` ${l}`).join("\n");
9209
- }
9210
-
9211
- // ../lib/dist/copier.js
9212
- var import_yaml = __toESM(require_dist(), 1);
9213
- var ANSWERS_FILE = ".copier-answers.yml";
9214
- var TEMPLATE_FILES = ["copier.yml", "copier.yaml"];
9215
- function parseAnswers(text) {
9216
- const data = (0, import_yaml.parse)(text);
9217
- if (data === null || typeof data !== "object" || Array.isArray(data))
9218
- throw new Error("answers file is not a mapping");
9219
- const { _commit, _src_path, ...answers } = data;
9220
- return {
9221
- commit: _commit === void 0 ? void 0 : String(_commit),
9222
- src: _src_path === void 0 ? void 0 : String(_src_path),
9223
- answers
9224
- };
9225
- }
9787
+ var process3 = globalThis.process;
9788
+ var {
9789
+ /**
9790
+ * Called when the process is exiting, whether via signal, explicit
9791
+ * exit, or running out of stuff to do.
9792
+ *
9793
+ * If the global process object is not suitable for instrumentation,
9794
+ * then this will be a no-op.
9795
+ *
9796
+ * Returns a function that may be used to unload signal-exit.
9797
+ */
9798
+ onExit,
9799
+ /**
9800
+ * Load the listeners. Likely you never need to call this, unless
9801
+ * doing a rather deep integration with signal-exit functionality.
9802
+ * Mostly exposed for the benefit of testing.
9803
+ *
9804
+ * @internal
9805
+ */
9806
+ load,
9807
+ /**
9808
+ * Unload the listeners. Likely you never need to call this, unless
9809
+ * doing a rather deep integration with signal-exit functionality.
9810
+ * Mostly exposed for the benefit of testing.
9811
+ *
9812
+ * @internal
9813
+ */
9814
+ unload
9815
+ } = signalExitWrap(processOk(process3) ? new SignalExit(process3) : new SignalExitFallback());
9226
9816
 
9227
- // ../lib/dist/marker.js
9228
- var import_yaml2 = __toESM(require_dist(), 1);
9229
- var MARKER_FILE = "PLEXUS.md";
9230
- function parseMarker(text) {
9231
- const { data, body: body2 } = splitFrontmatter(text);
9232
- const plexus = data.plexus;
9233
- const modules = data.modules;
9234
- if (typeof plexus !== "string" && typeof plexus !== "number")
9235
- throw new Error("marker: `plexus` must be a version");
9236
- if (!Array.isArray(modules) || !modules.every((m) => typeof m === "string"))
9237
- throw new Error("marker: `modules` must be a list of module codes");
9238
- return { plexus: String(plexus), modules, body: body2 };
9239
- }
9240
- function splitFrontmatter(text) {
9241
- const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)([\s\S]*)$/.exec(text);
9242
- if (!match)
9243
- throw new Error("no frontmatter: expected a `---` block at the top");
9244
- const data = (0, import_yaml2.parse)(match[1] ?? "");
9245
- if (data === null || typeof data !== "object" || Array.isArray(data))
9246
- throw new Error("frontmatter is not a mapping");
9247
- return { data, body: match[2] ?? "" };
9248
- }
9817
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/screen-manager.js
9818
+ import { stripVTControlCharacters } from "node:util";
9249
9819
 
9250
- // ../lib/dist/model.js
9251
- function kindOf(declaration) {
9252
- const has = (code) => declaration.modules.includes(code);
9253
- if (has("PLX-App"))
9254
- return "app";
9255
- if (has("PLX-Platform"))
9256
- return "platform";
9257
- if (has("PLX-Repo"))
9258
- return "repo";
9259
- return void 0;
9260
- }
9261
- function shortRemote(url) {
9262
- const bare = url.replace(/\.git$/, "").replace(/\/$/, "");
9263
- const m = /^(?:git@github\.com:|github\.com:|ssh:\/\/git@github\.com\/|https?:\/\/github\.com\/)(.+)$/.exec(bare);
9264
- return m ? `gh:${m[1]}` : bare;
9265
- }
9266
- function isNotable(dir) {
9267
- return Boolean(dir.git || dir.template || dir.copier || dir.declaration || dir.problems?.length);
9268
- }
9820
+ // ../../node_modules/.pnpm/@inquirer+ansi@2.0.9/node_modules/@inquirer/ansi/dist/index.js
9821
+ var ESC2 = "\x1B[";
9822
+ var cursorLeft = ESC2 + "G";
9823
+ var cursorHide = ESC2 + "?25l";
9824
+ var cursorShow = ESC2 + "?25h";
9825
+ var cursorUp = (rows = 1) => rows > 0 ? `${ESC2}${rows}A` : "";
9826
+ var cursorDown = (rows = 1) => rows > 0 ? `${ESC2}${rows}B` : "";
9827
+ var cursorTo = (x, y) => {
9828
+ if (typeof y === "number" && !Number.isNaN(y)) {
9829
+ return `${ESC2}${y + 1};${x + 1}H`;
9830
+ }
9831
+ return `${ESC2}${x + 1}G`;
9832
+ };
9833
+ var eraseLine = ESC2 + "2K";
9834
+ var eraseLines = (lines) => lines > 0 ? (eraseLine + cursorUp(1)).repeat(lines - 1) + eraseLine + cursorLeft : "";
9269
9835
 
9270
- // ../lib/dist/overview.js
9271
- import { join } from "node:path";
9272
- var PRUNED = /* @__PURE__ */ new Set([
9273
- "node_modules",
9274
- ".hg",
9275
- ".svn",
9276
- ".next",
9277
- ".nuxt",
9278
- ".turbo",
9279
- ".svelte-kit",
9280
- "dist",
9281
- "build",
9282
- "out",
9283
- ".output",
9284
- ".venv",
9285
- "venv",
9286
- "__pycache__",
9287
- "target",
9288
- ".cache",
9289
- ".pnpm-store",
9290
- "coverage",
9291
- "vendor",
9292
- ".terraform",
9293
- ".gradle"
9294
- ]);
9295
- async function overview(ctx, root) {
9296
- const dir = await walk(ctx, root, root.replace(/\/+$/, "").split("/").pop() || root);
9297
- return dir;
9298
- }
9299
- async function walk(ctx, path3, name) {
9300
- const entries = await ctx.readDir(path3);
9301
- const files = new Set(entries.filter((e) => !e.directory).map((e) => e.name));
9302
- const names = new Set(entries.map((e) => e.name));
9303
- const dir = { name, path: path3, children: [] };
9304
- if (names.has(".git"))
9305
- dir.git = await gitFacet(ctx, path3);
9306
- if (TEMPLATE_FILES.some((f) => files.has(f)))
9307
- dir.template = await templateFacet(ctx, path3);
9308
- if (files.has(ANSWERS_FILE)) {
9309
- await facet(ctx, dir, ANSWERS_FILE, (text) => {
9310
- dir.copier = parseAnswers(text);
9311
- });
9836
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/screen-manager.js
9837
+ var height = (content) => content.split("\n").length;
9838
+ var lastLine = (content) => content.split("\n").pop() ?? "";
9839
+ var ScreenManager = class {
9840
+ // These variables are keeping information to allow correct prompt re-rendering
9841
+ height = 0;
9842
+ extraLinesUnderPrompt = 0;
9843
+ cursorPos;
9844
+ rl;
9845
+ constructor(rl) {
9846
+ this.rl = rl;
9847
+ this.cursorPos = rl.getCursorPos();
9312
9848
  }
9313
- if (files.has(MARKER_FILE)) {
9314
- await facet(ctx, dir, MARKER_FILE, (text) => {
9315
- dir.declaration = parseMarker(text);
9316
- });
9849
+ write(content) {
9850
+ this.rl.output.unmute();
9851
+ this.rl.output.write(content);
9852
+ this.rl.output.mute();
9317
9853
  }
9318
- const subdirs = entries.filter((e) => e.directory && e.name !== ".git" && !PRUNED.has(e.name)).map((e) => e.name).sort();
9319
- for (const sub of subdirs) {
9320
- const child = await walk(ctx, join(path3, sub), sub);
9321
- if (isNotable(child) || child.children.length > 0)
9322
- dir.children.push(child);
9854
+ render(content, bottomContent = "") {
9855
+ const promptLine = lastLine(content);
9856
+ const rawPromptLine = stripVTControlCharacters(promptLine);
9857
+ let prompt = rawPromptLine;
9858
+ if (this.rl.line.length > 0) {
9859
+ prompt = prompt.slice(0, -this.rl.line.length);
9860
+ }
9861
+ this.rl.setPrompt(prompt);
9862
+ this.cursorPos = this.rl.getCursorPos();
9863
+ const width = readlineWidth();
9864
+ content = breakLines(content, width);
9865
+ bottomContent = breakLines(bottomContent, width);
9866
+ if (rawPromptLine.length % width === 0) {
9867
+ content += "\n";
9868
+ }
9869
+ let output = content + (bottomContent ? "\n" + bottomContent : "");
9870
+ const promptLineUpDiff = Math.floor(rawPromptLine.length / width) - this.cursorPos.rows;
9871
+ const bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0);
9872
+ if (bottomContentHeight > 0)
9873
+ output += cursorUp(bottomContentHeight);
9874
+ output += cursorTo(this.cursorPos.cols);
9875
+ this.write(cursorDown(this.extraLinesUnderPrompt) + eraseLines(this.height) + output);
9876
+ this.extraLinesUnderPrompt = bottomContentHeight;
9877
+ this.height = height(output);
9878
+ }
9879
+ checkCursorPos() {
9880
+ const cursorPos = this.rl.getCursorPos();
9881
+ if (cursorPos.cols !== this.cursorPos.cols) {
9882
+ this.write(cursorTo(cursorPos.cols));
9883
+ this.cursorPos = cursorPos;
9884
+ }
9885
+ }
9886
+ done({ clearContent }) {
9887
+ this.rl.setPrompt("");
9888
+ let output = cursorDown(this.extraLinesUnderPrompt);
9889
+ output += clearContent ? eraseLines(this.height) : "\n";
9890
+ output += cursorLeft;
9891
+ output += cursorShow;
9892
+ this.write(output);
9893
+ this.rl.close();
9323
9894
  }
9324
- return dir;
9325
- }
9326
- async function facet(ctx, dir, file, read) {
9327
- try {
9328
- read(await ctx.readFile(join(dir.path, file)));
9329
- } catch (error) {
9330
- dir.problems ??= [];
9331
- dir.problems.push(`${file}: ${error instanceof Error ? error.message : String(error)}`);
9895
+ };
9896
+
9897
+ // ../../node_modules/.pnpm/@inquirer+core@12.0.5_@types+node@26.6.5/node_modules/@inquirer/core/dist/lib/create-prompt.js
9898
+ import path from "node:path";
9899
+ var nativeSetImmediate = globalThis.setImmediate;
9900
+ var nativeClearImmediate = globalThis.clearImmediate;
9901
+ function listenTo(target, event, listener) {
9902
+ if ("on" in target) {
9903
+ target.on(event, listener);
9904
+ return () => target.removeListener(event, listener);
9332
9905
  }
9906
+ target.addEventListener(event, listener);
9907
+ return () => target.removeEventListener(event, listener);
9333
9908
  }
9334
- async function git(ctx, cwd, args) {
9909
+ function getCallSites() {
9910
+ const savedPrepareStackTrace = Error.prepareStackTrace;
9911
+ let result = [];
9335
9912
  try {
9336
- const out = (await ctx.read("git", args, { cwd })).trim();
9337
- return out === "" ? void 0 : out;
9913
+ Error.prepareStackTrace = (_, callSites) => {
9914
+ const callSitesWithoutCurrent = callSites.slice(1);
9915
+ result = callSitesWithoutCurrent;
9916
+ return callSitesWithoutCurrent;
9917
+ };
9918
+ new Error().stack;
9338
9919
  } catch {
9339
- return void 0;
9340
- }
9341
- }
9342
- async function gitFacet(ctx, cwd) {
9343
- const branch = await git(ctx, cwd, ["symbolic-ref", "--short", "-q", "HEAD"]) ?? await git(ctx, cwd, ["rev-parse", "--short", "HEAD"]) ?? "?";
9344
- const dirty = await git(ctx, cwd, ["status", "--porcelain"]) !== void 0;
9345
- const remote = await git(ctx, cwd, ["remote", "get-url", "origin"]);
9346
- let defaultRef = await git(ctx, cwd, ["symbolic-ref", "--short", "-q", "refs/remotes/origin/HEAD"]);
9347
- for (const b of ["main", "master"]) {
9348
- if (defaultRef)
9349
- break;
9350
- if (await git(ctx, cwd, ["rev-parse", "--verify", "-q", `refs/heads/${b}`]))
9351
- defaultRef = b;
9920
+ return result;
9352
9921
  }
9353
- const tag = defaultRef ? await git(ctx, cwd, ["describe", "--tags", "--abbrev=0", defaultRef]) : void 0;
9354
- const facet2 = { branch, dirty };
9355
- if (tag)
9356
- facet2.tag = tag;
9357
- if (remote)
9358
- facet2.remote = shortRemote(remote);
9359
- return facet2;
9922
+ Error.prepareStackTrace = savedPrepareStackTrace;
9923
+ return result;
9360
9924
  }
9361
- async function templateFacet(ctx, cwd) {
9362
- const tag = await git(ctx, cwd, ["describe", "--tags", "--abbrev=0"]) ?? (await git(ctx, cwd, ["tag", "--list", "--sort=-v:refname"]))?.split("\n")[0];
9363
- return tag ? { tag } : {};
9925
+ function createPrompt(view) {
9926
+ const callSites = getCallSites();
9927
+ const prompt = (config, context = {}) => {
9928
+ const { input = process.stdin, signal } = context;
9929
+ const cleanups = /* @__PURE__ */ new Set();
9930
+ const output = new import_mute_stream.default();
9931
+ output.pipe(context.output ?? process.stdout);
9932
+ const rl = readline2.createInterface({
9933
+ terminal: true,
9934
+ input,
9935
+ output
9936
+ });
9937
+ output.mute();
9938
+ const screen = new ScreenManager(rl);
9939
+ const { promise, resolve: resolve6, reject } = withResolver();
9940
+ return withHooks(rl, (cycle) => {
9941
+ const clearEffects = AsyncResource3.bind(() => effectScheduler.clearAll());
9942
+ const settlePrompt = (settle) => {
9943
+ try {
9944
+ clearEffects();
9945
+ settle();
9946
+ } catch (error) {
9947
+ reject(error);
9948
+ }
9949
+ };
9950
+ const resolvePrompt = (value) => settlePrompt(() => resolve6(value));
9951
+ const rejectPrompt = (error) => settlePrompt(() => reject(error));
9952
+ const promptPromise = Object.assign(promise.finally(() => {
9953
+ cleanups.forEach((cleanup) => cleanup());
9954
+ screen.done({ clearContent: Boolean(context.clearPromptOnDone) });
9955
+ output.end();
9956
+ }).then(() => promise), { cancel: () => rejectPrompt(new CancelPromptError()) });
9957
+ if (signal) {
9958
+ const abort = () => rejectPrompt(new AbortPromptError({ cause: signal.reason }));
9959
+ if (signal.aborted) {
9960
+ abort();
9961
+ return promptPromise;
9962
+ }
9963
+ cleanups.add(listenTo(signal, "abort", abort));
9964
+ }
9965
+ cleanups.add(onExit((code, signal2) => {
9966
+ rejectPrompt(new ExitPromptError(`User force closed the prompt with ${code} ${signal2}`));
9967
+ }));
9968
+ cleanups.add(listenTo(rl, "SIGINT", () => rejectPrompt(new ExitPromptError(`User force closed the prompt with SIGINT`))));
9969
+ cleanups.add(listenTo(rl, "close", clearEffects));
9970
+ const startCycle = () => {
9971
+ cleanups.add(listenTo(rl.input, "keypress", () => screen.checkCursorPos()));
9972
+ let pendingDone = null;
9973
+ cycle(() => {
9974
+ let effectsSettled = false;
9975
+ try {
9976
+ const nextView = view(config, (value) => {
9977
+ if (effectsSettled) {
9978
+ resolvePrompt(value);
9979
+ } else {
9980
+ pendingDone = { value };
9981
+ }
9982
+ });
9983
+ if (nextView === void 0) {
9984
+ let callerFilename = callSites[1]?.getFileName();
9985
+ if (callerFilename && !callerFilename.startsWith("file://")) {
9986
+ callerFilename = path.resolve(callerFilename);
9987
+ }
9988
+ throw new Error(`Prompt functions must return a string.
9989
+ at ${callerFilename}`);
9990
+ }
9991
+ const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
9992
+ screen.render(content, bottomContent);
9993
+ effectScheduler.run();
9994
+ } catch (error) {
9995
+ rejectPrompt(error);
9996
+ }
9997
+ effectsSettled = true;
9998
+ if (pendingDone !== null) {
9999
+ const { value } = pendingDone;
10000
+ pendingDone = null;
10001
+ resolvePrompt(value);
10002
+ }
10003
+ });
10004
+ };
10005
+ if ("readableFlowing" in input) {
10006
+ const immediate = nativeSetImmediate(startCycle);
10007
+ cleanups.add(() => nativeClearImmediate(immediate));
10008
+ } else {
10009
+ startCycle();
10010
+ }
10011
+ return promptPromise;
10012
+ });
10013
+ };
10014
+ return prompt;
9364
10015
  }
9365
10016
 
10017
+ // ../../node_modules/.pnpm/@inquirer+confirm@6.3.4_@types+node@26.6.5/node_modules/@inquirer/confirm/dist/index.js
10018
+ import { styleText as styleText2 } from "node:util";
10019
+ var confirmTheme = {
10020
+ keywords: {
10021
+ yes: "Yes",
10022
+ no: "No",
10023
+ error: ({ yes, no }) => `You must answer with "${yes}" or "${no}"`
10024
+ },
10025
+ style: {
10026
+ confirmDefault: (text) => {
10027
+ const first = text[0] ?? "";
10028
+ if (first.toLowerCase() === first.toUpperCase()) {
10029
+ return styleText2("cyan", text);
10030
+ }
10031
+ return first.toUpperCase() + text.slice(1);
10032
+ }
10033
+ }
10034
+ };
10035
+ var dist_default4 = createPrompt((config, done) => {
10036
+ const [status, setStatus] = useState("idle");
10037
+ const [value, setValue] = useState("");
10038
+ const [errorMsg, setError] = useState();
10039
+ const theme = makeTheme(confirmTheme, config.theme);
10040
+ const prefix = usePrefix({ status, theme });
10041
+ const { yes, no } = theme.keywords;
10042
+ const yesHint = (yes[0] ?? "").toLowerCase();
10043
+ const noHint = (no[0] ?? "").toLowerCase();
10044
+ const hint = config.default === false ? `${yesHint}/${theme.style.confirmDefault(noHint)}` : `${theme.style.confirmDefault(yesHint)}/${noHint}`;
10045
+ function boolToString(value2) {
10046
+ return value2 ? yes : no;
10047
+ }
10048
+ const { transformer = boolToString } = config;
10049
+ function getBooleanValue(value2) {
10050
+ const v = value2.trim().toLowerCase();
10051
+ if (v === "")
10052
+ return config.default !== false;
10053
+ if (yes.toLowerCase().startsWith(v))
10054
+ return true;
10055
+ if (no.toLowerCase().startsWith(v))
10056
+ return false;
10057
+ if ("yes".startsWith(v))
10058
+ return true;
10059
+ if ("no".startsWith(v))
10060
+ return false;
10061
+ return void 0;
10062
+ }
10063
+ useKeypress((key, rl) => {
10064
+ if (status !== "idle")
10065
+ return;
10066
+ if (isEnterKey(key)) {
10067
+ const answer = getBooleanValue(value);
10068
+ if (answer === void 0) {
10069
+ rl.write(value);
10070
+ setError(theme.keywords.error({ yes, no }));
10071
+ return;
10072
+ }
10073
+ setValue(transformer(answer));
10074
+ setStatus("done");
10075
+ done(answer);
10076
+ } else if (isTabKey(key)) {
10077
+ const answer = boolToString(!(getBooleanValue(value) ?? config.default !== false));
10078
+ rl.clearLine(0);
10079
+ rl.write(answer);
10080
+ setValue(answer);
10081
+ } else {
10082
+ setValue(rl.line);
10083
+ setError(void 0);
10084
+ }
10085
+ });
10086
+ let formattedValue = value;
10087
+ let defaultValue = "";
10088
+ if (status === "done") {
10089
+ formattedValue = theme.style.answer(value);
10090
+ } else {
10091
+ defaultValue = ` ${theme.style.defaultAnswer(hint)}`;
10092
+ }
10093
+ const message = theme.style.message(config.message, status);
10094
+ let error = "";
10095
+ if (errorMsg) {
10096
+ error = theme.style.error(errorMsg);
10097
+ }
10098
+ return [`${prefix} ${message}${defaultValue} ${formattedValue}`, error];
10099
+ });
10100
+
9366
10101
  // ../../node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
9367
10102
  var CommanderError = class extends Error {
9368
10103
  /**
@@ -10792,8 +11527,8 @@ var Command = class _Command extends EventEmitter {
10792
11527
  * @return {Command} `this` command for chaining
10793
11528
  */
10794
11529
  arguments(names) {
10795
- names.trim().split(/ +/).forEach((detail) => {
10796
- this.argument(detail);
11530
+ names.trim().split(/ +/).forEach((detail2) => {
11531
+ this.argument(detail2);
10797
11532
  });
10798
11533
  return this;
10799
11534
  }
@@ -12731,8 +13466,9 @@ function useColor() {
12731
13466
  // ../../node_modules/.pnpm/commander@15.0.0/node_modules/commander/index.js
12732
13467
  var program = new Command();
12733
13468
 
12734
- // src/commands/overview.ts
12735
- import { resolve } from "node:path";
13469
+ // src/commands/doctor.ts
13470
+ import { existsSync } from "node:fs";
13471
+ import { join as join7, resolve } from "node:path";
12736
13472
 
12737
13473
  // src/style.ts
12738
13474
  function style(enabled) {
@@ -12741,11 +13477,49 @@ function style(enabled) {
12741
13477
  }
12742
13478
  var colorByDefault = () => process.stdout.isTTY === true && !process.env.NO_COLOR;
12743
13479
 
12744
- // src/commands/overview.ts
13480
+ // src/commands/doctor.ts
13481
+ var WORKSPACE_COMPENDIUM = "plexus-ms/compendium";
12745
13482
  function register(program2) {
13483
+ program2.command("doctor").description("check every PLEXUS.md under a directory for modules that changed since and dependencies not declared").argument("[dir]", "directory to check", ".").option(
13484
+ "--compendium <path>",
13485
+ `compendium checkout to read the modules from (default: <dir>/${WORKSPACE_COMPENDIUM})`
13486
+ ).option("--color", "colour the report even when piped").option("--no-color", "never colour the report").action(async (dir, opts, command) => {
13487
+ const ctx = contextOf2(command);
13488
+ const root = resolve(dir);
13489
+ const compendium = resolve(opts.compendium ?? join7(root, WORKSPACE_COMPENDIUM));
13490
+ if (!existsSync(join7(compendium, "contracts")))
13491
+ throw new Error(
13492
+ `no compendium at ${compendium}; pass --compendium <path to a checkout of plexus-ms/compendium>`
13493
+ );
13494
+ const catalog = await readCatalog(ctx, compendium);
13495
+ const report = diagnose(await overview(ctx, root, { git: false }), catalog);
13496
+ const s = style(opts.color ?? colorByDefault());
13497
+ ctx.result(report, (r) => renderReport(r, s, !ctx.quiet));
13498
+ if (report.stale > 0 || report.declarations.length === 0) process.exitCode = 1;
13499
+ });
13500
+ }
13501
+ function renderReport(report, s, showCurrent) {
13502
+ const lines = [];
13503
+ for (const d of report.declarations) {
13504
+ if (d.findings.length === 0) {
13505
+ if (showCurrent) lines.push(`${s.ok("\u2713")} ${d.path}: ${d.plexus} ${s.dim(`[${d.modules.join(", ")}]`)}`);
13506
+ continue;
13507
+ }
13508
+ for (const f of d.findings) lines.push(`${s.warn("\u2717")} ${d.path}: ${f}`);
13509
+ }
13510
+ const n = report.declarations.length;
13511
+ if (n === 0) lines.push(s.warn("\u2717 no PLEXUS.md marker found"));
13512
+ else if (report.stale > 0) lines.push(s.warn(`\u2717 ${report.stale} of ${n} declarations stale or incomplete`));
13513
+ else lines.push(s.ok(`\u2713 ${n} declarations current and complete`));
13514
+ return lines.join("\n");
13515
+ }
13516
+
13517
+ // src/commands/overview.ts
13518
+ import { resolve as resolve2 } from "node:path";
13519
+ function register2(program2) {
12746
13520
  program2.command("overview").description("map the git repos, copier templates and projects, and Plexus units under a directory").argument("[dir]", "directory to map", ".").option("--color", "colour the tree even when piped").option("--no-color", "never colour the tree").action(async (dir, opts, command) => {
12747
- const ctx = contextOf(command);
12748
- const tree = await overview(ctx, resolve(dir));
13521
+ const ctx = contextOf2(command);
13522
+ const tree = await overview(ctx, resolve2(dir));
12749
13523
  const s = style(opts.color ?? colorByDefault());
12750
13524
  ctx.result(tree, (t) => renderTree(t, s, ctx.verbose >= 1));
12751
13525
  });
@@ -12787,8 +13561,68 @@ function annotate(dir, s, modules) {
12787
13561
  return tags.length ? ` ${tags.join(" ")}` : "";
12788
13562
  }
12789
13563
 
13564
+ // src/commands/propagate.ts
13565
+ import { resolve as resolve4 } from "node:path";
13566
+
13567
+ // src/commands/ship.ts
13568
+ import { resolve as resolve3 } from "node:path";
13569
+ function register3(program2) {
13570
+ program2.command("ship").description("release the train: tag every train repo identically, then copier-update every consumer").argument("[dir]", "the workspace: plexus-ms/ and the consumers sit under it", ".").option("--train <version>", "the train version, plain semver (default: minor+1 over the latest train)").action(async (dir, opts, command) => {
13571
+ const ctx = contextOf2(command);
13572
+ const result = await ship(ctx, { workspace: resolve3(dir), train: opts.train });
13573
+ ctx.result(result, (r) => renderSummary(r, `plx -y ship --train ${r.train} ${dir}`));
13574
+ if (!isClean(result)) process.exitCode = 1;
13575
+ });
13576
+ }
13577
+ function renderSummary(s, realCommand) {
13578
+ const lines = ["\u2500\u2500 summary \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"];
13579
+ for (const p of s.clean) lines.push(` \u2713 clean: ${p}`);
13580
+ for (const p of s.conflicted) lines.push(` \u2717 conflicts: ${p}`);
13581
+ for (const p of s.failed) lines.push(` \u2717 failed: ${p}`);
13582
+ for (const { path: path3, reason } of s.skipped) lines.push(` \u26A0 skipped: ${path3} (${reason})`);
13583
+ const clean = isClean(s);
13584
+ if (s.preview) {
13585
+ lines.push(" (preview only \u2014 nothing was changed)");
13586
+ if (clean) lines.push(`\u2713 dry run clean \u2014 run it for real: ${realCommand}`);
13587
+ } else if (clean) {
13588
+ lines.push("\u2713 done \u2014 review consumer diffs, commit (web repos on develop, platform repos on main), push");
13589
+ }
13590
+ if (!clean) lines.push("\u2717 needs attention \u2014 see above; fix the consumer, then re-run propagate");
13591
+ return lines.join("\n");
13592
+ }
13593
+
13594
+ // src/commands/propagate.ts
13595
+ function register4(program2) {
13596
+ program2.command("propagate").description("copier-update every consumer of the presets to the current train, and pin their ci-cd workflow refs").argument("[dir]", "the workspace: plexus-ms/ and the consumers sit under it", ".").option("--train <version>", "the train to propagate (default: the current one)").action(async (dir, opts, command) => {
13597
+ const ctx = contextOf2(command);
13598
+ const result = await ship(ctx, { workspace: resolve4(dir), train: opts.train, propagateOnly: true });
13599
+ ctx.result(result, (r) => renderSummary(r, `plx -y propagate --train ${r.train} ${dir}`));
13600
+ if (!isClean(result)) process.exitCode = 1;
13601
+ });
13602
+ }
13603
+
13604
+ // src/commands/requirements.ts
13605
+ import { join as join8, resolve as resolve5 } from "node:path";
13606
+ function register5(program2) {
13607
+ program2.command("requirements").description("lint the standard's map and module pages, or extract one module's requirement lines").argument("[dir]", "a checkout of the compendium", ".").option("--extract <page>", "print a module page's requirement lines instead of linting (path relative to dir)").action(async (dir, opts, command) => {
13608
+ const ctx = contextOf2(command);
13609
+ const compendium = resolve5(dir);
13610
+ if (opts.extract) {
13611
+ ctx.result(extractRequirements(await ctx.readFile(join8(compendium, opts.extract))));
13612
+ return;
13613
+ }
13614
+ const check = await checkCompendium(ctx, compendium);
13615
+ ctx.result(check, renderCheck);
13616
+ if (check.defects.length > 0) process.exitCode = 1;
13617
+ });
13618
+ }
13619
+ function renderCheck(c) {
13620
+ if (c.defects.length > 0) return c.defects.join("\n");
13621
+ return `\u2713 the map, ${c.contracts} contracts and ${c.approaches} approaches are well-formed`;
13622
+ }
13623
+
12790
13624
  // src/commands/index.ts
12791
- var commands = [register];
13625
+ var commands = [register2, register, register3, register4, register5];
12792
13626
 
12793
13627
  // src/program.ts
12794
13628
  var { version, description } = createRequire(import.meta.url)("../package.json");
@@ -12797,10 +13631,10 @@ function buildProgram() {
12797
13631
  program2.addOption(new Option("-n, --dry-run", "print every effect this run would have, perform none").env("PLX_DRY_RUN")).addOption(
12798
13632
  new Option("-v, --verbose", "say more: once for reads and inputs, twice for command output").argParser((_value, previous) => previous + 1).default(0)
12799
13633
  ).addOption(new Option("-q, --quiet", "say nothing but results and errors").env("PLX_QUIET")).addOption(new Option("-y, --yes", "answer every confirmation with yes (needed off a terminal)").env("PLX_YES")).addOption(new Option("--json", "print results as JSON").env("PLX_JSON"));
12800
- for (const register2 of commands) register2(program2);
13634
+ for (const register6 of commands) register6(program2);
12801
13635
  return program2;
12802
13636
  }
12803
- function contextOf(command) {
13637
+ function contextOf2(command) {
12804
13638
  const opts = command.optsWithGlobals();
12805
13639
  return new Context(
12806
13640
  opts,
@@ -12815,5 +13649,5 @@ try {
12815
13649
  const message = error instanceof Error ? error.message : String(error);
12816
13650
  process.stderr.write(`\u2717 ${message}
12817
13651
  `);
12818
- process.exitCode = 1;
13652
+ process.exitCode = error instanceof UsageError ? 2 : 1;
12819
13653
  }