@guuey/chat 0.16.9 → 0.16.11
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/dist/plan.d.ts.map +1 -1
- package/dist/plan.js +28 -7
- package/dist/react/guuey-chat.d.ts +55 -0
- package/dist/react/guuey-chat.d.ts.map +1 -1
- package/dist/react/guuey-chat.js +94 -3
- package/dist/react/markdown.d.ts +0 -26
- package/dist/react/markdown.d.ts.map +1 -1
- package/dist/react/markdown.js +50 -1
- package/dist/react/theme-css.d.ts.map +1 -1
- package/dist/react/theme-css.js +3 -0
- package/dist/strings.d.ts +11 -0
- package/dist/strings.d.ts.map +1 -1
- package/dist/strings.js +3 -0
- package/dist/theme.d.ts +4 -0
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +23 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/plan.ts +27 -8
- package/src/react/guuey-chat.tsx +170 -0
- package/src/react/markdown.tsx +39 -1
- package/src/react/theme-css.ts +3 -0
- package/src/strings.ts +17 -0
- package/src/theme.ts +23 -0
- package/src/types.ts +14 -1
- package/styles.css +85 -0
package/dist/plan.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AAkCA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,KAAK,EAUV,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EAIf,MAAM,YAAY,CAAC;AAuqBpB,uCAAuC;AACvC,wBAAgB,cAAc,CAC5B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,gBAAgB,EACxB,SAAS,GAAE,mBAAwB,GAClC,cAAc,
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AAkCA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,KAAK,EAUV,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EAIf,MAAM,YAAY,CAAC;AAuqBpB,uCAAuC;AACvC,wBAAgB,cAAc,CAC5B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,gBAAgB,EACxB,SAAS,GAAE,mBAAwB,GAClC,cAAc,CAkXhB;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,cAAc,CAAC,GACxD;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,GAAG,SAAS,CAiB5D"}
|
package/dist/plan.js
CHANGED
|
@@ -760,14 +760,35 @@ export function planTranscript(inputs, policy, overrides = {}) {
|
|
|
760
760
|
liveViewScopes.add(item.actionScope);
|
|
761
761
|
}
|
|
762
762
|
const cards = [...(inputs.historyCards ?? [])].sort((a, b) => a.seq - b.seq);
|
|
763
|
-
|
|
764
|
-
|
|
763
|
+
// guuey#535: ONE render session = ONE surface. Multiple history cards
|
|
764
|
+
// sharing an actionScope are the same surface referenced across turns
|
|
765
|
+
// (ggui SPEC §7.1.2.1 makes the amend result's {sessionId, resourceUri}
|
|
766
|
+
// the normative re-anchor reference — ggui#652; the stamp rides the
|
|
767
|
+
// existing locator persistence lane untouched). The LATEST reference
|
|
768
|
+
// anchors the surface; earlier references emit nothing — and latest
|
|
769
|
+
// wins even when it is locator-only, because the locator re-fetch
|
|
770
|
+
// restores CURRENT session state, better than an older frozen snapshot.
|
|
771
|
+
const scopes = cards.map((card) => {
|
|
765
772
|
const mount = snapshotViewMount(card.cardSnapshot);
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
773
|
+
return {
|
|
774
|
+
card,
|
|
775
|
+
mount,
|
|
776
|
+
scope: mount === undefined
|
|
777
|
+
? null
|
|
778
|
+
: mount.channel === "locator"
|
|
779
|
+
? mount.resourceUri
|
|
780
|
+
: mount.resource.uri,
|
|
781
|
+
};
|
|
782
|
+
});
|
|
783
|
+
const latestSeqByScope = new Map();
|
|
784
|
+
for (const { card, scope } of scopes) {
|
|
785
|
+
if (scope !== null)
|
|
786
|
+
latestSeqByScope.set(scope, card.seq);
|
|
787
|
+
}
|
|
788
|
+
for (const { card, mount, scope } of scopes) {
|
|
789
|
+
const key = `card.${card.seq}`;
|
|
790
|
+
if (scope !== null && latestSeqByScope.get(scope) !== card.seq)
|
|
791
|
+
continue; // a later turn re-anchored it
|
|
771
792
|
if (scope !== null && liveViewScopes.has(scope))
|
|
772
793
|
continue; // live mount owns it
|
|
773
794
|
const view = {
|
|
@@ -118,6 +118,28 @@ export interface GuueyChatHandle {
|
|
|
118
118
|
* to the transcript).
|
|
119
119
|
*/
|
|
120
120
|
viewSlotProps(): ViewSlotProps;
|
|
121
|
+
/**
|
|
122
|
+
* Forget this conversation (guuey#526 — the public-computer story).
|
|
123
|
+
*
|
|
124
|
+
* Local half, unconditional and immediate: aborts any in-flight turn
|
|
125
|
+
* FIRST (a completing turn can re-persist its own rows), drops the
|
|
126
|
+
* durable thread pointer AND its persisted storage key, wipes the
|
|
127
|
+
* visible transcript, clears the typed draft and any pending link ask —
|
|
128
|
+
* the next send mints a fresh thread.
|
|
129
|
+
*
|
|
130
|
+
* Server half, best-effort: when the surface has a platform door
|
|
131
|
+
* (`apiBaseUrl`) and a minted thread, fires
|
|
132
|
+
* `DELETE /v1/threads/:threadId` with the SAME identity the thread was
|
|
133
|
+
* created under (captured before any rotation) — real, child-first
|
|
134
|
+
* server-side erasure. A denied or failed delete still clears the
|
|
135
|
+
* device (the contract's unlinkability fallback) and surfaces nothing
|
|
136
|
+
* louder than the `thread-delete` debug event.
|
|
137
|
+
*
|
|
138
|
+
* Afterwards `onGuestSecretRotate` fires (when wired), so the identity
|
|
139
|
+
* owner mints a fresh guest secret — even an orphaned server row is
|
|
140
|
+
* unreachable from a rotated identity.
|
|
141
|
+
*/
|
|
142
|
+
clearConversation(): void;
|
|
121
143
|
}
|
|
122
144
|
export interface GuueyChatProps {
|
|
123
145
|
/** Pod base URL (with or without `/agent/invoke`). `null` disables chat. */
|
|
@@ -188,6 +210,39 @@ export interface GuueyChatProps {
|
|
|
188
210
|
* pod door) when omitted; an explicit reader always wins.
|
|
189
211
|
*/
|
|
190
212
|
reader?: UiResourceReader;
|
|
213
|
+
/**
|
|
214
|
+
* The forget-this-device affordance (guuey#526 — the public-computer
|
|
215
|
+
* story): a quiet "Clear conversation" control with a two-tap confirm,
|
|
216
|
+
* wired to {@link GuueyChatHandle.clearConversation}. Default: ON when
|
|
217
|
+
* the surface runs GUEST identity (`getGuestSecret` present — the
|
|
218
|
+
* founder's seamless principle; a signed-in surface has account-level
|
|
219
|
+
* recourse), OFF otherwise; pass a boolean to override either way.
|
|
220
|
+
*/
|
|
221
|
+
clearAffordance?: boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Guest-secret rotation hook (guuey#526): called at the END of every
|
|
224
|
+
* {@link GuueyChatHandle.clearConversation} — after the server delete
|
|
225
|
+
* has been dispatched with the OLD identity — so the owner of the
|
|
226
|
+
* secret's storage (the kit never stores it; `getGuestSecret` is a
|
|
227
|
+
* getter) mints a fresh one. Rotation is what makes even an orphaned
|
|
228
|
+
* server row unreachable: the new identity is a stranger to it. Guest
|
|
229
|
+
* KV state is (user,mcp)-scoped and is orphaned by rotation, by design.
|
|
230
|
+
*/
|
|
231
|
+
onGuestSecretRotate?: () => void;
|
|
232
|
+
/**
|
|
233
|
+
* Suggestion chips (guuey#533 — declared content, the one-truth design):
|
|
234
|
+
* rendered on the EMPTY transcript only (they retire the moment a
|
|
235
|
+
* message exists — live send or restored history both count), one tap
|
|
236
|
+
* SENDS the chip text verbatim through exactly the Send button's gate.
|
|
237
|
+
* Default-ON when content exists; `false` opts the surface out. The kit
|
|
238
|
+
* mirrors the card projection's caps render-side (4 shown, ≤80 chars
|
|
239
|
+
* each, blank-rejected) — a direct consumer bypassing the platform's
|
|
240
|
+
* emit gate gets the same bounds. Content is the host's (the widget
|
|
241
|
+
* passes the card's `suggestions`; a direct consumer passes its own);
|
|
242
|
+
* the kit never invents chips — an honest empty state beats invented
|
|
243
|
+
* questions in the builder's voice.
|
|
244
|
+
*/
|
|
245
|
+
suggestions?: readonly string[] | false;
|
|
191
246
|
/** The debug sink (spec §5) — fires only under the debug policy. */
|
|
192
247
|
onDebugEvent?: (event: ChatDebugEvent) => void;
|
|
193
248
|
/** R6 pass-through (relay hook, sandbox page/flags, host context…). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guuey-chat.d.ts","sourceRoot":"","sources":["../../src/react/guuey-chat.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,OAAO,EASL,KAAK,aAAa,EAEnB,MAAM,OAAO,CAAC;AACf,OAAO,
|
|
1
|
+
{"version":3,"file":"guuey-chat.d.ts","sourceRoot":"","sources":["../../src/react/guuey-chat.tsx"],"names":[],"mappings":"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"}
|
package/dist/react/guuey-chat.js
CHANGED
|
@@ -46,7 +46,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
46
46
|
* native GuueyChat, so there is no native surface to put a handle on yet.
|
|
47
47
|
*/
|
|
48
48
|
import { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef, useState, } from "react";
|
|
49
|
-
import { createUiActionRelay, createUiResourceReader, createWebAdapters, } from "@guuey/agent-client";
|
|
49
|
+
import { createUiActionRelay, createUiResourceReader, createWebAdapters, deleteThread, } from "@guuey/agent-client";
|
|
50
50
|
import { useAgentInvoke } from "@guuey/agent-client/react";
|
|
51
51
|
import { unavailableToolCallResult } from "@guuey/mcp-apps-host";
|
|
52
52
|
import { calmPolicy, debugPolicy } from "../policy.js";
|
|
@@ -85,7 +85,7 @@ const PROMPT_STATE = {
|
|
|
85
85
|
dismiss: "dismissed",
|
|
86
86
|
};
|
|
87
87
|
export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
|
|
88
|
-
const { endpointUrl, appId, apiBaseUrl, getAccessToken, getGuestSecret, adapters: adaptersProp, preset = "calm", policy: policyOverrides, components, strings: stringOverrides, theme = DEFAULT_CHAT_THEME, mode = "light", surface = "card", composer = true, window: windowing, reader, onDebugEvent, viewProps, promotedViewKey, onViewRef, onViewsChange, onPromptAction, onHitlAnswer, oauthReturnTo, onOAuthAuthorize, onErrorAction, onActivity, onReady, onThread, className, style, } = props;
|
|
88
|
+
const { endpointUrl, appId, apiBaseUrl, getAccessToken, getGuestSecret, adapters: adaptersProp, preset = "calm", policy: policyOverrides, components, strings: stringOverrides, theme = DEFAULT_CHAT_THEME, mode = "light", surface = "card", composer = true, window: windowing, reader, onDebugEvent, viewProps, promotedViewKey, onViewRef, onViewsChange, onPromptAction, onHitlAnswer, oauthReturnTo, onOAuthAuthorize, onErrorAction, clearAffordance, onGuestSecretRotate, suggestions, onActivity, onReady, onThread, className, style, } = props;
|
|
89
89
|
// Identity stabilization (guuey#303 QA — the template's own chat-rail
|
|
90
90
|
// shipped the failure): hosts pass inline literals and arrows, so prop
|
|
91
91
|
// IDENTITY is noise. The getter props route through refs (presence, not
|
|
@@ -96,8 +96,14 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
|
|
|
96
96
|
// host back → setState → re-render → "Maximum update depth exceeded".
|
|
97
97
|
const getAccessTokenRef = useRef(getAccessToken);
|
|
98
98
|
getAccessTokenRef.current = getAccessToken;
|
|
99
|
+
// The handle is created once ([] deps) but must read the LIVE base —
|
|
100
|
+
// same ref discipline as every other handle-read value in this file.
|
|
101
|
+
const apiBaseUrlRef = useRef(apiBaseUrl);
|
|
102
|
+
apiBaseUrlRef.current = apiBaseUrl;
|
|
99
103
|
const getGuestSecretRef = useRef(getGuestSecret);
|
|
100
104
|
getGuestSecretRef.current = getGuestSecret;
|
|
105
|
+
const onGuestSecretRotateRef = useRef(onGuestSecretRotate);
|
|
106
|
+
onGuestSecretRotateRef.current = onGuestSecretRotate;
|
|
101
107
|
const hasAccessToken = getAccessToken !== undefined;
|
|
102
108
|
const hasGuestSecret = getGuestSecret !== undefined;
|
|
103
109
|
const adapters = useMemo(() => adaptersProp ??
|
|
@@ -357,6 +363,40 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
|
|
|
357
363
|
// by construction. ONE pending ask at a time, newest replaces (a
|
|
358
364
|
// card spamming asks can never grow an unbounded stack).
|
|
359
365
|
const [pendingLink, setPendingLink] = useState(null);
|
|
366
|
+
// guuey#526: the two-tap confirm window for the clear affordance (an
|
|
367
|
+
// accidental tap must not nuke a conversation; a second tap within the
|
|
368
|
+
// window does — the state auto-expires).
|
|
369
|
+
const [clearArmed, setClearArmed] = useState(false);
|
|
370
|
+
useEffect(() => {
|
|
371
|
+
if (!clearArmed)
|
|
372
|
+
return;
|
|
373
|
+
const timer = setTimeout(() => setClearArmed(false), 4000);
|
|
374
|
+
return () => clearTimeout(timer);
|
|
375
|
+
}, [clearArmed]);
|
|
376
|
+
const showClearAffordance = clearAffordance ?? getGuestSecret !== undefined;
|
|
377
|
+
// guuey#533: the render-side mirror of the card projection's emit caps
|
|
378
|
+
// (4 shown / <=80 chars / blank-rejected) — same defense posture as the
|
|
379
|
+
// table normalizer: the kit is public npm and cannot assume every host
|
|
380
|
+
// routed content through platform's write gate.
|
|
381
|
+
const chips = useMemo(() => {
|
|
382
|
+
if (suggestions === false || suggestions === undefined)
|
|
383
|
+
return [];
|
|
384
|
+
return suggestions
|
|
385
|
+
.map((c) => c.trim())
|
|
386
|
+
.filter((c) => c.length > 0 && c.length <= 80)
|
|
387
|
+
.slice(0, 4);
|
|
388
|
+
}, [suggestions]);
|
|
389
|
+
const sendSuggestion = useCallback((text) => {
|
|
390
|
+
const live = liveRef.current;
|
|
391
|
+
// Exactly the Send button's gate (the #210 rule): unavailable, busy,
|
|
392
|
+
// or blank -> the tap is a no-op, never a bypass. The typed draft is
|
|
393
|
+
// left untouched (a chip send must not eat a half-typed message).
|
|
394
|
+
if (!live.available || live.busy || text.trim() === "")
|
|
395
|
+
return;
|
|
396
|
+
void live.invoke.send(text).catch(() => {
|
|
397
|
+
// Same contract as submit: the hook owns failure surfacing.
|
|
398
|
+
});
|
|
399
|
+
}, []);
|
|
360
400
|
const defaultOnOpenLink = useCallback((url) => {
|
|
361
401
|
setPendingLink(url);
|
|
362
402
|
}, []);
|
|
@@ -413,6 +453,49 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
|
|
|
413
453
|
focusComposer: () => {
|
|
414
454
|
inputRef.current?.focus();
|
|
415
455
|
},
|
|
456
|
+
clearConversation: () => {
|
|
457
|
+
const live = liveRef.current;
|
|
458
|
+
// Contract ordering (guuey#526, platform's frozen comment): abort
|
|
459
|
+
// FIRST — a completing turn can re-persist its own rows after the
|
|
460
|
+
// delete. Capture the id + guest secret BEFORE anything clears or
|
|
461
|
+
// rotates them: the delete must authenticate as the identity that
|
|
462
|
+
// OWNS the thread.
|
|
463
|
+
live.invoke.abort();
|
|
464
|
+
const threadId = threadIdRef.current;
|
|
465
|
+
const getGuest = getGuestSecretRef.current;
|
|
466
|
+
const guestSecret = getGuest !== undefined ? getGuest() : null;
|
|
467
|
+
if (apiBaseUrlRef.current !== undefined && threadId !== null) {
|
|
468
|
+
// Best-effort server erasure — fire-and-forget, never blocks the
|
|
469
|
+
// local clear. 200 and 404 are both "deleted" (idempotent by
|
|
470
|
+
// contract); denied/failed still cleared locally below (the
|
|
471
|
+
// unlinkability fallback) and surface ONLY as a debug line.
|
|
472
|
+
void deleteThread({
|
|
473
|
+
apiBaseUrl: apiBaseUrlRef.current,
|
|
474
|
+
threadId,
|
|
475
|
+
...(getAccessTokenRef.current !== undefined
|
|
476
|
+
? { getAccessToken: getAccessTokenRef.current }
|
|
477
|
+
: {}),
|
|
478
|
+
guestSecret,
|
|
479
|
+
}).then((outcome) => {
|
|
480
|
+
onDebugEventRef.current?.({ type: "thread-delete", threadId, outcome });
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
onDebugEventRef.current?.({ type: "thread-delete", threadId, outcome: "skipped" });
|
|
485
|
+
}
|
|
486
|
+
// The hook's reset owns the durable local half (pointer + storage
|
|
487
|
+
// key, transcript/fold/cards); the kit clears ITS OWN residue —
|
|
488
|
+
// the typed draft, a pending link ask, queued doorbells — so the
|
|
489
|
+
// device holds nothing of the conversation.
|
|
490
|
+
live.invoke.reset();
|
|
491
|
+
setInput("");
|
|
492
|
+
setPendingLink(null);
|
|
493
|
+
pendingDoorbellsRef.current = [];
|
|
494
|
+
// Rotation LAST: the delete above already captured the old
|
|
495
|
+
// identity, so the fresh secret is a stranger to even an orphaned
|
|
496
|
+
// server row.
|
|
497
|
+
onGuestSecretRotateRef.current?.();
|
|
498
|
+
},
|
|
416
499
|
// A getter, not a captured value: the handle is created once, but the
|
|
417
500
|
// thread hydrates after mount and can change — reads go through the
|
|
418
501
|
// same ref the default reader uses, so it is always the live id.
|
|
@@ -491,7 +574,15 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
|
|
|
491
574
|
onPromptAction?.(item, action);
|
|
492
575
|
}, [resolvePrompt, answerHitlPrompt, onHitlAnswer, onPromptAction, oauthReturnTo, onOAuthAuthorize]);
|
|
493
576
|
const strings = policy.strings;
|
|
494
|
-
return (_jsxs("div", { className: `guuey-chat-surface${className !== undefined ? ` ${className}` : ""}`, style: style, children: [_jsx(Transcript, { plan: plan, strings: strings, theme: theme, mode: mode, surface: surface, ...(windowing !== undefined ? { window: windowing } : {}), ...(components !== undefined ? { components } : {}), onToggle: toggle, onRetry: handleRetry, onPromptAction: handlePromptAction, ...(onErrorAction !== undefined ? { onErrorAction } : {}), resolvedMounts: resolvedMounts, onViewPhase: onViewPhase, onViewDiagnosis: onViewDiagnosis, ...(onViewRef !== undefined ? { onViewRef } : {}), viewProps: effectiveViewProps }),
|
|
577
|
+
return (_jsxs("div", { className: `guuey-chat-surface${className !== undefined ? ` ${className}` : ""}`, style: style, children: [_jsx(Transcript, { plan: plan, strings: strings, theme: theme, mode: mode, surface: surface, ...(windowing !== undefined ? { window: windowing } : {}), ...(components !== undefined ? { components } : {}), onToggle: toggle, onRetry: handleRetry, onPromptAction: handlePromptAction, ...(onErrorAction !== undefined ? { onErrorAction } : {}), resolvedMounts: resolvedMounts, onViewPhase: onViewPhase, onViewDiagnosis: onViewDiagnosis, ...(onViewRef !== undefined ? { onViewRef } : {}), viewProps: effectiveViewProps }), chips.length > 0 && inputs.messages.length === 0 && (_jsx("nav", { className: "guuey-chat-chips-row", "aria-label": strings.suggestionsLabel, children: chips.map((chip) => (_jsx("button", { type: "button", className: "guuey-chat-chip", onClick: () => sendSuggestion(chip), children: chip }, chip))) })), showClearAffordance && inputs.messages.length > 0 && (_jsx("div", { className: "guuey-chat-clear-row", children: _jsx("button", { type: "button", className: `guuey-chat-clear${clearArmed ? " guuey-chat-clear-armed" : ""}`, onClick: () => {
|
|
578
|
+
if (clearArmed) {
|
|
579
|
+
setClearArmed(false);
|
|
580
|
+
handle.clearConversation();
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
setClearArmed(true);
|
|
584
|
+
}
|
|
585
|
+
}, children: clearArmed ? strings.clearConversationConfirm : strings.clearConversationLabel }) })), pendingLink !== null && (_jsxs("div", { role: "status", className: "guuey-chat-link-ask", children: [_jsx("span", { className: "guuey-chat-link-ask-label", children: strings.linkAskLabel(new URL(pendingLink).host) }), _jsx("span", { className: "guuey-chat-link-ask-url", children: pendingLink }), _jsx("a", { className: "guuey-chat-link-ask-open", href: pendingLink, target: "_blank", rel: "noopener noreferrer", onClick: () => setPendingLink(null), children: strings.linkOpen }), _jsx("button", { type: "button", className: "guuey-chat-link-ask-dismiss", onClick: () => setPendingLink(null), children: strings.linkDismiss })] })), oauthReturn.notice !== null && (_jsxs("p", { role: "status", className: `guuey-chat-oauth-notice guuey-chat-oauth-${oauthReturn.notice.kind}`, children: [oauthReturn.notice.kind === "connected"
|
|
495
586
|
? strings.oauthConnected(oauthReturn.notice.serverName)
|
|
496
587
|
: strings.oauthFailed(oauthReturn.notice.reason), _jsx("button", { type: "button", className: "guuey-chat-oauth-dismiss", onClick: oauthReturn.dismiss, children: strings.promptDismissed })] })), composer && (_jsxs("form", { className: "guuey-chat-composer", onSubmit: (e) => {
|
|
497
588
|
e.preventDefault();
|
package/dist/react/markdown.d.ts
CHANGED
|
@@ -1,29 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The R1 markdown surface — the ONE place `@guuey/chat` renders
|
|
3
|
-
* agent-influenced content in the embedder's origin, and therefore the
|
|
4
|
-
* package's sanitizer boundary (spec §3.1).
|
|
5
|
-
*
|
|
6
|
-
* The pipeline is `@silverprotocol/richtext`: markdown → a TYPED AST in
|
|
7
|
-
* which raw HTML is structurally unrepresentable (no HTML node type
|
|
8
|
-
* exists; angle brackets can only ever be literal text) → React elements.
|
|
9
|
-
* That is deliberately STRONGER than the spec's letter (markdown → HTML →
|
|
10
|
-
* sanitize): there is no HTML string at any point, so there is nothing to
|
|
11
|
-
* sanitize incorrectly — no `dangerouslySetInnerHTML` anywhere in this
|
|
12
|
-
* package.
|
|
13
|
-
*
|
|
14
|
-
* Safety properties, each pinned by a test:
|
|
15
|
-
* - raw HTML (`<img onerror=…>`, `<script>`) renders as literal text;
|
|
16
|
-
* - link `href` is populated upstream ONLY for http/https/mailto —
|
|
17
|
-
* `javascript:`, `data:`, `vbscript:`, and relative targets parse as
|
|
18
|
-
* styled text with NO anchor `href` (richtext's `SAFE_HREF` allowlist);
|
|
19
|
-
* - navigable links carry `rel="noopener noreferrer" target="_blank"`;
|
|
20
|
-
* - there is NO image syntax in the node vocabulary at all — the spec's
|
|
21
|
-
* F5 ruling (markdown images off; R7 media blocks are the sanctioned
|
|
22
|
-
* image path) holds structurally, not by configuration.
|
|
23
|
-
*
|
|
24
|
-
* Streaming-tolerant by upstream design: unclosed emphasis mid-delta
|
|
25
|
-
* renders as formatted-so-far.
|
|
26
|
-
*/
|
|
27
1
|
import type { ReactNode } from "react";
|
|
28
2
|
import { type RichTextTableBlock } from "../richtext-table.js";
|
|
29
3
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/react/markdown.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/react/markdown.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AA0GlF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,kBAAkB,CAAA;CAAE,GAAG,SAAS,CA4B9E;AAwED,qEAAqE;AACrE,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAQ9D"}
|
package/dist/react/markdown.js
CHANGED
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* The R1 markdown surface — the ONE place `@guuey/chat` renders
|
|
4
|
+
* agent-influenced content in the embedder's origin, and therefore the
|
|
5
|
+
* package's sanitizer boundary (spec §3.1).
|
|
6
|
+
*
|
|
7
|
+
* The pipeline is `@silverprotocol/richtext`: markdown → a TYPED AST in
|
|
8
|
+
* which raw HTML is structurally unrepresentable (no HTML node type
|
|
9
|
+
* exists; angle brackets can only ever be literal text) → React elements.
|
|
10
|
+
* That is deliberately STRONGER than the spec's letter (markdown → HTML →
|
|
11
|
+
* sanitize): there is no HTML string at any point, so there is nothing to
|
|
12
|
+
* sanitize incorrectly — no `dangerouslySetInnerHTML` anywhere in this
|
|
13
|
+
* package.
|
|
14
|
+
*
|
|
15
|
+
* Safety properties, each pinned by a test:
|
|
16
|
+
* - raw HTML (`<img onerror=…>`, `<script>`) renders as literal text;
|
|
17
|
+
* - link `href` is populated upstream ONLY for http/https/mailto —
|
|
18
|
+
* `javascript:`, `data:`, `vbscript:`, and relative targets parse as
|
|
19
|
+
* styled text with NO anchor `href` (richtext's `SAFE_HREF` allowlist);
|
|
20
|
+
* - navigable links carry `rel="noopener noreferrer" target="_blank"`;
|
|
21
|
+
* - there is NO image syntax in the node vocabulary at all — the spec's
|
|
22
|
+
* F5 ruling (markdown images off; R7 media blocks are the sanctioned
|
|
23
|
+
* image path) holds structurally, not by configuration.
|
|
24
|
+
*
|
|
25
|
+
* Streaming-tolerant by upstream design: unclosed emphasis mid-delta
|
|
26
|
+
* renders as formatted-so-far.
|
|
27
|
+
*/
|
|
28
|
+
import { useState } from "react";
|
|
2
29
|
import { parseRichText, } from "@silverprotocol/richtext";
|
|
3
30
|
import { normalizeTableRow } from "../richtext-table.js";
|
|
4
31
|
/**
|
|
@@ -103,13 +130,35 @@ function Block({ block }) {
|
|
|
103
130
|
case "heading":
|
|
104
131
|
return (_jsx("p", { className: `guuey-chat-heading${block.level <= 3 ? " guuey-chat-heading-major" : ""}`, children: _jsx(Inline, { nodes: block.children }) }));
|
|
105
132
|
case "code-fence":
|
|
106
|
-
return _jsx(
|
|
133
|
+
return _jsx(CodeFence, { code: block.code });
|
|
107
134
|
case "list": {
|
|
108
135
|
const Tag = block.ordered ? "ol" : "ul";
|
|
109
136
|
return (_jsx(Tag, { ...(block.ordered && block.start !== undefined ? { start: block.start } : {}), children: block.items.map((item, j) => (_jsx("li", { children: _jsx(Inline, { nodes: item.children }) }, j))) }));
|
|
110
137
|
}
|
|
111
138
|
}
|
|
112
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* A fenced code block with its copy affordance (guuey#529 — the
|
|
142
|
+
* seamless-default family: every embedder's visitors get it with zero
|
|
143
|
+
* setup). The button lives in a wrapper DIV so the `<pre>` holds ONLY the
|
|
144
|
+
* code (select-all inside the fence never picks up UI text); the
|
|
145
|
+
* transcript's sibling-margin rules name the wrapper class alongside
|
|
146
|
+
* `pre`. Copy failure is shown truthfully: the label simply stays "Copy"
|
|
147
|
+
* (clipboard access needs a secure context + the iframe's
|
|
148
|
+
* clipboard-write grant — manual selection always still works).
|
|
149
|
+
*/
|
|
150
|
+
function CodeFence({ code }) {
|
|
151
|
+
const [copied, setCopied] = useState(false);
|
|
152
|
+
return (_jsxs("div", { className: "guuey-chat-code-wrap", children: [_jsx("pre", { className: "guuey-chat-code-fence", children: code }), _jsx("button", { type: "button", className: "guuey-chat-code-copy", "aria-label": copied ? "Copied" : "Copy code", onClick: () => {
|
|
153
|
+
const clipboard = navigator.clipboard;
|
|
154
|
+
if (clipboard === undefined)
|
|
155
|
+
return;
|
|
156
|
+
clipboard.writeText(code).then(() => {
|
|
157
|
+
setCopied(true);
|
|
158
|
+
setTimeout(() => setCopied(false), 1600);
|
|
159
|
+
}, () => setCopied(false));
|
|
160
|
+
}, children: copied ? "Copied" : "Copy" })] }));
|
|
161
|
+
}
|
|
113
162
|
/** Sanitized markdown → React elements (see the module docblock). */
|
|
114
163
|
export function Markdown({ text }) {
|
|
115
164
|
return (_jsx(_Fragment, { children: parseRichText(text).map((block, i) => (_jsx(Block, { block: block }, i))) }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-css.d.ts","sourceRoot":"","sources":["../../src/react/theme-css.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAazC;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"theme-css.d.ts","sourceRoot":"","sources":["../../src/react/theme-css.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAazC;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAyB3F"}
|
package/dist/react/theme-css.js
CHANGED
|
@@ -35,6 +35,9 @@ export function themeCssVars(theme, mode) {
|
|
|
35
35
|
"--_guuey-chat-gap": DENSITY_GAP[theme.shape.density],
|
|
36
36
|
"--_guuey-chat-scale": String(theme.typography.scale ?? 1),
|
|
37
37
|
};
|
|
38
|
+
if (palette.link !== undefined) {
|
|
39
|
+
vars["--_guuey-chat-link"] = palette.link;
|
|
40
|
+
}
|
|
38
41
|
if (theme.typography.fontFamily !== undefined) {
|
|
39
42
|
vars["--_guuey-chat-font"] = theme.typography.fontFamily;
|
|
40
43
|
}
|
package/dist/strings.d.ts
CHANGED
|
@@ -121,6 +121,17 @@ export interface ChatStrings {
|
|
|
121
121
|
linkAskLabel: (host: string) => string;
|
|
122
122
|
linkOpen: string;
|
|
123
123
|
linkDismiss: string;
|
|
124
|
+
/**
|
|
125
|
+
* The forget-this-device affordance (guuey#526): the quiet clear
|
|
126
|
+
* control and its two-tap confirm face.
|
|
127
|
+
*/
|
|
128
|
+
clearConversationLabel: string;
|
|
129
|
+
clearConversationConfirm: string;
|
|
130
|
+
/**
|
|
131
|
+
* The suggestion-chip row's accessible name (guuey#533) — the chips
|
|
132
|
+
* themselves are declared content (the app's own words), never kit copy.
|
|
133
|
+
*/
|
|
134
|
+
suggestionsLabel: string;
|
|
124
135
|
/** The 3c composer (`<GuueyChat>`). */
|
|
125
136
|
composerPlaceholder: string;
|
|
126
137
|
composerUnavailable: string;
|
package/dist/strings.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"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"}
|
package/dist/strings.js
CHANGED
|
@@ -80,6 +80,9 @@ export const defaultChatStrings = {
|
|
|
80
80
|
linkAskLabel: (host) => `This card wants to open ${host}`,
|
|
81
81
|
linkOpen: "Open",
|
|
82
82
|
linkDismiss: "Dismiss",
|
|
83
|
+
clearConversationLabel: "Clear conversation",
|
|
84
|
+
suggestionsLabel: "Suggestions",
|
|
85
|
+
clearConversationConfirm: "Tap again to clear this device",
|
|
83
86
|
composerPlaceholder: "Message the agent…",
|
|
84
87
|
composerUnavailable: "Chat is unavailable.",
|
|
85
88
|
composerLabel: "Message",
|
package/dist/theme.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ export declare const GuueyChatPalette: z.ZodObject<{
|
|
|
32
32
|
canvas: z.ZodString;
|
|
33
33
|
canvasMuted: z.ZodString;
|
|
34
34
|
error: z.ZodString;
|
|
35
|
+
link: z.ZodOptional<z.ZodString>;
|
|
35
36
|
}, z.core.$loose>;
|
|
36
37
|
export type GuueyChatPalette = z.infer<typeof GuueyChatPalette>;
|
|
37
38
|
/**
|
|
@@ -160,6 +161,7 @@ export declare const GuueyChatTheme: z.ZodObject<{
|
|
|
160
161
|
canvas: z.ZodString;
|
|
161
162
|
canvasMuted: z.ZodString;
|
|
162
163
|
error: z.ZodString;
|
|
164
|
+
link: z.ZodOptional<z.ZodString>;
|
|
163
165
|
}, z.core.$loose>;
|
|
164
166
|
dark: z.ZodObject<{
|
|
165
167
|
accent: z.ZodString;
|
|
@@ -170,6 +172,7 @@ export declare const GuueyChatTheme: z.ZodObject<{
|
|
|
170
172
|
canvas: z.ZodString;
|
|
171
173
|
canvasMuted: z.ZodString;
|
|
172
174
|
error: z.ZodString;
|
|
175
|
+
link: z.ZodOptional<z.ZodString>;
|
|
173
176
|
}, z.core.$loose>;
|
|
174
177
|
}, z.core.$loose>;
|
|
175
178
|
ramps: z.ZodOptional<z.ZodObject<{
|
|
@@ -240,6 +243,7 @@ export declare const GuueyChatTheme: z.ZodObject<{
|
|
|
240
243
|
comfortable: "comfortable";
|
|
241
244
|
}>;
|
|
242
245
|
}, z.core.$loose>;
|
|
246
|
+
courts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
243
247
|
}, z.core.$loose>;
|
|
244
248
|
export type GuueyChatTheme = z.infer<typeof GuueyChatTheme>;
|
|
245
249
|
/**
|
package/dist/theme.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;iBAiBnB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;iBAUtB,CAAC;AACX,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,eAAO,MAAM,kBAAkB;;;;iBAMrB,CAAC;AACX,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,eAAO,MAAM,iBAAiB;;iBAAqD,CAAC;AACpF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;iBAQnB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAKjB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsCjB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,EAAE,cA4BhC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAgC9B,CAAC;AA6CF;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,OAAO,EAClB,IAAI,GAAE,cAAmC,GACxC,cAAc,CAuBhB;AAYD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,OAAO,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,cAAmC,GACxC,cAAc,CAOhB"}
|
package/dist/theme.js
CHANGED
|
@@ -33,6 +33,12 @@ export const GuueyChatPalette = z
|
|
|
33
33
|
canvas: z.string(),
|
|
34
34
|
canvasMuted: z.string(),
|
|
35
35
|
error: z.string(),
|
|
36
|
+
/**
|
|
37
|
+
* Anchor color (guuey#528) — OPTIONAL by the evolution rule (a stored
|
|
38
|
+
* pre-#528 theme must keep passing the strict write gate); the default
|
|
39
|
+
* theme states it, so RESOLVED themes always carry it.
|
|
40
|
+
*/
|
|
41
|
+
link: z.string().optional(),
|
|
36
42
|
})
|
|
37
43
|
.loose();
|
|
38
44
|
/**
|
|
@@ -109,6 +115,14 @@ export const GuueyChatTheme = z
|
|
|
109
115
|
density: z.enum(["compact", "comfortable"]),
|
|
110
116
|
})
|
|
111
117
|
.loose(),
|
|
118
|
+
/**
|
|
119
|
+
* Per-court override DOCUMENTS (guuey#519), keyed by serving court —
|
|
120
|
+
* declared vocabulary (guuey#536: the manifest grammar mirrors this
|
|
121
|
+
* schema key-for-key, so the member must be stated, not passthrough).
|
|
122
|
+
* Entries are partial theme documents; `resolveCourtTheme` owns the
|
|
123
|
+
* per-token layering and resolved themes are always court-free.
|
|
124
|
+
*/
|
|
125
|
+
courts: z.record(z.string(), z.unknown()).optional(),
|
|
112
126
|
})
|
|
113
127
|
.loose();
|
|
114
128
|
/**
|
|
@@ -136,6 +150,7 @@ export const DEFAULT_CHAT_THEME = {
|
|
|
136
150
|
canvas: "#f7f7f5",
|
|
137
151
|
canvasMuted: "#eceded",
|
|
138
152
|
error: "#d64545",
|
|
153
|
+
link: "#111318",
|
|
139
154
|
},
|
|
140
155
|
dark: {
|
|
141
156
|
accent: "#e8e9ee",
|
|
@@ -146,6 +161,7 @@ export const DEFAULT_CHAT_THEME = {
|
|
|
146
161
|
canvas: "#0f1116",
|
|
147
162
|
canvasMuted: "#1b1e26",
|
|
148
163
|
error: "#ff6b6b",
|
|
164
|
+
link: "#e8e9ee",
|
|
149
165
|
},
|
|
150
166
|
},
|
|
151
167
|
typography: {},
|
|
@@ -170,6 +186,9 @@ export const GUUEY_CHAT_THEME = {
|
|
|
170
186
|
canvas: "#f6f5ee",
|
|
171
187
|
canvasMuted: "#ecebe0",
|
|
172
188
|
error: "#ff5b5b",
|
|
189
|
+
// slime-4, the founder-minted brand link green (guuey#528, 08-30) —
|
|
190
|
+
// the ladder had no readable green at link weight on light.
|
|
191
|
+
link: "#4e7a0e",
|
|
173
192
|
},
|
|
174
193
|
dark: {
|
|
175
194
|
accent: "#b8ff3a",
|
|
@@ -180,6 +199,9 @@ export const GUUEY_CHAT_THEME = {
|
|
|
180
199
|
canvas: "#0e1014",
|
|
181
200
|
canvasMuted: "#1a1d24",
|
|
182
201
|
error: "#ff5b5b",
|
|
202
|
+
// On dark the ladder's own slime IS readable at link weight — the
|
|
203
|
+
// #528 ruling minted slime-4 for LIGHT, where #b8ff3a is not.
|
|
204
|
+
link: "#b8ff3a",
|
|
183
205
|
},
|
|
184
206
|
},
|
|
185
207
|
typography: {},
|
|
@@ -211,6 +233,7 @@ const PALETTE_TOKENS = [
|
|
|
211
233
|
"canvas",
|
|
212
234
|
"canvasMuted",
|
|
213
235
|
"error",
|
|
236
|
+
"link",
|
|
214
237
|
];
|
|
215
238
|
function mergePalette(base, over) {
|
|
216
239
|
if (!over)
|
package/dist/types.d.ts
CHANGED
|
@@ -497,6 +497,19 @@ export type ChatDebugEvent = {
|
|
|
497
497
|
key: ItemKey;
|
|
498
498
|
resourceUri: string;
|
|
499
499
|
origin: "live" | "history";
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* `clearConversation()`'s server-erasure outcome (guuey#526). The clear
|
|
503
|
+
* itself is ALWAYS local-first and never blocks on this — the contract's
|
|
504
|
+
* unlinkability fallback says a denied/failed delete still clears the
|
|
505
|
+
* device and surfaces "nothing louder than a debug line"; this event IS
|
|
506
|
+
* that line. `"skipped"` = no platform door to call (no `apiBaseUrl`,
|
|
507
|
+
* or no thread ever minted) — the local-only clear, by construction.
|
|
508
|
+
*/
|
|
509
|
+
| {
|
|
510
|
+
type: "thread-delete";
|
|
511
|
+
threadId: string | null;
|
|
512
|
+
outcome: "deleted" | "denied" | "failed" | "skipped";
|
|
500
513
|
};
|
|
501
514
|
/**
|
|
502
515
|
* One renderable view the plan saw, BEFORE any chips/promotion pass —
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,WAAW,EACX,cAAc,EACd,QAAQ,EACR,SAAS,EACV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAE9B;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,YAAY,CAAC;IACjC,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;CAC1D;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,GAAG,EAAE,WAAW,CAAC;IACjB,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;IACzD,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,kBAAkB,GAAG,eAAe,CAAC;AAEnE,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;;OAWG;IACH,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,iFAAiF;IACjF,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACvD,iFAAiF;IACjF,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,kDAAkD;IAClD,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC7C,iFAAiF;IACjF,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC;IAC5D,yEAAyE;IACzE,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;IACrD;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC3D;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,uEAAuE;AACvE,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAE7B,+EAA+E;AAC/E,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,CAAC;AAIpF,UAAU,QAAQ;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,2EAA2E;IAC3E,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,kCAAkC;AAClC,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IACrC,6EAA6E;IAC7E,KAAK,EAAE,OAAO,CAAC;IACf;;;;;;;;;;OAUG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,2BAA2B;AAC3B,MAAM,WAAW,QAAS,SAAQ,QAAQ;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,4DAA4D;IAC5D,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,sBAAsB;AACtB,MAAM,WAAW,aAAc,SAAQ,QAAQ;IAC7C,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,kEAAkE;AAClE,MAAM,WAAW,cAAe,SAAQ,QAAQ;IAC9C,IAAI,EAAE,aAAa,CAAC;IACpB;;;OAGG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC9C,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,yCAAyC;AACzC,MAAM,WAAW,QAAS,SAAQ,QAAQ;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;IAClD,sEAAsE;IACtE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,uEAAuE;IACvE,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B;;;;OAIG;IACH,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,6DAA6D;AAC7D,MAAM,WAAW,aAAc,SAAQ,QAAQ;IAC7C,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,iEAAiE;AACjE,MAAM,WAAW,aAAc,SAAQ,QAAQ;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,sDAAsD;IACtD,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,iFAAiF;IACjF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;;OAIG;IACH,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACnC,mEAAmE;IACnE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kFAAkF;IAClF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAY,SAAQ,QAAQ;IAC3C,IAAI,EAAE,SAAS,CAAC;IAChB,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;CAClC;AAED,yBAAyB;AACzB,MAAM,WAAW,SAAU,SAAQ,QAAQ;IACzC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;IAC/C,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,QAAQ,GAAG,MAAM,CAAC;CACjC;AAED,wBAAwB;AACxB,MAAM,WAAW,QAAS,SAAQ,QAAQ;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;CACf;AAED,mDAAmD;AACnD,MAAM,WAAW,aAAc,SAAQ,QAAQ;IAC7C,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,EAAE,CAAC;IACxD,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;CACzB;AAED,wEAAwE;AACxE,MAAM,WAAW,iBAAkB,SAAQ,QAAQ;IACjD,IAAI,EAAE,QAAQ,CAAC;IACf,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,YAAY,CAAC;IACjC,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;IACzD,8DAA8D;IAC9D,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAe,SAAQ,QAAQ;IAC9C,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,GAAG,EAAE,WAAW,CAAC;IACjB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,oEAAoE;IACpE,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;IACnC;;;;;;OAMG;IACH,KAAK,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC;IACtE,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;IACzD,yEAAyE;IACzE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,sFAAsF;IACtF,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,8DAA8D;IAC9D,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;CACvB;AAED,0CAA0C;AAC1C,MAAM,MAAM,UAAU,GAAG,iBAAiB,GAAG,cAAc,CAAC;AAE5D;;;GAGG;AACH,MAAM,WAAW,UAAW,SAAQ,QAAQ;IAC1C,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,+EAA+E;IAC/E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,gDAAgD;AAChD,MAAM,WAAW,SAAU,SAAQ,QAAQ;IACzC,IAAI,EAAE,OAAO,CAAC;IACd;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,CAAC;IACnD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,iDAAiD;AACjD,MAAM,WAAW,mBAAoB,SAAQ,QAAQ;IACnD,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,oCAAoC;AACpC,MAAM,WAAW,cAAe,SAAQ,QAAQ;IAC9C,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,6EAA6E;AAC7E,MAAM,WAAW,WAAY,SAAQ,QAAQ;IAC3C,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,MAAM,WAAW,GACnB,eAAe,GACf,QAAQ,GACR,aAAa,GACb,QAAQ,GACR,aAAa,GACb,cAAc,GACd,aAAa,GACb,WAAW,GACX,SAAS,GACT,QAAQ,GACR,aAAa,GACb,UAAU,GACV,UAAU,GACV,SAAS,GACT,mBAAmB,GACnB,cAAc,GACd,WAAW,CAAC;AAEhB,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,QAAQ,CAAC;IACd,KAAK,EACD,YAAY,GACZ,UAAU,GACV,YAAY,GACZ,UAAU,GACV,YAAY,GACZ,SAAS,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,cAAc,GACtB;IACE,IAAI,EAAE,YAAY,CAAC;IACnB,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,8EAA8E;IAC9E,SAAS,CAAC,EAAE,gBAAgB,CAAC;CAC9B,GACD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAC5C;;;;;GAKG;GACD;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;AACpD;;;;;;;;;;GAUG;GACD;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE;AAC9F;;;;;;;GAOG;GACD;IACE,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;CACtD,CAAC;AAEN;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,OAAO,CAAC;IACb,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,4DAA4D;IAC5D,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;;OAKG;IACH,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,kEAAkE;IAClE,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;;OAIG;IACH,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guuey/chat",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.11",
|
|
4
4
|
"description": "The default end-user transcript UI for guuey agents — the headless view-model (planTranscript), calm/debug presets, the GuueyChatTheme token schema, the ChatStrings i18n seam, and (at ./react) the component kit that renders it: per-category components, <Transcript>, the live + history input assemblers, and stick-to-bottom/windowed/accessible transcript behavior; at ./native, the React Native renderer over the same view-model.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"@silverprotocol/core": "0.5.3",
|
|
40
40
|
"@silverprotocol/richtext": "0.5.3",
|
|
41
41
|
"zod": "^4.3.6",
|
|
42
|
-
"@guuey/agent-client": "0.16.
|
|
43
|
-
"@guuey/mcp-apps-host": "0.16.
|
|
42
|
+
"@guuey/agent-client": "0.16.11",
|
|
43
|
+
"@guuey/mcp-apps-host": "0.16.11"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"react": ">=18",
|
package/src/plan.ts
CHANGED
|
@@ -883,15 +883,34 @@ export function planTranscript(
|
|
|
883
883
|
if (item.kind === "view" && item.actionScope !== null) liveViewScopes.add(item.actionScope);
|
|
884
884
|
}
|
|
885
885
|
const cards = [...(inputs.historyCards ?? [])].sort((a, b) => a.seq - b.seq);
|
|
886
|
-
|
|
887
|
-
|
|
886
|
+
// guuey#535: ONE render session = ONE surface. Multiple history cards
|
|
887
|
+
// sharing an actionScope are the same surface referenced across turns
|
|
888
|
+
// (ggui SPEC §7.1.2.1 makes the amend result's {sessionId, resourceUri}
|
|
889
|
+
// the normative re-anchor reference — ggui#652; the stamp rides the
|
|
890
|
+
// existing locator persistence lane untouched). The LATEST reference
|
|
891
|
+
// anchors the surface; earlier references emit nothing — and latest
|
|
892
|
+
// wins even when it is locator-only, because the locator re-fetch
|
|
893
|
+
// restores CURRENT session state, better than an older frozen snapshot.
|
|
894
|
+
const scopes = cards.map((card) => {
|
|
888
895
|
const mount = snapshotViewMount(card.cardSnapshot);
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
896
|
+
return {
|
|
897
|
+
card,
|
|
898
|
+
mount,
|
|
899
|
+
scope:
|
|
900
|
+
mount === undefined
|
|
901
|
+
? null
|
|
902
|
+
: mount.channel === "locator"
|
|
903
|
+
? mount.resourceUri
|
|
904
|
+
: mount.resource.uri,
|
|
905
|
+
};
|
|
906
|
+
});
|
|
907
|
+
const latestSeqByScope = new Map<string, number>();
|
|
908
|
+
for (const { card, scope } of scopes) {
|
|
909
|
+
if (scope !== null) latestSeqByScope.set(scope, card.seq);
|
|
910
|
+
}
|
|
911
|
+
for (const { card, mount, scope } of scopes) {
|
|
912
|
+
const key = `card.${card.seq}`;
|
|
913
|
+
if (scope !== null && latestSeqByScope.get(scope) !== card.seq) continue; // a later turn re-anchored it
|
|
895
914
|
if (scope !== null && liveViewScopes.has(scope)) continue; // live mount owns it
|
|
896
915
|
const view: ViewMountItem = {
|
|
897
916
|
kind: "view",
|
package/src/react/guuey-chat.tsx
CHANGED
|
@@ -60,6 +60,7 @@ import {
|
|
|
60
60
|
createUiActionRelay,
|
|
61
61
|
createUiResourceReader,
|
|
62
62
|
createWebAdapters,
|
|
63
|
+
deleteThread,
|
|
63
64
|
type AgentInvokeAdapters,
|
|
64
65
|
} from "@guuey/agent-client";
|
|
65
66
|
import type { AgHitlAnswer, AgPausedAsk } from "@silverprotocol/core";
|
|
@@ -169,6 +170,28 @@ export interface GuueyChatHandle {
|
|
|
169
170
|
* to the transcript).
|
|
170
171
|
*/
|
|
171
172
|
viewSlotProps(): ViewSlotProps;
|
|
173
|
+
/**
|
|
174
|
+
* Forget this conversation (guuey#526 — the public-computer story).
|
|
175
|
+
*
|
|
176
|
+
* Local half, unconditional and immediate: aborts any in-flight turn
|
|
177
|
+
* FIRST (a completing turn can re-persist its own rows), drops the
|
|
178
|
+
* durable thread pointer AND its persisted storage key, wipes the
|
|
179
|
+
* visible transcript, clears the typed draft and any pending link ask —
|
|
180
|
+
* the next send mints a fresh thread.
|
|
181
|
+
*
|
|
182
|
+
* Server half, best-effort: when the surface has a platform door
|
|
183
|
+
* (`apiBaseUrl`) and a minted thread, fires
|
|
184
|
+
* `DELETE /v1/threads/:threadId` with the SAME identity the thread was
|
|
185
|
+
* created under (captured before any rotation) — real, child-first
|
|
186
|
+
* server-side erasure. A denied or failed delete still clears the
|
|
187
|
+
* device (the contract's unlinkability fallback) and surfaces nothing
|
|
188
|
+
* louder than the `thread-delete` debug event.
|
|
189
|
+
*
|
|
190
|
+
* Afterwards `onGuestSecretRotate` fires (when wired), so the identity
|
|
191
|
+
* owner mints a fresh guest secret — even an orphaned server row is
|
|
192
|
+
* unreachable from a rotated identity.
|
|
193
|
+
*/
|
|
194
|
+
clearConversation(): void;
|
|
172
195
|
}
|
|
173
196
|
|
|
174
197
|
export interface GuueyChatProps {
|
|
@@ -238,6 +261,39 @@ export interface GuueyChatProps {
|
|
|
238
261
|
* pod door) when omitted; an explicit reader always wins.
|
|
239
262
|
*/
|
|
240
263
|
reader?: UiResourceReader;
|
|
264
|
+
/**
|
|
265
|
+
* The forget-this-device affordance (guuey#526 — the public-computer
|
|
266
|
+
* story): a quiet "Clear conversation" control with a two-tap confirm,
|
|
267
|
+
* wired to {@link GuueyChatHandle.clearConversation}. Default: ON when
|
|
268
|
+
* the surface runs GUEST identity (`getGuestSecret` present — the
|
|
269
|
+
* founder's seamless principle; a signed-in surface has account-level
|
|
270
|
+
* recourse), OFF otherwise; pass a boolean to override either way.
|
|
271
|
+
*/
|
|
272
|
+
clearAffordance?: boolean;
|
|
273
|
+
/**
|
|
274
|
+
* Guest-secret rotation hook (guuey#526): called at the END of every
|
|
275
|
+
* {@link GuueyChatHandle.clearConversation} — after the server delete
|
|
276
|
+
* has been dispatched with the OLD identity — so the owner of the
|
|
277
|
+
* secret's storage (the kit never stores it; `getGuestSecret` is a
|
|
278
|
+
* getter) mints a fresh one. Rotation is what makes even an orphaned
|
|
279
|
+
* server row unreachable: the new identity is a stranger to it. Guest
|
|
280
|
+
* KV state is (user,mcp)-scoped and is orphaned by rotation, by design.
|
|
281
|
+
*/
|
|
282
|
+
onGuestSecretRotate?: () => void;
|
|
283
|
+
/**
|
|
284
|
+
* Suggestion chips (guuey#533 — declared content, the one-truth design):
|
|
285
|
+
* rendered on the EMPTY transcript only (they retire the moment a
|
|
286
|
+
* message exists — live send or restored history both count), one tap
|
|
287
|
+
* SENDS the chip text verbatim through exactly the Send button's gate.
|
|
288
|
+
* Default-ON when content exists; `false` opts the surface out. The kit
|
|
289
|
+
* mirrors the card projection's caps render-side (4 shown, ≤80 chars
|
|
290
|
+
* each, blank-rejected) — a direct consumer bypassing the platform's
|
|
291
|
+
* emit gate gets the same bounds. Content is the host's (the widget
|
|
292
|
+
* passes the card's `suggestions`; a direct consumer passes its own);
|
|
293
|
+
* the kit never invents chips — an honest empty state beats invented
|
|
294
|
+
* questions in the builder's voice.
|
|
295
|
+
*/
|
|
296
|
+
suggestions?: readonly string[] | false;
|
|
241
297
|
/** The debug sink (spec §5) — fires only under the debug policy. */
|
|
242
298
|
onDebugEvent?: (event: ChatDebugEvent) => void;
|
|
243
299
|
/** R6 pass-through (relay hook, sandbox page/flags, host context…). */
|
|
@@ -353,6 +409,9 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
|
|
|
353
409
|
oauthReturnTo,
|
|
354
410
|
onOAuthAuthorize,
|
|
355
411
|
onErrorAction,
|
|
412
|
+
clearAffordance,
|
|
413
|
+
onGuestSecretRotate,
|
|
414
|
+
suggestions,
|
|
356
415
|
onActivity,
|
|
357
416
|
onReady,
|
|
358
417
|
onThread,
|
|
@@ -370,8 +429,14 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
|
|
|
370
429
|
// host back → setState → re-render → "Maximum update depth exceeded".
|
|
371
430
|
const getAccessTokenRef = useRef(getAccessToken);
|
|
372
431
|
getAccessTokenRef.current = getAccessToken;
|
|
432
|
+
// The handle is created once ([] deps) but must read the LIVE base —
|
|
433
|
+
// same ref discipline as every other handle-read value in this file.
|
|
434
|
+
const apiBaseUrlRef = useRef(apiBaseUrl);
|
|
435
|
+
apiBaseUrlRef.current = apiBaseUrl;
|
|
373
436
|
const getGuestSecretRef = useRef(getGuestSecret);
|
|
374
437
|
getGuestSecretRef.current = getGuestSecret;
|
|
438
|
+
const onGuestSecretRotateRef = useRef(onGuestSecretRotate);
|
|
439
|
+
onGuestSecretRotateRef.current = onGuestSecretRotate;
|
|
375
440
|
const hasAccessToken = getAccessToken !== undefined;
|
|
376
441
|
const hasGuestSecret = getGuestSecret !== undefined;
|
|
377
442
|
|
|
@@ -646,6 +711,37 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
|
|
|
646
711
|
// by construction. ONE pending ask at a time, newest replaces (a
|
|
647
712
|
// card spamming asks can never grow an unbounded stack).
|
|
648
713
|
const [pendingLink, setPendingLink] = useState<string | null>(null);
|
|
714
|
+
// guuey#526: the two-tap confirm window for the clear affordance (an
|
|
715
|
+
// accidental tap must not nuke a conversation; a second tap within the
|
|
716
|
+
// window does — the state auto-expires).
|
|
717
|
+
const [clearArmed, setClearArmed] = useState(false);
|
|
718
|
+
useEffect(() => {
|
|
719
|
+
if (!clearArmed) return;
|
|
720
|
+
const timer = setTimeout(() => setClearArmed(false), 4000);
|
|
721
|
+
return () => clearTimeout(timer);
|
|
722
|
+
}, [clearArmed]);
|
|
723
|
+
const showClearAffordance = clearAffordance ?? getGuestSecret !== undefined;
|
|
724
|
+
// guuey#533: the render-side mirror of the card projection's emit caps
|
|
725
|
+
// (4 shown / <=80 chars / blank-rejected) — same defense posture as the
|
|
726
|
+
// table normalizer: the kit is public npm and cannot assume every host
|
|
727
|
+
// routed content through platform's write gate.
|
|
728
|
+
const chips = useMemo<readonly string[]>(() => {
|
|
729
|
+
if (suggestions === false || suggestions === undefined) return [];
|
|
730
|
+
return suggestions
|
|
731
|
+
.map((c) => c.trim())
|
|
732
|
+
.filter((c) => c.length > 0 && c.length <= 80)
|
|
733
|
+
.slice(0, 4);
|
|
734
|
+
}, [suggestions]);
|
|
735
|
+
const sendSuggestion = useCallback((text: string): void => {
|
|
736
|
+
const live = liveRef.current;
|
|
737
|
+
// Exactly the Send button's gate (the #210 rule): unavailable, busy,
|
|
738
|
+
// or blank -> the tap is a no-op, never a bypass. The typed draft is
|
|
739
|
+
// left untouched (a chip send must not eat a half-typed message).
|
|
740
|
+
if (!live.available || live.busy || text.trim() === "") return;
|
|
741
|
+
void live.invoke.send(text).catch(() => {
|
|
742
|
+
// Same contract as submit: the hook owns failure surfacing.
|
|
743
|
+
});
|
|
744
|
+
}, []);
|
|
649
745
|
const defaultOnOpenLink = useCallback((url: string) => {
|
|
650
746
|
setPendingLink(url);
|
|
651
747
|
}, []);
|
|
@@ -709,6 +805,48 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
|
|
|
709
805
|
focusComposer: (): void => {
|
|
710
806
|
inputRef.current?.focus();
|
|
711
807
|
},
|
|
808
|
+
clearConversation: (): void => {
|
|
809
|
+
const live = liveRef.current;
|
|
810
|
+
// Contract ordering (guuey#526, platform's frozen comment): abort
|
|
811
|
+
// FIRST — a completing turn can re-persist its own rows after the
|
|
812
|
+
// delete. Capture the id + guest secret BEFORE anything clears or
|
|
813
|
+
// rotates them: the delete must authenticate as the identity that
|
|
814
|
+
// OWNS the thread.
|
|
815
|
+
live.invoke.abort();
|
|
816
|
+
const threadId = threadIdRef.current;
|
|
817
|
+
const getGuest = getGuestSecretRef.current;
|
|
818
|
+
const guestSecret = getGuest !== undefined ? getGuest() : null;
|
|
819
|
+
if (apiBaseUrlRef.current !== undefined && threadId !== null) {
|
|
820
|
+
// Best-effort server erasure — fire-and-forget, never blocks the
|
|
821
|
+
// local clear. 200 and 404 are both "deleted" (idempotent by
|
|
822
|
+
// contract); denied/failed still cleared locally below (the
|
|
823
|
+
// unlinkability fallback) and surface ONLY as a debug line.
|
|
824
|
+
void deleteThread({
|
|
825
|
+
apiBaseUrl: apiBaseUrlRef.current,
|
|
826
|
+
threadId,
|
|
827
|
+
...(getAccessTokenRef.current !== undefined
|
|
828
|
+
? { getAccessToken: getAccessTokenRef.current }
|
|
829
|
+
: {}),
|
|
830
|
+
guestSecret,
|
|
831
|
+
}).then((outcome) => {
|
|
832
|
+
onDebugEventRef.current?.({ type: "thread-delete", threadId, outcome });
|
|
833
|
+
});
|
|
834
|
+
} else {
|
|
835
|
+
onDebugEventRef.current?.({ type: "thread-delete", threadId, outcome: "skipped" });
|
|
836
|
+
}
|
|
837
|
+
// The hook's reset owns the durable local half (pointer + storage
|
|
838
|
+
// key, transcript/fold/cards); the kit clears ITS OWN residue —
|
|
839
|
+
// the typed draft, a pending link ask, queued doorbells — so the
|
|
840
|
+
// device holds nothing of the conversation.
|
|
841
|
+
live.invoke.reset();
|
|
842
|
+
setInput("");
|
|
843
|
+
setPendingLink(null);
|
|
844
|
+
pendingDoorbellsRef.current = [];
|
|
845
|
+
// Rotation LAST: the delete above already captured the old
|
|
846
|
+
// identity, so the fresh secret is a stranger to even an orphaned
|
|
847
|
+
// server row.
|
|
848
|
+
onGuestSecretRotateRef.current?.();
|
|
849
|
+
},
|
|
712
850
|
// A getter, not a captured value: the handle is created once, but the
|
|
713
851
|
// thread hydrates after mount and can change — reads go through the
|
|
714
852
|
// same ref the default reader uses, so it is always the live id.
|
|
@@ -828,6 +966,38 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
|
|
|
828
966
|
{...(onViewRef !== undefined ? { onViewRef } : {})}
|
|
829
967
|
viewProps={effectiveViewProps}
|
|
830
968
|
/>
|
|
969
|
+
{chips.length > 0 && inputs.messages.length === 0 && (
|
|
970
|
+
<nav className="guuey-chat-chips-row" aria-label={strings.suggestionsLabel}>
|
|
971
|
+
{chips.map((chip) => (
|
|
972
|
+
<button
|
|
973
|
+
key={chip}
|
|
974
|
+
type="button"
|
|
975
|
+
className="guuey-chat-chip"
|
|
976
|
+
onClick={() => sendSuggestion(chip)}
|
|
977
|
+
>
|
|
978
|
+
{chip}
|
|
979
|
+
</button>
|
|
980
|
+
))}
|
|
981
|
+
</nav>
|
|
982
|
+
)}
|
|
983
|
+
{showClearAffordance && inputs.messages.length > 0 && (
|
|
984
|
+
<div className="guuey-chat-clear-row">
|
|
985
|
+
<button
|
|
986
|
+
type="button"
|
|
987
|
+
className={`guuey-chat-clear${clearArmed ? " guuey-chat-clear-armed" : ""}`}
|
|
988
|
+
onClick={() => {
|
|
989
|
+
if (clearArmed) {
|
|
990
|
+
setClearArmed(false);
|
|
991
|
+
handle.clearConversation();
|
|
992
|
+
} else {
|
|
993
|
+
setClearArmed(true);
|
|
994
|
+
}
|
|
995
|
+
}}
|
|
996
|
+
>
|
|
997
|
+
{clearArmed ? strings.clearConversationConfirm : strings.clearConversationLabel}
|
|
998
|
+
</button>
|
|
999
|
+
</div>
|
|
1000
|
+
)}
|
|
831
1001
|
{pendingLink !== null && (
|
|
832
1002
|
<div role="status" className="guuey-chat-link-ask">
|
|
833
1003
|
<span className="guuey-chat-link-ask-label">
|
package/src/react/markdown.tsx
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
* Streaming-tolerant by upstream design: unclosed emphasis mid-delta
|
|
25
25
|
* renders as formatted-so-far.
|
|
26
26
|
*/
|
|
27
|
+
import { useState } from "react";
|
|
27
28
|
import type { ReactNode } from "react";
|
|
28
29
|
import {
|
|
29
30
|
parseRichText,
|
|
@@ -188,7 +189,7 @@ function Block({ block }: { block: RichTextBlock }): ReactNode {
|
|
|
188
189
|
</p>
|
|
189
190
|
);
|
|
190
191
|
case "code-fence":
|
|
191
|
-
return <
|
|
192
|
+
return <CodeFence code={block.code} />;
|
|
192
193
|
case "list": {
|
|
193
194
|
const Tag = block.ordered ? "ol" : "ul";
|
|
194
195
|
return (
|
|
@@ -204,6 +205,43 @@ function Block({ block }: { block: RichTextBlock }): ReactNode {
|
|
|
204
205
|
}
|
|
205
206
|
}
|
|
206
207
|
|
|
208
|
+
/**
|
|
209
|
+
* A fenced code block with its copy affordance (guuey#529 — the
|
|
210
|
+
* seamless-default family: every embedder's visitors get it with zero
|
|
211
|
+
* setup). The button lives in a wrapper DIV so the `<pre>` holds ONLY the
|
|
212
|
+
* code (select-all inside the fence never picks up UI text); the
|
|
213
|
+
* transcript's sibling-margin rules name the wrapper class alongside
|
|
214
|
+
* `pre`. Copy failure is shown truthfully: the label simply stays "Copy"
|
|
215
|
+
* (clipboard access needs a secure context + the iframe's
|
|
216
|
+
* clipboard-write grant — manual selection always still works).
|
|
217
|
+
*/
|
|
218
|
+
function CodeFence({ code }: { code: string }): ReactNode {
|
|
219
|
+
const [copied, setCopied] = useState(false);
|
|
220
|
+
return (
|
|
221
|
+
<div className="guuey-chat-code-wrap">
|
|
222
|
+
<pre className="guuey-chat-code-fence">{code}</pre>
|
|
223
|
+
<button
|
|
224
|
+
type="button"
|
|
225
|
+
className="guuey-chat-code-copy"
|
|
226
|
+
aria-label={copied ? "Copied" : "Copy code"}
|
|
227
|
+
onClick={() => {
|
|
228
|
+
const clipboard = navigator.clipboard;
|
|
229
|
+
if (clipboard === undefined) return;
|
|
230
|
+
clipboard.writeText(code).then(
|
|
231
|
+
() => {
|
|
232
|
+
setCopied(true);
|
|
233
|
+
setTimeout(() => setCopied(false), 1600);
|
|
234
|
+
},
|
|
235
|
+
() => setCopied(false),
|
|
236
|
+
);
|
|
237
|
+
}}
|
|
238
|
+
>
|
|
239
|
+
{copied ? "Copied" : "Copy"}
|
|
240
|
+
</button>
|
|
241
|
+
</div>
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
207
245
|
/** Sanitized markdown → React elements (see the module docblock). */
|
|
208
246
|
export function Markdown({ text }: { text: string }): ReactNode {
|
|
209
247
|
return (
|
package/src/react/theme-css.ts
CHANGED
|
@@ -48,6 +48,9 @@ export function themeCssVars(theme: GuueyChatTheme, mode: ThemeMode): Record<str
|
|
|
48
48
|
"--_guuey-chat-gap": DENSITY_GAP[theme.shape.density],
|
|
49
49
|
"--_guuey-chat-scale": String(theme.typography.scale ?? 1),
|
|
50
50
|
};
|
|
51
|
+
if (palette.link !== undefined) {
|
|
52
|
+
vars["--_guuey-chat-link"] = palette.link;
|
|
53
|
+
}
|
|
51
54
|
if (theme.typography.fontFamily !== undefined) {
|
|
52
55
|
vars["--_guuey-chat-font"] = theme.typography.fontFamily;
|
|
53
56
|
}
|
package/src/strings.ts
CHANGED
|
@@ -137,6 +137,19 @@ export interface ChatStrings {
|
|
|
137
137
|
linkOpen: string;
|
|
138
138
|
linkDismiss: string;
|
|
139
139
|
|
|
140
|
+
/**
|
|
141
|
+
* The forget-this-device affordance (guuey#526): the quiet clear
|
|
142
|
+
* control and its two-tap confirm face.
|
|
143
|
+
*/
|
|
144
|
+
clearConversationLabel: string;
|
|
145
|
+
clearConversationConfirm: string;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* The suggestion-chip row's accessible name (guuey#533) — the chips
|
|
149
|
+
* themselves are declared content (the app's own words), never kit copy.
|
|
150
|
+
*/
|
|
151
|
+
suggestionsLabel: string;
|
|
152
|
+
|
|
140
153
|
/** The 3c composer (`<GuueyChat>`). */
|
|
141
154
|
composerPlaceholder: string;
|
|
142
155
|
composerUnavailable: string;
|
|
@@ -246,6 +259,10 @@ export const defaultChatStrings: ChatStrings = {
|
|
|
246
259
|
linkOpen: "Open",
|
|
247
260
|
linkDismiss: "Dismiss",
|
|
248
261
|
|
|
262
|
+
clearConversationLabel: "Clear conversation",
|
|
263
|
+
suggestionsLabel: "Suggestions",
|
|
264
|
+
clearConversationConfirm: "Tap again to clear this device",
|
|
265
|
+
|
|
249
266
|
composerPlaceholder: "Message the agent…",
|
|
250
267
|
composerUnavailable: "Chat is unavailable.",
|
|
251
268
|
composerLabel: "Message",
|
package/src/theme.ts
CHANGED
|
@@ -34,6 +34,12 @@ export const GuueyChatPalette = z
|
|
|
34
34
|
canvas: z.string(),
|
|
35
35
|
canvasMuted: z.string(),
|
|
36
36
|
error: z.string(),
|
|
37
|
+
/**
|
|
38
|
+
* Anchor color (guuey#528) — OPTIONAL by the evolution rule (a stored
|
|
39
|
+
* pre-#528 theme must keep passing the strict write gate); the default
|
|
40
|
+
* theme states it, so RESOLVED themes always carry it.
|
|
41
|
+
*/
|
|
42
|
+
link: z.string().optional(),
|
|
37
43
|
})
|
|
38
44
|
.loose();
|
|
39
45
|
export type GuueyChatPalette = z.infer<typeof GuueyChatPalette>;
|
|
@@ -122,6 +128,14 @@ export const GuueyChatTheme = z
|
|
|
122
128
|
density: z.enum(["compact", "comfortable"]),
|
|
123
129
|
})
|
|
124
130
|
.loose(),
|
|
131
|
+
/**
|
|
132
|
+
* Per-court override DOCUMENTS (guuey#519), keyed by serving court —
|
|
133
|
+
* declared vocabulary (guuey#536: the manifest grammar mirrors this
|
|
134
|
+
* schema key-for-key, so the member must be stated, not passthrough).
|
|
135
|
+
* Entries are partial theme documents; `resolveCourtTheme` owns the
|
|
136
|
+
* per-token layering and resolved themes are always court-free.
|
|
137
|
+
*/
|
|
138
|
+
courts: z.record(z.string(), z.unknown()).optional(),
|
|
125
139
|
})
|
|
126
140
|
.loose();
|
|
127
141
|
export type GuueyChatTheme = z.infer<typeof GuueyChatTheme>;
|
|
@@ -151,6 +165,7 @@ export const DEFAULT_CHAT_THEME: GuueyChatTheme = {
|
|
|
151
165
|
canvas: "#f7f7f5",
|
|
152
166
|
canvasMuted: "#eceded",
|
|
153
167
|
error: "#d64545",
|
|
168
|
+
link: "#111318",
|
|
154
169
|
},
|
|
155
170
|
dark: {
|
|
156
171
|
accent: "#e8e9ee",
|
|
@@ -161,6 +176,7 @@ export const DEFAULT_CHAT_THEME: GuueyChatTheme = {
|
|
|
161
176
|
canvas: "#0f1116",
|
|
162
177
|
canvasMuted: "#1b1e26",
|
|
163
178
|
error: "#ff6b6b",
|
|
179
|
+
link: "#e8e9ee",
|
|
164
180
|
},
|
|
165
181
|
},
|
|
166
182
|
typography: {},
|
|
@@ -186,6 +202,9 @@ export const GUUEY_CHAT_THEME: GuueyChatTheme = {
|
|
|
186
202
|
canvas: "#f6f5ee",
|
|
187
203
|
canvasMuted: "#ecebe0",
|
|
188
204
|
error: "#ff5b5b",
|
|
205
|
+
// slime-4, the founder-minted brand link green (guuey#528, 08-30) —
|
|
206
|
+
// the ladder had no readable green at link weight on light.
|
|
207
|
+
link: "#4e7a0e",
|
|
189
208
|
},
|
|
190
209
|
dark: {
|
|
191
210
|
accent: "#b8ff3a",
|
|
@@ -196,6 +215,9 @@ export const GUUEY_CHAT_THEME: GuueyChatTheme = {
|
|
|
196
215
|
canvas: "#0e1014",
|
|
197
216
|
canvasMuted: "#1a1d24",
|
|
198
217
|
error: "#ff5b5b",
|
|
218
|
+
// On dark the ladder's own slime IS readable at link weight — the
|
|
219
|
+
// #528 ruling minted slime-4 for LIGHT, where #b8ff3a is not.
|
|
220
|
+
link: "#b8ff3a",
|
|
199
221
|
},
|
|
200
222
|
},
|
|
201
223
|
typography: {},
|
|
@@ -229,6 +251,7 @@ const PALETTE_TOKENS = [
|
|
|
229
251
|
"canvas",
|
|
230
252
|
"canvasMuted",
|
|
231
253
|
"error",
|
|
254
|
+
"link",
|
|
232
255
|
] as const;
|
|
233
256
|
|
|
234
257
|
function mergePalette(
|
package/src/types.ts
CHANGED
|
@@ -540,7 +540,20 @@ export type ChatDebugEvent =
|
|
|
540
540
|
* is by construction, not a failure). Debug-only like every event here
|
|
541
541
|
* — calm end-user UX keeps deny == miss un-oracled.
|
|
542
542
|
*/
|
|
543
|
-
| { type: "locator-read-miss"; key: ItemKey; resourceUri: string; origin: "live" | "history" }
|
|
543
|
+
| { type: "locator-read-miss"; key: ItemKey; resourceUri: string; origin: "live" | "history" }
|
|
544
|
+
/**
|
|
545
|
+
* `clearConversation()`'s server-erasure outcome (guuey#526). The clear
|
|
546
|
+
* itself is ALWAYS local-first and never blocks on this — the contract's
|
|
547
|
+
* unlinkability fallback says a denied/failed delete still clears the
|
|
548
|
+
* device and surfaces "nothing louder than a debug line"; this event IS
|
|
549
|
+
* that line. `"skipped"` = no platform door to call (no `apiBaseUrl`,
|
|
550
|
+
* or no thread ever minted) — the local-only clear, by construction.
|
|
551
|
+
*/
|
|
552
|
+
| {
|
|
553
|
+
type: "thread-delete";
|
|
554
|
+
threadId: string | null;
|
|
555
|
+
outcome: "deleted" | "denied" | "failed" | "skipped";
|
|
556
|
+
};
|
|
544
557
|
|
|
545
558
|
/**
|
|
546
559
|
* One renderable view the plan saw, BEFORE any chips/promotion pass —
|
package/styles.css
CHANGED
|
@@ -40,6 +40,48 @@
|
|
|
40
40
|
margin-inline: auto;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/* ── suggestion chips (guuey#533) — empty-state only, one-tap-sends;
|
|
44
|
+
restyled ENTIRELY by the #521 composable tokens (surface/ink/radius
|
|
45
|
+
— no new tokens). ── */
|
|
46
|
+
.guuey-chat-chips-row {
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-wrap: wrap;
|
|
49
|
+
gap: 8px;
|
|
50
|
+
padding: 4px calc(var(--guuey-chat-gap) * 1.5);
|
|
51
|
+
}
|
|
52
|
+
.guuey-chat-chip {
|
|
53
|
+
background: var(--guuey-chat-surface, var(--_guuey-chat-surface));
|
|
54
|
+
color: var(--guuey-chat-ink, var(--_guuey-chat-ink));
|
|
55
|
+
border: 1px solid var(--guuey-chat-ink-muted);
|
|
56
|
+
border-radius: var(--guuey-chat-radius, var(--_guuey-chat-radius));
|
|
57
|
+
padding: 6px 12px;
|
|
58
|
+
font-size: 0.85em;
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
text-align: start;
|
|
61
|
+
}
|
|
62
|
+
.guuey-chat-chip:hover {
|
|
63
|
+
border-color: var(--guuey-chat-ink, var(--_guuey-chat-ink));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* ── forget-this-device (guuey#526) — quiet, right-aligned, two-tap. ── */
|
|
67
|
+
.guuey-chat-clear-row {
|
|
68
|
+
display: flex;
|
|
69
|
+
justify-content: flex-end;
|
|
70
|
+
padding: 0 calc(var(--guuey-chat-gap) * 1.5);
|
|
71
|
+
}
|
|
72
|
+
.guuey-chat-clear {
|
|
73
|
+
background: none;
|
|
74
|
+
border: none;
|
|
75
|
+
padding: 2px 4px;
|
|
76
|
+
font-size: 0.8em;
|
|
77
|
+
color: var(--guuey-chat-ink-muted);
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
}
|
|
80
|
+
.guuey-chat-clear-armed {
|
|
81
|
+
color: var(--guuey-chat-error);
|
|
82
|
+
font-weight: 600;
|
|
83
|
+
}
|
|
84
|
+
|
|
43
85
|
/* ── ui/open-link disclosure (guuey#522) — the URL is SHOWN before any
|
|
44
86
|
navigation; Open is the human's own anchor click. ── */
|
|
45
87
|
.guuey-chat-link-ask {
|
|
@@ -123,6 +165,14 @@
|
|
|
123
165
|
font-size: inherit;
|
|
124
166
|
}
|
|
125
167
|
|
|
168
|
+
/* Links (guuey#528): the one text class with its own token. The neutral
|
|
169
|
+
default equals ink (underline alone distinguishes — native), so an
|
|
170
|
+
unthemed embed stays monochrome; a brand states its link color once
|
|
171
|
+
(theme or the host CSS-var channel, composing per #521's model). */
|
|
172
|
+
.guuey-chat a {
|
|
173
|
+
color: var(--guuey-chat-link, var(--_guuey-chat-link, inherit));
|
|
174
|
+
}
|
|
175
|
+
|
|
126
176
|
/* ── R1 assistant text ── */
|
|
127
177
|
.guuey-chat-text {
|
|
128
178
|
align-self: flex-start;
|
|
@@ -152,6 +202,8 @@
|
|
|
152
202
|
.guuey-chat-text p + p,
|
|
153
203
|
.guuey-chat-text pre + p,
|
|
154
204
|
.guuey-chat-text p + pre,
|
|
205
|
+
.guuey-chat-text .guuey-chat-code-wrap + p,
|
|
206
|
+
.guuey-chat-text p + .guuey-chat-code-wrap,
|
|
155
207
|
.guuey-chat-text ul + p,
|
|
156
208
|
.guuey-chat-text p + ul,
|
|
157
209
|
.guuey-chat-text p + ol {
|
|
@@ -177,6 +229,39 @@
|
|
|
177
229
|
padding: 8px 10px;
|
|
178
230
|
overflow-x: auto;
|
|
179
231
|
}
|
|
232
|
+
/* The fence's copy affordance (guuey#529): hover-reveal on pointer
|
|
233
|
+
devices, persistent on touch — the common grammar. Tokens ride the
|
|
234
|
+
composable channel like everything else. */
|
|
235
|
+
.guuey-chat-code-wrap {
|
|
236
|
+
position: relative;
|
|
237
|
+
}
|
|
238
|
+
.guuey-chat-code-copy {
|
|
239
|
+
position: absolute;
|
|
240
|
+
top: 5px;
|
|
241
|
+
right: 5px;
|
|
242
|
+
padding: 2px 8px;
|
|
243
|
+
font: 600 11px/1.6 inherit;
|
|
244
|
+
border: 1px solid color-mix(in srgb, var(--guuey-chat-ink, var(--_guuey-chat-ink)) 15%, transparent);
|
|
245
|
+
border-radius: 6px;
|
|
246
|
+
background: var(--guuey-chat-surface, var(--_guuey-chat-surface));
|
|
247
|
+
color: var(--guuey-chat-ink-muted, var(--_guuey-chat-ink-muted));
|
|
248
|
+
cursor: pointer;
|
|
249
|
+
opacity: 0;
|
|
250
|
+
}
|
|
251
|
+
.guuey-chat-code-wrap:hover .guuey-chat-code-copy,
|
|
252
|
+
.guuey-chat-code-copy:focus-visible {
|
|
253
|
+
opacity: 1;
|
|
254
|
+
}
|
|
255
|
+
@media (hover: none) {
|
|
256
|
+
.guuey-chat-code-copy {
|
|
257
|
+
opacity: 1;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
261
|
+
.guuey-chat-code-copy {
|
|
262
|
+
transition: opacity 120ms ease-out;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
180
265
|
.guuey-chat-verbatim {
|
|
181
266
|
white-space: pre-wrap;
|
|
182
267
|
margin: 0;
|