@sideboard-ai/core 0.1.89 → 0.1.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/cursor-runner.cjs +129 -14
- package/dist/agents/cursor-runner.js +4 -1
- package/dist/{agents-LMUFTGKF.js → agents-HBLA6FEV.js} +4 -4
- package/dist/{agents-ODBP7J6E.js → agents-WS5QV6LE.js} +5 -5
- package/dist/{chunk-WANQFU3S.js → chunk-6XBXVXX2.js} +2 -2
- package/dist/{chunk-7D27DD2X.js → chunk-CIRXAYWS.js} +260 -61
- package/dist/{chunk-B2KIO2SD.js → chunk-CLGO7TLO.js} +2 -2
- package/dist/{chunk-CBJSPTBG.js → chunk-GXSYI7FH.js} +206 -5
- package/dist/{chunk-RJLBSYUO.js → chunk-KWNUZ4LR.js} +46 -77
- package/dist/{chunk-UHTNJKZX.js → chunk-NR6APJLD.js} +2 -2
- package/dist/{chunk-6EZRSCIT.js → chunk-QKYO6BHB.js} +2 -2
- package/dist/{chunk-ZXYWWSHZ.js → chunk-R7BQBSDT.js} +254 -61
- package/dist/{chunk-JE75QW2I.js → chunk-WBX46OPD.js} +237 -96
- package/dist/{chunk-OB6IRIFV.js → chunk-XH2GS2LO.js} +2 -2
- package/dist/{chunk-VZ2L4AEJ.js → chunk-XUWDLRAE.js} +2 -2
- package/dist/{coordinator-prompt-UK5LYFN5.js → coordinator-prompt-AKEY4WSO.js} +2 -2
- package/dist/{coordinator-prompt-CI5SHONJ.js → coordinator-prompt-OQOOD5ET.js} +2 -2
- package/dist/{global-workspace-2YZ2V4I5.js → global-workspace-3GNPQCLE.js} +3 -3
- package/dist/{global-workspace-JQQLPJM5.js → global-workspace-M3OMVDDH.js} +3 -3
- package/dist/index.cjs +1021 -473
- package/dist/index.d.cts +91 -20
- package/dist/index.d.ts +91 -20
- package/dist/index.js +244 -59
- package/dist/mcp/run-stdio.cjs +816 -428
- package/dist/mcp/run-stdio.js +77 -40
- package/dist/{workspaces-YWCC3WV4.js → workspaces-ERZC7ULY.js} +4 -4
- package/dist/{workspaces-FDO5L4NI.js → workspaces-J4WG6UFR.js} +4 -4
- package/dist/{worktree-7YNSJ224.js → worktree-DA4BOV7G.js} +7 -1
- package/dist/{worktree-4555QBQ7.js → worktree-EO5QAGJU.js} +7 -1
- package/package.json +1 -1
|
@@ -18,8 +18,8 @@ import {
|
|
|
18
18
|
} from "./chunk-LGXBYZZA.js";
|
|
19
19
|
|
|
20
20
|
// src/git/worktree.ts
|
|
21
|
-
import { existsSync, readdirSync } from "fs";
|
|
22
|
-
import { join } from "path";
|
|
21
|
+
import { existsSync as existsSync2, readdirSync } from "fs";
|
|
22
|
+
import { join as join2 } from "path";
|
|
23
23
|
|
|
24
24
|
// src/git/team-meta.ts
|
|
25
25
|
var SOCCER_TEAM_META = {
|
|
@@ -904,13 +904,96 @@ function formatIpcInvokeError(err) {
|
|
|
904
904
|
return formatGhLandError(msg);
|
|
905
905
|
}
|
|
906
906
|
|
|
907
|
+
// src/git/git-auth-mode.ts
|
|
908
|
+
import { isAbsolute } from "path";
|
|
909
|
+
|
|
910
|
+
// src/git/github-agent-auth.ts
|
|
911
|
+
import { chmodSync, existsSync, mkdirSync, writeFileSync } from "fs";
|
|
912
|
+
import { homedir } from "os";
|
|
913
|
+
import { dirname, join } from "path";
|
|
914
|
+
function githubAgentAuthDir() {
|
|
915
|
+
const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
|
|
916
|
+
if (override) return override;
|
|
917
|
+
return join(homedir(), ".sideboard-git-auth");
|
|
918
|
+
}
|
|
919
|
+
function githubCredentialStorePath() {
|
|
920
|
+
return join(githubAgentAuthDir(), "git-credentials");
|
|
921
|
+
}
|
|
922
|
+
function githubGhConfigDir() {
|
|
923
|
+
return join(githubAgentAuthDir(), "gh");
|
|
924
|
+
}
|
|
925
|
+
function writePrivateFile(file, body) {
|
|
926
|
+
mkdirSync(dirname(file), { recursive: true, mode: 448 });
|
|
927
|
+
try {
|
|
928
|
+
chmodSync(dirname(file), 448);
|
|
929
|
+
} catch {
|
|
930
|
+
}
|
|
931
|
+
writeFileSync(file, body, { encoding: "utf8", mode: 384 });
|
|
932
|
+
try {
|
|
933
|
+
chmodSync(file, 384);
|
|
934
|
+
} catch {
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
function gitCredentialStoreContents(token) {
|
|
938
|
+
return `https://x-access-token:${encodeURIComponent(token)}@github.com
|
|
939
|
+
`;
|
|
940
|
+
}
|
|
941
|
+
function ghHostsYml(token, user = "x-access-token") {
|
|
942
|
+
const u = user.replace(/[^A-Za-z0-9._-]/g, "") || "x-access-token";
|
|
943
|
+
return [
|
|
944
|
+
"github.com:",
|
|
945
|
+
" git_protocol: https",
|
|
946
|
+
` user: ${u}`,
|
|
947
|
+
` oauth_token: ${token}`,
|
|
948
|
+
" users:",
|
|
949
|
+
` ${u}:`,
|
|
950
|
+
` oauth_token: ${token}`,
|
|
951
|
+
""
|
|
952
|
+
].join("\n");
|
|
953
|
+
}
|
|
954
|
+
function materializeGithubAgentAuth(token, user) {
|
|
955
|
+
const trimmed = token.trim();
|
|
956
|
+
if (!trimmed) return;
|
|
957
|
+
const root = githubAgentAuthDir();
|
|
958
|
+
mkdirSync(root, { recursive: true, mode: 448 });
|
|
959
|
+
try {
|
|
960
|
+
chmodSync(root, 448);
|
|
961
|
+
} catch {
|
|
962
|
+
}
|
|
963
|
+
writePrivateFile(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
|
|
964
|
+
const ghDir = githubGhConfigDir();
|
|
965
|
+
mkdirSync(ghDir, { recursive: true, mode: 448 });
|
|
966
|
+
writePrivateFile(join(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
|
|
967
|
+
writePrivateFile(join(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
|
|
968
|
+
}
|
|
969
|
+
function githubAgentAuthReady() {
|
|
970
|
+
return existsSync(githubCredentialStorePath()) && existsSync(join(githubGhConfigDir(), "hosts.yml"));
|
|
971
|
+
}
|
|
972
|
+
function githubCredentialHelperGitConfig() {
|
|
973
|
+
const file = githubCredentialStorePath();
|
|
974
|
+
return [
|
|
975
|
+
{ key: "credential.helper", value: "" },
|
|
976
|
+
{ key: "credential.helper", value: `store --file=${file}` }
|
|
977
|
+
];
|
|
978
|
+
}
|
|
979
|
+
function githubGhConfigEnv() {
|
|
980
|
+
return {
|
|
981
|
+
GH_CONFIG_DIR: githubGhConfigDir(),
|
|
982
|
+
GH_PROMPT_DISABLED: "1"
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
|
|
907
986
|
// src/git/git-auth-mode.ts
|
|
908
987
|
var HTTPS_REWRITE = [
|
|
909
988
|
{ key: "url.https://github.com/.insteadOf", value: "git@github.com:" },
|
|
910
|
-
{ key: "url.https://github.com/.insteadOf", value: "ssh://git@github.com/" }
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
989
|
+
{ key: "url.https://github.com/.insteadOf", value: "ssh://git@github.com/" }
|
|
990
|
+
];
|
|
991
|
+
var TOKEN_TTL_MS = 12 * 60 * 60 * 1e3;
|
|
992
|
+
var tokenMemo = null;
|
|
993
|
+
var GITHUB_CHILD_TOKEN_KEYS = [
|
|
994
|
+
"GH_TOKEN",
|
|
995
|
+
"GITHUB_TOKEN",
|
|
996
|
+
"GH_ENTERPRISE_TOKEN"
|
|
914
997
|
];
|
|
915
998
|
function nonInteractiveGitProcessEnv() {
|
|
916
999
|
return {
|
|
@@ -935,42 +1018,46 @@ function appendIndexedGitConfig(existing, entries) {
|
|
|
935
1018
|
return out;
|
|
936
1019
|
}
|
|
937
1020
|
function githubAgentGitEnv(existing) {
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
function githubHttpsBearerEnv(existing, token) {
|
|
941
|
-
const rewrite = githubAgentGitEnv(existing);
|
|
942
|
-
const header = appendIndexedGitConfig(
|
|
943
|
-
{ ...existing, ...rewrite },
|
|
944
|
-
[
|
|
945
|
-
{
|
|
946
|
-
key: "http.https://github.com/.extraHeader",
|
|
947
|
-
value: `AUTHORIZATION: bearer ${token}`
|
|
948
|
-
}
|
|
949
|
-
]
|
|
950
|
-
);
|
|
951
|
-
return { ...rewrite, ...header };
|
|
1021
|
+
const helpers = githubAgentAuthReady() ? githubCredentialHelperGitConfig() : [{ key: "credential.helper", value: "" }];
|
|
1022
|
+
return appendIndexedGitConfig(existing, [...HTTPS_REWRITE, ...helpers]);
|
|
952
1023
|
}
|
|
953
1024
|
function applyGithubGitAuthEnv(existing, opts) {
|
|
954
1025
|
const out = { ...nonInteractiveGitProcessEnv() };
|
|
1026
|
+
const token = opts.token?.trim() || existing?.GH_TOKEN?.trim() || "" || "";
|
|
1027
|
+
if (token) materializeGithubAgentAuth(token);
|
|
1028
|
+
Object.assign(out, githubGhConfigEnv());
|
|
955
1029
|
if (opts.mode === "ssh") return out;
|
|
956
|
-
|
|
957
|
-
const provided = existingToken ? "" : opts.token?.trim() || "";
|
|
958
|
-
const token = existingToken || provided;
|
|
959
|
-
Object.assign(
|
|
960
|
-
out,
|
|
961
|
-
token ? githubHttpsBearerEnv(existing, token) : githubAgentGitEnv(existing)
|
|
962
|
-
);
|
|
963
|
-
if (provided) out.GH_TOKEN = provided;
|
|
1030
|
+
Object.assign(out, githubAgentGitEnv(existing));
|
|
964
1031
|
return out;
|
|
965
1032
|
}
|
|
1033
|
+
function scrubGithubTokensFromChildEnv(env) {
|
|
1034
|
+
for (const key of GITHUB_CHILD_TOKEN_KEYS) {
|
|
1035
|
+
delete env[key];
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
function mergeAgentGitAuthEnv(env, gitEnv) {
|
|
1039
|
+
Object.assign(env, gitEnv);
|
|
1040
|
+
scrubGithubTokensFromChildEnv(env);
|
|
1041
|
+
}
|
|
966
1042
|
async function resolveGithubAgentToken(mode, cwd) {
|
|
967
|
-
if (mode ===
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1043
|
+
if (tokenMemo && tokenMemo.mode === mode && Date.now() - tokenMemo.at < TOKEN_TTL_MS) {
|
|
1044
|
+
return tokenMemo.value;
|
|
1045
|
+
}
|
|
1046
|
+
let value = null;
|
|
1047
|
+
if (mode === "token") {
|
|
1048
|
+
value = getGithubPat();
|
|
1049
|
+
} else {
|
|
1050
|
+
try {
|
|
1051
|
+
value = await resolveGhAuthToken(cwd);
|
|
1052
|
+
} catch {
|
|
1053
|
+
value = null;
|
|
1054
|
+
}
|
|
973
1055
|
}
|
|
1056
|
+
tokenMemo = { mode, value, at: Date.now() };
|
|
1057
|
+
return value;
|
|
1058
|
+
}
|
|
1059
|
+
function resetGithubAgentTokenMemo() {
|
|
1060
|
+
tokenMemo = null;
|
|
974
1061
|
}
|
|
975
1062
|
async function resolveAgentGitAuthEnv(existing, opts) {
|
|
976
1063
|
let mode = "auto";
|
|
@@ -992,7 +1079,40 @@ async function resolveAgentGitAuthEnv(existing, opts) {
|
|
|
992
1079
|
}
|
|
993
1080
|
return applyGithubGitAuthEnv(existing, { mode, token });
|
|
994
1081
|
}
|
|
995
|
-
function
|
|
1082
|
+
async function warmGithubAgentAuth(opts) {
|
|
1083
|
+
if (!opts?.force && githubAgentAuthReady()) return;
|
|
1084
|
+
await resolveAgentGitAuthEnv(void 0, opts);
|
|
1085
|
+
}
|
|
1086
|
+
function normalizeWritableRoot(raw) {
|
|
1087
|
+
const trimmed = raw.trim().replace(/\/+$/, "");
|
|
1088
|
+
return trimmed && isAbsolute(trimmed) ? trimmed : null;
|
|
1089
|
+
}
|
|
1090
|
+
async function resolveCodexGitWritableRoots(cwd) {
|
|
1091
|
+
const roots = /* @__PURE__ */ new Set();
|
|
1092
|
+
const authDir = normalizeWritableRoot(githubAgentAuthDir());
|
|
1093
|
+
if (authDir) roots.add(authDir);
|
|
1094
|
+
try {
|
|
1095
|
+
const [gitDir, commonDir] = await Promise.all([
|
|
1096
|
+
git(["rev-parse", "--absolute-git-dir"], cwd, { reject: false, timeoutMs: 5e3 }),
|
|
1097
|
+
git(["rev-parse", "--path-format=absolute", "--git-common-dir"], cwd, {
|
|
1098
|
+
reject: false,
|
|
1099
|
+
timeoutMs: 5e3
|
|
1100
|
+
})
|
|
1101
|
+
]);
|
|
1102
|
+
const gitDirPath = gitDir.exitCode === 0 ? normalizeWritableRoot(gitDir.stdout) : null;
|
|
1103
|
+
const commonPath = commonDir.exitCode === 0 ? normalizeWritableRoot(commonDir.stdout) : null;
|
|
1104
|
+
if (gitDirPath) roots.add(gitDirPath);
|
|
1105
|
+
if (commonPath) roots.add(commonPath);
|
|
1106
|
+
} catch {
|
|
1107
|
+
}
|
|
1108
|
+
return [...roots];
|
|
1109
|
+
}
|
|
1110
|
+
function codexSandboxWritableRootsArgs(roots) {
|
|
1111
|
+
const abs = [...new Set(roots.map(normalizeWritableRoot).filter(Boolean))];
|
|
1112
|
+
if (abs.length === 0) return [];
|
|
1113
|
+
return ["-c", `sandbox_workspace_write.writable_roots=${JSON.stringify(abs)}`];
|
|
1114
|
+
}
|
|
1115
|
+
function codexUnattendedGitConfigArgs(sandbox, opts) {
|
|
996
1116
|
const args = [
|
|
997
1117
|
"-c",
|
|
998
1118
|
'shell_environment_policy.inherit="all"',
|
|
@@ -1001,39 +1121,44 @@ function codexUnattendedGitConfigArgs(sandbox) {
|
|
|
1001
1121
|
];
|
|
1002
1122
|
if (sandbox === "workspace-write") {
|
|
1003
1123
|
args.push("-c", "sandbox_workspace_write.network_access=true");
|
|
1124
|
+
args.push(...codexSandboxWritableRootsArgs(opts?.writableRoots ?? []));
|
|
1004
1125
|
}
|
|
1005
1126
|
return args;
|
|
1006
1127
|
}
|
|
1007
1128
|
function formatGitAuthModeDirective(mode) {
|
|
1129
|
+
const shared = [
|
|
1130
|
+
"- `git` and `gh` already authenticate in this process. Do not look for tokens in the environment, paste credentials into commands, or switch remotes to SSH.",
|
|
1131
|
+
"- Do not set GitHub token environment variables, pass `--with-token`, or run `gh auth login` from this turn.",
|
|
1132
|
+
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below.",
|
|
1133
|
+
"- If git/gh fail with auth errors, tell the user to run `gh auth login` on this Mac (or set a PAT in Account \u2192 GitHub). Do not wait for a Keychain dialog."
|
|
1134
|
+
];
|
|
1008
1135
|
switch (mode) {
|
|
1009
1136
|
case "gh":
|
|
1010
1137
|
return [
|
|
1011
1138
|
"Git authentication (Account \u2192 GitHub mode: gh CLI):",
|
|
1012
1139
|
"- This process rewrites `git@github.com:` and `ssh://git@github.com/` to HTTPS.",
|
|
1013
|
-
|
|
1014
|
-
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below."
|
|
1140
|
+
...shared
|
|
1015
1141
|
].join("\n");
|
|
1016
1142
|
case "ssh":
|
|
1017
1143
|
return [
|
|
1018
1144
|
"Git authentication (Account \u2192 GitHub mode: SSH):",
|
|
1019
1145
|
"- Keep SSH remotes (`git@github.com:\u2026`). Do not rewrite them to HTTPS.",
|
|
1020
1146
|
"- SSH is batch-mode: it will not prompt for a Keychain password. If push fails with `Permission denied (publickey)`, tell the user to unlock ssh-agent or switch Account \u2192 GitHub to Auto / gh CLI \u2014 do not rewrite remotes yourself.",
|
|
1021
|
-
"-
|
|
1147
|
+
"- `gh` already authenticates for PRs/API (no token in the environment). Do not set GitHub token environment variables or run `gh auth login` from this turn.",
|
|
1148
|
+
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below."
|
|
1022
1149
|
].join("\n");
|
|
1023
1150
|
case "token":
|
|
1024
1151
|
return [
|
|
1025
1152
|
"Git authentication (Account \u2192 GitHub mode: personal access token):",
|
|
1026
1153
|
"- This process rewrites GitHub SSH remotes to HTTPS.",
|
|
1027
|
-
|
|
1028
|
-
"- Push with `git push -u origin HEAD`. Create/update PRs with `gh` as below."
|
|
1154
|
+
...shared
|
|
1029
1155
|
].join("\n");
|
|
1030
1156
|
case "auto":
|
|
1031
1157
|
default:
|
|
1032
1158
|
return [
|
|
1033
1159
|
"Git authentication (Account \u2192 GitHub mode: auto):",
|
|
1034
|
-
"- This process rewrites GitHub SSH remotes to HTTPS
|
|
1035
|
-
|
|
1036
|
-
"- If HTTPS auth fails, tell the user to run `gh auth login` on this Mac or set Account \u2192 GitHub to a PAT \u2014 do not wait for a Keychain dialog."
|
|
1160
|
+
"- This process rewrites GitHub SSH remotes to HTTPS so git/ssh never prompt the macOS Keychain (required for unattended orchestrator turns).",
|
|
1161
|
+
...shared
|
|
1037
1162
|
].join("\n");
|
|
1038
1163
|
}
|
|
1039
1164
|
}
|
|
@@ -1442,7 +1567,7 @@ async function originGhRepoEnv(cwd, opts) {
|
|
|
1442
1567
|
await ensureGhPreferOrigin(cwd);
|
|
1443
1568
|
const slug = await resolveGithubRepoSlug(cwd);
|
|
1444
1569
|
const mode = opts?.mode ?? getGithubGitAuthMode();
|
|
1445
|
-
const token =
|
|
1570
|
+
const token = await resolveGithubAgentToken(mode, cwd);
|
|
1446
1571
|
return {
|
|
1447
1572
|
...applyGithubGitAuthEnv(opts?.env, { mode, token }),
|
|
1448
1573
|
...slug ? { GH_REPO: slug } : {}
|
|
@@ -1582,13 +1707,78 @@ async function getPr(repoPath, number) {
|
|
|
1582
1707
|
if (exitCode !== 0 || !stdout.trim()) return null;
|
|
1583
1708
|
return JSON.parse(stdout);
|
|
1584
1709
|
}
|
|
1585
|
-
function
|
|
1586
|
-
|
|
1710
|
+
function normalizeGitBranchName(ref) {
|
|
1711
|
+
return ref.trim().replace(/^refs\/heads\//, "").replace(/^origin\//, "");
|
|
1712
|
+
}
|
|
1713
|
+
function isDefaultishSourceRef(ref) {
|
|
1714
|
+
const n = normalizeGitBranchName(ref ?? "").toLowerCase();
|
|
1715
|
+
return !n || n === "head" || n === "default" || n === "main" || n === "master" || n === "develop" || n === "trunk";
|
|
1716
|
+
}
|
|
1717
|
+
function resolvePrSelectors(thread) {
|
|
1718
|
+
const out = [];
|
|
1719
|
+
const push = (value) => {
|
|
1720
|
+
const v = value?.trim();
|
|
1721
|
+
if (!v || out.includes(v)) return;
|
|
1722
|
+
out.push(v);
|
|
1723
|
+
};
|
|
1724
|
+
push(thread.prUrl);
|
|
1587
1725
|
if (thread.sourceType === "pr" && thread.sourceRef?.trim()) {
|
|
1588
|
-
|
|
1726
|
+
push(thread.sourceRef.replace(/^#/, "").trim());
|
|
1727
|
+
}
|
|
1728
|
+
push(thread.branchName);
|
|
1729
|
+
if (thread.sourceType === "branch") {
|
|
1730
|
+
const source = normalizeGitBranchName(thread.sourceRef ?? "");
|
|
1731
|
+
if (source && !isDefaultishSourceRef(source) && source !== thread.branchName?.trim()) {
|
|
1732
|
+
push(source);
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
return out;
|
|
1736
|
+
}
|
|
1737
|
+
function resolvePrSelector(thread) {
|
|
1738
|
+
return resolvePrSelectors(thread)[0] ?? null;
|
|
1739
|
+
}
|
|
1740
|
+
async function getPrForHeadBranch(repoPath, branch) {
|
|
1741
|
+
const head = normalizeGitBranchName(branch);
|
|
1742
|
+
if (!head || isDefaultishSourceRef(head)) return null;
|
|
1743
|
+
const slug = await resolveGithubRepoSlug(repoPath);
|
|
1744
|
+
const viewArgs = [
|
|
1745
|
+
"pr",
|
|
1746
|
+
"view",
|
|
1747
|
+
head,
|
|
1748
|
+
"--json",
|
|
1749
|
+
"number,title,headRefName,url,isCrossRepository"
|
|
1750
|
+
];
|
|
1751
|
+
if (slug) viewArgs.push("--repo", slug);
|
|
1752
|
+
const viewed = await gh(viewArgs, repoPath, { reject: false });
|
|
1753
|
+
if (viewed.exitCode === 0 && viewed.stdout.trim()) {
|
|
1754
|
+
try {
|
|
1755
|
+
return JSON.parse(viewed.stdout);
|
|
1756
|
+
} catch {
|
|
1757
|
+
return null;
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
const listHead = slug ? ghHeadRef(slug, head) : head;
|
|
1761
|
+
const listArgs = [
|
|
1762
|
+
"pr",
|
|
1763
|
+
"list",
|
|
1764
|
+
"--head",
|
|
1765
|
+
listHead,
|
|
1766
|
+
"--json",
|
|
1767
|
+
"number,title,headRefName,url,isCrossRepository",
|
|
1768
|
+
"--limit",
|
|
1769
|
+
"1",
|
|
1770
|
+
"--state",
|
|
1771
|
+
"open"
|
|
1772
|
+
];
|
|
1773
|
+
if (slug) listArgs.push("--repo", slug);
|
|
1774
|
+
const listed = await gh(listArgs, repoPath, { reject: false });
|
|
1775
|
+
if (listed.exitCode !== 0 || !listed.stdout.trim()) return null;
|
|
1776
|
+
try {
|
|
1777
|
+
const rows = JSON.parse(listed.stdout);
|
|
1778
|
+
return rows[0] ?? null;
|
|
1779
|
+
} catch {
|
|
1780
|
+
return null;
|
|
1589
1781
|
}
|
|
1590
|
-
if (thread.branchName?.trim()) return thread.branchName.trim();
|
|
1591
|
-
return null;
|
|
1592
1782
|
}
|
|
1593
1783
|
function normalizeGhTime(value) {
|
|
1594
1784
|
if (typeof value !== "string" || !value.trim()) return null;
|
|
@@ -1914,7 +2104,7 @@ async function fetchPrHead(repoPath, number, localBranch) {
|
|
|
1914
2104
|
const label = opts?.ghAuth ? `${remote} (gh auth)` : remote;
|
|
1915
2105
|
const gitOpts = { reject: false };
|
|
1916
2106
|
if (opts?.ghAuth) {
|
|
1917
|
-
const token = await
|
|
2107
|
+
const token = await resolveGithubAgentToken(getGithubGitAuthMode(), repoPath);
|
|
1918
2108
|
if (!token) {
|
|
1919
2109
|
errors.push(`${label}: gh auth token unavailable`);
|
|
1920
2110
|
return false;
|
|
@@ -1965,7 +2155,7 @@ async function fetchPrHead(repoPath, number, localBranch) {
|
|
|
1965
2155
|
const ensureOid = async (remote, opts) => {
|
|
1966
2156
|
const gitOpts = { reject: false };
|
|
1967
2157
|
if (opts?.ghAuth) {
|
|
1968
|
-
const token = await
|
|
2158
|
+
const token = await resolveGithubAgentToken(getGithubGitAuthMode(), repoPath);
|
|
1969
2159
|
if (!token) return false;
|
|
1970
2160
|
gitOpts.env = { GIT_TERMINAL_PROMPT: "0" };
|
|
1971
2161
|
gitOpts.config = {
|
|
@@ -2033,8 +2223,8 @@ function isLocalPrFetchBranch(ref) {
|
|
|
2033
2223
|
}
|
|
2034
2224
|
async function createThreadWorktree(opts) {
|
|
2035
2225
|
let branchName = `thread/${opts.slug}`;
|
|
2036
|
-
const worktreePath =
|
|
2037
|
-
if (
|
|
2226
|
+
const worktreePath = join2(worktreesRoot(opts.repoPath), opts.slug);
|
|
2227
|
+
if (existsSync2(worktreePath)) {
|
|
2038
2228
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
2039
2229
|
}
|
|
2040
2230
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -2103,8 +2293,8 @@ ${add.stdout}`;
|
|
|
2103
2293
|
async function createExistingBranchWorktree(opts) {
|
|
2104
2294
|
const branchName = opts.branchName.trim();
|
|
2105
2295
|
if (!branchName) throw new Error("branch name required");
|
|
2106
|
-
const worktreePath =
|
|
2107
|
-
if (
|
|
2296
|
+
const worktreePath = join2(worktreesRoot(opts.repoPath), opts.slug);
|
|
2297
|
+
if (existsSync2(worktreePath)) {
|
|
2108
2298
|
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
2109
2299
|
}
|
|
2110
2300
|
await ensureGhPreferOrigin(opts.repoPath);
|
|
@@ -2215,7 +2405,7 @@ async function pushBranch(worktreePath, branchName) {
|
|
|
2215
2405
|
if (ssh.exitCode === 0) return;
|
|
2216
2406
|
const sshErr = (ssh.stderr || ssh.stdout).trim();
|
|
2217
2407
|
const slug = await resolveGithubRepoSlug(worktreePath);
|
|
2218
|
-
const token = await
|
|
2408
|
+
const token = await resolveGithubAgentToken(getGithubGitAuthMode(), worktreePath);
|
|
2219
2409
|
if (!slug || !token) {
|
|
2220
2410
|
throw new Error(
|
|
2221
2411
|
sshErr || `git push origin ${branchName} failed` + (!token ? " (no SSH agent and gh auth token unavailable \u2014 run: gh auth login)" : "")
|
|
@@ -2392,8 +2582,8 @@ function sameRepoPath(a, b) {
|
|
|
2392
2582
|
return normalizeWorktreePath(a) === normalizeWorktreePath(b);
|
|
2393
2583
|
}
|
|
2394
2584
|
function listLocalThreadBranchSlugs(repoPath) {
|
|
2395
|
-
const refsDir =
|
|
2396
|
-
if (!
|
|
2585
|
+
const refsDir = join2(repoPath, ".git", "refs", "heads", "thread");
|
|
2586
|
+
if (!existsSync2(refsDir)) return [];
|
|
2397
2587
|
try {
|
|
2398
2588
|
return readdirSync(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
|
|
2399
2589
|
} catch {
|
|
@@ -2403,7 +2593,7 @@ function listLocalThreadBranchSlugs(repoPath) {
|
|
|
2403
2593
|
function collectTakenTeamSlugs(repoPath) {
|
|
2404
2594
|
const taken = /* @__PURE__ */ new Set();
|
|
2405
2595
|
const root = worktreesRoot(repoPath);
|
|
2406
|
-
if (
|
|
2596
|
+
if (existsSync2(root)) {
|
|
2407
2597
|
for (const entry of readdirSync(root, { withFileTypes: true })) {
|
|
2408
2598
|
if (entry.isDirectory() && entry.name !== ".DS_Store") {
|
|
2409
2599
|
taken.add(normalizeTakenSlug(entry.name));
|
|
@@ -2425,8 +2615,8 @@ function allocateTeamSlug(repoPath) {
|
|
|
2425
2615
|
const taken = collectTakenTeamSlugs(repoPath);
|
|
2426
2616
|
for (let attempt = 0; attempt < 32; attempt++) {
|
|
2427
2617
|
const team = allocateTeamName(taken);
|
|
2428
|
-
const path =
|
|
2429
|
-
if (!
|
|
2618
|
+
const path = join2(worktreesRoot(repoPath), team.slug);
|
|
2619
|
+
if (!existsSync2(path)) return team;
|
|
2430
2620
|
taken.add(team.slug);
|
|
2431
2621
|
}
|
|
2432
2622
|
throw new Error("No available soccer team worktree directories left");
|
|
@@ -2456,8 +2646,14 @@ export {
|
|
|
2456
2646
|
appendIndexedGitConfig,
|
|
2457
2647
|
githubAgentGitEnv,
|
|
2458
2648
|
applyGithubGitAuthEnv,
|
|
2649
|
+
scrubGithubTokensFromChildEnv,
|
|
2650
|
+
mergeAgentGitAuthEnv,
|
|
2459
2651
|
resolveGithubAgentToken,
|
|
2652
|
+
resetGithubAgentTokenMemo,
|
|
2460
2653
|
resolveAgentGitAuthEnv,
|
|
2654
|
+
warmGithubAgentAuth,
|
|
2655
|
+
resolveCodexGitWritableRoots,
|
|
2656
|
+
codexSandboxWritableRootsArgs,
|
|
2461
2657
|
codexUnattendedGitConfigArgs,
|
|
2462
2658
|
formatGitAuthModeDirective,
|
|
2463
2659
|
detectGhStack,
|
|
@@ -2484,7 +2680,10 @@ export {
|
|
|
2484
2680
|
listBranches,
|
|
2485
2681
|
listPrs,
|
|
2486
2682
|
getPr,
|
|
2683
|
+
isDefaultishSourceRef,
|
|
2684
|
+
resolvePrSelectors,
|
|
2487
2685
|
resolvePrSelector,
|
|
2686
|
+
getPrForHeadBranch,
|
|
2488
2687
|
detectLocalMergeConflicts,
|
|
2489
2688
|
getPrChecks,
|
|
2490
2689
|
getPrMeta,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureGlobalCoordinatorCwd
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XUWDLRAE.js";
|
|
4
4
|
import {
|
|
5
5
|
allocateTeamName,
|
|
6
6
|
takenSlugsFromThread,
|
|
7
7
|
teamSlugFromName
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-CIRXAYWS.js";
|
|
9
9
|
import {
|
|
10
10
|
resolveNewThreadOptions,
|
|
11
11
|
resolveThreadDefaults
|