@sideboard-ai/core 0.1.74 → 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.
Files changed (37) hide show
  1. package/dist/{agents-H7M5CQY2.js → agents-EWPHOM6Y.js} +6 -6
  2. package/dist/{agents-2S2JVLZ6.js → agents-GRAPUXWW.js} +5 -5
  3. package/dist/{app-settings-3TLA2EJ7.js → app-settings-6IOQYGBK.js} +7 -1
  4. package/dist/{app-settings-P42Z3VOB.js → app-settings-NILNWNNQ.js} +7 -1
  5. package/dist/{caffeinate-hold-KLC6SABD.js → caffeinate-hold-EAZNWJBE.js} +5 -1
  6. package/dist/caffeinate-hold-OHAUWOA6.js +20 -0
  7. package/dist/{chunk-77W62MTX.js → chunk-5LXWTU3J.js} +6 -6
  8. package/dist/{chunk-GJ2LZQJI.js → chunk-5VTWBI3I.js} +2 -2
  9. package/dist/{chunk-2NKSHIRI.js → chunk-6T2SKGCS.js} +3 -3
  10. package/dist/{chunk-OE7YBB5X.js → chunk-FUUVPN4A.js} +108 -3
  11. package/dist/{chunk-HCWAIEBU.js → chunk-HCGEFU3J.js} +8 -7
  12. package/dist/{chunk-XA2FQJTN.js → chunk-HSLQXL6M.js} +6 -5
  13. package/dist/{chunk-W7YOTDVO.js → chunk-IFPN6TER.js} +47 -2
  14. package/dist/chunk-MFF2RE3I.js +168 -0
  15. package/dist/{chunk-KBKPVKYZ.js → chunk-P33ZQ7ZC.js} +3 -3
  16. package/dist/{chunk-DG3S2UXP.js → chunk-PW5YHHP3.js} +2 -2
  17. package/dist/chunk-RV6DBEDQ.js +170 -0
  18. package/dist/{chunk-5KJMNNCB.js → chunk-SHCR6RPU.js} +3 -3
  19. package/dist/{chunk-PTJJIQK7.js → chunk-XKNBSYA7.js} +47 -2
  20. package/dist/{chunk-MF2YMEGD.js → chunk-YVVXWWCC.js} +110 -3
  21. package/dist/{coordinator-prompt-3XXSG7M2.js → coordinator-prompt-2OVON2LQ.js} +4 -4
  22. package/dist/{coordinator-prompt-RTUCCPCI.js → coordinator-prompt-K2R34A5T.js} +3 -3
  23. package/dist/{global-workspace-PJU6HISJ.js → global-workspace-RI367AM6.js} +4 -4
  24. package/dist/{global-workspace-CSIS62Z4.js → global-workspace-VG44RZUH.js} +5 -5
  25. package/dist/index.cjs +1548 -614
  26. package/dist/index.d.cts +226 -28
  27. package/dist/index.d.ts +226 -28
  28. package/dist/index.js +1277 -575
  29. package/dist/mcp/run-stdio.cjs +3153 -2509
  30. package/dist/mcp/run-stdio.js +690 -262
  31. package/dist/{workspaces-L4TXMUNM.js → workspaces-BQWQEZWE.js} +5 -5
  32. package/dist/{workspaces-W72KZL4B.js → workspaces-TYPJNUSM.js} +6 -6
  33. package/dist/{worktree-VOCH3WS3.js → worktree-5VLLFI5W.js} +5 -1
  34. package/dist/{worktree-KWXHMKRN.js → worktree-UNSOCYZU.js} +5 -1
  35. package/package.json +1 -1
  36. package/dist/caffeinate-hold-BEJIYPJ7.js +0 -107
  37. package/dist/chunk-JAWEDVVA.js +0 -106
@@ -0,0 +1,168 @@
1
+ import {
2
+ writePrivateFile
3
+ } from "./chunk-JT7R45JB.js";
4
+ import {
5
+ appDataDir
6
+ } from "./chunk-M37RITA6.js";
7
+
8
+ // src/store/caffeinate-hold.ts
9
+ import { spawn } from "child_process";
10
+ import { existsSync, readFileSync, unlinkSync } from "fs";
11
+ import { join } from "path";
12
+ var hooks = {};
13
+ function setCaffeinateHoldHooks(next) {
14
+ hooks = next;
15
+ }
16
+ function caffeinateHoldPath() {
17
+ return join(appDataDir(), "caffeinate-hold.json");
18
+ }
19
+ function processAlive(pid) {
20
+ if (hooks.processAlive) return hooks.processAlive(pid);
21
+ try {
22
+ process.kill(pid, 0);
23
+ return true;
24
+ } catch {
25
+ return false;
26
+ }
27
+ }
28
+ function killPid(pid) {
29
+ if (hooks.kill) {
30
+ hooks.kill(pid);
31
+ return;
32
+ }
33
+ try {
34
+ process.kill(pid, "SIGTERM");
35
+ } catch {
36
+ }
37
+ }
38
+ function uniqueIds(ids) {
39
+ const out = [];
40
+ const seen = /* @__PURE__ */ new Set();
41
+ for (const raw of ids) {
42
+ const id = raw.trim();
43
+ if (!id || seen.has(id)) continue;
44
+ seen.add(id);
45
+ out.push(id);
46
+ }
47
+ return out;
48
+ }
49
+ function readHold() {
50
+ const path = caffeinateHoldPath();
51
+ if (!existsSync(path)) return null;
52
+ try {
53
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
54
+ if (typeof parsed?.pid === "number" && parsed.pid > 0) {
55
+ return {
56
+ pid: parsed.pid,
57
+ threadIds: uniqueIds(
58
+ Array.isArray(parsed.threadIds) ? parsed.threadIds.filter((id) => typeof id === "string") : []
59
+ )
60
+ };
61
+ }
62
+ } catch {
63
+ }
64
+ return null;
65
+ }
66
+ function writeHold(pid, threadIds) {
67
+ writePrivateFile(
68
+ caffeinateHoldPath(),
69
+ `${JSON.stringify({ pid, threadIds: uniqueIds(threadIds) })}
70
+ `
71
+ );
72
+ }
73
+ function clearHold() {
74
+ try {
75
+ unlinkSync(caffeinateHoldPath());
76
+ } catch {
77
+ }
78
+ }
79
+ function idleState(platform) {
80
+ return { held: false, pid: null, running: false, platform, threadIds: [] };
81
+ }
82
+ function isThreadCaffeinated(threadId, state) {
83
+ if (!state.held) return false;
84
+ const id = threadId.trim();
85
+ if (!id) return false;
86
+ if (state.threadIds.includes(id)) return true;
87
+ return state.threadIds.length === 0;
88
+ }
89
+ function getCaffeinateHold() {
90
+ const platform = hooks.platform ?? process.platform;
91
+ const hold = readHold();
92
+ if (!hold) return idleState(platform);
93
+ const running = processAlive(hold.pid);
94
+ if (!running) {
95
+ clearHold();
96
+ return idleState(platform);
97
+ }
98
+ return {
99
+ held: true,
100
+ pid: hold.pid,
101
+ running: true,
102
+ platform,
103
+ threadIds: hold.threadIds ?? []
104
+ };
105
+ }
106
+ function stopHold(platform, pid) {
107
+ if (pid) killPid(pid);
108
+ clearHold();
109
+ return idleState(platform);
110
+ }
111
+ function setCaffeinateHold(enabled, opts) {
112
+ const platform = hooks.platform ?? process.platform;
113
+ const current = getCaffeinateHold();
114
+ const threadId = opts?.threadId?.trim() || "";
115
+ if (!enabled) {
116
+ if (threadId && current.threadIds.length > 0) {
117
+ const remaining = current.threadIds.filter((id) => id !== threadId);
118
+ if (remaining.length > 0 && current.pid) {
119
+ writeHold(current.pid, remaining);
120
+ return { ...current, threadIds: remaining };
121
+ }
122
+ }
123
+ return stopHold(platform, current.pid);
124
+ }
125
+ const threadIds = threadId ? uniqueIds([...current.threadIds, threadId]) : current.threadIds;
126
+ if (current.running && current.pid) {
127
+ writeHold(current.pid, threadIds);
128
+ return { ...current, threadIds };
129
+ }
130
+ if (platform !== "darwin") {
131
+ return idleState(platform);
132
+ }
133
+ const spawnImpl = hooks.spawn ?? spawn;
134
+ const child = spawnImpl("caffeinate", ["-dimsu"], {
135
+ detached: true,
136
+ stdio: "ignore"
137
+ });
138
+ const pid = child.pid;
139
+ if (!pid) {
140
+ try {
141
+ child.kill();
142
+ } catch {
143
+ }
144
+ return idleState(platform);
145
+ }
146
+ child.unref();
147
+ writeHold(pid, threadIds);
148
+ return { held: true, pid, running: true, platform, threadIds };
149
+ }
150
+ function releaseCaffeinateHoldForThread(threadId) {
151
+ const id = threadId.trim();
152
+ if (!id) return getCaffeinateHold();
153
+ const current = getCaffeinateHold();
154
+ if (!current.held) return current;
155
+ if (current.threadIds.length > 0 && !current.threadIds.includes(id)) {
156
+ return current;
157
+ }
158
+ return setCaffeinateHold(false, { threadId: id });
159
+ }
160
+
161
+ export {
162
+ setCaffeinateHoldHooks,
163
+ caffeinateHoldPath,
164
+ isThreadCaffeinated,
165
+ getCaffeinateHold,
166
+ setCaffeinateHold,
167
+ releaseCaffeinateHoldForThread
168
+ };
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-VROPG6QF.js";
10
10
  import {
11
11
  isOrchestratorThread
12
- } from "./chunk-2NKSHIRI.js";
12
+ } from "./chunk-6T2SKGCS.js";
13
13
  import {
14
14
  enrichPathWithNpmGlobalBin,
15
15
  isConductorBundledCli,
@@ -22,7 +22,7 @@ import {
22
22
  loadAppSettings,
23
23
  resolveAgentExecutable,
24
24
  resolveClaudeExecutable
25
- } from "./chunk-PTJJIQK7.js";
25
+ } from "./chunk-XKNBSYA7.js";
26
26
  import {
27
27
  appDataDir
28
28
  } from "./chunk-7MV3RXSC.js";
@@ -1009,7 +1009,7 @@ var claudeAdapter = {
1009
1009
  );
1010
1010
  }
1011
1011
  const mode = permissionMode(thread);
1012
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-PJU6HISJ.js");
1012
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-RI367AM6.js");
1013
1013
  const isOrchestrator = isOrchestratorThread2(thread);
1014
1014
  const injectedServers = await buildInjectedMcpServers({
1015
1015
  includeSideboard: true,
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  isGlobalRepoPath
3
- } from "./chunk-77W62MTX.js";
3
+ } from "./chunk-5LXWTU3J.js";
4
4
  import {
5
5
  ensureGhPreferOrigin,
6
6
  resolveRepoRoot
7
- } from "./chunk-MF2YMEGD.js";
7
+ } from "./chunk-YVVXWWCC.js";
8
8
  import {
9
9
  appDataDir
10
10
  } from "./chunk-M37RITA6.js";
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ writePrivateFile
5
+ } from "./chunk-NSTQ6QKD.js";
6
+ import {
7
+ appDataDir
8
+ } from "./chunk-7MV3RXSC.js";
9
+
10
+ // src/store/caffeinate-hold.ts
11
+ import { spawn } from "child_process";
12
+ import { existsSync, readFileSync, unlinkSync } from "fs";
13
+ import { join } from "path";
14
+ var hooks = {};
15
+ function setCaffeinateHoldHooks(next) {
16
+ hooks = next;
17
+ }
18
+ function caffeinateHoldPath() {
19
+ return join(appDataDir(), "caffeinate-hold.json");
20
+ }
21
+ function processAlive(pid) {
22
+ if (hooks.processAlive) return hooks.processAlive(pid);
23
+ try {
24
+ process.kill(pid, 0);
25
+ return true;
26
+ } catch {
27
+ return false;
28
+ }
29
+ }
30
+ function killPid(pid) {
31
+ if (hooks.kill) {
32
+ hooks.kill(pid);
33
+ return;
34
+ }
35
+ try {
36
+ process.kill(pid, "SIGTERM");
37
+ } catch {
38
+ }
39
+ }
40
+ function uniqueIds(ids) {
41
+ const out = [];
42
+ const seen = /* @__PURE__ */ new Set();
43
+ for (const raw of ids) {
44
+ const id = raw.trim();
45
+ if (!id || seen.has(id)) continue;
46
+ seen.add(id);
47
+ out.push(id);
48
+ }
49
+ return out;
50
+ }
51
+ function readHold() {
52
+ const path = caffeinateHoldPath();
53
+ if (!existsSync(path)) return null;
54
+ try {
55
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
56
+ if (typeof parsed?.pid === "number" && parsed.pid > 0) {
57
+ return {
58
+ pid: parsed.pid,
59
+ threadIds: uniqueIds(
60
+ Array.isArray(parsed.threadIds) ? parsed.threadIds.filter((id) => typeof id === "string") : []
61
+ )
62
+ };
63
+ }
64
+ } catch {
65
+ }
66
+ return null;
67
+ }
68
+ function writeHold(pid, threadIds) {
69
+ writePrivateFile(
70
+ caffeinateHoldPath(),
71
+ `${JSON.stringify({ pid, threadIds: uniqueIds(threadIds) })}
72
+ `
73
+ );
74
+ }
75
+ function clearHold() {
76
+ try {
77
+ unlinkSync(caffeinateHoldPath());
78
+ } catch {
79
+ }
80
+ }
81
+ function idleState(platform) {
82
+ return { held: false, pid: null, running: false, platform, threadIds: [] };
83
+ }
84
+ function isThreadCaffeinated(threadId, state) {
85
+ if (!state.held) return false;
86
+ const id = threadId.trim();
87
+ if (!id) return false;
88
+ if (state.threadIds.includes(id)) return true;
89
+ return state.threadIds.length === 0;
90
+ }
91
+ function getCaffeinateHold() {
92
+ const platform = hooks.platform ?? process.platform;
93
+ const hold = readHold();
94
+ if (!hold) return idleState(platform);
95
+ const running = processAlive(hold.pid);
96
+ if (!running) {
97
+ clearHold();
98
+ return idleState(platform);
99
+ }
100
+ return {
101
+ held: true,
102
+ pid: hold.pid,
103
+ running: true,
104
+ platform,
105
+ threadIds: hold.threadIds ?? []
106
+ };
107
+ }
108
+ function stopHold(platform, pid) {
109
+ if (pid) killPid(pid);
110
+ clearHold();
111
+ return idleState(platform);
112
+ }
113
+ function setCaffeinateHold(enabled, opts) {
114
+ const platform = hooks.platform ?? process.platform;
115
+ const current = getCaffeinateHold();
116
+ const threadId = opts?.threadId?.trim() || "";
117
+ if (!enabled) {
118
+ if (threadId && current.threadIds.length > 0) {
119
+ const remaining = current.threadIds.filter((id) => id !== threadId);
120
+ if (remaining.length > 0 && current.pid) {
121
+ writeHold(current.pid, remaining);
122
+ return { ...current, threadIds: remaining };
123
+ }
124
+ }
125
+ return stopHold(platform, current.pid);
126
+ }
127
+ const threadIds = threadId ? uniqueIds([...current.threadIds, threadId]) : current.threadIds;
128
+ if (current.running && current.pid) {
129
+ writeHold(current.pid, threadIds);
130
+ return { ...current, threadIds };
131
+ }
132
+ if (platform !== "darwin") {
133
+ return idleState(platform);
134
+ }
135
+ const spawnImpl = hooks.spawn ?? spawn;
136
+ const child = spawnImpl("caffeinate", ["-dimsu"], {
137
+ detached: true,
138
+ stdio: "ignore"
139
+ });
140
+ const pid = child.pid;
141
+ if (!pid) {
142
+ try {
143
+ child.kill();
144
+ } catch {
145
+ }
146
+ return idleState(platform);
147
+ }
148
+ child.unref();
149
+ writeHold(pid, threadIds);
150
+ return { held: true, pid, running: true, platform, threadIds };
151
+ }
152
+ function releaseCaffeinateHoldForThread(threadId) {
153
+ const id = threadId.trim();
154
+ if (!id) return getCaffeinateHold();
155
+ const current = getCaffeinateHold();
156
+ if (!current.held) return current;
157
+ if (current.threadIds.length > 0 && !current.threadIds.includes(id)) {
158
+ return current;
159
+ }
160
+ return setCaffeinateHold(false, { threadId: id });
161
+ }
162
+
163
+ export {
164
+ setCaffeinateHoldHooks,
165
+ caffeinateHoldPath,
166
+ isThreadCaffeinated,
167
+ getCaffeinateHold,
168
+ setCaffeinateHold,
169
+ releaseCaffeinateHoldForThread
170
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isOrchestratorThread
3
- } from "./chunk-77W62MTX.js";
3
+ } from "./chunk-5LXWTU3J.js";
4
4
  import {
5
5
  applyConnectedTeamToCli,
6
6
  brightsyMcpServerName,
@@ -19,7 +19,7 @@ import {
19
19
  loadAppSettings,
20
20
  resolveAgentExecutable,
21
21
  resolveClaudeExecutable
22
- } from "./chunk-W7YOTDVO.js";
22
+ } from "./chunk-IFPN6TER.js";
23
23
  import {
24
24
  appDataDir
25
25
  } from "./chunk-M37RITA6.js";
@@ -949,7 +949,7 @@ var claudeAdapter = {
949
949
  );
950
950
  }
951
951
  const mode = permissionMode(thread);
952
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-CSIS62Z4.js");
952
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-VG44RZUH.js");
953
953
  const isOrchestrator = isOrchestratorThread2(thread);
954
954
  const injectedServers = await buildInjectedMcpServers({
955
955
  includeSideboard: true,
@@ -172,6 +172,9 @@ function normalizeVault(raw) {
172
172
  if (typeof raw.slackAppToken === "string" && raw.slackAppToken.trim()) {
173
173
  out.slackAppToken = raw.slackAppToken.trim();
174
174
  }
175
+ if (typeof raw.githubPat === "string" && raw.githubPat.trim()) {
176
+ out.githubPat = raw.githubPat.trim();
177
+ }
175
178
  if (raw.environment && typeof raw.environment === "object") {
176
179
  const environment = {};
177
180
  for (const [key, value] of Object.entries(raw.environment)) {
@@ -199,6 +202,7 @@ var DEFAULT_AGENTS = /* @__PURE__ */ new Set([
199
202
  "brightsy",
200
203
  "cursor"
201
204
  ]);
205
+ var GITHUB_GIT_AUTH_MODES = ["auto", "gh", "ssh", "token"];
202
206
  function hasLinearOAuth(integrations) {
203
207
  return Boolean(
204
208
  integrations.linearAccessToken?.trim() || integrations.linearRefreshToken?.trim()
@@ -215,12 +219,14 @@ function toPublicAppSettings(settings) {
215
219
  const integrations = { ...settings.integrations };
216
220
  const slackClientSecret = integrations.slackClientSecret;
217
221
  const slackAppToken = integrations.slackAppToken;
222
+ const githubPat = integrations.githubPat;
218
223
  delete integrations.linearApiKey;
219
224
  delete integrations.linearAccessToken;
220
225
  delete integrations.linearRefreshToken;
221
226
  delete integrations.linearClientSecret;
222
227
  delete integrations.slackClientSecret;
223
228
  delete integrations.slackAppToken;
229
+ delete integrations.githubPat;
224
230
  return {
225
231
  ...settings,
226
232
  environment,
@@ -229,7 +235,8 @@ function toPublicAppSettings(settings) {
229
235
  hasLinearApiKey: hasLinearCredentials(settings.integrations),
230
236
  hasLinearOAuth: hasLinearOAuth(settings.integrations),
231
237
  hasSlackClientSecret: Boolean(slackClientSecret?.trim()),
232
- hasSlackAppToken: Boolean(slackAppToken?.trim())
238
+ hasSlackAppToken: Boolean(slackAppToken?.trim()),
239
+ hasGithubPat: Boolean(githubPat?.trim())
233
240
  }
234
241
  };
235
242
  }
@@ -288,6 +295,7 @@ function normalizeBrightsy(raw) {
288
295
  return out;
289
296
  }
290
297
  var ISSUE_SOURCES = /* @__PURE__ */ new Set(["linear", "github"]);
298
+ var GIT_AUTH_MODES = new Set(GITHUB_GIT_AUTH_MODES);
291
299
  function normalizeIntegrations(raw) {
292
300
  if (!raw || typeof raw !== "object") return {};
293
301
  const source = raw;
@@ -352,6 +360,13 @@ function normalizeIntegrations(raw) {
352
360
  const label = source.slackDeviceLabel.trim().slice(0, 64);
353
361
  if (label) out.slackDeviceLabel = label;
354
362
  }
363
+ if (typeof source.githubGitAuthMode === "string" && GIT_AUTH_MODES.has(source.githubGitAuthMode)) {
364
+ out.githubGitAuthMode = source.githubGitAuthMode;
365
+ }
366
+ if (typeof source.githubPat === "string") {
367
+ const pat = source.githubPat.trim();
368
+ if (pat) out.githubPat = pat;
369
+ }
355
370
  return out;
356
371
  }
357
372
  function normalizeDefaults(raw) {
@@ -501,7 +516,7 @@ function readSettingsFile() {
501
516
  }
502
517
  function diskHoldsSecrets(disk) {
503
518
  return Boolean(
504
- disk.integrations.linearApiKey || disk.integrations.linearAccessToken || disk.integrations.linearRefreshToken || disk.integrations.linearClientSecret || disk.integrations.slackClientSecret || disk.integrations.slackAppToken || Object.keys(disk.environment).length > 0
519
+ 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
505
520
  );
506
521
  }
507
522
  function mergeVault(disk) {
@@ -526,6 +541,9 @@ function mergeVault(disk) {
526
541
  if (vault.slackAppToken && !integrations.slackAppToken) {
527
542
  integrations.slackAppToken = vault.slackAppToken;
528
543
  }
544
+ if (vault.githubPat && !integrations.githubPat) {
545
+ integrations.githubPat = vault.githubPat;
546
+ }
529
547
  return { ...disk, environment, integrations };
530
548
  }
531
549
  function persistSplit(settings) {
@@ -536,12 +554,14 @@ function persistSplit(settings) {
536
554
  const linearClientSecret = integrations.linearClientSecret;
537
555
  const slackClientSecret = integrations.slackClientSecret;
538
556
  const slackAppToken = integrations.slackAppToken;
557
+ const githubPat = integrations.githubPat;
539
558
  delete integrations.linearApiKey;
540
559
  delete integrations.linearAccessToken;
541
560
  delete integrations.linearRefreshToken;
542
561
  delete integrations.linearClientSecret;
543
562
  delete integrations.slackClientSecret;
544
563
  delete integrations.slackAppToken;
564
+ delete integrations.githubPat;
545
565
  writePrivateFile(
546
566
  appSettingsPath(),
547
567
  `${JSON.stringify({ ...settings, environment: {}, integrations }, null, 2)}
@@ -554,6 +574,7 @@ function persistSplit(settings) {
554
574
  linearClientSecret,
555
575
  slackClientSecret,
556
576
  slackAppToken,
577
+ githubPat,
557
578
  environment: settings.environment
558
579
  });
559
580
  }
@@ -719,6 +740,20 @@ function updateIntegrationsSettings(patch) {
719
740
  integrations.slackDeviceLabel = patch.slackDeviceLabel.trim().slice(0, 64);
720
741
  }
721
742
  }
743
+ if ("githubGitAuthMode" in patch) {
744
+ if (patch.githubGitAuthMode == null) {
745
+ delete integrations.githubGitAuthMode;
746
+ } else if (GIT_AUTH_MODES.has(patch.githubGitAuthMode)) {
747
+ integrations.githubGitAuthMode = patch.githubGitAuthMode;
748
+ }
749
+ }
750
+ if ("githubPat" in patch) {
751
+ if (patch.githubPat == null || patch.githubPat.trim() === "") {
752
+ delete integrations.githubPat;
753
+ } else {
754
+ integrations.githubPat = patch.githubPat.trim();
755
+ }
756
+ }
722
757
  return saveAppSettings({ ...current, integrations });
723
758
  }
724
759
  function updateDefaultsSettings(patch) {
@@ -826,6 +861,13 @@ function disconnectLinearConnection() {
826
861
  function getIssueSource(settings = loadAppSettings()) {
827
862
  return settings.integrations.issueSource ?? "github";
828
863
  }
864
+ function getGithubGitAuthMode(settings = loadAppSettings()) {
865
+ return settings.integrations.githubGitAuthMode ?? "auto";
866
+ }
867
+ function getGithubPat(settings = loadAppSettings()) {
868
+ const pat = settings.integrations.githubPat?.trim();
869
+ return pat || null;
870
+ }
829
871
  function resolveEffectiveIssueSource(settings = loadAppSettings()) {
830
872
  const preferred = getIssueSource(settings);
831
873
  if (preferred === "linear" && !isLinearConnected(settings)) return "github";
@@ -1039,6 +1081,7 @@ export {
1039
1081
  writeSecureJson,
1040
1082
  isSecureFileEncrypted,
1041
1083
  HARNESS_ENV_KEYS,
1084
+ GITHUB_GIT_AUTH_MODES,
1042
1085
  toPublicAppSettings,
1043
1086
  appSettingsPath,
1044
1087
  claudeUserSettingsPath,
@@ -1061,6 +1104,8 @@ export {
1061
1104
  saveLinearOAuth,
1062
1105
  disconnectLinearConnection,
1063
1106
  getIssueSource,
1107
+ getGithubGitAuthMode,
1108
+ getGithubPat,
1064
1109
  resolveEffectiveIssueSource,
1065
1110
  getLinearApiKey,
1066
1111
  brightsyCloudConnectEnabled,