@flexkit/studio 0.2.35 → 0.2.37
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.
- package/dist/{activity-nav-button-ZHQOZBCC.js → activity-nav-button-KOOMUTOW.js} +2 -2
- package/dist/{activity-nav-button-ZHQOZBCC.js.map → activity-nav-button-KOOMUTOW.js.map} +1 -1
- package/dist/chat-page-XYQOQPMW.js +4 -0
- package/dist/chat-page-XYQOQPMW.js.map +1 -0
- package/dist/{chunk-W7JDZHCV.js → chunk-337GX2BR.js} +2 -2
- package/dist/{chunk-W7JDZHCV.js.map → chunk-337GX2BR.js.map} +1 -1
- package/dist/{chunk-7N3LTSVX.js → chunk-36YXPN42.js} +2 -2
- package/dist/{chunk-7N3LTSVX.js.map → chunk-36YXPN42.js.map} +1 -1
- package/dist/{chunk-DEG7QP5C.js → chunk-6NRMVVU4.js} +3 -3
- package/dist/{chunk-DEG7QP5C.js.map → chunk-6NRMVVU4.js.map} +1 -1
- package/dist/{chunk-PMLDA2FF.js → chunk-AQSL5HBZ.js} +2 -2
- package/dist/{chunk-PMLDA2FF.js.map → chunk-AQSL5HBZ.js.map} +1 -1
- package/dist/{chunk-Q4CWQHBJ.js → chunk-BHHLWGZ4.js} +2 -2
- package/dist/{chunk-Q4CWQHBJ.js.map → chunk-BHHLWGZ4.js.map} +1 -1
- package/dist/{chunk-TI3EHLRE.js → chunk-CC2U7ASG.js} +3 -3
- package/dist/{chunk-TI3EHLRE.js.map → chunk-CC2U7ASG.js.map} +1 -1
- package/dist/{chunk-J6EGNRRT.js → chunk-CRTUZ22E.js} +3 -3
- package/dist/{chunk-J6EGNRRT.js.map → chunk-CRTUZ22E.js.map} +1 -1
- package/dist/{chunk-KEGJNZLW.js → chunk-DO32GATF.js} +3 -3
- package/dist/{chunk-KEGJNZLW.js.map → chunk-DO32GATF.js.map} +1 -1
- package/dist/{chunk-RAUQCO6W.js → chunk-KOM7G7WT.js} +2 -2
- package/dist/{chunk-RAUQCO6W.js.map → chunk-KOM7G7WT.js.map} +1 -1
- package/dist/{chunk-WU2KCXBC.js → chunk-L5Z56DDM.js} +2 -2
- package/dist/{chunk-WU2KCXBC.js.map → chunk-L5Z56DDM.js.map} +1 -1
- package/dist/{chunk-36DLIVZF.js → chunk-LVKBKU6Q.js} +2 -2
- package/dist/{chunk-36DLIVZF.js.map → chunk-LVKBKU6Q.js.map} +1 -1
- package/dist/{chunk-PWGLA33F.js → chunk-ND2RTUMM.js} +3 -3
- package/dist/{chunk-PWGLA33F.js.map → chunk-ND2RTUMM.js.map} +1 -1
- package/dist/{chunk-PZWEC6KD.js → chunk-OWY5BQER.js} +2 -2
- package/dist/{chunk-PZWEC6KD.js.map → chunk-OWY5BQER.js.map} +1 -1
- package/dist/chunk-PLCI2RJA.js +3 -0
- package/dist/chunk-PLCI2RJA.js.map +1 -0
- package/dist/{chunk-ZMONKGWJ.js → chunk-PNGPE7QM.js} +3 -3
- package/dist/{chunk-ZMONKGWJ.js.map → chunk-PNGPE7QM.js.map} +1 -1
- package/dist/{chunk-XYE6ZAUB.js → chunk-RGISZNQ2.js} +2 -2
- package/dist/{chunk-XYE6ZAUB.js.map → chunk-RGISZNQ2.js.map} +1 -1
- package/dist/{chunk-R6DPAMLC.js → chunk-RX6QUDLZ.js} +3 -3
- package/dist/{chunk-R6DPAMLC.js.map → chunk-RX6QUDLZ.js.map} +1 -1
- package/dist/{chunk-BTH7HU5Y.js → chunk-U4DUXPZV.js} +2 -2
- package/dist/{chunk-BTH7HU5Y.js.map → chunk-U4DUXPZV.js.map} +1 -1
- package/dist/{chunk-ZRTWLY77.js → chunk-UULPCFWK.js} +3 -3
- package/dist/{chunk-ZRTWLY77.js.map → chunk-UULPCFWK.js.map} +1 -1
- package/dist/{chunk-RFKMFD2O.js → chunk-XV4QJKOJ.js} +2 -2
- package/dist/{chunk-RFKMFD2O.js.map → chunk-XV4QJKOJ.js.map} +1 -1
- package/dist/chunk-ZV7I5RUM.js +10 -0
- package/dist/chunk-ZV7I5RUM.js.map +1 -0
- package/dist/{entry-NQRN7SWV.js → entry-6EWYXIS5.js} +2 -2
- package/dist/{entry-NQRN7SWV.js.map → entry-6EWYXIS5.js.map} +1 -1
- package/dist/index.js +2 -2
- package/dist/{list-RPIG75US.js → list-GBM53HFN.js} +2 -2
- package/dist/{list-RPIG75US.js.map → list-GBM53HFN.js.map} +1 -1
- package/dist/{list-7SCWJXUE.js → list-N5W7G3LD.js} +3 -3
- package/dist/{list-7SCWJXUE.js.map → list-N5W7G3LD.js.map} +1 -1
- package/dist/{pages-KXERA5Z6.js → pages-HPR3UHT7.js} +3 -3
- package/dist/{pages-KXERA5Z6.js.map → pages-HPR3UHT7.js.map} +1 -1
- package/dist/{plugin-pages-NXA4BT7Y.js → plugin-pages-VDRT7RLY.js} +2 -2
- package/dist/{plugin-pages-NXA4BT7Y.js.map → plugin-pages-VDRT7RLY.js.map} +1 -1
- package/dist/{project-selector-SA6UUVBK.js → project-selector-RRG52TSX.js} +2 -2
- package/dist/{project-selector-SA6UUVBK.js.map → project-selector-RRG52TSX.js.map} +1 -1
- package/dist/record-links-CI4OJPWW.js +2 -0
- package/dist/{record-links-RTMCYEPM.js.map → record-links-CI4OJPWW.js.map} +1 -1
- package/dist/{root-IBZPU2D4.js → root-DF2BNGOF.js} +3 -3
- package/dist/{root-IBZPU2D4.js.map → root-DF2BNGOF.js.map} +1 -1
- package/dist/{root-TSZ3CSJU.js → root-IXK2ESCS.js} +3 -3
- package/dist/{root-TSZ3CSJU.js.map → root-IXK2ESCS.js.map} +1 -1
- package/dist/{root-MBFQXX4E.js → root-JFYE2JRJ.js} +2 -2
- package/dist/{root-MBFQXX4E.js.map → root-JFYE2JRJ.js.map} +1 -1
- package/dist/{root-6H6K3YQF.js → root-KF6EFGM6.js} +3 -3
- package/dist/{root-6H6K3YQF.js.map → root-KF6EFGM6.js.map} +1 -1
- package/dist/{root-W5ZPSNQ2.js → root-LUWJS7SQ.js} +2 -2
- package/dist/{root-W5ZPSNQ2.js.map → root-LUWJS7SQ.js.map} +1 -1
- package/dist/{root-TZIXWEZO.js → root-RGAV2YAF.js} +2 -2
- package/dist/{root-TZIXWEZO.js.map → root-RGAV2YAF.js.map} +1 -1
- package/dist/{search-ZLEYFT3T.js → search-DQLC3XDJ.js} +2 -2
- package/dist/{search-ZLEYFT3T.js.map → search-DQLC3XDJ.js.map} +1 -1
- package/dist/{skills-pages-RPMWIBLS.js → skills-pages-Q4YUDTC2.js} +2 -2
- package/dist/{skills-pages-RPMWIBLS.js.map → skills-pages-Q4YUDTC2.js.map} +1 -1
- package/dist/{source-VYWE5EB5.js → source-J3ZCTEWZ.js} +2 -2
- package/dist/{source-VYWE5EB5.js.map → source-J3ZCTEWZ.js.map} +1 -1
- package/package.json +6 -6
- package/dist/chat-page-IR4RF46H.js +0 -4
- package/dist/chat-page-IR4RF46H.js.map +0 -1
- package/dist/chunk-FJRDLP7V.js +0 -10
- package/dist/chunk-FJRDLP7V.js.map +0 -1
- package/dist/chunk-U6VZY3V2.js +0 -3
- package/dist/chunk-U6VZY3V2.js.map +0 -1
- package/dist/record-links-RTMCYEPM.js +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/ai/plugin-oauth.ts","../src/apps/ai/plugin-token-format.ts","../src/apps/ai/plugin-token.tsx"],"names":["OAUTH_START_PATH","PluginAccountMismatchError","httpsUrl","value","url","trustedPluginOAuthTargets","authorizeUrl","completionOrigin","origin","getPlatformOrigin","authorize","completion","connectPluginPopup","api","pluginId","scope","options","popup","transaction","error","targets","expectedOrigin","resolve","reject","polling","finished","handedOff","finish","interval","timeout","onMessage","poll","status","event","payload","pluginSecretFormats","plugin","connect","method","field","credentialFormFields","selected","item","credentialFormComplete","fields","values","credentialFormError","matchesTokenPattern","token","pattern","compileTokenPattern","findPastedPluginToken","text","plugins","words","word","found","tokens","format","request","lastRequestId","cancelLatest","listeners","setRequest","next","listener","subscribe","connectPlugin","id","connectionId","settle","connected","httpsHref","PluginTokenDialogHost","current","useSyncExternalStore","jsx","PluginTokenDialog","PluginCredentialsDialog","FieldError","message","HelpLink","href","label","safeHref","jsxs","ExternalLinkIcon","name","formId","useId","setMethod","useState","setValues","setError","saving","setSaving","selectedMethod","ready","save","problem","failure","Dialog","open","DialogContent","DialogHeader","DialogTitle","DialogDescription","index","inputId","fieldError","Input","previous","DialogFooter","Button","LoaderCircle","setToken"],"mappings":"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","file":"chunk-WU2KCXBC.js","sourcesContent":["import { getPlatformOrigin, type ApiClient } from './api';\nimport type { PluginScope } from './plugin-types';\n\nconst OAUTH_START_PATH = '/plugins/oauth/start';\n\n/** A Reconnect was completed with a different provider account than the one being reconnected. */\nexport class PluginAccountMismatchError extends Error {\n readonly code = 'account_mismatch';\n\n constructor() {\n super('You signed in with a different account. Use \"Connect another account\" to add it.');\n this.name = 'PluginAccountMismatchError';\n }\n}\n\nfunction httpsUrl(value: string): URL | null {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n return null;\n }\n\n if (url.protocol !== 'https:' || url.username !== '' || url.password !== '') {\n return null;\n }\n\n return url;\n}\n\n/** Popup navigation and postMessage stay on the platform OAuth start page. */\nfunction trustedPluginOAuthTargets(\n authorizeUrl: string,\n completionOrigin: string\n): { href: string; origin: string } | null {\n const origin = getPlatformOrigin();\n const authorize = httpsUrl(authorizeUrl);\n const completion = httpsUrl(completionOrigin);\n\n if (!authorize || !completion) {\n return null;\n }\n\n if (authorize.origin !== origin || authorize.pathname !== OAUTH_START_PATH) {\n return null;\n }\n\n if (completion.origin !== origin || completion.pathname !== '/') {\n return null;\n }\n\n return { href: authorize.href, origin };\n}\n\n/** Must be called directly from the click handler so browsers allow the popup. */\nexport async function connectPluginPopup(\n api: ApiClient,\n pluginId: string,\n scope: PluginScope,\n options?: { connectionId?: string }\n): Promise<void> {\n const popup = window.open('about:blank', `flexkit-plugin-${crypto.randomUUID()}`, 'popup,width=560,height=720');\n\n if (!popup) {\n throw new Error('Allow popups for Studio, then connect again.');\n }\n\n let transaction: Awaited<ReturnType<ApiClient['connectPlugins']>>;\n\n try {\n transaction = await api.connectPlugins({\n pluginId,\n scope,\n studioOrigin: window.location.origin,\n ...(options?.connectionId ? { connectionId: options.connectionId } : {}),\n });\n } catch (error) {\n popup.close();\n throw error;\n }\n\n const targets = trustedPluginOAuthTargets(transaction.authorizeUrl, transaction.completionOrigin);\n\n if (!targets) {\n popup.close();\n throw new Error('Connection could not be started.');\n }\n\n const expectedOrigin = targets.origin;\n\n await new Promise<void>((resolve, reject) => {\n let polling = false;\n let finished = false;\n // Once the popup leaves for the provider, `popup.closed` says nothing:\n // providers isolate their pages (Cross-Origin-Opener-Policy), which severs\n // the opener and reports the window as closed while it is open. From then\n // on only the transaction's status (and the timeout) ends the wait.\n let handedOff = false;\n const finish = (error?: Error) => {\n if (finished) {\n return;\n }\n\n finished = true;\n window.clearInterval(interval);\n window.clearTimeout(timeout);\n window.removeEventListener('message', onMessage);\n popup.close();\n\n if (error) {\n reject(error);\n\n return;\n }\n\n resolve();\n };\n const poll = async () => {\n if (polling || finished) {\n return;\n }\n\n polling = true;\n let status: Awaited<ReturnType<ApiClient['pluginOAuthStatus']>>;\n\n try {\n status = await api.pluginOAuthStatus(transaction.transactionId);\n } catch {\n polling = false;\n\n return;\n }\n\n polling = false;\n\n if (status.status === 'complete') {\n finish();\n\n return;\n }\n\n if (!handedOff && popup.closed && status.status === 'pending') {\n finish(new Error('Connection window was closed.'));\n\n return;\n }\n\n if (status.status === 'failed' || new Date(status.expires_at).getTime() < Date.now()) {\n finish(new Error('Connection was not completed. Please try again.'));\n }\n };\n const onMessage = (event: MessageEvent<unknown>) => {\n if (event.origin !== expectedOrigin || event.source !== popup || !event.data || typeof event.data !== 'object') {\n return;\n }\n\n const payload = event.data as { type?: string; transactionId?: string; status?: string; error?: string };\n\n if (payload.type === 'flexkit:plugin-oauth-ready' && payload.transactionId === transaction.transactionId) {\n handedOff = true;\n popup.postMessage(\n {\n type: 'flexkit:plugin-oauth-start',\n transactionId: transaction.transactionId,\n ticket: transaction.launchTicket,\n },\n expectedOrigin\n );\n\n return;\n }\n\n if (payload.type === 'flexkit:plugin-oauth' && payload.transactionId === transaction.transactionId) {\n if (payload.status === 'failed' && payload.error === 'account_mismatch') {\n finish(new PluginAccountMismatchError());\n\n return;\n }\n\n void poll();\n }\n };\n const interval = window.setInterval(() => {\n void poll();\n }, 2000);\n const timeout = window.setTimeout(() => finish(new Error('Connection timed out. Please try again.')), 600_000);\n window.addEventListener('message', onMessage);\n popup.location.href = targets.href;\n });\n}\n","import type { MarketplacePlugin, PluginCredentialField, PluginCredentialsConnect } from './plugin-types';\n\nexport type ConnectablePlugin = Pick<MarketplacePlugin, 'connect' | 'id' | 'name'>;\n\n/** Longer than any credential a provider issues; the server rejects more. */\nexport const MAX_CREDENTIAL_VALUE_LENGTH = 4096;\n\n/**\n * The secrets a plugin's connect form takes that can be recognized on their\n * own (a distinctive prefix, say), each with that pattern and what to call it.\n */\nexport function pluginSecretFormats(plugin: ConnectablePlugin): Array<{ label: string; pattern: string }> {\n const { connect } = plugin;\n\n if (connect?.type === 'api-token') {\n return connect.pattern ? [{ label: connect.tokenLabel, pattern: connect.pattern }] : [];\n }\n\n if (connect?.type === 'credentials') {\n return [...connect.fields, ...connect.methods.flatMap((method) => method.fields)]\n .filter((field) => field.kind === 'secret' && field.detect)\n .map((field) => ({ label: field.label, pattern: field.detect! }));\n }\n\n return [];\n}\n\n/** The fields a credentials form shows: the shared ones, then those of the chosen method. */\nexport function credentialFormFields(connect: PluginCredentialsConnect, method: string | null): PluginCredentialField[] {\n const selected = connect.methods.find((item) => item.key === method);\n\n return [...connect.fields, ...(selected?.fields ?? [])];\n}\n\n/** Whether every required field has a value: what the Connect button waits for. */\nexport function credentialFormComplete(\n fields: readonly PluginCredentialField[],\n values: { [key: string]: string }\n): boolean {\n return fields.every((field) => !field.required || Boolean(values[field.key]?.trim()));\n}\n\n/** The first problem with the values entered, or null when they can be submitted. */\nexport function credentialFormError(\n fields: readonly PluginCredentialField[],\n values: { [key: string]: string }\n): { field: string; message: string } | null {\n for (const field of fields) {\n const value = values[field.key]?.trim() ?? '';\n\n if (!value) {\n if (field.required) {\n return { field: field.key, message: `Enter the ${field.label}.` };\n }\n\n continue;\n }\n\n if (value.length > MAX_CREDENTIAL_VALUE_LENGTH) {\n return { field: field.key, message: `The ${field.label} is too long; paste only the value.` };\n }\n\n if (!matchesTokenPattern(value, field.pattern)) {\n return { field: field.key, message: `That is not a valid ${field.label}.` };\n }\n }\n\n return null;\n}\n\nexport function matchesTokenPattern(token: string, pattern: string | null): boolean {\n if (!pattern) {\n return true;\n }\n\n try {\n return new RegExp(pattern, 'u').test(token);\n } catch {\n // The server validates the pattern when it admits the plugin; never block on a bad one here.\n return true;\n }\n}\n\n/** A pattern that compiles; an empty or broken one detects nothing rather than every word. */\nfunction compileTokenPattern(pattern: string | null): RegExp | null {\n if (!pattern) {\n return null;\n }\n\n try {\n return new RegExp(pattern, 'u');\n } catch {\n return null;\n }\n}\n\n/**\n * The first plugin whose secret format `text` contains, if any, with every\n * secret-shaped word in the message and what the plugin calls that secret: a\n * token pasted into the chat would be stored in the conversation and sent to\n * the model.\n */\nexport function findPastedPluginToken(\n text: string,\n plugins: readonly ConnectablePlugin[]\n): { plugin: ConnectablePlugin; tokens: string[]; label: string } | null {\n // A token is often glued to a label (`token=…`, `key: …`) or wrapped in\n // brackets, quotes or a sentence's punctuation; none of those are part of it.\n const words = text\n .split(/[\\s\"'`()<>[\\]{},;:=!?&]+/)\n .map((word) => word.replace(/\\.+$/, ''))\n .filter(Boolean);\n let found: { plugin: ConnectablePlugin; label: string } | null = null;\n const tokens = new Set<string>();\n\n for (const plugin of plugins) {\n for (const format of pluginSecretFormats(plugin)) {\n const pattern = compileTokenPattern(format.pattern);\n\n for (const word of pattern ? words : []) {\n if (pattern!.test(word)) {\n found ??= { plugin, label: format.label };\n tokens.add(word);\n }\n }\n }\n }\n\n return found ? { ...found, tokens: [...tokens] } : null;\n}\n","import type { FormEvent, JSX } from 'react';\nimport { useId, useState, useSyncExternalStore } from 'react';\nimport { ExternalLinkIcon, LoaderCircle } from 'lucide-react';\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n} from '../../ui';\nimport type { ApiClient } from './api';\nimport { connectPluginPopup } from './plugin-oauth';\nimport {\n credentialFormComplete,\n credentialFormError,\n credentialFormFields,\n matchesTokenPattern,\n type ConnectablePlugin,\n} from './plugin-token-format';\nimport type { PluginApiTokenConnect, PluginCredentialsConnect, PluginScope } from './plugin-types';\n\ninterface TokenRequest {\n id: number;\n plugin: ConnectablePlugin & { connect: PluginApiTokenConnect };\n /** Saves the token; rejects with a message the dialog shows next to the field. */\n submit: (_token: string) => Promise<void>;\n settle: (_connected: boolean) => void;\n}\n\ninterface CredentialsRequest {\n id: number;\n plugin: ConnectablePlugin & { connect: PluginCredentialsConnect };\n /** Saves the form; rejects with a message the dialog shows under the fields. */\n submit: (_method: string | undefined, _values: { [key: string]: string }) => Promise<void>;\n settle: (_connected: boolean) => void;\n}\n\ntype FormRequest = ({ kind: 'token' } & TokenRequest) | ({ kind: 'credentials' } & CredentialsRequest);\n\n/** The one open connect form, outside React so any connect button can open it. */\nlet request: FormRequest | null = null;\nlet lastRequestId = 0;\n/** Cancels the latest request, whether its dialog has opened yet or not. */\nlet cancelLatest: (() => void) | null = null;\nconst listeners = new Set<() => void>();\n\nfunction setRequest(next: FormRequest | null): void {\n request = next;\n listeners.forEach((listener) => listener());\n}\n\nfunction subscribe(listener: () => void): () => void {\n listeners.add(listener);\n\n return () => listeners.delete(listener);\n}\n\n/**\n * Connects a plugin: a sign-in popup for OAuth plugins, the token dialog for\n * plugins that take a pasted token, the credentials dialog for plugins that\n * take the credentials of an app the user created at the provider. Resolves\n * `false` when the user closes a dialog without connecting.\n *\n * Call it straight from a click handler: browsers only allow the popup there.\n */\nexport function connectPlugin(\n api: ApiClient,\n plugin: ConnectablePlugin,\n scope: PluginScope,\n options?: { connectionId?: string }\n): Promise<boolean> {\n const { connect } = plugin;\n\n if (connect?.type !== 'api-token' && connect?.type !== 'credentials') {\n return connectPluginPopup(api, plugin.id, scope, options).then(() => true);\n }\n\n // Opening a second dialog closes the first, as if cancelled.\n cancelLatest?.();\n\n const id = ++lastRequestId;\n const connectionId = options?.connectionId ? { connectionId: options.connectionId } : {};\n\n return new Promise<boolean>((resolve) => {\n const settle = (connected: boolean): void => {\n // A save still running for a replaced dialog must not close its successor.\n if (request?.id === id) {\n setRequest(null);\n }\n\n if (lastRequestId === id) {\n cancelLatest = null;\n }\n\n resolve(connected);\n };\n const next: FormRequest =\n connect.type === 'api-token'\n ? {\n kind: 'token',\n id,\n plugin: { ...plugin, connect },\n submit: async (token) => {\n await api.connectPluginToken({ pluginId: plugin.id, scope, token, ...connectionId });\n },\n settle,\n }\n : {\n kind: 'credentials',\n id,\n plugin: { ...plugin, connect },\n submit: async (method, values) => {\n await api.connectPluginCredentials({ pluginId: plugin.id, scope, method, values, ...connectionId });\n },\n settle,\n };\n\n cancelLatest = () => settle(false);\n\n // Open after the current event: a menu item that started this closes first\n // and returns focus to its trigger, which would take it from the first field.\n setTimeout(() => {\n if (lastRequestId === id) {\n setRequest(next);\n }\n });\n });\n}\n\nfunction httpsHref(value: string | null): string | null {\n if (!value) {\n return null;\n }\n\n try {\n const url = new URL(value);\n\n return url.protocol === 'https:' ? url.href : null;\n } catch {\n return null;\n }\n}\n\n/** Mounted once by the Studio layout; renders the dialog `connectPlugin` opens for token and credentials plugins. */\nexport function PluginTokenDialogHost(): JSX.Element | null {\n const current = useSyncExternalStore(\n subscribe,\n () => request,\n () => null\n );\n\n if (!current) {\n return null;\n }\n\n // A new key per request resets the fields, so a secret never outlives its dialog.\n return current.kind === 'token' ? (\n <PluginTokenDialog key={current.id} request={current} />\n ) : (\n <PluginCredentialsDialog key={current.id} request={current} />\n );\n}\n\nfunction FieldError({ id, message }: { id: string; message: string | null }): JSX.Element | null {\n return message ? (\n <p className=\"fk:text-sm fk:text-destructive\" id={id}>\n {message}\n </p>\n ) : null;\n}\n\nfunction HelpLink({ href, label }: { href: string | null; label: string }): JSX.Element | null {\n const safeHref = httpsHref(href);\n\n return safeHref ? (\n <a\n className=\"fk:inline-flex fk:items-center fk:gap-1 fk:text-sm fk:text-muted-foreground fk:underline-offset-4 fk:hover:underline\"\n href={safeHref}\n rel=\"noreferrer\"\n target=\"_blank\"\n >\n {label}\n <ExternalLinkIcon className=\"fk:size-3.5\" />\n </a>\n ) : null;\n}\n\nfunction PluginCredentialsDialog({ request: current }: { request: CredentialsRequest }): JSX.Element {\n const { connect, name } = current.plugin;\n const formId = useId();\n const [method, setMethod] = useState<string | null>(connect.methods[0]?.key ?? null);\n const [values, setValues] = useState<{ [key: string]: string }>({});\n const [error, setError] = useState<{ field: string | null; message: string } | null>(null);\n const [saving, setSaving] = useState(false);\n const fields = credentialFormFields(connect, method);\n const selectedMethod = connect.methods.find((item) => item.key === method) ?? null;\n // Submitting surfaces which field is malformed; the button only waits for the required values.\n const ready = credentialFormComplete(fields, values);\n\n async function save(event: FormEvent): Promise<void> {\n event.preventDefault();\n\n if (saving) {\n return;\n }\n\n const problem = credentialFormError(fields, values);\n\n if (problem) {\n setError(problem);\n\n return;\n }\n\n setSaving(true);\n setError(null);\n\n try {\n await current.submit(\n method ?? undefined,\n Object.fromEntries(fields.map((field) => [field.key, values[field.key]?.trim() ?? '']).filter(([, value]) => value))\n );\n setValues({});\n current.settle(true);\n } catch (failure) {\n setError({ field: null, message: failure instanceof Error ? failure.message : `${name} could not be connected.` });\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <Dialog\n open\n onOpenChange={(open) => {\n if (!open && !saving) {\n current.settle(false);\n }\n }}\n >\n <DialogContent>\n <form className=\"fk:flex fk:flex-col fk:gap-4\" onSubmit={(event) => void save(event)}>\n <DialogHeader>\n <DialogTitle>Connect {name}</DialogTitle>\n <DialogDescription>\n {connect.description} Flexkit checks the credentials with {name}, stores them encrypted and sends them\n only to Flexkit's own {name} server; the agent can use the tools but never sees them.\n </DialogDescription>\n </DialogHeader>\n {connect.methods.length > 1 ? (\n <div className=\"fk:space-y-1.5\" role=\"group\" aria-label=\"How to connect\">\n {connect.methods.map((item) => (\n <button\n aria-pressed={method === item.key}\n className={`fk:flex fk:w-full fk:flex-col fk:rounded-lg fk:border fk:px-3 fk:py-2 fk:text-left fk:corner-squircle ${\n method === item.key ? 'fk:border-primary fk:bg-primary/5' : 'fk:border-border fk:hover:bg-muted/60'\n }`}\n disabled={saving}\n key={item.key}\n onClick={() => {\n setMethod(item.key);\n setError(null);\n }}\n type=\"button\"\n >\n <span className=\"fk:text-sm fk:font-medium\">{item.label}</span>\n {item.description ? (\n <span className=\"fk:text-xs fk:text-muted-foreground\">{item.description}</span>\n ) : null}\n </button>\n ))}\n </div>\n ) : selectedMethod?.description ? (\n <p className=\"fk:text-sm fk:text-muted-foreground\">{selectedMethod.description}</p>\n ) : null}\n {fields.map((field, index) => {\n const inputId = `${formId}-${field.key}`;\n const fieldError = error?.field === field.key ? error.message : null;\n\n return (\n <div className=\"fk:flex fk:flex-col fk:gap-2\" key={field.key}>\n <label className=\"fk:text-sm fk:font-medium\" htmlFor={inputId}>\n {field.label}\n </label>\n <Input\n aria-describedby={fieldError ? `${inputId}-error` : field.help ? `${inputId}-help` : undefined}\n aria-invalid={fieldError ? true : undefined}\n autoComplete=\"off\"\n autoFocus={index === 0}\n disabled={saving}\n id={inputId}\n placeholder={field.placeholder ?? undefined}\n spellCheck={false}\n type={field.kind === 'secret' ? 'password' : 'text'}\n value={values[field.key] ?? ''}\n onChange={(event) => {\n setValues((previous) => ({ ...previous, [field.key]: event.target.value }));\n setError(null);\n }}\n />\n {field.help && !fieldError ? (\n <p className=\"fk:text-sm fk:text-muted-foreground\" id={`${inputId}-help`}>\n {field.help}\n </p>\n ) : null}\n <FieldError id={`${inputId}-error`} message={fieldError} />\n </div>\n );\n })}\n <FieldError id={`${formId}-error`} message={error?.field === null ? error.message : null} />\n <HelpLink href={connect.helpUrl} label={`How to set up ${name}`} />\n <DialogFooter>\n <Button disabled={saving} size=\"sm\" type=\"button\" variant=\"outline\" onClick={() => current.settle(false)}>\n Cancel\n </Button>\n <Button disabled={saving || !ready} size=\"sm\" type=\"submit\">\n {saving ? <LoaderCircle className=\"fk:size-4 fk:animate-spin\" /> : null}\n Connect\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction PluginTokenDialog({ request: current }: { request: TokenRequest }): JSX.Element {\n const { connect, name } = current.plugin;\n const inputId = useId();\n const [token, setToken] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [saving, setSaving] = useState(false);\n\n async function save(event: FormEvent): Promise<void> {\n event.preventDefault();\n const value = token.trim();\n\n if (saving || !value) {\n return;\n }\n\n if (!matchesTokenPattern(value, connect.pattern)) {\n setError(`That does not look like a ${connect.tokenLabel}.`);\n\n return;\n }\n\n setSaving(true);\n setError(null);\n\n try {\n await current.submit(value);\n setToken('');\n current.settle(true);\n } catch (failure) {\n setError(failure instanceof Error ? failure.message : `${name} could not be connected.`);\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <Dialog\n open\n onOpenChange={(open) => {\n if (!open && !saving) {\n current.settle(false);\n }\n }}\n >\n <DialogContent>\n <form className=\"fk:flex fk:flex-col fk:gap-4\" onSubmit={(event) => void save(event)}>\n <DialogHeader>\n <DialogTitle>Connect {name}</DialogTitle>\n <DialogDescription>\n Paste a {connect.tokenLabel}. Flexkit stores it encrypted and sends it only to {name}; the agent can use{' '}\n {name}'s tools but never sees the token. Give it read access only, unless the agent should change\n things in {name}.\n </DialogDescription>\n </DialogHeader>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <label className=\"fk:text-sm fk:font-medium\" htmlFor={inputId}>\n {connect.tokenLabel}\n </label>\n <Input\n aria-describedby={error ? `${inputId}-error` : undefined}\n aria-invalid={error ? true : undefined}\n autoComplete=\"off\"\n autoFocus\n disabled={saving}\n id={inputId}\n placeholder={connect.placeholder ?? undefined}\n spellCheck={false}\n type=\"password\"\n value={token}\n onChange={(event) => {\n setToken(event.target.value);\n setError(null);\n }}\n />\n <FieldError id={`${inputId}-error`} message={error} />\n <HelpLink href={connect.helpUrl} label={`How to create a ${connect.tokenLabel}`} />\n </div>\n <DialogFooter>\n <Button disabled={saving} size=\"sm\" type=\"button\" variant=\"outline\" onClick={() => current.settle(false)}>\n Cancel\n </Button>\n <Button disabled={saving || !token.trim()} size=\"sm\" type=\"submit\">\n {saving ? <LoaderCircle className=\"fk:size-4 fk:animate-spin\" /> : null}\n Connect\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/apps/ai/plugin-oauth.ts","../src/apps/ai/plugin-token-format.ts","../src/apps/ai/plugin-token.tsx"],"names":["OAUTH_START_PATH","PluginAccountMismatchError","httpsUrl","value","url","trustedPluginOAuthTargets","authorizeUrl","completionOrigin","origin","getPlatformOrigin","authorize","completion","connectPluginPopup","api","pluginId","scope","options","popup","transaction","error","targets","expectedOrigin","resolve","reject","polling","finished","handedOff","finish","interval","timeout","onMessage","poll","status","event","payload","pluginSecretFormats","plugin","connect","method","field","credentialFormFields","selected","item","credentialFormComplete","fields","values","credentialFormError","matchesTokenPattern","token","pattern","compileTokenPattern","findPastedPluginToken","text","plugins","words","word","found","tokens","format","request","lastRequestId","cancelLatest","listeners","setRequest","next","listener","subscribe","connectPlugin","id","connectionId","settle","connected","httpsHref","PluginTokenDialogHost","current","useSyncExternalStore","jsx","PluginTokenDialog","PluginCredentialsDialog","FieldError","message","HelpLink","href","label","safeHref","jsxs","ExternalLinkIcon","name","formId","useId","setMethod","useState","setValues","setError","saving","setSaving","selectedMethod","ready","save","problem","failure","Dialog","open","DialogContent","DialogHeader","DialogTitle","DialogDescription","index","inputId","fieldError","Input","previous","DialogFooter","Button","LoaderCircle","setToken"],"mappings":"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","file":"chunk-L5Z56DDM.js","sourcesContent":["import { getPlatformOrigin, type ApiClient } from './api';\nimport type { PluginScope } from './plugin-types';\n\nconst OAUTH_START_PATH = '/plugins/oauth/start';\n\n/** A Reconnect was completed with a different provider account than the one being reconnected. */\nexport class PluginAccountMismatchError extends Error {\n readonly code = 'account_mismatch';\n\n constructor() {\n super('You signed in with a different account. Use \"Connect another account\" to add it.');\n this.name = 'PluginAccountMismatchError';\n }\n}\n\nfunction httpsUrl(value: string): URL | null {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n return null;\n }\n\n if (url.protocol !== 'https:' || url.username !== '' || url.password !== '') {\n return null;\n }\n\n return url;\n}\n\n/** Popup navigation and postMessage stay on the platform OAuth start page. */\nfunction trustedPluginOAuthTargets(\n authorizeUrl: string,\n completionOrigin: string\n): { href: string; origin: string } | null {\n const origin = getPlatformOrigin();\n const authorize = httpsUrl(authorizeUrl);\n const completion = httpsUrl(completionOrigin);\n\n if (!authorize || !completion) {\n return null;\n }\n\n if (authorize.origin !== origin || authorize.pathname !== OAUTH_START_PATH) {\n return null;\n }\n\n if (completion.origin !== origin || completion.pathname !== '/') {\n return null;\n }\n\n return { href: authorize.href, origin };\n}\n\n/** Must be called directly from the click handler so browsers allow the popup. */\nexport async function connectPluginPopup(\n api: ApiClient,\n pluginId: string,\n scope: PluginScope,\n options?: { connectionId?: string }\n): Promise<void> {\n const popup = window.open('about:blank', `flexkit-plugin-${crypto.randomUUID()}`, 'popup,width=560,height=720');\n\n if (!popup) {\n throw new Error('Allow popups for Studio, then connect again.');\n }\n\n let transaction: Awaited<ReturnType<ApiClient['connectPlugins']>>;\n\n try {\n transaction = await api.connectPlugins({\n pluginId,\n scope,\n studioOrigin: window.location.origin,\n ...(options?.connectionId ? { connectionId: options.connectionId } : {}),\n });\n } catch (error) {\n popup.close();\n throw error;\n }\n\n const targets = trustedPluginOAuthTargets(transaction.authorizeUrl, transaction.completionOrigin);\n\n if (!targets) {\n popup.close();\n throw new Error('Connection could not be started.');\n }\n\n const expectedOrigin = targets.origin;\n\n await new Promise<void>((resolve, reject) => {\n let polling = false;\n let finished = false;\n // Once the popup leaves for the provider, `popup.closed` says nothing:\n // providers isolate their pages (Cross-Origin-Opener-Policy), which severs\n // the opener and reports the window as closed while it is open. From then\n // on only the transaction's status (and the timeout) ends the wait.\n let handedOff = false;\n const finish = (error?: Error) => {\n if (finished) {\n return;\n }\n\n finished = true;\n window.clearInterval(interval);\n window.clearTimeout(timeout);\n window.removeEventListener('message', onMessage);\n popup.close();\n\n if (error) {\n reject(error);\n\n return;\n }\n\n resolve();\n };\n const poll = async () => {\n if (polling || finished) {\n return;\n }\n\n polling = true;\n let status: Awaited<ReturnType<ApiClient['pluginOAuthStatus']>>;\n\n try {\n status = await api.pluginOAuthStatus(transaction.transactionId);\n } catch {\n polling = false;\n\n return;\n }\n\n polling = false;\n\n if (status.status === 'complete') {\n finish();\n\n return;\n }\n\n if (!handedOff && popup.closed && status.status === 'pending') {\n finish(new Error('Connection window was closed.'));\n\n return;\n }\n\n if (status.status === 'failed' || new Date(status.expires_at).getTime() < Date.now()) {\n finish(new Error('Connection was not completed. Please try again.'));\n }\n };\n const onMessage = (event: MessageEvent<unknown>) => {\n if (event.origin !== expectedOrigin || event.source !== popup || !event.data || typeof event.data !== 'object') {\n return;\n }\n\n const payload = event.data as { type?: string; transactionId?: string; status?: string; error?: string };\n\n if (payload.type === 'flexkit:plugin-oauth-ready' && payload.transactionId === transaction.transactionId) {\n handedOff = true;\n popup.postMessage(\n {\n type: 'flexkit:plugin-oauth-start',\n transactionId: transaction.transactionId,\n ticket: transaction.launchTicket,\n },\n expectedOrigin\n );\n\n return;\n }\n\n if (payload.type === 'flexkit:plugin-oauth' && payload.transactionId === transaction.transactionId) {\n if (payload.status === 'failed' && payload.error === 'account_mismatch') {\n finish(new PluginAccountMismatchError());\n\n return;\n }\n\n void poll();\n }\n };\n const interval = window.setInterval(() => {\n void poll();\n }, 2000);\n const timeout = window.setTimeout(() => finish(new Error('Connection timed out. Please try again.')), 600_000);\n window.addEventListener('message', onMessage);\n popup.location.href = targets.href;\n });\n}\n","import type { MarketplacePlugin, PluginCredentialField, PluginCredentialsConnect } from './plugin-types';\n\nexport type ConnectablePlugin = Pick<MarketplacePlugin, 'connect' | 'id' | 'name'>;\n\n/** Longer than any credential a provider issues; the server rejects more. */\nexport const MAX_CREDENTIAL_VALUE_LENGTH = 4096;\n\n/**\n * The secrets a plugin's connect form takes that can be recognized on their\n * own (a distinctive prefix, say), each with that pattern and what to call it.\n */\nexport function pluginSecretFormats(plugin: ConnectablePlugin): Array<{ label: string; pattern: string }> {\n const { connect } = plugin;\n\n if (connect?.type === 'api-token') {\n return connect.pattern ? [{ label: connect.tokenLabel, pattern: connect.pattern }] : [];\n }\n\n if (connect?.type === 'credentials') {\n return [...connect.fields, ...connect.methods.flatMap((method) => method.fields)]\n .filter((field) => field.kind === 'secret' && field.detect)\n .map((field) => ({ label: field.label, pattern: field.detect! }));\n }\n\n return [];\n}\n\n/** The fields a credentials form shows: the shared ones, then those of the chosen method. */\nexport function credentialFormFields(connect: PluginCredentialsConnect, method: string | null): PluginCredentialField[] {\n const selected = connect.methods.find((item) => item.key === method);\n\n return [...connect.fields, ...(selected?.fields ?? [])];\n}\n\n/** Whether every required field has a value: what the Connect button waits for. */\nexport function credentialFormComplete(\n fields: readonly PluginCredentialField[],\n values: { [key: string]: string }\n): boolean {\n return fields.every((field) => !field.required || Boolean(values[field.key]?.trim()));\n}\n\n/** The first problem with the values entered, or null when they can be submitted. */\nexport function credentialFormError(\n fields: readonly PluginCredentialField[],\n values: { [key: string]: string }\n): { field: string; message: string } | null {\n for (const field of fields) {\n const value = values[field.key]?.trim() ?? '';\n\n if (!value) {\n if (field.required) {\n return { field: field.key, message: `Enter the ${field.label}.` };\n }\n\n continue;\n }\n\n if (value.length > MAX_CREDENTIAL_VALUE_LENGTH) {\n return { field: field.key, message: `The ${field.label} is too long; paste only the value.` };\n }\n\n if (!matchesTokenPattern(value, field.pattern)) {\n return { field: field.key, message: `That is not a valid ${field.label}.` };\n }\n }\n\n return null;\n}\n\nexport function matchesTokenPattern(token: string, pattern: string | null): boolean {\n if (!pattern) {\n return true;\n }\n\n try {\n return new RegExp(pattern, 'u').test(token);\n } catch {\n // The server validates the pattern when it admits the plugin; never block on a bad one here.\n return true;\n }\n}\n\n/** A pattern that compiles; an empty or broken one detects nothing rather than every word. */\nfunction compileTokenPattern(pattern: string | null): RegExp | null {\n if (!pattern) {\n return null;\n }\n\n try {\n return new RegExp(pattern, 'u');\n } catch {\n return null;\n }\n}\n\n/**\n * The first plugin whose secret format `text` contains, if any, with every\n * secret-shaped word in the message and what the plugin calls that secret: a\n * token pasted into the chat would be stored in the conversation and sent to\n * the model.\n */\nexport function findPastedPluginToken(\n text: string,\n plugins: readonly ConnectablePlugin[]\n): { plugin: ConnectablePlugin; tokens: string[]; label: string } | null {\n // A token is often glued to a label (`token=…`, `key: …`) or wrapped in\n // brackets, quotes or a sentence's punctuation; none of those are part of it.\n const words = text\n .split(/[\\s\"'`()<>[\\]{},;:=!?&]+/)\n .map((word) => word.replace(/\\.+$/, ''))\n .filter(Boolean);\n let found: { plugin: ConnectablePlugin; label: string } | null = null;\n const tokens = new Set<string>();\n\n for (const plugin of plugins) {\n for (const format of pluginSecretFormats(plugin)) {\n const pattern = compileTokenPattern(format.pattern);\n\n for (const word of pattern ? words : []) {\n if (pattern!.test(word)) {\n found ??= { plugin, label: format.label };\n tokens.add(word);\n }\n }\n }\n }\n\n return found ? { ...found, tokens: [...tokens] } : null;\n}\n","import type { FormEvent, JSX } from 'react';\nimport { useId, useState, useSyncExternalStore } from 'react';\nimport { ExternalLinkIcon, LoaderCircle } from 'lucide-react';\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n} from '../../ui';\nimport type { ApiClient } from './api';\nimport { connectPluginPopup } from './plugin-oauth';\nimport {\n credentialFormComplete,\n credentialFormError,\n credentialFormFields,\n matchesTokenPattern,\n type ConnectablePlugin,\n} from './plugin-token-format';\nimport type { PluginApiTokenConnect, PluginCredentialsConnect, PluginScope } from './plugin-types';\n\ninterface TokenRequest {\n id: number;\n plugin: ConnectablePlugin & { connect: PluginApiTokenConnect };\n /** Saves the token; rejects with a message the dialog shows next to the field. */\n submit: (_token: string) => Promise<void>;\n settle: (_connected: boolean) => void;\n}\n\ninterface CredentialsRequest {\n id: number;\n plugin: ConnectablePlugin & { connect: PluginCredentialsConnect };\n /** Saves the form; rejects with a message the dialog shows under the fields. */\n submit: (_method: string | undefined, _values: { [key: string]: string }) => Promise<void>;\n settle: (_connected: boolean) => void;\n}\n\ntype FormRequest = ({ kind: 'token' } & TokenRequest) | ({ kind: 'credentials' } & CredentialsRequest);\n\n/** The one open connect form, outside React so any connect button can open it. */\nlet request: FormRequest | null = null;\nlet lastRequestId = 0;\n/** Cancels the latest request, whether its dialog has opened yet or not. */\nlet cancelLatest: (() => void) | null = null;\nconst listeners = new Set<() => void>();\n\nfunction setRequest(next: FormRequest | null): void {\n request = next;\n listeners.forEach((listener) => listener());\n}\n\nfunction subscribe(listener: () => void): () => void {\n listeners.add(listener);\n\n return () => listeners.delete(listener);\n}\n\n/**\n * Connects a plugin: a sign-in popup for OAuth plugins, the token dialog for\n * plugins that take a pasted token, the credentials dialog for plugins that\n * take the credentials of an app the user created at the provider. Resolves\n * `false` when the user closes a dialog without connecting.\n *\n * Call it straight from a click handler: browsers only allow the popup there.\n */\nexport function connectPlugin(\n api: ApiClient,\n plugin: ConnectablePlugin,\n scope: PluginScope,\n options?: { connectionId?: string }\n): Promise<boolean> {\n const { connect } = plugin;\n\n if (connect?.type !== 'api-token' && connect?.type !== 'credentials') {\n return connectPluginPopup(api, plugin.id, scope, options).then(() => true);\n }\n\n // Opening a second dialog closes the first, as if cancelled.\n cancelLatest?.();\n\n const id = ++lastRequestId;\n const connectionId = options?.connectionId ? { connectionId: options.connectionId } : {};\n\n return new Promise<boolean>((resolve) => {\n const settle = (connected: boolean): void => {\n // A save still running for a replaced dialog must not close its successor.\n if (request?.id === id) {\n setRequest(null);\n }\n\n if (lastRequestId === id) {\n cancelLatest = null;\n }\n\n resolve(connected);\n };\n const next: FormRequest =\n connect.type === 'api-token'\n ? {\n kind: 'token',\n id,\n plugin: { ...plugin, connect },\n submit: async (token) => {\n await api.connectPluginToken({ pluginId: plugin.id, scope, token, ...connectionId });\n },\n settle,\n }\n : {\n kind: 'credentials',\n id,\n plugin: { ...plugin, connect },\n submit: async (method, values) => {\n await api.connectPluginCredentials({ pluginId: plugin.id, scope, method, values, ...connectionId });\n },\n settle,\n };\n\n cancelLatest = () => settle(false);\n\n // Open after the current event: a menu item that started this closes first\n // and returns focus to its trigger, which would take it from the first field.\n setTimeout(() => {\n if (lastRequestId === id) {\n setRequest(next);\n }\n });\n });\n}\n\nfunction httpsHref(value: string | null): string | null {\n if (!value) {\n return null;\n }\n\n try {\n const url = new URL(value);\n\n return url.protocol === 'https:' ? url.href : null;\n } catch {\n return null;\n }\n}\n\n/** Mounted once by the Studio layout; renders the dialog `connectPlugin` opens for token and credentials plugins. */\nexport function PluginTokenDialogHost(): JSX.Element | null {\n const current = useSyncExternalStore(\n subscribe,\n () => request,\n () => null\n );\n\n if (!current) {\n return null;\n }\n\n // A new key per request resets the fields, so a secret never outlives its dialog.\n return current.kind === 'token' ? (\n <PluginTokenDialog key={current.id} request={current} />\n ) : (\n <PluginCredentialsDialog key={current.id} request={current} />\n );\n}\n\nfunction FieldError({ id, message }: { id: string; message: string | null }): JSX.Element | null {\n return message ? (\n <p className=\"fk:text-sm fk:text-destructive\" id={id}>\n {message}\n </p>\n ) : null;\n}\n\nfunction HelpLink({ href, label }: { href: string | null; label: string }): JSX.Element | null {\n const safeHref = httpsHref(href);\n\n return safeHref ? (\n <a\n className=\"fk:inline-flex fk:items-center fk:gap-1 fk:text-sm fk:text-muted-foreground fk:underline-offset-4 fk:hover:underline\"\n href={safeHref}\n rel=\"noreferrer\"\n target=\"_blank\"\n >\n {label}\n <ExternalLinkIcon className=\"fk:size-3.5\" />\n </a>\n ) : null;\n}\n\nfunction PluginCredentialsDialog({ request: current }: { request: CredentialsRequest }): JSX.Element {\n const { connect, name } = current.plugin;\n const formId = useId();\n const [method, setMethod] = useState<string | null>(connect.methods[0]?.key ?? null);\n const [values, setValues] = useState<{ [key: string]: string }>({});\n const [error, setError] = useState<{ field: string | null; message: string } | null>(null);\n const [saving, setSaving] = useState(false);\n const fields = credentialFormFields(connect, method);\n const selectedMethod = connect.methods.find((item) => item.key === method) ?? null;\n // Submitting surfaces which field is malformed; the button only waits for the required values.\n const ready = credentialFormComplete(fields, values);\n\n async function save(event: FormEvent): Promise<void> {\n event.preventDefault();\n\n if (saving) {\n return;\n }\n\n const problem = credentialFormError(fields, values);\n\n if (problem) {\n setError(problem);\n\n return;\n }\n\n setSaving(true);\n setError(null);\n\n try {\n await current.submit(\n method ?? undefined,\n Object.fromEntries(fields.map((field) => [field.key, values[field.key]?.trim() ?? '']).filter(([, value]) => value))\n );\n setValues({});\n current.settle(true);\n } catch (failure) {\n setError({ field: null, message: failure instanceof Error ? failure.message : `${name} could not be connected.` });\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <Dialog\n open\n onOpenChange={(open) => {\n if (!open && !saving) {\n current.settle(false);\n }\n }}\n >\n <DialogContent>\n <form className=\"fk:flex fk:flex-col fk:gap-4\" onSubmit={(event) => void save(event)}>\n <DialogHeader>\n <DialogTitle>Connect {name}</DialogTitle>\n <DialogDescription>\n {connect.description} Flexkit checks the credentials with {name}, stores them encrypted and sends them\n only to Flexkit's own {name} server; the agent can use the tools but never sees them.\n </DialogDescription>\n </DialogHeader>\n {connect.methods.length > 1 ? (\n <div className=\"fk:space-y-1.5\" role=\"group\" aria-label=\"How to connect\">\n {connect.methods.map((item) => (\n <button\n aria-pressed={method === item.key}\n className={`fk:flex fk:w-full fk:flex-col fk:rounded-lg fk:border fk:px-3 fk:py-2 fk:text-left fk:corner-squircle ${\n method === item.key ? 'fk:border-primary fk:bg-primary/5' : 'fk:border-border fk:hover:bg-muted/60'\n }`}\n disabled={saving}\n key={item.key}\n onClick={() => {\n setMethod(item.key);\n setError(null);\n }}\n type=\"button\"\n >\n <span className=\"fk:text-sm fk:font-medium\">{item.label}</span>\n {item.description ? (\n <span className=\"fk:text-xs fk:text-muted-foreground\">{item.description}</span>\n ) : null}\n </button>\n ))}\n </div>\n ) : selectedMethod?.description ? (\n <p className=\"fk:text-sm fk:text-muted-foreground\">{selectedMethod.description}</p>\n ) : null}\n {fields.map((field, index) => {\n const inputId = `${formId}-${field.key}`;\n const fieldError = error?.field === field.key ? error.message : null;\n\n return (\n <div className=\"fk:flex fk:flex-col fk:gap-2\" key={field.key}>\n <label className=\"fk:text-sm fk:font-medium\" htmlFor={inputId}>\n {field.label}\n </label>\n <Input\n aria-describedby={fieldError ? `${inputId}-error` : field.help ? `${inputId}-help` : undefined}\n aria-invalid={fieldError ? true : undefined}\n autoComplete=\"off\"\n autoFocus={index === 0}\n disabled={saving}\n id={inputId}\n placeholder={field.placeholder ?? undefined}\n spellCheck={false}\n type={field.kind === 'secret' ? 'password' : 'text'}\n value={values[field.key] ?? ''}\n onChange={(event) => {\n setValues((previous) => ({ ...previous, [field.key]: event.target.value }));\n setError(null);\n }}\n />\n {field.help && !fieldError ? (\n <p className=\"fk:text-sm fk:text-muted-foreground\" id={`${inputId}-help`}>\n {field.help}\n </p>\n ) : null}\n <FieldError id={`${inputId}-error`} message={fieldError} />\n </div>\n );\n })}\n <FieldError id={`${formId}-error`} message={error?.field === null ? error.message : null} />\n <HelpLink href={connect.helpUrl} label={`How to set up ${name}`} />\n <DialogFooter>\n <Button disabled={saving} size=\"sm\" type=\"button\" variant=\"outline\" onClick={() => current.settle(false)}>\n Cancel\n </Button>\n <Button disabled={saving || !ready} size=\"sm\" type=\"submit\">\n {saving ? <LoaderCircle className=\"fk:size-4 fk:animate-spin\" /> : null}\n Connect\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction PluginTokenDialog({ request: current }: { request: TokenRequest }): JSX.Element {\n const { connect, name } = current.plugin;\n const inputId = useId();\n const [token, setToken] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [saving, setSaving] = useState(false);\n\n async function save(event: FormEvent): Promise<void> {\n event.preventDefault();\n const value = token.trim();\n\n if (saving || !value) {\n return;\n }\n\n if (!matchesTokenPattern(value, connect.pattern)) {\n setError(`That does not look like a ${connect.tokenLabel}.`);\n\n return;\n }\n\n setSaving(true);\n setError(null);\n\n try {\n await current.submit(value);\n setToken('');\n current.settle(true);\n } catch (failure) {\n setError(failure instanceof Error ? failure.message : `${name} could not be connected.`);\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <Dialog\n open\n onOpenChange={(open) => {\n if (!open && !saving) {\n current.settle(false);\n }\n }}\n >\n <DialogContent>\n <form className=\"fk:flex fk:flex-col fk:gap-4\" onSubmit={(event) => void save(event)}>\n <DialogHeader>\n <DialogTitle>Connect {name}</DialogTitle>\n <DialogDescription>\n Paste a {connect.tokenLabel}. Flexkit stores it encrypted and sends it only to {name}; the agent can use{' '}\n {name}'s tools but never sees the token. Give it read access only, unless the agent should change\n things in {name}.\n </DialogDescription>\n </DialogHeader>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <label className=\"fk:text-sm fk:font-medium\" htmlFor={inputId}>\n {connect.tokenLabel}\n </label>\n <Input\n aria-describedby={error ? `${inputId}-error` : undefined}\n aria-invalid={error ? true : undefined}\n autoComplete=\"off\"\n autoFocus\n disabled={saving}\n id={inputId}\n placeholder={connect.placeholder ?? undefined}\n spellCheck={false}\n type=\"password\"\n value={token}\n onChange={(event) => {\n setToken(event.target.value);\n setError(null);\n }}\n />\n <FieldError id={`${inputId}-error`} message={error} />\n <HelpLink href={connect.helpUrl} label={`How to create a ${connect.tokenLabel}`} />\n </div>\n <DialogFooter>\n <Button disabled={saving} size=\"sm\" type=\"button\" variant=\"outline\" onClick={() => current.settle(false)}>\n Cancel\n </Button>\n <Button disabled={saving || !token.trim()} size=\"sm\" type=\"submit\">\n {saving ? <LoaderCircle className=\"fk:size-4 fk:animate-spin\" /> : null}\n Connect\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import'./index.css';import {g,f as f$1}from'./chunk-
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import'./index.css';import {g,f as f$1}from'./chunk-PLCI2RJA.js';import {b}from'./chunk-5CVDMZUI.js';import {a,b as b$1,c,e}from'./chunk-N33S7BSG.js';import {c as c$1}from'./chunk-X3SHNHHM.js';import {useEffect}from'react';import {BellIcon}from'lucide-react';import {Link}from'react-router-dom';import A from'swr';import {jsx,jsxs}from'react/jsx-runtime';function T(t){let{data:i}=A(t?g(t).activitySummary():null,f$1,{refreshInterval:3e4});return i}function f(t){return t>99?"99+":t.toString()}function $({projectId:t}){let i=T(t),e$1=i?.needsActionCount??0,r=i?.unreadCount??0;useEffect(()=>{let n=b();if(n)return n.setBadgeCount(e$1),()=>{n.setBadgeCount(0);}},[e$1]);let s=e$1>0?`Activity: ${f(e$1)} waiting for you`:r>0?`Activity: ${f(r)} unread`:"Activity";return jsx(a,{children:jsxs(b$1,{children:[jsx(c,{asChild:true,children:jsx(c$1,{asChild:true,"aria-label":s,className:"fk:relative fk:h-8 fk:w-8 fk:rounded-full",size:"icon",variant:"ghost",children:jsxs(Link,{to:`/${t}/ai/activity`,children:[jsx(BellIcon,{className:"fk:size-4"}),e$1>0?jsx("span",{className:"fk:absolute fk:-right-1 fk:-top-1 fk:flex fk:h-4 fk:min-w-4 fk:items-center fk:justify-center fk:rounded-full fk:bg-amber-500 fk:px-1 fk:text-[0.625rem] fk:font-semibold fk:leading-none fk:text-white",children:f(e$1)}):r>0?jsx("span",{className:"fk:absolute fk:right-1 fk:top-1 fk:size-2 fk:rounded-full fk:bg-success"}):null]})})}),jsx(e,{children:s})]})})}export{T as a,$ as b};//# sourceMappingURL=chunk-LVKBKU6Q.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-LVKBKU6Q.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/ai/activity-nav-button.tsx"],"names":["useActivitySummary","projectId","data","useSWR","paths","fetcher","formatCount","count","ActivityNavButton","summary","needsAction","unread","useEffect","desktop","getDesktop","label","jsx","TooltipProvider","jsxs","Tooltip","TooltipTrigger","Button","Link","BellIcon","TooltipContent"],"mappings":"mWAeO,SAASA,CAAAA,CAAmBC,EAA4D,CAC7F,GAAM,CAAE,IAAA,CAAAC,CAAK,EAAIC,CAAAA,CAAwBF,CAAAA,CAAYG,EAAMH,CAAS,CAAA,CAAE,iBAAgB,CAAI,IAAA,CAAMI,IAAS,CACvG,eAAA,CAAiB,GACnB,CAAC,CAAA,CAED,OAAOH,CACT,CAEA,SAASI,EAAYC,CAAAA,CAAuB,CAC1C,OAAOA,CAAAA,CAAQ,EAAA,CAAK,MAAQA,CAAAA,CAAM,QAAA,EACpC,CAGO,SAASC,EAAkB,CAAE,SAAA,CAAAP,CAAU,CAAA,CAAuC,CACnF,IAAMQ,CAAAA,CAAUT,CAAAA,CAAmBC,CAAS,CAAA,CACtCS,GAAAA,CAAcD,GAAS,gBAAA,EAAoB,CAAA,CAC3CE,EAASF,CAAAA,EAAS,WAAA,EAAe,EAGvCG,SAAAA,CAAU,IAAM,CACd,IAAMC,CAAAA,CAAUC,GAAW,CAE3B,GAAKD,EAIL,OAAAA,CAAAA,CAAQ,cAAcH,GAAW,CAAA,CAE1B,IAAM,CACXG,CAAAA,CAAQ,aAAA,CAAc,CAAC,EACzB,CACF,EAAG,CAACH,GAAW,CAAC,CAAA,CAEhB,IAAMK,EACJL,GAAAA,CAAc,CAAA,CACV,aAAaJ,CAAAA,CAAYI,GAAW,CAAC,CAAA,gBAAA,CAAA,CACrCC,CAAAA,CAAS,EACP,CAAA,UAAA,EAAaL,CAAAA,CAAYK,CAAM,CAAC,CAAA,OAAA,CAAA,CAChC,WAER,OACEK,GAAAA,CAACC,EAAA,CACC,QAAA,CAAAC,KAACC,GAAAA,CAAA,CACC,UAAAH,GAAAA,CAACI,CAAAA,CAAA,CAAe,OAAA,CAAO,IAAA,CACrB,SAAAJ,GAAAA,CAACK,GAAAA,CAAA,CAAO,OAAA,CAAO,IAAA,CAAC,YAAA,CAAYN,CAAAA,CAAO,SAAA,CAAU,2CAAA,CAA4C,KAAK,MAAA,CAAO,OAAA,CAAQ,QAC3G,QAAA,CAAAG,IAAAA,CAACI,KAAA,CAAK,EAAA,CAAI,IAAIrB,CAAS,CAAA,YAAA,CAAA,CACrB,UAAAe,GAAAA,CAACO,QAAAA,CAAA,CAAS,SAAA,CAAU,WAAA,CAAY,EAC/Bb,GAAAA,CAAc,CAAA,CACbM,GAAAA,CAAC,MAAA,CAAA,CAAK,SAAA,CAAU,yMAAA,CACb,SAAAV,CAAAA,CAAYI,GAAW,EAC1B,CAAA,CACEC,CAAAA,CAAS,EACXK,GAAAA,CAAC,MAAA,CAAA,CAAK,UAAU,yEAAA,CAA0E,CAAA,CACxF,MACN,CAAA,CACF,CAAA,CACF,EACAA,GAAAA,CAACQ,CAAAA,CAAA,CAAgB,QAAA,CAAAT,CAAAA,CAAM,CAAA,CAAA,CACzB,CAAA,CACF,CAEJ","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/apps/ai/activity-nav-button.tsx"],"names":["useActivitySummary","projectId","data","useSWR","paths","fetcher","formatCount","count","ActivityNavButton","summary","needsAction","unread","useEffect","desktop","getDesktop","label","jsx","TooltipProvider","jsxs","Tooltip","TooltipTrigger","Button","Link","BellIcon","TooltipContent"],"mappings":"mWAeO,SAASA,CAAAA,CAAmBC,EAA4D,CAC7F,GAAM,CAAE,IAAA,CAAAC,CAAK,EAAIC,CAAAA,CAAwBF,CAAAA,CAAYG,EAAMH,CAAS,CAAA,CAAE,iBAAgB,CAAI,IAAA,CAAMI,IAAS,CACvG,eAAA,CAAiB,GACnB,CAAC,CAAA,CAED,OAAOH,CACT,CAEA,SAASI,EAAYC,CAAAA,CAAuB,CAC1C,OAAOA,CAAAA,CAAQ,EAAA,CAAK,MAAQA,CAAAA,CAAM,QAAA,EACpC,CAGO,SAASC,EAAkB,CAAE,SAAA,CAAAP,CAAU,CAAA,CAAuC,CACnF,IAAMQ,CAAAA,CAAUT,CAAAA,CAAmBC,CAAS,CAAA,CACtCS,GAAAA,CAAcD,GAAS,gBAAA,EAAoB,CAAA,CAC3CE,EAASF,CAAAA,EAAS,WAAA,EAAe,EAGvCG,SAAAA,CAAU,IAAM,CACd,IAAMC,CAAAA,CAAUC,GAAW,CAE3B,GAAKD,EAIL,OAAAA,CAAAA,CAAQ,cAAcH,GAAW,CAAA,CAE1B,IAAM,CACXG,CAAAA,CAAQ,aAAA,CAAc,CAAC,EACzB,CACF,EAAG,CAACH,GAAW,CAAC,CAAA,CAEhB,IAAMK,EACJL,GAAAA,CAAc,CAAA,CACV,aAAaJ,CAAAA,CAAYI,GAAW,CAAC,CAAA,gBAAA,CAAA,CACrCC,CAAAA,CAAS,EACP,CAAA,UAAA,EAAaL,CAAAA,CAAYK,CAAM,CAAC,CAAA,OAAA,CAAA,CAChC,WAER,OACEK,GAAAA,CAACC,EAAA,CACC,QAAA,CAAAC,KAACC,GAAAA,CAAA,CACC,UAAAH,GAAAA,CAACI,CAAAA,CAAA,CAAe,OAAA,CAAO,IAAA,CACrB,SAAAJ,GAAAA,CAACK,GAAAA,CAAA,CAAO,OAAA,CAAO,IAAA,CAAC,YAAA,CAAYN,CAAAA,CAAO,SAAA,CAAU,2CAAA,CAA4C,KAAK,MAAA,CAAO,OAAA,CAAQ,QAC3G,QAAA,CAAAG,IAAAA,CAACI,KAAA,CAAK,EAAA,CAAI,IAAIrB,CAAS,CAAA,YAAA,CAAA,CACrB,UAAAe,GAAAA,CAACO,QAAAA,CAAA,CAAS,SAAA,CAAU,WAAA,CAAY,EAC/Bb,GAAAA,CAAc,CAAA,CACbM,GAAAA,CAAC,MAAA,CAAA,CAAK,SAAA,CAAU,yMAAA,CACb,SAAAV,CAAAA,CAAYI,GAAW,EAC1B,CAAA,CACEC,CAAAA,CAAS,EACXK,GAAAA,CAAC,MAAA,CAAA,CAAK,UAAU,yEAAA,CAA0E,CAAA,CACxF,MACN,CAAA,CACF,CAAA,CACF,EACAA,GAAAA,CAACQ,CAAAA,CAAA,CAAgB,QAAA,CAAAT,CAAAA,CAAM,CAAA,CAAA,CACzB,CAAA,CACF,CAEJ","file":"chunk-LVKBKU6Q.js","sourcesContent":["import { useEffect } from 'react';\nimport type { JSX } from 'react';\nimport { BellIcon } from 'lucide-react';\nimport { Link } from 'react-router-dom';\nimport useSWR from 'swr';\nimport { Button } from '../../ui/primitives/button';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/primitives/tooltip';\nimport { getDesktop } from '../../core/desktop';\nimport { fetcher, paths } from './api';\nimport type { ActivitySummary } from './types';\n\n/**\n * The project's Activity badge counts. `ActivityNotifier` refreshes the same\n * SWR key on every poll, so every reader stays in sync with one request.\n */\nexport function useActivitySummary(projectId: string | undefined): ActivitySummary | undefined {\n const { data } = useSWR<ActivitySummary>(projectId ? paths(projectId).activitySummary() : null, fetcher, {\n refreshInterval: 30_000,\n });\n\n return data;\n}\n\nfunction formatCount(count: number): string {\n return count > 99 ? '99+' : count.toString();\n}\n\n/** Navbar shortcut to Activity, so pending items are visible from every app. */\nexport function ActivityNavButton({ projectId }: { projectId: string }): JSX.Element {\n const summary = useActivitySummary(projectId);\n const needsAction = summary?.needsActionCount ?? 0;\n const unread = summary?.unreadCount ?? 0;\n // The desktop app shows what waits for you on its dock or taskbar icon;\n // leaving the project or signing out clears it.\n useEffect(() => {\n const desktop = getDesktop();\n\n if (!desktop) {\n return;\n }\n\n desktop.setBadgeCount(needsAction);\n\n return () => {\n desktop.setBadgeCount(0);\n };\n }, [needsAction]);\n\n const label =\n needsAction > 0\n ? `Activity: ${formatCount(needsAction)} waiting for you`\n : unread > 0\n ? `Activity: ${formatCount(unread)} unread`\n : 'Activity';\n\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button asChild aria-label={label} className=\"fk:relative fk:h-8 fk:w-8 fk:rounded-full\" size=\"icon\" variant=\"ghost\">\n <Link to={`/${projectId}/ai/activity`}>\n <BellIcon className=\"fk:size-4\" />\n {needsAction > 0 ? (\n <span className=\"fk:absolute fk:-right-1 fk:-top-1 fk:flex fk:h-4 fk:min-w-4 fk:items-center fk:justify-center fk:rounded-full fk:bg-amber-500 fk:px-1 fk:text-[0.625rem] fk:font-semibold fk:leading-none fk:text-white\">\n {formatCount(needsAction)}\n </span>\n ) : unread > 0 ? (\n <span className=\"fk:absolute fk:right-1 fk:top-1 fk:size-2 fk:rounded-full fk:bg-success\" />\n ) : null}\n </Link>\n </Button>\n </TooltipTrigger>\n <TooltipContent>{label}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import'./index.css';import {d as d$1}from'./chunk-
|
|
2
|
-
`)}var x=["Which variants are running low on stock, and what is already on order?","Why are Orb Pendant Lamps being returned? Look at the returns, reviews and support tickets.","Which products are missing prices, titles or SEO copy in the UK or US?","Show last month\u2019s revenue by market and sales channel.","Which open support tickets need attention today?"],v=["Design a schema for my business. Ask me what you need to know first.","Set up a product catalog with variants, prices per market and stock per warehouse.","Help me import my products from a spreadsheet."];function _(t){let e=t.trim();return e?e.length>48?"Project names can be up to 48 characters.":null:"Give your project a name."}function O(t,e,a){switch(t){case "starter":return {kind:"starter",template:"commerce",sampleData:e};case "describe":return {kind:"describe",description:a};case "empty":return {kind:"empty"}}}var h=2e3,f=300,u=new Set;async function y(t){let e=await fetch(i(t),{credentials:"include"});return e.ok?(await e.json()).starter??"missing":null}function k(t){return t.state==="seeding"||t.state==="completed"}function F({fetchStatus:t,projectId:e,publish:a=r=>mutate(i(e),{starter:r},{revalidate:false}),revalidate:c=d$1,sleep:s=r=>new Promise(o=>setTimeout(o,r))}){if(u.has(e))return;u.add(e);let r=t??(()=>y(e));(async()=>{let o=false;try{for(let l=0;l<f;l+=1){await s(h);let n=null;try{n=await r();}catch{n=null;}if(n==="missing")return;if(n!==null&&(await a(n),!o&&k(n)&&(o=!0,await c(e)),!g(n)))return}}finally{u.delete(e);}})();}export{i as a,d as b,w as c,b as d,g as e,T as f,x as g,v as h,_ as i,O as j,k,F as l};//# sourceMappingURL=chunk-
|
|
3
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import'./index.css';import {d as d$1}from'./chunk-CC2U7ASG.js';import {c}from'./chunk-MBBE4RND.js';import {mutate}from'swr';function i(t){return `/api/flexkit/${t}/starter`}async function d(t,e,a,c="Something went wrong. Please try again."){try{let s=await fetch(t,{method:e,credentials:"same-origin",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)}),r=await s.json().catch(()=>({}));return s.ok?{...r,ok:!0}:{ok:!1,code:r.code??"unknown_error",message:r.error??c}}catch{return {ok:false,code:"network_error",message:"Flexkit is not reachable. Check your connection and try again."}}}function w(t){return d(c.me,"PATCH",{displayName:t})}function b(t,e){return d(i(t),"POST",e)}function g(t){return t?.state==="queued"||t?.state==="deploying"||t?.state==="seeding"}function T(t){return [`I'm setting up Flexkit for my business: ${t.trim()}`,"","Design a schema for it: propose the entities, fields and relationships we need to run it day to day, and market scopes if we sell in more than one market. Keep it practical and complete enough to use from the start. Once the schema is deployed, offer to add a few realistic sample records."].join(`
|
|
2
|
+
`)}var x=["Which variants are running low on stock, and what is already on order?","Why are Orb Pendant Lamps being returned? Look at the returns, reviews and support tickets.","Which products are missing prices, titles or SEO copy in the UK or US?","Show last month\u2019s revenue by market and sales channel.","Which open support tickets need attention today?"],v=["Design a schema for my business. Ask me what you need to know first.","Set up a product catalog with variants, prices per market and stock per warehouse.","Help me import my products from a spreadsheet."];function _(t){let e=t.trim();return e?e.length>48?"Project names can be up to 48 characters.":null:"Give your project a name."}function O(t,e,a){switch(t){case "starter":return {kind:"starter",template:"commerce",sampleData:e};case "describe":return {kind:"describe",description:a};case "empty":return {kind:"empty"}}}var h=2e3,f=300,u=new Set;async function y(t){let e=await fetch(i(t),{credentials:"include"});return e.ok?(await e.json()).starter??"missing":null}function k(t){return t.state==="seeding"||t.state==="completed"}function F({fetchStatus:t,projectId:e,publish:a=r=>mutate(i(e),{starter:r},{revalidate:false}),revalidate:c=d$1,sleep:s=r=>new Promise(o=>setTimeout(o,r))}){if(u.has(e))return;u.add(e);let r=t??(()=>y(e));(async()=>{let o=false;try{for(let l=0;l<f;l+=1){await s(h);let n=null;try{n=await r();}catch{n=null;}if(n==="missing")return;if(n!==null&&(await a(n),!o&&k(n)&&(o=!0,await c(e)),!g(n)))return}}finally{u.delete(e);}})();}export{i as a,d as b,w as c,b as d,g as e,T as f,x as g,v as h,_ as i,O as j,k,F as l};//# sourceMappingURL=chunk-ND2RTUMM.js.map
|
|
3
|
+
//# sourceMappingURL=chunk-ND2RTUMM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/config/onboarding.ts","../src/apps/ai/starter-watch.ts"],"names":["starterPath","projectId","send","url","method","body","fallbackMessage","response","json","saveDisplayName","displayName","userApiPaths","applyStarter","starter","isStarterRunning","status","describeBusinessPrompt","description","COMMERCE_STARTER_PROMPTS","EMPTY_STARTER_PROMPTS","validateProjectName","name","trimmed","toProjectStart","kind","sampleData","POLL_INTERVAL_MS","POLL_LIMIT","watching","fetchStarter","starterSchemaDeployed","watchStarter","fetchStatus","publish","mutate","revalidate","revalidateProjectSchema","sleep","ms","resolve","load","schemaLoaded","attempt"],"mappings":"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","file":"chunk-PWGLA33F.js","sourcesContent":["import { userApiPaths } from '../api-paths';\n\n/** Starter templates a new project can begin from; the backend owns their schema and sample data. */\nexport type StarterTemplate = 'commerce';\n\nexport type StarterStatus = {\n template: StarterTemplate;\n sampleData: boolean;\n state: 'queued' | 'deploying' | 'seeding' | 'completed' | 'failed';\n progress?: { done: number; total: number };\n error?: string;\n completedAt?: string;\n};\n\n/** How the user chose to start a new project, carried to its AI chat in the navigation state. */\nexport type ProjectStart =\n | { kind: 'starter'; template: StarterTemplate; sampleData: boolean }\n | { kind: 'describe'; description: string }\n | { kind: 'empty' };\n\n/** Navigation state the onboarding hands the AI chat of a new project. */\nexport type OnboardingNavigationState = { onboardingPrompt?: string };\n\nexport function starterPath(projectId: string): string {\n return `/api/flexkit/${projectId}/starter`;\n}\n\nexport type Failure = { ok: false; code: string; message: string };\n\n/** A JSON request to the hosted BFF, with its failures mapped to a message the UI can show. */\nexport async function send<T>(\n url: string,\n method: 'PATCH' | 'POST',\n body: unknown,\n fallbackMessage = 'Something went wrong. Please try again.'\n): Promise<({ ok: true } & T) | Failure> {\n try {\n const response = await fetch(url, {\n method,\n credentials: 'same-origin',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n const json = (await response.json().catch(() => ({}))) as { code?: string; error?: string } & T;\n\n if (response.ok) {\n return { ...json, ok: true };\n }\n\n return {\n ok: false,\n code: json.code ?? 'unknown_error',\n message: json.error ?? fallbackMessage,\n };\n } catch {\n return {\n ok: false,\n code: 'network_error',\n message: 'Flexkit is not reachable. Check your connection and try again.',\n };\n }\n}\n\n/** Hosted mode: saves the signed-in user's display name. */\nexport function saveDisplayName(displayName: string): Promise<{ ok: true } | Failure> {\n return send(userApiPaths.me, 'PATCH', { displayName });\n}\n\n/** Applies a starter template to a new, empty project; the schema and sample data arrive in the background. */\nexport function applyStarter(\n projectId: string,\n starter: { template: StarterTemplate; sampleData: boolean }\n): Promise<({ ok: true } & { starter: StarterStatus }) | Failure> {\n return send<{ starter: StarterStatus }>(starterPath(projectId), 'POST', starter);\n}\n\nexport function isStarterRunning(status: StarterStatus | null | undefined): boolean {\n return status?.state === 'queued' || status?.state === 'deploying' || status?.state === 'seeding';\n}\n\n/** The first message of a project whose owner described the business instead of picking a template. */\nexport function describeBusinessPrompt(description: string): string {\n return [\n `I'm setting up Flexkit for my business: ${description.trim()}`,\n '',\n 'Design a schema for it: propose the entities, fields and relationships we need to run it day to day, and market scopes if we sell in more than one market. Keep it practical and complete enough to use from the start. Once the schema is deployed, offer to add a few realistic sample records.',\n ].join('\\n');\n}\n\n/** Questions the commerce sample store can answer; each one finds a problem planted in the data. */\nexport const COMMERCE_STARTER_PROMPTS = [\n 'Which variants are running low on stock, and what is already on order?',\n 'Why are Orb Pendant Lamps being returned? Look at the returns, reviews and support tickets.',\n 'Which products are missing prices, titles or SEO copy in the UK or US?',\n 'Show last month’s revenue by market and sales channel.',\n 'Which open support tickets need attention today?',\n] as const;\n\nexport const EMPTY_STARTER_PROMPTS = [\n 'Design a schema for my business. Ask me what you need to know first.',\n 'Set up a product catalog with variants, prices per market and stock per warehouse.',\n 'Help me import my products from a spreadsheet.',\n] as const;\n\n/** Only what the field can tell; the backend owns the character rules and says what it refuses. */\nexport function validateProjectName(name: string): string | null {\n const trimmed = name.trim();\n\n if (!trimmed) {\n return 'Give your project a name.';\n }\n\n if (trimmed.length > 48) {\n return 'Project names can be up to 48 characters.';\n }\n\n return null;\n}\n\n/** The choice on the last step, as sent to the backend and the AI chat. */\nexport function toProjectStart(kind: ProjectStart['kind'], sampleData: boolean, description: string): ProjectStart {\n switch (kind) {\n case 'starter':\n return { kind: 'starter', template: 'commerce', sampleData };\n case 'describe':\n return { kind: 'describe', description };\n case 'empty':\n return { kind: 'empty' };\n }\n}\n","import { mutate } from 'swr';\nimport { isStarterRunning, starterPath, type StarterStatus } from '../../core/config/onboarding';\nimport { revalidateProjectSchema } from '../../core/config/use-project-schemas';\n\nconst POLL_INTERVAL_MS = 2_000;\n/** About ten minutes; a starter usually finishes in two. */\nconst POLL_LIMIT = 300;\nconst watching = new Set<string>();\n\n/** `null` = transient failure (keep polling). */\nexport type StarterFetcher = () => Promise<StarterStatus | null | 'missing'>;\n\nasync function fetchStarter(projectId: string): Promise<StarterStatus | null | 'missing'> {\n const response = await fetch(starterPath(projectId), { credentials: 'include' });\n\n if (!response.ok) {\n return null;\n }\n\n const body = (await response.json()) as { starter?: StarterStatus | null };\n\n return body.starter ?? 'missing';\n}\n\n/** The schema is live once the starter got past its deploy. */\nexport function starterSchemaDeployed(status: StarterStatus): boolean {\n return status.state === 'seeding' || status.state === 'completed';\n}\n\n/**\n * Follows a running starter until it settles, independently of which\n * component started it and of navigation inside the Studio. Shares its\n * results through the SWR cache of `starterPath`, and reloads the project\n * schema once, as soon as the starter's schema is deployed.\n */\nexport function watchStarter({\n fetchStatus,\n projectId,\n publish = (status) => mutate(starterPath(projectId), { starter: status }, { revalidate: false }),\n revalidate = revalidateProjectSchema,\n sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)),\n}: {\n fetchStatus?: StarterFetcher;\n projectId: string;\n publish?: (_status: StarterStatus) => Promise<unknown>;\n revalidate?: (_projectId: string) => Promise<unknown>;\n sleep?: (_ms: number) => Promise<void>;\n}): void {\n if (watching.has(projectId)) {\n return;\n }\n\n watching.add(projectId);\n\n const load = fetchStatus ?? (() => fetchStarter(projectId));\n\n void (async () => {\n let schemaLoaded = false;\n\n try {\n for (let attempt = 0; attempt < POLL_LIMIT; attempt += 1) {\n await sleep(POLL_INTERVAL_MS);\n\n let status: StarterStatus | null | 'missing' = null;\n\n try {\n status = await load();\n } catch {\n status = null;\n }\n\n if (status === 'missing') {\n return;\n }\n\n if (status === null) {\n continue;\n }\n\n await publish(status);\n\n if (!schemaLoaded && starterSchemaDeployed(status)) {\n schemaLoaded = true;\n await revalidate(projectId);\n }\n\n if (!isStarterRunning(status)) {\n return;\n }\n }\n } finally {\n watching.delete(projectId);\n }\n })();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/config/onboarding.ts","../src/apps/ai/starter-watch.ts"],"names":["starterPath","projectId","send","url","method","body","fallbackMessage","response","json","saveDisplayName","displayName","userApiPaths","applyStarter","starter","isStarterRunning","status","describeBusinessPrompt","description","COMMERCE_STARTER_PROMPTS","EMPTY_STARTER_PROMPTS","validateProjectName","name","trimmed","toProjectStart","kind","sampleData","POLL_INTERVAL_MS","POLL_LIMIT","watching","fetchStarter","starterSchemaDeployed","watchStarter","fetchStatus","publish","mutate","revalidate","revalidateProjectSchema","sleep","ms","resolve","load","schemaLoaded","attempt"],"mappings":"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","file":"chunk-ND2RTUMM.js","sourcesContent":["import { userApiPaths } from '../api-paths';\n\n/** Starter templates a new project can begin from; the backend owns their schema and sample data. */\nexport type StarterTemplate = 'commerce';\n\nexport type StarterStatus = {\n template: StarterTemplate;\n sampleData: boolean;\n state: 'queued' | 'deploying' | 'seeding' | 'completed' | 'failed';\n progress?: { done: number; total: number };\n error?: string;\n completedAt?: string;\n};\n\n/** How the user chose to start a new project, carried to its AI chat in the navigation state. */\nexport type ProjectStart =\n | { kind: 'starter'; template: StarterTemplate; sampleData: boolean }\n | { kind: 'describe'; description: string }\n | { kind: 'empty' };\n\n/** Navigation state the onboarding hands the AI chat of a new project. */\nexport type OnboardingNavigationState = { onboardingPrompt?: string };\n\nexport function starterPath(projectId: string): string {\n return `/api/flexkit/${projectId}/starter`;\n}\n\nexport type Failure = { ok: false; code: string; message: string };\n\n/** A JSON request to the hosted BFF, with its failures mapped to a message the UI can show. */\nexport async function send<T>(\n url: string,\n method: 'PATCH' | 'POST',\n body: unknown,\n fallbackMessage = 'Something went wrong. Please try again.'\n): Promise<({ ok: true } & T) | Failure> {\n try {\n const response = await fetch(url, {\n method,\n credentials: 'same-origin',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n const json = (await response.json().catch(() => ({}))) as { code?: string; error?: string } & T;\n\n if (response.ok) {\n return { ...json, ok: true };\n }\n\n return {\n ok: false,\n code: json.code ?? 'unknown_error',\n message: json.error ?? fallbackMessage,\n };\n } catch {\n return {\n ok: false,\n code: 'network_error',\n message: 'Flexkit is not reachable. Check your connection and try again.',\n };\n }\n}\n\n/** Hosted mode: saves the signed-in user's display name. */\nexport function saveDisplayName(displayName: string): Promise<{ ok: true } | Failure> {\n return send(userApiPaths.me, 'PATCH', { displayName });\n}\n\n/** Applies a starter template to a new, empty project; the schema and sample data arrive in the background. */\nexport function applyStarter(\n projectId: string,\n starter: { template: StarterTemplate; sampleData: boolean }\n): Promise<({ ok: true } & { starter: StarterStatus }) | Failure> {\n return send<{ starter: StarterStatus }>(starterPath(projectId), 'POST', starter);\n}\n\nexport function isStarterRunning(status: StarterStatus | null | undefined): boolean {\n return status?.state === 'queued' || status?.state === 'deploying' || status?.state === 'seeding';\n}\n\n/** The first message of a project whose owner described the business instead of picking a template. */\nexport function describeBusinessPrompt(description: string): string {\n return [\n `I'm setting up Flexkit for my business: ${description.trim()}`,\n '',\n 'Design a schema for it: propose the entities, fields and relationships we need to run it day to day, and market scopes if we sell in more than one market. Keep it practical and complete enough to use from the start. Once the schema is deployed, offer to add a few realistic sample records.',\n ].join('\\n');\n}\n\n/** Questions the commerce sample store can answer; each one finds a problem planted in the data. */\nexport const COMMERCE_STARTER_PROMPTS = [\n 'Which variants are running low on stock, and what is already on order?',\n 'Why are Orb Pendant Lamps being returned? Look at the returns, reviews and support tickets.',\n 'Which products are missing prices, titles or SEO copy in the UK or US?',\n 'Show last month’s revenue by market and sales channel.',\n 'Which open support tickets need attention today?',\n] as const;\n\nexport const EMPTY_STARTER_PROMPTS = [\n 'Design a schema for my business. Ask me what you need to know first.',\n 'Set up a product catalog with variants, prices per market and stock per warehouse.',\n 'Help me import my products from a spreadsheet.',\n] as const;\n\n/** Only what the field can tell; the backend owns the character rules and says what it refuses. */\nexport function validateProjectName(name: string): string | null {\n const trimmed = name.trim();\n\n if (!trimmed) {\n return 'Give your project a name.';\n }\n\n if (trimmed.length > 48) {\n return 'Project names can be up to 48 characters.';\n }\n\n return null;\n}\n\n/** The choice on the last step, as sent to the backend and the AI chat. */\nexport function toProjectStart(kind: ProjectStart['kind'], sampleData: boolean, description: string): ProjectStart {\n switch (kind) {\n case 'starter':\n return { kind: 'starter', template: 'commerce', sampleData };\n case 'describe':\n return { kind: 'describe', description };\n case 'empty':\n return { kind: 'empty' };\n }\n}\n","import { mutate } from 'swr';\nimport { isStarterRunning, starterPath, type StarterStatus } from '../../core/config/onboarding';\nimport { revalidateProjectSchema } from '../../core/config/use-project-schemas';\n\nconst POLL_INTERVAL_MS = 2_000;\n/** About ten minutes; a starter usually finishes in two. */\nconst POLL_LIMIT = 300;\nconst watching = new Set<string>();\n\n/** `null` = transient failure (keep polling). */\nexport type StarterFetcher = () => Promise<StarterStatus | null | 'missing'>;\n\nasync function fetchStarter(projectId: string): Promise<StarterStatus | null | 'missing'> {\n const response = await fetch(starterPath(projectId), { credentials: 'include' });\n\n if (!response.ok) {\n return null;\n }\n\n const body = (await response.json()) as { starter?: StarterStatus | null };\n\n return body.starter ?? 'missing';\n}\n\n/** The schema is live once the starter got past its deploy. */\nexport function starterSchemaDeployed(status: StarterStatus): boolean {\n return status.state === 'seeding' || status.state === 'completed';\n}\n\n/**\n * Follows a running starter until it settles, independently of which\n * component started it and of navigation inside the Studio. Shares its\n * results through the SWR cache of `starterPath`, and reloads the project\n * schema once, as soon as the starter's schema is deployed.\n */\nexport function watchStarter({\n fetchStatus,\n projectId,\n publish = (status) => mutate(starterPath(projectId), { starter: status }, { revalidate: false }),\n revalidate = revalidateProjectSchema,\n sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)),\n}: {\n fetchStatus?: StarterFetcher;\n projectId: string;\n publish?: (_status: StarterStatus) => Promise<unknown>;\n revalidate?: (_projectId: string) => Promise<unknown>;\n sleep?: (_ms: number) => Promise<void>;\n}): void {\n if (watching.has(projectId)) {\n return;\n }\n\n watching.add(projectId);\n\n const load = fetchStatus ?? (() => fetchStarter(projectId));\n\n void (async () => {\n let schemaLoaded = false;\n\n try {\n for (let attempt = 0; attempt < POLL_LIMIT; attempt += 1) {\n await sleep(POLL_INTERVAL_MS);\n\n let status: StarterStatus | null | 'missing' = null;\n\n try {\n status = await load();\n } catch {\n status = null;\n }\n\n if (status === 'missing') {\n return;\n }\n\n if (status === null) {\n continue;\n }\n\n await publish(status);\n\n if (!schemaLoaded && starterSchemaDeployed(status)) {\n schemaLoaded = true;\n await revalidate(projectId);\n }\n\n if (!isStarterRunning(status)) {\n return;\n }\n }\n } finally {\n watching.delete(projectId);\n }\n })();\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import'./index.css';import {f as f$1}from'./chunk-
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import'./index.css';import {f as f$1}from'./chunk-DO32GATF.js';import {f as f$2}from'./chunk-CC2U7ASG.js';import {createContext,useReducer,useContext}from'react';import {jsx}from'react/jsx-runtime';var d="core.context.scope:",a={breadcrumbs:[],isRouteLoading:false,pageTitle:"",scope:"",relationships:{}},u=createContext(a),l=createContext(()=>{});function f(e,t){let{type:n,payload:o}=t;switch(n){case "setScope":return typeof localStorage<"u"&&o.projectId&&localStorage.setItem(`${d}${o.projectId}`,o.scope),{...e,scope:o.scope};case "setRelationship":return {...e,relationships:{...e.relationships,...o}};default:throw Error(`Unknown action: ${n}`)}}function x({children:e}){let[t,n]=useReducer(f,a);return jsx(u.Provider,{value:t,children:jsx(l.Provider,{value:n,children:e})})}function m(){return useContext(u)}function C(){return useContext(l)}function A(e){return e?.find(t=>t.isDefault)?.name??e?.[0]?.name??f$1}function E(){let{currentProject:e}=f$2();return A(e?.scopes)}export{d as a,x as b,m as c,C as d,A as e,E as f};//# sourceMappingURL=chunk-OWY5BQER.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-OWY5BQER.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/app-context.tsx","../src/core/default-scope.ts"],"names":["SCOPE_STORAGE_KEY","initialState","AppContext","createContext","AppDispatchContext","reducer","state","action","type","payload","AppProvider","children","dispatch","useReducer","jsx","useAppContext","useContext","useAppDispatch","defaultScopeName","scopes","scope","DEFAULT_SCOPE_KEY","useDefaultScope","currentProject","useConfig"],"mappings":"sMAMO,IAAMA,CAAAA,CAAoB,sBAE3BC,CAAAA,CAAe,CACnB,YAAa,EAAC,CACd,eAAgB,KAAA,CAChB,SAAA,CAAW,GACX,KAAA,CAAO,EAAA,CACP,cAAe,EACjB,EAEMC,CAAAA,CAAaC,aAAAA,CAA8BF,CAAY,CAAA,CAEvDG,CAAAA,CAAqBD,cAAgE,IAAM,CAEjG,CAAC,EAED,SAASE,EAAQC,CAAAA,CAAuBC,CAAAA,CAAgE,CACtG,GAAM,CAAE,KAAAC,CAAAA,CAAM,OAAA,CAAAC,CAAQ,CAAA,CAAIF,CAAAA,CAE1B,OAAQC,CAAAA,EACN,KAAK,UAAA,CACH,OAAI,OAAO,YAAA,CAAiB,GAAA,EAAeC,EAAQ,SAAA,EACjD,YAAA,CAAa,QAAQ,CAAA,EAAGT,CAAiB,GAAGS,CAAAA,CAAQ,SAAS,GAAIA,CAAAA,CAAQ,KAAK,EAGzE,CACL,GAAGH,EACH,KAAA,CAAOG,CAAAA,CAAQ,KACjB,CAAA,CACF,KAAK,kBACH,OAAO,CACL,GAAGH,CAAAA,CACH,aAAA,CAAe,CAAE,GAAGA,CAAAA,CAAM,cAAe,GAAGG,CAAQ,CACtD,CAAA,CACF,QACE,MAAM,KAAA,CAAM,CAAA,gBAAA,EAAmBD,CAAc,CAAA,CAAE,CACnD,CACF,CAEO,SAASE,EAAY,CAAE,QAAA,CAAAC,CAAS,CAAA,CAAyC,CAC9E,GAAM,CAACL,CAAAA,CAAOM,CAAQ,CAAA,CAAIC,UAAAA,CAAWR,EAASJ,CAAY,CAAA,CAE1D,OACEa,GAAAA,CAACZ,CAAAA,CAAW,SAAX,CAAoB,KAAA,CAAOI,EAC1B,QAAA,CAAAQ,GAAAA,CAACV,EAAmB,QAAA,CAAnB,CAA4B,MAAOQ,CAAAA,CAAW,QAAA,CAAAD,EAAS,CAAA,CAC1D,CAEJ,CAEO,SAASI,CAAAA,EAAgC,CAC9C,OAAOC,UAAAA,CAAWd,CAAU,CAC9B,CAEO,SAASe,CAAAA,EAAmE,CACjF,OAAOD,UAAAA,CAAWZ,CAAkB,CACtC,CCpDO,SAASc,EAAiBC,CAAAA,CAAyD,CACxF,OAAOA,CAAAA,EAAQ,IAAA,CAAMC,GAAUA,CAAAA,CAAM,SAAS,GAAG,IAAA,EAAQD,CAAAA,GAAS,CAAC,CAAA,EAAG,IAAA,EAAQE,GAChF,CAGO,SAASC,GAA0B,CACxC,GAAM,CAAE,cAAA,CAAAC,CAAe,EAAIC,GAAAA,EAAU,CAErC,OAAON,CAAAA,CAAiBK,CAAAA,EAAgB,MAAM,CAChD","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/core/app-context.tsx","../src/core/default-scope.ts"],"names":["SCOPE_STORAGE_KEY","initialState","AppContext","createContext","AppDispatchContext","reducer","state","action","type","payload","AppProvider","children","dispatch","useReducer","jsx","useAppContext","useContext","useAppDispatch","defaultScopeName","scopes","scope","DEFAULT_SCOPE_KEY","useDefaultScope","currentProject","useConfig"],"mappings":"sMAMO,IAAMA,CAAAA,CAAoB,sBAE3BC,CAAAA,CAAe,CACnB,YAAa,EAAC,CACd,eAAgB,KAAA,CAChB,SAAA,CAAW,GACX,KAAA,CAAO,EAAA,CACP,cAAe,EACjB,EAEMC,CAAAA,CAAaC,aAAAA,CAA8BF,CAAY,CAAA,CAEvDG,CAAAA,CAAqBD,cAAgE,IAAM,CAEjG,CAAC,EAED,SAASE,EAAQC,CAAAA,CAAuBC,CAAAA,CAAgE,CACtG,GAAM,CAAE,KAAAC,CAAAA,CAAM,OAAA,CAAAC,CAAQ,CAAA,CAAIF,CAAAA,CAE1B,OAAQC,CAAAA,EACN,KAAK,UAAA,CACH,OAAI,OAAO,YAAA,CAAiB,GAAA,EAAeC,EAAQ,SAAA,EACjD,YAAA,CAAa,QAAQ,CAAA,EAAGT,CAAiB,GAAGS,CAAAA,CAAQ,SAAS,GAAIA,CAAAA,CAAQ,KAAK,EAGzE,CACL,GAAGH,EACH,KAAA,CAAOG,CAAAA,CAAQ,KACjB,CAAA,CACF,KAAK,kBACH,OAAO,CACL,GAAGH,CAAAA,CACH,aAAA,CAAe,CAAE,GAAGA,CAAAA,CAAM,cAAe,GAAGG,CAAQ,CACtD,CAAA,CACF,QACE,MAAM,KAAA,CAAM,CAAA,gBAAA,EAAmBD,CAAc,CAAA,CAAE,CACnD,CACF,CAEO,SAASE,EAAY,CAAE,QAAA,CAAAC,CAAS,CAAA,CAAyC,CAC9E,GAAM,CAACL,CAAAA,CAAOM,CAAQ,CAAA,CAAIC,UAAAA,CAAWR,EAASJ,CAAY,CAAA,CAE1D,OACEa,GAAAA,CAACZ,CAAAA,CAAW,SAAX,CAAoB,KAAA,CAAOI,EAC1B,QAAA,CAAAQ,GAAAA,CAACV,EAAmB,QAAA,CAAnB,CAA4B,MAAOQ,CAAAA,CAAW,QAAA,CAAAD,EAAS,CAAA,CAC1D,CAEJ,CAEO,SAASI,CAAAA,EAAgC,CAC9C,OAAOC,UAAAA,CAAWd,CAAU,CAC9B,CAEO,SAASe,CAAAA,EAAmE,CACjF,OAAOD,UAAAA,CAAWZ,CAAkB,CACtC,CCpDO,SAASc,EAAiBC,CAAAA,CAAyD,CACxF,OAAOA,CAAAA,EAAQ,IAAA,CAAMC,GAAUA,CAAAA,CAAM,SAAS,GAAG,IAAA,EAAQD,CAAAA,GAAS,CAAC,CAAA,EAAG,IAAA,EAAQE,GAChF,CAGO,SAASC,GAA0B,CACxC,GAAM,CAAE,cAAA,CAAAC,CAAe,EAAIC,GAAAA,EAAU,CAErC,OAAON,CAAAA,CAAiBK,CAAAA,EAAgB,MAAM,CAChD","file":"chunk-OWY5BQER.js","sourcesContent":["'use client';\n\nimport { createContext, useContext, useReducer } from 'react';\nimport type { Dispatch, JSX, ReactNode } from 'react';\nimport type { ActionSetRelationship, ActionSetScope, AppContextType } from './types';\n\nexport const SCOPE_STORAGE_KEY = 'core.context.scope:';\n\nconst initialState = {\n breadcrumbs: [],\n isRouteLoading: false,\n pageTitle: '',\n scope: '',\n relationships: {},\n};\n\nconst AppContext = createContext<AppContextType>(initialState);\n\nconst AppDispatchContext = createContext<Dispatch<ActionSetRelationship | ActionSetScope>>(() => {\n /* void */\n});\n\nfunction reducer(state: AppContextType, action: ActionSetRelationship | ActionSetScope): AppContextType {\n const { type, payload } = action;\n\n switch (type) {\n case 'setScope':\n if (typeof localStorage !== 'undefined' && payload.projectId) {\n localStorage.setItem(`${SCOPE_STORAGE_KEY}${payload.projectId}`, payload.scope);\n }\n\n return {\n ...state,\n scope: payload.scope,\n };\n case 'setRelationship':\n return {\n ...state,\n relationships: { ...state.relationships, ...payload },\n };\n default:\n throw Error(`Unknown action: ${type as string}`);\n }\n}\n\nexport function AppProvider({ children }: { children: ReactNode }): JSX.Element {\n const [state, dispatch] = useReducer(reducer, initialState);\n\n return (\n <AppContext.Provider value={state}>\n <AppDispatchContext.Provider value={dispatch}>{children}</AppDispatchContext.Provider>\n </AppContext.Provider>\n );\n}\n\nexport function useAppContext(): AppContextType {\n return useContext(AppContext);\n}\n\nexport function useAppDispatch(): Dispatch<ActionSetRelationship | ActionSetScope> {\n return useContext(AppDispatchContext);\n}\n","import { DEFAULT_SCOPE_KEY } from '../graphql-client/queries';\nimport { useConfig } from './config/config-context';\n\ntype ScopeLike = { name: string; isDefault?: boolean };\n\n/**\n * The scope local values fall back to: the one marked `isDefault`, whatever\n * its name. A project without scopes has a single scope named `default`.\n */\nexport function defaultScopeName(scopes: readonly ScopeLike[] | null | undefined): string {\n return scopes?.find((scope) => scope.isDefault)?.name ?? scopes?.[0]?.name ?? DEFAULT_SCOPE_KEY;\n}\n\n/** The current project's default scope. */\nexport function useDefaultScope(): string {\n const { currentProject } = useConfig();\n\n return defaultScopeName(currentProject?.scopes);\n}\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import'./index.css';import {e}from'./chunk-7KLXWCDS.js';import {b,c}from'./chunk-5CVDMZUI.js';import {put}from'@vercel/blob/client';function T(s,e){let l=e.trim();return l?s.trim()?/\s$/.test(s)||/^[.,!?;:]/.test(l)?`${s}${l}`:`${s} ${l}`:s.length===0?l:`${s}${l}`:s}async function C(s){if(typeof window>"u")throw new Error("Dictation is only available in the browser.");let e=window.AudioContext??window.webkitAudioContext;if(!e)throw new Error("This browser cannot decode recorded audio.");let l=await s.arrayBuffer(),u=new e;try{let n=await u.decodeAudioData(l.slice(0)),i=$(n),t=I(i,n.sampleRate,24e3),o=P(t),a=t.length/24e3;if(a<.25)throw new Error("No speech was captured. Try again.");if(a>60)throw new Error(`Dictation is limited to ${String(60)} seconds.`);return {durationSeconds:a,pcm:new Blob([o],{type:"audio/pcm"})}}finally{await u.close();}}function $(s){let{length:e,numberOfChannels:l}=s;if(l===1)return s.getChannelData(0).slice();let u=new Float32Array(e);for(let n=0;n<e;n+=1){let i=0;for(let t=0;t<l;t+=1)i+=s.getChannelData(t)[n]??0;u[n]=i/l;}return u}function I(s,e,l){if(e===l)return s;let u=e/l,n=Math.max(1,Math.round(s.length/u)),i=new Float32Array(n);for(let t=0;t<n;t+=1){let o=t*u,a=Math.floor(o),c=Math.min(a+1,s.length-1),r=o-a,g=s[a]??0,d=s[c]??0;i[t]=g+(d-g)*r;}return i}function P(s){let e=new ArrayBuffer(s.length*2),l=new DataView(e);for(let u=0;u<s.length;u+=1){let n=Math.max(-1,Math.min(1,s[u]??0));l.setInt16(u*2,n<0?n*32768:n*32767,true);}return e}async function R(s){if(!(typeof crypto>"u"||!crypto.subtle))try{let e=await crypto.subtle.digest("SHA-256",await s.arrayBuffer());return Array.from(new Uint8Array(e),l=>l.toString(16).padStart(2,"0")).join("")}catch{return}}var m=class extends Error{code;status;constructor(e,l,u=null){super(l),this.name="AgentUploadError",this.code=u,this.status=e;}};function y(){if(typeof window>"u")return "flexkit.io";if(b())return c;let{hostname:s}=window.location;return s==="localhost"||s==="127.0.0.1"||s==="flexkit.test"||s.endsWith(".flexkit.test")?"flexkit.test":"flexkit.io"}function M(){return `https://${y()}`}function x(s,e){return `https://${s}.api.${y()}/automations/webhook/${encodeURIComponent(e)}`}function N(s){let e$1=`/api/flexkit/${s}`,l=`${e$1}/automations`,u=`${e$1}/skills`,n=`${e$1}/agent/chats`;async function i(t,o){let a=await fetch(t,{credentials:"include",headers:{"Content-Type":"application/json",...o?.headers??{}},...o}),c=await a.json();if(!a.ok){let r=c&&typeof c=="object"&&"error"in c?String(c.error):"Request failed";throw new Error(r)}return c}return {connectPlugins:t=>i(`${e$1}/plugins/connect`,{method:"POST",body:JSON.stringify(t)}),connectPluginToken:t=>i(`${e$1}/plugins/connect-token`,{method:"POST",body:JSON.stringify(t)}),connectPluginCredentials:t=>i(`${e$1}/plugins/connect-credentials`,{method:"POST",body:JSON.stringify(t)}),pluginOAuthStatus:t=>i(`${e$1}/plugins/oauth-transactions/${encodeURIComponent(t)}`),updatePluginConnection:(t,o)=>i(`${e$1}/plugin-connections/${encodeURIComponent(t)}`,{method:"PATCH",body:JSON.stringify(o)}),disconnectPlugin:t=>i(`${e$1}/plugin-connections/${encodeURIComponent(t)}`,{method:"DELETE"}),installPlugin:t=>i(`${e$1}/plugins/${encodeURIComponent(t)}/installation`,{method:"PUT",body:JSON.stringify({})}),setPluginPolicy:(t,o)=>i(`${e$1}/plugins/${encodeURIComponent(t)}/policy`,{method:"PATCH",body:JSON.stringify(o)}),refreshPluginTools:t=>i(`${e$1}/plugin-connections/${encodeURIComponent(t)}/tools/refresh`,{method:"POST"}),cancelRun:async t=>i(`${l}/runs/${encodeURIComponent(t)}/cancel`,{method:"POST"}),createAgentChat:async t=>i(n,{body:JSON.stringify({modelId:t?.modelId??null}),method:"POST"}),savePromptSuggestion:t=>i(`${e$1}/agent/profile`,{method:"PATCH",body:JSON.stringify({promptSuggestion:t})}),deleteAgentChat:async t=>i(`${n}/${encodeURIComponent(t)}`,{method:"DELETE"}),getAgentChatStreamUrl:(t,o)=>`${n}/${encodeURIComponent(t)}/stream?workflowRunId=${encodeURIComponent(o)}`,renameAgentChat:async(t,o)=>i(`${n}/${encodeURIComponent(t)}`,{body:JSON.stringify({title:o}),method:"PATCH"}),sendAgentChatMessage:async(t,o)=>i(`${n}/${encodeURIComponent(t)}/messages`,{body:JSON.stringify(o),method:"POST"}),announcePluginConnected:async(t,o)=>i(`${n}/${encodeURIComponent(t)}/plugin-connected`,{body:JSON.stringify({pluginId:o}),method:"POST"}),sendAgentChatFollowUp:async(t,o)=>i(`${n}/${encodeURIComponent(t)}/follow-ups`,{body:JSON.stringify(o),method:"POST"}),answerAgentChatQuestion:async(t,o,a)=>{let c=await fetch(`${n}/${encodeURIComponent(t)}/questions/${encodeURIComponent(o)}/answer`,{body:JSON.stringify(a),credentials:"include",headers:{"Content-Type":"application/json"},method:"POST"}),r=await c.json();if(!c.ok&&!r.question)throw new Error(r.errorMessage??r.error??"Request failed");return {errorMessage:c.ok?void 0:r.errorMessage,question:r.question}},startAgentChat:async({attachments:t,content:o,modelId:a})=>i(n,{body:JSON.stringify({message:{attachments:t,content:o},modelId:a??null}),method:"POST"}),startQueuedAgentChatMessage:async(t,o)=>i(`${n}/${encodeURIComponent(t)}/follow-ups/${encodeURIComponent(o)}/start`,{method:"POST"}),stopAgentChat:async t=>i(`${n}/${encodeURIComponent(t)}/stop`,{method:"POST"}),stopAgentChatMonitor:async(t,o)=>i(`${n}/${encodeURIComponent(t)}/monitors/${encodeURIComponent(o)}/stop`,{method:"POST"}),transcribeAgentAudio:async(t,o)=>{let{durationSeconds:a,pcm:c}=await C(t),r=new FormData;r.append("file",c,"audio.pcm"),r.append("durationSeconds",String(a));let g=await fetch(`${e$1}/agent/transcribe`,{body:r,credentials:"include",method:"POST",signal:o}),d=await g.json();if(!g.ok){let S=d&&typeof d=="object"&&d.error?String(d.error):"Request failed";throw new Error(S)}if(!d.text?.trim())throw new Error("No speech was recognized. Try again.");return {text:d.text}},uploadAgentChatAttachment:async(t,o)=>{let[a,c]=await Promise.all([fetch(`${e$1}/agent/uploads`,{body:JSON.stringify({filename:t.name,mediaType:t.type||null,sizeBytes:t.size}),credentials:"include",headers:{"Content-Type":"application/json"},method:"POST",signal:o}),e({name:t.name,size:t.size})===null?R(t):void 0]),r=await a.json();if(!a.ok||!r.pathname||!r.token||!r.mediaType)throw new m(a.status,r.error?String(r.error):"The file could not be uploaded.",r.code??null);let g=await put(r.pathname,t,{abortSignal:o,access:"public",contentType:r.mediaType,token:r.token});return {filename:t.name,mediaType:r.mediaType,sizeBytes:t.size,url:g.url,...c?{sha256:c}:{}}},decideApproval:async(t,o)=>{let a=await fetch(`${l}/approvals/${encodeURIComponent(t)}/decide`,{body:JSON.stringify(o),credentials:"include",headers:{"Content-Type":"application/json"},method:"POST"}),c=await a.json();if(!a.ok&&typeof c.success!="boolean")throw new Error(c.error?String(c.error):"Request failed");return c},markActivityRead:async t=>i(`${e$1}/activity/read`,{body:JSON.stringify(t==="all"?{all:true}:{ids:t}),method:"POST"}),setActivityItemState:async(t,o)=>i(`${e$1}/activity/${encodeURIComponent(t)}`,{body:JSON.stringify({state:o}),method:"PATCH"}),createAutomation:async t=>i(l,{body:JSON.stringify(t),method:"POST"}),createSkill:async t=>i(u,{body:JSON.stringify(t),method:"POST"}),deleteAutomation:async t=>i(`${l}/${encodeURIComponent(t)}`,{method:"DELETE"}),deleteSkill:async t=>i(`${u}/${encodeURIComponent(t)}`,{method:"DELETE"}),getArtifactUrl:(t,o)=>{let a=o?.download?"?download=1":"";return `${l}/artifacts/${encodeURIComponent(t)}/content${a}`},getRunArtifacts:async t=>i(`${l}/runs/${encodeURIComponent(t)}/artifacts`).then(o=>o.artifacts),getStreamUrl:t=>`${l}/runs/${encodeURIComponent(t)}/stream`,getTranscriptUrl:t=>`${l}/runs/${encodeURIComponent(t)}/transcript`,listChannels:async(t,o)=>{let a=o?`${e$1}/plugin-connections/${encodeURIComponent(o)}/channels`:`${e$1}/plugins/${t}/channels`,c=await fetch(a,{credentials:"include",headers:{"Content-Type":"application/json"}}),r=await c.json();if(c.ok)return {channels:r.channels??[],errorMessage:r.errorMessage,success:r.success??true};if(r.success===false)return {channels:r.channels??[],errorMessage:r.errorMessage??`Failed to load ${t==="slack"?"Slack":"Teams"} channels.`,success:false};let g=r.error?String(r.error):"Request failed";throw new Error(g)},runAutomation:async t=>i(`${l}/${encodeURIComponent(t)}/runs`,{method:"POST"}),updateAutomation:async(t,o)=>i(`${l}/${encodeURIComponent(t)}`,{body:JSON.stringify(o),method:"PATCH"}),updateSkill:async(t,o)=>i(`${u}/${encodeURIComponent(t)}`,{body:JSON.stringify(o),method:"PATCH"})}}var p=class extends Error{status;constructor(e,l="Request failed"){super(l),this.name="FetcherError",this.status=e;}},D=async s=>{let e=await fetch(s,{credentials:"include"});if(!e.ok)throw new p(e.status);return await e.json()};function E(s){let e=`/api/flexkit/${s}/automations`,l=`/api/flexkit/${s}/skills`,u=`/api/flexkit/${s}/agent/chats`;return {activity:(n={})=>{let{filter:i="all",limit:t=25,offset:o=0}=n,a=new URLSearchParams({filter:i,limit:t.toString(),offset:o.toString()});return `/api/flexkit/${s}/activity?${a.toString()}`},activityItem:n=>`/api/flexkit/${s}/activity/${encodeURIComponent(n)}`,activitySummary:n=>n?`/api/flexkit/${s}/activity/summary?since=${encodeURIComponent(n)}`:`/api/flexkit/${s}/activity/summary`,agentChat:n=>`${u}/${encodeURIComponent(n)}`,agentChatSearch:n=>`${u}/search?q=${encodeURIComponent(n)}`,agentChats:(n=0)=>`${u}?offset=${n.toString()}`,agentProfile:()=>`/api/flexkit/${s}/agent/profile`,approval:n=>`${e}/approvals/${encodeURIComponent(n)}`,approvals:(n={})=>{let{limit:i=25,offset:t=0,runId:o,status:a}=n,c=new URLSearchParams({limit:i.toString(),offset:t.toString()});return a&&c.set("status",a),o&&c.set("runId",o),`${e}/approvals?${c.toString()}`},approvalsCount:`${e}/approvals?limit=1`,automation:n=>`${e}/${encodeURIComponent(n)}`,automationRuns:(n,i=0,t=25)=>`${e}/${encodeURIComponent(n)}/runs?offset=${i.toString()}&limit=${t.toString()}`,automations:(n={})=>{let{enabled:i,limit:t=25,offset:o=0,search:a,visibility:c}=n,r=new URLSearchParams({limit:t.toString(),offset:o.toString()});i&&i.length>0&&r.set("enabled",i.map(d=>d?"true":"false").join(",")),c&&c.length>0&&r.set("visibility",c.join(","));let g=a?.trim();return g&&r.set("q",g),`${e}?${r.toString()}`},creditBalance:`${e}/credits`,entities:`${e}/entities`,run:n=>`${e}/runs/${encodeURIComponent(n)}`,runHistory:(n,i=0,t=25)=>`${e}/runs?scope=${n}&offset=${i.toString()}&limit=${t.toString()}`,skill:n=>`${l}/${encodeURIComponent(n)}`,skills:(n={})=>{let{limit:i=25,offset:t=0,search:o,visibility:a}=n,c=new URLSearchParams({limit:i.toString(),offset:t.toString()});a&&a.length>0&&c.set("visibility",a.join(","));let r=o?.trim();return r&&c.set("q",r),`${l}?${c.toString()}`},spaces:`/api/flexkit/${s}/spaces`,members:n=>n?`/api/flexkit/${s}/members?spaceId=${encodeURIComponent(n)}`:`/api/flexkit/${s}/members`,tools:n=>n?`${e}/${encodeURIComponent(n)}/tools`:`${e}/tools`}}
|
|
2
|
+
export{T as a,M as b,x as c,N as d,p as e,D as f,E as g};//# sourceMappingURL=chunk-PLCI2RJA.js.map
|
|
3
|
+
//# sourceMappingURL=chunk-PLCI2RJA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/apps/ai/agent/dictation.ts","../src/apps/ai/api.ts"],"names":["appendDictatedText","existing","transcript","dictated","convertRecordedAudioToPcm","blob","AudioContextCtor","arrayBuffer","audioContext","audioBuffer","mono","mixToMono","resampled","resample","pcm","floatToPcm16","durationSeconds","buffer","length","channelCount","index","sum","channel","samples","sourceRate","targetRate","ratio","outputLength","output","sourceIndex","left","right","fraction","leftSample","rightSample","view","sample","sha256Hex","file","digest","byte","AgentUploadError","status","message","code","getApiRootDomain","getDesktop","flexkitDomain","hostname","getPlatformOrigin","getWebhookTriggerUrl","projectId","token","createApiClient","projectBasePath","automationsBasePath","skillsBasePath","agentChatsBasePath","request","url","init","response","data","error","input","id","runId","change","chatId","workflowRunId","title","pluginId","questionId","result","attachments","content","modelId","messageId","monitorId","audio","signal","formData","tokenResponse","sha256","getKnowledgeFileProblem","tokenData","put","approvalId","ids","itemId","state","automationId","skillId","artifactId","options","suffix","provider","connectionId","FetcherError","fetcher","paths","basePath","filter","limit","offset","params","since","query","enabled","search","visibility","value","trimmedSearch","scope","spaceId"],"mappings":"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","file":"chunk-PLCI2RJA.js","sourcesContent":["export const DICTATION_SAMPLE_RATE = 24_000;\nexport const DICTATION_MAX_DURATION_SECONDS = 60;\nexport const DICTATION_MIN_DURATION_SECONDS = 0.25;\n\nexport function appendDictatedText(existing: string, transcript: string): string {\n const dictated = transcript.trim();\n\n if (!dictated) {\n return existing;\n }\n\n if (!existing.trim()) {\n return existing.length === 0 ? dictated : `${existing}${dictated}`;\n }\n\n if (/\\s$/.test(existing) || /^[.,!?;:]/.test(dictated)) {\n return `${existing}${dictated}`;\n }\n\n return `${existing} ${dictated}`;\n}\n\nexport async function convertRecordedAudioToPcm(blob: Blob): Promise<{ durationSeconds: number; pcm: Blob }> {\n if (typeof window === 'undefined') {\n throw new Error('Dictation is only available in the browser.');\n }\n\n const AudioContextCtor = window.AudioContext ?? window.webkitAudioContext;\n\n if (!AudioContextCtor) {\n throw new Error('This browser cannot decode recorded audio.');\n }\n\n const arrayBuffer = await blob.arrayBuffer();\n const audioContext = new AudioContextCtor();\n\n try {\n const audioBuffer = await audioContext.decodeAudioData(arrayBuffer.slice(0));\n const mono = mixToMono(audioBuffer);\n const resampled = resample(mono, audioBuffer.sampleRate, DICTATION_SAMPLE_RATE);\n const pcm = floatToPcm16(resampled);\n const durationSeconds = resampled.length / DICTATION_SAMPLE_RATE;\n\n if (durationSeconds < DICTATION_MIN_DURATION_SECONDS) {\n throw new Error('No speech was captured. Try again.');\n }\n\n if (durationSeconds > DICTATION_MAX_DURATION_SECONDS) {\n throw new Error(`Dictation is limited to ${String(DICTATION_MAX_DURATION_SECONDS)} seconds.`);\n }\n\n return {\n durationSeconds,\n pcm: new Blob([pcm], { type: 'audio/pcm' }),\n };\n } finally {\n await audioContext.close();\n }\n}\n\nfunction mixToMono(buffer: AudioBuffer): Float32Array {\n const { length, numberOfChannels: channelCount } = buffer;\n\n if (channelCount === 1) {\n return buffer.getChannelData(0).slice();\n }\n\n const mono = new Float32Array(length);\n\n for (let index = 0; index < length; index += 1) {\n let sum = 0;\n\n for (let channel = 0; channel < channelCount; channel += 1) {\n sum += buffer.getChannelData(channel)[index] ?? 0;\n }\n\n mono[index] = sum / channelCount;\n }\n\n return mono;\n}\n\nfunction resample(samples: Float32Array, sourceRate: number, targetRate: number): Float32Array {\n if (sourceRate === targetRate) {\n return samples;\n }\n\n const ratio = sourceRate / targetRate;\n const outputLength = Math.max(1, Math.round(samples.length / ratio));\n const output = new Float32Array(outputLength);\n\n for (let index = 0; index < outputLength; index += 1) {\n const sourceIndex = index * ratio;\n const left = Math.floor(sourceIndex);\n const right = Math.min(left + 1, samples.length - 1);\n const fraction = sourceIndex - left;\n const leftSample = samples[left] ?? 0;\n const rightSample = samples[right] ?? 0;\n output[index] = leftSample + (rightSample - leftSample) * fraction;\n }\n\n return output;\n}\n\nfunction floatToPcm16(samples: Float32Array): ArrayBuffer {\n const buffer = new ArrayBuffer(samples.length * 2);\n const view = new DataView(buffer);\n\n for (let index = 0; index < samples.length; index += 1) {\n const sample = Math.max(-1, Math.min(1, samples[index] ?? 0));\n view.setInt16(index * 2, sample < 0 ? sample * 0x8000 : sample * 0x7fff, true);\n }\n\n return buffer;\n}\n\ndeclare global {\n interface Window {\n webkitAudioContext?: typeof AudioContext;\n }\n}\n","import { getKnowledgeFileProblem } from '../knowledge/knowledge';\nimport type { PluginConnection, PluginScope, PluginTools } from './plugin-types';\nimport { put } from '@vercel/blob/client';\nimport { convertRecordedAudioToPcm } from './agent/dictation';\nimport { getDesktop } from '../../core/desktop';\nimport { flexkitDomain } from '../../core/domains';\nimport type {\n ActivityItem,\n ActivityItemState,\n AgentChat,\n AgentChatAttachment,\n AgentChatFollowUpResult,\n AgentChatMessage,\n AgentChatMonitor,\n AgentChatQuestion,\n AgentChatQuestionResponse,\n AgentChatTurn,\n Automation,\n AutomationApproval,\n AutomationApprovalStatus,\n AutomationArtifact,\n AutomationInput,\n AutomationToolChannel,\n AutomationToolProvider,\n AutomationVisibility,\n MutationResult,\n Skill,\n SkillInput,\n} from './types';\n\nexport interface DecideApprovalInput {\n /** Approve and always allow this plugin tool for the automation. */\n remember?: boolean;\n approved: boolean;\n /** For a proposed automation: the approver's edited instructions and whether to run it once now. */\n automationEdits?: { instructions?: string; runOnce?: boolean };\n force?: boolean;\n reason?: string;\n /** For a proposed skill: the fields the approver edited. */\n skillEdits?: { content?: string; description?: string; name?: string };\n}\n\nexport interface SendAgentChatMessageInput {\n attachments?: AgentChatAttachment[];\n content: string;\n modelId?: string | null;\n}\n\n/** A new chat and its first turn, started by one request. */\nexport interface StartAgentChatResult {\n chat: AgentChat;\n turn: AgentChatTurn;\n}\n\n/** Lowercase hex SHA-256 of a file, or undefined where the browser cannot hash (insecure contexts). */\nasync function sha256Hex(file: File): Promise<string | undefined> {\n if (typeof crypto === 'undefined' || !crypto.subtle) {\n return undefined;\n }\n\n try {\n const digest = await crypto.subtle.digest('SHA-256', await file.arrayBuffer());\n\n return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, '0')).join('');\n } catch {\n return undefined;\n }\n}\n\n/** Thrown when the API refuses an upload; `code` lets the UI tailor the message. */\nexport class AgentUploadError extends Error {\n code: string | null;\n status: number;\n\n constructor(status: number, message: string, code: string | null = null) {\n super(message);\n this.name = 'AgentUploadError';\n this.code = code;\n this.status = status;\n }\n}\n\nexport interface ApiClient {\n /** Starts OAuth for a new account, or for `connectionId` to reconnect that specific account. */\n connectPlugins: (_input: {\n pluginId: string;\n scope: PluginScope;\n studioOrigin: string;\n connectionId?: string;\n }) => Promise<{ transactionId: string; authorizeUrl: string; completionOrigin: string; launchTicket: string }>;\n /** Connects a credentials plugin from its form, or replaces the credentials of `connectionId`. */\n connectPluginCredentials: (_input: {\n pluginId: string;\n scope: PluginScope;\n method?: string;\n values: { [key: string]: string };\n connectionId?: string;\n }) => Promise<{ connection: PluginConnection }>;\n /** Connects a token plugin with a pasted token, or replaces the token of `connectionId`. */\n connectPluginToken: (_input: {\n pluginId: string;\n scope: PluginScope;\n token: string;\n connectionId?: string;\n }) => Promise<{ connection: PluginConnection }>;\n /** Renames (label null resets to the provider name) or makes a connection primary. */\n updatePluginConnection: (\n _id: string,\n _input: { label?: string | null; primary?: true }\n ) => Promise<{ connection: PluginConnection }>;\n pluginOAuthStatus: (\n _id: string\n ) => Promise<{ id: string; status: 'pending' | 'exchanging' | 'complete' | 'failed'; expires_at: string }>;\n disconnectPlugin: (_id: string) => Promise<{ success: boolean }>;\n installPlugin: (_id: string) => Promise<unknown>;\n setPluginPolicy: (_id: string, _input: { enabled: boolean; allowPersonal: boolean }) => Promise<{ success: boolean }>;\n refreshPluginTools: (_id: string) => Promise<PluginTools>;\n\n cancelRun: (_runId: string) => Promise<MutationResult>;\n createAgentChat: (_input?: { modelId?: string | null }) => Promise<{ chat: AgentChat }>;\n deleteAgentChat: (_chatId: string) => Promise<{ success: boolean }>;\n /** Saves one change to the signed-in user's suggested prompts: a prompt used, or a set hidden. */\n savePromptSuggestion: (\n _change: { set: string; used: string } | { set: string; hide: true }\n ) => Promise<{ promptSuggestions: { [setKey: string]: { hidden: boolean; used: string[] } } }>;\n getAgentChatStreamUrl: (_chatId: string, _workflowRunId: string) => string;\n renameAgentChat: (_chatId: string, _title: string) => Promise<{ chat: AgentChat }>;\n sendAgentChatMessage: (_chatId: string, _input: SendAgentChatMessageInput) => Promise<AgentChatTurn>;\n /**\n * Sends a message while the chat's turn is running. The platform decides\n * whether it steers that turn or waits as the next one; if the turn has\n * meanwhile ended, the message starts the next turn.\n */\n sendAgentChatFollowUp: (_chatId: string, _input: SendAgentChatMessageInput) => Promise<AgentChatFollowUpResult>;\n /** The user connected a plugin from the chat's connect card: starts the turn that uses it, or queues it. */\n announcePluginConnected: (\n _chatId: string,\n _pluginId: string\n ) => Promise<Extract<AgentChatFollowUpResult, { followUp: unknown } | { turn: unknown }>>;\n /** Answers (or dismisses) the questions a chat turn waits on; a settled question comes back with an error. */\n answerAgentChatQuestion: (\n _chatId: string,\n _questionId: string,\n _response: AgentChatQuestionResponse\n ) => Promise<{ errorMessage?: string; question?: AgentChatQuestion }>;\n /** Creates a chat and sends its first message in one request. */\n startAgentChat: (_input: SendAgentChatMessageInput) => Promise<StartAgentChatResult>;\n /** Starts the next turn from a queued follow-up once the previous turn has ended. */\n startQueuedAgentChatMessage: (_chatId: string, _messageId: string) => Promise<AgentChatTurn>;\n stopAgentChat: (_chatId: string) => Promise<{ message: AgentChatMessage }>;\n stopAgentChatMonitor: (_chatId: string, _monitorId: string) => Promise<{ monitor: AgentChatMonitor }>;\n transcribeAgentAudio: (_audio: Blob, _signal?: AbortSignal) => Promise<{ text: string }>;\n /** Uploads a chat attachment straight to the platform file store. */\n uploadAgentChatAttachment: (_file: File, _signal?: AbortSignal) => Promise<AgentChatAttachment>;\n decideApproval: (\n _approvalId: string,\n _input: DecideApprovalInput\n ) => Promise<MutationResult & { approval?: AutomationApproval }>;\n createAutomation: (_input: AutomationInput) => Promise<MutationResult & { automation?: Automation }>;\n createSkill: (_input: SkillInput) => Promise<MutationResult & { skill?: Skill }>;\n deleteAutomation: (_automationId: string) => Promise<MutationResult>;\n deleteSkill: (_skillId: string) => Promise<MutationResult>;\n getArtifactUrl: (_artifactId: string, _options?: { download?: boolean }) => string;\n getRunArtifacts: (_workflowRunId: string) => Promise<AutomationArtifact[]>;\n getStreamUrl: (_workflowRunId: string) => string;\n /** JSON transcript of a finished run (owners and developers). */\n getTranscriptUrl: (_runId: string) => string;\n /** Lists delivery channels of `connectionId`, or of the provider's primary project account when omitted. */\n listChannels: (\n _provider: AutomationToolProvider,\n _connectionId?: string | null\n ) => Promise<{\n channels: AutomationToolChannel[];\n errorMessage?: string;\n success: boolean;\n }>;\n runAutomation: (_automationId: string) => Promise<MutationResult & { runId?: string }>;\n updateAutomation: (\n _automationId: string,\n _input: AutomationInput\n ) => Promise<MutationResult & { automation?: Automation }>;\n updateSkill: (_skillId: string, _input: SkillInput) => Promise<MutationResult & { skill?: Skill }>;\n /** Marks the caller's Activity items read; `'all'` marks every unread item. */\n markActivityRead: (_ids: string[] | 'all') => Promise<{ success: boolean }>;\n setActivityItemState: (\n _itemId: string,\n _state: Extract<ActivityItemState, 'unread' | 'read' | 'dismissed'>\n ) => Promise<{ item: ActivityItem }>;\n}\n\nfunction getApiRootDomain(): string {\n if (typeof window === 'undefined') {\n return 'flexkit.io';\n }\n\n // The desktop app serves the Studio on its own scheme (`flexkit://app`), so\n // its page hostname says nothing; the backend it was built for does.\n if (getDesktop()) {\n return flexkitDomain;\n }\n\n const { hostname } = window.location;\n const isDevHost =\n hostname === 'localhost' ||\n hostname === '127.0.0.1' ||\n hostname === 'flexkit.test' ||\n hostname.endsWith('.flexkit.test');\n\n return isDevHost ? 'flexkit.test' : 'flexkit.io';\n}\n\n/** Origin that hosts plugin OAuth start and completion. */\nexport function getPlatformOrigin(): string {\n return `https://${getApiRootDomain()}`;\n}\n\n/** Public URL an external system calls to fire a webhook trigger. */\nexport function getWebhookTriggerUrl(projectId: string, token: string): string {\n return `https://${projectId}.api.${getApiRootDomain()}/automations/webhook/${encodeURIComponent(token)}`;\n}\n\nexport function createApiClient(projectId: string): ApiClient {\n const projectBasePath = `/api/flexkit/${projectId}`;\n const automationsBasePath = `${projectBasePath}/automations`;\n const skillsBasePath = `${projectBasePath}/skills`;\n const agentChatsBasePath = `${projectBasePath}/agent/chats`;\n\n async function request<T>(url: string, init?: RequestInit): Promise<T> {\n const response = await fetch(url, {\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...(init?.headers ?? {}),\n },\n ...init,\n });\n const data = (await response.json()) as T;\n\n if (!response.ok) {\n const error = data && typeof data === 'object' && 'error' in data ? String(data.error) : 'Request failed';\n\n throw new Error(error);\n }\n\n return data;\n }\n\n return {\n connectPlugins: (input) =>\n request(`${projectBasePath}/plugins/connect`, { method: 'POST', body: JSON.stringify(input) }),\n connectPluginToken: (input) =>\n request(`${projectBasePath}/plugins/connect-token`, { method: 'POST', body: JSON.stringify(input) }),\n connectPluginCredentials: (input) =>\n request(`${projectBasePath}/plugins/connect-credentials`, { method: 'POST', body: JSON.stringify(input) }),\n pluginOAuthStatus: (id) => request(`${projectBasePath}/plugins/oauth-transactions/${encodeURIComponent(id)}`),\n updatePluginConnection: (id, input) =>\n request(`${projectBasePath}/plugin-connections/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n body: JSON.stringify(input),\n }),\n disconnectPlugin: (id) =>\n request(`${projectBasePath}/plugin-connections/${encodeURIComponent(id)}`, { method: 'DELETE' }),\n installPlugin: (id) =>\n request(`${projectBasePath}/plugins/${encodeURIComponent(id)}/installation`, {\n method: 'PUT',\n body: JSON.stringify({}),\n }),\n setPluginPolicy: (id, input) =>\n request(`${projectBasePath}/plugins/${encodeURIComponent(id)}/policy`, {\n method: 'PATCH',\n body: JSON.stringify(input),\n }),\n refreshPluginTools: (id) =>\n request(`${projectBasePath}/plugin-connections/${encodeURIComponent(id)}/tools/refresh`, { method: 'POST' }),\n cancelRun: async (runId) =>\n request<MutationResult>(`${automationsBasePath}/runs/${encodeURIComponent(runId)}/cancel`, { method: 'POST' }),\n createAgentChat: async (input) =>\n request<{ chat: AgentChat }>(agentChatsBasePath, {\n body: JSON.stringify({ modelId: input?.modelId ?? null }),\n method: 'POST',\n }),\n savePromptSuggestion: (change) =>\n request(`${projectBasePath}/agent/profile`, {\n method: 'PATCH',\n body: JSON.stringify({ promptSuggestion: change }),\n }),\n deleteAgentChat: async (chatId) =>\n request<{ success: boolean }>(`${agentChatsBasePath}/${encodeURIComponent(chatId)}`, { method: 'DELETE' }),\n getAgentChatStreamUrl: (chatId, workflowRunId) =>\n `${agentChatsBasePath}/${encodeURIComponent(chatId)}/stream?workflowRunId=${encodeURIComponent(workflowRunId)}`,\n renameAgentChat: async (chatId, title) =>\n request<{ chat: AgentChat }>(`${agentChatsBasePath}/${encodeURIComponent(chatId)}`, {\n body: JSON.stringify({ title }),\n method: 'PATCH',\n }),\n sendAgentChatMessage: async (chatId, input) =>\n request<AgentChatTurn>(`${agentChatsBasePath}/${encodeURIComponent(chatId)}/messages`, {\n body: JSON.stringify(input),\n method: 'POST',\n }),\n announcePluginConnected: async (chatId, pluginId) =>\n request(`${agentChatsBasePath}/${encodeURIComponent(chatId)}/plugin-connected`, {\n body: JSON.stringify({ pluginId }),\n method: 'POST',\n }),\n sendAgentChatFollowUp: async (chatId, input) =>\n request<AgentChatFollowUpResult>(`${agentChatsBasePath}/${encodeURIComponent(chatId)}/follow-ups`, {\n body: JSON.stringify(input),\n method: 'POST',\n }),\n answerAgentChatQuestion: async (chatId, questionId, response) => {\n const result = await fetch(\n `${agentChatsBasePath}/${encodeURIComponent(chatId)}/questions/${encodeURIComponent(questionId)}/answer`,\n {\n body: JSON.stringify(response),\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n }\n );\n const data = (await result.json()) as { errorMessage?: string; error?: string; question?: AgentChatQuestion };\n\n // A question settled elsewhere (409) comes back with its final state for the card to show.\n if (!result.ok && !data.question) {\n throw new Error(data.errorMessage ?? data.error ?? 'Request failed');\n }\n\n return { errorMessage: result.ok ? undefined : data.errorMessage, question: data.question };\n },\n startAgentChat: async ({ attachments, content, modelId }) =>\n request<StartAgentChatResult>(agentChatsBasePath, {\n body: JSON.stringify({ message: { attachments, content }, modelId: modelId ?? null }),\n method: 'POST',\n }),\n startQueuedAgentChatMessage: async (chatId, messageId) =>\n request<AgentChatTurn>(\n `${agentChatsBasePath}/${encodeURIComponent(chatId)}/follow-ups/${encodeURIComponent(messageId)}/start`,\n { method: 'POST' }\n ),\n stopAgentChat: async (chatId) =>\n request<{ message: AgentChatMessage }>(`${agentChatsBasePath}/${encodeURIComponent(chatId)}/stop`, {\n method: 'POST',\n }),\n stopAgentChatMonitor: async (chatId, monitorId) =>\n request<{ monitor: AgentChatMonitor }>(\n `${agentChatsBasePath}/${encodeURIComponent(chatId)}/monitors/${encodeURIComponent(monitorId)}/stop`,\n { method: 'POST' }\n ),\n transcribeAgentAudio: async (audio, signal) => {\n const { durationSeconds, pcm } = await convertRecordedAudioToPcm(audio);\n const formData = new FormData();\n formData.append('file', pcm, 'audio.pcm');\n formData.append('durationSeconds', String(durationSeconds));\n\n const response = await fetch(`${projectBasePath}/agent/transcribe`, {\n body: formData,\n credentials: 'include',\n method: 'POST',\n signal,\n });\n const data = (await response.json()) as { error?: string; text?: string };\n\n if (!response.ok) {\n const error = data && typeof data === 'object' && data.error ? String(data.error) : 'Request failed';\n\n throw new Error(error);\n }\n\n if (!data.text?.trim()) {\n throw new Error('No speech was recognized. Try again.');\n }\n\n return { text: data.text };\n },\n uploadAgentChatAttachment: async (file, signal) => {\n // The platform issues a token scoped to one pathname, type and size; the\n // browser then writes the bytes to the store directly, so large files\n // never pass through the API function body limit. The hash is computed\n // alongside: Knowledge documents are keyed by it, so the platform can tell\n // later whether this file is already one.\n const [tokenResponse, sha256] = await Promise.all([\n fetch(`${projectBasePath}/agent/uploads`, {\n body: JSON.stringify({ filename: file.name, mediaType: file.type || null, sizeBytes: file.size }),\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n signal,\n }),\n // Only files Knowledge can index are worth hashing; a screenshot never matches a document.\n getKnowledgeFileProblem({ name: file.name, size: file.size }) === null ? sha256Hex(file) : undefined,\n ]);\n const tokenData = (await tokenResponse.json()) as {\n code?: string;\n error?: string;\n mediaType?: string;\n pathname?: string;\n token?: string;\n };\n\n if (!tokenResponse.ok || !tokenData.pathname || !tokenData.token || !tokenData.mediaType) {\n throw new AgentUploadError(\n tokenResponse.status,\n tokenData.error ? String(tokenData.error) : 'The file could not be uploaded.',\n tokenData.code ?? null\n );\n }\n\n const blob = await put(tokenData.pathname, file, {\n abortSignal: signal,\n access: 'public',\n contentType: tokenData.mediaType,\n token: tokenData.token,\n });\n\n return {\n filename: file.name,\n mediaType: tokenData.mediaType,\n sizeBytes: file.size,\n url: blob.url,\n ...(sha256 ? { sha256 } : {}),\n };\n },\n decideApproval: async (approvalId, input) => {\n const response = await fetch(`${automationsBasePath}/approvals/${encodeURIComponent(approvalId)}/decide`, {\n body: JSON.stringify(input),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n });\n const data = (await response.json()) as MutationResult & { approval?: AutomationApproval; error?: string };\n\n // Business errors (stale_preview, already_decided) come back as 400\n // with a structured body the caller must be able to inspect.\n if (!response.ok && typeof data.success !== 'boolean') {\n throw new Error(data.error ? String(data.error) : 'Request failed');\n }\n\n return data;\n },\n markActivityRead: async (ids) =>\n request<{ success: boolean }>(`${projectBasePath}/activity/read`, {\n body: JSON.stringify(ids === 'all' ? { all: true } : { ids }),\n method: 'POST',\n }),\n setActivityItemState: async (itemId, state) =>\n request<{ item: ActivityItem }>(`${projectBasePath}/activity/${encodeURIComponent(itemId)}`, {\n body: JSON.stringify({ state }),\n method: 'PATCH',\n }),\n createAutomation: async (input) =>\n request<MutationResult & { automation?: Automation }>(automationsBasePath, {\n body: JSON.stringify(input),\n method: 'POST',\n }),\n createSkill: async (input) =>\n request<MutationResult & { skill?: Skill }>(skillsBasePath, {\n body: JSON.stringify(input),\n method: 'POST',\n }),\n deleteAutomation: async (automationId) =>\n request<MutationResult>(`${automationsBasePath}/${encodeURIComponent(automationId)}`, { method: 'DELETE' }),\n deleteSkill: async (skillId) =>\n request<MutationResult>(`${skillsBasePath}/${encodeURIComponent(skillId)}`, { method: 'DELETE' }),\n getArtifactUrl: (artifactId, options) => {\n const suffix = options?.download ? '?download=1' : '';\n\n return `${automationsBasePath}/artifacts/${encodeURIComponent(artifactId)}/content${suffix}`;\n },\n getRunArtifacts: async (workflowRunId) =>\n request<{ artifacts: AutomationArtifact[] }>(\n `${automationsBasePath}/runs/${encodeURIComponent(workflowRunId)}/artifacts`\n ).then((response) => response.artifacts),\n getStreamUrl: (workflowRunId) => `${automationsBasePath}/runs/${encodeURIComponent(workflowRunId)}/stream`,\n getTranscriptUrl: (runId) => `${automationsBasePath}/runs/${encodeURIComponent(runId)}/transcript`,\n listChannels: async (provider, connectionId) => {\n const url = connectionId\n ? `${projectBasePath}/plugin-connections/${encodeURIComponent(connectionId)}/channels`\n : `${projectBasePath}/plugins/${provider}/channels`;\n const response = await fetch(url, {\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n const data = (await response.json()) as {\n channels?: AutomationToolChannel[];\n error?: string;\n errorMessage?: string;\n success?: boolean;\n };\n\n if (response.ok) {\n return {\n channels: data.channels ?? [],\n errorMessage: data.errorMessage,\n success: data.success ?? true,\n };\n }\n\n if (data.success === false) {\n return {\n channels: data.channels ?? [],\n errorMessage: data.errorMessage ?? `Failed to load ${provider === 'slack' ? 'Slack' : 'Teams'} channels.`,\n success: false,\n };\n }\n\n const error = data.error ? String(data.error) : 'Request failed';\n\n throw new Error(error);\n },\n runAutomation: async (automationId) =>\n request<MutationResult & { runId?: string }>(`${automationsBasePath}/${encodeURIComponent(automationId)}/runs`, {\n method: 'POST',\n }),\n updateAutomation: async (automationId, input) =>\n request<MutationResult & { automation?: Automation }>(\n `${automationsBasePath}/${encodeURIComponent(automationId)}`,\n {\n body: JSON.stringify(input),\n method: 'PATCH',\n }\n ),\n updateSkill: async (skillId, input) =>\n request<MutationResult & { skill?: Skill }>(`${skillsBasePath}/${encodeURIComponent(skillId)}`, {\n body: JSON.stringify(input),\n method: 'PATCH',\n }),\n };\n}\n\nexport class FetcherError extends Error {\n status: number;\n\n constructor(status: number, message = 'Request failed') {\n super(message);\n this.name = 'FetcherError';\n this.status = status;\n }\n}\n\nexport const fetcher = async <T>(url: string): Promise<T> => {\n const response = await fetch(url, { credentials: 'include' });\n\n if (!response.ok) {\n throw new FetcherError(response.status);\n }\n\n return (await response.json()) as T;\n};\n\nexport function paths(projectId: string): {\n activity: (_options?: { filter?: 'all' | 'needs_action'; limit?: number; offset?: number }) => string;\n activityItem: (_itemId: string) => string;\n /** Badge counts; with `since`, also the unread items created after it. */\n activitySummary: (_since?: string | null) => string;\n agentChat: (_chatId: string) => string;\n agentChatSearch: (_query: string) => string;\n agentChats: (_offset?: number) => string;\n agentProfile: () => string;\n approval: (_approvalId: string) => string;\n approvals: (_options?: {\n limit?: number;\n offset?: number;\n runId?: string;\n status?: AutomationApprovalStatus;\n }) => string;\n approvalsCount: string;\n automation: (_automationId: string) => string;\n automationRuns: (_automationId: string, _offset?: number, _limit?: number) => string;\n automations: (_options?: {\n enabled?: boolean[];\n limit?: number;\n offset?: number;\n search?: string;\n visibility?: AutomationVisibility[];\n }) => string;\n creditBalance: string;\n entities: string;\n run: (_runId: string) => string;\n runHistory: (_scope: 'mine' | 'team', _offset?: number, _limit?: number) => string;\n skill: (_skillId: string) => string;\n skills: (_options?: {\n limit?: number;\n offset?: number;\n search?: string;\n visibility?: AutomationVisibility[];\n }) => string;\n spaces: string;\n /** Members for pickers; with a space id, only members who can see that space. */\n members: (_spaceId?: string | null) => string;\n tools: (_automationId?: string) => string;\n} {\n const basePath = `/api/flexkit/${projectId}/automations`;\n const skillsBasePath = `/api/flexkit/${projectId}/skills`;\n const agentChatsBasePath = `/api/flexkit/${projectId}/agent/chats`;\n\n return {\n activity: (options = {}) => {\n const { filter = 'all', limit = 25, offset = 0 } = options;\n const params = new URLSearchParams({ filter, limit: limit.toString(), offset: offset.toString() });\n\n return `/api/flexkit/${projectId}/activity?${params.toString()}`;\n },\n activityItem: (itemId) => `/api/flexkit/${projectId}/activity/${encodeURIComponent(itemId)}`,\n activitySummary: (since) =>\n since\n ? `/api/flexkit/${projectId}/activity/summary?since=${encodeURIComponent(since)}`\n : `/api/flexkit/${projectId}/activity/summary`,\n agentChat: (chatId) => `${agentChatsBasePath}/${encodeURIComponent(chatId)}`,\n agentChatSearch: (query) => `${agentChatsBasePath}/search?q=${encodeURIComponent(query)}`,\n agentChats: (offset = 0) => `${agentChatsBasePath}?offset=${offset.toString()}`,\n agentProfile: () => `/api/flexkit/${projectId}/agent/profile`,\n approval: (approvalId) => `${basePath}/approvals/${encodeURIComponent(approvalId)}`,\n approvals: (options = {}) => {\n const { limit = 25, offset = 0, runId, status } = options;\n const params = new URLSearchParams({\n limit: limit.toString(),\n offset: offset.toString(),\n });\n\n if (status) {\n params.set('status', status);\n }\n\n if (runId) {\n params.set('runId', runId);\n }\n\n return `${basePath}/approvals?${params.toString()}`;\n },\n approvalsCount: `${basePath}/approvals?limit=1`,\n automation: (automationId) => `${basePath}/${encodeURIComponent(automationId)}`,\n automationRuns: (automationId, offset = 0, limit = 25) =>\n `${basePath}/${encodeURIComponent(automationId)}/runs?offset=${offset.toString()}&limit=${limit.toString()}`,\n automations: (options = {}) => {\n const { enabled, limit = 25, offset = 0, search, visibility } = options;\n const params = new URLSearchParams({\n limit: limit.toString(),\n offset: offset.toString(),\n });\n\n if (enabled && enabled.length > 0) {\n params.set('enabled', enabled.map((value) => (value ? 'true' : 'false')).join(','));\n }\n\n if (visibility && visibility.length > 0) {\n params.set('visibility', visibility.join(','));\n }\n\n const trimmedSearch = search?.trim();\n\n if (trimmedSearch) {\n params.set('q', trimmedSearch);\n }\n\n return `${basePath}?${params.toString()}`;\n },\n creditBalance: `${basePath}/credits`,\n entities: `${basePath}/entities`,\n run: (runId) => `${basePath}/runs/${encodeURIComponent(runId)}`,\n runHistory: (scope, offset = 0, limit = 25) =>\n `${basePath}/runs?scope=${scope}&offset=${offset.toString()}&limit=${limit.toString()}`,\n skill: (skillId) => `${skillsBasePath}/${encodeURIComponent(skillId)}`,\n skills: (options = {}) => {\n const { limit = 25, offset = 0, search, visibility } = options;\n const params = new URLSearchParams({\n limit: limit.toString(),\n offset: offset.toString(),\n });\n\n if (visibility && visibility.length > 0) {\n params.set('visibility', visibility.join(','));\n }\n\n const trimmedSearch = search?.trim();\n\n if (trimmedSearch) {\n params.set('q', trimmedSearch);\n }\n\n return `${skillsBasePath}?${params.toString()}`;\n },\n spaces: `/api/flexkit/${projectId}/spaces`,\n members: (spaceId) =>\n spaceId\n ? `/api/flexkit/${projectId}/members?spaceId=${encodeURIComponent(spaceId)}`\n : `/api/flexkit/${projectId}/members`,\n tools: (automationId) =>\n automationId ? `${basePath}/${encodeURIComponent(automationId)}/tools` : `${basePath}/tools`,\n };\n}\n"]}
|