@sideboard-ai/core 0.1.45 → 0.1.49

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 (45) hide show
  1. package/dist/agents/cursor-runner.cjs +11 -4
  2. package/dist/agents/cursor-runner.js +11 -4
  3. package/dist/{agents-JSHCAZUZ.js → agents-3P4N6KHC.js} +12 -2
  4. package/dist/agents-LUB3Q773.js +82 -0
  5. package/dist/app-settings-7XVDQJ7F.js +80 -0
  6. package/dist/{app-settings-LYGVDGZY.js → app-settings-LZP632KI.js} +1 -1
  7. package/dist/{chunk-U3EQKJHA.js → chunk-3NAS4MWH.js} +1 -1
  8. package/dist/{chunk-ZNSM2DDD.js → chunk-5WYEJ3F3.js} +6 -2
  9. package/dist/chunk-7MV3RXSC.js +277 -0
  10. package/dist/chunk-DF5VQQKA.js +191 -0
  11. package/dist/chunk-E35APBHV.js +269 -0
  12. package/dist/chunk-EOYDCKQC.js +172 -0
  13. package/dist/chunk-GI7E5733.js +30 -0
  14. package/dist/chunk-GZXBYHJC.js +148 -0
  15. package/dist/chunk-HBJSHRY2.js +494 -0
  16. package/dist/chunk-ISY4EGF6.js +77 -0
  17. package/dist/chunk-KGZBYWZ3.js +23 -0
  18. package/dist/chunk-RQI4TOXK.js +2232 -0
  19. package/dist/chunk-S2LL5HA4.js +33 -0
  20. package/dist/{chunk-ANZ566Z5.js → chunk-SS34TVSY.js} +66 -7
  21. package/dist/{chunk-WYY3J7GR.js → chunk-T5QQVXK3.js} +6 -3
  22. package/dist/chunk-V4JRXYYU.js +122 -0
  23. package/dist/{chunk-6NAPN2N5.js → chunk-ZQCQIWIP.js} +1 -1
  24. package/dist/chunk-ZVV5EEQN.js +1892 -0
  25. package/dist/connected-teams-UBXHZGO4.js +24 -0
  26. package/dist/{coordinator-prompt-2XFYG3C5.js → coordinator-prompt-SPGDT7J5.js} +1 -1
  27. package/dist/coordinator-prompt-VG4BZ5JL.js +25 -0
  28. package/dist/cursor-recover-NNK7JPQM.js +44 -0
  29. package/dist/{global-workspace-YFOQUGWD.js → global-workspace-KSR3E63K.js} +3 -2
  30. package/dist/global-workspace-OJF4ENH4.js +40 -0
  31. package/dist/index.cjs +377 -30
  32. package/dist/index.d.cts +70 -11
  33. package/dist/index.d.ts +70 -11
  34. package/dist/index.js +5779 -193
  35. package/dist/mcp/run-stdio.cjs +331 -32
  36. package/dist/mcp/run-stdio.js +5618 -14
  37. package/dist/paths-2OFB7UJG.js +28 -0
  38. package/dist/run-HMRSRG3U.js +12 -0
  39. package/dist/thread-store-XICUWFNM.js +32 -0
  40. package/dist/title-4WAKWZRF.js +27 -0
  41. package/dist/workspaces-OZE7LRDO.js +24 -0
  42. package/dist/{workspaces-TIKLNDW3.js → workspaces-UJX7JIGH.js} +4 -3
  43. package/dist/worktree-XG5PCLZY.js +94 -0
  44. package/package.json +2 -2
  45. package/dist/chunk-I6QGZOOS.js +0 -5667
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+
3
+
4
+ // src/agents/orchestrator-capable.ts
5
+ var ORCHESTRATOR_AGENT_KINDS = [
6
+ "claude",
7
+ "codex",
8
+ "opencode",
9
+ "cursor"
10
+ ];
11
+ function isOrchestratorCapableAgent(agent) {
12
+ return Boolean(
13
+ agent && ORCHESTRATOR_AGENT_KINDS.includes(agent)
14
+ );
15
+ }
16
+ function assertOrchestratorCapableAgent(agent, context = "orchestration") {
17
+ if (!isOrchestratorCapableAgent(agent)) {
18
+ throw new Error(
19
+ `${agent} cannot run ${context} \u2014 it does not support Sideboard MCP. Use Claude, Cursor, Codex, or OpenCode.`
20
+ );
21
+ }
22
+ return agent;
23
+ }
24
+ function coerceOrchestratorAgent(agent, fallback = "claude") {
25
+ return isOrchestratorCapableAgent(agent) ? agent : fallback;
26
+ }
27
+
28
+ export {
29
+ ORCHESTRATOR_AGENT_KINDS,
30
+ isOrchestratorCapableAgent,
31
+ assertOrchestratorCapableAgent,
32
+ coerceOrchestratorAgent
33
+ };
@@ -15,7 +15,7 @@ import {
15
15
  claudeChromeEnabled,
16
16
  loadAppSettings,
17
17
  resolveClaudeExecutable
18
- } from "./chunk-WYY3J7GR.js";
18
+ } from "./chunk-T5QQVXK3.js";
19
19
  import {
20
20
  ensureAgentPath,
21
21
  run
@@ -597,6 +597,45 @@ async function buildInjectedMcpServers(opts) {
597
597
  }
598
598
  return servers;
599
599
  }
600
+ function toCursorMcpServers(servers) {
601
+ const out = {};
602
+ for (const s of servers) {
603
+ out[s.name] = {
604
+ command: s.command,
605
+ ...s.args ? { args: s.args } : {},
606
+ ...s.env ? { env: s.env } : {}
607
+ };
608
+ }
609
+ return out;
610
+ }
611
+ function toCodexMcpConfigArgs(servers) {
612
+ const args = [];
613
+ for (const s of servers) {
614
+ const prefix = `mcp_servers.${s.name}`;
615
+ args.push("-c", `${prefix}.command=${JSON.stringify(s.command)}`);
616
+ if (s.args?.length) {
617
+ args.push("-c", `${prefix}.args=${JSON.stringify(s.args)}`);
618
+ }
619
+ if (s.env) {
620
+ for (const [key, value] of Object.entries(s.env)) {
621
+ args.push("-c", `${prefix}.env.${key}=${JSON.stringify(value)}`);
622
+ }
623
+ }
624
+ }
625
+ return args;
626
+ }
627
+ function toOpencodeMcpConfigContent(servers) {
628
+ const mcp = {};
629
+ for (const s of servers) {
630
+ mcp[s.name] = {
631
+ type: "local",
632
+ command: [s.command, ...s.args ?? []],
633
+ enabled: true,
634
+ ...s.env && Object.keys(s.env).length > 0 ? { environment: s.env } : {}
635
+ };
636
+ }
637
+ return JSON.stringify({ mcp });
638
+ }
600
639
  function writeMcpServersConfig(servers) {
601
640
  if (servers.length === 0) return null;
602
641
  const mcpServers = {};
@@ -798,7 +837,7 @@ var claudeAdapter = {
798
837
  );
799
838
  }
800
839
  const mode = permissionMode(thread);
801
- const { isOrchestratorThread } = await import("./global-workspace-YFOQUGWD.js");
840
+ const { isOrchestratorThread } = await import("./global-workspace-KSR3E63K.js");
802
841
  const isOrchestrator = isOrchestratorThread(thread);
803
842
  const injectedServers = await buildInjectedMcpServers({
804
843
  includeSideboard: true,
@@ -1104,6 +1143,11 @@ var codexAdapter = {
1104
1143
  }
1105
1144
  const mode = permissionMode(thread);
1106
1145
  const model = thread.model?.trim();
1146
+ const injected = await buildInjectedMcpServers({
1147
+ includeSideboard: true,
1148
+ includeBrightsy: isBrightsyConnected()
1149
+ });
1150
+ const mcpOverrides = toCodexMcpConfigArgs(injected);
1107
1151
  const args = [
1108
1152
  "exec",
1109
1153
  ...sessionId ? ["resume", sessionId] : [],
@@ -1115,7 +1159,8 @@ var codexAdapter = {
1115
1159
  mode.codexSandbox,
1116
1160
  "--ask-for-approval",
1117
1161
  "never",
1118
- ...model ? ["--model", model] : []
1162
+ ...model ? ["--model", model] : [],
1163
+ ...mcpOverrides
1119
1164
  ];
1120
1165
  return {
1121
1166
  file: "codex",
@@ -1338,6 +1383,11 @@ var cursorAdapter = {
1338
1383
  const prompt = flattenTurnInput(input);
1339
1384
  const agentId = await this.resolveSessionId(thread.worktreePath, thread.sessionId);
1340
1385
  const apiKey = resolveCursorApiKey() || void 0;
1386
+ const injected = await buildInjectedMcpServers({
1387
+ includeSideboard: true,
1388
+ includeBrightsy: isBrightsyConnected()
1389
+ });
1390
+ const mcpServers = toCursorMcpServers(injected);
1341
1391
  const req = {
1342
1392
  prompt,
1343
1393
  cwd: thread.worktreePath,
@@ -1346,7 +1396,8 @@ var cursorAdapter = {
1346
1396
  effort: thread.effort,
1347
1397
  fast: thread.fast,
1348
1398
  planMode: thread.planMode,
1349
- apiKey
1399
+ apiKey,
1400
+ ...Object.keys(mcpServers).length > 0 ? { mcpServers } : {}
1350
1401
  };
1351
1402
  const runner = cursorRunnerPath();
1352
1403
  const isTs = runner.endsWith(".ts");
@@ -1490,6 +1541,11 @@ var opencodeAdapter = {
1490
1541
  if (model) {
1491
1542
  args.push("--model", model);
1492
1543
  }
1544
+ const injected = await buildInjectedMcpServers({
1545
+ includeSideboard: true,
1546
+ includeBrightsy: isBrightsyConnected()
1547
+ });
1548
+ const mcpContent = injected.length > 0 ? toOpencodeMcpConfigContent(injected) : null;
1493
1549
  return {
1494
1550
  file: "opencode",
1495
1551
  args,
@@ -1498,7 +1554,8 @@ var opencodeAdapter = {
1498
1554
  // message is given (see resolveRunInput in opencode's run.ts).
1499
1555
  stdin: prompt,
1500
1556
  env: {
1501
- OPENCODE_PERMISSION: mode.opencodePermission
1557
+ OPENCODE_PERMISSION: mode.opencodePermission,
1558
+ ...mcpContent ? { OPENCODE_CONFIG_CONTENT: mcpContent } : {}
1502
1559
  }
1503
1560
  };
1504
1561
  },
@@ -1784,11 +1841,13 @@ var FALLBACK_ORDER = [
1784
1841
  "cursor",
1785
1842
  "codex",
1786
1843
  "opencode",
1787
- "brightsy",
1788
1844
  "claude"
1789
1845
  ];
1790
1846
  function resolveQuotaFallbackAgent(current, preferred) {
1791
- const ordered = preferred ? [preferred, ...FALLBACK_ORDER.filter((a) => a !== preferred)] : FALLBACK_ORDER;
1847
+ const ordered = [
1848
+ ...preferred && preferred !== "brightsy" ? [preferred] : [],
1849
+ ...FALLBACK_ORDER.filter((a) => a !== preferred)
1850
+ ];
1792
1851
  return ordered.find((a) => a !== current) ?? (current === "cursor" ? "codex" : "cursor");
1793
1852
  }
1794
1853
 
@@ -133,7 +133,7 @@ function normalizeAdvanced(raw) {
133
133
  if (source.orchestrationQuotaOnLimit === "switch_agent" || source.orchestrationQuotaOnLimit === "wait_reset") {
134
134
  out.orchestrationQuotaOnLimit = source.orchestrationQuotaOnLimit;
135
135
  }
136
- if (typeof source.orchestrationQuotaFallbackAgent === "string" && DEFAULT_AGENTS.has(source.orchestrationQuotaFallbackAgent)) {
136
+ if (typeof source.orchestrationQuotaFallbackAgent === "string" && DEFAULT_AGENTS.has(source.orchestrationQuotaFallbackAgent) && source.orchestrationQuotaFallbackAgent !== "brightsy") {
137
137
  out.orchestrationQuotaFallbackAgent = source.orchestrationQuotaFallbackAgent;
138
138
  }
139
139
  return out;
@@ -381,7 +381,7 @@ function updateAdvancedSettings(patch) {
381
381
  if (patch.orchestrationQuotaOnLimit === "switch_agent" || patch.orchestrationQuotaOnLimit === "wait_reset") {
382
382
  advanced.orchestrationQuotaOnLimit = patch.orchestrationQuotaOnLimit;
383
383
  }
384
- if (typeof patch.orchestrationQuotaFallbackAgent === "string" && DEFAULT_AGENTS.has(patch.orchestrationQuotaFallbackAgent)) {
384
+ if (typeof patch.orchestrationQuotaFallbackAgent === "string" && DEFAULT_AGENTS.has(patch.orchestrationQuotaFallbackAgent) && patch.orchestrationQuotaFallbackAgent !== "brightsy") {
385
385
  advanced.orchestrationQuotaFallbackAgent = patch.orchestrationQuotaFallbackAgent;
386
386
  }
387
387
  return saveAppSettings({ ...current, advanced });
@@ -409,7 +409,10 @@ function orchestrationQuotaOnLimit(settings = loadAppSettings()) {
409
409
  }
410
410
  function orchestrationQuotaFallbackAgent(settings = loadAppSettings()) {
411
411
  const preferred = settings.advanced.orchestrationQuotaFallbackAgent;
412
- return preferred && DEFAULT_AGENTS.has(preferred) ? preferred : "cursor";
412
+ if (preferred && DEFAULT_AGENTS.has(preferred) && preferred !== "brightsy") {
413
+ return preferred;
414
+ }
415
+ return "cursor";
413
416
  }
414
417
  function maxConcurrentAgents(settings = loadAppSettings()) {
415
418
  const n = settings.advanced.maxConcurrent;
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ isGlobalRepoPath
5
+ } from "./chunk-DF5VQQKA.js";
6
+ import {
7
+ ensureGhPreferOrigin,
8
+ resolveRepoRoot
9
+ } from "./chunk-ZVV5EEQN.js";
10
+ import {
11
+ appDataDir
12
+ } from "./chunk-7MV3RXSC.js";
13
+
14
+ // src/store/workspaces.ts
15
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
16
+ import { basename, join } from "path";
17
+ function workspacesFile() {
18
+ return join(appDataDir(), "workspaces.json");
19
+ }
20
+ function removedWorkspacesFile() {
21
+ return join(appDataDir(), "removed-workspaces.json");
22
+ }
23
+ function readAll() {
24
+ const path = workspacesFile();
25
+ if (!existsSync(path)) return [];
26
+ try {
27
+ const raw = JSON.parse(readFileSync(path, "utf8"));
28
+ return Array.isArray(raw) ? raw : [];
29
+ } catch {
30
+ return [];
31
+ }
32
+ }
33
+ function writeAll(list) {
34
+ mkdirSync(appDataDir(), { recursive: true });
35
+ writeFileSync(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
36
+ }
37
+ function readRemoved() {
38
+ const path = removedWorkspacesFile();
39
+ if (!existsSync(path)) return /* @__PURE__ */ new Set();
40
+ try {
41
+ const raw = JSON.parse(readFileSync(path, "utf8"));
42
+ return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
43
+ } catch {
44
+ return /* @__PURE__ */ new Set();
45
+ }
46
+ }
47
+ function writeRemoved(paths) {
48
+ mkdirSync(appDataDir(), { recursive: true });
49
+ writeFileSync(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
50
+ }
51
+ function rememberRemoved(repoPath) {
52
+ const next = readRemoved();
53
+ next.add(repoPath);
54
+ writeRemoved(next);
55
+ }
56
+ function forgetRemoved(repoPath) {
57
+ const next = readRemoved();
58
+ if (!next.delete(repoPath)) return;
59
+ writeRemoved(next);
60
+ }
61
+ function listWorkspaces() {
62
+ const all = readAll();
63
+ const valid = all.filter(
64
+ (w) => Boolean(w.path) && w.path !== "/" && w.path !== "." && !isGlobalRepoPath(w.path)
65
+ );
66
+ if (valid.length !== all.length) writeAll(valid);
67
+ return valid.sort((a, b) => a.name.localeCompare(b.name));
68
+ }
69
+ async function addWorkspace(repoPath) {
70
+ const root = await resolveRepoRoot(repoPath);
71
+ if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
72
+ if (!existsSync(root)) throw new Error(`Repo not found: ${root}`);
73
+ forgetRemoved(root);
74
+ await ensureGhPreferOrigin(root);
75
+ const current = readAll();
76
+ const existing = current.find((w) => w.path === root);
77
+ if (existing) return existing;
78
+ const next = {
79
+ path: root,
80
+ name: basename(root),
81
+ addedAt: (/* @__PURE__ */ new Date()).toISOString()
82
+ };
83
+ writeAll([...current, next]);
84
+ return next;
85
+ }
86
+ function removeWorkspace(repoPath) {
87
+ writeAll(readAll().filter((w) => w.path !== repoPath));
88
+ rememberRemoved(repoPath);
89
+ }
90
+ async function ensureWorkspace(repoPath) {
91
+ return addWorkspace(repoPath);
92
+ }
93
+ function syncWorkspacesFromThreads(repoPaths) {
94
+ const current = readAll();
95
+ const removed = readRemoved();
96
+ const byPath = new Map(current.map((w) => [w.path, w]));
97
+ let dirty = false;
98
+ for (const path of repoPaths) {
99
+ if (!path || path === "/" || isGlobalRepoPath(path) || byPath.has(path) || removed.has(path)) {
100
+ continue;
101
+ }
102
+ if (!existsSync(path)) continue;
103
+ const ws = {
104
+ path,
105
+ name: basename(path),
106
+ addedAt: (/* @__PURE__ */ new Date()).toISOString()
107
+ };
108
+ byPath.set(path, ws);
109
+ dirty = true;
110
+ }
111
+ const next = [...byPath.values()];
112
+ if (dirty) writeAll(next);
113
+ return next.sort((a, b) => a.name.localeCompare(b.name));
114
+ }
115
+
116
+ export {
117
+ listWorkspaces,
118
+ addWorkspace,
119
+ removeWorkspace,
120
+ ensureWorkspace,
121
+ syncWorkspacesFromThreads
122
+ };
@@ -59,7 +59,7 @@ var COORDINATOR_TOOL_PLAYBOOK = [
59
59
  "- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
60
60
  "Inspect / review / PRs:",
61
61
  "- get_diff \u2014 compact diff summary",
62
- "- request_review \u2014 open a Review chat tab on a worktree thread (merge-readiness recommendation); then wait_for_turn / get_turn_result on the returned id",
62
+ '- request_review \u2014 open a Review chat tab on a worktree thread (attaches .sideboard/review.md when present, else local guidelines; sends "Review."); then wait_for_turn / get_turn_result on the returned id',
63
63
  "- Ask the worktree agent via send_to_thread to open a draft PR with `gh pr create --draft -R <origin-owner/name>` (workspace `github:` slug / that worktree's origin \u2014 never upstream). Do not open PRs from the orchestrator yourself.",
64
64
  "Human-only (do not attempt): merge, ready-for-review land, purge_thread.",
65
65
  "Thread links in replies: when mentioning a chat/thread for the user, include a markdown link `[Title](sideboard://thread/<id>)` using the full id (or the link field from create_thread / list_threads). Sideboard renders these as clickable opens.",