@zeph-to/cli 1.26.0 → 1.26.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/dist/listener.d.ts +8 -1
- package/dist/listener.d.ts.map +1 -1
- package/dist/listener.js +93 -13
- package/package.json +1 -1
package/dist/listener.d.ts
CHANGED
|
@@ -174,7 +174,14 @@ export interface StreamControl {
|
|
|
174
174
|
sessionName?: string;
|
|
175
175
|
/** Subscriber's device public key (Base64 SPKI) — presence turns on E2EE. */
|
|
176
176
|
subscriberPublicKey?: string;
|
|
177
|
+
/**
|
|
178
|
+
* Subscriber promises to send `agent.stream.renew` while it's watching.
|
|
179
|
+
* Only such a subscriber gets the short lease; clients that predate the
|
|
180
|
+
* renew protocol keep the 5-minute orphan guard (see STREAM_LEASE_MS).
|
|
181
|
+
*/
|
|
182
|
+
renew?: boolean;
|
|
177
183
|
}
|
|
184
|
+
export declare const STREAM_LEASE_MS = 15000;
|
|
178
185
|
export declare const MAX_CONCURRENT_STREAMS = 3;
|
|
179
186
|
export declare const stopStream: (sessionName: string) => void;
|
|
180
187
|
export declare const stopAllStreams: () => void;
|
|
@@ -198,7 +205,7 @@ export type StreamFramePayload = {
|
|
|
198
205
|
export type StreamErrorFrame = {
|
|
199
206
|
subtype: 'agent.stream.frame';
|
|
200
207
|
sessionName: string;
|
|
201
|
-
error: 'unknown_session' | 'e2ee_unavailable' | 'encrypt_failed' | 'stream_limit';
|
|
208
|
+
error: 'unknown_session' | 'e2ee_unavailable' | 'encrypt_failed' | 'stream_limit' | 'stream_gone';
|
|
202
209
|
};
|
|
203
210
|
/**
|
|
204
211
|
* Per-listener concurrency guard, as a pure predicate so the boundary is
|
package/dist/listener.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../src/listener.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../src/listener.ts"],"names":[],"mappings":"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"}
|
package/dist/listener.js
CHANGED
|
@@ -25,7 +25,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
25
25
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
26
26
|
};
|
|
27
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
-
exports.handleListener = exports.resolveWsUrl = exports.computeListenerDeviceId = exports.computeBackoff = exports.handlePush = exports.gcAttachments = exports.setAttachmentContext = exports.writeRemoteMarker = exports.collectSessions = exports.collectSessionsVerbose = exports.handleStreamControl = exports.buildStreamFrame = exports.isStreamCapReached = exports.stopAllStreams = exports.stopStream = exports.MAX_CONCURRENT_STREAMS = exports.scheduleInjectSnapshots = exports.handleScreenRequest = exports.collectWatchHits = exports.resetPatternWatches = exports.setPatternWatches = exports.deriveSessionState = exports.resetSessionStates = exports.detectRemoteAgent = exports.parseSessionName = exports.invalidateTmuxSocketCache = exports.resolveKeys = exports.paneCurrentCommand = exports.checkRateLimit = exports.AUTH_FAILURE_CODES = exports.sessionsReportDue = exports.sessionsFingerprint = exports.SESSION_REPORT_HEARTBEAT_MS = void 0;
|
|
28
|
+
exports.handleListener = exports.resolveWsUrl = exports.computeListenerDeviceId = exports.computeBackoff = exports.handlePush = exports.gcAttachments = exports.setAttachmentContext = exports.writeRemoteMarker = exports.collectSessions = exports.collectSessionsVerbose = exports.handleStreamControl = exports.buildStreamFrame = exports.isStreamCapReached = exports.stopAllStreams = exports.stopStream = exports.MAX_CONCURRENT_STREAMS = exports.STREAM_LEASE_MS = exports.scheduleInjectSnapshots = exports.handleScreenRequest = exports.collectWatchHits = exports.resetPatternWatches = exports.setPatternWatches = exports.deriveSessionState = exports.resetSessionStates = exports.detectRemoteAgent = exports.parseSessionName = exports.invalidateTmuxSocketCache = exports.resolveKeys = exports.paneCurrentCommand = exports.checkRateLimit = exports.AUTH_FAILURE_CODES = exports.sessionsReportDue = exports.sessionsFingerprint = exports.SESSION_REPORT_HEARTBEAT_MS = void 0;
|
|
29
29
|
const child_process_1 = require("child_process");
|
|
30
30
|
const crypto_1 = require("crypto");
|
|
31
31
|
const fs_1 = require("fs");
|
|
@@ -766,10 +766,27 @@ exports.scheduleInjectSnapshots = scheduleInjectSnapshots;
|
|
|
766
766
|
// still caps the actual payload, so very wide panes get top-truncated.
|
|
767
767
|
const STREAM_CAPTURE_LINES = 200;
|
|
768
768
|
const STREAM_INTERVAL_MS = 400;
|
|
769
|
-
// Orphan guard
|
|
770
|
-
//
|
|
771
|
-
//
|
|
769
|
+
// Orphan guard for subscribers that can't renew (clients older than the renew
|
|
770
|
+
// protocol): a phone that dies without sending agent.stream.stop must not leak
|
|
771
|
+
// an interval forever. Auto-stop after this long; the phone re-subscribes on
|
|
772
|
+
// reopen.
|
|
772
773
|
const STREAM_MAX_MS = 5 * 60_000;
|
|
774
|
+
// Lease for a renewal-capable subscriber (`start` carried `renew: true`).
|
|
775
|
+
// stream.stop is NOT a reliable slot-release signal: the native terminal runs
|
|
776
|
+
// in its own WebView that the OS destroys on swipe-back, killing the page mid-
|
|
777
|
+
// flight — no unmount, no stop, and the relay is pass-through so we never see
|
|
778
|
+
// the phone's socket drop either. Three such opens used to wedge
|
|
779
|
+
// MAX_CONCURRENT_STREAMS for a full STREAM_MAX_MS with every retry answering
|
|
780
|
+
// stream_limit. A lease inverts the burden: the viewer must keep proving it's
|
|
781
|
+
// there.
|
|
782
|
+
//
|
|
783
|
+
// This is also the worst-case wait before a vanished viewer's slot comes back,
|
|
784
|
+
// so it wants to be short — but a lease can only be as tight as the proof is
|
|
785
|
+
// frequent. At the web's 5s renew cadence this tolerates 3 consecutive dropped
|
|
786
|
+
// renews, the same margin as before, while cutting the wedge from 5 minutes to
|
|
787
|
+
// 15 seconds. A viewer that loses the race gets its stream reaped and re-
|
|
788
|
+
// subscribes on the next renew (see the stream_gone reply below).
|
|
789
|
+
exports.STREAM_LEASE_MS = 15_000;
|
|
773
790
|
// Per-listener concurrency guard: the API Gateway WS stage throttle (50 rps)
|
|
774
791
|
// is SHARED across every user, so a runaway machine (many sessions, or a
|
|
775
792
|
// client re-subscribe bug) streaming at 2.5 fps each can starve push delivery
|
|
@@ -785,6 +802,8 @@ const STREAM_MAX_ENCRYPT_FAILURES = 3;
|
|
|
785
802
|
// the log every STREAM_LOG_INTERVAL_MS and summarized on stop — the data that
|
|
786
803
|
// decides cloud-throttled (B-lite) vs direct/Tailscale (B-full).
|
|
787
804
|
const STREAM_LOG_INTERVAL_MS = 5_000;
|
|
805
|
+
/** How far a start (and each renew) pushes the deadline out. */
|
|
806
|
+
const leaseFor = (renewing) => (renewing ? exports.STREAM_LEASE_MS : STREAM_MAX_MS);
|
|
788
807
|
const activeStreams = new Map();
|
|
789
808
|
const maybeLogStreamStats = (sessionName, stats) => {
|
|
790
809
|
const elapsed = Date.now() - stats.lastLogAt;
|
|
@@ -823,6 +842,28 @@ exports.stopAllStreams = stopAllStreams;
|
|
|
823
842
|
*/
|
|
824
843
|
const isStreamCapReached = (activeCount) => activeCount >= exports.MAX_CONCURRENT_STREAMS;
|
|
825
844
|
exports.isStreamCapReached = isStreamCapReached;
|
|
845
|
+
/**
|
|
846
|
+
* At the cap, hand the slot to the new subscriber when the stalest holder
|
|
847
|
+
* can't prove it's still watching — an expired lease, or a client too old to
|
|
848
|
+
* renew at all (those hold a slot for STREAM_MAX_MS on nothing but hope, and
|
|
849
|
+
* a cached web build can keep producing them long after a deploy). Three
|
|
850
|
+
* actively-renewing viewers are all real, so that case still refuses.
|
|
851
|
+
* Returns the evicted session name, or null when every holder is live.
|
|
852
|
+
*/
|
|
853
|
+
const evictStalestStream = (now) => {
|
|
854
|
+
let victim = null;
|
|
855
|
+
for (const [name, entry] of activeStreams) {
|
|
856
|
+
if (entry.renewing && entry.expiresAt > now)
|
|
857
|
+
continue; // provably watched
|
|
858
|
+
if (!victim || entry.expiresAt < victim.expiresAt)
|
|
859
|
+
victim = { name, expiresAt: entry.expiresAt };
|
|
860
|
+
}
|
|
861
|
+
if (!victim)
|
|
862
|
+
return null;
|
|
863
|
+
log(`⧉ stream ${victim.name}: evicted — slot handed to a newer subscriber (no live lease)`);
|
|
864
|
+
(0, exports.stopStream)(victim.name);
|
|
865
|
+
return victim.name;
|
|
866
|
+
};
|
|
826
867
|
const streamErrorFrame = (sessionName, error) => ({
|
|
827
868
|
subtype: 'agent.stream.frame',
|
|
828
869
|
sessionName,
|
|
@@ -859,16 +900,40 @@ exports.buildStreamFrame = buildStreamFrame;
|
|
|
859
900
|
* path). start is idempotent — a repeat restarts the loop.
|
|
860
901
|
*/
|
|
861
902
|
const handleStreamControl = (req, send) => {
|
|
903
|
+
if (req.subtype !== 'agent.stream.start' && req.subtype !== 'agent.stream.stop' && req.subtype !== 'agent.stream.renew') {
|
|
904
|
+
return false;
|
|
905
|
+
}
|
|
906
|
+
// Every stream-control message names one machine, and the relay fans them
|
|
907
|
+
// out to all of this user's connections — so decide addressing once, here.
|
|
908
|
+
// Two machines can run the same tmux session name, and stop/renew carry no
|
|
909
|
+
// other identity: without this gate a stop meant for one listener would
|
|
910
|
+
// reach into the other's stream of that name (and a renew would refresh it).
|
|
911
|
+
if (req.targetDeviceId !== (0, exports.computeListenerDeviceId)())
|
|
912
|
+
return false;
|
|
862
913
|
if (req.subtype === 'agent.stream.stop') {
|
|
863
914
|
if (req.sessionName)
|
|
864
915
|
(0, exports.stopStream)(req.sessionName);
|
|
865
916
|
return true;
|
|
866
917
|
}
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
918
|
+
// Lease renewal — the subscriber is still watching.
|
|
919
|
+
if (req.subtype === 'agent.stream.renew') {
|
|
920
|
+
if (!req.sessionName)
|
|
921
|
+
return true;
|
|
922
|
+
const entry = activeStreams.get(req.sessionName);
|
|
923
|
+
if (entry) {
|
|
924
|
+
entry.expiresAt = Date.now() + leaseFor(entry.renewing);
|
|
925
|
+
return true;
|
|
926
|
+
}
|
|
927
|
+
// Addressed to us but we hold no such stream: it was reaped (lost
|
|
928
|
+
// renews), evicted, or dropped when our socket last reconnected. The
|
|
929
|
+
// viewer has no other way to learn that — it just keeps painting a
|
|
930
|
+
// frozen pane under a LIVE badge — so tell it to re-subscribe. Renew
|
|
931
|
+
// carries no subscriber key, so restarting it here would silently
|
|
932
|
+
// downgrade an E2EE stream to plaintext; only the client can redo the
|
|
933
|
+
// handshake.
|
|
934
|
+
send(streamErrorFrame(req.sessionName, 'stream_gone'));
|
|
935
|
+
return true;
|
|
936
|
+
}
|
|
872
937
|
const sessionName = req.sessionName;
|
|
873
938
|
if (!sessionName)
|
|
874
939
|
return true;
|
|
@@ -880,7 +945,7 @@ const handleStreamControl = (req, send) => {
|
|
|
880
945
|
// Concurrency guard AFTER the restart-stop: re-subscribing to an already
|
|
881
946
|
// active session doesn't count against the cap, only a genuinely new one
|
|
882
947
|
// does. Refuse the new stream instead of adding to the shared-throttle load.
|
|
883
|
-
if ((0, exports.isStreamCapReached)(activeStreams.size)) {
|
|
948
|
+
if ((0, exports.isStreamCapReached)(activeStreams.size) && !evictStalestStream(Date.now())) {
|
|
884
949
|
log(`⧉ stream ${sessionName}: refused — ${activeStreams.size}/${exports.MAX_CONCURRENT_STREAMS} streams already active on this listener`);
|
|
885
950
|
send(streamErrorFrame(sessionName, 'stream_limit'));
|
|
886
951
|
return true;
|
|
@@ -915,6 +980,15 @@ const handleStreamControl = (req, send) => {
|
|
|
915
980
|
let wireSeq = 0;
|
|
916
981
|
let encryptFailures = 0;
|
|
917
982
|
const timer = setInterval(() => {
|
|
983
|
+
// Lease check rides the capture tick: one deadline field, no second
|
|
984
|
+
// timer to leak. (The previous per-start expiry setTimeout was never
|
|
985
|
+
// cleared on stop, so a restart left the old one armed to kill the new
|
|
986
|
+
// incarnation.) Reaping here is what frees the slot for everyone whose
|
|
987
|
+
// stop never arrived.
|
|
988
|
+
if (Date.now() >= (activeStreams.get(sessionName)?.expiresAt ?? 0)) {
|
|
989
|
+
(0, exports.stopStream)(sessionName);
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
918
992
|
const captured = capturePane(sessionName, true, STREAM_CAPTURE_LINES);
|
|
919
993
|
if (!captured || captured.content === lastContent) {
|
|
920
994
|
stats.skipped++;
|
|
@@ -967,9 +1041,15 @@ const handleStreamControl = (req, send) => {
|
|
|
967
1041
|
});
|
|
968
1042
|
}, STREAM_INTERVAL_MS);
|
|
969
1043
|
timer.unref?.();
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1044
|
+
// A renewing subscriber gets the short lease; anything older keeps the
|
|
1045
|
+
// 5-minute orphan guard so a version-skewed client isn't cut off mid-view.
|
|
1046
|
+
const renewing = !!req.renew;
|
|
1047
|
+
activeStreams.set(sessionName, {
|
|
1048
|
+
timer,
|
|
1049
|
+
stats,
|
|
1050
|
+
expiresAt: Date.now() + leaseFor(renewing),
|
|
1051
|
+
renewing,
|
|
1052
|
+
});
|
|
973
1053
|
return true;
|
|
974
1054
|
};
|
|
975
1055
|
exports.handleStreamControl = handleStreamControl;
|