@mutmutco/cli 3.112.0 → 3.114.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 +232 -87
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -5001,7 +5001,7 @@ var program = new Command();
|
|
|
5001
5001
|
// src/index.ts
|
|
5002
5002
|
var import_promises11 = require("node:fs/promises");
|
|
5003
5003
|
var import_node_fs46 = require("node:fs");
|
|
5004
|
-
var
|
|
5004
|
+
var import_node_child_process20 = require("node:child_process");
|
|
5005
5005
|
|
|
5006
5006
|
// src/cli-shared.ts
|
|
5007
5007
|
var import_node_child_process3 = require("node:child_process");
|
|
@@ -8820,6 +8820,12 @@ var AUTO_UPDATE_TOGGLE_STEPS = "`/plugin` \u2192 Marketplaces tab \u2192 select
|
|
|
8820
8820
|
var CATALOG_CONTENT_REF = "main";
|
|
8821
8821
|
var CATALOG_REF_PIN_STEPS = `add \`"ref": "${CATALOG_CONTENT_REF}"\` to this marketplace's \`source\` in ~/.claude/plugins/known_marketplaces.json, then restart Claude`;
|
|
8822
8822
|
var PIN_HEAL_COMMAND = "run `mmi-cli doctor`";
|
|
8823
|
+
var HOST_RUNNING_REMEDY = "quit Claude Code, then run `mmi-cli doctor`";
|
|
8824
|
+
function marketplaceRemedyText(remedy, action, manualSteps) {
|
|
8825
|
+
if (remedy === "manual") return manualSteps;
|
|
8826
|
+
if (remedy === "host-running") return `${HOST_RUNNING_REMEDY} to ${action}`;
|
|
8827
|
+
return `${PIN_HEAL_COMMAND} to ${action}`;
|
|
8828
|
+
}
|
|
8823
8829
|
var ORG_MARKETPLACE_PINS = { autoUpdate: true, ref: CATALOG_CONTENT_REF };
|
|
8824
8830
|
function resolveCatalogRef(probe) {
|
|
8825
8831
|
const { name, registered, ref, autoUpdate } = probe;
|
|
@@ -8843,7 +8849,7 @@ function resolveCatalogRef(probe) {
|
|
|
8843
8849
|
reason: `no ref pinned \u2014 the catalog is served from the repo's default branch while plugin content is pinned to ${CATALOG_CONTENT_REF}`
|
|
8844
8850
|
};
|
|
8845
8851
|
}
|
|
8846
|
-
function checkMarketplaceAutoUpdate(probe,
|
|
8852
|
+
function checkMarketplaceAutoUpdate(probe, remedy = "manual") {
|
|
8847
8853
|
if (!probe) return null;
|
|
8848
8854
|
const evidence = [`${probe.name}: auto-update ${probe.effective ? "on" : "off"} \u2014 ${probe.reason}`];
|
|
8849
8855
|
if (probe.effective) {
|
|
@@ -8854,11 +8860,11 @@ function checkMarketplaceAutoUpdate(probe, healable = false) {
|
|
|
8854
8860
|
ok: true,
|
|
8855
8861
|
warn: true,
|
|
8856
8862
|
label: `marketplace auto-update (${probe.name})`,
|
|
8857
|
-
detail: `off \u2014 this machine will not pick up a new plugin release on its own; ${
|
|
8863
|
+
detail: `off \u2014 this machine will not pick up a new plugin release on its own; ${marketplaceRemedyText(remedy, "turn it on", `turn it on with ${AUTO_UPDATE_TOGGLE_STEPS}`)}`,
|
|
8858
8864
|
verbose: evidence
|
|
8859
8865
|
};
|
|
8860
8866
|
}
|
|
8861
|
-
function checkMarketplaceCatalogRef(probe,
|
|
8867
|
+
function checkMarketplaceCatalogRef(probe, remedy = "manual") {
|
|
8862
8868
|
if (!probe) return null;
|
|
8863
8869
|
const label = `marketplace catalog ref (${probe.name})`;
|
|
8864
8870
|
const evidence = [`${probe.name}: ${probe.reason}`, `auto-update: ${probe.autoUpdate ? "on" : "off"}`];
|
|
@@ -8875,7 +8881,7 @@ function checkMarketplaceCatalogRef(probe, healable = false) {
|
|
|
8875
8881
|
// ✗ branch carried it in `fix` only because `renderCheckLine` discarded `detail` on failure — one
|
|
8876
8882
|
// row, two conventions, decided by which field would actually print.
|
|
8877
8883
|
detail: `${drift} while auto-update is ON`,
|
|
8878
|
-
fix: `this machine installs plugin releases advertised by a branch nobody released; ${
|
|
8884
|
+
fix: `this machine installs plugin releases advertised by a branch nobody released; ${marketplaceRemedyText(remedy, "pin it", CATALOG_REF_PIN_STEPS)}`,
|
|
8879
8885
|
verbose: evidence
|
|
8880
8886
|
};
|
|
8881
8887
|
}
|
|
@@ -8884,11 +8890,11 @@ function checkMarketplaceCatalogRef(probe, healable = false) {
|
|
|
8884
8890
|
ok: true,
|
|
8885
8891
|
warn: true,
|
|
8886
8892
|
label,
|
|
8887
|
-
detail: `${drift} \u2014 harmless while auto-update is off, and the thing to fix before turning it on; ${
|
|
8893
|
+
detail: `${drift} \u2014 harmless while auto-update is off, and the thing to fix before turning it on; ${marketplaceRemedyText(remedy, "pin it", CATALOG_REF_PIN_STEPS)}`,
|
|
8888
8894
|
verbose: evidence
|
|
8889
8895
|
};
|
|
8890
8896
|
}
|
|
8891
|
-
function marketplaceRows(name, known, settings,
|
|
8897
|
+
function marketplaceRows(name, known, settings, remedy = "manual") {
|
|
8892
8898
|
const { registered, declared, ref } = readKnownMarketplace(known, name);
|
|
8893
8899
|
const autoUpdate = resolveAutoUpdate({
|
|
8894
8900
|
name,
|
|
@@ -8896,9 +8902,9 @@ function marketplaceRows(name, known, settings, healable = false) {
|
|
|
8896
8902
|
declared,
|
|
8897
8903
|
settingsDeclared: readSettingsAutoUpdate(settings, name)
|
|
8898
8904
|
});
|
|
8899
|
-
const rows = [checkMarketplaceAutoUpdate(autoUpdate,
|
|
8905
|
+
const rows = [checkMarketplaceAutoUpdate(autoUpdate, remedy), checkMarketplaceCatalogRef(
|
|
8900
8906
|
resolveCatalogRef({ name, registered, ref, autoUpdate: autoUpdate.effective }),
|
|
8901
|
-
|
|
8907
|
+
remedy
|
|
8902
8908
|
)];
|
|
8903
8909
|
return rows.filter((r) => r !== null);
|
|
8904
8910
|
}
|
|
@@ -11210,11 +11216,114 @@ var import_node_path19 = require("node:path");
|
|
|
11210
11216
|
|
|
11211
11217
|
// src/plugin-guard-io.ts
|
|
11212
11218
|
var import_node_fs17 = require("node:fs");
|
|
11213
|
-
var
|
|
11219
|
+
var import_node_child_process7 = require("node:child_process");
|
|
11214
11220
|
var import_node_path16 = require("node:path");
|
|
11215
11221
|
var import_node_os5 = require("node:os");
|
|
11216
11222
|
var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
|
|
11217
11223
|
|
|
11224
|
+
// src/npm-self-update.ts
|
|
11225
|
+
var import_node_child_process6 = require("node:child_process");
|
|
11226
|
+
var import_node_readline = require("node:readline");
|
|
11227
|
+
function npmSelfUpdateArgs(spec) {
|
|
11228
|
+
return [
|
|
11229
|
+
"install",
|
|
11230
|
+
"-g",
|
|
11231
|
+
spec,
|
|
11232
|
+
"--no-audit",
|
|
11233
|
+
"--no-fund",
|
|
11234
|
+
"--progress=false",
|
|
11235
|
+
"--loglevel=http",
|
|
11236
|
+
"--prefer-offline"
|
|
11237
|
+
];
|
|
11238
|
+
}
|
|
11239
|
+
function packageFromFetchLine(line) {
|
|
11240
|
+
const m = line.match(
|
|
11241
|
+
/GET\s+(?:\d+\s+)?https?:\/\/\S*?\/((?:@[^/\s]+(?:\/|%2[fF]))?[^/\s]+)\/-\/[^/\s]*?-(\d+\.\d+\.\d+[^/\s]*?)\.tgz/u
|
|
11242
|
+
);
|
|
11243
|
+
if (!m) return void 0;
|
|
11244
|
+
return `${m[1].replace(/%2[fF]/u, "/")}@${m[2]}`;
|
|
11245
|
+
}
|
|
11246
|
+
function narrateNpmLine(line) {
|
|
11247
|
+
const text = line.trim();
|
|
11248
|
+
if (!text) return void 0;
|
|
11249
|
+
if (/^npm\s+warn\s+deprecated\b/iu.test(text)) return void 0;
|
|
11250
|
+
if (/added \d+ packages?|removed \d+ packages?|changed \d+ packages?|up to date/iu.test(text)) return text;
|
|
11251
|
+
const fetched = /\bhttp fetch\b/iu.test(text) ? packageFromFetchLine(text) : void 0;
|
|
11252
|
+
if (fetched) return `downloading ${fetched}`;
|
|
11253
|
+
if (/^npm\s+(warn|error)\b/iu.test(text)) return text;
|
|
11254
|
+
if (/\b(idealTree|resolveWithNewModule|placeDep)\b/u.test(text)) return "resolving dependencies";
|
|
11255
|
+
if (/\bhttp fetch\b/iu.test(text)) return "resolving dependencies";
|
|
11256
|
+
if (/\b(reify|extract|ADDITION|CHANGE)\b/u.test(text)) return "installing packages";
|
|
11257
|
+
if (/\baudit\b/iu.test(text)) return "finishing";
|
|
11258
|
+
return void 0;
|
|
11259
|
+
}
|
|
11260
|
+
var NPM_LOG_POINTER = /^npm\s+(error|ERR!)\s+A complete log of this run can be found in/iu;
|
|
11261
|
+
function npmFailureTail(output, maxLines = 6, maxChars = 500) {
|
|
11262
|
+
const lines = output.split(/\r?\n/u).map((l) => l.trimEnd()).filter((l) => l.trim().length > 0).filter((l) => !NPM_LOG_POINTER.test(l.trim())).filter((l) => !/^npm\s+notice\b/iu.test(l.trim()));
|
|
11263
|
+
const tail = lines.slice(-maxLines).join(" \xB7 ");
|
|
11264
|
+
if (!tail) return output.trim().replace(/\s+/gu, " ").slice(-maxChars) || "npm produced no output";
|
|
11265
|
+
return tail.length > maxChars ? `\u2026${tail.slice(-maxChars)}` : tail;
|
|
11266
|
+
}
|
|
11267
|
+
async function runNpmStreaming(opts) {
|
|
11268
|
+
const spawnFn = opts.spawnFn ?? import_node_child_process6.spawn;
|
|
11269
|
+
return await new Promise((resolveRun) => {
|
|
11270
|
+
const chunks = [];
|
|
11271
|
+
let settled = false;
|
|
11272
|
+
let child2;
|
|
11273
|
+
const finish = (result) => {
|
|
11274
|
+
if (settled) return;
|
|
11275
|
+
settled = true;
|
|
11276
|
+
clearTimeout(timer);
|
|
11277
|
+
resolveRun(result);
|
|
11278
|
+
};
|
|
11279
|
+
const timer = setTimeout(() => {
|
|
11280
|
+
child2?.kill("SIGTERM");
|
|
11281
|
+
chunks.push(`npm install timed out after ${opts.timeoutMs}ms`);
|
|
11282
|
+
finish({ ok: false, code: null, output: chunks.join("\n") });
|
|
11283
|
+
}, opts.timeoutMs);
|
|
11284
|
+
try {
|
|
11285
|
+
child2 = spawnFn(opts.file, [...opts.args], {
|
|
11286
|
+
env: opts.env ?? process.env,
|
|
11287
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
11288
|
+
shell: false,
|
|
11289
|
+
windowsHide: true
|
|
11290
|
+
});
|
|
11291
|
+
} catch (e) {
|
|
11292
|
+
chunks.push(e instanceof Error ? e.message : String(e));
|
|
11293
|
+
finish({ ok: false, code: null, output: chunks.join("\n") });
|
|
11294
|
+
return;
|
|
11295
|
+
}
|
|
11296
|
+
const onLine = (line) => {
|
|
11297
|
+
chunks.push(line);
|
|
11298
|
+
opts.onLine?.(line);
|
|
11299
|
+
};
|
|
11300
|
+
if (child2.stdout) (0, import_node_readline.createInterface)({ input: child2.stdout }).on("line", onLine);
|
|
11301
|
+
if (child2.stderr) (0, import_node_readline.createInterface)({ input: child2.stderr }).on("line", onLine);
|
|
11302
|
+
child2.on("error", (e) => {
|
|
11303
|
+
chunks.push(e.message);
|
|
11304
|
+
finish({ ok: false, code: null, output: chunks.join("\n") });
|
|
11305
|
+
});
|
|
11306
|
+
child2.on("close", (code) => finish({ ok: code === 0, code, output: chunks.join("\n") }));
|
|
11307
|
+
});
|
|
11308
|
+
}
|
|
11309
|
+
async function verifyInstalledCli(probe, target) {
|
|
11310
|
+
let stdout;
|
|
11311
|
+
try {
|
|
11312
|
+
stdout = await probe();
|
|
11313
|
+
} catch (e) {
|
|
11314
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
11315
|
+
return { ok: false, detail: `the installed mmi-cli does not run (${message.trim().split(/\r?\n/u)[0]})` };
|
|
11316
|
+
}
|
|
11317
|
+
const version = /(\d+\.\d+\.\d+[^\s]*)/u.exec(stdout.trim())?.[1];
|
|
11318
|
+
if (!version) {
|
|
11319
|
+
return { ok: false, detail: `the installed mmi-cli printed no version (${stdout.trim().slice(0, 80) || "no output"})` };
|
|
11320
|
+
}
|
|
11321
|
+
if (target && version !== target) {
|
|
11322
|
+
return { ok: false, detail: `the installed mmi-cli reports ${version}, not the ${target} that was just installed` };
|
|
11323
|
+
}
|
|
11324
|
+
return { ok: true, detail: `verified: the installed mmi-cli runs ${version}` };
|
|
11325
|
+
}
|
|
11326
|
+
|
|
11218
11327
|
// src/plugin-guard.ts
|
|
11219
11328
|
function buildPluginGuardDecision(i) {
|
|
11220
11329
|
if (!i.isOrgRepo) return { state: "not-org" };
|
|
@@ -11448,12 +11557,12 @@ function marketplaceClonePresent(surface, home, exists = import_node_fs17.exists
|
|
|
11448
11557
|
return marketplaceCloneCandidates(surface, home, env).some(exists);
|
|
11449
11558
|
}
|
|
11450
11559
|
function runHostBinSync(bin, args) {
|
|
11451
|
-
return isWin ? (0,
|
|
11560
|
+
return isWin ? (0, import_node_child_process7.execFileSync)("cmd.exe", ["/c", bin, ...args], {
|
|
11452
11561
|
encoding: "utf8",
|
|
11453
11562
|
stdio: ["ignore", "pipe", "ignore"],
|
|
11454
11563
|
timeout: 15e3,
|
|
11455
11564
|
windowsHide: true
|
|
11456
|
-
}) : (0,
|
|
11565
|
+
}) : (0, import_node_child_process7.execFileSync)(bin, args, {
|
|
11457
11566
|
encoding: "utf8",
|
|
11458
11567
|
stdio: ["ignore", "pipe", "ignore"],
|
|
11459
11568
|
timeout: 15e3,
|
|
@@ -11521,15 +11630,28 @@ async function fetchNpmReleasedVersion() {
|
|
|
11521
11630
|
}
|
|
11522
11631
|
}
|
|
11523
11632
|
var NPM_INSTALL_TIMEOUT_MS = 12e4;
|
|
11524
|
-
|
|
11633
|
+
var CLI_VERSION_PROBE_TIMEOUT_MS = 3e4;
|
|
11634
|
+
async function npmSelfUpdateCli(target, onStep, deps = {}) {
|
|
11525
11635
|
const command = cliUpdateCommand(target);
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11636
|
+
const args = npmSelfUpdateArgs(`@mutmutco/cli@${target ?? "latest"}`);
|
|
11637
|
+
onStep?.(command);
|
|
11638
|
+
let last = "";
|
|
11639
|
+
const result = await (deps.run ?? runNpmStreaming)({
|
|
11640
|
+
file: isWin ? "cmd.exe" : "npm",
|
|
11641
|
+
args: isWin ? ["/c", "npm", ...args] : args,
|
|
11642
|
+
timeoutMs: NPM_INSTALL_TIMEOUT_MS,
|
|
11643
|
+
onLine: (line) => {
|
|
11644
|
+
const message = narrateNpmLine(line);
|
|
11645
|
+
if (!message || message === last) return;
|
|
11646
|
+
last = message;
|
|
11647
|
+
onStep?.(message);
|
|
11648
|
+
}
|
|
11649
|
+
});
|
|
11650
|
+
if (!result.ok) return { ok: false, detail: npmFailureTail(result.output) };
|
|
11651
|
+
const probe = deps.probeVersion ?? (async () => (await runHostBin("mmi-cli", ["--version"], { timeout: CLI_VERSION_PROBE_TIMEOUT_MS })).stdout);
|
|
11652
|
+
const verified = await verifyInstalledCli(probe, target);
|
|
11653
|
+
onStep?.(verified.detail);
|
|
11654
|
+
return verified.ok ? { ok: true, detail: `${command} exited 0 \u2014 ${verified.detail}` } : { ok: false, detail: `${command} exited 0 but ${verified.detail}` };
|
|
11533
11655
|
}
|
|
11534
11656
|
function kiloConfigListsPlugin(configRoot, home = (0, import_node_os5.homedir)(), read = (p) => (0, import_node_fs17.readFileSync)(p, "utf8"), exists = import_node_fs17.existsSync) {
|
|
11535
11657
|
const candidates = ["kilo.json", "kilo.jsonc", "opencode.json", "opencode.jsonc", "config.json"];
|
|
@@ -12016,8 +12138,11 @@ function readKnownMarketplacesFile(path2) {
|
|
|
12016
12138
|
return void 0;
|
|
12017
12139
|
}
|
|
12018
12140
|
}
|
|
12141
|
+
function claudeCodeEnvMarkerPresent(env = process.env) {
|
|
12142
|
+
return Boolean(env.CLAUDE_CODE_SESSION_ID?.trim() || env.CLAUDECODE?.trim() || env.CLAUDE_PLUGIN_ROOT?.trim());
|
|
12143
|
+
}
|
|
12019
12144
|
function claudeCodeIsRunning(env = process.env, listProcesses = defaultProcessList) {
|
|
12020
|
-
if (
|
|
12145
|
+
if (claudeCodeEnvMarkerPresent(env)) return true;
|
|
12021
12146
|
let table;
|
|
12022
12147
|
try {
|
|
12023
12148
|
table = listProcesses();
|
|
@@ -12028,7 +12153,7 @@ function claudeCodeIsRunning(env = process.env, listProcesses = defaultProcessLi
|
|
|
12028
12153
|
return table.split(/\r?\n/).some((line) => /(^|[/\\])claude(\.(exe|cmd|ps1))?\s/.test(`${line.trim()} `));
|
|
12029
12154
|
}
|
|
12030
12155
|
function defaultProcessList() {
|
|
12031
|
-
return isWin ? (0,
|
|
12156
|
+
return isWin ? (0, import_node_child_process7.execFileSync)("powershell.exe", ["-NoProfile", "-Command", "Get-CimInstance Win32_Process | ForEach-Object { $_.CommandLine }"], { encoding: "utf8", windowsHide: true, maxBuffer: 32 * 1024 * 1024, timeout: 15e3 }) : (0, import_node_child_process7.execFileSync)("ps", ["-eo", "args="], { encoding: "utf8", windowsHide: true, timeout: 15e3 });
|
|
12032
12157
|
}
|
|
12033
12158
|
function writeMarketplacePinsOnDisk(path2, pins, succeeded, failedVerb, declineWhileHostLive) {
|
|
12034
12159
|
if (pins.size === 0) return void 0;
|
|
@@ -12059,6 +12184,7 @@ function restoreMarketplacePinsOnDisk(path2, pins, hostIsRunning = claudeCodeIsR
|
|
|
12059
12184
|
}
|
|
12060
12185
|
function applyOrgMarketplacePins(path2, names, hostIsRunning = claudeCodeIsRunning) {
|
|
12061
12186
|
let landed = false;
|
|
12187
|
+
let blockedByHost = false;
|
|
12062
12188
|
const detail = writeMarketplacePinsOnDisk(
|
|
12063
12189
|
path2,
|
|
12064
12190
|
new Map(names.map((name) => [name, ORG_MARKETPLACE_PINS])),
|
|
@@ -12067,9 +12193,13 @@ function applyOrgMarketplacePins(path2, names, hostIsRunning = claudeCodeIsRunni
|
|
|
12067
12193
|
return `pinned ${[...pins.keys()].join(", ")} to ${ORG_MARKETPLACE_PINS.ref} with auto-update on`;
|
|
12068
12194
|
},
|
|
12069
12195
|
"pin",
|
|
12070
|
-
() =>
|
|
12196
|
+
() => {
|
|
12197
|
+
if (!hostIsRunning()) return void 0;
|
|
12198
|
+
blockedByHost = true;
|
|
12199
|
+
return "not pinned \u2014 Claude Code is running and rewrites this registration from its own copy; quit it, then run `mmi-cli doctor`";
|
|
12200
|
+
}
|
|
12071
12201
|
);
|
|
12072
|
-
return detail === void 0 ? void 0 : { detail, wrote: landed };
|
|
12202
|
+
return detail === void 0 ? void 0 : { detail, wrote: landed, blockedByHost };
|
|
12073
12203
|
}
|
|
12074
12204
|
function writeMarketplacePinPending(path2, names, now = Date.now()) {
|
|
12075
12205
|
try {
|
|
@@ -12777,7 +12907,8 @@ function workflowEntry(repo, workflowPath, yamlText) {
|
|
|
12777
12907
|
executor: "github-actions",
|
|
12778
12908
|
llm: llmFromHeader(yamlText),
|
|
12779
12909
|
resolved: "live",
|
|
12780
|
-
source: `${ORG}/${repo}:${workflowPath}
|
|
12910
|
+
source: `${ORG}/${repo}:${workflowPath}`,
|
|
12911
|
+
harbourUnmanaged: isHarbourUnmanaged(yamlText)
|
|
12781
12912
|
};
|
|
12782
12913
|
}
|
|
12783
12914
|
function awsRuleEntries(payload) {
|
|
@@ -12980,12 +13111,13 @@ function cadenceStale(registryCadence, liveCadence) {
|
|
|
12980
13111
|
return !liveCrons.every((cron) => registered.has(cron));
|
|
12981
13112
|
}
|
|
12982
13113
|
function reconcileGithubActions(liveGithub, registry2, readRepos, activeWorkflowNames = /* @__PURE__ */ new Set(), disabledWorkflowNames = /* @__PURE__ */ new Set()) {
|
|
13114
|
+
const managedLiveGithub = liveGithub.filter((e) => !e.harbourUnmanaged);
|
|
12983
13115
|
const registryGithub = registry2.filter((r) => r.executor === "github-actions");
|
|
12984
|
-
const liveByName = new Map(
|
|
13116
|
+
const liveByName = new Map(managedLiveGithub.map((e) => [e.name, e]));
|
|
12985
13117
|
const registryById = new Map(registryGithub.map((r) => [r.id, r]));
|
|
12986
13118
|
const drifts = [];
|
|
12987
13119
|
const parked = [];
|
|
12988
|
-
for (const e of
|
|
13120
|
+
for (const e of managedLiveGithub) {
|
|
12989
13121
|
if (!registryById.has(e.name)) {
|
|
12990
13122
|
drifts.push({
|
|
12991
13123
|
class: "live-but-unregistered",
|
|
@@ -13063,9 +13195,11 @@ function strayCronDrift(name) {
|
|
|
13063
13195
|
remedy: "strip on: schedule \u2192 workflow_dispatch and let the harbour dispatcher fire on the registry cadence (docs/schedules.md rule 1)"
|
|
13064
13196
|
};
|
|
13065
13197
|
}
|
|
13066
|
-
|
|
13198
|
+
function isHarbourUnmanaged(yamlText) {
|
|
13199
|
+
return /^#\s*harbour:\s*unmanaged\s*$/im.test(yamlText);
|
|
13200
|
+
}
|
|
13067
13201
|
function strayCronDrifts(workflows) {
|
|
13068
|
-
return workflows.filter((w) => !
|
|
13202
|
+
return workflows.filter((w) => !isHarbourUnmanaged(w.yamlText)).filter((w) => workflowTriggersSchedule(w.yamlText)).map((w) => strayCronDrift(w.name)).sort((a, b) => a.name.localeCompare(b.name));
|
|
13069
13203
|
}
|
|
13070
13204
|
function unlauncheredLlmDrift(entry) {
|
|
13071
13205
|
if (entry.llm !== "yes") return null;
|
|
@@ -13180,6 +13314,7 @@ function scheduleRecordFromWorkflow(repo, workflowPath, yamlText) {
|
|
|
13180
13314
|
if (!crons.length && !header.schedule) return null;
|
|
13181
13315
|
const basename6 = workflowPath.split("/").pop() ?? workflowPath;
|
|
13182
13316
|
const expectedId = `${repo}/${basename6.replace(/\.ya?ml$/, "")}`;
|
|
13317
|
+
if (isHarbourUnmanaged(yamlText)) return null;
|
|
13183
13318
|
const missing = SCHEDULE_HEADER_FIELDS.filter((f) => !header[f]);
|
|
13184
13319
|
if (missing.length) {
|
|
13185
13320
|
throw new Error(`schedules register: ${expectedId} (${workflowPath}) is a scheduled workflow but is missing the eight-field entry-template header field(s): ${missing.join(", ")} \u2014 see docs/schedules.md "The entry template".`);
|
|
@@ -13544,7 +13679,7 @@ ${lines.join("\n")}`;
|
|
|
13544
13679
|
}
|
|
13545
13680
|
|
|
13546
13681
|
// src/secrets.ts
|
|
13547
|
-
var
|
|
13682
|
+
var import_node_child_process8 = require("node:child_process");
|
|
13548
13683
|
var import_node_os7 = require("node:os");
|
|
13549
13684
|
|
|
13550
13685
|
// src/gh-create.ts
|
|
@@ -14816,7 +14951,7 @@ function spawnExitCode(status, signal) {
|
|
|
14816
14951
|
}
|
|
14817
14952
|
function defaultSpawn(command, args, env) {
|
|
14818
14953
|
const target = resolveSpawnTarget(command, args);
|
|
14819
|
-
const r = (0,
|
|
14954
|
+
const r = (0, import_node_child_process8.spawnSync)(target.cmd, target.args, {
|
|
14820
14955
|
windowsHide: true,
|
|
14821
14956
|
stdio: "inherit",
|
|
14822
14957
|
env,
|
|
@@ -15634,10 +15769,10 @@ var rollout_plan_default = {
|
|
|
15634
15769
|
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)."
|
|
15635
15770
|
},
|
|
15636
15771
|
baseline: {
|
|
15637
|
-
version: "3.
|
|
15638
|
-
tag: "v3.
|
|
15639
|
-
commit: "
|
|
15640
|
-
npm: "@mutmutco/cli@3.
|
|
15772
|
+
version: "3.114.0",
|
|
15773
|
+
tag: "v3.114.0",
|
|
15774
|
+
commit: "cbe675e9904f",
|
|
15775
|
+
npm: "@mutmutco/cli@3.114.0"
|
|
15641
15776
|
},
|
|
15642
15777
|
exitCriterion: "fleet-n-of-n",
|
|
15643
15778
|
hubOnlyShortcut: "forbidden",
|
|
@@ -15654,14 +15789,14 @@ var rollout_plan_default = {
|
|
|
15654
15789
|
repo: "mutmutco/mmi-hub",
|
|
15655
15790
|
role: "canary",
|
|
15656
15791
|
schedule: "train",
|
|
15657
|
-
v3Target: "v3.
|
|
15792
|
+
v3Target: "v3.114.0"
|
|
15658
15793
|
}
|
|
15659
15794
|
],
|
|
15660
15795
|
rollbackTrigger: "Any red inside the post-cut soak window: `devops train gate` FAIL attributable to the v4 doors, Hub endpoint health probe failure, a v3 client refused while the compat window must still admit it (SUPPORTED_MINOR_WINDOW=2, MIN_CLIENT_VERSION 0.0.0 \u2014 D6a), or npm consumer install/doctor failure on the v4 dist.",
|
|
15661
15796
|
rollback: {
|
|
15662
15797
|
independent: true,
|
|
15663
|
-
mechanism: "npm dist-tag latest -> 3.
|
|
15664
|
-
v3Target: "v3.
|
|
15798
|
+
mechanism: "npm dist-tag latest -> 3.114.0 and redeploy the Hub Lambda from tag v3.114.0 (cbe675e9904f); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
15799
|
+
v3Target: "v3.114.0 (@mutmutco/cli@3.114.0, tag commit cbe675e9904f \u2014 the preserved latest-v3 distribution, D6b)"
|
|
15665
15800
|
}
|
|
15666
15801
|
},
|
|
15667
15802
|
{
|
|
@@ -21315,7 +21450,7 @@ async function runPrLand(prNumber, options, deps) {
|
|
|
21315
21450
|
var import_node_fs22 = require("node:fs");
|
|
21316
21451
|
|
|
21317
21452
|
// src/stage-runner.ts
|
|
21318
|
-
var
|
|
21453
|
+
var import_node_child_process9 = require("node:child_process");
|
|
21319
21454
|
var import_node_fs21 = require("node:fs");
|
|
21320
21455
|
var import_node_path20 = require("node:path");
|
|
21321
21456
|
var import_node_net = require("node:net");
|
|
@@ -21327,7 +21462,7 @@ function normalizeEol(s) {
|
|
|
21327
21462
|
}
|
|
21328
21463
|
|
|
21329
21464
|
// src/stage-runner.ts
|
|
21330
|
-
var execFileP3 = (0, import_node_util5.promisify)(
|
|
21465
|
+
var execFileP3 = (0, import_node_util5.promisify)(import_node_child_process9.execFile);
|
|
21331
21466
|
var DOCKER_TIMEOUT_MS = 15e3;
|
|
21332
21467
|
var EARLY_EXIT_GRACE_MS = 2e3;
|
|
21333
21468
|
function earlyExitGraceMs() {
|
|
@@ -21849,7 +21984,7 @@ async function startStage(config = {}, opts = {}) {
|
|
|
21849
21984
|
let up = sub(config.up.trim());
|
|
21850
21985
|
if (opts.forceRecreate) up = appendForceRecreate(up);
|
|
21851
21986
|
const identity = await resolveStageIdentity(cwd);
|
|
21852
|
-
const child2 = (0,
|
|
21987
|
+
const child2 = (0, import_node_child_process9.spawn)(up, {
|
|
21853
21988
|
cwd,
|
|
21854
21989
|
shell: true,
|
|
21855
21990
|
// POSIX-only: the process group exists for the group-kill in stopStage. On win32 teardown is
|
|
@@ -22053,7 +22188,7 @@ async function executeWaveLand(plan, deps, opts = { preserveWorktree: true }) {
|
|
|
22053
22188
|
var import_node_os19 = require("node:os");
|
|
22054
22189
|
|
|
22055
22190
|
// src/board.ts
|
|
22056
|
-
var
|
|
22191
|
+
var import_node_child_process10 = require("node:child_process");
|
|
22057
22192
|
var import_node_fs23 = require("node:fs");
|
|
22058
22193
|
var import_node_os8 = require("node:os");
|
|
22059
22194
|
var import_node_path21 = require("node:path");
|
|
@@ -22398,7 +22533,7 @@ function findDuplicateLesson(source, openLessons) {
|
|
|
22398
22533
|
var BOARD_STATUSES = ["Todo", "In Progress", "In Review", "Done"];
|
|
22399
22534
|
|
|
22400
22535
|
// src/board.ts
|
|
22401
|
-
var rawExecFileP3 = (0, import_node_util6.promisify)(
|
|
22536
|
+
var rawExecFileP3 = (0, import_node_util6.promisify)(import_node_child_process10.execFile);
|
|
22402
22537
|
var BOARD_GIT_TIMEOUT_MS = 1e4;
|
|
22403
22538
|
var WRITE_PROBE_CONCURRENCY = 8;
|
|
22404
22539
|
var CLAIM_CONCURRENCY = 5;
|
|
@@ -25451,10 +25586,10 @@ function healClaudeBinary(host = {}, onStep) {
|
|
|
25451
25586
|
}
|
|
25452
25587
|
|
|
25453
25588
|
// src/statusline-invalidate.ts
|
|
25454
|
-
var
|
|
25589
|
+
var import_node_child_process11 = require("node:child_process");
|
|
25455
25590
|
function invalidateStatuslineBoardCache() {
|
|
25456
25591
|
try {
|
|
25457
|
-
const child2 = (0,
|
|
25592
|
+
const child2 = (0, import_node_child_process11.spawn)("jerv-cli", ["lane", "ops", "invalidate-board"], {
|
|
25458
25593
|
detached: true,
|
|
25459
25594
|
stdio: "ignore",
|
|
25460
25595
|
windowsHide: true
|
|
@@ -25673,12 +25808,12 @@ function renderVerifyBroker(input) {
|
|
|
25673
25808
|
}
|
|
25674
25809
|
|
|
25675
25810
|
// src/hotfix-coverage.ts
|
|
25676
|
-
var
|
|
25811
|
+
var import_node_child_process12 = require("node:child_process");
|
|
25677
25812
|
var CHERRY_TRAILER = /\(cherry picked from commit ([0-9a-f]{7,40})\)/g;
|
|
25678
25813
|
function checkHotfixCoverage(options = {}) {
|
|
25679
25814
|
const { cwd = process.cwd(), mainRef = "origin/main", rcRef = "origin/rc", manifestPaths = [] } = options;
|
|
25680
25815
|
const ack = (options.ack ?? []).filter(Boolean);
|
|
25681
|
-
const git2 = options.git ?? ((args, opts) => (0,
|
|
25816
|
+
const git2 = options.git ?? ((args, opts) => (0, import_node_child_process12.execFileSync)("git", args, { cwd, encoding: "utf8", input: opts?.input, stdio: ["pipe", "pipe", "pipe"] }));
|
|
25682
25817
|
const revList = (range) => {
|
|
25683
25818
|
const out = git2(["rev-list", "--no-merges", range]).trim();
|
|
25684
25819
|
return out ? out.split("\n") : [];
|
|
@@ -25746,7 +25881,7 @@ function checkHotfixCoverage(options = {}) {
|
|
|
25746
25881
|
}
|
|
25747
25882
|
function checkHotfixCarries(options) {
|
|
25748
25883
|
const { cwd = process.cwd(), branch, baseRef, targets } = options;
|
|
25749
|
-
const git2 = options.git ?? ((args, opts) => (0,
|
|
25884
|
+
const git2 = options.git ?? ((args, opts) => (0, import_node_child_process12.execFileSync)("git", args, { cwd, encoding: "utf8", input: opts?.input, stdio: ["pipe", "pipe", "pipe"] }));
|
|
25750
25885
|
const isAncestor = (sha, ref) => {
|
|
25751
25886
|
try {
|
|
25752
25887
|
git2(["merge-base", "--is-ancestor", sha, ref]);
|
|
@@ -26770,7 +26905,7 @@ async function announceRelease(deps, args) {
|
|
|
26770
26905
|
|
|
26771
26906
|
// src/repo-index.ts
|
|
26772
26907
|
var import_node_crypto4 = require("node:crypto");
|
|
26773
|
-
var
|
|
26908
|
+
var import_node_child_process13 = require("node:child_process");
|
|
26774
26909
|
var import_node_fs27 = require("node:fs");
|
|
26775
26910
|
var import_node_path25 = require("node:path");
|
|
26776
26911
|
var REPO_INDEX_SCHEMA = 1;
|
|
@@ -26916,7 +27051,7 @@ function loadReadmeHints(cwd, candidatePaths) {
|
|
|
26916
27051
|
function toPosix(p) {
|
|
26917
27052
|
return p.split(import_node_path25.sep).join("/");
|
|
26918
27053
|
}
|
|
26919
|
-
function listCandidatePaths(cwd, exec =
|
|
27054
|
+
function listCandidatePaths(cwd, exec = import_node_child_process13.execFileSync) {
|
|
26920
27055
|
try {
|
|
26921
27056
|
const out = exec("git", ["ls-files", "-z", "-c", "-o", "--exclude-standard"], {
|
|
26922
27057
|
cwd,
|
|
@@ -27039,7 +27174,7 @@ function searchRepoIndex(idx, query, limit = 20) {
|
|
|
27039
27174
|
}
|
|
27040
27175
|
return out;
|
|
27041
27176
|
}
|
|
27042
|
-
function inferRepoSlug(cwd, exec =
|
|
27177
|
+
function inferRepoSlug(cwd, exec = import_node_child_process13.execFileSync) {
|
|
27043
27178
|
try {
|
|
27044
27179
|
const url = String(exec("git", ["remote", "get-url", "origin"], { cwd, encoding: "utf8" })).trim();
|
|
27045
27180
|
const m = /[:/]([^/]+\/[^/]+?)(?:\.git)?$/.exec(url);
|
|
@@ -27189,7 +27324,7 @@ async function gcRepoIndexCloud(deps) {
|
|
|
27189
27324
|
var import_node_fs28 = require("node:fs");
|
|
27190
27325
|
var import_node_os12 = require("node:os");
|
|
27191
27326
|
var import_node_path26 = require("node:path");
|
|
27192
|
-
var
|
|
27327
|
+
var import_node_child_process14 = require("node:child_process");
|
|
27193
27328
|
var MAX_EMBED_BACKFILL_ROUNDS = 40;
|
|
27194
27329
|
function normalizeRepo(raw) {
|
|
27195
27330
|
const t = raw.trim().replace(/\.git$/, "");
|
|
@@ -27209,7 +27344,7 @@ function rosterRepos(projects) {
|
|
|
27209
27344
|
}
|
|
27210
27345
|
function shallowClone(repo, dest, token) {
|
|
27211
27346
|
const basic = Buffer.from(`x-access-token:${token}`, "utf8").toString("base64");
|
|
27212
|
-
(0,
|
|
27347
|
+
(0, import_node_child_process14.execFileSync)(
|
|
27213
27348
|
"git",
|
|
27214
27349
|
["-c", `http.extraHeader=Authorization: Basic ${basic}`, "clone", "--depth", "1", "--single-branch", `https://github.com/${repo}.git`, dest],
|
|
27215
27350
|
{ encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], windowsHide: true }
|
|
@@ -27478,7 +27613,7 @@ async function runRepoIndexHealth(opts) {
|
|
|
27478
27613
|
}
|
|
27479
27614
|
|
|
27480
27615
|
// src/spawn-policy-core.ts
|
|
27481
|
-
var
|
|
27616
|
+
var import_node_child_process15 = require("node:child_process");
|
|
27482
27617
|
var import_node_fs30 = require("node:fs");
|
|
27483
27618
|
var import_node_path27 = require("node:path");
|
|
27484
27619
|
var SPAWNERS = ["spawn", "spawnSync", "exec", "execSync", "execFile", "execFileSync"];
|
|
@@ -27549,7 +27684,7 @@ function findViolationsInSource(raw) {
|
|
|
27549
27684
|
return found;
|
|
27550
27685
|
}
|
|
27551
27686
|
function policedFiles(root) {
|
|
27552
|
-
const r = (0,
|
|
27687
|
+
const r = (0, import_node_child_process15.spawnSync)("git", ["ls-files", "-z", "--cached", "--others", "--exclude-standard"], {
|
|
27553
27688
|
cwd: root,
|
|
27554
27689
|
encoding: "utf8",
|
|
27555
27690
|
windowsHide: true,
|
|
@@ -27583,7 +27718,7 @@ function runSpawnPolicy(root) {
|
|
|
27583
27718
|
}
|
|
27584
27719
|
|
|
27585
27720
|
// src/test-policy-core.ts
|
|
27586
|
-
var
|
|
27721
|
+
var import_node_child_process16 = require("node:child_process");
|
|
27587
27722
|
var import_node_fs31 = require("node:fs");
|
|
27588
27723
|
var import_node_path28 = require("node:path");
|
|
27589
27724
|
var POLICY_FILE = "test-policy.json";
|
|
@@ -27713,14 +27848,14 @@ function evaluate(changed, policy, present = () => false) {
|
|
|
27713
27848
|
return findings;
|
|
27714
27849
|
}
|
|
27715
27850
|
function git(args, cwd) {
|
|
27716
|
-
return (0,
|
|
27851
|
+
return (0, import_node_child_process16.execFileSync)("git", args, { windowsHide: true, cwd, encoding: "utf8", maxBuffer: 32 * 1024 * 1024 });
|
|
27717
27852
|
}
|
|
27718
27853
|
var COAUTHOR_KEY = "Co-authored-by";
|
|
27719
27854
|
var GH_MESSAGE_SEPARATOR = /^-{5,}$/;
|
|
27720
27855
|
var LIFTED_KEYS = new RegExp(`^(?:${TRAILER_KEY}|${COAUTHOR_KEY}):`, "i");
|
|
27721
27856
|
function parseTrailers(message, cwd) {
|
|
27722
27857
|
try {
|
|
27723
|
-
return (0,
|
|
27858
|
+
return (0, import_node_child_process16.execFileSync)("git", ["interpret-trailers", "--parse", "--unfold"], {
|
|
27724
27859
|
windowsHide: true,
|
|
27725
27860
|
cwd,
|
|
27726
27861
|
input: message,
|
|
@@ -29521,9 +29656,9 @@ ${SSH_RECIPE_AGENT_NOTE}`);
|
|
|
29521
29656
|
|
|
29522
29657
|
// src/schedules-commands.ts
|
|
29523
29658
|
var import_promises5 = require("node:fs/promises");
|
|
29524
|
-
var
|
|
29659
|
+
var import_node_child_process17 = require("node:child_process");
|
|
29525
29660
|
var import_node_util7 = require("node:util");
|
|
29526
|
-
var execFileP5 = (0, import_node_util7.promisify)(
|
|
29661
|
+
var execFileP5 = (0, import_node_util7.promisify)(import_node_child_process17.execFile);
|
|
29527
29662
|
var AWS_REGION = "eu-central-1";
|
|
29528
29663
|
var AWS_TIMEOUT_MS = 3e4;
|
|
29529
29664
|
var AWS_RETRY_DELAY_MS = 1500;
|
|
@@ -32402,7 +32537,7 @@ var import_node_fs38 = require("node:fs");
|
|
|
32402
32537
|
var import_promises8 = require("node:fs/promises");
|
|
32403
32538
|
var import_node_path36 = require("node:path");
|
|
32404
32539
|
var import_node_os15 = require("node:os");
|
|
32405
|
-
var
|
|
32540
|
+
var import_node_child_process18 = require("node:child_process");
|
|
32406
32541
|
|
|
32407
32542
|
// src/board-advance.ts
|
|
32408
32543
|
function repoOf2(ref) {
|
|
@@ -33008,7 +33143,7 @@ async function remoteBranchExists2(branch, options = {}) {
|
|
|
33008
33143
|
}
|
|
33009
33144
|
var COMPOSE_TIMEOUT_MS = 12e4;
|
|
33010
33145
|
function spawnDeferredGcSweep() {
|
|
33011
|
-
spawnDetachedSelf(["worktree", "gc", "sweep-deferred", "--quiet"], { spawn:
|
|
33146
|
+
spawnDetachedSelf(["worktree", "gc", "sweep-deferred", "--quiet"], { spawn: import_node_child_process18.spawn, execPath: process.execPath, scriptPath: process.argv[1] });
|
|
33012
33147
|
}
|
|
33013
33148
|
async function createDeferredWorktreeStore() {
|
|
33014
33149
|
try {
|
|
@@ -36688,7 +36823,8 @@ var RESTART_LINE = "\u21BB Restart Claude to finish.";
|
|
|
36688
36823
|
var VERBOSE_INDENT = " ";
|
|
36689
36824
|
function checkGlyph(check) {
|
|
36690
36825
|
if (!check.ok) return "\u2717";
|
|
36691
|
-
|
|
36826
|
+
if (check.verified === false) return "?";
|
|
36827
|
+
return check.warn ? "\u26A0" : "\u2713";
|
|
36692
36828
|
}
|
|
36693
36829
|
function renderCheckLine(check) {
|
|
36694
36830
|
const head = check.detail ? `${checkGlyph(check)} ${check.label} \u2014 ${check.detail}` : `${checkGlyph(check)} ${check.label}`;
|
|
@@ -36706,9 +36842,11 @@ function renderTally(checks) {
|
|
|
36706
36842
|
const total = checks.length;
|
|
36707
36843
|
const failed = checks.filter((c) => !c.ok).length;
|
|
36708
36844
|
const unverified = checks.filter((c) => c.ok && c.verified === false).length;
|
|
36709
|
-
const
|
|
36710
|
-
|
|
36845
|
+
const warned = checks.filter((c) => c.ok && c.verified !== false && c.warn).length;
|
|
36846
|
+
const healthy = total - failed - unverified - warned;
|
|
36847
|
+
if (failed === 0 && unverified === 0 && warned === 0) return `\u2713 all ${total} checks healthy`;
|
|
36711
36848
|
const parts = [`\u2713 ${healthy} verified healthy`];
|
|
36849
|
+
if (warned > 0) parts.push(`\u26A0 ${warned} warn`);
|
|
36712
36850
|
if (unverified > 0) parts.push(`? ${unverified} unverified`);
|
|
36713
36851
|
if (failed > 0) parts.push(`\u2717 ${failed} failed`);
|
|
36714
36852
|
return `${parts.join(" \xB7 ")} \u2014 ${total} checks`;
|
|
@@ -38358,18 +38496,19 @@ async function runDoctorClean(opts, io, deps) {
|
|
|
38358
38496
|
if (payload) emitNow(payload);
|
|
38359
38497
|
}
|
|
38360
38498
|
async function runMarketplaceRows() {
|
|
38499
|
+
let healed;
|
|
38361
38500
|
if (applyEnv) {
|
|
38362
|
-
|
|
38363
|
-
if (healed) {
|
|
38501
|
+
healed = deps.healMarketplacePins();
|
|
38502
|
+
if (healed?.wrote) {
|
|
38364
38503
|
healIntent(`marketplace pins \u2014 ${healed.detail}`);
|
|
38365
|
-
|
|
38366
|
-
|
|
38367
|
-
|
|
38368
|
-
restartPending = true;
|
|
38369
|
-
}
|
|
38504
|
+
traceHeal("env-heals");
|
|
38505
|
+
markHealChanged();
|
|
38506
|
+
restartPending = true;
|
|
38370
38507
|
}
|
|
38371
38508
|
}
|
|
38372
|
-
for (const row of deps.marketplaceRows())
|
|
38509
|
+
for (const row of deps.marketplaceRows(healed?.blockedByHost)) {
|
|
38510
|
+
emitNow(healed && !healed.wrote ? { ...row, verbose: [...row.verbose ?? [], `heal: ${healed.detail}`] } : row);
|
|
38511
|
+
}
|
|
38373
38512
|
}
|
|
38374
38513
|
async function runTrainSyncRow() {
|
|
38375
38514
|
try {
|
|
@@ -38902,9 +39041,9 @@ function ghAccountCaveat(announcedLogin, accounts) {
|
|
|
38902
39041
|
var import_node_fs45 = require("node:fs");
|
|
38903
39042
|
var import_node_os18 = require("node:os");
|
|
38904
39043
|
var import_node_path42 = require("node:path");
|
|
38905
|
-
var
|
|
39044
|
+
var import_node_child_process19 = require("node:child_process");
|
|
38906
39045
|
var import_node_util8 = require("node:util");
|
|
38907
|
-
var execFileP6 = (0, import_node_util8.promisify)(
|
|
39046
|
+
var execFileP6 = (0, import_node_util8.promisify)(import_node_child_process19.execFile);
|
|
38908
39047
|
var MMI_PLUGIN_ID2 = "mmi@mutmutco";
|
|
38909
39048
|
function installedClaudePluginVersion() {
|
|
38910
39049
|
try {
|
|
@@ -38950,12 +39089,12 @@ function installedSurfacePluginVersion(surface) {
|
|
|
38950
39089
|
if (token === "claude") return installedClaudePluginVersion();
|
|
38951
39090
|
if (token !== "codex") return void 0;
|
|
38952
39091
|
try {
|
|
38953
|
-
const raw = process.platform === "win32" ? (0,
|
|
39092
|
+
const raw = process.platform === "win32" ? (0, import_node_child_process19.execFileSync)("cmd.exe", ["/c", "codex", "plugin", "list", "--json"], {
|
|
38954
39093
|
encoding: "utf8",
|
|
38955
39094
|
stdio: ["ignore", "pipe", "ignore"],
|
|
38956
39095
|
timeout: 15e3,
|
|
38957
39096
|
windowsHide: true
|
|
38958
|
-
}) : (0,
|
|
39097
|
+
}) : (0, import_node_child_process19.execFileSync)("codex", ["plugin", "list", "--json"], {
|
|
38959
39098
|
encoding: "utf8",
|
|
38960
39099
|
stdio: ["ignore", "pipe", "ignore"],
|
|
38961
39100
|
timeout: 15e3,
|
|
@@ -38973,7 +39112,7 @@ function installedActivePluginVersion(surface = detectSurface(process.env)) {
|
|
|
38973
39112
|
}
|
|
38974
39113
|
function worktreeRootSync() {
|
|
38975
39114
|
try {
|
|
38976
|
-
const out = (0,
|
|
39115
|
+
const out = (0, import_node_child_process19.execFileSync)("git", ["rev-parse", "--show-toplevel"], { windowsHide: true, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
38977
39116
|
let root = out.endsWith("\n") ? out.slice(0, -1) : out;
|
|
38978
39117
|
if (process.platform === "win32" && root.endsWith("\r")) root = root.slice(0, -1);
|
|
38979
39118
|
return root || null;
|
|
@@ -39226,7 +39365,7 @@ function mmiDoctorDeps(opts = {}) {
|
|
|
39226
39365
|
sessionPayload: () => readSessionPayload(process.cwd()),
|
|
39227
39366
|
// #3485 items 9 and 8: why the MMI plugin has never printed an "updated ? please restart" notice, and
|
|
39228
39367
|
// which branch it would pick one up from. Two local file reads, no network, fail-soft to no rows.
|
|
39229
|
-
marketplaceRows: () => {
|
|
39368
|
+
marketplaceRows: (hostBlocked) => {
|
|
39230
39369
|
try {
|
|
39231
39370
|
if (detectSurface(process.env) === "codex") return [];
|
|
39232
39371
|
const home = (0, import_node_os19.homedir)();
|
|
@@ -39235,8 +39374,14 @@ function mmiDoctorDeps(opts = {}) {
|
|
|
39235
39374
|
readFileSyncSafe((0, import_node_path43.join)(home, ...KNOWN_MARKETPLACES_RELATIVE), import_node_fs46.readFileSync),
|
|
39236
39375
|
readFileSyncSafe((0, import_node_path43.join)(home, ".claude", "settings.json"), import_node_fs46.readFileSync),
|
|
39237
39376
|
// #3974: this CLI heals these rows, so report mode names the doctor run rather than the hand
|
|
39238
|
-
// edit.
|
|
39239
|
-
|
|
39377
|
+
// edit. #4792 narrows WHICH run: `applyOrgMarketplacePins` declines outright while Claude Code
|
|
39378
|
+
// is up, because the host owns this file and rewrites it from its own copy (#4083). Naming the
|
|
39379
|
+
// doctor there is the circular-and-false remedy the issue was filed on — doctor ran twice and
|
|
39380
|
+
// healed neither row. So the live host, when there is one, is what the rows name first.
|
|
39381
|
+
// The heal lane pays for the full process probe and hands its answer down; every other lane
|
|
39382
|
+
// reads the free env markers, which are set precisely when doctor runs inside a Claude session
|
|
39383
|
+
// — the case the owner hit. A cheap lane never shells a process listing for this.
|
|
39384
|
+
hostBlocked ?? claudeCodeEnvMarkerPresent() ? "host-running" : "doctor"
|
|
39240
39385
|
);
|
|
39241
39386
|
const pending = readMarketplacePinPending(
|
|
39242
39387
|
(0, import_node_path43.join)(home, ".claude", "plugins", ".mmi-marketplace-pin-pending.json"),
|
|
@@ -39250,7 +39395,7 @@ function mmiDoctorDeps(opts = {}) {
|
|
|
39250
39395
|
...rest,
|
|
39251
39396
|
ok: true,
|
|
39252
39397
|
warn: true,
|
|
39253
|
-
detail: `pending restart
|
|
39398
|
+
detail: `pending restart \u2014 doctor pinned main at ${pending.at}; restart Claude Code to load it`,
|
|
39254
39399
|
verbose: [...row.verbose ?? [], "known_marketplaces.json was rewritten by the running Claude host after the verified doctor write"]
|
|
39255
39400
|
};
|
|
39256
39401
|
});
|
|
@@ -39863,11 +40008,11 @@ function runWorktreeInstall(command, cwd, quiet, opts) {
|
|
|
39863
40008
|
"pipe"
|
|
39864
40009
|
];
|
|
39865
40010
|
return new Promise((resolve5, reject) => {
|
|
39866
|
-
const child2 = opts?.shell ? (0,
|
|
40011
|
+
const child2 = opts?.shell ? (0, import_node_child_process20.spawn)(command, { cwd, stdio, windowsHide: true, shell: true }) : (() => {
|
|
39867
40012
|
const [bin, ...args] = command.split(" ");
|
|
39868
40013
|
const file = isWin2 ? "cmd.exe" : bin;
|
|
39869
40014
|
const spawnArgs = isWin2 ? ["/c", bin, ...args] : args;
|
|
39870
|
-
return (0,
|
|
40015
|
+
return (0, import_node_child_process20.spawn)(file, spawnArgs, { cwd, stdio, windowsHide: true });
|
|
39871
40016
|
})();
|
|
39872
40017
|
let stderrTail = "";
|
|
39873
40018
|
child2.stderr?.on("data", (chunk) => {
|
|
@@ -40250,7 +40395,7 @@ function scheduleRelatedDiscovery(o) {
|
|
|
40250
40395
|
try {
|
|
40251
40396
|
const args = ["issue", "discover-related", "--number", String(o.number), "--title", o.title, "--body", o.body, "--fail-soft"];
|
|
40252
40397
|
if (o.repo) args.push("--repo", o.repo);
|
|
40253
|
-
spawnDetachedSelf(args, { spawn:
|
|
40398
|
+
spawnDetachedSelf(args, { spawn: import_node_child_process20.spawn, execPath: process.execPath, scriptPath: process.argv[1] }, { cwd: process.cwd() });
|
|
40254
40399
|
} catch {
|
|
40255
40400
|
}
|
|
40256
40401
|
}
|
|
@@ -42848,11 +42993,11 @@ program2.command("session-start").description("run the SessionStart verbs (whoam
|
|
|
42848
42993
|
for (const line of scratchGcLines(process.cwd())) bannerIo.log(line);
|
|
42849
42994
|
const worktreeBanner = worktreeAutoProvisionBanner(process.cwd());
|
|
42850
42995
|
if (worktreeBanner) {
|
|
42851
|
-
spawnDetachedSelf(["worktree", "setup", "--quiet"], { spawn:
|
|
42996
|
+
spawnDetachedSelf(["worktree", "setup", "--quiet"], { spawn: import_node_child_process20.spawn, execPath: process.execPath, scriptPath: process.argv[1] });
|
|
42852
42997
|
bannerIo.log(worktreeBanner);
|
|
42853
42998
|
}
|
|
42854
42999
|
if (shouldSpawnReleaseCatchup((0, import_node_os19.homedir)(), process.env, readReleaseCatchupState)) {
|
|
42855
|
-
spawnDetachedSelf(["plugin", "release-catchup", "--quiet"], { spawn:
|
|
43000
|
+
spawnDetachedSelf(["plugin", "release-catchup", "--quiet"], { spawn: import_node_child_process20.spawn, execPath: process.execPath, scriptPath: process.argv[1] });
|
|
42856
43001
|
}
|
|
42857
43002
|
if (isLinkedWorktree(process.cwd())) {
|
|
42858
43003
|
const primaryRoot = await primaryCheckoutRoot(process.cwd());
|
package/package.json
CHANGED