@guuey/chat 0.16.8 → 0.16.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/plan.d.ts.map +1 -1
- package/dist/plan.js +28 -7
- package/dist/react/components.d.ts +1 -1
- package/dist/react/components.d.ts.map +1 -1
- package/dist/react/guuey-chat.d.ts +69 -1
- package/dist/react/guuey-chat.d.ts.map +1 -1
- package/dist/react/guuey-chat.js +116 -6
- package/dist/react/markdown.d.ts +0 -26
- package/dist/react/markdown.d.ts.map +1 -1
- package/dist/react/markdown.js +115 -2
- package/dist/react/theme-css.d.ts +8 -0
- package/dist/react/theme-css.d.ts.map +1 -1
- package/dist/react/theme-css.js +24 -13
- package/dist/react/transcript.d.ts +8 -0
- package/dist/react/transcript.d.ts.map +1 -1
- package/dist/react/transcript.js +2 -2
- package/dist/strings.d.ts +19 -0
- package/dist/strings.d.ts.map +1 -1
- package/dist/strings.js +6 -0
- package/dist/theme.d.ts +28 -0
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +67 -2
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +1 -0
- package/src/plan.ts +27 -8
- package/src/react/components.tsx +1 -0
- package/src/react/guuey-chat.tsx +237 -2
- package/src/react/markdown.tsx +104 -2
- package/src/react/theme-css.ts +24 -13
- package/src/react/transcript.tsx +10 -1
- package/src/strings.ts +30 -0
- package/src/theme.ts +71 -2
- package/src/types.ts +14 -1
- package/styles.css +239 -100
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>;
|
|
@@ -130,12 +144,20 @@ export type GuueyChatTheme = z.infer<typeof GuueyChatTheme>;
|
|
|
130
144
|
* The brand-neutral-but-polished package default — the theme a builder gets
|
|
131
145
|
* before configuring anything, and the per-token fallback floor every other
|
|
132
146
|
* theme resolves against.
|
|
147
|
+
*
|
|
148
|
+
* The accent is MONOCHROME (= ink) by founder ruling (guuey#521): an
|
|
149
|
+
* unthemed embed must never carry a foreign accent into a host's product —
|
|
150
|
+
* the old `#2f6bff` blue made every zero-config embed read "off-the-shelf
|
|
151
|
+
* chat vendor" inside someone else's brand (#414's lesson, mirrored). Ink
|
|
152
|
+
* as accent means the send button and user pill render as neutral
|
|
153
|
+
* ink-on-canvas and disappear into any host; a brand accent is a CHOICE
|
|
154
|
+
* (theme prop or one `--guuey-chat-accent` CSS variable), never a default.
|
|
133
155
|
*/
|
|
134
156
|
export const DEFAULT_CHAT_THEME: GuueyChatTheme = {
|
|
135
157
|
name: "default",
|
|
136
158
|
colors: {
|
|
137
159
|
light: {
|
|
138
|
-
accent: "#
|
|
160
|
+
accent: "#111318",
|
|
139
161
|
onAccent: "#ffffff",
|
|
140
162
|
ink: "#111318",
|
|
141
163
|
inkMuted: "#5b6270",
|
|
@@ -143,9 +165,10 @@ export const DEFAULT_CHAT_THEME: GuueyChatTheme = {
|
|
|
143
165
|
canvas: "#f7f7f5",
|
|
144
166
|
canvasMuted: "#eceded",
|
|
145
167
|
error: "#d64545",
|
|
168
|
+
link: "#111318",
|
|
146
169
|
},
|
|
147
170
|
dark: {
|
|
148
|
-
accent: "#
|
|
171
|
+
accent: "#e8e9ee",
|
|
149
172
|
onAccent: "#0b0d12",
|
|
150
173
|
ink: "#e8e9ee",
|
|
151
174
|
inkMuted: "#9aa0ac",
|
|
@@ -153,6 +176,7 @@ export const DEFAULT_CHAT_THEME: GuueyChatTheme = {
|
|
|
153
176
|
canvas: "#0f1116",
|
|
154
177
|
canvasMuted: "#1b1e26",
|
|
155
178
|
error: "#ff6b6b",
|
|
179
|
+
link: "#e8e9ee",
|
|
156
180
|
},
|
|
157
181
|
},
|
|
158
182
|
typography: {},
|
|
@@ -178,6 +202,9 @@ export const GUUEY_CHAT_THEME: GuueyChatTheme = {
|
|
|
178
202
|
canvas: "#f6f5ee",
|
|
179
203
|
canvasMuted: "#ecebe0",
|
|
180
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",
|
|
181
208
|
},
|
|
182
209
|
dark: {
|
|
183
210
|
accent: "#b8ff3a",
|
|
@@ -188,6 +215,9 @@ export const GUUEY_CHAT_THEME: GuueyChatTheme = {
|
|
|
188
215
|
canvas: "#0e1014",
|
|
189
216
|
canvasMuted: "#1a1d24",
|
|
190
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",
|
|
191
221
|
},
|
|
192
222
|
},
|
|
193
223
|
typography: {},
|
|
@@ -221,6 +251,7 @@ const PALETTE_TOKENS = [
|
|
|
221
251
|
"canvas",
|
|
222
252
|
"canvasMuted",
|
|
223
253
|
"error",
|
|
254
|
+
"link",
|
|
224
255
|
] as const;
|
|
225
256
|
|
|
226
257
|
function mergePalette(
|
|
@@ -269,6 +300,44 @@ export function resolveTheme(
|
|
|
269
300
|
};
|
|
270
301
|
}
|
|
271
302
|
|
|
303
|
+
/**
|
|
304
|
+
* The court-override member a theme DOCUMENT may carry (guuey#519).
|
|
305
|
+
* Values are theme documents themselves (validated by `resolveTheme`'s own
|
|
306
|
+
* lenient parse at resolution time, so a partial or future-schema court
|
|
307
|
+
* entry degrades per-token like any stored theme).
|
|
308
|
+
*/
|
|
309
|
+
const CourtOverrides = z
|
|
310
|
+
.object({ courts: z.record(z.string(), z.unknown()).optional() })
|
|
311
|
+
.loose();
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Per-court theme resolution (guuey#519 — the #414 rule generalized).
|
|
315
|
+
*
|
|
316
|
+
* A theme document may carry `courts`: explicit per-court override
|
|
317
|
+
* documents keyed by serving court (`"guuey"`, `"ggui"`, …). A surface
|
|
318
|
+
* resolves ITS court: the court's override resolved per-token OVER the
|
|
319
|
+
* resolved base document when declared, else the base alone. **Brand is
|
|
320
|
+
* never a default** — an undeclared or unknown court gets the neutral
|
|
321
|
+
* base by construction, and readers that never heard of `courts`
|
|
322
|
+
* (lenient parsers projecting only known tokens) keep reading the base
|
|
323
|
+
* untouched, so no court can inherit another court's brand.
|
|
324
|
+
*
|
|
325
|
+
* Resolved themes are court-free: `courts` never survives resolution.
|
|
326
|
+
* NEVER throws; unparseable input degrades exactly as `resolveTheme`.
|
|
327
|
+
*/
|
|
328
|
+
export function resolveCourtTheme(
|
|
329
|
+
candidate: unknown,
|
|
330
|
+
court: string,
|
|
331
|
+
base: GuueyChatTheme = DEFAULT_CHAT_THEME,
|
|
332
|
+
): GuueyChatTheme {
|
|
333
|
+
const resolvedBase = resolveTheme(candidate, base);
|
|
334
|
+
const parsed = CourtOverrides.safeParse(candidate);
|
|
335
|
+
if (!parsed.success) return resolvedBase;
|
|
336
|
+
const override = parsed.data.courts?.[court];
|
|
337
|
+
if (override === undefined) return resolvedBase;
|
|
338
|
+
return resolveTheme(override, resolvedBase);
|
|
339
|
+
}
|
|
340
|
+
|
|
272
341
|
/** Slot-level merge of two ramp statements (candidate slots win per slot). */
|
|
273
342
|
function mergeRampSet(
|
|
274
343
|
base: GuueyChatRampSet | undefined,
|
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 —
|