@sideboard-ai/core 0.1.192 → 0.1.194
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/{abletime-53T7G667.js → abletime-HR6P4GJH.js} +4 -3
- package/dist/{abletime-JFMBCSIQ.js → abletime-JINF5KJV.js} +4 -3
- package/dist/agents/cursor-runner.js +3 -3
- package/dist/{agents-TXGQIK2E.js → agents-OXDDPH2O.js} +10 -9
- package/dist/{agents-T5VBB6X3.js → agents-WQL7SZY6.js} +8 -7
- package/dist/{app-settings-663VQWUV.js → app-settings-5KHVKJKO.js} +5 -2
- package/dist/{app-settings-74HBAAH7.js → app-settings-J775CYOO.js} +5 -2
- package/dist/branch-prefix-7DTIUJT2.js +12 -0
- package/dist/branch-prefix-N3KTCRCE.js +10 -0
- package/dist/{caffeinate-hold-SK2QISPE.js → caffeinate-hold-22VFDPSO.js} +2 -2
- package/dist/{caffeinate-hold-DBKMRZZO.js → caffeinate-hold-OK4JJ5PP.js} +2 -2
- package/dist/{chunk-TWSCTJCR.js → chunk-2X6RGKLI.js} +7 -7
- package/dist/{chunk-HVIEYTUK.js → chunk-3OHR73VK.js} +1 -1
- package/dist/{chunk-AO35MGOE.js → chunk-4TYXWPAJ.js} +1 -1
- package/dist/{chunk-WHD4JNTN.js → chunk-6H2XPPPR.js} +8 -8
- package/dist/{chunk-7NSXGL6L.js → chunk-6YTI2HBG.js} +5 -5
- package/dist/{chunk-WLPXZFRE.js → chunk-7J72QJOM.js} +1 -1
- package/dist/{chunk-OKZFTOM2.js → chunk-AH6WIBLY.js} +19 -1
- package/dist/{chunk-GOZ6T3AG.js → chunk-CJFBSQIB.js} +1 -1
- package/dist/{chunk-XBLN52RZ.js → chunk-DP4TKAMZ.js} +3 -3
- package/dist/{chunk-4M2AK3O5.js → chunk-E37JHCO3.js} +1 -1
- package/dist/{chunk-JTJHOYCU.js → chunk-EQNRWDLN.js} +10 -4
- package/dist/chunk-FJZWM2ON.js +23 -0
- package/dist/{chunk-VV7UT3E2.js → chunk-HZTHWU6A.js} +5 -5
- package/dist/{chunk-TCQAFTSV.js → chunk-KJBYIIJU.js} +1 -1
- package/dist/{chunk-UBQIELFS.js → chunk-KTHRWHA3.js} +1 -1
- package/dist/{chunk-FY64F2ZQ.js → chunk-NLHFAMC2.js} +1 -1
- package/dist/{chunk-NF6ENGHS.js → chunk-NY366OEZ.js} +151 -160
- package/dist/{chunk-WXKXSZN4.js → chunk-S4QCBBXS.js} +6 -6
- package/dist/{chunk-J7LQVLFQ.js → chunk-S5GLSRLP.js} +19 -1
- package/dist/{chunk-IEEAVWAP.js → chunk-SALM35KD.js} +5 -5
- package/dist/{chunk-FZ3G5TXM.js → chunk-VRPPFKAO.js} +152 -162
- package/dist/chunk-WDRMZKVB.js +20 -0
- package/dist/{chunk-EFVFB2AH.js → chunk-WFUDY6PC.js} +12 -5
- package/dist/{chunk-OCQPTUR7.js → chunk-YWI3IBP2.js} +1 -1
- package/dist/{connected-teams-WOYCH7FR.js → connected-teams-PU4AMFNA.js} +2 -2
- package/dist/{connected-teams-ON2KIKQX.js → connected-teams-WK47ATT7.js} +2 -2
- package/dist/{coordinator-prompt-S4HHFSLI.js → coordinator-prompt-IX66YUJ2.js} +7 -6
- package/dist/{coordinator-prompt-PNUDN4DW.js → coordinator-prompt-LYKS3YNG.js} +6 -5
- package/dist/{cursor-recover-NDMLLNYX.js → cursor-recover-DTQAUDGO.js} +2 -2
- package/dist/{cursor-recover-L5MD6MBO.js → cursor-recover-TXVTLAMA.js} +1 -1
- package/dist/{global-workspace-JTBBH2K5.js → global-workspace-4QX6UEOY.js} +7 -6
- package/dist/{global-workspace-2BVCJUAL.js → global-workspace-SNJ2Z6SL.js} +6 -5
- package/dist/index.cjs +192 -146
- package/dist/index.d.cts +46 -8
- package/dist/index.d.ts +46 -8
- package/dist/index.js +55 -43
- package/dist/mcp/run-stdio.cjs +179 -145
- package/dist/mcp/run-stdio.js +19 -18
- package/dist/{orchestrator-4G76BOHH.js → orchestrator-A5KF2335.js} +10 -9
- package/dist/{orchestrator-LWEZ74RK.js → orchestrator-S3M2E7O6.js} +12 -11
- package/dist/{paths-RRCLNSJB.js → paths-C2VERLAE.js} +1 -1
- package/dist/{paths-53TLA7VQ.js → paths-LOXCISLX.js} +1 -1
- package/dist/{thread-store-ZL6GDIDP.js → thread-store-CO77HV2K.js} +2 -2
- package/dist/{thread-store-RXXNSRVO.js → thread-store-M4B52FUS.js} +2 -2
- package/dist/{workspaces-ZYPME3YD.js → workspaces-URMUVGAQ.js} +7 -6
- package/dist/{workspaces-OY7D5RPU.js → workspaces-UTOYGBYB.js} +6 -5
- package/dist/{worktree-7LOSSD7G.js → worktree-R43JOR4V.js} +5 -4
- package/dist/{worktree-LPWTX2NA.js → worktree-RM6UWNGZ.js} +6 -5
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -274,9 +274,12 @@ function parseSettingsFile(path2, source) {
|
|
|
274
274
|
const prompts = {
|
|
275
275
|
renameBranch: typeof promptsRaw.rename_branch === "string" ? promptsRaw.rename_branch : void 0,
|
|
276
276
|
createPr: typeof promptsRaw.create_pr === "string" ? promptsRaw.create_pr : void 0,
|
|
277
|
-
general: typeof promptsRaw.general === "string" ? promptsRaw.general : void 0
|
|
277
|
+
general: typeof promptsRaw.general === "string" ? promptsRaw.general : void 0,
|
|
278
|
+
resolveMergeConflicts: typeof promptsRaw.resolve_merge_conflicts === "string" ? promptsRaw.resolve_merge_conflicts : void 0
|
|
278
279
|
};
|
|
279
|
-
const hasPrompts = Boolean(
|
|
280
|
+
const hasPrompts = Boolean(
|
|
281
|
+
prompts.renameBranch || prompts.createPr || prompts.general || prompts.resolveMergeConflicts
|
|
282
|
+
);
|
|
280
283
|
return {
|
|
281
284
|
source,
|
|
282
285
|
setup,
|
|
@@ -302,9 +305,12 @@ function mergeSettings(base, overlay) {
|
|
|
302
305
|
const prompts = {
|
|
303
306
|
renameBranch: overlay.prompts?.renameBranch ?? base.prompts?.renameBranch,
|
|
304
307
|
createPr: overlay.prompts?.createPr ?? base.prompts?.createPr,
|
|
305
|
-
general: overlay.prompts?.general ?? base.prompts?.general
|
|
308
|
+
general: overlay.prompts?.general ?? base.prompts?.general,
|
|
309
|
+
resolveMergeConflicts: overlay.prompts?.resolveMergeConflicts ?? base.prompts?.resolveMergeConflicts
|
|
306
310
|
};
|
|
307
|
-
const hasPrompts = Boolean(
|
|
311
|
+
const hasPrompts = Boolean(
|
|
312
|
+
prompts.renameBranch || prompts.createPr || prompts.general || prompts.resolveMergeConflicts
|
|
313
|
+
);
|
|
308
314
|
return {
|
|
309
315
|
source: overlay.source,
|
|
310
316
|
setup: overlay.setup ?? base.setup,
|
|
@@ -428,7 +434,8 @@ function getRepoSetupInfo(worktreePath, repoPath) {
|
|
|
428
434
|
return {
|
|
429
435
|
hasConfig: hasWorkspaceHook(worktreePath, repoPath) || cursor || Boolean(convention),
|
|
430
436
|
hasSetupScript,
|
|
431
|
-
configLabel
|
|
437
|
+
configLabel,
|
|
438
|
+
...settings?.prompts ? { prompts: settings.prompts } : {}
|
|
432
439
|
};
|
|
433
440
|
}
|
|
434
441
|
var import_node_fs3, import_node_os, import_node_path3, import_smol_toml;
|
|
@@ -955,6 +962,32 @@ var init_secret_vault = __esm({
|
|
|
955
962
|
}
|
|
956
963
|
});
|
|
957
964
|
|
|
965
|
+
// src/git/branch-prefix.ts
|
|
966
|
+
var branch_prefix_exports = {};
|
|
967
|
+
__export(branch_prefix_exports, {
|
|
968
|
+
examplePrefixedBranch: () => examplePrefixedBranch,
|
|
969
|
+
resolveGitBranchPrefix: () => resolveGitBranchPrefix,
|
|
970
|
+
sanitizeGitBranchPrefix: () => sanitizeGitBranchPrefix
|
|
971
|
+
});
|
|
972
|
+
function sanitizeGitBranchPrefix(raw) {
|
|
973
|
+
const first = (raw ?? "").trim().replace(/^\/+|\/+$/g, "").split("/")[0] ?? "";
|
|
974
|
+
const slug = first.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 39);
|
|
975
|
+
return slug || null;
|
|
976
|
+
}
|
|
977
|
+
function resolveGitBranchPrefix(opts) {
|
|
978
|
+
return sanitizeGitBranchPrefix(opts.setting);
|
|
979
|
+
}
|
|
980
|
+
function examplePrefixedBranch(prefix, ticket) {
|
|
981
|
+
const head = sanitizeGitBranchPrefix(prefix);
|
|
982
|
+
const slug = ticket?.trim() ? `${ticket.trim()}-eng-fix-thing` : "bb-1234-eng-fix-thing";
|
|
983
|
+
return head ? `${head}/${slug}` : slug;
|
|
984
|
+
}
|
|
985
|
+
var init_branch_prefix = __esm({
|
|
986
|
+
"src/git/branch-prefix.ts"() {
|
|
987
|
+
"use strict";
|
|
988
|
+
}
|
|
989
|
+
});
|
|
990
|
+
|
|
958
991
|
// src/store/issue-source-labels.ts
|
|
959
992
|
function issueSourceLabel(source) {
|
|
960
993
|
if (source && source in ISSUE_SOURCE_LABELS) {
|
|
@@ -1023,6 +1056,7 @@ __export(app_settings_exports, {
|
|
|
1023
1056
|
getGithubPat: () => getGithubPat,
|
|
1024
1057
|
getIssueSource: () => getIssueSource,
|
|
1025
1058
|
getLinearApiKey: () => getLinearApiKey,
|
|
1059
|
+
gitBranchPrefixSetting: () => gitBranchPrefixSetting,
|
|
1026
1060
|
harnessEnvKey: () => harnessEnvKey,
|
|
1027
1061
|
isAbleTimeConnected: () => isAbleTimeConnected,
|
|
1028
1062
|
isIssueSourceConnected: () => isIssueSourceConnected,
|
|
@@ -1398,6 +1432,10 @@ function normalizeAdvanced(raw) {
|
|
|
1398
1432
|
if (typeof source.autoRenameBranch === "boolean") {
|
|
1399
1433
|
out.autoRenameBranch = source.autoRenameBranch;
|
|
1400
1434
|
}
|
|
1435
|
+
if (typeof source.branchPrefix === "string") {
|
|
1436
|
+
const prefix = sanitizeGitBranchPrefix(source.branchPrefix);
|
|
1437
|
+
if (prefix) out.branchPrefix = prefix;
|
|
1438
|
+
}
|
|
1401
1439
|
if (typeof source.autoRunAfterSetup === "boolean") {
|
|
1402
1440
|
out.autoRunAfterSetup = source.autoRunAfterSetup;
|
|
1403
1441
|
}
|
|
@@ -2251,6 +2289,13 @@ function updateAdvancedSettings(patch) {
|
|
|
2251
2289
|
if (typeof patch.autoRenameBranch === "boolean") {
|
|
2252
2290
|
advanced.autoRenameBranch = patch.autoRenameBranch;
|
|
2253
2291
|
}
|
|
2292
|
+
if (patch.branchPrefix === null || patch.branchPrefix === "") {
|
|
2293
|
+
delete advanced.branchPrefix;
|
|
2294
|
+
} else if (typeof patch.branchPrefix === "string") {
|
|
2295
|
+
const prefix = sanitizeGitBranchPrefix(patch.branchPrefix);
|
|
2296
|
+
if (prefix) advanced.branchPrefix = prefix;
|
|
2297
|
+
else delete advanced.branchPrefix;
|
|
2298
|
+
}
|
|
2254
2299
|
if (typeof patch.autoRunAfterSetup === "boolean") {
|
|
2255
2300
|
advanced.autoRunAfterSetup = patch.autoRunAfterSetup;
|
|
2256
2301
|
}
|
|
@@ -2311,6 +2356,9 @@ function updateAdvancedSettings(patch) {
|
|
|
2311
2356
|
function autoRenameBranchEnabled(settings = loadAppSettings()) {
|
|
2312
2357
|
return settings.advanced.autoRenameBranch !== false;
|
|
2313
2358
|
}
|
|
2359
|
+
function gitBranchPrefixSetting(settings = loadAppSettings()) {
|
|
2360
|
+
return sanitizeGitBranchPrefix(settings.advanced.branchPrefix);
|
|
2361
|
+
}
|
|
2314
2362
|
function autoRunAfterSetupEnabled(settings = loadAppSettings()) {
|
|
2315
2363
|
return Boolean(settings.advanced.autoRunAfterSetup);
|
|
2316
2364
|
}
|
|
@@ -2456,6 +2504,7 @@ var init_app_settings = __esm({
|
|
|
2456
2504
|
init_paths();
|
|
2457
2505
|
init_private_file();
|
|
2458
2506
|
init_secret_vault();
|
|
2507
|
+
init_branch_prefix();
|
|
2459
2508
|
init_issue_source_labels();
|
|
2460
2509
|
init_account_profile();
|
|
2461
2510
|
HARNESS_ENV_KEYS = {
|
|
@@ -7783,7 +7832,7 @@ var init_coordinator_prompt = __esm({
|
|
|
7783
7832
|
"- get_diff \u2014 compact diff summary",
|
|
7784
7833
|
"- 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
7834
|
'- 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
|
|
7835
|
+
"- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge \u2014 same prompts as the desktop git buttons (Resolve, Create PR, \u2026). Always steers the worktree agent; then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. 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
7836
|
'- 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
7837
|
'- 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
7838
|
"Process guides:",
|
|
@@ -14176,87 +14225,6 @@ var init_spawn = __esm({
|
|
|
14176
14225
|
}
|
|
14177
14226
|
});
|
|
14178
14227
|
|
|
14179
|
-
// src/land/pr-metadata.ts
|
|
14180
|
-
function looksGeneric(title) {
|
|
14181
|
-
const t = title.trim();
|
|
14182
|
-
if (!t) return true;
|
|
14183
|
-
if (t.length < 4) return true;
|
|
14184
|
-
if (GENERIC_TITLE_RE.test(t)) return true;
|
|
14185
|
-
if (!/[\s:/\-_]/.test(t) && t.length <= 24) return true;
|
|
14186
|
-
return false;
|
|
14187
|
-
}
|
|
14188
|
-
function truncateTitle(title, max = 72) {
|
|
14189
|
-
const t = title.trim().replace(/\s+/g, " ");
|
|
14190
|
-
if (t.length <= max) return t;
|
|
14191
|
-
return `${t.slice(0, max - 1).trimEnd()}\u2026`;
|
|
14192
|
-
}
|
|
14193
|
-
function titleFromPaths(paths) {
|
|
14194
|
-
if (paths.length === 0) return null;
|
|
14195
|
-
const top = paths.slice(0, 3).map((p) => p.replace(/\/$/, ""));
|
|
14196
|
-
if (paths.length === 1) return truncateTitle(`Update ${top[0]}`);
|
|
14197
|
-
if (paths.length <= 3) return truncateTitle(`Update ${top.join(", ")}`);
|
|
14198
|
-
return truncateTitle(`Update ${top[0]} and ${paths.length - 1} more files`);
|
|
14199
|
-
}
|
|
14200
|
-
async function suggestPrMetadata(worktreePath, opts) {
|
|
14201
|
-
const [{ stdout: logOut }, { stdout: nameStatus }, { stdout: statOut }] = await Promise.all([
|
|
14202
|
-
git(["log", "--format=%s", `${opts.base}..HEAD`], worktreePath, {
|
|
14203
|
-
reject: false
|
|
14204
|
-
}),
|
|
14205
|
-
git(["diff", "--name-only", `${opts.base}...HEAD`], worktreePath, {
|
|
14206
|
-
reject: false
|
|
14207
|
-
}),
|
|
14208
|
-
git(["diff", "--stat", `${opts.base}...HEAD`], worktreePath, {
|
|
14209
|
-
reject: false
|
|
14210
|
-
})
|
|
14211
|
-
]);
|
|
14212
|
-
const { stdout: dirtyNames } = await git(["diff", "--name-only", "HEAD"], worktreePath, {
|
|
14213
|
-
reject: false
|
|
14214
|
-
});
|
|
14215
|
-
const { stdout: untracked } = await git(
|
|
14216
|
-
["ls-files", "--others", "--exclude-standard"],
|
|
14217
|
-
worktreePath,
|
|
14218
|
-
{ reject: false }
|
|
14219
|
-
);
|
|
14220
|
-
const subjects = logOut.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
14221
|
-
const paths = [
|
|
14222
|
-
...new Set(
|
|
14223
|
-
[...nameStatus.split("\n"), ...dirtyNames.split("\n"), ...untracked.split("\n")].map((p) => p.trim()).filter(Boolean)
|
|
14224
|
-
)
|
|
14225
|
-
].sort((a, b) => a.localeCompare(b));
|
|
14226
|
-
const meaningfulSubjects = subjects.filter((s) => !looksGeneric(s));
|
|
14227
|
-
const fallback = opts.fallbackTitle?.trim() || null;
|
|
14228
|
-
const fallbackOk = fallback && !looksGeneric(fallback) ? fallback : null;
|
|
14229
|
-
const title = truncateTitle(
|
|
14230
|
-
meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? "Sideboard changes"
|
|
14231
|
-
);
|
|
14232
|
-
const commitMessage = meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? `sideboard: ${title}`;
|
|
14233
|
-
const summaryLines = meaningfulSubjects.length > 0 ? meaningfulSubjects.slice(0, 12).map((s) => `- ${s}`) : paths.slice(0, 20).map((p) => `- \`${p}\``);
|
|
14234
|
-
const bodyParts = [
|
|
14235
|
-
"## Summary",
|
|
14236
|
-
summaryLines.length > 0 ? summaryLines.join("\n") : "- Changes landed via Sideboard.",
|
|
14237
|
-
""
|
|
14238
|
-
];
|
|
14239
|
-
if (statOut.trim()) {
|
|
14240
|
-
bodyParts.push("## Diff", "```", statOut.trim(), "```", "");
|
|
14241
|
-
}
|
|
14242
|
-
if (opts.sourceLabel) {
|
|
14243
|
-
bodyParts.push(`_Landed via Sideboard from ${opts.sourceLabel}_`);
|
|
14244
|
-
}
|
|
14245
|
-
return {
|
|
14246
|
-
title,
|
|
14247
|
-
body: bodyParts.join("\n").trim() + "\n",
|
|
14248
|
-
commitMessage: truncateTitle(commitMessage, 72)
|
|
14249
|
-
};
|
|
14250
|
-
}
|
|
14251
|
-
var GENERIC_TITLE_RE;
|
|
14252
|
-
var init_pr_metadata = __esm({
|
|
14253
|
-
"src/land/pr-metadata.ts"() {
|
|
14254
|
-
"use strict";
|
|
14255
|
-
init_run();
|
|
14256
|
-
GENERIC_TITLE_RE = /^(sideboard:|thread\/|wip\b|tmp\b|update\b|changes?\b|misc\b|stuff\b)/i;
|
|
14257
|
-
}
|
|
14258
|
-
});
|
|
14259
|
-
|
|
14260
14228
|
// src/git/agent-git-actions.ts
|
|
14261
14229
|
function agentGitPrompt(action, opts) {
|
|
14262
14230
|
switch (action) {
|
|
@@ -14277,6 +14245,19 @@ function agentGitPrompt(action, opts) {
|
|
|
14277
14245
|
return "Merge PR.";
|
|
14278
14246
|
}
|
|
14279
14247
|
}
|
|
14248
|
+
function resolveSidebarGitPrompt(action, opts) {
|
|
14249
|
+
if (action === "create-pr" || action === "create-draft" || action === "create-web") {
|
|
14250
|
+
const custom = opts?.createPr?.trim();
|
|
14251
|
+
if (custom) return custom;
|
|
14252
|
+
return agentGitPrompt(action === "create-pr" ? "create-draft" : action);
|
|
14253
|
+
}
|
|
14254
|
+
if (action === "resolve-conflicts") {
|
|
14255
|
+
const custom = opts?.resolveMergeConflicts?.trim();
|
|
14256
|
+
if (custom) return custom;
|
|
14257
|
+
return agentGitPrompt("resolve-conflicts", opts);
|
|
14258
|
+
}
|
|
14259
|
+
return agentGitPrompt(action, opts);
|
|
14260
|
+
}
|
|
14280
14261
|
function gitActionExpansion(action, base) {
|
|
14281
14262
|
switch (action) {
|
|
14282
14263
|
case "commit-push":
|
|
@@ -19505,6 +19486,87 @@ var init_diff = __esm({
|
|
|
19505
19486
|
}
|
|
19506
19487
|
});
|
|
19507
19488
|
|
|
19489
|
+
// src/land/pr-metadata.ts
|
|
19490
|
+
function looksGeneric(title) {
|
|
19491
|
+
const t = title.trim();
|
|
19492
|
+
if (!t) return true;
|
|
19493
|
+
if (t.length < 4) return true;
|
|
19494
|
+
if (GENERIC_TITLE_RE.test(t)) return true;
|
|
19495
|
+
if (!/[\s:/\-_]/.test(t) && t.length <= 24) return true;
|
|
19496
|
+
return false;
|
|
19497
|
+
}
|
|
19498
|
+
function truncateTitle(title, max = 72) {
|
|
19499
|
+
const t = title.trim().replace(/\s+/g, " ");
|
|
19500
|
+
if (t.length <= max) return t;
|
|
19501
|
+
return `${t.slice(0, max - 1).trimEnd()}\u2026`;
|
|
19502
|
+
}
|
|
19503
|
+
function titleFromPaths(paths) {
|
|
19504
|
+
if (paths.length === 0) return null;
|
|
19505
|
+
const top = paths.slice(0, 3).map((p) => p.replace(/\/$/, ""));
|
|
19506
|
+
if (paths.length === 1) return truncateTitle(`Update ${top[0]}`);
|
|
19507
|
+
if (paths.length <= 3) return truncateTitle(`Update ${top.join(", ")}`);
|
|
19508
|
+
return truncateTitle(`Update ${top[0]} and ${paths.length - 1} more files`);
|
|
19509
|
+
}
|
|
19510
|
+
async function suggestPrMetadata(worktreePath, opts) {
|
|
19511
|
+
const [{ stdout: logOut }, { stdout: nameStatus }, { stdout: statOut }] = await Promise.all([
|
|
19512
|
+
git(["log", "--format=%s", `${opts.base}..HEAD`], worktreePath, {
|
|
19513
|
+
reject: false
|
|
19514
|
+
}),
|
|
19515
|
+
git(["diff", "--name-only", `${opts.base}...HEAD`], worktreePath, {
|
|
19516
|
+
reject: false
|
|
19517
|
+
}),
|
|
19518
|
+
git(["diff", "--stat", `${opts.base}...HEAD`], worktreePath, {
|
|
19519
|
+
reject: false
|
|
19520
|
+
})
|
|
19521
|
+
]);
|
|
19522
|
+
const { stdout: dirtyNames } = await git(["diff", "--name-only", "HEAD"], worktreePath, {
|
|
19523
|
+
reject: false
|
|
19524
|
+
});
|
|
19525
|
+
const { stdout: untracked } = await git(
|
|
19526
|
+
["ls-files", "--others", "--exclude-standard"],
|
|
19527
|
+
worktreePath,
|
|
19528
|
+
{ reject: false }
|
|
19529
|
+
);
|
|
19530
|
+
const subjects = logOut.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
19531
|
+
const paths = [
|
|
19532
|
+
...new Set(
|
|
19533
|
+
[...nameStatus.split("\n"), ...dirtyNames.split("\n"), ...untracked.split("\n")].map((p) => p.trim()).filter(Boolean)
|
|
19534
|
+
)
|
|
19535
|
+
].sort((a, b) => a.localeCompare(b));
|
|
19536
|
+
const meaningfulSubjects = subjects.filter((s) => !looksGeneric(s));
|
|
19537
|
+
const fallback = opts.fallbackTitle?.trim() || null;
|
|
19538
|
+
const fallbackOk = fallback && !looksGeneric(fallback) ? fallback : null;
|
|
19539
|
+
const title = truncateTitle(
|
|
19540
|
+
meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? "Sideboard changes"
|
|
19541
|
+
);
|
|
19542
|
+
const commitMessage = meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? `sideboard: ${title}`;
|
|
19543
|
+
const summaryLines = meaningfulSubjects.length > 0 ? meaningfulSubjects.slice(0, 12).map((s) => `- ${s}`) : paths.slice(0, 20).map((p) => `- \`${p}\``);
|
|
19544
|
+
const bodyParts = [
|
|
19545
|
+
"## Summary",
|
|
19546
|
+
summaryLines.length > 0 ? summaryLines.join("\n") : "- Changes landed via Sideboard.",
|
|
19547
|
+
""
|
|
19548
|
+
];
|
|
19549
|
+
if (statOut.trim()) {
|
|
19550
|
+
bodyParts.push("## Diff", "```", statOut.trim(), "```", "");
|
|
19551
|
+
}
|
|
19552
|
+
if (opts.sourceLabel) {
|
|
19553
|
+
bodyParts.push(`_Landed via Sideboard from ${opts.sourceLabel}_`);
|
|
19554
|
+
}
|
|
19555
|
+
return {
|
|
19556
|
+
title,
|
|
19557
|
+
body: bodyParts.join("\n").trim() + "\n",
|
|
19558
|
+
commitMessage: truncateTitle(commitMessage, 72)
|
|
19559
|
+
};
|
|
19560
|
+
}
|
|
19561
|
+
var GENERIC_TITLE_RE;
|
|
19562
|
+
var init_pr_metadata = __esm({
|
|
19563
|
+
"src/land/pr-metadata.ts"() {
|
|
19564
|
+
"use strict";
|
|
19565
|
+
init_run();
|
|
19566
|
+
GENERIC_TITLE_RE = /^(sideboard:|thread\/|wip\b|tmp\b|update\b|changes?\b|misc\b|stuff\b)/i;
|
|
19567
|
+
}
|
|
19568
|
+
});
|
|
19569
|
+
|
|
19508
19570
|
// src/land/land.ts
|
|
19509
19571
|
async function previewLand(thread) {
|
|
19510
19572
|
if (thread.sourceIsFork) {
|
|
@@ -20035,13 +20097,14 @@ function formatRenameBranchDirective(thread, opts) {
|
|
|
20035
20097
|
if (!isPlaceholderBranch(thread.branchName, thread.worktreePath)) return null;
|
|
20036
20098
|
const dir = worktreeNameFromPath(thread.worktreePath);
|
|
20037
20099
|
const ticket = thread.sourceType === "ticket" ? ticketSlugForBranch(thread.sourceRef ?? "") : null;
|
|
20038
|
-
const
|
|
20100
|
+
const prefix = sanitizeGitBranchPrefix(opts?.branchPrefix);
|
|
20101
|
+
const example = examplePrefixedBranch(prefix, ticket);
|
|
20102
|
+
const shape = prefix ? `\`${prefix}/<ticket-or-task>-<short-kebab-description>\`` : "`<ticket-or-task>-<short-kebab-description>`";
|
|
20039
20103
|
const lines = [
|
|
20040
20104
|
"Branch naming (do this early in the turn):",
|
|
20041
20105
|
`- Current branch \`${thread.branchName}\` is a temporary placeholder. The worktree folder \`${dir}\` is a stable nickname \u2014 do not rename or leave that directory.`,
|
|
20042
|
-
`- Rename the git branch to
|
|
20106
|
+
`- Rename the git branch to ${shape}, e.g. \`${example}\`:`,
|
|
20043
20107
|
" `git branch -m <new-name>`",
|
|
20044
|
-
"- Prefer Conventional Commits style prefixes when they fit (`fix/`, `feat/`, `chore/`, `docs/`).",
|
|
20045
20108
|
...ticket ? [
|
|
20046
20109
|
`- Keep ticket \`${ticket}\` in the new branch name so the issue stays findable.`
|
|
20047
20110
|
] : [],
|
|
@@ -20247,6 +20310,7 @@ var init_instructions = __esm({
|
|
|
20247
20310
|
import_node_fs50 = require("fs");
|
|
20248
20311
|
import_node_path47 = require("path");
|
|
20249
20312
|
init_git_auth_mode();
|
|
20313
|
+
init_branch_prefix();
|
|
20250
20314
|
init_worktree_labels();
|
|
20251
20315
|
init_detached_job_path();
|
|
20252
20316
|
PR_GOAL_RE = /greptile|\bci\b.*\b(green|pass)|checks?\s+(pass|green)|until\s+.*\b(pass|green|merge|clean)|\bfix ci\b|watch[- ]fix[- ]push/i;
|
|
@@ -20948,7 +21012,6 @@ var init_orchestrator = __esm({
|
|
|
20948
21012
|
init_spawn();
|
|
20949
21013
|
init_agents();
|
|
20950
21014
|
init_worktree();
|
|
20951
|
-
init_pr_metadata();
|
|
20952
21015
|
init_stack();
|
|
20953
21016
|
init_agent_git_actions();
|
|
20954
21017
|
init_pr_merge_archive();
|
|
@@ -21736,7 +21799,7 @@ var init_orchestrator = __esm({
|
|
|
21736
21799
|
}
|
|
21737
21800
|
const isBrightsy = fresh.agent === "brightsy";
|
|
21738
21801
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
21739
|
-
const { autoRenameBranchEnabled: autoRenameBranchEnabled2, getGithubGitAuthMode: getGithubGitAuthMode2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
21802
|
+
const { autoRenameBranchEnabled: autoRenameBranchEnabled2, getGithubGitAuthMode: getGithubGitAuthMode2, gitBranchPrefixSetting: gitBranchPrefixSetting2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
21740
21803
|
const gitAuthMode = getGithubGitAuthMode2();
|
|
21741
21804
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
21742
21805
|
githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
|
|
@@ -21772,9 +21835,16 @@ var init_orchestrator = __esm({
|
|
|
21772
21835
|
}
|
|
21773
21836
|
}
|
|
21774
21837
|
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
21775
|
-
|
|
21776
|
-
|
|
21777
|
-
|
|
21838
|
+
let renameBranchDirective = null;
|
|
21839
|
+
if (!isBrightsy && !isOrchestration && autoRenameBranchEnabled2()) {
|
|
21840
|
+
const { resolveGitBranchPrefix: resolveGitBranchPrefix2 } = await Promise.resolve().then(() => (init_branch_prefix(), branch_prefix_exports));
|
|
21841
|
+
renameBranchDirective = formatRenameBranchDirective(fresh, {
|
|
21842
|
+
customPrompt: settings?.prompts?.renameBranch,
|
|
21843
|
+
branchPrefix: resolveGitBranchPrefix2({
|
|
21844
|
+
setting: gitBranchPrefixSetting2()
|
|
21845
|
+
})
|
|
21846
|
+
});
|
|
21847
|
+
}
|
|
21778
21848
|
let seed = null;
|
|
21779
21849
|
if (!fresh.sessionId) {
|
|
21780
21850
|
const prior = fresh.messages.slice(0, -1);
|
|
@@ -22804,9 +22874,9 @@ var init_orchestrator = __esm({
|
|
|
22804
22874
|
return tab;
|
|
22805
22875
|
}
|
|
22806
22876
|
/**
|
|
22807
|
-
* Desktop git buttons + MCP `ask_git`.
|
|
22808
|
-
*
|
|
22809
|
-
*
|
|
22877
|
+
* Desktop git buttons + MCP `ask_git`. Always queues the worktree agent
|
|
22878
|
+
* with the action prompt (same path as Resolve). Repository `[prompts]`
|
|
22879
|
+
* overrides apply when set.
|
|
22810
22880
|
*/
|
|
22811
22881
|
async askGit(threadRef, action) {
|
|
22812
22882
|
if (!AGENT_GIT_ACTIONS.includes(action)) {
|
|
@@ -22824,17 +22894,6 @@ var init_orchestrator = __esm({
|
|
|
22824
22894
|
"No pull request linked. Ask the worktree agent to open a draft PR first (ask_git create-draft)."
|
|
22825
22895
|
);
|
|
22826
22896
|
}
|
|
22827
|
-
if ((action === "commit-push" || action === "create-draft" || action === "create-web") && thread.worktreePath?.trim() && !await isDirty(thread.worktreePath)) {
|
|
22828
|
-
try {
|
|
22829
|
-
await this.pushAndMaybeOpenPr(thread, action);
|
|
22830
|
-
} catch (err) {
|
|
22831
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
22832
|
-
updateThread(thread.id, { lastError: message });
|
|
22833
|
-
this.emit({ type: "error", threadId: thread.id, message });
|
|
22834
|
-
throw err;
|
|
22835
|
-
}
|
|
22836
|
-
return this.requireThread(threadRef);
|
|
22837
|
-
}
|
|
22838
22897
|
let prBase;
|
|
22839
22898
|
if (action === "resolve-conflicts") {
|
|
22840
22899
|
try {
|
|
@@ -22843,42 +22902,18 @@ var init_orchestrator = __esm({
|
|
|
22843
22902
|
} catch {
|
|
22844
22903
|
}
|
|
22845
22904
|
}
|
|
22846
|
-
|
|
22847
|
-
|
|
22848
|
-
|
|
22849
|
-
|
|
22850
|
-
|
|
22851
|
-
|
|
22852
|
-
|
|
22853
|
-
|
|
22854
|
-
|
|
22855
|
-
|
|
22856
|
-
|
|
22857
|
-
|
|
22858
|
-
base,
|
|
22859
|
-
fallbackTitle: thread.prTitle ?? thread.title
|
|
22860
|
-
});
|
|
22861
|
-
const url = await createOrUpdatePr(cwd, {
|
|
22862
|
-
title: meta.title,
|
|
22863
|
-
body: meta.body,
|
|
22864
|
-
base,
|
|
22865
|
-
head: branch,
|
|
22866
|
-
draft: action === "create-draft",
|
|
22867
|
-
web: action === "create-web"
|
|
22868
|
-
});
|
|
22869
|
-
if (!url) return;
|
|
22870
|
-
const patch = {
|
|
22871
|
-
prUrl: url,
|
|
22872
|
-
prTitle: meta.title,
|
|
22873
|
-
prIsDraft: action === "create-draft"
|
|
22874
|
-
};
|
|
22875
|
-
try {
|
|
22876
|
-
const fetched = await getPrMeta(cwd, url);
|
|
22877
|
-
if (fetched?.title) patch.prTitle = fetched.title;
|
|
22878
|
-
if (fetched) patch.prIsDraft = Boolean(fetched.isDraft);
|
|
22879
|
-
} catch {
|
|
22880
|
-
}
|
|
22881
|
-
updateThread(thread.id, patch);
|
|
22905
|
+
const settings = loadWorkspaceSettings(thread.worktreePath, thread.repoPath);
|
|
22906
|
+
return this.send(
|
|
22907
|
+
threadRef,
|
|
22908
|
+
resolveSidebarGitPrompt(action, {
|
|
22909
|
+
prBase,
|
|
22910
|
+
createPr: settings?.prompts?.createPr,
|
|
22911
|
+
resolveMergeConflicts: settings?.prompts?.resolveMergeConflicts
|
|
22912
|
+
}),
|
|
22913
|
+
{
|
|
22914
|
+
followUp: resolveOrchChildFollowUp()
|
|
22915
|
+
}
|
|
22916
|
+
);
|
|
22882
22917
|
}
|
|
22883
22918
|
setThreadOptions(threadRef, patch) {
|
|
22884
22919
|
const thread = this.requireThread(threadRef);
|
|
@@ -23494,6 +23529,7 @@ __export(index_exports, {
|
|
|
23494
23529
|
estimateMessageChars: () => estimateMessageChars,
|
|
23495
23530
|
estimateOccupancyTokens: () => estimateOccupancyTokens,
|
|
23496
23531
|
estimateThreadChars: () => estimateThreadChars,
|
|
23532
|
+
examplePrefixedBranch: () => examplePrefixedBranch,
|
|
23497
23533
|
expandComposerPrompt: () => expandComposerPrompt,
|
|
23498
23534
|
extractBrightsyContextSummary: () => extractBrightsyContextSummary,
|
|
23499
23535
|
extractGhErrorDetail: () => extractGhErrorDetail,
|
|
@@ -23606,6 +23642,7 @@ __export(index_exports, {
|
|
|
23606
23642
|
ghHeadRef: () => ghHeadRef,
|
|
23607
23643
|
ghRepoSelectArgs: () => ghRepoSelectArgs,
|
|
23608
23644
|
git: () => git,
|
|
23645
|
+
gitBranchPrefixSetting: () => gitBranchPrefixSetting,
|
|
23609
23646
|
githubAgentGitEnv: () => githubAgentGitEnv,
|
|
23610
23647
|
githubHttpsInsteadOfEntries: () => githubHttpsInsteadOfEntries,
|
|
23611
23648
|
githubRelationEditFlag: () => githubRelationEditFlag,
|
|
@@ -23854,6 +23891,7 @@ __export(index_exports, {
|
|
|
23854
23891
|
resolveEffectiveIssueSource: () => resolveEffectiveIssueSource,
|
|
23855
23892
|
resolveFilesToCopy: () => resolveFilesToCopy,
|
|
23856
23893
|
resolveGhAuthToken: () => resolveGhAuthToken,
|
|
23894
|
+
resolveGitBranchPrefix: () => resolveGitBranchPrefix,
|
|
23857
23895
|
resolveGitDirsForLockRecovery: () => resolveGitDirsForLockRecovery,
|
|
23858
23896
|
resolveGitHubIssueRepo: () => resolveGitHubIssueRepo,
|
|
23859
23897
|
resolveGithubAgentToken: () => resolveGithubAgentToken,
|
|
@@ -23876,6 +23914,7 @@ __export(index_exports, {
|
|
|
23876
23914
|
resolveReviewGuidelines: () => resolveReviewGuidelines,
|
|
23877
23915
|
resolveScheduleThreadId: () => resolveScheduleThreadId,
|
|
23878
23916
|
resolveSendFollowUp: () => resolveSendFollowUp,
|
|
23917
|
+
resolveSidebarGitPrompt: () => resolveSidebarGitPrompt,
|
|
23879
23918
|
resolveSlackListenMode: () => resolveSlackListenMode,
|
|
23880
23919
|
resolveThreadDefaults: () => resolveThreadDefaults,
|
|
23881
23920
|
resolveThreadEffort: () => resolveThreadEffort,
|
|
@@ -23895,6 +23934,7 @@ __export(index_exports, {
|
|
|
23895
23934
|
runSlackRelayClient: () => runSlackRelayClient,
|
|
23896
23935
|
runWorkspaceSetup: () => runWorkspaceSetup,
|
|
23897
23936
|
sameWorktreePath: () => sameWorktreePath,
|
|
23937
|
+
sanitizeGitBranchPrefix: () => sanitizeGitBranchPrefix,
|
|
23898
23938
|
sanitizeMcpServerName: () => sanitizeMcpServerName,
|
|
23899
23939
|
saveAbleTimeConnection: () => saveAbleTimeConnection,
|
|
23900
23940
|
saveAppSettings: () => saveAppSettings,
|
|
@@ -24040,6 +24080,7 @@ init_gh_errors();
|
|
|
24040
24080
|
init_git_auth_mode();
|
|
24041
24081
|
init_worktree();
|
|
24042
24082
|
init_stack();
|
|
24083
|
+
init_branch_prefix();
|
|
24043
24084
|
init_agent_git_actions();
|
|
24044
24085
|
|
|
24045
24086
|
// src/integrations/github.ts
|
|
@@ -29183,7 +29224,7 @@ async function startMcpServer() {
|
|
|
29183
29224
|
);
|
|
29184
29225
|
server.tool(
|
|
29185
29226
|
"ask_git",
|
|
29186
|
-
"Commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge \u2014 same
|
|
29227
|
+
"Commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge \u2014 same prompts as the desktop git buttons (including Resolve). Always steers the worktree agent; does not push or open the PR locally. 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.",
|
|
29187
29228
|
{
|
|
29188
29229
|
ref: import_zod9.z.string().describe("Worktree thread id/ref"),
|
|
29189
29230
|
action: import_zod9.z.enum(AGENT_GIT_ACTIONS).describe(
|
|
@@ -32104,6 +32145,7 @@ init_outbound_watch();
|
|
|
32104
32145
|
estimateMessageChars,
|
|
32105
32146
|
estimateOccupancyTokens,
|
|
32106
32147
|
estimateThreadChars,
|
|
32148
|
+
examplePrefixedBranch,
|
|
32107
32149
|
expandComposerPrompt,
|
|
32108
32150
|
extractBrightsyContextSummary,
|
|
32109
32151
|
extractGhErrorDetail,
|
|
@@ -32216,6 +32258,7 @@ init_outbound_watch();
|
|
|
32216
32258
|
ghHeadRef,
|
|
32217
32259
|
ghRepoSelectArgs,
|
|
32218
32260
|
git,
|
|
32261
|
+
gitBranchPrefixSetting,
|
|
32219
32262
|
githubAgentGitEnv,
|
|
32220
32263
|
githubHttpsInsteadOfEntries,
|
|
32221
32264
|
githubRelationEditFlag,
|
|
@@ -32464,6 +32507,7 @@ init_outbound_watch();
|
|
|
32464
32507
|
resolveEffectiveIssueSource,
|
|
32465
32508
|
resolveFilesToCopy,
|
|
32466
32509
|
resolveGhAuthToken,
|
|
32510
|
+
resolveGitBranchPrefix,
|
|
32467
32511
|
resolveGitDirsForLockRecovery,
|
|
32468
32512
|
resolveGitHubIssueRepo,
|
|
32469
32513
|
resolveGithubAgentToken,
|
|
@@ -32486,6 +32530,7 @@ init_outbound_watch();
|
|
|
32486
32530
|
resolveReviewGuidelines,
|
|
32487
32531
|
resolveScheduleThreadId,
|
|
32488
32532
|
resolveSendFollowUp,
|
|
32533
|
+
resolveSidebarGitPrompt,
|
|
32489
32534
|
resolveSlackListenMode,
|
|
32490
32535
|
resolveThreadDefaults,
|
|
32491
32536
|
resolveThreadEffort,
|
|
@@ -32505,6 +32550,7 @@ init_outbound_watch();
|
|
|
32505
32550
|
runSlackRelayClient,
|
|
32506
32551
|
runWorkspaceSetup,
|
|
32507
32552
|
sameWorktreePath,
|
|
32553
|
+
sanitizeGitBranchPrefix,
|
|
32508
32554
|
sanitizeMcpServerName,
|
|
32509
32555
|
saveAbleTimeConnection,
|
|
32510
32556
|
saveAppSettings,
|