claudius-chat-widget 1.6.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.
Files changed (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +89 -0
  3. package/dist/api/client.d.ts +24 -0
  4. package/dist/api/errors.d.ts +9 -0
  5. package/dist/api/index.d.ts +4 -0
  6. package/dist/api/types.d.ts +22 -0
  7. package/dist/claudius.cjs +2 -0
  8. package/dist/claudius.css +1 -0
  9. package/dist/claudius.iife.js +41 -0
  10. package/dist/claudius.js +1373 -0
  11. package/dist/components/ChatInput.d.ts +9 -0
  12. package/dist/components/ChatMessage.d.ts +10 -0
  13. package/dist/components/ChatSources.d.ts +7 -0
  14. package/dist/components/ChatToggleButton.d.ts +10 -0
  15. package/dist/components/ChatWidget.d.ts +29 -0
  16. package/dist/components/ChatWindow.d.ts +21 -0
  17. package/dist/components/GreetingBubble.d.ts +10 -0
  18. package/dist/components/SourceIcon.d.ts +7 -0
  19. package/dist/embed.d.ts +38 -0
  20. package/dist/hooks/useChat.d.ts +20 -0
  21. package/dist/hooks/useFocusTrap.d.ts +2 -0
  22. package/dist/hooks/useMediaQuery.d.ts +1 -0
  23. package/dist/hooks/useSwipeToDismiss.d.ts +4 -0
  24. package/dist/hooks/useTriggers.d.ts +32 -0
  25. package/dist/i18n.d.ts +21 -0
  26. package/dist/index.d.ts +12 -0
  27. package/dist/locales/de.d.ts +2 -0
  28. package/dist/locales/en.d.ts +2 -0
  29. package/dist/locales/es.d.ts +2 -0
  30. package/dist/locales/fr.d.ts +2 -0
  31. package/dist/locales/index.d.ts +9 -0
  32. package/dist/main.d.ts +1 -0
  33. package/dist/test-utils/MockChatApiClient.d.ts +64 -0
  34. package/dist/theme/index.d.ts +4 -0
  35. package/dist/theme/resolve.d.ts +19 -0
  36. package/dist/theme/themes.d.ts +8 -0
  37. package/dist/theme/types.d.ts +34 -0
  38. package/dist/theme/useTheme.d.ts +14 -0
  39. package/dist/utils/sanitize.d.ts +36 -0
  40. package/dist/utils/stripAnnouncementFormatting.d.ts +1 -0
  41. package/package.json +102 -0
@@ -0,0 +1,9 @@
1
+ import type { ClaudiusTranslations } from "../i18n";
2
+ interface ChatInputProps {
3
+ onSend: (message: string) => void;
4
+ isLoading: boolean;
5
+ placeholder?: string;
6
+ translations?: ClaudiusTranslations;
7
+ }
8
+ export declare function ChatInput({ onSend, isLoading, placeholder, translations, }: ChatInputProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { Source } from "../api/types";
2
+ interface ChatMessageProps {
3
+ role: "user" | "assistant";
4
+ content: string;
5
+ sources?: Source[];
6
+ onSourceClick?: () => void;
7
+ isSourceActive?: boolean;
8
+ }
9
+ export declare const ChatMessage: import("react").NamedExoticComponent<ChatMessageProps>;
10
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { Source } from "../api/types";
2
+ interface ChatSourcesProps {
3
+ sources: Source[];
4
+ onClose: () => void;
5
+ }
6
+ export declare const ChatSources: import("react").NamedExoticComponent<ChatSourcesProps>;
7
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { WidgetPosition } from "./ChatWidget";
2
+ import type { ClaudiusTranslations } from "../i18n";
3
+ interface ChatToggleButtonProps {
4
+ isOpen: boolean;
5
+ onClick: () => void;
6
+ position?: WidgetPosition;
7
+ translations?: ClaudiusTranslations;
8
+ }
9
+ export declare const ChatToggleButton: import("react").ForwardRefExoticComponent<ChatToggleButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
10
+ export {};
@@ -0,0 +1,29 @@
1
+ import { type Trigger } from "../hooks/useTriggers";
2
+ import { ClaudiusTranslations, defaultTranslations, createTranslations } from "../i18n";
3
+ import { type LocaleCode } from "../locales";
4
+ import type { ClaudiusThemeInput } from "../theme/types";
5
+ export type WidgetPosition = "bottom-right" | "bottom-left" | "top-right" | "top-left";
6
+ export interface ChatWidgetProps {
7
+ apiUrl: string;
8
+ title?: string;
9
+ subtitle?: string;
10
+ welcomeMessage?: string;
11
+ placeholder?: string;
12
+ persistMessages?: boolean;
13
+ storageKeyPrefix?: string;
14
+ requestTimeoutMs?: number;
15
+ /**
16
+ * Color-scheme mode ("light" | "dark" | "auto"), a built-in theme name
17
+ * ("default" | "minimal" | "playful" | "corporate"), an inline
18
+ * ClaudiusTheme object, or a URL to a theme JSON file.
19
+ */
20
+ theme?: ClaudiusThemeInput;
21
+ accentColor?: string;
22
+ position?: WidgetPosition;
23
+ locale?: LocaleCode;
24
+ translations?: Partial<ClaudiusTranslations>;
25
+ triggers?: Trigger[];
26
+ }
27
+ export declare function ChatWidget({ apiUrl, title, subtitle, welcomeMessage, placeholder, persistMessages, storageKeyPrefix, requestTimeoutMs, theme, accentColor, position, locale, translations: translationOverrides, triggers, }: ChatWidgetProps): import("react/jsx-runtime").JSX.Element;
28
+ export { defaultTranslations, createTranslations };
29
+ export type { ClaudiusTranslations };
@@ -0,0 +1,21 @@
1
+ import type { WidgetPosition } from "./ChatWidget";
2
+ import type { ClaudiusTranslations } from "../i18n";
3
+ import type { ChatMessage as ChatMessageData } from "../api/types";
4
+ interface ChatWindowProps {
5
+ messages: ChatMessageData[];
6
+ isLoading: boolean;
7
+ error: string | null;
8
+ canRetry?: boolean;
9
+ onSend: (message: string) => void;
10
+ onRetry?: () => void;
11
+ onClose: () => void;
12
+ title?: string;
13
+ subtitle?: string;
14
+ welcomeMessage?: string;
15
+ placeholder?: string;
16
+ position?: WidgetPosition;
17
+ translations?: ClaudiusTranslations;
18
+ isMobile?: boolean;
19
+ }
20
+ export declare function ChatWindow({ messages, isLoading, error, canRetry, onSend, onRetry, onClose, title, subtitle, welcomeMessage, placeholder, position, translations, isMobile, }: ChatWindowProps): import("react/jsx-runtime").JSX.Element;
21
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { WidgetPosition } from "./ChatWidget";
2
+ interface GreetingBubbleProps {
3
+ message: string;
4
+ position: WidgetPosition;
5
+ onOpen: () => void;
6
+ onDismiss: () => void;
7
+ dismissLabel: string;
8
+ }
9
+ export declare function GreetingBubble({ message, position, onOpen, onDismiss, dismissLabel, }: GreetingBubbleProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,7 @@
1
+ interface SourceIconProps {
2
+ count: number;
3
+ isActive: boolean;
4
+ onClick: () => void;
5
+ }
6
+ export declare const SourceIcon: import("react").NamedExoticComponent<SourceIconProps>;
7
+ export {};
@@ -0,0 +1,38 @@
1
+ import { WidgetPosition } from "./components/ChatWidget";
2
+ import type { Trigger } from "./hooks/useTriggers";
3
+ import type { LocaleCode } from "./locales";
4
+ import type { ClaudiusTranslations } from "./i18n";
5
+ import type { ClaudiusThemeInput } from "./theme/types";
6
+ import "./styles.css";
7
+ interface ClaudiusConfig {
8
+ apiUrl: string;
9
+ title?: string;
10
+ subtitle?: string;
11
+ welcomeMessage?: string;
12
+ placeholder?: string;
13
+ persistMessages?: boolean;
14
+ storageKeyPrefix?: string;
15
+ requestTimeoutMs?: number;
16
+ theme?: ClaudiusThemeInput;
17
+ accentColor?: string;
18
+ position?: WidgetPosition;
19
+ locale?: LocaleCode;
20
+ translations?: Partial<ClaudiusTranslations>;
21
+ triggers?: Trigger[];
22
+ }
23
+ declare global {
24
+ interface Window {
25
+ ClaudiusConfig?: ClaudiusConfig;
26
+ ClaudiusWidgetVersion?: string;
27
+ }
28
+ }
29
+ declare class ClaudiusChat extends HTMLElement {
30
+ private root;
31
+ private container;
32
+ static get observedAttributes(): string[];
33
+ connectedCallback(): void;
34
+ disconnectedCallback(): void;
35
+ attributeChangedCallback(): void;
36
+ private render;
37
+ }
38
+ export { ClaudiusChat };
@@ -0,0 +1,20 @@
1
+ import type { ClaudiusTranslations } from "../i18n";
2
+ import type { ChatMessage } from "../api/types";
3
+ interface UseChatOptions {
4
+ apiUrl: string;
5
+ persistMessages?: boolean;
6
+ storageKeyPrefix?: string;
7
+ timeoutMs?: number;
8
+ translations?: ClaudiusTranslations;
9
+ }
10
+ interface UseChatReturn {
11
+ messages: ChatMessage[];
12
+ isLoading: boolean;
13
+ error: string | null;
14
+ canRetry: boolean;
15
+ sendMessage: (content: string) => Promise<void>;
16
+ retry: () => Promise<void>;
17
+ clearMessages: () => void;
18
+ }
19
+ export declare function useChat({ apiUrl, persistMessages, storageKeyPrefix, timeoutMs, translations, }: UseChatOptions): UseChatReturn;
20
+ export type { ChatMessage };
@@ -0,0 +1,2 @@
1
+ import { type RefObject } from "react";
2
+ export declare function useFocusTrap(containerRef: RefObject<HTMLElement>, active: boolean): void;
@@ -0,0 +1 @@
1
+ export declare function useMediaQuery(query: string): boolean;
@@ -0,0 +1,4 @@
1
+ import { RefObject } from "react";
2
+ export declare function useSwipeToDismiss(sheetRef: RefObject<HTMLElement | null>, onDismiss: () => void, enabled: boolean): {
3
+ offsetY: number;
4
+ };
@@ -0,0 +1,32 @@
1
+ export type UrlPattern = string | RegExp;
2
+ export type TriggerAction = "open" | {
3
+ greeting: string;
4
+ };
5
+ export type Trigger = {
6
+ on: "time";
7
+ seconds: number;
8
+ matchUrl?: UrlPattern;
9
+ action: TriggerAction;
10
+ } | {
11
+ on: "scroll";
12
+ percent: number;
13
+ matchUrl?: UrlPattern;
14
+ action: TriggerAction;
15
+ } | {
16
+ on: "exit-intent";
17
+ matchUrl?: UrlPattern;
18
+ action: TriggerAction;
19
+ } | {
20
+ on: "url";
21
+ pattern: UrlPattern;
22
+ action: TriggerAction;
23
+ };
24
+ interface UseTriggersOptions {
25
+ triggers?: Trigger[];
26
+ enabled: boolean;
27
+ onOpen: () => void;
28
+ onGreeting: (message: string) => void;
29
+ }
30
+ export declare function matchesUrl(pattern: UrlPattern, url: string): boolean;
31
+ export declare function useTriggers({ triggers, enabled, onOpen, onGreeting, }: UseTriggersOptions): void;
32
+ export {};
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ export interface ClaudiusTranslations {
2
+ title: string;
3
+ subtitle: string;
4
+ welcomeMessage: string;
5
+ closeChat: string;
6
+ chatMessages: string;
7
+ typingIndicator: string;
8
+ placeholder: string;
9
+ sendMessage: string;
10
+ typeYourMessage: string;
11
+ openChat: string;
12
+ dismissGreeting: string;
13
+ errorGeneric: string;
14
+ errorConnection: string;
15
+ errorTimeout: string;
16
+ errorRateLimitMinute: string;
17
+ errorRateLimitHour: string;
18
+ errorRetry: string;
19
+ }
20
+ export declare const defaultTranslations: ClaudiusTranslations;
21
+ export declare function createTranslations(overrides?: Partial<ClaudiusTranslations>): ClaudiusTranslations;
@@ -0,0 +1,12 @@
1
+ export { ChatWidget } from "./components/ChatWidget";
2
+ export type { ChatWidgetProps, WidgetPosition, ClaudiusTranslations, } from "./components/ChatWidget";
3
+ export { defaultTranslations, createTranslations } from "./i18n";
4
+ export { locales, detectLocale, resolveTranslations } from "./locales";
5
+ export type { LocaleCode } from "./locales";
6
+ export type { Trigger, TriggerAction, UrlPattern } from "./hooks/useTriggers";
7
+ export { builtinThemes } from "./theme";
8
+ export type { ClaudiusTheme, ClaudiusThemeInput, BuiltinThemeName, ThemeColorToken, ThemeRadiusToken, ThemeShadowToken, ThemeFontToken, } from "./theme";
9
+ export { ChatApiClient } from "./api/client";
10
+ export type { ChatApiClientOptions } from "./api/client";
11
+ export { ChatApiError, DebounceError } from "./api/errors";
12
+ export type { Source, ChatMessage, ChatRequest, ChatResponse, ChatErrorResponse, } from "./api/types";
@@ -0,0 +1,2 @@
1
+ import type { ClaudiusTranslations } from "../i18n";
2
+ export declare const de: ClaudiusTranslations;
@@ -0,0 +1,2 @@
1
+ import type { ClaudiusTranslations } from "../i18n";
2
+ export declare const en: ClaudiusTranslations;
@@ -0,0 +1,2 @@
1
+ import type { ClaudiusTranslations } from "../i18n";
2
+ export declare const es: ClaudiusTranslations;
@@ -0,0 +1,2 @@
1
+ import type { ClaudiusTranslations } from "../i18n";
2
+ export declare const fr: ClaudiusTranslations;
@@ -0,0 +1,9 @@
1
+ import type { ClaudiusTranslations } from "../i18n";
2
+ export type LocaleCode = "en" | "es" | "fr" | "de";
3
+ export declare const locales: Record<LocaleCode, ClaudiusTranslations>;
4
+ export declare function detectLocale(): LocaleCode;
5
+ export interface ResolveTranslationsOptions {
6
+ locale?: LocaleCode;
7
+ translations?: Partial<ClaudiusTranslations>;
8
+ }
9
+ export declare function resolveTranslations(options?: ResolveTranslationsOptions): ClaudiusTranslations;
package/dist/main.d.ts ADDED
@@ -0,0 +1 @@
1
+ import "./styles.css";
@@ -0,0 +1,64 @@
1
+ import type { ChatMessage, ChatResponse } from "../api/types";
2
+ import { ChatApiError, DebounceError } from "../api/errors";
3
+ /**
4
+ * Programmable test double for `ChatApiClient`. Tests queue responses with
5
+ * `mockReply` / `mockError` / `mockTimeout`; calls to `sendMessage` consume
6
+ * one queued response per call (FIFO). When the queue is empty the client
7
+ * blocks on a `pending` promise so tests can drive loading-state assertions
8
+ * before resolving.
9
+ *
10
+ * Usage:
11
+ * const mock = new MockChatApiClient();
12
+ * installChatApiClientMock(mock); // before render / hook init
13
+ * mock.mockReply({ reply: "Hi!" });
14
+ * ...
15
+ */
16
+ export type QueuedResponse = {
17
+ kind: "reply";
18
+ response: ChatResponse;
19
+ } | {
20
+ kind: "error";
21
+ error: ChatApiError | DebounceError | Error;
22
+ } | {
23
+ kind: "timeout";
24
+ } | {
25
+ kind: "pending";
26
+ promise: Promise<ChatResponse>;
27
+ };
28
+ export declare class MockChatApiClient {
29
+ readonly calls: ChatMessage[][];
30
+ sendMessage: import("vitest").Mock<(messages: ChatMessage[]) => Promise<ChatResponse>>;
31
+ private queue;
32
+ /** Queue a successful reply for the next sendMessage call. */
33
+ mockReply(response: ChatResponse): this;
34
+ /** Queue a ChatApiError (or arbitrary Error) for the next call. */
35
+ mockError(error: ChatApiError | DebounceError | Error): this;
36
+ /** Queue a timeout-style failure (status 0, code "TIMEOUT"). */
37
+ mockTimeout(message?: string): this;
38
+ /** Queue a network failure (status 0, code "NETWORK_ERROR"). */
39
+ mockNetworkError(message?: string): this;
40
+ /**
41
+ * Queue a deferred reply. Returns a `resolve` function the test can call
42
+ * later to settle the in-flight request — useful for asserting the
43
+ * loading state mid-flight.
44
+ */
45
+ mockPending(): {
46
+ resolve: (response: ChatResponse) => void;
47
+ reject: (err: unknown) => void;
48
+ };
49
+ /** Total messages received across all sendMessage calls (last call). */
50
+ get lastCall(): ChatMessage[] | undefined;
51
+ /** Clear queued responses and call history. */
52
+ reset(): void;
53
+ private handleSend;
54
+ }
55
+ /**
56
+ * Install the mock as the implementation of `ChatApiClient` for the current
57
+ * test. Must be paired with `vi.mock("../api/client", ...)` at module
58
+ * top-level, since vi.mock is hoisted; this helper just wires the
59
+ * already-mocked constructor to return our instance.
60
+ *
61
+ * Most tests should call `useMockChatApiClient()` instead — it bundles the
62
+ * vi.mock setup with creation.
63
+ */
64
+ export declare function installChatApiClientMock(mock: MockChatApiClient): Promise<void>;
@@ -0,0 +1,4 @@
1
+ export { THEME_COLOR_TOKENS, THEME_RADIUS_TOKENS, THEME_SHADOW_TOKENS, THEME_FONT_TOKENS, } from "./types";
2
+ export type { ClaudiusTheme, ClaudiusThemeInput, BuiltinThemeName, ThemeColorToken, ThemeRadiusToken, ThemeShadowToken, ThemeFontToken, } from "./types";
3
+ export { builtinThemes, isBuiltinThemeName } from "./themes";
4
+ export { resolveThemeInput, themeToCssVars, type ResolvedThemeInput, type ColorSchemeMode, } from "./resolve";
@@ -0,0 +1,19 @@
1
+ import { type ClaudiusTheme, type ClaudiusThemeInput } from "./types";
2
+ export type ColorSchemeMode = "light" | "dark" | "auto";
3
+ export interface ResolvedThemeInput {
4
+ mode: ColorSchemeMode;
5
+ theme?: ClaudiusTheme;
6
+ /** Set when the input is a URL to a theme JSON file (fetched separately). */
7
+ url?: string;
8
+ }
9
+ /**
10
+ * Classifies the `theme` option. Mode strings keep their original meaning;
11
+ * built-in names map to their theme objects; any other string is a URL.
12
+ */
13
+ export declare function resolveThemeInput(input: ClaudiusThemeInput | undefined): ResolvedThemeInput;
14
+ /**
15
+ * Converts a theme object into the --cl-* custom-property map applied to the
16
+ * widget root. Light colors mirror into the -dark variables so themed tokens
17
+ * survive dark mode; `colorsDark` overrides the mirror per token.
18
+ */
19
+ export declare function themeToCssVars(theme: ClaudiusTheme): Record<string, string>;
@@ -0,0 +1,8 @@
1
+ import type { BuiltinThemeName, ClaudiusTheme } from "./types";
2
+ /**
3
+ * Built-in themes. `default` is intentionally empty: the baked-in token
4
+ * defaults (see tailwind.config.ts fallbacks and the dark block in
5
+ * styles.css) ARE the default theme.
6
+ */
7
+ export declare const builtinThemes: Record<BuiltinThemeName, ClaudiusTheme>;
8
+ export declare function isBuiltinThemeName(value: string): value is BuiltinThemeName;
@@ -0,0 +1,34 @@
1
+ export declare const THEME_COLOR_TOKENS: readonly ["accent", "accentText", "accentSoft", "accentTextMuted", "surface", "surfaceMuted", "text", "textMuted", "border", "userBubble", "userBubbleText", "assistantBubble", "assistantBubbleText", "field", "error", "errorSurface", "errorText", "link", "scrim"];
2
+ export declare const THEME_RADIUS_TOKENS: readonly ["sm", "md", "lg", "full", "tail"];
3
+ export declare const THEME_SHADOW_TOKENS: readonly ["elevated", "floating", "floatingHover"];
4
+ export declare const THEME_FONT_TOKENS: readonly ["heading", "body"];
5
+ export type ThemeColorToken = (typeof THEME_COLOR_TOKENS)[number];
6
+ export type ThemeRadiusToken = (typeof THEME_RADIUS_TOKENS)[number];
7
+ export type ThemeShadowToken = (typeof THEME_SHADOW_TOKENS)[number];
8
+ export type ThemeFontToken = (typeof THEME_FONT_TOKENS)[number];
9
+ /**
10
+ * A Claudius design-token theme. Every value is a CSS string applied via
11
+ * --cl-* custom properties. `colors` apply to both light and dark modes
12
+ * unless `colorsDark` overrides a token for dark mode specifically.
13
+ *
14
+ * JSON theme files validate against
15
+ * https://claudius-docs.pages.dev/schema/theme.v1.json
16
+ */
17
+ export interface ClaudiusTheme {
18
+ $schema?: string;
19
+ name?: string;
20
+ /** Initial color scheme this theme is designed for. Defaults to "light". */
21
+ colorScheme?: "light" | "dark" | "auto";
22
+ colors?: Partial<Record<ThemeColorToken, string>>;
23
+ colorsDark?: Partial<Record<ThemeColorToken, string>>;
24
+ radii?: Partial<Record<ThemeRadiusToken, string>>;
25
+ shadows?: Partial<Record<ThemeShadowToken, string>>;
26
+ fonts?: Partial<Record<ThemeFontToken, string>>;
27
+ }
28
+ export type BuiltinThemeName = "default" | "minimal" | "playful" | "corporate";
29
+ /**
30
+ * Everything the `theme` option accepts: the original color-scheme modes, a
31
+ * built-in theme name, an inline theme object, or a URL to a theme JSON file.
32
+ * `(string & {})` keeps literal autocomplete while allowing URLs.
33
+ */
34
+ export type ClaudiusThemeInput = "light" | "dark" | "auto" | BuiltinThemeName | ClaudiusTheme | (string & {});
@@ -0,0 +1,14 @@
1
+ import { type ColorSchemeMode } from "./resolve";
2
+ import type { ClaudiusThemeInput } from "./types";
3
+ export interface UseThemeResult {
4
+ mode: ColorSchemeMode;
5
+ /** --cl-* custom properties to apply inline on the widget root. */
6
+ cssVars: Record<string, string>;
7
+ }
8
+ /**
9
+ * Resolves the `theme` option into a color-scheme mode and a set of CSS
10
+ * custom properties. URL inputs are fetched; any failure (network, JSON,
11
+ * shape) logs one console.error and leaves the default theme active so the
12
+ * widget never breaks because a theme file is unreachable.
13
+ */
14
+ export declare function useTheme(input: ClaudiusThemeInput | undefined): UseThemeResult;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Sanitization utilities for XSS prevention.
3
+ *
4
+ * The widget uses React element rendering (not innerHTML) which is inherently
5
+ * safe for text content. These utilities handle edge cases like URL schemes.
6
+ */
7
+ /** Maximum allowed message length */
8
+ export declare const MAX_MESSAGE_LENGTH = 2000;
9
+ /**
10
+ * Validates and sanitizes a URL to prevent javascript:, data:, vbscript: attacks.
11
+ *
12
+ * @param url - The URL to sanitize
13
+ * @returns The original URL if safe, or null if potentially malicious
14
+ */
15
+ export declare function sanitizeUrl(url: string): string | null;
16
+ /**
17
+ * Checks if a URL is safe to use as an href.
18
+ *
19
+ * @param url - The URL to check
20
+ * @returns true if the URL is safe, false otherwise
21
+ */
22
+ export declare function isUrlSafe(url: string): boolean;
23
+ /**
24
+ * Validates message content length.
25
+ *
26
+ * @param content - The message content to validate
27
+ * @returns true if the content is within the allowed length
28
+ */
29
+ export declare function isValidMessageLength(content: string): boolean;
30
+ /**
31
+ * Sanitizes message content by trimming and enforcing length limits.
32
+ *
33
+ * @param content - The message content to sanitize
34
+ * @returns Sanitized content, or empty string if invalid
35
+ */
36
+ export declare function sanitizeMessageContent(content: string): string;
@@ -0,0 +1 @@
1
+ export declare function stripAnnouncementFormatting(content: string): string;
package/package.json ADDED
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "claudius-chat-widget",
3
+ "version": "1.6.0",
4
+ "type": "module",
5
+ "description": "Embeddable AI chat widget powered by Claude. Drop-in React component or standalone script embed, backed by a Cloudflare Worker.",
6
+ "keywords": [
7
+ "react",
8
+ "chat-widget",
9
+ "ai-chat",
10
+ "claude",
11
+ "anthropic",
12
+ "cloudflare-workers",
13
+ "embeddable-widget",
14
+ "customer-support",
15
+ "typescript"
16
+ ],
17
+ "author": "PAMulligan",
18
+ "license": "MIT",
19
+ "homepage": "https://claudius-docs.pages.dev",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/PMDevSolutions/Claudius.git",
23
+ "directory": "widget"
24
+ },
25
+ "bugs": {
26
+ "url": "https://github.com/PMDevSolutions/Claudius/issues"
27
+ },
28
+ "sideEffects": [
29
+ "**/*.css"
30
+ ],
31
+ "main": "./dist/claudius.cjs",
32
+ "module": "./dist/claudius.js",
33
+ "types": "./dist/index.d.ts",
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.ts",
37
+ "import": "./dist/claudius.js",
38
+ "require": "./dist/claudius.cjs"
39
+ },
40
+ "./embed": "./dist/claudius.iife.js",
41
+ "./style.css": "./dist/claudius.css"
42
+ },
43
+ "files": [
44
+ "dist"
45
+ ],
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "scripts": {
50
+ "dev": "vite",
51
+ "build": "vite build && vite build --config vite.config.embed.ts && tsc --emitDeclarationOnly",
52
+ "build:lib": "vite build && tsc --emitDeclarationOnly",
53
+ "build:embed": "vite build --config vite.config.embed.ts",
54
+ "test": "vitest run",
55
+ "test:watch": "vitest",
56
+ "test:coverage": "vitest run --coverage",
57
+ "e2e": "playwright test",
58
+ "e2e:ui": "playwright test --ui",
59
+ "e2e:install": "playwright install chromium",
60
+ "lint": "eslint src/",
61
+ "lint:fix": "eslint src/ --fix",
62
+ "format": "prettier --write \"src/**/*.{ts,tsx,css}\"",
63
+ "format:check": "prettier --check \"src/**/*.{ts,tsx,css}\"",
64
+ "typecheck": "tsc --noEmit",
65
+ "storybook": "storybook dev -p 6006",
66
+ "build-storybook": "storybook build"
67
+ },
68
+ "peerDependencies": {
69
+ "react": "^18.0.0 || ^19.0.0",
70
+ "react-dom": "^18.0.0 || ^19.0.0"
71
+ },
72
+ "devDependencies": {
73
+ "@eslint/js": "^9.24.0",
74
+ "@playwright/test": "^1.59.1",
75
+ "@storybook/react-vite": "10.4.1",
76
+ "@testing-library/jest-dom": "^6.6.0",
77
+ "@testing-library/react": "^16.3.0",
78
+ "@testing-library/user-event": "^14.6.0",
79
+ "@types/react": "^18.3.0",
80
+ "@types/react-dom": "^18.3.0",
81
+ "@vitejs/plugin-react": "^4.4.0",
82
+ "@vitest/coverage-v8": "^4.1.5",
83
+ "ajv": "^8.20.0",
84
+ "autoprefixer": "^10.4.0",
85
+ "eslint": "^9.24.0",
86
+ "eslint-config-prettier": "^10.1.0",
87
+ "eslint-plugin-jsx-a11y": "^6.10.2",
88
+ "eslint-plugin-react-hooks": "^5.2.0",
89
+ "eslint-plugin-react-refresh": "^0.4.20",
90
+ "jsdom": "^26.0.0",
91
+ "postcss": "^8.5.0",
92
+ "prettier": "^3.5.0",
93
+ "react": "^18.3.0",
94
+ "react-dom": "^18.3.0",
95
+ "storybook": "10.4.1",
96
+ "tailwindcss": "^3.4.0",
97
+ "typescript": "^5.8.0",
98
+ "typescript-eslint": "^8.30.0",
99
+ "vite": "^6.2.0",
100
+ "vitest": "^4.1.0"
101
+ }
102
+ }