@sideboard-ai/core 0.1.89 → 0.1.92
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/cursor-runner.cjs +129 -14
- package/dist/agents/cursor-runner.js +4 -1
- package/dist/{agents-LMUFTGKF.js → agents-JXQ5QHDU.js} +4 -4
- package/dist/{agents-ODBP7J6E.js → agents-TUV4NH7S.js} +5 -5
- package/dist/{chunk-RJLBSYUO.js → chunk-35LKGGOC.js} +45 -77
- package/dist/{chunk-WANQFU3S.js → chunk-6XBXVXX2.js} +2 -2
- package/dist/{chunk-7D27DD2X.js → chunk-CIRXAYWS.js} +260 -61
- package/dist/{chunk-B2KIO2SD.js → chunk-CLGO7TLO.js} +2 -2
- package/dist/{chunk-JE75QW2I.js → chunk-GJ2HJQIU.js} +236 -96
- package/dist/{chunk-CBJSPTBG.js → chunk-GXSYI7FH.js} +206 -5
- package/dist/{chunk-UHTNJKZX.js → chunk-NR6APJLD.js} +2 -2
- package/dist/{chunk-6EZRSCIT.js → chunk-QKYO6BHB.js} +2 -2
- package/dist/{chunk-ZXYWWSHZ.js → chunk-R7BQBSDT.js} +254 -61
- package/dist/{chunk-OB6IRIFV.js → chunk-XH2GS2LO.js} +2 -2
- package/dist/{chunk-VZ2L4AEJ.js → chunk-XUWDLRAE.js} +2 -2
- package/dist/{coordinator-prompt-UK5LYFN5.js → coordinator-prompt-AKEY4WSO.js} +2 -2
- package/dist/{coordinator-prompt-CI5SHONJ.js → coordinator-prompt-OQOOD5ET.js} +2 -2
- package/dist/{global-workspace-2YZ2V4I5.js → global-workspace-3GNPQCLE.js} +3 -3
- package/dist/{global-workspace-JQQLPJM5.js → global-workspace-M3OMVDDH.js} +3 -3
- package/dist/index.cjs +941 -455
- package/dist/index.d.cts +77 -19
- package/dist/index.d.ts +77 -19
- package/dist/index.js +166 -42
- package/dist/mcp/run-stdio.cjs +815 -428
- package/dist/mcp/run-stdio.js +77 -40
- package/dist/{workspaces-YWCC3WV4.js → workspaces-ERZC7ULY.js} +4 -4
- package/dist/{workspaces-FDO5L4NI.js → workspaces-J4WG6UFR.js} +4 -4
- package/dist/{worktree-7YNSJ224.js → worktree-DA4BOV7G.js} +7 -1
- package/dist/{worktree-4555QBQ7.js → worktree-EO5QAGJU.js} +7 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3068,42 +3068,124 @@ var init_gh_errors = __esm({
|
|
|
3068
3068
|
}
|
|
3069
3069
|
});
|
|
3070
3070
|
|
|
3071
|
+
// src/git/github-agent-auth.ts
|
|
3072
|
+
function githubAgentAuthDir() {
|
|
3073
|
+
const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
|
|
3074
|
+
if (override) return override;
|
|
3075
|
+
return (0, import_node_path10.join)((0, import_node_os4.homedir)(), ".sideboard-git-auth");
|
|
3076
|
+
}
|
|
3077
|
+
function githubCredentialStorePath() {
|
|
3078
|
+
return (0, import_node_path10.join)(githubAgentAuthDir(), "git-credentials");
|
|
3079
|
+
}
|
|
3080
|
+
function githubGhConfigDir() {
|
|
3081
|
+
return (0, import_node_path10.join)(githubAgentAuthDir(), "gh");
|
|
3082
|
+
}
|
|
3083
|
+
function writePrivateFile2(file, body) {
|
|
3084
|
+
(0, import_node_fs10.mkdirSync)((0, import_node_path10.dirname)(file), { recursive: true, mode: 448 });
|
|
3085
|
+
try {
|
|
3086
|
+
(0, import_node_fs10.chmodSync)((0, import_node_path10.dirname)(file), 448);
|
|
3087
|
+
} catch {
|
|
3088
|
+
}
|
|
3089
|
+
(0, import_node_fs10.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
|
|
3090
|
+
try {
|
|
3091
|
+
(0, import_node_fs10.chmodSync)(file, 384);
|
|
3092
|
+
} catch {
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
function gitCredentialStoreContents(token) {
|
|
3096
|
+
return `https://x-access-token:${encodeURIComponent(token)}@github.com
|
|
3097
|
+
`;
|
|
3098
|
+
}
|
|
3099
|
+
function ghHostsYml(token, user = "x-access-token") {
|
|
3100
|
+
const u = user.replace(/[^A-Za-z0-9._-]/g, "") || "x-access-token";
|
|
3101
|
+
return [
|
|
3102
|
+
"github.com:",
|
|
3103
|
+
" git_protocol: https",
|
|
3104
|
+
` user: ${u}`,
|
|
3105
|
+
` oauth_token: ${token}`,
|
|
3106
|
+
" users:",
|
|
3107
|
+
` ${u}:`,
|
|
3108
|
+
` oauth_token: ${token}`,
|
|
3109
|
+
""
|
|
3110
|
+
].join("\n");
|
|
3111
|
+
}
|
|
3112
|
+
function materializeGithubAgentAuth(token, user) {
|
|
3113
|
+
const trimmed = token.trim();
|
|
3114
|
+
if (!trimmed) return;
|
|
3115
|
+
const root = githubAgentAuthDir();
|
|
3116
|
+
(0, import_node_fs10.mkdirSync)(root, { recursive: true, mode: 448 });
|
|
3117
|
+
try {
|
|
3118
|
+
(0, import_node_fs10.chmodSync)(root, 448);
|
|
3119
|
+
} catch {
|
|
3120
|
+
}
|
|
3121
|
+
writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
|
|
3122
|
+
const ghDir = githubGhConfigDir();
|
|
3123
|
+
(0, import_node_fs10.mkdirSync)(ghDir, { recursive: true, mode: 448 });
|
|
3124
|
+
writePrivateFile2((0, import_node_path10.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
|
|
3125
|
+
writePrivateFile2((0, import_node_path10.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
|
|
3126
|
+
}
|
|
3127
|
+
function githubAgentAuthReady() {
|
|
3128
|
+
return (0, import_node_fs10.existsSync)(githubCredentialStorePath()) && (0, import_node_fs10.existsSync)((0, import_node_path10.join)(githubGhConfigDir(), "hosts.yml"));
|
|
3129
|
+
}
|
|
3130
|
+
function githubCredentialHelperGitConfig() {
|
|
3131
|
+
const file = githubCredentialStorePath();
|
|
3132
|
+
return [
|
|
3133
|
+
{ key: "credential.helper", value: "" },
|
|
3134
|
+
{ key: "credential.helper", value: `store --file=${file}` }
|
|
3135
|
+
];
|
|
3136
|
+
}
|
|
3137
|
+
function githubGhConfigEnv() {
|
|
3138
|
+
return {
|
|
3139
|
+
GH_CONFIG_DIR: githubGhConfigDir(),
|
|
3140
|
+
GH_PROMPT_DISABLED: "1"
|
|
3141
|
+
};
|
|
3142
|
+
}
|
|
3143
|
+
var import_node_fs10, import_node_os4, import_node_path10;
|
|
3144
|
+
var init_github_agent_auth = __esm({
|
|
3145
|
+
"src/git/github-agent-auth.ts"() {
|
|
3146
|
+
"use strict";
|
|
3147
|
+
import_node_fs10 = require("fs");
|
|
3148
|
+
import_node_os4 = require("os");
|
|
3149
|
+
import_node_path10 = require("path");
|
|
3150
|
+
}
|
|
3151
|
+
});
|
|
3152
|
+
|
|
3071
3153
|
// src/agents/path.ts
|
|
3072
3154
|
function prependPathDir(env, dir) {
|
|
3073
|
-
if (!dir || !(0,
|
|
3155
|
+
if (!dir || !(0, import_node_fs11.existsSync)(dir)) return;
|
|
3074
3156
|
const current = env.PATH ?? "";
|
|
3075
|
-
const parts = current.split(
|
|
3157
|
+
const parts = current.split(import_node_path11.delimiter).filter(Boolean);
|
|
3076
3158
|
if (parts.includes(dir)) {
|
|
3077
3159
|
env.PATH = current;
|
|
3078
3160
|
return;
|
|
3079
3161
|
}
|
|
3080
|
-
env.PATH = [dir, ...parts].join(
|
|
3162
|
+
env.PATH = [dir, ...parts].join(import_node_path11.delimiter);
|
|
3081
3163
|
}
|
|
3082
|
-
function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0,
|
|
3083
|
-
return (0,
|
|
3164
|
+
function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os5.homedir)()) {
|
|
3165
|
+
return (0, import_node_path11.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
|
|
3084
3166
|
}
|
|
3085
3167
|
function isConductorBundledCli(filePath) {
|
|
3086
3168
|
const p = (filePath ?? "").replace(/\\/g, "/");
|
|
3087
3169
|
return p.includes("/com.conductor.app/bin/") || p.endsWith("/com.conductor.app/bin");
|
|
3088
3170
|
}
|
|
3089
3171
|
function ensureAgentPath(env = process.env) {
|
|
3090
|
-
const home = env.HOME || env.USERPROFILE || (0,
|
|
3172
|
+
const home = env.HOME || env.USERPROFILE || (0, import_node_os5.homedir)();
|
|
3091
3173
|
const current = env.PATH ?? "";
|
|
3092
|
-
const parts = current.split(
|
|
3174
|
+
const parts = current.split(import_node_path11.delimiter).filter(Boolean);
|
|
3093
3175
|
const seen = new Set(parts);
|
|
3094
3176
|
const extras = [
|
|
3095
|
-
...EXTRA_BIN_DIRS.map((rel) => (0,
|
|
3177
|
+
...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path11.join)(home, rel)),
|
|
3096
3178
|
"/opt/homebrew/bin",
|
|
3097
3179
|
"/usr/local/bin",
|
|
3098
3180
|
// Keep after Homebrew/npm so a user-installed CLI still wins.
|
|
3099
3181
|
conductorBundledBinDir(home)
|
|
3100
3182
|
];
|
|
3101
3183
|
for (const dir of extras.reverse()) {
|
|
3102
|
-
if (!dir || seen.has(dir) || !(0,
|
|
3184
|
+
if (!dir || seen.has(dir) || !(0, import_node_fs11.existsSync)(dir)) continue;
|
|
3103
3185
|
parts.unshift(dir);
|
|
3104
3186
|
seen.add(dir);
|
|
3105
3187
|
}
|
|
3106
|
-
const next = parts.join(
|
|
3188
|
+
const next = parts.join(import_node_path11.delimiter);
|
|
3107
3189
|
env.PATH = next;
|
|
3108
3190
|
return next;
|
|
3109
3191
|
}
|
|
@@ -3117,7 +3199,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
|
|
|
3117
3199
|
stdio: ["ignore", "pipe", "ignore"]
|
|
3118
3200
|
}).trim().split(/\r?\n/).find(Boolean);
|
|
3119
3201
|
if (prefix) {
|
|
3120
|
-
const binDir = process.platform === "win32" ? prefix : (0,
|
|
3202
|
+
const binDir = process.platform === "win32" ? prefix : (0, import_node_path11.join)(prefix, "bin");
|
|
3121
3203
|
prependPathDir(env, binDir);
|
|
3122
3204
|
}
|
|
3123
3205
|
} catch {
|
|
@@ -3145,14 +3227,14 @@ function withExportedPath(command, pathValue) {
|
|
|
3145
3227
|
if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
|
|
3146
3228
|
return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
|
|
3147
3229
|
}
|
|
3148
|
-
var
|
|
3230
|
+
var import_node_fs11, import_node_child_process3, import_node_os5, import_node_path11, EXTRA_BIN_DIRS;
|
|
3149
3231
|
var init_path = __esm({
|
|
3150
3232
|
"src/agents/path.ts"() {
|
|
3151
3233
|
"use strict";
|
|
3152
|
-
|
|
3234
|
+
import_node_fs11 = require("fs");
|
|
3153
3235
|
import_node_child_process3 = require("child_process");
|
|
3154
|
-
|
|
3155
|
-
|
|
3236
|
+
import_node_os5 = require("os");
|
|
3237
|
+
import_node_path11 = require("path");
|
|
3156
3238
|
EXTRA_BIN_DIRS = [
|
|
3157
3239
|
".local/bin",
|
|
3158
3240
|
".cargo/bin",
|
|
@@ -3277,42 +3359,46 @@ function appendIndexedGitConfig(existing, entries) {
|
|
|
3277
3359
|
return out;
|
|
3278
3360
|
}
|
|
3279
3361
|
function githubAgentGitEnv(existing) {
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
function githubHttpsBearerEnv(existing, token) {
|
|
3283
|
-
const rewrite = githubAgentGitEnv(existing);
|
|
3284
|
-
const header = appendIndexedGitConfig(
|
|
3285
|
-
{ ...existing, ...rewrite },
|
|
3286
|
-
[
|
|
3287
|
-
{
|
|
3288
|
-
key: "http.https://github.com/.extraHeader",
|
|
3289
|
-
value: `AUTHORIZATION: bearer ${token}`
|
|
3290
|
-
}
|
|
3291
|
-
]
|
|
3292
|
-
);
|
|
3293
|
-
return { ...rewrite, ...header };
|
|
3362
|
+
const helpers = githubAgentAuthReady() ? githubCredentialHelperGitConfig() : [{ key: "credential.helper", value: "" }];
|
|
3363
|
+
return appendIndexedGitConfig(existing, [...HTTPS_REWRITE, ...helpers]);
|
|
3294
3364
|
}
|
|
3295
3365
|
function applyGithubGitAuthEnv(existing, opts) {
|
|
3296
3366
|
const out = { ...nonInteractiveGitProcessEnv() };
|
|
3367
|
+
const token = opts.token?.trim() || existing?.GH_TOKEN?.trim() || "" || "";
|
|
3368
|
+
if (token) materializeGithubAgentAuth(token);
|
|
3369
|
+
Object.assign(out, githubGhConfigEnv());
|
|
3297
3370
|
if (opts.mode === "ssh") return out;
|
|
3298
|
-
|
|
3299
|
-
const provided = existingToken ? "" : opts.token?.trim() || "";
|
|
3300
|
-
const token = existingToken || provided;
|
|
3301
|
-
Object.assign(
|
|
3302
|
-
out,
|
|
3303
|
-
token ? githubHttpsBearerEnv(existing, token) : githubAgentGitEnv(existing)
|
|
3304
|
-
);
|
|
3305
|
-
if (provided) out.GH_TOKEN = provided;
|
|
3371
|
+
Object.assign(out, githubAgentGitEnv(existing));
|
|
3306
3372
|
return out;
|
|
3307
3373
|
}
|
|
3374
|
+
function scrubGithubTokensFromChildEnv(env) {
|
|
3375
|
+
for (const key of GITHUB_CHILD_TOKEN_KEYS) {
|
|
3376
|
+
delete env[key];
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3379
|
+
function mergeAgentGitAuthEnv(env, gitEnv) {
|
|
3380
|
+
Object.assign(env, gitEnv);
|
|
3381
|
+
scrubGithubTokensFromChildEnv(env);
|
|
3382
|
+
}
|
|
3308
3383
|
async function resolveGithubAgentToken(mode, cwd) {
|
|
3309
|
-
if (mode ===
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3384
|
+
if (tokenMemo && tokenMemo.mode === mode && Date.now() - tokenMemo.at < TOKEN_TTL_MS) {
|
|
3385
|
+
return tokenMemo.value;
|
|
3386
|
+
}
|
|
3387
|
+
let value = null;
|
|
3388
|
+
if (mode === "token") {
|
|
3389
|
+
value = getGithubPat();
|
|
3390
|
+
} else {
|
|
3391
|
+
try {
|
|
3392
|
+
value = await resolveGhAuthToken(cwd);
|
|
3393
|
+
} catch {
|
|
3394
|
+
value = null;
|
|
3395
|
+
}
|
|
3315
3396
|
}
|
|
3397
|
+
tokenMemo = { mode, value, at: Date.now() };
|
|
3398
|
+
return value;
|
|
3399
|
+
}
|
|
3400
|
+
function resetGithubAgentTokenMemo() {
|
|
3401
|
+
tokenMemo = null;
|
|
3316
3402
|
}
|
|
3317
3403
|
async function resolveAgentGitAuthEnv(existing, opts) {
|
|
3318
3404
|
let mode = "auto";
|
|
@@ -3334,7 +3420,40 @@ async function resolveAgentGitAuthEnv(existing, opts) {
|
|
|
3334
3420
|
}
|
|
3335
3421
|
return applyGithubGitAuthEnv(existing, { mode, token });
|
|
3336
3422
|
}
|
|
3337
|
-
function
|
|
3423
|
+
async function warmGithubAgentAuth(opts) {
|
|
3424
|
+
if (!opts?.force && githubAgentAuthReady()) return;
|
|
3425
|
+
await resolveAgentGitAuthEnv(void 0, opts);
|
|
3426
|
+
}
|
|
3427
|
+
function normalizeWritableRoot(raw) {
|
|
3428
|
+
const trimmed = raw.trim().replace(/\/+$/, "");
|
|
3429
|
+
return trimmed && (0, import_node_path12.isAbsolute)(trimmed) ? trimmed : null;
|
|
3430
|
+
}
|
|
3431
|
+
async function resolveCodexGitWritableRoots(cwd) {
|
|
3432
|
+
const roots = /* @__PURE__ */ new Set();
|
|
3433
|
+
const authDir = normalizeWritableRoot(githubAgentAuthDir());
|
|
3434
|
+
if (authDir) roots.add(authDir);
|
|
3435
|
+
try {
|
|
3436
|
+
const [gitDir, commonDir] = await Promise.all([
|
|
3437
|
+
git(["rev-parse", "--absolute-git-dir"], cwd, { reject: false, timeoutMs: 5e3 }),
|
|
3438
|
+
git(["rev-parse", "--path-format=absolute", "--git-common-dir"], cwd, {
|
|
3439
|
+
reject: false,
|
|
3440
|
+
timeoutMs: 5e3
|
|
3441
|
+
})
|
|
3442
|
+
]);
|
|
3443
|
+
const gitDirPath = gitDir.exitCode === 0 ? normalizeWritableRoot(gitDir.stdout) : null;
|
|
3444
|
+
const commonPath = commonDir.exitCode === 0 ? normalizeWritableRoot(commonDir.stdout) : null;
|
|
3445
|
+
if (gitDirPath) roots.add(gitDirPath);
|
|
3446
|
+
if (commonPath) roots.add(commonPath);
|
|
3447
|
+
} catch {
|
|
3448
|
+
}
|
|
3449
|
+
return [...roots];
|
|
3450
|
+
}
|
|
3451
|
+
function codexSandboxWritableRootsArgs(roots) {
|
|
3452
|
+
const abs = [...new Set(roots.map(normalizeWritableRoot).filter(Boolean))];
|
|
3453
|
+
if (abs.length === 0) return [];
|
|
3454
|
+
return ["-c", `sandbox_workspace_write.writable_roots=${JSON.stringify(abs)}`];
|
|
3455
|
+
}
|
|
3456
|
+
function codexUnattendedGitConfigArgs(sandbox, opts) {
|
|
3338
3457
|
const args = [
|
|
3339
3458
|
"-c",
|
|
3340
3459
|
'shell_environment_policy.inherit="all"',
|
|
@@ -3343,54 +3462,65 @@ function codexUnattendedGitConfigArgs(sandbox) {
|
|
|
3343
3462
|
];
|
|
3344
3463
|
if (sandbox === "workspace-write") {
|
|
3345
3464
|
args.push("-c", "sandbox_workspace_write.network_access=true");
|
|
3465
|
+
args.push(...codexSandboxWritableRootsArgs(opts?.writableRoots ?? []));
|
|
3346
3466
|
}
|
|
3347
3467
|
return args;
|
|
3348
3468
|
}
|
|
3349
3469
|
function formatGitAuthModeDirective(mode) {
|
|
3470
|
+
const shared = [
|
|
3471
|
+
"- `git` and `gh` already authenticate in this process. Do not look for tokens in the environment, paste credentials into commands, or switch remotes to SSH.",
|
|
3472
|
+
"- Do not set GitHub token environment variables, pass `--with-token`, or run `gh auth login` from this turn.",
|
|
3473
|
+
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below.",
|
|
3474
|
+
"- If git/gh fail with auth errors, tell the user to run `gh auth login` on this Mac (or set a PAT in Account \u2192 GitHub). Do not wait for a Keychain dialog."
|
|
3475
|
+
];
|
|
3350
3476
|
switch (mode) {
|
|
3351
3477
|
case "gh":
|
|
3352
3478
|
return [
|
|
3353
3479
|
"Git authentication (Account \u2192 GitHub mode: gh CLI):",
|
|
3354
3480
|
"- This process rewrites `git@github.com:` and `ssh://git@github.com/` to HTTPS.",
|
|
3355
|
-
|
|
3356
|
-
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below."
|
|
3481
|
+
...shared
|
|
3357
3482
|
].join("\n");
|
|
3358
3483
|
case "ssh":
|
|
3359
3484
|
return [
|
|
3360
3485
|
"Git authentication (Account \u2192 GitHub mode: SSH):",
|
|
3361
3486
|
"- Keep SSH remotes (`git@github.com:\u2026`). Do not rewrite them to HTTPS.",
|
|
3362
3487
|
"- SSH is batch-mode: it will not prompt for a Keychain password. If push fails with `Permission denied (publickey)`, tell the user to unlock ssh-agent or switch Account \u2192 GitHub to Auto / gh CLI \u2014 do not rewrite remotes yourself.",
|
|
3363
|
-
"-
|
|
3488
|
+
"- `gh` already authenticates for PRs/API (no token in the environment). Do not set GitHub token environment variables or run `gh auth login` from this turn.",
|
|
3489
|
+
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below."
|
|
3364
3490
|
].join("\n");
|
|
3365
3491
|
case "token":
|
|
3366
3492
|
return [
|
|
3367
3493
|
"Git authentication (Account \u2192 GitHub mode: personal access token):",
|
|
3368
3494
|
"- This process rewrites GitHub SSH remotes to HTTPS.",
|
|
3369
|
-
|
|
3370
|
-
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below."
|
|
3495
|
+
...shared
|
|
3371
3496
|
].join("\n");
|
|
3372
3497
|
case "auto":
|
|
3373
3498
|
default:
|
|
3374
3499
|
return [
|
|
3375
3500
|
"Git authentication (Account \u2192 GitHub mode: auto):",
|
|
3376
|
-
"- This process rewrites GitHub SSH remotes to HTTPS
|
|
3377
|
-
|
|
3378
|
-
"- If HTTPS auth fails, tell the user to run `gh auth login` on this Mac or set Account \u2192 GitHub to a PAT \u2014 do not wait for a Keychain dialog."
|
|
3501
|
+
"- This process rewrites GitHub SSH remotes to HTTPS so git/ssh never prompt the macOS Keychain (required for unattended orchestrator turns).",
|
|
3502
|
+
...shared
|
|
3379
3503
|
].join("\n");
|
|
3380
3504
|
}
|
|
3381
3505
|
}
|
|
3382
|
-
var HTTPS_REWRITE;
|
|
3506
|
+
var import_node_path12, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
|
|
3383
3507
|
var init_git_auth_mode = __esm({
|
|
3384
3508
|
"src/git/git-auth-mode.ts"() {
|
|
3385
3509
|
"use strict";
|
|
3510
|
+
import_node_path12 = require("path");
|
|
3386
3511
|
init_app_settings();
|
|
3512
|
+
init_github_agent_auth();
|
|
3387
3513
|
init_run();
|
|
3388
3514
|
HTTPS_REWRITE = [
|
|
3389
3515
|
{ key: "url.https://github.com/.insteadOf", value: "git@github.com:" },
|
|
3390
|
-
{ key: "url.https://github.com/.insteadOf", value: "ssh://git@github.com/" }
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3516
|
+
{ key: "url.https://github.com/.insteadOf", value: "ssh://git@github.com/" }
|
|
3517
|
+
];
|
|
3518
|
+
TOKEN_TTL_MS = 12 * 60 * 60 * 1e3;
|
|
3519
|
+
tokenMemo = null;
|
|
3520
|
+
GITHUB_CHILD_TOKEN_KEYS = [
|
|
3521
|
+
"GH_TOKEN",
|
|
3522
|
+
"GITHUB_TOKEN",
|
|
3523
|
+
"GH_ENTERPRISE_TOKEN"
|
|
3394
3524
|
];
|
|
3395
3525
|
}
|
|
3396
3526
|
});
|
|
@@ -3751,10 +3881,12 @@ __export(worktree_exports, {
|
|
|
3751
3881
|
getPr: () => getPr,
|
|
3752
3882
|
getPrChecks: () => getPrChecks,
|
|
3753
3883
|
getPrDetails: () => getPrDetails,
|
|
3884
|
+
getPrForHeadBranch: () => getPrForHeadBranch,
|
|
3754
3885
|
getPrMeta: () => getPrMeta,
|
|
3755
3886
|
ghHeadRef: () => ghHeadRef,
|
|
3756
3887
|
ghRepoSelectArgs: () => ghRepoSelectArgs,
|
|
3757
3888
|
githubAgentGitEnv: () => githubAgentGitEnv,
|
|
3889
|
+
isDefaultishSourceRef: () => isDefaultishSourceRef,
|
|
3758
3890
|
isDirty: () => isDirty,
|
|
3759
3891
|
isPlaceholderBranch: () => isPlaceholderBranch,
|
|
3760
3892
|
isSideboardScratchPath: () => isSideboardScratchPath,
|
|
@@ -3772,6 +3904,7 @@ __export(worktree_exports, {
|
|
|
3772
3904
|
resolveDiffBaseRef: () => resolveDiffBaseRef,
|
|
3773
3905
|
resolveGithubRepoSlug: () => resolveGithubRepoSlug,
|
|
3774
3906
|
resolvePrSelector: () => resolvePrSelector,
|
|
3907
|
+
resolvePrSelectors: () => resolvePrSelectors,
|
|
3775
3908
|
resolveRepoRoot: () => resolveRepoRoot,
|
|
3776
3909
|
resolveWorktreeStartPoint: () => resolveWorktreeStartPoint,
|
|
3777
3910
|
slugify: () => slugify,
|
|
@@ -3880,7 +4013,7 @@ async function originGhRepoEnv(cwd, opts) {
|
|
|
3880
4013
|
await ensureGhPreferOrigin(cwd);
|
|
3881
4014
|
const slug = await resolveGithubRepoSlug(cwd);
|
|
3882
4015
|
const mode = opts?.mode ?? getGithubGitAuthMode();
|
|
3883
|
-
const token =
|
|
4016
|
+
const token = await resolveGithubAgentToken(mode, cwd);
|
|
3884
4017
|
return {
|
|
3885
4018
|
...applyGithubGitAuthEnv(opts?.env, { mode, token }),
|
|
3886
4019
|
...slug ? { GH_REPO: slug } : {}
|
|
@@ -4020,13 +4153,78 @@ async function getPr(repoPath, number) {
|
|
|
4020
4153
|
if (exitCode !== 0 || !stdout.trim()) return null;
|
|
4021
4154
|
return JSON.parse(stdout);
|
|
4022
4155
|
}
|
|
4023
|
-
function
|
|
4024
|
-
|
|
4156
|
+
function normalizeGitBranchName(ref) {
|
|
4157
|
+
return ref.trim().replace(/^refs\/heads\//, "").replace(/^origin\//, "");
|
|
4158
|
+
}
|
|
4159
|
+
function isDefaultishSourceRef(ref) {
|
|
4160
|
+
const n = normalizeGitBranchName(ref ?? "").toLowerCase();
|
|
4161
|
+
return !n || n === "head" || n === "default" || n === "main" || n === "master" || n === "develop" || n === "trunk";
|
|
4162
|
+
}
|
|
4163
|
+
function resolvePrSelectors(thread) {
|
|
4164
|
+
const out = [];
|
|
4165
|
+
const push = (value) => {
|
|
4166
|
+
const v = value?.trim();
|
|
4167
|
+
if (!v || out.includes(v)) return;
|
|
4168
|
+
out.push(v);
|
|
4169
|
+
};
|
|
4170
|
+
push(thread.prUrl);
|
|
4025
4171
|
if (thread.sourceType === "pr" && thread.sourceRef?.trim()) {
|
|
4026
|
-
|
|
4172
|
+
push(thread.sourceRef.replace(/^#/, "").trim());
|
|
4173
|
+
}
|
|
4174
|
+
push(thread.branchName);
|
|
4175
|
+
if (thread.sourceType === "branch") {
|
|
4176
|
+
const source = normalizeGitBranchName(thread.sourceRef ?? "");
|
|
4177
|
+
if (source && !isDefaultishSourceRef(source) && source !== thread.branchName?.trim()) {
|
|
4178
|
+
push(source);
|
|
4179
|
+
}
|
|
4180
|
+
}
|
|
4181
|
+
return out;
|
|
4182
|
+
}
|
|
4183
|
+
function resolvePrSelector(thread) {
|
|
4184
|
+
return resolvePrSelectors(thread)[0] ?? null;
|
|
4185
|
+
}
|
|
4186
|
+
async function getPrForHeadBranch(repoPath, branch) {
|
|
4187
|
+
const head = normalizeGitBranchName(branch);
|
|
4188
|
+
if (!head || isDefaultishSourceRef(head)) return null;
|
|
4189
|
+
const slug = await resolveGithubRepoSlug(repoPath);
|
|
4190
|
+
const viewArgs = [
|
|
4191
|
+
"pr",
|
|
4192
|
+
"view",
|
|
4193
|
+
head,
|
|
4194
|
+
"--json",
|
|
4195
|
+
"number,title,headRefName,url,isCrossRepository"
|
|
4196
|
+
];
|
|
4197
|
+
if (slug) viewArgs.push("--repo", slug);
|
|
4198
|
+
const viewed = await gh(viewArgs, repoPath, { reject: false });
|
|
4199
|
+
if (viewed.exitCode === 0 && viewed.stdout.trim()) {
|
|
4200
|
+
try {
|
|
4201
|
+
return JSON.parse(viewed.stdout);
|
|
4202
|
+
} catch {
|
|
4203
|
+
return null;
|
|
4204
|
+
}
|
|
4205
|
+
}
|
|
4206
|
+
const listHead = slug ? ghHeadRef(slug, head) : head;
|
|
4207
|
+
const listArgs = [
|
|
4208
|
+
"pr",
|
|
4209
|
+
"list",
|
|
4210
|
+
"--head",
|
|
4211
|
+
listHead,
|
|
4212
|
+
"--json",
|
|
4213
|
+
"number,title,headRefName,url,isCrossRepository",
|
|
4214
|
+
"--limit",
|
|
4215
|
+
"1",
|
|
4216
|
+
"--state",
|
|
4217
|
+
"open"
|
|
4218
|
+
];
|
|
4219
|
+
if (slug) listArgs.push("--repo", slug);
|
|
4220
|
+
const listed = await gh(listArgs, repoPath, { reject: false });
|
|
4221
|
+
if (listed.exitCode !== 0 || !listed.stdout.trim()) return null;
|
|
4222
|
+
try {
|
|
4223
|
+
const rows = JSON.parse(listed.stdout);
|
|
4224
|
+
return rows[0] ?? null;
|
|
4225
|
+
} catch {
|
|
4226
|
+
return null;
|
|
4027
4227
|
}
|
|
4028
|
-
if (thread.branchName?.trim()) return thread.branchName.trim();
|
|
4029
|
-
return null;
|
|
4030
4228
|
}
|
|
4031
4229
|
function normalizeGhTime(value) {
|
|
4032
4230
|
if (typeof value !== "string" || !value.trim()) return null;
|
|
@@ -4352,7 +4550,7 @@ async function fetchPrHead(repoPath, number, localBranch) {
|
|
|
4352
4550
|
const label = opts?.ghAuth ? `${remote} (gh auth)` : remote;
|
|
4353
4551
|
const gitOpts = { reject: false };
|
|
4354
4552
|
if (opts?.ghAuth) {
|
|
4355
|
-
const token = await
|
|
4553
|
+
const token = await resolveGithubAgentToken(getGithubGitAuthMode(), repoPath);
|
|
4356
4554
|
if (!token) {
|
|
4357
4555
|
errors.push(`${label}: gh auth token unavailable`);
|
|
4358
4556
|
return false;
|
|
@@ -4403,7 +4601,7 @@ async function fetchPrHead(repoPath, number, localBranch) {
|
|
|
4403
4601
|
const ensureOid = async (remote, opts) => {
|
|
4404
4602
|
const gitOpts = { reject: false };
|
|
4405
4603
|
if (opts?.ghAuth) {
|
|
4406
|
-
const token = await
|
|
4604
|
+
const token = await resolveGithubAgentToken(getGithubGitAuthMode(), repoPath);
|
|
4407
4605
|
if (!token) return false;
|
|
4408
4606
|
gitOpts.env = { GIT_TERMINAL_PROMPT: "0" };
|
|
4409
4607
|
gitOpts.config = {
|
|
@@ -4471,8 +4669,8 @@ function isLocalPrFetchBranch(ref) {
|
|
|
4471
4669
|
}
|
|
4472
4670
|
async function createThreadWorktree(opts) {
|
|
4473
4671
|
let branchName = `thread/${opts.slug}`;
|
|
4474
|
-
const worktreePath = (0,
|
|
4475
|
-
if ((0,
|
|
4672
|
+
const worktreePath = (0, import_node_path13.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
4673
|
+
if ((0, import_node_fs12.existsSync)(worktreePath)) {
|
|
4476
4674
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
4477
4675
|
}
|
|
4478
4676
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -4541,8 +4739,8 @@ ${add.stdout}`;
|
|
|
4541
4739
|
async function createExistingBranchWorktree(opts) {
|
|
4542
4740
|
const branchName = opts.branchName.trim();
|
|
4543
4741
|
if (!branchName) throw new Error("branch name required");
|
|
4544
|
-
const worktreePath = (0,
|
|
4545
|
-
if ((0,
|
|
4742
|
+
const worktreePath = (0, import_node_path13.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
4743
|
+
if ((0, import_node_fs12.existsSync)(worktreePath)) {
|
|
4546
4744
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
4547
4745
|
}
|
|
4548
4746
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -4653,7 +4851,7 @@ async function pushBranch(worktreePath, branchName) {
|
|
|
4653
4851
|
if (ssh.exitCode === 0) return;
|
|
4654
4852
|
const sshErr = (ssh.stderr || ssh.stdout).trim();
|
|
4655
4853
|
const slug = await resolveGithubRepoSlug(worktreePath);
|
|
4656
|
-
const token = await
|
|
4854
|
+
const token = await resolveGithubAgentToken(getGithubGitAuthMode(), worktreePath);
|
|
4657
4855
|
if (!slug || !token) {
|
|
4658
4856
|
throw new Error(
|
|
4659
4857
|
sshErr || `git push origin ${branchName} failed` + (!token ? " (no SSH agent and gh auth token unavailable \u2014 run: gh auth login)" : "")
|
|
@@ -4830,10 +5028,10 @@ function sameRepoPath(a, b) {
|
|
|
4830
5028
|
return normalizeWorktreePath(a) === normalizeWorktreePath(b);
|
|
4831
5029
|
}
|
|
4832
5030
|
function listLocalThreadBranchSlugs(repoPath) {
|
|
4833
|
-
const refsDir = (0,
|
|
4834
|
-
if (!(0,
|
|
5031
|
+
const refsDir = (0, import_node_path13.join)(repoPath, ".git", "refs", "heads", "thread");
|
|
5032
|
+
if (!(0, import_node_fs12.existsSync)(refsDir)) return [];
|
|
4835
5033
|
try {
|
|
4836
|
-
return (0,
|
|
5034
|
+
return (0, import_node_fs12.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
|
|
4837
5035
|
} catch {
|
|
4838
5036
|
return [];
|
|
4839
5037
|
}
|
|
@@ -4841,8 +5039,8 @@ function listLocalThreadBranchSlugs(repoPath) {
|
|
|
4841
5039
|
function collectTakenTeamSlugs(repoPath) {
|
|
4842
5040
|
const taken = /* @__PURE__ */ new Set();
|
|
4843
5041
|
const root = worktreesRoot(repoPath);
|
|
4844
|
-
if ((0,
|
|
4845
|
-
for (const entry of (0,
|
|
5042
|
+
if ((0, import_node_fs12.existsSync)(root)) {
|
|
5043
|
+
for (const entry of (0, import_node_fs12.readdirSync)(root, { withFileTypes: true })) {
|
|
4846
5044
|
if (entry.isDirectory() && entry.name !== ".DS_Store") {
|
|
4847
5045
|
taken.add(normalizeTakenSlug(entry.name));
|
|
4848
5046
|
}
|
|
@@ -4863,18 +5061,18 @@ function allocateTeamSlug(repoPath) {
|
|
|
4863
5061
|
const taken = collectTakenTeamSlugs(repoPath);
|
|
4864
5062
|
for (let attempt = 0; attempt < 32; attempt++) {
|
|
4865
5063
|
const team = allocateTeamName(taken);
|
|
4866
|
-
const path2 = (0,
|
|
4867
|
-
if (!(0,
|
|
5064
|
+
const path2 = (0, import_node_path13.join)(worktreesRoot(repoPath), team.slug);
|
|
5065
|
+
if (!(0, import_node_fs12.existsSync)(path2)) return team;
|
|
4868
5066
|
taken.add(team.slug);
|
|
4869
5067
|
}
|
|
4870
5068
|
throw new Error("No available soccer team worktree directories left");
|
|
4871
5069
|
}
|
|
4872
|
-
var
|
|
5070
|
+
var import_node_fs12, import_node_path13;
|
|
4873
5071
|
var init_worktree = __esm({
|
|
4874
5072
|
"src/git/worktree.ts"() {
|
|
4875
5073
|
"use strict";
|
|
4876
|
-
|
|
4877
|
-
|
|
5074
|
+
import_node_fs12 = require("fs");
|
|
5075
|
+
import_node_path13 = require("path");
|
|
4878
5076
|
init_paths();
|
|
4879
5077
|
init_thread_store();
|
|
4880
5078
|
init_teams();
|
|
@@ -4958,7 +5156,7 @@ function coordinatorTurnReminder(opts) {
|
|
|
4958
5156
|
function ensureGlobalCoordinatorCwd(opts) {
|
|
4959
5157
|
const dir = globalAgentCwd();
|
|
4960
5158
|
try {
|
|
4961
|
-
(0,
|
|
5159
|
+
(0, import_node_fs13.mkdirSync)(dir, { recursive: true });
|
|
4962
5160
|
} catch {
|
|
4963
5161
|
return dir;
|
|
4964
5162
|
}
|
|
@@ -4966,7 +5164,7 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
4966
5164
|
let orchId = opts?.orchestratorThreadId?.trim() || "";
|
|
4967
5165
|
if (!orchId) {
|
|
4968
5166
|
try {
|
|
4969
|
-
const existing = (0,
|
|
5167
|
+
const existing = (0, import_node_fs13.readFileSync)((0, import_node_path14.join)(dir, "AGENTS.md"), "utf8");
|
|
4970
5168
|
const m = existing.match(
|
|
4971
5169
|
/YOUR orchestration thread id is `([0-9a-f-]{36})`/i
|
|
4972
5170
|
);
|
|
@@ -5008,9 +5206,9 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
5008
5206
|
"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."
|
|
5009
5207
|
].join("\n");
|
|
5010
5208
|
try {
|
|
5011
|
-
(0,
|
|
5209
|
+
(0, import_node_fs13.writeFileSync)((0, import_node_path14.join)(dir, "CLAUDE.md"), `${body}
|
|
5012
5210
|
`, "utf8");
|
|
5013
|
-
(0,
|
|
5211
|
+
(0, import_node_fs13.writeFileSync)((0, import_node_path14.join)(dir, "AGENTS.md"), `${body}
|
|
5014
5212
|
`, "utf8");
|
|
5015
5213
|
} catch {
|
|
5016
5214
|
}
|
|
@@ -5042,12 +5240,12 @@ function coordinatorSystemPrompt(opts) {
|
|
|
5042
5240
|
formatWorkspaceInventory(opts.workspaces)
|
|
5043
5241
|
].join("\n");
|
|
5044
5242
|
}
|
|
5045
|
-
var
|
|
5243
|
+
var import_node_fs13, import_node_path14, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
|
|
5046
5244
|
var init_coordinator_prompt = __esm({
|
|
5047
5245
|
"src/orchestrator/coordinator-prompt.ts"() {
|
|
5048
5246
|
"use strict";
|
|
5049
|
-
|
|
5050
|
-
|
|
5247
|
+
import_node_fs13 = require("fs");
|
|
5248
|
+
import_node_path14 = require("path");
|
|
5051
5249
|
init_worktree();
|
|
5052
5250
|
init_app_settings();
|
|
5053
5251
|
init_paths();
|
|
@@ -5063,7 +5261,7 @@ var init_coordinator_prompt = __esm({
|
|
|
5063
5261
|
"- get_pr_stack / open_pr_stack_layers / add_stack_layer / create_pr_stack \u2014 GitHub stacked PRs (`gh stack`); one worktree per layer",
|
|
5064
5262
|
"- list_models \u2014 only when you need a specific model (rare); otherwise omit model so Account defaults apply",
|
|
5065
5263
|
"- list_threads / get_thread \u2014 fleet status (what is going on)",
|
|
5066
|
-
"- ask_user \u2014 multiple-choice
|
|
5264
|
+
"- ask_user \u2014 composer multiple-choice only when blocked on a concrete choice (approach fork, which API). Never for hellos, check-ins, or invented \u201Cwhat should we do?\u201D menus \u2014 reply in chat. Explain options first, description on every option, then wait.",
|
|
5067
5265
|
"- set_caffeinate \u2014 keep this Mac awake across turns (macOS caffeinate). Turn on for Slack / away-from-keyboard work. Turn OFF when the user says they are done, wrapping up, going to sleep, or no longer need the machine awake. Closing this chat also releases it.",
|
|
5068
5266
|
"Workspaces:",
|
|
5069
5267
|
"- add_workspace / remove_workspace \u2014 register or unregister a git repo",
|
|
@@ -5353,38 +5551,38 @@ __export(workspaces_exports, {
|
|
|
5353
5551
|
syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
|
|
5354
5552
|
});
|
|
5355
5553
|
function workspacesFile() {
|
|
5356
|
-
return (0,
|
|
5554
|
+
return (0, import_node_path15.join)(appDataDir(), "workspaces.json");
|
|
5357
5555
|
}
|
|
5358
5556
|
function removedWorkspacesFile() {
|
|
5359
|
-
return (0,
|
|
5557
|
+
return (0, import_node_path15.join)(appDataDir(), "removed-workspaces.json");
|
|
5360
5558
|
}
|
|
5361
5559
|
function readAll() {
|
|
5362
5560
|
const path2 = workspacesFile();
|
|
5363
|
-
if (!(0,
|
|
5561
|
+
if (!(0, import_node_fs14.existsSync)(path2)) return [];
|
|
5364
5562
|
try {
|
|
5365
|
-
const raw = JSON.parse((0,
|
|
5563
|
+
const raw = JSON.parse((0, import_node_fs14.readFileSync)(path2, "utf8"));
|
|
5366
5564
|
return Array.isArray(raw) ? raw : [];
|
|
5367
5565
|
} catch {
|
|
5368
5566
|
return [];
|
|
5369
5567
|
}
|
|
5370
5568
|
}
|
|
5371
5569
|
function writeAll(list) {
|
|
5372
|
-
(0,
|
|
5373
|
-
(0,
|
|
5570
|
+
(0, import_node_fs14.mkdirSync)(appDataDir(), { recursive: true });
|
|
5571
|
+
(0, import_node_fs14.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
|
|
5374
5572
|
}
|
|
5375
5573
|
function readRemoved() {
|
|
5376
5574
|
const path2 = removedWorkspacesFile();
|
|
5377
|
-
if (!(0,
|
|
5575
|
+
if (!(0, import_node_fs14.existsSync)(path2)) return /* @__PURE__ */ new Set();
|
|
5378
5576
|
try {
|
|
5379
|
-
const raw = JSON.parse((0,
|
|
5577
|
+
const raw = JSON.parse((0, import_node_fs14.readFileSync)(path2, "utf8"));
|
|
5380
5578
|
return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
|
|
5381
5579
|
} catch {
|
|
5382
5580
|
return /* @__PURE__ */ new Set();
|
|
5383
5581
|
}
|
|
5384
5582
|
}
|
|
5385
5583
|
function writeRemoved(paths) {
|
|
5386
|
-
(0,
|
|
5387
|
-
(0,
|
|
5584
|
+
(0, import_node_fs14.mkdirSync)(appDataDir(), { recursive: true });
|
|
5585
|
+
(0, import_node_fs14.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
|
|
5388
5586
|
}
|
|
5389
5587
|
function rememberRemoved(repoPath) {
|
|
5390
5588
|
const next = readRemoved();
|
|
@@ -5407,7 +5605,7 @@ function listWorkspaces() {
|
|
|
5407
5605
|
async function addWorkspace(repoPath) {
|
|
5408
5606
|
const root = await resolveRepoRoot(repoPath);
|
|
5409
5607
|
if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
|
|
5410
|
-
if (!(0,
|
|
5608
|
+
if (!(0, import_node_fs14.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
|
|
5411
5609
|
forgetRemoved(root);
|
|
5412
5610
|
await ensureGhPreferOrigin(root);
|
|
5413
5611
|
const current = readAll();
|
|
@@ -5415,7 +5613,7 @@ async function addWorkspace(repoPath) {
|
|
|
5415
5613
|
if (existing) return existing;
|
|
5416
5614
|
const next = {
|
|
5417
5615
|
path: root,
|
|
5418
|
-
name: (0,
|
|
5616
|
+
name: (0, import_node_path15.basename)(root),
|
|
5419
5617
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5420
5618
|
};
|
|
5421
5619
|
writeAll([...current, next]);
|
|
@@ -5437,10 +5635,10 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
5437
5635
|
if (!path2 || path2 === "/" || isGlobalRepoPath(path2) || byPath.has(path2) || removed.has(path2)) {
|
|
5438
5636
|
continue;
|
|
5439
5637
|
}
|
|
5440
|
-
if (!(0,
|
|
5638
|
+
if (!(0, import_node_fs14.existsSync)(path2)) continue;
|
|
5441
5639
|
const ws = {
|
|
5442
5640
|
path: path2,
|
|
5443
|
-
name: (0,
|
|
5641
|
+
name: (0, import_node_path15.basename)(path2),
|
|
5444
5642
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5445
5643
|
};
|
|
5446
5644
|
byPath.set(path2, ws);
|
|
@@ -5450,12 +5648,12 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
5450
5648
|
if (dirty) writeAll(next);
|
|
5451
5649
|
return next.sort((a, b) => a.name.localeCompare(b.name));
|
|
5452
5650
|
}
|
|
5453
|
-
var
|
|
5651
|
+
var import_node_fs14, import_node_path15;
|
|
5454
5652
|
var init_workspaces = __esm({
|
|
5455
5653
|
"src/store/workspaces.ts"() {
|
|
5456
5654
|
"use strict";
|
|
5457
|
-
|
|
5458
|
-
|
|
5655
|
+
import_node_fs14 = require("fs");
|
|
5656
|
+
import_node_path15 = require("path");
|
|
5459
5657
|
init_paths();
|
|
5460
5658
|
init_global_workspace();
|
|
5461
5659
|
init_worktree();
|
|
@@ -5464,32 +5662,32 @@ var init_workspaces = __esm({
|
|
|
5464
5662
|
|
|
5465
5663
|
// src/brightsy/config.ts
|
|
5466
5664
|
function brightsyConfigPath() {
|
|
5467
|
-
return (0,
|
|
5665
|
+
return (0, import_node_path16.join)((0, import_node_os6.homedir)(), ".brightsy", "config.json");
|
|
5468
5666
|
}
|
|
5469
5667
|
function loadBrightsyConfig() {
|
|
5470
5668
|
const path2 = brightsyConfigPath();
|
|
5471
|
-
if (!(0,
|
|
5669
|
+
if (!(0, import_node_fs15.existsSync)(path2)) {
|
|
5472
5670
|
throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
|
|
5473
5671
|
}
|
|
5474
|
-
const raw = JSON.parse((0,
|
|
5672
|
+
const raw = JSON.parse((0, import_node_fs15.readFileSync)(path2, "utf8"));
|
|
5475
5673
|
if (!raw.access_token || !raw.account_id) {
|
|
5476
5674
|
throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
|
|
5477
5675
|
}
|
|
5478
5676
|
return raw;
|
|
5479
5677
|
}
|
|
5480
5678
|
function saveBrightsyConfig(cfg) {
|
|
5481
|
-
(0,
|
|
5679
|
+
(0, import_node_fs15.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
|
|
5482
5680
|
`, {
|
|
5483
5681
|
mode: 384
|
|
5484
5682
|
});
|
|
5485
5683
|
}
|
|
5486
|
-
var
|
|
5684
|
+
var import_node_fs15, import_node_os6, import_node_path16;
|
|
5487
5685
|
var init_config = __esm({
|
|
5488
5686
|
"src/brightsy/config.ts"() {
|
|
5489
5687
|
"use strict";
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5688
|
+
import_node_fs15 = require("fs");
|
|
5689
|
+
import_node_os6 = require("os");
|
|
5690
|
+
import_node_path16 = require("path");
|
|
5493
5691
|
}
|
|
5494
5692
|
});
|
|
5495
5693
|
|
|
@@ -5592,22 +5790,22 @@ __export(connected_teams_exports, {
|
|
|
5592
5790
|
listConnectedBrightsyTeams: () => listConnectedBrightsyTeams
|
|
5593
5791
|
});
|
|
5594
5792
|
function storePath() {
|
|
5595
|
-
return (0,
|
|
5793
|
+
return (0, import_node_path17.join)(appDataDir(), "brightsy-teams.json");
|
|
5596
5794
|
}
|
|
5597
5795
|
function readStore() {
|
|
5598
5796
|
const path2 = storePath();
|
|
5599
|
-
if (!(0,
|
|
5797
|
+
if (!(0, import_node_fs16.existsSync)(path2)) return [];
|
|
5600
5798
|
try {
|
|
5601
|
-
const parsed = JSON.parse((0,
|
|
5799
|
+
const parsed = JSON.parse((0, import_node_fs16.readFileSync)(path2, "utf8"));
|
|
5602
5800
|
return Array.isArray(parsed.teams) ? parsed.teams : [];
|
|
5603
5801
|
} catch {
|
|
5604
5802
|
return [];
|
|
5605
5803
|
}
|
|
5606
5804
|
}
|
|
5607
5805
|
function writeStore(teams) {
|
|
5608
|
-
(0,
|
|
5806
|
+
(0, import_node_fs16.mkdirSync)(appDataDir(), { recursive: true });
|
|
5609
5807
|
const path2 = storePath();
|
|
5610
|
-
(0,
|
|
5808
|
+
(0, import_node_fs16.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
|
|
5611
5809
|
`, {
|
|
5612
5810
|
mode: 384
|
|
5613
5811
|
});
|
|
@@ -5769,12 +5967,12 @@ function brightsyMcpServerName(slug) {
|
|
|
5769
5967
|
const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
|
|
5770
5968
|
return `brightsy_${cleaned || "team"}`;
|
|
5771
5969
|
}
|
|
5772
|
-
var
|
|
5970
|
+
var import_node_fs16, import_node_path17;
|
|
5773
5971
|
var init_connected_teams = __esm({
|
|
5774
5972
|
"src/brightsy/connected-teams.ts"() {
|
|
5775
5973
|
"use strict";
|
|
5776
|
-
|
|
5777
|
-
|
|
5974
|
+
import_node_fs16 = require("fs");
|
|
5975
|
+
import_node_path17 = require("path");
|
|
5778
5976
|
init_paths();
|
|
5779
5977
|
init_accounts();
|
|
5780
5978
|
init_config();
|
|
@@ -5911,17 +6109,27 @@ function extractJsonErrorMessage(obj) {
|
|
|
5911
6109
|
}
|
|
5912
6110
|
return null;
|
|
5913
6111
|
}
|
|
6112
|
+
function isPinnedStderrLine(line) {
|
|
6113
|
+
if (/^\s*at\s/.test(line)) return false;
|
|
6114
|
+
return /cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|cursor startup failed:/i.test(
|
|
6115
|
+
line
|
|
6116
|
+
);
|
|
6117
|
+
}
|
|
5914
6118
|
function pushTurnStderr(tail, line, maxLines = 12) {
|
|
5915
6119
|
const trimmed = line.trim();
|
|
5916
6120
|
if (!trimmed) return;
|
|
5917
6121
|
if (NODE_VERSION_FOOTER.test(trimmed)) return;
|
|
5918
6122
|
if (/^reconnecting\.\.\./i.test(trimmed)) return;
|
|
5919
6123
|
tail.push(trimmed);
|
|
5920
|
-
while (tail.length > maxLines)
|
|
6124
|
+
while (tail.length > maxLines) {
|
|
6125
|
+
const dropIdx = tail.findIndex((l) => !isPinnedStderrLine(l));
|
|
6126
|
+
if (dropIdx === -1) tail.shift();
|
|
6127
|
+
else tail.splice(dropIdx, 1);
|
|
6128
|
+
}
|
|
5921
6129
|
}
|
|
5922
6130
|
function looksLikeMinifiedJsDump(line) {
|
|
5923
6131
|
if (line.length < 200) return false;
|
|
5924
|
-
return /yield Promise\.all/.test(line) || /\(0,[A-Za-z$]\.\w+\)/.test(line) || /CURSOR_RIPGREP_PATH/.test(line);
|
|
6132
|
+
return /yield Promise\.all/.test(line) || /\(0,[A-Za-z$]\.\w+\)/.test(line) || /CURSOR_RIPGREP_PATH/.test(line) || /findFilesWithRipgrep/.test(line) || /@cursor\/sdk\/dist\//.test(line);
|
|
5925
6133
|
}
|
|
5926
6134
|
function looksLikeNestedElectronCrash(line) {
|
|
5927
6135
|
return /HasCustomHostObject|ElectronInitializeICUandStartNode/i.test(line);
|
|
@@ -5936,7 +6144,15 @@ function summarizeTurnStderr(tail, maxChars = 500) {
|
|
|
5936
6144
|
const cursorStartup = [...tail].reverse().find((line) => /cursor startup failed:/i.test(line));
|
|
5937
6145
|
if (cursorStartup) return clipStderr(cursorStartup, maxChars);
|
|
5938
6146
|
if (tail.some(looksLikeNestedElectronCrash)) return NESTED_ELECTRON_SUMMARY;
|
|
5939
|
-
|
|
6147
|
+
if (tail.some(
|
|
6148
|
+
(line) => /\[resource_exhausted\]|resource_exhausted/i.test(line) || /findFilesWithRipgrep/.test(line)
|
|
6149
|
+
)) {
|
|
6150
|
+
return clipStderr(
|
|
6151
|
+
"Cursor local file search failed (ripgrep / resource_exhausted). Wait a minute and retry; if it keeps happening, check Cursor usage.",
|
|
6152
|
+
maxChars
|
|
6153
|
+
);
|
|
6154
|
+
}
|
|
6155
|
+
const moduleMissing = [...tail].reverse().find((line) => /cannot find (?:package|module)/i.test(line));
|
|
5940
6156
|
if (moduleMissing) return clipStderr(moduleMissing, maxChars);
|
|
5941
6157
|
const useful = tail.filter((line) => !looksLikeMinifiedJsDump(line));
|
|
5942
6158
|
if (useful.length === 0 && tail.some(looksLikeMinifiedJsDump)) {
|
|
@@ -5955,7 +6171,7 @@ function looksLikeAgentFailureMessage(text3) {
|
|
|
5955
6171
|
if (!lower) return false;
|
|
5956
6172
|
return /you've hit your|hit your (session|weekly|opus) limit|usage limit/.test(lower) || /credit balance is too low|out of credits|insufficient.?quota|quota.?exceeded/.test(lower) || /invalid user api key|invalid api key|not logged in|not authenticated|unauthorized/.test(
|
|
5957
6173
|
lower
|
|
5958
|
-
) || /\b429\b|too many requests|rate.?limit/.test(lower) || /prompt is too long|context.*(too long|exceed)|conversation too long/.test(lower);
|
|
6174
|
+
) || /\b429\b|too many requests|rate.?limit/.test(lower) || /prompt is too long|context.*(too long|exceed)|conversation too long/.test(lower) || /\[resource_exhausted\]|resource_exhausted/.test(lower) || /findFilesWithRipgrep/.test(text3);
|
|
5959
6175
|
}
|
|
5960
6176
|
function fallbackTurnFailDetail(assistantText) {
|
|
5961
6177
|
const t = assistantText.trim();
|
|
@@ -5977,6 +6193,9 @@ function humanizeAgentFailDetail(detail) {
|
|
|
5977
6193
|
if (/\b429\b|rate.?limit|too many requests/.test(lower)) {
|
|
5978
6194
|
return `${raw} \u2014 wait a moment and retry.`;
|
|
5979
6195
|
}
|
|
6196
|
+
if (/\[resource_exhausted\]|resource_exhausted|findfileswithripgrep/.test(lower)) {
|
|
6197
|
+
return "Cursor local file search failed (ripgrep / resource_exhausted). Wait a minute and retry; if it keeps happening, check Cursor usage.";
|
|
6198
|
+
}
|
|
5980
6199
|
if (/invalid user api key|invalid api key|not logged in|not authenticated|unauthorized|authentication|please run.*login|codex login|claude auth|cursor api/.test(
|
|
5981
6200
|
lower
|
|
5982
6201
|
)) {
|
|
@@ -6303,11 +6522,11 @@ async function syncCliForTarget(accountId) {
|
|
|
6303
6522
|
}
|
|
6304
6523
|
applyConnectedTeamToCli(team);
|
|
6305
6524
|
}
|
|
6306
|
-
var
|
|
6525
|
+
var import_node_fs17, brightsyAdapter;
|
|
6307
6526
|
var init_brightsy = __esm({
|
|
6308
6527
|
"src/agents/brightsy.ts"() {
|
|
6309
6528
|
"use strict";
|
|
6310
|
-
|
|
6529
|
+
import_node_fs17 = require("fs");
|
|
6311
6530
|
init_run();
|
|
6312
6531
|
init_connected_teams();
|
|
6313
6532
|
init_config();
|
|
@@ -6322,7 +6541,7 @@ var init_brightsy = __esm({
|
|
|
6322
6541
|
async detect() {
|
|
6323
6542
|
const brightsy = resolveAgentExecutable("brightsy");
|
|
6324
6543
|
if (brightsy !== "brightsy") {
|
|
6325
|
-
if (!(0,
|
|
6544
|
+
if (!(0, import_node_fs17.existsSync)(brightsy)) {
|
|
6326
6545
|
return {
|
|
6327
6546
|
agent: "brightsy",
|
|
6328
6547
|
installed: false,
|
|
@@ -6457,13 +6676,38 @@ var init_profile = __esm({
|
|
|
6457
6676
|
|
|
6458
6677
|
// src/agents/node-launch.ts
|
|
6459
6678
|
function isAsarPath(filePath) {
|
|
6679
|
+
if (/\.asar\.unpacked([/\\]|$)/.test(filePath)) return false;
|
|
6460
6680
|
return /\.asar([/\\]|$)/.test(filePath);
|
|
6461
6681
|
}
|
|
6682
|
+
function unpackedAsarPath(filePath) {
|
|
6683
|
+
if (!isAsarPath(filePath)) return null;
|
|
6684
|
+
const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
|
|
6685
|
+
if (unpacked === filePath) return null;
|
|
6686
|
+
return (0, import_node_fs18.existsSync)(unpacked) ? unpacked : null;
|
|
6687
|
+
}
|
|
6688
|
+
function nodeReadableScriptPath(scriptPath) {
|
|
6689
|
+
return unpackedAsarPath(scriptPath) ?? scriptPath;
|
|
6690
|
+
}
|
|
6691
|
+
async function findSystemNode() {
|
|
6692
|
+
const whichNode = await run("which", ["node"], { reject: false });
|
|
6693
|
+
const fromWhich = whichNode.exitCode === 0 && whichNode.stdout.trim() ? whichNode.stdout.trim() : "";
|
|
6694
|
+
if (fromWhich && !isElectronLikeCommand(fromWhich)) return fromWhich;
|
|
6695
|
+
const fallbacks = [
|
|
6696
|
+
...WELL_KNOWN_NODE_BINS,
|
|
6697
|
+
(0, import_node_path18.join)((0, import_node_os7.homedir)(), ".local/share/fnm/aliases/default/bin/node"),
|
|
6698
|
+
(0, import_node_path18.join)((0, import_node_os7.homedir)(), ".nvm/current/bin/node")
|
|
6699
|
+
];
|
|
6700
|
+
for (const bin of fallbacks) {
|
|
6701
|
+
if ((0, import_node_fs18.existsSync)(bin) && !isElectronLikeCommand(bin)) return bin;
|
|
6702
|
+
}
|
|
6703
|
+
return null;
|
|
6704
|
+
}
|
|
6462
6705
|
function applyNodeLaunch(launch, args) {
|
|
6706
|
+
const readableArgs = args.map(nodeReadableScriptPath);
|
|
6463
6707
|
if (!launch.env.ELECTRON_RUN_AS_NODE) {
|
|
6464
|
-
return { file: launch.file, args, env: launch.env };
|
|
6708
|
+
return { file: launch.file, args: readableArgs, env: launch.env };
|
|
6465
6709
|
}
|
|
6466
|
-
const wrapped = wrapElectronAsNodeLaunch(launch.file,
|
|
6710
|
+
const wrapped = wrapElectronAsNodeLaunch(launch.file, readableArgs);
|
|
6467
6711
|
if (process.platform === "win32") {
|
|
6468
6712
|
return { file: wrapped.file, args: wrapped.args, env: launch.env };
|
|
6469
6713
|
}
|
|
@@ -6472,27 +6716,73 @@ function applyNodeLaunch(launch, args) {
|
|
|
6472
6716
|
return { file: wrapped.file, args: wrapped.args, env };
|
|
6473
6717
|
}
|
|
6474
6718
|
async function resolveNodeLaunch(scriptPath) {
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
const whichNode = await run("which", ["node"], { reject: false });
|
|
6482
|
-
const nodeBin = whichNode.exitCode === 0 && whichNode.stdout.trim() ? whichNode.stdout.trim() : null;
|
|
6483
|
-
if (nodeBin) {
|
|
6484
|
-
return { file: nodeBin, env: {} };
|
|
6719
|
+
const script = nodeReadableScriptPath(scriptPath);
|
|
6720
|
+
if (!isAsarPath(script)) {
|
|
6721
|
+
const nodeBin = await findSystemNode();
|
|
6722
|
+
if (nodeBin) {
|
|
6723
|
+
return { file: nodeBin, env: {} };
|
|
6724
|
+
}
|
|
6485
6725
|
}
|
|
6486
6726
|
return {
|
|
6487
6727
|
file: process.execPath,
|
|
6488
6728
|
env: { ELECTRON_RUN_AS_NODE: "1" }
|
|
6489
6729
|
};
|
|
6490
6730
|
}
|
|
6731
|
+
var import_node_fs18, import_node_os7, import_node_path18, WELL_KNOWN_NODE_BINS;
|
|
6491
6732
|
var init_node_launch = __esm({
|
|
6492
6733
|
"src/agents/node-launch.ts"() {
|
|
6493
6734
|
"use strict";
|
|
6735
|
+
import_node_fs18 = require("fs");
|
|
6736
|
+
import_node_os7 = require("os");
|
|
6737
|
+
import_node_path18 = require("path");
|
|
6494
6738
|
init_nested_electron_env();
|
|
6495
6739
|
init_run();
|
|
6740
|
+
WELL_KNOWN_NODE_BINS = [
|
|
6741
|
+
"/opt/homebrew/bin/node",
|
|
6742
|
+
"/usr/local/bin/node"
|
|
6743
|
+
];
|
|
6744
|
+
}
|
|
6745
|
+
});
|
|
6746
|
+
|
|
6747
|
+
// src/agents/packaged-runtime.ts
|
|
6748
|
+
function electronResourcesPath() {
|
|
6749
|
+
const resources = process.resourcesPath;
|
|
6750
|
+
if (typeof resources !== "string" || !resources) return null;
|
|
6751
|
+
return resources;
|
|
6752
|
+
}
|
|
6753
|
+
function packagedCursorRuntimeDir() {
|
|
6754
|
+
const resources = electronResourcesPath();
|
|
6755
|
+
if (!resources) return null;
|
|
6756
|
+
const dir = (0, import_node_path19.join)(resources, "cursor-runtime");
|
|
6757
|
+
if (!(0, import_node_fs19.existsSync)((0, import_node_path19.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
|
|
6758
|
+
return dir;
|
|
6759
|
+
}
|
|
6760
|
+
function packagedCursorRunnerPath() {
|
|
6761
|
+
const dir = packagedCursorRuntimeDir();
|
|
6762
|
+
return dir ? (0, import_node_path19.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
|
|
6763
|
+
}
|
|
6764
|
+
function packagedMcpDir() {
|
|
6765
|
+
const resources = electronResourcesPath();
|
|
6766
|
+
if (!resources) return null;
|
|
6767
|
+
const dir = (0, import_node_path19.join)(resources, "sideboard-mcp");
|
|
6768
|
+
if (!(0, import_node_fs19.existsSync)((0, import_node_path19.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
|
|
6769
|
+
return dir;
|
|
6770
|
+
}
|
|
6771
|
+
function packagedMcpStdioPath() {
|
|
6772
|
+
const dir = packagedMcpDir();
|
|
6773
|
+
return dir ? (0, import_node_path19.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
|
|
6774
|
+
}
|
|
6775
|
+
function packagedCursorRipgrepCandidate(platformPkg, binName) {
|
|
6776
|
+
const dir = packagedCursorRuntimeDir();
|
|
6777
|
+
if (!dir) return null;
|
|
6778
|
+
return (0, import_node_path19.join)(dir, "node_modules", platformPkg, "bin", binName);
|
|
6779
|
+
}
|
|
6780
|
+
var import_node_fs19, import_node_path19;
|
|
6781
|
+
var init_packaged_runtime = __esm({
|
|
6782
|
+
"src/agents/packaged-runtime.ts"() {
|
|
6783
|
+
"use strict";
|
|
6784
|
+
import_node_fs19 = require("fs");
|
|
6785
|
+
import_node_path19 = require("path");
|
|
6496
6786
|
}
|
|
6497
6787
|
});
|
|
6498
6788
|
|
|
@@ -6579,35 +6869,37 @@ function corePackageDir() {
|
|
|
6579
6869
|
try {
|
|
6580
6870
|
const url = import_meta.url;
|
|
6581
6871
|
if (typeof url === "string" && url.length > 0) {
|
|
6582
|
-
return (0,
|
|
6872
|
+
return (0, import_node_path20.dirname)((0, import_node_url.fileURLToPath)(url));
|
|
6583
6873
|
}
|
|
6584
6874
|
} catch {
|
|
6585
6875
|
}
|
|
6586
6876
|
try {
|
|
6587
|
-
const req = (0, import_node_module.createRequire)((0,
|
|
6588
|
-
return (0,
|
|
6877
|
+
const req = (0, import_node_module.createRequire)((0, import_node_path20.join)(process.cwd(), "package.json"));
|
|
6878
|
+
return (0, import_node_path20.dirname)(req.resolve("@sideboard-ai/core"));
|
|
6589
6879
|
} catch {
|
|
6590
6880
|
return process.cwd();
|
|
6591
6881
|
}
|
|
6592
6882
|
}
|
|
6593
6883
|
function findSideboardMcpJsEntry() {
|
|
6594
6884
|
const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
|
|
6595
|
-
if (override && (0,
|
|
6885
|
+
if (override && (0, import_node_fs20.existsSync)(override)) return override;
|
|
6886
|
+
const packaged = packagedMcpStdioPath();
|
|
6887
|
+
if (packaged) return packaged;
|
|
6596
6888
|
let dir = corePackageDir();
|
|
6597
6889
|
for (let i = 0; i < 10; i++) {
|
|
6598
6890
|
const candidates = [
|
|
6599
|
-
(0,
|
|
6600
|
-
(0,
|
|
6601
|
-
(0,
|
|
6602
|
-
(0,
|
|
6603
|
-
(0,
|
|
6604
|
-
(0,
|
|
6605
|
-
(0,
|
|
6891
|
+
(0, import_node_path20.join)(dir, "mcp/run-stdio.js"),
|
|
6892
|
+
(0, import_node_path20.join)(dir, "mcp/run-stdio.cjs"),
|
|
6893
|
+
(0, import_node_path20.join)(dir, "dist/mcp/run-stdio.js"),
|
|
6894
|
+
(0, import_node_path20.join)(dir, "dist/mcp/run-stdio.cjs"),
|
|
6895
|
+
(0, import_node_path20.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
6896
|
+
(0, import_node_path20.join)(dir, "packages/cli/dist/index.js"),
|
|
6897
|
+
(0, import_node_path20.join)(dir, "cli/dist/index.js")
|
|
6606
6898
|
];
|
|
6607
6899
|
for (const p of candidates) {
|
|
6608
|
-
if ((0,
|
|
6900
|
+
if ((0, import_node_fs20.existsSync)(p) && !isAsarPath(p)) return p;
|
|
6609
6901
|
}
|
|
6610
|
-
const parent = (0,
|
|
6902
|
+
const parent = (0, import_node_path20.dirname)(dir);
|
|
6611
6903
|
if (parent === dir) break;
|
|
6612
6904
|
dir = parent;
|
|
6613
6905
|
}
|
|
@@ -6619,12 +6911,14 @@ async function resolveSideboardMcpServer() {
|
|
|
6619
6911
|
const isCli = /[/\\]cli[/\\]dist[/\\]index\.js$/.test(entry);
|
|
6620
6912
|
const scriptArgs = isCli ? [entry, "mcp"] : [entry];
|
|
6621
6913
|
const launch = applyNodeLaunch(await resolveNodeLaunch(entry), scriptArgs);
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6914
|
+
if (launch.file !== "/bin/sh" && !isElectronLikeCommand(launch.file)) {
|
|
6915
|
+
return {
|
|
6916
|
+
name: "sideboard",
|
|
6917
|
+
command: launch.file,
|
|
6918
|
+
args: launch.args,
|
|
6919
|
+
...Object.keys(launch.env).length > 0 ? { env: launch.env } : {}
|
|
6920
|
+
};
|
|
6921
|
+
}
|
|
6628
6922
|
}
|
|
6629
6923
|
const which = await run("which", ["sideboard"], { reject: false });
|
|
6630
6924
|
if (which.exitCode === 0 && which.stdout.trim()) {
|
|
@@ -6647,7 +6941,10 @@ async function buildInjectedMcpServers(opts) {
|
|
|
6647
6941
|
sideboard.env.SIDEBOARD_ORCHESTRATOR_THREAD_ID = orchId;
|
|
6648
6942
|
}
|
|
6649
6943
|
try {
|
|
6650
|
-
|
|
6944
|
+
mergeAgentGitAuthEnv(
|
|
6945
|
+
sideboard.env,
|
|
6946
|
+
await resolveAgentGitAuthEnv(sideboard.env)
|
|
6947
|
+
);
|
|
6651
6948
|
} catch {
|
|
6652
6949
|
}
|
|
6653
6950
|
servers.push(sideboard);
|
|
@@ -6669,9 +6966,6 @@ async function buildInjectedMcpServers(opts) {
|
|
|
6669
6966
|
}
|
|
6670
6967
|
return servers;
|
|
6671
6968
|
}
|
|
6672
|
-
function shSingleQuote(value) {
|
|
6673
|
-
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
6674
|
-
}
|
|
6675
6969
|
function cursorSafeMcpLaunch(command, args) {
|
|
6676
6970
|
if (process.platform === "win32") {
|
|
6677
6971
|
return args && args.length > 0 ? { command, args } : { command };
|
|
@@ -6679,31 +6973,13 @@ function cursorSafeMcpLaunch(command, args) {
|
|
|
6679
6973
|
const unwrapped = unwrapStrippedElectronLaunch(command, args);
|
|
6680
6974
|
const file = unwrapped?.file ?? command;
|
|
6681
6975
|
const fileArgs = unwrapped?.args ?? args ?? [];
|
|
6682
|
-
|
|
6683
|
-
return fileArgs.length > 0 ? { command: file, args: fileArgs } : { command: file };
|
|
6684
|
-
}
|
|
6685
|
-
const dir = (0, import_node_path16.join)(appDataDir(), "mcp-launch");
|
|
6686
|
-
(0, import_node_fs17.mkdirSync)(dir, { recursive: true });
|
|
6687
|
-
const wrap = (0, import_node_path16.join)(dir, "cursor-electron-as-node.sh");
|
|
6688
|
-
const execLine = [file, ...fileArgs].map(shSingleQuote).join(" ");
|
|
6689
|
-
(0, import_node_fs17.writeFileSync)(
|
|
6690
|
-
wrap,
|
|
6691
|
-
[
|
|
6692
|
-
"#!/bin/sh",
|
|
6693
|
-
"vars=`printenv | awk -F= '/^(ELECTRON_|CHROME_)/{print $1}'`",
|
|
6694
|
-
'[ -n "$vars" ] && unset $vars',
|
|
6695
|
-
"export ELECTRON_RUN_AS_NODE=1",
|
|
6696
|
-
`exec ${execLine} "$@"`,
|
|
6697
|
-
""
|
|
6698
|
-
].join("\n"),
|
|
6699
|
-
{ mode: 493 }
|
|
6700
|
-
);
|
|
6701
|
-
return { command: wrap };
|
|
6976
|
+
return fileArgs.length > 0 ? { command: file, args: fileArgs } : { command: file };
|
|
6702
6977
|
}
|
|
6703
6978
|
function mcpSpawnEnv(env) {
|
|
6704
6979
|
if (!env) return void 0;
|
|
6705
6980
|
const out = { ...env };
|
|
6706
6981
|
delete out.ELECTRON_RUN_AS_NODE;
|
|
6982
|
+
delete out.ELECTRON_RUN_AS_NODE;
|
|
6707
6983
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
6708
6984
|
}
|
|
6709
6985
|
function toCursorMcpServers(servers) {
|
|
@@ -6763,22 +7039,22 @@ function writeMcpServersConfig(servers) {
|
|
|
6763
7039
|
...env ? { env } : {}
|
|
6764
7040
|
};
|
|
6765
7041
|
}
|
|
6766
|
-
const dir = (0,
|
|
6767
|
-
const cfgPath = (0,
|
|
6768
|
-
(0,
|
|
7042
|
+
const dir = (0, import_node_fs20.mkdtempSync)((0, import_node_path20.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
|
|
7043
|
+
const cfgPath = (0, import_node_path20.join)(dir, "mcp.json");
|
|
7044
|
+
(0, import_node_fs20.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
|
|
6769
7045
|
return cfgPath;
|
|
6770
7046
|
}
|
|
6771
7047
|
async function writeInjectedMcpConfig(opts) {
|
|
6772
7048
|
return writeMcpServersConfig(await buildInjectedMcpServers(opts));
|
|
6773
7049
|
}
|
|
6774
|
-
var
|
|
7050
|
+
var import_node_fs20, import_node_module, import_node_os8, import_node_path20, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
|
|
6775
7051
|
var init_injected_mcp = __esm({
|
|
6776
7052
|
"src/agents/injected-mcp.ts"() {
|
|
6777
7053
|
"use strict";
|
|
6778
|
-
|
|
7054
|
+
import_node_fs20 = require("fs");
|
|
6779
7055
|
import_node_module = require("module");
|
|
6780
|
-
|
|
6781
|
-
|
|
7056
|
+
import_node_os8 = require("os");
|
|
7057
|
+
import_node_path20 = require("path");
|
|
6782
7058
|
import_node_url = require("url");
|
|
6783
7059
|
init_run();
|
|
6784
7060
|
init_config();
|
|
@@ -6787,6 +7063,7 @@ var init_injected_mcp = __esm({
|
|
|
6787
7063
|
init_app_settings();
|
|
6788
7064
|
init_paths();
|
|
6789
7065
|
init_node_launch();
|
|
7066
|
+
init_packaged_runtime();
|
|
6790
7067
|
init_nested_electron_env();
|
|
6791
7068
|
init_git_auth_mode();
|
|
6792
7069
|
import_meta = {};
|
|
@@ -6860,7 +7137,7 @@ var PLAN_MODE_INSTRUCTION;
|
|
|
6860
7137
|
var init_types = __esm({
|
|
6861
7138
|
"src/agents/types.ts"() {
|
|
6862
7139
|
"use strict";
|
|
6863
|
-
PLAN_MODE_INSTRUCTION = "Plan mode is active and must remain active until the user turns Plan mode off in the UI (or Approves / Hands off the plan). Analyze the codebase, search and read files as needed, and produce or refine a clear implementation plan. Do not modify, create, or delete any project files except via Sideboard MCP present_plan (writes .context/attachments/plan.md). When you need a clarifying decision (approach forks, auth choice, scope): (1) first write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it) \u2014 do not leave the user staring at bare labels; (2) then call Sideboard MCP ask_user with the same options, including a description on every option. Sideboard shows questions in the composer and mirrors them in chat. After ask_user, wait for the user's next message with their answers before finalizing the plan. When the plan is ready for approval: (1) call present_plan with the full markdown plan (title + content) so Sideboard saves .context/attachments/plan.md and shows it in chat for Approve / Hand off / Copy; (2) Claude should also call ExitPlanMode after present_plan. Do not skip present_plan \u2014 the plan must be a markdown file, not only chat prose.";
|
|
7140
|
+
PLAN_MODE_INSTRUCTION = "Plan mode is active and must remain active until the user turns Plan mode off in the UI (or Approves / Hands off the plan). Analyze the codebase, search and read files as needed, and produce or refine a clear implementation plan. Do not modify, create, or delete any project files except via Sideboard MCP present_plan (writes .context/attachments/plan.md). When you need a clarifying decision (approach forks, auth choice, scope) \u2014 not greetings, check-ins, or an invented task menu: (1) first write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it) \u2014 do not leave the user staring at bare labels; (2) then call Sideboard MCP ask_user with the same options, including a description on every option. If one option is the obvious default, proceed without asking. Sideboard shows questions in the composer and mirrors them in chat. After ask_user, wait for the user's next message with their answers before finalizing the plan. When the plan is ready for approval: (1) call present_plan with the full markdown plan (title + content) so Sideboard saves .context/attachments/plan.md and shows it in chat for Approve / Hand off / Copy; (2) Claude should also call ExitPlanMode after present_plan. Do not skip present_plan \u2014 the plan must be a markdown file, not only chat prose.";
|
|
6864
7141
|
}
|
|
6865
7142
|
});
|
|
6866
7143
|
|
|
@@ -6970,11 +7247,11 @@ function parseIssuesJson(raw) {
|
|
|
6970
7247
|
}
|
|
6971
7248
|
return [];
|
|
6972
7249
|
}
|
|
6973
|
-
var
|
|
7250
|
+
var import_node_fs21, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
|
|
6974
7251
|
var init_claude = __esm({
|
|
6975
7252
|
"src/agents/claude.ts"() {
|
|
6976
7253
|
"use strict";
|
|
6977
|
-
|
|
7254
|
+
import_node_fs21 = require("fs");
|
|
6978
7255
|
init_run();
|
|
6979
7256
|
init_app_settings();
|
|
6980
7257
|
init_claude_mcp();
|
|
@@ -7003,7 +7280,7 @@ var init_claude = __esm({
|
|
|
7003
7280
|
async detect() {
|
|
7004
7281
|
const claude = resolveClaudeExecutable();
|
|
7005
7282
|
if (claude !== "claude") {
|
|
7006
|
-
if (!(0,
|
|
7283
|
+
if (!(0, import_node_fs21.existsSync)(claude)) {
|
|
7007
7284
|
return {
|
|
7008
7285
|
agent: "claude",
|
|
7009
7286
|
installed: false,
|
|
@@ -7240,7 +7517,7 @@ async function listCodexModels() {
|
|
|
7240
7517
|
if (codex === "codex") {
|
|
7241
7518
|
const which = await run("which", ["codex"], { reject: false });
|
|
7242
7519
|
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
7243
|
-
} else if (!(0,
|
|
7520
|
+
} else if (!(0, import_node_fs22.existsSync)(codex)) {
|
|
7244
7521
|
return FALLBACK_CODEX_MODELS;
|
|
7245
7522
|
}
|
|
7246
7523
|
const listed = await run(codex, ["debug", "models"], { reject: false });
|
|
@@ -7275,12 +7552,12 @@ function usageFromCodex(usage) {
|
|
|
7275
7552
|
}
|
|
7276
7553
|
function codexConfigHasNetworkAccess() {
|
|
7277
7554
|
const candidates = [
|
|
7278
|
-
(0,
|
|
7279
|
-
(0,
|
|
7555
|
+
(0, import_node_path21.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
|
|
7556
|
+
(0, import_node_path21.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
|
|
7280
7557
|
];
|
|
7281
7558
|
for (const path2 of candidates) {
|
|
7282
|
-
if (!(0,
|
|
7283
|
-
const text3 = (0,
|
|
7559
|
+
if (!(0, import_node_fs22.existsSync)(path2)) continue;
|
|
7560
|
+
const text3 = (0, import_node_fs22.readFileSync)(path2, "utf8");
|
|
7284
7561
|
if (/network_access\s*=\s*true/.test(text3)) return true;
|
|
7285
7562
|
}
|
|
7286
7563
|
return false;
|
|
@@ -7312,21 +7589,21 @@ function asRecord(value) {
|
|
|
7312
7589
|
return void 0;
|
|
7313
7590
|
}
|
|
7314
7591
|
function codexLooksAuthenticated() {
|
|
7315
|
-
const authPath = (0,
|
|
7316
|
-
if (!(0,
|
|
7592
|
+
const authPath = (0, import_node_path21.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
|
|
7593
|
+
if (!(0, import_node_fs22.existsSync)(authPath)) return false;
|
|
7317
7594
|
try {
|
|
7318
|
-
return (0,
|
|
7595
|
+
return (0, import_node_fs22.statSync)(authPath).size > 2;
|
|
7319
7596
|
} catch {
|
|
7320
7597
|
return false;
|
|
7321
7598
|
}
|
|
7322
7599
|
}
|
|
7323
|
-
var
|
|
7600
|
+
var import_node_fs22, import_node_os9, import_node_path21, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
7324
7601
|
var init_codex = __esm({
|
|
7325
7602
|
"src/agents/codex.ts"() {
|
|
7326
7603
|
"use strict";
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7604
|
+
import_node_fs22 = require("fs");
|
|
7605
|
+
import_node_os9 = require("os");
|
|
7606
|
+
import_node_path21 = require("path");
|
|
7330
7607
|
init_run();
|
|
7331
7608
|
init_app_settings();
|
|
7332
7609
|
init_global_workspace();
|
|
@@ -7351,7 +7628,7 @@ var init_codex = __esm({
|
|
|
7351
7628
|
async detect() {
|
|
7352
7629
|
const codex = resolveAgentExecutable("codex");
|
|
7353
7630
|
if (codex !== "codex") {
|
|
7354
|
-
if (!(0,
|
|
7631
|
+
if (!(0, import_node_fs22.existsSync)(codex)) {
|
|
7355
7632
|
return {
|
|
7356
7633
|
agent: "codex",
|
|
7357
7634
|
installed: false,
|
|
@@ -7424,8 +7701,13 @@ var init_codex = __esm({
|
|
|
7424
7701
|
// `codex exec` rejects `--ask-for-approval` (global-only on newer CLIs).
|
|
7425
7702
|
"-c",
|
|
7426
7703
|
'approval_policy="never"',
|
|
7427
|
-
// Seatbelt cannot use the login Keychain;
|
|
7428
|
-
|
|
7704
|
+
// Seatbelt cannot use the login Keychain; inherit GH_CONFIG_DIR / GIT_CONFIG_*.
|
|
7705
|
+
// Default policy also strips *TOKEN*. Linked worktrees need the main
|
|
7706
|
+
// repo `.git` (+ `.git/worktrees/<name>`) as writable_roots so git commit
|
|
7707
|
+
// can create index.lock.
|
|
7708
|
+
...codexUnattendedGitConfigArgs(mode.codexSandbox, {
|
|
7709
|
+
writableRoots: mode.codexSandbox === "workspace-write" ? await resolveCodexGitWritableRoots(thread.worktreePath) : []
|
|
7710
|
+
}),
|
|
7429
7711
|
...model ? ["--model", model] : [],
|
|
7430
7712
|
...mcpOverrides
|
|
7431
7713
|
];
|
|
@@ -7746,6 +8028,74 @@ var init_cursor_events = __esm({
|
|
|
7746
8028
|
}
|
|
7747
8029
|
});
|
|
7748
8030
|
|
|
8031
|
+
// src/agents/cursor-ripgrep.ts
|
|
8032
|
+
function rgBinaryName() {
|
|
8033
|
+
return process.platform === "win32" ? "rg.exe" : "rg";
|
|
8034
|
+
}
|
|
8035
|
+
function platformRipgrepPackage() {
|
|
8036
|
+
return `@cursor/sdk-${process.platform}-${process.arch}`;
|
|
8037
|
+
}
|
|
8038
|
+
function usableRipgrepPath(candidate) {
|
|
8039
|
+
const raw = candidate?.trim();
|
|
8040
|
+
if (!raw || !(0, import_node_path22.isAbsolute)(raw)) return null;
|
|
8041
|
+
const readable = nodeReadableScriptPath(raw);
|
|
8042
|
+
if (!(0, import_node_fs23.existsSync)(readable) || isAsarPath(readable)) return null;
|
|
8043
|
+
return readable;
|
|
8044
|
+
}
|
|
8045
|
+
function walkForBundledRipgrep(startFile) {
|
|
8046
|
+
if (!startFile) return null;
|
|
8047
|
+
const pkg = platformRipgrepPackage();
|
|
8048
|
+
const name = rgBinaryName();
|
|
8049
|
+
let dir = (0, import_node_path22.dirname)((0, import_node_path22.resolve)(startFile));
|
|
8050
|
+
const root = (0, import_node_path22.parse)(dir).root;
|
|
8051
|
+
while (dir !== root) {
|
|
8052
|
+
const hit = usableRipgrepPath((0, import_node_path22.join)(dir, "node_modules", pkg, "bin", name));
|
|
8053
|
+
if (hit) return hit;
|
|
8054
|
+
const next = (0, import_node_path22.dirname)(dir);
|
|
8055
|
+
if (next === dir) break;
|
|
8056
|
+
dir = next;
|
|
8057
|
+
}
|
|
8058
|
+
return null;
|
|
8059
|
+
}
|
|
8060
|
+
function requireResolveBundledRipgrep(fromFile) {
|
|
8061
|
+
try {
|
|
8062
|
+
const req = (0, import_node_module2.createRequire)(fromFile);
|
|
8063
|
+
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
8064
|
+
return usableRipgrepPath((0, import_node_path22.join)((0, import_node_path22.dirname)(pkgJson), "bin", rgBinaryName()));
|
|
8065
|
+
} catch {
|
|
8066
|
+
return null;
|
|
8067
|
+
}
|
|
8068
|
+
}
|
|
8069
|
+
function resolveCursorRipgrepPath(opts) {
|
|
8070
|
+
const env = opts?.env ?? process.env;
|
|
8071
|
+
const fromEnv = usableRipgrepPath(env[RIPGREP_ENV]);
|
|
8072
|
+
if (fromEnv) return fromEnv;
|
|
8073
|
+
const fromPackaged = usableRipgrepPath(
|
|
8074
|
+
packagedCursorRipgrepCandidate(platformRipgrepPackage(), rgBinaryName())
|
|
8075
|
+
);
|
|
8076
|
+
if (fromPackaged) return fromPackaged;
|
|
8077
|
+
const start = opts?.startFile?.trim() || process.argv[1] || (0, import_node_url2.fileURLToPath)(import_meta2.url);
|
|
8078
|
+
return walkForBundledRipgrep(start) ?? requireResolveBundledRipgrep(start);
|
|
8079
|
+
}
|
|
8080
|
+
function cursorRipgrepEnv(opts) {
|
|
8081
|
+
const path2 = resolveCursorRipgrepPath(opts);
|
|
8082
|
+
return path2 ? { [RIPGREP_ENV]: path2 } : {};
|
|
8083
|
+
}
|
|
8084
|
+
var import_node_fs23, import_node_module2, import_node_path22, import_node_url2, import_meta2, RIPGREP_ENV;
|
|
8085
|
+
var init_cursor_ripgrep = __esm({
|
|
8086
|
+
"src/agents/cursor-ripgrep.ts"() {
|
|
8087
|
+
"use strict";
|
|
8088
|
+
import_node_fs23 = require("fs");
|
|
8089
|
+
import_node_module2 = require("module");
|
|
8090
|
+
import_node_path22 = require("path");
|
|
8091
|
+
import_node_url2 = require("url");
|
|
8092
|
+
init_node_launch();
|
|
8093
|
+
init_packaged_runtime();
|
|
8094
|
+
import_meta2 = {};
|
|
8095
|
+
RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
8096
|
+
}
|
|
8097
|
+
});
|
|
8098
|
+
|
|
7749
8099
|
// src/agents/cursor.ts
|
|
7750
8100
|
function resolveCursorApiKey() {
|
|
7751
8101
|
const fromEnv = (process.env.CURSOR_API_KEY || "").trim();
|
|
@@ -7785,51 +8135,55 @@ function entryDir() {
|
|
|
7785
8135
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
7786
8136
|
if (cjsDir) return cjsDir;
|
|
7787
8137
|
try {
|
|
7788
|
-
return (0,
|
|
8138
|
+
return (0, import_node_path23.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
7789
8139
|
} catch {
|
|
7790
8140
|
try {
|
|
7791
|
-
const req = (0,
|
|
7792
|
-
return (0,
|
|
8141
|
+
const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
|
|
8142
|
+
return (0, import_node_path23.dirname)(req.resolve("@sideboard-ai/core"));
|
|
7793
8143
|
} catch {
|
|
7794
8144
|
return process.cwd();
|
|
7795
8145
|
}
|
|
7796
8146
|
}
|
|
7797
8147
|
}
|
|
7798
8148
|
function cursorRunnerPath() {
|
|
8149
|
+
const packaged = packagedCursorRunnerPath();
|
|
8150
|
+
if (packaged) return packaged;
|
|
7799
8151
|
const root = entryDir();
|
|
7800
8152
|
const candidates = [
|
|
7801
|
-
(0,
|
|
7802
|
-
(0,
|
|
8153
|
+
(0, import_node_path23.join)(root, "agents", "cursor-runner.js"),
|
|
8154
|
+
(0, import_node_path23.join)(root, "agents", "cursor-runner.cjs"),
|
|
7803
8155
|
// If somehow resolved from package root instead of dist/
|
|
7804
|
-
(0,
|
|
7805
|
-
(0,
|
|
8156
|
+
(0, import_node_path23.join)(root, "dist", "agents", "cursor-runner.js"),
|
|
8157
|
+
(0, import_node_path23.join)(root, "dist", "agents", "cursor-runner.cjs"),
|
|
7806
8158
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
7807
|
-
(0,
|
|
7808
|
-
(0,
|
|
8159
|
+
(0, import_node_path23.join)(root, "cursor-runner.ts"),
|
|
8160
|
+
(0, import_node_path23.join)(root, "src", "agents", "cursor-runner.ts")
|
|
7809
8161
|
];
|
|
7810
8162
|
for (const candidate of candidates) {
|
|
7811
|
-
if ((0,
|
|
8163
|
+
if ((0, import_node_fs24.existsSync)(candidate)) return candidate;
|
|
7812
8164
|
}
|
|
7813
8165
|
return candidates[0];
|
|
7814
8166
|
}
|
|
7815
|
-
var
|
|
8167
|
+
var import_node_fs24, import_node_module3, import_node_path23, import_node_url3, import_sdk, import_meta3, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
|
|
7816
8168
|
var init_cursor = __esm({
|
|
7817
8169
|
"src/agents/cursor.ts"() {
|
|
7818
8170
|
"use strict";
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
8171
|
+
import_node_fs24 = require("fs");
|
|
8172
|
+
import_node_module3 = require("module");
|
|
8173
|
+
import_node_path23 = require("path");
|
|
8174
|
+
import_node_url3 = require("url");
|
|
7823
8175
|
import_sdk = require("@cursor/sdk");
|
|
7824
8176
|
init_run();
|
|
7825
8177
|
init_app_settings();
|
|
7826
8178
|
init_global_workspace();
|
|
7827
8179
|
init_cursor_events();
|
|
7828
8180
|
init_injected_mcp();
|
|
8181
|
+
init_cursor_ripgrep();
|
|
7829
8182
|
init_node_launch();
|
|
8183
|
+
init_packaged_runtime();
|
|
7830
8184
|
init_turn_input();
|
|
7831
8185
|
init_cursor_events();
|
|
7832
|
-
|
|
8186
|
+
import_meta3 = {};
|
|
7833
8187
|
FALLBACK_CURSOR_MODELS = [
|
|
7834
8188
|
{ id: "default", displayName: "Auto" },
|
|
7835
8189
|
{ id: "composer-2.5", displayName: "Composer 2.5" },
|
|
@@ -7896,6 +8250,7 @@ var init_cursor = __esm({
|
|
|
7896
8250
|
stdin: JSON.stringify(req),
|
|
7897
8251
|
env: {
|
|
7898
8252
|
...launch.env,
|
|
8253
|
+
...cursorRipgrepEnv({ startFile: runner }),
|
|
7899
8254
|
...apiKey ? { CURSOR_API_KEY: apiKey } : {}
|
|
7900
8255
|
}
|
|
7901
8256
|
};
|
|
@@ -7947,7 +8302,7 @@ async function listOpencodeModels() {
|
|
|
7947
8302
|
if (opencode === "opencode") {
|
|
7948
8303
|
const which = await run("which", ["opencode"], { reject: false });
|
|
7949
8304
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
7950
|
-
} else if (!(0,
|
|
8305
|
+
} else if (!(0, import_node_fs25.existsSync)(opencode)) {
|
|
7951
8306
|
return FALLBACK_OPENCODE_MODELS;
|
|
7952
8307
|
}
|
|
7953
8308
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -7977,11 +8332,11 @@ function usageFromOpencode(tokens) {
|
|
|
7977
8332
|
cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
|
|
7978
8333
|
};
|
|
7979
8334
|
}
|
|
7980
|
-
var
|
|
8335
|
+
var import_node_fs25, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
|
|
7981
8336
|
var init_opencode = __esm({
|
|
7982
8337
|
"src/agents/opencode.ts"() {
|
|
7983
8338
|
"use strict";
|
|
7984
|
-
|
|
8339
|
+
import_node_fs25 = require("fs");
|
|
7985
8340
|
init_run();
|
|
7986
8341
|
init_app_settings();
|
|
7987
8342
|
init_global_workspace();
|
|
@@ -8007,7 +8362,7 @@ var init_opencode = __esm({
|
|
|
8007
8362
|
async detect() {
|
|
8008
8363
|
const opencode = resolveAgentExecutable("opencode");
|
|
8009
8364
|
if (opencode !== "opencode") {
|
|
8010
|
-
if (!(0,
|
|
8365
|
+
if (!(0, import_node_fs25.existsSync)(opencode)) {
|
|
8011
8366
|
return {
|
|
8012
8367
|
agent: "opencode",
|
|
8013
8368
|
installed: false,
|
|
@@ -8804,40 +9159,40 @@ __export(plan_file_exports, {
|
|
|
8804
9159
|
writePlanFile: () => writePlanFile
|
|
8805
9160
|
});
|
|
8806
9161
|
function ensureAttachmentsGitignore2(worktreePath) {
|
|
8807
|
-
const gitignoreAbs = (0,
|
|
8808
|
-
if ((0,
|
|
8809
|
-
(0,
|
|
8810
|
-
(0,
|
|
9162
|
+
const gitignoreAbs = (0, import_node_path36.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
9163
|
+
if ((0, import_node_fs39.existsSync)(gitignoreAbs)) return;
|
|
9164
|
+
(0, import_node_fs39.mkdirSync)((0, import_node_path36.dirname)(gitignoreAbs), { recursive: true });
|
|
9165
|
+
(0, import_node_fs39.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
8811
9166
|
}
|
|
8812
9167
|
function planFileAbs(worktreePath) {
|
|
8813
|
-
return (0,
|
|
9168
|
+
return (0, import_node_path36.join)(worktreePath, PLAN_FILE_REL);
|
|
8814
9169
|
}
|
|
8815
9170
|
function readTextIfPresent2(abs) {
|
|
8816
|
-
if (!(0,
|
|
9171
|
+
if (!(0, import_node_fs39.existsSync)(abs)) return null;
|
|
8817
9172
|
try {
|
|
8818
|
-
const content = (0,
|
|
9173
|
+
const content = (0, import_node_fs39.readFileSync)(abs, "utf8");
|
|
8819
9174
|
return content.trim() ? content : null;
|
|
8820
9175
|
} catch {
|
|
8821
9176
|
return null;
|
|
8822
9177
|
}
|
|
8823
9178
|
}
|
|
8824
9179
|
function readPlanFile(worktreePath) {
|
|
8825
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
9180
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path36.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path36.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
8826
9181
|
}
|
|
8827
9182
|
function writePlanFile(worktreePath, content) {
|
|
8828
9183
|
ensureAttachmentsGitignore2(worktreePath);
|
|
8829
9184
|
const abs = planFileAbs(worktreePath);
|
|
8830
|
-
(0,
|
|
9185
|
+
(0, import_node_fs39.mkdirSync)((0, import_node_path36.dirname)(abs), { recursive: true });
|
|
8831
9186
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
8832
|
-
(0,
|
|
9187
|
+
(0, import_node_fs39.writeFileSync)(abs, body, "utf8");
|
|
8833
9188
|
return PLAN_FILE_REL;
|
|
8834
9189
|
}
|
|
8835
|
-
var
|
|
9190
|
+
var import_node_fs39, import_node_path36;
|
|
8836
9191
|
var init_plan_file = __esm({
|
|
8837
9192
|
"src/plan/plan-file.ts"() {
|
|
8838
9193
|
"use strict";
|
|
8839
|
-
|
|
8840
|
-
|
|
9194
|
+
import_node_fs39 = require("fs");
|
|
9195
|
+
import_node_path36 = require("path");
|
|
8841
9196
|
init_workspace_scratch();
|
|
8842
9197
|
init_plan_present();
|
|
8843
9198
|
init_plan_present();
|
|
@@ -8852,10 +9207,10 @@ __export(cursor_recover_exports, {
|
|
|
8852
9207
|
function recoverFinishedCursorRun(opts) {
|
|
8853
9208
|
const agentId = opts.agentId.trim();
|
|
8854
9209
|
if (!agentId) return null;
|
|
8855
|
-
const runsPath = (0,
|
|
8856
|
-
if (!(0,
|
|
9210
|
+
const runsPath = (0, import_node_path37.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
|
|
9211
|
+
if (!(0, import_node_fs40.existsSync)(runsPath)) return null;
|
|
8857
9212
|
try {
|
|
8858
|
-
const lines = (0,
|
|
9213
|
+
const lines = (0, import_node_fs40.readFileSync)(runsPath, "utf8").split("\n");
|
|
8859
9214
|
let best = null;
|
|
8860
9215
|
for (const line of lines) {
|
|
8861
9216
|
const trimmed = line.trim();
|
|
@@ -8881,12 +9236,12 @@ function recoverFinishedCursorRun(opts) {
|
|
|
8881
9236
|
return null;
|
|
8882
9237
|
}
|
|
8883
9238
|
}
|
|
8884
|
-
var
|
|
9239
|
+
var import_node_fs40, import_node_path37;
|
|
8885
9240
|
var init_cursor_recover = __esm({
|
|
8886
9241
|
"src/agents/cursor-recover.ts"() {
|
|
8887
9242
|
"use strict";
|
|
8888
|
-
|
|
8889
|
-
|
|
9243
|
+
import_node_fs40 = require("fs");
|
|
9244
|
+
import_node_path37 = require("path");
|
|
8890
9245
|
init_paths();
|
|
8891
9246
|
}
|
|
8892
9247
|
});
|
|
@@ -9040,6 +9395,7 @@ __export(index_exports, {
|
|
|
9040
9395
|
cleanupOrphanWorktrees: () => cleanupOrphanWorktrees,
|
|
9041
9396
|
cloneRepoIntoSideboard: () => cloneRepoIntoSideboard,
|
|
9042
9397
|
codexAdapter: () => codexAdapter,
|
|
9398
|
+
codexSandboxWritableRootsArgs: () => codexSandboxWritableRootsArgs,
|
|
9043
9399
|
codexUnattendedGitConfigArgs: () => codexUnattendedGitConfigArgs,
|
|
9044
9400
|
coerceOrchestratorAgent: () => coerceOrchestratorAgent,
|
|
9045
9401
|
collectTakenTeamSlugs: () => collectTakenTeamSlugs,
|
|
@@ -9156,6 +9512,7 @@ __export(index_exports, {
|
|
|
9156
9512
|
getPr: () => getPr,
|
|
9157
9513
|
getPrChecks: () => getPrChecks,
|
|
9158
9514
|
getPrDetails: () => getPrDetails,
|
|
9515
|
+
getPrForHeadBranch: () => getPrForHeadBranch,
|
|
9159
9516
|
getPrMeta: () => getPrMeta,
|
|
9160
9517
|
getPrStack: () => getPrStack,
|
|
9161
9518
|
getRepoSetupInfo: () => getRepoSetupInfo,
|
|
@@ -9192,6 +9549,7 @@ __export(index_exports, {
|
|
|
9192
9549
|
isCloudCoordinatorThread: () => isCloudCoordinatorThread,
|
|
9193
9550
|
isConductorBundledCli: () => isConductorBundledCli,
|
|
9194
9551
|
isCursorAutoModel: () => isCursorAutoModel,
|
|
9552
|
+
isDefaultishSourceRef: () => isDefaultishSourceRef,
|
|
9195
9553
|
isDirty: () => isDirty,
|
|
9196
9554
|
isGhRateLimitError: () => isGhRateLimitError,
|
|
9197
9555
|
isGlobalRepoPath: () => isGlobalRepoPath,
|
|
@@ -9258,8 +9616,10 @@ __export(index_exports, {
|
|
|
9258
9616
|
maybeCompactContext: () => maybeCompactContext,
|
|
9259
9617
|
mcpAllowTools: () => mcpAllowTools,
|
|
9260
9618
|
mcpAuthWarnings: () => mcpAuthWarnings,
|
|
9619
|
+
mergeAgentGitAuthEnv: () => mergeAgentGitAuthEnv,
|
|
9261
9620
|
mergePr: () => mergePr,
|
|
9262
9621
|
mergePrStack: () => mergePrStack,
|
|
9622
|
+
mergeSideboardIntoMcpServersJson: () => mergeSideboardIntoMcpServersJson,
|
|
9263
9623
|
mergeUsage: () => mergeUsage,
|
|
9264
9624
|
nextPastedTextName: () => nextPastedTextName,
|
|
9265
9625
|
nextThinkingEffort: () => nextThinkingEffort,
|
|
@@ -9310,6 +9670,7 @@ __export(index_exports, {
|
|
|
9310
9670
|
recordSlackOutboundWatch: () => recordSlackOutboundWatch,
|
|
9311
9671
|
refreshGitHubAuth: () => refreshGitHubAuth,
|
|
9312
9672
|
refreshSlackReplyBadges: () => refreshSlackReplyBadges,
|
|
9673
|
+
registerPackagedUserMcpClients: () => registerPackagedUserMcpClients,
|
|
9313
9674
|
releaseCaffeinateHoldForThread: () => releaseCaffeinateHoldForThread,
|
|
9314
9675
|
removeWorkspace: () => removeWorkspace,
|
|
9315
9676
|
removeWorktree: () => removeWorktree,
|
|
@@ -9318,9 +9679,11 @@ __export(index_exports, {
|
|
|
9318
9679
|
requestReview: () => requestReview,
|
|
9319
9680
|
requireAgent: () => requireAgent,
|
|
9320
9681
|
resetGhStackDetectCache: () => resetGhStackDetectCache,
|
|
9682
|
+
resetGithubAgentTokenMemo: () => resetGithubAgentTokenMemo,
|
|
9321
9683
|
resolveAgentExecutable: () => resolveAgentExecutable,
|
|
9322
9684
|
resolveAgentGitAuthEnv: () => resolveAgentGitAuthEnv,
|
|
9323
9685
|
resolveClaudeExecutable: () => resolveClaudeExecutable,
|
|
9686
|
+
resolveCodexGitWritableRoots: () => resolveCodexGitWritableRoots,
|
|
9324
9687
|
resolveCommandBinarySync: () => resolveCommandBinarySync,
|
|
9325
9688
|
resolveConductorCursorAgentId: () => resolveConductorCursorAgentId,
|
|
9326
9689
|
resolveCursorModelId: () => resolveCursorModelId,
|
|
@@ -9337,6 +9700,7 @@ __export(index_exports, {
|
|
|
9337
9700
|
resolveNewThreadOptions: () => resolveNewThreadOptions,
|
|
9338
9701
|
resolvePlanMarkdown: () => resolvePlanMarkdown,
|
|
9339
9702
|
resolvePrSelector: () => resolvePrSelector,
|
|
9703
|
+
resolvePrSelectors: () => resolvePrSelectors,
|
|
9340
9704
|
resolveQuotaFallbackAgent: () => resolveQuotaFallbackAgent,
|
|
9341
9705
|
resolveRepoRoot: () => resolveRepoRoot,
|
|
9342
9706
|
resolveReviewGuidelines: () => resolveReviewGuidelines,
|
|
@@ -9359,6 +9723,7 @@ __export(index_exports, {
|
|
|
9359
9723
|
sanitizeMcpServerName: () => sanitizeMcpServerName,
|
|
9360
9724
|
saveAppSettings: () => saveAppSettings,
|
|
9361
9725
|
saveLinearOAuth: () => saveLinearOAuth,
|
|
9726
|
+
scrubGithubTokensFromChildEnv: () => scrubGithubTokensFromChildEnv,
|
|
9362
9727
|
secureFileUnlocksWith: () => secureFileUnlocksWith,
|
|
9363
9728
|
setCaffeinateHold: () => setCaffeinateHold,
|
|
9364
9729
|
setHttpFetchImpl: () => setHttpFetchImpl,
|
|
@@ -9429,7 +9794,10 @@ __export(index_exports, {
|
|
|
9429
9794
|
updateLinearIssue: () => updateLinearIssue,
|
|
9430
9795
|
updateOpencodeSettings: () => updateOpencodeSettings,
|
|
9431
9796
|
updateThread: () => updateThread,
|
|
9797
|
+
userClaudeMcpConfigPath: () => userClaudeMcpConfigPath,
|
|
9798
|
+
userCursorMcpConfigPath: () => userCursorMcpConfigPath,
|
|
9432
9799
|
validateLinearApiKey: () => validateLinearApiKey,
|
|
9800
|
+
warmGithubAgentAuth: () => warmGithubAgentAuth,
|
|
9433
9801
|
withAgentInstructions: () => withAgentInstructions,
|
|
9434
9802
|
withExportedPath: () => withExportedPath,
|
|
9435
9803
|
withThreadLock: () => withThreadLock,
|
|
@@ -10513,10 +10881,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
10513
10881
|
const env = childEnvWithAppSettings(cmd.env);
|
|
10514
10882
|
try {
|
|
10515
10883
|
if (isOrchestratorThread(thread)) {
|
|
10516
|
-
|
|
10884
|
+
mergeAgentGitAuthEnv(env, await resolveAgentGitAuthEnv(env));
|
|
10517
10885
|
} else {
|
|
10518
|
-
|
|
10519
|
-
Object.assign(env, originEnv);
|
|
10886
|
+
mergeAgentGitAuthEnv(env, await originGhRepoEnv(thread.worktreePath, { env }));
|
|
10520
10887
|
}
|
|
10521
10888
|
} catch (err) {
|
|
10522
10889
|
const detail = err instanceof Error ? err.message : String(err);
|
|
@@ -10611,8 +10978,8 @@ init_usage();
|
|
|
10611
10978
|
init_claude_mcp();
|
|
10612
10979
|
|
|
10613
10980
|
// src/agents/instructions.ts
|
|
10614
|
-
var
|
|
10615
|
-
var
|
|
10981
|
+
var import_node_fs26 = require("fs");
|
|
10982
|
+
var import_node_path24 = require("path");
|
|
10616
10983
|
init_git_auth_mode();
|
|
10617
10984
|
init_worktree_labels();
|
|
10618
10985
|
function normPath3(p) {
|
|
@@ -10745,9 +11112,10 @@ function formatArtifactDirective() {
|
|
|
10745
11112
|
"Files / media browser (CMS file manager column):",
|
|
10746
11113
|
"4) Call Sideboard MCP `present_files` with optional title, path, and datasource (brightsy|memory).",
|
|
10747
11114
|
" Opens the Files column for browse/upload/pick. Do NOT say a file manager UI is missing.",
|
|
10748
|
-
"Multiple-choice questions
|
|
10749
|
-
"5) Call Sideboard MCP `ask_user` when
|
|
10750
|
-
"
|
|
11115
|
+
"Multiple-choice questions:",
|
|
11116
|
+
"5) Call Sideboard MCP `ask_user` only when work is blocked on choosing among a few concrete options (approach forks, which API, auth vs cookies). First write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it). Include a description on every option. After calling, stop and wait for their next message with answers. If you are asking a real multiple-choice, use ask_user rather than chat bullets so Sideboard shows the composer picker.",
|
|
11117
|
+
"Do not call ask_user for greetings, check-ins, \u201Chello\u201D, open-ended how-can-I-help, or to invent a menu of possible next tasks \u2014 reply in chat. If one option is the obvious default, proceed without asking.",
|
|
11118
|
+
"Never say artifacts, CMS UI, or the Files column are unavailable. Prefer present_schema for list/edit/publish; present_files for storage UI; html fences for standalone pages; ask_user only for those blocked predefined-option questions."
|
|
10751
11119
|
].join("\n");
|
|
10752
11120
|
}
|
|
10753
11121
|
function formatUiReminder() {
|
|
@@ -10758,7 +11126,7 @@ function formatUiReminder() {
|
|
|
10758
11126
|
"CMS forms/tables: MCP present_schema (Brightsy resource_id or inline schema+schemaUi).",
|
|
10759
11127
|
"Files column: MCP present_files (brightsy account storage or memory).",
|
|
10760
11128
|
"Do not say artifacts/CMS UI are unavailable.",
|
|
10761
|
-
"
|
|
11129
|
+
"ask_user: only when blocked on a real multiple-choice (approach fork, which API). Never for hellos, check-ins, or \u201Cwhat next?\u201D menus \u2014 reply in chat."
|
|
10762
11130
|
].join(" ");
|
|
10763
11131
|
}
|
|
10764
11132
|
var FILES_BY_AGENT = {
|
|
@@ -10782,11 +11150,11 @@ function loadAgentInstructions(worktreePath, agent) {
|
|
|
10782
11150
|
const out = [];
|
|
10783
11151
|
for (const rel of candidates) {
|
|
10784
11152
|
if (seenPaths.has(rel)) continue;
|
|
10785
|
-
const abs = (0,
|
|
10786
|
-
if (!(0,
|
|
11153
|
+
const abs = (0, import_node_path24.join)(worktreePath, rel);
|
|
11154
|
+
if (!(0, import_node_fs26.existsSync)(abs)) continue;
|
|
10787
11155
|
try {
|
|
10788
|
-
if (!(0,
|
|
10789
|
-
let content = (0,
|
|
11156
|
+
if (!(0, import_node_fs26.statSync)(abs).isFile()) continue;
|
|
11157
|
+
let content = (0, import_node_fs26.readFileSync)(abs, "utf8");
|
|
10790
11158
|
if (!content.trim()) continue;
|
|
10791
11159
|
if (content.length > MAX_CHARS_PER_FILE) {
|
|
10792
11160
|
content = `${content.slice(0, MAX_CHARS_PER_FILE)}
|
|
@@ -10868,9 +11236,9 @@ async function requireAgent(agent, opts) {
|
|
|
10868
11236
|
init_settings();
|
|
10869
11237
|
|
|
10870
11238
|
// src/hook/conductor.ts
|
|
10871
|
-
var
|
|
11239
|
+
var import_node_fs27 = require("fs");
|
|
10872
11240
|
var import_node_net = require("net");
|
|
10873
|
-
var
|
|
11241
|
+
var import_node_path25 = require("path");
|
|
10874
11242
|
var import_execa4 = require("execa");
|
|
10875
11243
|
var import_node_readline3 = require("readline");
|
|
10876
11244
|
init_settings();
|
|
@@ -10885,9 +11253,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
10885
11253
|
return new RegExp(`^${escaped}$`).test(name);
|
|
10886
11254
|
}
|
|
10887
11255
|
function readWorktreeInclude(repoPath) {
|
|
10888
|
-
const path2 = (0,
|
|
10889
|
-
if (!(0,
|
|
10890
|
-
return (0,
|
|
11256
|
+
const path2 = (0, import_node_path25.join)(repoPath, ".worktreeinclude");
|
|
11257
|
+
if (!(0, import_node_fs27.existsSync)(path2)) return [];
|
|
11258
|
+
return (0, import_node_fs27.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
10891
11259
|
}
|
|
10892
11260
|
function resolveFilesToCopy(repoPath) {
|
|
10893
11261
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -10897,10 +11265,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
10897
11265
|
if (settings?.fileIncludeGlobs?.length) {
|
|
10898
11266
|
const matched = [];
|
|
10899
11267
|
try {
|
|
10900
|
-
for (const entry of (0,
|
|
11268
|
+
for (const entry of (0, import_node_fs27.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
10901
11269
|
if (!entry.isFile()) continue;
|
|
10902
11270
|
for (const glob of settings.fileIncludeGlobs) {
|
|
10903
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
11271
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path25.basename)(glob), entry.name)) {
|
|
10904
11272
|
matched.push(entry.name);
|
|
10905
11273
|
break;
|
|
10906
11274
|
}
|
|
@@ -10912,7 +11280,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
10912
11280
|
}
|
|
10913
11281
|
const defaults = [];
|
|
10914
11282
|
try {
|
|
10915
|
-
for (const entry of (0,
|
|
11283
|
+
for (const entry of (0, import_node_fs27.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
10916
11284
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
10917
11285
|
defaults.push(entry.name);
|
|
10918
11286
|
}
|
|
@@ -10926,11 +11294,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
10926
11294
|
const patterns = resolveFilesToCopy(repoPath);
|
|
10927
11295
|
const copied = [];
|
|
10928
11296
|
for (const rel of patterns) {
|
|
10929
|
-
const src = (0,
|
|
10930
|
-
if (!(0,
|
|
10931
|
-
const dest = (0,
|
|
10932
|
-
(0,
|
|
10933
|
-
(0,
|
|
11297
|
+
const src = (0, import_node_path25.join)(repoPath, rel);
|
|
11298
|
+
if (!(0, import_node_fs27.existsSync)(src)) continue;
|
|
11299
|
+
const dest = (0, import_node_path25.join)(worktreePath, rel);
|
|
11300
|
+
(0, import_node_fs27.mkdirSync)((0, import_node_path25.dirname)(dest), { recursive: true });
|
|
11301
|
+
(0, import_node_fs27.copyFileSync)(src, dest);
|
|
10934
11302
|
copied.push(rel);
|
|
10935
11303
|
}
|
|
10936
11304
|
return copied;
|
|
@@ -10966,7 +11334,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
10966
11334
|
const env = stripNestedElectronEnv({
|
|
10967
11335
|
...baseEnv ?? process.env
|
|
10968
11336
|
});
|
|
10969
|
-
const name = opts.workspaceName ?? (0,
|
|
11337
|
+
const name = opts.workspaceName ?? (0, import_node_path25.basename)(opts.worktreePath);
|
|
10970
11338
|
const ports = opts.ports ?? [];
|
|
10971
11339
|
const primary = ports[0];
|
|
10972
11340
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -11052,7 +11420,10 @@ async function spawnWorkspaceScript(command, opts) {
|
|
|
11052
11420
|
loginEnv
|
|
11053
11421
|
);
|
|
11054
11422
|
try {
|
|
11055
|
-
|
|
11423
|
+
mergeAgentGitAuthEnv(
|
|
11424
|
+
env,
|
|
11425
|
+
await resolveAgentGitAuthEnv(env, { cwd: opts.worktreePath })
|
|
11426
|
+
);
|
|
11056
11427
|
} catch {
|
|
11057
11428
|
}
|
|
11058
11429
|
const shell = process.platform === "darwin" ? "zsh" : "bash";
|
|
@@ -11224,12 +11595,12 @@ init_convention_setup();
|
|
|
11224
11595
|
init_cursor_worktrees();
|
|
11225
11596
|
|
|
11226
11597
|
// src/diff/diff.ts
|
|
11227
|
-
var
|
|
11228
|
-
var
|
|
11598
|
+
var import_node_fs28 = require("fs");
|
|
11599
|
+
var import_node_path26 = require("path");
|
|
11229
11600
|
init_run();
|
|
11230
11601
|
init_worktree();
|
|
11231
11602
|
async function inspectGitWorktree(worktreePath) {
|
|
11232
|
-
if (!worktreePath || !(0,
|
|
11603
|
+
if (!worktreePath || !(0, import_node_fs28.existsSync)(worktreePath)) return "missing_worktree";
|
|
11233
11604
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
11234
11605
|
reject: false
|
|
11235
11606
|
});
|
|
@@ -11237,7 +11608,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
11237
11608
|
return "ok";
|
|
11238
11609
|
}
|
|
11239
11610
|
async function initializeGitRepository(worktreePath) {
|
|
11240
|
-
if (!worktreePath || !(0,
|
|
11611
|
+
if (!worktreePath || !(0, import_node_fs28.existsSync)(worktreePath)) {
|
|
11241
11612
|
throw new Error("Worktree not found");
|
|
11242
11613
|
}
|
|
11243
11614
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -11372,11 +11743,11 @@ new file mode 100644
|
|
|
11372
11743
|
};
|
|
11373
11744
|
}
|
|
11374
11745
|
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
11375
|
-
const abs = (0,
|
|
11746
|
+
const abs = (0, import_node_path26.join)(worktreePath, path2);
|
|
11376
11747
|
try {
|
|
11377
|
-
const st = (0,
|
|
11748
|
+
const st = (0, import_node_fs28.statSync)(abs);
|
|
11378
11749
|
if (st.isFile() && st.size > maxHunk) {
|
|
11379
|
-
const buf = (0,
|
|
11750
|
+
const buf = (0, import_node_fs28.readFileSync)(abs).subarray(0, maxHunk);
|
|
11380
11751
|
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
11381
11752
|
}
|
|
11382
11753
|
} catch {
|
|
@@ -11877,8 +12248,8 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
|
11877
12248
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
11878
12249
|
assertSafeRelativePath(relativePath);
|
|
11879
12250
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
11880
|
-
const abs = (0,
|
|
11881
|
-
const st = (0,
|
|
12251
|
+
const abs = (0, import_node_path26.join)(worktreePath, relativePath);
|
|
12252
|
+
const st = (0, import_node_fs28.statSync)(abs);
|
|
11882
12253
|
if (!st.isFile()) {
|
|
11883
12254
|
throw new Error(`Not a file: ${relativePath}`);
|
|
11884
12255
|
}
|
|
@@ -11887,7 +12258,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
11887
12258
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
11888
12259
|
);
|
|
11889
12260
|
}
|
|
11890
|
-
const buf = (0,
|
|
12261
|
+
const buf = (0, import_node_fs28.readFileSync)(abs);
|
|
11891
12262
|
return {
|
|
11892
12263
|
path: relativePath,
|
|
11893
12264
|
contentBase64: buf.toString("base64"),
|
|
@@ -11897,12 +12268,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
11897
12268
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
11898
12269
|
assertSafeRelativePath(relativePath);
|
|
11899
12270
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
11900
|
-
const abs = (0,
|
|
11901
|
-
const st = (0,
|
|
12271
|
+
const abs = (0, import_node_path26.join)(worktreePath, relativePath);
|
|
12272
|
+
const st = (0, import_node_fs28.statSync)(abs);
|
|
11902
12273
|
if (!st.isFile()) {
|
|
11903
12274
|
throw new Error(`Not a file: ${relativePath}`);
|
|
11904
12275
|
}
|
|
11905
|
-
const buf = (0,
|
|
12276
|
+
const buf = (0, import_node_fs28.readFileSync)(abs);
|
|
11906
12277
|
if (isImageRelativePath(relativePath)) {
|
|
11907
12278
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
11908
12279
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -11945,9 +12316,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
11945
12316
|
}
|
|
11946
12317
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
11947
12318
|
assertSafeRelativePath(relativePath);
|
|
11948
|
-
const abs = (0,
|
|
11949
|
-
(0,
|
|
11950
|
-
(0,
|
|
12319
|
+
const abs = (0, import_node_path26.join)(worktreePath, relativePath);
|
|
12320
|
+
(0, import_node_fs28.mkdirSync)((0, import_node_path26.dirname)(abs), { recursive: true });
|
|
12321
|
+
(0, import_node_fs28.writeFileSync)(abs, content, "utf8");
|
|
11951
12322
|
return { path: relativePath };
|
|
11952
12323
|
}
|
|
11953
12324
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -11966,9 +12337,9 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
11966
12337
|
}
|
|
11967
12338
|
|
|
11968
12339
|
// src/skills/discover.ts
|
|
11969
|
-
var
|
|
11970
|
-
var
|
|
11971
|
-
var
|
|
12340
|
+
var import_node_fs29 = require("fs");
|
|
12341
|
+
var import_node_os10 = require("os");
|
|
12342
|
+
var import_node_path27 = require("path");
|
|
11972
12343
|
function toCommand(name) {
|
|
11973
12344
|
return name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
11974
12345
|
}
|
|
@@ -12000,7 +12371,7 @@ function parseFrontmatter(content) {
|
|
|
12000
12371
|
}
|
|
12001
12372
|
function readSkill(skillMd, source) {
|
|
12002
12373
|
try {
|
|
12003
|
-
const content = (0,
|
|
12374
|
+
const content = (0, import_node_fs29.readFileSync)(skillMd, "utf8");
|
|
12004
12375
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
12005
12376
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
12006
12377
|
const name = fmName || dirName;
|
|
@@ -12019,19 +12390,19 @@ function readSkill(skillMd, source) {
|
|
|
12019
12390
|
}
|
|
12020
12391
|
}
|
|
12021
12392
|
function scanSkillsDir(dir, source, out) {
|
|
12022
|
-
if (!(0,
|
|
12393
|
+
if (!(0, import_node_fs29.existsSync)(dir)) return;
|
|
12023
12394
|
let entries;
|
|
12024
12395
|
try {
|
|
12025
|
-
entries = (0,
|
|
12396
|
+
entries = (0, import_node_fs29.readdirSync)(dir);
|
|
12026
12397
|
} catch {
|
|
12027
12398
|
return;
|
|
12028
12399
|
}
|
|
12029
12400
|
for (const entry of entries) {
|
|
12030
12401
|
if (entry.startsWith(".")) continue;
|
|
12031
|
-
const skillMd = (0,
|
|
12032
|
-
if (!(0,
|
|
12402
|
+
const skillMd = (0, import_node_path27.join)(dir, entry, "SKILL.md");
|
|
12403
|
+
if (!(0, import_node_fs29.existsSync)(skillMd)) continue;
|
|
12033
12404
|
try {
|
|
12034
|
-
if (!(0,
|
|
12405
|
+
if (!(0, import_node_fs29.statSync)(skillMd).isFile()) continue;
|
|
12035
12406
|
} catch {
|
|
12036
12407
|
continue;
|
|
12037
12408
|
}
|
|
@@ -12040,24 +12411,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
12040
12411
|
}
|
|
12041
12412
|
}
|
|
12042
12413
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
12043
|
-
if (!(0,
|
|
12414
|
+
if (!(0, import_node_fs29.existsSync)(pluginsRoot)) return;
|
|
12044
12415
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
12045
12416
|
if (depth > 7) return;
|
|
12046
12417
|
let entries;
|
|
12047
12418
|
try {
|
|
12048
|
-
entries = (0,
|
|
12419
|
+
entries = (0, import_node_fs29.readdirSync)(dir);
|
|
12049
12420
|
} catch {
|
|
12050
12421
|
return;
|
|
12051
12422
|
}
|
|
12052
12423
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
12053
|
-
const skill = readSkill((0,
|
|
12424
|
+
const skill = readSkill((0, import_node_path27.join)(dir, "SKILL.md"), "cli");
|
|
12054
12425
|
if (skill) out.push(skill);
|
|
12055
12426
|
}
|
|
12056
12427
|
for (const entry of entries) {
|
|
12057
12428
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
12058
|
-
const full = (0,
|
|
12429
|
+
const full = (0, import_node_path27.join)(dir, entry);
|
|
12059
12430
|
try {
|
|
12060
|
-
if (!(0,
|
|
12431
|
+
if (!(0, import_node_fs29.statSync)(full).isDirectory()) continue;
|
|
12061
12432
|
} catch {
|
|
12062
12433
|
continue;
|
|
12063
12434
|
}
|
|
@@ -12072,20 +12443,20 @@ function scanClaudePluginSkills(pluginsRoot, out) {
|
|
|
12072
12443
|
walk(pluginsRoot, 0, false);
|
|
12073
12444
|
}
|
|
12074
12445
|
function discoverSkills(worktreePath) {
|
|
12075
|
-
const home = (0,
|
|
12446
|
+
const home = (0, import_node_os10.homedir)();
|
|
12076
12447
|
const collected = [];
|
|
12077
12448
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
12078
|
-
scanSkillsDir((0,
|
|
12449
|
+
scanSkillsDir((0, import_node_path27.join)(worktreePath, rel), "workspace", collected);
|
|
12079
12450
|
}
|
|
12080
12451
|
for (const abs of [
|
|
12081
|
-
(0,
|
|
12082
|
-
(0,
|
|
12083
|
-
(0,
|
|
12084
|
-
(0,
|
|
12452
|
+
(0, import_node_path27.join)(home, ".claude/skills"),
|
|
12453
|
+
(0, import_node_path27.join)(home, ".cursor/skills"),
|
|
12454
|
+
(0, import_node_path27.join)(home, ".sideboard/skills"),
|
|
12455
|
+
(0, import_node_path27.join)(home, ".brightsy/skills")
|
|
12085
12456
|
]) {
|
|
12086
12457
|
scanSkillsDir(abs, "user", collected);
|
|
12087
12458
|
}
|
|
12088
|
-
scanClaudePluginSkills((0,
|
|
12459
|
+
scanClaudePluginSkills((0, import_node_path27.join)(home, ".claude/plugins"), collected);
|
|
12089
12460
|
const rank = { workspace: 0, user: 1, cli: 2 };
|
|
12090
12461
|
const byCommand = /* @__PURE__ */ new Map();
|
|
12091
12462
|
for (const skill of collected) {
|
|
@@ -12097,7 +12468,7 @@ function discoverSkills(worktreePath) {
|
|
|
12097
12468
|
return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
|
|
12098
12469
|
}
|
|
12099
12470
|
function readSkillBody(skillPath, maxChars = 12e3) {
|
|
12100
|
-
const raw = (0,
|
|
12471
|
+
const raw = (0, import_node_fs29.readFileSync)(skillPath, "utf8");
|
|
12101
12472
|
if (raw.startsWith("---")) {
|
|
12102
12473
|
const end = raw.indexOf("\n---", 3);
|
|
12103
12474
|
if (end >= 0) {
|
|
@@ -12238,8 +12609,8 @@ function buildDiffCommentAttachment(input) {
|
|
|
12238
12609
|
}
|
|
12239
12610
|
|
|
12240
12611
|
// src/composer/stage-files.ts
|
|
12241
|
-
var
|
|
12242
|
-
var
|
|
12612
|
+
var import_node_fs30 = require("fs");
|
|
12613
|
+
var import_node_path28 = require("path");
|
|
12243
12614
|
var import_node_crypto5 = require("crypto");
|
|
12244
12615
|
init_workspace_scratch();
|
|
12245
12616
|
var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
@@ -12265,7 +12636,7 @@ var IMAGE_MIME_BY_EXT = {
|
|
|
12265
12636
|
var MAX_INLINE_BYTES = 4e5;
|
|
12266
12637
|
var MAX_PREVIEW_BYTES = 5e6;
|
|
12267
12638
|
function fileExtension(filePath) {
|
|
12268
|
-
const base = (0,
|
|
12639
|
+
const base = (0, import_node_path28.basename)(filePath).toLowerCase();
|
|
12269
12640
|
return base.includes(".") ? base.split(".").pop() || "" : "";
|
|
12270
12641
|
}
|
|
12271
12642
|
function isImageFilePath(filePath) {
|
|
@@ -12275,22 +12646,22 @@ function imageMimeType(filePath) {
|
|
|
12275
12646
|
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
12276
12647
|
}
|
|
12277
12648
|
function ensureAttachmentsDir(worktreePath) {
|
|
12278
|
-
const dir = (0,
|
|
12279
|
-
(0,
|
|
12280
|
-
const gi = (0,
|
|
12281
|
-
if (!(0,
|
|
12282
|
-
(0,
|
|
12649
|
+
const dir = (0, import_node_path28.join)(worktreePath, ATTACHMENTS_DIR);
|
|
12650
|
+
(0, import_node_fs30.mkdirSync)(dir, { recursive: true });
|
|
12651
|
+
const gi = (0, import_node_path28.join)(dir, ".gitignore");
|
|
12652
|
+
if (!(0, import_node_fs30.existsSync)(gi)) {
|
|
12653
|
+
(0, import_node_fs30.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
|
|
12283
12654
|
}
|
|
12284
12655
|
return dir;
|
|
12285
12656
|
}
|
|
12286
12657
|
function uniqueAttachmentName(dir, originalName) {
|
|
12287
12658
|
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
12288
|
-
if (!(0,
|
|
12289
|
-
const ext = (0,
|
|
12659
|
+
if (!(0, import_node_fs30.existsSync)((0, import_node_path28.join)(dir, safe))) return safe;
|
|
12660
|
+
const ext = (0, import_node_path28.extname)(safe);
|
|
12290
12661
|
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
12291
12662
|
for (let i = 1; i < 1e4; i++) {
|
|
12292
12663
|
const candidate = `${stem}-${i}${ext}`;
|
|
12293
|
-
if (!(0,
|
|
12664
|
+
if (!(0, import_node_fs30.existsSync)((0, import_node_path28.join)(dir, candidate))) return candidate;
|
|
12294
12665
|
}
|
|
12295
12666
|
return `${stem}-${(0, import_node_crypto5.randomUUID)()}${ext}`;
|
|
12296
12667
|
}
|
|
@@ -12342,9 +12713,9 @@ function attachmentFromBuffer(name, buf, opts) {
|
|
|
12342
12713
|
};
|
|
12343
12714
|
}
|
|
12344
12715
|
function attachmentFromAbsolutePath(absolutePath) {
|
|
12345
|
-
const name = (0,
|
|
12716
|
+
const name = (0, import_node_path28.basename)(absolutePath);
|
|
12346
12717
|
try {
|
|
12347
|
-
const st = (0,
|
|
12718
|
+
const st = (0, import_node_fs30.statSync)(absolutePath);
|
|
12348
12719
|
if (!st.isFile()) {
|
|
12349
12720
|
return {
|
|
12350
12721
|
id: (0, import_node_crypto5.randomUUID)(),
|
|
@@ -12353,7 +12724,7 @@ function attachmentFromAbsolutePath(absolutePath) {
|
|
|
12353
12724
|
content: `(not a file: ${absolutePath})`
|
|
12354
12725
|
};
|
|
12355
12726
|
}
|
|
12356
|
-
const buf = (0,
|
|
12727
|
+
const buf = (0, import_node_fs30.readFileSync)(absolutePath);
|
|
12357
12728
|
return attachmentFromBuffer(name, buf, { sourceLabel: absolutePath });
|
|
12358
12729
|
} catch (err) {
|
|
12359
12730
|
return {
|
|
@@ -12369,15 +12740,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
|
12369
12740
|
const dir = ensureAttachmentsDir(worktreePath);
|
|
12370
12741
|
const out = [];
|
|
12371
12742
|
for (const abs of absolutePaths) {
|
|
12372
|
-
const originalName = (0,
|
|
12743
|
+
const originalName = (0, import_node_path28.basename)(abs);
|
|
12373
12744
|
try {
|
|
12374
|
-
const st = (0,
|
|
12745
|
+
const st = (0, import_node_fs30.statSync)(abs);
|
|
12375
12746
|
if (!st.isFile()) continue;
|
|
12376
12747
|
const name = uniqueAttachmentName(dir, originalName);
|
|
12377
|
-
const destAbs = (0,
|
|
12378
|
-
(0,
|
|
12748
|
+
const destAbs = (0, import_node_path28.join)(dir, name);
|
|
12749
|
+
(0, import_node_fs30.copyFileSync)(abs, destAbs);
|
|
12379
12750
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
12380
|
-
const buf = (0,
|
|
12751
|
+
const buf = (0, import_node_fs30.readFileSync)(destAbs);
|
|
12381
12752
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
12382
12753
|
} catch (err) {
|
|
12383
12754
|
out.push({
|
|
@@ -12399,8 +12770,8 @@ function stageBuffersAsAttachments(worktreePath, buffers) {
|
|
|
12399
12770
|
try {
|
|
12400
12771
|
const buf = Buffer.from(item.dataBase64, "base64");
|
|
12401
12772
|
const name = uniqueAttachmentName(dir, originalName);
|
|
12402
|
-
const destAbs = (0,
|
|
12403
|
-
(0,
|
|
12773
|
+
const destAbs = (0, import_node_path28.join)(dir, name);
|
|
12774
|
+
(0, import_node_fs30.writeFileSync)(destAbs, buf);
|
|
12404
12775
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
12405
12776
|
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
12406
12777
|
} catch (err) {
|
|
@@ -12436,18 +12807,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
12436
12807
|
if (!rel || rel.includes("..") || rel.startsWith("/")) {
|
|
12437
12808
|
out.push({
|
|
12438
12809
|
id: (0, import_node_crypto5.randomUUID)(),
|
|
12439
|
-
name: (0,
|
|
12810
|
+
name: (0, import_node_path28.basename)(rel) || "file",
|
|
12440
12811
|
kind: "file",
|
|
12441
12812
|
content: `(invalid path: ${rel})`
|
|
12442
12813
|
});
|
|
12443
12814
|
continue;
|
|
12444
12815
|
}
|
|
12445
|
-
const name = (0,
|
|
12816
|
+
const name = (0, import_node_path28.basename)(rel);
|
|
12446
12817
|
try {
|
|
12447
|
-
const abs = (0,
|
|
12448
|
-
const st = (0,
|
|
12818
|
+
const abs = (0, import_node_path28.join)(worktreePath, rel);
|
|
12819
|
+
const st = (0, import_node_fs30.statSync)(abs);
|
|
12449
12820
|
if (!st.isFile()) continue;
|
|
12450
|
-
const buf = (0,
|
|
12821
|
+
const buf = (0, import_node_fs30.readFileSync)(abs);
|
|
12451
12822
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
12452
12823
|
} catch (err) {
|
|
12453
12824
|
out.push({
|
|
@@ -12935,7 +13306,7 @@ async function confirmLand(thread, opts) {
|
|
|
12935
13306
|
}
|
|
12936
13307
|
|
|
12937
13308
|
// src/threads/create.ts
|
|
12938
|
-
var
|
|
13309
|
+
var import_node_fs31 = require("fs");
|
|
12939
13310
|
init_worktree();
|
|
12940
13311
|
init_app_settings();
|
|
12941
13312
|
init_thread_store();
|
|
@@ -12949,12 +13320,13 @@ async function createThread(input, _onSetupLine) {
|
|
|
12949
13320
|
});
|
|
12950
13321
|
await requireAgent(resolved.agent);
|
|
12951
13322
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
12952
|
-
if (!(0,
|
|
13323
|
+
if (!(0, import_node_fs31.existsSync)(repoPath)) {
|
|
12953
13324
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
12954
13325
|
}
|
|
12955
13326
|
let sourceRef = input.sourceRef;
|
|
12956
13327
|
let sourceIsFork = false;
|
|
12957
13328
|
let prUrl = null;
|
|
13329
|
+
let prTitle = null;
|
|
12958
13330
|
if (input.sourceType === "pr") {
|
|
12959
13331
|
const num2 = Number(input.sourceRef.replace(/^#/, ""));
|
|
12960
13332
|
if (!Number.isFinite(num2)) throw new Error(`Invalid PR number: ${input.sourceRef}`);
|
|
@@ -12970,6 +13342,12 @@ async function createThread(input, _onSetupLine) {
|
|
|
12970
13342
|
} else if (input.sourceType === "branch") {
|
|
12971
13343
|
if (!sourceRef || sourceRef === "HEAD" || sourceRef === "default") {
|
|
12972
13344
|
sourceRef = await resolveDefaultBranch(repoPath);
|
|
13345
|
+
} else {
|
|
13346
|
+
const existing = await getPrForHeadBranch(repoPath, sourceRef);
|
|
13347
|
+
if (existing?.url) {
|
|
13348
|
+
prUrl = existing.url;
|
|
13349
|
+
prTitle = existing.title;
|
|
13350
|
+
}
|
|
12973
13351
|
}
|
|
12974
13352
|
} else if (input.sourceType === "adopt") {
|
|
12975
13353
|
throw new Error("Use adoptThread() for adopt sources");
|
|
@@ -13000,7 +13378,8 @@ async function createThread(input, _onSetupLine) {
|
|
|
13000
13378
|
sourceIsFork,
|
|
13001
13379
|
parentThreadId: input.parentThreadId ?? null,
|
|
13002
13380
|
status: "idle",
|
|
13003
|
-
prUrl
|
|
13381
|
+
prUrl,
|
|
13382
|
+
prTitle
|
|
13004
13383
|
});
|
|
13005
13384
|
writeThread(thread);
|
|
13006
13385
|
await ensureWorkspace(repoPath);
|
|
@@ -13176,7 +13555,7 @@ async function forkThreadWorktree(input, onSetupLine) {
|
|
|
13176
13555
|
}
|
|
13177
13556
|
|
|
13178
13557
|
// src/threads/stack-layers.ts
|
|
13179
|
-
var
|
|
13558
|
+
var import_node_fs32 = require("fs");
|
|
13180
13559
|
init_run();
|
|
13181
13560
|
init_stack();
|
|
13182
13561
|
init_worktree();
|
|
@@ -13244,7 +13623,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
13244
13623
|
let createdWorktree = false;
|
|
13245
13624
|
const trees = await listWorktrees(repoPath);
|
|
13246
13625
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
13247
|
-
if (checkedOut?.path && (0,
|
|
13626
|
+
if (checkedOut?.path && (0, import_node_fs32.existsSync)(checkedOut.path)) {
|
|
13248
13627
|
if (input.reuseExistingWorktree !== false) {
|
|
13249
13628
|
worktreePath = checkedOut.path;
|
|
13250
13629
|
} else {
|
|
@@ -13386,7 +13765,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
13386
13765
|
async function createPrStack(input, onSetupLine) {
|
|
13387
13766
|
await requireAgent(input.agent);
|
|
13388
13767
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
13389
|
-
if (!(0,
|
|
13768
|
+
if (!(0, import_node_fs32.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
13390
13769
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
13391
13770
|
const status = await detectGhStack(repoPath);
|
|
13392
13771
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -13453,7 +13832,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
13453
13832
|
}
|
|
13454
13833
|
}
|
|
13455
13834
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
13456
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
13835
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs32.existsSync)(bootstrap.worktreePath)) {
|
|
13457
13836
|
try {
|
|
13458
13837
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
13459
13838
|
deleteBranch: bootstrap.branchName
|
|
@@ -13476,20 +13855,26 @@ function stackAgentDefaultsFrom(input) {
|
|
|
13476
13855
|
|
|
13477
13856
|
// src/threads/adopt.ts
|
|
13478
13857
|
var import_node_child_process4 = require("child_process");
|
|
13479
|
-
var
|
|
13480
|
-
var
|
|
13481
|
-
var
|
|
13482
|
-
var
|
|
13858
|
+
var import_node_fs33 = require("fs");
|
|
13859
|
+
var import_node_os11 = require("os");
|
|
13860
|
+
var import_node_path29 = require("path");
|
|
13861
|
+
var import_node_module4 = require("module");
|
|
13483
13862
|
init_worktree();
|
|
13484
13863
|
init_thread_store();
|
|
13485
|
-
var
|
|
13864
|
+
var import_meta4 = {};
|
|
13865
|
+
var CONDUCTOR_APP_SUPPORT = (0, import_node_path29.join)(
|
|
13486
13866
|
process.env.HOME ?? "",
|
|
13487
13867
|
"Library",
|
|
13488
13868
|
"Application Support",
|
|
13489
13869
|
"com.conductor.app"
|
|
13490
13870
|
);
|
|
13491
|
-
var CONDUCTOR_DB = (0,
|
|
13492
|
-
var CURSOR_SDK_STORE = (0,
|
|
13871
|
+
var CONDUCTOR_DB = (0, import_node_path29.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
13872
|
+
var CURSOR_SDK_STORE = (0, import_node_path29.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
13873
|
+
function openReadonlySqlite(file) {
|
|
13874
|
+
const req = (0, import_node_module4.createRequire)(import_meta4.url);
|
|
13875
|
+
const Database = req("better-sqlite3");
|
|
13876
|
+
return new Database(file, { readonly: true, fileMustExist: true });
|
|
13877
|
+
}
|
|
13493
13878
|
function mapAgentType(raw) {
|
|
13494
13879
|
if (!raw) return null;
|
|
13495
13880
|
const v = raw.toLowerCase();
|
|
@@ -13501,21 +13886,21 @@ function mapAgentType(raw) {
|
|
|
13501
13886
|
return null;
|
|
13502
13887
|
}
|
|
13503
13888
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
13504
|
-
if (!workspacePath || !(0,
|
|
13889
|
+
if (!workspacePath || !(0, import_node_fs33.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
13505
13890
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
13506
13891
|
let best = null;
|
|
13507
13892
|
let hashes;
|
|
13508
13893
|
try {
|
|
13509
|
-
hashes = (0,
|
|
13894
|
+
hashes = (0, import_node_fs33.readdirSync)(CURSOR_SDK_STORE);
|
|
13510
13895
|
} catch {
|
|
13511
13896
|
return null;
|
|
13512
13897
|
}
|
|
13513
13898
|
for (const hash of hashes) {
|
|
13514
|
-
const agentsFile = (0,
|
|
13515
|
-
if (!(0,
|
|
13899
|
+
const agentsFile = (0, import_node_path29.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
13900
|
+
if (!(0, import_node_fs33.existsSync)(agentsFile)) continue;
|
|
13516
13901
|
let text3;
|
|
13517
13902
|
try {
|
|
13518
|
-
text3 = (0,
|
|
13903
|
+
text3 = (0, import_node_fs33.readFileSync)(agentsFile, "utf8");
|
|
13519
13904
|
} catch {
|
|
13520
13905
|
continue;
|
|
13521
13906
|
}
|
|
@@ -13539,7 +13924,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
13539
13924
|
return best?.agentId ?? null;
|
|
13540
13925
|
}
|
|
13541
13926
|
async function adoptThread(input) {
|
|
13542
|
-
if (!(0,
|
|
13927
|
+
if (!(0, import_node_fs33.existsSync)(input.worktreePath)) {
|
|
13543
13928
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
13544
13929
|
}
|
|
13545
13930
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -13566,23 +13951,23 @@ function conductorDbPath() {
|
|
|
13566
13951
|
return CONDUCTOR_DB;
|
|
13567
13952
|
}
|
|
13568
13953
|
function listConductorWorkspaces() {
|
|
13569
|
-
if (!(0,
|
|
13954
|
+
if (!(0, import_node_fs33.existsSync)(CONDUCTOR_DB)) {
|
|
13570
13955
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
13571
13956
|
}
|
|
13572
|
-
const tmp = (0,
|
|
13573
|
-
const snapshot = (0,
|
|
13957
|
+
const tmp = (0, import_node_fs33.mkdtempSync)((0, import_node_path29.join)((0, import_node_os11.tmpdir)(), "sideboard-conductor-"));
|
|
13958
|
+
const snapshot = (0, import_node_path29.join)(tmp, "conductor.db");
|
|
13574
13959
|
try {
|
|
13575
|
-
(0,
|
|
13960
|
+
(0, import_node_fs33.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
13576
13961
|
for (const suffix of ["-wal", "-shm"]) {
|
|
13577
13962
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
13578
|
-
if ((0,
|
|
13963
|
+
if ((0, import_node_fs33.existsSync)(src)) {
|
|
13579
13964
|
try {
|
|
13580
|
-
(0,
|
|
13965
|
+
(0, import_node_fs33.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
13581
13966
|
} catch {
|
|
13582
13967
|
}
|
|
13583
13968
|
}
|
|
13584
13969
|
}
|
|
13585
|
-
const db =
|
|
13970
|
+
const db = openReadonlySqlite(snapshot);
|
|
13586
13971
|
try {
|
|
13587
13972
|
const tables = db.prepare(`SELECT name FROM sqlite_master WHERE type='table'`).all();
|
|
13588
13973
|
const names = new Set(tables.map((t) => t.name));
|
|
@@ -13653,27 +14038,27 @@ function listConductorWorkspaces() {
|
|
|
13653
14038
|
db.close();
|
|
13654
14039
|
}
|
|
13655
14040
|
} finally {
|
|
13656
|
-
(0,
|
|
14041
|
+
(0, import_node_fs33.rmSync)(tmp, { recursive: true, force: true });
|
|
13657
14042
|
}
|
|
13658
14043
|
}
|
|
13659
14044
|
function importConductorWorkspace(workspaceId) {
|
|
13660
|
-
if (!(0,
|
|
14045
|
+
if (!(0, import_node_fs33.existsSync)(CONDUCTOR_DB)) {
|
|
13661
14046
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
13662
14047
|
}
|
|
13663
|
-
const tmp = (0,
|
|
13664
|
-
const snapshot = (0,
|
|
14048
|
+
const tmp = (0, import_node_fs33.mkdtempSync)((0, import_node_path29.join)((0, import_node_os11.tmpdir)(), "sideboard-conductor-"));
|
|
14049
|
+
const snapshot = (0, import_node_path29.join)(tmp, "conductor.db");
|
|
13665
14050
|
try {
|
|
13666
|
-
(0,
|
|
14051
|
+
(0, import_node_fs33.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
13667
14052
|
for (const suffix of ["-wal", "-shm"]) {
|
|
13668
14053
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
13669
|
-
if ((0,
|
|
14054
|
+
if ((0, import_node_fs33.existsSync)(src)) {
|
|
13670
14055
|
try {
|
|
13671
|
-
(0,
|
|
14056
|
+
(0, import_node_fs33.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
13672
14057
|
} catch {
|
|
13673
14058
|
}
|
|
13674
14059
|
}
|
|
13675
14060
|
}
|
|
13676
|
-
const db =
|
|
14061
|
+
const db = openReadonlySqlite(snapshot);
|
|
13677
14062
|
try {
|
|
13678
14063
|
const row = db.prepare(
|
|
13679
14064
|
`SELECT
|
|
@@ -13686,7 +14071,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
13686
14071
|
).get(workspaceId);
|
|
13687
14072
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
13688
14073
|
const worktreePath = String(row.workspacePath);
|
|
13689
|
-
if (!(0,
|
|
14074
|
+
if (!(0, import_node_fs33.existsSync)(worktreePath)) {
|
|
13690
14075
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
13691
14076
|
}
|
|
13692
14077
|
let sessionId = null;
|
|
@@ -13749,7 +14134,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
13749
14134
|
db.close();
|
|
13750
14135
|
}
|
|
13751
14136
|
} finally {
|
|
13752
|
-
(0,
|
|
14137
|
+
(0, import_node_fs33.rmSync)(tmp, { recursive: true, force: true });
|
|
13753
14138
|
}
|
|
13754
14139
|
}
|
|
13755
14140
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
@@ -13760,8 +14145,8 @@ async function importConductorWorkspaceAsync(workspaceId) {
|
|
|
13760
14145
|
var import_node_events = require("events");
|
|
13761
14146
|
|
|
13762
14147
|
// src/slack/outbound-watch.ts
|
|
13763
|
-
var
|
|
13764
|
-
var
|
|
14148
|
+
var import_node_fs35 = require("fs");
|
|
14149
|
+
var import_node_path32 = require("path");
|
|
13765
14150
|
init_paths();
|
|
13766
14151
|
init_private_file();
|
|
13767
14152
|
init_secure_file();
|
|
@@ -13807,19 +14192,19 @@ async function slackAuthTest(token) {
|
|
|
13807
14192
|
}
|
|
13808
14193
|
|
|
13809
14194
|
// src/slack/reply-target.ts
|
|
13810
|
-
var
|
|
13811
|
-
var
|
|
14195
|
+
var import_node_fs34 = require("fs");
|
|
14196
|
+
var import_node_path30 = require("path");
|
|
13812
14197
|
init_paths();
|
|
13813
14198
|
init_private_file();
|
|
13814
14199
|
init_secure_file();
|
|
13815
14200
|
function storePath2() {
|
|
13816
|
-
return (0,
|
|
14201
|
+
return (0, import_node_path30.join)(appDataDir(), "slack-reply-to.json");
|
|
13817
14202
|
}
|
|
13818
14203
|
function readStore2() {
|
|
13819
14204
|
const path2 = storePath2();
|
|
13820
|
-
if (!(0,
|
|
14205
|
+
if (!(0, import_node_fs34.existsSync)(path2)) return {};
|
|
13821
14206
|
try {
|
|
13822
|
-
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0,
|
|
14207
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs34.readFileSync)(path2, "utf8"));
|
|
13823
14208
|
return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
|
|
13824
14209
|
} catch {
|
|
13825
14210
|
return {};
|
|
@@ -13836,11 +14221,11 @@ function getSlackReplyTarget(threadId) {
|
|
|
13836
14221
|
}
|
|
13837
14222
|
|
|
13838
14223
|
// src/slack/workspaces.ts
|
|
13839
|
-
var
|
|
14224
|
+
var import_node_path31 = require("path");
|
|
13840
14225
|
init_paths();
|
|
13841
14226
|
init_secure_file();
|
|
13842
14227
|
function storePath3() {
|
|
13843
|
-
return (0,
|
|
14228
|
+
return (0, import_node_path31.join)(appDataDir(), "slack-workspaces.json");
|
|
13844
14229
|
}
|
|
13845
14230
|
function readStore3() {
|
|
13846
14231
|
try {
|
|
@@ -13956,7 +14341,7 @@ var POLL_INTERVAL_MS = 12e3;
|
|
|
13956
14341
|
var lastPollMs = 0;
|
|
13957
14342
|
var nameCache = /* @__PURE__ */ new Map();
|
|
13958
14343
|
function storePath4() {
|
|
13959
|
-
return (0,
|
|
14344
|
+
return (0, import_node_path32.join)(appDataDir(), "slack-outbound-watch.json");
|
|
13960
14345
|
}
|
|
13961
14346
|
function watchId(teamId, channelId, ts) {
|
|
13962
14347
|
return `${teamId}:${channelId}:${ts}`;
|
|
@@ -13986,9 +14371,9 @@ function tsNewer(a, b) {
|
|
|
13986
14371
|
}
|
|
13987
14372
|
function readStore4() {
|
|
13988
14373
|
const path2 = storePath4();
|
|
13989
|
-
if (!(0,
|
|
14374
|
+
if (!(0, import_node_fs35.existsSync)(path2)) return [];
|
|
13990
14375
|
try {
|
|
13991
|
-
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0,
|
|
14376
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs35.readFileSync)(path2, "utf8"));
|
|
13992
14377
|
return Array.isArray(parsed?.watches) ? parsed.watches : [];
|
|
13993
14378
|
} catch {
|
|
13994
14379
|
return [];
|
|
@@ -14333,7 +14718,7 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
14333
14718
|
}
|
|
14334
14719
|
|
|
14335
14720
|
// src/orchestrator/orchestrator.ts
|
|
14336
|
-
var
|
|
14721
|
+
var import_node_fs41 = require("fs");
|
|
14337
14722
|
init_error_detail();
|
|
14338
14723
|
init_agents();
|
|
14339
14724
|
init_worktree();
|
|
@@ -14354,8 +14739,8 @@ function shouldAutoArchiveOnPrMerge(opts) {
|
|
|
14354
14739
|
}
|
|
14355
14740
|
|
|
14356
14741
|
// src/git/orphan-cleanup.ts
|
|
14357
|
-
var
|
|
14358
|
-
var
|
|
14742
|
+
var import_node_fs36 = require("fs");
|
|
14743
|
+
var import_node_path33 = require("path");
|
|
14359
14744
|
init_worktree();
|
|
14360
14745
|
init_thread_store();
|
|
14361
14746
|
init_paths();
|
|
@@ -14370,9 +14755,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14370
14755
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
14371
14756
|
);
|
|
14372
14757
|
const homeRoot = sideboardWorkspacesDir();
|
|
14373
|
-
if ((0,
|
|
14758
|
+
if ((0, import_node_fs36.existsSync)(homeRoot)) {
|
|
14374
14759
|
try {
|
|
14375
|
-
for (const entry of (0,
|
|
14760
|
+
for (const entry of (0, import_node_fs36.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
14376
14761
|
if (!entry.isDirectory()) continue;
|
|
14377
14762
|
void entry;
|
|
14378
14763
|
}
|
|
@@ -14382,7 +14767,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14382
14767
|
const orphans = [];
|
|
14383
14768
|
const seen = /* @__PURE__ */ new Set();
|
|
14384
14769
|
for (const repoPath of repos) {
|
|
14385
|
-
if (!repoPath || !(0,
|
|
14770
|
+
if (!repoPath || !(0, import_node_fs36.existsSync)(repoPath)) continue;
|
|
14386
14771
|
try {
|
|
14387
14772
|
const wts = await listWorktrees(repoPath);
|
|
14388
14773
|
for (const wt of wts) {
|
|
@@ -14393,7 +14778,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14393
14778
|
seen.add(path2);
|
|
14394
14779
|
let mtimeMs = 0;
|
|
14395
14780
|
try {
|
|
14396
|
-
mtimeMs = (0,
|
|
14781
|
+
mtimeMs = (0, import_node_fs36.statSync)(path2).mtimeMs;
|
|
14397
14782
|
} catch {
|
|
14398
14783
|
mtimeMs = 0;
|
|
14399
14784
|
}
|
|
@@ -14403,16 +14788,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14403
14788
|
}
|
|
14404
14789
|
try {
|
|
14405
14790
|
const root = worktreesRoot(repoPath);
|
|
14406
|
-
if ((0,
|
|
14407
|
-
for (const entry of (0,
|
|
14791
|
+
if ((0, import_node_fs36.existsSync)(root)) {
|
|
14792
|
+
for (const entry of (0, import_node_fs36.readdirSync)(root, { withFileTypes: true })) {
|
|
14408
14793
|
if (!entry.isDirectory()) continue;
|
|
14409
|
-
const path2 = (0,
|
|
14794
|
+
const path2 = (0, import_node_path33.join)(root, entry.name).replace(/\/$/, "");
|
|
14410
14795
|
if (known.has(path2) || seen.has(path2)) continue;
|
|
14411
|
-
if (!(0,
|
|
14796
|
+
if (!(0, import_node_fs36.existsSync)((0, import_node_path33.join)(path2, ".git"))) continue;
|
|
14412
14797
|
seen.add(path2);
|
|
14413
14798
|
let mtimeMs = 0;
|
|
14414
14799
|
try {
|
|
14415
|
-
mtimeMs = (0,
|
|
14800
|
+
mtimeMs = (0, import_node_fs36.statSync)(path2).mtimeMs;
|
|
14416
14801
|
} catch {
|
|
14417
14802
|
mtimeMs = Date.now();
|
|
14418
14803
|
}
|
|
@@ -14558,8 +14943,8 @@ async function applyThreadIntoMain(thread, opts) {
|
|
|
14558
14943
|
}
|
|
14559
14944
|
|
|
14560
14945
|
// src/git/clone-repo.ts
|
|
14561
|
-
var
|
|
14562
|
-
var
|
|
14946
|
+
var import_node_fs37 = require("fs");
|
|
14947
|
+
var import_node_path34 = require("path");
|
|
14563
14948
|
var import_execa6 = require("execa");
|
|
14564
14949
|
init_paths();
|
|
14565
14950
|
init_workspaces();
|
|
@@ -14569,12 +14954,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
14569
14954
|
if (!url) throw new Error("Clone URL is required");
|
|
14570
14955
|
let name = opts.name?.trim();
|
|
14571
14956
|
if (!name) {
|
|
14572
|
-
const leaf = (0,
|
|
14957
|
+
const leaf = (0, import_node_path34.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
14573
14958
|
name = leaf || "repo";
|
|
14574
14959
|
}
|
|
14575
14960
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
14576
|
-
const dest = (0,
|
|
14577
|
-
if ((0,
|
|
14961
|
+
const dest = (0, import_node_path34.join)(sideboardReposDir(), name);
|
|
14962
|
+
if ((0, import_node_fs37.existsSync)(dest)) {
|
|
14578
14963
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
14579
14964
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
14580
14965
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -14596,8 +14981,8 @@ init_orchestrator_capable();
|
|
|
14596
14981
|
|
|
14597
14982
|
// src/review/request-review.ts
|
|
14598
14983
|
var import_node_crypto8 = require("crypto");
|
|
14599
|
-
var
|
|
14600
|
-
var
|
|
14984
|
+
var import_node_fs38 = require("fs");
|
|
14985
|
+
var import_node_path35 = require("path");
|
|
14601
14986
|
init_global_workspace();
|
|
14602
14987
|
init_thread_store();
|
|
14603
14988
|
|
|
@@ -14745,22 +15130,22 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
14745
15130
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
14746
15131
|
}
|
|
14747
15132
|
function readTextIfPresent(abs) {
|
|
14748
|
-
if (!(0,
|
|
15133
|
+
if (!(0, import_node_fs38.existsSync)(abs)) return null;
|
|
14749
15134
|
try {
|
|
14750
|
-
const content = (0,
|
|
15135
|
+
const content = (0, import_node_fs38.readFileSync)(abs, "utf8");
|
|
14751
15136
|
return content.trim() ? content : null;
|
|
14752
15137
|
} catch {
|
|
14753
15138
|
return null;
|
|
14754
15139
|
}
|
|
14755
15140
|
}
|
|
14756
15141
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
14757
|
-
const gitignoreAbs = (0,
|
|
14758
|
-
if ((0,
|
|
14759
|
-
(0,
|
|
14760
|
-
(0,
|
|
15142
|
+
const gitignoreAbs = (0, import_node_path35.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
15143
|
+
if ((0, import_node_fs38.existsSync)(gitignoreAbs)) return;
|
|
15144
|
+
(0, import_node_fs38.mkdirSync)((0, import_node_path35.dirname)(gitignoreAbs), { recursive: true });
|
|
15145
|
+
(0, import_node_fs38.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
14761
15146
|
}
|
|
14762
15147
|
function resolveReviewGuidelines(worktreePath) {
|
|
14763
|
-
const repoAbs = (0,
|
|
15148
|
+
const repoAbs = (0, import_node_path35.join)(worktreePath, REPO_REVIEW_PATH);
|
|
14764
15149
|
const repoContent = readTextIfPresent(repoAbs);
|
|
14765
15150
|
if (repoContent) {
|
|
14766
15151
|
return {
|
|
@@ -14770,7 +15155,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
14770
15155
|
source: "repo"
|
|
14771
15156
|
};
|
|
14772
15157
|
}
|
|
14773
|
-
const localAbs = (0,
|
|
15158
|
+
const localAbs = (0, import_node_path35.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
14774
15159
|
const localContent = readTextIfPresent(localAbs);
|
|
14775
15160
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
14776
15161
|
return {
|
|
@@ -14780,7 +15165,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
14780
15165
|
source: "local"
|
|
14781
15166
|
};
|
|
14782
15167
|
}
|
|
14783
|
-
const legacyAbs = (0,
|
|
15168
|
+
const legacyAbs = (0, import_node_path35.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
14784
15169
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
14785
15170
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
14786
15171
|
return {
|
|
@@ -14791,8 +15176,8 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
14791
15176
|
};
|
|
14792
15177
|
}
|
|
14793
15178
|
ensureAttachmentsGitignore(worktreePath);
|
|
14794
|
-
(0,
|
|
14795
|
-
(0,
|
|
15179
|
+
(0, import_node_fs38.mkdirSync)((0, import_node_path35.dirname)(localAbs), { recursive: true });
|
|
15180
|
+
(0, import_node_fs38.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
|
|
14796
15181
|
return {
|
|
14797
15182
|
path: REVIEW_REQUEST_PATH,
|
|
14798
15183
|
name: REVIEW_REQUEST_NAME,
|
|
@@ -14801,7 +15186,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
14801
15186
|
};
|
|
14802
15187
|
}
|
|
14803
15188
|
function ensureReviewRequestFile(worktreePath) {
|
|
14804
|
-
const repoAbs = (0,
|
|
15189
|
+
const repoAbs = (0, import_node_path35.join)(worktreePath, REPO_REVIEW_PATH);
|
|
14805
15190
|
const repoContent = readTextIfPresent(repoAbs);
|
|
14806
15191
|
if (repoContent) {
|
|
14807
15192
|
return {
|
|
@@ -14811,10 +15196,10 @@ function ensureReviewRequestFile(worktreePath) {
|
|
|
14811
15196
|
source: "repo"
|
|
14812
15197
|
};
|
|
14813
15198
|
}
|
|
14814
|
-
const localAbs = (0,
|
|
14815
|
-
const localContent = readTextIfPresent(localAbs) ?? readTextIfPresent((0,
|
|
15199
|
+
const localAbs = (0, import_node_path35.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
15200
|
+
const localContent = readTextIfPresent(localAbs) ?? readTextIfPresent((0, import_node_path35.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
14816
15201
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
14817
|
-
const path2 = (0,
|
|
15202
|
+
const path2 = (0, import_node_fs38.existsSync)(localAbs) ? REVIEW_REQUEST_PATH : LEGACY_REVIEW_REQUEST_PATH;
|
|
14818
15203
|
return {
|
|
14819
15204
|
path: path2,
|
|
14820
15205
|
name: REVIEW_REQUEST_NAME,
|
|
@@ -14822,8 +15207,8 @@ function ensureReviewRequestFile(worktreePath) {
|
|
|
14822
15207
|
source: "local"
|
|
14823
15208
|
};
|
|
14824
15209
|
}
|
|
14825
|
-
(0,
|
|
14826
|
-
(0,
|
|
15210
|
+
(0, import_node_fs38.mkdirSync)((0, import_node_path35.dirname)(repoAbs), { recursive: true });
|
|
15211
|
+
(0, import_node_fs38.writeFileSync)(repoAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
|
|
14827
15212
|
return {
|
|
14828
15213
|
path: REPO_REVIEW_PATH,
|
|
14829
15214
|
name: REPO_REVIEW_NAME,
|
|
@@ -14843,7 +15228,7 @@ function buildReviewRequestAttachment(content, opts) {
|
|
|
14843
15228
|
};
|
|
14844
15229
|
}
|
|
14845
15230
|
function readExistingReviewRequestFile(worktreePath) {
|
|
14846
|
-
return readTextIfPresent((0,
|
|
15231
|
+
return readTextIfPresent((0, import_node_path35.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path35.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path35.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
14847
15232
|
}
|
|
14848
15233
|
async function requestReview(threadRef, send2) {
|
|
14849
15234
|
const from = findThreadByRef(threadRef);
|
|
@@ -15104,7 +15489,7 @@ var Orchestrator = class {
|
|
|
15104
15489
|
}
|
|
15105
15490
|
continue;
|
|
15106
15491
|
}
|
|
15107
|
-
if (!(0,
|
|
15492
|
+
if (!(0, import_node_fs41.existsSync)(thread.worktreePath)) {
|
|
15108
15493
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
15109
15494
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
15110
15495
|
continue;
|
|
@@ -16196,8 +16581,9 @@ var Orchestrator = class {
|
|
|
16196
16581
|
return result;
|
|
16197
16582
|
}
|
|
16198
16583
|
async mergePr(threadRef) {
|
|
16199
|
-
const { thread,
|
|
16584
|
+
const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
|
|
16200
16585
|
this.assertNotGlobal(thread, "Merge PR");
|
|
16586
|
+
const selector = selectors[0];
|
|
16201
16587
|
if (!selector) throw new Error("No pull request linked to this thread");
|
|
16202
16588
|
const result = await mergePr(cwd, selector);
|
|
16203
16589
|
const state = normalizePrState(result.state) || "MERGED";
|
|
@@ -16217,29 +16603,34 @@ var Orchestrator = class {
|
|
|
16217
16603
|
await this.persistPrMetaAndMaybeArchive(thread, metaLike);
|
|
16218
16604
|
return { url: metaLike.url, state };
|
|
16219
16605
|
}
|
|
16220
|
-
/** Resolve PR
|
|
16606
|
+
/** Resolve PR selectors and optionally persist `prUrl` when found. */
|
|
16221
16607
|
async withPrSelector(threadRef) {
|
|
16222
16608
|
const thread = this.requireThread(threadRef);
|
|
16223
|
-
const
|
|
16609
|
+
const selectors = resolvePrSelectors(thread);
|
|
16224
16610
|
const cwd = thread.worktreePath;
|
|
16225
16611
|
if (!cwd?.trim()) {
|
|
16226
16612
|
throw new Error(`Thread ${threadRef} has no worktreePath`);
|
|
16227
16613
|
}
|
|
16228
|
-
return { thread,
|
|
16614
|
+
return { thread, selectors, cwd };
|
|
16229
16615
|
}
|
|
16230
16616
|
async getPrChecks(threadRef) {
|
|
16231
|
-
const {
|
|
16232
|
-
|
|
16233
|
-
|
|
16617
|
+
const { selectors, cwd } = await this.withPrSelector(threadRef);
|
|
16618
|
+
for (const selector of selectors) {
|
|
16619
|
+
const checks = await getPrChecks(cwd, selector);
|
|
16620
|
+
if (checks) return checks;
|
|
16621
|
+
}
|
|
16622
|
+
return null;
|
|
16234
16623
|
}
|
|
16235
16624
|
async getPrMeta(threadRef) {
|
|
16236
|
-
const { thread,
|
|
16237
|
-
|
|
16238
|
-
|
|
16239
|
-
|
|
16240
|
-
|
|
16625
|
+
const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
|
|
16626
|
+
for (const selector of selectors) {
|
|
16627
|
+
const meta = await getPrMeta(cwd, selector);
|
|
16628
|
+
if (meta) {
|
|
16629
|
+
await this.persistPrMetaAndMaybeArchive(thread, meta);
|
|
16630
|
+
return meta;
|
|
16631
|
+
}
|
|
16241
16632
|
}
|
|
16242
|
-
return
|
|
16633
|
+
return null;
|
|
16243
16634
|
}
|
|
16244
16635
|
/**
|
|
16245
16636
|
* Persist PR URL/title/state and Conductor-style auto-archive when the PR
|
|
@@ -16363,9 +16754,12 @@ var Orchestrator = class {
|
|
|
16363
16754
|
return { stack: result.stack, threads: result.threads };
|
|
16364
16755
|
}
|
|
16365
16756
|
async getPrDetails(threadRef) {
|
|
16366
|
-
const { thread,
|
|
16367
|
-
|
|
16368
|
-
const
|
|
16757
|
+
const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
|
|
16758
|
+
let details = null;
|
|
16759
|
+
for (const selector of selectors) {
|
|
16760
|
+
details = await getPrDetails(cwd, selector);
|
|
16761
|
+
if (details) break;
|
|
16762
|
+
}
|
|
16369
16763
|
if (details) {
|
|
16370
16764
|
const patch = {};
|
|
16371
16765
|
if (details.url && details.url !== thread.prUrl) patch.prUrl = details.url;
|
|
@@ -16592,7 +16986,7 @@ var Orchestrator = class {
|
|
|
16592
16986
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
16593
16987
|
return restored2;
|
|
16594
16988
|
}
|
|
16595
|
-
if (!(0,
|
|
16989
|
+
if (!(0, import_node_fs41.existsSync)(thread.worktreePath)) {
|
|
16596
16990
|
const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
|
|
16597
16991
|
const { execa: execa7 } = await import("execa");
|
|
16598
16992
|
const slug = thread.worktreePath.split("/").pop();
|
|
@@ -16833,7 +17227,7 @@ init_coordinator_prompt();
|
|
|
16833
17227
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
16834
17228
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
16835
17229
|
var import_zod3 = require("zod");
|
|
16836
|
-
var
|
|
17230
|
+
var import_node_path38 = require("path");
|
|
16837
17231
|
init_worktree();
|
|
16838
17232
|
init_global_workspace();
|
|
16839
17233
|
init_list_models();
|
|
@@ -17447,6 +17841,7 @@ function registerLinearTools(server) {
|
|
|
17447
17841
|
}
|
|
17448
17842
|
|
|
17449
17843
|
// src/mcp/server.ts
|
|
17844
|
+
init_git_auth_mode();
|
|
17450
17845
|
var MAX_ORCH_THREADS = 5;
|
|
17451
17846
|
var CREATE_THREAD_TIMEOUT_MS = 9e4;
|
|
17452
17847
|
function withTimeout(promise, ms, label) {
|
|
@@ -17468,6 +17863,14 @@ function withTimeout(promise, ms, label) {
|
|
|
17468
17863
|
}
|
|
17469
17864
|
async function startMcpServer() {
|
|
17470
17865
|
const orch = getOrchestrator();
|
|
17866
|
+
try {
|
|
17867
|
+
await warmGithubAgentAuth();
|
|
17868
|
+
} catch (err) {
|
|
17869
|
+
console.error(
|
|
17870
|
+
"[sideboard-mcp] GitHub agent auth warm skipped:",
|
|
17871
|
+
err instanceof Error ? err.message : err
|
|
17872
|
+
);
|
|
17873
|
+
}
|
|
17471
17874
|
try {
|
|
17472
17875
|
const { maxConcurrentAgents: maxConcurrentAgents2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
17473
17876
|
orch.setMaxConcurrent(maxConcurrentAgents2());
|
|
@@ -17511,7 +17914,7 @@ async function startMcpServer() {
|
|
|
17511
17914
|
async () => {
|
|
17512
17915
|
const threads = orch.getThreads(true);
|
|
17513
17916
|
const lines = threads.map((t) => {
|
|
17514
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
17917
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path38.basename)(t.repoPath) || t.repoPath;
|
|
17515
17918
|
return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title} sideboard://thread/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}`;
|
|
17516
17919
|
});
|
|
17517
17920
|
return {
|
|
@@ -17574,7 +17977,7 @@ async function startMcpServer() {
|
|
|
17574
17977
|
);
|
|
17575
17978
|
server.tool(
|
|
17576
17979
|
"ask_user",
|
|
17577
|
-
"Ask the user clarifying multiple-choice
|
|
17980
|
+
"Ask the user a clarifying multiple-choice question in Sideboard\u2019s composer. Call only when work is blocked on choosing among a few concrete options (approach fork, which API, auth vs cookies). Do not call for greetings, check-ins, \u201Chello\u201D, open-ended how-can-I-help, or to invent a menu of possible next tasks \u2014 reply in chat instead. If one option is the obvious default, proceed without asking. Before calling, write a short chat message explaining the decision and what each option means. Include a description on every option. After calling, stop and wait for answers. Not for \u201Cis the plan ready?\u201D.",
|
|
17578
17981
|
{
|
|
17579
17982
|
questions: import_zod3.z.array(
|
|
17580
17983
|
import_zod3.z.object({
|
|
@@ -18819,6 +19222,76 @@ init_accounts();
|
|
|
18819
19222
|
init_connected_teams();
|
|
18820
19223
|
init_injected_mcp();
|
|
18821
19224
|
|
|
19225
|
+
// src/agents/user-mcp-config.ts
|
|
19226
|
+
var import_node_fs42 = require("fs");
|
|
19227
|
+
var import_node_os12 = require("os");
|
|
19228
|
+
var import_node_path39 = require("path");
|
|
19229
|
+
init_paths();
|
|
19230
|
+
init_injected_mcp();
|
|
19231
|
+
function userCursorMcpConfigPath() {
|
|
19232
|
+
return (0, import_node_path39.join)((0, import_node_os12.homedir)(), ".cursor", "mcp.json");
|
|
19233
|
+
}
|
|
19234
|
+
function userClaudeMcpConfigPath() {
|
|
19235
|
+
return (0, import_node_path39.join)((0, import_node_os12.homedir)(), ".claude.json");
|
|
19236
|
+
}
|
|
19237
|
+
function asObject(value) {
|
|
19238
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
19239
|
+
return { ...value };
|
|
19240
|
+
}
|
|
19241
|
+
function stripElectronSpawnEnv(env) {
|
|
19242
|
+
if (!env) return void 0;
|
|
19243
|
+
const next = { ...env };
|
|
19244
|
+
delete next.ELECTRON_RUN_AS_NODE;
|
|
19245
|
+
delete next.ELECTRON_RUN_AS_NODE;
|
|
19246
|
+
return Object.keys(next).length > 0 ? next : void 0;
|
|
19247
|
+
}
|
|
19248
|
+
function mergeSideboardIntoMcpServersJson(existing, sideboard) {
|
|
19249
|
+
const root = asObject(existing);
|
|
19250
|
+
const servers = asObject(root.mcpServers);
|
|
19251
|
+
const env = stripElectronSpawnEnv(sideboard.env);
|
|
19252
|
+
servers.sideboard = {
|
|
19253
|
+
command: sideboard.command,
|
|
19254
|
+
...sideboard.args && sideboard.args.length > 0 ? { args: sideboard.args } : {},
|
|
19255
|
+
...env ? { env } : {}
|
|
19256
|
+
};
|
|
19257
|
+
return { ...root, mcpServers: servers };
|
|
19258
|
+
}
|
|
19259
|
+
function writeMergedMcpServersJson(configPath, sideboard) {
|
|
19260
|
+
let existing = {};
|
|
19261
|
+
if ((0, import_node_fs42.existsSync)(configPath)) {
|
|
19262
|
+
try {
|
|
19263
|
+
existing = JSON.parse((0, import_node_fs42.readFileSync)(configPath, "utf8"));
|
|
19264
|
+
} catch {
|
|
19265
|
+
existing = {};
|
|
19266
|
+
}
|
|
19267
|
+
}
|
|
19268
|
+
const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
|
|
19269
|
+
(0, import_node_fs42.mkdirSync)((0, import_node_path39.dirname)(configPath), { recursive: true });
|
|
19270
|
+
(0, import_node_fs42.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
|
|
19271
|
+
`);
|
|
19272
|
+
}
|
|
19273
|
+
function launchFromResolved(server) {
|
|
19274
|
+
return {
|
|
19275
|
+
command: server.command,
|
|
19276
|
+
args: server.args,
|
|
19277
|
+
env: {
|
|
19278
|
+
...server.env ?? {},
|
|
19279
|
+
SIDEBOARD_APP_DATA: appDataDir()
|
|
19280
|
+
}
|
|
19281
|
+
};
|
|
19282
|
+
}
|
|
19283
|
+
async function registerPackagedUserMcpClients() {
|
|
19284
|
+
const launch = launchFromResolved(await resolveSideboardMcpServer());
|
|
19285
|
+
const cursor = userCursorMcpConfigPath();
|
|
19286
|
+
writeMergedMcpServersJson(cursor, launch);
|
|
19287
|
+
const claude = userClaudeMcpConfigPath();
|
|
19288
|
+
if ((0, import_node_fs42.existsSync)(claude)) {
|
|
19289
|
+
writeMergedMcpServersJson(claude, launch);
|
|
19290
|
+
return { cursor, claude };
|
|
19291
|
+
}
|
|
19292
|
+
return { cursor };
|
|
19293
|
+
}
|
|
19294
|
+
|
|
18822
19295
|
// src/slack/oauth.ts
|
|
18823
19296
|
var import_node_crypto10 = require("crypto");
|
|
18824
19297
|
init_app_settings();
|
|
@@ -20125,9 +20598,9 @@ var import_node_http3 = require("http");
|
|
|
20125
20598
|
var import_ws3 = require("ws");
|
|
20126
20599
|
|
|
20127
20600
|
// src/slack/relay-static.ts
|
|
20128
|
-
var
|
|
20601
|
+
var import_node_fs43 = require("fs");
|
|
20129
20602
|
var import_promises = require("fs/promises");
|
|
20130
|
-
var
|
|
20603
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
20131
20604
|
var TYPES = {
|
|
20132
20605
|
".css": "text/css; charset=utf-8",
|
|
20133
20606
|
".html": "text/html; charset=utf-8",
|
|
@@ -20158,9 +20631,9 @@ function resolveStaticPath(root, requestUrl) {
|
|
|
20158
20631
|
return null;
|
|
20159
20632
|
}
|
|
20160
20633
|
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
20161
|
-
const rootResolved =
|
|
20162
|
-
const candidate =
|
|
20163
|
-
if (candidate !== rootResolved && !candidate.startsWith(rootResolved +
|
|
20634
|
+
const rootResolved = import_node_path40.default.resolve(root);
|
|
20635
|
+
const candidate = import_node_path40.default.resolve(rootResolved, `.${pathname}`);
|
|
20636
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path40.default.sep)) {
|
|
20164
20637
|
return null;
|
|
20165
20638
|
}
|
|
20166
20639
|
return candidate;
|
|
@@ -20174,7 +20647,7 @@ async function fileSize(file) {
|
|
|
20174
20647
|
}
|
|
20175
20648
|
}
|
|
20176
20649
|
function sendFile(req, res, file, size) {
|
|
20177
|
-
const ext =
|
|
20650
|
+
const ext = import_node_path40.default.extname(file).toLowerCase();
|
|
20178
20651
|
res.writeHead(200, {
|
|
20179
20652
|
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
20180
20653
|
"Content-Length": size,
|
|
@@ -20184,7 +20657,7 @@ function sendFile(req, res, file, size) {
|
|
|
20184
20657
|
res.end();
|
|
20185
20658
|
return true;
|
|
20186
20659
|
}
|
|
20187
|
-
(0,
|
|
20660
|
+
(0, import_node_fs43.createReadStream)(file).pipe(res);
|
|
20188
20661
|
return true;
|
|
20189
20662
|
}
|
|
20190
20663
|
async function tryServeStatic(req, res, root) {
|
|
@@ -20193,7 +20666,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
20193
20666
|
if (!candidate) return false;
|
|
20194
20667
|
const direct = await fileSize(candidate);
|
|
20195
20668
|
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
20196
|
-
const asIndex =
|
|
20669
|
+
const asIndex = import_node_path40.default.join(candidate, "index.html");
|
|
20197
20670
|
const indexSize = await fileSize(asIndex);
|
|
20198
20671
|
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
20199
20672
|
return false;
|
|
@@ -20526,6 +20999,7 @@ async function startSlackRelayServer(opts) {
|
|
|
20526
20999
|
cleanupOrphanWorktrees,
|
|
20527
21000
|
cloneRepoIntoSideboard,
|
|
20528
21001
|
codexAdapter,
|
|
21002
|
+
codexSandboxWritableRootsArgs,
|
|
20529
21003
|
codexUnattendedGitConfigArgs,
|
|
20530
21004
|
coerceOrchestratorAgent,
|
|
20531
21005
|
collectTakenTeamSlugs,
|
|
@@ -20642,6 +21116,7 @@ async function startSlackRelayServer(opts) {
|
|
|
20642
21116
|
getPr,
|
|
20643
21117
|
getPrChecks,
|
|
20644
21118
|
getPrDetails,
|
|
21119
|
+
getPrForHeadBranch,
|
|
20645
21120
|
getPrMeta,
|
|
20646
21121
|
getPrStack,
|
|
20647
21122
|
getRepoSetupInfo,
|
|
@@ -20678,6 +21153,7 @@ async function startSlackRelayServer(opts) {
|
|
|
20678
21153
|
isCloudCoordinatorThread,
|
|
20679
21154
|
isConductorBundledCli,
|
|
20680
21155
|
isCursorAutoModel,
|
|
21156
|
+
isDefaultishSourceRef,
|
|
20681
21157
|
isDirty,
|
|
20682
21158
|
isGhRateLimitError,
|
|
20683
21159
|
isGlobalRepoPath,
|
|
@@ -20744,8 +21220,10 @@ async function startSlackRelayServer(opts) {
|
|
|
20744
21220
|
maybeCompactContext,
|
|
20745
21221
|
mcpAllowTools,
|
|
20746
21222
|
mcpAuthWarnings,
|
|
21223
|
+
mergeAgentGitAuthEnv,
|
|
20747
21224
|
mergePr,
|
|
20748
21225
|
mergePrStack,
|
|
21226
|
+
mergeSideboardIntoMcpServersJson,
|
|
20749
21227
|
mergeUsage,
|
|
20750
21228
|
nextPastedTextName,
|
|
20751
21229
|
nextThinkingEffort,
|
|
@@ -20796,6 +21274,7 @@ async function startSlackRelayServer(opts) {
|
|
|
20796
21274
|
recordSlackOutboundWatch,
|
|
20797
21275
|
refreshGitHubAuth,
|
|
20798
21276
|
refreshSlackReplyBadges,
|
|
21277
|
+
registerPackagedUserMcpClients,
|
|
20799
21278
|
releaseCaffeinateHoldForThread,
|
|
20800
21279
|
removeWorkspace,
|
|
20801
21280
|
removeWorktree,
|
|
@@ -20804,9 +21283,11 @@ async function startSlackRelayServer(opts) {
|
|
|
20804
21283
|
requestReview,
|
|
20805
21284
|
requireAgent,
|
|
20806
21285
|
resetGhStackDetectCache,
|
|
21286
|
+
resetGithubAgentTokenMemo,
|
|
20807
21287
|
resolveAgentExecutable,
|
|
20808
21288
|
resolveAgentGitAuthEnv,
|
|
20809
21289
|
resolveClaudeExecutable,
|
|
21290
|
+
resolveCodexGitWritableRoots,
|
|
20810
21291
|
resolveCommandBinarySync,
|
|
20811
21292
|
resolveConductorCursorAgentId,
|
|
20812
21293
|
resolveCursorModelId,
|
|
@@ -20823,6 +21304,7 @@ async function startSlackRelayServer(opts) {
|
|
|
20823
21304
|
resolveNewThreadOptions,
|
|
20824
21305
|
resolvePlanMarkdown,
|
|
20825
21306
|
resolvePrSelector,
|
|
21307
|
+
resolvePrSelectors,
|
|
20826
21308
|
resolveQuotaFallbackAgent,
|
|
20827
21309
|
resolveRepoRoot,
|
|
20828
21310
|
resolveReviewGuidelines,
|
|
@@ -20845,6 +21327,7 @@ async function startSlackRelayServer(opts) {
|
|
|
20845
21327
|
sanitizeMcpServerName,
|
|
20846
21328
|
saveAppSettings,
|
|
20847
21329
|
saveLinearOAuth,
|
|
21330
|
+
scrubGithubTokensFromChildEnv,
|
|
20848
21331
|
secureFileUnlocksWith,
|
|
20849
21332
|
setCaffeinateHold,
|
|
20850
21333
|
setHttpFetchImpl,
|
|
@@ -20915,7 +21398,10 @@ async function startSlackRelayServer(opts) {
|
|
|
20915
21398
|
updateLinearIssue,
|
|
20916
21399
|
updateOpencodeSettings,
|
|
20917
21400
|
updateThread,
|
|
21401
|
+
userClaudeMcpConfigPath,
|
|
21402
|
+
userCursorMcpConfigPath,
|
|
20918
21403
|
validateLinearApiKey,
|
|
21404
|
+
warmGithubAgentAuth,
|
|
20919
21405
|
withAgentInstructions,
|
|
20920
21406
|
withExportedPath,
|
|
20921
21407
|
withThreadLock,
|