@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/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 === "-" ? `${labels.file} - read empty stdin (nothing piped \u2014 pass a heredoc/pipe, or ${labels.file} <path>)` : `${labels.file} produced an empty ${labels.noun}`
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(platform, custom) {
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: platform === "win32" };
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 import_node_os = require("node:os");
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, import_node_os.homedir)(), "AppData", "Local");
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, import_node_os.homedir)(), ".mmi");
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
- return stat.isFIFO() || stat.isFile();
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
- async function readStdin() {
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
- for await (const chunk of process.stdin) chunks.push(chunk);
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 import_node_os3 = require("node:os");
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 import_node_os2 = require("node:os");
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, import_node_os2.homedir)(), ".mmi");
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, platform = process.platform, user) {
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, import_node_os2.userInfo)().username;
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 platform === "win32" ? `\\\\.\\pipe\\mmi-cli-${hash}` : (0, import_node_path6.join)(daemonDir(env), `mmi-cli-${hash}.sock`);
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, import_node_os3.tmpdir)());
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, import_node_os3.tmpdir)());
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.36.0",
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",