@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/commands/recover.js
CHANGED
|
@@ -1,12 +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");
|
|
10
|
+
const http_1 = require("../http");
|
|
9
11
|
const init_1 = require("../init");
|
|
12
|
+
const recovery_reconcile_1 = require("../recovery-reconcile");
|
|
13
|
+
const server_sync_1 = require("../server-sync");
|
|
10
14
|
function resolveNetworkContext() {
|
|
11
15
|
const cfg = (0, config_1.readConfig)();
|
|
12
16
|
const projectId = process.env.AGENTBRIDGE_PROJECT_ID ?? cfg.projectId ?? "";
|
|
@@ -19,9 +23,14 @@ function resolveNetworkContext() {
|
|
|
19
23
|
}
|
|
20
24
|
return { projectId, apiKey, apiBaseUrl };
|
|
21
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
|
+
}
|
|
22
30
|
function renderRecoverOutput(packet) {
|
|
23
31
|
const lines = [];
|
|
24
|
-
const
|
|
32
|
+
const activeDomains = (packet.domains_summary ?? []).filter((d) => d.state !== "retired");
|
|
33
|
+
const domainCount = activeDomains.length;
|
|
25
34
|
const ruleCount = packet.global_rules?.length ?? 0;
|
|
26
35
|
const hasCharterContext = Boolean(packet.charter_summary?.purpose);
|
|
27
36
|
lines.push("Project recovered.");
|
|
@@ -35,7 +44,7 @@ function renderRecoverOutput(packet) {
|
|
|
35
44
|
if (domainCount > 0) {
|
|
36
45
|
lines.push("");
|
|
37
46
|
lines.push("Domains found:");
|
|
38
|
-
for (const domain of
|
|
47
|
+
for (const domain of activeDomains) {
|
|
39
48
|
const pathNote = domain.owned_path_count > 0 ? `${domain.owned_path_count} path(s)` : "paths pending";
|
|
40
49
|
lines.push(`- ${domain.domain_name} — ${pathNote}`);
|
|
41
50
|
}
|
|
@@ -54,18 +63,56 @@ function renderRecoverOutput(packet) {
|
|
|
54
63
|
}
|
|
55
64
|
lines.push("");
|
|
56
65
|
lines.push("Next:");
|
|
57
|
-
lines.push(" agentbridge
|
|
66
|
+
lines.push(" agentbridge watch");
|
|
58
67
|
lines.push("");
|
|
59
68
|
return lines.join("\n");
|
|
60
69
|
}
|
|
61
70
|
function recoveryStatusLabel(packet) {
|
|
62
71
|
return packet.recovery_status ?? "unknown";
|
|
63
72
|
}
|
|
64
|
-
function
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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 `agent recover --force` to rebuild the domain map.",
|
|
114
|
+
"",
|
|
115
|
+
].join("\n");
|
|
69
116
|
}
|
|
70
117
|
function renderRecoveryStatusBlock(input) {
|
|
71
118
|
const lines = [];
|
|
@@ -78,6 +125,60 @@ function renderRecoveryStatusBlock(input) {
|
|
|
78
125
|
lines.push("");
|
|
79
126
|
return lines.join("\n");
|
|
80
127
|
}
|
|
128
|
+
function normalizeBootstrapError(error) {
|
|
129
|
+
if ((0, http_1.isCliHttpError)(error) && error.status === 422) {
|
|
130
|
+
const parsed = (0, http_1.parseCliHttpErrorBody)(error);
|
|
131
|
+
const details = [];
|
|
132
|
+
const nestedError = parsed && typeof parsed.error === "object" && parsed.error !== null
|
|
133
|
+
? parsed.error
|
|
134
|
+
: null;
|
|
135
|
+
const fieldErrors = nestedError && typeof nestedError.fieldErrors === "object" && nestedError.fieldErrors !== null
|
|
136
|
+
? nestedError.fieldErrors
|
|
137
|
+
: null;
|
|
138
|
+
if (fieldErrors) {
|
|
139
|
+
for (const [field, value] of Object.entries(fieldErrors)) {
|
|
140
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
141
|
+
details.push(`${field}: ${String(value[0])}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const detailText = details.length > 0 ? ` (${details.join("; ")})` : "";
|
|
146
|
+
return (0, errors_1.catalogCliError)("CONFIG_INCOMPLETE", {
|
|
147
|
+
what: `Recovery bootstrap payload was rejected by server validation${detailText}.`,
|
|
148
|
+
why: "The server cannot activate recovery until required bootstrap fields pass validation.",
|
|
149
|
+
next: "Retry `agentbridge recover`. If it fails again, run with AGENTBRIDGE_DEBUG=1 and share output.",
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (error instanceof Error) {
|
|
153
|
+
const message = error.message;
|
|
154
|
+
if (/does not have any commits yet/i.test(message) ||
|
|
155
|
+
/bad revision ['"]head['"]/i.test(message) ||
|
|
156
|
+
/not a git repository/i.test(message)) {
|
|
157
|
+
return new errors_1.SafeCliError({
|
|
158
|
+
code: "CONFIG_INCOMPLETE",
|
|
159
|
+
category: "CONFIG_ERROR",
|
|
160
|
+
what: "Repository has no usable git history for recovery mapping.",
|
|
161
|
+
why: "Recover infers baseline context from commit history and cannot proceed without it.",
|
|
162
|
+
next: [
|
|
163
|
+
"Create an initial commit, then rerun recover:",
|
|
164
|
+
"1) git add .",
|
|
165
|
+
"2) git commit -m \"Initial commit\"",
|
|
166
|
+
"3) agentbridge recover",
|
|
167
|
+
].join("\n"),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
if (/payload too large after compaction/i.test(message)) {
|
|
171
|
+
return new errors_1.SafeCliError({
|
|
172
|
+
code: "CONFIG_INCOMPLETE",
|
|
173
|
+
category: "CONFIG_ERROR",
|
|
174
|
+
what: "Repository evidence exceeded bootstrap payload limits.",
|
|
175
|
+
why: "The recovery evidence payload could not be compacted enough for server ingestion.",
|
|
176
|
+
next: "Run `agentbridge init` for an interactive baseline, or retry recover after reducing repository noise.",
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return error;
|
|
181
|
+
}
|
|
81
182
|
async function runRecover(options = {}) {
|
|
82
183
|
process.exitCode = 0;
|
|
83
184
|
process.stdout.write([
|
|
@@ -120,18 +221,64 @@ async function runRecover(options = {}) {
|
|
|
120
221
|
return;
|
|
121
222
|
}
|
|
122
223
|
const beforePacket = packet;
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
224
|
+
const cfg = (0, config_1.readConfig)();
|
|
225
|
+
const repoRoot = (0, node_process_1.cwd)();
|
|
226
|
+
const rulesOk = rulesInstalled(repoRoot);
|
|
227
|
+
let scan;
|
|
228
|
+
try {
|
|
229
|
+
process.stdout.write("Scanning repository layout...\n");
|
|
230
|
+
scan = await (0, init_1.scanRecoveryFromRepo)(ctx);
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
process.stderr.write(`${(0, errors_1.renderCliError)(normalizeBootstrapError(error))}\n`);
|
|
234
|
+
process.exitCode = 1;
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const existingActive = (0, recovery_reconcile_1.packetDomainsToRefs)(beforePacket, cfg.domains ?? []);
|
|
238
|
+
const plan = (0, recovery_reconcile_1.buildReconcilePlan)({
|
|
239
|
+
existingActive,
|
|
240
|
+
candidates: scan.candidateRefs,
|
|
241
|
+
mode: options.force ? "force" : "safe",
|
|
242
|
+
packet: beforePacket,
|
|
243
|
+
rulesInstalled: rulesOk,
|
|
244
|
+
});
|
|
245
|
+
const needsBaseline = (0, recovery_reconcile_1.recoveryBaselineRequired)(beforePacket);
|
|
246
|
+
const shouldApply = needsBaseline || options.force || plan.hasChanges;
|
|
247
|
+
let actionTaken = "reconciliation check only; no changes needed";
|
|
248
|
+
if (shouldApply) {
|
|
249
|
+
actionTaken = needsBaseline
|
|
127
250
|
? "build recovery baseline from repository evidence"
|
|
128
|
-
:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
251
|
+
: options.force
|
|
252
|
+
? "force-refresh recovery baseline from repository evidence"
|
|
253
|
+
: "reconcile recovery with repository evidence";
|
|
254
|
+
process.stdout.write("Applying recovery changes...\n");
|
|
255
|
+
try {
|
|
256
|
+
await (0, init_1.runBootstrapRecovery)(ctx, {
|
|
257
|
+
reconcilePlan: plan,
|
|
258
|
+
scan,
|
|
259
|
+
});
|
|
260
|
+
packet = await (0, server_sync_1.fetchProjectPacket)(ctx);
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
process.stderr.write(`${(0, errors_1.renderCliError)(normalizeBootstrapError(error))}\n`);
|
|
264
|
+
process.exitCode = 1;
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
132
267
|
}
|
|
133
268
|
const afterPacket = packet;
|
|
134
|
-
|
|
269
|
+
const qualityAfter = (0, recovery_reconcile_1.recoveryQualityLabel)((0, recovery_reconcile_1.buildReconcilePlan)({
|
|
270
|
+
existingActive: (0, recovery_reconcile_1.packetDomainsToRefs)(afterPacket, cfg.domains ?? []),
|
|
271
|
+
candidates: scan.candidateRefs,
|
|
272
|
+
mode: options.force ? "force" : "safe",
|
|
273
|
+
packet: afterPacket,
|
|
274
|
+
rulesInstalled: rulesOk,
|
|
275
|
+
}).quality);
|
|
276
|
+
process.stdout.write(renderReconcileReport({
|
|
277
|
+
plan,
|
|
278
|
+
applied: shouldApply,
|
|
279
|
+
qualityAfter,
|
|
280
|
+
}));
|
|
281
|
+
if ((0, recovery_reconcile_1.recoveryBaselineRequired)(afterPacket)) {
|
|
135
282
|
process.stderr.write([
|
|
136
283
|
"Recovery could not complete: baseline still required.",
|
|
137
284
|
"",
|
|
@@ -146,7 +293,6 @@ async function runRecover(options = {}) {
|
|
|
146
293
|
process.exitCode = 1;
|
|
147
294
|
return;
|
|
148
295
|
}
|
|
149
|
-
const repoRoot = (0, node_process_1.cwd)();
|
|
150
296
|
(0, gates_1.ensureGitignoreSessionEntry)(repoRoot);
|
|
151
297
|
(0, gates_1.ensureGatesFile)(repoRoot);
|
|
152
298
|
process.stdout.write(renderRecoveryStatusBlock({
|
|
@@ -154,7 +300,10 @@ async function runRecover(options = {}) {
|
|
|
154
300
|
before: beforePacket,
|
|
155
301
|
after: afterPacket,
|
|
156
302
|
action: actionTaken,
|
|
157
|
-
next: "agentbridge
|
|
303
|
+
next: "agentbridge watch",
|
|
158
304
|
}));
|
|
159
|
-
process.stdout.write(renderRecoverOutput(
|
|
305
|
+
process.stdout.write(renderRecoverOutput(afterPacket));
|
|
306
|
+
if ((0, recovery_reconcile_1.recoveryIsBasicPacket)(afterPacket)) {
|
|
307
|
+
process.stdout.write(renderBasicHint());
|
|
308
|
+
}
|
|
160
309
|
}
|
|
@@ -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 = {
|
|
@@ -395,6 +394,29 @@ function renderOtherSessions(lines, sessionIds) {
|
|
|
395
394
|
...sessionIds.map((id) => `- ${id}`),
|
|
396
395
|
];
|
|
397
396
|
}
|
|
397
|
+
async function resolveExecutionSurfaceIdForStart(ctx, opts, cfgExecutionSurfaceId) {
|
|
398
|
+
const explicitExecutionSurfaceId = opts.executionSurfaceId?.trim();
|
|
399
|
+
if (explicitExecutionSurfaceId) {
|
|
400
|
+
(0, config_1.updateConfig)({ executionSurfaceId: explicitExecutionSurfaceId });
|
|
401
|
+
return explicitExecutionSurfaceId;
|
|
402
|
+
}
|
|
403
|
+
const configuredExecutionSurfaceId = cfgExecutionSurfaceId?.trim();
|
|
404
|
+
if (configuredExecutionSurfaceId) {
|
|
405
|
+
return configuredExecutionSurfaceId;
|
|
406
|
+
}
|
|
407
|
+
try {
|
|
408
|
+
const callerPacket = await (0, server_sync_1.fetchCallerIdentityPacket)(ctx);
|
|
409
|
+
const discoveredExecutionSurfaceId = callerPacket?.execution_surface?.id?.trim() || null;
|
|
410
|
+
if (discoveredExecutionSurfaceId) {
|
|
411
|
+
(0, config_1.updateConfig)({ executionSurfaceId: discoveredExecutionSurfaceId });
|
|
412
|
+
return discoveredExecutionSurfaceId;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
catch {
|
|
416
|
+
// Keep the existing catalog error path if caller identity discovery fails.
|
|
417
|
+
}
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
398
420
|
async function executeStartWorkSession(opts) {
|
|
399
421
|
const summary = trimRequired(opts.summary ?? "", "--summary");
|
|
400
422
|
const scope = trimRequired(opts.scope ?? "", "--scope");
|
|
@@ -406,7 +428,7 @@ async function executeStartWorkSession(opts) {
|
|
|
406
428
|
if (!explicitAgentId && !configuredActiveAgentId) {
|
|
407
429
|
throw (0, errors_1.catalogCliError)("START_MISSING_ACTIVE_AGENT");
|
|
408
430
|
}
|
|
409
|
-
const executionSurfaceId = cfg.executionSurfaceId
|
|
431
|
+
const executionSurfaceId = await resolveExecutionSurfaceIdForStart(ctx, opts, cfg.executionSurfaceId);
|
|
410
432
|
if (!executionSurfaceId) {
|
|
411
433
|
throw (0, errors_1.catalogCliError)("START_EXECUTION_SURFACE_REQUIRED");
|
|
412
434
|
}
|
|
@@ -544,83 +566,55 @@ async function executeStartWorkSession(opts) {
|
|
|
544
566
|
otherSessionIds: [...new Set(otherSessionIds)],
|
|
545
567
|
};
|
|
546
568
|
}
|
|
547
|
-
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
const
|
|
559
|
-
|
|
560
|
-
allowServerCurrentForCr: true,
|
|
561
|
-
includeOtherActiveSessions: true,
|
|
562
|
-
});
|
|
563
|
-
if (resolution.state === "current_session_resolved") {
|
|
564
|
-
process.stdout.write("Active work session found - entering watch mode.\n");
|
|
565
|
-
if (!opts.skipWatch) {
|
|
566
|
-
const { runWatch } = await Promise.resolve().then(() => __importStar(require("./watch")));
|
|
567
|
-
await runWatch({ allowDirty: true });
|
|
568
|
-
}
|
|
569
|
-
return;
|
|
570
|
-
}
|
|
571
|
-
if (resolution.state === "ambiguous_active_sessions") {
|
|
572
|
-
process.stdout.write(`${(0, work_context_resolver_1.renderWorkContextLines)(resolution).join("\n")}\n`);
|
|
573
|
-
throw (0, errors_1.catalogCliError)((0, error_catalog_1.workContextStateToCode)(resolution.state));
|
|
574
|
-
}
|
|
575
|
-
if (resolution.state === "mismatch" || resolution.state === "stale_orphan_session_detected") {
|
|
576
|
-
process.stdout.write(`${(0, work_context_resolver_1.renderWorkContextLines)(resolution).join("\n")}\n`);
|
|
577
|
-
throw (0, errors_1.catalogCliError)((0, error_catalog_1.workContextStateToCode)(resolution.state));
|
|
578
|
-
}
|
|
579
|
-
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({
|
|
580
582
|
prompt: opts.prompt,
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
activeChangeRequestId: cfg.activeChangeRequestId ?? null,
|
|
584
|
-
});
|
|
585
|
-
const draft = {
|
|
586
|
-
summary: inferred.summary,
|
|
587
|
-
scope: opts.scope?.trim() || inferred.scope,
|
|
588
|
-
};
|
|
589
|
-
const confirmed = await (0, work_contract_1.confirmWorkContract)(draft, {
|
|
590
|
-
nonInteractive: !process.stdin.isTTY,
|
|
591
|
-
});
|
|
592
|
-
if (!confirmed) {
|
|
593
|
-
process.stdout.write("Cancelled.\n");
|
|
594
|
-
return;
|
|
595
|
-
}
|
|
596
|
-
await executeStartWorkSession({
|
|
597
|
-
...opts,
|
|
598
|
-
summary: confirmed.summary,
|
|
599
|
-
scope: confirmed.scope,
|
|
583
|
+
details: opts.details,
|
|
584
|
+
confirmClose: opts.confirmClose,
|
|
600
585
|
});
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
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;
|
|
606
596
|
}
|
|
607
597
|
async function runStart(opts = {}) {
|
|
598
|
+
const strictTrackedStart = isStrictTrackedStartRequest(opts);
|
|
608
599
|
const explicitSummaryFlag = opts.summaryFlagProvided === true;
|
|
609
600
|
const explicitScopeFlag = opts.scopeFlagProvided === true;
|
|
610
601
|
const explicitInputProvided = opts.summary !== undefined || opts.scope !== undefined;
|
|
611
602
|
const explicitModeRequested = explicitSummaryFlag || explicitScopeFlag || explicitInputProvided;
|
|
612
603
|
const explicitSummary = opts.summary?.trim();
|
|
613
604
|
const explicitScope = opts.scope?.trim();
|
|
614
|
-
if (
|
|
605
|
+
if (strictTrackedStart && explicitSummary && explicitScope) {
|
|
615
606
|
await executeStartWorkSession({ ...opts, summary: explicitSummary, scope: explicitScope });
|
|
616
607
|
if (!opts.skipWatch) {
|
|
617
608
|
const { runWatch } = await Promise.resolve().then(() => __importStar(require("./watch")));
|
|
618
|
-
await runWatch({ allowDirty: true });
|
|
609
|
+
await runWatch({ allowDirty: true, details: opts.details });
|
|
619
610
|
}
|
|
620
611
|
return;
|
|
621
612
|
}
|
|
613
|
+
if (strictTrackedStart) {
|
|
614
|
+
throw (0, errors_1.catalogCliError)("START_EXPLICIT_PAIR_REQUIRED");
|
|
615
|
+
}
|
|
622
616
|
if (explicitModeRequested) {
|
|
623
617
|
throw (0, errors_1.catalogCliError)("START_EXPLICIT_PAIR_REQUIRED");
|
|
624
618
|
}
|
|
625
|
-
await
|
|
619
|
+
await runDefaultStart(opts);
|
|
626
620
|
}
|