@sideboard-ai/core 0.1.258 → 0.1.261

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 (66) hide show
  1. package/dist/{abletime-IDQJI2KW.js → abletime-CDGINDXG.js} +6 -5
  2. package/dist/{abletime-OGQR4LIL.js → abletime-OQ4PC52L.js} +7 -6
  3. package/dist/{abletime-oauth-ZQUIY4EM.js → abletime-oauth-5A5EOH2A.js} +5 -4
  4. package/dist/{abletime-oauth-MBAG5MYU.js → abletime-oauth-KX2TDFTE.js} +6 -5
  5. package/dist/{abletime-rest-WEJERY4O.js → abletime-rest-PUGKYTRR.js} +6 -5
  6. package/dist/{abletime-rest-JZIIT5W3.js → abletime-rest-UEHOBLXD.js} +5 -4
  7. package/dist/agents/cursor-runner.cjs +274 -12
  8. package/dist/agents/cursor-runner.js +156 -13
  9. package/dist/{agents-HZP7YEKC.js → agents-IKVUGW5H.js} +12 -9
  10. package/dist/{agents-FSUI5MET.js → agents-J2P4KNEY.js} +21 -18
  11. package/dist/{app-settings-CLARFJUX.js → app-settings-OM7H64YM.js} +12 -3
  12. package/dist/{app-settings-ONYJ36XH.js → app-settings-VQEUCONM.js} +11 -2
  13. package/dist/chunk-3HO2OY5T.js +159 -0
  14. package/dist/{chunk-F7ANS66U.js → chunk-4F7J6UWD.js} +75 -33
  15. package/dist/{chunk-WDDUIGFK.js → chunk-4GK32AYX.js} +1 -1
  16. package/dist/{chunk-ZC3TVLY6.js → chunk-5OKJDCBK.js} +5 -5
  17. package/dist/{chunk-KJM3E3NF.js → chunk-6PFZ6XO7.js} +65 -6
  18. package/dist/{title-4A2ATYNY.js → chunk-7H655NEW.js} +1 -0
  19. package/dist/{chunk-R4DWUBOL.js → chunk-ABPNIYRS.js} +78 -37
  20. package/dist/{chunk-XIEDFRBP.js → chunk-B6XFBNYM.js} +2 -2
  21. package/dist/chunk-CEMNIGQH.js +161 -0
  22. package/dist/{chunk-66LAOKLK.js → chunk-D554YCHG.js} +2 -2
  23. package/dist/{chunk-HCNCZPDL.js → chunk-FSZ7YYFQ.js} +119 -63
  24. package/dist/{chunk-4723RAO3.js → chunk-FWNL62VA.js} +3 -1
  25. package/dist/{chunk-Y7CS2WGJ.js → chunk-GIZQAOHZ.js} +247 -109
  26. package/dist/chunk-HHEKVR6C.js +72 -0
  27. package/dist/{chunk-IFHHPPSL.js → chunk-J6ONZP74.js} +5 -5
  28. package/dist/{chunk-PJK24CN3.js → chunk-JTNY5CK4.js} +10 -10
  29. package/dist/{chunk-CPEIHTG7.js → chunk-KVQX62XI.js} +3 -3
  30. package/dist/{chunk-5F4YFGHL.js → chunk-LDXSAVWO.js} +7 -7
  31. package/dist/{title-4WAKWZRF.js → chunk-LX5R5JOR.js} +1 -0
  32. package/dist/{chunk-D6JWYJ4P.js → chunk-N2WW62LF.js} +1 -0
  33. package/dist/{chunk-RTQOCFIV.js → chunk-S7VDDJ34.js} +3 -3
  34. package/dist/{chunk-RJC2MKXN.js → chunk-TJ673EZT.js} +3 -1
  35. package/dist/{chunk-63YSFXLT.js → chunk-U3AOJLH3.js} +126 -70
  36. package/dist/{chunk-452Y24PW.js → chunk-VIC6TDYT.js} +68 -9
  37. package/dist/{chunk-553IEH7O.js → chunk-W5PWGEKS.js} +241 -104
  38. package/dist/{chunk-VVHHBOIA.js → chunk-WV7KJH2E.js} +5 -3
  39. package/dist/{chunk-BYRZS2S2.js → chunk-X2OTZ36G.js} +4 -4
  40. package/dist/{chunk-FGWUZOZN.js → chunk-YFTO7U2A.js} +3 -3
  41. package/dist/connected-teams-7CENZDWU.js +1 -1
  42. package/dist/{connected-teams-Z5GOIC5I.js → connected-teams-RU6VATCM.js} +2 -2
  43. package/dist/{coordinator-prompt-HZUWK3NP.js → coordinator-prompt-TU6656OK.js} +9 -8
  44. package/dist/{coordinator-prompt-Y6S6USNS.js → coordinator-prompt-VQHQ3RIX.js} +8 -7
  45. package/dist/{global-workspace-4JCITHB6.js → global-workspace-47NZVA44.js} +8 -7
  46. package/dist/{global-workspace-YA7U4M2N.js → global-workspace-PHF2MOGW.js} +9 -8
  47. package/dist/index.cjs +1443 -856
  48. package/dist/index.d.cts +118 -37
  49. package/dist/index.d.ts +118 -37
  50. package/dist/index.js +148 -64
  51. package/dist/managed-accounts-2AK5RIAF.js +39 -0
  52. package/dist/managed-accounts-4BLTJKAN.js +41 -0
  53. package/dist/mcp/run-stdio.cjs +2722 -2248
  54. package/dist/mcp/run-stdio.js +136 -50
  55. package/dist/{orchestrator-LWADJQTN.js → orchestrator-OCG4QVA5.js} +13 -11
  56. package/dist/{orchestrator-VHJZEVGA.js → orchestrator-VLTO5JBR.js} +13 -11
  57. package/dist/{plan-file-CKXUFTQ2.js → plan-file-VAHV5WBB.js} +2 -2
  58. package/dist/{thread-store-HDQ4CH54.js → thread-store-FJ5CDX2M.js} +1 -1
  59. package/dist/{thread-store-ZDR3Z5UG.js → thread-store-SHCUBWB3.js} +1 -1
  60. package/dist/title-ERD6D3C3.js +8 -0
  61. package/dist/title-Z7WAJN57.js +6 -0
  62. package/dist/{workspaces-IXZD7EC4.js → workspaces-2XTDS7N2.js} +9 -8
  63. package/dist/{workspaces-4KHEUPEX.js → workspaces-I7TWFTJM.js} +8 -7
  64. package/dist/{worktree-DAAF64UU.js → worktree-DDDF3WHV.js} +8 -7
  65. package/dist/{worktree-S3FOMEQ2.js → worktree-YASFE65H.js} +7 -6
  66. package/package.json +1 -1
@@ -1,9 +1,13 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ clipAgentEventForEmit
4
+ } from "../chunk-HHEKVR6C.js";
2
5
  import {
3
6
  createAgentStreamCoalescer
4
7
  } from "../chunk-AXQ4ZWHK.js";
5
8
  import {
6
9
  CURSOR_SDK_INSTALL_HINT,
10
+ TOOL_RESULT_STORE_MAX_CHARS,
7
11
  cursorCostOnlyUsageEvent,
8
12
  cursorDeltaToEvents,
9
13
  cursorSdkHasExpectedExports,
@@ -15,15 +19,16 @@ import {
15
19
  importCursorSdk,
16
20
  looksLikeCursorHttp2StreamClose,
17
21
  resolveCursorSdkRoot
18
- } from "../chunk-VVHHBOIA.js";
19
- import {
20
- cursorSdkStoreDir
21
- } from "../chunk-UWQ6UCIB.js";
22
- import "../chunk-EHT2DRT4.js";
22
+ } from "../chunk-WV7KJH2E.js";
23
+ import "../chunk-6K64FJDD.js";
23
24
  import "../chunk-QVN2WOKJ.js";
24
25
  import {
25
26
  dropNestedElectronEnvFromProcess
26
27
  } from "../chunk-4TR3HZFT.js";
28
+ import {
29
+ cursorSdkStoreDir
30
+ } from "../chunk-UWQ6UCIB.js";
31
+ import "../chunk-EHT2DRT4.js";
27
32
 
28
33
  // src/agents/cursor-runner.ts
29
34
  import { mkdirSync } from "fs";
@@ -81,7 +86,7 @@ async function retryOnceOnRetryableCursorError(fn, onRetry, delayMs = CURSOR_RET
81
86
  if (!isRetryableCursorTransportError(err)) throw err;
82
87
  onRetry?.(err);
83
88
  if (delayMs > 0) {
84
- await new Promise((resolve) => setTimeout(resolve, delayMs));
89
+ await new Promise((resolve2) => setTimeout(resolve2, delayMs));
85
90
  }
86
91
  return fn();
87
92
  }
@@ -109,8 +114,8 @@ async function* iterateUntilIdle(iterable, idleMs, onIdle, activity) {
109
114
  let idleTimer;
110
115
  const raced = await Promise.race([
111
116
  pending.then((result) => ({ kind: "item", result })),
112
- new Promise((resolve) => {
113
- idleTimer = setTimeout(() => resolve({ kind: "idle" }), waitMs);
117
+ new Promise((resolve2) => {
118
+ idleTimer = setTimeout(() => resolve2({ kind: "idle" }), waitMs);
114
119
  idleTimer.unref?.();
115
120
  })
116
121
  ]);
@@ -134,6 +139,138 @@ async function* iterateUntilIdle(iterable, idleMs, onIdle, activity) {
134
139
  }
135
140
  }
136
141
 
142
+ // src/agents/sliced-file-read.ts
143
+ import { readFileSync, realpathSync, statSync } from "fs";
144
+ import { isAbsolute, relative, resolve, sep } from "path";
145
+ var SLICED_READ_DEFAULT_LIMIT = 200;
146
+ var SLICED_READ_MAX_LINE_CHARS = 2e3;
147
+ var SLICED_READ_DESCRIPTION = "Read a text file. Defaults to 200 lines (and a small char budget). Pass offset (1-based) + limit to continue \u2014 never request the whole file when it is large.";
148
+ var SLICED_READ_INPUT_SCHEMA = {
149
+ type: "object",
150
+ properties: {
151
+ path: {
152
+ type: "string",
153
+ description: "Absolute or cwd-relative path inside the worktree."
154
+ },
155
+ offset: {
156
+ type: "number",
157
+ description: "1-based start line (default 1)."
158
+ },
159
+ limit: {
160
+ type: "number",
161
+ description: `Max lines to return (default ${SLICED_READ_DEFAULT_LIMIT}).`
162
+ }
163
+ },
164
+ required: ["path"]
165
+ };
166
+ function realpathOrSelf(path) {
167
+ try {
168
+ return realpathSync(path);
169
+ } catch {
170
+ return resolve(path);
171
+ }
172
+ }
173
+ function isOutsideWorktree(root, abs) {
174
+ const rel = relative(root, abs);
175
+ return rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel);
176
+ }
177
+ function resolveWithinCwd(cwd, input) {
178
+ const root = realpathOrSelf(cwd);
179
+ const abs = isAbsolute(input) ? resolve(input) : resolve(root, input);
180
+ if (isOutsideWorktree(root, abs)) {
181
+ throw new Error(`Path is outside the worktree: ${input}`);
182
+ }
183
+ const real = realpathOrSelf(abs);
184
+ if (isOutsideWorktree(root, real)) {
185
+ throw new Error(`Path is outside the worktree: ${input}`);
186
+ }
187
+ return real;
188
+ }
189
+ function capLine(line) {
190
+ if (line.length <= SLICED_READ_MAX_LINE_CHARS) return line;
191
+ return `${line.slice(0, SLICED_READ_MAX_LINE_CHARS)}\u2026(${line.length - SLICED_READ_MAX_LINE_CHARS} more chars on this line)`;
192
+ }
193
+ function looksBinary(buf) {
194
+ const n = Math.min(buf.length, 8192);
195
+ for (let i = 0; i < n; i += 1) {
196
+ if (buf[i] === 0) return true;
197
+ }
198
+ return false;
199
+ }
200
+ function asPositiveInt(value, fallback) {
201
+ const n = typeof value === "number" ? value : Number(value);
202
+ if (!Number.isFinite(n)) return fallback;
203
+ return Math.max(1, Math.floor(n));
204
+ }
205
+ function executeSlicedFileRead(cwd, args) {
206
+ const rawPath = typeof args.path === "string" ? args.path.trim() : "";
207
+ if (!rawPath) return "Error: path is required.";
208
+ let abs;
209
+ try {
210
+ abs = resolveWithinCwd(cwd, rawPath);
211
+ } catch (err) {
212
+ return `Error: ${err instanceof Error ? err.message : String(err)}`;
213
+ }
214
+ let buf;
215
+ try {
216
+ const st = statSync(abs);
217
+ if (!st.isFile()) return `Error: not a file: ${rawPath}`;
218
+ buf = readFileSync(abs);
219
+ } catch (err) {
220
+ return `Error: ${err instanceof Error ? err.message : String(err)}`;
221
+ }
222
+ if (looksBinary(buf)) {
223
+ return `Error: ${rawPath} looks binary (${buf.length} bytes). Do not dump it into the turn.`;
224
+ }
225
+ const text = buf.toString("utf8");
226
+ const lines = text.split("\n");
227
+ if (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
228
+ const totalLines = lines.length;
229
+ const offset = asPositiveInt(args.offset, 1);
230
+ const limit = asPositiveInt(args.limit, SLICED_READ_DEFAULT_LIMIT);
231
+ const start = Math.min(offset, totalLines + 1);
232
+ const end = Math.min(start + limit - 1, totalLines);
233
+ const numbered = [];
234
+ let used = 0;
235
+ let stoppedEarly = false;
236
+ for (let i = start; i <= end; i += 1) {
237
+ const row = `${String(i).padStart(6, " ")}|${capLine(lines[i - 1] ?? "")}`;
238
+ if (used + row.length + 1 > TOOL_RESULT_STORE_MAX_CHARS && numbered.length > 0) {
239
+ stoppedEarly = true;
240
+ break;
241
+ }
242
+ numbered.push(row);
243
+ used += row.length + 1;
244
+ }
245
+ const header = `${rawPath} (${totalLines} lines, ${buf.length} bytes)`;
246
+ if (totalLines === 0) return `${header}
247
+ (empty file)`;
248
+ if (start > totalLines) {
249
+ return `${header}
250
+ offset ${offset} is past EOF. Last line is ${totalLines}.`;
251
+ }
252
+ const shownEnd = start + numbered.length - 1;
253
+ const truncated = stoppedEarly || shownEnd < totalLines;
254
+ const body = numbered.join("\n");
255
+ if (!truncated && start === 1) return `${header}
256
+ ${body}`;
257
+ const next = shownEnd + 1;
258
+ const hint = truncated ? `
259
+
260
+ \u2026truncated; ${totalLines - shownEnd} lines remain. Re-call with offset=${next} (and limit) \u2014 do not read the whole file.` : start > 1 ? `
261
+
262
+ (lines ${start}\u2013${shownEnd} of ${totalLines})` : "";
263
+ return `${header}
264
+ ${body}${hint}`;
265
+ }
266
+ function slicedReadCustomToolConfig(cwd) {
267
+ return {
268
+ description: SLICED_READ_DESCRIPTION,
269
+ inputSchema: SLICED_READ_INPUT_SCHEMA,
270
+ execute: (args) => executeSlicedFileRead(cwd, args)
271
+ };
272
+ }
273
+
137
274
  // src/agents/cursor-model-selection.ts
138
275
  function buildCursorModelSelection(model, opts) {
139
276
  const raw = model && model.trim() || "";
@@ -151,7 +288,7 @@ function buildCursorModelSelection(model, opts) {
151
288
  // src/agents/cursor-runner.ts
152
289
  dropNestedElectronEnvFromProcess();
153
290
  function emit(event) {
154
- process.stdout.write(`${JSON.stringify(event)}
291
+ process.stdout.write(`${JSON.stringify(clipAgentEventForEmit(event, process.cwd()))}
155
292
  `);
156
293
  }
157
294
  function localAgentStore(Store, threadId) {
@@ -227,9 +364,13 @@ async function main() {
227
364
  const mode = req.planMode ? "plan" : "agent";
228
365
  const store = localAgentStore(JsonlLocalAgentStore, req.threadId);
229
366
  const isolateSources = [];
367
+ const customTools = {
368
+ read: slicedReadCustomToolConfig(req.cwd)
369
+ };
230
370
  const local = withCursorLocalHangGuards({
231
371
  cwd: req.cwd,
232
372
  store,
373
+ customTools,
233
374
  ...req.isolateAmbientMcp ? { settingSources: isolateSources } : {}
234
375
  });
235
376
  const mcpServers = req.mcpServers && Object.keys(req.mcpServers).length > 0 ? req.mcpServers : void 0;
@@ -239,6 +380,7 @@ async function main() {
239
380
  mode,
240
381
  local,
241
382
  name: "Sideboard",
383
+ disallowedTools: ["read"],
242
384
  ...mcpServers ? { mcpServers } : {}
243
385
  };
244
386
  const retryTransport = (fn) => retryOnceOnRetryableCursorError(fn, (err) => {
@@ -255,6 +397,7 @@ async function main() {
255
397
  model,
256
398
  mode,
257
399
  local,
400
+ disallowedTools: ["read"],
258
401
  ...mcpServers ? { mcpServers } : {}
259
402
  })
260
403
  ) : await createAgent();
@@ -303,8 +446,8 @@ async function main() {
303
446
  shuttingDown = true;
304
447
  void Promise.race([
305
448
  cancelLiveRun(),
306
- new Promise((resolve) => {
307
- setTimeout(resolve, 2e3);
449
+ new Promise((resolve2) => {
450
+ setTimeout(resolve2, 2e3);
308
451
  })
309
452
  ]).finally(() => process.exit(1));
310
453
  };
@@ -359,8 +502,8 @@ async function main() {
359
502
  stream.flush();
360
503
  const result = streamIdle ? await Promise.race([
361
504
  run.wait(),
362
- new Promise((resolve) => {
363
- setTimeout(() => resolve({ status: "cancelled" }), 5e3);
505
+ new Promise((resolve2) => {
506
+ setTimeout(() => resolve2({ status: "cancelled" }), 5e3);
364
507
  })
365
508
  ]) : await run.wait();
366
509
  if (result.status === "error") {
@@ -39,6 +39,7 @@ import {
39
39
  listModelsForAgent,
40
40
  listOpencodeModels,
41
41
  loginAgent,
42
+ loginManagedAccount,
42
43
  mcpStatusThinkingFromClaudeInit,
43
44
  openInSystemTerminal,
44
45
  opencodeAdapter,
@@ -55,15 +56,13 @@ import {
55
56
  resolveQuotaFallbackAgent,
56
57
  turnCostUsdFromCursorUsage,
57
58
  whichOnPath
58
- } from "./chunk-F7ANS66U.js";
59
- import "./chunk-PJK24CN3.js";
59
+ } from "./chunk-4F7J6UWD.js";
60
+ import "./chunk-JTNY5CK4.js";
61
+ import "./chunk-FSZ7YYFQ.js";
62
+ import "./chunk-N2WW62LF.js";
60
63
  import "./chunk-XAISOBBG.js";
61
64
  import "./chunk-P2BSMNHB.js";
62
65
  import "./chunk-VKQGAWHY.js";
63
- import "./chunk-HCNCZPDL.js";
64
- import "./chunk-D6JWYJ4P.js";
65
- import "./chunk-RJC2MKXN.js";
66
- import "./chunk-H547WSSZ.js";
67
66
  import "./chunk-DD67JWTN.js";
68
67
  import {
69
68
  conductorBundledBinDir,
@@ -81,12 +80,15 @@ import {
81
80
  assertOrchestratorCapableAgent,
82
81
  coerceOrchestratorAgent,
83
82
  isOrchestratorCapableAgent
84
- } from "./chunk-452Y24PW.js";
83
+ } from "./chunk-VIC6TDYT.js";
85
84
  import "./chunk-NSTQ6QKD.js";
86
- import "./chunk-KGZBYWZ3.js";
87
- import "./chunk-Z2LGMV6C.js";
88
85
  import "./chunk-WWUABK6B.js";
89
86
  import "./chunk-FJZWM2ON.js";
87
+ import "./chunk-CEMNIGQH.js";
88
+ import "./chunk-TJ673EZT.js";
89
+ import "./chunk-H547WSSZ.js";
90
+ import "./chunk-KGZBYWZ3.js";
91
+ import "./chunk-Z2LGMV6C.js";
90
92
  export {
91
93
  CLAUDE_MODEL_CATALOG,
92
94
  CURSOR_SDK_INSTALL_HINT,
@@ -134,6 +136,7 @@ export {
134
136
  listModelsForAgent,
135
137
  listOpencodeModels,
136
138
  loginAgent,
139
+ loginManagedAccount,
137
140
  mcpStatusThinkingFromClaudeInit,
138
141
  npmGlobalNodeModules,
139
142
  npmGlobalPrefix,
@@ -34,6 +34,7 @@ import {
34
34
  listModelsForAgent,
35
35
  listOpencodeModels,
36
36
  loginAgent,
37
+ loginManagedAccount,
37
38
  mcpStatusThinkingFromClaudeInit,
38
39
  openInSystemTerminal,
39
40
  opencodeAdapter,
@@ -46,12 +47,11 @@ import {
46
47
  resolveLoginCommand,
47
48
  resolveQuotaFallbackAgent,
48
49
  whichOnPath
49
- } from "./chunk-R4DWUBOL.js";
50
- import "./chunk-BYRZS2S2.js";
51
- import "./chunk-63YSFXLT.js";
52
- import "./chunk-6K64FJDD.js";
50
+ } from "./chunk-ABPNIYRS.js";
51
+ import "./chunk-X2OTZ36G.js";
52
+ import "./chunk-U3AOJLH3.js";
53
53
  import "./chunk-2P4XKWV2.js";
54
- import "./chunk-5F4YFGHL.js";
54
+ import "./chunk-LDXSAVWO.js";
55
55
  import "./chunk-ROPGQRPU.js";
56
56
  import "./chunk-N7WZ6NIN.js";
57
57
  import {
@@ -62,19 +62,8 @@ import {
62
62
  preferredCursorCostCents,
63
63
  resolveCursorSdkRoot,
64
64
  turnCostUsdFromCursorUsage
65
- } from "./chunk-VVHHBOIA.js";
66
- import {
67
- ORCHESTRATOR_AGENT_KINDS,
68
- assertOrchestratorCapableAgent,
69
- coerceOrchestratorAgent,
70
- isOrchestratorCapableAgent
71
- } from "./chunk-KJM3E3NF.js";
72
- import "./chunk-WDRMZKVB.js";
73
- import "./chunk-JT7R45JB.js";
74
- import "./chunk-4723RAO3.js";
75
- import "./chunk-UWQ6UCIB.js";
76
- import "./chunk-77WWLBCI.js";
77
- import "./chunk-EHT2DRT4.js";
65
+ } from "./chunk-WV7KJH2E.js";
66
+ import "./chunk-6K64FJDD.js";
78
67
  import {
79
68
  conductorBundledBinDir,
80
69
  enrichPathWithNpmGlobalBin,
@@ -86,7 +75,20 @@ import {
86
75
  resolveCommandBinarySync,
87
76
  withExportedPath
88
77
  } from "./chunk-QVN2WOKJ.js";
78
+ import {
79
+ ORCHESTRATOR_AGENT_KINDS,
80
+ assertOrchestratorCapableAgent,
81
+ coerceOrchestratorAgent,
82
+ isOrchestratorCapableAgent
83
+ } from "./chunk-6PFZ6XO7.js";
89
84
  import "./chunk-4TR3HZFT.js";
85
+ import "./chunk-WDRMZKVB.js";
86
+ import "./chunk-3HO2OY5T.js";
87
+ import "./chunk-JT7R45JB.js";
88
+ import "./chunk-FWNL62VA.js";
89
+ import "./chunk-UWQ6UCIB.js";
90
+ import "./chunk-77WWLBCI.js";
91
+ import "./chunk-EHT2DRT4.js";
90
92
  export {
91
93
  CLAUDE_MODEL_CATALOG,
92
94
  CURSOR_SDK_INSTALL_HINT,
@@ -134,6 +136,7 @@ export {
134
136
  listModelsForAgent,
135
137
  listOpencodeModels,
136
138
  loginAgent,
139
+ loginManagedAccount,
137
140
  mcpStatusThinkingFromClaudeInit,
138
141
  npmGlobalNodeModules,
139
142
  npmGlobalPrefix,
@@ -11,6 +11,7 @@ import {
11
11
  PROFILE_NOTES_MAX,
12
12
  REVIEW_LABEL_MAX,
13
13
  USAGE_ON_LIMIT_VALUES,
14
+ addManagedAccount,
14
15
  agentDoneSound,
15
16
  appSettingsPath,
16
17
  applyAppEnvironment,
@@ -72,6 +73,8 @@ import {
72
73
  orchestrationQuotaFallbackAgent,
73
74
  orchestrationQuotaOnLimit,
74
75
  readViewerContext,
76
+ removeManagedAccount,
77
+ renameManagedAccount,
75
78
  resolveAccountProfile,
76
79
  resolveAccountProfileFromSettings,
77
80
  resolveAgentExecutable,
@@ -88,6 +91,7 @@ import {
88
91
  saveAbleTimeConnection,
89
92
  saveAppSettings,
90
93
  saveLinearOAuth,
94
+ selectManagedAccount,
91
95
  showCostEnabled,
92
96
  slackAppLevelToken,
93
97
  slackListenEnabled,
@@ -104,12 +108,13 @@ import {
104
108
  updateProjectProfileSettings,
105
109
  usageOnLimit,
106
110
  writeViewerContext
107
- } from "./chunk-452Y24PW.js";
111
+ } from "./chunk-VIC6TDYT.js";
108
112
  import "./chunk-NSTQ6QKD.js";
109
- import "./chunk-KGZBYWZ3.js";
110
- import "./chunk-Z2LGMV6C.js";
111
113
  import "./chunk-WWUABK6B.js";
112
114
  import "./chunk-FJZWM2ON.js";
115
+ import "./chunk-CEMNIGQH.js";
116
+ import "./chunk-KGZBYWZ3.js";
117
+ import "./chunk-Z2LGMV6C.js";
113
118
  export {
114
119
  AGENT_DONE_SOUNDS,
115
120
  CHAT_TEXT_SCALES,
@@ -121,6 +126,7 @@ export {
121
126
  PROFILE_NOTES_MAX,
122
127
  REVIEW_LABEL_MAX,
123
128
  USAGE_ON_LIMIT_VALUES,
129
+ addManagedAccount,
124
130
  agentDoneSound,
125
131
  appSettingsPath,
126
132
  applyAppEnvironment,
@@ -182,6 +188,8 @@ export {
182
188
  orchestrationQuotaFallbackAgent,
183
189
  orchestrationQuotaOnLimit,
184
190
  readViewerContext,
191
+ removeManagedAccount,
192
+ renameManagedAccount,
185
193
  resolveAccountProfile,
186
194
  resolveAccountProfileFromSettings,
187
195
  resolveAgentExecutable,
@@ -198,6 +206,7 @@ export {
198
206
  saveAbleTimeConnection,
199
207
  saveAppSettings,
200
208
  saveLinearOAuth,
209
+ selectManagedAccount,
201
210
  showCostEnabled,
202
211
  slackAppLevelToken,
203
212
  slackListenEnabled,
@@ -9,6 +9,7 @@ import {
9
9
  PROFILE_NOTES_MAX,
10
10
  REVIEW_LABEL_MAX,
11
11
  USAGE_ON_LIMIT_VALUES,
12
+ addManagedAccount,
12
13
  agentDoneSound,
13
14
  appSettingsPath,
14
15
  applyAppEnvironment,
@@ -70,6 +71,8 @@ import {
70
71
  orchestrationQuotaFallbackAgent,
71
72
  orchestrationQuotaOnLimit,
72
73
  readViewerContext,
74
+ removeManagedAccount,
75
+ renameManagedAccount,
73
76
  resolveAccountProfile,
74
77
  resolveAccountProfileFromSettings,
75
78
  resolveAgentExecutable,
@@ -86,6 +89,7 @@ import {
86
89
  saveAbleTimeConnection,
87
90
  saveAppSettings,
88
91
  saveLinearOAuth,
92
+ selectManagedAccount,
89
93
  showCostEnabled,
90
94
  slackAppLevelToken,
91
95
  slackListenEnabled,
@@ -102,12 +106,13 @@ import {
102
106
  updateProjectProfileSettings,
103
107
  usageOnLimit,
104
108
  writeViewerContext
105
- } from "./chunk-KJM3E3NF.js";
109
+ } from "./chunk-6PFZ6XO7.js";
110
+ import "./chunk-4TR3HZFT.js";
106
111
  import "./chunk-WDRMZKVB.js";
112
+ import "./chunk-3HO2OY5T.js";
107
113
  import "./chunk-JT7R45JB.js";
108
114
  import "./chunk-77WWLBCI.js";
109
115
  import "./chunk-EHT2DRT4.js";
110
- import "./chunk-4TR3HZFT.js";
111
116
  export {
112
117
  AGENT_DONE_SOUNDS,
113
118
  CHAT_TEXT_SCALES,
@@ -119,6 +124,7 @@ export {
119
124
  PROFILE_NOTES_MAX,
120
125
  REVIEW_LABEL_MAX,
121
126
  USAGE_ON_LIMIT_VALUES,
127
+ addManagedAccount,
122
128
  agentDoneSound,
123
129
  appSettingsPath,
124
130
  applyAppEnvironment,
@@ -180,6 +186,8 @@ export {
180
186
  orchestrationQuotaFallbackAgent,
181
187
  orchestrationQuotaOnLimit,
182
188
  readViewerContext,
189
+ removeManagedAccount,
190
+ renameManagedAccount,
183
191
  resolveAccountProfile,
184
192
  resolveAccountProfileFromSettings,
185
193
  resolveAgentExecutable,
@@ -196,6 +204,7 @@ export {
196
204
  saveAbleTimeConnection,
197
205
  saveAppSettings,
198
206
  saveLinearOAuth,
207
+ selectManagedAccount,
199
208
  showCostEnabled,
200
209
  slackAppLevelToken,
201
210
  slackListenEnabled,
@@ -0,0 +1,159 @@
1
+ import {
2
+ appDataDir
3
+ } from "./chunk-EHT2DRT4.js";
4
+
5
+ // src/store/managed-accounts.ts
6
+ import { existsSync, mkdirSync, copyFileSync } from "fs";
7
+ import { homedir } from "os";
8
+ import { join } from "path";
9
+ var EMPTY_MANAGED_ACCOUNTS = {
10
+ accounts: [],
11
+ activeClaudeAccountId: null,
12
+ activeCodexAccountId: null
13
+ };
14
+ function isManagedAccountKind(value) {
15
+ return value === "claude" || value === "codex";
16
+ }
17
+ function systemConfigDir(kind) {
18
+ return kind === "claude" ? join(homedir(), ".claude") : join(homedir(), ".codex");
19
+ }
20
+ function managedAccountConfigDir(kind, id) {
21
+ return join(appDataDir(), "accounts", kind, id);
22
+ }
23
+ function activeAccountId(kind, state) {
24
+ return kind === "claude" ? state.activeClaudeAccountId : state.activeCodexAccountId;
25
+ }
26
+ function findManagedAccount(state, id, kind) {
27
+ if (!id) return null;
28
+ return state.accounts.find((a) => a.id === id && (kind == null || a.kind === kind)) ?? null;
29
+ }
30
+ function resolveAccountForThread(thread, state) {
31
+ if (thread.agent !== "claude" && thread.agent !== "codex") return null;
32
+ const kind = thread.agent;
33
+ if (thread.accountId !== void 0) {
34
+ return findManagedAccount(state, thread.accountId, kind);
35
+ }
36
+ return findManagedAccount(state, activeAccountId(kind, state), kind);
37
+ }
38
+ function accountIdToPin(thread, state) {
39
+ if (thread.agent !== "claude" && thread.agent !== "codex") return void 0;
40
+ if (thread.accountId !== void 0) return thread.accountId;
41
+ return activeAccountId(thread.agent, state);
42
+ }
43
+ function applyManagedAccountEnv(env, agent, account) {
44
+ if (!account) return;
45
+ if (agent === "claude" && account.kind === "claude") {
46
+ env.CLAUDE_CONFIG_DIR = account.configDir;
47
+ }
48
+ if (agent === "codex" && account.kind === "codex") {
49
+ env.CODEX_HOME = account.configDir;
50
+ }
51
+ }
52
+ function nextManagedAccount(kind, currentId, state) {
53
+ const list = state.accounts.filter((a) => a.kind === kind);
54
+ if (list.length === 0) return null;
55
+ const slots = [
56
+ { accountId: null, label: "System default" },
57
+ ...list.map((a) => ({ accountId: a.id, label: a.label }))
58
+ ];
59
+ const idx = slots.findIndex((s) => s.accountId === (currentId ?? null));
60
+ const from = idx < 0 ? 0 : idx;
61
+ const next = slots[(from + 1) % slots.length];
62
+ if (!next || next.accountId === (currentId ?? null)) return null;
63
+ return next;
64
+ }
65
+ function ensureManagedAccountDir(kind, id) {
66
+ const dir = managedAccountConfigDir(kind, id);
67
+ mkdirSync(dir, { recursive: true });
68
+ mirrorHostConfig(kind, dir);
69
+ return dir;
70
+ }
71
+ function mirrorHostConfig(kind, destDir) {
72
+ const src = systemConfigDir(kind);
73
+ const files = kind === "claude" ? ["settings.json"] : ["config.toml"];
74
+ for (const name of files) {
75
+ const from = join(src, name);
76
+ const to = join(destDir, name);
77
+ if (!existsSync(from) || existsSync(to)) continue;
78
+ try {
79
+ copyFileSync(from, to);
80
+ } catch {
81
+ }
82
+ }
83
+ }
84
+ function normalizeManagedAccounts(raw) {
85
+ if (!raw || typeof raw !== "object") return { ...EMPTY_MANAGED_ACCOUNTS };
86
+ const source = raw;
87
+ const accounts = [];
88
+ if (Array.isArray(source.accounts)) {
89
+ for (const item of source.accounts) {
90
+ if (!item || typeof item !== "object") continue;
91
+ const rec = item;
92
+ if (typeof rec.id !== "string" || !rec.id.trim()) continue;
93
+ if (!isManagedAccountKind(rec.kind)) continue;
94
+ if (typeof rec.label !== "string" || !rec.label.trim()) continue;
95
+ if (typeof rec.configDir !== "string" || !rec.configDir.trim()) continue;
96
+ accounts.push({
97
+ id: rec.id.trim(),
98
+ kind: rec.kind,
99
+ label: rec.label.trim().slice(0, 80),
100
+ configDir: rec.configDir.trim(),
101
+ createdAt: typeof rec.createdAt === "string" && rec.createdAt.trim() ? rec.createdAt.trim() : (/* @__PURE__ */ new Date()).toISOString()
102
+ });
103
+ }
104
+ }
105
+ const claudeId = typeof source.activeClaudeAccountId === "string" && source.activeClaudeAccountId.trim() ? source.activeClaudeAccountId.trim() : null;
106
+ const codexId = typeof source.activeCodexAccountId === "string" && source.activeCodexAccountId.trim() ? source.activeCodexAccountId.trim() : null;
107
+ return {
108
+ accounts,
109
+ activeClaudeAccountId: accounts.some((a) => a.id === claudeId && a.kind === "claude") ? claudeId : null,
110
+ activeCodexAccountId: accounts.some((a) => a.id === codexId && a.kind === "codex") ? codexId : null
111
+ };
112
+ }
113
+ function withAddedAccount(state, account) {
114
+ const accounts = [...state.accounts.filter((a) => a.id !== account.id), account];
115
+ if (account.kind === "claude") {
116
+ return { ...state, accounts, activeClaudeAccountId: account.id };
117
+ }
118
+ return { ...state, accounts, activeCodexAccountId: account.id };
119
+ }
120
+ function withSelectedAccount(state, kind, accountId) {
121
+ if (accountId && !findManagedAccount(state, accountId, kind)) {
122
+ accountId = null;
123
+ }
124
+ if (kind === "claude") return { ...state, activeClaudeAccountId: accountId };
125
+ return { ...state, activeCodexAccountId: accountId };
126
+ }
127
+ function withRemovedAccount(state, id) {
128
+ const accounts = state.accounts.filter((a) => a.id !== id);
129
+ return {
130
+ accounts,
131
+ activeClaudeAccountId: state.activeClaudeAccountId === id ? null : state.activeClaudeAccountId,
132
+ activeCodexAccountId: state.activeCodexAccountId === id ? null : state.activeCodexAccountId
133
+ };
134
+ }
135
+ function loginEnvPrefix(account) {
136
+ const key = account.kind === "claude" ? "CLAUDE_CONFIG_DIR" : "CODEX_HOME";
137
+ const escaped = account.configDir.replace(/'/g, `'\\''`);
138
+ return `export ${key}='${escaped}'`;
139
+ }
140
+
141
+ export {
142
+ EMPTY_MANAGED_ACCOUNTS,
143
+ isManagedAccountKind,
144
+ systemConfigDir,
145
+ managedAccountConfigDir,
146
+ activeAccountId,
147
+ findManagedAccount,
148
+ resolveAccountForThread,
149
+ accountIdToPin,
150
+ applyManagedAccountEnv,
151
+ nextManagedAccount,
152
+ ensureManagedAccountDir,
153
+ mirrorHostConfig,
154
+ normalizeManagedAccounts,
155
+ withAddedAccount,
156
+ withSelectedAccount,
157
+ withRemovedAccount,
158
+ loginEnvPrefix
159
+ };