muuuuse 2.3.0 → 2.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/README.md CHANGED
@@ -46,7 +46,7 @@ muuuuse 2 flow off
46
46
 
47
47
  Now both shells are armed. `muuuuse 1` generates the session key, `muuuuse 2` signs it, and only that signed pair relays. Every odd/even adjacent pair works the same way in parallel: `3/4`, `5/6`, `7/8`, and so on. Use those shells normally.
48
48
 
49
- `flow on` means that seat sends commentary and final answers. `flow off` means that seat waits for final answers only. Each seat decides what it sends out, so mixed calibration is allowed.
49
+ `flow on` means that seat relays commentary and final answers. `flow off` means that seat relays and accepts final answers only. Mixed calibration is allowed per seat.
50
50
 
51
51
  `continue <seat>` forwards that seat's relayed output into another armed seat without changing the signed odd/even pair law. This lets you build local loops like `1 -> 2 -> 3 -> 4 -> 1` while every adjacent pair still keeps its own session keypair.
52
52
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "muuuuse",
3
- "version": "2.3.0",
3
+ "version": "2.3.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/agents.js CHANGED
@@ -481,6 +481,7 @@ function parseCodexAssistantLine(line, options = {}) {
481
481
  return {
482
482
  id: entry.payload.id || hashText(line),
483
483
  text,
484
+ phase: phase === "commentary" ? "commentary" : "final_answer",
484
485
  timestamp: entry.timestamp || entry.payload.timestamp || new Date().toISOString(),
485
486
  };
486
487
  } catch {
@@ -597,6 +598,7 @@ function parseClaudeAssistantLine(line, options = {}) {
597
598
  return {
598
599
  id: entry.uuid || entry.message.id || hashText(line),
599
600
  text,
601
+ phase: flowMode && entry.message?.stop_reason !== "end_turn" ? "commentary" : "final_answer",
600
602
  timestamp: entry.timestamp || new Date().toISOString(),
601
603
  };
602
604
  } catch {
@@ -672,6 +674,7 @@ function readGeminiAnswers(filePath, lastMessageId = null, sinceMs = null) {
672
674
  const answers = finalMessages.slice(startIndex).map((message) => ({
673
675
  id: message.id || hashText(JSON.stringify(message)),
674
676
  text: sanitizeRelayText(message.content),
677
+ phase: "final_answer",
675
678
  timestamp: message.timestamp || entry.lastUpdated || new Date().toISOString(),
676
679
  }));
677
680
 
package/src/runtime.js CHANGED
@@ -444,6 +444,7 @@ function buildAnswerSignaturePayload(sessionName, challenge, entry) {
444
444
  id: entry.id,
445
445
  seatId: entry.seatId,
446
446
  origin: entry.origin,
447
+ phase: entry.phase || "final_answer",
447
448
  createdAt: entry.createdAt,
448
449
  text: entry.text,
449
450
  });
@@ -457,6 +458,7 @@ function buildContinuationEntry(sourceSessionName, targetSeatId, entry) {
457
458
  sourceSeatId: entry.seatId,
458
459
  targetSeatId,
459
460
  origin: entry.origin || "unknown",
461
+ phase: entry.phase || "final_answer",
460
462
  text: entry.text,
461
463
  createdAt: entry.createdAt || new Date().toISOString(),
462
464
  chainId: entry.chainId,
@@ -467,6 +469,15 @@ function buildContinuationEntry(sourceSessionName, targetSeatId, entry) {
467
469
  };
468
470
  }
469
471
 
472
+ function getRelayPhase(entry) {
473
+ const phase = String(entry?.phase || "").trim().toLowerCase();
474
+ return phase === "commentary" ? "commentary" : "final_answer";
475
+ }
476
+
477
+ function shouldAcceptInboundEntry(flowMode, entry) {
478
+ return flowMode === "on" || getRelayPhase(entry) === "final_answer";
479
+ }
480
+
470
481
  function getSeatDirIfExists(sessionName, seatId) {
471
482
  const dir = path.join(getStateRoot(), "sessions", sessionName, `seat-${seatId}`);
472
483
  try {
@@ -1067,6 +1078,10 @@ class ArmedSeat {
1067
1078
  return;
1068
1079
  }
1069
1080
 
1081
+ if (!shouldAcceptInboundEntry(this.flowMode, entry)) {
1082
+ continue;
1083
+ }
1084
+
1070
1085
  const payload = sanitizeRelayText(entry.text);
1071
1086
  const signaturePayload = buildAnswerSignaturePayload(this.sessionName, this.trustState.challenge, {
1072
1087
  chainId: entry.chainId || entry.id,
@@ -1074,6 +1089,7 @@ class ArmedSeat {
1074
1089
  id: entry.id,
1075
1090
  seatId: entry.seatId,
1076
1091
  origin: entry.origin || "unknown",
1092
+ phase: getRelayPhase(entry),
1077
1093
  createdAt: entry.createdAt,
1078
1094
  text: payload,
1079
1095
  });
@@ -1129,6 +1145,10 @@ class ArmedSeat {
1129
1145
  return;
1130
1146
  }
1131
1147
 
1148
+ if (!shouldAcceptInboundEntry(this.flowMode, entry)) {
1149
+ continue;
1150
+ }
1151
+
1132
1152
  const payload = sanitizeRelayText(entry.text);
1133
1153
  if (!payload) {
1134
1154
  continue;
@@ -1371,6 +1391,7 @@ class ArmedSeat {
1371
1391
  this.emitAnswer({
1372
1392
  id: answer.id || createId(12),
1373
1393
  origin: detectedAgent.type,
1394
+ phase: answer.phase || "final_answer",
1374
1395
  text: answer.text,
1375
1396
  createdAt: answer.timestamp || new Date().toISOString(),
1376
1397
  });
@@ -1416,6 +1437,7 @@ class ArmedSeat {
1416
1437
  type: "answer",
1417
1438
  seatId: this.seatId,
1418
1439
  origin: entry.origin || "unknown",
1440
+ phase: entry.phase || "final_answer",
1419
1441
  text: payload,
1420
1442
  createdAt: entry.createdAt || new Date().toISOString(),
1421
1443
  chainId: pendingInboundContext?.chainId || entry.chainId || entryId,