@sideboard-ai/core 0.1.77 → 0.1.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agents-XJV6J3K2.js → agents-EWPHOM6Y.js} +6 -6
- package/dist/{agents-LKUHPPEQ.js → agents-GRAPUXWW.js} +5 -5
- package/dist/{app-settings-3TLA2EJ7.js → app-settings-6IOQYGBK.js} +7 -1
- package/dist/{app-settings-P42Z3VOB.js → app-settings-NILNWNNQ.js} +7 -1
- package/dist/{chunk-VERLUKN2.js → chunk-5LXWTU3J.js} +6 -6
- package/dist/{chunk-2ZIPJRJE.js → chunk-5VTWBI3I.js} +2 -2
- package/dist/{chunk-GWTLKXXP.js → chunk-6T2SKGCS.js} +3 -3
- package/dist/{chunk-OE7YBB5X.js → chunk-FUUVPN4A.js} +108 -3
- package/dist/{chunk-EEKSZTMU.js → chunk-HCGEFU3J.js} +5 -5
- package/dist/{chunk-XJNCWYFR.js → chunk-HSLQXL6M.js} +3 -3
- package/dist/{chunk-W7YOTDVO.js → chunk-IFPN6TER.js} +47 -2
- package/dist/{chunk-2FJI5JXX.js → chunk-P33ZQ7ZC.js} +3 -3
- package/dist/{chunk-75U65MBE.js → chunk-PW5YHHP3.js} +2 -2
- package/dist/{chunk-QD37IILI.js → chunk-SHCR6RPU.js} +3 -3
- package/dist/{chunk-PTJJIQK7.js → chunk-XKNBSYA7.js} +47 -2
- package/dist/{chunk-MF2YMEGD.js → chunk-YVVXWWCC.js} +110 -3
- package/dist/{coordinator-prompt-LLFJUO2R.js → coordinator-prompt-2OVON2LQ.js} +4 -4
- package/dist/{coordinator-prompt-MRCMMRSF.js → coordinator-prompt-K2R34A5T.js} +3 -3
- package/dist/{global-workspace-TWHMYLTZ.js → global-workspace-RI367AM6.js} +4 -4
- package/dist/{global-workspace-YNMNO4CL.js → global-workspace-VG44RZUH.js} +5 -5
- package/dist/index.cjs +500 -178
- package/dist/index.d.cts +83 -8
- package/dist/index.d.ts +83 -8
- package/dist/index.js +344 -179
- package/dist/mcp/run-stdio.cjs +2439 -2228
- package/dist/mcp/run-stdio.js +156 -100
- package/dist/{workspaces-GQ4XKBD3.js → workspaces-BQWQEZWE.js} +5 -5
- package/dist/{workspaces-O3U5BENH.js → workspaces-TYPJNUSM.js} +6 -6
- package/dist/{worktree-VOCH3WS3.js → worktree-5VLLFI5W.js} +5 -1
- package/dist/{worktree-KWXHMKRN.js → worktree-UNSOCYZU.js} +5 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -79,11 +79,11 @@ var init_thinking_effort = __esm({
|
|
|
79
79
|
});
|
|
80
80
|
|
|
81
81
|
// src/hook/settings.ts
|
|
82
|
-
function expandHome(
|
|
83
|
-
if (
|
|
84
|
-
return (0, import_node_path.join)((0, import_node_os.homedir)(),
|
|
82
|
+
function expandHome(path2) {
|
|
83
|
+
if (path2.startsWith("~/") || path2 === "~") {
|
|
84
|
+
return (0, import_node_path.join)((0, import_node_os.homedir)(), path2.slice(2));
|
|
85
85
|
}
|
|
86
|
-
return
|
|
86
|
+
return path2;
|
|
87
87
|
}
|
|
88
88
|
function parseAvailableIn(raw) {
|
|
89
89
|
if (!Array.isArray(raw)) return void 0;
|
|
@@ -93,9 +93,9 @@ function parseAvailableIn(raw) {
|
|
|
93
93
|
}
|
|
94
94
|
return out.length ? out : void 0;
|
|
95
95
|
}
|
|
96
|
-
function parseSettingsFile(
|
|
97
|
-
if (!(0, import_node_fs.existsSync)(
|
|
98
|
-
const raw = (0, import_node_fs.readFileSync)(
|
|
96
|
+
function parseSettingsFile(path2, source) {
|
|
97
|
+
if (!(0, import_node_fs.existsSync)(path2)) return null;
|
|
98
|
+
const raw = (0, import_node_fs.readFileSync)(path2, "utf8");
|
|
99
99
|
const data = (0, import_smol_toml.parse)(raw);
|
|
100
100
|
const scripts = data.scripts ?? {};
|
|
101
101
|
const setup = typeof scripts.setup === "string" ? scripts.setup : void 0;
|
|
@@ -386,14 +386,14 @@ var init_paths = __esm({
|
|
|
386
386
|
});
|
|
387
387
|
|
|
388
388
|
// src/store/private-file.ts
|
|
389
|
-
function writePrivateFile(
|
|
390
|
-
(0, import_node_fs3.mkdirSync)((0, import_node_path4.dirname)(
|
|
391
|
-
(0, import_node_fs3.writeFileSync)(
|
|
392
|
-
chmodOwnerOnly(
|
|
389
|
+
function writePrivateFile(path2, contents) {
|
|
390
|
+
(0, import_node_fs3.mkdirSync)((0, import_node_path4.dirname)(path2), { recursive: true });
|
|
391
|
+
(0, import_node_fs3.writeFileSync)(path2, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
|
|
392
|
+
chmodOwnerOnly(path2);
|
|
393
393
|
}
|
|
394
|
-
function chmodOwnerOnly(
|
|
394
|
+
function chmodOwnerOnly(path2) {
|
|
395
395
|
try {
|
|
396
|
-
(0, import_node_fs3.chmodSync)(
|
|
396
|
+
(0, import_node_fs3.chmodSync)(path2, PRIVATE_FILE_MODE);
|
|
397
397
|
} catch {
|
|
398
398
|
}
|
|
399
399
|
}
|
|
@@ -493,12 +493,12 @@ function decryptEnvelope(envelope, key) {
|
|
|
493
493
|
]);
|
|
494
494
|
return JSON.parse(plaintext.toString("utf8"));
|
|
495
495
|
}
|
|
496
|
-
function readSecureJson(
|
|
497
|
-
if (!(0, import_node_fs4.existsSync)(
|
|
498
|
-
chmodOwnerOnly(
|
|
496
|
+
function readSecureJson(path2) {
|
|
497
|
+
if (!(0, import_node_fs4.existsSync)(path2)) return null;
|
|
498
|
+
chmodOwnerOnly(path2);
|
|
499
499
|
let parsed;
|
|
500
500
|
try {
|
|
501
|
-
parsed = JSON.parse((0, import_node_fs4.readFileSync)(
|
|
501
|
+
parsed = JSON.parse((0, import_node_fs4.readFileSync)(path2, "utf8"));
|
|
502
502
|
} catch {
|
|
503
503
|
return null;
|
|
504
504
|
}
|
|
@@ -511,24 +511,24 @@ function readSecureJson(path) {
|
|
|
511
511
|
}
|
|
512
512
|
return decryptEnvelope(parsed, key);
|
|
513
513
|
}
|
|
514
|
-
function writeSecureJson(
|
|
514
|
+
function writeSecureJson(path2, value) {
|
|
515
515
|
const key = resolveVaultKey();
|
|
516
516
|
const body = key ? encryptJson(value, key) : value;
|
|
517
|
-
writePrivateFile(
|
|
517
|
+
writePrivateFile(path2, `${JSON.stringify(body, null, 2)}
|
|
518
518
|
`);
|
|
519
519
|
}
|
|
520
|
-
function isSecureFileEncrypted(
|
|
521
|
-
if (!(0, import_node_fs4.existsSync)(
|
|
520
|
+
function isSecureFileEncrypted(path2) {
|
|
521
|
+
if (!(0, import_node_fs4.existsSync)(path2)) return false;
|
|
522
522
|
try {
|
|
523
|
-
return isEnvelope(JSON.parse((0, import_node_fs4.readFileSync)(
|
|
523
|
+
return isEnvelope(JSON.parse((0, import_node_fs4.readFileSync)(path2, "utf8")));
|
|
524
524
|
} catch {
|
|
525
525
|
return false;
|
|
526
526
|
}
|
|
527
527
|
}
|
|
528
|
-
function secureFileUnlocksWith(
|
|
529
|
-
if (!(0, import_node_fs4.existsSync)(
|
|
528
|
+
function secureFileUnlocksWith(path2, key) {
|
|
529
|
+
if (!(0, import_node_fs4.existsSync)(path2) || key.length !== 32) return true;
|
|
530
530
|
try {
|
|
531
|
-
const parsed = JSON.parse((0, import_node_fs4.readFileSync)(
|
|
531
|
+
const parsed = JSON.parse((0, import_node_fs4.readFileSync)(path2, "utf8"));
|
|
532
532
|
if (!isEnvelope(parsed)) return true;
|
|
533
533
|
decryptEnvelope(parsed, key);
|
|
534
534
|
return true;
|
|
@@ -583,6 +583,9 @@ function normalizeVault(raw) {
|
|
|
583
583
|
if (typeof raw.slackAppToken === "string" && raw.slackAppToken.trim()) {
|
|
584
584
|
out.slackAppToken = raw.slackAppToken.trim();
|
|
585
585
|
}
|
|
586
|
+
if (typeof raw.githubPat === "string" && raw.githubPat.trim()) {
|
|
587
|
+
out.githubPat = raw.githubPat.trim();
|
|
588
|
+
}
|
|
586
589
|
if (raw.environment && typeof raw.environment === "object") {
|
|
587
590
|
const environment = {};
|
|
588
591
|
for (const [key, value] of Object.entries(raw.environment)) {
|
|
@@ -607,6 +610,7 @@ var init_secret_vault = __esm({
|
|
|
607
610
|
// src/store/app-settings.ts
|
|
608
611
|
var app_settings_exports = {};
|
|
609
612
|
__export(app_settings_exports, {
|
|
613
|
+
GITHUB_GIT_AUTH_MODES: () => GITHUB_GIT_AUTH_MODES,
|
|
610
614
|
HARNESS_ENV_KEYS: () => HARNESS_ENV_KEYS,
|
|
611
615
|
appSettingsPath: () => appSettingsPath,
|
|
612
616
|
applyAppEnvironment: () => applyAppEnvironment,
|
|
@@ -630,6 +634,8 @@ __export(app_settings_exports, {
|
|
|
630
634
|
getDefaultEffort: () => getDefaultEffort,
|
|
631
635
|
getDefaultFast: () => getDefaultFast,
|
|
632
636
|
getDefaultModel: () => getDefaultModel,
|
|
637
|
+
getGithubGitAuthMode: () => getGithubGitAuthMode,
|
|
638
|
+
getGithubPat: () => getGithubPat,
|
|
633
639
|
getIssueSource: () => getIssueSource,
|
|
634
640
|
getLinearApiKey: () => getLinearApiKey,
|
|
635
641
|
harnessEnvKey: () => harnessEnvKey,
|
|
@@ -674,12 +680,14 @@ function toPublicAppSettings(settings) {
|
|
|
674
680
|
const integrations = { ...settings.integrations };
|
|
675
681
|
const slackClientSecret = integrations.slackClientSecret;
|
|
676
682
|
const slackAppToken = integrations.slackAppToken;
|
|
683
|
+
const githubPat = integrations.githubPat;
|
|
677
684
|
delete integrations.linearApiKey;
|
|
678
685
|
delete integrations.linearAccessToken;
|
|
679
686
|
delete integrations.linearRefreshToken;
|
|
680
687
|
delete integrations.linearClientSecret;
|
|
681
688
|
delete integrations.slackClientSecret;
|
|
682
689
|
delete integrations.slackAppToken;
|
|
690
|
+
delete integrations.githubPat;
|
|
683
691
|
return {
|
|
684
692
|
...settings,
|
|
685
693
|
environment,
|
|
@@ -688,7 +696,8 @@ function toPublicAppSettings(settings) {
|
|
|
688
696
|
hasLinearApiKey: hasLinearCredentials(settings.integrations),
|
|
689
697
|
hasLinearOAuth: hasLinearOAuth(settings.integrations),
|
|
690
698
|
hasSlackClientSecret: Boolean(slackClientSecret?.trim()),
|
|
691
|
-
hasSlackAppToken: Boolean(slackAppToken?.trim())
|
|
699
|
+
hasSlackAppToken: Boolean(slackAppToken?.trim()),
|
|
700
|
+
hasGithubPat: Boolean(githubPat?.trim())
|
|
692
701
|
}
|
|
693
702
|
};
|
|
694
703
|
}
|
|
@@ -703,8 +712,8 @@ function normalizeClaude(raw) {
|
|
|
703
712
|
const source = raw;
|
|
704
713
|
const out = {};
|
|
705
714
|
if (typeof source.executablePath === "string") {
|
|
706
|
-
const
|
|
707
|
-
if (
|
|
715
|
+
const path2 = source.executablePath.trim();
|
|
716
|
+
if (path2) out.executablePath = path2;
|
|
708
717
|
}
|
|
709
718
|
if (typeof source.chromeEnabled === "boolean") {
|
|
710
719
|
out.chromeEnabled = source.chromeEnabled;
|
|
@@ -716,8 +725,8 @@ function normalizeCliExecutable(raw) {
|
|
|
716
725
|
const source = raw;
|
|
717
726
|
const out = {};
|
|
718
727
|
if (typeof source.executablePath === "string") {
|
|
719
|
-
const
|
|
720
|
-
if (
|
|
728
|
+
const path2 = source.executablePath.trim();
|
|
729
|
+
if (path2) out.executablePath = path2;
|
|
721
730
|
}
|
|
722
731
|
return out;
|
|
723
732
|
}
|
|
@@ -726,8 +735,8 @@ function normalizeBrightsy(raw) {
|
|
|
726
735
|
const source = raw;
|
|
727
736
|
const out = {};
|
|
728
737
|
if (typeof source.executablePath === "string") {
|
|
729
|
-
const
|
|
730
|
-
if (
|
|
738
|
+
const path2 = source.executablePath.trim();
|
|
739
|
+
if (path2) out.executablePath = path2;
|
|
731
740
|
}
|
|
732
741
|
if (typeof source.cloudConnectEnabled === "boolean") {
|
|
733
742
|
out.cloudConnectEnabled = source.cloudConnectEnabled;
|
|
@@ -804,6 +813,13 @@ function normalizeIntegrations(raw) {
|
|
|
804
813
|
const label = source.slackDeviceLabel.trim().slice(0, 64);
|
|
805
814
|
if (label) out.slackDeviceLabel = label;
|
|
806
815
|
}
|
|
816
|
+
if (typeof source.githubGitAuthMode === "string" && GIT_AUTH_MODES.has(source.githubGitAuthMode)) {
|
|
817
|
+
out.githubGitAuthMode = source.githubGitAuthMode;
|
|
818
|
+
}
|
|
819
|
+
if (typeof source.githubPat === "string") {
|
|
820
|
+
const pat = source.githubPat.trim();
|
|
821
|
+
if (pat) out.githubPat = pat;
|
|
822
|
+
}
|
|
807
823
|
return out;
|
|
808
824
|
}
|
|
809
825
|
function normalizeDefaults(raw) {
|
|
@@ -931,11 +947,11 @@ function normalizeSettings(raw) {
|
|
|
931
947
|
};
|
|
932
948
|
}
|
|
933
949
|
function readSettingsFile() {
|
|
934
|
-
const
|
|
935
|
-
if (!(0, import_node_fs5.existsSync)(
|
|
950
|
+
const path2 = appSettingsPath();
|
|
951
|
+
if (!(0, import_node_fs5.existsSync)(path2)) return { ...EMPTY_SETTINGS };
|
|
936
952
|
try {
|
|
937
|
-
chmodOwnerOnly(
|
|
938
|
-
const parsed = JSON.parse((0, import_node_fs5.readFileSync)(
|
|
953
|
+
chmodOwnerOnly(path2);
|
|
954
|
+
const parsed = JSON.parse((0, import_node_fs5.readFileSync)(path2, "utf8"));
|
|
939
955
|
return normalizeSettings(parsed);
|
|
940
956
|
} catch {
|
|
941
957
|
return { ...EMPTY_SETTINGS };
|
|
@@ -943,7 +959,7 @@ function readSettingsFile() {
|
|
|
943
959
|
}
|
|
944
960
|
function diskHoldsSecrets(disk) {
|
|
945
961
|
return Boolean(
|
|
946
|
-
disk.integrations.linearApiKey || disk.integrations.linearAccessToken || disk.integrations.linearRefreshToken || disk.integrations.linearClientSecret || disk.integrations.slackClientSecret || disk.integrations.slackAppToken || Object.keys(disk.environment).length > 0
|
|
962
|
+
disk.integrations.linearApiKey || disk.integrations.linearAccessToken || disk.integrations.linearRefreshToken || disk.integrations.linearClientSecret || disk.integrations.slackClientSecret || disk.integrations.slackAppToken || disk.integrations.githubPat || Object.keys(disk.environment).length > 0
|
|
947
963
|
);
|
|
948
964
|
}
|
|
949
965
|
function mergeVault(disk) {
|
|
@@ -968,6 +984,9 @@ function mergeVault(disk) {
|
|
|
968
984
|
if (vault.slackAppToken && !integrations.slackAppToken) {
|
|
969
985
|
integrations.slackAppToken = vault.slackAppToken;
|
|
970
986
|
}
|
|
987
|
+
if (vault.githubPat && !integrations.githubPat) {
|
|
988
|
+
integrations.githubPat = vault.githubPat;
|
|
989
|
+
}
|
|
971
990
|
return { ...disk, environment, integrations };
|
|
972
991
|
}
|
|
973
992
|
function persistSplit(settings) {
|
|
@@ -978,12 +997,14 @@ function persistSplit(settings) {
|
|
|
978
997
|
const linearClientSecret = integrations.linearClientSecret;
|
|
979
998
|
const slackClientSecret = integrations.slackClientSecret;
|
|
980
999
|
const slackAppToken = integrations.slackAppToken;
|
|
1000
|
+
const githubPat = integrations.githubPat;
|
|
981
1001
|
delete integrations.linearApiKey;
|
|
982
1002
|
delete integrations.linearAccessToken;
|
|
983
1003
|
delete integrations.linearRefreshToken;
|
|
984
1004
|
delete integrations.linearClientSecret;
|
|
985
1005
|
delete integrations.slackClientSecret;
|
|
986
1006
|
delete integrations.slackAppToken;
|
|
1007
|
+
delete integrations.githubPat;
|
|
987
1008
|
writePrivateFile(
|
|
988
1009
|
appSettingsPath(),
|
|
989
1010
|
`${JSON.stringify({ ...settings, environment: {}, integrations }, null, 2)}
|
|
@@ -996,6 +1017,7 @@ function persistSplit(settings) {
|
|
|
996
1017
|
linearClientSecret,
|
|
997
1018
|
slackClientSecret,
|
|
998
1019
|
slackAppToken,
|
|
1020
|
+
githubPat,
|
|
999
1021
|
environment: settings.environment
|
|
1000
1022
|
});
|
|
1001
1023
|
}
|
|
@@ -1161,6 +1183,20 @@ function updateIntegrationsSettings(patch) {
|
|
|
1161
1183
|
integrations.slackDeviceLabel = patch.slackDeviceLabel.trim().slice(0, 64);
|
|
1162
1184
|
}
|
|
1163
1185
|
}
|
|
1186
|
+
if ("githubGitAuthMode" in patch) {
|
|
1187
|
+
if (patch.githubGitAuthMode == null) {
|
|
1188
|
+
delete integrations.githubGitAuthMode;
|
|
1189
|
+
} else if (GIT_AUTH_MODES.has(patch.githubGitAuthMode)) {
|
|
1190
|
+
integrations.githubGitAuthMode = patch.githubGitAuthMode;
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
if ("githubPat" in patch) {
|
|
1194
|
+
if (patch.githubPat == null || patch.githubPat.trim() === "") {
|
|
1195
|
+
delete integrations.githubPat;
|
|
1196
|
+
} else {
|
|
1197
|
+
integrations.githubPat = patch.githubPat.trim();
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1164
1200
|
return saveAppSettings({ ...current, integrations });
|
|
1165
1201
|
}
|
|
1166
1202
|
function updateDefaultsSettings(patch) {
|
|
@@ -1268,6 +1304,13 @@ function disconnectLinearConnection() {
|
|
|
1268
1304
|
function getIssueSource(settings = loadAppSettings()) {
|
|
1269
1305
|
return settings.integrations.issueSource ?? "github";
|
|
1270
1306
|
}
|
|
1307
|
+
function getGithubGitAuthMode(settings = loadAppSettings()) {
|
|
1308
|
+
return settings.integrations.githubGitAuthMode ?? "auto";
|
|
1309
|
+
}
|
|
1310
|
+
function getGithubPat(settings = loadAppSettings()) {
|
|
1311
|
+
const pat = settings.integrations.githubPat?.trim();
|
|
1312
|
+
return pat || null;
|
|
1313
|
+
}
|
|
1271
1314
|
function resolveEffectiveIssueSource(settings = loadAppSettings()) {
|
|
1272
1315
|
const preferred = getIssueSource(settings);
|
|
1273
1316
|
if (preferred === "linear" && !isLinearConnected(settings)) return "github";
|
|
@@ -1468,7 +1511,7 @@ function childEnvWithAppSettings(extra) {
|
|
|
1468
1511
|
function harnessEnvKey(harness) {
|
|
1469
1512
|
return HARNESS_ENV_KEYS[harness];
|
|
1470
1513
|
}
|
|
1471
|
-
var import_node_crypto2, import_node_fs5, import_node_os3, import_node_path6, HARNESS_ENV_KEYS, DEFAULT_AGENTS, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
|
|
1514
|
+
var import_node_crypto2, import_node_fs5, import_node_os3, import_node_path6, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
|
|
1472
1515
|
var init_app_settings = __esm({
|
|
1473
1516
|
"src/store/app-settings.ts"() {
|
|
1474
1517
|
"use strict";
|
|
@@ -1494,6 +1537,7 @@ var init_app_settings = __esm({
|
|
|
1494
1537
|
"brightsy",
|
|
1495
1538
|
"cursor"
|
|
1496
1539
|
]);
|
|
1540
|
+
GITHUB_GIT_AUTH_MODES = ["auto", "gh", "ssh", "token"];
|
|
1497
1541
|
CLOUD_CONNECT_AGENTS = /* @__PURE__ */ new Set([
|
|
1498
1542
|
"claude",
|
|
1499
1543
|
"codex",
|
|
@@ -1501,6 +1545,7 @@ var init_app_settings = __esm({
|
|
|
1501
1545
|
"cursor"
|
|
1502
1546
|
]);
|
|
1503
1547
|
ISSUE_SOURCES = /* @__PURE__ */ new Set(["linear", "github"]);
|
|
1548
|
+
GIT_AUTH_MODES = new Set(GITHUB_GIT_AUTH_MODES);
|
|
1504
1549
|
EMPTY_SETTINGS = {
|
|
1505
1550
|
environment: {},
|
|
1506
1551
|
claude: {},
|
|
@@ -1567,10 +1612,10 @@ function uniqueIds(ids) {
|
|
|
1567
1612
|
return out;
|
|
1568
1613
|
}
|
|
1569
1614
|
function readHold() {
|
|
1570
|
-
const
|
|
1571
|
-
if (!(0, import_node_fs6.existsSync)(
|
|
1615
|
+
const path2 = caffeinateHoldPath();
|
|
1616
|
+
if (!(0, import_node_fs6.existsSync)(path2)) return null;
|
|
1572
1617
|
try {
|
|
1573
|
-
const parsed = JSON.parse((0, import_node_fs6.readFileSync)(
|
|
1618
|
+
const parsed = JSON.parse((0, import_node_fs6.readFileSync)(path2, "utf8"));
|
|
1574
1619
|
if (typeof parsed?.pid === "number" && parsed.pid > 0) {
|
|
1575
1620
|
return {
|
|
1576
1621
|
pid: parsed.pid,
|
|
@@ -1790,17 +1835,17 @@ async function withThreadLock(id, fn) {
|
|
|
1790
1835
|
}
|
|
1791
1836
|
}
|
|
1792
1837
|
function readThread(id) {
|
|
1793
|
-
const
|
|
1794
|
-
if (!(0, import_node_fs7.existsSync)(
|
|
1795
|
-
const raw = (0, import_node_fs7.readFileSync)(
|
|
1838
|
+
const path2 = threadFilePath(id);
|
|
1839
|
+
if (!(0, import_node_fs7.existsSync)(path2)) return null;
|
|
1840
|
+
const raw = (0, import_node_fs7.readFileSync)(path2, "utf8");
|
|
1796
1841
|
return normalizeThread(JSON.parse(raw));
|
|
1797
1842
|
}
|
|
1798
1843
|
function writeThread(thread) {
|
|
1799
|
-
const
|
|
1800
|
-
const tmp = `${
|
|
1844
|
+
const path2 = threadFilePath(idPath(thread.id));
|
|
1845
|
+
const tmp = `${path2}.${process.pid}.tmp`;
|
|
1801
1846
|
const next = { ...thread, updatedAt: nowIso() };
|
|
1802
1847
|
(0, import_node_fs7.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
|
|
1803
|
-
(0, import_node_fs7.renameSync)(tmp,
|
|
1848
|
+
(0, import_node_fs7.renameSync)(tmp, path2);
|
|
1804
1849
|
}
|
|
1805
1850
|
function idPath(id) {
|
|
1806
1851
|
return id;
|
|
@@ -1820,8 +1865,8 @@ function listThreads(opts) {
|
|
|
1820
1865
|
return threads.filter((t) => t.status !== "archived");
|
|
1821
1866
|
}
|
|
1822
1867
|
function deleteThreadRecord(id) {
|
|
1823
|
-
const
|
|
1824
|
-
if ((0, import_node_fs7.existsSync)(
|
|
1868
|
+
const path2 = threadFilePath(id);
|
|
1869
|
+
if ((0, import_node_fs7.existsSync)(path2)) (0, import_node_fs7.unlinkSync)(path2);
|
|
1825
1870
|
const lock = threadLockPath(id);
|
|
1826
1871
|
if ((0, import_node_fs7.existsSync)(lock)) {
|
|
1827
1872
|
try {
|
|
@@ -2820,6 +2865,80 @@ var init_gh_errors = __esm({
|
|
|
2820
2865
|
}
|
|
2821
2866
|
});
|
|
2822
2867
|
|
|
2868
|
+
// src/git/git-auth-mode.ts
|
|
2869
|
+
function appendIndexedGitConfig(existing, entries) {
|
|
2870
|
+
const start = Number.parseInt(String(existing?.GIT_CONFIG_COUNT ?? "0"), 10);
|
|
2871
|
+
const count = Number.isFinite(start) && start > 0 ? start : 0;
|
|
2872
|
+
const out = {};
|
|
2873
|
+
entries.forEach((entry, i) => {
|
|
2874
|
+
const n = count + i;
|
|
2875
|
+
out[`GIT_CONFIG_KEY_${n}`] = entry.key;
|
|
2876
|
+
out[`GIT_CONFIG_VALUE_${n}`] = entry.value;
|
|
2877
|
+
});
|
|
2878
|
+
out.GIT_CONFIG_COUNT = String(count + entries.length);
|
|
2879
|
+
return out;
|
|
2880
|
+
}
|
|
2881
|
+
function githubAgentGitEnv(existing) {
|
|
2882
|
+
return appendIndexedGitConfig(existing, HTTPS_REWRITE);
|
|
2883
|
+
}
|
|
2884
|
+
function applyGithubGitAuthEnv(existing, opts) {
|
|
2885
|
+
const out = {};
|
|
2886
|
+
if (opts.mode === "gh" || opts.mode === "token") {
|
|
2887
|
+
Object.assign(out, githubAgentGitEnv(existing));
|
|
2888
|
+
}
|
|
2889
|
+
if (opts.mode === "token") {
|
|
2890
|
+
const token = opts.token?.trim();
|
|
2891
|
+
if (token && !existing?.GH_TOKEN?.trim()) {
|
|
2892
|
+
out.GH_TOKEN = token;
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
return out;
|
|
2896
|
+
}
|
|
2897
|
+
function formatGitAuthModeDirective(mode) {
|
|
2898
|
+
switch (mode) {
|
|
2899
|
+
case "gh":
|
|
2900
|
+
return [
|
|
2901
|
+
"Git authentication (Account \u2192 GitHub mode: gh CLI):",
|
|
2902
|
+
"- This process rewrites `git@github.com:` and `ssh://git@github.com/` to HTTPS.",
|
|
2903
|
+
"- `gh` supplies credentials (`gh auth git-credential`). Do not switch remotes to SSH.",
|
|
2904
|
+
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below."
|
|
2905
|
+
].join("\n");
|
|
2906
|
+
case "ssh":
|
|
2907
|
+
return [
|
|
2908
|
+
"Git authentication (Account \u2192 GitHub mode: SSH):",
|
|
2909
|
+
"- Keep SSH remotes (`git@github.com:\u2026`). Do not rewrite them to HTTPS.",
|
|
2910
|
+
"- Use this Mac\u2019s SSH agent / keys. If push fails with `Permission denied (publickey)`, tell the user to start ssh-agent or switch Account \u2192 GitHub to Auto / gh CLI \u2014 do not rewrite remotes yourself.",
|
|
2911
|
+
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below (API still uses `gh`)."
|
|
2912
|
+
].join("\n");
|
|
2913
|
+
case "token":
|
|
2914
|
+
return [
|
|
2915
|
+
"Git authentication (Account \u2192 GitHub mode: personal access token):",
|
|
2916
|
+
"- This process rewrites GitHub SSH remotes to HTTPS.",
|
|
2917
|
+
"- `GH_TOKEN` is set in the environment. Use HTTPS git and `gh`; do not paste the token into commands or chat.",
|
|
2918
|
+
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below."
|
|
2919
|
+
].join("\n");
|
|
2920
|
+
case "auto":
|
|
2921
|
+
default:
|
|
2922
|
+
return [
|
|
2923
|
+
"Git authentication (Account \u2192 GitHub mode: auto):",
|
|
2924
|
+
"- Prefer the existing remote URL (SSH or HTTPS). Do not rewrite remotes unless a push/fetch fails.",
|
|
2925
|
+
'- If `git push` fails with `Permission denied (publickey)`, this shell has no ssh-agent. Retry over HTTPS (do not stop): `git -c url.https://github.com/.insteadOf=git@github.com: -c http.extraHeader="AUTHORIZATION: bearer $(gh auth token)" push -u origin HEAD`.',
|
|
2926
|
+
"- Then create/update the PR with `gh` as below."
|
|
2927
|
+
].join("\n");
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
var HTTPS_REWRITE;
|
|
2931
|
+
var init_git_auth_mode = __esm({
|
|
2932
|
+
"src/git/git-auth-mode.ts"() {
|
|
2933
|
+
"use strict";
|
|
2934
|
+
HTTPS_REWRITE = [
|
|
2935
|
+
{ key: "url.https://github.com/.insteadOf", value: "git@github.com:" },
|
|
2936
|
+
{ key: "url.https://github.com/.insteadOf", value: "ssh://git@github.com/" },
|
|
2937
|
+
{ key: "credential.https://github.com.helper", value: "!gh auth git-credential" }
|
|
2938
|
+
];
|
|
2939
|
+
}
|
|
2940
|
+
});
|
|
2941
|
+
|
|
2823
2942
|
// src/agents/path.ts
|
|
2824
2943
|
function prependPathDir(env, dir) {
|
|
2825
2944
|
if (!dir || !(0, import_node_fs8.existsSync)(dir)) return;
|
|
@@ -3357,6 +3476,7 @@ __export(worktree_exports, {
|
|
|
3357
3476
|
getPrMeta: () => getPrMeta,
|
|
3358
3477
|
ghHeadRef: () => ghHeadRef,
|
|
3359
3478
|
ghRepoSelectArgs: () => ghRepoSelectArgs,
|
|
3479
|
+
githubAgentGitEnv: () => githubAgentGitEnv,
|
|
3360
3480
|
isDirty: () => isDirty,
|
|
3361
3481
|
isPlaceholderBranch: () => isPlaceholderBranch,
|
|
3362
3482
|
isSideboardScratchPath: () => isSideboardScratchPath,
|
|
@@ -3478,10 +3598,15 @@ ${view.stderr}`;
|
|
|
3478
3598
|
timeoutMs: 15e3
|
|
3479
3599
|
});
|
|
3480
3600
|
}
|
|
3481
|
-
async function originGhRepoEnv(cwd) {
|
|
3601
|
+
async function originGhRepoEnv(cwd, opts) {
|
|
3482
3602
|
await ensureGhPreferOrigin(cwd);
|
|
3483
3603
|
const slug = await resolveGithubRepoSlug(cwd);
|
|
3484
|
-
|
|
3604
|
+
const mode = opts?.mode ?? getGithubGitAuthMode();
|
|
3605
|
+
const token = mode === "token" ? getGithubPat() : null;
|
|
3606
|
+
return {
|
|
3607
|
+
...applyGithubGitAuthEnv(opts?.env, { mode, token }),
|
|
3608
|
+
...slug ? { GH_REPO: slug } : {}
|
|
3609
|
+
};
|
|
3485
3610
|
}
|
|
3486
3611
|
async function resolveDefaultBranch(repoPath, opts) {
|
|
3487
3612
|
const viaOrigin = await git(
|
|
@@ -4230,7 +4355,33 @@ async function commitAll(worktreePath, message) {
|
|
|
4230
4355
|
return true;
|
|
4231
4356
|
}
|
|
4232
4357
|
async function pushBranch(worktreePath, branchName) {
|
|
4233
|
-
await git(["push", "-u", "origin", branchName], worktreePath
|
|
4358
|
+
const ssh = await git(["push", "-u", "origin", branchName], worktreePath, {
|
|
4359
|
+
reject: false
|
|
4360
|
+
});
|
|
4361
|
+
if (ssh.exitCode === 0) return;
|
|
4362
|
+
const sshErr = (ssh.stderr || ssh.stdout).trim();
|
|
4363
|
+
const slug = await resolveGithubRepoSlug(worktreePath);
|
|
4364
|
+
const token = await resolveGhAuthToken(worktreePath);
|
|
4365
|
+
if (!slug || !token) {
|
|
4366
|
+
throw new Error(
|
|
4367
|
+
sshErr || `git push origin ${branchName} failed` + (!token ? " (no SSH agent and gh auth token unavailable \u2014 run: gh auth login)" : "")
|
|
4368
|
+
);
|
|
4369
|
+
}
|
|
4370
|
+
const tryHttps = async (header) => git(["push", "-u", "origin", branchName], worktreePath, {
|
|
4371
|
+
reject: false,
|
|
4372
|
+
env: { GIT_TERMINAL_PROMPT: "0" },
|
|
4373
|
+
config: {
|
|
4374
|
+
"url.https://github.com/.insteadOf": "git@github.com:",
|
|
4375
|
+
"http.extraHeader": header
|
|
4376
|
+
}
|
|
4377
|
+
});
|
|
4378
|
+
const bearer = await tryHttps(`AUTHORIZATION: bearer ${token}`);
|
|
4379
|
+
if (bearer.exitCode === 0) return;
|
|
4380
|
+
const basic = Buffer.from(`x-access-token:${token}`, "utf8").toString("base64");
|
|
4381
|
+
const basicPush = await tryHttps(`Authorization: Basic ${basic}`);
|
|
4382
|
+
if (basicPush.exitCode === 0) return;
|
|
4383
|
+
const httpsErr = (basicPush.stderr || bearer.stderr || bearer.stdout).trim();
|
|
4384
|
+
throw new Error(httpsErr || sshErr || `git push origin ${branchName} failed`);
|
|
4234
4385
|
}
|
|
4235
4386
|
async function mergePr(cwd, selector, opts) {
|
|
4236
4387
|
const slug = await resolveGithubRepoSlug(cwd);
|
|
@@ -4418,8 +4569,8 @@ function allocateTeamSlug(repoPath) {
|
|
|
4418
4569
|
const taken = collectTakenTeamSlugs(repoPath);
|
|
4419
4570
|
for (let attempt = 0; attempt < 32; attempt++) {
|
|
4420
4571
|
const team = allocateTeamName(taken);
|
|
4421
|
-
const
|
|
4422
|
-
if (!(0, import_node_fs9.existsSync)(
|
|
4572
|
+
const path2 = (0, import_node_path9.join)(worktreesRoot(repoPath), team.slug);
|
|
4573
|
+
if (!(0, import_node_fs9.existsSync)(path2)) return team;
|
|
4423
4574
|
taken.add(team.slug);
|
|
4424
4575
|
}
|
|
4425
4576
|
throw new Error("No available soccer team worktree directories left");
|
|
@@ -4435,10 +4586,13 @@ var init_worktree = __esm({
|
|
|
4435
4586
|
init_teams();
|
|
4436
4587
|
init_worktree_labels();
|
|
4437
4588
|
init_gh_errors();
|
|
4589
|
+
init_git_auth_mode();
|
|
4438
4590
|
init_run();
|
|
4591
|
+
init_app_settings();
|
|
4439
4592
|
init_pr_gates();
|
|
4440
4593
|
init_stack();
|
|
4441
4594
|
init_teams();
|
|
4595
|
+
init_git_auth_mode();
|
|
4442
4596
|
init_workspace_scratch();
|
|
4443
4597
|
init_worktree_labels();
|
|
4444
4598
|
}
|
|
@@ -4639,7 +4793,7 @@ var init_coordinator_prompt = __esm({
|
|
|
4639
4793
|
"Inspect / review / PRs:",
|
|
4640
4794
|
"- get_diff \u2014 compact diff summary",
|
|
4641
4795
|
'- request_review \u2014 open a Review chat tab on a worktree thread (attaches .sideboard/review.md when present, else local guidelines; sends "Review changes in this workspace."); then wait_for_turn / get_turn_result on the returned id',
|
|
4642
|
-
"- ask_git \u2014
|
|
4796
|
+
"- 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. Prefer this over paraphrasing.",
|
|
4643
4797
|
'- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Fix merge conflicts.", "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.',
|
|
4644
4798
|
"Human-only (do not attempt): ready-for-review land (confirm_land), purge_thread.",
|
|
4645
4799
|
"Thread links in replies: when mentioning a chat/thread for the user, include a markdown link `[Title](sideboard://thread/<id>)` using the full id (or the link field from create_thread / list_threads). Sideboard renders these as clickable opens.",
|
|
@@ -4912,10 +5066,10 @@ function removedWorkspacesFile() {
|
|
|
4912
5066
|
return (0, import_node_path11.join)(appDataDir(), "removed-workspaces.json");
|
|
4913
5067
|
}
|
|
4914
5068
|
function readAll() {
|
|
4915
|
-
const
|
|
4916
|
-
if (!(0, import_node_fs11.existsSync)(
|
|
5069
|
+
const path2 = workspacesFile();
|
|
5070
|
+
if (!(0, import_node_fs11.existsSync)(path2)) return [];
|
|
4917
5071
|
try {
|
|
4918
|
-
const raw = JSON.parse((0, import_node_fs11.readFileSync)(
|
|
5072
|
+
const raw = JSON.parse((0, import_node_fs11.readFileSync)(path2, "utf8"));
|
|
4919
5073
|
return Array.isArray(raw) ? raw : [];
|
|
4920
5074
|
} catch {
|
|
4921
5075
|
return [];
|
|
@@ -4926,10 +5080,10 @@ function writeAll(list) {
|
|
|
4926
5080
|
(0, import_node_fs11.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
|
|
4927
5081
|
}
|
|
4928
5082
|
function readRemoved() {
|
|
4929
|
-
const
|
|
4930
|
-
if (!(0, import_node_fs11.existsSync)(
|
|
5083
|
+
const path2 = removedWorkspacesFile();
|
|
5084
|
+
if (!(0, import_node_fs11.existsSync)(path2)) return /* @__PURE__ */ new Set();
|
|
4931
5085
|
try {
|
|
4932
|
-
const raw = JSON.parse((0, import_node_fs11.readFileSync)(
|
|
5086
|
+
const raw = JSON.parse((0, import_node_fs11.readFileSync)(path2, "utf8"));
|
|
4933
5087
|
return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
|
|
4934
5088
|
} catch {
|
|
4935
5089
|
return /* @__PURE__ */ new Set();
|
|
@@ -4986,17 +5140,17 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
4986
5140
|
const removed = readRemoved();
|
|
4987
5141
|
const byPath = new Map(current.map((w) => [w.path, w]));
|
|
4988
5142
|
let dirty = false;
|
|
4989
|
-
for (const
|
|
4990
|
-
if (!
|
|
5143
|
+
for (const path2 of repoPaths) {
|
|
5144
|
+
if (!path2 || path2 === "/" || isGlobalRepoPath(path2) || byPath.has(path2) || removed.has(path2)) {
|
|
4991
5145
|
continue;
|
|
4992
5146
|
}
|
|
4993
|
-
if (!(0, import_node_fs11.existsSync)(
|
|
5147
|
+
if (!(0, import_node_fs11.existsSync)(path2)) continue;
|
|
4994
5148
|
const ws = {
|
|
4995
|
-
path,
|
|
4996
|
-
name: (0, import_node_path11.basename)(
|
|
5149
|
+
path: path2,
|
|
5150
|
+
name: (0, import_node_path11.basename)(path2),
|
|
4997
5151
|
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4998
5152
|
};
|
|
4999
|
-
byPath.set(
|
|
5153
|
+
byPath.set(path2, ws);
|
|
5000
5154
|
dirty = true;
|
|
5001
5155
|
}
|
|
5002
5156
|
const next = [...byPath.values()];
|
|
@@ -5020,11 +5174,11 @@ function brightsyConfigPath() {
|
|
|
5020
5174
|
return (0, import_node_path12.join)((0, import_node_os5.homedir)(), ".brightsy", "config.json");
|
|
5021
5175
|
}
|
|
5022
5176
|
function loadBrightsyConfig() {
|
|
5023
|
-
const
|
|
5024
|
-
if (!(0, import_node_fs12.existsSync)(
|
|
5177
|
+
const path2 = brightsyConfigPath();
|
|
5178
|
+
if (!(0, import_node_fs12.existsSync)(path2)) {
|
|
5025
5179
|
throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
|
|
5026
5180
|
}
|
|
5027
|
-
const raw = JSON.parse((0, import_node_fs12.readFileSync)(
|
|
5181
|
+
const raw = JSON.parse((0, import_node_fs12.readFileSync)(path2, "utf8"));
|
|
5028
5182
|
if (!raw.access_token || !raw.account_id) {
|
|
5029
5183
|
throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
|
|
5030
5184
|
}
|
|
@@ -5148,10 +5302,10 @@ function storePath() {
|
|
|
5148
5302
|
return (0, import_node_path13.join)(appDataDir(), "brightsy-teams.json");
|
|
5149
5303
|
}
|
|
5150
5304
|
function readStore() {
|
|
5151
|
-
const
|
|
5152
|
-
if (!(0, import_node_fs13.existsSync)(
|
|
5305
|
+
const path2 = storePath();
|
|
5306
|
+
if (!(0, import_node_fs13.existsSync)(path2)) return [];
|
|
5153
5307
|
try {
|
|
5154
|
-
const parsed = JSON.parse((0, import_node_fs13.readFileSync)(
|
|
5308
|
+
const parsed = JSON.parse((0, import_node_fs13.readFileSync)(path2, "utf8"));
|
|
5155
5309
|
return Array.isArray(parsed.teams) ? parsed.teams : [];
|
|
5156
5310
|
} catch {
|
|
5157
5311
|
return [];
|
|
@@ -5159,8 +5313,8 @@ function readStore() {
|
|
|
5159
5313
|
}
|
|
5160
5314
|
function writeStore(teams) {
|
|
5161
5315
|
(0, import_node_fs13.mkdirSync)(appDataDir(), { recursive: true });
|
|
5162
|
-
const
|
|
5163
|
-
(0, import_node_fs13.writeFileSync)(
|
|
5316
|
+
const path2 = storePath();
|
|
5317
|
+
(0, import_node_fs13.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
|
|
5164
5318
|
`, {
|
|
5165
5319
|
mode: 384
|
|
5166
5320
|
});
|
|
@@ -6700,9 +6854,9 @@ function codexConfigHasNetworkAccess() {
|
|
|
6700
6854
|
(0, import_node_path15.join)((0, import_node_os7.homedir)(), ".codex", "config.toml"),
|
|
6701
6855
|
(0, import_node_path15.join)((0, import_node_os7.homedir)(), ".config", "codex", "config.toml")
|
|
6702
6856
|
];
|
|
6703
|
-
for (const
|
|
6704
|
-
if (!(0, import_node_fs17.existsSync)(
|
|
6705
|
-
const text3 = (0, import_node_fs17.readFileSync)(
|
|
6857
|
+
for (const path2 of candidates) {
|
|
6858
|
+
if (!(0, import_node_fs17.existsSync)(path2)) continue;
|
|
6859
|
+
const text3 = (0, import_node_fs17.readFileSync)(path2, "utf8");
|
|
6706
6860
|
if (/network_access\s*=\s*true/.test(text3)) return true;
|
|
6707
6861
|
}
|
|
6708
6862
|
return false;
|
|
@@ -8166,8 +8320,8 @@ function extractPresentedPlan(parts) {
|
|
|
8166
8320
|
const content = typeof input.content === "string" ? input.content : typeof input.plan === "string" ? input.plan : typeof input.markdown === "string" ? input.markdown : "";
|
|
8167
8321
|
if (!content.trim()) continue;
|
|
8168
8322
|
const title = typeof input.title === "string" && input.title.trim() ? input.title.trim() : "Plan";
|
|
8169
|
-
const
|
|
8170
|
-
return { title, content: content.trim(), path, source: "present_plan" };
|
|
8323
|
+
const path2 = typeof input.path === "string" && input.path.trim() ? input.path.trim() : PLAN_FILE_REL;
|
|
8324
|
+
return { title, content: content.trim(), path: path2, source: "present_plan" };
|
|
8171
8325
|
}
|
|
8172
8326
|
return null;
|
|
8173
8327
|
}
|
|
@@ -8356,6 +8510,7 @@ __export(index_exports, {
|
|
|
8356
8510
|
CONTEXT_MIN_MESSAGES: () => CONTEXT_MIN_MESSAGES,
|
|
8357
8511
|
COORDINATOR_TOOL_PLAYBOOK: () => COORDINATOR_TOOL_PLAYBOOK,
|
|
8358
8512
|
FAMOUS_SOCCER_TEAMS: () => FAMOUS_SOCCER_TEAMS,
|
|
8513
|
+
GITHUB_GIT_AUTH_MODES: () => GITHUB_GIT_AUTH_MODES,
|
|
8359
8514
|
GLOBAL_WORKSPACE_ID: () => GLOBAL_WORKSPACE_ID,
|
|
8360
8515
|
HARNESS_ENV_KEYS: () => HARNESS_ENV_KEYS,
|
|
8361
8516
|
LEGACY_ATTACHMENTS_DIR: () => LEGACY_ATTACHMENTS_DIR,
|
|
@@ -8405,10 +8560,12 @@ __export(index_exports, {
|
|
|
8405
8560
|
allocateTeamSlug: () => allocateTeamSlug,
|
|
8406
8561
|
appDataDir: () => appDataDir,
|
|
8407
8562
|
appSettingsPath: () => appSettingsPath,
|
|
8563
|
+
appendIndexedGitConfig: () => appendIndexedGitConfig,
|
|
8408
8564
|
appendMessage: () => appendMessage,
|
|
8409
8565
|
applyAgentEvent: () => applyAgentEvent,
|
|
8410
8566
|
applyAppEnvironment: () => applyAppEnvironment,
|
|
8411
8567
|
applyCompaction: () => applyCompaction,
|
|
8568
|
+
applyGithubGitAuthEnv: () => applyGithubGitAuthEnv,
|
|
8412
8569
|
applyThreadIntoMain: () => applyThreadIntoMain,
|
|
8413
8570
|
applyTurnUsage: () => applyTurnUsage,
|
|
8414
8571
|
assertOrchestratorCapableAgent: () => assertOrchestratorCapableAgent,
|
|
@@ -8523,6 +8680,7 @@ __export(index_exports, {
|
|
|
8523
8680
|
formatBrightsyFetchError: () => formatBrightsyFetchError,
|
|
8524
8681
|
formatFetchError: () => formatFetchError,
|
|
8525
8682
|
formatGhLandError: () => formatGhLandError,
|
|
8683
|
+
formatGitAuthModeDirective: () => formatGitAuthModeDirective,
|
|
8526
8684
|
formatIpcInvokeError: () => formatIpcInvokeError,
|
|
8527
8685
|
formatMessagesAsTranscript: () => formatMessagesAsTranscript,
|
|
8528
8686
|
formatPlanQuestionAnswers: () => formatPlanQuestionAnswers,
|
|
@@ -8549,6 +8707,8 @@ __export(index_exports, {
|
|
|
8549
8707
|
getDiff: () => getDiff,
|
|
8550
8708
|
getDiffSummary: () => getDiffSummary,
|
|
8551
8709
|
getGitHubStatus: () => getGitHubStatus,
|
|
8710
|
+
getGithubGitAuthMode: () => getGithubGitAuthMode,
|
|
8711
|
+
getGithubPat: () => getGithubPat,
|
|
8552
8712
|
getIssueSource: () => getIssueSource,
|
|
8553
8713
|
getLinearApiKey: () => getLinearApiKey,
|
|
8554
8714
|
getLinearAuthToken: () => getLinearAuthToken,
|
|
@@ -8567,6 +8727,7 @@ __export(index_exports, {
|
|
|
8567
8727
|
ghHeadRef: () => ghHeadRef,
|
|
8568
8728
|
ghRepoSelectArgs: () => ghRepoSelectArgs,
|
|
8569
8729
|
git: () => git,
|
|
8730
|
+
githubAgentGitEnv: () => githubAgentGitEnv,
|
|
8570
8731
|
globalAgentCwd: () => globalAgentCwd,
|
|
8571
8732
|
handleSlackInbound: () => handleSlackInbound,
|
|
8572
8733
|
harnessEnvKey: () => harnessEnvKey,
|
|
@@ -8789,6 +8950,7 @@ __export(index_exports, {
|
|
|
8789
8950
|
startSlackOAuth: () => startSlackOAuth,
|
|
8790
8951
|
startSlackRelayServer: () => startSlackRelayServer,
|
|
8791
8952
|
stripBrightsyNdjsonNoise: () => stripBrightsyNdjsonNoise,
|
|
8953
|
+
stripNestedElectronEnv: () => stripNestedElectronEnv,
|
|
8792
8954
|
submitPrStack: () => submitPrStack,
|
|
8793
8955
|
suggestSlug: () => suggestSlug,
|
|
8794
8956
|
summarizeConversation: () => summarizeConversation,
|
|
@@ -8847,6 +9009,7 @@ init_workspaces();
|
|
|
8847
9009
|
init_global_workspace();
|
|
8848
9010
|
init_run();
|
|
8849
9011
|
init_gh_errors();
|
|
9012
|
+
init_git_auth_mode();
|
|
8850
9013
|
init_worktree();
|
|
8851
9014
|
init_stack();
|
|
8852
9015
|
|
|
@@ -9613,8 +9776,8 @@ function toolDetail(name, input) {
|
|
|
9613
9776
|
if (!input) return void 0;
|
|
9614
9777
|
const command = str2(input.command) ?? str2(input.cmd);
|
|
9615
9778
|
if (command) return command;
|
|
9616
|
-
const
|
|
9617
|
-
if (
|
|
9779
|
+
const path2 = str2(input.file_path) ?? str2(input.path) ?? str2(input.filePath) ?? str2(input.filename);
|
|
9780
|
+
if (path2) return path2;
|
|
9618
9781
|
const pattern = str2(input.pattern) ?? str2(input.glob) ?? str2(input.glob_pattern);
|
|
9619
9782
|
if (pattern) return pattern;
|
|
9620
9783
|
const query = str2(input.query) ?? str2(input.prompt);
|
|
@@ -9658,12 +9821,12 @@ function toolDescription(name, input) {
|
|
|
9658
9821
|
return "Run shell command";
|
|
9659
9822
|
}
|
|
9660
9823
|
if (/edit|write|apply/i.test(name)) {
|
|
9661
|
-
const
|
|
9662
|
-
return
|
|
9824
|
+
const path2 = str2(input.file_path) ?? str2(input.path);
|
|
9825
|
+
return path2 ? `Edit ${path2.split("/").pop()}` : "Edit file";
|
|
9663
9826
|
}
|
|
9664
9827
|
if (/read/i.test(name)) {
|
|
9665
|
-
const
|
|
9666
|
-
return
|
|
9828
|
+
const path2 = str2(input.file_path) ?? str2(input.path);
|
|
9829
|
+
return path2 ? `Read ${path2.split("/").pop()}` : "Read file";
|
|
9667
9830
|
}
|
|
9668
9831
|
if (/grep/i.test(name)) return "Search files";
|
|
9669
9832
|
if (/glob/i.test(name)) return "Find files";
|
|
@@ -9892,8 +10055,13 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
9892
10055
|
}
|
|
9893
10056
|
const env = childEnvWithAppSettings(cmd.env);
|
|
9894
10057
|
if (!isOrchestratorThread(thread)) {
|
|
9895
|
-
|
|
9896
|
-
|
|
10058
|
+
try {
|
|
10059
|
+
const originEnv = await originGhRepoEnv(thread.worktreePath, { env });
|
|
10060
|
+
Object.assign(env, originEnv);
|
|
10061
|
+
} catch (err) {
|
|
10062
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
10063
|
+
console.warn(`[sideboard] originGhRepoEnv failed (${thread.worktreePath}): ${detail}`);
|
|
10064
|
+
}
|
|
9897
10065
|
}
|
|
9898
10066
|
const child = (0, import_execa2.execa)(cmd.file, cmd.args, {
|
|
9899
10067
|
cwd: cmd.cwd,
|
|
@@ -9983,6 +10151,7 @@ init_claude_mcp();
|
|
|
9983
10151
|
// src/agents/instructions.ts
|
|
9984
10152
|
var import_node_fs20 = require("fs");
|
|
9985
10153
|
var import_node_path17 = require("path");
|
|
10154
|
+
init_git_auth_mode();
|
|
9986
10155
|
init_worktree_labels();
|
|
9987
10156
|
function normPath2(p) {
|
|
9988
10157
|
return p.replace(/\/+$/, "");
|
|
@@ -10032,6 +10201,8 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
10032
10201
|
lines.push(
|
|
10033
10202
|
"- Push with `git push -u origin HEAD` (or the current branch name). Do not `git push upstream`."
|
|
10034
10203
|
);
|
|
10204
|
+
lines.push("");
|
|
10205
|
+
lines.push(formatGitAuthModeDirective(opts?.gitAuthMode ?? "auto"));
|
|
10035
10206
|
lines.push(
|
|
10036
10207
|
"- Derive the PR title and body from what the changes actually do and why \u2014 inspect the diff/commits and the user request. Do not use the soccer-team worktree nickname or placeholder branch as the PR title."
|
|
10037
10208
|
);
|
|
@@ -10219,9 +10390,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
10219
10390
|
return new RegExp(`^${escaped}$`).test(name);
|
|
10220
10391
|
}
|
|
10221
10392
|
function readWorktreeInclude(repoPath) {
|
|
10222
|
-
const
|
|
10223
|
-
if (!(0, import_node_fs21.existsSync)(
|
|
10224
|
-
return (0, import_node_fs21.readFileSync)(
|
|
10393
|
+
const path2 = (0, import_node_path18.join)(repoPath, ".worktreeinclude");
|
|
10394
|
+
if (!(0, import_node_fs21.existsSync)(path2)) return [];
|
|
10395
|
+
return (0, import_node_fs21.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
10225
10396
|
}
|
|
10226
10397
|
function resolveFilesToCopy(repoPath) {
|
|
10227
10398
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -10296,8 +10467,20 @@ async function captureLoginEnv() {
|
|
|
10296
10467
|
cachedLoginEnv = { ...process.env };
|
|
10297
10468
|
return { ...cachedLoginEnv };
|
|
10298
10469
|
}
|
|
10470
|
+
var NESTED_ELECTRON_ENV_PREFIXES = ["ELECTRON_", "CHROME_"];
|
|
10471
|
+
function stripNestedElectronEnv(env) {
|
|
10472
|
+
const out = { ...env };
|
|
10473
|
+
for (const key of Object.keys(out)) {
|
|
10474
|
+
if (NESTED_ELECTRON_ENV_PREFIXES.some((prefix) => key.startsWith(prefix))) {
|
|
10475
|
+
delete out[key];
|
|
10476
|
+
}
|
|
10477
|
+
}
|
|
10478
|
+
return out;
|
|
10479
|
+
}
|
|
10299
10480
|
function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
10300
|
-
const env = {
|
|
10481
|
+
const env = stripNestedElectronEnv({
|
|
10482
|
+
...baseEnv ?? process.env
|
|
10483
|
+
});
|
|
10301
10484
|
const name = opts.workspaceName ?? (0, import_node_path18.basename)(opts.worktreePath);
|
|
10302
10485
|
const ports = opts.ports ?? [];
|
|
10303
10486
|
const primary = ports[0];
|
|
@@ -10522,10 +10705,10 @@ var import_node_path19 = require("path");
|
|
|
10522
10705
|
var import_execa4 = require("execa");
|
|
10523
10706
|
var import_node_readline3 = require("readline");
|
|
10524
10707
|
function loadCursorWorktreesJson(rootPath) {
|
|
10525
|
-
const
|
|
10526
|
-
if (!(0, import_node_fs22.existsSync)(
|
|
10708
|
+
const path2 = (0, import_node_path19.join)(rootPath, ".cursor", "worktrees.json");
|
|
10709
|
+
if (!(0, import_node_fs22.existsSync)(path2)) return null;
|
|
10527
10710
|
try {
|
|
10528
|
-
return JSON.parse((0, import_node_fs22.readFileSync)(
|
|
10711
|
+
return JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf8"));
|
|
10529
10712
|
} catch {
|
|
10530
10713
|
return null;
|
|
10531
10714
|
}
|
|
@@ -10628,9 +10811,9 @@ function parseNameStatus(stdout) {
|
|
|
10628
10811
|
const out = [];
|
|
10629
10812
|
for (const line of stdout.split("\n").filter(Boolean)) {
|
|
10630
10813
|
const [status, ...pathParts] = line.split(" ");
|
|
10631
|
-
const
|
|
10632
|
-
if (!status || !
|
|
10633
|
-
out.push({ status: status[0] ?? status, path });
|
|
10814
|
+
const path2 = pathParts[pathParts.length - 1];
|
|
10815
|
+
if (!status || !path2) continue;
|
|
10816
|
+
out.push({ status: status[0] ?? status, path: path2 });
|
|
10634
10817
|
}
|
|
10635
10818
|
return out;
|
|
10636
10819
|
}
|
|
@@ -10638,12 +10821,12 @@ function parseNumstat(stdout) {
|
|
|
10638
10821
|
const map = /* @__PURE__ */ new Map();
|
|
10639
10822
|
for (const line of stdout.split("\n").filter(Boolean)) {
|
|
10640
10823
|
const [addRaw, delRaw, ...pathParts] = line.split(" ");
|
|
10641
|
-
const
|
|
10642
|
-
if (!
|
|
10824
|
+
const path2 = pathParts[pathParts.length - 1];
|
|
10825
|
+
if (!path2) continue;
|
|
10643
10826
|
const additions = addRaw === "-" ? 0 : Number(addRaw);
|
|
10644
10827
|
const deletions = delRaw === "-" ? 0 : Number(delRaw);
|
|
10645
10828
|
if (!Number.isFinite(additions) && !Number.isFinite(deletions)) continue;
|
|
10646
|
-
map.set(
|
|
10829
|
+
map.set(path2, {
|
|
10647
10830
|
additions: Number.isFinite(additions) ? additions : 0,
|
|
10648
10831
|
deletions: Number.isFinite(deletions) ? deletions : 0
|
|
10649
10832
|
});
|
|
@@ -10720,70 +10903,70 @@ function splitCombinedDiff(stdout) {
|
|
|
10720
10903
|
}
|
|
10721
10904
|
return map;
|
|
10722
10905
|
}
|
|
10723
|
-
function syntheticAddPatch(
|
|
10906
|
+
function syntheticAddPatch(path2, content, maxHunk) {
|
|
10724
10907
|
const lines = content.split("\n");
|
|
10725
10908
|
const body = lines.map((l) => `+${l}`).join("\n");
|
|
10726
|
-
const header = `diff --git a/${
|
|
10909
|
+
const header = `diff --git a/${path2} b/${path2}
|
|
10727
10910
|
new file mode 100644
|
|
10728
10911
|
--- /dev/null
|
|
10729
|
-
+++ b/${
|
|
10912
|
+
+++ b/${path2}
|
|
10730
10913
|
@@ -0,0 +1,${lines.length} @@
|
|
10731
10914
|
`;
|
|
10732
10915
|
return {
|
|
10733
|
-
path,
|
|
10916
|
+
path: path2,
|
|
10734
10917
|
status: "A",
|
|
10735
10918
|
patch: capPatch(`${header}${body}`, maxHunk),
|
|
10736
10919
|
additions: lines.length,
|
|
10737
10920
|
deletions: 0
|
|
10738
10921
|
};
|
|
10739
10922
|
}
|
|
10740
|
-
async function untrackedPatch(worktreePath,
|
|
10741
|
-
const abs = (0, import_node_path20.join)(worktreePath,
|
|
10923
|
+
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
10924
|
+
const abs = (0, import_node_path20.join)(worktreePath, path2);
|
|
10742
10925
|
try {
|
|
10743
10926
|
const st = (0, import_node_fs23.statSync)(abs);
|
|
10744
10927
|
if (st.isFile() && st.size > maxHunk) {
|
|
10745
10928
|
const buf = (0, import_node_fs23.readFileSync)(abs).subarray(0, maxHunk);
|
|
10746
|
-
return syntheticAddPatch(
|
|
10929
|
+
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
10747
10930
|
}
|
|
10748
10931
|
} catch {
|
|
10749
10932
|
}
|
|
10750
10933
|
const { stdout: patch } = await git(
|
|
10751
|
-
["diff", "--no-ext-diff", "--no-color", "--no-index", "--", "/dev/null",
|
|
10934
|
+
["diff", "--no-ext-diff", "--no-color", "--no-index", "--", "/dev/null", path2],
|
|
10752
10935
|
worktreePath,
|
|
10753
10936
|
{ reject: false, timeoutMs: 4e3 }
|
|
10754
10937
|
);
|
|
10755
|
-
const normalized = patch.replace(/^diff --git a\/.+? b\/.+?$/m, `diff --git a/${
|
|
10938
|
+
const normalized = patch.replace(/^diff --git a\/.+? b\/.+?$/m, `diff --git a/${path2} b/${path2}`).replace(/^--- .*$/m, "--- /dev/null").replace(/^\+\+\+ .*$/m, `+++ b/${path2}`);
|
|
10756
10939
|
const addLines = normalized.split("\n").filter((l) => l.startsWith("+") && !l.startsWith("+++")).length;
|
|
10757
10940
|
return {
|
|
10758
|
-
path,
|
|
10941
|
+
path: path2,
|
|
10759
10942
|
status: "A",
|
|
10760
10943
|
patch: capPatch(normalized, maxHunk),
|
|
10761
10944
|
additions: addLines,
|
|
10762
10945
|
deletions: 0
|
|
10763
10946
|
};
|
|
10764
10947
|
}
|
|
10765
|
-
async function listUntrackedPaths(worktreePath,
|
|
10948
|
+
async function listUntrackedPaths(worktreePath, path2) {
|
|
10766
10949
|
const args = ["ls-files", "-z", "--others", "--exclude-standard"];
|
|
10767
|
-
if (
|
|
10950
|
+
if (path2) args.push("--", path2);
|
|
10768
10951
|
const { stdout } = await git(args, worktreePath, { reject: false });
|
|
10769
10952
|
return stdout.split("\0").filter(Boolean).filter((p) => !isSideboardScratchPath(p));
|
|
10770
10953
|
}
|
|
10771
10954
|
async function listUntrackedFiles(worktreePath, maxHunk, paths) {
|
|
10772
10955
|
const list = paths ?? await listUntrackedPaths(worktreePath);
|
|
10773
10956
|
if (list.length === 0) return [];
|
|
10774
|
-
return Promise.all(list.map((
|
|
10957
|
+
return Promise.all(list.map((path2) => untrackedPatch(worktreePath, path2, maxHunk)));
|
|
10775
10958
|
}
|
|
10776
10959
|
function untrackedStubs(paths) {
|
|
10777
|
-
return paths.map((
|
|
10778
|
-
path,
|
|
10960
|
+
return paths.map((path2) => ({
|
|
10961
|
+
path: path2,
|
|
10779
10962
|
status: "A",
|
|
10780
10963
|
patch: "",
|
|
10781
10964
|
additions: 0,
|
|
10782
10965
|
deletions: 0
|
|
10783
10966
|
}));
|
|
10784
10967
|
}
|
|
10785
|
-
function pathspec(
|
|
10786
|
-
return
|
|
10968
|
+
function pathspec(path2) {
|
|
10969
|
+
return path2 ? ["--", path2] : [];
|
|
10787
10970
|
}
|
|
10788
10971
|
function gitDiff(args, cwd, opts) {
|
|
10789
10972
|
return git(["diff", "--no-ext-diff", "--no-color", ...args], cwd, {
|
|
@@ -10791,7 +10974,7 @@ function gitDiff(args, cwd, opts) {
|
|
|
10791
10974
|
timeoutMs: opts?.timeoutMs
|
|
10792
10975
|
});
|
|
10793
10976
|
}
|
|
10794
|
-
function fileFromPatch(
|
|
10977
|
+
function fileFromPatch(path2, patch, maxHunk) {
|
|
10795
10978
|
let status = "M";
|
|
10796
10979
|
if (/^new file mode /m.test(patch) || /^--- \/dev\/null/m.test(patch)) {
|
|
10797
10980
|
status = "A";
|
|
@@ -10803,15 +10986,15 @@ function fileFromPatch(path, patch, maxHunk) {
|
|
|
10803
10986
|
const additions = patch.split("\n").filter((l) => l.startsWith("+") && !l.startsWith("+++")).length;
|
|
10804
10987
|
const deletions = patch.split("\n").filter((l) => l.startsWith("-") && !l.startsWith("---")).length;
|
|
10805
10988
|
return {
|
|
10806
|
-
path,
|
|
10989
|
+
path: path2,
|
|
10807
10990
|
status,
|
|
10808
10991
|
patch: capPatch(patch, maxHunk),
|
|
10809
10992
|
additions,
|
|
10810
10993
|
deletions
|
|
10811
10994
|
};
|
|
10812
10995
|
}
|
|
10813
|
-
async function gitDiffParts(worktreePath, diffArgs, includePatches,
|
|
10814
|
-
const extra = pathspec(
|
|
10996
|
+
async function gitDiffParts(worktreePath, diffArgs, includePatches, path2) {
|
|
10997
|
+
const extra = pathspec(path2);
|
|
10815
10998
|
if (includePatches) {
|
|
10816
10999
|
const diff = await gitDiff([...diffArgs, ...extra], worktreePath, {
|
|
10817
11000
|
timeoutMs: 4e3
|
|
@@ -10849,17 +11032,17 @@ function filesFromDiff(nameStatus, numstat, combinedDiff, maxHunk) {
|
|
|
10849
11032
|
const patches = splitCombinedDiff(combinedDiff);
|
|
10850
11033
|
if (!nameStatus.trim() && patches.size > 0) {
|
|
10851
11034
|
return [...patches.entries()].map(
|
|
10852
|
-
([
|
|
11035
|
+
([path2, patch]) => fileFromPatch(path2, patch, maxHunk)
|
|
10853
11036
|
);
|
|
10854
11037
|
}
|
|
10855
11038
|
const counts = parseNumstat(numstat);
|
|
10856
11039
|
const files = [];
|
|
10857
|
-
for (const { status, path } of parseNameStatus(nameStatus)) {
|
|
10858
|
-
const n = counts.get(
|
|
11040
|
+
for (const { status, path: path2 } of parseNameStatus(nameStatus)) {
|
|
11041
|
+
const n = counts.get(path2);
|
|
10859
11042
|
files.push({
|
|
10860
|
-
path,
|
|
11043
|
+
path: path2,
|
|
10861
11044
|
status,
|
|
10862
|
-
patch: capPatch(patches.get(
|
|
11045
|
+
patch: capPatch(patches.get(path2) ?? "", maxHunk),
|
|
10863
11046
|
additions: n?.additions,
|
|
10864
11047
|
deletions: n?.deletions
|
|
10865
11048
|
});
|
|
@@ -10943,7 +11126,7 @@ function emptyPathDiff(scope, base, hasLastTurnBase, commitSha = null) {
|
|
|
10943
11126
|
};
|
|
10944
11127
|
}
|
|
10945
11128
|
async function getPathDiff(worktreePath, repoPath, opts) {
|
|
10946
|
-
const { path, scope, commitSha, lastTurnBase, hasLastTurnBase, includePatches, maxHunk } = opts;
|
|
11129
|
+
const { path: path2, scope, commitSha, lastTurnBase, hasLastTurnBase, includePatches, maxHunk } = opts;
|
|
10947
11130
|
if (scope === "last_turn" && !lastTurnBase) {
|
|
10948
11131
|
return emptyPathDiff(scope, "last turn", false);
|
|
10949
11132
|
}
|
|
@@ -10982,7 +11165,7 @@ async function getPathDiff(worktreePath, repoPath, opts) {
|
|
|
10982
11165
|
labelBase = "HEAD";
|
|
10983
11166
|
}
|
|
10984
11167
|
const diff = await gitDiff(
|
|
10985
|
-
includePatches ? [...diffArgs, "--",
|
|
11168
|
+
includePatches ? [...diffArgs, "--", path2] : ["--name-status", ...diffArgs, "--", path2],
|
|
10986
11169
|
worktreePath,
|
|
10987
11170
|
{ timeoutMs: 4e3 }
|
|
10988
11171
|
);
|
|
@@ -10990,8 +11173,8 @@ async function getPathDiff(worktreePath, repoPath, opts) {
|
|
|
10990
11173
|
if (includePatches) {
|
|
10991
11174
|
const parsed = filesFromDiff("", "", diff.stdout, maxHunk);
|
|
10992
11175
|
for (const file of parsed) filesMap.set(file.path, file);
|
|
10993
|
-
if (diff.stdout.trim() && !filesMap.has(
|
|
10994
|
-
filesMap.set(
|
|
11176
|
+
if (diff.stdout.trim() && !filesMap.has(path2)) {
|
|
11177
|
+
filesMap.set(path2, fileFromPatch(path2, diff.stdout, maxHunk));
|
|
10995
11178
|
}
|
|
10996
11179
|
} else {
|
|
10997
11180
|
for (const file of filesFromDiff(diff.stdout, "", "", maxHunk)) {
|
|
@@ -10999,7 +11182,7 @@ async function getPathDiff(worktreePath, repoPath, opts) {
|
|
|
10999
11182
|
}
|
|
11000
11183
|
}
|
|
11001
11184
|
if (filesMap.size === 0) {
|
|
11002
|
-
const maybe = await listUntrackedPaths(worktreePath,
|
|
11185
|
+
const maybe = await listUntrackedPaths(worktreePath, path2);
|
|
11003
11186
|
if (maybe.length > 0) {
|
|
11004
11187
|
const extra = includePatches ? await listUntrackedFiles(worktreePath, maxHunk, maybe) : untrackedStubs(maybe);
|
|
11005
11188
|
for (const file of extra) filesMap.set(file.path, file);
|
|
@@ -12025,8 +12208,8 @@ function splitForCompaction(messages, thresholds = {}) {
|
|
|
12025
12208
|
function formatToolPart(t, detail) {
|
|
12026
12209
|
if (detail === "summary") {
|
|
12027
12210
|
const label = t.description || t.detail || t.name;
|
|
12028
|
-
const
|
|
12029
|
-
return `- ${t.name}: ${label}${
|
|
12211
|
+
const path2 = t.filePath ? ` (${t.filePath})` : "";
|
|
12212
|
+
return `- ${t.name}: ${label}${path2}`;
|
|
12030
12213
|
}
|
|
12031
12214
|
const lines = [`#### Tool: ${t.name}`, `Status: ${t.status}`];
|
|
12032
12215
|
if (t.description) lines.push(`Description: ${t.description}`);
|
|
@@ -13182,10 +13365,10 @@ function storePath2() {
|
|
|
13182
13365
|
return (0, import_node_path24.join)(appDataDir(), "slack-reply-to.json");
|
|
13183
13366
|
}
|
|
13184
13367
|
function readStore2() {
|
|
13185
|
-
const
|
|
13186
|
-
if (!(0, import_node_fs29.existsSync)(
|
|
13368
|
+
const path2 = storePath2();
|
|
13369
|
+
if (!(0, import_node_fs29.existsSync)(path2)) return {};
|
|
13187
13370
|
try {
|
|
13188
|
-
const parsed = isSecureFileEncrypted(
|
|
13371
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs29.readFileSync)(path2, "utf8"));
|
|
13189
13372
|
return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
|
|
13190
13373
|
} catch {
|
|
13191
13374
|
return {};
|
|
@@ -13210,12 +13393,12 @@ function storePath3() {
|
|
|
13210
13393
|
}
|
|
13211
13394
|
function readStore3() {
|
|
13212
13395
|
try {
|
|
13213
|
-
const
|
|
13214
|
-
const wasEncrypted = isSecureFileEncrypted(
|
|
13215
|
-
const parsed = readSecureJson(
|
|
13396
|
+
const path2 = storePath3();
|
|
13397
|
+
const wasEncrypted = isSecureFileEncrypted(path2);
|
|
13398
|
+
const parsed = readSecureJson(path2);
|
|
13216
13399
|
const workspaces = Array.isArray(parsed?.workspaces) ? parsed.workspaces : [];
|
|
13217
13400
|
if (workspaces.length > 0 && !wasEncrypted && resolveVaultKey()) {
|
|
13218
|
-
writeSecureJson(
|
|
13401
|
+
writeSecureJson(path2, { workspaces });
|
|
13219
13402
|
}
|
|
13220
13403
|
return workspaces;
|
|
13221
13404
|
} catch {
|
|
@@ -13351,10 +13534,10 @@ function tsNewer(a, b) {
|
|
|
13351
13534
|
return Number(a) > Number(b);
|
|
13352
13535
|
}
|
|
13353
13536
|
function readStore4() {
|
|
13354
|
-
const
|
|
13355
|
-
if (!(0, import_node_fs30.existsSync)(
|
|
13537
|
+
const path2 = storePath4();
|
|
13538
|
+
if (!(0, import_node_fs30.existsSync)(path2)) return [];
|
|
13356
13539
|
try {
|
|
13357
|
-
const parsed = isSecureFileEncrypted(
|
|
13540
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs30.readFileSync)(path2, "utf8"));
|
|
13358
13541
|
return Array.isArray(parsed?.watches) ? parsed.watches : [];
|
|
13359
13542
|
} catch {
|
|
13360
13543
|
return [];
|
|
@@ -13726,8 +13909,8 @@ init_worktree();
|
|
|
13726
13909
|
init_thread_store();
|
|
13727
13910
|
init_paths();
|
|
13728
13911
|
init_app_settings();
|
|
13729
|
-
function isSideboardWorktreePath(
|
|
13730
|
-
return
|
|
13912
|
+
function isSideboardWorktreePath(path2) {
|
|
13913
|
+
return path2.includes("/.sideboard/worktrees/") || path2.includes("/sideboard/workspaces/");
|
|
13731
13914
|
}
|
|
13732
13915
|
async function findOrphanWorktrees(repoPaths) {
|
|
13733
13916
|
const threads = listThreads({ includeArchived: true });
|
|
@@ -13752,18 +13935,18 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
13752
13935
|
try {
|
|
13753
13936
|
const wts = await listWorktrees(repoPath);
|
|
13754
13937
|
for (const wt of wts) {
|
|
13755
|
-
const
|
|
13756
|
-
if (!isSideboardWorktreePath(
|
|
13757
|
-
if (known.has(
|
|
13758
|
-
if (seen.has(
|
|
13759
|
-
seen.add(
|
|
13938
|
+
const path2 = wt.path.replace(/\/$/, "");
|
|
13939
|
+
if (!isSideboardWorktreePath(path2)) continue;
|
|
13940
|
+
if (known.has(path2)) continue;
|
|
13941
|
+
if (seen.has(path2)) continue;
|
|
13942
|
+
seen.add(path2);
|
|
13760
13943
|
let mtimeMs = 0;
|
|
13761
13944
|
try {
|
|
13762
|
-
mtimeMs = (0, import_node_fs31.statSync)(
|
|
13945
|
+
mtimeMs = (0, import_node_fs31.statSync)(path2).mtimeMs;
|
|
13763
13946
|
} catch {
|
|
13764
13947
|
mtimeMs = 0;
|
|
13765
13948
|
}
|
|
13766
|
-
orphans.push({ path, repoPath, mtimeMs });
|
|
13949
|
+
orphans.push({ path: path2, repoPath, mtimeMs });
|
|
13767
13950
|
}
|
|
13768
13951
|
} catch {
|
|
13769
13952
|
}
|
|
@@ -13772,17 +13955,17 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
13772
13955
|
if ((0, import_node_fs31.existsSync)(root)) {
|
|
13773
13956
|
for (const entry of (0, import_node_fs31.readdirSync)(root, { withFileTypes: true })) {
|
|
13774
13957
|
if (!entry.isDirectory()) continue;
|
|
13775
|
-
const
|
|
13776
|
-
if (known.has(
|
|
13777
|
-
if (!(0, import_node_fs31.existsSync)((0, import_node_path27.join)(
|
|
13778
|
-
seen.add(
|
|
13958
|
+
const path2 = (0, import_node_path27.join)(root, entry.name).replace(/\/$/, "");
|
|
13959
|
+
if (known.has(path2) || seen.has(path2)) continue;
|
|
13960
|
+
if (!(0, import_node_fs31.existsSync)((0, import_node_path27.join)(path2, ".git"))) continue;
|
|
13961
|
+
seen.add(path2);
|
|
13779
13962
|
let mtimeMs = 0;
|
|
13780
13963
|
try {
|
|
13781
|
-
mtimeMs = (0, import_node_fs31.statSync)(
|
|
13964
|
+
mtimeMs = (0, import_node_fs31.statSync)(path2).mtimeMs;
|
|
13782
13965
|
} catch {
|
|
13783
13966
|
mtimeMs = Date.now();
|
|
13784
13967
|
}
|
|
13785
|
-
orphans.push({ path, repoPath, mtimeMs });
|
|
13968
|
+
orphans.push({ path: path2, repoPath, mtimeMs });
|
|
13786
13969
|
}
|
|
13787
13970
|
}
|
|
13788
13971
|
} catch {
|
|
@@ -14176,9 +14359,9 @@ function ensureReviewRequestFile(worktreePath) {
|
|
|
14176
14359
|
const localAbs = (0, import_node_path29.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
14177
14360
|
const localContent = readTextIfPresent(localAbs) ?? readTextIfPresent((0, import_node_path29.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
14178
14361
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
14179
|
-
const
|
|
14362
|
+
const path2 = (0, import_node_fs33.existsSync)(localAbs) ? REVIEW_REQUEST_PATH : LEGACY_REVIEW_REQUEST_PATH;
|
|
14180
14363
|
return {
|
|
14181
|
-
path,
|
|
14364
|
+
path: path2,
|
|
14182
14365
|
name: REVIEW_REQUEST_NAME,
|
|
14183
14366
|
content: localContent,
|
|
14184
14367
|
source: "local"
|
|
@@ -14194,13 +14377,13 @@ function ensureReviewRequestFile(worktreePath) {
|
|
|
14194
14377
|
};
|
|
14195
14378
|
}
|
|
14196
14379
|
function buildReviewRequestAttachment(content, opts) {
|
|
14197
|
-
const
|
|
14198
|
-
const name = opts?.name ?? (
|
|
14380
|
+
const path2 = opts?.path ?? REVIEW_REQUEST_PATH;
|
|
14381
|
+
const name = opts?.name ?? (path2 === REPO_REVIEW_PATH ? REPO_REVIEW_NAME : REVIEW_REQUEST_NAME);
|
|
14199
14382
|
return {
|
|
14200
14383
|
id: (0, import_node_crypto8.randomUUID)(),
|
|
14201
14384
|
name,
|
|
14202
14385
|
kind: "file",
|
|
14203
|
-
path,
|
|
14386
|
+
path: path2,
|
|
14204
14387
|
content
|
|
14205
14388
|
};
|
|
14206
14389
|
}
|
|
@@ -14920,14 +15103,16 @@ var Orchestrator = class {
|
|
|
14920
15103
|
}
|
|
14921
15104
|
const isBrightsy = fresh.agent === "brightsy";
|
|
14922
15105
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
15106
|
+
const { autoRenameBranchEnabled: autoRenameBranchEnabled2, getGithubGitAuthMode: getGithubGitAuthMode2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
15107
|
+
const gitAuthMode = getGithubGitAuthMode2();
|
|
14923
15108
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
14924
15109
|
githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
|
|
14925
15110
|
() => null
|
|
14926
|
-
)
|
|
15111
|
+
),
|
|
15112
|
+
gitAuthMode
|
|
14927
15113
|
});
|
|
14928
15114
|
const artifactDirective = isBrightsy ? null : formatArtifactDirective();
|
|
14929
15115
|
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
14930
|
-
const { autoRenameBranchEnabled: autoRenameBranchEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
14931
15116
|
const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled2() ? formatRenameBranchDirective(fresh, {
|
|
14932
15117
|
customPrompt: settings?.prompts?.renameBranch
|
|
14933
15118
|
}) : null;
|
|
@@ -15764,8 +15949,9 @@ var Orchestrator = class {
|
|
|
15764
15949
|
return tab;
|
|
15765
15950
|
}
|
|
15766
15951
|
/**
|
|
15767
|
-
*
|
|
15768
|
-
*
|
|
15952
|
+
* Desktop git buttons + MCP `ask_git`.
|
|
15953
|
+
* When the worktree is clean, push / open the PR here (HTTPS via `gh` if SSH
|
|
15954
|
+
* is missing). When dirty, queue the worktree agent to commit first.
|
|
15769
15955
|
*/
|
|
15770
15956
|
async askGit(threadRef, action) {
|
|
15771
15957
|
if (!AGENT_GIT_ACTIONS.includes(action)) {
|
|
@@ -15783,6 +15969,10 @@ var Orchestrator = class {
|
|
|
15783
15969
|
"No pull request linked. Ask the worktree agent to open a draft PR first (ask_git create-draft)."
|
|
15784
15970
|
);
|
|
15785
15971
|
}
|
|
15972
|
+
if ((action === "commit-push" || action === "create-draft" || action === "create-web") && thread.worktreePath?.trim() && !await isDirty(thread.worktreePath)) {
|
|
15973
|
+
await this.pushAndMaybeOpenPr(thread, action);
|
|
15974
|
+
return this.requireThread(threadRef);
|
|
15975
|
+
}
|
|
15786
15976
|
let prBase;
|
|
15787
15977
|
if (action === "resolve-conflicts") {
|
|
15788
15978
|
try {
|
|
@@ -15793,6 +15983,34 @@ var Orchestrator = class {
|
|
|
15793
15983
|
}
|
|
15794
15984
|
return this.send(threadRef, agentGitPrompt(action, { prBase }));
|
|
15795
15985
|
}
|
|
15986
|
+
/** Push origin (gh HTTPS fallback) and create/update the PR when requested. */
|
|
15987
|
+
async pushAndMaybeOpenPr(thread, action) {
|
|
15988
|
+
const cwd = thread.worktreePath;
|
|
15989
|
+
const branch = await currentBranch(cwd);
|
|
15990
|
+
await pushBranch(cwd, branch);
|
|
15991
|
+
if (action === "commit-push") return;
|
|
15992
|
+
const base = await resolveDefaultBranch(thread.repoPath);
|
|
15993
|
+
const meta = await suggestPrMetadata(cwd, {
|
|
15994
|
+
base,
|
|
15995
|
+
fallbackTitle: thread.prTitle ?? thread.title
|
|
15996
|
+
});
|
|
15997
|
+
const url = await createOrUpdatePr(cwd, {
|
|
15998
|
+
title: meta.title,
|
|
15999
|
+
body: meta.body,
|
|
16000
|
+
base,
|
|
16001
|
+
head: branch,
|
|
16002
|
+
draft: action === "create-draft",
|
|
16003
|
+
web: action === "create-web"
|
|
16004
|
+
});
|
|
16005
|
+
if (!url) return;
|
|
16006
|
+
const patch = { prUrl: url, prTitle: meta.title };
|
|
16007
|
+
try {
|
|
16008
|
+
const fetched = await getPrMeta(cwd, url);
|
|
16009
|
+
if (fetched?.title) patch.prTitle = fetched.title;
|
|
16010
|
+
} catch {
|
|
16011
|
+
}
|
|
16012
|
+
updateThread(thread.id, patch);
|
|
16013
|
+
}
|
|
15796
16014
|
setThreadOptions(threadRef, patch) {
|
|
15797
16015
|
const thread = this.requireThread(threadRef);
|
|
15798
16016
|
const next = {};
|
|
@@ -16373,9 +16591,9 @@ function labelGithubUrl(url) {
|
|
|
16373
16591
|
return null;
|
|
16374
16592
|
}
|
|
16375
16593
|
if (!/(^|\.)github\.com$/i.test(parsed.hostname)) return null;
|
|
16376
|
-
const
|
|
16594
|
+
const path2 = parsed.pathname;
|
|
16377
16595
|
const hash = parsed.hash || "";
|
|
16378
|
-
const pr =
|
|
16596
|
+
const pr = path2.match(/\/([^/]+)\/([^/]+)\/pull\/(\d+)/i);
|
|
16379
16597
|
if (pr) {
|
|
16380
16598
|
const n = pr[3];
|
|
16381
16599
|
if (/#discussion_r\d+/i.test(hash) || /#pullrequestreview-\d+/i.test(hash)) {
|
|
@@ -16386,11 +16604,11 @@ function labelGithubUrl(url) {
|
|
|
16386
16604
|
}
|
|
16387
16605
|
return { kind: "pr", label: `PR #${n}`, url: raw };
|
|
16388
16606
|
}
|
|
16389
|
-
const issueComment =
|
|
16607
|
+
const issueComment = path2.match(/\/([^/]+)\/([^/]+)\/issues\/(\d+)/i);
|
|
16390
16608
|
if (issueComment && /#issuecomment-\d+/i.test(hash)) {
|
|
16391
16609
|
return { kind: "comment", label: `Issue #${issueComment[3]} comment`, url: raw };
|
|
16392
16610
|
}
|
|
16393
|
-
const blob =
|
|
16611
|
+
const blob = path2.match(/\/([^/]+)\/([^/]+)\/blob\/[^/]+\/(.+)$/i);
|
|
16394
16612
|
if (blob) {
|
|
16395
16613
|
const filePath = decodeURIComponent(blob[3]);
|
|
16396
16614
|
const fileName = filePath.split("/").pop() || filePath;
|
|
@@ -16952,10 +17170,10 @@ async function startMcpServer() {
|
|
|
16952
17170
|
const t = orch.getThread(thread_id.trim());
|
|
16953
17171
|
if (t?.worktreePath?.trim()) root = t.worktreePath;
|
|
16954
17172
|
}
|
|
16955
|
-
const
|
|
17173
|
+
const path2 = writePlanFile2(root, content);
|
|
16956
17174
|
const payload = {
|
|
16957
17175
|
ok: true,
|
|
16958
|
-
path,
|
|
17176
|
+
path: path2,
|
|
16959
17177
|
title: title?.trim() || "Plan",
|
|
16960
17178
|
message: "Plan saved to .context/attachments/plan.md and shown in Sideboard chat for approval."
|
|
16961
17179
|
};
|
|
@@ -17379,7 +17597,7 @@ async function startMcpServer() {
|
|
|
17379
17597
|
);
|
|
17380
17598
|
server.tool(
|
|
17381
17599
|
"ask_git",
|
|
17382
|
-
"
|
|
17600
|
+
"Commit & push, open a draft PR, resolve conflicts, or merge \u2014 same actions as the desktop git buttons. When the worktree is clean, Sideboard pushes / opens the PR itself (HTTPS via `gh` if SSH is missing). When dirty, queues the worktree agent to commit; then wait_for_turn. Pass a worktree thread ref (not the orchestrator). Do not run git or gh from the orchestration cwd.",
|
|
17383
17601
|
{
|
|
17384
17602
|
ref: import_zod3.z.string().describe("Worktree thread id/ref"),
|
|
17385
17603
|
action: import_zod3.z.enum(AGENT_GIT_ACTIONS).describe(
|
|
@@ -17852,9 +18070,9 @@ var BrightsySideboardApi = class {
|
|
|
17852
18070
|
get endpoint() {
|
|
17853
18071
|
return (this.cfg.endpoint || "https://brightsy.ai").replace(/\/$/, "");
|
|
17854
18072
|
}
|
|
17855
|
-
async request(
|
|
18073
|
+
async request(path2, init = {}) {
|
|
17856
18074
|
await this.refreshIfNeeded();
|
|
17857
|
-
const url = `${this.endpoint}${
|
|
18075
|
+
const url = `${this.endpoint}${path2}`;
|
|
17858
18076
|
const headers = {
|
|
17859
18077
|
Authorization: `Bearer ${this.cfg.access_token}`,
|
|
17860
18078
|
Accept: "application/json"
|
|
@@ -19461,6 +19679,83 @@ var SlackRelayHub = class {
|
|
|
19461
19679
|
// src/slack/relay-server.ts
|
|
19462
19680
|
var import_node_http3 = require("http");
|
|
19463
19681
|
var import_ws3 = require("ws");
|
|
19682
|
+
|
|
19683
|
+
// src/slack/relay-static.ts
|
|
19684
|
+
var import_node_fs37 = require("fs");
|
|
19685
|
+
var import_promises = require("fs/promises");
|
|
19686
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
19687
|
+
var TYPES = {
|
|
19688
|
+
".css": "text/css; charset=utf-8",
|
|
19689
|
+
".html": "text/html; charset=utf-8",
|
|
19690
|
+
".ico": "image/x-icon",
|
|
19691
|
+
".jpeg": "image/jpeg",
|
|
19692
|
+
".jpg": "image/jpeg",
|
|
19693
|
+
".js": "text/javascript; charset=utf-8",
|
|
19694
|
+
".json": "application/json; charset=utf-8",
|
|
19695
|
+
".png": "image/png",
|
|
19696
|
+
".svg": "image/svg+xml",
|
|
19697
|
+
".txt": "text/plain; charset=utf-8",
|
|
19698
|
+
".webp": "image/webp",
|
|
19699
|
+
".woff2": "font/woff2"
|
|
19700
|
+
};
|
|
19701
|
+
function requestHostname(req) {
|
|
19702
|
+
const raw = req.headers.host ?? "";
|
|
19703
|
+
return raw.split(":")[0]?.toLowerCase() ?? "";
|
|
19704
|
+
}
|
|
19705
|
+
function hostnameAllowed(host, allowed) {
|
|
19706
|
+
if (!allowed || allowed.length === 0) return true;
|
|
19707
|
+
return allowed.includes(host);
|
|
19708
|
+
}
|
|
19709
|
+
function resolveStaticPath(root, requestUrl) {
|
|
19710
|
+
let pathname;
|
|
19711
|
+
try {
|
|
19712
|
+
pathname = decodeURIComponent(new URL(requestUrl, "http://relay.local").pathname);
|
|
19713
|
+
} catch {
|
|
19714
|
+
return null;
|
|
19715
|
+
}
|
|
19716
|
+
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
19717
|
+
const rootResolved = import_node_path33.default.resolve(root);
|
|
19718
|
+
const candidate = import_node_path33.default.resolve(rootResolved, `.${pathname}`);
|
|
19719
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path33.default.sep)) {
|
|
19720
|
+
return null;
|
|
19721
|
+
}
|
|
19722
|
+
return candidate;
|
|
19723
|
+
}
|
|
19724
|
+
async function fileSize(file) {
|
|
19725
|
+
try {
|
|
19726
|
+
const st = await (0, import_promises.stat)(file);
|
|
19727
|
+
return st.isFile() ? st.size : null;
|
|
19728
|
+
} catch {
|
|
19729
|
+
return null;
|
|
19730
|
+
}
|
|
19731
|
+
}
|
|
19732
|
+
function sendFile(req, res, file, size) {
|
|
19733
|
+
const ext = import_node_path33.default.extname(file).toLowerCase();
|
|
19734
|
+
res.writeHead(200, {
|
|
19735
|
+
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
19736
|
+
"Content-Length": size,
|
|
19737
|
+
"Cache-Control": ext === ".html" ? "no-cache" : "public, max-age=3600"
|
|
19738
|
+
});
|
|
19739
|
+
if (req.method === "HEAD") {
|
|
19740
|
+
res.end();
|
|
19741
|
+
return true;
|
|
19742
|
+
}
|
|
19743
|
+
(0, import_node_fs37.createReadStream)(file).pipe(res);
|
|
19744
|
+
return true;
|
|
19745
|
+
}
|
|
19746
|
+
async function tryServeStatic(req, res, root) {
|
|
19747
|
+
if (req.method !== "GET" && req.method !== "HEAD") return false;
|
|
19748
|
+
const candidate = resolveStaticPath(root, req.url || "/");
|
|
19749
|
+
if (!candidate) return false;
|
|
19750
|
+
const direct = await fileSize(candidate);
|
|
19751
|
+
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
19752
|
+
const asIndex = import_node_path33.default.join(candidate, "index.html");
|
|
19753
|
+
const indexSize = await fileSize(asIndex);
|
|
19754
|
+
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
19755
|
+
return false;
|
|
19756
|
+
}
|
|
19757
|
+
|
|
19758
|
+
// src/slack/relay-server.ts
|
|
19464
19759
|
function sendHtml(res, status, title, body) {
|
|
19465
19760
|
res.writeHead(status, { "Content-Type": "text/html; charset=utf-8" });
|
|
19466
19761
|
res.end(slackOAuthHtmlPage(title, body));
|
|
@@ -19559,7 +19854,26 @@ async function startSlackRelayServer(opts) {
|
|
|
19559
19854
|
const reqUrl = req.url || "/";
|
|
19560
19855
|
if (await handleCallback(reqUrl, res)) return;
|
|
19561
19856
|
if (handleResult(reqUrl, res)) return;
|
|
19562
|
-
if (req.url === "/health"
|
|
19857
|
+
if (req.url === "/health") {
|
|
19858
|
+
sendJson(res, 200, {
|
|
19859
|
+
ok: true,
|
|
19860
|
+
service: "sideboard-slack-relay",
|
|
19861
|
+
sessions: hub.listSessions().length,
|
|
19862
|
+
oauth: Boolean(clientSecret)
|
|
19863
|
+
});
|
|
19864
|
+
return;
|
|
19865
|
+
}
|
|
19866
|
+
const hostname2 = requestHostname(req);
|
|
19867
|
+
const canonical = (opts.canonicalSiteHost ?? "www.sideboard.cloud").toLowerCase();
|
|
19868
|
+
if (opts.redirectHosts?.includes(hostname2) && hostname2 !== canonical) {
|
|
19869
|
+
res.writeHead(301, { Location: `https://${canonical}${reqUrl}` });
|
|
19870
|
+
res.end();
|
|
19871
|
+
return;
|
|
19872
|
+
}
|
|
19873
|
+
if (opts.staticRoot && hostnameAllowed(hostname2, opts.staticHosts) && await tryServeStatic(req, res, opts.staticRoot)) {
|
|
19874
|
+
return;
|
|
19875
|
+
}
|
|
19876
|
+
if (req.url === "/") {
|
|
19563
19877
|
sendJson(res, 200, {
|
|
19564
19878
|
ok: true,
|
|
19565
19879
|
service: "sideboard-slack-relay",
|
|
@@ -19669,6 +19983,7 @@ async function startSlackRelayServer(opts) {
|
|
|
19669
19983
|
CONTEXT_MIN_MESSAGES,
|
|
19670
19984
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
19671
19985
|
FAMOUS_SOCCER_TEAMS,
|
|
19986
|
+
GITHUB_GIT_AUTH_MODES,
|
|
19672
19987
|
GLOBAL_WORKSPACE_ID,
|
|
19673
19988
|
HARNESS_ENV_KEYS,
|
|
19674
19989
|
LEGACY_ATTACHMENTS_DIR,
|
|
@@ -19718,10 +20033,12 @@ async function startSlackRelayServer(opts) {
|
|
|
19718
20033
|
allocateTeamSlug,
|
|
19719
20034
|
appDataDir,
|
|
19720
20035
|
appSettingsPath,
|
|
20036
|
+
appendIndexedGitConfig,
|
|
19721
20037
|
appendMessage,
|
|
19722
20038
|
applyAgentEvent,
|
|
19723
20039
|
applyAppEnvironment,
|
|
19724
20040
|
applyCompaction,
|
|
20041
|
+
applyGithubGitAuthEnv,
|
|
19725
20042
|
applyThreadIntoMain,
|
|
19726
20043
|
applyTurnUsage,
|
|
19727
20044
|
assertOrchestratorCapableAgent,
|
|
@@ -19836,6 +20153,7 @@ async function startSlackRelayServer(opts) {
|
|
|
19836
20153
|
formatBrightsyFetchError,
|
|
19837
20154
|
formatFetchError,
|
|
19838
20155
|
formatGhLandError,
|
|
20156
|
+
formatGitAuthModeDirective,
|
|
19839
20157
|
formatIpcInvokeError,
|
|
19840
20158
|
formatMessagesAsTranscript,
|
|
19841
20159
|
formatPlanQuestionAnswers,
|
|
@@ -19862,6 +20180,8 @@ async function startSlackRelayServer(opts) {
|
|
|
19862
20180
|
getDiff,
|
|
19863
20181
|
getDiffSummary,
|
|
19864
20182
|
getGitHubStatus,
|
|
20183
|
+
getGithubGitAuthMode,
|
|
20184
|
+
getGithubPat,
|
|
19865
20185
|
getIssueSource,
|
|
19866
20186
|
getLinearApiKey,
|
|
19867
20187
|
getLinearAuthToken,
|
|
@@ -19880,6 +20200,7 @@ async function startSlackRelayServer(opts) {
|
|
|
19880
20200
|
ghHeadRef,
|
|
19881
20201
|
ghRepoSelectArgs,
|
|
19882
20202
|
git,
|
|
20203
|
+
githubAgentGitEnv,
|
|
19883
20204
|
globalAgentCwd,
|
|
19884
20205
|
handleSlackInbound,
|
|
19885
20206
|
harnessEnvKey,
|
|
@@ -20102,6 +20423,7 @@ async function startSlackRelayServer(opts) {
|
|
|
20102
20423
|
startSlackOAuth,
|
|
20103
20424
|
startSlackRelayServer,
|
|
20104
20425
|
stripBrightsyNdjsonNoise,
|
|
20426
|
+
stripNestedElectronEnv,
|
|
20105
20427
|
submitPrStack,
|
|
20106
20428
|
suggestSlug,
|
|
20107
20429
|
summarizeConversation,
|