@mutmutco/cli 4.3.19 → 4.3.20

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 +225 -165
  2. package/package.json +1 -1
package/dist/main.cjs CHANGED
@@ -5227,7 +5227,7 @@ function unknownCommandDomainGuide(parentPath, token) {
5227
5227
 
5228
5228
  // src/command-composition.ts
5229
5229
  var import_node_os22 = require("node:os");
5230
- var import_node_path47 = require("node:path");
5230
+ var import_node_path48 = require("node:path");
5231
5231
 
5232
5232
  // src/board-read.ts
5233
5233
  var import_node_fs13 = require("node:fs");
@@ -13353,7 +13353,7 @@ function extractForwardRefs(markdown) {
13353
13353
  });
13354
13354
  return refs;
13355
13355
  }
13356
- function checkPins(root, readFile9, docs) {
13356
+ function checkPins(root, readFile10, docs) {
13357
13357
  const findings = [];
13358
13358
  for (const [doc, markdown] of Object.entries(docs)) {
13359
13359
  for (const pin of extractPins(markdown)) {
@@ -13361,7 +13361,7 @@ function checkPins(root, readFile9, docs) {
13361
13361
  findings.push({ kind: "malformed-pin", doc, line: pin.line, detail: pin.text });
13362
13362
  continue;
13363
13363
  }
13364
- const source = readFile9((0, import_node_path12.join)(root, pin.file));
13364
+ const source = readFile10((0, import_node_path12.join)(root, pin.file));
13365
13365
  if (source == null) {
13366
13366
  findings.push({ kind: "missing-test", doc, line: pin.line, detail: pin.file });
13367
13367
  continue;
@@ -13576,7 +13576,7 @@ function defaultTrackedFirstSegments(root, firstSegments, exec = import_node_chi
13576
13576
  }
13577
13577
  }
13578
13578
  function runDocRefs(root, deps = {}) {
13579
- const readFile9 = deps.readFile ?? readFileOrNull;
13579
+ const readFile10 = deps.readFile ?? readFileOrNull;
13580
13580
  const exists = deps.exists ?? import_node_fs14.existsSync;
13581
13581
  const listDocs = deps.listDocs ?? defaultListDocs;
13582
13582
  const isIgnored = deps.isIgnored ?? ((paths) => defaultIsIgnored(root, paths));
@@ -13585,11 +13585,11 @@ function runDocRefs(root, deps = {}) {
13585
13585
  const walked = listDocs(root);
13586
13586
  const ignoredDocs = walked.length ? isIgnored(walked) : /* @__PURE__ */ new Set();
13587
13587
  const docs = Object.fromEntries(
13588
- walked.filter((rel) => !ignoredDocs.has(rel)).map((rel) => [rel, readFile9((0, import_node_path12.join)(root, rel))]).filter(([, body]) => body != null)
13588
+ walked.filter((rel) => !ignoredDocs.has(rel)).map((rel) => [rel, readFile10((0, import_node_path12.join)(root, rel))]).filter(([, body]) => body != null)
13589
13589
  );
13590
13590
  const refResult = checkRefs(root, { exists, isIgnored, trackedFirstSegments }, docs);
13591
13591
  const findings = [
13592
- ...checkPins(root, readFile9, docs).findings,
13592
+ ...checkPins(root, readFile10, docs).findings,
13593
13593
  ...refResult.findings
13594
13594
  ];
13595
13595
  if (commandPaths == null) {
@@ -14186,22 +14186,22 @@ function labelsToPrune(orgLabelNames) {
14186
14186
  const org = new Set(orgLabelNames);
14187
14187
  return GITHUB_DEFAULT_LABELS.filter((name) => !org.has(name));
14188
14188
  }
14189
- function resolveSeedContent(seed, vars, readFile9) {
14190
- if (seed.source === "self") return readFile9(seed.target);
14189
+ function resolveSeedContent(seed, vars, readFile10) {
14190
+ if (seed.source === "self") return readFile10(seed.target);
14191
14191
  if (seed.source.startsWith("seed:")) {
14192
- const tmpl = readFile9(`skills/bootstrap/seeds/${seed.source.slice("seed:".length)}`);
14192
+ const tmpl = readFile10(`skills/bootstrap/seeds/${seed.source.slice("seed:".length)}`);
14193
14193
  return tmpl == null ? null : renderSeed(tmpl, vars);
14194
14194
  }
14195
14195
  return null;
14196
14196
  }
14197
- function resolveSeedWriteContent(seed, vars, readFile9, remoteContent) {
14197
+ function resolveSeedWriteContent(seed, vars, readFile10, remoteContent) {
14198
14198
  if (!seed.managedBlock) {
14199
- return { ok: true, content: resolveSeedContent(seed, vars, readFile9), managed: seed.source === "managed-block" };
14199
+ return { ok: true, content: resolveSeedContent(seed, vars, readFile10), managed: seed.source === "managed-block" };
14200
14200
  }
14201
- const base = remoteContent ?? resolveSeedContent(seed, vars, readFile9);
14201
+ const base = remoteContent ?? resolveSeedContent(seed, vars, readFile10);
14202
14202
  if (base == null) return { ok: true, content: null, managed: true };
14203
14203
  const blockSeed = { ...seed, source: seed.managedBlock.source, managedBlock: void 0 };
14204
- const desired = resolveSeedContent(blockSeed, vars, readFile9);
14204
+ const desired = resolveSeedContent(blockSeed, vars, readFile10);
14205
14205
  if (desired == null) return { ok: true, content: null, managed: true };
14206
14206
  const result = upsertManagedSeedBlock(base, desired, seed.managedBlock.begin, seed.managedBlock.end);
14207
14207
  return result.ok ? { ok: true, content: result.content, managed: true } : { ok: false, reason: result.reason, managed: true };
@@ -15502,10 +15502,10 @@ var rollout_plan_default = {
15502
15502
  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)."
15503
15503
  },
15504
15504
  baseline: {
15505
- version: "4.3.19",
15506
- tag: "v4.3.19",
15507
- commit: "5776052e13af",
15508
- npm: "@mutmutco/cli@4.3.19"
15505
+ version: "4.3.20",
15506
+ tag: "v4.3.20",
15507
+ commit: "f33217850417",
15508
+ npm: "@mutmutco/cli@4.3.20"
15509
15509
  },
15510
15510
  exitCriterion: "fleet-n-of-n",
15511
15511
  hubOnlyShortcut: "forbidden",
@@ -15522,14 +15522,14 @@ var rollout_plan_default = {
15522
15522
  repo: "mutmutco/mmi-hub",
15523
15523
  role: "canary",
15524
15524
  schedule: "train",
15525
- v3Target: "v4.3.19"
15525
+ v3Target: "v4.3.20"
15526
15526
  }
15527
15527
  ],
15528
15528
  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.",
15529
15529
  rollback: {
15530
15530
  independent: true,
15531
- mechanism: "npm dist-tag latest -> 4.3.19 and redeploy the Hub Lambda from tag v4.3.19 (5776052e13af); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
15532
- v3Target: "v4.3.19 (@mutmutco/cli@4.3.19, tag commit 5776052e13af \u2014 last known-good release carrying the repo-index v4-only contract)"
15531
+ mechanism: "npm dist-tag latest -> 4.3.20 and redeploy the Hub Lambda from tag v4.3.20 (f33217850417); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
15532
+ v3Target: "v4.3.20 (@mutmutco/cli@4.3.20, tag commit f33217850417 \u2014 last known-good release carrying the repo-index v4-only contract)"
15533
15533
  }
15534
15534
  },
15535
15535
  {
@@ -27537,7 +27537,7 @@ function registerBootstrapCommands(program3) {
27537
27537
  }
27538
27538
  const onlyManagedBlock = onlyTarget ? seedsToApply[0]?.managedBlock != null : false;
27539
27539
  const gh = async (args) => execFileP("gh", args, { timeout: 2e4 });
27540
- const readFile9 = (p) => (0, import_node_fs26.existsSync)(p) ? (0, import_node_fs26.readFileSync)(p, "utf8") : null;
27540
+ const readFile10 = (p) => (0, import_node_fs26.existsSync)(p) ? (0, import_node_fs26.readFileSync)(p, "utf8") : null;
27541
27541
  const enc = (p) => p.split("/").map(encodeURIComponent).join("/");
27542
27542
  const putSeed = async (target, content, ref, sha) => {
27543
27543
  const tmp = (0, import_node_path25.join)((0, import_node_os14.tmpdir)(), `mmi-seed-${process.pid}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}.json`);
@@ -27686,7 +27686,7 @@ function registerBootstrapCommands(program3) {
27686
27686
  if (isLegacyBlock) {
27687
27687
  content = upsertManagedGitignoreBlock(remoteContent).content;
27688
27688
  } else {
27689
- const writeContent = resolveSeedWriteContent(resolved, vars, readFile9, remoteContent);
27689
+ const writeContent = resolveSeedWriteContent(resolved, vars, readFile10, remoteContent);
27690
27690
  if (!writeContent.ok) {
27691
27691
  return fail(`bootstrap apply: ${resolved.target}: ${writeContent.reason} \u2014 refusing to overwrite repo-owned content`);
27692
27692
  }
@@ -27823,7 +27823,7 @@ ${onlyManagedBlock ? `Only the marker-bounded Hub-managed block inside repo-owne
27823
27823
  }
27824
27824
  const rulesetSeed = repo.toLowerCase() === "mutmutco/mmi-hub" ? void 0 : manifest.seeds.find((s) => s.target === ".github/rulesets/mmi-product-required-checks.json");
27825
27825
  if (rulesetSeed) {
27826
- const rulesetContent = resolveSeedContent({ ...rulesetSeed, target: rulesetSeed.target.replace("{{REPO_SLUG}}", slug) }, vars, readFile9);
27826
+ const rulesetContent = resolveSeedContent({ ...rulesetSeed, target: rulesetSeed.target.replace("{{REPO_SLUG}}", slug) }, vars, readFile10);
27827
27827
  if (rulesetContent) {
27828
27828
  try {
27829
27829
  const client = controlClient;
@@ -35940,7 +35940,7 @@ function renderVerifySecrets(body) {
35940
35940
  // src/command-register-collaboration.ts
35941
35941
  var import_node_child_process16 = require("node:child_process");
35942
35942
  var import_node_fs43 = require("node:fs");
35943
- var import_promises7 = require("node:fs/promises");
35943
+ var import_promises8 = require("node:fs/promises");
35944
35944
 
35945
35945
  // src/session-runtime.ts
35946
35946
  var WIN32_TRAMPOLINE = "const{spawn}=require('node:child_process');const a=JSON.parse(process.argv[1]);const c=spawn(a.cmd,a.args,{stdio:'ignore',windowsHide:true,cwd:a.cwd});c.on('exit',x=>process.exit(x??0));c.on('error',()=>process.exit(1));";
@@ -35959,7 +35959,7 @@ function spawnDetachedSelf(args, deps, opts = {}) {
35959
35959
  }
35960
35960
 
35961
35961
  // src/command-register-collaboration.ts
35962
- var import_node_path40 = require("node:path");
35962
+ var import_node_path41 = require("node:path");
35963
35963
 
35964
35964
  // src/attach-to-project.ts
35965
35965
  function boardAttachRateLimitedReceipt(resetEpochSeconds) {
@@ -36762,8 +36762,8 @@ function annotateChangeMeaning(changed, policy, read) {
36762
36762
  function isMeaningfulRow(file) {
36763
36763
  return file.meaningful !== false;
36764
36764
  }
36765
- function loadPolicy(root, readFile9 = readFileOrNull2) {
36766
- const raw = readFile9((0, import_node_path33.join)(root, POLICY_FILE));
36765
+ function loadPolicy(root, readFile10 = readFileOrNull2) {
36766
+ const raw = readFile10((0, import_node_path33.join)(root, POLICY_FILE));
36767
36767
  if (raw == null) return { mandatory: [], declared: false };
36768
36768
  return parsePolicy(raw, POLICY_FILE);
36769
36769
  }
@@ -37960,6 +37960,120 @@ async function checkDocsIndexAtHead(opts, deps) {
37960
37960
  };
37961
37961
  }
37962
37962
 
37963
+ // src/pr-create-zeroci.ts
37964
+ var import_promises7 = require("node:fs/promises");
37965
+ var import_node_path38 = require("node:path");
37966
+
37967
+ // src/jervcode-node-modules-cleanup.ts
37968
+ var import_node_fs40 = require("node:fs");
37969
+ var import_node_os20 = require("node:os");
37970
+ var import_node_path37 = require("node:path");
37971
+ var JERVCODE_PACKAGE_ENTRY = (0, import_node_path37.join)("node_modules", "@jervaise", "jervcode", "dist", "launcher-entry.js");
37972
+ var WIN_NAMES2 = ["jervcode.cmd", "jervcode"];
37973
+ var POSIX_NAMES2 = ["jervcode"];
37974
+ var NODE_MODULES_CLEANUP_TIMEOUT_MS = 3e5;
37975
+ function jervcodeCandidatePaths(env = process.env, home = (0, import_node_os20.homedir)(), platform2 = process.platform) {
37976
+ const names = platform2 === "win32" ? WIN_NAMES2 : POSIX_NAMES2;
37977
+ const out = [];
37978
+ for (const dir of jervCliCandidateDirs(env, home, platform2)) {
37979
+ for (const name of names) out.push((0, import_node_path37.join)(dir, name));
37980
+ }
37981
+ return out;
37982
+ }
37983
+ function resolveJervcodePath(env = process.env, home = (0, import_node_os20.homedir)(), platform2 = process.platform, exists = import_node_fs40.existsSync) {
37984
+ for (const candidate of jervcodeCandidatePaths(env, home, platform2)) {
37985
+ if (exists(candidate)) return candidate;
37986
+ }
37987
+ return void 0;
37988
+ }
37989
+ function jervcodeExecFileArgs(args, opts = {}) {
37990
+ const platform2 = opts.platform ?? process.platform;
37991
+ const exists = opts.exists ?? import_node_fs40.existsSync;
37992
+ const resolved = resolveJervcodePath(opts.env ?? process.env, opts.home ?? (0, import_node_os20.homedir)(), platform2, exists);
37993
+ if (resolved) {
37994
+ const entry = (0, import_node_path37.join)((0, import_node_path37.join)(resolved, ".."), JERVCODE_PACKAGE_ENTRY);
37995
+ if (exists(entry)) {
37996
+ return { file: opts.execPath ?? process.execPath, args: [entry, ...args], via: "node-entry" };
37997
+ }
37998
+ }
37999
+ const bin = resolved ?? "jervcode";
38000
+ if (platform2 === "win32") {
38001
+ return { file: "cmd.exe", args: ["/c", bin, ...args], via: resolved ? "cmd-shim" : "bare" };
38002
+ }
38003
+ return { file: bin, args: [...args], via: resolved ? "posix" : "bare" };
38004
+ }
38005
+ async function removeWorktreeNodeModulesViaHelper(wtPath, opts = {}) {
38006
+ const { cwd, timeoutMs = NODE_MODULES_CLEANUP_TIMEOUT_MS } = opts;
38007
+ const env = opts.env ?? process.env;
38008
+ const exec = opts.exec ?? execFileP;
38009
+ const candidates = jervcodeCandidatePaths(env, opts.home, opts.platform ?? process.platform);
38010
+ const plan = jervcodeExecFileArgs(["worktree-node-modules-cleanup", "--worktree", wtPath], opts);
38011
+ const execOptions = { timeout: timeoutMs, ...cwd ? { cwd } : {} };
38012
+ try {
38013
+ await exec(plan.file, plan.args, execOptions);
38014
+ return { ok: true };
38015
+ } catch (e) {
38016
+ const err = e;
38017
+ const base = formatJervCliSpawnFailure(err, plan, candidates);
38018
+ const stderr = typeof err.stderr === "string" ? err.stderr.trim() : "";
38019
+ const detail = stderr.split("\n")[0] || base;
38020
+ return { ok: false, error: `jervcode worktree-node-modules-cleanup failed: ${detail}` };
38021
+ }
38022
+ }
38023
+
38024
+ // src/pr-create-zeroci.ts
38025
+ var GATE_WORKFLOW_PATH = ".github/workflows/gate.yml";
38026
+ var ZEROCI_MINT_MARKER = "zeroci-mint: seat";
38027
+ var ZEROCI_MINT_TIMEOUT_MS = 18e5;
38028
+ var ZEROCI_MINT_MAX_BUFFER = 32 * 1024 * 1024;
38029
+ function createPrCreateZeroCiDeps() {
38030
+ const git3 = createPrCreateDocsIndexDeps();
38031
+ return {
38032
+ worktreeRoot: git3.worktreeRoot,
38033
+ originRepo: git3.originRepo,
38034
+ readGateWorkflow: async (root) => {
38035
+ try {
38036
+ return await (0, import_promises7.readFile)((0, import_node_path38.join)(root, GATE_WORKFLOW_PATH), "utf8");
38037
+ } catch {
38038
+ return void 0;
38039
+ }
38040
+ },
38041
+ mint: async (root) => {
38042
+ const plan = jervcodeExecFileArgs(["zeroci-receipt", "--from-gate"]);
38043
+ try {
38044
+ await execFileHard(plan.file, plan.args, {
38045
+ cwd: root,
38046
+ timeout: ZEROCI_MINT_TIMEOUT_MS,
38047
+ maxBuffer: ZEROCI_MINT_MAX_BUFFER,
38048
+ step: "jervcode zeroci-receipt --from-gate"
38049
+ });
38050
+ } catch (e) {
38051
+ const err = e;
38052
+ const stderr = typeof err.stderr === "string" ? err.stderr.trim() : "";
38053
+ throw new Error(stderr.split("\n").filter(Boolean).pop() || formatJervCliSpawnFailure(err, plan, jervcodeCandidatePaths()));
38054
+ }
38055
+ }
38056
+ };
38057
+ }
38058
+ async function mintZeroCiReceipt(opts, deps) {
38059
+ if (opts.zeroci === false) return void 0;
38060
+ const root = await deps.worktreeRoot();
38061
+ if (!root) return void 0;
38062
+ if (opts.repo) {
38063
+ const origin = await deps.originRepo(root);
38064
+ if (!origin || origin.toLowerCase() !== opts.repo.toLowerCase()) return void 0;
38065
+ }
38066
+ const gate = await deps.readGateWorkflow(root);
38067
+ if (!gate || !gate.includes("zeroci-verify")) return void 0;
38068
+ if (!gate.includes(ZEROCI_MINT_MARKER)) return void 0;
38069
+ try {
38070
+ await deps.mint(root);
38071
+ return void 0;
38072
+ } catch (e) {
38073
+ return `pr create: WARNING \u2014 ZeroCI receipt not minted, opening the PR anyway (the gate runs in full): ${e.message}`;
38074
+ }
38075
+ }
38076
+
37963
38077
  // src/pr-create-claim-guard.ts
37964
38078
  var CLAIM_GUARD_RATE_LIMIT_WAIT_CAP_MS = 3e4;
37965
38079
  function withRateLimitRetry(client, seams = {}) {
@@ -38018,68 +38132,11 @@ async function prCreateClaimRefusal(body, repoOption, deps = {}) {
38018
38132
 
38019
38133
  // src/worktree-merge-cleanup.ts
38020
38134
  var import_node_fs42 = require("node:fs");
38021
- var import_node_path39 = require("node:path");
38022
-
38023
- // src/jervcode-node-modules-cleanup.ts
38024
- var import_node_fs40 = require("node:fs");
38025
- var import_node_os20 = require("node:os");
38026
- var import_node_path37 = require("node:path");
38027
- var JERVCODE_PACKAGE_ENTRY = (0, import_node_path37.join)("node_modules", "@jervaise", "jervcode", "dist", "launcher-entry.js");
38028
- var WIN_NAMES2 = ["jervcode.cmd", "jervcode"];
38029
- var POSIX_NAMES2 = ["jervcode"];
38030
- var NODE_MODULES_CLEANUP_TIMEOUT_MS = 3e5;
38031
- function jervcodeCandidatePaths(env = process.env, home = (0, import_node_os20.homedir)(), platform2 = process.platform) {
38032
- const names = platform2 === "win32" ? WIN_NAMES2 : POSIX_NAMES2;
38033
- const out = [];
38034
- for (const dir of jervCliCandidateDirs(env, home, platform2)) {
38035
- for (const name of names) out.push((0, import_node_path37.join)(dir, name));
38036
- }
38037
- return out;
38038
- }
38039
- function resolveJervcodePath(env = process.env, home = (0, import_node_os20.homedir)(), platform2 = process.platform, exists = import_node_fs40.existsSync) {
38040
- for (const candidate of jervcodeCandidatePaths(env, home, platform2)) {
38041
- if (exists(candidate)) return candidate;
38042
- }
38043
- return void 0;
38044
- }
38045
- function jervcodeExecFileArgs(args, opts = {}) {
38046
- const platform2 = opts.platform ?? process.platform;
38047
- const exists = opts.exists ?? import_node_fs40.existsSync;
38048
- const resolved = resolveJervcodePath(opts.env ?? process.env, opts.home ?? (0, import_node_os20.homedir)(), platform2, exists);
38049
- if (resolved) {
38050
- const entry = (0, import_node_path37.join)((0, import_node_path37.join)(resolved, ".."), JERVCODE_PACKAGE_ENTRY);
38051
- if (exists(entry)) {
38052
- return { file: opts.execPath ?? process.execPath, args: [entry, ...args], via: "node-entry" };
38053
- }
38054
- }
38055
- const bin = resolved ?? "jervcode";
38056
- if (platform2 === "win32") {
38057
- return { file: "cmd.exe", args: ["/c", bin, ...args], via: resolved ? "cmd-shim" : "bare" };
38058
- }
38059
- return { file: bin, args: [...args], via: resolved ? "posix" : "bare" };
38060
- }
38061
- async function removeWorktreeNodeModulesViaHelper(wtPath, opts = {}) {
38062
- const { cwd, timeoutMs = NODE_MODULES_CLEANUP_TIMEOUT_MS } = opts;
38063
- const env = opts.env ?? process.env;
38064
- const exec = opts.exec ?? execFileP;
38065
- const candidates = jervcodeCandidatePaths(env, opts.home, opts.platform ?? process.platform);
38066
- const plan = jervcodeExecFileArgs(["worktree-node-modules-cleanup", "--worktree", wtPath], opts);
38067
- const execOptions = { timeout: timeoutMs, ...cwd ? { cwd } : {} };
38068
- try {
38069
- await exec(plan.file, plan.args, execOptions);
38070
- return { ok: true };
38071
- } catch (e) {
38072
- const err = e;
38073
- const base = formatJervCliSpawnFailure(err, plan, candidates);
38074
- const stderr = typeof err.stderr === "string" ? err.stderr.trim() : "";
38075
- const detail = stderr.split("\n")[0] || base;
38076
- return { ok: false, error: `jervcode worktree-node-modules-cleanup failed: ${detail}` };
38077
- }
38078
- }
38135
+ var import_node_path40 = require("node:path");
38079
38136
 
38080
38137
  // src/worktree-evidence-archive.ts
38081
38138
  var import_node_fs41 = require("node:fs");
38082
- var import_node_path38 = require("node:path");
38139
+ var import_node_path39 = require("node:path");
38083
38140
  var JERV_ARTIFACT_RUN_SCOPE_ENV_VARS = ["JERV_RUN_ID", ...SESSION_ID_ENV_VARS];
38084
38141
  function sanitizeArchiveSegment(value, max = 80) {
38085
38142
  const scrubbed = value.replace(/[^A-Za-z0-9._@+-]+/g, "-").replace(/^-+|-+$/g, "");
@@ -38111,7 +38168,7 @@ function archiveWorktreeJervArtifacts(args, deps = {}) {
38111
38168
  const resolveRoot = deps.resolveArchiveRoot ?? repoRuntimeStatePath;
38112
38169
  if (!args.primaryRoot?.trim()) return { status: "skipped", reason: "missing-primary-root" };
38113
38170
  if (!args.worktreePath?.trim()) return { status: "skipped", reason: "missing-worktree-path" };
38114
- const source = (0, import_node_path38.join)(args.worktreePath, ".jerv");
38171
+ const source = (0, import_node_path39.join)(args.worktreePath, ".jerv");
38115
38172
  if (!exists(source)) return { status: "absent" };
38116
38173
  if (!isDirectory(source)) return { status: "skipped", reason: "jerv-not-a-directory" };
38117
38174
  const runScope = resolveArtifactRunScope(env);
@@ -38119,7 +38176,7 @@ function archiveWorktreeJervArtifacts(args, deps = {}) {
38119
38176
  const stamp = now().toISOString().replace(/[:.]/g, "-");
38120
38177
  const dest = resolveRoot(args.primaryRoot, "jerv-artifacts", runScope, branchSlug, stamp, ".jerv");
38121
38178
  try {
38122
- mkdirp((0, import_node_path38.dirname)(dest));
38179
+ mkdirp((0, import_node_path39.dirname)(dest));
38123
38180
  copyDir(source, dest);
38124
38181
  if (!exists(dest)) return { status: "failed", error: `archive write left no directory at ${dest}` };
38125
38182
  return { status: "archived", path: dest, runScope };
@@ -38135,7 +38192,7 @@ function scanWorktreeTmpEvidence(worktreePath, newerThanMs, deps = {}) {
38135
38192
  const exists = deps.exists ?? import_node_fs41.existsSync;
38136
38193
  const stat4 = deps.stat ?? defaultStat;
38137
38194
  const readdir2 = deps.readdir ?? import_node_fs41.readdirSync;
38138
- const tmpRoot = (0, import_node_path38.join)(worktreePath, "tmp");
38195
+ const tmpRoot = (0, import_node_path39.join)(worktreePath, "tmp");
38139
38196
  if (!exists(tmpRoot)) return [];
38140
38197
  const entries = [];
38141
38198
  const walk2 = (dir) => {
@@ -38146,14 +38203,14 @@ function scanWorktreeTmpEvidence(worktreePath, newerThanMs, deps = {}) {
38146
38203
  return;
38147
38204
  }
38148
38205
  for (const name of names) {
38149
- const full = (0, import_node_path38.join)(dir, name);
38206
+ const full = (0, import_node_path39.join)(dir, name);
38150
38207
  let st;
38151
38208
  try {
38152
38209
  st = stat4(full);
38153
38210
  } catch {
38154
38211
  continue;
38155
38212
  }
38156
- const relPath = (0, import_node_path38.relative)(worktreePath, full).replace(/\\/g, "/");
38213
+ const relPath = (0, import_node_path39.relative)(worktreePath, full).replace(/\\/g, "/");
38157
38214
  if (st.isDirectory()) {
38158
38215
  if (st.mtimeMs > newerThanMs) entries.push({ relPath, bytes: 0, mtimeMs: st.mtimeMs });
38159
38216
  walk2(full);
@@ -38178,7 +38235,7 @@ function archiveWorktreeTmpArtifacts(args, deps = {}) {
38178
38235
  if (!args.primaryRoot?.trim()) return { status: "skipped", reason: "missing-primary-root" };
38179
38236
  if (!args.worktreePath?.trim()) return { status: "skipped", reason: "missing-worktree-path" };
38180
38237
  const scanned = scanWorktreeTmpEvidence(args.worktreePath, args.newerThanMs, deps);
38181
- const source = (0, import_node_path38.join)(args.worktreePath, "tmp");
38238
+ const source = (0, import_node_path39.join)(args.worktreePath, "tmp");
38182
38239
  if (!scanned.length) return { status: "absent" };
38183
38240
  if (!exists(source)) return { status: "absent" };
38184
38241
  const runScope = resolveArtifactRunScope(env);
@@ -38186,7 +38243,7 @@ function archiveWorktreeTmpArtifacts(args, deps = {}) {
38186
38243
  const stamp = now().toISOString().replace(/[:.]/g, "-");
38187
38244
  const dest = resolveRoot(args.primaryRoot, "worktree-artifacts", runScope, branchSlug, stamp, "tmp");
38188
38245
  try {
38189
- mkdirp((0, import_node_path38.dirname)(dest));
38246
+ mkdirp((0, import_node_path39.dirname)(dest));
38190
38247
  copyDir(source, dest);
38191
38248
  if (!exists(dest)) return { status: "failed", error: `archive write left no directory at ${dest}` };
38192
38249
  const bytes = scanned.reduce((sum, e) => sum + e.bytes, 0);
@@ -38255,7 +38312,7 @@ function normPath2(p) {
38255
38312
  return p.replace(/\\/g, "/").replace(/\/+$/, "");
38256
38313
  }
38257
38314
  function unlinkNodeModulesJunction(wtPath) {
38258
- const nm = (0, import_node_path39.join)(wtPath, "node_modules");
38315
+ const nm = (0, import_node_path40.join)(wtPath, "node_modules");
38259
38316
  try {
38260
38317
  if ((0, import_node_fs42.lstatSync)(nm).isSymbolicLink()) (0, import_node_fs42.rmdirSync)(nm);
38261
38318
  return { ok: true };
@@ -38392,7 +38449,7 @@ async function preCleanWorktreeForRemoval(wtPath, execGit) {
38392
38449
  }
38393
38450
  async function listNestedIgnoredNodeModules(wtPath, execGit) {
38394
38451
  const out = await execGit(["-C", wtPath, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory"]).catch(() => "");
38395
- return out.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.endsWith("node_modules/") && line !== "node_modules/").map((line) => (0, import_node_path39.join)(wtPath, line.slice(0, -1)));
38452
+ return out.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.endsWith("node_modules/") && line !== "node_modules/").map((line) => (0, import_node_path40.join)(wtPath, line.slice(0, -1)));
38396
38453
  }
38397
38454
  function safeRemoveTree(path2) {
38398
38455
  const stat4 = (0, import_node_fs42.lstatSync)(path2);
@@ -38405,7 +38462,7 @@ function safeRemoveTree(path2) {
38405
38462
  return;
38406
38463
  }
38407
38464
  if (stat4.isDirectory()) {
38408
- for (const entry of (0, import_node_fs42.readdirSync)(path2)) safeRemoveTree((0, import_node_path39.join)(path2, entry));
38465
+ for (const entry of (0, import_node_fs42.readdirSync)(path2)) safeRemoveTree((0, import_node_path40.join)(path2, entry));
38409
38466
  (0, import_node_fs42.rmdirSync)(path2);
38410
38467
  return;
38411
38468
  }
@@ -38448,7 +38505,7 @@ function unlinkEscapingReparsePoints(root, primaryRoot) {
38448
38505
  return { ok: false, error: `cannot scan ${normPath2(dir)} for reparse points: ${errorMessage(e)}` };
38449
38506
  }
38450
38507
  for (const entry of entries) {
38451
- const child2 = (0, import_node_path39.join)(dir, entry.name);
38508
+ const child2 = (0, import_node_path40.join)(dir, entry.name);
38452
38509
  if (entry.isSymbolicLink()) {
38453
38510
  let target = "";
38454
38511
  try {
@@ -38482,7 +38539,7 @@ async function describePreCleanFailure(wtPath, execGit, error) {
38482
38539
  const more = remaining.length > 10 ? ` (+${remaining.length - 10} more)` : "";
38483
38540
  const quote = (path2) => path2.replace(/'/g, "''");
38484
38541
  const nested = remaining.find((path2) => path2.endsWith("node_modules/") && path2 !== "node_modules/");
38485
- const remediation = remaining.includes("node_modules/") ? `jervcode worktree-node-modules-cleanup --worktree '${quote(wtPath)}'` : nested ? `Remove-Item -LiteralPath '${quote((0, import_node_path39.join)(wtPath, nested.slice(0, -1)))}' -Recurse -Force` : void 0;
38542
+ const remediation = remaining.includes("node_modules/") ? `jervcode worktree-node-modules-cleanup --worktree '${quote(wtPath)}'` : nested ? `Remove-Item -LiteralPath '${quote((0, import_node_path40.join)(wtPath, nested.slice(0, -1)))}' -Recurse -Force` : void 0;
38486
38543
  return { ok: false, error: `${error}; remaining ignored paths: ${shown}${more}`, ...remediation ? { remediation } : {} };
38487
38544
  }
38488
38545
  function formatWorktreeRemovalFailureDetail(options) {
@@ -38776,7 +38833,7 @@ async function cleanupPrMergeLocalBranch(branch, options) {
38776
38833
  const preHelperGuard = unlinkEscapingReparsePoints(wtPath, options.primaryRoot);
38777
38834
  if (!preHelperGuard.ok) return refuseReparseEscape(preHelperGuard.error);
38778
38835
  unlinkedReparsePoints.push(...preHelperGuard.unlinked);
38779
- if (pathExists((0, import_node_path39.join)(wtPath, "node_modules"))) {
38836
+ if (pathExists((0, import_node_path40.join)(wtPath, "node_modules"))) {
38780
38837
  const nmRemoved = await (options.removeRealNodeModules ?? ((p) => removeWorktreeNodeModulesViaHelper(p, { cwd: mainWorktreePath })))(wtPath);
38781
38838
  if (!nmRemoved.ok) {
38782
38839
  report.worktree = {
@@ -38943,10 +39000,10 @@ function argvWantsJson2() {
38943
39000
  return process.argv.some((a) => a === "--json" || a.startsWith("--json="));
38944
39001
  }
38945
39002
  function hubRoot() {
38946
- const fromPkg = (0, import_node_path40.join)(__dirname, "..", "..");
39003
+ const fromPkg = (0, import_node_path41.join)(__dirname, "..", "..");
38947
39004
  const marker = "skills/bootstrap/seeds/manifest.json";
38948
- if ((0, import_node_fs43.existsSync)((0, import_node_path40.join)(fromPkg, marker))) return fromPkg;
38949
- if ((0, import_node_fs43.existsSync)((0, import_node_path40.join)(process.cwd(), marker))) return process.cwd();
39005
+ if ((0, import_node_fs43.existsSync)((0, import_node_path41.join)(fromPkg, marker))) return fromPkg;
39006
+ if ((0, import_node_fs43.existsSync)((0, import_node_path41.join)(process.cwd(), marker))) return process.cwd();
38950
39007
  return null;
38951
39008
  }
38952
39009
  function ciAuditDeps() {
@@ -38958,7 +39015,7 @@ function ciAuditDeps() {
38958
39015
  getProjectMeta: async (slug) => fetchProjectBySlug(slug, registryClientDeps(await cfgPromise)),
38959
39016
  readSeedFile: (path2) => {
38960
39017
  if (!root) return null;
38961
- const fullPath = (0, import_node_path40.join)(root, path2);
39018
+ const fullPath = (0, import_node_path41.join)(root, path2);
38962
39019
  return (0, import_node_fs43.existsSync)(fullPath) ? (0, import_node_fs43.readFileSync)(fullPath, "utf8") : null;
38963
39020
  }
38964
39021
  };
@@ -39109,7 +39166,7 @@ function registerCollaborationCommands(program3) {
39109
39166
  try {
39110
39167
  title = await resolveIssueTitle(
39111
39168
  { title: opts.title, titleFile: opts.titleFile },
39112
- { readFile: import_promises7.readFile, readStdin }
39169
+ { readFile: import_promises8.readFile, readStdin }
39113
39170
  );
39114
39171
  } catch (e) {
39115
39172
  return fail(
@@ -39151,8 +39208,8 @@ function registerCollaborationCommands(program3) {
39151
39208
  let surfaceFlagLabel;
39152
39209
  try {
39153
39210
  issueType = resolveCreateType(o.type, "issue create", o.label);
39154
- title = await resolveIssueTitle({ title: o.title, titleFile: o.titleFile }, { readFile: import_promises7.readFile, readStdin });
39155
- body = await resolveIssueBody({ body: o.body, bodyFile: o.bodyFile }, { readFile: import_promises7.readFile, readStdin });
39211
+ title = await resolveIssueTitle({ title: o.title, titleFile: o.titleFile }, { readFile: import_promises8.readFile, readStdin });
39212
+ body = await resolveIssueBody({ body: o.body, bodyFile: o.bodyFile }, { readFile: import_promises8.readFile, readStdin });
39156
39213
  if (o.idempotencyKey) body = appendIdempotencyMarker(body, o.idempotencyKey);
39157
39214
  priority = resolveCreatePriority(o.priority, "issue create");
39158
39215
  extraLabels = [...o.label ?? []];
@@ -39360,7 +39417,7 @@ function registerCollaborationCommands(program3) {
39360
39417
  }
39361
39418
  let body;
39362
39419
  try {
39363
- body = await resolveIssueBody({ body: o.body, bodyFile: o.bodyFile }, { readFile: import_promises7.readFile, readStdin });
39420
+ body = await resolveIssueBody({ body: o.body, bodyFile: o.bodyFile }, { readFile: import_promises8.readFile, readStdin });
39364
39421
  } catch (e) {
39365
39422
  return fail(`issue comment: ${e.message}`);
39366
39423
  }
@@ -39420,8 +39477,8 @@ ${list}`);
39420
39477
  let title;
39421
39478
  const sourceRepo = o.repo ?? await resolveRepo(void 0);
39422
39479
  try {
39423
- title = await resolveIssueTitle({ title: o.title, titleFile: o.titleFile }, { readFile: import_promises7.readFile, readStdin });
39424
- body = await resolveIssueBody({ body: o.body, bodyFile: o.bodyFile }, { readFile: import_promises7.readFile, readStdin });
39480
+ title = await resolveIssueTitle({ title: o.title, titleFile: o.titleFile }, { readFile: import_promises8.readFile, readStdin });
39481
+ body = await resolveIssueBody({ body: o.body, bodyFile: o.bodyFile }, { readFile: import_promises8.readFile, readStdin });
39425
39482
  priority = resolveCreatePriority(o.priority, "report");
39426
39483
  if (!ISSUE_TYPES.includes(o.type)) {
39427
39484
  throw new Error(`unknown issue type "${o.type}" \u2014 expected one of: ${ISSUE_TYPES.join(", ")}`);
@@ -39476,8 +39533,8 @@ ${list}`);
39476
39533
  let args;
39477
39534
  try {
39478
39535
  skill = assertSkillName(o.skill);
39479
- rawBody = await resolveIssueBody({ body: o.body, bodyFile: o.bodyFile }, { readFile: import_promises7.readFile, readStdin });
39480
- const rawTitle = await resolveIssueTitle({ title: o.title, titleFile: o.titleFile }, { readFile: import_promises7.readFile, readStdin });
39536
+ rawBody = await resolveIssueBody({ body: o.body, bodyFile: o.bodyFile }, { readFile: import_promises8.readFile, readStdin });
39537
+ const rawTitle = await resolveIssueTitle({ title: o.title, titleFile: o.titleFile }, { readFile: import_promises8.readFile, readStdin });
39481
39538
  title = buildSkillLessonTitle(skill, rawTitle);
39482
39539
  priority = resolveCreatePriority(o.priority, "skill-lesson");
39483
39540
  body = buildSkillLessonBody(rawBody, sourceRepo, pluginSha);
@@ -39534,12 +39591,12 @@ ${list}`);
39534
39591
  console.log(JSON.stringify({ ...created, projectItemId, onBoard }));
39535
39592
  });
39536
39593
  const pr = program3.command("pr").description("pull requests \u2014 reliable create with structured output");
39537
- withExamples(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)").option("--draft", "open the PR in draft state (#2667)").option("--json", "machine-readable output (default; accepted for parity)").action(async (o) => {
39594
+ withExamples(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)").option("--draft", "open the PR in draft state (#2667)").option("--no-zeroci", "skip minting the ZeroCI receipt. By default pr create mints it first, which runs the gate commands locally \u2014 pr create then takes as long as this seat needs for its own gate run, and the CI gate skips them (#6284)").option("--json", "machine-readable output (default; accepted for parity)").action(async (o) => {
39538
39595
  let body;
39539
39596
  let title;
39540
39597
  try {
39541
- title = await resolveIssueTitle({ title: o.title, titleFile: o.titleFile }, { readFile: import_promises7.readFile, readStdin });
39542
- body = await resolveIssueBody({ body: o.body, bodyFile: o.bodyFile }, { readFile: import_promises7.readFile, readStdin });
39598
+ title = await resolveIssueTitle({ title: o.title, titleFile: o.titleFile }, { readFile: import_promises8.readFile, readStdin });
39599
+ body = await resolveIssueBody({ body: o.body, bodyFile: o.bodyFile }, { readFile: import_promises8.readFile, readStdin });
39543
39600
  } catch (e) {
39544
39601
  return fail(`pr create: ${e.message}`, e instanceof TextArgError ? { code: e.code, offending_flag: e.offendingFlag } : void 0);
39545
39602
  }
@@ -39559,6 +39616,9 @@ ${list}`);
39559
39616
  }
39560
39617
  const claimRefusal = await prCreateClaimRefusal(body, o.repo);
39561
39618
  if (claimRefusal) return fail(claimRefusal);
39619
+ const zeroCiWarn = await mintZeroCiReceipt({ repo: o.repo, zeroci: o.zeroci }, createPrCreateZeroCiDeps());
39620
+ if (zeroCiWarn) process.stderr.write(`${zeroCiWarn}
39621
+ `);
39562
39622
  const created = await ghCreate(buildPrArgs({ title, body, base: o.base, head: o.head, repo: o.repo, draft: o.draft }));
39563
39623
  if (isGhCreateRateLimited(created)) {
39564
39624
  console.log(JSON.stringify(created));
@@ -39602,11 +39662,11 @@ ${list}`);
39602
39662
  }
39603
39663
  });
39604
39664
  async function listCiWorkflowPaths(cwd = process.cwd()) {
39605
- const wfDir = (0, import_node_path40.join)(cwd, ".github", "workflows");
39665
+ const wfDir = (0, import_node_path41.join)(cwd, ".github", "workflows");
39606
39666
  if (!(0, import_node_fs43.existsSync)(wfDir)) return [];
39607
39667
  return (0, import_node_fs43.readdirSync)(wfDir).filter((name) => /\.(ya?ml)$/i.test(name)).filter((name) => {
39608
39668
  try {
39609
- return workflowReportsPrChecks((0, import_node_fs43.readFileSync)((0, import_node_path40.join)(wfDir, name), "utf8"));
39669
+ return workflowReportsPrChecks((0, import_node_fs43.readFileSync)((0, import_node_path41.join)(wfDir, name), "utf8"));
39610
39670
  } catch {
39611
39671
  return true;
39612
39672
  }
@@ -40094,7 +40154,7 @@ ${list}`);
40094
40154
  const remote = foreignCwd ? `https://github.com/${targetRepo2}.git` : "origin";
40095
40155
  let foreignCheckout;
40096
40156
  if (foreignCwd) {
40097
- const sibling = (0, import_node_path40.join)((0, import_node_path40.dirname)(beforeWorktrees[0]?.path || startingPath || process.cwd()), targetRepo2.split("/")[1]);
40157
+ const sibling = (0, import_node_path41.join)((0, import_node_path41.dirname)(beforeWorktrees[0]?.path || startingPath || process.cwd()), targetRepo2.split("/")[1]);
40098
40158
  const siblingRepo = repoFromRemoteUrl(await gitOut(["-C", sibling, "remote", "get-url", "origin"]).catch(() => ""));
40099
40159
  if (siblingRepo?.toLowerCase() === targetRepo2.toLowerCase()) {
40100
40160
  const siblingWorktrees = await execFileP("git", ["-C", sibling, "worktree", "list", "--porcelain"], { timeout: GIT_TIMEOUT_MS }).then((r) => parseGitWorktreePorcelain(r.stdout)).catch(() => void 0);
@@ -40464,7 +40524,7 @@ async function resolveWhoami(deps) {
40464
40524
  }
40465
40525
 
40466
40526
  // src/command-register-developer.ts
40467
- var import_node_path45 = require("node:path");
40527
+ var import_node_path46 = require("node:path");
40468
40528
 
40469
40529
  // src/wave-land.ts
40470
40530
  function planWaveLand(prs) {
@@ -40721,17 +40781,17 @@ var import_node_child_process17 = require("node:child_process");
40721
40781
  var import_node_crypto12 = require("node:crypto");
40722
40782
  var import_node_fs46 = require("node:fs");
40723
40783
  var import_node_os21 = require("node:os");
40724
- var import_node_path42 = require("node:path");
40784
+ var import_node_path43 = require("node:path");
40725
40785
 
40726
40786
  // ../scripts/distribution-digest.mjs
40727
40787
  var import_node_crypto11 = require("node:crypto");
40728
40788
  var import_node_fs45 = require("node:fs");
40729
- var import_node_path41 = require("node:path");
40789
+ var import_node_path42 = require("node:path");
40730
40790
  var slash = (value) => value.replaceAll("\\", "/");
40731
40791
  function repoPath(root, declaredPath, label) {
40732
- const absoluteRoot = (0, import_node_path41.resolve)(root);
40733
- const target = (0, import_node_path41.resolve)(root, declaredPath);
40734
- if (target !== absoluteRoot && !target.startsWith(`${absoluteRoot}${import_node_path41.sep}`)) {
40792
+ const absoluteRoot = (0, import_node_path42.resolve)(root);
40793
+ const target = (0, import_node_path42.resolve)(root, declaredPath);
40794
+ if (target !== absoluteRoot && !target.startsWith(`${absoluteRoot}${import_node_path42.sep}`)) {
40735
40795
  throw new Error(`${label} ${declaredPath} escapes the repository root`);
40736
40796
  }
40737
40797
  return target;
@@ -40845,7 +40905,7 @@ function walkFiles(root) {
40845
40905
  const files = [];
40846
40906
  const walk2 = (directory) => {
40847
40907
  for (const entry of (0, import_node_fs46.readdirSync)(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
40848
- const child2 = (0, import_node_path42.join)(directory, entry.name);
40908
+ const child2 = (0, import_node_path43.join)(directory, entry.name);
40849
40909
  if (entry.isDirectory()) walk2(child2);
40850
40910
  else files.push(child2);
40851
40911
  }
@@ -40855,10 +40915,10 @@ function walkFiles(root) {
40855
40915
  }
40856
40916
  function bomPathFor(root) {
40857
40917
  try {
40858
- const registry2 = JSON.parse((0, import_node_fs46.readFileSync)((0, import_node_path42.join)(root, "surfaces.json"), "utf8"));
40859
- return (0, import_node_path42.join)(root, registry2?.sharedAgentCore?.releaseMetadata?.bomPath ?? "distribution-bom.json");
40918
+ const registry2 = JSON.parse((0, import_node_fs46.readFileSync)((0, import_node_path43.join)(root, "surfaces.json"), "utf8"));
40919
+ return (0, import_node_path43.join)(root, registry2?.sharedAgentCore?.releaseMetadata?.bomPath ?? "distribution-bom.json");
40860
40920
  } catch {
40861
- return (0, import_node_path42.join)(root, "distribution-bom.json");
40921
+ return (0, import_node_path43.join)(root, "distribution-bom.json");
40862
40922
  }
40863
40923
  }
40864
40924
  function rebuildTo(packageRoot, outDir) {
@@ -40871,28 +40931,28 @@ function rebuildTo(packageRoot, outDir) {
40871
40931
  });
40872
40932
  }
40873
40933
  function runDistStatus(root) {
40874
- const stage = (0, import_node_fs46.mkdtempSync)((0, import_node_path42.join)((0, import_node_os21.tmpdir)(), "mmi-dist-drift-"));
40934
+ const stage = (0, import_node_fs46.mkdtempSync)((0, import_node_path43.join)((0, import_node_os21.tmpdir)(), "mmi-dist-drift-"));
40875
40935
  let overlayCount = 0;
40876
40936
  try {
40877
- const cliOut = (0, import_node_path42.join)(stage, "cli-dist");
40878
- const hubOut = (0, import_node_path42.join)(stage, "hub-dist");
40879
- rebuildTo((0, import_node_path42.join)(root, "cli"), cliOut);
40880
- rebuildTo((0, import_node_path42.join)(root, "updater"), hubOut);
40937
+ const cliOut = (0, import_node_path43.join)(stage, "cli-dist");
40938
+ const hubOut = (0, import_node_path43.join)(stage, "hub-dist");
40939
+ rebuildTo((0, import_node_path43.join)(root, "cli"), cliOut);
40940
+ rebuildTo((0, import_node_path43.join)(root, "updater"), hubOut);
40881
40941
  const outDirFor = (packageDir) => packageDir === "cli" ? cliOut : hubOut;
40882
40942
  const rebuilt = (path2) => {
40883
40943
  const spec = DIST_ARTIFACTS.find((entry) => entry.path === path2);
40884
- return spec ? readOrNull((0, import_node_path42.join)(outDirFor(spec.packageDir), spec.output)) : null;
40944
+ return spec ? readOrNull((0, import_node_path43.join)(outDirFor(spec.packageDir), spec.output)) : null;
40885
40945
  };
40886
- const committed = (path2) => readOrNull((0, import_node_path42.join)(root, path2));
40887
- const tree = (path2) => readOrNull((0, import_node_path42.join)(root, path2));
40888
- const distRoot = (0, import_node_path42.join)(root, "cli", "dist");
40889
- const distTree = () => walkFiles(distRoot).map((absolute) => `cli/dist/${(0, import_node_path42.relative)(distRoot, absolute).replaceAll("\\", "/")}`);
40946
+ const committed = (path2) => readOrNull((0, import_node_path43.join)(root, path2));
40947
+ const tree = (path2) => readOrNull((0, import_node_path43.join)(root, path2));
40948
+ const distRoot = (0, import_node_path43.join)(root, "cli", "dist");
40949
+ const distTree = () => walkFiles(distRoot).map((absolute) => `cli/dist/${(0, import_node_path43.relative)(distRoot, absolute).replaceAll("\\", "/")}`);
40890
40950
  const bom = JSON.parse((0, import_node_fs46.readFileSync)(bomPathFor(root), "utf8"));
40891
40951
  const digest = (entries) => {
40892
- const overlay = (0, import_node_path42.join)(stage, `overlay-${overlayCount++}`);
40952
+ const overlay = (0, import_node_path43.join)(stage, `overlay-${overlayCount++}`);
40893
40953
  for (const entry of entries) {
40894
- const target = (0, import_node_path42.join)(overlay, entry.path);
40895
- (0, import_node_fs46.mkdirSync)((0, import_node_path42.dirname)(target), { recursive: true });
40954
+ const target = (0, import_node_path43.join)(overlay, entry.path);
40955
+ (0, import_node_fs46.mkdirSync)((0, import_node_path43.dirname)(target), { recursive: true });
40896
40956
  (0, import_node_fs46.writeFileSync)(target, entry.bytes);
40897
40957
  }
40898
40958
  return digestPackedFiles(overlay, entries.map((entry) => entry.path));
@@ -40970,8 +41030,8 @@ function registerEdgeCommands(program3) {
40970
41030
  }
40971
41031
 
40972
41032
  // src/schedules-lift-command.ts
40973
- var import_promises8 = require("node:fs/promises");
40974
- var import_node_path43 = require("node:path");
41033
+ var import_promises9 = require("node:fs/promises");
41034
+ var import_node_path44 = require("node:path");
40975
41035
  var DEFAULT_WORKFLOWS_DIR = ".github/workflows";
40976
41036
  var SCHEDULE_REPO_RE = /^[A-Za-z0-9_.-]+$/;
40977
41037
  var SchedulesLiftUsageError = class extends Error {
@@ -40991,14 +41051,14 @@ var RegistryUnreachableError = class extends Error {
40991
41051
  async function readWorkflowFiles(dir) {
40992
41052
  let names;
40993
41053
  try {
40994
- names = await (0, import_promises8.readdir)(dir);
41054
+ names = await (0, import_promises9.readdir)(dir);
40995
41055
  } catch {
40996
41056
  return [];
40997
41057
  }
40998
41058
  const files = [];
40999
41059
  for (const name of names.sort()) {
41000
41060
  if (!/\.ya?ml$/.test(name)) continue;
41001
- files.push({ path: `.github/workflows/${name}`, text: await (0, import_promises8.readFile)((0, import_node_path43.join)(dir, name), "utf8") });
41061
+ files.push({ path: `.github/workflows/${name}`, text: await (0, import_promises9.readFile)((0, import_node_path44.join)(dir, name), "utf8") });
41002
41062
  }
41003
41063
  return files;
41004
41064
  }
@@ -41082,7 +41142,7 @@ function registerSchedulesLiftCommand(program3, deps = {}) {
41082
41142
  // src/spawn-policy-core.ts
41083
41143
  var import_node_child_process18 = require("node:child_process");
41084
41144
  var import_node_fs47 = require("node:fs");
41085
- var import_node_path44 = require("node:path");
41145
+ var import_node_path45 = require("node:path");
41086
41146
  var SPAWNERS = ["spawn", "spawnSync", "exec", "execSync", "execFile", "execFileSync"];
41087
41147
  var CALL_SOURCE = String.raw`(^|[^.\w$])(${SPAWNERS.join("|")})\s*\(`;
41088
41148
  var SOURCE_EXT = /\.(ts|mts|cts|js|mjs|cjs)$/;
@@ -41168,7 +41228,7 @@ function runSpawnPolicy(root) {
41168
41228
  for (const file of files) {
41169
41229
  let raw;
41170
41230
  try {
41171
- raw = (0, import_node_fs47.readFileSync)((0, import_node_path44.join)(root, file), "utf8");
41231
+ raw = (0, import_node_fs47.readFileSync)((0, import_node_path45.join)(root, file), "utf8");
41172
41232
  } catch {
41173
41233
  continue;
41174
41234
  }
@@ -41188,7 +41248,7 @@ function runSpawnPolicy(root) {
41188
41248
  function registerDeveloperCommands(program3) {
41189
41249
  const rules = program3.command("rules").description("org-managed .gitignore delivery");
41190
41250
  rules.command("gitignore").option("--write", "upsert the managed block into .gitignore (default: check only, non-zero exit on drift)").option("--json", "machine-readable output").description("verify (or --write) this repo's org-managed .gitignore block matches the SSOT").action((opts) => {
41191
- const path2 = (0, import_node_path45.join)(process.cwd(), ".gitignore");
41251
+ const path2 = (0, import_node_path46.join)(process.cwd(), ".gitignore");
41192
41252
  const current = (0, import_node_fs48.existsSync)(path2) ? (0, import_node_fs48.readFileSync)(path2, "utf8") : null;
41193
41253
  const plan = planManagedGitignore(current);
41194
41254
  const drift = [...plan.added.map((l) => `+${l}`), ...plan.removed.map((l) => `-${l}`)].join(", ") || "block normalize";
@@ -41448,10 +41508,10 @@ function registerDeveloperCommands(program3) {
41448
41508
  }
41449
41509
 
41450
41510
  // src/command-register-train-operations.ts
41451
- var import_promises10 = require("node:fs/promises");
41511
+ var import_promises11 = require("node:fs/promises");
41452
41512
 
41453
41513
  // src/hotfix-apply.ts
41454
- var import_promises9 = require("node:fs/promises");
41514
+ var import_promises10 = require("node:fs/promises");
41455
41515
 
41456
41516
  // src/slack-alert.ts
41457
41517
  var SSM_REGION = "eu-central-1";
@@ -42235,7 +42295,7 @@ async function runHotfixRelease(deps, versionInput, options = {}, doctor = runTr
42235
42295
  }
42236
42296
  let lines2;
42237
42297
  try {
42238
- lines2 = summaryFileLines(await (deps.readFile ?? ((p) => (0, import_promises9.readFile)(p, "utf8")))(options.announceSummaryFile));
42298
+ lines2 = summaryFileLines(await (deps.readFile ?? ((p) => (0, import_promises10.readFile)(p, "utf8")))(options.announceSummaryFile));
42239
42299
  } catch (e) {
42240
42300
  throw new Error(`could not read --announce-summary-file ${options.announceSummaryFile}: ${e.message} \u2014 see docs/Guides/train-troubleshooting.md#announce-summary-missing`);
42241
42301
  }
@@ -42794,7 +42854,7 @@ function checkHotfixCarries(options) {
42794
42854
 
42795
42855
  // src/train-commands.ts
42796
42856
  var import_node_fs49 = require("node:fs");
42797
- var import_node_path46 = require("node:path");
42857
+ var import_node_path47 = require("node:path");
42798
42858
  var INVOKED_ARGV = process.argv.slice(2);
42799
42859
  var RELEASE_BUMP_INTENTS = ["major", "minor", "patch"];
42800
42860
  function resolveReleaseBumpIntent(raw) {
@@ -42806,7 +42866,7 @@ function resolveReleaseBumpIntent(raw) {
42806
42866
  }
42807
42867
  function readRepoVersion() {
42808
42868
  try {
42809
- return JSON.parse((0, import_node_fs49.readFileSync)((0, import_node_path46.join)(process.cwd(), ".claude-plugin", "plugin.json"), "utf8")).version || void 0;
42869
+ return JSON.parse((0, import_node_fs49.readFileSync)((0, import_node_path47.join)(process.cwd(), ".claude-plugin", "plugin.json"), "utf8")).version || void 0;
42810
42870
  } catch {
42811
42871
  return void 0;
42812
42872
  }
@@ -42969,8 +43029,8 @@ function trainApplyDeps() {
42969
43029
  // Slack release announcement (#883): Hub-only + best-effort inside announceRelease itself.
42970
43030
  announce: (args) => announceRelease({
42971
43031
  run: async (file, cmdArgs) => (await execFileP(file, cmdArgs, { timeout: GH_TRAIN_TIMEOUT_MS })).stdout,
42972
- readFile: (path2) => (0, import_promises10.readFile)(path2, "utf8"),
42973
- removeFile: (path2) => (0, import_promises10.unlink)(path2)
43032
+ readFile: (path2) => (0, import_promises11.readFile)(path2, "utf8"),
43033
+ removeFile: (path2) => (0, import_promises11.unlink)(path2)
42974
43034
  }, args),
42975
43035
  // #4713 (I/O-boundary census): `null` used to mean BOTH "this project configures no edge domains"
42976
43036
  // (a real answer) and "the registry read missed" — so a release verdict printed an environments block
@@ -43356,7 +43416,7 @@ function registerTrainOperationsCommands(program3, runProjectInfoSyncCallback) {
43356
43416
  }
43357
43417
  let summaryLines;
43358
43418
  try {
43359
- summaryLines = summaryFileLines(await (0, import_promises10.readFile)(o.announceSummaryFile, "utf8"));
43419
+ summaryLines = summaryFileLines(await (0, import_promises11.readFile)(o.announceSummaryFile, "utf8"));
43360
43420
  } catch (e) {
43361
43421
  return fail(`release: could not read --announce-summary-file ${o.announceSummaryFile}: ${e.message} \u2014 see docs/Guides/train-troubleshooting.md#announce-summary-missing`);
43362
43422
  }
@@ -43550,7 +43610,7 @@ ${r.stderr ?? ""}`).catch(() => "");
43550
43610
  var ENV_HEAL_LOCK_STALE_MS = 10 * 6e4;
43551
43611
  var ENV_HEAL_LOCK_MAX_WAIT_MS = 2 * 6e4;
43552
43612
  function envHealLockPath(home) {
43553
- return (0, import_node_path47.join)(home, ".claude", "plugins", ".mmi-env-heal.lock");
43613
+ return (0, import_node_path48.join)(home, ".claude", "plugins", ".mmi-env-heal.lock");
43554
43614
  }
43555
43615
  async function withEnvHealLock(what, run) {
43556
43616
  try {
@@ -43721,7 +43781,7 @@ function mmiDoctorDeps(opts = {}) {
43721
43781
  // has no generated routing index would
43722
43782
  // get a permanent — demanding an artifact it never asked for.
43723
43783
  docsIndexState: (root) => {
43724
- if (!(0, import_node_fs50.existsSync)((0, import_node_path47.join)(root, DOCS_INDEX_PATH))) return void 0;
43784
+ if (!(0, import_node_fs50.existsSync)((0, import_node_path48.join)(root, DOCS_INDEX_PATH))) return void 0;
43725
43785
  const real = createDocsIndexDeps(root);
43726
43786
  let docs;
43727
43787
  const listDocs = () => docs ??= real.listDocs();
@@ -43730,7 +43790,7 @@ function mmiDoctorDeps(opts = {}) {
43730
43790
  },
43731
43791
  // #4168: working-tree heal — write if drifted, then re-check. Commit remains the operator's step.
43732
43792
  healDocsIndex: (root) => {
43733
- if (!(0, import_node_fs50.existsSync)((0, import_node_path47.join)(root, DOCS_INDEX_PATH))) return { drift: false, docCount: 0 };
43793
+ if (!(0, import_node_fs50.existsSync)((0, import_node_path48.join)(root, DOCS_INDEX_PATH))) return { drift: false, docCount: 0 };
43734
43794
  const real = createDocsIndexDeps(root);
43735
43795
  let docs;
43736
43796
  const listDocs = () => docs ??= real.listDocs();
@@ -44609,16 +44669,16 @@ function ciAuditDeps2() {
44609
44669
  // gate re-seed step is skipped gracefully rather than failing mid-run.
44610
44670
  readSeedFile: (path2) => {
44611
44671
  if (!root) return null;
44612
- const fullPath = (0, import_node_path47.join)(root, path2);
44672
+ const fullPath = (0, import_node_path48.join)(root, path2);
44613
44673
  return (0, import_node_fs50.existsSync)(fullPath) ? (0, import_node_fs50.readFileSync)(fullPath, "utf8") : null;
44614
44674
  }
44615
44675
  };
44616
44676
  }
44617
44677
  function hubRoot2() {
44618
- const fromPkg = (0, import_node_path47.join)(__dirname, "..", "..");
44678
+ const fromPkg = (0, import_node_path48.join)(__dirname, "..", "..");
44619
44679
  const marker = "skills/bootstrap/seeds/manifest.json";
44620
- if ((0, import_node_fs50.existsSync)((0, import_node_path47.join)(fromPkg, marker))) return fromPkg;
44621
- if ((0, import_node_fs50.existsSync)((0, import_node_path47.join)(process.cwd(), marker))) return process.cwd();
44680
+ if ((0, import_node_fs50.existsSync)((0, import_node_path48.join)(fromPkg, marker))) return fromPkg;
44681
+ if ((0, import_node_fs50.existsSync)((0, import_node_path48.join)(process.cwd(), marker))) return process.cwd();
44622
44682
  return null;
44623
44683
  }
44624
44684
  registerQueryCommands(program2);
@@ -44757,7 +44817,7 @@ function directoryBytes(path2) {
44757
44817
  return 0;
44758
44818
  }
44759
44819
  for (const entry of entries) {
44760
- const child2 = (0, import_node_path47.join)(path2, entry.name);
44820
+ const child2 = (0, import_node_path48.join)(path2, entry.name);
44761
44821
  if (entry.isDirectory()) total += directoryBytes(child2);
44762
44822
  else {
44763
44823
  try {
@@ -44787,7 +44847,7 @@ function pluginCacheFsDeps(configRoot, dirBytes) {
44787
44847
  dirBytes,
44788
44848
  listStagingDirs: (root) => (0, import_node_fs50.readdirSync)(root, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => {
44789
44849
  try {
44790
- return { name: d.name, mtimeMs: newestMtimeMs((0, import_node_path47.join)(root, d.name), listDirEntries, (p) => (0, import_node_fs50.statSync)(p).mtimeMs) };
44850
+ return { name: d.name, mtimeMs: newestMtimeMs((0, import_node_path48.join)(root, d.name), listDirEntries, (p) => (0, import_node_fs50.statSync)(p).mtimeMs) };
44791
44851
  } catch {
44792
44852
  return { name: d.name, mtimeMs: Date.now() };
44793
44853
  }
@@ -44801,7 +44861,7 @@ function stagingApplyFsGuard(configRoot) {
44801
44861
  return {
44802
44862
  referencedPaths: () => readInstalledPluginRefs(configRoot),
44803
44863
  mtimeMs: (name) => {
44804
- const p = (0, import_node_path47.join)(stagingRoot, name);
44864
+ const p = (0, import_node_path48.join)(stagingRoot, name);
44805
44865
  if (!(0, import_node_fs50.existsSync)(p)) return null;
44806
44866
  try {
44807
44867
  return newestMtimeMs(p, listDirEntries, (q) => (0, import_node_fs50.statSync)(q).mtimeMs);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "4.3.19",
3
+ "version": "4.3.20",
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",