@consciousclouds/operator-shell 0.1.0 → 0.2.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 +66 -0
- package/README.md +80 -31
- package/dist/chief/ChiefDrawer.d.ts +34 -2
- package/dist/chief/ChiefDrawer.d.ts.map +1 -1
- package/dist/chief/ChiefDrawer.js +43 -30
- package/dist/chief/ChiefDrawer.js.map +1 -1
- package/dist/chief/ChiefHeaderBar.d.ts +19 -0
- package/dist/chief/ChiefHeaderBar.d.ts.map +1 -0
- package/dist/chief/ChiefHeaderBar.js +7 -0
- package/dist/chief/ChiefHeaderBar.js.map +1 -0
- package/dist/chief/ChiefMarkdown.d.ts +12 -0
- package/dist/chief/ChiefMarkdown.d.ts.map +1 -0
- package/dist/chief/ChiefMarkdown.js +95 -0
- package/dist/chief/ChiefMarkdown.js.map +1 -0
- package/dist/chief/ChiefPanel.d.ts +44 -1
- package/dist/chief/ChiefPanel.d.ts.map +1 -1
- package/dist/chief/ChiefPanel.js +79 -29
- package/dist/chief/ChiefPanel.js.map +1 -1
- package/dist/chief/ChiefRegion.d.ts +44 -1
- package/dist/chief/ChiefRegion.d.ts.map +1 -1
- package/dist/chief/ChiefRegion.js +63 -27
- package/dist/chief/ChiefRegion.js.map +1 -1
- package/dist/chief/ChiefSession.d.ts +46 -10
- package/dist/chief/ChiefSession.d.ts.map +1 -1
- package/dist/chief/ChiefSession.js +252 -6
- package/dist/chief/ChiefSession.js.map +1 -1
- package/dist/chief/ChiefTrigger.d.ts +26 -0
- package/dist/chief/ChiefTrigger.d.ts.map +1 -0
- package/dist/chief/ChiefTrigger.js +21 -0
- package/dist/chief/ChiefTrigger.js.map +1 -0
- package/dist/chief/conversation-adapter.d.ts +70 -0
- package/dist/chief/conversation-adapter.d.ts.map +1 -0
- package/dist/chief/conversation-adapter.js +26 -0
- package/dist/chief/conversation-adapter.js.map +1 -0
- package/dist/chief/conversation-identity.d.ts +48 -0
- package/dist/chief/conversation-identity.d.ts.map +1 -0
- package/dist/chief/conversation-identity.js +100 -0
- package/dist/chief/conversation-identity.js.map +1 -0
- package/dist/chief/personality-display.d.ts +56 -0
- package/dist/chief/personality-display.d.ts.map +1 -0
- package/dist/chief/personality-display.js +52 -0
- package/dist/chief/personality-display.js.map +1 -0
- package/dist/chief/turn-adapter.d.ts +45 -0
- package/dist/chief/turn-adapter.d.ts.map +1 -1
- package/dist/chief/use-chief-turn.d.ts +127 -14
- package/dist/chief/use-chief-turn.d.ts.map +1 -1
- package/dist/chief/use-chief-turn.js +284 -28
- package/dist/chief/use-chief-turn.js.map +1 -1
- package/dist/chief/use-controlled-open.d.ts +2 -0
- package/dist/chief/use-controlled-open.d.ts.map +1 -0
- package/dist/chief/use-controlled-open.js +27 -0
- package/dist/chief/use-controlled-open.js.map +1 -0
- package/dist/chief/use-smooth-stream.d.ts +8 -0
- package/dist/chief/use-smooth-stream.d.ts.map +1 -0
- package/dist/chief/use-smooth-stream.js +128 -0
- package/dist/chief/use-smooth-stream.js.map +1 -0
- package/dist/flavor/types.d.ts +36 -21
- package/dist/flavor/types.d.ts.map +1 -1
- package/dist/frame/ComposedWorkspace.d.ts +39 -0
- package/dist/frame/ComposedWorkspace.d.ts.map +1 -0
- package/dist/frame/ComposedWorkspace.js +94 -0
- package/dist/frame/ComposedWorkspace.js.map +1 -0
- package/dist/frame/OperatorShell.d.ts +115 -13
- package/dist/frame/OperatorShell.d.ts.map +1 -1
- package/dist/frame/OperatorShell.js +200 -12
- package/dist/frame/OperatorShell.js.map +1 -1
- package/dist/guard/permissions.d.ts +2 -2
- package/dist/guard/permissions.js +2 -2
- package/dist/header/OperatorHeader.d.ts +15 -2
- package/dist/header/OperatorHeader.d.ts.map +1 -1
- package/dist/header/OperatorHeader.js +3 -3
- package/dist/header/OperatorHeader.js.map +1 -1
- package/dist/icons/registry.d.ts +7 -1
- package/dist/icons/registry.d.ts.map +1 -1
- package/dist/icons/registry.js +31 -2
- package/dist/icons/registry.js.map +1 -1
- package/dist/index.d.ts +24 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +43 -17
- package/dist/index.js.map +1 -1
- package/dist/sidebar/OperatorSidebar.d.ts +16 -1
- package/dist/sidebar/OperatorSidebar.d.ts.map +1 -1
- package/dist/sidebar/OperatorSidebar.js +13 -10
- package/dist/sidebar/OperatorSidebar.js.map +1 -1
- package/dist/workspace/FormWorkspace.d.ts +2 -3
- package/dist/workspace/FormWorkspace.d.ts.map +1 -1
- package/dist/workspace/FormWorkspace.js.map +1 -1
- package/dist/workspace/session-adapter.d.ts +95 -0
- package/dist/workspace/session-adapter.d.ts.map +1 -0
- package/dist/workspace/session-adapter.js +29 -0
- package/dist/workspace/session-adapter.js.map +1 -0
- package/package.json +10 -5
- package/styles/source.css +9 -0
|
@@ -1,9 +1,255 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* ChiefSession — the AI Region's shared BODY: the empty state (hint card +
|
|
5
|
+
* suggestion chips), the thread (question · streamed markdown answer ·
|
|
6
|
+
* color-coded metadata bar), and the pill composer, rendered from a
|
|
7
|
+
* ChiefTurnSession. Pure presentation of the one turn flow — every placement
|
|
8
|
+
* (rail, push, overlay) mounts this same column inside its own chrome, so
|
|
9
|
+
* moving Chief never forks its behavior or its look.
|
|
10
|
+
*
|
|
11
|
+
* Suggestion chips are inert Flavor strings (`flavor.chief.suggestions`);
|
|
12
|
+
* clicking one submits its text through `submitPrompt` — the SAME entry the
|
|
13
|
+
* composer uses, so a chip is a canned question, never a second code path.
|
|
14
|
+
*
|
|
15
|
+
* `composerRef` exposes the composer input to the mounting placement — ⌘J
|
|
16
|
+
* focus on the rail, focus-on-open in the dismissible placements;
|
|
17
|
+
* presentation only, no behavior lives here.
|
|
18
|
+
*
|
|
19
|
+
* MOTION (presentation only — the turn STATE and the adapter are untouched):
|
|
20
|
+
* the conversation is animated with the ConsciousClouds motion vocabulary
|
|
21
|
+
* (`@consciousclouds/tokens`' `motionTokens` — durations/curves/offsets, no
|
|
22
|
+
* inline magic numbers) through `motion/react`. The empty-state hint rises in
|
|
23
|
+
* and the suggestion chips STAGGER in gently; when the first turn starts the
|
|
24
|
+
* thread rises in (empty → active); inside the thread the "thinking…" state
|
|
25
|
+
* and the answer CROSSFADE (the leaving one lifts out as an absolute overlay,
|
|
26
|
+
* so nothing reflows) and the answer SETTLES to full size the instant
|
|
27
|
+
* streaming completes; the status line eases in. The token stream itself is
|
|
28
|
+
* never animated per-character (that fights the stream) — only the CONTAINER
|
|
29
|
+
* and the turn state are. Every gesture respects `prefers-reduced-motion`
|
|
30
|
+
* (`useReducedMotion`): reduced → instant, no transform, no fade.
|
|
31
|
+
*/
|
|
32
|
+
import * as React from "react";
|
|
33
|
+
import { ArrowRight, Loader2, Sparkles } from "lucide-react";
|
|
34
|
+
import { AnimatePresence, motion } from "motion/react";
|
|
35
|
+
import { motionTokens } from "@consciousclouds/tokens";
|
|
36
|
+
import { Button, cn, useReducedMotion } from "@consciousclouds/ui";
|
|
37
|
+
import { ChiefMarkdown } from "./ChiefMarkdown.js";
|
|
38
|
+
import { useSmoothStream } from "./use-smooth-stream.js";
|
|
39
|
+
/**
|
|
40
|
+
* The stream-settle amplitude: while a turn streams, the answer bubble sits a
|
|
41
|
+
* hair under full size and eases to `1` the moment the stream completes (busy
|
|
42
|
+
* → done) — a sub-perceptual "lock-in". An amplitude only; the timing and
|
|
43
|
+
* curve of the settle come from the motion tokens (`duration.base` /
|
|
44
|
+
* `easing.standard`), never inlined.
|
|
45
|
+
*/
|
|
46
|
+
const STREAM_SETTLE_SCALE = 0.995;
|
|
47
|
+
/** The metadata bar's color coding, shared by settled and live turns. */
|
|
48
|
+
function metaClasses(kind) {
|
|
49
|
+
return cn("rounded-md border px-3 py-2 text-xs", kind === "routed" && "border-primary/5 bg-primary/5 text-primary", kind === "unavailable" && "border-border bg-muted/40 text-muted-foreground", kind === "error" &&
|
|
50
|
+
"border-destructive/30 bg-destructive/5 text-destructive");
|
|
51
|
+
}
|
|
52
|
+
/** Compact relative recency for a thread row ("just now" · "5m" · "3h" · "2d"). */
|
|
53
|
+
function relativeRecency(iso) {
|
|
54
|
+
if (!iso)
|
|
55
|
+
return "";
|
|
56
|
+
const then = Date.parse(iso);
|
|
57
|
+
if (Number.isNaN(then))
|
|
58
|
+
return "";
|
|
59
|
+
const mins = Math.max(0, Math.round((Date.now() - then) / 60000));
|
|
60
|
+
if (mins < 1)
|
|
61
|
+
return "just now";
|
|
62
|
+
if (mins < 60)
|
|
63
|
+
return `${mins}m`;
|
|
64
|
+
const hours = Math.round(mins / 60);
|
|
65
|
+
if (hours < 24)
|
|
66
|
+
return `${hours}h`;
|
|
67
|
+
return `${Math.round(hours / 24)}d`;
|
|
68
|
+
}
|
|
69
|
+
/** The shared row style for the list tabs (Conversations / Workspaces). */
|
|
70
|
+
const listRowClasses = "w-full rounded-md border border-border/60 px-3 py-2 text-left text-[13px] text-foreground/80 transition-colors hover:bg-background/60 hover:text-foreground";
|
|
71
|
+
export function ChiefSession({ session, composerRef, accentColor, workspaces, className, }) {
|
|
72
|
+
const { title, placeholder, hint, hintExample, suggestions, cmd, setCmd, busy, turns, question, answer, meta, showThread, submit, submitPrompt, transcriptEnabled, conversations, activeConversationId, openConversation, newConversation, } = session;
|
|
73
|
+
// The drawer's view tabs. Rendered only when a beyond-the-thread surface exists
|
|
74
|
+
// (a transcript adapter and/or a workspaces region) — without either, the body
|
|
75
|
+
// is exactly the pre-tab thread column (fail-closed slots, zero change).
|
|
76
|
+
const [tab, setTab] = React.useState("conversation");
|
|
77
|
+
const showTabs = transcriptEnabled || Boolean(workspaces);
|
|
78
|
+
const activeTab = showTabs ? tab : "conversation";
|
|
79
|
+
// The composer stays visible on every tab (speaking is always one keystroke
|
|
80
|
+
// away), so submitting RETURNS to the Conversation tab — the answer must
|
|
81
|
+
// stream where the operator can see it, never into the hidden pane.
|
|
82
|
+
const submitAndShowThread = React.useCallback(async (e) => {
|
|
83
|
+
setTab("conversation");
|
|
84
|
+
await submit(e);
|
|
85
|
+
}, [submit]);
|
|
86
|
+
// The accessibility contract: reduced → every preset below is a no-op, so
|
|
87
|
+
// the render is instant (no transform, no fade). Defaults to reduced before
|
|
88
|
+
// hydration, so first paint never animates (the shared hook's safe default).
|
|
89
|
+
const reduced = useReducedMotion();
|
|
90
|
+
// Smooth streaming: the answer flows onto the screen at a paced, adaptive
|
|
91
|
+
// rate instead of chunking with the network's bursty deltas (the technique
|
|
92
|
+
// every polished chat UI uses). `displayed` is a catching-up prefix of the
|
|
93
|
+
// received `answer` (the LIVE — last — turn's; settled turns render their
|
|
94
|
+
// final text directly); `revealing` is true while it's still draining (the
|
|
95
|
+
// cursor rides + the bubble stays settled until the reveal finishes). Reduced
|
|
96
|
+
// motion → `displayed === answer` (the full answer paints at once).
|
|
97
|
+
const displayed = useSmoothStream(answer, { streaming: busy, reduced });
|
|
98
|
+
const revealing = displayed.length < answer.length;
|
|
99
|
+
// The settled thread — every exchange but the live one; those render their
|
|
100
|
+
// final text with no stream motion (they already animated when they were live).
|
|
101
|
+
const settled = turns.slice(0, -1);
|
|
102
|
+
// The live entry's render key — keys the live block so a NEW turn REPLACES it
|
|
103
|
+
// outright instead of crossfading out of it (the exit ghost belonged to the
|
|
104
|
+
// pre-thread replace model; under the append model the previous answer already
|
|
105
|
+
// stands in `settled`, so an exiting duplicate would double-render it).
|
|
106
|
+
const liveKey = turns.length > 0 ? turns[turns.length - 1].key : "live";
|
|
107
|
+
// Follow the stream — but only while the operator is AT the bottom: scrolling
|
|
108
|
+
// up to re-read a settled turn must never be yanked back by the reveal ticks.
|
|
109
|
+
// Submitting a new turn re-engages the pin (you return to your question).
|
|
110
|
+
// Instant (never smooth) — animated scrolling fights the token stream.
|
|
111
|
+
const scrollRef = React.useRef(null);
|
|
112
|
+
const stickRef = React.useRef(true);
|
|
113
|
+
const onThreadScroll = React.useCallback(() => {
|
|
114
|
+
const el = scrollRef.current;
|
|
115
|
+
if (el)
|
|
116
|
+
stickRef.current = el.scrollHeight - el.scrollTop - el.clientHeight < 48;
|
|
117
|
+
}, []);
|
|
118
|
+
React.useEffect(() => {
|
|
119
|
+
stickRef.current = true; // a new exchange re-engages follow (declared BEFORE the pin effect)
|
|
120
|
+
}, [turns.length]);
|
|
121
|
+
React.useEffect(() => {
|
|
122
|
+
// Returning to the thread re-engages follow and pins to the newest content:
|
|
123
|
+
// while the pane was display:none every pin was a spec no-op (no layout box),
|
|
124
|
+
// and the browser may fire a restoration scroll that would clear the stick —
|
|
125
|
+
// re-entering the tab means "show me the conversation now", so land at the end.
|
|
126
|
+
if (activeTab !== "conversation")
|
|
127
|
+
return;
|
|
128
|
+
stickRef.current = true;
|
|
129
|
+
const el = scrollRef.current;
|
|
130
|
+
if (el)
|
|
131
|
+
el.scrollTop = el.scrollHeight;
|
|
132
|
+
}, [activeTab]);
|
|
133
|
+
React.useEffect(() => {
|
|
134
|
+
const el = scrollRef.current;
|
|
135
|
+
if (el && stickRef.current)
|
|
136
|
+
el.scrollTop = el.scrollHeight;
|
|
137
|
+
}, [turns.length, displayed, busy]);
|
|
138
|
+
// The motion vocabulary — durations/curves/offsets from the tokens only.
|
|
139
|
+
const enterY = motionTokens.offset.enter.y;
|
|
140
|
+
const exitY = motionTokens.offset.exit.y;
|
|
141
|
+
const base = {
|
|
142
|
+
duration: motionTokens.duration.base,
|
|
143
|
+
ease: motionTokens.easing.standard,
|
|
144
|
+
};
|
|
145
|
+
const fast = {
|
|
146
|
+
duration: motionTokens.duration.fast,
|
|
147
|
+
ease: motionTokens.easing.standard,
|
|
148
|
+
};
|
|
149
|
+
// Empty state — the idle hint rises in; the chips stagger in one `fast` step
|
|
150
|
+
// apart (the harvested SDK ships no stagger, so this minimal, token-timed
|
|
151
|
+
// cascade lives here; see the return summary).
|
|
152
|
+
const hintMotion = reduced
|
|
153
|
+
? {}
|
|
154
|
+
: {
|
|
155
|
+
initial: { opacity: 0, y: enterY },
|
|
156
|
+
animate: { opacity: 1, y: 0 },
|
|
157
|
+
transition: base,
|
|
158
|
+
};
|
|
159
|
+
const chipsListMotion = reduced
|
|
160
|
+
? {}
|
|
161
|
+
: {
|
|
162
|
+
initial: "hidden",
|
|
163
|
+
animate: "show",
|
|
164
|
+
variants: {
|
|
165
|
+
hidden: {},
|
|
166
|
+
show: { transition: { staggerChildren: motionTokens.duration.fast } },
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
const chipMotion = reduced
|
|
170
|
+
? {}
|
|
171
|
+
: {
|
|
172
|
+
variants: {
|
|
173
|
+
hidden: { opacity: 0, y: enterY },
|
|
174
|
+
show: { opacity: 1, y: 0, transition: base },
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
// Thread — the whole thread rises in when the first turn starts (empty →
|
|
178
|
+
// active). Inside it the thinking indicator and the answer crossfade: the
|
|
179
|
+
// leaving one lifts out (exit offset) as an ABSOLUTE overlay (the `relative`
|
|
180
|
+
// wrapper anchors it) so the answer rises into place with no reflow; the
|
|
181
|
+
// answer settles to full size when streaming ends; the status line eases in.
|
|
182
|
+
const threadMotion = reduced
|
|
183
|
+
? {}
|
|
184
|
+
: {
|
|
185
|
+
initial: { opacity: 0, y: enterY },
|
|
186
|
+
animate: { opacity: 1, y: 0 },
|
|
187
|
+
transition: base,
|
|
188
|
+
};
|
|
189
|
+
const answerMotion = reduced
|
|
190
|
+
? {}
|
|
191
|
+
: {
|
|
192
|
+
initial: { opacity: 0, y: enterY },
|
|
193
|
+
animate: {
|
|
194
|
+
opacity: 1,
|
|
195
|
+
y: 0,
|
|
196
|
+
scale: busy || revealing ? STREAM_SETTLE_SCALE : 1,
|
|
197
|
+
},
|
|
198
|
+
exit: { opacity: 0, y: exitY, position: "absolute" },
|
|
199
|
+
transition: base,
|
|
200
|
+
};
|
|
201
|
+
const thinkingMotion = reduced
|
|
202
|
+
? {}
|
|
203
|
+
: {
|
|
204
|
+
initial: { opacity: 0, y: enterY },
|
|
205
|
+
animate: { opacity: 1, y: 0 },
|
|
206
|
+
exit: { opacity: 0, y: exitY, position: "absolute" },
|
|
207
|
+
transition: fast,
|
|
208
|
+
};
|
|
209
|
+
const metaMotion = reduced
|
|
210
|
+
? {}
|
|
211
|
+
: {
|
|
212
|
+
initial: { opacity: 0, y: enterY },
|
|
213
|
+
animate: { opacity: 1, y: 0 },
|
|
214
|
+
transition: base,
|
|
215
|
+
};
|
|
216
|
+
return (_jsxs("div", { className: cn("flex min-h-0 flex-1 flex-col", className), children: [showTabs && (_jsx("div", { role: "tablist", "aria-label": `${title} views`, className: "flex shrink-0 items-center gap-1 border-b border-border/50 px-3 py-2", children: [
|
|
217
|
+
{
|
|
218
|
+
key: "conversation",
|
|
219
|
+
label: "Conversation",
|
|
220
|
+
present: true,
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
key: "conversations",
|
|
224
|
+
label: "Conversations",
|
|
225
|
+
present: transcriptEnabled,
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
key: "workspaces",
|
|
229
|
+
label: "Workspaces",
|
|
230
|
+
present: Boolean(workspaces),
|
|
231
|
+
},
|
|
232
|
+
]
|
|
233
|
+
.filter((t) => t.present)
|
|
234
|
+
.map((t) => (_jsx("button", { type: "button", role: "tab", "aria-selected": activeTab === t.key, onClick: () => setTab(t.key), className: cn("rounded-md px-2.5 py-1 text-xs font-medium transition-colors", activeTab === t.key
|
|
235
|
+
? "bg-background/80 text-foreground"
|
|
236
|
+
: "text-muted-foreground hover:bg-background/50 hover:text-foreground"), children: t.label }, t.key))) })), activeTab === "conversations" && (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-1.5 overflow-y-auto p-4", role: "tabpanel", children: [_jsx("button", { type: "button", onClick: () => {
|
|
237
|
+
newConversation();
|
|
238
|
+
setTab("conversation");
|
|
239
|
+
}, className: cn(listRowClasses, "border-dashed text-center font-medium"), children: "+ New conversation" }), conversations.length === 0 ? (_jsxs("p", { className: "px-1 pt-2 text-xs text-muted-foreground", children: ["No conversations yet \u2014 ask ", title, " something and the thread becomes durable."] })) : (conversations.map((c) => {
|
|
240
|
+
const active = c.conversationId === activeConversationId;
|
|
241
|
+
return (_jsxs("button", { type: "button", onClick: () => {
|
|
242
|
+
openConversation(c.conversationId);
|
|
243
|
+
setTab("conversation");
|
|
244
|
+
}, className: cn(listRowClasses, active && "border-primary/30 bg-primary/5"), children: [_jsxs("span", { className: "block truncate font-medium text-foreground/90", children: ["Conversation ", c.conversationId.slice(0, 8), active ? " · active" : ""] }), _jsxs("span", { className: "block text-xs text-muted-foreground", children: [typeof c.records === "number"
|
|
245
|
+
? `${c.records} messages`
|
|
246
|
+
: "—", c.lastActivity
|
|
247
|
+
? ` · ${relativeRecency(c.lastActivity)}`
|
|
248
|
+
: ""] })] }, c.conversationId));
|
|
249
|
+
}))] })), activeTab === "workspaces" && workspaces && (_jsx("div", { className: "flex min-h-0 flex-1 flex-col gap-1.5 overflow-y-auto p-4", role: "tabpanel", children: workspaces.items.length === 0 ? (_jsx("p", { className: "px-1 pt-2 text-xs text-muted-foreground", children: "No kept workspaces yet \u2014 compose one and keep it by name." })) : (workspaces.items.map((w) => (_jsx("button", { type: "button", onClick: () => {
|
|
250
|
+
workspaces.onOpen(w.workspaceId);
|
|
251
|
+
setTab("conversation");
|
|
252
|
+
}, className: cn(listRowClasses, w.workspaceId === workspaces.activeId &&
|
|
253
|
+
"border-primary/30 bg-primary/5"), children: _jsx("span", { className: "block truncate", children: w.name }) }, w.workspaceId)))) })), _jsxs("div", { ref: scrollRef, onScroll: onThreadScroll, className: cn("flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-4", activeTab !== "conversation" && "hidden"), children: [!showThread && (_jsxs(_Fragment, { children: [_jsx(motion.div, { ...hintMotion, className: "rounded-lg bg-background/60 p-3", children: _jsxs("p", { className: "text-[13px] leading-relaxed text-foreground/80", children: [hint, hintExample ? (_jsxs(_Fragment, { children: [" ", "(", _jsx("span", { className: "font-medium text-foreground", children: hintExample }), ")"] })) : null, ". Some commands move the surface directly, with zero model tokens."] }) }), suggestions.length > 0 && (_jsx(motion.div, { ...chipsListMotion, className: "flex flex-col gap-1.5", children: suggestions.map((suggestion) => (_jsx(motion.button, { ...chipMotion, type: "button", disabled: busy, onClick: () => void submitPrompt(suggestion), className: "rounded-md border border-border/60 px-3 py-2 text-left text-[13px] text-foreground/80 transition-colors hover:bg-background/60 hover:text-foreground disabled:pointer-events-none disabled:opacity-50", children: suggestion }, suggestion))) }))] })), showThread && (_jsxs(motion.div, { ...threadMotion, className: "space-y-4", children: [settled.map((t) => (_jsxs("div", { className: "space-y-3", children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground", children: t.question }), t.answer ? (_jsx("div", { className: "rounded-lg bg-background/60 px-3 py-2 text-sm leading-relaxed text-foreground", children: _jsx(ChiefMarkdown, { children: t.answer }) })) : null, t.meta ? (_jsx("div", { className: metaClasses(t.meta.kind), children: t.meta.text })) : null] }, t.key))), _jsxs("div", { className: "relative space-y-3", children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground", children: question }), _jsx(AnimatePresence, { initial: false, children: displayed ? (_jsx(motion.div, { ...answerMotion, className: "rounded-lg bg-background/60 px-3 py-2 text-sm leading-relaxed text-foreground", children: _jsx(ChiefMarkdown, { streaming: busy || revealing, wordFade: busy || revealing, children: displayed }) }, "answer")) : busy ? (_jsxs(motion.div, { ...thinkingMotion, className: "flex items-center gap-2 text-xs text-muted-foreground", children: [_jsx(Loader2, { className: "size-3.5 animate-spin" }), " ", title, " is thinking\u2026"] }, "thinking")) : null }), _jsx(AnimatePresence, { initial: false, children: meta && (_jsx(motion.div, { ...metaMotion, className: metaClasses(meta.kind), children: meta.text }, meta.kind)) })] }, liveKey)] }))] }), _jsx("form", { onSubmit: submitAndShowThread, className: "shrink-0 border-t border-border/50 p-3", children: _jsxs("div", { className: "flex items-center gap-2 rounded-full bg-background/60 px-3 py-2 focus-within:ring-1 focus-within:ring-ring/40", children: [_jsx(Sparkles, { "aria-hidden": true, className: "size-3.5 shrink-0 text-muted-foreground", style: accentColor ? { color: accentColor } : undefined }), _jsx("input", { ref: composerRef, value: cmd, onChange: (e) => setCmd(e.target.value), placeholder: placeholder, className: "min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground", "aria-label": `Command ${title}` }), _jsx(Button, { type: "submit", variant: "ghost", size: "icon-xs", disabled: busy || !cmd.trim(), className: "rounded-full text-primary hover:text-primary", "aria-label": "Send", children: busy ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : (_jsx(ArrowRight, { className: "size-4" })) })] }) })] }));
|
|
8
254
|
}
|
|
9
255
|
//# sourceMappingURL=ChiefSession.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChiefSession.js","sourceRoot":"","sources":["../../src/chief/ChiefSession.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAeb,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAWjD,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAqB;IACjF,MAAM,EACJ,KAAK,EACL,WAAW,EACX,IAAI,EACJ,WAAW,EACX,GAAG,EACH,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,UAAU,EACV,MAAM,GACP,GAAG,OAAO,CAAC;IAEZ,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,8BAA8B,EAAE,SAAS,CAAC,aAC3D,eAAK,SAAS,EAAC,wDAAwD,aACpE,CAAC,UAAU,IAAI,CACd,aAAG,SAAS,EAAC,kCAAkC,aAC5C,IAAI,EACJ,WAAW,CAAC,CAAC,CAAC,CACb,8BACG,GAAG,OACH,eAAM,SAAS,EAAC,gCAAgC,YAAE,WAAW,GAAQ,SACrE,CACJ,CAAC,CAAC,CAAC,IAAI,0EAEN,CACL,EAEA,UAAU,IAAI,CACb,eAAK,SAAS,EAAC,WAAW,aACxB,cAAK,SAAS,EAAC,2CAA2C,YAAE,QAAQ,GAAO,EAE1E,MAAM,IAAI,CACT,eAAK,SAAS,EAAC,+GAA+G,aAC3H,MAAM,EACN,IAAI,IAAI,eAAM,SAAS,EAAC,mCAAmC,uBAAS,IACjE,CACP,EAEA,IAAI,IAAI,CAAC,MAAM,IAAI,CAClB,eAAK,SAAS,EAAC,uDAAuD,aACpE,KAAC,OAAO,IAAC,SAAS,EAAC,uBAAuB,GAAG,OAAE,KAAK,0BAChD,CACP,EAEA,IAAI,IAAI,CACP,cACE,SAAS,EAAE,EAAE,CACX,qCAAqC,EACrC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,gDAAgD,EAC1E,IAAI,CAAC,IAAI,KAAK,aAAa,IAAI,iDAAiD,EAChF,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,yDAAyD,CACnF,YAEA,IAAI,CAAC,IAAI,GACN,CACP,IACG,CACP,IACG,EAEN,eAAM,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC,qCAAqC,YACrE,eAAK,SAAS,EAAC,sHAAsH,aACnI,gBACE,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,CAAC,CAAsC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC5E,WAAW,EAAE,WAAW,EACxB,SAAS,EAAC,yFAAyF,gBACvF,WAAW,KAAK,EAAE,GAC9B,EACF,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,SAAS,EACd,QAAQ,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAC7B,SAAS,EAAC,iCAAiC,gBAChC,MAAM,YAEhB,IAAI,CAAC,CAAC,CAAC,KAAC,OAAO,IAAC,SAAS,EAAC,qBAAqB,GAAG,CAAC,CAAC,CAAC,KAAC,UAAU,IAAC,SAAS,EAAC,QAAQ,GAAG,GAChF,IACL,GACD,IACH,CACP,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"ChiefSession.js","sourceRoot":"","sources":["../../src/chief/ChiefSession.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChiefTrigger — the AI Region's header trigger: a pill button carrying the
|
|
3
|
+
* personality's icon + display name that summons/dismisses the Chief panel
|
|
4
|
+
* (the click twin of ⌘J). The frame mounts it in the header by default; a
|
|
5
|
+
* custom composition root may mount it anywhere and hand its element to the
|
|
6
|
+
* panel via `getTriggerElement` (outside-click exclusion + focus return).
|
|
7
|
+
*
|
|
8
|
+
* Icon and accent arrive RESOLVED (registry component + token-role color) —
|
|
9
|
+
* references resolve upstream, raw values never enter here.
|
|
10
|
+
*/
|
|
11
|
+
import * as React from "react";
|
|
12
|
+
import type { LucideIcon } from "lucide-react";
|
|
13
|
+
export interface ChiefTriggerProps {
|
|
14
|
+
/** The panel's current open state (drives aria-expanded + the active tint). */
|
|
15
|
+
open: boolean;
|
|
16
|
+
/** Summon/dismiss — the same open state ⌘J and the panel's dismissals drive. */
|
|
17
|
+
onToggle: () => void;
|
|
18
|
+
/** The personality display name (the D-Q2 precedence, resolved upstream). */
|
|
19
|
+
label: string;
|
|
20
|
+
icon: LucideIcon;
|
|
21
|
+
/** Composable CSS color from a token ROLE (resolvePersonalityAccent). */
|
|
22
|
+
accentColor?: string;
|
|
23
|
+
className?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare const ChiefTrigger: React.ForwardRefExoticComponent<ChiefTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
26
|
+
//# sourceMappingURL=ChiefTrigger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChiefTrigger.d.ts","sourceRoot":"","sources":["../../src/chief/ChiefTrigger.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM/C,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,IAAI,EAAE,OAAO,CAAC;IACd,gFAAgF;IAChF,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,6FA4BxB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* ChiefTrigger — the AI Region's header trigger: a pill button carrying the
|
|
5
|
+
* personality's icon + display name that summons/dismisses the Chief panel
|
|
6
|
+
* (the click twin of ⌘J). The frame mounts it in the header by default; a
|
|
7
|
+
* custom composition root may mount it anywhere and hand its element to the
|
|
8
|
+
* panel via `getTriggerElement` (outside-click exclusion + focus return).
|
|
9
|
+
*
|
|
10
|
+
* Icon and accent arrive RESOLVED (registry component + token-role color) —
|
|
11
|
+
* references resolve upstream, raw values never enter here.
|
|
12
|
+
*/
|
|
13
|
+
import * as React from "react";
|
|
14
|
+
import { cn } from "@consciousclouds/ui";
|
|
15
|
+
import { CHIEF_SHORTCUT_LABEL } from "./use-chief-shortcut.js";
|
|
16
|
+
export const ChiefTrigger = React.forwardRef(function ChiefTrigger({ open, onToggle, label, icon: Icon, accentColor, className }, ref) {
|
|
17
|
+
return (_jsxs("button", { ref: ref, type: "button", onClick: onToggle, "aria-haspopup": "dialog", "aria-expanded": open, "aria-label": `${open ? "Close" : "Open"} ${label}`, title: `${label} — ${CHIEF_SHORTCUT_LABEL}`, className: cn("flex h-8 items-center gap-1.5 rounded-full px-2.5 text-[13px] font-medium transition-colors", open
|
|
18
|
+
? "bg-primary/10 text-primary hover:bg-primary/15"
|
|
19
|
+
: "text-muted-foreground hover:bg-muted hover:text-foreground", className), children: [_jsx(Icon, { "aria-hidden": true, className: "size-3.5 shrink-0", style: accentColor ? { color: accentColor } : undefined }), _jsx("span", { className: "hidden sm:inline", children: label })] }));
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=ChiefTrigger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChiefTrigger.js","sourceRoot":"","sources":["../../src/chief/ChiefTrigger.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb;;;;;;;;;GASG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAe/D,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,CAC1C,SAAS,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,GAAG;IACtF,OAAO,CACL,kBACE,GAAG,EAAE,GAAG,EACR,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,QAAQ,mBACH,QAAQ,mBACP,IAAI,gBACP,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,EAAE,EACjD,KAAK,EAAE,GAAG,KAAK,MAAM,oBAAoB,EAAE,EAC3C,SAAS,EAAE,EAAE,CACX,6FAA6F,EAC7F,IAAI;YACF,CAAC,CAAC,gDAAgD;YAClD,CAAC,CAAC,4DAA4D,EAChE,SAAS,CACV,aAED,KAAC,IAAI,yBAEH,SAAS,EAAC,mBAAmB,EAC7B,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,GACvD,EACF,eAAM,SAAS,EAAC,kBAAkB,YAAE,KAAK,GAAQ,IAC1C,CACV,CAAC;AACJ,CAAC,CACF,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ConversationAdapter — the conversation TRANSCRIPT transport seam (Session
|
|
3
|
+
* Binder consumption slice), the read dual of TurnAdapter.
|
|
4
|
+
*
|
|
5
|
+
* THE SHELL OWNS THE THREAD; THE PRODUCT OWNS THE WIRE — the same injection
|
|
6
|
+
* contract as TurnAdapter (P1-1) and SessionAdapter. The shell ships the
|
|
7
|
+
* drawer's Conversations tab, thread hydration on restore/adoption, and the
|
|
8
|
+
* new-conversation gesture; it does NOT ship transport. The product implements
|
|
9
|
+
* and injects this adapter; its BFF routes, gateway URL, and credentials
|
|
10
|
+
* posture stay in the product. No adapter → no tabs, no hydration — the live
|
|
11
|
+
* turn flow stands alone (fail-closed slot, like every shell seam).
|
|
12
|
+
*
|
|
13
|
+
* STORAGE-AGNOSTIC BY CONTRACT (docs/design/session-binder.md, "the shell's
|
|
14
|
+
* read contract"): `listTurns` returns TURNS — {turnId, prompt, answer,
|
|
15
|
+
* outcome, composed?, createdAt} — never storage records. Whatever grammar the
|
|
16
|
+
* product's store speaks (Memory Tier-0 records, anything later), the ADAPTER
|
|
17
|
+
* folds it into turns; the shell renders turns and knows nothing of records.
|
|
18
|
+
*
|
|
19
|
+
* READS ARE GOVERNED, NEVER TRUSTED CLIENT STATE: the wire behind a real
|
|
20
|
+
* adapter re-authorizes every read (Control Plane `conversation.view` + the
|
|
21
|
+
* attested operator sub scoping rows server-side), so the adapter can only
|
|
22
|
+
* ever surface the operator's OWN transcripts. The conversation id names a
|
|
23
|
+
* thread; it is never authority.
|
|
24
|
+
*/
|
|
25
|
+
/** One thread of the operator's transcript, for the Conversations tab. */
|
|
26
|
+
export interface ConversationThreadSummary {
|
|
27
|
+
conversationId: string;
|
|
28
|
+
/** ISO timestamp of the thread's most recent record, for recency display. */
|
|
29
|
+
lastActivity?: string;
|
|
30
|
+
/** How many records the thread holds (a message ≈ half a turn). */
|
|
31
|
+
records?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The assistant record's RAW outcome, as the runtime recorded it:
|
|
35
|
+
* `routed` (deterministic navigation, carries `target`) · `error` (carries
|
|
36
|
+
* `code`) · `none`/absent (a plain answered turn).
|
|
37
|
+
*/
|
|
38
|
+
export interface ConversationTurnOutcome {
|
|
39
|
+
kind: string;
|
|
40
|
+
target?: string;
|
|
41
|
+
code?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* One TURN of a conversation, CHRONOLOGICAL (oldest first) — the locked
|
|
45
|
+
* storage-agnostic read shape (session-binder.md). `turnId` is the canonical
|
|
46
|
+
* conductor id (the durable transcript and the screen share one name).
|
|
47
|
+
*/
|
|
48
|
+
export interface ConversationTurn {
|
|
49
|
+
/** The canonical conductor turn id. */
|
|
50
|
+
turnId?: string;
|
|
51
|
+
/** The operator's question. */
|
|
52
|
+
prompt: string;
|
|
53
|
+
/** The final assistant answer (markdown; empty for a routed/failed turn). */
|
|
54
|
+
answer: string;
|
|
55
|
+
/** The turn's recorded outcome (routed target / error code / none). */
|
|
56
|
+
outcome?: ConversationTurnOutcome;
|
|
57
|
+
/** The composed-workspace marker, when the turn composed one. */
|
|
58
|
+
composed?: {
|
|
59
|
+
composer?: string;
|
|
60
|
+
intent?: string;
|
|
61
|
+
};
|
|
62
|
+
/** ISO timestamp of the turn's first record. */
|
|
63
|
+
createdAt?: string;
|
|
64
|
+
}
|
|
65
|
+
/** The injected transcript transport: list the operator's threads; read one thread as TURNS. */
|
|
66
|
+
export interface ConversationAdapter {
|
|
67
|
+
listConversations(): Promise<ConversationThreadSummary[]>;
|
|
68
|
+
listTurns(conversationId: string): Promise<ConversationTurn[]>;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=conversation-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-adapter.d.ts","sourceRoot":"","sources":["../../src/chief/conversation-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,0EAA0E;AAC1E,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAClC,iEAAiE;IACjE,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,gGAAgG;AAChG,MAAM,WAAW,mBAAmB;IAClC,iBAAiB,IAAI,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAC;IAC1D,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;CAChE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ConversationAdapter — the conversation TRANSCRIPT transport seam (Session
|
|
3
|
+
* Binder consumption slice), the read dual of TurnAdapter.
|
|
4
|
+
*
|
|
5
|
+
* THE SHELL OWNS THE THREAD; THE PRODUCT OWNS THE WIRE — the same injection
|
|
6
|
+
* contract as TurnAdapter (P1-1) and SessionAdapter. The shell ships the
|
|
7
|
+
* drawer's Conversations tab, thread hydration on restore/adoption, and the
|
|
8
|
+
* new-conversation gesture; it does NOT ship transport. The product implements
|
|
9
|
+
* and injects this adapter; its BFF routes, gateway URL, and credentials
|
|
10
|
+
* posture stay in the product. No adapter → no tabs, no hydration — the live
|
|
11
|
+
* turn flow stands alone (fail-closed slot, like every shell seam).
|
|
12
|
+
*
|
|
13
|
+
* STORAGE-AGNOSTIC BY CONTRACT (docs/design/session-binder.md, "the shell's
|
|
14
|
+
* read contract"): `listTurns` returns TURNS — {turnId, prompt, answer,
|
|
15
|
+
* outcome, composed?, createdAt} — never storage records. Whatever grammar the
|
|
16
|
+
* product's store speaks (Memory Tier-0 records, anything later), the ADAPTER
|
|
17
|
+
* folds it into turns; the shell renders turns and knows nothing of records.
|
|
18
|
+
*
|
|
19
|
+
* READS ARE GOVERNED, NEVER TRUSTED CLIENT STATE: the wire behind a real
|
|
20
|
+
* adapter re-authorizes every read (Control Plane `conversation.view` + the
|
|
21
|
+
* attested operator sub scoping rows server-side), so the adapter can only
|
|
22
|
+
* ever surface the operator's OWN transcripts. The conversation id names a
|
|
23
|
+
* thread; it is never authority.
|
|
24
|
+
*/
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=conversation-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-adapter.js","sourceRoot":"","sources":["../../src/chief/conversation-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation identity — the shell-owned MINT-OR-ADOPT seam (Session Binder
|
|
3
|
+
* slice 2a; docs/design/session-binder.md).
|
|
4
|
+
*
|
|
5
|
+
* The shell owns the conversation surface, so the shell owns the identity of
|
|
6
|
+
* the conversation it renders: ONE durable conversation id per personality,
|
|
7
|
+
* minted on first use, persisted in localStorage so a hard refresh continues
|
|
8
|
+
* the same thread, and ADOPTED (replaced) when the operator opens a kept
|
|
9
|
+
* Workspace Session that names its owning conversation — "a conversation owns
|
|
10
|
+
* a workspace" (Canvas OS §4), so opening the workspace rejoins its
|
|
11
|
+
* conversation.
|
|
12
|
+
*
|
|
13
|
+
* A CORRELATION REFERENCE ONLY — never authority. It rides the turn wire
|
|
14
|
+
* verbatim (`conversation_id`, the contract's inert thread-grouping key) and
|
|
15
|
+
* composition provenance; the conductor records turns under it, and every
|
|
16
|
+
* durable read is re-authorized server-side against the verified operator —
|
|
17
|
+
* a fabricated id can never read anyone else's thread.
|
|
18
|
+
*
|
|
19
|
+
* Storage failures (private mode, disabled storage) degrade to an EPHEMERAL
|
|
20
|
+
* per-mount id — the turn flow never breaks because persistence is unavailable.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* The storage key for a personality's conversation identity. Keyed by the
|
|
24
|
+
* Flavor's inert personality REFERENCE so distinct personalities on one origin
|
|
25
|
+
* keep distinct threads; products on their own origins are isolated anyway.
|
|
26
|
+
*/
|
|
27
|
+
export declare function conversationStorageKey(personalityRef?: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Restore the persisted conversation id, or mint-and-persist a fresh one.
|
|
30
|
+
* SSR-safe: on the server this returns "" (no conversation exists outside a
|
|
31
|
+
* browser); the client render mints/restores the real id. The id is never
|
|
32
|
+
* rendered into markup, so the difference cannot cause a hydration mismatch.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getOrMintConversationId(storageKey: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Adopt an existing conversation id (opening a kept Workspace Session rejoins
|
|
37
|
+
* the conversation that owns it): persist it and broadcast to live hooks in
|
|
38
|
+
* this tab. Empty ids are ignored — a record that predates conversation
|
|
39
|
+
* identity must not erase the current thread.
|
|
40
|
+
*/
|
|
41
|
+
export declare function adoptConversationId(storageKey: string, id: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Subscribe to conversation-identity changes for a storage key: same-tab
|
|
44
|
+
* adoptions (the custom event) and cross-tab changes (the `storage` event).
|
|
45
|
+
* Returns the unsubscribe.
|
|
46
|
+
*/
|
|
47
|
+
export declare function subscribeConversationId(storageKey: string, onChange: (id: string) => void): () => void;
|
|
48
|
+
//# sourceMappingURL=conversation-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-identity.d.ts","sourceRoot":"","sources":["../../src/chief/conversation-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAYH;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAelE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAUxE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAC7B,MAAM,IAAI,CAeZ"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation identity — the shell-owned MINT-OR-ADOPT seam (Session Binder
|
|
3
|
+
* slice 2a; docs/design/session-binder.md).
|
|
4
|
+
*
|
|
5
|
+
* The shell owns the conversation surface, so the shell owns the identity of
|
|
6
|
+
* the conversation it renders: ONE durable conversation id per personality,
|
|
7
|
+
* minted on first use, persisted in localStorage so a hard refresh continues
|
|
8
|
+
* the same thread, and ADOPTED (replaced) when the operator opens a kept
|
|
9
|
+
* Workspace Session that names its owning conversation — "a conversation owns
|
|
10
|
+
* a workspace" (Canvas OS §4), so opening the workspace rejoins its
|
|
11
|
+
* conversation.
|
|
12
|
+
*
|
|
13
|
+
* A CORRELATION REFERENCE ONLY — never authority. It rides the turn wire
|
|
14
|
+
* verbatim (`conversation_id`, the contract's inert thread-grouping key) and
|
|
15
|
+
* composition provenance; the conductor records turns under it, and every
|
|
16
|
+
* durable read is re-authorized server-side against the verified operator —
|
|
17
|
+
* a fabricated id can never read anyone else's thread.
|
|
18
|
+
*
|
|
19
|
+
* Storage failures (private mode, disabled storage) degrade to an EPHEMERAL
|
|
20
|
+
* per-mount id — the turn flow never breaks because persistence is unavailable.
|
|
21
|
+
*/
|
|
22
|
+
const STORAGE_PREFIX = "cc.chief.conversation:";
|
|
23
|
+
/** Same-tab adoption broadcast (the `storage` event only fires cross-tab). */
|
|
24
|
+
const ADOPT_EVENT = "cc:chief-conversation-adopted";
|
|
25
|
+
/**
|
|
26
|
+
* The storage key for a personality's conversation identity. Keyed by the
|
|
27
|
+
* Flavor's inert personality REFERENCE so distinct personalities on one origin
|
|
28
|
+
* keep distinct threads; products on their own origins are isolated anyway.
|
|
29
|
+
*/
|
|
30
|
+
export function conversationStorageKey(personalityRef) {
|
|
31
|
+
return `${STORAGE_PREFIX}${personalityRef ?? "default"}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Restore the persisted conversation id, or mint-and-persist a fresh one.
|
|
35
|
+
* SSR-safe: on the server this returns "" (no conversation exists outside a
|
|
36
|
+
* browser); the client render mints/restores the real id. The id is never
|
|
37
|
+
* rendered into markup, so the difference cannot cause a hydration mismatch.
|
|
38
|
+
*/
|
|
39
|
+
export function getOrMintConversationId(storageKey) {
|
|
40
|
+
if (typeof window === "undefined")
|
|
41
|
+
return "";
|
|
42
|
+
try {
|
|
43
|
+
const existing = window.localStorage.getItem(storageKey);
|
|
44
|
+
if (existing)
|
|
45
|
+
return existing;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
/* storage unavailable — fall through to an ephemeral mint */
|
|
49
|
+
}
|
|
50
|
+
const minted = crypto.randomUUID();
|
|
51
|
+
try {
|
|
52
|
+
window.localStorage.setItem(storageKey, minted);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
/* unpersisted mint: the conversation lives for this mount only */
|
|
56
|
+
}
|
|
57
|
+
return minted;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Adopt an existing conversation id (opening a kept Workspace Session rejoins
|
|
61
|
+
* the conversation that owns it): persist it and broadcast to live hooks in
|
|
62
|
+
* this tab. Empty ids are ignored — a record that predates conversation
|
|
63
|
+
* identity must not erase the current thread.
|
|
64
|
+
*/
|
|
65
|
+
export function adoptConversationId(storageKey, id) {
|
|
66
|
+
if (typeof window === "undefined" || !id)
|
|
67
|
+
return;
|
|
68
|
+
try {
|
|
69
|
+
window.localStorage.setItem(storageKey, id);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
/* adoption still applies in-memory via the broadcast below */
|
|
73
|
+
}
|
|
74
|
+
window.dispatchEvent(new CustomEvent(ADOPT_EVENT, { detail: { storageKey, id } }));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Subscribe to conversation-identity changes for a storage key: same-tab
|
|
78
|
+
* adoptions (the custom event) and cross-tab changes (the `storage` event).
|
|
79
|
+
* Returns the unsubscribe.
|
|
80
|
+
*/
|
|
81
|
+
export function subscribeConversationId(storageKey, onChange) {
|
|
82
|
+
if (typeof window === "undefined")
|
|
83
|
+
return () => { };
|
|
84
|
+
const onAdopt = (e) => {
|
|
85
|
+
const detail = e.detail;
|
|
86
|
+
if (detail?.storageKey === storageKey && detail.id)
|
|
87
|
+
onChange(detail.id);
|
|
88
|
+
};
|
|
89
|
+
const onStorage = (e) => {
|
|
90
|
+
if (e.key === storageKey && e.newValue)
|
|
91
|
+
onChange(e.newValue);
|
|
92
|
+
};
|
|
93
|
+
window.addEventListener(ADOPT_EVENT, onAdopt);
|
|
94
|
+
window.addEventListener("storage", onStorage);
|
|
95
|
+
return () => {
|
|
96
|
+
window.removeEventListener(ADOPT_EVENT, onAdopt);
|
|
97
|
+
window.removeEventListener("storage", onStorage);
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=conversation-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-identity.js","sourceRoot":"","sources":["../../src/chief/conversation-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,cAAc,GAAG,wBAAwB,CAAC;AAEhD,8EAA8E;AAC9E,MAAM,WAAW,GAAG,+BAA+B,CAAC;AAOpD;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,cAAuB;IAC5D,OAAO,GAAG,cAAc,GAAG,cAAc,IAAI,SAAS,EAAE,CAAC;AAC3D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,UAAkB;IACxD,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,EAAE,CAAC;IAC7C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,6DAA6D;IAC/D,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;IACpE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAkB,EAAE,EAAU;IAChE,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,CAAC,EAAE;QAAE,OAAO;IACjD,IAAI,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,8DAA8D;IAChE,CAAC;IACD,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAc,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,CAC1E,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAAkB,EAClB,QAA8B;IAE9B,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,CAAC,CAAQ,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAI,CAA8B,CAAC,MAAM,CAAC;QACtD,IAAI,MAAM,EAAE,UAAU,KAAK,UAAU,IAAI,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC;IACF,MAAM,SAAS,GAAG,CAAC,CAAe,EAAE,EAAE;QACpC,IAAI,CAAC,CAAC,GAAG,KAAK,UAAU,IAAI,CAAC,CAAC,QAAQ;YAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC/D,CAAC,CAAC;IACF,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC9C,OAAO,GAAG,EAAE;QACV,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACnD,CAAC,CAAC;AACJ,CAAC"}
|