@sideboard-ai/core 0.1.316 → 0.1.317

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 (33) hide show
  1. package/dist/{agents-Y3M3EKLY.js → agents-BJVSYC6Y.js} +4 -4
  2. package/dist/{agents-5XJ7EHGU.js → agents-KABJUDPI.js} +4 -4
  3. package/dist/{chunk-ATSZXRFQ.js → chunk-4XZJYBO2.js} +5 -34
  4. package/dist/{chunk-5CTG5W7S.js → chunk-A46CIARU.js} +1 -1
  5. package/dist/{chunk-PN32Z4JL.js → chunk-A6C67DY5.js} +2 -2
  6. package/dist/{chunk-7BLIY2DD.js → chunk-BXTISNKW.js} +15 -15
  7. package/dist/{chunk-FVTR54LY.js → chunk-GH7UMULC.js} +4 -4
  8. package/dist/{chunk-U35AHE2P.js → chunk-HOLB6ZFZ.js} +33 -2
  9. package/dist/{chunk-DNWO6PQJ.js → chunk-NRSC4N5X.js} +5 -34
  10. package/dist/{chunk-GFM63DTU.js → chunk-PX324N7P.js} +2 -2
  11. package/dist/{chunk-4ISF5XUA.js → chunk-U53JICJ2.js} +16 -16
  12. package/dist/{chunk-NKVNHBDB.js → chunk-XWUDFLBX.js} +3 -3
  13. package/dist/{chunk-CHUPIJP7.js → chunk-YEIHCSZS.js} +63 -2
  14. package/dist/{chunk-BPBDGJ43.js → chunk-YN6XONV5.js} +1 -1
  15. package/dist/{conductor-NZ4V5CJX.js → conductor-NIUBJLTS.js} +4 -4
  16. package/dist/{conductor-CFLBKVHJ.js → conductor-TP2NA44I.js} +4 -4
  17. package/dist/{coordinator-prompt-HUZC4DZ2.js → coordinator-prompt-3CT3D5UM.js} +3 -3
  18. package/dist/{coordinator-prompt-SPOYUZG5.js → coordinator-prompt-FQC2SZPP.js} +3 -3
  19. package/dist/{global-workspace-3NNDDTFD.js → global-workspace-72K6D354.js} +3 -3
  20. package/dist/{global-workspace-SK4JQBPN.js → global-workspace-BUWMRNW5.js} +3 -3
  21. package/dist/index.cjs +67 -36
  22. package/dist/index.js +12 -11
  23. package/dist/mcp/run-stdio.cjs +36 -34
  24. package/dist/mcp/run-stdio.js +6 -6
  25. package/dist/{orchestrator-KXEPWTG5.js → orchestrator-E72HYGTB.js} +6 -6
  26. package/dist/{orchestrator-7342RGRU.js → orchestrator-N54V3B76.js} +6 -6
  27. package/dist/{thread-store-5OF6M6VZ.js → thread-store-7BBA63KV.js} +1 -1
  28. package/dist/{thread-store-GOVVXQV2.js → thread-store-PLNIWFZ4.js} +1 -1
  29. package/dist/{workspaces-EYNZDL45.js → workspaces-2V5UYPYC.js} +3 -3
  30. package/dist/{workspaces-52L6NZ3P.js → workspaces-GAUHXBUL.js} +3 -3
  31. package/dist/{worktree-BP5ICYQ2.js → worktree-6FUQ7FEF.js} +2 -2
  32. package/dist/{worktree-UCOSAI7J.js → worktree-XJKLDYOL.js} +2 -2
  33. package/package.json +1 -1
@@ -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,
@@ -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";
@@ -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 {
@@ -32,11 +32,11 @@ import {
32
32
  tryReservePort,
33
33
  tryReservePorts,
34
34
  worktreeRunPortsPath
35
- } from "./chunk-ATSZXRFQ.js";
35
+ } from "./chunk-4XZJYBO2.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-PX324N7P.js";
38
+ import "./chunk-YN6XONV5.js";
39
+ import "./chunk-YEIHCSZS.js";
40
40
  import "./chunk-2P4XKWV2.js";
41
41
  import "./chunk-F2PVRF3B.js";
42
42
  import "./chunk-5XNT6BCG.js";
@@ -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,9 +7,9 @@ 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-PX324N7P.js";
11
+ import "./chunk-YN6XONV5.js";
12
+ import "./chunk-YEIHCSZS.js";
13
13
  import "./chunk-2P4XKWV2.js";
14
14
  import "./chunk-F2PVRF3B.js";
15
15
  import "./chunk-6K64FJDD.js";
@@ -18,9 +18,9 @@ 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-PX324N7P.js";
22
+ import "./chunk-YN6XONV5.js";
23
+ import "./chunk-YEIHCSZS.js";
24
24
  import "./chunk-2P4XKWV2.js";
25
25
  import "./chunk-F2PVRF3B.js";
26
26
  import "./chunk-6K64FJDD.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 {
package/dist/index.cjs CHANGED
@@ -4112,6 +4112,38 @@ var init_caffeinate_hold = __esm({
4112
4112
  }
4113
4113
  });
4114
4114
 
4115
+ // src/review/review-write-gate.ts
4116
+ function hasLiveReviewSibling(thread, siblings = []) {
4117
+ const selfId = thread.id;
4118
+ return siblings.some(
4119
+ (t) => t.id !== selfId && t.status !== "archived" && t.title.trim() === REVIEW_TAB_TITLE
4120
+ );
4121
+ }
4122
+ function isReviewWriteGatedThread(thread, siblings) {
4123
+ if (thread.sourceType === "pr" || thread.title.trim() === REVIEW_TAB_TITLE) {
4124
+ return true;
4125
+ }
4126
+ return hasLiveReviewSibling(thread, siblings);
4127
+ }
4128
+ function formatReviewWriteGateDirective() {
4129
+ return [
4130
+ "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.",
4131
+ "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.",
4132
+ "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.",
4133
+ "Do not request reviewers, change labels, or assign yourself unless they asked \u2014 those also notify the author."
4134
+ ].join("\n");
4135
+ }
4136
+ function formatReviewWriteGateReminder() {
4137
+ 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.";
4138
+ }
4139
+ var REVIEW_TAB_TITLE;
4140
+ var init_review_write_gate = __esm({
4141
+ "src/review/review-write-gate.ts"() {
4142
+ "use strict";
4143
+ REVIEW_TAB_TITLE = "Review";
4144
+ }
4145
+ });
4146
+
4115
4147
  // src/git/team-meta.ts
4116
4148
  var SOCCER_TEAM_META;
4117
4149
  var init_team_meta = __esm({
@@ -4983,11 +5015,12 @@ function branchDisplayLabel(branchName, worktreePath) {
4983
5015
  }
4984
5016
  function taskPurposeTitle(title) {
4985
5017
  const trimmed = title?.trim() ?? "";
4986
- if (!trimmed || teamSlugFromName(trimmed)) return null;
5018
+ if (!trimmed || teamSlugFromName(trimmed) || trimmed === REVIEW_TAB_TITLE) return null;
4987
5019
  return trimmed;
4988
5020
  }
4989
5021
  function threadDisplayLabel(thread) {
4990
- if (thread.userSetTitle && thread.title?.trim()) return thread.title.trim();
5022
+ const titled = thread.title?.trim() ?? "";
5023
+ if (thread.userSetTitle && titled && titled !== REVIEW_TAB_TITLE) return titled;
4991
5024
  if (thread.prTitle?.trim()) return thread.prTitle.trim();
4992
5025
  if (isPlaceholderBranch(thread.branchName, thread.worktreePath)) {
4993
5026
  const purpose = taskPurposeTitle(thread.title);
@@ -5003,6 +5036,35 @@ function worktreeDisplayLabelForGroup(threads) {
5003
5036
  const canonical = [...threads].sort((a, b) => a.createdAt.localeCompare(b.createdAt))[0];
5004
5037
  return threadDisplayLabel(canonical);
5005
5038
  }
5039
+ function worktreeAnchorLabel(threads) {
5040
+ if (threads.length === 0) return { title: "Worktree", subtitle: null };
5041
+ const canonical = [...threads].sort((a, b) => a.createdAt.localeCompare(b.createdAt))[0];
5042
+ const pr = threads.map((t) => t.prTitle?.trim()).find((v) => Boolean(v)) ?? "";
5043
+ const branch = (canonical.branchName ?? "").trim();
5044
+ const placeholder = isPlaceholderBranch(branch, canonical.worktreePath);
5045
+ const display = branchDisplayLabel(canonical.branchName, canonical.worktreePath);
5046
+ const realBranch = !placeholder && branch && branch !== "HEAD" ? branch : null;
5047
+ if (pr) {
5048
+ return {
5049
+ title: pr,
5050
+ subtitle: realBranch && realBranch !== pr ? realBranch : null
5051
+ };
5052
+ }
5053
+ if (placeholder) {
5054
+ const purpose = taskPurposeTitle(canonical.title);
5055
+ if (purpose) return { title: purpose, subtitle: null };
5056
+ }
5057
+ if (display) {
5058
+ return {
5059
+ title: display,
5060
+ subtitle: realBranch && realBranch !== display ? realBranch : null
5061
+ };
5062
+ }
5063
+ return {
5064
+ title: worktreeNameFromPath(canonical.worktreePath),
5065
+ subtitle: realBranch
5066
+ };
5067
+ }
5006
5068
  function agentNicknameFromWorktreePath(worktreePath) {
5007
5069
  const dir = worktreeNameFromPath(worktreePath);
5008
5070
  if (!soccerTokenFromTakenSlug(dir)) return null;
@@ -5053,6 +5115,7 @@ var WORKSPACE_TAG_LIMIT, WORKSPACE_TAG_MAX_LENGTH;
5053
5115
  var init_worktree_labels = __esm({
5054
5116
  "src/git/worktree-labels.ts"() {
5055
5117
  "use strict";
5118
+ init_review_write_gate();
5056
5119
  init_teams();
5057
5120
  WORKSPACE_TAG_LIMIT = 8;
5058
5121
  WORKSPACE_TAG_MAX_LENGTH = 32;
@@ -20887,38 +20950,6 @@ var init_chat_tabs = __esm({
20887
20950
  }
20888
20951
  });
20889
20952
 
20890
- // src/review/review-write-gate.ts
20891
- function hasLiveReviewSibling(thread, siblings = []) {
20892
- const selfId = thread.id;
20893
- return siblings.some(
20894
- (t) => t.id !== selfId && t.status !== "archived" && t.title.trim() === REVIEW_TAB_TITLE
20895
- );
20896
- }
20897
- function isReviewWriteGatedThread(thread, siblings) {
20898
- if (thread.sourceType === "pr" || thread.title.trim() === REVIEW_TAB_TITLE) {
20899
- return true;
20900
- }
20901
- return hasLiveReviewSibling(thread, siblings);
20902
- }
20903
- function formatReviewWriteGateDirective() {
20904
- return [
20905
- "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.",
20906
- "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.",
20907
- "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.",
20908
- "Do not request reviewers, change labels, or assign yourself unless they asked \u2014 those also notify the author."
20909
- ].join("\n");
20910
- }
20911
- function formatReviewWriteGateReminder() {
20912
- 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.";
20913
- }
20914
- var REVIEW_TAB_TITLE;
20915
- var init_review_write_gate = __esm({
20916
- "src/review/review-write-gate.ts"() {
20917
- "use strict";
20918
- REVIEW_TAB_TITLE = "Review";
20919
- }
20920
- });
20921
-
20922
20953
  // src/review/review-request-template.ts
20923
20954
  function wrapReviewSkillMarkdown(body) {
20924
20955
  const trimmed = body.replace(/^\uFEFF/, "").trim();
@@ -35497,7 +35528,7 @@ function listPhoneSidebar(viewerLogin = phoneViewerLogin()) {
35497
35528
  const badge = classifyWorktreeListBadges(group, viewerLogin, resolveProjectReviewLabel(settings, path2))[0];
35498
35529
  const blockedBy = issueBlockedByIds(group);
35499
35530
  return {
35500
- label: worktreeDisplayLabelForGroup(group),
35531
+ label: worktreeAnchorLabel(group).title,
35501
35532
  chats: group.map(summarize),
35502
35533
  ...tags.length > 0 ? { tags } : {},
35503
35534
  ...blockedBy.length > 0 ? { blockedBy } : {},
@@ -35577,7 +35608,7 @@ function projectPlace(thread) {
35577
35608
  return {
35578
35609
  kind: "project",
35579
35610
  repoPath: thread.repoPath,
35580
- worktree: worktreeDisplayLabelForGroup(group.length > 0 ? group : [thread])
35611
+ worktree: worktreeAnchorLabel(group.length > 0 ? group : [thread]).title
35581
35612
  };
35582
35613
  }
35583
35614
  function assertKnownProject(repoPath) {
package/dist/index.js CHANGED
@@ -203,7 +203,7 @@ import {
203
203
  worktreeCleanupSettings,
204
204
  writeAgentBlock,
205
205
  writeWorktreeFile
206
- } from "./chunk-4ISF5XUA.js";
206
+ } from "./chunk-U53JICJ2.js";
207
207
  import {
208
208
  LEGACY_PLAN_FILE_REL,
209
209
  PLAN_FILE_NAME,
@@ -293,7 +293,7 @@ import {
293
293
  userMcpNamesToDisable,
294
294
  worktreeMcpToolNames,
295
295
  writeInjectedMcpConfig
296
- } from "./chunk-NKVNHBDB.js";
296
+ } from "./chunk-XWUDFLBX.js";
297
297
  import {
298
298
  brightsyMcpServerName,
299
299
  connectBrightsyTeam,
@@ -424,7 +424,7 @@ import {
424
424
  workspaceAgentChatSummaries,
425
425
  worktreeRunPortsPath,
426
426
  wrapReviewSkillMarkdown
427
- } from "./chunk-ATSZXRFQ.js";
427
+ } from "./chunk-4XZJYBO2.js";
428
428
  import {
429
429
  STDERR_EVENT_MAX_CHARS,
430
430
  STDOUT_EVENT_MAX_CHARS,
@@ -626,7 +626,7 @@ import {
626
626
  stageBuffersAsAttachments,
627
627
  syncWorkspacesFromThreads,
628
628
  takenTeamSlugsForOrchestration
629
- } from "./chunk-GFM63DTU.js";
629
+ } from "./chunk-PX324N7P.js";
630
630
  import {
631
631
  GITHUB_PR_BODY_MAX_CHARS,
632
632
  GITHUB_PR_BODY_SAFE_CHARS,
@@ -714,7 +714,7 @@ import {
714
714
  suggestSlug,
715
715
  switchWorktreeBranch,
716
716
  warmGithubAgentAuth
717
- } from "./chunk-BPBDGJ43.js";
717
+ } from "./chunk-YN6XONV5.js";
718
718
  import {
719
719
  FAMOUS_SOCCER_TEAMS,
720
720
  allocateTeamName,
@@ -742,12 +742,13 @@ import {
742
742
  withThreadLock,
743
743
  workspaceNameLabel,
744
744
  workspaceTagsFromGroup,
745
+ worktreeAnchorLabel,
745
746
  worktreeDisplayLabel,
746
747
  worktreeDisplayLabelForGroup,
747
748
  worktreeNameFromPath,
748
749
  worktreeSlugForTicket,
749
750
  writeThread
750
- } from "./chunk-CHUPIJP7.js";
751
+ } from "./chunk-YEIHCSZS.js";
751
752
  import "./chunk-2P4XKWV2.js";
752
753
  import {
753
754
  BRIGHTSY_OAUTH_CLIENT_ID,
@@ -2708,7 +2709,7 @@ function listPhoneSidebar(viewerLogin = phoneViewerLogin()) {
2708
2709
  const badge = classifyWorktreeListBadges(group, viewerLogin, resolveProjectReviewLabel(settings, path2))[0];
2709
2710
  const blockedBy = issueBlockedByIds(group);
2710
2711
  return {
2711
- label: worktreeDisplayLabelForGroup(group),
2712
+ label: worktreeAnchorLabel(group).title,
2712
2713
  chats: group.map(summarize),
2713
2714
  ...tags.length > 0 ? { tags } : {},
2714
2715
  ...blockedBy.length > 0 ? { blockedBy } : {},
@@ -2788,7 +2789,7 @@ function projectPlace(thread) {
2788
2789
  return {
2789
2790
  kind: "project",
2790
2791
  repoPath: thread.repoPath,
2791
- worktree: worktreeDisplayLabelForGroup(group.length > 0 ? group : [thread])
2792
+ worktree: worktreeAnchorLabel(group.length > 0 ? group : [thread]).title
2792
2793
  };
2793
2794
  }
2794
2795
  function assertKnownProject(repoPath) {
@@ -8730,7 +8731,7 @@ async function startHeadlessHost(opts) {
8730
8731
  };
8731
8732
  const refreshRunning = async () => {
8732
8733
  try {
8733
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-KXEPWTG5.js");
8734
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-E72HYGTB.js");
8734
8735
  agentsRunning = getOrchestrator2().getRuntime().running;
8735
8736
  } catch {
8736
8737
  agentsRunning = 0;
@@ -10663,7 +10664,7 @@ async function handleJobStop(params, _ctx) {
10663
10664
  return stopDetachedJob(jobCwd(rec), id, reason ? { reason } : void 0);
10664
10665
  }
10665
10666
  async function defaultTurnWait(ref, timeoutMs) {
10666
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-KXEPWTG5.js");
10667
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-E72HYGTB.js");
10667
10668
  const orch = getOrchestrator2();
10668
10669
  const thread = await orch.waitForTurn(ref, timeoutMs, {
10669
10670
  resolveIfStillRunning: true
@@ -14316,7 +14317,7 @@ async function continueSourceThread(threadId, prompt) {
14316
14317
  await continueOnReply(threadId, prompt);
14317
14318
  return;
14318
14319
  }
14319
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-KXEPWTG5.js");
14320
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-E72HYGTB.js");
14320
14321
  await getOrchestrator2().send(threadId, prompt);
14321
14322
  } catch {
14322
14323
  }
@@ -2653,6 +2653,38 @@ var init_run = __esm({
2653
2653
  }
2654
2654
  });
2655
2655
 
2656
+ // src/review/review-write-gate.ts
2657
+ function hasLiveReviewSibling(thread, siblings = []) {
2658
+ const selfId = thread.id;
2659
+ return siblings.some(
2660
+ (t) => t.id !== selfId && t.status !== "archived" && t.title.trim() === REVIEW_TAB_TITLE
2661
+ );
2662
+ }
2663
+ function isReviewWriteGatedThread(thread, siblings) {
2664
+ if (thread.sourceType === "pr" || thread.title.trim() === REVIEW_TAB_TITLE) {
2665
+ return true;
2666
+ }
2667
+ return hasLiveReviewSibling(thread, siblings);
2668
+ }
2669
+ function formatReviewWriteGateDirective() {
2670
+ return [
2671
+ "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.",
2672
+ "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.",
2673
+ "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.",
2674
+ "Do not request reviewers, change labels, or assign yourself unless they asked \u2014 those also notify the author."
2675
+ ].join("\n");
2676
+ }
2677
+ function formatReviewWriteGateReminder() {
2678
+ 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.";
2679
+ }
2680
+ var REVIEW_TAB_TITLE;
2681
+ var init_review_write_gate = __esm({
2682
+ "src/review/review-write-gate.ts"() {
2683
+ "use strict";
2684
+ REVIEW_TAB_TITLE = "Review";
2685
+ }
2686
+ });
2687
+
2656
2688
  // src/git/team-meta.ts
2657
2689
  var SOCCER_TEAM_META;
2658
2690
  var init_team_meta = __esm({
@@ -3524,11 +3556,12 @@ function branchDisplayLabel(branchName, worktreePath) {
3524
3556
  }
3525
3557
  function taskPurposeTitle(title) {
3526
3558
  const trimmed = title?.trim() ?? "";
3527
- if (!trimmed || teamSlugFromName(trimmed)) return null;
3559
+ if (!trimmed || teamSlugFromName(trimmed) || trimmed === REVIEW_TAB_TITLE) return null;
3528
3560
  return trimmed;
3529
3561
  }
3530
3562
  function threadDisplayLabel(thread) {
3531
- if (thread.userSetTitle && thread.title?.trim()) return thread.title.trim();
3563
+ const titled = thread.title?.trim() ?? "";
3564
+ if (thread.userSetTitle && titled && titled !== REVIEW_TAB_TITLE) return titled;
3532
3565
  if (thread.prTitle?.trim()) return thread.prTitle.trim();
3533
3566
  if (isPlaceholderBranch(thread.branchName, thread.worktreePath)) {
3534
3567
  const purpose = taskPurposeTitle(thread.title);
@@ -3584,6 +3617,7 @@ var WORKSPACE_TAG_LIMIT, WORKSPACE_TAG_MAX_LENGTH;
3584
3617
  var init_worktree_labels = __esm({
3585
3618
  "src/git/worktree-labels.ts"() {
3586
3619
  "use strict";
3620
+ init_review_write_gate();
3587
3621
  init_teams();
3588
3622
  WORKSPACE_TAG_LIMIT = 8;
3589
3623
  WORKSPACE_TAG_MAX_LENGTH = 32;
@@ -17248,38 +17282,6 @@ var init_chat_tabs = __esm({
17248
17282
  }
17249
17283
  });
17250
17284
 
17251
- // src/review/review-write-gate.ts
17252
- function hasLiveReviewSibling(thread, siblings = []) {
17253
- const selfId = thread.id;
17254
- return siblings.some(
17255
- (t) => t.id !== selfId && t.status !== "archived" && t.title.trim() === REVIEW_TAB_TITLE
17256
- );
17257
- }
17258
- function isReviewWriteGatedThread(thread, siblings) {
17259
- if (thread.sourceType === "pr" || thread.title.trim() === REVIEW_TAB_TITLE) {
17260
- return true;
17261
- }
17262
- return hasLiveReviewSibling(thread, siblings);
17263
- }
17264
- function formatReviewWriteGateDirective() {
17265
- return [
17266
- "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.",
17267
- "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.",
17268
- "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.",
17269
- "Do not request reviewers, change labels, or assign yourself unless they asked \u2014 those also notify the author."
17270
- ].join("\n");
17271
- }
17272
- function formatReviewWriteGateReminder() {
17273
- 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.";
17274
- }
17275
- var REVIEW_TAB_TITLE;
17276
- var init_review_write_gate = __esm({
17277
- "src/review/review-write-gate.ts"() {
17278
- "use strict";
17279
- REVIEW_TAB_TITLE = "Review";
17280
- }
17281
- });
17282
-
17283
17285
  // src/review/review-request-template.ts
17284
17286
  var REVIEW_REQUEST_TEMPLATE, REVIEW_SKILL_PATH, REVIEW_SKILL_NAME;
17285
17287
  var init_review_request_template = __esm({
@@ -56,7 +56,7 @@ import {
56
56
  updateSchedule,
57
57
  workspaceTagTargetRef,
58
58
  writeAgentBlock
59
- } from "../chunk-7BLIY2DD.js";
59
+ } from "../chunk-BXTISNKW.js";
60
60
  import "../chunk-LX5R5JOR.js";
61
61
  import {
62
62
  commentAbleTimeTask,
@@ -97,7 +97,7 @@ import {
97
97
  shouldRegisterMcpWaitForTurn,
98
98
  sideboardMcpProfile,
99
99
  worktreeMcpToolNames
100
- } from "../chunk-FVTR54LY.js";
100
+ } from "../chunk-GH7UMULC.js";
101
101
  import "../chunk-53OCOGND.js";
102
102
  import "../chunk-V5BTGQ6M.js";
103
103
  import "../chunk-E63AM3PW.js";
@@ -114,7 +114,7 @@ import {
114
114
  waitForDetachedJob,
115
115
  waitForTurnToolResult,
116
116
  workspaceAgentChatSummaries
117
- } from "../chunk-DNWO6PQJ.js";
117
+ } from "../chunk-NRSC4N5X.js";
118
118
  import {
119
119
  HUGE_TOOL_RESULT_SUMMARY,
120
120
  clipToolResultForStore,
@@ -125,7 +125,7 @@ import {
125
125
  import {
126
126
  GLOBAL_WORKSPACE_ID,
127
127
  isCloudCoordinatorThread
128
- } from "../chunk-PN32Z4JL.js";
128
+ } from "../chunk-A6C67DY5.js";
129
129
  import {
130
130
  canonicalizeRepoPath,
131
131
  formatGhLandError,
@@ -136,7 +136,7 @@ import {
136
136
  resolveListPrsOptions,
137
137
  resolveRepoRoot,
138
138
  warmGithubAgentAuth
139
- } from "../chunk-5CTG5W7S.js";
139
+ } from "../chunk-A46CIARU.js";
140
140
  import {
141
141
  CLI_DIR
142
142
  } from "../chunk-N2WW62LF.js";
@@ -169,7 +169,7 @@ import {
169
169
  normalizeWorkspaceTags,
170
170
  readThread,
171
171
  updateThread
172
- } from "../chunk-U35AHE2P.js";
172
+ } from "../chunk-HOLB6ZFZ.js";
173
173
  import "../chunk-WMZIANPV.js";
174
174
  import "../chunk-KGZBYWZ3.js";
175
175
  import {
@@ -9,18 +9,18 @@ import {
9
9
  resolveSendFollowUp,
10
10
  startOrchestration,
11
11
  waitForPidExit
12
- } from "./chunk-4ISF5XUA.js";
12
+ } from "./chunk-U53JICJ2.js";
13
13
  import "./chunk-PGPSIEMW.js";
14
- import "./chunk-NKVNHBDB.js";
14
+ import "./chunk-XWUDFLBX.js";
15
15
  import "./chunk-HH3VVTEC.js";
16
- import "./chunk-ATSZXRFQ.js";
16
+ import "./chunk-4XZJYBO2.js";
17
17
  import "./chunk-7Q327QF2.js";
18
18
  import "./chunk-7H655NEW.js";
19
19
  import "./chunk-OLYNM52B.js";
20
20
  import "./chunk-NXNNYY3Q.js";
21
- import "./chunk-GFM63DTU.js";
22
- import "./chunk-BPBDGJ43.js";
23
- import "./chunk-CHUPIJP7.js";
21
+ import "./chunk-PX324N7P.js";
22
+ import "./chunk-YN6XONV5.js";
23
+ import "./chunk-YEIHCSZS.js";
24
24
  import "./chunk-2P4XKWV2.js";
25
25
  import "./chunk-RSA47QYR.js";
26
26
  import "./chunk-JAT3JFOS.js";