zas-agent 0.6.2 → 0.6.3
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/CHANGELOG.md +29 -1
- package/dist/cli.js +62 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.6.3] - 2026-09-04
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- The selected candidate pair is read from the transport, which names its
|
|
15
|
+
own pair on every engine. A transfer that connected and carried its whole
|
|
16
|
+
file could report `pair=none`, because the browser at the other end does
|
|
17
|
+
not mark a pair `nominated` on the controlled side. The empty field was
|
|
18
|
+
read as a missing pair and sent two rounds of diagnosis after a
|
|
19
|
+
connection that had been there all along.
|
|
20
|
+
- A peer connection state of `failed` has to hold before the engine acts on
|
|
21
|
+
it. Chrome reports `failed` while it is still gathering and returns to
|
|
22
|
+
`connecting` in the same millisecond; acting on the first one killed a
|
|
23
|
+
receiver at 0.88 s with pairs still waiting to be tried. The settle window
|
|
24
|
+
is shorter than the ICE grace, so a connection that really is dead still
|
|
25
|
+
gives up sooner than it did before.
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- The trace counts candidate pairs by check state just before the verdict:
|
|
30
|
+
`checks failed=24 in-progress=4`, or `checks none`. No pair selected could
|
|
31
|
+
not tell a run that formed no pairs from one that formed pairs and lost
|
|
32
|
+
every check, and those are different faults.
|
|
33
|
+
- A candidate the peer refuses is traced as `ice apply rejected <type>
|
|
34
|
+
<ErrorName>`. The rejection used to be swallowed, so a refused candidate
|
|
35
|
+
looked exactly like one the network lost.
|
|
36
|
+
|
|
10
37
|
## [0.6.2] - 2026-09-04
|
|
11
38
|
|
|
12
39
|
### Added
|
|
@@ -205,7 +232,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
205
232
|
two separate identities that cannot read each other's keys.
|
|
206
233
|
- Install snippets for Claude Code and Codex, printed by `zas-agent pair`.
|
|
207
234
|
|
|
208
|
-
[Unreleased]: https://github.com/soke1556/zas-agent/compare/v0.6.
|
|
235
|
+
[Unreleased]: https://github.com/soke1556/zas-agent/compare/v0.6.3...HEAD
|
|
236
|
+
[0.6.3]: https://github.com/soke1556/zas-agent/compare/v0.6.2...v0.6.3
|
|
209
237
|
[0.6.2]: https://github.com/soke1556/zas-agent/compare/v0.6.1...v0.6.2
|
|
210
238
|
[0.6.1]: https://github.com/soke1556/zas-agent/compare/v0.6.0...v0.6.1
|
|
211
239
|
[0.6.0]: https://github.com/soke1556/zas-agent/compare/v0.5.1...v0.6.0
|
package/dist/cli.js
CHANGED
|
@@ -854,6 +854,8 @@ function directFallbackCipherSize(size) {
|
|
|
854
854
|
}
|
|
855
855
|
var DIRECT_CONNECT_TIMEOUT_MS = 30 * 1e3;
|
|
856
856
|
var DIRECT_STALL_GRACE_MS = 5 * 1e3;
|
|
857
|
+
var DIRECT_CENSUS_WAIT_MS = 250;
|
|
858
|
+
var DIRECT_CONN_FAILED_SETTLE_MS = 1500;
|
|
857
859
|
var DIRECT_SIGNAL_WAIT_MS = 90 * 1e3;
|
|
858
860
|
|
|
859
861
|
// src/shared/direct-engine.ts
|
|
@@ -1022,17 +1024,36 @@ function countTurnUrls(servers) {
|
|
|
1022
1024
|
}
|
|
1023
1025
|
function pairFromStats(stats) {
|
|
1024
1026
|
let pair;
|
|
1027
|
+
let selectedId;
|
|
1025
1028
|
stats.forEach((s) => {
|
|
1029
|
+
if (s.type === "transport" && typeof s.selectedCandidatePairId === "string") {
|
|
1030
|
+
selectedId = s.selectedCandidatePairId;
|
|
1031
|
+
}
|
|
1026
1032
|
if (s.type === "candidate-pair" && s.state === "succeeded" && (s.nominated || s.selected)) {
|
|
1027
1033
|
pair = s;
|
|
1028
1034
|
}
|
|
1029
1035
|
});
|
|
1036
|
+
if (selectedId) {
|
|
1037
|
+
const named = stats.get(selectedId);
|
|
1038
|
+
if (named?.localCandidateId && named.remoteCandidateId) pair = named;
|
|
1039
|
+
}
|
|
1030
1040
|
if (!pair?.localCandidateId || !pair.remoteCandidateId) return void 0;
|
|
1031
1041
|
const local = stats.get(pair.localCandidateId);
|
|
1032
1042
|
const remote = stats.get(pair.remoteCandidateId);
|
|
1033
1043
|
if (!local?.candidateType || !remote?.candidateType) return void 0;
|
|
1034
1044
|
return { local: local.candidateType, remote: remote.candidateType };
|
|
1035
1045
|
}
|
|
1046
|
+
function checkCensus(stats) {
|
|
1047
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1048
|
+
stats.forEach((s) => {
|
|
1049
|
+
if (s.type !== "candidate-pair") return;
|
|
1050
|
+
const state = String(s.state ?? "?");
|
|
1051
|
+
counts.set(state, (counts.get(state) ?? 0) + 1);
|
|
1052
|
+
});
|
|
1053
|
+
if (counts.size === 0) return "checks none";
|
|
1054
|
+
const parts = [...counts].map(([state, n]) => `${state}=${n}`);
|
|
1055
|
+
return `checks ${parts.join(" ")}`;
|
|
1056
|
+
}
|
|
1036
1057
|
function pathOf(pair) {
|
|
1037
1058
|
if (pair.local === "relay" || pair.remote === "relay") return "relay";
|
|
1038
1059
|
return pair.local === "host" && pair.remote === "host" ? "lan" : "wan";
|
|
@@ -1059,6 +1080,7 @@ function session(ice, onPhase, onDiag, iceTransportPolicy = "all") {
|
|
|
1059
1080
|
let phase = "connecting";
|
|
1060
1081
|
let disconnectTimer;
|
|
1061
1082
|
let restartTimer;
|
|
1083
|
+
let connFailTimer;
|
|
1062
1084
|
let stallState = "idle";
|
|
1063
1085
|
const startedAt = Date.now();
|
|
1064
1086
|
const diag = {
|
|
@@ -1086,7 +1108,20 @@ function session(ice, onPhase, onDiag, iceTransportPolicy = "all") {
|
|
|
1086
1108
|
};
|
|
1087
1109
|
const connState = () => String(pc.connectionState ?? "");
|
|
1088
1110
|
pc.onconnectionstatechange = () => {
|
|
1089
|
-
|
|
1111
|
+
const state = connState();
|
|
1112
|
+
traceAdd(diag, `conn ${state}`);
|
|
1113
|
+
if (state !== "failed") {
|
|
1114
|
+
clearTimeout(connFailTimer);
|
|
1115
|
+
connFailTimer = void 0;
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1118
|
+
if (connFailTimer !== void 0) return;
|
|
1119
|
+
connFailTimer = setTimeout(() => {
|
|
1120
|
+
connFailTimer = void 0;
|
|
1121
|
+
if (connState() !== "failed") return;
|
|
1122
|
+
if (diag.msConnect !== void 0 && onStall) stalled();
|
|
1123
|
+
else failWithCensus("ice_failed");
|
|
1124
|
+
}, DIRECT_CONN_FAILED_SETTLE_MS);
|
|
1090
1125
|
};
|
|
1091
1126
|
let channel;
|
|
1092
1127
|
pc.onicecandidateerror = (e) => {
|
|
@@ -1095,6 +1130,7 @@ function session(ice, onPhase, onDiag, iceTransportPolicy = "all") {
|
|
|
1095
1130
|
};
|
|
1096
1131
|
const cleanup = () => {
|
|
1097
1132
|
clearTimeout(waitTimer);
|
|
1133
|
+
clearTimeout(connFailTimer);
|
|
1098
1134
|
clearTimeout(connectTimer);
|
|
1099
1135
|
clearTimeout(disconnectTimer);
|
|
1100
1136
|
clearTimeout(restartTimer);
|
|
@@ -1134,6 +1170,20 @@ function session(ice, onPhase, onDiag, iceTransportPolicy = "all") {
|
|
|
1134
1170
|
}
|
|
1135
1171
|
setPhase("failed");
|
|
1136
1172
|
};
|
|
1173
|
+
const failWithCensus = (reason) => {
|
|
1174
|
+
if (phase === "done" || phase === "failed") return;
|
|
1175
|
+
let reported = false;
|
|
1176
|
+
const report2 = () => {
|
|
1177
|
+
if (reported) return;
|
|
1178
|
+
reported = true;
|
|
1179
|
+
fail(reason);
|
|
1180
|
+
};
|
|
1181
|
+
const guard = setTimeout(report2, DIRECT_CENSUS_WAIT_MS);
|
|
1182
|
+
void pc.getStats().then((stats) => traceAdd(diag, checkCensus(stats))).catch(() => void 0).then(() => {
|
|
1183
|
+
clearTimeout(guard);
|
|
1184
|
+
report2();
|
|
1185
|
+
});
|
|
1186
|
+
};
|
|
1137
1187
|
const waitTimer = setTimeout(() => fail("peer_silent"), DIRECT_SIGNAL_WAIT_MS);
|
|
1138
1188
|
let connectTimer;
|
|
1139
1189
|
let heard = false;
|
|
@@ -1143,7 +1193,7 @@ function session(ice, onPhase, onDiag, iceTransportPolicy = "all") {
|
|
|
1143
1193
|
clearTimeout(waitTimer);
|
|
1144
1194
|
connectTimer = setTimeout(() => {
|
|
1145
1195
|
const iceUp = pc.iceConnectionState === "connected" || pc.iceConnectionState === "completed";
|
|
1146
|
-
|
|
1196
|
+
failWithCensus(iceUp ? "channel_never_opened" : "connect_timeout");
|
|
1147
1197
|
}, DIRECT_CONNECT_TIMEOUT_MS);
|
|
1148
1198
|
};
|
|
1149
1199
|
let onStall;
|
|
@@ -1153,7 +1203,7 @@ function session(ice, onPhase, onDiag, iceTransportPolicy = "all") {
|
|
|
1153
1203
|
clearTimeout(disconnectTimer);
|
|
1154
1204
|
if (stallState === "restarting") return;
|
|
1155
1205
|
if (diag.msConnect === void 0 || !onStall) {
|
|
1156
|
-
|
|
1206
|
+
failWithCensus(diag.msConnect === void 0 ? "ice_failed" : "disconnected");
|
|
1157
1207
|
return;
|
|
1158
1208
|
}
|
|
1159
1209
|
stallState = "restarting";
|
|
@@ -1168,7 +1218,7 @@ function session(ice, onPhase, onDiag, iceTransportPolicy = "all") {
|
|
|
1168
1218
|
traceAdd(diag, `ice ${String(s ?? "")}`);
|
|
1169
1219
|
if (s === "failed") {
|
|
1170
1220
|
if (diag.msConnect !== void 0 && onStall) stalled();
|
|
1171
|
-
else
|
|
1221
|
+
else failWithCensus("ice_failed");
|
|
1172
1222
|
}
|
|
1173
1223
|
if (s === "disconnected" && stallState === "idle") {
|
|
1174
1224
|
stallState = "grace";
|
|
@@ -1231,8 +1281,14 @@ function signalPlumbing(pc, send, onSendError, diag) {
|
|
|
1231
1281
|
generation: localGeneration
|
|
1232
1282
|
}).catch(onSendError);
|
|
1233
1283
|
};
|
|
1284
|
+
let applyRejects = 0;
|
|
1234
1285
|
const apply = (candidate) => {
|
|
1235
|
-
void pc.addIceCandidate(candidate ?? void 0).catch(() =>
|
|
1286
|
+
void pc.addIceCandidate(candidate ?? void 0).catch((e) => {
|
|
1287
|
+
if (applyRejects >= 3) return;
|
|
1288
|
+
applyRejects++;
|
|
1289
|
+
const name = e?.name || "Error";
|
|
1290
|
+
traceAdd(diag, `ice apply rejected ${candidate ? candType(candidate) : "end"} ${name}`);
|
|
1291
|
+
});
|
|
1236
1292
|
};
|
|
1237
1293
|
const applyIce = (candidate, generation) => {
|
|
1238
1294
|
countCand(diag, "remote", candidate);
|
|
@@ -3928,7 +3984,7 @@ async function report(client, properties) {
|
|
|
3928
3984
|
|
|
3929
3985
|
// src/server.ts
|
|
3930
3986
|
function agentVersion() {
|
|
3931
|
-
return true ? "0.6.
|
|
3987
|
+
return true ? "0.6.3" : "0.0.0-dev";
|
|
3932
3988
|
}
|
|
3933
3989
|
var AGENT_CUE = " The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.";
|
|
3934
3990
|
var PAIR_ANNOUNCE_MS = 15e3;
|
package/package.json
CHANGED