@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
|
@@ -8,12 +8,10 @@ import {
|
|
|
8
8
|
import { mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
9
9
|
import { dirname, join } from "path";
|
|
10
10
|
var WORKTREE_SIDEBOARD_EXCLUDE = ".sideboard/";
|
|
11
|
+
var WORKTREE_CONTEXT_EXCLUDE = ".context/";
|
|
11
12
|
var EXCLUDE_COMMENT = "# Sideboard worktree scratch \u2014 do not commit";
|
|
12
|
-
function
|
|
13
|
-
return body.split(/\r?\n/).some((line) =>
|
|
14
|
-
const t = line.trim();
|
|
15
|
-
return t === ".sideboard/" || t === ".sideboard" || t === "/.sideboard/";
|
|
16
|
-
});
|
|
13
|
+
function excludeHasLine(body, ...needles) {
|
|
14
|
+
return body.split(/\r?\n/).some((line) => needles.includes(line.trim()));
|
|
17
15
|
}
|
|
18
16
|
async function ensureWorktreeSideboardIgnored(worktreePath) {
|
|
19
17
|
if (!worktreePath.trim()) return;
|
|
@@ -32,16 +30,20 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
|
|
|
32
30
|
} catch {
|
|
33
31
|
body = "";
|
|
34
32
|
}
|
|
35
|
-
|
|
33
|
+
const missing = [];
|
|
34
|
+
if (!excludeHasLine(body, ".sideboard/", ".sideboard", "/.sideboard/")) {
|
|
35
|
+
missing.push(WORKTREE_SIDEBOARD_EXCLUDE);
|
|
36
|
+
}
|
|
37
|
+
if (!excludeHasLine(body, ".context/", ".context", "/.context/")) {
|
|
38
|
+
missing.push(WORKTREE_CONTEXT_EXCLUDE);
|
|
39
|
+
}
|
|
40
|
+
if (missing.length > 0) {
|
|
36
41
|
const prefix = body && !body.endsWith("\n") ? `${body}
|
|
37
42
|
` : body;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
`,
|
|
43
|
-
"utf8"
|
|
44
|
-
);
|
|
43
|
+
const header = body.includes(EXCLUDE_COMMENT) ? "" : `${EXCLUDE_COMMENT}
|
|
44
|
+
`;
|
|
45
|
+
writeFileSync(excludePath, `${prefix}${header}${missing.join("\n")}
|
|
46
|
+
`, "utf8");
|
|
45
47
|
}
|
|
46
48
|
const listed = await git(["ls-files", "-z", "--", ".sideboard"], worktreePath, {
|
|
47
49
|
reject: false,
|
|
@@ -58,5 +60,6 @@ ${WORKTREE_SIDEBOARD_EXCLUDE}
|
|
|
58
60
|
|
|
59
61
|
export {
|
|
60
62
|
WORKTREE_SIDEBOARD_EXCLUDE,
|
|
63
|
+
WORKTREE_CONTEXT_EXCLUDE,
|
|
61
64
|
ensureWorktreeSideboardIgnored
|
|
62
65
|
};
|
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
enrichWorkspacesWithGithub,
|
|
10
10
|
ensureGlobalCoordinatorCwd,
|
|
11
11
|
formatWorkspaceInventory
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-7TIUOYBK.js";
|
|
13
|
+
import "./chunk-3JBMACYX.js";
|
|
14
|
+
import "./chunk-NVXVEGGM.js";
|
|
15
15
|
import "./chunk-EUXOHTUK.js";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-SYFVUF2C.js";
|
|
17
17
|
import "./chunk-FNQNJOHY.js";
|
|
18
18
|
import "./chunk-CZD4NRDZ.js";
|
|
19
19
|
import "./chunk-NSTQ6QKD.js";
|
|
@@ -7,16 +7,16 @@ import {
|
|
|
7
7
|
enrichWorkspacesWithGithub,
|
|
8
8
|
ensureGlobalCoordinatorCwd,
|
|
9
9
|
formatWorkspaceInventory
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-2U6QF3PT.js";
|
|
11
|
+
import "./chunk-GE7M3QTE.js";
|
|
12
|
+
import "./chunk-JRH62XC4.js";
|
|
13
13
|
import "./chunk-4XNSGDXE.js";
|
|
14
14
|
import "./chunk-4TR3HZFT.js";
|
|
15
15
|
import "./chunk-JT7R45JB.js";
|
|
16
16
|
import "./chunk-TUGKX5BD.js";
|
|
17
17
|
import "./chunk-77WWLBCI.js";
|
|
18
18
|
import "./chunk-QZQEXME2.js";
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-QQKDGPUI.js";
|
|
20
20
|
import "./chunk-UFHNSFAS.js";
|
|
21
21
|
export {
|
|
22
22
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
@@ -17,12 +17,12 @@ import {
|
|
|
17
17
|
orchestratorSessionPoisonedByBuiltins,
|
|
18
18
|
slackCoordinatorSourceRef,
|
|
19
19
|
takenTeamSlugsForOrchestration
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-
|
|
20
|
+
} from "./chunk-SN6CMKF6.js";
|
|
21
|
+
import "./chunk-7TIUOYBK.js";
|
|
22
|
+
import "./chunk-3JBMACYX.js";
|
|
23
|
+
import "./chunk-NVXVEGGM.js";
|
|
24
24
|
import "./chunk-EUXOHTUK.js";
|
|
25
|
-
import "./chunk-
|
|
25
|
+
import "./chunk-SYFVUF2C.js";
|
|
26
26
|
import "./chunk-FNQNJOHY.js";
|
|
27
27
|
import "./chunk-CZD4NRDZ.js";
|
|
28
28
|
import "./chunk-NSTQ6QKD.js";
|
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
orchestratorSessionPoisonedByBuiltins,
|
|
16
16
|
slackCoordinatorSourceRef,
|
|
17
17
|
takenTeamSlugsForOrchestration
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-
|
|
18
|
+
} from "./chunk-G4MTYUWS.js";
|
|
19
|
+
import "./chunk-2U6QF3PT.js";
|
|
20
|
+
import "./chunk-GE7M3QTE.js";
|
|
21
|
+
import "./chunk-JRH62XC4.js";
|
|
22
22
|
import "./chunk-4XNSGDXE.js";
|
|
23
23
|
import "./chunk-4TR3HZFT.js";
|
|
24
24
|
import "./chunk-JT7R45JB.js";
|
|
@@ -27,7 +27,7 @@ import "./chunk-77WWLBCI.js";
|
|
|
27
27
|
import {
|
|
28
28
|
globalAgentCwd
|
|
29
29
|
} from "./chunk-QZQEXME2.js";
|
|
30
|
-
import "./chunk-
|
|
30
|
+
import "./chunk-QQKDGPUI.js";
|
|
31
31
|
import "./chunk-UFHNSFAS.js";
|
|
32
32
|
export {
|
|
33
33
|
GLOBAL_WORKSPACE_ID,
|
package/dist/index.cjs
CHANGED
|
@@ -2883,12 +2883,14 @@ function isWorkspaceScratchPath(relativePath) {
|
|
|
2883
2883
|
const p = relativePath.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/$/, "");
|
|
2884
2884
|
return p === ATTACHMENTS_DIR || p.startsWith(`${ATTACHMENTS_DIR}/`) || p === LEGACY_ATTACHMENTS_DIR || p.startsWith(`${LEGACY_ATTACHMENTS_DIR}/`) || p === ".sideboard" || p.startsWith(".sideboard/") || p === ".context" || p.startsWith(".context/");
|
|
2885
2885
|
}
|
|
2886
|
-
var ATTACHMENTS_DIR, LEGACY_ATTACHMENTS_DIR, ATTACHMENTS_GITIGNORE;
|
|
2886
|
+
var ATTACHMENTS_DIR, DETACHED_JOBS_DIR, LEGACY_ATTACHMENTS_DIR, LEGACY_DETACHED_JOBS_DIR, ATTACHMENTS_GITIGNORE;
|
|
2887
2887
|
var init_workspace_scratch = __esm({
|
|
2888
2888
|
"src/paths/workspace-scratch.ts"() {
|
|
2889
2889
|
"use strict";
|
|
2890
2890
|
ATTACHMENTS_DIR = ".context/attachments";
|
|
2891
|
+
DETACHED_JOBS_DIR = ".context/.sideboard/detached-jobs";
|
|
2891
2892
|
LEGACY_ATTACHMENTS_DIR = ".sideboard/attachments";
|
|
2893
|
+
LEGACY_DETACHED_JOBS_DIR = ".sideboard/detached-jobs";
|
|
2892
2894
|
ATTACHMENTS_GITIGNORE = `# Sideboard / workspace attachments (local only)
|
|
2893
2895
|
*
|
|
2894
2896
|
!.gitignore
|
|
@@ -4445,14 +4447,12 @@ var init_run = __esm({
|
|
|
4445
4447
|
// src/git/worktree-exclude.ts
|
|
4446
4448
|
var worktree_exclude_exports = {};
|
|
4447
4449
|
__export(worktree_exclude_exports, {
|
|
4450
|
+
WORKTREE_CONTEXT_EXCLUDE: () => WORKTREE_CONTEXT_EXCLUDE,
|
|
4448
4451
|
WORKTREE_SIDEBOARD_EXCLUDE: () => WORKTREE_SIDEBOARD_EXCLUDE,
|
|
4449
4452
|
ensureWorktreeSideboardIgnored: () => ensureWorktreeSideboardIgnored
|
|
4450
4453
|
});
|
|
4451
|
-
function
|
|
4452
|
-
return body.split(/\r?\n/).some((line) =>
|
|
4453
|
-
const t = line.trim();
|
|
4454
|
-
return t === ".sideboard/" || t === ".sideboard" || t === "/.sideboard/";
|
|
4455
|
-
});
|
|
4454
|
+
function excludeHasLine(body, ...needles) {
|
|
4455
|
+
return body.split(/\r?\n/).some((line) => needles.includes(line.trim()));
|
|
4456
4456
|
}
|
|
4457
4457
|
async function ensureWorktreeSideboardIgnored(worktreePath) {
|
|
4458
4458
|
if (!worktreePath.trim()) return;
|
|
@@ -4471,16 +4471,20 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
|
|
|
4471
4471
|
} catch {
|
|
4472
4472
|
body = "";
|
|
4473
4473
|
}
|
|
4474
|
-
|
|
4474
|
+
const missing = [];
|
|
4475
|
+
if (!excludeHasLine(body, ".sideboard/", ".sideboard", "/.sideboard/")) {
|
|
4476
|
+
missing.push(WORKTREE_SIDEBOARD_EXCLUDE);
|
|
4477
|
+
}
|
|
4478
|
+
if (!excludeHasLine(body, ".context/", ".context", "/.context/")) {
|
|
4479
|
+
missing.push(WORKTREE_CONTEXT_EXCLUDE);
|
|
4480
|
+
}
|
|
4481
|
+
if (missing.length > 0) {
|
|
4475
4482
|
const prefix = body && !body.endsWith("\n") ? `${body}
|
|
4476
4483
|
` : body;
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
`,
|
|
4482
|
-
"utf8"
|
|
4483
|
-
);
|
|
4484
|
+
const header = body.includes(EXCLUDE_COMMENT) ? "" : `${EXCLUDE_COMMENT}
|
|
4485
|
+
`;
|
|
4486
|
+
(0, import_node_fs16.writeFileSync)(excludePath, `${prefix}${header}${missing.join("\n")}
|
|
4487
|
+
`, "utf8");
|
|
4484
4488
|
}
|
|
4485
4489
|
const listed = await git(["ls-files", "-z", "--", ".sideboard"], worktreePath, {
|
|
4486
4490
|
reject: false,
|
|
@@ -4494,7 +4498,7 @@ ${WORKTREE_SIDEBOARD_EXCLUDE}
|
|
|
4494
4498
|
timeoutMs: 8e3
|
|
4495
4499
|
});
|
|
4496
4500
|
}
|
|
4497
|
-
var import_node_fs16, import_node_path17, WORKTREE_SIDEBOARD_EXCLUDE, EXCLUDE_COMMENT;
|
|
4501
|
+
var import_node_fs16, import_node_path17, WORKTREE_SIDEBOARD_EXCLUDE, WORKTREE_CONTEXT_EXCLUDE, EXCLUDE_COMMENT;
|
|
4498
4502
|
var init_worktree_exclude = __esm({
|
|
4499
4503
|
"src/git/worktree-exclude.ts"() {
|
|
4500
4504
|
"use strict";
|
|
@@ -4502,6 +4506,7 @@ var init_worktree_exclude = __esm({
|
|
|
4502
4506
|
import_node_path17 = require("path");
|
|
4503
4507
|
init_run();
|
|
4504
4508
|
WORKTREE_SIDEBOARD_EXCLUDE = ".sideboard/";
|
|
4509
|
+
WORKTREE_CONTEXT_EXCLUDE = ".context/";
|
|
4505
4510
|
EXCLUDE_COMMENT = "# Sideboard worktree scratch \u2014 do not commit";
|
|
4506
4511
|
}
|
|
4507
4512
|
});
|
|
@@ -6606,7 +6611,7 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
6606
6611
|
"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).",
|
|
6607
6612
|
"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.",
|
|
6608
6613
|
"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.",
|
|
6609
|
-
"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."
|
|
6614
|
+
"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."
|
|
6610
6615
|
].join("\n");
|
|
6611
6616
|
try {
|
|
6612
6617
|
(0, import_node_fs18.writeFileSync)((0, import_node_path20.join)(dir, "CLAUDE.md"), `${body}
|
|
@@ -6686,15 +6691,16 @@ var init_coordinator_prompt = __esm({
|
|
|
6686
6691
|
"- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
|
|
6687
6692
|
"Inspect / review / PRs:",
|
|
6688
6693
|
"- get_diff \u2014 compact diff summary",
|
|
6689
|
-
|
|
6690
|
-
|
|
6694
|
+
"- 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.",
|
|
6695
|
+
'- 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',
|
|
6696
|
+
"- 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.",
|
|
6691
6697
|
'- 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.',
|
|
6692
6698
|
'- 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.',
|
|
6693
6699
|
"Process guides:",
|
|
6694
6700
|
"- 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.",
|
|
6695
6701
|
"- 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.",
|
|
6696
|
-
"- 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` (
|
|
6697
|
-
"- One-offs: no guide. Same miss across threads: edit the skill or `.
|
|
6702
|
+
"- 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.",
|
|
6703
|
+
"- 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.",
|
|
6698
6704
|
"Human-only (do not attempt): ready-for-review land (confirm_land), purge_thread.",
|
|
6699
6705
|
"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.",
|
|
6700
6706
|
"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."
|
|
@@ -13275,7 +13281,7 @@ File: src/client/frontends/desktop/core/UserData.ts
|
|
|
13275
13281
|
|
|
13276
13282
|
## Growing the rules
|
|
13277
13283
|
|
|
13278
|
-
If a blocking issue is a missing or ambiguous repo rule that will recur, add one sentence to \`.claude/skills/review/SKILL.md\`
|
|
13284
|
+
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/\`.
|
|
13279
13285
|
`;
|
|
13280
13286
|
REVIEW_SKILL_PATH = ".claude/skills/review/SKILL.md";
|
|
13281
13287
|
REVIEW_SKILL_NAME = "review";
|
|
@@ -13329,41 +13335,64 @@ function skillGuidelines(content, source) {
|
|
|
13329
13335
|
source
|
|
13330
13336
|
};
|
|
13331
13337
|
}
|
|
13332
|
-
function
|
|
13333
|
-
|
|
13334
|
-
|
|
13335
|
-
|
|
13336
|
-
|
|
13337
|
-
|
|
13338
|
-
|
|
13339
|
-
|
|
13340
|
-
|
|
13338
|
+
function contextGuidelines(content, source) {
|
|
13339
|
+
return {
|
|
13340
|
+
path: CONTEXT_REVIEW_PATH,
|
|
13341
|
+
name: REPO_REVIEW_NAME,
|
|
13342
|
+
content,
|
|
13343
|
+
source
|
|
13344
|
+
};
|
|
13345
|
+
}
|
|
13346
|
+
function writeContextGuidelines(worktreePath, content) {
|
|
13347
|
+
const abs = (0, import_node_path32.join)(worktreePath, CONTEXT_REVIEW_PATH);
|
|
13341
13348
|
(0, import_node_fs32.mkdirSync)((0, import_node_path32.dirname)(abs), { recursive: true });
|
|
13342
|
-
|
|
13343
|
-
|
|
13349
|
+
const body = content.endsWith("\n") ? content : `${content}
|
|
13350
|
+
`;
|
|
13351
|
+
(0, import_node_fs32.writeFileSync)(abs, body, "utf8");
|
|
13352
|
+
return body;
|
|
13344
13353
|
}
|
|
13345
|
-
function
|
|
13354
|
+
function readSideboardReview(worktreePath, repoPath) {
|
|
13355
|
+
const fromWorktree = readTextIfPresent((0, import_node_path32.join)(worktreePath, REPO_REVIEW_PATH));
|
|
13356
|
+
if (fromWorktree) return fromWorktree;
|
|
13357
|
+
const repo = repoPath?.replace(/\/+$/, "");
|
|
13358
|
+
const wt = worktreePath.replace(/\/+$/, "");
|
|
13359
|
+
if (!repo || repo === wt) return null;
|
|
13360
|
+
return readTextIfPresent((0, import_node_path32.join)(repo, REPO_REVIEW_PATH));
|
|
13361
|
+
}
|
|
13362
|
+
function ensureReviewGuidelinesFile(worktreePath, repoPath) {
|
|
13346
13363
|
const skillContent = readTextIfPresent((0, import_node_path32.join)(worktreePath, REVIEW_SKILL_PATH));
|
|
13347
|
-
if (skillContent)
|
|
13348
|
-
|
|
13349
|
-
|
|
13350
|
-
|
|
13351
|
-
|
|
13352
|
-
|
|
13353
|
-
|
|
13354
|
-
|
|
13355
|
-
|
|
13364
|
+
if (skillContent) {
|
|
13365
|
+
return { ...skillGuidelines(skillContent, "skill"), wrote: false };
|
|
13366
|
+
}
|
|
13367
|
+
const contextContent = readTextIfPresent((0, import_node_path32.join)(worktreePath, CONTEXT_REVIEW_PATH));
|
|
13368
|
+
if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
|
|
13369
|
+
return { ...contextGuidelines(contextContent, "local"), wrote: false };
|
|
13370
|
+
}
|
|
13371
|
+
const fromSideboard = readSideboardReview(worktreePath, repoPath);
|
|
13372
|
+
if (fromSideboard && !shouldRefreshReviewRequestTemplate(fromSideboard)) {
|
|
13373
|
+
const body2 = writeContextGuidelines(worktreePath, fromSideboard);
|
|
13374
|
+
return { ...contextGuidelines(body2, "repo"), wrote: true };
|
|
13356
13375
|
}
|
|
13357
|
-
const
|
|
13358
|
-
|
|
13376
|
+
const local = readLocalGuidelines(worktreePath);
|
|
13377
|
+
const body = writeContextGuidelines(worktreePath, local?.content ?? REVIEW_REQUEST_TEMPLATE);
|
|
13378
|
+
return {
|
|
13379
|
+
...contextGuidelines(body, local ? "local" : "stock"),
|
|
13380
|
+
wrote: true
|
|
13381
|
+
};
|
|
13359
13382
|
}
|
|
13360
|
-
function
|
|
13361
|
-
const
|
|
13362
|
-
return
|
|
13383
|
+
function ensureReviewSkillFile(worktreePath, repoPath) {
|
|
13384
|
+
const g = ensureReviewGuidelinesFile(worktreePath, repoPath);
|
|
13385
|
+
return { path: g.path, content: g.content, wrote: g.wrote };
|
|
13386
|
+
}
|
|
13387
|
+
function resolveReviewGuidelines(worktreePath, repoPath) {
|
|
13388
|
+
return ensureReviewGuidelinesFile(worktreePath, repoPath);
|
|
13389
|
+
}
|
|
13390
|
+
function ensureReviewRequestFile(worktreePath, repoPath) {
|
|
13391
|
+
return ensureReviewGuidelinesFile(worktreePath, repoPath);
|
|
13363
13392
|
}
|
|
13364
13393
|
function buildReviewRequestAttachment(content, opts) {
|
|
13365
13394
|
const path2 = opts?.path ?? REVIEW_SKILL_PATH;
|
|
13366
|
-
const name = opts?.name ?? (path2 === REVIEW_SKILL_PATH ? REVIEW_SKILL_NAME : path2 === REPO_REVIEW_PATH ? REPO_REVIEW_NAME : REVIEW_REQUEST_NAME);
|
|
13395
|
+
const name = opts?.name ?? (path2 === REVIEW_SKILL_PATH ? REVIEW_SKILL_NAME : path2 === REPO_REVIEW_PATH || path2 === CONTEXT_REVIEW_PATH ? REPO_REVIEW_NAME : REVIEW_REQUEST_NAME);
|
|
13367
13396
|
return {
|
|
13368
13397
|
id: (0, import_node_crypto8.randomUUID)(),
|
|
13369
13398
|
name,
|
|
@@ -13373,7 +13402,7 @@ function buildReviewRequestAttachment(content, opts) {
|
|
|
13373
13402
|
};
|
|
13374
13403
|
}
|
|
13375
13404
|
function readExistingReviewRequestFile(worktreePath) {
|
|
13376
|
-
return readTextIfPresent((0, import_node_path32.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path32.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path32.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path32.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
13405
|
+
return readTextIfPresent((0, import_node_path32.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path32.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path32.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path32.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path32.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
13377
13406
|
}
|
|
13378
13407
|
async function requestReview(threadRef, send2) {
|
|
13379
13408
|
const from = findThreadByRef(threadRef);
|
|
@@ -13386,7 +13415,7 @@ async function requestReview(threadRef, send2) {
|
|
|
13386
13415
|
if (from.status === "archived") {
|
|
13387
13416
|
throw new Error(`Thread is archived: ${from.id}`);
|
|
13388
13417
|
}
|
|
13389
|
-
const guidelines = resolveReviewGuidelines(from.worktreePath);
|
|
13418
|
+
const guidelines = resolveReviewGuidelines(from.worktreePath, from.repoPath);
|
|
13390
13419
|
const tab = createChatTab({
|
|
13391
13420
|
fromThreadId: from.id,
|
|
13392
13421
|
title: "Review",
|
|
@@ -13400,7 +13429,7 @@ async function requestReview(threadRef, send2) {
|
|
|
13400
13429
|
const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
|
|
13401
13430
|
return { tab: started, from };
|
|
13402
13431
|
}
|
|
13403
|
-
var import_node_crypto8, import_node_fs32, import_node_path32, REPO_REVIEW_PATH, REPO_REVIEW_NAME, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
|
|
13432
|
+
var import_node_crypto8, import_node_fs32, import_node_path32, 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;
|
|
13404
13433
|
var init_request_review = __esm({
|
|
13405
13434
|
"src/review/request-review.ts"() {
|
|
13406
13435
|
"use strict";
|
|
@@ -13414,6 +13443,7 @@ var init_request_review = __esm({
|
|
|
13414
13443
|
init_workspace_scratch();
|
|
13415
13444
|
REPO_REVIEW_PATH = ".sideboard/review.md";
|
|
13416
13445
|
REPO_REVIEW_NAME = "review.md";
|
|
13446
|
+
CONTEXT_REVIEW_PATH = ".context/review.md";
|
|
13417
13447
|
REVIEW_REQUEST_PATH = `${ATTACHMENTS_DIR}/Review request.md`;
|
|
13418
13448
|
LEGACY_REVIEW_REQUEST_PATH = `${LEGACY_ATTACHMENTS_DIR}/Review request.md`;
|
|
13419
13449
|
REVIEW_REQUEST_NAME = "Review request.md";
|
|
@@ -13667,11 +13697,9 @@ async function runConventionSetup(repoPath, worktreePath, onLine, opts) {
|
|
|
13667
13697
|
}
|
|
13668
13698
|
async function runWorkspaceSetup(repoPath, worktreePath, onLine, opts) {
|
|
13669
13699
|
await ensureWorktreeSideboardIgnored(worktreePath);
|
|
13670
|
-
const
|
|
13671
|
-
if (
|
|
13672
|
-
onLine?.(
|
|
13673
|
-
`[setup] wrote ${REVIEW_SKILL_PATH} \u2014 commit it so later worktrees inherit Review guidelines`
|
|
13674
|
-
);
|
|
13700
|
+
const review = ensureReviewGuidelinesFile(worktreePath, repoPath);
|
|
13701
|
+
if (review.wrote) {
|
|
13702
|
+
onLine?.(`[setup] wrote ${review.path} \u2014 local Review guidelines`);
|
|
13675
13703
|
}
|
|
13676
13704
|
let setup = await runSetupScript(repoPath, worktreePath, onLine, opts);
|
|
13677
13705
|
if (!setup.ran) {
|
|
@@ -17211,7 +17239,7 @@ node <detached-job.js> wait <id> --until-done
|
|
|
17211
17239
|
node <detached-job.js> status <id>
|
|
17212
17240
|
\`\`\`
|
|
17213
17241
|
|
|
17214
|
-
\`<id>\` is kebab-case (\`mac-release\`, \`core-test\`, \`fly-deploy\`). State is \`.sideboard/detached-jobs/<id>/\` (local scratch).
|
|
17242
|
+
\`<id>\` is kebab-case (\`mac-release\`, \`core-test\`, \`fly-deploy\`). State is \`.context/.sideboard/detached-jobs/<id>/\` (local scratch).
|
|
17215
17243
|
|
|
17216
17244
|
Wait JSON:
|
|
17217
17245
|
|
|
@@ -17249,6 +17277,16 @@ node <detached-job.js> wait --pid-file FILE --log-file FILE [--ok-pattern TEXT]
|
|
|
17249
17277
|
4. On \`ok\`, present once more (\`status=ok\`, last \`delta\`) and finish the task. On \`failed\`, fix from the log.
|
|
17250
17278
|
|
|
17251
17279
|
Never tell the user \u201Csay status when it\u2019s done.\u201D You wait.
|
|
17280
|
+
|
|
17281
|
+
## PR checks (only if a goal is given)
|
|
17282
|
+
|
|
17283
|
+
Do **not** watch after every push. If the user gave a goal (Greptile 5/5, CI green, until checks pass), wait the same way:
|
|
17284
|
+
|
|
17285
|
+
\`\`\`bash
|
|
17286
|
+
node <detached-job.js> start pr-checks -- gh pr checks --watch
|
|
17287
|
+
\`\`\`
|
|
17288
|
+
|
|
17289
|
+
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.
|
|
17252
17290
|
`;
|
|
17253
17291
|
}
|
|
17254
17292
|
});
|
|
@@ -17638,7 +17676,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
17638
17676
|
"Short git requests from the Sideboard UI are complete instructions \u2014 expand them using the rules above without asking for clarification:"
|
|
17639
17677
|
);
|
|
17640
17678
|
lines.push(
|
|
17641
|
-
'- "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).'
|
|
17679
|
+
'- "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.'
|
|
17642
17680
|
);
|
|
17643
17681
|
lines.push(
|
|
17644
17682
|
'- "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).'
|
|
@@ -17647,7 +17685,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
17647
17685
|
'- "Commit, push, and open a PR in the browser." \u2192 commit, push, then `gh pr create --web -R \u2026`.'
|
|
17648
17686
|
);
|
|
17649
17687
|
lines.push(
|
|
17650
|
-
'- "Fix CI: <name>." \u2192 investigate that failing check, fix it, commit, and push.'
|
|
17688
|
+
'- "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.'
|
|
17651
17689
|
);
|
|
17652
17690
|
lines.push(
|
|
17653
17691
|
'- "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.'
|
|
@@ -17659,11 +17697,21 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
17659
17697
|
'- "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.'
|
|
17660
17698
|
);
|
|
17661
17699
|
lines.push("");
|
|
17700
|
+
lines.push(formatPrGateDirective());
|
|
17701
|
+
lines.push("");
|
|
17662
17702
|
lines.push(formatProcessGuideDirective());
|
|
17663
17703
|
return lines.join("\n");
|
|
17664
17704
|
}
|
|
17665
17705
|
function formatWorktreeReminder() {
|
|
17666
|
-
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.";
|
|
17706
|
+
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.";
|
|
17707
|
+
}
|
|
17708
|
+
function formatPrGateDirective() {
|
|
17709
|
+
return [
|
|
17710
|
+
"If a goal is given (not after every push):",
|
|
17711
|
+
"- 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.",
|
|
17712
|
+
"- Wait with `/long-running`: `gh pr checks --watch` (add `-R <origin>` when needed). Present the log. Do not ask the human to poll.",
|
|
17713
|
+
"- 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."
|
|
17714
|
+
].join("\n");
|
|
17667
17715
|
}
|
|
17668
17716
|
function formatProcessGuideDirective() {
|
|
17669
17717
|
return [
|
|
@@ -17671,7 +17719,7 @@ function formatProcessGuideDirective() {
|
|
|
17671
17719
|
"- 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.",
|
|
17672
17720
|
"- 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.",
|
|
17673
17721
|
"- 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.",
|
|
17674
|
-
"- Merge-readiness notes:
|
|
17722
|
+
"- 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.",
|
|
17675
17723
|
"- 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.",
|
|
17676
17724
|
"- 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."
|
|
17677
17725
|
].join("\n");
|
|
@@ -17686,7 +17734,7 @@ function formatLongRunningDirective(opts) {
|
|
|
17686
17734
|
"- Immediately `present_artifact` `type=log` with `artifact_id=<id>` and `status=running` \u2014 the side column is the live view.",
|
|
17687
17735
|
`- 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.`,
|
|
17688
17736
|
"- ok \u2192 finish the task. failed \u2192 read the log, fix, start once.",
|
|
17689
|
-
"State: `.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available)."
|
|
17737
|
+
"State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available)."
|
|
17690
17738
|
].join("\n");
|
|
17691
17739
|
}
|
|
17692
17740
|
function formatLongRunningReminder(opts) {
|
|
@@ -20604,10 +20652,12 @@ __export(index_exports, {
|
|
|
20604
20652
|
CONTEXT_KEEP_RECENT_CHARS: () => CONTEXT_KEEP_RECENT_CHARS,
|
|
20605
20653
|
CONTEXT_KEEP_RECENT_MESSAGES: () => CONTEXT_KEEP_RECENT_MESSAGES,
|
|
20606
20654
|
CONTEXT_MIN_MESSAGES: () => CONTEXT_MIN_MESSAGES,
|
|
20655
|
+
CONTEXT_REVIEW_PATH: () => CONTEXT_REVIEW_PATH,
|
|
20607
20656
|
CONVENTION_SETUP_RELPATHS: () => CONVENTION_SETUP_RELPATHS,
|
|
20608
20657
|
COORDINATOR_TOOL_PLAYBOOK: () => COORDINATOR_TOOL_PLAYBOOK,
|
|
20609
20658
|
DEFAULT_ABLETIME_HOST: () => DEFAULT_ABLETIME_HOST,
|
|
20610
20659
|
DEFAULT_WORKTREE_SORT: () => DEFAULT_WORKTREE_SORT,
|
|
20660
|
+
DETACHED_JOBS_DIR: () => DETACHED_JOBS_DIR,
|
|
20611
20661
|
FAMOUS_SOCCER_TEAMS: () => FAMOUS_SOCCER_TEAMS,
|
|
20612
20662
|
FOLLOW_UP_BEHAVIORS: () => FOLLOW_UP_BEHAVIORS,
|
|
20613
20663
|
GITHUB_GIT_AUTH_MODES: () => GITHUB_GIT_AUTH_MODES,
|
|
@@ -20618,6 +20668,7 @@ __export(index_exports, {
|
|
|
20618
20668
|
HOME_BOARD_CACHE_TTL_MS: () => HOME_BOARD_CACHE_TTL_MS,
|
|
20619
20669
|
ISSUE_SOURCE_LABELS: () => ISSUE_SOURCE_LABELS,
|
|
20620
20670
|
LEGACY_ATTACHMENTS_DIR: () => LEGACY_ATTACHMENTS_DIR,
|
|
20671
|
+
LEGACY_DETACHED_JOBS_DIR: () => LEGACY_DETACHED_JOBS_DIR,
|
|
20621
20672
|
LEGACY_PLAN_FILE_REL: () => LEGACY_PLAN_FILE_REL,
|
|
20622
20673
|
LEGACY_REVIEW_REQUEST_PATH: () => LEGACY_REVIEW_REQUEST_PATH,
|
|
20623
20674
|
LINEAR_OAUTH_CANCELLED: () => LINEAR_OAUTH_CANCELLED,
|
|
@@ -20808,6 +20859,7 @@ __export(index_exports, {
|
|
|
20808
20859
|
ensureConnectedBrightsyTeamTokens: () => ensureConnectedBrightsyTeamTokens,
|
|
20809
20860
|
ensureGhPreferOrigin: () => ensureGhPreferOrigin,
|
|
20810
20861
|
ensureGlobalCoordinatorCwd: () => ensureGlobalCoordinatorCwd,
|
|
20862
|
+
ensureReviewGuidelinesFile: () => ensureReviewGuidelinesFile,
|
|
20811
20863
|
ensureReviewRequestFile: () => ensureReviewRequestFile,
|
|
20812
20864
|
ensureReviewSkillFile: () => ensureReviewSkillFile,
|
|
20813
20865
|
ensureSlackCoordinator: () => ensureSlackCoordinator,
|
|
@@ -20857,6 +20909,7 @@ __export(index_exports, {
|
|
|
20857
20909
|
formatOptionalServicesReminder: () => formatOptionalServicesReminder,
|
|
20858
20910
|
formatPlanQuestionAnswers: () => formatPlanQuestionAnswers,
|
|
20859
20911
|
formatPlanQuestionsForChat: () => formatPlanQuestionsForChat,
|
|
20912
|
+
formatPrGateDirective: () => formatPrGateDirective,
|
|
20860
20913
|
formatProcessGuideDirective: () => formatProcessGuideDirective,
|
|
20861
20914
|
formatRateLimitResetHint: () => formatRateLimitResetHint,
|
|
20862
20915
|
formatRenameBranchDirective: () => formatRenameBranchDirective,
|
|
@@ -24760,9 +24813,25 @@ async function startMcpServer() {
|
|
|
24760
24813
|
};
|
|
24761
24814
|
}
|
|
24762
24815
|
);
|
|
24816
|
+
server.tool(
|
|
24817
|
+
"get_pr_checks",
|
|
24818
|
+
"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.",
|
|
24819
|
+
{ ref: import_zod5.z.string().describe("Worktree thread id/ref") },
|
|
24820
|
+
async ({ ref }) => {
|
|
24821
|
+
try {
|
|
24822
|
+
const checks = await orch.getPrChecks(ref);
|
|
24823
|
+
return {
|
|
24824
|
+
content: [{ type: "text", text: JSON.stringify(checks) }]
|
|
24825
|
+
};
|
|
24826
|
+
} catch (err) {
|
|
24827
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
24828
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
24829
|
+
}
|
|
24830
|
+
}
|
|
24831
|
+
);
|
|
24763
24832
|
server.tool(
|
|
24764
24833
|
"request_review",
|
|
24765
|
-
'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
|
|
24834
|
+
'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.',
|
|
24766
24835
|
{ ref: import_zod5.z.string().describe("Worktree thread id/ref to review") },
|
|
24767
24836
|
async ({ ref }) => {
|
|
24768
24837
|
try {
|
|
@@ -24790,7 +24859,7 @@ async function startMcpServer() {
|
|
|
24790
24859
|
);
|
|
24791
24860
|
server.tool(
|
|
24792
24861
|
"ask_git",
|
|
24793
|
-
"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.",
|
|
24862
|
+
"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.",
|
|
24794
24863
|
{
|
|
24795
24864
|
ref: import_zod5.z.string().describe("Worktree thread id/ref"),
|
|
24796
24865
|
action: import_zod5.z.enum(AGENT_GIT_ACTIONS).describe(
|
|
@@ -27600,10 +27669,12 @@ init_outbound_watch();
|
|
|
27600
27669
|
CONTEXT_KEEP_RECENT_CHARS,
|
|
27601
27670
|
CONTEXT_KEEP_RECENT_MESSAGES,
|
|
27602
27671
|
CONTEXT_MIN_MESSAGES,
|
|
27672
|
+
CONTEXT_REVIEW_PATH,
|
|
27603
27673
|
CONVENTION_SETUP_RELPATHS,
|
|
27604
27674
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
27605
27675
|
DEFAULT_ABLETIME_HOST,
|
|
27606
27676
|
DEFAULT_WORKTREE_SORT,
|
|
27677
|
+
DETACHED_JOBS_DIR,
|
|
27607
27678
|
FAMOUS_SOCCER_TEAMS,
|
|
27608
27679
|
FOLLOW_UP_BEHAVIORS,
|
|
27609
27680
|
GITHUB_GIT_AUTH_MODES,
|
|
@@ -27614,6 +27685,7 @@ init_outbound_watch();
|
|
|
27614
27685
|
HOME_BOARD_CACHE_TTL_MS,
|
|
27615
27686
|
ISSUE_SOURCE_LABELS,
|
|
27616
27687
|
LEGACY_ATTACHMENTS_DIR,
|
|
27688
|
+
LEGACY_DETACHED_JOBS_DIR,
|
|
27617
27689
|
LEGACY_PLAN_FILE_REL,
|
|
27618
27690
|
LEGACY_REVIEW_REQUEST_PATH,
|
|
27619
27691
|
LINEAR_OAUTH_CANCELLED,
|
|
@@ -27804,6 +27876,7 @@ init_outbound_watch();
|
|
|
27804
27876
|
ensureConnectedBrightsyTeamTokens,
|
|
27805
27877
|
ensureGhPreferOrigin,
|
|
27806
27878
|
ensureGlobalCoordinatorCwd,
|
|
27879
|
+
ensureReviewGuidelinesFile,
|
|
27807
27880
|
ensureReviewRequestFile,
|
|
27808
27881
|
ensureReviewSkillFile,
|
|
27809
27882
|
ensureSlackCoordinator,
|
|
@@ -27853,6 +27926,7 @@ init_outbound_watch();
|
|
|
27853
27926
|
formatOptionalServicesReminder,
|
|
27854
27927
|
formatPlanQuestionAnswers,
|
|
27855
27928
|
formatPlanQuestionsForChat,
|
|
27929
|
+
formatPrGateDirective,
|
|
27856
27930
|
formatProcessGuideDirective,
|
|
27857
27931
|
formatRateLimitResetHint,
|
|
27858
27932
|
formatRenameBranchDirective,
|