@mutmutco/cli 4.4.5 → 4.4.6
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 +194 -48
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -7288,37 +7288,71 @@ function pathWords(text) {
|
|
|
7288
7288
|
function proseWords(text) {
|
|
7289
7289
|
return text.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
|
|
7290
7290
|
}
|
|
7291
|
+
function countWords(words) {
|
|
7292
|
+
const counts = /* @__PURE__ */ new Map();
|
|
7293
|
+
for (const w of words) counts.set(w, (counts.get(w) ?? 0) + 1);
|
|
7294
|
+
return counts;
|
|
7295
|
+
}
|
|
7296
|
+
var TITLE_WEIGHT = 3;
|
|
7297
|
+
var PATH_WEIGHT = 4;
|
|
7298
|
+
var BODY_WEIGHT = 1;
|
|
7291
7299
|
function inferSurface(candidates, context = {}) {
|
|
7292
7300
|
const sorted = [...candidates].sort();
|
|
7293
7301
|
if (sorted.length === 0) throw new Error("inferSurface: no surface:* candidates to choose from");
|
|
7294
|
-
const
|
|
7295
|
-
const
|
|
7302
|
+
const titleCounts = countWords(proseWords([context.title ?? "", context.type ?? ""].join(" ")));
|
|
7303
|
+
const pathCounts = countWords(pathWords(context.body ?? ""));
|
|
7304
|
+
const bodyCounts = countWords(proseWords(context.body ?? ""));
|
|
7305
|
+
const scoreOf = (label) => {
|
|
7306
|
+
let score = 0;
|
|
7307
|
+
let fromPath = false;
|
|
7308
|
+
let fromTitle = false;
|
|
7309
|
+
for (const word of surfaceWords(label)) {
|
|
7310
|
+
const title = titleCounts.get(word) ?? 0;
|
|
7311
|
+
const path2 = pathCounts.get(word) ?? 0;
|
|
7312
|
+
const body = bodyCounts.get(word) ?? 0;
|
|
7313
|
+
if (title > 0) fromTitle = true;
|
|
7314
|
+
if (path2 > 0) fromPath = true;
|
|
7315
|
+
score += title * TITLE_WEIGHT + path2 * PATH_WEIGHT + body * BODY_WEIGHT;
|
|
7316
|
+
}
|
|
7317
|
+
return { score, fromPath, fromTitle };
|
|
7318
|
+
};
|
|
7296
7319
|
let best = sorted[0];
|
|
7297
7320
|
let bestScore = 0;
|
|
7298
7321
|
let bestFromPath = false;
|
|
7322
|
+
let bestFromTitle = false;
|
|
7323
|
+
const scores = /* @__PURE__ */ new Map();
|
|
7299
7324
|
for (const label of sorted) {
|
|
7300
|
-
const
|
|
7301
|
-
|
|
7302
|
-
const pathHits = words.filter((w) => pWords.has(w)).length;
|
|
7303
|
-
const proseHits = words.filter((w) => tWords.has(w)).length;
|
|
7304
|
-
const score = pathHits * 2 + proseHits;
|
|
7325
|
+
const { score, fromPath, fromTitle } = scoreOf(label);
|
|
7326
|
+
scores.set(label, score);
|
|
7305
7327
|
if (score > bestScore) {
|
|
7306
7328
|
bestScore = score;
|
|
7307
7329
|
best = label;
|
|
7308
|
-
bestFromPath =
|
|
7330
|
+
bestFromPath = fromPath;
|
|
7331
|
+
bestFromTitle = fromTitle;
|
|
7309
7332
|
}
|
|
7310
7333
|
}
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
};
|
|
7316
|
-
}
|
|
7334
|
+
const tied = sorted.filter((label) => (scores.get(label) ?? 0) === bestScore);
|
|
7335
|
+
const uncertain = bestScore === 0 || bestScore < TITLE_WEIGHT || tied.length > 1;
|
|
7336
|
+
const alternatives = uncertain ? sorted.filter((label) => label !== best && (scores.get(label) ?? 0) > 0).sort((a, b) => (scores.get(b) ?? 0) - (scores.get(a) ?? 0) || (a < b ? -1 : a > b ? 1 : 0)).slice(0, 3) : [];
|
|
7337
|
+
const reason = bestScore === 0 ? `no path or title/body word matched any of ${sorted.length} surface label(s) \u2014 defaulted to the alphabetically-first` : bestFromPath ? "matched a path mentioned in the issue body" : bestFromTitle ? "matched a word in the issue title/body" : "matched a word in the issue body";
|
|
7317
7338
|
return {
|
|
7318
7339
|
label: best,
|
|
7319
|
-
reason
|
|
7340
|
+
reason,
|
|
7341
|
+
...uncertain ? { uncertain: true } : {},
|
|
7342
|
+
...alternatives.length ? { alternatives } : {}
|
|
7320
7343
|
};
|
|
7321
7344
|
}
|
|
7345
|
+
function surfaceInferenceSuffix(inferred) {
|
|
7346
|
+
if (!inferred.uncertain) return "";
|
|
7347
|
+
const alts = inferred.alternatives?.length ? ` Other candidates: ${inferred.alternatives.join(", ")}.` : "";
|
|
7348
|
+
return ` This pick is low-confidence \u2014 pass --surface <value> to choose explicitly.${alts}`;
|
|
7349
|
+
}
|
|
7350
|
+
function surfaceInferenceNote(inferred) {
|
|
7351
|
+
const base = `mmi-cli: no --surface given \u2014 filed under ${inferred.label} (${inferred.reason}).`;
|
|
7352
|
+
return inferred.uncertain ? `${base}${surfaceInferenceSuffix(inferred)}
|
|
7353
|
+
` : `${base} Pass --surface to choose.
|
|
7354
|
+
`;
|
|
7355
|
+
}
|
|
7322
7356
|
async function checkSurfaceRequirement(input, deps = {}) {
|
|
7323
7357
|
if (input.waiver) {
|
|
7324
7358
|
const reason = input.waiver.reason.trim();
|
|
@@ -7350,7 +7384,7 @@ async function checkSurfaceRequirement(input, deps = {}) {
|
|
|
7350
7384
|
}
|
|
7351
7385
|
if (known.length === 0) return { enforcing: false, taxonomyAbsent: true };
|
|
7352
7386
|
if (labelsCarrySurface(input.labels)) return { enforcing: true };
|
|
7353
|
-
return { enforcing: true, inferred: inferSurface(known, { title: input.title, body: input.body }) };
|
|
7387
|
+
return { enforcing: true, inferred: inferSurface(known, { title: input.title, type: input.type, body: input.body }) };
|
|
7354
7388
|
}
|
|
7355
7389
|
function conflictingSurfaceInputs(surfaceFlag, labels) {
|
|
7356
7390
|
if (!surfaceFlag) return void 0;
|
|
@@ -15870,10 +15904,10 @@ var rollout_plan_default = {
|
|
|
15870
15904
|
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)."
|
|
15871
15905
|
},
|
|
15872
15906
|
baseline: {
|
|
15873
|
-
version: "4.4.
|
|
15874
|
-
tag: "v4.4.
|
|
15875
|
-
commit: "
|
|
15876
|
-
npm: "@mutmutco/cli@4.4.
|
|
15907
|
+
version: "4.4.6",
|
|
15908
|
+
tag: "v4.4.6",
|
|
15909
|
+
commit: "640e312fac88",
|
|
15910
|
+
npm: "@mutmutco/cli@4.4.6"
|
|
15877
15911
|
},
|
|
15878
15912
|
exitCriterion: "fleet-n-of-n",
|
|
15879
15913
|
hubOnlyShortcut: "forbidden",
|
|
@@ -15890,14 +15924,14 @@ var rollout_plan_default = {
|
|
|
15890
15924
|
repo: "mutmutco/mmi-hub",
|
|
15891
15925
|
role: "canary",
|
|
15892
15926
|
schedule: "train",
|
|
15893
|
-
v3Target: "v4.4.
|
|
15927
|
+
v3Target: "v4.4.6"
|
|
15894
15928
|
}
|
|
15895
15929
|
],
|
|
15896
15930
|
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.",
|
|
15897
15931
|
rollback: {
|
|
15898
15932
|
independent: true,
|
|
15899
|
-
mechanism: "npm dist-tag latest -> 4.4.
|
|
15900
|
-
v3Target: "v4.4.
|
|
15933
|
+
mechanism: "npm dist-tag latest -> 4.4.6 and redeploy the Hub Lambda from tag v4.4.6 (640e312fac88); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
15934
|
+
v3Target: "v4.4.6 (@mutmutco/cli@4.4.6, tag commit 640e312fac88 \u2014 last known-good release carrying the repo-index v4-only contract)"
|
|
15901
15935
|
}
|
|
15902
15936
|
},
|
|
15903
15937
|
{
|
|
@@ -22814,6 +22848,62 @@ async function waitForFoldIndexLock(deps, startBranch, resumeCommand) {
|
|
|
22814
22848
|
await sleep2(Math.min(GIT_INDEX_LOCK_POLL_MS, Math.max(1, deadline - now())));
|
|
22815
22849
|
}
|
|
22816
22850
|
}
|
|
22851
|
+
function isIndexLockFailure(message2) {
|
|
22852
|
+
return /index\.lock/i.test(message2) && /File exists/i.test(message2);
|
|
22853
|
+
}
|
|
22854
|
+
async function clearFoldChildIndexLock(deps) {
|
|
22855
|
+
const lockPath = requireValue(
|
|
22856
|
+
clean2(await deps.run("git", ["rev-parse", "--git-path", "index.lock"])),
|
|
22857
|
+
"git index lock path"
|
|
22858
|
+
);
|
|
22859
|
+
try {
|
|
22860
|
+
await (0, import_promises3.unlink)(lockPath);
|
|
22861
|
+
} catch (e) {
|
|
22862
|
+
if (e.code === "ENOENT") return void 0;
|
|
22863
|
+
throw e;
|
|
22864
|
+
}
|
|
22865
|
+
return lockPath;
|
|
22866
|
+
}
|
|
22867
|
+
async function resetFoldMainWithStaleLockRetry(deps, preFoldMainSha, killedCause) {
|
|
22868
|
+
try {
|
|
22869
|
+
await deps.run("git", ["reset", "--hard", preFoldMainSha]);
|
|
22870
|
+
return { ok: true, lockNote: "" };
|
|
22871
|
+
} catch (firstError) {
|
|
22872
|
+
const firstMessage = firstError instanceof Error ? firstError.message : String(firstError);
|
|
22873
|
+
if (!isIndexLockFailure(firstMessage)) return { ok: false, error: firstError, lockNote: "" };
|
|
22874
|
+
if (!foldChildWasKilled(killedCause)) {
|
|
22875
|
+
return {
|
|
22876
|
+
ok: false,
|
|
22877
|
+
error: firstError,
|
|
22878
|
+
lockNote: "the git index lock was NOT removed \u2014 no killed fold child is attributable, so its holder may still be alive (resolve or wait it out, then retry)"
|
|
22879
|
+
};
|
|
22880
|
+
}
|
|
22881
|
+
let clearedLockPath;
|
|
22882
|
+
try {
|
|
22883
|
+
clearedLockPath = await clearFoldChildIndexLock(deps);
|
|
22884
|
+
} catch (e) {
|
|
22885
|
+
return {
|
|
22886
|
+
ok: false,
|
|
22887
|
+
error: firstError,
|
|
22888
|
+
lockNote: `the fold child's stale git index lock could not be removed: ${e instanceof Error ? e.message : String(e)}`
|
|
22889
|
+
};
|
|
22890
|
+
}
|
|
22891
|
+
if (!clearedLockPath) return { ok: false, error: firstError, lockNote: "" };
|
|
22892
|
+
try {
|
|
22893
|
+
await deps.run("git", ["reset", "--hard", preFoldMainSha]);
|
|
22894
|
+
return {
|
|
22895
|
+
ok: true,
|
|
22896
|
+
lockNote: `removed the stale git index lock ${clearedLockPath} left by the fold child the train killed (signal), then retried the reset`
|
|
22897
|
+
};
|
|
22898
|
+
} catch (retryError) {
|
|
22899
|
+
return {
|
|
22900
|
+
ok: false,
|
|
22901
|
+
error: retryError,
|
|
22902
|
+
lockNote: `removed the stale git index lock ${clearedLockPath} left by the fold child the train killed (signal) and retried the reset once, which failed again`
|
|
22903
|
+
};
|
|
22904
|
+
}
|
|
22905
|
+
}
|
|
22906
|
+
}
|
|
22817
22907
|
async function recoverFailedRcand(deps, cause, preRcSha) {
|
|
22818
22908
|
const causeMessage = cause instanceof Error ? cause.message : String(cause);
|
|
22819
22909
|
const branch = await currentBranch(deps).catch(() => "");
|
|
@@ -22857,10 +22947,13 @@ Recovery sequence:
|
|
|
22857
22947
|
3. mmi-cli devops rcand --apply`
|
|
22858
22948
|
);
|
|
22859
22949
|
}
|
|
22950
|
+
function foldChildWasKilled(causeMessage) {
|
|
22951
|
+
return /\bSIGTERM\b|was killed \(signal/.test(causeMessage);
|
|
22952
|
+
}
|
|
22860
22953
|
function foldFailureAnchor(causeMessage) {
|
|
22861
|
-
if (
|
|
22862
|
-
if (/\bEPERM\b|\bEBUSY\b/.test(causeMessage)) return "
|
|
22863
|
-
if (/^(?:npm|node) .* failed\b/.test(causeMessage)) return "
|
|
22954
|
+
if (foldChildWasKilled(causeMessage)) return troubleshootingAnchor("fold-npm-ci-sigterm");
|
|
22955
|
+
if (/\bEPERM\b|\bEBUSY\b/.test(causeMessage)) return troubleshootingAnchor("fold-eperm-ebusy");
|
|
22956
|
+
if (/^(?:npm|node) .* failed\b/.test(causeMessage)) return troubleshootingAnchor("fold-lifecycle-script");
|
|
22864
22957
|
return void 0;
|
|
22865
22958
|
}
|
|
22866
22959
|
async function recoverFailedFold(deps, cause, startBranch, preFoldMainSha, resumeCommand) {
|
|
@@ -22889,13 +22982,12 @@ fold failed with an in-progress merge; automatic \`git merge --abort\` failed: $
|
|
|
22889
22982
|
if (probe.branch === "main" && preFoldMainSha) {
|
|
22890
22983
|
const mainDescendsFromPreFold = await deps.run("git", ["merge-base", "--is-ancestor", preFoldMainSha, "main"]).then(() => true).catch(() => false);
|
|
22891
22984
|
if (mainDescendsFromPreFold) {
|
|
22892
|
-
|
|
22893
|
-
|
|
22894
|
-
} catch (e) {
|
|
22985
|
+
const attempt = await resetFoldMainWithStaleLockRetry(deps, preFoldMainSha, rawCause);
|
|
22986
|
+
if (!attempt.ok) {
|
|
22895
22987
|
return foldFailureGuidance(
|
|
22896
22988
|
`${causeMessage}
|
|
22897
22989
|
|
|
22898
|
-
fold failed after this run's merge/fold committed locally on main; automatic \`git reset --hard ${shaLabel(preFoldMainSha)}\` failed: ${
|
|
22990
|
+
fold failed after this run's merge/fold committed locally on main; automatic \`git reset --hard ${shaLabel(preFoldMainSha)}\` failed: ${attempt.error instanceof Error ? attempt.error.message : String(attempt.error)}${attempt.lockNote ? `; ${attempt.lockNote}` : ""}.`,
|
|
22899
22991
|
await probeFoldFailureState(deps),
|
|
22900
22992
|
startBranch,
|
|
22901
22993
|
preFoldMainSha,
|
|
@@ -22910,7 +23002,7 @@ fold failed after this run's merge/fold committed locally on main; automatic \`g
|
|
|
22910
23002
|
startBranch,
|
|
22911
23003
|
preFoldMainSha,
|
|
22912
23004
|
resumeCommand,
|
|
22913
|
-
`local main was reset to its pre-fold state ${shaLabel(preFoldMainSha)} (discarding only this run's merge/fold commit(s) at ${shaLabel(probe.mainSha)})${aheadNote}`
|
|
23005
|
+
`local main was reset to its pre-fold state ${shaLabel(preFoldMainSha)} (discarding only this run's merge/fold commit(s) at ${shaLabel(probe.mainSha)})${attempt.lockNote ? `; ${attempt.lockNote}` : ""}${aheadNote}`
|
|
22914
23006
|
);
|
|
22915
23007
|
}
|
|
22916
23008
|
}
|
|
@@ -33529,10 +33621,10 @@ function formatOwnDetail(cmd) {
|
|
|
33529
33621
|
}
|
|
33530
33622
|
lines2.push("");
|
|
33531
33623
|
}
|
|
33532
|
-
const
|
|
33533
|
-
if (
|
|
33624
|
+
const ownOptions2 = cmd.options.filter((opt) => opt.flags !== "--help" && opt.flags !== "-V, --version");
|
|
33625
|
+
if (ownOptions2.length) {
|
|
33534
33626
|
lines2.push("Options:");
|
|
33535
|
-
for (const opt of
|
|
33627
|
+
for (const opt of ownOptions2) {
|
|
33536
33628
|
const tags = [];
|
|
33537
33629
|
if (opt.mandatory) tags.push("required");
|
|
33538
33630
|
if (opt.default !== void 0) tags.push(`default: ${JSON.stringify(opt.default)}`);
|
|
@@ -33594,6 +33686,56 @@ function formatExplainLoop(playbook) {
|
|
|
33594
33686
|
}
|
|
33595
33687
|
return lines2.join("\n");
|
|
33596
33688
|
}
|
|
33689
|
+
function ownOptions(cmd) {
|
|
33690
|
+
return cmd.options.filter((opt) => opt.flags !== "--help" && opt.flags !== "-V, --version");
|
|
33691
|
+
}
|
|
33692
|
+
function briefCommand(cmd) {
|
|
33693
|
+
return {
|
|
33694
|
+
path: cmd.path,
|
|
33695
|
+
...cmd.description ? { description: cmd.description } : {},
|
|
33696
|
+
arguments: cmd.arguments.map((arg) => ({
|
|
33697
|
+
name: arg.name,
|
|
33698
|
+
required: arg.required,
|
|
33699
|
+
...arg.variadic ? { variadic: true } : {},
|
|
33700
|
+
...arg.description ? { description: arg.description } : {}
|
|
33701
|
+
})),
|
|
33702
|
+
options: ownOptions(cmd).map((opt) => ({
|
|
33703
|
+
flags: opt.flags,
|
|
33704
|
+
takesValue: opt.takesValue,
|
|
33705
|
+
...opt.mandatory ? { required: true } : {},
|
|
33706
|
+
...opt.description ? { description: opt.description } : {}
|
|
33707
|
+
}))
|
|
33708
|
+
};
|
|
33709
|
+
}
|
|
33710
|
+
function explainBriefManifest(manifest, command) {
|
|
33711
|
+
return {
|
|
33712
|
+
schema_version: 1,
|
|
33713
|
+
scope: "command",
|
|
33714
|
+
brief: true,
|
|
33715
|
+
name: manifest.name,
|
|
33716
|
+
...manifest.version ? { version: manifest.version } : {},
|
|
33717
|
+
command: briefCommand(command),
|
|
33718
|
+
...command.subcommands.length ? { children: command.subcommands.map(briefCommand) } : {}
|
|
33719
|
+
};
|
|
33720
|
+
}
|
|
33721
|
+
function formatExplainBrief(cmd, rootName) {
|
|
33722
|
+
const lines2 = [`${rootName} ${cmd.path}${cmd.description ? ` \u2014 ${cmd.description}` : ""}`];
|
|
33723
|
+
for (const arg of cmd.arguments) {
|
|
33724
|
+
const flag = arg.required ? `<${arg.name}>` : `[${arg.name}]`;
|
|
33725
|
+
lines2.push(` ${flag} ${arg.required ? "required" : "optional"}${arg.description ? ` ${arg.description}` : ""}`);
|
|
33726
|
+
}
|
|
33727
|
+
for (const opt of ownOptions(cmd)) {
|
|
33728
|
+
lines2.push(` ${opt.flags} ${opt.takesValue ? "takes-value" : "flag"}${opt.mandatory ? " required" : ""}${opt.description ? ` ${opt.description}` : ""}`);
|
|
33729
|
+
}
|
|
33730
|
+
for (const child2 of cmd.subcommands) {
|
|
33731
|
+
const args = child2.arguments.map((arg) => arg.required ? `<${arg.name}>` : `[${arg.name}]`).join(" ");
|
|
33732
|
+
lines2.push(`${child2.path}${args ? ` ${args}` : ""}${child2.description ? ` \u2014 ${child2.description}` : ""}`);
|
|
33733
|
+
for (const opt of ownOptions(child2)) {
|
|
33734
|
+
lines2.push(` ${opt.flags} ${opt.takesValue ? "takes-value" : "flag"}${opt.mandatory ? " required" : ""}${opt.description ? ` ${opt.description}` : ""}`);
|
|
33735
|
+
}
|
|
33736
|
+
}
|
|
33737
|
+
return lines2.join("\n");
|
|
33738
|
+
}
|
|
33597
33739
|
function catalogCommandPaths(manifest) {
|
|
33598
33740
|
const acc = [];
|
|
33599
33741
|
const walk2 = (command) => {
|
|
@@ -33728,7 +33870,7 @@ function findCommandInManifest(manifest, commandPath3) {
|
|
|
33728
33870
|
return visit(manifest.tree);
|
|
33729
33871
|
}
|
|
33730
33872
|
function registerExplainCommand(program3) {
|
|
33731
|
-
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("--out <path>", "write the output to a UTF-8 file instead of stdout (#5802 byte contract)").option("--recursive", "include full schemas for immediate children (default: compact child index)").option("--full", "alias for --recursive").action((commandArgs, opts) => {
|
|
33873
|
+
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("--brief", "compact per-verb flags, value requirements, and one-line descriptions (no schemas or prose)").option("--out <path>", "write the output to a UTF-8 file instead of stdout (#5802 byte contract)").option("--recursive", "include full schemas for immediate children (default: compact child index)").option("--full", "alias for --recursive").action((commandArgs, opts) => {
|
|
33732
33874
|
const emit = (output) => {
|
|
33733
33875
|
if (!opts.out) console.log(output);
|
|
33734
33876
|
else console.log(`Wrote explain output to ${opts.out} (UTF-8, ${writeUtf8Receipt(opts.out, output)} bytes)`);
|
|
@@ -33767,6 +33909,10 @@ function registerExplainCommand(program3) {
|
|
|
33767
33909
|
return;
|
|
33768
33910
|
}
|
|
33769
33911
|
const recursive = Boolean(opts.recursive || opts.full);
|
|
33912
|
+
if (opts.brief) {
|
|
33913
|
+
emit(opts.json ? JSON.stringify(explainBriefManifest(manifest, command), null, 2) : formatExplainBrief(command, manifest.name));
|
|
33914
|
+
return;
|
|
33915
|
+
}
|
|
33770
33916
|
emit(opts.json ? JSON.stringify(explainCommandManifest(manifest, command, { recursive }), null, 2) : command.subcommands.length ? formatExplainGroup(command, manifest.name) : formatExplainCommand(command, manifest.name));
|
|
33771
33917
|
});
|
|
33772
33918
|
}
|
|
@@ -34438,10 +34584,10 @@ async function preflightBatchSurfaces(validated, rowRepo, options) {
|
|
|
34438
34584
|
continue;
|
|
34439
34585
|
}
|
|
34440
34586
|
if (known.length === 0) continue;
|
|
34441
|
-
const inferred = inferSurface(known, { title: spec.title, body: spec.body });
|
|
34587
|
+
const inferred = inferSurface(known, { title: spec.title, type: spec.type, body: spec.body });
|
|
34442
34588
|
spec.labels = [...spec.labels ?? [], inferred.label];
|
|
34443
34589
|
process.stderr.write(
|
|
34444
|
-
`mmi-cli: no --surface given \u2014 row ${row} filed under ${inferred.label} (${inferred.reason}). Pass --surface to choose
|
|
34590
|
+
`mmi-cli: no --surface given \u2014 row ${row} filed under ${inferred.label} (${inferred.reason}). Pass --surface to choose.${surfaceInferenceSuffix(inferred)}
|
|
34445
34591
|
`
|
|
34446
34592
|
);
|
|
34447
34593
|
}
|
|
@@ -40750,6 +40896,7 @@ function registerCollaborationCommands(program3) {
|
|
|
40750
40896
|
repo: planRepo,
|
|
40751
40897
|
labels: [...planLabels, ...surface ? [surface] : []],
|
|
40752
40898
|
title,
|
|
40899
|
+
type,
|
|
40753
40900
|
body: opts.body
|
|
40754
40901
|
});
|
|
40755
40902
|
if (warn) process.stderr.write(`${warn}
|
|
@@ -40757,10 +40904,7 @@ function registerCollaborationCommands(program3) {
|
|
|
40757
40904
|
if (refusal) fail(refusal.message, refusal.payload);
|
|
40758
40905
|
if (inferred && !surface) {
|
|
40759
40906
|
planInferred = inferred;
|
|
40760
|
-
process.stderr.write(
|
|
40761
|
-
`mmi-cli: no --surface given \u2014 filed under ${inferred.label} (${inferred.reason}). Pass --surface to choose.
|
|
40762
|
-
`
|
|
40763
|
-
);
|
|
40907
|
+
process.stderr.write(surfaceInferenceNote(inferred));
|
|
40764
40908
|
}
|
|
40765
40909
|
}
|
|
40766
40910
|
return {
|
|
@@ -40770,7 +40914,9 @@ function registerCollaborationCommands(program3) {
|
|
|
40770
40914
|
priority,
|
|
40771
40915
|
repo: opts.repo,
|
|
40772
40916
|
...surface ? { surface } : {},
|
|
40773
|
-
...planInferred ? { surface_inferred: true, surface: planInferred.label, surface_reason: planInferred.reason } : {}
|
|
40917
|
+
...planInferred ? { surface_inferred: true, surface: planInferred.label, surface_reason: planInferred.reason } : {},
|
|
40918
|
+
...planInferred?.uncertain ? { surface_uncertain: true } : {},
|
|
40919
|
+
...planInferred?.alternatives?.length ? { surface_alternatives: planInferred.alternatives } : {}
|
|
40774
40920
|
};
|
|
40775
40921
|
}
|
|
40776
40922
|
).action(async (o) => {
|
|
@@ -40814,7 +40960,7 @@ function registerCollaborationCommands(program3) {
|
|
|
40814
40960
|
return fail(`issue create: ${e.message}`, e instanceof TextArgError ? { code: e.code, offending_flag: e.offendingFlag } : void 0);
|
|
40815
40961
|
}
|
|
40816
40962
|
{
|
|
40817
|
-
const surfaceCheck = await checkSurfaceRequirement({ repo: targetRepo2, labels: extraLabels, title, body });
|
|
40963
|
+
const surfaceCheck = await checkSurfaceRequirement({ repo: targetRepo2, labels: extraLabels, title, type: issueType, body });
|
|
40818
40964
|
const { refusal, warn, inferred } = surfaceCheck;
|
|
40819
40965
|
if (warn) process.stderr.write(`${warn}
|
|
40820
40966
|
`);
|
|
@@ -40844,10 +40990,7 @@ function registerCollaborationCommands(program3) {
|
|
|
40844
40990
|
labels: extraLabels.length ? extraLabels : void 0
|
|
40845
40991
|
});
|
|
40846
40992
|
surfaceInferred = inferred;
|
|
40847
|
-
process.stderr.write(
|
|
40848
|
-
`mmi-cli: no --surface given \u2014 filed under ${inferred.label} (${inferred.reason}). Pass --surface to choose.
|
|
40849
|
-
`
|
|
40850
|
-
);
|
|
40993
|
+
process.stderr.write(surfaceInferenceNote(inferred));
|
|
40851
40994
|
}
|
|
40852
40995
|
if (refusal && !surfaceWaived()) return fail(refusal.message, refusal.payload);
|
|
40853
40996
|
}
|
|
@@ -40887,7 +41030,10 @@ function registerCollaborationCommands(program3) {
|
|
|
40887
41030
|
} : {},
|
|
40888
41031
|
...parentLinkFields(parent, parentLinkError),
|
|
40889
41032
|
// #1164: surfaced so a caller can see (and override with --surface) a pick it never asked for.
|
|
40890
|
-
...surfaceInferred ? { surface_inferred: true, surface: surfaceInferred.label, surface_reason: surfaceInferred.reason } : {}
|
|
41033
|
+
...surfaceInferred ? { surface_inferred: true, surface: surfaceInferred.label, surface_reason: surfaceInferred.reason } : {},
|
|
41034
|
+
// #6818: a weak/ambiguous pick says so, with its runner-ups, so the caller can pass --surface.
|
|
41035
|
+
...surfaceInferred?.uncertain ? { surface_uncertain: true } : {},
|
|
41036
|
+
...surfaceInferred?.alternatives?.length ? { surface_alternatives: surfaceInferred.alternatives } : {}
|
|
40891
41037
|
}));
|
|
40892
41038
|
}), [
|
|
40893
41039
|
'mmi-cli oracle issue create --type task --title "Wire the schema"',
|
package/package.json
CHANGED