@sub-zero/cocoa 0.0.0-stage → 0.1.1

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.
package/README.md CHANGED
@@ -1,3 +1,165 @@
1
- # Temporary Holding Version
1
+ # Cocoa
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A circular Cocoa portrait button that opens support chat at the bottom right of any web application. Cocoa connects visitors
4
+ to your SubZero chatbot and puts conversations in **Agents → Chatbots**, where your
5
+ team can view, reply, approve agent drafts, and take over.
6
+
7
+ Zero runtime dependencies. Works with vanilla JavaScript, React, Vue, Angular,
8
+ and other browser frameworks. Styles live in a Shadow DOM so host styles do not
9
+ change the widget.
10
+
11
+ ## Set up your chatbot
12
+
13
+ 1. In SubZero, configure hosted Cocoa under **Agents → Cocoa**, or connect your
14
+ own agent. Hosted Cocoa is a $20/month add-on using your server-stored provider
15
+ key; your provider charges separately. Installing this UI does not start a
16
+ subscription or include a hosted agent.
17
+ 2. Under **Agents → Chatbots**, create a chatbot for your project and agent.
18
+ 3. Add your website's exact origin, including scheme and development port
19
+ (for example `https://app.example.com` or `http://localhost:3000`), and enable it.
20
+ 4. Copy the chatbot ID from Settings & installation into the example below.
21
+
22
+ Only the **public chatbot ID** belongs in this widget. Never embed a model API
23
+ key, SubZero agent token, staff login token, or private RDK credential.
24
+
25
+ ## Install with npm
26
+
27
+ ```sh
28
+ npm install @sub-zero/cocoa
29
+ ```
30
+
31
+ ```js
32
+ import { createCocoa } from '@sub-zero/cocoa';
33
+
34
+ const cocoa = createCocoa({
35
+ chatbotId: 'YOUR_CHATBOT_UUID',
36
+ });
37
+ ```
38
+
39
+ Call `createCocoa` after the document body exists. The bubble appears immediately;
40
+ no conversation is created until the visitor sends a message. The default API is
41
+ `https://api.sub-zero.dev`.
42
+
43
+ ### React / Next.js
44
+
45
+ Mount once in a client component or application layout. Importing the package is
46
+ safe on the server; mounting it requires a browser.
47
+
48
+ ```jsx
49
+ 'use client';
50
+ import { useEffect } from 'react';
51
+ import { createCocoa } from '@sub-zero/cocoa';
52
+
53
+ export function CocoaSupport() {
54
+ useEffect(() => {
55
+ const cocoa = createCocoa({ chatbotId: 'YOUR_CHATBOT_UUID' });
56
+ return () => cocoa.destroy();
57
+ }, []);
58
+ return null;
59
+ }
60
+ ```
61
+
62
+ For Vue, mount in `onMounted` and destroy in `onUnmounted`. For Angular, mount in
63
+ `ngAfterViewInit` in the browser and destroy in `ngOnDestroy`. In an SPA, mount in
64
+ the application shell rather than on each route. For the same API/chatbot pair,
65
+ repeated calls return the existing instance; the first caller's options apply.
66
+
67
+ ### Plain HTML
68
+
69
+ Copy `node_modules/@sub-zero/cocoa/dist/cocoa.js` to your public assets:
70
+
71
+ ```html
72
+ <script defer src="/cocoa.js" data-chatbot="YOUR_CHATBOT_UUID"></script>
73
+ ```
74
+
75
+ Optional attributes: `data-api`, `data-title`, `data-launcher-label`, and
76
+ `data-accent-color`. To initialize manually, load the script without
77
+ `data-chatbot` and call `window.Cocoa.createCocoa(options)`. Automatic initialization
78
+ exposes the handle as `window.Cocoa.widget`.
79
+
80
+ SubZero's dashboard-hosted `/subzero-chat.js` uses the same implementation and
81
+ continues to accept existing `data-api` and `data-chatbot` installation snippets.
82
+ For a reproducible release, self-host the file from a pinned npm version.
83
+
84
+ ## Options and controls
85
+
86
+ ```js
87
+ const cocoa = createCocoa({
88
+ chatbotId: 'YOUR_CHATBOT_UUID',
89
+ apiUrl: 'https://api.sub-zero.dev',
90
+ title: 'Acme support',
91
+ launcherLabel: 'Need help?',
92
+ welcomeMessage: 'Hi! How can we help?',
93
+ accentColor: '#385b50',
94
+ visitorLabel: 'Alex', // display name only; not a verified identity
95
+ persistSession: true,
96
+ zIndex: 2147483000,
97
+ pollInterval: 2500,
98
+ // nonce: yourCspNonce,
99
+ onError(error) { console.warn(error.message); },
100
+ });
101
+
102
+ cocoa.open();
103
+ cocoa.close();
104
+ cocoa.toggle();
105
+ cocoa.reset(); // forget this tab's conversation; does not delete server history
106
+ cocoa.destroy(); // remove UI, stop timers, abort requests; keep session for remount
107
+ ```
108
+
109
+ `reset()` aborts in-flight requests and clears local conversation state. A message
110
+ already accepted by the server cannot be recalled. Call it on application logout or
111
+ account switch to avoid resuming a previous visitor's conversation in that tab.
112
+ Use `persistSession: false` to keep credentials in memory only. With the default
113
+ setting, the visitor credential and any unacknowledged message retry are held in
114
+ sessionStorage. Blocked storage falls back to memory; private-browser reloads may
115
+ therefore start a new conversation. This package does not collect the current
116
+ page URL, app state, or account information.
117
+
118
+ The widget supports Escape to close, labeled form controls, polite announcement
119
+ of new messages, reduced motion, and narrow screens. It is a nonmodal dialog:
120
+ visitors can continue interacting with the host page. Replies are rendered as
121
+ plain text, never executable HTML or Markdown.
122
+
123
+ Polling runs only while the chat is open and the page is visible. Errors back off
124
+ up to 30 seconds; requests time out after 20 seconds. Message retries reuse an
125
+ idempotency key, including after reload when sessionStorage is available. Closing
126
+ or pausing a conversation disables sending; expired sessions offer a fresh start.
127
+ There is no substitute AI when the assigned agent is offline. Human replies
128
+ still arrive through the same conversation.
129
+
130
+ ## Security and hosting
131
+
132
+ Use HTTPS for the API. HTTP is supported only for loopback development hosts.
133
+ Visitor tokens are sent only to the configured API, with cookies omitted and
134
+ redirects rejected. An allowed website origin controls embedding; it does not
135
+ verify the visitor's identity. Do not provide account-specific private data
136
+ based only on a name typed into chat.
137
+
138
+ For Content Security Policy, allow `data:` under `img-src` for the bundled Cocoa portrait, the API under `connect-src`, the script source
139
+ under `script-src`, and supply a valid nonce through the `nonce` option (or script
140
+ nonce attribute) for the widget stylesheet. The widget uses DOM APIs and is
141
+ compatible with Trusted Types enforcement. The supplied Cocoa portrait is bundled in the widget, so it needs no external image host. No remote fonts, images,
142
+ iframes, analytics, model SDKs, or third-party styles are loaded.
143
+
144
+ Existing SubZero chat webhooks and human approval policies apply unchanged. RDK
145
+ knowledge and provider credentials are handled by the assigned agent and backend,
146
+ never by this package.
147
+
148
+ ## Maintainers
149
+
150
+ From the frontend repository:
151
+
152
+ ```sh
153
+ npm run build:cocoa
154
+ npm run test:cocoa
155
+ cd packages/cocoa
156
+ npm pack --dry-run
157
+ npm publish --access public
158
+ ```
159
+
160
+ The package build uses only Node built-ins. Browser tests use the frontend's
161
+ Playwright development dependency and installed Chromium. The published tarball
162
+ contains only `dist`, this README, and package metadata. Do not publish the private
163
+ Angular application root. Review the version and `npm pack --dry-run` output before
164
+ publishing. No open-source license is granted (`UNLICENSED`); the source repository
165
+ may be private.