@mutmutco/cli 3.113.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 -88
- 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,7 +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$/, "")}`;
|
|
13183
|
-
if (
|
|
13317
|
+
if (isHarbourUnmanaged(yamlText)) return null;
|
|
13184
13318
|
const missing = SCHEDULE_HEADER_FIELDS.filter((f) => !header[f]);
|
|
13185
13319
|
if (missing.length) {
|
|
13186
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".`);
|
|
@@ -13545,7 +13679,7 @@ ${lines.join("\n")}`;
|
|
|
13545
13679
|
}
|
|
13546
13680
|
|
|
13547
13681
|
// src/secrets.ts
|
|
13548
|
-
var
|
|
13682
|
+
var import_node_child_process8 = require("node:child_process");
|
|
13549
13683
|
var import_node_os7 = require("node:os");
|
|
13550
13684
|
|
|
13551
13685
|
// src/gh-create.ts
|
|
@@ -14817,7 +14951,7 @@ function spawnExitCode(status, signal) {
|
|
|
14817
14951
|
}
|
|
14818
14952
|
function defaultSpawn(command, args, env) {
|
|
14819
14953
|
const target = resolveSpawnTarget(command, args);
|
|
14820
|
-
const r = (0,
|
|
14954
|
+
const r = (0, import_node_child_process8.spawnSync)(target.cmd, target.args, {
|
|
14821
14955
|
windowsHide: true,
|
|
14822
14956
|
stdio: "inherit",
|
|
14823
14957
|
env,
|
|
@@ -15635,10 +15769,10 @@ var rollout_plan_default = {
|
|
|
15635
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)."
|
|
15636
15770
|
},
|
|
15637
15771
|
baseline: {
|
|
15638
|
-
version: "3.
|
|
15639
|
-
tag: "v3.
|
|
15640
|
-
commit: "
|
|
15641
|
-
npm: "@mutmutco/cli@3.
|
|
15772
|
+
version: "3.114.0",
|
|
15773
|
+
tag: "v3.114.0",
|
|
15774
|
+
commit: "cbe675e9904f",
|
|
15775
|
+
npm: "@mutmutco/cli@3.114.0"
|
|
15642
15776
|
},
|
|
15643
15777
|
exitCriterion: "fleet-n-of-n",
|
|
15644
15778
|
hubOnlyShortcut: "forbidden",
|
|
@@ -15655,14 +15789,14 @@ var rollout_plan_default = {
|
|
|
15655
15789
|
repo: "mutmutco/mmi-hub",
|
|
15656
15790
|
role: "canary",
|
|
15657
15791
|
schedule: "train",
|
|
15658
|
-
v3Target: "v3.
|
|
15792
|
+
v3Target: "v3.114.0"
|
|
15659
15793
|
}
|
|
15660
15794
|
],
|
|
15661
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.",
|
|
15662
15796
|
rollback: {
|
|
15663
15797
|
independent: true,
|
|
15664
|
-
mechanism: "npm dist-tag latest -> 3.
|
|
15665
|
-
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)"
|
|
15666
15800
|
}
|
|
15667
15801
|
},
|
|
15668
15802
|
{
|
|
@@ -21316,7 +21450,7 @@ async function runPrLand(prNumber, options, deps) {
|
|
|
21316
21450
|
var import_node_fs22 = require("node:fs");
|
|
21317
21451
|
|
|
21318
21452
|
// src/stage-runner.ts
|
|
21319
|
-
var
|
|
21453
|
+
var import_node_child_process9 = require("node:child_process");
|
|
21320
21454
|
var import_node_fs21 = require("node:fs");
|
|
21321
21455
|
var import_node_path20 = require("node:path");
|
|
21322
21456
|
var import_node_net = require("node:net");
|
|
@@ -21328,7 +21462,7 @@ function normalizeEol(s) {
|
|
|
21328
21462
|
}
|
|
21329
21463
|
|
|
21330
21464
|
// src/stage-runner.ts
|
|
21331
|
-
var execFileP3 = (0, import_node_util5.promisify)(
|
|
21465
|
+
var execFileP3 = (0, import_node_util5.promisify)(import_node_child_process9.execFile);
|
|
21332
21466
|
var DOCKER_TIMEOUT_MS = 15e3;
|
|
21333
21467
|
var EARLY_EXIT_GRACE_MS = 2e3;
|
|
21334
21468
|
function earlyExitGraceMs() {
|
|
@@ -21850,7 +21984,7 @@ async function startStage(config = {}, opts = {}) {
|
|
|
21850
21984
|
let up = sub(config.up.trim());
|
|
21851
21985
|
if (opts.forceRecreate) up = appendForceRecreate(up);
|
|
21852
21986
|
const identity = await resolveStageIdentity(cwd);
|
|
21853
|
-
const child2 = (0,
|
|
21987
|
+
const child2 = (0, import_node_child_process9.spawn)(up, {
|
|
21854
21988
|
cwd,
|
|
21855
21989
|
shell: true,
|
|
21856
21990
|
// POSIX-only: the process group exists for the group-kill in stopStage. On win32 teardown is
|
|
@@ -22054,7 +22188,7 @@ async function executeWaveLand(plan, deps, opts = { preserveWorktree: true }) {
|
|
|
22054
22188
|
var import_node_os19 = require("node:os");
|
|
22055
22189
|
|
|
22056
22190
|
// src/board.ts
|
|
22057
|
-
var
|
|
22191
|
+
var import_node_child_process10 = require("node:child_process");
|
|
22058
22192
|
var import_node_fs23 = require("node:fs");
|
|
22059
22193
|
var import_node_os8 = require("node:os");
|
|
22060
22194
|
var import_node_path21 = require("node:path");
|
|
@@ -22399,7 +22533,7 @@ function findDuplicateLesson(source, openLessons) {
|
|
|
22399
22533
|
var BOARD_STATUSES = ["Todo", "In Progress", "In Review", "Done"];
|
|
22400
22534
|
|
|
22401
22535
|
// src/board.ts
|
|
22402
|
-
var rawExecFileP3 = (0, import_node_util6.promisify)(
|
|
22536
|
+
var rawExecFileP3 = (0, import_node_util6.promisify)(import_node_child_process10.execFile);
|
|
22403
22537
|
var BOARD_GIT_TIMEOUT_MS = 1e4;
|
|
22404
22538
|
var WRITE_PROBE_CONCURRENCY = 8;
|
|
22405
22539
|
var CLAIM_CONCURRENCY = 5;
|
|
@@ -25452,10 +25586,10 @@ function healClaudeBinary(host = {}, onStep) {
|
|
|
25452
25586
|
}
|
|
25453
25587
|
|
|
25454
25588
|
// src/statusline-invalidate.ts
|
|
25455
|
-
var
|
|
25589
|
+
var import_node_child_process11 = require("node:child_process");
|
|
25456
25590
|
function invalidateStatuslineBoardCache() {
|
|
25457
25591
|
try {
|
|
25458
|
-
const child2 = (0,
|
|
25592
|
+
const child2 = (0, import_node_child_process11.spawn)("jerv-cli", ["lane", "ops", "invalidate-board"], {
|
|
25459
25593
|
detached: true,
|
|
25460
25594
|
stdio: "ignore",
|
|
25461
25595
|
windowsHide: true
|
|
@@ -25674,12 +25808,12 @@ function renderVerifyBroker(input) {
|
|
|
25674
25808
|
}
|
|
25675
25809
|
|
|
25676
25810
|
// src/hotfix-coverage.ts
|
|
25677
|
-
var
|
|
25811
|
+
var import_node_child_process12 = require("node:child_process");
|
|
25678
25812
|
var CHERRY_TRAILER = /\(cherry picked from commit ([0-9a-f]{7,40})\)/g;
|
|
25679
25813
|
function checkHotfixCoverage(options = {}) {
|
|
25680
25814
|
const { cwd = process.cwd(), mainRef = "origin/main", rcRef = "origin/rc", manifestPaths = [] } = options;
|
|
25681
25815
|
const ack = (options.ack ?? []).filter(Boolean);
|
|
25682
|
-
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"] }));
|
|
25683
25817
|
const revList = (range) => {
|
|
25684
25818
|
const out = git2(["rev-list", "--no-merges", range]).trim();
|
|
25685
25819
|
return out ? out.split("\n") : [];
|
|
@@ -25747,7 +25881,7 @@ function checkHotfixCoverage(options = {}) {
|
|
|
25747
25881
|
}
|
|
25748
25882
|
function checkHotfixCarries(options) {
|
|
25749
25883
|
const { cwd = process.cwd(), branch, baseRef, targets } = options;
|
|
25750
|
-
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"] }));
|
|
25751
25885
|
const isAncestor = (sha, ref) => {
|
|
25752
25886
|
try {
|
|
25753
25887
|
git2(["merge-base", "--is-ancestor", sha, ref]);
|
|
@@ -26771,7 +26905,7 @@ async function announceRelease(deps, args) {
|
|
|
26771
26905
|
|
|
26772
26906
|
// src/repo-index.ts
|
|
26773
26907
|
var import_node_crypto4 = require("node:crypto");
|
|
26774
|
-
var
|
|
26908
|
+
var import_node_child_process13 = require("node:child_process");
|
|
26775
26909
|
var import_node_fs27 = require("node:fs");
|
|
26776
26910
|
var import_node_path25 = require("node:path");
|
|
26777
26911
|
var REPO_INDEX_SCHEMA = 1;
|
|
@@ -26917,7 +27051,7 @@ function loadReadmeHints(cwd, candidatePaths) {
|
|
|
26917
27051
|
function toPosix(p) {
|
|
26918
27052
|
return p.split(import_node_path25.sep).join("/");
|
|
26919
27053
|
}
|
|
26920
|
-
function listCandidatePaths(cwd, exec =
|
|
27054
|
+
function listCandidatePaths(cwd, exec = import_node_child_process13.execFileSync) {
|
|
26921
27055
|
try {
|
|
26922
27056
|
const out = exec("git", ["ls-files", "-z", "-c", "-o", "--exclude-standard"], {
|
|
26923
27057
|
cwd,
|
|
@@ -27040,7 +27174,7 @@ function searchRepoIndex(idx, query, limit = 20) {
|
|
|
27040
27174
|
}
|
|
27041
27175
|
return out;
|
|
27042
27176
|
}
|
|
27043
|
-
function inferRepoSlug(cwd, exec =
|
|
27177
|
+
function inferRepoSlug(cwd, exec = import_node_child_process13.execFileSync) {
|
|
27044
27178
|
try {
|
|
27045
27179
|
const url = String(exec("git", ["remote", "get-url", "origin"], { cwd, encoding: "utf8" })).trim();
|
|
27046
27180
|
const m = /[:/]([^/]+\/[^/]+?)(?:\.git)?$/.exec(url);
|
|
@@ -27190,7 +27324,7 @@ async function gcRepoIndexCloud(deps) {
|
|
|
27190
27324
|
var import_node_fs28 = require("node:fs");
|
|
27191
27325
|
var import_node_os12 = require("node:os");
|
|
27192
27326
|
var import_node_path26 = require("node:path");
|
|
27193
|
-
var
|
|
27327
|
+
var import_node_child_process14 = require("node:child_process");
|
|
27194
27328
|
var MAX_EMBED_BACKFILL_ROUNDS = 40;
|
|
27195
27329
|
function normalizeRepo(raw) {
|
|
27196
27330
|
const t = raw.trim().replace(/\.git$/, "");
|
|
@@ -27210,7 +27344,7 @@ function rosterRepos(projects) {
|
|
|
27210
27344
|
}
|
|
27211
27345
|
function shallowClone(repo, dest, token) {
|
|
27212
27346
|
const basic = Buffer.from(`x-access-token:${token}`, "utf8").toString("base64");
|
|
27213
|
-
(0,
|
|
27347
|
+
(0, import_node_child_process14.execFileSync)(
|
|
27214
27348
|
"git",
|
|
27215
27349
|
["-c", `http.extraHeader=Authorization: Basic ${basic}`, "clone", "--depth", "1", "--single-branch", `https://github.com/${repo}.git`, dest],
|
|
27216
27350
|
{ encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], windowsHide: true }
|
|
@@ -27479,7 +27613,7 @@ async function runRepoIndexHealth(opts) {
|
|
|
27479
27613
|
}
|
|
27480
27614
|
|
|
27481
27615
|
// src/spawn-policy-core.ts
|
|
27482
|
-
var
|
|
27616
|
+
var import_node_child_process15 = require("node:child_process");
|
|
27483
27617
|
var import_node_fs30 = require("node:fs");
|
|
27484
27618
|
var import_node_path27 = require("node:path");
|
|
27485
27619
|
var SPAWNERS = ["spawn", "spawnSync", "exec", "execSync", "execFile", "execFileSync"];
|
|
@@ -27550,7 +27684,7 @@ function findViolationsInSource(raw) {
|
|
|
27550
27684
|
return found;
|
|
27551
27685
|
}
|
|
27552
27686
|
function policedFiles(root) {
|
|
27553
|
-
const r = (0,
|
|
27687
|
+
const r = (0, import_node_child_process15.spawnSync)("git", ["ls-files", "-z", "--cached", "--others", "--exclude-standard"], {
|
|
27554
27688
|
cwd: root,
|
|
27555
27689
|
encoding: "utf8",
|
|
27556
27690
|
windowsHide: true,
|
|
@@ -27584,7 +27718,7 @@ function runSpawnPolicy(root) {
|
|
|
27584
27718
|
}
|
|
27585
27719
|
|
|
27586
27720
|
// src/test-policy-core.ts
|
|
27587
|
-
var
|
|
27721
|
+
var import_node_child_process16 = require("node:child_process");
|
|
27588
27722
|
var import_node_fs31 = require("node:fs");
|
|
27589
27723
|
var import_node_path28 = require("node:path");
|
|
27590
27724
|
var POLICY_FILE = "test-policy.json";
|
|
@@ -27714,14 +27848,14 @@ function evaluate(changed, policy, present = () => false) {
|
|
|
27714
27848
|
return findings;
|
|
27715
27849
|
}
|
|
27716
27850
|
function git(args, cwd) {
|
|
27717
|
-
return (0,
|
|
27851
|
+
return (0, import_node_child_process16.execFileSync)("git", args, { windowsHide: true, cwd, encoding: "utf8", maxBuffer: 32 * 1024 * 1024 });
|
|
27718
27852
|
}
|
|
27719
27853
|
var COAUTHOR_KEY = "Co-authored-by";
|
|
27720
27854
|
var GH_MESSAGE_SEPARATOR = /^-{5,}$/;
|
|
27721
27855
|
var LIFTED_KEYS = new RegExp(`^(?:${TRAILER_KEY}|${COAUTHOR_KEY}):`, "i");
|
|
27722
27856
|
function parseTrailers(message, cwd) {
|
|
27723
27857
|
try {
|
|
27724
|
-
return (0,
|
|
27858
|
+
return (0, import_node_child_process16.execFileSync)("git", ["interpret-trailers", "--parse", "--unfold"], {
|
|
27725
27859
|
windowsHide: true,
|
|
27726
27860
|
cwd,
|
|
27727
27861
|
input: message,
|
|
@@ -29522,9 +29656,9 @@ ${SSH_RECIPE_AGENT_NOTE}`);
|
|
|
29522
29656
|
|
|
29523
29657
|
// src/schedules-commands.ts
|
|
29524
29658
|
var import_promises5 = require("node:fs/promises");
|
|
29525
|
-
var
|
|
29659
|
+
var import_node_child_process17 = require("node:child_process");
|
|
29526
29660
|
var import_node_util7 = require("node:util");
|
|
29527
|
-
var execFileP5 = (0, import_node_util7.promisify)(
|
|
29661
|
+
var execFileP5 = (0, import_node_util7.promisify)(import_node_child_process17.execFile);
|
|
29528
29662
|
var AWS_REGION = "eu-central-1";
|
|
29529
29663
|
var AWS_TIMEOUT_MS = 3e4;
|
|
29530
29664
|
var AWS_RETRY_DELAY_MS = 1500;
|
|
@@ -32403,7 +32537,7 @@ var import_node_fs38 = require("node:fs");
|
|
|
32403
32537
|
var import_promises8 = require("node:fs/promises");
|
|
32404
32538
|
var import_node_path36 = require("node:path");
|
|
32405
32539
|
var import_node_os15 = require("node:os");
|
|
32406
|
-
var
|
|
32540
|
+
var import_node_child_process18 = require("node:child_process");
|
|
32407
32541
|
|
|
32408
32542
|
// src/board-advance.ts
|
|
32409
32543
|
function repoOf2(ref) {
|
|
@@ -33009,7 +33143,7 @@ async function remoteBranchExists2(branch, options = {}) {
|
|
|
33009
33143
|
}
|
|
33010
33144
|
var COMPOSE_TIMEOUT_MS = 12e4;
|
|
33011
33145
|
function spawnDeferredGcSweep() {
|
|
33012
|
-
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] });
|
|
33013
33147
|
}
|
|
33014
33148
|
async function createDeferredWorktreeStore() {
|
|
33015
33149
|
try {
|
|
@@ -36689,7 +36823,8 @@ var RESTART_LINE = "\u21BB Restart Claude to finish.";
|
|
|
36689
36823
|
var VERBOSE_INDENT = " ";
|
|
36690
36824
|
function checkGlyph(check) {
|
|
36691
36825
|
if (!check.ok) return "\u2717";
|
|
36692
|
-
|
|
36826
|
+
if (check.verified === false) return "?";
|
|
36827
|
+
return check.warn ? "\u26A0" : "\u2713";
|
|
36693
36828
|
}
|
|
36694
36829
|
function renderCheckLine(check) {
|
|
36695
36830
|
const head = check.detail ? `${checkGlyph(check)} ${check.label} \u2014 ${check.detail}` : `${checkGlyph(check)} ${check.label}`;
|
|
@@ -36707,9 +36842,11 @@ function renderTally(checks) {
|
|
|
36707
36842
|
const total = checks.length;
|
|
36708
36843
|
const failed = checks.filter((c) => !c.ok).length;
|
|
36709
36844
|
const unverified = checks.filter((c) => c.ok && c.verified === false).length;
|
|
36710
|
-
const
|
|
36711
|
-
|
|
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`;
|
|
36712
36848
|
const parts = [`\u2713 ${healthy} verified healthy`];
|
|
36849
|
+
if (warned > 0) parts.push(`\u26A0 ${warned} warn`);
|
|
36713
36850
|
if (unverified > 0) parts.push(`? ${unverified} unverified`);
|
|
36714
36851
|
if (failed > 0) parts.push(`\u2717 ${failed} failed`);
|
|
36715
36852
|
return `${parts.join(" \xB7 ")} \u2014 ${total} checks`;
|
|
@@ -38359,18 +38496,19 @@ async function runDoctorClean(opts, io, deps) {
|
|
|
38359
38496
|
if (payload) emitNow(payload);
|
|
38360
38497
|
}
|
|
38361
38498
|
async function runMarketplaceRows() {
|
|
38499
|
+
let healed;
|
|
38362
38500
|
if (applyEnv) {
|
|
38363
|
-
|
|
38364
|
-
if (healed) {
|
|
38501
|
+
healed = deps.healMarketplacePins();
|
|
38502
|
+
if (healed?.wrote) {
|
|
38365
38503
|
healIntent(`marketplace pins \u2014 ${healed.detail}`);
|
|
38366
|
-
|
|
38367
|
-
|
|
38368
|
-
|
|
38369
|
-
restartPending = true;
|
|
38370
|
-
}
|
|
38504
|
+
traceHeal("env-heals");
|
|
38505
|
+
markHealChanged();
|
|
38506
|
+
restartPending = true;
|
|
38371
38507
|
}
|
|
38372
38508
|
}
|
|
38373
|
-
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
|
+
}
|
|
38374
38512
|
}
|
|
38375
38513
|
async function runTrainSyncRow() {
|
|
38376
38514
|
try {
|
|
@@ -38903,9 +39041,9 @@ function ghAccountCaveat(announcedLogin, accounts) {
|
|
|
38903
39041
|
var import_node_fs45 = require("node:fs");
|
|
38904
39042
|
var import_node_os18 = require("node:os");
|
|
38905
39043
|
var import_node_path42 = require("node:path");
|
|
38906
|
-
var
|
|
39044
|
+
var import_node_child_process19 = require("node:child_process");
|
|
38907
39045
|
var import_node_util8 = require("node:util");
|
|
38908
|
-
var execFileP6 = (0, import_node_util8.promisify)(
|
|
39046
|
+
var execFileP6 = (0, import_node_util8.promisify)(import_node_child_process19.execFile);
|
|
38909
39047
|
var MMI_PLUGIN_ID2 = "mmi@mutmutco";
|
|
38910
39048
|
function installedClaudePluginVersion() {
|
|
38911
39049
|
try {
|
|
@@ -38951,12 +39089,12 @@ function installedSurfacePluginVersion(surface) {
|
|
|
38951
39089
|
if (token === "claude") return installedClaudePluginVersion();
|
|
38952
39090
|
if (token !== "codex") return void 0;
|
|
38953
39091
|
try {
|
|
38954
|
-
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"], {
|
|
38955
39093
|
encoding: "utf8",
|
|
38956
39094
|
stdio: ["ignore", "pipe", "ignore"],
|
|
38957
39095
|
timeout: 15e3,
|
|
38958
39096
|
windowsHide: true
|
|
38959
|
-
}) : (0,
|
|
39097
|
+
}) : (0, import_node_child_process19.execFileSync)("codex", ["plugin", "list", "--json"], {
|
|
38960
39098
|
encoding: "utf8",
|
|
38961
39099
|
stdio: ["ignore", "pipe", "ignore"],
|
|
38962
39100
|
timeout: 15e3,
|
|
@@ -38974,7 +39112,7 @@ function installedActivePluginVersion(surface = detectSurface(process.env)) {
|
|
|
38974
39112
|
}
|
|
38975
39113
|
function worktreeRootSync() {
|
|
38976
39114
|
try {
|
|
38977
|
-
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"] });
|
|
38978
39116
|
let root = out.endsWith("\n") ? out.slice(0, -1) : out;
|
|
38979
39117
|
if (process.platform === "win32" && root.endsWith("\r")) root = root.slice(0, -1);
|
|
38980
39118
|
return root || null;
|
|
@@ -39227,7 +39365,7 @@ function mmiDoctorDeps(opts = {}) {
|
|
|
39227
39365
|
sessionPayload: () => readSessionPayload(process.cwd()),
|
|
39228
39366
|
// #3485 items 9 and 8: why the MMI plugin has never printed an "updated ? please restart" notice, and
|
|
39229
39367
|
// which branch it would pick one up from. Two local file reads, no network, fail-soft to no rows.
|
|
39230
|
-
marketplaceRows: () => {
|
|
39368
|
+
marketplaceRows: (hostBlocked) => {
|
|
39231
39369
|
try {
|
|
39232
39370
|
if (detectSurface(process.env) === "codex") return [];
|
|
39233
39371
|
const home = (0, import_node_os19.homedir)();
|
|
@@ -39236,8 +39374,14 @@ function mmiDoctorDeps(opts = {}) {
|
|
|
39236
39374
|
readFileSyncSafe((0, import_node_path43.join)(home, ...KNOWN_MARKETPLACES_RELATIVE), import_node_fs46.readFileSync),
|
|
39237
39375
|
readFileSyncSafe((0, import_node_path43.join)(home, ".claude", "settings.json"), import_node_fs46.readFileSync),
|
|
39238
39376
|
// #3974: this CLI heals these rows, so report mode names the doctor run rather than the hand
|
|
39239
|
-
// edit.
|
|
39240
|
-
|
|
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"
|
|
39241
39385
|
);
|
|
39242
39386
|
const pending = readMarketplacePinPending(
|
|
39243
39387
|
(0, import_node_path43.join)(home, ".claude", "plugins", ".mmi-marketplace-pin-pending.json"),
|
|
@@ -39251,7 +39395,7 @@ function mmiDoctorDeps(opts = {}) {
|
|
|
39251
39395
|
...rest,
|
|
39252
39396
|
ok: true,
|
|
39253
39397
|
warn: true,
|
|
39254
|
-
detail: `pending restart
|
|
39398
|
+
detail: `pending restart \u2014 doctor pinned main at ${pending.at}; restart Claude Code to load it`,
|
|
39255
39399
|
verbose: [...row.verbose ?? [], "known_marketplaces.json was rewritten by the running Claude host after the verified doctor write"]
|
|
39256
39400
|
};
|
|
39257
39401
|
});
|
|
@@ -39864,11 +40008,11 @@ function runWorktreeInstall(command, cwd, quiet, opts) {
|
|
|
39864
40008
|
"pipe"
|
|
39865
40009
|
];
|
|
39866
40010
|
return new Promise((resolve5, reject) => {
|
|
39867
|
-
const child2 = opts?.shell ? (0,
|
|
40011
|
+
const child2 = opts?.shell ? (0, import_node_child_process20.spawn)(command, { cwd, stdio, windowsHide: true, shell: true }) : (() => {
|
|
39868
40012
|
const [bin, ...args] = command.split(" ");
|
|
39869
40013
|
const file = isWin2 ? "cmd.exe" : bin;
|
|
39870
40014
|
const spawnArgs = isWin2 ? ["/c", bin, ...args] : args;
|
|
39871
|
-
return (0,
|
|
40015
|
+
return (0, import_node_child_process20.spawn)(file, spawnArgs, { cwd, stdio, windowsHide: true });
|
|
39872
40016
|
})();
|
|
39873
40017
|
let stderrTail = "";
|
|
39874
40018
|
child2.stderr?.on("data", (chunk) => {
|
|
@@ -40251,7 +40395,7 @@ function scheduleRelatedDiscovery(o) {
|
|
|
40251
40395
|
try {
|
|
40252
40396
|
const args = ["issue", "discover-related", "--number", String(o.number), "--title", o.title, "--body", o.body, "--fail-soft"];
|
|
40253
40397
|
if (o.repo) args.push("--repo", o.repo);
|
|
40254
|
-
spawnDetachedSelf(args, { spawn:
|
|
40398
|
+
spawnDetachedSelf(args, { spawn: import_node_child_process20.spawn, execPath: process.execPath, scriptPath: process.argv[1] }, { cwd: process.cwd() });
|
|
40255
40399
|
} catch {
|
|
40256
40400
|
}
|
|
40257
40401
|
}
|
|
@@ -42849,11 +42993,11 @@ program2.command("session-start").description("run the SessionStart verbs (whoam
|
|
|
42849
42993
|
for (const line of scratchGcLines(process.cwd())) bannerIo.log(line);
|
|
42850
42994
|
const worktreeBanner = worktreeAutoProvisionBanner(process.cwd());
|
|
42851
42995
|
if (worktreeBanner) {
|
|
42852
|
-
spawnDetachedSelf(["worktree", "setup", "--quiet"], { spawn:
|
|
42996
|
+
spawnDetachedSelf(["worktree", "setup", "--quiet"], { spawn: import_node_child_process20.spawn, execPath: process.execPath, scriptPath: process.argv[1] });
|
|
42853
42997
|
bannerIo.log(worktreeBanner);
|
|
42854
42998
|
}
|
|
42855
42999
|
if (shouldSpawnReleaseCatchup((0, import_node_os19.homedir)(), process.env, readReleaseCatchupState)) {
|
|
42856
|
-
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] });
|
|
42857
43001
|
}
|
|
42858
43002
|
if (isLinkedWorktree(process.cwd())) {
|
|
42859
43003
|
const primaryRoot = await primaryCheckoutRoot(process.cwd());
|
package/package.json
CHANGED