@chanl/widget-sdk 0.2.0-canary.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 (128) hide show
  1. package/README.md +257 -0
  2. package/dist/auth.d.ts +26 -0
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +36 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/chat/chat-client.d.ts +81 -0
  7. package/dist/chat/chat-client.d.ts.map +1 -0
  8. package/dist/chat/chat-client.js +192 -0
  9. package/dist/chat/chat-client.js.map +1 -0
  10. package/dist/chat/stream-parser.d.ts +20 -0
  11. package/dist/chat/stream-parser.d.ts.map +1 -0
  12. package/dist/chat/stream-parser.js +134 -0
  13. package/dist/chat/stream-parser.js.map +1 -0
  14. package/dist/chat/widget-config.d.ts +7 -0
  15. package/dist/chat/widget-config.d.ts.map +1 -0
  16. package/dist/chat/widget-config.js +26 -0
  17. package/dist/chat/widget-config.js.map +1 -0
  18. package/dist/client.d.ts +66 -0
  19. package/dist/client.d.ts.map +1 -0
  20. package/dist/client.js +49 -0
  21. package/dist/client.js.map +1 -0
  22. package/dist/defaults.d.ts +12 -0
  23. package/dist/defaults.d.ts.map +1 -0
  24. package/dist/defaults.js +27 -0
  25. package/dist/defaults.js.map +1 -0
  26. package/dist/embed/loader-types.d.ts +119 -0
  27. package/dist/embed/loader-types.d.ts.map +1 -0
  28. package/dist/embed/loader-types.js +20 -0
  29. package/dist/embed/loader-types.js.map +1 -0
  30. package/dist/embed/loader.d.ts +101 -0
  31. package/dist/embed/loader.d.ts.map +1 -0
  32. package/dist/embed/loader.js +439 -0
  33. package/dist/embed/loader.js.map +1 -0
  34. package/dist/embed/v1.global.js +5 -0
  35. package/dist/embed/v1.global.js.map +1 -0
  36. package/dist/events.d.ts +10 -0
  37. package/dist/events.d.ts.map +1 -0
  38. package/dist/events.js +25 -0
  39. package/dist/events.js.map +1 -0
  40. package/dist/index.d.ts +19 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +29 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/logger.d.ts +14 -0
  45. package/dist/logger.d.ts.map +1 -0
  46. package/dist/logger.js +3 -0
  47. package/dist/logger.js.map +1 -0
  48. package/dist/next/index.d.ts +58 -0
  49. package/dist/next/index.d.ts.map +1 -0
  50. package/dist/next/index.js +83 -0
  51. package/dist/next/index.js.map +1 -0
  52. package/dist/react/index.d.ts +16 -0
  53. package/dist/react/index.d.ts.map +1 -0
  54. package/dist/react/index.js +20 -0
  55. package/dist/react/index.js.map +1 -0
  56. package/dist/react/types.d.ts +27 -0
  57. package/dist/react/types.d.ts.map +1 -0
  58. package/dist/react/types.js +8 -0
  59. package/dist/react/types.js.map +1 -0
  60. package/dist/react/use-chanl.d.ts +27 -0
  61. package/dist/react/use-chanl.d.ts.map +1 -0
  62. package/dist/react/use-chanl.js +57 -0
  63. package/dist/react/use-chanl.js.map +1 -0
  64. package/dist/react/use-chat.d.ts +32 -0
  65. package/dist/react/use-chat.d.ts.map +1 -0
  66. package/dist/react/use-chat.js +224 -0
  67. package/dist/react/use-chat.js.map +1 -0
  68. package/dist/react/use-voice.d.ts +37 -0
  69. package/dist/react/use-voice.d.ts.map +1 -0
  70. package/dist/react/use-voice.js +268 -0
  71. package/dist/react/use-voice.js.map +1 -0
  72. package/dist/react/widget.d.ts +43 -0
  73. package/dist/react/widget.d.ts.map +1 -0
  74. package/dist/react/widget.js +188 -0
  75. package/dist/react/widget.js.map +1 -0
  76. package/dist/storage/session-storage.d.ts +48 -0
  77. package/dist/storage/session-storage.d.ts.map +1 -0
  78. package/dist/storage/session-storage.js +84 -0
  79. package/dist/storage/session-storage.js.map +1 -0
  80. package/dist/types.d.ts +140 -0
  81. package/dist/types.d.ts.map +1 -0
  82. package/dist/types.js +7 -0
  83. package/dist/types.js.map +1 -0
  84. package/dist/voice/audio-recorder.d.ts +43 -0
  85. package/dist/voice/audio-recorder.d.ts.map +1 -0
  86. package/dist/voice/audio-recorder.js +127 -0
  87. package/dist/voice/audio-recorder.js.map +1 -0
  88. package/dist/voice/index.d.ts +13 -0
  89. package/dist/voice/index.d.ts.map +1 -0
  90. package/dist/voice/index.js +16 -0
  91. package/dist/voice/index.js.map +1 -0
  92. package/dist/voice/mock-mode.d.ts +93 -0
  93. package/dist/voice/mock-mode.d.ts.map +1 -0
  94. package/dist/voice/mock-mode.js +375 -0
  95. package/dist/voice/mock-mode.js.map +1 -0
  96. package/dist/voice/transports/index.d.ts +5 -0
  97. package/dist/voice/transports/index.d.ts.map +1 -0
  98. package/dist/voice/transports/index.js +10 -0
  99. package/dist/voice/transports/index.js.map +1 -0
  100. package/dist/voice/transports/transport.d.ts +70 -0
  101. package/dist/voice/transports/transport.d.ts.map +1 -0
  102. package/dist/voice/transports/transport.js +12 -0
  103. package/dist/voice/transports/transport.js.map +1 -0
  104. package/dist/voice/transports/vapi.d.ts +147 -0
  105. package/dist/voice/transports/vapi.d.ts.map +1 -0
  106. package/dist/voice/transports/vapi.js +337 -0
  107. package/dist/voice/transports/vapi.js.map +1 -0
  108. package/dist/voice/transports/webrtc.d.ts +58 -0
  109. package/dist/voice/transports/webrtc.d.ts.map +1 -0
  110. package/dist/voice/transports/webrtc.js +318 -0
  111. package/dist/voice/transports/webrtc.js.map +1 -0
  112. package/dist/voice/transports/websocket.d.ts +39 -0
  113. package/dist/voice/transports/websocket.d.ts.map +1 -0
  114. package/dist/voice/transports/websocket.js +280 -0
  115. package/dist/voice/transports/websocket.js.map +1 -0
  116. package/dist/voice/types.d.ts +323 -0
  117. package/dist/voice/types.d.ts.map +1 -0
  118. package/dist/voice/types.js +41 -0
  119. package/dist/voice/types.js.map +1 -0
  120. package/dist/voice/utils.d.ts +22 -0
  121. package/dist/voice/utils.d.ts.map +1 -0
  122. package/dist/voice/utils.js +44 -0
  123. package/dist/voice/utils.js.map +1 -0
  124. package/dist/voice/voice-client.d.ts +231 -0
  125. package/dist/voice/voice-client.d.ts.map +1 -0
  126. package/dist/voice/voice-client.js +1187 -0
  127. package/dist/voice/voice-client.js.map +1 -0
  128. package/package.json +91 -0
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @chanl/widget-sdk — Embeddable chat + voice widget SDK for Chanl AI agents.
3
+ *
4
+ * This is the public-facing SDK that powers chanl-site's embed widget and
5
+ * any third-party integration that wants chat or voice with a Chanl agent.
6
+ *
7
+ * Story 1 exports text chat only. Voice (Story 2) and unified client (Story 3)
8
+ * land in subsequent commits.
9
+ */
10
+ export { createChanlClient } from './client';
11
+ export type { ChanlClient, ChanlClientConfig } from './client';
12
+ export { createChatClient } from './chat/chat-client';
13
+ export { getWidgetConfig } from './chat/widget-config';
14
+ export { parseStream } from './chat/stream-parser';
15
+ export type { VoiceClient } from './voice/voice-client';
16
+ export { resolveBaseUrl } from './defaults';
17
+ export { buildAuthHeaders, isPublicKey } from './auth';
18
+ export type { ChatClientConfig, ChatSession, ChatMessageResponse, CreateSessionInput, MessagePart, ToolInvocation, WidgetConfig, ChanlUser, } from './types';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAKnD,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGxD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAGvD,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,SAAS,GACV,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /**
3
+ * @chanl/widget-sdk — Embeddable chat + voice widget SDK for Chanl AI agents.
4
+ *
5
+ * This is the public-facing SDK that powers chanl-site's embed widget and
6
+ * any third-party integration that wants chat or voice with a Chanl agent.
7
+ *
8
+ * Story 1 exports text chat only. Voice (Story 2) and unified client (Story 3)
9
+ * land in subsequent commits.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.isPublicKey = exports.buildAuthHeaders = exports.resolveBaseUrl = exports.parseStream = exports.getWidgetConfig = exports.createChatClient = exports.createChanlClient = void 0;
13
+ // ── Unified client (recommended) ──
14
+ var client_1 = require("./client");
15
+ Object.defineProperty(exports, "createChanlClient", { enumerable: true, get: function () { return client_1.createChanlClient; } });
16
+ // ── Chat (text) ──
17
+ var chat_client_1 = require("./chat/chat-client");
18
+ Object.defineProperty(exports, "createChatClient", { enumerable: true, get: function () { return chat_client_1.createChatClient; } });
19
+ var widget_config_1 = require("./chat/widget-config");
20
+ Object.defineProperty(exports, "getWidgetConfig", { enumerable: true, get: function () { return widget_config_1.getWidgetConfig; } });
21
+ var stream_parser_1 = require("./chat/stream-parser");
22
+ Object.defineProperty(exports, "parseStream", { enumerable: true, get: function () { return stream_parser_1.parseStream; } });
23
+ // ── Shared ──
24
+ var defaults_1 = require("./defaults");
25
+ Object.defineProperty(exports, "resolveBaseUrl", { enumerable: true, get: function () { return defaults_1.resolveBaseUrl; } });
26
+ var auth_1 = require("./auth");
27
+ Object.defineProperty(exports, "buildAuthHeaders", { enumerable: true, get: function () { return auth_1.buildAuthHeaders; } });
28
+ Object.defineProperty(exports, "isPublicKey", { enumerable: true, get: function () { return auth_1.isPublicKey; } });
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH,qCAAqC;AACrC,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAG1B,oBAAoB;AACpB,kDAAsD;AAA7C,+GAAA,gBAAgB,OAAA;AACzB,sDAAuD;AAA9C,gHAAA,eAAe,OAAA;AACxB,sDAAmD;AAA1C,4GAAA,WAAW,OAAA;AAOpB,eAAe;AACf,uCAA4C;AAAnC,0GAAA,cAAc,OAAA;AACvB,+BAAuD;AAA9C,wGAAA,gBAAgB,OAAA;AAAE,mGAAA,WAAW,OAAA"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Logger.ts - Minimal injectable logging contract
3
+ *
4
+ * Defines the minimum interface required for logging functionality.
5
+ * The default implementation is the browser's console object.
6
+ */
7
+ export interface Logger {
8
+ log(...args: unknown[]): void;
9
+ info(...args: unknown[]): void;
10
+ debug(...args: unknown[]): void;
11
+ warn(...args: unknown[]): void;
12
+ error(...args: unknown[]): void;
13
+ }
14
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,MAAM;IACrB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChC,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CACjC"}
package/dist/logger.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":""}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Compute the HMAC-SHA256 hex digest of a user's `externalId` using the
3
+ * workspace identity secret. Call this on the **server** only — your
4
+ * `CHANL_IDENTITY_SECRET` must never reach the browser.
5
+ *
6
+ * The widget identity flow mirrors Intercom's `user_hash` pattern:
7
+ *
8
+ * 1. Host app picks a stable `externalId` (Firebase uid, Clerk user id,
9
+ * Auth0 sub, database id — whatever its auth system already uses).
10
+ * 2. Host app's server calls `computeUserHash(externalId, secret)` where
11
+ * `secret` matches the `identitySecret` set on the Chanl workspace.
12
+ * 3. Host app renders `<ChanlWidget user={...} userHash={userHash} />` in
13
+ * a client component; only the hash crosses the server/client boundary,
14
+ * never the raw secret.
15
+ * 4. Chanl verifies the hash on every chat session creation. Pass → Chanl
16
+ * upserts a Customer by externalId + exposes custom attributes as
17
+ * `{{customer:<key>}}` prompt variables. Fail → 403.
18
+ *
19
+ * @param externalId - The stable user identifier from the host app.
20
+ * @param secret - The workspace identity secret, from server env only.
21
+ * @returns HMAC-SHA256 hex digest, ready to pass as `userHash`.
22
+ *
23
+ * @throws if `externalId` or `secret` is empty/not a string.
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * // app/dashboard/page.tsx (React Server Component)
28
+ * import { computeUserHash } from '@chanl/widget-sdk/next';
29
+ * import { ChanlWidget } from '@chanl/widget-sdk/react';
30
+ *
31
+ * export default async function Page() {
32
+ * const user = await getCurrentUser(); // Firebase / Clerk / NextAuth / anything
33
+ * const userHash = computeUserHash(
34
+ * user.id,
35
+ * process.env.CHANL_IDENTITY_SECRET!,
36
+ * );
37
+ *
38
+ * return (
39
+ * <>
40
+ * <main>...</main>
41
+ * <ChanlWidget
42
+ * pubKey={process.env.NEXT_PUBLIC_CHANL_PUB_KEY!}
43
+ * agentId="agent_xxx"
44
+ * user={{
45
+ * externalId: user.id,
46
+ * email: user.email,
47
+ * name: user.name,
48
+ * attributes: { plan: user.plan, role: user.role },
49
+ * }}
50
+ * userHash={userHash}
51
+ * />
52
+ * </>
53
+ * );
54
+ * }
55
+ * ```
56
+ */
57
+ export declare function computeUserHash(externalId: string, secret: string): string;
58
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAc1E"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeUserHash = computeUserHash;
4
+ /**
5
+ * @chanl/widget-sdk/next — Next.js-specific helpers.
6
+ *
7
+ * For use in React Server Components, route handlers, and server actions.
8
+ * Computes the HMAC-SHA256 identity hash on the server so the host app's
9
+ * workspace identity secret never reaches the browser.
10
+ *
11
+ * This subpath uses `node:crypto` and is Node-only — do not import from
12
+ * a client component. The rest of the widget SDK (components, hooks,
13
+ * loader) lives in the main entry and `./react` subpath.
14
+ */
15
+ const node_crypto_1 = require("node:crypto");
16
+ /**
17
+ * Compute the HMAC-SHA256 hex digest of a user's `externalId` using the
18
+ * workspace identity secret. Call this on the **server** only — your
19
+ * `CHANL_IDENTITY_SECRET` must never reach the browser.
20
+ *
21
+ * The widget identity flow mirrors Intercom's `user_hash` pattern:
22
+ *
23
+ * 1. Host app picks a stable `externalId` (Firebase uid, Clerk user id,
24
+ * Auth0 sub, database id — whatever its auth system already uses).
25
+ * 2. Host app's server calls `computeUserHash(externalId, secret)` where
26
+ * `secret` matches the `identitySecret` set on the Chanl workspace.
27
+ * 3. Host app renders `<ChanlWidget user={...} userHash={userHash} />` in
28
+ * a client component; only the hash crosses the server/client boundary,
29
+ * never the raw secret.
30
+ * 4. Chanl verifies the hash on every chat session creation. Pass → Chanl
31
+ * upserts a Customer by externalId + exposes custom attributes as
32
+ * `{{customer:<key>}}` prompt variables. Fail → 403.
33
+ *
34
+ * @param externalId - The stable user identifier from the host app.
35
+ * @param secret - The workspace identity secret, from server env only.
36
+ * @returns HMAC-SHA256 hex digest, ready to pass as `userHash`.
37
+ *
38
+ * @throws if `externalId` or `secret` is empty/not a string.
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * // app/dashboard/page.tsx (React Server Component)
43
+ * import { computeUserHash } from '@chanl/widget-sdk/next';
44
+ * import { ChanlWidget } from '@chanl/widget-sdk/react';
45
+ *
46
+ * export default async function Page() {
47
+ * const user = await getCurrentUser(); // Firebase / Clerk / NextAuth / anything
48
+ * const userHash = computeUserHash(
49
+ * user.id,
50
+ * process.env.CHANL_IDENTITY_SECRET!,
51
+ * );
52
+ *
53
+ * return (
54
+ * <>
55
+ * <main>...</main>
56
+ * <ChanlWidget
57
+ * pubKey={process.env.NEXT_PUBLIC_CHANL_PUB_KEY!}
58
+ * agentId="agent_xxx"
59
+ * user={{
60
+ * externalId: user.id,
61
+ * email: user.email,
62
+ * name: user.name,
63
+ * attributes: { plan: user.plan, role: user.role },
64
+ * }}
65
+ * userHash={userHash}
66
+ * />
67
+ * </>
68
+ * );
69
+ * }
70
+ * ```
71
+ */
72
+ function computeUserHash(externalId, secret) {
73
+ if (!externalId || typeof externalId !== 'string') {
74
+ throw new Error('computeUserHash: externalId must be a non-empty string');
75
+ }
76
+ if (!secret || typeof secret !== 'string') {
77
+ throw new Error('computeUserHash: CHANL_IDENTITY_SECRET is missing or empty. ' +
78
+ 'Set it as a server-side environment variable (e.g. `CHANL_IDENTITY_SECRET` ' +
79
+ 'in your Vercel project or `.env.local`) and never expose it to the client.');
80
+ }
81
+ return (0, node_crypto_1.createHmac)('sha256', secret).update(externalId).digest('hex');
82
+ }
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":";;AAqEA,0CAcC;AAnFD;;;;;;;;;;GAUG;AACH,6CAAyC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,SAAgB,eAAe,CAAC,UAAkB,EAAE,MAAc;IAChE,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CACb,wDAAwD,CACzD,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,8DAA8D;YAC5D,6EAA6E;YAC7E,4EAA4E,CAC/E,CAAC;IACJ,CAAC;IACD,OAAO,IAAA,wBAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @chanl/widget-sdk/react — React hooks + component for the chat widget.
3
+ *
4
+ * Subpath import:
5
+ * import { ChanlWidget, useChat, useVoice, useChanl } from '@chanl/widget-sdk/react';
6
+ */
7
+ export { ChanlWidget } from './widget';
8
+ export type { ChanlWidgetProps } from './widget';
9
+ export { useChat } from './use-chat';
10
+ export { useVoice } from './use-voice';
11
+ export type { UseVoiceOptions, UseVoiceReturn, VoiceMessage, VoiceMode, VoiceStatus, } from './use-voice';
12
+ export { useChanl } from './use-chanl';
13
+ export type { UseChanlOptions, UseChanlReturn } from './use-chanl';
14
+ export type { UIChatMessage, AgentConfig, ChatTheme } from './types';
15
+ export type { ChanlUser } from '../types';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EACV,eAAe,EACf,cAAc,EACd,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGnE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAErE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ /**
3
+ * @chanl/widget-sdk/react — React hooks + component for the chat widget.
4
+ *
5
+ * Subpath import:
6
+ * import { ChanlWidget, useChat, useVoice, useChanl } from '@chanl/widget-sdk/react';
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.useChanl = exports.useVoice = exports.useChat = exports.ChanlWidget = void 0;
10
+ // ── v1: drop-in widget component ──
11
+ var widget_1 = require("./widget");
12
+ Object.defineProperty(exports, "ChanlWidget", { enumerable: true, get: function () { return widget_1.ChanlWidget; } });
13
+ // ── Hooks (headless) ──
14
+ var use_chat_1 = require("./use-chat");
15
+ Object.defineProperty(exports, "useChat", { enumerable: true, get: function () { return use_chat_1.useChat; } });
16
+ var use_voice_1 = require("./use-voice");
17
+ Object.defineProperty(exports, "useVoice", { enumerable: true, get: function () { return use_voice_1.useVoice; } });
18
+ var use_chanl_1 = require("./use-chanl");
19
+ Object.defineProperty(exports, "useChanl", { enumerable: true, get: function () { return use_chanl_1.useChanl; } });
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,qCAAqC;AACrC,mCAAuC;AAA9B,qGAAA,WAAW,OAAA;AAGpB,yBAAyB;AACzB,uCAAqC;AAA5B,mGAAA,OAAO,OAAA;AAChB,yCAAuC;AAA9B,qGAAA,QAAQ,OAAA;AAQjB,yCAAuC;AAA9B,qGAAA,QAAQ,OAAA"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * UI-facing types for React hooks. Distinct from the SDK transport types
3
+ * (which are in src/types.ts) — these include UI metadata like display
4
+ * labels and durations for status pills.
5
+ */
6
+ export type ChatTheme = 'dark' | 'light';
7
+ export interface UIChatMessage {
8
+ id: string;
9
+ role: 'user' | 'assistant' | 'tool' | 'thinking' | 'status';
10
+ content: string;
11
+ timestamp: number;
12
+ /** User-friendly label for tool/status messages (e.g. "Searching listings...") */
13
+ label?: string;
14
+ /** Duration in seconds for thought/tool badges */
15
+ duration?: number;
16
+ }
17
+ export interface AgentConfig {
18
+ id: string;
19
+ name: string;
20
+ subtitle?: string;
21
+ avatarUrl?: string;
22
+ initials: string;
23
+ greeting: string;
24
+ suggestions: string[];
25
+ primaryColor?: string;
26
+ }
27
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/react/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * UI-facing types for React hooks. Distinct from the SDK transport types
4
+ * (which are in src/types.ts) — these include UI metadata like display
5
+ * labels and durations for status pills.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/react/types.ts"],"names":[],"mappings":";AAAA;;;;GAIG"}
@@ -0,0 +1,27 @@
1
+ import type { UIChatMessage, AgentConfig } from './types';
2
+ import type { VoiceMessage, VoiceStatus } from './use-voice';
3
+ export interface UseChanlOptions {
4
+ agentId: string;
5
+ apiKey: string;
6
+ baseUrl?: string;
7
+ greeting?: string;
8
+ debug?: boolean;
9
+ }
10
+ export interface UseChanlReturn {
11
+ messages: UIChatMessage[];
12
+ isTyping: boolean;
13
+ send: (text: string) => void;
14
+ sessionReady: boolean;
15
+ agentConfig: AgentConfig | null;
16
+ voiceState: VoiceStatus;
17
+ startVoice: (agentId?: string) => void;
18
+ stopVoice: () => void;
19
+ toggleMute: () => void;
20
+ isMuted: boolean;
21
+ isAgentSpeaking: boolean;
22
+ duration: number;
23
+ voiceMessages: VoiceMessage[];
24
+ error: string | null;
25
+ }
26
+ export declare function useChanl(opts: UseChanlOptions): UseChanlReturn;
27
+ //# sourceMappingURL=use-chanl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-chanl.d.ts","sourceRoot":"","sources":["../../src/react/use-chanl.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAE7B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAGhC,UAAU,EAAE,WAAW,CAAC;IACxB,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,YAAY,EAAE,CAAC;IAG9B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,cAAc,CAmC9D"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.useChanl = useChanl;
5
+ /**
6
+ * useChanl — unified text + voice React hook.
7
+ *
8
+ * Thin wrapper over useChat + useVoice so consumers can drive both modalities
9
+ * from a single hook. For voice-only or text-only use cases, import the
10
+ * dedicated hook directly (smaller bundle, clearer types).
11
+ *
12
+ * Usage:
13
+ * const {
14
+ * // text
15
+ * messages, isTyping, send, sessionReady, agentConfig,
16
+ * // voice
17
+ * voiceState, startVoice, stopVoice, toggleMute, isMuted,
18
+ * isAgentSpeaking, duration, voiceMessages,
19
+ * // shared
20
+ * error,
21
+ * } = useChanl({ agentId, apiKey });
22
+ */
23
+ const use_chat_1 = require("./use-chat");
24
+ const use_voice_1 = require("./use-voice");
25
+ function useChanl(opts) {
26
+ const chat = (0, use_chat_1.useChat)({
27
+ agentId: opts.agentId,
28
+ apiKey: opts.apiKey,
29
+ baseUrl: opts.baseUrl,
30
+ greeting: opts.greeting,
31
+ });
32
+ const voice = (0, use_voice_1.useVoice)({
33
+ apiKey: opts.apiKey,
34
+ baseUrl: opts.baseUrl,
35
+ debug: opts.debug,
36
+ });
37
+ return {
38
+ // text
39
+ messages: chat.messages,
40
+ isTyping: chat.isTyping,
41
+ send: chat.send,
42
+ sessionReady: chat.sessionReady,
43
+ agentConfig: chat.agentConfig,
44
+ // voice — default to the hook's configured agentId unless caller overrides
45
+ voiceState: voice.status,
46
+ startVoice: (agentId) => voice.start(agentId ?? opts.agentId),
47
+ stopVoice: voice.stop,
48
+ toggleMute: voice.toggleMute,
49
+ isMuted: voice.isMuted,
50
+ isAgentSpeaking: voice.isAgentSpeaking,
51
+ duration: voice.duration,
52
+ voiceMessages: voice.messages,
53
+ // shared — prefer chat error, fall back to voice error message
54
+ error: chat.error ?? voice.lastError?.message ?? null,
55
+ };
56
+ }
57
+ //# sourceMappingURL=use-chanl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-chanl.js","sourceRoot":"","sources":["../../src/react/use-chanl.ts"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAwDb,4BAmCC;AAzFD;;;;;;;;;;;;;;;;;GAiBG;AAEH,yCAAqC;AACrC,2CAAuC;AAkCvC,SAAgB,QAAQ,CAAC,IAAqB;IAC5C,MAAM,IAAI,GAAG,IAAA,kBAAO,EAAC;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,IAAA,oBAAQ,EAAC;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC;IAEH,OAAO;QACL,OAAO;QACP,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,WAAW,EAAE,IAAI,CAAC,WAAW;QAE7B,2EAA2E;QAC3E,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,UAAU,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;QACtE,SAAS,EAAE,KAAK,CAAC,IAAI;QACrB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,aAAa,EAAE,KAAK,CAAC,QAAQ;QAE7B,+DAA+D;QAC/D,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,EAAE,OAAO,IAAI,IAAI;KACtD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { ChanlUser } from '../types';
2
+ import type { AgentConfig, UIChatMessage as ChatMessage } from './types';
3
+ interface UseChat {
4
+ messages: ChatMessage[];
5
+ isTyping: boolean;
6
+ error: string | null;
7
+ send: (text: string) => void;
8
+ sessionReady: boolean;
9
+ agentConfig: AgentConfig | null;
10
+ }
11
+ interface UseChatOptions {
12
+ agentId: string;
13
+ apiKey: string;
14
+ baseUrl?: string;
15
+ greeting?: string;
16
+ /**
17
+ * Identified end-user — Intercom-style widget identity path.
18
+ * When present, the backend verifies `userHash` + upserts a Customer by
19
+ * externalId + exposes attributes as `{{customer:<key>}}` prompt variables.
20
+ * Changing `user.externalId` recreates the session.
21
+ */
22
+ user?: ChanlUser;
23
+ /** HMAC-SHA256 of `user.externalId` using workspace identity secret. */
24
+ userHash?: string;
25
+ /** Optional extra variables merged into prompt substitution. */
26
+ variables?: Record<string, string>;
27
+ /** Optional metadata (pageUrl, source, etc.). */
28
+ metadata?: Record<string, unknown>;
29
+ }
30
+ export declare function useChat({ agentId, apiKey, baseUrl, greeting, user, userHash, variables, metadata, }: UseChatOptions): UseChat;
31
+ export {};
32
+ //# sourceMappingURL=use-chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-chat.d.ts","sourceRoot":"","sources":["../../src/react/use-chat.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,IAAI,WAAW,EAAE,MAAM,SAAS,CAAC;AAIzE,UAAU,OAAO;IACf,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;CACjC;AAED,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAwBD,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,MAAM,EACN,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE,cAAc,GAAG,OAAO,CAwN1B"}