@a5c-ai/adapters-harness-mock 5.1.1-staging.00ceebd28cf2

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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +227 -0
  3. package/dist/bin/adapters-harness-mock.d.ts +32 -0
  4. package/dist/bin/adapters-harness-mock.d.ts.map +1 -0
  5. package/dist/bin/adapters-harness-mock.js +155 -0
  6. package/dist/bin/adapters-harness-mock.js.map +1 -0
  7. package/dist/bin/mock-harness.d.ts +2 -0
  8. package/dist/bin/mock-harness.d.ts.map +1 -0
  9. package/dist/bin/mock-harness.js +25 -0
  10. package/dist/bin/mock-harness.js.map +1 -0
  11. package/dist/http-mock.d.ts +39 -0
  12. package/dist/http-mock.d.ts.map +1 -0
  13. package/dist/http-mock.js +206 -0
  14. package/dist/http-mock.js.map +1 -0
  15. package/dist/index.d.ts +9 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +10 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/mock-process.d.ts +57 -0
  20. package/dist/mock-process.d.ts.map +1 -0
  21. package/dist/mock-process.js +388 -0
  22. package/dist/mock-process.js.map +1 -0
  23. package/dist/mocks/index.d.ts +53 -0
  24. package/dist/mocks/index.d.ts.map +1 -0
  25. package/dist/mocks/index.js +140 -0
  26. package/dist/mocks/index.js.map +1 -0
  27. package/dist/mocks/mock-types.d.ts +170 -0
  28. package/dist/mocks/mock-types.d.ts.map +1 -0
  29. package/dist/mocks/mock-types.js +2 -0
  30. package/dist/mocks/mock-types.js.map +1 -0
  31. package/dist/mocks/programmatic-mocks.d.ts +40 -0
  32. package/dist/mocks/programmatic-mocks.d.ts.map +1 -0
  33. package/dist/mocks/programmatic-mocks.js +229 -0
  34. package/dist/mocks/programmatic-mocks.js.map +1 -0
  35. package/dist/mocks/remote-mocks.d.ts +43 -0
  36. package/dist/mocks/remote-mocks.d.ts.map +1 -0
  37. package/dist/mocks/remote-mocks.js +332 -0
  38. package/dist/mocks/remote-mocks.js.map +1 -0
  39. package/dist/mocks/scriptable-transport.d.ts +23 -0
  40. package/dist/mocks/scriptable-transport.d.ts.map +1 -0
  41. package/dist/mocks/scriptable-transport.js +83 -0
  42. package/dist/mocks/scriptable-transport.js.map +1 -0
  43. package/dist/multi-execution.d.ts +1 -0
  44. package/dist/multi-execution.d.ts.map +1 -0
  45. package/dist/multi-execution.js +2 -0
  46. package/dist/multi-execution.js.map +1 -0
  47. package/dist/probe.d.ts +113 -0
  48. package/dist/probe.d.ts.map +1 -0
  49. package/dist/probe.js +722 -0
  50. package/dist/probe.js.map +1 -0
  51. package/dist/scenarios/errors.d.ts +21 -0
  52. package/dist/scenarios/errors.d.ts.map +1 -0
  53. package/dist/scenarios/errors.js +73 -0
  54. package/dist/scenarios/errors.js.map +1 -0
  55. package/dist/scenarios/hooks.d.ts +17 -0
  56. package/dist/scenarios/hooks.d.ts.map +1 -0
  57. package/dist/scenarios/hooks.js +129 -0
  58. package/dist/scenarios/hooks.js.map +1 -0
  59. package/dist/scenarios/index.d.ts +22 -0
  60. package/dist/scenarios/index.d.ts.map +1 -0
  61. package/dist/scenarios/index.js +65 -0
  62. package/dist/scenarios/index.js.map +1 -0
  63. package/dist/scenarios/interactive.d.ts +17 -0
  64. package/dist/scenarios/interactive.d.ts.map +1 -0
  65. package/dist/scenarios/interactive.js +65 -0
  66. package/dist/scenarios/interactive.js.map +1 -0
  67. package/dist/scenarios/per-agent.d.ts +17 -0
  68. package/dist/scenarios/per-agent.d.ts.map +1 -0
  69. package/dist/scenarios/per-agent.js +597 -0
  70. package/dist/scenarios/per-agent.js.map +1 -0
  71. package/dist/scenarios/wire-format.d.ts +56 -0
  72. package/dist/scenarios/wire-format.d.ts.map +1 -0
  73. package/dist/scenarios/wire-format.js +261 -0
  74. package/dist/scenarios/wire-format.js.map +1 -0
  75. package/dist/scenarios.d.ts +29 -0
  76. package/dist/scenarios.d.ts.map +1 -0
  77. package/dist/scenarios.js +141 -0
  78. package/dist/scenarios.js.map +1 -0
  79. package/dist/types.d.ts +463 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +9 -0
  82. package/dist/types.js.map +1 -0
  83. package/dist/websocket-mock.d.ts +58 -0
  84. package/dist/websocket-mock.d.ts.map +1 -0
  85. package/dist/websocket-mock.js +367 -0
  86. package/dist/websocket-mock.js.map +1 -0
  87. package/dist/workspace.d.ts +52 -0
  88. package/dist/workspace.d.ts.map +1 -0
  89. package/dist/workspace.js +157 -0
  90. package/dist/workspace.js.map +1 -0
  91. package/package.json +71 -0
@@ -0,0 +1,367 @@
1
+ /**
2
+ * WebSocket server mock implementation for harness-mock.
3
+ */
4
+ import { EventEmitter } from 'node:events';
5
+ import WebSocket, { WebSocketServer } from 'ws';
6
+ let nextConnectionId = 1;
7
+ export class WebSocketServerMock extends EventEmitter {
8
+ scenario;
9
+ id;
10
+ _port;
11
+ _serverUrl;
12
+ _server = null;
13
+ _exited = false;
14
+ _isRunning = false;
15
+ _startTime = Date.now();
16
+ _fileChanges = [];
17
+ _messageHistory = [];
18
+ _connections = new Map();
19
+ _completedConnections = [];
20
+ _reconnectAllowedAt = null;
21
+ _reconnectTimer = null;
22
+ constructor(scenario, id) {
23
+ super();
24
+ this.scenario = scenario;
25
+ this.id = id;
26
+ this._port = scenario.websocketServer?.port ?? 8081;
27
+ const host = scenario.websocketServer?.host ?? '127.0.0.1';
28
+ this._serverUrl = `ws://${host}:${this._port}`;
29
+ }
30
+ get port() {
31
+ return this._port;
32
+ }
33
+ get serverUrl() {
34
+ return this._serverUrl;
35
+ }
36
+ get exited() {
37
+ return this._exited;
38
+ }
39
+ get fileChanges() {
40
+ return [...this._fileChanges];
41
+ }
42
+ get isRunning() {
43
+ return this._isRunning;
44
+ }
45
+ get connectionCount() {
46
+ return this._connections.size;
47
+ }
48
+ get messageHistory() {
49
+ return [...this._messageHistory];
50
+ }
51
+ async start() {
52
+ if (this._server || this._isRunning) {
53
+ throw new Error('WebSocket server already started');
54
+ }
55
+ const config = this.scenario.websocketServer;
56
+ if (config?.startupDelayMs) {
57
+ await new Promise((resolve) => setTimeout(resolve, config.startupDelayMs));
58
+ }
59
+ if (config?.startupFails) {
60
+ throw new Error('Mock WebSocket server startup failed');
61
+ }
62
+ const host = config?.host ?? '127.0.0.1';
63
+ const port = config?.port ?? 8081;
64
+ this._port = port;
65
+ this._serverUrl = `ws://${host}:${port}`;
66
+ this._server = new WebSocketServer({
67
+ host,
68
+ port,
69
+ maxPayload: 1024 * 1024 * 8,
70
+ });
71
+ try {
72
+ await new Promise((resolve, reject) => {
73
+ const server = this._server;
74
+ if (!server) {
75
+ reject(new Error('WebSocket server failed to initialize'));
76
+ return;
77
+ }
78
+ const cleanup = () => {
79
+ server.off('error', onError);
80
+ server.off('listening', onListening);
81
+ };
82
+ const onError = (error) => {
83
+ cleanup();
84
+ reject(error);
85
+ };
86
+ const onListening = () => {
87
+ cleanup();
88
+ const address = server.address();
89
+ if (address && typeof address === 'object' && 'port' in address) {
90
+ this._port = address.port;
91
+ this._serverUrl = `ws://${host}:${address.port}`;
92
+ }
93
+ this._isRunning = true;
94
+ this.emit('started');
95
+ resolve();
96
+ };
97
+ server.once('error', onError);
98
+ server.once('listening', onListening);
99
+ });
100
+ }
101
+ catch (error) {
102
+ this._isRunning = false;
103
+ if (this._server) {
104
+ await new Promise((resolve) => this._server?.close(() => resolve()));
105
+ this._server = null;
106
+ }
107
+ throw error;
108
+ }
109
+ this._server.on('connection', (socket) => {
110
+ if (!this._isRunning) {
111
+ socket.close(1012, 'Server stopping');
112
+ return;
113
+ }
114
+ const now = Date.now();
115
+ if (this._reconnectAllowedAt != null && now < this._reconnectAllowedAt) {
116
+ socket.close(1013, 'Reconnect not yet allowed');
117
+ return;
118
+ }
119
+ const isReconnect = this._reconnectAllowedAt != null && now >= this._reconnectAllowedAt;
120
+ if (isReconnect) {
121
+ this._reconnectAllowedAt = null;
122
+ }
123
+ if (this.scenario.websocketServer?.maxConnections != null
124
+ && this._connections.size >= this.scenario.websocketServer.maxConnections) {
125
+ socket.close(1013, 'Mock connection limit reached');
126
+ return;
127
+ }
128
+ const connection = this.createConnection(socket);
129
+ this.emit('connection', connection.connectionId);
130
+ if (isReconnect) {
131
+ this.emit('reconnected', connection.connectionId);
132
+ }
133
+ this.scheduleScenarioEvents(connection);
134
+ this.attachSocketHandlers(connection);
135
+ });
136
+ }
137
+ broadcast(message) {
138
+ for (const connectionId of this._connections.keys()) {
139
+ this.sendTo(connectionId, message);
140
+ }
141
+ }
142
+ sendTo(connectionId, message) {
143
+ const connection = this._connections.get(connectionId);
144
+ if (!connection) {
145
+ throw new Error(`Unknown connection: ${connectionId}`);
146
+ }
147
+ if (connection.disconnectedAt) {
148
+ throw new Error(`Connection already closed: ${connectionId}`);
149
+ }
150
+ this.sendFrame(connection, message);
151
+ }
152
+ receiveFrom(connectionId, message) {
153
+ const connection = this._connections.get(connectionId);
154
+ if (!connection) {
155
+ throw new Error(`Unknown connection: ${connectionId}`);
156
+ }
157
+ if (connection.disconnectedAt) {
158
+ throw new Error(`Connection already closed: ${connectionId}`);
159
+ }
160
+ this.recordMessage(connection, 'inbound', message);
161
+ this.emit('message', { connectionId, direction: 'inbound', message });
162
+ this.checkForDrop(connection);
163
+ }
164
+ dropConnection(connectionId) {
165
+ const connection = this._connections.get(connectionId);
166
+ if (!connection || connection.disconnectedAt) {
167
+ return;
168
+ }
169
+ this.closeConnection(connection, 1011, 'Mock connection dropped');
170
+ const drops = this.scenario.websocketServer?.simulateDrops;
171
+ if (drops?.reconnectDelayMs != null) {
172
+ this._reconnectAllowedAt = Date.now() + drops.reconnectDelayMs;
173
+ if (this._reconnectTimer) {
174
+ clearTimeout(this._reconnectTimer);
175
+ }
176
+ this._reconnectTimer = setTimeout(() => {
177
+ this._reconnectTimer = null;
178
+ if (!this._isRunning)
179
+ return;
180
+ if (this._reconnectAllowedAt != null && Date.now() >= this._reconnectAllowedAt) {
181
+ this._reconnectAllowedAt = null;
182
+ }
183
+ }, drops.reconnectDelayMs);
184
+ }
185
+ }
186
+ getConnectionStatus() {
187
+ return Array.from(this._connections.values()).map((connection) => ({
188
+ connectionId: connection.connectionId,
189
+ connectedAt: connection.connectedAt,
190
+ messageCount: connection.messageCount,
191
+ }));
192
+ }
193
+ async stop() {
194
+ if (!this._isRunning) {
195
+ this._exited = true;
196
+ return;
197
+ }
198
+ this._isRunning = false;
199
+ if (this._reconnectTimer) {
200
+ clearTimeout(this._reconnectTimer);
201
+ this._reconnectTimer = null;
202
+ }
203
+ for (const connection of [...this._connections.values()]) {
204
+ this.closeConnection(connection, 1001, 'Server stopped');
205
+ }
206
+ this._connections.clear();
207
+ await new Promise((resolve) => {
208
+ if (!this._server) {
209
+ resolve();
210
+ return;
211
+ }
212
+ this._server.close(() => resolve());
213
+ this._server = null;
214
+ });
215
+ this._exited = true;
216
+ this.emit('stopped');
217
+ }
218
+ forceStop() {
219
+ void this.stop();
220
+ }
221
+ async waitForCompletion() {
222
+ if (!this._exited) {
223
+ await new Promise((resolve) => this.once('stopped', resolve));
224
+ }
225
+ const durationMs = Date.now() - this._startTime;
226
+ const completedConnections = this.getHistoricalConnections();
227
+ const averageConnectionDurationMs = completedConnections.length === 0
228
+ ? durationMs
229
+ : completedConnections.reduce((sum, connection) => sum + connection.durationMs, 0) / completedConnections.length;
230
+ const result = {
231
+ type: 'websocket',
232
+ connectionCount: completedConnections.length,
233
+ messageCount: this._messageHistory.length,
234
+ averageConnectionDurationMs,
235
+ };
236
+ return {
237
+ success: true,
238
+ durationMs,
239
+ results: result,
240
+ };
241
+ }
242
+ createConnection(socket) {
243
+ const connectionId = `ws-${nextConnectionId++}`;
244
+ const connection = {
245
+ connectionId,
246
+ socket,
247
+ connectedAt: new Date(),
248
+ messageCount: 0,
249
+ timers: [],
250
+ };
251
+ this._connections.set(connectionId, connection);
252
+ return connection;
253
+ }
254
+ scheduleScenarioEvents(connection) {
255
+ let delayMs = 0;
256
+ for (const event of this.scenario.events ?? []) {
257
+ delayMs += event.delayMs ?? 0;
258
+ const timer = setTimeout(() => {
259
+ if (!this._isRunning || !this._connections.has(connection.connectionId)) {
260
+ return;
261
+ }
262
+ this.sendFrame(connection, event);
263
+ this.emit('event', { connectionId: connection.connectionId, event });
264
+ }, delayMs);
265
+ connection.timers.push(timer);
266
+ }
267
+ for (const op of this.scenario.fileOperations ?? []) {
268
+ this._fileChanges.push(op);
269
+ }
270
+ }
271
+ recordMessage(connection, direction, message) {
272
+ connection.messageCount += 1;
273
+ this._messageHistory.push({
274
+ connectionId: connection.connectionId,
275
+ direction,
276
+ message,
277
+ timestamp: new Date(),
278
+ });
279
+ }
280
+ sendFrame(connection, message) {
281
+ if (connection.socket.readyState !== WebSocket.OPEN) {
282
+ throw new Error(`Connection already closed: ${connection.connectionId}`);
283
+ }
284
+ this.recordMessage(connection, 'outbound', message);
285
+ connection.socket.send(typeof message === 'string' ? message : JSON.stringify(message));
286
+ this.emit('message', { connectionId: connection.connectionId, direction: 'outbound', message });
287
+ this.checkForDrop(connection);
288
+ }
289
+ attachSocketHandlers(connection) {
290
+ connection.socket.on('message', (data, isBinary) => {
291
+ const message = this.decodeMessage(data, isBinary);
292
+ this.receiveFrom(connection.connectionId, message);
293
+ });
294
+ connection.socket.once('close', () => {
295
+ this.finalizeConnection(connection);
296
+ });
297
+ connection.socket.once('error', (error) => {
298
+ if (!connection.disconnectedAt) {
299
+ this.emit('error', error);
300
+ }
301
+ });
302
+ }
303
+ decodeMessage(data, isBinary) {
304
+ const normalized = this.normalizeRawData(data);
305
+ if (isBinary) {
306
+ return normalized;
307
+ }
308
+ const text = typeof normalized === 'string' ? normalized : normalized.toString('utf8');
309
+ try {
310
+ return JSON.parse(text);
311
+ }
312
+ catch {
313
+ return text;
314
+ }
315
+ }
316
+ normalizeRawData(data) {
317
+ if (typeof data === 'string') {
318
+ return data;
319
+ }
320
+ if (Buffer.isBuffer(data)) {
321
+ return data;
322
+ }
323
+ if (Array.isArray(data)) {
324
+ return Buffer.concat(data);
325
+ }
326
+ return Buffer.from(new Uint8Array(data));
327
+ }
328
+ closeConnection(connection, code, reason) {
329
+ if (connection.disconnectedAt) {
330
+ return;
331
+ }
332
+ connection.disconnectedAt = new Date();
333
+ for (const timer of connection.timers) {
334
+ clearTimeout(timer);
335
+ }
336
+ connection.timers.length = 0;
337
+ if (connection.socket.readyState === WebSocket.OPEN || connection.socket.readyState === WebSocket.CONNECTING) {
338
+ connection.socket.close(code, reason);
339
+ }
340
+ this.finalizeConnection(connection);
341
+ }
342
+ finalizeConnection(connection) {
343
+ if (!this._connections.has(connection.connectionId)) {
344
+ return;
345
+ }
346
+ connection.disconnectedAt ??= new Date();
347
+ this._connections.delete(connection.connectionId);
348
+ if (!this._completedConnections.includes(connection)) {
349
+ this._completedConnections.push(connection);
350
+ }
351
+ this.emit('disconnected', connection.connectionId);
352
+ }
353
+ checkForDrop(connection) {
354
+ const drops = this.scenario.websocketServer?.simulateDrops;
355
+ if (drops?.afterMessages != null && connection.messageCount >= drops.afterMessages) {
356
+ this.dropConnection(connection.connectionId);
357
+ }
358
+ }
359
+ getHistoricalConnections() {
360
+ const allConnections = [...this._completedConnections, ...this._connections.values()];
361
+ return allConnections.map((connection) => ({
362
+ connectionId: connection.connectionId,
363
+ durationMs: Math.max(0, (connection.disconnectedAt ?? new Date()).getTime() - connection.connectedAt.getTime()),
364
+ }));
365
+ }
366
+ }
367
+ //# sourceMappingURL=websocket-mock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket-mock.js","sourceRoot":"","sources":["../src/websocket-mock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * WorkspaceSandbox — isolated filesystem area for mock harness file operations.
3
+ *
4
+ * Creates a temporary directory that the mock harness can read/write to,
5
+ * providing snapshot and diff capabilities for test assertions.
6
+ */
7
+ import type { FileOperation } from './types.js';
8
+ export interface WorkspaceOptions {
9
+ /** Initial files to seed the workspace with. */
10
+ initialFiles?: Record<string, string>;
11
+ /** Whether to preserve the workspace after dispose() (for debugging). */
12
+ preserve?: boolean;
13
+ }
14
+ export declare class WorkspaceSandbox {
15
+ /** The root directory of this sandbox. */
16
+ readonly root: string;
17
+ private _disposed;
18
+ private _preserve;
19
+ private _initialSnapshot;
20
+ constructor(options?: WorkspaceOptions);
21
+ /** Resolve a relative path within the sandbox. */
22
+ resolve(relativePath: string): string;
23
+ /** Write a file to the sandbox. */
24
+ writeFile(relativePath: string, content: string): void;
25
+ /** Read a file from the sandbox. */
26
+ readFile(relativePath: string): string;
27
+ /** Check if a file exists in the sandbox. */
28
+ exists(relativePath: string): boolean;
29
+ /** Delete a file from the sandbox. */
30
+ deleteFile(relativePath: string): void;
31
+ /** List all files in the sandbox (relative paths). */
32
+ listFiles(): string[];
33
+ /**
34
+ * Apply a sequence of file operations to the sandbox.
35
+ * Translates absolute paths in the operations to sandbox-relative paths.
36
+ */
37
+ applyOperations(operations: FileOperation[], basePath?: string): void;
38
+ /**
39
+ * Get a diff of changes since the workspace was created.
40
+ * Returns arrays of created, modified, and deleted files.
41
+ */
42
+ diff(): {
43
+ created: string[];
44
+ modified: string[];
45
+ deleted: string[];
46
+ };
47
+ /** Snapshot the current state (for later comparison). */
48
+ snapshot(): Map<string, string>;
49
+ /** Clean up the sandbox. */
50
+ dispose(): void;
51
+ private _ensureNotDisposed;
52
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEtC,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,qBAAa,gBAAgB;IAC3B,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,gBAAgB,CAAsB;gBAElC,OAAO,CAAC,EAAE,gBAAgB;IAatC,kDAAkD;IAClD,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAQrC,mCAAmC;IACnC,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAOtD,oCAAoC;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAKtC,6CAA6C;IAC7C,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAKrC,sCAAsC;IACtC,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAKtC,sDAAsD;IACtD,SAAS,IAAI,MAAM,EAAE;IAiBrB;;;OAGG;IACH,eAAe,CAAC,UAAU,EAAE,aAAa,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IA+BrE;;;OAGG;IACH,IAAI,IAAI;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE;IAwBpE,yDAAyD;IACzD,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAS/B,4BAA4B;IAC5B,OAAO,IAAI,IAAI;IAQf,OAAO,CAAC,kBAAkB;CAK3B"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * WorkspaceSandbox — isolated filesystem area for mock harness file operations.
3
+ *
4
+ * Creates a temporary directory that the mock harness can read/write to,
5
+ * providing snapshot and diff capabilities for test assertions.
6
+ */
7
+ import * as fs from 'node:fs';
8
+ import * as os from 'node:os';
9
+ import * as path from 'node:path';
10
+ export class WorkspaceSandbox {
11
+ /** The root directory of this sandbox. */
12
+ root;
13
+ _disposed = false;
14
+ _preserve;
15
+ _initialSnapshot;
16
+ constructor(options) {
17
+ this.root = fs.mkdtempSync(path.join(os.tmpdir(), 'adapters-workspace-'));
18
+ this._preserve = options?.preserve ?? false;
19
+ this._initialSnapshot = new Map();
20
+ if (options?.initialFiles) {
21
+ for (const [filePath, content] of Object.entries(options.initialFiles)) {
22
+ this.writeFile(filePath, content);
23
+ this._initialSnapshot.set(filePath, content);
24
+ }
25
+ }
26
+ }
27
+ /** Resolve a relative path within the sandbox. */
28
+ resolve(relativePath) {
29
+ const resolved = path.resolve(this.root, relativePath);
30
+ if (!resolved.startsWith(this.root)) {
31
+ throw new Error(`Path escapes sandbox: ${relativePath}`);
32
+ }
33
+ return resolved;
34
+ }
35
+ /** Write a file to the sandbox. */
36
+ writeFile(relativePath, content) {
37
+ this._ensureNotDisposed();
38
+ const fullPath = this.resolve(relativePath);
39
+ fs.mkdirSync(path.dirname(fullPath), { recursive: true });
40
+ fs.writeFileSync(fullPath, content, 'utf-8');
41
+ }
42
+ /** Read a file from the sandbox. */
43
+ readFile(relativePath) {
44
+ this._ensureNotDisposed();
45
+ return fs.readFileSync(this.resolve(relativePath), 'utf-8');
46
+ }
47
+ /** Check if a file exists in the sandbox. */
48
+ exists(relativePath) {
49
+ this._ensureNotDisposed();
50
+ return fs.existsSync(this.resolve(relativePath));
51
+ }
52
+ /** Delete a file from the sandbox. */
53
+ deleteFile(relativePath) {
54
+ this._ensureNotDisposed();
55
+ fs.unlinkSync(this.resolve(relativePath));
56
+ }
57
+ /** List all files in the sandbox (relative paths). */
58
+ listFiles() {
59
+ this._ensureNotDisposed();
60
+ const results = [];
61
+ const walk = (dir) => {
62
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
63
+ const full = path.join(dir, entry.name);
64
+ if (entry.isDirectory()) {
65
+ walk(full);
66
+ }
67
+ else {
68
+ results.push(path.relative(this.root, full).replace(/\\/g, '/'));
69
+ }
70
+ }
71
+ };
72
+ walk(this.root);
73
+ return results.sort();
74
+ }
75
+ /**
76
+ * Apply a sequence of file operations to the sandbox.
77
+ * Translates absolute paths in the operations to sandbox-relative paths.
78
+ */
79
+ applyOperations(operations, basePath) {
80
+ this._ensureNotDisposed();
81
+ for (const op of operations) {
82
+ const relativePath = basePath
83
+ ? path.relative(basePath, op.path).replace(/\\/g, '/')
84
+ : op.path.replace(/^\//, '');
85
+ switch (op.type) {
86
+ case 'create':
87
+ case 'modify':
88
+ this.writeFile(relativePath, op.content ?? '');
89
+ break;
90
+ case 'delete':
91
+ if (this.exists(relativePath)) {
92
+ this.deleteFile(relativePath);
93
+ }
94
+ break;
95
+ case 'rename':
96
+ if (op.newPath) {
97
+ const newRelative = basePath
98
+ ? path.relative(basePath, op.newPath).replace(/\\/g, '/')
99
+ : op.newPath.replace(/^\//, '');
100
+ const content = this.readFile(relativePath);
101
+ this.writeFile(newRelative, content);
102
+ this.deleteFile(relativePath);
103
+ }
104
+ break;
105
+ }
106
+ }
107
+ }
108
+ /**
109
+ * Get a diff of changes since the workspace was created.
110
+ * Returns arrays of created, modified, and deleted files.
111
+ */
112
+ diff() {
113
+ this._ensureNotDisposed();
114
+ const currentFiles = new Set(this.listFiles());
115
+ const created = [];
116
+ const modified = [];
117
+ const deleted = [];
118
+ for (const file of currentFiles) {
119
+ if (!this._initialSnapshot.has(file)) {
120
+ created.push(file);
121
+ }
122
+ else if (this.readFile(file) !== this._initialSnapshot.get(file)) {
123
+ modified.push(file);
124
+ }
125
+ }
126
+ for (const file of this._initialSnapshot.keys()) {
127
+ if (!currentFiles.has(file)) {
128
+ deleted.push(file);
129
+ }
130
+ }
131
+ return { created: created.sort(), modified: modified.sort(), deleted: deleted.sort() };
132
+ }
133
+ /** Snapshot the current state (for later comparison). */
134
+ snapshot() {
135
+ this._ensureNotDisposed();
136
+ const snap = new Map();
137
+ for (const file of this.listFiles()) {
138
+ snap.set(file, this.readFile(file));
139
+ }
140
+ return snap;
141
+ }
142
+ /** Clean up the sandbox. */
143
+ dispose() {
144
+ if (this._disposed)
145
+ return;
146
+ this._disposed = true;
147
+ if (!this._preserve) {
148
+ fs.rmSync(this.root, { recursive: true, force: true });
149
+ }
150
+ }
151
+ _ensureNotDisposed() {
152
+ if (this._disposed) {
153
+ throw new Error('WorkspaceSandbox has been disposed');
154
+ }
155
+ }
156
+ }
157
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"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"}