@mutmutco/cli 2.43.0 → 2.44.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 +72 -14
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -8371,6 +8371,36 @@ async function runPrLand(prNumber, options, deps) {
|
|
|
8371
8371
|
// src/index.ts
|
|
8372
8372
|
var import_node_os5 = require("node:os");
|
|
8373
8373
|
|
|
8374
|
+
// src/attach-to-project.ts
|
|
8375
|
+
async function resolveAutoAddBoardAttach(client, cfg, selector, priority, warn = (m) => process.stderr.write(m)) {
|
|
8376
|
+
let projectItemId;
|
|
8377
|
+
try {
|
|
8378
|
+
const boardCfg = resolveBoardConfig(cfg);
|
|
8379
|
+
const lookup = await fetchIssueProjectItem(client, boardCfg, selector);
|
|
8380
|
+
projectItemId = lookup.item?.itemId;
|
|
8381
|
+
} catch (e) {
|
|
8382
|
+
warn(`warning: issue #${selector.number} board item lookup failed after auto-add: ${e.message}
|
|
8383
|
+
`);
|
|
8384
|
+
}
|
|
8385
|
+
if (priority) {
|
|
8386
|
+
if (projectItemId) {
|
|
8387
|
+
try {
|
|
8388
|
+
await setBoardItemPriority(client, cfg, projectItemId, priority);
|
|
8389
|
+
} catch (e) {
|
|
8390
|
+
const err = e;
|
|
8391
|
+
warn(
|
|
8392
|
+
`warning: issue #${selector.number} board Priority not set: ${(err.stderr || err.message || String(e)).trim()}
|
|
8393
|
+
`
|
|
8394
|
+
);
|
|
8395
|
+
}
|
|
8396
|
+
} else {
|
|
8397
|
+
warn(`warning: issue #${selector.number} board Priority not set: could not resolve project item id after auto-add
|
|
8398
|
+
`);
|
|
8399
|
+
}
|
|
8400
|
+
}
|
|
8401
|
+
return { projectItemId };
|
|
8402
|
+
}
|
|
8403
|
+
|
|
8374
8404
|
// src/gh-create.ts
|
|
8375
8405
|
var import_promises4 = require("node:fs/promises");
|
|
8376
8406
|
var import_node_os3 = require("node:os");
|
|
@@ -8448,6 +8478,9 @@ function parseAddedItemId(stdout) {
|
|
|
8448
8478
|
return void 0;
|
|
8449
8479
|
}
|
|
8450
8480
|
}
|
|
8481
|
+
function isAlreadyOnBoardError(stderr) {
|
|
8482
|
+
return /already exists in (?:this|the) project/i.test(stderr);
|
|
8483
|
+
}
|
|
8451
8484
|
function buildPrArgs({ title, body, base, head, repo }) {
|
|
8452
8485
|
const args = ["pr", "create"];
|
|
8453
8486
|
if (repo) args.push("--repo", repo);
|
|
@@ -13073,6 +13106,11 @@ var SSM_CHANNEL_PARAM = "/mmi-future/shared/SLACK_ALERTS_CHANNEL";
|
|
|
13073
13106
|
var SLACK_TIMEOUT_MS = 1e4;
|
|
13074
13107
|
var MAX_BULLETS = 6;
|
|
13075
13108
|
var MAX_SUMMARY_LINES = 8;
|
|
13109
|
+
function neutralizeHubProductBrands(text) {
|
|
13110
|
+
let s = text.replace(/\bMM-Fofu\b/gi, "design-system consumer").replace(/\bMM-Katip\b/gi, "workspace product").replace(/\b[Ff]o[Ff]u\b/g, "design-system").replace(/\bKatip\b/gi, "workspace");
|
|
13111
|
+
s = s.replace(/\bdesign-system\s+design-system\b/gi, "design-system");
|
|
13112
|
+
return s.replace(/\s{2,}/g, " ").trim();
|
|
13113
|
+
}
|
|
13076
13114
|
function escapeMrkdwn(text) {
|
|
13077
13115
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
13078
13116
|
}
|
|
@@ -13091,7 +13129,7 @@ function bulletToLine(raw) {
|
|
|
13091
13129
|
text = text.slice(0, tail.index).trim();
|
|
13092
13130
|
}
|
|
13093
13131
|
if (!text) return null;
|
|
13094
|
-
return `\u2022 ${escapeMrkdwn(text)}${link}`;
|
|
13132
|
+
return `\u2022 ${escapeMrkdwn(neutralizeHubProductBrands(text))}${link}`;
|
|
13095
13133
|
}
|
|
13096
13134
|
function curateReleaseNotes(notesMd, maxBullets = MAX_BULLETS) {
|
|
13097
13135
|
const lines = [];
|
|
@@ -13138,7 +13176,7 @@ function formatAnnouncement(args) {
|
|
|
13138
13176
|
].join("\n");
|
|
13139
13177
|
}
|
|
13140
13178
|
function summaryFileLines(content) {
|
|
13141
|
-
return content.split("\n").map((l) => l.trim()).filter(Boolean).slice(0, MAX_SUMMARY_LINES).map((l) => escapeMrkdwn(l.replace(/^[•*-]\s*/, ""))).filter(Boolean).map((l) => `\u2022 ${l}`);
|
|
13179
|
+
return content.split("\n").map((l) => l.trim()).filter(Boolean).slice(0, MAX_SUMMARY_LINES).map((l) => escapeMrkdwn(neutralizeHubProductBrands(l.replace(/^[•*-]\s*/, "")))).filter(Boolean).map((l) => `\u2022 ${l}`);
|
|
13142
13180
|
}
|
|
13143
13181
|
async function ssmParameter(deps, name, decrypt) {
|
|
13144
13182
|
const args = [
|
|
@@ -13170,6 +13208,12 @@ async function announceRelease(deps, args) {
|
|
|
13170
13208
|
if (args.summaryFile) {
|
|
13171
13209
|
if (!deps.readFile) throw new Error("summary file given but deps.readFile is missing");
|
|
13172
13210
|
lines = summaryFileLines(await deps.readFile(args.summaryFile));
|
|
13211
|
+
if (deps.removeFile) {
|
|
13212
|
+
try {
|
|
13213
|
+
await deps.removeFile(args.summaryFile);
|
|
13214
|
+
} catch {
|
|
13215
|
+
}
|
|
13216
|
+
}
|
|
13173
13217
|
}
|
|
13174
13218
|
if (lines.length === 0) lines = curateReleaseNotes(view.body ?? "");
|
|
13175
13219
|
if (lines.length === 0) lines = ["\u2022 maintenance release \u2014 see the notes for details"];
|
|
@@ -17038,11 +17082,11 @@ async function attachToProject(issueNumber, repo, priority) {
|
|
|
17038
17082
|
cfg = await loadConfigForRepo(targetRepo2);
|
|
17039
17083
|
} catch (e) {
|
|
17040
17084
|
console.error(`issue create: board attach skipped \u2014 ${e.message}`);
|
|
17041
|
-
return
|
|
17085
|
+
return { onBoard: false };
|
|
17042
17086
|
}
|
|
17043
17087
|
if (!cfg.projectId) {
|
|
17044
17088
|
console.error(`issue create: board attach skipped \u2014 no Hub registry board META for ${targetRepo2 ?? "current repo"}; run \`mmi-cli project get ${targetRepo2 ?? "<owner/repo>"}\` and backfill board coords`);
|
|
17045
|
-
return
|
|
17089
|
+
return { onBoard: false };
|
|
17046
17090
|
}
|
|
17047
17091
|
try {
|
|
17048
17092
|
const viewArgs = ["issue", "view", String(issueNumber), "--json", "id", "--jq", ".id"];
|
|
@@ -17061,12 +17105,25 @@ async function attachToProject(issueNumber, repo, priority) {
|
|
|
17061
17105
|
`);
|
|
17062
17106
|
}
|
|
17063
17107
|
}
|
|
17064
|
-
return projectItemId;
|
|
17108
|
+
return { projectItemId, onBoard: true };
|
|
17065
17109
|
} catch (e) {
|
|
17066
17110
|
const err = e;
|
|
17067
|
-
|
|
17111
|
+
const detail = (err.stderr || err.message || String(e)).trim();
|
|
17112
|
+
if (isAlreadyOnBoardError(detail)) {
|
|
17113
|
+
if (targetRepo2) {
|
|
17114
|
+
const { projectItemId } = await resolveAutoAddBoardAttach(
|
|
17115
|
+
defaultGitHubClient(),
|
|
17116
|
+
cfg,
|
|
17117
|
+
{ repo: targetRepo2, number: issueNumber },
|
|
17118
|
+
priority
|
|
17119
|
+
);
|
|
17120
|
+
return { projectItemId, onBoard: true };
|
|
17121
|
+
}
|
|
17122
|
+
return { onBoard: true };
|
|
17123
|
+
}
|
|
17124
|
+
process.stderr.write(`warning: issue #${issueNumber} created but NOT added to the project board: ${detail}
|
|
17068
17125
|
`);
|
|
17069
|
-
return
|
|
17126
|
+
return { onBoard: false };
|
|
17070
17127
|
}
|
|
17071
17128
|
}
|
|
17072
17129
|
var ghRunner = async (args, timeoutMs) => (await execFileP2("gh", args, { timeout: timeoutMs })).stdout;
|
|
@@ -17516,7 +17573,7 @@ issue.command("create").description("create an issue (type \u2192 label) and pri
|
|
|
17516
17573
|
}
|
|
17517
17574
|
}
|
|
17518
17575
|
const created = await ghCreate(args);
|
|
17519
|
-
const projectItemId = await attachToProject(created.number, o.repo, priority);
|
|
17576
|
+
const { projectItemId, onBoard } = await attachToProject(created.number, o.repo, priority);
|
|
17520
17577
|
let parent;
|
|
17521
17578
|
let parentLinkError;
|
|
17522
17579
|
if (o.parent !== void 0) {
|
|
@@ -17530,7 +17587,7 @@ issue.command("create").description("create an issue (type \u2192 label) and pri
|
|
|
17530
17587
|
}
|
|
17531
17588
|
}
|
|
17532
17589
|
if (o.related !== false) scheduleRelatedDiscovery({ repo: o.repo, number: created.number, title, body });
|
|
17533
|
-
console.log(JSON.stringify({ ...created, label: o.type, priority, projectItemId, ...parentLinkFields(parent, parentLinkError) }));
|
|
17590
|
+
console.log(JSON.stringify({ ...created, label: o.type, priority, projectItemId, onBoard, ...parentLinkFields(parent, parentLinkError) }));
|
|
17534
17591
|
});
|
|
17535
17592
|
issue.command("discover-related").description("find related issues for an existing issue and post only high-confidence links").requiredOption("--number <number>", "created issue number").requiredOption("--title <title>", "created issue title").requiredOption("--body <body>", "created issue body").option("--repo <owner/repo>", "target repo (defaults to the current repo)").option("--json", "print candidates instead of posting").action(async (o) => {
|
|
17536
17593
|
const number = Number(o.number);
|
|
@@ -17675,8 +17732,8 @@ program2.command("report").description("file a friction report on the Hub board
|
|
|
17675
17732
|
} catch {
|
|
17676
17733
|
}
|
|
17677
17734
|
const created = await ghCreate(args);
|
|
17678
|
-
const projectItemId = await attachToProject(created.number, targetRepo2, priority);
|
|
17679
|
-
console.log(JSON.stringify({ ...created, deduped: false, label: REPORT_LABEL, priority, projectItemId }));
|
|
17735
|
+
const { projectItemId, onBoard } = await attachToProject(created.number, targetRepo2, priority);
|
|
17736
|
+
console.log(JSON.stringify({ ...created, deduped: false, label: REPORT_LABEL, priority, projectItemId, onBoard }));
|
|
17680
17737
|
});
|
|
17681
17738
|
async function resolvePluginSha() {
|
|
17682
17739
|
const root = process.env.CLAUDE_PLUGIN_ROOT;
|
|
@@ -17874,8 +17931,8 @@ program2.command("skill-lesson").description("file a skill-lesson on the Hub boa
|
|
|
17874
17931
|
} catch {
|
|
17875
17932
|
}
|
|
17876
17933
|
const created = await ghCreate(args);
|
|
17877
|
-
const projectItemId = await attachToProject(created.number, targetRepo2, priority);
|
|
17878
|
-
console.log(JSON.stringify({ ...created, deduped: false, label: SKILL_LESSON_LABEL, skill, priority, projectItemId }));
|
|
17934
|
+
const { projectItemId, onBoard } = await attachToProject(created.number, targetRepo2, priority);
|
|
17935
|
+
console.log(JSON.stringify({ ...created, deduped: false, label: SKILL_LESSON_LABEL, skill, priority, projectItemId, onBoard }));
|
|
17879
17936
|
});
|
|
17880
17937
|
var pr = program2.command("pr").description("pull requests \u2014 reliable create with structured output");
|
|
17881
17938
|
pr.command("create").description("create a PR and print {number,url} JSON").option("--title <title>", "PR title").option("--title-file <path|->", "read the PR title from a UTF-8 file, or from stdin with -").option("--body <body>", "PR body (markdown)").option("--body-file <path|->", "read PR body from a UTF-8 file, or from stdin with -").option("--base <branch>", "base branch (defaults to the repo default)").option("--head <branch>", "head branch (defaults to the current branch)").option("--repo <owner/repo>", "target repo (defaults to the current repo)").action(async (o) => {
|
|
@@ -18628,7 +18685,8 @@ function trainApplyDeps() {
|
|
|
18628
18685
|
// Slack release announcement (#883): Hub-only + best-effort inside announceRelease itself.
|
|
18629
18686
|
announce: (args) => announceRelease({
|
|
18630
18687
|
run: async (file, cmdArgs) => (await execFileP2(file, cmdArgs, { timeout: GH_TRAIN_TIMEOUT_MS })).stdout,
|
|
18631
|
-
readFile: (path2) => (0, import_promises6.readFile)(path2, "utf8")
|
|
18688
|
+
readFile: (path2) => (0, import_promises6.readFile)(path2, "utf8"),
|
|
18689
|
+
removeFile: (path2) => (0, import_promises6.unlink)(path2)
|
|
18632
18690
|
}, args),
|
|
18633
18691
|
fetchEdgeDomains: async (slug) => {
|
|
18634
18692
|
const proj = await fetchProjectBySlug(slug, registryClientDeps(await loadConfig()));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mutmutco/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.44.0",
|
|
4
4
|
"description": "MMI Future CLI — delivers the org rules (whole-file), plus saga and KB access. The cross-IDE engine the plugin's SessionStart hook drives.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|