@mutmutco/cli 3.21.0 → 3.23.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 +59 -7
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -10237,6 +10237,11 @@ function resolvePrViewFields(tokens2, defaultPrFields) {
|
|
|
10237
10237
|
const provided = tokens2 !== void 0 && tokens2.length > 0;
|
|
10238
10238
|
return provided ? normalizeIssueViewJsonFields(tokens2) : defaultPrFields;
|
|
10239
10239
|
}
|
|
10240
|
+
function ensureField(fields, field) {
|
|
10241
|
+
const list = fields.split(",").map((f) => f.trim()).filter(Boolean);
|
|
10242
|
+
if (!list.includes(field)) list.push(field);
|
|
10243
|
+
return list.join(",");
|
|
10244
|
+
}
|
|
10240
10245
|
|
|
10241
10246
|
// src/sub-issue.ts
|
|
10242
10247
|
function parseIssueRef(ref) {
|
|
@@ -17278,6 +17283,39 @@ async function runPrForIssue(deps, issueRef, opts) {
|
|
|
17278
17283
|
}
|
|
17279
17284
|
return extractPrForIssueResponse(resp);
|
|
17280
17285
|
}
|
|
17286
|
+
async function runIssueViewContext(deps, opts) {
|
|
17287
|
+
const fields = opts.comments || opts.context ? ensureField(opts.jsonFields, "comments") : opts.jsonFields;
|
|
17288
|
+
const base = await deps.ghJson(["issue", "view", String(opts.number), "--repo", opts.repo, "--json", fields], GH_LIST_TIMEOUT_MS);
|
|
17289
|
+
if (!opts.context) return base;
|
|
17290
|
+
const result = { ...base };
|
|
17291
|
+
const ref = `${opts.repo}#${opts.number}`;
|
|
17292
|
+
let partial = false;
|
|
17293
|
+
try {
|
|
17294
|
+
result.linkedPrs = await runPrForIssue(deps, ref, { repo: opts.repo });
|
|
17295
|
+
} catch {
|
|
17296
|
+
result.linkedPrs = [];
|
|
17297
|
+
partial = true;
|
|
17298
|
+
}
|
|
17299
|
+
try {
|
|
17300
|
+
const children = await runIssueChildren(deps, ref, { recursive: false, boardProjectId: opts.boardProjectId });
|
|
17301
|
+
if (children.length) result.children = children;
|
|
17302
|
+
} catch {
|
|
17303
|
+
partial = true;
|
|
17304
|
+
}
|
|
17305
|
+
if (partial) result.partial = true;
|
|
17306
|
+
return result;
|
|
17307
|
+
}
|
|
17308
|
+
async function runPrViewContext(deps, opts) {
|
|
17309
|
+
let fields = opts.jsonFields;
|
|
17310
|
+
if (opts.comments || opts.context) fields = ensureField(fields, "comments");
|
|
17311
|
+
if (opts.context) fields = ensureField(fields, "closingIssuesReferences");
|
|
17312
|
+
const base = await deps.ghJson(["pr", "view", String(opts.number), "--repo", opts.repo, "--json", fields], GH_LIST_TIMEOUT_MS);
|
|
17313
|
+
if (!opts.context) return base;
|
|
17314
|
+
const result = { ...base };
|
|
17315
|
+
result.linkedIssues = Array.isArray(base.closingIssuesReferences) ? base.closingIssuesReferences : [];
|
|
17316
|
+
delete result.closingIssuesReferences;
|
|
17317
|
+
return result;
|
|
17318
|
+
}
|
|
17281
17319
|
function queryFail(command, e) {
|
|
17282
17320
|
if (e instanceof QueryReadError) {
|
|
17283
17321
|
const code = e.code === "NOT_FOUND" ? ERROR_CODES.ERR_NOT_FOUND : e.code === "NO_AUTH" ? ERROR_CODES.ERR_NO_AUTH : ERROR_CODES.ERR_BAD_ENUM;
|
|
@@ -17311,15 +17349,18 @@ async function resolveBoardProjectId(repoOption) {
|
|
|
17311
17349
|
return void 0;
|
|
17312
17350
|
}
|
|
17313
17351
|
}
|
|
17314
|
-
function
|
|
17315
|
-
|
|
17316
|
-
const pr2 = program3.commands.find((c) => c.name() === "pr");
|
|
17317
|
-
if (!issue2 || !pr2) return;
|
|
17318
|
-
const deps = {
|
|
17352
|
+
function queryDeps() {
|
|
17353
|
+
return {
|
|
17319
17354
|
ghJson: async (args, timeoutMs = GH_LIST_TIMEOUT_MS) => JSON.parse((await execFileP2("gh", args, { timeout: timeoutMs })).stdout),
|
|
17320
17355
|
viewer: () => githubLogin(),
|
|
17321
17356
|
resolveRepo: resolveRepo2
|
|
17322
17357
|
};
|
|
17358
|
+
}
|
|
17359
|
+
function registerQueryCommands(program3) {
|
|
17360
|
+
const issue2 = program3.commands.find((c) => c.name() === "issue");
|
|
17361
|
+
const pr2 = program3.commands.find((c) => c.name() === "pr");
|
|
17362
|
+
if (!issue2 || !pr2) return;
|
|
17363
|
+
const deps = queryDeps();
|
|
17323
17364
|
issue2.command("list").description("bounded issue read \u2014 filter by label/state/assignee (NO free-text search); always prints JSON").option("--label <label>", "filter by label").option("--state <state>", "open | closed | all", "open").option("--assignee <login>", "filter by assignee login").option("--limit <n>", "max issues to return (capped at 100)", (v) => Number(v), DEFAULT_LIMIT).option("--repo <owner/repo>", "target repo (defaults to the current repo)").option("--json", "machine-readable output (already the default \u2014 accepted for contract uniformity)").action(async (o) => {
|
|
17324
17365
|
try {
|
|
17325
17366
|
const state = validateEnum("--state", ISSUE_STATES, o.state, "issue list");
|
|
@@ -21107,13 +21148,19 @@ withExamples(mutating(
|
|
|
21107
21148
|
"--type is one of bug|feature|task.",
|
|
21108
21149
|
"--dry-run and --validate-only pre-validate the create plan before any issue is written."
|
|
21109
21150
|
]);
|
|
21110
|
-
issue.command("view <number>").description(
|
|
21151
|
+
issue.command("view <number>").description('read an issue as structured JSON \u2014 the mmi-cli path for non-board issue reads (#2347). --comments folds in every comment; --context also adds linkedPrs + children (the one-shot "load the whole item" read, #2894)').option("--repo <owner/repo>", "target repo (defaults to the current repo)").option("--json [fields...]", 'gh --json field list (overrides the default field set). Accepts commas, spaces, or repeated --json flags \u2014 in PowerShell an unquoted comma list is an array literal, so QUOTE it: --json "number,title,body,url"').option("--comments", 'include every comment (body + comments in one call) \u2014 the agentic "read the whole item before working it" read (#2894)').option("--context", "full working context in one call: implies --comments and also adds linkedPrs and, for an epic, a children summary (#2894)").action(async (number, o) => {
|
|
21111
21152
|
const n = Number(number);
|
|
21112
21153
|
if (!Number.isInteger(n) || n <= 0) return fail("issue view: <number> must be a positive integer");
|
|
21113
21154
|
const repo = await resolveRepo(o.repo);
|
|
21114
21155
|
if (!repo) return fail("issue view: could not resolve repo (pass --repo <owner/repo>)");
|
|
21115
21156
|
const fields = normalizeIssueViewJsonFields(o.json);
|
|
21116
21157
|
try {
|
|
21158
|
+
if (o.comments || o.context) {
|
|
21159
|
+
const boardProjectId = o.context ? await resolveBoardProjectId(o.repo) : void 0;
|
|
21160
|
+
const data2 = await runIssueViewContext(queryDeps(), { number: n, repo, comments: Boolean(o.comments), context: Boolean(o.context), jsonFields: fields, boardProjectId });
|
|
21161
|
+
console.log(JSON.stringify(data2));
|
|
21162
|
+
return;
|
|
21163
|
+
}
|
|
21117
21164
|
const data = await ghJson(["issue", "view", String(n), "--repo", repo, "--json", fields]);
|
|
21118
21165
|
console.log(JSON.stringify(data));
|
|
21119
21166
|
} catch (e) {
|
|
@@ -21357,7 +21404,7 @@ withExamples(pr.command("create").description("create a PR and print {number,url
|
|
|
21357
21404
|
"--head and --base default to the current branch and the repo default; only pass them to override.",
|
|
21358
21405
|
"Use --body-file for multiline PR bodies instead of shell-escaped inline markdown."
|
|
21359
21406
|
]);
|
|
21360
|
-
pr.command("view <number>").description("read a PR as structured JSON (merged state, head/base, URL, merge commit) \u2014 the mmi-cli read path (#2347)").option("--repo <owner/repo>", "target repo (defaults to the current repo)").option("--json [fields...]", 'gh --json field list (overrides the default field set). Accepts commas, spaces, or repeated --json flags \u2014 in PowerShell an unquoted comma list is an array literal, so QUOTE it: --json "state,baseRefName,mergeCommit"').action(async (number, o) => {
|
|
21407
|
+
pr.command("view <number>").description("read a PR as structured JSON (merged state, head/base, URL, merge commit) \u2014 the mmi-cli read path (#2347). --comments folds in every comment; --context also adds linkedIssues (the issues it closes/references, #2894)").option("--repo <owner/repo>", "target repo (defaults to the current repo)").option("--json [fields...]", 'gh --json field list (overrides the default field set). Accepts commas, spaces, or repeated --json flags \u2014 in PowerShell an unquoted comma list is an array literal, so QUOTE it: --json "state,baseRefName,mergeCommit"').option("--comments", "include every comment (body + comments in one call) \u2014 read the whole PR before landing it (#2894)").option("--context", "full working context in one call: implies --comments and also adds linkedIssues (the issues the PR closes/references) (#2894)").action(async (number, o) => {
|
|
21361
21408
|
const n = Number(number);
|
|
21362
21409
|
if (!Number.isInteger(n) || n <= 0) return fail("pr view: <number> must be a positive integer");
|
|
21363
21410
|
const repo = await resolveRepo(o.repo);
|
|
@@ -21365,6 +21412,11 @@ pr.command("view <number>").description("read a PR as structured JSON (merged st
|
|
|
21365
21412
|
const defaultPrFields = "number,title,state,url,isDraft,mergeable,mergedAt,mergeCommit,headRefName,baseRefName,author,labels";
|
|
21366
21413
|
const effective = resolvePrViewFields(o.json, defaultPrFields);
|
|
21367
21414
|
try {
|
|
21415
|
+
if (o.comments || o.context) {
|
|
21416
|
+
const data2 = await runPrViewContext(queryDeps(), { number: n, repo, comments: Boolean(o.comments), context: Boolean(o.context), jsonFields: effective });
|
|
21417
|
+
console.log(JSON.stringify(data2));
|
|
21418
|
+
return;
|
|
21419
|
+
}
|
|
21368
21420
|
const data = await ghJson(["pr", "view", String(n), "--repo", repo, "--json", effective]);
|
|
21369
21421
|
console.log(JSON.stringify(data));
|
|
21370
21422
|
} catch (e) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mutmutco/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.23.0",
|
|
4
4
|
"description": "MMI Future CLI — the org dev toolbox (board, registry, keyless secrets, release train, bootstrap, doctor) and the cross-IDE engine the plugin's session-start hook drives.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|