nivq-chat-widget 1.0.0 → 1.0.2

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
@@ -5,91 +5,100 @@ Embeddable NivQ chat experience as a framework-agnostic Web Component
5
5
  one tag and get the NivQ chat UI in a floating launcher (FAB) or inline panel.
6
6
 
7
7
  - **Style-isolated** — renders in a Shadow DOM; no CSS bleed in either direction.
8
- - **Secret-safe** — never touches your OAuth2 `clientSecret`. It fetches a
9
- short-lived token from your own token-broker endpoint. See
10
- [`docs/integration.md`](docs/integration.md).
8
+ - **Secret-safe** — never touches your OAuth2 `clientSecret`; it uses a
9
+ short-lived token from your own token-broker endpoint (see below).
11
10
  - **Themeable** — defaults to the NivQ brand; override palette, logo, radius.
12
11
  - **Lazy charts** — the Vega rendering stack loads only when a turn returns a chart.
13
12
 
14
13
  ## Quick start
15
14
 
15
+ Via CDN (jsDelivr) — no build step:
16
+
16
17
  ```html
17
- <script type="module" src="https://cdn.jsdelivr.net/npm/nivq-chat-widget@1/dist/nivq-chat.js"></script>
18
- <nivq-chat
19
- agent-id="YOUR_AGENT_ID"
20
- api-base-url="https://api.nivq.ai"
21
- token-endpoint="/nivq-token">
18
+ <script
19
+ type="module"
20
+ src="https://cdn.jsdelivr.net/npm/nivq-chat-widget@1/dist/nivq-chat.js"
21
+ ></script>
22
+ <nivq-chat agent-id="YOUR_AGENT_ID" api-base-url="https://api.nivq.ai" token-endpoint="/nivq-token">
22
23
  </nivq-chat>
23
24
  ```
24
25
 
25
- You must run a small **token broker** on your backend (≈20 lines) so the secret
26
- never reaches the browser. Full guide + Node/Spring examples:
27
- [`docs/integration.md`](docs/integration.md).
28
-
29
- ## Develop
26
+ Or via npm (bundlers / React / Angular):
30
27
 
31
28
  ```bash
32
- bun install
33
-
34
- # 1. Run the mock token broker against a NivQ backend + a dev API client:
35
- NIVQ_API_BASE=http://localhost:8080 \
36
- NIVQ_CLIENT_ID=nivq_… NIVQ_CLIENT_SECRET=… \
37
- bun run broker
38
-
39
- # 2. Run the dev harness, then fill in agent id + endpoints and click Mount:
40
- bun run dev
41
-
42
- bun run build # → dist/nivq-chat.js (+ lazy chart chunk)
43
- bun run type-check
29
+ npm i nivq-chat-widget
44
30
  ```
45
31
 
46
- ## Architecture
47
-
48
- ```
49
- <nivq-chat> (custom element, src/element.ts)
50
- └─ Shadow DOM + injected Tailwind stylesheet (tokens scoped to :host)
51
- └─ React root (src/Widget.tsx) — FAB or inline
52
- ├─ TokenProvider (src/auth) — fetches/caches the broker token
53
- ├─ useWidgetChat (src/chat) — SSE streaming, ephemeral/local state
54
- └─ chat UI (src/chat) — forked from nivq-web-client
32
+ ```ts
33
+ import "nivq-chat-widget"; // registers <nivq-chat>; ships its own types
55
34
  ```
56
35
 
57
- Presentational chat components are forked from `nivq-web-client`; a shared
58
- `nivq-chat-ui` package is a possible future consolidation.
59
-
60
- ## Publish (maintainers)
61
-
62
- Published to npm; the CDN URL is served straight from npm by jsDelivr — one
63
- publish covers both `npm i` and `<script>` consumers.
64
-
65
- ### CI release (recommended)
66
-
67
- `.github/workflows/release.yml` publishes automatically when a `v*` tag is
68
- pushed. The flow:
69
-
70
- ```bash
71
- npm version <patch|minor|major> # bumps package.json + creates tag vX.Y.Z
72
- git push --follow-tags # CI builds (via prepublishOnly) and publishes
36
+ Pin the major (`@1`) for automatic patches without breaking changes.
37
+
38
+ ## Token broker (required)
39
+
40
+ The widget authenticates with a **short-lived bearer token**, never your
41
+ `clientSecret`. Stand up one small endpoint on your backend that exchanges your
42
+ NivQ credentials for a token and returns only `{ access_token, expires_in }`:
43
+
44
+ ```js
45
+ // POST /nivq-token (your backend) — authenticate YOUR user first, then:
46
+ const r = await fetch(`${process.env.NIVQ_API_BASE}/oauth2/token`, {
47
+ method: "POST",
48
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
49
+ body: new URLSearchParams({
50
+ grant_type: "client_credentials",
51
+ client_id: process.env.NIVQ_CLIENT_ID,
52
+ client_secret: process.env.NIVQ_CLIENT_SECRET, // stays server-side
53
+ }),
54
+ });
55
+ const { access_token, expires_in } = await r.json();
56
+ res.json({ access_token, expires_in }); // never return the secret
73
57
  ```
74
58
 
75
- One-time setup: add repo secret **`NPM_TOKEN`** (npm automation token with
76
- publish rights for the `nivq-chat-widget` package) under Settings Secrets and variables →
77
- Actions. `.github/workflows/ci.yml` runs type-check + build on every push/PR.
78
-
79
- ### Manual publish (fallback)
80
-
81
- ```bash
82
- npm login # your npm account with publish rights
83
- npm publish # prepublishOnly runs the build automatically
59
+ The widget calls `POST {token-endpoint}`, caches the token, and refreshes it
60
+ before expiry. Full Node/Spring examples, the CORS allow-list step, and the
61
+ privacy notes are in `docs/integration.md` (shipped in the package).
62
+
63
+ > **CORS:** the widget streams straight from the browser to `api-base-url`, so
64
+ > add the origin(s) you embed on to the API key's **Allowed origins** when you
65
+ > create it.
66
+
67
+ ## Configuration
68
+
69
+ | Attribute | Required | Default | Description |
70
+ | ------------------ | -------- | -------------- | -------------------------------------------------------- |
71
+ | `agent-id` | ✅ | — | The NivQ agent to chat with |
72
+ | `token-endpoint` | ✅ | — | Your token broker URL |
73
+ | `api-base-url` | ✅ | — | NivQ chat API base (e.g. `https://api.nivq.ai`) |
74
+ | `mode` | | `fab` | `fab` (floating launcher) or `inline` |
75
+ | `target` | | — | Inline only: CSS selector of the container to mount into |
76
+ | `position` | | `bottom-right` | `bottom-right` or `bottom-left` (FAB) |
77
+ | `theme` | | `auto` | `light`, `dark`, or `auto` (follows OS) |
78
+ | `locale` | | `auto` | `tr`, `en`, or `auto` (browser language) |
79
+ | `primary-color` | | NivQ red | Hex (`#6d28d9`) or HSL triplet (`265 70% 50%`) |
80
+ | `accent-color` | | NivQ | Hex or HSL triplet |
81
+ | `radius` | | `0.625rem` | Corner radius (any CSS length) |
82
+ | `logo-url` | | NivQ mark | Replace the brand logo |
83
+ | `brand-name` | | `NivQ` | Header title / logo alt text |
84
+ | `launcher-label` | | — | Text next to the FAB icon |
85
+ | `greeting` | | — | Custom empty-state heading |
86
+ | `placeholder` | | localized | Input placeholder text |
87
+ | `title` | | localized | Panel header title |
88
+ | `external-user-id` | | — | Distinguishes your end-user |
89
+ | `persist` | | `false` | Persist the conversation in `localStorage` |
90
+ | `start-open` | | `false` | FAB only: open the panel on load |
91
+
92
+ Programmatic config:
93
+
94
+ ```js
95
+ document.querySelector("nivq-chat").configure({
96
+ primaryColor: "#6d28d9",
97
+ brandName: "Acme Assistant",
98
+ mode: "inline",
99
+ });
84
100
  ```
85
101
 
86
- After publish the CDN URL is live immediately:
87
-
88
- ```
89
- https://cdn.jsdelivr.net/npm/nivq-chat-widget@1/dist/nivq-chat.js
90
- ```
102
+ ## License
91
103
 
92
- `files: ["dist"]` ships only the build output (entry + chunks + `nivq-chat.d.ts`).
93
- Tell customers to pin the major (`@1`) — they get patches/minors, never breaking
94
- changes. Every release bumps `version` (immutable, long-cached URLs); the entry
95
- imports its chunks by relative path, so all `dist/*` files publish together.
104
+ UNLICENSED © Nivorbit. See https://nivq.ai.
@@ -1,4 +1,4 @@
1
- import { g as kg, R as ta, j as X7 } from "./element-D4amUXLj.js";
1
+ import { g as kg, R as ta, j as X7 } from "./element-D3xRY4Za.js";
2
2
  var Dd = { exports: {} }, Td = { exports: {} }, Ie = {};
3
3
  var pS;
4
4
  function K7() {
@@ -40903,15 +40903,7 @@ function kme(e) {
40903
40903
  }));
40904
40904
  }
40905
40905
  function g1e({ spec: e }) {
40906
- return /* @__PURE__ */ X7.jsx(
40907
- kme,
40908
- {
40909
- spec: e,
40910
- actions: !1,
40911
- renderer: "canvas",
40912
- className: "w-full"
40913
- }
40914
- );
40906
+ return /* @__PURE__ */ X7.jsx(kme, { spec: e, actions: !1, renderer: "canvas", className: "w-full" });
40915
40907
  }
40916
40908
  export {
40917
40909
  g1e as default