codicent-app-sdk 0.4.14 → 0.4.17

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 (97) hide show
  1. package/README.md +556 -521
  2. package/dist/cjs/components/AiInput.js +1 -1
  3. package/dist/cjs/components/AudioIcon.js +1 -1
  4. package/dist/cjs/components/ChatInput.js +1 -1
  5. package/dist/cjs/components/ChatMessage.js +1 -1
  6. package/dist/cjs/components/CombinedPlaceholderDialog.js +1 -1
  7. package/dist/cjs/components/DataMessagePicker.d.ts +33 -0
  8. package/dist/cjs/components/DataMessagePicker.d.ts.map +1 -0
  9. package/dist/cjs/components/DataMessagePicker.js +1 -0
  10. package/dist/cjs/components/Footer.js +1 -1
  11. package/dist/cjs/components/Header.js +1 -1
  12. package/dist/cjs/components/HtmlView.js +1 -1
  13. package/dist/cjs/components/MermaidChart.d.ts.map +1 -1
  14. package/dist/cjs/components/MermaidChart.js +1 -1
  15. package/dist/cjs/components/MessageInput.js +1 -1
  16. package/dist/cjs/components/MessageItem.js +1 -1
  17. package/dist/cjs/components/Profile.js +1 -1
  18. package/dist/cjs/components/Prompt.js +1 -1
  19. package/dist/cjs/components/SnapFooter.js +1 -1
  20. package/dist/cjs/components/TextHeader.js +1 -1
  21. package/dist/cjs/components/TypingIndicator.js +1 -1
  22. package/dist/cjs/components/UploadFile.js +1 -1
  23. package/dist/cjs/components/UrlProcessor.js +1 -1
  24. package/dist/cjs/components/VoiceIcon.js +1 -1
  25. package/dist/cjs/components/index.d.ts +2 -0
  26. package/dist/cjs/components/index.d.ts.map +1 -1
  27. package/dist/cjs/config/index.d.ts.map +1 -1
  28. package/dist/cjs/config/index.js +1 -1
  29. package/dist/cjs/hooks/useAuthState.js +1 -1
  30. package/dist/cjs/hooks/useCodicentState.js +1 -1
  31. package/dist/cjs/hooks/useLocalization.d.ts.map +1 -1
  32. package/dist/cjs/hooks/useLocalization.js +1 -1
  33. package/dist/cjs/hooks/useTools.d.ts.map +1 -1
  34. package/dist/cjs/hooks/useTools.js +1 -1
  35. package/dist/cjs/index.js +1 -1
  36. package/dist/cjs/pages/AppFrame.js +1 -1
  37. package/dist/cjs/pages/Chat.js +1 -1
  38. package/dist/cjs/pages/Compose.js +1 -1
  39. package/dist/cjs/pages/CrmPage.js +1 -1
  40. package/dist/cjs/pages/CrmPagePersistent.js +1 -1
  41. package/dist/cjs/pages/FormAccept.js +1 -1
  42. package/dist/cjs/pages/FormInvite.js +1 -1
  43. package/dist/cjs/pages/HtmlViewer.js +1 -1
  44. package/dist/cjs/pages/Login.js +1 -1
  45. package/dist/cjs/pages/Purchase.js +1 -1
  46. package/dist/cjs/pages/Sales.js +1 -1
  47. package/dist/cjs/pages/Search.js +1 -1
  48. package/dist/cjs/pages/Snap.js +1 -1
  49. package/dist/esm/components/AiInput.js +1 -1
  50. package/dist/esm/components/AudioIcon.js +1 -1
  51. package/dist/esm/components/ChatInput.js +1 -1
  52. package/dist/esm/components/ChatMessage.js +1 -1
  53. package/dist/esm/components/CombinedPlaceholderDialog.js +1 -1
  54. package/dist/esm/components/DataMessagePicker.d.ts +33 -0
  55. package/dist/esm/components/DataMessagePicker.d.ts.map +1 -0
  56. package/dist/esm/components/DataMessagePicker.js +1 -0
  57. package/dist/esm/components/Footer.js +1 -1
  58. package/dist/esm/components/Header.js +1 -1
  59. package/dist/esm/components/HtmlView.js +1 -1
  60. package/dist/esm/components/MermaidChart.d.ts.map +1 -1
  61. package/dist/esm/components/MermaidChart.js +1 -1
  62. package/dist/esm/components/MessageInput.js +1 -1
  63. package/dist/esm/components/MessageItem.js +1 -1
  64. package/dist/esm/components/Profile.js +1 -1
  65. package/dist/esm/components/Prompt.js +1 -1
  66. package/dist/esm/components/SnapFooter.js +1 -1
  67. package/dist/esm/components/TextHeader.js +1 -1
  68. package/dist/esm/components/TypingIndicator.js +1 -1
  69. package/dist/esm/components/UploadFile.js +1 -1
  70. package/dist/esm/components/UrlProcessor.js +1 -1
  71. package/dist/esm/components/VoiceIcon.js +1 -1
  72. package/dist/esm/components/index.d.ts +2 -0
  73. package/dist/esm/components/index.d.ts.map +1 -1
  74. package/dist/esm/config/index.d.ts.map +1 -1
  75. package/dist/esm/config/index.js +1 -1
  76. package/dist/esm/hooks/useAuthState.js +1 -1
  77. package/dist/esm/hooks/useCodicentState.js +1 -1
  78. package/dist/esm/hooks/useLocalization.d.ts.map +1 -1
  79. package/dist/esm/hooks/useLocalization.js +1 -1
  80. package/dist/esm/hooks/useTools.d.ts.map +1 -1
  81. package/dist/esm/hooks/useTools.js +1 -1
  82. package/dist/esm/index.js +1 -1
  83. package/dist/esm/pages/AppFrame.js +1 -1
  84. package/dist/esm/pages/Chat.js +1 -1
  85. package/dist/esm/pages/Compose.js +1 -1
  86. package/dist/esm/pages/CrmPage.js +1 -1
  87. package/dist/esm/pages/CrmPagePersistent.js +1 -1
  88. package/dist/esm/pages/FormAccept.js +1 -1
  89. package/dist/esm/pages/FormInvite.js +1 -1
  90. package/dist/esm/pages/HtmlViewer.js +1 -1
  91. package/dist/esm/pages/Login.js +1 -1
  92. package/dist/esm/pages/Purchase.js +1 -1
  93. package/dist/esm/pages/Sales.js +1 -1
  94. package/dist/esm/pages/Search.js +1 -1
  95. package/dist/esm/pages/Snap.js +1 -1
  96. package/dist/index.d.ts +263 -233
  97. package/package.json +1 -1
package/README.md CHANGED
@@ -1,521 +1,556 @@
1
- # Codicent App SDK
2
-
3
- ![Build Status](https://img.shields.io/github/actions/workflow/status/izaxon/codicent-app-sdk/main.yml?branch=main)
4
- ![License](https://img.shields.io/github/license/izaxon/codicent-app-sdk)
5
- ![Version](https://img.shields.io/badge/version-0.4.0-blue)
6
-
7
- **A comprehensive SDK for building AI-powered, chat-centric web applications with Codicent.**
8
-
9
- Codicent App SDK provides React components, hooks, and utilities to help you quickly build, customize, and deploy modern AI-powered apps. It is designed for rapid prototyping and production use, with built-in support for chat, markdown rendering, file uploads, and more.
10
-
11
- ---
12
-
13
- ## 🚀 Quick Start (v2 - Simplified Bootstrap)
14
-
15
- **New in v0.4.0:** Create a complete Codicent app with a single function call!
16
-
17
- ```tsx
18
- import { createCodicentApp } from 'codicent-app-sdk';
19
-
20
- const app = createCodicentApp({
21
- name: "My CRM",
22
- apiBaseUrl: "https://codicent.com/",
23
- buttons: [
24
- { title: "Customers", url: "./#/list?tag=customer2" },
25
- { title: "Quotes", url: "./#/list?tag=offertjson" },
26
- { title: "Chat", url: "./#/chat" },
27
- ],
28
- listDefinitions: {
29
- customer2: [
30
- { key: "name", title: "Name", filterable: true },
31
- { key: "email", title: "Email" },
32
- { key: "phone", title: "Phone" },
33
- ],
34
- },
35
- translations: {
36
- en: { "Kunder": "Customers", "Offerter": "Quotes" },
37
- sv: { "Customers": "Kunder", "Quotes": "Offerter" },
38
- },
39
- modules: {
40
- sales: true,
41
- voice: true,
42
- search: true,
43
- },
44
- chatInstructions: "You are a helpful CRM assistant.",
45
- });
46
-
47
- // Render to DOM
48
- app.render("#root");
49
- ```
50
-
51
- That's it! You now have a fully configured Codicent vertical app with:
52
- - ✅ Auth0 authentication
53
- - ✅ Navigation buttons
54
- - List views with filtering and sorting
55
- - i18n support
56
- - AI chat integration
57
- - ✅ Module-based feature flags
58
-
59
- ---
60
-
61
- ## Installation
62
-
63
- ### From GitHub (Recommended)
64
- ```bash
65
- npm install github:izaxon/codicent-app-sdk
66
- # or
67
- yarn add github:izaxon/codicent-app-sdk
68
- ```
69
-
70
- ### From npm
71
- ```bash
72
- npm install codicent-app-sdk
73
- # or
74
- yarn add codicent-app-sdk
75
- ```
76
-
77
- ---
78
-
79
- ## Usage
80
-
81
- ### Option 1: Simplified Bootstrap (v2 - Recommended)
82
-
83
- Use `createCodicentApp()` for the fastest setup. This handles all initialization, routing, and authentication automatically.
84
-
85
- ```tsx
86
- import { createCodicentApp } from 'codicent-app-sdk';
87
-
88
- const app = createCodicentApp({
89
- name: "My App",
90
- apiBaseUrl: "https://codicent.com/",
91
- // ... config
92
- });
93
-
94
- app.render("#root");
95
- ```
96
-
97
- See the [API Reference](#api-reference) below for all configuration options.
98
-
99
- ### Option 2: Manual Initialization (v1 - Still Supported)
100
-
101
- Before using the SDK, initialize it with your app’s settings:
102
-
103
- ```tsx
104
- import { initCodicentApp } from 'codicent-app-sdk';
105
-
106
- initCodicentApp({
107
- API_BASE_URL: 'https://codicent.com/',
108
- APP_NAME: 'my-app',
109
- // ...other config
110
- });
111
- ```
112
-
113
-
114
- #### Configuration Options
115
-
116
- **Required:**
117
- ```js
118
- API_BASE_URL: string // e.g. 'https://codicent.com/' or 'https://api.yourdomain.com/' (custom domains supported)
119
- APP_NAME: string // e.g. 'my-app'
120
- APP_PREFIX: string // e.g. 'myapp'
121
- USER_PREFIX: string // e.g. 'users'
122
- ```
123
-
124
- **Optional:**
125
- ```js
126
- BUTTON_BORDER_RADIUS: string
127
- BUTTON_BACKGROUND_COLOR: string
128
- DEFAULT_LANGUAGE: string
129
- SUBSCRIPTION_NEEDED: boolean
130
- REALTIME_VOICE_MODEL: string // Voice model: "alloy", "shimmer", or "echo" (default: "alloy")
131
- USE_REALTIME_SESSION_ENDPOINT: boolean // Use secure session endpoint (default: true)
132
-
133
- // Compose page location options:
134
- COMPOSE_HIDE_LOCATION: string // Set to "true" to hide the GPS toggle button entirely
135
- COMPOSE_AUTO_LOCATION: string // Set to "true" to automatically capture GPS on compose page load
136
- // ...and more
137
- ```
138
-
139
- #### Compose page GPS / location
140
-
141
- The `Compose` page (route `/new`) supports GPS location tagging. When a location is attached, a `#gps(lat,lon)` tag is appended to the message content — readable by the AI chat instructions and queryable via tag search.
142
-
143
- | Option | Value | Behaviour |
144
- |--------|-------|-----------|
145
- | `COMPOSE_HIDE_LOCATION` | `"true"` | Hides the GPS toggle button; users cannot attach location |
146
- | `COMPOSE_HIDE_LOCATION` | `"false"` (default) | Shows the GPS toggle button; users opt-in per post |
147
- | `COMPOSE_AUTO_LOCATION` | `"true"` | GPS is fetched **automatically** when the compose page opens — no button tap required. The toggle button is still shown so users can remove it if desired |
148
-
149
- Example — always capture location (e.g. a spot-logging app):
150
- ```js
151
- COMPOSE_HIDE_LOCATION: "false",
152
- COMPOSE_AUTO_LOCATION: "true",
153
- ```
154
-
155
- For AI voice configuration and security, see the [Voice Upgrade Guide](VOICE_UPGRADE_GUIDE.md).
156
-
157
- #### Using Custom Domains
158
-
159
- The SDK fully supports custom domains for self-hosted or white-label deployments. Simply configure your custom API base URL:
160
-
161
- ```tsx
162
- import { initCodicentApp } from 'codicent-app-sdk';
163
-
164
- // Using a custom domain
165
- initCodicentApp({
166
- API_BASE_URL: 'https://api.yourdomain.com/', // Your custom API endpoint
167
- APP_NAME: 'my-app',
168
- APP_PREFIX: 'myapp',
169
- USER_PREFIX: 'users',
170
- // ... other config
171
- });
172
- ```
173
-
174
- All API calls, including authentication, chat, file uploads, and data operations, will automatically route to your custom domain. Both the SDK and the underlying codicentjs library support custom base URLs.
175
-
176
- 📄 **For complete custom domain setup, see the [Custom Domain Configuration Guide](docs/CUSTOM_DOMAIN_GUIDE.md)**
177
-
178
- ---
179
-
180
- ## API Reference
181
-
182
- ### `createCodicentApp(config)`
183
-
184
- Creates a fully-configured Codicent app instance.
185
-
186
- **Parameters:**
187
-
188
- | Property | Type | Required | Description |
189
- |----------|------|----------|-------------|
190
- | `name` | `string` | | Application name |
191
- | `apiBaseUrl` | `string` | ✅ | API base URL (e.g., "https://codicent.com/") |
192
- | `appPrefix` | `string` | | App-specific URL prefix (defaults to kebab-cased name) |
193
- | `userPrefix` | `string` | | User namespace prefix (default: "users") |
194
- | `buttons` | `ButtonConfig[]` | | Navigation buttons |
195
- | `listDefinitions` | `ListDefinitions` | | List view column definitions per tag |
196
- | `translations` | `Translations` | | i18n translation maps by language |
197
- | `defaultLanguage` | `string` | | Default language code (default: "en") |
198
- | `modules` | `ModuleFlags` | | Feature module flags (sales, voice, forms, etc.) |
199
- | `chatInstructions` | `string` | | AI chat system prompt |
200
- | `voiceInstructions` | `string` | | AI voice system prompt |
201
- | `auth0` | `Auth0Config` | | Auth0 configuration |
202
- | `stripe` | `StripeConfig` | | Stripe configuration |
203
- | `theme` | `ThemeConfig` | | Theme/branding configuration |
204
-
205
- **Returns:** `CodicentApp` instance with:
206
- - `render(container)` - Render app to a DOM element
207
- - `unmount()` - Unmount the app
208
- - `getConfig()` - Get current configuration
209
-
210
- **Example:**
211
-
212
- ```tsx
213
- const app = createCodicentApp({
214
- name: "Sales CRM",
215
- apiBaseUrl: "https://codicent.com/",
216
- buttons: [
217
- { title: "Dashboard", url: "./#/" },
218
- { title: "Customers", url: "./#/list?tag=customer2" },
219
- ],
220
- listDefinitions: {
221
- customer2: [
222
- { key: "name", title: "Customer Name", filterable: true },
223
- { key: "email", title: "Email" },
224
- ],
225
- },
226
- modules: { sales: true, voice: false },
227
- });
228
-
229
- app.render("#root");
230
- ```
231
-
232
- ---
233
-
234
- ## TypeScript Types
235
-
236
- All public types are fully documented with JSDoc and exported from `codicent-app-sdk`:
237
-
238
- ```tsx
239
- import type {
240
- ButtonConfig,
241
- ColumnDefinition,
242
- ListDefinitions,
243
- ModuleFlags,
244
- Translations,
245
- UserInfo,
246
- DataMessage,
247
- CodicentAppState,
248
- // ... and more
249
- } from 'codicent-app-sdk';
250
- ```
251
-
252
- See [src/types/index.ts](src/types/index.ts) for the complete type definitions.
253
-
254
- ---
255
-
256
- ## Components
257
-
258
- ### Standalone Components
259
-
260
- The SDK exports several standalone React components that can be used independently:
261
-
262
- #### `Chat`
263
-
264
- AI chat interface component (exported from pages).
265
-
266
- ```tsx
267
- import { Chat } from 'codicent-app-sdk';
268
-
269
- <Chat />
270
- ```
271
-
272
- For detailed usage, see [src/pages/Chat.tsx](src/pages/Chat.tsx).
273
-
274
- #### `ListView`
275
-
276
- Display tabular data with sorting, filtering, and actions. While ListView is currently in the `codicentapp` package, you can import the types from the SDK:
277
-
278
- ```tsx
279
- import type { ColumnDefinition, ListViewProps } from 'codicent-app-sdk';
280
- ```
281
-
282
- See [codicentapp/src/components/ListView.tsx](../codicentapp/src/components/ListView.tsx) for the reference implementation.
283
-
284
- ---
285
-
286
- ### CRUD Operations
287
-
288
- The SDK provides comprehensive CRUD (Create, Read, Update, Delete) methods for managing structured data. For detailed documentation and examples, see:
289
-
290
- 📄 **[CRUD Method Usage Guide](../CRUD_METHOD_USAGE.md)** - Complete guide covering:
291
- - CodicentService CRUD methods
292
- - Usage patterns for project/task management and business records
293
- - JavaScript library (codicentjs) API
294
- - Best practices and complete examples
295
-
296
- ### Example: Simple Chat App
297
-
298
- ```tsx
299
- import React from 'react';
300
- import { CodicentService, useChat, Markdown, initCodicentApp } from 'codicent-app-sdk';
301
-
302
- initCodicentApp({
303
- API_BASE_URL: 'https://codicent.com/',
304
- APP_NAME: 'my-app',
305
- APP_PREFIX: 'myapp',
306
- USER_PREFIX: 'users',
307
- });
308
-
309
- const App = () => {
310
- const codicentService = new CodicentService();
311
- const { messages, sendMessage } = useChat(codicentService);
312
-
313
- return (
314
- <div>
315
- {messages.map(msg => (
316
- <div key={msg.id}>
317
- <Markdown content={msg.content} />
318
- </div>
319
- ))}
320
- <button onClick={() => sendMessage('Hello world')}>Send</button>
321
- </div>
322
- );
323
- };
324
- ```
325
-
326
- ---
327
-
328
- ## Features
329
-
330
- - **React Components:** Chat UI, Markdown, File Upload, Audio, and more
331
- - **Hooks:** Chat state, authentication, localization, theme, and more
332
- - **AI Voice:** Realtime voice AI with secure session endpoint support (see [Voice Upgrade Guide](VOICE_UPGRADE_GUIDE.md))
333
- - **State Management:** Efficient state machine with caching capabilities (see [State Management Caching Improvements](STATE_MANAGEMENT_CACHING_IMPROVEMENTS.md))
334
- - **Utilities:** Helpers for app state, device, logging, and more
335
- - **TypeScript Support:** Full typings for all exports
336
- - **Customizable:** Theming and configuration options
337
-
338
- ---
339
-
340
- ## Development
341
-
342
- ### Building and Publishing
343
-
344
- The SDK uses GitHub Actions to automate the build and publishing process:
345
-
346
- 1. On push to the main branch:
347
- - The package is automatically built
348
- - Documentation is deployed to GitHub Pages
349
-
350
- 2. When a new version tag is pushed (e.g., `v0.3.12`):
351
- - The package is built
352
- - A GitHub Release is created with the built package
353
- - The package is published to GitHub Packages
354
-
355
- ### Release Process
356
-
357
- To release a new version:
358
-
359
- ```bash
360
- # 1. Update version in package.json
361
- npm version patch|minor|major
362
-
363
- # 2. Push changes with tags
364
- git push --follow-tags
365
- ```
366
-
367
- This will trigger the GitHub Actions workflow to create a release and publish the package.
368
-
369
- ### Local Development
370
-
371
- For local development:
372
-
373
- ```bash
374
- # Install dependencies
375
- npm install
376
-
377
- # Run in development mode with watch
378
- npm run dev
379
-
380
- # Build locally
381
- npm run build
382
- ```
383
-
384
- The build process generates:
385
- - CommonJS modules in `dist/cjs`
386
- - ES modules in `dist/esm`
387
- - TypeScript definitions
388
-
389
- ### Testing Your Changes Locally
390
-
391
- You can test SDK changes in your project:
392
-
393
- ```bash
394
- # In the SDK directory
395
- npm link
396
-
397
- # In your project directory
398
- npm link codicent-app-sdk
399
- ```
400
-
401
- ### Documentation
402
-
403
- Documentation is automatically deployed to GitHub Pages as part of the workflow when changes are pushed to the main branch.
404
-
405
- For manual deployment:
406
-
407
- ```bash
408
- # To manually build and copy artifacts to docs directory
409
- npm run predeploy
410
-
411
- # To manually deploy documentation
412
- npm run deploy
413
- ```
414
-
415
- ## Publishing to npm
416
-
417
- To publish this package to npm:
418
-
419
- 1. **Login to npm** (if you haven't already):
420
- ```bash
421
- npm login
422
- ```
423
-
424
- 2. **Build the package**:
425
- ```bash
426
- npm run build
427
- ```
428
-
429
- 3. **Publish to npm**:
430
- ```bash
431
- npm publish --access public
432
- ```
433
-
434
- **Notes:**
435
- - Make sure the `"name"` field in `package.json` is set to `codicent-app-sdk` (no scope).
436
- - The package name must be unique on npm.
437
- - If you get a permissions error, ensure you are the owner of the package name on npm.
438
-
439
- ## Documentation
440
-
441
- For full documentation, visit [our docs site](https://izaxon.github.io/codicent-app-sdk/).
442
-
443
- ### Additional Documentation
444
-
445
- - **[Voice Upgrade Guide](VOICE_UPGRADE_GUIDE.md)** - Complete guide for implementing and upgrading realtime voice AI features
446
- - **[State Management Caching Improvements](STATE_MANAGEMENT_CACHING_IMPROVEMENTS.md)** - Comprehensive analysis and strategies for optimizing state management performance through intelligent caching
447
- - **[Implementation Guide](IMPLEMENTATION_GUIDE.md)** - ✅ **NEW!** How to enable and use the state management caching system (now implemented!)
448
-
449
- ## License
450
-
451
- MIT © Codicent Inside AB
452
-
453
- ---
454
-
455
- ## Fast Local SDK Testing Workflow
456
-
457
- To quickly test changes in your local SDK with your app project, you can use npm link or a local file dependency. This avoids publishing to npm for every change.
458
-
459
- ### Option 1: Using `npm link`
460
-
461
- 1. **Build your SDK in watch mode (if needed):**
462
- - If your SDK uses TypeScript or a bundler (like rollup), run it in watch mode so changes are rebuilt automatically.
463
- ```cmd
464
- npm run build -- --watch
465
- ```
466
- Or for TypeScript:
467
- ```cmd
468
- npx tsc --watch
469
- ```
470
-
471
- 2. **Link your SDK globally:**
472
- In your SDK root folder:
473
- ```cmd
474
- npm link
475
- ```
476
-
477
- 3. **Link your SDK in your app project:**
478
- In your app project folder (the one that uses the SDK):
479
- ```cmd
480
- npm link codicent-app-sdk
481
- ```
482
- (Replace `codicent-app-sdk` with the actual name in your SDK’s `package.json` if different.)
483
-
484
- 4. **Test changes instantly:**
485
- Now, when you make changes to your SDK and rebuild, your app will use the updated local version immediately—no need to publish or reinstall from npm.
486
-
487
- 5. **Unlink when done:**
488
- When you want to go back to using the npm-published version, run in your app project:
489
- ```cmd
490
- npm uninstall codicent-app-sdk
491
- npm install codicent-app-sdk
492
- ```
493
-
494
- ### Option 2: Using a Local File Dependency
495
-
496
- 1. In your app’s `package.json`, set the dependency to point to your local SDK folder:
497
- ```json
498
- "dependencies": {
499
- "codicent-app-sdk": "file:../codicent-app-sdk"
500
- }
501
- ```
502
- 2. Run `npm install` in your app project.
503
-
504
- ---
505
-
506
- ## Listening to `codicent-log` Events
507
-
508
- You can listen for SDK log events of type `codicent-log` in your application. This is useful for debugging or integrating with your own logging system.
509
-
510
- ```tsx
511
- // Listen for log events
512
- window.addEventListener('codicent-log', (event) => {
513
- // event.detail contains the log payload
514
- console.log('Codicent Log:', event.detail);
515
- });
516
- ```
517
-
518
- - The event is dispatched as a [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) on the `window` object.
519
- - The `event.detail` property contains the log data (such as level, message, and context).
520
-
521
- ---
1
+ # codicent-app-sdk
2
+
3
+ React SDK for building AI-powered, multi-tenant white-label applications on top of the Codicent platform.
4
+
5
+ **Current version:** 0.4.16 · **License:** MIT · **Peer deps:** React ≥16.8, Fluent UI v9, react-router-dom v6
6
+
7
+ ---
8
+
9
+ ## What it provides
10
+
11
+ - `CodicentService` — data CRUD, chat, file upload, token management
12
+ - React components — `Page`, `Content`, `Chat`, `ListView`, `Markdown`, `UploadFile`, and ~25 more
13
+ - Pages `AppFrame`, `Chat`, `Compose`, `Sales`, `Search`, `Snap`, `Login`, `Logout`, and more
14
+ - Hooks — `useCodicentApp`, `useLocalization`, `useChat`, `useRealtimeVoiceAI`, `useAuthState`, and more
15
+ - Global config `initCodicentApp()` initializer consumed by all SDK components
16
+ - Full TypeScript types
17
+
18
+ This SDK is the primary dependency of `codicentapp/` (the modern white-label Vite app) in the monorepo. See `codicentapp/` for a complete real-world usage reference.
19
+
20
+ ---
21
+
22
+ ## Installation
23
+
24
+ ### From npm
25
+ ```bash
26
+ npm install codicent-app-sdk
27
+ ```
28
+
29
+ ### Monorepo local dependency (recommended during development)
30
+ In your app's `package.json`:
31
+ ```json
32
+ "dependencies": {
33
+ "codicent-app-sdk": "file:../codicent-app-sdk"
34
+ }
35
+ ```
36
+ Then `npm install` in your app.
37
+
38
+ ### Peer dependencies
39
+ Install these alongside the SDK:
40
+ ```bash
41
+ npm install react react-dom react-router-dom @fluentui/react-components mermaid
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Usage
47
+
48
+ ### 1. Initialize the SDK (once, at app startup)
49
+
50
+ Call `initCodicentApp()` before rendering your React tree. It stores config globally so all SDK components and hooks can read it.
51
+
52
+ ```tsx
53
+ // main.tsx
54
+ import { initCodicentApp } from 'codicent-app-sdk';
55
+ import { translations } from './services/translationService';
56
+ import { getAppConfig } from './appconfig';
57
+
58
+ initCodicentApp({
59
+ API_BASE_URL: 'https://codicent.com/',
60
+ APP_NAME: 'my-crm',
61
+ APP_PREFIX: 'mycrm',
62
+ USER_PREFIX: 'users',
63
+ APP_CONFIG: getAppConfig(), // buttons, listDefinitions, chatInstructions
64
+ TRANSLATIONS: translations, // { sv: {...}, en: {...}, ... }
65
+ USE_REALTIME_SESSION_ENDPOINT: true,
66
+ });
67
+ ```
68
+
69
+ ### 2. Wrap with Auth0 and FluentProvider
70
+
71
+ The SDK components depend on these providers being present in the React tree:
72
+
73
+ ```tsx
74
+ // main.tsx (continued)
75
+ import { Auth0Provider } from '@auth0/auth0-react';
76
+ import { FluentProvider, webLightTheme } from '@fluentui/react-components';
77
+ import { createRoot } from 'react-dom/client';
78
+
79
+ createRoot(document.getElementById('root')!).render(
80
+ <Auth0Provider domain={AUTH0_DOMAIN} clientId={AUTH0_CLIENT_ID} authorizationParams={{ redirect_uri: window.location.origin }}>
81
+ <FluentProvider theme={webLightTheme}>
82
+ <App />
83
+ </FluentProvider>
84
+ </Auth0Provider>
85
+ );
86
+ ```
87
+
88
+ ### 3. Use `useCodicentApp()` in your root App component
89
+
90
+ ```tsx
91
+ // App.tsx
92
+ import { useCodicentApp } from 'codicent-app-sdk';
93
+ import { useAuth0 } from '@auth0/auth0-react';
94
+ import { HashRouter, Routes, Route } from 'react-router-dom';
95
+ import { Chat } from 'codicent-app-sdk';
96
+ import { ListPage } from './pages/ListPage';
97
+
98
+ export default function App() {
99
+ const auth0 = useAuth0();
100
+ const state = useCodicentApp({ auth0 });
101
+
102
+ if (!auth0.isAuthenticated) {
103
+ auth0.loginWithRedirect();
104
+ return null;
105
+ }
106
+
107
+ return (
108
+ <HashRouter>
109
+ <Routes>
110
+ <Route path="/chat" element={<Chat state={state} title="Chat" />} />
111
+ <Route path="/list" element={<ListPage state={state} />} />
112
+ </Routes>
113
+ </HashRouter>
114
+ );
115
+ }
116
+ ```
117
+
118
+ ### 4. Build pages using SDK components
119
+
120
+ ```tsx
121
+ // pages/ListPage.tsx
122
+ import { Page, Content, ListView, useLocalization, CodicentAppState, DataMessage } from 'codicent-app-sdk';
123
+ import { useEffect, useState } from 'react';
124
+ import { APP_CONFIG } from '../appconfig';
125
+ import { APP_BUTTONS } from '../constants';
126
+
127
+ export const ListPage: React.FC<{ state: CodicentAppState }> = ({ state }) => {
128
+ const { service } = state;
129
+ const { t } = useLocalization();
130
+ const [data, setData] = useState<DataMessage[]>([]);
131
+
132
+ useEffect(() => {
133
+ service.readDataMessages('customer2').then(setData);
134
+ }, [service]);
135
+
136
+ const columns = APP_CONFIG.apps[APP_BUTTONS].listDefinitions['customer2'];
137
+
138
+ return (
139
+ <Page title={t('Kunder')}>
140
+ <Content>
141
+ <ListView data={data} columns={columns} />
142
+ </Content>
143
+ </Page>
144
+ );
145
+ };
146
+ ```
147
+
148
+ ---
149
+
150
+ ## `initCodicentApp()` configuration options
151
+
152
+ **Required:**
153
+
154
+ | Key | Type | Description |
155
+ |-----|------|-------------|
156
+ | `API_BASE_URL` | `string` | Codicent backend URL, e.g. `"https://codicent.com/"` |
157
+ | `APP_NAME` | `string` | Application identifier |
158
+
159
+ **Common optional:**
160
+
161
+ | Key | Type | Description |
162
+ |-----|------|-------------|
163
+ | `APP_PREFIX` | `string` | URL/namespace prefix for this app |
164
+ | `USER_PREFIX` | `string` | User namespace prefix (default: `"users"`) |
165
+ | `APP_CONFIG` | `AppConfig` | Per-app config: buttons, listDefinitions, chatInstructions |
166
+ | `TRANSLATIONS` | `object` | i18n map `{ sv: {...}, en: {...} }`. Swedish strings are used as keys. |
167
+ | `DEFAULT_LANGUAGE` | `string` | Default language code (e.g. `"sv"`, `"en"`) |
168
+ | `USE_REALTIME_SESSION_ENDPOINT` | `boolean` | Use secure backend session token for voice AI (default: `true`) |
169
+ | `REALTIME_VOICE_MODEL` | `string` | Voice model: `"alloy"`, `"shimmer"`, or `"echo"` (default: `"alloy"`) |
170
+ | `SUBSCRIPTION_NEEDED` | `boolean` | Redirect to purchase page if no active subscription |
171
+ | `BUTTON_BORDER_RADIUS` | `string` | CSS border-radius for nav buttons |
172
+ | `BUTTON_BACKGROUND_COLOR` | `string` | Background color for nav buttons |
173
+
174
+ **Compose page GPS options:**
175
+
176
+ | Key | Value | Behaviour |
177
+ |-----|-------|-----------|
178
+ | `COMPOSE_HIDE_LOCATION` | `"true"` | Hides GPS toggle button entirely |
179
+ | `COMPOSE_HIDE_LOCATION` | `"false"` (default) | Shows GPS toggle; users opt-in per post |
180
+ | `COMPOSE_AUTO_LOCATION` | `"true"` | Captures GPS automatically on page open |
181
+
182
+ When a location is attached, `#gps(lat,lon)` is appended to message content — queryable via tag search and readable by AI.
183
+
184
+ ---
185
+
186
+ ## API Reference
187
+
188
+ ### `CodicentService`
189
+
190
+ The main service class for all data and chat operations. Access it via `state.service` from `useCodicentApp()`.
191
+
192
+ **Data message CRUD:**
193
+ ```ts
194
+ createDataMessage(tag: string, data: object, codicent?: string): Promise<string>
195
+
196
+ readDataMessages(
197
+ tag: string,
198
+ search?: string,
199
+ codicent?: string,
200
+ start?: number,
201
+ length?: number,
202
+ afterTimestamp?: string,
203
+ beforeTimestamp?: string,
204
+ dataFilters?: Record<string, string>
205
+ ): Promise<DataMessage[]>
206
+
207
+ readOneDataMessage(id: string): Promise<DataMessage | null>
208
+
209
+ updateDataMessage(id: string, data: object, codicent?: string): Promise<string>
210
+
211
+ deleteDataMessage(id: string, codicent?: string): Promise<string>
212
+
213
+ getSchema(tag: string, codicent?: string): Promise<object | null>
214
+ ```
215
+
216
+ **Chat and messages:**
217
+ ```ts
218
+ sendMessage(message: string, parentId?: string, codicent?: string): Promise<Message>
219
+ chat(message: string, messageId?: string, codicent?: string): Promise<Message>
220
+ getMessages(tags: string[], codicent?: string, length?: number): Promise<Message[]>
221
+ getMessagesFast(tags: string[], search?: string, length?: number, publicCodicent?: string, codicent?: string, start?: number): Promise<Message[]>
222
+ ```
223
+
224
+ **Files:**
225
+ ```ts
226
+ uploadFile(filename: string, formData: FormData): Promise<string>
227
+ getFileInfo(fileId: string): Promise<FileInfo>
228
+ static getImageUrl(fileId: string, width: number): string
229
+ static getFileUrl(fileId: string, extension?: string): string
230
+ ```
231
+
232
+ **Auth and tokens:**
233
+ ```ts
234
+ getToken(): string
235
+ generateApiToken(expires?: Date, forUserNickname?: string): Promise<string>
236
+ ```
237
+
238
+ ---
239
+
240
+ ### `useCodicentApp(options)`
241
+
242
+ Core hook that bootstraps app state, authentication, and the `CodicentService` instance.
243
+
244
+ ```ts
245
+ const state = useCodicentApp({
246
+ auth0: useAuth0(), // Required: Auth0 hook result
247
+ toolsConfig?: object, // Optional: custom AI tool handlers
248
+ authOptions?: object, // Optional: override auth behaviour
249
+ });
250
+ ```
251
+
252
+ Returns `CodicentAppState`:
253
+ ```ts
254
+ {
255
+ service: CodicentService; // Use for all data/chat operations
256
+ context: StateContext; // Project nickname, user info
257
+ auth: UseAuthState;
258
+ voice?: RealtimeVoice; // Voice AI connection (when active)
259
+ audio: AudioRecorderState;
260
+ stateMachine: AppStateMachine;
261
+ state: string; // Current state machine state
262
+ nickname: string; // Active project nickname
263
+ error: string;
264
+ isBusy: () => boolean;
265
+ html: string; // AI-generated HTML output
266
+ setHtml: (html: string) => void;
267
+ }
268
+ ```
269
+
270
+ ### 5. Use `DataMessagePicker` for tagged record lookup
271
+
272
+ ```tsx
273
+ import { DataMessagePicker } from 'codicent-app-sdk';
274
+
275
+ <DataMessagePicker
276
+ service={state.service}
277
+ tag="customer2"
278
+ placeholder="Search customers"
279
+ primaryKey="Company Name"
280
+ displayKeys={["Company Name", "City"]}
281
+ secondaryKeys={["Customer Number", "City"]}
282
+ searchKeys={["Company Name", "Customer Number", "City"]}
283
+ onSelect={(selection) => {
284
+ console.log('Selected customer', selection.id, selection.data);
285
+ }}
286
+ />
287
+ ```
288
+
289
+ The picker debounces lookups through `readDataMessages(...)`, shows compact autosuggest results, and returns the raw `DataMessage` plus a normalized selection payload.
290
+
291
+ ---
292
+
293
+ ### `useLocalization()`
294
+
295
+ ```ts
296
+ const { t, tAsync, getLanguageInfo } = useLocalization();
297
+
298
+ t('Kunder') // → "Customers" (in English)
299
+ await tAsync('Kunder') // API-backed translation with fallback
300
+ getLanguageInfo() // { code: 'en', name: 'English', ... }
301
+ ```
302
+
303
+ Swedish strings are used as keys. Pass your translation maps via `TRANSLATIONS` in `initCodicentApp()`.
304
+
305
+ ---
306
+
307
+ ### Components
308
+
309
+ #### `Page`
310
+ Full-screen layout wrapper with optional header and footer.
311
+ ```tsx
312
+ <Page title="Customers" hideFooter={false} audio={state.audio} voice={state.voice}>
313
+ <Content>...</Content>
314
+ </Page>
315
+ ```
316
+
317
+ #### `Content`
318
+ Flex content container — use inside `Page`.
319
+ ```tsx
320
+ <Content>
321
+ <ListView data={data} columns={columns} />
322
+ </Content>
323
+ ```
324
+
325
+ #### `Chat` (page)
326
+ Full chat UI with message history, input, typing indicators, file uploads.
327
+ ```tsx
328
+ <Chat
329
+ state={state}
330
+ title="AI Assistant"
331
+ codicent="my-project" // Optional: override which project to chat with
332
+ welcomeMessage="Hi!" // Optional: shown when no messages exist
333
+ hideFooter={false}
334
+ />
335
+ ```
336
+
337
+ #### `ListView`
338
+ Tabular data view with sorting, filtering, and column actions.
339
+ ```tsx
340
+ import { ListView } from 'codicent-app-sdk';
341
+
342
+ <ListView
343
+ data={dataMessages}
344
+ columns={[
345
+ { key: 'name', title: 'Name', filterable: true },
346
+ { key: ['offer_number', 'offerNumber'], title: 'Quote #', filterable: true },
347
+ { key: 'grand_total', title: 'Total', format: formatNumber },
348
+ { key: 'pdf', title: 'PDF', type: 'file' },
349
+ ]}
350
+ onSelect={(item) => navigate(`/chat?id=${item.originalMessageId}`)}
351
+ />
352
+ ```
353
+
354
+ Column definition options:
355
+ - `key: string | string[]` — JSON field name; array = fallback chain
356
+ - `format: (value) => string` — display transformer
357
+ - `filterable: true` per-column text filter
358
+ - `type: "file"` — renders download link
359
+ - `type: "checkbox"` — renders checkbox
360
+ - `action` icon button with click handler
361
+
362
+ #### `AppFrame`
363
+ Embeds an external URL in an iframe within the page layout.
364
+ ```tsx
365
+ <AppFrame src="https://example.com/embed" title="External view" showFooter={true} />
366
+ ```
367
+
368
+ #### `Markdown`
369
+ Renders markdown content including GFM and Mermaid diagrams.
370
+ ```tsx
371
+ <Markdown content={message.content} />
372
+ ```
373
+
374
+ #### `UploadFile`
375
+ File upload UI with progress.
376
+ ```tsx
377
+ <UploadFile service={state.service} codicent="my-project" />
378
+ ```
379
+
380
+ ---
381
+
382
+ ### Hooks summary
383
+
384
+ | Hook | Purpose |
385
+ |------|---------|
386
+ | `useCodicentApp()` | Core app state, service, auth |
387
+ | `useLocalization()` | i18n translation |
388
+ | `useChat(service)` | Chat message state and send |
389
+ | `useRealtimeVoiceAI(options)` | Real-time voice AI connection |
390
+ | `useAuthState(auth0)` | Auth lifecycle and token |
391
+ | `useTheme()` | App theme/branding |
392
+ | `useToaster()` | Toast notification helpers |
393
+ | `useStateWithLocalStorage()` | Persistent local state |
394
+ | `useAudioRecorder()` | Microphone recording |
395
+ | `useTemplateVariables()` | Template string utilities |
396
+ | `useTools()` | AI tool handler registration |
397
+ | `useEmbeddings()` | Vector embedding operations |
398
+
399
+ ---
400
+
401
+ ## TypeScript types
402
+
403
+ ```tsx
404
+ import type {
405
+ CodicentAppState,
406
+ ButtonConfig,
407
+ ColumnDefinition,
408
+ ListDefinitions,
409
+ DataMessage,
410
+ Message,
411
+ } from 'codicent-app-sdk';
412
+ ```
413
+
414
+ **`ButtonConfig`** — navigation button with optional RBAC claims:
415
+ ```ts
416
+ {
417
+ title: string;
418
+ url: string; // "#/list?tag=customer2", "voice:...", "mailto:...", etc.
419
+ claim?: string; // Show only if user has this claim
420
+ notClaim?: string; // Hide if user has this claim
421
+ subtitle?: string;
422
+ options?: ButtonConfig[];
423
+ }
424
+ ```
425
+
426
+ **`DataMessage`** result from `readDataMessages()`:
427
+ ```ts
428
+ {
429
+ id: string;
430
+ originalMessageId: string; // Stable ID across updates — use this for references/tags
431
+ content: string; // Raw: "@project #data #tag\n{json}"
432
+ data: Record<string, unknown>; // Parsed JSON payload
433
+ tags: string[];
434
+ createdAt: string;
435
+ }
436
+ ```
437
+
438
+ ---
439
+
440
+ ## Alternative: `createCodicentApp()` factory
441
+
442
+ For standalone deployments where you do not control the React entry point, `createCodicentApp()` wraps the full initialization (including Auth0Provider, FluentProvider, HashRouter) and renders to a DOM element:
443
+
444
+ ```tsx
445
+ import { createCodicentApp } from 'codicent-app-sdk';
446
+
447
+ const app = createCodicentApp({
448
+ name: 'My CRM',
449
+ apiBaseUrl: 'https://codicent.com/',
450
+ auth0: { domain: '...', clientId: '...' },
451
+ buttons: [
452
+ { title: 'Customers', url: './#/list?tag=customer2' },
453
+ { title: 'Chat', url: './#/chat' },
454
+ ],
455
+ listDefinitions: {
456
+ customer2: [
457
+ { key: 'name', title: 'Name', filterable: true },
458
+ { key: 'email', title: 'Email' },
459
+ ],
460
+ },
461
+ chatInstructions: 'You are a helpful CRM assistant.',
462
+ modules: { sales: true, voice: true },
463
+ });
464
+
465
+ app.render('#root');
466
+ // app.unmount();
467
+ // app.getConfig();
468
+ ```
469
+
470
+ The `codicentapp/` reference implementation uses `initCodicentApp()` + manual React tree setup, which gives more control over routing and layout. `createCodicentApp()` is appropriate for simpler or standalone deployments.
471
+
472
+ ---
473
+
474
+ ## Local development workflow
475
+
476
+ ### Build the SDK
477
+
478
+ ```bash
479
+ cd codicent-app-sdk
480
+ npm install
481
+ npm run build # Output: dist/cjs/, dist/esm/, dist/index.d.ts
482
+ npm run dev # Watch mode
483
+ ```
484
+
485
+ ### Test in codicentapp (file: reference)
486
+
487
+ In `codicentapp/package.json`:
488
+ ```json
489
+ "codicent-app-sdk": "file:../codicent-app-sdk"
490
+ ```
491
+ Then:
492
+ ```bash
493
+ cd codicentapp
494
+ npm install
495
+ npm run build
496
+ ```
497
+
498
+ ### Test with npm link
499
+
500
+ ```bash
501
+ # In SDK directory
502
+ npm link
503
+
504
+ # In your app directory
505
+ npm link codicent-app-sdk
506
+ ```
507
+
508
+ To restore npm version:
509
+ ```bash
510
+ npm uninstall codicent-app-sdk
511
+ npm install codicent-app-sdk
512
+ ```
513
+
514
+ ### Build output layout
515
+
516
+ ```
517
+ dist/
518
+ cjs/ CommonJS modules
519
+ esm/ ES modules
520
+ index.d.ts TypeScript definitions
521
+ ```
522
+
523
+ ### Release
524
+
525
+ ```bash
526
+ npm version patch # or minor / major
527
+ npm run build
528
+ npm publish --access public
529
+ ```
530
+
531
+ ---
532
+
533
+ ## Debugging
534
+
535
+ The SDK emits `codicent-log` custom events on `window`:
536
+
537
+ ```tsx
538
+ window.addEventListener('codicent-log', (event: CustomEvent) => {
539
+ console.log(event.detail); // { level, message, context }
540
+ });
541
+ ```
542
+
543
+ ---
544
+
545
+ ## Related
546
+
547
+ - `codicentapp/` — primary consumer; complete reference implementation
548
+ - `codicent-api-client/` — framework-agnostic fetch-based API client (shared with web components)
549
+ - `codicent-components/` — zero-build Web Components library using the same Codicent API
550
+ - [Voice Upgrade Guide](VOICE_UPGRADE_GUIDE.md) — real-time voice AI setup and security
551
+
552
+ ---
553
+
554
+ ## License
555
+
556
+ MIT © Codicent Inside AB