@cosmoops/connect-sdk 0.7.0 → 0.9.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.
- package/CHANGELOG.md +165 -0
- package/README.md +273 -91
- package/dist/cjs/client/components/access-gate.js +39 -4
- package/dist/cjs/client/components/ai-format.js +135 -0
- package/dist/cjs/client/components/ai-widgets.js +232 -0
- package/dist/cjs/client/components/app-shell.js +7 -6
- package/dist/cjs/client/components/ask-ai.js +334 -0
- package/dist/cjs/client/components/nav.js +1 -1
- package/dist/cjs/client/components/side-nav.js +1 -1
- package/dist/cjs/client/components/user-menu.js +28 -5
- package/dist/cjs/client/components/workspace-type-gate.js +48 -0
- package/dist/cjs/client/index.js +31 -3
- package/dist/cjs/client/provider.js +45 -2
- package/dist/cjs/server/client.js +1 -1
- package/dist/cjs/server/handler.js +43 -0
- package/dist/cjs/server/http.js +46 -24
- package/dist/cjs/server/resources/entitlements.js +41 -0
- package/dist/cjs/server/resources/identity.js +2 -0
- package/dist/esm/client/components/access-gate.js +40 -5
- package/dist/esm/client/components/ai-format.js +129 -0
- package/dist/esm/client/components/ai-widgets.js +223 -0
- package/dist/esm/client/components/app-shell.js +6 -5
- package/dist/esm/client/components/ask-ai.js +331 -0
- package/dist/esm/client/components/nav.js +1 -1
- package/dist/esm/client/components/side-nav.js +1 -1
- package/dist/esm/client/components/user-menu.js +28 -5
- package/dist/esm/client/components/workspace-type-gate.js +45 -0
- package/dist/esm/client/index.js +13 -2
- package/dist/esm/client/provider.js +43 -2
- package/dist/esm/server/client.js +1 -1
- package/dist/esm/server/handler.js +43 -0
- package/dist/esm/server/http.js +46 -24
- package/dist/esm/server/resources/entitlements.js +41 -0
- package/dist/esm/server/resources/identity.js +2 -0
- package/dist/theme.css +87 -0
- package/dist/types/client/components/access-gate.d.ts +17 -3
- package/dist/types/client/components/ai-format.d.ts +24 -0
- package/dist/types/client/components/ai-widgets.d.ts +42 -0
- package/dist/types/client/components/app-shell.d.ts +21 -5
- package/dist/types/client/components/ask-ai.d.ts +73 -0
- package/dist/types/client/components/nav.d.ts +3 -3
- package/dist/types/client/components/side-nav.d.ts +1 -1
- package/dist/types/client/components/user-menu.d.ts +2 -1
- package/dist/types/client/components/workspace-type-gate.d.ts +48 -0
- package/dist/types/client/index.d.ts +10 -3
- package/dist/types/client/provider.d.ts +44 -1
- package/dist/types/server/client.d.ts +1 -1
- package/dist/types/server/http.d.ts +6 -1
- package/dist/types/server/resources/entitlements.d.ts +33 -1
- package/dist/types/types.d.ts +174 -0
- package/package.json +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,171 @@
|
|
|
3
3
|
`@cosmoops/connect-sdk` follows semver, with the 0.x convention that **minor
|
|
4
4
|
versions may carry breaking changes** and patch versions never do.
|
|
5
5
|
|
|
6
|
+
## 0.9.0
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **`user.workspaceType`** on `exchangeCode()` and `getUser()` - `"individual"`
|
|
11
|
+
(a one-seat personal account, KYC) or `"business"` (a team, KYB). The one
|
|
12
|
+
fact about the signed-in workspace a partner could not look up on its own:
|
|
13
|
+
the application API has no workspace read, so an application serving both
|
|
14
|
+
audiences had to render one UI for everybody. An `"individual"` workspace
|
|
15
|
+
has exactly one seat and can never gain another, so a members table, an
|
|
16
|
+
invite button and a seat meter are all dead controls there.
|
|
17
|
+
|
|
18
|
+
Re-read it rather than caching it past sign-in: an individual workspace can
|
|
19
|
+
convert to a business one under a live session (the reverse never happens).
|
|
20
|
+
|
|
21
|
+
- **`audience`** on the same two responses - what your application is *sold*
|
|
22
|
+
to, joined with the account in front of you:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
const { user, audience } = await connect.identity.exchangeCode({ code, redirectUri });
|
|
26
|
+
// user.workspaceType -> "individual"
|
|
27
|
+
// audience.application -> "b2b"
|
|
28
|
+
// audience.matches -> false
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`matches: false` is a hard block, not a hint: readiness reports an
|
|
32
|
+
`audience_mismatch` blocker and any attempt to subscribe is refused. It ships
|
|
33
|
+
alongside `workspaceType` so the check stays `!audience.matches` instead of a
|
|
34
|
+
hardcoded audience constant in your own code that goes stale the moment the
|
|
35
|
+
catalogue entry changes. `audience.enforcedAtSignIn` tells you whether
|
|
36
|
+
Connect refuses the sign-in itself, in which case a mismatch can only reach
|
|
37
|
+
you on a session minted before that setting was turned on.
|
|
38
|
+
|
|
39
|
+
- **`<ConnectWorkspaceTypeGate>`**, plus `useConnectWorkspaceType()` and
|
|
40
|
+
`useConnectAudience()`:
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
<ConnectWorkspaceTypeGate type="business">
|
|
44
|
+
<TeamMembersTable />
|
|
45
|
+
</ConnectWorkspaceTypeGate>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This is *not* the audience gate - it does not know what your application is
|
|
49
|
+
sold to, and is for varying what each account type sees *inside* an
|
|
50
|
+
application both audiences can reach. `<ConnectAccessGate>` remains the one
|
|
51
|
+
that blocks a mismatched account outright, and already did.
|
|
52
|
+
|
|
53
|
+
Like every gate in this package: a UX gate, not a security boundary.
|
|
54
|
+
|
|
55
|
+
- **`<ConnectAskAi>`**, and `askAi` on `AppShell` - a chat panel grounded in
|
|
56
|
+
the signed-in workspace's Context Index. **On by default**, like `gate`:
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
<AppShell name="Dispatch" nav={nav}>
|
|
60
|
+
{children}
|
|
61
|
+
</AppShell>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
It stays inert until it can work - nothing renders for a signed-out visitor,
|
|
65
|
+
and a workspace whose Context Index is off gets a message in the panel rather
|
|
66
|
+
than a broken answer. Pass `askAi={false}` for an application that should not
|
|
67
|
+
offer it, or an object to override the heading, copy or markdown plugins.
|
|
68
|
+
|
|
69
|
+
It holds no credential, like everything else in `./client`: it POSTs to
|
|
70
|
+
`${basePath}/ai/chat`, a new bridge route on `createConnectHandler` that
|
|
71
|
+
resolves the workspace from the caller's own session and streams Connect's
|
|
72
|
+
answer straight through. A browser-supplied `workspaceId` would be another
|
|
73
|
+
tenant's documents delivered as a chat reply, so there isn't one.
|
|
74
|
+
|
|
75
|
+
The panel parses the server-sent event stream itself rather than pulling in
|
|
76
|
+
`ai`/`@ai-sdk/react`.
|
|
77
|
+
|
|
78
|
+
- **Answers that draw, not just write.** Connect's Ask AI can call a small set
|
|
79
|
+
of *presentation tools*, and this panel renders each one natively:
|
|
80
|
+
|
|
81
|
+
| Tool | Rendered as |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `showTable` | a sortable table with a CSV download |
|
|
84
|
+
| `showChart` | a bar / line / area chart (inline SVG), or a labelled proportion list for `pie` |
|
|
85
|
+
| `showMetrics` | up to six metric tiles with period-over-period deltas |
|
|
86
|
+
| `showTimeline` | dated events on a rail |
|
|
87
|
+
| `showDetails` | one entity's fields as a fact sheet |
|
|
88
|
+
| `showSteps` | a numbered procedure |
|
|
89
|
+
| `showSources` | the documents a grounded answer rested on |
|
|
90
|
+
|
|
91
|
+
Every value arrives **raw with a format tag** - a currency is the number
|
|
92
|
+
`12500`, never the string `"₹12,500"` - so it is formatted in the viewer's
|
|
93
|
+
locale here, and a column still sorts numerically. The seven widgets and
|
|
94
|
+
`formatAiValue` are exported for a partner rendering Connect's chat somewhere
|
|
95
|
+
other than this panel.
|
|
96
|
+
|
|
97
|
+
No charting library ships in this package: the chart is hand-drawn SVG. A
|
|
98
|
+
400px side panel does not need pan, zoom or brushes, and a charting
|
|
99
|
+
dependency is not a reasonable thing to make every platform install.
|
|
100
|
+
|
|
101
|
+
- **Markdown, via `streamdown`** - tables, fenced code, task lists, and a
|
|
102
|
+
word-by-word `blurIn` reveal with a caret while the answer streams. Three
|
|
103
|
+
host steps, all one-time:
|
|
104
|
+
|
|
105
|
+
1. `npm i streamdown` (a new **optional** peer dependency - the panel is the
|
|
106
|
+
only thing that uses it).
|
|
107
|
+
2. `@source "…/node_modules/streamdown/dist/*.js";` in your Tailwind CSS, so
|
|
108
|
+
its utility classes are generated.
|
|
109
|
+
3. `import "streamdown/styles.css";` for the streaming animation.
|
|
110
|
+
|
|
111
|
+
The colour tokens Streamdown expects (it paints with shadcn/ui's names) are
|
|
112
|
+
mapped onto HeroUI's in this SDK's `theme.css`, which you already import - so
|
|
113
|
+
answers inherit your platform's theme with no further work.
|
|
114
|
+
|
|
115
|
+
Syntax highlighting, KaTeX, Mermaid and CJK typography are Streamdown plugin
|
|
116
|
+
packages, off unless you pass them - several are large, and prose, tables and
|
|
117
|
+
plain code fences render without any of them:
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
import { code } from "@streamdown/code";
|
|
121
|
+
const PLUGINS = { code }; // module scope: Streamdown compares this by reference
|
|
122
|
+
|
|
123
|
+
<AppShell name="Dispatch" nav={nav} askAi={{ markdownPlugins: PLUGINS }}>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
- `streamResource()` on `useConnect()` - POST through the bridge and get the
|
|
127
|
+
raw `Response` back, unread and uncached. The seam `<ConnectAskAi>` streams
|
|
128
|
+
over, and the one to use for any future streaming route.
|
|
129
|
+
|
|
130
|
+
### Changed
|
|
131
|
+
|
|
132
|
+
- `ConnectSession` (the value behind `useConnect()`) carries `audience`,
|
|
133
|
+
`null` when signed out alongside the three fields that already were.
|
|
134
|
+
|
|
135
|
+
### Known gaps
|
|
136
|
+
|
|
137
|
+
- No SDK methods for the channel and call endpoints (`GET /channels`,
|
|
138
|
+
`GET`/`PUT`/`DELETE /channels/{channelId}/routing`, `GET /calls`,
|
|
139
|
+
`GET /calls/{callId}`). They are documented in the partner API and callable
|
|
140
|
+
over HTTP; they just have no typed wrapper here yet. The conformance suite
|
|
141
|
+
names them, and stays red until they land.
|
|
142
|
+
|
|
143
|
+
### Fixed
|
|
144
|
+
|
|
145
|
+
- `ai.chat()` no longer has its stream cut off mid-answer. The transport's
|
|
146
|
+
`timeoutMs` (20s by default) was handed to `fetch` as an `AbortSignal`, and a
|
|
147
|
+
`fetch` signal keeps governing the *body* long after the headers arrive - so
|
|
148
|
+
any conversation that took longer than the timeout to finish generating was
|
|
149
|
+
torn down. The timeout is now cleared once an attempt is done reading, which
|
|
150
|
+
for a `raw` (streaming) request means once the headers land. Pass your own
|
|
151
|
+
`signal` to bound the stream itself.
|
|
152
|
+
|
|
153
|
+
## 0.8.0
|
|
154
|
+
|
|
155
|
+
*Never published - `0.9.0` is the first release carrying these changes.*
|
|
156
|
+
|
|
157
|
+
### Changed (breaking)
|
|
158
|
+
|
|
159
|
+
- **`ConnectAppShell` renamed to `AppShell`.** No other change - same props,
|
|
160
|
+
same behaviour. Every other component in `/client` keeps its `Connect`
|
|
161
|
+
prefix; this is the one exception, by request. Update the import:
|
|
162
|
+
|
|
163
|
+
```diff
|
|
164
|
+
- import { ConnectAppShell, type ConnectAppShellProps } from "@cosmoops/connect-sdk/client";
|
|
165
|
+
+ import { AppShell, type AppShellProps } from "@cosmoops/connect-sdk/client";
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
If your own layout component is also called `AppShell` (a common name for
|
|
169
|
+
one), alias the import: `import { AppShell as ConnectAppShell } from "..."`.
|
|
170
|
+
|
|
6
171
|
## 0.6.0
|
|
7
172
|
|
|
8
173
|
### Added
|