@sideboard-ai/core 0.1.191 → 0.1.192
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-5OBZETUV.js → agents-T5VBB6X3.js} +2 -2
- package/dist/{agents-DTPVTDB5.js → agents-TXGQIK2E.js} +2 -2
- package/dist/{chunk-XXEIF2IL.js → chunk-7NSXGL6L.js} +3 -3
- package/dist/{chunk-GPSIZGEZ.js → chunk-FZ3G5TXM.js} +19 -12
- package/dist/{chunk-5RRAKGPK.js → chunk-NF6ENGHS.js} +20 -13
- package/dist/{chunk-OLDZXO53.js → chunk-TWSCTJCR.js} +2 -2
- package/dist/{chunk-VIODP5PT.js → chunk-VV7UT3E2.js} +3 -3
- package/dist/{chunk-GBWKMWUQ.js → chunk-WHD4JNTN.js} +2 -2
- package/dist/{coordinator-prompt-LWKOL3AZ.js → coordinator-prompt-PNUDN4DW.js} +1 -1
- package/dist/{coordinator-prompt-MSC44OOM.js → coordinator-prompt-S4HHFSLI.js} +1 -1
- package/dist/{global-workspace-6G5JJH2E.js → global-workspace-2BVCJUAL.js} +1 -1
- package/dist/{global-workspace-XATJTV3N.js → global-workspace-JTBBH2K5.js} +1 -1
- package/dist/index.cjs +64 -17
- package/dist/index.d.cts +9 -4
- package/dist/index.d.ts +9 -4
- package/dist/index.js +53 -13
- package/dist/mcp/run-stdio.cjs +62 -17
- package/dist/mcp/run-stdio.js +52 -13
- package/dist/{orchestrator-2X6LYBQI.js → orchestrator-4G76BOHH.js} +5 -3
- package/dist/{orchestrator-F3CXDBZB.js → orchestrator-LWEZ74RK.js} +5 -3
- package/dist/{workspaces-LMFCRXTT.js → workspaces-OY7D5RPU.js} +1 -1
- package/dist/{workspaces-FWKPWSXV.js → workspaces-ZYPME3YD.js} +1 -1
- package/package.json +1 -1
|
@@ -38,11 +38,11 @@ import {
|
|
|
38
38
|
resolveQuotaFallbackAgent,
|
|
39
39
|
turnCostUsdFromCursorUsage,
|
|
40
40
|
whichOnPath
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-WHD4JNTN.js";
|
|
42
42
|
import "./chunk-HVIEYTUK.js";
|
|
43
43
|
import "./chunk-Y4MIXGPA.js";
|
|
44
44
|
import "./chunk-VKQGAWHY.js";
|
|
45
|
-
import "./chunk-
|
|
45
|
+
import "./chunk-7NSXGL6L.js";
|
|
46
46
|
import "./chunk-XBLN52RZ.js";
|
|
47
47
|
import "./chunk-D6JWYJ4P.js";
|
|
48
48
|
import "./chunk-GOZ6T3AG.js";
|
|
@@ -32,8 +32,8 @@ import {
|
|
|
32
32
|
resolveLoginCommand,
|
|
33
33
|
resolveQuotaFallbackAgent,
|
|
34
34
|
whichOnPath
|
|
35
|
-
} from "./chunk-
|
|
36
|
-
import "./chunk-
|
|
35
|
+
} from "./chunk-TWSCTJCR.js";
|
|
36
|
+
import "./chunk-VV7UT3E2.js";
|
|
37
37
|
import "./chunk-WXKXSZN4.js";
|
|
38
38
|
import "./chunk-6K64FJDD.js";
|
|
39
39
|
import "./chunk-IEEAVWAP.js";
|
|
@@ -350,8 +350,8 @@ var COORDINATOR_TOOL_PLAYBOOK = [
|
|
|
350
350
|
"- start_board_card \u2014 same as create_thread for a ticket/PR/named branch (attaches issue text when resolvable). Then send_to_thread.",
|
|
351
351
|
"- fork_worktree \u2014 fork a worktree chat into a NEW git worktree + chat (transcript attached); optional agent; leave model unset (Auto) unless you have a reason. Not for orchestration chats.",
|
|
352
352
|
"- fork_chat \u2014 fork a worktree chat (same worktree tab) OR a Global orchestration chat (new orchestration tab); optional agent; leave model unset (Auto) unless you have a reason. Remote coordinators: use this to continue another orchestration chat on a different agent after session limits.",
|
|
353
|
-
"- send_to_thread \u2014
|
|
354
|
-
"- wait_for_turn / get_turn_result \u2014 wait for and read the agent reply (includes last-turn usage / costUsd when the child agent reported it). wait_for_turn returns within ~45s even if the child is still working (MCP clients kill longer tool calls). stillRunning is the source of truth \u2014 if it is false, the child is not working; do not tell the user it is running or \u201Cwaiting for a gate,\u201D even if status still says running/queued. If stillRunning is true, progress is a live snapshot of tools/thinking \u2014 call wait_for_turn again. status=queued with no lastActivityAt means the child has not started yet (concurrency cap) \u2014 keep waiting; do not force_stop or
|
|
353
|
+
"- send_to_thread \u2014 steer a prompt (start/continue a chat turn; Settings \u2192 Follow-up, default steer: interrupt and start now). force_stop: true only to replace a wrong in-flight request and clear the inbox \u2014 never to check in, resume after a halt notice, or because wait_for_turn returned stillRunning (that interrupts the child mid-thought)",
|
|
354
|
+
"- wait_for_turn / get_turn_result \u2014 wait for and read the agent reply (includes last-turn usage / costUsd when the child agent reported it). wait_for_turn returns within ~45s even if the child is still working (MCP clients kill longer tool calls). stillRunning is the source of truth \u2014 if it is false, the child is not working; do not tell the user it is running or \u201Cwaiting for a gate,\u201D even if status still says running/queued. If stillRunning is true, progress is a live snapshot of tools/thinking \u2014 call wait_for_turn again. status=queued with no lastActivityAt means the child has not started yet (concurrency cap) \u2014 keep waiting; do not force_stop or send_to_thread a check-in (that steers / interrupts). Do not send \u201Care you stuck?\u201D or assume a hang while lastActivityAt is recent. If stillRunning stays true across many waits with the same lastActivityAt, the child is stuck \u2014 tell the user; do not invent a gate. On status error, lastError (and text) is the failure \u2014 switch agent, tell the user, or retry; do not treat empty text as success. On status stopped or broken (or incomplete=true), the child was interrupted or died \u2014 resume with send_to_thread or tell the user; never treat stopped as a finished turn. Sideboard also injects a notice into this chat when a child stops unexpectedly.",
|
|
355
355
|
"- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
|
|
356
356
|
"- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
|
|
357
357
|
"Setup / run:",
|
|
@@ -361,7 +361,7 @@ var COORDINATOR_TOOL_PLAYBOOK = [
|
|
|
361
361
|
"- get_diff \u2014 compact diff summary",
|
|
362
362
|
"- get_pr_checks \u2014 snapshot of a worktree thread's PR checks (null = no PR). Use this to inspect status. If the user gave a goal, the worktree agent watches with `gh pr checks --watch` \u2014 do not poll for the human.",
|
|
363
363
|
'- request_review \u2014 open a Review chat tab on a worktree thread (attaches .claude/skills/review/SKILL.md when present, else .context/review.md copied from .sideboard/review.md / stock; sends "Review changes in this workspace."); then wait_for_turn (loop while stillRunning) / get_turn_result on the returned id. The review stays in that chat so they can read it and type next steps \u2014 do not tell the child to comment or update the PR or ticket.',
|
|
364
|
-
"- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it
|
|
364
|
+
"- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it steers the worktree agent \u2014 then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If ask_git / get_thread lastError says the GraphQL/PR body is too long, the branch is already pushed \u2014 send_to_thread so the worktree agent runs `gh pr create --body-file` with a short description. Do not invent SSH or auth failures from that error. If the user gave a goal (Greptile 5/5, CI green), send_to_thread that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
|
|
365
365
|
'- Merge (`ask_git` action=merge / send_to_thread "Merge PR.") only when the user explicitly asked to merge that PR. Do not merge because the work looks done, CI is green, or a typical flow includes it.',
|
|
366
366
|
'- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
|
|
367
367
|
"Process guides:",
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
summarizeTurnStderr,
|
|
34
34
|
toolDescription,
|
|
35
35
|
turnFailChatText
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-WHD4JNTN.js";
|
|
37
37
|
import {
|
|
38
38
|
extractPresentedPlan,
|
|
39
39
|
readPlanFile,
|
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
stageAbsolutePathsAsAttachments,
|
|
65
65
|
stageBuffersAsAttachments,
|
|
66
66
|
syncWorkspacesFromThreads
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-7NSXGL6L.js";
|
|
68
68
|
import {
|
|
69
69
|
addPrStackLayer,
|
|
70
70
|
allocateTeamName,
|
|
@@ -402,7 +402,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
402
402
|
await continueOnReply(threadId, prompt);
|
|
403
403
|
return;
|
|
404
404
|
}
|
|
405
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
405
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-4G76BOHH.js");
|
|
406
406
|
await getOrchestrator2().send(threadId, prompt);
|
|
407
407
|
} catch {
|
|
408
408
|
}
|
|
@@ -795,9 +795,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
795
795
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
796
796
|
);
|
|
797
797
|
}
|
|
798
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
798
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-2BVCJUAL.js");
|
|
799
799
|
if (isGlobalThread2(thread)) {
|
|
800
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
800
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-PNUDN4DW.js");
|
|
801
801
|
ensureGlobalCoordinatorCwd2(
|
|
802
802
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
803
803
|
);
|
|
@@ -2658,8 +2658,8 @@ function mcpWaitForTurnTimeoutMs(requested) {
|
|
|
2658
2658
|
if (!Number.isFinite(n)) return MCP_WAIT_FOR_TURN_MAX_MS;
|
|
2659
2659
|
return Math.min(Math.max(1e3, Math.floor(n)), MCP_WAIT_FOR_TURN_MAX_MS);
|
|
2660
2660
|
}
|
|
2661
|
-
var MCP_WAIT_STILL_RUNNING_HINT = "Child is still working. Call wait_for_turn again. Do not
|
|
2662
|
-
var MCP_WAIT_QUEUED_HINT = "Child is queued waiting for a concurrency slot \u2014 it has not started yet. Call wait_for_turn again. Do not
|
|
2661
|
+
var MCP_WAIT_STILL_RUNNING_HINT = "Child is still working. Call wait_for_turn again. Do not send_to_thread a check-in (that steers / interrupts) or assume a hang while progress is updating.";
|
|
2662
|
+
var MCP_WAIT_QUEUED_HINT = "Child is queued waiting for a concurrency slot \u2014 it has not started yet. Call wait_for_turn again. Do not send_to_thread a check-in (that steers / interrupts), force_stop, or assume it failed to start.";
|
|
2663
2663
|
function mcpWaitStillRunningHint(status) {
|
|
2664
2664
|
return status === "queued" ? MCP_WAIT_QUEUED_HINT : MCP_WAIT_STILL_RUNNING_HINT;
|
|
2665
2665
|
}
|
|
@@ -4155,7 +4155,7 @@ async function adoptThread(input) {
|
|
|
4155
4155
|
messages: input.messages ?? []
|
|
4156
4156
|
});
|
|
4157
4157
|
writeThread(thread);
|
|
4158
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
4158
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-OY7D5RPU.js");
|
|
4159
4159
|
await ensureWorkspace2(repoPath);
|
|
4160
4160
|
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
|
|
4161
4161
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
@@ -6458,7 +6458,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
6458
6458
|
${prompt}`;
|
|
6459
6459
|
}
|
|
6460
6460
|
async function defaultDeps() {
|
|
6461
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
6461
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-4G76BOHH.js");
|
|
6462
6462
|
const orch = getOrchestrator2();
|
|
6463
6463
|
return {
|
|
6464
6464
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -6589,6 +6589,10 @@ function resolveSendFollowUp(thread, requested) {
|
|
|
6589
6589
|
if (requested === "steer" || requested === "queue") return requested;
|
|
6590
6590
|
return isOrchestratorThread(thread) ? followUpBehavior() : "queue";
|
|
6591
6591
|
}
|
|
6592
|
+
function resolveOrchChildFollowUp(requested) {
|
|
6593
|
+
if (requested === "steer" || requested === "queue") return requested;
|
|
6594
|
+
return followUpBehavior();
|
|
6595
|
+
}
|
|
6592
6596
|
var STALE_AGENT_PID_WAIT_MS = 2500;
|
|
6593
6597
|
function writeLiveStatus(threadId, status, lastError) {
|
|
6594
6598
|
const latest = readThread(threadId);
|
|
@@ -8401,7 +8405,7 @@ var Orchestrator = class {
|
|
|
8401
8405
|
/**
|
|
8402
8406
|
* Desktop git buttons + MCP `ask_git`.
|
|
8403
8407
|
* When the worktree is clean, push / open the PR here (HTTPS via `gh` if SSH
|
|
8404
|
-
* is missing). When dirty,
|
|
8408
|
+
* is missing). When dirty, steer the worktree agent to commit first.
|
|
8405
8409
|
*/
|
|
8406
8410
|
async askGit(threadRef, action) {
|
|
8407
8411
|
if (!AGENT_GIT_ACTIONS.includes(action)) {
|
|
@@ -8438,7 +8442,9 @@ var Orchestrator = class {
|
|
|
8438
8442
|
} catch {
|
|
8439
8443
|
}
|
|
8440
8444
|
}
|
|
8441
|
-
return this.send(threadRef, agentGitPrompt(action, { prBase })
|
|
8445
|
+
return this.send(threadRef, agentGitPrompt(action, { prBase }), {
|
|
8446
|
+
followUp: resolveOrchChildFollowUp()
|
|
8447
|
+
});
|
|
8442
8448
|
}
|
|
8443
8449
|
/** Push origin (gh HTTPS fallback) and create/update the PR when requested. */
|
|
8444
8450
|
async pushAndMaybeOpenPr(thread, action) {
|
|
@@ -8582,7 +8588,7 @@ var Orchestrator = class {
|
|
|
8582
8588
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
8583
8589
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
8584
8590
|
try {
|
|
8585
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
8591
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-OY7D5RPU.js");
|
|
8586
8592
|
await ensureWorkspace2(thread.repoPath);
|
|
8587
8593
|
} catch {
|
|
8588
8594
|
}
|
|
@@ -8807,6 +8813,7 @@ export {
|
|
|
8807
8813
|
isPidAlive,
|
|
8808
8814
|
waitForPidExit,
|
|
8809
8815
|
resolveSendFollowUp,
|
|
8816
|
+
resolveOrchChildFollowUp,
|
|
8810
8817
|
Orchestrator,
|
|
8811
8818
|
getOrchestrator,
|
|
8812
8819
|
startOrchestration
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
stripBrightsyNdjsonNoise,
|
|
25
25
|
sumUsageList,
|
|
26
26
|
toolDescription
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-TWSCTJCR.js";
|
|
28
28
|
import {
|
|
29
29
|
SLACK_REPLY_FORMATTING,
|
|
30
30
|
addWorkspace,
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
stageAbsolutePathsAsAttachments,
|
|
48
48
|
stageBuffersAsAttachments,
|
|
49
49
|
syncWorkspacesFromThreads
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-VV7UT3E2.js";
|
|
51
51
|
import {
|
|
52
52
|
addPrStackLayer,
|
|
53
53
|
allocateTeamName,
|
|
@@ -467,7 +467,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
467
467
|
await continueOnReply(threadId, prompt);
|
|
468
468
|
return;
|
|
469
469
|
}
|
|
470
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
470
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-LWEZ74RK.js");
|
|
471
471
|
await getOrchestrator2().send(threadId, prompt);
|
|
472
472
|
} catch {
|
|
473
473
|
}
|
|
@@ -801,9 +801,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
801
801
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
802
802
|
);
|
|
803
803
|
}
|
|
804
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
804
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-JTBBH2K5.js");
|
|
805
805
|
if (isGlobalThread2(thread)) {
|
|
806
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
806
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-S4HHFSLI.js");
|
|
807
807
|
ensureGlobalCoordinatorCwd2(
|
|
808
808
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
809
809
|
);
|
|
@@ -2745,8 +2745,8 @@ function mcpWaitForTurnTimeoutMs(requested) {
|
|
|
2745
2745
|
if (!Number.isFinite(n)) return MCP_WAIT_FOR_TURN_MAX_MS;
|
|
2746
2746
|
return Math.min(Math.max(1e3, Math.floor(n)), MCP_WAIT_FOR_TURN_MAX_MS);
|
|
2747
2747
|
}
|
|
2748
|
-
var MCP_WAIT_STILL_RUNNING_HINT = "Child is still working. Call wait_for_turn again. Do not
|
|
2749
|
-
var MCP_WAIT_QUEUED_HINT = "Child is queued waiting for a concurrency slot \u2014 it has not started yet. Call wait_for_turn again. Do not
|
|
2748
|
+
var MCP_WAIT_STILL_RUNNING_HINT = "Child is still working. Call wait_for_turn again. Do not send_to_thread a check-in (that steers / interrupts) or assume a hang while progress is updating.";
|
|
2749
|
+
var MCP_WAIT_QUEUED_HINT = "Child is queued waiting for a concurrency slot \u2014 it has not started yet. Call wait_for_turn again. Do not send_to_thread a check-in (that steers / interrupts), force_stop, or assume it failed to start.";
|
|
2750
2750
|
function mcpWaitStillRunningHint(status) {
|
|
2751
2751
|
return status === "queued" ? MCP_WAIT_QUEUED_HINT : MCP_WAIT_STILL_RUNNING_HINT;
|
|
2752
2752
|
}
|
|
@@ -3874,7 +3874,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3874
3874
|
return readThread(thread.id) ?? thread;
|
|
3875
3875
|
}
|
|
3876
3876
|
async function listLinearIssues(agent, repoPath) {
|
|
3877
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
3877
|
+
const { getAdapter: getAdapter2 } = await import("./agents-TXGQIK2E.js");
|
|
3878
3878
|
await requireAgent(agent, { requireLinear: true });
|
|
3879
3879
|
const adapter = getAdapter2(agent);
|
|
3880
3880
|
if (!adapter.listLinearIssues) {
|
|
@@ -4296,7 +4296,7 @@ async function adoptThread(input) {
|
|
|
4296
4296
|
messages: input.messages ?? []
|
|
4297
4297
|
});
|
|
4298
4298
|
writeThread(thread);
|
|
4299
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
4299
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ZYPME3YD.js");
|
|
4300
4300
|
await ensureWorkspace2(repoPath);
|
|
4301
4301
|
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-X54WSOXM.js");
|
|
4302
4302
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
@@ -6805,7 +6805,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
6805
6805
|
${prompt}`;
|
|
6806
6806
|
}
|
|
6807
6807
|
async function defaultDeps() {
|
|
6808
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
6808
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-LWEZ74RK.js");
|
|
6809
6809
|
const orch = getOrchestrator2();
|
|
6810
6810
|
return {
|
|
6811
6811
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -6936,6 +6936,10 @@ function resolveSendFollowUp(thread, requested) {
|
|
|
6936
6936
|
if (requested === "steer" || requested === "queue") return requested;
|
|
6937
6937
|
return isOrchestratorThread(thread) ? followUpBehavior() : "queue";
|
|
6938
6938
|
}
|
|
6939
|
+
function resolveOrchChildFollowUp(requested) {
|
|
6940
|
+
if (requested === "steer" || requested === "queue") return requested;
|
|
6941
|
+
return followUpBehavior();
|
|
6942
|
+
}
|
|
6939
6943
|
var STALE_AGENT_PID_WAIT_MS = 2500;
|
|
6940
6944
|
function writeLiveStatus(threadId, status, lastError) {
|
|
6941
6945
|
const latest = readThread(threadId);
|
|
@@ -8748,7 +8752,7 @@ var Orchestrator = class {
|
|
|
8748
8752
|
/**
|
|
8749
8753
|
* Desktop git buttons + MCP `ask_git`.
|
|
8750
8754
|
* When the worktree is clean, push / open the PR here (HTTPS via `gh` if SSH
|
|
8751
|
-
* is missing). When dirty,
|
|
8755
|
+
* is missing). When dirty, steer the worktree agent to commit first.
|
|
8752
8756
|
*/
|
|
8753
8757
|
async askGit(threadRef, action) {
|
|
8754
8758
|
if (!AGENT_GIT_ACTIONS.includes(action)) {
|
|
@@ -8785,7 +8789,9 @@ var Orchestrator = class {
|
|
|
8785
8789
|
} catch {
|
|
8786
8790
|
}
|
|
8787
8791
|
}
|
|
8788
|
-
return this.send(threadRef, agentGitPrompt(action, { prBase })
|
|
8792
|
+
return this.send(threadRef, agentGitPrompt(action, { prBase }), {
|
|
8793
|
+
followUp: resolveOrchChildFollowUp()
|
|
8794
|
+
});
|
|
8789
8795
|
}
|
|
8790
8796
|
/** Push origin (gh HTTPS fallback) and create/update the PR when requested. */
|
|
8791
8797
|
async pushAndMaybeOpenPr(thread, action) {
|
|
@@ -8929,7 +8935,7 @@ var Orchestrator = class {
|
|
|
8929
8935
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
8930
8936
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
8931
8937
|
try {
|
|
8932
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
8938
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ZYPME3YD.js");
|
|
8933
8939
|
await ensureWorkspace2(thread.repoPath);
|
|
8934
8940
|
} catch {
|
|
8935
8941
|
}
|
|
@@ -9348,6 +9354,7 @@ export {
|
|
|
9348
9354
|
isPidAlive,
|
|
9349
9355
|
waitForPidExit,
|
|
9350
9356
|
resolveSendFollowUp,
|
|
9357
|
+
resolveOrchChildFollowUp,
|
|
9351
9358
|
Orchestrator,
|
|
9352
9359
|
getOrchestrator,
|
|
9353
9360
|
startOrchestration,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isOrchestratorThread
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VV7UT3E2.js";
|
|
4
4
|
import {
|
|
5
5
|
codexUnattendedGitConfigArgs,
|
|
6
6
|
mergeAgentGitAuthEnv,
|
|
@@ -1908,7 +1908,7 @@ var claudeAdapter = {
|
|
|
1908
1908
|
);
|
|
1909
1909
|
}
|
|
1910
1910
|
const mode = permissionMode(thread);
|
|
1911
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
1911
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-JTBBH2K5.js");
|
|
1912
1912
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
1913
1913
|
const injectedServers = await buildInjectedMcpServers({
|
|
1914
1914
|
includeSideboard: true,
|
|
@@ -395,8 +395,8 @@ var COORDINATOR_TOOL_PLAYBOOK = [
|
|
|
395
395
|
"- start_board_card \u2014 same as create_thread for a ticket/PR/named branch (attaches issue text when resolvable). Then send_to_thread.",
|
|
396
396
|
"- fork_worktree \u2014 fork a worktree chat into a NEW git worktree + chat (transcript attached); optional agent; leave model unset (Auto) unless you have a reason. Not for orchestration chats.",
|
|
397
397
|
"- fork_chat \u2014 fork a worktree chat (same worktree tab) OR a Global orchestration chat (new orchestration tab); optional agent; leave model unset (Auto) unless you have a reason. Remote coordinators: use this to continue another orchestration chat on a different agent after session limits.",
|
|
398
|
-
"- send_to_thread \u2014
|
|
399
|
-
"- wait_for_turn / get_turn_result \u2014 wait for and read the agent reply (includes last-turn usage / costUsd when the child agent reported it). wait_for_turn returns within ~45s even if the child is still working (MCP clients kill longer tool calls). stillRunning is the source of truth \u2014 if it is false, the child is not working; do not tell the user it is running or \u201Cwaiting for a gate,\u201D even if status still says running/queued. If stillRunning is true, progress is a live snapshot of tools/thinking \u2014 call wait_for_turn again. status=queued with no lastActivityAt means the child has not started yet (concurrency cap) \u2014 keep waiting; do not force_stop or
|
|
398
|
+
"- send_to_thread \u2014 steer a prompt (start/continue a chat turn; Settings \u2192 Follow-up, default steer: interrupt and start now). force_stop: true only to replace a wrong in-flight request and clear the inbox \u2014 never to check in, resume after a halt notice, or because wait_for_turn returned stillRunning (that interrupts the child mid-thought)",
|
|
399
|
+
"- wait_for_turn / get_turn_result \u2014 wait for and read the agent reply (includes last-turn usage / costUsd when the child agent reported it). wait_for_turn returns within ~45s even if the child is still working (MCP clients kill longer tool calls). stillRunning is the source of truth \u2014 if it is false, the child is not working; do not tell the user it is running or \u201Cwaiting for a gate,\u201D even if status still says running/queued. If stillRunning is true, progress is a live snapshot of tools/thinking \u2014 call wait_for_turn again. status=queued with no lastActivityAt means the child has not started yet (concurrency cap) \u2014 keep waiting; do not force_stop or send_to_thread a check-in (that steers / interrupts). Do not send \u201Care you stuck?\u201D or assume a hang while lastActivityAt is recent. If stillRunning stays true across many waits with the same lastActivityAt, the child is stuck \u2014 tell the user; do not invent a gate. On status error, lastError (and text) is the failure \u2014 switch agent, tell the user, or retry; do not treat empty text as success. On status stopped or broken (or incomplete=true), the child was interrupted or died \u2014 resume with send_to_thread or tell the user; never treat stopped as a finished turn. Sideboard also injects a notice into this chat when a child stops unexpectedly.",
|
|
400
400
|
"- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
|
|
401
401
|
"- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
|
|
402
402
|
"Setup / run:",
|
|
@@ -406,7 +406,7 @@ var COORDINATOR_TOOL_PLAYBOOK = [
|
|
|
406
406
|
"- get_diff \u2014 compact diff summary",
|
|
407
407
|
"- get_pr_checks \u2014 snapshot of a worktree thread's PR checks (null = no PR). Use this to inspect status. If the user gave a goal, the worktree agent watches with `gh pr checks --watch` \u2014 do not poll for the human.",
|
|
408
408
|
'- request_review \u2014 open a Review chat tab on a worktree thread (attaches .claude/skills/review/SKILL.md when present, else .context/review.md copied from .sideboard/review.md / stock; sends "Review changes in this workspace."); then wait_for_turn (loop while stillRunning) / get_turn_result on the returned id. The review stays in that chat so they can read it and type next steps \u2014 do not tell the child to comment or update the PR or ticket.',
|
|
409
|
-
"- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it
|
|
409
|
+
"- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it steers the worktree agent \u2014 then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If ask_git / get_thread lastError says the GraphQL/PR body is too long, the branch is already pushed \u2014 send_to_thread so the worktree agent runs `gh pr create --body-file` with a short description. Do not invent SSH or auth failures from that error. If the user gave a goal (Greptile 5/5, CI green), send_to_thread that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
|
|
410
410
|
'- Merge (`ask_git` action=merge / send_to_thread "Merge PR.") only when the user explicitly asked to merge that PR. Do not merge because the work looks done, CI is green, or a typical flow includes it.',
|
|
411
411
|
'- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
|
|
412
412
|
"Process guides:",
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "./chunk-Y4MIXGPA.js";
|
|
12
12
|
import {
|
|
13
13
|
isOrchestratorThread
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-7NSXGL6L.js";
|
|
15
15
|
import {
|
|
16
16
|
codexUnattendedGitConfigArgs,
|
|
17
17
|
mergeAgentGitAuthEnv,
|
|
@@ -2390,7 +2390,7 @@ var claudeAdapter = {
|
|
|
2390
2390
|
);
|
|
2391
2391
|
}
|
|
2392
2392
|
const mode = permissionMode(thread);
|
|
2393
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
2393
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-2BVCJUAL.js");
|
|
2394
2394
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
2395
2395
|
const injectedServers = await buildInjectedMcpServers({
|
|
2396
2396
|
includeSideboard: true,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
orchestratorSessionPoisonedByBuiltins,
|
|
18
18
|
slackCoordinatorSourceRef,
|
|
19
19
|
takenTeamSlugsForOrchestration
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-7NSXGL6L.js";
|
|
21
21
|
import "./chunk-XBLN52RZ.js";
|
|
22
22
|
import "./chunk-D6JWYJ4P.js";
|
|
23
23
|
import "./chunk-GOZ6T3AG.js";
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
orchestratorSessionPoisonedByBuiltins,
|
|
16
16
|
slackCoordinatorSourceRef,
|
|
17
17
|
takenTeamSlugsForOrchestration
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-VV7UT3E2.js";
|
|
19
19
|
import "./chunk-WXKXSZN4.js";
|
|
20
20
|
import "./chunk-6K64FJDD.js";
|
|
21
21
|
import "./chunk-J7LQVLFQ.js";
|
package/dist/index.cjs
CHANGED
|
@@ -7772,8 +7772,8 @@ var init_coordinator_prompt = __esm({
|
|
|
7772
7772
|
"- start_board_card \u2014 same as create_thread for a ticket/PR/named branch (attaches issue text when resolvable). Then send_to_thread.",
|
|
7773
7773
|
"- fork_worktree \u2014 fork a worktree chat into a NEW git worktree + chat (transcript attached); optional agent; leave model unset (Auto) unless you have a reason. Not for orchestration chats.",
|
|
7774
7774
|
"- fork_chat \u2014 fork a worktree chat (same worktree tab) OR a Global orchestration chat (new orchestration tab); optional agent; leave model unset (Auto) unless you have a reason. Remote coordinators: use this to continue another orchestration chat on a different agent after session limits.",
|
|
7775
|
-
"- send_to_thread \u2014
|
|
7776
|
-
"- wait_for_turn / get_turn_result \u2014 wait for and read the agent reply (includes last-turn usage / costUsd when the child agent reported it). wait_for_turn returns within ~45s even if the child is still working (MCP clients kill longer tool calls). stillRunning is the source of truth \u2014 if it is false, the child is not working; do not tell the user it is running or \u201Cwaiting for a gate,\u201D even if status still says running/queued. If stillRunning is true, progress is a live snapshot of tools/thinking \u2014 call wait_for_turn again. status=queued with no lastActivityAt means the child has not started yet (concurrency cap) \u2014 keep waiting; do not force_stop or
|
|
7775
|
+
"- send_to_thread \u2014 steer a prompt (start/continue a chat turn; Settings \u2192 Follow-up, default steer: interrupt and start now). force_stop: true only to replace a wrong in-flight request and clear the inbox \u2014 never to check in, resume after a halt notice, or because wait_for_turn returned stillRunning (that interrupts the child mid-thought)",
|
|
7776
|
+
"- wait_for_turn / get_turn_result \u2014 wait for and read the agent reply (includes last-turn usage / costUsd when the child agent reported it). wait_for_turn returns within ~45s even if the child is still working (MCP clients kill longer tool calls). stillRunning is the source of truth \u2014 if it is false, the child is not working; do not tell the user it is running or \u201Cwaiting for a gate,\u201D even if status still says running/queued. If stillRunning is true, progress is a live snapshot of tools/thinking \u2014 call wait_for_turn again. status=queued with no lastActivityAt means the child has not started yet (concurrency cap) \u2014 keep waiting; do not force_stop or send_to_thread a check-in (that steers / interrupts). Do not send \u201Care you stuck?\u201D or assume a hang while lastActivityAt is recent. If stillRunning stays true across many waits with the same lastActivityAt, the child is stuck \u2014 tell the user; do not invent a gate. On status error, lastError (and text) is the failure \u2014 switch agent, tell the user, or retry; do not treat empty text as success. On status stopped or broken (or incomplete=true), the child was interrupted or died \u2014 resume with send_to_thread or tell the user; never treat stopped as a finished turn. Sideboard also injects a notice into this chat when a child stops unexpectedly.",
|
|
7777
7777
|
"- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
|
|
7778
7778
|
"- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
|
|
7779
7779
|
"Setup / run:",
|
|
@@ -7783,7 +7783,7 @@ var init_coordinator_prompt = __esm({
|
|
|
7783
7783
|
"- get_diff \u2014 compact diff summary",
|
|
7784
7784
|
"- get_pr_checks \u2014 snapshot of a worktree thread's PR checks (null = no PR). Use this to inspect status. If the user gave a goal, the worktree agent watches with `gh pr checks --watch` \u2014 do not poll for the human.",
|
|
7785
7785
|
'- request_review \u2014 open a Review chat tab on a worktree thread (attaches .claude/skills/review/SKILL.md when present, else .context/review.md copied from .sideboard/review.md / stock; sends "Review changes in this workspace."); then wait_for_turn (loop while stillRunning) / get_turn_result on the returned id. The review stays in that chat so they can read it and type next steps \u2014 do not tell the child to comment or update the PR or ticket.',
|
|
7786
|
-
"- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it
|
|
7786
|
+
"- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it steers the worktree agent \u2014 then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If ask_git / get_thread lastError says the GraphQL/PR body is too long, the branch is already pushed \u2014 send_to_thread so the worktree agent runs `gh pr create --body-file` with a short description. Do not invent SSH or auth failures from that error. If the user gave a goal (Greptile 5/5, CI green), send_to_thread that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
|
|
7787
7787
|
'- Merge (`ask_git` action=merge / send_to_thread "Merge PR.") only when the user explicitly asked to merge that PR. Do not merge because the work looks done, CI is green, or a typical flow includes it.',
|
|
7788
7788
|
'- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
|
|
7789
7789
|
"Process guides:",
|
|
@@ -15956,8 +15956,8 @@ var init_wait_for_turn = __esm({
|
|
|
15956
15956
|
"src/mcp/wait-for-turn.ts"() {
|
|
15957
15957
|
"use strict";
|
|
15958
15958
|
MCP_WAIT_FOR_TURN_MAX_MS = 45e3;
|
|
15959
|
-
MCP_WAIT_STILL_RUNNING_HINT = "Child is still working. Call wait_for_turn again. Do not
|
|
15960
|
-
MCP_WAIT_QUEUED_HINT = "Child is queued waiting for a concurrency slot \u2014 it has not started yet. Call wait_for_turn again. Do not
|
|
15959
|
+
MCP_WAIT_STILL_RUNNING_HINT = "Child is still working. Call wait_for_turn again. Do not send_to_thread a check-in (that steers / interrupts) or assume a hang while progress is updating.";
|
|
15960
|
+
MCP_WAIT_QUEUED_HINT = "Child is queued waiting for a concurrency slot \u2014 it has not started yet. Call wait_for_turn again. Do not send_to_thread a check-in (that steers / interrupts), force_stop, or assume it failed to start.";
|
|
15961
15961
|
MCP_WAIT_STOPPED_HINT = "Child was stopped before the turn finished. Do not treat this as success. send_to_thread to resume, or tell the user.";
|
|
15962
15962
|
MCP_WAIT_BROKEN_HINT = "Child worktree is broken (missing on disk). Tell the user \u2014 do not treat this as success.";
|
|
15963
15963
|
MCP_WAIT_ERROR_HINT = "Child turn failed. lastError/text is the failure \u2014 switch agent, tell the user, or retry. Do not treat empty text as success.";
|
|
@@ -20831,6 +20831,7 @@ __export(orchestrator_exports, {
|
|
|
20831
20831
|
Orchestrator: () => Orchestrator,
|
|
20832
20832
|
getOrchestrator: () => getOrchestrator,
|
|
20833
20833
|
isPidAlive: () => isPidAlive,
|
|
20834
|
+
resolveOrchChildFollowUp: () => resolveOrchChildFollowUp,
|
|
20834
20835
|
resolveSendFollowUp: () => resolveSendFollowUp,
|
|
20835
20836
|
startOrchestration: () => startOrchestration,
|
|
20836
20837
|
waitForPidExit: () => waitForPidExit
|
|
@@ -20861,6 +20862,10 @@ function resolveSendFollowUp(thread, requested) {
|
|
|
20861
20862
|
if (requested === "steer" || requested === "queue") return requested;
|
|
20862
20863
|
return isOrchestratorThread(thread) ? followUpBehavior() : "queue";
|
|
20863
20864
|
}
|
|
20865
|
+
function resolveOrchChildFollowUp(requested) {
|
|
20866
|
+
if (requested === "steer" || requested === "queue") return requested;
|
|
20867
|
+
return followUpBehavior();
|
|
20868
|
+
}
|
|
20864
20869
|
function writeLiveStatus(threadId, status, lastError) {
|
|
20865
20870
|
const latest = readThread(threadId);
|
|
20866
20871
|
if (!latest || latest.status === "archived") return latest;
|
|
@@ -22801,7 +22806,7 @@ var init_orchestrator = __esm({
|
|
|
22801
22806
|
/**
|
|
22802
22807
|
* Desktop git buttons + MCP `ask_git`.
|
|
22803
22808
|
* When the worktree is clean, push / open the PR here (HTTPS via `gh` if SSH
|
|
22804
|
-
* is missing). When dirty,
|
|
22809
|
+
* is missing). When dirty, steer the worktree agent to commit first.
|
|
22805
22810
|
*/
|
|
22806
22811
|
async askGit(threadRef, action) {
|
|
22807
22812
|
if (!AGENT_GIT_ACTIONS.includes(action)) {
|
|
@@ -22838,7 +22843,9 @@ var init_orchestrator = __esm({
|
|
|
22838
22843
|
} catch {
|
|
22839
22844
|
}
|
|
22840
22845
|
}
|
|
22841
|
-
return this.send(threadRef, agentGitPrompt(action, { prBase })
|
|
22846
|
+
return this.send(threadRef, agentGitPrompt(action, { prBase }), {
|
|
22847
|
+
followUp: resolveOrchChildFollowUp()
|
|
22848
|
+
});
|
|
22842
22849
|
}
|
|
22843
22850
|
/** Push origin (gh HTTPS fallback) and create/update the PR when requested. */
|
|
22844
22851
|
async pushAndMaybeOpenPr(thread, action) {
|
|
@@ -23859,6 +23866,7 @@ __export(index_exports, {
|
|
|
23859
23866
|
resolveLoginCommand: () => resolveLoginCommand,
|
|
23860
23867
|
resolveNewOrchestratorOptions: () => resolveNewOrchestratorOptions,
|
|
23861
23868
|
resolveNewThreadOptions: () => resolveNewThreadOptions,
|
|
23869
|
+
resolveOrchChildFollowUp: () => resolveOrchChildFollowUp,
|
|
23862
23870
|
resolveOrchestratorDefaults: () => resolveOrchestratorDefaults,
|
|
23863
23871
|
resolvePlanMarkdown: () => resolvePlanMarkdown,
|
|
23864
23872
|
resolvePrSelector: () => resolvePrSelector,
|
|
@@ -24605,6 +24613,16 @@ query SideboardLabels($first: Int!) {
|
|
|
24605
24613
|
}
|
|
24606
24614
|
}
|
|
24607
24615
|
`;
|
|
24616
|
+
var TEAM_LABELS_QUERY = `
|
|
24617
|
+
query SideboardTeamLabels($id: String!, $first: Int!, $after: String) {
|
|
24618
|
+
team(id: $id) {
|
|
24619
|
+
labels(first: $first, after: $after) {
|
|
24620
|
+
nodes { id name }
|
|
24621
|
+
pageInfo { hasNextPage endCursor }
|
|
24622
|
+
}
|
|
24623
|
+
}
|
|
24624
|
+
}
|
|
24625
|
+
`;
|
|
24608
24626
|
var PROJECTS_QUERY = `
|
|
24609
24627
|
query SideboardProjects($first: Int!, $filter: ProjectFilter) {
|
|
24610
24628
|
projects(first: $first, filter: $filter) {
|
|
@@ -24978,15 +24996,38 @@ function formatRelationList(relations) {
|
|
|
24978
24996
|
if (!relations.length) return "(none)";
|
|
24979
24997
|
return relations.map((r) => `${r.type} ${r.issue.identifier || r.issue.id}`).join(", ");
|
|
24980
24998
|
}
|
|
24981
|
-
|
|
24982
|
-
|
|
24983
|
-
return (json.issueLabels?.nodes ?? []).flatMap((node) => {
|
|
24999
|
+
function mapLabelNodes(nodes) {
|
|
25000
|
+
return (nodes ?? []).flatMap((node) => {
|
|
24984
25001
|
const id = String(node.id ?? "").trim();
|
|
24985
25002
|
const name = String(node.name ?? "").trim();
|
|
24986
25003
|
if (!id) return [];
|
|
24987
25004
|
return [{ id, name }];
|
|
24988
25005
|
});
|
|
24989
25006
|
}
|
|
25007
|
+
async function listLinearWorkspaceLabels(opts) {
|
|
25008
|
+
const json = await linearGraphql(LABELS_QUERY, { first: 250 }, opts);
|
|
25009
|
+
return mapLabelNodes(json.issueLabels?.nodes);
|
|
25010
|
+
}
|
|
25011
|
+
async function listLinearLabels(opts) {
|
|
25012
|
+
const teamId = opts?.teamId?.trim();
|
|
25013
|
+
if (teamId) {
|
|
25014
|
+
const out = [];
|
|
25015
|
+
let after;
|
|
25016
|
+
for (let page = 0; page < 4; page++) {
|
|
25017
|
+
const json = await linearGraphql(
|
|
25018
|
+
TEAM_LABELS_QUERY,
|
|
25019
|
+
after ? { id: teamId, first: 250, after } : { id: teamId, first: 250 },
|
|
25020
|
+
opts
|
|
25021
|
+
);
|
|
25022
|
+
const conn = json.team?.labels;
|
|
25023
|
+
out.push(...mapLabelNodes(conn?.nodes));
|
|
25024
|
+
if (!conn?.pageInfo?.hasNextPage || !conn.pageInfo.endCursor) break;
|
|
25025
|
+
after = conn.pageInfo.endCursor;
|
|
25026
|
+
}
|
|
25027
|
+
if (out.length) return out;
|
|
25028
|
+
}
|
|
25029
|
+
return listLinearWorkspaceLabels(opts);
|
|
25030
|
+
}
|
|
24990
25031
|
async function listLinearProjects(filter, opts) {
|
|
24991
25032
|
const json = await linearGraphql(PROJECTS_QUERY, { first: 50, filter: filter ?? {} }, opts);
|
|
24992
25033
|
return (json.projects?.nodes ?? []).flatMap((node) => {
|
|
@@ -25281,7 +25322,7 @@ async function updateLinearIssue(input, opts) {
|
|
|
25281
25322
|
}
|
|
25282
25323
|
const addRelations = input.relations?.length ? input.relations : void 0;
|
|
25283
25324
|
const removeRelations = input.removeRelations?.length ? input.removeRelations : void 0;
|
|
25284
|
-
const needsIssue = Boolean(input.state?.trim()) || input.cycle !== void 0 || Boolean(addRelations) || Boolean(removeRelations);
|
|
25325
|
+
const needsIssue = Boolean(input.state?.trim()) || input.cycle !== void 0 || input.labels !== void 0 || Boolean(addRelations) || Boolean(removeRelations);
|
|
25285
25326
|
const existing = needsIssue ? await getLinearIssue(issueId, opts) : void 0;
|
|
25286
25327
|
if (input.state?.trim()) {
|
|
25287
25328
|
const { teams } = await listLinearTeams(opts);
|
|
@@ -25316,7 +25357,10 @@ async function updateLinearIssue(input, opts) {
|
|
|
25316
25357
|
mutationInput.priority = normalizePriority(input.priority);
|
|
25317
25358
|
}
|
|
25318
25359
|
if (input.labels !== void 0) {
|
|
25319
|
-
mutationInput.labelIds = await resolveLinearLabelIds(input.labels,
|
|
25360
|
+
mutationInput.labelIds = await resolveLinearLabelIds(input.labels, {
|
|
25361
|
+
...opts,
|
|
25362
|
+
teamId: existing?.team?.id
|
|
25363
|
+
});
|
|
25320
25364
|
}
|
|
25321
25365
|
if (input.project !== void 0) {
|
|
25322
25366
|
mutationInput.projectId = await resolveLinearProjectId(input.project, opts);
|
|
@@ -25622,7 +25666,7 @@ function parseProjectTitles(raw) {
|
|
|
25622
25666
|
}
|
|
25623
25667
|
async function listGitHubIssueProjects(number, cwd, repoArgs) {
|
|
25624
25668
|
const result = await gh(
|
|
25625
|
-
["issue", "view", String(number), ...repoArgs, "--json", "projectItems
|
|
25669
|
+
["issue", "view", String(number), ...repoArgs, "--json", "projectItems"],
|
|
25626
25670
|
cwd,
|
|
25627
25671
|
{ reject: false }
|
|
25628
25672
|
);
|
|
@@ -28956,7 +29000,7 @@ async function startMcpServer() {
|
|
|
28956
29000
|
);
|
|
28957
29001
|
server.tool(
|
|
28958
29002
|
"send_to_thread",
|
|
28959
|
-
'
|
|
29003
|
+
'Steer a prompt on a worktree thread chat (Settings \u2192 Follow-up, default steer: interrupt and start now, skip the inbox). Use after create_thread to start or continue a conversation. For commit/push/PR, prefer ask_git (canonical desktop-button phrases). Send "Merge PR." / ask_git merge only when the user explicitly asked to merge. force_stop=true kills the in-flight turn and clears the queue before this prompt \u2014 only when the current request is wrong and must be replaced. Do not send_to_thread to check in, resume after a halt notice, or because wait_for_turn returned stillRunning; that interrupts the child mid-thought. Call wait_for_turn again instead.',
|
|
28960
29004
|
{
|
|
28961
29005
|
ref: import_zod9.z.string(),
|
|
28962
29006
|
prompt: import_zod9.z.string(),
|
|
@@ -28969,7 +29013,9 @@ async function startMcpServer() {
|
|
|
28969
29013
|
orch.stop(ref, { clearQueue: true, notifyParent: false });
|
|
28970
29014
|
}
|
|
28971
29015
|
}
|
|
28972
|
-
const thread = await orch.send(ref, prompt
|
|
29016
|
+
const thread = await orch.send(ref, prompt, {
|
|
29017
|
+
followUp: resolveOrchChildFollowUp()
|
|
29018
|
+
});
|
|
28973
29019
|
return mcpJson({
|
|
28974
29020
|
id: thread.id,
|
|
28975
29021
|
status: thread.status,
|
|
@@ -28980,7 +29026,7 @@ async function startMcpServer() {
|
|
|
28980
29026
|
);
|
|
28981
29027
|
server.tool(
|
|
28982
29028
|
"wait_for_turn",
|
|
28983
|
-
"Wait until the thread 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. stillRunning is the source of truth \u2014 if false, the child is not working (do not say it is waiting for a gate). If stillRunning is true, progress is tools/thinking (or \u201Cqueued, waiting for a concurrency slot\u201D if it has not started). Call wait_for_turn again. Do not
|
|
29029
|
+
"Wait until the thread 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. stillRunning is the source of truth \u2014 if false, the child is not working (do not say it is waiting for a gate). If stillRunning is true, progress is tools/thinking (or \u201Cqueued, waiting for a concurrency slot\u201D if it has not started). Call wait_for_turn again. Do not send_to_thread a check-in (that steers / interrupts), force_stop, or assume a hang. On status error, lastError/text is the failure. On status stopped or broken, the child did not finish \u2014 resume with send_to_thread or tell the user; do not treat that as success. When finished, usage is the last agent turn\u2019s tokens + costUsd (when the provider reported cost).",
|
|
28984
29030
|
{
|
|
28985
29031
|
ref: import_zod9.z.string(),
|
|
28986
29032
|
timeoutMs: import_zod9.z.number().optional()
|
|
@@ -29137,7 +29183,7 @@ async function startMcpServer() {
|
|
|
29137
29183
|
);
|
|
29138
29184
|
server.tool(
|
|
29139
29185
|
"ask_git",
|
|
29140
|
-
"Commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge \u2014 same actions as the desktop git buttons. When the worktree is clean, Sideboard pushes / opens the PR itself (HTTPS via `gh` even when origin is SSH / Settings \u2192 Git is SSH). When dirty,
|
|
29186
|
+
"Commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge \u2014 same actions as the desktop git buttons. When the worktree is clean, Sideboard pushes / opens the PR itself (HTTPS via `gh` even when origin is SSH / Settings \u2192 Git is SSH). When dirty, steers the worktree agent to commit (Settings \u2192 Follow-up, default interrupt now); then wait_for_turn (loop while stillRunning). Do not start a checks loop on a plain push \u2014 only if the user gave a goal (Greptile 5/5, CI green). Pass a worktree thread ref (not the orchestrator). action=ready-for-review and action=merge only when the user explicitly asked (or clicked the desktop button). Do not run git or gh from the orchestration cwd. If this tool errors that the GraphQL/PR body is too long, the branch is already pushed \u2014 have the worktree agent retry `gh pr create --body-file` with a short description (GitHub limit 65,536 characters). Do not invent SSH/auth failures from that error.",
|
|
29141
29187
|
{
|
|
29142
29188
|
ref: import_zod9.z.string().describe("Worktree thread id/ref"),
|
|
29143
29189
|
action: import_zod9.z.enum(AGENT_GIT_ACTIONS).describe(
|
|
@@ -32430,6 +32476,7 @@ init_outbound_watch();
|
|
|
32430
32476
|
resolveLoginCommand,
|
|
32431
32477
|
resolveNewOrchestratorOptions,
|
|
32432
32478
|
resolveNewThreadOptions,
|
|
32479
|
+
resolveOrchChildFollowUp,
|
|
32433
32480
|
resolveOrchestratorDefaults,
|
|
32434
32481
|
resolvePlanMarkdown,
|
|
32435
32482
|
resolvePrSelector,
|