@agentbridge1/cli 0.0.5 → 0.0.6
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/accept.js +4 -4
- package/dist/commands/check.js +10 -1
- package/dist/commands/connect.js +2 -2
- package/dist/commands/doctor.js +98 -22
- package/dist/commands/proof-guidance.js +30 -0
- package/dist/commands/recover.js +109 -22
- package/dist/commands/setup-mcp.js +22 -1
- package/dist/commands/start.js +33 -63
- package/dist/commands/verify.js +124 -91
- package/dist/commands/watch.js +428 -113
- package/dist/error-catalog.js +50 -15
- package/dist/gates.js +3 -3
- package/dist/git-evidence.js +2 -0
- package/dist/http.js +29 -0
- package/dist/index.js +46 -30
- package/dist/init.js +124 -18
- package/dist/local-memory.js +33 -0
- package/dist/local-proof.js +158 -0
- package/dist/local-session-mirror.js +247 -0
- package/dist/local-supervision.js +250 -0
- package/dist/mcp/agentbridge-mcp.js +22947 -0
- package/dist/mcp/agentbridge-mcp.js.map +7 -0
- package/dist/mcp-runtime.js +31 -0
- package/dist/preflight-changed-files.js +24 -17
- package/dist/proof-obligations.js +155 -0
- package/dist/recovery-reconcile.js +183 -0
- package/dist/server-sync.js +24 -0
- package/dist/session-state.js +119 -21
- package/dist/session.js +9 -2
- package/dist/supervision.js +100 -6
- package/package.json +5 -2
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-06T12:05:27.957Z",
|
|
3
|
+
"gitHead": "ec17ba8",
|
|
4
|
+
"sourceLatestMtime": "2026-06-06T11:59:41.649Z",
|
|
5
|
+
"sourceLatestFile": "src/commands/watch.ts"
|
|
6
6
|
}
|
package/dist/commands/accept.js
CHANGED
|
@@ -10,6 +10,7 @@ const server_sync_1 = require("../server-sync");
|
|
|
10
10
|
const operator_snapshot_1 = require("../operator-snapshot");
|
|
11
11
|
const work_context_resolver_1 = require("../work-context-resolver");
|
|
12
12
|
const error_catalog_1 = require("../error-catalog");
|
|
13
|
+
const proof_obligations_1 = require("../proof-obligations");
|
|
13
14
|
const acceptance_preflight_1 = require("../acceptance-preflight");
|
|
14
15
|
const acceptance_block_1 = require("../acceptance-block");
|
|
15
16
|
function resolveNetworkContext() {
|
|
@@ -36,10 +37,9 @@ function blockedErrorCode(report) {
|
|
|
36
37
|
if ((report.out_of_scope_files ?? []).length > 0 || report.scope_status === "drift") {
|
|
37
38
|
return "SCOPE_DRIFT_OUT_OF_SCOPE_FILE";
|
|
38
39
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return "PROOF_STALE_AFTER_CHANGE";
|
|
40
|
+
const proofCode = (0, proof_obligations_1.resolveProofBlockingErrorCode)(report);
|
|
41
|
+
if (proofCode)
|
|
42
|
+
return proofCode;
|
|
43
43
|
return "ACCEPTANCE_BLOCKED";
|
|
44
44
|
}
|
|
45
45
|
function buildStructuredBlockedOutput(report) {
|
package/dist/commands/check.js
CHANGED
|
@@ -9,6 +9,7 @@ const acceptance_preflight_1 = require("../acceptance-preflight");
|
|
|
9
9
|
const work_context_resolver_1 = require("../work-context-resolver");
|
|
10
10
|
const operator_snapshot_1 = require("../operator-snapshot");
|
|
11
11
|
const proof_guidance_1 = require("../proof-guidance");
|
|
12
|
+
const proof_obligations_1 = require("../proof-obligations");
|
|
12
13
|
const memory_context_render_1 = require("../memory-context-render");
|
|
13
14
|
const acceptance_block_1 = require("../acceptance-block");
|
|
14
15
|
function resolveNetworkContext() {
|
|
@@ -184,8 +185,16 @@ function renderAcceptanceReport(report) {
|
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
187
|
}
|
|
188
|
+
const obligationSection = (0, proof_obligations_1.renderProofObligationSection)(report);
|
|
189
|
+
if (obligationSection.length > 0) {
|
|
190
|
+
lines.push(...obligationSection);
|
|
191
|
+
}
|
|
187
192
|
lines.push(`Decision: ${report.decision}`);
|
|
188
|
-
|
|
193
|
+
const obligationErrorLines = (0, proof_obligations_1.renderProofObligationErrorLines)(report);
|
|
194
|
+
if (obligationErrorLines.length > 0) {
|
|
195
|
+
lines.push(...obligationErrorLines);
|
|
196
|
+
}
|
|
197
|
+
else if (report.decision === "needs_proof") {
|
|
189
198
|
lines.push("✗ Error code: PROOF_MISSING");
|
|
190
199
|
lines.push(" What happened: No verification proof exists for this work session.");
|
|
191
200
|
lines.push(" Why it matters: Unverified work cannot be accepted — proof is required.");
|
package/dist/commands/connect.js
CHANGED
|
@@ -358,7 +358,7 @@ async function runConnect(options = {}) {
|
|
|
358
358
|
"",
|
|
359
359
|
"Next:",
|
|
360
360
|
" agentbridge doctor",
|
|
361
|
-
" agentbridge
|
|
361
|
+
" agentbridge watch",
|
|
362
362
|
"",
|
|
363
363
|
].join("\n"));
|
|
364
364
|
}
|
|
@@ -366,6 +366,6 @@ async function runConnect(options = {}) {
|
|
|
366
366
|
process.stdout.write("✓ Connected.\n");
|
|
367
367
|
process.stdout.write("Run `agentbridge use <agent-id>` and then:\n");
|
|
368
368
|
process.stdout.write(" agentbridge doctor\n");
|
|
369
|
-
process.stdout.write(" agentbridge
|
|
369
|
+
process.stdout.write(" agentbridge watch\n");
|
|
370
370
|
}
|
|
371
371
|
}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -10,6 +10,7 @@ const http_1 = require("../http");
|
|
|
10
10
|
const dist_freshness_1 = require("./dist-freshness");
|
|
11
11
|
const session_state_1 = require("../session-state");
|
|
12
12
|
const server_sync_1 = require("../server-sync");
|
|
13
|
+
const recovery_reconcile_1 = require("../recovery-reconcile");
|
|
13
14
|
function cliRootFromCommandDir() {
|
|
14
15
|
return (0, node_path_1.resolve)(__dirname, "..", "..");
|
|
15
16
|
}
|
|
@@ -86,11 +87,27 @@ function extractHttpReason(error) {
|
|
|
86
87
|
}
|
|
87
88
|
return `http_${error.status}`;
|
|
88
89
|
}
|
|
89
|
-
function
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
|
|
90
|
+
function detectGovernanceSignals(workspaceRoot) {
|
|
91
|
+
const rulesMdcPath = (0, node_path_1.resolve)(workspaceRoot, ".cursor", "rules", "agentbridge.mdc");
|
|
92
|
+
const rulesMarkdownPath = (0, node_path_1.resolve)(workspaceRoot, "AGENTBRIDGE.md");
|
|
93
|
+
const mcpConfigPath = (0, node_path_1.resolve)(workspaceRoot, ".cursor", "mcp.json");
|
|
94
|
+
const rulesInstalled = (0, node_fs_1.existsSync)(rulesMdcPath) && (0, node_fs_1.existsSync)(rulesMarkdownPath);
|
|
95
|
+
let mcpConfigured = false;
|
|
96
|
+
if ((0, node_fs_1.existsSync)(mcpConfigPath)) {
|
|
97
|
+
try {
|
|
98
|
+
const parsed = JSON.parse((0, node_fs_1.readFileSync)(mcpConfigPath, "utf8"));
|
|
99
|
+
mcpConfigured = Boolean(parsed?.mcpServers &&
|
|
100
|
+
(parsed.mcpServers["agentbridge"] || parsed.mcpServers["agentbridge-mcp"]));
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
mcpConfigured = false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
rulesInstalled,
|
|
108
|
+
mcpConfigured,
|
|
109
|
+
governanceStatus: rulesInstalled && mcpConfigured ? "active" : "inactive",
|
|
110
|
+
};
|
|
94
111
|
}
|
|
95
112
|
async function checkProjectAccess(ctx) {
|
|
96
113
|
if (!ctx.configComplete) {
|
|
@@ -219,6 +236,7 @@ async function checkIdentityAccess(ctx) {
|
|
|
219
236
|
}
|
|
220
237
|
async function runDoctor(cliRootOverride) {
|
|
221
238
|
const cliRoot = cliRootOverride ?? cliRootFromCommandDir();
|
|
239
|
+
const workspaceRoot = process.cwd();
|
|
222
240
|
const cfg = (0, config_1.readConfig)();
|
|
223
241
|
const freshness = (0, dist_freshness_1.getDistFreshnessReport)(cliRoot);
|
|
224
242
|
const configPath = cliRootOverride
|
|
@@ -238,6 +256,7 @@ async function runDoctor(cliRootOverride) {
|
|
|
238
256
|
const projectConfigPresent = projectIdPresent && apiKeyPresent && baseUrlPresent;
|
|
239
257
|
const activeSession = (0, session_state_1.readSessionState)();
|
|
240
258
|
const hasActiveWork = Boolean(activeSession?.id || activeSession?.serverSessionId);
|
|
259
|
+
const governance = detectGovernanceSignals(workspaceRoot);
|
|
241
260
|
const envContributed = Boolean(process.env.AGENTBRIDGE_PROJECT_ID) ||
|
|
242
261
|
Boolean(process.env.AGENTBRIDGE_API_KEY) ||
|
|
243
262
|
Boolean(process.env.AGENTBRIDGE_BASE_URL) ||
|
|
@@ -277,12 +296,9 @@ async function runDoctor(cliRootOverride) {
|
|
|
277
296
|
apiBaseUrl: resolvedBaseUrl,
|
|
278
297
|
configComplete: projectConfigPresent && projectAccess.status === "ok",
|
|
279
298
|
});
|
|
280
|
-
lines.push(`
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
284
|
-
lines.push(`Caller identity model: ${identityAccess.identityModel}`);
|
|
285
|
-
lines.push(`Execution surface present: ${identityAccess.executionSurfaceId ? "yes" : "no"}`);
|
|
299
|
+
lines.push(`Rules installed: ${governance.rulesInstalled ? "yes" : "no"}`);
|
|
300
|
+
lines.push(`MCP configured: ${governance.mcpConfigured ? "yes" : "no"}`);
|
|
301
|
+
lines.push(`Agent governance: ${governance.governanceStatus}`);
|
|
286
302
|
lines.push(`Start capable: ${identityAccess.startCapable ? "yes" : "no"}`);
|
|
287
303
|
if (projectAccess.status === "failed" && projectAccess.reason) {
|
|
288
304
|
const view = (0, error_catalog_1.catalogViewForDoctorReason)(projectAccess.reason, projectAccess.suggestedNextAction);
|
|
@@ -309,32 +325,77 @@ async function runDoctor(cliRootOverride) {
|
|
|
309
325
|
productStatus = "active_work_found";
|
|
310
326
|
}
|
|
311
327
|
else {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
328
|
+
if ((0, recovery_reconcile_1.recoveryBaselineRequired)(projectAccess.packet)) {
|
|
329
|
+
productStatus = "needs_recover";
|
|
330
|
+
}
|
|
331
|
+
else if ((0, recovery_reconcile_1.recoveryIsBasicPacket)(projectAccess.packet)) {
|
|
332
|
+
productStatus = "ready_basic_recovery";
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
productStatus = "ready";
|
|
336
|
+
}
|
|
315
337
|
}
|
|
316
338
|
}
|
|
339
|
+
const localSupervisionReady = true;
|
|
340
|
+
const cloudSyncReady = projectAccess.status === "ok";
|
|
341
|
+
const strictTrackedReady = projectAccess.status === "ok" && identityAccess.status === "ok" && identityAccess.startCapable;
|
|
342
|
+
lines.push("");
|
|
343
|
+
lines.push("Capability levels:");
|
|
344
|
+
lines.push(`- Local supervision: ${localSupervisionReady ? "ready" : "unavailable"}`);
|
|
345
|
+
lines.push(`- Cloud sync: ${cloudSyncReady ? "ready" : "unavailable"}`);
|
|
346
|
+
lines.push(`- Strict tracked work: ${strictTrackedReady ? "ready" : "unavailable"}`);
|
|
347
|
+
if (!cloudSyncReady && projectAccess.reason) {
|
|
348
|
+
lines.push(` Cloud sync note: ${projectAccess.reason}`);
|
|
349
|
+
}
|
|
350
|
+
if (!strictTrackedReady && identityAccess.reason) {
|
|
351
|
+
lines.push(` Strict tracked note: ${identityAccess.reason}`);
|
|
352
|
+
}
|
|
317
353
|
lines.push("");
|
|
318
354
|
lines.push("Product status:");
|
|
319
355
|
if (productStatus === "ready") {
|
|
320
356
|
lines.push("- Connection: ready");
|
|
357
|
+
lines.push("- Governance: " + governance.governanceStatus);
|
|
321
358
|
lines.push("- Recovery: ready");
|
|
322
|
-
lines.push(
|
|
359
|
+
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
360
|
+
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
361
|
+
lines.push("- Next: run `agentbridge watch` beside Cursor for live supervision");
|
|
362
|
+
}
|
|
363
|
+
else if (productStatus === "ready_basic_recovery") {
|
|
364
|
+
lines.push("- Connection: ready");
|
|
365
|
+
lines.push("- Governance: " + governance.governanceStatus);
|
|
366
|
+
lines.push("- Recovery: basic");
|
|
367
|
+
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
368
|
+
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
369
|
+
lines.push("- Note: Project context exists, but domains are not fully mapped yet.");
|
|
370
|
+
lines.push("- Next: run `agent recover --force` for a full domain rebuild, or `agentbridge watch` for live supervision");
|
|
323
371
|
}
|
|
324
372
|
else if (productStatus === "active_work_found") {
|
|
373
|
+
const recoveryBasic = (0, recovery_reconcile_1.recoveryIsBasicPacket)(projectAccess.packet);
|
|
325
374
|
lines.push("- Connection: ready");
|
|
326
|
-
lines.push("-
|
|
375
|
+
lines.push("- Governance: " + governance.governanceStatus);
|
|
376
|
+
lines.push("- Recovery: " + (recoveryBasic ? "basic" : "ready"));
|
|
377
|
+
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
378
|
+
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
379
|
+
if (recoveryBasic) {
|
|
380
|
+
lines.push("- Note: Project context exists, but domains are not fully mapped yet.");
|
|
381
|
+
}
|
|
327
382
|
lines.push("- Active work: found");
|
|
328
|
-
lines.push("- Next: agentbridge
|
|
383
|
+
lines.push("- Next: run `agentbridge watch` beside Cursor for live supervision");
|
|
329
384
|
}
|
|
330
385
|
else if (productStatus === "needs_recover") {
|
|
331
386
|
lines.push("- Connection: ready");
|
|
387
|
+
lines.push("- Governance: " + governance.governanceStatus);
|
|
332
388
|
lines.push("- Recovery: required");
|
|
389
|
+
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
390
|
+
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
333
391
|
lines.push("- Next: agentbridge recover");
|
|
334
392
|
}
|
|
335
393
|
else {
|
|
336
394
|
lines.push("- Connection: incomplete");
|
|
395
|
+
lines.push("- Governance: " + governance.governanceStatus);
|
|
337
396
|
lines.push("- Recovery: pending");
|
|
397
|
+
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
398
|
+
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
338
399
|
if (!projectConfigPresent) {
|
|
339
400
|
lines.push("- Note: Connection details are missing. Add credentials, then rerun agentbridge doctor.");
|
|
340
401
|
}
|
|
@@ -342,9 +403,6 @@ async function runDoctor(cliRootOverride) {
|
|
|
342
403
|
lines.push("- Reason: execution surface missing.");
|
|
343
404
|
lines.push("- Next: agentbridge connect");
|
|
344
405
|
}
|
|
345
|
-
else if (identityAccess.status !== "ok") {
|
|
346
|
-
lines.push("- Note: Caller identity is unresolved. Run agentbridge identity list and set a valid active agent.");
|
|
347
|
-
}
|
|
348
406
|
else {
|
|
349
407
|
lines.push("- Note: Connection check failed. Verify credentials/network, then rerun agentbridge doctor.");
|
|
350
408
|
}
|
|
@@ -352,12 +410,30 @@ async function runDoctor(cliRootOverride) {
|
|
|
352
410
|
lines.push("- Next: agentbridge doctor");
|
|
353
411
|
}
|
|
354
412
|
}
|
|
413
|
+
lines.push("");
|
|
414
|
+
lines.push("Advanced details:");
|
|
415
|
+
lines.push(`- Caller identity access: ${identityAccess.status}`);
|
|
416
|
+
if (identityAccess.reason) {
|
|
417
|
+
lines.push(`- Caller identity reason: ${identityAccess.reason}`);
|
|
418
|
+
}
|
|
419
|
+
lines.push(`- Caller identity model: ${identityAccess.identityModel}`);
|
|
420
|
+
lines.push(`- Execution surface present: ${identityAccess.executionSurfaceId ? "yes" : "no"}`);
|
|
421
|
+
lines.push(`- Start capable (strict/session modes): ${identityAccess.startCapable ? "yes" : "no"}`);
|
|
422
|
+
if (identityAccess.status !== "ok") {
|
|
423
|
+
lines.push("- Note: internal identity mismatch affects strict/resume flows, not room-level inferred watch startup.");
|
|
424
|
+
}
|
|
425
|
+
if (governance.governanceStatus === "inactive") {
|
|
426
|
+
lines.push("");
|
|
427
|
+
lines.push("Governance note: AgentBridge can review in terminal, but your AI agent may not stop automatically until rules and MCP are both configured.");
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
lines.push("");
|
|
431
|
+
lines.push("Governance note: AgentBridge rules are installed and MCP is configured. The AI agent should stop when AgentBridge flags blocked work.");
|
|
432
|
+
}
|
|
355
433
|
process.stdout.write(`${lines.join("\n")}\n`);
|
|
356
434
|
if (freshness.state === "stale")
|
|
357
435
|
return 1;
|
|
358
436
|
if (projectAccess.status === "failed")
|
|
359
437
|
return 1;
|
|
360
|
-
if (identityAccess.status === "failed")
|
|
361
|
-
return 1;
|
|
362
438
|
return 0;
|
|
363
439
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runProofGuidance = runProofGuidance;
|
|
4
|
+
const config_1 = require("../config");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
const server_sync_1 = require("../server-sync");
|
|
7
|
+
function resolveNetworkContext() {
|
|
8
|
+
const cfg = (0, config_1.readConfig)();
|
|
9
|
+
const projectId = process.env.AGENTBRIDGE_PROJECT_ID ?? cfg.projectId;
|
|
10
|
+
const apiKey = process.env.AGENTBRIDGE_API_KEY ?? cfg.apiKey ?? "";
|
|
11
|
+
const apiBaseUrl = process.env.AGENTBRIDGE_BASE_URL ?? cfg.apiBaseUrl ?? "https://agentauth-api-production.up.railway.app";
|
|
12
|
+
if (!projectId) {
|
|
13
|
+
throw new errors_1.SafeCliError("Missing AGENTBRIDGE_PROJECT_ID. Set AGENTBRIDGE_PROJECT_ID (or run `agentbridge init --project ...`).");
|
|
14
|
+
}
|
|
15
|
+
if (!apiKey) {
|
|
16
|
+
throw new errors_1.SafeCliError("Missing AGENTBRIDGE_API_KEY. Provide --api-key, set AGENTBRIDGE_API_KEY, or save apiKey in .agentbridge/config.json.");
|
|
17
|
+
}
|
|
18
|
+
return { projectId, apiKey, apiBaseUrl };
|
|
19
|
+
}
|
|
20
|
+
async function runProofGuidance(options = {}) {
|
|
21
|
+
const ctx = resolveNetworkContext();
|
|
22
|
+
const guidance = await (0, server_sync_1.fetchAgentProofGuidance)(ctx, {
|
|
23
|
+
workSessionId: options.workSessionId,
|
|
24
|
+
changeRequestId: options.changeRequestId,
|
|
25
|
+
rolloutProofTooWeak: options.rolloutProofTooWeak,
|
|
26
|
+
rolloutProofNotRelevant: options.rolloutProofNotRelevant,
|
|
27
|
+
rolloutImpactCoverageGap: options.rolloutImpactCoverageGap,
|
|
28
|
+
});
|
|
29
|
+
process.stdout.write(`${JSON.stringify(guidance, null, 2)}\n`);
|
|
30
|
+
}
|
package/dist/commands/recover.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.runRecover = runRecover;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const node_process_1 = require("node:process");
|
|
4
7
|
const config_1 = require("../config");
|
|
5
8
|
const errors_1 = require("../errors");
|
|
6
|
-
const server_sync_1 = require("../server-sync");
|
|
7
|
-
const node_process_1 = require("node:process");
|
|
8
9
|
const gates_1 = require("../gates");
|
|
9
|
-
const init_1 = require("../init");
|
|
10
10
|
const http_1 = require("../http");
|
|
11
|
+
const init_1 = require("../init");
|
|
12
|
+
const recovery_reconcile_1 = require("../recovery-reconcile");
|
|
13
|
+
const server_sync_1 = require("../server-sync");
|
|
11
14
|
function resolveNetworkContext() {
|
|
12
15
|
const cfg = (0, config_1.readConfig)();
|
|
13
16
|
const projectId = process.env.AGENTBRIDGE_PROJECT_ID ?? cfg.projectId ?? "";
|
|
@@ -20,9 +23,14 @@ function resolveNetworkContext() {
|
|
|
20
23
|
}
|
|
21
24
|
return { projectId, apiKey, apiBaseUrl };
|
|
22
25
|
}
|
|
26
|
+
function rulesInstalled(repoRoot) {
|
|
27
|
+
return ((0, node_fs_1.existsSync)((0, node_path_1.resolve)(repoRoot, "AGENTBRIDGE.md")) &&
|
|
28
|
+
(0, node_fs_1.existsSync)((0, node_path_1.resolve)(repoRoot, ".cursor", "rules", "agentbridge.mdc")));
|
|
29
|
+
}
|
|
23
30
|
function renderRecoverOutput(packet) {
|
|
24
31
|
const lines = [];
|
|
25
|
-
const
|
|
32
|
+
const activeDomains = (packet.domains_summary ?? []).filter((d) => d.state !== "retired");
|
|
33
|
+
const domainCount = activeDomains.length;
|
|
26
34
|
const ruleCount = packet.global_rules?.length ?? 0;
|
|
27
35
|
const hasCharterContext = Boolean(packet.charter_summary?.purpose);
|
|
28
36
|
lines.push("Project recovered.");
|
|
@@ -36,7 +44,7 @@ function renderRecoverOutput(packet) {
|
|
|
36
44
|
if (domainCount > 0) {
|
|
37
45
|
lines.push("");
|
|
38
46
|
lines.push("Domains found:");
|
|
39
|
-
for (const domain of
|
|
47
|
+
for (const domain of activeDomains) {
|
|
40
48
|
const pathNote = domain.owned_path_count > 0 ? `${domain.owned_path_count} path(s)` : "paths pending";
|
|
41
49
|
lines.push(`- ${domain.domain_name} — ${pathNote}`);
|
|
42
50
|
}
|
|
@@ -55,18 +63,56 @@ function renderRecoverOutput(packet) {
|
|
|
55
63
|
}
|
|
56
64
|
lines.push("");
|
|
57
65
|
lines.push("Next:");
|
|
58
|
-
lines.push(" agentbridge
|
|
66
|
+
lines.push(" agentbridge watch");
|
|
59
67
|
lines.push("");
|
|
60
68
|
return lines.join("\n");
|
|
61
69
|
}
|
|
62
70
|
function recoveryStatusLabel(packet) {
|
|
63
71
|
return packet.recovery_status ?? "unknown";
|
|
64
72
|
}
|
|
65
|
-
function
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
function formatDomainLines(refs) {
|
|
74
|
+
if (refs.length === 0)
|
|
75
|
+
return " (none)";
|
|
76
|
+
return refs.map((d) => `- ${d.name}`).join("\n");
|
|
77
|
+
}
|
|
78
|
+
function renderReconcileReport(input) {
|
|
79
|
+
const { plan, applied, qualityAfter } = input;
|
|
80
|
+
const lines = [""];
|
|
81
|
+
if (applied) {
|
|
82
|
+
lines.push("AgentBridge checked recovery.");
|
|
83
|
+
lines.push(`Recovery quality: ${qualityAfter}`);
|
|
84
|
+
if (plan.toAdd.length > 0) {
|
|
85
|
+
lines.push("");
|
|
86
|
+
lines.push("Added:");
|
|
87
|
+
lines.push(formatDomainLines(plan.toAdd));
|
|
88
|
+
}
|
|
89
|
+
if (plan.toPreserve.length > 0) {
|
|
90
|
+
lines.push("");
|
|
91
|
+
lines.push("Existing domains preserved:");
|
|
92
|
+
lines.push(formatDomainLines(plan.toPreserve));
|
|
93
|
+
}
|
|
94
|
+
if (plan.toRetire.length > 0) {
|
|
95
|
+
lines.push("");
|
|
96
|
+
lines.push("Retired:");
|
|
97
|
+
lines.push(formatDomainLines(plan.toRetire));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
lines.push("AgentBridge checked recovery.");
|
|
102
|
+
lines.push("No changes needed.");
|
|
103
|
+
lines.push("Recovery is up to date.");
|
|
104
|
+
lines.push(`Recovery quality: ${qualityAfter}`);
|
|
105
|
+
}
|
|
106
|
+
return lines.join("\n") + "\n";
|
|
107
|
+
}
|
|
108
|
+
function renderBasicHint() {
|
|
109
|
+
return [
|
|
110
|
+
"",
|
|
111
|
+
"Recovery: basic",
|
|
112
|
+
"AgentBridge found only a generic project area.",
|
|
113
|
+
"Run `agent recover --force` to rebuild the domain map.",
|
|
114
|
+
"",
|
|
115
|
+
].join("\n");
|
|
70
116
|
}
|
|
71
117
|
function renderRecoveryStatusBlock(input) {
|
|
72
118
|
const lines = [];
|
|
@@ -175,15 +221,42 @@ async function runRecover(options = {}) {
|
|
|
175
221
|
return;
|
|
176
222
|
}
|
|
177
223
|
const beforePacket = packet;
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
224
|
+
const cfg = (0, config_1.readConfig)();
|
|
225
|
+
const repoRoot = (0, node_process_1.cwd)();
|
|
226
|
+
const rulesOk = rulesInstalled(repoRoot);
|
|
227
|
+
let scan;
|
|
228
|
+
try {
|
|
229
|
+
process.stdout.write("Scanning repository layout...\n");
|
|
230
|
+
scan = await (0, init_1.scanRecoveryFromRepo)(ctx);
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
process.stderr.write(`${(0, errors_1.renderCliError)(normalizeBootstrapError(error))}\n`);
|
|
234
|
+
process.exitCode = 1;
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const existingActive = (0, recovery_reconcile_1.packetDomainsToRefs)(beforePacket, cfg.domains ?? []);
|
|
238
|
+
const plan = (0, recovery_reconcile_1.buildReconcilePlan)({
|
|
239
|
+
existingActive,
|
|
240
|
+
candidates: scan.candidateRefs,
|
|
241
|
+
mode: options.force ? "force" : "safe",
|
|
242
|
+
packet: beforePacket,
|
|
243
|
+
rulesInstalled: rulesOk,
|
|
244
|
+
});
|
|
245
|
+
const needsBaseline = (0, recovery_reconcile_1.recoveryBaselineRequired)(beforePacket);
|
|
246
|
+
const shouldApply = needsBaseline || options.force || plan.hasChanges;
|
|
247
|
+
let actionTaken = "reconciliation check only; no changes needed";
|
|
248
|
+
if (shouldApply) {
|
|
249
|
+
actionTaken = needsBaseline
|
|
182
250
|
? "build recovery baseline from repository evidence"
|
|
183
|
-
:
|
|
184
|
-
|
|
251
|
+
: options.force
|
|
252
|
+
? "force-refresh recovery baseline from repository evidence"
|
|
253
|
+
: "reconcile recovery with repository evidence";
|
|
254
|
+
process.stdout.write("Applying recovery changes...\n");
|
|
185
255
|
try {
|
|
186
|
-
await (0, init_1.runBootstrapRecovery)(ctx
|
|
256
|
+
await (0, init_1.runBootstrapRecovery)(ctx, {
|
|
257
|
+
reconcilePlan: plan,
|
|
258
|
+
scan,
|
|
259
|
+
});
|
|
187
260
|
packet = await (0, server_sync_1.fetchProjectPacket)(ctx);
|
|
188
261
|
}
|
|
189
262
|
catch (error) {
|
|
@@ -193,7 +266,19 @@ async function runRecover(options = {}) {
|
|
|
193
266
|
}
|
|
194
267
|
}
|
|
195
268
|
const afterPacket = packet;
|
|
196
|
-
|
|
269
|
+
const qualityAfter = (0, recovery_reconcile_1.recoveryQualityLabel)((0, recovery_reconcile_1.buildReconcilePlan)({
|
|
270
|
+
existingActive: (0, recovery_reconcile_1.packetDomainsToRefs)(afterPacket, cfg.domains ?? []),
|
|
271
|
+
candidates: scan.candidateRefs,
|
|
272
|
+
mode: options.force ? "force" : "safe",
|
|
273
|
+
packet: afterPacket,
|
|
274
|
+
rulesInstalled: rulesOk,
|
|
275
|
+
}).quality);
|
|
276
|
+
process.stdout.write(renderReconcileReport({
|
|
277
|
+
plan,
|
|
278
|
+
applied: shouldApply,
|
|
279
|
+
qualityAfter,
|
|
280
|
+
}));
|
|
281
|
+
if ((0, recovery_reconcile_1.recoveryBaselineRequired)(afterPacket)) {
|
|
197
282
|
process.stderr.write([
|
|
198
283
|
"Recovery could not complete: baseline still required.",
|
|
199
284
|
"",
|
|
@@ -208,7 +293,6 @@ async function runRecover(options = {}) {
|
|
|
208
293
|
process.exitCode = 1;
|
|
209
294
|
return;
|
|
210
295
|
}
|
|
211
|
-
const repoRoot = (0, node_process_1.cwd)();
|
|
212
296
|
(0, gates_1.ensureGitignoreSessionEntry)(repoRoot);
|
|
213
297
|
(0, gates_1.ensureGatesFile)(repoRoot);
|
|
214
298
|
process.stdout.write(renderRecoveryStatusBlock({
|
|
@@ -216,7 +300,10 @@ async function runRecover(options = {}) {
|
|
|
216
300
|
before: beforePacket,
|
|
217
301
|
after: afterPacket,
|
|
218
302
|
action: actionTaken,
|
|
219
|
-
next: "agentbridge
|
|
303
|
+
next: "agentbridge watch",
|
|
220
304
|
}));
|
|
221
|
-
process.stdout.write(renderRecoverOutput(
|
|
305
|
+
process.stdout.write(renderRecoverOutput(afterPacket));
|
|
306
|
+
if ((0, recovery_reconcile_1.recoveryIsBasicPacket)(afterPacket)) {
|
|
307
|
+
process.stdout.write(renderBasicHint());
|
|
308
|
+
}
|
|
222
309
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.runSetupMcp = runSetupMcp;
|
|
4
|
+
const node_path_1 = require("node:path");
|
|
4
5
|
const config_1 = require("../config");
|
|
6
|
+
const mcp_runtime_1 = require("../mcp-runtime");
|
|
5
7
|
const MCP_SERVER_NAME = "agentbridge";
|
|
6
8
|
function standardSnippet(projectId, apiKey, apiBaseUrl) {
|
|
7
9
|
const serverConfig = {
|
|
@@ -47,8 +49,27 @@ async function runSetupMcp(options = {}) {
|
|
|
47
49
|
else {
|
|
48
50
|
process.stdout.write("\n✓ Credentials filled from .agentbridge/config.json\n");
|
|
49
51
|
}
|
|
52
|
+
const cliDistDir = (0, node_path_1.resolve)(__dirname, "..");
|
|
53
|
+
if (!(0, mcp_runtime_1.isMcpRuntimeAvailable)(cliDistDir)) {
|
|
54
|
+
process.stdout.write([
|
|
55
|
+
"",
|
|
56
|
+
"⚠ MCP runtime is missing from this CLI install.",
|
|
57
|
+
" `agentbridge mcp` will exit until you reinstall:",
|
|
58
|
+
" npm install -g @agentbridge1/cli@latest",
|
|
59
|
+
"",
|
|
60
|
+
" Or point mcp.json at a repo build:",
|
|
61
|
+
" node /path/to/AuthAgent/cli/dist/mcp/agentbridge-mcp.js",
|
|
62
|
+
"",
|
|
63
|
+
].join("\n"));
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
process.stdout.write([
|
|
67
|
+
"",
|
|
68
|
+
"✓ MCP runtime is bundled with this CLI (`agentbridge mcp` is ready).",
|
|
69
|
+
"",
|
|
70
|
+
].join("\n"));
|
|
71
|
+
}
|
|
50
72
|
process.stdout.write([
|
|
51
|
-
"",
|
|
52
73
|
"After saving the config, restart your editor to activate the MCP server.",
|
|
53
74
|
"The MCP server lets your AI assistant call tools like agent_hello, check AgentBridge status, and trigger approvals.",
|
|
54
75
|
"",
|