sofia-cli 0.1.1 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -20
- package/dist/infra/deploy.sh +193 -0
- package/dist/infra/gather-env.sh +211 -0
- package/dist/infra/infra/deploy.sh +193 -0
- package/dist/infra/infra/gather-env.sh +211 -0
- package/dist/infra/infra/main.bicep +90 -0
- package/dist/infra/infra/main.bicepparam +18 -0
- package/dist/infra/infra/resources.bicep +134 -0
- package/dist/infra/infra/teardown.sh +114 -0
- package/dist/infra/main.bicep +90 -0
- package/dist/infra/main.bicepparam +18 -0
- package/dist/infra/resources.bicep +134 -0
- package/dist/infra/teardown.sh +114 -0
- package/dist/src/cli/developCommand.js +0 -2
- package/dist/src/cli/index.js +8 -1
- package/dist/src/cli/workshopCommand.js +1 -1
- package/dist/src/develop/index.js +1 -1
- package/dist/src/develop/pocUtils.js +228 -0
- package/dist/src/develop/ralphLoop.js +3 -3
- package/dist/src/shared/data/cards.json +655 -670
- package/docs/architecture.md +2 -1
- package/package.json +5 -3
- package/src/cli/developCommand.ts +1 -3
- package/src/cli/index.ts +11 -1
- package/src/cli/workshopCommand.ts +21 -17
- package/src/develop/dynamicScaffolder.ts +36 -30
- package/src/develop/index.ts +13 -2
- package/src/develop/pocUtils.ts +296 -0
- package/src/develop/ralphLoop.ts +8 -28
- package/src/develop/templateRegistry.ts +19 -18
- package/src/shared/data/cards.json +655 -670
- package/tests/e2e/developE2e.spec.ts +3 -61
- package/tests/e2e/developFailureE2e.spec.ts +34 -38
- package/tests/integration/pocGithubMcp.spec.ts +29 -39
- package/tests/integration/pocLocalFallback.spec.ts +29 -39
- package/tests/integration/ralphLoopFlow.spec.ts +46 -66
- package/tests/integration/ralphLoopPartial.spec.ts +30 -37
- package/tests/unit/develop/githubMcpAdapter.spec.ts +0 -134
- package/tests/unit/develop/outputValidator.spec.ts +45 -21
- package/tests/unit/develop/ralphLoop.spec.ts +58 -94
- package/tsconfig.json +2 -1
- package/vitest.workspace.ts +5 -0
- package/dist/src/develop/pocScaffolder.js +0 -542
- package/dist/tests/e2e/developE2e.spec.js +0 -126
- package/dist/tests/e2e/developFailureE2e.spec.js +0 -247
- package/dist/tests/e2e/developPty.spec.js +0 -75
- package/dist/tests/e2e/discoveryWebSearchRelevance.spec.js +0 -84
- package/dist/tests/e2e/harness.spec.js +0 -83
- package/dist/tests/e2e/mcpLive.spec.js +0 -120
- package/dist/tests/e2e/newSession.e2e.spec.js +0 -177
- package/dist/tests/e2e/ralphLoopEnrichmentComparison.spec.js +0 -62
- package/dist/tests/e2e/workiqEnrichment.spec.js +0 -56
- package/dist/tests/e2e/zavaSimulation.spec.js +0 -452
- package/dist/tests/fixtures/test-fixture-project/src/add.js +0 -3
- package/dist/tests/fixtures/test-fixture-project/tests/failing.test.js +0 -6
- package/dist/tests/fixtures/test-fixture-project/tests/hanging.test.js +0 -8
- package/dist/tests/fixtures/test-fixture-project/tests/passing.test.js +0 -10
- package/dist/tests/fixtures/test-fixture-project/vitest.config.js +0 -6
- package/dist/tests/integration/autoStartConversation.spec.js +0 -138
- package/dist/tests/integration/defaultCommand.spec.js +0 -147
- package/dist/tests/integration/directCommandNonTty.spec.js +0 -224
- package/dist/tests/integration/directCommandTty.spec.js +0 -151
- package/dist/tests/integration/discoveryEnrichmentFlow.spec.js +0 -175
- package/dist/tests/integration/exportArtifacts.spec.js +0 -202
- package/dist/tests/integration/exportFallbackFlow.spec.js +0 -99
- package/dist/tests/integration/mcpDegradationFlow.spec.js +0 -190
- package/dist/tests/integration/mcpTransportFlow.spec.js +0 -139
- package/dist/tests/integration/newSessionFlow.spec.js +0 -343
- package/dist/tests/integration/pocGithubMcp.spec.js +0 -186
- package/dist/tests/integration/pocLocalFallback.spec.js +0 -171
- package/dist/tests/integration/pocScaffold.spec.js +0 -163
- package/dist/tests/integration/ralphLoopFlow.spec.js +0 -359
- package/dist/tests/integration/ralphLoopPartial.spec.js +0 -368
- package/dist/tests/integration/resumeAndBacktrack.spec.js +0 -247
- package/dist/tests/integration/spinnerLifecycle.spec.js +0 -220
- package/dist/tests/integration/summarizationFlow.spec.js +0 -115
- package/dist/tests/integration/testRunnerReal.spec.js +0 -52
- package/dist/tests/integration/webSearchAgent.spec.js +0 -128
- package/dist/tests/live/copilotSdkLive.spec.js +0 -107
- package/dist/tests/live/zavaFullWorkshop.spec.js +0 -392
- package/dist/tests/setup/loadEnv.js +0 -3
- package/dist/tests/unit/cli/developCommand.spec.js +0 -567
- package/dist/tests/unit/cli/directCommands.spec.js +0 -279
- package/dist/tests/unit/cli/envLoader.spec.js +0 -58
- package/dist/tests/unit/cli/ioContext.spec.js +0 -119
- package/dist/tests/unit/cli/preflight.spec.js +0 -108
- package/dist/tests/unit/cli/statusCommand.spec.js +0 -111
- package/dist/tests/unit/cli/workshopClientFallback.spec.js +0 -80
- package/dist/tests/unit/cli/workshopCommand.spec.js +0 -329
- package/dist/tests/unit/config/vitestEnvSetup.spec.js +0 -13
- package/dist/tests/unit/develop/checkpointState.spec.js +0 -315
- package/dist/tests/unit/develop/codeGenerator.spec.js +0 -355
- package/dist/tests/unit/develop/githubMcpAdapter.spec.js +0 -231
- package/dist/tests/unit/develop/mcpContextEnricher.spec.js +0 -433
- package/dist/tests/unit/develop/outputValidator.spec.js +0 -119
- package/dist/tests/unit/develop/pocScaffolder.spec.js +0 -353
- package/dist/tests/unit/develop/ralphLoop.spec.js +0 -1248
- package/dist/tests/unit/develop/templateRegistry.spec.js +0 -85
- package/dist/tests/unit/develop/testRunner.spec.js +0 -249
- package/dist/tests/unit/infraBicep.spec.js +0 -92
- package/dist/tests/unit/infraDeploy.spec.js +0 -82
- package/dist/tests/unit/infraTeardown.spec.js +0 -63
- package/dist/tests/unit/logging/logger.spec.js +0 -43
- package/dist/tests/unit/loop/conversationLoop.spec.js +0 -592
- package/dist/tests/unit/loop/phaseSummarizer.spec.js +0 -141
- package/dist/tests/unit/loop/streamingMarkdown.spec.js +0 -147
- package/dist/tests/unit/mcp/mcpManager.spec.js +0 -279
- package/dist/tests/unit/mcp/mcpTransport.spec.js +0 -529
- package/dist/tests/unit/mcp/retryPolicy.spec.js +0 -218
- package/dist/tests/unit/mcp/timeoutValidation.spec.js +0 -46
- package/dist/tests/unit/mcp/webSearch.spec.js +0 -567
- package/dist/tests/unit/phases/contextSummarizer.spec.js +0 -140
- package/dist/tests/unit/phases/discoveryEnricher.repeatCalls.spec.js +0 -93
- package/dist/tests/unit/phases/discoveryEnricher.spec.js +0 -411
- package/dist/tests/unit/phases/phaseExtractors.spec.js +0 -352
- package/dist/tests/unit/phases/phaseHandlers.spec.js +0 -425
- package/dist/tests/unit/prompts/promptLoader.spec.js +0 -118
- package/dist/tests/unit/schemas/pocSchemas.spec.js +0 -412
- package/dist/tests/unit/schemas/session.spec.js +0 -257
- package/dist/tests/unit/sessions/exportPaths.spec.js +0 -31
- package/dist/tests/unit/sessions/exportWriter.spec.js +0 -655
- package/dist/tests/unit/sessions/sessionManager.spec.js +0 -151
- package/dist/tests/unit/sessions/sessionStore.spec.js +0 -116
- package/dist/tests/unit/shared/activitySpinner.spec.js +0 -175
- package/dist/tests/unit/shared/cardsLoader.spec.js +0 -76
- package/dist/tests/unit/shared/copilotClient.spec.js +0 -155
- package/dist/tests/unit/shared/errorClassifier.spec.js +0 -131
- package/dist/tests/unit/shared/events.spec.js +0 -55
- package/dist/tests/unit/shared/markdownRenderer.spec.js +0 -35
- package/dist/tests/unit/shared/markdownRendererChunks.spec.js +0 -70
- package/dist/tests/unit/shared/tableRenderer.spec.js +0 -34
- package/dist/vitest.config.js +0 -14
- package/dist/vitest.live.config.js +0 -18
- package/src/develop/pocScaffolder.ts +0 -646
- package/tests/integration/pocScaffold.spec.ts +0 -220
- package/tests/unit/develop/pocScaffolder.spec.ts +0 -451
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* T006: Unit tests for retryPolicy.
|
|
3
|
-
*
|
|
4
|
-
* Verifies:
|
|
5
|
-
* - withRetry retries once on connection-refused
|
|
6
|
-
* - withRetry retries once on timeout
|
|
7
|
-
* - withRetry does NOT retry on auth-failure
|
|
8
|
-
* - withRetry does NOT retry on unknown error
|
|
9
|
-
* - Applies ±20% jitter to initial delay
|
|
10
|
-
* - Logs warn on retry attempt
|
|
11
|
-
*/
|
|
12
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
13
|
-
import { withRetry, isRetryable, classifyMcpError } from '../../../src/mcp/retryPolicy.js';
|
|
14
|
-
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
15
|
-
function makeLogger() {
|
|
16
|
-
return {
|
|
17
|
-
info: vi.fn(),
|
|
18
|
-
warn: vi.fn(),
|
|
19
|
-
error: vi.fn(),
|
|
20
|
-
debug: vi.fn(),
|
|
21
|
-
trace: vi.fn(),
|
|
22
|
-
fatal: vi.fn(),
|
|
23
|
-
child: vi.fn().mockReturnThis(),
|
|
24
|
-
level: 'silent',
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
function makeConnRefusedError() {
|
|
28
|
-
const err = new Error('connect ECONNREFUSED 127.0.0.1:3000');
|
|
29
|
-
err.code = 'ECONNREFUSED';
|
|
30
|
-
return err;
|
|
31
|
-
}
|
|
32
|
-
function makeTimeoutError() {
|
|
33
|
-
const err = new Error('connect ETIMEDOUT');
|
|
34
|
-
err.code = 'ETIMEDOUT';
|
|
35
|
-
return err;
|
|
36
|
-
}
|
|
37
|
-
function makeDnsError() {
|
|
38
|
-
const err = new Error('getaddrinfo ENOTFOUND example.com');
|
|
39
|
-
err.code = 'ENOTFOUND';
|
|
40
|
-
return err;
|
|
41
|
-
}
|
|
42
|
-
function makeAuthError() {
|
|
43
|
-
const err = new Error('401 Unauthorized');
|
|
44
|
-
err.code = 'ERR_TLS_CERT_ALTNAME_INVALID';
|
|
45
|
-
return err;
|
|
46
|
-
}
|
|
47
|
-
// ── Tests ────────────────────────────────────────────────────────────────────
|
|
48
|
-
describe('withRetry()', () => {
|
|
49
|
-
beforeEach(() => {
|
|
50
|
-
vi.useFakeTimers();
|
|
51
|
-
});
|
|
52
|
-
afterEach(() => {
|
|
53
|
-
vi.useRealTimers();
|
|
54
|
-
});
|
|
55
|
-
it('returns result when fn succeeds on first try', async () => {
|
|
56
|
-
const fn = vi.fn().mockResolvedValue('success');
|
|
57
|
-
const result = await withRetry(fn, {
|
|
58
|
-
serverName: 'test',
|
|
59
|
-
toolName: 'tool',
|
|
60
|
-
});
|
|
61
|
-
expect(result).toBe('success');
|
|
62
|
-
expect(fn).toHaveBeenCalledTimes(1);
|
|
63
|
-
});
|
|
64
|
-
it('retries once on connection-refused and succeeds', async () => {
|
|
65
|
-
const fn = vi
|
|
66
|
-
.fn()
|
|
67
|
-
.mockRejectedValueOnce(makeConnRefusedError())
|
|
68
|
-
.mockResolvedValueOnce('recovered');
|
|
69
|
-
const logger = makeLogger();
|
|
70
|
-
const resultPromise = withRetry(fn, {
|
|
71
|
-
serverName: 'ctx7',
|
|
72
|
-
toolName: 'resolve',
|
|
73
|
-
initialDelayMs: 100,
|
|
74
|
-
logger,
|
|
75
|
-
});
|
|
76
|
-
// Advance past the delay
|
|
77
|
-
await vi.advanceTimersByTimeAsync(200);
|
|
78
|
-
const result = await resultPromise;
|
|
79
|
-
expect(result).toBe('recovered');
|
|
80
|
-
expect(fn).toHaveBeenCalledTimes(2);
|
|
81
|
-
});
|
|
82
|
-
it('retries once on timeout and succeeds', async () => {
|
|
83
|
-
const fn = vi.fn().mockRejectedValueOnce(makeTimeoutError()).mockResolvedValueOnce('ok');
|
|
84
|
-
const resultPromise = withRetry(fn, {
|
|
85
|
-
serverName: 'github',
|
|
86
|
-
toolName: 'create_repo',
|
|
87
|
-
initialDelayMs: 100,
|
|
88
|
-
});
|
|
89
|
-
await vi.advanceTimersByTimeAsync(200);
|
|
90
|
-
const result = await resultPromise;
|
|
91
|
-
expect(result).toBe('ok');
|
|
92
|
-
expect(fn).toHaveBeenCalledTimes(2);
|
|
93
|
-
});
|
|
94
|
-
it('retries once on dns-failure and succeeds', async () => {
|
|
95
|
-
const fn = vi.fn().mockRejectedValueOnce(makeDnsError()).mockResolvedValueOnce('resolved');
|
|
96
|
-
const resultPromise = withRetry(fn, {
|
|
97
|
-
serverName: 'remote',
|
|
98
|
-
toolName: 'call',
|
|
99
|
-
initialDelayMs: 100,
|
|
100
|
-
});
|
|
101
|
-
await vi.advanceTimersByTimeAsync(200);
|
|
102
|
-
const result = await resultPromise;
|
|
103
|
-
expect(result).toBe('resolved');
|
|
104
|
-
expect(fn).toHaveBeenCalledTimes(2);
|
|
105
|
-
});
|
|
106
|
-
it('does NOT retry on auth-failure — throws immediately', async () => {
|
|
107
|
-
const fn = vi.fn().mockRejectedValue(makeAuthError());
|
|
108
|
-
await expect(withRetry(fn, {
|
|
109
|
-
serverName: 'github',
|
|
110
|
-
toolName: 'create_repo',
|
|
111
|
-
initialDelayMs: 100,
|
|
112
|
-
})).rejects.toThrow('401 Unauthorized');
|
|
113
|
-
expect(fn).toHaveBeenCalledTimes(1);
|
|
114
|
-
});
|
|
115
|
-
it('does NOT retry on unknown error — throws immediately', async () => {
|
|
116
|
-
const fn = vi.fn().mockRejectedValue(new Error('something unexpected'));
|
|
117
|
-
await expect(withRetry(fn, {
|
|
118
|
-
serverName: 'test',
|
|
119
|
-
toolName: 'tool',
|
|
120
|
-
initialDelayMs: 100,
|
|
121
|
-
})).rejects.toThrow('something unexpected');
|
|
122
|
-
expect(fn).toHaveBeenCalledTimes(1);
|
|
123
|
-
});
|
|
124
|
-
it('throws the second error when retry also fails', async () => {
|
|
125
|
-
const fn = vi
|
|
126
|
-
.fn()
|
|
127
|
-
.mockRejectedValueOnce(makeConnRefusedError())
|
|
128
|
-
.mockRejectedValueOnce(new Error('second failure'));
|
|
129
|
-
// Attach the rejection handler immediately to avoid unhandled rejection warning
|
|
130
|
-
const resultPromise = withRetry(fn, {
|
|
131
|
-
serverName: 'test',
|
|
132
|
-
toolName: 'tool',
|
|
133
|
-
initialDelayMs: 100,
|
|
134
|
-
}).catch((err) => err);
|
|
135
|
-
await vi.advanceTimersByTimeAsync(200);
|
|
136
|
-
const err = await resultPromise;
|
|
137
|
-
expect(err).toBeInstanceOf(Error);
|
|
138
|
-
expect(err.message).toBe('second failure');
|
|
139
|
-
expect(fn).toHaveBeenCalledTimes(2);
|
|
140
|
-
});
|
|
141
|
-
it('logs warn on retry attempt with server, tool, attempt, delayMs, errorClass', async () => {
|
|
142
|
-
const fn = vi.fn().mockRejectedValueOnce(makeConnRefusedError()).mockResolvedValueOnce('ok');
|
|
143
|
-
const logger = makeLogger();
|
|
144
|
-
const resultPromise = withRetry(fn, {
|
|
145
|
-
serverName: 'context7',
|
|
146
|
-
toolName: 'resolve-library-id',
|
|
147
|
-
initialDelayMs: 1000,
|
|
148
|
-
logger,
|
|
149
|
-
});
|
|
150
|
-
await vi.advanceTimersByTimeAsync(1500);
|
|
151
|
-
await resultPromise;
|
|
152
|
-
expect(logger.warn).toHaveBeenCalledTimes(1);
|
|
153
|
-
const warnCall = logger.warn.mock.calls[0];
|
|
154
|
-
const logObj = warnCall[0];
|
|
155
|
-
expect(logObj).toHaveProperty('server', 'context7');
|
|
156
|
-
expect(logObj).toHaveProperty('tool', 'resolve-library-id');
|
|
157
|
-
expect(logObj).toHaveProperty('attempt', 1);
|
|
158
|
-
expect(logObj).toHaveProperty('delayMs');
|
|
159
|
-
expect(logObj).toHaveProperty('errorClass', 'connection-refused');
|
|
160
|
-
});
|
|
161
|
-
it('applies ±20% jitter to delay', async () => {
|
|
162
|
-
// We'll override Math.random to test jitter boundaries
|
|
163
|
-
const originalRandom = Math.random;
|
|
164
|
-
// First test: random = 0 → jitter factor = 1 + (0*2-1)*0.2 = 0.8
|
|
165
|
-
Math.random = () => 0;
|
|
166
|
-
const fn1 = vi.fn().mockRejectedValueOnce(makeConnRefusedError()).mockResolvedValueOnce('ok');
|
|
167
|
-
const logger1 = makeLogger();
|
|
168
|
-
const p1 = withRetry(fn1, {
|
|
169
|
-
serverName: 'test',
|
|
170
|
-
toolName: 'tool',
|
|
171
|
-
initialDelayMs: 1000,
|
|
172
|
-
jitter: 0.2,
|
|
173
|
-
logger: logger1,
|
|
174
|
-
});
|
|
175
|
-
await vi.advanceTimersByTimeAsync(1500);
|
|
176
|
-
await p1;
|
|
177
|
-
const delay1 = logger1.warn.mock.calls[0][0].delayMs;
|
|
178
|
-
expect(delay1).toBe(800); // 1000 * 0.8
|
|
179
|
-
// Second test: random = 1 → jitter factor = 1 + (1*2-1)*0.2 = 1.2
|
|
180
|
-
Math.random = () => 1;
|
|
181
|
-
const fn2 = vi.fn().mockRejectedValueOnce(makeConnRefusedError()).mockResolvedValueOnce('ok');
|
|
182
|
-
const logger2 = makeLogger();
|
|
183
|
-
const p2 = withRetry(fn2, {
|
|
184
|
-
serverName: 'test',
|
|
185
|
-
toolName: 'tool',
|
|
186
|
-
initialDelayMs: 1000,
|
|
187
|
-
jitter: 0.2,
|
|
188
|
-
logger: logger2,
|
|
189
|
-
});
|
|
190
|
-
await vi.advanceTimersByTimeAsync(1500);
|
|
191
|
-
await p2;
|
|
192
|
-
const delay2 = logger2.warn.mock.calls[0][0].delayMs;
|
|
193
|
-
expect(delay2).toBe(1200); // 1000 * 1.2
|
|
194
|
-
Math.random = originalRandom;
|
|
195
|
-
});
|
|
196
|
-
});
|
|
197
|
-
describe('isRetryable()', () => {
|
|
198
|
-
it('returns true for connection-refused', () => {
|
|
199
|
-
expect(isRetryable(makeConnRefusedError())).toBe(true);
|
|
200
|
-
});
|
|
201
|
-
it('returns true for timeout', () => {
|
|
202
|
-
expect(isRetryable(makeTimeoutError())).toBe(true);
|
|
203
|
-
});
|
|
204
|
-
it('returns true for dns-failure', () => {
|
|
205
|
-
expect(isRetryable(makeDnsError())).toBe(true);
|
|
206
|
-
});
|
|
207
|
-
it('returns false for auth-failure', () => {
|
|
208
|
-
expect(isRetryable(makeAuthError())).toBe(false);
|
|
209
|
-
});
|
|
210
|
-
it('returns false for unknown error', () => {
|
|
211
|
-
expect(isRetryable(new Error('random'))).toBe(false);
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
describe('classifyMcpError (re-export)', () => {
|
|
215
|
-
it('classifies ECONNREFUSED as connection-refused', () => {
|
|
216
|
-
expect(classifyMcpError(makeConnRefusedError())).toBe('connection-refused');
|
|
217
|
-
});
|
|
218
|
-
});
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* T044: Timeout validation test for SC-003-007.
|
|
3
|
-
*
|
|
4
|
-
* Forces a short timeoutMs on MCP calls and asserts that a classified
|
|
5
|
-
* 'timeout' error is returned/thrown and handled gracefully by adapters.
|
|
6
|
-
*/
|
|
7
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
8
|
-
import { classifyMcpError } from '../../../src/mcp/mcpManager.js';
|
|
9
|
-
describe('Timeout validation (T044)', () => {
|
|
10
|
-
it('classifyMcpError identifies AbortError as timeout', () => {
|
|
11
|
-
const error = new DOMException('The operation was aborted', 'AbortError');
|
|
12
|
-
const classification = classifyMcpError(error);
|
|
13
|
-
expect(classification).toBe('timeout');
|
|
14
|
-
});
|
|
15
|
-
it('classifyMcpError identifies timeout message strings', () => {
|
|
16
|
-
const error = new Error('Request timed out after 30000ms');
|
|
17
|
-
const classification = classifyMcpError(error);
|
|
18
|
-
expect(classification).toBe('timeout');
|
|
19
|
-
});
|
|
20
|
-
it('classifyMcpError identifies ETIMEDOUT errno as timeout', () => {
|
|
21
|
-
const error = Object.assign(new Error('connect ETIMEDOUT'), { code: 'ETIMEDOUT' });
|
|
22
|
-
const classification = classifyMcpError(error);
|
|
23
|
-
expect(classification).toBe('timeout');
|
|
24
|
-
});
|
|
25
|
-
it('adapters handle timeout errors gracefully without crashing', async () => {
|
|
26
|
-
const { GitHubMcpAdapter } = await import('../../../src/develop/githubMcpAdapter.js');
|
|
27
|
-
const timeoutMcpManager = {
|
|
28
|
-
isAvailable: vi.fn().mockReturnValue(true),
|
|
29
|
-
callTool: vi
|
|
30
|
-
.fn()
|
|
31
|
-
.mockRejectedValue(new DOMException('The operation was aborted', 'AbortError')),
|
|
32
|
-
markConnected: vi.fn(),
|
|
33
|
-
markDisconnected: vi.fn(),
|
|
34
|
-
disconnectAll: vi.fn(),
|
|
35
|
-
};
|
|
36
|
-
const adapter = new GitHubMcpAdapter(timeoutMcpManager);
|
|
37
|
-
// createRepository should degrade gracefully
|
|
38
|
-
const repoResult = await adapter.createRepository({
|
|
39
|
-
name: 'test-repo',
|
|
40
|
-
description: 'test',
|
|
41
|
-
private: true,
|
|
42
|
-
});
|
|
43
|
-
// Should return a degraded result, not throw
|
|
44
|
-
expect(repoResult).toBeDefined();
|
|
45
|
-
});
|
|
46
|
-
});
|