@sideboard-ai/core 0.1.242 → 0.1.244

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 (52) hide show
  1. package/dist/{abletime-VSV6AUBV.js → abletime-CWIJ7INC.js} +4 -4
  2. package/dist/{abletime-UX4VUENQ.js → abletime-OI6FNSXX.js} +4 -4
  3. package/dist/{abletime-oauth-DKBUZV2C.js → abletime-oauth-CHVTUZBR.js} +3 -3
  4. package/dist/{abletime-oauth-QMDV45JC.js → abletime-oauth-PUIPZTA4.js} +3 -3
  5. package/dist/{abletime-rest-NL56UVK5.js → abletime-rest-32NIVXAY.js} +3 -3
  6. package/dist/{abletime-rest-VPBC2XS5.js → abletime-rest-APJUKFKL.js} +3 -3
  7. package/dist/{agents-PBRIHUYM.js → agents-BQZ2CHXK.js} +9 -5
  8. package/dist/{agents-CDQCQVWU.js → agents-Q23R4WOR.js} +9 -5
  9. package/dist/{app-settings-AGDLF75Z.js → app-settings-652J57CX.js} +1 -1
  10. package/dist/{app-settings-I27UBVI4.js → app-settings-VOPXJMGV.js} +1 -1
  11. package/dist/{chunk-3Q4PVZ3U.js → chunk-2QRU4IFI.js} +32 -5
  12. package/dist/{chunk-3PGFAVFL.js → chunk-43F44EKX.js} +2 -2
  13. package/dist/{chunk-LRMJ6V6U.js → chunk-4HMV53AB.js} +1506 -1465
  14. package/dist/{chunk-OKHOYI53.js → chunk-576S3HJ7.js} +5 -5
  15. package/dist/{chunk-TB6UMHIF.js → chunk-5ZFULOTC.js} +10 -2
  16. package/dist/{chunk-3AJUH66R.js → chunk-6I5YQTNK.js} +2 -1
  17. package/dist/{chunk-NJ5OXOTN.js → chunk-7HOKP4GR.js} +2 -1
  18. package/dist/{chunk-DXY4K5MP.js → chunk-BL2UGKWU.js} +3 -3
  19. package/dist/{chunk-CWHMLCLN.js → chunk-C64YQAA6.js} +3 -3
  20. package/dist/{chunk-QXYWLO6W.js → chunk-CYYQ6577.js} +28 -5
  21. package/dist/{chunk-O3UAQAYA.js → chunk-E6C5NR46.js} +10 -2
  22. package/dist/{chunk-CRAXJAYJ.js → chunk-G45QP2ZD.js} +3 -3
  23. package/dist/{chunk-BILEJG3V.js → chunk-GFRC6JQN.js} +5 -5
  24. package/dist/{chunk-YXOOSFAF.js → chunk-IMO7AZI4.js} +2 -2
  25. package/dist/{chunk-DJU54RYW.js → chunk-PGPSIEMW.js} +13 -0
  26. package/dist/{chunk-P3DCZRER.js → chunk-PPJ5JTWA.js} +1 -0
  27. package/dist/{chunk-5ELC3KK3.js → chunk-QNJXJIWJ.js} +5 -5
  28. package/dist/{chunk-JFOPOMK7.js → chunk-WDDUIGFK.js} +13 -0
  29. package/dist/{chunk-IVXPXYH2.js → chunk-WURF67ID.js} +5 -5
  30. package/dist/{chunk-R3YKDTVE.js → chunk-YJJ2A5CI.js} +1572 -1529
  31. package/dist/{chunk-QLWMHQPH.js → chunk-YLGBQVRK.js} +1 -0
  32. package/dist/{coordinator-prompt-5UINTEA6.js → coordinator-prompt-WQIICPT6.js} +4 -4
  33. package/dist/{coordinator-prompt-ATK73HYU.js → coordinator-prompt-ZBYRREHD.js} +4 -4
  34. package/dist/{global-workspace-ZJBBICFJ.js → global-workspace-2N6KISDO.js} +4 -4
  35. package/dist/{global-workspace-TD5SARNW.js → global-workspace-3SQU4GL4.js} +4 -4
  36. package/dist/index.cjs +590 -470
  37. package/dist/index.d.cts +50 -3
  38. package/dist/index.d.ts +50 -3
  39. package/dist/index.js +73 -39
  40. package/dist/mcp/run-stdio.cjs +1649 -1552
  41. package/dist/mcp/run-stdio.js +51 -37
  42. package/dist/{orchestrator-VYNPNHY4.js → orchestrator-ABF6QFE6.js} +7 -7
  43. package/dist/{orchestrator-66ZFQHW5.js → orchestrator-ZJ6SYGW7.js} +7 -7
  44. package/dist/{plan-file-UUKCZEYP.js → plan-file-7MMIPV7Y.js} +9 -1
  45. package/dist/{plan-file-2EPHYRX7.js → plan-file-CKXUFTQ2.js} +9 -1
  46. package/dist/{thread-store-YOPKY74K.js → thread-store-JQB7KZJR.js} +1 -1
  47. package/dist/{thread-store-AYPBEZT5.js → thread-store-SCV2IZYS.js} +1 -1
  48. package/dist/{workspaces-JX5R4V24.js → workspaces-CFI7XVAE.js} +4 -4
  49. package/dist/{workspaces-4SFSCYKT.js → workspaces-QLKWW3O2.js} +4 -4
  50. package/dist/{worktree-AGVPKDBH.js → worktree-4UAOZUJ4.js} +5 -3
  51. package/dist/{worktree-Y5FES5D6.js → worktree-PK3QETXO.js} +5 -3
  52. package/package.json +1 -1
@@ -8,7 +8,7 @@ import {
8
8
  resolveRepoRoot,
9
9
  takenSlugsFromThread,
10
10
  teamSlugFromName
11
- } from "./chunk-TB6UMHIF.js";
11
+ } from "./chunk-5ZFULOTC.js";
12
12
  import {
13
13
  ATTACHMENTS_DIR,
14
14
  attachmentsGitignoreBody
@@ -18,7 +18,7 @@ import {
18
18
  listThreads,
19
19
  updateThread,
20
20
  writeThread
21
- } from "./chunk-NJ5OXOTN.js";
21
+ } from "./chunk-7HOKP4GR.js";
22
22
  import {
23
23
  assertOrchestratorCapableAgent,
24
24
  formatAccountProfilePlaybookLine,
@@ -31,7 +31,7 @@ import {
31
31
  resolveThreadDefaults,
32
32
  resolveViewerProfile,
33
33
  resolveViewerProfileForRepo
34
- } from "./chunk-QLWMHQPH.js";
34
+ } from "./chunk-YLGBQVRK.js";
35
35
  import {
36
36
  appDataDir,
37
37
  globalAgentCwd,
@@ -327,7 +327,7 @@ function coordinatorGreenfieldPlaybook(reposDir) {
327
327
  "- Examples:",
328
328
  ` - Clone: \`git clone <url> ${reposDir}/<name>\``,
329
329
  ` - New GitHub repo: \`gh repo create <owner>/<name> --private --clone -- ${reposDir}/<name>\` (or mkdir + git init + gh repo create + remote add + push)`,
330
- "- Then: add_workspace with that absolute path \u2192 create_thread (repoPath + parentThreadId) \u2192 send_to_thread (build) \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft (or send_to_thread `gh pr create --draft -R <origin-owner/name>`).",
330
+ "- Then: add_workspace with that absolute path \u2192 create_thread (repoPath + parentThreadId) \u2192 send_to_thread (build) \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft (or send_to_thread `gh pr create --draft --assignee @me -R <origin-owner/name>`).",
331
331
  "- Always target the child worktree's **origin** (`github:` slug from list_workspaces / `git remote get-url origin` in that worktree). Never open PRs against `upstream`.",
332
332
  "- Do coding work in the child worktree thread, not by editing files in this home cwd."
333
333
  ].join("\n");
@@ -375,7 +375,7 @@ var COORDINATOR_TOOL_PLAYBOOK = [
375
375
  '- request_review \u2014 open a Review chat tab on a worktree thread (attaches .claude/skills/review/SKILL.md when present, else .context/review.md copied from .sideboard/review.md / stock; sends "Review changes in this workspace."); then wait_for_turn (loop while stillRunning) / get_turn_result on the returned id. The review stays in that chat so they can read it and type next steps \u2014 do not tell the child to comment or update the PR or ticket.',
376
376
  "- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge \u2014 same prompts as the desktop git buttons (Resolve, Create PR, \u2026). Always steers the worktree agent; then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If the user gave a goal (Greptile 5/5, CI green), send_to_thread that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
377
377
  '- Merge (`ask_git` action=merge / send_to_thread "Merge PR.") only when the user explicitly asked to merge that PR. Do not merge because the work looks done, CI is green, or a typical flow includes it.',
378
- '- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
378
+ '- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft --assignee @me -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
379
379
  "Process guides:",
380
380
  "- Long child jobs (pack, test, deploy, anything that may run more than ~30s): workers always have `/long-running` (Sideboard product skill). Tell them to detach and wait; they may `stop_job` if it hangs or is doing the wrong thing; do not ask the human to poll.",
381
381
  "- Recurring multi-item / fan-out: if the child worktree has `.claude/skills/graph-engineering/SKILL.md`, tell the worker to follow it (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch three threads.",
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-D6JWYJ4P.js";
6
6
  import {
7
7
  listThreads
8
- } from "./chunk-NJ5OXOTN.js";
8
+ } from "./chunk-7HOKP4GR.js";
9
9
  import {
10
10
  ensureWorktreeSideboardIgnored
11
11
  } from "./chunk-DD67JWTN.js";
@@ -22,7 +22,7 @@ import {
22
22
  import {
23
23
  getGithubGitAuthMode,
24
24
  getGithubPat
25
- } from "./chunk-QLWMHQPH.js";
25
+ } from "./chunk-YLGBQVRK.js";
26
26
  import {
27
27
  worktreesRoot
28
28
  } from "./chunk-KK63BFYN.js";
@@ -3069,6 +3069,11 @@ async function mergePr(cwd, selector, opts) {
3069
3069
  }
3070
3070
  return { url, state: "MERGED" };
3071
3071
  }
3072
+ function ghPrCreateAssigneeArgs(assignee) {
3073
+ const raw = assignee?.trim();
3074
+ if (raw && /^(none|unassigned)$/i.test(raw)) return [];
3075
+ return ["--assignee", raw || "@me"];
3076
+ }
3072
3077
  async function createOrUpdatePr(worktreePath, opts) {
3073
3078
  await ensureGhPreferOrigin(worktreePath);
3074
3079
  const slug = await resolveGithubRepoSlug(worktreePath);
@@ -3143,6 +3148,7 @@ async function createOrUpdatePrWithBodyFile(worktreePath, opts) {
3143
3148
  headRef
3144
3149
  ];
3145
3150
  if (opts.draft) args2.push("--draft");
3151
+ args2.push(...ghPrCreateAssigneeArgs(opts.assignee));
3146
3152
  await gh(args2, worktreePath, { reject: false });
3147
3153
  const again = await gh(
3148
3154
  [...repoArgs, "pr", "view", branchOnly, "--json", "url", "--jq", ".url"],
@@ -3164,6 +3170,7 @@ async function createOrUpdatePrWithBodyFile(worktreePath, opts) {
3164
3170
  headRef
3165
3171
  ];
3166
3172
  if (opts.draft) args.push("--draft");
3173
+ args.push(...ghPrCreateAssigneeArgs(opts.assignee));
3167
3174
  const created = await gh(args, worktreePath, { reject: false });
3168
3175
  if (created.exitCode !== 0) {
3169
3176
  const raw = created.stderr.trim() || created.stdout.trim() || "gh pr create failed";
@@ -3297,6 +3304,7 @@ export {
3297
3304
  pushBranch,
3298
3305
  markPrReady,
3299
3306
  mergePr,
3307
+ ghPrCreateAssigneeArgs,
3300
3308
  createOrUpdatePr,
3301
3309
  suggestSlug,
3302
3310
  collectTakenTeamSlugs,
@@ -75,7 +75,8 @@ function normalizeThread(raw) {
75
75
  runScriptRequest: normalizeRunScriptRequest(raw.runScriptRequest),
76
76
  quotaResumeAt: raw.quotaResumeAt ?? null,
77
77
  quotaContinuedFromId: raw.quotaContinuedFromId ?? null,
78
- archivedAt: typeof raw.archivedAt === "string" && raw.archivedAt.trim() ? raw.archivedAt.trim() : void 0
78
+ archivedAt: typeof raw.archivedAt === "string" && raw.archivedAt.trim() ? raw.archivedAt.trim() : void 0,
79
+ compactedMessages: Array.isArray(raw.compactedMessages) ? raw.compactedMessages : void 0
79
80
  };
80
81
  }
81
82
  function createEmptyThread(partial) {
@@ -77,7 +77,8 @@ function normalizeThread(raw) {
77
77
  runScriptRequest: normalizeRunScriptRequest(raw.runScriptRequest),
78
78
  quotaResumeAt: raw.quotaResumeAt ?? null,
79
79
  quotaContinuedFromId: raw.quotaContinuedFromId ?? null,
80
- archivedAt: typeof raw.archivedAt === "string" && raw.archivedAt.trim() ? raw.archivedAt.trim() : void 0
80
+ archivedAt: typeof raw.archivedAt === "string" && raw.archivedAt.trim() ? raw.archivedAt.trim() : void 0,
81
+ compactedMessages: Array.isArray(raw.compactedMessages) ? raw.compactedMessages : void 0
81
82
  };
82
83
  }
83
84
  function createEmptyThread(partial) {
@@ -2,17 +2,17 @@
2
2
 
3
3
  import {
4
4
  textFromAbleTimeDoc
5
- } from "./chunk-YXOOSFAF.js";
5
+ } from "./chunk-IMO7AZI4.js";
6
6
  import {
7
7
  assertAbleTimeCredential,
8
8
  callAbleTimeTool,
9
9
  normalizeAbleTimeHost,
10
10
  rewriteAbleTimeError
11
- } from "./chunk-IVXPXYH2.js";
11
+ } from "./chunk-WURF67ID.js";
12
12
  import {
13
13
  isAbleTimeConnected,
14
14
  saveAbleTimeConnection
15
- } from "./chunk-QLWMHQPH.js";
15
+ } from "./chunk-YLGBQVRK.js";
16
16
 
17
17
  // src/integrations/abletime.ts
18
18
  var CLOSED_STATES = /* @__PURE__ */ new Set([
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DEFAULT_ABLETIME_HOST,
3
3
  normalizeAbleTimeHost
4
- } from "./chunk-5ELC3KK3.js";
4
+ } from "./chunk-QNJXJIWJ.js";
5
5
  import {
6
6
  httpFetch
7
7
  } from "./chunk-N7WZ6NIN.js";
@@ -10,7 +10,7 @@ import {
10
10
  getAbleTimeHost,
11
11
  loadAppSettings,
12
12
  saveAbleTimeConnection
13
- } from "./chunk-P3DCZRER.js";
13
+ } from "./chunk-PPJ5JTWA.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-VSV6AUBV.js");
283
+ const { getAbleTimeOrientation } = await import("./abletime-CWIJ7INC.js");
284
284
  const orientation = await getAbleTimeOrientation({ token, host });
285
285
  return saveAbleTimeConnection({
286
286
  accessToken: token,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  isOrchestratorThread
3
- } from "./chunk-BILEJG3V.js";
3
+ } from "./chunk-GFRC6JQN.js";
4
4
  import {
5
5
  codexUnattendedGitConfigArgs,
6
6
  mergeAgentGitAuthEnv,
7
7
  resolveAgentGitAuthEnv,
8
8
  resolveCodexGitWritableRoots
9
- } from "./chunk-O3UAQAYA.js";
9
+ } from "./chunk-E6C5NR46.js";
10
10
  import {
11
11
  applyConnectedTeamToCli,
12
12
  brightsyMcpServerName,
@@ -45,7 +45,7 @@ import {
45
45
  loadAppSettings,
46
46
  resolveAgentExecutable,
47
47
  resolveClaudeExecutable
48
- } from "./chunk-P3DCZRER.js";
48
+ } from "./chunk-PPJ5JTWA.js";
49
49
  import {
50
50
  appDataDir
51
51
  } from "./chunk-A4JGXX2F.js";
@@ -630,6 +630,10 @@ var SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS = ["mcp__sideboard__linear_*"];
630
630
  var SIDEBOARD_ABLETIME_MCP_ALLOWED_TOOLS = ["mcp__sideboard__abletime_*"];
631
631
  function sideboardWorktreeAllowedTools(opts) {
632
632
  const out = [...SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS];
633
+ if (!opts?.planMode) {
634
+ const idx = out.indexOf("mcp__sideboard__present_plan");
635
+ if (idx >= 0) out.splice(idx, 1);
636
+ }
633
637
  if (opts?.github !== false) out.push(...SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS);
634
638
  if (opts?.linear) out.push(...SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS);
635
639
  if (opts?.abletime) out.push(...SIDEBOARD_ABLETIME_MCP_ALLOWED_TOOLS);
@@ -1617,6 +1621,16 @@ function skillToolFromTextPart(part, id) {
1617
1621
  updatedAt: Date.now()
1618
1622
  };
1619
1623
  }
1624
+ function compactSummaryPart(text, id = "compact-summary") {
1625
+ return compactToolPart(text, id, { status: "done" });
1626
+ }
1627
+ function compactPartsForSummaryMessage(message) {
1628
+ const existing = (message.parts ?? []).filter(
1629
+ (p) => p.type === "tool" && isCompactToolName(p.name)
1630
+ );
1631
+ if (existing.length) return existing;
1632
+ return [compactSummaryPart(message.text ?? "")];
1633
+ }
1620
1634
  function compactToolPart(text, id, opts) {
1621
1635
  const input = { trigger: opts?.trigger ?? "auto" };
1622
1636
  return withPartTimes(
@@ -1932,6 +1946,10 @@ function normalizeParseResult(parsed) {
1932
1946
 
1933
1947
  // src/agents/types.ts
1934
1948
  var PLAN_MODE_INSTRUCTION = "Plan mode is active and must remain active until the user turns Plan mode off in the UI (or Approves / Hands off the plan). Analyze the codebase, search and read files as needed, and produce or refine a clear implementation plan. Do not modify, create, or delete any project files except via Sideboard MCP present_plan (writes .context/attachments/plan.md). When you need a clarifying decision (approach forks, auth choice, scope) \u2014 not greetings, check-ins, or an invented task menu: (1) first write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it) \u2014 do not leave the user staring at bare labels; (2) then call Sideboard MCP ask_user with the same options, including a description on every option. If one option is the obvious default, proceed without asking. Sideboard shows questions in the composer and mirrors them in chat. After ask_user, wait for the user's next message with their answers before finalizing the plan. When the plan is ready for approval: (1) call present_plan with the full markdown plan (title + content) so Sideboard saves .context/attachments/plan.md and shows it in chat for Approve / Hand off / Copy; (2) Claude should also call ExitPlanMode after present_plan. Do not skip present_plan \u2014 the plan must be a markdown file, not only chat prose.";
1949
+ var PLAN_MODE_OFF_INSTRUCTION = "Plan mode is off. Do not call present_plan or ExitPlanMode \u2014 those only work when the user turns Plan on in the composer. If you need to propose an approach, write it in chat.";
1950
+ function planModeTurnInstruction(planMode) {
1951
+ return planMode ? PLAN_MODE_INSTRUCTION : PLAN_MODE_OFF_INSTRUCTION;
1952
+ }
1935
1953
  function permissionMode(thread) {
1936
1954
  if (thread.sourceType === "orchestration") {
1937
1955
  return {
@@ -2414,7 +2432,7 @@ var claudeAdapter = {
2414
2432
  );
2415
2433
  }
2416
2434
  const mode = permissionMode(thread);
2417
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-ZJBBICFJ.js");
2435
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-2N6KISDO.js");
2418
2436
  const isOrchestrator = isOrchestratorThread2(thread);
2419
2437
  const injectedServers = await buildInjectedMcpServers({
2420
2438
  includeSideboard: true,
@@ -2441,7 +2459,8 @@ var claudeAdapter = {
2441
2459
  ...sideboardWorktreeAllowedTools({
2442
2460
  github: true,
2443
2461
  linear: isLinearConnected(),
2444
- abletime: isAbleTimeConnected()
2462
+ abletime: isAbleTimeConnected(),
2463
+ planMode: thread.planMode
2445
2464
  }),
2446
2465
  ...brightsyMcpAllowedTools(injectedBrightsyNames)
2447
2466
  ];
@@ -4424,6 +4443,8 @@ export {
4424
4443
  STDOUT_EVENT_MAX_CHARS,
4425
4444
  STDERR_EVENT_MAX_CHARS,
4426
4445
  clipAgentEventForPaint,
4446
+ compactSummaryPart,
4447
+ compactPartsForSummaryMessage,
4427
4448
  applyAgentEvent,
4428
4449
  partsToAssistantText,
4429
4450
  lastAssistantMessageText,
@@ -4473,6 +4494,8 @@ export {
4473
4494
  isInjectedOrchMcpName,
4474
4495
  userMcpNamesToDisable,
4475
4496
  PLAN_MODE_INSTRUCTION,
4497
+ PLAN_MODE_OFF_INSTRUCTION,
4498
+ planModeTurnInstruction,
4476
4499
  permissionMode,
4477
4500
  mcpStatusThinkingFromClaudeInit,
4478
4501
  claudeAdapter,
@@ -7,10 +7,10 @@ import {
7
7
  import {
8
8
  getGithubGitAuthMode,
9
9
  getGithubPat
10
- } from "./chunk-P3DCZRER.js";
10
+ } from "./chunk-PPJ5JTWA.js";
11
11
  import {
12
12
  listThreads
13
- } from "./chunk-3AJUH66R.js";
13
+ } from "./chunk-6I5YQTNK.js";
14
14
  import {
15
15
  worktreesRoot
16
16
  } from "./chunk-A4JGXX2F.js";
@@ -3106,6 +3106,11 @@ async function mergePr(cwd, selector, opts) {
3106
3106
  }
3107
3107
  return { url, state: "MERGED" };
3108
3108
  }
3109
+ function ghPrCreateAssigneeArgs(assignee) {
3110
+ const raw = assignee?.trim();
3111
+ if (raw && /^(none|unassigned)$/i.test(raw)) return [];
3112
+ return ["--assignee", raw || "@me"];
3113
+ }
3109
3114
  async function createOrUpdatePr(worktreePath, opts) {
3110
3115
  await ensureGhPreferOrigin(worktreePath);
3111
3116
  const slug = await resolveGithubRepoSlug(worktreePath);
@@ -3180,6 +3185,7 @@ async function createOrUpdatePrWithBodyFile(worktreePath, opts) {
3180
3185
  headRef
3181
3186
  ];
3182
3187
  if (opts.draft) args2.push("--draft");
3188
+ args2.push(...ghPrCreateAssigneeArgs(opts.assignee));
3183
3189
  await gh(args2, worktreePath, { reject: false });
3184
3190
  const again = await gh(
3185
3191
  [...repoArgs, "pr", "view", branchOnly, "--json", "url", "--jq", ".url"],
@@ -3201,6 +3207,7 @@ async function createOrUpdatePrWithBodyFile(worktreePath, opts) {
3201
3207
  headRef
3202
3208
  ];
3203
3209
  if (opts.draft) args.push("--draft");
3210
+ args.push(...ghPrCreateAssigneeArgs(opts.assignee));
3204
3211
  const created = await gh(args, worktreePath, { reject: false });
3205
3212
  if (created.exitCode !== 0) {
3206
3213
  const raw = created.stderr.trim() || created.stdout.trim() || "gh pr create failed";
@@ -3359,6 +3366,7 @@ export {
3359
3366
  pushBranch,
3360
3367
  markPrReady,
3361
3368
  mergePr,
3369
+ ghPrCreateAssigneeArgs,
3362
3370
  createOrUpdatePr,
3363
3371
  suggestSlug,
3364
3372
  collectTakenTeamSlugs,
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  textFromAbleTimeDoc
3
- } from "./chunk-3PGFAVFL.js";
3
+ } from "./chunk-43F44EKX.js";
4
4
  import {
5
5
  assertAbleTimeCredential,
6
6
  callAbleTimeTool,
7
7
  normalizeAbleTimeHost,
8
8
  rewriteAbleTimeError
9
- } from "./chunk-5ELC3KK3.js";
9
+ } from "./chunk-QNJXJIWJ.js";
10
10
  import {
11
11
  isAbleTimeConnected,
12
12
  saveAbleTimeConnection
13
- } from "./chunk-P3DCZRER.js";
13
+ } from "./chunk-PPJ5JTWA.js";
14
14
 
15
15
  // src/integrations/abletime.ts
16
16
  var CLOSED_STATES = /* @__PURE__ */ new Set([
@@ -6,7 +6,7 @@ import {
6
6
  resolveRepoRoot,
7
7
  takenSlugsFromThread,
8
8
  teamSlugFromName
9
- } from "./chunk-O3UAQAYA.js";
9
+ } from "./chunk-E6C5NR46.js";
10
10
  import {
11
11
  ATTACHMENTS_DIR,
12
12
  attachmentsGitignoreBody
@@ -23,13 +23,13 @@ import {
23
23
  resolveThreadDefaults,
24
24
  resolveViewerProfile,
25
25
  resolveViewerProfileForRepo
26
- } from "./chunk-P3DCZRER.js";
26
+ } from "./chunk-PPJ5JTWA.js";
27
27
  import {
28
28
  createEmptyThread,
29
29
  listThreads,
30
30
  updateThread,
31
31
  writeThread
32
- } from "./chunk-3AJUH66R.js";
32
+ } from "./chunk-6I5YQTNK.js";
33
33
  import {
34
34
  appDataDir,
35
35
  globalAgentCwd,
@@ -372,7 +372,7 @@ function coordinatorGreenfieldPlaybook(reposDir) {
372
372
  "- Examples:",
373
373
  ` - Clone: \`git clone <url> ${reposDir}/<name>\``,
374
374
  ` - New GitHub repo: \`gh repo create <owner>/<name> --private --clone -- ${reposDir}/<name>\` (or mkdir + git init + gh repo create + remote add + push)`,
375
- "- Then: add_workspace with that absolute path \u2192 create_thread (repoPath + parentThreadId) \u2192 send_to_thread (build) \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft (or send_to_thread `gh pr create --draft -R <origin-owner/name>`).",
375
+ "- Then: add_workspace with that absolute path \u2192 create_thread (repoPath + parentThreadId) \u2192 send_to_thread (build) \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft (or send_to_thread `gh pr create --draft --assignee @me -R <origin-owner/name>`).",
376
376
  "- Always target the child worktree's **origin** (`github:` slug from list_workspaces / `git remote get-url origin` in that worktree). Never open PRs against `upstream`.",
377
377
  "- Do coding work in the child worktree thread, not by editing files in this home cwd."
378
378
  ].join("\n");
@@ -420,7 +420,7 @@ var COORDINATOR_TOOL_PLAYBOOK = [
420
420
  '- request_review \u2014 open a Review chat tab on a worktree thread (attaches .claude/skills/review/SKILL.md when present, else .context/review.md copied from .sideboard/review.md / stock; sends "Review changes in this workspace."); then wait_for_turn (loop while stillRunning) / get_turn_result on the returned id. The review stays in that chat so they can read it and type next steps \u2014 do not tell the child to comment or update the PR or ticket.',
421
421
  "- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge \u2014 same prompts as the desktop git buttons (Resolve, Create PR, \u2026). Always steers the worktree agent; then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If the user gave a goal (Greptile 5/5, CI green), send_to_thread that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
422
422
  '- Merge (`ask_git` action=merge / send_to_thread "Merge PR.") only when the user explicitly asked to merge that PR. Do not merge because the work looks done, CI is green, or a typical flow includes it.',
423
- '- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
423
+ '- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft --assignee @me -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
424
424
  "Process guides:",
425
425
  "- Long child jobs (pack, test, deploy, anything that may run more than ~30s): workers always have `/long-running` (Sideboard product skill). Tell them to detach and wait; they may `stop_job` if it hangs or is doing the wrong thing; do not ask the human to poll.",
426
426
  "- Recurring multi-item / fan-out: if the child worktree has `.claude/skills/graph-engineering/SKILL.md`, tell the worker to follow it (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch three threads.",
@@ -6,14 +6,14 @@ import {
6
6
  normalizeAbleTimeCredential,
7
7
  normalizeAbleTimeHost,
8
8
  rewriteAbleTimeError
9
- } from "./chunk-IVXPXYH2.js";
9
+ } from "./chunk-WURF67ID.js";
10
10
  import {
11
11
  httpFetch
12
12
  } from "./chunk-VKQGAWHY.js";
13
13
  import {
14
14
  getAbleTimeAccessToken,
15
15
  getAbleTimeHost
16
- } from "./chunk-QLWMHQPH.js";
16
+ } from "./chunk-YLGBQVRK.js";
17
17
 
18
18
  // src/integrations/abletime-rest.ts
19
19
  var ABLETIME_REST_PREFIX = "/api/public/v2";
@@ -19,6 +19,15 @@ function isPresentPlanToolName(name) {
19
19
  if (!name) return false;
20
20
  return /present_plan$/i.test(name) || /^mcp__sideboard__present_plan$/i.test(name);
21
21
  }
22
+ function threadMayPresentPlan(thread) {
23
+ return Boolean(thread?.planMode);
24
+ }
25
+ function shouldRegisterPresentPlan(thread) {
26
+ if (thread == null) return true;
27
+ return threadMayPresentPlan(thread);
28
+ }
29
+ var PRESENT_PLAN_TOOL_DESCRIPTION = "Only when Sideboard Plan mode is on (composer Plan chip). Saves the implementation plan to .context/attachments/plan.md and shows Approve / Hand off / Copy in chat. Pass the full plan body in content. Then Claude should call ExitPlanMode. If Plan mode is off, do not call this \u2014 write the plan in chat.";
30
+ var PRESENT_PLAN_REQUIRES_PLAN_MODE = "Plan mode is off. Do not call present_plan or ExitPlanMode. Write the plan in chat. The user can turn Plan on in the composer.";
22
31
  function extractPresentedPlan(parts) {
23
32
  if (!parts?.length) return null;
24
33
  for (let i = parts.length - 1; i >= 0; i--) {
@@ -93,6 +102,10 @@ export {
93
102
  PLAN_FILE_NAME,
94
103
  LEGACY_PLAN_FILE_REL,
95
104
  isPresentPlanToolName,
105
+ threadMayPresentPlan,
106
+ shouldRegisterPresentPlan,
107
+ PRESENT_PLAN_TOOL_DESCRIPTION,
108
+ PRESENT_PLAN_REQUIRES_PLAN_MODE,
96
109
  extractPresentedPlan,
97
110
  resolvePlanMarkdown,
98
111
  planFileAbs,
@@ -462,6 +462,7 @@ function archivedUpdatedMs(thread) {
462
462
  }
463
463
  function isHistoryRetentionStub(thread) {
464
464
  if ((thread.attachments?.length ?? 0) > 0) return false;
465
+ if ((thread.compactedMessages?.length ?? 0) > 0) return false;
465
466
  const messages = thread.messages ?? [];
466
467
  if (messages.length === 0) return true;
467
468
  if (messages.length > 1) return false;
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  getAbleTimeHost,
6
6
  isAbleTimeConnected
7
- } from "./chunk-P3DCZRER.js";
7
+ } from "./chunk-PPJ5JTWA.js";
8
8
 
9
9
  // src/integrations/abletime-mcp.ts
10
10
  var DEFAULT_ABLETIME_HOST = "https://track.abletime.com";
@@ -153,7 +153,7 @@ function textsFromUnknown(value) {
153
153
  return "";
154
154
  }
155
155
  async function abletimeMcpRequest(method, params, opts) {
156
- const rawToken = opts?.token ?? await import("./abletime-oauth-QMDV45JC.js").then((m) => m.ensureAbleTimeAccessToken());
156
+ const rawToken = opts?.token ?? await import("./abletime-oauth-PUIPZTA4.js").then((m) => m.ensureAbleTimeAccessToken());
157
157
  if (!rawToken?.trim()) {
158
158
  throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
159
159
  }
@@ -224,9 +224,9 @@ async function callAbleTimeTool(name, args = {}, opts) {
224
224
  if (!opts?.token && !isAbleTimeConnected()) {
225
225
  throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
226
226
  }
227
- const rawToken = opts?.token ?? await import("./abletime-oauth-QMDV45JC.js").then((m) => m.ensureAbleTimeAccessToken());
227
+ const rawToken = opts?.token ?? await import("./abletime-oauth-PUIPZTA4.js").then((m) => m.ensureAbleTimeAccessToken());
228
228
  if (rawToken && ableTimeUsesRest(rawToken)) {
229
- const { callAbleTimeRestTool } = await import("./abletime-rest-NL56UVK5.js");
229
+ const { callAbleTimeRestTool } = await import("./abletime-rest-32NIVXAY.js");
230
230
  return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
231
231
  }
232
232
  const requestOpts = { ...opts, pm: opts?.pm ?? abletimeToolUsesPm(name) };
@@ -242,7 +242,7 @@ async function callAbleTimeTool(name, args = {}, opts) {
242
242
  return await call();
243
243
  }
244
244
  if (rawToken && ableTimeUsesRest(rawToken) && isAbleTimeRejectedCredential(message)) {
245
- const { callAbleTimeRestTool } = await import("./abletime-rest-NL56UVK5.js");
245
+ const { callAbleTimeRestTool } = await import("./abletime-rest-32NIVXAY.js");
246
246
  return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
247
247
  }
248
248
  throw err instanceof Error ? new Error(rewriteAbleTimeError(err.message)) : err;
@@ -21,6 +21,15 @@ function isPresentPlanToolName(name) {
21
21
  if (!name) return false;
22
22
  return /present_plan$/i.test(name) || /^mcp__sideboard__present_plan$/i.test(name);
23
23
  }
24
+ function threadMayPresentPlan(thread) {
25
+ return Boolean(thread?.planMode);
26
+ }
27
+ function shouldRegisterPresentPlan(thread) {
28
+ if (thread == null) return true;
29
+ return threadMayPresentPlan(thread);
30
+ }
31
+ var PRESENT_PLAN_TOOL_DESCRIPTION = "Only when Sideboard Plan mode is on (composer Plan chip). Saves the implementation plan to .context/attachments/plan.md and shows Approve / Hand off / Copy in chat. Pass the full plan body in content. Then Claude should call ExitPlanMode. If Plan mode is off, do not call this \u2014 write the plan in chat.";
32
+ var PRESENT_PLAN_REQUIRES_PLAN_MODE = "Plan mode is off. Do not call present_plan or ExitPlanMode. Write the plan in chat. The user can turn Plan on in the composer.";
24
33
  function extractPresentedPlan(parts) {
25
34
  if (!parts?.length) return null;
26
35
  for (let i = parts.length - 1; i >= 0; i--) {
@@ -95,6 +104,10 @@ export {
95
104
  PLAN_FILE_NAME,
96
105
  LEGACY_PLAN_FILE_REL,
97
106
  isPresentPlanToolName,
107
+ threadMayPresentPlan,
108
+ shouldRegisterPresentPlan,
109
+ PRESENT_PLAN_TOOL_DESCRIPTION,
110
+ PRESENT_PLAN_REQUIRES_PLAN_MODE,
98
111
  extractPresentedPlan,
99
112
  resolvePlanMarkdown,
100
113
  planFileAbs,
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  getAbleTimeHost,
8
8
  isAbleTimeConnected
9
- } from "./chunk-QLWMHQPH.js";
9
+ } from "./chunk-YLGBQVRK.js";
10
10
 
11
11
  // src/integrations/abletime-mcp.ts
12
12
  var DEFAULT_ABLETIME_HOST = "https://track.abletime.com";
@@ -155,7 +155,7 @@ function textsFromUnknown(value) {
155
155
  return "";
156
156
  }
157
157
  async function abletimeMcpRequest(method, params, opts) {
158
- const rawToken = opts?.token ?? await import("./abletime-oauth-DKBUZV2C.js").then((m) => m.ensureAbleTimeAccessToken());
158
+ const rawToken = opts?.token ?? await import("./abletime-oauth-CHVTUZBR.js").then((m) => m.ensureAbleTimeAccessToken());
159
159
  if (!rawToken?.trim()) {
160
160
  throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
161
161
  }
@@ -226,9 +226,9 @@ async function callAbleTimeTool(name, args = {}, opts) {
226
226
  if (!opts?.token && !isAbleTimeConnected()) {
227
227
  throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
228
228
  }
229
- const rawToken = opts?.token ?? await import("./abletime-oauth-DKBUZV2C.js").then((m) => m.ensureAbleTimeAccessToken());
229
+ const rawToken = opts?.token ?? await import("./abletime-oauth-CHVTUZBR.js").then((m) => m.ensureAbleTimeAccessToken());
230
230
  if (rawToken && ableTimeUsesRest(rawToken)) {
231
- const { callAbleTimeRestTool } = await import("./abletime-rest-VPBC2XS5.js");
231
+ const { callAbleTimeRestTool } = await import("./abletime-rest-APJUKFKL.js");
232
232
  return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
233
233
  }
234
234
  const requestOpts = { ...opts, pm: opts?.pm ?? abletimeToolUsesPm(name) };
@@ -244,7 +244,7 @@ async function callAbleTimeTool(name, args = {}, opts) {
244
244
  return await call();
245
245
  }
246
246
  if (rawToken && ableTimeUsesRest(rawToken) && isAbleTimeRejectedCredential(message)) {
247
- const { callAbleTimeRestTool } = await import("./abletime-rest-VPBC2XS5.js");
247
+ const { callAbleTimeRestTool } = await import("./abletime-rest-APJUKFKL.js");
248
248
  return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
249
249
  }
250
250
  throw err instanceof Error ? new Error(rewriteAbleTimeError(err.message)) : err;