@sideboard-ai/core 0.1.151 → 0.1.153
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/{abletime-223A3LY6.js → abletime-H7LPGIP2.js} +3 -3
- package/dist/{abletime-CLC5UJC2.js → abletime-JSTJLXAW.js} +3 -3
- package/dist/agents/cursor-runner.js +2 -2
- package/dist/{agents-JAOMXDXN.js → agents-V24DYZI4.js} +8 -9
- package/dist/{agents-U2JCFXW4.js → agents-YVW75KBO.js} +8 -9
- package/dist/{app-settings-3CHCNIMD.js → app-settings-H3INSR67.js} +38 -4
- package/dist/{app-settings-J3JBCUOT.js → app-settings-VRQI3FIE.js} +38 -4
- package/dist/{caffeinate-hold-NBRUWYXO.js → caffeinate-hold-DBKMRZZO.js} +2 -2
- package/dist/{caffeinate-hold-X3JNPR42.js → caffeinate-hold-SK2QISPE.js} +2 -2
- package/dist/chunk-2F63IMCL.js +959 -0
- package/dist/{chunk-GCWAAPJ5.js → chunk-2NRNP7QP.js} +432 -239
- package/dist/{chunk-4XNSGDXE.js → chunk-3BWVOUQG.js} +244 -1
- package/dist/{chunk-LZAOX76N.js → chunk-4THE3EY7.js} +6 -6
- package/dist/{chunk-TUGKX5BD.js → chunk-7UURXPKD.js} +1 -1
- package/dist/{chunk-DCOZABNT.js → chunk-AO35MGOE.js} +1 -1
- package/dist/{chunk-3JBMACYX.js → chunk-CJQLPPEJ.js} +387 -15
- package/dist/{chunk-CZD4NRDZ.js → chunk-D7EGJ3EI.js} +244 -1
- package/dist/{chunk-QZQEXME2.js → chunk-EFVFB2AH.js} +1 -1
- package/dist/{chunk-B7XK37WZ.js → chunk-FDCFXMDG.js} +1 -1
- package/dist/{chunk-WLV7TRMR.js → chunk-JOK4XWBG.js} +1 -1
- package/dist/{chunk-BD2ICC4D.js → chunk-JTJHOYCU.js} +1 -1
- package/dist/{chunk-6H4TJ5TA.js → chunk-KMNODRWF.js} +481 -212
- package/dist/{chunk-GE7M3QTE.js → chunk-LQMFCS54.js} +387 -15
- package/dist/{chunk-G7SIQFBQ.js → chunk-LZ6QMEQC.js} +1 -1
- package/dist/{chunk-EUXOHTUK.js → chunk-LZQULFIT.js} +1 -1
- package/dist/{chunk-KLBOWJ74.js → chunk-OCQPTUR7.js} +1 -1
- package/dist/{chunk-UIS7BVCX.js → chunk-QZEZXYVV.js} +13 -13
- package/dist/chunk-RNC3GR6L.js +905 -0
- package/dist/{chunk-VHX673DI.js → chunk-WLPXZFRE.js} +1 -1
- package/dist/{chunk-7F4XE6UG.js → chunk-XD2BAANL.js} +5 -5
- package/dist/{connected-teams-XO766HB4.js → connected-teams-DBWAMP7G.js} +2 -2
- package/dist/{connected-teams-I2WZZZFA.js → connected-teams-WGONUQOF.js} +2 -2
- package/dist/{coordinator-prompt-LWYUZAXR.js → coordinator-prompt-7FHKCWXB.js} +5 -5
- package/dist/{coordinator-prompt-ZK5MII7W.js → coordinator-prompt-KX2FVVYT.js} +5 -5
- package/dist/{cursor-recover-NOQYOFRF.js → cursor-recover-L5MD6MBO.js} +1 -1
- package/dist/{cursor-recover-QSLWEZNA.js → cursor-recover-NDMLLNYX.js} +2 -2
- package/dist/{global-workspace-IB2CCEJF.js → global-workspace-2BRRKSDN.js} +5 -6
- package/dist/{global-workspace-T7RL3XEC.js → global-workspace-4LHCZ2DC.js} +5 -6
- package/dist/index.cjs +1961 -786
- package/dist/index.d.cts +228 -30
- package/dist/index.d.ts +228 -30
- package/dist/index.js +322 -110
- package/dist/mcp/run-stdio.cjs +1817 -1264
- package/dist/mcp/run-stdio.js +250 -82
- package/dist/{orchestrator-DPTRBKEH.js → orchestrator-5PSHBLP6.js} +10 -12
- package/dist/{orchestrator-Y5MWUU7C.js → orchestrator-ZSSU3FKW.js} +9 -11
- package/dist/{paths-UMEDHOS5.js → paths-53TLA7VQ.js} +1 -1
- package/dist/{paths-QCI3MTO5.js → paths-RRCLNSJB.js} +1 -1
- package/dist/{thread-store-WGASXXXR.js → thread-store-KBFBHT5G.js} +2 -2
- package/dist/{thread-store-57ZLHR3A.js → thread-store-MVQU6HPJ.js} +2 -2
- package/dist/{workspaces-ZXCUVCZC.js → workspaces-5UNDTN4G.js} +5 -7
- package/dist/{workspaces-VICQYI2N.js → workspaces-MQYNZXUK.js} +5 -7
- package/dist/{worktree-HTUM35NT.js → worktree-PEWDAX5O.js} +4 -4
- package/dist/{worktree-DPIREDFR.js → worktree-T4SWFSTT.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-77MP647F.js +0 -210
- package/dist/chunk-ADCEGG4A.js +0 -592
- package/dist/chunk-HWZWBJWL.js +0 -120
- package/dist/chunk-OXOU2FRS.js +0 -212
- package/dist/chunk-TSCWSAQL.js +0 -122
- package/dist/chunk-Y2FNDKHF.js +0 -538
|
@@ -33,18 +33,27 @@ import {
|
|
|
33
33
|
summarizeTurnStderr,
|
|
34
34
|
toolDescription,
|
|
35
35
|
turnFailChatText
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-4THE3EY7.js";
|
|
37
37
|
import {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
} from "./chunk-TSCWSAQL.js";
|
|
38
|
+
extractPresentedPlan,
|
|
39
|
+
readPlanFile,
|
|
40
|
+
writePlanFile
|
|
41
|
+
} from "./chunk-2SDMENAL.js";
|
|
43
42
|
import {
|
|
43
|
+
releaseCaffeinateHoldForThread
|
|
44
|
+
} from "./chunk-OCQPTUR7.js";
|
|
45
|
+
import {
|
|
46
|
+
SLACK_REPLY_FORMATTING,
|
|
47
|
+
addWorkspace,
|
|
44
48
|
assertOrchestratorCapableAgent,
|
|
45
49
|
attachmentsFromWorktreePaths,
|
|
46
50
|
coerceOrchestratorAgent,
|
|
51
|
+
coordinatorSystemPrompt,
|
|
52
|
+
coordinatorTurnReminder,
|
|
47
53
|
createGlobalChat,
|
|
54
|
+
enrichWorkspacesWithGithub,
|
|
55
|
+
ensureGlobalCoordinatorCwd,
|
|
56
|
+
ensureWorkspace,
|
|
48
57
|
healOrchestrationSoccerTitles,
|
|
49
58
|
isCloudCoordinatorThread,
|
|
50
59
|
isGlobalRepoPath,
|
|
@@ -54,24 +63,11 @@ import {
|
|
|
54
63
|
isSlackCoordinatorThread,
|
|
55
64
|
orchestratorSessionPoisonedByBuiltins,
|
|
56
65
|
persistPendingFileAttachments,
|
|
66
|
+
removeWorkspace,
|
|
57
67
|
stageAbsolutePathsAsAttachments,
|
|
58
|
-
stageBuffersAsAttachments
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
extractPresentedPlan,
|
|
62
|
-
readPlanFile,
|
|
63
|
-
writePlanFile
|
|
64
|
-
} from "./chunk-2SDMENAL.js";
|
|
65
|
-
import {
|
|
66
|
-
releaseCaffeinateHoldForThread
|
|
67
|
-
} from "./chunk-KLBOWJ74.js";
|
|
68
|
-
import {
|
|
69
|
-
SLACK_REPLY_FORMATTING,
|
|
70
|
-
coordinatorSystemPrompt,
|
|
71
|
-
coordinatorTurnReminder,
|
|
72
|
-
enrichWorkspacesWithGithub,
|
|
73
|
-
ensureGlobalCoordinatorCwd
|
|
74
|
-
} from "./chunk-OXOU2FRS.js";
|
|
68
|
+
stageBuffersAsAttachments,
|
|
69
|
+
syncWorkspacesFromThreads
|
|
70
|
+
} from "./chunk-RNC3GR6L.js";
|
|
75
71
|
import {
|
|
76
72
|
addPrStackLayer,
|
|
77
73
|
allocateTeamName,
|
|
@@ -119,7 +115,7 @@ import {
|
|
|
119
115
|
withRepoGitLock,
|
|
120
116
|
worktreeDisplayLabelForGroup,
|
|
121
117
|
worktreeNameFromPath
|
|
122
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-CJQLPPEJ.js";
|
|
123
119
|
import {
|
|
124
120
|
ATTACHMENTS_DIR,
|
|
125
121
|
LEGACY_ATTACHMENTS_DIR
|
|
@@ -135,7 +131,7 @@ import {
|
|
|
135
131
|
updateThread,
|
|
136
132
|
withThreadLock,
|
|
137
133
|
writeThread
|
|
138
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-LZQULFIT.js";
|
|
139
135
|
import {
|
|
140
136
|
ensureWorktreeSideboardIgnored
|
|
141
137
|
} from "./chunk-SYFVUF2C.js";
|
|
@@ -162,7 +158,7 @@ import {
|
|
|
162
158
|
stripNestedElectronEnv,
|
|
163
159
|
updateAdvancedSettings,
|
|
164
160
|
writeSecureJson
|
|
165
|
-
} from "./chunk-
|
|
161
|
+
} from "./chunk-D7EGJ3EI.js";
|
|
166
162
|
import {
|
|
167
163
|
writePrivateFile
|
|
168
164
|
} from "./chunk-NSTQ6QKD.js";
|
|
@@ -175,9 +171,10 @@ import {
|
|
|
175
171
|
sideboardReposDir,
|
|
176
172
|
sideboardWorkspacesDir,
|
|
177
173
|
threadLivePath,
|
|
174
|
+
threadsDir,
|
|
178
175
|
workspaceSettingsSourceLabel,
|
|
179
176
|
worktreesRoot
|
|
180
|
-
} from "./chunk-
|
|
177
|
+
} from "./chunk-JTJHOYCU.js";
|
|
181
178
|
|
|
182
179
|
// src/orchestrator/orchestrator.ts
|
|
183
180
|
import { EventEmitter } from "events";
|
|
@@ -395,7 +392,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
395
392
|
await continueOnReply(threadId, prompt);
|
|
396
393
|
return;
|
|
397
394
|
}
|
|
398
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
395
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-ZSSU3FKW.js");
|
|
399
396
|
await getOrchestrator2().send(threadId, prompt);
|
|
400
397
|
} catch {
|
|
401
398
|
}
|
|
@@ -655,7 +652,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
655
652
|
}
|
|
656
653
|
|
|
657
654
|
// src/orchestrator/orchestrator.ts
|
|
658
|
-
import { existsSync as
|
|
655
|
+
import { existsSync as existsSync17 } from "fs";
|
|
659
656
|
|
|
660
657
|
// src/agents/spawn.ts
|
|
661
658
|
import { createInterface } from "readline";
|
|
@@ -736,9 +733,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
736
733
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
737
734
|
);
|
|
738
735
|
}
|
|
739
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
736
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-4LHCZ2DC.js");
|
|
740
737
|
if (isGlobalThread2(thread)) {
|
|
741
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
738
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-KX2FVVYT.js");
|
|
742
739
|
ensureGlobalCoordinatorCwd2(
|
|
743
740
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
744
741
|
);
|
|
@@ -1590,32 +1587,15 @@ File: src/client/frontends/desktop/core/UserData.ts
|
|
|
1590
1587
|
|
|
1591
1588
|
## Growing the rules
|
|
1592
1589
|
|
|
1593
|
-
If a blocking issue is a missing or ambiguous repo rule that will recur, add one sentence to \`.claude/skills/review/SKILL.md\`
|
|
1590
|
+
If a blocking issue is a missing or ambiguous repo rule that will recur, add one sentence to \`.claude/skills/review/SKILL.md\` when that skill already exists. Otherwise write it to \`.context/review.md\` (do not create a review skill). Do not only patch this diff when the same miss will happen again. Do not write new skills under \`.sideboard/skills/\`.
|
|
1594
1591
|
`;
|
|
1595
1592
|
var REVIEW_SKILL_PATH = ".claude/skills/review/SKILL.md";
|
|
1596
1593
|
var REVIEW_SKILL_NAME = "review";
|
|
1597
|
-
var REVIEW_SKILL_FRONTMATTER = `---
|
|
1598
|
-
name: review
|
|
1599
|
-
description: >-
|
|
1600
|
-
Merge-readiness review for this repository. Use when reviewing a PR, worktree
|
|
1601
|
-
diff, or Sideboard Review (Approve / Approve with nits / Request changes).
|
|
1602
|
-
---
|
|
1603
|
-
|
|
1604
|
-
`;
|
|
1605
|
-
function wrapReviewSkillMarkdown(body) {
|
|
1606
|
-
const trimmed = body.replace(/^\uFEFF/, "").trim();
|
|
1607
|
-
const source = trimmed || REVIEW_REQUEST_TEMPLATE.trim();
|
|
1608
|
-
if (/^---\s*\n[\s\S]*?\n---\s*\n/.test(source)) {
|
|
1609
|
-
return source.endsWith("\n") ? source : `${source}
|
|
1610
|
-
`;
|
|
1611
|
-
}
|
|
1612
|
-
return `${REVIEW_SKILL_FRONTMATTER}${source}
|
|
1613
|
-
`;
|
|
1614
|
-
}
|
|
1615
1594
|
|
|
1616
1595
|
// src/review/request-review.ts
|
|
1617
1596
|
var REPO_REVIEW_PATH = ".sideboard/review.md";
|
|
1618
1597
|
var REPO_REVIEW_NAME = "review.md";
|
|
1598
|
+
var CONTEXT_REVIEW_PATH = ".context/review.md";
|
|
1619
1599
|
var REVIEW_REQUEST_PATH = `${ATTACHMENTS_DIR}/Review request.md`;
|
|
1620
1600
|
var LEGACY_REVIEW_REQUEST_PATH = `${LEGACY_ATTACHMENTS_DIR}/Review request.md`;
|
|
1621
1601
|
var REVIEW_REQUEST_NAME = "Review request.md";
|
|
@@ -1662,37 +1642,57 @@ function skillGuidelines(content, source) {
|
|
|
1662
1642
|
source
|
|
1663
1643
|
};
|
|
1664
1644
|
}
|
|
1665
|
-
function
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
const fromLocal = readLocalGuidelines(worktreePath)?.content ?? null;
|
|
1673
|
-
const content = wrapReviewSkillMarkdown(fromRepo ?? fromLocal ?? REVIEW_REQUEST_TEMPLATE);
|
|
1674
|
-
mkdirSync(dirname(abs), { recursive: true });
|
|
1675
|
-
writeFileSync(abs, content, "utf8");
|
|
1676
|
-
return { path: REVIEW_SKILL_PATH, content, wrote: true };
|
|
1645
|
+
function contextGuidelines(content, source) {
|
|
1646
|
+
return {
|
|
1647
|
+
path: CONTEXT_REVIEW_PATH,
|
|
1648
|
+
name: REPO_REVIEW_NAME,
|
|
1649
|
+
content,
|
|
1650
|
+
source
|
|
1651
|
+
};
|
|
1677
1652
|
}
|
|
1678
|
-
function
|
|
1653
|
+
function writeContextGuidelines(worktreePath, content) {
|
|
1654
|
+
const abs = join4(worktreePath, CONTEXT_REVIEW_PATH);
|
|
1655
|
+
mkdirSync(dirname(abs), { recursive: true });
|
|
1656
|
+
const body = content.endsWith("\n") ? content : `${content}
|
|
1657
|
+
`;
|
|
1658
|
+
writeFileSync(abs, body, "utf8");
|
|
1659
|
+
return body;
|
|
1660
|
+
}
|
|
1661
|
+
function readSideboardReview(worktreePath, repoPath) {
|
|
1662
|
+
const fromWorktree = readTextIfPresent(join4(worktreePath, REPO_REVIEW_PATH));
|
|
1663
|
+
if (fromWorktree) return fromWorktree;
|
|
1664
|
+
const repo = repoPath?.replace(/\/+$/, "");
|
|
1665
|
+
const wt = worktreePath.replace(/\/+$/, "");
|
|
1666
|
+
if (!repo || repo === wt) return null;
|
|
1667
|
+
return readTextIfPresent(join4(repo, REPO_REVIEW_PATH));
|
|
1668
|
+
}
|
|
1669
|
+
function ensureReviewGuidelinesFile(worktreePath, repoPath) {
|
|
1679
1670
|
const skillContent = readTextIfPresent(join4(worktreePath, REVIEW_SKILL_PATH));
|
|
1680
|
-
if (skillContent)
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
content: local.content,
|
|
1687
|
-
source: "local"
|
|
1688
|
-
};
|
|
1671
|
+
if (skillContent) {
|
|
1672
|
+
return { ...skillGuidelines(skillContent, "skill"), wrote: false };
|
|
1673
|
+
}
|
|
1674
|
+
const contextContent = readTextIfPresent(join4(worktreePath, CONTEXT_REVIEW_PATH));
|
|
1675
|
+
if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
|
|
1676
|
+
return { ...contextGuidelines(contextContent, "local"), wrote: false };
|
|
1689
1677
|
}
|
|
1690
|
-
const
|
|
1691
|
-
|
|
1678
|
+
const fromSideboard = readSideboardReview(worktreePath, repoPath);
|
|
1679
|
+
if (fromSideboard && !shouldRefreshReviewRequestTemplate(fromSideboard)) {
|
|
1680
|
+
const body2 = writeContextGuidelines(worktreePath, fromSideboard);
|
|
1681
|
+
return { ...contextGuidelines(body2, "repo"), wrote: true };
|
|
1682
|
+
}
|
|
1683
|
+
const local = readLocalGuidelines(worktreePath);
|
|
1684
|
+
const body = writeContextGuidelines(worktreePath, local?.content ?? REVIEW_REQUEST_TEMPLATE);
|
|
1685
|
+
return {
|
|
1686
|
+
...contextGuidelines(body, local ? "local" : "stock"),
|
|
1687
|
+
wrote: true
|
|
1688
|
+
};
|
|
1689
|
+
}
|
|
1690
|
+
function resolveReviewGuidelines(worktreePath, repoPath) {
|
|
1691
|
+
return ensureReviewGuidelinesFile(worktreePath, repoPath);
|
|
1692
1692
|
}
|
|
1693
1693
|
function buildReviewRequestAttachment(content, opts) {
|
|
1694
1694
|
const path = opts?.path ?? REVIEW_SKILL_PATH;
|
|
1695
|
-
const name = opts?.name ?? (path === REVIEW_SKILL_PATH ? REVIEW_SKILL_NAME : path === REPO_REVIEW_PATH ? REPO_REVIEW_NAME : REVIEW_REQUEST_NAME);
|
|
1695
|
+
const name = opts?.name ?? (path === REVIEW_SKILL_PATH ? REVIEW_SKILL_NAME : path === REPO_REVIEW_PATH || path === CONTEXT_REVIEW_PATH ? REPO_REVIEW_NAME : REVIEW_REQUEST_NAME);
|
|
1696
1696
|
return {
|
|
1697
1697
|
id: randomUUID2(),
|
|
1698
1698
|
name,
|
|
@@ -1712,7 +1712,7 @@ async function requestReview(threadRef, send) {
|
|
|
1712
1712
|
if (from.status === "archived") {
|
|
1713
1713
|
throw new Error(`Thread is archived: ${from.id}`);
|
|
1714
1714
|
}
|
|
1715
|
-
const guidelines = resolveReviewGuidelines(from.worktreePath);
|
|
1715
|
+
const guidelines = resolveReviewGuidelines(from.worktreePath, from.repoPath);
|
|
1716
1716
|
const tab = createChatTab({
|
|
1717
1717
|
fromThreadId: from.id,
|
|
1718
1718
|
title: "Review",
|
|
@@ -1937,6 +1937,8 @@ async function attachAbort(handle, signal) {
|
|
|
1937
1937
|
async function runSetupScript(repoPath, worktreePath, onLine, opts) {
|
|
1938
1938
|
const settings = loadWorkspaceSettings(worktreePath, repoPath);
|
|
1939
1939
|
if (!settings?.setup) return { ran: false, exitCode: null, source: null };
|
|
1940
|
+
const source = workspaceSettingsSourceLabel(worktreePath, repoPath);
|
|
1941
|
+
onLine?.(`[setup] ${source ?? "settings.toml"}`);
|
|
1940
1942
|
const handle = await spawnWorkspaceScript(settings.setup, {
|
|
1941
1943
|
worktreePath,
|
|
1942
1944
|
repoPath,
|
|
@@ -1947,7 +1949,7 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
|
|
|
1947
1949
|
return {
|
|
1948
1950
|
ran: true,
|
|
1949
1951
|
exitCode,
|
|
1950
|
-
source
|
|
1952
|
+
source,
|
|
1951
1953
|
kill: handle.kill
|
|
1952
1954
|
};
|
|
1953
1955
|
}
|
|
@@ -1971,11 +1973,9 @@ async function runConventionSetup(repoPath, worktreePath, onLine, opts) {
|
|
|
1971
1973
|
}
|
|
1972
1974
|
async function runWorkspaceSetup(repoPath, worktreePath, onLine, opts) {
|
|
1973
1975
|
await ensureWorktreeSideboardIgnored(worktreePath);
|
|
1974
|
-
const
|
|
1975
|
-
if (
|
|
1976
|
-
onLine?.(
|
|
1977
|
-
`[setup] wrote ${REVIEW_SKILL_PATH} \u2014 commit it so later worktrees inherit Review guidelines`
|
|
1978
|
-
);
|
|
1976
|
+
const review = ensureReviewGuidelinesFile(worktreePath, repoPath);
|
|
1977
|
+
if (review.wrote) {
|
|
1978
|
+
onLine?.(`[setup] wrote ${review.path} \u2014 local Review guidelines`);
|
|
1979
1979
|
}
|
|
1980
1980
|
let setup = await runSetupScript(repoPath, worktreePath, onLine, opts);
|
|
1981
1981
|
if (!setup.ran) {
|
|
@@ -2078,9 +2078,114 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
2078
2078
|
};
|
|
2079
2079
|
}
|
|
2080
2080
|
|
|
2081
|
-
// src/
|
|
2082
|
-
import { existsSync as existsSync5,
|
|
2081
|
+
// src/store/setup-log.ts
|
|
2082
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
2083
2083
|
import { join as join6 } from "path";
|
|
2084
|
+
var EMPTY = {
|
|
2085
|
+
output: "",
|
|
2086
|
+
running: false,
|
|
2087
|
+
exitCode: null,
|
|
2088
|
+
source: null
|
|
2089
|
+
};
|
|
2090
|
+
var memory = /* @__PURE__ */ new Map();
|
|
2091
|
+
var persistTimers = /* @__PURE__ */ new Map();
|
|
2092
|
+
function setupLogPath(threadId) {
|
|
2093
|
+
return join6(threadsDir(), `${threadId}.setup.log.json`);
|
|
2094
|
+
}
|
|
2095
|
+
function emptySetupLog() {
|
|
2096
|
+
return { ...EMPTY };
|
|
2097
|
+
}
|
|
2098
|
+
function clone(snap) {
|
|
2099
|
+
return { ...snap };
|
|
2100
|
+
}
|
|
2101
|
+
function persistNow(threadId) {
|
|
2102
|
+
const timer = persistTimers.get(threadId);
|
|
2103
|
+
if (timer) {
|
|
2104
|
+
clearTimeout(timer);
|
|
2105
|
+
persistTimers.delete(threadId);
|
|
2106
|
+
}
|
|
2107
|
+
const snap = memory.get(threadId);
|
|
2108
|
+
if (!snap) return;
|
|
2109
|
+
try {
|
|
2110
|
+
writeFileSync2(setupLogPath(threadId), `${JSON.stringify(snap)}
|
|
2111
|
+
`, "utf8");
|
|
2112
|
+
} catch {
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
function schedulePersist(threadId) {
|
|
2116
|
+
if (persistTimers.has(threadId)) return;
|
|
2117
|
+
persistTimers.set(
|
|
2118
|
+
threadId,
|
|
2119
|
+
setTimeout(() => {
|
|
2120
|
+
persistTimers.delete(threadId);
|
|
2121
|
+
persistNow(threadId);
|
|
2122
|
+
}, 100)
|
|
2123
|
+
);
|
|
2124
|
+
}
|
|
2125
|
+
function loadFromDisk(threadId) {
|
|
2126
|
+
const path = setupLogPath(threadId);
|
|
2127
|
+
if (!existsSync5(path)) return null;
|
|
2128
|
+
try {
|
|
2129
|
+
const raw = JSON.parse(readFileSync5(path, "utf8"));
|
|
2130
|
+
return {
|
|
2131
|
+
output: typeof raw.output === "string" ? raw.output : "",
|
|
2132
|
+
running: Boolean(raw.running),
|
|
2133
|
+
exitCode: typeof raw.exitCode === "number" ? raw.exitCode : null,
|
|
2134
|
+
source: typeof raw.source === "string" ? raw.source : null
|
|
2135
|
+
};
|
|
2136
|
+
} catch {
|
|
2137
|
+
return null;
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
function readSetupLog(threadId) {
|
|
2141
|
+
const cached = memory.get(threadId);
|
|
2142
|
+
if (cached) return clone(cached);
|
|
2143
|
+
const disk = loadFromDisk(threadId);
|
|
2144
|
+
if (disk) {
|
|
2145
|
+
memory.set(threadId, disk);
|
|
2146
|
+
return clone(disk);
|
|
2147
|
+
}
|
|
2148
|
+
return emptySetupLog();
|
|
2149
|
+
}
|
|
2150
|
+
function beginSetupLog(threadId) {
|
|
2151
|
+
const snap = {
|
|
2152
|
+
output: "",
|
|
2153
|
+
running: true,
|
|
2154
|
+
exitCode: null,
|
|
2155
|
+
source: null
|
|
2156
|
+
};
|
|
2157
|
+
memory.set(threadId, snap);
|
|
2158
|
+
persistNow(threadId);
|
|
2159
|
+
return clone(snap);
|
|
2160
|
+
}
|
|
2161
|
+
function appendSetupLog(threadId, line) {
|
|
2162
|
+
const current = memory.get(threadId) ?? readSetupLog(threadId);
|
|
2163
|
+
const snap = {
|
|
2164
|
+
...current,
|
|
2165
|
+
output: current.output ? `${current.output}
|
|
2166
|
+
${line}` : line,
|
|
2167
|
+
running: true
|
|
2168
|
+
};
|
|
2169
|
+
memory.set(threadId, snap);
|
|
2170
|
+
schedulePersist(threadId);
|
|
2171
|
+
return clone(snap);
|
|
2172
|
+
}
|
|
2173
|
+
function finishSetupLog(threadId, exitCode, source) {
|
|
2174
|
+
const current = memory.get(threadId) ?? readSetupLog(threadId);
|
|
2175
|
+
const snap = {
|
|
2176
|
+
...current,
|
|
2177
|
+
running: false,
|
|
2178
|
+
exitCode,
|
|
2179
|
+
source: source ?? current.source
|
|
2180
|
+
};
|
|
2181
|
+
memory.set(threadId, snap);
|
|
2182
|
+
persistNow(threadId);
|
|
2183
|
+
return clone(snap);
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
// src/git/orphan-cleanup.ts
|
|
2187
|
+
import { existsSync as existsSync6, readdirSync as readdirSync2, statSync } from "fs";
|
|
2188
|
+
import { join as join7 } from "path";
|
|
2084
2189
|
function isSideboardWorktreePath(path) {
|
|
2085
2190
|
return path.includes("/.sideboard/worktrees/") || path.includes("/sideboard/workspaces/");
|
|
2086
2191
|
}
|
|
@@ -2091,7 +2196,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
2091
2196
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
2092
2197
|
);
|
|
2093
2198
|
const homeRoot = sideboardWorkspacesDir();
|
|
2094
|
-
if (
|
|
2199
|
+
if (existsSync6(homeRoot)) {
|
|
2095
2200
|
try {
|
|
2096
2201
|
for (const entry of readdirSync2(homeRoot, { withFileTypes: true })) {
|
|
2097
2202
|
if (!entry.isDirectory()) continue;
|
|
@@ -2103,7 +2208,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
2103
2208
|
const orphans = [];
|
|
2104
2209
|
const seen = /* @__PURE__ */ new Set();
|
|
2105
2210
|
for (const repoPath of repos) {
|
|
2106
|
-
if (!repoPath || !
|
|
2211
|
+
if (!repoPath || !existsSync6(repoPath)) continue;
|
|
2107
2212
|
try {
|
|
2108
2213
|
const wts = await listWorktrees(repoPath);
|
|
2109
2214
|
for (const wt of wts) {
|
|
@@ -2124,12 +2229,12 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
2124
2229
|
}
|
|
2125
2230
|
try {
|
|
2126
2231
|
const root = worktreesRoot(repoPath);
|
|
2127
|
-
if (
|
|
2232
|
+
if (existsSync6(root)) {
|
|
2128
2233
|
for (const entry of readdirSync2(root, { withFileTypes: true })) {
|
|
2129
2234
|
if (!entry.isDirectory()) continue;
|
|
2130
|
-
const path =
|
|
2235
|
+
const path = join7(root, entry.name).replace(/\/$/, "");
|
|
2131
2236
|
if (known.has(path) || seen.has(path)) continue;
|
|
2132
|
-
if (!
|
|
2237
|
+
if (!existsSync6(join7(path, ".git"))) continue;
|
|
2133
2238
|
seen.add(path);
|
|
2134
2239
|
let mtimeMs = 0;
|
|
2135
2240
|
try {
|
|
@@ -2269,8 +2374,8 @@ async function applyThreadIntoMain(thread, opts) {
|
|
|
2269
2374
|
}
|
|
2270
2375
|
|
|
2271
2376
|
// src/git/clone-repo.ts
|
|
2272
|
-
import { existsSync as
|
|
2273
|
-
import { basename as basename2, join as
|
|
2377
|
+
import { existsSync as existsSync7 } from "fs";
|
|
2378
|
+
import { basename as basename2, join as join8 } from "path";
|
|
2274
2379
|
import { execa as execa4 } from "execa";
|
|
2275
2380
|
async function cloneRepoIntoSideboard(opts) {
|
|
2276
2381
|
const url = opts.url.trim();
|
|
@@ -2281,8 +2386,8 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
2281
2386
|
name = leaf || "repo";
|
|
2282
2387
|
}
|
|
2283
2388
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
2284
|
-
const dest =
|
|
2285
|
-
if (
|
|
2389
|
+
const dest = join8(sideboardReposDir(), name);
|
|
2390
|
+
if (existsSync7(dest)) {
|
|
2286
2391
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
2287
2392
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
2288
2393
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -2299,14 +2404,14 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
2299
2404
|
}
|
|
2300
2405
|
|
|
2301
2406
|
// src/store/desktop-host.ts
|
|
2302
|
-
import { readFileSync as
|
|
2303
|
-
import { join as
|
|
2407
|
+
import { readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
2408
|
+
import { join as join9 } from "path";
|
|
2304
2409
|
function desktopHostPidPath() {
|
|
2305
|
-
return
|
|
2410
|
+
return join9(appDataDir(), "desktop-host.pid");
|
|
2306
2411
|
}
|
|
2307
2412
|
function readDesktopHostPid() {
|
|
2308
2413
|
try {
|
|
2309
|
-
const pid = Number.parseInt(
|
|
2414
|
+
const pid = Number.parseInt(readFileSync6(desktopHostPidPath(), "utf8").trim(), 10);
|
|
2310
2415
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
2311
2416
|
return pid;
|
|
2312
2417
|
} catch {
|
|
@@ -2373,7 +2478,7 @@ function notifyParentOfChildHalt(child, status, send) {
|
|
|
2373
2478
|
}
|
|
2374
2479
|
|
|
2375
2480
|
// src/threads/create.ts
|
|
2376
|
-
import { existsSync as
|
|
2481
|
+
import { existsSync as existsSync8 } from "fs";
|
|
2377
2482
|
|
|
2378
2483
|
// src/detect/detect.ts
|
|
2379
2484
|
var REQUIRE_AGENT_TIMEOUT_MS = 8e3;
|
|
@@ -2539,12 +2644,19 @@ function urlsMatch(a, b) {
|
|
|
2539
2644
|
const norm = (u) => u.trim().replace(/\/+$/, "").toLowerCase();
|
|
2540
2645
|
return Boolean(a && b && norm(a) === norm(b));
|
|
2541
2646
|
}
|
|
2647
|
+
function threadPrUrlMatchesNumber(thread, number) {
|
|
2648
|
+
if (!Number.isFinite(number) || number < 1) return false;
|
|
2649
|
+
const url = (thread.prUrl ?? "").trim();
|
|
2650
|
+
if (!url) return false;
|
|
2651
|
+
return new RegExp(`/pull/${number}(?:/|$|[?#])`, "i").test(url);
|
|
2652
|
+
}
|
|
2542
2653
|
function threadMatchesPr(thread, pr) {
|
|
2543
2654
|
const num = String(pr.number);
|
|
2544
2655
|
if (thread.sourceType === "pr" && normalizeIssueKey(thread.sourceRef ?? "") === num) {
|
|
2545
2656
|
return true;
|
|
2546
2657
|
}
|
|
2547
2658
|
if (thread.prUrl && pr.url && urlsMatch(thread.prUrl, pr.url)) return true;
|
|
2659
|
+
if (threadPrUrlMatchesNumber(thread, pr.number)) return true;
|
|
2548
2660
|
const head = pr.headRefName.trim().toLowerCase();
|
|
2549
2661
|
if (!head) return false;
|
|
2550
2662
|
const branch = (thread.branchName ?? "").trim().toLowerCase();
|
|
@@ -2597,19 +2709,32 @@ function findLiveThreadForCreate(input, threads) {
|
|
|
2597
2709
|
(t) => threadMatchesPr(t, {
|
|
2598
2710
|
number: Number.isFinite(number) ? number : -1,
|
|
2599
2711
|
title: input.title ?? "",
|
|
2600
|
-
url: "",
|
|
2601
|
-
headRefName: ""
|
|
2712
|
+
url: input.prUrl ?? "",
|
|
2713
|
+
headRefName: input.headRefName ?? ""
|
|
2602
2714
|
})
|
|
2603
2715
|
);
|
|
2604
2716
|
}
|
|
2605
2717
|
if (input.sourceType === "branch") {
|
|
2606
2718
|
if (isDefaultBranchCreateRef(input.sourceRef)) return void 0;
|
|
2607
|
-
|
|
2719
|
+
const byBranch = live.find(
|
|
2608
2720
|
(t) => threadMatchesBranch(t, {
|
|
2609
2721
|
ref: input.sourceRef,
|
|
2610
2722
|
repoPath: input.repoPath
|
|
2611
2723
|
})
|
|
2612
2724
|
);
|
|
2725
|
+
if (byBranch) return byBranch;
|
|
2726
|
+
if (input.prUrl || input.headRefName) {
|
|
2727
|
+
const number = Number(normalizeIssueKey(input.sourceRef));
|
|
2728
|
+
return live.find(
|
|
2729
|
+
(t) => threadMatchesPr(t, {
|
|
2730
|
+
number: Number.isFinite(number) ? number : -1,
|
|
2731
|
+
title: input.title ?? "",
|
|
2732
|
+
url: input.prUrl ?? "",
|
|
2733
|
+
headRefName: input.headRefName ?? input.sourceRef
|
|
2734
|
+
})
|
|
2735
|
+
);
|
|
2736
|
+
}
|
|
2737
|
+
return void 0;
|
|
2613
2738
|
}
|
|
2614
2739
|
return void 0;
|
|
2615
2740
|
}
|
|
@@ -2835,42 +2960,53 @@ function assembleHomeBoard(input) {
|
|
|
2835
2960
|
}
|
|
2836
2961
|
return { columns, hidden, totals };
|
|
2837
2962
|
}
|
|
2838
|
-
var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards).
|
|
2963
|
+
var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards). Do not create a second worktree for a ticket, PR, or named branch that already has a live checkout \u2014 create_thread / start_board_card return that thread (alreadyStarted). Creating from the default branch still opens a new isolated worktree. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats stay in the sidebar. Do not invent status.";
|
|
2839
2964
|
|
|
2840
2965
|
// src/threads/create.ts
|
|
2841
2966
|
function persistCreateAttachments(worktreePath, attachments) {
|
|
2842
2967
|
return persistPendingFileAttachments(worktreePath, attachments ?? []);
|
|
2843
2968
|
}
|
|
2969
|
+
function liveThreadsForCreate() {
|
|
2970
|
+
return listThreads({ includeArchived: false }).map((t) => ({
|
|
2971
|
+
...t,
|
|
2972
|
+
repoPath: canonicalizeRepoPath(t.repoPath)
|
|
2973
|
+
}));
|
|
2974
|
+
}
|
|
2975
|
+
function reuseLiveThread(input, repoPath, match) {
|
|
2976
|
+
if (input.reuseExisting === false) return void 0;
|
|
2977
|
+
const existing = findLiveThreadForCreate(
|
|
2978
|
+
{
|
|
2979
|
+
sourceType: match.sourceType,
|
|
2980
|
+
sourceRef: match.sourceRef,
|
|
2981
|
+
repoPath,
|
|
2982
|
+
title: match.title ?? input.title,
|
|
2983
|
+
cowboy: input.cowboy,
|
|
2984
|
+
prUrl: match.prUrl,
|
|
2985
|
+
headRefName: match.headRefName
|
|
2986
|
+
},
|
|
2987
|
+
liveThreadsForCreate()
|
|
2988
|
+
);
|
|
2989
|
+
if (!existing) return void 0;
|
|
2990
|
+
const thread = readThread(existing.id) ?? existing;
|
|
2991
|
+
if (!input.attachments?.length) return thread;
|
|
2992
|
+
return updateThread(thread.id, {
|
|
2993
|
+
attachments: persistCreateAttachments(thread.worktreePath, [
|
|
2994
|
+
...thread.attachments,
|
|
2995
|
+
...input.attachments
|
|
2996
|
+
])
|
|
2997
|
+
});
|
|
2998
|
+
}
|
|
2844
2999
|
async function createThread(input, _onSetupLine) {
|
|
2845
3000
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
2846
|
-
if (!
|
|
3001
|
+
if (!existsSync8(repoPath)) {
|
|
2847
3002
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
2848
3003
|
}
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
title: input.title,
|
|
2856
|
-
cowboy: input.cowboy
|
|
2857
|
-
},
|
|
2858
|
-
listThreads({ includeArchived: false }).map((t) => ({
|
|
2859
|
-
...t,
|
|
2860
|
-
repoPath: canonicalizeRepoPath(t.repoPath)
|
|
2861
|
-
}))
|
|
2862
|
-
);
|
|
2863
|
-
if (existing) {
|
|
2864
|
-
const thread2 = readThread(existing.id) ?? existing;
|
|
2865
|
-
if (!input.attachments?.length) return thread2;
|
|
2866
|
-
return updateThread(thread2.id, {
|
|
2867
|
-
attachments: persistCreateAttachments(thread2.worktreePath, [
|
|
2868
|
-
...thread2.attachments,
|
|
2869
|
-
...input.attachments
|
|
2870
|
-
])
|
|
2871
|
-
});
|
|
2872
|
-
}
|
|
2873
|
-
}
|
|
3004
|
+
const reused = reuseLiveThread(input, repoPath, {
|
|
3005
|
+
sourceType: input.sourceType,
|
|
3006
|
+
sourceRef: input.sourceRef,
|
|
3007
|
+
title: input.title
|
|
3008
|
+
});
|
|
3009
|
+
if (reused) return reused;
|
|
2874
3010
|
const resolved = resolveNewThreadOptions({
|
|
2875
3011
|
agent: input.agent,
|
|
2876
3012
|
model: input.model,
|
|
@@ -2879,7 +3015,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2879
3015
|
});
|
|
2880
3016
|
await requireAgent(resolved.agent);
|
|
2881
3017
|
if (input.cowboy) {
|
|
2882
|
-
const { cowboyModeEnabled } = await import("./app-settings-
|
|
3018
|
+
const { cowboyModeEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
2883
3019
|
if (!cowboyModeEnabled()) {
|
|
2884
3020
|
throw new Error(
|
|
2885
3021
|
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
@@ -2937,7 +3073,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2937
3073
|
let sourceIsFork = false;
|
|
2938
3074
|
if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
|
|
2939
3075
|
if (isAbleTimeConnected() && getIssueSource() === "abletime") {
|
|
2940
|
-
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-
|
|
3076
|
+
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-JSTJLXAW.js");
|
|
2941
3077
|
const task = await ensureAbleTimeTask({
|
|
2942
3078
|
title: title?.trim() || "Untitled work",
|
|
2943
3079
|
description: input.prompt?.trim() || void 0
|
|
@@ -2947,6 +3083,12 @@ async function createThread(input, _onSetupLine) {
|
|
|
2947
3083
|
persistedSourceRef = task.identifier;
|
|
2948
3084
|
title = title?.trim() || task.title;
|
|
2949
3085
|
attachments = [...attachments, issueAttachmentForAbleTimeTask(task)];
|
|
3086
|
+
const reusedTicket = reuseLiveThread(
|
|
3087
|
+
{ ...input, sourceType: "ticket", sourceRef, title, attachments },
|
|
3088
|
+
repoPath,
|
|
3089
|
+
{ sourceType: "ticket", sourceRef, title }
|
|
3090
|
+
);
|
|
3091
|
+
if (reusedTicket) return reusedTicket;
|
|
2950
3092
|
}
|
|
2951
3093
|
}
|
|
2952
3094
|
let prUrl = null;
|
|
@@ -2956,6 +3098,14 @@ async function createThread(input, _onSetupLine) {
|
|
|
2956
3098
|
if (!Number.isFinite(num)) throw new Error(`Invalid PR number: ${input.sourceRef}`);
|
|
2957
3099
|
const pr = await getPr(repoPath, num);
|
|
2958
3100
|
if (!pr) throw new Error(`PR #${num} not found`);
|
|
3101
|
+
const reusedPr = reuseLiveThread(input, repoPath, {
|
|
3102
|
+
sourceType: "pr",
|
|
3103
|
+
sourceRef: String(pr.number),
|
|
3104
|
+
title: input.title ?? pr.title,
|
|
3105
|
+
prUrl: pr.url,
|
|
3106
|
+
headRefName: pr.headRefName
|
|
3107
|
+
});
|
|
3108
|
+
if (reusedPr) return reusedPr;
|
|
2959
3109
|
sourceIsFork = pr.isCrossRepository;
|
|
2960
3110
|
prUrl = pr.url;
|
|
2961
3111
|
const localFetchBranch = `sideboard-pr-${pr.number}`;
|
|
@@ -2968,9 +3118,19 @@ async function createThread(input, _onSetupLine) {
|
|
|
2968
3118
|
sourceRef = await resolveDefaultBranch(repoPath);
|
|
2969
3119
|
} else {
|
|
2970
3120
|
const existing = await getPrForHeadBranch(repoPath, sourceRef);
|
|
2971
|
-
if (existing
|
|
2972
|
-
|
|
2973
|
-
|
|
3121
|
+
if (existing) {
|
|
3122
|
+
const reusedPr = reuseLiveThread(input, repoPath, {
|
|
3123
|
+
sourceType: "pr",
|
|
3124
|
+
sourceRef: String(existing.number),
|
|
3125
|
+
title: input.title ?? existing.title,
|
|
3126
|
+
prUrl: existing.url,
|
|
3127
|
+
headRefName: existing.headRefName
|
|
3128
|
+
});
|
|
3129
|
+
if (reusedPr) return reusedPr;
|
|
3130
|
+
if (existing.url) {
|
|
3131
|
+
prUrl = existing.url;
|
|
3132
|
+
prTitle = existing.title;
|
|
3133
|
+
}
|
|
2974
3134
|
}
|
|
2975
3135
|
}
|
|
2976
3136
|
} else if (sourceType === "adopt") {
|
|
@@ -3009,15 +3169,6 @@ async function createThread(input, _onSetupLine) {
|
|
|
3009
3169
|
await ensureWorkspace(repoPath);
|
|
3010
3170
|
return readThread(thread.id) ?? thread;
|
|
3011
3171
|
}
|
|
3012
|
-
async function listLinearIssues(agent, repoPath) {
|
|
3013
|
-
const { getAdapter: getAdapter2 } = await import("./agents-JAOMXDXN.js");
|
|
3014
|
-
await requireAgent(agent, { requireLinear: true });
|
|
3015
|
-
const adapter = getAdapter2(agent);
|
|
3016
|
-
if (!adapter.listLinearIssues) {
|
|
3017
|
-
throw new Error(`${agent} does not support Linear issue listing`);
|
|
3018
|
-
}
|
|
3019
|
-
return adapter.listLinearIssues(repoPath);
|
|
3020
|
-
}
|
|
3021
3172
|
|
|
3022
3173
|
// src/threads/cowboy.ts
|
|
3023
3174
|
function isCowboyThread(thread) {
|
|
@@ -3033,11 +3184,11 @@ function shouldRemoveWorktreeOnTeardown(thread) {
|
|
|
3033
3184
|
|
|
3034
3185
|
// src/store/turn-live.ts
|
|
3035
3186
|
import {
|
|
3036
|
-
existsSync as
|
|
3187
|
+
existsSync as existsSync9,
|
|
3037
3188
|
renameSync,
|
|
3038
3189
|
unlinkSync as unlinkSync2,
|
|
3039
|
-
writeFileSync as
|
|
3040
|
-
readFileSync as
|
|
3190
|
+
writeFileSync as writeFileSync4,
|
|
3191
|
+
readFileSync as readFileSync7
|
|
3041
3192
|
} from "fs";
|
|
3042
3193
|
var buffers = /* @__PURE__ */ new Map();
|
|
3043
3194
|
var FLUSH_MS = 800;
|
|
@@ -3114,7 +3265,7 @@ function writeTurnLive(threadId, progress) {
|
|
|
3114
3265
|
const path = threadLivePath(threadId);
|
|
3115
3266
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
3116
3267
|
try {
|
|
3117
|
-
|
|
3268
|
+
writeFileSync4(tmp, JSON.stringify(progress), "utf8");
|
|
3118
3269
|
renameSync(tmp, path);
|
|
3119
3270
|
} catch {
|
|
3120
3271
|
try {
|
|
@@ -3125,9 +3276,9 @@ function writeTurnLive(threadId, progress) {
|
|
|
3125
3276
|
}
|
|
3126
3277
|
function readTurnLive(threadId) {
|
|
3127
3278
|
const path = threadLivePath(threadId);
|
|
3128
|
-
if (!
|
|
3279
|
+
if (!existsSync9(path)) return null;
|
|
3129
3280
|
try {
|
|
3130
|
-
const raw = JSON.parse(
|
|
3281
|
+
const raw = JSON.parse(readFileSync7(path, "utf8"));
|
|
3131
3282
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
3132
3283
|
return raw;
|
|
3133
3284
|
} catch {
|
|
@@ -3139,7 +3290,7 @@ function clearTurnLive(threadId) {
|
|
|
3139
3290
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
3140
3291
|
buffers.delete(threadId);
|
|
3141
3292
|
const path = threadLivePath(threadId);
|
|
3142
|
-
if (!
|
|
3293
|
+
if (!existsSync9(path)) return;
|
|
3143
3294
|
try {
|
|
3144
3295
|
unlinkSync2(path);
|
|
3145
3296
|
} catch {
|
|
@@ -3323,26 +3474,26 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
|
|
|
3323
3474
|
import { execFileSync } from "child_process";
|
|
3324
3475
|
import {
|
|
3325
3476
|
copyFileSync as copyFileSync2,
|
|
3326
|
-
existsSync as
|
|
3477
|
+
existsSync as existsSync10,
|
|
3327
3478
|
mkdtempSync,
|
|
3328
3479
|
readdirSync as readdirSync3,
|
|
3329
|
-
readFileSync as
|
|
3480
|
+
readFileSync as readFileSync8,
|
|
3330
3481
|
rmSync
|
|
3331
3482
|
} from "fs";
|
|
3332
3483
|
import { tmpdir } from "os";
|
|
3333
|
-
import { join as
|
|
3484
|
+
import { join as join10 } from "path";
|
|
3334
3485
|
import { createRequire } from "module";
|
|
3335
|
-
var CONDUCTOR_APP_SUPPORT =
|
|
3486
|
+
var CONDUCTOR_APP_SUPPORT = join10(
|
|
3336
3487
|
process.env.HOME ?? "",
|
|
3337
3488
|
"Library",
|
|
3338
3489
|
"Application Support",
|
|
3339
3490
|
"com.conductor.app"
|
|
3340
3491
|
);
|
|
3341
|
-
var CONDUCTOR_DB =
|
|
3342
|
-
var CURSOR_SDK_STORE =
|
|
3492
|
+
var CONDUCTOR_DB = join10(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
3493
|
+
var CURSOR_SDK_STORE = join10(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
3343
3494
|
function thisModuleFile() {
|
|
3344
3495
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
3345
|
-
return cjsFile || process.argv[1] ||
|
|
3496
|
+
return cjsFile || process.argv[1] || join10(process.cwd(), "package.json");
|
|
3346
3497
|
}
|
|
3347
3498
|
function openReadonlySqlite(file) {
|
|
3348
3499
|
const req = createRequire(thisModuleFile());
|
|
@@ -3360,7 +3511,7 @@ function mapAgentType(raw) {
|
|
|
3360
3511
|
return null;
|
|
3361
3512
|
}
|
|
3362
3513
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
3363
|
-
if (!workspacePath || !
|
|
3514
|
+
if (!workspacePath || !existsSync10(CURSOR_SDK_STORE)) return null;
|
|
3364
3515
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
3365
3516
|
let best = null;
|
|
3366
3517
|
let hashes;
|
|
@@ -3370,11 +3521,11 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
3370
3521
|
return null;
|
|
3371
3522
|
}
|
|
3372
3523
|
for (const hash of hashes) {
|
|
3373
|
-
const agentsFile =
|
|
3374
|
-
if (!
|
|
3524
|
+
const agentsFile = join10(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
3525
|
+
if (!existsSync10(agentsFile)) continue;
|
|
3375
3526
|
let text;
|
|
3376
3527
|
try {
|
|
3377
|
-
text =
|
|
3528
|
+
text = readFileSync8(agentsFile, "utf8");
|
|
3378
3529
|
} catch {
|
|
3379
3530
|
continue;
|
|
3380
3531
|
}
|
|
@@ -3398,7 +3549,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
3398
3549
|
return best?.agentId ?? null;
|
|
3399
3550
|
}
|
|
3400
3551
|
async function adoptThread(input) {
|
|
3401
|
-
if (!
|
|
3552
|
+
if (!existsSync10(input.worktreePath)) {
|
|
3402
3553
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
3403
3554
|
}
|
|
3404
3555
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -3417,23 +3568,23 @@ async function adoptThread(input) {
|
|
|
3417
3568
|
messages: input.messages ?? []
|
|
3418
3569
|
});
|
|
3419
3570
|
writeThread(thread);
|
|
3420
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
3571
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-MQYNZXUK.js");
|
|
3421
3572
|
await ensureWorkspace2(repoPath);
|
|
3422
3573
|
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
|
|
3423
3574
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
3424
3575
|
return thread;
|
|
3425
3576
|
}
|
|
3426
3577
|
function listConductorWorkspaces() {
|
|
3427
|
-
if (!
|
|
3578
|
+
if (!existsSync10(CONDUCTOR_DB)) {
|
|
3428
3579
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
3429
3580
|
}
|
|
3430
|
-
const tmp = mkdtempSync(
|
|
3431
|
-
const snapshot =
|
|
3581
|
+
const tmp = mkdtempSync(join10(tmpdir(), "sideboard-conductor-"));
|
|
3582
|
+
const snapshot = join10(tmp, "conductor.db");
|
|
3432
3583
|
try {
|
|
3433
3584
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
3434
3585
|
for (const suffix of ["-wal", "-shm"]) {
|
|
3435
3586
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
3436
|
-
if (
|
|
3587
|
+
if (existsSync10(src)) {
|
|
3437
3588
|
try {
|
|
3438
3589
|
copyFileSync2(src, `${snapshot}${suffix}`);
|
|
3439
3590
|
} catch {
|
|
@@ -3515,16 +3666,16 @@ function listConductorWorkspaces() {
|
|
|
3515
3666
|
}
|
|
3516
3667
|
}
|
|
3517
3668
|
function importConductorWorkspace(workspaceId) {
|
|
3518
|
-
if (!
|
|
3669
|
+
if (!existsSync10(CONDUCTOR_DB)) {
|
|
3519
3670
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
3520
3671
|
}
|
|
3521
|
-
const tmp = mkdtempSync(
|
|
3522
|
-
const snapshot =
|
|
3672
|
+
const tmp = mkdtempSync(join10(tmpdir(), "sideboard-conductor-"));
|
|
3673
|
+
const snapshot = join10(tmp, "conductor.db");
|
|
3523
3674
|
try {
|
|
3524
3675
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
3525
3676
|
for (const suffix of ["-wal", "-shm"]) {
|
|
3526
3677
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
3527
|
-
if (
|
|
3678
|
+
if (existsSync10(src)) {
|
|
3528
3679
|
try {
|
|
3529
3680
|
copyFileSync2(src, `${snapshot}${suffix}`);
|
|
3530
3681
|
} catch {
|
|
@@ -3544,7 +3695,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
3544
3695
|
).get(workspaceId);
|
|
3545
3696
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
3546
3697
|
const worktreePath = String(row.workspacePath);
|
|
3547
|
-
if (!
|
|
3698
|
+
if (!existsSync10(worktreePath)) {
|
|
3548
3699
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
3549
3700
|
}
|
|
3550
3701
|
let sessionId = null;
|
|
@@ -3615,7 +3766,7 @@ async function importConductorWorkspaceAsync(workspaceId) {
|
|
|
3615
3766
|
}
|
|
3616
3767
|
|
|
3617
3768
|
// src/threads/stack-layers.ts
|
|
3618
|
-
import { existsSync as
|
|
3769
|
+
import { existsSync as existsSync11 } from "fs";
|
|
3619
3770
|
function stackIdFrom(stack) {
|
|
3620
3771
|
if (stack.stackNumber != null) return `gh-stack-${stack.stackNumber}`;
|
|
3621
3772
|
const key = stack.layers.map((l) => l.branchName).join("|");
|
|
@@ -3678,7 +3829,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
3678
3829
|
let createdWorktree = false;
|
|
3679
3830
|
const trees = await listWorktrees(repoPath);
|
|
3680
3831
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
3681
|
-
if (checkedOut?.path &&
|
|
3832
|
+
if (checkedOut?.path && existsSync11(checkedOut.path)) {
|
|
3682
3833
|
if (input.reuseExistingWorktree !== false) {
|
|
3683
3834
|
worktreePath = checkedOut.path;
|
|
3684
3835
|
} else {
|
|
@@ -3820,7 +3971,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
3820
3971
|
async function createPrStack(input, onSetupLine) {
|
|
3821
3972
|
await requireAgent(input.agent);
|
|
3822
3973
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
3823
|
-
if (!
|
|
3974
|
+
if (!existsSync11(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
3824
3975
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
3825
3976
|
const status = await detectGhStack(repoPath);
|
|
3826
3977
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -3887,7 +4038,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
3887
4038
|
}
|
|
3888
4039
|
}
|
|
3889
4040
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
3890
|
-
if (!claimed.has(bootstrap.worktreePath) &&
|
|
4041
|
+
if (!claimed.has(bootstrap.worktreePath) && existsSync11(bootstrap.worktreePath)) {
|
|
3891
4042
|
try {
|
|
3892
4043
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
3893
4044
|
deleteBranch: bootstrap.branchName
|
|
@@ -3899,10 +4050,10 @@ async function createPrStack(input, onSetupLine) {
|
|
|
3899
4050
|
}
|
|
3900
4051
|
|
|
3901
4052
|
// src/diff/diff.ts
|
|
3902
|
-
import { existsSync as
|
|
3903
|
-
import { dirname as dirname3, join as
|
|
4053
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync3, readFileSync as readFileSync9, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
4054
|
+
import { dirname as dirname3, join as join11 } from "path";
|
|
3904
4055
|
async function inspectGitWorktree(worktreePath) {
|
|
3905
|
-
if (!worktreePath || !
|
|
4056
|
+
if (!worktreePath || !existsSync12(worktreePath)) return "missing_worktree";
|
|
3906
4057
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
3907
4058
|
reject: false
|
|
3908
4059
|
});
|
|
@@ -3910,7 +4061,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
3910
4061
|
return "ok";
|
|
3911
4062
|
}
|
|
3912
4063
|
async function initializeGitRepository(worktreePath) {
|
|
3913
|
-
if (!worktreePath || !
|
|
4064
|
+
if (!worktreePath || !existsSync12(worktreePath)) {
|
|
3914
4065
|
throw new Error("Worktree not found");
|
|
3915
4066
|
}
|
|
3916
4067
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -4046,11 +4197,11 @@ new file mode 100644
|
|
|
4046
4197
|
};
|
|
4047
4198
|
}
|
|
4048
4199
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
4049
|
-
const abs =
|
|
4200
|
+
const abs = join11(worktreePath, path);
|
|
4050
4201
|
try {
|
|
4051
4202
|
const st = statSync2(abs);
|
|
4052
4203
|
if (st.isFile() && st.size > maxHunk) {
|
|
4053
|
-
const buf =
|
|
4204
|
+
const buf = readFileSync9(abs).subarray(0, maxHunk);
|
|
4054
4205
|
return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
|
|
4055
4206
|
}
|
|
4056
4207
|
} catch {
|
|
@@ -4551,7 +4702,7 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
|
4551
4702
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
4552
4703
|
assertSafeRelativePath(relativePath);
|
|
4553
4704
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
4554
|
-
const abs =
|
|
4705
|
+
const abs = join11(worktreePath, relativePath);
|
|
4555
4706
|
const st = statSync2(abs);
|
|
4556
4707
|
if (!st.isFile()) {
|
|
4557
4708
|
throw new Error(`Not a file: ${relativePath}`);
|
|
@@ -4561,7 +4712,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
4561
4712
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
4562
4713
|
);
|
|
4563
4714
|
}
|
|
4564
|
-
const buf =
|
|
4715
|
+
const buf = readFileSync9(abs);
|
|
4565
4716
|
return {
|
|
4566
4717
|
path: relativePath,
|
|
4567
4718
|
contentBase64: buf.toString("base64"),
|
|
@@ -4571,12 +4722,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
4571
4722
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
4572
4723
|
assertSafeRelativePath(relativePath);
|
|
4573
4724
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
4574
|
-
const abs =
|
|
4725
|
+
const abs = join11(worktreePath, relativePath);
|
|
4575
4726
|
const st = statSync2(abs);
|
|
4576
4727
|
if (!st.isFile()) {
|
|
4577
4728
|
throw new Error(`Not a file: ${relativePath}`);
|
|
4578
4729
|
}
|
|
4579
|
-
const buf =
|
|
4730
|
+
const buf = readFileSync9(abs);
|
|
4580
4731
|
if (isImageRelativePath(relativePath)) {
|
|
4581
4732
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
4582
4733
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -4619,9 +4770,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
4619
4770
|
}
|
|
4620
4771
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
4621
4772
|
assertSafeRelativePath(relativePath);
|
|
4622
|
-
const abs =
|
|
4773
|
+
const abs = join11(worktreePath, relativePath);
|
|
4623
4774
|
mkdirSync3(dirname3(abs), { recursive: true });
|
|
4624
|
-
|
|
4775
|
+
writeFileSync5(abs, content, "utf8");
|
|
4625
4776
|
return { path: relativePath };
|
|
4626
4777
|
}
|
|
4627
4778
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -4746,9 +4897,9 @@ async function confirmLand(thread, opts) {
|
|
|
4746
4897
|
}
|
|
4747
4898
|
|
|
4748
4899
|
// src/skills/discover.ts
|
|
4749
|
-
import { existsSync as
|
|
4900
|
+
import { existsSync as existsSync13, readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
|
|
4750
4901
|
import { homedir } from "os";
|
|
4751
|
-
import { join as
|
|
4902
|
+
import { join as join12 } from "path";
|
|
4752
4903
|
|
|
4753
4904
|
// src/skills/bundled/long-running.ts
|
|
4754
4905
|
var LONG_RUNNING_SKILL_COMMAND = "long-running";
|
|
@@ -4816,6 +4967,16 @@ node <detached-job.js> wait --pid-file FILE --log-file FILE [--ok-pattern TEXT]
|
|
|
4816
4967
|
4. On \`ok\`, present once more (\`status=ok\`, last \`delta\`) and finish the task. On \`failed\`, fix from the log.
|
|
4817
4968
|
|
|
4818
4969
|
Never tell the user \u201Csay status when it\u2019s done.\u201D You wait.
|
|
4970
|
+
|
|
4971
|
+
## PR checks (only if a goal is given)
|
|
4972
|
+
|
|
4973
|
+
Do **not** watch after every push. If the user gave a goal (Greptile 5/5, CI green, until checks pass), wait the same way:
|
|
4974
|
+
|
|
4975
|
+
\`\`\`bash
|
|
4976
|
+
node <detached-job.js> start pr-checks -- gh pr checks --watch
|
|
4977
|
+
\`\`\`
|
|
4978
|
+
|
|
4979
|
+
On miss, fix, commit, push, and watch again until the goal is met or you are blocked. Do not ask the human to poll. Do not merge unless asked.
|
|
4819
4980
|
`;
|
|
4820
4981
|
|
|
4821
4982
|
// src/skills/discover.ts
|
|
@@ -4867,7 +5028,7 @@ function parseFrontmatter(content) {
|
|
|
4867
5028
|
}
|
|
4868
5029
|
function readSkill(skillMd, source) {
|
|
4869
5030
|
try {
|
|
4870
|
-
const content =
|
|
5031
|
+
const content = readFileSync10(skillMd, "utf8");
|
|
4871
5032
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
4872
5033
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
4873
5034
|
const name = fmName || dirName;
|
|
@@ -4886,7 +5047,7 @@ function readSkill(skillMd, source) {
|
|
|
4886
5047
|
}
|
|
4887
5048
|
}
|
|
4888
5049
|
function scanSkillsDir(dir, source, out) {
|
|
4889
|
-
if (!
|
|
5050
|
+
if (!existsSync13(dir)) return;
|
|
4890
5051
|
let entries;
|
|
4891
5052
|
try {
|
|
4892
5053
|
entries = readdirSync4(dir);
|
|
@@ -4895,8 +5056,8 @@ function scanSkillsDir(dir, source, out) {
|
|
|
4895
5056
|
}
|
|
4896
5057
|
for (const entry of entries) {
|
|
4897
5058
|
if (entry.startsWith(".")) continue;
|
|
4898
|
-
const skillMd =
|
|
4899
|
-
if (!
|
|
5059
|
+
const skillMd = join12(dir, entry, "SKILL.md");
|
|
5060
|
+
if (!existsSync13(skillMd)) continue;
|
|
4900
5061
|
try {
|
|
4901
5062
|
if (!statSync3(skillMd).isFile()) continue;
|
|
4902
5063
|
} catch {
|
|
@@ -4907,7 +5068,7 @@ function scanSkillsDir(dir, source, out) {
|
|
|
4907
5068
|
}
|
|
4908
5069
|
}
|
|
4909
5070
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
4910
|
-
if (!
|
|
5071
|
+
if (!existsSync13(pluginsRoot)) return;
|
|
4911
5072
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
4912
5073
|
if (depth > 7) return;
|
|
4913
5074
|
let entries;
|
|
@@ -4917,12 +5078,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
|
|
|
4917
5078
|
return;
|
|
4918
5079
|
}
|
|
4919
5080
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
4920
|
-
const skill = readSkill(
|
|
5081
|
+
const skill = readSkill(join12(dir, "SKILL.md"), "cli");
|
|
4921
5082
|
if (skill) out.push(skill);
|
|
4922
5083
|
}
|
|
4923
5084
|
for (const entry of entries) {
|
|
4924
5085
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
4925
|
-
const full =
|
|
5086
|
+
const full = join12(dir, entry);
|
|
4926
5087
|
try {
|
|
4927
5088
|
if (!statSync3(full).isDirectory()) continue;
|
|
4928
5089
|
} catch {
|
|
@@ -4942,17 +5103,17 @@ function discoverSkills(worktreePath) {
|
|
|
4942
5103
|
const home = homedir();
|
|
4943
5104
|
const collected = [];
|
|
4944
5105
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
4945
|
-
scanSkillsDir(
|
|
5106
|
+
scanSkillsDir(join12(worktreePath, rel), "workspace", collected);
|
|
4946
5107
|
}
|
|
4947
5108
|
for (const abs of [
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
5109
|
+
join12(home, ".claude/skills"),
|
|
5110
|
+
join12(home, ".cursor/skills"),
|
|
5111
|
+
join12(home, ".sideboard/skills"),
|
|
5112
|
+
join12(home, ".brightsy/skills")
|
|
4952
5113
|
]) {
|
|
4953
5114
|
scanSkillsDir(abs, "user", collected);
|
|
4954
5115
|
}
|
|
4955
|
-
scanClaudePluginSkills(
|
|
5116
|
+
scanClaudePluginSkills(join12(home, ".claude/plugins"), collected);
|
|
4956
5117
|
collected.push(...bundledSkills());
|
|
4957
5118
|
const rank = {
|
|
4958
5119
|
workspace: 0,
|
|
@@ -4978,7 +5139,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
4978
5139
|
\u2026(truncated)` : body;
|
|
4979
5140
|
}
|
|
4980
5141
|
}
|
|
4981
|
-
const raw =
|
|
5142
|
+
const raw = readFileSync10(skillPath, "utf8");
|
|
4982
5143
|
if (raw.startsWith("---")) {
|
|
4983
5144
|
const end = raw.indexOf("\n---", 3);
|
|
4984
5145
|
if (end >= 0) {
|
|
@@ -5071,26 +5232,26 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
|
|
|
5071
5232
|
}
|
|
5072
5233
|
|
|
5073
5234
|
// src/agents/instructions.ts
|
|
5074
|
-
import { existsSync as
|
|
5075
|
-
import { join as
|
|
5235
|
+
import { existsSync as existsSync15, readFileSync as readFileSync11, statSync as statSync4 } from "fs";
|
|
5236
|
+
import { join as join14 } from "path";
|
|
5076
5237
|
|
|
5077
5238
|
// src/skills/detached-job-path.ts
|
|
5078
|
-
import { existsSync as
|
|
5079
|
-
import { dirname as dirname4, join as
|
|
5239
|
+
import { existsSync as existsSync14 } from "fs";
|
|
5240
|
+
import { dirname as dirname4, join as join13 } from "path";
|
|
5080
5241
|
import { fileURLToPath } from "url";
|
|
5081
5242
|
function packagedDetachedJobPath() {
|
|
5082
5243
|
const dir = packagedMcpDir();
|
|
5083
5244
|
if (!dir) return null;
|
|
5084
|
-
const script =
|
|
5085
|
-
return
|
|
5245
|
+
const script = join13(dir, "scripts", "detached-job.js");
|
|
5246
|
+
return existsSync14(script) ? script : null;
|
|
5086
5247
|
}
|
|
5087
5248
|
function resolveDetachedJobScript() {
|
|
5088
5249
|
const packaged = packagedDetachedJobPath();
|
|
5089
5250
|
if (packaged) return packaged;
|
|
5090
5251
|
let dir = dirname4(fileURLToPath(import.meta.url));
|
|
5091
5252
|
for (let i = 0; i < 8; i++) {
|
|
5092
|
-
const candidate =
|
|
5093
|
-
if (
|
|
5253
|
+
const candidate = join13(dir, "scripts", "detached-job.js");
|
|
5254
|
+
if (existsSync14(candidate)) return candidate;
|
|
5094
5255
|
const parent = dirname4(dir);
|
|
5095
5256
|
if (parent === dir) break;
|
|
5096
5257
|
dir = parent;
|
|
@@ -5181,7 +5342,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
5181
5342
|
"Short git requests from the Sideboard UI are complete instructions \u2014 expand them using the rules above without asking for clarification:"
|
|
5182
5343
|
);
|
|
5183
5344
|
lines.push(
|
|
5184
|
-
'- "Commit and push." \u2192 commit any uncommitted work with a purpose-stating message, then push to origin (updates an existing PR if one is linked).'
|
|
5345
|
+
'- "Commit and push." \u2192 commit any uncommitted work with a purpose-stating message, then push to origin (updates an existing PR if one is linked). Do not start a checks loop unless they gave a goal.'
|
|
5185
5346
|
);
|
|
5186
5347
|
lines.push(
|
|
5187
5348
|
'- "Commit, push, and open a draft PR." \u2192 commit, push, then create a draft PR with `gh pr create --draft -R \u2026` (title/body from the change purpose).'
|
|
@@ -5190,7 +5351,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
5190
5351
|
'- "Commit, push, and open a PR in the browser." \u2192 commit, push, then `gh pr create --web -R \u2026`.'
|
|
5191
5352
|
);
|
|
5192
5353
|
lines.push(
|
|
5193
|
-
'- "Fix CI: <name>." \u2192 investigate that failing check, fix it, commit, and push.'
|
|
5354
|
+
'- "Fix CI: <name>." \u2192 investigate that failing check, fix it, commit, and push. Loop only if they gave a goal to keep going until it passes.'
|
|
5194
5355
|
);
|
|
5195
5356
|
lines.push(
|
|
5196
5357
|
'- "Merge the remote branch (<base>) into your branch and resolve conflicts. Then, commit and push your changes." \u2192 fetch the PR base, merge it into this branch, resolve conflicts carefully, commit, and push until the PR is mergeable.'
|
|
@@ -5202,11 +5363,21 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
5202
5363
|
'- "Merge PR." \u2192 merge this thread\'s open pull request on GitHub (this phrase is the explicit ask). If `gh stack view` shows a stack, use `gh stack merge`; otherwise `gh pr merge` (respect repo defaults / squash vs merge). Do not force-push main/master or merge locally into the main checkout.'
|
|
5203
5364
|
);
|
|
5204
5365
|
lines.push("");
|
|
5366
|
+
lines.push(formatPrGateDirective());
|
|
5367
|
+
lines.push("");
|
|
5205
5368
|
lines.push(formatProcessGuideDirective());
|
|
5206
5369
|
return lines.join("\n");
|
|
5207
5370
|
}
|
|
5208
5371
|
function formatWorktreeReminder() {
|
|
5209
|
-
return "Sideboard worktree: stay in this cwd for all file and git work. Push and open PRs against origin, never upstream. Do not edit the main repo checkout.";
|
|
5372
|
+
return "Sideboard worktree: stay in this cwd for all file and git work. Push and open PRs against origin, never upstream. Do not edit the main repo checkout. If a goal is given (Greptile 5/5, CI green), watch-fix-push until it lands \u2014 do not watch after every push.";
|
|
5373
|
+
}
|
|
5374
|
+
function formatPrGateDirective() {
|
|
5375
|
+
return [
|
|
5376
|
+
"If a goal is given (not after every push):",
|
|
5377
|
+
"- Enter a watch-fix-push loop and stay in it until that goal is met or you are blocked (examples: \u201CGreptile 5/5\u201D, \u201CCI green\u201D, \u201Cuntil checks pass\u201D). Do not stop after one red run or one review cycle.",
|
|
5378
|
+
"- Wait with `/long-running`: `gh pr checks --watch` (add `-R <origin>` when needed). Present the log. Do not ask the human to poll.",
|
|
5379
|
+
"- Greptile 5/5: wait for the greptile check; read the latest `N/5` from the PR body or Greptile\u2019s most recently *updated* issue comment; also fetch unresolved review comments / the \u201CPrompt to fix all with AI\u201D block. Done = **5/5 and zero unresolved Greptile comments**. If Greptile is idle, comment `@greptile review`. Cap about 5 iterations, then report leftovers. Do not merge unless asked."
|
|
5380
|
+
].join("\n");
|
|
5210
5381
|
}
|
|
5211
5382
|
function formatProcessGuideDirective() {
|
|
5212
5383
|
return [
|
|
@@ -5214,7 +5385,7 @@ function formatProcessGuideDirective() {
|
|
|
5214
5385
|
"- Long jobs (pack, test, deploy, anything that may run more than ~30s): Sideboard always provides `/long-running`. Detach and wait \u2014 do not ask the human to poll.",
|
|
5215
5386
|
"- If `.claude/skills/graph-engineering/SKILL.md` exists, follow it (`/graph-engineering`) for migrations, ports, batch fixes, and other fan-out. Judge first; state on disk; grow the rulebook; do not patch around it.",
|
|
5216
5387
|
"- If this same shape of work will happen again, write `.claude/skills/<kebab-name>/SKILL.md` in this worktree (Claude Code project skill). Sideboard `/name`, Claude Code, and `attach` all load that path. Do not leave the method only in chat.",
|
|
5217
|
-
"- Merge-readiness notes:
|
|
5388
|
+
"- Merge-readiness notes: if `.claude/skills/review/SKILL.md` already exists, edit it. Otherwise write them to `.context/review.md` (copied from `.sideboard/review.md` when that file exists). Do not create a review skill.",
|
|
5218
5389
|
"- Do not write new skills under `.sideboard/skills/` (that folder only \u2014 other `.sideboard/` files such as settings.toml are fine). Point Codex/OpenCode at the Claude skill from `AGENTS.md`. Optional: symlink `.cursor/skills/<name>` to the Claude skill.",
|
|
5219
5390
|
"- Skip a guide for a one-off. If a matching skill exists, follow it. Same miss twice \u2192 edit the skill, do not patch around it."
|
|
5220
5391
|
].join("\n");
|
|
@@ -5382,8 +5553,8 @@ async function syncThreadBranchFromGit(threadId) {
|
|
|
5382
5553
|
|
|
5383
5554
|
// src/store/schedules.ts
|
|
5384
5555
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
5385
|
-
import { existsSync as
|
|
5386
|
-
import { join as
|
|
5556
|
+
import { existsSync as existsSync16, readFileSync as readFileSync12 } from "fs";
|
|
5557
|
+
import { join as join15 } from "path";
|
|
5387
5558
|
import { Cron } from "croner";
|
|
5388
5559
|
var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
|
|
5389
5560
|
var UNIT_MS = {
|
|
@@ -5393,7 +5564,7 @@ var UNIT_MS = {
|
|
|
5393
5564
|
d: 864e5
|
|
5394
5565
|
};
|
|
5395
5566
|
function schedulesPath() {
|
|
5396
|
-
return
|
|
5567
|
+
return join15(appDataDir(), "schedules.json");
|
|
5397
5568
|
}
|
|
5398
5569
|
function parseDurationMs(every) {
|
|
5399
5570
|
const m = every.trim().match(DURATION_RE);
|
|
@@ -5493,9 +5664,9 @@ function normalizeTask(raw) {
|
|
|
5493
5664
|
}
|
|
5494
5665
|
function readAll() {
|
|
5495
5666
|
const path = schedulesPath();
|
|
5496
|
-
if (!
|
|
5667
|
+
if (!existsSync16(path)) return [];
|
|
5497
5668
|
try {
|
|
5498
|
-
const parsed = JSON.parse(
|
|
5669
|
+
const parsed = JSON.parse(readFileSync12(path, "utf8"));
|
|
5499
5670
|
if (!Array.isArray(parsed)) return [];
|
|
5500
5671
|
return parsed.map((row) => {
|
|
5501
5672
|
try {
|
|
@@ -5618,7 +5789,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
5618
5789
|
${prompt}`;
|
|
5619
5790
|
}
|
|
5620
5791
|
async function defaultDeps() {
|
|
5621
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
5792
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-ZSSU3FKW.js");
|
|
5622
5793
|
const orch = getOrchestrator2();
|
|
5623
5794
|
return {
|
|
5624
5795
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -5858,7 +6029,7 @@ var Orchestrator = class {
|
|
|
5858
6029
|
}
|
|
5859
6030
|
continue;
|
|
5860
6031
|
}
|
|
5861
|
-
if (!
|
|
6032
|
+
if (!existsSync17(thread.worktreePath)) {
|
|
5862
6033
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
5863
6034
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
5864
6035
|
continue;
|
|
@@ -5877,7 +6048,7 @@ var Orchestrator = class {
|
|
|
5877
6048
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
5878
6049
|
});
|
|
5879
6050
|
}
|
|
5880
|
-
const { autoCleanupOrphansEnabled } = await import("./app-settings-
|
|
6051
|
+
const { autoCleanupOrphansEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
5881
6052
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
5882
6053
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
5883
6054
|
}
|
|
@@ -6117,7 +6288,7 @@ var Orchestrator = class {
|
|
|
6117
6288
|
}
|
|
6118
6289
|
await setup;
|
|
6119
6290
|
if (skipSetup) return;
|
|
6120
|
-
const { autoRunAfterSetupEnabled } = await import("./app-settings-
|
|
6291
|
+
const { autoRunAfterSetupEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
6121
6292
|
if (autoRunAfterSetupEnabled()) {
|
|
6122
6293
|
try {
|
|
6123
6294
|
await this.startDev(threadId);
|
|
@@ -6425,7 +6596,7 @@ var Orchestrator = class {
|
|
|
6425
6596
|
}
|
|
6426
6597
|
const isBrightsy = fresh.agent === "brightsy";
|
|
6427
6598
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
6428
|
-
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-
|
|
6599
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-VRQI3FIE.js");
|
|
6429
6600
|
const gitAuthMode = getGithubGitAuthMode();
|
|
6430
6601
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
6431
6602
|
githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
|
|
@@ -6531,7 +6702,7 @@ var Orchestrator = class {
|
|
|
6531
6702
|
if (!this.stoppedTurns.has(threadId) && this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
|
|
6532
6703
|
const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
|
|
6533
6704
|
if (sessionId) {
|
|
6534
|
-
const { recoverFinishedCursorRun } = await import("./cursor-recover-
|
|
6705
|
+
const { recoverFinishedCursorRun } = await import("./cursor-recover-L5MD6MBO.js");
|
|
6535
6706
|
for (let i = 0; i < 8; i++) {
|
|
6536
6707
|
const recovered = recoverFinishedCursorRun({
|
|
6537
6708
|
agentId: sessionId,
|
|
@@ -6921,6 +7092,15 @@ var Orchestrator = class {
|
|
|
6921
7092
|
getActiveRuns(threadRef) {
|
|
6922
7093
|
return this.requireThread(threadRef).activeRuns ?? [];
|
|
6923
7094
|
}
|
|
7095
|
+
getSetupLog(threadRef) {
|
|
7096
|
+
const thread = this.getThread(threadRef);
|
|
7097
|
+
if (!thread) return readSetupLog(threadRef);
|
|
7098
|
+
const snap = readSetupLog(thread.id);
|
|
7099
|
+
if (snap.running && !this.processes.has(`${thread.id}:setup`)) {
|
|
7100
|
+
return { ...snap, running: false };
|
|
7101
|
+
}
|
|
7102
|
+
return snap;
|
|
7103
|
+
}
|
|
6924
7104
|
async runSetup(threadRef) {
|
|
6925
7105
|
const thread = this.requireThread(threadRef);
|
|
6926
7106
|
this.assertNotGlobal(thread, "Setup");
|
|
@@ -6934,20 +7114,31 @@ var Orchestrator = class {
|
|
|
6934
7114
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6935
7115
|
kill: () => abort.abort()
|
|
6936
7116
|
});
|
|
7117
|
+
beginSetupLog(thread.id);
|
|
6937
7118
|
this.emit({ type: "setup_started", threadId: thread.id });
|
|
7119
|
+
let finished = false;
|
|
7120
|
+
const finish = (exitCode, source) => {
|
|
7121
|
+
if (finished) return;
|
|
7122
|
+
finished = true;
|
|
7123
|
+
finishSetupLog(thread.id, exitCode, source);
|
|
7124
|
+
this.emit({ type: "setup_finished", threadId: thread.id, exitCode });
|
|
7125
|
+
};
|
|
6938
7126
|
try {
|
|
6939
7127
|
const setup = await runWorkspaceSetup(
|
|
6940
7128
|
thread.repoPath,
|
|
6941
7129
|
thread.worktreePath,
|
|
6942
7130
|
(line) => {
|
|
7131
|
+
appendSetupLog(thread.id, line);
|
|
6943
7132
|
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
6944
7133
|
},
|
|
6945
7134
|
{ signal: abort.signal }
|
|
6946
7135
|
);
|
|
6947
7136
|
if (!setup.ran) {
|
|
6948
|
-
|
|
6949
|
-
|
|
6950
|
-
);
|
|
7137
|
+
const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
|
|
7138
|
+
appendSetupLog(thread.id, line);
|
|
7139
|
+
this.emit({ type: "setup_output", threadId: thread.id, line });
|
|
7140
|
+
finish(null, null);
|
|
7141
|
+
throw new Error(line);
|
|
6951
7142
|
}
|
|
6952
7143
|
if (setup.exitCode !== 0 && setup.exitCode !== null) {
|
|
6953
7144
|
const live = readThread(thread.id);
|
|
@@ -6960,8 +7151,11 @@ var Orchestrator = class {
|
|
|
6960
7151
|
});
|
|
6961
7152
|
}
|
|
6962
7153
|
}
|
|
6963
|
-
|
|
7154
|
+
finish(setup.exitCode, setup.source);
|
|
6964
7155
|
return { exitCode: setup.exitCode, source: setup.source };
|
|
7156
|
+
} catch (err) {
|
|
7157
|
+
finish(null, null);
|
|
7158
|
+
throw err;
|
|
6965
7159
|
} finally {
|
|
6966
7160
|
this.processes.delete(key);
|
|
6967
7161
|
}
|
|
@@ -7288,7 +7482,7 @@ var Orchestrator = class {
|
|
|
7288
7482
|
updateThread(thread.id, { title: meta.title });
|
|
7289
7483
|
}
|
|
7290
7484
|
}
|
|
7291
|
-
const { autoArchiveOnMergeEnabled } = await import("./app-settings-
|
|
7485
|
+
const { autoArchiveOnMergeEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
7292
7486
|
const latest = this.requireThread(thread.id);
|
|
7293
7487
|
if (!shouldAutoArchiveOnPrMerge({
|
|
7294
7488
|
previousPrState: prevState || null,
|
|
@@ -7605,7 +7799,7 @@ var Orchestrator = class {
|
|
|
7605
7799
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
7606
7800
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
7607
7801
|
try {
|
|
7608
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
7802
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-MQYNZXUK.js");
|
|
7609
7803
|
await ensureWorkspace2(thread.repoPath);
|
|
7610
7804
|
} catch {
|
|
7611
7805
|
}
|
|
@@ -7632,7 +7826,7 @@ var Orchestrator = class {
|
|
|
7632
7826
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
7633
7827
|
} catch {
|
|
7634
7828
|
}
|
|
7635
|
-
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-
|
|
7829
|
+
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-VRQI3FIE.js");
|
|
7636
7830
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
7637
7831
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
7638
7832
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -7647,19 +7841,19 @@ var Orchestrator = class {
|
|
|
7647
7841
|
throw new Error("Thread is not archived");
|
|
7648
7842
|
}
|
|
7649
7843
|
if (isGlobalThread(thread)) {
|
|
7650
|
-
const { globalAgentCwd } = await import("./paths-
|
|
7844
|
+
const { globalAgentCwd } = await import("./paths-RRCLNSJB.js");
|
|
7651
7845
|
updateThread(thread.id, { worktreePath: globalAgentCwd() });
|
|
7652
7846
|
const restored2 = setStatus(thread.id, "idle");
|
|
7653
7847
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
7654
7848
|
return restored2;
|
|
7655
7849
|
}
|
|
7656
|
-
if (!
|
|
7850
|
+
if (!existsSync17(thread.worktreePath)) {
|
|
7657
7851
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
7658
7852
|
throw new Error(
|
|
7659
7853
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
7660
7854
|
);
|
|
7661
7855
|
}
|
|
7662
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
7856
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-PEWDAX5O.js");
|
|
7663
7857
|
const slug = thread.worktreePath.split("/").pop();
|
|
7664
7858
|
const dest = thread.worktreePath;
|
|
7665
7859
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -7769,7 +7963,7 @@ async function startOrchestration(opts) {
|
|
|
7769
7963
|
sourceRef: "default",
|
|
7770
7964
|
...createOpts
|
|
7771
7965
|
}).catch(async () => {
|
|
7772
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
7966
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-PEWDAX5O.js");
|
|
7773
7967
|
const repo = await resolveRepoRoot2(repoPath);
|
|
7774
7968
|
const def = await resolveDefaultBranch2(repo);
|
|
7775
7969
|
return orch.createThread({
|
|
@@ -7779,7 +7973,7 @@ async function startOrchestration(opts) {
|
|
|
7779
7973
|
repoPath: repo
|
|
7780
7974
|
});
|
|
7781
7975
|
});
|
|
7782
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
7976
|
+
const { updateThread: upd } = await import("./thread-store-MVQU6HPJ.js");
|
|
7783
7977
|
const updated = upd(thread.id, {
|
|
7784
7978
|
sourceType: "orchestration",
|
|
7785
7979
|
sourceRef: goal
|
|
@@ -7812,7 +8006,6 @@ export {
|
|
|
7812
8006
|
findBoardPr,
|
|
7813
8007
|
assembleHomeBoard,
|
|
7814
8008
|
HOME_BOARD_AGENT_HINT,
|
|
7815
|
-
listLinearIssues,
|
|
7816
8009
|
readTurnLive,
|
|
7817
8010
|
resolveScheduleThreadId,
|
|
7818
8011
|
listSchedules,
|