muuuuse 3.3.1 → 3.3.2

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
@@ -45,7 +45,7 @@ Terminal 2:
45
45
  muuuuse 2 link 1 flow off link 3 flow on link 4 flow on
46
46
  ```
47
47
 
48
- Now both shells are armed in the same cwd and join the same relay graph. Every seat has its own Ed25519 keypair. Each forwarded relay is signed by the sending seat. A target seat only accepts inbound relays from seats it links back to, so the graph can be open-ended without becoming an all-to-all broadcast.
48
+ Now both shells are armed in the same cwd and join the same relay graph. Every seat has its own Ed25519 keypair. Each forwarded relay is signed by the sending seat. A target seat only accepts inbound relays when the sender linked to that target, so the graph can be open-ended without becoming an all-to-all broadcast.
49
49
 
50
50
  `link <seat> flow on` means that outbound edge sends commentary and final answers. `link <seat> flow off` means that outbound edge sends final answers only. This is sender-side routing, not receiver-side filtering.
51
51
 
@@ -79,7 +79,7 @@ muuuuse stop
79
79
 
80
80
  - state lives under `~/.muuuuse`
81
81
  - all armed seats in the same cwd share one relay session graph
82
- - only signed relays from reciprocally linked seats are accepted
82
+ - only signed relays from senders that linked the target seat are accepted
83
83
  - `continue <seat>` is a convenience alias for a single signed outbound link
84
84
  - supported relay detection is built for Codex, Claude, and Gemini
85
85
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "muuuuse",
3
- "version": "3.3.1",
3
+ "version": "3.3.2",
4
4
  "description": "🔌Muuuuse arms regular terminals and relays assistant output across signed terminal links.",
5
5
  "type": "commonjs",
6
6
  "bin": {
package/src/runtime.js CHANGED
@@ -872,13 +872,33 @@ class ArmedSeat {
872
872
  return Number.isFinite(requestedAtMs) && requestedAtMs > this.startedAtMs;
873
873
  }
874
874
 
875
- hasAuthorizedSource(sourceSeatId) {
875
+ sourceLinksToTarget(sourceSeatId, targetSeatId = this.seatId) {
876
876
  const desiredSeatId = normalizeSeatId(sourceSeatId);
877
- if (!desiredSeatId) {
877
+ const desiredTargetSeatId = normalizeSeatId(targetSeatId);
878
+ if (!desiredSeatId || !desiredTargetSeatId) {
878
879
  return false;
879
880
  }
880
881
 
881
- return this.getConfiguredTargets().some((target) => target.seatId === desiredSeatId);
882
+ const sourcePaths = getSeatPaths(this.sessionName, desiredSeatId);
883
+ const sourceStatus = readJson(sourcePaths.statusPath, null);
884
+ const sourceMeta = readJson(sourcePaths.metaPath, null);
885
+ const sourceContinueSeatId = sourceStatus?.continueSeatId || sourceMeta?.continueSeatId || null;
886
+ const sourceContinueTargets = normalizeContinueTargets(
887
+ sourceStatus?.continueTargets || sourceMeta?.continueTargets
888
+ );
889
+
890
+ const configuredTargets = [...sourceContinueTargets];
891
+ if (
892
+ sourceContinueSeatId &&
893
+ !configuredTargets.some((target) => target.seatId === normalizeSeatId(sourceContinueSeatId))
894
+ ) {
895
+ configuredTargets.push({
896
+ seatId: normalizeSeatId(sourceContinueSeatId),
897
+ flowMode: normalizeFlowMode(sourceStatus?.flowMode || sourceMeta?.flowMode),
898
+ });
899
+ }
900
+
901
+ return configuredTargets.some((target) => target.seatId === desiredTargetSeatId);
882
902
  }
883
903
 
884
904
  readSourcePublicKey(sourceSeatId) {
@@ -922,7 +942,7 @@ class ArmedSeat {
922
942
  const sourceSeatId = normalizeSeatId(entry?.sourceSeatId || entry?.seatId);
923
943
  const targetSeatId = normalizeSeatId(entry?.targetSeatId);
924
944
  const payload = sanitizeRelayText(entry?.text);
925
- if (!sourceSeatId || targetSeatId !== this.seatId || !payload || !this.hasAuthorizedSource(sourceSeatId)) {
945
+ if (!sourceSeatId || targetSeatId !== this.seatId || !payload || !this.sourceLinksToTarget(sourceSeatId, targetSeatId)) {
926
946
  return false;
927
947
  }
928
948
 
@@ -1348,7 +1368,7 @@ class ArmedSeat {
1348
1368
  `Seat ${this.seatId} links signed relay targets: ${configuredTargets.map((target) => `${target.seatId}:${target.flowMode}`).join(", ")}.`
1349
1369
  );
1350
1370
  }
1351
- this.log("Signed relays are accepted only from seats that this seat links back to.");
1371
+ this.log("Signed relays are accepted when the sender linked to this seat.");
1352
1372
  this.log("Run `muuuuse status` or `muuuuse stop` from any terminal.");
1353
1373
 
1354
1374
  try {
package/src/util.js CHANGED
@@ -296,7 +296,7 @@ function usage() {
296
296
  " 4. `flow on` sends commentary and final answers on that edge. `flow off` sends final answers only.",
297
297
  " 5. `continue <seat>` is shorthand for one outbound link that uses the seat's default `flow on|off`.",
298
298
  " 6. Every forwarded relay is signed with the sender seat's key.",
299
- " 7. A seat only accepts signed inbound relays from seats it links back to.",
299
+ " 7. A seat only accepts signed inbound relays when the sender linked to that seat.",
300
300
  " 8. Use those armed shells normally.",
301
301
  " 9. Run `muuuuse status` or `muuuuse stop` from any shell.",
302
302
  "",