@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
package/dist/commands/recover.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.runRecover = runRecover;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const node_process_1 = require("node:process");
|
|
4
7
|
const config_1 = require("../config");
|
|
5
8
|
const errors_1 = require("../errors");
|
|
6
|
-
const server_sync_1 = require("../server-sync");
|
|
7
|
-
const node_process_1 = require("node:process");
|
|
8
9
|
const gates_1 = require("../gates");
|
|
9
|
-
const init_1 = require("../init");
|
|
10
10
|
const http_1 = require("../http");
|
|
11
|
+
const init_1 = require("../init");
|
|
12
|
+
const recovery_reconcile_1 = require("../recovery-reconcile");
|
|
13
|
+
const server_sync_1 = require("../server-sync");
|
|
11
14
|
function resolveNetworkContext() {
|
|
12
15
|
const cfg = (0, config_1.readConfig)();
|
|
13
16
|
const projectId = process.env.AGENTBRIDGE_PROJECT_ID ?? cfg.projectId ?? "";
|
|
@@ -20,9 +23,14 @@ function resolveNetworkContext() {
|
|
|
20
23
|
}
|
|
21
24
|
return { projectId, apiKey, apiBaseUrl };
|
|
22
25
|
}
|
|
26
|
+
function rulesInstalled(repoRoot) {
|
|
27
|
+
return ((0, node_fs_1.existsSync)((0, node_path_1.resolve)(repoRoot, "AGENTBRIDGE.md")) &&
|
|
28
|
+
(0, node_fs_1.existsSync)((0, node_path_1.resolve)(repoRoot, ".cursor", "rules", "agentbridge.mdc")));
|
|
29
|
+
}
|
|
23
30
|
function renderRecoverOutput(packet) {
|
|
24
31
|
const lines = [];
|
|
25
|
-
const
|
|
32
|
+
const activeDomains = (packet.domains_summary ?? []).filter((d) => d.state !== "retired");
|
|
33
|
+
const domainCount = activeDomains.length;
|
|
26
34
|
const ruleCount = packet.global_rules?.length ?? 0;
|
|
27
35
|
const hasCharterContext = Boolean(packet.charter_summary?.purpose);
|
|
28
36
|
lines.push("Project recovered.");
|
|
@@ -36,7 +44,7 @@ function renderRecoverOutput(packet) {
|
|
|
36
44
|
if (domainCount > 0) {
|
|
37
45
|
lines.push("");
|
|
38
46
|
lines.push("Domains found:");
|
|
39
|
-
for (const domain of
|
|
47
|
+
for (const domain of activeDomains) {
|
|
40
48
|
const pathNote = domain.owned_path_count > 0 ? `${domain.owned_path_count} path(s)` : "paths pending";
|
|
41
49
|
lines.push(`- ${domain.domain_name} — ${pathNote}`);
|
|
42
50
|
}
|
|
@@ -55,18 +63,56 @@ function renderRecoverOutput(packet) {
|
|
|
55
63
|
}
|
|
56
64
|
lines.push("");
|
|
57
65
|
lines.push("Next:");
|
|
58
|
-
lines.push(" agentbridge
|
|
66
|
+
lines.push(" agentbridge watch");
|
|
59
67
|
lines.push("");
|
|
60
68
|
return lines.join("\n");
|
|
61
69
|
}
|
|
62
70
|
function recoveryStatusLabel(packet) {
|
|
63
71
|
return packet.recovery_status ?? "unknown";
|
|
64
72
|
}
|
|
65
|
-
function
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
function formatDomainLines(refs) {
|
|
74
|
+
if (refs.length === 0)
|
|
75
|
+
return " (none)";
|
|
76
|
+
return refs.map((d) => `- ${d.name}`).join("\n");
|
|
77
|
+
}
|
|
78
|
+
function renderReconcileReport(input) {
|
|
79
|
+
const { plan, applied, qualityAfter } = input;
|
|
80
|
+
const lines = [""];
|
|
81
|
+
if (applied) {
|
|
82
|
+
lines.push("AgentBridge checked recovery.");
|
|
83
|
+
lines.push(`Recovery quality: ${qualityAfter}`);
|
|
84
|
+
if (plan.toAdd.length > 0) {
|
|
85
|
+
lines.push("");
|
|
86
|
+
lines.push("Added:");
|
|
87
|
+
lines.push(formatDomainLines(plan.toAdd));
|
|
88
|
+
}
|
|
89
|
+
if (plan.toPreserve.length > 0) {
|
|
90
|
+
lines.push("");
|
|
91
|
+
lines.push("Existing domains preserved:");
|
|
92
|
+
lines.push(formatDomainLines(plan.toPreserve));
|
|
93
|
+
}
|
|
94
|
+
if (plan.toRetire.length > 0) {
|
|
95
|
+
lines.push("");
|
|
96
|
+
lines.push("Retired:");
|
|
97
|
+
lines.push(formatDomainLines(plan.toRetire));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
lines.push("AgentBridge checked recovery.");
|
|
102
|
+
lines.push("No changes needed.");
|
|
103
|
+
lines.push("Recovery is up to date.");
|
|
104
|
+
lines.push(`Recovery quality: ${qualityAfter}`);
|
|
105
|
+
}
|
|
106
|
+
return lines.join("\n") + "\n";
|
|
107
|
+
}
|
|
108
|
+
function renderBasicHint() {
|
|
109
|
+
return [
|
|
110
|
+
"",
|
|
111
|
+
"Recovery: basic",
|
|
112
|
+
"AgentBridge found only a generic project area.",
|
|
113
|
+
"Run `agentbridge recover --force` to rebuild the domain map.",
|
|
114
|
+
"",
|
|
115
|
+
].join("\n");
|
|
70
116
|
}
|
|
71
117
|
function renderRecoveryStatusBlock(input) {
|
|
72
118
|
const lines = [];
|
|
@@ -100,7 +146,18 @@ function normalizeBootstrapError(error) {
|
|
|
100
146
|
return (0, errors_1.catalogCliError)("CONFIG_INCOMPLETE", {
|
|
101
147
|
what: `Recovery bootstrap payload was rejected by server validation${detailText}.`,
|
|
102
148
|
why: "The server cannot activate recovery until required bootstrap fields pass validation.",
|
|
103
|
-
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}`,
|
|
104
161
|
});
|
|
105
162
|
}
|
|
106
163
|
if (error instanceof Error) {
|
|
@@ -175,15 +232,42 @@ async function runRecover(options = {}) {
|
|
|
175
232
|
return;
|
|
176
233
|
}
|
|
177
234
|
const beforePacket = packet;
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
235
|
+
const cfg = (0, config_1.readConfig)();
|
|
236
|
+
const repoRoot = (0, node_process_1.cwd)();
|
|
237
|
+
const rulesOk = rulesInstalled(repoRoot);
|
|
238
|
+
let scan;
|
|
239
|
+
try {
|
|
240
|
+
process.stdout.write("Scanning repository layout...\n");
|
|
241
|
+
scan = await (0, init_1.scanRecoveryFromRepo)(ctx);
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
process.stderr.write(`${(0, errors_1.renderCliError)(normalizeBootstrapError(error))}\n`);
|
|
245
|
+
process.exitCode = 1;
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const existingActive = (0, recovery_reconcile_1.packetDomainsToRefs)(beforePacket, cfg.domains ?? []);
|
|
249
|
+
const plan = (0, recovery_reconcile_1.buildReconcilePlan)({
|
|
250
|
+
existingActive,
|
|
251
|
+
candidates: scan.candidateRefs,
|
|
252
|
+
mode: options.force ? "force" : "safe",
|
|
253
|
+
packet: beforePacket,
|
|
254
|
+
rulesInstalled: rulesOk,
|
|
255
|
+
});
|
|
256
|
+
const needsBaseline = (0, recovery_reconcile_1.recoveryBaselineRequired)(beforePacket);
|
|
257
|
+
const shouldApply = needsBaseline || options.force || plan.hasChanges;
|
|
258
|
+
let actionTaken = "reconciliation check only; no changes needed";
|
|
259
|
+
if (shouldApply) {
|
|
260
|
+
actionTaken = needsBaseline
|
|
182
261
|
? "build recovery baseline from repository evidence"
|
|
183
|
-
:
|
|
184
|
-
|
|
262
|
+
: options.force
|
|
263
|
+
? "force-refresh recovery baseline from repository evidence"
|
|
264
|
+
: "reconcile recovery with repository evidence";
|
|
265
|
+
process.stdout.write("Applying recovery changes...\n");
|
|
185
266
|
try {
|
|
186
|
-
await (0, init_1.runBootstrapRecovery)(ctx
|
|
267
|
+
await (0, init_1.runBootstrapRecovery)(ctx, {
|
|
268
|
+
reconcilePlan: plan,
|
|
269
|
+
scan,
|
|
270
|
+
});
|
|
187
271
|
packet = await (0, server_sync_1.fetchProjectPacket)(ctx);
|
|
188
272
|
}
|
|
189
273
|
catch (error) {
|
|
@@ -193,7 +277,19 @@ async function runRecover(options = {}) {
|
|
|
193
277
|
}
|
|
194
278
|
}
|
|
195
279
|
const afterPacket = packet;
|
|
196
|
-
|
|
280
|
+
const qualityAfter = (0, recovery_reconcile_1.recoveryQualityLabel)((0, recovery_reconcile_1.buildReconcilePlan)({
|
|
281
|
+
existingActive: (0, recovery_reconcile_1.packetDomainsToRefs)(afterPacket, cfg.domains ?? []),
|
|
282
|
+
candidates: scan.candidateRefs,
|
|
283
|
+
mode: options.force ? "force" : "safe",
|
|
284
|
+
packet: afterPacket,
|
|
285
|
+
rulesInstalled: rulesOk,
|
|
286
|
+
}).quality);
|
|
287
|
+
process.stdout.write(renderReconcileReport({
|
|
288
|
+
plan,
|
|
289
|
+
applied: shouldApply,
|
|
290
|
+
qualityAfter,
|
|
291
|
+
}));
|
|
292
|
+
if ((0, recovery_reconcile_1.recoveryBaselineRequired)(afterPacket)) {
|
|
197
293
|
process.stderr.write([
|
|
198
294
|
"Recovery could not complete: baseline still required.",
|
|
199
295
|
"",
|
|
@@ -208,7 +304,6 @@ async function runRecover(options = {}) {
|
|
|
208
304
|
process.exitCode = 1;
|
|
209
305
|
return;
|
|
210
306
|
}
|
|
211
|
-
const repoRoot = (0, node_process_1.cwd)();
|
|
212
307
|
(0, gates_1.ensureGitignoreSessionEntry)(repoRoot);
|
|
213
308
|
(0, gates_1.ensureGatesFile)(repoRoot);
|
|
214
309
|
process.stdout.write(renderRecoveryStatusBlock({
|
|
@@ -216,7 +311,10 @@ async function runRecover(options = {}) {
|
|
|
216
311
|
before: beforePacket,
|
|
217
312
|
after: afterPacket,
|
|
218
313
|
action: actionTaken,
|
|
219
|
-
next: "agentbridge
|
|
314
|
+
next: "agentbridge watch",
|
|
220
315
|
}));
|
|
221
|
-
process.stdout.write(renderRecoverOutput(
|
|
316
|
+
process.stdout.write(renderRecoverOutput(afterPacket));
|
|
317
|
+
if ((0, recovery_reconcile_1.recoveryIsBasicPacket)(afterPacket)) {
|
|
318
|
+
process.stdout.write(renderBasicHint());
|
|
319
|
+
}
|
|
222
320
|
}
|
|
@@ -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
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.runSetupMcp = runSetupMcp;
|
|
4
|
+
const node_path_1 = require("node:path");
|
|
4
5
|
const config_1 = require("../config");
|
|
6
|
+
const mcp_runtime_1 = require("../mcp-runtime");
|
|
5
7
|
const MCP_SERVER_NAME = "agentbridge";
|
|
6
8
|
function standardSnippet(projectId, apiKey, apiBaseUrl) {
|
|
7
9
|
const serverConfig = {
|
|
@@ -47,8 +49,27 @@ async function runSetupMcp(options = {}) {
|
|
|
47
49
|
else {
|
|
48
50
|
process.stdout.write("\n✓ Credentials filled from .agentbridge/config.json\n");
|
|
49
51
|
}
|
|
52
|
+
const cliDistDir = (0, node_path_1.resolve)(__dirname, "..");
|
|
53
|
+
if (!(0, mcp_runtime_1.isMcpRuntimeAvailable)(cliDistDir)) {
|
|
54
|
+
process.stdout.write([
|
|
55
|
+
"",
|
|
56
|
+
"⚠ MCP runtime is missing from this CLI install.",
|
|
57
|
+
" `agentbridge mcp` will exit until you reinstall:",
|
|
58
|
+
" npm install -g @agentbridge1/cli@latest",
|
|
59
|
+
"",
|
|
60
|
+
" Or point mcp.json at a repo build:",
|
|
61
|
+
" node /path/to/AuthAgent/cli/dist/mcp/agentbridge-mcp.js",
|
|
62
|
+
"",
|
|
63
|
+
].join("\n"));
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
process.stdout.write([
|
|
67
|
+
"",
|
|
68
|
+
"✓ MCP runtime is bundled with this CLI (`agentbridge mcp` is ready).",
|
|
69
|
+
"",
|
|
70
|
+
].join("\n"));
|
|
71
|
+
}
|
|
50
72
|
process.stdout.write([
|
|
51
|
-
"",
|
|
52
73
|
"After saving the config, restart your editor to activate the MCP server.",
|
|
53
74
|
"The MCP server lets your AI assistant call tools like agent_hello, check AgentBridge status, and trigger approvals.",
|
|
54
75
|
"",
|
package/dist/commands/start.js
CHANGED
|
@@ -39,9 +39,8 @@ const domain_resolution_1 = require("../domain-resolution");
|
|
|
39
39
|
const errors_1 = require("../errors");
|
|
40
40
|
const error_catalog_1 = require("../error-catalog");
|
|
41
41
|
const http_1 = require("../http");
|
|
42
|
-
const git_status_1 = require("../git-status");
|
|
43
42
|
const session_1 = require("../session");
|
|
44
|
-
const
|
|
43
|
+
const session_state_1 = require("../session-state");
|
|
45
44
|
const server_sync_1 = require("../server-sync");
|
|
46
45
|
const work_context_resolver_1 = require("../work-context-resolver");
|
|
47
46
|
const PROMOTION_PLAN = {
|
|
@@ -567,84 +566,55 @@ async function executeStartWorkSession(opts) {
|
|
|
567
566
|
otherSessionIds: [...new Set(otherSessionIds)],
|
|
568
567
|
};
|
|
569
568
|
}
|
|
570
|
-
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
if (!
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
const resolution = await (0, work_context_resolver_1.resolveWorkContext)(ctx, {
|
|
584
|
-
allowServerCurrentForCr: true,
|
|
585
|
-
includeOtherActiveSessions: true,
|
|
586
|
-
});
|
|
587
|
-
if (resolution.state === "current_session_resolved") {
|
|
588
|
-
process.stdout.write("Active work session found - entering watch mode.\n");
|
|
589
|
-
if (!opts.skipWatch) {
|
|
590
|
-
const { runWatch } = await Promise.resolve().then(() => __importStar(require("./watch")));
|
|
591
|
-
await runWatch({ allowDirty: true });
|
|
592
|
-
}
|
|
593
|
-
return;
|
|
594
|
-
}
|
|
595
|
-
if (resolution.state === "ambiguous_active_sessions") {
|
|
596
|
-
process.stdout.write(`${(0, work_context_resolver_1.renderWorkContextLines)(resolution).join("\n")}\n`);
|
|
597
|
-
throw (0, errors_1.catalogCliError)((0, error_catalog_1.workContextStateToCode)(resolution.state));
|
|
598
|
-
}
|
|
599
|
-
if (resolution.state === "mismatch" || resolution.state === "stale_orphan_session_detected") {
|
|
600
|
-
process.stdout.write(`${(0, work_context_resolver_1.renderWorkContextLines)(resolution).join("\n")}\n`);
|
|
601
|
-
throw (0, errors_1.catalogCliError)((0, error_catalog_1.workContextStateToCode)(resolution.state));
|
|
602
|
-
}
|
|
603
|
-
const inferred = (0, work_contract_1.inferWorkContract)({
|
|
569
|
+
function hasActiveLocalRun() {
|
|
570
|
+
const local = (0, session_state_1.readSessionState)();
|
|
571
|
+
if (!local)
|
|
572
|
+
return false;
|
|
573
|
+
if (local.status !== "active" && local.status !== "blocked")
|
|
574
|
+
return false;
|
|
575
|
+
if (!local.id || local.id === "none")
|
|
576
|
+
return false;
|
|
577
|
+
return true;
|
|
578
|
+
}
|
|
579
|
+
async function runDefaultStart(opts = {}) {
|
|
580
|
+
const { runLocalSupervision } = await Promise.resolve().then(() => __importStar(require("../local-supervision")));
|
|
581
|
+
await runLocalSupervision({
|
|
604
582
|
prompt: opts.prompt,
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
activeChangeRequestId: cfg.activeChangeRequestId ?? null,
|
|
608
|
-
});
|
|
609
|
-
const draft = {
|
|
610
|
-
summary: inferred.summary,
|
|
611
|
-
scope: opts.scope?.trim() || inferred.scope,
|
|
612
|
-
};
|
|
613
|
-
const confirmed = await (0, work_contract_1.confirmWorkContract)(draft, {
|
|
614
|
-
nonInteractive: !process.stdin.isTTY,
|
|
615
|
-
});
|
|
616
|
-
if (!confirmed) {
|
|
617
|
-
process.stdout.write("Cancelled.\n");
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
620
|
-
await executeStartWorkSession({
|
|
621
|
-
...opts,
|
|
622
|
-
summary: confirmed.summary,
|
|
623
|
-
scope: confirmed.scope,
|
|
583
|
+
details: opts.details,
|
|
584
|
+
confirmClose: opts.confirmClose,
|
|
624
585
|
});
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
586
|
+
}
|
|
587
|
+
function isStrictTrackedStartRequest(opts) {
|
|
588
|
+
if (opts.resume === true)
|
|
589
|
+
return true;
|
|
590
|
+
if (opts.changeRequestId?.trim())
|
|
591
|
+
return true;
|
|
592
|
+
const explicitSummaryFlag = opts.summaryFlagProvided === true;
|
|
593
|
+
const explicitScopeFlag = opts.scopeFlagProvided === true;
|
|
594
|
+
const explicitInputProvided = opts.summary !== undefined || opts.scope !== undefined;
|
|
595
|
+
return explicitSummaryFlag || explicitScopeFlag || explicitInputProvided;
|
|
630
596
|
}
|
|
631
597
|
async function runStart(opts = {}) {
|
|
598
|
+
const strictTrackedStart = isStrictTrackedStartRequest(opts);
|
|
632
599
|
const explicitSummaryFlag = opts.summaryFlagProvided === true;
|
|
633
600
|
const explicitScopeFlag = opts.scopeFlagProvided === true;
|
|
634
601
|
const explicitInputProvided = opts.summary !== undefined || opts.scope !== undefined;
|
|
635
602
|
const explicitModeRequested = explicitSummaryFlag || explicitScopeFlag || explicitInputProvided;
|
|
636
603
|
const explicitSummary = opts.summary?.trim();
|
|
637
604
|
const explicitScope = opts.scope?.trim();
|
|
638
|
-
if (
|
|
605
|
+
if (strictTrackedStart && explicitSummary && explicitScope) {
|
|
639
606
|
await executeStartWorkSession({ ...opts, summary: explicitSummary, scope: explicitScope });
|
|
640
607
|
if (!opts.skipWatch) {
|
|
641
608
|
const { runWatch } = await Promise.resolve().then(() => __importStar(require("./watch")));
|
|
642
|
-
await runWatch({ allowDirty: true });
|
|
609
|
+
await runWatch({ allowDirty: true, details: opts.details });
|
|
643
610
|
}
|
|
644
611
|
return;
|
|
645
612
|
}
|
|
613
|
+
if (strictTrackedStart) {
|
|
614
|
+
throw (0, errors_1.catalogCliError)("START_EXPLICIT_PAIR_REQUIRED");
|
|
615
|
+
}
|
|
646
616
|
if (explicitModeRequested) {
|
|
647
617
|
throw (0, errors_1.catalogCliError)("START_EXPLICIT_PAIR_REQUIRED");
|
|
648
618
|
}
|
|
649
|
-
await
|
|
619
|
+
await runDefaultStart(opts);
|
|
650
620
|
}
|