@sideboard-ai/core 0.1.67 → 0.1.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/{agents-OTBZVTZO.js → agents-GB7XL2LI.js} +8 -7
  2. package/dist/{agents-TS3EI2YI.js → agents-TCAK3MXN.js} +8 -7
  3. package/dist/{app-settings-ONKMFSEJ.js → app-settings-3TLA2EJ7.js} +16 -1
  4. package/dist/{app-settings-GJVZGU3M.js → app-settings-P42Z3VOB.js} +16 -1
  5. package/dist/caffeinate-hold-BEJIYPJ7.js +107 -0
  6. package/dist/caffeinate-hold-KLC6SABD.js +14 -0
  7. package/dist/{chunk-WAFIF22N.js → chunk-3CY6WJ7O.js} +2 -2
  8. package/dist/{chunk-7ZOQY4A7.js → chunk-57ROTAFD.js} +62 -3
  9. package/dist/{chunk-57WWNMFP.js → chunk-7NCIHRAU.js} +22 -4
  10. package/dist/{chunk-FGDJOJ2L.js → chunk-AE5VBOFE.js} +1 -1
  11. package/dist/{chunk-DB3I75FI.js → chunk-BTL7EMGT.js} +4 -4
  12. package/dist/{chunk-4UIYN56C.js → chunk-D4DPQ552.js} +1 -1
  13. package/dist/{chunk-JWZNK3CQ.js → chunk-DGPUAZA4.js} +62 -3
  14. package/dist/{chunk-ZRFAZVGL.js → chunk-H2IXNFQ2.js} +22 -4
  15. package/dist/chunk-JAWEDVVA.js +106 -0
  16. package/dist/chunk-JT7R45JB.js +20 -0
  17. package/dist/{chunk-4BUCGNZS.js → chunk-MF2YMEGD.js} +83 -29
  18. package/dist/{chunk-K7LM4CLD.js → chunk-NG7S3OPX.js} +12 -6
  19. package/dist/chunk-NSTQ6QKD.js +23 -0
  20. package/dist/{chunk-LW5CMQGZ.js → chunk-OE7YBB5X.js} +83 -29
  21. package/dist/{chunk-BPOTVI5J.js → chunk-PTJJIQK7.js} +472 -18
  22. package/dist/{chunk-B4PRRKMA.js → chunk-S25IHL5H.js} +12 -6
  23. package/dist/{chunk-5HTTCYWA.js → chunk-UH57WVFP.js} +2 -2
  24. package/dist/{chunk-M5V4QIWF.js → chunk-VROPG6QF.js} +1 -1
  25. package/dist/{chunk-MHR4OGZ4.js → chunk-W7YOTDVO.js} +493 -18
  26. package/dist/{connected-teams-RUNMOCG5.js → connected-teams-35EIRJCP.js} +2 -2
  27. package/dist/{connected-teams-OMDHTL6A.js → connected-teams-ZRS53OAT.js} +2 -2
  28. package/dist/{coordinator-prompt-6HMTOX4G.js → coordinator-prompt-2J4PIMUF.js} +7 -4
  29. package/dist/{coordinator-prompt-3BSMKZL4.js → coordinator-prompt-QYYG2IBB.js} +7 -4
  30. package/dist/{global-workspace-YZ2NJVLL.js → global-workspace-KHIFQUUM.js} +12 -5
  31. package/dist/{global-workspace-QS7A23CB.js → global-workspace-SVRYNJZA.js} +12 -5
  32. package/dist/index.cjs +4805 -1262
  33. package/dist/index.d.cts +570 -22
  34. package/dist/index.d.ts +570 -22
  35. package/dist/index.js +3084 -340
  36. package/dist/mcp/run-stdio.cjs +2339 -617
  37. package/dist/mcp/run-stdio.js +1289 -290
  38. package/dist/{run-Y2MI3EVV.js → run-A4RHY7HH.js} +1 -1
  39. package/dist/{run-JLD2Y52J.js → run-V2WZUMJA.js} +1 -1
  40. package/dist/{workspaces-EBFW7I7S.js → workspaces-AHFTHVBT.js} +7 -6
  41. package/dist/{workspaces-AIUYUXB7.js → workspaces-SVQIEVIZ.js} +7 -6
  42. package/dist/{worktree-WMDJW2BL.js → worktree-KWXHMKRN.js} +2 -2
  43. package/dist/{worktree-7NBPIVFZ.js → worktree-VOCH3WS3.js} +2 -2
  44. package/package.json +3 -1
package/dist/index.d.cts CHANGED
@@ -284,6 +284,8 @@ interface PrMeta {
284
284
  reviewDecision: string | null;
285
285
  baseRefName: string;
286
286
  headRefName: string;
287
+ /** True when the PR is sitting in a GitHub merge queue. */
288
+ isInMergeQueue: boolean;
287
289
  }
288
290
  /** One layer in a GitHub PR stack (bottom = position 1). */
289
291
  interface PrStackLayer {
@@ -367,6 +369,8 @@ interface DiffResult {
367
369
  hasLastTurnBase: boolean;
368
370
  /** Recent commits on the branch (vs merge-base), for the Commits flyout. */
369
371
  commits: DiffCommit[];
372
+ /** Resolved merge-base SHA when comparing the branch to the default. */
373
+ mergeBase?: string | null;
370
374
  }
371
375
  interface LandPreview {
372
376
  branch: string;
@@ -600,7 +604,7 @@ interface CliExecutableSettings {
600
604
  }
601
605
  /** Local agent that runs the Brightsy cloud coordinator. */
602
606
  type BrightsyCloudConnectAgent = 'claude' | 'codex' | 'opencode' | 'cursor';
603
- /** Brightsy cloud remote-orchestrator preferences (Slack / Discord / Teams). */
607
+ /** Brightsy cloud remote-orchestrator preferences. */
604
608
  interface BrightsyHarnessSettings {
605
609
  /** Absolute path to the Brightsy CLI. Empty/omitted = `brightsy` on PATH. */
606
610
  executablePath?: string;
@@ -619,16 +623,48 @@ interface BrightsyHarnessSettings {
619
623
  type IssueSource = 'linear' | 'github';
620
624
  /**
621
625
  * Sideboard-owned third-party connections (Account / Integrations).
622
- * GitHub uses machine `gh` auth; Linear uses a stored API key.
626
+ * GitHub uses machine `gh` auth; Linear uses OAuth (or a stored API key).
623
627
  */
624
628
  interface IntegrationsSettings {
625
- /** Linear personal API key (https://linear.app/settings/api). */
629
+ /** Linear personal API key (https://linear.app/settings/api). Fallback when OAuth is unused. */
626
630
  linearApiKey?: string;
631
+ /** Linear OAuth access token (Account → Linear → Connect via browser). */
632
+ linearAccessToken?: string;
633
+ /** Linear OAuth refresh token (rotated on each refresh). */
634
+ linearRefreshToken?: string;
635
+ /** Epoch ms when {@link IntegrationsSettings.linearAccessToken} expires. */
636
+ linearTokenExpiresAt?: number;
637
+ /** Linear OAuth app Client ID override (else baked / env). */
638
+ linearClientId?: string;
639
+ /** Linear OAuth app Client Secret override (optional with PKCE). */
640
+ linearClientSecret?: string;
641
+ /** Display name of the connected Linear user (non-secret). */
642
+ linearViewerName?: string;
643
+ /** Display name of the connected Linear workspace (non-secret). */
644
+ linearOrganizationName?: string;
627
645
  /**
628
646
  * Preferred issue source for Create-from / Link issue (default: GitHub).
629
- * When `linear` but no API key, runtime falls back to GitHub Issues.
647
+ * When `linear` but not connected, runtime falls back to GitHub Issues.
630
648
  */
631
649
  issueSource?: IssueSource;
650
+ /** Slack app Client ID for browser OAuth (Account → Slack). */
651
+ slackClientId?: string;
652
+ /** Slack app Client Secret for browser OAuth. */
653
+ slackClientSecret?: string;
654
+ /**
655
+ * Slack app-level token (`xapp-…`, `connections:write`) for Socket Mode listen.
656
+ * App-wide — not per workspace.
657
+ */
658
+ slackAppToken?: string;
659
+ /** When true, desktop/CLI listen for Slack DMs and @mentions via Socket Mode. */
660
+ slackListenEnabled?: boolean;
661
+ /**
662
+ * Stable per-Mac id for the Slack relay (Personal vs Work can both stay online).
663
+ * Generated once; do not copy between machines.
664
+ */
665
+ slackDeviceId?: string;
666
+ /** Human label for this Mac destination, e.g. Personal / Work. */
667
+ slackDeviceLabel?: string;
632
668
  }
633
669
  /**
634
670
  * Conductor-inspired power-user preferences (Settings → Advanced).
@@ -652,8 +688,12 @@ interface AdvancedAppSettings {
652
688
  */
653
689
  caffeinateWhileRunning?: boolean;
654
690
  /**
655
- * Keep the Mac awake with `caffeinate` while Brightsy cloud connect is listening
656
- * (so Slack/Discord/Teams tasks can be polled). Default off.
691
+ * Keep the Mac awake with `caffeinate` while Slack Listen is connected
692
+ * (so Personal/Work stay reachable with the lid closed on AC). Default off.
693
+ */
694
+ caffeinateWhileSlackListen?: boolean;
695
+ /**
696
+ * @deprecated Prefer `caffeinateWhileSlackListen`. Still read on load for migration.
657
697
  */
658
698
  caffeinateWhileCloudConnect?: boolean;
659
699
  /**
@@ -697,7 +737,7 @@ interface AppSettings {
697
737
  codex: CliExecutableSettings;
698
738
  /** OpenCode CLI executable override. */
699
739
  opencode: CliExecutableSettings;
700
- /** Brightsy cloud connect preferences (Slack / Discord / Teams). */
740
+ /** Brightsy cloud connect preferences. */
701
741
  brightsy: BrightsyHarnessSettings;
702
742
  /** GitHub / Linear connections and issue-source preference. */
703
743
  integrations: IntegrationsSettings;
@@ -706,6 +746,19 @@ interface AppSettings {
706
746
  /** Power-user / Conductor-style advanced preferences. */
707
747
  advanced: AdvancedAppSettings;
708
748
  }
749
+ /** Integrations fields safe to send to the renderer (no token values). */
750
+ type PublicIntegrationsSettings = Omit<IntegrationsSettings, 'linearApiKey' | 'linearAccessToken' | 'linearRefreshToken' | 'linearClientSecret' | 'slackClientSecret' | 'slackAppToken'> & {
751
+ /** True when Linear is connected (OAuth or API key). */
752
+ hasLinearApiKey: boolean;
753
+ hasLinearOAuth: boolean;
754
+ hasSlackClientSecret: boolean;
755
+ hasSlackAppToken: boolean;
756
+ };
757
+ /** Settings payload for the desktop UI. Secret values are omitted. */
758
+ type PublicAppSettings = Omit<AppSettings, 'integrations'> & {
759
+ integrations: PublicIntegrationsSettings;
760
+ };
761
+ declare function toPublicAppSettings(settings: AppSettings): PublicAppSettings;
709
762
  declare function appSettingsPath(): string;
710
763
  /** User-level Claude Code settings file (`~/.claude/settings.json`). */
711
764
  declare function claudeUserSettingsPath(): string;
@@ -730,7 +783,15 @@ declare function updateOpencodeSettings(patch: {
730
783
  }): AppSettings;
731
784
  declare function updateIntegrationsSettings(patch: {
732
785
  linearApiKey?: string | null;
786
+ linearClientId?: string | null;
787
+ linearClientSecret?: string | null;
733
788
  issueSource?: IssueSource | null;
789
+ slackClientId?: string | null;
790
+ slackClientSecret?: string | null;
791
+ slackAppToken?: string | null;
792
+ slackListenEnabled?: boolean | null;
793
+ slackDeviceId?: string | null;
794
+ slackDeviceLabel?: string | null;
734
795
  }): AppSettings;
735
796
  declare function updateDefaultsSettings(patch: {
736
797
  agent?: AgentKind | null;
@@ -770,8 +831,18 @@ declare function resolveNewThreadOptions(overrides?: {
770
831
  effort: ThinkingEffort;
771
832
  fast: boolean;
772
833
  };
773
- /** True when Sideboard has a Linear API key stored. */
834
+ /** True when Sideboard has Linear OAuth tokens or an API key stored. */
774
835
  declare function isLinearConnected(settings?: AppSettings): boolean;
836
+ /** Persist Linear OAuth tokens after authorize or refresh. */
837
+ declare function saveLinearOAuth(input: {
838
+ accessToken: string;
839
+ refreshToken?: string;
840
+ expiresIn?: number;
841
+ viewerName?: string;
842
+ organizationName?: string;
843
+ }): AppSettings;
844
+ /** Clear Linear OAuth tokens and API key. Does not revoke remotely. */
845
+ declare function disconnectLinearConnection(): AppSettings;
775
846
  /** Preferred issue source (default GitHub). */
776
847
  declare function getIssueSource(settings?: AppSettings): IssueSource;
777
848
  /**
@@ -781,6 +852,21 @@ declare function getIssueSource(settings?: AppSettings): IssueSource;
781
852
  declare function resolveEffectiveIssueSource(settings?: AppSettings): IssueSource;
782
853
  declare function getLinearApiKey(settings?: AppSettings): string | null;
783
854
  declare function brightsyCloudConnectEnabled(settings?: AppSettings): boolean;
855
+ /** Slack Socket Mode inbound (Account → Slack). Default off. */
856
+ declare function slackListenEnabled(settings?: AppSettings): boolean;
857
+ /**
858
+ * Stable per-Mac identity for the Slack relay so Personal and Work can both
859
+ * stay online as separate destinations.
860
+ */
861
+ declare function ensureSlackDeviceIdentity(settings?: AppSettings): {
862
+ deviceId: string;
863
+ deviceLabel: string;
864
+ };
865
+ /**
866
+ * App-level token for Slack Socket Mode (`xapp-…`).
867
+ * Env `SIDEBOARD_SLACK_APP_TOKEN` wins over settings.
868
+ */
869
+ declare function slackAppLevelToken(settings?: AppSettings): string;
784
870
  /** Default off — worktree agents only get Brightsy MCP on ask / prior use. */
785
871
  declare function brightsyInjectWorktreeMcpEnabled(settings?: AppSettings): boolean;
786
872
  /**
@@ -795,6 +881,8 @@ declare function updateAdvancedSettings(patch: Partial<AdvancedAppSettings>): Ap
795
881
  declare function autoRenameBranchEnabled(settings?: AppSettings): boolean;
796
882
  declare function autoRunAfterSetupEnabled(settings?: AppSettings): boolean;
797
883
  declare function caffeinateWhileRunningEnabled(settings?: AppSettings): boolean;
884
+ declare function caffeinateWhileSlackListenEnabled(settings?: AppSettings): boolean;
885
+ /** @deprecated Use caffeinateWhileSlackListenEnabled. */
798
886
  declare function caffeinateWhileCloudConnectEnabled(settings?: AppSettings): boolean;
799
887
  declare function deleteBranchOnPurgeEnabled(settings?: AppSettings): boolean;
800
888
  /** Conductor-style opt-in — default off. */
@@ -823,6 +911,33 @@ declare function applyAppEnvironment(target?: NodeJS.ProcessEnv, settings?: AppS
823
911
  declare function childEnvWithAppSettings(extra?: Record<string, string | undefined>): NodeJS.ProcessEnv;
824
912
  declare function harnessEnvKey(harness: HarnessId): string | null;
825
913
 
914
+ interface CaffeinateHoldState {
915
+ held: boolean;
916
+ pid: number | null;
917
+ running: boolean;
918
+ platform: NodeJS.Platform;
919
+ }
920
+ declare function caffeinateHoldPath(): string;
921
+ declare function getCaffeinateHold(): CaffeinateHoldState;
922
+ /**
923
+ * Session hold so the Mac stays awake across orchestration turns (MCP
924
+ * processes exit). Detached `caffeinate` on macOS; no-op elsewhere.
925
+ */
926
+ declare function setCaffeinateHold(enabled: boolean): CaffeinateHoldState;
927
+
928
+ /** Desktop registers a 32-byte key from Electron safeStorage. */
929
+ declare function setVaultMasterKey(key: Buffer | null): void;
930
+ declare function persistVaultKeyInKeychain(key: Buffer): void;
931
+ /** Existing Keychain vault key, if any. Does not create a new item. */
932
+ declare function readKeychainVaultKey(): Buffer | null;
933
+ /**
934
+ * AES-256-GCM key for secret files.
935
+ * `SIDEBOARD_SECRET_VAULT=plain` (tests) skips encryption.
936
+ */
937
+ declare function resolveVaultKey(): Buffer | null;
938
+ /** True if `path` is missing, plaintext, or decrypts with `key`. */
939
+ declare function secureFileUnlocksWith(path: string, key: Buffer): boolean;
940
+
826
941
  /**
827
942
  * Resolve thinking effort for persisted threads.
828
943
  * Legacy threads only had `fast` (which also drove Claude `--effort low`);
@@ -899,6 +1014,15 @@ declare function createGlobalChat(opts: CreateGlobalChatOpts): Thread;
899
1014
  */
900
1015
  declare function healOrchestrationSoccerTitles(): number;
901
1016
  declare function listGlobalThreads(includeArchived?: boolean): Thread[];
1017
+ /** Stable sourceRef for a Slack inbound orchestration chat (one per Slack user). */
1018
+ declare function slackCoordinatorSourceRef(teamId: string, userId: string): string;
1019
+ declare function isSlackCoordinatorThread(thread: Pick<Thread, 'sourceType' | 'sourceRef' | 'repoPath'>): boolean;
1020
+ /**
1021
+ * Find or create a Global orchestration chat for one Slack user (team + user).
1022
+ * Inbound DMs/@mentions from that person continue this thread — not the Brightsy
1023
+ * cloud singleton and not other Slack users' chats.
1024
+ */
1025
+ declare function ensureSlackCoordinator(teamId: string, userId: string, agent: AgentKind): Thread;
902
1026
  /** Find or create the singleton Brightsy cloud coordinator under Global. */
903
1027
  declare function ensureCloudCoordinator(agent: AgentKind): Thread;
904
1028
 
@@ -1046,7 +1170,9 @@ declare function ensureGhPreferOrigin(cwd: string): Promise<void>;
1046
1170
  * Makerkit-style `upstream`. `GH_REPO` is the CLI's documented override.
1047
1171
  */
1048
1172
  declare function originGhRepoEnv(cwd: string): Promise<Record<string, string>>;
1049
- declare function resolveDefaultBranch(repoPath: string): Promise<string>;
1173
+ declare function resolveDefaultBranch(repoPath: string, opts?: {
1174
+ network?: boolean;
1175
+ }): Promise<string>;
1050
1176
  /**
1051
1177
  * Prefer `origin/<branch>` for diff/merge-base so Changes / Land don't inflate
1052
1178
  * against a stale local default-branch tip (common after adopting a PR).
@@ -1216,7 +1342,7 @@ declare function refreshGitHubAuth(): Promise<GitHubStatus>;
1216
1342
 
1217
1343
  /**
1218
1344
  * List open issues assigned to the authenticated Linear user via GraphQL.
1219
- * Uses Sideboard-stored API key (Account → Linear), not agent MCP.
1345
+ * Uses Sideboard-stored OAuth token or API key (Account → Linear), not agent MCP.
1220
1346
  */
1221
1347
  declare function listLinearIssuesDirect(opts?: {
1222
1348
  limit?: number;
@@ -1225,6 +1351,39 @@ declare function listLinearIssuesDirect(opts?: {
1225
1351
  /** Probe Linear with the stored key (or provided key). */
1226
1352
  declare function validateLinearApiKey(apiKey: string): Promise<boolean>;
1227
1353
 
1354
+ declare function hasBakedLinearOAuth(): boolean;
1355
+
1356
+ /** Fixed port so the Linear OAuth redirect URI can be registered once. */
1357
+ declare const LINEAR_OAUTH_PORT = 19848;
1358
+ declare const LINEAR_OAUTH_REDIRECT = "http://127.0.0.1:19848/callback";
1359
+ /** Read-only — Sideboard lists assigned issues; it does not create them. */
1360
+ declare const LINEAR_OAUTH_SCOPES = "read";
1361
+ declare function linearOAuthCredentials(): {
1362
+ clientId: string;
1363
+ clientSecret: string;
1364
+ };
1365
+ declare function createLinearPkce(): {
1366
+ verifier: string;
1367
+ challenge: string;
1368
+ };
1369
+ declare function linearOAuthAuthorizeUrl(clientId: string, state: string, codeChallenge: string): string;
1370
+ /** Authorization header for Linear GraphQL: personal keys as-is, OAuth as Bearer. */
1371
+ declare function linearAuthorizationHeader(token: string): string;
1372
+ /**
1373
+ * Token for Linear GraphQL: valid OAuth access token (refreshing if needed),
1374
+ * else a stored personal API key.
1375
+ */
1376
+ declare function getLinearAuthToken(settings?: AppSettings): Promise<string | null>;
1377
+ /**
1378
+ * Open Linear OAuth in the browser, listen on a localhost callback, store tokens.
1379
+ */
1380
+ declare function startLinearOAuth(opts?: {
1381
+ openUrl?: (url: string) => void | Promise<void>;
1382
+ timeoutMs?: number;
1383
+ }): Promise<AppSettings>;
1384
+ /** Revoke OAuth tokens (best-effort) and clear Linear credentials including API key. */
1385
+ declare function disconnectLinear(): Promise<AppSettings>;
1386
+
1228
1387
  interface ListIssuesResult {
1229
1388
  source: IssueSource;
1230
1389
  /** Preference before fallback (useful for “Set up Linear” UI). */
@@ -1871,6 +2030,18 @@ interface GetDiffOptions {
1871
2030
  lastTurnBase?: string | null;
1872
2031
  /** When scope is `commits`, show only this commit's patch. */
1873
2032
  commitSha?: string | null;
2033
+ /**
2034
+ * When false, skip unified patches (file list + line counts only).
2035
+ * Default true. The Changes file list should pass false and load one
2036
+ * file's patch with `path` when the editor opens.
2037
+ */
2038
+ includePatches?: boolean;
2039
+ /** Scope stats, commits, dirty, unpushed. Default true. */
2040
+ includeMeta?: boolean;
2041
+ /** Untracked files. Default follows the scope (usually on). */
2042
+ includeUntracked?: boolean;
2043
+ /** Only this worktree-relative path. */
2044
+ path?: string;
1874
2045
  }
1875
2046
  /** Recent commits since merge-base (Cursor Commits submenu). */
1876
2047
  declare function listBranchCommits(worktreePath: string, repoPath: string, opts?: {
@@ -2432,6 +2603,11 @@ declare class Orchestrator {
2432
2603
  diff(threadRef: string, opts?: {
2433
2604
  scope?: DiffScope;
2434
2605
  commitSha?: string | null;
2606
+ base?: string;
2607
+ includePatches?: boolean;
2608
+ includeMeta?: boolean;
2609
+ includeUntracked?: boolean;
2610
+ path?: string;
2435
2611
  }): Promise<DiffResult>;
2436
2612
  diffSummary(threadRef: string): Promise<{
2437
2613
  base: string;
@@ -2759,6 +2935,11 @@ declare function formatWorkspaceInventory(workspaces: WorkspaceInventoryEntry[])
2759
2935
  /** Resolve GitHub slugs for registered workspaces (best-effort). */
2760
2936
  declare function enrichWorkspacesWithGithub(workspaces: Workspace[]): Promise<WorkspaceInventoryEntry[]>;
2761
2937
  declare const COORDINATOR_TOOL_PLAYBOOK: string;
2938
+ /**
2939
+ * Formatting rules when the coordinator reply is posted into Slack (DM / @mention).
2940
+ * Slack uses mrkdwn, not CommonMark — `**bold**` shows literal asterisks.
2941
+ */
2942
+ declare const SLACK_REPLY_FORMATTING: string;
2762
2943
  /**
2763
2944
  * Short identity block prepended to every orchestration turn prompt.
2764
2945
  * Survives Claude `--resume` (which drops cachedPrefix).
@@ -2780,8 +2961,8 @@ declare function coordinatorSystemPrompt(opts: {
2780
2961
  goal: string;
2781
2962
  parentId: string;
2782
2963
  workspaces: WorkspaceInventoryEntry[];
2783
- /** cloud = Brightsy reply framing; desktop = local Orchestration chat */
2784
- audience?: 'cloud' | 'desktop';
2964
+ /** cloud = Brightsy reply framing; slack = Sideboard Slack app; desktop = local Orchestration chat */
2965
+ audience?: 'cloud' | 'slack' | 'desktop';
2785
2966
  }): string;
2786
2967
 
2787
2968
  /**
@@ -2854,6 +3035,82 @@ declare function getBrightsySession(): Promise<BrightsySession>;
2854
3035
  */
2855
3036
  declare function switchBrightsyAccount(accountIdOrSlug: string): Promise<BrightsySession>;
2856
3037
 
3038
+ interface SlackOutboundWatch {
3039
+ id: string;
3040
+ teamId: string;
3041
+ channelId: string;
3042
+ /** Posted message ts. */
3043
+ ts: string;
3044
+ /** Parent thread ts (same as `ts` for top-level posts). */
3045
+ threadTs: string;
3046
+ kind: 'dm' | 'channel';
3047
+ toUserId?: string;
3048
+ toLabel: string;
3049
+ ownerUserId?: string;
3050
+ postedAt: string;
3051
+ lastSeenTs: string;
3052
+ unread: boolean;
3053
+ replyUserId?: string;
3054
+ replyUserName?: string;
3055
+ replyTs?: string;
3056
+ replyPreview?: string;
3057
+ permalink?: string;
3058
+ }
3059
+ interface SlackReplyBadge {
3060
+ id: string;
3061
+ userId: string;
3062
+ userName: string;
3063
+ initials: string;
3064
+ hue: number;
3065
+ permalink: string;
3066
+ label: string;
3067
+ preview?: string;
3068
+ repliedAt: string;
3069
+ }
3070
+ declare function slackArchiveUrl(channelId: string, ts: string): string;
3071
+ declare function recordSlackOutboundWatch(input: {
3072
+ teamId: string;
3073
+ channelId: string;
3074
+ ts: string;
3075
+ threadTs?: string;
3076
+ kind: 'dm' | 'channel';
3077
+ toUserId?: string;
3078
+ toLabel: string;
3079
+ ownerUserId?: string;
3080
+ }): SlackOutboundWatch | null;
3081
+ declare function listSlackReplyBadges(): SlackReplyBadge[];
3082
+ declare function dismissSlackReplyBadge(badgeKey: string): SlackReplyBadge[];
3083
+ declare function permalinkForSlackReplyBadge(badgeKey: string): string | null;
3084
+ declare function refreshSlackReplyBadges(opts?: {
3085
+ fetchImpl?: typeof fetch;
3086
+ force?: boolean;
3087
+ now?: number;
3088
+ }): Promise<SlackReplyBadge[]>;
3089
+
3090
+ interface SlackWorkspace {
3091
+ team_id: string;
3092
+ team_name: string;
3093
+ user_id?: string;
3094
+ bot_token?: string;
3095
+ user_token?: string;
3096
+ scopes?: string;
3097
+ connected_at: string;
3098
+ }
3099
+ /** Safe to send to the renderer / MCP (no tokens). */
3100
+ interface SlackWorkspaceInfo {
3101
+ team_id: string;
3102
+ team_name: string;
3103
+ user_id?: string;
3104
+ has_bot_token: boolean;
3105
+ has_user_token: boolean;
3106
+ connected_at: string;
3107
+ }
3108
+ declare function listSlackWorkspaces(): SlackWorkspaceInfo[];
3109
+ declare function getSlackWorkspace(teamId: string): SlackWorkspace | null;
3110
+ declare function disconnectSlackWorkspace(teamId: string): SlackWorkspaceInfo[];
3111
+ /** Add or update a workspace from a pasted bot (`xoxb-`) or user (`xoxp-`) token. */
3112
+ declare function connectSlackToken(rawToken: string): Promise<SlackWorkspaceInfo>;
3113
+
2857
3114
  /** Live status of the Brightsy cloud connect daemon in the desktop app. */
2858
3115
  interface CloudConnectStatus {
2859
3116
  enabled: boolean;
@@ -2864,6 +3121,21 @@ interface CloudConnectStatus {
2864
3121
  lastError: string | null;
2865
3122
  lastLog: string | null;
2866
3123
  }
3124
+ /** Live status of Sideboard Slack Listen (hosted relay). */
3125
+ interface SlackListenStatus {
3126
+ enabled: boolean;
3127
+ running: boolean;
3128
+ hasAppToken: boolean;
3129
+ /** Built-in Sideboard Slack app Client ID/Secret are present (not sent to renderer). */
3130
+ bakedOAuth: boolean;
3131
+ /** How inbound events arrive when listening. */
3132
+ mode: 'relay' | null;
3133
+ workspaceCount: number;
3134
+ /** This Mac’s Slack destination label (Personal / Work). */
3135
+ deviceLabel: string | null;
3136
+ lastError: string | null;
3137
+ lastLog: string | null;
3138
+ }
2867
3139
  /** Shared typed surface for Electron preload ↔ renderer (and docs). */
2868
3140
  interface IpcApi {
2869
3141
  detectAgents(): Promise<AgentStatus[]>;
@@ -2873,14 +3145,14 @@ interface IpcApi {
2873
3145
  installAgent(agent: AgentKind): Promise<AgentSetupActionResult>;
2874
3146
  /** Open the agent’s login/auth command in the system terminal. */
2875
3147
  loginAgent(agent: AgentKind): Promise<AgentSetupActionResult>;
2876
- getAppSettings(): Promise<AppSettings>;
2877
- saveAppSettings(settings: AppSettings): Promise<AppSettings>;
2878
- updateAppEnvironment(patch: Record<string, string | null | undefined>): Promise<AppSettings>;
3148
+ getAppSettings(): Promise<PublicAppSettings>;
3149
+ saveAppSettings(settings: AppSettings): Promise<PublicAppSettings>;
3150
+ updateAppEnvironment(patch: Record<string, string | null | undefined>): Promise<PublicAppSettings>;
2879
3151
  updateClaudeSettings(patch: Partial<ClaudeHarnessSettings> & {
2880
3152
  executablePath?: string | null;
2881
- }): Promise<AppSettings>;
3153
+ }): Promise<PublicAppSettings>;
2882
3154
  /** Persist a custom executable path for Claude / Codex / OpenCode / Brightsy. */
2883
- updateAgentExecutable(agent: CliAgentKind, executablePath: string | null): Promise<AppSettings>;
3155
+ updateAgentExecutable(agent: CliAgentKind, executablePath: string | null): Promise<PublicAppSettings>;
2884
3156
  /** Native file picker for a Claude Code executable override. */
2885
3157
  pickClaudeExecutable(): Promise<string | null>;
2886
3158
  /** Native file picker for a CLI agent executable override. */
@@ -2926,20 +3198,46 @@ interface IpcApi {
2926
3198
  }): Promise<CloudConnectStatus>;
2927
3199
  updateBrightsySettings(patch: Partial<BrightsyHarnessSettings> & {
2928
3200
  cloudConnectAgent?: BrightsyCloudConnectAgent | null;
2929
- }): Promise<AppSettings>;
2930
- updateAdvancedSettings(patch: Partial<AdvancedAppSettings>): Promise<AppSettings>;
3201
+ }): Promise<PublicAppSettings>;
3202
+ updateAdvancedSettings(patch: Partial<AdvancedAppSettings>): Promise<PublicAppSettings>;
2931
3203
  updateIntegrationsSettings(patch: {
2932
3204
  linearApiKey?: string | null;
2933
3205
  issueSource?: IssueSource | null;
2934
- }): Promise<AppSettings>;
3206
+ slackClientId?: string | null;
3207
+ slackClientSecret?: string | null;
3208
+ slackAppToken?: string | null;
3209
+ slackListenEnabled?: boolean | null;
3210
+ slackDeviceId?: string | null;
3211
+ slackDeviceLabel?: string | null;
3212
+ }): Promise<PublicAppSettings>;
2935
3213
  updateDefaultsSettings(patch: {
2936
3214
  agent?: AgentKind | null;
2937
3215
  model?: string | null;
2938
3216
  effort?: ThinkingEffort | 'normal' | null;
2939
3217
  fast?: boolean | null;
2940
- }): Promise<AppSettings>;
3218
+ }): Promise<PublicAppSettings>;
2941
3219
  /** Machine-global GitHub status via `gh`. */
2942
3220
  getGitHubStatus(): Promise<GitHubStatus>;
3221
+ /** Connected Slack workspaces (no tokens). */
3222
+ getSlackWorkspaces(): Promise<SlackWorkspaceInfo[]>;
3223
+ /** Add a workspace from a pasted bot (xoxb-) or user (xoxp-) token. */
3224
+ connectSlackToken(token: string): Promise<SlackWorkspaceInfo[]>;
3225
+ /** Browser OAuth — opens Slack, waits for localhost callback. */
3226
+ startSlackOAuth(): Promise<SlackWorkspaceInfo[]>;
3227
+ disconnectSlackWorkspace(teamId: string): Promise<SlackWorkspaceInfo[]>;
3228
+ /** Browser OAuth — opens Linear, waits for localhost callback. */
3229
+ startLinearOAuth(): Promise<PublicAppSettings>;
3230
+ /** Revoke Linear OAuth (best-effort) and clear stored Linear credentials. */
3231
+ disconnectLinear(): Promise<PublicAppSettings>;
3232
+ /** Sideboard Slack listen (DMs + @mentions → Global orchestrator). */
3233
+ getSlackListenStatus(): Promise<SlackListenStatus>;
3234
+ setSlackListen(opts: {
3235
+ enabled: boolean;
3236
+ }): Promise<SlackListenStatus>;
3237
+ /** Unread Slack replies to messages this Mac posted (does not drive the Mac). */
3238
+ getSlackReplyBadges(): Promise<SlackReplyBadge[]>;
3239
+ /** Open the Slack thread in the browser/app and clear that user's badge. */
3240
+ openSlackReply(badgeId: string): Promise<SlackReplyBadge[]>;
2943
3241
  /**
2944
3242
  * Unified issues for Create-from / Link issue (Linear API or GitHub Issues,
2945
3243
  * based on Account preference with Linear→GitHub fallback).
@@ -3026,6 +3324,11 @@ interface IpcApi {
3026
3324
  getDiff(threadRef: string, opts?: {
3027
3325
  scope?: DiffScope;
3028
3326
  commitSha?: string | null;
3327
+ base?: string;
3328
+ includePatches?: boolean;
3329
+ includeMeta?: boolean;
3330
+ includeUntracked?: boolean;
3331
+ path?: string;
3029
3332
  }): Promise<DiffResult>;
3030
3333
  /** `git init` in the thread worktree when Changes has no Git repo (Cursor-style). */
3031
3334
  initializeGit(threadRef: string): Promise<void>;
@@ -3456,4 +3759,249 @@ declare function writeInjectedMcpConfig(opts: {
3456
3759
  includeBrightsy?: boolean;
3457
3760
  }): Promise<string | null>;
3458
3761
 
3459
- export { ATTACHMENTS_DIR, type ActiveRun, type AddStackLayerInput, type AdoptInput, type AdvancedAppSettings, type AgentAdapter, type AgentEvent, type AgentInstructionFile, type AgentKind, type AgentModelCatalog, type AgentModelInfo, type AgentSetupActionResult, type AgentSetupInfo, type AgentSetupKind, type AgentStatus, type AgentTurnInput, type AnthropicCacheControl, type AppSettings, type ApplyIntoMainResult, type AttachCommand, type Autonomy, BRIGHTSY_MCP_ALLOWED_TOOLS, type BranchInfo, type BrightsyAccount, type BrightsyChatTarget, type BrightsyChatTargets, type BrightsyCloudConnectAgent, type BrightsyHarnessSettings, type BrightsySession, BrightsySideboardApi, type BrightsyTeamTargets, CLAUDE_MODEL_CATALOG, CLOUD_COORDINATOR_BUSY_REPLY, CLOUD_COORDINATOR_STOPPED_REPLY, CLOUD_COORDINATOR_TIMEOUT_REPLY, CLOUD_ORCHESTRATOR_GOAL, CONTEXT_COMPACT_CHARS, CONTEXT_KEEP_RECENT_CHARS, CONTEXT_KEEP_RECENT_MESSAGES, CONTEXT_MIN_MESSAGES, COORDINATOR_TOOL_PLAYBOOK, type ClaudeHarnessSettings, type CleanupOrphansResult, type CliAgentKind, type CliExecutableSettings, type CloudConnectAgent, type CloudConnectOptions, type CloudConnectStatus, type CompactResult, type CompactThresholds, type ComposerFileBuffer, type ConductorSettings, type ConductorWorkspace, type ConnectedBrightsyTeamInfo, type CreateChatTabInput, type CreateGlobalChatOpts, type CreateStackInput, type CreateThreadInput, type CreateWorktreeResult, type CursorModelInfo, type CursorSdkStreamMessage, type CursorTurnRequest, type CursorWorktreesConfig, type DefaultsAppSettings, type DevServerHandle, type DiffCommentInput, type DiffCommentLine, type DiffCommit, type DiffFile, type DiffResult, type DiffScope, type DiffScopeStat, type ExpandResult, FAMOUS_SOCCER_TEAMS, type ForkChatTabInput, type ForkThreadWorktreeInput, type FormatGhLandErrorOptions, GLOBAL_WORKSPACE_ID, type GetDiffOptions, type GhStackStatus, type GitHubStatus, type GitWorktreeStatus, HARNESS_ENV_KEYS, type HarnessId, type InitStackFromThreadInput, type IntegrationsSettings, type IpcApi, type IssueInfo, type IssueSource, LEGACY_ATTACHMENTS_DIR, LEGACY_PLAN_FILE_REL, LEGACY_REVIEW_REQUEST_PATH, type LandPreview, type LandResult, type ListIssuesResult, MAX_ANTHROPIC_CACHE_CONTROL_BLOCKS, type McpServerStatus, type MessagePart, ORCHESTRATOR_AGENT_KINDS, type OpenPrStackLayersInput, type OpenStackLayerInput, type OpenStackLayerResult, type OrchestrationQuotaOnLimit, Orchestrator, type OrchestratorAgentKind, type OrchestratorEvent, type OrchestratorRuntime, type OrphanWorktree, PASTE_ATTACH_MIN_CHARS, PASTE_ATTACH_MIN_LINES, PLAN_FILE_NAME, PLAN_FILE_REL, PLAN_MODE_INSTRUCTION, type PendingPlanQuestions, type PlanQuestion, type PlanQuestionAnswer, type PlanQuestionOption, type PlanToolPartLike, type PrActor, type PrCheckRun, type PrCommentInfo, type PrCommitInfo, type PrDetails, type PrInfo, type PrMeta, type PrReviewInfo, type PrStack, type PrStackLayer, type PresentedPlan, REPO_REVIEW_NAME, REPO_REVIEW_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PATH, REVIEW_REQUEST_PREFILL, type RepoSettings, type RepoSetupInfo, type RequestReviewResult, type ResolvedReviewGuidelines, type ReviewGuidelinesSource, type RunMode, type RunScript, SIDEBOARD_FORCE_STOP, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_MCP_PROFILE_ENV, type ScriptHandle, type SideboardMcpProfile, type SkillInfo, type SourceType, type SpawnTurnHandle, type SummarizeResult, THINKING_EFFORTS, type TeamName, type ThinkingEffort, type Thread, type ThreadAttachment, type ThreadMessage, type ThreadOptionsPatch, type ThreadStatus, type TokenUsage, type ToolPartLike, type TranscriptToolDetail, type TurnCommand, type Workspace, type WorkspaceInventoryEntry, type WorkspaceScriptEnvOpts, addPrStackLayer, addStackLayerFromThread, addWorkspace, adoptThread, allAdapters, allocatePort, allocatePortRange, allocateTeamName, allocateTeamSlug, appDataDir, appSettingsPath, appendMessage, applyAgentEvent, applyAppEnvironment, applyCompaction, applyThreadIntoMain, assertOrchestratorCapableAgent, attachmentFromAbsolutePath, attachmentsFromBuffers, attachmentsFromWorktreePaths, attachmentsGitignoreBody, autoArchiveOnMergeEnabled, autoCleanupOrphansEnabled, autoRenameBranchEnabled, autoRunAfterSetupEnabled, branchDisplayLabel, brightsyAdapter, brightsyCloudConnectAgent, brightsyCloudConnectEnabled, brightsyConfigPath, brightsyInjectWorktreeMcpEnabled, brightsyMcpAllowedTools, brightsyMcpServerName, buildCachedUserContent, buildClaudeStreamJsonUserMessage, buildDiffCommentAttachment, buildForkTranscriptAttachment, buildPastedTextAttachment, buildReviewRequestAttachment, buildSessionSeed, buildWorkspaceScriptEnv, caffeinateWhileCloudConnectEnabled, caffeinateWhileRunningEnabled, captureLoginEnv, captureTurnBaseline, checkoutPrStackLayer, childEnvWithAppSettings, claudeAdapter, claudeChromeEnabled, claudeUserSettingsPath, cleanupOrphanWorktrees, cloneRepoIntoSideboard, codexAdapter, coerceOrchestratorAgent, collectTakenTeamSlugs, commitAll, conductorBundledBinDir, conductorDbPath, confirmLand, connectBrightsyTeam, coordinatorSystemPrompt, coordinatorTurnReminder, copyConfiguredFiles, countCacheControlBlocks, createChatTab, createEmptyThread, createExistingBranchWorktree, createGlobalChat, createOrUpdatePr, createPrStack, createThread, createThreadWorktree, currentBranch, cursorAdapter, cursorSdkMessageToEvents, decodeBrightsyTarget, deleteBranchOnPurgeEnabled, deleteThreadRecord, detectAgents, detectGhStack, detectLocalMergeConflicts, disconnectBrightsyTeam, discoverSkills, dropCachedPrefixOnResume, encodeBrightsyTarget, enrichPathWithNpmGlobalBin, enrichWorkspacesWithGithub, ensureAgentPath, ensureCloudCoordinator, ensureGhPreferOrigin, ensureGlobalCoordinatorCwd, ensureReviewRequestFile, ensureWorkspace, estimateMessageChars, estimateThreadChars, expandComposerPrompt, extractGhErrorDetail, extractPendingPlanQuestions, extractPresentedPlan, extractiveSummary, fetchPrHead, finalizeParts, findInvalidCacheControlTtlOrder, findOrphanWorktrees, findThreadByRef, findThreadForStackLayer, flattenTurnInput, forkChatTab, forkMessageSlice, forkThreadWorktree, formatAgentInstructions, formatArtifactDirective, formatBrightsyFetchError, formatGhLandError, formatIpcInvokeError, formatMessagesAsTranscript, formatPlanQuestionAnswers, formatPlanQuestionsForChat, formatRateLimitResetHint, formatRenameBranchDirective, formatTranscriptMarkdown, formatWorkspaceInventory, formatWorktreeDirective, formatWorktreeReminder, getAdapter, getAgentSetupInfo, getBrightsySession, getDefaultAgent, getDefaultEffort, getDefaultFast, getDefaultModel, getDefaultRunScript, getDiff, getDiffSummary, getGitHubStatus, getIssueSource, getLinearApiKey, getOrchestrator, getPr, getPrChecks, getPrDetails, getPrMeta, getPrStack, getRepoSetupInfo, getRunMode, getRunScript, gh, ghHeadRef, ghRepoSelectArgs, git, globalAgentCwd, harnessEnvKey, hasConductorHook, hasCursorWorktreeSetup, hasRepoHook, hasWorkspaceHook, healOrchestrationSoccerTitles, importConductorWorkspace, importConductorWorkspaceAsync, initPrStack, initStackFromThread, initializeGitRepository, inspectGitWorktree, installAgent, isAskUserToolName, isBrightsyConnected, isBrightsyNdjsonLine, isCloudCoordinatorThread, isConductorBundledCli, isCursorAutoModel, isDirty, isGhRateLimitError, isGlobalRepoPath, isGlobalThread, isImageFilePath, isInPrStack, isLinearConnected, isOrchestratorCapableAgent, isOrchestratorThread, isPidAlive, isPlaceholderBranch, isPresentPlanToolName, isSessionQuotaLimit, isSideboardScratchPath, isThinkingEffort, isWorkspaceScratchPath, listAgentSetupInfo, listBranchCommits, listBranches, listBrightsyAccounts, listBrightsyChatTargets, listCodexModels, listConductorWorkspaces, listConnectedBrightsyTeams, listCursorModels, listGitHubIssues, listGlobalThreads, listIssues, listLinearIssues, listLinearIssuesDirect, listModelsForAgent, listOpencodeModels, listPrs, listRunScripts, listThreads, listWorkspaces, listWorktreeFiles, listWorktrees, loadAgentInstructions, loadAppSettings, loadBrightsyConfig, loadConductorSettings, loadRepoSettings, loadWorkspaceSettings, locksDir, loginAgent, lookupSoccerTeam, maxConcurrentAgents, maybeCompactContext, mcpAllowTools, mcpAuthWarnings, mergePr, mergePrStack, mergeUsage, nextPastedTextName, nextThinkingEffort, normalizeParseResult, normalizeThinkingEffort, normalizeThread, normalizeTurnInput, normalizeWorktreePath, openInSystemTerminal, openPrStackLayers, openStackLayer, opencodeAdapter, orchestrationQuotaFallbackAgent, orchestrationQuotaOnLimit, orchestrationTitleNeedsSoccerNickname, orchestratorSessionPoisonedByBuiltins, originGhRepoEnv, parseCursorRunnerLine, parseForceStopMessage, parseGhStackViewJson, parseGithubSlugFromRemoteUrl, parseMcpList, parsePlanQuestionsInput, parseSessionQuotaResetAt, partsToAssistantText, pastedTextStats, permissionMode, planFileAbs, posixShellSingleQuote, prepareTerminalCommand, previewLand, promptMentionsBrightsy, pushBranch, readExistingReviewRequestFile, readPlanFile, readSkillBody, readThread, readWorktreeFile, readWorktreeFileForUpload, readWorktreeInclude, refreshGitHubAuth, removeWorkspace, removeWorktree, repoSlug, requestReview, requireAgent, resetGhStackDetectCache, resolveAgentExecutable, resolveClaudeExecutable, resolveCommandBinarySync, resolveConductorCursorAgentId, resolveCursorModelId, resolveDefaultBranch, resolveDiffBaseRef, resolveEffectiveIssueSource, resolveFilesToCopy, resolveGhAuthToken, resolveGithubRepoSlug, resolveLoginCommand, resolveNewThreadOptions, resolvePlanMarkdown, resolvePrSelector, resolveQuotaFallbackAgent, resolveRepoRoot, resolveReviewGuidelines, resolveThreadDefaults, resolveThreadEffort, resolveWorktreeStartPoint, run, runArchiveScript, runCloudConnect, runCursorWorktreeSetup, runSetupScript, sameWorktreePath, sanitizeMcpServerName, saveAppSettings, setStatus, settingsSourceLabel, shouldAttachPastedText, shouldCompactContext, shouldInjectBrightsyMcp, shouldRefreshReviewRequestTemplate, shouldRunWorktreeCleanup, sideboardHomeDir, sideboardMcpProfile, sideboardReposDir, sideboardWorkspacesDir, slugify, spawnAgentTurn, splitForCompaction, stackAgentDefaultsFrom, stackIdFrom, stackMergeReadiness, stageAbsolutePathsAsAttachments, stageBuffersAsAttachments, startDevServer, startMcpServer, startOrchestration, stripBrightsyNdjsonNoise, submitPrStack, suggestSlug, summarizeConversation, switchBrightsyAccount, syncWorkspacesFromThreads, takenTeamSlugsForChatTab, takenTeamSlugsForOrchestration, taskMessageText, thinkingEffortBars, thinkingEffortLabel, threadDisplayLabel, threadFilePath, threadLockPath, threadRequestsBrightsyMcp, threadsDir, threadsSharingWorktree, toolDescription, toolDetail, toolFilePath, totalTokens, updateAdvancedSettings, updateAgentExecutable, updateAppEnvironment, updateBrightsySettings, updateClaudeSettings, updateCodexSettings, updateDefaultsSettings, updateIntegrationsSettings, updateOpencodeSettings, updateThread, validateLinearApiKey, withAgentInstructions, withExportedPath, withThreadLock, workspaceSettingsSourceLabel, worktreeCleanupSettings, worktreeDisplayLabel, worktreeDisplayLabelForGroup, worktreeNameFromPath, worktreesRoot, writeInjectedMcpConfig, writePlanFile, writeThread, writeWorktreeFile };
3762
+ /** Public WebSocket URL for the hosted Slack inbound relay (path included). */
3763
+ declare const BAKED_SLACK_RELAY_URL = "wss://slack-relay.sideboard.cloud/desktop";
3764
+ declare function hasBakedSlackOAuth(): boolean;
3765
+ /**
3766
+ * Relay URL for inbound Slack when this Mac has no local xapp-.
3767
+ * Override with SIDEBOARD_SLACK_RELAY_URL for local relay testing.
3768
+ */
3769
+ declare function slackRelayUrl(): string;
3770
+
3771
+ /** Fixed port so the Slack app redirect URI can be registered once. */
3772
+ declare const SLACK_OAUTH_PORT = 19847;
3773
+ declare const SLACK_OAUTH_REDIRECT = "http://127.0.0.1:19847/callback";
3774
+ declare function slackOAuthCredentials(): {
3775
+ clientId: string;
3776
+ clientSecret: string;
3777
+ };
3778
+ /**
3779
+ * Open Slack OAuth in the browser, listen on a localhost callback, store tokens.
3780
+ */
3781
+ declare function startSlackOAuth(opts?: {
3782
+ openUrl?: (url: string) => void | Promise<void>;
3783
+ timeoutMs?: number;
3784
+ }): Promise<SlackWorkspaceInfo>;
3785
+
3786
+ /** Minimal WebSocket surface so tests can inject a fake without DOM lib types. */
3787
+ interface SlackWebSocket {
3788
+ send(data: string): void;
3789
+ close(code?: number, reason?: string): void;
3790
+ addEventListener(type: 'open' | 'message' | 'error' | 'close', listener: (ev: {
3791
+ data?: unknown;
3792
+ }) => void): void;
3793
+ }
3794
+ type SlackWebSocketCtor = new (url: string) => SlackWebSocket;
3795
+ interface SlackInboundMessage {
3796
+ teamId: string;
3797
+ channelId: string;
3798
+ ts: string;
3799
+ threadTs?: string;
3800
+ userId?: string;
3801
+ text: string;
3802
+ kind: 'dm' | 'mention';
3803
+ }
3804
+ interface SlackSocketModeOptions {
3805
+ appToken: string;
3806
+ signal?: AbortSignal;
3807
+ onLog?: (line: string) => void;
3808
+ onEvent: (msg: SlackInboundMessage) => void | Promise<void>;
3809
+ fetchImpl?: typeof fetch;
3810
+ WebSocketImpl?: SlackWebSocketCtor;
3811
+ }
3812
+
3813
+ declare const SLACK_LISTEN_BUSY_REPLY: string;
3814
+ declare const SLACK_LISTEN_STOPPED_REPLY = "Sideboard stopped the in-progress turn. Send another message when you want to continue.";
3815
+ declare const SLACK_LISTEN_TIMEOUT_REPLY: string;
3816
+ interface SlackListenOptions {
3817
+ agent?: AgentKind;
3818
+ signal?: AbortSignal;
3819
+ onLog?: (line: string) => void;
3820
+ /** Override hosted relay URL (tests / local relay). */
3821
+ relayUrl?: string;
3822
+ fetchImpl?: typeof fetch;
3823
+ WebSocketImpl?: SlackSocketModeOptions['WebSocketImpl'];
3824
+ /** Tests: handle without talking to Slack Web API. */
3825
+ postReply?: (msg: SlackInboundMessage, text: string) => Promise<void>;
3826
+ /** Tests: ack reactions without talking to Slack Web API. */
3827
+ addReaction?: (msg: SlackInboundMessage, name: string) => Promise<void>;
3828
+ }
3829
+ declare function formatSlackInboundPrompt(msg: SlackInboundMessage): string;
3830
+ /**
3831
+ * Prefix Slack replies with This Mac's destination (`Work: …`) so a user with
3832
+ * more than one device can see who answered and address follow-ups the same way.
3833
+ */
3834
+ declare function formatSlackSignedReply(deviceLabel: string, text: string): string;
3835
+ /** Slack emoji short name for “seen / got it”. */
3836
+ declare const SLACK_SEEN_REACTION = "+1";
3837
+ /** Thumbs-up the inbound message so Slack shows the bot saw it. */
3838
+ declare function ackSlackInboundSeen(msg: SlackInboundMessage, opts: Pick<SlackListenOptions, 'addReaction' | 'fetchImpl' | 'onLog'>): Promise<void>;
3839
+ declare function handleSlackInbound(msg: SlackInboundMessage, opts: SlackListenOptions): Promise<void>;
3840
+ /**
3841
+ * Only handle Slack events for Slack users who connected this Sideboard
3842
+ * (OAuth authed_user). Other people messaging the bot must run their own Mac.
3843
+ */
3844
+ declare function isInboundForThisDesktop(msg: SlackInboundMessage): boolean;
3845
+ /**
3846
+ * Sideboard-native Slack inbound via the hosted relay.
3847
+ * The Mac never holds an app-level `xapp-` token.
3848
+ */
3849
+ declare function runSlackListen(opts?: SlackListenOptions): Promise<void>;
3850
+ /** How Listen will receive Slack events on this machine. */
3851
+ declare function resolveSlackListenMode(opts?: {
3852
+ relayUrl?: string | null;
3853
+ workspaceCount?: number;
3854
+ }): 'relay' | null;
3855
+
3856
+ interface SlackAuthTest {
3857
+ ok: boolean;
3858
+ url?: string;
3859
+ team?: string;
3860
+ user?: string;
3861
+ team_id?: string;
3862
+ user_id?: string;
3863
+ bot_id?: string;
3864
+ }
3865
+
3866
+ /** Desktop → relay */
3867
+ type SlackRelayClientMessage = {
3868
+ type: 'register';
3869
+ teamId: string;
3870
+ /** Slack user who owns this Sideboard (from OAuth authed_user). */
3871
+ userId: string;
3872
+ /** Stable per-Mac id so Personal and Work can both stay connected. */
3873
+ deviceId: string;
3874
+ /** Human label, e.g. "Personal" / "Work". */
3875
+ deviceLabel?: string;
3876
+ botToken: string;
3877
+ /** User token proves identity (auth.test user_id must match). */
3878
+ userToken: string;
3879
+ } | {
3880
+ type: 'claim';
3881
+ eventId: string;
3882
+ } | {
3883
+ type: 'ping';
3884
+ };
3885
+ /** Relay → desktop */
3886
+ type SlackRelayServerMessage = {
3887
+ type: 'registered';
3888
+ teamId: string;
3889
+ userId: string;
3890
+ deviceId: string;
3891
+ } | {
3892
+ type: 'event';
3893
+ eventId: string;
3894
+ message: SlackInboundMessage;
3895
+ } | {
3896
+ type: 'claim_ok';
3897
+ eventId: string;
3898
+ } | {
3899
+ type: 'claim_denied';
3900
+ eventId: string;
3901
+ } | {
3902
+ type: 'error';
3903
+ message: string;
3904
+ } | {
3905
+ type: 'pong';
3906
+ };
3907
+ declare function parseSlackRelayClientMessage(raw: string): SlackRelayClientMessage | null;
3908
+ declare function parseSlackRelayServerMessage(raw: string): SlackRelayServerMessage | null;
3909
+
3910
+ interface SlackRelaySocket {
3911
+ send(data: string): void;
3912
+ close(code?: number, reason?: string): void;
3913
+ }
3914
+ interface SlackRelaySession {
3915
+ id: string;
3916
+ teamId: string;
3917
+ userId: string;
3918
+ deviceId: string;
3919
+ deviceLabel: string;
3920
+ socket: SlackRelaySocket;
3921
+ connectedAt: number;
3922
+ }
3923
+ interface SlackRelayHubOptions {
3924
+ fetchImpl?: typeof fetch;
3925
+ /** Inject auth.test for tests. */
3926
+ authTest?: (token: string) => Promise<Pick<SlackAuthTest, 'team_id' | 'user_id' | 'ok'>>;
3927
+ onLog?: (line: string) => void;
3928
+ }
3929
+ /**
3930
+ * In-memory registry of desktop sessions keyed by team + Slack user + device.
3931
+ * Personal and Work Macs can both stay online. Inbound events fan out to the
3932
+ * matching destination(s); the first device to claim handles the turn.
3933
+ */
3934
+ declare class SlackRelayHub {
3935
+ private readonly sessions;
3936
+ private readonly bySocket;
3937
+ private readonly pendingClaims;
3938
+ private seq;
3939
+ private readonly fetchImpl?;
3940
+ private readonly authTest;
3941
+ private readonly log;
3942
+ constructor(opts?: SlackRelayHubOptions);
3943
+ sessionFor(teamId: string, userId: string, deviceId: string): SlackRelaySession | null;
3944
+ sessionsForUser(teamId: string, userId: string): SlackRelaySession[];
3945
+ listSessions(): SlackRelaySession[];
3946
+ detachSocket(socket: SlackRelaySocket): void;
3947
+ handleClientMessage(socket: SlackRelaySocket, msg: SlackRelayClientMessage): Promise<void>;
3948
+ register(socket: SlackRelaySocket, teamId: string, userId: string, deviceId: string, deviceLabel: string | undefined, botToken: string, userToken: string): Promise<void>;
3949
+ /**
3950
+ * Fan-out an inbound event to matching device(s) for that Slack user.
3951
+ * Optional leading `Personal:` / `Work:` selects by device label.
3952
+ * Desktops must claim; first claim wins.
3953
+ */
3954
+ routeEvent(message: SlackInboundMessage): boolean;
3955
+ private handleClaim;
3956
+ private send;
3957
+ }
3958
+
3959
+ interface SlackRelayServerOptions {
3960
+ appToken: string;
3961
+ port?: number;
3962
+ host?: string;
3963
+ signal?: AbortSignal;
3964
+ onLog?: (line: string) => void;
3965
+ fetchImpl?: typeof fetch;
3966
+ /** Injected hub (tests). */
3967
+ hub?: SlackRelayHub;
3968
+ }
3969
+ interface SlackRelayServerHandle {
3970
+ port: number;
3971
+ url: string;
3972
+ hub: SlackRelayHub;
3973
+ close: () => Promise<void>;
3974
+ }
3975
+ /**
3976
+ * Hosted Slack inbound relay: one Socket Mode connection (xapp- on the server)
3977
+ * plus desktop WebSocket sessions that register via bot-token auth.test.
3978
+ */
3979
+ declare function startSlackRelayServer(opts: SlackRelayServerOptions): Promise<SlackRelayServerHandle>;
3980
+
3981
+ interface SlackRelayRegisterWorkspace {
3982
+ teamId: string;
3983
+ /** Slack user who owns this Sideboard (OAuth authed_user). */
3984
+ userId: string;
3985
+ botToken: string;
3986
+ userToken: string;
3987
+ }
3988
+ interface SlackRelayClientOptions {
3989
+ /** Full WebSocket URL including path, e.g. wss://slack-relay.sideboard.cloud/desktop */
3990
+ url: string;
3991
+ workspaces: SlackRelayRegisterWorkspace[];
3992
+ /** Stable per-Mac destination id. */
3993
+ deviceId: string;
3994
+ /** Human label shown in relay logs, e.g. Personal / Work. */
3995
+ deviceLabel?: string;
3996
+ signal?: AbortSignal;
3997
+ onEvent: (msg: SlackInboundMessage) => void | Promise<void>;
3998
+ onLog?: (line: string) => void;
3999
+ WebSocketImpl?: SlackWebSocketCtor;
4000
+ }
4001
+ /**
4002
+ * Desktop client: connect to the hosted Slack relay, register this Mac as a
4003
+ * destination for the OAuth Slack user, claim inbound events before handling.
4004
+ */
4005
+ declare function runSlackRelayClient(opts: SlackRelayClientOptions): Promise<void>;
4006
+
4007
+ export { ATTACHMENTS_DIR, type ActiveRun, type AddStackLayerInput, type AdoptInput, type AdvancedAppSettings, type AgentAdapter, type AgentEvent, type AgentInstructionFile, type AgentKind, type AgentModelCatalog, type AgentModelInfo, type AgentSetupActionResult, type AgentSetupInfo, type AgentSetupKind, type AgentStatus, type AgentTurnInput, type AnthropicCacheControl, type AppSettings, type ApplyIntoMainResult, type AttachCommand, type Autonomy, BAKED_SLACK_RELAY_URL, BRIGHTSY_MCP_ALLOWED_TOOLS, type BranchInfo, type BrightsyAccount, type BrightsyChatTarget, type BrightsyChatTargets, type BrightsyCloudConnectAgent, type BrightsyHarnessSettings, type BrightsySession, BrightsySideboardApi, type BrightsyTeamTargets, CLAUDE_MODEL_CATALOG, CLOUD_COORDINATOR_BUSY_REPLY, CLOUD_COORDINATOR_STOPPED_REPLY, CLOUD_COORDINATOR_TIMEOUT_REPLY, CLOUD_ORCHESTRATOR_GOAL, CONTEXT_COMPACT_CHARS, CONTEXT_KEEP_RECENT_CHARS, CONTEXT_KEEP_RECENT_MESSAGES, CONTEXT_MIN_MESSAGES, COORDINATOR_TOOL_PLAYBOOK, type CaffeinateHoldState, type ClaudeHarnessSettings, type CleanupOrphansResult, type CliAgentKind, type CliExecutableSettings, type CloudConnectAgent, type CloudConnectOptions, type CloudConnectStatus, type CompactResult, type CompactThresholds, type ComposerFileBuffer, type ConductorSettings, type ConductorWorkspace, type ConnectedBrightsyTeamInfo, type CreateChatTabInput, type CreateGlobalChatOpts, type CreateStackInput, type CreateThreadInput, type CreateWorktreeResult, type CursorModelInfo, type CursorSdkStreamMessage, type CursorTurnRequest, type CursorWorktreesConfig, type DefaultsAppSettings, type DevServerHandle, type DiffCommentInput, type DiffCommentLine, type DiffCommit, type DiffFile, type DiffResult, type DiffScope, type DiffScopeStat, type ExpandResult, FAMOUS_SOCCER_TEAMS, type ForkChatTabInput, type ForkThreadWorktreeInput, type FormatGhLandErrorOptions, GLOBAL_WORKSPACE_ID, type GetDiffOptions, type GhStackStatus, type GitHubStatus, type GitWorktreeStatus, HARNESS_ENV_KEYS, type HarnessId, type InitStackFromThreadInput, type IntegrationsSettings, type IpcApi, type IssueInfo, type IssueSource, LEGACY_ATTACHMENTS_DIR, LEGACY_PLAN_FILE_REL, LEGACY_REVIEW_REQUEST_PATH, LINEAR_OAUTH_PORT, LINEAR_OAUTH_REDIRECT, LINEAR_OAUTH_SCOPES, type LandPreview, type LandResult, type ListIssuesResult, MAX_ANTHROPIC_CACHE_CONTROL_BLOCKS, type McpServerStatus, type MessagePart, ORCHESTRATOR_AGENT_KINDS, type OpenPrStackLayersInput, type OpenStackLayerInput, type OpenStackLayerResult, type OrchestrationQuotaOnLimit, Orchestrator, type OrchestratorAgentKind, type OrchestratorEvent, type OrchestratorRuntime, type OrphanWorktree, PASTE_ATTACH_MIN_CHARS, PASTE_ATTACH_MIN_LINES, PLAN_FILE_NAME, PLAN_FILE_REL, PLAN_MODE_INSTRUCTION, type PendingPlanQuestions, type PlanQuestion, type PlanQuestionAnswer, type PlanQuestionOption, type PlanToolPartLike, type PrActor, type PrCheckRun, type PrCommentInfo, type PrCommitInfo, type PrDetails, type PrInfo, type PrMeta, type PrReviewInfo, type PrStack, type PrStackLayer, type PresentedPlan, type PublicAppSettings, type PublicIntegrationsSettings, REPO_REVIEW_NAME, REPO_REVIEW_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PATH, REVIEW_REQUEST_PREFILL, type RepoSettings, type RepoSetupInfo, type RequestReviewResult, type ResolvedReviewGuidelines, type ReviewGuidelinesSource, type RunMode, type RunScript, SIDEBOARD_FORCE_STOP, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_MCP_PROFILE_ENV, SLACK_LISTEN_BUSY_REPLY, SLACK_LISTEN_STOPPED_REPLY, SLACK_LISTEN_TIMEOUT_REPLY, SLACK_OAUTH_PORT, SLACK_OAUTH_REDIRECT, SLACK_REPLY_FORMATTING, SLACK_SEEN_REACTION, type ScriptHandle, type SideboardMcpProfile, type SkillInfo, type SlackInboundMessage, type SlackListenOptions, type SlackListenStatus, type SlackOutboundWatch, type SlackRelayClientMessage, type SlackRelayClientOptions, SlackRelayHub, type SlackRelayServerHandle, type SlackRelayServerMessage, type SlackRelayServerOptions, type SlackReplyBadge, type SlackWorkspaceInfo, type SourceType, type SpawnTurnHandle, type SummarizeResult, THINKING_EFFORTS, type TeamName, type ThinkingEffort, type Thread, type ThreadAttachment, type ThreadMessage, type ThreadOptionsPatch, type ThreadStatus, type TokenUsage, type ToolPartLike, type TranscriptToolDetail, type TurnCommand, type Workspace, type WorkspaceInventoryEntry, type WorkspaceScriptEnvOpts, ackSlackInboundSeen, addPrStackLayer, addStackLayerFromThread, addWorkspace, adoptThread, allAdapters, allocatePort, allocatePortRange, allocateTeamName, allocateTeamSlug, appDataDir, appSettingsPath, appendMessage, applyAgentEvent, applyAppEnvironment, applyCompaction, applyThreadIntoMain, assertOrchestratorCapableAgent, attachmentFromAbsolutePath, attachmentsFromBuffers, attachmentsFromWorktreePaths, attachmentsGitignoreBody, autoArchiveOnMergeEnabled, autoCleanupOrphansEnabled, autoRenameBranchEnabled, autoRunAfterSetupEnabled, branchDisplayLabel, brightsyAdapter, brightsyCloudConnectAgent, brightsyCloudConnectEnabled, brightsyConfigPath, brightsyInjectWorktreeMcpEnabled, brightsyMcpAllowedTools, brightsyMcpServerName, buildCachedUserContent, buildClaudeStreamJsonUserMessage, buildDiffCommentAttachment, buildForkTranscriptAttachment, buildPastedTextAttachment, buildReviewRequestAttachment, buildSessionSeed, buildWorkspaceScriptEnv, caffeinateHoldPath, caffeinateWhileCloudConnectEnabled, caffeinateWhileRunningEnabled, caffeinateWhileSlackListenEnabled, captureLoginEnv, captureTurnBaseline, checkoutPrStackLayer, childEnvWithAppSettings, claudeAdapter, claudeChromeEnabled, claudeUserSettingsPath, cleanupOrphanWorktrees, cloneRepoIntoSideboard, codexAdapter, coerceOrchestratorAgent, collectTakenTeamSlugs, commitAll, conductorBundledBinDir, conductorDbPath, confirmLand, connectBrightsyTeam, connectSlackToken, coordinatorSystemPrompt, coordinatorTurnReminder, copyConfiguredFiles, countCacheControlBlocks, createChatTab, createEmptyThread, createExistingBranchWorktree, createGlobalChat, createLinearPkce, createOrUpdatePr, createPrStack, createThread, createThreadWorktree, currentBranch, cursorAdapter, cursorSdkMessageToEvents, decodeBrightsyTarget, deleteBranchOnPurgeEnabled, deleteThreadRecord, detectAgents, detectGhStack, detectLocalMergeConflicts, disconnectBrightsyTeam, disconnectLinear, disconnectLinearConnection, disconnectSlackWorkspace, discoverSkills, dismissSlackReplyBadge, dropCachedPrefixOnResume, encodeBrightsyTarget, enrichPathWithNpmGlobalBin, enrichWorkspacesWithGithub, ensureAgentPath, ensureCloudCoordinator, ensureGhPreferOrigin, ensureGlobalCoordinatorCwd, ensureReviewRequestFile, ensureSlackCoordinator, ensureSlackDeviceIdentity, ensureWorkspace, estimateMessageChars, estimateThreadChars, expandComposerPrompt, extractGhErrorDetail, extractPendingPlanQuestions, extractPresentedPlan, extractiveSummary, fetchPrHead, finalizeParts, findInvalidCacheControlTtlOrder, findOrphanWorktrees, findThreadByRef, findThreadForStackLayer, flattenTurnInput, forkChatTab, forkMessageSlice, forkThreadWorktree, formatAgentInstructions, formatArtifactDirective, formatBrightsyFetchError, formatGhLandError, formatIpcInvokeError, formatMessagesAsTranscript, formatPlanQuestionAnswers, formatPlanQuestionsForChat, formatRateLimitResetHint, formatRenameBranchDirective, formatSlackInboundPrompt, formatSlackSignedReply, formatTranscriptMarkdown, formatWorkspaceInventory, formatWorktreeDirective, formatWorktreeReminder, getAdapter, getAgentSetupInfo, getBrightsySession, getCaffeinateHold, getDefaultAgent, getDefaultEffort, getDefaultFast, getDefaultModel, getDefaultRunScript, getDiff, getDiffSummary, getGitHubStatus, getIssueSource, getLinearApiKey, getLinearAuthToken, getOrchestrator, getPr, getPrChecks, getPrDetails, getPrMeta, getPrStack, getRepoSetupInfo, getRunMode, getRunScript, getSlackWorkspace, gh, ghHeadRef, ghRepoSelectArgs, git, globalAgentCwd, handleSlackInbound, harnessEnvKey, hasBakedLinearOAuth, hasBakedSlackOAuth, hasConductorHook, hasCursorWorktreeSetup, hasRepoHook, hasWorkspaceHook, healOrchestrationSoccerTitles, importConductorWorkspace, importConductorWorkspaceAsync, initPrStack, initStackFromThread, initializeGitRepository, inspectGitWorktree, installAgent, isAskUserToolName, isBrightsyConnected, isBrightsyNdjsonLine, isCloudCoordinatorThread, isConductorBundledCli, isCursorAutoModel, isDirty, isGhRateLimitError, isGlobalRepoPath, isGlobalThread, isImageFilePath, isInPrStack, isInboundForThisDesktop, isLinearConnected, isOrchestratorCapableAgent, isOrchestratorThread, isPidAlive, isPlaceholderBranch, isPresentPlanToolName, isSessionQuotaLimit, isSideboardScratchPath, isSlackCoordinatorThread, isThinkingEffort, isWorkspaceScratchPath, linearAuthorizationHeader, linearOAuthAuthorizeUrl, linearOAuthCredentials, listAgentSetupInfo, listBranchCommits, listBranches, listBrightsyAccounts, listBrightsyChatTargets, listCodexModels, listConductorWorkspaces, listConnectedBrightsyTeams, listCursorModels, listGitHubIssues, listGlobalThreads, listIssues, listLinearIssues, listLinearIssuesDirect, listModelsForAgent, listOpencodeModels, listPrs, listRunScripts, listSlackReplyBadges, listSlackWorkspaces, listThreads, listWorkspaces, listWorktreeFiles, listWorktrees, loadAgentInstructions, loadAppSettings, loadBrightsyConfig, loadConductorSettings, loadRepoSettings, loadWorkspaceSettings, locksDir, loginAgent, lookupSoccerTeam, maxConcurrentAgents, maybeCompactContext, mcpAllowTools, mcpAuthWarnings, mergePr, mergePrStack, mergeUsage, nextPastedTextName, nextThinkingEffort, normalizeParseResult, normalizeThinkingEffort, normalizeThread, normalizeTurnInput, normalizeWorktreePath, openInSystemTerminal, openPrStackLayers, openStackLayer, opencodeAdapter, orchestrationQuotaFallbackAgent, orchestrationQuotaOnLimit, orchestrationTitleNeedsSoccerNickname, orchestratorSessionPoisonedByBuiltins, originGhRepoEnv, parseCursorRunnerLine, parseForceStopMessage, parseGhStackViewJson, parseGithubSlugFromRemoteUrl, parseMcpList, parsePlanQuestionsInput, parseSessionQuotaResetAt, parseSlackRelayClientMessage, parseSlackRelayServerMessage, partsToAssistantText, pastedTextStats, permalinkForSlackReplyBadge, permissionMode, persistVaultKeyInKeychain, planFileAbs, posixShellSingleQuote, prepareTerminalCommand, previewLand, promptMentionsBrightsy, pushBranch, readExistingReviewRequestFile, readKeychainVaultKey, readPlanFile, readSkillBody, readThread, readWorktreeFile, readWorktreeFileForUpload, readWorktreeInclude, recordSlackOutboundWatch, refreshGitHubAuth, refreshSlackReplyBadges, removeWorkspace, removeWorktree, repoSlug, requestReview, requireAgent, resetGhStackDetectCache, resolveAgentExecutable, resolveClaudeExecutable, resolveCommandBinarySync, resolveConductorCursorAgentId, resolveCursorModelId, resolveDefaultBranch, resolveDiffBaseRef, resolveEffectiveIssueSource, resolveFilesToCopy, resolveGhAuthToken, resolveGithubRepoSlug, resolveLoginCommand, resolveNewThreadOptions, resolvePlanMarkdown, resolvePrSelector, resolveQuotaFallbackAgent, resolveRepoRoot, resolveReviewGuidelines, resolveSlackListenMode, resolveThreadDefaults, resolveThreadEffort, resolveVaultKey, resolveWorktreeStartPoint, run, runArchiveScript, runCloudConnect, runCursorWorktreeSetup, runSetupScript, runSlackListen, runSlackRelayClient, sameWorktreePath, sanitizeMcpServerName, saveAppSettings, saveLinearOAuth, secureFileUnlocksWith, setCaffeinateHold, setStatus, setVaultMasterKey, settingsSourceLabel, shouldAttachPastedText, shouldCompactContext, shouldInjectBrightsyMcp, shouldRefreshReviewRequestTemplate, shouldRunWorktreeCleanup, sideboardHomeDir, sideboardMcpProfile, sideboardReposDir, sideboardWorkspacesDir, slackAppLevelToken, slackArchiveUrl, slackCoordinatorSourceRef, slackListenEnabled, slackOAuthCredentials, slackRelayUrl, slugify, spawnAgentTurn, splitForCompaction, stackAgentDefaultsFrom, stackIdFrom, stackMergeReadiness, stageAbsolutePathsAsAttachments, stageBuffersAsAttachments, startDevServer, startLinearOAuth, startMcpServer, startOrchestration, startSlackOAuth, startSlackRelayServer, stripBrightsyNdjsonNoise, submitPrStack, suggestSlug, summarizeConversation, switchBrightsyAccount, syncWorkspacesFromThreads, takenTeamSlugsForChatTab, takenTeamSlugsForOrchestration, taskMessageText, thinkingEffortBars, thinkingEffortLabel, threadDisplayLabel, threadFilePath, threadLockPath, threadRequestsBrightsyMcp, threadsDir, threadsSharingWorktree, toPublicAppSettings, toolDescription, toolDetail, toolFilePath, totalTokens, updateAdvancedSettings, updateAgentExecutable, updateAppEnvironment, updateBrightsySettings, updateClaudeSettings, updateCodexSettings, updateDefaultsSettings, updateIntegrationsSettings, updateOpencodeSettings, updateThread, validateLinearApiKey, withAgentInstructions, withExportedPath, withThreadLock, workspaceSettingsSourceLabel, worktreeCleanupSettings, worktreeDisplayLabel, worktreeDisplayLabelForGroup, worktreeNameFromPath, worktreesRoot, writeInjectedMcpConfig, writePlanFile, writeThread, writeWorktreeFile };