@the-open-engine/zeroshot 6.29.0 → 6.29.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/cli/index.js +2 -4
- package/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -1
- package/lib/agent-cli-provider/adapters/codex.js +0 -1
- package/lib/agent-cli-provider/adapters/codex.js.map +1 -1
- package/lib/cluster/client.cjs +30 -7
- package/lib/cluster/client.d.cts +52 -0
- package/lib/cluster/client.d.mts +52 -0
- package/lib/cluster/client.d.ts +4 -6
- package/lib/cluster/client.mjs +32 -9
- package/lib/cluster/connection-state.cjs +25 -0
- package/lib/cluster/connection-state.d.cts +13 -0
- package/lib/cluster/connection-state.d.mts +13 -0
- package/lib/cluster/connection-state.d.ts +13 -0
- package/lib/cluster/connection-state.mjs +21 -0
- package/lib/{target/hosted-run/contracts.js → cluster/connection-types.cjs} +0 -1
- package/lib/cluster/connection-types.d.cts +33 -0
- package/lib/cluster/connection-types.d.mts +33 -0
- package/lib/cluster/connection-types.d.ts +33 -0
- package/lib/cluster/connection-types.mjs +1 -0
- package/lib/cluster/connection.cjs +18 -46
- package/lib/cluster/connection.d.cts +26 -0
- package/lib/cluster/connection.d.mts +26 -0
- package/lib/cluster/connection.d.ts +7 -25
- package/lib/cluster/connection.mjs +12 -42
- package/lib/cluster/errors.cjs +9 -1
- package/lib/cluster/errors.d.cts +29 -0
- package/lib/cluster/errors.d.mts +29 -0
- package/lib/cluster/errors.d.ts +4 -0
- package/lib/cluster/errors.mjs +7 -0
- package/lib/cluster/frames.d.cts +12 -0
- package/lib/cluster/frames.d.mts +12 -0
- package/lib/cluster/generated/protocol-schema.d.cts +1 -0
- package/lib/cluster/generated/protocol-schema.d.mts +1 -0
- package/lib/cluster/generated/protocol.d.cts +781 -0
- package/lib/cluster/generated/protocol.d.mts +781 -0
- package/lib/cluster/index.cjs +2 -2
- package/lib/cluster/index.d.cts +13 -0
- package/lib/cluster/index.d.mts +13 -0
- package/lib/cluster/index.d.ts +3 -3
- package/lib/cluster/index.mjs +2 -2
- package/lib/cluster/json-source.cjs +1 -0
- package/lib/cluster/json-source.d.cts +5 -0
- package/lib/cluster/json-source.d.mts +5 -0
- package/lib/cluster/json-source.d.ts +1 -0
- package/lib/cluster/json-source.mjs +1 -0
- package/lib/cluster/payload-value.cjs +1 -0
- package/lib/cluster/payload-value.d.cts +8 -0
- package/lib/cluster/payload-value.d.mts +8 -0
- package/lib/cluster/payload-value.d.ts +1 -0
- package/lib/cluster/payload-value.mjs +1 -0
- package/lib/cluster/queue.d.cts +15 -0
- package/lib/cluster/queue.d.mts +15 -0
- package/lib/cluster/socket.cjs +8 -0
- package/lib/cluster/socket.d.cts +13 -0
- package/lib/cluster/socket.d.mts +13 -0
- package/lib/cluster/socket.d.ts +2 -0
- package/lib/cluster/socket.mjs +7 -0
- package/lib/cluster/subscriptions.d.cts +73 -0
- package/lib/cluster/subscriptions.d.mts +73 -0
- package/lib/cluster/subscriptions.d.ts +5 -1
- package/lib/cluster/validators.cjs +1 -0
- package/lib/cluster/validators.d.cts +7 -0
- package/lib/cluster/validators.d.mts +7 -0
- package/lib/cluster/validators.d.ts +1 -0
- package/lib/cluster/validators.mjs +1 -0
- package/lib/cluster-worker/engine-adapter.js +4 -10
- package/lib/cluster-worker/profiles.js +1 -42
- package/lib/hosted-session/authority.cjs +61 -0
- package/lib/hosted-session/authority.d.cts +3 -0
- package/lib/hosted-session/authority.d.mts +3 -0
- package/lib/hosted-session/authority.d.ts +3 -0
- package/lib/hosted-session/authority.mjs +57 -0
- package/lib/hosted-session/coordinator.cjs +78 -51
- package/lib/hosted-session/coordinator.d.cts +11 -0
- package/lib/hosted-session/coordinator.d.mts +11 -0
- package/lib/hosted-session/coordinator.d.ts +4 -2
- package/lib/hosted-session/coordinator.mjs +75 -51
- package/lib/hosted-session/errors.cjs +25 -0
- package/lib/hosted-session/errors.d.cts +10 -0
- package/lib/hosted-session/errors.d.mts +10 -0
- package/lib/hosted-session/errors.d.ts +10 -0
- package/lib/hosted-session/errors.mjs +19 -0
- package/lib/hosted-session/index.cjs +4 -1
- package/lib/hosted-session/index.d.cts +2 -0
- package/lib/hosted-session/index.d.mts +2 -0
- package/lib/hosted-session/index.d.ts +2 -2
- package/lib/hosted-session/index.mjs +1 -1
- package/lib/hosted-session/reconnecting-watch.cjs +131 -0
- package/lib/hosted-session/reconnecting-watch.d.cts +13 -0
- package/lib/hosted-session/reconnecting-watch.d.mts +13 -0
- package/lib/hosted-session/reconnecting-watch.d.ts +13 -0
- package/lib/hosted-session/reconnecting-watch.mjs +127 -0
- package/lib/hosted-session/types.d.cts +32 -0
- package/lib/hosted-session/types.d.mts +32 -0
- package/lib/hosted-session/types.d.ts +19 -7
- package/lib/hosted-target/access-url.cjs +44 -0
- package/lib/hosted-target/access-url.d.cts +2 -0
- package/lib/hosted-target/access-url.d.mts +2 -0
- package/lib/hosted-target/access-url.d.ts +2 -0
- package/lib/hosted-target/access-url.mjs +41 -0
- package/lib/hosted-target/adapter-request.cjs +12 -0
- package/lib/hosted-target/adapter-request.d.cts +17 -0
- package/lib/hosted-target/adapter-request.d.mts +17 -0
- package/lib/hosted-target/adapter-request.d.ts +17 -0
- package/lib/hosted-target/adapter-request.mjs +9 -0
- package/lib/hosted-target/adapter-types.cjs +2 -0
- package/lib/hosted-target/adapter-types.d.cts +27 -0
- package/lib/hosted-target/adapter-types.d.mts +27 -0
- package/lib/hosted-target/adapter-types.d.ts +27 -0
- package/lib/hosted-target/adapter-types.mjs +1 -0
- package/lib/hosted-target/bounds.cjs +10 -0
- package/lib/hosted-target/bounds.d.cts +7 -0
- package/lib/hosted-target/bounds.d.mts +7 -0
- package/lib/hosted-target/bounds.d.ts +7 -0
- package/lib/hosted-target/bounds.mjs +7 -0
- package/lib/hosted-target/capsule-error-response.cjs +76 -0
- package/lib/hosted-target/capsule-error-response.d.cts +2 -0
- package/lib/hosted-target/capsule-error-response.d.mts +2 -0
- package/lib/hosted-target/capsule-error-response.d.ts +2 -0
- package/lib/hosted-target/capsule-error-response.mjs +73 -0
- package/lib/hosted-target/errors.cjs +88 -0
- package/lib/hosted-target/errors.d.cts +36 -0
- package/lib/hosted-target/errors.d.mts +36 -0
- package/lib/hosted-target/errors.d.ts +36 -0
- package/lib/hosted-target/errors.mjs +75 -0
- package/lib/hosted-target/index.cjs +16 -0
- package/lib/hosted-target/index.d.cts +3 -0
- package/lib/hosted-target/index.d.mts +3 -0
- package/lib/hosted-target/index.d.ts +3 -0
- package/lib/hosted-target/index.mjs +2 -0
- package/lib/hosted-target/response-validation.cjs +169 -0
- package/lib/hosted-target/response-validation.d.cts +5 -0
- package/lib/hosted-target/response-validation.d.mts +5 -0
- package/lib/hosted-target/response-validation.d.ts +5 -0
- package/lib/hosted-target/response-validation.mjs +163 -0
- package/lib/hosted-target/retry-executor.cjs +51 -0
- package/lib/hosted-target/retry-executor.d.cts +8 -0
- package/lib/hosted-target/retry-executor.d.mts +8 -0
- package/lib/hosted-target/retry-executor.d.ts +8 -0
- package/lib/hosted-target/retry-executor.mjs +48 -0
- package/lib/hosted-target/retry.cjs +78 -0
- package/lib/hosted-target/retry.d.cts +9 -0
- package/lib/hosted-target/retry.d.mts +9 -0
- package/lib/hosted-target/retry.d.ts +9 -0
- package/lib/hosted-target/retry.mjs +73 -0
- package/lib/hosted-target/target-adapter.cjs +10 -0
- package/lib/hosted-target/target-adapter.d.cts +3 -0
- package/lib/hosted-target/target-adapter.d.mts +3 -0
- package/lib/hosted-target/target-adapter.d.ts +3 -0
- package/lib/hosted-target/target-adapter.mjs +7 -0
- package/lib/hosted-target/types.cjs +4 -0
- package/lib/hosted-target/types.d.cts +50 -0
- package/lib/hosted-target/types.d.mts +50 -0
- package/lib/hosted-target/types.d.ts +50 -0
- package/lib/hosted-target/types.mjs +1 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.cjs +185 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.d.cts +13 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.d.mts +13 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.d.ts +13 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.mjs +181 -0
- package/lib/start-cluster.js +3 -3
- package/lib/target/bounded-response.cjs +51 -0
- package/lib/target/bounded-response.d.cts +1 -0
- package/lib/target/bounded-response.d.mts +1 -0
- package/lib/target/bounded-response.d.ts +1 -0
- package/lib/target/bounded-response.js +51 -0
- package/lib/target/bounded-response.mjs +48 -0
- package/lib/target/credential-lock.js +1 -3
- package/lib/target/credential-store.js +9 -4
- package/lib/target/device-flow.cjs +213 -0
- package/lib/target/device-flow.d.cts +54 -0
- package/lib/target/device-flow.d.mts +54 -0
- package/lib/target/device-flow.d.ts +26 -14
- package/lib/target/device-flow.js +162 -58
- package/lib/target/device-flow.mjs +203 -0
- package/lib/target/discovery-errors.cjs +10 -0
- package/lib/target/discovery-errors.d.cts +3 -0
- package/lib/target/discovery-errors.d.mts +3 -0
- package/lib/target/discovery-errors.d.ts +3 -0
- package/lib/target/discovery-errors.js +10 -0
- package/lib/target/discovery-errors.mjs +6 -0
- package/lib/target/discovery-sections.cjs +191 -0
- package/lib/target/discovery-sections.d.cts +52 -0
- package/lib/target/discovery-sections.d.mts +52 -0
- package/lib/target/discovery-sections.d.ts +52 -0
- package/lib/target/discovery-sections.js +191 -0
- package/lib/target/discovery-sections.mjs +179 -0
- package/lib/target/discovery-validation.cjs +109 -0
- package/lib/target/discovery-validation.d.cts +28 -0
- package/lib/target/discovery-validation.d.mts +28 -0
- package/lib/target/discovery-validation.d.ts +28 -0
- package/lib/target/discovery-validation.js +109 -0
- package/lib/target/discovery-validation.mjs +99 -0
- package/lib/target/discovery.cjs +112 -0
- package/lib/target/discovery.d.cts +74 -0
- package/lib/target/discovery.d.mts +74 -0
- package/lib/target/discovery.d.ts +67 -5
- package/lib/target/discovery.js +94 -79
- package/lib/target/discovery.mjs +105 -0
- package/lib/target/index.d.ts +6 -6
- package/lib/target/index.js +36 -36
- package/lib/target/oauth-http.d.ts +2 -0
- package/lib/target/oauth-http.js +25 -0
- package/lib/target/refresh-exchange.d.ts +11 -0
- package/lib/target/refresh-exchange.js +24 -0
- package/lib/target/refresh-revocation.d.ts +8 -0
- package/lib/target/refresh-revocation.js +19 -0
- package/lib/target/route-template.cjs +85 -0
- package/lib/target/route-template.d.cts +7 -0
- package/lib/target/route-template.d.mts +7 -0
- package/lib/target/route-template.d.ts +7 -0
- package/lib/target/route-template.js +85 -0
- package/lib/target/route-template.mjs +81 -0
- package/lib/target/session-errors.d.ts +4 -0
- package/lib/target/session-errors.js +12 -0
- package/lib/target/session-verification.d.ts +10 -0
- package/lib/target/session-verification.js +42 -0
- package/lib/target/target-registry.d.ts +7 -3
- package/lib/target/target-registry.js +41 -10
- package/lib/target/target-session-manager.d.ts +48 -0
- package/lib/target/target-session-manager.js +226 -0
- package/lib/target/target-session.d.ts +39 -32
- package/lib/target/target-session.js +63 -151
- package/lib/target/token-response.cjs +51 -0
- package/lib/target/token-response.d.cts +7 -0
- package/lib/target/token-response.d.mts +7 -0
- package/lib/target/token-response.d.ts +7 -0
- package/lib/target/token-response.js +51 -0
- package/lib/target/token-response.mjs +48 -0
- package/package.json +4 -7
- package/scripts/build-cluster.js +23 -3
- package/scripts/opcore-introduced-check.js +0 -2
- package/src/agent-cli-provider/adapters/codex.ts +0 -1
- package/src/cluster/client.ts +42 -15
- package/src/cluster/connection-state.ts +33 -0
- package/src/cluster/connection-types.ts +28 -0
- package/src/cluster/connection.ts +37 -68
- package/src/cluster/errors.ts +5 -0
- package/src/cluster/index.ts +3 -1
- package/src/cluster/json-source.ts +1 -0
- package/src/cluster/payload-value.ts +1 -0
- package/src/cluster/socket.ts +13 -0
- package/src/cluster/subscriptions.ts +7 -2
- package/src/cluster/validators.ts +1 -0
- package/src/cluster/ws.d.ts +1 -1
- package/src/hosted-session/authority.ts +77 -0
- package/src/hosted-session/coordinator.ts +113 -56
- package/src/hosted-session/errors.ts +21 -0
- package/src/hosted-session/index.ts +14 -2
- package/src/hosted-session/reconnecting-watch.ts +148 -0
- package/src/hosted-session/types.ts +22 -8
- package/src/hosted-target/access-url.ts +46 -0
- package/src/hosted-target/adapter-request.ts +28 -0
- package/src/hosted-target/adapter-types.ts +39 -0
- package/src/hosted-target/bounds.ts +1 -0
- package/src/hosted-target/capsule-error-response.ts +107 -0
- package/src/hosted-target/errors.ts +36 -35
- package/src/hosted-target/index.ts +10 -23
- package/src/hosted-target/response-validation.ts +170 -62
- package/src/hosted-target/retry-executor.ts +62 -0
- package/src/hosted-target/retry.ts +47 -11
- package/src/hosted-target/target-adapter.ts +12 -8
- package/src/hosted-target/types.ts +19 -18
- package/src/hosted-target/zero-cloud-v1-adapter.ts +229 -316
- package/src/isolation-manager.js +1 -16
- package/src/target/bounded-response.ts +68 -0
- package/src/target/credential-lock.ts +1 -3
- package/src/target/credential-store.ts +14 -10
- package/src/target/device-flow.ts +209 -85
- package/src/target/discovery-errors.ts +6 -0
- package/src/target/discovery-sections.ts +251 -0
- package/src/target/discovery-validation.ts +144 -0
- package/src/target/discovery.ts +163 -97
- package/src/target/index.ts +15 -11
- package/src/target/oauth-http.ts +27 -0
- package/src/target/refresh-exchange.ts +36 -0
- package/src/target/refresh-revocation.ts +29 -0
- package/src/target/route-template.ts +105 -0
- package/src/target/session-errors.ts +9 -0
- package/src/target/session-verification.ts +51 -0
- package/src/target/target-registry.ts +60 -27
- package/src/target/target-session-manager.ts +285 -0
- package/src/target/target-session.ts +105 -226
- package/src/target/token-response.ts +62 -0
- package/docker/zeroshot-oecp/Cargo.toml +0 -12
- package/docker/zeroshot-oecp/Dockerfile +0 -65
- package/docker/zeroshot-oecp/src/main.rs +0 -32
- package/lib/target/bounded-json.d.ts +0 -6
- package/lib/target/bounded-json.js +0 -43
- package/lib/target/hosted-run/client.d.ts +0 -26
- package/lib/target/hosted-run/client.js +0 -158
- package/lib/target/hosted-run/commands.d.ts +0 -4
- package/lib/target/hosted-run/commands.js +0 -113
- package/lib/target/hosted-run/contracts.d.ts +0 -49
- package/lib/target/hosted-run/input.d.ts +0 -5
- package/lib/target/hosted-run/input.js +0 -200
- package/lib/target/hosted-run.d.ts +0 -4
- package/lib/target/hosted-run.js +0 -12
- package/src/target/bounded-json.ts +0 -48
- package/src/target/hosted-run/client.ts +0 -198
- package/src/target/hosted-run/commands.ts +0 -140
- package/src/target/hosted-run/contracts.ts +0 -53
- package/src/target/hosted-run/input.ts +0 -199
- package/src/target/hosted-run.ts +0 -8
|
@@ -1,163 +1,75 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LoginRequiredError = void 0;
|
|
3
|
+
exports.TargetSessionManager = exports.LoginRequiredError = void 0;
|
|
4
4
|
exports.targetLogin = targetLogin;
|
|
5
5
|
exports.refreshAccessToken = refreshAccessToken;
|
|
6
6
|
exports.getAccessTokenProvider = getAccessTokenProvider;
|
|
7
7
|
exports.revokeAndCleanup = revokeAndCleanup;
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
const target_session_manager_js_1 = require("./target-session-manager.js");
|
|
9
|
+
var target_session_manager_js_2 = require("./target-session-manager.js");
|
|
10
|
+
Object.defineProperty(exports, "LoginRequiredError", { enumerable: true, get: function () { return target_session_manager_js_2.LoginRequiredError; } });
|
|
11
|
+
Object.defineProperty(exports, "TargetSessionManager", { enumerable: true, get: function () { return target_session_manager_js_2.TargetSessionManager; } });
|
|
12
|
+
function transientSettings(targetName, target) {
|
|
13
|
+
const state = {
|
|
14
|
+
_targets: { [targetName]: target },
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
load: () => state,
|
|
18
|
+
mutate: (mutator) => mutator(state),
|
|
19
|
+
};
|
|
18
20
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
throw new device_flow_ts_1.UnboundSessionError(codeResponse.verification_uri);
|
|
36
|
-
}
|
|
37
|
-
const serviceKey = (0, credential_store_ts_1.targetServiceKey)(target.id);
|
|
38
|
-
const release = await acquireLock();
|
|
39
|
-
try {
|
|
40
|
-
await credentialStore.set(serviceKey, credential_store_ts_1.TARGET_ACCOUNT, tokenResponse.refresh_token);
|
|
41
|
-
}
|
|
42
|
-
finally {
|
|
43
|
-
await release();
|
|
44
|
-
}
|
|
45
|
-
(0, target_registry_ts_1.updateTargetOrganization)(targetName, tokenResponse.organization, settings);
|
|
46
|
-
return { organization: tokenResponse.organization };
|
|
21
|
+
function legacyManager(init) {
|
|
22
|
+
const clock = init.clock ?? init.deps.clock ?? { now: () => Date.now() };
|
|
23
|
+
return new target_session_manager_js_1.TargetSessionManager({
|
|
24
|
+
targetName: init.targetName,
|
|
25
|
+
target: init.target,
|
|
26
|
+
credentialStore: init.credentialStore,
|
|
27
|
+
acquireLock: init.acquireLock,
|
|
28
|
+
settings: init.deps.settings ?? transientSettings(init.targetName, init.target),
|
|
29
|
+
deps: {
|
|
30
|
+
http: init.deps.http,
|
|
31
|
+
clock,
|
|
32
|
+
browserOpener: { open: () => Promise.resolve() },
|
|
33
|
+
stderr: { write: () => undefined },
|
|
34
|
+
discoveryEndpoints: init.deps.discoveryEndpoints,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
47
37
|
}
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const body = new URLSearchParams({
|
|
59
|
-
grant_type: 'refresh_token',
|
|
60
|
-
refresh_token: currentRefreshToken,
|
|
61
|
-
client_id: clientId,
|
|
62
|
-
audience: 'capsule',
|
|
63
|
-
});
|
|
64
|
-
let tokenResponse;
|
|
65
|
-
const response = await http.fetch(tokenEndpoint, {
|
|
66
|
-
method: 'POST',
|
|
67
|
-
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
68
|
-
body: body.toString(),
|
|
69
|
-
redirect: 'error',
|
|
70
|
-
});
|
|
71
|
-
if (!response.ok) {
|
|
72
|
-
const errorBody = (await response.json().catch(() => ({ error: 'unknown' })));
|
|
73
|
-
if (errorBody.error === 'invalid_grant') {
|
|
74
|
-
await credentialStore.delete(serviceKey, credential_store_ts_1.TARGET_ACCOUNT);
|
|
75
|
-
throw new LoginRequiredError(targetName);
|
|
76
|
-
}
|
|
77
|
-
throw new Error(`Token refresh failed (${response.status}): ${errorBody.error}`);
|
|
78
|
-
}
|
|
79
|
-
tokenResponse = (await response.json());
|
|
80
|
-
try {
|
|
81
|
-
await credentialStore.set(serviceKey, credential_store_ts_1.TARGET_ACCOUNT, tokenResponse.refresh_token);
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
await bestEffortRevoke(tokenResponse.refresh_token, revocationEndpoint, clientId, http);
|
|
85
|
-
await credentialStore.delete(serviceKey, credential_store_ts_1.TARGET_ACCOUNT);
|
|
86
|
-
throw new LoginRequiredError(targetName);
|
|
87
|
-
}
|
|
88
|
-
return { accessToken: tokenResponse.access_token, expiresIn: tokenResponse.expires_in };
|
|
89
|
-
}
|
|
90
|
-
finally {
|
|
91
|
-
await release();
|
|
92
|
-
}
|
|
38
|
+
function targetLogin(...args) {
|
|
39
|
+
const [targetName, target, credentialStore, acquireLock, settings, deps] = args;
|
|
40
|
+
return new target_session_manager_js_1.TargetSessionManager({
|
|
41
|
+
targetName,
|
|
42
|
+
target,
|
|
43
|
+
credentialStore,
|
|
44
|
+
acquireLock,
|
|
45
|
+
settings,
|
|
46
|
+
deps,
|
|
47
|
+
}).login();
|
|
93
48
|
}
|
|
94
|
-
async function
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
method: 'POST',
|
|
105
|
-
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
106
|
-
body: body.toString(),
|
|
107
|
-
redirect: 'error',
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
catch {
|
|
111
|
-
// Best-effort
|
|
112
|
-
}
|
|
49
|
+
async function refreshAccessToken(...args) {
|
|
50
|
+
const [targetName, target, credentialStore, acquireLock, deps, clock] = args;
|
|
51
|
+
return legacyManager({
|
|
52
|
+
targetName,
|
|
53
|
+
target,
|
|
54
|
+
credentialStore,
|
|
55
|
+
acquireLock,
|
|
56
|
+
deps,
|
|
57
|
+
...(clock === undefined ? {} : { clock }),
|
|
58
|
+
}).getAccessTokenWithLifetime('capsule');
|
|
113
59
|
}
|
|
114
|
-
function getAccessTokenProvider(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
expiresAt = clock.now() + result.expiresIn * 1000;
|
|
125
|
-
return result.accessToken;
|
|
126
|
-
},
|
|
127
|
-
};
|
|
60
|
+
function getAccessTokenProvider(...args) {
|
|
61
|
+
const [targetName, target, credentialStore, acquireLock, deps, clock] = args;
|
|
62
|
+
return legacyManager({
|
|
63
|
+
targetName,
|
|
64
|
+
target,
|
|
65
|
+
credentialStore,
|
|
66
|
+
acquireLock,
|
|
67
|
+
deps,
|
|
68
|
+
...(clock === undefined ? {} : { clock }),
|
|
69
|
+
}).tokenProvider('capsule');
|
|
128
70
|
}
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
const release = await acquireLock();
|
|
134
|
-
try {
|
|
135
|
-
const refreshToken = await credentialStore.get(serviceKey, credential_store_ts_1.TARGET_ACCOUNT);
|
|
136
|
-
if (refreshToken && revocationEndpoint) {
|
|
137
|
-
const body = new URLSearchParams({
|
|
138
|
-
token: refreshToken,
|
|
139
|
-
client_id: clientId,
|
|
140
|
-
token_type_hint: 'refresh_token',
|
|
141
|
-
});
|
|
142
|
-
try {
|
|
143
|
-
const response = await http.fetch(revocationEndpoint, {
|
|
144
|
-
method: 'POST',
|
|
145
|
-
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
146
|
-
body: body.toString(),
|
|
147
|
-
redirect: 'error',
|
|
148
|
-
});
|
|
149
|
-
if (!response.ok && !force) {
|
|
150
|
-
throw new Error(`Remote revocation failed (${response.status}). Use --force to remove anyway.`);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
catch (err) {
|
|
154
|
-
if (!force)
|
|
155
|
-
throw err;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
await credentialStore.delete(serviceKey, credential_store_ts_1.TARGET_ACCOUNT);
|
|
159
|
-
}
|
|
160
|
-
finally {
|
|
161
|
-
await release();
|
|
162
|
-
}
|
|
71
|
+
function revokeAndCleanup(...args) {
|
|
72
|
+
const [target, credentialStore, acquireLock, deps, force] = args;
|
|
73
|
+
const targetName = deps.targetName ?? target.id;
|
|
74
|
+
return legacyManager({ targetName, target, credentialStore, acquireLock, deps }).revoke(force);
|
|
163
75
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTokenResponse = parseTokenResponse;
|
|
4
|
+
const MAX_TOKEN_BYTES = 16 * 1024;
|
|
5
|
+
const TOKEN_RESPONSE_FIELDS = [
|
|
6
|
+
'access_token',
|
|
7
|
+
'refresh_token',
|
|
8
|
+
'token_type',
|
|
9
|
+
'expires_in',
|
|
10
|
+
'refresh_expires_in',
|
|
11
|
+
'scope',
|
|
12
|
+
];
|
|
13
|
+
function boundedString(value, maxBytes) {
|
|
14
|
+
return typeof value === 'string' && value.length > 0 &&
|
|
15
|
+
new TextEncoder().encode(value).byteLength <= maxBytes;
|
|
16
|
+
}
|
|
17
|
+
function tokenFieldsValid(token) {
|
|
18
|
+
const fields = Object.keys(token);
|
|
19
|
+
return fields.length === TOKEN_RESPONSE_FIELDS.length &&
|
|
20
|
+
fields.every((key) => TOKEN_RESPONSE_FIELDS.includes(key));
|
|
21
|
+
}
|
|
22
|
+
function tokenLifetimesValid(token) {
|
|
23
|
+
return Number.isSafeInteger(token.expires_in) &&
|
|
24
|
+
token.expires_in > 0 &&
|
|
25
|
+
token.expires_in <= 86_400 &&
|
|
26
|
+
Number.isSafeInteger(token.refresh_expires_in) &&
|
|
27
|
+
token.refresh_expires_in > 0 &&
|
|
28
|
+
token.refresh_expires_in <= 31_536_000;
|
|
29
|
+
}
|
|
30
|
+
function tokenStringsValid(token) {
|
|
31
|
+
return boundedString(token.access_token, MAX_TOKEN_BYTES) &&
|
|
32
|
+
boundedString(token.refresh_token, MAX_TOKEN_BYTES) &&
|
|
33
|
+
token.token_type === 'Bearer' &&
|
|
34
|
+
boundedString(token.scope, 512) &&
|
|
35
|
+
!/[\u0000-\u001f\u007f]/.test(token.scope);
|
|
36
|
+
}
|
|
37
|
+
function parseTokenResponse(value) {
|
|
38
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
39
|
+
throw new Error('Token response is malformed');
|
|
40
|
+
}
|
|
41
|
+
const token = value;
|
|
42
|
+
if (!tokenFieldsValid(token) || !tokenLifetimesValid(token) || !tokenStringsValid(token)) {
|
|
43
|
+
throw new Error('Token response is malformed');
|
|
44
|
+
}
|
|
45
|
+
return Object.freeze({
|
|
46
|
+
access_token: token.access_token,
|
|
47
|
+
refresh_token: token.refresh_token,
|
|
48
|
+
token_type: 'Bearer',
|
|
49
|
+
expires_in: token.expires_in,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTokenResponse = parseTokenResponse;
|
|
4
|
+
const MAX_TOKEN_BYTES = 16 * 1024;
|
|
5
|
+
const TOKEN_RESPONSE_FIELDS = [
|
|
6
|
+
'access_token',
|
|
7
|
+
'refresh_token',
|
|
8
|
+
'token_type',
|
|
9
|
+
'expires_in',
|
|
10
|
+
'refresh_expires_in',
|
|
11
|
+
'scope',
|
|
12
|
+
];
|
|
13
|
+
function boundedString(value, maxBytes) {
|
|
14
|
+
return typeof value === 'string' && value.length > 0 &&
|
|
15
|
+
new TextEncoder().encode(value).byteLength <= maxBytes;
|
|
16
|
+
}
|
|
17
|
+
function tokenFieldsValid(token) {
|
|
18
|
+
const fields = Object.keys(token);
|
|
19
|
+
return fields.length === TOKEN_RESPONSE_FIELDS.length &&
|
|
20
|
+
fields.every((key) => TOKEN_RESPONSE_FIELDS.includes(key));
|
|
21
|
+
}
|
|
22
|
+
function tokenLifetimesValid(token) {
|
|
23
|
+
return Number.isSafeInteger(token.expires_in) &&
|
|
24
|
+
token.expires_in > 0 &&
|
|
25
|
+
token.expires_in <= 86_400 &&
|
|
26
|
+
Number.isSafeInteger(token.refresh_expires_in) &&
|
|
27
|
+
token.refresh_expires_in > 0 &&
|
|
28
|
+
token.refresh_expires_in <= 31_536_000;
|
|
29
|
+
}
|
|
30
|
+
function tokenStringsValid(token) {
|
|
31
|
+
return boundedString(token.access_token, MAX_TOKEN_BYTES) &&
|
|
32
|
+
boundedString(token.refresh_token, MAX_TOKEN_BYTES) &&
|
|
33
|
+
token.token_type === 'Bearer' &&
|
|
34
|
+
boundedString(token.scope, 512) &&
|
|
35
|
+
!/[\u0000-\u001f\u007f]/.test(token.scope);
|
|
36
|
+
}
|
|
37
|
+
function parseTokenResponse(value) {
|
|
38
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
39
|
+
throw new Error('Token response is malformed');
|
|
40
|
+
}
|
|
41
|
+
const token = value;
|
|
42
|
+
if (!tokenFieldsValid(token) || !tokenLifetimesValid(token) || !tokenStringsValid(token)) {
|
|
43
|
+
throw new Error('Token response is malformed');
|
|
44
|
+
}
|
|
45
|
+
return Object.freeze({
|
|
46
|
+
access_token: token.access_token,
|
|
47
|
+
refresh_token: token.refresh_token,
|
|
48
|
+
token_type: 'Bearer',
|
|
49
|
+
expires_in: token.expires_in,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const MAX_TOKEN_BYTES = 16 * 1024;
|
|
2
|
+
const TOKEN_RESPONSE_FIELDS = [
|
|
3
|
+
'access_token',
|
|
4
|
+
'refresh_token',
|
|
5
|
+
'token_type',
|
|
6
|
+
'expires_in',
|
|
7
|
+
'refresh_expires_in',
|
|
8
|
+
'scope',
|
|
9
|
+
];
|
|
10
|
+
function boundedString(value, maxBytes) {
|
|
11
|
+
return typeof value === 'string' && value.length > 0 &&
|
|
12
|
+
new TextEncoder().encode(value).byteLength <= maxBytes;
|
|
13
|
+
}
|
|
14
|
+
function tokenFieldsValid(token) {
|
|
15
|
+
const fields = Object.keys(token);
|
|
16
|
+
return fields.length === TOKEN_RESPONSE_FIELDS.length &&
|
|
17
|
+
fields.every((key) => TOKEN_RESPONSE_FIELDS.includes(key));
|
|
18
|
+
}
|
|
19
|
+
function tokenLifetimesValid(token) {
|
|
20
|
+
return Number.isSafeInteger(token.expires_in) &&
|
|
21
|
+
token.expires_in > 0 &&
|
|
22
|
+
token.expires_in <= 86_400 &&
|
|
23
|
+
Number.isSafeInteger(token.refresh_expires_in) &&
|
|
24
|
+
token.refresh_expires_in > 0 &&
|
|
25
|
+
token.refresh_expires_in <= 31_536_000;
|
|
26
|
+
}
|
|
27
|
+
function tokenStringsValid(token) {
|
|
28
|
+
return boundedString(token.access_token, MAX_TOKEN_BYTES) &&
|
|
29
|
+
boundedString(token.refresh_token, MAX_TOKEN_BYTES) &&
|
|
30
|
+
token.token_type === 'Bearer' &&
|
|
31
|
+
boundedString(token.scope, 512) &&
|
|
32
|
+
!/[\u0000-\u001f\u007f]/.test(token.scope);
|
|
33
|
+
}
|
|
34
|
+
export function parseTokenResponse(value) {
|
|
35
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
36
|
+
throw new Error('Token response is malformed');
|
|
37
|
+
}
|
|
38
|
+
const token = value;
|
|
39
|
+
if (!tokenFieldsValid(token) || !tokenLifetimesValid(token) || !tokenStringsValid(token)) {
|
|
40
|
+
throw new Error('Token response is malformed');
|
|
41
|
+
}
|
|
42
|
+
return Object.freeze({
|
|
43
|
+
access_token: token.access_token,
|
|
44
|
+
refresh_token: token.refresh_token,
|
|
45
|
+
token_type: 'Bearer',
|
|
46
|
+
expires_in: token.expires_in,
|
|
47
|
+
});
|
|
48
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@the-open-engine/zeroshot",
|
|
3
|
-
"version": "6.29.
|
|
3
|
+
"version": "6.29.1",
|
|
4
4
|
"description": "Multi-agent orchestration engine for Claude, Codex, and Gemini",
|
|
5
5
|
"main": "src/orchestrator.js",
|
|
6
6
|
"bin": {
|
|
@@ -44,20 +44,20 @@
|
|
|
44
44
|
"typecheck:agent-cli-provider": "tsc --project tsconfig.agent-cli-provider.json",
|
|
45
45
|
"typecheck:hosted-target": "tsc --project tsconfig.hosted-target.json",
|
|
46
46
|
"typecheck:hosted-session": "tsc --project tsconfig.hosted-session.json",
|
|
47
|
-
"test:hosted-target": "node --test tests/hosted-target/*.test.ts",
|
|
47
|
+
"test:hosted-target": "npm run build:cluster && node --test tests/hosted-target/*.test.ts",
|
|
48
48
|
"test:target": "npm run build:agent-cli-provider && npm run build:target && node --test tests/target/*.test.ts",
|
|
49
49
|
"typecheck:target": "tsc --project tsconfig.target.json",
|
|
50
50
|
"typecheck:cluster": "tsc --project tsconfig.cluster.json",
|
|
51
51
|
"lint:agent-cli-provider": "eslint \"src/agent-cli-provider/**/*.ts\" \"tests/agent-cli-provider/**/*.ts\"",
|
|
52
52
|
"build:agent-cli-provider": "tsc --project tsconfig.agent-cli-provider.build.json",
|
|
53
53
|
"build:target": "tsc --project tsconfig.target.build.json",
|
|
54
|
-
"build:cluster": "npm run protocol:generate && tsc --project tsconfig.cluster.cjs.json && tsc --project tsconfig.cluster.esm.json && tsc --project tsconfig.hosted-session.cjs.json && tsc --project tsconfig.hosted-session.esm.json && node scripts/build-cluster.js",
|
|
54
|
+
"build:cluster": "npm run protocol:generate && tsc --project tsconfig.cluster.cjs.json && tsc --project tsconfig.cluster.esm.json && tsc --project tsconfig.hosted-target.cjs.json && tsc --project tsconfig.hosted-target.esm.json && tsc --project tsconfig.hosted-session.cjs.json && tsc --project tsconfig.hosted-session.esm.json && node scripts/build-cluster.js",
|
|
55
55
|
"test:agent-cli-provider": "node --test tests/agent-cli-provider/*.test.js",
|
|
56
56
|
"test:omp": "npm run build:agent-cli-provider && node --test tests/agent-cli-provider/omp-*.test.js && node tests/run-tests.js tests/omp-rpc-watcher.test.js tests/omp-isolation-capability.test.js tests/omp-docker-auth.test.js tests/omp-docker-fresh-only.test.js",
|
|
57
57
|
"test:providers:live": "npm run build:agent-cli-provider && node scripts/live-provider-smoke.js",
|
|
58
58
|
"check:agent-cli-provider": "npm run check:agent-cli-provider:ci",
|
|
59
59
|
"check:agent-cli-provider:ci": "npm run typecheck:agent-cli-provider && npm run lint:agent-cli-provider && npm run build:agent-cli-provider && npm run test:agent-cli-provider",
|
|
60
|
-
"test:cluster-client": "npm run build:cluster && node --test tests/cluster/client.test.js tests/cluster/parity.test.js tests/cluster/architecture.test.js tests/cluster/verifier-regressions.test.js tests/cluster/request-validation.test.js tests/hosted-session/coordinator.test.js",
|
|
60
|
+
"test:cluster-client": "npm run build:cluster && node --test tests/cluster/client.test.js tests/cluster/client-lifecycle.test.js tests/cluster/parity.test.js tests/cluster/architecture.test.js tests/cluster/verifier-regressions.test.js tests/cluster/request-validation.test.js tests/hosted-session/coordinator.test.js tests/hosted-session/coordinator-cancellation.test.js",
|
|
61
61
|
"test:cluster-package": "npm run build:agent-cli-provider && npm run build:cluster && npm run build:target && node --test tests/cluster/package.test.js",
|
|
62
62
|
"dev:link": "npm link",
|
|
63
63
|
"opcore:status": "opcore status --repo . --json",
|
|
@@ -157,9 +157,6 @@
|
|
|
157
157
|
"files": [
|
|
158
158
|
"src/",
|
|
159
159
|
"lib/",
|
|
160
|
-
"!src/target/register-hosted-commands.ts",
|
|
161
|
-
"!lib/target/register-hosted-commands.js",
|
|
162
|
-
"!lib/target/register-hosted-commands.d.ts",
|
|
163
160
|
"bin/",
|
|
164
161
|
"cli/",
|
|
165
162
|
"task-lib/",
|
package/scripts/build-cluster.js
CHANGED
|
@@ -6,8 +6,11 @@ const path = require('node:path');
|
|
|
6
6
|
const root = path.resolve(__dirname, '..');
|
|
7
7
|
const clusterBuildRoot = path.join(root, '.cluster-build');
|
|
8
8
|
const hostedSessionBuildRoot = path.join(root, '.hosted-session-build');
|
|
9
|
+
const hostedTargetBuildRoot = path.join(root, '.hosted-target-build');
|
|
9
10
|
const clusterOutputRoot = path.join(root, 'lib/cluster');
|
|
10
11
|
const hostedSessionOutputRoot = path.join(root, 'lib/hosted-session');
|
|
12
|
+
const hostedTargetOutputRoot = path.join(root, 'lib/hosted-target');
|
|
13
|
+
const targetOutputRoot = path.join(root, 'lib/target');
|
|
11
14
|
|
|
12
15
|
function filesBelow(directory) {
|
|
13
16
|
const entries = fs.readdirSync(directory, { withFileTypes: true });
|
|
@@ -17,6 +20,15 @@ function filesBelow(directory) {
|
|
|
17
20
|
});
|
|
18
21
|
}
|
|
19
22
|
|
|
23
|
+
function declarationContent(source, localExtension) {
|
|
24
|
+
return fs
|
|
25
|
+
.readFileSync(source, 'utf8')
|
|
26
|
+
.replace(/(["'])(\.\.?\/[^"']+)\.ts\1/g, (_match, quote, specifier) => {
|
|
27
|
+
const extension = specifier.startsWith('../target/') ? '.js' : localExtension;
|
|
28
|
+
return `${quote}${specifier}${extension}${quote}`;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
20
32
|
function copyBuild(sourceRoot, outputRoot, mode) {
|
|
21
33
|
for (const source of filesBelow(sourceRoot)) {
|
|
22
34
|
const relative = path.relative(sourceRoot, source);
|
|
@@ -32,15 +44,18 @@ function copyBuild(sourceRoot, outputRoot, mode) {
|
|
|
32
44
|
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
33
45
|
fs.writeFileSync(target, content);
|
|
34
46
|
} else if (mode === 'cjs' && extension === '.ts' && relative.endsWith('.d.ts')) {
|
|
35
|
-
const
|
|
36
|
-
fs.mkdirSync(path.dirname(
|
|
37
|
-
fs.
|
|
47
|
+
const base = path.join(outputRoot, relative.slice(0, -5));
|
|
48
|
+
fs.mkdirSync(path.dirname(base), { recursive: true });
|
|
49
|
+
fs.writeFileSync(`${base}.d.ts`, declarationContent(source, '.js'));
|
|
50
|
+
fs.writeFileSync(`${base}.d.cts`, declarationContent(source, '.cjs'));
|
|
51
|
+
fs.writeFileSync(`${base}.d.mts`, declarationContent(source, '.mjs'));
|
|
38
52
|
}
|
|
39
53
|
}
|
|
40
54
|
}
|
|
41
55
|
|
|
42
56
|
fs.rmSync(clusterOutputRoot, { recursive: true, force: true });
|
|
43
57
|
fs.rmSync(hostedSessionOutputRoot, { recursive: true, force: true });
|
|
58
|
+
fs.rmSync(hostedTargetOutputRoot, { recursive: true, force: true });
|
|
44
59
|
copyBuild(path.join(clusterBuildRoot, 'cjs'), clusterOutputRoot, 'cjs');
|
|
45
60
|
copyBuild(path.join(clusterBuildRoot, 'esm'), clusterOutputRoot, 'esm');
|
|
46
61
|
copyBuild(
|
|
@@ -53,5 +68,10 @@ copyBuild(
|
|
|
53
68
|
hostedSessionOutputRoot,
|
|
54
69
|
'esm'
|
|
55
70
|
);
|
|
71
|
+
copyBuild(path.join(hostedTargetBuildRoot, 'cjs', 'hosted-target'), hostedTargetOutputRoot, 'cjs');
|
|
72
|
+
copyBuild(path.join(hostedTargetBuildRoot, 'esm', 'hosted-target'), hostedTargetOutputRoot, 'esm');
|
|
73
|
+
copyBuild(path.join(hostedTargetBuildRoot, 'cjs', 'target'), targetOutputRoot, 'cjs');
|
|
74
|
+
copyBuild(path.join(hostedTargetBuildRoot, 'esm', 'target'), targetOutputRoot, 'esm');
|
|
56
75
|
fs.rmSync(clusterBuildRoot, { recursive: true, force: true });
|
|
57
76
|
fs.rmSync(hostedSessionBuildRoot, { recursive: true, force: true });
|
|
77
|
+
fs.rmSync(hostedTargetBuildRoot, { recursive: true, force: true });
|
|
@@ -197,8 +197,6 @@ function createRequest(repo, baseline, changes, options) {
|
|
|
197
197
|
for (const change of changes) {
|
|
198
198
|
normalizeBaselineRename(baseline, change);
|
|
199
199
|
if (change.kind === 'D') {
|
|
200
|
-
overlays.push({ action: 'delete', path: change.path });
|
|
201
|
-
files.push(change.path);
|
|
202
200
|
continue;
|
|
203
201
|
}
|
|
204
202
|
const content = readAfter(repo, change, options.staged);
|
|
@@ -28,7 +28,6 @@ import { parseCodexEvent } from './codex-parser';
|
|
|
28
28
|
|
|
29
29
|
const MODEL_CATALOG: Readonly<Record<string, ModelCatalogEntry>> = {
|
|
30
30
|
'gpt-5.4': { rank: 2 },
|
|
31
|
-
'openai/gpt-5.4': { rank: 2 },
|
|
32
31
|
'gpt-5.5': { rank: 3 },
|
|
33
32
|
'gpt-5.6': { rank: 3 },
|
|
34
33
|
'gpt-5.6-sol': { rank: 3 },
|
package/src/cluster/client.ts
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
|
+
/// <reference path="./ws.d.ts" />
|
|
1
2
|
import { PROTOCOL_VERSION } from './generated/protocol.js';
|
|
2
3
|
import type {
|
|
3
4
|
AgentAttachParams, AgentAttachResult, ApplyParams, ApplyResult, DeleteParams, DeleteResult,
|
|
4
5
|
GetParams, GetResult, InitializeParams, InitializeResult, LogsParams, LogsResult,
|
|
5
6
|
PlanParams, PlanResult, ResubmitParams, ResubmitResult, RetryParams, RetryResult,
|
|
6
|
-
StopParams, StopResult, UpdateParams, UpdateResult, WatchParams,
|
|
7
|
+
StopParams, StopResult, UpdateParams, UpdateResult, WatchParams,
|
|
7
8
|
} from './generated/protocol.js';
|
|
8
9
|
import { Connection } from './connection.js';
|
|
9
10
|
import type { CallOptions } from './connection.js';
|
|
10
|
-
import { addSocketListener } from './socket.js';
|
|
11
|
+
import { addSocketEmitterListener, addSocketListener } from './socket.js';
|
|
11
12
|
import type { WebSocketLike } from './socket.js';
|
|
12
|
-
import { ClusterConfigError, ClusterProtocolError, ClusterTransportError } from './errors.js';
|
|
13
|
+
import { ClusterConfigError, ClusterProtocolError, ClusterTransportError, ClusterUpgradeError } from './errors.js';
|
|
13
14
|
import {
|
|
14
15
|
AgentAttachSubscriptionStream,
|
|
15
16
|
LogsSubscriptionStream,
|
|
16
17
|
WatchSubscriptionStream,
|
|
17
18
|
} from './subscriptions.js';
|
|
19
|
+
import type { WatchSubscription } from './subscriptions.js';
|
|
20
|
+
export type { WatchSubscription } from './subscriptions.js';
|
|
18
21
|
|
|
19
22
|
export interface WebSocketFactoryOptions {
|
|
20
23
|
readonly headers?: Readonly<Record<string, string>>;
|
|
@@ -26,7 +29,6 @@ export interface ConnectOptions {
|
|
|
26
29
|
readonly initialize?: InitializeParams;
|
|
27
30
|
readonly headers?: Readonly<Record<string, string>>;
|
|
28
31
|
}
|
|
29
|
-
export interface WatchSubscription { readonly result: WatchResult; readonly stream: WatchSubscriptionStream; }
|
|
30
32
|
export interface LogsSubscription { readonly result: LogsResult; readonly stream: LogsSubscriptionStream; }
|
|
31
33
|
export interface AgentAttachSubscription { readonly result: AgentAttachResult; readonly stream: AgentAttachSubscriptionStream; }
|
|
32
34
|
export interface CoherentWatchSubscription extends WatchSubscription { readonly snapshot: GetResult; }
|
|
@@ -131,13 +133,7 @@ async function defaultWebSocketFactory(
|
|
|
131
133
|
protocols?: string | readonly string[],
|
|
132
134
|
) => WebSocketLike;
|
|
133
135
|
}).WebSocket;
|
|
134
|
-
if (globalWebSocket) {
|
|
135
|
-
if (options?.headers && Object.keys(options.headers).length > 0) {
|
|
136
|
-
throw new ClusterConfigError(
|
|
137
|
-
'WebSocket upgrade headers require the ws library; the browser WebSocket API cannot carry request headers',
|
|
138
|
-
'HEADERS_UNSUPPORTED',
|
|
139
|
-
);
|
|
140
|
-
}
|
|
136
|
+
if (globalWebSocket && (!options?.headers || Object.keys(options.headers).length === 0)) {
|
|
141
137
|
return new globalWebSocket(url, protocols);
|
|
142
138
|
}
|
|
143
139
|
try {
|
|
@@ -175,6 +171,7 @@ async function waitForOpen(socket: WebSocketLike, signal?: AbortSignal): Promise
|
|
|
175
171
|
await new Promise<void>((resolve, reject) => {
|
|
176
172
|
let settled = false;
|
|
177
173
|
const removers: Array<() => void> = [];
|
|
174
|
+
let upgradeFailure: ClusterUpgradeError | ClusterTransportError | undefined;
|
|
178
175
|
const settle = (fn: () => void) => {
|
|
179
176
|
if (settled) return;
|
|
180
177
|
settled = true;
|
|
@@ -186,15 +183,45 @@ async function waitForOpen(socket: WebSocketLike, signal?: AbortSignal): Promise
|
|
|
186
183
|
'connect aborted locally; the server may still have committed this request',
|
|
187
184
|
'AbortError',
|
|
188
185
|
)));
|
|
186
|
+
const onUnexpectedResponse = (...args: unknown[]) => {
|
|
187
|
+
const response = args.find(
|
|
188
|
+
(value) => value !== null && typeof value === 'object' && 'statusCode' in value,
|
|
189
|
+
) as { statusCode?: unknown; resume?: () => void } | undefined;
|
|
190
|
+
const status = response?.statusCode;
|
|
191
|
+
upgradeFailure = typeof status === 'number'
|
|
192
|
+
? new ClusterUpgradeError(status)
|
|
193
|
+
: new ClusterTransportError('WebSocket upgrade rejected', 'UPGRADE_REJECTED');
|
|
194
|
+
response?.resume?.();
|
|
195
|
+
if (socket.terminate) {
|
|
196
|
+
socket.terminate();
|
|
197
|
+
} else {
|
|
198
|
+
settle(() => reject(upgradeFailure));
|
|
199
|
+
}
|
|
200
|
+
};
|
|
189
201
|
removers.push(
|
|
190
202
|
addSocketListener(socket, 'open', () => settle(resolve)),
|
|
191
|
-
addSocketListener(socket, 'error', (error) => settle(() => reject(
|
|
192
|
-
|
|
203
|
+
addSocketListener(socket, 'error', (error) => settle(() => reject(
|
|
204
|
+
upgradeFailure ??
|
|
205
|
+
new ClusterTransportError('WebSocket failed to open', 'OPEN_FAILED', { cause: error }),
|
|
206
|
+
))),
|
|
207
|
+
addSocketListener(socket, 'close', () => settle(() => reject(
|
|
208
|
+
upgradeFailure ??
|
|
209
|
+
new ClusterTransportError('WebSocket closed before opening', 'OPEN_FAILED'),
|
|
210
|
+
))),
|
|
211
|
+
addSocketEmitterListener(socket, 'unexpected-response', onUnexpectedResponse),
|
|
193
212
|
);
|
|
194
213
|
signal?.addEventListener('abort', onAbort, { once: true });
|
|
195
214
|
});
|
|
196
215
|
}
|
|
197
216
|
|
|
217
|
+
async function disposeFailedSocket(socket: WebSocketLike): Promise<void> {
|
|
218
|
+
if (socket.readyState === 0 && socket.terminate) {
|
|
219
|
+
socket.terminate();
|
|
220
|
+
} else {
|
|
221
|
+
await socket.close();
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
198
225
|
export async function connect(url: string, options: ConnectOptions = {}): Promise<Connection> {
|
|
199
226
|
const factory = options.webSocketFactory ?? defaultWebSocketFactory;
|
|
200
227
|
let socket: WebSocketLike | undefined;
|
|
@@ -209,7 +236,7 @@ export async function connect(url: string, options: ConnectOptions = {}): Promis
|
|
|
209
236
|
return connection;
|
|
210
237
|
} catch (error) {
|
|
211
238
|
if (socket) {
|
|
212
|
-
try { await socket
|
|
239
|
+
try { await disposeFailedSocket(socket); }
|
|
213
240
|
catch { /* preserve the construction error */ }
|
|
214
241
|
}
|
|
215
242
|
throw error;
|
|
@@ -231,7 +258,7 @@ export async function connectInitialized(url: string, options: ConnectOptions =
|
|
|
231
258
|
return { connection, client, initializeResult };
|
|
232
259
|
} catch (error) {
|
|
233
260
|
if (socket) {
|
|
234
|
-
try { await socket
|
|
261
|
+
try { await disposeFailedSocket(socket); }
|
|
235
262
|
catch { /* preserve the construction error */ }
|
|
236
263
|
}
|
|
237
264
|
throw error;
|