@sideboard-ai/core 0.1.150 → 0.1.152
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-YWBQXOA2.js → agents-CUKWIM34.js} +6 -6
- package/dist/{agents-KKXGTEV6.js → agents-VHXCBBBD.js} +6 -6
- package/dist/{chunk-W6N6GQME.js → chunk-2SDMENAL.js} +1 -1
- package/dist/{chunk-NOTANBYC.js → chunk-2U6QF3PT.js} +7 -6
- package/dist/{chunk-Z2PVJKMN.js → chunk-3JBMACYX.js} +2 -2
- package/dist/{chunk-QGJHIJHV.js → chunk-67TIJ7S5.js} +2 -2
- package/dist/{chunk-NUPITVRF.js → chunk-6X7Z34XE.js} +105 -60
- package/dist/{chunk-DXCNW2JF.js → chunk-7BQNSUR2.js} +96 -75
- package/dist/{chunk-DMRIZR6M.js → chunk-7TIUOYBK.js} +7 -6
- package/dist/{chunk-YGGBJY5A.js → chunk-EY6QXPPO.js} +3 -3
- package/dist/{chunk-AF6O55PJ.js → chunk-G4MTYUWS.js} +3 -3
- package/dist/{chunk-ZGFYFVJF.js → chunk-GE7M3QTE.js} +2 -2
- package/dist/{chunk-SDN4ZYQH.js → chunk-GFQ57XAX.js} +3 -3
- package/dist/{chunk-WHU7YGWP.js → chunk-JRH62XC4.js} +4 -0
- package/dist/{chunk-HAS5EPBS.js → chunk-K2ANSHUO.js} +2 -2
- package/dist/{chunk-Y4NAPW5I.js → chunk-QQKDGPUI.js} +16 -13
- package/dist/{chunk-PTOSP4AH.js → chunk-RFMQY56R.js} +1 -1
- package/dist/{chunk-VO4SPEBS.js → chunk-SN6CMKF6.js} +3 -3
- package/dist/{chunk-VSFGPWCQ.js → chunk-SYFVUF2C.js} +16 -13
- package/dist/{coordinator-prompt-UCQJTFA7.js → coordinator-prompt-TBX4MOFM.js} +4 -4
- package/dist/{coordinator-prompt-NYR5TPBD.js → coordinator-prompt-WGFRYCHE.js} +4 -4
- package/dist/{global-workspace-4QHDAD2D.js → global-workspace-BHLUJ46D.js} +5 -5
- package/dist/{global-workspace-4SENNWBU.js → global-workspace-IY5QAV5C.js} +5 -5
- package/dist/index.cjs +138 -64
- package/dist/index.d.cts +39 -21
- package/dist/index.d.ts +39 -21
- package/dist/index.js +38 -12
- package/dist/mcp/run-stdio.cjs +120 -79
- package/dist/mcp/run-stdio.js +28 -12
- package/dist/{orchestrator-GZE4X3XV.js → orchestrator-256DFPSX.js} +9 -9
- package/dist/{orchestrator-QSBRWME5.js → orchestrator-NUA6SEV7.js} +9 -9
- package/dist/{plan-file-5S5TUNAW.js → plan-file-LSSSQGTQ.js} +2 -2
- package/dist/{plan-file-IBSU2PVW.js → plan-file-OZEBFSGQ.js} +2 -2
- package/dist/{workspaces-RDUSB6FD.js → workspaces-4FSXVIZM.js} +6 -6
- package/dist/{workspaces-7S7QKCUE.js → workspaces-NECIQTAO.js} +6 -6
- package/dist/{worktree-63AGPPLO.js → worktree-DPIREDFR.js} +3 -3
- package/dist/{worktree-JIZ3QMZX.js → worktree-HTUM35NT.js} +3 -3
- package/dist/{worktree-exclude-6MQWGWV5.js → worktree-exclude-N5X5I422.js} +3 -1
- package/dist/{worktree-exclude-TV6EV6BS.js → worktree-exclude-X54WSOXM.js} +3 -1
- package/package.json +1 -1
- /package/dist/{chunk-Y7YBWWIG.js → chunk-NVXVEGGM.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
CONTEXT_KEEP_RECENT_CHARS,
|
|
10
10
|
CONTEXT_KEEP_RECENT_MESSAGES,
|
|
11
11
|
CONTEXT_MIN_MESSAGES,
|
|
12
|
+
CONTEXT_REVIEW_PATH,
|
|
12
13
|
DEFAULT_WORKTREE_SORT,
|
|
13
14
|
HOME_BOARD_AGENT_HINT,
|
|
14
15
|
HOME_BOARD_CACHE_TTL_MS,
|
|
@@ -71,6 +72,7 @@ import {
|
|
|
71
72
|
disconnectOptionalService,
|
|
72
73
|
disconnectSlackWorkspace,
|
|
73
74
|
discoverSkills,
|
|
75
|
+
ensureReviewGuidelinesFile,
|
|
74
76
|
ensureReviewRequestFile,
|
|
75
77
|
ensureReviewSkillFile,
|
|
76
78
|
estimateMessageChars,
|
|
@@ -98,6 +100,7 @@ import {
|
|
|
98
100
|
formatMessagesAsTranscript,
|
|
99
101
|
formatOptionalServicesDirective,
|
|
100
102
|
formatOptionalServicesReminder,
|
|
103
|
+
formatPrGateDirective,
|
|
101
104
|
formatProcessGuideDirective,
|
|
102
105
|
formatRenameBranchDirective,
|
|
103
106
|
formatScheduleWhen,
|
|
@@ -213,7 +216,7 @@ import {
|
|
|
213
216
|
worktreeCleanupSettings,
|
|
214
217
|
wrapReviewSkillMarkdown,
|
|
215
218
|
writeWorktreeFile
|
|
216
|
-
} from "./chunk-
|
|
219
|
+
} from "./chunk-6X7Z34XE.js";
|
|
217
220
|
import {
|
|
218
221
|
LEGACY_PLAN_FILE_REL,
|
|
219
222
|
PLAN_FILE_NAME,
|
|
@@ -224,7 +227,7 @@ import {
|
|
|
224
227
|
readPlanFile,
|
|
225
228
|
resolvePlanMarkdown,
|
|
226
229
|
writePlanFile
|
|
227
|
-
} from "./chunk-
|
|
230
|
+
} from "./chunk-RFMQY56R.js";
|
|
228
231
|
import {
|
|
229
232
|
BRIGHTSY_MCP_ALLOWED_TOOLS,
|
|
230
233
|
CLAUDE_MODEL_CATALOG,
|
|
@@ -307,7 +310,7 @@ import {
|
|
|
307
310
|
withEventParentId,
|
|
308
311
|
withEventsParentId,
|
|
309
312
|
writeInjectedMcpConfig
|
|
310
|
-
} from "./chunk-
|
|
313
|
+
} from "./chunk-GFQ57XAX.js";
|
|
311
314
|
import {
|
|
312
315
|
brightsyMcpServerName,
|
|
313
316
|
connectBrightsyTeam,
|
|
@@ -332,7 +335,7 @@ import {
|
|
|
332
335
|
listWorkspaces,
|
|
333
336
|
removeWorkspace,
|
|
334
337
|
syncWorkspacesFromThreads
|
|
335
|
-
} from "./chunk-
|
|
338
|
+
} from "./chunk-K2ANSHUO.js";
|
|
336
339
|
import {
|
|
337
340
|
CLOUD_COORDINATOR_BUSY_REPLY,
|
|
338
341
|
CLOUD_COORDINATOR_STOPPED_REPLY,
|
|
@@ -367,7 +370,7 @@ import {
|
|
|
367
370
|
stageAbsolutePathsAsAttachments,
|
|
368
371
|
stageBuffersAsAttachments,
|
|
369
372
|
takenTeamSlugsForOrchestration
|
|
370
|
-
} from "./chunk-
|
|
373
|
+
} from "./chunk-G4MTYUWS.js";
|
|
371
374
|
import {
|
|
372
375
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
373
376
|
SLACK_REPLY_FORMATTING,
|
|
@@ -376,7 +379,7 @@ import {
|
|
|
376
379
|
enrichWorkspacesWithGithub,
|
|
377
380
|
ensureGlobalCoordinatorCwd,
|
|
378
381
|
formatWorkspaceInventory
|
|
379
|
-
} from "./chunk-
|
|
382
|
+
} from "./chunk-2U6QF3PT.js";
|
|
380
383
|
import {
|
|
381
384
|
FAMOUS_SOCCER_TEAMS,
|
|
382
385
|
GITHUB_PR_BODY_MAX_CHARS,
|
|
@@ -468,13 +471,15 @@ import {
|
|
|
468
471
|
worktreeDisplayLabel,
|
|
469
472
|
worktreeDisplayLabelForGroup,
|
|
470
473
|
worktreeNameFromPath
|
|
471
|
-
} from "./chunk-
|
|
474
|
+
} from "./chunk-GE7M3QTE.js";
|
|
472
475
|
import {
|
|
473
476
|
ATTACHMENTS_DIR,
|
|
477
|
+
DETACHED_JOBS_DIR,
|
|
474
478
|
LEGACY_ATTACHMENTS_DIR,
|
|
479
|
+
LEGACY_DETACHED_JOBS_DIR,
|
|
475
480
|
attachmentsGitignoreBody,
|
|
476
481
|
isWorkspaceScratchPath
|
|
477
|
-
} from "./chunk-
|
|
482
|
+
} from "./chunk-JRH62XC4.js";
|
|
478
483
|
import {
|
|
479
484
|
ABLETIME_MCP_PATH,
|
|
480
485
|
DEFAULT_ABLETIME_HOST,
|
|
@@ -649,7 +654,7 @@ import {
|
|
|
649
654
|
workspaceSettingsSourceLabel,
|
|
650
655
|
worktreesRoot
|
|
651
656
|
} from "./chunk-QZQEXME2.js";
|
|
652
|
-
import "./chunk-
|
|
657
|
+
import "./chunk-QQKDGPUI.js";
|
|
653
658
|
import {
|
|
654
659
|
conductorBundledBinDir,
|
|
655
660
|
enrichPathWithNpmGlobalBin,
|
|
@@ -3579,7 +3584,7 @@ async function startMcpServer() {
|
|
|
3579
3584
|
thread_id: z5.string().optional().describe("Sideboard thread id when cwd is not the worktree")
|
|
3580
3585
|
},
|
|
3581
3586
|
async ({ title, content, thread_id }) => {
|
|
3582
|
-
const { writePlanFile: writePlanFile2 } = await import("./plan-file-
|
|
3587
|
+
const { writePlanFile: writePlanFile2 } = await import("./plan-file-LSSSQGTQ.js");
|
|
3583
3588
|
let root = process.cwd();
|
|
3584
3589
|
if (thread_id?.trim()) {
|
|
3585
3590
|
const t = orch.getThread(thread_id.trim());
|
|
@@ -4022,9 +4027,25 @@ async function startMcpServer() {
|
|
|
4022
4027
|
};
|
|
4023
4028
|
}
|
|
4024
4029
|
);
|
|
4030
|
+
server.tool(
|
|
4031
|
+
"get_pr_checks",
|
|
4032
|
+
"Snapshot of GitHub PR checks for a worktree thread (`gh pr checks` plus merge/review gates). null = no PR. If the user gave a goal (Greptile 5/5, CI green), the worktree agent watches with `gh pr checks --watch` via /long-running \u2014 this tool is a snapshot, not a waiter. Coordinators: do not run gh from the orchestration cwd.",
|
|
4033
|
+
{ ref: z5.string().describe("Worktree thread id/ref") },
|
|
4034
|
+
async ({ ref }) => {
|
|
4035
|
+
try {
|
|
4036
|
+
const checks = await orch.getPrChecks(ref);
|
|
4037
|
+
return {
|
|
4038
|
+
content: [{ type: "text", text: JSON.stringify(checks) }]
|
|
4039
|
+
};
|
|
4040
|
+
} catch (err) {
|
|
4041
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
4042
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
4043
|
+
}
|
|
4044
|
+
}
|
|
4045
|
+
);
|
|
4025
4046
|
server.tool(
|
|
4026
4047
|
"request_review",
|
|
4027
|
-
'Start a merge-readiness Review on a worktree agent thread (same as the desktop Review button). Opens a new Review chat tab, attaches .claude/skills/review/SKILL.md when present (else
|
|
4048
|
+
'Start a merge-readiness Review on a worktree agent thread (same as the desktop Review button). Opens a new Review chat tab, attaches .claude/skills/review/SKILL.md when present (else copies .sideboard/review.md into .context/review.md, or seeds that file from the stock template), and sends "Review changes in this workspace." Expect Approve / Approve with nits / Request changes / Needs more information. Pass a worktree thread ref \u2014 not the orchestrator. Then wait_for_turn (loop while stillRunning) / get_turn_result on the returned review tab id.',
|
|
4028
4049
|
{ ref: z5.string().describe("Worktree thread id/ref to review") },
|
|
4029
4050
|
async ({ ref }) => {
|
|
4030
4051
|
try {
|
|
@@ -4052,7 +4073,7 @@ async function startMcpServer() {
|
|
|
4052
4073
|
);
|
|
4053
4074
|
server.tool(
|
|
4054
4075
|
"ask_git",
|
|
4055
|
-
"Commit & push, open a draft PR, 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, queues the worktree agent to commit; then wait_for_turn (loop while stillRunning). Pass a worktree thread ref (not the orchestrator). action=merge only when the user explicitly asked to merge that PR. 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.",
|
|
4076
|
+
"Commit & push, open a draft PR, 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, queues the worktree agent to commit; 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=merge only when the user explicitly asked to merge that PR. 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.",
|
|
4056
4077
|
{
|
|
4057
4078
|
ref: z5.string().describe("Worktree thread id/ref"),
|
|
4058
4079
|
action: z5.enum(AGENT_GIT_ACTIONS).describe(
|
|
@@ -6814,10 +6835,12 @@ export {
|
|
|
6814
6835
|
CONTEXT_KEEP_RECENT_CHARS,
|
|
6815
6836
|
CONTEXT_KEEP_RECENT_MESSAGES,
|
|
6816
6837
|
CONTEXT_MIN_MESSAGES,
|
|
6838
|
+
CONTEXT_REVIEW_PATH,
|
|
6817
6839
|
CONVENTION_SETUP_RELPATHS,
|
|
6818
6840
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
6819
6841
|
DEFAULT_ABLETIME_HOST,
|
|
6820
6842
|
DEFAULT_WORKTREE_SORT,
|
|
6843
|
+
DETACHED_JOBS_DIR,
|
|
6821
6844
|
FAMOUS_SOCCER_TEAMS,
|
|
6822
6845
|
FOLLOW_UP_BEHAVIORS,
|
|
6823
6846
|
GITHUB_GIT_AUTH_MODES,
|
|
@@ -6828,6 +6851,7 @@ export {
|
|
|
6828
6851
|
HOME_BOARD_CACHE_TTL_MS,
|
|
6829
6852
|
ISSUE_SOURCE_LABELS,
|
|
6830
6853
|
LEGACY_ATTACHMENTS_DIR,
|
|
6854
|
+
LEGACY_DETACHED_JOBS_DIR,
|
|
6831
6855
|
LEGACY_PLAN_FILE_REL,
|
|
6832
6856
|
LEGACY_REVIEW_REQUEST_PATH,
|
|
6833
6857
|
LINEAR_OAUTH_CANCELLED,
|
|
@@ -7018,6 +7042,7 @@ export {
|
|
|
7018
7042
|
ensureConnectedBrightsyTeamTokens,
|
|
7019
7043
|
ensureGhPreferOrigin,
|
|
7020
7044
|
ensureGlobalCoordinatorCwd,
|
|
7045
|
+
ensureReviewGuidelinesFile,
|
|
7021
7046
|
ensureReviewRequestFile,
|
|
7022
7047
|
ensureReviewSkillFile,
|
|
7023
7048
|
ensureSlackCoordinator,
|
|
@@ -7067,6 +7092,7 @@ export {
|
|
|
7067
7092
|
formatOptionalServicesReminder,
|
|
7068
7093
|
formatPlanQuestionAnswers,
|
|
7069
7094
|
formatPlanQuestionsForChat,
|
|
7095
|
+
formatPrGateDirective,
|
|
7070
7096
|
formatProcessGuideDirective,
|
|
7071
7097
|
formatRateLimitResetHint,
|
|
7072
7098
|
formatRenameBranchDirective,
|
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -2931,14 +2931,12 @@ var init_gh_errors = __esm({
|
|
|
2931
2931
|
// src/git/worktree-exclude.ts
|
|
2932
2932
|
var worktree_exclude_exports = {};
|
|
2933
2933
|
__export(worktree_exclude_exports, {
|
|
2934
|
+
WORKTREE_CONTEXT_EXCLUDE: () => WORKTREE_CONTEXT_EXCLUDE,
|
|
2934
2935
|
WORKTREE_SIDEBOARD_EXCLUDE: () => WORKTREE_SIDEBOARD_EXCLUDE,
|
|
2935
2936
|
ensureWorktreeSideboardIgnored: () => ensureWorktreeSideboardIgnored
|
|
2936
2937
|
});
|
|
2937
|
-
function
|
|
2938
|
-
return body.split(/\r?\n/).some((line) =>
|
|
2939
|
-
const t = line.trim();
|
|
2940
|
-
return t === ".sideboard/" || t === ".sideboard" || t === "/.sideboard/";
|
|
2941
|
-
});
|
|
2938
|
+
function excludeHasLine(body, ...needles) {
|
|
2939
|
+
return body.split(/\r?\n/).some((line) => needles.includes(line.trim()));
|
|
2942
2940
|
}
|
|
2943
2941
|
async function ensureWorktreeSideboardIgnored(worktreePath) {
|
|
2944
2942
|
if (!worktreePath.trim()) return;
|
|
@@ -2957,16 +2955,20 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
|
|
|
2957
2955
|
} catch {
|
|
2958
2956
|
body = "";
|
|
2959
2957
|
}
|
|
2960
|
-
|
|
2958
|
+
const missing = [];
|
|
2959
|
+
if (!excludeHasLine(body, ".sideboard/", ".sideboard", "/.sideboard/")) {
|
|
2960
|
+
missing.push(WORKTREE_SIDEBOARD_EXCLUDE);
|
|
2961
|
+
}
|
|
2962
|
+
if (!excludeHasLine(body, ".context/", ".context", "/.context/")) {
|
|
2963
|
+
missing.push(WORKTREE_CONTEXT_EXCLUDE);
|
|
2964
|
+
}
|
|
2965
|
+
if (missing.length > 0) {
|
|
2961
2966
|
const prefix = body && !body.endsWith("\n") ? `${body}
|
|
2962
2967
|
` : body;
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
`,
|
|
2968
|
-
"utf8"
|
|
2969
|
-
);
|
|
2968
|
+
const header = body.includes(EXCLUDE_COMMENT) ? "" : `${EXCLUDE_COMMENT}
|
|
2969
|
+
`;
|
|
2970
|
+
(0, import_node_fs13.writeFileSync)(excludePath, `${prefix}${header}${missing.join("\n")}
|
|
2971
|
+
`, "utf8");
|
|
2970
2972
|
}
|
|
2971
2973
|
const listed = await git(["ls-files", "-z", "--", ".sideboard"], worktreePath, {
|
|
2972
2974
|
reject: false,
|
|
@@ -2980,7 +2982,7 @@ ${WORKTREE_SIDEBOARD_EXCLUDE}
|
|
|
2980
2982
|
timeoutMs: 8e3
|
|
2981
2983
|
});
|
|
2982
2984
|
}
|
|
2983
|
-
var import_node_fs13, import_node_path14, WORKTREE_SIDEBOARD_EXCLUDE, EXCLUDE_COMMENT;
|
|
2985
|
+
var import_node_fs13, import_node_path14, WORKTREE_SIDEBOARD_EXCLUDE, WORKTREE_CONTEXT_EXCLUDE, EXCLUDE_COMMENT;
|
|
2984
2986
|
var init_worktree_exclude = __esm({
|
|
2985
2987
|
"src/git/worktree-exclude.ts"() {
|
|
2986
2988
|
"use strict";
|
|
@@ -2988,6 +2990,7 @@ var init_worktree_exclude = __esm({
|
|
|
2988
2990
|
import_node_path14 = require("path");
|
|
2989
2991
|
init_run();
|
|
2990
2992
|
WORKTREE_SIDEBOARD_EXCLUDE = ".sideboard/";
|
|
2993
|
+
WORKTREE_CONTEXT_EXCLUDE = ".context/";
|
|
2991
2994
|
EXCLUDE_COMMENT = "# Sideboard worktree scratch \u2014 do not commit";
|
|
2992
2995
|
}
|
|
2993
2996
|
});
|
|
@@ -6740,7 +6743,7 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
6740
6743
|
"Typical flow (Home board): list_board \u2192 create_thread (sourceType=ticket|pr|branch) \u2192 send_to_thread \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft \u2192 wait_for_turn. Merge only if the user explicitly asked (`ask_git` merge).",
|
|
6741
6744
|
"Typical flow (branch / explicit source): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
|
|
6742
6745
|
"Typical flow (new app): Bash create/clone under repos dir \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
|
|
6743
|
-
"Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
|
|
6746
|
+
"Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). If the user gave a goal (Greptile 5/5, CI green), pass that goal through so they watch-fix-push until it lands \u2014 do not start that loop on a plain push, and do not tell the human to poll. Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
|
|
6744
6747
|
].join("\n");
|
|
6745
6748
|
try {
|
|
6746
6749
|
(0, import_node_fs17.writeFileSync)((0, import_node_path20.join)(dir, "CLAUDE.md"), `${body}
|
|
@@ -6820,15 +6823,16 @@ var init_coordinator_prompt = __esm({
|
|
|
6820
6823
|
"- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
|
|
6821
6824
|
"Inspect / review / PRs:",
|
|
6822
6825
|
"- get_diff \u2014 compact diff summary",
|
|
6823
|
-
|
|
6824
|
-
|
|
6826
|
+
"- 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.",
|
|
6827
|
+
'- 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',
|
|
6828
|
+
"- ask_git \u2014 commit & push, open a draft PR, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it queues 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.",
|
|
6825
6829
|
'- 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.',
|
|
6826
6830
|
'- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "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.',
|
|
6827
6831
|
"Process guides:",
|
|
6828
6832
|
"- Long child jobs (pack, test, deploy, anything that may run more than ~30s): workers always have `/long-running` (Sideboard product skill). Tell them to detach and wait; do not ask the human to poll.",
|
|
6829
6833
|
"- Recurring multi-item / fan-out: if the child worktree has `.claude/skills/graph-engineering/SKILL.md`, tell the worker to follow it (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch three threads.",
|
|
6830
|
-
"- Recurring shapes: have the worktree agent write `.claude/skills/<kebab-name>/SKILL.md` (commit it) so later threads and native Claude Code / attach see it. Merge-review sentences go in `.claude/skills/review/SKILL.md` (
|
|
6831
|
-
"- One-offs: no guide. Same miss across threads: edit the skill or `.
|
|
6834
|
+
"- Recurring shapes: have the worktree agent write `.claude/skills/<kebab-name>/SKILL.md` (commit it) so later threads and native Claude Code / attach see it. Merge-review sentences go in `.claude/skills/review/SKILL.md` when that skill already exists; otherwise `.context/review.md` (do not create a review skill). Do not use `.sideboard/skills/` (that folder only). Codex/OpenCode: one line in AGENTS.md pointing at that file.",
|
|
6835
|
+
"- One-offs: no guide. Same miss across threads: edit the existing skill or `.context/review.md`, then rerun the batch \u2014 do not patch three threads.",
|
|
6832
6836
|
"Human-only (do not attempt): ready-for-review land (confirm_land), purge_thread.",
|
|
6833
6837
|
"Thread links in replies: when mentioning a chat/thread for the user, include a markdown link `[Title](sideboard://thread/<id>)` using the full id (or the link field from create_thread / list_threads). Sideboard renders these as clickable opens.",
|
|
6834
6838
|
"Bash / Read / etc: allowed for (1) inspecting target worktrees / registered repo paths from MCP, and (2) greenfield setup under ~/sideboard/repos (git clone, gh repo create, git init+remote). Never git init/clone *inside* this synthetic home cwd \u2014 emptiness here is expected, not a bug."
|
|
@@ -12107,17 +12111,7 @@ var init_chat_tabs = __esm({
|
|
|
12107
12111
|
});
|
|
12108
12112
|
|
|
12109
12113
|
// src/review/review-request-template.ts
|
|
12110
|
-
|
|
12111
|
-
const trimmed = body.replace(/^\uFEFF/, "").trim();
|
|
12112
|
-
const source = trimmed || REVIEW_REQUEST_TEMPLATE.trim();
|
|
12113
|
-
if (/^---\s*\n[\s\S]*?\n---\s*\n/.test(source)) {
|
|
12114
|
-
return source.endsWith("\n") ? source : `${source}
|
|
12115
|
-
`;
|
|
12116
|
-
}
|
|
12117
|
-
return `${REVIEW_SKILL_FRONTMATTER}${source}
|
|
12118
|
-
`;
|
|
12119
|
-
}
|
|
12120
|
-
var REVIEW_REQUEST_TEMPLATE, REVIEW_SKILL_PATH, REVIEW_SKILL_NAME, REVIEW_SKILL_FRONTMATTER;
|
|
12114
|
+
var REVIEW_REQUEST_TEMPLATE, REVIEW_SKILL_PATH, REVIEW_SKILL_NAME;
|
|
12121
12115
|
var init_review_request_template = __esm({
|
|
12122
12116
|
"src/review/review-request-template.ts"() {
|
|
12123
12117
|
"use strict";
|
|
@@ -12240,18 +12234,10 @@ File: src/client/frontends/desktop/core/UserData.ts
|
|
|
12240
12234
|
|
|
12241
12235
|
## Growing the rules
|
|
12242
12236
|
|
|
12243
|
-
If a blocking issue is a missing or ambiguous repo rule that will recur, add one sentence to \`.claude/skills/review/SKILL.md\`
|
|
12237
|
+
If a blocking issue is a missing or ambiguous repo rule that will recur, add one sentence to \`.claude/skills/review/SKILL.md\` when that skill already exists. Otherwise write it to \`.context/review.md\` (do not create a review skill). Do not only patch this diff when the same miss will happen again. Do not write new skills under \`.sideboard/skills/\`.
|
|
12244
12238
|
`;
|
|
12245
12239
|
REVIEW_SKILL_PATH = ".claude/skills/review/SKILL.md";
|
|
12246
12240
|
REVIEW_SKILL_NAME = "review";
|
|
12247
|
-
REVIEW_SKILL_FRONTMATTER = `---
|
|
12248
|
-
name: review
|
|
12249
|
-
description: >-
|
|
12250
|
-
Merge-readiness review for this repository. Use when reviewing a PR, worktree
|
|
12251
|
-
diff, or Sideboard Review (Approve / Approve with nits / Request changes).
|
|
12252
|
-
---
|
|
12253
|
-
|
|
12254
|
-
`;
|
|
12255
12241
|
}
|
|
12256
12242
|
});
|
|
12257
12243
|
|
|
@@ -12294,37 +12280,57 @@ function skillGuidelines(content, source) {
|
|
|
12294
12280
|
source
|
|
12295
12281
|
};
|
|
12296
12282
|
}
|
|
12297
|
-
function
|
|
12298
|
-
|
|
12299
|
-
|
|
12300
|
-
|
|
12301
|
-
|
|
12302
|
-
|
|
12303
|
-
|
|
12304
|
-
const fromLocal = readLocalGuidelines(worktreePath)?.content ?? null;
|
|
12305
|
-
const content = wrapReviewSkillMarkdown(fromRepo ?? fromLocal ?? REVIEW_REQUEST_TEMPLATE);
|
|
12306
|
-
(0, import_node_fs29.mkdirSync)((0, import_node_path29.dirname)(abs), { recursive: true });
|
|
12307
|
-
(0, import_node_fs29.writeFileSync)(abs, content, "utf8");
|
|
12308
|
-
return { path: REVIEW_SKILL_PATH, content, wrote: true };
|
|
12283
|
+
function contextGuidelines(content, source) {
|
|
12284
|
+
return {
|
|
12285
|
+
path: CONTEXT_REVIEW_PATH,
|
|
12286
|
+
name: REPO_REVIEW_NAME,
|
|
12287
|
+
content,
|
|
12288
|
+
source
|
|
12289
|
+
};
|
|
12309
12290
|
}
|
|
12310
|
-
function
|
|
12291
|
+
function writeContextGuidelines(worktreePath, content) {
|
|
12292
|
+
const abs = (0, import_node_path29.join)(worktreePath, CONTEXT_REVIEW_PATH);
|
|
12293
|
+
(0, import_node_fs29.mkdirSync)((0, import_node_path29.dirname)(abs), { recursive: true });
|
|
12294
|
+
const body = content.endsWith("\n") ? content : `${content}
|
|
12295
|
+
`;
|
|
12296
|
+
(0, import_node_fs29.writeFileSync)(abs, body, "utf8");
|
|
12297
|
+
return body;
|
|
12298
|
+
}
|
|
12299
|
+
function readSideboardReview(worktreePath, repoPath) {
|
|
12300
|
+
const fromWorktree = readTextIfPresent((0, import_node_path29.join)(worktreePath, REPO_REVIEW_PATH));
|
|
12301
|
+
if (fromWorktree) return fromWorktree;
|
|
12302
|
+
const repo = repoPath?.replace(/\/+$/, "");
|
|
12303
|
+
const wt = worktreePath.replace(/\/+$/, "");
|
|
12304
|
+
if (!repo || repo === wt) return null;
|
|
12305
|
+
return readTextIfPresent((0, import_node_path29.join)(repo, REPO_REVIEW_PATH));
|
|
12306
|
+
}
|
|
12307
|
+
function ensureReviewGuidelinesFile(worktreePath, repoPath) {
|
|
12311
12308
|
const skillContent = readTextIfPresent((0, import_node_path29.join)(worktreePath, REVIEW_SKILL_PATH));
|
|
12312
|
-
if (skillContent)
|
|
12313
|
-
|
|
12314
|
-
|
|
12315
|
-
|
|
12316
|
-
|
|
12317
|
-
|
|
12318
|
-
|
|
12319
|
-
|
|
12320
|
-
|
|
12309
|
+
if (skillContent) {
|
|
12310
|
+
return { ...skillGuidelines(skillContent, "skill"), wrote: false };
|
|
12311
|
+
}
|
|
12312
|
+
const contextContent = readTextIfPresent((0, import_node_path29.join)(worktreePath, CONTEXT_REVIEW_PATH));
|
|
12313
|
+
if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
|
|
12314
|
+
return { ...contextGuidelines(contextContent, "local"), wrote: false };
|
|
12315
|
+
}
|
|
12316
|
+
const fromSideboard = readSideboardReview(worktreePath, repoPath);
|
|
12317
|
+
if (fromSideboard && !shouldRefreshReviewRequestTemplate(fromSideboard)) {
|
|
12318
|
+
const body2 = writeContextGuidelines(worktreePath, fromSideboard);
|
|
12319
|
+
return { ...contextGuidelines(body2, "repo"), wrote: true };
|
|
12321
12320
|
}
|
|
12322
|
-
const
|
|
12323
|
-
|
|
12321
|
+
const local = readLocalGuidelines(worktreePath);
|
|
12322
|
+
const body = writeContextGuidelines(worktreePath, local?.content ?? REVIEW_REQUEST_TEMPLATE);
|
|
12323
|
+
return {
|
|
12324
|
+
...contextGuidelines(body, local ? "local" : "stock"),
|
|
12325
|
+
wrote: true
|
|
12326
|
+
};
|
|
12327
|
+
}
|
|
12328
|
+
function resolveReviewGuidelines(worktreePath, repoPath) {
|
|
12329
|
+
return ensureReviewGuidelinesFile(worktreePath, repoPath);
|
|
12324
12330
|
}
|
|
12325
12331
|
function buildReviewRequestAttachment(content, opts) {
|
|
12326
12332
|
const path = opts?.path ?? REVIEW_SKILL_PATH;
|
|
12327
|
-
const name = opts?.name ?? (path === REVIEW_SKILL_PATH ? REVIEW_SKILL_NAME : path === REPO_REVIEW_PATH ? REPO_REVIEW_NAME : REVIEW_REQUEST_NAME);
|
|
12333
|
+
const name = opts?.name ?? (path === REVIEW_SKILL_PATH ? REVIEW_SKILL_NAME : path === REPO_REVIEW_PATH || path === CONTEXT_REVIEW_PATH ? REPO_REVIEW_NAME : REVIEW_REQUEST_NAME);
|
|
12328
12334
|
return {
|
|
12329
12335
|
id: (0, import_node_crypto7.randomUUID)(),
|
|
12330
12336
|
name,
|
|
@@ -12344,7 +12350,7 @@ async function requestReview(threadRef, send) {
|
|
|
12344
12350
|
if (from.status === "archived") {
|
|
12345
12351
|
throw new Error(`Thread is archived: ${from.id}`);
|
|
12346
12352
|
}
|
|
12347
|
-
const guidelines = resolveReviewGuidelines(from.worktreePath);
|
|
12353
|
+
const guidelines = resolveReviewGuidelines(from.worktreePath, from.repoPath);
|
|
12348
12354
|
const tab = createChatTab({
|
|
12349
12355
|
fromThreadId: from.id,
|
|
12350
12356
|
title: "Review",
|
|
@@ -12358,7 +12364,7 @@ async function requestReview(threadRef, send) {
|
|
|
12358
12364
|
const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
|
|
12359
12365
|
return { tab: started, from };
|
|
12360
12366
|
}
|
|
12361
|
-
var import_node_crypto7, import_node_fs29, import_node_path29, REPO_REVIEW_PATH, REPO_REVIEW_NAME, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
|
|
12367
|
+
var import_node_crypto7, import_node_fs29, import_node_path29, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
|
|
12362
12368
|
var init_request_review = __esm({
|
|
12363
12369
|
"src/review/request-review.ts"() {
|
|
12364
12370
|
"use strict";
|
|
@@ -12372,6 +12378,7 @@ var init_request_review = __esm({
|
|
|
12372
12378
|
init_workspace_scratch();
|
|
12373
12379
|
REPO_REVIEW_PATH = ".sideboard/review.md";
|
|
12374
12380
|
REPO_REVIEW_NAME = "review.md";
|
|
12381
|
+
CONTEXT_REVIEW_PATH = ".context/review.md";
|
|
12375
12382
|
REVIEW_REQUEST_PATH = `${ATTACHMENTS_DIR}/Review request.md`;
|
|
12376
12383
|
LEGACY_REVIEW_REQUEST_PATH = `${LEGACY_ATTACHMENTS_DIR}/Review request.md`;
|
|
12377
12384
|
REVIEW_REQUEST_NAME = "Review request.md";
|
|
@@ -12625,11 +12632,9 @@ async function runConventionSetup(repoPath, worktreePath, onLine, opts) {
|
|
|
12625
12632
|
}
|
|
12626
12633
|
async function runWorkspaceSetup(repoPath, worktreePath, onLine, opts) {
|
|
12627
12634
|
await ensureWorktreeSideboardIgnored(worktreePath);
|
|
12628
|
-
const
|
|
12629
|
-
if (
|
|
12630
|
-
onLine?.(
|
|
12631
|
-
`[setup] wrote ${REVIEW_SKILL_PATH} \u2014 commit it so later worktrees inherit Review guidelines`
|
|
12632
|
-
);
|
|
12635
|
+
const review = ensureReviewGuidelinesFile(worktreePath, repoPath);
|
|
12636
|
+
if (review.wrote) {
|
|
12637
|
+
onLine?.(`[setup] wrote ${review.path} \u2014 local Review guidelines`);
|
|
12633
12638
|
}
|
|
12634
12639
|
let setup = await runSetupScript(repoPath, worktreePath, onLine, opts);
|
|
12635
12640
|
if (!setup.ran) {
|
|
@@ -16177,7 +16182,7 @@ node <detached-job.js> wait <id> --until-done
|
|
|
16177
16182
|
node <detached-job.js> status <id>
|
|
16178
16183
|
\`\`\`
|
|
16179
16184
|
|
|
16180
|
-
\`<id>\` is kebab-case (\`mac-release\`, \`core-test\`, \`fly-deploy\`). State is \`.sideboard/detached-jobs/<id>/\` (local scratch).
|
|
16185
|
+
\`<id>\` is kebab-case (\`mac-release\`, \`core-test\`, \`fly-deploy\`). State is \`.context/.sideboard/detached-jobs/<id>/\` (local scratch).
|
|
16181
16186
|
|
|
16182
16187
|
Wait JSON:
|
|
16183
16188
|
|
|
@@ -16215,6 +16220,16 @@ node <detached-job.js> wait --pid-file FILE --log-file FILE [--ok-pattern TEXT]
|
|
|
16215
16220
|
4. On \`ok\`, present once more (\`status=ok\`, last \`delta\`) and finish the task. On \`failed\`, fix from the log.
|
|
16216
16221
|
|
|
16217
16222
|
Never tell the user \u201Csay status when it\u2019s done.\u201D You wait.
|
|
16223
|
+
|
|
16224
|
+
## PR checks (only if a goal is given)
|
|
16225
|
+
|
|
16226
|
+
Do **not** watch after every push. If the user gave a goal (Greptile 5/5, CI green, until checks pass), wait the same way:
|
|
16227
|
+
|
|
16228
|
+
\`\`\`bash
|
|
16229
|
+
node <detached-job.js> start pr-checks -- gh pr checks --watch
|
|
16230
|
+
\`\`\`
|
|
16231
|
+
|
|
16232
|
+
On miss, fix, commit, push, and watch again until the goal is met or you are blocked. Do not ask the human to poll. Do not merge unless asked.
|
|
16218
16233
|
`;
|
|
16219
16234
|
}
|
|
16220
16235
|
});
|
|
@@ -16604,7 +16619,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
16604
16619
|
"Short git requests from the Sideboard UI are complete instructions \u2014 expand them using the rules above without asking for clarification:"
|
|
16605
16620
|
);
|
|
16606
16621
|
lines.push(
|
|
16607
|
-
'- "Commit and push." \u2192 commit any uncommitted work with a purpose-stating message, then push to origin (updates an existing PR if one is linked).'
|
|
16622
|
+
'- "Commit and push." \u2192 commit any uncommitted work with a purpose-stating message, then push to origin (updates an existing PR if one is linked). Do not start a checks loop unless they gave a goal.'
|
|
16608
16623
|
);
|
|
16609
16624
|
lines.push(
|
|
16610
16625
|
'- "Commit, push, and open a draft PR." \u2192 commit, push, then create a draft PR with `gh pr create --draft -R \u2026` (title/body from the change purpose).'
|
|
@@ -16613,7 +16628,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
16613
16628
|
'- "Commit, push, and open a PR in the browser." \u2192 commit, push, then `gh pr create --web -R \u2026`.'
|
|
16614
16629
|
);
|
|
16615
16630
|
lines.push(
|
|
16616
|
-
'- "Fix CI: <name>." \u2192 investigate that failing check, fix it, commit, and push.'
|
|
16631
|
+
'- "Fix CI: <name>." \u2192 investigate that failing check, fix it, commit, and push. Loop only if they gave a goal to keep going until it passes.'
|
|
16617
16632
|
);
|
|
16618
16633
|
lines.push(
|
|
16619
16634
|
'- "Merge the remote branch (<base>) into your branch and resolve conflicts. Then, commit and push your changes." \u2192 fetch the PR base, merge it into this branch, resolve conflicts carefully, commit, and push until the PR is mergeable.'
|
|
@@ -16625,11 +16640,21 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
16625
16640
|
'- "Merge PR." \u2192 merge this thread\'s open pull request on GitHub (this phrase is the explicit ask). If `gh stack view` shows a stack, use `gh stack merge`; otherwise `gh pr merge` (respect repo defaults / squash vs merge). Do not force-push main/master or merge locally into the main checkout.'
|
|
16626
16641
|
);
|
|
16627
16642
|
lines.push("");
|
|
16643
|
+
lines.push(formatPrGateDirective());
|
|
16644
|
+
lines.push("");
|
|
16628
16645
|
lines.push(formatProcessGuideDirective());
|
|
16629
16646
|
return lines.join("\n");
|
|
16630
16647
|
}
|
|
16631
16648
|
function formatWorktreeReminder() {
|
|
16632
|
-
return "Sideboard worktree: stay in this cwd for all file and git work. Push and open PRs against origin, never upstream. Do not edit the main repo checkout.";
|
|
16649
|
+
return "Sideboard worktree: stay in this cwd for all file and git work. Push and open PRs against origin, never upstream. Do not edit the main repo checkout. If a goal is given (Greptile 5/5, CI green), watch-fix-push until it lands \u2014 do not watch after every push.";
|
|
16650
|
+
}
|
|
16651
|
+
function formatPrGateDirective() {
|
|
16652
|
+
return [
|
|
16653
|
+
"If a goal is given (not after every push):",
|
|
16654
|
+
"- Enter a watch-fix-push loop and stay in it until that goal is met or you are blocked (examples: \u201CGreptile 5/5\u201D, \u201CCI green\u201D, \u201Cuntil checks pass\u201D). Do not stop after one red run or one review cycle.",
|
|
16655
|
+
"- Wait with `/long-running`: `gh pr checks --watch` (add `-R <origin>` when needed). Present the log. Do not ask the human to poll.",
|
|
16656
|
+
"- Greptile 5/5: wait for the greptile check; read the latest `N/5` from the PR body or Greptile\u2019s most recently *updated* issue comment; also fetch unresolved review comments / the \u201CPrompt to fix all with AI\u201D block. Done = **5/5 and zero unresolved Greptile comments**. If Greptile is idle, comment `@greptile review`. Cap about 5 iterations, then report leftovers. Do not merge unless asked."
|
|
16657
|
+
].join("\n");
|
|
16633
16658
|
}
|
|
16634
16659
|
function formatProcessGuideDirective() {
|
|
16635
16660
|
return [
|
|
@@ -16637,7 +16662,7 @@ function formatProcessGuideDirective() {
|
|
|
16637
16662
|
"- Long jobs (pack, test, deploy, anything that may run more than ~30s): Sideboard always provides `/long-running`. Detach and wait \u2014 do not ask the human to poll.",
|
|
16638
16663
|
"- If `.claude/skills/graph-engineering/SKILL.md` exists, follow it (`/graph-engineering`) for migrations, ports, batch fixes, and other fan-out. Judge first; state on disk; grow the rulebook; do not patch around it.",
|
|
16639
16664
|
"- If this same shape of work will happen again, write `.claude/skills/<kebab-name>/SKILL.md` in this worktree (Claude Code project skill). Sideboard `/name`, Claude Code, and `attach` all load that path. Do not leave the method only in chat.",
|
|
16640
|
-
"- Merge-readiness notes:
|
|
16665
|
+
"- Merge-readiness notes: if `.claude/skills/review/SKILL.md` already exists, edit it. Otherwise write them to `.context/review.md` (copied from `.sideboard/review.md` when that file exists). Do not create a review skill.",
|
|
16641
16666
|
"- Do not write new skills under `.sideboard/skills/` (that folder only \u2014 other `.sideboard/` files such as settings.toml are fine). Point Codex/OpenCode at the Claude skill from `AGENTS.md`. Optional: symlink `.cursor/skills/<name>` to the Claude skill.",
|
|
16642
16667
|
"- Skip a guide for a one-off. If a matching skill exists, follow it. Same miss twice \u2192 edit the skill, do not patch around it."
|
|
16643
16668
|
].join("\n");
|
|
@@ -16652,7 +16677,7 @@ function formatLongRunningDirective(opts) {
|
|
|
16652
16677
|
"- Immediately `present_artifact` `type=log` with `artifact_id=<id>` and `status=running` \u2014 the side column is the live view.",
|
|
16653
16678
|
`- Loop \`${invoke} wait <id>\` (returns in ~45s). stillRunning \u2192 present the same id with \`content=delta\` only \u2192 wait again. Do not resend the full log or HTML.`,
|
|
16654
16679
|
"- ok \u2192 finish the task. failed \u2192 read the log, fix, start once.",
|
|
16655
|
-
"State: `.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available)."
|
|
16680
|
+
"State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available)."
|
|
16656
16681
|
].join("\n");
|
|
16657
16682
|
}
|
|
16658
16683
|
function formatLongRunningReminder(opts) {
|
|
@@ -22502,9 +22527,25 @@ async function startMcpServer() {
|
|
|
22502
22527
|
};
|
|
22503
22528
|
}
|
|
22504
22529
|
);
|
|
22530
|
+
server.tool(
|
|
22531
|
+
"get_pr_checks",
|
|
22532
|
+
"Snapshot of GitHub PR checks for a worktree thread (`gh pr checks` plus merge/review gates). null = no PR. If the user gave a goal (Greptile 5/5, CI green), the worktree agent watches with `gh pr checks --watch` via /long-running \u2014 this tool is a snapshot, not a waiter. Coordinators: do not run gh from the orchestration cwd.",
|
|
22533
|
+
{ ref: import_zod5.z.string().describe("Worktree thread id/ref") },
|
|
22534
|
+
async ({ ref }) => {
|
|
22535
|
+
try {
|
|
22536
|
+
const checks = await orch.getPrChecks(ref);
|
|
22537
|
+
return {
|
|
22538
|
+
content: [{ type: "text", text: JSON.stringify(checks) }]
|
|
22539
|
+
};
|
|
22540
|
+
} catch (err) {
|
|
22541
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
22542
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
22543
|
+
}
|
|
22544
|
+
}
|
|
22545
|
+
);
|
|
22505
22546
|
server.tool(
|
|
22506
22547
|
"request_review",
|
|
22507
|
-
'Start a merge-readiness Review on a worktree agent thread (same as the desktop Review button). Opens a new Review chat tab, attaches .claude/skills/review/SKILL.md when present (else
|
|
22548
|
+
'Start a merge-readiness Review on a worktree agent thread (same as the desktop Review button). Opens a new Review chat tab, attaches .claude/skills/review/SKILL.md when present (else copies .sideboard/review.md into .context/review.md, or seeds that file from the stock template), and sends "Review changes in this workspace." Expect Approve / Approve with nits / Request changes / Needs more information. Pass a worktree thread ref \u2014 not the orchestrator. Then wait_for_turn (loop while stillRunning) / get_turn_result on the returned review tab id.',
|
|
22508
22549
|
{ ref: import_zod5.z.string().describe("Worktree thread id/ref to review") },
|
|
22509
22550
|
async ({ ref }) => {
|
|
22510
22551
|
try {
|
|
@@ -22532,7 +22573,7 @@ async function startMcpServer() {
|
|
|
22532
22573
|
);
|
|
22533
22574
|
server.tool(
|
|
22534
22575
|
"ask_git",
|
|
22535
|
-
"Commit & push, open a draft PR, 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, queues the worktree agent to commit; then wait_for_turn (loop while stillRunning). Pass a worktree thread ref (not the orchestrator). action=merge only when the user explicitly asked to merge that PR. 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.",
|
|
22576
|
+
"Commit & push, open a draft PR, 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, queues the worktree agent to commit; 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=merge only when the user explicitly asked to merge that PR. 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.",
|
|
22536
22577
|
{
|
|
22537
22578
|
ref: import_zod5.z.string().describe("Worktree thread id/ref"),
|
|
22538
22579
|
action: import_zod5.z.enum(AGENT_GIT_ACTIONS).describe(
|