@sideboard-ai/core 0.1.316 → 0.1.318

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 (48) hide show
  1. package/dist/{abletime-NZ2ABWAL.js → abletime-KWOBUL46.js} +4 -4
  2. package/dist/{abletime-oauth-CBFFBINA.js → abletime-oauth-IUIAGLFJ.js} +3 -3
  3. package/dist/{abletime-rest-NSOP72AI.js → abletime-rest-RWN4EPY3.js} +3 -3
  4. package/dist/{agents-Y3M3EKLY.js → agents-2AR7I6B6.js} +6 -6
  5. package/dist/{agents-5XJ7EHGU.js → agents-KABJUDPI.js} +4 -4
  6. package/dist/{app-settings-RQAFJZCD.js → app-settings-V6YPYY57.js} +1 -1
  7. package/dist/{chunk-4ISF5XUA.js → chunk-23ZUL2EX.js} +25 -25
  8. package/dist/{chunk-VVV7EI6T.js → chunk-2HOZMSKQ.js} +2 -2
  9. package/dist/{chunk-ELBK34TY.js → chunk-7ADEYEMH.js} +5 -5
  10. package/dist/{chunk-5CTG5W7S.js → chunk-A46CIARU.js} +1 -1
  11. package/dist/{chunk-PN32Z4JL.js → chunk-A6C67DY5.js} +2 -2
  12. package/dist/{chunk-NXNNYY3Q.js → chunk-AESO2KJS.js} +2 -2
  13. package/dist/{chunk-S3U4HR5F.js → chunk-AZ4GEEGL.js} +2 -2
  14. package/dist/{chunk-7BLIY2DD.js → chunk-BXTISNKW.js} +15 -15
  15. package/dist/{chunk-U7PNCYNX.js → chunk-E52SQENB.js} +1 -0
  16. package/dist/{chunk-OLYNM52B.js → chunk-FDXHNROD.js} +2 -2
  17. package/dist/{chunk-FVTR54LY.js → chunk-GH7UMULC.js} +4 -4
  18. package/dist/{chunk-U35AHE2P.js → chunk-HOLB6ZFZ.js} +33 -2
  19. package/dist/{chunk-NKVNHBDB.js → chunk-IAPO7ZFG.js} +4 -4
  20. package/dist/{chunk-DNWO6PQJ.js → chunk-NRSC4N5X.js} +5 -34
  21. package/dist/{chunk-ATSZXRFQ.js → chunk-ST2UQBJT.js} +6 -35
  22. package/dist/{chunk-BPBDGJ43.js → chunk-TUJFCJJU.js} +2 -2
  23. package/dist/{chunk-GXSV3X3L.js → chunk-W5QZWAUB.js} +3 -3
  24. package/dist/{chunk-CCUGIVYN.js → chunk-XOZNEAWF.js} +3 -3
  25. package/dist/{chunk-GFM63DTU.js → chunk-YALFZKSC.js} +3 -3
  26. package/dist/{chunk-CHUPIJP7.js → chunk-YEIHCSZS.js} +63 -2
  27. package/dist/{conductor-CFLBKVHJ.js → conductor-MG2RAQNT.js} +5 -5
  28. package/dist/{conductor-NZ4V5CJX.js → conductor-NIUBJLTS.js} +4 -4
  29. package/dist/{coordinator-prompt-HUZC4DZ2.js → coordinator-prompt-3CT3D5UM.js} +3 -3
  30. package/dist/{coordinator-prompt-SPOYUZG5.js → coordinator-prompt-X74F3JIC.js} +4 -4
  31. package/dist/{global-workspace-SK4JQBPN.js → global-workspace-BUWMRNW5.js} +3 -3
  32. package/dist/{global-workspace-3NNDDTFD.js → global-workspace-FTNJEML3.js} +4 -4
  33. package/dist/index.cjs +96 -42
  34. package/dist/index.d.cts +2 -0
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +50 -27
  37. package/dist/mcp/run-stdio.cjs +36 -34
  38. package/dist/mcp/run-stdio.js +6 -6
  39. package/dist/{optional-cli-LMSRZNH4.js → optional-cli-6GGESWGE.js} +4 -4
  40. package/dist/{orchestrator-KXEPWTG5.js → orchestrator-2SXK4U65.js} +9 -9
  41. package/dist/{orchestrator-7342RGRU.js → orchestrator-N54V3B76.js} +6 -6
  42. package/dist/{thread-store-5OF6M6VZ.js → thread-store-7BBA63KV.js} +1 -1
  43. package/dist/{thread-store-GOVVXQV2.js → thread-store-PLNIWFZ4.js} +1 -1
  44. package/dist/{workspaces-EYNZDL45.js → workspaces-2V5UYPYC.js} +3 -3
  45. package/dist/{workspaces-52L6NZ3P.js → workspaces-MGKEAYNM.js} +4 -4
  46. package/dist/{worktree-BP5ICYQ2.js → worktree-THAXW5U7.js} +3 -3
  47. package/dist/{worktree-UCOSAI7J.js → worktree-XJKLDYOL.js} +2 -2
  48. package/package.json +1 -1
@@ -15,6 +15,32 @@ import {
15
15
  // src/store/thread-store.ts
16
16
  import { randomUUID } from "crypto";
17
17
 
18
+ // src/review/review-write-gate.ts
19
+ var REVIEW_TAB_TITLE = "Review";
20
+ function hasLiveReviewSibling(thread, siblings = []) {
21
+ const selfId = thread.id;
22
+ return siblings.some(
23
+ (t) => t.id !== selfId && t.status !== "archived" && t.title.trim() === REVIEW_TAB_TITLE
24
+ );
25
+ }
26
+ function isReviewWriteGatedThread(thread, siblings) {
27
+ if (thread.sourceType === "pr" || thread.title.trim() === REVIEW_TAB_TITLE) {
28
+ return true;
29
+ }
30
+ return hasLiveReviewSibling(thread, siblings);
31
+ }
32
+ function formatReviewWriteGateDirective() {
33
+ return [
34
+ "Review writes are public. The PR or ticket author sees GitHub/Linear/AbleTime comments, ticket updates, and submitted reviews immediately \u2014 a draft will confuse them.",
35
+ "Write the recommendation in chat so the user can work through the feedback first. Do not call github_comment, linear_comment, abletime_comment, github_update_issue, linear_update_issue, abletime_update_task, or run `gh pr review` / `gh pr comment`, until they type a next step that asks you to post.",
36
+ "After the review is in chat, stop. Do not call ask_user. The user needs time to read and will type the next steps. If they already asked you to post a specific comment or update in this turn, that is confirmation.",
37
+ "Do not request reviewers, change labels, or assign yourself unless they asked \u2014 those also notify the author."
38
+ ].join("\n");
39
+ }
40
+ function formatReviewWriteGateReminder() {
41
+ return "Review writes: keep the review in chat. Do not ask_user after it \u2014 they read and type next steps. Do not github_comment / linear_comment / *_update_* / `gh pr review` on the PR or ticket until they ask. Authors see those immediately.";
42
+ }
43
+
18
44
  // src/git/team-meta.ts
19
45
  var SOCCER_TEAM_META = {
20
46
  "aalborg": { location: "Aalborg, Denmark", league: "Danish Superliga" },
@@ -875,11 +901,12 @@ function branchDisplayLabel(branchName, worktreePath) {
875
901
  }
876
902
  function taskPurposeTitle(title) {
877
903
  const trimmed = title?.trim() ?? "";
878
- if (!trimmed || teamSlugFromName(trimmed)) return null;
904
+ if (!trimmed || teamSlugFromName(trimmed) || trimmed === REVIEW_TAB_TITLE) return null;
879
905
  return trimmed;
880
906
  }
881
907
  function threadDisplayLabel(thread) {
882
- if (thread.userSetTitle && thread.title?.trim()) return thread.title.trim();
908
+ const titled = thread.title?.trim() ?? "";
909
+ if (thread.userSetTitle && titled && titled !== REVIEW_TAB_TITLE) return titled;
883
910
  if (thread.prTitle?.trim()) return thread.prTitle.trim();
884
911
  if (isPlaceholderBranch(thread.branchName, thread.worktreePath)) {
885
912
  const purpose = taskPurposeTitle(thread.title);
@@ -1285,6 +1312,10 @@ function findThreadByRef(ref) {
1285
1312
  }
1286
1313
 
1287
1314
  export {
1315
+ REVIEW_TAB_TITLE,
1316
+ isReviewWriteGatedThread,
1317
+ formatReviewWriteGateDirective,
1318
+ formatReviewWriteGateReminder,
1288
1319
  FAMOUS_SOCCER_TEAMS,
1289
1320
  lookupSoccerTeam,
1290
1321
  teamSlugFromName,
@@ -12,13 +12,13 @@ import {
12
12
  } from "./chunk-7Q327QF2.js";
13
13
  import {
14
14
  isOrchestratorThread
15
- } from "./chunk-GFM63DTU.js";
15
+ } from "./chunk-YALFZKSC.js";
16
16
  import {
17
17
  codexUnattendedGitConfigArgs,
18
18
  mergeAgentGitAuthEnv,
19
19
  resolveAgentGitAuthEnv,
20
20
  resolveCodexGitWritableRoots
21
- } from "./chunk-BPBDGJ43.js";
21
+ } from "./chunk-TUJFCJJU.js";
22
22
  import {
23
23
  loadBrightsyConfig
24
24
  } from "./chunk-RSA47QYR.js";
@@ -76,7 +76,7 @@ import {
76
76
  loadAppSettings,
77
77
  resolveAgentExecutable,
78
78
  resolveClaudeExecutable
79
- } from "./chunk-U7PNCYNX.js";
79
+ } from "./chunk-E52SQENB.js";
80
80
  import {
81
81
  isElectronLikeCommand,
82
82
  unwrapStrippedElectronLaunch
@@ -2609,7 +2609,7 @@ var claudeAdapter = {
2609
2609
  );
2610
2610
  }
2611
2611
  const mode = permissionMode(thread);
2612
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-3NNDDTFD.js");
2612
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-FTNJEML3.js");
2613
2613
  const isOrchestrator = isOrchestratorThread2(thread);
2614
2614
  const rpc = worktreeAgentRpc(isOrchestrator);
2615
2615
  const injectedServers = await buildInjectedMcpServers({
@@ -11,11 +11,11 @@ import {
11
11
  isGlobalThread,
12
12
  isOrchestratorThread,
13
13
  isSlackCoordinatorThread
14
- } from "./chunk-PN32Z4JL.js";
14
+ } from "./chunk-A6C67DY5.js";
15
15
  import {
16
16
  mergeAgentGitAuthEnv,
17
17
  resolveAgentGitAuthEnv
18
- } from "./chunk-5CTG5W7S.js";
18
+ } from "./chunk-A46CIARU.js";
19
19
  import {
20
20
  ATTACHMENTS_DIR,
21
21
  DETACHED_JOBS_DIR,
@@ -37,6 +37,7 @@ import {
37
37
  stripNestedElectronEnv
38
38
  } from "./chunk-WWUABK6B.js";
39
39
  import {
40
+ REVIEW_TAB_TITLE,
40
41
  allocateTeamName,
41
42
  createEmptyThread,
42
43
  findThreadByRef,
@@ -46,7 +47,7 @@ import {
46
47
  updateThread,
47
48
  worktreeNameFromPath,
48
49
  writeThread
49
- } from "./chunk-U35AHE2P.js";
50
+ } from "./chunk-HOLB6ZFZ.js";
50
51
  import {
51
52
  findConventionSetup,
52
53
  loadRepoSettings,
@@ -762,32 +763,6 @@ function forkChatTab(input) {
762
763
  return tab;
763
764
  }
764
765
 
765
- // src/review/review-write-gate.ts
766
- var REVIEW_TAB_TITLE = "Review";
767
- function hasLiveReviewSibling(thread, siblings = []) {
768
- const selfId = thread.id;
769
- return siblings.some(
770
- (t) => t.id !== selfId && t.status !== "archived" && t.title.trim() === REVIEW_TAB_TITLE
771
- );
772
- }
773
- function isReviewWriteGatedThread(thread, siblings) {
774
- if (thread.sourceType === "pr" || thread.title.trim() === REVIEW_TAB_TITLE) {
775
- return true;
776
- }
777
- return hasLiveReviewSibling(thread, siblings);
778
- }
779
- function formatReviewWriteGateDirective() {
780
- return [
781
- "Review writes are public. The PR or ticket author sees GitHub/Linear/AbleTime comments, ticket updates, and submitted reviews immediately \u2014 a draft will confuse them.",
782
- "Write the recommendation in chat so the user can work through the feedback first. Do not call github_comment, linear_comment, abletime_comment, github_update_issue, linear_update_issue, abletime_update_task, or run `gh pr review` / `gh pr comment`, until they type a next step that asks you to post.",
783
- "After the review is in chat, stop. Do not call ask_user. The user needs time to read and will type the next steps. If they already asked you to post a specific comment or update in this turn, that is confirmation.",
784
- "Do not request reviewers, change labels, or assign yourself unless they asked \u2014 those also notify the author."
785
- ].join("\n");
786
- }
787
- function formatReviewWriteGateReminder() {
788
- return "Review writes: keep the review in chat. Do not ask_user after it \u2014 they read and type next steps. Do not github_comment / linear_comment / *_update_* / `gh pr review` on the PR or ticket until they ask. Authors see those immediately.";
789
- }
790
-
791
766
  // src/review/review-request-template.ts
792
767
  var REVIEW_REQUEST_TEMPLATE = `# Review guidelines:
793
768
 
@@ -1703,7 +1678,7 @@ var PORT_RANGE_SIZE = 10;
1703
1678
  var RECLAIM_RETRY_DELAY_MS = 40;
1704
1679
  var RECLAIM_TRIES = 8;
1705
1680
  async function killReclaimable(ports, worktreePath, signal) {
1706
- const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-NZ4V5CJX.js");
1681
+ const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-NIUBJLTS.js");
1707
1682
  if (worktreePath) killStaleWorktreeListeners2(ports, worktreePath, signal);
1708
1683
  else killListenersOnPorts2(ports);
1709
1684
  }
@@ -2411,10 +2386,6 @@ export {
2411
2386
  buildForkTranscriptAttachment,
2412
2387
  createChatTab,
2413
2388
  forkChatTab,
2414
- REVIEW_TAB_TITLE,
2415
- isReviewWriteGatedThread,
2416
- formatReviewWriteGateDirective,
2417
- formatReviewWriteGateReminder,
2418
2389
  requestReview,
2419
2390
  RUN_PORTS_REL,
2420
2391
  worktreeRunPortsPath,
@@ -8,12 +8,13 @@ import {
8
8
  isGlobalThread,
9
9
  isOrchestratorThread,
10
10
  isSlackCoordinatorThread
11
- } from "./chunk-GFM63DTU.js";
11
+ } from "./chunk-YALFZKSC.js";
12
12
  import {
13
13
  mergeAgentGitAuthEnv,
14
14
  resolveAgentGitAuthEnv
15
- } from "./chunk-BPBDGJ43.js";
15
+ } from "./chunk-TUJFCJJU.js";
16
16
  import {
17
+ REVIEW_TAB_TITLE,
17
18
  allocateTeamName,
18
19
  createEmptyThread,
19
20
  findThreadByRef,
@@ -23,7 +24,7 @@ import {
23
24
  updateThread,
24
25
  worktreeNameFromPath,
25
26
  writeThread
26
- } from "./chunk-CHUPIJP7.js";
27
+ } from "./chunk-YEIHCSZS.js";
27
28
  import {
28
29
  ensureWorktreeSideboardIgnored
29
30
  } from "./chunk-2P4XKWV2.js";
@@ -43,7 +44,7 @@ import {
43
44
  import {
44
45
  assertOrchestratorCapableAgent,
45
46
  contextTokens
46
- } from "./chunk-U7PNCYNX.js";
47
+ } from "./chunk-E52SQENB.js";
47
48
  import {
48
49
  stripNestedElectronEnv
49
50
  } from "./chunk-4TR3HZFT.js";
@@ -787,32 +788,6 @@ function forkChatTab(input) {
787
788
  return tab;
788
789
  }
789
790
 
790
- // src/review/review-write-gate.ts
791
- var REVIEW_TAB_TITLE = "Review";
792
- function hasLiveReviewSibling(thread, siblings = []) {
793
- const selfId = thread.id;
794
- return siblings.some(
795
- (t) => t.id !== selfId && t.status !== "archived" && t.title.trim() === REVIEW_TAB_TITLE
796
- );
797
- }
798
- function isReviewWriteGatedThread(thread, siblings) {
799
- if (thread.sourceType === "pr" || thread.title.trim() === REVIEW_TAB_TITLE) {
800
- return true;
801
- }
802
- return hasLiveReviewSibling(thread, siblings);
803
- }
804
- function formatReviewWriteGateDirective() {
805
- return [
806
- "Review writes are public. The PR or ticket author sees GitHub/Linear/AbleTime comments, ticket updates, and submitted reviews immediately \u2014 a draft will confuse them.",
807
- "Write the recommendation in chat so the user can work through the feedback first. Do not call github_comment, linear_comment, abletime_comment, github_update_issue, linear_update_issue, abletime_update_task, or run `gh pr review` / `gh pr comment`, until they type a next step that asks you to post.",
808
- "After the review is in chat, stop. Do not call ask_user. The user needs time to read and will type the next steps. If they already asked you to post a specific comment or update in this turn, that is confirmation.",
809
- "Do not request reviewers, change labels, or assign yourself unless they asked \u2014 those also notify the author."
810
- ].join("\n");
811
- }
812
- function formatReviewWriteGateReminder() {
813
- return "Review writes: keep the review in chat. Do not ask_user after it \u2014 they read and type next steps. Do not github_comment / linear_comment / *_update_* / `gh pr review` on the PR or ticket until they ask. Authors see those immediately.";
814
- }
815
-
816
791
  // src/review/review-request-template.ts
817
792
  var REVIEW_REQUEST_TEMPLATE = `# Review guidelines:
818
793
 
@@ -1833,7 +1808,7 @@ var PORT_RANGE_SIZE = 10;
1833
1808
  var RECLAIM_RETRY_DELAY_MS = 40;
1834
1809
  var RECLAIM_TRIES = 8;
1835
1810
  async function killReclaimable(ports, worktreePath, signal) {
1836
- const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-CFLBKVHJ.js");
1811
+ const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-MG2RAQNT.js");
1837
1812
  if (worktreePath) killStaleWorktreeListeners2(ports, worktreePath, signal);
1838
1813
  else killListenersOnPorts2(ports);
1839
1814
  }
@@ -2584,10 +2559,6 @@ export {
2584
2559
  buildForkTranscriptAttachment,
2585
2560
  createChatTab,
2586
2561
  forkChatTab,
2587
- REVIEW_TAB_TITLE,
2588
- isReviewWriteGatedThread,
2589
- formatReviewWriteGateDirective,
2590
- formatReviewWriteGateReminder,
2591
2562
  REVIEW_REQUEST_TEMPLATE,
2592
2563
  REVIEW_SKILL_PATH,
2593
2564
  REVIEW_SKILL_NAME,
@@ -4,7 +4,7 @@ import {
4
4
  normalizeTakenSlug,
5
5
  normalizeWorktreePath,
6
6
  takenSlugsFromThread
7
- } from "./chunk-CHUPIJP7.js";
7
+ } from "./chunk-YEIHCSZS.js";
8
8
  import {
9
9
  ensureWorktreeSideboardIgnored
10
10
  } from "./chunk-2P4XKWV2.js";
@@ -24,7 +24,7 @@ import {
24
24
  import {
25
25
  getGithubGitAuthMode,
26
26
  getGithubPat
27
- } from "./chunk-U7PNCYNX.js";
27
+ } from "./chunk-E52SQENB.js";
28
28
  import {
29
29
  worktreesRoot
30
30
  } from "./chunk-H4UEFJRI.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  abletimeRestUrl,
3
3
  textFromAbleTimeDoc
4
- } from "./chunk-VVV7EI6T.js";
4
+ } from "./chunk-2HOZMSKQ.js";
5
5
  import {
6
6
  assertAbleTimeCredential,
7
7
  callAbleTimeTool,
8
8
  normalizeAbleTimeHost,
9
9
  rewriteAbleTimeError
10
- } from "./chunk-ELBK34TY.js";
10
+ } from "./chunk-7ADEYEMH.js";
11
11
  import {
12
12
  httpFetch
13
13
  } from "./chunk-JAT3JFOS.js";
@@ -20,7 +20,7 @@ import {
20
20
  getAbleTimeHost,
21
21
  isAbleTimeConnected,
22
22
  saveAbleTimeConnection
23
- } from "./chunk-U7PNCYNX.js";
23
+ } from "./chunk-E52SQENB.js";
24
24
 
25
25
  // src/integrations/issue-attachments.ts
26
26
  import { existsSync, mkdirSync, writeFileSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DEFAULT_ABLETIME_HOST,
3
3
  normalizeAbleTimeHost
4
- } from "./chunk-ELBK34TY.js";
4
+ } from "./chunk-7ADEYEMH.js";
5
5
  import {
6
6
  httpFetch
7
7
  } from "./chunk-JAT3JFOS.js";
@@ -10,7 +10,7 @@ import {
10
10
  getAbleTimeHost,
11
11
  loadAppSettings,
12
12
  saveAbleTimeConnection
13
- } from "./chunk-U7PNCYNX.js";
13
+ } from "./chunk-E52SQENB.js";
14
14
 
15
15
  // src/integrations/abletime-oauth.ts
16
16
  import { createHash, randomBytes } from "crypto";
@@ -280,7 +280,7 @@ async function startAbleTimeOAuth(opts) {
280
280
  persistAbleTimeTokens(data, { host });
281
281
  const token = data.access_token.trim();
282
282
  try {
283
- const { getAbleTimeOrientation } = await import("./abletime-NZ2ABWAL.js");
283
+ const { getAbleTimeOrientation } = await import("./abletime-KWOBUL46.js");
284
284
  const orientation = await getAbleTimeOrientation({ token, host });
285
285
  return saveAbleTimeConnection({
286
286
  accessToken: token,
@@ -3,7 +3,7 @@ import {
3
3
  ensureGhPreferOrigin,
4
4
  resolveGithubRepoSlug,
5
5
  resolveRepoRoot
6
- } from "./chunk-BPBDGJ43.js";
6
+ } from "./chunk-TUJFCJJU.js";
7
7
  import {
8
8
  allocateTeamName,
9
9
  createEmptyThread,
@@ -12,7 +12,7 @@ import {
12
12
  teamSlugFromName,
13
13
  updateThread,
14
14
  writeThread
15
- } from "./chunk-CHUPIJP7.js";
15
+ } from "./chunk-YEIHCSZS.js";
16
16
  import {
17
17
  ATTACHMENTS_DIR,
18
18
  attachmentsGitignoreBody
@@ -29,7 +29,7 @@ import {
29
29
  resolveThreadDefaults,
30
30
  resolveViewerProfile,
31
31
  resolveViewerProfileForRepo
32
- } from "./chunk-U7PNCYNX.js";
32
+ } from "./chunk-E52SQENB.js";
33
33
  import {
34
34
  appDataDir,
35
35
  globalAgentCwd,
@@ -16,6 +16,32 @@ import {
16
16
  // src/store/thread-store.ts
17
17
  import { randomUUID } from "crypto";
18
18
 
19
+ // src/review/review-write-gate.ts
20
+ var REVIEW_TAB_TITLE = "Review";
21
+ function hasLiveReviewSibling(thread, siblings = []) {
22
+ const selfId = thread.id;
23
+ return siblings.some(
24
+ (t) => t.id !== selfId && t.status !== "archived" && t.title.trim() === REVIEW_TAB_TITLE
25
+ );
26
+ }
27
+ function isReviewWriteGatedThread(thread, siblings) {
28
+ if (thread.sourceType === "pr" || thread.title.trim() === REVIEW_TAB_TITLE) {
29
+ return true;
30
+ }
31
+ return hasLiveReviewSibling(thread, siblings);
32
+ }
33
+ function formatReviewWriteGateDirective() {
34
+ return [
35
+ "Review writes are public. The PR or ticket author sees GitHub/Linear/AbleTime comments, ticket updates, and submitted reviews immediately \u2014 a draft will confuse them.",
36
+ "Write the recommendation in chat so the user can work through the feedback first. Do not call github_comment, linear_comment, abletime_comment, github_update_issue, linear_update_issue, abletime_update_task, or run `gh pr review` / `gh pr comment`, until they type a next step that asks you to post.",
37
+ "After the review is in chat, stop. Do not call ask_user. The user needs time to read and will type the next steps. If they already asked you to post a specific comment or update in this turn, that is confirmation.",
38
+ "Do not request reviewers, change labels, or assign yourself unless they asked \u2014 those also notify the author."
39
+ ].join("\n");
40
+ }
41
+ function formatReviewWriteGateReminder() {
42
+ return "Review writes: keep the review in chat. Do not ask_user after it \u2014 they read and type next steps. Do not github_comment / linear_comment / *_update_* / `gh pr review` on the PR or ticket until they ask. Authors see those immediately.";
43
+ }
44
+
19
45
  // src/git/team-meta.ts
20
46
  var SOCCER_TEAM_META = {
21
47
  "aalborg": { location: "Aalborg, Denmark", league: "Danish Superliga" },
@@ -876,11 +902,12 @@ function branchDisplayLabel(branchName, worktreePath) {
876
902
  }
877
903
  function taskPurposeTitle(title) {
878
904
  const trimmed = title?.trim() ?? "";
879
- if (!trimmed || teamSlugFromName(trimmed)) return null;
905
+ if (!trimmed || teamSlugFromName(trimmed) || trimmed === REVIEW_TAB_TITLE) return null;
880
906
  return trimmed;
881
907
  }
882
908
  function threadDisplayLabel(thread) {
883
- if (thread.userSetTitle && thread.title?.trim()) return thread.title.trim();
909
+ const titled = thread.title?.trim() ?? "";
910
+ if (thread.userSetTitle && titled && titled !== REVIEW_TAB_TITLE) return titled;
884
911
  if (thread.prTitle?.trim()) return thread.prTitle.trim();
885
912
  if (isPlaceholderBranch(thread.branchName, thread.worktreePath)) {
886
913
  const purpose = taskPurposeTitle(thread.title);
@@ -896,6 +923,35 @@ function worktreeDisplayLabelForGroup(threads) {
896
923
  const canonical = [...threads].sort((a, b) => a.createdAt.localeCompare(b.createdAt))[0];
897
924
  return threadDisplayLabel(canonical);
898
925
  }
926
+ function worktreeAnchorLabel(threads) {
927
+ if (threads.length === 0) return { title: "Worktree", subtitle: null };
928
+ const canonical = [...threads].sort((a, b) => a.createdAt.localeCompare(b.createdAt))[0];
929
+ const pr = threads.map((t) => t.prTitle?.trim()).find((v) => Boolean(v)) ?? "";
930
+ const branch = (canonical.branchName ?? "").trim();
931
+ const placeholder = isPlaceholderBranch(branch, canonical.worktreePath);
932
+ const display = branchDisplayLabel(canonical.branchName, canonical.worktreePath);
933
+ const realBranch = !placeholder && branch && branch !== "HEAD" ? branch : null;
934
+ if (pr) {
935
+ return {
936
+ title: pr,
937
+ subtitle: realBranch && realBranch !== pr ? realBranch : null
938
+ };
939
+ }
940
+ if (placeholder) {
941
+ const purpose = taskPurposeTitle(canonical.title);
942
+ if (purpose) return { title: purpose, subtitle: null };
943
+ }
944
+ if (display) {
945
+ return {
946
+ title: display,
947
+ subtitle: realBranch && realBranch !== display ? realBranch : null
948
+ };
949
+ }
950
+ return {
951
+ title: worktreeNameFromPath(canonical.worktreePath),
952
+ subtitle: realBranch
953
+ };
954
+ }
899
955
  function agentNicknameFromWorktreePath(worktreePath) {
900
956
  const dir = worktreeNameFromPath(worktreePath);
901
957
  if (!soccerTokenFromTakenSlug(dir)) return null;
@@ -1246,6 +1302,10 @@ function findThreadByRef(ref) {
1246
1302
  }
1247
1303
 
1248
1304
  export {
1305
+ REVIEW_TAB_TITLE,
1306
+ isReviewWriteGatedThread,
1307
+ formatReviewWriteGateDirective,
1308
+ formatReviewWriteGateReminder,
1249
1309
  FAMOUS_SOCCER_TEAMS,
1250
1310
  lookupSoccerTeam,
1251
1311
  teamSlugFromName,
@@ -1263,6 +1323,7 @@ export {
1263
1323
  threadDisplayLabel,
1264
1324
  worktreeDisplayLabel,
1265
1325
  worktreeDisplayLabelForGroup,
1326
+ worktreeAnchorLabel,
1266
1327
  agentNicknameFromWorktreePath,
1267
1328
  workspaceNameLabel,
1268
1329
  worktreeIdentityTitles,
@@ -32,18 +32,18 @@ import {
32
32
  tryReservePort,
33
33
  tryReservePorts,
34
34
  worktreeRunPortsPath
35
- } from "./chunk-ATSZXRFQ.js";
35
+ } from "./chunk-ST2UQBJT.js";
36
36
  import "./chunk-7Q327QF2.js";
37
- import "./chunk-GFM63DTU.js";
38
- import "./chunk-BPBDGJ43.js";
39
- import "./chunk-CHUPIJP7.js";
37
+ import "./chunk-YALFZKSC.js";
38
+ import "./chunk-TUJFCJJU.js";
39
+ import "./chunk-YEIHCSZS.js";
40
40
  import "./chunk-2P4XKWV2.js";
41
41
  import "./chunk-F2PVRF3B.js";
42
42
  import "./chunk-5XNT6BCG.js";
43
43
  import "./chunk-6K64FJDD.js";
44
44
  import "./chunk-LG6RJBIY.js";
45
45
  import "./chunk-QVN2WOKJ.js";
46
- import "./chunk-U7PNCYNX.js";
46
+ import "./chunk-E52SQENB.js";
47
47
  import "./chunk-77WWLBCI.js";
48
48
  import {
49
49
  stripNestedElectronEnv
@@ -34,10 +34,10 @@ import {
34
34
  tryReservePort,
35
35
  tryReservePorts,
36
36
  worktreeRunPortsPath
37
- } from "./chunk-DNWO6PQJ.js";
37
+ } from "./chunk-NRSC4N5X.js";
38
38
  import "./chunk-I5TESHDN.js";
39
- import "./chunk-PN32Z4JL.js";
40
- import "./chunk-5CTG5W7S.js";
39
+ import "./chunk-A6C67DY5.js";
40
+ import "./chunk-A46CIARU.js";
41
41
  import "./chunk-N2WW62LF.js";
42
42
  import "./chunk-DD67JWTN.js";
43
43
  import "./chunk-2UG25RMK.js";
@@ -48,7 +48,7 @@ import {
48
48
  } from "./chunk-WWUABK6B.js";
49
49
  import "./chunk-FJZWM2ON.js";
50
50
  import "./chunk-J2LNLI4S.js";
51
- import "./chunk-U35AHE2P.js";
51
+ import "./chunk-HOLB6ZFZ.js";
52
52
  import "./chunk-WMZIANPV.js";
53
53
  import "./chunk-KGZBYWZ3.js";
54
54
  import {
@@ -9,8 +9,8 @@ import {
9
9
  enrichWorkspacesWithGithub,
10
10
  ensureGlobalCoordinatorCwd,
11
11
  formatWorkspaceInventory
12
- } from "./chunk-PN32Z4JL.js";
13
- import "./chunk-5CTG5W7S.js";
12
+ } from "./chunk-A6C67DY5.js";
13
+ import "./chunk-A46CIARU.js";
14
14
  import "./chunk-N2WW62LF.js";
15
15
  import "./chunk-DD67JWTN.js";
16
16
  import "./chunk-2UG25RMK.js";
@@ -19,7 +19,7 @@ import "./chunk-NSTQ6QKD.js";
19
19
  import "./chunk-WWUABK6B.js";
20
20
  import "./chunk-FJZWM2ON.js";
21
21
  import "./chunk-J2LNLI4S.js";
22
- import "./chunk-U35AHE2P.js";
22
+ import "./chunk-HOLB6ZFZ.js";
23
23
  import "./chunk-WMZIANPV.js";
24
24
  import "./chunk-KGZBYWZ3.js";
25
25
  import "./chunk-WOU343SI.js";
@@ -7,15 +7,15 @@ import {
7
7
  enrichWorkspacesWithGithub,
8
8
  ensureGlobalCoordinatorCwd,
9
9
  formatWorkspaceInventory
10
- } from "./chunk-GFM63DTU.js";
11
- import "./chunk-BPBDGJ43.js";
12
- import "./chunk-CHUPIJP7.js";
10
+ } from "./chunk-YALFZKSC.js";
11
+ import "./chunk-TUJFCJJU.js";
12
+ import "./chunk-YEIHCSZS.js";
13
13
  import "./chunk-2P4XKWV2.js";
14
14
  import "./chunk-F2PVRF3B.js";
15
15
  import "./chunk-6K64FJDD.js";
16
16
  import "./chunk-LG6RJBIY.js";
17
17
  import "./chunk-QVN2WOKJ.js";
18
- import "./chunk-U7PNCYNX.js";
18
+ import "./chunk-E52SQENB.js";
19
19
  import "./chunk-77WWLBCI.js";
20
20
  import "./chunk-4TR3HZFT.js";
21
21
  import "./chunk-WDRMZKVB.js";
@@ -20,8 +20,8 @@ import {
20
20
  remoteCoordinatorSourceRef,
21
21
  slackCoordinatorSourceRef,
22
22
  takenTeamSlugsForOrchestration
23
- } from "./chunk-PN32Z4JL.js";
24
- import "./chunk-5CTG5W7S.js";
23
+ } from "./chunk-A6C67DY5.js";
24
+ import "./chunk-A46CIARU.js";
25
25
  import "./chunk-N2WW62LF.js";
26
26
  import "./chunk-DD67JWTN.js";
27
27
  import "./chunk-2UG25RMK.js";
@@ -30,7 +30,7 @@ import "./chunk-NSTQ6QKD.js";
30
30
  import "./chunk-WWUABK6B.js";
31
31
  import "./chunk-FJZWM2ON.js";
32
32
  import "./chunk-J2LNLI4S.js";
33
- import "./chunk-U35AHE2P.js";
33
+ import "./chunk-HOLB6ZFZ.js";
34
34
  import "./chunk-WMZIANPV.js";
35
35
  import "./chunk-KGZBYWZ3.js";
36
36
  import {
@@ -18,15 +18,15 @@ import {
18
18
  remoteCoordinatorSourceRef,
19
19
  slackCoordinatorSourceRef,
20
20
  takenTeamSlugsForOrchestration
21
- } from "./chunk-GFM63DTU.js";
22
- import "./chunk-BPBDGJ43.js";
23
- import "./chunk-CHUPIJP7.js";
21
+ } from "./chunk-YALFZKSC.js";
22
+ import "./chunk-TUJFCJJU.js";
23
+ import "./chunk-YEIHCSZS.js";
24
24
  import "./chunk-2P4XKWV2.js";
25
25
  import "./chunk-F2PVRF3B.js";
26
26
  import "./chunk-6K64FJDD.js";
27
27
  import "./chunk-LG6RJBIY.js";
28
28
  import "./chunk-QVN2WOKJ.js";
29
- import "./chunk-U7PNCYNX.js";
29
+ import "./chunk-E52SQENB.js";
30
30
  import "./chunk-77WWLBCI.js";
31
31
  import "./chunk-4TR3HZFT.js";
32
32
  import "./chunk-WDRMZKVB.js";