muuuuse 0.2.0 → 1.3.1

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/src/util.js CHANGED
@@ -5,18 +5,17 @@ const path = require("node:path");
5
5
  const { spawnSync } = require("node:child_process");
6
6
 
7
7
  const BRAND = "🔌Muuuuse";
8
- const POLL_MS = 900;
9
- const CONTROLLER_WAIT_MS = 1000;
8
+ const POLL_MS = 250;
10
9
  const SESSION_MATCH_WINDOW_MS = 5 * 60 * 1000;
11
10
  const MAX_RELAY_CHARS = 4000;
12
11
 
13
12
  const FLAG_ALIASES = new Map([
14
13
  ["--max-relays", "maxRelays"],
15
- ["--seed-seat", "seedSeat"],
16
- ["--step", "step"],
14
+ ["--no-preset", "noPreset"],
15
+ ["--session", "session"],
17
16
  ]);
18
17
 
19
- const MULTI_FLAGS = new Set(["step"]);
18
+ const BOOLEAN_FLAGS = new Set(["noPreset"]);
20
19
 
21
20
  function shellEscape(value) {
22
21
  return `'${String(value).replace(/'/g, `'\\''`)}'`;
@@ -121,10 +120,6 @@ function readCommandVersion(command, args = ["--version"]) {
121
120
  return (result.stdout || result.stderr || "").trim().split("\n")[0] || null;
122
121
  }
123
122
 
124
- function findFirstExisting(paths) {
125
- return paths.find((candidate) => fs.existsSync(candidate)) || null;
126
- }
127
-
128
123
  function stripAnsi(text) {
129
124
  return String(text || "").replace(
130
125
  // eslint-disable-next-line no-control-regex
@@ -172,10 +167,27 @@ function slugifySegment(value) {
172
167
  .replace(/^-+|-+$/g, "") || "default";
173
168
  }
174
169
 
170
+ function hashText(text) {
171
+ return createHash("sha1").update(String(text || "")).digest("hex");
172
+ }
173
+
175
174
  function getStateRoot() {
176
175
  return ensureDir(path.join(os.homedir(), ".muuuuse"));
177
176
  }
178
177
 
178
+ function getDefaultSessionName(currentPath = process.cwd()) {
179
+ const resolvedPath = (() => {
180
+ try {
181
+ return fs.realpathSync(currentPath);
182
+ } catch (error) {
183
+ return path.resolve(currentPath);
184
+ }
185
+ })();
186
+
187
+ const label = slugifySegment(path.basename(resolvedPath));
188
+ return `${label}-${hashText(resolvedPath).slice(0, 8)}`;
189
+ }
190
+
179
191
  function getSessionDir(sessionName) {
180
192
  return ensureDir(path.join(getStateRoot(), "sessions", slugifySegment(sessionName)));
181
193
  }
@@ -188,29 +200,18 @@ function getSeatPaths(sessionName, seatId) {
188
200
  const dir = getSeatDir(sessionName, seatId);
189
201
  return {
190
202
  dir,
191
- metaPath: path.join(dir, "meta.json"),
192
- daemonPath: path.join(dir, "daemon.json"),
193
- commandsPath: path.join(dir, "commands.jsonl"),
194
203
  eventsPath: path.join(dir, "events.jsonl"),
195
- scriptPath: path.join(dir, "script.json"),
204
+ metaPath: path.join(dir, "meta.json"),
196
205
  statusPath: path.join(dir, "status.json"),
197
206
  };
198
207
  }
199
208
 
200
- function getControllerPath(sessionName) {
201
- return path.join(getSessionDir(sessionName), "controller.json");
202
- }
203
-
204
- function hashText(text) {
205
- return createHash("sha1").update(String(text || "")).digest("hex");
206
- }
207
-
208
209
  function parseFlags(argv) {
209
210
  const positionals = [];
210
211
  const flags = {
211
- step: [],
212
212
  maxRelays: Number.POSITIVE_INFINITY,
213
- seedSeat: 1,
213
+ noPreset: false,
214
+ session: null,
214
215
  };
215
216
 
216
217
  for (let index = 0; index < argv.length; index += 1) {
@@ -226,6 +227,11 @@ function parseFlags(argv) {
226
227
  throw new Error(`Unknown flag: ${rawFlag}`);
227
228
  }
228
229
 
230
+ if (BOOLEAN_FLAGS.has(key)) {
231
+ flags[key] = true;
232
+ continue;
233
+ }
234
+
229
235
  const next = inlineValue !== undefined ? inlineValue : argv[index + 1];
230
236
  if (inlineValue === undefined) {
231
237
  index += 1;
@@ -235,18 +241,12 @@ function parseFlags(argv) {
235
241
  throw new Error(`Missing value for ${rawFlag}`);
236
242
  }
237
243
 
238
- if (MULTI_FLAGS.has(key)) {
239
- flags[key].push(next);
240
- continue;
241
- }
242
-
243
244
  flags[key] = next;
244
245
  }
245
246
 
246
247
  flags.maxRelays = flags.maxRelays === Number.POSITIVE_INFINITY
247
248
  ? Number.POSITIVE_INFINITY
248
249
  : toInt(flags.maxRelays, Number.POSITIVE_INFINITY);
249
- flags.seedSeat = toInt(flags.seedSeat, 1);
250
250
 
251
251
  return {
252
252
  positionals,
@@ -256,33 +256,31 @@ function parseFlags(argv) {
256
256
 
257
257
  function usage() {
258
258
  return [
259
- `${BRAND} is the local-only 3-seat relay for Codex, Claude, Gemini, or deterministic scripts.`,
259
+ `${BRAND} wraps two local programs and bounces final blocks between them.`,
260
260
  "",
261
261
  "Usage:",
262
- " muuuuse 1",
263
- " muuuuse 2",
264
- " muuuuse 3 [optional kickoff prompt]",
265
- " muuuuse script [count] [--step <text>]",
266
- " muuuuse live",
262
+ " muuuuse 1 <program...>",
263
+ " muuuuse 2 <program...>",
264
+ " muuuuse 3 stop",
265
+ " muuuuse 3 status",
267
266
  " muuuuse doctor",
268
267
  "",
269
- "Flow:",
270
- " 1. Run `muuuuse 1` in the first tmux terminal.",
271
- " 2. Run `muuuuse 2` in the second tmux terminal.",
272
- " 3. Launch Codex, Claude, Gemini, or `muuuuse script` inside those armed seats.",
273
- " 4. Run `muuuuse 3` in the control terminal to auto-pair the two seats.",
268
+ "Examples:",
269
+ " muuuuse 1 codex",
270
+ " muuuuse 2 gemini",
271
+ " muuuuse 3 stop",
272
+ " muuuuse 1 bash -lc 'while read line; do printf \"script one: %s\\n\\n\" \"$line\"; done'",
274
273
  "",
275
274
  "Notes:",
276
- " - Visible brand: 🔌Muuuuse",
277
- " - Remote routing belongs to Codeman / codemansbot, not this package.",
278
- " - Optional kickoff: `muuuuse 3 \"Start by proposing the first concrete repo task.\"`",
279
- " - Optional script loop: `muuuuse script 4` captures four prompts and cycles them forever.",
275
+ " - Seats auto-pair by current working directory by default.",
276
+ " - Use `--session <name>` on seats and seat 3 if you want an explicit shared lane.",
277
+ " - Known presets (`codex`, `claude`, `gemini`) expand to recommended launch flags.",
278
+ " - Any other program runs as-is inside the current terminal under a PTY wrapper.",
280
279
  ].join("\n");
281
280
  }
282
281
 
283
282
  module.exports = {
284
283
  BRAND,
285
- CONTROLLER_WAIT_MS,
286
284
  MAX_RELAY_CHARS,
287
285
  POLL_MS,
288
286
  SESSION_MATCH_WINDOW_MS,
@@ -290,8 +288,7 @@ module.exports = {
290
288
  commandExists,
291
289
  createId,
292
290
  ensureDir,
293
- findFirstExisting,
294
- getControllerPath,
291
+ getDefaultSessionName,
295
292
  getFileSize,
296
293
  getSeatDir,
297
294
  getSeatPaths,