@adminide-stack/yantra-mobile 12.0.39-alpha.1 → 12.0.39-alpha.2

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.
@@ -108,7 +108,7 @@ async function mintSurfaceSystemToken(input) {
108
108
  environmentTagId,
109
109
  orgName,
110
110
  projectId,
111
- algorithm: "RS256"
111
+ algorithm: "HS256"
112
112
  }
113
113
  });
114
114
  const createErr = ((_n = (_m = createResult.errors) == null ? void 0 : _m[0]) == null ? void 0 : _n.message) || "";
@@ -1 +1 @@
1
- {"version":3,"file":"mintSurfaceSystemToken.js","sources":["../../src/hooks/mintSurfaceSystemToken.ts"],"sourcesContent":["import { readAuth0IdToken } from '../bridge/readAuth0Session';\nimport { config } from '../config/env-config';\n\nconst OBTAIN_USER_SYSTEM_TOKEN = `\n mutation ObtainUserSystemToken($input: ObtainUserSystemTokenInput!) {\n obtainUserSystemToken(input: $input) {\n token\n }\n }\n`;\n\nconst GET_USER_SYSTEM_TOKEN = `\n query GetUserSystemToken {\n getUserSystemToken {\n id\n expiresAt\n isSystemToken\n }\n }\n`;\n\nconst CREATE_SECRET_API_TOKEN = `\n mutation CreateSecretApiToken($input: SecretApiTokenInput!) {\n createSecretApiToken(input: $input) {\n id\n expiresAt\n }\n }\n`;\n\nconst REVEAL_SECRET_API_TOKEN = `\n mutation RevealSecretApiToken($id: ID!) {\n revealSecretApiToken(id: $id)\n }\n`;\n\ntype GqlResult<T> = {\n data?: T;\n errors?: Array<{ message?: string }>;\n};\n\nfunction normalizeGraphqlUrl(url: string): string {\n return url.trim().replace(/\\/$/, '');\n}\n\n/** App GRAPHQL_URL from env (optional override for device LAN rewrite). */\nexport function resolveSurfaceCatalogBackend(graphqlUrl?: string): string {\n const raw = graphqlUrl?.trim() || config.GRAPHQL_URL;\n if (!raw?.trim()) {\n throw new Error('GRAPHQL_URL is not configured');\n }\n return normalizeGraphqlUrl(raw);\n}\n\nasync function gqlFetch<T>(\n graphqlUrl: string,\n idToken: string,\n query: string,\n variables?: Record<string, unknown>,\n): Promise<GqlResult<T>> {\n const res = await fetch(graphqlUrl, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${idToken}`,\n },\n body: JSON.stringify({ query, variables }),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`GraphQL HTTP ${res.status}: ${text.slice(0, 200)}`);\n }\n return (await res.json()) as GqlResult<T>;\n}\n\nexport type MintSurfaceTokenInput = {\n /** App GRAPHQL_URL (e.g. device-rewritten). Defaults to env GRAPHQL_URL. */\n graphqlUrl?: string;\n orgName?: string | null;\n projectId?: string | null;\n tagId?: string | null;\n};\n\nexport type MintSurfaceTokenResult = {\n token: string;\n /** Exact backend URL string to stamp into cdecli_token_meta. */\n backend: string;\n};\n\n/**\n * Reveal (or obtain) a system token on GRAPHQL_URL.\n */\nexport async function mintSurfaceSystemToken(input: MintSurfaceTokenInput): Promise<MintSurfaceTokenResult> {\n const idToken = await readAuth0IdToken();\n if (!idToken) {\n throw new Error('No Auth0 id_token in storage — sign in to the mobile app first.');\n }\n\n const graphqlUrl = resolveSurfaceCatalogBackend(input.graphqlUrl);\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] minting system token via', graphqlUrl);\n }\n\n const orgName = input.orgName?.trim() || 'default';\n const projectId = input.projectId?.trim() || 'default';\n const environmentTagId = input.tagId?.trim() || undefined;\n\n if (environmentTagId) {\n try {\n const obtained = await gqlFetch<{ obtainUserSystemToken?: { token?: string } | null }>(\n graphqlUrl,\n idToken,\n OBTAIN_USER_SYSTEM_TOKEN,\n {\n input: {\n projectId,\n environmentTagId,\n orgName,\n renewBufferSeconds: 7 * 24 * 60 * 60,\n },\n },\n );\n const token = obtained.data?.obtainUserSystemToken?.token?.trim();\n if (token && !obtained.errors?.length) {\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] obtained system token length=', token.length);\n }\n return { token, backend: graphqlUrl };\n }\n } catch (err) {\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.warn('[WebBuilder] obtainUserSystemToken failed, falling back to reveal:', err);\n }\n }\n }\n\n const getResult = await gqlFetch<{ getUserSystemToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n GET_USER_SYSTEM_TOKEN,\n );\n if (getResult.errors?.length) {\n throw new Error(getResult.errors[0]?.message || 'GetUserSystemToken failed');\n }\n\n let tokenId = getResult.data?.getUserSystemToken?.id ?? null;\n\n if (!tokenId) {\n const createResult = await gqlFetch<{ createSecretApiToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n CREATE_SECRET_API_TOKEN,\n {\n input: {\n name: 'System Token',\n expiryInSeconds: 31536000,\n isSystemToken: true,\n environmentTagId,\n orgName,\n projectId,\n algorithm: 'RS256',\n },\n },\n );\n\n const createErr = createResult.errors?.[0]?.message || '';\n if (createErr && !/already have a system token/i.test(createErr)) {\n throw new Error(createErr);\n }\n\n if (createResult.data?.createSecretApiToken?.id) {\n tokenId = createResult.data.createSecretApiToken.id;\n } else {\n const refetch = await gqlFetch<{ getUserSystemToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n GET_USER_SYSTEM_TOKEN,\n );\n tokenId = refetch.data?.getUserSystemToken?.id ?? null;\n }\n }\n\n if (!tokenId) {\n throw new Error('No system token id on GraphQL backend — cannot reveal.');\n }\n\n const reveal = await gqlFetch<{ revealSecretApiToken?: string | null }>(\n graphqlUrl,\n idToken,\n REVEAL_SECRET_API_TOKEN,\n { id: tokenId },\n );\n if (reveal.errors?.length) {\n throw new Error(reveal.errors[0]?.message || 'RevealSecretApiToken failed');\n }\n\n const token = reveal.data?.revealSecretApiToken?.trim();\n if (!token) {\n throw new Error('RevealSecretApiToken returned empty token');\n }\n\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] minted system token length=', token.length);\n }\n return { token, backend: graphqlUrl };\n}\n\nexport function appendSurfaceAuthParams(baseUrl: string, token: string, state: string): string {\n try {\n const url = new URL(baseUrl);\n url.searchParams.set('token', token);\n url.searchParams.set('code', token);\n url.searchParams.set('state', state);\n return url.toString();\n } catch {\n const sep = baseUrl.includes('?') ? '&' : '?';\n return `${baseUrl}${sep}token=${encodeURIComponent(token)}&code=${encodeURIComponent(token)}&state=${encodeURIComponent(state)}`;\n }\n}\n\nfunction tokenFingerprint(token: string): string {\n const sig = token.split('.')[2] ?? token;\n return sig.slice(-24);\n}\n\n/** Shared WebView boot script: token + meta + fetch shims for surface-kit auth. */\nfunction buildSurfaceHandoffScript(token: string, backend: string, state: string, withGateRecovery: boolean): string {\n const safeToken = JSON.stringify(token);\n const safeBackend = JSON.stringify(backend);\n const safeState = JSON.stringify(state);\n const fp = JSON.stringify(tokenFingerprint(token));\n const recovery = withGateRecovery\n ? `\n function tryRecover() {\n stamp();\n var gate = document.querySelector('[data-surface-login]');\n if (!gate) return;\n if (sessionStorage.getItem('__yantra_wb_token_reload')) return;\n sessionStorage.setItem('__yantra_wb_token_reload', '1');\n var u = new URL(window.location.href);\n u.searchParams.set('token', t);\n u.searchParams.set('code', t);\n u.searchParams.set('state', state);\n window.location.replace(u.toString());\n }\n tryRecover();\n var i = 0;\n var timer = setInterval(function () {\n i += 1;\n tryRecover();\n if (i >= 40 || !document.querySelector('[data-surface-login]')) clearInterval(timer);\n }, 250);\n`\n : `\n var n = 0;\n var id = setInterval(function () {\n stamp();\n n += 1;\n if (n >= 80) clearInterval(id);\n }, 50);\n`;\n\n return `\n(function () {\n try {\n var t = ${safeToken};\n var backend = ${safeBackend};\n var state = ${safeState};\n var fp = ${fp};\n var PROBE_Q = 'query { getUserAccount { id } }';\n\n if (!window.__yantraWbFetchPatched) {\n window.__yantraWbFetchPatched = true;\n var origFetch = window.fetch.bind(window);\n window.fetch = function (input, init) {\n try {\n var url = typeof input === 'string' ? input : (input && input.url) ? String(input.url) : '';\n // Force surface-kit resolveCatalogBackend() to our GRAPHQL_URL (not remote agent → ideback).\n if (url.indexOf('/v1/auth/context') !== -1) {\n return Promise.resolve(new Response(\n JSON.stringify({ backendGraphqlUrl: backend }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n ));\n }\n var body = init && typeof init.body === 'string' ? init.body : '';\n if (body && body.indexOf('getUserAccount') !== -1) {\n var parsed = JSON.parse(body);\n var q = parsed && typeof parsed.query === 'string' ? parsed.query.replace(/\\\\s+/g, ' ').trim() : '';\n if (q === PROBE_Q) {\n return Promise.resolve(new Response(\n JSON.stringify({ data: { getUserAccount: { id: 'mobile-webview-handoff' } } }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n ));\n }\n }\n } catch (e0) {}\n return origFetch(input, init);\n };\n }\n\n function stamp() {\n try {\n sessionStorage.setItem('cdecli_oauth_state', state);\n localStorage.setItem('cdecli_token', t);\n sessionStorage.setItem('cdecli_token', t);\n localStorage.setItem('cdecli_system_token', t);\n localStorage.setItem('cdecli_token_meta', JSON.stringify({\n backend: backend,\n verifiedAt: Date.now(),\n fp: fp\n }));\n } catch (e1) {}\n }\n stamp();\n ${recovery}\n } catch (e) {}\n true;\n})();\ntrue;\n`;\n}\n\nexport function buildCdecliTokenInjection(token: string, backend: string, state: string): string {\n return buildSurfaceHandoffScript(token, backend, state, false);\n}\n\nexport function buildSurfaceGateRecoveryScript(token: string, backend: string, state: string): string {\n return buildSurfaceHandoffScript(token, backend, state, true);\n}\n"],"names":["token"],"mappings":"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"}
1
+ {"version":3,"file":"mintSurfaceSystemToken.js","sources":["../../src/hooks/mintSurfaceSystemToken.ts"],"sourcesContent":["import { readAuth0IdToken } from '../bridge/readAuth0Session';\nimport { config } from '../config/env-config';\n\nconst OBTAIN_USER_SYSTEM_TOKEN = `\n mutation ObtainUserSystemToken($input: ObtainUserSystemTokenInput!) {\n obtainUserSystemToken(input: $input) {\n token\n }\n }\n`;\n\nconst GET_USER_SYSTEM_TOKEN = `\n query GetUserSystemToken {\n getUserSystemToken {\n id\n expiresAt\n isSystemToken\n }\n }\n`;\n\nconst CREATE_SECRET_API_TOKEN = `\n mutation CreateSecretApiToken($input: SecretApiTokenInput!) {\n createSecretApiToken(input: $input) {\n id\n expiresAt\n }\n }\n`;\n\nconst REVEAL_SECRET_API_TOKEN = `\n mutation RevealSecretApiToken($id: ID!) {\n revealSecretApiToken(id: $id)\n }\n`;\n\ntype GqlResult<T> = {\n data?: T;\n errors?: Array<{ message?: string }>;\n};\n\nfunction normalizeGraphqlUrl(url: string): string {\n return url.trim().replace(/\\/$/, '');\n}\n\n/** App GRAPHQL_URL from env (optional override for device LAN rewrite). */\nexport function resolveSurfaceCatalogBackend(graphqlUrl?: string): string {\n const raw = graphqlUrl?.trim() || config.GRAPHQL_URL;\n if (!raw?.trim()) {\n throw new Error('GRAPHQL_URL is not configured');\n }\n return normalizeGraphqlUrl(raw);\n}\n\nasync function gqlFetch<T>(\n graphqlUrl: string,\n idToken: string,\n query: string,\n variables?: Record<string, unknown>,\n): Promise<GqlResult<T>> {\n const res = await fetch(graphqlUrl, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${idToken}`,\n },\n body: JSON.stringify({ query, variables }),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`GraphQL HTTP ${res.status}: ${text.slice(0, 200)}`);\n }\n return (await res.json()) as GqlResult<T>;\n}\n\nexport type MintSurfaceTokenInput = {\n /** App GRAPHQL_URL (e.g. device-rewritten). Defaults to env GRAPHQL_URL. */\n graphqlUrl?: string;\n orgName?: string | null;\n projectId?: string | null;\n tagId?: string | null;\n};\n\nexport type MintSurfaceTokenResult = {\n token: string;\n /** Exact backend URL string to stamp into cdecli_token_meta. */\n backend: string;\n};\n\n/**\n * Reveal (or obtain) a system token on GRAPHQL_URL.\n */\nexport async function mintSurfaceSystemToken(input: MintSurfaceTokenInput): Promise<MintSurfaceTokenResult> {\n const idToken = await readAuth0IdToken();\n if (!idToken) {\n throw new Error('No Auth0 id_token in storage — sign in to the mobile app first.');\n }\n\n const graphqlUrl = resolveSurfaceCatalogBackend(input.graphqlUrl);\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] minting system token via', graphqlUrl);\n }\n\n const orgName = input.orgName?.trim() || 'default';\n const projectId = input.projectId?.trim() || 'default';\n const environmentTagId = input.tagId?.trim() || undefined;\n\n if (environmentTagId) {\n try {\n const obtained = await gqlFetch<{ obtainUserSystemToken?: { token?: string } | null }>(\n graphqlUrl,\n idToken,\n OBTAIN_USER_SYSTEM_TOKEN,\n {\n input: {\n projectId,\n environmentTagId,\n orgName,\n renewBufferSeconds: 7 * 24 * 60 * 60,\n },\n },\n );\n const token = obtained.data?.obtainUserSystemToken?.token?.trim();\n if (token && !obtained.errors?.length) {\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] obtained system token length=', token.length);\n }\n return { token, backend: graphqlUrl };\n }\n } catch (err) {\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.warn('[WebBuilder] obtainUserSystemToken failed, falling back to reveal:', err);\n }\n }\n }\n\n const getResult = await gqlFetch<{ getUserSystemToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n GET_USER_SYSTEM_TOKEN,\n );\n if (getResult.errors?.length) {\n throw new Error(getResult.errors[0]?.message || 'GetUserSystemToken failed');\n }\n\n let tokenId = getResult.data?.getUserSystemToken?.id ?? null;\n\n if (!tokenId) {\n const createResult = await gqlFetch<{ createSecretApiToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n CREATE_SECRET_API_TOKEN,\n {\n input: {\n name: 'System Token',\n expiryInSeconds: 31536000,\n isSystemToken: true,\n environmentTagId,\n orgName,\n projectId,\n algorithm: 'HS256',\n },\n },\n );\n\n const createErr = createResult.errors?.[0]?.message || '';\n if (createErr && !/already have a system token/i.test(createErr)) {\n throw new Error(createErr);\n }\n\n if (createResult.data?.createSecretApiToken?.id) {\n tokenId = createResult.data.createSecretApiToken.id;\n } else {\n const refetch = await gqlFetch<{ getUserSystemToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n GET_USER_SYSTEM_TOKEN,\n );\n tokenId = refetch.data?.getUserSystemToken?.id ?? null;\n }\n }\n\n if (!tokenId) {\n throw new Error('No system token id on GraphQL backend — cannot reveal.');\n }\n\n const reveal = await gqlFetch<{ revealSecretApiToken?: string | null }>(\n graphqlUrl,\n idToken,\n REVEAL_SECRET_API_TOKEN,\n { id: tokenId },\n );\n if (reveal.errors?.length) {\n throw new Error(reveal.errors[0]?.message || 'RevealSecretApiToken failed');\n }\n\n const token = reveal.data?.revealSecretApiToken?.trim();\n if (!token) {\n throw new Error('RevealSecretApiToken returned empty token');\n }\n\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] minted system token length=', token.length);\n }\n return { token, backend: graphqlUrl };\n}\n\nexport function appendSurfaceAuthParams(baseUrl: string, token: string, state: string): string {\n try {\n const url = new URL(baseUrl);\n url.searchParams.set('token', token);\n url.searchParams.set('code', token);\n url.searchParams.set('state', state);\n return url.toString();\n } catch {\n const sep = baseUrl.includes('?') ? '&' : '?';\n return `${baseUrl}${sep}token=${encodeURIComponent(token)}&code=${encodeURIComponent(token)}&state=${encodeURIComponent(state)}`;\n }\n}\n\nfunction tokenFingerprint(token: string): string {\n const sig = token.split('.')[2] ?? token;\n return sig.slice(-24);\n}\n\n/** Shared WebView boot script: token + meta + fetch shims for surface-kit auth. */\nfunction buildSurfaceHandoffScript(token: string, backend: string, state: string, withGateRecovery: boolean): string {\n const safeToken = JSON.stringify(token);\n const safeBackend = JSON.stringify(backend);\n const safeState = JSON.stringify(state);\n const fp = JSON.stringify(tokenFingerprint(token));\n const recovery = withGateRecovery\n ? `\n function tryRecover() {\n stamp();\n var gate = document.querySelector('[data-surface-login]');\n if (!gate) return;\n if (sessionStorage.getItem('__yantra_wb_token_reload')) return;\n sessionStorage.setItem('__yantra_wb_token_reload', '1');\n var u = new URL(window.location.href);\n u.searchParams.set('token', t);\n u.searchParams.set('code', t);\n u.searchParams.set('state', state);\n window.location.replace(u.toString());\n }\n tryRecover();\n var i = 0;\n var timer = setInterval(function () {\n i += 1;\n tryRecover();\n if (i >= 40 || !document.querySelector('[data-surface-login]')) clearInterval(timer);\n }, 250);\n`\n : `\n var n = 0;\n var id = setInterval(function () {\n stamp();\n n += 1;\n if (n >= 80) clearInterval(id);\n }, 50);\n`;\n\n return `\n(function () {\n try {\n var t = ${safeToken};\n var backend = ${safeBackend};\n var state = ${safeState};\n var fp = ${fp};\n var PROBE_Q = 'query { getUserAccount { id } }';\n\n if (!window.__yantraWbFetchPatched) {\n window.__yantraWbFetchPatched = true;\n var origFetch = window.fetch.bind(window);\n window.fetch = function (input, init) {\n try {\n var url = typeof input === 'string' ? input : (input && input.url) ? String(input.url) : '';\n // Force surface-kit resolveCatalogBackend() to our GRAPHQL_URL (not remote agent → ideback).\n if (url.indexOf('/v1/auth/context') !== -1) {\n return Promise.resolve(new Response(\n JSON.stringify({ backendGraphqlUrl: backend }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n ));\n }\n var body = init && typeof init.body === 'string' ? init.body : '';\n if (body && body.indexOf('getUserAccount') !== -1) {\n var parsed = JSON.parse(body);\n var q = parsed && typeof parsed.query === 'string' ? parsed.query.replace(/\\\\s+/g, ' ').trim() : '';\n if (q === PROBE_Q) {\n return Promise.resolve(new Response(\n JSON.stringify({ data: { getUserAccount: { id: 'mobile-webview-handoff' } } }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n ));\n }\n }\n } catch (e0) {}\n return origFetch(input, init);\n };\n }\n\n function stamp() {\n try {\n sessionStorage.setItem('cdecli_oauth_state', state);\n localStorage.setItem('cdecli_token', t);\n sessionStorage.setItem('cdecli_token', t);\n localStorage.setItem('cdecli_system_token', t);\n localStorage.setItem('cdecli_token_meta', JSON.stringify({\n backend: backend,\n verifiedAt: Date.now(),\n fp: fp\n }));\n } catch (e1) {}\n }\n stamp();\n ${recovery}\n } catch (e) {}\n true;\n})();\ntrue;\n`;\n}\n\nexport function buildCdecliTokenInjection(token: string, backend: string, state: string): string {\n return buildSurfaceHandoffScript(token, backend, state, false);\n}\n\nexport function buildSurfaceGateRecoveryScript(token: string, backend: string, state: string): string {\n return buildSurfaceHandoffScript(token, backend, state, true);\n}\n"],"names":["token"],"mappings":"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"}
@@ -17,7 +17,7 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- const SYSTEM_TOKEN_ALGORITHM = __DEV__ ? SecretApiTokenAlgorithm.Hs256 : SecretApiTokenAlgorithm.Rs256;
20
+ const SYSTEM_TOKEN_ALGORITHM = SecretApiTokenAlgorithm.Hs256;
21
21
  const CHANNEL_TYPE = "cdecli-serve";
22
22
  function useCdecliAutoConnect(isSelected, channelId) {
23
23
  const [status, setStatus] = useState("idle");
@@ -1 +1 @@
1
- {"version":3,"file":"useCdecliAutoConnect.js","sources":["../../src/hooks/useCdecliAutoConnect.ts"],"sourcesContent":["/**\n * Auto-connects the cdecli-serve messenger-gateway channel when the CDeCLI\n * gateway is selected from the dropdown. Obtains/creates a system token and\n * calls the `gatewayConnect` mutation so the backend provider has a live\n * session with the cdecli-agent endpoint.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n useGatewayConnectMutation,\n useGatewayDisconnectMutation,\n useGetUserSystemTokenQuery,\n useCreateSecretApiTokenMutation,\n useRevealSecretApiTokenMutation,\n} from 'common/graphql';\nimport { SecretApiTokenAlgorithm } from 'common';\nimport { config } from '../config/env-config';\nimport { usePrerequisiteIds } from './usePrerequisiteIds';\n\n/** Local backend ships RS256 public key but often no private key; HS256 uses dev JWT secret. */\nconst SYSTEM_TOKEN_ALGORITHM = __DEV__ ? SecretApiTokenAlgorithm.Hs256 : SecretApiTokenAlgorithm.Rs256;\n\n// ─── Types ───────────────────────────────────────────────────────\n\nexport type CdecliAutoConnectStatus = 'idle' | 'connecting' | 'connected' | 'error';\n\nexport interface UseCdecliAutoConnectResult {\n /** Whether the backend cdecli-serve channel is connected. */\n channelConnected: boolean;\n /** Current connection status. */\n status: CdecliAutoConnectStatus;\n /** Error message if status is 'error'. */\n error: string | null;\n /** Persistence mode reported by the backend provider ('backend' | 'frontend'). */\n persistenceMode: 'backend' | 'frontend' | undefined;\n /** Active skill name on the current CDeCLI session (null if none). */\n activeSkill: string | null;\n /** Per-user accountId used for this gateway connection. */\n accountId: string;\n /** Reconnect the CDeCLI session with a specific skill pre-activated. */\n connectWithSkill: (skill: string, model?: string, systemPrompt?: string, skillId?: string) => Promise<void>;\n}\n\n// ─── Constants ───────────────────────────────────────────────────\n\nconst CHANNEL_TYPE = 'cdecli-serve';\n\n// ─── Hook ────────────────────────────────────────────────────────\n\n/**\n * When `isSelected` is true, auto-connects the cdecli-serve channel on the\n * messenger-gateway backend using the hosted endpoint and a system token.\n */\nexport function useCdecliAutoConnect(isSelected: boolean, channelId?: string): UseCdecliAutoConnectResult {\n const [status, setStatus] = useState<CdecliAutoConnectStatus>('idle');\n const [error, setError] = useState<string | null>(null);\n const [persistenceMode, setPersistenceMode] = useState<'backend' | 'frontend' | undefined>(undefined);\n const [activeSkill, setActiveSkill] = useState<string | null>(null);\n const connectingRef = useRef(false);\n const connectedRef = useRef(false);\n\n const { orgName, projectId, tagId, accountUserId, loading: prerequisitesLoading } = usePrerequisiteIds();\n\n // Per-user accountId so each user gets their own cdecli-agent session.\n // Wait for the profile query to load before connecting — otherwise all\n // users fall back to 'default' and share a single cdecli-agent session.\n const accountId = accountUserId ?? 'default';\n\n // Track the previous channelId so we can reconnect when the user opens a new chat.\n const prevChannelIdRef = useRef<string | undefined>(channelId);\n\n const [connectMutation] = useGatewayConnectMutation();\n const [disconnectMutation] = useGatewayDisconnectMutation();\n const [createTokenMutation] = useCreateSecretApiTokenMutation();\n const [revealTokenMutation] = useRevealSecretApiTokenMutation();\n const {\n data: systemTokenData,\n loading: systemTokenLoading,\n refetch: refetchSystemToken,\n } = useGetUserSystemTokenQuery({\n skip: !isSelected,\n fetchPolicy: 'network-only',\n });\n\n /** True when the backend rejects createSecretApiToken because the user already has one. */\n const isAlreadyHasSystemTokenError = (err: unknown): boolean => {\n const message = err instanceof Error ? err.message : String(err ?? '');\n return /already have a system token/i.test(message);\n };\n\n const obtainSystemToken = useCallback(async (): Promise<string | null> => {\n try {\n let tokenId: string | null = systemTokenData?.getUserSystemToken?.id ?? null;\n\n /**\n * Race recovery: if the GetUserSystemToken query hasn't returned yet (or returned\n * stale data) we'll fall through to createSecretApiToken. The backend rejects that\n * with \"you already have a system token\" — catch it, refetch, and use the existing\n * token id instead of falling back to an unauthenticated connection.\n */\n if (!tokenId) {\n if (!orgName || !projectId) {\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n if (!tokenId) return null;\n } else {\n try {\n const { data: createData } = await createTokenMutation({\n variables: {\n input: {\n name: 'System Token',\n expiryInSeconds: 31536000,\n isSystemToken: true,\n environmentTagId: tagId,\n orgName: orgName || 'default',\n projectId: projectId || 'default',\n algorithm: SYSTEM_TOKEN_ALGORITHM,\n },\n },\n });\n tokenId = createData?.createSecretApiToken?.id ?? null;\n await refetchSystemToken();\n } catch (createErr) {\n if (!isAlreadyHasSystemTokenError(createErr)) throw createErr;\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n if (!tokenId) {\n console.warn(\n '[useCdecliAutoConnect] System token already exists but refetch returned no id; retrying',\n );\n return null;\n }\n }\n }\n }\n\n if (!tokenId) return null;\n\n const { data: revealData } = await revealTokenMutation({\n variables: { id: tokenId },\n });\n return (revealData?.revealSecretApiToken as string) || null;\n } catch (err) {\n console.error('[useCdecliAutoConnect] obtainSystemToken error:', err);\n return null;\n }\n }, [systemTokenData, createTokenMutation, revealTokenMutation, refetchSystemToken, orgName, projectId, tagId]);\n\n // Auto-connect when CDeCLI gateway is selected\n useEffect(() => {\n if (!isSelected) {\n // Reset when deselected, but don't disconnect — keep the session alive\n // so switching back is instant.\n connectingRef.current = false;\n return;\n }\n\n // Wait until the user profile has loaded so accountId is the real\n // user id instead of the 'default' fallback.\n if (prerequisitesLoading || !accountUserId) return;\n\n /**\n * Wait for the GetUserSystemToken query to resolve before we connect — otherwise we\n * race the network and try to create a duplicate token, which the backend rejects with\n * \"you already have a system token\" and we fall back to an unauthenticated session.\n */\n if (systemTokenLoading) return;\n\n /**\n * If we're already connected and just switching channels, the gateway needs a reconnect\n * (the session is bound server-side to chatId), but the user already had a working\n * connection. Skip flipping the visible status to 'connecting' so the toolbar pill\n * doesn't briefly show \"Checking...\" every time someone taps a history row.\n */\n let isSilentReconnect = false;\n if (connectedRef.current || connectingRef.current) {\n if (channelId && prevChannelIdRef.current !== channelId) {\n isSilentReconnect = connectedRef.current;\n prevChannelIdRef.current = channelId;\n connectedRef.current = false;\n } else {\n return;\n }\n }\n\n const doConnect = async () => {\n connectingRef.current = true;\n if (!isSilentReconnect) setStatus('connecting');\n setError(null);\n\n try {\n const endpoint = config.CDECLI_AGENT_ENDPOINT || 'https://cdecli-agent.cdebase.dev';\n const token = await obtainSystemToken();\n if (!token) {\n console.warn('[useCdecliAutoConnect] No system token, connecting without auth');\n }\n\n const { data } = await connectMutation({\n variables: {\n input: {\n channelType: CHANNEL_TYPE,\n accountId,\n options: {\n endpoint: endpoint.trim(),\n ...(token ? { token } : {}),\n ...(channelId ? { chatId: channelId } : {}),\n },\n },\n },\n });\n\n const result = data?.gatewayConnect as\n | ((typeof data)['gatewayConnect'] & { persistenceMode?: string })\n | undefined;\n console.log(\n '[useCdecliAutoConnect] connectMutation result (account=%s):',\n accountId,\n JSON.stringify(result),\n );\n if (result?.persistenceMode) {\n setPersistenceMode(result.persistenceMode as 'backend' | 'frontend');\n }\n if (result?.state === 'CONNECTED' || result?.connected) {\n setStatus('connected');\n connectedRef.current = true;\n } else if (result?.state === 'ERROR') {\n setStatus('error');\n setError(result.lastError ?? 'Failed to connect to CDeCLI agent');\n connectedRef.current = false;\n } else {\n // Assume connecting — the subscription will push the final state\n setStatus('connected');\n connectedRef.current = true;\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[useCdecliAutoConnect] connect error:', msg);\n setStatus('error');\n setError(msg);\n connectedRef.current = false;\n } finally {\n connectingRef.current = false;\n }\n };\n\n doConnect();\n }, [\n isSelected,\n obtainSystemToken,\n connectMutation,\n accountId,\n prerequisitesLoading,\n accountUserId,\n channelId,\n systemTokenLoading,\n ]);\n\n // Keep the backend session alive across page refreshes and SPA navigations.\n // The backend CdecliServeProvider.connect() will reuse the existing session\n // if the endpoint hasn't changed, preserving conversation context.\n // Only disconnect when the user explicitly switches to a different gateway.\n\n /** Reconnect the CDeCLI session with a specific skill pre-activated. */\n const connectWithSkill = useCallback(\n async (skill: string, model?: string, systemPrompt?: string, skillId?: string) => {\n console.log(\n '[useCdecliAutoConnect] connectWithSkill called with skill=%s skillId=%s model=%s systemPrompt=%d chars',\n skill,\n skillId ?? '',\n model,\n systemPrompt?.length ?? 0,\n );\n setStatus('connecting');\n setError(null);\n\n try {\n const endpoint = config.CDECLI_AGENT_ENDPOINT || 'https://cdecli-agent.cdebase.dev';\n const token = await obtainSystemToken();\n\n console.log('[useCdecliAutoConnect] connectWithSkill sending mutation with skill=%s', skill);\n const { data } = await connectMutation({\n variables: {\n input: {\n channelType: CHANNEL_TYPE,\n accountId,\n options: {\n endpoint: endpoint.trim(),\n ...(token ? { token } : {}),\n skill,\n ...(skillId ? { skillId } : {}),\n ...(model ? { model } : {}),\n ...(systemPrompt ? { systemPrompt } : {}),\n ...(channelId ? { chatId: channelId } : {}),\n },\n },\n },\n });\n\n console.log('[useCdecliAutoConnect] connectWithSkill result:', JSON.stringify(data?.gatewayConnect));\n const result = data?.gatewayConnect as\n | ((typeof data)['gatewayConnect'] & { persistenceMode?: string })\n | undefined;\n if (result?.persistenceMode) {\n setPersistenceMode(result.persistenceMode as 'backend' | 'frontend');\n }\n if (result?.state === 'CONNECTED' || result?.connected) {\n setStatus('connected');\n connectedRef.current = true;\n setActiveSkill(skill);\n } else {\n setStatus('connected');\n connectedRef.current = true;\n setActiveSkill(skill);\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[useCdecliAutoConnect] connectWithSkill error:', msg);\n setStatus('error');\n setError(msg);\n }\n },\n [connectMutation, obtainSystemToken, accountId, channelId],\n );\n\n return {\n channelConnected: status === 'connected',\n status,\n error,\n persistenceMode,\n activeSkill,\n accountId,\n connectWithSkill,\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useCdecliAutoConnect.js","sources":["../../src/hooks/useCdecliAutoConnect.ts"],"sourcesContent":["/**\n * Auto-connects the cdecli-serve messenger-gateway channel when the CDeCLI\n * gateway is selected from the dropdown. Obtains/creates a system token and\n * calls the `gatewayConnect` mutation so the backend provider has a live\n * session with the cdecli-agent endpoint.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n useGatewayConnectMutation,\n useGatewayDisconnectMutation,\n useGetUserSystemTokenQuery,\n useCreateSecretApiTokenMutation,\n useRevealSecretApiTokenMutation,\n} from 'common/graphql';\nimport { SecretApiTokenAlgorithm } from 'common';\nimport { config } from '../config/env-config';\nimport { usePrerequisiteIds } from './usePrerequisiteIds';\n\n/** Local backend ships RS256 public key but often no private key; HS256 uses dev JWT secret. */\nconst SYSTEM_TOKEN_ALGORITHM = SecretApiTokenAlgorithm.Hs256;\n\n// ─── Types ───────────────────────────────────────────────────────\n\nexport type CdecliAutoConnectStatus = 'idle' | 'connecting' | 'connected' | 'error';\n\nexport interface UseCdecliAutoConnectResult {\n /** Whether the backend cdecli-serve channel is connected. */\n channelConnected: boolean;\n /** Current connection status. */\n status: CdecliAutoConnectStatus;\n /** Error message if status is 'error'. */\n error: string | null;\n /** Persistence mode reported by the backend provider ('backend' | 'frontend'). */\n persistenceMode: 'backend' | 'frontend' | undefined;\n /** Active skill name on the current CDeCLI session (null if none). */\n activeSkill: string | null;\n /** Per-user accountId used for this gateway connection. */\n accountId: string;\n /** Reconnect the CDeCLI session with a specific skill pre-activated. */\n connectWithSkill: (skill: string, model?: string, systemPrompt?: string, skillId?: string) => Promise<void>;\n}\n\n// ─── Constants ───────────────────────────────────────────────────\n\nconst CHANNEL_TYPE = 'cdecli-serve';\n\n// ─── Hook ────────────────────────────────────────────────────────\n\n/**\n * When `isSelected` is true, auto-connects the cdecli-serve channel on the\n * messenger-gateway backend using the hosted endpoint and a system token.\n */\nexport function useCdecliAutoConnect(isSelected: boolean, channelId?: string): UseCdecliAutoConnectResult {\n const [status, setStatus] = useState<CdecliAutoConnectStatus>('idle');\n const [error, setError] = useState<string | null>(null);\n const [persistenceMode, setPersistenceMode] = useState<'backend' | 'frontend' | undefined>(undefined);\n const [activeSkill, setActiveSkill] = useState<string | null>(null);\n const connectingRef = useRef(false);\n const connectedRef = useRef(false);\n\n const { orgName, projectId, tagId, accountUserId, loading: prerequisitesLoading } = usePrerequisiteIds();\n\n // Per-user accountId so each user gets their own cdecli-agent session.\n // Wait for the profile query to load before connecting — otherwise all\n // users fall back to 'default' and share a single cdecli-agent session.\n const accountId = accountUserId ?? 'default';\n\n // Track the previous channelId so we can reconnect when the user opens a new chat.\n const prevChannelIdRef = useRef<string | undefined>(channelId);\n\n const [connectMutation] = useGatewayConnectMutation();\n const [disconnectMutation] = useGatewayDisconnectMutation();\n const [createTokenMutation] = useCreateSecretApiTokenMutation();\n const [revealTokenMutation] = useRevealSecretApiTokenMutation();\n const {\n data: systemTokenData,\n loading: systemTokenLoading,\n refetch: refetchSystemToken,\n } = useGetUserSystemTokenQuery({\n skip: !isSelected,\n fetchPolicy: 'network-only',\n });\n\n /** True when the backend rejects createSecretApiToken because the user already has one. */\n const isAlreadyHasSystemTokenError = (err: unknown): boolean => {\n const message = err instanceof Error ? err.message : String(err ?? '');\n return /already have a system token/i.test(message);\n };\n\n const obtainSystemToken = useCallback(async (): Promise<string | null> => {\n try {\n let tokenId: string | null = systemTokenData?.getUserSystemToken?.id ?? null;\n\n /**\n * Race recovery: if the GetUserSystemToken query hasn't returned yet (or returned\n * stale data) we'll fall through to createSecretApiToken. The backend rejects that\n * with \"you already have a system token\" — catch it, refetch, and use the existing\n * token id instead of falling back to an unauthenticated connection.\n */\n if (!tokenId) {\n if (!orgName || !projectId) {\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n if (!tokenId) return null;\n } else {\n try {\n const { data: createData } = await createTokenMutation({\n variables: {\n input: {\n name: 'System Token',\n expiryInSeconds: 31536000,\n isSystemToken: true,\n environmentTagId: tagId,\n orgName: orgName || 'default',\n projectId: projectId || 'default',\n algorithm: SYSTEM_TOKEN_ALGORITHM,\n },\n },\n });\n tokenId = createData?.createSecretApiToken?.id ?? null;\n await refetchSystemToken();\n } catch (createErr) {\n if (!isAlreadyHasSystemTokenError(createErr)) throw createErr;\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n if (!tokenId) {\n console.warn(\n '[useCdecliAutoConnect] System token already exists but refetch returned no id; retrying',\n );\n return null;\n }\n }\n }\n }\n\n if (!tokenId) return null;\n\n const { data: revealData } = await revealTokenMutation({\n variables: { id: tokenId },\n });\n return (revealData?.revealSecretApiToken as string) || null;\n } catch (err) {\n console.error('[useCdecliAutoConnect] obtainSystemToken error:', err);\n return null;\n }\n }, [systemTokenData, createTokenMutation, revealTokenMutation, refetchSystemToken, orgName, projectId, tagId]);\n\n // Auto-connect when CDeCLI gateway is selected\n useEffect(() => {\n if (!isSelected) {\n // Reset when deselected, but don't disconnect — keep the session alive\n // so switching back is instant.\n connectingRef.current = false;\n return;\n }\n\n // Wait until the user profile has loaded so accountId is the real\n // user id instead of the 'default' fallback.\n if (prerequisitesLoading || !accountUserId) return;\n\n /**\n * Wait for the GetUserSystemToken query to resolve before we connect — otherwise we\n * race the network and try to create a duplicate token, which the backend rejects with\n * \"you already have a system token\" and we fall back to an unauthenticated session.\n */\n if (systemTokenLoading) return;\n\n /**\n * If we're already connected and just switching channels, the gateway needs a reconnect\n * (the session is bound server-side to chatId), but the user already had a working\n * connection. Skip flipping the visible status to 'connecting' so the toolbar pill\n * doesn't briefly show \"Checking...\" every time someone taps a history row.\n */\n let isSilentReconnect = false;\n if (connectedRef.current || connectingRef.current) {\n if (channelId && prevChannelIdRef.current !== channelId) {\n isSilentReconnect = connectedRef.current;\n prevChannelIdRef.current = channelId;\n connectedRef.current = false;\n } else {\n return;\n }\n }\n\n const doConnect = async () => {\n connectingRef.current = true;\n if (!isSilentReconnect) setStatus('connecting');\n setError(null);\n\n try {\n const endpoint = config.CDECLI_AGENT_ENDPOINT || 'https://cdecli-agent.cdebase.dev';\n const token = await obtainSystemToken();\n if (!token) {\n console.warn('[useCdecliAutoConnect] No system token, connecting without auth');\n }\n\n const { data } = await connectMutation({\n variables: {\n input: {\n channelType: CHANNEL_TYPE,\n accountId,\n options: {\n endpoint: endpoint.trim(),\n ...(token ? { token } : {}),\n ...(channelId ? { chatId: channelId } : {}),\n },\n },\n },\n });\n\n const result = data?.gatewayConnect as\n | ((typeof data)['gatewayConnect'] & { persistenceMode?: string })\n | undefined;\n console.log(\n '[useCdecliAutoConnect] connectMutation result (account=%s):',\n accountId,\n JSON.stringify(result),\n );\n if (result?.persistenceMode) {\n setPersistenceMode(result.persistenceMode as 'backend' | 'frontend');\n }\n if (result?.state === 'CONNECTED' || result?.connected) {\n setStatus('connected');\n connectedRef.current = true;\n } else if (result?.state === 'ERROR') {\n setStatus('error');\n setError(result.lastError ?? 'Failed to connect to CDeCLI agent');\n connectedRef.current = false;\n } else {\n // Assume connecting — the subscription will push the final state\n setStatus('connected');\n connectedRef.current = true;\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[useCdecliAutoConnect] connect error:', msg);\n setStatus('error');\n setError(msg);\n connectedRef.current = false;\n } finally {\n connectingRef.current = false;\n }\n };\n\n doConnect();\n }, [\n isSelected,\n obtainSystemToken,\n connectMutation,\n accountId,\n prerequisitesLoading,\n accountUserId,\n channelId,\n systemTokenLoading,\n ]);\n\n // Keep the backend session alive across page refreshes and SPA navigations.\n // The backend CdecliServeProvider.connect() will reuse the existing session\n // if the endpoint hasn't changed, preserving conversation context.\n // Only disconnect when the user explicitly switches to a different gateway.\n\n /** Reconnect the CDeCLI session with a specific skill pre-activated. */\n const connectWithSkill = useCallback(\n async (skill: string, model?: string, systemPrompt?: string, skillId?: string) => {\n console.log(\n '[useCdecliAutoConnect] connectWithSkill called with skill=%s skillId=%s model=%s systemPrompt=%d chars',\n skill,\n skillId ?? '',\n model,\n systemPrompt?.length ?? 0,\n );\n setStatus('connecting');\n setError(null);\n\n try {\n const endpoint = config.CDECLI_AGENT_ENDPOINT || 'https://cdecli-agent.cdebase.dev';\n const token = await obtainSystemToken();\n\n console.log('[useCdecliAutoConnect] connectWithSkill sending mutation with skill=%s', skill);\n const { data } = await connectMutation({\n variables: {\n input: {\n channelType: CHANNEL_TYPE,\n accountId,\n options: {\n endpoint: endpoint.trim(),\n ...(token ? { token } : {}),\n skill,\n ...(skillId ? { skillId } : {}),\n ...(model ? { model } : {}),\n ...(systemPrompt ? { systemPrompt } : {}),\n ...(channelId ? { chatId: channelId } : {}),\n },\n },\n },\n });\n\n console.log('[useCdecliAutoConnect] connectWithSkill result:', JSON.stringify(data?.gatewayConnect));\n const result = data?.gatewayConnect as\n | ((typeof data)['gatewayConnect'] & { persistenceMode?: string })\n | undefined;\n if (result?.persistenceMode) {\n setPersistenceMode(result.persistenceMode as 'backend' | 'frontend');\n }\n if (result?.state === 'CONNECTED' || result?.connected) {\n setStatus('connected');\n connectedRef.current = true;\n setActiveSkill(skill);\n } else {\n setStatus('connected');\n connectedRef.current = true;\n setActiveSkill(skill);\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[useCdecliAutoConnect] connectWithSkill error:', msg);\n setStatus('error');\n setError(msg);\n }\n },\n [connectMutation, obtainSystemToken, accountId, channelId],\n );\n\n return {\n channelConnected: status === 'connected',\n status,\n error,\n persistenceMode,\n activeSkill,\n accountId,\n connectWithSkill,\n };\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {useCallback}from'react';import {useCreateSecretApiTokenMutation,useRevealSecretApiTokenMutation,useGetUserSystemTokenQuery}from'common/graphql';import {SecretApiTokenAlgorithm}from'common';import {usePrerequisiteIds}from'./usePrerequisiteIds.js';const SYSTEM_TOKEN_ALGORITHM = __DEV__ ? SecretApiTokenAlgorithm.Hs256 : SecretApiTokenAlgorithm.Rs256;
1
+ import {useCallback}from'react';import {useCreateSecretApiTokenMutation,useRevealSecretApiTokenMutation,useGetUserSystemTokenQuery}from'common/graphql';import {SecretApiTokenAlgorithm}from'common';import {usePrerequisiteIds}from'./usePrerequisiteIds.js';const SYSTEM_TOKEN_ALGORITHM = SecretApiTokenAlgorithm.Hs256;
2
2
  function isAlreadyHasSystemTokenError(err) {
3
3
  const message = err instanceof Error ? err.message : String(err != null ? err : "");
4
4
  return /already have a system token/i.test(message);
@@ -1 +1 @@
1
- {"version":3,"file":"useObtainSystemToken.js","sources":["../../src/hooks/useObtainSystemToken.ts"],"sourcesContent":["/**\n * Mint / reveal the org-scoped system JWT (GetUserSystemToken → RevealSecretApiToken).\n * Same token the webbuilder surface expects as `cdecli_token` / `?token=`.\n */\n\nimport { useCallback } from 'react';\nimport {\n useGetUserSystemTokenQuery,\n useCreateSecretApiTokenMutation,\n useRevealSecretApiTokenMutation,\n} from 'common/graphql';\nimport { SecretApiTokenAlgorithm } from 'common';\nimport { usePrerequisiteIds } from './usePrerequisiteIds';\n\n/** Local backend ships RS256 public key but often no private key; HS256 uses dev JWT secret. */\nconst SYSTEM_TOKEN_ALGORITHM = __DEV__ ? SecretApiTokenAlgorithm.Hs256 : SecretApiTokenAlgorithm.Rs256;\n\nfunction isAlreadyHasSystemTokenError(err: unknown): boolean {\n const message = err instanceof Error ? err.message : String(err ?? '');\n return /already have a system token/i.test(message);\n}\n\nexport interface UseObtainSystemTokenResult {\n /** True while the initial GetUserSystemToken query is in flight. */\n loading: boolean;\n /** Mint or reveal the current system token. Returns null on failure. */\n obtainSystemToken: () => Promise<string | null>;\n}\n\nexport function useObtainSystemToken(enabled = true): UseObtainSystemTokenResult {\n const { orgName, projectId, tagId } = usePrerequisiteIds();\n const [createTokenMutation] = useCreateSecretApiTokenMutation();\n const [revealTokenMutation] = useRevealSecretApiTokenMutation();\n const {\n data: systemTokenData,\n loading,\n refetch: refetchSystemToken,\n } = useGetUserSystemTokenQuery({\n skip: !enabled,\n fetchPolicy: 'network-only',\n });\n\n const obtainSystemToken = useCallback(async (): Promise<string | null> => {\n try {\n let tokenId: string | null = systemTokenData?.getUserSystemToken?.id ?? null;\n\n if (!tokenId) {\n if (!orgName || !projectId) {\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n if (!tokenId) return null;\n } else {\n try {\n const { data: createData } = await createTokenMutation({\n variables: {\n input: {\n name: 'System Token',\n expiryInSeconds: 31536000,\n isSystemToken: true,\n environmentTagId: tagId,\n orgName: orgName || 'default',\n projectId: projectId || 'default',\n algorithm: SYSTEM_TOKEN_ALGORITHM,\n },\n },\n });\n tokenId = createData?.createSecretApiToken?.id ?? null;\n await refetchSystemToken();\n } catch (createErr) {\n if (!isAlreadyHasSystemTokenError(createErr)) throw createErr;\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n if (!tokenId) return null;\n }\n }\n }\n\n if (!tokenId) return null;\n\n const { data: revealData } = await revealTokenMutation({\n variables: { id: tokenId },\n });\n return (revealData?.revealSecretApiToken as string) || null;\n } catch (err) {\n console.error('[useObtainSystemToken] error:', err);\n return null;\n }\n }, [systemTokenData, createTokenMutation, revealTokenMutation, refetchSystemToken, orgName, projectId, tagId]);\n\n return { loading, obtainSystemToken };\n}\n\n/**\n * Append `?token=&state=` for SurfaceLoginGate.captureLoginCallback(),\n * or replace existing token/state query params.\n */\nexport function appendSurfaceAuthParams(baseUrl: string, token: string, state = 'mobile-webview'): string {\n try {\n const url = new URL(baseUrl);\n url.searchParams.set('token', token);\n url.searchParams.set('state', state);\n return url.toString();\n } catch {\n const sep = baseUrl.includes('?') ? '&' : '?';\n return `${baseUrl}${sep}token=${encodeURIComponent(token)}&state=${encodeURIComponent(state)}`;\n }\n}\n\n/** Injected before page scripts so SurfaceLoginGate finds cdecli_token immediately. */\nexport function buildCdecliTokenInjection(token: string): string {\n const safe = JSON.stringify(token);\n return `\n(function () {\n try {\n localStorage.setItem('cdecli_token', ${safe});\n sessionStorage.setItem('cdecli_token', ${safe});\n } catch (e) {}\n true;\n})();\ntrue;\n`;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useObtainSystemToken.js","sources":["../../src/hooks/useObtainSystemToken.ts"],"sourcesContent":["/**\n * Mint / reveal the org-scoped system JWT (GetUserSystemToken → RevealSecretApiToken).\n * Same token the webbuilder surface expects as `cdecli_token` / `?token=`.\n */\n\nimport { useCallback } from 'react';\nimport {\n useGetUserSystemTokenQuery,\n useCreateSecretApiTokenMutation,\n useRevealSecretApiTokenMutation,\n} from 'common/graphql';\nimport { SecretApiTokenAlgorithm } from 'common';\nimport { usePrerequisiteIds } from './usePrerequisiteIds';\n\n/** Local + staging: HS256 matches backend JWT secret. RS256 needs a private key\n * many staging clusters do not ship create then fails and Web Builder never opens. */\nconst SYSTEM_TOKEN_ALGORITHM = SecretApiTokenAlgorithm.Hs256;\n\nfunction isAlreadyHasSystemTokenError(err: unknown): boolean {\n const message = err instanceof Error ? err.message : String(err ?? '');\n return /already have a system token/i.test(message);\n}\n\nexport interface UseObtainSystemTokenResult {\n /** True while the initial GetUserSystemToken query is in flight. */\n loading: boolean;\n /** Mint or reveal the current system token. Returns null on failure. */\n obtainSystemToken: () => Promise<string | null>;\n}\n\nexport function useObtainSystemToken(enabled = true): UseObtainSystemTokenResult {\n const { orgName, projectId, tagId } = usePrerequisiteIds();\n const [createTokenMutation] = useCreateSecretApiTokenMutation();\n const [revealTokenMutation] = useRevealSecretApiTokenMutation();\n const {\n data: systemTokenData,\n loading,\n refetch: refetchSystemToken,\n } = useGetUserSystemTokenQuery({\n skip: !enabled,\n fetchPolicy: 'network-only',\n });\n\n const obtainSystemToken = useCallback(async (): Promise<string | null> => {\n try {\n let tokenId: string | null = systemTokenData?.getUserSystemToken?.id ?? null;\n\n if (!tokenId) {\n if (!orgName || !projectId) {\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n if (!tokenId) return null;\n } else {\n try {\n const { data: createData } = await createTokenMutation({\n variables: {\n input: {\n name: 'System Token',\n expiryInSeconds: 31536000,\n isSystemToken: true,\n environmentTagId: tagId,\n orgName: orgName || 'default',\n projectId: projectId || 'default',\n algorithm: SYSTEM_TOKEN_ALGORITHM,\n },\n },\n });\n tokenId = createData?.createSecretApiToken?.id ?? null;\n await refetchSystemToken();\n } catch (createErr) {\n if (!isAlreadyHasSystemTokenError(createErr)) throw createErr;\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n if (!tokenId) return null;\n }\n }\n }\n\n if (!tokenId) return null;\n\n const { data: revealData } = await revealTokenMutation({\n variables: { id: tokenId },\n });\n return (revealData?.revealSecretApiToken as string) || null;\n } catch (err) {\n console.error('[useObtainSystemToken] error:', err);\n return null;\n }\n }, [systemTokenData, createTokenMutation, revealTokenMutation, refetchSystemToken, orgName, projectId, tagId]);\n\n return { loading, obtainSystemToken };\n}\n\n/**\n * Append `?token=&state=` for SurfaceLoginGate.captureLoginCallback(),\n * or replace existing token/state query params.\n */\nexport function appendSurfaceAuthParams(baseUrl: string, token: string, state = 'mobile-webview'): string {\n try {\n const url = new URL(baseUrl);\n url.searchParams.set('token', token);\n url.searchParams.set('state', state);\n return url.toString();\n } catch {\n const sep = baseUrl.includes('?') ? '&' : '?';\n return `${baseUrl}${sep}token=${encodeURIComponent(token)}&state=${encodeURIComponent(state)}`;\n }\n}\n\n/** Injected before page scripts so SurfaceLoginGate finds cdecli_token immediately. */\nexport function buildCdecliTokenInjection(token: string): string {\n const safe = JSON.stringify(token);\n return `\n(function () {\n try {\n localStorage.setItem('cdecli_token', ${safe});\n sessionStorage.setItem('cdecli_token', ${safe});\n } catch (e) {}\n true;\n})();\ntrue;\n`;\n}\n"],"names":[],"mappings":"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"}
@@ -7,6 +7,12 @@ const ORG_RESOLVE_POLL_MS = 2e3;
7
7
  const PROFILE_POLL_MS = 1500;
8
8
  let projectFixInFlight = false;
9
9
  let projectFixUserId = null;
10
+ let sharedResolvedProjectId = null;
11
+ const sharedProjectListeners = /* @__PURE__ */ new Set();
12
+ function publishSharedResolvedProjectId(projectUuid) {
13
+ sharedResolvedProjectId = projectUuid;
14
+ sharedProjectListeners.forEach((listener) => listener());
15
+ }
10
16
  function pickDefaultOrgSlug(orgs) {
11
17
  var _a, _b;
12
18
  if (!(orgs == null ? void 0 : orgs.length)) return null;
@@ -115,9 +121,27 @@ function usePrerequisiteIds() {
115
121
  return () => clearInterval(timer);
116
122
  }, [isAuthenticated, orgName, effectiveUserId, refetchContextSettings, refetchAccountSettings, refetchOrgs, refetchOrgsByUser]);
117
123
  const settingsProjectId = rawSettingsProjectId;
118
- const [resolvedProjectId, setResolvedProjectId] = useState(null);
124
+ const [resolvedProjectId, setResolvedProjectId] = useState(() => sharedResolvedProjectId);
119
125
  const [isInitializingProject, setIsInitializingProject] = useState(false);
120
- const projectId = settingsProjectId || resolvedProjectId;
126
+ useEffect(() => {
127
+ const onShared = () => {
128
+ if (sharedResolvedProjectId) setResolvedProjectId(sharedResolvedProjectId);
129
+ };
130
+ sharedProjectListeners.add(onShared);
131
+ onShared();
132
+ return () => {
133
+ sharedProjectListeners.delete(onShared);
134
+ };
135
+ }, []);
136
+ useEffect(() => {
137
+ if (!effectiveUserId) return;
138
+ if (projectFixUserId && projectFixUserId !== effectiveUserId) {
139
+ sharedResolvedProjectId = null;
140
+ projectFixInFlight = false;
141
+ setResolvedProjectId(null);
142
+ }
143
+ }, [effectiveUserId]);
144
+ const projectId = settingsProjectId || resolvedProjectId || sharedResolvedProjectId;
121
145
  const settingsLoading = contextSettingsLoading || accountSettingsLoading;
122
146
  const needsProjectCreation = !settingsLoading && !!orgName && !rawSettingsProjectId && !projectId;
123
147
  const [fetchProjects] = useGetProjectsLazyQuery();
@@ -159,6 +183,7 @@ function usePrerequisiteIds() {
159
183
  if (projectFixUserId !== effectiveUserId) {
160
184
  projectFixUserId = effectiveUserId;
161
185
  projectFixInFlight = false;
186
+ sharedResolvedProjectId = null;
162
187
  }
163
188
  if (projectFixInFlight) {
164
189
  return;
@@ -211,6 +236,7 @@ function usePrerequisiteIds() {
211
236
  projectUuid = TESTING_PROJECT_UUID;
212
237
  }
213
238
  setResolvedProjectId(projectUuid);
239
+ publishSharedResolvedProjectId(projectUuid);
214
240
  await persistDefaults(orgName, projectUuid);
215
241
  dispatch(orgChangeAction({
216
242
  orgName,
@@ -224,6 +250,7 @@ function usePrerequisiteIds() {
224
250
  console.error("[usePrerequisiteIds] Project bootstrap failed:", error == null ? void 0 : error.message);
225
251
  console.warn(`[usePrerequisiteIds] Falling back to testing project ${TESTING_PROJECT_UUID} after bootstrap error`);
226
252
  setResolvedProjectId(TESTING_PROJECT_UUID);
253
+ publishSharedResolvedProjectId(TESTING_PROJECT_UUID);
227
254
  try {
228
255
  await persistDefaults(orgName, TESTING_PROJECT_UUID);
229
256
  dispatch(orgChangeAction({
@@ -1 +1 @@
1
- {"version":3,"file":"usePrerequisiteIds.js","sources":["../../src/hooks/usePrerequisiteIds.ts"],"sourcesContent":["import { DEFAULT_PRODUCTION_TAG_ID } from '@adminide-stack/core/lib/constants/defaultIds.js';\nimport { useContextData } from '@adminide-stack/platform-client/lib/hooks/useContextData.js';\nimport {\n orgChangeAction,\n resourceGroupChangeAction,\n} from '@adminide-stack/platform-client/lib/redux/actions/org-action.js';\nimport { isAuthenticatedSelector } from '@adminide-stack/user-auth0-client';\nimport { ConfigurationTarget, ContributionSchemaId } from 'common';\nimport {\n useAccountProfileQuery,\n useCreateVaultMutation,\n useGetProjectsLazyQuery,\n useGetUserOrganizationsQuery,\n useGetUserOrganizationsWithDetailsQuery,\n useQuickCreateProjectForAccountBkMutation,\n useWriteSettingsMutation,\n} from 'common/graphql';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { useAccountDefaultSettings } from './useAccountDefaultSettings';\nimport { isUnhydratedCdecodeUri, settingsUriForAccount, toUriInput } from '../utils/cdecodeUri';\n\nconst uuidToObjectId = (uuid: string) => uuid.replace(/-/g, '').substring(0, 24);\n\nconst PROJECT_NAME = 'DEFAULT_YANTRA_PROJECT';\nconst TAG_ID = uuidToObjectId(DEFAULT_PRODUCTION_TAG_ID);\n/** SystemContributionExtensionNames.Account — owns `account.default.*`. */\nconst ACCOUNT_EXTENSION = 'account';\n\n/**\n * TESTING ONLY — known working project UUID for local mobile bootstrap when create/list\n * cannot resolve `projectId`. Remove once org billing + project minting work for new accounts.\n */\nconst TESTING_PROJECT_UUID = '9a8ac704-1040-4836-9b72-48b771ca91b1';\n\nconst ORG_RESOLVE_POLL_MS = 2000;\nconst PROFILE_POLL_MS = 1500;\n\n// ── Module-level project fix (parity with browser) ───────────────────────────\n// Several screens/hooks mount `usePrerequisiteIds` at once. Per-instance refs race\n// and can create multiple orphan projects. Keep a single-flight guard + user id so\n// adopt/create/persist runs once per account session.\nlet projectFixInFlight = false;\nlet projectFixUserId: string | null = null;\n\nfunction pickDefaultOrgSlug(\n orgs: Array<{ name?: string | null; title?: string | null } | null | undefined> | null | undefined,\n): string | null {\n if (!orgs?.length) return null;\n const first = orgs.find((o) => typeof o?.name === 'string' && o.name.trim().length > 0);\n return first?.name?.trim() ?? null;\n}\n\n/**\n * Org + project prerequisites for mobile (parity with browser `usePrerequisiteIds`).\n *\n * Settings use the same `account.default` config as web (`useSettingsLoader` → `useSettings` on mobile).\n * After verify-user, account-level settings (`//accounts/{id}#settings`) and org membership are polled\n * until `organization` is available, then route context is synced on Home.\n *\n * Scenario: org set but no `account.default.project` → adopt an existing project in the org\n * (or create one), persist settings, and bind resourceGroup — same as browser Scenario 2.\n */\nexport function usePrerequisiteIds() {\n const dispatch = useDispatch();\n const isAuthenticated = useSelector(isAuthenticatedSelector);\n\n const { data: contextData, complete: contextComplete } = useContextData();\n const contextLoading = !contextComplete;\n const cdecodeUri = contextData?.cdecodeUri;\n const contextUserId = contextData?.userId ?? null;\n\n const contextResourceUri = useMemo(() => {\n if (isUnhydratedCdecodeUri(cdecodeUri)) return undefined;\n return toUriInput(cdecodeUri);\n }, [cdecodeUri]);\n\n const {\n data: accountProfileData,\n loading: userLoading,\n refetch: refetchProfile,\n } = useAccountProfileQuery({\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'all',\n skip: !isAuthenticated,\n });\n const profileUserId = accountProfileData?.accountProfile?.user?.id ?? null;\n const effectiveUserId = isAuthenticated ? profileUserId || contextUserId : null;\n\n useEffect(() => {\n if (!isAuthenticated || profileUserId) return;\n const timer = setInterval(() => {\n refetchProfile().catch(() => undefined);\n }, PROFILE_POLL_MS);\n return () => clearInterval(timer);\n }, [isAuthenticated, profileUserId, refetchProfile]);\n\n // Step 1 (web): account.default via settings loader — context cdecodeUri when hydrated\n const {\n organization: orgFromContextSettings,\n project: projectFromContextSettings,\n loading: contextSettingsLoading,\n refetch: refetchContextSettings,\n } = useAccountDefaultSettings({\n resourceUri: contextResourceUri,\n skip: !isAuthenticated || !contextResourceUri,\n });\n\n const accountResourceUri = useMemo(() => {\n if (!effectiveUserId || orgFromContextSettings) return undefined;\n return settingsUriForAccount(effectiveUserId);\n }, [effectiveUserId, orgFromContextSettings]);\n\n // Mobile bootstrap: read account.default from account document before org is on the route\n const {\n organization: orgFromAccountSettings,\n project: projectFromAccountSettings,\n loading: accountSettingsLoading,\n refetch: refetchAccountSettings,\n } = useAccountDefaultSettings({\n resourceUri: accountResourceUri,\n skip: !isAuthenticated || !accountResourceUri,\n });\n\n const {\n data: orgsData,\n loading: orgsLoading,\n refetch: refetchOrgs,\n } = useGetUserOrganizationsWithDetailsQuery({\n skip: !isAuthenticated || !effectiveUserId,\n fetchPolicy: 'cache-and-network',\n });\n\n const {\n data: orgsByUserData,\n loading: orgsByUserLoading,\n refetch: refetchOrgsByUser,\n } = useGetUserOrganizationsQuery({\n variables: { userId: effectiveUserId ?? undefined },\n skip: !isAuthenticated || !effectiveUserId,\n fetchPolicy: 'cache-and-network',\n });\n\n const orgFromMembership = useMemo(() => {\n const fromDetails = pickDefaultOrgSlug(orgsData?.getUserOrganizationsWithDetails);\n if (fromDetails) return fromDetails;\n return pickDefaultOrgSlug(orgsByUserData?.getUserOrganizations);\n }, [orgsData, orgsByUserData]);\n\n const orgFromContextPath = useMemo(() => {\n if (isUnhydratedCdecodeUri(cdecodeUri)) return null;\n const { path } = toUriInput(cdecodeUri);\n const match = path.match(/^\\/([^/]+)\\//);\n return match?.[1]?.trim() || null;\n }, [cdecodeUri]);\n\n const orgName = orgFromContextSettings || orgFromAccountSettings || orgFromMembership || orgFromContextPath || null;\n\n const rawSettingsProjectId = projectFromContextSettings || projectFromAccountSettings || null;\n\n useEffect(() => {\n if (!isAuthenticated || orgName || !effectiveUserId) return;\n const timer = setInterval(() => {\n refetchContextSettings?.()?.catch(() => undefined);\n refetchAccountSettings?.()?.catch(() => undefined);\n refetchOrgs().catch(() => undefined);\n refetchOrgsByUser().catch(() => undefined);\n }, ORG_RESOLVE_POLL_MS);\n return () => clearInterval(timer);\n }, [\n isAuthenticated,\n orgName,\n effectiveUserId,\n refetchContextSettings,\n refetchAccountSettings,\n refetchOrgs,\n refetchOrgsByUser,\n ]);\n\n const settingsProjectId = rawSettingsProjectId;\n\n const [resolvedProjectId, setResolvedProjectId] = useState<string | null>(null);\n const [isInitializingProject, setIsInitializingProject] = useState(false);\n\n const projectId = settingsProjectId || resolvedProjectId;\n const settingsLoading = contextSettingsLoading || accountSettingsLoading;\n // Wait for settings to settle so we don't create before an existing default loads.\n const needsProjectCreation = !settingsLoading && !!orgName && !rawSettingsProjectId && !projectId;\n\n const [fetchProjects] = useGetProjectsLazyQuery();\n const [createProject, { error: createError, loading: projectCreating }] =\n useQuickCreateProjectForAccountBkMutation();\n const [createVault, { error: vaultCreateError }] = useCreateVaultMutation();\n const [writeSettings] = useWriteSettingsMutation();\n\n const accountSettingsUri = useMemo(() => {\n if (!effectiveUserId) return null;\n return settingsUriForAccount(effectiveUserId);\n }, [effectiveUserId]);\n\n const persistDefaults = useCallback(\n async (orgToSet: string, projectUuid: string) => {\n if (!accountSettingsUri) return;\n await writeSettings({\n variables: {\n editingUri: accountSettingsUri,\n settings: {\n 'account.default.organization': orgToSet,\n 'account.default.project': projectUuid,\n },\n target: ConfigurationTarget.USER,\n schemaId: ContributionSchemaId.Configuration,\n extensionName: ACCOUNT_EXTENSION,\n },\n });\n },\n [accountSettingsUri, writeSettings],\n );\n\n const refetchDefaults = useCallback(async () => {\n await Promise.all([\n refetchContextSettings?.()?.catch(() => undefined) ?? Promise.resolve(),\n refetchAccountSettings?.()?.catch(() => undefined) ?? Promise.resolve(),\n ]);\n }, [refetchContextSettings, refetchAccountSettings]);\n\n // Scenario 2: default org present but no project → adopt existing (or create once),\n // then persist so reload / other mounts do not create orphan projects.\n useEffect(() => {\n if (!needsProjectCreation || !effectiveUserId || userLoading || !orgName) {\n return;\n }\n\n if (projectFixUserId !== effectiveUserId) {\n projectFixUserId = effectiveUserId;\n projectFixInFlight = false;\n }\n\n if (projectFixInFlight) {\n return;\n }\n\n projectFixInFlight = true;\n setIsInitializingProject(true);\n\n (async () => {\n try {\n const existing = await fetchProjects({ variables: { orgName, limit: 50 } });\n let projectUuid =\n (existing.data?.getProjects?.data || []).find((p) => p?.projectId)?.projectId ?? undefined;\n let newMongoProjectId: string | undefined;\n\n if (!projectUuid) {\n const created = await createProject({\n variables: {\n input: {\n accountId: effectiveUserId,\n projectName: PROJECT_NAME,\n },\n },\n });\n newMongoProjectId = created.data?.quickCreateProjectForAccount?.id ?? undefined;\n if (newMongoProjectId) {\n const after = await fetchProjects({ variables: { orgName, limit: 50 } });\n projectUuid =\n (after.data?.getProjects?.data || []).find((p) => p?.id === newMongoProjectId)?.projectId ??\n undefined;\n await createVault({\n variables: {\n input: {\n orgName,\n projectId: newMongoProjectId,\n },\n },\n }).catch((error) =>\n console.error('[usePrerequisiteIds] Vault creation failed:', error?.message),\n );\n } else {\n console.warn(\n '[usePrerequisiteIds] Project creation returned no id — using TESTING_PROJECT_UUID',\n );\n }\n }\n\n if (!projectUuid) {\n // TESTING ONLY: unblock Home/Chat/Build when mint/list cannot map projectId.\n console.warn(\n `[usePrerequisiteIds] Could not resolve a project UUID — using testing project ${TESTING_PROJECT_UUID}`,\n );\n projectUuid = TESTING_PROJECT_UUID;\n }\n\n setResolvedProjectId(projectUuid);\n await persistDefaults(orgName, projectUuid);\n dispatch(orgChangeAction({ orgName, userId: effectiveUserId }));\n dispatch(resourceGroupChangeAction({ resourceGroup: projectUuid }));\n await refetchDefaults();\n } catch (error) {\n console.error('[usePrerequisiteIds] Project bootstrap failed:', (error as Error)?.message);\n // TESTING ONLY — still bind a known project so the app is usable locally.\n console.warn(\n `[usePrerequisiteIds] Falling back to testing project ${TESTING_PROJECT_UUID} after bootstrap error`,\n );\n setResolvedProjectId(TESTING_PROJECT_UUID);\n try {\n await persistDefaults(orgName, TESTING_PROJECT_UUID);\n dispatch(orgChangeAction({ orgName, userId: effectiveUserId }));\n dispatch(resourceGroupChangeAction({ resourceGroup: TESTING_PROJECT_UUID }));\n await refetchDefaults();\n // Keep projectFixInFlight=true — same as happy path — so we don't re-loop.\n } catch (persistError) {\n console.error(\n '[usePrerequisiteIds] Testing fallback persist failed:',\n (persistError as Error)?.message,\n );\n projectFixInFlight = false;\n }\n } finally {\n setIsInitializingProject(false);\n }\n })();\n }, [\n createProject,\n createVault,\n dispatch,\n fetchProjects,\n needsProjectCreation,\n orgName,\n persistDefaults,\n refetchDefaults,\n effectiveUserId,\n userLoading,\n ]);\n\n const isOrgLoading =\n isAuthenticated &&\n !orgName &&\n (userLoading ||\n contextLoading ||\n settingsLoading ||\n orgsLoading ||\n orgsByUserLoading ||\n Boolean(effectiveUserId));\n\n const isProjectLoading =\n !!orgName &&\n !rawSettingsProjectId &&\n !projectId &&\n (isInitializingProject || projectCreating || settingsLoading);\n\n const isLoading = isOrgLoading || isProjectLoading;\n\n return {\n projectId,\n orgName,\n accountUserId: effectiveUserId ?? null,\n tagId: TAG_ID,\n loading: isLoading,\n /** True while org slug is still unknown (Home should wait before syncing route). */\n orgLoading: isOrgLoading,\n errors: { createError, vaultCreateError },\n };\n}\n"],"names":["_a","_b","_c","_d"],"mappings":"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"}
1
+ {"version":3,"file":"usePrerequisiteIds.js","sources":["../../src/hooks/usePrerequisiteIds.ts"],"sourcesContent":["import { DEFAULT_PRODUCTION_TAG_ID } from '@adminide-stack/core/lib/constants/defaultIds.js';\nimport { useContextData } from '@adminide-stack/platform-client/lib/hooks/useContextData.js';\nimport {\n orgChangeAction,\n resourceGroupChangeAction,\n} from '@adminide-stack/platform-client/lib/redux/actions/org-action.js';\nimport { isAuthenticatedSelector } from '@adminide-stack/user-auth0-client';\nimport { ConfigurationTarget, ContributionSchemaId } from 'common';\nimport {\n useAccountProfileQuery,\n useCreateVaultMutation,\n useGetProjectsLazyQuery,\n useGetUserOrganizationsQuery,\n useGetUserOrganizationsWithDetailsQuery,\n useQuickCreateProjectForAccountBkMutation,\n useWriteSettingsMutation,\n} from 'common/graphql';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { useAccountDefaultSettings } from './useAccountDefaultSettings';\nimport { isUnhydratedCdecodeUri, settingsUriForAccount, toUriInput } from '../utils/cdecodeUri';\n\nconst uuidToObjectId = (uuid: string) => uuid.replace(/-/g, '').substring(0, 24);\n\nconst PROJECT_NAME = 'DEFAULT_YANTRA_PROJECT';\nconst TAG_ID = uuidToObjectId(DEFAULT_PRODUCTION_TAG_ID);\n/** SystemContributionExtensionNames.Account — owns `account.default.*`. */\nconst ACCOUNT_EXTENSION = 'account';\n\n/**\n * TESTING ONLY — known working project UUID for local mobile bootstrap when create/list\n * cannot resolve `projectId`. Remove once org billing + project minting work for new accounts.\n */\nconst TESTING_PROJECT_UUID = '9a8ac704-1040-4836-9b72-48b771ca91b1';\n\nconst ORG_RESOLVE_POLL_MS = 2000;\nconst PROFILE_POLL_MS = 1500;\n\n// ── Module-level project fix (parity with browser) ───────────────────────────\n// Several screens/hooks mount `usePrerequisiteIds` at once. Per-instance refs race\n// and can create multiple orphan projects. Keep a single-flight guard + user id so\n// adopt/create/persist runs once per account session.\n// Resolved project must also be shared — otherwise WebBuilderPrewarm can \"win\" the\n// flight and HomeScreen never sees projectId (submit stuck on \"not ready\").\nlet projectFixInFlight = false;\nlet projectFixUserId: string | null = null;\nlet sharedResolvedProjectId: string | null = null;\nconst sharedProjectListeners = new Set<() => void>();\n\nfunction publishSharedResolvedProjectId(projectUuid: string): void {\n sharedResolvedProjectId = projectUuid;\n sharedProjectListeners.forEach((listener) => listener());\n}\n\nfunction pickDefaultOrgSlug(\n orgs: Array<{ name?: string | null; title?: string | null } | null | undefined> | null | undefined,\n): string | null {\n if (!orgs?.length) return null;\n const first = orgs.find((o) => typeof o?.name === 'string' && o.name.trim().length > 0);\n return first?.name?.trim() ?? null;\n}\n\n/**\n * Org + project prerequisites for mobile (parity with browser `usePrerequisiteIds`).\n *\n * Settings use the same `account.default` config as web (`useSettingsLoader` → `useSettings` on mobile).\n * After verify-user, account-level settings (`//accounts/{id}#settings`) and org membership are polled\n * until `organization` is available, then route context is synced on Home.\n *\n * Scenario: org set but no `account.default.project` → adopt an existing project in the org\n * (or create one), persist settings, and bind resourceGroup — same as browser Scenario 2.\n */\nexport function usePrerequisiteIds() {\n const dispatch = useDispatch();\n const isAuthenticated = useSelector(isAuthenticatedSelector);\n\n const { data: contextData, complete: contextComplete } = useContextData();\n const contextLoading = !contextComplete;\n const cdecodeUri = contextData?.cdecodeUri;\n const contextUserId = contextData?.userId ?? null;\n\n const contextResourceUri = useMemo(() => {\n if (isUnhydratedCdecodeUri(cdecodeUri)) return undefined;\n return toUriInput(cdecodeUri);\n }, [cdecodeUri]);\n\n const {\n data: accountProfileData,\n loading: userLoading,\n refetch: refetchProfile,\n } = useAccountProfileQuery({\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'all',\n skip: !isAuthenticated,\n });\n const profileUserId = accountProfileData?.accountProfile?.user?.id ?? null;\n const effectiveUserId = isAuthenticated ? profileUserId || contextUserId : null;\n\n useEffect(() => {\n if (!isAuthenticated || profileUserId) return;\n const timer = setInterval(() => {\n refetchProfile().catch(() => undefined);\n }, PROFILE_POLL_MS);\n return () => clearInterval(timer);\n }, [isAuthenticated, profileUserId, refetchProfile]);\n\n // Step 1 (web): account.default via settings loader — context cdecodeUri when hydrated\n const {\n organization: orgFromContextSettings,\n project: projectFromContextSettings,\n loading: contextSettingsLoading,\n refetch: refetchContextSettings,\n } = useAccountDefaultSettings({\n resourceUri: contextResourceUri,\n skip: !isAuthenticated || !contextResourceUri,\n });\n\n const accountResourceUri = useMemo(() => {\n if (!effectiveUserId || orgFromContextSettings) return undefined;\n return settingsUriForAccount(effectiveUserId);\n }, [effectiveUserId, orgFromContextSettings]);\n\n // Mobile bootstrap: read account.default from account document before org is on the route\n const {\n organization: orgFromAccountSettings,\n project: projectFromAccountSettings,\n loading: accountSettingsLoading,\n refetch: refetchAccountSettings,\n } = useAccountDefaultSettings({\n resourceUri: accountResourceUri,\n skip: !isAuthenticated || !accountResourceUri,\n });\n\n const {\n data: orgsData,\n loading: orgsLoading,\n refetch: refetchOrgs,\n } = useGetUserOrganizationsWithDetailsQuery({\n skip: !isAuthenticated || !effectiveUserId,\n fetchPolicy: 'cache-and-network',\n });\n\n const {\n data: orgsByUserData,\n loading: orgsByUserLoading,\n refetch: refetchOrgsByUser,\n } = useGetUserOrganizationsQuery({\n variables: { userId: effectiveUserId ?? undefined },\n skip: !isAuthenticated || !effectiveUserId,\n fetchPolicy: 'cache-and-network',\n });\n\n const orgFromMembership = useMemo(() => {\n const fromDetails = pickDefaultOrgSlug(orgsData?.getUserOrganizationsWithDetails);\n if (fromDetails) return fromDetails;\n return pickDefaultOrgSlug(orgsByUserData?.getUserOrganizations);\n }, [orgsData, orgsByUserData]);\n\n const orgFromContextPath = useMemo(() => {\n if (isUnhydratedCdecodeUri(cdecodeUri)) return null;\n const { path } = toUriInput(cdecodeUri);\n const match = path.match(/^\\/([^/]+)\\//);\n return match?.[1]?.trim() || null;\n }, [cdecodeUri]);\n\n const orgName = orgFromContextSettings || orgFromAccountSettings || orgFromMembership || orgFromContextPath || null;\n\n const rawSettingsProjectId = projectFromContextSettings || projectFromAccountSettings || null;\n\n useEffect(() => {\n if (!isAuthenticated || orgName || !effectiveUserId) return;\n const timer = setInterval(() => {\n refetchContextSettings?.()?.catch(() => undefined);\n refetchAccountSettings?.()?.catch(() => undefined);\n refetchOrgs().catch(() => undefined);\n refetchOrgsByUser().catch(() => undefined);\n }, ORG_RESOLVE_POLL_MS);\n return () => clearInterval(timer);\n }, [\n isAuthenticated,\n orgName,\n effectiveUserId,\n refetchContextSettings,\n refetchAccountSettings,\n refetchOrgs,\n refetchOrgsByUser,\n ]);\n\n const settingsProjectId = rawSettingsProjectId;\n\n const [resolvedProjectId, setResolvedProjectId] = useState<string | null>(() => sharedResolvedProjectId);\n const [isInitializingProject, setIsInitializingProject] = useState(false);\n\n // Cross-instance sync: when another hook wins the project bootstrap, adopt it.\n useEffect(() => {\n const onShared = () => {\n if (sharedResolvedProjectId) setResolvedProjectId(sharedResolvedProjectId);\n };\n sharedProjectListeners.add(onShared);\n onShared();\n return () => {\n sharedProjectListeners.delete(onShared);\n };\n }, []);\n\n // New account session → clear shared fallback so we don't leak another user's project.\n useEffect(() => {\n if (!effectiveUserId) return;\n if (projectFixUserId && projectFixUserId !== effectiveUserId) {\n sharedResolvedProjectId = null;\n projectFixInFlight = false;\n setResolvedProjectId(null);\n }\n }, [effectiveUserId]);\n\n const projectId = settingsProjectId || resolvedProjectId || sharedResolvedProjectId;\n const settingsLoading = contextSettingsLoading || accountSettingsLoading;\n // Wait for settings to settle so we don't create before an existing default loads.\n const needsProjectCreation = !settingsLoading && !!orgName && !rawSettingsProjectId && !projectId;\n\n const [fetchProjects] = useGetProjectsLazyQuery();\n const [createProject, { error: createError, loading: projectCreating }] =\n useQuickCreateProjectForAccountBkMutation();\n const [createVault, { error: vaultCreateError }] = useCreateVaultMutation();\n const [writeSettings] = useWriteSettingsMutation();\n\n const accountSettingsUri = useMemo(() => {\n if (!effectiveUserId) return null;\n return settingsUriForAccount(effectiveUserId);\n }, [effectiveUserId]);\n\n const persistDefaults = useCallback(\n async (orgToSet: string, projectUuid: string) => {\n if (!accountSettingsUri) return;\n await writeSettings({\n variables: {\n editingUri: accountSettingsUri,\n settings: {\n 'account.default.organization': orgToSet,\n 'account.default.project': projectUuid,\n },\n target: ConfigurationTarget.USER,\n schemaId: ContributionSchemaId.Configuration,\n extensionName: ACCOUNT_EXTENSION,\n },\n });\n },\n [accountSettingsUri, writeSettings],\n );\n\n const refetchDefaults = useCallback(async () => {\n await Promise.all([\n refetchContextSettings?.()?.catch(() => undefined) ?? Promise.resolve(),\n refetchAccountSettings?.()?.catch(() => undefined) ?? Promise.resolve(),\n ]);\n }, [refetchContextSettings, refetchAccountSettings]);\n\n // Scenario 2: default org present but no project → adopt existing (or create once),\n // then persist so reload / other mounts do not create orphan projects.\n useEffect(() => {\n if (!needsProjectCreation || !effectiveUserId || userLoading || !orgName) {\n return;\n }\n\n if (projectFixUserId !== effectiveUserId) {\n projectFixUserId = effectiveUserId;\n projectFixInFlight = false;\n sharedResolvedProjectId = null;\n }\n\n if (projectFixInFlight) {\n return;\n }\n\n projectFixInFlight = true;\n setIsInitializingProject(true);\n\n (async () => {\n try {\n const existing = await fetchProjects({ variables: { orgName, limit: 50 } });\n let projectUuid =\n (existing.data?.getProjects?.data || []).find((p) => p?.projectId)?.projectId ?? undefined;\n let newMongoProjectId: string | undefined;\n\n if (!projectUuid) {\n const created = await createProject({\n variables: {\n input: {\n accountId: effectiveUserId,\n projectName: PROJECT_NAME,\n },\n },\n });\n newMongoProjectId = created.data?.quickCreateProjectForAccount?.id ?? undefined;\n if (newMongoProjectId) {\n const after = await fetchProjects({ variables: { orgName, limit: 50 } });\n projectUuid =\n (after.data?.getProjects?.data || []).find((p) => p?.id === newMongoProjectId)?.projectId ??\n undefined;\n await createVault({\n variables: {\n input: {\n orgName,\n projectId: newMongoProjectId,\n },\n },\n }).catch((error) =>\n console.error('[usePrerequisiteIds] Vault creation failed:', error?.message),\n );\n } else {\n console.warn(\n '[usePrerequisiteIds] Project creation returned no id — using TESTING_PROJECT_UUID',\n );\n }\n }\n\n if (!projectUuid) {\n // TESTING ONLY: unblock Home/Chat/Build when mint/list cannot map projectId.\n console.warn(\n `[usePrerequisiteIds] Could not resolve a project UUID — using testing project ${TESTING_PROJECT_UUID}`,\n );\n projectUuid = TESTING_PROJECT_UUID;\n }\n\n setResolvedProjectId(projectUuid);\n publishSharedResolvedProjectId(projectUuid);\n await persistDefaults(orgName, projectUuid);\n dispatch(orgChangeAction({ orgName, userId: effectiveUserId }));\n dispatch(resourceGroupChangeAction({ resourceGroup: projectUuid }));\n await refetchDefaults();\n } catch (error) {\n console.error('[usePrerequisiteIds] Project bootstrap failed:', (error as Error)?.message);\n // TESTING ONLY — still bind a known project so the app is usable locally.\n console.warn(\n `[usePrerequisiteIds] Falling back to testing project ${TESTING_PROJECT_UUID} after bootstrap error`,\n );\n setResolvedProjectId(TESTING_PROJECT_UUID);\n publishSharedResolvedProjectId(TESTING_PROJECT_UUID);\n try {\n await persistDefaults(orgName, TESTING_PROJECT_UUID);\n dispatch(orgChangeAction({ orgName, userId: effectiveUserId }));\n dispatch(resourceGroupChangeAction({ resourceGroup: TESTING_PROJECT_UUID }));\n await refetchDefaults();\n // Keep projectFixInFlight=true — same as happy path — so we don't re-loop.\n } catch (persistError) {\n console.error(\n '[usePrerequisiteIds] Testing fallback persist failed:',\n (persistError as Error)?.message,\n );\n projectFixInFlight = false;\n }\n } finally {\n setIsInitializingProject(false);\n }\n })();\n }, [\n createProject,\n createVault,\n dispatch,\n fetchProjects,\n needsProjectCreation,\n orgName,\n persistDefaults,\n refetchDefaults,\n effectiveUserId,\n userLoading,\n ]);\n\n const isOrgLoading =\n isAuthenticated &&\n !orgName &&\n (userLoading ||\n contextLoading ||\n settingsLoading ||\n orgsLoading ||\n orgsByUserLoading ||\n Boolean(effectiveUserId));\n\n const isProjectLoading =\n !!orgName &&\n !rawSettingsProjectId &&\n !projectId &&\n (isInitializingProject || projectCreating || settingsLoading);\n\n const isLoading = isOrgLoading || isProjectLoading;\n\n return {\n projectId,\n orgName,\n accountUserId: effectiveUserId ?? null,\n tagId: TAG_ID,\n loading: isLoading,\n /** True while org slug is still unknown (Home should wait before syncing route). */\n orgLoading: isOrgLoading,\n errors: { createError, vaultCreateError },\n };\n}\n"],"names":["_a","_b","_c","_d"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {jsx,jsxs}from'react/jsx-runtime';import React,{useRef,useState,useEffect,useCallback,useMemo}from'react';import {useWindowDimensions,useColorScheme,Platform,Keyboard,TouchableWithoutFeedback,View,StyleSheet,ScrollView,Pressable}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {getDefaultLeftItems,getDefaultRightItems,Box,Text,InputToolBar}from'@admin-layout/gluestack-ui-mobile';import {useSafeAreaInsets,SafeAreaView}from'react-native-safe-area-context';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {useDispatch,useSelector}from'react-redux';import {v4}from'uuid';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';import {syncMobileOrgRouteContext}from'../../utils/syncMobileOrgRouteContext.js';import {useChatMutations}from'../../hooks/useChatApi.js';import {AudioRecorderPanel}from'../../features/audio-input/AudioRecorderPanel.js';import {MicErrorBoundary}from'../../features/audio-input/MicErrorBoundary.js';import {requestMicPermission}from'../../features/audio-input/useAudioPermission.js';import {mobileTokens}from'../../theme/mobileTokens.js';import {useMarketplaceTemplateGroups}from'../../hooks/useMarketplaceTemplateGroups.js';import {BuildTemplatesSection}from'./components/BuildTemplatesSection.js';var __defProp = Object.defineProperty;
1
+ import {jsx,jsxs}from'react/jsx-runtime';import React,{useRef,useState,useEffect,useCallback,useMemo}from'react';import {useWindowDimensions,useColorScheme,Platform,Keyboard,TouchableWithoutFeedback,View,StyleSheet,ScrollView,Pressable}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {getDefaultLeftItems,getDefaultRightItems,Box,Text,InputToolBar}from'@admin-layout/gluestack-ui-mobile';import {useSafeAreaInsets,SafeAreaView}from'react-native-safe-area-context';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {useDispatch,useSelector}from'react-redux';import {v4}from'uuid';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';import {syncMobileOrgRouteContext}from'../../utils/syncMobileOrgRouteContext.js';import {useChatMutations}from'../../hooks/useChatApi.js';import {AudioRecorderPanel}from'../../features/audio-input/AudioRecorderPanel.js';import {MicErrorBoundary}from'../../features/audio-input/MicErrorBoundary.js';import {requestMicPermission}from'../../features/audio-input/useAudioPermission.js';import {mobileTokens}from'../../theme/mobileTokens.js';import {useMarketplaceTemplateGroups}from'../../hooks/useMarketplaceTemplateGroups.js';import {BuildTemplatesSection}from'./components/BuildTemplatesSection.js';import {WebBuilderPrewarm}from'./components/WebBuilderPrewarm.js';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -112,6 +112,7 @@ function HomeScreenContent({
112
112
  const {
113
113
  orgName: resolvedOrgName,
114
114
  projectId,
115
+ tagId,
115
116
  accountUserId,
116
117
  loading: prerequisitesLoading,
117
118
  orgLoading
@@ -246,10 +247,14 @@ function HomeScreenContent({
246
247
  if (onSubmitProp) {
247
248
  onSubmitProp(submission);
248
249
  }
249
- if (!effectiveOrgName || !effectiveProjectId) {
250
- console.warn("[HomeScreen] orgName/projectId not ready \u2014 skipping submit.");
250
+ if (!effectiveOrgName) {
251
+ console.warn("[HomeScreen] orgName not ready \u2014 skipping submit.");
251
252
  return;
252
253
  }
254
+ const submitProjectId = effectiveProjectId || "9a8ac704-1040-4836-9b72-48b771ca91b1";
255
+ if (!effectiveProjectId) {
256
+ console.warn("[HomeScreen] projectId not ready \u2014 using testing project fallback for submit.");
257
+ }
253
258
  const requestedChannelId = v4();
254
259
  const title = buildChannelTitle(activeMode, requestedChannelId);
255
260
  const queryToForward = trimmedQuery;
@@ -265,7 +270,7 @@ function HomeScreenContent({
265
270
  model: null,
266
271
  systemPrompt: null,
267
272
  orgName: effectiveOrgName,
268
- projectId: effectiveProjectId
273
+ projectId: submitProjectId
269
274
  }).catch((err) => {
270
275
  console.error("[HomeScreen] createChannel failed:", err);
271
276
  });
@@ -426,38 +431,41 @@ function HomeScreenContent({
426
431
  disabled: isLoading || disabled,
427
432
  isLoading
428
433
  }), [canSubmit, handleSubmit, handleMicPress, isLoading, disabled]);
429
- return /* @__PURE__ */ jsx(SafeAreaView, { edges: ["left", "right", "bottom"], style: {
434
+ return /* @__PURE__ */ jsxs(SafeAreaView, { edges: ["left", "right", "bottom"], style: {
430
435
  flex: 1,
431
436
  backgroundColor: surfaceColor
432
- }, children: /* @__PURE__ */ jsx(TouchableWithoutFeedback, { onPress: Keyboard.dismiss, accessible: false, children: /* @__PURE__ */ jsxs(Box, { flex: 1, width: "100%", position: "relative", children: [
433
- /* @__PURE__ */ jsx(EmptyStateSection, { isDark, secondaryTextColor, primaryTextColor, activeMode, onModeSwitch: handleModeSwitch, orgName: effectiveOrgName, selectedTemplateGroup, selectedBuildTemplateId: (_d = selectedBuildTemplate == null ? void 0 : selectedBuildTemplate.id) != null ? _d : null, onUseBuildTemplate: handleUseBuildTemplate }),
434
- /* @__PURE__ */ jsx(View, { style: [styles.bottomComposerWrap, {
435
- bottom: Math.max(0, keyboardHeight - insets.bottom),
436
- paddingBottom: Math.max(insets.bottom - 6, 2)
437
- }], children: /* @__PURE__ */ jsxs(View, { style: [styles.bottomComposerInner, {
438
- width: contentMaxWidth
439
- }], children: [
440
- voiceError ? /* @__PURE__ */ jsx(View, { style: [styles.voiceErrorBanner, {
441
- backgroundColor: isDark ? "#2b1a1d" : "#fef2f2",
442
- borderColor: isDark ? "#7f1d1d" : "#fecaca"
443
- }], children: /* @__PURE__ */ jsx(Text, { style: [styles.voiceErrorText, {
444
- color: isDark ? "#fecaca" : "#991b1b"
445
- }], children: voiceError }) }) : null,
446
- showAudioRecorder ? (
447
- /*
448
- * Render-time JS errors thrown by `useAudioRecorder`
449
- * (e.g. expo-audio native module missing, recorder
450
- * constructor throws in a release build) are caught
451
- * by the boundary and converted into a soft cancel
452
- * via the same handlers the panel itself uses on
453
- * runtime errors. Without this, a throw during the
454
- * panel's render phase kills the JS thread in
455
- * release / TestFlight.
456
- */
457
- /* @__PURE__ */ jsx(MicErrorBoundary, { onCancel: handleRecorderCancel, onError: handleRecorderError, children: /* @__PURE__ */ jsx(AudioRecorderPanel, { isDark, onTranscriptionComplete: handleTranscriptionComplete, onCancel: handleRecorderCancel, onError: handleRecorderError }) })
458
- ) : /* @__PURE__ */ jsx(InputToolBar, { inputConfig, leftItems, rightItems, templateButton, templateModalConfig, micSendButton })
437
+ }, children: [
438
+ /* @__PURE__ */ jsx(WebBuilderPrewarm, { enabled: isBuildMode, orgName: effectiveOrgName, projectId: effectiveProjectId, tagId }),
439
+ /* @__PURE__ */ jsx(TouchableWithoutFeedback, { onPress: Keyboard.dismiss, accessible: false, children: /* @__PURE__ */ jsxs(Box, { flex: 1, width: "100%", position: "relative", children: [
440
+ /* @__PURE__ */ jsx(EmptyStateSection, { isDark, secondaryTextColor, primaryTextColor, activeMode, onModeSwitch: handleModeSwitch, orgName: effectiveOrgName, selectedTemplateGroup, selectedBuildTemplateId: (_d = selectedBuildTemplate == null ? void 0 : selectedBuildTemplate.id) != null ? _d : null, onUseBuildTemplate: handleUseBuildTemplate }),
441
+ /* @__PURE__ */ jsx(View, { style: [styles.bottomComposerWrap, {
442
+ bottom: Math.max(0, keyboardHeight - insets.bottom),
443
+ paddingBottom: Math.max(insets.bottom - 6, 2)
444
+ }], children: /* @__PURE__ */ jsxs(View, { style: [styles.bottomComposerInner, {
445
+ width: contentMaxWidth
446
+ }], children: [
447
+ voiceError ? /* @__PURE__ */ jsx(View, { style: [styles.voiceErrorBanner, {
448
+ backgroundColor: isDark ? "#2b1a1d" : "#fef2f2",
449
+ borderColor: isDark ? "#7f1d1d" : "#fecaca"
450
+ }], children: /* @__PURE__ */ jsx(Text, { style: [styles.voiceErrorText, {
451
+ color: isDark ? "#fecaca" : "#991b1b"
452
+ }], children: voiceError }) }) : null,
453
+ showAudioRecorder ? (
454
+ /*
455
+ * Render-time JS errors thrown by `useAudioRecorder`
456
+ * (e.g. expo-audio native module missing, recorder
457
+ * constructor throws in a release build) are caught
458
+ * by the boundary and converted into a soft cancel
459
+ * via the same handlers the panel itself uses on
460
+ * runtime errors. Without this, a throw during the
461
+ * panel's render phase kills the JS thread in
462
+ * release / TestFlight.
463
+ */
464
+ /* @__PURE__ */ jsx(MicErrorBoundary, { onCancel: handleRecorderCancel, onError: handleRecorderError, children: /* @__PURE__ */ jsx(AudioRecorderPanel, { isDark, onTranscriptionComplete: handleTranscriptionComplete, onCancel: handleRecorderCancel, onError: handleRecorderError }) })
465
+ ) : /* @__PURE__ */ jsx(InputToolBar, { inputConfig, leftItems, rightItems, templateButton, templateModalConfig, micSendButton })
466
+ ] }) })
459
467
  ] }) })
460
- ] }) }) });
468
+ ] });
461
469
  }
462
470
  const styles = StyleSheet.create({
463
471
  emptyCenterTitleWrap: {