repoburg 1.3.163 → 1.3.166

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 (27) hide show
  1. package/backend/.env +1 -0
  2. package/backend/dist/src/application-state/application-state.service.js +3 -3
  3. package/backend/dist/src/application-state/application-state.service.js.map +1 -1
  4. package/backend/dist/src/llm-orchestration/llm-orchestration.interfaces.d.ts +2 -1
  5. package/backend/dist/src/llm-orchestration/llm-orchestration.interfaces.js.map +1 -1
  6. package/backend/dist/src/mcp-server/mcp-internal.controller.d.ts +3 -11
  7. package/backend/dist/src/mcp-server/mcp-internal.controller.js.map +1 -1
  8. package/backend/dist/src/mcp-server/mcp-server.bootstrap.js +9 -7
  9. package/backend/dist/src/mcp-server/mcp-server.bootstrap.js.map +1 -1
  10. package/backend/dist/src/mcp-server/mcp-server.constants.d.ts +1 -0
  11. package/backend/dist/src/mcp-server/mcp-server.constants.js.map +1 -1
  12. package/backend/dist/src/mcp-server/mcp-server.controller.d.ts +1 -9
  13. package/backend/dist/src/mcp-server/mcp-server.module.js +1 -5
  14. package/backend/dist/src/mcp-server/mcp-server.module.js.map +1 -1
  15. package/backend/dist/src/mcp-server/mcp-server.process.service.js.map +1 -1
  16. package/backend/dist/src/mcp-server/mcp-server.service.d.ts +9 -13
  17. package/backend/dist/src/mcp-server/mcp-server.service.js +27 -24
  18. package/backend/dist/src/mcp-server/mcp-server.service.js.map +1 -1
  19. package/backend/dist/src/tool-hooks/hook-context.interface.d.ts +2 -1
  20. package/backend/dist/src/utils/tool-schema-converter.d.ts +8 -3
  21. package/backend/dist/src/utils/tool-schema-converter.js.map +1 -1
  22. package/backend/dist/tsconfig.build.tsbuildinfo +1 -1
  23. package/daemon/dist/mcp-gateway.js +38 -18
  24. package/daemon/dist/mcp-gateway.spec.js +295 -0
  25. package/daemon/package.json +15 -2
  26. package/package.json +1 -1
  27. package/platform-cli.js +264 -1
@@ -25,6 +25,11 @@ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
25
25
  const crypto_1 = require("crypto");
26
26
  const stateManager_1 = require("./stateManager");
27
27
  const serviceManager_1 = require("./serviceManager");
28
+ /**
29
+ * Daemon-level tool names exposed by the gateway (always available, no
30
+ * instance routing needed).
31
+ */
32
+ const DAEMON_TOOL_NAMES = ['list_instances', 'start_instance', 'stop_instance'];
28
33
  // ---------------------------------------------------------------------------
29
34
  // Gateway
30
35
  // ---------------------------------------------------------------------------
@@ -33,6 +38,10 @@ const INSTANCE_NAME_PARAM = {
33
38
  type: 'string',
34
39
  description: 'Name of the Repoburg instance to manage. Use the list_instances tool to see available instances.',
35
40
  };
41
+ /** Extracts an error message from an unknown catch value. */
42
+ function errorMessage(err) {
43
+ return err instanceof Error ? err.message : String(err);
44
+ }
36
45
  class McpGateway {
37
46
  constructor() {
38
47
  this.sessions = new Map();
@@ -101,7 +110,7 @@ class McpGateway {
101
110
  res.status(405).send('Method not allowed');
102
111
  }
103
112
  catch (err) {
104
- console.error(`[McpGateway] Error handling MCP request: ${err.message}`);
113
+ console.error(`[McpGateway] Error handling MCP request: ${errorMessage(err)}`);
105
114
  if (!res.headersSent) {
106
115
  res.status(500).send('Internal server error');
107
116
  }
@@ -127,17 +136,23 @@ class McpGateway {
127
136
  const { name, arguments: args } = request.params;
128
137
  const toolArgs = args ?? {};
129
138
  // Daemon-level tools
139
+ let result;
130
140
  if (name === 'list_instances') {
131
- return this.handleListInstances();
141
+ result = this.handleListInstances();
142
+ }
143
+ else if (name === 'start_instance') {
144
+ result = await this.handleStartInstance(toolArgs);
132
145
  }
133
- if (name === 'start_instance') {
134
- return this.handleStartInstance(toolArgs);
146
+ else if (name === 'stop_instance') {
147
+ result = await this.handleStopInstance(toolArgs);
135
148
  }
136
- if (name === 'stop_instance') {
137
- return this.handleStopInstance(toolArgs);
149
+ else {
150
+ // manage_* tools — proxy to the target instance
151
+ result = await this.handleManageTool(name, toolArgs);
138
152
  }
139
- // manage_* tools proxy to the target instance
140
- return this.handleManageTool(name, toolArgs);
153
+ // Cast to the SDK's expected ServerResult union — structurally compatible
154
+ // but the Zod-inferred type is too narrow for direct assignment.
155
+ return result;
141
156
  });
142
157
  return server;
143
158
  }
@@ -165,12 +180,16 @@ class McpGateway {
165
180
  console.warn(`[McpGateway] Failed to fetch tools from instance '${runningInstance.name}' (${resp.status}).`);
166
181
  return;
167
182
  }
168
- const tools = (await resp.json());
169
- this.toolCache = tools.map((tool) => this.augmentWithInstanceName(tool));
183
+ const rawTools = (await resp.json());
184
+ this.toolCache = rawTools.map((raw) => this.augmentWithInstanceName({
185
+ name: raw.tool_name,
186
+ description: raw.description,
187
+ inputSchema: raw.input_schema,
188
+ }));
170
189
  console.log(`[McpGateway] Cached ${this.toolCache.length} manage_* tools from instance '${runningInstance.name}'.`);
171
190
  }
172
191
  catch (err) {
173
- console.warn(`[McpGateway] Could not refresh tool cache: ${err.message}`);
192
+ console.warn(`[McpGateway] Could not refresh tool cache: ${errorMessage(err)}`);
174
193
  }
175
194
  finally {
176
195
  this.isRefreshing = false;
@@ -256,21 +275,22 @@ class McpGateway {
256
275
  }
257
276
  async handleStartInstance(args) {
258
277
  const projectPath = args.path;
259
- if (!projectPath) {
278
+ if (typeof projectPath !== 'string') {
260
279
  return this.errorResult('Missing required parameter: path');
261
280
  }
281
+ const name = typeof args.name === 'string' ? args.name : undefined;
262
282
  try {
263
- const service = await serviceManager_1.serviceManager.start(projectPath, args.name);
283
+ const service = await serviceManager_1.serviceManager.start(projectPath, name);
264
284
  this.invalidateToolCache();
265
285
  return this.textResult(`Instance '${service.name}' started on port ${service.port} (path: ${service.path}).`);
266
286
  }
267
287
  catch (err) {
268
- return this.errorResult(`Failed to start instance: ${err.message}`);
288
+ return this.errorResult(`Failed to start instance: ${errorMessage(err)}`);
269
289
  }
270
290
  }
271
291
  async handleStopInstance(args) {
272
292
  const name = args.name;
273
- if (!name) {
293
+ if (typeof name !== 'string') {
274
294
  return this.errorResult('Missing required parameter: name');
275
295
  }
276
296
  try {
@@ -278,7 +298,7 @@ class McpGateway {
278
298
  return this.textResult(`Instance '${name}' stopped.`);
279
299
  }
280
300
  catch (err) {
281
- return this.errorResult(`Failed to stop instance: ${err.message}`);
301
+ return this.errorResult(`Failed to stop instance: ${errorMessage(err)}`);
282
302
  }
283
303
  }
284
304
  // -------------------------------------------------------------------------
@@ -286,7 +306,7 @@ class McpGateway {
286
306
  // -------------------------------------------------------------------------
287
307
  async handleManageTool(toolName, args) {
288
308
  const instanceName = args.instance_name;
289
- if (!instanceName) {
309
+ if (typeof instanceName !== 'string') {
290
310
  return this.errorResult(`Missing required parameter: instance_name. Use the list_instances tool to see available instances.`);
291
311
  }
292
312
  const service = stateManager_1.stateManager.getService(instanceName);
@@ -314,7 +334,7 @@ class McpGateway {
314
334
  return this.toToolResult(result);
315
335
  }
316
336
  catch (err) {
317
- return this.errorResult(`Failed to reach instance '${instanceName}': ${err.message}`);
337
+ return this.errorResult(`Failed to reach instance '${instanceName}': ${errorMessage(err)}`);
318
338
  }
319
339
  }
320
340
  // -------------------------------------------------------------------------
@@ -0,0 +1,295 @@
1
+ "use strict";
2
+ /**
3
+ * Tests for the MCP gateway — the daemon-hosted single MCP entry point that
4
+ * manages all Repoburg instances.
5
+ *
6
+ * Tests focus on:
7
+ * - Tool cache refresh (fetch from running instance, augment with instance_name)
8
+ * - Cache invalidation
9
+ * - getGatewayInfo() shape
10
+ * - Daemon-level tool routing (list_instances, start_instance, stop_instance)
11
+ * - manage_* proxy routing (missing instance_name, unknown instance, not running,
12
+ * valid POST, fetch failure, result mapping)
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ // Mock dependencies before importing the gateway.
16
+ jest.mock('./stateManager', () => ({
17
+ stateManager: {
18
+ getServices: jest.fn(),
19
+ getService: jest.fn(),
20
+ },
21
+ }));
22
+ jest.mock('./serviceManager', () => ({
23
+ serviceManager: {
24
+ start: jest.fn(),
25
+ stop: jest.fn(),
26
+ },
27
+ }));
28
+ // Mock MCP SDK — we test the gateway's logic, not the SDK.
29
+ jest.mock('@modelcontextprotocol/sdk/server/index.js', () => ({
30
+ Server: jest.fn().mockImplementation(() => ({
31
+ setRequestHandler: jest.fn(),
32
+ connect: jest.fn(),
33
+ close: jest.fn(),
34
+ })),
35
+ }));
36
+ jest.mock('@modelcontextprotocol/sdk/server/streamableHttp.js', () => ({
37
+ StreamableHTTPServerTransport: jest.fn(),
38
+ }));
39
+ jest.mock('@modelcontextprotocol/sdk/types.js', () => ({
40
+ CallToolRequestSchema: 'callTool',
41
+ ListToolsRequestSchema: 'listTools',
42
+ isInitializeRequest: jest.fn(),
43
+ }));
44
+ const mcp_gateway_1 = require("./mcp-gateway");
45
+ const stateManager_1 = require("./stateManager");
46
+ const serviceManager_1 = require("./serviceManager");
47
+ const mockStateManager = stateManager_1.stateManager;
48
+ const mockServiceManager = serviceManager_1.serviceManager;
49
+ // Helper: create a mock Service object.
50
+ function mockService(name, status = 'running') {
51
+ return { name, path: `/projects/${name}`, port: 3400, status, pid: 12345 };
52
+ }
53
+ // Helper: raw tool definition as returned by backend's GET /mcp-internal/tools.
54
+ function rawToolDef(name, description, required = []) {
55
+ return {
56
+ tool_name: name,
57
+ description,
58
+ input_schema: {
59
+ type: 'object',
60
+ properties: required.reduce((acc, r) => {
61
+ acc[r] = { type: 'string', description: `${r} param` };
62
+ return acc;
63
+ }, {}),
64
+ required: required.length > 0 ? required : undefined,
65
+ },
66
+ };
67
+ }
68
+ describe('McpGateway', () => {
69
+ beforeEach(() => {
70
+ jest.clearAllMocks();
71
+ // Reset gateway state between tests.
72
+ mcp_gateway_1.mcpGateway.invalidateToolCache();
73
+ // Default: no instances.
74
+ mockStateManager.getServices.mockReturnValue([]);
75
+ mockStateManager.getService.mockReturnValue(undefined);
76
+ mockServiceManager.start.mockReset();
77
+ mockServiceManager.stop.mockReset();
78
+ });
79
+ describe('refreshToolCache', () => {
80
+ it('should fetch tools from a running instance and augment with instance_name', async () => {
81
+ mockStateManager.getServices.mockReturnValue([mockService('alpha', 'running')]);
82
+ global.fetch = jest.fn().mockResolvedValue({
83
+ ok: true,
84
+ json: async () => [rawToolDef('manage_agents', 'Manage agents', ['action'])],
85
+ });
86
+ await mcp_gateway_1.mcpGateway.refreshToolCache();
87
+ const info = await mcp_gateway_1.mcpGateway.getGatewayInfo();
88
+ const manageTools = info.tools.filter((t) => t.name.startsWith('manage_'));
89
+ expect(manageTools).toHaveLength(1);
90
+ expect(manageTools[0].name).toBe('manage_agents');
91
+ expect(manageTools[0].inputSchema.properties).toHaveProperty('instance_name');
92
+ expect(manageTools[0].inputSchema.required).toContain('instance_name');
93
+ });
94
+ it('should leave cache null when no instance is running', async () => {
95
+ mockStateManager.getServices.mockReturnValue([mockService('alpha', 'stopped')]);
96
+ await mcp_gateway_1.mcpGateway.refreshToolCache();
97
+ const info = await mcp_gateway_1.mcpGateway.getGatewayInfo();
98
+ // Only daemon-level tools, no manage_* tools.
99
+ const manageTools = info.tools.filter((t) => t.name.startsWith('manage_'));
100
+ expect(manageTools).toHaveLength(0);
101
+ });
102
+ it('should skip refresh when cache is already populated', async () => {
103
+ mockStateManager.getServices.mockReturnValue([mockService('alpha', 'running')]);
104
+ const fetchMock = jest.fn().mockResolvedValue({
105
+ ok: true,
106
+ json: async () => [rawToolDef('manage_agents', 'Manage agents')],
107
+ });
108
+ global.fetch = fetchMock;
109
+ await mcp_gateway_1.mcpGateway.refreshToolCache();
110
+ await mcp_gateway_1.mcpGateway.refreshToolCache(); // second call
111
+ // fetch should only be called once (cache hit on second call).
112
+ expect(fetchMock).toHaveBeenCalledTimes(1);
113
+ });
114
+ it('should handle fetch failure gracefully (cache stays null)', async () => {
115
+ mockStateManager.getServices.mockReturnValue([mockService('alpha', 'running')]);
116
+ global.fetch = jest.fn().mockResolvedValue({ ok: false, status: 500 });
117
+ await mcp_gateway_1.mcpGateway.refreshToolCache();
118
+ const info = await mcp_gateway_1.mcpGateway.getGatewayInfo();
119
+ const manageTools = info.tools.filter((t) => t.name.startsWith('manage_'));
120
+ expect(manageTools).toHaveLength(0);
121
+ });
122
+ });
123
+ describe('invalidateToolCache', () => {
124
+ it('should clear cache so next refresh re-fetches', async () => {
125
+ mockStateManager.getServices.mockReturnValue([mockService('alpha', 'running')]);
126
+ const fetchMock = jest.fn().mockResolvedValue({
127
+ ok: true,
128
+ json: async () => [rawToolDef('manage_agents', 'Manage agents')],
129
+ });
130
+ global.fetch = fetchMock;
131
+ await mcp_gateway_1.mcpGateway.refreshToolCache();
132
+ expect(fetchMock).toHaveBeenCalledTimes(1);
133
+ mcp_gateway_1.mcpGateway.invalidateToolCache();
134
+ await mcp_gateway_1.mcpGateway.refreshToolCache();
135
+ expect(fetchMock).toHaveBeenCalledTimes(2);
136
+ });
137
+ });
138
+ describe('getGatewayInfo', () => {
139
+ it('should return descriptor with server_name, url, instances, tools, client_config', async () => {
140
+ mockStateManager.getServices.mockReturnValue([
141
+ mockService('alpha', 'running'),
142
+ mockService('beta', 'stopped'),
143
+ ]);
144
+ const info = await mcp_gateway_1.mcpGateway.getGatewayInfo();
145
+ expect(info.server_name).toBe('repoburg-gateway');
146
+ expect(info.url).toBe('http://localhost:9998/mcp');
147
+ expect(info.instances).toHaveLength(2);
148
+ expect(info.instances[0].name).toBe('alpha');
149
+ expect(info.instances[0].status).toBe('running');
150
+ expect(info.client_config).toContain('http://localhost:9998/mcp');
151
+ // Should always include daemon-level tools.
152
+ const toolNames = info.tools.map((t) => t.name);
153
+ expect(toolNames).toContain('list_instances');
154
+ expect(toolNames).toContain('start_instance');
155
+ expect(toolNames).toContain('stop_instance');
156
+ });
157
+ });
158
+ describe('daemon-level tool routing', () => {
159
+ it('list_instances should return text with instance info', () => {
160
+ mockStateManager.getServices.mockReturnValue([
161
+ mockService('alpha', 'running'),
162
+ mockService('beta', 'stopped'),
163
+ ]);
164
+ const result = mcp_gateway_1.mcpGateway.handleListInstances();
165
+ const text = result.content[0].text;
166
+ expect(text).toContain('alpha');
167
+ expect(text).toContain('running');
168
+ expect(text).toContain('beta');
169
+ expect(text).toContain('stopped');
170
+ expect(result.isError).toBeUndefined();
171
+ });
172
+ it('list_instances should show message when no instances', () => {
173
+ mockStateManager.getServices.mockReturnValue([]);
174
+ const result = mcp_gateway_1.mcpGateway.handleListInstances();
175
+ expect(result.content[0].text).toContain('No Repoburg instances');
176
+ });
177
+ it('start_instance should call serviceManager.start and invalidate cache', async () => {
178
+ mockServiceManager.start.mockResolvedValue(mockService('gamma', 'running'));
179
+ const result = await mcp_gateway_1.mcpGateway.handleStartInstance({
180
+ path: '/projects/gamma',
181
+ name: 'gamma',
182
+ });
183
+ expect(mockServiceManager.start).toHaveBeenCalledWith('/projects/gamma', 'gamma');
184
+ expect(result.content[0].text).toContain('gamma');
185
+ expect(result.isError).toBeUndefined();
186
+ });
187
+ it('start_instance should error when path is missing', async () => {
188
+ const result = await mcp_gateway_1.mcpGateway.handleStartInstance({});
189
+ expect(result.isError).toBe(true);
190
+ expect(result.content[0].text).toContain('Missing required parameter: path');
191
+ });
192
+ it('stop_instance should call serviceManager.stop', async () => {
193
+ const result = await mcp_gateway_1.mcpGateway.handleStopInstance({ name: 'alpha' });
194
+ expect(mockServiceManager.stop).toHaveBeenCalledWith('alpha');
195
+ expect(result.content[0].text).toContain('alpha');
196
+ expect(result.isError).toBeUndefined();
197
+ });
198
+ it('stop_instance should error when name is missing', async () => {
199
+ const result = await mcp_gateway_1.mcpGateway.handleStopInstance({});
200
+ expect(result.isError).toBe(true);
201
+ expect(result.content[0].text).toContain('Missing required parameter: name');
202
+ });
203
+ });
204
+ describe('manage_* proxy routing', () => {
205
+ it('should error when instance_name is missing', async () => {
206
+ const result = await mcp_gateway_1.mcpGateway.handleManageTool('manage_agents', {
207
+ action: 'create',
208
+ });
209
+ expect(result.isError).toBe(true);
210
+ expect(result.content[0].text).toContain('instance_name');
211
+ });
212
+ it('should error when instance is not found', async () => {
213
+ mockStateManager.getService.mockReturnValue(undefined);
214
+ const result = await mcp_gateway_1.mcpGateway.handleManageTool('manage_agents', {
215
+ instance_name: 'unknown',
216
+ action: 'create',
217
+ });
218
+ expect(result.isError).toBe(true);
219
+ expect(result.content[0].text).toContain("not found");
220
+ });
221
+ it('should error when instance is not running', async () => {
222
+ mockStateManager.getService.mockReturnValue(mockService('alpha', 'stopped'));
223
+ const result = await mcp_gateway_1.mcpGateway.handleManageTool('manage_agents', {
224
+ instance_name: 'alpha',
225
+ action: 'create',
226
+ });
227
+ expect(result.isError).toBe(true);
228
+ expect(result.content[0].text).toContain('not running');
229
+ });
230
+ it('should strip instance_name and POST to the instance backend', async () => {
231
+ mockStateManager.getService.mockReturnValue(mockService('alpha', 'running'));
232
+ const fetchMock = jest.fn().mockResolvedValue({
233
+ ok: true,
234
+ json: async () => ({
235
+ status: 'SUCCESS',
236
+ summary: 'Agent created',
237
+ execution_log: { output: 'Created agent "test"' },
238
+ }),
239
+ });
240
+ global.fetch = fetchMock;
241
+ const result = await mcp_gateway_1.mcpGateway.handleManageTool('manage_agents', {
242
+ instance_name: 'alpha',
243
+ action: 'create',
244
+ name: 'test',
245
+ });
246
+ expect(fetchMock).toHaveBeenCalledWith('http://localhost:3400/mcp-internal/execute-tool', expect.objectContaining({
247
+ method: 'POST',
248
+ body: JSON.stringify({
249
+ tool_name: 'manage_agents',
250
+ arguments: { action: 'create', name: 'test' }, // instance_name stripped
251
+ }),
252
+ }));
253
+ expect(result.isError).toBeUndefined();
254
+ expect(result.content[0].text).toContain('Created agent "test"');
255
+ });
256
+ it('should map FAILURE result to isError: true', async () => {
257
+ mockStateManager.getService.mockReturnValue(mockService('alpha', 'running'));
258
+ global.fetch = jest.fn().mockResolvedValue({
259
+ ok: true,
260
+ json: async () => ({
261
+ status: 'FAILURE',
262
+ summary: 'Validation error',
263
+ error_message: 'Name is required',
264
+ execution_log: { output: '', error_message: 'Name is required' },
265
+ }),
266
+ });
267
+ const result = await mcp_gateway_1.mcpGateway.handleManageTool('manage_agents', {
268
+ instance_name: 'alpha',
269
+ action: 'create',
270
+ });
271
+ expect(result.isError).toBe(true);
272
+ expect(result.content[0].text).toContain('Name is required');
273
+ });
274
+ it('should error when fetch to backend fails', async () => {
275
+ mockStateManager.getService.mockReturnValue(mockService('alpha', 'running'));
276
+ global.fetch = jest.fn().mockRejectedValue(new Error('ECONNREFUSED'));
277
+ const result = await mcp_gateway_1.mcpGateway.handleManageTool('manage_agents', {
278
+ instance_name: 'alpha',
279
+ action: 'create',
280
+ });
281
+ expect(result.isError).toBe(true);
282
+ expect(result.content[0].text).toContain('ECONNREFUSED');
283
+ });
284
+ it('should error when backend returns non-ok HTTP status', async () => {
285
+ mockStateManager.getService.mockReturnValue(mockService('alpha', 'running'));
286
+ global.fetch = jest.fn().mockResolvedValue({ ok: false, status: 500 });
287
+ const result = await mcp_gateway_1.mcpGateway.handleManageTool('manage_agents', {
288
+ instance_name: 'alpha',
289
+ action: 'create',
290
+ });
291
+ expect(result.isError).toBe(true);
292
+ expect(result.content[0].text).toContain('500');
293
+ });
294
+ });
295
+ });
@@ -7,7 +7,8 @@
7
7
  "scripts": {
8
8
  "build": "tsc",
9
9
  "start": "cross-env NODE_ENV=production node dist/index.js",
10
- "dev": "NODE_ENV=development ts-node-dev --respawn --transpile-only src/index.ts"
10
+ "dev": "NODE_ENV=development ts-node-dev --respawn --transpile-only src/index.ts",
11
+ "test": "jest"
11
12
  },
12
13
  "keywords": [],
13
14
  "author": "Celal Ertug",
@@ -16,9 +17,21 @@
16
17
  "@types/cors": "^2.8.17",
17
18
  "@types/express": "^4.17.21",
18
19
  "@types/fs-extra": "^11.0.4",
20
+ "@types/jest": "^29.5.14",
19
21
  "@types/node": "^20.14.9",
20
22
  "@types/ws": "^8.5.10",
23
+ "jest": "^29.7.0",
24
+ "ts-jest": "^29.4.11",
21
25
  "ts-node-dev": "^2.0.0",
22
26
  "typescript": "^5.5.2"
27
+ },
28
+ "jest": {
29
+ "moduleFileExtensions": ["js", "json", "ts"],
30
+ "rootDir": "src",
31
+ "testRegex": ".*\\.spec\\.ts$",
32
+ "transform": {
33
+ "^.+\\.(t|j)s$": ["ts-jest", { "isolatedModules": true }]
34
+ },
35
+ "testEnvironment": "node"
23
36
  }
24
- }
37
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "repoburg",
3
- "version": "1.3.163",
3
+ "version": "1.3.166",
4
4
  "description": "A local AI-powered software developer assistant that runs on your own machine.",
5
5
  "author": "Celal Ertug",
6
6
  "license": "SEE LICENSE IN LICENSE",