@agentbridge1/cli 0.0.5 → 0.0.7
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 +5 -2
- package/dist/commands/doctor.js +228 -63
- package/dist/commands/install-rules.js +64 -0
- package/dist/commands/proof-guidance.js +30 -0
- package/dist/commands/recover.js +121 -23
- package/dist/commands/room.js +82 -0
- 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/config.js +31 -1
- package/dist/error-catalog.js +51 -16
- package/dist/gates.js +3 -3
- package/dist/git-evidence.js +2 -0
- package/dist/http.js +29 -0
- package/dist/index.js +78 -30
- package/dist/init.js +134 -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/rules-sync.js +138 -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-07T04:20:05.843Z",
|
|
3
|
+
"gitHead": "aa4b2fb",
|
|
4
|
+
"sourceLatestMtime": "2026-06-07T04:16:53.273Z",
|
|
5
|
+
"sourceLatestFile": "src/commands/room.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
|
@@ -293,6 +293,9 @@ async function runConnect(options = {}) {
|
|
|
293
293
|
diagnostics.bootstrapStatus = "skipped";
|
|
294
294
|
diagnostics.rotateStatus = "skipped";
|
|
295
295
|
}
|
|
296
|
+
if (connectionUpgraded) {
|
|
297
|
+
await verifyCredentials(projectId, effectiveApiKey, apiBaseUrl);
|
|
298
|
+
}
|
|
296
299
|
if (!executionSurfaceId) {
|
|
297
300
|
(0, config_1.updateConfig)({
|
|
298
301
|
projectId,
|
|
@@ -358,7 +361,7 @@ async function runConnect(options = {}) {
|
|
|
358
361
|
"",
|
|
359
362
|
"Next:",
|
|
360
363
|
" agentbridge doctor",
|
|
361
|
-
" agentbridge
|
|
364
|
+
" agentbridge watch",
|
|
362
365
|
"",
|
|
363
366
|
].join("\n"));
|
|
364
367
|
}
|
|
@@ -366,6 +369,6 @@ async function runConnect(options = {}) {
|
|
|
366
369
|
process.stdout.write("✓ Connected.\n");
|
|
367
370
|
process.stdout.write("Run `agentbridge use <agent-id>` and then:\n");
|
|
368
371
|
process.stdout.write(" agentbridge doctor\n");
|
|
369
|
-
process.stdout.write(" agentbridge
|
|
372
|
+
process.stdout.write(" agentbridge watch\n");
|
|
370
373
|
}
|
|
371
374
|
}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -10,9 +10,16 @@ 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");
|
|
14
|
+
const rules_sync_1 = require("../rules-sync");
|
|
13
15
|
function cliRootFromCommandDir() {
|
|
14
16
|
return (0, node_path_1.resolve)(__dirname, "..", "..");
|
|
15
17
|
}
|
|
18
|
+
function isRecoveryBaselinePendingHello(hello) {
|
|
19
|
+
return (hello.setup_required === true ||
|
|
20
|
+
hello.agentbridge_status === "recovery_baseline_pending" ||
|
|
21
|
+
hello.instruction?.recovery_status === "baseline_required");
|
|
22
|
+
}
|
|
16
23
|
function normalizeReasonCandidate(value) {
|
|
17
24
|
if (!value)
|
|
18
25
|
return undefined;
|
|
@@ -86,11 +93,70 @@ function extractHttpReason(error) {
|
|
|
86
93
|
}
|
|
87
94
|
return `http_${error.status}`;
|
|
88
95
|
}
|
|
89
|
-
function
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
96
|
+
function detectGovernanceSignals(workspaceRoot, expectedProjectId) {
|
|
97
|
+
const analysis = (0, rules_sync_1.analyzeRulesArtifacts)(workspaceRoot, expectedProjectId);
|
|
98
|
+
const mcpConfigPath = (0, node_path_1.resolve)(workspaceRoot, ".cursor", "mcp.json");
|
|
99
|
+
let mcpConfigured = false;
|
|
100
|
+
if ((0, node_fs_1.existsSync)(mcpConfigPath)) {
|
|
101
|
+
try {
|
|
102
|
+
const parsed = JSON.parse((0, node_fs_1.readFileSync)(mcpConfigPath, "utf8"));
|
|
103
|
+
mcpConfigured = Boolean(parsed?.mcpServers &&
|
|
104
|
+
(parsed.mcpServers["agentbridge"] || parsed.mcpServers["agentbridge-mcp"]));
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
mcpConfigured = false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
rulesFilesPresent: analysis.filesPresent,
|
|
112
|
+
rulesFormat: analysis.format,
|
|
113
|
+
rulesProjectIdInRepo: analysis.projectIdInRepo,
|
|
114
|
+
rulesProjectIdMatches: analysis.projectIdMatchesConfig,
|
|
115
|
+
rulesInstalled: analysis.protocolRulesValid,
|
|
116
|
+
rulesIssues: analysis.issues,
|
|
117
|
+
mcpConfigured,
|
|
118
|
+
governanceStatus: analysis.protocolRulesValid && mcpConfigured ? "active" : "inactive",
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function isRouteMissingBody(body) {
|
|
122
|
+
return body.toLowerCase().includes("route not found");
|
|
123
|
+
}
|
|
124
|
+
function mapProjectAccessFailure(error) {
|
|
125
|
+
if (error instanceof http_1.CliHttpError) {
|
|
126
|
+
const reason = extractHttpReason(error);
|
|
127
|
+
if (reason === "not_project_member") {
|
|
128
|
+
return {
|
|
129
|
+
status: "failed",
|
|
130
|
+
reason,
|
|
131
|
+
suggestedNextAction: "use an API key/agent that is a member of this project, or add this agent to the project.",
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
if (reason === "unauthorized") {
|
|
135
|
+
return {
|
|
136
|
+
status: "failed",
|
|
137
|
+
reason,
|
|
138
|
+
suggestedNextAction: "verify AGENTBRIDGE_API_KEY is valid for this environment and has project read access.",
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (reason === "project_not_found") {
|
|
142
|
+
return {
|
|
143
|
+
status: "failed",
|
|
144
|
+
reason,
|
|
145
|
+
suggestedNextAction: "verify AGENTBRIDGE_PROJECT_ID points to an existing project in this API environment.",
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
status: "failed",
|
|
150
|
+
reason,
|
|
151
|
+
suggestedNextAction: "confirm project ID, API key, and base URL are correct and that this key has project read access.",
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
const messageReason = error instanceof Error ? normalizeReasonCandidate(error.message) : undefined;
|
|
155
|
+
return {
|
|
156
|
+
status: "failed",
|
|
157
|
+
reason: messageReason ?? "network_error",
|
|
158
|
+
suggestedNextAction: "check network reachability to the API base URL and retry doctor.",
|
|
159
|
+
};
|
|
94
160
|
}
|
|
95
161
|
async function checkProjectAccess(ctx) {
|
|
96
162
|
if (!ctx.configComplete) {
|
|
@@ -102,46 +168,33 @@ async function checkProjectAccess(ctx) {
|
|
|
102
168
|
const projectId = ctx.projectId;
|
|
103
169
|
const apiKey = ctx.apiKey;
|
|
104
170
|
const apiBaseUrl = ctx.apiBaseUrl;
|
|
171
|
+
const syncCtx = { projectId, apiKey, apiBaseUrl, apiKeySource: "config" };
|
|
172
|
+
const summaryPath = `/v1/dev/projects/${encodeURIComponent(projectId)}/summary`;
|
|
173
|
+
const packetPath = `/v1/dev/projects/${encodeURIComponent(projectId)}/packet`;
|
|
105
174
|
try {
|
|
106
|
-
|
|
175
|
+
await (0, http_1.getJson)(syncCtx, summaryPath);
|
|
176
|
+
let packet;
|
|
177
|
+
try {
|
|
178
|
+
packet = await (0, http_1.getJson)(syncCtx, packetPath);
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// Summary proves access; packet is optional (recovery metadata only).
|
|
182
|
+
}
|
|
107
183
|
return { status: "ok", packet };
|
|
108
184
|
}
|
|
109
185
|
catch (error) {
|
|
110
|
-
if (error instanceof http_1.CliHttpError
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
suggestedNextAction: "use an API key/agent that is a member of this project, or add this agent to the project.",
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
if (reason === "unauthorized") {
|
|
120
|
-
return {
|
|
121
|
-
status: "failed",
|
|
122
|
-
reason,
|
|
123
|
-
suggestedNextAction: "verify AGENTBRIDGE_API_KEY is valid for this environment and has project read access.",
|
|
124
|
-
};
|
|
186
|
+
if (error instanceof http_1.CliHttpError &&
|
|
187
|
+
error.status === 404 &&
|
|
188
|
+
isRouteMissingBody(error.body ?? "")) {
|
|
189
|
+
try {
|
|
190
|
+
const packet = await (0, http_1.getJson)(syncCtx, packetPath);
|
|
191
|
+
return { status: "ok", packet };
|
|
125
192
|
}
|
|
126
|
-
|
|
127
|
-
return
|
|
128
|
-
status: "failed",
|
|
129
|
-
reason,
|
|
130
|
-
suggestedNextAction: "verify AGENTBRIDGE_PROJECT_ID points to an existing project in this API environment.",
|
|
131
|
-
};
|
|
193
|
+
catch (packetError) {
|
|
194
|
+
return mapProjectAccessFailure(packetError);
|
|
132
195
|
}
|
|
133
|
-
return {
|
|
134
|
-
status: "failed",
|
|
135
|
-
reason,
|
|
136
|
-
suggestedNextAction: "confirm project ID, API key, and base URL are correct and that this key has project read access.",
|
|
137
|
-
};
|
|
138
196
|
}
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
status: "failed",
|
|
142
|
-
reason: messageReason ?? "network_error",
|
|
143
|
-
suggestedNextAction: "check network reachability to the API base URL and retry doctor.",
|
|
144
|
-
};
|
|
197
|
+
return mapProjectAccessFailure(error);
|
|
145
198
|
}
|
|
146
199
|
}
|
|
147
200
|
async function checkIdentityAccess(ctx) {
|
|
@@ -156,7 +209,8 @@ async function checkIdentityAccess(ctx) {
|
|
|
156
209
|
}
|
|
157
210
|
const helloUrl = `${ctx.apiBaseUrl}/v1/dev/projects/${ctx.projectId}/hello`;
|
|
158
211
|
let identityModel = "unknown";
|
|
159
|
-
let
|
|
212
|
+
let helloExecutionSurfaceId = null;
|
|
213
|
+
let baselinePending = false;
|
|
160
214
|
try {
|
|
161
215
|
const helloRes = await fetch(helloUrl, {
|
|
162
216
|
method: "POST",
|
|
@@ -168,18 +222,22 @@ async function checkIdentityAccess(ctx) {
|
|
|
168
222
|
});
|
|
169
223
|
if (helloRes.ok) {
|
|
170
224
|
const hello = (await helloRes.json());
|
|
225
|
+
baselinePending = isRecoveryBaselinePendingHello(hello);
|
|
171
226
|
if (hello.identity_model === "work_identity") {
|
|
172
227
|
identityModel = "work_identity";
|
|
173
228
|
}
|
|
174
229
|
else if (hello.identity_model === "legacy") {
|
|
175
230
|
identityModel = "legacy";
|
|
176
231
|
}
|
|
177
|
-
|
|
232
|
+
helloExecutionSurfaceId = hello.execution_surface?.id?.trim() || null;
|
|
178
233
|
}
|
|
179
234
|
}
|
|
180
235
|
catch {
|
|
181
236
|
// Keep default unknown/null and continue with identity resolution checks.
|
|
182
237
|
}
|
|
238
|
+
const configSurfaceId = ctx.configExecutionSurfaceId?.trim() || null;
|
|
239
|
+
const executionSurfaceId = helloExecutionSurfaceId || configSurfaceId;
|
|
240
|
+
const executionSurfaceSource = helloExecutionSurfaceId ? "hello" : configSurfaceId ? "config" : undefined;
|
|
183
241
|
try {
|
|
184
242
|
const syncCtx = {
|
|
185
243
|
projectId: ctx.projectId,
|
|
@@ -192,18 +250,28 @@ async function checkIdentityAccess(ctx) {
|
|
|
192
250
|
(0, server_sync_1.listWorkIdentities)(syncCtx),
|
|
193
251
|
]);
|
|
194
252
|
const callerId = callerPacket?.work_identity?.id ?? null;
|
|
195
|
-
const
|
|
196
|
-
if (
|
|
197
|
-
|
|
253
|
+
const callerResolvable = Boolean(callerId) || identities.length === 1;
|
|
254
|
+
if (identityModel === "unknown" &&
|
|
255
|
+
callerResolvable &&
|
|
256
|
+
(baselinePending || Boolean(configSurfaceId))) {
|
|
257
|
+
identityModel = "work_identity";
|
|
198
258
|
}
|
|
199
|
-
|
|
200
|
-
|
|
259
|
+
const startCapable = Boolean(executionSurfaceId);
|
|
260
|
+
if (callerResolvable) {
|
|
261
|
+
return {
|
|
262
|
+
status: "ok",
|
|
263
|
+
identityModel,
|
|
264
|
+
executionSurfaceId,
|
|
265
|
+
executionSurfaceSource,
|
|
266
|
+
startCapable,
|
|
267
|
+
};
|
|
201
268
|
}
|
|
202
269
|
return {
|
|
203
270
|
status: "failed",
|
|
204
271
|
reason: "caller_identity_unresolved",
|
|
205
272
|
identityModel,
|
|
206
273
|
executionSurfaceId,
|
|
274
|
+
executionSurfaceSource,
|
|
207
275
|
startCapable,
|
|
208
276
|
};
|
|
209
277
|
}
|
|
@@ -213,12 +281,14 @@ async function checkIdentityAccess(ctx) {
|
|
|
213
281
|
reason: "caller_identity_unresolved",
|
|
214
282
|
identityModel,
|
|
215
283
|
executionSurfaceId,
|
|
284
|
+
executionSurfaceSource,
|
|
216
285
|
startCapable: Boolean(executionSurfaceId),
|
|
217
286
|
};
|
|
218
287
|
}
|
|
219
288
|
}
|
|
220
289
|
async function runDoctor(cliRootOverride) {
|
|
221
290
|
const cliRoot = cliRootOverride ?? cliRootFromCommandDir();
|
|
291
|
+
const workspaceRoot = process.cwd();
|
|
222
292
|
const cfg = (0, config_1.readConfig)();
|
|
223
293
|
const freshness = (0, dist_freshness_1.getDistFreshnessReport)(cliRoot);
|
|
224
294
|
const configPath = cliRootOverride
|
|
@@ -238,6 +308,7 @@ async function runDoctor(cliRootOverride) {
|
|
|
238
308
|
const projectConfigPresent = projectIdPresent && apiKeyPresent && baseUrlPresent;
|
|
239
309
|
const activeSession = (0, session_state_1.readSessionState)();
|
|
240
310
|
const hasActiveWork = Boolean(activeSession?.id || activeSession?.serverSessionId);
|
|
311
|
+
const governance = detectGovernanceSignals(workspaceRoot, resolvedProjectId ?? undefined);
|
|
241
312
|
const envContributed = Boolean(process.env.AGENTBRIDGE_PROJECT_ID) ||
|
|
242
313
|
Boolean(process.env.AGENTBRIDGE_API_KEY) ||
|
|
243
314
|
Boolean(process.env.AGENTBRIDGE_BASE_URL) ||
|
|
@@ -271,18 +342,35 @@ async function runDoctor(cliRootOverride) {
|
|
|
271
342
|
if (projectAccess.reason) {
|
|
272
343
|
lines.push(`Project access reason: ${projectAccess.reason}`);
|
|
273
344
|
}
|
|
345
|
+
lines.push(`API key accepted by server: ${projectAccess.status === "ok"
|
|
346
|
+
? "yes"
|
|
347
|
+
: projectAccess.status === "skipped"
|
|
348
|
+
? "skipped"
|
|
349
|
+
: "no"}`);
|
|
274
350
|
const identityAccess = await checkIdentityAccess({
|
|
275
351
|
projectId: resolvedProjectId,
|
|
276
352
|
apiKey: resolvedApiKey,
|
|
277
353
|
apiBaseUrl: resolvedBaseUrl,
|
|
278
|
-
configComplete: projectConfigPresent
|
|
354
|
+
configComplete: projectConfigPresent,
|
|
355
|
+
configExecutionSurfaceId: cfg.executionSurfaceId,
|
|
279
356
|
});
|
|
280
|
-
lines.push(`
|
|
281
|
-
|
|
282
|
-
|
|
357
|
+
lines.push(`Rules files present: ${governance.rulesFilesPresent ? "yes" : "no"}`);
|
|
358
|
+
lines.push(`Rules format: ${governance.rulesFormat}`);
|
|
359
|
+
if (governance.rulesProjectIdInRepo) {
|
|
360
|
+
lines.push(`Rules project ID: ${governance.rulesProjectIdInRepo}`);
|
|
361
|
+
}
|
|
362
|
+
if (governance.rulesProjectIdMatches !== null) {
|
|
363
|
+
lines.push(`Rules project ID match: ${governance.rulesProjectIdMatches ? "yes" : "no"}`);
|
|
364
|
+
}
|
|
365
|
+
lines.push(`Rules installed: ${governance.rulesInstalled ? "yes" : "no"}`);
|
|
366
|
+
lines.push(`MCP configured: ${governance.mcpConfigured ? "yes" : "no"}`);
|
|
367
|
+
lines.push(`Agent governance: ${governance.governanceStatus}`);
|
|
368
|
+
if (governance.rulesIssues.length > 0) {
|
|
369
|
+
for (const issue of governance.rulesIssues) {
|
|
370
|
+
lines.push(`Rules issue: ${issue}`);
|
|
371
|
+
}
|
|
372
|
+
lines.push("Rules fix: run `agentbridge install-rules`");
|
|
283
373
|
}
|
|
284
|
-
lines.push(`Caller identity model: ${identityAccess.identityModel}`);
|
|
285
|
-
lines.push(`Execution surface present: ${identityAccess.executionSurfaceId ? "yes" : "no"}`);
|
|
286
374
|
lines.push(`Start capable: ${identityAccess.startCapable ? "yes" : "no"}`);
|
|
287
375
|
if (projectAccess.status === "failed" && projectAccess.reason) {
|
|
288
376
|
const view = (0, error_catalog_1.catalogViewForDoctorReason)(projectAccess.reason, projectAccess.suggestedNextAction);
|
|
@@ -309,55 +397,132 @@ async function runDoctor(cliRootOverride) {
|
|
|
309
397
|
productStatus = "active_work_found";
|
|
310
398
|
}
|
|
311
399
|
else {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
400
|
+
if ((0, recovery_reconcile_1.recoveryBaselineRequired)(projectAccess.packet)) {
|
|
401
|
+
productStatus = "needs_recover";
|
|
402
|
+
}
|
|
403
|
+
else if ((0, recovery_reconcile_1.recoveryIsBasicPacket)(projectAccess.packet)) {
|
|
404
|
+
productStatus = "ready_basic_recovery";
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
productStatus = "ready";
|
|
408
|
+
}
|
|
315
409
|
}
|
|
316
410
|
}
|
|
411
|
+
const localSupervisionReady = true;
|
|
412
|
+
const cloudSyncReady = projectAccess.status === "ok";
|
|
413
|
+
const strictTrackedReady = projectAccess.status === "ok" && identityAccess.status === "ok" && identityAccess.startCapable;
|
|
414
|
+
lines.push("");
|
|
415
|
+
lines.push("Capability levels:");
|
|
416
|
+
lines.push(`- Local supervision: ${localSupervisionReady ? "ready" : "unavailable"}`);
|
|
417
|
+
lines.push(`- Cloud sync: ${cloudSyncReady ? "ready" : "unavailable"}`);
|
|
418
|
+
lines.push(`- Strict tracked work: ${strictTrackedReady ? "ready" : "unavailable"}`);
|
|
419
|
+
if (!cloudSyncReady && projectAccess.reason) {
|
|
420
|
+
lines.push(` Cloud sync note: ${projectAccess.reason}`);
|
|
421
|
+
}
|
|
422
|
+
if (!strictTrackedReady && identityAccess.reason) {
|
|
423
|
+
lines.push(` Strict tracked note: ${identityAccess.reason}`);
|
|
424
|
+
}
|
|
317
425
|
lines.push("");
|
|
318
426
|
lines.push("Product status:");
|
|
319
427
|
if (productStatus === "ready") {
|
|
320
428
|
lines.push("- Connection: ready");
|
|
429
|
+
lines.push("- Governance: " + governance.governanceStatus);
|
|
321
430
|
lines.push("- Recovery: ready");
|
|
322
|
-
lines.push(
|
|
431
|
+
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
432
|
+
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
433
|
+
lines.push("- Next: run `agentbridge watch` beside Cursor for live supervision");
|
|
434
|
+
}
|
|
435
|
+
else if (productStatus === "ready_basic_recovery") {
|
|
436
|
+
lines.push("- Connection: ready");
|
|
437
|
+
lines.push("- Governance: " + governance.governanceStatus);
|
|
438
|
+
lines.push("- Recovery: basic");
|
|
439
|
+
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
440
|
+
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
441
|
+
lines.push("- Note: Project context exists, but domains are not fully mapped yet.");
|
|
442
|
+
lines.push("- Next: run `agentbridge recover --force` for a full domain rebuild, or `agentbridge watch` for live supervision");
|
|
323
443
|
}
|
|
324
444
|
else if (productStatus === "active_work_found") {
|
|
445
|
+
const recoveryBasic = (0, recovery_reconcile_1.recoveryIsBasicPacket)(projectAccess.packet);
|
|
325
446
|
lines.push("- Connection: ready");
|
|
326
|
-
lines.push("-
|
|
447
|
+
lines.push("- Governance: " + governance.governanceStatus);
|
|
448
|
+
lines.push("- Recovery: " + (recoveryBasic ? "basic" : "ready"));
|
|
449
|
+
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
450
|
+
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
451
|
+
if (recoveryBasic) {
|
|
452
|
+
lines.push("- Note: Project context exists, but domains are not fully mapped yet.");
|
|
453
|
+
}
|
|
327
454
|
lines.push("- Active work: found");
|
|
328
|
-
lines.push("- Next: agentbridge
|
|
455
|
+
lines.push("- Next: run `agentbridge watch` beside Cursor for live supervision");
|
|
329
456
|
}
|
|
330
457
|
else if (productStatus === "needs_recover") {
|
|
331
458
|
lines.push("- Connection: ready");
|
|
459
|
+
lines.push("- Governance: " + governance.governanceStatus);
|
|
332
460
|
lines.push("- Recovery: required");
|
|
461
|
+
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
462
|
+
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
333
463
|
lines.push("- Next: agentbridge recover");
|
|
334
464
|
}
|
|
335
465
|
else {
|
|
336
466
|
lines.push("- Connection: incomplete");
|
|
467
|
+
lines.push("- Governance: " + governance.governanceStatus);
|
|
337
468
|
lines.push("- Recovery: pending");
|
|
469
|
+
lines.push(`- Rules: ${governance.rulesInstalled ? "installed" : "missing"}`);
|
|
470
|
+
lines.push(`- MCP: ${governance.mcpConfigured ? "configured" : "missing"}`);
|
|
338
471
|
if (!projectConfigPresent) {
|
|
339
472
|
lines.push("- Note: Connection details are missing. Add credentials, then rerun agentbridge doctor.");
|
|
340
473
|
}
|
|
474
|
+
else if (projectAccess.status === "failed" &&
|
|
475
|
+
(projectAccess.reason === "unauthorized" ||
|
|
476
|
+
projectAccess.reason === "forbidden" ||
|
|
477
|
+
projectAccess.reason === "not_project_member")) {
|
|
478
|
+
lines.push("- Reason: API key rejected by server.");
|
|
479
|
+
lines.push("- Next: run `agentbridge room exit`, get a fresh key from the dashboard, then `agentbridge connect`.");
|
|
480
|
+
if (identityAccess.executionSurfaceId) {
|
|
481
|
+
lines.push("- Note: Config still has a saved execution surface, but the server rejected the stored API key.");
|
|
482
|
+
}
|
|
483
|
+
}
|
|
341
484
|
else if (!identityAccess.startCapable) {
|
|
342
485
|
lines.push("- Reason: execution surface missing.");
|
|
343
486
|
lines.push("- Next: agentbridge connect");
|
|
344
487
|
}
|
|
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
488
|
else {
|
|
349
489
|
lines.push("- Note: Connection check failed. Verify credentials/network, then rerun agentbridge doctor.");
|
|
350
490
|
}
|
|
351
|
-
if (identityAccess.startCapable
|
|
491
|
+
if (identityAccess.startCapable &&
|
|
492
|
+
projectAccess.status === "failed" &&
|
|
493
|
+
projectAccess.reason !== "unauthorized" &&
|
|
494
|
+
projectAccess.reason !== "forbidden" &&
|
|
495
|
+
projectAccess.reason !== "not_project_member") {
|
|
352
496
|
lines.push("- Next: agentbridge doctor");
|
|
353
497
|
}
|
|
354
498
|
}
|
|
499
|
+
lines.push("");
|
|
500
|
+
lines.push("Advanced details:");
|
|
501
|
+
lines.push(`- Caller identity access: ${identityAccess.status}`);
|
|
502
|
+
if (identityAccess.reason) {
|
|
503
|
+
lines.push(`- Caller identity reason: ${identityAccess.reason}`);
|
|
504
|
+
}
|
|
505
|
+
lines.push(`- Caller identity model: ${identityAccess.identityModel}`);
|
|
506
|
+
lines.push(`- Execution surface present: ${identityAccess.executionSurfaceId ? "yes" : "no"}`);
|
|
507
|
+
if (identityAccess.executionSurfaceSource) {
|
|
508
|
+
lines.push(`- Execution surface source: ${identityAccess.executionSurfaceSource}`);
|
|
509
|
+
}
|
|
510
|
+
lines.push(`- Start capable (strict/session modes): ${identityAccess.startCapable ? "yes" : "no"}`);
|
|
511
|
+
if (identityAccess.status !== "ok") {
|
|
512
|
+
lines.push("- Note: internal identity mismatch affects strict/resume flows, not room-level inferred watch startup.");
|
|
513
|
+
}
|
|
514
|
+
if (governance.governanceStatus === "inactive") {
|
|
515
|
+
lines.push("");
|
|
516
|
+
lines.push("Governance note: AgentBridge can review in terminal, but your AI agent may not stop automatically until rules and MCP are both configured.");
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
519
|
+
lines.push("");
|
|
520
|
+
lines.push("Governance note: AgentBridge rules are installed and MCP is configured. The AI agent should stop when AgentBridge flags blocked work.");
|
|
521
|
+
}
|
|
355
522
|
process.stdout.write(`${lines.join("\n")}\n`);
|
|
356
523
|
if (freshness.state === "stale")
|
|
357
524
|
return 1;
|
|
358
525
|
if (projectAccess.status === "failed")
|
|
359
526
|
return 1;
|
|
360
|
-
if (identityAccess.status === "failed")
|
|
361
|
-
return 1;
|
|
362
527
|
return 0;
|
|
363
528
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runInstallRules = runInstallRules;
|
|
4
|
+
const node_path_1 = require("node:path");
|
|
5
|
+
const node_process_1 = require("node:process");
|
|
6
|
+
const config_1 = require("../config");
|
|
7
|
+
const errors_1 = require("../errors");
|
|
8
|
+
const http_1 = require("../http");
|
|
9
|
+
const rules_sync_1 = require("../rules-sync");
|
|
10
|
+
function resolveNetworkContext(overrides) {
|
|
11
|
+
const cfg = (0, config_1.readConfig)();
|
|
12
|
+
const projectId = overrides.projectId ?? process.env.AGENTBRIDGE_PROJECT_ID ?? cfg.projectId ?? "";
|
|
13
|
+
const apiKey = overrides.apiKey ?? process.env.AGENTBRIDGE_API_KEY ?? cfg.apiKey ?? "";
|
|
14
|
+
const apiBaseUrl = overrides.apiBaseUrl ??
|
|
15
|
+
process.env.AGENTBRIDGE_BASE_URL ??
|
|
16
|
+
cfg.apiBaseUrl ??
|
|
17
|
+
"https://agentauth-api-production.up.railway.app";
|
|
18
|
+
if (!projectId || !apiKey) {
|
|
19
|
+
throw (0, errors_1.catalogCliError)("CONFIG_INCOMPLETE");
|
|
20
|
+
}
|
|
21
|
+
return { projectId, apiKey, apiBaseUrl };
|
|
22
|
+
}
|
|
23
|
+
async function runInstallRules(opts = {}) {
|
|
24
|
+
const ctx = resolveNetworkContext(opts);
|
|
25
|
+
const workspaceRoot = (0, node_process_1.cwd)();
|
|
26
|
+
let rules;
|
|
27
|
+
try {
|
|
28
|
+
rules = await (0, rules_sync_1.fetchProjectRules)(ctx);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if ((0, http_1.isCliHttpError)(error)) {
|
|
32
|
+
throw new errors_1.SafeCliError(`Could not fetch AgentBridge rules for project ${ctx.projectId} (${error.status}).`);
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
if (!Array.isArray(rules.files) || rules.files.length === 0) {
|
|
37
|
+
throw new errors_1.SafeCliError("AgentBridge rules response did not include any files to install.");
|
|
38
|
+
}
|
|
39
|
+
(0, rules_sync_1.writeRulesFiles)(workspaceRoot, rules.files);
|
|
40
|
+
let installedAt = null;
|
|
41
|
+
try {
|
|
42
|
+
const marked = await (0, rules_sync_1.markProjectRulesInstalled)(ctx);
|
|
43
|
+
installedAt = marked.rules_installed_at ?? null;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if ((0, http_1.isCliHttpError)(error)) {
|
|
47
|
+
throw new errors_1.SafeCliError(`Wrote rules files locally, but could not mark them installed on the server (${error.status}).`);
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
const projectName = (0, rules_sync_1.extractProjectNameFromRulesResponse)(rules.files);
|
|
52
|
+
const lines = [
|
|
53
|
+
"Installed AgentBridge protocol rules:",
|
|
54
|
+
` Project: ${projectName ?? "(unknown name)"} (${ctx.projectId})`,
|
|
55
|
+
` Wrote: ${(0, node_path_1.resolve)(workspaceRoot, "AGENTBRIDGE.md")}`,
|
|
56
|
+
` Wrote: ${(0, node_path_1.resolve)(workspaceRoot, ".cursor", "rules", "agentbridge.mdc")}`,
|
|
57
|
+
];
|
|
58
|
+
if (installedAt) {
|
|
59
|
+
lines.push(` Server marked installed at: ${installedAt}`);
|
|
60
|
+
}
|
|
61
|
+
lines.push("");
|
|
62
|
+
lines.push("Next: run `agentbridge doctor` to verify rules and MCP configuration.");
|
|
63
|
+
process.stdout.write(`${lines.join("\n")}\n`);
|
|
64
|
+
}
|
|
@@ -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
|
+
}
|