@mutmutco/codex-plugin 4.5.224 → 4.5.225
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/cli/dist/main.cjs
CHANGED
|
@@ -524,6 +524,7 @@ __export(github_client_exports, {
|
|
|
524
524
|
classifyGhTokenExecFailure: () => classifyGhTokenExecFailure,
|
|
525
525
|
createGitHubClient: () => createGitHubClient,
|
|
526
526
|
defaultGitHubClient: () => defaultGitHubClient,
|
|
527
|
+
githubKeyringTokenRead: () => githubKeyringTokenRead,
|
|
527
528
|
githubToken: () => githubToken,
|
|
528
529
|
githubTokenRead: () => githubTokenRead,
|
|
529
530
|
rateLimitResetNote: () => rateLimitResetNote,
|
|
@@ -543,16 +544,22 @@ function classifyGhTokenExecFailure(e) {
|
|
|
543
544
|
}
|
|
544
545
|
return { state: "failed", detail };
|
|
545
546
|
}
|
|
547
|
+
async function githubKeyringTokenRead() {
|
|
548
|
+
const env = { ...process.env };
|
|
549
|
+
delete env.GH_TOKEN;
|
|
550
|
+
delete env.GITHUB_TOKEN;
|
|
551
|
+
cachedGhCliTokenRead ??= execFileP("gh", ["auth", "token"], { env }).then(({ stdout }) => {
|
|
552
|
+
const token = stdout.trim();
|
|
553
|
+
return token ? { state: "ok", token } : { state: "absent", detail: "`gh auth token` exited 0 without printing a token" };
|
|
554
|
+
}).catch((e) => classifyGhTokenExecFailure(e));
|
|
555
|
+
return cachedGhCliTokenRead;
|
|
556
|
+
}
|
|
546
557
|
async function githubTokenRead() {
|
|
547
558
|
const mmiPat = process.env.MMI_GH_PAT?.trim();
|
|
548
559
|
if (mmiPat) return { state: "ok", token: mmiPat };
|
|
549
560
|
if (process.env.GH_TOKEN) return { state: "ok", token: process.env.GH_TOKEN };
|
|
550
561
|
if (process.env.GITHUB_TOKEN) return { state: "ok", token: process.env.GITHUB_TOKEN };
|
|
551
|
-
|
|
552
|
-
const token = stdout.trim();
|
|
553
|
-
return token ? { state: "ok", token } : { state: "absent", detail: "`gh auth token` exited 0 without printing a token" };
|
|
554
|
-
}).catch((e) => classifyGhTokenExecFailure(e));
|
|
555
|
-
return cachedGhCliTokenRead;
|
|
562
|
+
return githubKeyringTokenRead();
|
|
556
563
|
}
|
|
557
564
|
async function githubToken() {
|
|
558
565
|
const read = await githubTokenRead();
|
|
@@ -1158,6 +1165,7 @@ var init_house_map = __esm({
|
|
|
1158
1165
|
// org-managed repository rule delivery (.gitignore)
|
|
1159
1166
|
// --- vault — secrets ----------------------------------------------------------------------------
|
|
1160
1167
|
secrets: "vault",
|
|
1168
|
+
oauth: "vault",
|
|
1161
1169
|
"org oauth": "vault",
|
|
1162
1170
|
// OAuth credential planning/set/verify
|
|
1163
1171
|
// --- learning — self-improvement ----------------------------------------------------------------
|
|
@@ -1576,7 +1584,12 @@ async function writeHubBoardField(request) {
|
|
|
1576
1584
|
signal: AbortSignal.timeout(25e3)
|
|
1577
1585
|
});
|
|
1578
1586
|
const body = await res.json().catch(() => null);
|
|
1579
|
-
if (!res.ok || body?.updated !== true)
|
|
1587
|
+
if (!res.ok || body?.updated !== true) {
|
|
1588
|
+
throw Object.assign(new Error(`board field write HTTP ${res.status}: ${body?.error ?? "unconfirmed result"}`), {
|
|
1589
|
+
status: res.status,
|
|
1590
|
+
rateLimited: res.status === 429 || res.status === 503 && body?.code === "github-rate-limited"
|
|
1591
|
+
});
|
|
1592
|
+
}
|
|
1580
1593
|
}
|
|
1581
1594
|
async function addIssueToProjectViaHub(cfg, contentNodeId) {
|
|
1582
1595
|
const config = await loadConfig();
|
|
@@ -14891,6 +14904,10 @@ var VERB_ALIAS_TABLE = [
|
|
|
14891
14904
|
// #6494: there is no top-level or housed `registry` command; org/registry project metadata is
|
|
14892
14905
|
// `oracle org project get`.
|
|
14893
14906
|
{ typed: ["registry"], canonical: ["oracle", "org", "project", "get"] },
|
|
14907
|
+
// #9049: the legacy `registry org` (org constants + App spend) consolidated to `oracle org config
|
|
14908
|
+
// get` (command-consolidation.ts move(registry, config, 'org', 'get')) — the bare `registry` entry
|
|
14909
|
+
// above must not shadow it, or `--github-spend-minutes` lands on project get, which rejects it.
|
|
14910
|
+
{ typed: ["registry", "org"], canonical: ["oracle", "org", "config", "get"] },
|
|
14894
14911
|
// #6486: filing/managing an issue reads as devops work (it ships something) but issues are oracle's
|
|
14895
14912
|
// live truth; the real command is `oracle issue create`. (A narrower house-token-only reroute for
|
|
14896
14913
|
// this same case may also exist elsewhere — this entry keeps the general table a complete answer on
|
|
@@ -21815,8 +21832,23 @@ mutation($projectId: ID!, $itemId: ID!) {
|
|
|
21815
21832
|
async function updateItemSingleSelect(client, projectId, itemId, fieldId, optionId) {
|
|
21816
21833
|
if (process.env.MMI_ACTOR?.trim() === "app") {
|
|
21817
21834
|
const { writeHubBoardField: writeHubBoardField2 } = await Promise.resolve().then(() => (init_board_write(), board_write_exports));
|
|
21818
|
-
|
|
21819
|
-
|
|
21835
|
+
try {
|
|
21836
|
+
await writeHubBoardField2({ projectId, itemId, fieldId, optionId });
|
|
21837
|
+
return { credential: "app_installation" };
|
|
21838
|
+
} catch (error) {
|
|
21839
|
+
const refusal = error;
|
|
21840
|
+
if (refusal?.rateLimited !== true || refusal.status !== 503 && refusal.status !== 429) throw error;
|
|
21841
|
+
try {
|
|
21842
|
+
const identity = await githubKeyringTokenRead();
|
|
21843
|
+
if (identity.state !== "ok") throw error;
|
|
21844
|
+
const owner = createGitHubClient({ token: async () => identity.token });
|
|
21845
|
+
await owner.graphql(UPDATE_ITEM_FIELD_MUTATION, { projectId, itemId, fieldId, optionId });
|
|
21846
|
+
} catch {
|
|
21847
|
+
throw error;
|
|
21848
|
+
}
|
|
21849
|
+
process.stderr.write("board write: Hub App allowance exhausted \u2014 wrote with your own GitHub login (#9053)\n");
|
|
21850
|
+
return { credential: "user" };
|
|
21851
|
+
}
|
|
21820
21852
|
}
|
|
21821
21853
|
try {
|
|
21822
21854
|
await client.graphql(UPDATE_ITEM_FIELD_MUTATION, { projectId, itemId, fieldId, optionId });
|
|
@@ -27056,10 +27088,10 @@ var rollout_plan_default = {
|
|
|
27056
27088
|
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)."
|
|
27057
27089
|
},
|
|
27058
27090
|
baseline: {
|
|
27059
|
-
version: "4.5.
|
|
27060
|
-
tag: "v4.5.
|
|
27061
|
-
commit: "
|
|
27062
|
-
npm: "@mutmutco/cli@4.5.
|
|
27091
|
+
version: "4.5.225",
|
|
27092
|
+
tag: "v4.5.225",
|
|
27093
|
+
commit: "b41b26dda1a8",
|
|
27094
|
+
npm: "@mutmutco/cli@4.5.225"
|
|
27063
27095
|
},
|
|
27064
27096
|
exitCriterion: "fleet-n-of-n",
|
|
27065
27097
|
hubOnlyShortcut: "forbidden",
|
|
@@ -27076,14 +27108,14 @@ var rollout_plan_default = {
|
|
|
27076
27108
|
repo: "mutmutco/mmi-hub",
|
|
27077
27109
|
role: "canary",
|
|
27078
27110
|
schedule: "train",
|
|
27079
|
-
v3Target: "v4.5.
|
|
27111
|
+
v3Target: "v4.5.225"
|
|
27080
27112
|
}
|
|
27081
27113
|
],
|
|
27082
27114
|
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.",
|
|
27083
27115
|
rollback: {
|
|
27084
27116
|
independent: true,
|
|
27085
|
-
mechanism: "npm dist-tag latest -> 4.5.
|
|
27086
|
-
v3Target: "v4.5.
|
|
27117
|
+
mechanism: "npm dist-tag latest -> 4.5.225 and redeploy the Hub Lambda from tag v4.5.225 (b41b26dda1a8); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
27118
|
+
v3Target: "v4.5.225 (@mutmutco/cli@4.5.225, tag commit b41b26dda1a8 \u2014 last known-good release carrying the repo-index v4-only contract)"
|
|
27087
27119
|
}
|
|
27088
27120
|
},
|
|
27089
27121
|
{
|
|
@@ -39550,7 +39582,7 @@ var PRIMARY_GROUPS = [
|
|
|
39550
39582
|
["Setup and support", ["bootstrap", "secrets", "docs", "tests", "spawn", "dist"]],
|
|
39551
39583
|
["Coordinate and improve", ["wave", "report", "skill-lesson", "closure-rate"]]
|
|
39552
39584
|
];
|
|
39553
|
-
var OPERATIONAL_TOP_LEVEL = /* @__PURE__ */ new Set(["org", "runtime", "plugin", "packages", "github", "archive-prune"]);
|
|
39585
|
+
var OPERATIONAL_TOP_LEVEL = /* @__PURE__ */ new Set(["oauth", "org", "runtime", "plugin", "packages", "github", "archive-prune"]);
|
|
39554
39586
|
var CAMPAIGN_ORCHESTRATOR_TOP_LEVEL = /* @__PURE__ */ new Set(["pickup", "read"]);
|
|
39555
39587
|
var SUPPORT_PRIMARY = /* @__PURE__ */ new Set(["doctor", "whoami", "commands", "explain", "docs", "tests", "spawn", "dist", "wave", "report", "skill-lesson", "closure-rate"]);
|
|
39556
39588
|
var TOP_LEVEL_ORDER = /* @__PURE__ */ new Map();
|
|
@@ -39604,6 +39636,7 @@ var COMMAND_OWNERSHIP = {
|
|
|
39604
39636
|
// #7833
|
|
39605
39637
|
bootstrap: { module_owner: "cli/src/bootstrap-commands.ts", consumer: "repo-bootstrap" },
|
|
39606
39638
|
secrets: { module_owner: "cli/src/secrets-commands.ts", consumer: "authenticated-operator" },
|
|
39639
|
+
oauth: { module_owner: "cli/src/connections-oauth.ts", consumer: "authenticated-operator" },
|
|
39607
39640
|
docs: { module_owner: "cli/src/docs-index-command.ts", consumer: "repo-gates" },
|
|
39608
39641
|
tests: { module_owner: "cli/src/test-policy-core.ts", consumer: "repo-gates" },
|
|
39609
39642
|
spawn: { module_owner: "cli/src/spawn-policy-core.ts", consumer: "repo-gates" },
|
|
@@ -62441,6 +62474,18 @@ function parseBrokerInt(raw, flag, min, max) {
|
|
|
62441
62474
|
}
|
|
62442
62475
|
return n;
|
|
62443
62476
|
}
|
|
62477
|
+
function parseBrokerLimit(raw) {
|
|
62478
|
+
const n = Number(raw);
|
|
62479
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
62480
|
+
throw new Error(`read: --limit must be a positive integer (received '${raw}')`);
|
|
62481
|
+
}
|
|
62482
|
+
if (n > 100) {
|
|
62483
|
+
process.stderr.write(`mmi-cli read: --limit ${raw} clamped to 100; results may be truncated
|
|
62484
|
+
`);
|
|
62485
|
+
return 100;
|
|
62486
|
+
}
|
|
62487
|
+
return n;
|
|
62488
|
+
}
|
|
62444
62489
|
function parseBrokerJsonFields(raw, allowed) {
|
|
62445
62490
|
if (raw === void 0 || raw === false) return void 0;
|
|
62446
62491
|
if (raw === true) return void 0;
|
|
@@ -62562,7 +62607,7 @@ function buildPrListSpec(o) {
|
|
|
62562
62607
|
if (search !== void 0) args.push("--search", search);
|
|
62563
62608
|
const assignee = parseBrokerAssignee(o.assignee);
|
|
62564
62609
|
if (assignee) args.push("--assignee", assignee);
|
|
62565
|
-
if (o.limit !== void 0) args.push("--limit", String(
|
|
62610
|
+
if (o.limit !== void 0) args.push("--limit", String(parseBrokerLimit(o.limit)));
|
|
62566
62611
|
return { program: "gh", args, timeoutMs: SINGLE_SHOT_TIMEOUT_MS };
|
|
62567
62612
|
}
|
|
62568
62613
|
function withRepo(args, repo) {
|
|
@@ -62600,7 +62645,7 @@ function buildRunListSpec(o) {
|
|
|
62600
62645
|
if (status) args.push("--status", status);
|
|
62601
62646
|
const created = parseBrokerCreated(o.created);
|
|
62602
62647
|
if (created) args.push("--created", created);
|
|
62603
|
-
if (o.limit !== void 0) args.push("--limit", String(
|
|
62648
|
+
if (o.limit !== void 0) args.push("--limit", String(parseBrokerLimit(o.limit)));
|
|
62604
62649
|
return { program: "gh", args, timeoutMs: SINGLE_SHOT_TIMEOUT_MS };
|
|
62605
62650
|
}
|
|
62606
62651
|
function buildRunWatchSpec(id, o) {
|
|
@@ -62660,7 +62705,7 @@ function buildIssueListSpec(o) {
|
|
|
62660
62705
|
if (label !== void 0) args.push("--label", label);
|
|
62661
62706
|
const state = parseBrokerIssueState(o.state);
|
|
62662
62707
|
if (state) args.push("--state", state);
|
|
62663
|
-
if (o.limit !== void 0) args.push("--limit", String(
|
|
62708
|
+
if (o.limit !== void 0) args.push("--limit", String(parseBrokerLimit(o.limit)));
|
|
62664
62709
|
return { program: "gh", args, timeoutMs: SINGLE_SHOT_TIMEOUT_MS };
|
|
62665
62710
|
}
|
|
62666
62711
|
function brokerChildEnv(base = process.env) {
|
|
@@ -62792,6 +62837,7 @@ function registerAppReadBrokerCommands(program3, resolveRepo2, overrides) {
|
|
|
62792
62837
|
const repoOpt = (v) => parseBrokerRepo(v, "--repo");
|
|
62793
62838
|
const idOpt = (what) => (v) => parseBrokerId(v, what);
|
|
62794
62839
|
const intOpt = (flag, min, max) => (v) => String(parseBrokerInt(v, flag, min, max));
|
|
62840
|
+
const limitOpt = (v) => String(parseBrokerLimit(v));
|
|
62795
62841
|
const jsonOpt = (v) => parseBrokerJsonFields(v);
|
|
62796
62842
|
const checksJsonOpt = (v) => parseBrokerJsonFields(v, GH_PR_CHECKS_JSON_FIELDS);
|
|
62797
62843
|
const workflowOpt = (v) => parseBrokerWorkflow(v);
|
|
@@ -62815,7 +62861,7 @@ function registerAppReadBrokerCommands(program3, resolveRepo2, overrides) {
|
|
|
62815
62861
|
}
|
|
62816
62862
|
await dispatchGh(spec, "read run view", o.jq);
|
|
62817
62863
|
});
|
|
62818
|
-
run.command("list").description("list workflow runs (workflow/branch/commit/status/created/limit/json; formatters refused)").option("--repo <owner/repo>", "target repo (defaults to the current repo)", repoOpt).option("--json [fields]", "machine-readable output (comma-separated gh fields)", jsonOpt).option("--workflow <name>", "filter by workflow name or file", workflowOpt).option("--branch <name>", "filter by branch", branchOpt).option("--commit <sha>", "filter by the full 40-character head commit SHA (#8937)", (v) => parseBrokerCommit(v)).option("--status <status>", "filter by run status", runStatusOpt).option("--created <filter>", 'only runs created in this window, e.g. ">=2026-10-11T00:30:00Z" (#8096)', (v) => parseBrokerCreated(v)).option("--limit <n>", "maximum runs to fetch (1-100
|
|
62864
|
+
run.command("list").description("list workflow runs (workflow/branch/commit/status/created/limit/json; formatters refused)").option("--repo <owner/repo>", "target repo (defaults to the current repo)", repoOpt).option("--json [fields]", "machine-readable output (comma-separated gh fields)", jsonOpt).option("--workflow <name>", "filter by workflow name or file", workflowOpt).option("--branch <name>", "filter by branch", branchOpt).option("--commit <sha>", "filter by the full 40-character head commit SHA (#8937)", (v) => parseBrokerCommit(v)).option("--status <status>", "filter by run status", runStatusOpt).option("--created <filter>", 'only runs created in this window, e.g. ">=2026-10-11T00:30:00Z" (#8096)', (v) => parseBrokerCreated(v)).option("--limit <n>", "maximum runs to fetch (1-100; larger values clamp to 100)", limitOpt).option("--jq <expr>", JQ_HELP, jqOpt).action(async (o) => {
|
|
62819
62865
|
let spec;
|
|
62820
62866
|
try {
|
|
62821
62867
|
requireJqJson(o.jq, o.json);
|
|
@@ -62835,7 +62881,7 @@ function registerAppReadBrokerCommands(program3, resolveRepo2, overrides) {
|
|
|
62835
62881
|
await dispatchGh(spec, "read run watch");
|
|
62836
62882
|
});
|
|
62837
62883
|
const pr = read.command("pr").description("pull-request reads \u2014 view/list/diff ride gh; queue uses fixed GraphQL; checks is REST-backed (deterministic closed-custody adapter; native was EMPTY only on the historical #3035 fixture)");
|
|
62838
|
-
pr.command("list").description("list viewer-free PRs (author/viewer filters stay personal)").option("--repo <owner/repo>", "target repo (required \u2014 no git-origin default)", repoOpt).option("--json [fields]", "native gh JSON fields", jsonOpt).addOption(new Option("--state <state>", "open|closed|merged|all").choices(["open", "closed", "merged", "all"])).option("--base <branch>", "base branch", branchOpt).option("--head <branch>", "head branch", branchOpt).option("--label <label>", "filter by label", labelOpt).option("--search <query>", "viewer-free search", (v) => parseBrokerPrSearch(v)).option("--assignee <login>", "explicit assignee (viewer refused)", assigneeOpt).option("--limit <n>", "maximum PRs (1-100
|
|
62884
|
+
pr.command("list").description("list viewer-free PRs (author/viewer filters stay personal)").option("--repo <owner/repo>", "target repo (required \u2014 no git-origin default)", repoOpt).option("--json [fields]", "native gh JSON fields", jsonOpt).addOption(new Option("--state <state>", "open|closed|merged|all").choices(["open", "closed", "merged", "all"])).option("--base <branch>", "base branch", branchOpt).option("--head <branch>", "head branch", branchOpt).option("--label <label>", "filter by label", labelOpt).option("--search <query>", "viewer-free search", (v) => parseBrokerPrSearch(v)).option("--assignee <login>", "explicit assignee (viewer refused)", assigneeOpt).option("--limit <n>", "maximum PRs (1-100; larger values clamp to 100)", limitOpt).option("--jq <expr>", JQ_HELP, jqOpt).action(async (o) => {
|
|
62839
62885
|
if (!o.repo) return fail(missingBrokerPrRepoMessage("list"));
|
|
62840
62886
|
try {
|
|
62841
62887
|
requireJqJson(o.jq, o.json);
|
|
@@ -62917,7 +62963,7 @@ function registerAppReadBrokerCommands(program3, resolveRepo2, overrides) {
|
|
|
62917
62963
|
return fail(`read issue view: ${e.message}`);
|
|
62918
62964
|
}
|
|
62919
62965
|
});
|
|
62920
|
-
issue.command("list").description("list/search issues (search/assignee/label/state/limit/json; viewer pronouns refused \u2014 viewer-scoped reads stay personal)").option("--repo <owner/repo>", "target repo (defaults to the current repo)", repoOpt).option("--json [fields]", "machine-readable output (comma-separated gh fields)", jsonOpt).option("--search <query>", "search issues", searchOpt).option("--assignee <login>", "filter by assignee (viewer pronouns refused)", assigneeOpt).option("--label <label>", "filter by label", labelOpt).addOption(new Option("--state <state>", "open|closed|all").choices(["open", "closed", "all"])).option("--limit <n>", "maximum issues to fetch (1-100
|
|
62966
|
+
issue.command("list").description("list/search issues (search/assignee/label/state/limit/json; viewer pronouns refused \u2014 viewer-scoped reads stay personal)").option("--repo <owner/repo>", "target repo (defaults to the current repo)", repoOpt).option("--json [fields]", "machine-readable output (comma-separated gh fields)", jsonOpt).option("--search <query>", "search issues", searchOpt).option("--assignee <login>", "filter by assignee (viewer pronouns refused)", assigneeOpt).option("--label <label>", "filter by label", labelOpt).addOption(new Option("--state <state>", "open|closed|all").choices(["open", "closed", "all"])).option("--limit <n>", "maximum issues to fetch (1-100; larger values clamp to 100)", limitOpt).option("--jq <expr>", JQ_HELP, jqOpt).action(async (o) => {
|
|
62921
62967
|
let spec;
|
|
62922
62968
|
try {
|
|
62923
62969
|
requireJqJson(o.jq, o.json);
|
|
@@ -63453,6 +63499,25 @@ function renderTrackToDirectResult(result) {
|
|
|
63453
63499
|
return lines2.join("\n");
|
|
63454
63500
|
}
|
|
63455
63501
|
|
|
63502
|
+
// src/connections-oauth.ts
|
|
63503
|
+
async function connectProvider(provider, repo, deps) {
|
|
63504
|
+
if (!/^[a-z][a-z0-9-]*$/.test(provider)) throw new Error("invalid provider");
|
|
63505
|
+
const result = await postJson(`/connections/${provider}/connect`, { repo }, deps, "POST", { noRetry: true });
|
|
63506
|
+
const body = result.body;
|
|
63507
|
+
if (!result.ok || typeof body?.authorizeUrl !== "string") throw new Error(result.error ?? "could not start consent");
|
|
63508
|
+
return body.authorizeUrl;
|
|
63509
|
+
}
|
|
63510
|
+
function registerConnectionsOauth(program3, deps) {
|
|
63511
|
+
program3.command("oauth").description("Hub-owned provider connections").command("connect <provider>").requiredOption("--repo <owner/repo>", "consuming project repository").description("print a one-time provider consent URL; tokens stay inside the Hub").action(async (provider, options) => {
|
|
63512
|
+
try {
|
|
63513
|
+
console.log(await connectProvider(provider, options.repo, await deps()));
|
|
63514
|
+
} catch (e) {
|
|
63515
|
+
console.error(e.message);
|
|
63516
|
+
process.exitCode = 1;
|
|
63517
|
+
}
|
|
63518
|
+
});
|
|
63519
|
+
}
|
|
63520
|
+
|
|
63456
63521
|
// src/schedules-commands.ts
|
|
63457
63522
|
var import_promises10 = require("node:fs/promises");
|
|
63458
63523
|
init_clean_exit();
|
|
@@ -67234,6 +67299,7 @@ program2.command("archive-prune").description("inventory worktree evidence archi
|
|
|
67234
67299
|
});
|
|
67235
67300
|
installProcessBackstop();
|
|
67236
67301
|
consolidateCommandNamespaces(program2);
|
|
67302
|
+
registerConnectionsOauth(program2, async () => registryClientDeps(await loadConfig()));
|
|
67237
67303
|
registerOrgHealthQuery(program2);
|
|
67238
67304
|
applyCommandTaxonomy(program2);
|
|
67239
67305
|
function registeredPathPrefix(path2) {
|
package/cli/package.json
CHANGED
package/package.json
CHANGED
package/skills/board/SKILL.md
CHANGED
|
@@ -21,7 +21,7 @@ accepts an incomplete board. The CLI partitions rows into **Yours**, **Free to c
|
|
|
21
21
|
stamps (4 hours without work) hold nothing. Partition rules, stamp details and `--out` rationale:
|
|
22
22
|
[reference.md](reference.md).
|
|
23
23
|
|
|
24
|
-
**Under the App pool, never type raw `gh` for a read** (`gh issue list/view --jq`, `gh run view --jq`, `gh api -q` all bounce). Use `MMI_ACTOR=app mmi-cli devops read issue view <n> --repo <owner/repo> --json <fields>` (or `issue list`, `pr view`, `run view`); `--jq '<expr>'` on that typed read filters locally. Filter in a pipe or save output (`>`, `2>&1`, `--out`) under this worktree's `.jerv/tmp/` (`mkdir -p .jerv/tmp` first), never `../` or a sibling path: the workspace output guard refuses those. Body edits are read-then-edit: `MMI_ACTOR=app mmi-cli devops read issue view <n> --repo <owner/repo> --json body > .jerv/tmp/issue-body.json`, append or filter the JSON locally (`node -e`; the typed read's own `--jq` also filters locally), then write back with `gh issue edit <n> --repo <owner/repo> --body-file .jerv/tmp/issue-body.md` — `gh` writes pass under the pool.
|
|
24
|
+
**Under the App pool, never type raw `gh` for a read** (`gh issue list/view --jq`, `gh run view --jq`, `gh api -q` all bounce). Use `MMI_ACTOR=app mmi-cli devops read issue view <n> --repo <owner/repo> --json <fields>` (or `issue list`, `pr view`, `run view`); `--jq '<expr>'` on that typed read filters locally. Filter in a pipe or save output (`>`, `2>&1`, `--out`) under this worktree's `.jerv/tmp/` (`mkdir -p .jerv/tmp` first), never `../` or a sibling path: the workspace output guard refuses those. Body edits are read-then-edit: `MMI_ACTOR=app mmi-cli devops read issue view <n> --repo <owner/repo> --json body > .jerv/tmp/issue-body.json`, append or filter the JSON locally (`node -e`; the typed read's own `--jq` also filters locally), then write back with `gh issue edit <n> --repo <owner/repo> --body-file .jerv/tmp/issue-body.md` — `gh` writes pass under the pool. When `node -e` reads saved JSON, pass an absolute path or use `JSON.parse(require('fs').readFileSync(process.argv[1],'utf8'))`: `require()` of a relative path (e.g. `tmp\board.json` from `cygpath -w`) throws MODULE_NOT_FOUND.
|
|
25
25
|
|
|
26
26
|
## Step 2 — render it
|
|
27
27
|
|
|
@@ -60,7 +60,12 @@ mmi-cli oracle board claim <ref> <ref> <ref> --json
|
|
|
60
60
|
|
|
61
61
|
Announce issue/PR counts; refresh `mmi-cli oracle board read` this session and select ordinary claims from **Free to claim**. Read every result: failures exit nonzero. On conflict, do not blindly retry: refresh, pick another candidate or coordinate a handoff; `--force` only for an owner-authorized intentional takeover. Run writes separately, never `;`; dependent follow-ups use `&&`.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
Run each `mmi-cli oracle issue create` as its own simple command with plain double-quoted arguments — never a shell
|
|
64
|
+
helper function or nested escaped quotes around a long body in the same call: the workspace env-enumeration guard
|
|
65
|
+
blocks any command whose quoting it cannot prove inert. Write the body to a file under `.jerv/tmp/` and pass
|
|
66
|
+
`--body-file` (`--title-file` for titles with backticks).
|
|
67
|
+
|
|
68
|
+
Follow printed owner rulings; record new ones with `mmi-cli oracle issue decision`. One concurrent worktree per batch: [reference.md](reference.md). Always pass `--surface <value>` explicitly on every `mmi-cli oracle issue create` (surface inference is strict and bounces when the body merely mentions a path); use `--no-surface` only for genuinely exempt filings.
|
|
64
69
|
|
|
65
70
|
With several task lanes in one session, pass `worktree: <the mmi-worktrees/<Repo>/<issue>-<slug> path jerv_worktree_create reported>` to `jerv_worktree_exec` / `jerv_worktree_land` every time; they refuse to guess (#5629). While any mmi-worktrees lane is registered for this repo, run focused tests/gates from the task-worktree root `jerv_worktree_create` reported — never the primary checkout; the test policy refuses it (`test-command-untrusted-worktree-cwd`).
|
|
66
71
|
|
|
@@ -65,6 +65,10 @@ and PR facts.
|
|
|
65
65
|
full `closingIssuesReferences` list and moves **each** issue to Done, verifying every one and naming any
|
|
66
66
|
that did not move. So a bundle is a first-class landing, not a trick.
|
|
67
67
|
|
|
68
|
+
Preflight: when the lane changed `docs/`, run `mmi-cli oracle docs index --write`, then commit and push BEFORE
|
|
69
|
+
`mmi-cli devops pr create` — freshness is checked at the pushed commit even under an active merge queue, so never
|
|
70
|
+
defer index regeneration to after merge.
|
|
71
|
+
|
|
68
72
|
Materialize the body as a real UTF-8 file and pass its path; do not pipe it to `--body-file -`. Read
|
|
69
73
|
`mmi-cli explain devops pr create --json` before the write — flags change.
|
|
70
74
|
|
|
@@ -70,6 +70,10 @@ jobs:
|
|
|
70
70
|
if: ${{ steps.development-gate.outputs.reuse != 'true' }}
|
|
71
71
|
env:
|
|
72
72
|
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
73
|
+
# Suite only: generic product gates must not load or require design-agent content.
|
|
74
|
+
- name: Check kit agent-file drift
|
|
75
|
+
if: ${{ steps.development-gate.outputs.reuse != 'true' }}
|
|
76
|
+
uses: mutmutco/MMI-Hub/.github/actions/check-kit-agent-files@{{GATE_RUNNER_SHA}}
|
|
73
77
|
- uses: mutmutco/MMI-Hub/.github/actions/run-with-budget@{{GATE_BUDGET_SHA}}
|
|
74
78
|
if: ${{ steps.development-gate.outputs.reuse != 'true' }}
|
|
75
79
|
with:
|