@sideboard-ai/core 0.1.107 → 0.1.110

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 (44) hide show
  1. package/dist/agents/cursor-runner.cjs +87 -12
  2. package/dist/agents/cursor-runner.js +38 -12
  3. package/dist/{agents-T4RHL5UX.js → agents-MQDW3YXL.js} +6 -6
  4. package/dist/{agents-4XQANGFO.js → agents-WK54VP7J.js} +8 -8
  5. package/dist/{app-settings-2WH6DVOW.js → app-settings-5XAGNDX7.js} +3 -1
  6. package/dist/{app-settings-6AXBWM3K.js → app-settings-J4LUWIRN.js} +4 -2
  7. package/dist/{chunk-HUKCGRAT.js → chunk-3UOKB6VQ.js} +47 -2
  8. package/dist/{chunk-SMWVSSE5.js → chunk-4EWPKYOU.js} +4 -4
  9. package/dist/{chunk-7ZTQHC2Q.js → chunk-4NR5FL46.js} +11 -1
  10. package/dist/{chunk-TLPJHLLM.js → chunk-4TR3HZFT.js} +1 -1
  11. package/dist/{chunk-VTTTV2LM.js → chunk-7KWYXGIU.js} +2 -2
  12. package/dist/{chunk-KGSVLZV6.js → chunk-A4VZXJEJ.js} +2 -0
  13. package/dist/{chunk-5XUKY2JY.js → chunk-AROMOP3C.js} +8 -16
  14. package/dist/{chunk-PZVA2VDF.js → chunk-C4KHDW3U.js} +2 -2
  15. package/dist/{chunk-3SIFRHJ3.js → chunk-EAAB4EK5.js} +1597 -1704
  16. package/dist/{chunk-GYFNFU62.js → chunk-KQBI5HNT.js} +8 -16
  17. package/dist/{chunk-P3BQ5DOL.js → chunk-KYOTBZ6S.js} +2 -0
  18. package/dist/{chunk-6HRR4T4P.js → chunk-RSIWPLRG.js} +483 -46
  19. package/dist/{chunk-EX4NZN3O.js → chunk-SGEVS5SY.js} +11 -1
  20. package/dist/{chunk-THXSFETX.js → chunk-VOD3HFLP.js} +4 -4
  21. package/dist/{chunk-XOYH3OMI.js → chunk-VOJSO3RM.js} +484 -55
  22. package/dist/{chunk-MMI4RJ5I.js → chunk-WIHKHR5R.js} +14 -3
  23. package/dist/{chunk-XEFHG6VG.js → chunk-XOZDAVOP.js} +1449 -1518
  24. package/dist/{chunk-LRO7YVLJ.js → chunk-YFAXVUY2.js} +2 -2
  25. package/dist/{chunk-6JJTMI7G.js → chunk-YXDR43ZC.js} +2 -2
  26. package/dist/{coordinator-prompt-4TUQUEHY.js → coordinator-prompt-AR66L3N4.js} +5 -5
  27. package/dist/{coordinator-prompt-YQWRXCPX.js → coordinator-prompt-BHMLWL64.js} +4 -4
  28. package/dist/{global-workspace-H37LFFXI.js → global-workspace-SKFODUQQ.js} +5 -5
  29. package/dist/{global-workspace-V6TMECDU.js → global-workspace-XSUFEIAQ.js} +6 -6
  30. package/dist/index.cjs +2388 -2006
  31. package/dist/index.d.cts +115 -26
  32. package/dist/index.d.ts +115 -26
  33. package/dist/index.js +141 -98
  34. package/dist/mcp/run-stdio.cjs +2354 -1988
  35. package/dist/mcp/run-stdio.js +90 -82
  36. package/dist/{orchestrator-DEHSKERK.js → orchestrator-FCZVCKBK.js} +11 -11
  37. package/dist/{orchestrator-2P7DX44Q.js → orchestrator-SCATSB3O.js} +8 -8
  38. package/dist/{thread-store-DQJGDKIJ.js → thread-store-LPTBVW5C.js} +1 -1
  39. package/dist/{thread-store-4OUEQ2DB.js → thread-store-OEALWU7Y.js} +1 -1
  40. package/dist/{workspaces-UPEVANU4.js → workspaces-HV3J4TTW.js} +7 -7
  41. package/dist/{workspaces-JU3P6FHB.js → workspaces-XAQVKTLO.js} +6 -6
  42. package/dist/{worktree-6MFKE465.js → worktree-N2EV24EE.js} +3 -3
  43. package/dist/{worktree-NR5YJG2E.js → worktree-XFJED3VU.js} +4 -4
  44. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -12,14 +12,17 @@ import {
12
12
  REVIEW_REQUEST_PATH,
13
13
  REVIEW_REQUEST_PREFILL,
14
14
  REVIEW_REQUEST_TEMPLATE,
15
+ REVIEW_SKILL_NAME,
16
+ REVIEW_SKILL_PATH,
17
+ SESSION_RESET_OCCUPANCY_TOKENS,
15
18
  SlackApiError,
16
19
  addStackLayerFromThread,
17
20
  adoptThread,
18
21
  agentGitPrompt,
19
22
  allocatePort,
20
23
  allocatePortRange,
21
- applyAgentEvent,
22
24
  applyCompaction,
25
+ applyPromptCacheTtlEnv,
23
26
  applyThreadIntoMain,
24
27
  armSchedules,
25
28
  attachmentFromAbsolutePath,
@@ -51,11 +54,11 @@ import {
51
54
  discoverSkills,
52
55
  dismissSlackReplyBadge,
53
56
  ensureReviewRequestFile,
57
+ ensureReviewSkillFile,
54
58
  estimateMessageChars,
55
59
  estimateThreadChars,
56
60
  expandComposerPrompt,
57
61
  extractiveSummary,
58
- finalizeParts,
59
62
  findOrphanWorktrees,
60
63
  findThreadForStackLayer,
61
64
  fireSchedule,
@@ -90,12 +93,14 @@ import {
90
93
  initStackFromThread,
91
94
  initializeGitRepository,
92
95
  inspectGitWorktree,
93
- isBrightsyNdjsonLine,
96
+ isCowboyThread,
94
97
  isDesktopHostAlive,
95
98
  isImageFilePath,
96
99
  isPidAlive,
100
+ isPrimaryCheckoutThread,
97
101
  isSlackExternalReplyPrompt,
98
102
  isThisProcessDesktopHost,
103
+ lastRequestOccupancy,
99
104
  listBranchCommits,
100
105
  listConductorWorkspaces,
101
106
  listLinearIssues,
@@ -108,11 +113,9 @@ import {
108
113
  listWorktreeFiles,
109
114
  loadAgentInstructions,
110
115
  maybeCompactContext,
111
- normalizeParseResult,
112
116
  openPrStackLayers,
113
117
  openStackLayer,
114
118
  parseDurationMs,
115
- partsToAssistantText,
116
119
  pendingSlackExternalReplies,
117
120
  permalinkForSlackReplyBadge,
118
121
  previewLand,
@@ -142,6 +145,8 @@ import {
142
145
  setSlackReplyTarget,
143
146
  shouldCompactContext,
144
147
  shouldRefreshReviewRequestTemplate,
148
+ shouldRemoveWorktreeOnTeardown,
149
+ shouldResetSessionForOccupancy,
145
150
  shouldRunWorktreeCleanup,
146
151
  slackApi,
147
152
  slackArchiveUrl,
@@ -154,21 +159,18 @@ import {
154
159
  stageBuffersAsAttachments,
155
160
  startDevServer,
156
161
  startOrchestration,
157
- stripBrightsyNdjsonNoise,
158
162
  summarizeConversation,
159
163
  takenTeamSlugsForChatTab,
160
164
  thisProcessShouldDrainAgentQueues,
161
165
  threadsSharingWorktree,
162
- toolDescription,
163
- toolDetail,
164
- toolFilePath,
165
166
  updateSchedule,
166
167
  upsertSlackWorkspace,
167
168
  waitForPidExit,
168
169
  withAgentInstructions,
169
170
  worktreeCleanupSettings,
171
+ wrapReviewSkillMarkdown,
170
172
  writeWorktreeFile
171
- } from "./chunk-3SIFRHJ3.js";
173
+ } from "./chunk-EAAB4EK5.js";
172
174
  import {
173
175
  BRIGHTSY_MCP_ALLOWED_TOOLS,
174
176
  CLAUDE_MODEL_CATALOG,
@@ -176,7 +178,9 @@ import {
176
178
  PLAN_MODE_INSTRUCTION,
177
179
  SIDEBOARD_MCP_ALLOWED_TOOLS,
178
180
  SIDEBOARD_MCP_PROFILE_ENV,
181
+ WORKTREE_MCP_TOOLS,
179
182
  allAdapters,
183
+ applyAgentEvent,
180
184
  applyTurnUsage,
181
185
  brightsyAdapter,
182
186
  brightsyMcpAllowedTools,
@@ -190,6 +194,7 @@ import {
190
194
  decodeBrightsyTarget,
191
195
  dropCachedPrefixOnResume,
192
196
  encodeBrightsyTarget,
197
+ finalizeParts,
193
198
  findInvalidCacheControlTtlOrder,
194
199
  flattenTurnInput,
195
200
  fromInclusiveInputUsage,
@@ -197,8 +202,10 @@ import {
197
202
  getAgentSetupInfo,
198
203
  installAgent,
199
204
  isBrightsyConnected,
205
+ isBrightsyNdjsonLine,
200
206
  isCursorAutoModel,
201
207
  isSessionQuotaLimit,
208
+ isSubagentToolName,
202
209
  listAgentSetupInfo,
203
210
  listBrightsyChatTargets,
204
211
  listCodexModels,
@@ -209,11 +216,14 @@ import {
209
216
  mcpAllowTools,
210
217
  mcpAuthWarnings,
211
218
  mergeUsage,
219
+ messagePartParentId,
220
+ normalizeParseResult,
212
221
  normalizeTurnInput,
213
222
  openInSystemTerminal,
214
223
  opencodeAdapter,
215
224
  parseMcpList,
216
225
  parseSessionQuotaResetAt,
226
+ partsToAssistantText,
217
227
  permissionMode,
218
228
  prepareTerminalCommand,
219
229
  promptMentionsBrightsy,
@@ -225,10 +235,16 @@ import {
225
235
  sanitizeMcpServerName,
226
236
  shouldInjectBrightsyMcp,
227
237
  sideboardMcpProfile,
238
+ stripBrightsyNdjsonNoise,
228
239
  threadRequestsBrightsyMcp,
240
+ toolDescription,
241
+ toolDetail,
242
+ toolFilePath,
229
243
  totalTokens,
244
+ withEventParentId,
245
+ withEventsParentId,
230
246
  writeInjectedMcpConfig
231
- } from "./chunk-6HRR4T4P.js";
247
+ } from "./chunk-RSIWPLRG.js";
232
248
  import {
233
249
  brightsyConfigPath,
234
250
  brightsyMcpServerName,
@@ -247,7 +263,7 @@ import {
247
263
  listWorkspaces,
248
264
  removeWorkspace,
249
265
  syncWorkspacesFromThreads
250
- } from "./chunk-VTTTV2LM.js";
266
+ } from "./chunk-7KWYXGIU.js";
251
267
  import {
252
268
  CLOUD_COORDINATOR_BUSY_REPLY,
253
269
  CLOUD_COORDINATOR_STOPPED_REPLY,
@@ -275,7 +291,7 @@ import {
275
291
  parseForceStopMessage,
276
292
  slackCoordinatorSourceRef,
277
293
  takenTeamSlugsForOrchestration
278
- } from "./chunk-SMWVSSE5.js";
294
+ } from "./chunk-4EWPKYOU.js";
279
295
  import {
280
296
  COORDINATOR_TOOL_PLAYBOOK,
281
297
  SLACK_REPLY_FORMATTING,
@@ -284,7 +300,7 @@ import {
284
300
  enrichWorkspacesWithGithub,
285
301
  ensureGlobalCoordinatorCwd,
286
302
  formatWorkspaceInventory
287
- } from "./chunk-GYFNFU62.js";
303
+ } from "./chunk-KQBI5HNT.js";
288
304
  import {
289
305
  LEGACY_PLAN_FILE_REL,
290
306
  PLAN_FILE_NAME,
@@ -296,11 +312,11 @@ import {
296
312
  resolvePlanMarkdown,
297
313
  writePlanFile
298
314
  } from "./chunk-QTUESPAW.js";
299
- import "./chunk-MMI4RJ5I.js";
315
+ import "./chunk-WIHKHR5R.js";
300
316
  import {
301
317
  cursorSdkMessageToEvents,
302
318
  parseCursorRunnerLine
303
- } from "./chunk-HUKCGRAT.js";
319
+ } from "./chunk-3UOKB6VQ.js";
304
320
  import {
305
321
  caffeinateHoldPath,
306
322
  getCaffeinateHold,
@@ -388,7 +404,7 @@ import {
388
404
  worktreeDisplayLabel,
389
405
  worktreeDisplayLabelForGroup,
390
406
  worktreeNameFromPath
391
- } from "./chunk-PZVA2VDF.js";
407
+ } from "./chunk-C4KHDW3U.js";
392
408
  import {
393
409
  ATTACHMENTS_DIR,
394
410
  LEGACY_ATTACHMENTS_DIR,
@@ -414,6 +430,7 @@ import {
414
430
  childEnvWithAppSettings,
415
431
  claudeChromeEnabled,
416
432
  claudeUserSettingsPath,
433
+ cowboyModeEnabled,
417
434
  deleteBranchOnPurgeEnabled,
418
435
  disconnectLinearConnection,
419
436
  ensureSlackDeviceIdentity,
@@ -455,10 +472,10 @@ import {
455
472
  updateDefaultsSettings,
456
473
  updateIntegrationsSettings,
457
474
  updateOpencodeSettings
458
- } from "./chunk-7ZTQHC2Q.js";
475
+ } from "./chunk-4NR5FL46.js";
459
476
  import {
460
477
  stripNestedElectronEnv
461
- } from "./chunk-TLPJHLLM.js";
478
+ } from "./chunk-4TR3HZFT.js";
462
479
  import "./chunk-JT7R45JB.js";
463
480
  import {
464
481
  appendMessage,
@@ -473,7 +490,7 @@ import {
473
490
  updateThread,
474
491
  withThreadLock,
475
492
  writeThread
476
- } from "./chunk-KGSVLZV6.js";
493
+ } from "./chunk-A4VZXJEJ.js";
477
494
  import {
478
495
  THINKING_EFFORTS,
479
496
  isThinkingEffort,
@@ -2225,7 +2242,7 @@ async function startMcpServer() {
2225
2242
  );
2226
2243
  }
2227
2244
  try {
2228
- const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-6AXBWM3K.js");
2245
+ const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-J4LUWIRN.js");
2229
2246
  orch.setMaxConcurrent(maxConcurrentAgents2());
2230
2247
  } catch {
2231
2248
  }
@@ -2241,74 +2258,77 @@ async function startMcpServer() {
2241
2258
  name: "sideboard",
2242
2259
  version: "0.1.0"
2243
2260
  });
2244
- server.tool(
2245
- "list_workspaces",
2246
- "List registered Sideboard workspaces (repos). Each line is name, path, and github:owner/repo when resolvable \u2014 use path as repoPath for list_branches/list_prs/list_issues/create_thread.",
2247
- {},
2248
- async () => {
2249
- const workspaces = orch.listWorkspaces();
2250
- const lines = await Promise.all(
2251
- workspaces.map(async (w) => {
2252
- const slug = await resolveGithubRepoSlug(w.path).catch(() => null);
2253
- return slug ? `${w.name} ${w.path} github:${slug}` : `${w.name} ${w.path}`;
2254
- })
2255
- );
2256
- return {
2257
- content: [
2258
- { type: "text", text: lines.join("\n") || "(no workspaces)" }
2259
- ]
2260
- };
2261
- }
2262
- );
2263
- server.tool(
2264
- "list_threads",
2265
- "List Sideboard threads across all workspaces (one summary line each \u2014 token-frugal). Each line ends with sideboard://thread/<id> \u2014 use that URL in markdown links so the UI can open the chat.",
2266
- {},
2267
- async () => {
2268
- const threads = orch.getThreads(true);
2269
- const lines = threads.map((t) => {
2270
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : basename(t.repoPath) || t.repoPath;
2261
+ const worktreeProfile = sideboardMcpProfile() === "worktree";
2262
+ if (!worktreeProfile) {
2263
+ server.tool(
2264
+ "list_workspaces",
2265
+ "List registered Sideboard workspaces (repos). Each line is name, path, and github:owner/repo when resolvable \u2014 use path as repoPath for list_branches/list_prs/list_issues/create_thread.",
2266
+ {},
2267
+ async () => {
2268
+ const workspaces = orch.listWorkspaces();
2269
+ const lines = await Promise.all(
2270
+ workspaces.map(async (w) => {
2271
+ const slug = await resolveGithubRepoSlug(w.path).catch(() => null);
2272
+ return slug ? `${w.name} ${w.path} github:${slug}` : `${w.name} ${w.path}`;
2273
+ })
2274
+ );
2275
+ return {
2276
+ content: [
2277
+ { type: "text", text: lines.join("\n") || "(no workspaces)" }
2278
+ ]
2279
+ };
2280
+ }
2281
+ );
2282
+ server.tool(
2283
+ "list_threads",
2284
+ "List Sideboard threads across all workspaces (one summary line each \u2014 token-frugal). Each line ends with sideboard://thread/<id> \u2014 use that URL in markdown links so the UI can open the chat.",
2285
+ {},
2286
+ async () => {
2287
+ const threads = orch.getThreads(true);
2288
+ const lines = threads.map((t) => {
2289
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : basename(t.repoPath) || t.repoPath;
2290
+ const live = t.status === "running" || t.status === "queued" ? readTurnLive(t.id) : null;
2291
+ const progress = live?.summary ? ` ${live.summary}` : "";
2292
+ 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}` : ""}${progress}`;
2293
+ });
2294
+ return {
2295
+ content: [{ type: "text", text: lines.join("\n") || "(no threads)" }]
2296
+ };
2297
+ }
2298
+ );
2299
+ server.tool(
2300
+ "get_thread",
2301
+ "Get a compact thread summary by id/ref. While running, includes progress (last tool/thinking) and lastActivityAt.",
2302
+ { ref: z4.string() },
2303
+ async ({ ref }) => {
2304
+ const t = orch.getThread(ref);
2305
+ if (!t) {
2306
+ return { content: [{ type: "text", text: `Thread not found: ${ref}` }], isError: true };
2307
+ }
2271
2308
  const live = t.status === "running" || t.status === "queued" ? readTurnLive(t.id) : null;
2272
- const progress = live?.summary ? ` ${live.summary}` : "";
2273
- 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}` : ""}${progress}`;
2274
- });
2275
- return {
2276
- content: [{ type: "text", text: lines.join("\n") || "(no threads)" }]
2277
- };
2278
- }
2279
- );
2280
- server.tool(
2281
- "get_thread",
2282
- "Get a compact thread summary by id/ref. While running, includes progress (last tool/thinking) and lastActivityAt.",
2283
- { ref: z4.string() },
2284
- async ({ ref }) => {
2285
- const t = orch.getThread(ref);
2286
- if (!t) {
2287
- return { content: [{ type: "text", text: `Thread not found: ${ref}` }], isError: true };
2309
+ const summary = {
2310
+ id: t.id,
2311
+ title: t.title,
2312
+ status: t.status,
2313
+ agent: t.agent,
2314
+ sourceType: t.sourceType,
2315
+ sourceRef: t.sourceRef,
2316
+ branchName: t.branchName,
2317
+ worktreePath: t.worktreePath,
2318
+ sessionId: t.sessionId,
2319
+ queueLength: t.queue.length,
2320
+ messageCount: t.messages.length,
2321
+ devPort: t.devPort,
2322
+ prUrl: t.prUrl,
2323
+ lastError: t.lastError ?? null,
2324
+ stillRunning: t.status === "running" || t.status === "queued",
2325
+ progress: live?.summary ?? null,
2326
+ lastActivityAt: live?.updatedAt ?? null
2327
+ };
2328
+ return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
2288
2329
  }
2289
- const live = t.status === "running" || t.status === "queued" ? readTurnLive(t.id) : null;
2290
- const summary = {
2291
- id: t.id,
2292
- title: t.title,
2293
- status: t.status,
2294
- agent: t.agent,
2295
- sourceType: t.sourceType,
2296
- sourceRef: t.sourceRef,
2297
- branchName: t.branchName,
2298
- worktreePath: t.worktreePath,
2299
- sessionId: t.sessionId,
2300
- queueLength: t.queue.length,
2301
- messageCount: t.messages.length,
2302
- devPort: t.devPort,
2303
- prUrl: t.prUrl,
2304
- lastError: t.lastError ?? null,
2305
- stillRunning: t.status === "running" || t.status === "queued",
2306
- progress: live?.summary ?? null,
2307
- lastActivityAt: live?.updatedAt ?? null
2308
- };
2309
- return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
2310
- }
2311
- );
2330
+ );
2331
+ }
2312
2332
  server.tool(
2313
2333
  "present_artifact",
2314
2334
  "Show an HTML, SVG, markdown, or React document in Sideboard\u2019s Claude-style side column (desktop). Use instead of claude.ai\u2019s artifact tool \u2014 pass the full document content. Prefer type=html for interactive pages. For type=react, pass a single component module that `export default`s a component (JSX/TSX ok) \u2014 Sideboard bootstraps React/ReactDOM/Babel and renders it; only `react`/`react-dom` imports are available, no other npm packages.",
@@ -2437,12 +2457,12 @@ async function startMcpServer() {
2437
2457
  return { content: [{ type: "text", text: JSON.stringify(payload) }] };
2438
2458
  }
2439
2459
  );
2440
- registerSlackTools(server);
2441
- registerLinearTools(server);
2442
- if (sideboardMcpProfile() !== "worktree") {
2460
+ if (!worktreeProfile) {
2461
+ registerSlackTools(server);
2462
+ registerLinearTools(server);
2443
2463
  registerScheduleTools(server);
2444
2464
  const { getCaffeinateHold: getCaffeinateHold2, setCaffeinateHold: setCaffeinateHold2 } = await import("./caffeinate-hold-X3JNPR42.js");
2445
- const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await import("./app-settings-6AXBWM3K.js");
2465
+ const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await import("./app-settings-J4LUWIRN.js");
2446
2466
  const accountDefaults = resolveThreadDefaults2();
2447
2467
  const accountDefaultsHint = `Account defaults: agent=${accountDefaults.agent}, model=${accountDefaults.model?.trim() || "Auto"}, effort=${accountDefaults.effort}`;
2448
2468
  server.tool(
@@ -2485,7 +2505,7 @@ async function startMcpServer() {
2485
2505
  );
2486
2506
  server.tool(
2487
2507
  "create_thread",
2488
- `Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces. From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Setup (settings.toml, .cursor/worktrees.json, or script/setup) runs in the background in parallel with the first turn. Then use send_to_thread to chat.`,
2508
+ `Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces. cowboy=true uses the project folder on the default branch (no isolated worktree; land is commit+push). From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Setup (settings.toml, .cursor/worktrees.json, or script/setup) runs in the background in parallel with the first turn (skipped for cowboy). Then use send_to_thread to chat.`,
2489
2509
  {
2490
2510
  sourceType: z4.enum(["branch", "pr", "ticket"]),
2491
2511
  sourceRef: z4.string(),
@@ -2495,6 +2515,9 @@ async function startMcpServer() {
2495
2515
  ),
2496
2516
  repoPath: z4.string(),
2497
2517
  title: z4.string().optional(),
2518
+ cowboy: z4.boolean().optional().describe(
2519
+ "If true, work in the project folder on the default branch (no thread/* worktree). Requires Settings \u2192 Advanced \u2192 Cowboy mode. Land is commit+push to that branch. Archive does not delete the folder."
2520
+ ),
2498
2521
  parentThreadId: z4.string().optional().describe(
2499
2522
  "Orchestration: omit (preferred) or pass YOUR chat id from the turn reminder / AGENTS.md. Do not invent uuids."
2500
2523
  )
@@ -2555,7 +2578,8 @@ async function startMcpServer() {
2555
2578
  fast: opts.fast,
2556
2579
  repoPath: args.repoPath,
2557
2580
  title: args.title,
2558
- parentThreadId: parentId || null
2581
+ parentThreadId: parentId || null,
2582
+ cowboy: args.cowboy || void 0
2559
2583
  }),
2560
2584
  CREATE_THREAD_TIMEOUT_MS,
2561
2585
  "create_thread"
@@ -2573,6 +2597,7 @@ async function startMcpServer() {
2573
2597
  agent: thread.agent,
2574
2598
  model: thread.model,
2575
2599
  status: thread.status,
2600
+ cowboy: Boolean(thread.cowboy),
2576
2601
  link: `sideboard://thread/${thread.id}`,
2577
2602
  parentThreadId: thread.parentThreadId,
2578
2603
  ...agentCoercedFrom ? {
@@ -2793,7 +2818,7 @@ async function startMcpServer() {
2793
2818
  );
2794
2819
  server.tool(
2795
2820
  "request_review",
2796
- 'Start a merge-readiness Review on a worktree agent thread (same as the desktop Review button). Opens a new Review chat tab, attaches .sideboard/review.md when present (else local Review request.md / stock template), and sends "Review changes in this workspace." Expect Approve / Approve with nits / Request changes / Needs more information. Pass a worktree thread ref \u2014 not the orchestrator. Then wait_for_turn (loop while stillRunning) / get_turn_result on the returned review tab id.',
2821
+ 'Start a merge-readiness Review on a worktree agent thread (same as the desktop Review button). Opens a new Review chat tab, attaches .claude/skills/review/SKILL.md when present (else seeds that skill from .sideboard/review.md or the stock template), and sends "Review changes in this workspace." Expect Approve / Approve with nits / Request changes / Needs more information. Pass a worktree thread ref \u2014 not the orchestrator. Then wait_for_turn (loop while stillRunning) / get_turn_result on the returned review tab id.',
2797
2822
  { ref: z4.string().describe("Worktree thread id/ref to review") },
2798
2823
  async ({ ref }) => {
2799
2824
  try {
@@ -4534,10 +4559,11 @@ function slackReplyThreadTs(msg) {
4534
4559
  }
4535
4560
  var SLACK_PROGRESS_DELAY_MS = 2e4;
4536
4561
  var SLACK_PROGRESS_EDIT_MS = 15e3;
4562
+ var SLACK_PROGRESS_PLACEHOLDER = "Thinking\u2026";
4537
4563
  function formatSlackWorkingText(summary) {
4538
4564
  const line = (summary ?? "").trim();
4539
- if (!line || /^working/i.test(line)) return "Working\u2026";
4540
- return `Working\u2026 ${line}`;
4565
+ if (!line || /^(working|thinking)/i.test(line)) return SLACK_PROGRESS_PLACEHOLDER;
4566
+ return line;
4541
4567
  }
4542
4568
  var SLACK_SEEN_REACTION = "eyes";
4543
4569
  function writeTokenForTeam(teamId) {
@@ -4673,7 +4699,7 @@ function startSlackTurnProgress(msg, threadId, opts) {
4673
4699
  };
4674
4700
  const postWorking = async () => {
4675
4701
  if (!stillLive()) return;
4676
- const summary = readTurnLive(threadId())?.summary ?? "Working\u2026";
4702
+ const summary = readTurnLive(threadId())?.summary ?? SLACK_PROGRESS_PLACEHOLDER;
4677
4703
  const body = formatSlackWorkingText(summary);
4678
4704
  try {
4679
4705
  const posted = await postSlackText(target, signForThisMac(body), opts);
@@ -4691,7 +4717,7 @@ function startSlackTurnProgress(msg, threadId, opts) {
4691
4717
  };
4692
4718
  const editWorking = async () => {
4693
4719
  if (!postedTs || !stillLive()) return;
4694
- const summary = readTurnLive(threadId())?.summary ?? "Working\u2026";
4720
+ const summary = readTurnLive(threadId())?.summary ?? SLACK_PROGRESS_PLACEHOLDER;
4695
4721
  const body = formatSlackWorkingText(summary);
4696
4722
  if (body === lastBody) return;
4697
4723
  lastBody = body;
@@ -5594,6 +5620,9 @@ export {
5594
5620
  REVIEW_REQUEST_PATH,
5595
5621
  REVIEW_REQUEST_PREFILL,
5596
5622
  REVIEW_REQUEST_TEMPLATE,
5623
+ REVIEW_SKILL_NAME,
5624
+ REVIEW_SKILL_PATH,
5625
+ SESSION_RESET_OCCUPANCY_TOKENS,
5597
5626
  SIDEBOARD_FORCE_STOP,
5598
5627
  SIDEBOARD_MCP_ALLOWED_TOOLS,
5599
5628
  SIDEBOARD_MCP_PROFILE_ENV,
@@ -5608,6 +5637,7 @@ export {
5608
5637
  SlackOAuthCancelledError,
5609
5638
  SlackRelayHub,
5610
5639
  THINKING_EFFORTS,
5640
+ WORKTREE_MCP_TOOLS,
5611
5641
  ackSlackInboundSeen,
5612
5642
  addPrStackLayer,
5613
5643
  addStackLayerFromThread,
@@ -5627,6 +5657,7 @@ export {
5627
5657
  applyAppEnvironment,
5628
5658
  applyCompaction,
5629
5659
  applyGithubGitAuthEnv,
5660
+ applyPromptCacheTtlEnv,
5630
5661
  applyThreadIntoMain,
5631
5662
  applyTurnUsage,
5632
5663
  armSchedules,
@@ -5688,6 +5719,7 @@ export {
5688
5719
  coordinatorTurnReminder,
5689
5720
  copyConfiguredFiles,
5690
5721
  countCacheControlBlocks,
5722
+ cowboyModeEnabled,
5691
5723
  createChatTab,
5692
5724
  createEmptyThread,
5693
5725
  createExistingBranchWorktree,
@@ -5726,6 +5758,7 @@ export {
5726
5758
  ensureGhPreferOrigin,
5727
5759
  ensureGlobalCoordinatorCwd,
5728
5760
  ensureReviewRequestFile,
5761
+ ensureReviewSkillFile,
5729
5762
  ensureSlackCoordinator,
5730
5763
  ensureSlackDeviceIdentity,
5731
5764
  ensureWorkspace,
@@ -5837,6 +5870,7 @@ export {
5837
5870
  isBrightsyNdjsonLine,
5838
5871
  isCloudCoordinatorThread,
5839
5872
  isConductorBundledCli,
5873
+ isCowboyThread,
5840
5874
  isCursorAutoModel,
5841
5875
  isDefaultishSourceRef,
5842
5876
  isDesktopHostAlive,
@@ -5855,15 +5889,18 @@ export {
5855
5889
  isPlaceholderBranch,
5856
5890
  isPrNotMergeableError,
5857
5891
  isPresentPlanToolName,
5892
+ isPrimaryCheckoutThread,
5858
5893
  isSessionQuotaLimit,
5859
5894
  isSideboardScratchPath,
5860
5895
  isSlackCoordinatorThread,
5861
5896
  isSlackExternalReplyPrompt,
5862
5897
  isSlackOAuthCancelled,
5898
+ isSubagentToolName,
5863
5899
  isThinkingEffort,
5864
5900
  isThisProcessDesktopHost,
5865
5901
  isThreadCaffeinated,
5866
5902
  isWorkspaceScratchPath,
5903
+ lastRequestOccupancy,
5867
5904
  linearAuthorizationHeader,
5868
5905
  linearGraphql,
5869
5906
  linearOAuthAuthorizeUrl,
@@ -5913,6 +5950,7 @@ export {
5913
5950
  mergePrStack,
5914
5951
  mergeSideboardIntoMcpServersJson,
5915
5952
  mergeUsage,
5953
+ messagePartParentId,
5916
5954
  nextPastedTextName,
5917
5955
  nextThinkingEffort,
5918
5956
  nonInteractiveGitProcessEnv,
@@ -6031,6 +6069,8 @@ export {
6031
6069
  shouldCompactContext,
6032
6070
  shouldInjectBrightsyMcp,
6033
6071
  shouldRefreshReviewRequestTemplate,
6072
+ shouldRemoveWorktreeOnTeardown,
6073
+ shouldResetSessionForOccupancy,
6034
6074
  shouldRunWorktreeCleanup,
6035
6075
  sideboardHomeDir,
6036
6076
  sideboardMcpProfile,
@@ -6100,6 +6140,8 @@ export {
6100
6140
  waitForPidExit,
6101
6141
  warmGithubAgentAuth,
6102
6142
  withAgentInstructions,
6143
+ withEventParentId,
6144
+ withEventsParentId,
6103
6145
  withExportedPath,
6104
6146
  withThreadLock,
6105
6147
  workspaceSettingsSourceLabel,
@@ -6108,6 +6150,7 @@ export {
6108
6150
  worktreeDisplayLabelForGroup,
6109
6151
  worktreeNameFromPath,
6110
6152
  worktreesRoot,
6153
+ wrapReviewSkillMarkdown,
6111
6154
  writeInjectedMcpConfig,
6112
6155
  writePlanFile,
6113
6156
  writeThread,