@mutmutco/cli 3.128.0 → 3.130.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.cjs +52 -168
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -16037,10 +16037,10 @@ var rollout_plan_default = {
|
|
|
16037
16037
|
note: "The v4.0.0 stamp happens at cut time (D6e #4463); until then the candidate is the origin/development head artifacts (built cli/dist + npm pack), identity proven by dist content hash (D6a)."
|
|
16038
16038
|
},
|
|
16039
16039
|
baseline: {
|
|
16040
|
-
version: "3.
|
|
16041
|
-
tag: "v3.
|
|
16042
|
-
commit: "
|
|
16043
|
-
npm: "@mutmutco/cli@3.
|
|
16040
|
+
version: "3.130.0",
|
|
16041
|
+
tag: "v3.130.0",
|
|
16042
|
+
commit: "4092383c82be",
|
|
16043
|
+
npm: "@mutmutco/cli@3.130.0"
|
|
16044
16044
|
},
|
|
16045
16045
|
exitCriterion: "fleet-n-of-n",
|
|
16046
16046
|
hubOnlyShortcut: "forbidden",
|
|
@@ -16057,14 +16057,14 @@ var rollout_plan_default = {
|
|
|
16057
16057
|
repo: "mutmutco/mmi-hub",
|
|
16058
16058
|
role: "canary",
|
|
16059
16059
|
schedule: "train",
|
|
16060
|
-
v3Target: "v3.
|
|
16060
|
+
v3Target: "v3.130.0"
|
|
16061
16061
|
}
|
|
16062
16062
|
],
|
|
16063
16063
|
rollbackTrigger: "Any red inside the post-cut soak window: `devops train gate` FAIL attributable to the v4 doors, Hub endpoint health probe failure, a v3 client refused while the compat window must still admit it (SUPPORTED_MINOR_WINDOW=2, MIN_CLIENT_VERSION 0.0.0 \u2014 D6a), or npm consumer install/doctor failure on the v4 dist.",
|
|
16064
16064
|
rollback: {
|
|
16065
16065
|
independent: true,
|
|
16066
|
-
mechanism: "npm dist-tag latest -> 3.
|
|
16067
|
-
v3Target: "v3.
|
|
16066
|
+
mechanism: "npm dist-tag latest -> 3.130.0 and redeploy the Hub Lambda from tag v3.130.0 (4092383c82be); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
16067
|
+
v3Target: "v3.130.0 (@mutmutco/cli@3.130.0, tag commit 4092383c82be \u2014 the preserved latest-v3 distribution, D6b)"
|
|
16068
16068
|
}
|
|
16069
16069
|
},
|
|
16070
16070
|
{
|
|
@@ -16253,7 +16253,7 @@ function formatTrainStatus(r) {
|
|
|
16253
16253
|
"",
|
|
16254
16254
|
`release track: ${r.releaseTrack} \u2014 stages: ${r.branches.join(" -> ")}`,
|
|
16255
16255
|
`cli version: ${r.cliVersion}${r.repoVersion ? ` (repo: ${r.repoVersion})` : ""}${r.releasedVersion ? ` (released: ${r.releasedVersion})` : ""}`,
|
|
16256
|
-
`release bump intent: ${r.bumpIntent ?? "not declared \u2014 set MMI_BUMP_INTENT=major|minor
|
|
16256
|
+
`release bump intent: ${r.bumpIntent ?? "not declared \u2014 an ordinary train defaults to patch (#4929); set MMI_BUMP_INTENT=major|minor to override"}`
|
|
16257
16257
|
];
|
|
16258
16258
|
if (r.versionLag.ok) {
|
|
16259
16259
|
lines.push("version lag: none \u2014 CLI is current");
|
|
@@ -17065,7 +17065,7 @@ async function runIssueViewContext(deps, opts) {
|
|
|
17065
17065
|
}
|
|
17066
17066
|
async function runPrViewContext(deps, opts) {
|
|
17067
17067
|
let fields = opts.jsonFields;
|
|
17068
|
-
if (opts.comments || opts.context) fields = ensureField(fields, "comments");
|
|
17068
|
+
if (opts.comments || opts.context) fields = ensureField(ensureField(fields, "body"), "comments");
|
|
17069
17069
|
if (opts.context) fields = ensureField(fields, "closingIssuesReferences");
|
|
17070
17070
|
const base = await deps.ghJson(["pr", "view", String(opts.number), "--repo", opts.repo, "--json", fields], GH_LIST_TIMEOUT_MS);
|
|
17071
17071
|
if (!opts.context) return base;
|
|
@@ -20417,21 +20417,7 @@ async function resolveTrainBumpIntent(deps, env = process.env) {
|
|
|
20417
20417
|
}
|
|
20418
20418
|
return explicit.major > latest.major ? "major" : explicit.minor > latest.minor ? "minor" : "patch";
|
|
20419
20419
|
}
|
|
20420
|
-
|
|
20421
|
-
return requireValue(
|
|
20422
|
-
clean2(await deps.run("node", ["scripts/next-version.mjs", "intent"])),
|
|
20423
|
-
"release bump intent"
|
|
20424
|
-
);
|
|
20425
|
-
} catch (e) {
|
|
20426
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
20427
|
-
const usage = /usage: next-version\.mjs <([^>]+)>/.exec(message);
|
|
20428
|
-
if (usage && !usage[1].split("|").includes("intent")) {
|
|
20429
|
-
throw new Error(
|
|
20430
|
-
`release bump intent: this repo's seeded scripts/next-version.mjs predates the \`intent\` verb (its usage lists <${usage[1]}>), so unset-intent derivation cannot run here. Declare the intent explicitly and rerun \u2014 MMI_BUMP_INTENT=major|minor|patch (or MMI_RELEASE_VERSION=X.Y.Z for an exact target); the train then resolves it in the CLI without shelling this script. The durable fix is refreshing the seeded script from the Hub via seed propagation.`
|
|
20431
|
-
);
|
|
20432
|
-
}
|
|
20433
|
-
throw e;
|
|
20434
|
-
}
|
|
20420
|
+
return "patch";
|
|
20435
20421
|
}
|
|
20436
20422
|
async function runTrainApply(command, deps, options = {}) {
|
|
20437
20423
|
const watch = options.watch ?? false;
|
|
@@ -22817,9 +22803,6 @@ var BOARD_GIT_TIMEOUT_MS = 1e4;
|
|
|
22817
22803
|
var WRITE_PROBE_CONCURRENCY = 8;
|
|
22818
22804
|
var CLAIM_CONCURRENCY = 5;
|
|
22819
22805
|
var BOARD_ACTIVE_READ_MAX_PAGES = 100;
|
|
22820
|
-
var BOARD_PROJECTION_STALE_MS = 24 * 60 * 6e4;
|
|
22821
|
-
var BOARD_PROJECTION_RECONCILE_STALE_MS = 3 * 60 * 6e4;
|
|
22822
|
-
var BOARD_PROJECTION_TIMEOUT_MS = 8e3;
|
|
22823
22806
|
var execFileP4 = (file, args, options = {}) => (
|
|
22824
22807
|
// encoding 'utf8' guarantees string output at runtime; the cast pins the type (promisify's
|
|
22825
22808
|
// overloads widen to string|Buffer when options is spread in).
|
|
@@ -23087,7 +23070,7 @@ function renderBoardItem(item) {
|
|
|
23087
23070
|
return lines.join("\n");
|
|
23088
23071
|
}
|
|
23089
23072
|
function renderBoardReport(report) {
|
|
23090
|
-
const lines = [`Board \xB7 ${report.project.title} \xB7 @${report.viewer}`, renderBoardSource(
|
|
23073
|
+
const lines = [`Board \xB7 ${report.project.title} \xB7 @${report.viewer}`, renderBoardSource()];
|
|
23091
23074
|
renderScope(lines, "PRIMARY", report.repo, report.primary, report.viewer);
|
|
23092
23075
|
renderScope(lines, "SECONDARY", "Other repos on this project", report.secondary, report.viewer);
|
|
23093
23076
|
if (report.warnings.length) {
|
|
@@ -23191,132 +23174,13 @@ async function resolveWritableReposForClaimables(items, client) {
|
|
|
23191
23174
|
function writableOrUnknown(writable) {
|
|
23192
23175
|
return /* @__PURE__ */ new Set([...writable.repos, ...writable.unknown]);
|
|
23193
23176
|
}
|
|
23194
|
-
|
|
23195
|
-
|
|
23196
|
-
const token = await hubAuthToken({ baseUrl, githubToken });
|
|
23197
|
-
if (!token) throw new Error("no Hub session token");
|
|
23198
|
-
const url = new URL("/board-projection", `${baseUrl.replace(/\/$/, "")}/`);
|
|
23199
|
-
url.searchParams.set("owner", owner);
|
|
23200
|
-
url.searchParams.set("number", String(number));
|
|
23201
|
-
const res = await fetch(url, {
|
|
23202
|
-
method: "GET",
|
|
23203
|
-
headers: { ...clientVersionHeaders(), Authorization: `Bearer ${token}` },
|
|
23204
|
-
signal: AbortSignal.timeout(BOARD_PROJECTION_TIMEOUT_MS)
|
|
23205
|
-
});
|
|
23206
|
-
if (res.status === 404) return null;
|
|
23207
|
-
if (res.status === 426) throw new Error(upgradeRequiredError(res, await res.json().catch(() => null)));
|
|
23208
|
-
if (!res.ok) throw new Error(`board projection HTTP ${res.status}`);
|
|
23209
|
-
return await res.json();
|
|
23210
|
-
}
|
|
23211
|
-
function projectionItems(row) {
|
|
23212
|
-
if (!row.items || typeof row.items !== "object" || Array.isArray(row.items)) {
|
|
23213
|
-
throw new Error("malformed projection items");
|
|
23214
|
-
}
|
|
23215
|
-
const items = [];
|
|
23216
|
-
for (const raw of Object.values(row.items)) {
|
|
23217
|
-
if (!raw || typeof raw !== "object") throw new Error("malformed projection item");
|
|
23218
|
-
if (raw.tombstone === true) continue;
|
|
23219
|
-
const item = raw;
|
|
23220
|
-
if (typeof item.itemId !== "string" || typeof item.contentId !== "string" || item.contentType !== "Issue" && item.contentType !== "PullRequest" || typeof item.repository !== "string" || typeof item.number !== "number" || !Number.isFinite(item.number) || typeof item.ref !== "string" || typeof item.url !== "string" || typeof item.title !== "string" || typeof item.state !== "string" || !BOARD_STATUSES.includes(item.status) || !Array.isArray(item.assignees) || item.assignees.some((value) => typeof value !== "string") || !Array.isArray(item.labels) || item.labels.some((value) => typeof value !== "string") || typeof item.sourceTimestamp !== "string") {
|
|
23221
|
-
throw new Error("malformed projection item");
|
|
23222
|
-
}
|
|
23223
|
-
if (item.state.toUpperCase() === "CLOSED" || item.status === "Done") continue;
|
|
23224
|
-
items.push(withLoopState({
|
|
23225
|
-
itemId: item.itemId,
|
|
23226
|
-
contentId: item.contentId,
|
|
23227
|
-
contentType: item.contentType,
|
|
23228
|
-
repository: item.repository,
|
|
23229
|
-
number: item.number,
|
|
23230
|
-
ref: item.ref,
|
|
23231
|
-
url: item.url,
|
|
23232
|
-
title: item.title,
|
|
23233
|
-
state: item.state,
|
|
23234
|
-
// #4441: the reconciler stamps each item's content updatedAt as sourceTimestamp — the same
|
|
23235
|
-
// idle-age evidence the live read carries, so projection reads derive staleness too.
|
|
23236
|
-
updatedAt: item.sourceTimestamp,
|
|
23237
|
-
status: item.status,
|
|
23238
|
-
statusOptionId: item.statusOptionId,
|
|
23239
|
-
priority: item.priority,
|
|
23240
|
-
priorityOptionId: item.priorityOptionId,
|
|
23241
|
-
assignees: [...item.assignees],
|
|
23242
|
-
labels: [...item.labels],
|
|
23243
|
-
type: item.type
|
|
23244
|
-
}));
|
|
23245
|
-
}
|
|
23246
|
-
return items;
|
|
23247
|
-
}
|
|
23248
|
-
async function readViewerLogin(client) {
|
|
23249
|
-
const user = await client.rest("GET", "user");
|
|
23250
|
-
if (!user?.login) throw new Error("viewer login unavailable");
|
|
23251
|
-
return user.login;
|
|
23252
|
-
}
|
|
23253
|
-
function projectionFreshness(row, now) {
|
|
23254
|
-
const projectedAtMs = Date.parse(row.watermark?.projectedAt);
|
|
23255
|
-
const sourceTimestampMs = Date.parse(row.watermark?.sourceTimestamp);
|
|
23256
|
-
if (!Number.isFinite(projectedAtMs) || !Number.isFinite(sourceTimestampMs)) {
|
|
23257
|
-
throw new Error("malformed projection watermark");
|
|
23258
|
-
}
|
|
23259
|
-
const projectedAgeMs = Math.max(0, now - projectedAtMs);
|
|
23260
|
-
const sourceAgeMs = Math.max(0, now - sourceTimestampMs);
|
|
23261
|
-
return {
|
|
23262
|
-
projectedAt: row.watermark.projectedAt,
|
|
23263
|
-
projectedAgeMs,
|
|
23264
|
-
sourceTimestamp: row.watermark.sourceTimestamp,
|
|
23265
|
-
sourceAgeMs,
|
|
23266
|
-
// #4774: health must agree with BOTH ages a caller can see on the source line — a projection whose
|
|
23267
|
-
// rebuild (projectedAt) went stale is exactly as unreliable as one whose source events did, even
|
|
23268
|
-
// while recent webhook activity keeps sourceAgeMs looking fresh.
|
|
23269
|
-
health: row.watermark.health === "stale" || sourceAgeMs > BOARD_PROJECTION_STALE_MS || projectedAgeMs > BOARD_PROJECTION_RECONCILE_STALE_MS ? "stale" : "fresh"
|
|
23270
|
-
};
|
|
23271
|
-
}
|
|
23272
|
-
function renderBoardSource(report) {
|
|
23273
|
-
if (report.source === "projection" && report.freshness) {
|
|
23274
|
-
return `source: projection \xB7 projected ${formatClaimAge(report.freshness.projectedAgeMs)} ago \xB7 source events through ${report.freshness.sourceTimestamp} \xB7 health ${report.freshness.health}`;
|
|
23275
|
-
}
|
|
23276
|
-
return `source: live${report.sourceReason ? ` (${report.sourceReason})` : ""}`;
|
|
23177
|
+
function renderBoardSource() {
|
|
23178
|
+
return "source: live";
|
|
23277
23179
|
}
|
|
23278
23180
|
async function readBoard(options, deps = {}) {
|
|
23279
23181
|
const cfg = resolveBoardConfig(options.config);
|
|
23280
23182
|
const client = deps.client ?? defaultGitHubClient();
|
|
23281
|
-
|
|
23282
|
-
let source = "live";
|
|
23283
|
-
let freshness = null;
|
|
23284
|
-
let sourceReason;
|
|
23285
|
-
if (!options.live) {
|
|
23286
|
-
try {
|
|
23287
|
-
const baseUrl = options.config.sagaApiUrl;
|
|
23288
|
-
const row = await (deps.fetchProjection ?? defaultFetchBoardProjection)(cfg.projectOwner, cfg.projectNumber, baseUrl);
|
|
23289
|
-
if (!row) {
|
|
23290
|
-
sourceReason = "projection absent";
|
|
23291
|
-
} else if (row.schemaVersion !== 1) {
|
|
23292
|
-
sourceReason = `unsupported projection schema ${String(row.schemaVersion)}`;
|
|
23293
|
-
} else if (row.watermark?.health === "oversize") {
|
|
23294
|
-
sourceReason = "projection oversize";
|
|
23295
|
-
} else {
|
|
23296
|
-
const [viewer, repo] = await Promise.all([
|
|
23297
|
-
readViewerLogin(client),
|
|
23298
|
-
resolveCurrentRepo(options, deps)
|
|
23299
|
-
]);
|
|
23300
|
-
const now = (deps.now ?? Date.now)();
|
|
23301
|
-
collected = {
|
|
23302
|
-
items: projectionItems(row),
|
|
23303
|
-
viewer,
|
|
23304
|
-
repo,
|
|
23305
|
-
projectId: cfg.projectId,
|
|
23306
|
-
projectTitle: String(cfg.projectNumber),
|
|
23307
|
-
warnings: [],
|
|
23308
|
-
partial: false
|
|
23309
|
-
};
|
|
23310
|
-
freshness = projectionFreshness(row, now);
|
|
23311
|
-
source = "projection";
|
|
23312
|
-
}
|
|
23313
|
-
} catch {
|
|
23314
|
-
sourceReason = "projection read error";
|
|
23315
|
-
}
|
|
23316
|
-
}
|
|
23317
|
-
if (!collected) {
|
|
23318
|
-
collected = await collectBoardItems(cfg, { repo: options.repo, allowPartial: options.allowPartial, activeOnly: true }, deps);
|
|
23319
|
-
}
|
|
23183
|
+
const collected = await collectBoardItems(cfg, { repo: options.repo, allowPartial: options.allowPartial, activeOnly: true }, deps);
|
|
23320
23184
|
const writable = await resolveWritableReposForClaimables(collected.items, client);
|
|
23321
23185
|
collected.warnings.push(...writable.warnings);
|
|
23322
23186
|
collected.partial = collected.partial || writable.partial;
|
|
@@ -23328,9 +23192,7 @@ async function readBoard(options, deps = {}) {
|
|
|
23328
23192
|
...groups,
|
|
23329
23193
|
warnings: collected.warnings,
|
|
23330
23194
|
partial: collected.partial,
|
|
23331
|
-
source
|
|
23332
|
-
freshness,
|
|
23333
|
-
...sourceReason ? { sourceReason } : {}
|
|
23195
|
+
source: "live"
|
|
23334
23196
|
};
|
|
23335
23197
|
if (options.includeBundleDetails || options.includeAllBodies) {
|
|
23336
23198
|
await attachBundleDetails(report, client, options.allowPartial ?? false, { all: options.includeAllBodies });
|
|
@@ -32691,8 +32553,7 @@ function registerBoardCommands(program3) {
|
|
|
32691
32553
|
repo: o.repo,
|
|
32692
32554
|
includeBundleDetails: o.bundleDetails,
|
|
32693
32555
|
includeAllBodies: o.bodies,
|
|
32694
|
-
allowPartial: o.allowPartial
|
|
32695
|
-
live: o.live
|
|
32556
|
+
allowPartial: o.allowPartial
|
|
32696
32557
|
});
|
|
32697
32558
|
console.log(o.json ? JSON.stringify(report) : renderBoardReport(report));
|
|
32698
32559
|
} catch (e) {
|
|
@@ -32703,7 +32564,7 @@ function registerBoardCommands(program3) {
|
|
|
32703
32564
|
return alreadyClaimed ? `Check ${ref}: claimed and In Progress, no live contest - claim would renew the lease (nothing written)` : `Check ${ref}: free - claim would proceed (nothing written)`;
|
|
32704
32565
|
}
|
|
32705
32566
|
const board = program3.command("board").description("read, claim, show, and move Project v2 work items for the current repo");
|
|
32706
|
-
board.command("read", { isDefault: true }).description("read the board and print user-owned, claimable, and taken items").option("--json", "machine-readable output").option("--repo <owner/repo>", "current repo (defaults to git origin)").option("--bundle-details", "fetch body/comments only for user-owned and claimable issues").option("--bodies", "fetch body/comments for EVERY scoped row, including taken and unowned in-flight ones \u2014 for consumers that scope by Status rather than ownership (#4861); implies --bundle-details and costs one extra read per row").option("--allow-partial", "return partial board results when later page/detail reads fail").
|
|
32567
|
+
board.command("read", { isDefault: true }).description("read the board and print user-owned, claimable, and taken items").option("--json", "machine-readable output").option("--repo <owner/repo>", "current repo (defaults to git origin)").option("--bundle-details", "fetch body/comments only for user-owned and claimable issues").option("--bodies", "fetch body/comments for EVERY scoped row, including taken and unowned in-flight ones \u2014 for consumers that scope by Status rather than ownership (#4861); implies --bundle-details and costs one extra read per row").option("--allow-partial", "return partial board results when later page/detail reads fail").addHelpText("after", "\nread is always the authoritative live GitHub Project v2 board (#4926).\n--allow-partial applies to the paginated path and detail reads.\n").action((o) => runBoardRead(o));
|
|
32707
32568
|
withExamples(mutating(
|
|
32708
32569
|
board.command("claim <issues...>").description("claim issues: assign them and move their Project v2 Status to In Progress \u2014 idempotent, so an item already yours and In Progress succeeds unchanged (one or more refs)").option("--json", "machine-readable output").option("--repo <owner/repo>", "current repo for local issue numbers (defaults to git origin)").option("--for <login>", "assign to this login instead of @me \u2014 agent claims on behalf of the master").option("--force", "take an item already claimed by another lane that shows live evidence of active work (#3727)").option("--check", "read-only: run every claim gate and report the verdict, writing nothing \u2014 exits 1 with the same refusal a real claim would raise (#4511)").option("--allow-partial", "return success JSON if assignment succeeds but the status move fails"),
|
|
32709
32570
|
(_opts, args) => ({ command: "board claim", issues: args[0] ?? [] })
|
|
@@ -36286,12 +36147,8 @@ var LOOP_PLAYBOOKS = {
|
|
|
36286
36147
|
]
|
|
36287
36148
|
}
|
|
36288
36149
|
};
|
|
36289
|
-
function
|
|
36150
|
+
function formatOwnDetail(cmd) {
|
|
36290
36151
|
const lines = [];
|
|
36291
|
-
if (cmd.description) {
|
|
36292
|
-
lines.push(cmd.description);
|
|
36293
|
-
lines.push("");
|
|
36294
|
-
}
|
|
36295
36152
|
const args = cmd.arguments;
|
|
36296
36153
|
if (args.length) {
|
|
36297
36154
|
lines.push("Arguments:");
|
|
@@ -36302,10 +36159,10 @@ function formatExplainCommand(cmd, rootName) {
|
|
|
36302
36159
|
}
|
|
36303
36160
|
lines.push("");
|
|
36304
36161
|
}
|
|
36305
|
-
|
|
36162
|
+
const ownOptions = cmd.options.filter((opt) => opt.flags !== "--help" && opt.flags !== "-V, --version");
|
|
36163
|
+
if (ownOptions.length) {
|
|
36306
36164
|
lines.push("Options:");
|
|
36307
|
-
for (const opt of
|
|
36308
|
-
if (opt.flags === "--help" || opt.flags === "-V, --version") continue;
|
|
36165
|
+
for (const opt of ownOptions) {
|
|
36309
36166
|
const tags = [];
|
|
36310
36167
|
if (opt.mandatory) tags.push("required");
|
|
36311
36168
|
if (opt.default !== void 0) tags.push(`default: ${JSON.stringify(opt.default)}`);
|
|
@@ -36330,6 +36187,15 @@ function formatExplainCommand(cmd, rootName) {
|
|
|
36330
36187
|
}
|
|
36331
36188
|
lines.push("");
|
|
36332
36189
|
}
|
|
36190
|
+
return lines;
|
|
36191
|
+
}
|
|
36192
|
+
function formatExplainCommand(cmd, rootName) {
|
|
36193
|
+
const lines = [];
|
|
36194
|
+
if (cmd.description) {
|
|
36195
|
+
lines.push(cmd.description);
|
|
36196
|
+
lines.push("");
|
|
36197
|
+
}
|
|
36198
|
+
lines.push(...formatOwnDetail(cmd));
|
|
36333
36199
|
return lines.join("\n").trimEnd();
|
|
36334
36200
|
}
|
|
36335
36201
|
function formatExplainGroup(cmd, rootName) {
|
|
@@ -36337,9 +36203,10 @@ function formatExplainGroup(cmd, rootName) {
|
|
|
36337
36203
|
const lines = [
|
|
36338
36204
|
`${rootName} ${canonical(cmd)}${cmd.description ? ` \u2014 ${cmd.description}` : ""}`,
|
|
36339
36205
|
`Category: ${cmd.category} \xB7 Discovery: ${cmd.discovery}`,
|
|
36340
|
-
""
|
|
36341
|
-
"Commands:"
|
|
36206
|
+
""
|
|
36342
36207
|
];
|
|
36208
|
+
lines.push(...formatOwnDetail(cmd));
|
|
36209
|
+
lines.push("Commands:");
|
|
36343
36210
|
for (const child2 of cmd.subcommands) {
|
|
36344
36211
|
const args = child2.arguments.map((arg) => {
|
|
36345
36212
|
const name = arg.variadic ? `${arg.name}...` : arg.name;
|
|
@@ -43860,6 +43727,23 @@ installProcessBackstop();
|
|
|
43860
43727
|
consolidateCommandNamespaces(program2);
|
|
43861
43728
|
registerOrgHealthQuery(program2);
|
|
43862
43729
|
applyCommandTaxonomy(program2);
|
|
43730
|
+
function registeredPathPrefix(path2) {
|
|
43731
|
+
const tokens2 = path2.split(" ");
|
|
43732
|
+
let node = program2;
|
|
43733
|
+
let depth = 0;
|
|
43734
|
+
while (depth < tokens2.length) {
|
|
43735
|
+
const next = node.commands.find((c) => c.name() === tokens2[depth]);
|
|
43736
|
+
if (!next) break;
|
|
43737
|
+
node = next;
|
|
43738
|
+
depth += 1;
|
|
43739
|
+
}
|
|
43740
|
+
return tokens2.slice(0, Math.max(depth, 1)).join(" ");
|
|
43741
|
+
}
|
|
43742
|
+
function recoveryPointerFor(path2) {
|
|
43743
|
+
const runnable = registeredPathPrefix(path2);
|
|
43744
|
+
if (runnable === path2) return `run: mmi-cli ${canonicalPathFor(runnable)} \u2026`;
|
|
43745
|
+
return `'${path2}' is not a registered command \u2014 run \`mmi-cli ${canonicalPathFor(runnable)} --help\` for what lives under it`;
|
|
43746
|
+
}
|
|
43863
43747
|
function resolveHouseShim(argv) {
|
|
43864
43748
|
const houseToken = argv[2];
|
|
43865
43749
|
if (!houseToken) return;
|
|
@@ -43869,7 +43753,7 @@ function resolveHouseShim(argv) {
|
|
|
43869
43753
|
const flatHouse = houseForPath(flatPath);
|
|
43870
43754
|
if (!flatHouse || flatHouse === "core") return;
|
|
43871
43755
|
process.stderr.write(
|
|
43872
|
-
`mmi-cli: the flat '${flatPath}' alias was removed in ${COMPAT_SHIM_DEATH_WAVE} (#4316) \u2014
|
|
43756
|
+
`mmi-cli: the flat '${flatPath}' alias was removed in ${COMPAT_SHIM_DEATH_WAVE} (#4316) \u2014 ${recoveryPointerFor(flatPath)}
|
|
43873
43757
|
`
|
|
43874
43758
|
);
|
|
43875
43759
|
hardExit(2);
|
|
@@ -43893,7 +43777,7 @@ function resolveHouseShim(argv) {
|
|
|
43893
43777
|
}
|
|
43894
43778
|
if (actual) {
|
|
43895
43779
|
process.stderr.write(
|
|
43896
|
-
`mmi-cli ${houseToken}: '${lookupPath}' lives in house '${actual}' \u2014
|
|
43780
|
+
`mmi-cli ${houseToken}: '${lookupPath}' lives in house '${actual}' \u2014 ${recoveryPointerFor(lookupPath)}
|
|
43897
43781
|
`
|
|
43898
43782
|
);
|
|
43899
43783
|
} else {
|
package/package.json
CHANGED