@sideboard-ai/core 0.1.77 → 0.1.79
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-XJV6J3K2.js → agents-EWPHOM6Y.js} +6 -6
- package/dist/{agents-LKUHPPEQ.js → agents-GRAPUXWW.js} +5 -5
- package/dist/{app-settings-3TLA2EJ7.js → app-settings-6IOQYGBK.js} +7 -1
- package/dist/{app-settings-P42Z3VOB.js → app-settings-NILNWNNQ.js} +7 -1
- package/dist/{chunk-VERLUKN2.js → chunk-5LXWTU3J.js} +6 -6
- package/dist/{chunk-2ZIPJRJE.js → chunk-5VTWBI3I.js} +2 -2
- package/dist/{chunk-GWTLKXXP.js → chunk-6T2SKGCS.js} +3 -3
- package/dist/{chunk-OE7YBB5X.js → chunk-FUUVPN4A.js} +108 -3
- package/dist/{chunk-EEKSZTMU.js → chunk-HCGEFU3J.js} +5 -5
- package/dist/{chunk-XJNCWYFR.js → chunk-HSLQXL6M.js} +3 -3
- package/dist/{chunk-W7YOTDVO.js → chunk-IFPN6TER.js} +47 -2
- package/dist/{chunk-2FJI5JXX.js → chunk-P33ZQ7ZC.js} +3 -3
- package/dist/{chunk-75U65MBE.js → chunk-PW5YHHP3.js} +2 -2
- package/dist/{chunk-QD37IILI.js → chunk-SHCR6RPU.js} +3 -3
- package/dist/{chunk-PTJJIQK7.js → chunk-XKNBSYA7.js} +47 -2
- package/dist/{chunk-MF2YMEGD.js → chunk-YVVXWWCC.js} +110 -3
- package/dist/{coordinator-prompt-LLFJUO2R.js → coordinator-prompt-2OVON2LQ.js} +4 -4
- package/dist/{coordinator-prompt-MRCMMRSF.js → coordinator-prompt-K2R34A5T.js} +3 -3
- package/dist/{global-workspace-TWHMYLTZ.js → global-workspace-RI367AM6.js} +4 -4
- package/dist/{global-workspace-YNMNO4CL.js → global-workspace-VG44RZUH.js} +5 -5
- package/dist/index.cjs +500 -178
- package/dist/index.d.cts +83 -8
- package/dist/index.d.ts +83 -8
- package/dist/index.js +344 -179
- package/dist/mcp/run-stdio.cjs +2439 -2228
- package/dist/mcp/run-stdio.js +156 -100
- package/dist/{workspaces-GQ4XKBD3.js → workspaces-BQWQEZWE.js} +5 -5
- package/dist/{workspaces-O3U5BENH.js → workspaces-TYPJNUSM.js} +6 -6
- package/dist/{worktree-VOCH3WS3.js → worktree-5VLLFI5W.js} +5 -1
- package/dist/{worktree-KWXHMKRN.js → worktree-UNSOCYZU.js} +5 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
listWorkspaces,
|
|
5
5
|
removeWorkspace,
|
|
6
6
|
syncWorkspacesFromThreads
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-PW5YHHP3.js";
|
|
8
8
|
import {
|
|
9
9
|
BRIGHTSY_MCP_ALLOWED_TOOLS,
|
|
10
10
|
CLAUDE_MODEL_CATALOG,
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
sideboardMcpProfile,
|
|
59
59
|
threadRequestsBrightsyMcp,
|
|
60
60
|
writeInjectedMcpConfig
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-SHCR6RPU.js";
|
|
62
62
|
import {
|
|
63
63
|
CLOUD_COORDINATOR_BUSY_REPLY,
|
|
64
64
|
CLOUD_COORDINATOR_STOPPED_REPLY,
|
|
@@ -85,7 +85,7 @@ import {
|
|
|
85
85
|
parseForceStopMessage,
|
|
86
86
|
slackCoordinatorSourceRef,
|
|
87
87
|
takenTeamSlugsForOrchestration
|
|
88
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-5LXWTU3J.js";
|
|
89
89
|
import {
|
|
90
90
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
91
91
|
SLACK_REPLY_FORMATTING,
|
|
@@ -94,7 +94,7 @@ import {
|
|
|
94
94
|
enrichWorkspacesWithGithub,
|
|
95
95
|
ensureGlobalCoordinatorCwd,
|
|
96
96
|
formatWorkspaceInventory
|
|
97
|
-
} from "./chunk-
|
|
97
|
+
} from "./chunk-HCGEFU3J.js";
|
|
98
98
|
import {
|
|
99
99
|
brightsyConfigPath,
|
|
100
100
|
brightsyMcpServerName,
|
|
@@ -129,66 +129,6 @@ import {
|
|
|
129
129
|
pushTurnStderr,
|
|
130
130
|
summarizeTurnStderr
|
|
131
131
|
} from "./chunk-SEOICVGB.js";
|
|
132
|
-
import {
|
|
133
|
-
HARNESS_ENV_KEYS,
|
|
134
|
-
appSettingsPath,
|
|
135
|
-
applyAppEnvironment,
|
|
136
|
-
autoArchiveOnMergeEnabled,
|
|
137
|
-
autoCleanupOrphansEnabled,
|
|
138
|
-
autoRenameBranchEnabled,
|
|
139
|
-
autoRunAfterSetupEnabled,
|
|
140
|
-
brightsyCloudConnectAgent,
|
|
141
|
-
brightsyCloudConnectEnabled,
|
|
142
|
-
brightsyInjectWorktreeMcpEnabled,
|
|
143
|
-
caffeinateWhileCloudConnectEnabled,
|
|
144
|
-
caffeinateWhileRunningEnabled,
|
|
145
|
-
caffeinateWhileSlackListenEnabled,
|
|
146
|
-
childEnvWithAppSettings,
|
|
147
|
-
claudeChromeEnabled,
|
|
148
|
-
claudeUserSettingsPath,
|
|
149
|
-
deleteBranchOnPurgeEnabled,
|
|
150
|
-
disconnectLinearConnection,
|
|
151
|
-
ensureSlackDeviceIdentity,
|
|
152
|
-
getDefaultAgent,
|
|
153
|
-
getDefaultEffort,
|
|
154
|
-
getDefaultFast,
|
|
155
|
-
getDefaultModel,
|
|
156
|
-
getIssueSource,
|
|
157
|
-
getLinearApiKey,
|
|
158
|
-
harnessEnvKey,
|
|
159
|
-
isLinearConnected,
|
|
160
|
-
isSecureFileEncrypted,
|
|
161
|
-
loadAppSettings,
|
|
162
|
-
maxConcurrentAgents,
|
|
163
|
-
orchestrationQuotaFallbackAgent,
|
|
164
|
-
orchestrationQuotaOnLimit,
|
|
165
|
-
persistVaultKeyInKeychain,
|
|
166
|
-
readKeychainVaultKey,
|
|
167
|
-
readSecureJson,
|
|
168
|
-
resolveAgentExecutable,
|
|
169
|
-
resolveClaudeExecutable,
|
|
170
|
-
resolveEffectiveIssueSource,
|
|
171
|
-
resolveNewThreadOptions,
|
|
172
|
-
resolveThreadDefaults,
|
|
173
|
-
resolveVaultKey,
|
|
174
|
-
saveAppSettings,
|
|
175
|
-
saveLinearOAuth,
|
|
176
|
-
secureFileUnlocksWith,
|
|
177
|
-
setVaultMasterKey,
|
|
178
|
-
slackAppLevelToken,
|
|
179
|
-
slackListenEnabled,
|
|
180
|
-
toPublicAppSettings,
|
|
181
|
-
updateAdvancedSettings,
|
|
182
|
-
updateAgentExecutable,
|
|
183
|
-
updateAppEnvironment,
|
|
184
|
-
updateBrightsySettings,
|
|
185
|
-
updateClaudeSettings,
|
|
186
|
-
updateCodexSettings,
|
|
187
|
-
updateDefaultsSettings,
|
|
188
|
-
updateIntegrationsSettings,
|
|
189
|
-
updateOpencodeSettings,
|
|
190
|
-
writeSecureJson
|
|
191
|
-
} from "./chunk-W7YOTDVO.js";
|
|
192
132
|
import {
|
|
193
133
|
caffeinateHoldPath,
|
|
194
134
|
getCaffeinateHold,
|
|
@@ -196,14 +136,13 @@ import {
|
|
|
196
136
|
releaseCaffeinateHoldForThread,
|
|
197
137
|
setCaffeinateHold
|
|
198
138
|
} from "./chunk-MFF2RE3I.js";
|
|
199
|
-
import {
|
|
200
|
-
writePrivateFile
|
|
201
|
-
} from "./chunk-JT7R45JB.js";
|
|
202
139
|
import {
|
|
203
140
|
FAMOUS_SOCCER_TEAMS,
|
|
204
141
|
addPrStackLayer,
|
|
205
142
|
allocateTeamName,
|
|
206
143
|
allocateTeamSlug,
|
|
144
|
+
appendIndexedGitConfig,
|
|
145
|
+
applyGithubGitAuthEnv,
|
|
207
146
|
branchDisplayLabel,
|
|
208
147
|
checkoutPrStackLayer,
|
|
209
148
|
collectTakenTeamSlugs,
|
|
@@ -218,6 +157,7 @@ import {
|
|
|
218
157
|
extractGhErrorDetail,
|
|
219
158
|
fetchPrHead,
|
|
220
159
|
formatGhLandError,
|
|
160
|
+
formatGitAuthModeDirective,
|
|
221
161
|
formatIpcInvokeError,
|
|
222
162
|
formatRateLimitResetHint,
|
|
223
163
|
getPr,
|
|
@@ -227,6 +167,7 @@ import {
|
|
|
227
167
|
getPrStack,
|
|
228
168
|
ghHeadRef,
|
|
229
169
|
ghRepoSelectArgs,
|
|
170
|
+
githubAgentGitEnv,
|
|
230
171
|
initPrStack,
|
|
231
172
|
isDirty,
|
|
232
173
|
isGhRateLimitError,
|
|
@@ -261,13 +202,79 @@ import {
|
|
|
261
202
|
worktreeDisplayLabel,
|
|
262
203
|
worktreeDisplayLabelForGroup,
|
|
263
204
|
worktreeNameFromPath
|
|
264
|
-
} from "./chunk-
|
|
205
|
+
} from "./chunk-YVVXWWCC.js";
|
|
265
206
|
import {
|
|
266
207
|
ATTACHMENTS_DIR,
|
|
267
208
|
LEGACY_ATTACHMENTS_DIR,
|
|
268
209
|
attachmentsGitignoreBody,
|
|
269
210
|
isWorkspaceScratchPath
|
|
270
211
|
} from "./chunk-FKOIHGKV.js";
|
|
212
|
+
import {
|
|
213
|
+
GITHUB_GIT_AUTH_MODES,
|
|
214
|
+
HARNESS_ENV_KEYS,
|
|
215
|
+
appSettingsPath,
|
|
216
|
+
applyAppEnvironment,
|
|
217
|
+
autoArchiveOnMergeEnabled,
|
|
218
|
+
autoCleanupOrphansEnabled,
|
|
219
|
+
autoRenameBranchEnabled,
|
|
220
|
+
autoRunAfterSetupEnabled,
|
|
221
|
+
brightsyCloudConnectAgent,
|
|
222
|
+
brightsyCloudConnectEnabled,
|
|
223
|
+
brightsyInjectWorktreeMcpEnabled,
|
|
224
|
+
caffeinateWhileCloudConnectEnabled,
|
|
225
|
+
caffeinateWhileRunningEnabled,
|
|
226
|
+
caffeinateWhileSlackListenEnabled,
|
|
227
|
+
childEnvWithAppSettings,
|
|
228
|
+
claudeChromeEnabled,
|
|
229
|
+
claudeUserSettingsPath,
|
|
230
|
+
deleteBranchOnPurgeEnabled,
|
|
231
|
+
disconnectLinearConnection,
|
|
232
|
+
ensureSlackDeviceIdentity,
|
|
233
|
+
getDefaultAgent,
|
|
234
|
+
getDefaultEffort,
|
|
235
|
+
getDefaultFast,
|
|
236
|
+
getDefaultModel,
|
|
237
|
+
getGithubGitAuthMode,
|
|
238
|
+
getGithubPat,
|
|
239
|
+
getIssueSource,
|
|
240
|
+
getLinearApiKey,
|
|
241
|
+
harnessEnvKey,
|
|
242
|
+
isLinearConnected,
|
|
243
|
+
isSecureFileEncrypted,
|
|
244
|
+
loadAppSettings,
|
|
245
|
+
maxConcurrentAgents,
|
|
246
|
+
orchestrationQuotaFallbackAgent,
|
|
247
|
+
orchestrationQuotaOnLimit,
|
|
248
|
+
persistVaultKeyInKeychain,
|
|
249
|
+
readKeychainVaultKey,
|
|
250
|
+
readSecureJson,
|
|
251
|
+
resolveAgentExecutable,
|
|
252
|
+
resolveClaudeExecutable,
|
|
253
|
+
resolveEffectiveIssueSource,
|
|
254
|
+
resolveNewThreadOptions,
|
|
255
|
+
resolveThreadDefaults,
|
|
256
|
+
resolveVaultKey,
|
|
257
|
+
saveAppSettings,
|
|
258
|
+
saveLinearOAuth,
|
|
259
|
+
secureFileUnlocksWith,
|
|
260
|
+
setVaultMasterKey,
|
|
261
|
+
slackAppLevelToken,
|
|
262
|
+
slackListenEnabled,
|
|
263
|
+
toPublicAppSettings,
|
|
264
|
+
updateAdvancedSettings,
|
|
265
|
+
updateAgentExecutable,
|
|
266
|
+
updateAppEnvironment,
|
|
267
|
+
updateBrightsySettings,
|
|
268
|
+
updateClaudeSettings,
|
|
269
|
+
updateCodexSettings,
|
|
270
|
+
updateDefaultsSettings,
|
|
271
|
+
updateIntegrationsSettings,
|
|
272
|
+
updateOpencodeSettings,
|
|
273
|
+
writeSecureJson
|
|
274
|
+
} from "./chunk-IFPN6TER.js";
|
|
275
|
+
import {
|
|
276
|
+
writePrivateFile
|
|
277
|
+
} from "./chunk-JT7R45JB.js";
|
|
271
278
|
import {
|
|
272
279
|
appendMessage,
|
|
273
280
|
createEmptyThread,
|
|
@@ -1075,8 +1082,8 @@ function toolDetail(name, input) {
|
|
|
1075
1082
|
if (!input) return void 0;
|
|
1076
1083
|
const command = str(input.command) ?? str(input.cmd);
|
|
1077
1084
|
if (command) return command;
|
|
1078
|
-
const
|
|
1079
|
-
if (
|
|
1085
|
+
const path2 = str(input.file_path) ?? str(input.path) ?? str(input.filePath) ?? str(input.filename);
|
|
1086
|
+
if (path2) return path2;
|
|
1080
1087
|
const pattern = str(input.pattern) ?? str(input.glob) ?? str(input.glob_pattern);
|
|
1081
1088
|
if (pattern) return pattern;
|
|
1082
1089
|
const query = str(input.query) ?? str(input.prompt);
|
|
@@ -1120,12 +1127,12 @@ function toolDescription(name, input) {
|
|
|
1120
1127
|
return "Run shell command";
|
|
1121
1128
|
}
|
|
1122
1129
|
if (/edit|write|apply/i.test(name)) {
|
|
1123
|
-
const
|
|
1124
|
-
return
|
|
1130
|
+
const path2 = str(input.file_path) ?? str(input.path);
|
|
1131
|
+
return path2 ? `Edit ${path2.split("/").pop()}` : "Edit file";
|
|
1125
1132
|
}
|
|
1126
1133
|
if (/read/i.test(name)) {
|
|
1127
|
-
const
|
|
1128
|
-
return
|
|
1134
|
+
const path2 = str(input.file_path) ?? str(input.path);
|
|
1135
|
+
return path2 ? `Read ${path2.split("/").pop()}` : "Read file";
|
|
1129
1136
|
}
|
|
1130
1137
|
if (/grep/i.test(name)) return "Search files";
|
|
1131
1138
|
if (/glob/i.test(name)) return "Find files";
|
|
@@ -1332,9 +1339,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
1332
1339
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
1333
1340
|
);
|
|
1334
1341
|
}
|
|
1335
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
1342
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-VG44RZUH.js");
|
|
1336
1343
|
if (isGlobalThread2(thread)) {
|
|
1337
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
1344
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-2OVON2LQ.js");
|
|
1338
1345
|
ensureGlobalCoordinatorCwd2(
|
|
1339
1346
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
1340
1347
|
);
|
|
@@ -1351,8 +1358,13 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
1351
1358
|
}
|
|
1352
1359
|
const env = childEnvWithAppSettings(cmd.env);
|
|
1353
1360
|
if (!isOrchestratorThread(thread)) {
|
|
1354
|
-
|
|
1355
|
-
|
|
1361
|
+
try {
|
|
1362
|
+
const originEnv = await originGhRepoEnv(thread.worktreePath, { env });
|
|
1363
|
+
Object.assign(env, originEnv);
|
|
1364
|
+
} catch (err) {
|
|
1365
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
1366
|
+
console.warn(`[sideboard] originGhRepoEnv failed (${thread.worktreePath}): ${detail}`);
|
|
1367
|
+
}
|
|
1356
1368
|
}
|
|
1357
1369
|
const child = execa(cmd.file, cmd.args, {
|
|
1358
1370
|
cwd: cmd.cwd,
|
|
@@ -1487,6 +1499,8 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
1487
1499
|
lines.push(
|
|
1488
1500
|
"- Push with `git push -u origin HEAD` (or the current branch name). Do not `git push upstream`."
|
|
1489
1501
|
);
|
|
1502
|
+
lines.push("");
|
|
1503
|
+
lines.push(formatGitAuthModeDirective(opts?.gitAuthMode ?? "auto"));
|
|
1490
1504
|
lines.push(
|
|
1491
1505
|
"- Derive the PR title and body from what the changes actually do and why \u2014 inspect the diff/commits and the user request. Do not use the soccer-team worktree nickname or placeholder branch as the PR title."
|
|
1492
1506
|
);
|
|
@@ -1672,9 +1686,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
1672
1686
|
return new RegExp(`^${escaped}$`).test(name);
|
|
1673
1687
|
}
|
|
1674
1688
|
function readWorktreeInclude(repoPath) {
|
|
1675
|
-
const
|
|
1676
|
-
if (!existsSync2(
|
|
1677
|
-
return readFileSync2(
|
|
1689
|
+
const path2 = join2(repoPath, ".worktreeinclude");
|
|
1690
|
+
if (!existsSync2(path2)) return [];
|
|
1691
|
+
return readFileSync2(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
1678
1692
|
}
|
|
1679
1693
|
function resolveFilesToCopy(repoPath) {
|
|
1680
1694
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -1749,8 +1763,20 @@ async function captureLoginEnv() {
|
|
|
1749
1763
|
cachedLoginEnv = { ...process.env };
|
|
1750
1764
|
return { ...cachedLoginEnv };
|
|
1751
1765
|
}
|
|
1766
|
+
var NESTED_ELECTRON_ENV_PREFIXES = ["ELECTRON_", "CHROME_"];
|
|
1767
|
+
function stripNestedElectronEnv(env) {
|
|
1768
|
+
const out = { ...env };
|
|
1769
|
+
for (const key of Object.keys(out)) {
|
|
1770
|
+
if (NESTED_ELECTRON_ENV_PREFIXES.some((prefix) => key.startsWith(prefix))) {
|
|
1771
|
+
delete out[key];
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
return out;
|
|
1775
|
+
}
|
|
1752
1776
|
function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
1753
|
-
const env = {
|
|
1777
|
+
const env = stripNestedElectronEnv({
|
|
1778
|
+
...baseEnv ?? process.env
|
|
1779
|
+
});
|
|
1754
1780
|
const name = opts.workspaceName ?? basename(opts.worktreePath);
|
|
1755
1781
|
const ports = opts.ports ?? [];
|
|
1756
1782
|
const primary = ports[0];
|
|
@@ -1975,10 +2001,10 @@ import { join as join3 } from "path";
|
|
|
1975
2001
|
import { execa as execa3 } from "execa";
|
|
1976
2002
|
import { createInterface as createInterface3 } from "readline";
|
|
1977
2003
|
function loadCursorWorktreesJson(rootPath) {
|
|
1978
|
-
const
|
|
1979
|
-
if (!existsSync3(
|
|
2004
|
+
const path2 = join3(rootPath, ".cursor", "worktrees.json");
|
|
2005
|
+
if (!existsSync3(path2)) return null;
|
|
1980
2006
|
try {
|
|
1981
|
-
return JSON.parse(readFileSync3(
|
|
2007
|
+
return JSON.parse(readFileSync3(path2, "utf8"));
|
|
1982
2008
|
} catch {
|
|
1983
2009
|
return null;
|
|
1984
2010
|
}
|
|
@@ -2079,9 +2105,9 @@ function parseNameStatus(stdout) {
|
|
|
2079
2105
|
const out = [];
|
|
2080
2106
|
for (const line of stdout.split("\n").filter(Boolean)) {
|
|
2081
2107
|
const [status, ...pathParts] = line.split(" ");
|
|
2082
|
-
const
|
|
2083
|
-
if (!status || !
|
|
2084
|
-
out.push({ status: status[0] ?? status, path });
|
|
2108
|
+
const path2 = pathParts[pathParts.length - 1];
|
|
2109
|
+
if (!status || !path2) continue;
|
|
2110
|
+
out.push({ status: status[0] ?? status, path: path2 });
|
|
2085
2111
|
}
|
|
2086
2112
|
return out;
|
|
2087
2113
|
}
|
|
@@ -2089,12 +2115,12 @@ function parseNumstat(stdout) {
|
|
|
2089
2115
|
const map = /* @__PURE__ */ new Map();
|
|
2090
2116
|
for (const line of stdout.split("\n").filter(Boolean)) {
|
|
2091
2117
|
const [addRaw, delRaw, ...pathParts] = line.split(" ");
|
|
2092
|
-
const
|
|
2093
|
-
if (!
|
|
2118
|
+
const path2 = pathParts[pathParts.length - 1];
|
|
2119
|
+
if (!path2) continue;
|
|
2094
2120
|
const additions = addRaw === "-" ? 0 : Number(addRaw);
|
|
2095
2121
|
const deletions = delRaw === "-" ? 0 : Number(delRaw);
|
|
2096
2122
|
if (!Number.isFinite(additions) && !Number.isFinite(deletions)) continue;
|
|
2097
|
-
map.set(
|
|
2123
|
+
map.set(path2, {
|
|
2098
2124
|
additions: Number.isFinite(additions) ? additions : 0,
|
|
2099
2125
|
deletions: Number.isFinite(deletions) ? deletions : 0
|
|
2100
2126
|
});
|
|
@@ -2171,70 +2197,70 @@ function splitCombinedDiff(stdout) {
|
|
|
2171
2197
|
}
|
|
2172
2198
|
return map;
|
|
2173
2199
|
}
|
|
2174
|
-
function syntheticAddPatch(
|
|
2200
|
+
function syntheticAddPatch(path2, content, maxHunk) {
|
|
2175
2201
|
const lines = content.split("\n");
|
|
2176
2202
|
const body = lines.map((l) => `+${l}`).join("\n");
|
|
2177
|
-
const header = `diff --git a/${
|
|
2203
|
+
const header = `diff --git a/${path2} b/${path2}
|
|
2178
2204
|
new file mode 100644
|
|
2179
2205
|
--- /dev/null
|
|
2180
|
-
+++ b/${
|
|
2206
|
+
+++ b/${path2}
|
|
2181
2207
|
@@ -0,0 +1,${lines.length} @@
|
|
2182
2208
|
`;
|
|
2183
2209
|
return {
|
|
2184
|
-
path,
|
|
2210
|
+
path: path2,
|
|
2185
2211
|
status: "A",
|
|
2186
2212
|
patch: capPatch(`${header}${body}`, maxHunk),
|
|
2187
2213
|
additions: lines.length,
|
|
2188
2214
|
deletions: 0
|
|
2189
2215
|
};
|
|
2190
2216
|
}
|
|
2191
|
-
async function untrackedPatch(worktreePath,
|
|
2192
|
-
const abs = join4(worktreePath,
|
|
2217
|
+
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
2218
|
+
const abs = join4(worktreePath, path2);
|
|
2193
2219
|
try {
|
|
2194
2220
|
const st = statSync2(abs);
|
|
2195
2221
|
if (st.isFile() && st.size > maxHunk) {
|
|
2196
2222
|
const buf = readFileSync4(abs).subarray(0, maxHunk);
|
|
2197
|
-
return syntheticAddPatch(
|
|
2223
|
+
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
2198
2224
|
}
|
|
2199
2225
|
} catch {
|
|
2200
2226
|
}
|
|
2201
2227
|
const { stdout: patch } = await git(
|
|
2202
|
-
["diff", "--no-ext-diff", "--no-color", "--no-index", "--", "/dev/null",
|
|
2228
|
+
["diff", "--no-ext-diff", "--no-color", "--no-index", "--", "/dev/null", path2],
|
|
2203
2229
|
worktreePath,
|
|
2204
2230
|
{ reject: false, timeoutMs: 4e3 }
|
|
2205
2231
|
);
|
|
2206
|
-
const normalized = patch.replace(/^diff --git a\/.+? b\/.+?$/m, `diff --git a/${
|
|
2232
|
+
const normalized = patch.replace(/^diff --git a\/.+? b\/.+?$/m, `diff --git a/${path2} b/${path2}`).replace(/^--- .*$/m, "--- /dev/null").replace(/^\+\+\+ .*$/m, `+++ b/${path2}`);
|
|
2207
2233
|
const addLines = normalized.split("\n").filter((l) => l.startsWith("+") && !l.startsWith("+++")).length;
|
|
2208
2234
|
return {
|
|
2209
|
-
path,
|
|
2235
|
+
path: path2,
|
|
2210
2236
|
status: "A",
|
|
2211
2237
|
patch: capPatch(normalized, maxHunk),
|
|
2212
2238
|
additions: addLines,
|
|
2213
2239
|
deletions: 0
|
|
2214
2240
|
};
|
|
2215
2241
|
}
|
|
2216
|
-
async function listUntrackedPaths(worktreePath,
|
|
2242
|
+
async function listUntrackedPaths(worktreePath, path2) {
|
|
2217
2243
|
const args = ["ls-files", "-z", "--others", "--exclude-standard"];
|
|
2218
|
-
if (
|
|
2244
|
+
if (path2) args.push("--", path2);
|
|
2219
2245
|
const { stdout } = await git(args, worktreePath, { reject: false });
|
|
2220
2246
|
return stdout.split("\0").filter(Boolean).filter((p) => !isSideboardScratchPath(p));
|
|
2221
2247
|
}
|
|
2222
2248
|
async function listUntrackedFiles(worktreePath, maxHunk, paths) {
|
|
2223
2249
|
const list = paths ?? await listUntrackedPaths(worktreePath);
|
|
2224
2250
|
if (list.length === 0) return [];
|
|
2225
|
-
return Promise.all(list.map((
|
|
2251
|
+
return Promise.all(list.map((path2) => untrackedPatch(worktreePath, path2, maxHunk)));
|
|
2226
2252
|
}
|
|
2227
2253
|
function untrackedStubs(paths) {
|
|
2228
|
-
return paths.map((
|
|
2229
|
-
path,
|
|
2254
|
+
return paths.map((path2) => ({
|
|
2255
|
+
path: path2,
|
|
2230
2256
|
status: "A",
|
|
2231
2257
|
patch: "",
|
|
2232
2258
|
additions: 0,
|
|
2233
2259
|
deletions: 0
|
|
2234
2260
|
}));
|
|
2235
2261
|
}
|
|
2236
|
-
function pathspec(
|
|
2237
|
-
return
|
|
2262
|
+
function pathspec(path2) {
|
|
2263
|
+
return path2 ? ["--", path2] : [];
|
|
2238
2264
|
}
|
|
2239
2265
|
function gitDiff(args, cwd, opts) {
|
|
2240
2266
|
return git(["diff", "--no-ext-diff", "--no-color", ...args], cwd, {
|
|
@@ -2242,7 +2268,7 @@ function gitDiff(args, cwd, opts) {
|
|
|
2242
2268
|
timeoutMs: opts?.timeoutMs
|
|
2243
2269
|
});
|
|
2244
2270
|
}
|
|
2245
|
-
function fileFromPatch(
|
|
2271
|
+
function fileFromPatch(path2, patch, maxHunk) {
|
|
2246
2272
|
let status = "M";
|
|
2247
2273
|
if (/^new file mode /m.test(patch) || /^--- \/dev\/null/m.test(patch)) {
|
|
2248
2274
|
status = "A";
|
|
@@ -2254,15 +2280,15 @@ function fileFromPatch(path, patch, maxHunk) {
|
|
|
2254
2280
|
const additions = patch.split("\n").filter((l) => l.startsWith("+") && !l.startsWith("+++")).length;
|
|
2255
2281
|
const deletions = patch.split("\n").filter((l) => l.startsWith("-") && !l.startsWith("---")).length;
|
|
2256
2282
|
return {
|
|
2257
|
-
path,
|
|
2283
|
+
path: path2,
|
|
2258
2284
|
status,
|
|
2259
2285
|
patch: capPatch(patch, maxHunk),
|
|
2260
2286
|
additions,
|
|
2261
2287
|
deletions
|
|
2262
2288
|
};
|
|
2263
2289
|
}
|
|
2264
|
-
async function gitDiffParts(worktreePath, diffArgs, includePatches,
|
|
2265
|
-
const extra = pathspec(
|
|
2290
|
+
async function gitDiffParts(worktreePath, diffArgs, includePatches, path2) {
|
|
2291
|
+
const extra = pathspec(path2);
|
|
2266
2292
|
if (includePatches) {
|
|
2267
2293
|
const diff = await gitDiff([...diffArgs, ...extra], worktreePath, {
|
|
2268
2294
|
timeoutMs: 4e3
|
|
@@ -2300,17 +2326,17 @@ function filesFromDiff(nameStatus, numstat, combinedDiff, maxHunk) {
|
|
|
2300
2326
|
const patches = splitCombinedDiff(combinedDiff);
|
|
2301
2327
|
if (!nameStatus.trim() && patches.size > 0) {
|
|
2302
2328
|
return [...patches.entries()].map(
|
|
2303
|
-
([
|
|
2329
|
+
([path2, patch]) => fileFromPatch(path2, patch, maxHunk)
|
|
2304
2330
|
);
|
|
2305
2331
|
}
|
|
2306
2332
|
const counts = parseNumstat(numstat);
|
|
2307
2333
|
const files = [];
|
|
2308
|
-
for (const { status, path } of parseNameStatus(nameStatus)) {
|
|
2309
|
-
const n = counts.get(
|
|
2334
|
+
for (const { status, path: path2 } of parseNameStatus(nameStatus)) {
|
|
2335
|
+
const n = counts.get(path2);
|
|
2310
2336
|
files.push({
|
|
2311
|
-
path,
|
|
2337
|
+
path: path2,
|
|
2312
2338
|
status,
|
|
2313
|
-
patch: capPatch(patches.get(
|
|
2339
|
+
patch: capPatch(patches.get(path2) ?? "", maxHunk),
|
|
2314
2340
|
additions: n?.additions,
|
|
2315
2341
|
deletions: n?.deletions
|
|
2316
2342
|
});
|
|
@@ -2394,7 +2420,7 @@ function emptyPathDiff(scope, base, hasLastTurnBase, commitSha = null) {
|
|
|
2394
2420
|
};
|
|
2395
2421
|
}
|
|
2396
2422
|
async function getPathDiff(worktreePath, repoPath, opts) {
|
|
2397
|
-
const { path, scope, commitSha, lastTurnBase, hasLastTurnBase, includePatches, maxHunk } = opts;
|
|
2423
|
+
const { path: path2, scope, commitSha, lastTurnBase, hasLastTurnBase, includePatches, maxHunk } = opts;
|
|
2398
2424
|
if (scope === "last_turn" && !lastTurnBase) {
|
|
2399
2425
|
return emptyPathDiff(scope, "last turn", false);
|
|
2400
2426
|
}
|
|
@@ -2433,7 +2459,7 @@ async function getPathDiff(worktreePath, repoPath, opts) {
|
|
|
2433
2459
|
labelBase = "HEAD";
|
|
2434
2460
|
}
|
|
2435
2461
|
const diff = await gitDiff(
|
|
2436
|
-
includePatches ? [...diffArgs, "--",
|
|
2462
|
+
includePatches ? [...diffArgs, "--", path2] : ["--name-status", ...diffArgs, "--", path2],
|
|
2437
2463
|
worktreePath,
|
|
2438
2464
|
{ timeoutMs: 4e3 }
|
|
2439
2465
|
);
|
|
@@ -2441,8 +2467,8 @@ async function getPathDiff(worktreePath, repoPath, opts) {
|
|
|
2441
2467
|
if (includePatches) {
|
|
2442
2468
|
const parsed = filesFromDiff("", "", diff.stdout, maxHunk);
|
|
2443
2469
|
for (const file of parsed) filesMap.set(file.path, file);
|
|
2444
|
-
if (diff.stdout.trim() && !filesMap.has(
|
|
2445
|
-
filesMap.set(
|
|
2470
|
+
if (diff.stdout.trim() && !filesMap.has(path2)) {
|
|
2471
|
+
filesMap.set(path2, fileFromPatch(path2, diff.stdout, maxHunk));
|
|
2446
2472
|
}
|
|
2447
2473
|
} else {
|
|
2448
2474
|
for (const file of filesFromDiff(diff.stdout, "", "", maxHunk)) {
|
|
@@ -2450,7 +2476,7 @@ async function getPathDiff(worktreePath, repoPath, opts) {
|
|
|
2450
2476
|
}
|
|
2451
2477
|
}
|
|
2452
2478
|
if (filesMap.size === 0) {
|
|
2453
|
-
const maybe = await listUntrackedPaths(worktreePath,
|
|
2479
|
+
const maybe = await listUntrackedPaths(worktreePath, path2);
|
|
2454
2480
|
if (maybe.length > 0) {
|
|
2455
2481
|
const extra = includePatches ? await listUntrackedFiles(worktreePath, maxHunk, maybe) : untrackedStubs(maybe);
|
|
2456
2482
|
for (const file of extra) filesMap.set(file.path, file);
|
|
@@ -3473,8 +3499,8 @@ function splitForCompaction(messages, thresholds = {}) {
|
|
|
3473
3499
|
function formatToolPart(t, detail) {
|
|
3474
3500
|
if (detail === "summary") {
|
|
3475
3501
|
const label = t.description || t.detail || t.name;
|
|
3476
|
-
const
|
|
3477
|
-
return `- ${t.name}: ${label}${
|
|
3502
|
+
const path2 = t.filePath ? ` (${t.filePath})` : "";
|
|
3503
|
+
return `- ${t.name}: ${label}${path2}`;
|
|
3478
3504
|
}
|
|
3479
3505
|
const lines = [`#### Tool: ${t.name}`, `Status: ${t.status}`];
|
|
3480
3506
|
if (t.description) lines.push(`Description: ${t.description}`);
|
|
@@ -3812,7 +3838,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3812
3838
|
return readThread(thread.id) ?? thread;
|
|
3813
3839
|
}
|
|
3814
3840
|
async function listLinearIssues(agent, repoPath) {
|
|
3815
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
3841
|
+
const { getAdapter: getAdapter2 } = await import("./agents-EWPHOM6Y.js");
|
|
3816
3842
|
await requireAgent(agent, { requireLinear: true });
|
|
3817
3843
|
const adapter = getAdapter2(agent);
|
|
3818
3844
|
if (!adapter.listLinearIssues) {
|
|
@@ -4355,7 +4381,7 @@ async function adoptThread(input) {
|
|
|
4355
4381
|
messages: input.messages ?? []
|
|
4356
4382
|
});
|
|
4357
4383
|
writeThread(thread);
|
|
4358
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
4384
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-TYPJNUSM.js");
|
|
4359
4385
|
await ensureWorkspace2(repoPath);
|
|
4360
4386
|
return thread;
|
|
4361
4387
|
}
|
|
@@ -4606,10 +4632,10 @@ function storePath() {
|
|
|
4606
4632
|
return join8(appDataDir(), "slack-reply-to.json");
|
|
4607
4633
|
}
|
|
4608
4634
|
function readStore() {
|
|
4609
|
-
const
|
|
4610
|
-
if (!existsSync10(
|
|
4635
|
+
const path2 = storePath();
|
|
4636
|
+
if (!existsSync10(path2)) return {};
|
|
4611
4637
|
try {
|
|
4612
|
-
const parsed = isSecureFileEncrypted(
|
|
4638
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse(readFileSync8(path2, "utf8"));
|
|
4613
4639
|
return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
|
|
4614
4640
|
} catch {
|
|
4615
4641
|
return {};
|
|
@@ -4632,12 +4658,12 @@ function storePath2() {
|
|
|
4632
4658
|
}
|
|
4633
4659
|
function readStore2() {
|
|
4634
4660
|
try {
|
|
4635
|
-
const
|
|
4636
|
-
const wasEncrypted = isSecureFileEncrypted(
|
|
4637
|
-
const parsed = readSecureJson(
|
|
4661
|
+
const path2 = storePath2();
|
|
4662
|
+
const wasEncrypted = isSecureFileEncrypted(path2);
|
|
4663
|
+
const parsed = readSecureJson(path2);
|
|
4638
4664
|
const workspaces = Array.isArray(parsed?.workspaces) ? parsed.workspaces : [];
|
|
4639
4665
|
if (workspaces.length > 0 && !wasEncrypted && resolveVaultKey()) {
|
|
4640
|
-
writeSecureJson(
|
|
4666
|
+
writeSecureJson(path2, { workspaces });
|
|
4641
4667
|
}
|
|
4642
4668
|
return workspaces;
|
|
4643
4669
|
} catch {
|
|
@@ -4773,10 +4799,10 @@ function tsNewer(a, b) {
|
|
|
4773
4799
|
return Number(a) > Number(b);
|
|
4774
4800
|
}
|
|
4775
4801
|
function readStore3() {
|
|
4776
|
-
const
|
|
4777
|
-
if (!existsSync11(
|
|
4802
|
+
const path2 = storePath3();
|
|
4803
|
+
if (!existsSync11(path2)) return [];
|
|
4778
4804
|
try {
|
|
4779
|
-
const parsed = isSecureFileEncrypted(
|
|
4805
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse(readFileSync9(path2, "utf8"));
|
|
4780
4806
|
return Array.isArray(parsed?.watches) ? parsed.watches : [];
|
|
4781
4807
|
} catch {
|
|
4782
4808
|
return [];
|
|
@@ -5140,8 +5166,8 @@ function shouldAutoArchiveOnPrMerge(opts) {
|
|
|
5140
5166
|
// src/git/orphan-cleanup.ts
|
|
5141
5167
|
import { existsSync as existsSync12, readdirSync as readdirSync4, statSync as statSync5 } from "fs";
|
|
5142
5168
|
import { join as join11 } from "path";
|
|
5143
|
-
function isSideboardWorktreePath(
|
|
5144
|
-
return
|
|
5169
|
+
function isSideboardWorktreePath(path2) {
|
|
5170
|
+
return path2.includes("/.sideboard/worktrees/") || path2.includes("/sideboard/workspaces/");
|
|
5145
5171
|
}
|
|
5146
5172
|
async function findOrphanWorktrees(repoPaths) {
|
|
5147
5173
|
const threads = listThreads({ includeArchived: true });
|
|
@@ -5166,18 +5192,18 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
5166
5192
|
try {
|
|
5167
5193
|
const wts = await listWorktrees(repoPath);
|
|
5168
5194
|
for (const wt of wts) {
|
|
5169
|
-
const
|
|
5170
|
-
if (!isSideboardWorktreePath(
|
|
5171
|
-
if (known.has(
|
|
5172
|
-
if (seen.has(
|
|
5173
|
-
seen.add(
|
|
5195
|
+
const path2 = wt.path.replace(/\/$/, "");
|
|
5196
|
+
if (!isSideboardWorktreePath(path2)) continue;
|
|
5197
|
+
if (known.has(path2)) continue;
|
|
5198
|
+
if (seen.has(path2)) continue;
|
|
5199
|
+
seen.add(path2);
|
|
5174
5200
|
let mtimeMs = 0;
|
|
5175
5201
|
try {
|
|
5176
|
-
mtimeMs = statSync5(
|
|
5202
|
+
mtimeMs = statSync5(path2).mtimeMs;
|
|
5177
5203
|
} catch {
|
|
5178
5204
|
mtimeMs = 0;
|
|
5179
5205
|
}
|
|
5180
|
-
orphans.push({ path, repoPath, mtimeMs });
|
|
5206
|
+
orphans.push({ path: path2, repoPath, mtimeMs });
|
|
5181
5207
|
}
|
|
5182
5208
|
} catch {
|
|
5183
5209
|
}
|
|
@@ -5186,17 +5212,17 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
5186
5212
|
if (existsSync12(root)) {
|
|
5187
5213
|
for (const entry of readdirSync4(root, { withFileTypes: true })) {
|
|
5188
5214
|
if (!entry.isDirectory()) continue;
|
|
5189
|
-
const
|
|
5190
|
-
if (known.has(
|
|
5191
|
-
if (!existsSync12(join11(
|
|
5192
|
-
seen.add(
|
|
5215
|
+
const path2 = join11(root, entry.name).replace(/\/$/, "");
|
|
5216
|
+
if (known.has(path2) || seen.has(path2)) continue;
|
|
5217
|
+
if (!existsSync12(join11(path2, ".git"))) continue;
|
|
5218
|
+
seen.add(path2);
|
|
5193
5219
|
let mtimeMs = 0;
|
|
5194
5220
|
try {
|
|
5195
|
-
mtimeMs = statSync5(
|
|
5221
|
+
mtimeMs = statSync5(path2).mtimeMs;
|
|
5196
5222
|
} catch {
|
|
5197
5223
|
mtimeMs = Date.now();
|
|
5198
5224
|
}
|
|
5199
|
-
orphans.push({ path, repoPath, mtimeMs });
|
|
5225
|
+
orphans.push({ path: path2, repoPath, mtimeMs });
|
|
5200
5226
|
}
|
|
5201
5227
|
}
|
|
5202
5228
|
} catch {
|
|
@@ -5579,9 +5605,9 @@ function ensureReviewRequestFile(worktreePath) {
|
|
|
5579
5605
|
const localAbs = join13(worktreePath, REVIEW_REQUEST_PATH);
|
|
5580
5606
|
const localContent = readTextIfPresent(localAbs) ?? readTextIfPresent(join13(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
5581
5607
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
5582
|
-
const
|
|
5608
|
+
const path2 = existsSync14(localAbs) ? REVIEW_REQUEST_PATH : LEGACY_REVIEW_REQUEST_PATH;
|
|
5583
5609
|
return {
|
|
5584
|
-
path,
|
|
5610
|
+
path: path2,
|
|
5585
5611
|
name: REVIEW_REQUEST_NAME,
|
|
5586
5612
|
content: localContent,
|
|
5587
5613
|
source: "local"
|
|
@@ -5597,13 +5623,13 @@ function ensureReviewRequestFile(worktreePath) {
|
|
|
5597
5623
|
};
|
|
5598
5624
|
}
|
|
5599
5625
|
function buildReviewRequestAttachment(content, opts) {
|
|
5600
|
-
const
|
|
5601
|
-
const name = opts?.name ?? (
|
|
5626
|
+
const path2 = opts?.path ?? REVIEW_REQUEST_PATH;
|
|
5627
|
+
const name = opts?.name ?? (path2 === REPO_REVIEW_PATH ? REPO_REVIEW_NAME : REVIEW_REQUEST_NAME);
|
|
5602
5628
|
return {
|
|
5603
5629
|
id: randomUUID4(),
|
|
5604
5630
|
name,
|
|
5605
5631
|
kind: "file",
|
|
5606
|
-
path,
|
|
5632
|
+
path: path2,
|
|
5607
5633
|
content
|
|
5608
5634
|
};
|
|
5609
5635
|
}
|
|
@@ -5872,7 +5898,7 @@ var Orchestrator = class {
|
|
|
5872
5898
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
5873
5899
|
});
|
|
5874
5900
|
}
|
|
5875
|
-
const { autoCleanupOrphansEnabled: autoCleanupOrphansEnabled2 } = await import("./app-settings-
|
|
5901
|
+
const { autoCleanupOrphansEnabled: autoCleanupOrphansEnabled2 } = await import("./app-settings-6IOQYGBK.js");
|
|
5876
5902
|
if (autoCleanupOrphansEnabled2() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
5877
5903
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
5878
5904
|
}
|
|
@@ -6029,7 +6055,7 @@ var Orchestrator = class {
|
|
|
6029
6055
|
}
|
|
6030
6056
|
async finishCreateThread(threadId, prompt) {
|
|
6031
6057
|
await this.runSetupAfterCreate(threadId);
|
|
6032
|
-
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await import("./app-settings-
|
|
6058
|
+
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await import("./app-settings-6IOQYGBK.js");
|
|
6033
6059
|
if (autoRunAfterSetupEnabled2()) {
|
|
6034
6060
|
try {
|
|
6035
6061
|
await this.startDev(threadId);
|
|
@@ -6307,14 +6333,16 @@ var Orchestrator = class {
|
|
|
6307
6333
|
}
|
|
6308
6334
|
const isBrightsy = fresh.agent === "brightsy";
|
|
6309
6335
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
6336
|
+
const { autoRenameBranchEnabled: autoRenameBranchEnabled2, getGithubGitAuthMode: getGithubGitAuthMode2 } = await import("./app-settings-6IOQYGBK.js");
|
|
6337
|
+
const gitAuthMode = getGithubGitAuthMode2();
|
|
6310
6338
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
6311
6339
|
githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
|
|
6312
6340
|
() => null
|
|
6313
|
-
)
|
|
6341
|
+
),
|
|
6342
|
+
gitAuthMode
|
|
6314
6343
|
});
|
|
6315
6344
|
const artifactDirective = isBrightsy ? null : formatArtifactDirective();
|
|
6316
6345
|
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
6317
|
-
const { autoRenameBranchEnabled: autoRenameBranchEnabled2 } = await import("./app-settings-3TLA2EJ7.js");
|
|
6318
6346
|
const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled2() ? formatRenameBranchDirective(fresh, {
|
|
6319
6347
|
customPrompt: settings?.prompts?.renameBranch
|
|
6320
6348
|
}) : null;
|
|
@@ -7020,7 +7048,7 @@ var Orchestrator = class {
|
|
|
7020
7048
|
updateThread(thread.id, { title: meta.title });
|
|
7021
7049
|
}
|
|
7022
7050
|
}
|
|
7023
|
-
const { autoArchiveOnMergeEnabled: autoArchiveOnMergeEnabled2 } = await import("./app-settings-
|
|
7051
|
+
const { autoArchiveOnMergeEnabled: autoArchiveOnMergeEnabled2 } = await import("./app-settings-6IOQYGBK.js");
|
|
7024
7052
|
const latest = this.requireThread(thread.id);
|
|
7025
7053
|
if (!shouldAutoArchiveOnPrMerge({
|
|
7026
7054
|
previousPrState: prevState || null,
|
|
@@ -7151,8 +7179,9 @@ var Orchestrator = class {
|
|
|
7151
7179
|
return tab;
|
|
7152
7180
|
}
|
|
7153
7181
|
/**
|
|
7154
|
-
*
|
|
7155
|
-
*
|
|
7182
|
+
* Desktop git buttons + MCP `ask_git`.
|
|
7183
|
+
* When the worktree is clean, push / open the PR here (HTTPS via `gh` if SSH
|
|
7184
|
+
* is missing). When dirty, queue the worktree agent to commit first.
|
|
7156
7185
|
*/
|
|
7157
7186
|
async askGit(threadRef, action) {
|
|
7158
7187
|
if (!AGENT_GIT_ACTIONS.includes(action)) {
|
|
@@ -7170,6 +7199,10 @@ var Orchestrator = class {
|
|
|
7170
7199
|
"No pull request linked. Ask the worktree agent to open a draft PR first (ask_git create-draft)."
|
|
7171
7200
|
);
|
|
7172
7201
|
}
|
|
7202
|
+
if ((action === "commit-push" || action === "create-draft" || action === "create-web") && thread.worktreePath?.trim() && !await isDirty(thread.worktreePath)) {
|
|
7203
|
+
await this.pushAndMaybeOpenPr(thread, action);
|
|
7204
|
+
return this.requireThread(threadRef);
|
|
7205
|
+
}
|
|
7173
7206
|
let prBase;
|
|
7174
7207
|
if (action === "resolve-conflicts") {
|
|
7175
7208
|
try {
|
|
@@ -7180,6 +7213,34 @@ var Orchestrator = class {
|
|
|
7180
7213
|
}
|
|
7181
7214
|
return this.send(threadRef, agentGitPrompt(action, { prBase }));
|
|
7182
7215
|
}
|
|
7216
|
+
/** Push origin (gh HTTPS fallback) and create/update the PR when requested. */
|
|
7217
|
+
async pushAndMaybeOpenPr(thread, action) {
|
|
7218
|
+
const cwd = thread.worktreePath;
|
|
7219
|
+
const branch = await currentBranch(cwd);
|
|
7220
|
+
await pushBranch(cwd, branch);
|
|
7221
|
+
if (action === "commit-push") return;
|
|
7222
|
+
const base = await resolveDefaultBranch(thread.repoPath);
|
|
7223
|
+
const meta = await suggestPrMetadata(cwd, {
|
|
7224
|
+
base,
|
|
7225
|
+
fallbackTitle: thread.prTitle ?? thread.title
|
|
7226
|
+
});
|
|
7227
|
+
const url = await createOrUpdatePr(cwd, {
|
|
7228
|
+
title: meta.title,
|
|
7229
|
+
body: meta.body,
|
|
7230
|
+
base,
|
|
7231
|
+
head: branch,
|
|
7232
|
+
draft: action === "create-draft",
|
|
7233
|
+
web: action === "create-web"
|
|
7234
|
+
});
|
|
7235
|
+
if (!url) return;
|
|
7236
|
+
const patch = { prUrl: url, prTitle: meta.title };
|
|
7237
|
+
try {
|
|
7238
|
+
const fetched = await getPrMeta(cwd, url);
|
|
7239
|
+
if (fetched?.title) patch.prTitle = fetched.title;
|
|
7240
|
+
} catch {
|
|
7241
|
+
}
|
|
7242
|
+
updateThread(thread.id, patch);
|
|
7243
|
+
}
|
|
7183
7244
|
setThreadOptions(threadRef, patch) {
|
|
7184
7245
|
const thread = this.requireThread(threadRef);
|
|
7185
7246
|
const next = {};
|
|
@@ -7275,7 +7336,7 @@ var Orchestrator = class {
|
|
|
7275
7336
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
7276
7337
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
7277
7338
|
try {
|
|
7278
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
7339
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-TYPJNUSM.js");
|
|
7279
7340
|
await ensureWorkspace2(thread.repoPath);
|
|
7280
7341
|
} catch {
|
|
7281
7342
|
}
|
|
@@ -7297,7 +7358,7 @@ var Orchestrator = class {
|
|
|
7297
7358
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
7298
7359
|
} catch {
|
|
7299
7360
|
}
|
|
7300
|
-
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await import("./app-settings-
|
|
7361
|
+
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await import("./app-settings-6IOQYGBK.js");
|
|
7301
7362
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled2();
|
|
7302
7363
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
7303
7364
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -7318,7 +7379,7 @@ var Orchestrator = class {
|
|
|
7318
7379
|
return restored2;
|
|
7319
7380
|
}
|
|
7320
7381
|
if (!existsSync15(thread.worktreePath)) {
|
|
7321
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
7382
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-5VLLFI5W.js");
|
|
7322
7383
|
const { execa: execa6 } = await import("execa");
|
|
7323
7384
|
const slug = thread.worktreePath.split("/").pop();
|
|
7324
7385
|
const dest = thread.worktreePath;
|
|
@@ -7427,7 +7488,7 @@ async function startOrchestration(opts) {
|
|
|
7427
7488
|
sourceRef: "default",
|
|
7428
7489
|
...createOpts
|
|
7429
7490
|
}).catch(async () => {
|
|
7430
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
7491
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-5VLLFI5W.js");
|
|
7431
7492
|
const repo = await resolveRepoRoot2(repoPath);
|
|
7432
7493
|
const def = await resolveDefaultBranch2(repo);
|
|
7433
7494
|
return createThread({
|
|
@@ -7745,9 +7806,9 @@ function labelGithubUrl(url) {
|
|
|
7745
7806
|
return null;
|
|
7746
7807
|
}
|
|
7747
7808
|
if (!/(^|\.)github\.com$/i.test(parsed.hostname)) return null;
|
|
7748
|
-
const
|
|
7809
|
+
const path2 = parsed.pathname;
|
|
7749
7810
|
const hash = parsed.hash || "";
|
|
7750
|
-
const pr =
|
|
7811
|
+
const pr = path2.match(/\/([^/]+)\/([^/]+)\/pull\/(\d+)/i);
|
|
7751
7812
|
if (pr) {
|
|
7752
7813
|
const n = pr[3];
|
|
7753
7814
|
if (/#discussion_r\d+/i.test(hash) || /#pullrequestreview-\d+/i.test(hash)) {
|
|
@@ -7758,11 +7819,11 @@ function labelGithubUrl(url) {
|
|
|
7758
7819
|
}
|
|
7759
7820
|
return { kind: "pr", label: `PR #${n}`, url: raw };
|
|
7760
7821
|
}
|
|
7761
|
-
const issueComment =
|
|
7822
|
+
const issueComment = path2.match(/\/([^/]+)\/([^/]+)\/issues\/(\d+)/i);
|
|
7762
7823
|
if (issueComment && /#issuecomment-\d+/i.test(hash)) {
|
|
7763
7824
|
return { kind: "comment", label: `Issue #${issueComment[3]} comment`, url: raw };
|
|
7764
7825
|
}
|
|
7765
|
-
const blob =
|
|
7826
|
+
const blob = path2.match(/\/([^/]+)\/([^/]+)\/blob\/[^/]+\/(.+)$/i);
|
|
7766
7827
|
if (blob) {
|
|
7767
7828
|
const filePath = decodeURIComponent(blob[3]);
|
|
7768
7829
|
const fileName = filePath.split("/").pop() || filePath;
|
|
@@ -8179,7 +8240,7 @@ function withTimeout(promise, ms, label) {
|
|
|
8179
8240
|
async function startMcpServer() {
|
|
8180
8241
|
const orch = getOrchestrator();
|
|
8181
8242
|
try {
|
|
8182
|
-
const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-
|
|
8243
|
+
const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-6IOQYGBK.js");
|
|
8183
8244
|
orch.setMaxConcurrent(maxConcurrentAgents2());
|
|
8184
8245
|
} catch {
|
|
8185
8246
|
}
|
|
@@ -8324,10 +8385,10 @@ async function startMcpServer() {
|
|
|
8324
8385
|
const t = orch.getThread(thread_id.trim());
|
|
8325
8386
|
if (t?.worktreePath?.trim()) root = t.worktreePath;
|
|
8326
8387
|
}
|
|
8327
|
-
const
|
|
8388
|
+
const path2 = writePlanFile2(root, content);
|
|
8328
8389
|
const payload = {
|
|
8329
8390
|
ok: true,
|
|
8330
|
-
path,
|
|
8391
|
+
path: path2,
|
|
8331
8392
|
title: title?.trim() || "Plan",
|
|
8332
8393
|
message: "Plan saved to .context/attachments/plan.md and shown in Sideboard chat for approval."
|
|
8333
8394
|
};
|
|
@@ -8389,7 +8450,7 @@ async function startMcpServer() {
|
|
|
8389
8450
|
registerLinearTools(server);
|
|
8390
8451
|
if (sideboardMcpProfile() !== "worktree") {
|
|
8391
8452
|
const { getCaffeinateHold: getCaffeinateHold2, setCaffeinateHold: setCaffeinateHold2 } = await import("./caffeinate-hold-EAZNWJBE.js");
|
|
8392
|
-
const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await import("./app-settings-
|
|
8453
|
+
const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await import("./app-settings-6IOQYGBK.js");
|
|
8393
8454
|
const accountDefaults = resolveThreadDefaults2();
|
|
8394
8455
|
const accountDefaultsHint = `Account defaults: agent=${accountDefaults.agent}, model=${accountDefaults.model?.trim() || "Auto"}, effort=${accountDefaults.effort}`;
|
|
8395
8456
|
server.tool(
|
|
@@ -8751,7 +8812,7 @@ async function startMcpServer() {
|
|
|
8751
8812
|
);
|
|
8752
8813
|
server.tool(
|
|
8753
8814
|
"ask_git",
|
|
8754
|
-
"
|
|
8815
|
+
"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` if SSH is missing). When dirty, queues the worktree agent to commit; then wait_for_turn. Pass a worktree thread ref (not the orchestrator). Do not run git or gh from the orchestration cwd.",
|
|
8755
8816
|
{
|
|
8756
8817
|
ref: z3.string().describe("Worktree thread id/ref"),
|
|
8757
8818
|
action: z3.enum(AGENT_GIT_ACTIONS).describe(
|
|
@@ -9219,9 +9280,9 @@ var BrightsySideboardApi = class {
|
|
|
9219
9280
|
get endpoint() {
|
|
9220
9281
|
return (this.cfg.endpoint || "https://brightsy.ai").replace(/\/$/, "");
|
|
9221
9282
|
}
|
|
9222
|
-
async request(
|
|
9283
|
+
async request(path2, init = {}) {
|
|
9223
9284
|
await this.refreshIfNeeded();
|
|
9224
|
-
const url = `${this.endpoint}${
|
|
9285
|
+
const url = `${this.endpoint}${path2}`;
|
|
9225
9286
|
const headers = {
|
|
9226
9287
|
Authorization: `Bearer ${this.cfg.access_token}`,
|
|
9227
9288
|
Accept: "application/json"
|
|
@@ -10809,6 +10870,83 @@ var SlackRelayHub = class {
|
|
|
10809
10870
|
// src/slack/relay-server.ts
|
|
10810
10871
|
import { createServer as createServer3 } from "http";
|
|
10811
10872
|
import { WebSocketServer } from "ws";
|
|
10873
|
+
|
|
10874
|
+
// src/slack/relay-static.ts
|
|
10875
|
+
import { createReadStream } from "fs";
|
|
10876
|
+
import { stat } from "fs/promises";
|
|
10877
|
+
import path from "path";
|
|
10878
|
+
var TYPES = {
|
|
10879
|
+
".css": "text/css; charset=utf-8",
|
|
10880
|
+
".html": "text/html; charset=utf-8",
|
|
10881
|
+
".ico": "image/x-icon",
|
|
10882
|
+
".jpeg": "image/jpeg",
|
|
10883
|
+
".jpg": "image/jpeg",
|
|
10884
|
+
".js": "text/javascript; charset=utf-8",
|
|
10885
|
+
".json": "application/json; charset=utf-8",
|
|
10886
|
+
".png": "image/png",
|
|
10887
|
+
".svg": "image/svg+xml",
|
|
10888
|
+
".txt": "text/plain; charset=utf-8",
|
|
10889
|
+
".webp": "image/webp",
|
|
10890
|
+
".woff2": "font/woff2"
|
|
10891
|
+
};
|
|
10892
|
+
function requestHostname(req) {
|
|
10893
|
+
const raw = req.headers.host ?? "";
|
|
10894
|
+
return raw.split(":")[0]?.toLowerCase() ?? "";
|
|
10895
|
+
}
|
|
10896
|
+
function hostnameAllowed(host, allowed) {
|
|
10897
|
+
if (!allowed || allowed.length === 0) return true;
|
|
10898
|
+
return allowed.includes(host);
|
|
10899
|
+
}
|
|
10900
|
+
function resolveStaticPath(root, requestUrl) {
|
|
10901
|
+
let pathname;
|
|
10902
|
+
try {
|
|
10903
|
+
pathname = decodeURIComponent(new URL(requestUrl, "http://relay.local").pathname);
|
|
10904
|
+
} catch {
|
|
10905
|
+
return null;
|
|
10906
|
+
}
|
|
10907
|
+
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
10908
|
+
const rootResolved = path.resolve(root);
|
|
10909
|
+
const candidate = path.resolve(rootResolved, `.${pathname}`);
|
|
10910
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + path.sep)) {
|
|
10911
|
+
return null;
|
|
10912
|
+
}
|
|
10913
|
+
return candidate;
|
|
10914
|
+
}
|
|
10915
|
+
async function fileSize(file) {
|
|
10916
|
+
try {
|
|
10917
|
+
const st = await stat(file);
|
|
10918
|
+
return st.isFile() ? st.size : null;
|
|
10919
|
+
} catch {
|
|
10920
|
+
return null;
|
|
10921
|
+
}
|
|
10922
|
+
}
|
|
10923
|
+
function sendFile(req, res, file, size) {
|
|
10924
|
+
const ext = path.extname(file).toLowerCase();
|
|
10925
|
+
res.writeHead(200, {
|
|
10926
|
+
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
10927
|
+
"Content-Length": size,
|
|
10928
|
+
"Cache-Control": ext === ".html" ? "no-cache" : "public, max-age=3600"
|
|
10929
|
+
});
|
|
10930
|
+
if (req.method === "HEAD") {
|
|
10931
|
+
res.end();
|
|
10932
|
+
return true;
|
|
10933
|
+
}
|
|
10934
|
+
createReadStream(file).pipe(res);
|
|
10935
|
+
return true;
|
|
10936
|
+
}
|
|
10937
|
+
async function tryServeStatic(req, res, root) {
|
|
10938
|
+
if (req.method !== "GET" && req.method !== "HEAD") return false;
|
|
10939
|
+
const candidate = resolveStaticPath(root, req.url || "/");
|
|
10940
|
+
if (!candidate) return false;
|
|
10941
|
+
const direct = await fileSize(candidate);
|
|
10942
|
+
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
10943
|
+
const asIndex = path.join(candidate, "index.html");
|
|
10944
|
+
const indexSize = await fileSize(asIndex);
|
|
10945
|
+
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
10946
|
+
return false;
|
|
10947
|
+
}
|
|
10948
|
+
|
|
10949
|
+
// src/slack/relay-server.ts
|
|
10812
10950
|
function sendHtml(res, status, title, body) {
|
|
10813
10951
|
res.writeHead(status, { "Content-Type": "text/html; charset=utf-8" });
|
|
10814
10952
|
res.end(slackOAuthHtmlPage(title, body));
|
|
@@ -10907,7 +11045,26 @@ async function startSlackRelayServer(opts) {
|
|
|
10907
11045
|
const reqUrl = req.url || "/";
|
|
10908
11046
|
if (await handleCallback(reqUrl, res)) return;
|
|
10909
11047
|
if (handleResult(reqUrl, res)) return;
|
|
10910
|
-
if (req.url === "/health"
|
|
11048
|
+
if (req.url === "/health") {
|
|
11049
|
+
sendJson(res, 200, {
|
|
11050
|
+
ok: true,
|
|
11051
|
+
service: "sideboard-slack-relay",
|
|
11052
|
+
sessions: hub.listSessions().length,
|
|
11053
|
+
oauth: Boolean(clientSecret)
|
|
11054
|
+
});
|
|
11055
|
+
return;
|
|
11056
|
+
}
|
|
11057
|
+
const hostname = requestHostname(req);
|
|
11058
|
+
const canonical = (opts.canonicalSiteHost ?? "www.sideboard.cloud").toLowerCase();
|
|
11059
|
+
if (opts.redirectHosts?.includes(hostname) && hostname !== canonical) {
|
|
11060
|
+
res.writeHead(301, { Location: `https://${canonical}${reqUrl}` });
|
|
11061
|
+
res.end();
|
|
11062
|
+
return;
|
|
11063
|
+
}
|
|
11064
|
+
if (opts.staticRoot && hostnameAllowed(hostname, opts.staticHosts) && await tryServeStatic(req, res, opts.staticRoot)) {
|
|
11065
|
+
return;
|
|
11066
|
+
}
|
|
11067
|
+
if (req.url === "/") {
|
|
10911
11068
|
sendJson(res, 200, {
|
|
10912
11069
|
ok: true,
|
|
10913
11070
|
service: "sideboard-slack-relay",
|
|
@@ -11016,6 +11173,7 @@ export {
|
|
|
11016
11173
|
CONTEXT_MIN_MESSAGES,
|
|
11017
11174
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
11018
11175
|
FAMOUS_SOCCER_TEAMS,
|
|
11176
|
+
GITHUB_GIT_AUTH_MODES,
|
|
11019
11177
|
GLOBAL_WORKSPACE_ID,
|
|
11020
11178
|
HARNESS_ENV_KEYS,
|
|
11021
11179
|
LEGACY_ATTACHMENTS_DIR,
|
|
@@ -11065,10 +11223,12 @@ export {
|
|
|
11065
11223
|
allocateTeamSlug,
|
|
11066
11224
|
appDataDir,
|
|
11067
11225
|
appSettingsPath,
|
|
11226
|
+
appendIndexedGitConfig,
|
|
11068
11227
|
appendMessage,
|
|
11069
11228
|
applyAgentEvent,
|
|
11070
11229
|
applyAppEnvironment,
|
|
11071
11230
|
applyCompaction,
|
|
11231
|
+
applyGithubGitAuthEnv,
|
|
11072
11232
|
applyThreadIntoMain,
|
|
11073
11233
|
applyTurnUsage,
|
|
11074
11234
|
assertOrchestratorCapableAgent,
|
|
@@ -11183,6 +11343,7 @@ export {
|
|
|
11183
11343
|
formatBrightsyFetchError,
|
|
11184
11344
|
formatFetchError,
|
|
11185
11345
|
formatGhLandError,
|
|
11346
|
+
formatGitAuthModeDirective,
|
|
11186
11347
|
formatIpcInvokeError,
|
|
11187
11348
|
formatMessagesAsTranscript,
|
|
11188
11349
|
formatPlanQuestionAnswers,
|
|
@@ -11209,6 +11370,8 @@ export {
|
|
|
11209
11370
|
getDiff,
|
|
11210
11371
|
getDiffSummary,
|
|
11211
11372
|
getGitHubStatus,
|
|
11373
|
+
getGithubGitAuthMode,
|
|
11374
|
+
getGithubPat,
|
|
11212
11375
|
getIssueSource,
|
|
11213
11376
|
getLinearApiKey,
|
|
11214
11377
|
getLinearAuthToken,
|
|
@@ -11227,6 +11390,7 @@ export {
|
|
|
11227
11390
|
ghHeadRef,
|
|
11228
11391
|
ghRepoSelectArgs,
|
|
11229
11392
|
git,
|
|
11393
|
+
githubAgentGitEnv,
|
|
11230
11394
|
globalAgentCwd,
|
|
11231
11395
|
handleSlackInbound,
|
|
11232
11396
|
harnessEnvKey,
|
|
@@ -11449,6 +11613,7 @@ export {
|
|
|
11449
11613
|
startSlackOAuth,
|
|
11450
11614
|
startSlackRelayServer,
|
|
11451
11615
|
stripBrightsyNdjsonNoise,
|
|
11616
|
+
stripNestedElectronEnv,
|
|
11452
11617
|
submitPrStack,
|
|
11453
11618
|
suggestSlug,
|
|
11454
11619
|
summarizeConversation,
|