@agentbridge1/cli 0.0.1
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/bin/agentbridge.js +11 -0
- package/dist/acceptance-block.js +21 -0
- package/dist/acceptance-preflight.js +91 -0
- package/dist/api-client.js +6 -0
- package/dist/authority-request.js +25 -0
- package/dist/briefing.js +26 -0
- package/dist/bug-registry.js +350 -0
- package/dist/build-info.json +6 -0
- package/dist/canonical-state.js +11 -0
- package/dist/claimed-paths.js +42 -0
- package/dist/cli-failure-log.js +34 -0
- package/dist/commands/accept.js +241 -0
- package/dist/commands/attention.js +85 -0
- package/dist/commands/autopilot.js +93 -0
- package/dist/commands/bug.js +106 -0
- package/dist/commands/check.js +283 -0
- package/dist/commands/connect.js +159 -0
- package/dist/commands/dist-freshness.js +105 -0
- package/dist/commands/doctor.js +300 -0
- package/dist/commands/done.js +292 -0
- package/dist/commands/handoff.js +189 -0
- package/dist/commands/handshake.js +78 -0
- package/dist/commands/health.js +154 -0
- package/dist/commands/identity.js +57 -0
- package/dist/commands/init.js +5 -0
- package/dist/commands/memory.js +400 -0
- package/dist/commands/next.js +21 -0
- package/dist/commands/precommit-check.js +17 -0
- package/dist/commands/recover.js +116 -0
- package/dist/commands/session.js +229 -0
- package/dist/commands/setup-mcp.js +56 -0
- package/dist/commands/start.js +626 -0
- package/dist/commands/status.js +486 -0
- package/dist/commands/use.js +13 -0
- package/dist/commands/verify.js +264 -0
- package/dist/commands/version.js +32 -0
- package/dist/commands/watch.js +1718 -0
- package/dist/config.js +55 -0
- package/dist/domain-resolution.js +63 -0
- package/dist/error-catalog.js +494 -0
- package/dist/errors.js +276 -0
- package/dist/file-fingerprints.js +45 -0
- package/dist/gates.js +200 -0
- package/dist/git-evidence.js +285 -0
- package/dist/git-status.js +81 -0
- package/dist/http.js +151 -0
- package/dist/index.js +622 -0
- package/dist/init.js +458 -0
- package/dist/memory-context-render.js +51 -0
- package/dist/operator-snapshot.js +99 -0
- package/dist/precommit.js +72 -0
- package/dist/preflight-changed-files.js +109 -0
- package/dist/proof-guidance.js +110 -0
- package/dist/redact-secrets.js +15 -0
- package/dist/revert-crossing.js +73 -0
- package/dist/server-sync.js +433 -0
- package/dist/session-state.js +138 -0
- package/dist/session.js +89 -0
- package/dist/supervision.js +212 -0
- package/dist/terminal-ui.js +18 -0
- package/dist/test-runner.js +62 -0
- package/dist/types.js +2 -0
- package/dist/verification-conditions.js +185 -0
- package/dist/watch-core.js +208 -0
- package/dist/watch-packet-handshake.js +71 -0
- package/dist/watcher.js +62 -0
- package/dist/work-context-resolver.js +412 -0
- package/dist/work-contract.js +110 -0
- package/package.json +44 -0
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.repairMissingBlockingFiles = repairMissingBlockingFiles;
|
|
4
|
+
exports.renderStatus = renderStatus;
|
|
5
|
+
exports.runStatus = runStatus;
|
|
6
|
+
const config_1 = require("../config");
|
|
7
|
+
const session_state_1 = require("../session-state");
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const work_context_resolver_1 = require("../work-context-resolver");
|
|
10
|
+
const operator_snapshot_1 = require("../operator-snapshot");
|
|
11
|
+
const health_1 = require("./health");
|
|
12
|
+
const server_sync_1 = require("../server-sync");
|
|
13
|
+
const canonical_state_1 = require("../canonical-state");
|
|
14
|
+
const acceptance_preflight_1 = require("../acceptance-preflight");
|
|
15
|
+
function repairMissingBlockingFiles() {
|
|
16
|
+
const state = (0, session_state_1.readSessionState)();
|
|
17
|
+
if (!state || state.id === "none" || state.status === "closed") {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
let repaired = 0;
|
|
21
|
+
for (const crossing of state.crossings) {
|
|
22
|
+
if (crossing.status === "unresolved" &&
|
|
23
|
+
(crossing.tier === "tier_a" || crossing.tier === "tier_b") &&
|
|
24
|
+
!(0, node_fs_1.existsSync)(crossing.file)) {
|
|
25
|
+
crossing.status = "denied";
|
|
26
|
+
repaired += 1;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (repaired > 0) {
|
|
30
|
+
const unresolvedProtected = state.crossings.some((crossing) => crossing.status === "unresolved" &&
|
|
31
|
+
(crossing.tier === "tier_a" || crossing.tier === "tier_b"));
|
|
32
|
+
if (!unresolvedProtected) {
|
|
33
|
+
state.blockedAt = undefined;
|
|
34
|
+
state.status = "active";
|
|
35
|
+
}
|
|
36
|
+
(0, session_state_1.writeSessionState)(state);
|
|
37
|
+
}
|
|
38
|
+
return repaired;
|
|
39
|
+
}
|
|
40
|
+
function renderStatus() {
|
|
41
|
+
const cfg = (0, config_1.readConfig)();
|
|
42
|
+
const state = (0, session_state_1.readSessionState)();
|
|
43
|
+
if (!cfg.projectId && !cfg.activeAgentId) {
|
|
44
|
+
return "No local AgentBridge config found.\nNext: run `agentbridge init`.";
|
|
45
|
+
}
|
|
46
|
+
const lines = [];
|
|
47
|
+
lines.push(`Project: ${cfg.projectId ?? "not set"}`);
|
|
48
|
+
lines.push(`Active agent: ${cfg.activeAgentId ?? "not set"}`);
|
|
49
|
+
const protectedDomains = (cfg.domains ?? [])
|
|
50
|
+
.filter((domain) => domain.tier === "tier_a" || domain.tier === "tier_b")
|
|
51
|
+
.map((domain) => domain.domain);
|
|
52
|
+
lines.push(`Protected domains: ${protectedDomains.length > 0 ? protectedDomains.join(", ") : "none"}`);
|
|
53
|
+
const recentHandoff = (0, session_state_1.readRecentHandoffs)(1)[0];
|
|
54
|
+
if (recentHandoff) {
|
|
55
|
+
lines.push(`Recent handoff: ${recentHandoff.agentId} -> ${recentHandoff.pendingHandoffToAgent ?? "unknown"} (${recentHandoff.pendingHandoffDomain ?? "unclassified"})`);
|
|
56
|
+
}
|
|
57
|
+
if (!state || state.id === "none" || state.status === "closed") {
|
|
58
|
+
lines.push("Session: no active session");
|
|
59
|
+
if (cfg.lastAcceptedSessionId) {
|
|
60
|
+
lines.push(`Last accepted session: ${cfg.lastAcceptedSessionId}`);
|
|
61
|
+
}
|
|
62
|
+
lines.push("Next: agentbridge watch");
|
|
63
|
+
return lines.join("\n");
|
|
64
|
+
}
|
|
65
|
+
lines.push(`Lane: ${state.laneDomain ?? "unclassified"}`);
|
|
66
|
+
lines.push(`Session: ${state.status}`);
|
|
67
|
+
lines.push(`Blocked: ${state.blockedAt ? "yes" : "no"}`);
|
|
68
|
+
lines.push(`Changed files: ${state.changedFiles.length}`);
|
|
69
|
+
const unresolvedProtected = state.crossings.filter((c) => c.status === "unresolved" && (c.tier === "tier_a" || c.tier === "tier_b"));
|
|
70
|
+
const unresolvedInformational = state.crossings.filter((c) => c.status === "unresolved" && c.tier !== "tier_a" && c.tier !== "tier_b");
|
|
71
|
+
const handoffRequired = state.crossings.some((c) => c.status === "handoff");
|
|
72
|
+
const approvals = state.approvals.length;
|
|
73
|
+
lines.push(`Unresolved crossings: ${unresolvedProtected.length}`);
|
|
74
|
+
if (unresolvedInformational.length > 0) {
|
|
75
|
+
lines.push(`Informational crossings: ${unresolvedInformational.length}`);
|
|
76
|
+
}
|
|
77
|
+
lines.push(`Scoped approvals: ${approvals}`);
|
|
78
|
+
const acceptanceSummary = unresolvedProtected.length > 0 ? "failed" : "needs_proof";
|
|
79
|
+
lines.push(`Acceptance: ${acceptanceSummary} (run agentbridge check)`);
|
|
80
|
+
if (unresolvedProtected.length > 0) {
|
|
81
|
+
const first = unresolvedProtected[0];
|
|
82
|
+
lines.push(`Blocking file: ${first.file} (${first.domain ?? "unclassified"} · ${first.tier.toUpperCase()})`);
|
|
83
|
+
if (!(0, node_fs_1.existsSync)(first.file)) {
|
|
84
|
+
lines.push("Blocking file no longer exists; run agentbridge status --repair");
|
|
85
|
+
}
|
|
86
|
+
lines.push("Allowed actions: approve / deny / limit / handoff / abandon");
|
|
87
|
+
}
|
|
88
|
+
else if (handoffRequired) {
|
|
89
|
+
lines.push("Close state: handoff required");
|
|
90
|
+
lines.push("Next action: post handoff details (handoff command will be available in Phase 2)");
|
|
91
|
+
}
|
|
92
|
+
else if (unresolvedInformational.length > 0) {
|
|
93
|
+
const firstInfo = unresolvedInformational[0];
|
|
94
|
+
lines.push(`Informational file: ${firstInfo.file} (${firstInfo.domain ?? "unclassified"} · ${firstInfo.tier.toUpperCase()})`);
|
|
95
|
+
lines.push("Non-blocking: informational crossing recorded");
|
|
96
|
+
lines.push("Next action: continue in lane or close session");
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
lines.push("Next action: continue in lane or close session");
|
|
100
|
+
}
|
|
101
|
+
return lines.join("\n");
|
|
102
|
+
}
|
|
103
|
+
function resolveNetworkContext() {
|
|
104
|
+
const cfg = (0, config_1.readConfig)();
|
|
105
|
+
const projectId = process.env.AGENTBRIDGE_PROJECT_ID ?? cfg.projectId;
|
|
106
|
+
const apiKey = process.env.AGENTBRIDGE_API_KEY ?? cfg.apiKey ?? "";
|
|
107
|
+
const apiBaseUrl = process.env.AGENTBRIDGE_BASE_URL ?? cfg.apiBaseUrl ?? "https://agentauth-api-production.up.railway.app";
|
|
108
|
+
if (!projectId || !apiKey)
|
|
109
|
+
return null;
|
|
110
|
+
return { projectId, apiKey, apiBaseUrl };
|
|
111
|
+
}
|
|
112
|
+
function hasHandoffRequiredAction(actions) {
|
|
113
|
+
return actions.some((action) => action.toLowerCase().includes("handoff"));
|
|
114
|
+
}
|
|
115
|
+
function renderAcceptanceBlock(input) {
|
|
116
|
+
return [
|
|
117
|
+
"Acceptance:",
|
|
118
|
+
`- decision: ${input.decision}`,
|
|
119
|
+
`- changed files: ${input.changedFiles}`,
|
|
120
|
+
`- missing proof: ${input.missingProof}`,
|
|
121
|
+
"- next: run agentbridge check",
|
|
122
|
+
].join("\n");
|
|
123
|
+
}
|
|
124
|
+
function renderWorkContextTruthBlock(input) {
|
|
125
|
+
const lines = [];
|
|
126
|
+
lines.push("WORK CONTEXT");
|
|
127
|
+
lines.push("Current work context:");
|
|
128
|
+
lines.push(`- current CR: ${input.currentCr ?? "none"}`);
|
|
129
|
+
lines.push(`- current session: ${input.currentSessionId ?? "none"}`);
|
|
130
|
+
lines.push(`- source: ${input.source}`);
|
|
131
|
+
lines.push("");
|
|
132
|
+
lines.push("Other active server sessions:");
|
|
133
|
+
if (input.otherActiveSessions.length === 0) {
|
|
134
|
+
lines.push("- none");
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
for (const session of input.otherActiveSessions) {
|
|
138
|
+
lines.push(`- ${session.id} / ${session.change_request_id ?? "no CR"} / ${session.status}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
lines.push("");
|
|
142
|
+
lines.push("Last accepted:");
|
|
143
|
+
lines.push(`- ${input.lastAcceptedSessionId ?? "none"}`);
|
|
144
|
+
return lines;
|
|
145
|
+
}
|
|
146
|
+
function firstTopMemoryItem(candidate) {
|
|
147
|
+
return (candidate.invariants[0] ??
|
|
148
|
+
candidate.known_traps[0] ??
|
|
149
|
+
candidate.future_proof_requirements[0] ??
|
|
150
|
+
candidate.accepted_lessons[0] ??
|
|
151
|
+
null);
|
|
152
|
+
}
|
|
153
|
+
function renderMemoryCandidatesBlock(input) {
|
|
154
|
+
if (!input.candidate) {
|
|
155
|
+
return [
|
|
156
|
+
"Memory candidates:",
|
|
157
|
+
"- status: unavailable",
|
|
158
|
+
`- why: ${input.unavailableReason ?? "No candidate context available."}`,
|
|
159
|
+
"- next: agentbridge memory suggest --compact",
|
|
160
|
+
];
|
|
161
|
+
}
|
|
162
|
+
const topItem = firstTopMemoryItem(input.candidate);
|
|
163
|
+
const lines = ["Memory candidates:", "- status: available", `- decision: ${input.candidate.decision}`];
|
|
164
|
+
if (topItem) {
|
|
165
|
+
lines.push(`- top item: ${topItem}`);
|
|
166
|
+
}
|
|
167
|
+
lines.push("- next: agentbridge memory suggest --compact");
|
|
168
|
+
return lines;
|
|
169
|
+
}
|
|
170
|
+
function deriveProofState(snapshot) {
|
|
171
|
+
if (snapshot.completion_state === "failed")
|
|
172
|
+
return "failed";
|
|
173
|
+
if (snapshot.evidence_missing_count > 0 || snapshot.completion_state === "needs_proof") {
|
|
174
|
+
return "needs_proof";
|
|
175
|
+
}
|
|
176
|
+
if (snapshot.completion_state === "needs_review")
|
|
177
|
+
return "needs_review";
|
|
178
|
+
return snapshot.completion_state;
|
|
179
|
+
}
|
|
180
|
+
function deriveHandoffState(snapshot) {
|
|
181
|
+
if (snapshot.completion_state === "ready_for_handoff")
|
|
182
|
+
return "ready_for_handoff";
|
|
183
|
+
if (snapshot.completion_state === "ready_to_accept")
|
|
184
|
+
return "ready_to_accept";
|
|
185
|
+
if (snapshot.completion_state === "accepted")
|
|
186
|
+
return "accepted";
|
|
187
|
+
if (snapshot.completion_state === "no_current_session")
|
|
188
|
+
return "no_current_session";
|
|
189
|
+
return "needs_review";
|
|
190
|
+
}
|
|
191
|
+
function buildTrustedTruthLines(input) {
|
|
192
|
+
const lines = [];
|
|
193
|
+
lines.push("TRUSTED TRUTH SCREEN");
|
|
194
|
+
lines.push(`- work context: ${input.snapshot.work_context_state} (source: ${input.workContextSource})`);
|
|
195
|
+
lines.push(`- current CR/session: ${input.snapshot.current_change_request_id ?? "none"} / ${input.snapshot.current_work_session_id ?? "none"}`);
|
|
196
|
+
lines.push(`- completion state: ${input.snapshot.completion_state}`);
|
|
197
|
+
lines.push(`- proof state: ${deriveProofState(input.snapshot)} (missing=${input.snapshot.evidence_missing_count})`);
|
|
198
|
+
lines.push(`- handoff state: ${deriveHandoffState(input.snapshot)}`);
|
|
199
|
+
lines.push(`- memory candidate state: ${input.memoryCandidate ? `available (${input.memoryCandidate.decision})` : "unavailable"}`);
|
|
200
|
+
if (!input.memoryCandidate && input.memoryUnavailableReason) {
|
|
201
|
+
lines.push(`- memory reason: ${input.memoryUnavailableReason}`);
|
|
202
|
+
}
|
|
203
|
+
lines.push(`- other active sessions: ${input.otherActiveSessions.length}`);
|
|
204
|
+
lines.push(`- last accepted session: ${input.lastAcceptedSessionId ?? "none"}`);
|
|
205
|
+
lines.push(`- next action: ${input.snapshot.next_action}`);
|
|
206
|
+
lines.push(`- next reason: ${input.snapshot.next_reason}`);
|
|
207
|
+
return lines;
|
|
208
|
+
}
|
|
209
|
+
function buildLocalOnlySnapshot(state) {
|
|
210
|
+
const hasLocalSession = !!state && state.id !== "none" && state.status !== "closed";
|
|
211
|
+
if (!hasLocalSession) {
|
|
212
|
+
return {
|
|
213
|
+
completion_state: "no_current_session",
|
|
214
|
+
completion_state_label: "No current session",
|
|
215
|
+
decision: "none",
|
|
216
|
+
next_action: "agentbridge watch",
|
|
217
|
+
next_reason: "No local active session and no network context available.",
|
|
218
|
+
work_context_state: "no_current_session",
|
|
219
|
+
work_context_source: "none",
|
|
220
|
+
has_current_session: false,
|
|
221
|
+
current_change_request_id: null,
|
|
222
|
+
current_work_session_id: null,
|
|
223
|
+
other_active_sessions_count: 0,
|
|
224
|
+
changed_files_count: 0,
|
|
225
|
+
evidence_missing_count: 0,
|
|
226
|
+
risks_remaining_count: 0,
|
|
227
|
+
protocol_warnings_count: 0,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
const unresolvedProtected = state.crossings.filter((crossing) => crossing.status === "unresolved" && (crossing.tier === "tier_a" || crossing.tier === "tier_b"));
|
|
231
|
+
const localFailed = unresolvedProtected.length > 0;
|
|
232
|
+
return {
|
|
233
|
+
completion_state: localFailed ? "failed" : "needs_proof",
|
|
234
|
+
completion_state_label: localFailed ? "Failed" : "Needs proof",
|
|
235
|
+
decision: localFailed ? "failed" : "needs_proof",
|
|
236
|
+
next_action: localFailed ? "agentbridge check" : "agentbridge check",
|
|
237
|
+
next_reason: localFailed
|
|
238
|
+
? "Local protected crossings remain unresolved."
|
|
239
|
+
: "Local session has pending changes; confirm acceptance when API context is available.",
|
|
240
|
+
work_context_state: "no_current_session",
|
|
241
|
+
work_context_source: "local session",
|
|
242
|
+
has_current_session: true,
|
|
243
|
+
current_change_request_id: null,
|
|
244
|
+
current_work_session_id: state.serverSessionId ?? null,
|
|
245
|
+
other_active_sessions_count: 0,
|
|
246
|
+
changed_files_count: state.changedFiles.length,
|
|
247
|
+
evidence_missing_count: state.changedFiles.length > 0 ? 1 : 0,
|
|
248
|
+
risks_remaining_count: 0,
|
|
249
|
+
protocol_warnings_count: 0,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
async function runStatus(options) {
|
|
253
|
+
const cfg = (0, config_1.readConfig)();
|
|
254
|
+
if (options?.repair) {
|
|
255
|
+
const repaired = repairMissingBlockingFiles();
|
|
256
|
+
process.stdout.write(`Repaired ${repaired} missing blocking crossing(s).\n`);
|
|
257
|
+
}
|
|
258
|
+
const state = (0, session_state_1.readSessionState)();
|
|
259
|
+
const hasLocalSession = !!state && state.id !== "none" && state.status !== "closed";
|
|
260
|
+
const base = renderStatus();
|
|
261
|
+
const output = [base];
|
|
262
|
+
let ctx = null;
|
|
263
|
+
try {
|
|
264
|
+
ctx = resolveNetworkContext();
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
ctx = null;
|
|
268
|
+
}
|
|
269
|
+
if (ctx) {
|
|
270
|
+
const { resolution } = await (0, acceptance_preflight_1.resolveAcceptanceWorkContext)(ctx, {
|
|
271
|
+
includeOtherActiveSessions: true,
|
|
272
|
+
useConfigActiveChangeRequestId: false,
|
|
273
|
+
});
|
|
274
|
+
const snapshot = (0, operator_snapshot_1.buildOperatorSnapshot)(resolution);
|
|
275
|
+
const healthChecks = (0, health_1.buildHealthChecks)({
|
|
276
|
+
configProjectId: !!cfg.projectId,
|
|
277
|
+
configApiKey: !!cfg.apiKey,
|
|
278
|
+
workContextResolved: resolution.state === "current_session_resolved",
|
|
279
|
+
protocolWarnings: snapshot.protocol_warnings_count,
|
|
280
|
+
evidenceMissing: snapshot.evidence_missing_count,
|
|
281
|
+
});
|
|
282
|
+
const healthRollup = (0, health_1.deriveHealthRollup)({ snapshot, checks: healthChecks });
|
|
283
|
+
let memoryCandidate = null;
|
|
284
|
+
let memoryUnavailableReason;
|
|
285
|
+
if (resolution.state === "current_session_resolved" && snapshot.current_work_session_id) {
|
|
286
|
+
try {
|
|
287
|
+
memoryCandidate = await (0, server_sync_1.fetchMemorySuggestion)(ctx, {
|
|
288
|
+
workSessionId: snapshot.current_work_session_id,
|
|
289
|
+
changeRequestId: snapshot.current_change_request_id ?? undefined,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
memoryUnavailableReason = "Memory suggestion is currently unavailable.";
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
memoryUnavailableReason = "No current resolved server session for memory suggestions.";
|
|
298
|
+
}
|
|
299
|
+
const trustedTruth = buildTrustedTruthLines({
|
|
300
|
+
snapshot,
|
|
301
|
+
workContextSource: resolution.contextSource,
|
|
302
|
+
otherActiveSessions: resolution.otherActiveSessions,
|
|
303
|
+
memoryCandidate,
|
|
304
|
+
memoryUnavailableReason,
|
|
305
|
+
lastAcceptedSessionId: cfg.lastAcceptedSessionId ?? null,
|
|
306
|
+
});
|
|
307
|
+
if (options?.json) {
|
|
308
|
+
process.stdout.write(`${JSON.stringify({
|
|
309
|
+
snapshot,
|
|
310
|
+
health: {
|
|
311
|
+
checks: healthChecks,
|
|
312
|
+
rollup: healthRollup,
|
|
313
|
+
},
|
|
314
|
+
memory_candidate: memoryCandidate,
|
|
315
|
+
truth_screen: {
|
|
316
|
+
work_context: {
|
|
317
|
+
state: snapshot.work_context_state,
|
|
318
|
+
source: resolution.contextSource,
|
|
319
|
+
},
|
|
320
|
+
current_cr_session: {
|
|
321
|
+
change_request_id: snapshot.current_change_request_id,
|
|
322
|
+
work_session_id: snapshot.current_work_session_id,
|
|
323
|
+
},
|
|
324
|
+
completion_state: snapshot.completion_state,
|
|
325
|
+
proof_state: deriveProofState(snapshot),
|
|
326
|
+
handoff_state: deriveHandoffState(snapshot),
|
|
327
|
+
memory_candidate_state: memoryCandidate ? "available" : "unavailable",
|
|
328
|
+
other_active_sessions: resolution.otherActiveSessions,
|
|
329
|
+
last_accepted_session_id: cfg.lastAcceptedSessionId ?? null,
|
|
330
|
+
next_action: snapshot.next_action,
|
|
331
|
+
next_reason: snapshot.next_reason,
|
|
332
|
+
},
|
|
333
|
+
}, null, 2)}\n`);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const currentCr = resolution.binding?.changeRequestId ?? resolution.requestedChangeRequestId ?? null;
|
|
337
|
+
const currentSessionId = resolution.binding?.workSessionId ?? null;
|
|
338
|
+
output.push(...trustedTruth);
|
|
339
|
+
output.push("");
|
|
340
|
+
output.push("");
|
|
341
|
+
output.push(...renderWorkContextTruthBlock({
|
|
342
|
+
currentCr,
|
|
343
|
+
currentSessionId,
|
|
344
|
+
source: resolution.contextSource,
|
|
345
|
+
otherActiveSessions: resolution.otherActiveSessions,
|
|
346
|
+
lastAcceptedSessionId: cfg.lastAcceptedSessionId ?? null,
|
|
347
|
+
}));
|
|
348
|
+
if (resolution.state === "current_session_resolved" && resolution.binding) {
|
|
349
|
+
const report = resolution.binding.report;
|
|
350
|
+
if (report) {
|
|
351
|
+
output.push("");
|
|
352
|
+
output.push(renderAcceptanceBlock({
|
|
353
|
+
decision: report.decision,
|
|
354
|
+
changedFiles: report.changed_files.length,
|
|
355
|
+
missingProof: report.evidence_missing.length,
|
|
356
|
+
}));
|
|
357
|
+
if (hasHandoffRequiredAction(report.next_required_action)) {
|
|
358
|
+
output.push("Close state: handoff required");
|
|
359
|
+
output.push("Next action: agentbridge handoff --summary \"<what changed>\"");
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
output.push("");
|
|
363
|
+
output.push(...renderMemoryCandidatesBlock({ candidate: memoryCandidate, unavailableReason: memoryUnavailableReason }));
|
|
364
|
+
output.push("");
|
|
365
|
+
output.push("Health rollup:");
|
|
366
|
+
output.push(`- overall: ${healthRollup.overall_status}`);
|
|
367
|
+
output.push(`- checks pass/warn: ${healthRollup.pass_count}/${healthRollup.warn_count}`);
|
|
368
|
+
output.push(`- missing proof: ${healthRollup.has_missing_proof ? "yes" : "no"}`);
|
|
369
|
+
output.push(`- protocol warnings: ${healthRollup.has_protocol_warnings ? "yes" : "no"}`);
|
|
370
|
+
output.push("");
|
|
371
|
+
output.push(...(0, operator_snapshot_1.renderOperatorNextStepBlock)(snapshot));
|
|
372
|
+
process.stdout.write(`${output.join("\n")}\n`);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
output.push("");
|
|
376
|
+
output.push(...(0, work_context_resolver_1.renderWorkContextLines)(resolution));
|
|
377
|
+
if (hasLocalSession) {
|
|
378
|
+
const fallbackDecision = state.crossings.some((crossing) => crossing.status === "unresolved" &&
|
|
379
|
+
(crossing.tier === "tier_a" || crossing.tier === "tier_b"))
|
|
380
|
+
? "failed"
|
|
381
|
+
: "needs_proof";
|
|
382
|
+
output.push(renderAcceptanceBlock({
|
|
383
|
+
decision: fallbackDecision,
|
|
384
|
+
changedFiles: state.changedFiles.length,
|
|
385
|
+
missingProof: state.changedFiles.length > 0 ? 1 : 0,
|
|
386
|
+
}));
|
|
387
|
+
}
|
|
388
|
+
output.push("");
|
|
389
|
+
output.push(...renderMemoryCandidatesBlock({ candidate: memoryCandidate, unavailableReason: memoryUnavailableReason }));
|
|
390
|
+
output.push("");
|
|
391
|
+
output.push("Health rollup:");
|
|
392
|
+
output.push(`- overall: ${healthRollup.overall_status}`);
|
|
393
|
+
output.push(`- checks pass/warn: ${healthRollup.pass_count}/${healthRollup.warn_count}`);
|
|
394
|
+
output.push(`- missing proof: ${healthRollup.has_missing_proof ? "yes" : "no"}`);
|
|
395
|
+
output.push(`- protocol warnings: ${healthRollup.has_protocol_warnings ? "yes" : "no"}`);
|
|
396
|
+
output.push("");
|
|
397
|
+
output.push(...(0, operator_snapshot_1.renderOperatorNextStepBlock)(snapshot));
|
|
398
|
+
process.stdout.write(`${output.join("\n")}\n`);
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
const localSnapshot = buildLocalOnlySnapshot(state);
|
|
402
|
+
const localHealthChecks = (0, health_1.buildHealthChecks)({
|
|
403
|
+
configProjectId: !!cfg.projectId,
|
|
404
|
+
configApiKey: !!cfg.apiKey,
|
|
405
|
+
workContextResolved: false,
|
|
406
|
+
protocolWarnings: localSnapshot.protocol_warnings_count,
|
|
407
|
+
evidenceMissing: localSnapshot.evidence_missing_count,
|
|
408
|
+
});
|
|
409
|
+
localHealthChecks[2] = {
|
|
410
|
+
id: "network-context",
|
|
411
|
+
status: "warn",
|
|
412
|
+
detail: "no active API context",
|
|
413
|
+
};
|
|
414
|
+
const localHealthRollup = (0, health_1.deriveHealthRollup)({
|
|
415
|
+
snapshot: localSnapshot,
|
|
416
|
+
checks: localHealthChecks,
|
|
417
|
+
});
|
|
418
|
+
const localResolutionState = hasLocalSession ? "current_session_resolved" : "no_current_session";
|
|
419
|
+
const localTrustedTruth = buildTrustedTruthLines({
|
|
420
|
+
snapshot: {
|
|
421
|
+
...localSnapshot,
|
|
422
|
+
work_context_state: (0, canonical_state_1.toCanonicalWorkContextState)(localResolutionState),
|
|
423
|
+
},
|
|
424
|
+
workContextSource: hasLocalSession ? "local session" : "none",
|
|
425
|
+
otherActiveSessions: [],
|
|
426
|
+
memoryCandidate: null,
|
|
427
|
+
memoryUnavailableReason: "No network context available.",
|
|
428
|
+
lastAcceptedSessionId: cfg.lastAcceptedSessionId ?? null,
|
|
429
|
+
});
|
|
430
|
+
if (options?.json) {
|
|
431
|
+
process.stdout.write(`${JSON.stringify({
|
|
432
|
+
snapshot: localSnapshot,
|
|
433
|
+
health: {
|
|
434
|
+
checks: localHealthChecks,
|
|
435
|
+
rollup: localHealthRollup,
|
|
436
|
+
},
|
|
437
|
+
memory_candidate: null,
|
|
438
|
+
truth_screen: {
|
|
439
|
+
work_context: {
|
|
440
|
+
state: localSnapshot.work_context_state,
|
|
441
|
+
source: hasLocalSession ? "local session" : "none",
|
|
442
|
+
},
|
|
443
|
+
current_cr_session: {
|
|
444
|
+
change_request_id: localSnapshot.current_change_request_id,
|
|
445
|
+
work_session_id: localSnapshot.current_work_session_id,
|
|
446
|
+
},
|
|
447
|
+
completion_state: localSnapshot.completion_state,
|
|
448
|
+
proof_state: deriveProofState(localSnapshot),
|
|
449
|
+
handoff_state: deriveHandoffState(localSnapshot),
|
|
450
|
+
memory_candidate_state: "unavailable",
|
|
451
|
+
other_active_sessions: [],
|
|
452
|
+
last_accepted_session_id: cfg.lastAcceptedSessionId ?? null,
|
|
453
|
+
next_action: localSnapshot.next_action,
|
|
454
|
+
next_reason: localSnapshot.next_reason,
|
|
455
|
+
},
|
|
456
|
+
}, null, 2)}\n`);
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
output.push(...localTrustedTruth);
|
|
460
|
+
output.push("");
|
|
461
|
+
if (hasLocalSession) {
|
|
462
|
+
const fallbackDecision = state.crossings.some((crossing) => crossing.status === "unresolved" &&
|
|
463
|
+
(crossing.tier === "tier_a" || crossing.tier === "tier_b"))
|
|
464
|
+
? "failed"
|
|
465
|
+
: "needs_proof";
|
|
466
|
+
output.push(renderAcceptanceBlock({
|
|
467
|
+
decision: fallbackDecision,
|
|
468
|
+
changedFiles: state.changedFiles.length,
|
|
469
|
+
missingProof: state.changedFiles.length > 0 ? 1 : 0,
|
|
470
|
+
}));
|
|
471
|
+
}
|
|
472
|
+
output.push("");
|
|
473
|
+
output.push("Work context source:");
|
|
474
|
+
output.push("- local-only (network/API context unavailable)");
|
|
475
|
+
output.push("");
|
|
476
|
+
output.push(...renderMemoryCandidatesBlock({ candidate: null, unavailableReason: "No network context available." }));
|
|
477
|
+
output.push("");
|
|
478
|
+
output.push("Health rollup:");
|
|
479
|
+
output.push(`- overall: ${localHealthRollup.overall_status}`);
|
|
480
|
+
output.push(`- checks pass/warn: ${localHealthRollup.pass_count}/${localHealthRollup.warn_count}`);
|
|
481
|
+
output.push(`- missing proof: ${localHealthRollup.has_missing_proof ? "yes" : "no"}`);
|
|
482
|
+
output.push(`- protocol warnings: ${localHealthRollup.has_protocol_warnings ? "yes" : "no"}`);
|
|
483
|
+
output.push("");
|
|
484
|
+
output.push(...(0, operator_snapshot_1.renderOperatorNextStepBlock)(localSnapshot));
|
|
485
|
+
process.stdout.write(`${output.join("\n")}\n`);
|
|
486
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runUse = runUse;
|
|
4
|
+
const config_1 = require("../config");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
function runUse(agentId) {
|
|
7
|
+
const trimmed = agentId.trim();
|
|
8
|
+
if (!trimmed) {
|
|
9
|
+
throw new errors_1.SafeCliError("Usage: agentbridge use <agent-id>");
|
|
10
|
+
}
|
|
11
|
+
(0, config_1.updateConfig)({ activeAgentId: trimmed });
|
|
12
|
+
process.stdout.write(`Active agent set to ${trimmed}\n`);
|
|
13
|
+
}
|