@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.
- 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 +192 -13
- package/dist/commands/doctor.js +163 -29
- package/dist/commands/proof-guidance.js +30 -0
- package/dist/commands/recover.js +171 -22
- package/dist/commands/setup-mcp.js +22 -1
- package/dist/commands/start.js +57 -63
- package/dist/commands/verify.js +124 -91
- package/dist/commands/watch.js +428 -113
- package/dist/error-catalog.js +57 -16
- package/dist/gates.js +3 -3
- package/dist/git-evidence.js +2 -0
- package/dist/http.js +29 -0
- package/dist/index.js +47 -30
- package/dist/init.js +204 -30
- 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/server-sync.js +36 -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/session-state.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isActiveLocalSession = isActiveLocalSession;
|
|
4
|
+
exports.resolveRepoRoot = resolveRepoRoot;
|
|
3
5
|
exports.readSessionState = readSessionState;
|
|
4
6
|
exports.writeSessionState = writeSessionState;
|
|
5
7
|
exports.archiveClosedSession = archiveClosedSession;
|
|
@@ -8,11 +10,34 @@ exports.readRecentHandoffs = readRecentHandoffs;
|
|
|
8
10
|
exports.clearSessionState = clearSessionState;
|
|
9
11
|
const node_fs_1 = require("node:fs");
|
|
10
12
|
const node_path_1 = require("node:path");
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const local_proof_1 = require("./local-proof");
|
|
14
|
+
function isActiveLocalSession(state) {
|
|
15
|
+
if (!state)
|
|
16
|
+
return false;
|
|
17
|
+
if (state.status === "closed")
|
|
18
|
+
return false;
|
|
19
|
+
if (!state.id || state.id === "none")
|
|
20
|
+
return false;
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
function resolveRepoRoot() {
|
|
24
|
+
return process.env.AGENTBRIDGE_REPO_ROOT?.trim() || process.cwd();
|
|
25
|
+
}
|
|
26
|
+
function sessionDir() {
|
|
27
|
+
return (0, node_path_1.resolve)(resolveRepoRoot(), ".agentbridge");
|
|
28
|
+
}
|
|
29
|
+
function sessionPath() {
|
|
30
|
+
return (0, node_path_1.resolve)(sessionDir(), "session.json");
|
|
31
|
+
}
|
|
32
|
+
function sessionsDir() {
|
|
33
|
+
return (0, node_path_1.resolve)(sessionDir(), "sessions");
|
|
34
|
+
}
|
|
35
|
+
function handoffsDir() {
|
|
36
|
+
return (0, node_path_1.resolve)(sessionDir(), "handoffs");
|
|
37
|
+
}
|
|
38
|
+
function sessionBackupPath() {
|
|
39
|
+
return (0, node_path_1.resolve)(sessionDir(), "session.json.bak");
|
|
40
|
+
}
|
|
16
41
|
function isRecord(value) {
|
|
17
42
|
return typeof value === "object" && value !== null;
|
|
18
43
|
}
|
|
@@ -28,6 +53,49 @@ function isBoundaryCrossingArray(value) {
|
|
|
28
53
|
function isScopedApprovalArray(value) {
|
|
29
54
|
return Array.isArray(value);
|
|
30
55
|
}
|
|
56
|
+
const AGENT_ACTIVITY_EVENTS = new Set([
|
|
57
|
+
"start_work_session",
|
|
58
|
+
"claim_lane",
|
|
59
|
+
"release_lane",
|
|
60
|
+
"update_work_session_scope",
|
|
61
|
+
"post_handoff",
|
|
62
|
+
"close_work_session",
|
|
63
|
+
]);
|
|
64
|
+
function isAgentActivity(value) {
|
|
65
|
+
if (!isRecord(value))
|
|
66
|
+
return false;
|
|
67
|
+
if (value.source !== "mcp")
|
|
68
|
+
return false;
|
|
69
|
+
if (typeof value.updatedAt !== "string" || value.updatedAt.length === 0)
|
|
70
|
+
return false;
|
|
71
|
+
if (!AGENT_ACTIVITY_EVENTS.has(value.lastEvent))
|
|
72
|
+
return false;
|
|
73
|
+
if (value.intent !== undefined && typeof value.intent !== "string")
|
|
74
|
+
return false;
|
|
75
|
+
if (value.claimedPaths !== undefined && !isStringArray(value.claimedPaths))
|
|
76
|
+
return false;
|
|
77
|
+
if (value.workSessionId !== undefined && typeof value.workSessionId !== "string")
|
|
78
|
+
return false;
|
|
79
|
+
if (value.changeRequestId !== undefined && typeof value.changeRequestId !== "string")
|
|
80
|
+
return false;
|
|
81
|
+
if (value.laneDomain !== undefined && value.laneDomain !== null && typeof value.laneDomain !== "string") {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
if (value.laneId !== undefined && typeof value.laneId !== "string")
|
|
85
|
+
return false;
|
|
86
|
+
if (value.laneType !== undefined && !["product_area", "file_path", "task", "system"].includes(String(value.laneType))) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
if (value.laneValue !== undefined && typeof value.laneValue !== "string")
|
|
90
|
+
return false;
|
|
91
|
+
if (value.summary !== undefined && typeof value.summary !== "string")
|
|
92
|
+
return false;
|
|
93
|
+
if (value.closedAt !== undefined && typeof value.closedAt !== "string")
|
|
94
|
+
return false;
|
|
95
|
+
if (value.handoffId !== undefined && typeof value.handoffId !== "string")
|
|
96
|
+
return false;
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
31
99
|
function isLocalSessionState(value) {
|
|
32
100
|
if (!isRecord(value))
|
|
33
101
|
return false;
|
|
@@ -49,30 +117,57 @@ function isLocalSessionState(value) {
|
|
|
49
117
|
return false;
|
|
50
118
|
if (typeof value.createdAt !== "string" || value.createdAt.length === 0)
|
|
51
119
|
return false;
|
|
120
|
+
if (value.intent !== undefined && typeof value.intent !== "string")
|
|
121
|
+
return false;
|
|
122
|
+
if (value.mode !== undefined &&
|
|
123
|
+
value.mode !== "local_supervision" &&
|
|
124
|
+
value.mode !== "strict_tracked") {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
if (value.updatedAt !== undefined && typeof value.updatedAt !== "string")
|
|
128
|
+
return false;
|
|
129
|
+
if (value.closedAt !== undefined && typeof value.closedAt !== "string")
|
|
130
|
+
return false;
|
|
52
131
|
if (value.claimedPaths !== undefined && !isStringArray(value.claimedPaths))
|
|
53
132
|
return false;
|
|
133
|
+
if (value.lastLocalVerificationRun !== undefined &&
|
|
134
|
+
!(0, local_proof_1.isLocalVerificationRun)(value.lastLocalVerificationRun)) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
if (value.agentActivity !== undefined && !isAgentActivity(value.agentActivity)) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
54
140
|
return true;
|
|
55
141
|
}
|
|
142
|
+
function sanitizeAgentActivity(state) {
|
|
143
|
+
if (state.agentActivity !== undefined && !isAgentActivity(state.agentActivity)) {
|
|
144
|
+
const { agentActivity: _removed, ...rest } = state;
|
|
145
|
+
return rest;
|
|
146
|
+
}
|
|
147
|
+
return state;
|
|
148
|
+
}
|
|
56
149
|
function readJsonFile(path) {
|
|
57
150
|
return JSON.parse((0, node_fs_1.readFileSync)(path, "utf8"));
|
|
58
151
|
}
|
|
59
152
|
function quarantineInvalidSessionFile() {
|
|
60
|
-
|
|
153
|
+
const path = sessionPath();
|
|
154
|
+
if (!(0, node_fs_1.existsSync)(path))
|
|
61
155
|
return;
|
|
62
|
-
const quarantinedPath = (0, node_path_1.resolve)(
|
|
63
|
-
(0, node_fs_1.renameSync)(
|
|
156
|
+
const quarantinedPath = (0, node_path_1.resolve)(sessionDir(), `session.invalid-${new Date().toISOString().replace(/[:.]/g, "-")}.json`);
|
|
157
|
+
(0, node_fs_1.renameSync)(path, quarantinedPath);
|
|
64
158
|
}
|
|
65
159
|
function readSessionState() {
|
|
66
|
-
|
|
160
|
+
const path = sessionPath();
|
|
161
|
+
if (!(0, node_fs_1.existsSync)(path)) {
|
|
67
162
|
return null;
|
|
68
163
|
}
|
|
69
164
|
try {
|
|
70
|
-
const parsed = readJsonFile(
|
|
165
|
+
const parsed = readJsonFile(path);
|
|
71
166
|
if (!isLocalSessionState(parsed)) {
|
|
72
167
|
quarantineInvalidSessionFile();
|
|
73
168
|
return null;
|
|
74
169
|
}
|
|
75
|
-
return parsed;
|
|
170
|
+
return sanitizeAgentActivity(parsed);
|
|
76
171
|
}
|
|
77
172
|
catch {
|
|
78
173
|
quarantineInvalidSessionFile();
|
|
@@ -83,8 +178,10 @@ function writeSessionState(state) {
|
|
|
83
178
|
if (!isLocalSessionState(state)) {
|
|
84
179
|
throw new Error("Refusing to write invalid session state.");
|
|
85
180
|
}
|
|
86
|
-
|
|
87
|
-
const
|
|
181
|
+
const dir = sessionDir();
|
|
182
|
+
const path = sessionPath();
|
|
183
|
+
(0, node_fs_1.mkdirSync)(dir, { recursive: true });
|
|
184
|
+
const tempPath = (0, node_path_1.resolve)(dir, `session.json.tmp-${process.pid.toString()}-${Date.now().toString(36)}`);
|
|
88
185
|
const serialized = `${JSON.stringify(state, null, 2)}\n`;
|
|
89
186
|
(0, node_fs_1.writeFileSync)(tempPath, serialized, "utf8");
|
|
90
187
|
const tempParsed = readJsonFile(tempPath);
|
|
@@ -92,10 +189,10 @@ function writeSessionState(state) {
|
|
|
92
189
|
(0, node_fs_1.rmSync)(tempPath, { force: true });
|
|
93
190
|
throw new Error("Refusing to persist invalid session state payload.");
|
|
94
191
|
}
|
|
95
|
-
if ((0, node_fs_1.existsSync)(
|
|
96
|
-
(0, node_fs_1.renameSync)(
|
|
192
|
+
if ((0, node_fs_1.existsSync)(path)) {
|
|
193
|
+
(0, node_fs_1.renameSync)(path, sessionBackupPath());
|
|
97
194
|
}
|
|
98
|
-
(0, node_fs_1.renameSync)(tempPath,
|
|
195
|
+
(0, node_fs_1.renameSync)(tempPath, path);
|
|
99
196
|
}
|
|
100
197
|
function timestampPrefix(iso) {
|
|
101
198
|
return iso.replace(/[:.]/g, "-");
|
|
@@ -107,20 +204,21 @@ function writeArchive(dir, state) {
|
|
|
107
204
|
(0, node_fs_1.writeFileSync)((0, node_path_1.resolve)(dir, fileName), `${JSON.stringify(state, null, 2)}\n`, "utf8");
|
|
108
205
|
}
|
|
109
206
|
function archiveClosedSession(state) {
|
|
110
|
-
writeArchive(
|
|
207
|
+
writeArchive(sessionsDir(), state);
|
|
111
208
|
}
|
|
112
209
|
function archiveHandoff(state) {
|
|
113
|
-
writeArchive(
|
|
210
|
+
writeArchive(handoffsDir(), state);
|
|
114
211
|
}
|
|
115
212
|
function readRecentHandoffs(limit = 1) {
|
|
116
|
-
|
|
213
|
+
const dir = handoffsDir();
|
|
214
|
+
if (!(0, node_fs_1.existsSync)(dir)) {
|
|
117
215
|
return [];
|
|
118
216
|
}
|
|
119
|
-
const files = (0, node_fs_1.readdirSync)(
|
|
217
|
+
const files = (0, node_fs_1.readdirSync)(dir)
|
|
120
218
|
.filter((file) => file.endsWith(".json"))
|
|
121
219
|
.sort((a, b) => b.localeCompare(a))
|
|
122
220
|
.slice(0, Math.max(0, limit));
|
|
123
|
-
return files.map((file) => JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.resolve)(
|
|
221
|
+
return files.map((file) => JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.resolve)(dir, file), "utf8")));
|
|
124
222
|
}
|
|
125
223
|
function clearSessionState() {
|
|
126
224
|
writeSessionState({
|
package/dist/session.js
CHANGED
|
@@ -53,10 +53,13 @@ function captureLocalSessionBaseline() {
|
|
|
53
53
|
function openLocalSession(input) {
|
|
54
54
|
const claimedPaths = [...new Set((input.claimedPaths ?? []).map((path) => path.trim()).filter(Boolean))];
|
|
55
55
|
const baseline = captureLocalSessionBaseline();
|
|
56
|
+
const now = baseline.startedAt;
|
|
56
57
|
const state = {
|
|
57
58
|
id: `local_${Date.now().toString(36)}`,
|
|
58
|
-
agentId: input.agentId,
|
|
59
|
+
agentId: input.agentId?.trim() || "local",
|
|
59
60
|
laneDomain: input.laneDomain,
|
|
61
|
+
intent: input.intent?.trim() || undefined,
|
|
62
|
+
mode: input.mode,
|
|
60
63
|
changeRequestId: input.changeRequestId,
|
|
61
64
|
claimedPaths,
|
|
62
65
|
status: "active",
|
|
@@ -67,7 +70,8 @@ function openLocalSession(input) {
|
|
|
67
70
|
serverSessionId: input.serverSessionId,
|
|
68
71
|
pendingHandoffToAgent: input.pendingHandoffToAgent,
|
|
69
72
|
pendingHandoffDomain: input.pendingHandoffDomain,
|
|
70
|
-
createdAt:
|
|
73
|
+
createdAt: now,
|
|
74
|
+
updatedAt: now,
|
|
71
75
|
startedAt: baseline.startedAt,
|
|
72
76
|
gitHead: baseline.gitHead,
|
|
73
77
|
dirtyFilesAtStart: baseline.dirtyFilesAtStart,
|
|
@@ -81,8 +85,11 @@ function closeLocalSession(state) {
|
|
|
81
85
|
if (!closable.ok) {
|
|
82
86
|
return { ok: false, reason: closable.reason ?? "Session blocked" };
|
|
83
87
|
}
|
|
88
|
+
const closedAt = new Date().toISOString();
|
|
84
89
|
state.status = "closed";
|
|
85
90
|
state.closeReason = state.closeReason ?? "completed";
|
|
91
|
+
state.closedAt = closedAt;
|
|
92
|
+
state.updatedAt = closedAt;
|
|
86
93
|
(0, session_state_1.archiveClosedSession)(state);
|
|
87
94
|
(0, session_state_1.writeSessionState)(state);
|
|
88
95
|
return { ok: true };
|
package/dist/supervision.js
CHANGED
|
@@ -5,9 +5,12 @@ exports.requiredProofHints = requiredProofHints;
|
|
|
5
5
|
exports.computeScopeDriftAlerts = computeScopeDriftAlerts;
|
|
6
6
|
exports.supervisionFromAcceptance = supervisionFromAcceptance;
|
|
7
7
|
exports.fallbackSupervisionSnapshot = fallbackSupervisionSnapshot;
|
|
8
|
+
exports.enrichSupervisionWithLocalState = enrichSupervisionWithLocalState;
|
|
8
9
|
exports.supervisionSignature = supervisionSignature;
|
|
9
10
|
exports.renderSupervisionSummary = renderSupervisionSummary;
|
|
11
|
+
const claimed_paths_1 = require("./claimed-paths");
|
|
10
12
|
const domain_resolution_1 = require("./domain-resolution");
|
|
13
|
+
const preflight_changed_files_1 = require("./preflight-changed-files");
|
|
11
14
|
const memory_context_render_1 = require("./memory-context-render");
|
|
12
15
|
const CLI_GIT_REQUIRED_PROOF = [
|
|
13
16
|
"tracked modified file handled",
|
|
@@ -41,7 +44,7 @@ function requiredProofHints(workType) {
|
|
|
41
44
|
return ["explicit verification evidence for changed docs/files"];
|
|
42
45
|
return [
|
|
43
46
|
"explicit verification evidence for changed files",
|
|
44
|
-
"run agentbridge
|
|
47
|
+
"run agentbridge verify, then rerun agentbridge watch",
|
|
45
48
|
];
|
|
46
49
|
}
|
|
47
50
|
function escapeRegex(text) {
|
|
@@ -121,7 +124,7 @@ function supervisionFromAcceptance(report, domains) {
|
|
|
121
124
|
requiredProof,
|
|
122
125
|
knownTraps: report.known_traps.slice(0, 3),
|
|
123
126
|
memoryContext: report.memory_context,
|
|
124
|
-
nextAction: "Run
|
|
127
|
+
nextAction: "Run `agentbridge verify -- <command>`, then rerun `agentbridge watch`.",
|
|
125
128
|
driftAlerts,
|
|
126
129
|
};
|
|
127
130
|
}
|
|
@@ -144,11 +147,69 @@ function fallbackSupervisionSnapshot(input) {
|
|
|
144
147
|
decision: input.unresolvedProtectedCrossing || input.blocked ? "failed" : "needs_proof",
|
|
145
148
|
requiredProof,
|
|
146
149
|
knownTraps: [],
|
|
147
|
-
nextAction: "Run
|
|
150
|
+
nextAction: "Run `agentbridge verify -- <command>`, then rerun `agentbridge watch`.",
|
|
148
151
|
driftAlerts,
|
|
149
152
|
serverAcceptanceUnavailable: input.serverAcceptanceUnavailable,
|
|
150
153
|
};
|
|
151
154
|
}
|
|
155
|
+
function formatMcpEventTime(iso) {
|
|
156
|
+
if (!iso)
|
|
157
|
+
return "";
|
|
158
|
+
try {
|
|
159
|
+
const d = new Date(iso);
|
|
160
|
+
const h = d.getHours().toString().padStart(2, "0");
|
|
161
|
+
const m = d.getMinutes().toString().padStart(2, "0");
|
|
162
|
+
return `${h}:${m}`;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return "";
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function effectiveDeclaredPaths(state) {
|
|
169
|
+
return uniqueSorted([
|
|
170
|
+
...(state.claimedPaths ?? []),
|
|
171
|
+
...(state.agentActivity?.claimedPaths ?? []),
|
|
172
|
+
]);
|
|
173
|
+
}
|
|
174
|
+
/** Merge local session MCP mirror + post-baseline disk lens into a supervision snapshot. */
|
|
175
|
+
function enrichSupervisionWithLocalState(state, supervision) {
|
|
176
|
+
const postBaselineFiles = state.startedAt != null ? (0, preflight_changed_files_1.computeCurrentWorkFiles)(state) : [];
|
|
177
|
+
const totalDirty = (0, preflight_changed_files_1.repoDirtySnapshot)().length;
|
|
178
|
+
const claimedPaths = effectiveDeclaredPaths(state);
|
|
179
|
+
const driftFiles = claimedPaths.length > 0 ? (0, claimed_paths_1.filesOutsideClaimedPaths)(postBaselineFiles, claimedPaths) : [];
|
|
180
|
+
const declaredVsObservedDrift = claimedPaths.length > 0 && driftFiles.length > 0 ? "warn" : "none";
|
|
181
|
+
const activity = state.agentActivity;
|
|
182
|
+
const hasDeclared = activity !== undefined || Boolean(state.intent?.trim()) || claimedPaths.length > 0;
|
|
183
|
+
const agentDeclared = hasDeclared
|
|
184
|
+
? {
|
|
185
|
+
intent: activity?.intent ?? state.intent,
|
|
186
|
+
claimedPaths,
|
|
187
|
+
lastEvent: activity?.lastEvent,
|
|
188
|
+
workSessionId: activity?.workSessionId ?? state.serverSessionId,
|
|
189
|
+
updatedAt: activity?.updatedAt,
|
|
190
|
+
summary: activity?.summary,
|
|
191
|
+
fromMcp: activity?.source === "mcp",
|
|
192
|
+
}
|
|
193
|
+
: undefined;
|
|
194
|
+
const changedFiles = postBaselineFiles.length > 0 ? postBaselineFiles : supervision.changedFiles;
|
|
195
|
+
return {
|
|
196
|
+
...supervision,
|
|
197
|
+
changedFiles,
|
|
198
|
+
workType: inferSupervisionWorkType(changedFiles),
|
|
199
|
+
agentDeclared,
|
|
200
|
+
diskObserved: {
|
|
201
|
+
postBaselineFiles,
|
|
202
|
+
totalDirty,
|
|
203
|
+
},
|
|
204
|
+
declaredVsObservedDrift,
|
|
205
|
+
declaredDriftFiles: driftFiles,
|
|
206
|
+
scopeStatus: declaredVsObservedDrift === "warn"
|
|
207
|
+
? "drift"
|
|
208
|
+
: supervision.scopeStatus === "unknown" && changedFiles.length > 0
|
|
209
|
+
? "clean"
|
|
210
|
+
: supervision.scopeStatus,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
152
213
|
function supervisionSignature(snapshot) {
|
|
153
214
|
return JSON.stringify({
|
|
154
215
|
workSessionId: snapshot.workSessionId,
|
|
@@ -160,12 +221,45 @@ function supervisionSignature(snapshot) {
|
|
|
160
221
|
requiredProof: snapshot.requiredProof,
|
|
161
222
|
drift: snapshot.driftAlerts.map((a) => `${a.file}:${a.severity}:${a.likelyDomain}`),
|
|
162
223
|
serverAcceptanceUnavailable: snapshot.serverAcceptanceUnavailable ? "yes" : "no",
|
|
224
|
+
agentDeclared: snapshot.agentDeclared
|
|
225
|
+
? `${snapshot.agentDeclared.intent ?? ""}:${snapshot.agentDeclared.lastEvent ?? ""}`
|
|
226
|
+
: "",
|
|
227
|
+
declaredDrift: snapshot.declaredDriftFiles?.join(",") ?? "",
|
|
163
228
|
});
|
|
164
229
|
}
|
|
165
|
-
function renderSupervisionSummary(snapshot) {
|
|
230
|
+
function renderSupervisionSummary(snapshot, options) {
|
|
166
231
|
const lines = [];
|
|
167
|
-
lines.push("AgentBridge supervision:");
|
|
168
|
-
|
|
232
|
+
lines.push(options?.compact ? "AgentBridge watch:" : "AgentBridge supervision:");
|
|
233
|
+
if (!options?.compact) {
|
|
234
|
+
lines.push(`Current run: ${snapshot.workSessionId}${snapshot.changeRequestId ? ` / task ${snapshot.changeRequestId}` : ""}`);
|
|
235
|
+
}
|
|
236
|
+
const declared = snapshot.agentDeclared;
|
|
237
|
+
if (declared) {
|
|
238
|
+
const intentLabel = declared.intent?.trim() || declared.summary?.trim() || "(no intent text)";
|
|
239
|
+
const eventSuffix = declared.lastEvent && declared.updatedAt
|
|
240
|
+
? ` [${declared.lastEvent} @ ${formatMcpEventTime(declared.updatedAt)}]`
|
|
241
|
+
: declared.lastEvent
|
|
242
|
+
? ` [${declared.lastEvent}]`
|
|
243
|
+
: "";
|
|
244
|
+
lines.push(`Agent (MCP): ${intentLabel}${eventSuffix}`);
|
|
245
|
+
if (declared.claimedPaths.length > 0) {
|
|
246
|
+
const scopePreview = declared.claimedPaths.length > 6
|
|
247
|
+
? `${declared.claimedPaths.slice(0, 6).join(", ")} (+${declared.claimedPaths.length - 6} more)`
|
|
248
|
+
: declared.claimedPaths.join(", ");
|
|
249
|
+
lines.push(`Declared scope: ${scopePreview}`);
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
lines.push("Declared scope: (none yet)");
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const diskCount = snapshot.diskObserved?.postBaselineFiles.length ?? snapshot.changedFiles.length;
|
|
256
|
+
lines.push(`Files (disk): ${diskCount} changed since session start`);
|
|
257
|
+
if (snapshot.declaredVsObservedDrift === "warn" && snapshot.declaredDriftFiles?.length) {
|
|
258
|
+
const preview = snapshot.declaredDriftFiles.length > 4
|
|
259
|
+
? `${snapshot.declaredDriftFiles.slice(0, 4).join(", ")} (+${snapshot.declaredDriftFiles.length - 4} more)`
|
|
260
|
+
: snapshot.declaredDriftFiles.join(", ");
|
|
261
|
+
lines.push(`Note: ${snapshot.declaredDriftFiles.length} file(s) outside declared scope (${preview}) — warn only, not blocked`);
|
|
262
|
+
}
|
|
169
263
|
lines.push(`Changed files: ${snapshot.changedFiles.length}`);
|
|
170
264
|
lines.push(`Detected work type: ${snapshot.workType}`);
|
|
171
265
|
lines.push(`Scope: ${snapshot.scopeStatus}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentbridge1/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "CLI for AgentBridge — structured AI agent work sessions with domain authority and approval gates",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"build": "node build.mjs",
|
|
11
11
|
"prepare": "npm run build",
|
|
12
12
|
"prepack": "npm run build",
|
|
13
|
-
"smoke": "npm run build && node dist/index.js --help && node dist/index.js mcp --help",
|
|
13
|
+
"smoke": "npm run build && test -f dist/mcp/agentbridge-mcp.js && node dist/index.js --help && node dist/index.js mcp --help",
|
|
14
14
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
15
15
|
"test": "vitest run"
|
|
16
16
|
},
|
|
@@ -41,5 +41,8 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"chalk": "^5.6.2",
|
|
43
43
|
"chokidar": "^4.0.3"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"esbuild": "^0.25.12"
|
|
44
47
|
}
|
|
45
48
|
}
|