@sideboard-ai/core 0.1.312 → 0.1.314

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 (40) hide show
  1. package/dist/{agents-XDI6QHBA.js → agents-KIC6CNXF.js} +4 -4
  2. package/dist/{agents-IOJRGGK3.js → agents-S7VBS5JL.js} +4 -4
  3. package/dist/{chunk-ZW7RSQHY.js → chunk-5QYCCXXQ.js} +2 -2
  4. package/dist/{chunk-VIVXKN5N.js → chunk-6EGQPMSR.js} +11 -11
  5. package/dist/{chunk-4FZUUH6W.js → chunk-7DBL5AF4.js} +119 -55
  6. package/dist/{chunk-QC2TQMPJ.js → chunk-7UP4D5XI.js} +2 -2
  7. package/dist/{chunk-2P2HYXA2.js → chunk-A45QMSVB.js} +119 -55
  8. package/dist/{chunk-PXMLMBMI.js → chunk-E63AM3PW.js} +29 -6
  9. package/dist/{chunk-VEVFHO6K.js → chunk-HH3VVTEC.js} +43 -11
  10. package/dist/{chunk-WRZRX4Q7.js → chunk-NMPQ7GIS.js} +3 -3
  11. package/dist/{chunk-33KDPEK4.js → chunk-RSA47QYR.js} +29 -6
  12. package/dist/{chunk-X3FSWWW2.js → chunk-S3KYDK6W.js} +4 -4
  13. package/dist/{chunk-62ESCTJ4.js → chunk-TO5UL7VN.js} +3 -3
  14. package/dist/{chunk-42JGPPVS.js → chunk-V5BTGQ6M.js} +38 -6
  15. package/dist/{chunk-LLTWP4PK.js → chunk-YK77HB3W.js} +10 -10
  16. package/dist/{chunk-RU6DTCCV.js → chunk-ZQLZ2A3I.js} +1 -1
  17. package/dist/{chunk-5QX2NYXL.js → chunk-ZSVKUOFH.js} +4 -4
  18. package/dist/{conductor-CTWR6NH4.js → conductor-G6TKCMIW.js} +2 -2
  19. package/dist/{conductor-YOBSYPLT.js → conductor-IIDQ2U24.js} +2 -2
  20. package/dist/{connected-teams-WLWIVYGD.js → connected-teams-IFW3NQ6G.js} +4 -2
  21. package/dist/{connected-teams-BBNYTR3I.js → connected-teams-IHK2WXUI.js} +4 -2
  22. package/dist/{coordinator-prompt-YAZRQ4BI.js → coordinator-prompt-5USNNCG6.js} +1 -1
  23. package/dist/{coordinator-prompt-GZCWQAAV.js → coordinator-prompt-EXJSULAR.js} +1 -1
  24. package/dist/{global-workspace-H6X32IJZ.js → global-workspace-UDRTONQE.js} +1 -1
  25. package/dist/{global-workspace-BZAVBOH3.js → global-workspace-ZGPIGJ6J.js} +1 -1
  26. package/dist/index.cjs +194 -67
  27. package/dist/index.d.cts +13 -8
  28. package/dist/index.d.ts +13 -8
  29. package/dist/index.js +11 -11
  30. package/dist/mcp/run-stdio.cjs +193 -67
  31. package/dist/mcp/run-stdio.js +7 -7
  32. package/dist/{oauth-WCUZ6Z5G.js → oauth-CI3U5ZAA.js} +1 -1
  33. package/dist/{oauth-DP4ZV2M2.js → oauth-CR5FY4CJ.js} +1 -1
  34. package/dist/{optional-cli-QDIT57VD.js → optional-cli-MLZSE6KW.js} +1 -1
  35. package/dist/{optional-cli-QY6V5S5N.js → optional-cli-SI4BCPRH.js} +2 -2
  36. package/dist/{orchestrator-S44BMNN7.js → orchestrator-AM7VT2BD.js} +7 -7
  37. package/dist/{orchestrator-BYTSILLH.js → orchestrator-V6NLIPLH.js} +7 -7
  38. package/dist/{workspaces-BQUDYTBX.js → workspaces-3TTODHKN.js} +1 -1
  39. package/dist/{workspaces-AGOLRBYZ.js → workspaces-TATO466L.js} +1 -1
  40. package/package.json +1 -1
@@ -5,27 +5,50 @@ import {
5
5
  } from "./chunk-2GPQZZLY.js";
6
6
 
7
7
  // src/brightsy/config.ts
8
- import { existsSync, readFileSync, writeFileSync } from "fs";
8
+ import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
9
9
  import { homedir } from "os";
10
- import { join } from "path";
10
+ import { dirname, join } from "path";
11
+ function resolveBrightsyConfigFile(path) {
12
+ try {
13
+ if (existsSync(path) && statSync(path).isDirectory()) {
14
+ return join(path, "config.json");
15
+ }
16
+ } catch {
17
+ }
18
+ return path;
19
+ }
11
20
  function brightsyConfigPath() {
12
21
  const override = process.env.BRIGHTSY_CONFIG?.trim();
13
- if (override) return override;
14
- return join(homedir(), ".brightsy", "config.json");
22
+ const raw = override || join(homedir(), ".brightsy", "config.json");
23
+ return resolveBrightsyConfigFile(raw);
15
24
  }
16
25
  function loadBrightsyConfig() {
17
26
  const path = brightsyConfigPath();
18
27
  if (!existsSync(path)) {
19
28
  throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
20
29
  }
21
- const raw = JSON.parse(readFileSync(path, "utf8"));
30
+ let text;
31
+ try {
32
+ text = readFileSync(path, "utf8");
33
+ } catch (err) {
34
+ const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
35
+ if (code === "EISDIR") {
36
+ throw new Error(
37
+ `Brightsy config is a directory (${path}) \u2014 expected ~/.brightsy/config.json`
38
+ );
39
+ }
40
+ throw err;
41
+ }
42
+ const raw = JSON.parse(text);
22
43
  if (!raw.access_token || !raw.account_id) {
23
44
  throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
24
45
  }
25
46
  return raw;
26
47
  }
27
48
  function saveBrightsyConfig(cfg) {
28
- writeFileSync(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
49
+ const path = brightsyConfigPath();
50
+ mkdirSync(dirname(path), { recursive: true });
51
+ writeFileSync(path, `${JSON.stringify(cfg, null, 2)}
29
52
  `, {
30
53
  mode: 384
31
54
  });
@@ -5,7 +5,7 @@ import {
5
5
  loadBrightsyConfig,
6
6
  refreshBrightsyAccessToken,
7
7
  saveBrightsyConfig
8
- } from "./chunk-33KDPEK4.js";
8
+ } from "./chunk-RSA47QYR.js";
9
9
  import {
10
10
  run
11
11
  } from "./chunk-QVN2WOKJ.js";
@@ -19,7 +19,7 @@ import { join } from "path";
19
19
 
20
20
  // src/brightsy/accounts.ts
21
21
  async function loadConnectedTeams() {
22
- const { listConnectedBrightsyTeams: listConnectedBrightsyTeams2 } = await import("./connected-teams-BBNYTR3I.js");
22
+ const { listConnectedBrightsyTeams: listConnectedBrightsyTeams2 } = await import("./connected-teams-IHK2WXUI.js");
23
23
  return listConnectedBrightsyTeams2();
24
24
  }
25
25
  async function runBrightsyTeamsJson(args) {
@@ -47,15 +47,15 @@ async function listBrightsyAccounts() {
47
47
  }
48
48
  async function getBrightsySession() {
49
49
  try {
50
- const { ensureBrightsyLocalConfigFresh: ensureBrightsyLocalConfigFresh2 } = await import("./oauth-DP4ZV2M2.js");
51
- const { ensureConnectedBrightsyTeamTokens: ensureConnectedBrightsyTeamTokens2 } = await import("./connected-teams-BBNYTR3I.js");
50
+ const { ensureBrightsyLocalConfigFresh: ensureBrightsyLocalConfigFresh2 } = await import("./oauth-CR5FY4CJ.js");
51
+ const { ensureConnectedBrightsyTeamTokens: ensureConnectedBrightsyTeamTokens2 } = await import("./connected-teams-IHK2WXUI.js");
52
52
  await ensureBrightsyLocalConfigFresh2();
53
53
  await ensureConnectedBrightsyTeamTokens2();
54
54
  loadBrightsyConfig();
55
55
  const data = await runBrightsyTeamsJson([]);
56
56
  const accounts = Array.isArray(data.teams) ? data.teams : [];
57
57
  const active = data.active ?? accounts.find((a) => a.active) ?? null;
58
- const { ensureCliTeamTracked: ensureCliTeamTracked2 } = await import("./connected-teams-BBNYTR3I.js");
58
+ const { ensureCliTeamTracked: ensureCliTeamTracked2 } = await import("./connected-teams-IHK2WXUI.js");
59
59
  const connectedTeams = ensureCliTeamTracked2(
60
60
  active ? { id: active.id, slug: active.slug, name: active.name } : void 0
61
61
  );
@@ -95,7 +95,7 @@ async function performBrightsyAccountSwitch(accountIdOrSlug) {
95
95
  return { cfg, target: data.active };
96
96
  }
97
97
  async function switchBrightsyAccount(accountIdOrSlug) {
98
- const { connectBrightsyTeam: connectBrightsyTeam2 } = await import("./connected-teams-BBNYTR3I.js");
98
+ const { connectBrightsyTeam: connectBrightsyTeam2 } = await import("./connected-teams-IHK2WXUI.js");
99
99
  await connectBrightsyTeam2(accountIdOrSlug);
100
100
  return getBrightsySession();
101
101
  }
@@ -134,6 +134,25 @@ function listConnectedBrightsyTeams() {
134
134
  function getConnectedBrightsyTeamsRaw() {
135
135
  return readStore();
136
136
  }
137
+ function teamFromCliSession(cfg, current) {
138
+ return {
139
+ ...current,
140
+ access_token: cfg.access_token,
141
+ refresh_token: cfg.refresh_token ?? current.refresh_token,
142
+ expires_at: cfg.expires_at ?? current.expires_at,
143
+ endpoint: cfg.endpoint ?? current.endpoint,
144
+ oauth_client_id: cfg.oauth_client_id ?? current.oauth_client_id,
145
+ slug: cfg.account_slug || current.slug
146
+ };
147
+ }
148
+ function brightsySessionShouldReplace(a, b) {
149
+ if (!a.access_token) return false;
150
+ const aStale = brightsyAccessTokenNeedsRefresh(a.expires_at);
151
+ const bStale = !b.access_token || brightsyAccessTokenNeedsRefresh(b.expires_at);
152
+ if (!aStale && bStale) return true;
153
+ if (aStale) return false;
154
+ return (a.expires_at ?? 0) > (b.expires_at ?? 0);
155
+ }
137
156
  function applyConnectedTeamToCli(team) {
138
157
  let base = {};
139
158
  try {
@@ -220,22 +239,34 @@ async function ensureConnectedBrightsyTeamTokens(opts) {
220
239
  }
221
240
  next.push(refreshed);
222
241
  }
223
- if (changed) writeStore(next);
224
242
  try {
225
243
  const cfg2 = loadBrightsyConfig();
226
- const active = next.find((t) => t.id === cfg2.account_id);
227
- if (active && active.access_token !== cfg2.access_token) {
228
- applyConnectedTeamToCli(active);
244
+ const idx = next.findIndex((t) => t.id === cfg2.account_id);
245
+ if (idx >= 0) {
246
+ const active = next[idx];
247
+ if (brightsySessionShouldReplace(cfg2, active)) {
248
+ next[idx] = teamFromCliSession(cfg2, active);
249
+ changed = true;
250
+ } else if (active.access_token !== cfg2.access_token) {
251
+ applyConnectedTeamToCli(active);
252
+ }
229
253
  }
230
254
  } catch {
231
255
  }
256
+ if (changed) writeStore(next);
232
257
  return next;
233
258
  }
234
259
  function ensureCliTeamTracked(meta) {
235
260
  try {
236
261
  const cfg = loadBrightsyConfig();
237
262
  const existing = readStore();
238
- if (existing.some((t) => t.id === cfg.account_id)) {
263
+ const idx = existing.findIndex((t) => t.id === cfg.account_id);
264
+ if (idx >= 0) {
265
+ const current = existing[idx];
266
+ if (brightsySessionShouldReplace(cfg, current)) {
267
+ existing[idx] = teamFromCliSession(cfg, current);
268
+ writeStore(existing);
269
+ }
239
270
  return listConnectedBrightsyTeams();
240
271
  }
241
272
  const team = {
@@ -312,6 +343,7 @@ export {
312
343
  switchBrightsyAccount,
313
344
  listConnectedBrightsyTeams,
314
345
  getConnectedBrightsyTeamsRaw,
346
+ brightsySessionShouldReplace,
315
347
  applyConnectedTeamToCli,
316
348
  ensureConnectedBrightsyTeamTokens,
317
349
  ensureCliTeamTracked,
@@ -239,7 +239,7 @@ function connectorAuthCaution(posthog, cliConnected) {
239
239
  const signIn = posthog ? "If a connector MCP is listed but needsAuth or returns unauthorized, do not sign in to that MCP." : "If a Vercel, Supabase, or Sentry MCP is listed but needsAuth or returns unauthorized, do not sign in to that MCP.";
240
240
  const token = cliConnected ? " CLI tokens are already in this process." : "";
241
241
  const key = posthog ? " Do not read a PostHog key from the environment." : "";
242
- return `${signIn}${token}${key}`;
242
+ return `${signIn}${token}${key} When this Sideboard connection works, ignore a Claude connector that failed to start. Use the Claude connector only when this connection is not set or the CLI call fails.`;
243
243
  }
244
244
  function connectorReminderBit(spec, cli) {
245
245
  if (!spec.cli) return `${spec.label}: \`posthog_api\``;
@@ -266,14 +266,14 @@ function formatOptionalServicesReminder(integrations, cli) {
266
266
  const bits = connected.map((spec) => connectorReminderBit(spec, cli)).join(". ");
267
267
  const tokenBit = connected.some((spec) => spec.cli) ? "CLI tokens are already in this process. " : "";
268
268
  const posthog = connected.some((spec) => spec.id === "posthog");
269
- const auth = posthog ? "If a connector MCP needsAuth or is unauthorized, ignore it and use the CLI or `posthog_api`. Do not read a PostHog key from the environment." : "If a Vercel, Supabase, or Sentry MCP needsAuth or is unauthorized, ignore it and use the CLI.";
269
+ const auth = posthog ? "If a connector MCP needsAuth or is unauthorized, ignore it and use the CLI or `posthog_api` while this Sideboard connection works. Use the Claude connector only when it is not set or the call fails. Do not read a PostHog key from the environment." : "If a Vercel, Supabase, or Sentry MCP needsAuth or is unauthorized, ignore it and use the CLI while this Sideboard connection works. Use the Claude connector only when it is not set or the CLI call fails.";
270
270
  return `Settings \u2192 Connectors: ${tokenBit}${bits}. ${auth} Do not add vendor MCPs. Shell dumps from those CLIs go in \`.context/cli/\` \u2014 read a slice.`;
271
271
  }
272
272
  async function connectedCliPresence(integrations) {
273
273
  const ids = connectedOptionalServices(integrations).filter((spec) => spec.cli).map((spec) => spec.id);
274
274
  if (ids.length === 0) return void 0;
275
275
  try {
276
- const { optionalCliPresence } = await import("./optional-cli-QY6V5S5N.js");
276
+ const { optionalCliPresence } = await import("./optional-cli-SI4BCPRH.js");
277
277
  return await optionalCliPresence(ids);
278
278
  } catch {
279
279
  return void 0;
@@ -3,27 +3,50 @@ import {
3
3
  } from "./chunk-JAT3JFOS.js";
4
4
 
5
5
  // src/brightsy/config.ts
6
- import { existsSync, readFileSync, writeFileSync } from "fs";
6
+ import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
7
7
  import { homedir } from "os";
8
- import { join } from "path";
8
+ import { dirname, join } from "path";
9
+ function resolveBrightsyConfigFile(path) {
10
+ try {
11
+ if (existsSync(path) && statSync(path).isDirectory()) {
12
+ return join(path, "config.json");
13
+ }
14
+ } catch {
15
+ }
16
+ return path;
17
+ }
9
18
  function brightsyConfigPath() {
10
19
  const override = process.env.BRIGHTSY_CONFIG?.trim();
11
- if (override) return override;
12
- return join(homedir(), ".brightsy", "config.json");
20
+ const raw = override || join(homedir(), ".brightsy", "config.json");
21
+ return resolveBrightsyConfigFile(raw);
13
22
  }
14
23
  function loadBrightsyConfig() {
15
24
  const path = brightsyConfigPath();
16
25
  if (!existsSync(path)) {
17
26
  throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
18
27
  }
19
- const raw = JSON.parse(readFileSync(path, "utf8"));
28
+ let text;
29
+ try {
30
+ text = readFileSync(path, "utf8");
31
+ } catch (err) {
32
+ const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
33
+ if (code === "EISDIR") {
34
+ throw new Error(
35
+ `Brightsy config is a directory (${path}) \u2014 expected ~/.brightsy/config.json`
36
+ );
37
+ }
38
+ throw err;
39
+ }
40
+ const raw = JSON.parse(text);
20
41
  if (!raw.access_token || !raw.account_id) {
21
42
  throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
22
43
  }
23
44
  return raw;
24
45
  }
25
46
  function saveBrightsyConfig(cfg) {
26
- writeFileSync(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
47
+ const path = brightsyConfigPath();
48
+ mkdirSync(dirname(path), { recursive: true });
49
+ writeFileSync(path, `${JSON.stringify(cfg, null, 2)}
27
50
  `, {
28
51
  mode: 384
29
52
  });
@@ -341,12 +341,12 @@ var COORDINATOR_TOOL_PLAYBOOK = [
341
341
  "- list_projects \u2014 registered repos (path + github slug + project context when set). Use account / project context to pick the right repo for tickets or reviews.",
342
342
  "- list_board \u2014 Home Kanban of workspaces (New / Draft / Review / Approved / Merged; one card per checkout). Sibling chats on a card are separate agents, not one agent. Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 approved \u2192 merged. Archive removes the card to Settings \u2192 History (list_archive to browse, restore_workspace to bring it back). Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind, column, limit.",
343
343
  `- list_branches / list_prs / list_issues \u2014 pass repoPath from list_projects. Review is PRs (the surface for assigned ticket work), not the tickets: "Get me N tickets to review" \u2192 list_prs(queue=review, limit=N) then create_workspace sourceType=pr. That is open non-draft PRs labeled with this project's ready-for-review GitHub label (Settings \u2192 Projects; default eng-review) with no individual user reviewer yet. A team request (engineering-team) is not a claim \u2014 the viewer is on that team and can pick it up; claimed means an individual account is the reviewer. Bots ignored. Use Settings \u2192 Agents / Projects context (roles, teams, labels \u2014 freeform text; project adds to account) to prefer the right queues. queue=mine is review-requested:@me; queue=approved|changes uses those labels. Also: state, label, reviewer=me|unassigned|login, query, limit default 40 max 250; raise limit or tighten when truncated. list_issues (query, assignee=me|unassigned|all|user, limit default 40 max 250) lists Linear, AbleTime, or GitHub tickets \u2014 do not use it for that review-inbox ask. When they ask for tickets to work on, follow their context (assignee=me or unassigned as it says).`,
344
- "- Find work: when they ask to find work, pick up tickets, or list reviews, use Settings \u2192 Agents (account) plus Settings \u2192 Projects (per-repo) context. Tickets \u2192 Sideboard list_issues / linear_* (Account Linear). Reviews \u2192 list_prs(queue=review). Do not call Claude Linear MCP or any other vendor Linear MCP \u2014 those HTTP connectors hang or flap on the first turn. If a vendor MCP is down or reconnecting, ignore it and keep going with Sideboard tools. Show the options \u2014 do not create_workspace or start unless they also asked to start (e.g. \u201Cfind me work and start it\u201D). Do not start this unprompted. To change that context, show the proposed text, ask_user (Save this context / Do not save), wait, then update_viewer_context with confirmed=true. Never write it without confirmation.",
344
+ "- Find work: when they ask to find work, pick up tickets, or list reviews, use Settings \u2192 Agents (account) plus Settings \u2192 Projects (per-repo) context. Tickets \u2192 Sideboard list_issues / linear_* (Account Linear). Reviews \u2192 list_prs(queue=review). Do not call Claude Linear MCP or any other vendor Linear MCP \u2014 those HTTP connectors hang or flap on the first turn. If a vendor MCP is down or reconnecting, ignore it and keep going with Sideboard tools. A failed Claude connector is not a Sideboard outage \u2014 do not mention it when the Account connection works. Show the options \u2014 do not create_workspace or start unless they also asked to start (e.g. \u201Cfind me work and start it\u201D). Do not start this unprompted. To change that context, show the proposed text, ask_user (Save this context / Do not save), wait, then update_viewer_context with confirmed=true. Never write it without confirmation.",
345
345
  "- Ticket updates: list_issues / linear_search_issues / github_search_issues with updatedSince (yesterday, 2d, or ISO). One call returns new assignments, ticket edits, and new comments \u2014 do not get_issue every ticket just to check for comments. kind=created vs updated distinguishes new tickets from existing ones.",
346
- "- linear_* (when Linear is connected) \u2014 list_teams for team key/states; linear_list_projects for project names; get/search include the project a ticket is on; get/create/update/comment with ENG-123. Worktree agents have the same Account tools \u2014 prefer they comment, update status, and create spin-offs (parent=) on their own ticket when they were asked to do the work. When reviewing a PR or ticket, do not comment or update until the user types a next step \u2014 they should work through the feedback in chat first. Do not tell the child to ask_user after the review. Scope errors: reconnect Linear in Account settings. Prefer these over any Linear MCP the CLI may still list.",
347
- "- github_* \u2014 get/comment/update/create GitHub issues via Account `gh` (#123). github_list_projects and get/search include GitHub Projects. projectsError or a missing read:project scope \u2192 `gh auth refresh -s read:project`. Worktree agents have these too. Prefer over any vendor GitHub MCP. Pass parent= for spin-offs. When reviewing a PR or ticket, do not comment, submit `gh pr review`, or update the PR/ticket until the user types a next step.",
346
+ "- linear_* (when Linear is connected) \u2014 list_teams for team key/states; linear_list_projects for project names; get/search include the project a ticket is on; get/create/update/comment with ENG-123. Worktree agents have the same Account tools \u2014 prefer they comment, update status, and create spin-offs (parent=) on their own ticket when they were asked to do the work. When reviewing a PR or ticket, do not comment or update until the user types a next step \u2014 they should work through the feedback in chat first. Do not tell the child to ask_user after the review. Scope errors: reconnect Linear in Account settings. Prefer these over any Linear MCP the CLI may still list. Worktree agents use the Claude Linear connector only when Account Linear is not set or the Sideboard call fails, and they do not mention that connector startup failure when Sideboard works.",
347
+ "- github_* \u2014 get/comment/update/create GitHub issues via Account `gh` (#123). github_list_projects and get/search include GitHub Projects. projectsError or a missing read:project scope \u2192 `gh auth refresh -s read:project`. Worktree agents have these too. Prefer Sideboard `github_*` while Account `gh` works. A failed Claude GitHub connector (`mcp_github_github`) is not a Sideboard outage \u2014 do not mention it. Use that connector only when `gh` is not set up or the Sideboard call fails. Pass parent= for spin-offs. When reviewing a PR or ticket, do not comment, submit `gh pr review`, or update the PR/ticket until the user types a next step.",
348
348
  "- abletime_* (when AbleTime is connected) \u2014 orientation first; abletime_list_projects lists projects; get/list include the project a task is on; get/comment/update/create (parent= for spin-offs); ensure_task when work has no ticket (or create_workspace from the default branch auto-creates one). Worktree agents have the same Account tools. Same review-write gate as Linear/GitHub.",
349
- "- Optional connectors (Vercel, Supabase, Sentry) in Settings \u2192 Connectors inject tokens into worktree agent env when connected. Prefer official CLIs (`vercel`, `supabase`, `sentry-cli`). When Settings \u2192 Connectors has a PostHog personal API key, PostHog is the Sideboard tool `posthog_api` (GET by default; POST `/api/projects/:id/query/` or `/api/environments/:id/query/` is a read and does not need write=true; other POST and PATCH need write=true only when the user asked to change data). The PostHog key stays in the vault \u2014 do not read it from the environment, and do not sign in to a PostHog MCP. When no PostHog API key is set, leave the Claude PostHog connector alone. If a Vercel, Supabase, or Sentry MCP needsAuth or is unauthorized, do not sign in \u2014 use the native CLI. Tell any worktree agent (Claude / Cursor / Codex / OpenCode) to write CLI output to `.context/cli/` and read a slice. If a CLI is missing, the user presses Install CLI on that row. Do not add vendor MCPs. Git (`gh`) stays Settings \u2192 Git; issue tracking stays Settings \u2192 Issues. The phone remote is Settings \u2192 Remote \u2014 do not look up Slack users.",
349
+ "- Optional connectors (Vercel, Supabase, Sentry) in Settings \u2192 Connectors inject tokens into worktree agent env when connected. Prefer official CLIs (`vercel`, `supabase`, `sentry-cli`). When Settings \u2192 Connectors has a PostHog personal API key, PostHog is the Sideboard tool `posthog_api` (GET by default; POST `/api/projects/:id/query/` or `/api/environments/:id/query/` is a read and does not need write=true; other POST and PATCH need write=true only when the user asked to change data). The PostHog key stays in the vault \u2014 do not read it from the environment, and do not sign in to a PostHog MCP. When no PostHog API key is set, use the Claude PostHog connector. When a key is set, ignore a failed Claude PostHog connector and do not sign in to a PostHog MCP. If a Vercel, Supabase, or Sentry MCP needsAuth or is unauthorized while that Sideboard token is set, do not sign in \u2014 use the native CLI. When that token is not set or the CLI call fails, the Claude connector is the fallback. Do not mention a Claude connector startup failure when the Sideboard connection works. Tell any worktree agent (Claude / Cursor / Codex / OpenCode) to write CLI output to `.context/cli/` and read a slice. If a CLI is missing, the user presses Install CLI on that row. Do not add vendor MCPs. Git (`gh`) stays Settings \u2192 Git; issue tracking stays Settings \u2192 Issues. The phone remote is Settings \u2192 Remote \u2014 do not look up Slack users.",
350
350
  "- get_pr_stack / open_pr_stack_layers / add_stack_layer / create_pr_stack \u2014 GitHub stacked PRs (`gh stack`); one worktree per layer",
351
351
  "- list_models \u2014 only when you need a specific model (rare); otherwise omit model so Account defaults apply",
352
352
  "- list_chats / get_chat \u2014 live thread list (parent id + last message preview). get_chat on this orchestration chat lists child worktree agents (status + lastText). blockedReason is why that agent is waiting on a person. Also includes usage / lastTurnUsage. Archived workspaces and agents are list_archive, not this list.",
@@ -91,7 +91,7 @@ function connectorAuthCaution(posthog, cliConnected) {
91
91
  const signIn = posthog ? "If a connector MCP is listed but needsAuth or returns unauthorized, do not sign in to that MCP." : "If a Vercel, Supabase, or Sentry MCP is listed but needsAuth or returns unauthorized, do not sign in to that MCP.";
92
92
  const token = cliConnected ? " CLI tokens are already in this process." : "";
93
93
  const key = posthog ? " Do not read a PostHog key from the environment." : "";
94
- return `${signIn}${token}${key}`;
94
+ return `${signIn}${token}${key} When this Sideboard connection works, ignore a Claude connector that failed to start. Use the Claude connector only when this connection is not set or the CLI call fails.`;
95
95
  }
96
96
  function connectorReminderBit(spec, cli) {
97
97
  if (!spec.cli) return `${spec.label}: \`posthog_api\``;
@@ -118,14 +118,14 @@ function formatOptionalServicesReminder(integrations, cli) {
118
118
  const bits = connected.map((spec) => connectorReminderBit(spec, cli)).join(". ");
119
119
  const tokenBit = connected.some((spec) => spec.cli) ? "CLI tokens are already in this process. " : "";
120
120
  const posthog = connected.some((spec) => spec.id === "posthog");
121
- const auth = posthog ? "If a connector MCP needsAuth or is unauthorized, ignore it and use the CLI or `posthog_api`. Do not read a PostHog key from the environment." : "If a Vercel, Supabase, or Sentry MCP needsAuth or is unauthorized, ignore it and use the CLI.";
121
+ const auth = posthog ? "If a connector MCP needsAuth or is unauthorized, ignore it and use the CLI or `posthog_api` while this Sideboard connection works. Use the Claude connector only when it is not set or the call fails. Do not read a PostHog key from the environment." : "If a Vercel, Supabase, or Sentry MCP needsAuth or is unauthorized, ignore it and use the CLI while this Sideboard connection works. Use the Claude connector only when it is not set or the CLI call fails.";
122
122
  return `Settings \u2192 Connectors: ${tokenBit}${bits}. ${auth} Do not add vendor MCPs. Shell dumps from those CLIs go in \`.context/cli/\` \u2014 read a slice.`;
123
123
  }
124
124
  async function connectedCliPresence(integrations) {
125
125
  const ids = connectedOptionalServices(integrations).filter((spec) => spec.cli).map((spec) => spec.id);
126
126
  if (ids.length === 0) return void 0;
127
127
  try {
128
- const { optionalCliPresence } = await import("./optional-cli-QDIT57VD.js");
128
+ const { optionalCliPresence } = await import("./optional-cli-MLZSE6KW.js");
129
129
  return await optionalCliPresence(ids);
130
130
  } catch {
131
131
  return void 0;
@@ -7,7 +7,7 @@ import {
7
7
  loadBrightsyConfig,
8
8
  refreshBrightsyAccessToken,
9
9
  saveBrightsyConfig
10
- } from "./chunk-PXMLMBMI.js";
10
+ } from "./chunk-E63AM3PW.js";
11
11
  import {
12
12
  run
13
13
  } from "./chunk-2UG25RMK.js";
@@ -93,6 +93,25 @@ function listConnectedBrightsyTeams() {
93
93
  function getConnectedBrightsyTeamsRaw() {
94
94
  return readStore();
95
95
  }
96
+ function teamFromCliSession(cfg, current) {
97
+ return {
98
+ ...current,
99
+ access_token: cfg.access_token,
100
+ refresh_token: cfg.refresh_token ?? current.refresh_token,
101
+ expires_at: cfg.expires_at ?? current.expires_at,
102
+ endpoint: cfg.endpoint ?? current.endpoint,
103
+ oauth_client_id: cfg.oauth_client_id ?? current.oauth_client_id,
104
+ slug: cfg.account_slug || current.slug
105
+ };
106
+ }
107
+ function brightsySessionShouldReplace(a, b) {
108
+ if (!a.access_token) return false;
109
+ const aStale = brightsyAccessTokenNeedsRefresh(a.expires_at);
110
+ const bStale = !b.access_token || brightsyAccessTokenNeedsRefresh(b.expires_at);
111
+ if (!aStale && bStale) return true;
112
+ if (aStale) return false;
113
+ return (a.expires_at ?? 0) > (b.expires_at ?? 0);
114
+ }
96
115
  function applyConnectedTeamToCli(team) {
97
116
  let base = {};
98
117
  try {
@@ -179,22 +198,34 @@ async function ensureConnectedBrightsyTeamTokens(opts) {
179
198
  }
180
199
  next.push(refreshed);
181
200
  }
182
- if (changed) writeStore(next);
183
201
  try {
184
202
  const cfg2 = loadBrightsyConfig();
185
- const active = next.find((t) => t.id === cfg2.account_id);
186
- if (active && active.access_token !== cfg2.access_token) {
187
- applyConnectedTeamToCli(active);
203
+ const idx = next.findIndex((t) => t.id === cfg2.account_id);
204
+ if (idx >= 0) {
205
+ const active = next[idx];
206
+ if (brightsySessionShouldReplace(cfg2, active)) {
207
+ next[idx] = teamFromCliSession(cfg2, active);
208
+ changed = true;
209
+ } else if (active.access_token !== cfg2.access_token) {
210
+ applyConnectedTeamToCli(active);
211
+ }
188
212
  }
189
213
  } catch {
190
214
  }
215
+ if (changed) writeStore(next);
191
216
  return next;
192
217
  }
193
218
  function ensureCliTeamTracked(meta) {
194
219
  try {
195
220
  const cfg = loadBrightsyConfig();
196
221
  const existing = readStore();
197
- if (existing.some((t) => t.id === cfg.account_id)) {
222
+ const idx = existing.findIndex((t) => t.id === cfg.account_id);
223
+ if (idx >= 0) {
224
+ const current = existing[idx];
225
+ if (brightsySessionShouldReplace(cfg, current)) {
226
+ existing[idx] = teamFromCliSession(cfg, current);
227
+ writeStore(existing);
228
+ }
198
229
  return listConnectedBrightsyTeams();
199
230
  }
200
231
  const team = {
@@ -268,6 +299,7 @@ function brightsyMcpServerName(slug) {
268
299
  export {
269
300
  listConnectedBrightsyTeams,
270
301
  getConnectedBrightsyTeamsRaw,
302
+ brightsySessionShouldReplace,
271
303
  applyConnectedTeamToCli,
272
304
  ensureConnectedBrightsyTeamTokens,
273
305
  ensureCliTeamTracked,
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  formatOptionalServicesDirectiveForTurn,
8
8
  formatOptionalServicesReminderForTurn
9
- } from "./chunk-62ESCTJ4.js";
9
+ } from "./chunk-TO5UL7VN.js";
10
10
  import {
11
11
  extractPresentedPlan,
12
12
  isPresentPlanToolName,
@@ -27,7 +27,7 @@ import {
27
27
  parseSessionQuotaResetAt,
28
28
  planModeTurnInstruction,
29
29
  resolveQuotaFallbackAgent
30
- } from "./chunk-2P2HYXA2.js";
30
+ } from "./chunk-A45QMSVB.js";
31
31
  import {
32
32
  REVIEW_TAB_TITLE,
33
33
  applyWorktreePkgCacheEnv,
@@ -69,7 +69,7 @@ import {
69
69
  worktreeDevProcessKey,
70
70
  worktreeRunProcessKey,
71
71
  worktreeSetupProcessKey
72
- } from "./chunk-ZW7RSQHY.js";
72
+ } from "./chunk-5QYCCXXQ.js";
73
73
  import {
74
74
  applyAgentEvent,
75
75
  clipAgentEventForPaint,
@@ -121,7 +121,7 @@ import {
121
121
  stageAbsolutePathsAsAttachments,
122
122
  stageBuffersAsAttachments,
123
123
  syncWorkspacesFromThreads
124
- } from "./chunk-X3FSWWW2.js";
124
+ } from "./chunk-S3KYDK6W.js";
125
125
  import {
126
126
  addPrStackLayer,
127
127
  allocateTeamSlug,
@@ -506,9 +506,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
506
506
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
507
507
  );
508
508
  }
509
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-H6X32IJZ.js");
509
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-UDRTONQE.js");
510
510
  if (isGlobalThread2(thread)) {
511
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-GZCWQAAV.js");
511
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-EXJSULAR.js");
512
512
  ensureGlobalCoordinatorCwd2(
513
513
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
514
514
  );
@@ -3544,7 +3544,7 @@ async function adoptThread(input) {
3544
3544
  messages: input.messages ?? []
3545
3545
  });
3546
3546
  writeThread(thread);
3547
- const { addWorkspace: addWorkspace2 } = await import("./workspaces-AGOLRBYZ.js");
3547
+ const { addWorkspace: addWorkspace2 } = await import("./workspaces-TATO466L.js");
3548
3548
  await addWorkspace2(repoPath);
3549
3549
  const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-5N2KTYIT.js");
3550
3550
  await ensureWorktreeSideboardIgnored(input.worktreePath);
@@ -5628,7 +5628,7 @@ function formatIssueToolsDirective(opts) {
5628
5628
  if (!opts.linear && !opts.abletime && !github) return null;
5629
5629
  const lines = [
5630
5630
  "Issue tracking (Settings \u2192 Issues / Git \u2014 already signed in):",
5631
- "- Use Sideboard `linear_*` / `github_*` / `abletime_*` tools. Do not call Claude Linear MCP, vendor GitHub MCP, or any other vendor issue MCP \u2014 those need a separate login and hang. If a vendor namespace shows needsAuth, ignore it and keep going with Sideboard tools."
5631
+ "- Use Sideboard `linear_*` / `github_*` / `abletime_*` when that Account connection is set and the call works. If it is not set, or the Sideboard call fails because the connection is down, use the Claude connector for that service. Do not mention a Claude connector that failed to start (for example `mcp_github_github` or `plugin:github:github`) when the Sideboard connection is working. A vendor issue MCP that only needsAuth is noise \u2014 do not sign in to it while Sideboard covers that service."
5632
5632
  ];
5633
5633
  if (opts.linear) {
5634
5634
  lines.push(
@@ -5668,7 +5668,7 @@ function formatIssueToolsReminder(opts) {
5668
5668
  ].filter(Boolean);
5669
5669
  const ticket = opts.ticketId?.trim();
5670
5670
  const ticketBit = ticket ? ` This ticket: ${ticket}${opts.ticketProvider ? ` (${opts.ticketProvider})` : ""} \u2014 get; comment/update review findings only after they ask. Spin-offs use parent=.` : " get/comment/update/create (parent= for spin-offs).";
5671
- return `Issues: Sideboard ${names.join(" / ")} (Account). Ignore vendor issue MCP auth.${ticketBit} Review stays in chat \u2014 do not ask_user after it; they type next steps. Authors see comments immediately.`;
5671
+ return `Issues: Sideboard ${names.join(" / ")} when that Account connection works. If it is not set or the call fails, use the Claude connector. Do not mention a Claude connector startup failure when Sideboard covers it.${ticketBit} Review stays in chat \u2014 do not ask_user after it; they type next steps. Authors see comments immediately.`;
5672
5672
  }
5673
5673
  function formatPrGateDirective() {
5674
5674
  return [
@@ -6438,7 +6438,7 @@ function formatScheduledPrompt(name, prompt) {
6438
6438
  ${prompt}`;
6439
6439
  }
6440
6440
  async function defaultDeps() {
6441
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-S44BMNN7.js");
6441
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-AM7VT2BD.js");
6442
6442
  const orch = getOrchestrator2();
6443
6443
  return {
6444
6444
  findThread: (id) => findThreadByRef(id),
@@ -2,7 +2,7 @@ import {
2
2
  OPTIONAL_SERVICES,
3
3
  isOptionalServiceId,
4
4
  optionalServiceSpec
5
- } from "./chunk-WRZRX4Q7.js";
5
+ } from "./chunk-NMPQ7GIS.js";
6
6
  import {
7
7
  installNpmGlobalPackage,
8
8
  whichOnPath
@@ -386,12 +386,12 @@ var COORDINATOR_TOOL_PLAYBOOK = [
386
386
  "- list_projects \u2014 registered repos (path + github slug + project context when set). Use account / project context to pick the right repo for tickets or reviews.",
387
387
  "- list_board \u2014 Home Kanban of workspaces (New / Draft / Review / Approved / Merged; one card per checkout). Sibling chats on a card are separate agents, not one agent. Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 approved \u2192 merged. Archive removes the card to Settings \u2192 History (list_archive to browse, restore_workspace to bring it back). Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind, column, limit.",
388
388
  `- list_branches / list_prs / list_issues \u2014 pass repoPath from list_projects. Review is PRs (the surface for assigned ticket work), not the tickets: "Get me N tickets to review" \u2192 list_prs(queue=review, limit=N) then create_workspace sourceType=pr. That is open non-draft PRs labeled with this project's ready-for-review GitHub label (Settings \u2192 Projects; default eng-review) with no individual user reviewer yet. A team request (engineering-team) is not a claim \u2014 the viewer is on that team and can pick it up; claimed means an individual account is the reviewer. Bots ignored. Use Settings \u2192 Agents / Projects context (roles, teams, labels \u2014 freeform text; project adds to account) to prefer the right queues. queue=mine is review-requested:@me; queue=approved|changes uses those labels. Also: state, label, reviewer=me|unassigned|login, query, limit default 40 max 250; raise limit or tighten when truncated. list_issues (query, assignee=me|unassigned|all|user, limit default 40 max 250) lists Linear, AbleTime, or GitHub tickets \u2014 do not use it for that review-inbox ask. When they ask for tickets to work on, follow their context (assignee=me or unassigned as it says).`,
389
- "- Find work: when they ask to find work, pick up tickets, or list reviews, use Settings \u2192 Agents (account) plus Settings \u2192 Projects (per-repo) context. Tickets \u2192 Sideboard list_issues / linear_* (Account Linear). Reviews \u2192 list_prs(queue=review). Do not call Claude Linear MCP or any other vendor Linear MCP \u2014 those HTTP connectors hang or flap on the first turn. If a vendor MCP is down or reconnecting, ignore it and keep going with Sideboard tools. Show the options \u2014 do not create_workspace or start unless they also asked to start (e.g. \u201Cfind me work and start it\u201D). Do not start this unprompted. To change that context, show the proposed text, ask_user (Save this context / Do not save), wait, then update_viewer_context with confirmed=true. Never write it without confirmation.",
389
+ "- Find work: when they ask to find work, pick up tickets, or list reviews, use Settings \u2192 Agents (account) plus Settings \u2192 Projects (per-repo) context. Tickets \u2192 Sideboard list_issues / linear_* (Account Linear). Reviews \u2192 list_prs(queue=review). Do not call Claude Linear MCP or any other vendor Linear MCP \u2014 those HTTP connectors hang or flap on the first turn. If a vendor MCP is down or reconnecting, ignore it and keep going with Sideboard tools. A failed Claude connector is not a Sideboard outage \u2014 do not mention it when the Account connection works. Show the options \u2014 do not create_workspace or start unless they also asked to start (e.g. \u201Cfind me work and start it\u201D). Do not start this unprompted. To change that context, show the proposed text, ask_user (Save this context / Do not save), wait, then update_viewer_context with confirmed=true. Never write it without confirmation.",
390
390
  "- Ticket updates: list_issues / linear_search_issues / github_search_issues with updatedSince (yesterday, 2d, or ISO). One call returns new assignments, ticket edits, and new comments \u2014 do not get_issue every ticket just to check for comments. kind=created vs updated distinguishes new tickets from existing ones.",
391
- "- linear_* (when Linear is connected) \u2014 list_teams for team key/states; linear_list_projects for project names; get/search include the project a ticket is on; get/create/update/comment with ENG-123. Worktree agents have the same Account tools \u2014 prefer they comment, update status, and create spin-offs (parent=) on their own ticket when they were asked to do the work. When reviewing a PR or ticket, do not comment or update until the user types a next step \u2014 they should work through the feedback in chat first. Do not tell the child to ask_user after the review. Scope errors: reconnect Linear in Account settings. Prefer these over any Linear MCP the CLI may still list.",
392
- "- github_* \u2014 get/comment/update/create GitHub issues via Account `gh` (#123). github_list_projects and get/search include GitHub Projects. projectsError or a missing read:project scope \u2192 `gh auth refresh -s read:project`. Worktree agents have these too. Prefer over any vendor GitHub MCP. Pass parent= for spin-offs. When reviewing a PR or ticket, do not comment, submit `gh pr review`, or update the PR/ticket until the user types a next step.",
391
+ "- linear_* (when Linear is connected) \u2014 list_teams for team key/states; linear_list_projects for project names; get/search include the project a ticket is on; get/create/update/comment with ENG-123. Worktree agents have the same Account tools \u2014 prefer they comment, update status, and create spin-offs (parent=) on their own ticket when they were asked to do the work. When reviewing a PR or ticket, do not comment or update until the user types a next step \u2014 they should work through the feedback in chat first. Do not tell the child to ask_user after the review. Scope errors: reconnect Linear in Account settings. Prefer these over any Linear MCP the CLI may still list. Worktree agents use the Claude Linear connector only when Account Linear is not set or the Sideboard call fails, and they do not mention that connector startup failure when Sideboard works.",
392
+ "- github_* \u2014 get/comment/update/create GitHub issues via Account `gh` (#123). github_list_projects and get/search include GitHub Projects. projectsError or a missing read:project scope \u2192 `gh auth refresh -s read:project`. Worktree agents have these too. Prefer Sideboard `github_*` while Account `gh` works. A failed Claude GitHub connector (`mcp_github_github`) is not a Sideboard outage \u2014 do not mention it. Use that connector only when `gh` is not set up or the Sideboard call fails. Pass parent= for spin-offs. When reviewing a PR or ticket, do not comment, submit `gh pr review`, or update the PR/ticket until the user types a next step.",
393
393
  "- abletime_* (when AbleTime is connected) \u2014 orientation first; abletime_list_projects lists projects; get/list include the project a task is on; get/comment/update/create (parent= for spin-offs); ensure_task when work has no ticket (or create_workspace from the default branch auto-creates one). Worktree agents have the same Account tools. Same review-write gate as Linear/GitHub.",
394
- "- Optional connectors (Vercel, Supabase, Sentry) in Settings \u2192 Connectors inject tokens into worktree agent env when connected. Prefer official CLIs (`vercel`, `supabase`, `sentry-cli`). When Settings \u2192 Connectors has a PostHog personal API key, PostHog is the Sideboard tool `posthog_api` (GET by default; POST `/api/projects/:id/query/` or `/api/environments/:id/query/` is a read and does not need write=true; other POST and PATCH need write=true only when the user asked to change data). The PostHog key stays in the vault \u2014 do not read it from the environment, and do not sign in to a PostHog MCP. When no PostHog API key is set, leave the Claude PostHog connector alone. If a Vercel, Supabase, or Sentry MCP needsAuth or is unauthorized, do not sign in \u2014 use the native CLI. Tell any worktree agent (Claude / Cursor / Codex / OpenCode) to write CLI output to `.context/cli/` and read a slice. If a CLI is missing, the user presses Install CLI on that row. Do not add vendor MCPs. Git (`gh`) stays Settings \u2192 Git; issue tracking stays Settings \u2192 Issues. The phone remote is Settings \u2192 Remote \u2014 do not look up Slack users.",
394
+ "- Optional connectors (Vercel, Supabase, Sentry) in Settings \u2192 Connectors inject tokens into worktree agent env when connected. Prefer official CLIs (`vercel`, `supabase`, `sentry-cli`). When Settings \u2192 Connectors has a PostHog personal API key, PostHog is the Sideboard tool `posthog_api` (GET by default; POST `/api/projects/:id/query/` or `/api/environments/:id/query/` is a read and does not need write=true; other POST and PATCH need write=true only when the user asked to change data). The PostHog key stays in the vault \u2014 do not read it from the environment, and do not sign in to a PostHog MCP. When no PostHog API key is set, use the Claude PostHog connector. When a key is set, ignore a failed Claude PostHog connector and do not sign in to a PostHog MCP. If a Vercel, Supabase, or Sentry MCP needsAuth or is unauthorized while that Sideboard token is set, do not sign in \u2014 use the native CLI. When that token is not set or the CLI call fails, the Claude connector is the fallback. Do not mention a Claude connector startup failure when the Sideboard connection works. Tell any worktree agent (Claude / Cursor / Codex / OpenCode) to write CLI output to `.context/cli/` and read a slice. If a CLI is missing, the user presses Install CLI on that row. Do not add vendor MCPs. Git (`gh`) stays Settings \u2192 Git; issue tracking stays Settings \u2192 Issues. The phone remote is Settings \u2192 Remote \u2014 do not look up Slack users.",
395
395
  "- get_pr_stack / open_pr_stack_layers / add_stack_layer / create_pr_stack \u2014 GitHub stacked PRs (`gh stack`); one worktree per layer",
396
396
  "- list_models \u2014 only when you need a specific model (rare); otherwise omit model so Account defaults apply",
397
397
  "- list_chats / get_chat \u2014 live thread list (parent id + last message preview). get_chat on this orchestration chat lists child worktree agents (status + lastText). blockedReason is why that agent is waiting on a person. Also includes usage / lastTurnUsage. Archived workspaces and agents are list_archive, not this list.",
@@ -34,9 +34,9 @@ import {
34
34
  tryReservePort,
35
35
  tryReservePorts,
36
36
  worktreeRunPortsPath
37
- } from "./chunk-ZW7RSQHY.js";
37
+ } from "./chunk-5QYCCXXQ.js";
38
38
  import "./chunk-I5TESHDN.js";
39
- import "./chunk-X3FSWWW2.js";
39
+ import "./chunk-S3KYDK6W.js";
40
40
  import "./chunk-DLGGLV2M.js";
41
41
  import "./chunk-N2WW62LF.js";
42
42
  import "./chunk-DD67JWTN.js";
@@ -32,9 +32,9 @@ import {
32
32
  tryReservePort,
33
33
  tryReservePorts,
34
34
  worktreeRunPortsPath
35
- } from "./chunk-QC2TQMPJ.js";
35
+ } from "./chunk-7UP4D5XI.js";
36
36
  import "./chunk-7Q327QF2.js";
37
- import "./chunk-5QX2NYXL.js";
37
+ import "./chunk-ZSVKUOFH.js";
38
38
  import "./chunk-BIPXOHZI.js";
39
39
  import "./chunk-HG25AYBV.js";
40
40
  import "./chunk-2P4XKWV2.js";
@@ -3,14 +3,15 @@
3
3
  import {
4
4
  applyConnectedTeamToCli,
5
5
  brightsyMcpServerName,
6
+ brightsySessionShouldReplace,
6
7
  connectBrightsyTeam,
7
8
  disconnectBrightsyTeam,
8
9
  ensureCliTeamTracked,
9
10
  ensureConnectedBrightsyTeamTokens,
10
11
  getConnectedBrightsyTeamsRaw,
11
12
  listConnectedBrightsyTeams
12
- } from "./chunk-42JGPPVS.js";
13
- import "./chunk-PXMLMBMI.js";
13
+ } from "./chunk-V5BTGQ6M.js";
14
+ import "./chunk-E63AM3PW.js";
14
15
  import "./chunk-2GPQZZLY.js";
15
16
  import "./chunk-2UG25RMK.js";
16
17
  import "./chunk-WWUABK6B.js";
@@ -18,6 +19,7 @@ import "./chunk-WOU343SI.js";
18
19
  export {
19
20
  applyConnectedTeamToCli,
20
21
  brightsyMcpServerName,
22
+ brightsySessionShouldReplace,
21
23
  connectBrightsyTeam,
22
24
  disconnectBrightsyTeam,
23
25
  ensureCliTeamTracked,
@@ -1,14 +1,15 @@
1
1
  import {
2
2
  applyConnectedTeamToCli,
3
3
  brightsyMcpServerName,
4
+ brightsySessionShouldReplace,
4
5
  connectBrightsyTeam,
5
6
  disconnectBrightsyTeam,
6
7
  ensureCliTeamTracked,
7
8
  ensureConnectedBrightsyTeamTokens,
8
9
  getConnectedBrightsyTeamsRaw,
9
10
  listConnectedBrightsyTeams
10
- } from "./chunk-VEVFHO6K.js";
11
- import "./chunk-33KDPEK4.js";
11
+ } from "./chunk-HH3VVTEC.js";
12
+ import "./chunk-RSA47QYR.js";
12
13
  import "./chunk-JAT3JFOS.js";
13
14
  import "./chunk-QVN2WOKJ.js";
14
15
  import "./chunk-4TR3HZFT.js";
@@ -16,6 +17,7 @@ import "./chunk-H4UEFJRI.js";
16
17
  export {
17
18
  applyConnectedTeamToCli,
18
19
  brightsyMcpServerName,
20
+ brightsySessionShouldReplace,
19
21
  connectBrightsyTeam,
20
22
  disconnectBrightsyTeam,
21
23
  ensureCliTeamTracked,
@@ -7,7 +7,7 @@ import {
7
7
  enrichWorkspacesWithGithub,
8
8
  ensureGlobalCoordinatorCwd,
9
9
  formatWorkspaceInventory
10
- } from "./chunk-5QX2NYXL.js";
10
+ } from "./chunk-ZSVKUOFH.js";
11
11
  import "./chunk-BIPXOHZI.js";
12
12
  import "./chunk-HG25AYBV.js";
13
13
  import "./chunk-2P4XKWV2.js";
@@ -9,7 +9,7 @@ import {
9
9
  enrichWorkspacesWithGithub,
10
10
  ensureGlobalCoordinatorCwd,
11
11
  formatWorkspaceInventory
12
- } from "./chunk-X3FSWWW2.js";
12
+ } from "./chunk-S3KYDK6W.js";
13
13
  import "./chunk-DLGGLV2M.js";
14
14
  import "./chunk-N2WW62LF.js";
15
15
  import "./chunk-DD67JWTN.js";