@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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "builtAt": "2026-06-03T09:58:38.231Z",
3
- "gitHead": "6fcc74c",
4
- "sourceLatestMtime": "2026-06-03T05:08:44.109Z",
5
- "sourceLatestFile": "src/commands/doctor.ts"
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
  }
@@ -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
- if (report.decision === "needs_proof")
40
- return "PROOF_MISSING";
41
- if (report.decision === "stale_evidence")
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) {
@@ -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
- if (report.decision === "needs_proof") {
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.");
@@ -358,7 +358,7 @@ async function runConnect(options = {}) {
358
358
  "",
359
359
  "Next:",
360
360
  " agentbridge doctor",
361
- " agentbridge start",
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 start\n");
369
+ process.stdout.write(" agentbridge watch\n");
370
370
  }
371
371
  }
@@ -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 recoveryRequiredByPacket(packet) {
90
- if (!packet || packet.project_mode !== "recovery")
91
- return false;
92
- const status = packet.recovery_status ?? null;
93
- return status === "baseline_required" || status === "pending" || status === null;
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(`Caller identity access: ${identityAccess.status}`);
281
- if (identityAccess.reason) {
282
- lines.push(`Caller identity reason: ${identityAccess.reason}`);
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
- productStatus = recoveryRequiredByPacket(projectAccess.packet)
313
- ? "needs_recover"
314
- : "ready";
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("- Next: agentbridge start");
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("- Recovery: ready");
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 start");
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
+ }
@@ -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 domainCount = packet.domains_summary.length;
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 packet.domains_summary) {
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 start");
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 baselineRequired(packet) {
66
- const status = packet.recovery_status ?? null;
67
- if (packet.project_mode !== "recovery")
68
- return false;
69
- return status === "baseline_required" || status === "pending" || status === null;
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 needsRecovery = baselineRequired(beforePacket);
179
- let actionTaken = "baseline already exists; no rebuild needed";
180
- if (needsRecovery || options.force) {
181
- actionTaken = needsRecovery
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
- : "force-refresh recovery baseline from repository evidence";
184
- process.stdout.write("Building recovery baseline now...\n");
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
- if (baselineRequired(afterPacket)) {
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 start",
303
+ next: "agentbridge watch",
220
304
  }));
221
- process.stdout.write(renderRecoverOutput(packet));
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
  "",