@locusai/sdk 0.10.2 → 0.10.5
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/agent/git-workflow.d.ts +2 -1
- package/dist/agent/git-workflow.d.ts.map +1 -1
- package/dist/agent/task-executor.d.ts +5 -0
- package/dist/agent/task-executor.d.ts.map +1 -1
- package/dist/agent/worker.d.ts.map +1 -1
- package/dist/agent/worker.js +205 -30
- package/dist/ai/claude-runner.d.ts +3 -1
- package/dist/ai/claude-runner.d.ts.map +1 -1
- package/dist/ai/codex-runner.d.ts +8 -1
- package/dist/ai/codex-runner.d.ts.map +1 -1
- package/dist/ai/factory.d.ts +2 -0
- package/dist/ai/factory.d.ts.map +1 -1
- package/dist/ai/runner.d.ts +5 -0
- package/dist/ai/runner.d.ts.map +1 -1
- package/dist/index-node.js +245 -41
- package/dist/orchestrator/tier-merge.d.ts.map +1 -1
- package/dist/planning/agents/architect.d.ts.map +1 -1
- package/dist/planning/agents/cross-task-reviewer.d.ts.map +1 -1
- package/dist/planning/agents/sprint-organizer.d.ts.map +1 -1
- package/dist/planning/agents/tech-lead.d.ts.map +1 -1
- package/dist/worktree/worktree-config.d.ts +2 -0
- package/dist/worktree/worktree-config.d.ts.map +1 -1
- package/dist/worktree/worktree-manager.d.ts +10 -1
- package/dist/worktree/worktree-manager.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index-node.js
CHANGED
|
@@ -768,10 +768,12 @@ class ClaudeRunner {
|
|
|
768
768
|
currentToolName;
|
|
769
769
|
activeTools = new Map;
|
|
770
770
|
activeProcess = null;
|
|
771
|
-
|
|
771
|
+
timeoutMs;
|
|
772
|
+
constructor(projectPath, model = DEFAULT_MODEL[PROVIDER.CLAUDE], log, timeoutMs) {
|
|
772
773
|
this.model = model;
|
|
773
774
|
this.log = log;
|
|
774
775
|
this.projectPath = import_node_path3.resolve(projectPath);
|
|
776
|
+
this.timeoutMs = timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
775
777
|
}
|
|
776
778
|
setEventEmitter(emitter) {
|
|
777
779
|
this.eventEmitter = emitter;
|
|
@@ -787,11 +789,14 @@ class ClaudeRunner {
|
|
|
787
789
|
let lastError = null;
|
|
788
790
|
for (let attempt = 1;attempt <= maxRetries; attempt++) {
|
|
789
791
|
try {
|
|
790
|
-
return await this.executeRun(prompt);
|
|
792
|
+
return await this.withTimeout(this.executeRun(prompt));
|
|
791
793
|
} catch (error) {
|
|
792
794
|
const err = error;
|
|
793
795
|
lastError = err;
|
|
794
796
|
const isLastAttempt = attempt === maxRetries;
|
|
797
|
+
if (err.message.includes("timed out")) {
|
|
798
|
+
throw err;
|
|
799
|
+
}
|
|
795
800
|
if (!isLastAttempt) {
|
|
796
801
|
const delay = Math.pow(2, attempt) * 1000;
|
|
797
802
|
console.warn(`Claude CLI attempt ${attempt} failed: ${err.message}. Retrying in ${delay}ms...`);
|
|
@@ -801,6 +806,23 @@ class ClaudeRunner {
|
|
|
801
806
|
}
|
|
802
807
|
throw lastError || new Error("Claude CLI failed after multiple attempts");
|
|
803
808
|
}
|
|
809
|
+
withTimeout(promise) {
|
|
810
|
+
if (this.timeoutMs <= 0)
|
|
811
|
+
return promise;
|
|
812
|
+
return new Promise((resolve2, reject) => {
|
|
813
|
+
const timer = setTimeout(() => {
|
|
814
|
+
this.abort();
|
|
815
|
+
reject(new Error(`Claude CLI execution timed out after ${Math.round(this.timeoutMs / 60000)} minutes`));
|
|
816
|
+
}, this.timeoutMs);
|
|
817
|
+
promise.then((value) => {
|
|
818
|
+
clearTimeout(timer);
|
|
819
|
+
resolve2(value);
|
|
820
|
+
}, (err) => {
|
|
821
|
+
clearTimeout(timer);
|
|
822
|
+
reject(err);
|
|
823
|
+
});
|
|
824
|
+
});
|
|
825
|
+
}
|
|
804
826
|
async* runStream(prompt) {
|
|
805
827
|
const args = [
|
|
806
828
|
"--dangerously-skip-permissions",
|
|
@@ -1165,7 +1187,7 @@ ${c.primary("[Claude]")} ${c.bold(`Running ${content_block.name}...`)}
|
|
|
1165
1187
|
return new Error(message);
|
|
1166
1188
|
}
|
|
1167
1189
|
}
|
|
1168
|
-
var import_node_child_process, import_node_path3, SANDBOX_SETTINGS;
|
|
1190
|
+
var import_node_child_process, import_node_path3, SANDBOX_SETTINGS, DEFAULT_TIMEOUT_MS;
|
|
1169
1191
|
var init_claude_runner = __esm(() => {
|
|
1170
1192
|
init_config();
|
|
1171
1193
|
init_colors();
|
|
@@ -1173,12 +1195,16 @@ var init_claude_runner = __esm(() => {
|
|
|
1173
1195
|
import_node_child_process = require("node:child_process");
|
|
1174
1196
|
import_node_path3 = require("node:path");
|
|
1175
1197
|
SANDBOX_SETTINGS = JSON.stringify({
|
|
1198
|
+
permissions: {
|
|
1199
|
+
deny: ["Read(../**)", "Edit(../**)"]
|
|
1200
|
+
},
|
|
1176
1201
|
sandbox: {
|
|
1177
1202
|
enabled: true,
|
|
1178
1203
|
autoAllow: true,
|
|
1179
1204
|
allowUnsandboxedCommands: false
|
|
1180
1205
|
}
|
|
1181
1206
|
});
|
|
1207
|
+
DEFAULT_TIMEOUT_MS = 60 * 60 * 1000;
|
|
1182
1208
|
});
|
|
1183
1209
|
|
|
1184
1210
|
// src/ai/codex-runner.ts
|
|
@@ -1187,10 +1213,17 @@ class CodexRunner {
|
|
|
1187
1213
|
model;
|
|
1188
1214
|
log;
|
|
1189
1215
|
activeProcess = null;
|
|
1190
|
-
|
|
1216
|
+
eventEmitter;
|
|
1217
|
+
currentToolName;
|
|
1218
|
+
timeoutMs;
|
|
1219
|
+
constructor(projectPath, model = DEFAULT_MODEL[PROVIDER.CODEX], log, timeoutMs) {
|
|
1191
1220
|
this.projectPath = projectPath;
|
|
1192
1221
|
this.model = model;
|
|
1193
1222
|
this.log = log;
|
|
1223
|
+
this.timeoutMs = timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
1224
|
+
}
|
|
1225
|
+
setEventEmitter(emitter) {
|
|
1226
|
+
this.eventEmitter = emitter;
|
|
1194
1227
|
}
|
|
1195
1228
|
abort() {
|
|
1196
1229
|
if (this.activeProcess && !this.activeProcess.killed) {
|
|
@@ -1203,9 +1236,12 @@ class CodexRunner {
|
|
|
1203
1236
|
let lastError = null;
|
|
1204
1237
|
for (let attempt = 1;attempt <= maxRetries; attempt++) {
|
|
1205
1238
|
try {
|
|
1206
|
-
return await this.executeRun(prompt);
|
|
1239
|
+
return await this.withTimeout(this.executeRun(prompt));
|
|
1207
1240
|
} catch (error) {
|
|
1208
1241
|
lastError = error;
|
|
1242
|
+
if (lastError.message.includes("timed out")) {
|
|
1243
|
+
throw lastError;
|
|
1244
|
+
}
|
|
1209
1245
|
if (attempt < maxRetries) {
|
|
1210
1246
|
const delay = Math.pow(2, attempt) * 1000;
|
|
1211
1247
|
console.warn(`Codex CLI attempt ${attempt} failed: ${lastError.message}. Retrying in ${delay}ms...`);
|
|
@@ -1215,9 +1251,31 @@ class CodexRunner {
|
|
|
1215
1251
|
}
|
|
1216
1252
|
throw lastError || new Error("Codex CLI failed after multiple attempts");
|
|
1217
1253
|
}
|
|
1254
|
+
withTimeout(promise) {
|
|
1255
|
+
if (this.timeoutMs <= 0)
|
|
1256
|
+
return promise;
|
|
1257
|
+
return new Promise((resolve2, reject) => {
|
|
1258
|
+
const timer = setTimeout(() => {
|
|
1259
|
+
this.abort();
|
|
1260
|
+
reject(new Error(`Codex CLI execution timed out after ${Math.round(this.timeoutMs / 60000)} minutes`));
|
|
1261
|
+
}, this.timeoutMs);
|
|
1262
|
+
promise.then((value) => {
|
|
1263
|
+
clearTimeout(timer);
|
|
1264
|
+
resolve2(value);
|
|
1265
|
+
}, (err) => {
|
|
1266
|
+
clearTimeout(timer);
|
|
1267
|
+
reject(err);
|
|
1268
|
+
});
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
1218
1271
|
async* runStream(prompt) {
|
|
1219
1272
|
const outputPath = import_node_path4.join(import_node_os2.tmpdir(), `locus-codex-${import_node_crypto.randomUUID()}.txt`);
|
|
1220
1273
|
const args = this.buildArgs(outputPath);
|
|
1274
|
+
this.eventEmitter?.emitSessionStarted({
|
|
1275
|
+
model: this.model,
|
|
1276
|
+
provider: "codex"
|
|
1277
|
+
});
|
|
1278
|
+
this.eventEmitter?.emitPromptSubmitted(prompt, prompt.length > 500);
|
|
1221
1279
|
const codex = import_node_child_process2.spawn("codex", args, {
|
|
1222
1280
|
cwd: this.projectPath,
|
|
1223
1281
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -1230,7 +1288,21 @@ class CodexRunner {
|
|
|
1230
1288
|
let processEnded = false;
|
|
1231
1289
|
let errorMessage = "";
|
|
1232
1290
|
let finalOutput = "";
|
|
1291
|
+
let finalContent = "";
|
|
1292
|
+
let isThinking = false;
|
|
1233
1293
|
const enqueueChunk = (chunk) => {
|
|
1294
|
+
this.emitEventForChunk(chunk, isThinking);
|
|
1295
|
+
if (chunk.type === "thinking") {
|
|
1296
|
+
isThinking = true;
|
|
1297
|
+
} else if (chunk.type === "text_delta" || chunk.type === "tool_use") {
|
|
1298
|
+
if (isThinking) {
|
|
1299
|
+
this.eventEmitter?.emitThinkingStoped();
|
|
1300
|
+
isThinking = false;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
if (chunk.type === "text_delta") {
|
|
1304
|
+
finalContent += chunk.content;
|
|
1305
|
+
}
|
|
1234
1306
|
if (resolveChunk) {
|
|
1235
1307
|
const resolve2 = resolveChunk;
|
|
1236
1308
|
resolveChunk = null;
|
|
@@ -1271,16 +1343,21 @@ class CodexRunner {
|
|
|
1271
1343
|
codex.stderr.on("data", processOutput);
|
|
1272
1344
|
codex.on("error", (err) => {
|
|
1273
1345
|
errorMessage = `Failed to start Codex CLI: ${err.message}. Ensure 'codex' is installed and available in PATH.`;
|
|
1346
|
+
this.eventEmitter?.emitErrorOccurred(errorMessage, "SPAWN_ERROR");
|
|
1274
1347
|
signalEnd();
|
|
1275
1348
|
});
|
|
1276
1349
|
codex.on("close", (code) => {
|
|
1277
1350
|
this.activeProcess = null;
|
|
1278
|
-
this.cleanupTempFile(outputPath);
|
|
1279
1351
|
if (code === 0) {
|
|
1280
1352
|
const result = this.readOutput(outputPath, finalOutput);
|
|
1353
|
+
this.cleanupTempFile(outputPath);
|
|
1281
1354
|
enqueueChunk({ type: "result", content: result });
|
|
1282
|
-
} else
|
|
1283
|
-
|
|
1355
|
+
} else {
|
|
1356
|
+
this.cleanupTempFile(outputPath);
|
|
1357
|
+
if (!errorMessage) {
|
|
1358
|
+
errorMessage = this.createErrorFromOutput(code, finalOutput).message;
|
|
1359
|
+
this.eventEmitter?.emitErrorOccurred(errorMessage, `EXIT_${code}`);
|
|
1360
|
+
}
|
|
1284
1361
|
}
|
|
1285
1362
|
signalEnd();
|
|
1286
1363
|
});
|
|
@@ -1294,6 +1371,12 @@ class CodexRunner {
|
|
|
1294
1371
|
} else if (processEnded) {
|
|
1295
1372
|
if (errorMessage) {
|
|
1296
1373
|
yield { type: "error", error: errorMessage };
|
|
1374
|
+
this.eventEmitter?.emitSessionEnded(false);
|
|
1375
|
+
} else {
|
|
1376
|
+
if (finalContent) {
|
|
1377
|
+
this.eventEmitter?.emitResponseCompleted(finalContent);
|
|
1378
|
+
}
|
|
1379
|
+
this.eventEmitter?.emitSessionEnded(true);
|
|
1297
1380
|
}
|
|
1298
1381
|
break;
|
|
1299
1382
|
} else {
|
|
@@ -1303,6 +1386,12 @@ class CodexRunner {
|
|
|
1303
1386
|
if (chunk === null) {
|
|
1304
1387
|
if (errorMessage) {
|
|
1305
1388
|
yield { type: "error", error: errorMessage };
|
|
1389
|
+
this.eventEmitter?.emitSessionEnded(false);
|
|
1390
|
+
} else {
|
|
1391
|
+
if (finalContent) {
|
|
1392
|
+
this.eventEmitter?.emitResponseCompleted(finalContent);
|
|
1393
|
+
}
|
|
1394
|
+
this.eventEmitter?.emitSessionEnded(true);
|
|
1306
1395
|
}
|
|
1307
1396
|
break;
|
|
1308
1397
|
}
|
|
@@ -1310,6 +1399,36 @@ class CodexRunner {
|
|
|
1310
1399
|
}
|
|
1311
1400
|
}
|
|
1312
1401
|
}
|
|
1402
|
+
emitEventForChunk(chunk, isThinking) {
|
|
1403
|
+
if (!this.eventEmitter)
|
|
1404
|
+
return;
|
|
1405
|
+
switch (chunk.type) {
|
|
1406
|
+
case "text_delta":
|
|
1407
|
+
this.eventEmitter.emitTextDelta(chunk.content);
|
|
1408
|
+
break;
|
|
1409
|
+
case "tool_use":
|
|
1410
|
+
if (this.currentToolName) {
|
|
1411
|
+
this.eventEmitter.emitToolCompleted(this.currentToolName);
|
|
1412
|
+
}
|
|
1413
|
+
this.currentToolName = chunk.tool;
|
|
1414
|
+
this.eventEmitter.emitToolStarted(chunk.tool);
|
|
1415
|
+
break;
|
|
1416
|
+
case "thinking":
|
|
1417
|
+
if (!isThinking) {
|
|
1418
|
+
this.eventEmitter.emitThinkingStarted(chunk.content);
|
|
1419
|
+
}
|
|
1420
|
+
break;
|
|
1421
|
+
case "result":
|
|
1422
|
+
if (this.currentToolName) {
|
|
1423
|
+
this.eventEmitter.emitToolCompleted(this.currentToolName);
|
|
1424
|
+
this.currentToolName = undefined;
|
|
1425
|
+
}
|
|
1426
|
+
break;
|
|
1427
|
+
case "error":
|
|
1428
|
+
this.eventEmitter.emitErrorOccurred(chunk.error);
|
|
1429
|
+
break;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1313
1432
|
executeRun(prompt) {
|
|
1314
1433
|
return new Promise((resolve2, reject) => {
|
|
1315
1434
|
const outputPath = import_node_path4.join(import_node_os2.tmpdir(), `locus-codex-${import_node_crypto.randomUUID()}.txt`);
|
|
@@ -1339,10 +1458,12 @@ class CodexRunner {
|
|
|
1339
1458
|
});
|
|
1340
1459
|
codex.on("close", (code) => {
|
|
1341
1460
|
this.activeProcess = null;
|
|
1342
|
-
this.cleanupTempFile(outputPath);
|
|
1343
1461
|
if (code === 0) {
|
|
1344
|
-
|
|
1462
|
+
const result = this.readOutput(outputPath, output);
|
|
1463
|
+
this.cleanupTempFile(outputPath);
|
|
1464
|
+
resolve2(result);
|
|
1345
1465
|
} else {
|
|
1466
|
+
this.cleanupTempFile(outputPath);
|
|
1346
1467
|
reject(this.createErrorFromOutput(code, errorOutput));
|
|
1347
1468
|
}
|
|
1348
1469
|
});
|
|
@@ -1352,12 +1473,18 @@ class CodexRunner {
|
|
|
1352
1473
|
}
|
|
1353
1474
|
buildArgs(outputPath) {
|
|
1354
1475
|
const args = [
|
|
1476
|
+
"--ask-for-approval",
|
|
1477
|
+
"never",
|
|
1355
1478
|
"exec",
|
|
1356
1479
|
"--sandbox",
|
|
1357
1480
|
"workspace-write",
|
|
1358
1481
|
"--skip-git-repo-check",
|
|
1359
1482
|
"--output-last-message",
|
|
1360
|
-
outputPath
|
|
1483
|
+
outputPath,
|
|
1484
|
+
"-c",
|
|
1485
|
+
"sandbox_workspace_write.network_access=true",
|
|
1486
|
+
"-c",
|
|
1487
|
+
'sandbox.excludedCommands=["git", "gh"]'
|
|
1361
1488
|
];
|
|
1362
1489
|
if (this.model) {
|
|
1363
1490
|
args.push("--model", this.model);
|
|
@@ -1408,7 +1535,7 @@ class CodexRunner {
|
|
|
1408
1535
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
1409
1536
|
}
|
|
1410
1537
|
}
|
|
1411
|
-
var import_node_child_process2, import_node_crypto, import_node_fs2, import_node_os2, import_node_path4;
|
|
1538
|
+
var import_node_child_process2, import_node_crypto, import_node_fs2, import_node_os2, import_node_path4, DEFAULT_TIMEOUT_MS2;
|
|
1412
1539
|
var init_codex_runner = __esm(() => {
|
|
1413
1540
|
init_config();
|
|
1414
1541
|
init_resolve_bin();
|
|
@@ -1417,6 +1544,7 @@ var init_codex_runner = __esm(() => {
|
|
|
1417
1544
|
import_node_fs2 = require("node:fs");
|
|
1418
1545
|
import_node_os2 = require("node:os");
|
|
1419
1546
|
import_node_path4 = require("node:path");
|
|
1547
|
+
DEFAULT_TIMEOUT_MS2 = 60 * 60 * 1000;
|
|
1420
1548
|
});
|
|
1421
1549
|
|
|
1422
1550
|
// src/ai/factory.ts
|
|
@@ -1425,9 +1553,9 @@ function createAiRunner(provider, config) {
|
|
|
1425
1553
|
const model = config.model ?? DEFAULT_MODEL[resolvedProvider];
|
|
1426
1554
|
switch (resolvedProvider) {
|
|
1427
1555
|
case PROVIDER.CODEX:
|
|
1428
|
-
return new CodexRunner(config.projectPath, model, config.log);
|
|
1556
|
+
return new CodexRunner(config.projectPath, model, config.log, config.timeoutMs);
|
|
1429
1557
|
default:
|
|
1430
|
-
return new ClaudeRunner(config.projectPath, model, config.log);
|
|
1558
|
+
return new ClaudeRunner(config.projectPath, model, config.log, config.timeoutMs);
|
|
1431
1559
|
}
|
|
1432
1560
|
}
|
|
1433
1561
|
var init_factory = __esm(() => {
|
|
@@ -1952,8 +2080,9 @@ class WorktreeManager {
|
|
|
1952
2080
|
this.ensureDirectory(this.rootPath, "Worktree root");
|
|
1953
2081
|
addWorktree();
|
|
1954
2082
|
}
|
|
1955
|
-
this.
|
|
1956
|
-
|
|
2083
|
+
const baseCommitHash = this.git("rev-parse HEAD", worktreePath).trim();
|
|
2084
|
+
this.log(`Worktree created at ${worktreePath} (base: ${baseCommitHash.slice(0, 8)})`, "success");
|
|
2085
|
+
return { worktreePath, branch, baseBranch, baseCommitHash };
|
|
1957
2086
|
}
|
|
1958
2087
|
list() {
|
|
1959
2088
|
const output = this.git("worktree list --porcelain", this.projectPath);
|
|
@@ -2058,27 +2187,54 @@ class WorktreeManager {
|
|
|
2058
2187
|
try {
|
|
2059
2188
|
const count = this.git(`rev-list --count "${baseBranch}..HEAD"`, worktreePath).trim();
|
|
2060
2189
|
return Number.parseInt(count, 10) > 0;
|
|
2190
|
+
} catch (err) {
|
|
2191
|
+
this.log(`Could not compare HEAD against base branch "${baseBranch}": ${err instanceof Error ? err.message : String(err)}`, "warn");
|
|
2192
|
+
return false;
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
hasCommitsAheadOfHash(worktreePath, baseHash) {
|
|
2196
|
+
try {
|
|
2197
|
+
const headHash = this.git("rev-parse HEAD", worktreePath).trim();
|
|
2198
|
+
return headHash !== baseHash;
|
|
2061
2199
|
} catch {
|
|
2062
2200
|
return false;
|
|
2063
2201
|
}
|
|
2064
2202
|
}
|
|
2065
|
-
commitChanges(worktreePath, message, baseBranch) {
|
|
2203
|
+
commitChanges(worktreePath, message, baseBranch, baseCommitHash) {
|
|
2066
2204
|
const hasUncommittedChanges = this.hasChanges(worktreePath);
|
|
2205
|
+
if (hasUncommittedChanges) {
|
|
2206
|
+
const statusOutput = this.git("status --porcelain", worktreePath).trim();
|
|
2207
|
+
this.log(`Detected uncommitted changes:
|
|
2208
|
+
${statusOutput.split(`
|
|
2209
|
+
`).slice(0, 10).join(`
|
|
2210
|
+
`)}${statusOutput.split(`
|
|
2211
|
+
`).length > 10 ? `
|
|
2212
|
+
... and ${statusOutput.split(`
|
|
2213
|
+
`).length - 10} more` : ""}`, "info");
|
|
2214
|
+
}
|
|
2067
2215
|
if (!hasUncommittedChanges) {
|
|
2068
2216
|
if (baseBranch && this.hasCommitsAhead(worktreePath, baseBranch)) {
|
|
2069
2217
|
const hash2 = this.git("rev-parse HEAD", worktreePath).trim();
|
|
2070
2218
|
this.log(`Agent already committed changes (${hash2.slice(0, 8)}); skipping additional commit`, "info");
|
|
2071
2219
|
return hash2;
|
|
2072
2220
|
}
|
|
2073
|
-
this.
|
|
2221
|
+
if (baseCommitHash && this.hasCommitsAheadOfHash(worktreePath, baseCommitHash)) {
|
|
2222
|
+
const hash2 = this.git("rev-parse HEAD", worktreePath).trim();
|
|
2223
|
+
this.log(`Agent already committed changes (${hash2.slice(0, 8)}, detected via base commit hash); skipping additional commit`, "info");
|
|
2224
|
+
return hash2;
|
|
2225
|
+
}
|
|
2226
|
+
const branch = this.getBranch(worktreePath);
|
|
2227
|
+
this.log(`No changes detected in worktree (branch: ${branch}, baseBranch: ${baseBranch ?? "none"}, baseCommitHash: ${baseCommitHash?.slice(0, 8) ?? "none"})`, "warn");
|
|
2074
2228
|
return null;
|
|
2075
2229
|
}
|
|
2076
2230
|
this.git("add -A", worktreePath);
|
|
2077
2231
|
const staged = this.git("diff --cached --name-only", worktreePath).trim();
|
|
2078
2232
|
if (!staged) {
|
|
2079
|
-
this.log("
|
|
2233
|
+
this.log("All changes were ignored by .gitignore — nothing to commit", "warn");
|
|
2080
2234
|
return null;
|
|
2081
2235
|
}
|
|
2236
|
+
this.log(`Staging ${staged.split(`
|
|
2237
|
+
`).length} file(s) for commit`, "info");
|
|
2082
2238
|
this.gitExec(["commit", "-m", message], worktreePath);
|
|
2083
2239
|
const hash = this.git("rev-parse HEAD", worktreePath).trim();
|
|
2084
2240
|
this.log(`Committed: ${hash.slice(0, 8)}`, "success");
|
|
@@ -2500,15 +2656,27 @@ class TaskExecutor {
|
|
|
2500
2656
|
const basePrompt = await this.promptBuilder.build(task);
|
|
2501
2657
|
try {
|
|
2502
2658
|
this.deps.log("Starting Execution...", "info");
|
|
2503
|
-
await this.deps.aiRunner.run(basePrompt);
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
summary: "Task completed by the agent"
|
|
2507
|
-
};
|
|
2659
|
+
const output = await this.deps.aiRunner.run(basePrompt);
|
|
2660
|
+
const summary = this.extractSummary(output);
|
|
2661
|
+
return { success: true, summary };
|
|
2508
2662
|
} catch (error) {
|
|
2509
2663
|
return { success: false, summary: `Error: ${error}` };
|
|
2510
2664
|
}
|
|
2511
2665
|
}
|
|
2666
|
+
extractSummary(output) {
|
|
2667
|
+
if (!output || !output.trim()) {
|
|
2668
|
+
return "Task completed by the agent";
|
|
2669
|
+
}
|
|
2670
|
+
const paragraphs = output.split(/\n\n+/).map((p) => p.trim()).filter((p) => p.length > 0);
|
|
2671
|
+
if (paragraphs.length === 0) {
|
|
2672
|
+
return "Task completed by the agent";
|
|
2673
|
+
}
|
|
2674
|
+
const last = paragraphs[paragraphs.length - 1];
|
|
2675
|
+
if (last.length > 500) {
|
|
2676
|
+
return `${last.slice(0, 497)}...`;
|
|
2677
|
+
}
|
|
2678
|
+
return last;
|
|
2679
|
+
}
|
|
2512
2680
|
}
|
|
2513
2681
|
var init_task_executor = __esm(() => {
|
|
2514
2682
|
init_prompt_builder();
|
|
@@ -2526,7 +2694,7 @@ class GitWorkflow {
|
|
|
2526
2694
|
this.log = log;
|
|
2527
2695
|
this.ghUsername = ghUsername;
|
|
2528
2696
|
const projectPath = config.projectPath || process.cwd();
|
|
2529
|
-
this.worktreeManager = config.useWorktrees ? new WorktreeManager(projectPath, { cleanupPolicy: "auto" }) : null;
|
|
2697
|
+
this.worktreeManager = config.useWorktrees ? new WorktreeManager(projectPath, { cleanupPolicy: "auto" }, log) : null;
|
|
2530
2698
|
this.prService = config.autoPush ? new PrService(projectPath, log) : null;
|
|
2531
2699
|
}
|
|
2532
2700
|
createTaskWorktree(task, defaultExecutor) {
|
|
@@ -2534,6 +2702,7 @@ class GitWorkflow {
|
|
|
2534
2702
|
return {
|
|
2535
2703
|
worktreePath: null,
|
|
2536
2704
|
baseBranch: null,
|
|
2705
|
+
baseCommitHash: null,
|
|
2537
2706
|
executor: defaultExecutor
|
|
2538
2707
|
};
|
|
2539
2708
|
}
|
|
@@ -2559,10 +2728,11 @@ class GitWorkflow {
|
|
|
2559
2728
|
return {
|
|
2560
2729
|
worktreePath: result.worktreePath,
|
|
2561
2730
|
baseBranch: result.baseBranch,
|
|
2731
|
+
baseCommitHash: result.baseCommitHash,
|
|
2562
2732
|
executor: taskExecutor
|
|
2563
2733
|
};
|
|
2564
2734
|
}
|
|
2565
|
-
commitAndPush(worktreePath, task, baseBranch) {
|
|
2735
|
+
commitAndPush(worktreePath, task, baseBranch, baseCommitHash) {
|
|
2566
2736
|
if (!this.worktreeManager) {
|
|
2567
2737
|
return { branch: null, pushed: false, pushFailed: false };
|
|
2568
2738
|
}
|
|
@@ -2579,7 +2749,7 @@ class GitWorkflow {
|
|
|
2579
2749
|
|
|
2580
2750
|
${trailers.join(`
|
|
2581
2751
|
`)}`;
|
|
2582
|
-
const hash = this.worktreeManager.commitChanges(worktreePath, commitMessage, baseBranch);
|
|
2752
|
+
const hash = this.worktreeManager.commitChanges(worktreePath, commitMessage, baseBranch, baseCommitHash);
|
|
2583
2753
|
if (!hash) {
|
|
2584
2754
|
this.log("No changes to commit for this task", "info");
|
|
2585
2755
|
return {
|
|
@@ -2619,7 +2789,12 @@ ${trailers.join(`
|
|
|
2619
2789
|
} catch (err) {
|
|
2620
2790
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
2621
2791
|
this.log(`Git commit failed: ${errorMessage}`, "error");
|
|
2622
|
-
return {
|
|
2792
|
+
return {
|
|
2793
|
+
branch: null,
|
|
2794
|
+
pushed: false,
|
|
2795
|
+
pushFailed: true,
|
|
2796
|
+
pushError: `Git commit/push failed: ${errorMessage}`
|
|
2797
|
+
};
|
|
2623
2798
|
}
|
|
2624
2799
|
}
|
|
2625
2800
|
createPullRequest(task, branch, summary, baseBranch) {
|
|
@@ -2851,7 +3026,7 @@ class AgentWorker {
|
|
|
2851
3026
|
}
|
|
2852
3027
|
async executeTask(task) {
|
|
2853
3028
|
const fullTask = await this.client.tasks.getById(task.id, this.config.workspaceId);
|
|
2854
|
-
const { worktreePath, baseBranch, executor } = this.gitWorkflow.createTaskWorktree(fullTask, this.taskExecutor);
|
|
3029
|
+
const { worktreePath, baseBranch, baseCommitHash, executor } = this.gitWorkflow.createTaskWorktree(fullTask, this.taskExecutor);
|
|
2855
3030
|
this.currentWorktreePath = worktreePath;
|
|
2856
3031
|
let branchPushed = false;
|
|
2857
3032
|
let keepBranch = false;
|
|
@@ -2863,7 +3038,7 @@ class AgentWorker {
|
|
|
2863
3038
|
let prError = null;
|
|
2864
3039
|
let noChanges = false;
|
|
2865
3040
|
if (result.success && worktreePath) {
|
|
2866
|
-
const commitResult = this.gitWorkflow.commitAndPush(worktreePath, fullTask, baseBranch ?? undefined);
|
|
3041
|
+
const commitResult = this.gitWorkflow.commitAndPush(worktreePath, fullTask, baseBranch ?? undefined, baseCommitHash ?? undefined);
|
|
2867
3042
|
taskBranch = commitResult.branch;
|
|
2868
3043
|
branchPushed = commitResult.pushed;
|
|
2869
3044
|
keepBranch = taskBranch !== null;
|
|
@@ -4986,6 +5161,9 @@ class TierMergeService {
|
|
|
4986
5161
|
}
|
|
4987
5162
|
}
|
|
4988
5163
|
findTierTaskBranches(tier) {
|
|
5164
|
+
const tierTaskIds = this.tierTaskIds.get(tier);
|
|
5165
|
+
if (!tierTaskIds || tierTaskIds.length === 0)
|
|
5166
|
+
return [];
|
|
4989
5167
|
try {
|
|
4990
5168
|
const output = import_node_child_process8.execSync('git branch -r --list "origin/agent/*" --format="%(refname:short)"', { cwd: this.projectPath, encoding: "utf-8" }).trim();
|
|
4991
5169
|
if (!output)
|
|
@@ -4993,13 +5171,13 @@ class TierMergeService {
|
|
|
4993
5171
|
const remoteBranches = output.split(`
|
|
4994
5172
|
`).map((b) => b.replace("origin/", ""));
|
|
4995
5173
|
return remoteBranches.filter((branch) => {
|
|
4996
|
-
const
|
|
4997
|
-
if (!
|
|
5174
|
+
const branchSuffix = branch.replace(/^agent\//, "");
|
|
5175
|
+
if (!branchSuffix)
|
|
4998
5176
|
return false;
|
|
4999
|
-
|
|
5000
|
-
return this.tierTaskIds.get(tier)?.some((id) => id.startsWith(taskIdPrefix) || taskIdPrefix.startsWith(id.slice(0, 8))) ?? false;
|
|
5177
|
+
return tierTaskIds.some((id) => branchSuffix.startsWith(`${id}-`) || branchSuffix === id || branchSuffix.startsWith(id));
|
|
5001
5178
|
});
|
|
5002
|
-
} catch {
|
|
5179
|
+
} catch (err) {
|
|
5180
|
+
console.log(c.dim(` Could not list remote branches for tier ${tier}: ${err instanceof Error ? err.message : String(err)}`));
|
|
5003
5181
|
return [];
|
|
5004
5182
|
}
|
|
5005
5183
|
}
|
|
@@ -5550,6 +5728,7 @@ Review and refine the Tech Lead's breakdown:
|
|
|
5550
5728
|
3. **Task Merging** — If two tasks are trivially small and related, merge them.
|
|
5551
5729
|
4. **Complexity Scoring** — Rate each task 1-5 (1=trivial, 5=very complex).
|
|
5552
5730
|
5. **Missing Tasks** — Add any tasks the Tech Lead missed (database migrations, configuration, testing, etc.).
|
|
5731
|
+
6. **Description Quality** — Review and improve each task description to be a clear, actionable implementation guide. Each description must tell the executing agent exactly what to do, where to do it (specific files/modules), how to do it (patterns, utilities, data flow), and what is NOT in scope. Vague descriptions like "Add authentication" must be rewritten with specific file paths, implementation approach, and boundaries.
|
|
5553
5732
|
|
|
5554
5733
|
## CRITICAL: Task Isolation & Overlap Detection
|
|
5555
5734
|
|
|
@@ -5575,7 +5754,7 @@ Your entire response must be a single JSON object — no text before it, no text
|
|
|
5575
5754
|
"tasks": [
|
|
5576
5755
|
{
|
|
5577
5756
|
"title": "string",
|
|
5578
|
-
"description": "string (
|
|
5757
|
+
"description": "string (detailed implementation guide: what to do, where to do it, how to do it, and boundaries)",
|
|
5579
5758
|
"assigneeRole": "BACKEND | FRONTEND | QA | PM | DESIGN",
|
|
5580
5759
|
"priority": "HIGH | MEDIUM | LOW | CRITICAL",
|
|
5581
5760
|
"labels": ["string"],
|
|
@@ -5668,6 +5847,15 @@ Verify tier assignments are correct:
|
|
|
5668
5847
|
### 5. Merge Conflict Risk Zones
|
|
5669
5848
|
Identify the highest-risk files (files that multiple same-tier tasks might touch) and ensure only ONE task per tier modifies each.
|
|
5670
5849
|
|
|
5850
|
+
### 6. Description Quality Validation
|
|
5851
|
+
For each task, verify the description is a clear, actionable implementation guide. Each description must specify:
|
|
5852
|
+
- **What to do** — the specific goal and expected behavior/outcome
|
|
5853
|
+
- **Where to do it** — specific files, modules, or directories to modify or create
|
|
5854
|
+
- **How to do it** — implementation approach, patterns to follow, existing utilities to use
|
|
5855
|
+
- **Boundaries** — what is NOT in scope for this task
|
|
5856
|
+
|
|
5857
|
+
If any description is vague (e.g., "Add authentication", "Update the API", "Fix the frontend"), rewrite it with concrete implementation details. The executing agent receives ONLY the task title, description, and acceptance criteria as its instructions.
|
|
5858
|
+
|
|
5671
5859
|
## Output Format
|
|
5672
5860
|
|
|
5673
5861
|
Your entire response must be a single JSON object — no text before it, no text after it, no markdown code blocks, no explanation. Start your response with the "{" character:
|
|
@@ -5676,7 +5864,7 @@ Your entire response must be a single JSON object — no text before it, no text
|
|
|
5676
5864
|
"hasIssues": true | false,
|
|
5677
5865
|
"issues": [
|
|
5678
5866
|
{
|
|
5679
|
-
"type": "file_overlap" | "duplicated_work" | "not_self_contained" | "merge_conflict_risk" | "wrong_tier",
|
|
5867
|
+
"type": "file_overlap" | "duplicated_work" | "not_self_contained" | "merge_conflict_risk" | "wrong_tier" | "vague_description",
|
|
5680
5868
|
"description": "string describing the specific issue",
|
|
5681
5869
|
"affectedTasks": ["Task Title 1", "Task Title 2"],
|
|
5682
5870
|
"resolution": "string describing how to fix it (merge, move to different tier, consolidate)"
|
|
@@ -5689,7 +5877,7 @@ Your entire response must be a single JSON object — no text before it, no text
|
|
|
5689
5877
|
"tasks": [
|
|
5690
5878
|
{
|
|
5691
5879
|
"title": "string",
|
|
5692
|
-
"description": "string",
|
|
5880
|
+
"description": "string (detailed implementation guide: what to do, where to do it, how to do it, and boundaries)",
|
|
5693
5881
|
"assigneeRole": "BACKEND | FRONTEND | QA | PM | DESIGN",
|
|
5694
5882
|
"priority": "CRITICAL | HIGH | MEDIUM | LOW",
|
|
5695
5883
|
"labels": ["string"],
|
|
@@ -5713,6 +5901,7 @@ IMPORTANT:
|
|
|
5713
5901
|
- If hasIssues is false, the revisedPlan should be identical to the input plan (no changes needed)
|
|
5714
5902
|
- The revisedPlan is ALWAYS required — it becomes the final plan
|
|
5715
5903
|
- When merging tasks, combine their acceptance criteria and update descriptions to cover all consolidated work
|
|
5904
|
+
- Ensure every task description is a detailed implementation guide (what, where, how, boundaries) — rewrite vague descriptions
|
|
5716
5905
|
- Prefer fewer, larger, self-contained tasks over many small conflicting ones
|
|
5717
5906
|
- Every task MUST have a "tier" field (integer >= 0)
|
|
5718
5907
|
- tier 0 = foundational (runs first), tier 1 = depends on tier 0, tier 2 = depends on tier 1, etc.
|
|
@@ -5751,6 +5940,7 @@ Produce the final sprint plan:
|
|
|
5751
5940
|
4. **Tier Assignment** — Assign each task an execution tier (integer, starting at 0). Tasks within the same tier run IN PARALLEL on separate git branches. Tasks in tier N+1 only start AFTER all tier N tasks are complete and merged. Tier 0 = foundational tasks (config, schemas, shared code). Higher tiers build on lower tier outputs.
|
|
5752
5941
|
5. **Duration Estimate** — How many days this sprint will take with 2-3 agents working in parallel
|
|
5753
5942
|
6. **Final Task List** — Each task with all fields filled in, ordered by execution priority
|
|
5943
|
+
7. **Description Quality Check** — Ensure every task description is a clear, actionable implementation guide. Each description must specify: what to do, where to do it (specific files/modules/directories), how to do it (implementation approach, patterns to follow, existing utilities to use), and what is NOT in scope. If any description is vague or generic, rewrite it with specifics. Remember: an independent agent will receive ONLY the task title, description, and acceptance criteria — the description is its primary instruction.
|
|
5754
5944
|
|
|
5755
5945
|
Guidelines:
|
|
5756
5946
|
- The order of tasks in the array determines execution order. Tasks are dispatched sequentially from first to last.
|
|
@@ -5760,6 +5950,7 @@ Guidelines:
|
|
|
5760
5950
|
- Group related independent tasks in the same tier for maximum parallelism
|
|
5761
5951
|
- Ensure acceptance criteria are specific and testable
|
|
5762
5952
|
- Keep the sprint focused — if it's too large (>12 tasks), consider reducing scope
|
|
5953
|
+
- Ensure every task description reads as a standalone implementation brief — not a summary
|
|
5763
5954
|
|
|
5764
5955
|
## CRITICAL: Task Isolation Validation
|
|
5765
5956
|
|
|
@@ -5781,7 +5972,7 @@ Your entire response must be a single JSON object — no text before it, no text
|
|
|
5781
5972
|
"tasks": [
|
|
5782
5973
|
{
|
|
5783
5974
|
"title": "string",
|
|
5784
|
-
"description": "string",
|
|
5975
|
+
"description": "string (detailed implementation guide: what to do, where to do it, how to do it, and boundaries)",
|
|
5785
5976
|
"assigneeRole": "BACKEND | FRONTEND | QA | PM | DESIGN",
|
|
5786
5977
|
"priority": "CRITICAL | HIGH | MEDIUM | LOW",
|
|
5787
5978
|
"labels": ["string"],
|
|
@@ -5837,7 +6028,7 @@ ${input.codebaseIndex || "No codebase index available."}
|
|
|
5837
6028
|
Analyze the CEO's directive and produce a detailed task breakdown. For each task:
|
|
5838
6029
|
|
|
5839
6030
|
1. **Title** — Clear, action-oriented (e.g., "Implement user registration API endpoint")
|
|
5840
|
-
2. **Description** —
|
|
6031
|
+
2. **Description** — A detailed, actionable implementation guide (see description requirements below)
|
|
5841
6032
|
3. **Assignee Role** — Who should work on this: BACKEND, FRONTEND, QA, PM, or DESIGN
|
|
5842
6033
|
4. **Priority** — HIGH, MEDIUM, or LOW based on business impact
|
|
5843
6034
|
5. **Labels** — Relevant tags (e.g., "api", "database", "ui", "auth")
|
|
@@ -5849,6 +6040,19 @@ Think about:
|
|
|
5849
6040
|
- What the right granularity is (not too big, not too small)
|
|
5850
6041
|
- What risks or unknowns exist
|
|
5851
6042
|
|
|
6043
|
+
## CRITICAL: Task Description Requirements
|
|
6044
|
+
|
|
6045
|
+
Each task description will be handed to an INDEPENDENT agent as its primary instruction. The agent will have access to the codebase but NO context about the planning meeting. Descriptions must be clear enough for the agent to execute the task without ambiguity.
|
|
6046
|
+
|
|
6047
|
+
Each description MUST include:
|
|
6048
|
+
1. **What to do** — Clearly state the goal and what needs to be implemented, changed, or created. Be specific about the expected behavior or outcome.
|
|
6049
|
+
2. **Where to do it** — List the specific files, modules, or directories that need to be modified or created. Reference existing code paths when extending functionality.
|
|
6050
|
+
3. **How to do it** — Provide key implementation details: which patterns to follow, which existing utilities or services to use, what the data flow looks like.
|
|
6051
|
+
4. **Boundaries** — Clarify what is NOT in scope for this task to prevent overlap with other tasks.
|
|
6052
|
+
|
|
6053
|
+
Bad example: "Add authentication to the API."
|
|
6054
|
+
Good example: "Implement JWT-based authentication middleware in src/middleware/auth.ts. Create a verifyToken middleware that extracts the Bearer token from the Authorization header, validates it using the existing JWT_SECRET from env config, and attaches the decoded user payload to req.user. Apply this middleware to all routes in src/routes/protected/. Add a POST /auth/login endpoint in src/routes/auth.ts that accepts {email, password}, validates credentials against the users table, and returns a signed JWT. This task does NOT include user registration or password reset — those are handled separately."
|
|
6055
|
+
|
|
5852
6056
|
## CRITICAL: Task Isolation Rules
|
|
5853
6057
|
|
|
5854
6058
|
Tasks will be executed by INDEPENDENT agents on SEPARATE git branches that get merged together. Each agent has NO knowledge of what other agents are doing. Therefore:
|
|
@@ -5867,7 +6071,7 @@ Your entire response must be a single JSON object — no text before it, no text
|
|
|
5867
6071
|
"tasks": [
|
|
5868
6072
|
{
|
|
5869
6073
|
"title": "string",
|
|
5870
|
-
"description": "string (
|
|
6074
|
+
"description": "string (detailed implementation guide: what to do, where to do it, how to do it, and boundaries — see description requirements above)",
|
|
5871
6075
|
"assigneeRole": "BACKEND | FRONTEND | QA | PM | DESIGN",
|
|
5872
6076
|
"priority": "HIGH | MEDIUM | LOW",
|
|
5873
6077
|
"labels": ["string"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tier-merge.d.ts","sourceRoot":"","sources":["../../src/orchestrator/tier-merge.ts"],"names":[],"mappings":"AAMA;;;;;;;;;GASG;AACH,qBAAa,gBAAgB;IAKzB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,QAAQ;IALlB,yDAAyD;IACzD,OAAO,CAAC,WAAW,CAAoC;gBAG7C,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GAAG,IAAI;IAGjC;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,GAAG,IAAI;IAY3E;;;OAGG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAKpC;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAiB3C;;;;;;;;OAQG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA0ElE;;;OAGG;IACH,OAAO,CAAC,oBAAoB;
|
|
1
|
+
{"version":3,"file":"tier-merge.d.ts","sourceRoot":"","sources":["../../src/orchestrator/tier-merge.ts"],"names":[],"mappings":"AAMA;;;;;;;;;GASG;AACH,qBAAa,gBAAgB;IAKzB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,QAAQ;IALlB,yDAAyD;IACzD,OAAO,CAAC,WAAW,CAAoC;gBAG7C,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GAAG,IAAI;IAGjC;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,GAAG,IAAI;IAY3E;;;OAGG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAKpC;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAiB3C;;;;;;;;OAQG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA0ElE;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA0C5B,OAAO,CAAC,OAAO;CAOhB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"architect.d.ts","sourceRoot":"","sources":["../../../src/planning/agents/architect.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"architect.d.ts","sourceRoot":"","sources":["../../../src/planning/agents/architect.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CA+ElE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cross-task-reviewer.d.ts","sourceRoot":"","sources":["../../../src/planning/agents/cross-task-reviewer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,sBAAsB,GAC5B,MAAM,
|
|
1
|
+
{"version":3,"file":"cross-task-reviewer.d.ts","sourceRoot":"","sources":["../../../src/planning/agents/cross-task-reviewer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,sBAAsB,GAC5B,MAAM,CAuIR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sprint-organizer.d.ts","sourceRoot":"","sources":["../../../src/planning/agents/sprint-organizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,oBAAoB,GAC1B,MAAM,
|
|
1
|
+
{"version":3,"file":"sprint-organizer.d.ts","sourceRoot":"","sources":["../../../src/planning/agents/sprint-organizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,oBAAoB,GAC1B,MAAM,CA0FR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tech-lead.d.ts","sourceRoot":"","sources":["../../../src/planning/agents/tech-lead.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"tech-lead.d.ts","sourceRoot":"","sources":["../../../src/planning/agents/tech-lead.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAoFhE"}
|
|
@@ -52,6 +52,8 @@ export interface CreateWorktreeResult {
|
|
|
52
52
|
branch: string;
|
|
53
53
|
/** Base branch used to create the task branch */
|
|
54
54
|
baseBranch: string;
|
|
55
|
+
/** Commit hash of the base branch at worktree creation time */
|
|
56
|
+
baseCommitHash: string;
|
|
55
57
|
}
|
|
56
58
|
/** Default worktree configuration */
|
|
57
59
|
export declare const DEFAULT_WORKTREE_CONFIG: WorktreeConfig;
|