@agentbridge1/cli 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-info.json +4 -4
- package/dist/commands/connect.js +58 -119
- package/dist/commands/doctor.js +185 -58
- package/dist/commands/install-rules.js +64 -0
- package/dist/commands/recover.js +13 -2
- package/dist/commands/room.js +82 -0
- package/dist/commands/setup-mcp.js +54 -44
- package/dist/commands/start.js +85 -22
- package/dist/commands/watch.js +661 -92
- package/dist/config.js +31 -1
- package/dist/contract-verdict.js +186 -0
- package/dist/error-catalog.js +30 -1
- package/dist/git-status.js +6 -2
- package/dist/index.js +43 -5
- package/dist/init.js +10 -0
- package/dist/intent-validation.js +37 -0
- package/dist/local-proof.js +12 -4
- package/dist/mcp/agentbridge-mcp.js +602 -23
- package/dist/mcp/agentbridge-mcp.js.map +4 -4
- package/dist/mcp-config.js +64 -0
- package/dist/rules-sync.js +138 -0
- package/dist/supervision.js +191 -48
- package/dist/test-runner.js +201 -15
- package/package.json +1 -1
|
@@ -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
|
+
}
|
package/dist/commands/recover.js
CHANGED
|
@@ -110,7 +110,7 @@ function renderBasicHint() {
|
|
|
110
110
|
"",
|
|
111
111
|
"Recovery: basic",
|
|
112
112
|
"AgentBridge found only a generic project area.",
|
|
113
|
-
"Run `
|
|
113
|
+
"Run `agentbridge recover --force` to rebuild the domain map.",
|
|
114
114
|
"",
|
|
115
115
|
].join("\n");
|
|
116
116
|
}
|
|
@@ -146,7 +146,18 @@ function normalizeBootstrapError(error) {
|
|
|
146
146
|
return (0, errors_1.catalogCliError)("CONFIG_INCOMPLETE", {
|
|
147
147
|
what: `Recovery bootstrap payload was rejected by server validation${detailText}.`,
|
|
148
148
|
why: "The server cannot activate recovery until required bootstrap fields pass validation.",
|
|
149
|
-
next: "Retry `agentbridge recover`. If it fails again, run with
|
|
149
|
+
next: "Retry `agentbridge recover`. If it fails again, run with AGENTBRIDGE_DEBUG_HTTP=1 and share output.",
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if ((0, http_1.isCliHttpError)(error) && error.status >= 500) {
|
|
153
|
+
const parsed = (0, http_1.parseCliHttpErrorBody)(error);
|
|
154
|
+
const serverDetail = (0, http_1.extractHttpErrorCode)(parsed) ||
|
|
155
|
+
error.body.trim().slice(0, 240) ||
|
|
156
|
+
"no response body";
|
|
157
|
+
return (0, errors_1.catalogCliError)("SERVER_ERROR", {
|
|
158
|
+
what: `Recovery bootstrap failed with HTTP ${error.status}.`,
|
|
159
|
+
why: "The server errored while applying recovery baseline at POST /v1/dev/projects/{id}/bootstrap.",
|
|
160
|
+
next: `Retry agentbridge recover. For full request/response traces, run with AGENTBRIDGE_DEBUG_HTTP=1. Server detail: ${serverDetail}`,
|
|
150
161
|
});
|
|
151
162
|
}
|
|
152
163
|
if (error instanceof Error) {
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runRoomExit = runRoomExit;
|
|
4
|
+
const config_1 = require("../config");
|
|
5
|
+
const session_state_1 = require("../session-state");
|
|
6
|
+
function envOverridesConfig() {
|
|
7
|
+
const overrides = [];
|
|
8
|
+
if (process.env.AGENTBRIDGE_PROJECT_ID?.trim()) {
|
|
9
|
+
overrides.push("AGENTBRIDGE_PROJECT_ID");
|
|
10
|
+
}
|
|
11
|
+
if (process.env.AGENTBRIDGE_API_KEY?.trim()) {
|
|
12
|
+
overrides.push("AGENTBRIDGE_API_KEY");
|
|
13
|
+
}
|
|
14
|
+
if (process.env.AGENTBRIDGE_BASE_URL?.trim()) {
|
|
15
|
+
overrides.push("AGENTBRIDGE_BASE_URL");
|
|
16
|
+
}
|
|
17
|
+
return overrides;
|
|
18
|
+
}
|
|
19
|
+
function shouldClearLocalSession(keepSession) {
|
|
20
|
+
if (keepSession)
|
|
21
|
+
return false;
|
|
22
|
+
const state = (0, session_state_1.readSessionState)();
|
|
23
|
+
if (!state)
|
|
24
|
+
return false;
|
|
25
|
+
return state.status === "active" || state.status === "blocked";
|
|
26
|
+
}
|
|
27
|
+
function runRoomExit(options = {}) {
|
|
28
|
+
const before = (0, config_1.readConfig)();
|
|
29
|
+
const hadConnection = Boolean(before.projectId || before.apiKey || before.executionSurfaceId || before.activeAgentId);
|
|
30
|
+
const result = (0, config_1.clearRoomConnection)();
|
|
31
|
+
const clearedSession = shouldClearLocalSession(Boolean(options.keepSession));
|
|
32
|
+
if (clearedSession) {
|
|
33
|
+
(0, session_state_1.clearSessionState)();
|
|
34
|
+
}
|
|
35
|
+
const envOverrides = envOverridesConfig();
|
|
36
|
+
if (options.json) {
|
|
37
|
+
process.stdout.write(`${JSON.stringify({
|
|
38
|
+
action: "room_exit",
|
|
39
|
+
config_path: config_1.CONFIG_PATH,
|
|
40
|
+
had_connection: hadConnection,
|
|
41
|
+
cleared_keys: result.clearedKeys,
|
|
42
|
+
previous_project_id: result.previousProjectId ?? null,
|
|
43
|
+
had_api_key: result.hadApiKey,
|
|
44
|
+
cleared_local_session: clearedSession,
|
|
45
|
+
env_overrides: envOverrides,
|
|
46
|
+
preserved: ["domains", "apiBaseUrl", "precommitHookInstalled", "cliPath"],
|
|
47
|
+
}, null, 2)}\n`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
process.stdout.write("AgentBridge room exit\n");
|
|
51
|
+
process.stdout.write("─────────────────────────────────────────\n");
|
|
52
|
+
if (!hadConnection && result.clearedKeys.length === 0) {
|
|
53
|
+
process.stdout.write("No saved room connection in .agentbridge/config.json.\n");
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
process.stdout.write("Cleared saved room connection from .agentbridge/config.json.\n");
|
|
57
|
+
if (result.previousProjectId) {
|
|
58
|
+
process.stdout.write(` Project: ${result.previousProjectId}\n`);
|
|
59
|
+
}
|
|
60
|
+
if (result.hadApiKey) {
|
|
61
|
+
process.stdout.write(" API key: removed from config\n");
|
|
62
|
+
}
|
|
63
|
+
if (result.clearedKeys.includes("executionSurfaceId")) {
|
|
64
|
+
process.stdout.write(" Execution surface: removed from config\n");
|
|
65
|
+
}
|
|
66
|
+
if (result.clearedKeys.includes("activeAgentId")) {
|
|
67
|
+
process.stdout.write(" Active agent: removed from config\n");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (clearedSession) {
|
|
71
|
+
process.stdout.write("Cleared active local supervision session (.agentbridge/session.json).\n");
|
|
72
|
+
}
|
|
73
|
+
process.stdout.write("\nPreserved: domain map and other recovery data from init/recover.\n");
|
|
74
|
+
process.stdout.write("Server rules and MCP config on disk are unchanged.\n");
|
|
75
|
+
if (envOverrides.length > 0) {
|
|
76
|
+
process.stdout.write(`\nNote: ${envOverrides.join(", ")} still set in your shell — they override config until unset.\n`);
|
|
77
|
+
}
|
|
78
|
+
process.stdout.write("\nNext:\n");
|
|
79
|
+
process.stdout.write(" 1. Get a fresh API key at https://agentbridge.dev/dashboard\n");
|
|
80
|
+
process.stdout.write(" 2. agentbridge connect --project <id> --api-key <key>\n");
|
|
81
|
+
process.stdout.write(" 3. agentbridge doctor\n");
|
|
82
|
+
}
|
|
@@ -3,72 +3,82 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.runSetupMcp = runSetupMcp;
|
|
4
4
|
const node_path_1 = require("node:path");
|
|
5
5
|
const config_1 = require("../config");
|
|
6
|
+
const mcp_config_1 = require("../mcp-config");
|
|
6
7
|
const mcp_runtime_1 = require("../mcp-runtime");
|
|
7
8
|
const MCP_SERVER_NAME = "agentbridge";
|
|
8
|
-
function
|
|
9
|
-
const serverConfig = {
|
|
10
|
-
command: "agentbridge",
|
|
11
|
-
args: ["mcp"],
|
|
12
|
-
env: {
|
|
13
|
-
AGENTBRIDGE_PROJECT_ID: projectId,
|
|
14
|
-
AGENTBRIDGE_API_KEY: apiKey,
|
|
15
|
-
AGENTBRIDGE_BASE_URL: apiBaseUrl,
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
return JSON.stringify({ [MCP_SERVER_NAME]: serverConfig }, null, 2);
|
|
19
|
-
}
|
|
20
|
-
async function runSetupMcp(options = {}) {
|
|
21
|
-
const cfg = (0, config_1.readConfig)();
|
|
22
|
-
const projectId = process.env.AGENTBRIDGE_PROJECT_ID ?? cfg.projectId ?? "<your-project-id>";
|
|
23
|
-
const apiKey = process.env.AGENTBRIDGE_API_KEY ?? cfg.apiKey ?? "<your-api-key>";
|
|
24
|
-
const apiBaseUrl = process.env.AGENTBRIDGE_BASE_URL ??
|
|
25
|
-
cfg.apiBaseUrl ??
|
|
26
|
-
"https://agentauth-api-production.up.railway.app";
|
|
27
|
-
const editor = options.editor ?? "cursor";
|
|
28
|
-
process.stdout.write("\nAgentBridge MCP Setup\n");
|
|
29
|
-
process.stdout.write("─────────────────────────────────────────\n\n");
|
|
9
|
+
function editorConfigHint(editor) {
|
|
30
10
|
if (editor === "cursor") {
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
else if (editor === "windsurf") {
|
|
34
|
-
process.stdout.write("Add this to your ~/.codeium/windsurf/mcp_config.json:\n\n");
|
|
35
|
-
}
|
|
36
|
-
else if (editor === "vscode") {
|
|
37
|
-
process.stdout.write("Add this to your .vscode/mcp.json:\n\n");
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
process.stdout.write(`Add this to your ${editor} MCP config:\n\n`);
|
|
11
|
+
return "Add this to your ~/.cursor/mcp.json (or project-level .cursor/mcp.json):\n\n";
|
|
41
12
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
mcpServers: JSON.parse(standardSnippet(projectId, apiKey, apiBaseUrl)),
|
|
45
|
-
}, null, 2) + "\n");
|
|
46
|
-
if (projectId === "<your-project-id>" || apiKey === "<your-api-key>") {
|
|
47
|
-
process.stdout.write("\n⚠ Credentials not found. Run `agentbridge connect` first to save your project ID and API key.\n");
|
|
13
|
+
if (editor === "windsurf") {
|
|
14
|
+
return "Add this to your ~/.codeium/windsurf/mcp_config.json:\n\n";
|
|
48
15
|
}
|
|
49
|
-
|
|
50
|
-
|
|
16
|
+
if (editor === "vscode") {
|
|
17
|
+
return "Add this to your .vscode/mcp.json:\n\n";
|
|
51
18
|
}
|
|
52
|
-
|
|
19
|
+
return "Add this to your " + editor + " MCP config:\n\n";
|
|
20
|
+
}
|
|
21
|
+
function printRuntimeStatus(cliDistDir) {
|
|
53
22
|
if (!(0, mcp_runtime_1.isMcpRuntimeAvailable)(cliDistDir)) {
|
|
54
23
|
process.stdout.write([
|
|
55
24
|
"",
|
|
56
25
|
"⚠ MCP runtime is missing from this CLI install.",
|
|
57
|
-
"
|
|
26
|
+
" agentbridge mcp will exit until you reinstall:",
|
|
58
27
|
" npm install -g @agentbridge1/cli@latest",
|
|
59
28
|
"",
|
|
60
29
|
" Or point mcp.json at a repo build:",
|
|
61
30
|
" node /path/to/AuthAgent/cli/dist/mcp/agentbridge-mcp.js",
|
|
62
31
|
"",
|
|
63
32
|
].join("\n"));
|
|
33
|
+
return;
|
|
64
34
|
}
|
|
65
|
-
|
|
35
|
+
process.stdout.write(["", "✓ MCP runtime is bundled with this CLI (agentbridge mcp is ready).", ""].join("\n"));
|
|
36
|
+
}
|
|
37
|
+
async function runSetupMcp(options = {}) {
|
|
38
|
+
const cliDistDir = (0, node_path_1.resolve)(__dirname, "..");
|
|
39
|
+
const editor = options.editor ?? "cursor";
|
|
40
|
+
process.stdout.write("\nAgentBridge MCP Setup\n");
|
|
41
|
+
process.stdout.write("─────────────────────────────────────────\n\n");
|
|
42
|
+
if (options.local) {
|
|
43
|
+
const entry = (0, mcp_config_1.buildLocalMcpServerEntry)(cliDistDir);
|
|
44
|
+
const mcpPath = (0, mcp_config_1.writeLocalMcpConfig)(cliDistDir);
|
|
45
|
+
process.stdout.write("Mode: local-first (no project ID or API key required)\n\n");
|
|
46
|
+
process.stdout.write("MCP config written: " + mcpPath + "\n\n");
|
|
47
|
+
process.stdout.write("Configured entry:\n\n");
|
|
48
|
+
process.stdout.write(JSON.stringify({ mcpServers: { [MCP_SERVER_NAME]: entry } }, null, 2) + "\n");
|
|
49
|
+
process.stdout.write("\nLocal mode: agent_hello creates work contracts on disk.\n" +
|
|
50
|
+
" Run agentbridge watch in this repo, then restart Cursor.\n");
|
|
51
|
+
printRuntimeStatus(cliDistDir);
|
|
66
52
|
process.stdout.write([
|
|
67
53
|
"",
|
|
68
|
-
"
|
|
54
|
+
"Next:",
|
|
55
|
+
" 1. Restart Cursor to load MCP.",
|
|
56
|
+
" 2. agentbridge watch",
|
|
57
|
+
" 3. In chat: agent_hello({ intent: \"what you are about to do\" })",
|
|
69
58
|
"",
|
|
70
59
|
].join("\n"));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const cfg = (0, config_1.readConfig)();
|
|
63
|
+
const projectId = process.env.AGENTBRIDGE_PROJECT_ID ?? cfg.projectId ?? "<your-project-id>";
|
|
64
|
+
const apiKey = process.env.AGENTBRIDGE_API_KEY ?? cfg.apiKey ?? "<your-api-key>";
|
|
65
|
+
const apiBaseUrl = process.env.AGENTBRIDGE_BASE_URL ??
|
|
66
|
+
cfg.apiBaseUrl ??
|
|
67
|
+
"https://agentauth-api-production.up.railway.app";
|
|
68
|
+
process.stdout.write(editorConfigHint(editor));
|
|
69
|
+
process.stdout.write("Recommended config:\n\n");
|
|
70
|
+
const serverEntry = (0, mcp_config_1.buildServerMcpServerEntry)(projectId, apiKey, apiBaseUrl);
|
|
71
|
+
process.stdout.write(JSON.stringify({ mcpServers: { [MCP_SERVER_NAME]: serverEntry } }, null, 2) + "\n");
|
|
72
|
+
if (projectId === "<your-project-id>" || apiKey === "<your-api-key>") {
|
|
73
|
+
process.stdout.write("\n⚠ Credentials not found. Run agentbridge connect first to save your project ID and API key.\n" +
|
|
74
|
+
" Or use local mode: agentbridge setup-mcp --local\n");
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const mcpPath = (0, mcp_config_1.mergeAgentbridgeIntoCursorMcp)(serverEntry);
|
|
78
|
+
process.stdout.write("\nMCP config written: " + mcpPath + "\n");
|
|
79
|
+
process.stdout.write("\n✓ Credentials filled from .agentbridge/config.json\n");
|
|
71
80
|
}
|
|
81
|
+
printRuntimeStatus(cliDistDir);
|
|
72
82
|
process.stdout.write([
|
|
73
83
|
"After saving the config, restart your editor to activate the MCP server.",
|
|
74
84
|
"The MCP server lets your AI assistant call tools like agent_hello, check AgentBridge status, and trigger approvals.",
|
package/dist/commands/start.js
CHANGED
|
@@ -33,12 +33,14 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runLocalStart = runLocalStart;
|
|
36
37
|
exports.runStart = runStart;
|
|
37
38
|
const config_1 = require("../config");
|
|
38
39
|
const domain_resolution_1 = require("../domain-resolution");
|
|
39
40
|
const errors_1 = require("../errors");
|
|
40
41
|
const error_catalog_1 = require("../error-catalog");
|
|
41
42
|
const http_1 = require("../http");
|
|
43
|
+
const intent_validation_1 = require("../intent-validation");
|
|
42
44
|
const session_1 = require("../session");
|
|
43
45
|
const session_state_1 = require("../session-state");
|
|
44
46
|
const server_sync_1 = require("../server-sync");
|
|
@@ -300,10 +302,19 @@ async function resolveStartOwnership(input) {
|
|
|
300
302
|
projectId: ctx.projectId,
|
|
301
303
|
identities,
|
|
302
304
|
});
|
|
303
|
-
|
|
304
|
-
|
|
305
|
+
const explicitDomain = input.explicitDomain?.trim();
|
|
306
|
+
const inferredScopeDomain = (0, domain_resolution_1.inferLaneFromFiles)([input.scope], input.configuredDomains).laneDomain;
|
|
307
|
+
let resolvedDomain = explicitDomain ||
|
|
308
|
+
inferredScopeDomain ||
|
|
305
309
|
callerIdentity.domainName ||
|
|
306
310
|
undefined;
|
|
311
|
+
let laneClaimSource = explicitDomain
|
|
312
|
+
? "explicit_domain"
|
|
313
|
+
: inferredScopeDomain
|
|
314
|
+
? "scope_pattern"
|
|
315
|
+
: callerIdentity.domainName
|
|
316
|
+
? "caller_identity_domain"
|
|
317
|
+
: "unresolved";
|
|
307
318
|
let packetDomainOwner = null;
|
|
308
319
|
let packetDomainName = null;
|
|
309
320
|
try {
|
|
@@ -315,6 +326,7 @@ async function resolveStartOwnership(input) {
|
|
|
315
326
|
const first = domainPacket.domains[0];
|
|
316
327
|
if (!resolvedDomain && first?.domain_name) {
|
|
317
328
|
resolvedDomain = first.domain_name;
|
|
329
|
+
laneClaimSource = "domain_packet";
|
|
318
330
|
}
|
|
319
331
|
packetDomainOwner = first?.owner_work_identity_id ?? null;
|
|
320
332
|
packetDomainName = first?.domain_name ?? null;
|
|
@@ -325,6 +337,11 @@ async function resolveStartOwnership(input) {
|
|
|
325
337
|
if (!resolvedDomain) {
|
|
326
338
|
throw (0, errors_1.catalogCliError)("START_DOMAIN_UNRESOLVED");
|
|
327
339
|
}
|
|
340
|
+
const laneClaimConfidence = laneClaimSource === "explicit_domain" || laneClaimSource === "scope_pattern"
|
|
341
|
+
? "high"
|
|
342
|
+
: laneClaimSource === "domain_packet" || laneClaimSource === "caller_identity_domain"
|
|
343
|
+
? "medium"
|
|
344
|
+
: "low";
|
|
328
345
|
const projectDomain = projectPacket.domains_summary.find((domain) => equalsIgnoreCase(domain.domain_name, resolvedDomain));
|
|
329
346
|
const ownerFromProjectPacket = projectDomain?.owner_work_identity_id ?? null;
|
|
330
347
|
const ownerFromPacket = packetDomainOwner;
|
|
@@ -343,6 +360,8 @@ async function resolveStartOwnership(input) {
|
|
|
343
360
|
identitySource: resolvedIdentity.source,
|
|
344
361
|
identityWarning: resolvedIdentity.warning,
|
|
345
362
|
suggestedActiveAgentId: resolvedIdentity.suggestedActiveAgentId,
|
|
363
|
+
laneClaimConfidence,
|
|
364
|
+
laneClaimSource,
|
|
346
365
|
};
|
|
347
366
|
}
|
|
348
367
|
async function ensureChangeRequestReady(changeRequestId, ownerWorkIdentityId, resolvedDomain, scope) {
|
|
@@ -441,6 +460,14 @@ async function executeStartWorkSession(opts) {
|
|
|
441
460
|
});
|
|
442
461
|
const resolvedDomain = ownership.resolvedDomain;
|
|
443
462
|
const activeAgentId = ownership.resolvedAgentId;
|
|
463
|
+
if (ownership.laneClaimConfidence === "low") {
|
|
464
|
+
throw (0, errors_1.catalogCliError)("START_LANE_CLAIM_LOW_CONFIDENCE");
|
|
465
|
+
}
|
|
466
|
+
if (ownership.laneClaimConfidence === "medium" && opts.confirmDomain !== true) {
|
|
467
|
+
throw (0, errors_1.catalogCliError)("START_LANE_CLAIM_CONFIRM_REQUIRED", {
|
|
468
|
+
what: `Lane claim is medium confidence (${ownership.laneClaimSource}) for domain "${resolvedDomain}".`,
|
|
469
|
+
});
|
|
470
|
+
}
|
|
444
471
|
const explicitResume = opts.resume === true;
|
|
445
472
|
const explicitCrId = opts.changeRequestId?.trim() || undefined;
|
|
446
473
|
const existingCrId = explicitCrId ?? (explicitResume ? cfg.activeChangeRequestId?.trim() || undefined : undefined);
|
|
@@ -545,18 +572,31 @@ async function executeStartWorkSession(opts) {
|
|
|
545
572
|
}
|
|
546
573
|
(0, config_1.updateConfig)({ activeChangeRequestId: changeRequest.id });
|
|
547
574
|
const output = [
|
|
548
|
-
"AgentBridge
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
`- ${
|
|
554
|
-
...(activeAgentId ? [
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
"
|
|
575
|
+
"AgentBridge start",
|
|
576
|
+
"",
|
|
577
|
+
"1) Actions performed",
|
|
578
|
+
`- Started tracked work for scope: ${scope}`,
|
|
579
|
+
`- Linked task ${changeRequest.id} to run ${workSessionId}`,
|
|
580
|
+
`- Work session: ${workSessionId}`,
|
|
581
|
+
...(activeAgentId ? [`- Agent: ${activeAgentId}`] : []),
|
|
582
|
+
...(resolvedDomain ? [`- Domain: ${resolvedDomain}`] : []),
|
|
583
|
+
"",
|
|
584
|
+
"2) Proof present / missing",
|
|
585
|
+
"- Present: task + run are active and linked",
|
|
586
|
+
"- Missing: verification proof for this change (tests/checks not recorded yet)",
|
|
587
|
+
`- Identity source: ${ownership.identitySource}`,
|
|
588
|
+
`- Lane claim confidence: ${ownership.laneClaimConfidence} (${ownership.laneClaimSource})`,
|
|
589
|
+
...(ownership.identityWarning
|
|
590
|
+
? [
|
|
591
|
+
"- Warning: identity config mismatch detected (using caller identity fallback)",
|
|
592
|
+
ownership.identityWarning,
|
|
593
|
+
]
|
|
594
|
+
: []),
|
|
595
|
+
"",
|
|
596
|
+
"3) Next move",
|
|
597
|
+
"- Keep supervision running with `agentbridge watch`",
|
|
598
|
+
"- After changes, run `agentbridge verify -- <command>`",
|
|
599
|
+
"- Re-run `agentbridge watch` to confirm proof and boundaries",
|
|
560
600
|
];
|
|
561
601
|
process.stdout.write(`${renderOtherSessions(output, [...new Set(otherSessionIds)]).join("\n")}\n`);
|
|
562
602
|
return {
|
|
@@ -567,14 +607,31 @@ async function executeStartWorkSession(opts) {
|
|
|
567
607
|
};
|
|
568
608
|
}
|
|
569
609
|
function hasActiveLocalRun() {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
if (
|
|
576
|
-
|
|
577
|
-
|
|
610
|
+
return (0, session_state_1.isActiveLocalSession)((0, session_state_1.readSessionState)());
|
|
611
|
+
}
|
|
612
|
+
async function runLocalStart(intent) {
|
|
613
|
+
const validatedIntent = (0, intent_validation_1.validateIntent)(intent);
|
|
614
|
+
const existing = (0, session_state_1.readSessionState)();
|
|
615
|
+
if ((0, session_state_1.isActiveLocalSession)(existing)) {
|
|
616
|
+
if (existing.intent?.trim() === validatedIntent) {
|
|
617
|
+
process.stdout.write(`Contract already active: ${validatedIntent}\n`);
|
|
618
|
+
return existing;
|
|
619
|
+
}
|
|
620
|
+
throw (0, errors_1.catalogCliError)("START_EXPLICIT_PAIR_REQUIRED", {
|
|
621
|
+
what: "A different AgentBridge contract is already active.",
|
|
622
|
+
why: `Current contract: ${existing.intent ?? "(unknown)"}`,
|
|
623
|
+
next: "Finish the current contract in watch, or close it before starting a new one.",
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
const session = (0, session_1.openLocalSession)({
|
|
627
|
+
agentId: "local",
|
|
628
|
+
laneDomain: null,
|
|
629
|
+
intent: validatedIntent,
|
|
630
|
+
domains: [],
|
|
631
|
+
mode: "local_supervision",
|
|
632
|
+
});
|
|
633
|
+
process.stdout.write(`Contract created: ${validatedIntent}\n`);
|
|
634
|
+
return session;
|
|
578
635
|
}
|
|
579
636
|
async function runDefaultStart(opts = {}) {
|
|
580
637
|
const { runLocalSupervision } = await Promise.resolve().then(() => __importStar(require("../local-supervision")));
|
|
@@ -595,6 +652,12 @@ function isStrictTrackedStartRequest(opts) {
|
|
|
595
652
|
return explicitSummaryFlag || explicitScopeFlag || explicitInputProvided;
|
|
596
653
|
}
|
|
597
654
|
async function runStart(opts = {}) {
|
|
655
|
+
const cfg = (0, config_1.readConfig)();
|
|
656
|
+
const localIntent = opts.prompt?.trim() || opts.summary?.trim();
|
|
657
|
+
if (!cfg.projectId?.trim() && localIntent) {
|
|
658
|
+
await runLocalStart(localIntent);
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
598
661
|
const strictTrackedStart = isStrictTrackedStartRequest(opts);
|
|
599
662
|
const explicitSummaryFlag = opts.summaryFlagProvided === true;
|
|
600
663
|
const explicitScopeFlag = opts.scopeFlagProvided === true;
|