@sideboard-ai/core 0.1.278 → 0.1.279
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/agents/cursor-runner.cjs +3 -3
- package/dist/agents/cursor-runner.js +5 -5
- package/dist/{agents-2FOWVJCN.js → agents-DYCFLDNL.js} +5 -5
- package/dist/{agents-JBVJRDH3.js → agents-RXP5NZBC.js} +3 -3
- package/dist/{chunk-UKSJO36E.js → chunk-CPA43FBK.js} +4 -4
- package/dist/{chunk-FELFTNH2.js → chunk-CPGJ5ICZ.js} +261 -19
- package/dist/{chunk-NIB2IZ6J.js → chunk-HNNS25SG.js} +5 -5
- package/dist/{chunk-MGS5T2A3.js → chunk-HQXBBUQX.js} +161 -9
- package/dist/{chunk-FIBZEFKA.js → chunk-IFURHRAR.js} +1 -1
- package/dist/{chunk-5N4Q46SG.js → chunk-K2S33ZCB.js} +5 -5
- package/dist/{chunk-NT7RIWRR.js → chunk-RK5PIWCW.js} +3 -3
- package/dist/{chunk-A2G3ZBJS.js → chunk-SKSOCIJT.js} +8 -8
- package/dist/{chunk-QTZO4LPU.js → chunk-TZ5JHIYK.js} +8 -8
- package/dist/{chunk-27Z4MEQ5.js → chunk-UZUXWBXK.js} +1 -1
- package/dist/{chunk-SQOAFR2U.js → chunk-V5DMHB6Y.js} +270 -23
- package/dist/{chunk-FAGK33E2.js → chunk-Y7JPL4WA.js} +1 -1
- package/dist/{chunk-HOMZKYHF.js → chunk-YDXNCBA2.js} +107 -8
- package/dist/{conductor-YYQKZAND.js → conductor-J6WDOXWM.js} +3 -3
- package/dist/{conductor-GBCE37K4.js → conductor-OW6NAK3N.js} +4 -4
- package/dist/{coordinator-prompt-SFZCZ3HR.js → coordinator-prompt-ERTHREGJ.js} +1 -1
- package/dist/{coordinator-prompt-B3GLVXPP.js → coordinator-prompt-Z2D32HWK.js} +1 -1
- package/dist/{global-workspace-7XEXTIHL.js → global-workspace-5PJXO45Z.js} +1 -1
- package/dist/{global-workspace-N2YYJKA5.js → global-workspace-AK5PSPQ2.js} +1 -1
- package/dist/index.cjs +798 -445
- package/dist/index.d.cts +52 -15
- package/dist/index.d.ts +52 -15
- package/dist/index.js +251 -290
- package/dist/mcp/run-stdio.cjs +529 -257
- package/dist/mcp/run-stdio.js +40 -124
- package/dist/{orchestrator-6QJLM6Y4.js → orchestrator-E5WK57DA.js} +5 -5
- package/dist/{orchestrator-QMKVXVUR.js → orchestrator-KY2KBBE2.js} +7 -7
- package/dist/{workspaces-PBB6HY2D.js → workspaces-UP6DQ3WL.js} +1 -1
- package/dist/{workspaces-BJCHMGVG.js → workspaces-WU2RNLDV.js} +1 -1
- package/package.json +1 -1
package/dist/mcp/run-stdio.js
CHANGED
|
@@ -28,7 +28,9 @@ import {
|
|
|
28
28
|
HOME_BOARD_AGENT_HINT,
|
|
29
29
|
HOME_BOARD_CACHE_TTL_MS,
|
|
30
30
|
MAX_RUN_LOG_CHARS,
|
|
31
|
+
agentBlockFields,
|
|
31
32
|
assembleHomeBoard,
|
|
33
|
+
chatBlockedSuffix,
|
|
32
34
|
createSchedule,
|
|
33
35
|
dedupeBoardIssues,
|
|
34
36
|
dedupeBoardPrs,
|
|
@@ -45,14 +47,19 @@ import {
|
|
|
45
47
|
issueNeedsWorkspacePick,
|
|
46
48
|
listSchedules,
|
|
47
49
|
localhostPreviewUrl,
|
|
50
|
+
notifyOrchestrator,
|
|
48
51
|
readTurnLive,
|
|
52
|
+
resolveNotifyCallerThread,
|
|
49
53
|
resolveOrchChildFollowUp,
|
|
50
54
|
resolveScheduleThreadId,
|
|
51
55
|
scheduleNeedsCaffeinate,
|
|
52
56
|
sliceRunLogOutput,
|
|
57
|
+
stampAskUserBlock,
|
|
58
|
+
stampNotifyBlock,
|
|
59
|
+
stampPlanBlock,
|
|
53
60
|
syncBoardPins,
|
|
54
61
|
updateSchedule
|
|
55
|
-
} from "../chunk-
|
|
62
|
+
} from "../chunk-CPGJ5ICZ.js";
|
|
56
63
|
import "../chunk-LX5R5JOR.js";
|
|
57
64
|
import {
|
|
58
65
|
PRESENT_PLAN_REQUIRES_PLAN_MODE,
|
|
@@ -71,7 +78,7 @@ import {
|
|
|
71
78
|
sideboardMcpProfile,
|
|
72
79
|
trustSystemCertificates,
|
|
73
80
|
worktreeMcpToolNames
|
|
74
|
-
} from "../chunk-
|
|
81
|
+
} from "../chunk-RK5PIWCW.js";
|
|
75
82
|
import "../chunk-TQRSVE7D.js";
|
|
76
83
|
import "../chunk-P2BSMNHB.js";
|
|
77
84
|
import {
|
|
@@ -85,19 +92,19 @@ import {
|
|
|
85
92
|
stopDetachedJob,
|
|
86
93
|
threadsSharingWorktree,
|
|
87
94
|
waitForDetachedJob,
|
|
88
|
-
waitForTurnToolResult
|
|
89
|
-
|
|
95
|
+
waitForTurnToolResult,
|
|
96
|
+
workspaceAgentChatSummaries
|
|
97
|
+
} from "../chunk-YDXNCBA2.js";
|
|
90
98
|
import {
|
|
91
99
|
clipToolResultForStore,
|
|
92
100
|
isInternalAgentStatusText,
|
|
93
101
|
looksLikeHugeToolResultDump
|
|
94
|
-
} from "../chunk-
|
|
102
|
+
} from "../chunk-CPA43FBK.js";
|
|
95
103
|
import {
|
|
96
104
|
GLOBAL_WORKSPACE_ID,
|
|
97
105
|
isCloudCoordinatorThread,
|
|
98
|
-
isOrchestratorThread,
|
|
99
106
|
listWorkspaces
|
|
100
|
-
} from "../chunk-
|
|
107
|
+
} from "../chunk-TZ5JHIYK.js";
|
|
101
108
|
import {
|
|
102
109
|
canonicalizeRepoPath,
|
|
103
110
|
formatGhLandError,
|
|
@@ -138,10 +145,7 @@ import {
|
|
|
138
145
|
} from "../chunk-WWUABK6B.js";
|
|
139
146
|
import "../chunk-FJZWM2ON.js";
|
|
140
147
|
import "../chunk-UN5Q7POQ.js";
|
|
141
|
-
import
|
|
142
|
-
findThreadByRef,
|
|
143
|
-
readThread
|
|
144
|
-
} from "../chunk-JANCPF7Z.js";
|
|
148
|
+
import "../chunk-JANCPF7Z.js";
|
|
145
149
|
import "../chunk-4RZRHTSZ.js";
|
|
146
150
|
import "../chunk-KGZBYWZ3.js";
|
|
147
151
|
import {
|
|
@@ -2097,101 +2101,6 @@ function resolveRunScriptThreadRef(ref) {
|
|
|
2097
2101
|
return thread.id;
|
|
2098
2102
|
}
|
|
2099
2103
|
|
|
2100
|
-
// src/orchestrator/notify-orchestrator.ts
|
|
2101
|
-
var MAX_NOTIFY_ORCHESTRATOR_MESSAGE_CHARS = 1500;
|
|
2102
|
-
var inputRequiredNotified = /* @__PURE__ */ new Set();
|
|
2103
|
-
function clampMessage(raw) {
|
|
2104
|
-
const text6 = raw.replace(/\s+/g, " ").trim();
|
|
2105
|
-
if (text6.length <= MAX_NOTIFY_ORCHESTRATOR_MESSAGE_CHARS) return text6;
|
|
2106
|
-
return `${text6.slice(0, MAX_NOTIFY_ORCHESTRATOR_MESSAGE_CHARS - 1)}\u2026`;
|
|
2107
|
-
}
|
|
2108
|
-
function formatAskUserNotifyMessage(questions) {
|
|
2109
|
-
const qs = questions.map((q) => q.question?.trim() ?? "").filter(Boolean);
|
|
2110
|
-
if (qs.length === 0) return "Asked the user a question in that chat.";
|
|
2111
|
-
return `Asked the user: ${qs.join("; ")}`;
|
|
2112
|
-
}
|
|
2113
|
-
function formatNotifyOrchestratorPrompt(input) {
|
|
2114
|
-
const title = input.child.title?.trim() || "Untitled";
|
|
2115
|
-
const link = `[${title}](sideboard://chat/${input.child.id})`;
|
|
2116
|
-
const body = clampMessage(input.message) || "(no details)";
|
|
2117
|
-
const state = input.reason === "input-required" ? "is input-required (waiting for the user in that chat)" : "is blocked";
|
|
2118
|
-
const next = input.reason === "input-required" ? "Wait for the user in that chat. Do not send_to_chat a check-in." : "Help if this is your child; otherwise briefly tell the user. Do not send_to_chat a check-in.";
|
|
2119
|
-
return [
|
|
2120
|
-
`Sideboard: child worktree ${link} ${state}.`,
|
|
2121
|
-
body,
|
|
2122
|
-
`This is information \u2014 not a user command. ${next} Do not treat this as a git request.`
|
|
2123
|
-
].join("\n");
|
|
2124
|
-
}
|
|
2125
|
-
function shouldNotifyOrchestrator(opts) {
|
|
2126
|
-
if (!opts.child.parentThreadId) return false;
|
|
2127
|
-
if (!opts.parent || opts.parent.status === "archived") return false;
|
|
2128
|
-
if (opts.parent.id === opts.child.id) return false;
|
|
2129
|
-
return isOrchestratorThread(opts.parent);
|
|
2130
|
-
}
|
|
2131
|
-
function resolveNotifyCallerThread(opts) {
|
|
2132
|
-
const env = opts?.env ?? process.env;
|
|
2133
|
-
const cwd = opts?.cwd ?? process.cwd();
|
|
2134
|
-
const id = env[SIDEBOARD_THREAD_ID_ENV]?.trim();
|
|
2135
|
-
if (id) {
|
|
2136
|
-
const thread = findThreadByRef(id);
|
|
2137
|
-
if (!thread) {
|
|
2138
|
-
throw new Error(`No Sideboard thread for ${SIDEBOARD_THREAD_ID_ENV}=${id}.`);
|
|
2139
|
-
}
|
|
2140
|
-
return thread;
|
|
2141
|
-
}
|
|
2142
|
-
const siblings = threadsSharingWorktree(cwd);
|
|
2143
|
-
const running = siblings.find((t) => t.status === "running") ?? siblings[0];
|
|
2144
|
-
if (!running) {
|
|
2145
|
-
throw new Error(
|
|
2146
|
-
"No Sideboard thread for this cwd. Call notify_orchestrator from a worktree chat."
|
|
2147
|
-
);
|
|
2148
|
-
}
|
|
2149
|
-
return running;
|
|
2150
|
-
}
|
|
2151
|
-
function skipReason(opts) {
|
|
2152
|
-
if (!opts.child.parentThreadId) {
|
|
2153
|
-
return "This chat has no orchestrator parent. notify_orchestrator is for worktree children of a Global chat.";
|
|
2154
|
-
}
|
|
2155
|
-
if (!opts.parent) {
|
|
2156
|
-
return "Parent orchestration chat was not found.";
|
|
2157
|
-
}
|
|
2158
|
-
if (opts.parent.status === "archived") {
|
|
2159
|
-
return "Parent orchestration chat is archived.";
|
|
2160
|
-
}
|
|
2161
|
-
if (!isOrchestratorThread(opts.parent)) {
|
|
2162
|
-
return "Parent is not a Global orchestration chat.";
|
|
2163
|
-
}
|
|
2164
|
-
return "Cannot notify orchestrator.";
|
|
2165
|
-
}
|
|
2166
|
-
async function notifyOrchestrator(input) {
|
|
2167
|
-
const parent = input.child.parentThreadId ? readThread(input.child.parentThreadId) : null;
|
|
2168
|
-
if (!shouldNotifyOrchestrator({ child: input.child, parent })) {
|
|
2169
|
-
return { ok: false, error: skipReason({ child: input.child, parent }) };
|
|
2170
|
-
}
|
|
2171
|
-
const parentId = parent.id;
|
|
2172
|
-
if (input.reason === "input-required") {
|
|
2173
|
-
if (inputRequiredNotified.has(input.child.id)) {
|
|
2174
|
-
return { ok: true, parentThreadId: parentId, deduped: true };
|
|
2175
|
-
}
|
|
2176
|
-
inputRequiredNotified.add(input.child.id);
|
|
2177
|
-
}
|
|
2178
|
-
const prompt = formatNotifyOrchestratorPrompt({
|
|
2179
|
-
child: input.child,
|
|
2180
|
-
reason: input.reason,
|
|
2181
|
-
message: input.message
|
|
2182
|
-
});
|
|
2183
|
-
try {
|
|
2184
|
-
await input.send(parentId, prompt, { followUp: "queue" });
|
|
2185
|
-
} catch (err) {
|
|
2186
|
-
if (input.reason === "input-required") {
|
|
2187
|
-
inputRequiredNotified.delete(input.child.id);
|
|
2188
|
-
}
|
|
2189
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
2190
|
-
return { ok: false, error: message };
|
|
2191
|
-
}
|
|
2192
|
-
return { ok: true, parentThreadId: parentId };
|
|
2193
|
-
}
|
|
2194
|
-
|
|
2195
2104
|
// src/mcp/thread-visibility.ts
|
|
2196
2105
|
function lastMessagePreview(messages, max = 160) {
|
|
2197
2106
|
if (!messages?.length) return null;
|
|
@@ -2209,7 +2118,8 @@ function childThreadRefs(parentId, threads) {
|
|
|
2209
2118
|
title: t.title,
|
|
2210
2119
|
status: t.status,
|
|
2211
2120
|
agent: t.agent,
|
|
2212
|
-
lastText: lastMessagePreview(t.messages, 120)
|
|
2121
|
+
lastText: lastMessagePreview(t.messages, 120),
|
|
2122
|
+
...t.agentBlock?.reason ? { blockedReason: t.agentBlock.reason, blockedSource: t.agentBlock.source } : {}
|
|
2213
2123
|
}));
|
|
2214
2124
|
}
|
|
2215
2125
|
|
|
@@ -3834,6 +3744,7 @@ async function createOrchChildThread(orch, args, resolveNewThreadOptions) {
|
|
|
3834
3744
|
link: `sideboard://chat/${thread.id}`,
|
|
3835
3745
|
parentChatId: thread.parentThreadId,
|
|
3836
3746
|
parentThreadId: thread.parentThreadId,
|
|
3747
|
+
chats: workspaceAgentChatSummaries(thread.worktreePath),
|
|
3837
3748
|
...alreadyStarted ? { alreadyStarted: true } : {},
|
|
3838
3749
|
...opts.coercedFrom ? { agentCoercedFrom: opts.coercedFrom } : {},
|
|
3839
3750
|
...opts.ignoredAgent ? { agentIgnored: opts.ignoredAgent } : {},
|
|
@@ -3920,7 +3831,7 @@ async function startMcpServer() {
|
|
|
3920
3831
|
);
|
|
3921
3832
|
server.tool(
|
|
3922
3833
|
"list_chats",
|
|
3923
|
-
"List chats across all projects (one summary line each \u2014 token-frugal). Includes parent id, last message preview, and live progress so you can see workspace children. Each line ends with sideboard://chat/<id> \u2014 use that URL in markdown links so the UI can open the chat.",
|
|
3834
|
+
"List chats across all projects (one summary line each \u2014 token-frugal). Includes parent id, last message preview, blocked: when an agent is waiting on a person, and live progress so you can see workspace children. Each line ends with sideboard://chat/<id> \u2014 use that URL in markdown links so the UI can open the chat.",
|
|
3924
3835
|
{},
|
|
3925
3836
|
async () => {
|
|
3926
3837
|
const threads = orch.getThreads(true);
|
|
@@ -3932,7 +3843,7 @@ async function startMcpServer() {
|
|
|
3932
3843
|
const previewBit = preview ? ` ${preview}` : "";
|
|
3933
3844
|
const err = t.lastError ? ` error:${t.lastError.replace(/\s+/g, " ").slice(0, 60)}` : "";
|
|
3934
3845
|
const progress = live?.summary && !isInternalAgentStatusText(live.summary) ? ` ${live.summary}` : "";
|
|
3935
|
-
return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title}${parent}${previewBit}${err} sideboard://chat/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}${progress}`;
|
|
3846
|
+
return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title}${parent}${previewBit}${chatBlockedSuffix(t)}${err} sideboard://chat/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}${progress}`;
|
|
3936
3847
|
});
|
|
3937
3848
|
return {
|
|
3938
3849
|
content: [{ type: "text", text: lines.join("\n") || "(no chats)" }]
|
|
@@ -3941,7 +3852,7 @@ async function startMcpServer() {
|
|
|
3941
3852
|
);
|
|
3942
3853
|
server.tool(
|
|
3943
3854
|
"list_board",
|
|
3944
|
-
"Home Kanban of
|
|
3855
|
+
"Home Kanban of workspaces (New, Draft, Review, Merged) \u2014 one card per checkout; sibling chats on that card are separate agents. Same cards as desktop Home. Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind (ticket/PR/branch source), ownership (mine = your PRs / WIP; reviewing = someone else's PR), column, limit (default 40). create_workspace adds a workspace (and a Home card), or returns the live checkout if that ticket/PR/named branch is already checked out. That reuse is one checkout, not one agent \u2014 fork_chat to add another.",
|
|
3945
3856
|
{
|
|
3946
3857
|
query: z8.string().optional().describe("Case-insensitive token search across title, id, labels, repo"),
|
|
3947
3858
|
repoPath: z8.string().optional().describe("Limit to one project path from list_projects"),
|
|
@@ -3981,7 +3892,7 @@ async function startMcpServer() {
|
|
|
3981
3892
|
);
|
|
3982
3893
|
server.tool(
|
|
3983
3894
|
"get_chat",
|
|
3984
|
-
"Get a compact chat summary by id/ref. Includes last message preview, parentChatId, and child workspace chats (status + lastText). While running, includes progress (last tool/thinking) and lastActivityAt. Includes usage (billed token + costUsd totals when providers reported cost) and lastTurnUsage.",
|
|
3895
|
+
"Get a compact chat summary by id/ref. Includes last message preview, parentChatId, and child workspace chats (status + lastText). While running, includes progress (last tool/thinking) and lastActivityAt. Includes usage (billed token + costUsd totals when providers reported cost) and lastTurnUsage. blockedReason is why that agent is waiting on a person (question, plan approval, or a reported block).",
|
|
3985
3896
|
{ ref: z8.string() },
|
|
3986
3897
|
async ({ ref }) => {
|
|
3987
3898
|
const t = orch.getThread(ref);
|
|
@@ -4011,6 +3922,7 @@ async function startMcpServer() {
|
|
|
4011
3922
|
devPort: t.devPort,
|
|
4012
3923
|
prUrl: t.prUrl,
|
|
4013
3924
|
lastError: t.lastError ?? null,
|
|
3925
|
+
...agentBlockFields(t),
|
|
4014
3926
|
stillRunning,
|
|
4015
3927
|
progress: liveSummary ?? (stillRunning && t.status === "queued" ? "Queued \u2014 waiting for a concurrency slot" : null),
|
|
4016
3928
|
lastActivityAt: live?.updatedAt ?? null,
|
|
@@ -4072,7 +3984,7 @@ async function startMcpServer() {
|
|
|
4072
3984
|
};
|
|
4073
3985
|
await notifyParent({
|
|
4074
3986
|
reason: "input-required",
|
|
4075
|
-
message:
|
|
3987
|
+
message: stampAskUserBlock(resolveNotifyCallerThread, questions)
|
|
4076
3988
|
});
|
|
4077
3989
|
return mcpJson(payload);
|
|
4078
3990
|
}
|
|
@@ -4104,7 +4016,7 @@ async function startMcpServer() {
|
|
|
4104
4016
|
const payload = {
|
|
4105
4017
|
ok: true,
|
|
4106
4018
|
path,
|
|
4107
|
-
title: title
|
|
4019
|
+
title: stampPlanBlock(t?.id, title),
|
|
4108
4020
|
message: "Plan saved to .context/attachments/plan.md and shown in Sideboard chat for approval."
|
|
4109
4021
|
};
|
|
4110
4022
|
return mcpJson(payload);
|
|
@@ -4309,7 +4221,7 @@ async function startMcpServer() {
|
|
|
4309
4221
|
if (worktreeProfile) {
|
|
4310
4222
|
server.tool(
|
|
4311
4223
|
"notify_orchestrator",
|
|
4312
|
-
"Wake the parent Global orchestrator with a short status so it does not have to poll wait_for_turn. Use when you are blocked and the parent may have moved on (missing access, waiting on something the coordinator must handle). ask_user already notifies for input-required \u2014 do not call this for the same question. Information only: never a git command. Do not use this to steer other worktrees.",
|
|
4224
|
+
"Wake the parent Global orchestrator with a short status so it does not have to poll wait_for_turn. Use when you are blocked and the parent may have moved on (missing access, waiting on something the coordinator must handle). The message is shown on the sidebar and board until the next user message in this chat. ask_user already notifies for input-required \u2014 do not call this for the same question. Information only: never a git command. Do not use this to steer other worktrees.",
|
|
4313
4225
|
{
|
|
4314
4226
|
message: z8.string().min(1).max(1500).describe("Why you are blocked / what the parent should know (short)."),
|
|
4315
4227
|
reason: z8.enum(["input-required", "blocked"]).optional().describe(
|
|
@@ -4321,7 +4233,7 @@ async function startMcpServer() {
|
|
|
4321
4233
|
const child = resolveNotifyCallerThread();
|
|
4322
4234
|
const result = await notifyOrchestrator({
|
|
4323
4235
|
child,
|
|
4324
|
-
reason: reason
|
|
4236
|
+
reason: stampNotifyBlock(child.id, reason, message),
|
|
4325
4237
|
message,
|
|
4326
4238
|
send: (id, prompt, opts) => orch.send(id, prompt, opts)
|
|
4327
4239
|
});
|
|
@@ -4379,7 +4291,7 @@ async function startMcpServer() {
|
|
|
4379
4291
|
);
|
|
4380
4292
|
server.tool(
|
|
4381
4293
|
"create_workspace",
|
|
4382
|
-
`Create a workspace (isolated git
|
|
4294
|
+
`Create a workspace (isolated git checkout + first chat) from branch, pr, or ticket. A ticket, PR, or named branch has one checkout \u2014 if one already matches, returns it (alreadyStarted=true) instead of a second checkout. That is not one agent: chats lists every agent on that checkout. Add another with fork_chat; send_to_chat only the chat that should do this job. Creating from the default branch still opens a new isolated checkout. Pass repoPath from list_projects. cowboy=true uses the project folder on the default branch (no isolated worktree; land is commit+push). From an orchestration chat, omit parentChatId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Omit agent/model \u2014 Sideboard applies ${accountDefaultsHint}. Do not pass your own agent or agent=cursor; those are ignored. Setup (settings.toml, .cursor/worktrees.json, or script/setup) runs in the background in parallel with the first turn (skipped for cowboy).`,
|
|
4383
4295
|
{
|
|
4384
4296
|
sourceType: z8.enum(["branch", "pr", "ticket"]),
|
|
4385
4297
|
sourceRef: z8.string(),
|
|
@@ -4409,7 +4321,7 @@ async function startMcpServer() {
|
|
|
4409
4321
|
);
|
|
4410
4322
|
server.tool(
|
|
4411
4323
|
"start_board_card",
|
|
4412
|
-
"Same as create_workspace for a ticket, PR, or named branch (attaches issue text when Sideboard can resolve it). Does not create a second
|
|
4324
|
+
"Same as create_workspace for a ticket, PR, or named branch (attaches issue text when Sideboard can resolve it). Does not create a second checkout when one already matches \u2014 returns that workspace (alreadyStarted) and its chats. A workspace can have many agents. fork_chat to add one; send_to_chat only the chat that should do this job.",
|
|
4413
4325
|
{
|
|
4414
4326
|
kind: z8.enum(["ticket", "pr", "branch"]),
|
|
4415
4327
|
ref: z8.string().describe("Ticket identifier (ENG-12), PR number (44), or branch name from list_board"),
|
|
@@ -4436,7 +4348,8 @@ async function startMcpServer() {
|
|
|
4436
4348
|
id: existing.id,
|
|
4437
4349
|
title: existing.title,
|
|
4438
4350
|
status: existing.status,
|
|
4439
|
-
link: `sideboard://chat/${existing.id}
|
|
4351
|
+
link: `sideboard://chat/${existing.id}`,
|
|
4352
|
+
chats: workspaceAgentChatSummaries(orch.getThread(existing.id)?.worktreePath)
|
|
4440
4353
|
});
|
|
4441
4354
|
}
|
|
4442
4355
|
const workspaces = orch.listWorkspaces();
|
|
@@ -4536,7 +4449,7 @@ async function startMcpServer() {
|
|
|
4536
4449
|
if (shouldRegisterMcpWaitForTurn()) {
|
|
4537
4450
|
server.tool(
|
|
4538
4451
|
"wait_for_turn",
|
|
4539
|
-
"Wait until the chat finishes its current/queued turn, or return early with a live progress snapshot. MCP clients often kill tools around 60s, so this returns within 45s even while the child is still working. taskState is the A2A-style lifecycle: submitted (queued, not started), working, input-required (ask_user), completed, failed, canceled. stillRunning is true only for submitted/working. If stillRunning, text and usage are empty (they would be the previous turn) \u2014 read progress and call wait_for_turn again. Do not send_to_chat a check-in (that steers / interrupts). On failed, lastError/text is the failure. On canceled, the child did not finish \u2014 resume with send_to_chat or tell the user. On input-required, wait for the user in that chat. When finished, text is this turn\u2019s assistant reply and usage is that turn\u2019s tokens + costUsd (this turn, not the Claude session total; sessionCostUsd is the provider session total when present).",
|
|
4452
|
+
"Wait until the chat finishes its current/queued turn, or return early with a live progress snapshot. MCP clients often kill tools around 60s, so this returns within 45s even while the child is still working. taskState is the A2A-style lifecycle: submitted (queued, not started), working, input-required (ask_user), completed, failed, canceled. stillRunning is true only for submitted/working. blockedReason is why the child is waiting on a person (the question, plan approval, or a reported block) \u2014 read it and do not send_to_chat a check-in. If stillRunning, text and usage are empty (they would be the previous turn) \u2014 read progress and call wait_for_turn again. Do not send_to_chat a check-in (that steers / interrupts). On failed, lastError/text is the failure. On canceled, the child did not finish \u2014 resume with send_to_chat or tell the user. On input-required, wait for the user in that chat. When finished, text is this turn\u2019s assistant reply and usage is that turn\u2019s tokens + costUsd (this turn, not the Claude session total; sessionCostUsd is the provider session total when present).",
|
|
4540
4453
|
{
|
|
4541
4454
|
ref: z8.string(),
|
|
4542
4455
|
timeoutMs: z8.number().optional()
|
|
@@ -4556,7 +4469,9 @@ async function startMcpServer() {
|
|
|
4556
4469
|
stillRunning: result.stillRunning,
|
|
4557
4470
|
progress: result.progress,
|
|
4558
4471
|
lastActivityAt: result.lastActivityAt,
|
|
4559
|
-
usage: result.usage
|
|
4472
|
+
usage: result.usage,
|
|
4473
|
+
blockedReason: result.blockedReason,
|
|
4474
|
+
blockedSource: result.blockedSource
|
|
4560
4475
|
})
|
|
4561
4476
|
);
|
|
4562
4477
|
}
|
|
@@ -4564,15 +4479,16 @@ async function startMcpServer() {
|
|
|
4564
4479
|
}
|
|
4565
4480
|
server.tool(
|
|
4566
4481
|
"get_turn_result",
|
|
4567
|
-
"Assistant message and last-turn usage when the turn finished. While stillRunning (submitted/working), text and usage are empty so a previous reply cannot be mistaken for this turn \u2014 use progress for tools/thinking. Not the full transcript. Includes taskState (A2A lifecycle).",
|
|
4482
|
+
"Assistant message and last-turn usage when the turn finished. While stillRunning (submitted/working), text and usage are empty so a previous reply cannot be mistaken for this turn \u2014 use progress for tools/thinking. Not the full transcript. Includes taskState (A2A lifecycle) and blockedReason (why the agent is waiting on a person).",
|
|
4568
4483
|
{ ref: z8.string() },
|
|
4569
4484
|
async ({ ref }) => {
|
|
4570
4485
|
const result = orch.getTurnResult(ref);
|
|
4571
|
-
const hint = mcpWaitTaskHint(result.taskState, result.status);
|
|
4486
|
+
const hint = mcpWaitTaskHint(result.taskState, result.status, result.blockedReason);
|
|
4487
|
+
const waiting = Boolean(result.blockedReason) && !result.stillRunning && result.taskState !== "failed" && result.taskState !== "canceled";
|
|
4572
4488
|
return mcpJson({
|
|
4573
4489
|
...result,
|
|
4574
4490
|
hint,
|
|
4575
|
-
incomplete: needsCoordinatorAction(result.taskState)
|
|
4491
|
+
incomplete: needsCoordinatorAction(result.taskState) || waiting
|
|
4576
4492
|
});
|
|
4577
4493
|
}
|
|
4578
4494
|
);
|
|
@@ -4786,7 +4702,7 @@ async function startMcpServer() {
|
|
|
4786
4702
|
);
|
|
4787
4703
|
server.tool(
|
|
4788
4704
|
"fork_chat",
|
|
4789
|
-
"
|
|
4705
|
+
"Add another agent chat on the SAME workspace (same files, Run, and git). Also forks a Global orchestration chat into a new orchestration tab. Pass agent when the new chat should use a different harness. Leave model unset for Auto unless you have a reason. Orchestration forks require an MCP-capable agent (claude, cursor, codex, opencode \u2014 not brightsy). Use this for a second agent on a checkout (review, another harness, parallel work on the same branch). Do not create_workspace again for that \u2014 it returns the existing checkout. Then send_to_chat / wait_for_turn (loop while stillRunning) on the returned id. Use fork_workspace only when the work needs its own git checkout.",
|
|
4790
4706
|
{
|
|
4791
4707
|
ref: z8.string().describe("Thread id/ref to fork (worktree agent or orchestration chat)"),
|
|
4792
4708
|
through_index: z8.number().optional().describe("Inclusive message index to include in the transcript (default: all)"),
|
|
@@ -11,17 +11,17 @@ import {
|
|
|
11
11
|
resolveSendFollowUp,
|
|
12
12
|
startOrchestration,
|
|
13
13
|
waitForPidExit
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-CPGJ5ICZ.js";
|
|
15
15
|
import "./chunk-LX5R5JOR.js";
|
|
16
16
|
import "./chunk-4GK32AYX.js";
|
|
17
17
|
import "./chunk-5DZUWGKV.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-RK5PIWCW.js";
|
|
19
19
|
import "./chunk-TQRSVE7D.js";
|
|
20
20
|
import "./chunk-P2BSMNHB.js";
|
|
21
21
|
import "./chunk-VKQGAWHY.js";
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-YDXNCBA2.js";
|
|
23
|
+
import "./chunk-CPA43FBK.js";
|
|
24
|
+
import "./chunk-TZ5JHIYK.js";
|
|
25
25
|
import "./chunk-K7MWJLR7.js";
|
|
26
26
|
import "./chunk-N2WW62LF.js";
|
|
27
27
|
import "./chunk-DD67JWTN.js";
|
|
@@ -9,22 +9,22 @@ import {
|
|
|
9
9
|
resolveSendFollowUp,
|
|
10
10
|
startOrchestration,
|
|
11
11
|
waitForPidExit
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-V5DMHB6Y.js";
|
|
13
|
+
import "./chunk-HNNS25SG.js";
|
|
14
14
|
import "./chunk-GWFVCCJZ.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-HQXBBUQX.js";
|
|
16
|
+
import "./chunk-Y7JPL4WA.js";
|
|
17
17
|
import "./chunk-7H655NEW.js";
|
|
18
18
|
import "./chunk-PGPSIEMW.js";
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-SKSOCIJT.js";
|
|
20
20
|
import "./chunk-IPPY3FG5.js";
|
|
21
21
|
import "./chunk-FWNL62VA.js";
|
|
22
22
|
import "./chunk-2P4XKWV2.js";
|
|
23
23
|
import "./chunk-ROPGQRPU.js";
|
|
24
24
|
import "./chunk-N7WZ6NIN.js";
|
|
25
25
|
import "./chunk-AXQ4ZWHK.js";
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-
|
|
26
|
+
import "./chunk-IFURHRAR.js";
|
|
27
|
+
import "./chunk-K2S33ZCB.js";
|
|
28
28
|
import "./chunk-6K64FJDD.js";
|
|
29
29
|
import "./chunk-UWQ6UCIB.js";
|
|
30
30
|
import "./chunk-QVN2WOKJ.js";
|