perchai-cli 2.4.47 → 2.4.48

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 (2) hide show
  1. package/dist/perch.mjs +235 -171
  2. package/package.json +1 -1
package/dist/perch.mjs CHANGED
@@ -75918,6 +75918,7 @@ function isTurnAbortedError(error) {
75918
75918
  var TURN_STOPPED_BY_USER_MESSAGE;
75919
75919
  var init_turnAbort = __esm({
75920
75920
  "features/perchTerminal/runtime/turnAbort.ts"() {
75921
+ "use strict";
75921
75922
  TURN_STOPPED_BY_USER_MESSAGE = "Turn stopped by user.";
75922
75923
  }
75923
75924
  });
@@ -76223,6 +76224,7 @@ function getToolDisplayName(toolName) {
76223
76224
  var NON_MODULE_TOOL_OWNERS, TOOL_RISK, TOOL_DISPLAY_NAMES;
76224
76225
  var init_catalog = __esm({
76225
76226
  "features/perchTerminal/runtime/toolSystem/catalog.ts"() {
76227
+ "use strict";
76226
76228
  init_toolNames();
76227
76229
  NON_MODULE_TOOL_OWNERS = {
76228
76230
  [TOOL_NAMES.listSources]: "lane",
@@ -91108,7 +91110,6 @@ Final answers lead with findings, name artifacts or delivery status, and give on
91108
91110
  var MARKET_DESK_TOOL_NAMES;
91109
91111
  var init_marketDeskAccess = __esm({
91110
91112
  "features/perchTerminal/runtime/marketDesk/marketDeskAccess.ts"() {
91111
- "use strict";
91112
91113
  init_toolNames();
91113
91114
  MARKET_DESK_TOOL_NAMES = /* @__PURE__ */ new Set([
91114
91115
  TOOL_NAMES.getMarketSignal,
@@ -91788,7 +91789,6 @@ function listFinancialPlaybooks() {
91788
91789
  var AP_AUDIT_PACKET_DEF, PLAYBOOKS;
91789
91790
  var init_registry2 = __esm({
91790
91791
  "features/perchTerminal/runtime/financialPlaybooks/registry.ts"() {
91791
- "use strict";
91792
91792
  init_managedWorkflowRegistry2();
91793
91793
  init_toolNames();
91794
91794
  AP_AUDIT_PACKET_DEF = {
@@ -115612,10 +115612,10 @@ function matchStringTarget(hostname, target) {
115612
115612
  }
115613
115613
  return false;
115614
115614
  }
115615
- function getDefaultPropagationTargets(supabaseUrl2) {
115615
+ function getDefaultPropagationTargets(supabaseUrl) {
115616
115616
  const targets = [];
115617
115617
  try {
115618
- const url = new URL(supabaseUrl2);
115618
+ const url = new URL(supabaseUrl);
115619
115619
  targets.push(url.hostname);
115620
115620
  } catch (error) {
115621
115621
  }
@@ -115712,8 +115712,8 @@ function applySettingDefaults(options, defaults) {
115712
115712
  else delete result2.accessToken;
115713
115713
  return result2;
115714
115714
  }
115715
- function validateSupabaseUrl(supabaseUrl2) {
115716
- const trimmedUrl = supabaseUrl2 === null || supabaseUrl2 === void 0 ? void 0 : supabaseUrl2.trim();
115715
+ function validateSupabaseUrl(supabaseUrl) {
115716
+ const trimmedUrl = supabaseUrl === null || supabaseUrl === void 0 ? void 0 : supabaseUrl.trim();
115717
115717
  if (!trimmedUrl) throw new Error("supabaseUrl is required.");
115718
115718
  if (!trimmedUrl.match(/^https?:\/\//i)) throw new Error("Invalid supabaseUrl: Must be a valid HTTP or HTTPS URL.");
115719
115719
  try {
@@ -115771,12 +115771,12 @@ var init_dist4 = __esm({
115771
115771
  resolveHeadersConstructor = () => {
115772
115772
  return Headers;
115773
115773
  };
115774
- fetchWithAuth = (supabaseKey, supabaseUrl2, getAccessToken, customFetch, tracePropagationOptions) => {
115774
+ fetchWithAuth = (supabaseKey, supabaseUrl, getAccessToken, customFetch, tracePropagationOptions) => {
115775
115775
  const fetch$1 = resolveFetch2(customFetch);
115776
115776
  const HeadersConstructor = resolveHeadersConstructor();
115777
115777
  const traceEnabled = (tracePropagationOptions === null || tracePropagationOptions === void 0 ? void 0 : tracePropagationOptions.enabled) === true;
115778
115778
  const respectSampling = (tracePropagationOptions === null || tracePropagationOptions === void 0 ? void 0 : tracePropagationOptions.respectSamplingDecision) !== false;
115779
- const traceTargets = traceEnabled ? getDefaultPropagationTargets(supabaseUrl2) : null;
115779
+ const traceTargets = traceEnabled ? getDefaultPropagationTargets(supabaseUrl) : null;
115780
115780
  return async (input, init) => {
115781
115781
  var _await$getAccessToken;
115782
115782
  const accessToken = (_await$getAccessToken = await getAccessToken()) !== null && _await$getAccessToken !== void 0 ? _await$getAccessToken : supabaseKey;
@@ -115987,11 +115987,11 @@ var init_dist4 = __esm({
115987
115987
  * const { data } = await supabase.from('profiles').select('*')
115988
115988
  * ```
115989
115989
  */
115990
- constructor(supabaseUrl2, supabaseKey, options) {
115990
+ constructor(supabaseUrl, supabaseKey, options) {
115991
115991
  var _settings$auth$storag, _settings$global$head;
115992
- this.supabaseUrl = supabaseUrl2;
115992
+ this.supabaseUrl = supabaseUrl;
115993
115993
  this.supabaseKey = supabaseKey;
115994
- const baseUrl = validateSupabaseUrl(supabaseUrl2);
115994
+ const baseUrl = validateSupabaseUrl(supabaseUrl);
115995
115995
  if (!supabaseKey) throw new Error("supabaseKey is required.");
115996
115996
  this.realtimeUrl = new URL("realtime/v1", baseUrl);
115997
115997
  this.realtimeUrl.protocol = this.realtimeUrl.protocol.replace("http", "ws");
@@ -116019,7 +116019,7 @@ var init_dist4 = __esm({
116019
116019
  throw new Error(`@supabase/supabase-js: Supabase Client is configured with the accessToken option, accessing supabase.auth.${String(prop)} is not possible`);
116020
116020
  } });
116021
116021
  }
116022
- this.fetch = fetchWithAuth(supabaseKey, supabaseUrl2, this._getAccessToken.bind(this), settings.global.fetch, settings.tracePropagation);
116022
+ this.fetch = fetchWithAuth(supabaseKey, supabaseUrl, this._getAccessToken.bind(this), settings.global.fetch, settings.tracePropagation);
116023
116023
  this.realtime = this._initRealtimeClient(_objectSpread23({
116024
116024
  headers: this.headers,
116025
116025
  accessToken: this._getAccessToken.bind(this),
@@ -116203,8 +116203,8 @@ var init_dist4 = __esm({
116203
116203
  }
116204
116204
  }
116205
116205
  };
116206
- createClient = (supabaseUrl2, supabaseKey, options) => {
116207
- return new SupabaseClient(supabaseUrl2, supabaseKey, options);
116206
+ createClient = (supabaseUrl, supabaseKey, options) => {
116207
+ return new SupabaseClient(supabaseUrl, supabaseKey, options);
116208
116208
  };
116209
116209
  if (shouldShowDeprecationWarning()) console.warn("\u26A0\uFE0F Node.js 18 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 20 or later. For more information, visit: https://github.com/orgs/supabase/discussions/37217");
116210
116210
  }
@@ -119113,6 +119113,24 @@ var init_autoRouter = __esm({
119113
119113
  }
119114
119114
  });
119115
119115
 
119116
+ // lib/auth/browserSession.ts
119117
+ async function syncBrowserAuthSession() {
119118
+ if (typeof window === "undefined") return null;
119119
+ const response = await fetch("/api/auth/session", SESSION_FETCH_OPTIONS);
119120
+ if (!response.ok) return null;
119121
+ const body = await response.json();
119122
+ return body.session ?? null;
119123
+ }
119124
+ var SESSION_FETCH_OPTIONS;
119125
+ var init_browserSession = __esm({
119126
+ "lib/auth/browserSession.ts"() {
119127
+ SESSION_FETCH_OPTIONS = {
119128
+ credentials: "same-origin",
119129
+ cache: "no-store"
119130
+ };
119131
+ }
119132
+ });
119133
+
119116
119134
  // features/perchTerminal/runtime/roost.ts
119117
119135
  function normalizeRoostTier(value) {
119118
119136
  if (value === "max") return "pro_max";
@@ -119473,9 +119491,18 @@ async function callModelRouterViaServer(request, opts, endpoint = "/api/perch-te
119473
119491
  async function fetchModelProxyWithRetry(endpoint, init, options) {
119474
119492
  const maxAttempts = Math.max(1, options?.maxAttempts ?? MODEL_PROXY_MAX_ATTEMPTS);
119475
119493
  let lastError = null;
119494
+ let authSynced = false;
119476
119495
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
119477
119496
  try {
119478
119497
  const response = await fetch(endpoint, init);
119498
+ if (response.status === 401 && !authSynced && typeof globalThis.window !== "undefined") {
119499
+ authSynced = true;
119500
+ await syncBrowserAuthSession();
119501
+ options?.onRetry?.(attempt, "HTTP 401 (session sync)");
119502
+ await response.body?.cancel().catch(() => void 0);
119503
+ await waitForModelProxyRetry(attempt, init.signal);
119504
+ continue;
119505
+ }
119479
119506
  if (!isRetriableModelProxyStatus(response.status) || attempt === maxAttempts - 1) {
119480
119507
  return response;
119481
119508
  }
@@ -119609,6 +119636,7 @@ var init_modelRouter = __esm({
119609
119636
  init_modelRegistry();
119610
119637
  init_contextMeter();
119611
119638
  init_inferenceUsageRecorder();
119639
+ init_browserSession();
119612
119640
  init_roostUserSelectionClient();
119613
119641
  init_providerModelStep();
119614
119642
  init_toolCallNormalizer();
@@ -129014,10 +129042,10 @@ var require_dist4 = __commonJS({
129014
129042
  }
129015
129043
  return false;
129016
129044
  }
129017
- function getDefaultPropagationTargets2(supabaseUrl2) {
129045
+ function getDefaultPropagationTargets2(supabaseUrl) {
129018
129046
  const targets = [];
129019
129047
  try {
129020
- const url = new URL(supabaseUrl2);
129048
+ const url = new URL(supabaseUrl);
129021
129049
  targets.push(url.hostname);
129022
129050
  } catch (error) {
129023
129051
  }
@@ -129083,12 +129111,12 @@ var require_dist4 = __commonJS({
129083
129111
  var resolveHeadersConstructor2 = () => {
129084
129112
  return Headers;
129085
129113
  };
129086
- var fetchWithAuth2 = (supabaseKey, supabaseUrl2, getAccessToken, customFetch, tracePropagationOptions) => {
129114
+ var fetchWithAuth2 = (supabaseKey, supabaseUrl, getAccessToken, customFetch, tracePropagationOptions) => {
129087
129115
  const fetch$1 = resolveFetch3(customFetch);
129088
129116
  const HeadersConstructor = resolveHeadersConstructor2();
129089
129117
  const traceEnabled = (tracePropagationOptions === null || tracePropagationOptions === void 0 ? void 0 : tracePropagationOptions.enabled) === true;
129090
129118
  const respectSampling = (tracePropagationOptions === null || tracePropagationOptions === void 0 ? void 0 : tracePropagationOptions.respectSamplingDecision) !== false;
129091
- const traceTargets = traceEnabled ? getDefaultPropagationTargets2(supabaseUrl2) : null;
129119
+ const traceTargets = traceEnabled ? getDefaultPropagationTargets2(supabaseUrl) : null;
129092
129120
  return async (input, init) => {
129093
129121
  var _await$getAccessToken;
129094
129122
  const accessToken = (_await$getAccessToken = await getAccessToken()) !== null && _await$getAccessToken !== void 0 ? _await$getAccessToken : supabaseKey;
@@ -129144,8 +129172,8 @@ var require_dist4 = __commonJS({
129144
129172
  else delete result2.accessToken;
129145
129173
  return result2;
129146
129174
  }
129147
- function validateSupabaseUrl2(supabaseUrl2) {
129148
- const trimmedUrl = supabaseUrl2 === null || supabaseUrl2 === void 0 ? void 0 : supabaseUrl2.trim();
129175
+ function validateSupabaseUrl2(supabaseUrl) {
129176
+ const trimmedUrl = supabaseUrl === null || supabaseUrl === void 0 ? void 0 : supabaseUrl.trim();
129149
129177
  if (!trimmedUrl) throw new Error("supabaseUrl is required.");
129150
129178
  if (!trimmedUrl.match(/^https?:\/\//i)) throw new Error("Invalid supabaseUrl: Must be a valid HTTP or HTTPS URL.");
129151
129179
  try {
@@ -129347,11 +129375,11 @@ var require_dist4 = __commonJS({
129347
129375
  * const { data } = await supabase.from('profiles').select('*')
129348
129376
  * ```
129349
129377
  */
129350
- constructor(supabaseUrl2, supabaseKey, options) {
129378
+ constructor(supabaseUrl, supabaseKey, options) {
129351
129379
  var _settings$auth$storag, _settings$global$head;
129352
- this.supabaseUrl = supabaseUrl2;
129380
+ this.supabaseUrl = supabaseUrl;
129353
129381
  this.supabaseKey = supabaseKey;
129354
- const baseUrl = validateSupabaseUrl2(supabaseUrl2);
129382
+ const baseUrl = validateSupabaseUrl2(supabaseUrl);
129355
129383
  if (!supabaseKey) throw new Error("supabaseKey is required.");
129356
129384
  this.realtimeUrl = new URL("realtime/v1", baseUrl);
129357
129385
  this.realtimeUrl.protocol = this.realtimeUrl.protocol.replace("http", "ws");
@@ -129379,7 +129407,7 @@ var require_dist4 = __commonJS({
129379
129407
  throw new Error(`@supabase/supabase-js: Supabase Client is configured with the accessToken option, accessing supabase.auth.${String(prop)} is not possible`);
129380
129408
  } });
129381
129409
  }
129382
- this.fetch = fetchWithAuth2(supabaseKey, supabaseUrl2, this._getAccessToken.bind(this), settings.global.fetch, settings.tracePropagation);
129410
+ this.fetch = fetchWithAuth2(supabaseKey, supabaseUrl, this._getAccessToken.bind(this), settings.global.fetch, settings.tracePropagation);
129383
129411
  this.realtime = this._initRealtimeClient(_objectSpread24({
129384
129412
  headers: this.headers,
129385
129413
  accessToken: this._getAccessToken.bind(this),
@@ -129563,8 +129591,8 @@ var require_dist4 = __commonJS({
129563
129591
  }
129564
129592
  }
129565
129593
  };
129566
- var createClient3 = (supabaseUrl2, supabaseKey, options) => {
129567
- return new SupabaseClient2(supabaseUrl2, supabaseKey, options);
129594
+ var createClient3 = (supabaseUrl, supabaseKey, options) => {
129595
+ return new SupabaseClient2(supabaseUrl, supabaseKey, options);
129568
129596
  };
129569
129597
  function shouldShowDeprecationWarning2() {
129570
129598
  if (typeof window !== "undefined") return false;
@@ -130625,13 +130653,13 @@ var require_createBrowserClient = __commonJS({
130625
130653
  var cookies_1 = require_cookies();
130626
130654
  var warnDeprecatedPackage_1 = require_warnDeprecatedPackage();
130627
130655
  var cachedBrowserClient;
130628
- function createBrowserClient2(supabaseUrl2, supabaseKey, options) {
130656
+ function createBrowserClient2(supabaseUrl, supabaseKey, options) {
130629
130657
  (0, warnDeprecatedPackage_1.warnIfUsingDeprecatedAuthHelpersPackage)();
130630
130658
  const shouldUseSingleton = options?.isSingleton === true || (!options || !("isSingleton" in options)) && (0, utils_1.isBrowser)();
130631
130659
  if (shouldUseSingleton && cachedBrowserClient) {
130632
130660
  return cachedBrowserClient;
130633
130661
  }
130634
- if (!supabaseUrl2 || !supabaseKey) {
130662
+ if (!supabaseUrl || !supabaseKey) {
130635
130663
  throw new Error(`@supabase/ssr: Your project's URL and API key are required to create a Supabase client!
130636
130664
 
130637
130665
  Check your Supabase project's API settings to find these values
@@ -130642,7 +130670,7 @@ https://supabase.com/dashboard/project/_/settings/api`);
130642
130670
  ...options,
130643
130671
  cookieEncoding: options?.cookieEncoding ?? "base64url"
130644
130672
  }, false);
130645
- const client = (0, supabase_js_1.createClient)(supabaseUrl2, supabaseKey, {
130673
+ const client = (0, supabase_js_1.createClient)(supabaseUrl, supabaseKey, {
130646
130674
  // TODO: resolve type error
130647
130675
  ...options,
130648
130676
  global: {
@@ -130678,15 +130706,15 @@ var require_createServerClient = __commonJS({
130678
130706
  "node_modules/@supabase/ssr/dist/main/createServerClient.js"(exports2) {
130679
130707
  "use strict";
130680
130708
  Object.defineProperty(exports2, "__esModule", { value: true });
130681
- exports2.createServerClient = createServerClient2;
130709
+ exports2.createServerClient = createServerClient;
130682
130710
  var supabase_js_1 = require_dist4();
130683
130711
  var version_1 = require_version3();
130684
130712
  var cookies_1 = require_cookies();
130685
130713
  var helpers_1 = require_helpers2();
130686
130714
  var warnDeprecatedPackage_1 = require_warnDeprecatedPackage();
130687
- function createServerClient2(supabaseUrl2, supabaseKey, options) {
130715
+ function createServerClient(supabaseUrl, supabaseKey, options) {
130688
130716
  (0, warnDeprecatedPackage_1.warnIfUsingDeprecatedAuthHelpersPackage)();
130689
- if (!supabaseUrl2 || !supabaseKey) {
130717
+ if (!supabaseUrl || !supabaseKey) {
130690
130718
  throw new Error(`Your project's URL and Key are required to create a Supabase client!
130691
130719
 
130692
130720
  Check your Supabase project's API settings to find these values
@@ -130697,7 +130725,7 @@ https://supabase.com/dashboard/project/_/settings/api`);
130697
130725
  ...options,
130698
130726
  cookieEncoding: options?.cookieEncoding ?? "base64url"
130699
130727
  }, true);
130700
- const client = (0, supabase_js_1.createClient)(supabaseUrl2, supabaseKey, {
130728
+ const client = (0, supabase_js_1.createClient)(supabaseUrl, supabaseKey, {
130701
130729
  // TODO: resolve type error
130702
130730
  ...options,
130703
130731
  global: {
@@ -130776,36 +130804,6 @@ var require_main4 = __commonJS({
130776
130804
  }
130777
130805
  });
130778
130806
 
130779
- // lib/supabase/factory.ts
130780
- function supabaseUrl() {
130781
- return process.env.NEXT_PUBLIC_SUPABASE_URL;
130782
- }
130783
- function supabaseAnonKey() {
130784
- return process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
130785
- }
130786
- function authCookieOptions() {
130787
- const secure = process.env.NODE_ENV === "production";
130788
- return {
130789
- cookieOptions: {
130790
- path: "/",
130791
- sameSite: "lax",
130792
- ...secure ? { secure: true } : {}
130793
- }
130794
- };
130795
- }
130796
- function createBrowserSupabaseClient() {
130797
- return (0, import_ssr.createBrowserClient)(supabaseUrl(), supabaseAnonKey(), {
130798
- isSingleton: true,
130799
- ...authCookieOptions()
130800
- });
130801
- }
130802
- var import_ssr;
130803
- var init_factory = __esm({
130804
- "lib/supabase/factory.ts"() {
130805
- import_ssr = __toESM(require_main4());
130806
- }
130807
- });
130808
-
130809
130807
  // lib/supabase/client.ts
130810
130808
  function createClient2() {
130811
130809
  if (!isSupabaseConfigured()) {
@@ -130814,15 +130812,19 @@ function createClient2() {
130814
130812
  );
130815
130813
  }
130816
130814
  if (!browserClient) {
130817
- browserClient = createBrowserSupabaseClient();
130815
+ browserClient = (0, import_ssr.createBrowserClient)(
130816
+ process.env.NEXT_PUBLIC_SUPABASE_URL,
130817
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
130818
+ { isSingleton: true }
130819
+ );
130818
130820
  }
130819
130821
  return browserClient;
130820
130822
  }
130821
- var browserClient;
130823
+ var import_ssr, browserClient;
130822
130824
  var init_client = __esm({
130823
130825
  "lib/supabase/client.ts"() {
130826
+ import_ssr = __toESM(require_main4());
130824
130827
  init_config();
130825
- init_factory();
130826
130828
  }
130827
130829
  });
130828
130830
 
@@ -223673,6 +223675,12 @@ var init_usageCommand = __esm({
223673
223675
  }
223674
223676
  });
223675
223677
 
223678
+ // lib/perch-ai/entitlements.ts
223679
+ var init_entitlements = __esm({
223680
+ "lib/perch-ai/entitlements.ts"() {
223681
+ }
223682
+ });
223683
+
223676
223684
  // lib/perch-ai/access.ts
223677
223685
  function hasPrivilegedPerchAiRole(memberships) {
223678
223686
  return memberships.some(
@@ -223690,6 +223698,7 @@ function canShowPerchDevTools(membershipRole) {
223690
223698
  }
223691
223699
  var init_access = __esm({
223692
223700
  "lib/perch-ai/access.ts"() {
223701
+ init_entitlements();
223693
223702
  }
223694
223703
  });
223695
223704
 
@@ -234040,111 +234049,6 @@ var init_cliAuthSession = __esm({
234040
234049
  }
234041
234050
  });
234042
234051
 
234043
- // features/perchTerminal/runtime/cliHost/modelConnection.ts
234044
- async function connectCliModelProxy(input = {}) {
234045
- const storedSession = input.storedSession === void 0 ? await readStoredCliAuthSession() : input.storedSession;
234046
- const usableStoredSession = isStoredCliAuthSessionUsable(storedSession) ? storedSession : null;
234047
- const appUrl = resolveCliAppUrl(input.appUrl, usableStoredSession?.appUrl ?? null);
234048
- if (!appUrl) return noCliModelConnection();
234049
- if (!usableStoredSession?.accessToken) return noCliModelConnection(appUrl);
234050
- const fetchImpl = input.fetchImpl ?? globalThis.fetch;
234051
- if (typeof fetchImpl !== "function") return noCliModelConnection(appUrl);
234052
- const selection = await fetchPublicModelDefaultSelection(
234053
- appUrl,
234054
- fetchImpl,
234055
- usableStoredSession?.accessToken ?? null
234056
- );
234057
- if (!selection) return noCliModelConnection(appUrl);
234058
- const priorProxy = process.env[MODEL_PROXY_ENV];
234059
- const priorToken = process.env[MODEL_PROXY_TOKEN_ENV];
234060
- process.env[MODEL_PROXY_ENV] = appUrl;
234061
- if (usableStoredSession?.accessToken) {
234062
- process.env[MODEL_PROXY_TOKEN_ENV] = usableStoredSession.accessToken;
234063
- }
234064
- return {
234065
- appUrl,
234066
- authenticated: !!usableStoredSession?.accessToken,
234067
- userId: usableStoredSession?.userId ?? null,
234068
- email: usableStoredSession?.email ?? null,
234069
- founderModelSelection: selection,
234070
- restore: () => {
234071
- if (priorProxy === void 0) {
234072
- delete process.env[MODEL_PROXY_ENV];
234073
- } else {
234074
- process.env[MODEL_PROXY_ENV] = priorProxy;
234075
- }
234076
- if (priorToken === void 0) {
234077
- delete process.env[MODEL_PROXY_TOKEN_ENV];
234078
- } else {
234079
- process.env[MODEL_PROXY_TOKEN_ENV] = priorToken;
234080
- }
234081
- }
234082
- };
234083
- }
234084
- function resolveCliAppUrl(explicit, stored) {
234085
- const raw = explicit?.trim() || process.env[CLI_APP_URL_ENV]?.trim() || process.env[FALLBACK_APP_URL_ENV]?.trim() || stored?.trim() || DEFAULT_CLI_APP_URL;
234086
- if (!raw) return null;
234087
- const withProtocol = /^https?:\/\//i.test(raw) ? raw : `http://${raw}`;
234088
- try {
234089
- const url = new URL(withProtocol);
234090
- url.pathname = url.pathname.replace(/\/+$/, "");
234091
- url.search = "";
234092
- url.hash = "";
234093
- return url.toString().replace(/\/+$/, "");
234094
- } catch {
234095
- return null;
234096
- }
234097
- }
234098
- async function fetchPublicModelDefaultSelection(appUrl, fetchImpl, accessToken) {
234099
- const url = `${appUrl}/api/perch-terminal/public-model-default`;
234100
- const controller = new AbortController();
234101
- const timeout = setTimeout(() => controller.abort(), 3500);
234102
- try {
234103
- const response = await fetchImpl(url, {
234104
- method: "GET",
234105
- headers: {
234106
- Accept: "application/json",
234107
- ...accessToken ? { Authorization: `Bearer ${accessToken}` } : {}
234108
- },
234109
- signal: controller.signal
234110
- });
234111
- if (!response.ok) return null;
234112
- const body = await response.json();
234113
- if (!body || typeof body !== "object") return null;
234114
- const record = body;
234115
- if (record.ok !== true) return null;
234116
- return parsePublicModelDefaultPayload({ selection: record.selection }).selection;
234117
- } catch {
234118
- return null;
234119
- } finally {
234120
- clearTimeout(timeout);
234121
- }
234122
- }
234123
- function noCliModelConnection(appUrl = null) {
234124
- return {
234125
- appUrl,
234126
- authenticated: false,
234127
- userId: null,
234128
- email: null,
234129
- founderModelSelection: null,
234130
- restore: () => {
234131
- }
234132
- };
234133
- }
234134
- var MODEL_PROXY_ENV, MODEL_PROXY_TOKEN_ENV, CLI_APP_URL_ENV, FALLBACK_APP_URL_ENV, DEFAULT_CLI_APP_URL;
234135
- var init_modelConnection = __esm({
234136
- "features/perchTerminal/runtime/cliHost/modelConnection.ts"() {
234137
- "use strict";
234138
- init_publicModelDefault();
234139
- init_cliAuthSession();
234140
- MODEL_PROXY_ENV = "PERCH_MODEL_CALL_PROXY_URL";
234141
- MODEL_PROXY_TOKEN_ENV = "PERCH_MODEL_CALL_PROXY_TOKEN";
234142
- CLI_APP_URL_ENV = "PERCH_CLI_APP_URL";
234143
- FALLBACK_APP_URL_ENV = "PERCH_APP_URL";
234144
- DEFAULT_CLI_APP_URL = "https://app.perchai.app";
234145
- }
234146
- });
234147
-
234148
234052
  // features/perchTerminal/runtime/cliHost/cliStandaloneOAuth.ts
234149
234053
  import { execFile as execFile2 } from "node:child_process";
234150
234054
  import http from "node:http";
@@ -234353,6 +234257,166 @@ var init_cliStandaloneOAuth = __esm({
234353
234257
  }
234354
234258
  });
234355
234259
 
234260
+ // features/perchTerminal/runtime/cliHost/cliAuthRefresh.ts
234261
+ async function ensureFreshCliAuthSession(input) {
234262
+ const session = input.session;
234263
+ if (!session?.accessToken?.trim()) return null;
234264
+ const nowSeconds = Math.floor(Date.now() / 1e3);
234265
+ const stillUsable = !session.expiresAt || session.expiresAt > nowSeconds + 90;
234266
+ if (stillUsable) return session;
234267
+ if (!session.refreshToken?.trim()) return null;
234268
+ const fetchImpl = input.fetchImpl ?? globalThis.fetch;
234269
+ if (typeof fetchImpl !== "function") return null;
234270
+ const appUrl = session.appUrl?.trim();
234271
+ if (!appUrl) return null;
234272
+ const config = await fetchCliAuthConfig(appUrl, fetchImpl).catch(() => ({ ok: false }));
234273
+ if (!config.ok || !config.supabaseUrl || !config.supabaseAnonKey) return null;
234274
+ const supabase = createClient(config.supabaseUrl, config.supabaseAnonKey, {
234275
+ auth: {
234276
+ autoRefreshToken: false,
234277
+ detectSessionInUrl: false,
234278
+ persistSession: false
234279
+ }
234280
+ });
234281
+ try {
234282
+ const { data, error } = await supabase.auth.refreshSession({
234283
+ refresh_token: session.refreshToken
234284
+ });
234285
+ if (error || !data.session) return null;
234286
+ const refreshed = {
234287
+ version: 1,
234288
+ appUrl: session.appUrl,
234289
+ accessToken: data.session.access_token,
234290
+ refreshToken: data.session.refresh_token ?? session.refreshToken,
234291
+ expiresAt: data.session.expires_at ?? null,
234292
+ userId: data.session.user?.id ?? session.userId ?? null,
234293
+ email: data.session.user?.email ?? session.email ?? null,
234294
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
234295
+ };
234296
+ await writeStoredCliAuthSession(refreshed);
234297
+ return refreshed;
234298
+ } catch {
234299
+ return null;
234300
+ }
234301
+ }
234302
+ var init_cliAuthRefresh = __esm({
234303
+ "features/perchTerminal/runtime/cliHost/cliAuthRefresh.ts"() {
234304
+ "use strict";
234305
+ init_dist4();
234306
+ init_cliStandaloneOAuth();
234307
+ init_cliAuthSession();
234308
+ }
234309
+ });
234310
+
234311
+ // features/perchTerminal/runtime/cliHost/modelConnection.ts
234312
+ async function connectCliModelProxy(input = {}) {
234313
+ const storedSession = input.storedSession === void 0 ? await readStoredCliAuthSession() : input.storedSession;
234314
+ const usableStoredSession = await ensureFreshCliAuthSession({
234315
+ session: storedSession,
234316
+ fetchImpl: input.fetchImpl
234317
+ });
234318
+ const appUrl = resolveCliAppUrl(input.appUrl, usableStoredSession?.appUrl ?? null);
234319
+ if (!appUrl) return noCliModelConnection();
234320
+ if (!usableStoredSession?.accessToken) return noCliModelConnection(appUrl);
234321
+ const fetchImpl = input.fetchImpl ?? globalThis.fetch;
234322
+ if (typeof fetchImpl !== "function") return noCliModelConnection(appUrl);
234323
+ const selection = await fetchPublicModelDefaultSelection(
234324
+ appUrl,
234325
+ fetchImpl,
234326
+ usableStoredSession?.accessToken ?? null
234327
+ );
234328
+ if (!selection) return noCliModelConnection(appUrl);
234329
+ const priorProxy = process.env[MODEL_PROXY_ENV];
234330
+ const priorToken = process.env[MODEL_PROXY_TOKEN_ENV];
234331
+ process.env[MODEL_PROXY_ENV] = appUrl;
234332
+ if (usableStoredSession?.accessToken) {
234333
+ process.env[MODEL_PROXY_TOKEN_ENV] = usableStoredSession.accessToken;
234334
+ }
234335
+ return {
234336
+ appUrl,
234337
+ authenticated: !!usableStoredSession?.accessToken,
234338
+ userId: usableStoredSession?.userId ?? null,
234339
+ email: usableStoredSession?.email ?? null,
234340
+ founderModelSelection: selection,
234341
+ restore: () => {
234342
+ if (priorProxy === void 0) {
234343
+ delete process.env[MODEL_PROXY_ENV];
234344
+ } else {
234345
+ process.env[MODEL_PROXY_ENV] = priorProxy;
234346
+ }
234347
+ if (priorToken === void 0) {
234348
+ delete process.env[MODEL_PROXY_TOKEN_ENV];
234349
+ } else {
234350
+ process.env[MODEL_PROXY_TOKEN_ENV] = priorToken;
234351
+ }
234352
+ }
234353
+ };
234354
+ }
234355
+ function resolveCliAppUrl(explicit, stored) {
234356
+ const raw = explicit?.trim() || process.env[CLI_APP_URL_ENV]?.trim() || process.env[FALLBACK_APP_URL_ENV]?.trim() || stored?.trim() || DEFAULT_CLI_APP_URL;
234357
+ if (!raw) return null;
234358
+ const withProtocol = /^https?:\/\//i.test(raw) ? raw : `http://${raw}`;
234359
+ try {
234360
+ const url = new URL(withProtocol);
234361
+ url.pathname = url.pathname.replace(/\/+$/, "");
234362
+ url.search = "";
234363
+ url.hash = "";
234364
+ return url.toString().replace(/\/+$/, "");
234365
+ } catch {
234366
+ return null;
234367
+ }
234368
+ }
234369
+ async function fetchPublicModelDefaultSelection(appUrl, fetchImpl, accessToken) {
234370
+ const url = `${appUrl}/api/perch-terminal/public-model-default`;
234371
+ const controller = new AbortController();
234372
+ const timeout = setTimeout(() => controller.abort(), 3500);
234373
+ try {
234374
+ const response = await fetchImpl(url, {
234375
+ method: "GET",
234376
+ headers: {
234377
+ Accept: "application/json",
234378
+ ...accessToken ? { Authorization: `Bearer ${accessToken}` } : {}
234379
+ },
234380
+ signal: controller.signal
234381
+ });
234382
+ if (!response.ok) return null;
234383
+ const body = await response.json();
234384
+ if (!body || typeof body !== "object") return null;
234385
+ const record = body;
234386
+ if (record.ok !== true) return null;
234387
+ return parsePublicModelDefaultPayload({ selection: record.selection }).selection;
234388
+ } catch {
234389
+ return null;
234390
+ } finally {
234391
+ clearTimeout(timeout);
234392
+ }
234393
+ }
234394
+ function noCliModelConnection(appUrl = null) {
234395
+ return {
234396
+ appUrl,
234397
+ authenticated: false,
234398
+ userId: null,
234399
+ email: null,
234400
+ founderModelSelection: null,
234401
+ restore: () => {
234402
+ }
234403
+ };
234404
+ }
234405
+ var MODEL_PROXY_ENV, MODEL_PROXY_TOKEN_ENV, CLI_APP_URL_ENV, FALLBACK_APP_URL_ENV, DEFAULT_CLI_APP_URL;
234406
+ var init_modelConnection = __esm({
234407
+ "features/perchTerminal/runtime/cliHost/modelConnection.ts"() {
234408
+ "use strict";
234409
+ init_publicModelDefault();
234410
+ init_cliAuthSession();
234411
+ init_cliAuthRefresh();
234412
+ MODEL_PROXY_ENV = "PERCH_MODEL_CALL_PROXY_URL";
234413
+ MODEL_PROXY_TOKEN_ENV = "PERCH_MODEL_CALL_PROXY_TOKEN";
234414
+ CLI_APP_URL_ENV = "PERCH_CLI_APP_URL";
234415
+ FALLBACK_APP_URL_ENV = "PERCH_APP_URL";
234416
+ DEFAULT_CLI_APP_URL = "https://app.perchai.app";
234417
+ }
234418
+ });
234419
+
234356
234420
  // lib/perchTerminal/statusLabels.ts
234357
234421
  function sectionLabel(sectionKey) {
234358
234422
  if (STATUS_LABELS[sectionKey]) return STATUS_LABELS[sectionKey];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perchai-cli",
3
- "version": "2.4.47",
3
+ "version": "2.4.48",
4
4
  "description": "Perch AI command-line interface",
5
5
  "bin": {
6
6
  "perch": "bin/perch"