@sideboard-ai/core 0.1.287 → 0.1.289

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 (65) hide show
  1. package/dist/{abletime-I4RODUKT.js → abletime-4WJUVE64.js} +4 -4
  2. package/dist/{abletime-4CH2IOX5.js → abletime-VFKYNSJT.js} +4 -4
  3. package/dist/{abletime-oauth-7OZZ3ABX.js → abletime-oauth-FW24YHYX.js} +3 -3
  4. package/dist/{abletime-oauth-C2HN2Q6F.js → abletime-oauth-ICMB2XV2.js} +3 -3
  5. package/dist/{abletime-rest-E4LBRFLM.js → abletime-rest-HFMRTUDT.js} +3 -3
  6. package/dist/{abletime-rest-WFI2HWBU.js → abletime-rest-OGWC7BC6.js} +3 -3
  7. package/dist/agents/cursor-runner.js +3 -3
  8. package/dist/{agents-D3PU4UCP.js → agents-4BBCKITL.js} +20 -18
  9. package/dist/{agents-KU4QPB3Y.js → agents-XAKSP653.js} +18 -16
  10. package/dist/{app-settings-EQQZQNYD.js → app-settings-EHMXHNG5.js} +1 -1
  11. package/dist/{app-settings-NI4X5HW3.js → app-settings-MR2U6AXN.js} +1 -1
  12. package/dist/{chunk-K5XSTHHP.js → chunk-2IXKTAIT.js} +2 -2
  13. package/dist/{chunk-YNTXWFXT.js → chunk-36J3IZBS.js} +12 -12
  14. package/dist/{chunk-IJMUYHPT.js → chunk-3E4NOIXN.js} +3 -3
  15. package/dist/chunk-4BXRRHDC.js +139 -0
  16. package/dist/{chunk-5MGLNVNK.js → chunk-5HPMKLJ7.js} +2 -2
  17. package/dist/{chunk-VOIWX5HA.js → chunk-7UUILVMV.js} +1 -1
  18. package/dist/chunk-AF2DMY3K.js +295 -0
  19. package/dist/{chunk-5QOLFOAX.js → chunk-AFLNFGGB.js} +1 -1
  20. package/dist/{chunk-5T4YWFLD.js → chunk-AHH5USEA.js} +2 -2
  21. package/dist/{chunk-6CVVNAIU.js → chunk-B3BPLPKQ.js} +2 -2
  22. package/dist/{chunk-LKVP7JCB.js → chunk-C546EOEF.js} +35 -315
  23. package/dist/{chunk-QPBR5SAL.js → chunk-EBGJXOXT.js} +27 -129
  24. package/dist/{chunk-RFPMTOV2.js → chunk-G74TSBJ3.js} +6 -6
  25. package/dist/{chunk-L65YT2SC.js → chunk-GBAACE3C.js} +7 -7
  26. package/dist/{chunk-VQEARG5H.js → chunk-GU6DT6NO.js} +5 -5
  27. package/dist/{chunk-S2OOM7AU.js → chunk-K6IOJI3L.js} +1 -1
  28. package/dist/{chunk-UFJLNCOF.js → chunk-LUQ7MIVD.js} +8 -298
  29. package/dist/{chunk-U6QDXT4K.js → chunk-MIVX7QKI.js} +1 -1
  30. package/dist/{chunk-WRIMAEF2.js → chunk-MVZO7QZ2.js} +12 -12
  31. package/dist/{chunk-LS4FFCPL.js → chunk-MYJYINTS.js} +3 -3
  32. package/dist/{chunk-DEJALWKM.js → chunk-NFPWLDCH.js} +5 -5
  33. package/dist/chunk-NXXQFLNQ.js +300 -0
  34. package/dist/{chunk-KLAQ4G34.js → chunk-O4324MXE.js} +4 -4
  35. package/dist/chunk-OH4EN323.js +89 -0
  36. package/dist/{chunk-ZGAMETNF.js → chunk-V3BSO2O6.js} +4 -4
  37. package/dist/{chunk-Z3EE3PUZ.js → chunk-VNCPRMIK.js} +10 -300
  38. package/dist/chunk-W2KZTDET.js +302 -0
  39. package/dist/{chunk-TMM4FEZ5.js → chunk-Y67TBJD5.js} +3 -3
  40. package/dist/{chunk-XSDCLM3F.js → chunk-YSLCWCMJ.js} +1 -1
  41. package/dist/{conductor-FOKYVMUE.js → conductor-5MNGC25D.js} +6 -6
  42. package/dist/{conductor-KDUL6AMD.js → conductor-UFJXJPTF.js} +7 -7
  43. package/dist/{coordinator-prompt-GU5PGLG6.js → coordinator-prompt-5Q66Y5KW.js} +4 -4
  44. package/dist/{coordinator-prompt-YARYX53V.js → coordinator-prompt-BYPEW6DE.js} +4 -4
  45. package/dist/{global-workspace-SMCPOWE5.js → global-workspace-BTH2YGDZ.js} +4 -4
  46. package/dist/{global-workspace-C5HMC66E.js → global-workspace-YKOYXSB2.js} +4 -4
  47. package/dist/index.cjs +618 -323
  48. package/dist/index.d.cts +42 -10
  49. package/dist/index.d.ts +42 -10
  50. package/dist/index.js +494 -281
  51. package/dist/mcp/run-stdio.cjs +602 -225
  52. package/dist/mcp/run-stdio.js +334 -188
  53. package/dist/optional-cli-6SW4OOX3.js +23 -0
  54. package/dist/optional-cli-FRUZSZ3U.js +98 -0
  55. package/dist/{orchestrator-2UAVOXTN.js → orchestrator-IG4VU7MT.js} +13 -11
  56. package/dist/{orchestrator-NWKE56BW.js → orchestrator-MKF3YBNK.js} +10 -8
  57. package/dist/{thread-store-7XBOUQ5K.js → thread-store-DPKESDFR.js} +1 -1
  58. package/dist/{thread-store-ZQZDREVH.js → thread-store-X6S2GIR5.js} +1 -1
  59. package/dist/{workspaces-KHQ5ETSQ.js → workspaces-ELO2YVTU.js} +4 -4
  60. package/dist/{workspaces-DQMDCRB2.js → workspaces-RFD6I4FM.js} +4 -4
  61. package/dist/{worktree-NKLNVNXX.js → worktree-ADVQ6X6C.js} +3 -3
  62. package/dist/{worktree-YTZC3UQN.js → worktree-TN7DZDJZ.js} +3 -3
  63. package/package.json +1 -1
  64. /package/dist/{chunk-N5UGX3JL.js → chunk-QB5MDOHL.js} +0 -0
  65. /package/dist/{chunk-JPH7PYSK.js → chunk-YRXV3E7J.js} +0 -0
@@ -9,16 +9,16 @@ import {
9
9
  looksLikeSkillBody,
10
10
  skillCommandFromBody,
11
11
  withEventParentId
12
- } from "./chunk-XSDCLM3F.js";
12
+ } from "./chunk-YSLCWCMJ.js";
13
13
  import {
14
14
  isOrchestratorThread
15
- } from "./chunk-ZGAMETNF.js";
15
+ } from "./chunk-V3BSO2O6.js";
16
16
  import {
17
17
  codexUnattendedGitConfigArgs,
18
18
  mergeAgentGitAuthEnv,
19
19
  resolveAgentGitAuthEnv,
20
20
  resolveCodexGitWritableRoots
21
- } from "./chunk-K5XSTHHP.js";
21
+ } from "./chunk-2IXKTAIT.js";
22
22
  import {
23
23
  loadBrightsyConfig
24
24
  } from "./chunk-33KDPEK4.js";
@@ -38,19 +38,15 @@ import {
38
38
  packagedMcpStdioPath,
39
39
  parseCursorRunnerLine,
40
40
  resolveNodeLaunch
41
- } from "./chunk-VOIWX5HA.js";
41
+ } from "./chunk-7UUILVMV.js";
42
42
  import {
43
43
  extractJsonErrorMessage,
44
44
  formatUnknownDetail,
45
45
  looksLikeAgentFailureMessage,
46
46
  looksLikeBrightsyEmptyCompletion
47
- } from "./chunk-U6QDXT4K.js";
47
+ } from "./chunk-MIVX7QKI.js";
48
48
  import {
49
- enrichPathWithNpmGlobalBin,
50
- isConductorBundledCli,
51
- resolveCommandBinarySync,
52
- run,
53
- withExportedPath
49
+ run
54
50
  } from "./chunk-QVN2WOKJ.js";
55
51
  import {
56
52
  AGENT_RPC_CLAUDE_SDK_SERVER,
@@ -71,7 +67,7 @@ import {
71
67
  loadAppSettings,
72
68
  resolveAgentExecutable,
73
69
  resolveClaudeExecutable
74
- } from "./chunk-YNTXWFXT.js";
70
+ } from "./chunk-36J3IZBS.js";
75
71
  import {
76
72
  isElectronLikeCommand,
77
73
  unwrapStrippedElectronLaunch
@@ -716,7 +712,8 @@ var SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS = [
716
712
  "mcp__sideboard__create_schedule",
717
713
  "mcp__sideboard__update_schedule",
718
714
  "mcp__sideboard__delete_schedule",
719
- "mcp__sideboard__run_schedule"
715
+ "mcp__sideboard__run_schedule",
716
+ "mcp__sideboard__posthog_api"
720
717
  ];
721
718
  var SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS = ["mcp__sideboard__github_*"];
722
719
  var SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS = ["mcp__sideboard__linear_*"];
@@ -1755,7 +1752,7 @@ var claudeAdapter = {
1755
1752
  );
1756
1753
  }
1757
1754
  const mode = permissionMode(thread);
1758
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-C5HMC66E.js");
1755
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-YKOYXSB2.js");
1759
1756
  const isOrchestrator = isOrchestratorThread2(thread);
1760
1757
  const rpc = worktreeAgentRpc(isOrchestrator);
1761
1758
  const injectedServers = await buildInjectedMcpServers({
@@ -3647,283 +3644,6 @@ async function getClaudePlanUsage(opts = {}) {
3647
3644
  return inflight;
3648
3645
  }
3649
3646
 
3650
- // src/agents/install.ts
3651
- import { existsSync as existsSync11 } from "fs";
3652
- var SETUP = {
3653
- claude: {
3654
- agent: "claude",
3655
- kind: "cli",
3656
- summary: "Install the Claude Code CLI, then complete login in a terminal.",
3657
- docsUrl: "https://code.claude.com/docs/en/install",
3658
- installCommand: "npm install -g @anthropic-ai/claude-code",
3659
- loginCommand: "claude auth login",
3660
- npmPackage: "@anthropic-ai/claude-code",
3661
- updateArgs: ["update"]
3662
- },
3663
- codex: {
3664
- agent: "codex",
3665
- kind: "cli",
3666
- summary: "Install the Codex CLI, then run login in a terminal.",
3667
- docsUrl: "https://github.com/openai/codex",
3668
- installCommand: "npm install -g @openai/codex",
3669
- loginCommand: "codex login",
3670
- npmPackage: "@openai/codex",
3671
- updateArgs: ["update"]
3672
- },
3673
- opencode: {
3674
- agent: "opencode",
3675
- kind: "cli",
3676
- summary: "Install OpenCode (curl installer or npm), then authenticate providers.",
3677
- docsUrl: "https://opencode.ai/docs",
3678
- // Prefer the official installer; npm package name is opencode-ai.
3679
- installCommand: "curl -fsSL https://opencode.ai/install | bash",
3680
- loginCommand: "opencode auth login",
3681
- npmPackage: "opencode-ai@latest",
3682
- updateArgs: ["upgrade"]
3683
- },
3684
- cursor: {
3685
- agent: "cursor",
3686
- kind: "cli",
3687
- summary: "Install (or update) @cursor/sdk with npm \u2014 Sideboard does not pin it in the app. Then add a CURSOR_API_KEY.",
3688
- docsUrl: "https://www.npmjs.com/package/@cursor/sdk",
3689
- installCommand: "npm install -g @cursor/sdk",
3690
- loginCommand: null,
3691
- npmPackage: "@cursor/sdk"
3692
- },
3693
- brightsy: {
3694
- agent: "brightsy",
3695
- kind: "cli",
3696
- summary: "Install (or update) the Brightsy CLI with npm, then run `brightsy login`.",
3697
- docsUrl: "https://www.npmjs.com/package/@brightsy/cli",
3698
- installCommand: "npm install -g @brightsy/cli",
3699
- loginCommand: "brightsy login",
3700
- npmPackage: "@brightsy/cli"
3701
- }
3702
- };
3703
- var CLI_BIN = {
3704
- claude: "claude",
3705
- codex: "codex",
3706
- opencode: "opencode",
3707
- brightsy: "brightsy"
3708
- };
3709
- function getAgentSetupInfo(agent) {
3710
- return SETUP[agent];
3711
- }
3712
- function listAgentSetupInfo() {
3713
- return Object.values(SETUP);
3714
- }
3715
- var CLI_LOGIN_AGENTS = /* @__PURE__ */ new Set([
3716
- "claude",
3717
- "codex",
3718
- "opencode",
3719
- "brightsy"
3720
- ]);
3721
- function resolveLoginCommand(agent) {
3722
- const info = getAgentSetupInfo(agent);
3723
- if (!info.loginCommand) return null;
3724
- if (!CLI_LOGIN_AGENTS.has(agent)) return info.loginCommand;
3725
- const exe = resolveAgentExecutable(agent);
3726
- return info.loginCommand.replace(/^\S+/, exe);
3727
- }
3728
- async function prepareTerminalCommand(command) {
3729
- enrichPathWithNpmGlobalBin();
3730
- const trimmed = command.trim();
3731
- if (!trimmed) return trimmed;
3732
- if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
3733
- const match = /^(\S+)(\s[\s\S]*)?$/.exec(trimmed);
3734
- const bin = match?.[1];
3735
- let whichPath = null;
3736
- if (bin && !bin.includes("/") && !bin.includes("\\")) {
3737
- const which = await run("which", [bin], { reject: false, timeoutMs: 3e3 });
3738
- whichPath = which.exitCode === 0 ? which.stdout.trim() : null;
3739
- }
3740
- const resolved = resolveCommandBinarySync(trimmed, whichPath);
3741
- return withExportedPath(resolved, process.env.PATH ?? "");
3742
- }
3743
- async function openInSystemTerminal(command) {
3744
- const trimmed = (await prepareTerminalCommand(command)).trim();
3745
- if (!trimmed) throw new Error("Command is empty");
3746
- if (process.platform === "darwin") {
3747
- const escaped = trimmed.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
3748
- const script = `tell application "Terminal" to do script "${escaped}"`;
3749
- const result = await run("osascript", ["-e", script], { reject: false });
3750
- if (result.exitCode !== 0) {
3751
- throw new Error(result.stderr.trim() || result.stdout.trim() || "Failed to open Terminal");
3752
- }
3753
- await run("osascript", ["-e", 'tell application "Terminal" to activate'], {
3754
- reject: false
3755
- });
3756
- return;
3757
- }
3758
- if (process.platform === "win32") {
3759
- const result = await run(
3760
- "cmd.exe",
3761
- ["/c", "start", "cmd.exe", "/k", trimmed],
3762
- { reject: false }
3763
- );
3764
- if (result.exitCode !== 0) {
3765
- throw new Error(result.stderr.trim() || result.stdout.trim() || "Failed to open cmd");
3766
- }
3767
- return;
3768
- }
3769
- const candidates = [
3770
- { file: "gnome-terminal", args: ["--", "bash", "-lc", `${trimmed}; exec bash`] },
3771
- { file: "x-terminal-emulator", args: ["-e", "bash", "-lc", `${trimmed}; exec bash`] },
3772
- { file: "konsole", args: ["-e", "bash", "-lc", `${trimmed}; exec bash`] },
3773
- { file: "xterm", args: ["-e", "bash", "-lc", `${trimmed}; exec bash`] }
3774
- ];
3775
- for (const c of candidates) {
3776
- const which = await run("which", [c.file], { reject: false });
3777
- if (which.exitCode !== 0 || !which.stdout.trim()) continue;
3778
- const result = await run(c.file, c.args, { reject: false });
3779
- if (result.exitCode === 0) return;
3780
- }
3781
- throw new Error(
3782
- `No terminal found to run: ${trimmed}. Install gnome-terminal (or similar), or run the command manually.`
3783
- );
3784
- }
3785
- async function whichOnPath(bin) {
3786
- const which = await run("which", [bin], { reject: false, timeoutMs: 3e3 });
3787
- if (which.exitCode !== 0) return null;
3788
- return which.stdout.trim().split(/\r?\n/).find(Boolean) ?? null;
3789
- }
3790
- async function installNpmGlobalPackage(opts) {
3791
- enrichPathWithNpmGlobalBin();
3792
- const result = await run("npm", ["install", "-g", opts.npmPackage], { reject: false });
3793
- const ok = result.exitCode === 0;
3794
- if (!ok) {
3795
- try {
3796
- await openInSystemTerminal(opts.installCommand);
3797
- return {
3798
- ok: false,
3799
- openedTerminal: true,
3800
- command: opts.installCommand,
3801
- exitCode: result.exitCode,
3802
- stdout: result.stdout,
3803
- stderr: result.stderr,
3804
- message: `npm install failed (exit ${result.exitCode}). Opened Terminal with: ${opts.installCommand}`
3805
- };
3806
- } catch {
3807
- return {
3808
- ok: false,
3809
- command: opts.installCommand,
3810
- exitCode: result.exitCode,
3811
- stdout: result.stdout,
3812
- stderr: result.stderr,
3813
- message: result.stderr.trim() || result.stdout.trim() || `npm install failed (exit ${result.exitCode})`
3814
- };
3815
- }
3816
- }
3817
- enrichPathWithNpmGlobalBin();
3818
- const binPath = opts.cliBin ? await whichOnPath(opts.cliBin) : null;
3819
- return {
3820
- ok: true,
3821
- command: opts.installCommand,
3822
- exitCode: 0,
3823
- stdout: result.stdout,
3824
- stderr: result.stderr,
3825
- // Library-only packages (`@cursor/sdk`) have no CLI to look for.
3826
- message: !opts.cliBin ? `Installed ${opts.npmPackage}` : binPath ? `Installed ${opts.npmPackage} \u2192 ${binPath}` : `Installed ${opts.npmPackage} (CLI not yet on PATH)`
3827
- };
3828
- }
3829
- async function resolveExistingCli(agent) {
3830
- if (agent === "cursor") return null;
3831
- const exe = resolveAgentExecutable(agent);
3832
- if ((exe.includes("/") || exe.includes("\\")) && existsSync11(exe)) return exe;
3833
- enrichPathWithNpmGlobalBin();
3834
- return whichOnPath(CLI_BIN[agent]);
3835
- }
3836
- async function runVendorUpdate(existing, updateArgs) {
3837
- const result = await run(existing, updateArgs, {
3838
- reject: false,
3839
- timeoutMs: 12e4
3840
- });
3841
- const command = `${existing} ${updateArgs.join(" ")}`;
3842
- const ok = result.exitCode === 0;
3843
- const detail = result.stdout.trim() || result.stderr.trim() || `exit ${result.exitCode}`;
3844
- return {
3845
- ok,
3846
- command,
3847
- exitCode: result.exitCode,
3848
- stdout: result.stdout,
3849
- stderr: result.stderr,
3850
- message: ok ? isConductorBundledCli(existing) ? `Updated Conductor\u2019s CLI at ${existing}. ${detail}` : `Updated ${command}. ${detail}` : `Update failed (${command}): ${detail}`
3851
- };
3852
- }
3853
- function isCurlInstaller(command) {
3854
- return /curl\s| \|\s*bash/.test(command);
3855
- }
3856
- async function installAgent(agent) {
3857
- const info = getAgentSetupInfo(agent);
3858
- if (info.kind === "bundled-sdk" || info.kind === "api-key") {
3859
- return {
3860
- ok: true,
3861
- message: info.summary
3862
- };
3863
- }
3864
- if (!info.installCommand) {
3865
- return { ok: false, message: `No install command for ${agent}` };
3866
- }
3867
- const existing = await resolveExistingCli(agent);
3868
- if (existing && info.updateArgs?.length) {
3869
- return runVendorUpdate(existing, info.updateArgs);
3870
- }
3871
- if (info.npmPackage && !isCurlInstaller(info.installCommand)) {
3872
- const cliBin = agent === "cursor" ? null : CLI_BIN[agent];
3873
- return installNpmGlobalPackage({
3874
- npmPackage: info.npmPackage,
3875
- installCommand: info.installCommand,
3876
- cliBin
3877
- });
3878
- }
3879
- await openInSystemTerminal(info.installCommand);
3880
- return {
3881
- ok: true,
3882
- openedTerminal: true,
3883
- command: info.installCommand,
3884
- message: `Opened Terminal to run: ${info.installCommand}`
3885
- };
3886
- }
3887
- async function loginAgent(agent) {
3888
- const info = getAgentSetupInfo(agent);
3889
- const loginCommand = resolveLoginCommand(agent);
3890
- if (!loginCommand) {
3891
- return {
3892
- ok: true,
3893
- message: info.kind === "bundled-sdk" || info.kind === "api-key" ? info.summary : `No login command for ${agent}`
3894
- };
3895
- }
3896
- const prepared = await prepareTerminalCommand(loginCommand);
3897
- await openInSystemTerminal(prepared);
3898
- return {
3899
- ok: true,
3900
- openedTerminal: true,
3901
- command: prepared,
3902
- message: `Opened Terminal to run: ${prepared}`
3903
- };
3904
- }
3905
- async function loginManagedAccount(accountId) {
3906
- const { loadAppSettings: loadAppSettings2 } = await import("./app-settings-NI4X5HW3.js");
3907
- const { loginEnvPrefix } = await import("./managed-accounts-2AK5RIAF.js");
3908
- const account = loadAppSettings2().accounts.accounts.find((a) => a.id === accountId);
3909
- if (!account) {
3910
- return { ok: false, message: `Account not found: ${accountId}` };
3911
- }
3912
- const loginCommand = resolveLoginCommand(account.kind);
3913
- if (!loginCommand) {
3914
- return { ok: false, message: `No login command for ${account.kind}` };
3915
- }
3916
- const prepared = await prepareTerminalCommand(loginCommand);
3917
- const prefixed = `${loginEnvPrefix(account)} && ${prepared}`;
3918
- await openInSystemTerminal(prefixed);
3919
- return {
3920
- ok: true,
3921
- openedTerminal: true,
3922
- command: prefixed,
3923
- message: `Opened Terminal to run: ${prefixed}`
3924
- };
3925
- }
3926
-
3927
3647
  // src/agents/index.ts
3928
3648
  var adapters = {
3929
3649
  claude: claudeAdapter,
@@ -4018,16 +3738,6 @@ export {
4018
3738
  formatClaudeUsageOverLimitConfirm,
4019
3739
  formatClaudeUsageOverLimitWait,
4020
3740
  getClaudePlanUsage,
4021
- getAgentSetupInfo,
4022
- listAgentSetupInfo,
4023
- resolveLoginCommand,
4024
- prepareTerminalCommand,
4025
- openInSystemTerminal,
4026
- whichOnPath,
4027
- installNpmGlobalPackage,
4028
- installAgent,
4029
- loginAgent,
4030
- loginManagedAccount,
4031
3741
  getAdapter,
4032
3742
  allAdapters
4033
3743
  };
@@ -0,0 +1,302 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ enrichPathWithNpmGlobalBin,
5
+ isConductorBundledCli,
6
+ resolveCommandBinarySync,
7
+ run,
8
+ withExportedPath
9
+ } from "./chunk-2UG25RMK.js";
10
+ import {
11
+ resolveAgentExecutable
12
+ } from "./chunk-MVZO7QZ2.js";
13
+
14
+ // src/agents/install.ts
15
+ import { existsSync } from "fs";
16
+ var SETUP = {
17
+ claude: {
18
+ agent: "claude",
19
+ kind: "cli",
20
+ summary: "Install the Claude Code CLI, then complete login in a terminal.",
21
+ docsUrl: "https://code.claude.com/docs/en/install",
22
+ installCommand: "npm install -g @anthropic-ai/claude-code",
23
+ loginCommand: "claude auth login",
24
+ npmPackage: "@anthropic-ai/claude-code",
25
+ updateArgs: ["update"]
26
+ },
27
+ codex: {
28
+ agent: "codex",
29
+ kind: "cli",
30
+ summary: "Install the Codex CLI, then run login in a terminal.",
31
+ docsUrl: "https://github.com/openai/codex",
32
+ installCommand: "npm install -g @openai/codex",
33
+ loginCommand: "codex login",
34
+ npmPackage: "@openai/codex",
35
+ updateArgs: ["update"]
36
+ },
37
+ opencode: {
38
+ agent: "opencode",
39
+ kind: "cli",
40
+ summary: "Install OpenCode (curl installer or npm), then authenticate providers.",
41
+ docsUrl: "https://opencode.ai/docs",
42
+ // Prefer the official installer; npm package name is opencode-ai.
43
+ installCommand: "curl -fsSL https://opencode.ai/install | bash",
44
+ loginCommand: "opencode auth login",
45
+ npmPackage: "opencode-ai@latest",
46
+ updateArgs: ["upgrade"]
47
+ },
48
+ cursor: {
49
+ agent: "cursor",
50
+ kind: "cli",
51
+ summary: "Install (or update) @cursor/sdk with npm \u2014 Sideboard does not pin it in the app. Then add a CURSOR_API_KEY.",
52
+ docsUrl: "https://www.npmjs.com/package/@cursor/sdk",
53
+ installCommand: "npm install -g @cursor/sdk",
54
+ loginCommand: null,
55
+ npmPackage: "@cursor/sdk"
56
+ },
57
+ brightsy: {
58
+ agent: "brightsy",
59
+ kind: "cli",
60
+ summary: "Install (or update) the Brightsy CLI with npm, then run `brightsy login`.",
61
+ docsUrl: "https://www.npmjs.com/package/@brightsy/cli",
62
+ installCommand: "npm install -g @brightsy/cli",
63
+ loginCommand: "brightsy login",
64
+ npmPackage: "@brightsy/cli"
65
+ }
66
+ };
67
+ var CLI_BIN = {
68
+ claude: "claude",
69
+ codex: "codex",
70
+ opencode: "opencode",
71
+ brightsy: "brightsy"
72
+ };
73
+ function getAgentSetupInfo(agent) {
74
+ return SETUP[agent];
75
+ }
76
+ function listAgentSetupInfo() {
77
+ return Object.values(SETUP);
78
+ }
79
+ var CLI_LOGIN_AGENTS = /* @__PURE__ */ new Set([
80
+ "claude",
81
+ "codex",
82
+ "opencode",
83
+ "brightsy"
84
+ ]);
85
+ function resolveLoginCommand(agent) {
86
+ const info = getAgentSetupInfo(agent);
87
+ if (!info.loginCommand) return null;
88
+ if (!CLI_LOGIN_AGENTS.has(agent)) return info.loginCommand;
89
+ const exe = resolveAgentExecutable(agent);
90
+ return info.loginCommand.replace(/^\S+/, exe);
91
+ }
92
+ async function prepareTerminalCommand(command) {
93
+ enrichPathWithNpmGlobalBin();
94
+ const trimmed = command.trim();
95
+ if (!trimmed) return trimmed;
96
+ if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
97
+ const match = /^(\S+)(\s[\s\S]*)?$/.exec(trimmed);
98
+ const bin = match?.[1];
99
+ let whichPath = null;
100
+ if (bin && !bin.includes("/") && !bin.includes("\\")) {
101
+ const which = await run("which", [bin], { reject: false, timeoutMs: 3e3 });
102
+ whichPath = which.exitCode === 0 ? which.stdout.trim() : null;
103
+ }
104
+ const resolved = resolveCommandBinarySync(trimmed, whichPath);
105
+ return withExportedPath(resolved, process.env.PATH ?? "");
106
+ }
107
+ async function openInSystemTerminal(command) {
108
+ const trimmed = (await prepareTerminalCommand(command)).trim();
109
+ if (!trimmed) throw new Error("Command is empty");
110
+ if (process.platform === "darwin") {
111
+ const escaped = trimmed.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
112
+ const script = `tell application "Terminal" to do script "${escaped}"`;
113
+ const result = await run("osascript", ["-e", script], { reject: false });
114
+ if (result.exitCode !== 0) {
115
+ throw new Error(result.stderr.trim() || result.stdout.trim() || "Failed to open Terminal");
116
+ }
117
+ await run("osascript", ["-e", 'tell application "Terminal" to activate'], {
118
+ reject: false
119
+ });
120
+ return;
121
+ }
122
+ if (process.platform === "win32") {
123
+ const result = await run(
124
+ "cmd.exe",
125
+ ["/c", "start", "cmd.exe", "/k", trimmed],
126
+ { reject: false }
127
+ );
128
+ if (result.exitCode !== 0) {
129
+ throw new Error(result.stderr.trim() || result.stdout.trim() || "Failed to open cmd");
130
+ }
131
+ return;
132
+ }
133
+ const candidates = [
134
+ { file: "gnome-terminal", args: ["--", "bash", "-lc", `${trimmed}; exec bash`] },
135
+ { file: "x-terminal-emulator", args: ["-e", "bash", "-lc", `${trimmed}; exec bash`] },
136
+ { file: "konsole", args: ["-e", "bash", "-lc", `${trimmed}; exec bash`] },
137
+ { file: "xterm", args: ["-e", "bash", "-lc", `${trimmed}; exec bash`] }
138
+ ];
139
+ for (const c of candidates) {
140
+ const which = await run("which", [c.file], { reject: false });
141
+ if (which.exitCode !== 0 || !which.stdout.trim()) continue;
142
+ const result = await run(c.file, c.args, { reject: false });
143
+ if (result.exitCode === 0) return;
144
+ }
145
+ throw new Error(
146
+ `No terminal found to run: ${trimmed}. Install gnome-terminal (or similar), or run the command manually.`
147
+ );
148
+ }
149
+ async function whichOnPath(bin) {
150
+ const which = await run("which", [bin], { reject: false, timeoutMs: 3e3 });
151
+ if (which.exitCode !== 0) return null;
152
+ return which.stdout.trim().split(/\r?\n/).find(Boolean) ?? null;
153
+ }
154
+ async function installNpmGlobalPackage(opts) {
155
+ enrichPathWithNpmGlobalBin();
156
+ const result = await run("npm", ["install", "-g", opts.npmPackage], { reject: false });
157
+ const ok = result.exitCode === 0;
158
+ if (!ok) {
159
+ try {
160
+ await openInSystemTerminal(opts.installCommand);
161
+ return {
162
+ ok: false,
163
+ openedTerminal: true,
164
+ command: opts.installCommand,
165
+ exitCode: result.exitCode,
166
+ stdout: result.stdout,
167
+ stderr: result.stderr,
168
+ message: `npm install failed (exit ${result.exitCode}). Opened Terminal with: ${opts.installCommand}`
169
+ };
170
+ } catch {
171
+ return {
172
+ ok: false,
173
+ command: opts.installCommand,
174
+ exitCode: result.exitCode,
175
+ stdout: result.stdout,
176
+ stderr: result.stderr,
177
+ message: result.stderr.trim() || result.stdout.trim() || `npm install failed (exit ${result.exitCode})`
178
+ };
179
+ }
180
+ }
181
+ enrichPathWithNpmGlobalBin();
182
+ const binPath = opts.cliBin ? await whichOnPath(opts.cliBin) : null;
183
+ return {
184
+ ok: true,
185
+ command: opts.installCommand,
186
+ exitCode: 0,
187
+ stdout: result.stdout,
188
+ stderr: result.stderr,
189
+ // Library-only packages (`@cursor/sdk`) have no CLI to look for.
190
+ message: !opts.cliBin ? `Installed ${opts.npmPackage}` : binPath ? `Installed ${opts.npmPackage} \u2192 ${binPath}` : `Installed ${opts.npmPackage} (CLI not yet on PATH)`
191
+ };
192
+ }
193
+ async function resolveExistingCli(agent) {
194
+ if (agent === "cursor") return null;
195
+ const exe = resolveAgentExecutable(agent);
196
+ if ((exe.includes("/") || exe.includes("\\")) && existsSync(exe)) return exe;
197
+ enrichPathWithNpmGlobalBin();
198
+ return whichOnPath(CLI_BIN[agent]);
199
+ }
200
+ async function runVendorUpdate(existing, updateArgs) {
201
+ const result = await run(existing, updateArgs, {
202
+ reject: false,
203
+ timeoutMs: 12e4
204
+ });
205
+ const command = `${existing} ${updateArgs.join(" ")}`;
206
+ const ok = result.exitCode === 0;
207
+ const detail = result.stdout.trim() || result.stderr.trim() || `exit ${result.exitCode}`;
208
+ return {
209
+ ok,
210
+ command,
211
+ exitCode: result.exitCode,
212
+ stdout: result.stdout,
213
+ stderr: result.stderr,
214
+ message: ok ? isConductorBundledCli(existing) ? `Updated Conductor\u2019s CLI at ${existing}. ${detail}` : `Updated ${command}. ${detail}` : `Update failed (${command}): ${detail}`
215
+ };
216
+ }
217
+ function isCurlInstaller(command) {
218
+ return /curl\s| \|\s*bash/.test(command);
219
+ }
220
+ async function installAgent(agent) {
221
+ const info = getAgentSetupInfo(agent);
222
+ if (info.kind === "bundled-sdk" || info.kind === "api-key") {
223
+ return {
224
+ ok: true,
225
+ message: info.summary
226
+ };
227
+ }
228
+ if (!info.installCommand) {
229
+ return { ok: false, message: `No install command for ${agent}` };
230
+ }
231
+ const existing = await resolveExistingCli(agent);
232
+ if (existing && info.updateArgs?.length) {
233
+ return runVendorUpdate(existing, info.updateArgs);
234
+ }
235
+ if (info.npmPackage && !isCurlInstaller(info.installCommand)) {
236
+ const cliBin = agent === "cursor" ? null : CLI_BIN[agent];
237
+ return installNpmGlobalPackage({
238
+ npmPackage: info.npmPackage,
239
+ installCommand: info.installCommand,
240
+ cliBin
241
+ });
242
+ }
243
+ await openInSystemTerminal(info.installCommand);
244
+ return {
245
+ ok: true,
246
+ openedTerminal: true,
247
+ command: info.installCommand,
248
+ message: `Opened Terminal to run: ${info.installCommand}`
249
+ };
250
+ }
251
+ async function loginAgent(agent) {
252
+ const info = getAgentSetupInfo(agent);
253
+ const loginCommand = resolveLoginCommand(agent);
254
+ if (!loginCommand) {
255
+ return {
256
+ ok: true,
257
+ message: info.kind === "bundled-sdk" || info.kind === "api-key" ? info.summary : `No login command for ${agent}`
258
+ };
259
+ }
260
+ const prepared = await prepareTerminalCommand(loginCommand);
261
+ await openInSystemTerminal(prepared);
262
+ return {
263
+ ok: true,
264
+ openedTerminal: true,
265
+ command: prepared,
266
+ message: `Opened Terminal to run: ${prepared}`
267
+ };
268
+ }
269
+ async function loginManagedAccount(accountId) {
270
+ const { loadAppSettings } = await import("./app-settings-EHMXHNG5.js");
271
+ const { loginEnvPrefix } = await import("./managed-accounts-46A4KRUE.js");
272
+ const account = loadAppSettings().accounts.accounts.find((a) => a.id === accountId);
273
+ if (!account) {
274
+ return { ok: false, message: `Account not found: ${accountId}` };
275
+ }
276
+ const loginCommand = resolveLoginCommand(account.kind);
277
+ if (!loginCommand) {
278
+ return { ok: false, message: `No login command for ${account.kind}` };
279
+ }
280
+ const prepared = await prepareTerminalCommand(loginCommand);
281
+ const prefixed = `${loginEnvPrefix(account)} && ${prepared}`;
282
+ await openInSystemTerminal(prefixed);
283
+ return {
284
+ ok: true,
285
+ openedTerminal: true,
286
+ command: prefixed,
287
+ message: `Opened Terminal to run: ${prefixed}`
288
+ };
289
+ }
290
+
291
+ export {
292
+ getAgentSetupInfo,
293
+ listAgentSetupInfo,
294
+ resolveLoginCommand,
295
+ prepareTerminalCommand,
296
+ openInSystemTerminal,
297
+ whichOnPath,
298
+ installNpmGlobalPackage,
299
+ installAgent,
300
+ loginAgent,
301
+ loginManagedAccount
302
+ };
@@ -3,13 +3,13 @@
3
3
  import {
4
4
  abletimeRestUrl,
5
5
  textFromAbleTimeDoc
6
- } from "./chunk-5T4YWFLD.js";
6
+ } from "./chunk-AHH5USEA.js";
7
7
  import {
8
8
  assertAbleTimeCredential,
9
9
  callAbleTimeTool,
10
10
  normalizeAbleTimeHost,
11
11
  rewriteAbleTimeError
12
- } from "./chunk-VQEARG5H.js";
12
+ } from "./chunk-GU6DT6NO.js";
13
13
  import {
14
14
  httpFetch
15
15
  } from "./chunk-2GPQZZLY.js";
@@ -22,7 +22,7 @@ import {
22
22
  getAbleTimeHost,
23
23
  isAbleTimeConnected,
24
24
  saveAbleTimeConnection
25
- } from "./chunk-WRIMAEF2.js";
25
+ } from "./chunk-MVZO7QZ2.js";
26
26
 
27
27
  // src/integrations/issue-attachments.ts
28
28
  import { existsSync, mkdirSync, writeFileSync } from "fs";