@sideboard-ai/core 0.1.306 → 0.1.308
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/{chunk-OVNIP265.js → chunk-CTFBZZGZ.js} +49 -4
- package/dist/{chunk-WBCKUFXC.js → chunk-GXFOZ5XL.js} +53 -7
- package/dist/{chunk-5SFA27CF.js → chunk-HRPSFU4Q.js} +13 -2
- package/dist/{chunk-32IN7PXB.js → chunk-T6TEANP5.js} +31 -7
- package/dist/{conductor-ZFRXTVGP.js → conductor-E6M3BATZ.js} +1 -1
- package/dist/{conductor-YBXURAUL.js → conductor-IPIMGUR4.js} +1 -1
- package/dist/index.cjs +121 -17
- package/dist/index.d.cts +64 -1
- package/dist/index.d.ts +64 -1
- package/dist/index.js +32 -14
- package/dist/mcp/run-stdio.cjs +41 -6
- package/dist/mcp/run-stdio.js +2 -2
- package/dist/{orchestrator-UXHU766C.js → orchestrator-JTDQ47H7.js} +2 -2
- package/dist/{orchestrator-XP5S4E5F.js → orchestrator-SJU5LYAO.js} +2 -2
- package/package.json +1 -1
|
@@ -1288,12 +1288,23 @@ function isAskUserToolName(name) {
|
|
|
1288
1288
|
const base = name.replace(/^mcp__sideboard__/i, "");
|
|
1289
1289
|
return ASK_USER_TOOL_RE.test(name) || /^ask_user$/i.test(base);
|
|
1290
1290
|
}
|
|
1291
|
+
function questionsFromToolPart(part) {
|
|
1292
|
+
const fromInput = parsePlanQuestionsInput(part.input);
|
|
1293
|
+
if (fromInput.length) return fromInput;
|
|
1294
|
+
const raw = part.result?.trim();
|
|
1295
|
+
if (!raw || !raw.startsWith("{")) return [];
|
|
1296
|
+
try {
|
|
1297
|
+
return parsePlanQuestionsInput(JSON.parse(raw));
|
|
1298
|
+
} catch {
|
|
1299
|
+
return [];
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1291
1302
|
function extractPendingPlanQuestions(parts) {
|
|
1292
1303
|
if (!parts?.length) return null;
|
|
1293
1304
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
1294
1305
|
const p = parts[i];
|
|
1295
1306
|
if (p.type !== "tool" || !isAskUserToolName(p.name)) continue;
|
|
1296
|
-
const questions =
|
|
1307
|
+
const questions = questionsFromToolPart(p);
|
|
1297
1308
|
if (!questions.length) continue;
|
|
1298
1309
|
return {
|
|
1299
1310
|
id: p.id || `ask-${i}`,
|
|
@@ -1304,13 +1315,47 @@ function extractPendingPlanQuestions(parts) {
|
|
|
1304
1315
|
}
|
|
1305
1316
|
return null;
|
|
1306
1317
|
}
|
|
1318
|
+
function pendingFromAskBlock(block, dismissedQuestionSignature) {
|
|
1319
|
+
if (!block || block.source !== "ask_user" || !block.questions?.length) return null;
|
|
1320
|
+
const dismissed = dismissedQuestionSignature?.trim();
|
|
1321
|
+
if (dismissed && (!block.questionSignature || block.questionSignature === dismissed)) {
|
|
1322
|
+
return null;
|
|
1323
|
+
}
|
|
1324
|
+
const signature = block.questionSignature?.trim() || planQuestionsSignature(block.questions);
|
|
1325
|
+
return {
|
|
1326
|
+
id: `ask-block:${signature}`,
|
|
1327
|
+
signature,
|
|
1328
|
+
questions: block.questions,
|
|
1329
|
+
source: "ask_user"
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
function askBlockStillWaiting(block, messages) {
|
|
1333
|
+
const askedAt = block?.at;
|
|
1334
|
+
if (!askedAt) return false;
|
|
1335
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1336
|
+
const message = messages[i];
|
|
1337
|
+
if (message.role !== "user" || message.origin === "continue") continue;
|
|
1338
|
+
if (!message.ts) return true;
|
|
1339
|
+
return askedAt > message.ts;
|
|
1340
|
+
}
|
|
1341
|
+
return true;
|
|
1342
|
+
}
|
|
1307
1343
|
function latestPendingPlanQuestions(input) {
|
|
1308
1344
|
if (input.userReplied) return null;
|
|
1309
1345
|
const fromLive = extractPendingPlanQuestions(input.liveParts);
|
|
1310
1346
|
if (fromLive) return fromLive;
|
|
1311
1347
|
const last = input.messages[input.messages.length - 1];
|
|
1312
|
-
if (last?.role === "
|
|
1313
|
-
|
|
1348
|
+
if (last?.role === "agent") {
|
|
1349
|
+
const fromParts = extractPendingPlanQuestions(last.parts);
|
|
1350
|
+
if (fromParts) return fromParts;
|
|
1351
|
+
}
|
|
1352
|
+
const fromBlock = pendingFromAskBlock(
|
|
1353
|
+
input.agentBlock,
|
|
1354
|
+
input.dismissedQuestionSignature
|
|
1355
|
+
);
|
|
1356
|
+
if (fromBlock && askBlockStillWaiting(input.agentBlock, input.messages)) {
|
|
1357
|
+
return fromBlock;
|
|
1358
|
+
}
|
|
1314
1359
|
return null;
|
|
1315
1360
|
}
|
|
1316
1361
|
var PLAN_QUESTION_ANSWERS_PREFIX = "Answers to your questions:";
|
|
@@ -1778,7 +1823,7 @@ var PORT_RANGE_SIZE = 10;
|
|
|
1778
1823
|
var RECLAIM_RETRY_DELAY_MS = 40;
|
|
1779
1824
|
var RECLAIM_TRIES = 8;
|
|
1780
1825
|
async function killReclaimable(ports, worktreePath, signal) {
|
|
1781
|
-
const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-
|
|
1826
|
+
const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-IPIMGUR4.js");
|
|
1782
1827
|
if (worktreePath) killStaleWorktreeListeners2(ports, worktreePath, signal);
|
|
1783
1828
|
else killListenersOnPorts2(ports);
|
|
1784
1829
|
}
|
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
worktreeDevProcessKey,
|
|
56
56
|
worktreeRunProcessKey,
|
|
57
57
|
worktreeSetupProcessKey
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-CTFBZZGZ.js";
|
|
59
59
|
import {
|
|
60
60
|
applyAgentEvent,
|
|
61
61
|
clipAgentEventForPaint,
|
|
@@ -1654,6 +1654,23 @@ function worktreeAgentBlock(group) {
|
|
|
1654
1654
|
}
|
|
1655
1655
|
return best;
|
|
1656
1656
|
}
|
|
1657
|
+
function sidebarRowAgentBlock(group, opts) {
|
|
1658
|
+
if (opts.active) {
|
|
1659
|
+
const open = group.find((thread) => thread.id === opts.selectedId);
|
|
1660
|
+
if (open) return visibleAgentBlock(open);
|
|
1661
|
+
}
|
|
1662
|
+
return worktreeAgentBlock(group);
|
|
1663
|
+
}
|
|
1664
|
+
function sidebarParentSelectId(group, primaryId, opts) {
|
|
1665
|
+
if (opts.active) return primaryId;
|
|
1666
|
+
return sidebarQuestionThreadId(group, primaryId);
|
|
1667
|
+
}
|
|
1668
|
+
function sidebarQuestionThreadId(group, primaryId) {
|
|
1669
|
+
const block = worktreeAgentBlock(group);
|
|
1670
|
+
if (!block) return primaryId;
|
|
1671
|
+
const owner = group.find((thread) => visibleAgentBlock(thread) === block);
|
|
1672
|
+
return owner?.id ?? primaryId;
|
|
1673
|
+
}
|
|
1657
1674
|
function threadCardBlockFields(group) {
|
|
1658
1675
|
const block = worktreeAgentBlock(group);
|
|
1659
1676
|
return block ? { blockedReason: block.reason, blockedSource: block.source } : null;
|
|
@@ -1800,7 +1817,7 @@ function decisionBlockFromParts(parts, planMode, at = (/* @__PURE__ */ new Date(
|
|
|
1800
1817
|
const reason = pending ? formatAskUserNotifyMessage(pending.questions) : "Waiting for an answer in that chat.";
|
|
1801
1818
|
return {
|
|
1802
1819
|
...makeAgentBlock("ask_user", reason, at),
|
|
1803
|
-
...pending ? { questionSignature: pending.signature } : {}
|
|
1820
|
+
...pending ? { questionSignature: pending.signature, questions: pending.questions } : {}
|
|
1804
1821
|
};
|
|
1805
1822
|
}
|
|
1806
1823
|
if (!planMode || last?.type !== "tool") return null;
|
|
@@ -1815,14 +1832,24 @@ function decisionBlockFromParts(parts, planMode, at = (/* @__PURE__ */ new Date(
|
|
|
1815
1832
|
at
|
|
1816
1833
|
);
|
|
1817
1834
|
}
|
|
1835
|
+
function withStampedQuestions(decision, existing) {
|
|
1836
|
+
if (decision.source !== "ask_user" || decision.questions?.length) return decision;
|
|
1837
|
+
if (existing?.source !== "ask_user" || !existing.questions?.length) return decision;
|
|
1838
|
+
return {
|
|
1839
|
+
...decision,
|
|
1840
|
+
questions: existing.questions,
|
|
1841
|
+
questionSignature: decision.questionSignature ?? existing.questionSignature
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1818
1844
|
function agentBlockAfterTurn(input) {
|
|
1819
1845
|
if (input.failed) return null;
|
|
1820
1846
|
const decision = decisionBlockFromParts(input.parts, input.planMode);
|
|
1821
1847
|
if (decision) {
|
|
1822
|
-
|
|
1848
|
+
const next = withStampedQuestions(decision, input.existing);
|
|
1849
|
+
if (isDismissedAskUserBlock(next, input.dismissedQuestionSignature)) {
|
|
1823
1850
|
return input.existing?.source === "reported" ? input.existing : null;
|
|
1824
1851
|
}
|
|
1825
|
-
return
|
|
1852
|
+
return next;
|
|
1826
1853
|
}
|
|
1827
1854
|
if (input.existing && input.existing.source !== "reported" && lastTopLevelTool(input.parts)) {
|
|
1828
1855
|
return null;
|
|
@@ -1865,7 +1892,7 @@ function settleAgentBlock(threadId, parts, failed) {
|
|
|
1865
1892
|
});
|
|
1866
1893
|
const prev = thread.agentBlock ?? null;
|
|
1867
1894
|
if (prev === next) return;
|
|
1868
|
-
if (prev && next && prev.source === next.source && prev.reason === next.reason && prev.at === next.at && prev.questionSignature === next.questionSignature) {
|
|
1895
|
+
if (prev && next && prev.source === next.source && prev.reason === next.reason && prev.at === next.at && prev.questionSignature === next.questionSignature && planQuestionsSignature(prev.questions ?? []) === planQuestionsSignature(next.questions ?? [])) {
|
|
1869
1896
|
return;
|
|
1870
1897
|
}
|
|
1871
1898
|
updateThread(threadId, { agentBlock: next });
|
|
@@ -1888,7 +1915,11 @@ function stampAskUserBlock(resolveCaller, questions) {
|
|
|
1888
1915
|
try {
|
|
1889
1916
|
writeAgentBlock(
|
|
1890
1917
|
resolveCaller().id,
|
|
1891
|
-
parsed.length ? {
|
|
1918
|
+
parsed.length ? {
|
|
1919
|
+
...block,
|
|
1920
|
+
questionSignature: planQuestionsSignature(parsed),
|
|
1921
|
+
questions: parsed
|
|
1922
|
+
} : block
|
|
1892
1923
|
);
|
|
1893
1924
|
} catch {
|
|
1894
1925
|
}
|
|
@@ -5837,6 +5868,15 @@ function connectedOrchestratorTurnReminder(thread, find) {
|
|
|
5837
5868
|
function formatWorktreeReminder() {
|
|
5838
5869
|
return "Sideboard workspace: 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. Schedules: create_schedule (at / every / cron; chatId=self for this chat). set_workspace_tags updates labels on this workspace (omit ref).";
|
|
5839
5870
|
}
|
|
5871
|
+
function formatClaudeSubagentReminder() {
|
|
5872
|
+
return 'Claude subagents: if Task/Agent workers will edit files, write a short plan in this chat and continue in the same turn. Do not ask the user whether to isolate, and do not set worktree.bgIsolation to none. One writer may edit this workspace. Every other writer is an Agent with isolation "worktree" and a disjoint file list (read-only explore agents may overlap). While those agents run, leave their files alone. Merge each returned branch into this workspace, then remove the temporary worktree. You stay in this cwd. If Claude says another write-capable agent is in this directory, or that writes to the shared checkout are blocked, re-spawn that agent with isolation "worktree" or make the edit yourself.';
|
|
5873
|
+
}
|
|
5874
|
+
function claudeSubagentTurnReminder(thread) {
|
|
5875
|
+
if (thread.agent !== "claude" || thread.planMode || isOrchestratorThread(thread)) {
|
|
5876
|
+
return null;
|
|
5877
|
+
}
|
|
5878
|
+
return formatClaudeSubagentReminder();
|
|
5879
|
+
}
|
|
5840
5880
|
var PR_GOAL_RE = /greptile|\bci\b.*\b(green|pass)|checks?\s+(pass|green)|until\s+.*\b(pass|green|merge|clean)|\bfix ci\b|watch[- ]fix[- ]push/i;
|
|
5841
5881
|
function mentionsPrGoal(prompt) {
|
|
5842
5882
|
return PR_GOAL_RE.test(prompt);
|
|
@@ -6701,7 +6741,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
6701
6741
|
${prompt}`;
|
|
6702
6742
|
}
|
|
6703
6743
|
async function defaultDeps() {
|
|
6704
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
6744
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-SJU5LYAO.js");
|
|
6705
6745
|
const orch = getOrchestrator2();
|
|
6706
6746
|
return {
|
|
6707
6747
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -7773,6 +7813,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
7773
7813
|
);
|
|
7774
7814
|
const turnReminders = [
|
|
7775
7815
|
worktreeReminder,
|
|
7816
|
+
claudeSubagentTurnReminder(thread),
|
|
7776
7817
|
connectedOrchestratorTurnReminder(thread, (id) => readThread(id)),
|
|
7777
7818
|
optionalServicesReminder,
|
|
7778
7819
|
issueToolsReminder,
|
|
@@ -9611,6 +9652,9 @@ export {
|
|
|
9611
9652
|
worktreeBoardStatus,
|
|
9612
9653
|
visibleAgentBlock,
|
|
9613
9654
|
worktreeAgentBlock,
|
|
9655
|
+
sidebarRowAgentBlock,
|
|
9656
|
+
sidebarParentSelectId,
|
|
9657
|
+
sidebarQuestionThreadId,
|
|
9614
9658
|
reviewLabelForRepo,
|
|
9615
9659
|
classifyWorktreeListBadges,
|
|
9616
9660
|
isHomeBoardThread,
|
|
@@ -9764,6 +9808,8 @@ export {
|
|
|
9764
9808
|
formatConnectedOrchestratorReminder,
|
|
9765
9809
|
connectedOrchestratorTurnReminder,
|
|
9766
9810
|
formatWorktreeReminder,
|
|
9811
|
+
formatClaudeSubagentReminder,
|
|
9812
|
+
claudeSubagentTurnReminder,
|
|
9767
9813
|
mentionsPrGoal,
|
|
9768
9814
|
issueTicketFromThread,
|
|
9769
9815
|
linearTicketIdFromThread,
|
|
@@ -1235,12 +1235,23 @@ function isAskUserToolName(name) {
|
|
|
1235
1235
|
const base = name.replace(/^mcp__sideboard__/i, "");
|
|
1236
1236
|
return ASK_USER_TOOL_RE.test(name) || /^ask_user$/i.test(base);
|
|
1237
1237
|
}
|
|
1238
|
+
function questionsFromToolPart(part) {
|
|
1239
|
+
const fromInput = parsePlanQuestionsInput(part.input);
|
|
1240
|
+
if (fromInput.length) return fromInput;
|
|
1241
|
+
const raw = part.result?.trim();
|
|
1242
|
+
if (!raw || !raw.startsWith("{")) return [];
|
|
1243
|
+
try {
|
|
1244
|
+
return parsePlanQuestionsInput(JSON.parse(raw));
|
|
1245
|
+
} catch {
|
|
1246
|
+
return [];
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1238
1249
|
function extractPendingPlanQuestions(parts) {
|
|
1239
1250
|
if (!parts?.length) return null;
|
|
1240
1251
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
1241
1252
|
const p = parts[i];
|
|
1242
1253
|
if (p.type !== "tool" || !isAskUserToolName(p.name)) continue;
|
|
1243
|
-
const questions =
|
|
1254
|
+
const questions = questionsFromToolPart(p);
|
|
1244
1255
|
if (!questions.length) continue;
|
|
1245
1256
|
return {
|
|
1246
1257
|
id: p.id || `ask-${i}`,
|
|
@@ -1676,7 +1687,7 @@ var PORT_RANGE_SIZE = 10;
|
|
|
1676
1687
|
var RECLAIM_RETRY_DELAY_MS = 40;
|
|
1677
1688
|
var RECLAIM_TRIES = 8;
|
|
1678
1689
|
async function killReclaimable(ports, worktreePath, signal) {
|
|
1679
|
-
const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-
|
|
1690
|
+
const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-E6M3BATZ.js");
|
|
1680
1691
|
if (worktreePath) killStaleWorktreeListeners2(ports, worktreePath, signal);
|
|
1681
1692
|
else killListenersOnPorts2(ports);
|
|
1682
1693
|
}
|
|
@@ -68,7 +68,7 @@ import {
|
|
|
68
68
|
worktreeDevProcessKey,
|
|
69
69
|
worktreeRunProcessKey,
|
|
70
70
|
worktreeSetupProcessKey
|
|
71
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-HRPSFU4Q.js";
|
|
72
72
|
import {
|
|
73
73
|
applyAgentEvent,
|
|
74
74
|
clipAgentEventForPaint,
|
|
@@ -1703,7 +1703,7 @@ function decisionBlockFromParts(parts, planMode, at = (/* @__PURE__ */ new Date(
|
|
|
1703
1703
|
const reason = pending ? formatAskUserNotifyMessage(pending.questions) : "Waiting for an answer in that chat.";
|
|
1704
1704
|
return {
|
|
1705
1705
|
...makeAgentBlock("ask_user", reason, at),
|
|
1706
|
-
...pending ? { questionSignature: pending.signature } : {}
|
|
1706
|
+
...pending ? { questionSignature: pending.signature, questions: pending.questions } : {}
|
|
1707
1707
|
};
|
|
1708
1708
|
}
|
|
1709
1709
|
if (!planMode || last?.type !== "tool") return null;
|
|
@@ -1718,14 +1718,24 @@ function decisionBlockFromParts(parts, planMode, at = (/* @__PURE__ */ new Date(
|
|
|
1718
1718
|
at
|
|
1719
1719
|
);
|
|
1720
1720
|
}
|
|
1721
|
+
function withStampedQuestions(decision, existing) {
|
|
1722
|
+
if (decision.source !== "ask_user" || decision.questions?.length) return decision;
|
|
1723
|
+
if (existing?.source !== "ask_user" || !existing.questions?.length) return decision;
|
|
1724
|
+
return {
|
|
1725
|
+
...decision,
|
|
1726
|
+
questions: existing.questions,
|
|
1727
|
+
questionSignature: decision.questionSignature ?? existing.questionSignature
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1721
1730
|
function agentBlockAfterTurn(input) {
|
|
1722
1731
|
if (input.failed) return null;
|
|
1723
1732
|
const decision = decisionBlockFromParts(input.parts, input.planMode);
|
|
1724
1733
|
if (decision) {
|
|
1725
|
-
|
|
1734
|
+
const next = withStampedQuestions(decision, input.existing);
|
|
1735
|
+
if (isDismissedAskUserBlock(next, input.dismissedQuestionSignature)) {
|
|
1726
1736
|
return input.existing?.source === "reported" ? input.existing : null;
|
|
1727
1737
|
}
|
|
1728
|
-
return
|
|
1738
|
+
return next;
|
|
1729
1739
|
}
|
|
1730
1740
|
if (input.existing && input.existing.source !== "reported" && lastTopLevelTool(input.parts)) {
|
|
1731
1741
|
return null;
|
|
@@ -1768,7 +1778,7 @@ function settleAgentBlock(threadId, parts, failed) {
|
|
|
1768
1778
|
});
|
|
1769
1779
|
const prev = thread.agentBlock ?? null;
|
|
1770
1780
|
if (prev === next) return;
|
|
1771
|
-
if (prev && next && prev.source === next.source && prev.reason === next.reason && prev.at === next.at && prev.questionSignature === next.questionSignature) {
|
|
1781
|
+
if (prev && next && prev.source === next.source && prev.reason === next.reason && prev.at === next.at && prev.questionSignature === next.questionSignature && planQuestionsSignature(prev.questions ?? []) === planQuestionsSignature(next.questions ?? [])) {
|
|
1772
1782
|
return;
|
|
1773
1783
|
}
|
|
1774
1784
|
updateThread(threadId, { agentBlock: next });
|
|
@@ -1791,7 +1801,11 @@ function stampAskUserBlock(resolveCaller, questions) {
|
|
|
1791
1801
|
try {
|
|
1792
1802
|
writeAgentBlock(
|
|
1793
1803
|
resolveCaller().id,
|
|
1794
|
-
parsed.length ? {
|
|
1804
|
+
parsed.length ? {
|
|
1805
|
+
...block,
|
|
1806
|
+
questionSignature: planQuestionsSignature(parsed),
|
|
1807
|
+
questions: parsed
|
|
1808
|
+
} : block
|
|
1795
1809
|
);
|
|
1796
1810
|
} catch {
|
|
1797
1811
|
}
|
|
@@ -5533,6 +5547,15 @@ function connectedOrchestratorTurnReminder(thread, find) {
|
|
|
5533
5547
|
function formatWorktreeReminder() {
|
|
5534
5548
|
return "Sideboard workspace: 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. Schedules: create_schedule (at / every / cron; chatId=self for this chat). set_workspace_tags updates labels on this workspace (omit ref).";
|
|
5535
5549
|
}
|
|
5550
|
+
function formatClaudeSubagentReminder() {
|
|
5551
|
+
return 'Claude subagents: if Task/Agent workers will edit files, write a short plan in this chat and continue in the same turn. Do not ask the user whether to isolate, and do not set worktree.bgIsolation to none. One writer may edit this workspace. Every other writer is an Agent with isolation "worktree" and a disjoint file list (read-only explore agents may overlap). While those agents run, leave their files alone. Merge each returned branch into this workspace, then remove the temporary worktree. You stay in this cwd. If Claude says another write-capable agent is in this directory, or that writes to the shared checkout are blocked, re-spawn that agent with isolation "worktree" or make the edit yourself.';
|
|
5552
|
+
}
|
|
5553
|
+
function claudeSubagentTurnReminder(thread) {
|
|
5554
|
+
if (thread.agent !== "claude" || thread.planMode || isOrchestratorThread(thread)) {
|
|
5555
|
+
return null;
|
|
5556
|
+
}
|
|
5557
|
+
return formatClaudeSubagentReminder();
|
|
5558
|
+
}
|
|
5536
5559
|
var PR_GOAL_RE = /greptile|\bci\b.*\b(green|pass)|checks?\s+(pass|green)|until\s+.*\b(pass|green|merge|clean)|\bfix ci\b|watch[- ]fix[- ]push/i;
|
|
5537
5560
|
function mentionsPrGoal(prompt) {
|
|
5538
5561
|
return PR_GOAL_RE.test(prompt);
|
|
@@ -6366,7 +6389,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
6366
6389
|
${prompt}`;
|
|
6367
6390
|
}
|
|
6368
6391
|
async function defaultDeps() {
|
|
6369
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
6392
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-JTDQ47H7.js");
|
|
6370
6393
|
const orch = getOrchestrator2();
|
|
6371
6394
|
return {
|
|
6372
6395
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -7438,6 +7461,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
7438
7461
|
);
|
|
7439
7462
|
const turnReminders = [
|
|
7440
7463
|
worktreeReminder,
|
|
7464
|
+
claudeSubagentTurnReminder(thread),
|
|
7441
7465
|
connectedOrchestratorTurnReminder(thread, (id) => readThread(id)),
|
|
7442
7466
|
optionalServicesReminder,
|
|
7443
7467
|
issueToolsReminder,
|
package/dist/index.cjs
CHANGED
|
@@ -6746,6 +6746,23 @@ function worktreeAgentBlock(group) {
|
|
|
6746
6746
|
}
|
|
6747
6747
|
return best;
|
|
6748
6748
|
}
|
|
6749
|
+
function sidebarRowAgentBlock(group, opts) {
|
|
6750
|
+
if (opts.active) {
|
|
6751
|
+
const open = group.find((thread) => thread.id === opts.selectedId);
|
|
6752
|
+
if (open) return visibleAgentBlock(open);
|
|
6753
|
+
}
|
|
6754
|
+
return worktreeAgentBlock(group);
|
|
6755
|
+
}
|
|
6756
|
+
function sidebarParentSelectId(group, primaryId, opts) {
|
|
6757
|
+
if (opts.active) return primaryId;
|
|
6758
|
+
return sidebarQuestionThreadId(group, primaryId);
|
|
6759
|
+
}
|
|
6760
|
+
function sidebarQuestionThreadId(group, primaryId) {
|
|
6761
|
+
const block = worktreeAgentBlock(group);
|
|
6762
|
+
if (!block) return primaryId;
|
|
6763
|
+
const owner = group.find((thread) => visibleAgentBlock(thread) === block);
|
|
6764
|
+
return owner?.id ?? primaryId;
|
|
6765
|
+
}
|
|
6749
6766
|
function threadCardBlockFields(group) {
|
|
6750
6767
|
const block = worktreeAgentBlock(group);
|
|
6751
6768
|
return block ? { blockedReason: block.reason, blockedSource: block.source } : null;
|
|
@@ -8339,12 +8356,23 @@ function isAskUserToolName(name) {
|
|
|
8339
8356
|
const base = name.replace(/^mcp__sideboard__/i, "");
|
|
8340
8357
|
return ASK_USER_TOOL_RE.test(name) || /^ask_user$/i.test(base);
|
|
8341
8358
|
}
|
|
8359
|
+
function questionsFromToolPart(part) {
|
|
8360
|
+
const fromInput = parsePlanQuestionsInput(part.input);
|
|
8361
|
+
if (fromInput.length) return fromInput;
|
|
8362
|
+
const raw = part.result?.trim();
|
|
8363
|
+
if (!raw || !raw.startsWith("{")) return [];
|
|
8364
|
+
try {
|
|
8365
|
+
return parsePlanQuestionsInput(JSON.parse(raw));
|
|
8366
|
+
} catch {
|
|
8367
|
+
return [];
|
|
8368
|
+
}
|
|
8369
|
+
}
|
|
8342
8370
|
function extractPendingPlanQuestions(parts) {
|
|
8343
8371
|
if (!parts?.length) return null;
|
|
8344
8372
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
8345
8373
|
const p = parts[i];
|
|
8346
8374
|
if (p.type !== "tool" || !isAskUserToolName(p.name)) continue;
|
|
8347
|
-
const questions2 =
|
|
8375
|
+
const questions2 = questionsFromToolPart(p);
|
|
8348
8376
|
if (!questions2.length) continue;
|
|
8349
8377
|
return {
|
|
8350
8378
|
id: p.id || `ask-${i}`,
|
|
@@ -8355,13 +8383,47 @@ function extractPendingPlanQuestions(parts) {
|
|
|
8355
8383
|
}
|
|
8356
8384
|
return null;
|
|
8357
8385
|
}
|
|
8386
|
+
function pendingFromAskBlock(block, dismissedQuestionSignature) {
|
|
8387
|
+
if (!block || block.source !== "ask_user" || !block.questions?.length) return null;
|
|
8388
|
+
const dismissed = dismissedQuestionSignature?.trim();
|
|
8389
|
+
if (dismissed && (!block.questionSignature || block.questionSignature === dismissed)) {
|
|
8390
|
+
return null;
|
|
8391
|
+
}
|
|
8392
|
+
const signature = block.questionSignature?.trim() || planQuestionsSignature(block.questions);
|
|
8393
|
+
return {
|
|
8394
|
+
id: `ask-block:${signature}`,
|
|
8395
|
+
signature,
|
|
8396
|
+
questions: block.questions,
|
|
8397
|
+
source: "ask_user"
|
|
8398
|
+
};
|
|
8399
|
+
}
|
|
8400
|
+
function askBlockStillWaiting(block, messages) {
|
|
8401
|
+
const askedAt = block?.at;
|
|
8402
|
+
if (!askedAt) return false;
|
|
8403
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
8404
|
+
const message = messages[i];
|
|
8405
|
+
if (message.role !== "user" || message.origin === "continue") continue;
|
|
8406
|
+
if (!message.ts) return true;
|
|
8407
|
+
return askedAt > message.ts;
|
|
8408
|
+
}
|
|
8409
|
+
return true;
|
|
8410
|
+
}
|
|
8358
8411
|
function latestPendingPlanQuestions(input) {
|
|
8359
8412
|
if (input.userReplied) return null;
|
|
8360
8413
|
const fromLive = extractPendingPlanQuestions(input.liveParts);
|
|
8361
8414
|
if (fromLive) return fromLive;
|
|
8362
8415
|
const last = input.messages[input.messages.length - 1];
|
|
8363
|
-
if (last?.role === "
|
|
8364
|
-
|
|
8416
|
+
if (last?.role === "agent") {
|
|
8417
|
+
const fromParts = extractPendingPlanQuestions(last.parts);
|
|
8418
|
+
if (fromParts) return fromParts;
|
|
8419
|
+
}
|
|
8420
|
+
const fromBlock = pendingFromAskBlock(
|
|
8421
|
+
input.agentBlock,
|
|
8422
|
+
input.dismissedQuestionSignature
|
|
8423
|
+
);
|
|
8424
|
+
if (fromBlock && askBlockStillWaiting(input.agentBlock, input.messages)) {
|
|
8425
|
+
return fromBlock;
|
|
8426
|
+
}
|
|
8365
8427
|
return null;
|
|
8366
8428
|
}
|
|
8367
8429
|
function isPlanQuestionAnswersMessage(text7) {
|
|
@@ -22161,7 +22223,7 @@ function decisionBlockFromParts(parts, planMode, at = (/* @__PURE__ */ new Date(
|
|
|
22161
22223
|
const reason = pending ? formatAskUserNotifyMessage(pending.questions) : "Waiting for an answer in that chat.";
|
|
22162
22224
|
return {
|
|
22163
22225
|
...makeAgentBlock("ask_user", reason, at),
|
|
22164
|
-
...pending ? { questionSignature: pending.signature } : {}
|
|
22226
|
+
...pending ? { questionSignature: pending.signature, questions: pending.questions } : {}
|
|
22165
22227
|
};
|
|
22166
22228
|
}
|
|
22167
22229
|
if (!planMode || last?.type !== "tool") return null;
|
|
@@ -22176,14 +22238,24 @@ function decisionBlockFromParts(parts, planMode, at = (/* @__PURE__ */ new Date(
|
|
|
22176
22238
|
at
|
|
22177
22239
|
);
|
|
22178
22240
|
}
|
|
22241
|
+
function withStampedQuestions(decision, existing) {
|
|
22242
|
+
if (decision.source !== "ask_user" || decision.questions?.length) return decision;
|
|
22243
|
+
if (existing?.source !== "ask_user" || !existing.questions?.length) return decision;
|
|
22244
|
+
return {
|
|
22245
|
+
...decision,
|
|
22246
|
+
questions: existing.questions,
|
|
22247
|
+
questionSignature: decision.questionSignature ?? existing.questionSignature
|
|
22248
|
+
};
|
|
22249
|
+
}
|
|
22179
22250
|
function agentBlockAfterTurn(input) {
|
|
22180
22251
|
if (input.failed) return null;
|
|
22181
22252
|
const decision = decisionBlockFromParts(input.parts, input.planMode);
|
|
22182
22253
|
if (decision) {
|
|
22183
|
-
|
|
22254
|
+
const next = withStampedQuestions(decision, input.existing);
|
|
22255
|
+
if (isDismissedAskUserBlock(next, input.dismissedQuestionSignature)) {
|
|
22184
22256
|
return input.existing?.source === "reported" ? input.existing : null;
|
|
22185
22257
|
}
|
|
22186
|
-
return
|
|
22258
|
+
return next;
|
|
22187
22259
|
}
|
|
22188
22260
|
if (input.existing && input.existing.source !== "reported" && lastTopLevelTool(input.parts)) {
|
|
22189
22261
|
return null;
|
|
@@ -22226,7 +22298,7 @@ function settleAgentBlock(threadId, parts, failed) {
|
|
|
22226
22298
|
});
|
|
22227
22299
|
const prev = thread.agentBlock ?? null;
|
|
22228
22300
|
if (prev === next) return;
|
|
22229
|
-
if (prev && next && prev.source === next.source && prev.reason === next.reason && prev.at === next.at && prev.questionSignature === next.questionSignature) {
|
|
22301
|
+
if (prev && next && prev.source === next.source && prev.reason === next.reason && prev.at === next.at && prev.questionSignature === next.questionSignature && planQuestionsSignature(prev.questions ?? []) === planQuestionsSignature(next.questions ?? [])) {
|
|
22230
22302
|
return;
|
|
22231
22303
|
}
|
|
22232
22304
|
updateThread(threadId, { agentBlock: next });
|
|
@@ -22249,7 +22321,11 @@ function stampAskUserBlock(resolveCaller, questions2) {
|
|
|
22249
22321
|
try {
|
|
22250
22322
|
writeAgentBlock(
|
|
22251
22323
|
resolveCaller().id,
|
|
22252
|
-
parsed.length ? {
|
|
22324
|
+
parsed.length ? {
|
|
22325
|
+
...block,
|
|
22326
|
+
questionSignature: planQuestionsSignature(parsed),
|
|
22327
|
+
questions: parsed
|
|
22328
|
+
} : block
|
|
22253
22329
|
);
|
|
22254
22330
|
} catch {
|
|
22255
22331
|
}
|
|
@@ -27622,6 +27698,15 @@ function connectedOrchestratorTurnReminder(thread, find) {
|
|
|
27622
27698
|
function formatWorktreeReminder() {
|
|
27623
27699
|
return "Sideboard workspace: 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. Schedules: create_schedule (at / every / cron; chatId=self for this chat). set_workspace_tags updates labels on this workspace (omit ref).";
|
|
27624
27700
|
}
|
|
27701
|
+
function formatClaudeSubagentReminder() {
|
|
27702
|
+
return 'Claude subagents: if Task/Agent workers will edit files, write a short plan in this chat and continue in the same turn. Do not ask the user whether to isolate, and do not set worktree.bgIsolation to none. One writer may edit this workspace. Every other writer is an Agent with isolation "worktree" and a disjoint file list (read-only explore agents may overlap). While those agents run, leave their files alone. Merge each returned branch into this workspace, then remove the temporary worktree. You stay in this cwd. If Claude says another write-capable agent is in this directory, or that writes to the shared checkout are blocked, re-spawn that agent with isolation "worktree" or make the edit yourself.';
|
|
27703
|
+
}
|
|
27704
|
+
function claudeSubagentTurnReminder(thread) {
|
|
27705
|
+
if (thread.agent !== "claude" || thread.planMode || isOrchestratorThread(thread)) {
|
|
27706
|
+
return null;
|
|
27707
|
+
}
|
|
27708
|
+
return formatClaudeSubagentReminder();
|
|
27709
|
+
}
|
|
27625
27710
|
function mentionsPrGoal(prompt) {
|
|
27626
27711
|
return PR_GOAL_RE.test(prompt);
|
|
27627
27712
|
}
|
|
@@ -29903,6 +29988,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
29903
29988
|
);
|
|
29904
29989
|
const turnReminders = [
|
|
29905
29990
|
worktreeReminder,
|
|
29991
|
+
claudeSubagentTurnReminder(thread),
|
|
29906
29992
|
connectedOrchestratorTurnReminder(thread, (id) => readThread(id)),
|
|
29907
29993
|
optionalServicesReminder,
|
|
29908
29994
|
issueToolsReminder,
|
|
@@ -32052,6 +32138,7 @@ __export(index_exports, {
|
|
|
32052
32138
|
classifyWorktreeListBadges: () => classifyWorktreeListBadges,
|
|
32053
32139
|
claudeAdapter: () => claudeAdapter,
|
|
32054
32140
|
claudeChromeEnabled: () => claudeChromeEnabled,
|
|
32141
|
+
claudeSubagentTurnReminder: () => claudeSubagentTurnReminder,
|
|
32055
32142
|
claudeUsageOverLimitWindows: () => claudeUsageOverLimitWindows,
|
|
32056
32143
|
claudeUserSettingsPath: () => claudeUserSettingsPath,
|
|
32057
32144
|
cleanupArchivedHistory: () => cleanupArchivedHistory,
|
|
@@ -32203,6 +32290,7 @@ __export(index_exports, {
|
|
|
32203
32290
|
formatAskUserNotifyMessage: () => formatAskUserNotifyMessage,
|
|
32204
32291
|
formatBrightsyFetchError: () => formatBrightsyFetchError,
|
|
32205
32292
|
formatClaudeExtraUsageDetail: () => formatClaudeExtraUsageDetail,
|
|
32293
|
+
formatClaudeSubagentReminder: () => formatClaudeSubagentReminder,
|
|
32206
32294
|
formatClaudeUsageCompact: () => formatClaudeUsageCompact,
|
|
32207
32295
|
formatClaudeUsageFetchedAt: () => formatClaudeUsageFetchedAt,
|
|
32208
32296
|
formatClaudeUsageOverLimitConfirm: () => formatClaudeUsageOverLimitConfirm,
|
|
@@ -32739,6 +32827,9 @@ __export(index_exports, {
|
|
|
32739
32827
|
shouldRunWorktreeCleanup: () => shouldRunWorktreeCleanup,
|
|
32740
32828
|
shouldStampSetupLastError: () => shouldStampSetupLastError,
|
|
32741
32829
|
showCostEnabled: () => showCostEnabled,
|
|
32830
|
+
sidebarParentSelectId: () => sidebarParentSelectId,
|
|
32831
|
+
sidebarQuestionThreadId: () => sidebarQuestionThreadId,
|
|
32832
|
+
sidebarRowAgentBlock: () => sidebarRowAgentBlock,
|
|
32742
32833
|
sideboardHomeDir: () => sideboardHomeDir,
|
|
32743
32834
|
sideboardMcpProfile: () => sideboardMcpProfile,
|
|
32744
32835
|
sideboardReposDir: () => sideboardReposDir,
|
|
@@ -35060,10 +35151,12 @@ function emitChatTurn(opts, chatId, threadId) {
|
|
|
35060
35151
|
return;
|
|
35061
35152
|
}
|
|
35062
35153
|
const result = getOrchestrator().getTurnResult(thread.id);
|
|
35063
|
-
const pending =
|
|
35064
|
-
|
|
35065
|
-
|
|
35066
|
-
|
|
35154
|
+
const pending = latestPendingPlanQuestions({
|
|
35155
|
+
messages: thread.messages,
|
|
35156
|
+
agentBlock: thread.agentBlock,
|
|
35157
|
+
dismissedQuestionSignature: thread.dismissedQuestionSignature
|
|
35158
|
+
});
|
|
35159
|
+
if (pending && result.taskState !== "failed" && result.taskState !== "canceled" && (result.taskState === "input-required" || thread.agentBlock?.source === "ask_user")) {
|
|
35067
35160
|
emitControl(opts, {
|
|
35068
35161
|
op: "ask",
|
|
35069
35162
|
chatId,
|
|
@@ -35430,7 +35523,11 @@ init_ask_user();
|
|
|
35430
35523
|
function republishPendingAsk(opts, chatId) {
|
|
35431
35524
|
const thread = readPhoneThread(chatId);
|
|
35432
35525
|
if (!thread) return;
|
|
35433
|
-
const pending = latestPendingPlanQuestions({
|
|
35526
|
+
const pending = latestPendingPlanQuestions({
|
|
35527
|
+
messages: thread.messages,
|
|
35528
|
+
agentBlock: thread.agentBlock,
|
|
35529
|
+
dismissedQuestionSignature: thread.dismissedQuestionSignature
|
|
35530
|
+
});
|
|
35434
35531
|
if (!pending) return;
|
|
35435
35532
|
emitControl(opts, {
|
|
35436
35533
|
op: "ask",
|
|
@@ -37689,10 +37786,12 @@ function runCoordinatorPrompt(opts, body, generation) {
|
|
|
37689
37786
|
thread = readThread(thread.id) ?? thread;
|
|
37690
37787
|
if (thread.status === "stopped") return;
|
|
37691
37788
|
const result = orch.getTurnResult(thread.id);
|
|
37692
|
-
const pending =
|
|
37693
|
-
|
|
37694
|
-
|
|
37695
|
-
|
|
37789
|
+
const pending = latestPendingPlanQuestions({
|
|
37790
|
+
messages: thread.messages,
|
|
37791
|
+
agentBlock: thread.agentBlock,
|
|
37792
|
+
dismissedQuestionSignature: thread.dismissedQuestionSignature
|
|
37793
|
+
});
|
|
37794
|
+
if (pending && result.taskState !== "failed" && result.taskState !== "canceled" && (result.taskState === "input-required" || thread.agentBlock?.source === "ask_user")) {
|
|
37696
37795
|
opts.onOutbound({
|
|
37697
37796
|
type: "ask_user",
|
|
37698
37797
|
text: result.text.trim(),
|
|
@@ -46899,6 +46998,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
46899
46998
|
classifyWorktreeListBadges,
|
|
46900
46999
|
claudeAdapter,
|
|
46901
47000
|
claudeChromeEnabled,
|
|
47001
|
+
claudeSubagentTurnReminder,
|
|
46902
47002
|
claudeUsageOverLimitWindows,
|
|
46903
47003
|
claudeUserSettingsPath,
|
|
46904
47004
|
cleanupArchivedHistory,
|
|
@@ -47050,6 +47150,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
47050
47150
|
formatAskUserNotifyMessage,
|
|
47051
47151
|
formatBrightsyFetchError,
|
|
47052
47152
|
formatClaudeExtraUsageDetail,
|
|
47153
|
+
formatClaudeSubagentReminder,
|
|
47053
47154
|
formatClaudeUsageCompact,
|
|
47054
47155
|
formatClaudeUsageFetchedAt,
|
|
47055
47156
|
formatClaudeUsageOverLimitConfirm,
|
|
@@ -47586,6 +47687,9 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
47586
47687
|
shouldRunWorktreeCleanup,
|
|
47587
47688
|
shouldStampSetupLastError,
|
|
47588
47689
|
showCostEnabled,
|
|
47690
|
+
sidebarParentSelectId,
|
|
47691
|
+
sidebarQuestionThreadId,
|
|
47692
|
+
sidebarRowAgentBlock,
|
|
47589
47693
|
sideboardHomeDir,
|
|
47590
47694
|
sideboardMcpProfile,
|
|
47591
47695
|
sideboardReposDir,
|