@mutmutco/cli 2.36.0 → 2.38.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/README.md +1 -0
- package/dist/index.cjs +40 -5
- package/dist/main.cjs +3209 -2528
- package/dist/saga.cjs +60 -18
- package/package.json +1 -1
package/dist/saga.cjs
CHANGED
|
@@ -3443,6 +3443,13 @@ var import_node_crypto3 = require("node:crypto");
|
|
|
3443
3443
|
var import_promises2 = require("node:fs/promises");
|
|
3444
3444
|
|
|
3445
3445
|
// src/issue-body.ts
|
|
3446
|
+
var import_node_os = require("node:os");
|
|
3447
|
+
function emptyStdinMessage(fileFlag) {
|
|
3448
|
+
if ((0, import_node_os.platform)() === "win32") {
|
|
3449
|
+
return `${fileFlag} - read empty stdin (on Windows, ${fileFlag} - is unreliable through the npm .cmd shim \u2014 use ${fileFlag} <path>, or pipe to \`node cli/dist/index.cjs\` directly)`;
|
|
3450
|
+
}
|
|
3451
|
+
return `${fileFlag} - read empty stdin (nothing piped \u2014 pass a heredoc/pipe, or ${fileFlag} <path>)`;
|
|
3452
|
+
}
|
|
3446
3453
|
async function resolveTextArg(input, deps, labels) {
|
|
3447
3454
|
const hasValue = input.value !== void 0;
|
|
3448
3455
|
const hasFile = input.file !== void 0;
|
|
@@ -3457,7 +3464,7 @@ async function resolveTextArg(input, deps, labels) {
|
|
|
3457
3464
|
const text = source === "-" ? await deps.readStdin() : await deps.readFile(source, "utf8");
|
|
3458
3465
|
if (text.trim().length === 0) {
|
|
3459
3466
|
throw new Error(
|
|
3460
|
-
source === "-" ?
|
|
3467
|
+
source === "-" ? emptyStdinMessage(labels.file) : `${labels.file} produced an empty ${labels.noun}`
|
|
3461
3468
|
);
|
|
3462
3469
|
}
|
|
3463
3470
|
return text;
|
|
@@ -3481,9 +3488,9 @@ var HEAD_MIN_INTERVAL_MS = 5 * 60 * 1e3;
|
|
|
3481
3488
|
var HEAD_ENGINE_TIMEOUT_MS = 15e3;
|
|
3482
3489
|
var HEAD_PROMPT_ACTION_LIMIT = 50;
|
|
3483
3490
|
var HEAD_PROMPT_DECISION_LIMIT = 80;
|
|
3484
|
-
function resolveEngine(
|
|
3491
|
+
function resolveEngine(platform2, custom) {
|
|
3485
3492
|
if (custom) return { cmd: custom, args: [], shell: true };
|
|
3486
|
-
return { cmd: "claude", args: ["-p", "--no-session-persistence"], shell:
|
|
3493
|
+
return { cmd: "claude", args: ["-p", "--no-session-persistence"], shell: platform2 === "win32" };
|
|
3487
3494
|
}
|
|
3488
3495
|
function headTsPath(key) {
|
|
3489
3496
|
const safe = (s) => s.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
@@ -4210,7 +4217,7 @@ function formatSnapshotHuman(snapshot) {
|
|
|
4210
4217
|
var import_node_crypto = require("node:crypto");
|
|
4211
4218
|
var import_node_fs5 = require("node:fs");
|
|
4212
4219
|
var import_node_path5 = require("node:path");
|
|
4213
|
-
var
|
|
4220
|
+
var import_node_os2 = require("node:os");
|
|
4214
4221
|
var REFRESH_WINDOW_MS = 10 * 60 * 1e3;
|
|
4215
4222
|
var EXCHANGE_TIMEOUT_MS = 8e3;
|
|
4216
4223
|
var EXCHANGE_ATTEMPTS = 2;
|
|
@@ -4223,10 +4230,10 @@ function tokenFingerprint(token) {
|
|
|
4223
4230
|
function defaultHubSessionCachePath(env = process.env) {
|
|
4224
4231
|
if (env.MMI_HUB_SESSION_CACHE) return env.MMI_HUB_SESSION_CACHE;
|
|
4225
4232
|
if (process.platform === "win32") {
|
|
4226
|
-
const base2 = env.LOCALAPPDATA || (0, import_node_path5.join)((0,
|
|
4233
|
+
const base2 = env.LOCALAPPDATA || (0, import_node_path5.join)((0, import_node_os2.homedir)(), "AppData", "Local");
|
|
4227
4234
|
return (0, import_node_path5.join)(base2, "MMI Future", "mmi-cli", "hub-session.json");
|
|
4228
4235
|
}
|
|
4229
|
-
const base = env.XDG_STATE_HOME || (0, import_node_path5.join)((0,
|
|
4236
|
+
const base = env.XDG_STATE_HOME || (0, import_node_path5.join)((0, import_node_os2.homedir)(), ".mmi");
|
|
4230
4237
|
return (0, import_node_path5.join)(base, "mmi-cli", "hub-session.json");
|
|
4231
4238
|
}
|
|
4232
4239
|
function readCache(path2, apiUrl, now, githubTokenFingerprint) {
|
|
@@ -4363,19 +4370,54 @@ var injectedStdin;
|
|
|
4363
4370
|
function setInjectedStdin(payload) {
|
|
4364
4371
|
injectedStdin = payload;
|
|
4365
4372
|
}
|
|
4366
|
-
function stdinHasPipedInput(statFd = () => (0, import_node_fs6.fstatSync)(0)) {
|
|
4373
|
+
function stdinHasPipedInput(statFd = () => (0, import_node_fs6.fstatSync)(0), getIsTTY = () => process.stdin.isTTY) {
|
|
4367
4374
|
try {
|
|
4368
4375
|
const stat = statFd();
|
|
4369
|
-
|
|
4376
|
+
if (stat.isFIFO() || stat.isFile()) return true;
|
|
4377
|
+
if (stat.isCharacterDevice()) return false;
|
|
4378
|
+
if (stat.isSocket()) return false;
|
|
4379
|
+
if (getIsTTY() === true) return false;
|
|
4380
|
+
return true;
|
|
4370
4381
|
} catch {
|
|
4371
4382
|
return false;
|
|
4372
4383
|
}
|
|
4373
4384
|
}
|
|
4374
|
-
|
|
4385
|
+
var STDIN_MAX_BYTES = 8 * 1024 * 1024;
|
|
4386
|
+
var STDIN_DRAIN_TIMEOUT_MS = 5e3;
|
|
4387
|
+
async function readStdin(opts = {}) {
|
|
4375
4388
|
if (injectedStdin !== void 0) return injectedStdin;
|
|
4376
4389
|
if (!stdinHasPipedInput()) return "";
|
|
4390
|
+
const maxBytes = opts.maxBytes ?? STDIN_MAX_BYTES;
|
|
4391
|
+
const timeoutMs = opts.timeoutMs ?? STDIN_DRAIN_TIMEOUT_MS;
|
|
4377
4392
|
const chunks = [];
|
|
4378
|
-
|
|
4393
|
+
let total = 0;
|
|
4394
|
+
const drain = (async () => {
|
|
4395
|
+
for await (const chunk of process.stdin) {
|
|
4396
|
+
const buf = chunk;
|
|
4397
|
+
const room = maxBytes - total;
|
|
4398
|
+
if (buf.length >= room) {
|
|
4399
|
+
chunks.push(buf.subarray(0, room));
|
|
4400
|
+
total = maxBytes;
|
|
4401
|
+
break;
|
|
4402
|
+
}
|
|
4403
|
+
chunks.push(buf);
|
|
4404
|
+
total += buf.length;
|
|
4405
|
+
}
|
|
4406
|
+
})().catch(() => {
|
|
4407
|
+
});
|
|
4408
|
+
let timer;
|
|
4409
|
+
const timeout = new Promise((resolve) => {
|
|
4410
|
+
timer = setTimeout(resolve, timeoutMs);
|
|
4411
|
+
});
|
|
4412
|
+
try {
|
|
4413
|
+
await Promise.race([drain, timeout]);
|
|
4414
|
+
} finally {
|
|
4415
|
+
if (timer) clearTimeout(timer);
|
|
4416
|
+
try {
|
|
4417
|
+
process.stdin.unref();
|
|
4418
|
+
} catch {
|
|
4419
|
+
}
|
|
4420
|
+
}
|
|
4379
4421
|
return Buffer.concat(chunks).toString("utf8");
|
|
4380
4422
|
}
|
|
4381
4423
|
|
|
@@ -4834,7 +4876,7 @@ function runSagaCli(injectedStdin2) {
|
|
|
4834
4876
|
var import_node_net = require("node:net");
|
|
4835
4877
|
var import_node_crypto5 = require("node:crypto");
|
|
4836
4878
|
var import_node_fs10 = require("node:fs");
|
|
4837
|
-
var
|
|
4879
|
+
var import_node_os4 = require("node:os");
|
|
4838
4880
|
|
|
4839
4881
|
// src/daemon-client.ts
|
|
4840
4882
|
var import_node_fs9 = require("node:fs");
|
|
@@ -4843,7 +4885,7 @@ var import_node_path7 = require("node:path");
|
|
|
4843
4885
|
// src/daemon-protocol.ts
|
|
4844
4886
|
var import_node_crypto4 = require("node:crypto");
|
|
4845
4887
|
var import_node_fs8 = require("node:fs");
|
|
4846
|
-
var
|
|
4888
|
+
var import_node_os3 = require("node:os");
|
|
4847
4889
|
var import_node_path6 = require("node:path");
|
|
4848
4890
|
var DEFAULT_IDLE_EXIT_MS = 30 * 6e4;
|
|
4849
4891
|
function idleExitMs(env = process.env) {
|
|
@@ -4851,7 +4893,7 @@ function idleExitMs(env = process.env) {
|
|
|
4851
4893
|
return Number.isFinite(n) && n > 0 ? n : DEFAULT_IDLE_EXIT_MS;
|
|
4852
4894
|
}
|
|
4853
4895
|
function daemonDir(env = process.env) {
|
|
4854
|
-
return env.MMI_CLI_DAEMON_DIR || (0, import_node_path6.join)((0,
|
|
4896
|
+
return env.MMI_CLI_DAEMON_DIR || (0, import_node_path6.join)((0, import_node_os3.homedir)(), ".mmi");
|
|
4855
4897
|
}
|
|
4856
4898
|
function tokenPath(env = process.env) {
|
|
4857
4899
|
return (0, import_node_path6.join)(daemonDir(env), "daemon-token");
|
|
@@ -4872,18 +4914,18 @@ function tokensEqual(a, b) {
|
|
|
4872
4914
|
const hb = (0, import_node_crypto4.createHash)("sha256").update(b).digest();
|
|
4873
4915
|
return (0, import_node_crypto4.timingSafeEqual)(ha, hb);
|
|
4874
4916
|
}
|
|
4875
|
-
function socketPath(env = process.env,
|
|
4917
|
+
function socketPath(env = process.env, platform2 = process.platform, user) {
|
|
4876
4918
|
if (env.MMI_CLI_DAEMON_SOCKET) return env.MMI_CLI_DAEMON_SOCKET;
|
|
4877
4919
|
let name = user;
|
|
4878
4920
|
if (!name) {
|
|
4879
4921
|
try {
|
|
4880
|
-
name = (0,
|
|
4922
|
+
name = (0, import_node_os3.userInfo)().username;
|
|
4881
4923
|
} catch {
|
|
4882
4924
|
name = env.USERNAME || env.USER || "default";
|
|
4883
4925
|
}
|
|
4884
4926
|
}
|
|
4885
4927
|
const hash = (0, import_node_crypto4.createHash)("sha256").update(name).digest("hex").slice(0, 12);
|
|
4886
|
-
return
|
|
4928
|
+
return platform2 === "win32" ? `\\\\.\\pipe\\mmi-cli-${hash}` : (0, import_node_path6.join)(daemonDir(env), `mmi-cli-${hash}.sock`);
|
|
4887
4929
|
}
|
|
4888
4930
|
var HOT_VERBS = /* @__PURE__ */ new Set(["note", "probe", "capture", "session", "head-update"]);
|
|
4889
4931
|
function argvReadsStdin(args) {
|
|
@@ -4974,7 +5016,7 @@ async function handleRequest(req, stamp) {
|
|
|
4974
5016
|
console.error = orig.error;
|
|
4975
5017
|
setInjectedStdin(void 0);
|
|
4976
5018
|
try {
|
|
4977
|
-
process.chdir((0,
|
|
5019
|
+
process.chdir((0, import_node_os4.tmpdir)());
|
|
4978
5020
|
} catch {
|
|
4979
5021
|
}
|
|
4980
5022
|
}
|
|
@@ -5096,7 +5138,7 @@ function startDaemon(deps = {}) {
|
|
|
5096
5138
|
}
|
|
5097
5139
|
function runDaemon() {
|
|
5098
5140
|
try {
|
|
5099
|
-
process.chdir((0,
|
|
5141
|
+
process.chdir((0, import_node_os4.tmpdir)());
|
|
5100
5142
|
} catch {
|
|
5101
5143
|
}
|
|
5102
5144
|
process.on("uncaughtException", () => process.exit(1));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mutmutco/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.38.0",
|
|
4
4
|
"description": "MMI Future CLI — delivers the org rules (whole-file), plus saga and KB access. The cross-IDE engine the plugin's SessionStart hook drives.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|