@sideboard-ai/core 0.1.177 → 0.1.178

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
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-J7LQVLFQ.js";
8
8
  import {
9
9
  listThreads
10
- } from "./chunk-7UURXPKD.js";
10
+ } from "./chunk-TCQAFTSV.js";
11
11
  import {
12
12
  worktreesRoot
13
13
  } from "./chunk-EFVFB2AH.js";
@@ -2117,7 +2117,7 @@ async function getPr(repoPath, number) {
2117
2117
  "view",
2118
2118
  String(number),
2119
2119
  "--json",
2120
- "number,title,headRefName,url,isCrossRepository"
2120
+ "number,title,headRefName,url,isCrossRepository,author"
2121
2121
  ];
2122
2122
  if (slug) args.push("--repo", slug);
2123
2123
  const { stdout, exitCode } = await gh(args, repoPath, { reject: false });
@@ -2163,7 +2163,7 @@ async function getPrForHeadBranch(repoPath, branch) {
2163
2163
  "view",
2164
2164
  head,
2165
2165
  "--json",
2166
- "number,title,headRefName,url,isCrossRepository"
2166
+ "number,title,headRefName,url,isCrossRepository,author"
2167
2167
  ];
2168
2168
  if (slug) viewArgs.push("--repo", slug);
2169
2169
  const viewed = await gh(viewArgs, repoPath, { reject: false });
@@ -2181,7 +2181,7 @@ async function getPrForHeadBranch(repoPath, branch) {
2181
2181
  "--head",
2182
2182
  listHead,
2183
2183
  "--json",
2184
- "number,title,headRefName,url,isCrossRepository",
2184
+ "number,title,headRefName,url,isCrossRepository,author",
2185
2185
  "--limit",
2186
2186
  "1",
2187
2187
  "--state",
@@ -2383,7 +2383,7 @@ async function getPrMeta(cwd, selector) {
2383
2383
  "view",
2384
2384
  selector,
2385
2385
  "--json",
2386
- "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,isInMergeQueue,mergeStateStatus,mergeable"
2386
+ "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,isInMergeQueue,mergeStateStatus,mergeable,author,reviewRequests"
2387
2387
  ];
2388
2388
  if (slug) viewArgs.push("--repo", slug);
2389
2389
  let { stdout, exitCode, stderr } = await gh(viewArgs, cwd, { reject: false });
@@ -2393,7 +2393,7 @@ async function getPrMeta(cwd, selector) {
2393
2393
  "view",
2394
2394
  selector,
2395
2395
  "--json",
2396
- "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,mergeStateStatus,mergeable"
2396
+ "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,mergeStateStatus,mergeable,author,reviewRequests"
2397
2397
  ];
2398
2398
  if (slug) retry.push("--repo", slug);
2399
2399
  ({ stdout, exitCode, stderr } = await gh(retry, cwd, { reject: false }));
@@ -2414,6 +2414,7 @@ async function getPrMeta(cwd, selector) {
2414
2414
  };
2415
2415
  const probed = await probeLocalMergeGate(cwd, gate);
2416
2416
  const resolved = probed.gate ?? gate;
2417
+ const author = view.author ?? {};
2417
2418
  return {
2418
2419
  number: Number(view.number),
2419
2420
  title: String(view.title ?? ""),
@@ -2425,7 +2426,9 @@ async function getPrMeta(cwd, selector) {
2425
2426
  headRefName: String(view.headRefName ?? ""),
2426
2427
  isInMergeQueue: Boolean(resolved.isInMergeQueue),
2427
2428
  mergeable: resolved.mergeable,
2428
- mergeStateStatus: resolved.mergeStateStatus
2429
+ mergeStateStatus: resolved.mergeStateStatus,
2430
+ authorLogin: author.login?.trim() || null,
2431
+ reviewerLogins: humanReviewerLogins(view.reviewRequests)
2429
2432
  };
2430
2433
  } catch {
2431
2434
  return null;
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-D6JWYJ4P.js";
6
6
  import {
7
7
  listThreads
8
- } from "./chunk-LZQULFIT.js";
8
+ } from "./chunk-GOZ6T3AG.js";
9
9
  import {
10
10
  ensureWorktreeSideboardIgnored
11
11
  } from "./chunk-SYFVUF2C.js";
@@ -2080,7 +2080,7 @@ async function getPr(repoPath, number) {
2080
2080
  "view",
2081
2081
  String(number),
2082
2082
  "--json",
2083
- "number,title,headRefName,url,isCrossRepository"
2083
+ "number,title,headRefName,url,isCrossRepository,author"
2084
2084
  ];
2085
2085
  if (slug) args.push("--repo", slug);
2086
2086
  const { stdout, exitCode } = await gh(args, repoPath, { reject: false });
@@ -2126,7 +2126,7 @@ async function getPrForHeadBranch(repoPath, branch) {
2126
2126
  "view",
2127
2127
  head,
2128
2128
  "--json",
2129
- "number,title,headRefName,url,isCrossRepository"
2129
+ "number,title,headRefName,url,isCrossRepository,author"
2130
2130
  ];
2131
2131
  if (slug) viewArgs.push("--repo", slug);
2132
2132
  const viewed = await gh(viewArgs, repoPath, { reject: false });
@@ -2144,7 +2144,7 @@ async function getPrForHeadBranch(repoPath, branch) {
2144
2144
  "--head",
2145
2145
  listHead,
2146
2146
  "--json",
2147
- "number,title,headRefName,url,isCrossRepository",
2147
+ "number,title,headRefName,url,isCrossRepository,author",
2148
2148
  "--limit",
2149
2149
  "1",
2150
2150
  "--state",
@@ -2346,7 +2346,7 @@ async function getPrMeta(cwd, selector) {
2346
2346
  "view",
2347
2347
  selector,
2348
2348
  "--json",
2349
- "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,isInMergeQueue,mergeStateStatus,mergeable"
2349
+ "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,isInMergeQueue,mergeStateStatus,mergeable,author,reviewRequests"
2350
2350
  ];
2351
2351
  if (slug) viewArgs.push("--repo", slug);
2352
2352
  let { stdout, exitCode, stderr } = await gh(viewArgs, cwd, { reject: false });
@@ -2356,7 +2356,7 @@ async function getPrMeta(cwd, selector) {
2356
2356
  "view",
2357
2357
  selector,
2358
2358
  "--json",
2359
- "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,mergeStateStatus,mergeable"
2359
+ "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,mergeStateStatus,mergeable,author,reviewRequests"
2360
2360
  ];
2361
2361
  if (slug) retry.push("--repo", slug);
2362
2362
  ({ stdout, exitCode, stderr } = await gh(retry, cwd, { reject: false }));
@@ -2377,6 +2377,7 @@ async function getPrMeta(cwd, selector) {
2377
2377
  };
2378
2378
  const probed = await probeLocalMergeGate(cwd, gate);
2379
2379
  const resolved = probed.gate ?? gate;
2380
+ const author = view.author ?? {};
2380
2381
  return {
2381
2382
  number: Number(view.number),
2382
2383
  title: String(view.title ?? ""),
@@ -2388,7 +2389,9 @@ async function getPrMeta(cwd, selector) {
2388
2389
  headRefName: String(view.headRefName ?? ""),
2389
2390
  isInMergeQueue: Boolean(resolved.isInMergeQueue),
2390
2391
  mergeable: resolved.mergeable,
2391
- mergeStateStatus: resolved.mergeStateStatus
2392
+ mergeStateStatus: resolved.mergeStateStatus,
2393
+ authorLogin: author.login?.trim() || null,
2394
+ reviewerLogins: humanReviewerLogins(view.reviewRequests)
2392
2395
  };
2393
2396
  } catch {
2394
2397
  return null;
@@ -7,7 +7,7 @@ import {
7
7
  resolveRepoRoot,
8
8
  takenSlugsFromThread,
9
9
  teamSlugFromName
10
- } from "./chunk-7O53GXTA.js";
10
+ } from "./chunk-XBLN52RZ.js";
11
11
  import {
12
12
  ATTACHMENTS_DIR,
13
13
  attachmentsGitignoreBody
@@ -17,7 +17,7 @@ import {
17
17
  listThreads,
18
18
  updateThread,
19
19
  writeThread
20
- } from "./chunk-LZQULFIT.js";
20
+ } from "./chunk-GOZ6T3AG.js";
21
21
  import {
22
22
  assertOrchestratorCapableAgent,
23
23
  formatAccountProfilePlaybookLine,
@@ -7,13 +7,13 @@ import {
7
7
  enrichWorkspacesWithGithub,
8
8
  ensureGlobalCoordinatorCwd,
9
9
  formatWorkspaceInventory
10
- } from "./chunk-3ZFGZ7RT.js";
11
- import "./chunk-7JIYKYLL.js";
10
+ } from "./chunk-7T5XKNOF.js";
11
+ import "./chunk-WXKXSZN4.js";
12
12
  import "./chunk-6K64FJDD.js";
13
13
  import "./chunk-J7LQVLFQ.js";
14
14
  import "./chunk-4TR3HZFT.js";
15
15
  import "./chunk-JT7R45JB.js";
16
- import "./chunk-7UURXPKD.js";
16
+ import "./chunk-TCQAFTSV.js";
17
17
  import "./chunk-77WWLBCI.js";
18
18
  import "./chunk-EFVFB2AH.js";
19
19
  import "./chunk-QQKDGPUI.js";
@@ -9,10 +9,10 @@ import {
9
9
  enrichWorkspacesWithGithub,
10
10
  ensureGlobalCoordinatorCwd,
11
11
  formatWorkspaceInventory
12
- } from "./chunk-FJWQCZ74.js";
13
- import "./chunk-7O53GXTA.js";
12
+ } from "./chunk-XV3EFFZ6.js";
13
+ import "./chunk-XBLN52RZ.js";
14
14
  import "./chunk-D6JWYJ4P.js";
15
- import "./chunk-LZQULFIT.js";
15
+ import "./chunk-GOZ6T3AG.js";
16
16
  import "./chunk-SYFVUF2C.js";
17
17
  import "./chunk-FNQNJOHY.js";
18
18
  import "./chunk-OKZFTOM2.js";
@@ -15,13 +15,13 @@ import {
15
15
  orchestratorSessionPoisonedByBuiltins,
16
16
  slackCoordinatorSourceRef,
17
17
  takenTeamSlugsForOrchestration
18
- } from "./chunk-3ZFGZ7RT.js";
19
- import "./chunk-7JIYKYLL.js";
18
+ } from "./chunk-7T5XKNOF.js";
19
+ import "./chunk-WXKXSZN4.js";
20
20
  import "./chunk-6K64FJDD.js";
21
21
  import "./chunk-J7LQVLFQ.js";
22
22
  import "./chunk-4TR3HZFT.js";
23
23
  import "./chunk-JT7R45JB.js";
24
- import "./chunk-7UURXPKD.js";
24
+ import "./chunk-TCQAFTSV.js";
25
25
  import "./chunk-77WWLBCI.js";
26
26
  import {
27
27
  globalAgentCwd
@@ -17,10 +17,10 @@ import {
17
17
  orchestratorSessionPoisonedByBuiltins,
18
18
  slackCoordinatorSourceRef,
19
19
  takenTeamSlugsForOrchestration
20
- } from "./chunk-FJWQCZ74.js";
21
- import "./chunk-7O53GXTA.js";
20
+ } from "./chunk-XV3EFFZ6.js";
21
+ import "./chunk-XBLN52RZ.js";
22
22
  import "./chunk-D6JWYJ4P.js";
23
- import "./chunk-LZQULFIT.js";
23
+ import "./chunk-GOZ6T3AG.js";
24
24
  import "./chunk-SYFVUF2C.js";
25
25
  import "./chunk-FNQNJOHY.js";
26
26
  import "./chunk-OKZFTOM2.js";
package/dist/index.cjs CHANGED
@@ -2745,6 +2745,8 @@ function createEmptyThread(partial) {
2745
2745
  prTitle: partial.prTitle ?? null,
2746
2746
  prState: partial.prState ?? null,
2747
2747
  prIsDraft: Boolean(partial.prIsDraft),
2748
+ prAuthorLogin: partial.prAuthorLogin?.trim() || null,
2749
+ prReviewerLogins: partial.prReviewerLogins ?? [],
2748
2750
  skipAutoArchiveOnMerge: partial.skipAutoArchiveOnMerge ?? false,
2749
2751
  cowboy: Boolean(partial.cowboy),
2750
2752
  stackId: partial.stackId ?? null,
@@ -6269,7 +6271,7 @@ async function getPr(repoPath, number) {
6269
6271
  "view",
6270
6272
  String(number),
6271
6273
  "--json",
6272
- "number,title,headRefName,url,isCrossRepository"
6274
+ "number,title,headRefName,url,isCrossRepository,author"
6273
6275
  ];
6274
6276
  if (slug) args.push("--repo", slug);
6275
6277
  const { stdout, exitCode } = await gh(args, repoPath, { reject: false });
@@ -6315,7 +6317,7 @@ async function getPrForHeadBranch(repoPath, branch) {
6315
6317
  "view",
6316
6318
  head,
6317
6319
  "--json",
6318
- "number,title,headRefName,url,isCrossRepository"
6320
+ "number,title,headRefName,url,isCrossRepository,author"
6319
6321
  ];
6320
6322
  if (slug) viewArgs.push("--repo", slug);
6321
6323
  const viewed = await gh(viewArgs, repoPath, { reject: false });
@@ -6333,7 +6335,7 @@ async function getPrForHeadBranch(repoPath, branch) {
6333
6335
  "--head",
6334
6336
  listHead,
6335
6337
  "--json",
6336
- "number,title,headRefName,url,isCrossRepository",
6338
+ "number,title,headRefName,url,isCrossRepository,author",
6337
6339
  "--limit",
6338
6340
  "1",
6339
6341
  "--state",
@@ -6535,7 +6537,7 @@ async function getPrMeta(cwd, selector) {
6535
6537
  "view",
6536
6538
  selector,
6537
6539
  "--json",
6538
- "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,isInMergeQueue,mergeStateStatus,mergeable"
6540
+ "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,isInMergeQueue,mergeStateStatus,mergeable,author,reviewRequests"
6539
6541
  ];
6540
6542
  if (slug) viewArgs.push("--repo", slug);
6541
6543
  let { stdout, exitCode, stderr } = await gh(viewArgs, cwd, { reject: false });
@@ -6545,7 +6547,7 @@ async function getPrMeta(cwd, selector) {
6545
6547
  "view",
6546
6548
  selector,
6547
6549
  "--json",
6548
- "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,mergeStateStatus,mergeable"
6550
+ "number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,mergeStateStatus,mergeable,author,reviewRequests"
6549
6551
  ];
6550
6552
  if (slug) retry.push("--repo", slug);
6551
6553
  ({ stdout, exitCode, stderr } = await gh(retry, cwd, { reject: false }));
@@ -6566,6 +6568,7 @@ async function getPrMeta(cwd, selector) {
6566
6568
  };
6567
6569
  const probed = await probeLocalMergeGate(cwd, gate);
6568
6570
  const resolved = probed.gate ?? gate;
6571
+ const author = view.author ?? {};
6569
6572
  return {
6570
6573
  number: Number(view.number),
6571
6574
  title: String(view.title ?? ""),
@@ -6577,7 +6580,9 @@ async function getPrMeta(cwd, selector) {
6577
6580
  headRefName: String(view.headRefName ?? ""),
6578
6581
  isInMergeQueue: Boolean(resolved.isInMergeQueue),
6579
6582
  mergeable: resolved.mergeable,
6580
- mergeStateStatus: resolved.mergeStateStatus
6583
+ mergeStateStatus: resolved.mergeStateStatus,
6584
+ authorLogin: author.login?.trim() || null,
6585
+ reviewerLogins: humanReviewerLogins(view.reviewRequests)
6581
6586
  };
6582
6587
  } catch {
6583
6588
  return null;
@@ -14789,6 +14794,8 @@ function worktreeBindingFrom(from) {
14789
14794
  prTitle: from.prTitle,
14790
14795
  prState: from.prState,
14791
14796
  prIsDraft: from.prIsDraft,
14797
+ prAuthorLogin: from.prAuthorLogin,
14798
+ prReviewerLogins: from.prReviewerLogins,
14792
14799
  skipAutoArchiveOnMerge: from.skipAutoArchiveOnMerge,
14793
14800
  stackId: from.stackId,
14794
14801
  stackLayer: from.stackLayer,
@@ -16313,6 +16320,35 @@ function groupHomeBoardWorktrees(threads, sort = DEFAULT_WORKTREE_SORT, labelOf
16313
16320
  }
16314
16321
  return [...map.values()].map((list) => sortThreadsInWorktree(list)).sort((a, b) => compareWorktreeGroups(a, b, sort, labelOf));
16315
16322
  }
16323
+ function normalizeViewerLogin(login) {
16324
+ return (login ?? "").trim().toLowerCase();
16325
+ }
16326
+ function loginsInclude(logins, viewerLogin) {
16327
+ const me = normalizeViewerLogin(viewerLogin);
16328
+ if (!me) return false;
16329
+ return (logins ?? []).some((login) => normalizeViewerLogin(login) === me);
16330
+ }
16331
+ function classifyWorktreeOwnership(group, viewerLogin = "") {
16332
+ const me = normalizeViewerLogin(viewerLogin);
16333
+ if (group.some((t) => {
16334
+ const author = normalizeViewerLogin(t.prAuthorLogin);
16335
+ return Boolean(author && me && author === me);
16336
+ })) {
16337
+ return "mine";
16338
+ }
16339
+ const reviewing = group.some((t) => {
16340
+ const author = normalizeViewerLogin(t.prAuthorLogin);
16341
+ if (author && me && author !== me) return true;
16342
+ if (t.sourceType === "pr" && (!author || !me || author !== me)) return true;
16343
+ if (me && loginsInclude(t.prReviewerLogins, me)) return true;
16344
+ return false;
16345
+ });
16346
+ return reviewing ? "reviewing" : "mine";
16347
+ }
16348
+ function worktreeMatchesOwnership(group, filter, viewerLogin = "") {
16349
+ if (filter === "all") return true;
16350
+ return classifyWorktreeOwnership(group, viewerLogin) === filter;
16351
+ }
16316
16352
  function classifyWorktreeColumn(group) {
16317
16353
  if (group.some((t) => isMergedPrState(t.prUrl, t.prState))) return "done";
16318
16354
  if (group.some((t) => isOpenPrState(t.prUrl, t.prState) && !t.prIsDraft)) {
@@ -16668,6 +16704,8 @@ function assembleHomeBoard(input) {
16668
16704
  const tokens = tokenizeQuery(input.query ?? "");
16669
16705
  const repo = input.repoPath?.trim() ?? "";
16670
16706
  const kind = input.kind ?? "all";
16707
+ const ownership = input.ownership ?? DEFAULT_BOARD_OWNERSHIP;
16708
+ const viewerLogin = input.viewerLogin ?? "";
16671
16709
  const limit = Math.max(1, input.limit ?? BOARD_PAGE_SIZE);
16672
16710
  const wsName = input.workspaceName ?? (() => "");
16673
16711
  const live = input.threads.filter((t) => t.status !== "archived" && isHomeBoardThread(t));
@@ -16696,6 +16734,7 @@ function assembleHomeBoard(input) {
16696
16734
  };
16697
16735
  for (const group of groupHomeBoardWorktrees(live)) {
16698
16736
  if (!group.some((t) => threadMatchesKind(t, kind))) continue;
16737
+ if (!worktreeMatchesOwnership(group, ownership, viewerLogin)) continue;
16699
16738
  const col = classifyWorktreeColumn(group);
16700
16739
  if (col === "backlog") continue;
16701
16740
  const primary = group[0];
@@ -16725,7 +16764,7 @@ function assembleHomeBoard(input) {
16725
16764
  }
16726
16765
  return { columns, hidden, totals };
16727
16766
  }
16728
- var GLOBAL_WORKSPACE_ID2, BOARD_COLUMN_DEFS, HOME_BOARD_CACHE_TTL_MS, DEFAULT_WORKTREE_SORT, DEFAULTISH_BRANCH, BOARD_PAGE_SIZE, HOME_BOARD_AGENT_HINT;
16767
+ var GLOBAL_WORKSPACE_ID2, BOARD_COLUMN_DEFS, HOME_BOARD_CACHE_TTL_MS, DEFAULT_WORKTREE_SORT, DEFAULT_BOARD_OWNERSHIP, DEFAULTISH_BRANCH, BOARD_PAGE_SIZE, HOME_BOARD_AGENT_HINT;
16729
16768
  var init_home_board = __esm({
16730
16769
  "src/board/home-board.ts"() {
16731
16770
  "use strict";
@@ -16740,9 +16779,10 @@ var init_home_board = __esm({
16740
16779
  ];
16741
16780
  HOME_BOARD_CACHE_TTL_MS = 15 * 60 * 1e3;
16742
16781
  DEFAULT_WORKTREE_SORT = "created";
16782
+ DEFAULT_BOARD_OWNERSHIP = "all";
16743
16783
  DEFAULTISH_BRANCH = /^(main|master|develop|development|trunk|default|head)$/;
16744
16784
  BOARD_PAGE_SIZE = 40;
16745
- 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.";
16785
+ 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.";
16746
16786
  }
16747
16787
  });
16748
16788
 
@@ -17429,6 +17469,7 @@ async function createThread(input, _onSetupLine) {
17429
17469
  }
17430
17470
  let prUrl = null;
17431
17471
  let prTitle = null;
17472
+ let prAuthorLogin2 = null;
17432
17473
  if (sourceType === "pr") {
17433
17474
  const num2 = Number(input.sourceRef.replace(/^#/, ""));
17434
17475
  if (!Number.isFinite(num2)) throw new Error(`Invalid PR number: ${input.sourceRef}`);
@@ -17444,6 +17485,7 @@ async function createThread(input, _onSetupLine) {
17444
17485
  if (reusedPr) return reusedPr;
17445
17486
  sourceIsFork = pr.isCrossRepository;
17446
17487
  prUrl = pr.url;
17488
+ prAuthorLogin2 = pr.author?.login?.trim() || null;
17447
17489
  const localFetchBranch = `sideboard-pr-${pr.number}`;
17448
17490
  await fetchPrHead(repoPath, pr.number, localFetchBranch);
17449
17491
  sourceRef = localFetchBranch;
@@ -17466,6 +17508,7 @@ async function createThread(input, _onSetupLine) {
17466
17508
  if (existing.url) {
17467
17509
  prUrl = existing.url;
17468
17510
  prTitle = existing.title;
17511
+ prAuthorLogin2 = existing.author?.login?.trim() || null;
17469
17512
  }
17470
17513
  }
17471
17514
  }
@@ -17500,7 +17543,8 @@ async function createThread(input, _onSetupLine) {
17500
17543
  parentThreadId: input.parentThreadId ?? null,
17501
17544
  status: "idle",
17502
17545
  prUrl,
17503
- prTitle
17546
+ prTitle,
17547
+ prAuthorLogin: prAuthorLogin2
17504
17548
  });
17505
17549
  writeThread(thread);
17506
17550
  await ensureWorkspace(repoPath);
@@ -20552,6 +20596,11 @@ function isPidAlive(pid) {
20552
20596
  return false;
20553
20597
  }
20554
20598
  }
20599
+ function sameLoginList(a, b) {
20600
+ const left = [...a ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
20601
+ const right = [...b ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
20602
+ return left.length === right.length && left.every((login, i) => login === right[i]);
20603
+ }
20555
20604
  async function waitForPidExit(pid, timeoutMs) {
20556
20605
  const start = Date.now();
20557
20606
  while (isPidAlive(pid)) {
@@ -22328,6 +22377,14 @@ var init_orchestrator = __esm({
22328
22377
  if (nextState && nextState !== prevState) patch.prState = nextState;
22329
22378
  const nextDraft = Boolean(meta.isDraft) && nextState !== "MERGED" && nextState !== "CLOSED";
22330
22379
  if (nextDraft !== Boolean(thread.prIsDraft)) patch.prIsDraft = nextDraft;
22380
+ const nextAuthor = meta.authorLogin?.trim() || "";
22381
+ if (nextAuthor && nextAuthor !== (thread.prAuthorLogin ?? "").trim()) {
22382
+ patch.prAuthorLogin = nextAuthor;
22383
+ }
22384
+ const nextReviewers = meta.reviewerLogins ?? [];
22385
+ if (!sameLoginList(nextReviewers, thread.prReviewerLogins)) {
22386
+ patch.prReviewerLogins = nextReviewers;
22387
+ }
22331
22388
  if (thread.skipAutoArchiveOnMerge && nextState && nextState !== "MERGED" && nextState !== "CLOSED") {
22332
22389
  patch.skipAutoArchiveOnMerge = false;
22333
22390
  }
@@ -22355,6 +22412,14 @@ var init_orchestrator = __esm({
22355
22412
  const sibPatch = { prState: "MERGED", prIsDraft: false };
22356
22413
  if (meta.url && meta.url !== t.prUrl) sibPatch.prUrl = meta.url;
22357
22414
  if (meta.title && meta.title !== t.prTitle) sibPatch.prTitle = meta.title;
22415
+ const sibAuthor = meta.authorLogin?.trim() || "";
22416
+ if (sibAuthor && sibAuthor !== (t.prAuthorLogin ?? "").trim()) {
22417
+ sibPatch.prAuthorLogin = sibAuthor;
22418
+ }
22419
+ const sibReviewers = meta.reviewerLogins ?? [];
22420
+ if (!sameLoginList(sibReviewers, t.prReviewerLogins)) {
22421
+ sibPatch.prReviewerLogins = sibReviewers;
22422
+ }
22358
22423
  if (Object.keys(sibPatch).length > 0) updateThread(t.id, sibPatch);
22359
22424
  }
22360
22425
  for (const t of siblings) {
@@ -27436,25 +27501,31 @@ async function startMcpServer() {
27436
27501
  );
27437
27502
  server.tool(
27438
27503
  "list_board",
27439
- "Home Kanban of worktrees (New, Draft, Review, Merged) \u2014 one card per checkout; sibling chat tabs nest as inner cards. Same cards as desktop Home. Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind (ticket/PR/branch source), column, limit (default 40). create_thread adds a worktree (and a Home card), or returns the live one if that ticket/PR/named branch is already checked out.",
27504
+ "Home Kanban of worktrees (New, Draft, Review, Merged) \u2014 one card per checkout; sibling chat tabs nest as inner cards. Same cards as desktop Home. Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind (ticket/PR/branch source), ownership (mine = your PRs / WIP; reviewing = someone else's PR), column, limit (default 40). create_thread adds a worktree (and a Home card), or returns the live one if that ticket/PR/named branch is already checked out.",
27440
27505
  {
27441
27506
  query: import_zod8.z.string().optional().describe("Case-insensitive token search across title, id, labels, repo"),
27442
27507
  repoPath: import_zod8.z.string().optional().describe("Limit to one workspace path from list_workspaces"),
27443
27508
  kind: import_zod8.z.enum(["all", "tickets", "prs", "branches", "threads"]).optional().describe("Filter by worktree source (default all)"),
27509
+ ownership: import_zod8.z.enum(["all", "mine", "reviewing"]).optional().describe(
27510
+ "Mine = PRs you authored or local WIP; reviewing = someone else's PR. Uses the gh login."
27511
+ ),
27444
27512
  column: import_zod8.z.enum(["new", "draft", "review", "done", "needs_you"]).optional().describe(
27445
27513
  "Return cards for this column only (totals still include the rest). needs_you is a legacy alias for new."
27446
27514
  ),
27447
27515
  limit: import_zod8.z.number().int().positive().optional().describe("Max cards per column (default 40). hidden counts the remainder.")
27448
27516
  },
27449
- async ({ query, repoPath, kind, column, limit }) => {
27517
+ async ({ query, repoPath, kind, ownership, column, limit }) => {
27450
27518
  const workspaces = orch.listWorkspaces();
27451
27519
  const all = orch.getThreads(true);
27452
27520
  const names = new Map(workspaces.map((w) => [w.path, w.name]));
27521
+ const github = await getGitHubStatus();
27453
27522
  const snap = assembleHomeBoard({
27454
27523
  threads: all.filter((t) => t.status !== "archived"),
27455
27524
  query,
27456
27525
  repoPath,
27457
27526
  kind: kind ?? "all",
27527
+ ownership: ownership ?? "all",
27528
+ viewerLogin: github.login ?? "",
27458
27529
  column: column === "needs_you" ? "new" : column,
27459
27530
  limit,
27460
27531
  workspaceName: (path2) => names.get(path2) ?? ""
package/dist/index.d.cts CHANGED
@@ -147,6 +147,17 @@ interface Thread {
147
147
  * Draft column; open + not draft → Review. Omitted/false when unknown.
148
148
  */
149
149
  prIsDraft?: boolean;
150
+ /**
151
+ * Cached GitHub PR author login from create-from-PR / `getPrMeta`.
152
+ * Compared to the `gh` viewer login for Board/sidebar Mine vs Reviewing.
153
+ */
154
+ prAuthorLogin?: string | null;
155
+ /**
156
+ * Cached human requested-reviewer logins (bots and team slugs omitted).
157
+ * Used when the author is unknown so a review-requested PR still counts
158
+ * as Reviewing.
159
+ */
160
+ prReviewerLogins?: string[];
150
161
  /**
151
162
  * When true, skip auto-archive if the PR is already MERGED (set on restore
152
163
  * so unarchiving a merged workspace does not immediately re-archive).
@@ -356,6 +367,10 @@ interface PrMeta {
356
367
  mergeable: string | null;
357
368
  /** GitHub `mergeStateStatus` (CLEAN / DIRTY / BEHIND / BLOCKED / …). */
358
369
  mergeStateStatus: string | null;
370
+ /** GitHub author login when fetched with `--json author`. */
371
+ authorLogin?: string | null;
372
+ /** Human requested-reviewer logins (bots and team slugs omitted). */
373
+ reviewerLogins?: string[];
359
374
  }
360
375
  /** One layer in a GitHub PR stack (bottom = position 1). */
361
376
  interface PrStackLayer {
@@ -1360,7 +1375,7 @@ declare function resolveThreadEffort(raw: {
1360
1375
  fast?: unknown;
1361
1376
  }): ThinkingEffort;
1362
1377
  declare function normalizeThread(raw: Thread): Thread;
1363
- declare function createEmptyThread(partial: Omit<Thread, 'id' | 'createdAt' | 'updatedAt' | 'messages' | 'queue' | 'status' | 'devPort' | 'activeRuns' | 'prUrl' | 'prTitle' | 'prState' | 'prIsDraft' | 'skipAutoArchiveOnMerge' | 'stackId' | 'stackLayer' | 'userSetTitle' | 'sessionId' | 'sourceIsFork' | 'parentThreadId' | 'autonomy' | 'model' | 'effort' | 'fast' | 'planMode' | 'attachments'> & Partial<Pick<Thread, 'sessionId' | 'sourceIsFork' | 'parentThreadId' | 'autonomy' | 'model' | 'effort' | 'fast' | 'planMode' | 'messages' | 'queue' | 'status' | 'devPort' | 'activeRuns' | 'prUrl' | 'prTitle' | 'prState' | 'prIsDraft' | 'skipAutoArchiveOnMerge' | 'cowboy' | 'stackId' | 'stackLayer' | 'userSetTitle' | 'attachments'>>): Thread;
1378
+ declare function createEmptyThread(partial: Omit<Thread, 'id' | 'createdAt' | 'updatedAt' | 'messages' | 'queue' | 'status' | 'devPort' | 'activeRuns' | 'prUrl' | 'prTitle' | 'prState' | 'prIsDraft' | 'prAuthorLogin' | 'prReviewerLogins' | 'skipAutoArchiveOnMerge' | 'stackId' | 'stackLayer' | 'userSetTitle' | 'sessionId' | 'sourceIsFork' | 'parentThreadId' | 'autonomy' | 'model' | 'effort' | 'fast' | 'planMode' | 'attachments'> & Partial<Pick<Thread, 'sessionId' | 'sourceIsFork' | 'parentThreadId' | 'autonomy' | 'model' | 'effort' | 'fast' | 'planMode' | 'messages' | 'queue' | 'status' | 'devPort' | 'activeRuns' | 'prUrl' | 'prTitle' | 'prState' | 'prIsDraft' | 'prAuthorLogin' | 'prReviewerLogins' | 'skipAutoArchiveOnMerge' | 'cowboy' | 'stackId' | 'stackLayer' | 'userSetTitle' | 'attachments'>>): Thread;
1364
1379
  declare function withThreadLock<T>(id: string, fn: () => Promise<T>): Promise<T>;
1365
1380
  /** Drop the in-memory thread list (other-process writes, tests, store watcher). */
1366
1381
  declare function invalidateThreadListCache(): void;
package/dist/index.d.ts CHANGED
@@ -147,6 +147,17 @@ interface Thread {
147
147
  * Draft column; open + not draft → Review. Omitted/false when unknown.
148
148
  */
149
149
  prIsDraft?: boolean;
150
+ /**
151
+ * Cached GitHub PR author login from create-from-PR / `getPrMeta`.
152
+ * Compared to the `gh` viewer login for Board/sidebar Mine vs Reviewing.
153
+ */
154
+ prAuthorLogin?: string | null;
155
+ /**
156
+ * Cached human requested-reviewer logins (bots and team slugs omitted).
157
+ * Used when the author is unknown so a review-requested PR still counts
158
+ * as Reviewing.
159
+ */
160
+ prReviewerLogins?: string[];
150
161
  /**
151
162
  * When true, skip auto-archive if the PR is already MERGED (set on restore
152
163
  * so unarchiving a merged workspace does not immediately re-archive).
@@ -356,6 +367,10 @@ interface PrMeta {
356
367
  mergeable: string | null;
357
368
  /** GitHub `mergeStateStatus` (CLEAN / DIRTY / BEHIND / BLOCKED / …). */
358
369
  mergeStateStatus: string | null;
370
+ /** GitHub author login when fetched with `--json author`. */
371
+ authorLogin?: string | null;
372
+ /** Human requested-reviewer logins (bots and team slugs omitted). */
373
+ reviewerLogins?: string[];
359
374
  }
360
375
  /** One layer in a GitHub PR stack (bottom = position 1). */
361
376
  interface PrStackLayer {
@@ -1360,7 +1375,7 @@ declare function resolveThreadEffort(raw: {
1360
1375
  fast?: unknown;
1361
1376
  }): ThinkingEffort;
1362
1377
  declare function normalizeThread(raw: Thread): Thread;
1363
- declare function createEmptyThread(partial: Omit<Thread, 'id' | 'createdAt' | 'updatedAt' | 'messages' | 'queue' | 'status' | 'devPort' | 'activeRuns' | 'prUrl' | 'prTitle' | 'prState' | 'prIsDraft' | 'skipAutoArchiveOnMerge' | 'stackId' | 'stackLayer' | 'userSetTitle' | 'sessionId' | 'sourceIsFork' | 'parentThreadId' | 'autonomy' | 'model' | 'effort' | 'fast' | 'planMode' | 'attachments'> & Partial<Pick<Thread, 'sessionId' | 'sourceIsFork' | 'parentThreadId' | 'autonomy' | 'model' | 'effort' | 'fast' | 'planMode' | 'messages' | 'queue' | 'status' | 'devPort' | 'activeRuns' | 'prUrl' | 'prTitle' | 'prState' | 'prIsDraft' | 'skipAutoArchiveOnMerge' | 'cowboy' | 'stackId' | 'stackLayer' | 'userSetTitle' | 'attachments'>>): Thread;
1378
+ declare function createEmptyThread(partial: Omit<Thread, 'id' | 'createdAt' | 'updatedAt' | 'messages' | 'queue' | 'status' | 'devPort' | 'activeRuns' | 'prUrl' | 'prTitle' | 'prState' | 'prIsDraft' | 'prAuthorLogin' | 'prReviewerLogins' | 'skipAutoArchiveOnMerge' | 'stackId' | 'stackLayer' | 'userSetTitle' | 'sessionId' | 'sourceIsFork' | 'parentThreadId' | 'autonomy' | 'model' | 'effort' | 'fast' | 'planMode' | 'attachments'> & Partial<Pick<Thread, 'sessionId' | 'sourceIsFork' | 'parentThreadId' | 'autonomy' | 'model' | 'effort' | 'fast' | 'planMode' | 'messages' | 'queue' | 'status' | 'devPort' | 'activeRuns' | 'prUrl' | 'prTitle' | 'prState' | 'prIsDraft' | 'prAuthorLogin' | 'prReviewerLogins' | 'skipAutoArchiveOnMerge' | 'cowboy' | 'stackId' | 'stackLayer' | 'userSetTitle' | 'attachments'>>): Thread;
1364
1379
  declare function withThreadLock<T>(id: string, fn: () => Promise<T>): Promise<T>;
1365
1380
  /** Drop the in-memory thread list (other-process writes, tests, store watcher). */
1366
1381
  declare function invalidateThreadListCache(): void;
package/dist/index.js CHANGED
@@ -238,7 +238,7 @@ import {
238
238
  worktreeCleanupSettings,
239
239
  wrapReviewSkillMarkdown,
240
240
  writeWorktreeFile
241
- } from "./chunk-DVYRABZC.js";
241
+ } from "./chunk-GVC4IVF5.js";
242
242
  import {
243
243
  LEGACY_PLAN_FILE_REL,
244
244
  PLAN_FILE_NAME,
@@ -344,7 +344,7 @@ import {
344
344
  withEventParentId,
345
345
  withEventsParentId,
346
346
  writeInjectedMcpConfig
347
- } from "./chunk-NIB6BTC6.js";
347
+ } from "./chunk-IVJFEB3T.js";
348
348
  import {
349
349
  CLOUD_COORDINATOR_BUSY_REPLY,
350
350
  CLOUD_COORDINATOR_STOPPED_REPLY,
@@ -387,7 +387,7 @@ import {
387
387
  stageBuffersAsAttachments,
388
388
  syncWorkspacesFromThreads,
389
389
  takenTeamSlugsForOrchestration
390
- } from "./chunk-3ZFGZ7RT.js";
390
+ } from "./chunk-7T5XKNOF.js";
391
391
  import {
392
392
  FAMOUS_SOCCER_TEAMS,
393
393
  GITHUB_PR_BODY_MAX_CHARS,
@@ -484,7 +484,7 @@ import {
484
484
  worktreeDisplayLabelForGroup,
485
485
  worktreeNameFromPath,
486
486
  worktreeSlugForTicket
487
- } from "./chunk-7JIYKYLL.js";
487
+ } from "./chunk-WXKXSZN4.js";
488
488
  import {
489
489
  ATTACHMENTS_DIR,
490
490
  CLI_DIR,
@@ -675,7 +675,7 @@ import {
675
675
  updateThread,
676
676
  withThreadLock,
677
677
  writeThread
678
- } from "./chunk-7UURXPKD.js";
678
+ } from "./chunk-TCQAFTSV.js";
679
679
  import {
680
680
  THINKING_EFFORTS,
681
681
  isThinkingEffort,
@@ -4354,25 +4354,31 @@ async function startMcpServer() {
4354
4354
  );
4355
4355
  server.tool(
4356
4356
  "list_board",
4357
- "Home Kanban of worktrees (New, Draft, Review, Merged) \u2014 one card per checkout; sibling chat tabs nest as inner cards. Same cards as desktop Home. Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind (ticket/PR/branch source), column, limit (default 40). create_thread adds a worktree (and a Home card), or returns the live one if that ticket/PR/named branch is already checked out.",
4357
+ "Home Kanban of worktrees (New, Draft, Review, Merged) \u2014 one card per checkout; sibling chat tabs nest as inner cards. Same cards as desktop Home. Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind (ticket/PR/branch source), ownership (mine = your PRs / WIP; reviewing = someone else's PR), column, limit (default 40). create_thread adds a worktree (and a Home card), or returns the live one if that ticket/PR/named branch is already checked out.",
4358
4358
  {
4359
4359
  query: z8.string().optional().describe("Case-insensitive token search across title, id, labels, repo"),
4360
4360
  repoPath: z8.string().optional().describe("Limit to one workspace path from list_workspaces"),
4361
4361
  kind: z8.enum(["all", "tickets", "prs", "branches", "threads"]).optional().describe("Filter by worktree source (default all)"),
4362
+ ownership: z8.enum(["all", "mine", "reviewing"]).optional().describe(
4363
+ "Mine = PRs you authored or local WIP; reviewing = someone else's PR. Uses the gh login."
4364
+ ),
4362
4365
  column: z8.enum(["new", "draft", "review", "done", "needs_you"]).optional().describe(
4363
4366
  "Return cards for this column only (totals still include the rest). needs_you is a legacy alias for new."
4364
4367
  ),
4365
4368
  limit: z8.number().int().positive().optional().describe("Max cards per column (default 40). hidden counts the remainder.")
4366
4369
  },
4367
- async ({ query, repoPath, kind, column, limit }) => {
4370
+ async ({ query, repoPath, kind, ownership, column, limit }) => {
4368
4371
  const workspaces = orch.listWorkspaces();
4369
4372
  const all = orch.getThreads(true);
4370
4373
  const names = new Map(workspaces.map((w) => [w.path, w.name]));
4374
+ const github = await getGitHubStatus();
4371
4375
  const snap = assembleHomeBoard({
4372
4376
  threads: all.filter((t) => t.status !== "archived"),
4373
4377
  query,
4374
4378
  repoPath,
4375
4379
  kind: kind ?? "all",
4380
+ ownership: ownership ?? "all",
4381
+ viewerLogin: github.login ?? "",
4376
4382
  column: column === "needs_you" ? "new" : column,
4377
4383
  limit,
4378
4384
  workspaceName: (path2) => names.get(path2) ?? ""