inline-chat-kit 0.54.3 → 0.55.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/CHANGELOG.md +71 -0
- package/dist/ChatExperience/ChatExperience.d.ts +115 -0
- package/dist/ChatExperience-C2UXwrrI.js +5844 -0
- package/dist/ChatExperience-C2UXwrrI.js.map +1 -0
- package/dist/demo/ChatExperienceDemo.d.ts +27 -0
- package/dist/demo/InlineChatBanner.d.ts +6 -0
- package/dist/demo/IntroLanding.d.ts +43 -0
- package/dist/demo/featureStatus.d.ts +18 -0
- package/dist/demo/index.d.ts +8 -0
- package/dist/demo/scriptedApi.d.ts +49 -0
- package/dist/demo.js +693 -0
- package/dist/demo.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/inline-chat-kit.css +1 -1
- package/dist/inline-chat-kit.js +8 -5541
- package/dist/inline-chat-kit.js.map +1 -1
- package/dist/theme/useThemeAttribute.d.ts +16 -0
- package/getting-started.md +33 -69
- package/package.json +7 -3
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,77 @@ The versions before 1.0 follow the pre-release convention: **a breaking change
|
|
|
8
8
|
or new public API bumps the minor**, and the patch is for fixes. Anything that would break an
|
|
9
9
|
existing install is called out under **Breaking**, with what to do about it.
|
|
10
10
|
|
|
11
|
+
## 0.55.1 — 2026-09-13
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **The demo's landing page ignored the theme the host had chosen.**
|
|
16
|
+
`data-theme` was written by an effect inside `ChatExperience`, which is the
|
|
17
|
+
chat — and the landing page stands in front of it. A site that had decided
|
|
18
|
+
this page is read in light got a dark landing page and a light conversation,
|
|
19
|
+
changing colour under the reader at the press of a button.
|
|
20
|
+
|
|
21
|
+
The effect is `useThemeAttribute` now and both callers use it. `undefined`
|
|
22
|
+
and `null` stop meaning the same thing, which is what keeps two callers from
|
|
23
|
+
fighting over one attribute: `null` is "nobody has chosen", so the attribute
|
|
24
|
+
comes off and the kit follows `prefers-color-scheme`; `undefined` is "not
|
|
25
|
+
mine to say", which is how a caller opts out of a hook that cannot be called
|
|
26
|
+
conditionally.
|
|
27
|
+
|
|
28
|
+
## 0.55.0 — 2026-09-13
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- **`ChatExperience` — the whole thing, assembled.** Every other export here is
|
|
33
|
+
a piece: a header, a scroll container, a turn, a pane. Putting them together
|
|
34
|
+
was a page's job right up until two pages did it, and then it was a copy.
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
<ChatExperience onSend={ask} title="Chat" placeholder="Ask anything…" />
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
It holds a sent turn at the top while its answer is written and lets go when
|
|
41
|
+
it settles; titles the header from the first question actually asked rather
|
|
42
|
+
than from the first keystroke; places the artifact pane *beside* the
|
|
43
|
+
conversation rather than inside it, which is the difference between a pane
|
|
44
|
+
and a modal; announces a full context window once, through the kit's own live
|
|
45
|
+
region rather than a second one; and asks whether there is a pointer before
|
|
46
|
+
drawing a cursor for it. A host gives it content and identity — `onSend`, the
|
|
47
|
+
copy, what is in the pane, where "back" goes.
|
|
48
|
+
|
|
49
|
+
The pieces are all still exported. Assemble them yourself when your app needs
|
|
50
|
+
a shape this one does not have.
|
|
51
|
+
|
|
52
|
+
- **`inline-chat-kit/demo`** — the scripted showcase behind its own entry
|
|
53
|
+
point: the landing page, the banner, and the particle-physics answers. An app
|
|
54
|
+
that never imports it never carries a line of it; the library entry is 1.8 kB
|
|
55
|
+
and the demo is 22.
|
|
56
|
+
|
|
57
|
+
### Fixed
|
|
58
|
+
|
|
59
|
+
- **Two variables the kit expected a host to define.** The chat stylesheet said
|
|
60
|
+
`var(--bg)` and the landing page said `--color-bg-page`, `--font-geist-sans`
|
|
61
|
+
and `--font-jetbrains-mono` — none of which this package ships. They rendered
|
|
62
|
+
correctly in a host that happened to have them and silently wrong in one that
|
|
63
|
+
did not: a header see-through over a scrolling answer, and an intro in serif
|
|
64
|
+
on a white page. All of it is on `--ick-` tokens now.
|
|
65
|
+
|
|
66
|
+
### Internal
|
|
67
|
+
|
|
68
|
+
- **The fork that caused the last three bug reports is gone.** Two apps each
|
|
69
|
+
kept their own copy of the assembly — 865 lines and 890, ~90% identical —
|
|
70
|
+
along with 537 byte-identical lines of scripted answers and two stylesheets.
|
|
71
|
+
Every fix went into one of them.
|
|
72
|
+
|
|
73
|
+
- **`noForks.test.ts`** measures it from now on: any file under `apps/` sharing
|
|
74
|
+
more than half its substantial lines with a file in the kit fails, naming
|
|
75
|
+
both files and the share. Comments are stripped so a quotation is not a fork,
|
|
76
|
+
and whitespace is normalised so a reformat is not a defence. Watched failing
|
|
77
|
+
before it was trusted — a planted copy reports `100% (327 of 327 lines)`.
|
|
78
|
+
|
|
79
|
+
- The getting-started example is now the one-liner, compiled on every build and
|
|
80
|
+
quoted into the page character for character, as before.
|
|
81
|
+
|
|
11
82
|
## 0.54.3 — 2026-09-13
|
|
12
83
|
|
|
13
84
|
### Fixed
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ChatHeaderAction } from '../ChatHeader/ChatHeader';
|
|
3
|
+
import { ReplyThreadPopupProps } from '../ReplyThreadPopup/ReplyThreadPopup';
|
|
4
|
+
import { UseChatTurnsOptions } from '../useChatTurns/useChatTurns';
|
|
5
|
+
import { FoldMotion } from '../QuestionGroup/QuestionGroup';
|
|
6
|
+
import { InlineAnimConfig } from '../ChatInput/ChatInput';
|
|
7
|
+
import { TranscribeHandler } from '../voice/useVoiceInput';
|
|
8
|
+
import { TurnPartUpdate } from '../turnParts/turnParts';
|
|
9
|
+
import { Answer } from '../QuestionCard/types';
|
|
10
|
+
import { Decision } from '../Approval/Approval';
|
|
11
|
+
/**
|
|
12
|
+
* The whole thing, assembled.
|
|
13
|
+
*
|
|
14
|
+
* ## Why this is in the kit and not in your page
|
|
15
|
+
*
|
|
16
|
+
* Every other export here is a piece: a header, a scroll container, a turn, a
|
|
17
|
+
* pane. Putting them together is a page's job right up until two pages do it,
|
|
18
|
+
* and then it is a copy — which is exactly what happened. The playground's
|
|
19
|
+
* page and the website's page were 865 and 890 lines of ~90% identical code,
|
|
20
|
+
* along with 537 identical lines of scripted answers and 300 of stylesheet.
|
|
21
|
+
*
|
|
22
|
+
* That copy is where the last three reported faults lived. Not in the kit: in
|
|
23
|
+
* the fact that a fix went into one page and the other kept the old one. The
|
|
24
|
+
* header rendered see-through because the second copy never defined `--bg`.
|
|
25
|
+
* The empty state snapped out of existence because the second copy never got
|
|
26
|
+
* the `AnimatePresence`. The sent message stayed pinned to the top for the
|
|
27
|
+
* rest of the session because the second copy never got the released anchor.
|
|
28
|
+
*
|
|
29
|
+
* So the assembly lives here, where a fix is made once and arrives everywhere
|
|
30
|
+
* by `npm install`. What stays a host's: the answers, the copy, the artifact's
|
|
31
|
+
* contents, the logo, where "back" goes. Content and identity — the two things
|
|
32
|
+
* a library cannot know and should not guess.
|
|
33
|
+
*
|
|
34
|
+
* ## What it does that a page would have to remember to
|
|
35
|
+
*
|
|
36
|
+
* Holds the sent turn at the top while its answer is written and lets go when
|
|
37
|
+
* it settles. Keeps a title from the first question actually asked rather than
|
|
38
|
+
* from the first keystroke. Announces a full context window once, through the
|
|
39
|
+
* kit's own live region rather than a second one. Places the artifact pane
|
|
40
|
+
* *beside* the conversation rather than inside it, which is the difference
|
|
41
|
+
* between a pane and a modal. Asks whether there is a pointer before drawing a
|
|
42
|
+
* cursor for it.
|
|
43
|
+
*/
|
|
44
|
+
/** The opening block, before anybody has asked anything. */
|
|
45
|
+
export interface ChatExperienceEmpty {
|
|
46
|
+
title: string;
|
|
47
|
+
description?: string;
|
|
48
|
+
/** One opener per branch of your `onSend`, ideally: everything the kit can
|
|
49
|
+
draw becomes reachable by pressing something rather than by knowing what
|
|
50
|
+
to type. Sent, not typed into the box — an opener that only fills the
|
|
51
|
+
input asks somebody to press send on a sentence they did not write. */
|
|
52
|
+
suggestions?: string[];
|
|
53
|
+
}
|
|
54
|
+
/** What the pane shows while an artifact is open. The kit draws the pane; what
|
|
55
|
+
is inside it is the host's, which is why this returns children. */
|
|
56
|
+
export interface ChatExperienceArtifact {
|
|
57
|
+
title: string;
|
|
58
|
+
meta?: string;
|
|
59
|
+
children: ReactNode;
|
|
60
|
+
}
|
|
61
|
+
/** A part the host drives, handed the writer for the turn it belongs to. */
|
|
62
|
+
export type PartWriter = (turnId: string, part: TurnPartUpdate) => void;
|
|
63
|
+
export interface ChatExperienceProps {
|
|
64
|
+
/** Where answers come from. Return a string, a promise of one, or an async
|
|
65
|
+
iterable of deltas — see `useChatTurns`. */
|
|
66
|
+
onSend: UseChatTurnsOptions["onSend"];
|
|
67
|
+
/** Speech to text. The kit records; the host transcribes. Omit and the
|
|
68
|
+
microphone does not appear. */
|
|
69
|
+
onTranscribe?: TranscribeHandler;
|
|
70
|
+
/** A follow-up asked on a passage. Omit and replying in a thread is off. */
|
|
71
|
+
onThreadReply?: ReplyThreadPopupProps["onSendMessage"];
|
|
72
|
+
/** Shown in the header until a question has actually been asked. */
|
|
73
|
+
title?: string;
|
|
74
|
+
/** Where the back control goes. */
|
|
75
|
+
backHref?: string;
|
|
76
|
+
backLabel?: string;
|
|
77
|
+
/** Extra header actions, added after the ones this manages. */
|
|
78
|
+
actions?: ChatHeaderAction[];
|
|
79
|
+
placeholder?: string;
|
|
80
|
+
empty?: ChatExperienceEmpty;
|
|
81
|
+
/** The context meter. Leave `contextTotal` off and there is no meter. A real
|
|
82
|
+
app reads this off its API's usage; a demo can count it off the text. */
|
|
83
|
+
contextTotal?: number;
|
|
84
|
+
/** What a system prompt and the tool definitions cost before anybody types. */
|
|
85
|
+
contextBase?: number;
|
|
86
|
+
/** The pane beside the conversation, asked for the artifact that is open. */
|
|
87
|
+
artifact?: (openId: string) => ChatExperienceArtifact | null;
|
|
88
|
+
/** The theme, if the host keeps it. Left off, this manages its own and puts
|
|
89
|
+
a toggle in the header; `data-theme` on the root element either way, and
|
|
90
|
+
unset until somebody chooses, so the kit follows the system preference —
|
|
91
|
+
which is what it is there for. */
|
|
92
|
+
theme?: "light" | "dark" | null;
|
|
93
|
+
onThemeChange?: (theme: "light" | "dark") => void;
|
|
94
|
+
/** The pointer-following cursor, and the rule that hides the real one. Only
|
|
95
|
+
ever where there is a pointer to replace. */
|
|
96
|
+
cursor?: boolean;
|
|
97
|
+
/** The freeform-marker / precise-selection pair in the header. */
|
|
98
|
+
selectionToggle?: boolean;
|
|
99
|
+
/** How far below the top edge a sent message comes to rest. Sets the
|
|
100
|
+
conversation's own top padding too — the two have to agree, so one number
|
|
101
|
+
writes both. */
|
|
102
|
+
anchorOffset?: number;
|
|
103
|
+
/** Room left under the composer once an answer settles. */
|
|
104
|
+
endOffset?: number;
|
|
105
|
+
/** Motion, opened up so a tuning panel can reach it. */
|
|
106
|
+
animationConfig?: InlineAnimConfig;
|
|
107
|
+
foldMotion?: FoldMotion;
|
|
108
|
+
/** How long the feed waits before its first row arrives. */
|
|
109
|
+
feedDelay?: number;
|
|
110
|
+
onAnswerQuestion?: (write: PartWriter, turnId: string, partId: string, questionId: string, answer: Answer) => void;
|
|
111
|
+
onEditQuestion?: (write: PartWriter, turnId: string, partId: string, index: number) => void;
|
|
112
|
+
onDecideApproval?: (write: PartWriter, turnId: string, partId: string, decision: Decision) => void;
|
|
113
|
+
className?: string;
|
|
114
|
+
}
|
|
115
|
+
export declare function ChatExperience({ onSend, onTranscribe, onThreadReply, title, backHref, backLabel, actions, placeholder, empty, contextTotal, contextBase, artifact, theme: themeProp, onThemeChange, cursor, selectionToggle, anchorOffset, endOffset, animationConfig, foldMotion, feedDelay, onAnswerQuestion, onEditQuestion, onDecideApproval, className, }: ChatExperienceProps): import("react").JSX.Element;
|