@sideboard-ai/core 0.1.257 → 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
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ appDataDir
5
+ } from "./chunk-Z2LGMV6C.js";
6
+
7
+ // src/store/managed-accounts.ts
8
+ import { existsSync, mkdirSync, copyFileSync } from "fs";
9
+ import { homedir } from "os";
10
+ import { join } from "path";
11
+ var EMPTY_MANAGED_ACCOUNTS = {
12
+ accounts: [],
13
+ activeClaudeAccountId: null,
14
+ activeCodexAccountId: null
15
+ };
16
+ function isManagedAccountKind(value) {
17
+ return value === "claude" || value === "codex";
18
+ }
19
+ function systemConfigDir(kind) {
20
+ return kind === "claude" ? join(homedir(), ".claude") : join(homedir(), ".codex");
21
+ }
22
+ function managedAccountConfigDir(kind, id) {
23
+ return join(appDataDir(), "accounts", kind, id);
24
+ }
25
+ function activeAccountId(kind, state) {
26
+ return kind === "claude" ? state.activeClaudeAccountId : state.activeCodexAccountId;
27
+ }
28
+ function findManagedAccount(state, id, kind) {
29
+ if (!id) return null;
30
+ return state.accounts.find((a) => a.id === id && (kind == null || a.kind === kind)) ?? null;
31
+ }
32
+ function resolveAccountForThread(thread, state) {
33
+ if (thread.agent !== "claude" && thread.agent !== "codex") return null;
34
+ const kind = thread.agent;
35
+ if (thread.accountId !== void 0) {
36
+ return findManagedAccount(state, thread.accountId, kind);
37
+ }
38
+ return findManagedAccount(state, activeAccountId(kind, state), kind);
39
+ }
40
+ function accountIdToPin(thread, state) {
41
+ if (thread.agent !== "claude" && thread.agent !== "codex") return void 0;
42
+ if (thread.accountId !== void 0) return thread.accountId;
43
+ return activeAccountId(thread.agent, state);
44
+ }
45
+ function applyManagedAccountEnv(env, agent, account) {
46
+ if (!account) return;
47
+ if (agent === "claude" && account.kind === "claude") {
48
+ env.CLAUDE_CONFIG_DIR = account.configDir;
49
+ }
50
+ if (agent === "codex" && account.kind === "codex") {
51
+ env.CODEX_HOME = account.configDir;
52
+ }
53
+ }
54
+ function nextManagedAccount(kind, currentId, state) {
55
+ const list = state.accounts.filter((a) => a.kind === kind);
56
+ if (list.length === 0) return null;
57
+ const slots = [
58
+ { accountId: null, label: "System default" },
59
+ ...list.map((a) => ({ accountId: a.id, label: a.label }))
60
+ ];
61
+ const idx = slots.findIndex((s) => s.accountId === (currentId ?? null));
62
+ const from = idx < 0 ? 0 : idx;
63
+ const next = slots[(from + 1) % slots.length];
64
+ if (!next || next.accountId === (currentId ?? null)) return null;
65
+ return next;
66
+ }
67
+ function ensureManagedAccountDir(kind, id) {
68
+ const dir = managedAccountConfigDir(kind, id);
69
+ mkdirSync(dir, { recursive: true });
70
+ mirrorHostConfig(kind, dir);
71
+ return dir;
72
+ }
73
+ function mirrorHostConfig(kind, destDir) {
74
+ const src = systemConfigDir(kind);
75
+ const files = kind === "claude" ? ["settings.json"] : ["config.toml"];
76
+ for (const name of files) {
77
+ const from = join(src, name);
78
+ const to = join(destDir, name);
79
+ if (!existsSync(from) || existsSync(to)) continue;
80
+ try {
81
+ copyFileSync(from, to);
82
+ } catch {
83
+ }
84
+ }
85
+ }
86
+ function normalizeManagedAccounts(raw) {
87
+ if (!raw || typeof raw !== "object") return { ...EMPTY_MANAGED_ACCOUNTS };
88
+ const source = raw;
89
+ const accounts = [];
90
+ if (Array.isArray(source.accounts)) {
91
+ for (const item of source.accounts) {
92
+ if (!item || typeof item !== "object") continue;
93
+ const rec = item;
94
+ if (typeof rec.id !== "string" || !rec.id.trim()) continue;
95
+ if (!isManagedAccountKind(rec.kind)) continue;
96
+ if (typeof rec.label !== "string" || !rec.label.trim()) continue;
97
+ if (typeof rec.configDir !== "string" || !rec.configDir.trim()) continue;
98
+ accounts.push({
99
+ id: rec.id.trim(),
100
+ kind: rec.kind,
101
+ label: rec.label.trim().slice(0, 80),
102
+ configDir: rec.configDir.trim(),
103
+ createdAt: typeof rec.createdAt === "string" && rec.createdAt.trim() ? rec.createdAt.trim() : (/* @__PURE__ */ new Date()).toISOString()
104
+ });
105
+ }
106
+ }
107
+ const claudeId = typeof source.activeClaudeAccountId === "string" && source.activeClaudeAccountId.trim() ? source.activeClaudeAccountId.trim() : null;
108
+ const codexId = typeof source.activeCodexAccountId === "string" && source.activeCodexAccountId.trim() ? source.activeCodexAccountId.trim() : null;
109
+ return {
110
+ accounts,
111
+ activeClaudeAccountId: accounts.some((a) => a.id === claudeId && a.kind === "claude") ? claudeId : null,
112
+ activeCodexAccountId: accounts.some((a) => a.id === codexId && a.kind === "codex") ? codexId : null
113
+ };
114
+ }
115
+ function withAddedAccount(state, account) {
116
+ const accounts = [...state.accounts.filter((a) => a.id !== account.id), account];
117
+ if (account.kind === "claude") {
118
+ return { ...state, accounts, activeClaudeAccountId: account.id };
119
+ }
120
+ return { ...state, accounts, activeCodexAccountId: account.id };
121
+ }
122
+ function withSelectedAccount(state, kind, accountId) {
123
+ if (accountId && !findManagedAccount(state, accountId, kind)) {
124
+ accountId = null;
125
+ }
126
+ if (kind === "claude") return { ...state, activeClaudeAccountId: accountId };
127
+ return { ...state, activeCodexAccountId: accountId };
128
+ }
129
+ function withRemovedAccount(state, id) {
130
+ const accounts = state.accounts.filter((a) => a.id !== id);
131
+ return {
132
+ accounts,
133
+ activeClaudeAccountId: state.activeClaudeAccountId === id ? null : state.activeClaudeAccountId,
134
+ activeCodexAccountId: state.activeCodexAccountId === id ? null : state.activeCodexAccountId
135
+ };
136
+ }
137
+ function loginEnvPrefix(account) {
138
+ const key = account.kind === "claude" ? "CLAUDE_CONFIG_DIR" : "CODEX_HOME";
139
+ const escaped = account.configDir.replace(/'/g, `'\\''`);
140
+ return `export ${key}='${escaped}'`;
141
+ }
142
+
143
+ export {
144
+ EMPTY_MANAGED_ACCOUNTS,
145
+ isManagedAccountKind,
146
+ systemConfigDir,
147
+ managedAccountConfigDir,
148
+ activeAccountId,
149
+ findManagedAccount,
150
+ resolveAccountForThread,
151
+ accountIdToPin,
152
+ applyManagedAccountEnv,
153
+ nextManagedAccount,
154
+ ensureManagedAccountDir,
155
+ mirrorHostConfig,
156
+ normalizeManagedAccounts,
157
+ withAddedAccount,
158
+ withSelectedAccount,
159
+ withRemovedAccount,
160
+ loginEnvPrefix
161
+ };
@@ -4,14 +4,14 @@ import {
4
4
  normalizeAbleTimeCredential,
5
5
  normalizeAbleTimeHost,
6
6
  rewriteAbleTimeError
7
- } from "./chunk-IFHHPPSL.js";
7
+ } from "./chunk-J6ONZP74.js";
8
8
  import {
9
9
  httpFetch
10
10
  } from "./chunk-N7WZ6NIN.js";
11
11
  import {
12
12
  getAbleTimeAccessToken,
13
13
  getAbleTimeHost
14
- } from "./chunk-KJM3E3NF.js";
14
+ } from "./chunk-6PFZ6XO7.js";
15
15
 
16
16
  // src/integrations/abletime-rest.ts
17
17
  var ABLETIME_REST_PREFIX = "/api/public/v2";
@@ -2,10 +2,7 @@
2
2
 
3
3
  import {
4
4
  isWorkspaceScratchPath
5
- } from "./chunk-D6JWYJ4P.js";
6
- import {
7
- listThreads
8
- } from "./chunk-RJC2MKXN.js";
5
+ } from "./chunk-N2WW62LF.js";
9
6
  import {
10
7
  ensureWorktreeSideboardIgnored
11
8
  } from "./chunk-DD67JWTN.js";
@@ -22,16 +19,19 @@ import {
22
19
  import {
23
20
  getGithubGitAuthMode,
24
21
  getGithubPat
25
- } from "./chunk-452Y24PW.js";
22
+ } from "./chunk-VIC6TDYT.js";
23
+ import {
24
+ listThreads
25
+ } from "./chunk-TJ673EZT.js";
26
26
  import {
27
27
  worktreesRoot
28
28
  } from "./chunk-Z2LGMV6C.js";
29
29
 
30
30
  // src/git/worktree.ts
31
31
  import { randomBytes } from "crypto";
32
- import { existsSync, readdirSync, realpathSync, unlinkSync, writeFileSync } from "fs";
32
+ import { existsSync as existsSync2, realpathSync, unlinkSync, writeFileSync } from "fs";
33
33
  import { tmpdir } from "os";
34
- import { join } from "path";
34
+ import { join as join2 } from "path";
35
35
 
36
36
  // src/git/team-meta.ts
37
37
  var SOCCER_TEAM_META = {
@@ -881,6 +881,42 @@ function worktreeDisplayLabelForGroup(threads) {
881
881
  const canonical = [...threads].sort((a, b) => a.createdAt.localeCompare(b.createdAt))[0];
882
882
  return threadDisplayLabel(canonical);
883
883
  }
884
+ function agentNicknameFromWorktreePath(worktreePath) {
885
+ const dir = worktreeNameFromPath(worktreePath);
886
+ if (!soccerTokenFromTakenSlug(dir)) return null;
887
+ return teamNameFromSlug(dir);
888
+ }
889
+ function worktreeIdentityTitles(thread, parentTitle) {
890
+ const out = [];
891
+ const push = (value) => {
892
+ const trimmed = value?.trim();
893
+ if (trimmed) out.push(trimmed);
894
+ };
895
+ push(parentTitle);
896
+ push(thread.prTitle);
897
+ const branch = thread.branchName?.trim() ?? "";
898
+ const path = thread.worktreePath?.trim() ?? "";
899
+ if (branch && path && branch !== "HEAD" && !isPlaceholderBranch(branch, path)) {
900
+ push(branch);
901
+ }
902
+ return out;
903
+ }
904
+ function foldLabel(value) {
905
+ return value.trim().replace(/[.…]+$/g, "").replace(/\s+/g, " ").toLowerCase();
906
+ }
907
+ function isWorktreeIdentityTitle(title, identities) {
908
+ const a = foldLabel(title);
909
+ if (!a || a === "untitled" || a === "new agent") return true;
910
+ for (const identity of identities) {
911
+ const b = foldLabel(identity);
912
+ if (!b) continue;
913
+ if (a === b) return true;
914
+ const shorter = a.length <= b.length ? a : b;
915
+ const longer = a.length <= b.length ? b : a;
916
+ if (shorter.length >= 20 && longer.startsWith(shorter)) return true;
917
+ }
918
+ return false;
919
+ }
884
920
 
885
921
  // src/git/gh-errors.ts
886
922
  var GITHUB_PR_BODY_MAX_CHARS = 65536;
@@ -1863,6 +1899,70 @@ async function addPrStackLayer(cwd, branchName) {
1863
1899
  }
1864
1900
  }
1865
1901
 
1902
+ // src/git/team-slugs.ts
1903
+ import { existsSync, readdirSync } from "fs";
1904
+ import { join } from "path";
1905
+ function sameRepoPath(a, b) {
1906
+ return normalizeWorktreePath(a) === normalizeWorktreePath(b);
1907
+ }
1908
+ function listLocalPlaceholderBranchSlugs(repoPath) {
1909
+ const slugs = [];
1910
+ const headsDir = join(repoPath, ".git", "refs", "heads");
1911
+ const threadDir = join(headsDir, "thread");
1912
+ try {
1913
+ if (existsSync(threadDir)) {
1914
+ for (const name of readdirSync(threadDir)) {
1915
+ if (!name.startsWith(".")) slugs.push(normalizeTakenSlug(name));
1916
+ }
1917
+ }
1918
+ if (existsSync(headsDir)) {
1919
+ for (const entry of readdirSync(headsDir, { withFileTypes: true })) {
1920
+ if (entry.isFile() && !entry.name.startsWith(".")) {
1921
+ slugs.push(normalizeTakenSlug(entry.name));
1922
+ }
1923
+ }
1924
+ }
1925
+ } catch {
1926
+ return slugs;
1927
+ }
1928
+ return slugs;
1929
+ }
1930
+ function collectTakenTeamSlugs(repoPath) {
1931
+ const taken = /* @__PURE__ */ new Set();
1932
+ const root = worktreesRoot(repoPath);
1933
+ if (existsSync(root)) {
1934
+ for (const entry of readdirSync(root, { withFileTypes: true })) {
1935
+ if (entry.isDirectory() && entry.name !== ".DS_Store") {
1936
+ for (const slug of takenSlugsFromThread({ worktreePath: entry.name })) {
1937
+ taken.add(slug);
1938
+ }
1939
+ }
1940
+ }
1941
+ }
1942
+ for (const slug of listLocalPlaceholderBranchSlugs(repoPath)) {
1943
+ for (const token of takenSlugsFromThread({ branchName: slug })) {
1944
+ taken.add(token);
1945
+ }
1946
+ }
1947
+ for (const thread of listThreads({ includeArchived: true })) {
1948
+ if (!sameRepoPath(thread.repoPath, repoPath)) continue;
1949
+ for (const slug of takenSlugsFromThread(thread)) {
1950
+ taken.add(slug);
1951
+ }
1952
+ }
1953
+ return taken;
1954
+ }
1955
+ function allocateTeamSlug(repoPath) {
1956
+ const taken = collectTakenTeamSlugs(repoPath);
1957
+ for (let attempt = 0; attempt < 32; attempt++) {
1958
+ const team = allocateTeamName(taken);
1959
+ const path = join(worktreesRoot(repoPath), team.slug);
1960
+ if (!existsSync(path)) return team;
1961
+ taken.add(team.slug);
1962
+ }
1963
+ throw new Error("No available soccer team worktree directories left");
1964
+ }
1965
+
1866
1966
  // src/git/worktree.ts
1867
1967
  async function lookupGithubGraphqlReset(cwd) {
1868
1968
  const result = await gh(["api", "rate_limit"], cwd, { reject: false });
@@ -2821,9 +2921,9 @@ async function refreshOriginAndMaybeFastForwardMain(repoPath, sourceRef) {
2821
2921
  await fastForwardMainCheckoutIfSafe(repoPath, { branch: def });
2822
2922
  }
2823
2923
  async function createThreadWorktree(opts) {
2824
- let branchName = `thread/${opts.slug}`;
2825
- const worktreePath = join(worktreesRoot(opts.repoPath), opts.slug);
2826
- if (existsSync(worktreePath)) {
2924
+ let branchName = opts.slug;
2925
+ const worktreePath = join2(worktreesRoot(opts.repoPath), opts.slug);
2926
+ if (existsSync2(worktreePath)) {
2827
2927
  throw new Error(`Worktree already exists at ${worktreePath}`);
2828
2928
  }
2829
2929
  await ensureGhPreferOrigin(opts.repoPath);
@@ -2864,8 +2964,8 @@ ${add.stdout}`;
2864
2964
  async function createExistingBranchWorktree(opts) {
2865
2965
  const branchName = opts.branchName.trim();
2866
2966
  if (!branchName) throw new Error("branch name required");
2867
- const worktreePath = join(worktreesRoot(opts.repoPath), opts.slug);
2868
- if (existsSync(worktreePath)) {
2967
+ const worktreePath = join2(worktreesRoot(opts.repoPath), opts.slug);
2968
+ if (existsSync2(worktreePath)) {
2869
2969
  throw new Error(`Worktree already exists at ${worktreePath}`);
2870
2970
  }
2871
2971
  await ensureGhPreferOrigin(opts.repoPath);
@@ -3204,7 +3304,7 @@ async function createOrUpdatePr(worktreePath, opts) {
3204
3304
  const headRef = ghHeadRef(slug, opts.head);
3205
3305
  const branchOnly = opts.head.trim().replace(/^refs\/heads\//, "");
3206
3306
  const bodyText = clampGithubPrBody(opts.body ?? opts.title);
3207
- const bodyFile = join(
3307
+ const bodyFile = join2(
3208
3308
  tmpdir(),
3209
3309
  `sideboard-pr-body-${process.pid}-${randomBytes(6).toString("hex")}.md`
3210
3310
  );
@@ -3302,53 +3402,6 @@ function suggestSlug(source) {
3302
3402
  const stamp = Date.now().toString(36).slice(-4);
3303
3403
  return `${base || "thread"}-${stamp}`;
3304
3404
  }
3305
- function sameRepoPath(a, b) {
3306
- return normalizeWorktreePath(a) === normalizeWorktreePath(b);
3307
- }
3308
- function listLocalThreadBranchSlugs(repoPath) {
3309
- const refsDir = join(repoPath, ".git", "refs", "heads", "thread");
3310
- if (!existsSync(refsDir)) return [];
3311
- try {
3312
- return readdirSync(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
3313
- } catch {
3314
- return [];
3315
- }
3316
- }
3317
- function collectTakenTeamSlugs(repoPath) {
3318
- const taken = /* @__PURE__ */ new Set();
3319
- const root = worktreesRoot(repoPath);
3320
- if (existsSync(root)) {
3321
- for (const entry of readdirSync(root, { withFileTypes: true })) {
3322
- if (entry.isDirectory() && entry.name !== ".DS_Store") {
3323
- for (const slug of takenSlugsFromThread({ worktreePath: entry.name })) {
3324
- taken.add(slug);
3325
- }
3326
- }
3327
- }
3328
- }
3329
- for (const slug of listLocalThreadBranchSlugs(repoPath)) {
3330
- for (const token of takenSlugsFromThread({ branchName: slug })) {
3331
- taken.add(token);
3332
- }
3333
- }
3334
- for (const thread of listThreads({ includeArchived: true })) {
3335
- if (!sameRepoPath(thread.repoPath, repoPath)) continue;
3336
- for (const slug of takenSlugsFromThread(thread)) {
3337
- taken.add(slug);
3338
- }
3339
- }
3340
- return taken;
3341
- }
3342
- function allocateTeamSlug(repoPath) {
3343
- const taken = collectTakenTeamSlugs(repoPath);
3344
- for (let attempt = 0; attempt < 32; attempt++) {
3345
- const team = allocateTeamName(taken);
3346
- const path = join(worktreesRoot(repoPath), team.slug);
3347
- if (!existsSync(path)) return team;
3348
- taken.add(team.slug);
3349
- }
3350
- throw new Error("No available soccer team worktree directories left");
3351
- }
3352
3405
 
3353
3406
  export {
3354
3407
  FAMOUS_SOCCER_TEAMS,
@@ -3365,6 +3418,9 @@ export {
3365
3418
  threadDisplayLabel,
3366
3419
  worktreeDisplayLabel,
3367
3420
  worktreeDisplayLabelForGroup,
3421
+ agentNicknameFromWorktreePath,
3422
+ worktreeIdentityTitles,
3423
+ isWorktreeIdentityTitle,
3368
3424
  formatGhLandError,
3369
3425
  githubAgentGitEnv,
3370
3426
  mergeAgentGitAuthEnv,
@@ -3381,6 +3437,8 @@ export {
3381
3437
  getPrStack,
3382
3438
  initPrStack,
3383
3439
  addPrStackLayer,
3440
+ collectTakenTeamSlugs,
3441
+ allocateTeamSlug,
3384
3442
  slugify,
3385
3443
  resolveRepoRoot,
3386
3444
  canonicalizeRepoPath,
@@ -3426,7 +3484,5 @@ export {
3426
3484
  mergePr,
3427
3485
  ghPrCreateAssigneeArgs,
3428
3486
  createOrUpdatePr,
3429
- suggestSlug,
3430
- collectTakenTeamSlugs,
3431
- allocateTeamSlug
3487
+ suggestSlug
3432
3488
  };
@@ -81,6 +81,7 @@ function normalizeThread(raw) {
81
81
  runScriptRequest: normalizeRunScriptRequest(raw.runScriptRequest),
82
82
  quotaResumeAt: raw.quotaResumeAt ?? null,
83
83
  quotaContinuedFromId: raw.quotaContinuedFromId ?? null,
84
+ accountId: raw.accountId === null ? null : typeof raw.accountId === "string" && raw.accountId.trim() ? raw.accountId.trim() : void 0,
84
85
  archivedAt: typeof raw.archivedAt === "string" && raw.archivedAt.trim() ? raw.archivedAt.trim() : void 0,
85
86
  compactedMessages: Array.isArray(raw.compactedMessages) ? raw.compactedMessages : void 0
86
87
  };
@@ -133,7 +134,8 @@ function createEmptyThread(partial) {
133
134
  repoPath: partial.repoPath,
134
135
  agent: partial.agent,
135
136
  lastError: null,
136
- agentPid: null
137
+ agentPid: null,
138
+ ...partial.accountId !== void 0 ? { accountId: partial.accountId } : {}
137
139
  };
138
140
  }
139
141
  async function withThreadLock(id, fn) {