@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
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
loadBrightsyConfig,
|
|
5
5
|
refreshBrightsyAccessToken,
|
|
6
6
|
saveBrightsyConfig
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-AN3THU7F.js";
|
|
8
8
|
import {
|
|
9
9
|
appDataDir
|
|
10
10
|
} from "./chunk-EFVFB2AH.js";
|
|
@@ -18,7 +18,7 @@ import { join } from "path";
|
|
|
18
18
|
|
|
19
19
|
// src/brightsy/accounts.ts
|
|
20
20
|
async function loadConnectedTeams() {
|
|
21
|
-
const { listConnectedBrightsyTeams: listConnectedBrightsyTeams2 } = await import("./connected-teams-
|
|
21
|
+
const { listConnectedBrightsyTeams: listConnectedBrightsyTeams2 } = await import("./connected-teams-ON2KIKQX.js");
|
|
22
22
|
return listConnectedBrightsyTeams2();
|
|
23
23
|
}
|
|
24
24
|
async function runBrightsyTeamsJson(args) {
|
|
@@ -46,15 +46,15 @@ async function listBrightsyAccounts() {
|
|
|
46
46
|
}
|
|
47
47
|
async function getBrightsySession() {
|
|
48
48
|
try {
|
|
49
|
-
const { ensureBrightsyLocalConfigFresh: ensureBrightsyLocalConfigFresh2 } = await import("./oauth-
|
|
50
|
-
const { ensureConnectedBrightsyTeamTokens: ensureConnectedBrightsyTeamTokens2 } = await import("./connected-teams-
|
|
49
|
+
const { ensureBrightsyLocalConfigFresh: ensureBrightsyLocalConfigFresh2 } = await import("./oauth-6ZQ4Q4XN.js");
|
|
50
|
+
const { ensureConnectedBrightsyTeamTokens: ensureConnectedBrightsyTeamTokens2 } = await import("./connected-teams-ON2KIKQX.js");
|
|
51
51
|
await ensureBrightsyLocalConfigFresh2();
|
|
52
52
|
await ensureConnectedBrightsyTeamTokens2();
|
|
53
53
|
loadBrightsyConfig();
|
|
54
54
|
const data = await runBrightsyTeamsJson([]);
|
|
55
55
|
const accounts = Array.isArray(data.teams) ? data.teams : [];
|
|
56
56
|
const active = data.active ?? accounts.find((a) => a.active) ?? null;
|
|
57
|
-
const { ensureCliTeamTracked: ensureCliTeamTracked2 } = await import("./connected-teams-
|
|
57
|
+
const { ensureCliTeamTracked: ensureCliTeamTracked2 } = await import("./connected-teams-ON2KIKQX.js");
|
|
58
58
|
const connectedTeams = ensureCliTeamTracked2(
|
|
59
59
|
active ? { id: active.id, slug: active.slug, name: active.name } : void 0
|
|
60
60
|
);
|
|
@@ -94,7 +94,7 @@ async function performBrightsyAccountSwitch(accountIdOrSlug) {
|
|
|
94
94
|
return { cfg, target: data.active };
|
|
95
95
|
}
|
|
96
96
|
async function switchBrightsyAccount(accountIdOrSlug) {
|
|
97
|
-
const { connectBrightsyTeam: connectBrightsyTeam2 } = await import("./connected-teams-
|
|
97
|
+
const { connectBrightsyTeam: connectBrightsyTeam2 } = await import("./connected-teams-ON2KIKQX.js");
|
|
98
98
|
await connectBrightsyTeam2(accountIdOrSlug);
|
|
99
99
|
return getBrightsySession();
|
|
100
100
|
}
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
summarizeTurnStderr,
|
|
34
34
|
toolDescription,
|
|
35
35
|
turnFailChatText
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-W44EKPIR.js";
|
|
37
37
|
import {
|
|
38
38
|
extractPresentedPlan,
|
|
39
39
|
readPlanFile,
|
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
stageAbsolutePathsAsAttachments,
|
|
65
65
|
stageBuffersAsAttachments,
|
|
66
66
|
syncWorkspacesFromThreads
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-FJWQCZ74.js";
|
|
68
68
|
import {
|
|
69
69
|
addPrStackLayer,
|
|
70
70
|
allocateTeamName,
|
|
@@ -401,7 +401,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
401
401
|
await continueOnReply(threadId, prompt);
|
|
402
402
|
return;
|
|
403
403
|
}
|
|
404
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
404
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-2KZD7N4X.js");
|
|
405
405
|
await getOrchestrator2().send(threadId, prompt);
|
|
406
406
|
} catch {
|
|
407
407
|
}
|
|
@@ -794,9 +794,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
794
794
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
795
795
|
);
|
|
796
796
|
}
|
|
797
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
797
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-J737XNUX.js");
|
|
798
798
|
if (isGlobalThread2(thread)) {
|
|
799
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
799
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-BE2FERYE.js");
|
|
800
800
|
ensureGlobalCoordinatorCwd2(
|
|
801
801
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
802
802
|
);
|
|
@@ -991,6 +991,7 @@ var AGENT_GIT_ACTIONS = [
|
|
|
991
991
|
"create-draft",
|
|
992
992
|
"create-web",
|
|
993
993
|
"resolve-conflicts",
|
|
994
|
+
"ready-for-review",
|
|
994
995
|
"merge"
|
|
995
996
|
];
|
|
996
997
|
function agentGitPrompt(action, opts) {
|
|
@@ -1006,6 +1007,8 @@ function agentGitPrompt(action, opts) {
|
|
|
1006
1007
|
const named = base ? ` (${base})` : "";
|
|
1007
1008
|
return `Merge the remote branch${named} into your branch and resolve conflicts. Then, commit and push your changes.`;
|
|
1008
1009
|
}
|
|
1010
|
+
case "ready-for-review":
|
|
1011
|
+
return "Ready for review.";
|
|
1009
1012
|
case "merge":
|
|
1010
1013
|
return "Merge PR.";
|
|
1011
1014
|
}
|
|
@@ -1021,6 +1024,8 @@ function gitActionExpansion(action, base) {
|
|
|
1021
1024
|
return "Commit, push, then `gh pr create --web -R <origin-owner/name>`.";
|
|
1022
1025
|
case "resolve-conflicts":
|
|
1023
1026
|
return `Fetch the PR base${base ? ` (\`${base}\`)` : ""}, merge it into this branch, resolve conflicts carefully, then commit and push until the PR is mergeable.`;
|
|
1027
|
+
case "ready-for-review":
|
|
1028
|
+
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.";
|
|
1024
1029
|
case "merge":
|
|
1025
1030
|
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.";
|
|
1026
1031
|
}
|
|
@@ -3555,7 +3560,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3555
3560
|
let sourceIsFork = false;
|
|
3556
3561
|
if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
|
|
3557
3562
|
if (isAbleTimeConnected() && getIssueSource() === "abletime") {
|
|
3558
|
-
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-
|
|
3563
|
+
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-BFIDZR3O.js");
|
|
3559
3564
|
const task = await ensureAbleTimeTask({
|
|
3560
3565
|
title: title?.trim() || "Untitled work",
|
|
3561
3566
|
description: input.prompt?.trim() || void 0
|
|
@@ -4063,7 +4068,7 @@ async function adoptThread(input) {
|
|
|
4063
4068
|
messages: input.messages ?? []
|
|
4064
4069
|
});
|
|
4065
4070
|
writeThread(thread);
|
|
4066
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
4071
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-DR4UNOQC.js");
|
|
4067
4072
|
await ensureWorkspace2(repoPath);
|
|
4068
4073
|
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
|
|
4069
4074
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
@@ -5844,7 +5849,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
5844
5849
|
);
|
|
5845
5850
|
}
|
|
5846
5851
|
lines.push(
|
|
5847
|
-
'- 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.'
|
|
5852
|
+
'- 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.'
|
|
5848
5853
|
);
|
|
5849
5854
|
lines.push("");
|
|
5850
5855
|
lines.push(formatProcessGuideDirective({ worktreePath: thread.worktreePath }));
|
|
@@ -6339,7 +6344,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
6339
6344
|
${prompt}`;
|
|
6340
6345
|
}
|
|
6341
6346
|
async function defaultDeps() {
|
|
6342
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
6347
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-2KZD7N4X.js");
|
|
6343
6348
|
const orch = getOrchestrator2();
|
|
6344
6349
|
return {
|
|
6345
6350
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -8257,7 +8262,7 @@ var Orchestrator = class {
|
|
|
8257
8262
|
"ask_git targets a worktree agent thread (not the orchestrator). Pass a child/worktree thread ref."
|
|
8258
8263
|
);
|
|
8259
8264
|
}
|
|
8260
|
-
if (action === "merge" && !thread.prUrl) {
|
|
8265
|
+
if ((action === "merge" || action === "ready-for-review") && !thread.prUrl) {
|
|
8261
8266
|
throw new Error(
|
|
8262
8267
|
"No pull request linked. Ask the worktree agent to open a draft PR first (ask_git create-draft)."
|
|
8263
8268
|
);
|
|
@@ -8425,7 +8430,7 @@ var Orchestrator = class {
|
|
|
8425
8430
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
8426
8431
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
8427
8432
|
try {
|
|
8428
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
8433
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-DR4UNOQC.js");
|
|
8429
8434
|
await ensureWorkspace2(thread.repoPath);
|
|
8430
8435
|
} catch {
|
|
8431
8436
|
}
|
|
@@ -3,17 +3,26 @@ var injected = null;
|
|
|
3
3
|
function setHttpFetchImpl(fetchImpl) {
|
|
4
4
|
injected = fetchImpl;
|
|
5
5
|
}
|
|
6
|
+
var TLS_ISSUER_RE = /UNABLE_TO_GET_ISSUER_CERT|UNABLE_TO_VERIFY_LEAF_SIGNATURE|SELF_SIGNED_CERT_IN_CHAIN/i;
|
|
7
|
+
var 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.";
|
|
8
|
+
function tlsIssuerHint(code, message) {
|
|
9
|
+
const text = `${code ?? ""} ${message}`;
|
|
10
|
+
return TLS_ISSUER_RE.test(text) ? TLS_ISSUER_HINT : "";
|
|
11
|
+
}
|
|
6
12
|
function formatFetchError(err, url) {
|
|
7
13
|
if (!(err instanceof Error)) return `${String(err)} (${url})`;
|
|
8
14
|
const cause = err.cause;
|
|
9
15
|
let detail = "";
|
|
16
|
+
let hint = tlsIssuerHint(void 0, err.message);
|
|
10
17
|
if (cause instanceof Error) {
|
|
11
18
|
const code = typeof cause.code === "string" ? cause.code : void 0;
|
|
12
19
|
detail = code ? ` [${code}: ${cause.message}]` : ` [${cause.message}]`;
|
|
20
|
+
hint = tlsIssuerHint(code, `${err.message} ${cause.message}`) || hint;
|
|
13
21
|
} else if (cause != null) {
|
|
14
22
|
detail = ` [${String(cause)}]`;
|
|
23
|
+
hint = tlsIssuerHint(void 0, String(cause)) || hint;
|
|
15
24
|
}
|
|
16
|
-
return `${err.message}${detail} (${url})`;
|
|
25
|
+
return `${err.message}${detail} (${url})${hint}`;
|
|
17
26
|
}
|
|
18
27
|
async function httpFetch(input, init) {
|
|
19
28
|
const url = typeof input === "string" ? input : input.href;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isOrchestratorThread
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3ZFGZ7RT.js";
|
|
4
4
|
import {
|
|
5
5
|
codexUnattendedGitConfigArgs,
|
|
6
6
|
mergeAgentGitAuthEnv,
|
|
@@ -12,10 +12,10 @@ import {
|
|
|
12
12
|
brightsyMcpServerName,
|
|
13
13
|
ensureCliTeamTracked,
|
|
14
14
|
ensureConnectedBrightsyTeamTokens
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-IEEAVWAP.js";
|
|
16
16
|
import {
|
|
17
17
|
loadBrightsyConfig
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-AN3THU7F.js";
|
|
19
19
|
import {
|
|
20
20
|
applyAgentRunnerHeapEnv,
|
|
21
21
|
applyNodeLaunch,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
packagedMcpStdioPath,
|
|
30
30
|
parseCursorRunnerLine,
|
|
31
31
|
resolveNodeLaunch
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-NQTKRAUF.js";
|
|
33
33
|
import {
|
|
34
34
|
claudeChromeEnabled,
|
|
35
35
|
isAbleTimeConnected,
|
|
@@ -1898,7 +1898,7 @@ var claudeAdapter = {
|
|
|
1898
1898
|
);
|
|
1899
1899
|
}
|
|
1900
1900
|
const mode = permissionMode(thread);
|
|
1901
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
1901
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-3HIWNQ3B.js");
|
|
1902
1902
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
1903
1903
|
const injectedServers = await buildInjectedMcpServers({
|
|
1904
1904
|
includeSideboard: true,
|
|
@@ -2684,6 +2684,9 @@ function resolveCursorApiKey() {
|
|
|
2684
2684
|
if (fromEnv) return fromEnv;
|
|
2685
2685
|
return (loadAppSettings().environment.CURSOR_API_KEY || "").trim();
|
|
2686
2686
|
}
|
|
2687
|
+
function isCursorApiKeyConfigured() {
|
|
2688
|
+
return Boolean(resolveCursorApiKey());
|
|
2689
|
+
}
|
|
2687
2690
|
function isCursorAutoModel(model) {
|
|
2688
2691
|
const id = (model ?? "").trim().toLowerCase();
|
|
2689
2692
|
return !id || id === "default" || id === "auto";
|
|
@@ -3700,6 +3703,7 @@ export {
|
|
|
3700
3703
|
userMcpNamesToDisable,
|
|
3701
3704
|
listCodexModels,
|
|
3702
3705
|
codexAdapter,
|
|
3706
|
+
isCursorApiKeyConfigured,
|
|
3703
3707
|
isCursorAutoModel,
|
|
3704
3708
|
resolveCursorModelId,
|
|
3705
3709
|
listCursorModels,
|
|
@@ -2,6 +2,9 @@ import {
|
|
|
2
2
|
isElectronLikeCommand,
|
|
3
3
|
wrapElectronAsNodeLaunch
|
|
4
4
|
} from "./chunk-4TR3HZFT.js";
|
|
5
|
+
import {
|
|
6
|
+
appDataDir
|
|
7
|
+
} from "./chunk-EFVFB2AH.js";
|
|
5
8
|
import {
|
|
6
9
|
run
|
|
7
10
|
} from "./chunk-UFHNSFAS.js";
|
|
@@ -301,14 +304,139 @@ function formatTurnExitError(exitCode, stderrSummary) {
|
|
|
301
304
|
return `exit ${code}: ${detail}`;
|
|
302
305
|
}
|
|
303
306
|
|
|
307
|
+
// src/http/system-ca.ts
|
|
308
|
+
import { spawnSync } from "child_process";
|
|
309
|
+
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
|
310
|
+
import { dirname, join } from "path";
|
|
311
|
+
import tls from "tls";
|
|
312
|
+
var NODE_USE_SYSTEM_CA = "NODE_USE_SYSTEM_CA";
|
|
313
|
+
var NODE_EXTRA_CA_CERTS = "NODE_EXTRA_CA_CERTS";
|
|
314
|
+
var BUNDLE_NAME = "system-ca.pem";
|
|
315
|
+
var BUNDLE_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
316
|
+
var LINUX_CA_FILES = [
|
|
317
|
+
"/etc/ssl/certs/ca-certificates.crt",
|
|
318
|
+
"/etc/pki/tls/certs/ca-bundle.crt",
|
|
319
|
+
"/etc/ssl/ca-bundle.pem",
|
|
320
|
+
"/etc/ssl/cert.pem"
|
|
321
|
+
];
|
|
322
|
+
var PEM_CERT_RE = /-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g;
|
|
323
|
+
function splitPemCertificates(pem) {
|
|
324
|
+
return pem.match(PEM_CERT_RE) ?? [];
|
|
325
|
+
}
|
|
326
|
+
function readExistingFile(path) {
|
|
327
|
+
try {
|
|
328
|
+
return existsSync(path) ? readFileSync(path, "utf8") : "";
|
|
329
|
+
} catch {
|
|
330
|
+
return "";
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
function darwinKeychainPem(spawn) {
|
|
334
|
+
const result = spawn("/usr/bin/security", ["find-certificate", "-a", "-p"], {
|
|
335
|
+
encoding: "utf8",
|
|
336
|
+
maxBuffer: 32 * 1024 * 1024,
|
|
337
|
+
timeout: 15e3
|
|
338
|
+
});
|
|
339
|
+
if (result.status !== 0) return "";
|
|
340
|
+
return typeof result.stdout === "string" ? result.stdout : "";
|
|
341
|
+
}
|
|
342
|
+
function linuxSystemCaPem() {
|
|
343
|
+
for (const path of LINUX_CA_FILES) {
|
|
344
|
+
const pem = readExistingFile(path);
|
|
345
|
+
if (splitPemCertificates(pem).length > 0) return pem;
|
|
346
|
+
}
|
|
347
|
+
return "";
|
|
348
|
+
}
|
|
349
|
+
function collectSystemCaPem(io = {}) {
|
|
350
|
+
const platform = io.platform ?? process.platform;
|
|
351
|
+
if (platform === "darwin") {
|
|
352
|
+
return darwinKeychainPem(io.spawn ?? spawnSync);
|
|
353
|
+
}
|
|
354
|
+
if (platform === "linux") {
|
|
355
|
+
return linuxSystemCaPem();
|
|
356
|
+
}
|
|
357
|
+
return "";
|
|
358
|
+
}
|
|
359
|
+
function systemCaBundlePath(io = {}) {
|
|
360
|
+
return join((io.appData ?? appDataDir)(), BUNDLE_NAME);
|
|
361
|
+
}
|
|
362
|
+
function bundleIsFresh(path, now) {
|
|
363
|
+
try {
|
|
364
|
+
if (!existsSync(path)) return false;
|
|
365
|
+
if (splitPemCertificates(readFileSync(path, "utf8")).length === 0) return false;
|
|
366
|
+
return now - statSync(path).mtimeMs < BUNDLE_MAX_AGE_MS;
|
|
367
|
+
} catch {
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
function materializeSystemCaBundle(io = {}) {
|
|
372
|
+
const inherited = process.env.NODE_EXTRA_CA_CERTS?.trim();
|
|
373
|
+
if (inherited && splitPemCertificates(readExistingFile(inherited)).length > 0) {
|
|
374
|
+
return inherited;
|
|
375
|
+
}
|
|
376
|
+
const platform = io.platform ?? process.platform;
|
|
377
|
+
if (platform === "linux") {
|
|
378
|
+
for (const path of LINUX_CA_FILES) {
|
|
379
|
+
if (splitPemCertificates(readExistingFile(path)).length > 0) return path;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
const dest = systemCaBundlePath(io);
|
|
383
|
+
const now = (io.now ?? Date.now)();
|
|
384
|
+
if (bundleIsFresh(dest, now)) return dest;
|
|
385
|
+
const pem = collectSystemCaPem(io);
|
|
386
|
+
if (splitPemCertificates(pem).length === 0) {
|
|
387
|
+
return existsSync(dest) && splitPemCertificates(readExistingFile(dest)).length > 0 ? dest : void 0;
|
|
388
|
+
}
|
|
389
|
+
try {
|
|
390
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
391
|
+
writeFileSync(dest, pem.endsWith("\n") ? pem : `${pem}
|
|
392
|
+
`, { mode: 384 });
|
|
393
|
+
return dest;
|
|
394
|
+
} catch {
|
|
395
|
+
return void 0;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
function applySystemCaEnv(env) {
|
|
399
|
+
if (!String(env[NODE_USE_SYSTEM_CA] ?? "").trim()) {
|
|
400
|
+
env[NODE_USE_SYSTEM_CA] = "1";
|
|
401
|
+
}
|
|
402
|
+
if (String(env[NODE_EXTRA_CA_CERTS] ?? "").trim()) return;
|
|
403
|
+
const inherited = process.env.NODE_EXTRA_CA_CERTS?.trim();
|
|
404
|
+
if (inherited) env[NODE_EXTRA_CA_CERTS] = inherited;
|
|
405
|
+
}
|
|
406
|
+
function extraCertsFromBundle() {
|
|
407
|
+
const path = process.env.NODE_EXTRA_CA_CERTS?.trim();
|
|
408
|
+
if (path) return splitPemCertificates(readExistingFile(path));
|
|
409
|
+
const dest = systemCaBundlePath();
|
|
410
|
+
return splitPemCertificates(readExistingFile(dest));
|
|
411
|
+
}
|
|
412
|
+
function trustSystemCertificates(io = {}) {
|
|
413
|
+
try {
|
|
414
|
+
const api = tls;
|
|
415
|
+
if (typeof api.getCACertificates !== "function" || typeof api.setDefaultCACertificates !== "function") {
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
const current = api.getCACertificates("default");
|
|
419
|
+
const system = api.getCACertificates("system");
|
|
420
|
+
let extra = extraCertsFromBundle();
|
|
421
|
+
if (system.length === 0 && extra.length === 0) {
|
|
422
|
+
extra = splitPemCertificates(collectSystemCaPem(io));
|
|
423
|
+
}
|
|
424
|
+
if (system.length === 0 && extra.length === 0) return false;
|
|
425
|
+
api.setDefaultCACertificates([...current, ...system, ...extra]);
|
|
426
|
+
return true;
|
|
427
|
+
} catch {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
304
432
|
// src/agents/node-launch.ts
|
|
305
|
-
import { existsSync as
|
|
433
|
+
import { existsSync as existsSync3, readdirSync, realpathSync } from "fs";
|
|
306
434
|
import { homedir } from "os";
|
|
307
|
-
import { join as
|
|
435
|
+
import { join as join3 } from "path";
|
|
308
436
|
|
|
309
437
|
// src/agents/packaged-runtime.ts
|
|
310
|
-
import { existsSync } from "fs";
|
|
311
|
-
import { join } from "path";
|
|
438
|
+
import { existsSync as existsSync2 } from "fs";
|
|
439
|
+
import { join as join2 } from "path";
|
|
312
440
|
function electronResourcesPath() {
|
|
313
441
|
const resources = process.resourcesPath;
|
|
314
442
|
if (typeof resources !== "string" || !resources) return null;
|
|
@@ -317,36 +445,36 @@ function electronResourcesPath() {
|
|
|
317
445
|
function packagedCursorRuntimeDir() {
|
|
318
446
|
const resources = electronResourcesPath();
|
|
319
447
|
if (!resources) return null;
|
|
320
|
-
const dir =
|
|
321
|
-
if (!
|
|
448
|
+
const dir = join2(resources, "cursor-runtime");
|
|
449
|
+
if (!existsSync2(join2(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
|
|
322
450
|
return dir;
|
|
323
451
|
}
|
|
324
452
|
function packagedCursorRunnerPath() {
|
|
325
453
|
const dir = packagedCursorRuntimeDir();
|
|
326
|
-
return dir ?
|
|
454
|
+
return dir ? join2(dir, "core-dist", "agents", "cursor-runner.js") : null;
|
|
327
455
|
}
|
|
328
456
|
function packagedMcpDir() {
|
|
329
457
|
const resources = electronResourcesPath();
|
|
330
458
|
if (!resources) return null;
|
|
331
|
-
const dir =
|
|
332
|
-
if (!
|
|
459
|
+
const dir = join2(resources, "sideboard-mcp");
|
|
460
|
+
if (!existsSync2(join2(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
|
|
333
461
|
return dir;
|
|
334
462
|
}
|
|
335
463
|
function packagedMcpStdioPath() {
|
|
336
464
|
const dir = packagedMcpDir();
|
|
337
|
-
return dir ?
|
|
465
|
+
return dir ? join2(dir, "core-dist", "mcp", "run-stdio.js") : null;
|
|
338
466
|
}
|
|
339
467
|
function packagedBundledNodePath() {
|
|
340
468
|
const resources = electronResourcesPath();
|
|
341
469
|
if (!resources) return null;
|
|
342
|
-
const bin =
|
|
343
|
-
if (!
|
|
470
|
+
const bin = join2(resources, "node", "bin", "node");
|
|
471
|
+
if (!existsSync2(bin)) return null;
|
|
344
472
|
return bin;
|
|
345
473
|
}
|
|
346
474
|
function packagedCursorRipgrepCandidate(platformPkg, binName) {
|
|
347
475
|
const dir = packagedCursorRuntimeDir();
|
|
348
476
|
if (!dir) return null;
|
|
349
|
-
return
|
|
477
|
+
return join2(dir, "node_modules", platformPkg, "bin", binName);
|
|
350
478
|
}
|
|
351
479
|
|
|
352
480
|
// src/agents/node-launch.ts
|
|
@@ -367,6 +495,7 @@ function applyAgentRunnerHeapEnv(env) {
|
|
|
367
495
|
env.NODE_OPTIONS,
|
|
368
496
|
AGENT_RUNNER_MAX_OLD_SPACE_MB
|
|
369
497
|
);
|
|
498
|
+
applySystemCaEnv(env);
|
|
370
499
|
}
|
|
371
500
|
function envWithAgentHeap(env) {
|
|
372
501
|
const next = { ...env };
|
|
@@ -381,7 +510,7 @@ function unpackedAsarPath(filePath) {
|
|
|
381
510
|
if (!isAsarPath(filePath)) return null;
|
|
382
511
|
const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
|
|
383
512
|
if (unpacked === filePath) return null;
|
|
384
|
-
return
|
|
513
|
+
return existsSync3(unpacked) ? unpacked : null;
|
|
385
514
|
}
|
|
386
515
|
function nodeReadableScriptPath(scriptPath) {
|
|
387
516
|
return unpackedAsarPath(scriptPath) ?? scriptPath;
|
|
@@ -422,7 +551,7 @@ function pickPreferredNode(candidates) {
|
|
|
422
551
|
return best;
|
|
423
552
|
}
|
|
424
553
|
function versionDirNodeBins(root, toBin) {
|
|
425
|
-
if (!
|
|
554
|
+
if (!existsSync3(root)) return [];
|
|
426
555
|
try {
|
|
427
556
|
return readdirSync(root).map(toBin);
|
|
428
557
|
} catch {
|
|
@@ -431,28 +560,28 @@ function versionDirNodeBins(root, toBin) {
|
|
|
431
560
|
}
|
|
432
561
|
function defaultNodeBinCandidates(home = homedir()) {
|
|
433
562
|
const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
|
|
434
|
-
(prefix) => PREFERRED_LTS_MAJORS.map((major) =>
|
|
563
|
+
(prefix) => PREFERRED_LTS_MAJORS.map((major) => join3(prefix, "opt", `node@${major}`, "bin", "node"))
|
|
435
564
|
);
|
|
436
565
|
return [
|
|
437
566
|
...kegs,
|
|
438
567
|
"/opt/homebrew/bin/node",
|
|
439
568
|
"/usr/local/bin/node",
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
569
|
+
join3(home, ".local/share/fnm/aliases/default/bin/node"),
|
|
570
|
+
join3(home, ".nvm/current/bin/node"),
|
|
571
|
+
join3(home, ".volta/bin/node"),
|
|
572
|
+
join3(home, ".asdf/shims/node"),
|
|
573
|
+
join3(home, ".local/share/mise/shims/node"),
|
|
445
574
|
...versionDirNodeBins(
|
|
446
|
-
|
|
447
|
-
(name) =>
|
|
575
|
+
join3(home, ".nvm", "versions", "node"),
|
|
576
|
+
(name) => join3(home, ".nvm", "versions", "node", name, "bin", "node")
|
|
448
577
|
),
|
|
449
578
|
...versionDirNodeBins(
|
|
450
|
-
|
|
451
|
-
(name) =>
|
|
579
|
+
join3(home, ".local/share/fnm", "node-versions"),
|
|
580
|
+
(name) => join3(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
|
|
452
581
|
),
|
|
453
582
|
...versionDirNodeBins(
|
|
454
|
-
|
|
455
|
-
(name) =>
|
|
583
|
+
join3(home, ".volta", "tools", "image", "node"),
|
|
584
|
+
(name) => join3(home, ".volta", "tools", "image", "node", name, "bin", "node")
|
|
456
585
|
)
|
|
457
586
|
];
|
|
458
587
|
}
|
|
@@ -461,7 +590,7 @@ function uniqueExistingNodeBins(paths) {
|
|
|
461
590
|
const out = [];
|
|
462
591
|
for (const raw of paths) {
|
|
463
592
|
const p = raw.trim();
|
|
464
|
-
if (!p || !
|
|
593
|
+
if (!p || !existsSync3(p) || isElectronLikeCommand(p)) continue;
|
|
465
594
|
let key = p;
|
|
466
595
|
try {
|
|
467
596
|
key = realpathSync(p);
|
|
@@ -854,9 +983,9 @@ function parseCursorRunnerLine(line) {
|
|
|
854
983
|
}
|
|
855
984
|
|
|
856
985
|
// src/agents/cursor-ripgrep.ts
|
|
857
|
-
import { existsSync as
|
|
986
|
+
import { existsSync as existsSync4 } from "fs";
|
|
858
987
|
import { createRequire } from "module";
|
|
859
|
-
import { dirname, isAbsolute, join as
|
|
988
|
+
import { dirname as dirname2, isAbsolute, join as join4, parse, resolve as resolvePath } from "path";
|
|
860
989
|
var RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
861
990
|
function rgBinaryName() {
|
|
862
991
|
return process.platform === "win32" ? "rg.exe" : "rg";
|
|
@@ -868,19 +997,19 @@ function usableRipgrepPath(candidate) {
|
|
|
868
997
|
const raw = candidate?.trim();
|
|
869
998
|
if (!raw || !isAbsolute(raw)) return null;
|
|
870
999
|
const readable = nodeReadableScriptPath(raw);
|
|
871
|
-
if (!
|
|
1000
|
+
if (!existsSync4(readable) || isAsarPath(readable)) return null;
|
|
872
1001
|
return readable;
|
|
873
1002
|
}
|
|
874
1003
|
function walkForBundledRipgrep(startFile) {
|
|
875
1004
|
if (!startFile) return null;
|
|
876
1005
|
const pkg = platformRipgrepPackage();
|
|
877
1006
|
const name = rgBinaryName();
|
|
878
|
-
let dir =
|
|
1007
|
+
let dir = dirname2(resolvePath(startFile));
|
|
879
1008
|
const root = parse(dir).root;
|
|
880
1009
|
while (dir !== root) {
|
|
881
|
-
const hit = usableRipgrepPath(
|
|
1010
|
+
const hit = usableRipgrepPath(join4(dir, "node_modules", pkg, "bin", name));
|
|
882
1011
|
if (hit) return hit;
|
|
883
|
-
const next =
|
|
1012
|
+
const next = dirname2(dir);
|
|
884
1013
|
if (next === dir) break;
|
|
885
1014
|
dir = next;
|
|
886
1015
|
}
|
|
@@ -890,7 +1019,7 @@ function requireResolveBundledRipgrep(fromFile) {
|
|
|
890
1019
|
try {
|
|
891
1020
|
const req = createRequire(fromFile);
|
|
892
1021
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
893
|
-
return usableRipgrepPath(
|
|
1022
|
+
return usableRipgrepPath(join4(dirname2(pkgJson), "bin", rgBinaryName()));
|
|
894
1023
|
} catch {
|
|
895
1024
|
return null;
|
|
896
1025
|
}
|
|
@@ -934,6 +1063,9 @@ export {
|
|
|
934
1063
|
shouldFeedErrorBackToAgent,
|
|
935
1064
|
formatAgentErrorContinuePrompt,
|
|
936
1065
|
formatTurnExitError,
|
|
1066
|
+
materializeSystemCaBundle,
|
|
1067
|
+
applySystemCaEnv,
|
|
1068
|
+
trustSystemCertificates,
|
|
937
1069
|
packagedCursorRunnerPath,
|
|
938
1070
|
packagedMcpDir,
|
|
939
1071
|
packagedMcpStdioPath,
|
|
@@ -3,17 +3,26 @@
|
|
|
3
3
|
|
|
4
4
|
// src/http/fetch.ts
|
|
5
5
|
var injected = null;
|
|
6
|
+
var TLS_ISSUER_RE = /UNABLE_TO_GET_ISSUER_CERT|UNABLE_TO_VERIFY_LEAF_SIGNATURE|SELF_SIGNED_CERT_IN_CHAIN/i;
|
|
7
|
+
var 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.";
|
|
8
|
+
function tlsIssuerHint(code, message) {
|
|
9
|
+
const text = `${code ?? ""} ${message}`;
|
|
10
|
+
return TLS_ISSUER_RE.test(text) ? TLS_ISSUER_HINT : "";
|
|
11
|
+
}
|
|
6
12
|
function formatFetchError(err, url) {
|
|
7
13
|
if (!(err instanceof Error)) return `${String(err)} (${url})`;
|
|
8
14
|
const cause = err.cause;
|
|
9
15
|
let detail = "";
|
|
16
|
+
let hint = tlsIssuerHint(void 0, err.message);
|
|
10
17
|
if (cause instanceof Error) {
|
|
11
18
|
const code = typeof cause.code === "string" ? cause.code : void 0;
|
|
12
19
|
detail = code ? ` [${code}: ${cause.message}]` : ` [${cause.message}]`;
|
|
20
|
+
hint = tlsIssuerHint(code, `${err.message} ${cause.message}`) || hint;
|
|
13
21
|
} else if (cause != null) {
|
|
14
22
|
detail = ` [${String(cause)}]`;
|
|
23
|
+
hint = tlsIssuerHint(void 0, String(cause)) || hint;
|
|
15
24
|
}
|
|
16
|
-
return `${err.message}${detail} (${url})`;
|
|
25
|
+
return `${err.message}${detail} (${url})${hint}`;
|
|
17
26
|
}
|
|
18
27
|
async function httpFetch(input, init) {
|
|
19
28
|
const url = typeof input === "string" ? input : input.href;
|