muuuuse 2.3.3 → 2.3.5
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 +1 -1
- package/src/cli.js +127 -20
- package/src/runtime.js +78 -22
- package/src/util.js +8 -10
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { BRAND, normalizeSeatId, usage } = require("./util");
|
|
1
|
+
const { BRAND, getPartnerSeatId, normalizeSeatId, usage } = require("./util");
|
|
2
2
|
const { ArmedSeat, getStatusReport, stopAllSessions } = require("./runtime");
|
|
3
3
|
|
|
4
4
|
async function main(argv = process.argv.slice(2)) {
|
|
@@ -56,9 +56,10 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
56
56
|
|
|
57
57
|
const seatId = normalizeSeatId(command);
|
|
58
58
|
if (seatId) {
|
|
59
|
-
const { flowMode, continueSeatId } = parseSeatOptions(command, argv.slice(1));
|
|
59
|
+
const { flowMode, continueSeatId, continueTargets } = parseSeatOptions(command, argv.slice(1));
|
|
60
60
|
const seat = new ArmedSeat({
|
|
61
61
|
cwd: process.cwd(),
|
|
62
|
+
continueTargets,
|
|
62
63
|
continueSeatId,
|
|
63
64
|
flowMode,
|
|
64
65
|
seatId,
|
|
@@ -83,8 +84,9 @@ function renderSeatStatus(seat) {
|
|
|
83
84
|
if (seat.partnerLive) {
|
|
84
85
|
bits.push("peer live");
|
|
85
86
|
}
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
const renderedLinks = renderLinkTargets(seat);
|
|
88
|
+
if (renderedLinks) {
|
|
89
|
+
bits.push(`link ${renderedLinks}`);
|
|
88
90
|
}
|
|
89
91
|
if (seat.trust) {
|
|
90
92
|
bits.push(`trust ${seat.trust}`);
|
|
@@ -103,11 +105,31 @@ function renderSeatStatus(seat) {
|
|
|
103
105
|
return output;
|
|
104
106
|
}
|
|
105
107
|
|
|
108
|
+
function renderLinkTargets(seat) {
|
|
109
|
+
const targets = [];
|
|
110
|
+
if (seat.partnerSeatId) {
|
|
111
|
+
targets.push({
|
|
112
|
+
targetSeatId: seat.partnerSeatId,
|
|
113
|
+
flowMode: seat.flowMode || "off",
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
for (const target of Array.isArray(seat.continueTargets) ? seat.continueTargets : []) {
|
|
117
|
+
targets.push(target);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return targets
|
|
121
|
+
.map((target) => `${target.targetSeatId}:${target.flowMode}`)
|
|
122
|
+
.join(", ");
|
|
123
|
+
}
|
|
124
|
+
|
|
106
125
|
function parseSeatOptions(command, args) {
|
|
126
|
+
const seatId = normalizeSeatId(command);
|
|
107
127
|
let flowMode = "off";
|
|
108
128
|
let continueSeatId = null;
|
|
129
|
+
let continueTargets = [];
|
|
130
|
+
let index = 0;
|
|
109
131
|
|
|
110
|
-
|
|
132
|
+
while (index < args.length) {
|
|
111
133
|
const token = String(args[index] || "").trim().toLowerCase();
|
|
112
134
|
|
|
113
135
|
if (token === "flow") {
|
|
@@ -121,10 +143,23 @@ function parseSeatOptions(command, args) {
|
|
|
121
143
|
}
|
|
122
144
|
|
|
123
145
|
if (token === "continue") {
|
|
124
|
-
const
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
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;
|
|
154
|
+
}
|
|
155
|
+
|
|
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;
|
|
128
163
|
continue;
|
|
129
164
|
}
|
|
130
165
|
break;
|
|
@@ -133,25 +168,97 @@ function parseSeatOptions(command, args) {
|
|
|
133
168
|
break;
|
|
134
169
|
}
|
|
135
170
|
|
|
136
|
-
if (
|
|
137
|
-
return { flowMode, continueSeatId };
|
|
171
|
+
if (index === args.length) {
|
|
172
|
+
return { flowMode, continueSeatId, continueTargets };
|
|
138
173
|
}
|
|
139
174
|
|
|
140
175
|
throw new Error(
|
|
141
|
-
`\`muuuuse ${command}\` accepts no extra arguments, \`flow on\` / \`flow off\`, optional \`continue <seat>\`, or
|
|
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.`
|
|
142
177
|
);
|
|
143
178
|
}
|
|
144
179
|
|
|
145
|
-
function
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
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
|
+
function parseLinkTargets(args, seatId, defaultFlowMode) {
|
|
215
|
+
const partnerSeatId = seatId ? getPartnerSeatId(seatId) : null;
|
|
216
|
+
const continueTargets = [];
|
|
217
|
+
let flowMode = defaultFlowMode;
|
|
218
|
+
let consumed = 0;
|
|
219
|
+
|
|
220
|
+
while (consumed < args.length) {
|
|
221
|
+
const targetSeatId = normalizeSeatId(args[consumed]);
|
|
222
|
+
if (!targetSeatId) {
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const targetFlowMode = parseFlowModeToken(args[consumed + 1], args[consumed + 2]);
|
|
227
|
+
if (!targetFlowMode) {
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (targetSeatId === partnerSeatId) {
|
|
232
|
+
flowMode = targetFlowMode;
|
|
233
|
+
} else {
|
|
234
|
+
upsertTarget(continueTargets, {
|
|
235
|
+
targetSeatId,
|
|
236
|
+
flowMode: targetFlowMode,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
consumed += 3;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return { consumed, continueTargets, flowMode };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function parseFlowModeToken(flowToken, modeToken) {
|
|
247
|
+
const normalizedFlowToken = String(flowToken || "").trim().toLowerCase();
|
|
248
|
+
const normalizedModeToken = String(modeToken || "").trim().toLowerCase();
|
|
249
|
+
if (normalizedFlowToken === "flow" && (normalizedModeToken === "on" || normalizedModeToken === "off")) {
|
|
250
|
+
return normalizedModeToken;
|
|
149
251
|
}
|
|
150
|
-
|
|
151
|
-
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function upsertTarget(targets, nextTarget) {
|
|
256
|
+
const existingIndex = targets.findIndex((entry) => entry.targetSeatId === nextTarget.targetSeatId);
|
|
257
|
+
if (existingIndex >= 0) {
|
|
258
|
+
targets[existingIndex] = nextTarget;
|
|
259
|
+
return;
|
|
152
260
|
}
|
|
153
|
-
|
|
154
|
-
expected.every((value, index) => String(args[index]).trim().toLowerCase() === String(value).trim().toLowerCase());
|
|
261
|
+
targets.push(nextTarget);
|
|
155
262
|
}
|
|
156
263
|
|
|
157
264
|
module.exports = {
|
package/src/runtime.js
CHANGED
|
@@ -91,6 +91,26 @@ function normalizeContinueSeatId(value) {
|
|
|
91
91
|
return seatId || null;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
function normalizeContinueTargets(targets, defaultFlowMode = "off") {
|
|
95
|
+
const normalized = [];
|
|
96
|
+
const seen = new Set();
|
|
97
|
+
|
|
98
|
+
for (const entry of Array.isArray(targets) ? targets : []) {
|
|
99
|
+
const targetSeatId = normalizeSeatId(entry?.targetSeatId ?? entry?.seatId ?? entry);
|
|
100
|
+
if (!targetSeatId || seen.has(targetSeatId)) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
seen.add(targetSeatId);
|
|
105
|
+
normalized.push({
|
|
106
|
+
targetSeatId,
|
|
107
|
+
flowMode: normalizeFlowMode(entry?.flowMode ?? entry?.flow ?? defaultFlowMode),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return normalized;
|
|
112
|
+
}
|
|
113
|
+
|
|
94
114
|
function resolveShell() {
|
|
95
115
|
const shell = String(process.env.SHELL || "").trim();
|
|
96
116
|
return shell || "/bin/bash";
|
|
@@ -471,6 +491,7 @@ function buildAnswerSignaturePayload(sessionName, challenge, entry) {
|
|
|
471
491
|
seatId: entry.seatId,
|
|
472
492
|
origin: entry.origin,
|
|
473
493
|
phase: entry.phase || "final_answer",
|
|
494
|
+
flowMode: entry.flowMode || "off",
|
|
474
495
|
createdAt: entry.createdAt,
|
|
475
496
|
text: entry.text,
|
|
476
497
|
});
|
|
@@ -490,6 +511,7 @@ function buildContinuationEntry(sourceSessionName, targetSeatId, entry) {
|
|
|
490
511
|
chainId: entry.chainId,
|
|
491
512
|
hop: entry.hop,
|
|
492
513
|
sourceAnswerId: entry.id,
|
|
514
|
+
flowMode: entry.flowMode || null,
|
|
493
515
|
publicKey: entry.publicKey || null,
|
|
494
516
|
signature: entry.signature || null,
|
|
495
517
|
};
|
|
@@ -613,9 +635,15 @@ class ArmedSeat {
|
|
|
613
635
|
this.partnerSeatId = getPartnerSeatId(options.seatId);
|
|
614
636
|
this.anchorSeatId = isAnchorSeat(options.seatId) ? options.seatId : this.partnerSeatId;
|
|
615
637
|
this.flowMode = normalizeFlowMode(options.flowMode);
|
|
616
|
-
this.
|
|
638
|
+
this.continueTargets = normalizeContinueTargets(
|
|
639
|
+
options.continueTargets || (
|
|
640
|
+
options.continueSeatId ? [{ targetSeatId: options.continueSeatId, flowMode: options.flowMode }] : []
|
|
641
|
+
),
|
|
642
|
+
this.flowMode
|
|
643
|
+
);
|
|
644
|
+
this.continueSeatId = this.continueTargets[0]?.targetSeatId || normalizeContinueSeatId(options.continueSeatId);
|
|
617
645
|
this.cwd = normalizeWorkingPath(options.cwd);
|
|
618
|
-
if (this.
|
|
646
|
+
if (this.continueTargets.some((target) => target.targetSeatId === this.seatId)) {
|
|
619
647
|
throw new Error(`\`muuuuse ${this.seatId}\` cannot continue to itself.`);
|
|
620
648
|
}
|
|
621
649
|
this.sessionName = resolveSessionName(this.cwd, this.seatId);
|
|
@@ -692,6 +720,7 @@ class ArmedSeat {
|
|
|
692
720
|
sessionName: this.sessionName,
|
|
693
721
|
flowMode: this.flowMode,
|
|
694
722
|
continueSeatId: this.continueSeatId,
|
|
723
|
+
continueTargets: this.continueTargets,
|
|
695
724
|
cwd: this.cwd,
|
|
696
725
|
pid: process.pid,
|
|
697
726
|
childPid: this.childPid,
|
|
@@ -708,6 +737,7 @@ class ArmedSeat {
|
|
|
708
737
|
sessionName: this.sessionName,
|
|
709
738
|
flowMode: this.flowMode,
|
|
710
739
|
continueSeatId: this.continueSeatId,
|
|
740
|
+
continueTargets: this.continueTargets,
|
|
711
741
|
cwd: this.cwd,
|
|
712
742
|
pid: process.pid,
|
|
713
743
|
childPid: this.childPid,
|
|
@@ -1053,18 +1083,23 @@ class ArmedSeat {
|
|
|
1053
1083
|
return Number.isFinite(requestedAtMs) && requestedAtMs > this.startedAtMs;
|
|
1054
1084
|
}
|
|
1055
1085
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1086
|
+
shouldCaptureCommentary() {
|
|
1087
|
+
return this.flowMode === "on" || this.continueTargets.some((target) => target.flowMode === "on");
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
findContinuationTarget(targetSeatId) {
|
|
1091
|
+
const normalizedTargetSeatId = normalizeSeatId(targetSeatId);
|
|
1092
|
+
if (!normalizedTargetSeatId) {
|
|
1058
1093
|
return null;
|
|
1059
1094
|
}
|
|
1060
1095
|
|
|
1061
1096
|
const candidates = listSessionNames()
|
|
1062
1097
|
.map((sessionName) => {
|
|
1063
|
-
if (!getSeatDirIfExists(sessionName,
|
|
1098
|
+
if (!getSeatDirIfExists(sessionName, normalizedTargetSeatId)) {
|
|
1064
1099
|
return null;
|
|
1065
1100
|
}
|
|
1066
1101
|
|
|
1067
|
-
const seat = buildSeatReport(sessionName,
|
|
1102
|
+
const seat = buildSeatReport(sessionName, normalizedTargetSeatId);
|
|
1068
1103
|
if (!seat || !matchesWorkingPath(seat.cwd, this.cwd)) {
|
|
1069
1104
|
return null;
|
|
1070
1105
|
}
|
|
@@ -1105,7 +1140,8 @@ class ArmedSeat {
|
|
|
1105
1140
|
return;
|
|
1106
1141
|
}
|
|
1107
1142
|
|
|
1108
|
-
|
|
1143
|
+
const inboundFlowMode = normalizeFlowMode(entry.flowMode || this.flowMode);
|
|
1144
|
+
if (!shouldAcceptInboundEntry(inboundFlowMode, entry)) {
|
|
1109
1145
|
continue;
|
|
1110
1146
|
}
|
|
1111
1147
|
|
|
@@ -1117,6 +1153,7 @@ class ArmedSeat {
|
|
|
1117
1153
|
seatId: entry.seatId,
|
|
1118
1154
|
origin: entry.origin || "unknown",
|
|
1119
1155
|
phase: getRelayPhase(entry),
|
|
1156
|
+
flowMode: inboundFlowMode,
|
|
1120
1157
|
createdAt: entry.createdAt,
|
|
1121
1158
|
text: payload,
|
|
1122
1159
|
});
|
|
@@ -1172,7 +1209,8 @@ class ArmedSeat {
|
|
|
1172
1209
|
return;
|
|
1173
1210
|
}
|
|
1174
1211
|
|
|
1175
|
-
|
|
1212
|
+
const continueFlowMode = normalizeFlowMode(entry.flowMode || this.flowMode);
|
|
1213
|
+
if (!shouldAcceptInboundEntry(continueFlowMode, entry)) {
|
|
1176
1214
|
continue;
|
|
1177
1215
|
}
|
|
1178
1216
|
|
|
@@ -1384,12 +1422,13 @@ class ArmedSeat {
|
|
|
1384
1422
|
}
|
|
1385
1423
|
|
|
1386
1424
|
const answers = [];
|
|
1425
|
+
const captureCommentary = this.shouldCaptureCommentary();
|
|
1387
1426
|
if (detectedAgent.type === "codex") {
|
|
1388
1427
|
const result = readCodexAnswers(
|
|
1389
1428
|
this.liveState.sessionFile,
|
|
1390
1429
|
this.liveState.offset,
|
|
1391
1430
|
this.liveState.captureSinceMs,
|
|
1392
|
-
{ flowMode:
|
|
1431
|
+
{ flowMode: captureCommentary }
|
|
1393
1432
|
);
|
|
1394
1433
|
this.liveState.offset = result.nextOffset;
|
|
1395
1434
|
answers.push(...result.answers);
|
|
@@ -1398,7 +1437,7 @@ class ArmedSeat {
|
|
|
1398
1437
|
this.liveState.sessionFile,
|
|
1399
1438
|
this.liveState.offset,
|
|
1400
1439
|
this.liveState.captureSinceMs,
|
|
1401
|
-
{ flowMode:
|
|
1440
|
+
{ flowMode: captureCommentary }
|
|
1402
1441
|
);
|
|
1403
1442
|
this.liveState.offset = result.nextOffset;
|
|
1404
1443
|
answers.push(...result.answers);
|
|
@@ -1407,7 +1446,7 @@ class ArmedSeat {
|
|
|
1407
1446
|
this.liveState.sessionFile,
|
|
1408
1447
|
this.liveState.lastMessageId,
|
|
1409
1448
|
this.liveState.captureSinceMs,
|
|
1410
|
-
{ flowMode:
|
|
1449
|
+
{ flowMode: captureCommentary }
|
|
1411
1450
|
);
|
|
1412
1451
|
this.liveState.lastMessageId = result.lastMessageId;
|
|
1413
1452
|
this.liveState.offset = result.fileSize;
|
|
@@ -1465,6 +1504,7 @@ class ArmedSeat {
|
|
|
1465
1504
|
seatId: this.seatId,
|
|
1466
1505
|
origin: entry.origin || "unknown",
|
|
1467
1506
|
phase: entry.phase || "final_answer",
|
|
1507
|
+
flowMode: this.flowMode,
|
|
1468
1508
|
text: payload,
|
|
1469
1509
|
createdAt: entry.createdAt || new Date().toISOString(),
|
|
1470
1510
|
chainId: pendingInboundContext?.chainId || entry.chainId || entryId,
|
|
@@ -1484,19 +1524,24 @@ class ArmedSeat {
|
|
|
1484
1524
|
}
|
|
1485
1525
|
|
|
1486
1526
|
forwardContinuation(signedEntry) {
|
|
1487
|
-
if (
|
|
1527
|
+
if (this.continueTargets.length === 0) {
|
|
1488
1528
|
return;
|
|
1489
1529
|
}
|
|
1490
1530
|
|
|
1491
|
-
const
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1531
|
+
for (const targetEntry of this.continueTargets) {
|
|
1532
|
+
const target = this.findContinuationTarget(targetEntry.targetSeatId);
|
|
1533
|
+
if (!target) {
|
|
1534
|
+
this.log(`[${this.seatId}] continue ${targetEntry.targetSeatId} unavailable`);
|
|
1535
|
+
continue;
|
|
1536
|
+
}
|
|
1496
1537
|
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1538
|
+
const continuationEntry = buildContinuationEntry(this.sessionName, target.seatId, {
|
|
1539
|
+
...signedEntry,
|
|
1540
|
+
flowMode: targetEntry.flowMode,
|
|
1541
|
+
});
|
|
1542
|
+
appendJsonl(target.paths.continuePath, continuationEntry);
|
|
1543
|
+
this.log(`[${this.seatId} => ${target.seatId} ${targetEntry.flowMode}] ${previewText(continuationEntry.text)}`);
|
|
1544
|
+
}
|
|
1500
1545
|
}
|
|
1501
1546
|
|
|
1502
1547
|
async tick() {
|
|
@@ -1545,8 +1590,10 @@ class ArmedSeat {
|
|
|
1545
1590
|
this.log(`${BRAND} seat ${this.seatId} armed for ${this.sessionName}.`);
|
|
1546
1591
|
this.log("Use this shell normally. Codex, Claude, and Gemini relay automatically from their local session logs.");
|
|
1547
1592
|
this.log(`Seat ${this.seatId} relay mode is flow ${this.flowMode}.`);
|
|
1548
|
-
if (this.
|
|
1549
|
-
this.log(
|
|
1593
|
+
if (this.continueTargets.length > 0) {
|
|
1594
|
+
this.log(
|
|
1595
|
+
`Seat ${this.seatId} continues to ${this.continueTargets.map((target) => `seat ${target.targetSeatId} (${target.flowMode})`).join(", ")}.`
|
|
1596
|
+
);
|
|
1550
1597
|
}
|
|
1551
1598
|
if (isAnchorSeat(this.seatId)) {
|
|
1552
1599
|
this.log(`Seat ${this.seatId} generated the session key and is waiting for seat ${this.partnerSeatId} to sign it.`);
|
|
@@ -1647,9 +1694,18 @@ function buildSeatReport(sessionName, seatId) {
|
|
|
1647
1694
|
|
|
1648
1695
|
return {
|
|
1649
1696
|
seatId,
|
|
1697
|
+
partnerSeatId: status?.partnerSeatId || meta?.partnerSeatId || getPartnerSeatId(seatId),
|
|
1650
1698
|
state: wrapperLive ? status?.state || "running" : "orphaned_child",
|
|
1651
1699
|
flowMode: status?.flowMode || meta?.flowMode || "off",
|
|
1652
1700
|
continueSeatId: status?.continueSeatId || meta?.continueSeatId || null,
|
|
1701
|
+
continueTargets: normalizeContinueTargets(
|
|
1702
|
+
status?.continueTargets || meta?.continueTargets || (
|
|
1703
|
+
(status?.continueSeatId || meta?.continueSeatId)
|
|
1704
|
+
? [{ targetSeatId: status?.continueSeatId || meta?.continueSeatId, flowMode: status?.flowMode || meta?.flowMode || "off" }]
|
|
1705
|
+
: []
|
|
1706
|
+
),
|
|
1707
|
+
status?.flowMode || meta?.flowMode || "off"
|
|
1708
|
+
),
|
|
1653
1709
|
wrapperPid,
|
|
1654
1710
|
childPid,
|
|
1655
1711
|
wrapperLive,
|
package/src/util.js
CHANGED
|
@@ -285,17 +285,15 @@ function usage() {
|
|
|
285
285
|
`${BRAND} arms regular terminals in isolated odd/even pairs and relays assistant output between each pair.`,
|
|
286
286
|
"",
|
|
287
287
|
"Usage:",
|
|
288
|
+
" muuuuse",
|
|
288
289
|
" muuuuse 1",
|
|
289
|
-
" muuuuse 1 flow on",
|
|
290
|
-
" muuuuse 1 flow off",
|
|
291
|
-
" muuuuse 1 flow on continue 3",
|
|
290
|
+
" muuuuse 1 link 2 flow on",
|
|
291
|
+
" muuuuse 1 link 2 flow on 3 flow off",
|
|
292
292
|
" muuuuse 2",
|
|
293
|
-
" muuuuse 2 flow on",
|
|
294
|
-
" muuuuse 2 flow off",
|
|
295
|
-
" muuuuse 2 flow on continue 3",
|
|
293
|
+
" muuuuse 2 link 1 flow on",
|
|
296
294
|
" muuuuse 3",
|
|
297
295
|
" muuuuse 4",
|
|
298
|
-
" muuuuse 4 flow
|
|
296
|
+
" muuuuse 4 link 3 flow off 1 flow on",
|
|
299
297
|
" muuuuse stop",
|
|
300
298
|
" muuuuse status",
|
|
301
299
|
"",
|
|
@@ -304,9 +302,9 @@ function usage() {
|
|
|
304
302
|
" 2. Run `muuuuse 2` in terminal two.",
|
|
305
303
|
" 3. The odd seat generates the session key and the matching even seat signs it automatically.",
|
|
306
304
|
" 4. Additional pairs work the same way: `3/4`, `5/6`, `7/8`...",
|
|
307
|
-
" 5.
|
|
308
|
-
" 6.
|
|
309
|
-
" 7.
|
|
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.",
|
|
310
308
|
" 8. `flow off` sends final answers only. `flow on` keeps assistant commentary bouncing.",
|
|
311
309
|
" 9. Run `muuuuse status` or `muuuuse stop` from any shell.",
|
|
312
310
|
"",
|