@sideboard-ai/core 0.1.97 → 0.1.99
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 +47 -2
- package/dist/agents/cursor-runner.js +47 -2
- package/dist/{agents-WS5QV6LE.js → agents-3MWWWSMF.js} +2 -2
- package/dist/{agents-HBLA6FEV.js → agents-ESJKIQQA.js} +2 -2
- package/dist/{chunk-CLGO7TLO.js → chunk-FO67IJTY.js} +24 -25
- package/dist/{chunk-WBX46OPD.js → chunk-FYS2BULQ.js} +2 -2
- package/dist/{chunk-NR6APJLD.js → chunk-HI2OTFFR.js} +24 -25
- package/dist/{chunk-KWNUZ4LR.js → chunk-MBP3XG57.js} +2 -2
- package/dist/{chunk-6XBXVXX2.js → chunk-OANJQTVG.js} +1 -1
- package/dist/{chunk-QKYO6BHB.js → chunk-UYQYK2RY.js} +1 -1
- package/dist/{global-workspace-M3OMVDDH.js → global-workspace-RSQXRLT7.js} +3 -1
- package/dist/{global-workspace-3GNPQCLE.js → global-workspace-WMF3BJP5.js} +3 -1
- package/dist/index.cjs +541 -420
- package/dist/index.d.cts +24 -3
- package/dist/index.d.ts +24 -3
- package/dist/index.js +241 -128
- package/dist/mcp/run-stdio.cjs +225 -167
- package/dist/mcp/run-stdio.js +129 -70
- package/dist/{workspaces-ERZC7ULY.js → workspaces-4ZY4QPWQ.js} +2 -2
- package/dist/{workspaces-J4WG6UFR.js → workspaces-MZVQHRSJ.js} +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3072,23 +3072,23 @@ var init_gh_errors = __esm({
|
|
|
3072
3072
|
function githubAgentAuthDir() {
|
|
3073
3073
|
const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
|
|
3074
3074
|
if (override) return override;
|
|
3075
|
-
return (0,
|
|
3075
|
+
return (0, import_node_path11.join)((0, import_node_os4.homedir)(), ".sideboard-git-auth");
|
|
3076
3076
|
}
|
|
3077
3077
|
function githubCredentialStorePath() {
|
|
3078
|
-
return (0,
|
|
3078
|
+
return (0, import_node_path11.join)(githubAgentAuthDir(), "git-credentials");
|
|
3079
3079
|
}
|
|
3080
3080
|
function githubGhConfigDir() {
|
|
3081
|
-
return (0,
|
|
3081
|
+
return (0, import_node_path11.join)(githubAgentAuthDir(), "gh");
|
|
3082
3082
|
}
|
|
3083
3083
|
function writePrivateFile2(file, body) {
|
|
3084
|
-
(0,
|
|
3084
|
+
(0, import_node_fs11.mkdirSync)((0, import_node_path11.dirname)(file), { recursive: true, mode: 448 });
|
|
3085
3085
|
try {
|
|
3086
|
-
(0,
|
|
3086
|
+
(0, import_node_fs11.chmodSync)((0, import_node_path11.dirname)(file), 448);
|
|
3087
3087
|
} catch {
|
|
3088
3088
|
}
|
|
3089
|
-
(0,
|
|
3089
|
+
(0, import_node_fs11.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
|
|
3090
3090
|
try {
|
|
3091
|
-
(0,
|
|
3091
|
+
(0, import_node_fs11.chmodSync)(file, 384);
|
|
3092
3092
|
} catch {
|
|
3093
3093
|
}
|
|
3094
3094
|
}
|
|
@@ -3113,19 +3113,19 @@ function materializeGithubAgentAuth(token, user) {
|
|
|
3113
3113
|
const trimmed = token.trim();
|
|
3114
3114
|
if (!trimmed) return;
|
|
3115
3115
|
const root = githubAgentAuthDir();
|
|
3116
|
-
(0,
|
|
3116
|
+
(0, import_node_fs11.mkdirSync)(root, { recursive: true, mode: 448 });
|
|
3117
3117
|
try {
|
|
3118
|
-
(0,
|
|
3118
|
+
(0, import_node_fs11.chmodSync)(root, 448);
|
|
3119
3119
|
} catch {
|
|
3120
3120
|
}
|
|
3121
3121
|
writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
|
|
3122
3122
|
const ghDir = githubGhConfigDir();
|
|
3123
|
-
(0,
|
|
3124
|
-
writePrivateFile2((0,
|
|
3125
|
-
writePrivateFile2((0,
|
|
3123
|
+
(0, import_node_fs11.mkdirSync)(ghDir, { recursive: true, mode: 448 });
|
|
3124
|
+
writePrivateFile2((0, import_node_path11.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
|
|
3125
|
+
writePrivateFile2((0, import_node_path11.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
|
|
3126
3126
|
}
|
|
3127
3127
|
function githubAgentAuthReady() {
|
|
3128
|
-
return (0,
|
|
3128
|
+
return (0, import_node_fs11.existsSync)(githubCredentialStorePath()) && (0, import_node_fs11.existsSync)((0, import_node_path11.join)(githubGhConfigDir(), "hosts.yml"));
|
|
3129
3129
|
}
|
|
3130
3130
|
function githubCredentialHelperGitConfig() {
|
|
3131
3131
|
const file = githubCredentialStorePath();
|
|
@@ -3140,29 +3140,29 @@ function githubGhConfigEnv() {
|
|
|
3140
3140
|
GH_PROMPT_DISABLED: "1"
|
|
3141
3141
|
};
|
|
3142
3142
|
}
|
|
3143
|
-
var
|
|
3143
|
+
var import_node_fs11, import_node_os4, import_node_path11;
|
|
3144
3144
|
var init_github_agent_auth = __esm({
|
|
3145
3145
|
"src/git/github-agent-auth.ts"() {
|
|
3146
3146
|
"use strict";
|
|
3147
|
-
|
|
3147
|
+
import_node_fs11 = require("fs");
|
|
3148
3148
|
import_node_os4 = require("os");
|
|
3149
|
-
|
|
3149
|
+
import_node_path11 = require("path");
|
|
3150
3150
|
}
|
|
3151
3151
|
});
|
|
3152
3152
|
|
|
3153
3153
|
// src/agents/path.ts
|
|
3154
3154
|
function prependPathDir(env, dir) {
|
|
3155
|
-
if (!dir || !(0,
|
|
3155
|
+
if (!dir || !(0, import_node_fs12.existsSync)(dir)) return;
|
|
3156
3156
|
const current = env.PATH ?? "";
|
|
3157
|
-
const parts = current.split(
|
|
3157
|
+
const parts = current.split(import_node_path12.delimiter).filter(Boolean);
|
|
3158
3158
|
if (parts.includes(dir)) {
|
|
3159
3159
|
env.PATH = current;
|
|
3160
3160
|
return;
|
|
3161
3161
|
}
|
|
3162
|
-
env.PATH = [dir, ...parts].join(
|
|
3162
|
+
env.PATH = [dir, ...parts].join(import_node_path12.delimiter);
|
|
3163
3163
|
}
|
|
3164
3164
|
function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os5.homedir)()) {
|
|
3165
|
-
return (0,
|
|
3165
|
+
return (0, import_node_path12.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
|
|
3166
3166
|
}
|
|
3167
3167
|
function isConductorBundledCli(filePath) {
|
|
3168
3168
|
const p = (filePath ?? "").replace(/\\/g, "/");
|
|
@@ -3171,21 +3171,21 @@ function isConductorBundledCli(filePath) {
|
|
|
3171
3171
|
function ensureAgentPath(env = process.env) {
|
|
3172
3172
|
const home = env.HOME || env.USERPROFILE || (0, import_node_os5.homedir)();
|
|
3173
3173
|
const current = env.PATH ?? "";
|
|
3174
|
-
const parts = current.split(
|
|
3174
|
+
const parts = current.split(import_node_path12.delimiter).filter(Boolean);
|
|
3175
3175
|
const seen = new Set(parts);
|
|
3176
3176
|
const extras = [
|
|
3177
|
-
...EXTRA_BIN_DIRS.map((rel) => (0,
|
|
3177
|
+
...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path12.join)(home, rel)),
|
|
3178
3178
|
"/opt/homebrew/bin",
|
|
3179
3179
|
"/usr/local/bin",
|
|
3180
3180
|
// Keep after Homebrew/npm so a user-installed CLI still wins.
|
|
3181
3181
|
conductorBundledBinDir(home)
|
|
3182
3182
|
];
|
|
3183
3183
|
for (const dir of extras.reverse()) {
|
|
3184
|
-
if (!dir || seen.has(dir) || !(0,
|
|
3184
|
+
if (!dir || seen.has(dir) || !(0, import_node_fs12.existsSync)(dir)) continue;
|
|
3185
3185
|
parts.unshift(dir);
|
|
3186
3186
|
seen.add(dir);
|
|
3187
3187
|
}
|
|
3188
|
-
const next = parts.join(
|
|
3188
|
+
const next = parts.join(import_node_path12.delimiter);
|
|
3189
3189
|
env.PATH = next;
|
|
3190
3190
|
return next;
|
|
3191
3191
|
}
|
|
@@ -3199,7 +3199,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
|
|
|
3199
3199
|
stdio: ["ignore", "pipe", "ignore"]
|
|
3200
3200
|
}).trim().split(/\r?\n/).find(Boolean);
|
|
3201
3201
|
if (prefix) {
|
|
3202
|
-
const binDir = process.platform === "win32" ? prefix : (0,
|
|
3202
|
+
const binDir = process.platform === "win32" ? prefix : (0, import_node_path12.join)(prefix, "bin");
|
|
3203
3203
|
prependPathDir(env, binDir);
|
|
3204
3204
|
}
|
|
3205
3205
|
} catch {
|
|
@@ -3227,14 +3227,14 @@ function withExportedPath(command, pathValue) {
|
|
|
3227
3227
|
if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
|
|
3228
3228
|
return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
|
|
3229
3229
|
}
|
|
3230
|
-
var
|
|
3230
|
+
var import_node_fs12, import_node_child_process3, import_node_os5, import_node_path12, EXTRA_BIN_DIRS;
|
|
3231
3231
|
var init_path = __esm({
|
|
3232
3232
|
"src/agents/path.ts"() {
|
|
3233
3233
|
"use strict";
|
|
3234
|
-
|
|
3234
|
+
import_node_fs12 = require("fs");
|
|
3235
3235
|
import_node_child_process3 = require("child_process");
|
|
3236
3236
|
import_node_os5 = require("os");
|
|
3237
|
-
|
|
3237
|
+
import_node_path12 = require("path");
|
|
3238
3238
|
EXTRA_BIN_DIRS = [
|
|
3239
3239
|
".local/bin",
|
|
3240
3240
|
".cargo/bin",
|
|
@@ -3426,7 +3426,7 @@ async function warmGithubAgentAuth(opts) {
|
|
|
3426
3426
|
}
|
|
3427
3427
|
function normalizeWritableRoot(raw) {
|
|
3428
3428
|
const trimmed = raw.trim().replace(/\/+$/, "");
|
|
3429
|
-
return trimmed && (0,
|
|
3429
|
+
return trimmed && (0, import_node_path13.isAbsolute)(trimmed) ? trimmed : null;
|
|
3430
3430
|
}
|
|
3431
3431
|
async function resolveCodexGitWritableRoots(cwd) {
|
|
3432
3432
|
const roots = /* @__PURE__ */ new Set();
|
|
@@ -3503,11 +3503,11 @@ function formatGitAuthModeDirective(mode) {
|
|
|
3503
3503
|
].join("\n");
|
|
3504
3504
|
}
|
|
3505
3505
|
}
|
|
3506
|
-
var
|
|
3506
|
+
var import_node_path13, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
|
|
3507
3507
|
var init_git_auth_mode = __esm({
|
|
3508
3508
|
"src/git/git-auth-mode.ts"() {
|
|
3509
3509
|
"use strict";
|
|
3510
|
-
|
|
3510
|
+
import_node_path13 = require("path");
|
|
3511
3511
|
init_app_settings();
|
|
3512
3512
|
init_github_agent_auth();
|
|
3513
3513
|
init_run();
|
|
@@ -4669,8 +4669,8 @@ function isLocalPrFetchBranch(ref) {
|
|
|
4669
4669
|
}
|
|
4670
4670
|
async function createThreadWorktree(opts) {
|
|
4671
4671
|
let branchName = `thread/${opts.slug}`;
|
|
4672
|
-
const worktreePath = (0,
|
|
4673
|
-
if ((0,
|
|
4672
|
+
const worktreePath = (0, import_node_path14.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
4673
|
+
if ((0, import_node_fs13.existsSync)(worktreePath)) {
|
|
4674
4674
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
4675
4675
|
}
|
|
4676
4676
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -4739,8 +4739,8 @@ ${add.stdout}`;
|
|
|
4739
4739
|
async function createExistingBranchWorktree(opts) {
|
|
4740
4740
|
const branchName = opts.branchName.trim();
|
|
4741
4741
|
if (!branchName) throw new Error("branch name required");
|
|
4742
|
-
const worktreePath = (0,
|
|
4743
|
-
if ((0,
|
|
4742
|
+
const worktreePath = (0, import_node_path14.join)(worktreesRoot(opts.repoPath), opts.slug);
|
|
4743
|
+
if ((0, import_node_fs13.existsSync)(worktreePath)) {
|
|
4744
4744
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
4745
4745
|
}
|
|
4746
4746
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -5028,10 +5028,10 @@ function sameRepoPath(a, b) {
|
|
|
5028
5028
|
return normalizeWorktreePath(a) === normalizeWorktreePath(b);
|
|
5029
5029
|
}
|
|
5030
5030
|
function listLocalThreadBranchSlugs(repoPath) {
|
|
5031
|
-
const refsDir = (0,
|
|
5032
|
-
if (!(0,
|
|
5031
|
+
const refsDir = (0, import_node_path14.join)(repoPath, ".git", "refs", "heads", "thread");
|
|
5032
|
+
if (!(0, import_node_fs13.existsSync)(refsDir)) return [];
|
|
5033
5033
|
try {
|
|
5034
|
-
return (0,
|
|
5034
|
+
return (0, import_node_fs13.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
|
|
5035
5035
|
} catch {
|
|
5036
5036
|
return [];
|
|
5037
5037
|
}
|
|
@@ -5039,8 +5039,8 @@ function listLocalThreadBranchSlugs(repoPath) {
|
|
|
5039
5039
|
function collectTakenTeamSlugs(repoPath) {
|
|
5040
5040
|
const taken = /* @__PURE__ */ new Set();
|
|
5041
5041
|
const root = worktreesRoot(repoPath);
|
|
5042
|
-
if ((0,
|
|
5043
|
-
for (const entry of (0,
|
|
5042
|
+
if ((0, import_node_fs13.existsSync)(root)) {
|
|
5043
|
+
for (const entry of (0, import_node_fs13.readdirSync)(root, { withFileTypes: true })) {
|
|
5044
5044
|
if (entry.isDirectory() && entry.name !== ".DS_Store") {
|
|
5045
5045
|
taken.add(normalizeTakenSlug(entry.name));
|
|
5046
5046
|
}
|
|
@@ -5061,18 +5061,18 @@ function allocateTeamSlug(repoPath) {
|
|
|
5061
5061
|
const taken = collectTakenTeamSlugs(repoPath);
|
|
5062
5062
|
for (let attempt = 0; attempt < 32; attempt++) {
|
|
5063
5063
|
const team = allocateTeamName(taken);
|
|
5064
|
-
const path2 = (0,
|
|
5065
|
-
if (!(0,
|
|
5064
|
+
const path2 = (0, import_node_path14.join)(worktreesRoot(repoPath), team.slug);
|
|
5065
|
+
if (!(0, import_node_fs13.existsSync)(path2)) return team;
|
|
5066
5066
|
taken.add(team.slug);
|
|
5067
5067
|
}
|
|
5068
5068
|
throw new Error("No available soccer team worktree directories left");
|
|
5069
5069
|
}
|
|
5070
|
-
var
|
|
5070
|
+
var import_node_fs13, import_node_path14;
|
|
5071
5071
|
var init_worktree = __esm({
|
|
5072
5072
|
"src/git/worktree.ts"() {
|
|
5073
5073
|
"use strict";
|
|
5074
|
-
|
|
5075
|
-
|
|
5074
|
+
import_node_fs13 = require("fs");
|
|
5075
|
+
import_node_path14 = require("path");
|
|
5076
5076
|
init_paths();
|
|
5077
5077
|
init_thread_store();
|
|
5078
5078
|
init_teams();
|
|
@@ -5156,7 +5156,7 @@ function coordinatorTurnReminder(opts) {
|
|
|
5156
5156
|
function ensureGlobalCoordinatorCwd(opts) {
|
|
5157
5157
|
const dir = globalAgentCwd();
|
|
5158
5158
|
try {
|
|
5159
|
-
(0,
|
|
5159
|
+
(0, import_node_fs14.mkdirSync)(dir, { recursive: true });
|
|
5160
5160
|
} catch {
|
|
5161
5161
|
return dir;
|
|
5162
5162
|
}
|
|
@@ -5164,7 +5164,7 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
5164
5164
|
let orchId = opts?.orchestratorThreadId?.trim() || "";
|
|
5165
5165
|
if (!orchId) {
|
|
5166
5166
|
try {
|
|
5167
|
-
const existing = (0,
|
|
5167
|
+
const existing = (0, import_node_fs14.readFileSync)((0, import_node_path15.join)(dir, "AGENTS.md"), "utf8");
|
|
5168
5168
|
const m = existing.match(
|
|
5169
5169
|
/YOUR orchestration thread id is `([0-9a-f-]{36})`/i
|
|
5170
5170
|
);
|
|
@@ -5206,9 +5206,9 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
5206
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."
|
|
5207
5207
|
].join("\n");
|
|
5208
5208
|
try {
|
|
5209
|
-
(0,
|
|
5209
|
+
(0, import_node_fs14.writeFileSync)((0, import_node_path15.join)(dir, "CLAUDE.md"), `${body}
|
|
5210
5210
|
`, "utf8");
|
|
5211
|
-
(0,
|
|
5211
|
+
(0, import_node_fs14.writeFileSync)((0, import_node_path15.join)(dir, "AGENTS.md"), `${body}
|
|
5212
5212
|
`, "utf8");
|
|
5213
5213
|
} catch {
|
|
5214
5214
|
}
|
|
@@ -5240,12 +5240,12 @@ function coordinatorSystemPrompt(opts) {
|
|
|
5240
5240
|
formatWorkspaceInventory(opts.workspaces)
|
|
5241
5241
|
].join("\n");
|
|
5242
5242
|
}
|
|
5243
|
-
var
|
|
5243
|
+
var import_node_fs14, import_node_path15, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
|
|
5244
5244
|
var init_coordinator_prompt = __esm({
|
|
5245
5245
|
"src/orchestrator/coordinator-prompt.ts"() {
|
|
5246
5246
|
"use strict";
|
|
5247
|
-
|
|
5248
|
-
|
|
5247
|
+
import_node_fs14 = require("fs");
|
|
5248
|
+
import_node_path15 = require("path");
|
|
5249
5249
|
init_worktree();
|
|
5250
5250
|
init_app_settings();
|
|
5251
5251
|
init_paths();
|
|
@@ -5307,6 +5307,7 @@ __export(global_workspace_exports, {
|
|
|
5307
5307
|
createGlobalChat: () => createGlobalChat,
|
|
5308
5308
|
ensureCloudCoordinator: () => ensureCloudCoordinator,
|
|
5309
5309
|
ensureSlackCoordinator: () => ensureSlackCoordinator,
|
|
5310
|
+
findSlackCoordinator: () => findSlackCoordinator,
|
|
5310
5311
|
globalAgentCwd: () => globalAgentCwd,
|
|
5311
5312
|
healOrchestrationSoccerTitles: () => healOrchestrationSoccerTitles,
|
|
5312
5313
|
isCloudCoordinatorThread: () => isCloudCoordinatorThread,
|
|
@@ -5453,42 +5454,40 @@ function findSlackCoordinator(teamId, userId) {
|
|
|
5453
5454
|
(t) => t.status !== "archived" && t.sourceRef === ref && isSlackCoordinatorThread(t)
|
|
5454
5455
|
);
|
|
5455
5456
|
}
|
|
5456
|
-
function ensureSlackCoordinator(teamId, userId, agent) {
|
|
5457
|
+
function ensureSlackCoordinator(teamId, userId, agent, opts) {
|
|
5457
5458
|
const defaults = resolveThreadDefaults();
|
|
5458
5459
|
const desired = assertOrchestratorCapableAgent(agent);
|
|
5459
5460
|
const ref = slackCoordinatorSourceRef(teamId, userId);
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
if (
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5461
|
+
if (!opts?.forceNew) {
|
|
5462
|
+
const existing = findSlackCoordinator(teamId, userId);
|
|
5463
|
+
if (existing) {
|
|
5464
|
+
const patch = {};
|
|
5465
|
+
if (existing.repoPath !== GLOBAL_WORKSPACE_ID) {
|
|
5466
|
+
patch.repoPath = GLOBAL_WORKSPACE_ID;
|
|
5467
|
+
patch.worktreePath = globalAgentCwd();
|
|
5468
|
+
patch.branchName = "global";
|
|
5469
|
+
}
|
|
5470
|
+
const hasAgentTurns = existing.messages.some((m) => m.role === "agent");
|
|
5471
|
+
const canRetarget = !existing.sessionId && !hasAgentTurns && existing.status !== "running" && existing.status !== "queued";
|
|
5472
|
+
if (canRetarget) {
|
|
5473
|
+
if (existing.agent !== desired) patch.agent = desired;
|
|
5474
|
+
if (existing.model !== defaults.model) patch.model = defaults.model;
|
|
5475
|
+
if (existing.effort !== defaults.effort) patch.effort = defaults.effort;
|
|
5476
|
+
if (existing.fast !== defaults.fast) patch.fast = defaults.fast;
|
|
5477
|
+
}
|
|
5478
|
+
if (Object.keys(patch).length > 0) {
|
|
5479
|
+
return updateThread(existing.id, patch);
|
|
5480
|
+
}
|
|
5481
|
+
return existing;
|
|
5478
5482
|
}
|
|
5479
|
-
return existing;
|
|
5480
5483
|
}
|
|
5481
|
-
|
|
5484
|
+
return createGlobalChat({
|
|
5482
5485
|
sourceRef: ref,
|
|
5483
5486
|
agent: desired,
|
|
5484
5487
|
model: defaults.model,
|
|
5485
5488
|
effort: defaults.effort,
|
|
5486
5489
|
fast: defaults.fast
|
|
5487
5490
|
});
|
|
5488
|
-
const all = listThreads({ includeArchived: true }).filter(
|
|
5489
|
-
(t) => t.status !== "archived" && t.sourceRef === ref && isSlackCoordinatorThread(t)
|
|
5490
|
-
).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
5491
|
-
return all[0] ?? created;
|
|
5492
5491
|
}
|
|
5493
5492
|
function ensureCloudCoordinator(agent) {
|
|
5494
5493
|
const defaults = resolveThreadDefaults();
|
|
@@ -5551,38 +5550,38 @@ __export(workspaces_exports, {
|
|
|
5551
5550
|
syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
|
|
5552
5551
|
});
|
|
5553
5552
|
function workspacesFile() {
|
|
5554
|
-
return (0,
|
|
5553
|
+
return (0, import_node_path16.join)(appDataDir(), "workspaces.json");
|
|
5555
5554
|
}
|
|
5556
5555
|
function removedWorkspacesFile() {
|
|
5557
|
-
return (0,
|
|
5556
|
+
return (0, import_node_path16.join)(appDataDir(), "removed-workspaces.json");
|
|
5558
5557
|
}
|
|
5559
5558
|
function readAll() {
|
|
5560
5559
|
const path2 = workspacesFile();
|
|
5561
|
-
if (!(0,
|
|
5560
|
+
if (!(0, import_node_fs15.existsSync)(path2)) return [];
|
|
5562
5561
|
try {
|
|
5563
|
-
const raw = JSON.parse((0,
|
|
5562
|
+
const raw = JSON.parse((0, import_node_fs15.readFileSync)(path2, "utf8"));
|
|
5564
5563
|
return Array.isArray(raw) ? raw : [];
|
|
5565
5564
|
} catch {
|
|
5566
5565
|
return [];
|
|
5567
5566
|
}
|
|
5568
5567
|
}
|
|
5569
5568
|
function writeAll(list) {
|
|
5570
|
-
(0,
|
|
5571
|
-
(0,
|
|
5569
|
+
(0, import_node_fs15.mkdirSync)(appDataDir(), { recursive: true });
|
|
5570
|
+
(0, import_node_fs15.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
|
|
5572
5571
|
}
|
|
5573
5572
|
function readRemoved() {
|
|
5574
5573
|
const path2 = removedWorkspacesFile();
|
|
5575
|
-
if (!(0,
|
|
5574
|
+
if (!(0, import_node_fs15.existsSync)(path2)) return /* @__PURE__ */ new Set();
|
|
5576
5575
|
try {
|
|
5577
|
-
const raw = JSON.parse((0,
|
|
5576
|
+
const raw = JSON.parse((0, import_node_fs15.readFileSync)(path2, "utf8"));
|
|
5578
5577
|
return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
|
|
5579
5578
|
} catch {
|
|
5580
5579
|
return /* @__PURE__ */ new Set();
|
|
5581
5580
|
}
|
|
5582
5581
|
}
|
|
5583
5582
|
function writeRemoved(paths) {
|
|
5584
|
-
(0,
|
|
5585
|
-
(0,
|
|
5583
|
+
(0, import_node_fs15.mkdirSync)(appDataDir(), { recursive: true });
|
|
5584
|
+
(0, import_node_fs15.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
|
|
5586
5585
|
}
|
|
5587
5586
|
function rememberRemoved(repoPath) {
|
|
5588
5587
|
const next = readRemoved();
|
|
@@ -5605,7 +5604,7 @@ function listWorkspaces() {
|
|
|
5605
5604
|
async function addWorkspace(repoPath) {
|
|
5606
5605
|
const root = await resolveRepoRoot(repoPath);
|
|
5607
5606
|
if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
|
|
5608
|
-
if (!(0,
|
|
5607
|
+
if (!(0, import_node_fs15.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
|
|
5609
5608
|
forgetRemoved(root);
|
|
5610
5609
|
await ensureGhPreferOrigin(root);
|
|
5611
5610
|
const current = readAll();
|
|
@@ -5613,7 +5612,7 @@ async function addWorkspace(repoPath) {
|
|
|
5613
5612
|
if (existing) return existing;
|
|
5614
5613
|
const next = {
|
|
5615
5614
|
path: root,
|
|
5616
|
-
name: (0,
|
|
5615
|
+
name: (0, import_node_path16.basename)(root),
|
|
5617
5616
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5618
5617
|
};
|
|
5619
5618
|
writeAll([...current, next]);
|
|
@@ -5635,10 +5634,10 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
5635
5634
|
if (!path2 || path2 === "/" || isGlobalRepoPath(path2) || byPath.has(path2) || removed.has(path2)) {
|
|
5636
5635
|
continue;
|
|
5637
5636
|
}
|
|
5638
|
-
if (!(0,
|
|
5637
|
+
if (!(0, import_node_fs15.existsSync)(path2)) continue;
|
|
5639
5638
|
const ws = {
|
|
5640
5639
|
path: path2,
|
|
5641
|
-
name: (0,
|
|
5640
|
+
name: (0, import_node_path16.basename)(path2),
|
|
5642
5641
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5643
5642
|
};
|
|
5644
5643
|
byPath.set(path2, ws);
|
|
@@ -5648,12 +5647,12 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
5648
5647
|
if (dirty) writeAll(next);
|
|
5649
5648
|
return next.sort((a, b) => a.name.localeCompare(b.name));
|
|
5650
5649
|
}
|
|
5651
|
-
var
|
|
5650
|
+
var import_node_fs15, import_node_path16;
|
|
5652
5651
|
var init_workspaces = __esm({
|
|
5653
5652
|
"src/store/workspaces.ts"() {
|
|
5654
5653
|
"use strict";
|
|
5655
|
-
|
|
5656
|
-
|
|
5654
|
+
import_node_fs15 = require("fs");
|
|
5655
|
+
import_node_path16 = require("path");
|
|
5657
5656
|
init_paths();
|
|
5658
5657
|
init_global_workspace();
|
|
5659
5658
|
init_worktree();
|
|
@@ -5662,32 +5661,32 @@ var init_workspaces = __esm({
|
|
|
5662
5661
|
|
|
5663
5662
|
// src/brightsy/config.ts
|
|
5664
5663
|
function brightsyConfigPath() {
|
|
5665
|
-
return (0,
|
|
5664
|
+
return (0, import_node_path17.join)((0, import_node_os6.homedir)(), ".brightsy", "config.json");
|
|
5666
5665
|
}
|
|
5667
5666
|
function loadBrightsyConfig() {
|
|
5668
5667
|
const path2 = brightsyConfigPath();
|
|
5669
|
-
if (!(0,
|
|
5668
|
+
if (!(0, import_node_fs16.existsSync)(path2)) {
|
|
5670
5669
|
throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
|
|
5671
5670
|
}
|
|
5672
|
-
const raw = JSON.parse((0,
|
|
5671
|
+
const raw = JSON.parse((0, import_node_fs16.readFileSync)(path2, "utf8"));
|
|
5673
5672
|
if (!raw.access_token || !raw.account_id) {
|
|
5674
5673
|
throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
|
|
5675
5674
|
}
|
|
5676
5675
|
return raw;
|
|
5677
5676
|
}
|
|
5678
5677
|
function saveBrightsyConfig(cfg) {
|
|
5679
|
-
(0,
|
|
5678
|
+
(0, import_node_fs16.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
|
|
5680
5679
|
`, {
|
|
5681
5680
|
mode: 384
|
|
5682
5681
|
});
|
|
5683
5682
|
}
|
|
5684
|
-
var
|
|
5683
|
+
var import_node_fs16, import_node_os6, import_node_path17;
|
|
5685
5684
|
var init_config = __esm({
|
|
5686
5685
|
"src/brightsy/config.ts"() {
|
|
5687
5686
|
"use strict";
|
|
5688
|
-
|
|
5687
|
+
import_node_fs16 = require("fs");
|
|
5689
5688
|
import_node_os6 = require("os");
|
|
5690
|
-
|
|
5689
|
+
import_node_path17 = require("path");
|
|
5691
5690
|
}
|
|
5692
5691
|
});
|
|
5693
5692
|
|
|
@@ -5790,22 +5789,22 @@ __export(connected_teams_exports, {
|
|
|
5790
5789
|
listConnectedBrightsyTeams: () => listConnectedBrightsyTeams
|
|
5791
5790
|
});
|
|
5792
5791
|
function storePath() {
|
|
5793
|
-
return (0,
|
|
5792
|
+
return (0, import_node_path18.join)(appDataDir(), "brightsy-teams.json");
|
|
5794
5793
|
}
|
|
5795
5794
|
function readStore() {
|
|
5796
5795
|
const path2 = storePath();
|
|
5797
|
-
if (!(0,
|
|
5796
|
+
if (!(0, import_node_fs17.existsSync)(path2)) return [];
|
|
5798
5797
|
try {
|
|
5799
|
-
const parsed = JSON.parse((0,
|
|
5798
|
+
const parsed = JSON.parse((0, import_node_fs17.readFileSync)(path2, "utf8"));
|
|
5800
5799
|
return Array.isArray(parsed.teams) ? parsed.teams : [];
|
|
5801
5800
|
} catch {
|
|
5802
5801
|
return [];
|
|
5803
5802
|
}
|
|
5804
5803
|
}
|
|
5805
5804
|
function writeStore(teams) {
|
|
5806
|
-
(0,
|
|
5805
|
+
(0, import_node_fs17.mkdirSync)(appDataDir(), { recursive: true });
|
|
5807
5806
|
const path2 = storePath();
|
|
5808
|
-
(0,
|
|
5807
|
+
(0, import_node_fs17.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
|
|
5809
5808
|
`, {
|
|
5810
5809
|
mode: 384
|
|
5811
5810
|
});
|
|
@@ -5967,12 +5966,12 @@ function brightsyMcpServerName(slug) {
|
|
|
5967
5966
|
const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
|
|
5968
5967
|
return `brightsy_${cleaned || "team"}`;
|
|
5969
5968
|
}
|
|
5970
|
-
var
|
|
5969
|
+
var import_node_fs17, import_node_path18;
|
|
5971
5970
|
var init_connected_teams = __esm({
|
|
5972
5971
|
"src/brightsy/connected-teams.ts"() {
|
|
5973
5972
|
"use strict";
|
|
5974
|
-
|
|
5975
|
-
|
|
5973
|
+
import_node_fs17 = require("fs");
|
|
5974
|
+
import_node_path18 = require("path");
|
|
5976
5975
|
init_paths();
|
|
5977
5976
|
init_accounts();
|
|
5978
5977
|
init_config();
|
|
@@ -6522,11 +6521,11 @@ async function syncCliForTarget(accountId) {
|
|
|
6522
6521
|
}
|
|
6523
6522
|
applyConnectedTeamToCli(team);
|
|
6524
6523
|
}
|
|
6525
|
-
var
|
|
6524
|
+
var import_node_fs18, brightsyAdapter;
|
|
6526
6525
|
var init_brightsy = __esm({
|
|
6527
6526
|
"src/agents/brightsy.ts"() {
|
|
6528
6527
|
"use strict";
|
|
6529
|
-
|
|
6528
|
+
import_node_fs18 = require("fs");
|
|
6530
6529
|
init_run();
|
|
6531
6530
|
init_connected_teams();
|
|
6532
6531
|
init_config();
|
|
@@ -6541,7 +6540,7 @@ var init_brightsy = __esm({
|
|
|
6541
6540
|
async detect() {
|
|
6542
6541
|
const brightsy = resolveAgentExecutable("brightsy");
|
|
6543
6542
|
if (brightsy !== "brightsy") {
|
|
6544
|
-
if (!(0,
|
|
6543
|
+
if (!(0, import_node_fs18.existsSync)(brightsy)) {
|
|
6545
6544
|
return {
|
|
6546
6545
|
agent: "brightsy",
|
|
6547
6546
|
installed: false,
|
|
@@ -6683,7 +6682,7 @@ function unpackedAsarPath(filePath) {
|
|
|
6683
6682
|
if (!isAsarPath(filePath)) return null;
|
|
6684
6683
|
const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
|
|
6685
6684
|
if (unpacked === filePath) return null;
|
|
6686
|
-
return (0,
|
|
6685
|
+
return (0, import_node_fs19.existsSync)(unpacked) ? unpacked : null;
|
|
6687
6686
|
}
|
|
6688
6687
|
function nodeReadableScriptPath(scriptPath) {
|
|
6689
6688
|
return unpackedAsarPath(scriptPath) ?? scriptPath;
|
|
@@ -6694,11 +6693,11 @@ async function findSystemNode() {
|
|
|
6694
6693
|
if (fromWhich && !isElectronLikeCommand(fromWhich)) return fromWhich;
|
|
6695
6694
|
const fallbacks = [
|
|
6696
6695
|
...WELL_KNOWN_NODE_BINS,
|
|
6697
|
-
(0,
|
|
6698
|
-
(0,
|
|
6696
|
+
(0, import_node_path19.join)((0, import_node_os7.homedir)(), ".local/share/fnm/aliases/default/bin/node"),
|
|
6697
|
+
(0, import_node_path19.join)((0, import_node_os7.homedir)(), ".nvm/current/bin/node")
|
|
6699
6698
|
];
|
|
6700
6699
|
for (const bin of fallbacks) {
|
|
6701
|
-
if ((0,
|
|
6700
|
+
if ((0, import_node_fs19.existsSync)(bin) && !isElectronLikeCommand(bin)) return bin;
|
|
6702
6701
|
}
|
|
6703
6702
|
return null;
|
|
6704
6703
|
}
|
|
@@ -6728,13 +6727,13 @@ async function resolveNodeLaunch(scriptPath) {
|
|
|
6728
6727
|
env: { ELECTRON_RUN_AS_NODE: "1" }
|
|
6729
6728
|
};
|
|
6730
6729
|
}
|
|
6731
|
-
var
|
|
6730
|
+
var import_node_fs19, import_node_os7, import_node_path19, WELL_KNOWN_NODE_BINS;
|
|
6732
6731
|
var init_node_launch = __esm({
|
|
6733
6732
|
"src/agents/node-launch.ts"() {
|
|
6734
6733
|
"use strict";
|
|
6735
|
-
|
|
6734
|
+
import_node_fs19 = require("fs");
|
|
6736
6735
|
import_node_os7 = require("os");
|
|
6737
|
-
|
|
6736
|
+
import_node_path19 = require("path");
|
|
6738
6737
|
init_nested_electron_env();
|
|
6739
6738
|
init_run();
|
|
6740
6739
|
WELL_KNOWN_NODE_BINS = [
|
|
@@ -6753,36 +6752,36 @@ function electronResourcesPath() {
|
|
|
6753
6752
|
function packagedCursorRuntimeDir() {
|
|
6754
6753
|
const resources = electronResourcesPath();
|
|
6755
6754
|
if (!resources) return null;
|
|
6756
|
-
const dir = (0,
|
|
6757
|
-
if (!(0,
|
|
6755
|
+
const dir = (0, import_node_path20.join)(resources, "cursor-runtime");
|
|
6756
|
+
if (!(0, import_node_fs20.existsSync)((0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
|
|
6758
6757
|
return dir;
|
|
6759
6758
|
}
|
|
6760
6759
|
function packagedCursorRunnerPath() {
|
|
6761
6760
|
const dir = packagedCursorRuntimeDir();
|
|
6762
|
-
return dir ? (0,
|
|
6761
|
+
return dir ? (0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
|
|
6763
6762
|
}
|
|
6764
6763
|
function packagedMcpDir() {
|
|
6765
6764
|
const resources = electronResourcesPath();
|
|
6766
6765
|
if (!resources) return null;
|
|
6767
|
-
const dir = (0,
|
|
6768
|
-
if (!(0,
|
|
6766
|
+
const dir = (0, import_node_path20.join)(resources, "sideboard-mcp");
|
|
6767
|
+
if (!(0, import_node_fs20.existsSync)((0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
|
|
6769
6768
|
return dir;
|
|
6770
6769
|
}
|
|
6771
6770
|
function packagedMcpStdioPath() {
|
|
6772
6771
|
const dir = packagedMcpDir();
|
|
6773
|
-
return dir ? (0,
|
|
6772
|
+
return dir ? (0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
|
|
6774
6773
|
}
|
|
6775
6774
|
function packagedCursorRipgrepCandidate(platformPkg, binName) {
|
|
6776
6775
|
const dir = packagedCursorRuntimeDir();
|
|
6777
6776
|
if (!dir) return null;
|
|
6778
|
-
return (0,
|
|
6777
|
+
return (0, import_node_path20.join)(dir, "node_modules", platformPkg, "bin", binName);
|
|
6779
6778
|
}
|
|
6780
|
-
var
|
|
6779
|
+
var import_node_fs20, import_node_path20;
|
|
6781
6780
|
var init_packaged_runtime = __esm({
|
|
6782
6781
|
"src/agents/packaged-runtime.ts"() {
|
|
6783
6782
|
"use strict";
|
|
6784
|
-
|
|
6785
|
-
|
|
6783
|
+
import_node_fs20 = require("fs");
|
|
6784
|
+
import_node_path20 = require("path");
|
|
6786
6785
|
}
|
|
6787
6786
|
});
|
|
6788
6787
|
|
|
@@ -6869,37 +6868,37 @@ function corePackageDir() {
|
|
|
6869
6868
|
try {
|
|
6870
6869
|
const url = import_meta.url;
|
|
6871
6870
|
if (typeof url === "string" && url.length > 0) {
|
|
6872
|
-
return (0,
|
|
6871
|
+
return (0, import_node_path21.dirname)((0, import_node_url.fileURLToPath)(url));
|
|
6873
6872
|
}
|
|
6874
6873
|
} catch {
|
|
6875
6874
|
}
|
|
6876
6875
|
try {
|
|
6877
|
-
const req = (0, import_node_module.createRequire)((0,
|
|
6878
|
-
return (0,
|
|
6876
|
+
const req = (0, import_node_module.createRequire)((0, import_node_path21.join)(process.cwd(), "package.json"));
|
|
6877
|
+
return (0, import_node_path21.dirname)(req.resolve("@sideboard-ai/core"));
|
|
6879
6878
|
} catch {
|
|
6880
6879
|
return process.cwd();
|
|
6881
6880
|
}
|
|
6882
6881
|
}
|
|
6883
6882
|
function findSideboardMcpJsEntry() {
|
|
6884
6883
|
const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
|
|
6885
|
-
if (override && (0,
|
|
6884
|
+
if (override && (0, import_node_fs21.existsSync)(override)) return override;
|
|
6886
6885
|
const packaged = packagedMcpStdioPath();
|
|
6887
6886
|
if (packaged) return packaged;
|
|
6888
6887
|
let dir = corePackageDir();
|
|
6889
6888
|
for (let i = 0; i < 10; i++) {
|
|
6890
6889
|
const candidates = [
|
|
6891
|
-
(0,
|
|
6892
|
-
(0,
|
|
6893
|
-
(0,
|
|
6894
|
-
(0,
|
|
6895
|
-
(0,
|
|
6896
|
-
(0,
|
|
6897
|
-
(0,
|
|
6890
|
+
(0, import_node_path21.join)(dir, "mcp/run-stdio.js"),
|
|
6891
|
+
(0, import_node_path21.join)(dir, "mcp/run-stdio.cjs"),
|
|
6892
|
+
(0, import_node_path21.join)(dir, "dist/mcp/run-stdio.js"),
|
|
6893
|
+
(0, import_node_path21.join)(dir, "dist/mcp/run-stdio.cjs"),
|
|
6894
|
+
(0, import_node_path21.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
6895
|
+
(0, import_node_path21.join)(dir, "packages/cli/dist/index.js"),
|
|
6896
|
+
(0, import_node_path21.join)(dir, "cli/dist/index.js")
|
|
6898
6897
|
];
|
|
6899
6898
|
for (const p of candidates) {
|
|
6900
|
-
if ((0,
|
|
6899
|
+
if ((0, import_node_fs21.existsSync)(p) && !isAsarPath(p)) return p;
|
|
6901
6900
|
}
|
|
6902
|
-
const parent = (0,
|
|
6901
|
+
const parent = (0, import_node_path21.dirname)(dir);
|
|
6903
6902
|
if (parent === dir) break;
|
|
6904
6903
|
dir = parent;
|
|
6905
6904
|
}
|
|
@@ -7040,22 +7039,22 @@ function writeMcpServersConfig(servers) {
|
|
|
7040
7039
|
...env ? { env } : {}
|
|
7041
7040
|
};
|
|
7042
7041
|
}
|
|
7043
|
-
const dir = (0,
|
|
7044
|
-
const cfgPath = (0,
|
|
7045
|
-
(0,
|
|
7042
|
+
const dir = (0, import_node_fs21.mkdtempSync)((0, import_node_path21.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
|
|
7043
|
+
const cfgPath = (0, import_node_path21.join)(dir, "mcp.json");
|
|
7044
|
+
(0, import_node_fs21.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
|
|
7046
7045
|
return cfgPath;
|
|
7047
7046
|
}
|
|
7048
7047
|
async function writeInjectedMcpConfig(opts) {
|
|
7049
7048
|
return writeMcpServersConfig(await buildInjectedMcpServers(opts));
|
|
7050
7049
|
}
|
|
7051
|
-
var
|
|
7050
|
+
var import_node_fs21, import_node_module, import_node_os8, import_node_path21, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
|
|
7052
7051
|
var init_injected_mcp = __esm({
|
|
7053
7052
|
"src/agents/injected-mcp.ts"() {
|
|
7054
7053
|
"use strict";
|
|
7055
|
-
|
|
7054
|
+
import_node_fs21 = require("fs");
|
|
7056
7055
|
import_node_module = require("module");
|
|
7057
7056
|
import_node_os8 = require("os");
|
|
7058
|
-
|
|
7057
|
+
import_node_path21 = require("path");
|
|
7059
7058
|
import_node_url = require("url");
|
|
7060
7059
|
init_run();
|
|
7061
7060
|
init_config();
|
|
@@ -7248,11 +7247,11 @@ function parseIssuesJson(raw) {
|
|
|
7248
7247
|
}
|
|
7249
7248
|
return [];
|
|
7250
7249
|
}
|
|
7251
|
-
var
|
|
7250
|
+
var import_node_fs22, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
|
|
7252
7251
|
var init_claude = __esm({
|
|
7253
7252
|
"src/agents/claude.ts"() {
|
|
7254
7253
|
"use strict";
|
|
7255
|
-
|
|
7254
|
+
import_node_fs22 = require("fs");
|
|
7256
7255
|
init_run();
|
|
7257
7256
|
init_app_settings();
|
|
7258
7257
|
init_claude_mcp();
|
|
@@ -7281,7 +7280,7 @@ var init_claude = __esm({
|
|
|
7281
7280
|
async detect() {
|
|
7282
7281
|
const claude = resolveClaudeExecutable();
|
|
7283
7282
|
if (claude !== "claude") {
|
|
7284
|
-
if (!(0,
|
|
7283
|
+
if (!(0, import_node_fs22.existsSync)(claude)) {
|
|
7285
7284
|
return {
|
|
7286
7285
|
agent: "claude",
|
|
7287
7286
|
installed: false,
|
|
@@ -7518,7 +7517,7 @@ async function listCodexModels() {
|
|
|
7518
7517
|
if (codex === "codex") {
|
|
7519
7518
|
const which = await run("which", ["codex"], { reject: false });
|
|
7520
7519
|
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
7521
|
-
} else if (!(0,
|
|
7520
|
+
} else if (!(0, import_node_fs23.existsSync)(codex)) {
|
|
7522
7521
|
return FALLBACK_CODEX_MODELS;
|
|
7523
7522
|
}
|
|
7524
7523
|
const listed = await run(codex, ["debug", "models"], { reject: false });
|
|
@@ -7553,12 +7552,12 @@ function usageFromCodex(usage) {
|
|
|
7553
7552
|
}
|
|
7554
7553
|
function codexConfigHasNetworkAccess() {
|
|
7555
7554
|
const candidates = [
|
|
7556
|
-
(0,
|
|
7557
|
-
(0,
|
|
7555
|
+
(0, import_node_path22.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
|
|
7556
|
+
(0, import_node_path22.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
|
|
7558
7557
|
];
|
|
7559
7558
|
for (const path2 of candidates) {
|
|
7560
|
-
if (!(0,
|
|
7561
|
-
const text3 = (0,
|
|
7559
|
+
if (!(0, import_node_fs23.existsSync)(path2)) continue;
|
|
7560
|
+
const text3 = (0, import_node_fs23.readFileSync)(path2, "utf8");
|
|
7562
7561
|
if (/network_access\s*=\s*true/.test(text3)) return true;
|
|
7563
7562
|
}
|
|
7564
7563
|
return false;
|
|
@@ -7590,21 +7589,21 @@ function asRecord(value) {
|
|
|
7590
7589
|
return void 0;
|
|
7591
7590
|
}
|
|
7592
7591
|
function codexLooksAuthenticated() {
|
|
7593
|
-
const authPath = (0,
|
|
7594
|
-
if (!(0,
|
|
7592
|
+
const authPath = (0, import_node_path22.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
|
|
7593
|
+
if (!(0, import_node_fs23.existsSync)(authPath)) return false;
|
|
7595
7594
|
try {
|
|
7596
|
-
return (0,
|
|
7595
|
+
return (0, import_node_fs23.statSync)(authPath).size > 2;
|
|
7597
7596
|
} catch {
|
|
7598
7597
|
return false;
|
|
7599
7598
|
}
|
|
7600
7599
|
}
|
|
7601
|
-
var
|
|
7600
|
+
var import_node_fs23, import_node_os9, import_node_path22, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
7602
7601
|
var init_codex = __esm({
|
|
7603
7602
|
"src/agents/codex.ts"() {
|
|
7604
7603
|
"use strict";
|
|
7605
|
-
|
|
7604
|
+
import_node_fs23 = require("fs");
|
|
7606
7605
|
import_node_os9 = require("os");
|
|
7607
|
-
|
|
7606
|
+
import_node_path22 = require("path");
|
|
7608
7607
|
init_run();
|
|
7609
7608
|
init_app_settings();
|
|
7610
7609
|
init_global_workspace();
|
|
@@ -7629,7 +7628,7 @@ var init_codex = __esm({
|
|
|
7629
7628
|
async detect() {
|
|
7630
7629
|
const codex = resolveAgentExecutable("codex");
|
|
7631
7630
|
if (codex !== "codex") {
|
|
7632
|
-
if (!(0,
|
|
7631
|
+
if (!(0, import_node_fs23.existsSync)(codex)) {
|
|
7633
7632
|
return {
|
|
7634
7633
|
agent: "codex",
|
|
7635
7634
|
installed: false,
|
|
@@ -8038,21 +8037,21 @@ function platformRipgrepPackage() {
|
|
|
8038
8037
|
}
|
|
8039
8038
|
function usableRipgrepPath(candidate) {
|
|
8040
8039
|
const raw = candidate?.trim();
|
|
8041
|
-
if (!raw || !(0,
|
|
8040
|
+
if (!raw || !(0, import_node_path23.isAbsolute)(raw)) return null;
|
|
8042
8041
|
const readable = nodeReadableScriptPath(raw);
|
|
8043
|
-
if (!(0,
|
|
8042
|
+
if (!(0, import_node_fs24.existsSync)(readable) || isAsarPath(readable)) return null;
|
|
8044
8043
|
return readable;
|
|
8045
8044
|
}
|
|
8046
8045
|
function walkForBundledRipgrep(startFile) {
|
|
8047
8046
|
if (!startFile) return null;
|
|
8048
8047
|
const pkg = platformRipgrepPackage();
|
|
8049
8048
|
const name = rgBinaryName();
|
|
8050
|
-
let dir = (0,
|
|
8051
|
-
const root = (0,
|
|
8049
|
+
let dir = (0, import_node_path23.dirname)((0, import_node_path23.resolve)(startFile));
|
|
8050
|
+
const root = (0, import_node_path23.parse)(dir).root;
|
|
8052
8051
|
while (dir !== root) {
|
|
8053
|
-
const hit = usableRipgrepPath((0,
|
|
8052
|
+
const hit = usableRipgrepPath((0, import_node_path23.join)(dir, "node_modules", pkg, "bin", name));
|
|
8054
8053
|
if (hit) return hit;
|
|
8055
|
-
const next = (0,
|
|
8054
|
+
const next = (0, import_node_path23.dirname)(dir);
|
|
8056
8055
|
if (next === dir) break;
|
|
8057
8056
|
dir = next;
|
|
8058
8057
|
}
|
|
@@ -8062,7 +8061,7 @@ function requireResolveBundledRipgrep(fromFile) {
|
|
|
8062
8061
|
try {
|
|
8063
8062
|
const req = (0, import_node_module2.createRequire)(fromFile);
|
|
8064
8063
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
8065
|
-
return usableRipgrepPath((0,
|
|
8064
|
+
return usableRipgrepPath((0, import_node_path23.join)((0, import_node_path23.dirname)(pkgJson), "bin", rgBinaryName()));
|
|
8066
8065
|
} catch {
|
|
8067
8066
|
return null;
|
|
8068
8067
|
}
|
|
@@ -8082,13 +8081,13 @@ function cursorRipgrepEnv(opts) {
|
|
|
8082
8081
|
const path2 = resolveCursorRipgrepPath(opts);
|
|
8083
8082
|
return path2 ? { [RIPGREP_ENV]: path2 } : {};
|
|
8084
8083
|
}
|
|
8085
|
-
var
|
|
8084
|
+
var import_node_fs24, import_node_module2, import_node_path23, import_node_url2, import_meta2, RIPGREP_ENV;
|
|
8086
8085
|
var init_cursor_ripgrep = __esm({
|
|
8087
8086
|
"src/agents/cursor-ripgrep.ts"() {
|
|
8088
8087
|
"use strict";
|
|
8089
|
-
|
|
8088
|
+
import_node_fs24 = require("fs");
|
|
8090
8089
|
import_node_module2 = require("module");
|
|
8091
|
-
|
|
8090
|
+
import_node_path23 = require("path");
|
|
8092
8091
|
import_node_url2 = require("url");
|
|
8093
8092
|
init_node_launch();
|
|
8094
8093
|
init_packaged_runtime();
|
|
@@ -8136,11 +8135,11 @@ function entryDir() {
|
|
|
8136
8135
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
8137
8136
|
if (cjsDir) return cjsDir;
|
|
8138
8137
|
try {
|
|
8139
|
-
return (0,
|
|
8138
|
+
return (0, import_node_path24.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
8140
8139
|
} catch {
|
|
8141
8140
|
try {
|
|
8142
8141
|
const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
|
|
8143
|
-
return (0,
|
|
8142
|
+
return (0, import_node_path24.dirname)(req.resolve("@sideboard-ai/core"));
|
|
8144
8143
|
} catch {
|
|
8145
8144
|
return process.cwd();
|
|
8146
8145
|
}
|
|
@@ -8151,27 +8150,27 @@ function cursorRunnerPath() {
|
|
|
8151
8150
|
if (packaged) return packaged;
|
|
8152
8151
|
const root = entryDir();
|
|
8153
8152
|
const candidates = [
|
|
8154
|
-
(0,
|
|
8155
|
-
(0,
|
|
8153
|
+
(0, import_node_path24.join)(root, "agents", "cursor-runner.js"),
|
|
8154
|
+
(0, import_node_path24.join)(root, "agents", "cursor-runner.cjs"),
|
|
8156
8155
|
// If somehow resolved from package root instead of dist/
|
|
8157
|
-
(0,
|
|
8158
|
-
(0,
|
|
8156
|
+
(0, import_node_path24.join)(root, "dist", "agents", "cursor-runner.js"),
|
|
8157
|
+
(0, import_node_path24.join)(root, "dist", "agents", "cursor-runner.cjs"),
|
|
8159
8158
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
8160
|
-
(0,
|
|
8161
|
-
(0,
|
|
8159
|
+
(0, import_node_path24.join)(root, "cursor-runner.ts"),
|
|
8160
|
+
(0, import_node_path24.join)(root, "src", "agents", "cursor-runner.ts")
|
|
8162
8161
|
];
|
|
8163
8162
|
for (const candidate of candidates) {
|
|
8164
|
-
if ((0,
|
|
8163
|
+
if ((0, import_node_fs25.existsSync)(candidate)) return candidate;
|
|
8165
8164
|
}
|
|
8166
8165
|
return candidates[0];
|
|
8167
8166
|
}
|
|
8168
|
-
var
|
|
8167
|
+
var import_node_fs25, import_node_module3, import_node_path24, import_node_url3, import_sdk, import_meta3, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
|
|
8169
8168
|
var init_cursor = __esm({
|
|
8170
8169
|
"src/agents/cursor.ts"() {
|
|
8171
8170
|
"use strict";
|
|
8172
|
-
|
|
8171
|
+
import_node_fs25 = require("fs");
|
|
8173
8172
|
import_node_module3 = require("module");
|
|
8174
|
-
|
|
8173
|
+
import_node_path24 = require("path");
|
|
8175
8174
|
import_node_url3 = require("url");
|
|
8176
8175
|
import_sdk = require("@cursor/sdk");
|
|
8177
8176
|
init_run();
|
|
@@ -8303,7 +8302,7 @@ async function listOpencodeModels() {
|
|
|
8303
8302
|
if (opencode === "opencode") {
|
|
8304
8303
|
const which = await run("which", ["opencode"], { reject: false });
|
|
8305
8304
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
8306
|
-
} else if (!(0,
|
|
8305
|
+
} else if (!(0, import_node_fs26.existsSync)(opencode)) {
|
|
8307
8306
|
return FALLBACK_OPENCODE_MODELS;
|
|
8308
8307
|
}
|
|
8309
8308
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -8333,11 +8332,11 @@ function usageFromOpencode(tokens) {
|
|
|
8333
8332
|
cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
|
|
8334
8333
|
};
|
|
8335
8334
|
}
|
|
8336
|
-
var
|
|
8335
|
+
var import_node_fs26, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
|
|
8337
8336
|
var init_opencode = __esm({
|
|
8338
8337
|
"src/agents/opencode.ts"() {
|
|
8339
8338
|
"use strict";
|
|
8340
|
-
|
|
8339
|
+
import_node_fs26 = require("fs");
|
|
8341
8340
|
init_run();
|
|
8342
8341
|
init_app_settings();
|
|
8343
8342
|
init_global_workspace();
|
|
@@ -8363,7 +8362,7 @@ var init_opencode = __esm({
|
|
|
8363
8362
|
async detect() {
|
|
8364
8363
|
const opencode = resolveAgentExecutable("opencode");
|
|
8365
8364
|
if (opencode !== "opencode") {
|
|
8366
|
-
if (!(0,
|
|
8365
|
+
if (!(0, import_node_fs26.existsSync)(opencode)) {
|
|
8367
8366
|
return {
|
|
8368
8367
|
agent: "opencode",
|
|
8369
8368
|
installed: false,
|
|
@@ -9160,40 +9159,40 @@ __export(plan_file_exports, {
|
|
|
9160
9159
|
writePlanFile: () => writePlanFile
|
|
9161
9160
|
});
|
|
9162
9161
|
function ensureAttachmentsGitignore2(worktreePath) {
|
|
9163
|
-
const gitignoreAbs = (0,
|
|
9164
|
-
if ((0,
|
|
9165
|
-
(0,
|
|
9166
|
-
(0,
|
|
9162
|
+
const gitignoreAbs = (0, import_node_path37.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
9163
|
+
if ((0, import_node_fs40.existsSync)(gitignoreAbs)) return;
|
|
9164
|
+
(0, import_node_fs40.mkdirSync)((0, import_node_path37.dirname)(gitignoreAbs), { recursive: true });
|
|
9165
|
+
(0, import_node_fs40.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
9167
9166
|
}
|
|
9168
9167
|
function planFileAbs(worktreePath) {
|
|
9169
|
-
return (0,
|
|
9168
|
+
return (0, import_node_path37.join)(worktreePath, PLAN_FILE_REL);
|
|
9170
9169
|
}
|
|
9171
9170
|
function readTextIfPresent2(abs) {
|
|
9172
|
-
if (!(0,
|
|
9171
|
+
if (!(0, import_node_fs40.existsSync)(abs)) return null;
|
|
9173
9172
|
try {
|
|
9174
|
-
const content = (0,
|
|
9173
|
+
const content = (0, import_node_fs40.readFileSync)(abs, "utf8");
|
|
9175
9174
|
return content.trim() ? content : null;
|
|
9176
9175
|
} catch {
|
|
9177
9176
|
return null;
|
|
9178
9177
|
}
|
|
9179
9178
|
}
|
|
9180
9179
|
function readPlanFile(worktreePath) {
|
|
9181
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
9180
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path37.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path37.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
9182
9181
|
}
|
|
9183
9182
|
function writePlanFile(worktreePath, content) {
|
|
9184
9183
|
ensureAttachmentsGitignore2(worktreePath);
|
|
9185
9184
|
const abs = planFileAbs(worktreePath);
|
|
9186
|
-
(0,
|
|
9185
|
+
(0, import_node_fs40.mkdirSync)((0, import_node_path37.dirname)(abs), { recursive: true });
|
|
9187
9186
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
9188
|
-
(0,
|
|
9187
|
+
(0, import_node_fs40.writeFileSync)(abs, body, "utf8");
|
|
9189
9188
|
return PLAN_FILE_REL;
|
|
9190
9189
|
}
|
|
9191
|
-
var
|
|
9190
|
+
var import_node_fs40, import_node_path37;
|
|
9192
9191
|
var init_plan_file = __esm({
|
|
9193
9192
|
"src/plan/plan-file.ts"() {
|
|
9194
9193
|
"use strict";
|
|
9195
|
-
|
|
9196
|
-
|
|
9194
|
+
import_node_fs40 = require("fs");
|
|
9195
|
+
import_node_path37 = require("path");
|
|
9197
9196
|
init_workspace_scratch();
|
|
9198
9197
|
init_plan_present();
|
|
9199
9198
|
init_plan_present();
|
|
@@ -9208,10 +9207,10 @@ __export(cursor_recover_exports, {
|
|
|
9208
9207
|
function recoverFinishedCursorRun(opts) {
|
|
9209
9208
|
const agentId = opts.agentId.trim();
|
|
9210
9209
|
if (!agentId) return null;
|
|
9211
|
-
const runsPath = (0,
|
|
9212
|
-
if (!(0,
|
|
9210
|
+
const runsPath = (0, import_node_path38.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
|
|
9211
|
+
if (!(0, import_node_fs41.existsSync)(runsPath)) return null;
|
|
9213
9212
|
try {
|
|
9214
|
-
const lines = (0,
|
|
9213
|
+
const lines = (0, import_node_fs41.readFileSync)(runsPath, "utf8").split("\n");
|
|
9215
9214
|
let best = null;
|
|
9216
9215
|
for (const line of lines) {
|
|
9217
9216
|
const trimmed = line.trim();
|
|
@@ -9237,12 +9236,12 @@ function recoverFinishedCursorRun(opts) {
|
|
|
9237
9236
|
return null;
|
|
9238
9237
|
}
|
|
9239
9238
|
}
|
|
9240
|
-
var
|
|
9239
|
+
var import_node_fs41, import_node_path38;
|
|
9241
9240
|
var init_cursor_recover = __esm({
|
|
9242
9241
|
"src/agents/cursor-recover.ts"() {
|
|
9243
9242
|
"use strict";
|
|
9244
|
-
|
|
9245
|
-
|
|
9243
|
+
import_node_fs41 = require("fs");
|
|
9244
|
+
import_node_path38 = require("path");
|
|
9246
9245
|
init_paths();
|
|
9247
9246
|
}
|
|
9248
9247
|
});
|
|
@@ -9389,6 +9388,7 @@ __export(index_exports, {
|
|
|
9389
9388
|
captureTurnBaseline: () => captureTurnBaseline,
|
|
9390
9389
|
checkoutPrStackLayer: () => checkoutPrStackLayer,
|
|
9391
9390
|
childEnvWithAppSettings: () => childEnvWithAppSettings,
|
|
9391
|
+
claimDesktopHost: () => claimDesktopHost,
|
|
9392
9392
|
claudeAdapter: () => claudeAdapter,
|
|
9393
9393
|
claudeChromeEnabled: () => claudeChromeEnabled,
|
|
9394
9394
|
claudeUserSettingsPath: () => claudeUserSettingsPath,
|
|
@@ -9427,6 +9427,7 @@ __export(index_exports, {
|
|
|
9427
9427
|
decodeBrightsyTarget: () => decodeBrightsyTarget,
|
|
9428
9428
|
deleteBranchOnPurgeEnabled: () => deleteBranchOnPurgeEnabled,
|
|
9429
9429
|
deleteThreadRecord: () => deleteThreadRecord,
|
|
9430
|
+
desktopHostPidPath: () => desktopHostPidPath,
|
|
9430
9431
|
detectAgents: () => detectAgents,
|
|
9431
9432
|
detectGhStack: () => detectGhStack,
|
|
9432
9433
|
detectLocalMergeConflicts: () => detectLocalMergeConflicts,
|
|
@@ -9460,6 +9461,7 @@ __export(index_exports, {
|
|
|
9460
9461
|
findConventionSetup: () => findConventionSetup,
|
|
9461
9462
|
findInvalidCacheControlTtlOrder: () => findInvalidCacheControlTtlOrder,
|
|
9462
9463
|
findOrphanWorktrees: () => findOrphanWorktrees,
|
|
9464
|
+
findSlackCoordinator: () => findSlackCoordinator,
|
|
9463
9465
|
findThreadByRef: () => findThreadByRef,
|
|
9464
9466
|
findThreadForStackLayer: () => findThreadForStackLayer,
|
|
9465
9467
|
flattenTurnInput: () => flattenTurnInput,
|
|
@@ -9551,6 +9553,7 @@ __export(index_exports, {
|
|
|
9551
9553
|
isConductorBundledCli: () => isConductorBundledCli,
|
|
9552
9554
|
isCursorAutoModel: () => isCursorAutoModel,
|
|
9553
9555
|
isDefaultishSourceRef: () => isDefaultishSourceRef,
|
|
9556
|
+
isDesktopHostAlive: () => isDesktopHostAlive,
|
|
9554
9557
|
isDirty: () => isDirty,
|
|
9555
9558
|
isGhRateLimitError: () => isGhRateLimitError,
|
|
9556
9559
|
isGlobalRepoPath: () => isGlobalRepoPath,
|
|
@@ -9572,6 +9575,7 @@ __export(index_exports, {
|
|
|
9572
9575
|
isSlackExternalReplyPrompt: () => isSlackExternalReplyPrompt,
|
|
9573
9576
|
isSlackOAuthCancelled: () => isSlackOAuthCancelled,
|
|
9574
9577
|
isThinkingEffort: () => isThinkingEffort,
|
|
9578
|
+
isThisProcessDesktopHost: () => isThisProcessDesktopHost,
|
|
9575
9579
|
isThreadCaffeinated: () => isThreadCaffeinated,
|
|
9576
9580
|
isWorkspaceScratchPath: () => isWorkspaceScratchPath,
|
|
9577
9581
|
linearAuthorizationHeader: () => linearAuthorizationHeader,
|
|
@@ -9673,6 +9677,7 @@ __export(index_exports, {
|
|
|
9673
9677
|
refreshSlackReplyBadges: () => refreshSlackReplyBadges,
|
|
9674
9678
|
registerPackagedUserMcpClients: () => registerPackagedUserMcpClients,
|
|
9675
9679
|
releaseCaffeinateHoldForThread: () => releaseCaffeinateHoldForThread,
|
|
9680
|
+
releaseDesktopHost: () => releaseDesktopHost,
|
|
9676
9681
|
removeWorkspace: () => removeWorkspace,
|
|
9677
9682
|
removeWorktree: () => removeWorktree,
|
|
9678
9683
|
repoSlug: () => repoSlug,
|
|
@@ -9773,6 +9778,7 @@ __export(index_exports, {
|
|
|
9773
9778
|
taskMessageText: () => taskMessageText,
|
|
9774
9779
|
thinkingEffortBars: () => thinkingEffortBars,
|
|
9775
9780
|
thinkingEffortLabel: () => thinkingEffortLabel,
|
|
9781
|
+
thisProcessShouldDrainAgentQueues: () => thisProcessShouldDrainAgentQueues,
|
|
9776
9782
|
threadDisplayLabel: () => threadDisplayLabel,
|
|
9777
9783
|
threadFilePath: () => threadFilePath,
|
|
9778
9784
|
threadLockPath: () => threadLockPath,
|
|
@@ -9820,6 +9826,55 @@ init_app_settings();
|
|
|
9820
9826
|
init_caffeinate_hold();
|
|
9821
9827
|
init_secure_file();
|
|
9822
9828
|
init_thread_store();
|
|
9829
|
+
|
|
9830
|
+
// src/store/desktop-host.ts
|
|
9831
|
+
var import_node_fs10 = require("fs");
|
|
9832
|
+
var import_node_path10 = require("path");
|
|
9833
|
+
init_paths();
|
|
9834
|
+
function desktopHostPidPath() {
|
|
9835
|
+
return (0, import_node_path10.join)(appDataDir(), "desktop-host.pid");
|
|
9836
|
+
}
|
|
9837
|
+
function claimDesktopHost(pid = process.pid) {
|
|
9838
|
+
(0, import_node_fs10.writeFileSync)(desktopHostPidPath(), `${pid}
|
|
9839
|
+
`, "utf8");
|
|
9840
|
+
}
|
|
9841
|
+
function releaseDesktopHost(pid = process.pid) {
|
|
9842
|
+
if (readDesktopHostPid() !== pid) return;
|
|
9843
|
+
try {
|
|
9844
|
+
(0, import_node_fs10.unlinkSync)(desktopHostPidPath());
|
|
9845
|
+
} catch {
|
|
9846
|
+
}
|
|
9847
|
+
}
|
|
9848
|
+
function readDesktopHostPid() {
|
|
9849
|
+
try {
|
|
9850
|
+
const pid = Number.parseInt((0, import_node_fs10.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
|
|
9851
|
+
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
9852
|
+
return pid;
|
|
9853
|
+
} catch {
|
|
9854
|
+
return null;
|
|
9855
|
+
}
|
|
9856
|
+
}
|
|
9857
|
+
function pidAlive(pid) {
|
|
9858
|
+
try {
|
|
9859
|
+
process.kill(pid, 0);
|
|
9860
|
+
return true;
|
|
9861
|
+
} catch {
|
|
9862
|
+
return false;
|
|
9863
|
+
}
|
|
9864
|
+
}
|
|
9865
|
+
function isDesktopHostAlive() {
|
|
9866
|
+
const pid = readDesktopHostPid();
|
|
9867
|
+
return pid != null && pidAlive(pid);
|
|
9868
|
+
}
|
|
9869
|
+
function isThisProcessDesktopHost() {
|
|
9870
|
+
return readDesktopHostPid() === process.pid && pidAlive(process.pid);
|
|
9871
|
+
}
|
|
9872
|
+
function thisProcessShouldDrainAgentQueues() {
|
|
9873
|
+
if (isThisProcessDesktopHost()) return true;
|
|
9874
|
+
return !isDesktopHostAlive();
|
|
9875
|
+
}
|
|
9876
|
+
|
|
9877
|
+
// src/index.ts
|
|
9823
9878
|
init_workspaces();
|
|
9824
9879
|
init_global_workspace();
|
|
9825
9880
|
init_run();
|
|
@@ -10979,8 +11034,8 @@ init_usage();
|
|
|
10979
11034
|
init_claude_mcp();
|
|
10980
11035
|
|
|
10981
11036
|
// src/agents/instructions.ts
|
|
10982
|
-
var
|
|
10983
|
-
var
|
|
11037
|
+
var import_node_fs27 = require("fs");
|
|
11038
|
+
var import_node_path25 = require("path");
|
|
10984
11039
|
init_git_auth_mode();
|
|
10985
11040
|
init_worktree_labels();
|
|
10986
11041
|
function normPath3(p) {
|
|
@@ -11151,11 +11206,11 @@ function loadAgentInstructions(worktreePath, agent) {
|
|
|
11151
11206
|
const out = [];
|
|
11152
11207
|
for (const rel of candidates) {
|
|
11153
11208
|
if (seenPaths.has(rel)) continue;
|
|
11154
|
-
const abs = (0,
|
|
11155
|
-
if (!(0,
|
|
11209
|
+
const abs = (0, import_node_path25.join)(worktreePath, rel);
|
|
11210
|
+
if (!(0, import_node_fs27.existsSync)(abs)) continue;
|
|
11156
11211
|
try {
|
|
11157
|
-
if (!(0,
|
|
11158
|
-
let content = (0,
|
|
11212
|
+
if (!(0, import_node_fs27.statSync)(abs).isFile()) continue;
|
|
11213
|
+
let content = (0, import_node_fs27.readFileSync)(abs, "utf8");
|
|
11159
11214
|
if (!content.trim()) continue;
|
|
11160
11215
|
if (content.length > MAX_CHARS_PER_FILE) {
|
|
11161
11216
|
content = `${content.slice(0, MAX_CHARS_PER_FILE)}
|
|
@@ -11237,9 +11292,9 @@ async function requireAgent(agent, opts) {
|
|
|
11237
11292
|
init_settings();
|
|
11238
11293
|
|
|
11239
11294
|
// src/hook/conductor.ts
|
|
11240
|
-
var
|
|
11295
|
+
var import_node_fs28 = require("fs");
|
|
11241
11296
|
var import_node_net = require("net");
|
|
11242
|
-
var
|
|
11297
|
+
var import_node_path26 = require("path");
|
|
11243
11298
|
var import_execa4 = require("execa");
|
|
11244
11299
|
var import_node_readline3 = require("readline");
|
|
11245
11300
|
init_settings();
|
|
@@ -11254,9 +11309,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
11254
11309
|
return new RegExp(`^${escaped}$`).test(name);
|
|
11255
11310
|
}
|
|
11256
11311
|
function readWorktreeInclude(repoPath) {
|
|
11257
|
-
const path2 = (0,
|
|
11258
|
-
if (!(0,
|
|
11259
|
-
return (0,
|
|
11312
|
+
const path2 = (0, import_node_path26.join)(repoPath, ".worktreeinclude");
|
|
11313
|
+
if (!(0, import_node_fs28.existsSync)(path2)) return [];
|
|
11314
|
+
return (0, import_node_fs28.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
11260
11315
|
}
|
|
11261
11316
|
function resolveFilesToCopy(repoPath) {
|
|
11262
11317
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -11266,10 +11321,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
11266
11321
|
if (settings?.fileIncludeGlobs?.length) {
|
|
11267
11322
|
const matched = [];
|
|
11268
11323
|
try {
|
|
11269
|
-
for (const entry of (0,
|
|
11324
|
+
for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
11270
11325
|
if (!entry.isFile()) continue;
|
|
11271
11326
|
for (const glob of settings.fileIncludeGlobs) {
|
|
11272
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
11327
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path26.basename)(glob), entry.name)) {
|
|
11273
11328
|
matched.push(entry.name);
|
|
11274
11329
|
break;
|
|
11275
11330
|
}
|
|
@@ -11281,7 +11336,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
11281
11336
|
}
|
|
11282
11337
|
const defaults = [];
|
|
11283
11338
|
try {
|
|
11284
|
-
for (const entry of (0,
|
|
11339
|
+
for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
11285
11340
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
11286
11341
|
defaults.push(entry.name);
|
|
11287
11342
|
}
|
|
@@ -11295,11 +11350,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
11295
11350
|
const patterns = resolveFilesToCopy(repoPath);
|
|
11296
11351
|
const copied = [];
|
|
11297
11352
|
for (const rel of patterns) {
|
|
11298
|
-
const src = (0,
|
|
11299
|
-
if (!(0,
|
|
11300
|
-
const dest = (0,
|
|
11301
|
-
(0,
|
|
11302
|
-
(0,
|
|
11353
|
+
const src = (0, import_node_path26.join)(repoPath, rel);
|
|
11354
|
+
if (!(0, import_node_fs28.existsSync)(src)) continue;
|
|
11355
|
+
const dest = (0, import_node_path26.join)(worktreePath, rel);
|
|
11356
|
+
(0, import_node_fs28.mkdirSync)((0, import_node_path26.dirname)(dest), { recursive: true });
|
|
11357
|
+
(0, import_node_fs28.copyFileSync)(src, dest);
|
|
11303
11358
|
copied.push(rel);
|
|
11304
11359
|
}
|
|
11305
11360
|
return copied;
|
|
@@ -11335,7 +11390,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
11335
11390
|
const env = stripNestedElectronEnv({
|
|
11336
11391
|
...baseEnv ?? process.env
|
|
11337
11392
|
});
|
|
11338
|
-
const name = opts.workspaceName ?? (0,
|
|
11393
|
+
const name = opts.workspaceName ?? (0, import_node_path26.basename)(opts.worktreePath);
|
|
11339
11394
|
const ports = opts.ports ?? [];
|
|
11340
11395
|
const primary = ports[0];
|
|
11341
11396
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -11596,12 +11651,12 @@ init_convention_setup();
|
|
|
11596
11651
|
init_cursor_worktrees();
|
|
11597
11652
|
|
|
11598
11653
|
// src/diff/diff.ts
|
|
11599
|
-
var
|
|
11600
|
-
var
|
|
11654
|
+
var import_node_fs29 = require("fs");
|
|
11655
|
+
var import_node_path27 = require("path");
|
|
11601
11656
|
init_run();
|
|
11602
11657
|
init_worktree();
|
|
11603
11658
|
async function inspectGitWorktree(worktreePath) {
|
|
11604
|
-
if (!worktreePath || !(0,
|
|
11659
|
+
if (!worktreePath || !(0, import_node_fs29.existsSync)(worktreePath)) return "missing_worktree";
|
|
11605
11660
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
11606
11661
|
reject: false
|
|
11607
11662
|
});
|
|
@@ -11609,7 +11664,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
11609
11664
|
return "ok";
|
|
11610
11665
|
}
|
|
11611
11666
|
async function initializeGitRepository(worktreePath) {
|
|
11612
|
-
if (!worktreePath || !(0,
|
|
11667
|
+
if (!worktreePath || !(0, import_node_fs29.existsSync)(worktreePath)) {
|
|
11613
11668
|
throw new Error("Worktree not found");
|
|
11614
11669
|
}
|
|
11615
11670
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -11745,11 +11800,11 @@ new file mode 100644
|
|
|
11745
11800
|
};
|
|
11746
11801
|
}
|
|
11747
11802
|
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
11748
|
-
const abs = (0,
|
|
11803
|
+
const abs = (0, import_node_path27.join)(worktreePath, path2);
|
|
11749
11804
|
try {
|
|
11750
|
-
const st = (0,
|
|
11805
|
+
const st = (0, import_node_fs29.statSync)(abs);
|
|
11751
11806
|
if (st.isFile() && st.size > maxHunk) {
|
|
11752
|
-
const buf = (0,
|
|
11807
|
+
const buf = (0, import_node_fs29.readFileSync)(abs).subarray(0, maxHunk);
|
|
11753
11808
|
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
11754
11809
|
}
|
|
11755
11810
|
} catch {
|
|
@@ -12250,8 +12305,8 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
|
12250
12305
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
12251
12306
|
assertSafeRelativePath(relativePath);
|
|
12252
12307
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
12253
|
-
const abs = (0,
|
|
12254
|
-
const st = (0,
|
|
12308
|
+
const abs = (0, import_node_path27.join)(worktreePath, relativePath);
|
|
12309
|
+
const st = (0, import_node_fs29.statSync)(abs);
|
|
12255
12310
|
if (!st.isFile()) {
|
|
12256
12311
|
throw new Error(`Not a file: ${relativePath}`);
|
|
12257
12312
|
}
|
|
@@ -12260,7 +12315,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
12260
12315
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
12261
12316
|
);
|
|
12262
12317
|
}
|
|
12263
|
-
const buf = (0,
|
|
12318
|
+
const buf = (0, import_node_fs29.readFileSync)(abs);
|
|
12264
12319
|
return {
|
|
12265
12320
|
path: relativePath,
|
|
12266
12321
|
contentBase64: buf.toString("base64"),
|
|
@@ -12270,12 +12325,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
12270
12325
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
12271
12326
|
assertSafeRelativePath(relativePath);
|
|
12272
12327
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
12273
|
-
const abs = (0,
|
|
12274
|
-
const st = (0,
|
|
12328
|
+
const abs = (0, import_node_path27.join)(worktreePath, relativePath);
|
|
12329
|
+
const st = (0, import_node_fs29.statSync)(abs);
|
|
12275
12330
|
if (!st.isFile()) {
|
|
12276
12331
|
throw new Error(`Not a file: ${relativePath}`);
|
|
12277
12332
|
}
|
|
12278
|
-
const buf = (0,
|
|
12333
|
+
const buf = (0, import_node_fs29.readFileSync)(abs);
|
|
12279
12334
|
if (isImageRelativePath(relativePath)) {
|
|
12280
12335
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
12281
12336
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -12318,9 +12373,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
12318
12373
|
}
|
|
12319
12374
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
12320
12375
|
assertSafeRelativePath(relativePath);
|
|
12321
|
-
const abs = (0,
|
|
12322
|
-
(0,
|
|
12323
|
-
(0,
|
|
12376
|
+
const abs = (0, import_node_path27.join)(worktreePath, relativePath);
|
|
12377
|
+
(0, import_node_fs29.mkdirSync)((0, import_node_path27.dirname)(abs), { recursive: true });
|
|
12378
|
+
(0, import_node_fs29.writeFileSync)(abs, content, "utf8");
|
|
12324
12379
|
return { path: relativePath };
|
|
12325
12380
|
}
|
|
12326
12381
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -12339,9 +12394,9 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
12339
12394
|
}
|
|
12340
12395
|
|
|
12341
12396
|
// src/skills/discover.ts
|
|
12342
|
-
var
|
|
12397
|
+
var import_node_fs30 = require("fs");
|
|
12343
12398
|
var import_node_os10 = require("os");
|
|
12344
|
-
var
|
|
12399
|
+
var import_node_path28 = require("path");
|
|
12345
12400
|
function toCommand(name) {
|
|
12346
12401
|
return name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
12347
12402
|
}
|
|
@@ -12373,7 +12428,7 @@ function parseFrontmatter(content) {
|
|
|
12373
12428
|
}
|
|
12374
12429
|
function readSkill(skillMd, source) {
|
|
12375
12430
|
try {
|
|
12376
|
-
const content = (0,
|
|
12431
|
+
const content = (0, import_node_fs30.readFileSync)(skillMd, "utf8");
|
|
12377
12432
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
12378
12433
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
12379
12434
|
const name = fmName || dirName;
|
|
@@ -12392,19 +12447,19 @@ function readSkill(skillMd, source) {
|
|
|
12392
12447
|
}
|
|
12393
12448
|
}
|
|
12394
12449
|
function scanSkillsDir(dir, source, out) {
|
|
12395
|
-
if (!(0,
|
|
12450
|
+
if (!(0, import_node_fs30.existsSync)(dir)) return;
|
|
12396
12451
|
let entries;
|
|
12397
12452
|
try {
|
|
12398
|
-
entries = (0,
|
|
12453
|
+
entries = (0, import_node_fs30.readdirSync)(dir);
|
|
12399
12454
|
} catch {
|
|
12400
12455
|
return;
|
|
12401
12456
|
}
|
|
12402
12457
|
for (const entry of entries) {
|
|
12403
12458
|
if (entry.startsWith(".")) continue;
|
|
12404
|
-
const skillMd = (0,
|
|
12405
|
-
if (!(0,
|
|
12459
|
+
const skillMd = (0, import_node_path28.join)(dir, entry, "SKILL.md");
|
|
12460
|
+
if (!(0, import_node_fs30.existsSync)(skillMd)) continue;
|
|
12406
12461
|
try {
|
|
12407
|
-
if (!(0,
|
|
12462
|
+
if (!(0, import_node_fs30.statSync)(skillMd).isFile()) continue;
|
|
12408
12463
|
} catch {
|
|
12409
12464
|
continue;
|
|
12410
12465
|
}
|
|
@@ -12413,24 +12468,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
12413
12468
|
}
|
|
12414
12469
|
}
|
|
12415
12470
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
12416
|
-
if (!(0,
|
|
12471
|
+
if (!(0, import_node_fs30.existsSync)(pluginsRoot)) return;
|
|
12417
12472
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
12418
12473
|
if (depth > 7) return;
|
|
12419
12474
|
let entries;
|
|
12420
12475
|
try {
|
|
12421
|
-
entries = (0,
|
|
12476
|
+
entries = (0, import_node_fs30.readdirSync)(dir);
|
|
12422
12477
|
} catch {
|
|
12423
12478
|
return;
|
|
12424
12479
|
}
|
|
12425
12480
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
12426
|
-
const skill = readSkill((0,
|
|
12481
|
+
const skill = readSkill((0, import_node_path28.join)(dir, "SKILL.md"), "cli");
|
|
12427
12482
|
if (skill) out.push(skill);
|
|
12428
12483
|
}
|
|
12429
12484
|
for (const entry of entries) {
|
|
12430
12485
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
12431
|
-
const full = (0,
|
|
12486
|
+
const full = (0, import_node_path28.join)(dir, entry);
|
|
12432
12487
|
try {
|
|
12433
|
-
if (!(0,
|
|
12488
|
+
if (!(0, import_node_fs30.statSync)(full).isDirectory()) continue;
|
|
12434
12489
|
} catch {
|
|
12435
12490
|
continue;
|
|
12436
12491
|
}
|
|
@@ -12448,17 +12503,17 @@ function discoverSkills(worktreePath) {
|
|
|
12448
12503
|
const home = (0, import_node_os10.homedir)();
|
|
12449
12504
|
const collected = [];
|
|
12450
12505
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
12451
|
-
scanSkillsDir((0,
|
|
12506
|
+
scanSkillsDir((0, import_node_path28.join)(worktreePath, rel), "workspace", collected);
|
|
12452
12507
|
}
|
|
12453
12508
|
for (const abs of [
|
|
12454
|
-
(0,
|
|
12455
|
-
(0,
|
|
12456
|
-
(0,
|
|
12457
|
-
(0,
|
|
12509
|
+
(0, import_node_path28.join)(home, ".claude/skills"),
|
|
12510
|
+
(0, import_node_path28.join)(home, ".cursor/skills"),
|
|
12511
|
+
(0, import_node_path28.join)(home, ".sideboard/skills"),
|
|
12512
|
+
(0, import_node_path28.join)(home, ".brightsy/skills")
|
|
12458
12513
|
]) {
|
|
12459
12514
|
scanSkillsDir(abs, "user", collected);
|
|
12460
12515
|
}
|
|
12461
|
-
scanClaudePluginSkills((0,
|
|
12516
|
+
scanClaudePluginSkills((0, import_node_path28.join)(home, ".claude/plugins"), collected);
|
|
12462
12517
|
const rank = { workspace: 0, user: 1, cli: 2 };
|
|
12463
12518
|
const byCommand = /* @__PURE__ */ new Map();
|
|
12464
12519
|
for (const skill of collected) {
|
|
@@ -12470,7 +12525,7 @@ function discoverSkills(worktreePath) {
|
|
|
12470
12525
|
return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
|
|
12471
12526
|
}
|
|
12472
12527
|
function readSkillBody(skillPath, maxChars = 12e3) {
|
|
12473
|
-
const raw = (0,
|
|
12528
|
+
const raw = (0, import_node_fs30.readFileSync)(skillPath, "utf8");
|
|
12474
12529
|
if (raw.startsWith("---")) {
|
|
12475
12530
|
const end = raw.indexOf("\n---", 3);
|
|
12476
12531
|
if (end >= 0) {
|
|
@@ -12611,8 +12666,8 @@ function buildDiffCommentAttachment(input) {
|
|
|
12611
12666
|
}
|
|
12612
12667
|
|
|
12613
12668
|
// src/composer/stage-files.ts
|
|
12614
|
-
var
|
|
12615
|
-
var
|
|
12669
|
+
var import_node_fs31 = require("fs");
|
|
12670
|
+
var import_node_path29 = require("path");
|
|
12616
12671
|
var import_node_crypto5 = require("crypto");
|
|
12617
12672
|
init_workspace_scratch();
|
|
12618
12673
|
var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
@@ -12638,7 +12693,7 @@ var IMAGE_MIME_BY_EXT = {
|
|
|
12638
12693
|
var MAX_INLINE_BYTES = 4e5;
|
|
12639
12694
|
var MAX_PREVIEW_BYTES = 5e6;
|
|
12640
12695
|
function fileExtension(filePath) {
|
|
12641
|
-
const base = (0,
|
|
12696
|
+
const base = (0, import_node_path29.basename)(filePath).toLowerCase();
|
|
12642
12697
|
return base.includes(".") ? base.split(".").pop() || "" : "";
|
|
12643
12698
|
}
|
|
12644
12699
|
function isImageFilePath(filePath) {
|
|
@@ -12648,22 +12703,22 @@ function imageMimeType(filePath) {
|
|
|
12648
12703
|
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
12649
12704
|
}
|
|
12650
12705
|
function ensureAttachmentsDir(worktreePath) {
|
|
12651
|
-
const dir = (0,
|
|
12652
|
-
(0,
|
|
12653
|
-
const gi = (0,
|
|
12654
|
-
if (!(0,
|
|
12655
|
-
(0,
|
|
12706
|
+
const dir = (0, import_node_path29.join)(worktreePath, ATTACHMENTS_DIR);
|
|
12707
|
+
(0, import_node_fs31.mkdirSync)(dir, { recursive: true });
|
|
12708
|
+
const gi = (0, import_node_path29.join)(dir, ".gitignore");
|
|
12709
|
+
if (!(0, import_node_fs31.existsSync)(gi)) {
|
|
12710
|
+
(0, import_node_fs31.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
|
|
12656
12711
|
}
|
|
12657
12712
|
return dir;
|
|
12658
12713
|
}
|
|
12659
12714
|
function uniqueAttachmentName(dir, originalName) {
|
|
12660
12715
|
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
12661
|
-
if (!(0,
|
|
12662
|
-
const ext = (0,
|
|
12716
|
+
if (!(0, import_node_fs31.existsSync)((0, import_node_path29.join)(dir, safe))) return safe;
|
|
12717
|
+
const ext = (0, import_node_path29.extname)(safe);
|
|
12663
12718
|
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
12664
12719
|
for (let i = 1; i < 1e4; i++) {
|
|
12665
12720
|
const candidate = `${stem}-${i}${ext}`;
|
|
12666
|
-
if (!(0,
|
|
12721
|
+
if (!(0, import_node_fs31.existsSync)((0, import_node_path29.join)(dir, candidate))) return candidate;
|
|
12667
12722
|
}
|
|
12668
12723
|
return `${stem}-${(0, import_node_crypto5.randomUUID)()}${ext}`;
|
|
12669
12724
|
}
|
|
@@ -12715,9 +12770,9 @@ function attachmentFromBuffer(name, buf, opts) {
|
|
|
12715
12770
|
};
|
|
12716
12771
|
}
|
|
12717
12772
|
function attachmentFromAbsolutePath(absolutePath) {
|
|
12718
|
-
const name = (0,
|
|
12773
|
+
const name = (0, import_node_path29.basename)(absolutePath);
|
|
12719
12774
|
try {
|
|
12720
|
-
const st = (0,
|
|
12775
|
+
const st = (0, import_node_fs31.statSync)(absolutePath);
|
|
12721
12776
|
if (!st.isFile()) {
|
|
12722
12777
|
return {
|
|
12723
12778
|
id: (0, import_node_crypto5.randomUUID)(),
|
|
@@ -12726,7 +12781,7 @@ function attachmentFromAbsolutePath(absolutePath) {
|
|
|
12726
12781
|
content: `(not a file: ${absolutePath})`
|
|
12727
12782
|
};
|
|
12728
12783
|
}
|
|
12729
|
-
const buf = (0,
|
|
12784
|
+
const buf = (0, import_node_fs31.readFileSync)(absolutePath);
|
|
12730
12785
|
return attachmentFromBuffer(name, buf, { sourceLabel: absolutePath });
|
|
12731
12786
|
} catch (err) {
|
|
12732
12787
|
return {
|
|
@@ -12742,15 +12797,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
|
12742
12797
|
const dir = ensureAttachmentsDir(worktreePath);
|
|
12743
12798
|
const out = [];
|
|
12744
12799
|
for (const abs of absolutePaths) {
|
|
12745
|
-
const originalName = (0,
|
|
12800
|
+
const originalName = (0, import_node_path29.basename)(abs);
|
|
12746
12801
|
try {
|
|
12747
|
-
const st = (0,
|
|
12802
|
+
const st = (0, import_node_fs31.statSync)(abs);
|
|
12748
12803
|
if (!st.isFile()) continue;
|
|
12749
12804
|
const name = uniqueAttachmentName(dir, originalName);
|
|
12750
|
-
const destAbs = (0,
|
|
12751
|
-
(0,
|
|
12805
|
+
const destAbs = (0, import_node_path29.join)(dir, name);
|
|
12806
|
+
(0, import_node_fs31.copyFileSync)(abs, destAbs);
|
|
12752
12807
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
12753
|
-
const buf = (0,
|
|
12808
|
+
const buf = (0, import_node_fs31.readFileSync)(destAbs);
|
|
12754
12809
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
12755
12810
|
} catch (err) {
|
|
12756
12811
|
out.push({
|
|
@@ -12772,8 +12827,8 @@ function stageBuffersAsAttachments(worktreePath, buffers) {
|
|
|
12772
12827
|
try {
|
|
12773
12828
|
const buf = Buffer.from(item.dataBase64, "base64");
|
|
12774
12829
|
const name = uniqueAttachmentName(dir, originalName);
|
|
12775
|
-
const destAbs = (0,
|
|
12776
|
-
(0,
|
|
12830
|
+
const destAbs = (0, import_node_path29.join)(dir, name);
|
|
12831
|
+
(0, import_node_fs31.writeFileSync)(destAbs, buf);
|
|
12777
12832
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
12778
12833
|
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
12779
12834
|
} catch (err) {
|
|
@@ -12809,18 +12864,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
12809
12864
|
if (!rel || rel.includes("..") || rel.startsWith("/")) {
|
|
12810
12865
|
out.push({
|
|
12811
12866
|
id: (0, import_node_crypto5.randomUUID)(),
|
|
12812
|
-
name: (0,
|
|
12867
|
+
name: (0, import_node_path29.basename)(rel) || "file",
|
|
12813
12868
|
kind: "file",
|
|
12814
12869
|
content: `(invalid path: ${rel})`
|
|
12815
12870
|
});
|
|
12816
12871
|
continue;
|
|
12817
12872
|
}
|
|
12818
|
-
const name = (0,
|
|
12873
|
+
const name = (0, import_node_path29.basename)(rel);
|
|
12819
12874
|
try {
|
|
12820
|
-
const abs = (0,
|
|
12821
|
-
const st = (0,
|
|
12875
|
+
const abs = (0, import_node_path29.join)(worktreePath, rel);
|
|
12876
|
+
const st = (0, import_node_fs31.statSync)(abs);
|
|
12822
12877
|
if (!st.isFile()) continue;
|
|
12823
|
-
const buf = (0,
|
|
12878
|
+
const buf = (0, import_node_fs31.readFileSync)(abs);
|
|
12824
12879
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
12825
12880
|
} catch (err) {
|
|
12826
12881
|
out.push({
|
|
@@ -13308,7 +13363,7 @@ async function confirmLand(thread, opts) {
|
|
|
13308
13363
|
}
|
|
13309
13364
|
|
|
13310
13365
|
// src/threads/create.ts
|
|
13311
|
-
var
|
|
13366
|
+
var import_node_fs32 = require("fs");
|
|
13312
13367
|
init_worktree();
|
|
13313
13368
|
init_app_settings();
|
|
13314
13369
|
init_thread_store();
|
|
@@ -13322,7 +13377,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
13322
13377
|
});
|
|
13323
13378
|
await requireAgent(resolved.agent);
|
|
13324
13379
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
13325
|
-
if (!(0,
|
|
13380
|
+
if (!(0, import_node_fs32.existsSync)(repoPath)) {
|
|
13326
13381
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
13327
13382
|
}
|
|
13328
13383
|
let sourceRef = input.sourceRef;
|
|
@@ -13474,6 +13529,7 @@ function createChatTab(input) {
|
|
|
13474
13529
|
if (isOrchestratorThread(from) || binding.sourceType === "orchestration") {
|
|
13475
13530
|
assertOrchestratorCapableAgent(nextAgent);
|
|
13476
13531
|
}
|
|
13532
|
+
const singletonInbox = isSlackCoordinatorThread(from) || isCloudCoordinatorThread(from);
|
|
13477
13533
|
const thread = createEmptyThread({
|
|
13478
13534
|
title,
|
|
13479
13535
|
// Chat-tab nicknames (soccer team or explicit) must stick. Post-turn
|
|
@@ -13481,6 +13537,10 @@ function createChatTab(input) {
|
|
|
13481
13537
|
// shared worktree folder name (e.g. fork "Arsenal" → "Monaco").
|
|
13482
13538
|
userSetTitle: true,
|
|
13483
13539
|
...binding,
|
|
13540
|
+
// Slack / Brightsy cloud identity stays on the original chat. A + tab
|
|
13541
|
+
// that copies `slack:team:user` would steal inbound DMs after you close
|
|
13542
|
+
// the connected chat.
|
|
13543
|
+
sourceRef: singletonInbox ? title : binding.sourceRef,
|
|
13484
13544
|
agent: nextAgent,
|
|
13485
13545
|
model: input.model !== void 0 ? input.model : input.agent && input.agent !== from.agent ? null : from.model,
|
|
13486
13546
|
effort: input.effort !== void 0 ? input.effort : from.effort,
|
|
@@ -13557,7 +13617,7 @@ async function forkThreadWorktree(input, onSetupLine) {
|
|
|
13557
13617
|
}
|
|
13558
13618
|
|
|
13559
13619
|
// src/threads/stack-layers.ts
|
|
13560
|
-
var
|
|
13620
|
+
var import_node_fs33 = require("fs");
|
|
13561
13621
|
init_run();
|
|
13562
13622
|
init_stack();
|
|
13563
13623
|
init_worktree();
|
|
@@ -13625,7 +13685,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
13625
13685
|
let createdWorktree = false;
|
|
13626
13686
|
const trees = await listWorktrees(repoPath);
|
|
13627
13687
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
13628
|
-
if (checkedOut?.path && (0,
|
|
13688
|
+
if (checkedOut?.path && (0, import_node_fs33.existsSync)(checkedOut.path)) {
|
|
13629
13689
|
if (input.reuseExistingWorktree !== false) {
|
|
13630
13690
|
worktreePath = checkedOut.path;
|
|
13631
13691
|
} else {
|
|
@@ -13767,7 +13827,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
13767
13827
|
async function createPrStack(input, onSetupLine) {
|
|
13768
13828
|
await requireAgent(input.agent);
|
|
13769
13829
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
13770
|
-
if (!(0,
|
|
13830
|
+
if (!(0, import_node_fs33.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
13771
13831
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
13772
13832
|
const status = await detectGhStack(repoPath);
|
|
13773
13833
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -13834,7 +13894,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
13834
13894
|
}
|
|
13835
13895
|
}
|
|
13836
13896
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
13837
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
13897
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs33.existsSync)(bootstrap.worktreePath)) {
|
|
13838
13898
|
try {
|
|
13839
13899
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
13840
13900
|
deleteBranch: bootstrap.branchName
|
|
@@ -13857,21 +13917,21 @@ function stackAgentDefaultsFrom(input) {
|
|
|
13857
13917
|
|
|
13858
13918
|
// src/threads/adopt.ts
|
|
13859
13919
|
var import_node_child_process4 = require("child_process");
|
|
13860
|
-
var
|
|
13920
|
+
var import_node_fs34 = require("fs");
|
|
13861
13921
|
var import_node_os11 = require("os");
|
|
13862
|
-
var
|
|
13922
|
+
var import_node_path30 = require("path");
|
|
13863
13923
|
var import_node_module4 = require("module");
|
|
13864
13924
|
init_worktree();
|
|
13865
13925
|
init_thread_store();
|
|
13866
13926
|
var import_meta4 = {};
|
|
13867
|
-
var CONDUCTOR_APP_SUPPORT = (0,
|
|
13927
|
+
var CONDUCTOR_APP_SUPPORT = (0, import_node_path30.join)(
|
|
13868
13928
|
process.env.HOME ?? "",
|
|
13869
13929
|
"Library",
|
|
13870
13930
|
"Application Support",
|
|
13871
13931
|
"com.conductor.app"
|
|
13872
13932
|
);
|
|
13873
|
-
var CONDUCTOR_DB = (0,
|
|
13874
|
-
var CURSOR_SDK_STORE = (0,
|
|
13933
|
+
var CONDUCTOR_DB = (0, import_node_path30.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
13934
|
+
var CURSOR_SDK_STORE = (0, import_node_path30.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
13875
13935
|
function openReadonlySqlite(file) {
|
|
13876
13936
|
const req = (0, import_node_module4.createRequire)(import_meta4.url);
|
|
13877
13937
|
const Database = req("better-sqlite3");
|
|
@@ -13888,21 +13948,21 @@ function mapAgentType(raw) {
|
|
|
13888
13948
|
return null;
|
|
13889
13949
|
}
|
|
13890
13950
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
13891
|
-
if (!workspacePath || !(0,
|
|
13951
|
+
if (!workspacePath || !(0, import_node_fs34.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
13892
13952
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
13893
13953
|
let best = null;
|
|
13894
13954
|
let hashes;
|
|
13895
13955
|
try {
|
|
13896
|
-
hashes = (0,
|
|
13956
|
+
hashes = (0, import_node_fs34.readdirSync)(CURSOR_SDK_STORE);
|
|
13897
13957
|
} catch {
|
|
13898
13958
|
return null;
|
|
13899
13959
|
}
|
|
13900
13960
|
for (const hash of hashes) {
|
|
13901
|
-
const agentsFile = (0,
|
|
13902
|
-
if (!(0,
|
|
13961
|
+
const agentsFile = (0, import_node_path30.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
13962
|
+
if (!(0, import_node_fs34.existsSync)(agentsFile)) continue;
|
|
13903
13963
|
let text3;
|
|
13904
13964
|
try {
|
|
13905
|
-
text3 = (0,
|
|
13965
|
+
text3 = (0, import_node_fs34.readFileSync)(agentsFile, "utf8");
|
|
13906
13966
|
} catch {
|
|
13907
13967
|
continue;
|
|
13908
13968
|
}
|
|
@@ -13926,7 +13986,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
13926
13986
|
return best?.agentId ?? null;
|
|
13927
13987
|
}
|
|
13928
13988
|
async function adoptThread(input) {
|
|
13929
|
-
if (!(0,
|
|
13989
|
+
if (!(0, import_node_fs34.existsSync)(input.worktreePath)) {
|
|
13930
13990
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
13931
13991
|
}
|
|
13932
13992
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -13953,18 +14013,18 @@ function conductorDbPath() {
|
|
|
13953
14013
|
return CONDUCTOR_DB;
|
|
13954
14014
|
}
|
|
13955
14015
|
function listConductorWorkspaces() {
|
|
13956
|
-
if (!(0,
|
|
14016
|
+
if (!(0, import_node_fs34.existsSync)(CONDUCTOR_DB)) {
|
|
13957
14017
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
13958
14018
|
}
|
|
13959
|
-
const tmp = (0,
|
|
13960
|
-
const snapshot = (0,
|
|
14019
|
+
const tmp = (0, import_node_fs34.mkdtempSync)((0, import_node_path30.join)((0, import_node_os11.tmpdir)(), "sideboard-conductor-"));
|
|
14020
|
+
const snapshot = (0, import_node_path30.join)(tmp, "conductor.db");
|
|
13961
14021
|
try {
|
|
13962
|
-
(0,
|
|
14022
|
+
(0, import_node_fs34.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
13963
14023
|
for (const suffix of ["-wal", "-shm"]) {
|
|
13964
14024
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
13965
|
-
if ((0,
|
|
14025
|
+
if ((0, import_node_fs34.existsSync)(src)) {
|
|
13966
14026
|
try {
|
|
13967
|
-
(0,
|
|
14027
|
+
(0, import_node_fs34.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
13968
14028
|
} catch {
|
|
13969
14029
|
}
|
|
13970
14030
|
}
|
|
@@ -14040,22 +14100,22 @@ function listConductorWorkspaces() {
|
|
|
14040
14100
|
db.close();
|
|
14041
14101
|
}
|
|
14042
14102
|
} finally {
|
|
14043
|
-
(0,
|
|
14103
|
+
(0, import_node_fs34.rmSync)(tmp, { recursive: true, force: true });
|
|
14044
14104
|
}
|
|
14045
14105
|
}
|
|
14046
14106
|
function importConductorWorkspace(workspaceId) {
|
|
14047
|
-
if (!(0,
|
|
14107
|
+
if (!(0, import_node_fs34.existsSync)(CONDUCTOR_DB)) {
|
|
14048
14108
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
14049
14109
|
}
|
|
14050
|
-
const tmp = (0,
|
|
14051
|
-
const snapshot = (0,
|
|
14110
|
+
const tmp = (0, import_node_fs34.mkdtempSync)((0, import_node_path30.join)((0, import_node_os11.tmpdir)(), "sideboard-conductor-"));
|
|
14111
|
+
const snapshot = (0, import_node_path30.join)(tmp, "conductor.db");
|
|
14052
14112
|
try {
|
|
14053
|
-
(0,
|
|
14113
|
+
(0, import_node_fs34.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
14054
14114
|
for (const suffix of ["-wal", "-shm"]) {
|
|
14055
14115
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
14056
|
-
if ((0,
|
|
14116
|
+
if ((0, import_node_fs34.existsSync)(src)) {
|
|
14057
14117
|
try {
|
|
14058
|
-
(0,
|
|
14118
|
+
(0, import_node_fs34.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
14059
14119
|
} catch {
|
|
14060
14120
|
}
|
|
14061
14121
|
}
|
|
@@ -14073,7 +14133,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
14073
14133
|
).get(workspaceId);
|
|
14074
14134
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
14075
14135
|
const worktreePath = String(row.workspacePath);
|
|
14076
|
-
if (!(0,
|
|
14136
|
+
if (!(0, import_node_fs34.existsSync)(worktreePath)) {
|
|
14077
14137
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
14078
14138
|
}
|
|
14079
14139
|
let sessionId = null;
|
|
@@ -14136,7 +14196,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
14136
14196
|
db.close();
|
|
14137
14197
|
}
|
|
14138
14198
|
} finally {
|
|
14139
|
-
(0,
|
|
14199
|
+
(0, import_node_fs34.rmSync)(tmp, { recursive: true, force: true });
|
|
14140
14200
|
}
|
|
14141
14201
|
}
|
|
14142
14202
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
@@ -14147,8 +14207,8 @@ async function importConductorWorkspaceAsync(workspaceId) {
|
|
|
14147
14207
|
var import_node_events = require("events");
|
|
14148
14208
|
|
|
14149
14209
|
// src/slack/outbound-watch.ts
|
|
14150
|
-
var
|
|
14151
|
-
var
|
|
14210
|
+
var import_node_fs36 = require("fs");
|
|
14211
|
+
var import_node_path33 = require("path");
|
|
14152
14212
|
init_paths();
|
|
14153
14213
|
init_private_file();
|
|
14154
14214
|
init_secure_file();
|
|
@@ -14194,19 +14254,19 @@ async function slackAuthTest(token) {
|
|
|
14194
14254
|
}
|
|
14195
14255
|
|
|
14196
14256
|
// src/slack/reply-target.ts
|
|
14197
|
-
var
|
|
14198
|
-
var
|
|
14257
|
+
var import_node_fs35 = require("fs");
|
|
14258
|
+
var import_node_path31 = require("path");
|
|
14199
14259
|
init_paths();
|
|
14200
14260
|
init_private_file();
|
|
14201
14261
|
init_secure_file();
|
|
14202
14262
|
function storePath2() {
|
|
14203
|
-
return (0,
|
|
14263
|
+
return (0, import_node_path31.join)(appDataDir(), "slack-reply-to.json");
|
|
14204
14264
|
}
|
|
14205
14265
|
function readStore2() {
|
|
14206
14266
|
const path2 = storePath2();
|
|
14207
|
-
if (!(0,
|
|
14267
|
+
if (!(0, import_node_fs35.existsSync)(path2)) return {};
|
|
14208
14268
|
try {
|
|
14209
|
-
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0,
|
|
14269
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs35.readFileSync)(path2, "utf8"));
|
|
14210
14270
|
return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
|
|
14211
14271
|
} catch {
|
|
14212
14272
|
return {};
|
|
@@ -14223,11 +14283,11 @@ function getSlackReplyTarget(threadId) {
|
|
|
14223
14283
|
}
|
|
14224
14284
|
|
|
14225
14285
|
// src/slack/workspaces.ts
|
|
14226
|
-
var
|
|
14286
|
+
var import_node_path32 = require("path");
|
|
14227
14287
|
init_paths();
|
|
14228
14288
|
init_secure_file();
|
|
14229
14289
|
function storePath3() {
|
|
14230
|
-
return (0,
|
|
14290
|
+
return (0, import_node_path32.join)(appDataDir(), "slack-workspaces.json");
|
|
14231
14291
|
}
|
|
14232
14292
|
function readStore3() {
|
|
14233
14293
|
try {
|
|
@@ -14343,7 +14403,7 @@ var POLL_INTERVAL_MS = 12e3;
|
|
|
14343
14403
|
var lastPollMs = 0;
|
|
14344
14404
|
var nameCache = /* @__PURE__ */ new Map();
|
|
14345
14405
|
function storePath4() {
|
|
14346
|
-
return (0,
|
|
14406
|
+
return (0, import_node_path33.join)(appDataDir(), "slack-outbound-watch.json");
|
|
14347
14407
|
}
|
|
14348
14408
|
function watchId(teamId, channelId, ts) {
|
|
14349
14409
|
return `${teamId}:${channelId}:${ts}`;
|
|
@@ -14373,9 +14433,9 @@ function tsNewer(a, b) {
|
|
|
14373
14433
|
}
|
|
14374
14434
|
function readStore4() {
|
|
14375
14435
|
const path2 = storePath4();
|
|
14376
|
-
if (!(0,
|
|
14436
|
+
if (!(0, import_node_fs36.existsSync)(path2)) return [];
|
|
14377
14437
|
try {
|
|
14378
|
-
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0,
|
|
14438
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs36.readFileSync)(path2, "utf8"));
|
|
14379
14439
|
return Array.isArray(parsed?.watches) ? parsed.watches : [];
|
|
14380
14440
|
} catch {
|
|
14381
14441
|
return [];
|
|
@@ -14720,7 +14780,7 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
14720
14780
|
}
|
|
14721
14781
|
|
|
14722
14782
|
// src/orchestrator/orchestrator.ts
|
|
14723
|
-
var
|
|
14783
|
+
var import_node_fs42 = require("fs");
|
|
14724
14784
|
init_error_detail();
|
|
14725
14785
|
init_agents();
|
|
14726
14786
|
init_worktree();
|
|
@@ -14741,8 +14801,8 @@ function shouldAutoArchiveOnPrMerge(opts) {
|
|
|
14741
14801
|
}
|
|
14742
14802
|
|
|
14743
14803
|
// src/git/orphan-cleanup.ts
|
|
14744
|
-
var
|
|
14745
|
-
var
|
|
14804
|
+
var import_node_fs37 = require("fs");
|
|
14805
|
+
var import_node_path34 = require("path");
|
|
14746
14806
|
init_worktree();
|
|
14747
14807
|
init_thread_store();
|
|
14748
14808
|
init_paths();
|
|
@@ -14757,9 +14817,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14757
14817
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
14758
14818
|
);
|
|
14759
14819
|
const homeRoot = sideboardWorkspacesDir();
|
|
14760
|
-
if ((0,
|
|
14820
|
+
if ((0, import_node_fs37.existsSync)(homeRoot)) {
|
|
14761
14821
|
try {
|
|
14762
|
-
for (const entry of (0,
|
|
14822
|
+
for (const entry of (0, import_node_fs37.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
14763
14823
|
if (!entry.isDirectory()) continue;
|
|
14764
14824
|
void entry;
|
|
14765
14825
|
}
|
|
@@ -14769,7 +14829,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14769
14829
|
const orphans = [];
|
|
14770
14830
|
const seen = /* @__PURE__ */ new Set();
|
|
14771
14831
|
for (const repoPath of repos) {
|
|
14772
|
-
if (!repoPath || !(0,
|
|
14832
|
+
if (!repoPath || !(0, import_node_fs37.existsSync)(repoPath)) continue;
|
|
14773
14833
|
try {
|
|
14774
14834
|
const wts = await listWorktrees(repoPath);
|
|
14775
14835
|
for (const wt of wts) {
|
|
@@ -14780,7 +14840,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14780
14840
|
seen.add(path2);
|
|
14781
14841
|
let mtimeMs = 0;
|
|
14782
14842
|
try {
|
|
14783
|
-
mtimeMs = (0,
|
|
14843
|
+
mtimeMs = (0, import_node_fs37.statSync)(path2).mtimeMs;
|
|
14784
14844
|
} catch {
|
|
14785
14845
|
mtimeMs = 0;
|
|
14786
14846
|
}
|
|
@@ -14790,16 +14850,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14790
14850
|
}
|
|
14791
14851
|
try {
|
|
14792
14852
|
const root = worktreesRoot(repoPath);
|
|
14793
|
-
if ((0,
|
|
14794
|
-
for (const entry of (0,
|
|
14853
|
+
if ((0, import_node_fs37.existsSync)(root)) {
|
|
14854
|
+
for (const entry of (0, import_node_fs37.readdirSync)(root, { withFileTypes: true })) {
|
|
14795
14855
|
if (!entry.isDirectory()) continue;
|
|
14796
|
-
const path2 = (0,
|
|
14856
|
+
const path2 = (0, import_node_path34.join)(root, entry.name).replace(/\/$/, "");
|
|
14797
14857
|
if (known.has(path2) || seen.has(path2)) continue;
|
|
14798
|
-
if (!(0,
|
|
14858
|
+
if (!(0, import_node_fs37.existsSync)((0, import_node_path34.join)(path2, ".git"))) continue;
|
|
14799
14859
|
seen.add(path2);
|
|
14800
14860
|
let mtimeMs = 0;
|
|
14801
14861
|
try {
|
|
14802
|
-
mtimeMs = (0,
|
|
14862
|
+
mtimeMs = (0, import_node_fs37.statSync)(path2).mtimeMs;
|
|
14803
14863
|
} catch {
|
|
14804
14864
|
mtimeMs = Date.now();
|
|
14805
14865
|
}
|
|
@@ -14945,8 +15005,8 @@ async function applyThreadIntoMain(thread, opts) {
|
|
|
14945
15005
|
}
|
|
14946
15006
|
|
|
14947
15007
|
// src/git/clone-repo.ts
|
|
14948
|
-
var
|
|
14949
|
-
var
|
|
15008
|
+
var import_node_fs38 = require("fs");
|
|
15009
|
+
var import_node_path35 = require("path");
|
|
14950
15010
|
var import_execa6 = require("execa");
|
|
14951
15011
|
init_paths();
|
|
14952
15012
|
init_workspaces();
|
|
@@ -14956,12 +15016,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
14956
15016
|
if (!url) throw new Error("Clone URL is required");
|
|
14957
15017
|
let name = opts.name?.trim();
|
|
14958
15018
|
if (!name) {
|
|
14959
|
-
const leaf = (0,
|
|
15019
|
+
const leaf = (0, import_node_path35.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
14960
15020
|
name = leaf || "repo";
|
|
14961
15021
|
}
|
|
14962
15022
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
14963
|
-
const dest = (0,
|
|
14964
|
-
if ((0,
|
|
15023
|
+
const dest = (0, import_node_path35.join)(sideboardReposDir(), name);
|
|
15024
|
+
if ((0, import_node_fs38.existsSync)(dest)) {
|
|
14965
15025
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
14966
15026
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
14967
15027
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -14983,8 +15043,8 @@ init_orchestrator_capable();
|
|
|
14983
15043
|
|
|
14984
15044
|
// src/review/request-review.ts
|
|
14985
15045
|
var import_node_crypto8 = require("crypto");
|
|
14986
|
-
var
|
|
14987
|
-
var
|
|
15046
|
+
var import_node_fs39 = require("fs");
|
|
15047
|
+
var import_node_path36 = require("path");
|
|
14988
15048
|
init_global_workspace();
|
|
14989
15049
|
init_thread_store();
|
|
14990
15050
|
|
|
@@ -15132,22 +15192,22 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
15132
15192
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
15133
15193
|
}
|
|
15134
15194
|
function readTextIfPresent(abs) {
|
|
15135
|
-
if (!(0,
|
|
15195
|
+
if (!(0, import_node_fs39.existsSync)(abs)) return null;
|
|
15136
15196
|
try {
|
|
15137
|
-
const content = (0,
|
|
15197
|
+
const content = (0, import_node_fs39.readFileSync)(abs, "utf8");
|
|
15138
15198
|
return content.trim() ? content : null;
|
|
15139
15199
|
} catch {
|
|
15140
15200
|
return null;
|
|
15141
15201
|
}
|
|
15142
15202
|
}
|
|
15143
15203
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
15144
|
-
const gitignoreAbs = (0,
|
|
15145
|
-
if ((0,
|
|
15146
|
-
(0,
|
|
15147
|
-
(0,
|
|
15204
|
+
const gitignoreAbs = (0, import_node_path36.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
15205
|
+
if ((0, import_node_fs39.existsSync)(gitignoreAbs)) return;
|
|
15206
|
+
(0, import_node_fs39.mkdirSync)((0, import_node_path36.dirname)(gitignoreAbs), { recursive: true });
|
|
15207
|
+
(0, import_node_fs39.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
15148
15208
|
}
|
|
15149
15209
|
function resolveReviewGuidelines(worktreePath) {
|
|
15150
|
-
const repoAbs = (0,
|
|
15210
|
+
const repoAbs = (0, import_node_path36.join)(worktreePath, REPO_REVIEW_PATH);
|
|
15151
15211
|
const repoContent = readTextIfPresent(repoAbs);
|
|
15152
15212
|
if (repoContent) {
|
|
15153
15213
|
return {
|
|
@@ -15157,7 +15217,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
15157
15217
|
source: "repo"
|
|
15158
15218
|
};
|
|
15159
15219
|
}
|
|
15160
|
-
const localAbs = (0,
|
|
15220
|
+
const localAbs = (0, import_node_path36.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
15161
15221
|
const localContent = readTextIfPresent(localAbs);
|
|
15162
15222
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
15163
15223
|
return {
|
|
@@ -15167,7 +15227,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
15167
15227
|
source: "local"
|
|
15168
15228
|
};
|
|
15169
15229
|
}
|
|
15170
|
-
const legacyAbs = (0,
|
|
15230
|
+
const legacyAbs = (0, import_node_path36.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
15171
15231
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
15172
15232
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
15173
15233
|
return {
|
|
@@ -15178,8 +15238,8 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
15178
15238
|
};
|
|
15179
15239
|
}
|
|
15180
15240
|
ensureAttachmentsGitignore(worktreePath);
|
|
15181
|
-
(0,
|
|
15182
|
-
(0,
|
|
15241
|
+
(0, import_node_fs39.mkdirSync)((0, import_node_path36.dirname)(localAbs), { recursive: true });
|
|
15242
|
+
(0, import_node_fs39.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
|
|
15183
15243
|
return {
|
|
15184
15244
|
path: REVIEW_REQUEST_PATH,
|
|
15185
15245
|
name: REVIEW_REQUEST_NAME,
|
|
@@ -15188,7 +15248,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
15188
15248
|
};
|
|
15189
15249
|
}
|
|
15190
15250
|
function ensureReviewRequestFile(worktreePath) {
|
|
15191
|
-
const repoAbs = (0,
|
|
15251
|
+
const repoAbs = (0, import_node_path36.join)(worktreePath, REPO_REVIEW_PATH);
|
|
15192
15252
|
const repoContent = readTextIfPresent(repoAbs);
|
|
15193
15253
|
if (repoContent) {
|
|
15194
15254
|
return {
|
|
@@ -15198,10 +15258,10 @@ function ensureReviewRequestFile(worktreePath) {
|
|
|
15198
15258
|
source: "repo"
|
|
15199
15259
|
};
|
|
15200
15260
|
}
|
|
15201
|
-
const localAbs = (0,
|
|
15202
|
-
const localContent = readTextIfPresent(localAbs) ?? readTextIfPresent((0,
|
|
15261
|
+
const localAbs = (0, import_node_path36.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
15262
|
+
const localContent = readTextIfPresent(localAbs) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
15203
15263
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
15204
|
-
const path2 = (0,
|
|
15264
|
+
const path2 = (0, import_node_fs39.existsSync)(localAbs) ? REVIEW_REQUEST_PATH : LEGACY_REVIEW_REQUEST_PATH;
|
|
15205
15265
|
return {
|
|
15206
15266
|
path: path2,
|
|
15207
15267
|
name: REVIEW_REQUEST_NAME,
|
|
@@ -15209,8 +15269,8 @@ function ensureReviewRequestFile(worktreePath) {
|
|
|
15209
15269
|
source: "local"
|
|
15210
15270
|
};
|
|
15211
15271
|
}
|
|
15212
|
-
(0,
|
|
15213
|
-
(0,
|
|
15272
|
+
(0, import_node_fs39.mkdirSync)((0, import_node_path36.dirname)(repoAbs), { recursive: true });
|
|
15273
|
+
(0, import_node_fs39.writeFileSync)(repoAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
|
|
15214
15274
|
return {
|
|
15215
15275
|
path: REPO_REVIEW_PATH,
|
|
15216
15276
|
name: REPO_REVIEW_NAME,
|
|
@@ -15230,7 +15290,7 @@ function buildReviewRequestAttachment(content, opts) {
|
|
|
15230
15290
|
};
|
|
15231
15291
|
}
|
|
15232
15292
|
function readExistingReviewRequestFile(worktreePath) {
|
|
15233
|
-
return readTextIfPresent((0,
|
|
15293
|
+
return readTextIfPresent((0, import_node_path36.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
15234
15294
|
}
|
|
15235
15295
|
async function requestReview(threadRef, send2) {
|
|
15236
15296
|
const from = findThreadByRef(threadRef);
|
|
@@ -15496,7 +15556,7 @@ var Orchestrator = class {
|
|
|
15496
15556
|
}
|
|
15497
15557
|
continue;
|
|
15498
15558
|
}
|
|
15499
|
-
if (!(0,
|
|
15559
|
+
if (!(0, import_node_fs42.existsSync)(thread.worktreePath)) {
|
|
15500
15560
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
15501
15561
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
15502
15562
|
continue;
|
|
@@ -15734,6 +15794,9 @@ var Orchestrator = class {
|
|
|
15734
15794
|
}
|
|
15735
15795
|
return withThreadLock(thread.id, async () => {
|
|
15736
15796
|
const current = this.requireThread(thread.id);
|
|
15797
|
+
if (current.status === "archived") {
|
|
15798
|
+
throw new Error(`Thread is archived: ${thread.id}`);
|
|
15799
|
+
}
|
|
15737
15800
|
const queue = [...current.queue, prompt];
|
|
15738
15801
|
this.haltDrain.delete(thread.id);
|
|
15739
15802
|
const patch = { queue, status: "queued" };
|
|
@@ -15744,7 +15807,9 @@ var Orchestrator = class {
|
|
|
15744
15807
|
updateThread(thread.id, patch);
|
|
15745
15808
|
this.emit({ type: "queue_changed", threadId: thread.id, queue });
|
|
15746
15809
|
this.emit({ type: "status_changed", threadId: thread.id, status: "queued" });
|
|
15747
|
-
|
|
15810
|
+
if (thisProcessShouldDrainAgentQueues()) {
|
|
15811
|
+
void this.drainQueue(thread.id);
|
|
15812
|
+
}
|
|
15748
15813
|
return this.requireThread(thread.id);
|
|
15749
15814
|
});
|
|
15750
15815
|
}
|
|
@@ -15797,10 +15862,10 @@ var Orchestrator = class {
|
|
|
15797
15862
|
async sendQueuedMessageNow(threadRef, index) {
|
|
15798
15863
|
const thread = this.requireThread(threadRef);
|
|
15799
15864
|
const promoted = await withThreadLock(thread.id, async () => {
|
|
15800
|
-
const
|
|
15801
|
-
if (index < 0 || index >=
|
|
15802
|
-
const item =
|
|
15803
|
-
const rest =
|
|
15865
|
+
const current2 = this.requireThread(thread.id);
|
|
15866
|
+
if (index < 0 || index >= current2.queue.length) return false;
|
|
15867
|
+
const item = current2.queue[index];
|
|
15868
|
+
const rest = current2.queue.filter((_, i) => i !== index);
|
|
15804
15869
|
const queue = [item, ...rest];
|
|
15805
15870
|
this.haltDrain.delete(thread.id);
|
|
15806
15871
|
updateThread(thread.id, { queue });
|
|
@@ -15808,10 +15873,16 @@ var Orchestrator = class {
|
|
|
15808
15873
|
return true;
|
|
15809
15874
|
});
|
|
15810
15875
|
if (!promoted) return this.requireThread(thread.id);
|
|
15876
|
+
const current = this.requireThread(thread.id);
|
|
15811
15877
|
const inFlight = this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id);
|
|
15878
|
+
const livePid = current.agentPid;
|
|
15879
|
+
const foreignLive = !inFlight && typeof livePid === "number" && livePid > 0 && isPidAlive(livePid);
|
|
15812
15880
|
if (inFlight) {
|
|
15813
15881
|
this.stop(thread.id, { clearQueue: false, continueQueue: true });
|
|
15814
15882
|
} else {
|
|
15883
|
+
if (foreignLive) {
|
|
15884
|
+
this.stop(thread.id, { clearQueue: false, continueQueue: true });
|
|
15885
|
+
}
|
|
15815
15886
|
void this.drainQueue(thread.id);
|
|
15816
15887
|
}
|
|
15817
15888
|
return this.requireThread(thread.id);
|
|
@@ -16246,6 +16317,13 @@ var Orchestrator = class {
|
|
|
16246
16317
|
if (handle) handle.kill();
|
|
16247
16318
|
const proc = this.processes.get(`${thread.id}:agent`);
|
|
16248
16319
|
if (proc) proc.kill();
|
|
16320
|
+
const pid = thread.agentPid;
|
|
16321
|
+
if (typeof pid === "number" && pid > 0 && isPidAlive(pid)) {
|
|
16322
|
+
try {
|
|
16323
|
+
process.kill(pid, "SIGTERM");
|
|
16324
|
+
} catch {
|
|
16325
|
+
}
|
|
16326
|
+
}
|
|
16249
16327
|
const stopped = writeLiveStatus(thread.id, "stopped") ?? readThread(thread.id) ?? thread;
|
|
16250
16328
|
if (stopped.status === "stopped") {
|
|
16251
16329
|
this.emit({ type: "status_changed", threadId: thread.id, status: "stopped" });
|
|
@@ -17026,7 +17104,7 @@ var Orchestrator = class {
|
|
|
17026
17104
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
17027
17105
|
return restored2;
|
|
17028
17106
|
}
|
|
17029
|
-
if (!(0,
|
|
17107
|
+
if (!(0, import_node_fs42.existsSync)(thread.worktreePath)) {
|
|
17030
17108
|
const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
|
|
17031
17109
|
const { execa: execa7 } = await import("execa");
|
|
17032
17110
|
const slug = thread.worktreePath.split("/").pop();
|
|
@@ -17267,7 +17345,7 @@ init_coordinator_prompt();
|
|
|
17267
17345
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
17268
17346
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
17269
17347
|
var import_zod3 = require("zod");
|
|
17270
|
-
var
|
|
17348
|
+
var import_node_path39 = require("path");
|
|
17271
17349
|
init_worktree();
|
|
17272
17350
|
init_global_workspace();
|
|
17273
17351
|
init_list_models();
|
|
@@ -17954,7 +18032,7 @@ async function startMcpServer() {
|
|
|
17954
18032
|
async () => {
|
|
17955
18033
|
const threads = orch.getThreads(true);
|
|
17956
18034
|
const lines = threads.map((t) => {
|
|
17957
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
18035
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path39.basename)(t.repoPath) || t.repoPath;
|
|
17958
18036
|
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}` : ""}`;
|
|
17959
18037
|
});
|
|
17960
18038
|
return {
|
|
@@ -19263,16 +19341,16 @@ init_connected_teams();
|
|
|
19263
19341
|
init_injected_mcp();
|
|
19264
19342
|
|
|
19265
19343
|
// src/agents/user-mcp-config.ts
|
|
19266
|
-
var
|
|
19344
|
+
var import_node_fs43 = require("fs");
|
|
19267
19345
|
var import_node_os12 = require("os");
|
|
19268
|
-
var
|
|
19346
|
+
var import_node_path40 = require("path");
|
|
19269
19347
|
init_paths();
|
|
19270
19348
|
init_injected_mcp();
|
|
19271
19349
|
function userCursorMcpConfigPath() {
|
|
19272
|
-
return (0,
|
|
19350
|
+
return (0, import_node_path40.join)((0, import_node_os12.homedir)(), ".cursor", "mcp.json");
|
|
19273
19351
|
}
|
|
19274
19352
|
function userClaudeMcpConfigPath() {
|
|
19275
|
-
return (0,
|
|
19353
|
+
return (0, import_node_path40.join)((0, import_node_os12.homedir)(), ".claude.json");
|
|
19276
19354
|
}
|
|
19277
19355
|
function asObject(value) {
|
|
19278
19356
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
@@ -19299,16 +19377,16 @@ function mergeSideboardIntoMcpServersJson(existing, sideboard) {
|
|
|
19299
19377
|
}
|
|
19300
19378
|
function writeMergedMcpServersJson(configPath, sideboard) {
|
|
19301
19379
|
let existing = {};
|
|
19302
|
-
if ((0,
|
|
19380
|
+
if ((0, import_node_fs43.existsSync)(configPath)) {
|
|
19303
19381
|
try {
|
|
19304
|
-
existing = JSON.parse((0,
|
|
19382
|
+
existing = JSON.parse((0, import_node_fs43.readFileSync)(configPath, "utf8"));
|
|
19305
19383
|
} catch {
|
|
19306
19384
|
existing = {};
|
|
19307
19385
|
}
|
|
19308
19386
|
}
|
|
19309
19387
|
const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
|
|
19310
|
-
(0,
|
|
19311
|
-
(0,
|
|
19388
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path40.dirname)(configPath), { recursive: true });
|
|
19389
|
+
(0, import_node_fs43.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
|
|
19312
19390
|
`);
|
|
19313
19391
|
}
|
|
19314
19392
|
function launchFromResolved(server) {
|
|
@@ -19326,7 +19404,7 @@ async function registerPackagedUserMcpClients() {
|
|
|
19326
19404
|
const cursor = userCursorMcpConfigPath();
|
|
19327
19405
|
writeMergedMcpServersJson(cursor, launch);
|
|
19328
19406
|
const claude = userClaudeMcpConfigPath();
|
|
19329
|
-
if ((0,
|
|
19407
|
+
if ((0, import_node_fs43.existsSync)(claude)) {
|
|
19330
19408
|
writeMergedMcpServersJson(claude, launch);
|
|
19331
19409
|
return { cursor, claude };
|
|
19332
19410
|
}
|
|
@@ -20130,11 +20208,16 @@ function slackInboundSuperseded(opts) {
|
|
|
20130
20208
|
}
|
|
20131
20209
|
return opts.currentInboundGeneration() !== opts.inboundGeneration;
|
|
20132
20210
|
}
|
|
20133
|
-
function
|
|
20211
|
+
function slackCoordinatorGone(err) {
|
|
20212
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
20213
|
+
return /thread not found|thread is archived/i.test(errMsg);
|
|
20214
|
+
}
|
|
20215
|
+
function interruptSlackCoordinatorForInbound(msg, _agent, log = () => void 0) {
|
|
20134
20216
|
const userId = msg.userId?.trim();
|
|
20135
20217
|
if (!userId) return false;
|
|
20136
20218
|
try {
|
|
20137
|
-
const coordinator =
|
|
20219
|
+
const coordinator = findSlackCoordinator(msg.teamId, userId);
|
|
20220
|
+
if (!coordinator) return false;
|
|
20138
20221
|
const fresh = readThread(coordinator.id) ?? coordinator;
|
|
20139
20222
|
if (fresh.status !== "running" && fresh.status !== "queued") return false;
|
|
20140
20223
|
getOrchestrator().stop(fresh.id, { clearQueue: true });
|
|
@@ -20300,15 +20383,16 @@ async function handleSlackInbound(msg, opts) {
|
|
|
20300
20383
|
log(`skip superseded ${msg.kind} ${msg.ts}`);
|
|
20301
20384
|
return;
|
|
20302
20385
|
}
|
|
20303
|
-
const coordinator = ensureSlackCoordinator(msg.teamId, userId, agent);
|
|
20304
|
-
let fresh = readThread(coordinator.id) ?? coordinator;
|
|
20305
20386
|
if (isSlackStopCommand(msg.text)) {
|
|
20306
|
-
|
|
20307
|
-
|
|
20308
|
-
|
|
20309
|
-
|
|
20310
|
-
|
|
20311
|
-
|
|
20387
|
+
const live = findSlackCoordinator(msg.teamId, userId);
|
|
20388
|
+
if (live) {
|
|
20389
|
+
try {
|
|
20390
|
+
getOrchestrator().stop(live.id, { clearQueue: true });
|
|
20391
|
+
log(`stop ${msg.kind} ${msg.ts} \u2192 coordinator ${live.id.slice(0, 8)}`);
|
|
20392
|
+
} catch (err) {
|
|
20393
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
20394
|
+
log(`stop ${msg.ts}: ${errMsg}`);
|
|
20395
|
+
}
|
|
20312
20396
|
}
|
|
20313
20397
|
if (slackInboundSuperseded(opts)) {
|
|
20314
20398
|
log(`skip superseded stop reply ${msg.ts}`);
|
|
@@ -20318,34 +20402,65 @@ async function handleSlackInbound(msg, opts) {
|
|
|
20318
20402
|
log(`replied stopped ${msg.ts}`);
|
|
20319
20403
|
return;
|
|
20320
20404
|
}
|
|
20405
|
+
const opened = ensureSlackCoordinator(msg.teamId, userId, agent);
|
|
20406
|
+
let fresh = readThread(opened.id) ?? opened;
|
|
20321
20407
|
if (fresh.status === "running" || fresh.status === "queued") {
|
|
20322
20408
|
interruptSlackCoordinatorForInbound(msg, agent, log);
|
|
20323
|
-
fresh = readThread(
|
|
20409
|
+
fresh = readThread(fresh.id) ?? fresh;
|
|
20324
20410
|
}
|
|
20325
20411
|
log(
|
|
20326
20412
|
`run ${msg.kind} ${msg.ts} user ${userId} \u2192 coordinator ${fresh.id.slice(0, 8)} (${inventory.length} workspace${inventory.length === 1 ? "" : "s"})`
|
|
20327
20413
|
);
|
|
20328
20414
|
const prompt = formatSlackInboundPrompt(msg);
|
|
20329
|
-
setSlackReplyTarget({
|
|
20330
|
-
threadId: fresh.id,
|
|
20331
|
-
teamId: msg.teamId,
|
|
20332
|
-
channelId: msg.channelId,
|
|
20333
|
-
threadTs: slackReplyThreadTs(msg)
|
|
20334
|
-
});
|
|
20335
20415
|
const orch = getOrchestrator();
|
|
20416
|
+
const bindReplyTarget = (threadId) => {
|
|
20417
|
+
setSlackReplyTarget({
|
|
20418
|
+
threadId,
|
|
20419
|
+
teamId: msg.teamId,
|
|
20420
|
+
channelId: msg.channelId,
|
|
20421
|
+
threadTs: slackReplyThreadTs(msg)
|
|
20422
|
+
});
|
|
20423
|
+
};
|
|
20424
|
+
bindReplyTarget(fresh.id);
|
|
20425
|
+
const runTurn = async (threadId) => {
|
|
20426
|
+
await orch.send(threadId, prompt);
|
|
20427
|
+
await orch.waitForTurn(threadId, 14 * 60 * 1e3);
|
|
20428
|
+
};
|
|
20336
20429
|
let reply;
|
|
20337
20430
|
try {
|
|
20338
|
-
|
|
20339
|
-
|
|
20431
|
+
try {
|
|
20432
|
+
await runTurn(fresh.id);
|
|
20433
|
+
} catch (err) {
|
|
20434
|
+
if (!slackCoordinatorGone(err)) throw err;
|
|
20435
|
+
log(`coordinator ${fresh.id.slice(0, 8)} gone, opening a new chat`);
|
|
20436
|
+
fresh = ensureSlackCoordinator(msg.teamId, userId, agent, { forceNew: true });
|
|
20437
|
+
bindReplyTarget(fresh.id);
|
|
20438
|
+
await runTurn(fresh.id);
|
|
20439
|
+
}
|
|
20340
20440
|
if (slackInboundSuperseded(opts)) {
|
|
20341
20441
|
log(`turn finished ${msg.ts} (superseded)`);
|
|
20342
20442
|
return;
|
|
20343
20443
|
}
|
|
20344
|
-
|
|
20345
|
-
if (
|
|
20444
|
+
let after = readThread(fresh.id);
|
|
20445
|
+
if (after?.status === "stopped") {
|
|
20346
20446
|
log(`turn finished ${msg.ts} (interrupted, skip post)`);
|
|
20347
20447
|
return;
|
|
20348
20448
|
}
|
|
20449
|
+
if (!after || after.status === "archived") {
|
|
20450
|
+
log(`coordinator ${fresh.id.slice(0, 8)} closed, opening a new chat`);
|
|
20451
|
+
fresh = ensureSlackCoordinator(msg.teamId, userId, agent, { forceNew: true });
|
|
20452
|
+
bindReplyTarget(fresh.id);
|
|
20453
|
+
await runTurn(fresh.id);
|
|
20454
|
+
if (slackInboundSuperseded(opts)) {
|
|
20455
|
+
log(`turn finished ${msg.ts} (superseded)`);
|
|
20456
|
+
return;
|
|
20457
|
+
}
|
|
20458
|
+
after = readThread(fresh.id);
|
|
20459
|
+
if (!after || after.status === "stopped" || after.status === "archived") {
|
|
20460
|
+
log(`turn finished ${msg.ts} (interrupted, skip post)`);
|
|
20461
|
+
return;
|
|
20462
|
+
}
|
|
20463
|
+
}
|
|
20349
20464
|
reply = orch.getTurnResult(fresh.id).text.trim();
|
|
20350
20465
|
} catch (err) {
|
|
20351
20466
|
if (slackInboundSuperseded(opts)) {
|
|
@@ -20353,8 +20468,7 @@ async function handleSlackInbound(msg, opts) {
|
|
|
20353
20468
|
return;
|
|
20354
20469
|
}
|
|
20355
20470
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
20356
|
-
|
|
20357
|
-
if (gone) {
|
|
20471
|
+
if (slackCoordinatorGone(err)) {
|
|
20358
20472
|
log(`turn finished ${msg.ts} (thread gone, skip post)`);
|
|
20359
20473
|
return;
|
|
20360
20474
|
}
|
|
@@ -20704,9 +20818,9 @@ var import_node_http3 = require("http");
|
|
|
20704
20818
|
var import_ws3 = require("ws");
|
|
20705
20819
|
|
|
20706
20820
|
// src/slack/relay-static.ts
|
|
20707
|
-
var
|
|
20821
|
+
var import_node_fs44 = require("fs");
|
|
20708
20822
|
var import_promises = require("fs/promises");
|
|
20709
|
-
var
|
|
20823
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
20710
20824
|
var TYPES = {
|
|
20711
20825
|
".css": "text/css; charset=utf-8",
|
|
20712
20826
|
".html": "text/html; charset=utf-8",
|
|
@@ -20737,9 +20851,9 @@ function resolveStaticPath(root, requestUrl) {
|
|
|
20737
20851
|
return null;
|
|
20738
20852
|
}
|
|
20739
20853
|
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
20740
|
-
const rootResolved =
|
|
20741
|
-
const candidate =
|
|
20742
|
-
if (candidate !== rootResolved && !candidate.startsWith(rootResolved +
|
|
20854
|
+
const rootResolved = import_node_path41.default.resolve(root);
|
|
20855
|
+
const candidate = import_node_path41.default.resolve(rootResolved, `.${pathname}`);
|
|
20856
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path41.default.sep)) {
|
|
20743
20857
|
return null;
|
|
20744
20858
|
}
|
|
20745
20859
|
return candidate;
|
|
@@ -20753,7 +20867,7 @@ async function fileSize(file) {
|
|
|
20753
20867
|
}
|
|
20754
20868
|
}
|
|
20755
20869
|
function sendFile(req, res, file, size) {
|
|
20756
|
-
const ext =
|
|
20870
|
+
const ext = import_node_path41.default.extname(file).toLowerCase();
|
|
20757
20871
|
res.writeHead(200, {
|
|
20758
20872
|
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
20759
20873
|
"Content-Length": size,
|
|
@@ -20763,7 +20877,7 @@ function sendFile(req, res, file, size) {
|
|
|
20763
20877
|
res.end();
|
|
20764
20878
|
return true;
|
|
20765
20879
|
}
|
|
20766
|
-
(0,
|
|
20880
|
+
(0, import_node_fs44.createReadStream)(file).pipe(res);
|
|
20767
20881
|
return true;
|
|
20768
20882
|
}
|
|
20769
20883
|
async function tryServeStatic(req, res, root) {
|
|
@@ -20772,7 +20886,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
20772
20886
|
if (!candidate) return false;
|
|
20773
20887
|
const direct = await fileSize(candidate);
|
|
20774
20888
|
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
20775
|
-
const asIndex =
|
|
20889
|
+
const asIndex = import_node_path41.default.join(candidate, "index.html");
|
|
20776
20890
|
const indexSize = await fileSize(asIndex);
|
|
20777
20891
|
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
20778
20892
|
return false;
|
|
@@ -21098,6 +21212,7 @@ async function startSlackRelayServer(opts) {
|
|
|
21098
21212
|
captureTurnBaseline,
|
|
21099
21213
|
checkoutPrStackLayer,
|
|
21100
21214
|
childEnvWithAppSettings,
|
|
21215
|
+
claimDesktopHost,
|
|
21101
21216
|
claudeAdapter,
|
|
21102
21217
|
claudeChromeEnabled,
|
|
21103
21218
|
claudeUserSettingsPath,
|
|
@@ -21136,6 +21251,7 @@ async function startSlackRelayServer(opts) {
|
|
|
21136
21251
|
decodeBrightsyTarget,
|
|
21137
21252
|
deleteBranchOnPurgeEnabled,
|
|
21138
21253
|
deleteThreadRecord,
|
|
21254
|
+
desktopHostPidPath,
|
|
21139
21255
|
detectAgents,
|
|
21140
21256
|
detectGhStack,
|
|
21141
21257
|
detectLocalMergeConflicts,
|
|
@@ -21169,6 +21285,7 @@ async function startSlackRelayServer(opts) {
|
|
|
21169
21285
|
findConventionSetup,
|
|
21170
21286
|
findInvalidCacheControlTtlOrder,
|
|
21171
21287
|
findOrphanWorktrees,
|
|
21288
|
+
findSlackCoordinator,
|
|
21172
21289
|
findThreadByRef,
|
|
21173
21290
|
findThreadForStackLayer,
|
|
21174
21291
|
flattenTurnInput,
|
|
@@ -21260,6 +21377,7 @@ async function startSlackRelayServer(opts) {
|
|
|
21260
21377
|
isConductorBundledCli,
|
|
21261
21378
|
isCursorAutoModel,
|
|
21262
21379
|
isDefaultishSourceRef,
|
|
21380
|
+
isDesktopHostAlive,
|
|
21263
21381
|
isDirty,
|
|
21264
21382
|
isGhRateLimitError,
|
|
21265
21383
|
isGlobalRepoPath,
|
|
@@ -21281,6 +21399,7 @@ async function startSlackRelayServer(opts) {
|
|
|
21281
21399
|
isSlackExternalReplyPrompt,
|
|
21282
21400
|
isSlackOAuthCancelled,
|
|
21283
21401
|
isThinkingEffort,
|
|
21402
|
+
isThisProcessDesktopHost,
|
|
21284
21403
|
isThreadCaffeinated,
|
|
21285
21404
|
isWorkspaceScratchPath,
|
|
21286
21405
|
linearAuthorizationHeader,
|
|
@@ -21382,6 +21501,7 @@ async function startSlackRelayServer(opts) {
|
|
|
21382
21501
|
refreshSlackReplyBadges,
|
|
21383
21502
|
registerPackagedUserMcpClients,
|
|
21384
21503
|
releaseCaffeinateHoldForThread,
|
|
21504
|
+
releaseDesktopHost,
|
|
21385
21505
|
removeWorkspace,
|
|
21386
21506
|
removeWorktree,
|
|
21387
21507
|
repoSlug,
|
|
@@ -21482,6 +21602,7 @@ async function startSlackRelayServer(opts) {
|
|
|
21482
21602
|
taskMessageText,
|
|
21483
21603
|
thinkingEffortBars,
|
|
21484
21604
|
thinkingEffortLabel,
|
|
21605
|
+
thisProcessShouldDrainAgentQueues,
|
|
21485
21606
|
threadDisplayLabel,
|
|
21486
21607
|
threadFilePath,
|
|
21487
21608
|
threadLockPath,
|