@mutmutco/cli 4.1.1 → 4.1.2

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 (2) hide show
  1. package/dist/main.cjs +99 -19
  2. package/package.json +1 -1
package/dist/main.cjs CHANGED
@@ -2306,7 +2306,8 @@ __export(index_exports, {
2306
2306
  positionalTargetForm: () => positionalTargetForm,
2307
2307
  registryClientDeps: () => registryClientDeps,
2308
2308
  repoSlug: () => repoSlug,
2309
- suggestCommandPath: () => suggestCommandPath
2309
+ suggestCommandPath: () => suggestCommandPath,
2310
+ unknownCommandCandidates: () => unknownCommandCandidates
2310
2311
  });
2311
2312
  module.exports = __toCommonJS(index_exports);
2312
2313
 
@@ -12867,10 +12868,10 @@ var rollout_plan_default = {
12867
12868
  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)."
12868
12869
  },
12869
12870
  baseline: {
12870
- version: "4.1.1",
12871
- tag: "v4.1.1",
12872
- commit: "df9ba86cbdba",
12873
- npm: "@mutmutco/cli@4.1.1"
12871
+ version: "4.1.2",
12872
+ tag: "v4.1.2",
12873
+ commit: "bb1a56a57cda",
12874
+ npm: "@mutmutco/cli@4.1.2"
12874
12875
  },
12875
12876
  exitCriterion: "fleet-n-of-n",
12876
12877
  hubOnlyShortcut: "forbidden",
@@ -12887,14 +12888,14 @@ var rollout_plan_default = {
12887
12888
  repo: "mutmutco/mmi-hub",
12888
12889
  role: "canary",
12889
12890
  schedule: "train",
12890
- v3Target: "v4.1.1"
12891
+ v3Target: "v4.1.2"
12891
12892
  }
12892
12893
  ],
12893
12894
  rollbackTrigger: "Any red inside the post-contract soak window: `devops train gate` FAIL attributable to the v4 doors, Hub endpoint health probe failure, a pre-v4 client admitted instead of receiving actionable HTTP 426, or npm consumer install/doctor failure on the v4-only dist.",
12894
12895
  rollback: {
12895
12896
  independent: true,
12896
- mechanism: "npm dist-tag latest -> 4.1.1 and redeploy the Hub Lambda from tag v4.1.1 (df9ba86cbdba); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
12897
- v3Target: "v4.1.1 (@mutmutco/cli@4.1.1, tag commit df9ba86cbdba \u2014 last known-good release carrying the repo-index v4-only contract)"
12897
+ mechanism: "npm dist-tag latest -> 4.1.2 and redeploy the Hub Lambda from tag v4.1.2 (bb1a56a57cda); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
12898
+ v3Target: "v4.1.2 (@mutmutco/cli@4.1.2, tag commit bb1a56a57cda \u2014 last known-good release carrying the repo-index v4-only contract)"
12898
12899
  }
12899
12900
  },
12900
12901
  {
@@ -25946,8 +25947,9 @@ function verifiedReadyBase(statusValue, repo) {
25946
25947
  if (!v4 || typeof v4 !== "object" || Array.isArray(v4)) return null;
25947
25948
  const pointer = v4;
25948
25949
  const artifactDigests = pointer.artifactDigests;
25950
+ const expectedArtifactDigests = pointer.materialLayout === 2 ? 1 : pointer.materialLayout === void 0 || pointer.materialLayout === 1 ? 2 : 0;
25949
25951
  const counts = [pointer.chunkCount, pointer.embeddingCount, pointer.tombstoneCount];
25950
- const structurallyVerified = status.repo === repo && pointer.repo === repo && pointer.state === "ready" && pointer.integrity === "verified" && typeof pointer.commit === "string" && COMMIT3.test(pointer.commit) && typeof pointer.digest === "string" && SHA256.test(pointer.digest) && Array.isArray(artifactDigests) && artifactDigests.length === 2 && new Set(artifactDigests).size === artifactDigests.length && artifactDigests.every((digest) => typeof digest === "string" && SHA256.test(digest)) && counts.every((count) => Number.isInteger(count) && Number(count) >= 0) && pointer.embeddingCount === pointer.chunkCount && typeof pointer.activatedAt === "string" && UTC_MILLIS.test(pointer.activatedAt) && Number.isFinite(Date.parse(pointer.activatedAt)) && new Date(pointer.activatedAt).toISOString() === pointer.activatedAt;
25952
+ const structurallyVerified = status.repo === repo && pointer.repo === repo && pointer.state === "ready" && pointer.integrity === "verified" && typeof pointer.commit === "string" && COMMIT3.test(pointer.commit) && typeof pointer.digest === "string" && SHA256.test(pointer.digest) && Array.isArray(artifactDigests) && artifactDigests.length === expectedArtifactDigests && new Set(artifactDigests).size === artifactDigests.length && artifactDigests.every((digest) => typeof digest === "string" && SHA256.test(digest)) && counts.every((count) => Number.isInteger(count) && Number(count) >= 0) && pointer.embeddingCount === pointer.chunkCount && typeof pointer.activatedAt === "string" && UTC_MILLIS.test(pointer.activatedAt) && Number.isFinite(Date.parse(pointer.activatedAt)) && new Date(pointer.activatedAt).toISOString() === pointer.activatedAt;
25951
25953
  return structurallyVerified && typeof pointer.commit === "string" && typeof pointer.digest === "string" ? { commit: pointer.commit, digest: pointer.digest } : null;
25952
25954
  }
25953
25955
  function activePointerDigest(statusValue) {
@@ -34448,15 +34450,68 @@ function formatExplainLoop(playbook) {
34448
34450
  }
34449
34451
  return lines.join("\n");
34450
34452
  }
34451
- function explainCommandManifest(manifest, command) {
34452
- return {
34453
+ function catalogCommandPaths(manifest) {
34454
+ const acc = [];
34455
+ const walk2 = (command) => {
34456
+ if (command.path) acc.push(command.path);
34457
+ for (const child2 of command.subcommands) walk2(child2);
34458
+ };
34459
+ walk2(manifest.tree);
34460
+ return acc;
34461
+ }
34462
+ function nearestExplainTargets(query, paths, limit = 5) {
34463
+ const all = [...paths];
34464
+ const leafOf = (p) => p.slice(p.lastIndexOf(" ") + 1);
34465
+ const leaf = leafOf(query);
34466
+ const exactLeaf = all.filter((p) => p !== query && leafOf(p) === leaf).sort();
34467
+ if (exactLeaf.length) return exactLeaf.slice(0, limit);
34468
+ const out = [];
34469
+ const nearPath = didYouMean(query, all);
34470
+ if (nearPath) out.push(nearPath);
34471
+ const nearLeaf = didYouMean(leaf, new Set(all.map(leafOf)));
34472
+ if (nearLeaf) {
34473
+ for (const p of all.filter((candidate2) => leafOf(candidate2) === nearLeaf).sort()) {
34474
+ if (!out.includes(p)) out.push(p);
34475
+ if (out.length >= limit) break;
34476
+ }
34477
+ }
34478
+ return out.slice(0, limit);
34479
+ }
34480
+ function explainCommandManifest(manifest, command, opts = {}) {
34481
+ const base = {
34453
34482
  schema_version: 1,
34454
34483
  scope: "command",
34455
34484
  name: manifest.name,
34456
- ...manifest.version ? { version: manifest.version } : {},
34485
+ ...manifest.version ? { version: manifest.version } : {}
34486
+ };
34487
+ if (!command.subcommands.length) {
34488
+ return {
34489
+ ...base,
34490
+ command: { ...command, subcommands: [] }
34491
+ };
34492
+ }
34493
+ if (opts.recursive) {
34494
+ return {
34495
+ ...base,
34496
+ command: {
34497
+ ...command,
34498
+ subcommands: command.subcommands.map((child2) => ({ ...child2, subcommands: [] }))
34499
+ }
34500
+ };
34501
+ }
34502
+ return {
34503
+ ...base,
34457
34504
  command: {
34458
34505
  ...command,
34459
- subcommands: command.subcommands.map((child2) => ({ ...child2, subcommands: [] }))
34506
+ subcommands: []
34507
+ },
34508
+ children: command.subcommands.map((child2) => ({
34509
+ path: child2.path,
34510
+ ...child2.description ? { summary: child2.description } : {},
34511
+ detail: `mmi-cli explain ${child2.path} --json`
34512
+ })),
34513
+ next: {
34514
+ recursive: `mmi-cli explain ${command.path} --json --recursive`
34460
34515
  }
34461
34516
  };
34462
34517
  }
@@ -34472,7 +34527,7 @@ function findCommandInManifest(manifest, commandPath3) {
34472
34527
  return visit(manifest.tree);
34473
34528
  }
34474
34529
  function registerExplainCommand(program3) {
34475
- program3.command("explain").description("print a command's purpose, flags, and examples from the live schema \u2014 one grounding call replaces trial-and-error").argument("[command...]", 'the command path to explain (e.g. "issue create")').addOption(new Option("--loop <name>", "print the canonical command sequence: agent | start-work | ship-pr | hotfix").choices(Object.keys(LOOP_PLAYBOOKS))).option("--json", "machine-readable focused command, route, or loop detail").action((commandArgs, opts) => {
34530
+ program3.command("explain").description("print a command's purpose, flags, and examples from the live schema \u2014 one grounding call replaces trial-and-error").argument("[command...]", 'the command path to explain (e.g. "issue create")').addOption(new Option("--loop <name>", "print the canonical command sequence: agent | start-work | ship-pr | hotfix").choices(Object.keys(LOOP_PLAYBOOKS))).option("--json", "machine-readable focused command, route, or loop detail").option("--recursive", "include full schemas for immediate children (default: compact child index)").option("--full", "alias for --recursive").action((commandArgs, opts) => {
34476
34531
  if (opts.loop) {
34477
34532
  if (!LOOP_PLAYBOOKS[opts.loop]) {
34478
34533
  const valid = Object.keys(LOOP_PLAYBOOKS).join(", ");
@@ -34490,10 +34545,19 @@ function registerExplainCommand(program3) {
34490
34545
  const commandPath3 = commandArgs.join(" ");
34491
34546
  const command = findCommandInManifest(manifest, commandPath3);
34492
34547
  if (!command) {
34493
- fail(`explain: unknown command "${commandPath3}"`, { code: ERROR_CODES.ERR_NOT_FOUND });
34548
+ const nearest = nearestExplainTargets(commandPath3, catalogCommandPaths(manifest));
34549
+ fail(`explain: unknown command "${commandPath3}"`, {
34550
+ code: ERROR_CODES.ERR_NOT_FOUND,
34551
+ ...nearest.length ? {
34552
+ expected: nearest,
34553
+ did_you_mean: nearest[0],
34554
+ corrected_command: `mmi-cli explain ${nearest[0]} --json`
34555
+ } : {}
34556
+ });
34494
34557
  return;
34495
34558
  }
34496
- console.log(opts.json ? JSON.stringify(explainCommandManifest(manifest, command), null, 2) : command.subcommands.length ? formatExplainGroup(command, manifest.name) : formatExplainCommand(command, manifest.name));
34559
+ const recursive = Boolean(opts.recursive || opts.full);
34560
+ console.log(opts.json ? JSON.stringify(explainCommandManifest(manifest, command, { recursive }), null, 2) : command.subcommands.length ? formatExplainGroup(command, manifest.name) : formatExplainCommand(command, manifest.name));
34497
34561
  });
34498
34562
  }
34499
34563
 
@@ -38932,13 +38996,28 @@ function positionalTargetForm(cmd, opts = {}) {
38932
38996
  if (!first) return void 0;
38933
38997
  return formatPositionalTarget(canonicalPathFor(commandPath2(cmd)) ?? commandPath2(cmd), first.name(), opts);
38934
38998
  }
38999
+ function unknownCommandCandidates(parent, allPaths) {
39000
+ if (!parent) return [...allPaths];
39001
+ const scoped = parent.commands.length ? parent.commands.filter((child2) => commandMetadata(child2)?.category !== "internal").map(commandPath2) : [];
39002
+ const house = houseForPath(commandPath2(parent));
39003
+ const sameHouse = house ? allPaths.filter((p) => houseForPath(p) === house) : [...allPaths];
39004
+ const seen = /* @__PURE__ */ new Set();
39005
+ const out = [];
39006
+ for (const p of [...scoped, ...sameHouse]) {
39007
+ if (seen.has(p)) continue;
39008
+ seen.add(p);
39009
+ out.push(p);
39010
+ }
39011
+ return out;
39012
+ }
38935
39013
  function resolveParseHint() {
38936
39014
  if (lastParseErrorKind === "unknown-command") {
38937
39015
  const parent = resolveCommandFromArgv(program2, process.argv.slice(2));
38938
- const candidates = parent && parent.commands.length ? parent.commands.filter((child2) => commandMetadata(child2)?.category !== "internal").map(commandPath2) : allCommandPaths();
39016
+ const candidates = unknownCommandCandidates(parent, allCommandPaths());
38939
39017
  const path3 = lastUnknownCommand ? suggestCommandPath(lastUnknownCommand, candidates) : void 0;
38940
39018
  const canonical = path3 ? canonicalPathFor(path3) ?? path3 : void 0;
38941
- return canonical ? `(did you mean \`mmi-cli ${canonical}\`? ${DISCOVERY_HINT})` : STALE_HINT;
39019
+ if (canonical) return `(did you mean \`mmi-cli ${canonical}\`? ${DISCOVERY_HINT})`;
39020
+ return parent ? `(${DISCOVERY_HINT})` : STALE_HINT;
38942
39021
  }
38943
39022
  if (lastParseErrorKind !== "bad-arguments") return STALE_HINT;
38944
39023
  const cmd = resolveCommandFromArgv(program2, process.argv.slice(2));
@@ -42085,5 +42164,6 @@ program2.parseAsync(process.argv).then(() => finishCliRun()).catch((e) => failGr
42085
42164
  positionalTargetForm,
42086
42165
  registryClientDeps,
42087
42166
  repoSlug,
42088
- suggestCommandPath
42167
+ suggestCommandPath,
42168
+ unknownCommandCandidates
42089
42169
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "4.1.1",
3
+ "version": "4.1.2",
4
4
  "description": "MMI Future CLI — the org dev toolbox and shared cross-IDE engine for every registry-declared MMI coding surface.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",