@mutmutco/cli 2.62.0 → 2.64.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/index.cjs CHANGED
@@ -1,28 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __esm = (fn, res, err) => function __init() {
6
- if (err) throw err[0];
7
- try {
8
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
9
- } catch (e) {
10
- throw err = [e], e;
11
- }
12
- };
13
- var __export = (target, all) => {
14
- for (var name in all)
15
- __defProp(target, name, { get: all[name], enumerable: true });
16
- };
17
-
18
- // ../infra/compat.mjs
19
- var init_compat = __esm({
20
- "../infra/compat.mjs"() {
21
- "use strict";
22
- }
23
- });
24
3
 
25
4
  // src/client-version.ts
5
+ var import_node_fs = require("node:fs");
6
+ var import_node_path = require("node:path");
26
7
  function resolveClientVersionManifestCandidates(distDir = __dirname) {
27
8
  return [
28
9
  (0, import_node_path.join)(distDir, "..", "..", ".claude-plugin", "plugin.json"),
@@ -46,287 +27,8 @@ function resolveClientVersion() {
46
27
  }
47
28
  return "0.0.0";
48
29
  }
49
- var import_node_fs, import_node_path;
50
- var init_client_version = __esm({
51
- "src/client-version.ts"() {
52
- "use strict";
53
- import_node_fs = require("node:fs");
54
- import_node_path = require("node:path");
55
- init_compat();
56
- }
57
- });
58
-
59
- // src/stdin-inject.ts
60
- function setInjectedStdin(payload) {
61
- injectedStdin = payload;
62
- }
63
- function stdinHasPipedInput(statFd = () => (0, import_node_fs2.fstatSync)(0), getIsTTY = () => process.stdin.isTTY) {
64
- try {
65
- const stat = statFd();
66
- if (stat.isFIFO() || stat.isFile()) return true;
67
- if (stat.isCharacterDevice()) return false;
68
- if (stat.isSocket()) return false;
69
- if (getIsTTY() === true) return false;
70
- return true;
71
- } catch {
72
- return false;
73
- }
74
- }
75
- async function readStdin(opts = {}) {
76
- if (injectedStdin !== void 0) return injectedStdin;
77
- if (!stdinHasPipedInput()) return "";
78
- const maxBytes = opts.maxBytes ?? STDIN_MAX_BYTES;
79
- const timeoutMs = opts.timeoutMs ?? STDIN_DRAIN_TIMEOUT_MS;
80
- const chunks = [];
81
- let total = 0;
82
- const drain = (async () => {
83
- for await (const chunk of process.stdin) {
84
- const buf = chunk;
85
- const room = maxBytes - total;
86
- if (buf.length >= room) {
87
- chunks.push(buf.subarray(0, room));
88
- total = maxBytes;
89
- break;
90
- }
91
- chunks.push(buf);
92
- total += buf.length;
93
- }
94
- })().catch(() => {
95
- });
96
- let timer;
97
- const timeout = new Promise((resolve) => {
98
- timer = setTimeout(resolve, timeoutMs);
99
- });
100
- try {
101
- await Promise.race([drain, timeout]);
102
- } finally {
103
- if (timer) clearTimeout(timer);
104
- try {
105
- process.stdin.unref();
106
- } catch {
107
- }
108
- }
109
- return Buffer.concat(chunks).toString("utf8");
110
- }
111
- var import_node_fs2, injectedStdin, STDIN_MAX_BYTES, STDIN_DRAIN_TIMEOUT_MS;
112
- var init_stdin_inject = __esm({
113
- "src/stdin-inject.ts"() {
114
- "use strict";
115
- import_node_fs2 = require("node:fs");
116
- STDIN_MAX_BYTES = 8 * 1024 * 1024;
117
- STDIN_DRAIN_TIMEOUT_MS = 5e3;
118
- }
119
- });
120
-
121
- // src/daemon-protocol.ts
122
- function daemonDir(env = process.env) {
123
- return env.MMI_CLI_DAEMON_DIR || (0, import_node_path2.join)((0, import_node_os.homedir)(), ".mmi");
124
- }
125
- function tokenPath(env = process.env) {
126
- return (0, import_node_path2.join)(daemonDir(env), "daemon-token");
127
- }
128
- function readDaemonToken(env = process.env) {
129
- try {
130
- const t = (0, import_node_fs3.readFileSync)(tokenPath(env), "utf8").trim();
131
- return t.length > 0 ? t : void 0;
132
- } catch {
133
- return void 0;
134
- }
135
- }
136
- function socketPath(env = process.env, platform = process.platform, user) {
137
- if (env.MMI_CLI_DAEMON_SOCKET) return env.MMI_CLI_DAEMON_SOCKET;
138
- let name = user;
139
- if (!name) {
140
- try {
141
- name = (0, import_node_os.userInfo)().username;
142
- } catch {
143
- name = env.USERNAME || env.USER || "default";
144
- }
145
- }
146
- const hash = (0, import_node_crypto.createHash)("sha256").update(name).digest("hex").slice(0, 12);
147
- return platform === "win32" ? `\\\\.\\pipe\\mmi-cli-${hash}` : (0, import_node_path2.join)(daemonDir(env), `mmi-cli-${hash}.sock`);
148
- }
149
- function argvReadsStdin(args) {
150
- for (let i = 0; i < args.length; i++) {
151
- const a = args[i];
152
- if (a.endsWith("-file=-")) return true;
153
- if (a.endsWith("-file") && args[i + 1] === "-") return true;
154
- }
155
- return false;
156
- }
157
- function daemonEligible(args) {
158
- const verb2 = args[1] ?? "";
159
- return args[0] === "saga" && HOT_VERBS.has(verb2) && !CONTINUITY_HOT_VERBS.has(verb2) && !args.includes("--run") && !args.includes("--help") && !args.includes("-h") && !argvReadsStdin(args);
160
- }
161
- function buildStamp(version, bundleMtimeMs) {
162
- return `${version}#${Math.trunc(bundleMtimeMs)}`;
163
- }
164
- function parseLine(line) {
165
- try {
166
- const v = JSON.parse(line);
167
- return v && typeof v === "object" ? v : void 0;
168
- } catch {
169
- return void 0;
170
- }
171
- }
172
- var import_node_crypto, import_node_fs3, import_node_os, import_node_path2, DEFAULT_IDLE_EXIT_MS, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_RESPONSE_TIMEOUT_MS, HOT_VERBS, CONTINUITY_HOT_VERBS, STDIN_VERBS, encodeLine, MAX_FRAME_LENGTH, LineBuffer;
173
- var init_daemon_protocol = __esm({
174
- "src/daemon-protocol.ts"() {
175
- "use strict";
176
- import_node_crypto = require("node:crypto");
177
- import_node_fs3 = require("node:fs");
178
- import_node_os = require("node:os");
179
- import_node_path2 = require("node:path");
180
- DEFAULT_IDLE_EXIT_MS = 30 * 6e4;
181
- DEFAULT_CONNECT_TIMEOUT_MS = 200;
182
- DEFAULT_RESPONSE_TIMEOUT_MS = 2e3;
183
- HOT_VERBS = /* @__PURE__ */ new Set(["note", "probe", "capture", "session", "head-update"]);
184
- CONTINUITY_HOT_VERBS = /* @__PURE__ */ new Set(["note", "probe", "capture", "session", "head-update"]);
185
- STDIN_VERBS = /* @__PURE__ */ new Set(["capture", "session"]);
186
- encodeLine = (obj) => `${JSON.stringify(obj)}
187
- `;
188
- MAX_FRAME_LENGTH = 1024 * 1024;
189
- LineBuffer = class {
190
- constructor(maxFrameLength = MAX_FRAME_LENGTH) {
191
- this.maxFrameLength = maxFrameLength;
192
- }
193
- maxFrameLength;
194
- buf = "";
195
- push(chunk) {
196
- this.buf += chunk;
197
- const parts = this.buf.split("\n");
198
- this.buf = parts.pop() ?? "";
199
- if (this.buf.length > this.maxFrameLength || parts.some((p) => p.length > this.maxFrameLength)) {
200
- this.buf = "";
201
- throw new RangeError("daemon frame too long");
202
- }
203
- return parts.filter((p) => p.length > 0);
204
- }
205
- };
206
- }
207
- });
208
-
209
- // src/daemon-client.ts
210
- var daemon_client_exports = {};
211
- __export(daemon_client_exports, {
212
- clientStamp: () => clientStamp,
213
- spawnDaemon: () => spawnDaemon,
214
- tryDaemonRun: () => tryDaemonRun
215
- });
216
- function clientStamp() {
217
- let mtime = 0;
218
- try {
219
- mtime = (0, import_node_fs4.statSync)((0, import_node_path3.join)(__dirname, "index.cjs")).mtimeMs;
220
- } catch {
221
- }
222
- return buildStamp(resolveClientVersion(), mtime);
223
- }
224
- function spawnDaemon() {
225
- try {
226
- (0, import_node_child_process.spawn)(process.execPath, [process.argv[1], "daemon", "--run"], {
227
- detached: true,
228
- stdio: "ignore",
229
- windowsHide: true,
230
- cwd: (0, import_node_os2.tmpdir)()
231
- }).unref();
232
- } catch {
233
- }
234
- }
235
- function requestOnce(req, path, connectTimeoutMs, responseTimeoutMs) {
236
- return new Promise((resolve) => {
237
- let socket;
238
- try {
239
- socket = (0, import_node_net.connect)(path);
240
- } catch {
241
- return resolve(void 0);
242
- }
243
- let done = false;
244
- let responseTimer;
245
- const connectTimer = setTimeout(() => finish(void 0), connectTimeoutMs);
246
- function finish(v) {
247
- if (done) return;
248
- done = true;
249
- clearTimeout(connectTimer);
250
- if (responseTimer) clearTimeout(responseTimer);
251
- try {
252
- socket.destroy();
253
- } catch {
254
- }
255
- resolve(v);
256
- }
257
- const lb = new LineBuffer();
258
- socket.setEncoding("utf8");
259
- socket.on("connect", () => {
260
- clearTimeout(connectTimer);
261
- responseTimer = setTimeout(() => finish(void 0), responseTimeoutMs);
262
- socket.write(encodeLine(req));
263
- });
264
- socket.on("data", (chunk) => {
265
- let lines;
266
- try {
267
- lines = lb.push(chunk);
268
- } catch {
269
- return finish(void 0);
270
- }
271
- if (lines.length) finish(parseLine(lines[0]));
272
- });
273
- socket.on("error", () => finish(void 0));
274
- socket.on("close", () => finish(void 0));
275
- });
276
- }
277
- async function tryDaemonRun(args, deps = {}) {
278
- const env = deps.env ?? process.env;
279
- if (env.MMI_CLI_NO_DAEMON) return { handled: false };
280
- if (!daemonEligible(args)) return { handled: false };
281
- const respawn = deps.spawnDaemon ?? spawnDaemon;
282
- let stdin;
283
- try {
284
- if (STDIN_VERBS.has(args[1] ?? "")) {
285
- stdin = await (deps.readInput ?? readStdin)();
286
- setInjectedStdin(stdin);
287
- }
288
- const req = {
289
- args,
290
- cwd: process.cwd(),
291
- stamp: deps.stamp ?? clientStamp(),
292
- token: deps.token ?? readDaemonToken(env) ?? "",
293
- ...stdin !== void 0 ? { stdin } : {}
294
- };
295
- const resp = await requestOnce(
296
- req,
297
- deps.path ?? socketPath(env),
298
- deps.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS,
299
- deps.responseTimeoutMs ?? DEFAULT_RESPONSE_TIMEOUT_MS
300
- );
301
- if (!resp || resp.restart) {
302
- respawn();
303
- return { handled: false, stdin };
304
- }
305
- if (resp.decline || typeof resp.code !== "number") return { handled: false, stdin };
306
- if (resp.stdout) (deps.out ?? ((s) => process.stdout.write(s)))(resp.stdout);
307
- if (resp.stderr) (deps.errOut ?? ((s) => process.stderr.write(s)))(resp.stderr);
308
- return { handled: true, code: resp.code };
309
- } catch {
310
- return { handled: false, stdin };
311
- }
312
- }
313
- var import_node_net, import_node_child_process, import_node_fs4, import_node_os2, import_node_path3;
314
- var init_daemon_client = __esm({
315
- "src/daemon-client.ts"() {
316
- "use strict";
317
- import_node_net = require("node:net");
318
- import_node_child_process = require("node:child_process");
319
- import_node_fs4 = require("node:fs");
320
- import_node_os2 = require("node:os");
321
- import_node_path3 = require("node:path");
322
- init_client_version();
323
- init_stdin_inject();
324
- init_daemon_protocol();
325
- }
326
- });
327
30
 
328
31
  // src/boot.ts
329
- init_client_version();
330
32
  function requireSibling(name) {
331
33
  try {
332
34
  return require(name);
@@ -340,14 +42,6 @@ function requireSibling(name) {
340
42
  var verb = process.argv[2];
341
43
  if (process.argv.length === 3 && (verb === "--version" || verb === "-V")) {
342
44
  console.log(resolveClientVersion());
343
- } else if (verb === "saga") {
344
- void Promise.resolve().then(() => (init_daemon_client(), daemon_client_exports)).then(async (c) => {
345
- const r = await c.tryDaemonRun(process.argv.slice(2)).catch(() => ({ handled: false }));
346
- if (r.handled) process.exitCode = r.code;
347
- else requireSibling("./saga.cjs")?.runSagaCli("stdin" in r ? r.stdin : void 0);
348
- });
349
- } else if (verb === "daemon" && process.argv[3] === "--run" && process.argv.length === 4) {
350
- requireSibling("./saga.cjs")?.runDaemon();
351
45
  } else {
352
46
  requireSibling("./main.cjs");
353
47
  }