@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
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveSupervisionIntent = resolveSupervisionIntent;
|
|
4
|
+
exports.probeCloudCapability = probeCloudCapability;
|
|
5
|
+
exports.runLocalSupervision = runLocalSupervision;
|
|
6
|
+
const promises_1 = require("node:readline/promises");
|
|
7
|
+
const node_process_1 = require("node:process");
|
|
8
|
+
const config_1 = require("./config");
|
|
9
|
+
const domain_resolution_1 = require("./domain-resolution");
|
|
10
|
+
const git_status_1 = require("./git-status");
|
|
11
|
+
const local_proof_1 = require("./local-proof");
|
|
12
|
+
const local_memory_1 = require("./local-memory");
|
|
13
|
+
const session_1 = require("./session");
|
|
14
|
+
const session_state_1 = require("./session-state");
|
|
15
|
+
const server_sync_1 = require("./server-sync");
|
|
16
|
+
const preflight_changed_files_1 = require("./preflight-changed-files");
|
|
17
|
+
function resolveSupervisionIntent(prompt, currentWorkFiles, existing) {
|
|
18
|
+
if (prompt?.trim())
|
|
19
|
+
return prompt.trim();
|
|
20
|
+
if (existing?.intent?.trim())
|
|
21
|
+
return existing.intent.trim();
|
|
22
|
+
if (currentWorkFiles.length > 0) {
|
|
23
|
+
const branch = (0, git_status_1.getBranchName)();
|
|
24
|
+
if (branch !== "unknown")
|
|
25
|
+
return `Work on ${branch}`;
|
|
26
|
+
const preview = currentWorkFiles.slice(0, 2).join(", ");
|
|
27
|
+
return currentWorkFiles.length > 2 ? `Changes in ${preview}...` : `Changes in ${preview}`;
|
|
28
|
+
}
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
async function probeCloudCapability() {
|
|
32
|
+
const cfg = (0, config_1.readConfig)();
|
|
33
|
+
const projectId = cfg.projectId?.trim() || process.env.AGENTBRIDGE_PROJECT_ID?.trim();
|
|
34
|
+
const apiKey = cfg.apiKey?.trim() || process.env.AGENTBRIDGE_API_KEY?.trim();
|
|
35
|
+
const apiBaseUrl = cfg.apiBaseUrl?.trim() || process.env.AGENTBRIDGE_API_BASE_URL?.trim();
|
|
36
|
+
const hasActiveAgent = Boolean(cfg.activeAgentId?.trim() || process.env.AGENTBRIDGE_AGENT_ID?.trim());
|
|
37
|
+
const hasExecutionSurface = Boolean(cfg.executionSurfaceId?.trim());
|
|
38
|
+
if (!projectId || !apiKey || !apiBaseUrl) {
|
|
39
|
+
return {
|
|
40
|
+
localSupervision: "ready",
|
|
41
|
+
cloudSync: "not_configured",
|
|
42
|
+
strictTrackedWork: "unavailable",
|
|
43
|
+
reason: "missing project credentials",
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
await (0, server_sync_1.fetchProjectPacket)((0, config_1.contextFromConfig)());
|
|
48
|
+
if (!hasActiveAgent || !hasExecutionSurface) {
|
|
49
|
+
return {
|
|
50
|
+
localSupervision: "ready",
|
|
51
|
+
cloudSync: "incomplete",
|
|
52
|
+
strictTrackedWork: "unavailable",
|
|
53
|
+
reason: !hasExecutionSurface ? "execution surface missing" : "active agent missing",
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
localSupervision: "ready",
|
|
58
|
+
cloudSync: "ready",
|
|
59
|
+
strictTrackedWork: "ready",
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return {
|
|
64
|
+
localSupervision: "ready",
|
|
65
|
+
cloudSync: "unreachable",
|
|
66
|
+
strictTrackedWork: "unavailable",
|
|
67
|
+
reason: "could not reach project API",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function cloudSyncLabel(status) {
|
|
72
|
+
if (status === "ready")
|
|
73
|
+
return "configured";
|
|
74
|
+
if (status === "not_configured")
|
|
75
|
+
return "not configured";
|
|
76
|
+
if (status === "incomplete")
|
|
77
|
+
return "incomplete";
|
|
78
|
+
return "unreachable";
|
|
79
|
+
}
|
|
80
|
+
function memoryCloudSync(status) {
|
|
81
|
+
if (status === "ready")
|
|
82
|
+
return "synced";
|
|
83
|
+
if (status === "not_configured")
|
|
84
|
+
return "not_configured";
|
|
85
|
+
return "failed";
|
|
86
|
+
}
|
|
87
|
+
function persistCurrentWorkFiles(state, currentWorkFiles) {
|
|
88
|
+
state.changedFiles = currentWorkFiles;
|
|
89
|
+
state.updatedAt = new Date().toISOString();
|
|
90
|
+
(0, session_state_1.writeSessionState)(state);
|
|
91
|
+
return currentWorkFiles;
|
|
92
|
+
}
|
|
93
|
+
async function askConfirmClose() {
|
|
94
|
+
if (!process.stdin.isTTY)
|
|
95
|
+
return false;
|
|
96
|
+
const rl = (0, promises_1.createInterface)({ input: node_process_1.stdin, output: node_process_1.stdout });
|
|
97
|
+
try {
|
|
98
|
+
const answer = await rl.question("Close this task and write memory? [Y/n] ");
|
|
99
|
+
const trimmed = answer.trim().toLowerCase();
|
|
100
|
+
return trimmed === "" || trimmed === "y" || trimmed === "yes";
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
rl.close();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function ensureLocalSession(intent, existing) {
|
|
107
|
+
if ((0, session_state_1.isActiveLocalSession)(existing)) {
|
|
108
|
+
if (intent && existing.intent !== intent) {
|
|
109
|
+
existing.intent = intent;
|
|
110
|
+
existing.updatedAt = new Date().toISOString();
|
|
111
|
+
(0, session_state_1.writeSessionState)(existing);
|
|
112
|
+
}
|
|
113
|
+
return existing;
|
|
114
|
+
}
|
|
115
|
+
const cfg = (0, config_1.readConfig)();
|
|
116
|
+
const lane = (0, domain_resolution_1.inferLaneFromFiles)([], cfg.domains ?? []);
|
|
117
|
+
return (0, session_1.openLocalSession)({
|
|
118
|
+
agentId: cfg.activeAgentId ?? "local",
|
|
119
|
+
laneDomain: lane.laneDomain,
|
|
120
|
+
claimedPaths: [],
|
|
121
|
+
domains: cfg.domains ?? [],
|
|
122
|
+
intent,
|
|
123
|
+
mode: "local_supervision",
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function formatTaskLine(state, prompt) {
|
|
127
|
+
const task = prompt?.trim() || state.intent?.trim();
|
|
128
|
+
return task ? `Task: ${task}` : "Task: none yet";
|
|
129
|
+
}
|
|
130
|
+
function formatStatusLine(currentWorkFiles, blockingIssue, prompt) {
|
|
131
|
+
if (currentWorkFiles.length === 0) {
|
|
132
|
+
return prompt?.trim() ? "Status: waiting for changes" : "Status: waiting for new work";
|
|
133
|
+
}
|
|
134
|
+
if (blockingIssue) {
|
|
135
|
+
return `Status: proof required — ${blockingIssue.whatHappened}`;
|
|
136
|
+
}
|
|
137
|
+
return `Status: ${currentWorkFiles.length} changed file(s), proof current`;
|
|
138
|
+
}
|
|
139
|
+
function renderProofGuidance(blockingIssue) {
|
|
140
|
+
if (!blockingIssue)
|
|
141
|
+
return [];
|
|
142
|
+
const lines = [blockingIssue.nextAction];
|
|
143
|
+
if (blockingIssue.errorCode === "PROOF_STALE_AFTER_CHANGE") {
|
|
144
|
+
lines.push("Proof is stale because files changed after verification.");
|
|
145
|
+
lines.push("Record fresh proof:");
|
|
146
|
+
lines.push("agentbridge verify -- <test command>");
|
|
147
|
+
}
|
|
148
|
+
else if (blockingIssue.errorCode === "PROOF_MISSING") {
|
|
149
|
+
lines.push("Proof required for files changed after this session started.");
|
|
150
|
+
lines.push("Record proof:");
|
|
151
|
+
lines.push("agentbridge verify -- <test command>");
|
|
152
|
+
}
|
|
153
|
+
return lines;
|
|
154
|
+
}
|
|
155
|
+
async function runLocalSupervision(opts = {}) {
|
|
156
|
+
const cfg = (0, config_1.readConfig)();
|
|
157
|
+
const cloud = await probeCloudCapability();
|
|
158
|
+
const existing = (0, session_state_1.readSessionState)();
|
|
159
|
+
const isNewSession = !(0, session_state_1.isActiveLocalSession)(existing);
|
|
160
|
+
if (!(0, session_state_1.isActiveLocalSession)(existing) && cfg.activeChangeRequestId) {
|
|
161
|
+
(0, config_1.updateConfig)({ activeChangeRequestId: undefined });
|
|
162
|
+
process.stdout.write("Note: ignoring stale previously tracked task linkage in checkpoint mode.\n");
|
|
163
|
+
}
|
|
164
|
+
const dirtyNow = (0, git_status_1.getDirtyWorkingTreeFiles)();
|
|
165
|
+
const promptIntent = opts.prompt?.trim() || undefined;
|
|
166
|
+
const preliminaryIntent = promptIntent || ((0, session_state_1.isActiveLocalSession)(existing) ? existing?.intent : undefined);
|
|
167
|
+
const state = ensureLocalSession(preliminaryIntent, existing);
|
|
168
|
+
let currentWorkFiles = (0, preflight_changed_files_1.computeCurrentWorkFiles)(state, dirtyNow);
|
|
169
|
+
const derivedIntent = resolveSupervisionIntent(undefined, currentWorkFiles, state);
|
|
170
|
+
if (!state.intent?.trim() && derivedIntent) {
|
|
171
|
+
state.intent = derivedIntent;
|
|
172
|
+
state.updatedAt = new Date().toISOString();
|
|
173
|
+
(0, session_state_1.writeSessionState)(state);
|
|
174
|
+
}
|
|
175
|
+
currentWorkFiles = persistCurrentWorkFiles(state, currentWorkFiles);
|
|
176
|
+
const proofEval = (0, local_proof_1.evaluateLocalProof)(currentWorkFiles, state.lastLocalVerificationRun);
|
|
177
|
+
const blockingIssue = (0, local_proof_1.buildLocalProofBlockingIssue)(proofEval);
|
|
178
|
+
const lines = [];
|
|
179
|
+
const baselineCount = state.dirtyFilesAtStart?.length ?? 0;
|
|
180
|
+
if (isNewSession) {
|
|
181
|
+
lines.push("Task checkpoint opened.");
|
|
182
|
+
if (baselineCount > 0) {
|
|
183
|
+
lines.push(`Pre-existing dirty files found: ${baselineCount}`);
|
|
184
|
+
lines.push("These will be treated as baseline, not current work.");
|
|
185
|
+
lines.push("Waiting for new changes.");
|
|
186
|
+
}
|
|
187
|
+
lines.push("");
|
|
188
|
+
}
|
|
189
|
+
lines.push(formatTaskLine(state, opts.prompt));
|
|
190
|
+
lines.push("Mode: task checkpoint");
|
|
191
|
+
lines.push(`Cloud sync: ${cloudSyncLabel(cloud.cloudSync)}${cloud.reason ? ` (${cloud.reason})` : ""}`);
|
|
192
|
+
lines.push(formatStatusLine(currentWorkFiles, blockingIssue, opts.prompt));
|
|
193
|
+
if (currentWorkFiles.length === 0) {
|
|
194
|
+
lines.push("No new work detected since this checkpoint opened.");
|
|
195
|
+
}
|
|
196
|
+
if (blockingIssue) {
|
|
197
|
+
lines.push("");
|
|
198
|
+
lines.push(...renderProofGuidance(blockingIssue));
|
|
199
|
+
}
|
|
200
|
+
if (opts.details) {
|
|
201
|
+
lines.push("");
|
|
202
|
+
if (baselineCount > 0) {
|
|
203
|
+
lines.push("Baseline files (not current work):");
|
|
204
|
+
for (const file of (state.dirtyFilesAtStart ?? []).slice(0, 10)) {
|
|
205
|
+
lines.push(`- ${file}`);
|
|
206
|
+
}
|
|
207
|
+
if (baselineCount > 10) {
|
|
208
|
+
lines.push(`- ... +${baselineCount - 10} more`);
|
|
209
|
+
}
|
|
210
|
+
lines.push("");
|
|
211
|
+
}
|
|
212
|
+
if (currentWorkFiles.length > 0) {
|
|
213
|
+
lines.push("Current work files:");
|
|
214
|
+
for (const file of currentWorkFiles.slice(0, 10)) {
|
|
215
|
+
lines.push(`- ${file}`);
|
|
216
|
+
}
|
|
217
|
+
if (currentWorkFiles.length > 10) {
|
|
218
|
+
lines.push(`- ... +${currentWorkFiles.length - 10} more`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
lines.push("");
|
|
223
|
+
lines.push("For live supervision while the agent codes:");
|
|
224
|
+
lines.push(" agentbridge watch");
|
|
225
|
+
lines.push("");
|
|
226
|
+
lines.push("For task checkpoint/close:");
|
|
227
|
+
lines.push(" agentbridge start");
|
|
228
|
+
process.stdout.write(`${lines.join("\n")}\n`);
|
|
229
|
+
if (!blockingIssue && currentWorkFiles.length > 0) {
|
|
230
|
+
const shouldClose = opts.confirmClose === true || (await askConfirmClose());
|
|
231
|
+
if (shouldClose) {
|
|
232
|
+
state.closeReason = "completed";
|
|
233
|
+
const closeResult = (0, session_1.closeLocalSession)(state);
|
|
234
|
+
if (!closeResult.ok) {
|
|
235
|
+
process.stdout.write(`\nCould not close: ${closeResult.reason}\n`);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
(0, local_memory_1.writeLocalMemory)(state, { cloudSync: memoryCloudSync(cloud.cloudSync) });
|
|
239
|
+
process.stdout.write("\n");
|
|
240
|
+
process.stdout.write("Task closed.\n");
|
|
241
|
+
process.stdout.write("Local memory written.\n");
|
|
242
|
+
process.stdout.write(`Cloud sync: ${cloudSyncLabel(cloud.cloudSync)}\n`);
|
|
243
|
+
process.stdout.write("Run `agentbridge start \"<intent>\"` for the next task checkpoint.\n");
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
if (cloud.cloudSync !== "ready") {
|
|
248
|
+
process.stdout.write("\nContinuing locally.\n");
|
|
249
|
+
}
|
|
250
|
+
}
|