@almanak/mcp-server 0.2.1 → 0.2.2
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/dist/client.d.ts +65 -11
- package/dist/client.js +31 -13
- package/dist/client.js.map +1 -1
- package/dist/testing/__tests__/platform-client.test.js +48 -0
- package/dist/testing/__tests__/platform-client.test.js.map +1 -1
- package/dist/testing/__tests__/tools.test.js +0 -71
- package/dist/testing/__tests__/tools.test.js.map +1 -1
- package/dist/testing/__tests__/workspace-export-tools.test.d.ts +1 -0
- package/dist/testing/__tests__/workspace-export-tools.test.js +439 -0
- package/dist/testing/__tests__/workspace-export-tools.test.js.map +1 -0
- package/dist/tools.d.ts +28 -0
- package/dist/tools.js +354 -80
- package/dist/tools.js.map +1 -1
- package/dist/workspace-git.d.ts +91 -0
- package/dist/workspace-git.js +374 -0
- package/dist/workspace-git.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
40
|
+
const node_child_process_1 = require("node:child_process");
|
|
41
|
+
const node_fs_1 = require("node:fs");
|
|
42
|
+
const os = __importStar(require("node:os"));
|
|
43
|
+
const path = __importStar(require("node:path"));
|
|
44
|
+
const node_test_1 = require("node:test");
|
|
45
|
+
const tools_1 = require("../../tools");
|
|
46
|
+
const workspace_git_1 = require("../../workspace-git");
|
|
47
|
+
const SESSION_ID = 'f0e1d2c3-4b5a-6978-8a9b-0c1d2e3f4a5b';
|
|
48
|
+
function makeClient(opts = {}) {
|
|
49
|
+
const calls = [];
|
|
50
|
+
const client = {
|
|
51
|
+
getSessionRepoLink: async () => { var _a; return (_a = opts.sessionRepoLink) !== null && _a !== void 0 ? _a : { valid: true, data: { linked: false } }; },
|
|
52
|
+
sessionId: () => (opts.sessionId === undefined ? SESSION_ID : opts.sessionId),
|
|
53
|
+
linkSessionRepository: async (sessionId, body) => {
|
|
54
|
+
var _a;
|
|
55
|
+
calls.push({ sessionId, body });
|
|
56
|
+
return (_a = opts.linkResponse) !== null && _a !== void 0 ? _a : { valid: true, data: {} };
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
return { client, calls };
|
|
60
|
+
}
|
|
61
|
+
async function callTool(handler, name, args) {
|
|
62
|
+
const result = await handler.callTool(name, args);
|
|
63
|
+
return JSON.parse(result.content[0].text);
|
|
64
|
+
}
|
|
65
|
+
function git(cwd, ...args) {
|
|
66
|
+
return (0, node_child_process_1.execFileSync)('git', args, { cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] }).trim();
|
|
67
|
+
}
|
|
68
|
+
const tempDirs = [];
|
|
69
|
+
async function makeTempDir(prefix) {
|
|
70
|
+
const dir = await node_fs_1.promises.mkdtemp(path.join(os.tmpdir(), prefix));
|
|
71
|
+
tempDirs.push(dir);
|
|
72
|
+
// macOS-style symlinked tmp roots would break the path.relative checks in flattenRootDir.
|
|
73
|
+
return node_fs_1.promises.realpath(dir);
|
|
74
|
+
}
|
|
75
|
+
/** Bare repository the tools push to; a file:// URL bypasses the credential helper entirely. */
|
|
76
|
+
async function makeBareRemote() {
|
|
77
|
+
const dir = path.join(await makeTempDir('almanak-mcp-remote-'), 'strategy.git');
|
|
78
|
+
(0, node_child_process_1.execFileSync)('git', ['init', '-q', '--bare', dir]);
|
|
79
|
+
return { dir, cloneUrl: `file://${dir}` };
|
|
80
|
+
}
|
|
81
|
+
function linkResponse(cloneUrl, overrides = {}) {
|
|
82
|
+
return {
|
|
83
|
+
valid: true,
|
|
84
|
+
data: {
|
|
85
|
+
status: 'linked',
|
|
86
|
+
provider: 'almanak',
|
|
87
|
+
repoId: 'repo-1',
|
|
88
|
+
repoOwner: 'u-1234',
|
|
89
|
+
repoName: 'my-strategy',
|
|
90
|
+
repoUrl: 'https://git.almanak.co/u-1234/my-strategy',
|
|
91
|
+
cloneUrl,
|
|
92
|
+
gitHost: 'git.almanak.co',
|
|
93
|
+
defaultBranch: 'main',
|
|
94
|
+
strategyLinkId: 'strategy-link-1',
|
|
95
|
+
configureMode: 'credential_helper',
|
|
96
|
+
...overrides,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const originalGlobalConfig = process.env.GIT_CONFIG_GLOBAL;
|
|
101
|
+
(0, node_test_1.before)(() => {
|
|
102
|
+
// A developer's global gitconfig (commit signing, hooks path, templates) must not leak into the
|
|
103
|
+
// end-to-end runs: the tool sets its own repo-local identity and never depends on a global one.
|
|
104
|
+
process.env.GIT_CONFIG_GLOBAL = '/dev/null';
|
|
105
|
+
});
|
|
106
|
+
(0, node_test_1.after)(async () => {
|
|
107
|
+
if (originalGlobalConfig === undefined)
|
|
108
|
+
delete process.env.GIT_CONFIG_GLOBAL;
|
|
109
|
+
else
|
|
110
|
+
process.env.GIT_CONFIG_GLOBAL = originalGlobalConfig;
|
|
111
|
+
await Promise.all(tempDirs.map((dir) => node_fs_1.promises.rm(dir, { recursive: true, force: true })));
|
|
112
|
+
});
|
|
113
|
+
(0, node_test_1.describe)('strategies_export_workspace (mocked platform)', () => {
|
|
114
|
+
(0, node_test_1.test)('returns already_linked and never creates a repository when the chat is linked', async () => {
|
|
115
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
116
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'strategy.py'), 'print(1)\n');
|
|
117
|
+
const { client, calls } = makeClient({
|
|
118
|
+
sessionRepoLink: {
|
|
119
|
+
valid: true,
|
|
120
|
+
data: {
|
|
121
|
+
linked: true,
|
|
122
|
+
provider: 'almanak',
|
|
123
|
+
repoOwner: 'u-1234',
|
|
124
|
+
repoName: 'existing',
|
|
125
|
+
repoUrl: 'https://git.almanak.co/u-1234/existing',
|
|
126
|
+
cloneUrl: 'https://git.almanak.co/u-1234/existing.git',
|
|
127
|
+
defaultBranch: 'main',
|
|
128
|
+
strategyLinkId: 'strategy-link-existing',
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
133
|
+
const result = await callTool(handler, 'strategies_export_workspace', { repoName: 'another' });
|
|
134
|
+
strict_1.default.equal(result.data.status, 'already_linked');
|
|
135
|
+
strict_1.default.equal(result.data.repoOwner, 'u-1234');
|
|
136
|
+
strict_1.default.equal(result.data.repoName, 'existing');
|
|
137
|
+
strict_1.default.equal(result.data.strategyLinkId, 'strategy-link-existing');
|
|
138
|
+
strict_1.default.equal(result.data.provider, 'almanak');
|
|
139
|
+
strict_1.default.match(result.data.message, /git add\/commit\/push/);
|
|
140
|
+
strict_1.default.equal(calls.length, 0);
|
|
141
|
+
strict_1.default.equal(await node_fs_1.promises.stat(path.join(workspace, '.git')).catch(() => null), null, 'must not touch git');
|
|
142
|
+
});
|
|
143
|
+
(0, node_test_1.test)('maps a 409 name_conflict from the backend', async () => {
|
|
144
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
145
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'strategy.py'), 'print(1)\n');
|
|
146
|
+
const { client, calls } = makeClient({
|
|
147
|
+
linkResponse: { valid: false, statusCode: 409, errorCode: 'name_conflict', error: 'A repository named my-strategy already exists.' },
|
|
148
|
+
});
|
|
149
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
150
|
+
const result = await callTool(handler, 'strategies_export_workspace', { repoName: 'my-strategy', description: 'desc', provider: 'almanak' });
|
|
151
|
+
strict_1.default.equal(result.data.status, 'name_conflict');
|
|
152
|
+
strict_1.default.match(result.data.message, /already exists/);
|
|
153
|
+
strict_1.default.match(result.data.message, /different repoName/);
|
|
154
|
+
strict_1.default.deepEqual(calls, [
|
|
155
|
+
{ sessionId: SESSION_ID, body: { create: { repoName: 'my-strategy', description: 'desc', provider: 'almanak' } } },
|
|
156
|
+
]);
|
|
157
|
+
});
|
|
158
|
+
(0, node_test_1.test)('maps the other backend error codes', async () => {
|
|
159
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
160
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'strategy.py'), 'print(1)\n');
|
|
161
|
+
const cases = [
|
|
162
|
+
['github_connection_required', 'github_connection_required'],
|
|
163
|
+
['provider_disabled', 'provider_disabled'],
|
|
164
|
+
['repo_config_in_progress', 'in_progress'],
|
|
165
|
+
];
|
|
166
|
+
for (const [errorCode, status] of cases) {
|
|
167
|
+
const { client } = makeClient({ linkResponse: { valid: false, statusCode: 403, errorCode, error: 'nope' } });
|
|
168
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
169
|
+
const result = await callTool(handler, 'strategies_export_workspace', { repoName: 'x' });
|
|
170
|
+
strict_1.default.equal(result.data.status, status, errorCode);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
(0, node_test_1.test)('fails preflight on an empty workspace without calling the backend', async () => {
|
|
174
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
175
|
+
// Only session-internal / skipped content: nothing exportable.
|
|
176
|
+
await node_fs_1.promises.mkdir(path.join(workspace, '.almanak'), { recursive: true });
|
|
177
|
+
await node_fs_1.promises.writeFile(path.join(workspace, '.almanak', 'session.json'), '{}');
|
|
178
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'almanak_state.db'), '');
|
|
179
|
+
await node_fs_1.promises.writeFile(path.join(workspace, '.env'), 'SECRET=1');
|
|
180
|
+
await node_fs_1.promises.mkdir(path.join(workspace, '.venv', 'lib'), { recursive: true });
|
|
181
|
+
await node_fs_1.promises.writeFile(path.join(workspace, '.venv', 'lib', 'x.py'), '');
|
|
182
|
+
const { client, calls } = makeClient();
|
|
183
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
184
|
+
const result = await callTool(handler, 'strategies_export_workspace', { repoName: 'x' });
|
|
185
|
+
strict_1.default.equal(result.data.status, 'preflight_failed');
|
|
186
|
+
strict_1.default.match(result.data.message, /No exportable files/);
|
|
187
|
+
strict_1.default.equal(calls.length, 0);
|
|
188
|
+
});
|
|
189
|
+
(0, node_test_1.test)('rejects an invalid rootDir as preflight_failed', async () => {
|
|
190
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
191
|
+
const { client, calls } = makeClient();
|
|
192
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
193
|
+
const result = await callTool(handler, 'strategies_export_workspace', { repoName: 'x', rootDir: '../outside' });
|
|
194
|
+
strict_1.default.equal(result.data.status, 'preflight_failed');
|
|
195
|
+
strict_1.default.match(result.data.message, /Invalid rootDir/);
|
|
196
|
+
strict_1.default.equal(calls.length, 0);
|
|
197
|
+
});
|
|
198
|
+
(0, node_test_1.test)('refuses to flatten a rootDir whose entries collide with the workspace root', async () => {
|
|
199
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
200
|
+
await node_fs_1.promises.mkdir(path.join(workspace, 'my_strategy'));
|
|
201
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'my_strategy', 'strategy.py'), 'new\n');
|
|
202
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'my_strategy', 'config.json'), '{}');
|
|
203
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'strategy.py'), 'old\n');
|
|
204
|
+
const { client, calls } = makeClient();
|
|
205
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
206
|
+
const result = await callTool(handler, 'strategies_export_workspace', { repoName: 'x', rootDir: 'my_strategy' });
|
|
207
|
+
strict_1.default.equal(result.data.status, 'preflight_failed');
|
|
208
|
+
strict_1.default.match(result.data.message, /strategy\.py already exist/);
|
|
209
|
+
strict_1.default.equal(calls.length, 0);
|
|
210
|
+
// Nothing moved: the refusal happens before any rename.
|
|
211
|
+
strict_1.default.equal(await node_fs_1.promises.readFile(path.join(workspace, 'strategy.py'), 'utf-8'), 'old\n');
|
|
212
|
+
strict_1.default.equal(await node_fs_1.promises.readFile(path.join(workspace, 'my_strategy', 'strategy.py'), 'utf-8'), 'new\n');
|
|
213
|
+
strict_1.default.equal(await node_fs_1.promises.stat(path.join(workspace, 'config.json')).catch(() => null), null);
|
|
214
|
+
});
|
|
215
|
+
(0, node_test_1.test)('refuses when the platform token has no session id', async () => {
|
|
216
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
217
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'strategy.py'), 'print(1)\n');
|
|
218
|
+
const { client, calls } = makeClient({ sessionId: null });
|
|
219
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
220
|
+
const result = await callTool(handler, 'strategies_export_workspace', { repoName: 'x' });
|
|
221
|
+
strict_1.default.equal(result.data.status, 'failed');
|
|
222
|
+
strict_1.default.match(result.data.error, /agentSessionId/);
|
|
223
|
+
strict_1.default.equal(calls.length, 0);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
(0, node_test_1.describe)('strategies_export_workspace rootDir normalization', () => {
|
|
227
|
+
// A name_conflict reply stops the export right after the link call, so these cases can
|
|
228
|
+
// observe how rootDir was interpreted (flattened or not) without touching git.
|
|
229
|
+
const conflict = { valid: false, statusCode: 409, errorCode: 'name_conflict', error: 'taken' };
|
|
230
|
+
async function workspaceWithStrategy(subdir) {
|
|
231
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
232
|
+
const dir = subdir ? path.join(workspace, subdir) : workspace;
|
|
233
|
+
await node_fs_1.promises.mkdir(dir, { recursive: true });
|
|
234
|
+
await node_fs_1.promises.writeFile(path.join(dir, 'strategy.py'), 'print(1)\n');
|
|
235
|
+
return workspace;
|
|
236
|
+
}
|
|
237
|
+
async function exportWith(workspace, rootDir) {
|
|
238
|
+
const { client, calls } = makeClient({ linkResponse: conflict });
|
|
239
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
240
|
+
const result = await callTool(handler, 'strategies_export_workspace', { repoName: 'x', rootDir });
|
|
241
|
+
return { result, calls };
|
|
242
|
+
}
|
|
243
|
+
(0, node_test_1.test)('normalizes workspace-absolute paths with non-UUID session ids', async () => {
|
|
244
|
+
const workspace = await workspaceWithStrategy('morpho_blue_susds_liquidation');
|
|
245
|
+
const { result, calls } = await exportWith(workspace, '/tmp/workspaces/session_abc-123/morpho_blue_susds_liquidation/');
|
|
246
|
+
strict_1.default.equal(result.data.status, 'name_conflict');
|
|
247
|
+
strict_1.default.equal(calls.length, 1);
|
|
248
|
+
strict_1.default.equal(await node_fs_1.promises.readFile(path.join(workspace, 'strategy.py'), 'utf-8'), 'print(1)\n', 'subfolder must be flattened');
|
|
249
|
+
});
|
|
250
|
+
(0, node_test_1.test)('treats the bare workspace root as no rootDir (ALM-3357)', async () => {
|
|
251
|
+
const workspace = await workspaceWithStrategy();
|
|
252
|
+
const { result, calls } = await exportWith(workspace, '/tmp/workspaces/01e61670-119d-4091-871e-2368fdf38f5c');
|
|
253
|
+
strict_1.default.equal(result.data.status, 'name_conflict');
|
|
254
|
+
strict_1.default.equal(calls.length, 1);
|
|
255
|
+
});
|
|
256
|
+
(0, node_test_1.test)('treats the workspace root with trailing slash as no rootDir', async () => {
|
|
257
|
+
const workspace = await workspaceWithStrategy();
|
|
258
|
+
const { result, calls } = await exportWith(workspace, '/workspaces/session_abc-123/');
|
|
259
|
+
strict_1.default.equal(result.data.status, 'name_conflict');
|
|
260
|
+
strict_1.default.equal(calls.length, 1);
|
|
261
|
+
});
|
|
262
|
+
(0, node_test_1.test)('rejects nested internal directories', async () => {
|
|
263
|
+
const workspace = await workspaceWithStrategy('morpho_blue_susds_liquidation');
|
|
264
|
+
const { result, calls } = await exportWith(workspace, 'morpho_blue_susds_liquidation/.git/config');
|
|
265
|
+
strict_1.default.equal(result.data.status, 'preflight_failed');
|
|
266
|
+
strict_1.default.match(result.data.message, /Invalid rootDir/);
|
|
267
|
+
strict_1.default.equal(calls.length, 0);
|
|
268
|
+
});
|
|
269
|
+
(0, node_test_1.test)('normalizes valid relative strategy folders', async () => {
|
|
270
|
+
const workspace = await workspaceWithStrategy('morpho_blue_susds_liquidation');
|
|
271
|
+
const { result, calls } = await exportWith(workspace, './morpho_blue_susds_liquidation/');
|
|
272
|
+
strict_1.default.equal(result.data.status, 'name_conflict');
|
|
273
|
+
strict_1.default.equal(calls.length, 1);
|
|
274
|
+
strict_1.default.equal(await node_fs_1.promises.readFile(path.join(workspace, 'strategy.py'), 'utf-8'), 'print(1)\n', 'subfolder must be flattened');
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
(0, node_test_1.describe)('strategies_export_workspace (real git)', () => {
|
|
278
|
+
(0, node_test_1.test)('inits, commits, pushes the workspace to the linked repository and returns the sha', async () => {
|
|
279
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
280
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'strategy.py'), 'print("hello")\n');
|
|
281
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'config.json'), '{"chain":"base"}\n');
|
|
282
|
+
await node_fs_1.promises.writeFile(path.join(workspace, '.env'), 'SECRET=1\n');
|
|
283
|
+
await node_fs_1.promises.writeFile(path.join(workspace, '.env.example'), 'SECRET=\n');
|
|
284
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'almanak_state.db'), 'sqlite\n');
|
|
285
|
+
await node_fs_1.promises.mkdir(path.join(workspace, '.almanak'));
|
|
286
|
+
await node_fs_1.promises.writeFile(path.join(workspace, '.almanak', 'session.json'), '{}');
|
|
287
|
+
await node_fs_1.promises.mkdir(path.join(workspace, '.venv'));
|
|
288
|
+
await node_fs_1.promises.writeFile(path.join(workspace, '.venv', 'pyvenv.cfg'), '');
|
|
289
|
+
const remote = await makeBareRemote();
|
|
290
|
+
const { client, calls } = makeClient({ linkResponse: linkResponse(remote.cloneUrl) });
|
|
291
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
292
|
+
const result = await callTool(handler, 'strategies_export_workspace', { repoName: 'my-strategy', description: 'A strategy' });
|
|
293
|
+
strict_1.default.equal(result.data.status, 'completed', JSON.stringify(result));
|
|
294
|
+
strict_1.default.equal(result.data.branch, 'main');
|
|
295
|
+
strict_1.default.equal(result.data.provider, 'almanak');
|
|
296
|
+
strict_1.default.equal(result.data.repoOwner, 'u-1234');
|
|
297
|
+
strict_1.default.equal(result.data.repoName, 'my-strategy');
|
|
298
|
+
strict_1.default.equal(result.data.repoUrl, 'https://git.almanak.co/u-1234/my-strategy');
|
|
299
|
+
strict_1.default.equal(result.data.strategyLinkId, 'strategy-link-1');
|
|
300
|
+
strict_1.default.match(result.data.commitSha, /^[0-9a-f]{40}$/);
|
|
301
|
+
strict_1.default.equal(calls.length, 1);
|
|
302
|
+
strict_1.default.equal(calls[0].sessionId, SESSION_ID);
|
|
303
|
+
// The bare remote received exactly that commit on main, with the skip rules applied.
|
|
304
|
+
strict_1.default.equal(git(remote.dir, 'rev-parse', 'refs/heads/main'), result.data.commitSha);
|
|
305
|
+
const tree = git(remote.dir, 'ls-tree', '-r', '--name-only', 'main').split('\n').sort();
|
|
306
|
+
strict_1.default.deepEqual(tree, ['.env.example', 'config.json', 'strategy.py']);
|
|
307
|
+
strict_1.default.equal(git(remote.dir, 'log', '-1', '--format=%s %an <%ae>', 'main'), 'feat: initial strategy export from Almanak Almanak Code <code@almanak.co>');
|
|
308
|
+
// The workspace is now a checkout tracking origin/main with the managed excludes in place.
|
|
309
|
+
strict_1.default.equal(git(workspace, 'rev-parse', 'HEAD'), result.data.commitSha);
|
|
310
|
+
strict_1.default.equal(git(workspace, 'rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'), 'origin/main');
|
|
311
|
+
strict_1.default.equal(git(workspace, 'remote', 'get-url', 'origin'), remote.cloneUrl);
|
|
312
|
+
const exclude = await node_fs_1.promises.readFile(path.join(workspace, '.git', 'info', 'exclude'), 'utf-8');
|
|
313
|
+
strict_1.default.ok(exclude.includes(workspace_git_1.MANDATORY_GIT_EXCLUDES_BLOCK_START));
|
|
314
|
+
strict_1.default.ok(exclude.includes('almanak_state.db.gw.session'));
|
|
315
|
+
strict_1.default.equal(git(workspace, 'status', '--porcelain'), '', 'internal files must be ignored, not left untracked');
|
|
316
|
+
// Internal files stayed on disk.
|
|
317
|
+
strict_1.default.equal(await node_fs_1.promises.readFile(path.join(workspace, 'almanak_state.db'), 'utf-8'), 'sqlite\n');
|
|
318
|
+
});
|
|
319
|
+
(0, node_test_1.test)('flattens rootDir into the workspace root before exporting', async () => {
|
|
320
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
321
|
+
await node_fs_1.promises.mkdir(path.join(workspace, 'my_strategy', 'lib'), { recursive: true });
|
|
322
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'my_strategy', 'strategy.py'), 'print(1)\n');
|
|
323
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'my_strategy', 'lib', 'util.py'), 'x = 1\n');
|
|
324
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'my_strategy', '.gitignore'), '*.log\n');
|
|
325
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'almanak_state.db'), '');
|
|
326
|
+
const remote = await makeBareRemote();
|
|
327
|
+
const { client } = makeClient({ linkResponse: linkResponse(remote.cloneUrl) });
|
|
328
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
329
|
+
const result = await callTool(handler, 'strategies_export_workspace', {
|
|
330
|
+
repoName: 'my-strategy',
|
|
331
|
+
rootDir: `/tmp/workspaces/${SESSION_ID}/my_strategy/`,
|
|
332
|
+
});
|
|
333
|
+
strict_1.default.equal(result.data.status, 'completed', JSON.stringify(result));
|
|
334
|
+
strict_1.default.equal(await node_fs_1.promises.stat(path.join(workspace, 'my_strategy')).catch(() => null), null, 'emptied rootDir is removed');
|
|
335
|
+
strict_1.default.equal(await node_fs_1.promises.readFile(path.join(workspace, 'strategy.py'), 'utf-8'), 'print(1)\n');
|
|
336
|
+
const tree = git(remote.dir, 'ls-tree', '-r', '--name-only', 'main').split('\n').sort();
|
|
337
|
+
strict_1.default.deepEqual(tree, ['.gitignore', 'lib/util.py', 'strategy.py']);
|
|
338
|
+
});
|
|
339
|
+
(0, node_test_1.test)('reports linked_push_failed (and keeps the link) when the push is rejected', async () => {
|
|
340
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
341
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'strategy.py'), 'print(1)\n');
|
|
342
|
+
// A clone URL nobody serves: the link succeeded, the push cannot.
|
|
343
|
+
const missing = path.join(await makeTempDir('almanak-mcp-missing-'), 'nope.git');
|
|
344
|
+
const { client } = makeClient({ linkResponse: linkResponse(`file://${missing}`) });
|
|
345
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
346
|
+
const result = await callTool(handler, 'strategies_export_workspace', { repoName: 'my-strategy' });
|
|
347
|
+
strict_1.default.equal(result.data.status, 'linked_push_failed', JSON.stringify(result));
|
|
348
|
+
strict_1.default.equal(result.data.branch, 'main');
|
|
349
|
+
strict_1.default.equal(result.data.strategyLinkId, 'strategy-link-1');
|
|
350
|
+
strict_1.default.equal(result.data.cloneUrl, `file://${missing}`);
|
|
351
|
+
strict_1.default.match(result.data.error, /git push/);
|
|
352
|
+
strict_1.default.match(result.data.message, /git push -u origin main/);
|
|
353
|
+
// The local commit exists so a manual push can succeed once the remote is fixed.
|
|
354
|
+
strict_1.default.match(git(workspace, 'rev-parse', 'HEAD'), /^[0-9a-f]{40}$/);
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
(0, node_test_1.describe)('strategies_link_workspace (real git)', () => {
|
|
358
|
+
async function seedRemote() {
|
|
359
|
+
const remote = await makeBareRemote();
|
|
360
|
+
const seed = await makeTempDir('almanak-mcp-seed-');
|
|
361
|
+
git(seed, 'init', '-q');
|
|
362
|
+
git(seed, 'symbolic-ref', 'HEAD', 'refs/heads/main');
|
|
363
|
+
git(seed, 'config', 'user.name', 'Seed');
|
|
364
|
+
git(seed, 'config', 'user.email', 'seed@example.com');
|
|
365
|
+
await node_fs_1.promises.writeFile(path.join(seed, 'strategy.py'), 'print("remote")\n');
|
|
366
|
+
git(seed, 'add', '-A');
|
|
367
|
+
git(seed, 'commit', '-q', '-m', 'seed');
|
|
368
|
+
git(seed, 'push', '-q', remote.cloneUrl, 'main');
|
|
369
|
+
return { ...remote, sha: git(seed, 'rev-parse', 'HEAD') };
|
|
370
|
+
}
|
|
371
|
+
(0, node_test_1.test)('clones the default branch into an empty workspace', async () => {
|
|
372
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
373
|
+
await node_fs_1.promises.mkdir(path.join(workspace, '.almanak'));
|
|
374
|
+
await node_fs_1.promises.writeFile(path.join(workspace, '.almanak', 'session.json'), '{}');
|
|
375
|
+
const remote = await seedRemote();
|
|
376
|
+
const { client, calls } = makeClient({ linkResponse: linkResponse(remote.cloneUrl) });
|
|
377
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
378
|
+
const result = await callTool(handler, 'strategies_link_workspace', { strategy_link_id: 'strategy-link-1' });
|
|
379
|
+
strict_1.default.equal(result.data.status, 'linked', JSON.stringify(result));
|
|
380
|
+
strict_1.default.equal(result.data.branch, 'main');
|
|
381
|
+
strict_1.default.equal(result.data.strategyLinkId, 'strategy-link-1');
|
|
382
|
+
strict_1.default.deepEqual(calls, [{ sessionId: SESSION_ID, body: { strategyLinkId: 'strategy-link-1' } }]);
|
|
383
|
+
strict_1.default.equal(git(workspace, 'rev-parse', 'HEAD'), remote.sha);
|
|
384
|
+
strict_1.default.equal(await node_fs_1.promises.readFile(path.join(workspace, 'strategy.py'), 'utf-8'), 'print("remote")\n');
|
|
385
|
+
strict_1.default.equal(git(workspace, 'status', '--porcelain'), '');
|
|
386
|
+
});
|
|
387
|
+
(0, node_test_1.test)('keeps existing user files uncommitted on a session branch instead of overwriting them', async () => {
|
|
388
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
389
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'strategy.py'), 'print("local")\n');
|
|
390
|
+
const remote = await seedRemote();
|
|
391
|
+
const { client } = makeClient({ linkResponse: linkResponse(remote.cloneUrl) });
|
|
392
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
393
|
+
const result = await callTool(handler, 'strategies_link_workspace', { strategy_link_id: 'strategy-link-1' });
|
|
394
|
+
strict_1.default.equal(result.data.status, 'linked', JSON.stringify(result));
|
|
395
|
+
strict_1.default.equal(result.data.branch, `almanak/session-${SESSION_ID.slice(0, 8)}`);
|
|
396
|
+
strict_1.default.match(result.data.message, /NOT overwritten/);
|
|
397
|
+
strict_1.default.equal(await node_fs_1.promises.readFile(path.join(workspace, 'strategy.py'), 'utf-8'), 'print("local")\n');
|
|
398
|
+
strict_1.default.equal(git(workspace, 'symbolic-ref', '--short', 'HEAD'), `almanak/session-${SESSION_ID.slice(0, 8)}`);
|
|
399
|
+
strict_1.default.equal(git(workspace, 'status', '--porcelain'), '?? strategy.py');
|
|
400
|
+
strict_1.default.equal(git(workspace, 'rev-parse', 'refs/remotes/origin/main'), remote.sha);
|
|
401
|
+
});
|
|
402
|
+
(0, node_test_1.test)('only repoints origin when the workspace is already a git repository', async () => {
|
|
403
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
404
|
+
git(workspace, 'init', '-q');
|
|
405
|
+
git(workspace, 'symbolic-ref', 'HEAD', 'refs/heads/work');
|
|
406
|
+
git(workspace, 'remote', 'add', 'origin', 'https://example.invalid/old.git');
|
|
407
|
+
await node_fs_1.promises.writeFile(path.join(workspace, 'strategy.py'), 'x\n');
|
|
408
|
+
const remote = await seedRemote();
|
|
409
|
+
const { client } = makeClient({ linkResponse: linkResponse(remote.cloneUrl, { status: 'already_linked' }) });
|
|
410
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
411
|
+
const result = await callTool(handler, 'strategies_link_workspace', { strategy_link_id: 'strategy-link-1' });
|
|
412
|
+
strict_1.default.equal(result.data.status, 'already_linked');
|
|
413
|
+
strict_1.default.equal(result.data.branch, 'work');
|
|
414
|
+
strict_1.default.equal(git(workspace, 'remote', 'get-url', 'origin'), remote.cloneUrl);
|
|
415
|
+
strict_1.default.equal(git(workspace, 'status', '--porcelain'), '?? strategy.py');
|
|
416
|
+
});
|
|
417
|
+
(0, node_test_1.test)('does not touch git when the chat is linked to a different strategy', async () => {
|
|
418
|
+
const workspace = await makeTempDir('almanak-mcp-ws-');
|
|
419
|
+
const { client } = makeClient({
|
|
420
|
+
linkResponse: linkResponse('https://git.almanak.co/u-1234/other.git', { status: 'already_linked', strategyLinkId: 'strategy-link-other' }),
|
|
421
|
+
});
|
|
422
|
+
const handler = new tools_1.PlatformToolHandler(client, { modes: ['strategies'], workspaceRoot: workspace });
|
|
423
|
+
const result = await callTool(handler, 'strategies_link_workspace', { strategy_link_id: 'strategy-link-1' });
|
|
424
|
+
strict_1.default.equal(result.data.status, 'already_linked');
|
|
425
|
+
strict_1.default.equal(result.data.strategyLinkId, 'strategy-link-other');
|
|
426
|
+
strict_1.default.equal(await node_fs_1.promises.stat(path.join(workspace, '.git')).catch(() => null), null);
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
(0, node_test_1.describe)('redactSecrets', () => {
|
|
430
|
+
(0, node_test_1.test)('strips URL userinfo and token-like strings from git diagnostics', () => {
|
|
431
|
+
const stderr = 'fatal: unable to access https://x-access-token:ghp_abcdefghijklmnopqrstuvwxyz0123456789@github.com/o/r.git: 403';
|
|
432
|
+
const redacted = (0, workspace_git_1.redactSecrets)(stderr);
|
|
433
|
+
strict_1.default.ok(!redacted.includes('ghp_'));
|
|
434
|
+
strict_1.default.ok(redacted.includes('https://***@github.com/o/r.git'));
|
|
435
|
+
strict_1.default.equal((0, workspace_git_1.redactSecrets)('token: ' + 'A'.repeat(40)), 'token: [redacted]');
|
|
436
|
+
strict_1.default.equal((0, workspace_git_1.redactSecrets)('short abc123'), 'short abc123');
|
|
437
|
+
});
|
|
438
|
+
});
|
|
439
|
+
//# sourceMappingURL=workspace-export-tools.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-export-tools.test.js","sourceRoot":"","sources":["../../../src/testing/__tests__/workspace-export-tools.test.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.d.ts
CHANGED
|
@@ -29,6 +29,12 @@ export interface ToolHandlerOptions {
|
|
|
29
29
|
* call time instead of failing at construction.
|
|
30
30
|
*/
|
|
31
31
|
testController?: TestControllerClient | null;
|
|
32
|
+
/**
|
|
33
|
+
* Session workspace root the git-backed tools operate in. Defaults to
|
|
34
|
+
* ``process.cwd()``: almanak-code spawns stdio MCP servers without a cwd
|
|
35
|
+
* override, so the server inherits the worker's ``--cwd <workspaceDir>``.
|
|
36
|
+
*/
|
|
37
|
+
workspaceRoot?: string;
|
|
32
38
|
}
|
|
33
39
|
export declare class PlatformToolHandler implements McpServerHandler {
|
|
34
40
|
private client;
|
|
@@ -47,6 +53,28 @@ export declare class PlatformToolHandler implements McpServerHandler {
|
|
|
47
53
|
* is unavailable. Best effort by design: a failed check must never block the export flow.
|
|
48
54
|
*/
|
|
49
55
|
private getLinkedSessionRepo;
|
|
56
|
+
/** Workspace root for git-backed tools (see ToolHandlerOptions.workspaceRoot). */
|
|
57
|
+
private get workspaceRoot();
|
|
58
|
+
private gitOpts;
|
|
59
|
+
/**
|
|
60
|
+
* Map a failed `POST /agent-sessions/{id}/repository` response to the tool's status vocabulary.
|
|
61
|
+
* Returns null when the response is a success.
|
|
62
|
+
*/
|
|
63
|
+
private mapLinkFailure;
|
|
64
|
+
/**
|
|
65
|
+
* strategies_export_workspace: create + link a new repository, then init/commit/push the
|
|
66
|
+
* workspace from inside this call. Every step is synchronous so the agent can continue in
|
|
67
|
+
* the same turn on `completed`.
|
|
68
|
+
*/
|
|
69
|
+
private exportWorkspace;
|
|
70
|
+
private alreadyLinkedResult;
|
|
71
|
+
private linkedPushFailed;
|
|
72
|
+
/**
|
|
73
|
+
* strategies_link_workspace: attach the chat to an existing strategy link and wire the
|
|
74
|
+
* workspace to its repository with git (clone into an empty workspace, or fetch + new branch
|
|
75
|
+
* when user files exist so nothing is overwritten).
|
|
76
|
+
*/
|
|
77
|
+
private linkWorkspace;
|
|
50
78
|
private register;
|
|
51
79
|
private registerAll;
|
|
52
80
|
/**
|