@sideboard-ai/core 0.1.42 → 0.1.44

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.
@@ -15,7 +15,7 @@ import {
15
15
  claudeChromeEnabled,
16
16
  loadAppSettings,
17
17
  resolveClaudeExecutable
18
- } from "./chunk-YZ23S32T.js";
18
+ } from "./chunk-FSIK442J.js";
19
19
  import {
20
20
  ensureAgentPath,
21
21
  run
@@ -798,7 +798,7 @@ var claudeAdapter = {
798
798
  );
799
799
  }
800
800
  const mode = permissionMode(thread);
801
- const { isOrchestratorThread } = await import("./global-workspace-4GVWSCEX.js");
801
+ const { isOrchestratorThread } = await import("./global-workspace-FU6UIPDY.js");
802
802
  const isOrchestrator = isOrchestratorThread(thread);
803
803
  const injectedServers = await buildInjectedMcpServers({
804
804
  includeSideboard: true,
@@ -851,9 +851,8 @@ var claudeAdapter = {
851
851
  if (thread.model) {
852
852
  args.push("--model", thread.model);
853
853
  }
854
- if (thread.fast) {
855
- args.push("--effort", "low");
856
- }
854
+ const effort = thread.effort ?? (thread.fast ? "low" : "high");
855
+ args.push("--effort", effort);
857
856
  if (sessionId) {
858
857
  args.push("--resume", sessionId);
859
858
  }
@@ -1344,6 +1343,7 @@ var cursorAdapter = {
1344
1343
  cwd: thread.worktreePath,
1345
1344
  agentId,
1346
1345
  model: thread.model,
1346
+ effort: thread.effort,
1347
1347
  fast: thread.fast,
1348
1348
  planMode: thread.planMode,
1349
1349
  apiKey
@@ -6,9 +6,10 @@ import {
6
6
  enrichWorkspacesWithGithub,
7
7
  ensureGlobalCoordinatorCwd,
8
8
  formatWorkspaceInventory
9
- } from "./chunk-UPMGXM4X.js";
10
- import "./chunk-VA2U5EQH.js";
11
- import "./chunk-5UIKSPDD.js";
9
+ } from "./chunk-JM2TVGNW.js";
10
+ import "./chunk-7PCTK4WO.js";
11
+ import "./chunk-ENSD62HW.js";
12
+ import "./chunk-77WWLBCI.js";
12
13
  import "./chunk-M37RITA6.js";
13
14
  import "./chunk-AJ6ROGD7.js";
14
15
  export {
@@ -11,10 +11,11 @@ import {
11
11
  orchestrationTitleNeedsSoccerNickname,
12
12
  orchestratorSessionPoisonedByBuiltins,
13
13
  takenTeamSlugsForOrchestration
14
- } from "./chunk-6TZSJMXF.js";
15
- import "./chunk-UPMGXM4X.js";
16
- import "./chunk-VA2U5EQH.js";
17
- import "./chunk-5UIKSPDD.js";
14
+ } from "./chunk-I3PKMLFW.js";
15
+ import "./chunk-JM2TVGNW.js";
16
+ import "./chunk-7PCTK4WO.js";
17
+ import "./chunk-ENSD62HW.js";
18
+ import "./chunk-77WWLBCI.js";
18
19
  import {
19
20
  globalAgentCwd
20
21
  } from "./chunk-M37RITA6.js";
package/dist/index.cjs CHANGED
@@ -30,6 +30,54 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
+ // src/types/thinking-effort.ts
34
+ function normalizeThinkingEffort(value) {
35
+ if (typeof value !== "string") return null;
36
+ const v = value.trim().toLowerCase();
37
+ if (v === "normal") return "medium";
38
+ if (EFFORT_SET.has(v)) return v;
39
+ return null;
40
+ }
41
+ function isThinkingEffort(value) {
42
+ return typeof value === "string" && EFFORT_SET.has(value.trim().toLowerCase());
43
+ }
44
+ function nextThinkingEffort(current) {
45
+ const i = THINKING_EFFORTS.indexOf(current);
46
+ return THINKING_EFFORTS[(i + 1) % THINKING_EFFORTS.length];
47
+ }
48
+ function thinkingEffortBars(effort) {
49
+ const i = THINKING_EFFORTS.indexOf(effort);
50
+ return i >= 0 ? i + 1 : 3;
51
+ }
52
+ function thinkingEffortLabel(effort) {
53
+ switch (effort) {
54
+ case "low":
55
+ return "Low";
56
+ case "medium":
57
+ return "Medium";
58
+ case "high":
59
+ return "High";
60
+ case "xhigh":
61
+ return "Extra High";
62
+ case "max":
63
+ return "Max";
64
+ }
65
+ }
66
+ var THINKING_EFFORTS, EFFORT_SET;
67
+ var init_thinking_effort = __esm({
68
+ "src/types/thinking-effort.ts"() {
69
+ "use strict";
70
+ THINKING_EFFORTS = [
71
+ "low",
72
+ "medium",
73
+ "high",
74
+ "xhigh",
75
+ "max"
76
+ ];
77
+ EFFORT_SET = new Set(THINKING_EFFORTS);
78
+ }
79
+ });
80
+
33
81
  // src/hook/settings.ts
34
82
  function expandHome(path) {
35
83
  if (path.startsWith("~/") || path === "~") {
@@ -355,6 +403,8 @@ __export(app_settings_exports, {
355
403
  claudeUserSettingsPath: () => claudeUserSettingsPath,
356
404
  deleteBranchOnPurgeEnabled: () => deleteBranchOnPurgeEnabled,
357
405
  getDefaultAgent: () => getDefaultAgent,
406
+ getDefaultEffort: () => getDefaultEffort,
407
+ getDefaultFast: () => getDefaultFast,
358
408
  getDefaultModel: () => getDefaultModel,
359
409
  getIssueSource: () => getIssueSource,
360
410
  getLinearApiKey: () => getLinearApiKey,
@@ -428,6 +478,12 @@ function normalizeDefaults(raw) {
428
478
  const model = source.model.trim();
429
479
  if (model) out.model = model;
430
480
  }
481
+ if (normalizeThinkingEffort(source.effort)) {
482
+ out.effort = normalizeThinkingEffort(source.effort);
483
+ }
484
+ if (typeof source.fast === "boolean") {
485
+ out.fast = source.fast;
486
+ }
431
487
  return out;
432
488
  }
433
489
  function normalizeAdvanced(raw) {
@@ -606,6 +662,21 @@ function updateDefaultsSettings(patch) {
606
662
  defaults.model = patch.model.trim();
607
663
  }
608
664
  }
665
+ if ("effort" in patch) {
666
+ if (patch.effort == null) {
667
+ delete defaults.effort;
668
+ } else {
669
+ const effort = normalizeThinkingEffort(patch.effort);
670
+ if (effort) defaults.effort = effort;
671
+ }
672
+ }
673
+ if ("fast" in patch) {
674
+ if (patch.fast == null) {
675
+ delete defaults.fast;
676
+ } else {
677
+ defaults.fast = Boolean(patch.fast);
678
+ }
679
+ }
609
680
  return saveAppSettings({ ...current, defaults });
610
681
  }
611
682
  function getDefaultAgent(settings = loadAppSettings()) {
@@ -615,10 +686,18 @@ function getDefaultModel(settings = loadAppSettings()) {
615
686
  const model = settings.defaults.model?.trim();
616
687
  return model || null;
617
688
  }
689
+ function getDefaultEffort(settings = loadAppSettings()) {
690
+ return normalizeThinkingEffort(settings.defaults.effort) ?? "high";
691
+ }
692
+ function getDefaultFast(settings = loadAppSettings()) {
693
+ return settings.defaults.fast === true;
694
+ }
618
695
  function resolveThreadDefaults(settings = loadAppSettings()) {
619
696
  return {
620
697
  agent: getDefaultAgent(settings),
621
- model: getDefaultModel(settings)
698
+ model: getDefaultModel(settings),
699
+ effort: getDefaultEffort(settings),
700
+ fast: getDefaultFast(settings)
622
701
  };
623
702
  }
624
703
  function isLinearConnected(settings = loadAppSettings()) {
@@ -742,6 +821,7 @@ var init_app_settings = __esm({
742
821
  import_node_fs3 = require("fs");
743
822
  import_node_os3 = require("os");
744
823
  import_node_path4 = require("path");
824
+ init_thinking_effort();
745
825
  init_paths();
746
826
  HARNESS_ENV_KEYS = {
747
827
  claude: "ANTHROPIC_API_KEY",
@@ -785,6 +865,7 @@ __export(thread_store_exports, {
785
865
  listThreads: () => listThreads,
786
866
  normalizeThread: () => normalizeThread,
787
867
  readThread: () => readThread,
868
+ resolveThreadEffort: () => resolveThreadEffort,
788
869
  setStatus: () => setStatus,
789
870
  updateThread: () => updateThread,
790
871
  withThreadLock: () => withThreadLock,
@@ -793,10 +874,17 @@ __export(thread_store_exports, {
793
874
  function nowIso() {
794
875
  return (/* @__PURE__ */ new Date()).toISOString();
795
876
  }
877
+ function resolveThreadEffort(raw) {
878
+ const fromField = normalizeThinkingEffort(raw.effort);
879
+ if (fromField) return fromField;
880
+ if (raw.fast) return "low";
881
+ return "high";
882
+ }
796
883
  function normalizeThread(raw) {
797
884
  return {
798
885
  ...raw,
799
886
  model: raw.model ?? null,
887
+ effort: resolveThreadEffort(raw),
800
888
  fast: Boolean(raw.fast),
801
889
  planMode: Boolean(raw.planMode),
802
890
  autonomy: raw.autonomy ?? "default",
@@ -815,6 +903,7 @@ function createEmptyThread(partial) {
815
903
  sessionId: partial.sessionId ?? null,
816
904
  autonomy: partial.autonomy ?? "default",
817
905
  model: partial.model ?? null,
906
+ effort: partial.effort ?? "high",
818
907
  fast: partial.fast ?? false,
819
908
  planMode: partial.planMode ?? false,
820
909
  sourceIsFork: partial.sourceIsFork ?? false,
@@ -922,6 +1011,7 @@ var init_thread_store = __esm({
922
1011
  import_node_crypto = require("crypto");
923
1012
  import_node_fs4 = require("fs");
924
1013
  import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
1014
+ init_thinking_effort();
925
1015
  init_paths();
926
1016
  }
927
1017
  });
@@ -3106,8 +3196,9 @@ var init_coordinator_prompt = __esm({
3106
3196
  "Setup / run:",
3107
3197
  "- run_setup \u2014 re-run worktree setup",
3108
3198
  "- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
3109
- "Inspect / PRs:",
3199
+ "Inspect / review / PRs:",
3110
3200
  "- get_diff \u2014 compact diff summary",
3201
+ "- request_review \u2014 open a Review chat tab on a worktree thread (merge-readiness recommendation); then wait_for_turn / get_turn_result on the returned id",
3111
3202
  "- Ask the worktree agent via send_to_thread to open a draft PR with `gh pr create --draft -R <origin-owner/name>` (workspace `github:` slug / that worktree's origin \u2014 never upstream). Do not open PRs from the orchestrator yourself.",
3112
3203
  "Human-only (do not attempt): merge, ready-for-review land, purge_thread.",
3113
3204
  "Thread links in replies: when mentioning a chat/thread for the user, include a markdown link `[Title](sideboard://thread/<id>)` using the full id (or the link field from create_thread / list_threads). Sideboard renders these as clickable opens.",
@@ -3207,6 +3298,7 @@ function createGlobalChat(opts) {
3207
3298
  agent: opts.agent,
3208
3299
  autonomy: opts.autonomy ?? "default",
3209
3300
  model: opts.model ?? null,
3301
+ effort: opts.effort ?? "high",
3210
3302
  fast: Boolean(opts.fast),
3211
3303
  planMode: Boolean(opts.planMode),
3212
3304
  attachments: opts.attachments ?? [],
@@ -4743,9 +4835,8 @@ var init_claude = __esm({
4743
4835
  if (thread.model) {
4744
4836
  args.push("--model", thread.model);
4745
4837
  }
4746
- if (thread.fast) {
4747
- args.push("--effort", "low");
4748
- }
4838
+ const effort = thread.effort ?? (thread.fast ? "low" : "high");
4839
+ args.push("--effort", effort);
4749
4840
  if (sessionId) {
4750
4841
  args.push("--resume", sessionId);
4751
4842
  }
@@ -5333,6 +5424,7 @@ var init_cursor = __esm({
5333
5424
  cwd: thread.worktreePath,
5334
5425
  agentId,
5335
5426
  model: thread.model,
5427
+ effort: thread.effort,
5336
5428
  fast: thread.fast,
5337
5429
  planMode: thread.planMode,
5338
5430
  apiKey
@@ -5867,10 +5959,10 @@ __export(cursor_recover_exports, {
5867
5959
  function recoverFinishedCursorRun(opts) {
5868
5960
  const agentId = opts.agentId.trim();
5869
5961
  if (!agentId) return null;
5870
- const runsPath = (0, import_node_path23.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
5871
- if (!(0, import_node_fs24.existsSync)(runsPath)) return null;
5962
+ const runsPath = (0, import_node_path24.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
5963
+ if (!(0, import_node_fs25.existsSync)(runsPath)) return null;
5872
5964
  try {
5873
- const lines = (0, import_node_fs24.readFileSync)(runsPath, "utf8").split("\n");
5965
+ const lines = (0, import_node_fs25.readFileSync)(runsPath, "utf8").split("\n");
5874
5966
  let best = null;
5875
5967
  for (const line of lines) {
5876
5968
  const trimmed = line.trim();
@@ -5896,12 +5988,12 @@ function recoverFinishedCursorRun(opts) {
5896
5988
  return null;
5897
5989
  }
5898
5990
  }
5899
- var import_node_fs24, import_node_path23;
5991
+ var import_node_fs25, import_node_path24;
5900
5992
  var init_cursor_recover = __esm({
5901
5993
  "src/agents/cursor-recover.ts"() {
5902
5994
  "use strict";
5903
- import_node_fs24 = require("fs");
5904
- import_node_path23 = require("path");
5995
+ import_node_fs25 = require("fs");
5996
+ import_node_path24 = require("path");
5905
5997
  init_paths();
5906
5998
  }
5907
5999
  });
@@ -5959,8 +6051,12 @@ __export(index_exports, {
5959
6051
  PASTE_ATTACH_MIN_CHARS: () => PASTE_ATTACH_MIN_CHARS,
5960
6052
  PASTE_ATTACH_MIN_LINES: () => PASTE_ATTACH_MIN_LINES,
5961
6053
  PLAN_MODE_INSTRUCTION: () => PLAN_MODE_INSTRUCTION,
6054
+ REVIEW_REQUEST_NAME: () => REVIEW_REQUEST_NAME,
6055
+ REVIEW_REQUEST_PATH: () => REVIEW_REQUEST_PATH,
6056
+ REVIEW_REQUEST_PREFILL: () => REVIEW_REQUEST_PREFILL,
5962
6057
  SIDEBOARD_FORCE_STOP: () => SIDEBOARD_FORCE_STOP,
5963
6058
  SIDEBOARD_MCP_ALLOWED_TOOLS: () => SIDEBOARD_MCP_ALLOWED_TOOLS,
6059
+ THINKING_EFFORTS: () => THINKING_EFFORTS,
5964
6060
  addWorkspace: () => addWorkspace,
5965
6061
  adoptThread: () => adoptThread,
5966
6062
  allAdapters: () => allAdapters,
@@ -5993,6 +6089,7 @@ __export(index_exports, {
5993
6089
  buildDiffCommentAttachment: () => buildDiffCommentAttachment,
5994
6090
  buildForkTranscriptAttachment: () => buildForkTranscriptAttachment,
5995
6091
  buildPastedTextAttachment: () => buildPastedTextAttachment,
6092
+ buildReviewRequestAttachment: () => buildReviewRequestAttachment,
5996
6093
  buildSessionSeed: () => buildSessionSeed,
5997
6094
  buildWorkspaceScriptEnv: () => buildWorkspaceScriptEnv,
5998
6095
  caffeinateWhileCloudConnectEnabled: () => caffeinateWhileCloudConnectEnabled,
@@ -6067,6 +6164,8 @@ __export(index_exports, {
6067
6164
  getAgentSetupInfo: () => getAgentSetupInfo,
6068
6165
  getBrightsySession: () => getBrightsySession,
6069
6166
  getDefaultAgent: () => getDefaultAgent,
6167
+ getDefaultEffort: () => getDefaultEffort,
6168
+ getDefaultFast: () => getDefaultFast,
6070
6169
  getDefaultModel: () => getDefaultModel,
6071
6170
  getDefaultRunScript: () => getDefaultRunScript,
6072
6171
  getDiff: () => getDiff,
@@ -6111,6 +6210,7 @@ __export(index_exports, {
6111
6210
  isOrchestratorThread: () => isOrchestratorThread,
6112
6211
  isPidAlive: () => isPidAlive,
6113
6212
  isPlaceholderBranch: () => isPlaceholderBranch,
6213
+ isThinkingEffort: () => isThinkingEffort,
6114
6214
  listAgentSetupInfo: () => listAgentSetupInfo,
6115
6215
  listBranchCommits: () => listBranchCommits,
6116
6216
  listBranches: () => listBranches,
@@ -6148,7 +6248,9 @@ __export(index_exports, {
6148
6248
  mergePr: () => mergePr,
6149
6249
  mergeUsage: () => mergeUsage,
6150
6250
  nextPastedTextName: () => nextPastedTextName,
6251
+ nextThinkingEffort: () => nextThinkingEffort,
6151
6252
  normalizeParseResult: () => normalizeParseResult,
6253
+ normalizeThinkingEffort: () => normalizeThinkingEffort,
6152
6254
  normalizeThread: () => normalizeThread,
6153
6255
  normalizeTurnInput: () => normalizeTurnInput,
6154
6256
  normalizeWorktreePath: () => normalizeWorktreePath,
@@ -6166,6 +6268,7 @@ __export(index_exports, {
6166
6268
  permissionMode: () => permissionMode,
6167
6269
  previewLand: () => previewLand,
6168
6270
  pushBranch: () => pushBranch,
6271
+ readExistingReviewRequestFile: () => readExistingReviewRequestFile,
6169
6272
  readSkillBody: () => readSkillBody,
6170
6273
  readThread: () => readThread,
6171
6274
  readWorktreeFile: () => readWorktreeFile,
@@ -6175,6 +6278,7 @@ __export(index_exports, {
6175
6278
  removeWorkspace: () => removeWorkspace,
6176
6279
  removeWorktree: () => removeWorktree,
6177
6280
  repoSlug: () => repoSlug,
6281
+ requestReview: () => requestReview,
6178
6282
  requireAgent: () => requireAgent,
6179
6283
  resolveClaudeExecutable: () => resolveClaudeExecutable,
6180
6284
  resolveConductorCursorAgentId: () => resolveConductorCursorAgentId,
@@ -6187,6 +6291,7 @@ __export(index_exports, {
6187
6291
  resolvePrSelector: () => resolvePrSelector,
6188
6292
  resolveRepoRoot: () => resolveRepoRoot,
6189
6293
  resolveThreadDefaults: () => resolveThreadDefaults,
6294
+ resolveThreadEffort: () => resolveThreadEffort,
6190
6295
  resolveWorktreeStartPoint: () => resolveWorktreeStartPoint,
6191
6296
  run: () => run,
6192
6297
  runArchiveScript: () => runArchiveScript,
@@ -6220,6 +6325,8 @@ __export(index_exports, {
6220
6325
  takenTeamSlugsForChatTab: () => takenTeamSlugsForChatTab,
6221
6326
  takenTeamSlugsForOrchestration: () => takenTeamSlugsForOrchestration,
6222
6327
  taskMessageText: () => taskMessageText,
6328
+ thinkingEffortBars: () => thinkingEffortBars,
6329
+ thinkingEffortLabel: () => thinkingEffortLabel,
6223
6330
  threadDisplayLabel: () => threadDisplayLabel,
6224
6331
  threadFilePath: () => threadFilePath,
6225
6332
  threadLockPath: () => threadLockPath,
@@ -6250,6 +6357,7 @@ __export(index_exports, {
6250
6357
  writeWorktreeFile: () => writeWorktreeFile
6251
6358
  });
6252
6359
  module.exports = __toCommonJS(index_exports);
6360
+ init_thinking_effort();
6253
6361
  init_paths();
6254
6362
  init_app_settings();
6255
6363
  init_thread_store();
@@ -8937,6 +9045,7 @@ async function createThread(input, onSetupLine) {
8937
9045
  agent: input.agent,
8938
9046
  autonomy: input.autonomy ?? "default",
8939
9047
  model: input.model ?? null,
9048
+ effort: input.effort ?? "high",
8940
9049
  fast: Boolean(input.fast),
8941
9050
  planMode: Boolean(input.planMode),
8942
9051
  attachments: input.attachments ?? [],
@@ -9052,7 +9161,8 @@ function createChatTab(input) {
9052
9161
  ...binding,
9053
9162
  agent: input.agent ?? from.agent,
9054
9163
  model: input.model !== void 0 ? input.model : input.agent && input.agent !== from.agent ? null : from.model,
9055
- fast: from.fast,
9164
+ effort: input.effort !== void 0 ? input.effort : from.effort,
9165
+ fast: input.fast !== void 0 ? Boolean(input.fast) : from.fast,
9056
9166
  planMode: from.planMode,
9057
9167
  autonomy: input.autonomy ?? from.autonomy,
9058
9168
  attachments: input.attachments ?? [],
@@ -9092,6 +9202,7 @@ async function forkThreadWorktree(input, onSetupLine) {
9092
9202
  agent: input.agent ?? from.agent,
9093
9203
  autonomy: from.autonomy,
9094
9204
  model: from.model,
9205
+ effort: from.effort,
9095
9206
  fast: from.fast,
9096
9207
  planMode: from.planMode,
9097
9208
  title: input.title?.trim() || void 0,
@@ -9387,7 +9498,7 @@ async function importConductorWorkspaceAsync(workspaceId) {
9387
9498
 
9388
9499
  // src/orchestrator/orchestrator.ts
9389
9500
  var import_node_events = require("events");
9390
- var import_node_fs25 = require("fs");
9501
+ var import_node_fs26 = require("fs");
9391
9502
  init_error_detail();
9392
9503
  init_agents();
9393
9504
  init_worktree();
@@ -9631,6 +9742,60 @@ async function cloneRepoIntoSideboard(opts) {
9631
9742
 
9632
9743
  // src/orchestrator/orchestrator.ts
9633
9744
  init_thread_store();
9745
+
9746
+ // src/review/request-review.ts
9747
+ var import_node_crypto5 = require("crypto");
9748
+ var import_node_fs24 = require("fs");
9749
+ var import_node_path23 = require("path");
9750
+ init_global_workspace();
9751
+ init_thread_store();
9752
+ var REVIEW_REQUEST_PATH = ".sideboard/attachments/Review request.md";
9753
+ var REVIEW_REQUEST_NAME = "Review request.md";
9754
+ var REVIEW_REQUEST_PREFILL = `Please review the changes in this workspace and recommend whether they are ready to merge.
9755
+
9756
+ Start with a **Recommendation**: Approve, Approve with nits, Request changes, or Needs more information \u2014 and say why in 1\u20133 sentences. Then list blocking findings vs nits (findings may be empty).`;
9757
+ function buildReviewRequestAttachment(content) {
9758
+ return {
9759
+ id: (0, import_node_crypto5.randomUUID)(),
9760
+ name: REVIEW_REQUEST_NAME,
9761
+ kind: "file",
9762
+ path: REVIEW_REQUEST_PATH,
9763
+ content
9764
+ };
9765
+ }
9766
+ function readExistingReviewRequestFile(worktreePath) {
9767
+ const abs = (0, import_node_path23.join)(worktreePath, REVIEW_REQUEST_PATH);
9768
+ if (!(0, import_node_fs24.existsSync)(abs)) return null;
9769
+ try {
9770
+ const content = (0, import_node_fs24.readFileSync)(abs, "utf8");
9771
+ return content.trim() ? content : null;
9772
+ } catch {
9773
+ return null;
9774
+ }
9775
+ }
9776
+ async function requestReview(threadRef, send) {
9777
+ const from = findThreadByRef(threadRef);
9778
+ if (!from) throw new Error(`Thread not found: ${threadRef}`);
9779
+ if (isOrchestratorThread(from)) {
9780
+ throw new Error(
9781
+ "request_review targets a worktree agent thread (not the orchestrator). Pass a child/worktree thread ref."
9782
+ );
9783
+ }
9784
+ if (from.status === "archived") {
9785
+ throw new Error(`Thread is archived: ${from.id}`);
9786
+ }
9787
+ const existing = readExistingReviewRequestFile(from.worktreePath);
9788
+ const attachments = existing ? [buildReviewRequestAttachment(existing)] : [];
9789
+ const tab = createChatTab({
9790
+ fromThreadId: from.id,
9791
+ title: "Review",
9792
+ attachments
9793
+ });
9794
+ const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
9795
+ return { tab: started, from };
9796
+ }
9797
+
9798
+ // src/orchestrator/orchestrator.ts
9634
9799
  init_types();
9635
9800
  init_settings();
9636
9801
 
@@ -9749,7 +9914,7 @@ var Orchestrator = class {
9749
9914
  }
9750
9915
  continue;
9751
9916
  }
9752
- if (!(0, import_node_fs25.existsSync)(thread.worktreePath)) {
9917
+ if (!(0, import_node_fs26.existsSync)(thread.worktreePath)) {
9753
9918
  setStatus(thread.id, "broken", "Worktree missing on disk");
9754
9919
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
9755
9920
  continue;
@@ -10647,10 +10812,20 @@ var Orchestrator = class {
10647
10812
  setAutonomy(threadRef, autonomy) {
10648
10813
  return this.setThreadOptions(threadRef, { autonomy });
10649
10814
  }
10815
+ /**
10816
+ * Open a Review chat tab on a worktree thread (same as the desktop Review button)
10817
+ * and send the merge-readiness prefill.
10818
+ */
10819
+ async requestReview(threadRef) {
10820
+ const { tab } = await requestReview(threadRef, (ref, prompt) => this.send(ref, prompt));
10821
+ this.emit({ type: "status_changed", threadId: tab.id, status: tab.status });
10822
+ return tab;
10823
+ }
10650
10824
  setThreadOptions(threadRef, patch) {
10651
10825
  const thread = this.requireThread(threadRef);
10652
10826
  const next = {};
10653
10827
  if (patch.autonomy !== void 0) next.autonomy = patch.autonomy;
10828
+ if (patch.effort !== void 0) next.effort = patch.effort;
10654
10829
  if (patch.fast !== void 0) next.fast = patch.fast;
10655
10830
  if (patch.planMode !== void 0) next.planMode = patch.planMode;
10656
10831
  if (patch.model !== void 0) next.model = patch.model;
@@ -10770,7 +10945,7 @@ var Orchestrator = class {
10770
10945
  updateThread(thread.id, { worktreePath: globalAgentCwd2() });
10771
10946
  return setStatus(thread.id, "idle");
10772
10947
  }
10773
- if (!(0, import_node_fs25.existsSync)(thread.worktreePath)) {
10948
+ if (!(0, import_node_fs26.existsSync)(thread.worktreePath)) {
10774
10949
  const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
10775
10950
  const { execa: execa7 } = await import("execa");
10776
10951
  const slug = thread.worktreePath.split("/").pop();
@@ -10828,6 +11003,7 @@ async function startOrchestration(opts) {
10828
11003
  agent: opts.agent,
10829
11004
  autonomy: opts.autonomy,
10830
11005
  model: opts.model,
11006
+ effort: opts.effort,
10831
11007
  fast: opts.fast,
10832
11008
  planMode: opts.planMode,
10833
11009
  attachments: opts.attachments
@@ -10845,6 +11021,7 @@ async function startOrchestration(opts) {
10845
11021
  title,
10846
11022
  autonomy: opts.autonomy,
10847
11023
  model: opts.model,
11024
+ effort: opts.effort,
10848
11025
  fast: opts.fast,
10849
11026
  planMode: opts.planMode,
10850
11027
  attachments: opts.attachments
@@ -10882,7 +11059,7 @@ init_coordinator_prompt();
10882
11059
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
10883
11060
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
10884
11061
  var import_zod = require("zod");
10885
- var import_node_path24 = require("path");
11062
+ var import_node_path25 = require("path");
10886
11063
  init_worktree();
10887
11064
  init_global_workspace();
10888
11065
 
@@ -10930,7 +11107,7 @@ async function startMcpServer() {
10930
11107
  async () => {
10931
11108
  const threads = orch.getThreads(true);
10932
11109
  const lines = threads.map((t) => {
10933
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path24.basename)(t.repoPath) || t.repoPath;
11110
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path25.basename)(t.repoPath) || t.repoPath;
10934
11111
  return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title} sideboard://thread/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}`;
10935
11112
  });
10936
11113
  return {
@@ -11273,6 +11450,34 @@ async function startMcpServer() {
11273
11450
  };
11274
11451
  }
11275
11452
  );
11453
+ server.tool(
11454
+ "request_review",
11455
+ "Start a merge-readiness Review on a worktree agent thread (same as the desktop Review button). Opens a new Review chat tab, optionally attaches .sideboard/attachments/Review request.md when present, and asks for Approve / Approve with nits / Request changes / Needs more information. Pass a worktree thread ref \u2014 not the orchestrator. Then wait_for_turn / get_turn_result on the returned review tab id.",
11456
+ { ref: import_zod.z.string().describe("Worktree thread id/ref to review") },
11457
+ async ({ ref }) => {
11458
+ try {
11459
+ const tab = await orch.requestReview(ref);
11460
+ const from = orch.getThread(ref);
11461
+ return {
11462
+ content: [
11463
+ {
11464
+ type: "text",
11465
+ text: JSON.stringify({
11466
+ id: tab.id,
11467
+ title: tab.title,
11468
+ status: tab.status,
11469
+ fromThreadId: from?.id ?? ref,
11470
+ link: `sideboard://thread/${tab.id}`
11471
+ })
11472
+ }
11473
+ ]
11474
+ };
11475
+ } catch (err) {
11476
+ const message = err instanceof Error ? err.message : String(err);
11477
+ return { content: [{ type: "text", text: message }], isError: true };
11478
+ }
11479
+ }
11480
+ );
11276
11481
  server.tool(
11277
11482
  "run_dev_script",
11278
11483
  "Start a .sideboard/.conductor run script for a thread (default script if name omitted); returns port",
@@ -11816,8 +12021,12 @@ init_injected_mcp();
11816
12021
  PASTE_ATTACH_MIN_CHARS,
11817
12022
  PASTE_ATTACH_MIN_LINES,
11818
12023
  PLAN_MODE_INSTRUCTION,
12024
+ REVIEW_REQUEST_NAME,
12025
+ REVIEW_REQUEST_PATH,
12026
+ REVIEW_REQUEST_PREFILL,
11819
12027
  SIDEBOARD_FORCE_STOP,
11820
12028
  SIDEBOARD_MCP_ALLOWED_TOOLS,
12029
+ THINKING_EFFORTS,
11821
12030
  addWorkspace,
11822
12031
  adoptThread,
11823
12032
  allAdapters,
@@ -11850,6 +12059,7 @@ init_injected_mcp();
11850
12059
  buildDiffCommentAttachment,
11851
12060
  buildForkTranscriptAttachment,
11852
12061
  buildPastedTextAttachment,
12062
+ buildReviewRequestAttachment,
11853
12063
  buildSessionSeed,
11854
12064
  buildWorkspaceScriptEnv,
11855
12065
  caffeinateWhileCloudConnectEnabled,
@@ -11924,6 +12134,8 @@ init_injected_mcp();
11924
12134
  getAgentSetupInfo,
11925
12135
  getBrightsySession,
11926
12136
  getDefaultAgent,
12137
+ getDefaultEffort,
12138
+ getDefaultFast,
11927
12139
  getDefaultModel,
11928
12140
  getDefaultRunScript,
11929
12141
  getDiff,
@@ -11968,6 +12180,7 @@ init_injected_mcp();
11968
12180
  isOrchestratorThread,
11969
12181
  isPidAlive,
11970
12182
  isPlaceholderBranch,
12183
+ isThinkingEffort,
11971
12184
  listAgentSetupInfo,
11972
12185
  listBranchCommits,
11973
12186
  listBranches,
@@ -12005,7 +12218,9 @@ init_injected_mcp();
12005
12218
  mergePr,
12006
12219
  mergeUsage,
12007
12220
  nextPastedTextName,
12221
+ nextThinkingEffort,
12008
12222
  normalizeParseResult,
12223
+ normalizeThinkingEffort,
12009
12224
  normalizeThread,
12010
12225
  normalizeTurnInput,
12011
12226
  normalizeWorktreePath,
@@ -12023,6 +12238,7 @@ init_injected_mcp();
12023
12238
  permissionMode,
12024
12239
  previewLand,
12025
12240
  pushBranch,
12241
+ readExistingReviewRequestFile,
12026
12242
  readSkillBody,
12027
12243
  readThread,
12028
12244
  readWorktreeFile,
@@ -12032,6 +12248,7 @@ init_injected_mcp();
12032
12248
  removeWorkspace,
12033
12249
  removeWorktree,
12034
12250
  repoSlug,
12251
+ requestReview,
12035
12252
  requireAgent,
12036
12253
  resolveClaudeExecutable,
12037
12254
  resolveConductorCursorAgentId,
@@ -12044,6 +12261,7 @@ init_injected_mcp();
12044
12261
  resolvePrSelector,
12045
12262
  resolveRepoRoot,
12046
12263
  resolveThreadDefaults,
12264
+ resolveThreadEffort,
12047
12265
  resolveWorktreeStartPoint,
12048
12266
  run,
12049
12267
  runArchiveScript,
@@ -12077,6 +12295,8 @@ init_injected_mcp();
12077
12295
  takenTeamSlugsForChatTab,
12078
12296
  takenTeamSlugsForOrchestration,
12079
12297
  taskMessageText,
12298
+ thinkingEffortBars,
12299
+ thinkingEffortLabel,
12080
12300
  threadDisplayLabel,
12081
12301
  threadFilePath,
12082
12302
  threadLockPath,