@lalternative/assistant 0.0.0-stage → 0.2.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/assistant-launcher.tsx","../src/assistant-panel.tsx","../src/attachments.ts","../src/format.ts","../src/icons.tsx","../src/labels.ts"],"sourcesContent":["import { useState } from \"react\";\nimport { AssistantPanel } from \"./assistant-panel\";\nimport { Icon } from \"./icons\";\nimport { defaultLabels } from \"./labels\";\nimport type { AssistantPanelProps } from \"./types\";\n\nexport type AssistantLauncherProps = Omit<AssistantPanelProps, \"onClose\" | \"initialHistory\">;\n\nexport function AssistantLauncher(props: AssistantLauncherProps) {\n const [open, setOpen] = useState(false);\n const [showHistory, setShowHistory] = useState(false);\n const labels = { ...defaultLabels, ...props.labels };\n const openPanel = (history: boolean) => {\n setShowHistory(history);\n setOpen(true);\n };\n if (open) return <AssistantPanel {...props} initialHistory={showHistory} onClose={() => setOpen(false)} />;\n return (\n <div className=\"lalt-assistant lalt-assistant-launcher\">\n <button type=\"button\" onClick={() => openPanel(true)} className=\"lalt-assistant-launch lalt-assistant-launch-secondary\">\n <Icon name=\"clock\" />\n {labels.history}\n </button>\n <button type=\"button\" onClick={() => openPanel(false)} className=\"lalt-assistant-launch lalt-assistant-launch-primary\">\n <Icon name=\"bot\" />\n {labels.launcher}\n </button>\n </div>\n );\n}\n","import {\n useCallback,\n useEffect,\n useRef,\n useState,\n type ClipboardEvent,\n type DragEvent,\n type KeyboardEvent,\n type PointerEvent as ReactPointerEvent,\n} from \"react\";\nimport { useAttachments, pastedFiles, type PendingAttachment } from \"./attachments\";\nimport { errorMessage, formatSize, relativeTime } from \"./format\";\nimport { Icon } from \"./icons\";\nimport { defaultLabels } from \"./labels\";\nimport type {\n AssistantConversationSummary,\n AssistantLabels,\n AssistantMessage,\n AssistantPanelProps,\n AssistantScope,\n} from \"./types\";\n\nconst MIN_WIDTH = 360;\nconst DEFAULT_WIDTH = 520;\nconst PASTED_TEXT_NAME = \"texte-colle.txt\";\n\nfunction storedWidth(key: string): number {\n try {\n const v = Number(localStorage.getItem(key));\n return v >= MIN_WIDTH ? v : DEFAULT_WIDTH;\n } catch {\n return DEFAULT_WIDTH;\n }\n}\n\nfunction usePanelWidth(key: string) {\n const [width, setWidth] = useState(() => storedWidth(key));\n const [expanded, setExpanded] = useState(false);\n const startResize = (e: ReactPointerEvent) => {\n e.preventDefault();\n setExpanded(false);\n let latest = width;\n const move = (ev: PointerEvent) => {\n latest = Math.max(MIN_WIDTH, Math.min(window.innerWidth - 80, window.innerWidth - ev.clientX));\n setWidth(latest);\n };\n const up = () => {\n window.removeEventListener(\"pointermove\", move);\n window.removeEventListener(\"pointerup\", up);\n try {\n localStorage.setItem(key, String(latest));\n } catch {\n return;\n }\n };\n window.addEventListener(\"pointermove\", move);\n window.addEventListener(\"pointerup\", up);\n };\n return { width, expanded, setExpanded, startResize };\n}\n\nexport function AssistantPanel({\n api,\n scopes,\n scopeId,\n onScopeChange,\n scopeLocked = false,\n quickActions = [],\n attachmentLimits,\n pasteAsFileThreshold,\n labels: labelOverrides,\n renderMarkdown,\n renderScopePicker,\n renderMessageFooter,\n readScreen,\n widthStorageKey = \"lalt.assistant.width\",\n onClose,\n initialHistory = false,\n}: AssistantPanelProps) {\n const labels: AssistantLabels = { ...defaultLabels, ...labelOverrides };\n const scopeLabel = scopes.find((s) => s.id === scopeId)?.label ?? \"\";\n\n const [conversationId, setConversationId] = useState<string | undefined>();\n const [thread, setThread] = useState<AssistantMessage[]>([]);\n const [draft, setDraft] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [historyOpen, setHistoryOpen] = useState(initialHistory);\n const [menuOpen, setMenuOpen] = useState(false);\n const [pending, setPending] = useState(false);\n const [loading, setLoading] = useState(false);\n const [dragging, setDragging] = useState(false);\n const [conversations, setConversations] = useState<AssistantConversationSummary[]>([]);\n const fileInput = useRef<HTMLInputElement>(null);\n const endRef = useRef<HTMLDivElement>(null);\n const generation = useRef(0);\n\n const attachments = useAttachments({ attach: api.attach?.bind(api), scopeId, limits: attachmentLimits, labels });\n\n const refreshConversations = useCallback(() => {\n api.listConversations().then(setConversations, (err: unknown) => setError(errorMessage(err, labels.requestFailed)));\n }, [api, labels.requestFailed]);\n\n useEffect(refreshConversations, [refreshConversations]);\n\n useEffect(() => {\n endRef.current?.scrollIntoView?.({ block: \"end\" });\n }, [thread.length, pending]);\n\n const newConversation = () => {\n generation.current++;\n setThread([]);\n setConversationId(undefined);\n setError(null);\n setHistoryOpen(false);\n setMenuOpen(false);\n setPending(false);\n attachments.clear();\n };\n\n const openConversation = (c: AssistantConversationSummary) => {\n const current = ++generation.current;\n setHistoryOpen(false);\n setMenuOpen(false);\n setError(null);\n setLoading(true);\n api.getConversation(c.id).then(\n (detail) => {\n if (current !== generation.current) return;\n setThread(detail.messages);\n setConversationId(detail.id);\n if (detail.scopeId && detail.scopeId !== scopeId) onScopeChange?.(detail.scopeId);\n setLoading(false);\n },\n (err: unknown) => {\n if (current !== generation.current) return;\n setError(errorMessage(err, labels.requestFailed));\n setLoading(false);\n },\n );\n };\n\n const canSend = !!scopeId && !pending && !attachments.uploading;\n\n const send = (message: string, shownAs: string) => {\n const ready = attachments.done;\n if (!canSend || (!message.trim() && ready.length === 0)) return false;\n const current = generation.current;\n setError(null);\n setHistoryOpen(false);\n setPending(true);\n setThread((t) => [...t, { role: \"user\", content: shownAs, attachments: ready }]);\n attachments.clear();\n api\n .send({\n scopeId,\n conversationId,\n message,\n attachmentIds: ready.map((a) => a.id),\n screen: readScreen?.(),\n })\n .then(\n (res) => {\n if (current !== generation.current) return;\n setConversationId(res.conversationId);\n setThread((t) => [...t, { role: \"assistant\", content: res.answer, meta: res.meta }]);\n setPending(false);\n refreshConversations();\n },\n (err: unknown) => {\n if (current !== generation.current) return;\n setError(errorMessage(err, labels.requestFailed));\n setPending(false);\n },\n );\n return true;\n };\n\n const submit = () => {\n const text = draft.trim();\n if (send(text, text)) setDraft(\"\");\n };\n\n const onKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n submit();\n }\n };\n\n const onPaste = (e: ClipboardEvent<HTMLTextAreaElement>) => {\n if (!attachments.enabled) return;\n const files = pastedFiles(e.clipboardData, pasteAsFileThreshold, PASTED_TEXT_NAME);\n if (files.length === 0) return;\n e.preventDefault();\n attachments.add(files);\n };\n\n const onDragOver = (e: DragEvent) => {\n if (!attachments.enabled || !Array.from(e.dataTransfer?.types ?? []).includes(\"Files\")) return;\n e.preventDefault();\n setDragging(true);\n };\n\n const onDrop = (e: DragEvent) => {\n if (!attachments.enabled) return;\n e.preventDefault();\n setDragging(false);\n attachments.add(Array.from(e.dataTransfer?.files ?? []));\n };\n\n const empty = thread.length === 0 && !pending && !loading;\n const panel = usePanelWidth(widthStorageKey);\n\n return (\n <aside\n role=\"dialog\"\n aria-label={labels.launcher}\n className=\"lalt-assistant lalt-assistant-panel\"\n data-expanded={panel.expanded || undefined}\n style={{ [\"--lalt-assistant-width\" as string]: panel.expanded ? \"min(1100px, 92vw)\" : `${panel.width}px` }}\n onDragOver={onDragOver}\n onDragLeave={(e) => {\n if (e.currentTarget === e.target) setDragging(false);\n }}\n onDrop={onDrop}\n >\n <div\n onPointerDown={panel.startResize}\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={labels.resize}\n className=\"lalt-assistant-resize\"\n />\n {dragging && <div className=\"lalt-assistant-dropzone\">{labels.dropHere}</div>}\n <header className=\"lalt-assistant-header\">\n <div className=\"lalt-assistant-menu\">\n <button type=\"button\" className=\"lalt-assistant-title\" onClick={() => setMenuOpen((v) => !v)} aria-expanded={menuOpen}>\n <Icon name=\"bot\" />\n {labels.launcher}\n <Icon name=\"chevronDown\" size={14} className=\"lalt-assistant-muted\" />\n </button>\n {menuOpen && (\n <div role=\"menu\" className=\"lalt-assistant-menu-content\">\n <button type=\"button\" role=\"menuitem\" onClick={newConversation}>\n <Icon name=\"plus\" />\n {labels.newConversation}\n </button>\n {conversations.length > 0 && (\n <>\n <div className=\"lalt-assistant-menu-label\">{labels.recent}</div>\n {conversations.slice(0, 5).map((c) => (\n <button key={c.id} type=\"button\" role=\"menuitem\" onClick={() => openConversation(c)}>\n <span className=\"lalt-assistant-grow lalt-assistant-truncate\">{c.title}</span>\n <span className=\"lalt-assistant-muted lalt-assistant-small\">{relativeTime(c.updatedAt)}</span>\n </button>\n ))}\n </>\n )}\n <div className=\"lalt-assistant-menu-separator\" />\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => {\n setMenuOpen(false);\n setHistoryOpen(true);\n }}\n >\n <Icon name=\"clock\" />\n {labels.allHistory}\n </button>\n </div>\n )}\n </div>\n <div className=\"lalt-assistant-grow\" />\n {scopeLocked || scopes.length <= 1 ? (\n <span className=\"lalt-assistant-muted lalt-assistant-small lalt-assistant-truncate lalt-assistant-scope-label\">\n {scopeLabel}\n </span>\n ) : renderScopePicker ? (\n renderScopePicker({\n scopes,\n scopeId,\n label: labels.scope,\n onChange: (id) => {\n onScopeChange?.(id);\n newConversation();\n },\n })\n ) : (\n <select\n value={scopeId}\n onChange={(e) => {\n onScopeChange?.(e.target.value);\n newConversation();\n }}\n aria-label={labels.scope}\n className=\"lalt-assistant-select\"\n >\n {scopes.map((s) => (\n <option key={s.id} value={s.id}>\n {s.label}\n </option>\n ))}\n </select>\n )}\n <button\n type=\"button\"\n onClick={() => panel.setExpanded((v) => !v)}\n aria-label={panel.expanded ? labels.collapse : labels.expand}\n className=\"lalt-assistant-icon-button lalt-assistant-wide-only\"\n >\n <Icon name={panel.expanded ? \"minimize\" : \"maximize\"} />\n </button>\n <button type=\"button\" onClick={onClose} aria-label={labels.close} className=\"lalt-assistant-icon-button\">\n <Icon name=\"x\" />\n </button>\n </header>\n\n <div className=\"lalt-assistant-body\">\n {historyOpen ? (\n <HistoryList conversations={conversations} scopes={scopes} labels={labels} onOpen={openConversation} />\n ) : empty ? (\n <div>\n <h2 className=\"lalt-assistant-empty-title\">{labels.emptyTitle}</h2>\n {labels.intro && <p className=\"lalt-assistant-intro\">{labels.intro}</p>}\n <div className=\"lalt-assistant-actions\">\n {quickActions.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n onClick={() => send(a.prompt, a.label)}\n disabled={!canSend}\n className=\"lalt-assistant-action\"\n >\n <div className=\"lalt-assistant-action-label\">{a.label}</div>\n {a.hint && <div className=\"lalt-assistant-muted lalt-assistant-small\">{a.hint}</div>}\n </button>\n ))}\n </div>\n </div>\n ) : (\n <div className=\"lalt-assistant-thread\">\n {thread.map((m, i) =>\n m.role === \"user\" ? (\n <div key={i} className=\"lalt-assistant-user\">\n {m.content}\n {m.attachments && m.attachments.length > 0 && (\n <div className=\"lalt-assistant-sent-files\">\n {m.attachments.map((a) => (\n <span key={a.id} className=\"lalt-assistant-sent-file\">\n <Icon name=\"file\" size={12} />\n {a.filename}\n </span>\n ))}\n </div>\n )}\n </div>\n ) : (\n <div key={i} className=\"lalt-assistant-answer\">\n {renderMarkdown ? renderMarkdown(m.content) : <div className=\"lalt-assistant-plain\">{m.content}</div>}\n {renderMessageFooter?.(m)}\n </div>\n ),\n )}\n {(pending || loading) && (\n <div className=\"lalt-assistant-muted lalt-assistant-small lalt-assistant-status\">\n <span className=\"lalt-assistant-spinner\" />\n {loading ? labels.loading : labels.thinking}\n </div>\n )}\n </div>\n )}\n {error && (\n <p role=\"alert\" className=\"lalt-assistant-error\">\n {error}\n </p>\n )}\n <div ref={endRef} />\n </div>\n\n <div className=\"lalt-assistant-footer\">\n <div className=\"lalt-assistant-composer\">\n {(attachments.items.length > 0 || attachments.notice) && (\n <div className=\"lalt-assistant-chips\">\n {attachments.items.map((item) => (\n <AttachmentChip key={item.localId} item={item} labels={labels} onRemove={() => attachments.remove(item.localId)} />\n ))}\n {attachments.notice && <p className=\"lalt-assistant-error\">{attachments.notice}</p>}\n </div>\n )}\n <textarea\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={onKeyDown}\n onPaste={onPaste}\n rows={3}\n placeholder={labels.placeholder}\n aria-label=\"Message\"\n className=\"lalt-assistant-textarea\"\n />\n <div className=\"lalt-assistant-composer-row\">\n {attachments.enabled && (\n <>\n <button\n type=\"button\"\n onClick={() => fileInput.current?.click()}\n aria-label={labels.attach}\n title={labels.attach}\n className=\"lalt-assistant-icon-button\"\n >\n <Icon name=\"paperclip\" />\n </button>\n <input\n ref={fileInput}\n type=\"file\"\n multiple\n hidden\n data-testid=\"lalt-assistant-file-input\"\n accept={attachmentLimits ? [...attachmentLimits.imageTypes, ...attachmentLimits.fileTypes].join(\",\") : undefined}\n onChange={(e) => {\n attachments.add(Array.from(e.target.files ?? []));\n e.target.value = \"\";\n }}\n />\n </>\n )}\n <div className=\"lalt-assistant-grow\" />\n <button\n type=\"button\"\n onClick={submit}\n disabled={!canSend || (!draft.trim() && attachments.done.length === 0)}\n aria-label={labels.send}\n className=\"lalt-assistant-send\"\n >\n <Icon name=\"arrowUp\" />\n </button>\n </div>\n </div>\n </div>\n </aside>\n );\n}\n\nfunction AttachmentChip({ item, labels, onRemove }: { item: PendingAttachment; labels: AssistantLabels; onRemove: () => void }) {\n return (\n <div className=\"lalt-assistant-chip\" data-status={item.status} title={item.error}>\n {item.previewUrl ? <img src={item.previewUrl} alt=\"\" className=\"lalt-assistant-chip-preview\" /> : <Icon name=\"file\" size={14} />}\n <span className=\"lalt-assistant-chip-text\">\n <span className=\"lalt-assistant-truncate\">{item.file.name}</span>\n <span className=\"lalt-assistant-muted lalt-assistant-small\">\n {item.status === \"error\" ? item.error : item.status === \"uploading\" ? labels.uploading : formatSize(item.file.size)}\n </span>\n </span>\n {item.status === \"uploading\" && <span className=\"lalt-assistant-spinner\" />}\n <button type=\"button\" onClick={onRemove} aria-label={`${labels.removeAttachment} ${item.file.name}`} className=\"lalt-assistant-chip-remove\">\n <Icon name=\"x\" size={12} />\n </button>\n </div>\n );\n}\n\nfunction HistoryList({\n conversations,\n scopes,\n labels,\n onOpen,\n}: {\n conversations: AssistantConversationSummary[];\n scopes: AssistantScope[];\n labels: AssistantLabels;\n onOpen: (c: AssistantConversationSummary) => void;\n}) {\n if (conversations.length === 0) {\n return <p className=\"lalt-assistant-muted lalt-assistant-history-empty\">{labels.noConversation}</p>;\n }\n return (\n <ul className=\"lalt-assistant-history\">\n {conversations.map((c) => {\n const scope = scopes.find((s) => s.id === c.scopeId)?.label;\n return (\n <li key={c.id}>\n <button type=\"button\" onClick={() => onOpen(c)}>\n <div className=\"lalt-assistant-truncate\">{c.title}</div>\n <div className=\"lalt-assistant-muted lalt-assistant-small\">\n {[scope, relativeTime(c.updatedAt)].filter(Boolean).join(\" · \")}\n </div>\n </button>\n </li>\n );\n })}\n </ul>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { formatSize } from \"./format\";\nimport type { AssistantAttachment, AssistantLabels, AttachmentLimits } from \"./types\";\n\nexport interface PendingAttachment {\n localId: string;\n file: File;\n status: \"uploading\" | \"done\" | \"error\";\n error?: string;\n attachment?: AssistantAttachment;\n previewUrl?: string;\n}\n\nconst typesByExtension: Record<string, string> = {\n txt: \"text/plain\",\n log: \"text/plain\",\n md: \"text/markdown\",\n markdown: \"text/markdown\",\n csv: \"text/csv\",\n json: \"application/json\",\n xml: \"application/xml\",\n yaml: \"application/yaml\",\n yml: \"application/yaml\",\n html: \"text/html\",\n};\n\nexport function withType(file: File): File {\n if (file.type) return file;\n const type = typesByExtension[file.name.split(\".\").pop()?.toLowerCase() ?? \"\"];\n return type ? new File([file], file.name, { type }) : file;\n}\n\nexport function fileError(file: File, limits: AttachmentLimits | undefined, labels: AssistantLabels): string | undefined {\n if (!limits) return undefined;\n const type = file.type.toLowerCase();\n if (limits.imageTypes.includes(type)) {\n return file.size > limits.maxImageBytes ? labels.fileTooLarge(file.name, formatSize(limits.maxImageBytes)) : undefined;\n }\n if (limits.fileTypes.includes(type)) {\n return file.size > limits.maxFileBytes ? labels.fileTooLarge(file.name, formatSize(limits.maxFileBytes)) : undefined;\n }\n return labels.fileTypeRefused(file.name);\n}\n\nexport function pastedFiles(data: DataTransfer | null, pasteAsFileThreshold: number | undefined, name: string): File[] {\n if (!data) return [];\n const files = Array.from(data.items ?? [])\n .filter((item) => item.kind === \"file\")\n .map((item) => item.getAsFile())\n .filter((f): f is File => f !== null);\n if (files.length > 0) return files;\n const text = data.getData(\"text/plain\");\n if (pasteAsFileThreshold !== undefined && text.length > pasteAsFileThreshold) {\n return [new File([text], name, { type: \"text/plain\" })];\n }\n return [];\n}\n\nfunction previewOf(file: File): string | undefined {\n if (!file.type.startsWith(\"image/\") || typeof URL.createObjectURL !== \"function\") return undefined;\n return URL.createObjectURL(file);\n}\n\nfunction revoke(item: PendingAttachment) {\n if (item.previewUrl && typeof URL.revokeObjectURL === \"function\") URL.revokeObjectURL(item.previewUrl);\n}\n\nlet nextId = 0;\n\nexport function useAttachments({\n attach,\n scopeId,\n limits,\n labels,\n}: {\n attach?: (file: File, scopeId: string) => Promise<AssistantAttachment>;\n scopeId: string;\n limits?: AttachmentLimits;\n labels: AssistantLabels;\n}) {\n const [items, setItems] = useState<PendingAttachment[]>([]);\n const [notice, setNotice] = useState<string | null>(null);\n const itemsRef = useRef(items);\n itemsRef.current = items;\n\n useEffect(() => () => itemsRef.current.forEach(revoke), []);\n\n const update = (localId: string, patch: Partial<PendingAttachment>) =>\n setItems((list) => list.map((i) => (i.localId === localId ? { ...i, ...patch } : i)));\n\n const add = useCallback(\n (incoming: File[]) => {\n if (!attach || incoming.length === 0) return;\n setNotice(null);\n const room = limits ? limits.maxCount - itemsRef.current.length : incoming.length;\n if (incoming.length > room) setNotice(labels.tooManyFiles(limits?.maxCount ?? 0));\n const accepted = incoming.slice(0, Math.max(0, room)).map((raw) => {\n const file = withType(raw);\n const error = fileError(file, limits, labels);\n const item: PendingAttachment = {\n localId: `a${nextId++}`,\n file,\n status: error ? \"error\" : \"uploading\",\n error,\n previewUrl: error ? undefined : previewOf(file),\n };\n return item;\n });\n if (accepted.length === 0) return;\n itemsRef.current = [...itemsRef.current, ...accepted];\n setItems(itemsRef.current);\n for (const item of accepted) {\n if (item.status !== \"uploading\") continue;\n attach(item.file, scopeId).then(\n (attachment) => update(item.localId, { status: \"done\", attachment }),\n (err: unknown) =>\n update(item.localId, { status: \"error\", error: (err as { message?: string })?.message || labels.uploadFailed }),\n );\n }\n },\n [attach, scopeId, limits, labels],\n );\n\n const remove = useCallback((localId: string) => {\n setItems((list) => {\n list.filter((i) => i.localId === localId).forEach(revoke);\n return list.filter((i) => i.localId !== localId);\n });\n setNotice(null);\n }, []);\n\n const clear = useCallback(() => {\n itemsRef.current.forEach(revoke);\n itemsRef.current = [];\n setItems([]);\n setNotice(null);\n }, []);\n\n const done = items.filter((i) => i.status === \"done\" && i.attachment).map((i) => i.attachment as AssistantAttachment);\n return {\n enabled: !!attach,\n items,\n notice,\n done,\n uploading: items.some((i) => i.status === \"uploading\"),\n add,\n remove,\n clear,\n };\n}\n","export function relativeTime(iso: string | undefined, now = Date.now()): string {\n if (!iso) return \"\";\n const minutes = Math.round((now - new Date(iso).getTime()) / 60000);\n if (minutes < 1) return \"à l'instant\";\n if (minutes < 60) return `il y a ${minutes} min`;\n const hours = Math.round(minutes / 60);\n if (hours < 24) return `il y a ${hours} heure${hours > 1 ? \"s\" : \"\"}`;\n const days = Math.round(hours / 24);\n return `il y a ${days} jour${days > 1 ? \"s\" : \"\"}`;\n}\n\nexport function formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} o`;\n if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} Ko`;\n return `${(bytes / (1024 * 1024)).toFixed(1).replace(/\\.0$/, \"\")} Mo`;\n}\n\nconst SCREEN_TEXT_LIMIT = 12000;\n\nexport function readMainScreen(): { path: string; title: string; text: string } | undefined {\n if (typeof document === \"undefined\") return undefined;\n const main = document.querySelector(\"main\");\n const text = (main?.innerText ?? \"\").replace(/\\n{3,}/g, \"\\n\\n\").trim().slice(0, SCREEN_TEXT_LIMIT);\n return { path: window.location.pathname + window.location.search, title: document.title, text };\n}\n\nexport function errorMessage(error: unknown, fallback: string): string {\n const e = error as { message?: string } | null;\n return e?.message || fallback;\n}\n","import type { ReactNode } from \"react\";\n\nconst paths: Record<string, ReactNode> = {\n bot: (\n <>\n <path d=\"M12 8V4H8\" />\n <rect width=\"16\" height=\"12\" x=\"4\" y=\"8\" rx=\"2\" />\n <path d=\"M2 14h2M20 14h2M15 13v2M9 13v2\" />\n </>\n ),\n clock: (\n <>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 6v6l4 2\" />\n </>\n ),\n chevronDown: <path d=\"m6 9 6 6 6-6\" />,\n plus: <path d=\"M5 12h14M12 5v14\" />,\n x: <path d=\"M18 6 6 18M6 6l12 12\" />,\n maximize: <path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\" />,\n minimize: <path d=\"M4 14h6v6M20 10h-6V4M14 10l7-7M3 21l7-7\" />,\n arrowUp: <path d=\"m5 12 7-7 7 7M12 19V5\" />,\n paperclip: (\n <path d=\"m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48\" />\n ),\n file: (\n <>\n <path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\" />\n <path d=\"M14 2v4a2 2 0 0 0 2 2h4\" />\n </>\n ),\n};\n\nexport type IconName = keyof typeof paths;\n\nexport function Icon({ name, size = 16, className }: { name: IconName; size?: number; className?: string }) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n className={className}\n >\n {paths[name]}\n </svg>\n );\n}\n","import type { AssistantLabels } from \"./types\";\n\nexport const defaultLabels: AssistantLabels = {\n launcher: \"Assistant\",\n history: \"Historique\",\n newConversation: \"Nouvelle conversation\",\n recent: \"Récentes\",\n allHistory: \"Voir tout l'historique\",\n emptyTitle: \"Que puis-je faire ?\",\n intro: \"\",\n noConversation: \"Aucune conversation pour l'instant.\",\n placeholder: \"Décrivez votre besoin…\",\n send: \"Envoyer\",\n attach: \"Joindre un fichier\",\n removeAttachment: \"Retirer\",\n close: \"Fermer\",\n expand: \"Agrandir\",\n collapse: \"Réduire\",\n resize: \"Redimensionner l'assistant\",\n scope: \"Projet\",\n loading: \"Chargement…\",\n thinking: \"L'assistant regarde — ça peut prendre un moment.\",\n dropHere: \"Déposez vos fichiers ici\",\n uploading: \"Envoi…\",\n tooManyFiles: (max) => `Au plus ${max} fichiers par message.`,\n fileTooLarge: (name, max) => `${name} dépasse ${max}.`,\n fileTypeRefused: (name) => `${name} : type de fichier non accepté.`,\n uploadFailed: \"L'envoi du fichier a échoué.\",\n requestFailed: \"La requête à l'assistant a échoué.\",\n};\n"],"mappings":"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","names":["useState","useCallback","useEffect","useRef","useState","Fragment","jsx","jsxs","useState","useRef","useCallback","useEffect","jsx","jsxs","useState"]}
package/package.json CHANGED
@@ -1,6 +1,49 @@
1
1
  {
2
2
  "name": "@lalternative/assistant",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0",
4
+ "description": "Shared floating AI assistant UI for L'Alternative apps (launcher, resizable drawer, history, attachments) over a host-supplied capability adapter",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./styles.css": "./dist/assistant.css"
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "prepublishOnly": "tsup",
21
+ "dev": "tsup --watch",
22
+ "typecheck": "tsc --noEmit",
23
+ "test": "vitest run"
24
+ },
25
+ "peerDependencies": {
26
+ "react": ">=18.0.0",
27
+ "react-dom": ">=18.0.0"
28
+ },
29
+ "devDependencies": {
30
+ "@testing-library/react": "^16.3.0",
31
+ "@types/react": "^19.0.0",
32
+ "@types/react-dom": "^19.0.0",
33
+ "jsdom": "^26.1.0",
34
+ "react": "^19.2.0",
35
+ "react-dom": "^19.2.0",
36
+ "tsup": "^8.5.1",
37
+ "typescript": "^5.7.0",
38
+ "vitest": "^4.0.0"
39
+ },
40
+ "publishConfig": {
41
+ "registry": "https://registry.npmjs.org",
42
+ "access": "public"
43
+ },
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "https://github.com/lalternative/packages.git",
47
+ "directory": "assistant"
48
+ }
49
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.