@aria-cli/tools 1.0.9 → 1.0.11
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/package.json +9 -5
- package/src/__tests__/web-fetch-download.test.ts +0 -433
- package/src/__tests__/web-tools.test.ts +0 -619
- package/src/ask-user-interaction.ts +0 -33
- package/src/cache/web-cache.ts +0 -110
- package/src/definitions/arion.ts +0 -118
- package/src/definitions/browser/browser.ts +0 -502
- package/src/definitions/browser/index.ts +0 -5
- package/src/definitions/browser/pw-downloads.ts +0 -142
- package/src/definitions/browser/pw-interactions.ts +0 -282
- package/src/definitions/browser/pw-responses.ts +0 -98
- package/src/definitions/browser/pw-session.ts +0 -405
- package/src/definitions/browser/pw-shared.ts +0 -85
- package/src/definitions/browser/pw-snapshot.ts +0 -383
- package/src/definitions/browser/pw-state.ts +0 -101
- package/src/definitions/browser/types.ts +0 -203
- package/src/definitions/code-intelligence.ts +0 -526
- package/src/definitions/core.ts +0 -118
- package/src/definitions/delegation.ts +0 -567
- package/src/definitions/deploy.ts +0 -73
- package/src/definitions/filesystem.ts +0 -217
- package/src/definitions/frg.ts +0 -67
- package/src/definitions/index.ts +0 -28
- package/src/definitions/memory.ts +0 -150
- package/src/definitions/messaging.ts +0 -734
- package/src/definitions/meta.ts +0 -392
- package/src/definitions/network.ts +0 -179
- package/src/definitions/outlook.ts +0 -318
- package/src/definitions/patch/apply-patch.ts +0 -235
- package/src/definitions/patch/fuzzy-match.ts +0 -217
- package/src/definitions/patch/index.ts +0 -1
- package/src/definitions/patch/patch-parser.ts +0 -297
- package/src/definitions/patch/sandbox-paths.ts +0 -129
- package/src/definitions/process/index.ts +0 -5
- package/src/definitions/process/process-registry.ts +0 -303
- package/src/definitions/process/process.ts +0 -456
- package/src/definitions/process/pty-keys.ts +0 -298
- package/src/definitions/process/session-slug.ts +0 -147
- package/src/definitions/quip.ts +0 -225
- package/src/definitions/search.ts +0 -67
- package/src/definitions/session-history.ts +0 -79
- package/src/definitions/shell.ts +0 -202
- package/src/definitions/slack.ts +0 -211
- package/src/definitions/web.ts +0 -119
- package/src/executors/apply-patch.ts +0 -1035
- package/src/executors/arion.ts +0 -199
- package/src/executors/code-intelligence.ts +0 -1179
- package/src/executors/deploy.ts +0 -1066
- package/src/executors/filesystem.ts +0 -1428
- package/src/executors/frg-freshness.ts +0 -743
- package/src/executors/frg.ts +0 -394
- package/src/executors/index.ts +0 -280
- package/src/executors/learning-meta.ts +0 -1367
- package/src/executors/lsp-client.ts +0 -355
- package/src/executors/memory.ts +0 -978
- package/src/executors/meta.ts +0 -293
- package/src/executors/process-registry.ts +0 -570
- package/src/executors/pty-session-store.ts +0 -43
- package/src/executors/pty.ts +0 -342
- package/src/executors/restart.ts +0 -133
- package/src/executors/search-freshness.ts +0 -249
- package/src/executors/search-types.ts +0 -98
- package/src/executors/search.ts +0 -89
- package/src/executors/self-diagnose.ts +0 -552
- package/src/executors/session-history.ts +0 -435
- package/src/executors/shell-safety.ts +0 -519
- package/src/executors/shell.ts +0 -1243
- package/src/executors/utils.ts +0 -40
- package/src/executors/web.ts +0 -786
- package/src/extraction/content-extraction.ts +0 -281
- package/src/extraction/index.ts +0 -5
- package/src/headless-control-contract.ts +0 -1149
- package/src/index.ts +0 -788
- package/src/local-control-http-auth.ts +0 -2
- package/src/mcp/client.ts +0 -218
- package/src/mcp/connection.ts +0 -568
- package/src/mcp/index.ts +0 -11
- package/src/mcp/jsonrpc.ts +0 -195
- package/src/mcp/types.ts +0 -199
- package/src/network-control-adapter.ts +0 -88
- package/src/network-runtime/address-types.ts +0 -218
- package/src/network-runtime/db-owner-fencing.ts +0 -91
- package/src/network-runtime/delivery-receipts.ts +0 -372
- package/src/network-runtime/direct-endpoint-authority.ts +0 -35
- package/src/network-runtime/index.ts +0 -316
- package/src/network-runtime/local-control-contract.ts +0 -784
- package/src/network-runtime/node-store-contract.ts +0 -46
- package/src/network-runtime/pair-route-contract.ts +0 -97
- package/src/network-runtime/peer-capabilities.ts +0 -48
- package/src/network-runtime/peer-principal-ref.ts +0 -20
- package/src/network-runtime/peer-state-machine.ts +0 -160
- package/src/network-runtime/protocol-schemas.ts +0 -265
- package/src/network-runtime/runtime-bootstrap-contract.ts +0 -83
- package/src/outlook/desktop-session.ts +0 -409
- package/src/policy.ts +0 -171
- package/src/providers/brave.ts +0 -80
- package/src/providers/duckduckgo.ts +0 -199
- package/src/providers/exa.ts +0 -85
- package/src/providers/firecrawl.ts +0 -77
- package/src/providers/index.ts +0 -8
- package/src/providers/jina.ts +0 -70
- package/src/providers/router.ts +0 -121
- package/src/providers/search-provider.ts +0 -74
- package/src/providers/tavily.ts +0 -74
- package/src/quip/desktop-session.ts +0 -435
- package/src/registry/index.ts +0 -1
- package/src/registry/registry.ts +0 -905
- package/src/runtime-socket-local-control-client.ts +0 -632
- package/src/security/dns-normalization.ts +0 -34
- package/src/security/dns-pinning.ts +0 -138
- package/src/security/external-content.ts +0 -129
- package/src/security/ssrf.ts +0 -207
- package/src/slack/desktop-session.ts +0 -493
- package/src/tool-factory.ts +0 -91
- package/src/types.ts +0 -1341
- package/src/utils/retry.ts +0 -163
- package/src/utils/safe-parse-json.ts +0 -176
- package/src/utils/url.ts +0 -20
- package/tests/benchmarks/registry.bench.ts +0 -57
- package/tests/cache/web-cache.test.ts +0 -147
- package/tests/critical-integration.test.ts +0 -1465
- package/tests/definitions/apply-patch.test.ts +0 -586
- package/tests/definitions/browser.test.ts +0 -495
- package/tests/definitions/delegation-pause-resume.test.ts +0 -758
- package/tests/definitions/execution.test.ts +0 -671
- package/tests/definitions/messaging-inbox-scope.test.ts +0 -229
- package/tests/definitions/messaging.test.ts +0 -1468
- package/tests/definitions/outlook.test.ts +0 -30
- package/tests/definitions/process.test.ts +0 -469
- package/tests/definitions/slack.test.ts +0 -28
- package/tests/definitions/tool-inventory.test.ts +0 -218
- package/tests/e2e/delegation-quest-orchestration.e2e.test.ts +0 -433
- package/tests/e2e/memory-tool-discovery-contract.e2e.test.ts +0 -81
- package/tests/executors/apply-patch.test.ts +0 -538
- package/tests/executors/arion.test.ts +0 -309
- package/tests/executors/conversation-primitives.test.ts +0 -250
- package/tests/executors/deploy.test.ts +0 -746
- package/tests/executors/filesystem-tools.test.ts +0 -357
- package/tests/executors/filesystem.test.ts +0 -959
- package/tests/executors/frg-freshness.test.ts +0 -136
- package/tests/executors/frg-merge.test.ts +0 -70
- package/tests/executors/frg-session-content.test.ts +0 -40
- package/tests/executors/frg.test.ts +0 -56
- package/tests/executors/memory-bugfixes.test.ts +0 -257
- package/tests/executors/memory-real-memoria.integration.test.ts +0 -316
- package/tests/executors/memory.test.ts +0 -853
- package/tests/executors/meta-tools.test.ts +0 -411
- package/tests/executors/meta.test.ts +0 -683
- package/tests/executors/path-containment.test.ts +0 -51
- package/tests/executors/process-registry.test.ts +0 -505
- package/tests/executors/pty.test.ts +0 -664
- package/tests/executors/quest-security.test.ts +0 -249
- package/tests/executors/read-file-media.test.ts +0 -230
- package/tests/executors/recall-knowledge-schema.test.ts +0 -209
- package/tests/executors/recall-tags.test.ts +0 -278
- package/tests/executors/remember-null-safety.contract.test.ts +0 -41
- package/tests/executors/restart.test.ts +0 -67
- package/tests/executors/search-unified.test.ts +0 -381
- package/tests/executors/session-history.test.ts +0 -340
- package/tests/executors/session-transcript.test.ts +0 -561
- package/tests/executors/shell-abort.test.ts +0 -416
- package/tests/executors/shell-env-blocklist.test.ts +0 -648
- package/tests/executors/shell-env-process.test.ts +0 -245
- package/tests/executors/shell-process-registry.test.ts +0 -334
- package/tests/executors/shell-tools.test.ts +0 -393
- package/tests/executors/shell.test.ts +0 -690
- package/tests/executors/web-abort-vs-timeout.test.ts +0 -213
- package/tests/executors/web-integration.test.ts +0 -633
- package/tests/executors/web-symlink.test.ts +0 -18
- package/tests/executors/web.test.ts +0 -1400
- package/tests/executors/write-stdin.test.ts +0 -145
- package/tests/extraction/content-extraction.test.ts +0 -153
- package/tests/guards/tools-default-test-lane.integration.test.ts +0 -21
- package/tests/guards/tools-package-test-commands.e2e.test.ts +0 -43
- package/tests/guards/tools-test-lane-manifest.contract.test.ts +0 -76
- package/tests/guards/tools-vitest-workspace-alias.contract.test.ts +0 -63
- package/tests/helpers/async-waits.ts +0 -53
- package/tests/integration/headless-control-contract.integration.test.ts +0 -153
- package/tests/integration/memory-tool-schema-parity.integration.test.ts +0 -67
- package/tests/integration/meta-tools-round-trip.integration.test.ts +0 -506
- package/tests/integration/quest-round-trip.test.ts +0 -303
- package/tests/integration/registry-executor-flow.test.ts +0 -85
- package/tests/integration.test.ts +0 -177
- package/tests/loading-tier.test.ts +0 -126
- package/tests/mcp/client-reconnect.test.ts +0 -267
- package/tests/mcp/connection.test.ts +0 -846
- package/tests/mcp/injectable-logger.test.ts +0 -83
- package/tests/mcp/jsonrpc.test.ts +0 -109
- package/tests/mcp/lifecycle.test.ts +0 -879
- package/tests/network-runtime/address-types.contract.test.ts +0 -143
- package/tests/network-runtime/continuity-bind-schema.contract.test.ts +0 -203
- package/tests/network-runtime/local-control-contract.test.ts +0 -869
- package/tests/network-runtime/local-control-invite-token.contract.test.ts +0 -146
- package/tests/network-runtime/node-store-contract.test.ts +0 -11
- package/tests/network-runtime/pair-protocol-nodeid.contract.test.ts +0 -15
- package/tests/network-runtime/peer-state-machine.contract.test.ts +0 -148
- package/tests/network-runtime/protocol-schemas.contract.test.ts +0 -512
- package/tests/network-runtime/relay-pending-nodeid.contract.test.ts +0 -62
- package/tests/network-runtime/runtime-bootstrap-contract.test.ts +0 -227
- package/tests/network-runtime/runtime-socket-local-control-client.test.ts +0 -621
- package/tests/network-runtime/wait-for-message-script.test.ts +0 -288
- package/tests/parallel.test.ts +0 -71
- package/tests/policy.test.ts +0 -184
- package/tests/print-default-test-lane.ts +0 -14
- package/tests/print-test-lane-manifest.ts +0 -22
- package/tests/providers/brave.test.ts +0 -159
- package/tests/providers/duckduckgo.test.ts +0 -207
- package/tests/providers/exa.test.ts +0 -175
- package/tests/providers/firecrawl.test.ts +0 -168
- package/tests/providers/jina.test.ts +0 -144
- package/tests/providers/router.test.ts +0 -328
- package/tests/providers/tavily.test.ts +0 -165
- package/tests/registry/discovery.test.ts +0 -154
- package/tests/registry/injectable-logger.test.ts +0 -230
- package/tests/registry/input-validation.test.ts +0 -361
- package/tests/registry/interface-completeness.test.ts +0 -85
- package/tests/registry/mcp-integration.test.ts +0 -103
- package/tests/registry/mcp-read-only-hint.test.ts +0 -60
- package/tests/registry/memoria-discovery.test.ts +0 -390
- package/tests/registry/nested-validation.test.ts +0 -283
- package/tests/registry/pseudo-tool-filtering.test.ts +0 -258
- package/tests/registry/registration-lifecycle.test.ts +0 -133
- package/tests/registry-validation.test.ts +0 -424
- package/tests/registry.test.ts +0 -460
- package/tests/security/dns-pinning.test.ts +0 -162
- package/tests/security/external-content.test.ts +0 -144
- package/tests/security/ssrf.test.ts +0 -118
- package/tests/shell-safety-integration.test.ts +0 -32
- package/tests/shell-safety.test.ts +0 -365
- package/tests/slack/desktop-session.test.ts +0 -50
- package/tests/test-lane-manifest.ts +0 -440
- package/tests/test-utils.ts +0 -27
- package/tests/tool-factory.test.ts +0 -188
- package/tests/utils/retry.test.ts +0 -231
- package/tests/utils/url.test.ts +0 -63
- package/tsconfig.cjs.json +0 -24
- package/tsconfig.json +0 -12
- package/vitest.config.ts +0 -55
- package/vitest.e2e.config.ts +0 -24
- package/vitest.integration.config.ts +0 -24
- package/vitest.native.config.ts +0 -24
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { MCPClient } from "../../src/mcp/client.js";
|
|
3
|
-
import type { MCPServerConfig } from "../../src/mcp/types.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Tests for MCPClient reconnect race conditions.
|
|
7
|
-
*
|
|
8
|
-
* aria-rfu.10: disconnect() during a pending reconnect timer did not cancel
|
|
9
|
-
* the timer, so reconnect would fire after disconnect and create a zombie
|
|
10
|
-
* connection.
|
|
11
|
-
*
|
|
12
|
-
* aria-288: Two rapid process exits trigger two reconnect() calls that race.
|
|
13
|
-
* The second connect() throws 'already connected' because the first reconnect
|
|
14
|
-
* already re-established the connection. Fixed with a servers.has() guard.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
// We mock MCPServerConnection so we don't spawn real child processes.
|
|
18
|
-
vi.mock("../../src/mcp/connection.js", () => {
|
|
19
|
-
const { EventEmitter } = require("events");
|
|
20
|
-
|
|
21
|
-
class MockMCPServerConnection extends EventEmitter {
|
|
22
|
-
config: MCPServerConfig;
|
|
23
|
-
_initialized = false;
|
|
24
|
-
|
|
25
|
-
constructor(config: MCPServerConfig) {
|
|
26
|
-
super();
|
|
27
|
-
this.config = config;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
get name() {
|
|
31
|
-
return this.config.name;
|
|
32
|
-
}
|
|
33
|
-
get initialized() {
|
|
34
|
-
return this._initialized;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async initialize() {
|
|
38
|
-
this._initialized = true;
|
|
39
|
-
return {};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async shutdown() {
|
|
43
|
-
this._initialized = false;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async listTools() {
|
|
47
|
-
return [];
|
|
48
|
-
}
|
|
49
|
-
async listResources() {
|
|
50
|
-
return [];
|
|
51
|
-
}
|
|
52
|
-
async listPrompts() {
|
|
53
|
-
return [];
|
|
54
|
-
}
|
|
55
|
-
async callTool(_name: string, _args: unknown) {
|
|
56
|
-
return { success: true, message: "mock result" };
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return { MCPServerConnection: MockMCPServerConnection };
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
describe("MCPClient reconnect race condition", () => {
|
|
64
|
-
let client: MCPClient;
|
|
65
|
-
const config: MCPServerConfig = {
|
|
66
|
-
name: "test-server",
|
|
67
|
-
command: "node",
|
|
68
|
-
args: ["fake-server.js"],
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
beforeEach(() => {
|
|
72
|
-
vi.useFakeTimers();
|
|
73
|
-
client = new MCPClient();
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
afterEach(() => {
|
|
77
|
-
vi.useRealTimers();
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it("disconnect() during pending reconnect cancels the reconnect", async () => {
|
|
81
|
-
// Connect normally
|
|
82
|
-
const conn = await client.connect(config);
|
|
83
|
-
expect(client.getConnectedServers()).toContain("test-server");
|
|
84
|
-
|
|
85
|
-
// Simulate an unexpected exit (non-zero code) to trigger auto-reconnect
|
|
86
|
-
conn.emit("exit", 1);
|
|
87
|
-
|
|
88
|
-
// At this point, reconnect() has been called and is awaiting its setTimeout.
|
|
89
|
-
// The server entry was already removed by the exit handler.
|
|
90
|
-
expect(client.getConnectedServers()).not.toContain("test-server");
|
|
91
|
-
|
|
92
|
-
// Now disconnect while the reconnect timer is pending
|
|
93
|
-
await client.disconnect("test-server");
|
|
94
|
-
|
|
95
|
-
// Advance time past the reconnect delay (1s for attempt 0)
|
|
96
|
-
await vi.advanceTimersByTimeAsync(2000);
|
|
97
|
-
|
|
98
|
-
// After advancing, reconnect should NOT have re-created the connection
|
|
99
|
-
expect(client.getConnectedServers()).not.toContain("test-server");
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it("reconnect after disconnect does not create zombie connection", async () => {
|
|
103
|
-
// Connect, then trigger an unexpected exit
|
|
104
|
-
const conn = await client.connect(config);
|
|
105
|
-
conn.emit("exit", 1);
|
|
106
|
-
|
|
107
|
-
// Disconnect the server (should cancel pending reconnect)
|
|
108
|
-
await client.disconnect("test-server");
|
|
109
|
-
|
|
110
|
-
// Spy on connect to verify it is NOT called
|
|
111
|
-
const connectSpy = vi.spyOn(client, "connect");
|
|
112
|
-
|
|
113
|
-
// Advance timers well past all 3 retry attempts (1s + 2s + 4s = 7s)
|
|
114
|
-
await vi.advanceTimersByTimeAsync(10000);
|
|
115
|
-
|
|
116
|
-
// connect should not have been called — reconnect was cancelled
|
|
117
|
-
expect(connectSpy).not.toHaveBeenCalled();
|
|
118
|
-
expect(client.getConnectedServers()).toHaveLength(0);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it("reconnect proceeds normally when disconnect is not called", async () => {
|
|
122
|
-
const conn = await client.connect(config);
|
|
123
|
-
conn.emit("exit", 1);
|
|
124
|
-
|
|
125
|
-
// Do NOT disconnect — let reconnect run
|
|
126
|
-
|
|
127
|
-
// Advance past the 1s delay for attempt 0
|
|
128
|
-
await vi.advanceTimersByTimeAsync(1100);
|
|
129
|
-
|
|
130
|
-
// Reconnect should have re-established the connection
|
|
131
|
-
expect(client.getConnectedServers()).toContain("test-server");
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it("disconnectAll cancels all pending reconnects", async () => {
|
|
135
|
-
// Connect two servers
|
|
136
|
-
const config2: MCPServerConfig = {
|
|
137
|
-
name: "test-server-2",
|
|
138
|
-
command: "node",
|
|
139
|
-
args: ["fake-server-2.js"],
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const conn1 = await client.connect(config);
|
|
143
|
-
const conn2 = await client.connect(config2);
|
|
144
|
-
|
|
145
|
-
// Trigger unexpected exits on both
|
|
146
|
-
conn1.emit("exit", 1);
|
|
147
|
-
conn2.emit("exit", 1);
|
|
148
|
-
|
|
149
|
-
// disconnectAll should cancel both pending reconnects
|
|
150
|
-
await client.disconnectAll();
|
|
151
|
-
|
|
152
|
-
// Advance past all retry delays
|
|
153
|
-
await vi.advanceTimersByTimeAsync(10000);
|
|
154
|
-
|
|
155
|
-
// Neither should have reconnected
|
|
156
|
-
expect(client.getConnectedServers()).toHaveLength(0);
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* aria-288: Double-reconnect race condition.
|
|
162
|
-
*
|
|
163
|
-
* When a server process exits twice in quick succession (e.g. the process
|
|
164
|
-
* emits two 'exit' events, or the exit handler fires while a reconnect is
|
|
165
|
-
* already in-flight), two reconnect() calls race. Without the servers.has()
|
|
166
|
-
* guard, the second one calls connect() which throws 'already connected'.
|
|
167
|
-
*/
|
|
168
|
-
describe("MCPClient double-reconnect race (aria-288)", () => {
|
|
169
|
-
let client: MCPClient;
|
|
170
|
-
const config: MCPServerConfig = {
|
|
171
|
-
name: "race-server",
|
|
172
|
-
command: "node",
|
|
173
|
-
args: ["fake-server.js"],
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
beforeEach(() => {
|
|
177
|
-
vi.useFakeTimers();
|
|
178
|
-
client = new MCPClient();
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
afterEach(async () => {
|
|
182
|
-
await client.disconnectAll();
|
|
183
|
-
vi.useRealTimers();
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
it("two rapid exit events do not cause 'already connected' error", async () => {
|
|
187
|
-
// Connect normally
|
|
188
|
-
const conn = await client.connect(config);
|
|
189
|
-
expect(client.getConnectedServers()).toContain("race-server");
|
|
190
|
-
|
|
191
|
-
// Simulate two rapid exit events — this is the core race scenario.
|
|
192
|
-
// The first exit removes the server from the map and queues a reconnect.
|
|
193
|
-
// The second exit fires while the first reconnect timer is still pending.
|
|
194
|
-
conn.emit("exit", 1);
|
|
195
|
-
conn.emit("exit", 1);
|
|
196
|
-
|
|
197
|
-
// Both reconnect() calls are now awaiting their setTimeout timers.
|
|
198
|
-
// The server should be removed from the connected list.
|
|
199
|
-
expect(client.getConnectedServers()).not.toContain("race-server");
|
|
200
|
-
|
|
201
|
-
// Advance time past the 1s delay for attempt 0. Both reconnects fire.
|
|
202
|
-
// Without the fix, the second would throw 'Server already connected'.
|
|
203
|
-
// With the fix, the second sees servers.has() is true and skips.
|
|
204
|
-
await vi.advanceTimersByTimeAsync(1100);
|
|
205
|
-
|
|
206
|
-
// Exactly one connection should exist — no error, no duplicate.
|
|
207
|
-
expect(client.getConnectedServers()).toContain("race-server");
|
|
208
|
-
expect(client.getConnectedServers()).toHaveLength(1);
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
it("second reconnect is a no-op when first reconnect succeeds", async () => {
|
|
212
|
-
const conn = await client.connect(config);
|
|
213
|
-
|
|
214
|
-
// Spy on connect to count calls
|
|
215
|
-
const connectSpy = vi.spyOn(client, "connect");
|
|
216
|
-
|
|
217
|
-
// Trigger two rapid exits
|
|
218
|
-
conn.emit("exit", 1);
|
|
219
|
-
conn.emit("exit", 1);
|
|
220
|
-
|
|
221
|
-
// Advance past the first reconnect delay
|
|
222
|
-
await vi.advanceTimersByTimeAsync(1100);
|
|
223
|
-
|
|
224
|
-
// connect() should have been called exactly once (by the first reconnect).
|
|
225
|
-
// The second reconnect should have bailed out via the servers.has() guard.
|
|
226
|
-
expect(connectSpy).toHaveBeenCalledTimes(1);
|
|
227
|
-
expect(client.getConnectedServers()).toContain("race-server");
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
it("reconnected server is functional after double-exit race", async () => {
|
|
231
|
-
const conn = await client.connect(config);
|
|
232
|
-
|
|
233
|
-
// Trigger the race
|
|
234
|
-
conn.emit("exit", 1);
|
|
235
|
-
conn.emit("exit", 1);
|
|
236
|
-
|
|
237
|
-
// Let reconnect complete
|
|
238
|
-
await vi.advanceTimersByTimeAsync(1100);
|
|
239
|
-
|
|
240
|
-
// The reconnected server should be usable — listAllTools should not throw.
|
|
241
|
-
const tools = await client.listAllTools();
|
|
242
|
-
expect(tools).toEqual([]);
|
|
243
|
-
|
|
244
|
-
// callTool should also work (returns success:false for missing tool,
|
|
245
|
-
// but the important thing is it doesn't throw 'Server not connected').
|
|
246
|
-
const result = await client.callTool("race-server", "some_tool", {});
|
|
247
|
-
// The mock connection doesn't support callTool, so it won't throw
|
|
248
|
-
// 'Server not connected' which would indicate the connection is broken.
|
|
249
|
-
expect(result).toBeDefined();
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
it("three rapid exits still result in exactly one connection", async () => {
|
|
253
|
-
const conn = await client.connect(config);
|
|
254
|
-
|
|
255
|
-
// Extreme case: three exits in quick succession
|
|
256
|
-
conn.emit("exit", 1);
|
|
257
|
-
conn.emit("exit", 1);
|
|
258
|
-
conn.emit("exit", 1);
|
|
259
|
-
|
|
260
|
-
// Advance past all reconnect timers
|
|
261
|
-
await vi.advanceTimersByTimeAsync(1100);
|
|
262
|
-
|
|
263
|
-
// Should still have exactly one connection
|
|
264
|
-
expect(client.getConnectedServers()).toHaveLength(1);
|
|
265
|
-
expect(client.getConnectedServers()).toContain("race-server");
|
|
266
|
-
});
|
|
267
|
-
});
|