@sideboard-ai/core 0.1.219 → 0.1.221

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.
@@ -8908,6 +8908,12 @@ var init_fetch = __esm({
8908
8908
  });
8909
8909
 
8910
8910
  // src/brightsy/oauth.ts
8911
+ function defaultFetch(fetchImpl) {
8912
+ return fetchImpl ?? globalThis.fetch.bind(globalThis);
8913
+ }
8914
+ function normalizeBrightsyEndpoint(endpoint) {
8915
+ return (endpoint || "https://brightsy.ai").replace(/\/$/, "");
8916
+ }
8911
8917
  function brightsyAccessTokenNeedsRefresh(expiresAt, now = Date.now()) {
8912
8918
  if (typeof expiresAt !== "number" || !Number.isFinite(expiresAt) || expiresAt <= 0) {
8913
8919
  return true;
@@ -8921,10 +8927,53 @@ function applyGrant(current, grant) {
8921
8927
  expires_at: grant.expires_at ?? current.expires_at
8922
8928
  };
8923
8929
  }
8930
+ async function registerBrightsyOAuthClient(opts) {
8931
+ const endpoint = normalizeBrightsyEndpoint(opts.endpoint);
8932
+ const url = `${endpoint}/oauth/register`;
8933
+ const clientId = (opts.clientId || BRIGHTSY_OAUTH_CLIENT_ID).trim();
8934
+ const redirectUri = opts.redirectUri || BRIGHTSY_OAUTH_REDIRECT;
8935
+ const fetchImpl = defaultFetch(opts.fetchImpl);
8936
+ let res;
8937
+ try {
8938
+ res = await fetchImpl(url, {
8939
+ method: "POST",
8940
+ headers: { "Content-Type": "application/json" },
8941
+ body: JSON.stringify({
8942
+ client_id: clientId,
8943
+ client_name: "Sideboard",
8944
+ description: "Sideboard desktop Brightsy MCP client",
8945
+ redirect_uris: [redirectUri],
8946
+ scope: "brightsy:api",
8947
+ grant_types: ["authorization_code", "refresh_token"],
8948
+ response_types: ["code"],
8949
+ token_endpoint_auth_method: "none"
8950
+ })
8951
+ });
8952
+ } catch (err) {
8953
+ throw new Error(formatFetchError(err, url));
8954
+ }
8955
+ if (!res.ok) return null;
8956
+ const data = await res.json();
8957
+ if (!data.client_id?.trim()) return null;
8958
+ return {
8959
+ client_id: data.client_id.trim(),
8960
+ client_secret: data.client_secret?.trim() || void 0
8961
+ };
8962
+ }
8963
+ async function ensureBrightsyOAuthClientId(opts) {
8964
+ const existing = opts.clientId?.trim();
8965
+ if (existing) return existing;
8966
+ const registered = await registerBrightsyOAuthClient({
8967
+ endpoint: opts.endpoint,
8968
+ fetchImpl: opts.fetchImpl
8969
+ });
8970
+ return registered?.client_id || BRIGHTSY_OAUTH_CLIENT_ID;
8971
+ }
8924
8972
  async function refreshBrightsyAccessToken(opts) {
8925
- const endpoint = (opts.endpoint || "https://brightsy.ai").replace(/\/$/, "");
8973
+ const endpoint = normalizeBrightsyEndpoint(opts.endpoint);
8926
8974
  const url = `${endpoint}/oauth/token`;
8927
- const fetchImpl = opts.fetchImpl ?? globalThis.fetch.bind(globalThis);
8975
+ const fetchImpl = defaultFetch(opts.fetchImpl);
8976
+ const clientId = opts.clientId?.trim() || BRIGHTSY_OAUTH_CLIENT_ID;
8928
8977
  let res;
8929
8978
  try {
8930
8979
  res = await fetchImpl(url, {
@@ -8933,7 +8982,7 @@ async function refreshBrightsyAccessToken(opts) {
8933
8982
  body: new URLSearchParams({
8934
8983
  grant_type: "refresh_token",
8935
8984
  refresh_token: opts.refreshToken,
8936
- client_id: opts.clientId || "brightsy-cli"
8985
+ client_id: clientId
8937
8986
  })
8938
8987
  });
8939
8988
  } catch (err) {
@@ -8948,34 +8997,55 @@ async function refreshBrightsyAccessToken(opts) {
8948
8997
  expires_at: data.expires_in ? Date.now() + data.expires_in * 1e3 : void 0
8949
8998
  };
8950
8999
  }
8951
- async function ensureBrightsyLocalConfigFresh(opts) {
9000
+ async function ensureBrightsyLocalConfigFreshOnce(opts) {
8952
9001
  let cfg;
8953
9002
  try {
8954
9003
  cfg = loadBrightsyConfig();
8955
9004
  } catch {
8956
9005
  return null;
8957
9006
  }
8958
- if (!cfg.refresh_token || !brightsyAccessTokenNeedsRefresh(cfg.expires_at)) {
9007
+ const refreshToken = cfg.refresh_token;
9008
+ if (!refreshToken || !brightsyAccessTokenNeedsRefresh(cfg.expires_at)) {
8959
9009
  return cfg;
8960
9010
  }
8961
- const grant = await refreshBrightsyAccessToken({
8962
- endpoint: cfg.endpoint || "https://brightsy.ai",
8963
- refreshToken: cfg.refresh_token,
9011
+ const endpoint = normalizeBrightsyEndpoint(cfg.endpoint);
9012
+ const clientId = await ensureBrightsyOAuthClientId({
9013
+ endpoint,
8964
9014
  clientId: cfg.oauth_client_id,
8965
9015
  fetchImpl: opts?.fetchImpl
8966
9016
  });
9017
+ if (clientId !== cfg.oauth_client_id) {
9018
+ cfg = { ...cfg, oauth_client_id: clientId };
9019
+ saveBrightsyConfig(cfg);
9020
+ }
9021
+ const grant = await refreshBrightsyAccessToken({
9022
+ endpoint,
9023
+ refreshToken,
9024
+ clientId,
9025
+ fetchImpl: opts?.fetchImpl
9026
+ });
8967
9027
  if (!grant) return cfg;
8968
- const next = { ...cfg, ...applyGrant(cfg, grant) };
9028
+ const next = { ...cfg, ...applyGrant(cfg, grant), oauth_client_id: clientId };
8969
9029
  saveBrightsyConfig(next);
8970
9030
  return next;
8971
9031
  }
8972
- var REFRESH_SKEW_MS;
9032
+ async function ensureBrightsyLocalConfigFresh(opts) {
9033
+ if (refreshInFlight) return refreshInFlight;
9034
+ refreshInFlight = ensureBrightsyLocalConfigFreshOnce(opts).finally(() => {
9035
+ refreshInFlight = null;
9036
+ });
9037
+ return refreshInFlight;
9038
+ }
9039
+ var REFRESH_SKEW_MS, BRIGHTSY_OAUTH_CLIENT_ID, BRIGHTSY_OAUTH_REDIRECT, refreshInFlight;
8973
9040
  var init_oauth = __esm({
8974
9041
  "src/brightsy/oauth.ts"() {
8975
9042
  "use strict";
8976
9043
  init_fetch();
8977
9044
  init_config();
8978
9045
  REFRESH_SKEW_MS = 6e4;
9046
+ BRIGHTSY_OAUTH_CLIENT_ID = "sideboard";
9047
+ BRIGHTSY_OAUTH_REDIRECT = "http://127.0.0.1:19850/callback";
9048
+ refreshInFlight = null;
8979
9049
  }
8980
9050
  });
8981
9051
 
@@ -9024,10 +9094,10 @@ function applyConnectedTeamToCli(team) {
9024
9094
  account_id: team.id,
9025
9095
  account_slug: team.slug,
9026
9096
  endpoint: team.endpoint ?? base.endpoint ?? "https://brightsy.ai",
9027
- oauth_client_id: base.oauth_client_id
9097
+ oauth_client_id: team.oauth_client_id ?? base.oauth_client_id
9028
9098
  });
9029
9099
  }
9030
- async function refreshTeamToken(team) {
9100
+ async function refreshTeamToken(team, opts) {
9031
9101
  if (!team.refresh_token) return team;
9032
9102
  const cfg = (() => {
9033
9103
  try {
@@ -9036,21 +9106,31 @@ async function refreshTeamToken(team) {
9036
9106
  return null;
9037
9107
  }
9038
9108
  })();
9109
+ const endpoint = team.endpoint || "https://brightsy.ai";
9110
+ const clientId = await ensureBrightsyOAuthClientId({
9111
+ endpoint,
9112
+ clientId: team.oauth_client_id || cfg?.oauth_client_id,
9113
+ fetchImpl: opts?.fetchImpl
9114
+ });
9039
9115
  const grant = await refreshBrightsyAccessToken({
9040
- endpoint: team.endpoint || "https://brightsy.ai",
9116
+ endpoint,
9041
9117
  refreshToken: team.refresh_token,
9042
- clientId: cfg?.oauth_client_id
9118
+ clientId,
9119
+ fetchImpl: opts?.fetchImpl
9043
9120
  });
9044
- if (!grant) return team;
9121
+ if (!grant) return { ...team, oauth_client_id: clientId || team.oauth_client_id };
9045
9122
  return {
9046
9123
  ...team,
9047
9124
  access_token: grant.access_token,
9048
9125
  refresh_token: grant.refresh_token || team.refresh_token,
9049
- expires_at: grant.expires_at ?? team.expires_at
9126
+ expires_at: grant.expires_at ?? team.expires_at,
9127
+ oauth_client_id: clientId
9050
9128
  };
9051
9129
  }
9052
- async function ensureConnectedBrightsyTeamTokens() {
9053
- await ensureBrightsyLocalConfigFresh().catch(() => null);
9130
+ async function ensureConnectedBrightsyTeamTokens(opts) {
9131
+ await ensureBrightsyLocalConfigFresh({ fetchImpl: opts?.fetchImpl }).catch(
9132
+ () => null
9133
+ );
9054
9134
  const teams = readStore4();
9055
9135
  if (teams.length === 0) return [];
9056
9136
  const next = [];
@@ -9060,8 +9140,8 @@ async function ensureConnectedBrightsyTeamTokens() {
9060
9140
  next.push(team);
9061
9141
  continue;
9062
9142
  }
9063
- const refreshed = await refreshTeamToken(team);
9064
- if (refreshed.access_token !== team.access_token || refreshed.refresh_token !== team.refresh_token || refreshed.expires_at !== team.expires_at) {
9143
+ const refreshed = await refreshTeamToken(team, opts);
9144
+ if (refreshed.access_token !== team.access_token || refreshed.refresh_token !== team.refresh_token || refreshed.expires_at !== team.expires_at || refreshed.oauth_client_id !== team.oauth_client_id) {
9065
9145
  changed = true;
9066
9146
  }
9067
9147
  next.push(refreshed);
@@ -9091,7 +9171,8 @@ function ensureCliTeamTracked(meta) {
9091
9171
  access_token: cfg.access_token,
9092
9172
  refresh_token: cfg.refresh_token,
9093
9173
  expires_at: cfg.expires_at,
9094
- endpoint: cfg.endpoint
9174
+ endpoint: cfg.endpoint,
9175
+ oauth_client_id: cfg.oauth_client_id
9095
9176
  };
9096
9177
  writeStore2([...existing, team]);
9097
9178
  } catch {
@@ -9893,6 +9974,7 @@ function teamEnv(team) {
9893
9974
  return {
9894
9975
  BRIGHTSY_API_TOKEN: team.access_token,
9895
9976
  ...team.refresh_token ? { BRIGHTSY_REFRESH_TOKEN: team.refresh_token } : {},
9977
+ ...team.oauth_client_id ? { BRIGHTSY_OAUTH_CLIENT_ID: team.oauth_client_id } : {},
9896
9978
  BRIGHTSY_ACCOUNT_ID: team.id,
9897
9979
  BRIGHTSY_API_URL: endpoint
9898
9980
  };
@@ -16213,12 +16295,12 @@ async function ensureAbleTimeAccessToken() {
16213
16295
  return access;
16214
16296
  }
16215
16297
  if (refresh) {
16216
- if (!refreshInFlight) {
16217
- refreshInFlight = refreshAbleTimeAccessToken(refresh).finally(() => {
16218
- refreshInFlight = null;
16298
+ if (!refreshInFlight2) {
16299
+ refreshInFlight2 = refreshAbleTimeAccessToken(refresh).finally(() => {
16300
+ refreshInFlight2 = null;
16219
16301
  });
16220
16302
  }
16221
- return refreshInFlight;
16303
+ return refreshInFlight2;
16222
16304
  }
16223
16305
  return access || null;
16224
16306
  }
@@ -16341,7 +16423,7 @@ async function startAbleTimeOAuth(opts) {
16341
16423
  return loadAppSettings();
16342
16424
  }
16343
16425
  }
16344
- var import_node_crypto9, import_node_http, ABLETIME_OAUTH_CALLBACK_PATH, ABLETIME_OAUTH_PORT, ABLETIME_OAUTH_LOCAL_CALLBACK, ABLETIME_OAUTH_REDIRECT, BOUNCE_QUERY_KEYS, BAKED_ABLETIME_OAUTH_CLIENT_ID, ABLETIME_OAUTH_RESOURCE, REFRESH_SKEW_MS2, refreshInFlight, ABLETIME_OAUTH_CANCELLED, AbleTimeOAuthCancelledError;
16426
+ var import_node_crypto9, import_node_http, ABLETIME_OAUTH_CALLBACK_PATH, ABLETIME_OAUTH_PORT, ABLETIME_OAUTH_LOCAL_CALLBACK, ABLETIME_OAUTH_REDIRECT, BOUNCE_QUERY_KEYS, BAKED_ABLETIME_OAUTH_CLIENT_ID, ABLETIME_OAUTH_RESOURCE, REFRESH_SKEW_MS2, refreshInFlight2, ABLETIME_OAUTH_CANCELLED, AbleTimeOAuthCancelledError;
16345
16427
  var init_abletime_oauth = __esm({
16346
16428
  "src/integrations/abletime-oauth.ts"() {
16347
16429
  "use strict";
@@ -16358,7 +16440,7 @@ var init_abletime_oauth = __esm({
16358
16440
  BAKED_ABLETIME_OAUTH_CLIENT_ID = "https://www.sideboard.cloud/oauth/abletime-client.json";
16359
16441
  ABLETIME_OAUTH_RESOURCE = `${DEFAULT_ABLETIME_HOST}/api/public/v2/mcp`;
16360
16442
  REFRESH_SKEW_MS2 = 5 * 6e4;
16361
- refreshInFlight = null;
16443
+ refreshInFlight2 = null;
16362
16444
  ABLETIME_OAUTH_CANCELLED = "AbleTime sign-in cancelled";
16363
16445
  AbleTimeOAuthCancelledError = class extends Error {
16364
16446
  constructor(message = ABLETIME_OAUTH_CANCELLED) {
@@ -24238,7 +24320,7 @@ async function persistLinearTokens(data, viewer) {
24238
24320
  organizationName: viewer?.organizationName
24239
24321
  });
24240
24322
  }
24241
- var refreshInFlight2 = null;
24323
+ var refreshInFlight3 = null;
24242
24324
  async function refreshLinearAccessToken(refreshToken) {
24243
24325
  const { clientId, clientSecret } = linearOAuthCredentials();
24244
24326
  const body = new URLSearchParams({
@@ -24269,12 +24351,12 @@ async function getLinearAuthToken(settings = loadAppSettings()) {
24269
24351
  return access;
24270
24352
  }
24271
24353
  if (refresh) {
24272
- if (!refreshInFlight2) {
24273
- refreshInFlight2 = refreshLinearAccessToken(refresh).finally(() => {
24274
- refreshInFlight2 = null;
24354
+ if (!refreshInFlight3) {
24355
+ refreshInFlight3 = refreshLinearAccessToken(refresh).finally(() => {
24356
+ refreshInFlight3 = null;
24275
24357
  });
24276
24358
  }
24277
- return refreshInFlight2.catch((err) => {
24359
+ return refreshInFlight3.catch((err) => {
24278
24360
  if (apiKey) return apiKey;
24279
24361
  throw err;
24280
24362
  });
@@ -50,7 +50,7 @@ import {
50
50
  syncBoardPins,
51
51
  updateSchedule,
52
52
  waitForDetachedJob
53
- } from "../chunk-XGE6YUO6.js";
53
+ } from "../chunk-ALDVGAIO.js";
54
54
  import "../chunk-JFOPOMK7.js";
55
55
  import "../chunk-YWI3IBP2.js";
56
56
  import {
@@ -61,14 +61,14 @@ import {
61
61
  materializeSystemCaBundle,
62
62
  sideboardMcpProfile,
63
63
  trustSystemCertificates
64
- } from "../chunk-IAP5NXQ4.js";
64
+ } from "../chunk-3Y4FIARC.js";
65
65
  import {
66
66
  GLOBAL_WORKSPACE_ID,
67
67
  isCloudCoordinatorThread,
68
68
  listWorkspaces
69
69
  } from "../chunk-P2EAAM3H.js";
70
- import "../chunk-SVXIJ2IC.js";
71
- import "../chunk-Y4MIXGPA.js";
70
+ import "../chunk-UNMMKZ4Q.js";
71
+ import "../chunk-P2BSMNHB.js";
72
72
  import "../chunk-CLI5DVU4.js";
73
73
  import "../chunk-HSYE5ID6.js";
74
74
  import {
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ BRIGHTSY_OAUTH_CLIENT_ID,
5
+ BRIGHTSY_OAUTH_REDIRECT,
6
+ brightsyAccessTokenNeedsRefresh,
7
+ ensureBrightsyLocalConfigFresh,
8
+ ensureBrightsyOAuthClientId,
9
+ normalizeBrightsyEndpoint,
10
+ refreshBrightsyAccessToken,
11
+ registerBrightsyOAuthClient
12
+ } from "./chunk-P2BSMNHB.js";
13
+ import "./chunk-VKQGAWHY.js";
14
+ export {
15
+ BRIGHTSY_OAUTH_CLIENT_ID,
16
+ BRIGHTSY_OAUTH_REDIRECT,
17
+ brightsyAccessTokenNeedsRefresh,
18
+ ensureBrightsyLocalConfigFresh,
19
+ ensureBrightsyOAuthClientId,
20
+ normalizeBrightsyEndpoint,
21
+ refreshBrightsyAccessToken,
22
+ registerBrightsyOAuthClient
23
+ };
@@ -0,0 +1,21 @@
1
+ import {
2
+ BRIGHTSY_OAUTH_CLIENT_ID,
3
+ BRIGHTSY_OAUTH_REDIRECT,
4
+ brightsyAccessTokenNeedsRefresh,
5
+ ensureBrightsyLocalConfigFresh,
6
+ ensureBrightsyOAuthClientId,
7
+ normalizeBrightsyEndpoint,
8
+ refreshBrightsyAccessToken,
9
+ registerBrightsyOAuthClient
10
+ } from "./chunk-ROPGQRPU.js";
11
+ import "./chunk-N7WZ6NIN.js";
12
+ export {
13
+ BRIGHTSY_OAUTH_CLIENT_ID,
14
+ BRIGHTSY_OAUTH_REDIRECT,
15
+ brightsyAccessTokenNeedsRefresh,
16
+ ensureBrightsyLocalConfigFresh,
17
+ ensureBrightsyOAuthClientId,
18
+ normalizeBrightsyEndpoint,
19
+ refreshBrightsyAccessToken,
20
+ registerBrightsyOAuthClient
21
+ };
@@ -10,13 +10,13 @@ import {
10
10
  resolveSendFollowUp,
11
11
  startOrchestration,
12
12
  waitForPidExit
13
- } from "./chunk-XGE6YUO6.js";
13
+ } from "./chunk-ALDVGAIO.js";
14
14
  import "./chunk-JFOPOMK7.js";
15
15
  import "./chunk-YWI3IBP2.js";
16
- import "./chunk-IAP5NXQ4.js";
16
+ import "./chunk-3Y4FIARC.js";
17
17
  import "./chunk-P2EAAM3H.js";
18
- import "./chunk-SVXIJ2IC.js";
19
- import "./chunk-Y4MIXGPA.js";
18
+ import "./chunk-UNMMKZ4Q.js";
19
+ import "./chunk-P2BSMNHB.js";
20
20
  import "./chunk-VKQGAWHY.js";
21
21
  import "./chunk-NFWPDEN4.js";
22
22
  import "./chunk-D6JWYJ4P.js";
@@ -8,15 +8,15 @@ import {
8
8
  resolveSendFollowUp,
9
9
  startOrchestration,
10
10
  waitForPidExit
11
- } from "./chunk-EIICOB7P.js";
11
+ } from "./chunk-B73KKJQB.js";
12
12
  import "./chunk-DJU54RYW.js";
13
- import "./chunk-K642ORWF.js";
13
+ import "./chunk-YG2X34EF.js";
14
14
  import "./chunk-N2VST3NL.js";
15
15
  import "./chunk-KTZESHYH.js";
16
16
  import "./chunk-6K64FJDD.js";
17
17
  import "./chunk-PO4M4JAJ.js";
18
- import "./chunk-IILG7DPX.js";
19
- import "./chunk-AN3THU7F.js";
18
+ import "./chunk-QILV2BRW.js";
19
+ import "./chunk-ROPGQRPU.js";
20
20
  import "./chunk-N7WZ6NIN.js";
21
21
  import "./chunk-AXQ4ZWHK.js";
22
22
  import "./chunk-TQBUXKIB.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sideboard-ai/core",
3
- "version": "0.1.219",
3
+ "version": "0.1.221",
4
4
  "description": "Sideboard core — orchestration, agents, git worktrees, MCP server",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -1,103 +0,0 @@
1
- import {
2
- formatFetchError
3
- } from "./chunk-N7WZ6NIN.js";
4
-
5
- // src/brightsy/config.ts
6
- import { existsSync, readFileSync, writeFileSync } from "fs";
7
- import { homedir } from "os";
8
- import { join } from "path";
9
- function brightsyConfigPath() {
10
- const override = process.env.BRIGHTSY_CONFIG?.trim();
11
- if (override) return override;
12
- return join(homedir(), ".brightsy", "config.json");
13
- }
14
- function loadBrightsyConfig() {
15
- const path = brightsyConfigPath();
16
- if (!existsSync(path)) {
17
- throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
18
- }
19
- const raw = JSON.parse(readFileSync(path, "utf8"));
20
- if (!raw.access_token || !raw.account_id) {
21
- throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
22
- }
23
- return raw;
24
- }
25
- function saveBrightsyConfig(cfg) {
26
- writeFileSync(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
27
- `, {
28
- mode: 384
29
- });
30
- }
31
-
32
- // src/brightsy/oauth.ts
33
- var REFRESH_SKEW_MS = 6e4;
34
- function brightsyAccessTokenNeedsRefresh(expiresAt, now = Date.now()) {
35
- if (typeof expiresAt !== "number" || !Number.isFinite(expiresAt) || expiresAt <= 0) {
36
- return true;
37
- }
38
- return now >= expiresAt - REFRESH_SKEW_MS;
39
- }
40
- function applyGrant(current, grant) {
41
- return {
42
- access_token: grant.access_token,
43
- refresh_token: grant.refresh_token || current.refresh_token,
44
- expires_at: grant.expires_at ?? current.expires_at
45
- };
46
- }
47
- async function refreshBrightsyAccessToken(opts) {
48
- const endpoint = (opts.endpoint || "https://brightsy.ai").replace(/\/$/, "");
49
- const url = `${endpoint}/oauth/token`;
50
- const fetchImpl = opts.fetchImpl ?? globalThis.fetch.bind(globalThis);
51
- let res;
52
- try {
53
- res = await fetchImpl(url, {
54
- method: "POST",
55
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
56
- body: new URLSearchParams({
57
- grant_type: "refresh_token",
58
- refresh_token: opts.refreshToken,
59
- client_id: opts.clientId || "brightsy-cli"
60
- })
61
- });
62
- } catch (err) {
63
- throw new Error(formatFetchError(err, url));
64
- }
65
- if (!res.ok) return null;
66
- const data = await res.json();
67
- if (!data.access_token) return null;
68
- return {
69
- access_token: data.access_token,
70
- refresh_token: data.refresh_token,
71
- expires_at: data.expires_in ? Date.now() + data.expires_in * 1e3 : void 0
72
- };
73
- }
74
- async function ensureBrightsyLocalConfigFresh(opts) {
75
- let cfg;
76
- try {
77
- cfg = loadBrightsyConfig();
78
- } catch {
79
- return null;
80
- }
81
- if (!cfg.refresh_token || !brightsyAccessTokenNeedsRefresh(cfg.expires_at)) {
82
- return cfg;
83
- }
84
- const grant = await refreshBrightsyAccessToken({
85
- endpoint: cfg.endpoint || "https://brightsy.ai",
86
- refreshToken: cfg.refresh_token,
87
- clientId: cfg.oauth_client_id,
88
- fetchImpl: opts?.fetchImpl
89
- });
90
- if (!grant) return cfg;
91
- const next = { ...cfg, ...applyGrant(cfg, grant) };
92
- saveBrightsyConfig(next);
93
- return next;
94
- }
95
-
96
- export {
97
- brightsyConfigPath,
98
- loadBrightsyConfig,
99
- saveBrightsyConfig,
100
- brightsyAccessTokenNeedsRefresh,
101
- refreshBrightsyAccessToken,
102
- ensureBrightsyLocalConfigFresh
103
- };
@@ -1,104 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import {
4
- formatFetchError
5
- } from "./chunk-VKQGAWHY.js";
6
-
7
- // src/brightsy/config.ts
8
- import { existsSync, readFileSync, writeFileSync } from "fs";
9
- import { homedir } from "os";
10
- import { join } from "path";
11
- function brightsyConfigPath() {
12
- const override = process.env.BRIGHTSY_CONFIG?.trim();
13
- if (override) return override;
14
- return join(homedir(), ".brightsy", "config.json");
15
- }
16
- function loadBrightsyConfig() {
17
- const path = brightsyConfigPath();
18
- if (!existsSync(path)) {
19
- throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
20
- }
21
- const raw = JSON.parse(readFileSync(path, "utf8"));
22
- if (!raw.access_token || !raw.account_id) {
23
- throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
24
- }
25
- return raw;
26
- }
27
- function saveBrightsyConfig(cfg) {
28
- writeFileSync(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
29
- `, {
30
- mode: 384
31
- });
32
- }
33
-
34
- // src/brightsy/oauth.ts
35
- var REFRESH_SKEW_MS = 6e4;
36
- function brightsyAccessTokenNeedsRefresh(expiresAt, now = Date.now()) {
37
- if (typeof expiresAt !== "number" || !Number.isFinite(expiresAt) || expiresAt <= 0) {
38
- return true;
39
- }
40
- return now >= expiresAt - REFRESH_SKEW_MS;
41
- }
42
- function applyGrant(current, grant) {
43
- return {
44
- access_token: grant.access_token,
45
- refresh_token: grant.refresh_token || current.refresh_token,
46
- expires_at: grant.expires_at ?? current.expires_at
47
- };
48
- }
49
- async function refreshBrightsyAccessToken(opts) {
50
- const endpoint = (opts.endpoint || "https://brightsy.ai").replace(/\/$/, "");
51
- const url = `${endpoint}/oauth/token`;
52
- const fetchImpl = opts.fetchImpl ?? globalThis.fetch.bind(globalThis);
53
- let res;
54
- try {
55
- res = await fetchImpl(url, {
56
- method: "POST",
57
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
58
- body: new URLSearchParams({
59
- grant_type: "refresh_token",
60
- refresh_token: opts.refreshToken,
61
- client_id: opts.clientId || "brightsy-cli"
62
- })
63
- });
64
- } catch (err) {
65
- throw new Error(formatFetchError(err, url));
66
- }
67
- if (!res.ok) return null;
68
- const data = await res.json();
69
- if (!data.access_token) return null;
70
- return {
71
- access_token: data.access_token,
72
- refresh_token: data.refresh_token,
73
- expires_at: data.expires_in ? Date.now() + data.expires_in * 1e3 : void 0
74
- };
75
- }
76
- async function ensureBrightsyLocalConfigFresh(opts) {
77
- let cfg;
78
- try {
79
- cfg = loadBrightsyConfig();
80
- } catch {
81
- return null;
82
- }
83
- if (!cfg.refresh_token || !brightsyAccessTokenNeedsRefresh(cfg.expires_at)) {
84
- return cfg;
85
- }
86
- const grant = await refreshBrightsyAccessToken({
87
- endpoint: cfg.endpoint || "https://brightsy.ai",
88
- refreshToken: cfg.refresh_token,
89
- clientId: cfg.oauth_client_id,
90
- fetchImpl: opts?.fetchImpl
91
- });
92
- if (!grant) return cfg;
93
- const next = { ...cfg, ...applyGrant(cfg, grant) };
94
- saveBrightsyConfig(next);
95
- return next;
96
- }
97
-
98
- export {
99
- loadBrightsyConfig,
100
- saveBrightsyConfig,
101
- brightsyAccessTokenNeedsRefresh,
102
- refreshBrightsyAccessToken,
103
- ensureBrightsyLocalConfigFresh
104
- };
@@ -1,11 +0,0 @@
1
- import {
2
- brightsyAccessTokenNeedsRefresh,
3
- ensureBrightsyLocalConfigFresh,
4
- refreshBrightsyAccessToken
5
- } from "./chunk-AN3THU7F.js";
6
- import "./chunk-N7WZ6NIN.js";
7
- export {
8
- brightsyAccessTokenNeedsRefresh,
9
- ensureBrightsyLocalConfigFresh,
10
- refreshBrightsyAccessToken
11
- };
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import {
4
- brightsyAccessTokenNeedsRefresh,
5
- ensureBrightsyLocalConfigFresh,
6
- refreshBrightsyAccessToken
7
- } from "./chunk-Y4MIXGPA.js";
8
- import "./chunk-VKQGAWHY.js";
9
- export {
10
- brightsyAccessTokenNeedsRefresh,
11
- ensureBrightsyLocalConfigFresh,
12
- refreshBrightsyAccessToken
13
- };