@agentbridge1/cli 0.0.4 → 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.
@@ -44,7 +44,7 @@ const CATALOG = {
44
44
  title: "No active tracked work session.",
45
45
  what: "No active tracked work session was found for this command.",
46
46
  why: "Proof, verify, accept, and handoff require a bound work session.",
47
- next: 'Run `agentbridge start --summary "<work>" --scope "<path>"` then `agentbridge watch`.',
47
+ next: "Run `agentbridge watch` beside Cursor for live supervision, or `agentbridge verify -- <test command>` to record proof.",
48
48
  blocksAcceptance: true,
49
49
  },
50
50
  WORK_CONTEXT_BINDING_REQUIRED: {
@@ -53,7 +53,7 @@ const CATALOG = {
53
53
  title: "Work session binding required.",
54
54
  what: "This command needs a linked local/server work session.",
55
55
  why: "The CLI and server must agree on the active change request and session.",
56
- next: 'Run `agentbridge start --summary "<task>" --scope "<path>"` to create and bind a new session, or `agentbridge watch --change-request <id>` to bind an existing one.',
56
+ next: 'Run `agentbridge watch --allow-dirty` for default review, or `agentbridge watch --task "<task>" --scope "<path>"` for strict mode.',
57
57
  blocksAcceptance: true,
58
58
  },
59
59
  PROOF_STALE_AFTER_CHANGE: {
@@ -70,8 +70,8 @@ const CATALOG = {
70
70
  category: "SCOPE_DRIFT_ERROR",
71
71
  title: "Scope drift detected.",
72
72
  what: "The agent changed a file outside the declared scope.",
73
- why: "Out-of-scope edits block acceptance until reviewed or rescoped.",
74
- next: 'Options: (1) revert the out-of-scope file, (2) restart with an expanded scope via `agentbridge start --scope "<wider-path>"`, or (3) run `agentbridge handoff` before switching to a new scoped job.',
73
+ why: "Out-of-scope edits are not safe to trust until reviewed or rescoped.",
74
+ next: 'Options: (1) revert the out-of-scope file, (2) widen strict scope via `agentbridge watch --task "<work>" --scope "<wider-path>"`, or (3) split into a separate task.',
75
75
  blocksAcceptance: true,
76
76
  },
77
77
  HANDOFF_REQUIRED: {
@@ -176,9 +176,12 @@ const CATALOG = {
176
176
  code: "START_MISSING_ACTIVE_AGENT",
177
177
  category: "IDENTITY_ERROR",
178
178
  title: "No active agent configured.",
179
- what: "Neither activeAgentId nor --agent was provided for start.",
180
- why: "Start must bind work to a WorkIdentity in this project.",
181
- next: "Run `agentbridge identity list` then `agentbridge use <agent-id>`, or pass --agent.",
179
+ what: "Neither activeAgentId nor --agent was provided for strict tracked start.",
180
+ why: "Strict tracked work (--summary/--scope, --resume, or --change-request) must bind to a WorkIdentity in this project.",
181
+ next: [
182
+ "For strict tracked work: run `agentbridge identity list` then `agentbridge use <agent-id>`, or pass --agent.",
183
+ "For room-level watching only: run `agentbridge start` with no strict flags.",
184
+ ].join("\n"),
182
185
  },
183
186
  START_EXECUTION_SURFACE_REQUIRED: {
184
187
  code: "START_EXECUTION_SURFACE_REQUIRED",
@@ -186,7 +189,13 @@ const CATALOG = {
186
189
  title: "Execution surface missing.",
187
190
  what: "No executionSurfaceId is saved in .agentbridge/config.json.",
188
191
  why: "The server needs a stable execution surface to open a tracked session.",
189
- next: "Run `agentbridge watch --execution-surface <surface-id>` once to persist it.",
192
+ next: [
193
+ "Run:",
194
+ " agentbridge connect --project <project-id> --api-key <key> --api-base-url <url>",
195
+ "Then:",
196
+ " agentbridge doctor",
197
+ "If this continues, AgentBridge could not create an AgentConnection/execution surface for this project.",
198
+ ].join("\n"),
190
199
  },
191
200
  START_AGENT_INVALID: {
192
201
  code: "START_AGENT_INVALID",
@@ -231,10 +240,10 @@ const CATALOG = {
231
240
  START_CR_OWNERSHIP_MISMATCH: {
232
241
  code: "START_CR_OWNERSHIP_MISMATCH",
233
242
  category: "START_ERROR",
234
- title: "Change request ownership mismatch.",
235
- what: "The change request is owned by a different WorkIdentity than this API key.",
236
- why: "Start cannot reassign an existing CR to another agent without authorization.",
237
- next: "Use an API key bound to the CR owner, or start a new change request.",
243
+ title: "Tracked task belongs to another connected agent.",
244
+ what: "AgentBridge found an old tracked task owned by a different connected agent.",
245
+ why: "AgentBridge will not let one connected agent automatically take over another agent's tracked work.",
246
+ next: "Run `agentbridge watch` for live supervision, or switch back to the original connected agent if you intend to resume old tracked work.",
238
247
  },
239
248
  START_CR_NOT_EXECUTABLE: {
240
249
  code: "START_CR_NOT_EXECUTABLE",
@@ -287,6 +296,33 @@ const CATALOG = {
287
296
  next: "Run `agentbridge verify -- <command>` then `agentbridge check`.",
288
297
  blocksAcceptance: true,
289
298
  },
299
+ PROOF_TOO_WEAK: {
300
+ code: "PROOF_TOO_WEAK",
301
+ category: "PROOF_ERROR",
302
+ title: "Proof too weak.",
303
+ what: "Verification ran, but proof strength is below what this change requires.",
304
+ why: "High-risk or source changes need stronger proof than file-existence checks.",
305
+ next: "Rerun with a stronger command from proof guidance (e.g. `agentbridge verify -- npm test`).",
306
+ blocksAcceptance: true,
307
+ },
308
+ PROOF_NOT_RELEVANT: {
309
+ code: "PROOF_NOT_RELEVANT",
310
+ category: "PROOF_ERROR",
311
+ title: "Proof not relevant.",
312
+ what: "Recorded proof does not cover the files or impact of this change.",
313
+ why: "Proof must match the changed files — unrelated passing tests do not count.",
314
+ next: "Rerun verification scoped to the changed files listed in the acceptance report.",
315
+ blocksAcceptance: true,
316
+ },
317
+ PROOF_IMPACT_COVERAGE_GAP: {
318
+ code: "PROOF_IMPACT_COVERAGE_GAP",
319
+ category: "PROOF_ERROR",
320
+ title: "Proof impact coverage gap.",
321
+ what: "Proof exists but does not cover required impact areas for this work type.",
322
+ why: "Some change profiles require broader verification than a single lightweight check.",
323
+ next: "Run the minimum commands listed under proof guidance in `agentbridge check`.",
324
+ blocksAcceptance: true,
325
+ },
290
326
  PROOF_EVIDENCE_NOT_RECORDED: {
291
327
  code: "PROOF_EVIDENCE_NOT_RECORDED",
292
328
  category: "PROOF_ERROR",
@@ -335,7 +371,7 @@ const CATALOG = {
335
371
  title: "Work already closed.",
336
372
  what: "This change request or session is already in a terminal acceptance state.",
337
373
  why: "Accept and verify cannot mutate closed work.",
338
- next: "Start a new scoped job with `agentbridge start`.",
374
+ next: "Run `agentbridge watch --allow-dirty` to review new coding work.",
339
375
  blocksAcceptance: true,
340
376
  },
341
377
  WORK_CONTEXT_SESSION_CR_MISMATCH: {
@@ -353,7 +389,7 @@ const CATALOG = {
353
389
  title: "Stale local session.",
354
390
  what: "Local session id no longer exists on the server.",
355
391
  why: "Watch and verify would track orphaned state.",
356
- next: 'Local session state has been cleared. Run `agentbridge start --summary "<task>" --scope "<path>"` to begin fresh.',
392
+ next: 'Local session state has been cleared. Run `agentbridge watch --allow-dirty` to review current work.',
357
393
  blocksAcceptance: true,
358
394
  },
359
395
  WORK_CONTEXT_SCOPE_MISMATCH: {
@@ -362,7 +398,7 @@ const CATALOG = {
362
398
  title: "Session scope or task mismatch.",
363
399
  what: "The active session was started with a different task or scope than requested.",
364
400
  why: "Resuming the wrong session would silently corrupt proof and scope boundaries.",
365
- next: 'Finish or abandon the current session (`agentbridge session abandon --reason "..."`) then rerun `agentbridge start --summary "<task>" --scope "<path>"`.',
401
+ next: 'Finish or abandon the current session (`agentbridge session abandon --reason "..."`) then rerun `agentbridge watch --task "<task>" --scope "<path>"`.',
366
402
  blocksAcceptance: true,
367
403
  },
368
404
  WORK_CONTEXT_AMBIGUOUS_SESSIONS: {
@@ -408,6 +444,9 @@ const SERVER_CODE_ALIASES = {
408
444
  proof_stale: "PROOF_STALE_AFTER_CHANGE",
409
445
  stale_evidence_after_change: "PROOF_STALE_AFTER_CHANGE",
410
446
  evidence_missing: "PROOF_MISSING",
447
+ proof_too_weak: "PROOF_TOO_WEAK",
448
+ proof_not_relevant: "PROOF_NOT_RELEVANT",
449
+ proof_impact_coverage_gap: "PROOF_IMPACT_COVERAGE_GAP",
411
450
  scope_drift: "SCOPE_DRIFT_OUT_OF_SCOPE_FILE",
412
451
  out_of_scope_file: "SCOPE_DRIFT_OUT_OF_SCOPE_FILE",
413
452
  cr_no_owner: "START_OWNER_UNRESOLVED",
@@ -418,11 +457,13 @@ const SERVER_CODE_ALIASES = {
418
457
  local_session_not_found: "WORK_CONTEXT_STALE_LOCAL_SESSION",
419
458
  };
420
459
  function mapServerCodeToCatalog(code) {
460
+ if (typeof code !== "string" || code.trim().length === 0)
461
+ return "";
421
462
  const normalized = code.toLowerCase();
422
463
  return SERVER_CODE_ALIASES[normalized] ?? code;
423
464
  }
424
465
  function catalogEntryForCode(code) {
425
- if (!code)
466
+ if (!code || typeof code !== "string")
426
467
  return null;
427
468
  const direct = CATALOG[code];
428
469
  if (direct)
package/dist/gates.js CHANGED
@@ -19,9 +19,9 @@ exports.ensureGatesFile = ensureGatesFile;
19
19
  const node_fs_1 = __importDefault(require("node:fs"));
20
20
  const node_path_1 = __importDefault(require("node:path"));
21
21
  exports.DEFAULT_GATES = {
22
- rollout_proof_too_weak: "warn_only",
23
- rollout_proof_not_relevant: "warn_only",
24
- rollout_impact_coverage_gap: "warn_only",
22
+ rollout_proof_too_weak: "hard_fail",
23
+ rollout_proof_not_relevant: "hard_fail",
24
+ rollout_impact_coverage_gap: "hard_fail",
25
25
  };
26
26
  exports.STATS_HISTORY_CAP = 20;
27
27
  exports.GITIGNORE_SESSION_LINE = ".agentbridge/session.json";
@@ -23,6 +23,8 @@ const PREFERRED_PREFIXES = [
23
23
  "db/",
24
24
  "prisma/",
25
25
  "supabase/",
26
+ "backend/",
27
+ "Hitch/",
26
28
  "lib/",
27
29
  "services/",
28
30
  "modules/",
package/dist/http.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CliMissingConfigError = exports.CliHttpError = void 0;
4
4
  exports.isCliHttpError = isCliHttpError;
5
5
  exports.parseCliHttpErrorBody = parseCliHttpErrorBody;
6
+ exports.extractHttpErrorCode = extractHttpErrorCode;
6
7
  exports.postJson = postJson;
7
8
  exports.putJson = putJson;
8
9
  exports.getJson = getJson;
@@ -33,6 +34,34 @@ function parseCliHttpErrorBody(err) {
33
34
  }
34
35
  return null;
35
36
  }
37
+ /** Extract a string error code from a parsed HTTP error body (handles nested error objects). */
38
+ function extractHttpErrorCode(parsed) {
39
+ if (!parsed)
40
+ return "";
41
+ const topCode = parsed["code"];
42
+ if (typeof topCode === "string" && topCode.trim().length > 0) {
43
+ return topCode.trim();
44
+ }
45
+ const err = parsed["error"];
46
+ if (typeof err === "string" && err.trim().length > 0) {
47
+ return err.trim();
48
+ }
49
+ if (err !== null && typeof err === "object" && !Array.isArray(err)) {
50
+ const nested = err["code"];
51
+ if (typeof nested === "string" && nested.trim().length > 0) {
52
+ return nested.trim();
53
+ }
54
+ const nestedMessage = err["message"];
55
+ if (typeof nestedMessage === "string" && nestedMessage.trim().length > 0) {
56
+ return nestedMessage.trim();
57
+ }
58
+ }
59
+ const message = parsed["message"];
60
+ if (typeof message === "string" && message.trim().length > 0) {
61
+ return message.trim();
62
+ }
63
+ return "";
64
+ }
36
65
  class CliMissingConfigError extends Error {
37
66
  code = "CONFIG_INCOMPLETE";
38
67
  constructor(message) {
package/dist/index.js CHANGED
@@ -30,9 +30,10 @@ const bug_1 = require("./commands/bug");
30
30
  const autopilot_1 = require("./commands/autopilot");
31
31
  const attention_1 = require("./commands/attention");
32
32
  const recover_1 = require("./commands/recover");
33
+ const proof_guidance_1 = require("./commands/proof-guidance");
33
34
  const node_path_1 = require("node:path");
34
35
  const node_child_process_1 = require("node:child_process");
35
- const node_fs_1 = require("node:fs");
36
+ const mcp_runtime_1 = require("./mcp-runtime");
36
37
  const errors_1 = require("./errors");
37
38
  const cli_failure_log_1 = require("./cli-failure-log");
38
39
  const session_state_1 = require("./session-state");
@@ -48,15 +49,19 @@ const COMMAND_HELP = {
48
49
  " Run `agentbridge connect` first to save credentials.\n",
49
50
  use: " agentbridge use <agent-id>\n" +
50
51
  " Set the active agent identity used by `watch` and `start`.\n",
51
- start: " agentbridge start [\"intent\"] [\"scope\"]\n" +
52
- " Advanced: agentbridge start --summary \"<summary>\" --scope \"<path-or-glob>\" [--domain <name>] [--agent <id>] [--change-request <cr_id>] [--resume]\n" +
53
- " Start supervised work. Without flags, proposes a smart work contract and asks for confirmation.\n" +
54
- " --resume Continue the active change request/session instead of creating a new one.\n",
55
- watch: " agentbridge watch [--change-request <cr_id>] [--execution-surface <es_id>] [--allow-dirty] [--daemon] [--once]\n" +
56
- " Product entrypoint: AgentBridge infers coding context and reviews proof/scope risk.\n" +
57
- " --allow-dirty Skip the pre-existing dirty-files prompt.\n" +
58
- " --daemon Non-interactive mode: skip all prompts, auto-deny domain crossings.\n" +
59
- " --once Run one startup/supervision pass and exit.\n",
52
+ start: " agentbridge start [\"intent\"] [--details] [--yes]\n" +
53
+ " Open or close a task checkpoint (not the live watcher).\n" +
54
+ " For live supervision beside Cursor, run `agentbridge watch`.\n" +
55
+ " Record proof: `agentbridge verify -- <test command>`.\n",
56
+ watch: " agentbridge watch [--allow-dirty] [--once] [--daemon] [--details] [--task \"<summary>\"] [--scope \"<path>\"]\n" +
57
+ " Primary live supervision command run beside Cursor while the agent codes.\n" +
58
+ " Shows MCP-declared intent and disk changes; warns on scope drift.\n" +
59
+ " No --task or --scope required for normal use.\n" +
60
+ " --task / --scope Optional strict mode (both required together).\n" +
61
+ " --allow-dirty Skip the pre-existing dirty-files prompt.\n" +
62
+ " --once Run one supervision pass and exit.\n" +
63
+ " --daemon Non-interactive mode: skip prompts, auto-deny domain crossings.\n" +
64
+ " --change-request / --execution-surface Advanced session binding.\n",
60
65
  "setup-mcp": " agentbridge setup-mcp [--editor cursor|windsurf|vscode]\n" +
61
66
  " Print the MCP server configuration snippet to add to your editor.\n",
62
67
  mcp: " agentbridge mcp\n" +
@@ -64,6 +69,8 @@ const COMMAND_HELP = {
64
69
  status: " agentbridge status [--repair] [--json]\n Show current work session status.\n",
65
70
  health: " agentbridge health [--json]\n Check project health against server.\n",
66
71
  check: " agentbridge check [--json]\n Check whether current work session can be accepted.\n",
72
+ "proof-guidance": " agentbridge proof-guidance [--work-session <id>] [--change-request <id>] [--rollout-proof-too-weak warn_only|soft_fail|hard_fail]\n" +
73
+ " Print deterministic proof guidance JSON for the current or specified session.\n",
67
74
  next: " agentbridge next [--json]\n Show the recommended next action.\n",
68
75
  verify: " agentbridge verify [--json] -- <command>\n" +
69
76
  " Run a command and verify output meets acceptance criteria.\n",
@@ -103,30 +110,26 @@ function usage(command, opts) {
103
110
  "Usage: agentbridge <command> [flags]",
104
111
  "",
105
112
  "Quick start:",
106
- " New repo:",
107
- " agentbridge doctor",
108
- " agentbridge start",
109
- " Existing repo:",
110
- " agentbridge doctor",
111
- " agentbridge recover",
112
- " agentbridge start",
113
+ " agentbridge recover Understand an existing repo (first time)",
114
+ " agentbridge watch Live supervision beside Cursor (primary watcher)",
115
+ " agentbridge start [\"intent\"] Task checkpoint / close (not the live watcher)",
116
+ " agentbridge verify -- <command> Record verification proof AgentBridge trusts",
113
117
  "",
114
- "Commands:",
115
- " doctor Check AgentBridge connection and repo readiness",
116
- " recover Understand an existing repo before agents continue",
117
- " start Start or attach to supervised agent work",
118
+ "Setup:",
119
+ " agentbridge doctor Check connection and repo readiness",
120
+ " agentbridge connect Save credentials (cloud projects)",
118
121
  "",
119
122
  "Advanced commands:",
120
- " connect Save credentials and verify connection to a project",
123
+ " start --task ... --scope ... Strict scoped session (both flags required)",
121
124
  " init Recover domain map from git history and bootstrap the project",
122
125
  " use Set active agent identity",
123
- " watch Watch for file changes (advanced/manual)",
124
- " start --summary ... --scope ... Backward-compatible explicit start mode",
126
+ " watch --task ... --scope ... Strict scope mode (optional flags on watch)",
125
127
  " setup-mcp Print MCP server config for your editor",
126
128
  " mcp Start local MCP stdio server",
127
129
  " status Show current session status",
128
130
  " health Check project health",
129
131
  " check Check acceptance readiness",
132
+ " proof-guidance Print deterministic proof guidance JSON",
130
133
  " next Show recommended next action",
131
134
  " verify Run command and verify output",
132
135
  " handoff Submit a handoff with proof of work",
@@ -269,27 +272,27 @@ async function main() {
269
272
  return;
270
273
  }
271
274
  if (command === "mcp") {
272
- const repoRoot = (0, node_path_1.resolve)(__dirname, "..", "..");
273
- const localMcpEntrypoint = (0, node_path_1.resolve)(repoRoot, "mcp", "agentbridge-mcp.ts");
274
- if (!(0, node_fs_1.existsSync)(localMcpEntrypoint)) {
275
+ const runtime = (0, mcp_runtime_1.resolveMcpRuntime)(__dirname);
276
+ if (!runtime) {
275
277
  process.stderr.write([
276
278
  "",
277
279
  "AgentBridge MCP runtime is unavailable in this installation.",
278
280
  "",
279
281
  "Try:",
280
- " npm install -g @agentbridge/cli",
282
+ " npm install -g @agentbridge1/cli@latest",
281
283
  " agentbridge doctor",
282
284
  "",
283
285
  ].join("\n"));
284
286
  process.exit(2);
285
287
  return;
286
288
  }
287
- const child = (0, node_child_process_1.spawnSync)("npx", ["tsx", localMcpEntrypoint], {
289
+ const child = (0, node_child_process_1.spawnSync)(runtime.command, runtime.args, {
288
290
  stdio: "inherit",
289
291
  env: process.env,
290
292
  });
291
293
  if (child.error) {
292
- process.stderr.write(`Failed to start MCP server via npx/tsx: ${child.error.message}\n`);
294
+ const via = runtime.mode === "bundled" ? "node" : "npx/tsx";
295
+ process.stderr.write(`Failed to start MCP server via ${via}: ${child.error.message}\n`);
293
296
  process.exit(2);
294
297
  return;
295
298
  }
@@ -336,6 +339,7 @@ async function main() {
336
339
  allowDirty: flags["--allow-dirty"] === "true",
337
340
  daemon: flags["--daemon"] === "true",
338
341
  once: flags["--once"] === "true",
342
+ details: flags["--details"] === "true",
339
343
  });
340
344
  return;
341
345
  }
@@ -350,8 +354,11 @@ async function main() {
350
354
  scopeFlagProvided,
351
355
  domain: flags["--domain"],
352
356
  agentId: flags["--agent"],
357
+ executionSurfaceId: flags["--execution-surface"],
353
358
  changeRequestId: flags["--change-request"],
354
359
  resume: flags["--resume"] === "true",
360
+ details: flags["--details"] === "true",
361
+ confirmClose: flags["--yes"] === "true",
355
362
  });
356
363
  return;
357
364
  }
@@ -380,6 +387,16 @@ async function main() {
380
387
  await (0, check_1.runCheck)({ json: flags["--json"] === "true" });
381
388
  return;
382
389
  }
390
+ if (command === "proof-guidance") {
391
+ await (0, proof_guidance_1.runProofGuidance)({
392
+ workSessionId: flags["--work-session"],
393
+ changeRequestId: flags["--change-request"],
394
+ rolloutProofTooWeak: flags["--rollout-proof-too-weak"],
395
+ rolloutProofNotRelevant: flags["--rollout-proof-not-relevant"],
396
+ rolloutImpactCoverageGap: flags["--rollout-impact-coverage-gap"],
397
+ });
398
+ return;
399
+ }
383
400
  if (command === "next") {
384
401
  await (0, next_1.runNext)({ json: flags["--json"] === "true" });
385
402
  return;