@agentbridge1/cli 0.0.7 → 0.0.8
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/build-info.json +4 -4
- package/dist/commands/connect.js +58 -122
- package/dist/commands/doctor.js +46 -8
- package/dist/commands/setup-mcp.js +54 -44
- package/dist/commands/start.js +85 -22
- package/dist/commands/watch.js +661 -92
- package/dist/contract-verdict.js +186 -0
- package/dist/error-catalog.js +29 -0
- package/dist/git-status.js +6 -2
- package/dist/index.js +11 -5
- package/dist/intent-validation.js +37 -0
- package/dist/local-proof.js +12 -4
- package/dist/mcp/agentbridge-mcp.js +602 -23
- package/dist/mcp/agentbridge-mcp.js.map +4 -4
- package/dist/mcp-config.js +64 -0
- package/dist/supervision.js +191 -48
- package/dist/test-runner.js +201 -15
- package/package.json +1 -1
package/dist/build-info.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"builtAt": "2026-06-
|
|
3
|
-
"gitHead": "
|
|
4
|
-
"sourceLatestMtime": "2026-06-
|
|
5
|
-
"sourceLatestFile": "src/commands/
|
|
2
|
+
"builtAt": "2026-06-20T05:37:34.216Z",
|
|
3
|
+
"gitHead": "fb83b92",
|
|
4
|
+
"sourceLatestMtime": "2026-06-20T04:44:28.305Z",
|
|
5
|
+
"sourceLatestFile": "src/commands/setup-mcp.ts"
|
|
6
6
|
}
|
package/dist/commands/connect.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.runConnect = runConnect;
|
|
|
4
4
|
const config_1 = require("../config");
|
|
5
5
|
const errors_1 = require("../errors");
|
|
6
6
|
const http_1 = require("../http");
|
|
7
|
+
const install_rules_1 = require("./install-rules");
|
|
8
|
+
const mcp_config_1 = require("../mcp-config");
|
|
7
9
|
function resolveBaseUrl(override) {
|
|
8
10
|
return (override ??
|
|
9
11
|
process.env.AGENTBRIDGE_BASE_URL ??
|
|
@@ -132,64 +134,12 @@ async function resolveExecutionSurfaceFromHello(projectId, apiKey, apiBaseUrl) {
|
|
|
132
134
|
};
|
|
133
135
|
}
|
|
134
136
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
Authorization: `Bearer ${apiKey}`,
|
|
142
|
-
"Content-Type": "application/json",
|
|
143
|
-
},
|
|
144
|
-
body: JSON.stringify({}),
|
|
145
|
-
});
|
|
146
|
-
if (!res.ok)
|
|
147
|
-
return { ok: false, status: res.status, reason: `http_${res.status}` };
|
|
148
|
-
const body = (await res.json());
|
|
149
|
-
const nextApiKey = body.api_key?.trim();
|
|
150
|
-
const executionSurfaceId = body.execution_surface_id?.trim();
|
|
151
|
-
if (!nextApiKey || !executionSurfaceId) {
|
|
152
|
-
return { ok: false, status: 200, reason: "invalid_payload" };
|
|
153
|
-
}
|
|
154
|
-
return { ok: true, apiKey: nextApiKey, executionSurfaceId };
|
|
155
|
-
}
|
|
156
|
-
catch {
|
|
157
|
-
return { ok: false, status: 0, reason: "network_error" };
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
async function rotateActiveConnectionKey(projectId, apiKey, apiBaseUrl) {
|
|
161
|
-
const listUrl = `${apiBaseUrl}/v1/dev/projects/${projectId}/connections`;
|
|
162
|
-
try {
|
|
163
|
-
const listRes = await fetch(listUrl, {
|
|
164
|
-
headers: { Authorization: `Bearer ${apiKey}` },
|
|
165
|
-
});
|
|
166
|
-
if (!listRes.ok)
|
|
167
|
-
return { ok: false, reason: `list_http_${listRes.status}` };
|
|
168
|
-
const listBody = (await listRes.json());
|
|
169
|
-
const activeConnection = (listBody.connections ?? []).find((connection) => connection?.id && connection?.status === "active");
|
|
170
|
-
if (!activeConnection?.id)
|
|
171
|
-
return { ok: false, reason: "no_active_connection" };
|
|
172
|
-
const rotateUrl = `${apiBaseUrl}/v1/dev/projects/${projectId}/connections/${activeConnection.id}/rotate-key`;
|
|
173
|
-
const rotateRes = await fetch(rotateUrl, {
|
|
174
|
-
method: "POST",
|
|
175
|
-
headers: {
|
|
176
|
-
Authorization: `Bearer ${apiKey}`,
|
|
177
|
-
"Content-Type": "application/json",
|
|
178
|
-
},
|
|
179
|
-
body: JSON.stringify({}),
|
|
180
|
-
});
|
|
181
|
-
if (!rotateRes.ok)
|
|
182
|
-
return { ok: false, reason: `rotate_http_${rotateRes.status}` };
|
|
183
|
-
const rotateBody = (await rotateRes.json());
|
|
184
|
-
const rotatedApiKey = rotateBody.api_key?.trim();
|
|
185
|
-
const executionSurfaceId = rotateBody.connection?.execution_surface?.id?.trim();
|
|
186
|
-
if (!rotatedApiKey || !executionSurfaceId)
|
|
187
|
-
return { ok: false, reason: "invalid_payload" };
|
|
188
|
-
return { ok: true, apiKey: rotatedApiKey, executionSurfaceId };
|
|
189
|
-
}
|
|
190
|
-
catch {
|
|
191
|
-
return { ok: false, reason: "network_error" };
|
|
192
|
-
}
|
|
137
|
+
/**
|
|
138
|
+
* Merge the AgentBridge MCP server entry into .cursor/mcp.json (project-level).
|
|
139
|
+
* Preserves any other MCP servers already configured.
|
|
140
|
+
*/
|
|
141
|
+
function writeMcpConfig(projectId, apiKey, apiBaseUrl) {
|
|
142
|
+
return (0, mcp_config_1.writeServerMcpConfig)(projectId, apiKey, apiBaseUrl);
|
|
193
143
|
}
|
|
194
144
|
async function runConnect(options = {}) {
|
|
195
145
|
process.stdout.write("AgentBridge connect\n");
|
|
@@ -249,89 +199,67 @@ async function runConnect(options = {}) {
|
|
|
249
199
|
throw err;
|
|
250
200
|
}
|
|
251
201
|
process.stdout.write("OK\n");
|
|
252
|
-
let effectiveApiKey = apiKey;
|
|
253
202
|
const diagnostics = {
|
|
254
203
|
helloIdentityModel: "unknown",
|
|
255
204
|
helloStatus: "not_attempted",
|
|
256
|
-
bootstrapStatus: "not_attempted",
|
|
257
|
-
rotateStatus: "not_attempted",
|
|
258
205
|
};
|
|
259
|
-
const helloResolution = await resolveExecutionSurfaceFromHello(projectId,
|
|
206
|
+
const helloResolution = await resolveExecutionSurfaceFromHello(projectId, apiKey, apiBaseUrl);
|
|
260
207
|
diagnostics.helloIdentityModel = helloResolution.identityModel;
|
|
261
208
|
diagnostics.helloStatus = helloResolution.status;
|
|
262
|
-
|
|
263
|
-
let connectionUpgraded = false;
|
|
264
|
-
if (!executionSurfaceId) {
|
|
265
|
-
diagnostics.bootstrapStatus = "attempted";
|
|
266
|
-
const bootstrapAttempt = await bootstrapDefaultConnection(projectId, effectiveApiKey, apiBaseUrl);
|
|
267
|
-
if (bootstrapAttempt.ok) {
|
|
268
|
-
effectiveApiKey = bootstrapAttempt.apiKey;
|
|
269
|
-
executionSurfaceId = bootstrapAttempt.executionSurfaceId;
|
|
270
|
-
diagnostics.bootstrapStatus = "ok";
|
|
271
|
-
diagnostics.rotateStatus = "skipped";
|
|
272
|
-
connectionUpgraded = true;
|
|
273
|
-
}
|
|
274
|
-
else if (bootstrapAttempt.status === 409) {
|
|
275
|
-
diagnostics.bootstrapStatus = "http_409_existing_connection";
|
|
276
|
-
const rotated = await rotateActiveConnectionKey(projectId, effectiveApiKey, apiBaseUrl);
|
|
277
|
-
if (rotated.ok) {
|
|
278
|
-
diagnostics.rotateStatus = "ok";
|
|
279
|
-
effectiveApiKey = rotated.apiKey;
|
|
280
|
-
executionSurfaceId = rotated.executionSurfaceId;
|
|
281
|
-
connectionUpgraded = true;
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
diagnostics.rotateStatus = rotated.reason;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
diagnostics.bootstrapStatus = bootstrapAttempt.reason;
|
|
289
|
-
diagnostics.rotateStatus = "skipped";
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
else {
|
|
293
|
-
diagnostics.bootstrapStatus = "skipped";
|
|
294
|
-
diagnostics.rotateStatus = "skipped";
|
|
295
|
-
}
|
|
296
|
-
if (connectionUpgraded) {
|
|
297
|
-
await verifyCredentials(projectId, effectiveApiKey, apiBaseUrl);
|
|
298
|
-
}
|
|
209
|
+
const executionSurfaceId = helloResolution.executionSurfaceId;
|
|
299
210
|
if (!executionSurfaceId) {
|
|
300
211
|
(0, config_1.updateConfig)({
|
|
301
212
|
projectId,
|
|
302
|
-
apiKey
|
|
213
|
+
apiKey,
|
|
303
214
|
apiBaseUrl,
|
|
304
215
|
});
|
|
305
|
-
|
|
306
|
-
"
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
216
|
+
const helloWhy = helloResolution.identityModel === "legacy"
|
|
217
|
+
? "This API key is a legacy project agent key, not a room connection key from room create or rotate."
|
|
218
|
+
: helloResolution.status === "unknown_identity_model"
|
|
219
|
+
? "The server /hello response did not include identity_model work_identity for this key."
|
|
220
|
+
: helloResolution.status === "missing_execution_surface"
|
|
221
|
+
? "/hello returned work_identity but no execution_surface.id."
|
|
222
|
+
: helloResolution.status.startsWith("http_")
|
|
223
|
+
? `/hello failed (${helloResolution.status}).`
|
|
224
|
+
: "AgentBridge could not resolve an execution surface for this key.";
|
|
225
|
+
throw (0, errors_1.catalogCliError)("CONNECT_EXECUTION_SURFACE_MISSING", {
|
|
226
|
+
what: `Project access was verified, but connect could not bind an execution surface (hello: ${diagnostics.helloIdentityModel}, status: ${diagnostics.helloStatus}).`,
|
|
227
|
+
why: helloWhy,
|
|
228
|
+
});
|
|
316
229
|
}
|
|
317
230
|
// Persist credentials
|
|
318
231
|
(0, config_1.updateConfig)({
|
|
319
232
|
projectId,
|
|
320
|
-
apiKey
|
|
233
|
+
apiKey,
|
|
321
234
|
apiBaseUrl,
|
|
322
235
|
...(executionSurfaceId ? { executionSurfaceId } : {}),
|
|
323
236
|
});
|
|
324
237
|
process.stdout.write("Credentials saved to .agentbridge/config.json\n");
|
|
325
|
-
|
|
326
|
-
|
|
238
|
+
process.stdout.write(`Execution surface: ${executionSurfaceId}\n`);
|
|
239
|
+
// Auto-write .cursor/mcp.json (merge — preserves other MCP servers)
|
|
240
|
+
try {
|
|
241
|
+
const mcpPath = writeMcpConfig(projectId, apiKey, apiBaseUrl);
|
|
242
|
+
process.stdout.write(`MCP config written: ${mcpPath}\n`);
|
|
327
243
|
}
|
|
328
|
-
|
|
329
|
-
|
|
244
|
+
catch (err) {
|
|
245
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
246
|
+
process.stdout.write(`⚠ Could not write MCP config automatically: ${msg}\n`);
|
|
247
|
+
process.stdout.write(" Run `agentbridge setup-mcp` to generate it manually.\n");
|
|
248
|
+
}
|
|
249
|
+
// Auto-install project rules (soft — failure is non-blocking)
|
|
250
|
+
try {
|
|
251
|
+
await (0, install_rules_1.runInstallRules)({ projectId, apiKey, apiBaseUrl });
|
|
252
|
+
process.stdout.write("AgentBridge rules installed.\n");
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
256
|
+
process.stdout.write(`⚠ Could not install project rules: ${msg}\n`);
|
|
257
|
+
process.stdout.write(" Run `agentbridge install-rules` manually after connecting.\n");
|
|
330
258
|
}
|
|
331
259
|
// Pick or auto-select an agent identity
|
|
332
260
|
let activeAgentId = options.agentId ?? cfg.activeAgentId;
|
|
333
261
|
if (!activeAgentId) {
|
|
334
|
-
const agents = await listAgents(projectId,
|
|
262
|
+
const agents = await listAgents(projectId, apiKey, apiBaseUrl);
|
|
335
263
|
if (agents.length === 1 && agents[0]) {
|
|
336
264
|
activeAgentId = agents[0].id;
|
|
337
265
|
(0, config_1.updateConfig)({ activeAgentId });
|
|
@@ -360,15 +288,23 @@ async function runConnect(options = {}) {
|
|
|
360
288
|
process.stdout.write([
|
|
361
289
|
"",
|
|
362
290
|
"Next:",
|
|
363
|
-
"
|
|
364
|
-
" agentbridge
|
|
291
|
+
" 1. Restart your editor to activate the MCP server.",
|
|
292
|
+
" 2. agentbridge doctor (verify CLI + MCP + rules are aligned)",
|
|
293
|
+
" 3. agentbridge start \"task summary\"",
|
|
294
|
+
" 4. agentbridge watch",
|
|
365
295
|
"",
|
|
366
296
|
].join("\n"));
|
|
367
297
|
}
|
|
368
298
|
else {
|
|
369
299
|
process.stdout.write("✓ Connected.\n");
|
|
370
|
-
process.stdout.write(
|
|
371
|
-
|
|
372
|
-
|
|
300
|
+
process.stdout.write([
|
|
301
|
+
"",
|
|
302
|
+
"Next:",
|
|
303
|
+
" 1. Run `agentbridge use <agent-id>` to select an agent identity.",
|
|
304
|
+
" 2. Restart your editor to activate the MCP server.",
|
|
305
|
+
" 3. agentbridge doctor",
|
|
306
|
+
" 4. agentbridge start \"task summary\"",
|
|
307
|
+
"",
|
|
308
|
+
].join("\n"));
|
|
373
309
|
}
|
|
374
310
|
}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -97,16 +97,23 @@ function detectGovernanceSignals(workspaceRoot, expectedProjectId) {
|
|
|
97
97
|
const analysis = (0, rules_sync_1.analyzeRulesArtifacts)(workspaceRoot, expectedProjectId);
|
|
98
98
|
const mcpConfigPath = (0, node_path_1.resolve)(workspaceRoot, ".cursor", "mcp.json");
|
|
99
99
|
let mcpConfigured = false;
|
|
100
|
+
let mcpProjectId = null;
|
|
100
101
|
if ((0, node_fs_1.existsSync)(mcpConfigPath)) {
|
|
101
102
|
try {
|
|
102
103
|
const parsed = JSON.parse((0, node_fs_1.readFileSync)(mcpConfigPath, "utf8"));
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
const entry = parsed?.mcpServers?.["agentbridge"] ?? parsed?.mcpServers?.["agentbridge-mcp"];
|
|
105
|
+
mcpConfigured = Boolean(entry);
|
|
106
|
+
if (entry?.env?.AGENTBRIDGE_PROJECT_ID) {
|
|
107
|
+
mcpProjectId = entry.env.AGENTBRIDGE_PROJECT_ID;
|
|
108
|
+
}
|
|
105
109
|
}
|
|
106
110
|
catch {
|
|
107
111
|
mcpConfigured = false;
|
|
108
112
|
}
|
|
109
113
|
}
|
|
114
|
+
const mcpCredentialMismatch = mcpConfigured && mcpProjectId !== null && expectedProjectId !== undefined
|
|
115
|
+
? mcpProjectId !== expectedProjectId
|
|
116
|
+
: false;
|
|
110
117
|
return {
|
|
111
118
|
rulesFilesPresent: analysis.filesPresent,
|
|
112
119
|
rulesFormat: analysis.format,
|
|
@@ -115,6 +122,8 @@ function detectGovernanceSignals(workspaceRoot, expectedProjectId) {
|
|
|
115
122
|
rulesInstalled: analysis.protocolRulesValid,
|
|
116
123
|
rulesIssues: analysis.issues,
|
|
117
124
|
mcpConfigured,
|
|
125
|
+
mcpCredentialMismatch,
|
|
126
|
+
mcpProjectId,
|
|
118
127
|
governanceStatus: analysis.protocolRulesValid && mcpConfigured ? "active" : "inactive",
|
|
119
128
|
};
|
|
120
129
|
}
|
|
@@ -180,7 +189,7 @@ async function checkProjectAccess(ctx) {
|
|
|
180
189
|
catch {
|
|
181
190
|
// Summary proves access; packet is optional (recovery metadata only).
|
|
182
191
|
}
|
|
183
|
-
return { status: "ok", packet };
|
|
192
|
+
return { status: "ok", packet, projectId };
|
|
184
193
|
}
|
|
185
194
|
catch (error) {
|
|
186
195
|
if (error instanceof http_1.CliHttpError &&
|
|
@@ -364,7 +373,36 @@ async function runDoctor(cliRootOverride) {
|
|
|
364
373
|
}
|
|
365
374
|
lines.push(`Rules installed: ${governance.rulesInstalled ? "yes" : "no"}`);
|
|
366
375
|
lines.push(`MCP configured: ${governance.mcpConfigured ? "yes" : "no"}`);
|
|
376
|
+
if (governance.mcpConfigured && governance.mcpProjectId) {
|
|
377
|
+
lines.push(`MCP project id: ${governance.mcpProjectId}`);
|
|
378
|
+
}
|
|
367
379
|
lines.push(`Agent governance: ${governance.governanceStatus}`);
|
|
380
|
+
const cliConnected = projectAccess.status === "ok";
|
|
381
|
+
const supervisionStatus = !cliConnected
|
|
382
|
+
? "blind"
|
|
383
|
+
: governance.mcpCredentialMismatch
|
|
384
|
+
? "broken"
|
|
385
|
+
: !governance.mcpConfigured && !governance.rulesInstalled
|
|
386
|
+
? "blind"
|
|
387
|
+
: !governance.mcpConfigured || !governance.rulesInstalled
|
|
388
|
+
? "degraded"
|
|
389
|
+
: "ready";
|
|
390
|
+
lines.push(`Supervision status: ${supervisionStatus}`);
|
|
391
|
+
if (supervisionStatus === "broken") {
|
|
392
|
+
lines.push(` Supervision note: BROKEN — CLI project id (${projectAccess.projectId ?? "?"}) does not match MCP project id (${governance.mcpProjectId ?? "?"}).`);
|
|
393
|
+
lines.push(" Fix: run `agentbridge connect` again to re-write the MCP config with the correct credentials.");
|
|
394
|
+
}
|
|
395
|
+
else if (supervisionStatus === "blind") {
|
|
396
|
+
lines.push(" Supervision note: watch can observe filesystem changes only — MCP and rules both missing.");
|
|
397
|
+
}
|
|
398
|
+
else if (supervisionStatus === "degraded") {
|
|
399
|
+
if (!governance.mcpConfigured) {
|
|
400
|
+
lines.push(" Supervision note: MCP not configured — agent tool usage and implementation packets are invisible to watch.");
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
lines.push(" Supervision note: rules not installed — agent is not operating under AgentBridge protocol.");
|
|
404
|
+
}
|
|
405
|
+
}
|
|
368
406
|
if (governance.rulesIssues.length > 0) {
|
|
369
407
|
for (const issue of governance.rulesIssues) {
|
|
370
408
|
lines.push(`Rules issue: ${issue}`);
|
|
@@ -426,7 +464,7 @@ async function runDoctor(cliRootOverride) {
|
|
|
426
464
|
lines.push("Product status:");
|
|
427
465
|
if (productStatus === "ready") {
|
|
428
466
|
lines.push("- Connection: ready");
|
|
429
|
-
lines.push(
|
|
467
|
+
lines.push(`- Supervision: ${supervisionStatus}`);
|
|
430
468
|
lines.push("- Recovery: ready");
|
|
431
469
|
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
432
470
|
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
@@ -434,7 +472,7 @@ async function runDoctor(cliRootOverride) {
|
|
|
434
472
|
}
|
|
435
473
|
else if (productStatus === "ready_basic_recovery") {
|
|
436
474
|
lines.push("- Connection: ready");
|
|
437
|
-
lines.push(
|
|
475
|
+
lines.push(`- Supervision: ${supervisionStatus}`);
|
|
438
476
|
lines.push("- Recovery: basic");
|
|
439
477
|
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
440
478
|
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
@@ -444,7 +482,7 @@ async function runDoctor(cliRootOverride) {
|
|
|
444
482
|
else if (productStatus === "active_work_found") {
|
|
445
483
|
const recoveryBasic = (0, recovery_reconcile_1.recoveryIsBasicPacket)(projectAccess.packet);
|
|
446
484
|
lines.push("- Connection: ready");
|
|
447
|
-
lines.push(
|
|
485
|
+
lines.push(`- Supervision: ${supervisionStatus}`);
|
|
448
486
|
lines.push("- Recovery: " + (recoveryBasic ? "basic" : "ready"));
|
|
449
487
|
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
450
488
|
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
@@ -456,7 +494,7 @@ async function runDoctor(cliRootOverride) {
|
|
|
456
494
|
}
|
|
457
495
|
else if (productStatus === "needs_recover") {
|
|
458
496
|
lines.push("- Connection: ready");
|
|
459
|
-
lines.push(
|
|
497
|
+
lines.push(`- Supervision: ${supervisionStatus}`);
|
|
460
498
|
lines.push("- Recovery: required");
|
|
461
499
|
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
462
500
|
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
@@ -464,7 +502,7 @@ async function runDoctor(cliRootOverride) {
|
|
|
464
502
|
}
|
|
465
503
|
else {
|
|
466
504
|
lines.push("- Connection: incomplete");
|
|
467
|
-
lines.push(
|
|
505
|
+
lines.push(`- Supervision: ${supervisionStatus}`);
|
|
468
506
|
lines.push("- Recovery: pending");
|
|
469
507
|
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
470
508
|
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
@@ -3,72 +3,82 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.runSetupMcp = runSetupMcp;
|
|
4
4
|
const node_path_1 = require("node:path");
|
|
5
5
|
const config_1 = require("../config");
|
|
6
|
+
const mcp_config_1 = require("../mcp-config");
|
|
6
7
|
const mcp_runtime_1 = require("../mcp-runtime");
|
|
7
8
|
const MCP_SERVER_NAME = "agentbridge";
|
|
8
|
-
function
|
|
9
|
-
const serverConfig = {
|
|
10
|
-
command: "agentbridge",
|
|
11
|
-
args: ["mcp"],
|
|
12
|
-
env: {
|
|
13
|
-
AGENTBRIDGE_PROJECT_ID: projectId,
|
|
14
|
-
AGENTBRIDGE_API_KEY: apiKey,
|
|
15
|
-
AGENTBRIDGE_BASE_URL: apiBaseUrl,
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
return JSON.stringify({ [MCP_SERVER_NAME]: serverConfig }, null, 2);
|
|
19
|
-
}
|
|
20
|
-
async function runSetupMcp(options = {}) {
|
|
21
|
-
const cfg = (0, config_1.readConfig)();
|
|
22
|
-
const projectId = process.env.AGENTBRIDGE_PROJECT_ID ?? cfg.projectId ?? "<your-project-id>";
|
|
23
|
-
const apiKey = process.env.AGENTBRIDGE_API_KEY ?? cfg.apiKey ?? "<your-api-key>";
|
|
24
|
-
const apiBaseUrl = process.env.AGENTBRIDGE_BASE_URL ??
|
|
25
|
-
cfg.apiBaseUrl ??
|
|
26
|
-
"https://agentauth-api-production.up.railway.app";
|
|
27
|
-
const editor = options.editor ?? "cursor";
|
|
28
|
-
process.stdout.write("\nAgentBridge MCP Setup\n");
|
|
29
|
-
process.stdout.write("─────────────────────────────────────────\n\n");
|
|
9
|
+
function editorConfigHint(editor) {
|
|
30
10
|
if (editor === "cursor") {
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
else if (editor === "windsurf") {
|
|
34
|
-
process.stdout.write("Add this to your ~/.codeium/windsurf/mcp_config.json:\n\n");
|
|
35
|
-
}
|
|
36
|
-
else if (editor === "vscode") {
|
|
37
|
-
process.stdout.write("Add this to your .vscode/mcp.json:\n\n");
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
process.stdout.write(`Add this to your ${editor} MCP config:\n\n`);
|
|
11
|
+
return "Add this to your ~/.cursor/mcp.json (or project-level .cursor/mcp.json):\n\n";
|
|
41
12
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
mcpServers: JSON.parse(standardSnippet(projectId, apiKey, apiBaseUrl)),
|
|
45
|
-
}, null, 2) + "\n");
|
|
46
|
-
if (projectId === "<your-project-id>" || apiKey === "<your-api-key>") {
|
|
47
|
-
process.stdout.write("\n⚠ Credentials not found. Run `agentbridge connect` first to save your project ID and API key.\n");
|
|
13
|
+
if (editor === "windsurf") {
|
|
14
|
+
return "Add this to your ~/.codeium/windsurf/mcp_config.json:\n\n";
|
|
48
15
|
}
|
|
49
|
-
|
|
50
|
-
|
|
16
|
+
if (editor === "vscode") {
|
|
17
|
+
return "Add this to your .vscode/mcp.json:\n\n";
|
|
51
18
|
}
|
|
52
|
-
|
|
19
|
+
return "Add this to your " + editor + " MCP config:\n\n";
|
|
20
|
+
}
|
|
21
|
+
function printRuntimeStatus(cliDistDir) {
|
|
53
22
|
if (!(0, mcp_runtime_1.isMcpRuntimeAvailable)(cliDistDir)) {
|
|
54
23
|
process.stdout.write([
|
|
55
24
|
"",
|
|
56
25
|
"⚠ MCP runtime is missing from this CLI install.",
|
|
57
|
-
"
|
|
26
|
+
" agentbridge mcp will exit until you reinstall:",
|
|
58
27
|
" npm install -g @agentbridge1/cli@latest",
|
|
59
28
|
"",
|
|
60
29
|
" Or point mcp.json at a repo build:",
|
|
61
30
|
" node /path/to/AuthAgent/cli/dist/mcp/agentbridge-mcp.js",
|
|
62
31
|
"",
|
|
63
32
|
].join("\n"));
|
|
33
|
+
return;
|
|
64
34
|
}
|
|
65
|
-
|
|
35
|
+
process.stdout.write(["", "✓ MCP runtime is bundled with this CLI (agentbridge mcp is ready).", ""].join("\n"));
|
|
36
|
+
}
|
|
37
|
+
async function runSetupMcp(options = {}) {
|
|
38
|
+
const cliDistDir = (0, node_path_1.resolve)(__dirname, "..");
|
|
39
|
+
const editor = options.editor ?? "cursor";
|
|
40
|
+
process.stdout.write("\nAgentBridge MCP Setup\n");
|
|
41
|
+
process.stdout.write("─────────────────────────────────────────\n\n");
|
|
42
|
+
if (options.local) {
|
|
43
|
+
const entry = (0, mcp_config_1.buildLocalMcpServerEntry)(cliDistDir);
|
|
44
|
+
const mcpPath = (0, mcp_config_1.writeLocalMcpConfig)(cliDistDir);
|
|
45
|
+
process.stdout.write("Mode: local-first (no project ID or API key required)\n\n");
|
|
46
|
+
process.stdout.write("MCP config written: " + mcpPath + "\n\n");
|
|
47
|
+
process.stdout.write("Configured entry:\n\n");
|
|
48
|
+
process.stdout.write(JSON.stringify({ mcpServers: { [MCP_SERVER_NAME]: entry } }, null, 2) + "\n");
|
|
49
|
+
process.stdout.write("\nLocal mode: agent_hello creates work contracts on disk.\n" +
|
|
50
|
+
" Run agentbridge watch in this repo, then restart Cursor.\n");
|
|
51
|
+
printRuntimeStatus(cliDistDir);
|
|
66
52
|
process.stdout.write([
|
|
67
53
|
"",
|
|
68
|
-
"
|
|
54
|
+
"Next:",
|
|
55
|
+
" 1. Restart Cursor to load MCP.",
|
|
56
|
+
" 2. agentbridge watch",
|
|
57
|
+
" 3. In chat: agent_hello({ intent: \"what you are about to do\" })",
|
|
69
58
|
"",
|
|
70
59
|
].join("\n"));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const cfg = (0, config_1.readConfig)();
|
|
63
|
+
const projectId = process.env.AGENTBRIDGE_PROJECT_ID ?? cfg.projectId ?? "<your-project-id>";
|
|
64
|
+
const apiKey = process.env.AGENTBRIDGE_API_KEY ?? cfg.apiKey ?? "<your-api-key>";
|
|
65
|
+
const apiBaseUrl = process.env.AGENTBRIDGE_BASE_URL ??
|
|
66
|
+
cfg.apiBaseUrl ??
|
|
67
|
+
"https://agentauth-api-production.up.railway.app";
|
|
68
|
+
process.stdout.write(editorConfigHint(editor));
|
|
69
|
+
process.stdout.write("Recommended config:\n\n");
|
|
70
|
+
const serverEntry = (0, mcp_config_1.buildServerMcpServerEntry)(projectId, apiKey, apiBaseUrl);
|
|
71
|
+
process.stdout.write(JSON.stringify({ mcpServers: { [MCP_SERVER_NAME]: serverEntry } }, null, 2) + "\n");
|
|
72
|
+
if (projectId === "<your-project-id>" || apiKey === "<your-api-key>") {
|
|
73
|
+
process.stdout.write("\n⚠ Credentials not found. Run agentbridge connect first to save your project ID and API key.\n" +
|
|
74
|
+
" Or use local mode: agentbridge setup-mcp --local\n");
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const mcpPath = (0, mcp_config_1.mergeAgentbridgeIntoCursorMcp)(serverEntry);
|
|
78
|
+
process.stdout.write("\nMCP config written: " + mcpPath + "\n");
|
|
79
|
+
process.stdout.write("\n✓ Credentials filled from .agentbridge/config.json\n");
|
|
71
80
|
}
|
|
81
|
+
printRuntimeStatus(cliDistDir);
|
|
72
82
|
process.stdout.write([
|
|
73
83
|
"After saving the config, restart your editor to activate the MCP server.",
|
|
74
84
|
"The MCP server lets your AI assistant call tools like agent_hello, check AgentBridge status, and trigger approvals.",
|