muuuuse 2.3.5 → 3.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "muuuuse",
3
- "version": "2.3.5",
3
+ "version": "3.1.1",
4
4
  "description": "🔌Muuuuse arms regular terminals in isolated pairs and can continue relay output into any other armed seat.",
5
5
  "type": "commonjs",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -116,10 +116,10 @@ function renderLinkTargets(seat) {
116
116
  for (const target of Array.isArray(seat.continueTargets) ? seat.continueTargets : []) {
117
117
  targets.push(target);
118
118
  }
119
-
120
- return targets
121
- .map((target) => `${target.targetSeatId}:${target.flowMode}`)
122
- .join(", ");
119
+ if (targets.length === 0) {
120
+ return "";
121
+ }
122
+ return targets.map((target) => `${target.targetSeatId}:${target.flowMode}`).join(", ");
123
123
  }
124
124
 
125
125
  function parseSeatOptions(command, args) {
@@ -127,90 +127,47 @@ function parseSeatOptions(command, args) {
127
127
  let flowMode = "off";
128
128
  let continueSeatId = null;
129
129
  let continueTargets = [];
130
- let index = 0;
131
-
132
- while (index < args.length) {
133
- const token = String(args[index] || "").trim().toLowerCase();
130
+ if (args.length === 0) {
131
+ return { flowMode, continueSeatId, continueTargets };
132
+ }
134
133
 
135
- if (token === "flow") {
136
- const flowToken = String(args[index + 1] || "").trim().toLowerCase();
137
- if (flowToken === "on" || flowToken === "off") {
138
- flowMode = flowToken;
139
- index += 2;
140
- continue;
141
- }
142
- break;
134
+ if (String(args[0] || "").trim().toLowerCase() === "link") {
135
+ const parsedLinks = parseLinkTargets(args.slice(1), seatId, flowMode);
136
+ if (parsedLinks.consumed === args.length - 1 && parsedLinks.consumed > 0) {
137
+ return {
138
+ flowMode: parsedLinks.flowMode,
139
+ continueSeatId: parsedLinks.continueTargets[0]?.targetSeatId || null,
140
+ continueTargets: parsedLinks.continueTargets,
141
+ };
143
142
  }
144
-
145
- if (token === "continue") {
146
- const parsedTargets = parseContinueTargets(args.slice(index + 1), flowMode);
147
- if (parsedTargets.targets.length > 0) {
148
- continueTargets = mergeTargets(continueTargets, parsedTargets.targets);
149
- continueSeatId = continueTargets[0].targetSeatId;
150
- index += 1 + parsedTargets.consumed;
151
- continue;
152
- }
153
- break;
143
+ } else {
144
+ let index = 0;
145
+
146
+ const flowToken = String(args[index] || "").trim().toLowerCase();
147
+ const flowModeToken = String(args[index + 1] || "").trim().toLowerCase();
148
+ if (flowToken === "flow" && (flowModeToken === "on" || flowModeToken === "off")) {
149
+ flowMode = flowModeToken;
150
+ index += 2;
154
151
  }
155
152
 
156
- if (token === "link") {
157
- const parsedLinks = parseLinkTargets(args.slice(index + 1), seatId, flowMode);
158
- if (parsedLinks.consumed > 0) {
159
- flowMode = parsedLinks.flowMode;
160
- continueTargets = mergeTargets(continueTargets, parsedLinks.continueTargets);
161
- continueSeatId = continueTargets[0]?.targetSeatId || null;
162
- index += 1 + parsedLinks.consumed;
163
- continue;
164
- }
165
- break;
153
+ const continueToken = String(args[index] || "").trim().toLowerCase();
154
+ const targetSeatId = normalizeSeatId(args[index + 1]);
155
+ if (continueToken === "continue" && targetSeatId) {
156
+ continueSeatId = targetSeatId;
157
+ continueTargets = [{ targetSeatId, flowMode }];
158
+ index += 2;
166
159
  }
167
160
 
168
- break;
169
- }
170
-
171
- if (index === args.length) {
172
- return { flowMode, continueSeatId, continueTargets };
161
+ if (index === args.length) {
162
+ return { flowMode, continueSeatId, continueTargets };
163
+ }
173
164
  }
174
165
 
175
166
  throw new Error(
176
- `\`muuuuse ${command}\` accepts no extra arguments, \`flow on\` / \`flow off\`, optional \`continue <seat>\`, or \`link <seat> flow on [<seat> flow off ...]\`. Run it directly in the terminal you want to arm.`
167
+ `\`muuuuse ${command}\` accepts no extra arguments or \`link <seat> flow on [<seat> flow off ...]\`. Run it directly in the terminal you want to arm.`
177
168
  );
178
169
  }
179
170
 
180
- function mergeTargets(existingTargets, nextTargets) {
181
- const merged = [];
182
- for (const target of Array.isArray(existingTargets) ? existingTargets : []) {
183
- upsertTarget(merged, target);
184
- }
185
- for (const target of Array.isArray(nextTargets) ? nextTargets : []) {
186
- upsertTarget(merged, target);
187
- }
188
-
189
- return merged;
190
- }
191
-
192
- function parseContinueTargets(args, defaultFlowMode) {
193
- const targets = [];
194
- let consumed = 0;
195
-
196
- while (consumed < args.length) {
197
- const targetSeatId = normalizeSeatId(args[consumed]);
198
- if (!targetSeatId) {
199
- break;
200
- }
201
-
202
- const nextFlowMode = parseFlowModeToken(args[consumed + 1], args[consumed + 2]);
203
- const target = {
204
- targetSeatId,
205
- flowMode: nextFlowMode || defaultFlowMode,
206
- };
207
- upsertTarget(targets, target);
208
- consumed += nextFlowMode ? 3 : 1;
209
- }
210
-
211
- return { consumed, targets };
212
- }
213
-
214
171
  function parseLinkTargets(args, seatId, defaultFlowMode) {
215
172
  const partnerSeatId = seatId ? getPartnerSeatId(seatId) : null;
216
173
  const continueTargets = [];
@@ -263,4 +220,5 @@ function upsertTarget(targets, nextTarget) {
263
220
 
264
221
  module.exports = {
265
222
  main,
223
+ parseSeatOptions,
266
224
  };
package/src/runtime.js CHANGED
@@ -42,6 +42,7 @@ const {
42
42
 
43
43
  const TYPE_CHUNK_DELAY_MS = 18;
44
44
  const TYPE_CHUNK_SIZE = 24;
45
+ const TYPE_SUBMIT_DELAY_MS = 60;
45
46
  const MIRROR_SUPPRESSION_WINDOW_MS = 30 * 1000;
46
47
  const PENDING_RELAY_CONTEXT_TTL_MS = 2 * 60 * 1000;
47
48
  const EMITTED_ANSWER_TTL_MS = 5 * 60 * 1000;
@@ -620,6 +621,14 @@ async function sendTextAndEnter(child, text, shouldAbort = () => false) {
620
621
  return false;
621
622
  }
622
623
 
624
+ // Some TUIs treat fast, chunked relay typing as paste input and suppress an
625
+ // immediate Enter. A short settle delay keeps submit behavior reliable.
626
+ await sleep(TYPE_SUBMIT_DELAY_MS);
627
+
628
+ if (shouldAbort() || !child) {
629
+ return false;
630
+ }
631
+
623
632
  try {
624
633
  child.write("\r");
625
634
  } catch {
package/src/util.js CHANGED
@@ -287,10 +287,10 @@ function usage() {
287
287
  "Usage:",
288
288
  " muuuuse",
289
289
  " muuuuse 1",
290
+ " muuuuse 1 link 2 flow off",
290
291
  " muuuuse 1 link 2 flow on",
291
292
  " muuuuse 1 link 2 flow on 3 flow off",
292
293
  " muuuuse 2",
293
- " muuuuse 2 link 1 flow on",
294
294
  " muuuuse 3",
295
295
  " muuuuse 4",
296
296
  " muuuuse 4 link 3 flow off 1 flow on",
@@ -298,13 +298,13 @@ function usage() {
298
298
  " muuuuse status",
299
299
  "",
300
300
  "Flow:",
301
- " 1. Run `muuuuse 1` in terminal one.",
302
- " 2. Run `muuuuse 2` in terminal two.",
301
+ " 1. Run `muuuuse 1` in terminal one, then `muuuuse 2` in terminal two.",
302
+ " 2. Bare seats default to final-only pair relay.",
303
303
  " 3. The odd seat generates the session key and the matching even seat signs it automatically.",
304
304
  " 4. Additional pairs work the same way: `3/4`, `5/6`, `7/8`...",
305
- " 5. Use `link <seat> flow on [<seat> flow off ...]` to set each outbound path.",
306
- " 6. Linking the odd/even partner sets the normal pair flow. Extra linked seats become continuations.",
307
- " 7. Legacy `flow on` / `flow off` and `continue` still parse, but `link` is the main command shape.",
305
+ " 5. Use `link <seat> flow on [<seat> flow off ...]` to set each outbound route.",
306
+ " 6. Include the odd/even partner in `link` to set normal pair flow.",
307
+ " 7. Any extra linked seats receive routed copies with their own flow mode.",
308
308
  " 8. `flow off` sends final answers only. `flow on` keeps assistant commentary bouncing.",
309
309
  " 9. Run `muuuuse status` or `muuuuse stop` from any shell.",
310
310
  "",