@sideboard-ai/core 0.1.177 → 0.1.179

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 (31) hide show
  1. package/dist/{agents-544IX5KA.js → agents-2UD26PUT.js} +4 -4
  2. package/dist/{agents-UENEQ6J2.js → agents-XPWZG3JU.js} +4 -4
  3. package/dist/{chunk-3ZFGZ7RT.js → chunk-7T5XKNOF.js} +2 -2
  4. package/dist/{chunk-LZQULFIT.js → chunk-GOZ6T3AG.js} +2 -0
  5. package/dist/{chunk-DVYRABZC.js → chunk-GVC4IVF5.js} +76 -16
  6. package/dist/{chunk-NIB6BTC6.js → chunk-IVJFEB3T.js} +3 -3
  7. package/dist/{chunk-DJUDDKXM.js → chunk-MZOZ6PIZ.js} +75 -15
  8. package/dist/{chunk-7UURXPKD.js → chunk-TCQAFTSV.js} +2 -0
  9. package/dist/{chunk-W44EKPIR.js → chunk-VUFJ5MAN.js} +3 -3
  10. package/dist/{chunk-7JIYKYLL.js → chunk-WXKXSZN4.js} +10 -7
  11. package/dist/{chunk-7O53GXTA.js → chunk-XBLN52RZ.js} +10 -7
  12. package/dist/{chunk-FJWQCZ74.js → chunk-XV3EFFZ6.js} +2 -2
  13. package/dist/{coordinator-prompt-PRM5ARWG.js → coordinator-prompt-3NRUXH3F.js} +3 -3
  14. package/dist/{coordinator-prompt-BE2FERYE.js → coordinator-prompt-GKH7Q7PK.js} +3 -3
  15. package/dist/{global-workspace-3HIWNQ3B.js → global-workspace-2FQU62S2.js} +3 -3
  16. package/dist/{global-workspace-J737XNUX.js → global-workspace-C2JMJXYV.js} +3 -3
  17. package/dist/index.cjs +82 -11
  18. package/dist/index.d.cts +16 -1
  19. package/dist/index.d.ts +16 -1
  20. package/dist/index.js +13 -7
  21. package/dist/mcp/run-stdio.cjs +127 -11
  22. package/dist/mcp/run-stdio.js +59 -8
  23. package/dist/{orchestrator-FTGAFZMK.js → orchestrator-HOMNNKMT.js} +5 -5
  24. package/dist/{orchestrator-XAJ3LREM.js → orchestrator-WNFMRRQP.js} +5 -5
  25. package/dist/{thread-store-KBFBHT5G.js → thread-store-RXXNSRVO.js} +1 -1
  26. package/dist/{thread-store-MVQU6HPJ.js → thread-store-ZL6GDIDP.js} +1 -1
  27. package/dist/{workspaces-ULHYXM4Y.js → workspaces-J3M3IPR3.js} +3 -3
  28. package/dist/{workspaces-DR4UNOQC.js → workspaces-YVZYX5H2.js} +3 -3
  29. package/dist/{worktree-LC4VRWDM.js → worktree-7LOSSD7G.js} +2 -2
  30. package/dist/{worktree-UTDBQXSS.js → worktree-LPWTX2NA.js} +2 -2
  31. package/package.json +1 -1
@@ -32,9 +32,9 @@ import {
32
32
  resolveLoginCommand,
33
33
  resolveQuotaFallbackAgent,
34
34
  whichOnPath
35
- } from "./chunk-NIB6BTC6.js";
36
- import "./chunk-3ZFGZ7RT.js";
37
- import "./chunk-7JIYKYLL.js";
35
+ } from "./chunk-IVJFEB3T.js";
36
+ import "./chunk-7T5XKNOF.js";
37
+ import "./chunk-WXKXSZN4.js";
38
38
  import "./chunk-6K64FJDD.js";
39
39
  import "./chunk-IEEAVWAP.js";
40
40
  import "./chunk-AN3THU7F.js";
@@ -53,7 +53,7 @@ import {
53
53
  } from "./chunk-J7LQVLFQ.js";
54
54
  import "./chunk-4TR3HZFT.js";
55
55
  import "./chunk-JT7R45JB.js";
56
- import "./chunk-7UURXPKD.js";
56
+ import "./chunk-TCQAFTSV.js";
57
57
  import "./chunk-77WWLBCI.js";
58
58
  import "./chunk-EFVFB2AH.js";
59
59
  import "./chunk-QQKDGPUI.js";
@@ -38,14 +38,14 @@ import {
38
38
  resolveQuotaFallbackAgent,
39
39
  turnCostUsdFromCursorUsage,
40
40
  whichOnPath
41
- } from "./chunk-W44EKPIR.js";
41
+ } from "./chunk-VUFJ5MAN.js";
42
42
  import "./chunk-HVIEYTUK.js";
43
43
  import "./chunk-Y4MIXGPA.js";
44
44
  import "./chunk-VKQGAWHY.js";
45
- import "./chunk-FJWQCZ74.js";
46
- import "./chunk-7O53GXTA.js";
45
+ import "./chunk-XV3EFFZ6.js";
46
+ import "./chunk-XBLN52RZ.js";
47
47
  import "./chunk-D6JWYJ4P.js";
48
- import "./chunk-LZQULFIT.js";
48
+ import "./chunk-GOZ6T3AG.js";
49
49
  import "./chunk-SYFVUF2C.js";
50
50
  import {
51
51
  conductorBundledBinDir,
@@ -5,7 +5,7 @@ import {
5
5
  resolveRepoRoot,
6
6
  takenSlugsFromThread,
7
7
  teamSlugFromName
8
- } from "./chunk-7JIYKYLL.js";
8
+ } from "./chunk-WXKXSZN4.js";
9
9
  import {
10
10
  ATTACHMENTS_DIR,
11
11
  attachmentsGitignoreBody
@@ -28,7 +28,7 @@ import {
28
28
  listThreads,
29
29
  updateThread,
30
30
  writeThread
31
- } from "./chunk-7UURXPKD.js";
31
+ } from "./chunk-TCQAFTSV.js";
32
32
  import {
33
33
  appDataDir,
34
34
  globalAgentCwd,
@@ -75,6 +75,8 @@ function createEmptyThread(partial) {
75
75
  prTitle: partial.prTitle ?? null,
76
76
  prState: partial.prState ?? null,
77
77
  prIsDraft: Boolean(partial.prIsDraft),
78
+ prAuthorLogin: partial.prAuthorLogin?.trim() || null,
79
+ prReviewerLogins: partial.prReviewerLogins ?? [],
78
80
  skipAutoArchiveOnMerge: partial.skipAutoArchiveOnMerge ?? false,
79
81
  cowboy: Boolean(partial.cowboy),
80
82
  stackId: partial.stackId ?? null,
@@ -24,7 +24,7 @@ import {
24
24
  stripBrightsyNdjsonNoise,
25
25
  sumUsageList,
26
26
  toolDescription
27
- } from "./chunk-NIB6BTC6.js";
27
+ } from "./chunk-IVJFEB3T.js";
28
28
  import {
29
29
  SLACK_REPLY_FORMATTING,
30
30
  addWorkspace,
@@ -47,7 +47,7 @@ import {
47
47
  stageAbsolutePathsAsAttachments,
48
48
  stageBuffersAsAttachments,
49
49
  syncWorkspacesFromThreads
50
- } from "./chunk-3ZFGZ7RT.js";
50
+ } from "./chunk-7T5XKNOF.js";
51
51
  import {
52
52
  addPrStackLayer,
53
53
  allocateTeamName,
@@ -97,7 +97,7 @@ import {
97
97
  worktreeDisplayLabelForGroup,
98
98
  worktreeNameFromPath,
99
99
  worktreeSlugForTicket
100
- } from "./chunk-7JIYKYLL.js";
100
+ } from "./chunk-WXKXSZN4.js";
101
101
  import {
102
102
  ATTACHMENTS_DIR,
103
103
  DETACHED_JOBS_DIR,
@@ -170,7 +170,7 @@ import {
170
170
  updateThread,
171
171
  withThreadLock,
172
172
  writeThread
173
- } from "./chunk-7UURXPKD.js";
173
+ } from "./chunk-TCQAFTSV.js";
174
174
  import {
175
175
  appDataDir,
176
176
  findConventionSetup,
@@ -467,7 +467,7 @@ async function continueSourceThread(threadId, prompt) {
467
467
  await continueOnReply(threadId, prompt);
468
468
  return;
469
469
  }
470
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-FTGAFZMK.js");
470
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-HOMNNKMT.js");
471
471
  await getOrchestrator2().send(threadId, prompt);
472
472
  } catch {
473
473
  }
@@ -801,9 +801,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
801
801
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
802
802
  );
803
803
  }
804
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-3HIWNQ3B.js");
804
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-2FQU62S2.js");
805
805
  if (isGlobalThread2(thread)) {
806
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-PRM5ARWG.js");
806
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-3NRUXH3F.js");
807
807
  ensureGlobalCoordinatorCwd2(
808
808
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
809
809
  );
@@ -1568,6 +1568,8 @@ function worktreeBindingFrom(from) {
1568
1568
  prTitle: from.prTitle,
1569
1569
  prState: from.prState,
1570
1570
  prIsDraft: from.prIsDraft,
1571
+ prAuthorLogin: from.prAuthorLogin,
1572
+ prReviewerLogins: from.prReviewerLogins,
1571
1573
  skipAutoArchiveOnMerge: from.skipAutoArchiveOnMerge,
1572
1574
  stackId: from.stackId,
1573
1575
  stackLayer: from.stackLayer,
@@ -3163,6 +3165,36 @@ function groupHomeBoardWorktrees(threads, sort = DEFAULT_WORKTREE_SORT, labelOf
3163
3165
  }
3164
3166
  return [...map.values()].map((list) => sortThreadsInWorktree(list)).sort((a, b) => compareWorktreeGroups(a, b, sort, labelOf));
3165
3167
  }
3168
+ var DEFAULT_BOARD_OWNERSHIP = "all";
3169
+ function normalizeViewerLogin(login) {
3170
+ return (login ?? "").trim().toLowerCase();
3171
+ }
3172
+ function loginsInclude(logins, viewerLogin) {
3173
+ const me = normalizeViewerLogin(viewerLogin);
3174
+ if (!me) return false;
3175
+ return (logins ?? []).some((login) => normalizeViewerLogin(login) === me);
3176
+ }
3177
+ function classifyWorktreeOwnership(group, viewerLogin = "") {
3178
+ const me = normalizeViewerLogin(viewerLogin);
3179
+ if (group.some((t) => {
3180
+ const author = normalizeViewerLogin(t.prAuthorLogin);
3181
+ return Boolean(author && me && author === me);
3182
+ })) {
3183
+ return "mine";
3184
+ }
3185
+ const reviewing = group.some((t) => {
3186
+ const author = normalizeViewerLogin(t.prAuthorLogin);
3187
+ if (author && me && author !== me) return true;
3188
+ if (t.sourceType === "pr" && (!author || !me || author !== me)) return true;
3189
+ if (me && loginsInclude(t.prReviewerLogins, me)) return true;
3190
+ return false;
3191
+ });
3192
+ return reviewing ? "reviewing" : "mine";
3193
+ }
3194
+ function worktreeMatchesOwnership(group, filter, viewerLogin = "") {
3195
+ if (filter === "all") return true;
3196
+ return classifyWorktreeOwnership(group, viewerLogin) === filter;
3197
+ }
3166
3198
  function classifyWorktreeColumn(group) {
3167
3199
  if (group.some((t) => isMergedPrState(t.prUrl, t.prState))) return "done";
3168
3200
  if (group.some((t) => isOpenPrState(t.prUrl, t.prState) && !t.prIsDraft)) {
@@ -3520,6 +3552,8 @@ function assembleHomeBoard(input) {
3520
3552
  const tokens = tokenizeQuery(input.query ?? "");
3521
3553
  const repo = input.repoPath?.trim() ?? "";
3522
3554
  const kind = input.kind ?? "all";
3555
+ const ownership = input.ownership ?? DEFAULT_BOARD_OWNERSHIP;
3556
+ const viewerLogin = input.viewerLogin ?? "";
3523
3557
  const limit = Math.max(1, input.limit ?? BOARD_PAGE_SIZE);
3524
3558
  const wsName = input.workspaceName ?? (() => "");
3525
3559
  const live = input.threads.filter((t) => t.status !== "archived" && isHomeBoardThread(t));
@@ -3548,6 +3582,7 @@ function assembleHomeBoard(input) {
3548
3582
  };
3549
3583
  for (const group of groupHomeBoardWorktrees(live)) {
3550
3584
  if (!group.some((t) => threadMatchesKind(t, kind))) continue;
3585
+ if (!worktreeMatchesOwnership(group, ownership, viewerLogin)) continue;
3551
3586
  const col = classifyWorktreeColumn(group);
3552
3587
  if (col === "backlog") continue;
3553
3588
  const primary = group[0];
@@ -3577,7 +3612,7 @@ function assembleHomeBoard(input) {
3577
3612
  }
3578
3613
  return { columns, hidden, totals };
3579
3614
  }
3580
- var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards). Do not create a second worktree for a ticket, PR, or named branch that already has a live checkout \u2014 create_thread / start_board_card return that thread (alreadyStarted). Creating from the default branch still opens a new isolated worktree. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats stay in the sidebar. Do not invent status.";
3615
+ var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards). Do not create a second worktree for a ticket, PR, or named branch that already has a live checkout \u2014 create_thread / start_board_card return that thread (alreadyStarted). Creating from the default branch still opens a new isolated worktree. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Merged. ownership=mine is PRs you authored (or WIP with no PR); ownership=reviewing is someone else's PR (or a review-requested checkout). Viewer login comes from gh, not a setting. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats stay in the sidebar. Do not invent status.";
3581
3616
 
3582
3617
  // src/threads/create.ts
3583
3618
  function persistCreateAttachments(worktreePath, attachments) {
@@ -3710,6 +3745,7 @@ async function createThread(input, _onSetupLine) {
3710
3745
  }
3711
3746
  let prUrl = null;
3712
3747
  let prTitle = null;
3748
+ let prAuthorLogin2 = null;
3713
3749
  if (sourceType === "pr") {
3714
3750
  const num = Number(input.sourceRef.replace(/^#/, ""));
3715
3751
  if (!Number.isFinite(num)) throw new Error(`Invalid PR number: ${input.sourceRef}`);
@@ -3725,6 +3761,7 @@ async function createThread(input, _onSetupLine) {
3725
3761
  if (reusedPr) return reusedPr;
3726
3762
  sourceIsFork = pr.isCrossRepository;
3727
3763
  prUrl = pr.url;
3764
+ prAuthorLogin2 = pr.author?.login?.trim() || null;
3728
3765
  const localFetchBranch = `sideboard-pr-${pr.number}`;
3729
3766
  await fetchPrHead(repoPath, pr.number, localFetchBranch);
3730
3767
  sourceRef = localFetchBranch;
@@ -3747,6 +3784,7 @@ async function createThread(input, _onSetupLine) {
3747
3784
  if (existing.url) {
3748
3785
  prUrl = existing.url;
3749
3786
  prTitle = existing.title;
3787
+ prAuthorLogin2 = existing.author?.login?.trim() || null;
3750
3788
  }
3751
3789
  }
3752
3790
  }
@@ -3781,14 +3819,15 @@ async function createThread(input, _onSetupLine) {
3781
3819
  parentThreadId: input.parentThreadId ?? null,
3782
3820
  status: "idle",
3783
3821
  prUrl,
3784
- prTitle
3822
+ prTitle,
3823
+ prAuthorLogin: prAuthorLogin2
3785
3824
  });
3786
3825
  writeThread(thread);
3787
3826
  await ensureWorkspace(repoPath);
3788
3827
  return readThread(thread.id) ?? thread;
3789
3828
  }
3790
3829
  async function listLinearIssues(agent, repoPath) {
3791
- const { getAdapter: getAdapter2 } = await import("./agents-544IX5KA.js");
3830
+ const { getAdapter: getAdapter2 } = await import("./agents-2UD26PUT.js");
3792
3831
  await requireAgent(agent, { requireLinear: true });
3793
3832
  const adapter = getAdapter2(agent);
3794
3833
  if (!adapter.listLinearIssues) {
@@ -4210,7 +4249,7 @@ async function adoptThread(input) {
4210
4249
  messages: input.messages ?? []
4211
4250
  });
4212
4251
  writeThread(thread);
4213
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ULHYXM4Y.js");
4252
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-J3M3IPR3.js");
4214
4253
  await ensureWorkspace2(repoPath);
4215
4254
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-X54WSOXM.js");
4216
4255
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -6692,7 +6731,7 @@ function formatScheduledPrompt(name, prompt) {
6692
6731
  ${prompt}`;
6693
6732
  }
6694
6733
  async function defaultDeps() {
6695
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-FTGAFZMK.js");
6734
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-HOMNNKMT.js");
6696
6735
  const orch = getOrchestrator2();
6697
6736
  return {
6698
6737
  findThread: (id) => findThreadByRef(id),
@@ -6806,6 +6845,11 @@ function isPidAlive(pid) {
6806
6845
  return false;
6807
6846
  }
6808
6847
  }
6848
+ function sameLoginList(a, b) {
6849
+ const left = [...a ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
6850
+ const right = [...b ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
6851
+ return left.length === right.length && left.every((login, i) => login === right[i]);
6852
+ }
6809
6853
  async function waitForPidExit(pid, timeoutMs) {
6810
6854
  const start = Date.now();
6811
6855
  while (isPidAlive(pid)) {
@@ -8455,6 +8499,14 @@ var Orchestrator = class {
8455
8499
  if (nextState && nextState !== prevState) patch.prState = nextState;
8456
8500
  const nextDraft = Boolean(meta.isDraft) && nextState !== "MERGED" && nextState !== "CLOSED";
8457
8501
  if (nextDraft !== Boolean(thread.prIsDraft)) patch.prIsDraft = nextDraft;
8502
+ const nextAuthor = meta.authorLogin?.trim() || "";
8503
+ if (nextAuthor && nextAuthor !== (thread.prAuthorLogin ?? "").trim()) {
8504
+ patch.prAuthorLogin = nextAuthor;
8505
+ }
8506
+ const nextReviewers = meta.reviewerLogins ?? [];
8507
+ if (!sameLoginList(nextReviewers, thread.prReviewerLogins)) {
8508
+ patch.prReviewerLogins = nextReviewers;
8509
+ }
8458
8510
  if (thread.skipAutoArchiveOnMerge && nextState && nextState !== "MERGED" && nextState !== "CLOSED") {
8459
8511
  patch.skipAutoArchiveOnMerge = false;
8460
8512
  }
@@ -8482,6 +8534,14 @@ var Orchestrator = class {
8482
8534
  const sibPatch = { prState: "MERGED", prIsDraft: false };
8483
8535
  if (meta.url && meta.url !== t.prUrl) sibPatch.prUrl = meta.url;
8484
8536
  if (meta.title && meta.title !== t.prTitle) sibPatch.prTitle = meta.title;
8537
+ const sibAuthor = meta.authorLogin?.trim() || "";
8538
+ if (sibAuthor && sibAuthor !== (t.prAuthorLogin ?? "").trim()) {
8539
+ sibPatch.prAuthorLogin = sibAuthor;
8540
+ }
8541
+ const sibReviewers = meta.reviewerLogins ?? [];
8542
+ if (!sameLoginList(sibReviewers, t.prReviewerLogins)) {
8543
+ sibPatch.prReviewerLogins = sibReviewers;
8544
+ }
8485
8545
  if (Object.keys(sibPatch).length > 0) updateThread(t.id, sibPatch);
8486
8546
  }
8487
8547
  for (const t of siblings) {
@@ -8782,7 +8842,7 @@ var Orchestrator = class {
8782
8842
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
8783
8843
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
8784
8844
  try {
8785
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ULHYXM4Y.js");
8845
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-J3M3IPR3.js");
8786
8846
  await ensureWorkspace2(thread.repoPath);
8787
8847
  } catch {
8788
8848
  }
@@ -8836,7 +8896,7 @@ var Orchestrator = class {
8836
8896
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
8837
8897
  );
8838
8898
  }
8839
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-UTDBQXSS.js");
8899
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-LPWTX2NA.js");
8840
8900
  const slug = thread.worktreePath.split("/").pop();
8841
8901
  const dest = thread.worktreePath;
8842
8902
  await withRepoGitLock(thread.repoPath, async () => {
@@ -8946,7 +9006,7 @@ async function startOrchestration(opts) {
8946
9006
  sourceRef: "default",
8947
9007
  ...createOpts
8948
9008
  }).catch(async () => {
8949
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-UTDBQXSS.js");
9009
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-LPWTX2NA.js");
8950
9010
  const repo = await resolveRepoRoot2(repoPath);
8951
9011
  const def = await resolveDefaultBranch2(repo);
8952
9012
  return orch.createThread({
@@ -8956,7 +9016,7 @@ async function startOrchestration(opts) {
8956
9016
  repoPath: repo
8957
9017
  });
8958
9018
  });
8959
- const { updateThread: upd } = await import("./thread-store-KBFBHT5G.js");
9019
+ const { updateThread: upd } = await import("./thread-store-RXXNSRVO.js");
8960
9020
  const updated = upd(thread.id, {
8961
9021
  sourceType: "orchestration",
8962
9022
  sourceRef: goal
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  isOrchestratorThread
3
- } from "./chunk-3ZFGZ7RT.js";
3
+ } from "./chunk-7T5XKNOF.js";
4
4
  import {
5
5
  codexUnattendedGitConfigArgs,
6
6
  mergeAgentGitAuthEnv,
7
7
  resolveAgentGitAuthEnv,
8
8
  resolveCodexGitWritableRoots
9
- } from "./chunk-7JIYKYLL.js";
9
+ } from "./chunk-WXKXSZN4.js";
10
10
  import {
11
11
  applyConnectedTeamToCli,
12
12
  brightsyMcpServerName,
@@ -1898,7 +1898,7 @@ var claudeAdapter = {
1898
1898
  );
1899
1899
  }
1900
1900
  const mode = permissionMode(thread);
1901
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-3HIWNQ3B.js");
1901
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-2FQU62S2.js");
1902
1902
  const isOrchestrator = isOrchestratorThread2(thread);
1903
1903
  const injectedServers = await buildInjectedMcpServers({
1904
1904
  includeSideboard: true,
@@ -33,7 +33,7 @@ import {
33
33
  summarizeTurnStderr,
34
34
  toolDescription,
35
35
  turnFailChatText
36
- } from "./chunk-W44EKPIR.js";
36
+ } from "./chunk-VUFJ5MAN.js";
37
37
  import {
38
38
  extractPresentedPlan,
39
39
  readPlanFile,
@@ -64,7 +64,7 @@ import {
64
64
  stageAbsolutePathsAsAttachments,
65
65
  stageBuffersAsAttachments,
66
66
  syncWorkspacesFromThreads
67
- } from "./chunk-FJWQCZ74.js";
67
+ } from "./chunk-XV3EFFZ6.js";
68
68
  import {
69
69
  addPrStackLayer,
70
70
  allocateTeamName,
@@ -114,7 +114,7 @@ import {
114
114
  worktreeDisplayLabelForGroup,
115
115
  worktreeNameFromPath,
116
116
  worktreeSlugForTicket
117
- } from "./chunk-7O53GXTA.js";
117
+ } from "./chunk-XBLN52RZ.js";
118
118
  import {
119
119
  ATTACHMENTS_DIR,
120
120
  DETACHED_JOBS_DIR,
@@ -132,7 +132,7 @@ import {
132
132
  updateThread,
133
133
  withThreadLock,
134
134
  writeThread
135
- } from "./chunk-LZQULFIT.js";
135
+ } from "./chunk-GOZ6T3AG.js";
136
136
  import {
137
137
  ensureWorktreeSideboardIgnored
138
138
  } from "./chunk-SYFVUF2C.js";
@@ -402,7 +402,7 @@ async function continueSourceThread(threadId, prompt) {
402
402
  await continueOnReply(threadId, prompt);
403
403
  return;
404
404
  }
405
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-XAJ3LREM.js");
405
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-WNFMRRQP.js");
406
406
  await getOrchestrator2().send(threadId, prompt);
407
407
  } catch {
408
408
  }
@@ -795,9 +795,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
795
795
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
796
796
  );
797
797
  }
798
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-J737XNUX.js");
798
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-C2JMJXYV.js");
799
799
  if (isGlobalThread2(thread)) {
800
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-BE2FERYE.js");
800
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-GKH7Q7PK.js");
801
801
  ensureGlobalCoordinatorCwd2(
802
802
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
803
803
  );
@@ -1537,6 +1537,8 @@ function worktreeBindingFrom(from) {
1537
1537
  prTitle: from.prTitle,
1538
1538
  prState: from.prState,
1539
1539
  prIsDraft: from.prIsDraft,
1540
+ prAuthorLogin: from.prAuthorLogin,
1541
+ prReviewerLogins: from.prReviewerLogins,
1540
1542
  skipAutoArchiveOnMerge: from.skipAutoArchiveOnMerge,
1541
1543
  stackId: from.stackId,
1542
1544
  stackLayer: from.stackLayer,
@@ -3071,6 +3073,36 @@ function groupHomeBoardWorktrees(threads, sort = DEFAULT_WORKTREE_SORT, labelOf
3071
3073
  }
3072
3074
  return [...map.values()].map((list) => sortThreadsInWorktree(list)).sort((a, b) => compareWorktreeGroups(a, b, sort, labelOf));
3073
3075
  }
3076
+ var DEFAULT_BOARD_OWNERSHIP = "all";
3077
+ function normalizeViewerLogin(login) {
3078
+ return (login ?? "").trim().toLowerCase();
3079
+ }
3080
+ function loginsInclude(logins, viewerLogin) {
3081
+ const me = normalizeViewerLogin(viewerLogin);
3082
+ if (!me) return false;
3083
+ return (logins ?? []).some((login) => normalizeViewerLogin(login) === me);
3084
+ }
3085
+ function classifyWorktreeOwnership(group, viewerLogin = "") {
3086
+ const me = normalizeViewerLogin(viewerLogin);
3087
+ if (group.some((t) => {
3088
+ const author = normalizeViewerLogin(t.prAuthorLogin);
3089
+ return Boolean(author && me && author === me);
3090
+ })) {
3091
+ return "mine";
3092
+ }
3093
+ const reviewing = group.some((t) => {
3094
+ const author = normalizeViewerLogin(t.prAuthorLogin);
3095
+ if (author && me && author !== me) return true;
3096
+ if (t.sourceType === "pr" && (!author || !me || author !== me)) return true;
3097
+ if (me && loginsInclude(t.prReviewerLogins, me)) return true;
3098
+ return false;
3099
+ });
3100
+ return reviewing ? "reviewing" : "mine";
3101
+ }
3102
+ function worktreeMatchesOwnership(group, filter, viewerLogin = "") {
3103
+ if (filter === "all") return true;
3104
+ return classifyWorktreeOwnership(group, viewerLogin) === filter;
3105
+ }
3074
3106
  function classifyWorktreeColumn(group) {
3075
3107
  if (group.some((t) => isMergedPrState(t.prUrl, t.prState))) return "done";
3076
3108
  if (group.some((t) => isOpenPrState(t.prUrl, t.prState) && !t.prIsDraft)) {
@@ -3391,6 +3423,8 @@ function assembleHomeBoard(input) {
3391
3423
  const tokens = tokenizeQuery(input.query ?? "");
3392
3424
  const repo = input.repoPath?.trim() ?? "";
3393
3425
  const kind = input.kind ?? "all";
3426
+ const ownership = input.ownership ?? DEFAULT_BOARD_OWNERSHIP;
3427
+ const viewerLogin = input.viewerLogin ?? "";
3394
3428
  const limit = Math.max(1, input.limit ?? BOARD_PAGE_SIZE);
3395
3429
  const wsName = input.workspaceName ?? (() => "");
3396
3430
  const live = input.threads.filter((t) => t.status !== "archived" && isHomeBoardThread(t));
@@ -3419,6 +3453,7 @@ function assembleHomeBoard(input) {
3419
3453
  };
3420
3454
  for (const group of groupHomeBoardWorktrees(live)) {
3421
3455
  if (!group.some((t) => threadMatchesKind(t, kind))) continue;
3456
+ if (!worktreeMatchesOwnership(group, ownership, viewerLogin)) continue;
3422
3457
  const col = classifyWorktreeColumn(group);
3423
3458
  if (col === "backlog") continue;
3424
3459
  const primary = group[0];
@@ -3448,7 +3483,7 @@ function assembleHomeBoard(input) {
3448
3483
  }
3449
3484
  return { columns, hidden, totals };
3450
3485
  }
3451
- var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards). Do not create a second worktree for a ticket, PR, or named branch that already has a live checkout \u2014 create_thread / start_board_card return that thread (alreadyStarted). Creating from the default branch still opens a new isolated worktree. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats stay in the sidebar. Do not invent status.";
3486
+ var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards). Do not create a second worktree for a ticket, PR, or named branch that already has a live checkout \u2014 create_thread / start_board_card return that thread (alreadyStarted). Creating from the default branch still opens a new isolated worktree. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Merged. ownership=mine is PRs you authored (or WIP with no PR); ownership=reviewing is someone else's PR (or a review-requested checkout). Viewer login comes from gh, not a setting. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats stay in the sidebar. Do not invent status.";
3452
3487
 
3453
3488
  // src/threads/create.ts
3454
3489
  function persistCreateAttachments(worktreePath, attachments) {
@@ -3581,6 +3616,7 @@ async function createThread(input, _onSetupLine) {
3581
3616
  }
3582
3617
  let prUrl = null;
3583
3618
  let prTitle = null;
3619
+ let prAuthorLogin2 = null;
3584
3620
  if (sourceType === "pr") {
3585
3621
  const num = Number(input.sourceRef.replace(/^#/, ""));
3586
3622
  if (!Number.isFinite(num)) throw new Error(`Invalid PR number: ${input.sourceRef}`);
@@ -3596,6 +3632,7 @@ async function createThread(input, _onSetupLine) {
3596
3632
  if (reusedPr) return reusedPr;
3597
3633
  sourceIsFork = pr.isCrossRepository;
3598
3634
  prUrl = pr.url;
3635
+ prAuthorLogin2 = pr.author?.login?.trim() || null;
3599
3636
  const localFetchBranch = `sideboard-pr-${pr.number}`;
3600
3637
  await fetchPrHead(repoPath, pr.number, localFetchBranch);
3601
3638
  sourceRef = localFetchBranch;
@@ -3618,6 +3655,7 @@ async function createThread(input, _onSetupLine) {
3618
3655
  if (existing.url) {
3619
3656
  prUrl = existing.url;
3620
3657
  prTitle = existing.title;
3658
+ prAuthorLogin2 = existing.author?.login?.trim() || null;
3621
3659
  }
3622
3660
  }
3623
3661
  }
@@ -3652,7 +3690,8 @@ async function createThread(input, _onSetupLine) {
3652
3690
  parentThreadId: input.parentThreadId ?? null,
3653
3691
  status: "idle",
3654
3692
  prUrl,
3655
- prTitle
3693
+ prTitle,
3694
+ prAuthorLogin: prAuthorLogin2
3656
3695
  });
3657
3696
  writeThread(thread);
3658
3697
  await ensureWorkspace(repoPath);
@@ -4069,7 +4108,7 @@ async function adoptThread(input) {
4069
4108
  messages: input.messages ?? []
4070
4109
  });
4071
4110
  writeThread(thread);
4072
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-DR4UNOQC.js");
4111
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-YVZYX5H2.js");
4073
4112
  await ensureWorkspace2(repoPath);
4074
4113
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
4075
4114
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -6345,7 +6384,7 @@ function formatScheduledPrompt(name, prompt) {
6345
6384
  ${prompt}`;
6346
6385
  }
6347
6386
  async function defaultDeps() {
6348
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-XAJ3LREM.js");
6387
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-WNFMRRQP.js");
6349
6388
  const orch = getOrchestrator2();
6350
6389
  return {
6351
6390
  findThread: (id) => findThreadByRef(id),
@@ -6459,6 +6498,11 @@ function isPidAlive(pid) {
6459
6498
  return false;
6460
6499
  }
6461
6500
  }
6501
+ function sameLoginList(a, b) {
6502
+ const left = [...a ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
6503
+ const right = [...b ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
6504
+ return left.length === right.length && left.every((login, i) => login === right[i]);
6505
+ }
6462
6506
  async function waitForPidExit(pid, timeoutMs) {
6463
6507
  const start = Date.now();
6464
6508
  while (isPidAlive(pid)) {
@@ -8108,6 +8152,14 @@ var Orchestrator = class {
8108
8152
  if (nextState && nextState !== prevState) patch.prState = nextState;
8109
8153
  const nextDraft = Boolean(meta.isDraft) && nextState !== "MERGED" && nextState !== "CLOSED";
8110
8154
  if (nextDraft !== Boolean(thread.prIsDraft)) patch.prIsDraft = nextDraft;
8155
+ const nextAuthor = meta.authorLogin?.trim() || "";
8156
+ if (nextAuthor && nextAuthor !== (thread.prAuthorLogin ?? "").trim()) {
8157
+ patch.prAuthorLogin = nextAuthor;
8158
+ }
8159
+ const nextReviewers = meta.reviewerLogins ?? [];
8160
+ if (!sameLoginList(nextReviewers, thread.prReviewerLogins)) {
8161
+ patch.prReviewerLogins = nextReviewers;
8162
+ }
8111
8163
  if (thread.skipAutoArchiveOnMerge && nextState && nextState !== "MERGED" && nextState !== "CLOSED") {
8112
8164
  patch.skipAutoArchiveOnMerge = false;
8113
8165
  }
@@ -8135,6 +8187,14 @@ var Orchestrator = class {
8135
8187
  const sibPatch = { prState: "MERGED", prIsDraft: false };
8136
8188
  if (meta.url && meta.url !== t.prUrl) sibPatch.prUrl = meta.url;
8137
8189
  if (meta.title && meta.title !== t.prTitle) sibPatch.prTitle = meta.title;
8190
+ const sibAuthor = meta.authorLogin?.trim() || "";
8191
+ if (sibAuthor && sibAuthor !== (t.prAuthorLogin ?? "").trim()) {
8192
+ sibPatch.prAuthorLogin = sibAuthor;
8193
+ }
8194
+ const sibReviewers = meta.reviewerLogins ?? [];
8195
+ if (!sameLoginList(sibReviewers, t.prReviewerLogins)) {
8196
+ sibPatch.prReviewerLogins = sibReviewers;
8197
+ }
8138
8198
  if (Object.keys(sibPatch).length > 0) updateThread(t.id, sibPatch);
8139
8199
  }
8140
8200
  for (const t of siblings) {
@@ -8435,7 +8495,7 @@ var Orchestrator = class {
8435
8495
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
8436
8496
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
8437
8497
  try {
8438
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-DR4UNOQC.js");
8498
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-YVZYX5H2.js");
8439
8499
  await ensureWorkspace2(thread.repoPath);
8440
8500
  } catch {
8441
8501
  }
@@ -8489,7 +8549,7 @@ var Orchestrator = class {
8489
8549
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
8490
8550
  );
8491
8551
  }
8492
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-LC4VRWDM.js");
8552
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-7LOSSD7G.js");
8493
8553
  const slug = thread.worktreePath.split("/").pop();
8494
8554
  const dest = thread.worktreePath;
8495
8555
  await withRepoGitLock(thread.repoPath, async () => {
@@ -8599,7 +8659,7 @@ async function startOrchestration(opts) {
8599
8659
  sourceRef: "default",
8600
8660
  ...createOpts
8601
8661
  }).catch(async () => {
8602
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-LC4VRWDM.js");
8662
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-7LOSSD7G.js");
8603
8663
  const repo = await resolveRepoRoot2(repoPath);
8604
8664
  const def = await resolveDefaultBranch2(repo);
8605
8665
  return orch.createThread({
@@ -8609,7 +8669,7 @@ async function startOrchestration(opts) {
8609
8669
  repoPath: repo
8610
8670
  });
8611
8671
  });
8612
- const { updateThread: upd } = await import("./thread-store-MVQU6HPJ.js");
8672
+ const { updateThread: upd } = await import("./thread-store-ZL6GDIDP.js");
8613
8673
  const updated = upd(thread.id, {
8614
8674
  sourceType: "orchestration",
8615
8675
  sourceRef: goal
@@ -73,6 +73,8 @@ function createEmptyThread(partial) {
73
73
  prTitle: partial.prTitle ?? null,
74
74
  prState: partial.prState ?? null,
75
75
  prIsDraft: Boolean(partial.prIsDraft),
76
+ prAuthorLogin: partial.prAuthorLogin?.trim() || null,
77
+ prReviewerLogins: partial.prReviewerLogins ?? [],
76
78
  skipAutoArchiveOnMerge: partial.skipAutoArchiveOnMerge ?? false,
77
79
  cowboy: Boolean(partial.cowboy),
78
80
  stackId: partial.stackId ?? null,
@@ -11,13 +11,13 @@ import {
11
11
  } from "./chunk-Y4MIXGPA.js";
12
12
  import {
13
13
  isOrchestratorThread
14
- } from "./chunk-FJWQCZ74.js";
14
+ } from "./chunk-XV3EFFZ6.js";
15
15
  import {
16
16
  codexUnattendedGitConfigArgs,
17
17
  mergeAgentGitAuthEnv,
18
18
  resolveAgentGitAuthEnv,
19
19
  resolveCodexGitWritableRoots
20
- } from "./chunk-7O53GXTA.js";
20
+ } from "./chunk-XBLN52RZ.js";
21
21
  import {
22
22
  enrichPathWithNpmGlobalBin,
23
23
  isConductorBundledCli,
@@ -2342,7 +2342,7 @@ var claudeAdapter = {
2342
2342
  );
2343
2343
  }
2344
2344
  const mode = permissionMode(thread);
2345
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-J737XNUX.js");
2345
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-C2JMJXYV.js");
2346
2346
  const isOrchestrator = isOrchestratorThread2(thread);
2347
2347
  const injectedServers = await buildInjectedMcpServers({
2348
2348
  includeSideboard: true,