diff --git a/web/app/dashboard/channels/_components/edit.tsx b/web/app/dashboard/channels/_components/edit.tsx index 79005eb..91cae2f 100644 --- a/web/app/dashboard/channels/_components/edit.tsx +++ b/web/app/dashboard/channels/_components/edit.tsx @@ -744,7 +744,7 @@ function WebAccessGuide({ channelId }: { channelId: string }) { channelId: "${channelId}" }; -` +` }, [channelId, origin]) async function copyText(text: string, successMessage: string) { diff --git a/web/app/dashboard/conversations/_components/chat-panel.tsx b/web/app/dashboard/conversations/_components/chat-panel.tsx index 03d8d26..91a03b6 100644 --- a/web/app/dashboard/conversations/_components/chat-panel.tsx +++ b/web/app/dashboard/conversations/_components/chat-panel.tsx @@ -350,7 +350,7 @@ export function ChatPanel() { const messagesScroll = (
{!loading && messages.length > 0 && messagesHasMore ? ( diff --git a/web/components/chat/shared-message-editor.tsx b/web/components/chat/shared-message-editor.tsx index 7c9880e..25a4bd0 100644 --- a/web/components/chat/shared-message-editor.tsx +++ b/web/components/chat/shared-message-editor.tsx @@ -446,9 +446,9 @@ export function SharedMessageEditor({ function getEditorClassName(variant: SharedMessageEditorVariant) { if (variant === "customer") { - return "cs-ai-agent-scrollbar min-h-12 max-h-40 overflow-y-auto px-1.5 py-1 text-sm leading-6 text-foreground outline-none [&_p]:m-0 [&_p+*]:mt-2 [&_.cs-ai-agent-editor-image-wrap]:my-2 [&_.cs-ai-agent-editor-image]:max-h-64 [&_.cs-ai-agent-editor-image]:max-w-full [&_.cs-ai-agent-editor-image]:rounded-lg [&_.cs-ai-agent-editor-image]:object-contain [&_.cs-ai-agent-editor-image-wrap-uploading_.cs-ai-agent-editor-image]:opacity-55" + return "agent-desk-scrollbar min-h-12 max-h-40 overflow-y-auto px-1.5 py-1 text-sm leading-6 text-foreground outline-none [&_p]:m-0 [&_p+*]:mt-2 [&_.agent-desk-editor-image-wrap]:my-2 [&_.agent-desk-editor-image]:max-h-64 [&_.agent-desk-editor-image]:max-w-full [&_.agent-desk-editor-image]:rounded-lg [&_.agent-desk-editor-image]:object-contain [&_.agent-desk-editor-image-wrap-uploading_.agent-desk-editor-image]:opacity-55" } - return "h-full min-h-12 max-h-[20vh] overflow-y-auto px-1.5 py-1 text-sm leading-6 text-foreground outline-none sm:max-h-none [&_.ProseMirror-focused]:outline-none [&_p]:m-0 [&_p+.cs-ai-agent-editor-image-wrap]:mt-2 [&_.cs-ai-agent-editor-image-wrap]:my-2 [&_.cs-ai-agent-editor-image]:max-h-64 [&_.cs-ai-agent-editor-image]:max-w-full [&_.cs-ai-agent-editor-image]:rounded-md [&_.cs-ai-agent-editor-image]:object-contain [&_.cs-ai-agent-editor-image-wrap-uploading_.cs-ai-agent-editor-image]:opacity-55 [&_p.is-editor-empty:first-child]:before:text-muted-foreground" + return "h-full min-h-12 max-h-[20vh] overflow-y-auto px-1.5 py-1 text-sm leading-6 text-foreground outline-none sm:max-h-none [&_.ProseMirror-focused]:outline-none [&_p]:m-0 [&_p+.agent-desk-editor-image-wrap]:mt-2 [&_.agent-desk-editor-image-wrap]:my-2 [&_.agent-desk-editor-image]:max-h-64 [&_.agent-desk-editor-image]:max-w-full [&_.agent-desk-editor-image]:rounded-md [&_.agent-desk-editor-image]:object-contain [&_.agent-desk-editor-image-wrap-uploading_.agent-desk-editor-image]:opacity-55 [&_p.is-editor-empty:first-child]:before:text-muted-foreground" } function getToolbarClassName(variant: SharedMessageEditorVariant) { diff --git a/web/components/support-chat/message-list.tsx b/web/components/support-chat/message-list.tsx index 135fc4c..e423e7b 100644 --- a/web/components/support-chat/message-list.tsx +++ b/web/components/support-chat/message-list.tsx @@ -219,7 +219,7 @@ export const SupportChatMessageList = forwardRef
{hasMoreOlder && onLoadOlder ? ( diff --git a/web/components/support-chat/widget-demo.tsx b/web/components/support-chat/widget-demo.tsx index 212059e..7007d6c 100644 --- a/web/components/support-chat/widget-demo.tsx +++ b/web/components/support-chat/widget-demo.tsx @@ -7,7 +7,7 @@ import { useEffect, useMemo, useState } from "react" import type { CSAgentConfig } from "@/lib/sdk/config-types" import { useI18n } from "@/i18n/provider" -const STORAGE_KEY = "cs-ai-agent-web-widget-test-config" +const STORAGE_KEY = "agent-desk-web-widget-test-config" const DEFAULT_JWT_TTL_MINUTES = "30" const INITIAL_CONFIG: CSAgentConfig = { channelId: "", @@ -56,7 +56,7 @@ function removeMountedWidget() { window.CSAgentWidget?.destroy() document .querySelectorAll( - '[data-cs-ai-agent-widget="launcher"], [data-cs-ai-agent-widget="frame"], [data-cs-ai-agent-widget="script"]' + '[data-agent-desk-widget="launcher"], [data-agent-desk-widget="frame"], [data-agent-desk-widget="script"]' ) .forEach((node) => node.remove()) @@ -72,7 +72,7 @@ function injectWidget(config: CSAgentConfig) { const script = document.createElement("script") script.async = true - script.src = `${window.location.origin}/sdk/cs-ai-agent-sdk.min.js` + script.src = `${window.location.origin}/sdk/agent-desk-sdk.min.js` script.dataset.csAgentWidget = "script" document.body.appendChild(script) } @@ -187,8 +187,8 @@ export function SupportWidgetDemo() { const snippet = useMemo(() => { const scriptSrc = origin - ? `${origin}/sdk/cs-ai-agent-sdk.min.js` - : "/sdk/cs-ai-agent-sdk.min.js" + ? `${origin}/sdk/agent-desk-sdk.min.js` + : "/sdk/agent-desk-sdk.min.js" const configLines = [` channelId: "${config.channelId || ""}"`] if (config.authMode === "jwt") { diff --git a/web/lib/auth.ts b/web/lib/auth.ts index e59d8cf..f4e94db 100644 --- a/web/lib/auth.ts +++ b/web/lib/auth.ts @@ -15,8 +15,8 @@ export type AuthSession = { roles: string[] } -const SESSION_STORAGE_KEY = "cs-ai-agent-session" -export const AUTH_SESSION_EXPIRED_EVENT = "cs-ai-agent-auth-expired" +const SESSION_STORAGE_KEY = "agent-desk-session" +export const AUTH_SESSION_EXPIRED_EVENT = "agent-desk-auth-expired" function hasWindow() { return typeof window !== "undefined" diff --git a/web/lib/im-editor-image.ts b/web/lib/im-editor-image.ts index 7722e5e..01289c2 100644 --- a/web/lib/im-editor-image.ts +++ b/web/lib/im-editor-image.ts @@ -30,15 +30,15 @@ export const MessageImageExtension = Image.extend({ return ({ node }) => { const wrapper = document.createElement("span") wrapper.className = - "cs-ai-agent-editor-image-wrap relative inline-block max-w-full align-middle" + "agent-desk-editor-image-wrap relative inline-block max-w-full align-middle" const image = document.createElement("img") - image.className = "cs-ai-agent-editor-image" + image.className = "agent-desk-editor-image" image.draggable = true const overlay = document.createElement("span") overlay.className = - "cs-ai-agent-editor-image-loading pointer-events-none absolute inset-0 hidden items-center justify-center rounded-lg bg-background/55 backdrop-blur-[1px]" + "agent-desk-editor-image-loading pointer-events-none absolute inset-0 hidden items-center justify-center rounded-lg bg-background/55 backdrop-blur-[1px]" const spinner = document.createElement("span") spinner.className = @@ -115,10 +115,10 @@ export function markEditorImageUploadedByTitle( image.setAttribute("data-provider", uploaded.provider) image.setAttribute("data-storage-key", uploaded.storageKey) image.setAttribute("alt", uploaded.filename || image.getAttribute("alt") || "image") - image.classList.remove("cs-ai-agent-editor-image-uploading") + image.classList.remove("agent-desk-editor-image-uploading") image.removeAttribute("data-uploading") image.removeAttribute("title") - setImageUploading(image.closest(".cs-ai-agent-editor-image-wrap"), false) + setImageUploading(image.closest(".agent-desk-editor-image-wrap"), false) } export function setEditorImageUploadingByTitle(editor: Editor, title: string) { @@ -126,9 +126,9 @@ export function setEditorImageUploadingByTitle(editor: Editor, title: string) { if (!image) { return } - image.classList.add("cs-ai-agent-editor-image-uploading") + image.classList.add("agent-desk-editor-image-uploading") image.setAttribute("data-uploading", "true") - setImageUploading(image.closest(".cs-ai-agent-editor-image-wrap"), true) + setImageUploading(image.closest(".agent-desk-editor-image-wrap"), true) } export function buildSendableEditorHTML( @@ -223,8 +223,8 @@ function setImageUploading(wrapper: Element | null, uploading: boolean) { if (!(wrapper instanceof HTMLElement)) { return } - wrapper.classList.toggle("cs-ai-agent-editor-image-wrap-uploading", uploading) - const overlay = wrapper.querySelector(".cs-ai-agent-editor-image-loading") + wrapper.classList.toggle("agent-desk-editor-image-wrap-uploading", uploading) + const overlay = wrapper.querySelector(".agent-desk-editor-image-loading") if (overlay) { overlay.classList.toggle("hidden", !uploading) overlay.classList.toggle("flex", uploading) diff --git a/web/lib/sdk/cs-ai-agent-sdk.test.mjs b/web/lib/sdk/agent-desk-sdk.test.mjs similarity index 95% rename from web/lib/sdk/cs-ai-agent-sdk.test.mjs rename to web/lib/sdk/agent-desk-sdk.test.mjs index ff325db..9b86368 100644 --- a/web/lib/sdk/cs-ai-agent-sdk.test.mjs +++ b/web/lib/sdk/agent-desk-sdk.test.mjs @@ -37,14 +37,14 @@ function createElement(tagName) { } async function loadSdk(config) { - const source = await readFile(new URL("./cs-ai-agent-sdk.ts", import.meta.url), "utf8") + const source = await readFile(new URL("./agent-desk-sdk.ts", import.meta.url), "utf8") const compiled = ts.transpileModule(source, { compilerOptions: { target: ts.ScriptTarget.ES2017, module: ts.ModuleKind.ESNext, importsNotUsedAsValues: ts.ImportsNotUsedAsValues.Remove, }, - fileName: "cs-ai-agent-sdk.ts", + fileName: "agent-desk-sdk.ts", }) const body = createElement("body") const sandbox = { @@ -62,7 +62,7 @@ async function loadSdk(config) { document: { body, currentScript: { - src: "https://chat.example/sdk/cs-ai-agent-sdk.min.js", + src: "https://chat.example/sdk/agent-desk-sdk.min.js", }, createElement, createElementNS: (_namespace, tagName) => createElement(tagName), diff --git a/web/lib/sdk/cs-ai-agent-sdk.ts b/web/lib/sdk/agent-desk-sdk.ts similarity index 95% rename from web/lib/sdk/cs-ai-agent-sdk.ts rename to web/lib/sdk/agent-desk-sdk.ts index e0ba673..1280f4c 100644 --- a/web/lib/sdk/cs-ai-agent-sdk.ts +++ b/web/lib/sdk/agent-desk-sdk.ts @@ -57,10 +57,10 @@ function getLauncherText() { } type FrameMessage = - | { type: "cs-ai-agent:init"; payload: SupportChatRuntimeConfig } - | { type: "cs-ai-agent:open" } - | { type: "cs-ai-agent:minimize" } - | { type: "cs-ai-agent:maximized"; payload: { isMaximized: boolean } } + | { type: "agent-desk:init"; payload: SupportChatRuntimeConfig } + | { type: "agent-desk:open" } + | { type: "agent-desk:minimize" } + | { type: "agent-desk:maximized"; payload: { isMaximized: boolean } } (function () { const DEFAULT_CONFIG: Pick< @@ -115,7 +115,7 @@ type FrameMessage = function resolveWidgetBaseUrl(config: NormalizedCSAgentConfig) { const currentScript = document.currentScript as HTMLScriptElement | null if (currentScript?.src) { - return currentScript.src.replace(/\/sdk\/cs-ai-agent-sdk\.min\.js(?:\?.*)?$/, "") + return currentScript.src.replace(/\/sdk\/agent-desk-sdk\.min\.js(?:\?.*)?$/, "") } return String(config.widgetBaseUrl || config.baseUrl || window.location.origin).replace(/\/$/, "") } @@ -272,7 +272,7 @@ type FrameMessage = try { state.frame.contentWindow.postMessage(message, state.frameUrl.origin) } catch (error) { - console.error("[cs-ai-agent-widget] postMessage failed", error) + console.error("[agent-desk-widget] postMessage failed", error) } } @@ -284,14 +284,14 @@ type FrameMessage = if (!state.initSent) { state.initSent = true postToFrame({ - type: "cs-ai-agent:init", + type: "agent-desk:init", payload: state.frameConfig || createFrameConfig(state.config, ""), }) } - postToFrame({ type: state.isOpen ? "cs-ai-agent:open" : "cs-ai-agent:minimize" }) + postToFrame({ type: state.isOpen ? "agent-desk:open" : "agent-desk:minimize" }) postToFrame({ - type: "cs-ai-agent:maximized", + type: "agent-desk:maximized", payload: { isMaximized: state.isMaximized }, }) } @@ -392,24 +392,24 @@ type FrameMessage = } const data = (event.data || {}) as { type?: string } - if (data.type === "cs-ai-agent:ready") { + if (data.type === "agent-desk:ready") { state.frameReady = true flushFrameState() return } - if (data.type === "cs-ai-agent:request-minimize") { + if (data.type === "agent-desk:request-minimize") { state.isOpen = false syncFrameVisibility() return } - if (data.type === "cs-ai-agent:request-close") { + if (data.type === "agent-desk:request-close") { destroyFrame() return } - if (data.type === "cs-ai-agent:request-toggle-maximize") { + if (data.type === "agent-desk:request-toggle-maximize") { state.isMaximized = !state.isMaximized syncFrameVisibility() } @@ -499,7 +499,7 @@ type FrameMessage = state.config.baseUrl = widgetBaseUrl } if (!state.config.channelId) { - console.error("[cs-ai-agent-widget] channelId is required") + console.error("[agent-desk-widget] channelId is required") return } @@ -548,7 +548,7 @@ type FrameMessage = syncFrameVisibility() }) .catch((error) => { - console.error("[cs-ai-agent-widget] open failed", error) + console.error("[agent-desk-widget] open failed", error) }) } diff --git a/web/lib/support-host-bridge.ts b/web/lib/support-host-bridge.ts index 014628e..1ca3ef6 100644 --- a/web/lib/support-host-bridge.ts +++ b/web/lib/support-host-bridge.ts @@ -8,14 +8,14 @@ type HostBridgeOptions = { onMaximizedChange?: (isMaximized: boolean) => void } -const INIT_MESSAGE_TYPE = "cs-ai-agent:init" -const OPEN_MESSAGE_TYPE = "cs-ai-agent:open" -const MINIMIZE_MESSAGE_TYPE = "cs-ai-agent:minimize" -const MAXIMIZED_MESSAGE_TYPE = "cs-ai-agent:maximized" -const READY_MESSAGE_TYPE = "cs-ai-agent:ready" -const REQUEST_MINIMIZE_MESSAGE_TYPE = "cs-ai-agent:request-minimize" -const REQUEST_CLOSE_MESSAGE_TYPE = "cs-ai-agent:request-close" -const REQUEST_TOGGLE_MAXIMIZE_MESSAGE_TYPE = "cs-ai-agent:request-toggle-maximize" +const INIT_MESSAGE_TYPE = "agent-desk:init" +const OPEN_MESSAGE_TYPE = "agent-desk:open" +const MINIMIZE_MESSAGE_TYPE = "agent-desk:minimize" +const MAXIMIZED_MESSAGE_TYPE = "agent-desk:maximized" +const READY_MESSAGE_TYPE = "agent-desk:ready" +const REQUEST_MINIMIZE_MESSAGE_TYPE = "agent-desk:request-minimize" +const REQUEST_CLOSE_MESSAGE_TYPE = "agent-desk:request-close" +const REQUEST_TOGGLE_MAXIMIZE_MESSAGE_TYPE = "agent-desk:request-toggle-maximize" export function bindSupportHostBridge(options: HostBridgeOptions = {}) { if (typeof window === "undefined") { diff --git a/web/public/sdk/agent-desk-sdk.min.js b/web/public/sdk/agent-desk-sdk.min.js new file mode 100644 index 0000000..9643c19 --- /dev/null +++ b/web/public/sdk/agent-desk-sdk.min.js @@ -0,0 +1 @@ +var __rest=this&&this.__rest||function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var r=0;for(i=Object.getOwnPropertySymbols(e);rString(e||"").trim())}catch(e){return Promise.reject(e)}}().then(e=>{if(!n.config)throw new Error("channelId is required");return n.frameUrl=function(e,t){const n=r(e),i=new URL(`${n}/support/chat/`);return i.searchParams.set("channelId",e.channelId),i.searchParams.set("baseUrl",e.baseUrl),e.apiBaseUrl&&i.searchParams.set("apiBaseUrl",e.apiBaseUrl),e.externalId&&i.searchParams.set("externalId",e.externalId),e.externalName&&i.searchParams.set("externalName",e.externalName),t&&i.searchParams.set("userToken",t),i}(n.config,e),n.frameConfig=a(n.config,e),n.frameUrl})}function s(){n.frameHideTimer&&(window.clearTimeout(n.frameHideTimer),n.frameHideTimer=null),n.frameDestroyTimer&&(window.clearTimeout(n.frameDestroyTimer),n.frameDestroyTimer=null)}function l(){const e=n.frame,t=n.config;if(e&&t){if(e.style.position="fixed",e.style.border="0",e.style.overflow="hidden",e.style.background="#fff",e.style.zIndex="2147483000",e.style.boxShadow="0 28px 80px rgba(15, 35, 65, 0.28)",e.style.willChange="top,right,bottom,left,width,height,opacity,transform,border-radius",e.style.transition="top 260ms cubic-bezier(0.22, 1, 0.36, 1), right 260ms cubic-bezier(0.22, 1, 0.36, 1), bottom 260ms cubic-bezier(0.22, 1, 0.36, 1), left 260ms cubic-bezier(0.22, 1, 0.36, 1), width 260ms cubic-bezier(0.22, 1, 0.36, 1), height 260ms cubic-bezier(0.22, 1, 0.36, 1), opacity 220ms ease, transform 260ms cubic-bezier(0.22, 1, 0.36, 1), border-radius 260ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 260ms ease",e.style.transformOrigin="left"===t.position?"left bottom":"right bottom",n.isMaximized)return e.style.top="max(12px, env(safe-area-inset-top))",e.style.right="max(12px, env(safe-area-inset-right))",e.style.bottom="max(12px, env(safe-area-inset-bottom))",e.style.left="max(12px, env(safe-area-inset-left))",e.style.width="calc(100vw - max(12px, env(safe-area-inset-left)) - max(12px, env(safe-area-inset-right)))",e.style.maxWidth="none",e.style.height="calc(100dvh - max(12px, env(safe-area-inset-top)) - max(12px, env(safe-area-inset-bottom)))",void(e.style.borderRadius="20px");e.style.top="",e.style.bottom="max(88px, calc(72px + env(safe-area-inset-bottom)))",e.style.right="left"===t.position?"":"max(12px, env(safe-area-inset-right))",e.style.left="left"===t.position?"max(12px, env(safe-area-inset-left))":"",e.style.width=t.width||"380px",e.style.maxWidth="calc(100vw - max(12px, env(safe-area-inset-left)) - max(12px, env(safe-area-inset-right)))",e.style.height="min(760px, calc(100dvh - max(104px, calc(88px + env(safe-area-inset-bottom))) - max(12px, env(safe-area-inset-top))))",e.style.borderRadius="24px"}}function d(e){var t;if((null===(t=n.frame)||void 0===t?void 0:t.contentWindow)&&n.frameUrl)try{n.frame.contentWindow.postMessage(e,n.frameUrl.origin)}catch(e){console.error("[agent-desk-widget] postMessage failed",e)}}function c(){n.frame&&n.frameLoaded&&n.frameReady&&n.config&&(n.initSent||(n.initSent=!0,d({type:"agent-desk:init",payload:n.frameConfig||a(n.config,"")})),d({type:n.isOpen?"agent-desk:open":"agent-desk:minimize"}),d({type:"agent-desk:maximized",payload:{isMaximized:n.isMaximized}}))}function f(){const e=n.frame;if(e){if(s(),l(),e.style.display="block",n.isOpen)return e.style.visibility="visible",e.style.pointerEvents="auto",n.frameHideTimer=window.setTimeout(()=>{n.frame&&(n.frame.style.opacity="1",n.frame.style.transform="translate3d(0, 0, 0) scale(1)")},16),void c();e.style.pointerEvents="none",e.style.opacity="0",e.style.transform=n.isMaximized?"translate3d(0, 10px, 0) scale(0.985)":"translate3d(0, 16px, 0) scale(0.96)",n.frameHideTimer=window.setTimeout(()=>{n.frame&&!n.isOpen&&(n.frame.style.visibility="hidden")},n.animationDuration),c()}}function m(e){const t=e||window.CSAgentConfig||{channelId:""};n.config=i(t);const a=r(n.config);t.baseUrl||(n.config.baseUrl=a),n.config.channelId?(n.configLoading=!0,function(e){const t=String(e.apiBaseUrl||e.baseUrl||"").replace(/\/$/,"");if(!t||!e.channelId||"function"!=typeof fetch)return Promise.resolve(e);const n=`${t}/api/channel/config?channelId=${encodeURIComponent(e.channelId)}`;return fetch(n,{method:"GET",cache:"no-store",headers:{"X-Channel-Id":e.channelId}}).then(e=>e.json()).then(t=>t&&!1!==t.success?function(e,t){if(!t)return e;const n=Object.assign({},e);return["title","subtitle","themeColor","position","width"].forEach(e=>{const i=t[e];null!=i&&(n[e]=i)}),n}(e,t.data||{}):e).catch(()=>e)}(n.config).then(e=>{var t;n.configLoading=!1,n.config=i(e),(null===(t=n.button)||void 0===t?void 0:t.parentNode)&&(n.button.parentNode.removeChild(n.button),n.button=null),function(){if(n.button)return n.button;const e=n.config;if(!e)return null;const t=document.createElement("button"),i=document.createElementNS("http://www.w3.org/2000/svg","svg"),r=document.createElement("span");t.type="button",t.dataset.csAgentWidget="launcher",t.setAttribute("aria-label",e.title||getDefaultWidgetTitle()),i.setAttribute("viewBox","0 0 24 24"),i.setAttribute("fill","none"),i.setAttribute("stroke","currentColor"),i.setAttribute("stroke-width","2"),i.setAttribute("stroke-linecap","round"),i.setAttribute("stroke-linejoin","round"),i.setAttribute("aria-hidden","true"),i.style.width="24px",i.style.height="24px",i.style.flex="0 0 auto",["M3 11a9 9 0 1 1 18 0","M3 11h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z","M21 11h-3a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2z","M21 16v2a4 4 0 0 1-4 4h-5"].forEach(e=>{const t=document.createElementNS("http://www.w3.org/2000/svg","path");t.setAttribute("d",e),i.appendChild(t)}),r.textContent=getLauncherText(),r.style.display="block",t.style.position="fixed",t.style.bottom="24px",t.style.right="left"===e.position?"":"24px",t.style.left="left"===e.position?"24px":"",t.style.zIndex="2147483000",t.style.display="inline-flex",t.style.flexDirection="column",t.style.alignItems="center",t.style.justifyContent="center",t.style.gap="4px",t.style.width="64px",t.style.height="64px",t.style.border="0",t.style.borderRadius="999px",t.style.padding="0",t.style.background=e.themeColor||"#0f6cbd",t.style.color="#fff",t.style.font="600 13px/1 sans-serif",t.style.boxShadow="0 18px 40px rgba(15, 35, 65, 0.24)",t.style.cursor="pointer",t.appendChild(i),t.appendChild(r),t.addEventListener("click",()=>{if(n.isOpen)return n.isOpen=!1,void f();u()}),document.body.appendChild(t),n.button=t}()})):console.error("[agent-desk-widget] channelId is required")}function u(){return o().then(()=>{n.frame||(n.frame?n.frame:n.frameUrl&&n.config&&(n.frame=document.createElement("iframe"),n.frame.dataset.csAgentWidget="frame",n.frame.title=n.config.title||getDefaultWidgetTitle(),n.frame.src=n.frameUrl.toString(),l(),n.frame.style.display="block",n.frame.style.visibility="hidden",n.frame.style.pointerEvents="none",n.frame.style.opacity="0",n.frame.style.transform="translate3d(0, 18px, 0) scale(0.96)",n.frame.addEventListener("load",()=>{n.frameLoaded=!0,f()}),document.body.appendChild(n.frame),n.frame)),n.frame&&(n.isOpen=!0,f())}).catch(e=>{console.error("[agent-desk-widget] open failed",e)})}t||(window.__CS_AI_AGENT_WIDGET_STATE__=n),window.CSAgentWidget={mount:m,destroy:function(){var e,t;s(),(null===(e=n.frame)||void 0===e?void 0:e.parentNode)&&n.frame.parentNode.removeChild(n.frame),(null===(t=n.button)||void 0===t?void 0:t.parentNode)&&n.button.parentNode.removeChild(n.button),n.button=null,n.frame=null,n.frameLoaded=!1,n.frameReady=!1,n.initSent=!1,n.isOpen=!1,n.isMaximized=!1,n.configLoading=!1,n.frameConfig=null,n.frameUrl=null},open:()=>u(),close:()=>{n.isOpen=!1,f()},getChatUrl:()=>{var e;return n.config||m(window.CSAgentConfig||{channelId:""}),(null===(e=n.config)||void 0===e?void 0:e.channelId)?o().then(e=>e.toString()):Promise.reject(new Error("channelId is required"))}},n.listenerBound||(window.addEventListener("message",function(e){if(!n.frame||e.source!==n.frame.contentWindow)return;const t=e.data||{};return"agent-desk:ready"===t.type?(n.frameReady=!0,void c()):"agent-desk:request-minimize"===t.type?(n.isOpen=!1,void f()):void("agent-desk:request-close"!==t.type?"agent-desk:request-toggle-maximize"===t.type&&(n.isMaximized=!n.isMaximized,f()):n.frame&&(s(),n.frame.style.pointerEvents="none",n.frame.style.opacity="0",n.frame.style.transform="translate3d(0, 18px, 0) scale(0.94)",n.frame.style.visibility="hidden",n.frameDestroyTimer=window.setTimeout(()=>{n.frame&&(n.frame.parentNode&&n.frame.parentNode.removeChild(n.frame),n.frame=null,n.frameLoaded=!1,n.frameReady=!1,n.initSent=!1,n.isOpen=!1,n.isMaximized=!1,s())},n.animationDuration)))}),n.listenerBound=!0),window.CSAgentConfig&&m(window.CSAgentConfig)}(); diff --git a/web/public/sdk/cs-ai-agent-sdk.min.js b/web/public/sdk/cs-ai-agent-sdk.min.js deleted file mode 100644 index e934d85..0000000 --- a/web/public/sdk/cs-ai-agent-sdk.min.js +++ /dev/null @@ -1 +0,0 @@ -var __rest=this&&this.__rest||function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var r=0;for(i=Object.getOwnPropertySymbols(e);rString(e||"").trim())}catch(e){return Promise.reject(e)}}().then(e=>{if(!n.config)throw new Error("channelId is required");return n.frameUrl=function(e,t){const n=r(e),i=new URL(`${n}/support/chat/`);return i.searchParams.set("channelId",e.channelId),i.searchParams.set("baseUrl",e.baseUrl),e.apiBaseUrl&&i.searchParams.set("apiBaseUrl",e.apiBaseUrl),e.externalId&&i.searchParams.set("externalId",e.externalId),e.externalName&&i.searchParams.set("externalName",e.externalName),t&&i.searchParams.set("userToken",t),i}(n.config,e),n.frameConfig=a(n.config,e),n.frameUrl})}function s(){n.frameHideTimer&&(window.clearTimeout(n.frameHideTimer),n.frameHideTimer=null),n.frameDestroyTimer&&(window.clearTimeout(n.frameDestroyTimer),n.frameDestroyTimer=null)}function l(){const e=n.frame,t=n.config;if(e&&t){if(e.style.position="fixed",e.style.border="0",e.style.overflow="hidden",e.style.background="#fff",e.style.zIndex="2147483000",e.style.boxShadow="0 28px 80px rgba(15, 35, 65, 0.28)",e.style.willChange="top,right,bottom,left,width,height,opacity,transform,border-radius",e.style.transition="top 260ms cubic-bezier(0.22, 1, 0.36, 1), right 260ms cubic-bezier(0.22, 1, 0.36, 1), bottom 260ms cubic-bezier(0.22, 1, 0.36, 1), left 260ms cubic-bezier(0.22, 1, 0.36, 1), width 260ms cubic-bezier(0.22, 1, 0.36, 1), height 260ms cubic-bezier(0.22, 1, 0.36, 1), opacity 220ms ease, transform 260ms cubic-bezier(0.22, 1, 0.36, 1), border-radius 260ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 260ms ease",e.style.transformOrigin="left"===t.position?"left bottom":"right bottom",n.isMaximized)return e.style.top="max(12px, env(safe-area-inset-top))",e.style.right="max(12px, env(safe-area-inset-right))",e.style.bottom="max(12px, env(safe-area-inset-bottom))",e.style.left="max(12px, env(safe-area-inset-left))",e.style.width="calc(100vw - max(12px, env(safe-area-inset-left)) - max(12px, env(safe-area-inset-right)))",e.style.maxWidth="none",e.style.height="calc(100dvh - max(12px, env(safe-area-inset-top)) - max(12px, env(safe-area-inset-bottom)))",void(e.style.borderRadius="20px");e.style.top="",e.style.bottom="max(88px, calc(72px + env(safe-area-inset-bottom)))",e.style.right="left"===t.position?"":"max(12px, env(safe-area-inset-right))",e.style.left="left"===t.position?"max(12px, env(safe-area-inset-left))":"",e.style.width=t.width||"380px",e.style.maxWidth="calc(100vw - max(12px, env(safe-area-inset-left)) - max(12px, env(safe-area-inset-right)))",e.style.height="min(760px, calc(100dvh - max(104px, calc(88px + env(safe-area-inset-bottom))) - max(12px, env(safe-area-inset-top))))",e.style.borderRadius="24px"}}function c(e){var t;if((null===(t=n.frame)||void 0===t?void 0:t.contentWindow)&&n.frameUrl)try{n.frame.contentWindow.postMessage(e,n.frameUrl.origin)}catch(e){console.error("[cs-ai-agent-widget] postMessage failed",e)}}function d(){n.frame&&n.frameLoaded&&n.frameReady&&n.config&&(n.initSent||(n.initSent=!0,c({type:"cs-ai-agent:init",payload:n.frameConfig||a(n.config,"")})),c({type:n.isOpen?"cs-ai-agent:open":"cs-ai-agent:minimize"}),c({type:"cs-ai-agent:maximized",payload:{isMaximized:n.isMaximized}}))}function f(){const e=n.frame;if(e){if(s(),l(),e.style.display="block",n.isOpen)return e.style.visibility="visible",e.style.pointerEvents="auto",n.frameHideTimer=window.setTimeout(()=>{n.frame&&(n.frame.style.opacity="1",n.frame.style.transform="translate3d(0, 0, 0) scale(1)")},16),void d();e.style.pointerEvents="none",e.style.opacity="0",e.style.transform=n.isMaximized?"translate3d(0, 10px, 0) scale(0.985)":"translate3d(0, 16px, 0) scale(0.96)",n.frameHideTimer=window.setTimeout(()=>{n.frame&&!n.isOpen&&(n.frame.style.visibility="hidden")},n.animationDuration),d()}}function m(e){const t=e||window.CSAgentConfig||{channelId:""};n.config=i(t);const a=r(n.config);t.baseUrl||(n.config.baseUrl=a),n.config.channelId?(n.configLoading=!0,function(e){const t=String(e.apiBaseUrl||e.baseUrl||"").replace(/\/$/,"");if(!t||!e.channelId||"function"!=typeof fetch)return Promise.resolve(e);const n=`${t}/api/channel/config?channelId=${encodeURIComponent(e.channelId)}`;return fetch(n,{method:"GET",cache:"no-store",headers:{"X-Channel-Id":e.channelId}}).then(e=>e.json()).then(t=>t&&!1!==t.success?function(e,t){if(!t)return e;const n=Object.assign({},e);return["title","subtitle","themeColor","position","width"].forEach(e=>{const i=t[e];null!=i&&(n[e]=i)}),n}(e,t.data||{}):e).catch(()=>e)}(n.config).then(e=>{var t;n.configLoading=!1,n.config=i(e),(null===(t=n.button)||void 0===t?void 0:t.parentNode)&&(n.button.parentNode.removeChild(n.button),n.button=null),function(){if(n.button)return n.button;const e=n.config;if(!e)return null;const t=document.createElement("button"),i=document.createElementNS("http://www.w3.org/2000/svg","svg"),r=document.createElement("span");t.type="button",t.dataset.csAgentWidget="launcher",t.setAttribute("aria-label",e.title||getDefaultWidgetTitle()),i.setAttribute("viewBox","0 0 24 24"),i.setAttribute("fill","none"),i.setAttribute("stroke","currentColor"),i.setAttribute("stroke-width","2"),i.setAttribute("stroke-linecap","round"),i.setAttribute("stroke-linejoin","round"),i.setAttribute("aria-hidden","true"),i.style.width="24px",i.style.height="24px",i.style.flex="0 0 auto",["M3 11a9 9 0 1 1 18 0","M3 11h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z","M21 11h-3a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2z","M21 16v2a4 4 0 0 1-4 4h-5"].forEach(e=>{const t=document.createElementNS("http://www.w3.org/2000/svg","path");t.setAttribute("d",e),i.appendChild(t)}),r.textContent=getLauncherText(),r.style.display="block",t.style.position="fixed",t.style.bottom="24px",t.style.right="left"===e.position?"":"24px",t.style.left="left"===e.position?"24px":"",t.style.zIndex="2147483000",t.style.display="inline-flex",t.style.flexDirection="column",t.style.alignItems="center",t.style.justifyContent="center",t.style.gap="4px",t.style.width="64px",t.style.height="64px",t.style.border="0",t.style.borderRadius="999px",t.style.padding="0",t.style.background=e.themeColor||"#0f6cbd",t.style.color="#fff",t.style.font="600 13px/1 sans-serif",t.style.boxShadow="0 18px 40px rgba(15, 35, 65, 0.24)",t.style.cursor="pointer",t.appendChild(i),t.appendChild(r),t.addEventListener("click",()=>{if(n.isOpen)return n.isOpen=!1,void f();u()}),document.body.appendChild(t),n.button=t}()})):console.error("[cs-ai-agent-widget] channelId is required")}function u(){return o().then(()=>{n.frame||(n.frame?n.frame:n.frameUrl&&n.config&&(n.frame=document.createElement("iframe"),n.frame.dataset.csAgentWidget="frame",n.frame.title=n.config.title||getDefaultWidgetTitle(),n.frame.src=n.frameUrl.toString(),l(),n.frame.style.display="block",n.frame.style.visibility="hidden",n.frame.style.pointerEvents="none",n.frame.style.opacity="0",n.frame.style.transform="translate3d(0, 18px, 0) scale(0.96)",n.frame.addEventListener("load",()=>{n.frameLoaded=!0,f()}),document.body.appendChild(n.frame),n.frame)),n.frame&&(n.isOpen=!0,f())}).catch(e=>{console.error("[cs-ai-agent-widget] open failed",e)})}t||(window.__CS_AI_AGENT_WIDGET_STATE__=n),window.CSAgentWidget={mount:m,destroy:function(){var e,t;s(),(null===(e=n.frame)||void 0===e?void 0:e.parentNode)&&n.frame.parentNode.removeChild(n.frame),(null===(t=n.button)||void 0===t?void 0:t.parentNode)&&n.button.parentNode.removeChild(n.button),n.button=null,n.frame=null,n.frameLoaded=!1,n.frameReady=!1,n.initSent=!1,n.isOpen=!1,n.isMaximized=!1,n.configLoading=!1,n.frameConfig=null,n.frameUrl=null},open:()=>u(),close:()=>{n.isOpen=!1,f()},getChatUrl:()=>{var e;return n.config||m(window.CSAgentConfig||{channelId:""}),(null===(e=n.config)||void 0===e?void 0:e.channelId)?o().then(e=>e.toString()):Promise.reject(new Error("channelId is required"))}},n.listenerBound||(window.addEventListener("message",function(e){if(!n.frame||e.source!==n.frame.contentWindow)return;const t=e.data||{};return"cs-ai-agent:ready"===t.type?(n.frameReady=!0,void d()):"cs-ai-agent:request-minimize"===t.type?(n.isOpen=!1,void f()):void("cs-ai-agent:request-close"!==t.type?"cs-ai-agent:request-toggle-maximize"===t.type&&(n.isMaximized=!n.isMaximized,f()):n.frame&&(s(),n.frame.style.pointerEvents="none",n.frame.style.opacity="0",n.frame.style.transform="translate3d(0, 18px, 0) scale(0.94)",n.frame.style.visibility="hidden",n.frameDestroyTimer=window.setTimeout(()=>{n.frame&&(n.frame.parentNode&&n.frame.parentNode.removeChild(n.frame),n.frame=null,n.frameLoaded=!1,n.frameReady=!1,n.initSent=!1,n.isOpen=!1,n.isMaximized=!1,s())},n.animationDuration)))}),n.listenerBound=!0),window.CSAgentConfig&&m(window.CSAgentConfig)}(); diff --git a/web/scripts/build-sdk.mjs b/web/scripts/build-sdk.mjs index 7bb3c3d..c36bbd8 100644 --- a/web/scripts/build-sdk.mjs +++ b/web/scripts/build-sdk.mjs @@ -6,9 +6,9 @@ import ts from "typescript"; const currentDir = path.dirname(fileURLToPath(import.meta.url)); const rootDir = path.resolve(currentDir, ".."); -const source = path.join(rootDir, "lib", "sdk", "cs-ai-agent-sdk.ts"); +const source = path.join(rootDir, "lib", "sdk", "agent-desk-sdk.ts"); const targetDir = path.join(rootDir, "public", "sdk"); -const target = path.join(targetDir, "cs-ai-agent-sdk.min.js"); +const target = path.join(targetDir, "agent-desk-sdk.min.js"); await mkdir(targetDir, { recursive: true }); const sourceCode = await readFile(source, "utf8"); diff --git a/web/styles/main.scss b/web/styles/main.scss index 3bebbab..fcd8903 100644 --- a/web/styles/main.scss +++ b/web/styles/main.scss @@ -4,7 +4,7 @@ $thumb: #cbd5e1; $thumb-hover: #94a3b8; -.cs-ai-agent-scrollbar { +.agent-desk-scrollbar { scrollbar-width: thin; scrollbar-color: $thumb transparent; @@ -29,7 +29,7 @@ $thumb-hover: #94a3b8; } } -.dark .cs-ai-agent-scrollbar { +.dark .agent-desk-scrollbar { scrollbar-color: hsl(var(--border)) transparent; &::-webkit-scrollbar-thumb {