@sideboard-ai/core 0.1.174 → 0.1.176
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{abletime-PCLL36HW.js → abletime-BFIDZR3O.js} +2 -2
- package/dist/{abletime-7VW4EGPT.js → abletime-INEHQH6K.js} +2 -2
- package/dist/agents/cursor-runner.cjs +91 -62
- package/dist/agents/cursor-runner.js +1 -1
- package/dist/{agents-ZWYRGFZB.js → agents-544IX5KA.js} +8 -6
- package/dist/{agents-LMPVUPOH.js → agents-UENEQ6J2.js} +7 -5
- package/dist/{chunk-ZY7K4T37.js → chunk-3ZFGZ7RT.js} +5 -5
- package/dist/{chunk-HJPGIETB.js → chunk-4ELBAYFW.js} +19 -14
- package/dist/{chunk-M267JPEA.js → chunk-AN3THU7F.js} +1 -1
- package/dist/{chunk-AQPVBVJE.js → chunk-BBNUL4IE.js} +1 -1
- package/dist/{chunk-VCVBICMZ.js → chunk-FJWQCZ74.js} +5 -5
- package/dist/{chunk-LZ6QMEQC.js → chunk-HVIEYTUK.js} +1 -1
- package/dist/{chunk-XD2BAANL.js → chunk-IEEAVWAP.js} +6 -6
- package/dist/{chunk-YEPVWJ3R.js → chunk-JUA7XEXR.js} +16 -11
- package/dist/{chunk-ELBYOGVA.js → chunk-N7WZ6NIN.js} +10 -1
- package/dist/{chunk-CUA4S537.js → chunk-NIB6BTC6.js} +9 -5
- package/dist/{chunk-XXIH6XYR.js → chunk-NQTKRAUF.js} +167 -35
- package/dist/{chunk-CMJ2FBBV.js → chunk-RE2YWFUQ.js} +1 -1
- package/dist/{chunk-6GN5WPYZ.js → chunk-VKQGAWHY.js} +10 -1
- package/dist/{chunk-TPPZXZTA.js → chunk-W44EKPIR.js} +228 -95
- package/dist/{chunk-S42XV45P.js → chunk-Y4MIXGPA.js} +1 -1
- package/dist/{connected-teams-DBWAMP7G.js → connected-teams-ON2KIKQX.js} +3 -3
- package/dist/{connected-teams-WGONUQOF.js → connected-teams-WOYCH7FR.js} +3 -3
- package/dist/{coordinator-prompt-K3HXEPFD.js → coordinator-prompt-BE2FERYE.js} +1 -1
- package/dist/{coordinator-prompt-LJKA2ODR.js → coordinator-prompt-PRM5ARWG.js} +1 -1
- package/dist/{global-workspace-VDFSU3DD.js → global-workspace-3HIWNQ3B.js} +1 -1
- package/dist/{global-workspace-KA7T26F5.js → global-workspace-J737XNUX.js} +1 -1
- package/dist/index.cjs +584 -379
- package/dist/index.d.cts +53 -10
- package/dist/index.d.ts +53 -10
- package/dist/index.js +76 -27
- package/dist/mcp/run-stdio.cjs +778 -576
- package/dist/mcp/run-stdio.js +78 -27
- package/dist/{oauth-A7XXI2TM.js → oauth-6ZQ4Q4XN.js} +2 -2
- package/dist/{oauth-YJBAURIJ.js → oauth-O7UGLZOY.js} +2 -2
- package/dist/{orchestrator-DMSSC4SV.js → orchestrator-2KZD7N4X.js} +6 -6
- package/dist/{orchestrator-VMUZJFTZ.js → orchestrator-GDKEVLFK.js} +7 -7
- package/dist/{workspaces-GOGBPATJ.js → workspaces-DR4UNOQC.js} +1 -1
- package/dist/{workspaces-UR7YEFMZ.js → workspaces-ULHYXM4Y.js} +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -7684,8 +7684,8 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
7684
7684
|
"",
|
|
7685
7685
|
"When creating threads, pass `repoPath` from `list_workspaces` (or the path you just registered).",
|
|
7686
7686
|
orchId ? `Pass parentThreadId="${orchId}" (or omit it). Never invent another parentThreadId.` : "Pass `parentThreadId` for children (this chat's id from the turn reminder).",
|
|
7687
|
-
"Omit `agent` / `model` on `create_thread
|
|
7688
|
-
"Never pass `agent=codex` when you yourself are Codex \u2014 nested Codex
|
|
7687
|
+
"Omit `agent` / `model` on `create_thread`. Sideboard applies Settings \u2192 Default agent, model & effort. Do not pass your own agent or `agent=cursor` \u2014 those are ignored.",
|
|
7688
|
+
"Never pass `agent=codex` when you yourself are Codex \u2014 nested Codex can deadlock on shared ~/.codex locks. Omit agent; Sideboard applies Account defaults, and switches that nested-Codex case to Cursor only when a CURSOR_API_KEY is configured.",
|
|
7689
7689
|
"Typical flow (Home board): list_board \u2192 create_thread (sourceType=ticket|pr|branch) \u2192 send_to_thread \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft \u2192 wait_for_turn. Merge only if the user explicitly asked (`ask_git` merge).",
|
|
7690
7690
|
"Typical flow (branch / explicit source): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
|
|
7691
7691
|
"Typical flow (find work): list_workspaces \u2192 pick repo(s) matching account / project context \u2192 Sideboard list_issues / linear_* (tickets) or list_prs(queue=review) (reviews) \u2192 show the options. Never wait on Claude Linear MCP. Only create_thread + send_to_thread when they asked to start (e.g. \u201Cfind me work and start it\u201D) \u2014 then wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
|
|
@@ -7762,7 +7762,7 @@ var init_coordinator_prompt = __esm({
|
|
|
7762
7762
|
"Workspaces:",
|
|
7763
7763
|
"- add_workspace / remove_workspace \u2014 register or unregister a git repo",
|
|
7764
7764
|
"Worktree threads (chats):",
|
|
7765
|
-
"- create_thread \u2014 create a worktree + chat from branch | pr | ticket (appears on Home). Do not create a second worktree for a ticket, PR, or named branch that already has one \u2014 that call returns the live thread (alreadyStarted=true). Creating from the default branch still opens a new isolated worktree. Pass repoPath + parentThreadId; omit agent and model
|
|
7765
|
+
"- create_thread \u2014 create a worktree + chat from branch | pr | ticket (appears on Home). Do not create a second worktree for a ticket, PR, or named branch that already has one \u2014 that call returns the live thread (alreadyStarted=true). Creating from the default branch still opens a new isolated worktree. Pass repoPath + parentThreadId; omit agent and model so Sideboard applies Settings \u2192 Default agent, model & effort (never pass your own agent or agent=cursor). If the repo has a setup script, Sideboard runs it in the background (does not block send_to_thread). Nested Codex (you are Codex and the child would be Codex) can deadlock on ~/.codex locks \u2014 omit agent; Sideboard switches the child to Cursor when a CURSOR_API_KEY is set, otherwise keeps the Account default",
|
|
7766
7766
|
"- start_board_card \u2014 same as create_thread for a ticket/PR/named branch (attaches issue text when resolvable). Then send_to_thread.",
|
|
7767
7767
|
"- fork_worktree \u2014 fork a worktree chat into a NEW git worktree + chat (transcript attached); optional agent; leave model unset (Auto) unless you have a reason. Not for orchestration chats.",
|
|
7768
7768
|
"- fork_chat \u2014 fork a worktree chat (same worktree tab) OR a Global orchestration chat (new orchestration tab); optional agent; leave model unset (Auto) unless you have a reason. Remote coordinators: use this to continue another orchestration chat on a different agent after session limits.",
|
|
@@ -7777,9 +7777,9 @@ var init_coordinator_prompt = __esm({
|
|
|
7777
7777
|
"- get_diff \u2014 compact diff summary",
|
|
7778
7778
|
"- get_pr_checks \u2014 snapshot of a worktree thread's PR checks (null = no PR). Use this to inspect status. If the user gave a goal, the worktree agent watches with `gh pr checks --watch` \u2014 do not poll for the human.",
|
|
7779
7779
|
'- request_review \u2014 open a Review chat tab on a worktree thread (attaches .claude/skills/review/SKILL.md when present, else .context/review.md copied from .sideboard/review.md / stock; sends "Review changes in this workspace."); then wait_for_turn (loop while stillRunning) / get_turn_result on the returned id',
|
|
7780
|
-
"- ask_git \u2014 commit & push, open a draft PR, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it queues the worktree agent \u2014 then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If ask_git / get_thread lastError says the GraphQL/PR body is too long, the branch is already pushed \u2014 send_to_thread so the worktree agent runs `gh pr create --body-file` with a short description. Do not invent SSH or auth failures from that error. If the user gave a goal (Greptile 5/5, CI green), send_to_thread that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
|
|
7780
|
+
"- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it queues the worktree agent \u2014 then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If ask_git / get_thread lastError says the GraphQL/PR body is too long, the branch is already pushed \u2014 send_to_thread so the worktree agent runs `gh pr create --body-file` with a short description. Do not invent SSH or auth failures from that error. If the user gave a goal (Greptile 5/5, CI green), send_to_thread that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
|
|
7781
7781
|
'- Merge (`ask_git` action=merge / send_to_thread "Merge PR.") only when the user explicitly asked to merge that PR. Do not merge because the work looks done, CI is green, or a typical flow includes it.',
|
|
7782
|
-
'- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
|
|
7782
|
+
'- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
|
|
7783
7783
|
"Process guides:",
|
|
7784
7784
|
"- Long child jobs (pack, test, deploy, anything that may run more than ~30s): workers always have `/long-running` (Sideboard product skill). Tell them to detach and wait; they may `stop_job` if it hangs or is doing the wrong thing; do not ask the human to poll.",
|
|
7785
7785
|
"- Recurring multi-item / fan-out: if the child worktree has `.claude/skills/graph-engineering/SKILL.md`, tell the worker to follow it (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch three threads.",
|
|
@@ -8943,17 +8943,24 @@ var init_config = __esm({
|
|
|
8943
8943
|
function setHttpFetchImpl(fetchImpl) {
|
|
8944
8944
|
injected = fetchImpl;
|
|
8945
8945
|
}
|
|
8946
|
+
function tlsIssuerHint(code, message) {
|
|
8947
|
+
const text7 = `${code ?? ""} ${message}`;
|
|
8948
|
+
return TLS_ISSUER_RE.test(text7) ? TLS_ISSUER_HINT : "";
|
|
8949
|
+
}
|
|
8946
8950
|
function formatFetchError(err, url) {
|
|
8947
8951
|
if (!(err instanceof Error)) return `${String(err)} (${url})`;
|
|
8948
8952
|
const cause = err.cause;
|
|
8949
8953
|
let detail = "";
|
|
8954
|
+
let hint = tlsIssuerHint(void 0, err.message);
|
|
8950
8955
|
if (cause instanceof Error) {
|
|
8951
8956
|
const code = typeof cause.code === "string" ? cause.code : void 0;
|
|
8952
8957
|
detail = code ? ` [${code}: ${cause.message}]` : ` [${cause.message}]`;
|
|
8958
|
+
hint = tlsIssuerHint(code, `${err.message} ${cause.message}`) || hint;
|
|
8953
8959
|
} else if (cause != null) {
|
|
8954
8960
|
detail = ` [${String(cause)}]`;
|
|
8961
|
+
hint = tlsIssuerHint(void 0, String(cause)) || hint;
|
|
8955
8962
|
}
|
|
8956
|
-
return `${err.message}${detail} (${url})`;
|
|
8963
|
+
return `${err.message}${detail} (${url})${hint}`;
|
|
8957
8964
|
}
|
|
8958
8965
|
async function httpFetch(input, init) {
|
|
8959
8966
|
const url = typeof input === "string" ? input : input.href;
|
|
@@ -8964,11 +8971,13 @@ async function httpFetch(input, init) {
|
|
|
8964
8971
|
throw new Error(formatFetchError(err, url));
|
|
8965
8972
|
}
|
|
8966
8973
|
}
|
|
8967
|
-
var injected;
|
|
8974
|
+
var injected, TLS_ISSUER_RE, TLS_ISSUER_HINT;
|
|
8968
8975
|
var init_fetch = __esm({
|
|
8969
8976
|
"src/http/fetch.ts"() {
|
|
8970
8977
|
"use strict";
|
|
8971
8978
|
injected = null;
|
|
8979
|
+
TLS_ISSUER_RE = /UNABLE_TO_GET_ISSUER_CERT|UNABLE_TO_VERIFY_LEAF_SIGNATURE|SELF_SIGNED_CERT_IN_CHAIN/i;
|
|
8980
|
+
TLS_ISSUER_HINT = " \u2014 Node rejected the TLS certificate (corporate VPN/proxy CA). Desktop Linear can still work; reconnecting the API key will not fix this.";
|
|
8972
8981
|
}
|
|
8973
8982
|
});
|
|
8974
8983
|
|
|
@@ -10521,6 +10530,138 @@ var init_profile = __esm({
|
|
|
10521
10530
|
}
|
|
10522
10531
|
});
|
|
10523
10532
|
|
|
10533
|
+
// src/http/system-ca.ts
|
|
10534
|
+
function splitPemCertificates(pem) {
|
|
10535
|
+
return pem.match(PEM_CERT_RE) ?? [];
|
|
10536
|
+
}
|
|
10537
|
+
function readExistingFile(path2) {
|
|
10538
|
+
try {
|
|
10539
|
+
return (0, import_node_fs26.existsSync)(path2) ? (0, import_node_fs26.readFileSync)(path2, "utf8") : "";
|
|
10540
|
+
} catch {
|
|
10541
|
+
return "";
|
|
10542
|
+
}
|
|
10543
|
+
}
|
|
10544
|
+
function darwinKeychainPem(spawn2) {
|
|
10545
|
+
const result = spawn2("/usr/bin/security", ["find-certificate", "-a", "-p"], {
|
|
10546
|
+
encoding: "utf8",
|
|
10547
|
+
maxBuffer: 32 * 1024 * 1024,
|
|
10548
|
+
timeout: 15e3
|
|
10549
|
+
});
|
|
10550
|
+
if (result.status !== 0) return "";
|
|
10551
|
+
return typeof result.stdout === "string" ? result.stdout : "";
|
|
10552
|
+
}
|
|
10553
|
+
function linuxSystemCaPem() {
|
|
10554
|
+
for (const path2 of LINUX_CA_FILES) {
|
|
10555
|
+
const pem = readExistingFile(path2);
|
|
10556
|
+
if (splitPemCertificates(pem).length > 0) return pem;
|
|
10557
|
+
}
|
|
10558
|
+
return "";
|
|
10559
|
+
}
|
|
10560
|
+
function collectSystemCaPem(io = {}) {
|
|
10561
|
+
const platform = io.platform ?? process.platform;
|
|
10562
|
+
if (platform === "darwin") {
|
|
10563
|
+
return darwinKeychainPem(io.spawn ?? import_node_child_process4.spawnSync);
|
|
10564
|
+
}
|
|
10565
|
+
if (platform === "linux") {
|
|
10566
|
+
return linuxSystemCaPem();
|
|
10567
|
+
}
|
|
10568
|
+
return "";
|
|
10569
|
+
}
|
|
10570
|
+
function systemCaBundlePath(io = {}) {
|
|
10571
|
+
return (0, import_node_path28.join)((io.appData ?? appDataDir)(), BUNDLE_NAME);
|
|
10572
|
+
}
|
|
10573
|
+
function bundleIsFresh(path2, now) {
|
|
10574
|
+
try {
|
|
10575
|
+
if (!(0, import_node_fs26.existsSync)(path2)) return false;
|
|
10576
|
+
if (splitPemCertificates((0, import_node_fs26.readFileSync)(path2, "utf8")).length === 0) return false;
|
|
10577
|
+
return now - (0, import_node_fs26.statSync)(path2).mtimeMs < BUNDLE_MAX_AGE_MS;
|
|
10578
|
+
} catch {
|
|
10579
|
+
return false;
|
|
10580
|
+
}
|
|
10581
|
+
}
|
|
10582
|
+
function materializeSystemCaBundle(io = {}) {
|
|
10583
|
+
const inherited = process.env.NODE_EXTRA_CA_CERTS?.trim();
|
|
10584
|
+
if (inherited && splitPemCertificates(readExistingFile(inherited)).length > 0) {
|
|
10585
|
+
return inherited;
|
|
10586
|
+
}
|
|
10587
|
+
const platform = io.platform ?? process.platform;
|
|
10588
|
+
if (platform === "linux") {
|
|
10589
|
+
for (const path2 of LINUX_CA_FILES) {
|
|
10590
|
+
if (splitPemCertificates(readExistingFile(path2)).length > 0) return path2;
|
|
10591
|
+
}
|
|
10592
|
+
}
|
|
10593
|
+
const dest = systemCaBundlePath(io);
|
|
10594
|
+
const now = (io.now ?? Date.now)();
|
|
10595
|
+
if (bundleIsFresh(dest, now)) return dest;
|
|
10596
|
+
const pem = collectSystemCaPem(io);
|
|
10597
|
+
if (splitPemCertificates(pem).length === 0) {
|
|
10598
|
+
return (0, import_node_fs26.existsSync)(dest) && splitPemCertificates(readExistingFile(dest)).length > 0 ? dest : void 0;
|
|
10599
|
+
}
|
|
10600
|
+
try {
|
|
10601
|
+
(0, import_node_fs26.mkdirSync)((0, import_node_path28.dirname)(dest), { recursive: true });
|
|
10602
|
+
(0, import_node_fs26.writeFileSync)(dest, pem.endsWith("\n") ? pem : `${pem}
|
|
10603
|
+
`, { mode: 384 });
|
|
10604
|
+
return dest;
|
|
10605
|
+
} catch {
|
|
10606
|
+
return void 0;
|
|
10607
|
+
}
|
|
10608
|
+
}
|
|
10609
|
+
function applySystemCaEnv(env) {
|
|
10610
|
+
if (!String(env[NODE_USE_SYSTEM_CA] ?? "").trim()) {
|
|
10611
|
+
env[NODE_USE_SYSTEM_CA] = "1";
|
|
10612
|
+
}
|
|
10613
|
+
if (String(env[NODE_EXTRA_CA_CERTS] ?? "").trim()) return;
|
|
10614
|
+
const inherited = process.env.NODE_EXTRA_CA_CERTS?.trim();
|
|
10615
|
+
if (inherited) env[NODE_EXTRA_CA_CERTS] = inherited;
|
|
10616
|
+
}
|
|
10617
|
+
function extraCertsFromBundle() {
|
|
10618
|
+
const path2 = process.env.NODE_EXTRA_CA_CERTS?.trim();
|
|
10619
|
+
if (path2) return splitPemCertificates(readExistingFile(path2));
|
|
10620
|
+
const dest = systemCaBundlePath();
|
|
10621
|
+
return splitPemCertificates(readExistingFile(dest));
|
|
10622
|
+
}
|
|
10623
|
+
function trustSystemCertificates(io = {}) {
|
|
10624
|
+
try {
|
|
10625
|
+
const api = import_node_tls.default;
|
|
10626
|
+
if (typeof api.getCACertificates !== "function" || typeof api.setDefaultCACertificates !== "function") {
|
|
10627
|
+
return false;
|
|
10628
|
+
}
|
|
10629
|
+
const current = api.getCACertificates("default");
|
|
10630
|
+
const system = api.getCACertificates("system");
|
|
10631
|
+
let extra = extraCertsFromBundle();
|
|
10632
|
+
if (system.length === 0 && extra.length === 0) {
|
|
10633
|
+
extra = splitPemCertificates(collectSystemCaPem(io));
|
|
10634
|
+
}
|
|
10635
|
+
if (system.length === 0 && extra.length === 0) return false;
|
|
10636
|
+
api.setDefaultCACertificates([...current, ...system, ...extra]);
|
|
10637
|
+
return true;
|
|
10638
|
+
} catch {
|
|
10639
|
+
return false;
|
|
10640
|
+
}
|
|
10641
|
+
}
|
|
10642
|
+
var import_node_child_process4, import_node_fs26, import_node_path28, import_node_tls, NODE_USE_SYSTEM_CA, NODE_EXTRA_CA_CERTS, BUNDLE_NAME, BUNDLE_MAX_AGE_MS, LINUX_CA_FILES, PEM_CERT_RE;
|
|
10643
|
+
var init_system_ca = __esm({
|
|
10644
|
+
"src/http/system-ca.ts"() {
|
|
10645
|
+
"use strict";
|
|
10646
|
+
import_node_child_process4 = require("child_process");
|
|
10647
|
+
import_node_fs26 = require("fs");
|
|
10648
|
+
import_node_path28 = require("path");
|
|
10649
|
+
import_node_tls = __toESM(require("tls"), 1);
|
|
10650
|
+
init_paths();
|
|
10651
|
+
NODE_USE_SYSTEM_CA = "NODE_USE_SYSTEM_CA";
|
|
10652
|
+
NODE_EXTRA_CA_CERTS = "NODE_EXTRA_CA_CERTS";
|
|
10653
|
+
BUNDLE_NAME = "system-ca.pem";
|
|
10654
|
+
BUNDLE_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
10655
|
+
LINUX_CA_FILES = [
|
|
10656
|
+
"/etc/ssl/certs/ca-certificates.crt",
|
|
10657
|
+
"/etc/pki/tls/certs/ca-bundle.crt",
|
|
10658
|
+
"/etc/ssl/ca-bundle.pem",
|
|
10659
|
+
"/etc/ssl/cert.pem"
|
|
10660
|
+
];
|
|
10661
|
+
PEM_CERT_RE = /-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g;
|
|
10662
|
+
}
|
|
10663
|
+
});
|
|
10664
|
+
|
|
10524
10665
|
// src/agents/packaged-runtime.ts
|
|
10525
10666
|
function electronResourcesPath() {
|
|
10526
10667
|
const resources = process.resourcesPath;
|
|
@@ -10530,43 +10671,43 @@ function electronResourcesPath() {
|
|
|
10530
10671
|
function packagedCursorRuntimeDir() {
|
|
10531
10672
|
const resources = electronResourcesPath();
|
|
10532
10673
|
if (!resources) return null;
|
|
10533
|
-
const dir = (0,
|
|
10534
|
-
if (!(0,
|
|
10674
|
+
const dir = (0, import_node_path29.join)(resources, "cursor-runtime");
|
|
10675
|
+
if (!(0, import_node_fs27.existsSync)((0, import_node_path29.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
|
|
10535
10676
|
return dir;
|
|
10536
10677
|
}
|
|
10537
10678
|
function packagedCursorRunnerPath() {
|
|
10538
10679
|
const dir = packagedCursorRuntimeDir();
|
|
10539
|
-
return dir ? (0,
|
|
10680
|
+
return dir ? (0, import_node_path29.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
|
|
10540
10681
|
}
|
|
10541
10682
|
function packagedMcpDir() {
|
|
10542
10683
|
const resources = electronResourcesPath();
|
|
10543
10684
|
if (!resources) return null;
|
|
10544
|
-
const dir = (0,
|
|
10545
|
-
if (!(0,
|
|
10685
|
+
const dir = (0, import_node_path29.join)(resources, "sideboard-mcp");
|
|
10686
|
+
if (!(0, import_node_fs27.existsSync)((0, import_node_path29.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
|
|
10546
10687
|
return dir;
|
|
10547
10688
|
}
|
|
10548
10689
|
function packagedMcpStdioPath() {
|
|
10549
10690
|
const dir = packagedMcpDir();
|
|
10550
|
-
return dir ? (0,
|
|
10691
|
+
return dir ? (0, import_node_path29.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
|
|
10551
10692
|
}
|
|
10552
10693
|
function packagedBundledNodePath() {
|
|
10553
10694
|
const resources = electronResourcesPath();
|
|
10554
10695
|
if (!resources) return null;
|
|
10555
|
-
const bin = (0,
|
|
10556
|
-
if (!(0,
|
|
10696
|
+
const bin = (0, import_node_path29.join)(resources, "node", "bin", "node");
|
|
10697
|
+
if (!(0, import_node_fs27.existsSync)(bin)) return null;
|
|
10557
10698
|
return bin;
|
|
10558
10699
|
}
|
|
10559
10700
|
function packagedCursorRipgrepCandidate(platformPkg, binName) {
|
|
10560
10701
|
const dir = packagedCursorRuntimeDir();
|
|
10561
10702
|
if (!dir) return null;
|
|
10562
|
-
return (0,
|
|
10703
|
+
return (0, import_node_path29.join)(dir, "node_modules", platformPkg, "bin", binName);
|
|
10563
10704
|
}
|
|
10564
|
-
var
|
|
10705
|
+
var import_node_fs27, import_node_path29;
|
|
10565
10706
|
var init_packaged_runtime = __esm({
|
|
10566
10707
|
"src/agents/packaged-runtime.ts"() {
|
|
10567
10708
|
"use strict";
|
|
10568
|
-
|
|
10569
|
-
|
|
10709
|
+
import_node_fs27 = require("fs");
|
|
10710
|
+
import_node_path29 = require("path");
|
|
10570
10711
|
}
|
|
10571
10712
|
});
|
|
10572
10713
|
|
|
@@ -10586,6 +10727,7 @@ function applyAgentRunnerHeapEnv(env) {
|
|
|
10586
10727
|
env.NODE_OPTIONS,
|
|
10587
10728
|
AGENT_RUNNER_MAX_OLD_SPACE_MB
|
|
10588
10729
|
);
|
|
10730
|
+
applySystemCaEnv(env);
|
|
10589
10731
|
}
|
|
10590
10732
|
function envWithAgentHeap(env) {
|
|
10591
10733
|
const next = { ...env };
|
|
@@ -10600,7 +10742,7 @@ function unpackedAsarPath(filePath) {
|
|
|
10600
10742
|
if (!isAsarPath(filePath)) return null;
|
|
10601
10743
|
const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
|
|
10602
10744
|
if (unpacked === filePath) return null;
|
|
10603
|
-
return (0,
|
|
10745
|
+
return (0, import_node_fs28.existsSync)(unpacked) ? unpacked : null;
|
|
10604
10746
|
}
|
|
10605
10747
|
function nodeReadableScriptPath(scriptPath) {
|
|
10606
10748
|
return unpackedAsarPath(scriptPath) ?? scriptPath;
|
|
@@ -10640,37 +10782,37 @@ function pickPreferredNode(candidates) {
|
|
|
10640
10782
|
return best;
|
|
10641
10783
|
}
|
|
10642
10784
|
function versionDirNodeBins(root, toBin) {
|
|
10643
|
-
if (!(0,
|
|
10785
|
+
if (!(0, import_node_fs28.existsSync)(root)) return [];
|
|
10644
10786
|
try {
|
|
10645
|
-
return (0,
|
|
10787
|
+
return (0, import_node_fs28.readdirSync)(root).map(toBin);
|
|
10646
10788
|
} catch {
|
|
10647
10789
|
return [];
|
|
10648
10790
|
}
|
|
10649
10791
|
}
|
|
10650
10792
|
function defaultNodeBinCandidates(home = (0, import_node_os8.homedir)()) {
|
|
10651
10793
|
const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
|
|
10652
|
-
(prefix) => PREFERRED_LTS_MAJORS.map((major) => (0,
|
|
10794
|
+
(prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path30.join)(prefix, "opt", `node@${major}`, "bin", "node"))
|
|
10653
10795
|
);
|
|
10654
10796
|
return [
|
|
10655
10797
|
...kegs,
|
|
10656
10798
|
"/opt/homebrew/bin/node",
|
|
10657
10799
|
"/usr/local/bin/node",
|
|
10658
|
-
(0,
|
|
10659
|
-
(0,
|
|
10660
|
-
(0,
|
|
10661
|
-
(0,
|
|
10662
|
-
(0,
|
|
10800
|
+
(0, import_node_path30.join)(home, ".local/share/fnm/aliases/default/bin/node"),
|
|
10801
|
+
(0, import_node_path30.join)(home, ".nvm/current/bin/node"),
|
|
10802
|
+
(0, import_node_path30.join)(home, ".volta/bin/node"),
|
|
10803
|
+
(0, import_node_path30.join)(home, ".asdf/shims/node"),
|
|
10804
|
+
(0, import_node_path30.join)(home, ".local/share/mise/shims/node"),
|
|
10663
10805
|
...versionDirNodeBins(
|
|
10664
|
-
(0,
|
|
10665
|
-
(name) => (0,
|
|
10806
|
+
(0, import_node_path30.join)(home, ".nvm", "versions", "node"),
|
|
10807
|
+
(name) => (0, import_node_path30.join)(home, ".nvm", "versions", "node", name, "bin", "node")
|
|
10666
10808
|
),
|
|
10667
10809
|
...versionDirNodeBins(
|
|
10668
|
-
(0,
|
|
10669
|
-
(name) => (0,
|
|
10810
|
+
(0, import_node_path30.join)(home, ".local/share/fnm", "node-versions"),
|
|
10811
|
+
(name) => (0, import_node_path30.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
|
|
10670
10812
|
),
|
|
10671
10813
|
...versionDirNodeBins(
|
|
10672
|
-
(0,
|
|
10673
|
-
(name) => (0,
|
|
10814
|
+
(0, import_node_path30.join)(home, ".volta", "tools", "image", "node"),
|
|
10815
|
+
(name) => (0, import_node_path30.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
|
|
10674
10816
|
)
|
|
10675
10817
|
];
|
|
10676
10818
|
}
|
|
@@ -10679,10 +10821,10 @@ function uniqueExistingNodeBins(paths) {
|
|
|
10679
10821
|
const out = [];
|
|
10680
10822
|
for (const raw of paths) {
|
|
10681
10823
|
const p = raw.trim();
|
|
10682
|
-
if (!p || !(0,
|
|
10824
|
+
if (!p || !(0, import_node_fs28.existsSync)(p) || isElectronLikeCommand(p)) continue;
|
|
10683
10825
|
let key = p;
|
|
10684
10826
|
try {
|
|
10685
|
-
key = (0,
|
|
10827
|
+
key = (0, import_node_fs28.realpathSync)(p);
|
|
10686
10828
|
} catch {
|
|
10687
10829
|
continue;
|
|
10688
10830
|
}
|
|
@@ -10762,14 +10904,15 @@ async function resolveNodeLaunch(scriptPath) {
|
|
|
10762
10904
|
env: { ELECTRON_RUN_AS_NODE: "1" }
|
|
10763
10905
|
};
|
|
10764
10906
|
}
|
|
10765
|
-
var
|
|
10907
|
+
var import_node_fs28, import_node_os8, import_node_path30, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
|
|
10766
10908
|
var init_node_launch = __esm({
|
|
10767
10909
|
"src/agents/node-launch.ts"() {
|
|
10768
10910
|
"use strict";
|
|
10769
|
-
|
|
10911
|
+
import_node_fs28 = require("fs");
|
|
10770
10912
|
import_node_os8 = require("os");
|
|
10771
|
-
|
|
10913
|
+
import_node_path30 = require("path");
|
|
10772
10914
|
init_nested_electron_env();
|
|
10915
|
+
init_system_ca();
|
|
10773
10916
|
init_run();
|
|
10774
10917
|
init_packaged_runtime();
|
|
10775
10918
|
AGENT_RUNNER_MAX_OLD_SPACE_MB = 8192;
|
|
@@ -10869,37 +11012,37 @@ function corePackageDir() {
|
|
|
10869
11012
|
try {
|
|
10870
11013
|
const url = import_meta.url;
|
|
10871
11014
|
if (typeof url === "string" && url.length > 0) {
|
|
10872
|
-
return (0,
|
|
11015
|
+
return (0, import_node_path31.dirname)((0, import_node_url.fileURLToPath)(url));
|
|
10873
11016
|
}
|
|
10874
11017
|
} catch {
|
|
10875
11018
|
}
|
|
10876
11019
|
try {
|
|
10877
|
-
const req = (0, import_node_module.createRequire)((0,
|
|
10878
|
-
return (0,
|
|
11020
|
+
const req = (0, import_node_module.createRequire)((0, import_node_path31.join)(process.cwd(), "package.json"));
|
|
11021
|
+
return (0, import_node_path31.dirname)(req.resolve("@sideboard-ai/core"));
|
|
10879
11022
|
} catch {
|
|
10880
11023
|
return process.cwd();
|
|
10881
11024
|
}
|
|
10882
11025
|
}
|
|
10883
11026
|
function findSideboardMcpJsEntry() {
|
|
10884
11027
|
const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
|
|
10885
|
-
if (override && (0,
|
|
11028
|
+
if (override && (0, import_node_fs29.existsSync)(override)) return override;
|
|
10886
11029
|
const packaged = packagedMcpStdioPath();
|
|
10887
11030
|
if (packaged) return packaged;
|
|
10888
11031
|
let dir = corePackageDir();
|
|
10889
11032
|
for (let i = 0; i < 10; i++) {
|
|
10890
11033
|
const candidates = [
|
|
10891
|
-
(0,
|
|
10892
|
-
(0,
|
|
10893
|
-
(0,
|
|
10894
|
-
(0,
|
|
10895
|
-
(0,
|
|
10896
|
-
(0,
|
|
10897
|
-
(0,
|
|
11034
|
+
(0, import_node_path31.join)(dir, "mcp/run-stdio.js"),
|
|
11035
|
+
(0, import_node_path31.join)(dir, "mcp/run-stdio.cjs"),
|
|
11036
|
+
(0, import_node_path31.join)(dir, "dist/mcp/run-stdio.js"),
|
|
11037
|
+
(0, import_node_path31.join)(dir, "dist/mcp/run-stdio.cjs"),
|
|
11038
|
+
(0, import_node_path31.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
11039
|
+
(0, import_node_path31.join)(dir, "packages/cli/dist/index.js"),
|
|
11040
|
+
(0, import_node_path31.join)(dir, "cli/dist/index.js")
|
|
10898
11041
|
];
|
|
10899
11042
|
for (const p of candidates) {
|
|
10900
|
-
if ((0,
|
|
11043
|
+
if ((0, import_node_fs29.existsSync)(p) && !isAsarPath(p)) return p;
|
|
10901
11044
|
}
|
|
10902
|
-
const parent = (0,
|
|
11045
|
+
const parent = (0, import_node_path31.dirname)(dir);
|
|
10903
11046
|
if (parent === dir) break;
|
|
10904
11047
|
dir = parent;
|
|
10905
11048
|
}
|
|
@@ -11046,22 +11189,22 @@ function writeMcpServersConfig(servers) {
|
|
|
11046
11189
|
...env ? { env } : {}
|
|
11047
11190
|
};
|
|
11048
11191
|
}
|
|
11049
|
-
const dir = (0,
|
|
11050
|
-
const cfgPath = (0,
|
|
11051
|
-
(0,
|
|
11192
|
+
const dir = (0, import_node_fs29.mkdtempSync)((0, import_node_path31.join)((0, import_node_os9.tmpdir)(), "sideboard-mcp-"));
|
|
11193
|
+
const cfgPath = (0, import_node_path31.join)(dir, "mcp.json");
|
|
11194
|
+
(0, import_node_fs29.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
|
|
11052
11195
|
return cfgPath;
|
|
11053
11196
|
}
|
|
11054
11197
|
async function writeInjectedMcpConfig(opts) {
|
|
11055
11198
|
return writeMcpServersConfig(await buildInjectedMcpServers(opts));
|
|
11056
11199
|
}
|
|
11057
|
-
var
|
|
11200
|
+
var import_node_fs29, import_node_module, import_node_os9, import_node_path31, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS, SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS, SIDEBOARD_ABLETIME_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
|
|
11058
11201
|
var init_injected_mcp = __esm({
|
|
11059
11202
|
"src/agents/injected-mcp.ts"() {
|
|
11060
11203
|
"use strict";
|
|
11061
|
-
|
|
11204
|
+
import_node_fs29 = require("fs");
|
|
11062
11205
|
import_node_module = require("module");
|
|
11063
11206
|
import_node_os9 = require("os");
|
|
11064
|
-
|
|
11207
|
+
import_node_path31 = require("path");
|
|
11065
11208
|
import_node_url = require("url");
|
|
11066
11209
|
init_run();
|
|
11067
11210
|
init_config();
|
|
@@ -11448,11 +11591,11 @@ function parseIssuesJson(raw) {
|
|
|
11448
11591
|
}
|
|
11449
11592
|
return [];
|
|
11450
11593
|
}
|
|
11451
|
-
var
|
|
11594
|
+
var import_node_fs30, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, mcpListCache, claudeAdapter;
|
|
11452
11595
|
var init_claude = __esm({
|
|
11453
11596
|
"src/agents/claude.ts"() {
|
|
11454
11597
|
"use strict";
|
|
11455
|
-
|
|
11598
|
+
import_node_fs30 = require("fs");
|
|
11456
11599
|
init_run();
|
|
11457
11600
|
init_app_settings();
|
|
11458
11601
|
init_claude_mcp();
|
|
@@ -11492,7 +11635,7 @@ var init_claude = __esm({
|
|
|
11492
11635
|
async detect() {
|
|
11493
11636
|
const claude = resolveClaudeExecutable();
|
|
11494
11637
|
if (claude !== "claude") {
|
|
11495
|
-
if (!(0,
|
|
11638
|
+
if (!(0, import_node_fs30.existsSync)(claude)) {
|
|
11496
11639
|
return {
|
|
11497
11640
|
agent: "claude",
|
|
11498
11641
|
installed: false,
|
|
@@ -11752,10 +11895,10 @@ var init_claude = __esm({
|
|
|
11752
11895
|
|
|
11753
11896
|
// src/agents/user-mcp-config.ts
|
|
11754
11897
|
function userCursorMcpConfigPath() {
|
|
11755
|
-
return (0,
|
|
11898
|
+
return (0, import_node_path32.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
|
|
11756
11899
|
}
|
|
11757
11900
|
function userClaudeMcpConfigPath() {
|
|
11758
|
-
return (0,
|
|
11901
|
+
return (0, import_node_path32.join)((0, import_node_os10.homedir)(), ".claude.json");
|
|
11759
11902
|
}
|
|
11760
11903
|
function asObject(value) {
|
|
11761
11904
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
@@ -11782,16 +11925,16 @@ function mergeSideboardIntoMcpServersJson(existing, sideboard) {
|
|
|
11782
11925
|
}
|
|
11783
11926
|
function writeMergedMcpServersJson(configPath, sideboard) {
|
|
11784
11927
|
let existing = {};
|
|
11785
|
-
if ((0,
|
|
11928
|
+
if ((0, import_node_fs31.existsSync)(configPath)) {
|
|
11786
11929
|
try {
|
|
11787
|
-
existing = JSON.parse((0,
|
|
11930
|
+
existing = JSON.parse((0, import_node_fs31.readFileSync)(configPath, "utf8"));
|
|
11788
11931
|
} catch {
|
|
11789
11932
|
existing = {};
|
|
11790
11933
|
}
|
|
11791
11934
|
}
|
|
11792
11935
|
const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
|
|
11793
|
-
(0,
|
|
11794
|
-
(0,
|
|
11936
|
+
(0, import_node_fs31.mkdirSync)((0, import_node_path32.dirname)(configPath), { recursive: true });
|
|
11937
|
+
(0, import_node_fs31.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
|
|
11795
11938
|
`);
|
|
11796
11939
|
}
|
|
11797
11940
|
function launchFromResolved(server) {
|
|
@@ -11809,19 +11952,19 @@ async function registerPackagedUserMcpClients() {
|
|
|
11809
11952
|
const cursor = userCursorMcpConfigPath();
|
|
11810
11953
|
writeMergedMcpServersJson(cursor, launch);
|
|
11811
11954
|
const claude = userClaudeMcpConfigPath();
|
|
11812
|
-
if ((0,
|
|
11955
|
+
if ((0, import_node_fs31.existsSync)(claude)) {
|
|
11813
11956
|
writeMergedMcpServersJson(claude, launch);
|
|
11814
11957
|
return { cursor, claude };
|
|
11815
11958
|
}
|
|
11816
11959
|
return { cursor };
|
|
11817
11960
|
}
|
|
11818
|
-
var
|
|
11961
|
+
var import_node_fs31, import_node_os10, import_node_path32;
|
|
11819
11962
|
var init_user_mcp_config = __esm({
|
|
11820
11963
|
"src/agents/user-mcp-config.ts"() {
|
|
11821
11964
|
"use strict";
|
|
11822
|
-
|
|
11965
|
+
import_node_fs31 = require("fs");
|
|
11823
11966
|
import_node_os10 = require("os");
|
|
11824
|
-
|
|
11967
|
+
import_node_path32 = require("path");
|
|
11825
11968
|
init_paths();
|
|
11826
11969
|
init_injected_mcp();
|
|
11827
11970
|
}
|
|
@@ -11849,25 +11992,25 @@ function listMcpNamesFromCodexToml(text7) {
|
|
|
11849
11992
|
}
|
|
11850
11993
|
function readJsonObject(path2) {
|
|
11851
11994
|
try {
|
|
11852
|
-
return JSON.parse((0,
|
|
11995
|
+
return JSON.parse((0, import_node_fs32.readFileSync)(path2, "utf8"));
|
|
11853
11996
|
} catch {
|
|
11854
11997
|
return {};
|
|
11855
11998
|
}
|
|
11856
11999
|
}
|
|
11857
12000
|
function readText(path2) {
|
|
11858
12001
|
try {
|
|
11859
|
-
return (0,
|
|
12002
|
+
return (0, import_node_fs32.readFileSync)(path2, "utf8");
|
|
11860
12003
|
} catch {
|
|
11861
12004
|
return "";
|
|
11862
12005
|
}
|
|
11863
12006
|
}
|
|
11864
12007
|
function userCodexConfigPaths(home = (0, import_node_os11.homedir)()) {
|
|
11865
|
-
return [(0,
|
|
12008
|
+
return [(0, import_node_path33.join)(home, ".codex", "config.toml"), (0, import_node_path33.join)(home, ".config", "codex", "config.toml")];
|
|
11866
12009
|
}
|
|
11867
12010
|
function userOpencodeConfigPaths(home = (0, import_node_os11.homedir)()) {
|
|
11868
12011
|
return [
|
|
11869
|
-
(0,
|
|
11870
|
-
(0,
|
|
12012
|
+
(0, import_node_path33.join)(home, ".config", "opencode", "opencode.json"),
|
|
12013
|
+
(0, import_node_path33.join)(home, ".config", "opencode", "opencode.jsonc")
|
|
11871
12014
|
];
|
|
11872
12015
|
}
|
|
11873
12016
|
function userMcpNamesToDisable(opts) {
|
|
@@ -11889,7 +12032,7 @@ function userMcpNamesToDisable(opts) {
|
|
|
11889
12032
|
function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
|
|
11890
12033
|
const names = [];
|
|
11891
12034
|
for (const path2 of userCodexConfigPaths(home)) {
|
|
11892
|
-
if (!(0,
|
|
12035
|
+
if (!(0, import_node_fs32.existsSync)(path2)) continue;
|
|
11893
12036
|
names.push(...listMcpNamesFromCodexToml(readText(path2)));
|
|
11894
12037
|
}
|
|
11895
12038
|
return names;
|
|
@@ -11897,7 +12040,7 @@ function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
|
|
|
11897
12040
|
function listUserOpencodeMcpNames(home = (0, import_node_os11.homedir)()) {
|
|
11898
12041
|
const names = [];
|
|
11899
12042
|
for (const path2 of userOpencodeConfigPaths(home)) {
|
|
11900
|
-
if (!(0,
|
|
12043
|
+
if (!(0, import_node_fs32.existsSync)(path2)) continue;
|
|
11901
12044
|
names.push(...listMcpNamesFromJsonMap(readJsonObject(path2), "mcp"));
|
|
11902
12045
|
}
|
|
11903
12046
|
return names;
|
|
@@ -11910,13 +12053,13 @@ function toCodexDisableUserMcpArgs(names) {
|
|
|
11910
12053
|
}
|
|
11911
12054
|
return args;
|
|
11912
12055
|
}
|
|
11913
|
-
var
|
|
12056
|
+
var import_node_fs32, import_node_os11, import_node_path33, import_smol_toml2;
|
|
11914
12057
|
var init_orch_mcp_isolation = __esm({
|
|
11915
12058
|
"src/agents/orch-mcp-isolation.ts"() {
|
|
11916
12059
|
"use strict";
|
|
11917
|
-
|
|
12060
|
+
import_node_fs32 = require("fs");
|
|
11918
12061
|
import_node_os11 = require("os");
|
|
11919
|
-
|
|
12062
|
+
import_node_path33 = require("path");
|
|
11920
12063
|
import_smol_toml2 = require("smol-toml");
|
|
11921
12064
|
init_user_mcp_config();
|
|
11922
12065
|
}
|
|
@@ -11932,7 +12075,7 @@ async function listCodexModels() {
|
|
|
11932
12075
|
if (codex === "codex") {
|
|
11933
12076
|
const which = await run("which", ["codex"], { reject: false });
|
|
11934
12077
|
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
11935
|
-
} else if (!(0,
|
|
12078
|
+
} else if (!(0, import_node_fs33.existsSync)(codex)) {
|
|
11936
12079
|
return FALLBACK_CODEX_MODELS;
|
|
11937
12080
|
}
|
|
11938
12081
|
const listed = await run(codex, ["debug", "models"], { reject: false });
|
|
@@ -11967,12 +12110,12 @@ function usageFromCodex(usage) {
|
|
|
11967
12110
|
}
|
|
11968
12111
|
function codexConfigHasNetworkAccess() {
|
|
11969
12112
|
const candidates = [
|
|
11970
|
-
(0,
|
|
11971
|
-
(0,
|
|
12113
|
+
(0, import_node_path34.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
|
|
12114
|
+
(0, import_node_path34.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
|
|
11972
12115
|
];
|
|
11973
12116
|
for (const path2 of candidates) {
|
|
11974
|
-
if (!(0,
|
|
11975
|
-
const text7 = (0,
|
|
12117
|
+
if (!(0, import_node_fs33.existsSync)(path2)) continue;
|
|
12118
|
+
const text7 = (0, import_node_fs33.readFileSync)(path2, "utf8");
|
|
11976
12119
|
if (/network_access\s*=\s*true/.test(text7)) return true;
|
|
11977
12120
|
}
|
|
11978
12121
|
return false;
|
|
@@ -12004,21 +12147,21 @@ function asRecord2(value) {
|
|
|
12004
12147
|
return void 0;
|
|
12005
12148
|
}
|
|
12006
12149
|
function codexLooksAuthenticated() {
|
|
12007
|
-
const authPath = (0,
|
|
12008
|
-
if (!(0,
|
|
12150
|
+
const authPath = (0, import_node_path34.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
|
|
12151
|
+
if (!(0, import_node_fs33.existsSync)(authPath)) return false;
|
|
12009
12152
|
try {
|
|
12010
|
-
return (0,
|
|
12153
|
+
return (0, import_node_fs33.statSync)(authPath).size > 2;
|
|
12011
12154
|
} catch {
|
|
12012
12155
|
return false;
|
|
12013
12156
|
}
|
|
12014
12157
|
}
|
|
12015
|
-
var
|
|
12158
|
+
var import_node_fs33, import_node_os12, import_node_path34, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
12016
12159
|
var init_codex = __esm({
|
|
12017
12160
|
"src/agents/codex.ts"() {
|
|
12018
12161
|
"use strict";
|
|
12019
|
-
|
|
12162
|
+
import_node_fs33 = require("fs");
|
|
12020
12163
|
import_node_os12 = require("os");
|
|
12021
|
-
|
|
12164
|
+
import_node_path34 = require("path");
|
|
12022
12165
|
init_run();
|
|
12023
12166
|
init_app_settings();
|
|
12024
12167
|
init_global_workspace();
|
|
@@ -12044,7 +12187,7 @@ var init_codex = __esm({
|
|
|
12044
12187
|
async detect() {
|
|
12045
12188
|
const codex = resolveAgentExecutable("codex");
|
|
12046
12189
|
if (codex !== "codex") {
|
|
12047
|
-
if (!(0,
|
|
12190
|
+
if (!(0, import_node_fs33.existsSync)(codex)) {
|
|
12048
12191
|
return {
|
|
12049
12192
|
agent: "codex",
|
|
12050
12193
|
installed: false,
|
|
@@ -12539,21 +12682,21 @@ function platformRipgrepPackage() {
|
|
|
12539
12682
|
}
|
|
12540
12683
|
function usableRipgrepPath(candidate) {
|
|
12541
12684
|
const raw = candidate?.trim();
|
|
12542
|
-
if (!raw || !(0,
|
|
12685
|
+
if (!raw || !(0, import_node_path35.isAbsolute)(raw)) return null;
|
|
12543
12686
|
const readable = nodeReadableScriptPath(raw);
|
|
12544
|
-
if (!(0,
|
|
12687
|
+
if (!(0, import_node_fs34.existsSync)(readable) || isAsarPath(readable)) return null;
|
|
12545
12688
|
return readable;
|
|
12546
12689
|
}
|
|
12547
12690
|
function walkForBundledRipgrep(startFile) {
|
|
12548
12691
|
if (!startFile) return null;
|
|
12549
12692
|
const pkg = platformRipgrepPackage();
|
|
12550
12693
|
const name = rgBinaryName();
|
|
12551
|
-
let dir = (0,
|
|
12552
|
-
const root = (0,
|
|
12694
|
+
let dir = (0, import_node_path35.dirname)((0, import_node_path35.resolve)(startFile));
|
|
12695
|
+
const root = (0, import_node_path35.parse)(dir).root;
|
|
12553
12696
|
while (dir !== root) {
|
|
12554
|
-
const hit = usableRipgrepPath((0,
|
|
12697
|
+
const hit = usableRipgrepPath((0, import_node_path35.join)(dir, "node_modules", pkg, "bin", name));
|
|
12555
12698
|
if (hit) return hit;
|
|
12556
|
-
const next = (0,
|
|
12699
|
+
const next = (0, import_node_path35.dirname)(dir);
|
|
12557
12700
|
if (next === dir) break;
|
|
12558
12701
|
dir = next;
|
|
12559
12702
|
}
|
|
@@ -12563,7 +12706,7 @@ function requireResolveBundledRipgrep(fromFile) {
|
|
|
12563
12706
|
try {
|
|
12564
12707
|
const req = (0, import_node_module2.createRequire)(fromFile);
|
|
12565
12708
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
12566
|
-
return usableRipgrepPath((0,
|
|
12709
|
+
return usableRipgrepPath((0, import_node_path35.join)((0, import_node_path35.dirname)(pkgJson), "bin", rgBinaryName()));
|
|
12567
12710
|
} catch {
|
|
12568
12711
|
return null;
|
|
12569
12712
|
}
|
|
@@ -12585,13 +12728,13 @@ function cursorRipgrepEnv(opts) {
|
|
|
12585
12728
|
const path2 = resolveCursorRipgrepPath(opts);
|
|
12586
12729
|
return path2 ? { [RIPGREP_ENV]: path2 } : {};
|
|
12587
12730
|
}
|
|
12588
|
-
var
|
|
12731
|
+
var import_node_fs34, import_node_module2, import_node_path35, RIPGREP_ENV;
|
|
12589
12732
|
var init_cursor_ripgrep = __esm({
|
|
12590
12733
|
"src/agents/cursor-ripgrep.ts"() {
|
|
12591
12734
|
"use strict";
|
|
12592
|
-
|
|
12735
|
+
import_node_fs34 = require("fs");
|
|
12593
12736
|
import_node_module2 = require("module");
|
|
12594
|
-
|
|
12737
|
+
import_node_path35 = require("path");
|
|
12595
12738
|
init_node_launch();
|
|
12596
12739
|
init_packaged_runtime();
|
|
12597
12740
|
RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
@@ -12604,6 +12747,9 @@ function resolveCursorApiKey() {
|
|
|
12604
12747
|
if (fromEnv) return fromEnv;
|
|
12605
12748
|
return (loadAppSettings().environment.CURSOR_API_KEY || "").trim();
|
|
12606
12749
|
}
|
|
12750
|
+
function isCursorApiKeyConfigured() {
|
|
12751
|
+
return Boolean(resolveCursorApiKey());
|
|
12752
|
+
}
|
|
12607
12753
|
function isCursorAutoModel(model) {
|
|
12608
12754
|
const id = (model ?? "").trim().toLowerCase();
|
|
12609
12755
|
return !id || id === "default" || id === "auto";
|
|
@@ -12637,11 +12783,11 @@ function entryDir() {
|
|
|
12637
12783
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
12638
12784
|
if (cjsDir) return cjsDir;
|
|
12639
12785
|
try {
|
|
12640
|
-
return (0,
|
|
12786
|
+
return (0, import_node_path36.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
12641
12787
|
} catch {
|
|
12642
12788
|
try {
|
|
12643
12789
|
const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
|
|
12644
|
-
return (0,
|
|
12790
|
+
return (0, import_node_path36.dirname)(req.resolve("@sideboard-ai/core"));
|
|
12645
12791
|
} catch {
|
|
12646
12792
|
return process.cwd();
|
|
12647
12793
|
}
|
|
@@ -12652,27 +12798,27 @@ function cursorRunnerPath() {
|
|
|
12652
12798
|
if (packaged) return packaged;
|
|
12653
12799
|
const root = entryDir();
|
|
12654
12800
|
const candidates = [
|
|
12655
|
-
(0,
|
|
12656
|
-
(0,
|
|
12801
|
+
(0, import_node_path36.join)(root, "agents", "cursor-runner.js"),
|
|
12802
|
+
(0, import_node_path36.join)(root, "agents", "cursor-runner.cjs"),
|
|
12657
12803
|
// If somehow resolved from package root instead of dist/
|
|
12658
|
-
(0,
|
|
12659
|
-
(0,
|
|
12804
|
+
(0, import_node_path36.join)(root, "dist", "agents", "cursor-runner.js"),
|
|
12805
|
+
(0, import_node_path36.join)(root, "dist", "agents", "cursor-runner.cjs"),
|
|
12660
12806
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
12661
|
-
(0,
|
|
12662
|
-
(0,
|
|
12807
|
+
(0, import_node_path36.join)(root, "cursor-runner.ts"),
|
|
12808
|
+
(0, import_node_path36.join)(root, "src", "agents", "cursor-runner.ts")
|
|
12663
12809
|
];
|
|
12664
12810
|
for (const candidate of candidates) {
|
|
12665
|
-
if ((0,
|
|
12811
|
+
if ((0, import_node_fs35.existsSync)(candidate)) return candidate;
|
|
12666
12812
|
}
|
|
12667
12813
|
return candidates[0];
|
|
12668
12814
|
}
|
|
12669
|
-
var
|
|
12815
|
+
var import_node_fs35, import_node_module3, import_node_path36, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
|
|
12670
12816
|
var init_cursor = __esm({
|
|
12671
12817
|
"src/agents/cursor.ts"() {
|
|
12672
12818
|
"use strict";
|
|
12673
|
-
|
|
12819
|
+
import_node_fs35 = require("fs");
|
|
12674
12820
|
import_node_module3 = require("module");
|
|
12675
|
-
|
|
12821
|
+
import_node_path36 = require("path");
|
|
12676
12822
|
import_node_url2 = require("url");
|
|
12677
12823
|
import_sdk = require("@cursor/sdk");
|
|
12678
12824
|
init_run();
|
|
@@ -12824,7 +12970,7 @@ async function listOpencodeModels() {
|
|
|
12824
12970
|
if (opencode === "opencode") {
|
|
12825
12971
|
const which = await run("which", ["opencode"], { reject: false });
|
|
12826
12972
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
12827
|
-
} else if (!(0,
|
|
12973
|
+
} else if (!(0, import_node_fs36.existsSync)(opencode)) {
|
|
12828
12974
|
return FALLBACK_OPENCODE_MODELS;
|
|
12829
12975
|
}
|
|
12830
12976
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -12854,11 +13000,11 @@ function usageFromOpencode(tokens) {
|
|
|
12854
13000
|
cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
|
|
12855
13001
|
};
|
|
12856
13002
|
}
|
|
12857
|
-
var
|
|
13003
|
+
var import_node_fs36, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
|
|
12858
13004
|
var init_opencode = __esm({
|
|
12859
13005
|
"src/agents/opencode.ts"() {
|
|
12860
13006
|
"use strict";
|
|
12861
|
-
|
|
13007
|
+
import_node_fs36 = require("fs");
|
|
12862
13008
|
init_run();
|
|
12863
13009
|
init_app_settings();
|
|
12864
13010
|
init_global_workspace();
|
|
@@ -12886,7 +13032,7 @@ var init_opencode = __esm({
|
|
|
12886
13032
|
async detect() {
|
|
12887
13033
|
const opencode = resolveAgentExecutable("opencode");
|
|
12888
13034
|
if (opencode !== "opencode") {
|
|
12889
|
-
if (!(0,
|
|
13035
|
+
if (!(0, import_node_fs36.existsSync)(opencode)) {
|
|
12890
13036
|
return {
|
|
12891
13037
|
agent: "opencode",
|
|
12892
13038
|
installed: false,
|
|
@@ -13627,6 +13773,7 @@ __export(agents_exports, {
|
|
|
13627
13773
|
installAgent: () => installAgent,
|
|
13628
13774
|
installNpmGlobalPackage: () => installNpmGlobalPackage,
|
|
13629
13775
|
isConductorBundledCli: () => isConductorBundledCli,
|
|
13776
|
+
isCursorApiKeyConfigured: () => isCursorApiKeyConfigured,
|
|
13630
13777
|
isCursorAutoModel: () => isCursorAutoModel,
|
|
13631
13778
|
isOrchestratorCapableAgent: () => isOrchestratorCapableAgent,
|
|
13632
13779
|
isSessionQuotaLimit: () => isSessionQuotaLimit,
|
|
@@ -13695,15 +13842,15 @@ var init_agents = __esm({
|
|
|
13695
13842
|
|
|
13696
13843
|
// src/hook/worktree-pkg-cache.ts
|
|
13697
13844
|
function worktreePkgCacheRoot(worktreePath) {
|
|
13698
|
-
return (0,
|
|
13845
|
+
return (0, import_node_path37.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
|
|
13699
13846
|
}
|
|
13700
13847
|
function worktreePkgCacheEnv(worktreePath) {
|
|
13701
13848
|
const root = worktreePkgCacheRoot(worktreePath);
|
|
13702
|
-
const store = (0,
|
|
13703
|
-
const pnpmCache = (0,
|
|
13704
|
-
const npmCache = (0,
|
|
13705
|
-
const nodeGyp = (0,
|
|
13706
|
-
const electron = (0,
|
|
13849
|
+
const store = (0, import_node_path37.join)(root, "pnpm-store");
|
|
13850
|
+
const pnpmCache = (0, import_node_path37.join)(root, "pnpm");
|
|
13851
|
+
const npmCache = (0, import_node_path37.join)(root, "npm");
|
|
13852
|
+
const nodeGyp = (0, import_node_path37.join)(root, "node-gyp");
|
|
13853
|
+
const electron = (0, import_node_path37.join)(root, "electron");
|
|
13707
13854
|
return {
|
|
13708
13855
|
npm_config_store_dir: store,
|
|
13709
13856
|
PNPM_STORE_DIR: store,
|
|
@@ -13725,8 +13872,8 @@ function fillGroup(env, keys, values) {
|
|
|
13725
13872
|
}
|
|
13726
13873
|
}
|
|
13727
13874
|
function ensureWorktreePkgCacheDirs(worktreePath) {
|
|
13728
|
-
if (!(0,
|
|
13729
|
-
(0,
|
|
13875
|
+
if (!(0, import_node_fs37.existsSync)(worktreePath)) return;
|
|
13876
|
+
(0, import_node_fs37.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
|
|
13730
13877
|
}
|
|
13731
13878
|
function applyWorktreePkgCacheEnv(env, worktreePath) {
|
|
13732
13879
|
const cwd = worktreePath.trim();
|
|
@@ -13739,12 +13886,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
|
|
|
13739
13886
|
fillGroup(env, ["electron_config_cache"], next);
|
|
13740
13887
|
ensureWorktreePkgCacheDirs(cwd);
|
|
13741
13888
|
}
|
|
13742
|
-
var
|
|
13889
|
+
var import_node_fs37, import_node_path37, WORKTREE_PKG_CACHE_REL;
|
|
13743
13890
|
var init_worktree_pkg_cache = __esm({
|
|
13744
13891
|
"src/hook/worktree-pkg-cache.ts"() {
|
|
13745
13892
|
"use strict";
|
|
13746
|
-
|
|
13747
|
-
|
|
13893
|
+
import_node_fs37 = require("fs");
|
|
13894
|
+
import_node_path37 = require("path");
|
|
13748
13895
|
WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
|
|
13749
13896
|
}
|
|
13750
13897
|
});
|
|
@@ -14065,6 +14212,8 @@ function agentGitPrompt(action, opts) {
|
|
|
14065
14212
|
const named = base ? ` (${base})` : "";
|
|
14066
14213
|
return `Merge the remote branch${named} into your branch and resolve conflicts. Then, commit and push your changes.`;
|
|
14067
14214
|
}
|
|
14215
|
+
case "ready-for-review":
|
|
14216
|
+
return "Ready for review.";
|
|
14068
14217
|
case "merge":
|
|
14069
14218
|
return "Merge PR.";
|
|
14070
14219
|
}
|
|
@@ -14079,6 +14228,8 @@ function gitActionExpansion(action, base) {
|
|
|
14079
14228
|
return "Commit, push, then `gh pr create --web -R <origin-owner/name>`.";
|
|
14080
14229
|
case "resolve-conflicts":
|
|
14081
14230
|
return `Fetch the PR base${base ? ` (\`${base}\`)` : ""}, merge it into this branch, resolve conflicts carefully, then commit and push until the PR is mergeable.`;
|
|
14231
|
+
case "ready-for-review":
|
|
14232
|
+
return "This phrase is the explicit ask to mark this thread's draft pull request ready for review on GitHub (`gh pr ready -R <origin-owner/name>` or `gh pr ready`). Update title/body if the purpose drifted. Do not merge.";
|
|
14082
14233
|
case "merge":
|
|
14083
14234
|
return "This phrase is the explicit ask to merge this thread's open pull request on GitHub. If `gh stack view` shows a stack, use `gh stack merge`; otherwise `gh pr merge` (respect repo defaults / squash vs merge). Do not force-push main/master or merge locally into the main checkout.";
|
|
14084
14235
|
}
|
|
@@ -14121,6 +14272,7 @@ var init_agent_git_actions = __esm({
|
|
|
14121
14272
|
"create-draft",
|
|
14122
14273
|
"create-web",
|
|
14123
14274
|
"resolve-conflicts",
|
|
14275
|
+
"ready-for-review",
|
|
14124
14276
|
"merge"
|
|
14125
14277
|
];
|
|
14126
14278
|
RESOLVE_CONFLICTS_RE = /^Merge the remote branch(?: \(([^)]+)\))? into your branch and resolve conflicts\. Then, commit and push your changes\.$/;
|
|
@@ -14892,21 +15044,21 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
14892
15044
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
14893
15045
|
}
|
|
14894
15046
|
function readTextIfPresent(abs) {
|
|
14895
|
-
if (!(0,
|
|
15047
|
+
if (!(0, import_node_fs38.existsSync)(abs)) return null;
|
|
14896
15048
|
try {
|
|
14897
|
-
const content = (0,
|
|
15049
|
+
const content = (0, import_node_fs38.readFileSync)(abs, "utf8");
|
|
14898
15050
|
return content.trim() ? content : null;
|
|
14899
15051
|
} catch {
|
|
14900
15052
|
return null;
|
|
14901
15053
|
}
|
|
14902
15054
|
}
|
|
14903
15055
|
function readLocalGuidelines(worktreePath) {
|
|
14904
|
-
const localAbs = (0,
|
|
15056
|
+
const localAbs = (0, import_node_path38.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
14905
15057
|
const localContent = readTextIfPresent(localAbs);
|
|
14906
15058
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
14907
15059
|
return { path: REVIEW_REQUEST_PATH, content: localContent };
|
|
14908
15060
|
}
|
|
14909
|
-
const legacyAbs = (0,
|
|
15061
|
+
const legacyAbs = (0, import_node_path38.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
14910
15062
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
14911
15063
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
14912
15064
|
return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
|
|
@@ -14930,27 +15082,27 @@ function contextGuidelines(content, source) {
|
|
|
14930
15082
|
};
|
|
14931
15083
|
}
|
|
14932
15084
|
function writeContextGuidelines(worktreePath, content) {
|
|
14933
|
-
const abs = (0,
|
|
14934
|
-
(0,
|
|
15085
|
+
const abs = (0, import_node_path38.join)(worktreePath, CONTEXT_REVIEW_PATH);
|
|
15086
|
+
(0, import_node_fs38.mkdirSync)((0, import_node_path38.dirname)(abs), { recursive: true });
|
|
14935
15087
|
const body = content.endsWith("\n") ? content : `${content}
|
|
14936
15088
|
`;
|
|
14937
|
-
(0,
|
|
15089
|
+
(0, import_node_fs38.writeFileSync)(abs, body, "utf8");
|
|
14938
15090
|
return body;
|
|
14939
15091
|
}
|
|
14940
15092
|
function readSideboardReview(worktreePath, repoPath) {
|
|
14941
|
-
const fromWorktree = readTextIfPresent((0,
|
|
15093
|
+
const fromWorktree = readTextIfPresent((0, import_node_path38.join)(worktreePath, REPO_REVIEW_PATH));
|
|
14942
15094
|
if (fromWorktree) return fromWorktree;
|
|
14943
15095
|
const repo = repoPath?.replace(/\/+$/, "");
|
|
14944
15096
|
const wt = worktreePath.replace(/\/+$/, "");
|
|
14945
15097
|
if (!repo || repo === wt) return null;
|
|
14946
|
-
return readTextIfPresent((0,
|
|
15098
|
+
return readTextIfPresent((0, import_node_path38.join)(repo, REPO_REVIEW_PATH));
|
|
14947
15099
|
}
|
|
14948
15100
|
function ensureReviewGuidelinesFile(worktreePath, repoPath) {
|
|
14949
|
-
const skillContent = readTextIfPresent((0,
|
|
15101
|
+
const skillContent = readTextIfPresent((0, import_node_path38.join)(worktreePath, REVIEW_SKILL_PATH));
|
|
14950
15102
|
if (skillContent) {
|
|
14951
15103
|
return { ...skillGuidelines(skillContent, "skill"), wrote: false };
|
|
14952
15104
|
}
|
|
14953
|
-
const contextContent = readTextIfPresent((0,
|
|
15105
|
+
const contextContent = readTextIfPresent((0, import_node_path38.join)(worktreePath, CONTEXT_REVIEW_PATH));
|
|
14954
15106
|
if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
|
|
14955
15107
|
return { ...contextGuidelines(contextContent, "local"), wrote: false };
|
|
14956
15108
|
}
|
|
@@ -14988,7 +15140,7 @@ function buildReviewRequestAttachment(content, opts) {
|
|
|
14988
15140
|
};
|
|
14989
15141
|
}
|
|
14990
15142
|
function readExistingReviewRequestFile(worktreePath) {
|
|
14991
|
-
return readTextIfPresent((0,
|
|
15143
|
+
return readTextIfPresent((0, import_node_path38.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path38.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path38.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path38.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path38.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
14992
15144
|
}
|
|
14993
15145
|
async function requestReview(threadRef, send2) {
|
|
14994
15146
|
const from = findThreadByRef(threadRef);
|
|
@@ -15015,13 +15167,13 @@ async function requestReview(threadRef, send2) {
|
|
|
15015
15167
|
const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
|
|
15016
15168
|
return { tab: started, from };
|
|
15017
15169
|
}
|
|
15018
|
-
var import_node_crypto8,
|
|
15170
|
+
var import_node_crypto8, import_node_fs38, import_node_path38, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
|
|
15019
15171
|
var init_request_review = __esm({
|
|
15020
15172
|
"src/review/request-review.ts"() {
|
|
15021
15173
|
"use strict";
|
|
15022
15174
|
import_node_crypto8 = require("crypto");
|
|
15023
|
-
|
|
15024
|
-
|
|
15175
|
+
import_node_fs38 = require("fs");
|
|
15176
|
+
import_node_path38 = require("path");
|
|
15025
15177
|
init_global_workspace();
|
|
15026
15178
|
init_chat_tabs();
|
|
15027
15179
|
init_thread_store();
|
|
@@ -15047,9 +15199,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
15047
15199
|
return new RegExp(`^${escaped}$`).test(name);
|
|
15048
15200
|
}
|
|
15049
15201
|
function readWorktreeInclude(repoPath) {
|
|
15050
|
-
const path2 = (0,
|
|
15051
|
-
if (!(0,
|
|
15052
|
-
return (0,
|
|
15202
|
+
const path2 = (0, import_node_path39.join)(repoPath, ".worktreeinclude");
|
|
15203
|
+
if (!(0, import_node_fs39.existsSync)(path2)) return [];
|
|
15204
|
+
return (0, import_node_fs39.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
15053
15205
|
}
|
|
15054
15206
|
function resolveFilesToCopy(repoPath) {
|
|
15055
15207
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -15059,10 +15211,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
15059
15211
|
if (settings?.fileIncludeGlobs?.length) {
|
|
15060
15212
|
const matched = [];
|
|
15061
15213
|
try {
|
|
15062
|
-
for (const entry of (0,
|
|
15214
|
+
for (const entry of (0, import_node_fs39.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
15063
15215
|
if (!entry.isFile()) continue;
|
|
15064
15216
|
for (const glob of settings.fileIncludeGlobs) {
|
|
15065
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
15217
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path39.basename)(glob), entry.name)) {
|
|
15066
15218
|
matched.push(entry.name);
|
|
15067
15219
|
break;
|
|
15068
15220
|
}
|
|
@@ -15074,7 +15226,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
15074
15226
|
}
|
|
15075
15227
|
const defaults = [];
|
|
15076
15228
|
try {
|
|
15077
|
-
for (const entry of (0,
|
|
15229
|
+
for (const entry of (0, import_node_fs39.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
15078
15230
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
15079
15231
|
defaults.push(entry.name);
|
|
15080
15232
|
}
|
|
@@ -15088,11 +15240,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
15088
15240
|
const patterns = resolveFilesToCopy(repoPath);
|
|
15089
15241
|
const copied = [];
|
|
15090
15242
|
for (const rel of patterns) {
|
|
15091
|
-
const src = (0,
|
|
15092
|
-
if (!(0,
|
|
15093
|
-
const dest = (0,
|
|
15094
|
-
(0,
|
|
15095
|
-
(0,
|
|
15243
|
+
const src = (0, import_node_path39.join)(repoPath, rel);
|
|
15244
|
+
if (!(0, import_node_fs39.existsSync)(src)) continue;
|
|
15245
|
+
const dest = (0, import_node_path39.join)(worktreePath, rel);
|
|
15246
|
+
(0, import_node_fs39.mkdirSync)((0, import_node_path39.dirname)(dest), { recursive: true });
|
|
15247
|
+
(0, import_node_fs39.copyFileSync)(src, dest);
|
|
15096
15248
|
copied.push(rel);
|
|
15097
15249
|
}
|
|
15098
15250
|
return copied;
|
|
@@ -15127,7 +15279,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
15127
15279
|
const env = stripNestedElectronEnv({
|
|
15128
15280
|
...baseEnv ?? process.env
|
|
15129
15281
|
});
|
|
15130
|
-
const name = opts.workspaceName ?? (0,
|
|
15282
|
+
const name = opts.workspaceName ?? (0, import_node_path39.basename)(opts.worktreePath);
|
|
15131
15283
|
const ports = opts.ports ?? [];
|
|
15132
15284
|
const primary = ports[0];
|
|
15133
15285
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -15390,13 +15542,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
15390
15542
|
done: handle.done
|
|
15391
15543
|
};
|
|
15392
15544
|
}
|
|
15393
|
-
var
|
|
15545
|
+
var import_node_fs39, import_node_net, import_node_path39, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
15394
15546
|
var init_conductor = __esm({
|
|
15395
15547
|
"src/hook/conductor.ts"() {
|
|
15396
15548
|
"use strict";
|
|
15397
|
-
|
|
15549
|
+
import_node_fs39 = require("fs");
|
|
15398
15550
|
import_node_net = require("net");
|
|
15399
|
-
|
|
15551
|
+
import_node_path39 = require("path");
|
|
15400
15552
|
import_execa4 = require("execa");
|
|
15401
15553
|
import_node_readline3 = require("readline");
|
|
15402
15554
|
init_settings();
|
|
@@ -15424,9 +15576,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
15424
15576
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
15425
15577
|
);
|
|
15426
15578
|
const homeRoot = sideboardWorkspacesDir();
|
|
15427
|
-
if ((0,
|
|
15579
|
+
if ((0, import_node_fs40.existsSync)(homeRoot)) {
|
|
15428
15580
|
try {
|
|
15429
|
-
for (const entry of (0,
|
|
15581
|
+
for (const entry of (0, import_node_fs40.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
15430
15582
|
if (!entry.isDirectory()) continue;
|
|
15431
15583
|
void entry;
|
|
15432
15584
|
}
|
|
@@ -15436,7 +15588,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
15436
15588
|
const orphans = [];
|
|
15437
15589
|
const seen = /* @__PURE__ */ new Set();
|
|
15438
15590
|
for (const repoPath of repos) {
|
|
15439
|
-
if (!repoPath || !(0,
|
|
15591
|
+
if (!repoPath || !(0, import_node_fs40.existsSync)(repoPath)) continue;
|
|
15440
15592
|
try {
|
|
15441
15593
|
const wts = await listWorktrees(repoPath);
|
|
15442
15594
|
for (const wt of wts) {
|
|
@@ -15447,7 +15599,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
15447
15599
|
seen.add(path2);
|
|
15448
15600
|
let mtimeMs = 0;
|
|
15449
15601
|
try {
|
|
15450
|
-
mtimeMs = (0,
|
|
15602
|
+
mtimeMs = (0, import_node_fs40.statSync)(path2).mtimeMs;
|
|
15451
15603
|
} catch {
|
|
15452
15604
|
mtimeMs = 0;
|
|
15453
15605
|
}
|
|
@@ -15457,16 +15609,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
15457
15609
|
}
|
|
15458
15610
|
try {
|
|
15459
15611
|
const root = worktreesRoot(repoPath);
|
|
15460
|
-
if ((0,
|
|
15461
|
-
for (const entry of (0,
|
|
15612
|
+
if ((0, import_node_fs40.existsSync)(root)) {
|
|
15613
|
+
for (const entry of (0, import_node_fs40.readdirSync)(root, { withFileTypes: true })) {
|
|
15462
15614
|
if (!entry.isDirectory()) continue;
|
|
15463
|
-
const path2 = (0,
|
|
15615
|
+
const path2 = (0, import_node_path40.join)(root, entry.name).replace(/\/$/, "");
|
|
15464
15616
|
if (known.has(path2) || seen.has(path2)) continue;
|
|
15465
|
-
if (!(0,
|
|
15617
|
+
if (!(0, import_node_fs40.existsSync)((0, import_node_path40.join)(path2, ".git"))) continue;
|
|
15466
15618
|
seen.add(path2);
|
|
15467
15619
|
let mtimeMs = 0;
|
|
15468
15620
|
try {
|
|
15469
|
-
mtimeMs = (0,
|
|
15621
|
+
mtimeMs = (0, import_node_fs40.statSync)(path2).mtimeMs;
|
|
15470
15622
|
} catch {
|
|
15471
15623
|
mtimeMs = Date.now();
|
|
15472
15624
|
}
|
|
@@ -15527,12 +15679,12 @@ function worktreeCleanupSettings() {
|
|
|
15527
15679
|
autoCleanupOrphans: a.autoCleanupOrphans
|
|
15528
15680
|
};
|
|
15529
15681
|
}
|
|
15530
|
-
var
|
|
15682
|
+
var import_node_fs40, import_node_path40;
|
|
15531
15683
|
var init_orphan_cleanup = __esm({
|
|
15532
15684
|
"src/git/orphan-cleanup.ts"() {
|
|
15533
15685
|
"use strict";
|
|
15534
|
-
|
|
15535
|
-
|
|
15686
|
+
import_node_fs40 = require("fs");
|
|
15687
|
+
import_node_path40 = require("path");
|
|
15536
15688
|
init_worktree();
|
|
15537
15689
|
init_thread_store();
|
|
15538
15690
|
init_paths();
|
|
@@ -15635,12 +15787,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
15635
15787
|
if (!url) throw new Error("Clone URL is required");
|
|
15636
15788
|
let name = opts.name?.trim();
|
|
15637
15789
|
if (!name) {
|
|
15638
|
-
const leaf = (0,
|
|
15790
|
+
const leaf = (0, import_node_path41.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
15639
15791
|
name = leaf || "repo";
|
|
15640
15792
|
}
|
|
15641
15793
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
15642
|
-
const dest = (0,
|
|
15643
|
-
if ((0,
|
|
15794
|
+
const dest = (0, import_node_path41.join)(sideboardReposDir(), name);
|
|
15795
|
+
if ((0, import_node_fs41.existsSync)(dest)) {
|
|
15644
15796
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
15645
15797
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
15646
15798
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -15655,12 +15807,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
15655
15807
|
const workspace = await ensureWorkspace(repoPath);
|
|
15656
15808
|
return { repoPath, workspace };
|
|
15657
15809
|
}
|
|
15658
|
-
var
|
|
15810
|
+
var import_node_fs41, import_node_path41, import_execa6;
|
|
15659
15811
|
var init_clone_repo = __esm({
|
|
15660
15812
|
"src/git/clone-repo.ts"() {
|
|
15661
15813
|
"use strict";
|
|
15662
|
-
|
|
15663
|
-
|
|
15814
|
+
import_node_fs41 = require("fs");
|
|
15815
|
+
import_node_path41 = require("path");
|
|
15664
15816
|
import_execa6 = require("execa");
|
|
15665
15817
|
init_paths();
|
|
15666
15818
|
init_workspaces();
|
|
@@ -15778,24 +15930,24 @@ function jobTreeAlive(pid) {
|
|
|
15778
15930
|
return jobAlive(pid) || processGroupAlive(pid);
|
|
15779
15931
|
}
|
|
15780
15932
|
function readIntFile(file) {
|
|
15781
|
-
if (!(0,
|
|
15782
|
-
const n = Number.parseInt((0,
|
|
15933
|
+
if (!(0, import_node_fs42.existsSync)(file)) return null;
|
|
15934
|
+
const n = Number.parseInt((0, import_node_fs42.readFileSync)(file, "utf8").trim(), 10);
|
|
15783
15935
|
return Number.isInteger(n) ? n : null;
|
|
15784
15936
|
}
|
|
15785
15937
|
function jobDir(root, id, legacy = false) {
|
|
15786
|
-
return (0,
|
|
15938
|
+
return (0, import_node_path42.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
|
|
15787
15939
|
}
|
|
15788
15940
|
function resolveJobDir(root, id) {
|
|
15789
15941
|
const modern = jobDir(root, id, false);
|
|
15790
|
-
if ((0,
|
|
15942
|
+
if ((0, import_node_fs42.existsSync)(modern)) return modern;
|
|
15791
15943
|
const legacy = jobDir(root, id, true);
|
|
15792
|
-
if ((0,
|
|
15944
|
+
if ((0, import_node_fs42.existsSync)(legacy)) return legacy;
|
|
15793
15945
|
return modern;
|
|
15794
15946
|
}
|
|
15795
15947
|
function listJobIdsIn(root, rel) {
|
|
15796
|
-
const dir = (0,
|
|
15797
|
-
if (!(0,
|
|
15798
|
-
return (0,
|
|
15948
|
+
const dir = (0, import_node_path42.join)(root, rel);
|
|
15949
|
+
if (!(0, import_node_fs42.existsSync)(dir)) return [];
|
|
15950
|
+
return (0, import_node_fs42.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
|
|
15799
15951
|
}
|
|
15800
15952
|
function listRunningDetachedJobs(worktreePath) {
|
|
15801
15953
|
const root = worktreePath.trim();
|
|
@@ -15807,7 +15959,7 @@ function listRunningDetachedJobs(worktreePath) {
|
|
|
15807
15959
|
const running = [];
|
|
15808
15960
|
for (const id of ids) {
|
|
15809
15961
|
const dir = resolveJobDir(root, id);
|
|
15810
|
-
const pid = readIntFile((0,
|
|
15962
|
+
const pid = readIntFile((0, import_node_path42.join)(dir, "pid"));
|
|
15811
15963
|
if (jobTreeAlive(pid)) running.push(id);
|
|
15812
15964
|
}
|
|
15813
15965
|
return running.sort();
|
|
@@ -15860,13 +16012,13 @@ function planJobContinue(opts) {
|
|
|
15860
16012
|
return { action: "none" };
|
|
15861
16013
|
}
|
|
15862
16014
|
function tailProgress(logFile, maxLines = 12) {
|
|
15863
|
-
if (!(0,
|
|
15864
|
-
const lines = (0,
|
|
16015
|
+
if (!(0, import_node_fs42.existsSync)(logFile)) return "(no log yet)";
|
|
16016
|
+
const lines = (0, import_node_fs42.readFileSync)(logFile, "utf8").split("\n");
|
|
15865
16017
|
return lines.slice(-maxLines).join("\n");
|
|
15866
16018
|
}
|
|
15867
16019
|
function readLogLines(file) {
|
|
15868
|
-
if (!(0,
|
|
15869
|
-
const lines = (0,
|
|
16020
|
+
if (!(0, import_node_fs42.existsSync)(file)) return [];
|
|
16021
|
+
const lines = (0, import_node_fs42.readFileSync)(file, "utf8").split("\n");
|
|
15870
16022
|
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
15871
16023
|
return lines;
|
|
15872
16024
|
}
|
|
@@ -15877,15 +16029,15 @@ function takeDelta(logFile, cursorFile) {
|
|
|
15877
16029
|
return { delta: lines.slice(start).join("\n"), nextCursor: lines.length };
|
|
15878
16030
|
}
|
|
15879
16031
|
function snapshotJob(dir) {
|
|
15880
|
-
const pid = readIntFile((0,
|
|
16032
|
+
const pid = readIntFile((0, import_node_path42.join)(dir, "pid"));
|
|
15881
16033
|
const running = jobTreeAlive(pid);
|
|
15882
16034
|
return {
|
|
15883
16035
|
pid,
|
|
15884
16036
|
running,
|
|
15885
|
-
exitCode: readIntFile((0,
|
|
15886
|
-
log: (0,
|
|
15887
|
-
cursor: (0,
|
|
15888
|
-
progress: tailProgress((0,
|
|
16037
|
+
exitCode: readIntFile((0, import_node_path42.join)(dir, "exit")),
|
|
16038
|
+
log: (0, import_node_path42.join)(dir, "log"),
|
|
16039
|
+
cursor: (0, import_node_path42.join)(dir, "present.cursor"),
|
|
16040
|
+
progress: tailProgress((0, import_node_path42.join)(dir, "log"))
|
|
15889
16041
|
};
|
|
15890
16042
|
}
|
|
15891
16043
|
function toResult(id, snap, extra) {
|
|
@@ -15894,8 +16046,8 @@ function toResult(id, snap, extra) {
|
|
|
15894
16046
|
const stillRunning = snap.running && !ok;
|
|
15895
16047
|
const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
|
|
15896
16048
|
try {
|
|
15897
|
-
(0,
|
|
15898
|
-
(0,
|
|
16049
|
+
(0, import_node_fs42.mkdirSync)((0, import_node_path42.dirname)(snap.cursor), { recursive: true });
|
|
16050
|
+
(0, import_node_fs42.writeFileSync)(snap.cursor, `${nextCursor}
|
|
15899
16051
|
`);
|
|
15900
16052
|
} catch {
|
|
15901
16053
|
}
|
|
@@ -15922,7 +16074,7 @@ async function waitForDetachedJob(cwd, id, opts) {
|
|
|
15922
16074
|
const dir = resolveJobDir(root, jobId);
|
|
15923
16075
|
const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
|
|
15924
16076
|
const sleep2 = opts?.sleep ?? sleepMs;
|
|
15925
|
-
if (!(0,
|
|
16077
|
+
if (!(0, import_node_fs42.existsSync)(dir)) {
|
|
15926
16078
|
return {
|
|
15927
16079
|
stillRunning: false,
|
|
15928
16080
|
ok: false,
|
|
@@ -15968,10 +16120,10 @@ function killProcessTree(pid, signal) {
|
|
|
15968
16120
|
}
|
|
15969
16121
|
function appendJobLog(logFile, line) {
|
|
15970
16122
|
try {
|
|
15971
|
-
(0,
|
|
16123
|
+
(0, import_node_fs42.mkdirSync)((0, import_node_path42.dirname)(logFile), { recursive: true });
|
|
15972
16124
|
const body = line.endsWith("\n") ? line : `${line}
|
|
15973
16125
|
`;
|
|
15974
|
-
(0,
|
|
16126
|
+
(0, import_node_fs42.appendFileSync)(logFile, body);
|
|
15975
16127
|
} catch {
|
|
15976
16128
|
}
|
|
15977
16129
|
}
|
|
@@ -15981,7 +16133,7 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
15981
16133
|
const dir = resolveJobDir(root, jobId);
|
|
15982
16134
|
const sleep2 = opts?.sleep ?? sleepMs;
|
|
15983
16135
|
const why = opts?.reason?.trim() ?? "";
|
|
15984
|
-
if (!(0,
|
|
16136
|
+
if (!(0, import_node_fs42.existsSync)(dir)) {
|
|
15985
16137
|
return {
|
|
15986
16138
|
stillRunning: false,
|
|
15987
16139
|
ok: false,
|
|
@@ -16017,10 +16169,10 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
16017
16169
|
killProcessTree(targetPid, "SIGKILL");
|
|
16018
16170
|
await sleep2(100);
|
|
16019
16171
|
}
|
|
16020
|
-
const exitFile = (0,
|
|
16021
|
-
if (!(0,
|
|
16172
|
+
const exitFile = (0, import_node_path42.join)(dir, "exit");
|
|
16173
|
+
if (!(0, import_node_fs42.existsSync)(exitFile)) {
|
|
16022
16174
|
try {
|
|
16023
|
-
(0,
|
|
16175
|
+
(0, import_node_fs42.writeFileSync)(exitFile, "1\n");
|
|
16024
16176
|
} catch {
|
|
16025
16177
|
}
|
|
16026
16178
|
}
|
|
@@ -16040,12 +16192,12 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
16040
16192
|
hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
|
|
16041
16193
|
};
|
|
16042
16194
|
}
|
|
16043
|
-
var
|
|
16195
|
+
var import_node_fs42, import_node_path42, MAX_JOB_CONTINUES, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
|
|
16044
16196
|
var init_wait_for_job = __esm({
|
|
16045
16197
|
"src/mcp/wait-for-job.ts"() {
|
|
16046
16198
|
"use strict";
|
|
16047
|
-
|
|
16048
|
-
|
|
16199
|
+
import_node_fs42 = require("fs");
|
|
16200
|
+
import_node_path42 = require("path");
|
|
16049
16201
|
init_workspace_scratch();
|
|
16050
16202
|
init_wait_for_turn();
|
|
16051
16203
|
MAX_JOB_CONTINUES = 8;
|
|
@@ -17182,7 +17334,7 @@ function reuseLiveThread(input, repoPath, match) {
|
|
|
17182
17334
|
}
|
|
17183
17335
|
async function createThread(input, _onSetupLine) {
|
|
17184
17336
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
17185
|
-
if (!(0,
|
|
17337
|
+
if (!(0, import_node_fs43.existsSync)(repoPath)) {
|
|
17186
17338
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
17187
17339
|
}
|
|
17188
17340
|
const reused = reuseLiveThread(input, repoPath, {
|
|
@@ -17363,11 +17515,11 @@ async function listLinearIssues(agent, repoPath) {
|
|
|
17363
17515
|
}
|
|
17364
17516
|
return adapter.listLinearIssues(repoPath);
|
|
17365
17517
|
}
|
|
17366
|
-
var
|
|
17518
|
+
var import_node_fs43;
|
|
17367
17519
|
var init_create = __esm({
|
|
17368
17520
|
"src/threads/create.ts"() {
|
|
17369
17521
|
"use strict";
|
|
17370
|
-
|
|
17522
|
+
import_node_fs43 = require("fs");
|
|
17371
17523
|
init_detect();
|
|
17372
17524
|
init_worktree();
|
|
17373
17525
|
init_home_board();
|
|
@@ -17487,20 +17639,20 @@ function writeTurnLive(threadId, progress) {
|
|
|
17487
17639
|
const path2 = threadLivePath(threadId);
|
|
17488
17640
|
const tmp = `${path2}.${process.pid}.tmp`;
|
|
17489
17641
|
try {
|
|
17490
|
-
(0,
|
|
17491
|
-
(0,
|
|
17642
|
+
(0, import_node_fs44.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
|
|
17643
|
+
(0, import_node_fs44.renameSync)(tmp, path2);
|
|
17492
17644
|
} catch {
|
|
17493
17645
|
try {
|
|
17494
|
-
(0,
|
|
17646
|
+
(0, import_node_fs44.unlinkSync)(tmp);
|
|
17495
17647
|
} catch {
|
|
17496
17648
|
}
|
|
17497
17649
|
}
|
|
17498
17650
|
}
|
|
17499
17651
|
function readTurnLive(threadId) {
|
|
17500
17652
|
const path2 = threadLivePath(threadId);
|
|
17501
|
-
if (!(0,
|
|
17653
|
+
if (!(0, import_node_fs44.existsSync)(path2)) return null;
|
|
17502
17654
|
try {
|
|
17503
|
-
const raw = JSON.parse((0,
|
|
17655
|
+
const raw = JSON.parse((0, import_node_fs44.readFileSync)(path2, "utf8"));
|
|
17504
17656
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
17505
17657
|
return raw;
|
|
17506
17658
|
} catch {
|
|
@@ -17512,17 +17664,17 @@ function clearTurnLive(threadId) {
|
|
|
17512
17664
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
17513
17665
|
buffers.delete(threadId);
|
|
17514
17666
|
const path2 = threadLivePath(threadId);
|
|
17515
|
-
if (!(0,
|
|
17667
|
+
if (!(0, import_node_fs44.existsSync)(path2)) return;
|
|
17516
17668
|
try {
|
|
17517
|
-
(0,
|
|
17669
|
+
(0, import_node_fs44.unlinkSync)(path2);
|
|
17518
17670
|
} catch {
|
|
17519
17671
|
}
|
|
17520
17672
|
}
|
|
17521
|
-
var
|
|
17673
|
+
var import_node_fs44, buffers, FLUSH_MS, MAX_PARTS;
|
|
17522
17674
|
var init_turn_live = __esm({
|
|
17523
17675
|
"src/store/turn-live.ts"() {
|
|
17524
17676
|
"use strict";
|
|
17525
|
-
|
|
17677
|
+
import_node_fs44 = require("fs");
|
|
17526
17678
|
init_message_parts();
|
|
17527
17679
|
init_paths();
|
|
17528
17680
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -17742,7 +17894,7 @@ var init_quota_failover = __esm({
|
|
|
17742
17894
|
// src/threads/adopt.ts
|
|
17743
17895
|
function thisModuleFile() {
|
|
17744
17896
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
17745
|
-
return cjsFile || process.argv[1] || (0,
|
|
17897
|
+
return cjsFile || process.argv[1] || (0, import_node_path43.join)(process.cwd(), "package.json");
|
|
17746
17898
|
}
|
|
17747
17899
|
function openReadonlySqlite(file) {
|
|
17748
17900
|
const req = (0, import_node_module4.createRequire)(thisModuleFile());
|
|
@@ -17760,21 +17912,21 @@ function mapAgentType(raw) {
|
|
|
17760
17912
|
return null;
|
|
17761
17913
|
}
|
|
17762
17914
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
17763
|
-
if (!workspacePath || !(0,
|
|
17915
|
+
if (!workspacePath || !(0, import_node_fs45.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
17764
17916
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
17765
17917
|
let best = null;
|
|
17766
17918
|
let hashes;
|
|
17767
17919
|
try {
|
|
17768
|
-
hashes = (0,
|
|
17920
|
+
hashes = (0, import_node_fs45.readdirSync)(CURSOR_SDK_STORE);
|
|
17769
17921
|
} catch {
|
|
17770
17922
|
return null;
|
|
17771
17923
|
}
|
|
17772
17924
|
for (const hash of hashes) {
|
|
17773
|
-
const agentsFile = (0,
|
|
17774
|
-
if (!(0,
|
|
17925
|
+
const agentsFile = (0, import_node_path43.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
17926
|
+
if (!(0, import_node_fs45.existsSync)(agentsFile)) continue;
|
|
17775
17927
|
let text7;
|
|
17776
17928
|
try {
|
|
17777
|
-
text7 = (0,
|
|
17929
|
+
text7 = (0, import_node_fs45.readFileSync)(agentsFile, "utf8");
|
|
17778
17930
|
} catch {
|
|
17779
17931
|
continue;
|
|
17780
17932
|
}
|
|
@@ -17798,7 +17950,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
17798
17950
|
return best?.agentId ?? null;
|
|
17799
17951
|
}
|
|
17800
17952
|
async function adoptThread(input) {
|
|
17801
|
-
if (!(0,
|
|
17953
|
+
if (!(0, import_node_fs45.existsSync)(input.worktreePath)) {
|
|
17802
17954
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
17803
17955
|
}
|
|
17804
17956
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -17827,18 +17979,18 @@ function conductorDbPath() {
|
|
|
17827
17979
|
return CONDUCTOR_DB;
|
|
17828
17980
|
}
|
|
17829
17981
|
function listConductorWorkspaces() {
|
|
17830
|
-
if (!(0,
|
|
17982
|
+
if (!(0, import_node_fs45.existsSync)(CONDUCTOR_DB)) {
|
|
17831
17983
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
17832
17984
|
}
|
|
17833
|
-
const tmp = (0,
|
|
17834
|
-
const snapshot = (0,
|
|
17985
|
+
const tmp = (0, import_node_fs45.mkdtempSync)((0, import_node_path43.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
|
|
17986
|
+
const snapshot = (0, import_node_path43.join)(tmp, "conductor.db");
|
|
17835
17987
|
try {
|
|
17836
|
-
(0,
|
|
17988
|
+
(0, import_node_fs45.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
17837
17989
|
for (const suffix of ["-wal", "-shm"]) {
|
|
17838
17990
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
17839
|
-
if ((0,
|
|
17991
|
+
if ((0, import_node_fs45.existsSync)(src)) {
|
|
17840
17992
|
try {
|
|
17841
|
-
(0,
|
|
17993
|
+
(0, import_node_fs45.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
17842
17994
|
} catch {
|
|
17843
17995
|
}
|
|
17844
17996
|
}
|
|
@@ -17914,22 +18066,22 @@ function listConductorWorkspaces() {
|
|
|
17914
18066
|
db.close();
|
|
17915
18067
|
}
|
|
17916
18068
|
} finally {
|
|
17917
|
-
(0,
|
|
18069
|
+
(0, import_node_fs45.rmSync)(tmp, { recursive: true, force: true });
|
|
17918
18070
|
}
|
|
17919
18071
|
}
|
|
17920
18072
|
function importConductorWorkspace(workspaceId) {
|
|
17921
|
-
if (!(0,
|
|
18073
|
+
if (!(0, import_node_fs45.existsSync)(CONDUCTOR_DB)) {
|
|
17922
18074
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
17923
18075
|
}
|
|
17924
|
-
const tmp = (0,
|
|
17925
|
-
const snapshot = (0,
|
|
18076
|
+
const tmp = (0, import_node_fs45.mkdtempSync)((0, import_node_path43.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
|
|
18077
|
+
const snapshot = (0, import_node_path43.join)(tmp, "conductor.db");
|
|
17926
18078
|
try {
|
|
17927
|
-
(0,
|
|
18079
|
+
(0, import_node_fs45.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
17928
18080
|
for (const suffix of ["-wal", "-shm"]) {
|
|
17929
18081
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
17930
|
-
if ((0,
|
|
18082
|
+
if ((0, import_node_fs45.existsSync)(src)) {
|
|
17931
18083
|
try {
|
|
17932
|
-
(0,
|
|
18084
|
+
(0, import_node_fs45.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
17933
18085
|
} catch {
|
|
17934
18086
|
}
|
|
17935
18087
|
}
|
|
@@ -17947,7 +18099,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
17947
18099
|
).get(workspaceId);
|
|
17948
18100
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
17949
18101
|
const worktreePath = String(row.workspacePath);
|
|
17950
|
-
if (!(0,
|
|
18102
|
+
if (!(0, import_node_fs45.existsSync)(worktreePath)) {
|
|
17951
18103
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
17952
18104
|
}
|
|
17953
18105
|
let sessionId = null;
|
|
@@ -17987,7 +18139,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
17987
18139
|
}
|
|
17988
18140
|
let repoPath = worktreePath;
|
|
17989
18141
|
try {
|
|
17990
|
-
repoPath = (0,
|
|
18142
|
+
repoPath = (0, import_node_child_process5.execFileSync)("git", ["rev-parse", "--show-toplevel"], {
|
|
17991
18143
|
cwd: worktreePath,
|
|
17992
18144
|
encoding: "utf8"
|
|
17993
18145
|
}).trim();
|
|
@@ -18010,31 +18162,31 @@ function importConductorWorkspace(workspaceId) {
|
|
|
18010
18162
|
db.close();
|
|
18011
18163
|
}
|
|
18012
18164
|
} finally {
|
|
18013
|
-
(0,
|
|
18165
|
+
(0, import_node_fs45.rmSync)(tmp, { recursive: true, force: true });
|
|
18014
18166
|
}
|
|
18015
18167
|
}
|
|
18016
18168
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
18017
18169
|
return importConductorWorkspace(workspaceId);
|
|
18018
18170
|
}
|
|
18019
|
-
var
|
|
18171
|
+
var import_node_child_process5, import_node_fs45, import_node_os13, import_node_path43, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
|
|
18020
18172
|
var init_adopt = __esm({
|
|
18021
18173
|
"src/threads/adopt.ts"() {
|
|
18022
18174
|
"use strict";
|
|
18023
|
-
|
|
18024
|
-
|
|
18175
|
+
import_node_child_process5 = require("child_process");
|
|
18176
|
+
import_node_fs45 = require("fs");
|
|
18025
18177
|
import_node_os13 = require("os");
|
|
18026
|
-
|
|
18178
|
+
import_node_path43 = require("path");
|
|
18027
18179
|
import_node_module4 = require("module");
|
|
18028
18180
|
init_worktree();
|
|
18029
18181
|
init_thread_store();
|
|
18030
|
-
CONDUCTOR_APP_SUPPORT = (0,
|
|
18182
|
+
CONDUCTOR_APP_SUPPORT = (0, import_node_path43.join)(
|
|
18031
18183
|
process.env.HOME ?? "",
|
|
18032
18184
|
"Library",
|
|
18033
18185
|
"Application Support",
|
|
18034
18186
|
"com.conductor.app"
|
|
18035
18187
|
);
|
|
18036
|
-
CONDUCTOR_DB = (0,
|
|
18037
|
-
CURSOR_SDK_STORE = (0,
|
|
18188
|
+
CONDUCTOR_DB = (0, import_node_path43.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
18189
|
+
CURSOR_SDK_STORE = (0, import_node_path43.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
18038
18190
|
}
|
|
18039
18191
|
});
|
|
18040
18192
|
|
|
@@ -18101,7 +18253,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
18101
18253
|
let createdWorktree = false;
|
|
18102
18254
|
const trees = await listWorktrees(repoPath);
|
|
18103
18255
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
18104
|
-
if (checkedOut?.path && (0,
|
|
18256
|
+
if (checkedOut?.path && (0, import_node_fs46.existsSync)(checkedOut.path)) {
|
|
18105
18257
|
if (input.reuseExistingWorktree !== false) {
|
|
18106
18258
|
worktreePath = checkedOut.path;
|
|
18107
18259
|
} else {
|
|
@@ -18243,7 +18395,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
18243
18395
|
async function createPrStack(input, onSetupLine) {
|
|
18244
18396
|
await requireAgent(input.agent);
|
|
18245
18397
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
18246
|
-
if (!(0,
|
|
18398
|
+
if (!(0, import_node_fs46.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
18247
18399
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
18248
18400
|
const status = await detectGhStack(repoPath);
|
|
18249
18401
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -18310,7 +18462,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
18310
18462
|
}
|
|
18311
18463
|
}
|
|
18312
18464
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
18313
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
18465
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs46.existsSync)(bootstrap.worktreePath)) {
|
|
18314
18466
|
try {
|
|
18315
18467
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
18316
18468
|
deleteBranch: bootstrap.branchName
|
|
@@ -18330,11 +18482,11 @@ function stackAgentDefaultsFrom(input) {
|
|
|
18330
18482
|
planMode: input.planMode
|
|
18331
18483
|
};
|
|
18332
18484
|
}
|
|
18333
|
-
var
|
|
18485
|
+
var import_node_fs46;
|
|
18334
18486
|
var init_stack_layers = __esm({
|
|
18335
18487
|
"src/threads/stack-layers.ts"() {
|
|
18336
18488
|
"use strict";
|
|
18337
|
-
|
|
18489
|
+
import_node_fs46 = require("fs");
|
|
18338
18490
|
init_detect();
|
|
18339
18491
|
init_run();
|
|
18340
18492
|
init_stack();
|
|
@@ -18347,7 +18499,7 @@ var init_stack_layers = __esm({
|
|
|
18347
18499
|
|
|
18348
18500
|
// src/diff/diff.ts
|
|
18349
18501
|
async function inspectGitWorktree(worktreePath) {
|
|
18350
|
-
if (!worktreePath || !(0,
|
|
18502
|
+
if (!worktreePath || !(0, import_node_fs47.existsSync)(worktreePath)) return "missing_worktree";
|
|
18351
18503
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
18352
18504
|
reject: false
|
|
18353
18505
|
});
|
|
@@ -18355,7 +18507,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
18355
18507
|
return "ok";
|
|
18356
18508
|
}
|
|
18357
18509
|
async function initializeGitRepository(worktreePath) {
|
|
18358
|
-
if (!worktreePath || !(0,
|
|
18510
|
+
if (!worktreePath || !(0, import_node_fs47.existsSync)(worktreePath)) {
|
|
18359
18511
|
throw new Error("Worktree not found");
|
|
18360
18512
|
}
|
|
18361
18513
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -18489,11 +18641,11 @@ new file mode 100644
|
|
|
18489
18641
|
};
|
|
18490
18642
|
}
|
|
18491
18643
|
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
18492
|
-
const abs = (0,
|
|
18644
|
+
const abs = (0, import_node_path44.join)(worktreePath, path2);
|
|
18493
18645
|
try {
|
|
18494
|
-
const st = (0,
|
|
18646
|
+
const st = (0, import_node_fs47.statSync)(abs);
|
|
18495
18647
|
if (st.isFile() && st.size > maxHunk) {
|
|
18496
|
-
const buf = (0,
|
|
18648
|
+
const buf = (0, import_node_fs47.readFileSync)(abs).subarray(0, maxHunk);
|
|
18497
18649
|
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
18498
18650
|
}
|
|
18499
18651
|
} catch {
|
|
@@ -18982,8 +19134,8 @@ function isImageRelativePath(relativePath) {
|
|
|
18982
19134
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
18983
19135
|
assertSafeRelativePath(relativePath);
|
|
18984
19136
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
18985
|
-
const abs = (0,
|
|
18986
|
-
const st = (0,
|
|
19137
|
+
const abs = (0, import_node_path44.join)(worktreePath, relativePath);
|
|
19138
|
+
const st = (0, import_node_fs47.statSync)(abs);
|
|
18987
19139
|
if (!st.isFile()) {
|
|
18988
19140
|
throw new Error(`Not a file: ${relativePath}`);
|
|
18989
19141
|
}
|
|
@@ -18992,7 +19144,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
18992
19144
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
18993
19145
|
);
|
|
18994
19146
|
}
|
|
18995
|
-
const buf = (0,
|
|
19147
|
+
const buf = (0, import_node_fs47.readFileSync)(abs);
|
|
18996
19148
|
return {
|
|
18997
19149
|
path: relativePath,
|
|
18998
19150
|
contentBase64: buf.toString("base64"),
|
|
@@ -19002,12 +19154,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
19002
19154
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
19003
19155
|
assertSafeRelativePath(relativePath);
|
|
19004
19156
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
19005
|
-
const abs = (0,
|
|
19006
|
-
const st = (0,
|
|
19157
|
+
const abs = (0, import_node_path44.join)(worktreePath, relativePath);
|
|
19158
|
+
const st = (0, import_node_fs47.statSync)(abs);
|
|
19007
19159
|
if (!st.isFile()) {
|
|
19008
19160
|
throw new Error(`Not a file: ${relativePath}`);
|
|
19009
19161
|
}
|
|
19010
|
-
const buf = (0,
|
|
19162
|
+
const buf = (0, import_node_fs47.readFileSync)(abs);
|
|
19011
19163
|
if (isImageRelativePath(relativePath)) {
|
|
19012
19164
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
19013
19165
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -19050,9 +19202,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
19050
19202
|
}
|
|
19051
19203
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
19052
19204
|
assertSafeRelativePath(relativePath);
|
|
19053
|
-
const abs = (0,
|
|
19054
|
-
(0,
|
|
19055
|
-
(0,
|
|
19205
|
+
const abs = (0, import_node_path44.join)(worktreePath, relativePath);
|
|
19206
|
+
(0, import_node_fs47.mkdirSync)((0, import_node_path44.dirname)(abs), { recursive: true });
|
|
19207
|
+
(0, import_node_fs47.writeFileSync)(abs, content, "utf8");
|
|
19056
19208
|
return { path: relativePath };
|
|
19057
19209
|
}
|
|
19058
19210
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -19069,12 +19221,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
19069
19221
|
truncated: full.files.length > maxFiles
|
|
19070
19222
|
};
|
|
19071
19223
|
}
|
|
19072
|
-
var
|
|
19224
|
+
var import_node_fs47, import_node_path44, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
|
|
19073
19225
|
var init_diff = __esm({
|
|
19074
19226
|
"src/diff/diff.ts"() {
|
|
19075
19227
|
"use strict";
|
|
19076
|
-
|
|
19077
|
-
|
|
19228
|
+
import_node_fs47 = require("fs");
|
|
19229
|
+
import_node_path44 = require("path");
|
|
19078
19230
|
init_run();
|
|
19079
19231
|
init_worktree();
|
|
19080
19232
|
mergeBaseCache = /* @__PURE__ */ new Map();
|
|
@@ -19350,7 +19502,7 @@ function parseFrontmatter(content) {
|
|
|
19350
19502
|
}
|
|
19351
19503
|
function readSkill(skillMd, source) {
|
|
19352
19504
|
try {
|
|
19353
|
-
const content = (0,
|
|
19505
|
+
const content = (0, import_node_fs48.readFileSync)(skillMd, "utf8");
|
|
19354
19506
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
19355
19507
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
19356
19508
|
const name = fmName || dirName;
|
|
@@ -19369,19 +19521,19 @@ function readSkill(skillMd, source) {
|
|
|
19369
19521
|
}
|
|
19370
19522
|
}
|
|
19371
19523
|
function scanSkillsDir(dir, source, out) {
|
|
19372
|
-
if (!(0,
|
|
19524
|
+
if (!(0, import_node_fs48.existsSync)(dir)) return;
|
|
19373
19525
|
let entries;
|
|
19374
19526
|
try {
|
|
19375
|
-
entries = (0,
|
|
19527
|
+
entries = (0, import_node_fs48.readdirSync)(dir);
|
|
19376
19528
|
} catch {
|
|
19377
19529
|
return;
|
|
19378
19530
|
}
|
|
19379
19531
|
for (const entry of entries) {
|
|
19380
19532
|
if (entry.startsWith(".")) continue;
|
|
19381
|
-
const skillMd = (0,
|
|
19382
|
-
if (!(0,
|
|
19533
|
+
const skillMd = (0, import_node_path45.join)(dir, entry, "SKILL.md");
|
|
19534
|
+
if (!(0, import_node_fs48.existsSync)(skillMd)) continue;
|
|
19383
19535
|
try {
|
|
19384
|
-
if (!(0,
|
|
19536
|
+
if (!(0, import_node_fs48.statSync)(skillMd).isFile()) continue;
|
|
19385
19537
|
} catch {
|
|
19386
19538
|
continue;
|
|
19387
19539
|
}
|
|
@@ -19390,24 +19542,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
19390
19542
|
}
|
|
19391
19543
|
}
|
|
19392
19544
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
19393
|
-
if (!(0,
|
|
19545
|
+
if (!(0, import_node_fs48.existsSync)(pluginsRoot)) return;
|
|
19394
19546
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
19395
19547
|
if (depth > 7) return;
|
|
19396
19548
|
let entries;
|
|
19397
19549
|
try {
|
|
19398
|
-
entries = (0,
|
|
19550
|
+
entries = (0, import_node_fs48.readdirSync)(dir);
|
|
19399
19551
|
} catch {
|
|
19400
19552
|
return;
|
|
19401
19553
|
}
|
|
19402
19554
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
19403
|
-
const skill = readSkill((0,
|
|
19555
|
+
const skill = readSkill((0, import_node_path45.join)(dir, "SKILL.md"), "cli");
|
|
19404
19556
|
if (skill) out.push(skill);
|
|
19405
19557
|
}
|
|
19406
19558
|
for (const entry of entries) {
|
|
19407
19559
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
19408
|
-
const full = (0,
|
|
19560
|
+
const full = (0, import_node_path45.join)(dir, entry);
|
|
19409
19561
|
try {
|
|
19410
|
-
if (!(0,
|
|
19562
|
+
if (!(0, import_node_fs48.statSync)(full).isDirectory()) continue;
|
|
19411
19563
|
} catch {
|
|
19412
19564
|
continue;
|
|
19413
19565
|
}
|
|
@@ -19425,17 +19577,17 @@ function discoverSkills(worktreePath) {
|
|
|
19425
19577
|
const home = (0, import_node_os14.homedir)();
|
|
19426
19578
|
const collected = [];
|
|
19427
19579
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
19428
|
-
scanSkillsDir((0,
|
|
19580
|
+
scanSkillsDir((0, import_node_path45.join)(worktreePath, rel), "workspace", collected);
|
|
19429
19581
|
}
|
|
19430
19582
|
for (const abs of [
|
|
19431
|
-
(0,
|
|
19432
|
-
(0,
|
|
19433
|
-
(0,
|
|
19434
|
-
(0,
|
|
19583
|
+
(0, import_node_path45.join)(home, ".claude/skills"),
|
|
19584
|
+
(0, import_node_path45.join)(home, ".cursor/skills"),
|
|
19585
|
+
(0, import_node_path45.join)(home, ".sideboard/skills"),
|
|
19586
|
+
(0, import_node_path45.join)(home, ".brightsy/skills")
|
|
19435
19587
|
]) {
|
|
19436
19588
|
scanSkillsDir(abs, "user", collected);
|
|
19437
19589
|
}
|
|
19438
|
-
scanClaudePluginSkills((0,
|
|
19590
|
+
scanClaudePluginSkills((0, import_node_path45.join)(home, ".claude/plugins"), collected);
|
|
19439
19591
|
collected.push(...bundledSkills());
|
|
19440
19592
|
const rank = {
|
|
19441
19593
|
workspace: 0,
|
|
@@ -19461,7 +19613,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
19461
19613
|
\u2026(truncated)` : body;
|
|
19462
19614
|
}
|
|
19463
19615
|
}
|
|
19464
|
-
const raw = (0,
|
|
19616
|
+
const raw = (0, import_node_fs48.readFileSync)(skillPath, "utf8");
|
|
19465
19617
|
if (raw.startsWith("---")) {
|
|
19466
19618
|
const end = raw.indexOf("\n---", 3);
|
|
19467
19619
|
if (end >= 0) {
|
|
@@ -19475,13 +19627,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
19475
19627
|
|
|
19476
19628
|
\u2026(truncated)` : raw;
|
|
19477
19629
|
}
|
|
19478
|
-
var
|
|
19630
|
+
var import_node_fs48, import_node_os14, import_node_path45, BUNDLED_SKILL_PREFIX;
|
|
19479
19631
|
var init_discover = __esm({
|
|
19480
19632
|
"src/skills/discover.ts"() {
|
|
19481
19633
|
"use strict";
|
|
19482
|
-
|
|
19634
|
+
import_node_fs48 = require("fs");
|
|
19483
19635
|
import_node_os14 = require("os");
|
|
19484
|
-
|
|
19636
|
+
import_node_path45 = require("path");
|
|
19485
19637
|
init_long_running();
|
|
19486
19638
|
BUNDLED_SKILL_PREFIX = "bundled:";
|
|
19487
19639
|
}
|
|
@@ -19575,8 +19727,8 @@ var init_expand = __esm({
|
|
|
19575
19727
|
// src/skills/detached-job-path.ts
|
|
19576
19728
|
function detachedJobScriptIn(dir) {
|
|
19577
19729
|
for (const name of DETACHED_JOB_FILENAMES) {
|
|
19578
|
-
const script = (0,
|
|
19579
|
-
if ((0,
|
|
19730
|
+
const script = (0, import_node_path46.join)(dir, "scripts", name);
|
|
19731
|
+
if ((0, import_node_fs49.existsSync)(script)) return script;
|
|
19580
19732
|
}
|
|
19581
19733
|
return null;
|
|
19582
19734
|
}
|
|
@@ -19588,11 +19740,11 @@ function packagedDetachedJobPath() {
|
|
|
19588
19740
|
function resolveDetachedJobScript() {
|
|
19589
19741
|
const packaged = packagedDetachedJobPath();
|
|
19590
19742
|
if (packaged) return packaged;
|
|
19591
|
-
let dir = (0,
|
|
19743
|
+
let dir = (0, import_node_path46.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
19592
19744
|
for (let i = 0; i < 8; i++) {
|
|
19593
19745
|
const candidate = detachedJobScriptIn(dir);
|
|
19594
19746
|
if (candidate) return candidate;
|
|
19595
|
-
const parent = (0,
|
|
19747
|
+
const parent = (0, import_node_path46.dirname)(dir);
|
|
19596
19748
|
if (parent === dir) break;
|
|
19597
19749
|
dir = parent;
|
|
19598
19750
|
}
|
|
@@ -19603,12 +19755,12 @@ function formatDetachedJobInvoke(scriptPath) {
|
|
|
19603
19755
|
if (resolved) return `node ${JSON.stringify(resolved)}`;
|
|
19604
19756
|
return "node scripts/detached-job.cjs";
|
|
19605
19757
|
}
|
|
19606
|
-
var
|
|
19758
|
+
var import_node_fs49, import_node_path46, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
|
|
19607
19759
|
var init_detached_job_path = __esm({
|
|
19608
19760
|
"src/skills/detached-job-path.ts"() {
|
|
19609
19761
|
"use strict";
|
|
19610
|
-
|
|
19611
|
-
|
|
19762
|
+
import_node_fs49 = require("fs");
|
|
19763
|
+
import_node_path46 = require("path");
|
|
19612
19764
|
import_node_url3 = require("url");
|
|
19613
19765
|
init_packaged_runtime();
|
|
19614
19766
|
import_meta3 = {};
|
|
@@ -19686,7 +19838,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
19686
19838
|
);
|
|
19687
19839
|
}
|
|
19688
19840
|
lines.push(
|
|
19689
|
-
'- Sideboard git buttons send short phrases ("Commit and push.", "Merge PR.", \u2026) with their meaning attached \u2014 act on them without asking for clarification. If the user gives a goal (Greptile 5/5, CI green, until checks pass), you get the watch-fix-push playbook with that request.'
|
|
19841
|
+
'- Sideboard git buttons send short phrases ("Commit and push.", "Ready for review.", "Merge PR.", \u2026) with their meaning attached \u2014 act on them without asking for clarification. If the user gives a goal (Greptile 5/5, CI green, until checks pass), you get the watch-fix-push playbook with that request.'
|
|
19690
19842
|
);
|
|
19691
19843
|
lines.push("");
|
|
19692
19844
|
lines.push(formatProcessGuideDirective({ worktreePath: thread.worktreePath }));
|
|
@@ -19788,9 +19940,9 @@ function formatPrGateDirective() {
|
|
|
19788
19940
|
}
|
|
19789
19941
|
function formatProcessGuideDirective(opts) {
|
|
19790
19942
|
const worktree = opts?.worktreePath?.trim();
|
|
19791
|
-
const hasGraphSkill = !!worktree && (0,
|
|
19792
|
-
const hasReviewSkill = !!worktree && (0,
|
|
19793
|
-
const hasInstallSkill = !!worktree && (0,
|
|
19943
|
+
const hasGraphSkill = !!worktree && (0, import_node_fs50.existsSync)((0, import_node_path47.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
|
|
19944
|
+
const hasReviewSkill = !!worktree && (0, import_node_fs50.existsSync)((0, import_node_path47.join)(worktree, ".claude/skills/review/SKILL.md"));
|
|
19945
|
+
const hasInstallSkill = !!worktree && (0, import_node_fs50.existsSync)((0, import_node_path47.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
|
|
19794
19946
|
return [
|
|
19795
19947
|
"Process guides (recurring work only):",
|
|
19796
19948
|
hasGraphSkill ? "- Migrations, ports, batch fixes, and other fan-out: follow `.claude/skills/graph-engineering/SKILL.md` (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch around it." : null,
|
|
@@ -19828,12 +19980,12 @@ function formatArtifactDirective() {
|
|
|
19828
19980
|
function formatUiReminder() {
|
|
19829
19981
|
return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
|
|
19830
19982
|
}
|
|
19831
|
-
var
|
|
19983
|
+
var import_node_fs50, import_node_path47, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
|
|
19832
19984
|
var init_instructions = __esm({
|
|
19833
19985
|
"src/agents/instructions.ts"() {
|
|
19834
19986
|
"use strict";
|
|
19835
|
-
|
|
19836
|
-
|
|
19987
|
+
import_node_fs50 = require("fs");
|
|
19988
|
+
import_node_path47 = require("path");
|
|
19837
19989
|
init_git_auth_mode();
|
|
19838
19990
|
init_worktree_labels();
|
|
19839
19991
|
init_detached_job_path();
|
|
@@ -20186,40 +20338,40 @@ __export(plan_file_exports, {
|
|
|
20186
20338
|
writePlanFile: () => writePlanFile
|
|
20187
20339
|
});
|
|
20188
20340
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
20189
|
-
const gitignoreAbs = (0,
|
|
20190
|
-
if ((0,
|
|
20191
|
-
(0,
|
|
20192
|
-
(0,
|
|
20341
|
+
const gitignoreAbs = (0, import_node_path48.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
20342
|
+
if ((0, import_node_fs51.existsSync)(gitignoreAbs)) return;
|
|
20343
|
+
(0, import_node_fs51.mkdirSync)((0, import_node_path48.dirname)(gitignoreAbs), { recursive: true });
|
|
20344
|
+
(0, import_node_fs51.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
20193
20345
|
}
|
|
20194
20346
|
function planFileAbs(worktreePath) {
|
|
20195
|
-
return (0,
|
|
20347
|
+
return (0, import_node_path48.join)(worktreePath, PLAN_FILE_REL);
|
|
20196
20348
|
}
|
|
20197
20349
|
function readTextIfPresent2(abs) {
|
|
20198
|
-
if (!(0,
|
|
20350
|
+
if (!(0, import_node_fs51.existsSync)(abs)) return null;
|
|
20199
20351
|
try {
|
|
20200
|
-
const content = (0,
|
|
20352
|
+
const content = (0, import_node_fs51.readFileSync)(abs, "utf8");
|
|
20201
20353
|
return content.trim() ? content : null;
|
|
20202
20354
|
} catch {
|
|
20203
20355
|
return null;
|
|
20204
20356
|
}
|
|
20205
20357
|
}
|
|
20206
20358
|
function readPlanFile(worktreePath) {
|
|
20207
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
20359
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path48.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path48.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
20208
20360
|
}
|
|
20209
20361
|
function writePlanFile(worktreePath, content) {
|
|
20210
20362
|
ensureAttachmentsGitignore(worktreePath);
|
|
20211
20363
|
const abs = planFileAbs(worktreePath);
|
|
20212
|
-
(0,
|
|
20364
|
+
(0, import_node_fs51.mkdirSync)((0, import_node_path48.dirname)(abs), { recursive: true });
|
|
20213
20365
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
20214
|
-
(0,
|
|
20366
|
+
(0, import_node_fs51.writeFileSync)(abs, body, "utf8");
|
|
20215
20367
|
return PLAN_FILE_REL;
|
|
20216
20368
|
}
|
|
20217
|
-
var
|
|
20369
|
+
var import_node_fs51, import_node_path48;
|
|
20218
20370
|
var init_plan_file = __esm({
|
|
20219
20371
|
"src/plan/plan-file.ts"() {
|
|
20220
20372
|
"use strict";
|
|
20221
|
-
|
|
20222
|
-
|
|
20373
|
+
import_node_fs51 = require("fs");
|
|
20374
|
+
import_node_path48 = require("path");
|
|
20223
20375
|
init_workspace_scratch();
|
|
20224
20376
|
init_plan_present();
|
|
20225
20377
|
init_plan_present();
|
|
@@ -20267,13 +20419,13 @@ var init_sync_branch = __esm({
|
|
|
20267
20419
|
|
|
20268
20420
|
// src/agents/cursor-store.ts
|
|
20269
20421
|
function cursorSdkStoreDir(threadId) {
|
|
20270
|
-
const root = (0,
|
|
20422
|
+
const root = (0, import_node_path49.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
|
|
20271
20423
|
const id = sanitizeCursorStoreSegment(threadId);
|
|
20272
20424
|
if (!id) return root;
|
|
20273
|
-
return (0,
|
|
20425
|
+
return (0, import_node_path49.join)(root, "threads", id);
|
|
20274
20426
|
}
|
|
20275
20427
|
function cursorSdkRunsNdjsonPath(threadId) {
|
|
20276
|
-
return (0,
|
|
20428
|
+
return (0, import_node_path49.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
|
|
20277
20429
|
}
|
|
20278
20430
|
function cursorSdkRunsNdjsonSearchPaths(threadId) {
|
|
20279
20431
|
const scoped = cursorSdkRunsNdjsonPath(threadId);
|
|
@@ -20286,11 +20438,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
|
|
|
20286
20438
|
function sanitizeCursorStoreSegment(threadId) {
|
|
20287
20439
|
return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
20288
20440
|
}
|
|
20289
|
-
var
|
|
20441
|
+
var import_node_path49, CURSOR_SDK_STORE_DIR;
|
|
20290
20442
|
var init_cursor_store = __esm({
|
|
20291
20443
|
"src/agents/cursor-store.ts"() {
|
|
20292
20444
|
"use strict";
|
|
20293
|
-
|
|
20445
|
+
import_node_path49 = require("path");
|
|
20294
20446
|
init_paths();
|
|
20295
20447
|
CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
|
|
20296
20448
|
}
|
|
@@ -20312,9 +20464,9 @@ function recoverFinishedCursorRun(opts) {
|
|
|
20312
20464
|
return best;
|
|
20313
20465
|
}
|
|
20314
20466
|
function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
20315
|
-
if (!(0,
|
|
20467
|
+
if (!(0, import_node_fs52.existsSync)(runsPath)) return null;
|
|
20316
20468
|
try {
|
|
20317
|
-
const lines = (0,
|
|
20469
|
+
const lines = (0, import_node_fs52.readFileSync)(runsPath, "utf8").split("\n");
|
|
20318
20470
|
let best = null;
|
|
20319
20471
|
for (const line of lines) {
|
|
20320
20472
|
const trimmed = line.trim();
|
|
@@ -20340,11 +20492,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
|
20340
20492
|
return null;
|
|
20341
20493
|
}
|
|
20342
20494
|
}
|
|
20343
|
-
var
|
|
20495
|
+
var import_node_fs52;
|
|
20344
20496
|
var init_cursor_recover = __esm({
|
|
20345
20497
|
"src/agents/cursor-recover.ts"() {
|
|
20346
20498
|
"use strict";
|
|
20347
|
-
|
|
20499
|
+
import_node_fs52 = require("fs");
|
|
20348
20500
|
init_cursor_store();
|
|
20349
20501
|
}
|
|
20350
20502
|
});
|
|
@@ -20476,13 +20628,13 @@ async function startOrchestration(opts) {
|
|
|
20476
20628
|
}
|
|
20477
20629
|
return updated;
|
|
20478
20630
|
}
|
|
20479
|
-
var import_node_events,
|
|
20631
|
+
var import_node_events, import_node_fs53, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
|
|
20480
20632
|
var init_orchestrator = __esm({
|
|
20481
20633
|
"src/orchestrator/orchestrator.ts"() {
|
|
20482
20634
|
"use strict";
|
|
20483
20635
|
import_node_events = require("events");
|
|
20484
20636
|
init_outbound_watch();
|
|
20485
|
-
|
|
20637
|
+
import_node_fs53 = require("fs");
|
|
20486
20638
|
init_error_detail();
|
|
20487
20639
|
init_run();
|
|
20488
20640
|
init_stale_lock();
|
|
@@ -20655,7 +20807,7 @@ var init_orchestrator = __esm({
|
|
|
20655
20807
|
}
|
|
20656
20808
|
continue;
|
|
20657
20809
|
}
|
|
20658
|
-
if (!(0,
|
|
20810
|
+
if (!(0, import_node_fs53.existsSync)(thread.worktreePath)) {
|
|
20659
20811
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
20660
20812
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
20661
20813
|
continue;
|
|
@@ -22330,7 +22482,7 @@ var init_orchestrator = __esm({
|
|
|
22330
22482
|
"ask_git targets a worktree agent thread (not the orchestrator). Pass a child/worktree thread ref."
|
|
22331
22483
|
);
|
|
22332
22484
|
}
|
|
22333
|
-
if (action === "merge" && !thread.prUrl) {
|
|
22485
|
+
if ((action === "merge" || action === "ready-for-review") && !thread.prUrl) {
|
|
22334
22486
|
throw new Error(
|
|
22335
22487
|
"No pull request linked. Ask the worktree agent to open a draft PR first (ask_git create-draft)."
|
|
22336
22488
|
);
|
|
@@ -22546,7 +22698,7 @@ var init_orchestrator = __esm({
|
|
|
22546
22698
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
22547
22699
|
return restored2;
|
|
22548
22700
|
}
|
|
22549
|
-
if (!(0,
|
|
22701
|
+
if (!(0, import_node_fs53.existsSync)(thread.worktreePath)) {
|
|
22550
22702
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
22551
22703
|
throw new Error(
|
|
22552
22704
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -22864,6 +23016,7 @@ __export(index_exports, {
|
|
|
22864
23016
|
applyForwardOccupancy: () => applyForwardOccupancy,
|
|
22865
23017
|
applyGithubGitAuthEnv: () => applyGithubGitAuthEnv,
|
|
22866
23018
|
applyPromptCacheTtlEnv: () => applyPromptCacheTtlEnv,
|
|
23019
|
+
applySystemCaEnv: () => applySystemCaEnv,
|
|
22867
23020
|
applyThreadIntoMain: () => applyThreadIntoMain,
|
|
22868
23021
|
applyTurnUsage: () => applyTurnUsage,
|
|
22869
23022
|
armSchedules: () => armSchedules,
|
|
@@ -23144,6 +23297,7 @@ __export(index_exports, {
|
|
|
23144
23297
|
isCloudCoordinatorThread: () => isCloudCoordinatorThread,
|
|
23145
23298
|
isConductorBundledCli: () => isConductorBundledCli,
|
|
23146
23299
|
isCowboyThread: () => isCowboyThread,
|
|
23300
|
+
isCursorApiKeyConfigured: () => isCursorApiKeyConfigured,
|
|
23147
23301
|
isCursorAutoModel: () => isCursorAutoModel,
|
|
23148
23302
|
isDefaultishSourceRef: () => isDefaultishSourceRef,
|
|
23149
23303
|
isDesktopHostAlive: () => isDesktopHostAlive,
|
|
@@ -23242,6 +23396,7 @@ __export(index_exports, {
|
|
|
23242
23396
|
lookupSoccerTeam: () => lookupSoccerTeam,
|
|
23243
23397
|
mapAbleTimeTask: () => mapAbleTimeTask,
|
|
23244
23398
|
markPrReady: () => markPrReady,
|
|
23399
|
+
materializeSystemCaBundle: () => materializeSystemCaBundle,
|
|
23245
23400
|
maxConcurrentAgents: () => maxConcurrentAgents,
|
|
23246
23401
|
maybeCompactContext: () => maybeCompactContext,
|
|
23247
23402
|
mcpAllowTools: () => mcpAllowTools,
|
|
@@ -23465,6 +23620,7 @@ __export(index_exports, {
|
|
|
23465
23620
|
toolDetail: () => toolDetail,
|
|
23466
23621
|
toolFilePath: () => toolFilePath,
|
|
23467
23622
|
totalTokens: () => totalTokens,
|
|
23623
|
+
trustSystemCertificates: () => trustSystemCertificates,
|
|
23468
23624
|
turnCostUsdFromCursorUsage: () => turnCostUsdFromCursorUsage,
|
|
23469
23625
|
updateAbleTimeTask: () => updateAbleTimeTask,
|
|
23470
23626
|
updateAdvancedSettings: () => updateAdvancedSettings,
|
|
@@ -24831,6 +24987,7 @@ async function installOptionalServiceCli(id) {
|
|
|
24831
24987
|
|
|
24832
24988
|
// src/index.ts
|
|
24833
24989
|
init_fetch();
|
|
24990
|
+
init_system_ca();
|
|
24834
24991
|
init_agents();
|
|
24835
24992
|
init_spawn();
|
|
24836
24993
|
init_message_parts();
|
|
@@ -25176,7 +25333,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
25176
25333
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
25177
25334
|
var import_zod8 = require("zod");
|
|
25178
25335
|
var import_node_crypto13 = require("crypto");
|
|
25179
|
-
var
|
|
25336
|
+
var import_node_path52 = require("path");
|
|
25180
25337
|
init_orchestrator();
|
|
25181
25338
|
init_worktree();
|
|
25182
25339
|
init_global_workspace();
|
|
@@ -26760,27 +26917,27 @@ init_gh_errors();
|
|
|
26760
26917
|
init_git_auth_mode();
|
|
26761
26918
|
|
|
26762
26919
|
// src/board/load-home-board.ts
|
|
26763
|
-
var
|
|
26764
|
-
var
|
|
26920
|
+
var import_node_fs55 = require("fs");
|
|
26921
|
+
var import_node_path51 = require("path");
|
|
26765
26922
|
init_worktree();
|
|
26766
26923
|
init_paths();
|
|
26767
26924
|
|
|
26768
26925
|
// src/board/board-pins.ts
|
|
26769
26926
|
var import_node_crypto12 = require("crypto");
|
|
26770
|
-
var
|
|
26771
|
-
var
|
|
26927
|
+
var import_node_fs54 = require("fs");
|
|
26928
|
+
var import_node_path50 = require("path");
|
|
26772
26929
|
init_paths();
|
|
26773
26930
|
init_home_board();
|
|
26774
26931
|
var FILE = "home-board-pins.json";
|
|
26775
26932
|
var VERSION = 1;
|
|
26776
26933
|
function pinsFile() {
|
|
26777
|
-
return (0,
|
|
26934
|
+
return (0, import_node_path50.join)(appDataDir(), FILE);
|
|
26778
26935
|
}
|
|
26779
26936
|
function readDisk() {
|
|
26780
26937
|
const path2 = pinsFile();
|
|
26781
|
-
if (!(0,
|
|
26938
|
+
if (!(0, import_node_fs54.existsSync)(path2)) return [];
|
|
26782
26939
|
try {
|
|
26783
|
-
const raw = JSON.parse((0,
|
|
26940
|
+
const raw = JSON.parse((0, import_node_fs54.readFileSync)(path2, "utf8"));
|
|
26784
26941
|
if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
|
|
26785
26942
|
return raw.items.filter((item) => item?.id && item.kind && item.ref);
|
|
26786
26943
|
} catch {
|
|
@@ -26788,8 +26945,8 @@ function readDisk() {
|
|
|
26788
26945
|
}
|
|
26789
26946
|
}
|
|
26790
26947
|
function writeDisk(items) {
|
|
26791
|
-
(0,
|
|
26792
|
-
(0,
|
|
26948
|
+
(0, import_node_fs54.mkdirSync)(appDataDir(), { recursive: true });
|
|
26949
|
+
(0, import_node_fs54.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
|
|
26793
26950
|
}
|
|
26794
26951
|
function listBoardPins() {
|
|
26795
26952
|
return readDisk();
|
|
@@ -26841,7 +26998,7 @@ function replaceBoardPins(items) {
|
|
|
26841
26998
|
}
|
|
26842
26999
|
function clearBoardPins() {
|
|
26843
27000
|
try {
|
|
26844
|
-
(0,
|
|
27001
|
+
(0, import_node_fs54.unlinkSync)(pinsFile());
|
|
26845
27002
|
} catch {
|
|
26846
27003
|
}
|
|
26847
27004
|
}
|
|
@@ -26858,7 +27015,7 @@ function homeBoardWorkspaceKey(workspaces) {
|
|
|
26858
27015
|
return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
|
|
26859
27016
|
}
|
|
26860
27017
|
function cacheFile() {
|
|
26861
|
-
return (0,
|
|
27018
|
+
return (0, import_node_path51.join)(appDataDir(), "home-board-cache.json");
|
|
26862
27019
|
}
|
|
26863
27020
|
function emptyInputs() {
|
|
26864
27021
|
return {
|
|
@@ -26884,9 +27041,9 @@ function shouldCacheHomeBoardInputs(inputs) {
|
|
|
26884
27041
|
}
|
|
26885
27042
|
function readDiskCache() {
|
|
26886
27043
|
const path2 = cacheFile();
|
|
26887
|
-
if (!(0,
|
|
27044
|
+
if (!(0, import_node_fs55.existsSync)(path2)) return null;
|
|
26888
27045
|
try {
|
|
26889
|
-
const raw = JSON.parse((0,
|
|
27046
|
+
const raw = JSON.parse((0, import_node_fs55.readFileSync)(path2, "utf8"));
|
|
26890
27047
|
if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
|
|
26891
27048
|
return null;
|
|
26892
27049
|
}
|
|
@@ -26900,14 +27057,14 @@ function readDiskCache() {
|
|
|
26900
27057
|
}
|
|
26901
27058
|
function writeDiskCache(entry) {
|
|
26902
27059
|
try {
|
|
26903
|
-
(0,
|
|
26904
|
-
(0,
|
|
27060
|
+
(0, import_node_fs55.mkdirSync)(appDataDir(), { recursive: true });
|
|
27061
|
+
(0, import_node_fs55.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
|
|
26905
27062
|
} catch {
|
|
26906
27063
|
}
|
|
26907
27064
|
}
|
|
26908
27065
|
function deleteDiskCache() {
|
|
26909
27066
|
try {
|
|
26910
|
-
(0,
|
|
27067
|
+
(0, import_node_fs55.unlinkSync)(cacheFile());
|
|
26911
27068
|
} catch {
|
|
26912
27069
|
}
|
|
26913
27070
|
}
|
|
@@ -27043,6 +27200,54 @@ async function getHomeBoardInputs(workspaces, opts) {
|
|
|
27043
27200
|
|
|
27044
27201
|
// src/mcp/server.ts
|
|
27045
27202
|
init_home_board();
|
|
27203
|
+
|
|
27204
|
+
// src/mcp/create-thread-agent.ts
|
|
27205
|
+
init_cursor();
|
|
27206
|
+
function resolveOrchCreateThreadOptions(input) {
|
|
27207
|
+
const { resolveNewThreadOptions: resolveNewThreadOptions2 } = input;
|
|
27208
|
+
const account = resolveNewThreadOptions2({});
|
|
27209
|
+
const requested = input.requestedAgent;
|
|
27210
|
+
const parent = input.parentAgent ?? void 0;
|
|
27211
|
+
const cursorReady = input.cursorReady ?? isCursorApiKeyConfigured();
|
|
27212
|
+
let agent = account.agent;
|
|
27213
|
+
let ignoredAgent;
|
|
27214
|
+
let honorRequestedModel = false;
|
|
27215
|
+
if (requested) {
|
|
27216
|
+
const parentEcho = Boolean(parent) && requested === parent && requested !== account.agent;
|
|
27217
|
+
const cursorAutofill = requested === "cursor" && account.agent !== "cursor";
|
|
27218
|
+
if (parentEcho || cursorAutofill) {
|
|
27219
|
+
ignoredAgent = requested;
|
|
27220
|
+
} else {
|
|
27221
|
+
agent = requested;
|
|
27222
|
+
honorRequestedModel = input.requestedModel !== void 0;
|
|
27223
|
+
}
|
|
27224
|
+
}
|
|
27225
|
+
let coercedFrom;
|
|
27226
|
+
if (agent === "codex" && parent === "codex" && cursorReady) {
|
|
27227
|
+
coercedFrom = requested ?? "codex";
|
|
27228
|
+
agent = "cursor";
|
|
27229
|
+
}
|
|
27230
|
+
const opts = resolveNewThreadOptions2({
|
|
27231
|
+
agent,
|
|
27232
|
+
model: honorRequestedModel ? input.requestedModel : void 0
|
|
27233
|
+
});
|
|
27234
|
+
return {
|
|
27235
|
+
...opts,
|
|
27236
|
+
...ignoredAgent ? { ignoredAgent } : {},
|
|
27237
|
+
...coercedFrom ? { coercedFrom } : {}
|
|
27238
|
+
};
|
|
27239
|
+
}
|
|
27240
|
+
function orchCreateThreadAgentNote(input) {
|
|
27241
|
+
if (input.coercedFrom) {
|
|
27242
|
+
return `Avoid nested Codex under a Codex orchestrator \u2014 used agent=${input.agent}`;
|
|
27243
|
+
}
|
|
27244
|
+
if (input.ignoredAgent) {
|
|
27245
|
+
return `Ignored agent=${input.ignoredAgent} \u2014 used Account default agent=${input.agent}`;
|
|
27246
|
+
}
|
|
27247
|
+
return void 0;
|
|
27248
|
+
}
|
|
27249
|
+
|
|
27250
|
+
// src/mcp/server.ts
|
|
27046
27251
|
var MAX_ORCH_THREADS = 5;
|
|
27047
27252
|
var CREATE_THREAD_TIMEOUT_MS = 9e4;
|
|
27048
27253
|
function withTimeout(promise, ms, label) {
|
|
@@ -27090,18 +27295,13 @@ async function createOrchChildThread(orch, args, resolveNewThreadOptions2) {
|
|
|
27090
27295
|
};
|
|
27091
27296
|
}
|
|
27092
27297
|
}
|
|
27093
|
-
|
|
27094
|
-
|
|
27095
|
-
|
|
27096
|
-
|
|
27097
|
-
|
|
27098
|
-
const accountAgent = resolveNewThreadOptions2({}).agent;
|
|
27099
|
-
agentArg = accountAgent !== "codex" ? accountAgent : "cursor";
|
|
27100
|
-
}
|
|
27101
|
-
const opts = resolveNewThreadOptions2({
|
|
27102
|
-
agent: agentArg,
|
|
27103
|
-
model: args.model
|
|
27298
|
+
const opts = resolveOrchCreateThreadOptions({
|
|
27299
|
+
requestedAgent: args.agent,
|
|
27300
|
+
requestedModel: args.model,
|
|
27301
|
+
parentAgent: parent?.agent,
|
|
27302
|
+
resolveNewThreadOptions: resolveNewThreadOptions2
|
|
27104
27303
|
});
|
|
27304
|
+
const agentNote = orchCreateThreadAgentNote(opts);
|
|
27105
27305
|
try {
|
|
27106
27306
|
const priorIds = new Set(orch.getThreads(false).map((t) => t.id));
|
|
27107
27307
|
const thread = await withTimeout(
|
|
@@ -27137,10 +27337,9 @@ async function createOrchChildThread(orch, args, resolveNewThreadOptions2) {
|
|
|
27137
27337
|
link: `sideboard://thread/${thread.id}`,
|
|
27138
27338
|
parentThreadId: thread.parentThreadId,
|
|
27139
27339
|
...alreadyStarted ? { alreadyStarted: true } : {},
|
|
27140
|
-
...
|
|
27141
|
-
|
|
27142
|
-
|
|
27143
|
-
} : {},
|
|
27340
|
+
...opts.coercedFrom ? { agentCoercedFrom: opts.coercedFrom } : {},
|
|
27341
|
+
...opts.ignoredAgent ? { agentIgnored: opts.ignoredAgent } : {},
|
|
27342
|
+
...agentNote ? { note: agentNote } : {},
|
|
27144
27343
|
...parentCorrectedFrom ? { parentCorrectedFrom, parentNote } : {}
|
|
27145
27344
|
})
|
|
27146
27345
|
};
|
|
@@ -27215,7 +27414,7 @@ async function startMcpServer() {
|
|
|
27215
27414
|
async () => {
|
|
27216
27415
|
const threads = orch.getThreads(true);
|
|
27217
27416
|
const lines = threads.map((t) => {
|
|
27218
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
27417
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path52.basename)(t.repoPath) || t.repoPath;
|
|
27219
27418
|
const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
|
|
27220
27419
|
const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
|
|
27221
27420
|
const preview = lastMessagePreview(t.messages, 80);
|
|
@@ -27500,11 +27699,13 @@ async function startMcpServer() {
|
|
|
27500
27699
|
);
|
|
27501
27700
|
server.tool(
|
|
27502
27701
|
"create_thread",
|
|
27503
|
-
`Create a worktree thread (chat) from branch, pr, or ticket. A ticket, PR, or named branch may have only one live worktree \u2014 if one already matches, returns it (alreadyStarted=true) instead of a second checkout. Creating from the default branch still opens a new isolated worktree. Pass repoPath from list_workspaces. cowboy=true uses the project folder on the default branch (no isolated worktree; land is commit+push). From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid.
|
|
27702
|
+
`Create a worktree thread (chat) from branch, pr, or ticket. A ticket, PR, or named branch may have only one live worktree \u2014 if one already matches, returns it (alreadyStarted=true) instead of a second checkout. Creating from the default branch still opens a new isolated worktree. Pass repoPath from list_workspaces. cowboy=true uses the project folder on the default branch (no isolated worktree; land is commit+push). From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Omit agent/model \u2014 Sideboard applies ${accountDefaultsHint}. Do not pass your own agent or agent=cursor; those are ignored. Setup (settings.toml, .cursor/worktrees.json, or script/setup) runs in the background in parallel with the first turn (skipped for cowboy). Then use send_to_thread to chat.`,
|
|
27504
27703
|
{
|
|
27505
27704
|
sourceType: import_zod8.z.enum(["branch", "pr", "ticket"]),
|
|
27506
27705
|
sourceRef: import_zod8.z.string(),
|
|
27507
|
-
agent: import_zod8.z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]).optional().describe(
|
|
27706
|
+
agent: import_zod8.z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]).optional().describe(
|
|
27707
|
+
`Usually omit. Sideboard uses Account default agent (${accountDefaults.agent}). Passing your own agent or cursor is ignored.`
|
|
27708
|
+
),
|
|
27508
27709
|
model: import_zod8.z.string().nullable().optional().describe(
|
|
27509
27710
|
`Usually omit to use Account default model (${accountDefaults.model?.trim() || "Auto"}). Pass null only to force Auto / agent-default.`
|
|
27510
27711
|
),
|
|
@@ -27808,11 +28009,11 @@ async function startMcpServer() {
|
|
|
27808
28009
|
);
|
|
27809
28010
|
server.tool(
|
|
27810
28011
|
"ask_git",
|
|
27811
|
-
"Commit & push, open a draft PR, resolve conflicts, or merge \u2014 same actions as the desktop git buttons. When the worktree is clean, Sideboard pushes / opens the PR itself (HTTPS via `gh` even when origin is SSH / Settings \u2192 Git is SSH). When dirty, queues the worktree agent to commit; then wait_for_turn (loop while stillRunning). Do not start a checks loop on a plain push \u2014 only if the user gave a goal (Greptile 5/5, CI green). Pass a worktree thread ref (not the orchestrator). action=merge only when the user explicitly asked
|
|
28012
|
+
"Commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge \u2014 same actions as the desktop git buttons. When the worktree is clean, Sideboard pushes / opens the PR itself (HTTPS via `gh` even when origin is SSH / Settings \u2192 Git is SSH). When dirty, queues the worktree agent to commit; then wait_for_turn (loop while stillRunning). Do not start a checks loop on a plain push \u2014 only if the user gave a goal (Greptile 5/5, CI green). Pass a worktree thread ref (not the orchestrator). action=ready-for-review and action=merge only when the user explicitly asked (or clicked the desktop button). Do not run git or gh from the orchestration cwd. If this tool errors that the GraphQL/PR body is too long, the branch is already pushed \u2014 have the worktree agent retry `gh pr create --body-file` with a short description (GitHub limit 65,536 characters). Do not invent SSH/auth failures from that error.",
|
|
27812
28013
|
{
|
|
27813
28014
|
ref: import_zod8.z.string().describe("Worktree thread id/ref"),
|
|
27814
28015
|
action: import_zod8.z.enum(AGENT_GIT_ACTIONS).describe(
|
|
27815
|
-
"commit-push | create-draft | create-web | resolve-conflicts | merge"
|
|
28016
|
+
"commit-push | create-draft | create-web | resolve-conflicts | ready-for-review | merge"
|
|
27816
28017
|
)
|
|
27817
28018
|
},
|
|
27818
28019
|
async ({ ref, action }) => {
|
|
@@ -30175,9 +30376,9 @@ var import_node_http3 = require("http");
|
|
|
30175
30376
|
var import_ws3 = require("ws");
|
|
30176
30377
|
|
|
30177
30378
|
// src/slack/relay-static.ts
|
|
30178
|
-
var
|
|
30379
|
+
var import_node_fs56 = require("fs");
|
|
30179
30380
|
var import_promises = require("fs/promises");
|
|
30180
|
-
var
|
|
30381
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
30181
30382
|
var TYPES = {
|
|
30182
30383
|
".css": "text/css; charset=utf-8",
|
|
30183
30384
|
".html": "text/html; charset=utf-8",
|
|
@@ -30208,9 +30409,9 @@ function resolveStaticPath(root, requestUrl) {
|
|
|
30208
30409
|
return null;
|
|
30209
30410
|
}
|
|
30210
30411
|
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
30211
|
-
const rootResolved =
|
|
30212
|
-
const candidate =
|
|
30213
|
-
if (candidate !== rootResolved && !candidate.startsWith(rootResolved +
|
|
30412
|
+
const rootResolved = import_node_path53.default.resolve(root);
|
|
30413
|
+
const candidate = import_node_path53.default.resolve(rootResolved, `.${pathname}`);
|
|
30414
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path53.default.sep)) {
|
|
30214
30415
|
return null;
|
|
30215
30416
|
}
|
|
30216
30417
|
return candidate;
|
|
@@ -30224,7 +30425,7 @@ async function fileSize(file) {
|
|
|
30224
30425
|
}
|
|
30225
30426
|
}
|
|
30226
30427
|
function sendFile(req, res, file, size) {
|
|
30227
|
-
const ext =
|
|
30428
|
+
const ext = import_node_path53.default.extname(file).toLowerCase();
|
|
30228
30429
|
res.writeHead(200, {
|
|
30229
30430
|
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
30230
30431
|
"Content-Length": size,
|
|
@@ -30234,7 +30435,7 @@ function sendFile(req, res, file, size) {
|
|
|
30234
30435
|
res.end();
|
|
30235
30436
|
return true;
|
|
30236
30437
|
}
|
|
30237
|
-
(0,
|
|
30438
|
+
(0, import_node_fs56.createReadStream)(file).pipe(res);
|
|
30238
30439
|
return true;
|
|
30239
30440
|
}
|
|
30240
30441
|
async function tryServeStatic(req, res, root) {
|
|
@@ -30243,7 +30444,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
30243
30444
|
if (!candidate) return false;
|
|
30244
30445
|
const direct = await fileSize(candidate);
|
|
30245
30446
|
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
30246
|
-
const asIndex =
|
|
30447
|
+
const asIndex = import_node_path53.default.join(candidate, "index.html");
|
|
30247
30448
|
const indexSize = await fileSize(asIndex);
|
|
30248
30449
|
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
30249
30450
|
return false;
|
|
@@ -30593,6 +30794,7 @@ init_outbound_watch();
|
|
|
30593
30794
|
applyForwardOccupancy,
|
|
30594
30795
|
applyGithubGitAuthEnv,
|
|
30595
30796
|
applyPromptCacheTtlEnv,
|
|
30797
|
+
applySystemCaEnv,
|
|
30596
30798
|
applyThreadIntoMain,
|
|
30597
30799
|
applyTurnUsage,
|
|
30598
30800
|
armSchedules,
|
|
@@ -30873,6 +31075,7 @@ init_outbound_watch();
|
|
|
30873
31075
|
isCloudCoordinatorThread,
|
|
30874
31076
|
isConductorBundledCli,
|
|
30875
31077
|
isCowboyThread,
|
|
31078
|
+
isCursorApiKeyConfigured,
|
|
30876
31079
|
isCursorAutoModel,
|
|
30877
31080
|
isDefaultishSourceRef,
|
|
30878
31081
|
isDesktopHostAlive,
|
|
@@ -30971,6 +31174,7 @@ init_outbound_watch();
|
|
|
30971
31174
|
lookupSoccerTeam,
|
|
30972
31175
|
mapAbleTimeTask,
|
|
30973
31176
|
markPrReady,
|
|
31177
|
+
materializeSystemCaBundle,
|
|
30974
31178
|
maxConcurrentAgents,
|
|
30975
31179
|
maybeCompactContext,
|
|
30976
31180
|
mcpAllowTools,
|
|
@@ -31194,6 +31398,7 @@ init_outbound_watch();
|
|
|
31194
31398
|
toolDetail,
|
|
31195
31399
|
toolFilePath,
|
|
31196
31400
|
totalTokens,
|
|
31401
|
+
trustSystemCertificates,
|
|
31197
31402
|
turnCostUsdFromCursorUsage,
|
|
31198
31403
|
updateAbleTimeTask,
|
|
31199
31404
|
updateAdvancedSettings,
|