@guuey/chat 0.16.6 → 0.16.8
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/native/markdown.d.ts +12 -0
- package/dist/native/markdown.d.ts.map +1 -1
- package/dist/native/markdown.js +21 -0
- package/dist/plan.d.ts.map +1 -1
- package/dist/plan.js +5 -1
- package/dist/react/guuey-chat.d.ts.map +1 -1
- package/dist/react/guuey-chat.js +11 -4
- package/dist/react/markdown.d.ts +9 -0
- package/dist/react/markdown.d.ts.map +1 -1
- package/dist/react/markdown.js +13 -1
- package/dist/richtext-table.d.ts +26 -0
- package/dist/richtext-table.d.ts.map +1 -0
- package/dist/richtext-table.js +11 -0
- package/package.json +5 -5
- package/src/native/markdown.tsx +57 -0
- package/src/plan.ts +5 -1
- package/src/react/guuey-chat.tsx +11 -4
- package/src/react/markdown.tsx +38 -0
- package/src/richtext-table.ts +30 -0
- package/styles.css +19 -0
|
@@ -20,6 +20,18 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import type { ReactNode } from "react";
|
|
22
22
|
import type { NativeChatTokens } from "./theme-native.js";
|
|
23
|
+
import { type RichTextTableBlock } from "../richtext-table.js";
|
|
24
|
+
/**
|
|
25
|
+
* The native table projection (guuey#370): header row bold with a
|
|
26
|
+
* separator, body rows as flex rows, per-column alignment mapped to RN
|
|
27
|
+
* textAlign. Exported for tests; not part of the package surface.
|
|
28
|
+
*/
|
|
29
|
+
export declare function NativeTableBlock({ block, color, tokens, trailing, }: {
|
|
30
|
+
block: RichTextTableBlock;
|
|
31
|
+
color: string;
|
|
32
|
+
tokens: NativeChatTokens;
|
|
33
|
+
trailing?: ReactNode;
|
|
34
|
+
}): ReactNode;
|
|
23
35
|
/** Sanitized markdown → themed RN elements (see the module docblock). */
|
|
24
36
|
export declare function NativeMarkdown({ text, color, tokens, trailing, }: {
|
|
25
37
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/native/markdown.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/native/markdown.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAwJlF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,KAAK,EACL,MAAM,EACN,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,GAAG,SAAS,CAqCZ;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,KAAK,EACL,MAAM,EACN,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,gBAAgB,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,GAAG,SAAS,CAeZ"}
|
package/dist/native/markdown.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Linking, Text, View } from "react-native";
|
|
3
3
|
import { parseRichText, } from "@silverprotocol/richtext";
|
|
4
|
+
import { normalizeTableRow } from "../richtext-table.js";
|
|
4
5
|
function InlineRuns({ nodes, color, tokens, bold, italic, }) {
|
|
5
6
|
return nodes.map((node, i) => {
|
|
6
7
|
const baseStyle = {
|
|
@@ -43,6 +44,8 @@ function InlineRuns({ nodes, color, tokens, bold, italic, }) {
|
|
|
43
44
|
}
|
|
44
45
|
function BlockView({ block, color, tokens, trailing, }) {
|
|
45
46
|
switch (block.type) {
|
|
47
|
+
case "table":
|
|
48
|
+
return _jsx(NativeTableBlock, { block: block, color: color, tokens: tokens, trailing: trailing });
|
|
46
49
|
case "paragraph":
|
|
47
50
|
return (_jsxs(Text, { style: { fontSize: tokens.fontSize, lineHeight: Math.round(tokens.fontSize * 1.45) }, children: [_jsx(InlineRuns, { nodes: block.children, color: color, tokens: tokens }), trailing] }));
|
|
48
51
|
case "heading":
|
|
@@ -62,6 +65,24 @@ function BlockView({ block, color, tokens, trailing, }) {
|
|
|
62
65
|
return (_jsx(View, { style: { gap: 2 }, children: block.items.map((item, j) => (_jsxs(View, { style: { flexDirection: "row" }, children: [_jsx(Text, { style: { color, fontSize: tokens.fontSize, fontFamily: tokens.fontFamily }, children: block.ordered ? `${(block.start ?? 1) + j}. ` : "• " }), _jsxs(Text, { style: { flexShrink: 1, fontSize: tokens.fontSize, lineHeight: Math.round(tokens.fontSize * 1.45) }, children: [_jsx(InlineRuns, { nodes: item.children, color: color, tokens: tokens }), j === block.items.length - 1 ? trailing : null] })] }, j))) }));
|
|
63
66
|
}
|
|
64
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* The native table projection (guuey#370): header row bold with a
|
|
70
|
+
* separator, body rows as flex rows, per-column alignment mapped to RN
|
|
71
|
+
* textAlign. Exported for tests; not part of the package surface.
|
|
72
|
+
*/
|
|
73
|
+
export function NativeTableBlock({ block, color, tokens, trailing, }) {
|
|
74
|
+
const columnCount = block.header.cells.length;
|
|
75
|
+
const cellStyle = (i) => ({
|
|
76
|
+
flex: 1,
|
|
77
|
+
...(block.align[i] !== undefined ? { textAlign: block.align[i] } : {}),
|
|
78
|
+
});
|
|
79
|
+
return (_jsxs(View, { style: { gap: 2 }, children: [_jsx(View, { style: {
|
|
80
|
+
flexDirection: "row",
|
|
81
|
+
borderBottomWidth: 1,
|
|
82
|
+
borderBottomColor: tokens.palette.canvasMuted,
|
|
83
|
+
paddingBottom: 2,
|
|
84
|
+
}, children: normalizeTableRow(block.header, columnCount).map((cell, i) => (_jsx(Text, { style: { ...cellStyle(i), color, fontSize: tokens.fontSize, fontWeight: "700" }, children: _jsx(InlineRuns, { nodes: cell.children, color: color, tokens: tokens, bold: true }) }, i))) }), block.rows.map((row, r) => (_jsx(View, { style: { flexDirection: "row" }, children: normalizeTableRow(row, columnCount).map((cell, i) => (_jsx(Text, { style: { ...cellStyle(i), fontSize: tokens.fontSize }, children: _jsx(InlineRuns, { nodes: cell.children, color: color, tokens: tokens }) }, i))) }, r))), trailing] }));
|
|
85
|
+
}
|
|
65
86
|
/** Sanitized markdown → themed RN elements (see the module docblock). */
|
|
66
87
|
export function NativeMarkdown({ text, color, tokens, trailing, }) {
|
|
67
88
|
const blocks = parseRichText(text);
|
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,CA+VhB;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
|
@@ -780,7 +780,11 @@ export function planTranscript(inputs, policy, overrides = {}) {
|
|
|
780
780
|
label: null,
|
|
781
781
|
diagnosis: mount === undefined ? null : (inputs.viewDiagnoses?.[key] ?? null),
|
|
782
782
|
attribution: null,
|
|
783
|
-
|
|
783
|
+
// guuey#402: the chip titles with the producing tool's humanized
|
|
784
|
+
// name once the read plane persists it (the platform half); absent
|
|
785
|
+
// keeps the generic fallback — pre-enabler rows are indistinguishable
|
|
786
|
+
// by construction, never by invention.
|
|
787
|
+
toolTitle: card.toolName !== undefined ? policy.tool.humanizeTitle(card.toolName) : null,
|
|
784
788
|
actionScope: scope,
|
|
785
789
|
};
|
|
786
790
|
view.label = viewLabel(view, policy);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guuey-chat.d.ts","sourceRoot":"","sources":["../../src/react/guuey-chat.tsx"],"names":[],"mappings":"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
|
|
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
|
@@ -131,7 +131,13 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
|
|
|
131
131
|
if (apiBaseUrl === undefined && (endpointUrl === undefined || endpointUrl === null)) {
|
|
132
132
|
return undefined;
|
|
133
133
|
}
|
|
134
|
-
|
|
134
|
+
// guuey#421 CLOSURE FIX (the live-capture find): this wrapper used to
|
|
135
|
+
// take only `resourceUri`, silently DROPPING the hints param — so the
|
|
136
|
+
// inner reader never learned `origin: "history"` and dialed the pod
|
|
137
|
+
// first on every old-conversation load (the 404 pair, warm/cold
|
|
138
|
+
// dependent). The #421 gate lived in agent-client all along; the
|
|
139
|
+
// kit-default wrapper starved it. Thread the hints through.
|
|
140
|
+
return async (resourceUri, hints) => {
|
|
135
141
|
const threadId = threadIdRef.current;
|
|
136
142
|
// Assembled per read: `createUiResourceReader` is a cheap closure, and
|
|
137
143
|
// the guest secret is re-resolved each call so a rotation takes
|
|
@@ -153,7 +159,7 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
|
|
|
153
159
|
...(getToken !== undefined ? { getAccessToken: getToken } : {}),
|
|
154
160
|
guestSecret: getGuest !== undefined ? getGuest() : null,
|
|
155
161
|
});
|
|
156
|
-
return read(resourceUri);
|
|
162
|
+
return read(resourceUri, hints);
|
|
157
163
|
};
|
|
158
164
|
}, [apiBaseUrl, endpointUrl]);
|
|
159
165
|
const effectiveReader = reader ?? defaultReader;
|
|
@@ -271,8 +277,9 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
|
|
|
271
277
|
// REAL result envelope and its #440 classifier grades honestly; the
|
|
272
278
|
// post-turn agent turn then starts through the ui/message doorbell
|
|
273
279
|
// (the sink below). The #356 staging seam remains a PUBLIC export
|
|
274
|
-
// (withActionStaging) for hosts that choose the composer-staging UX
|
|
275
|
-
//
|
|
280
|
+
// (withActionStaging) for hosts that choose the composer-staging UX;
|
|
281
|
+
// no first-party surface applies it any more (the widget converged on
|
|
282
|
+
// this relay+doorbell path in guuey#404).
|
|
276
283
|
const stagedDefaultOnCallTool = defaultOnCallTool;
|
|
277
284
|
// The ui/message sink (guuey#422): the view hands the host role-user
|
|
278
285
|
// content (ggui's #440 doorbell — the model directive that drains a
|
package/dist/react/markdown.d.ts
CHANGED
|
@@ -25,6 +25,15 @@
|
|
|
25
25
|
* renders as formatted-so-far.
|
|
26
26
|
*/
|
|
27
27
|
import type { ReactNode } from "react";
|
|
28
|
+
import { type RichTextTableBlock } from "../richtext-table.js";
|
|
29
|
+
/**
|
|
30
|
+
* The table arm (guuey#370 — sdk#23's node). Cells render through the
|
|
31
|
+
* SAME `<Inline>` sanitizer path as every other run. Exported for tests;
|
|
32
|
+
* not part of the package surface.
|
|
33
|
+
*/
|
|
34
|
+
export declare function TableBlock({ block }: {
|
|
35
|
+
block: RichTextTableBlock;
|
|
36
|
+
}): ReactNode;
|
|
28
37
|
/** Sanitized markdown → React elements (see the module docblock). */
|
|
29
38
|
export declare function Markdown({ text }: {
|
|
30
39
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/react/markdown.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/react/markdown.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AA0ClF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,kBAAkB,CAAA;CAAE,GAAG,SAAS,CA4B9E;AAmCD,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,5 +1,6 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { parseRichText, } from "@silverprotocol/richtext";
|
|
3
|
+
import { normalizeTableRow } from "../richtext-table.js";
|
|
3
4
|
function Inline({ nodes }) {
|
|
4
5
|
return nodes.map((node, i) => {
|
|
5
6
|
switch (node.type) {
|
|
@@ -20,8 +21,19 @@ function Inline({ nodes }) {
|
|
|
20
21
|
}
|
|
21
22
|
});
|
|
22
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* The table arm (guuey#370 — sdk#23's node). Cells render through the
|
|
26
|
+
* SAME `<Inline>` sanitizer path as every other run. Exported for tests;
|
|
27
|
+
* not part of the package surface.
|
|
28
|
+
*/
|
|
29
|
+
export function TableBlock({ block }) {
|
|
30
|
+
const columnCount = block.header.cells.length;
|
|
31
|
+
return (_jsx("div", { className: "guuey-chat-table-wrap", children: _jsxs("table", { className: "guuey-chat-table", children: [_jsx("thead", { children: _jsx("tr", { children: normalizeTableRow(block.header, columnCount).map((cell, i) => (_jsx("th", { ...(block.align[i] !== undefined ? { style: { textAlign: block.align[i] } } : {}), children: _jsx(Inline, { nodes: cell.children }) }, i))) }) }), _jsx("tbody", { children: block.rows.map((row, r) => (_jsx("tr", { children: normalizeTableRow(row, columnCount).map((cell, i) => (_jsx("td", { ...(block.align[i] !== undefined ? { style: { textAlign: block.align[i] } } : {}), children: _jsx(Inline, { nodes: cell.children }) }, i))) }, r))) })] }) }));
|
|
32
|
+
}
|
|
23
33
|
function Block({ block }) {
|
|
24
34
|
switch (block.type) {
|
|
35
|
+
case "table":
|
|
36
|
+
return _jsx(TableBlock, { block: block });
|
|
25
37
|
case "paragraph":
|
|
26
38
|
return (_jsx("p", { children: _jsx(Inline, { nodes: block.children }) }));
|
|
27
39
|
case "heading":
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table rendering support (guuey#370 — sdk#23's vocabulary, live since
|
|
3
|
+
* `@silverprotocol/richtext@0.5.3`).
|
|
4
|
+
*
|
|
5
|
+
* The block type DERIVES from the upstream union (strict-typing rule:
|
|
6
|
+
* the parser's types are the source of truth). History note: this module
|
|
7
|
+
* was born one cut earlier as a structural MIRROR + narrowing guard so
|
|
8
|
+
* both renderer arms could land BEFORE the bump (the renderers switch
|
|
9
|
+
* default-less on `block.type` — a bump without an arm would have
|
|
10
|
+
* rendered tables as NOTHING); with 0.5.3 pinned, the mirror and guard
|
|
11
|
+
* are deleted per the pre-launch one-contract rule and the arms moved
|
|
12
|
+
* into the switches proper.
|
|
13
|
+
*/
|
|
14
|
+
import type { RichTextBlock, RichTextTableCell } from "@silverprotocol/richtext";
|
|
15
|
+
export type RichTextTableBlock = Extract<RichTextBlock, {
|
|
16
|
+
type: "table";
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Renderer-side GFM normalization (defense in depth — the parser already
|
|
20
|
+
* pads/drops): every row exactly `columnCount` cells, short rows padded
|
|
21
|
+
* with empty-inline cells, excess dropped.
|
|
22
|
+
*/
|
|
23
|
+
export declare function normalizeTableRow(row: {
|
|
24
|
+
cells: RichTextTableCell[];
|
|
25
|
+
}, columnCount: number): RichTextTableCell[];
|
|
26
|
+
//# sourceMappingURL=richtext-table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"richtext-table.d.ts","sourceRoot":"","sources":["../src/richtext-table.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAEjF,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAE3E;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE;IAAE,KAAK,EAAE,iBAAiB,EAAE,CAAA;CAAE,EACnC,WAAW,EAAE,MAAM,GAClB,iBAAiB,EAAE,CAIrB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renderer-side GFM normalization (defense in depth — the parser already
|
|
3
|
+
* pads/drops): every row exactly `columnCount` cells, short rows padded
|
|
4
|
+
* with empty-inline cells, excess dropped.
|
|
5
|
+
*/
|
|
6
|
+
export function normalizeTableRow(row, columnCount) {
|
|
7
|
+
const cells = row.cells.slice(0, columnCount);
|
|
8
|
+
while (cells.length < columnCount)
|
|
9
|
+
cells.push({ children: [] });
|
|
10
|
+
return cells;
|
|
11
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guuey/chat",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.8",
|
|
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",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"./styles.css": "./styles.css"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@silverprotocol/core": "0.5.
|
|
40
|
-
"@silverprotocol/richtext": "0.5.
|
|
39
|
+
"@silverprotocol/core": "0.5.3",
|
|
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.8",
|
|
43
|
+
"@guuey/mcp-apps-host": "0.16.8"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"react": ">=18",
|
package/src/native/markdown.tsx
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
type RichTextInline,
|
|
27
27
|
} from "@silverprotocol/richtext";
|
|
28
28
|
import type { NativeChatTokens } from "./theme-native.js";
|
|
29
|
+
import { normalizeTableRow, type RichTextTableBlock } from "../richtext-table.js";
|
|
29
30
|
|
|
30
31
|
function InlineRuns({
|
|
31
32
|
nodes,
|
|
@@ -120,6 +121,8 @@ function BlockView({
|
|
|
120
121
|
trailing?: ReactNode;
|
|
121
122
|
}): ReactNode {
|
|
122
123
|
switch (block.type) {
|
|
124
|
+
case "table":
|
|
125
|
+
return <NativeTableBlock block={block} color={color} tokens={tokens} trailing={trailing} />;
|
|
123
126
|
case "paragraph":
|
|
124
127
|
return (
|
|
125
128
|
<Text style={{ fontSize: tokens.fontSize, lineHeight: Math.round(tokens.fontSize * 1.45) }}>
|
|
@@ -175,6 +178,60 @@ function BlockView({
|
|
|
175
178
|
}
|
|
176
179
|
}
|
|
177
180
|
|
|
181
|
+
/**
|
|
182
|
+
* The native table projection (guuey#370): header row bold with a
|
|
183
|
+
* separator, body rows as flex rows, per-column alignment mapped to RN
|
|
184
|
+
* textAlign. Exported for tests; not part of the package surface.
|
|
185
|
+
*/
|
|
186
|
+
export function NativeTableBlock({
|
|
187
|
+
block,
|
|
188
|
+
color,
|
|
189
|
+
tokens,
|
|
190
|
+
trailing,
|
|
191
|
+
}: {
|
|
192
|
+
block: RichTextTableBlock;
|
|
193
|
+
color: string;
|
|
194
|
+
tokens: NativeChatTokens;
|
|
195
|
+
trailing?: ReactNode;
|
|
196
|
+
}): ReactNode {
|
|
197
|
+
const columnCount = block.header.cells.length;
|
|
198
|
+
const cellStyle = (i: number) => ({
|
|
199
|
+
flex: 1,
|
|
200
|
+
...(block.align[i] !== undefined ? { textAlign: block.align[i] } : {}),
|
|
201
|
+
});
|
|
202
|
+
return (
|
|
203
|
+
<View style={{ gap: 2 }}>
|
|
204
|
+
<View
|
|
205
|
+
style={{
|
|
206
|
+
flexDirection: "row",
|
|
207
|
+
borderBottomWidth: 1,
|
|
208
|
+
borderBottomColor: tokens.palette.canvasMuted,
|
|
209
|
+
paddingBottom: 2,
|
|
210
|
+
}}
|
|
211
|
+
>
|
|
212
|
+
{normalizeTableRow(block.header, columnCount).map((cell, i) => (
|
|
213
|
+
<Text
|
|
214
|
+
key={i}
|
|
215
|
+
style={{ ...cellStyle(i), color, fontSize: tokens.fontSize, fontWeight: "700" }}
|
|
216
|
+
>
|
|
217
|
+
<InlineRuns nodes={cell.children} color={color} tokens={tokens} bold />
|
|
218
|
+
</Text>
|
|
219
|
+
))}
|
|
220
|
+
</View>
|
|
221
|
+
{block.rows.map((row, r) => (
|
|
222
|
+
<View key={r} style={{ flexDirection: "row" }}>
|
|
223
|
+
{normalizeTableRow(row, columnCount).map((cell, i) => (
|
|
224
|
+
<Text key={i} style={{ ...cellStyle(i), fontSize: tokens.fontSize }}>
|
|
225
|
+
<InlineRuns nodes={cell.children} color={color} tokens={tokens} />
|
|
226
|
+
</Text>
|
|
227
|
+
))}
|
|
228
|
+
</View>
|
|
229
|
+
))}
|
|
230
|
+
{trailing}
|
|
231
|
+
</View>
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
178
235
|
/** Sanitized markdown → themed RN elements (see the module docblock). */
|
|
179
236
|
export function NativeMarkdown({
|
|
180
237
|
text,
|
package/src/plan.ts
CHANGED
|
@@ -903,7 +903,11 @@ export function planTranscript(
|
|
|
903
903
|
label: null,
|
|
904
904
|
diagnosis: mount === undefined ? null : (inputs.viewDiagnoses?.[key] ?? null),
|
|
905
905
|
attribution: null,
|
|
906
|
-
|
|
906
|
+
// guuey#402: the chip titles with the producing tool's humanized
|
|
907
|
+
// name once the read plane persists it (the platform half); absent
|
|
908
|
+
// keeps the generic fallback — pre-enabler rows are indistinguishable
|
|
909
|
+
// by construction, never by invention.
|
|
910
|
+
toolTitle: card.toolName !== undefined ? policy.tool.humanizeTitle(card.toolName) : null,
|
|
907
911
|
actionScope: scope,
|
|
908
912
|
};
|
|
909
913
|
view.label = viewLabel(view, policy);
|
package/src/react/guuey-chat.tsx
CHANGED
|
@@ -394,7 +394,13 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
|
|
|
394
394
|
if (apiBaseUrl === undefined && (endpointUrl === undefined || endpointUrl === null)) {
|
|
395
395
|
return undefined;
|
|
396
396
|
}
|
|
397
|
-
|
|
397
|
+
// guuey#421 CLOSURE FIX (the live-capture find): this wrapper used to
|
|
398
|
+
// take only `resourceUri`, silently DROPPING the hints param — so the
|
|
399
|
+
// inner reader never learned `origin: "history"` and dialed the pod
|
|
400
|
+
// first on every old-conversation load (the 404 pair, warm/cold
|
|
401
|
+
// dependent). The #421 gate lived in agent-client all along; the
|
|
402
|
+
// kit-default wrapper starved it. Thread the hints through.
|
|
403
|
+
return async (resourceUri: string, hints?: Parameters<UiResourceReader>[1]) => {
|
|
398
404
|
const threadId = threadIdRef.current;
|
|
399
405
|
// Assembled per read: `createUiResourceReader` is a cheap closure, and
|
|
400
406
|
// the guest secret is re-resolved each call so a rotation takes
|
|
@@ -416,7 +422,7 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
|
|
|
416
422
|
...(getToken !== undefined ? { getAccessToken: getToken } : {}),
|
|
417
423
|
guestSecret: getGuest !== undefined ? getGuest() : null,
|
|
418
424
|
});
|
|
419
|
-
return read(resourceUri);
|
|
425
|
+
return read(resourceUri, hints);
|
|
420
426
|
};
|
|
421
427
|
}, [apiBaseUrl, endpointUrl]);
|
|
422
428
|
const effectiveReader = reader ?? defaultReader;
|
|
@@ -540,8 +546,9 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
|
|
|
540
546
|
// REAL result envelope and its #440 classifier grades honestly; the
|
|
541
547
|
// post-turn agent turn then starts through the ui/message doorbell
|
|
542
548
|
// (the sink below). The #356 staging seam remains a PUBLIC export
|
|
543
|
-
// (withActionStaging) for hosts that choose the composer-staging UX
|
|
544
|
-
//
|
|
549
|
+
// (withActionStaging) for hosts that choose the composer-staging UX;
|
|
550
|
+
// no first-party surface applies it any more (the widget converged on
|
|
551
|
+
// this relay+doorbell path in guuey#404).
|
|
545
552
|
const stagedDefaultOnCallTool = defaultOnCallTool;
|
|
546
553
|
|
|
547
554
|
// The ui/message sink (guuey#422): the view hands the host role-user
|
package/src/react/markdown.tsx
CHANGED
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
type RichTextBlock,
|
|
31
31
|
type RichTextInline,
|
|
32
32
|
} from "@silverprotocol/richtext";
|
|
33
|
+
import { normalizeTableRow, type RichTextTableBlock } from "../richtext-table.js";
|
|
33
34
|
|
|
34
35
|
function Inline({ nodes }: { nodes: RichTextInline[] }): ReactNode {
|
|
35
36
|
return nodes.map((node, i) => {
|
|
@@ -71,8 +72,45 @@ function Inline({ nodes }: { nodes: RichTextInline[] }): ReactNode {
|
|
|
71
72
|
});
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
/**
|
|
76
|
+
* The table arm (guuey#370 — sdk#23's node). Cells render through the
|
|
77
|
+
* SAME `<Inline>` sanitizer path as every other run. Exported for tests;
|
|
78
|
+
* not part of the package surface.
|
|
79
|
+
*/
|
|
80
|
+
export function TableBlock({ block }: { block: RichTextTableBlock }): ReactNode {
|
|
81
|
+
const columnCount = block.header.cells.length;
|
|
82
|
+
return (
|
|
83
|
+
<div className="guuey-chat-table-wrap">
|
|
84
|
+
<table className="guuey-chat-table">
|
|
85
|
+
<thead>
|
|
86
|
+
<tr>
|
|
87
|
+
{normalizeTableRow(block.header, columnCount).map((cell, i) => (
|
|
88
|
+
<th key={i} {...(block.align[i] !== undefined ? { style: { textAlign: block.align[i] } } : {})}>
|
|
89
|
+
<Inline nodes={cell.children} />
|
|
90
|
+
</th>
|
|
91
|
+
))}
|
|
92
|
+
</tr>
|
|
93
|
+
</thead>
|
|
94
|
+
<tbody>
|
|
95
|
+
{block.rows.map((row, r) => (
|
|
96
|
+
<tr key={r}>
|
|
97
|
+
{normalizeTableRow(row, columnCount).map((cell, i) => (
|
|
98
|
+
<td key={i} {...(block.align[i] !== undefined ? { style: { textAlign: block.align[i] } } : {})}>
|
|
99
|
+
<Inline nodes={cell.children} />
|
|
100
|
+
</td>
|
|
101
|
+
))}
|
|
102
|
+
</tr>
|
|
103
|
+
))}
|
|
104
|
+
</tbody>
|
|
105
|
+
</table>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
74
110
|
function Block({ block }: { block: RichTextBlock }): ReactNode {
|
|
75
111
|
switch (block.type) {
|
|
112
|
+
case "table":
|
|
113
|
+
return <TableBlock block={block} />;
|
|
76
114
|
case "paragraph":
|
|
77
115
|
return (
|
|
78
116
|
<p>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table rendering support (guuey#370 — sdk#23's vocabulary, live since
|
|
3
|
+
* `@silverprotocol/richtext@0.5.3`).
|
|
4
|
+
*
|
|
5
|
+
* The block type DERIVES from the upstream union (strict-typing rule:
|
|
6
|
+
* the parser's types are the source of truth). History note: this module
|
|
7
|
+
* was born one cut earlier as a structural MIRROR + narrowing guard so
|
|
8
|
+
* both renderer arms could land BEFORE the bump (the renderers switch
|
|
9
|
+
* default-less on `block.type` — a bump without an arm would have
|
|
10
|
+
* rendered tables as NOTHING); with 0.5.3 pinned, the mirror and guard
|
|
11
|
+
* are deleted per the pre-launch one-contract rule and the arms moved
|
|
12
|
+
* into the switches proper.
|
|
13
|
+
*/
|
|
14
|
+
import type { RichTextBlock, RichTextTableCell } from "@silverprotocol/richtext";
|
|
15
|
+
|
|
16
|
+
export type RichTextTableBlock = Extract<RichTextBlock, { type: "table" }>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Renderer-side GFM normalization (defense in depth — the parser already
|
|
20
|
+
* pads/drops): every row exactly `columnCount` cells, short rows padded
|
|
21
|
+
* with empty-inline cells, excess dropped.
|
|
22
|
+
*/
|
|
23
|
+
export function normalizeTableRow(
|
|
24
|
+
row: { cells: RichTextTableCell[] },
|
|
25
|
+
columnCount: number,
|
|
26
|
+
): RichTextTableCell[] {
|
|
27
|
+
const cells = row.cells.slice(0, columnCount);
|
|
28
|
+
while (cells.length < columnCount) cells.push({ children: [] });
|
|
29
|
+
return cells;
|
|
30
|
+
}
|
package/styles.css
CHANGED
|
@@ -40,6 +40,25 @@
|
|
|
40
40
|
margin-inline: auto;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/* ── R1 tables (guuey#370 — the sdk#23 node) ── */
|
|
44
|
+
.guuey-chat-table-wrap {
|
|
45
|
+
overflow-x: auto; /* wide tables scroll inside the bubble, never the page */
|
|
46
|
+
}
|
|
47
|
+
.guuey-chat-table {
|
|
48
|
+
border-collapse: collapse;
|
|
49
|
+
font-size: 0.95em;
|
|
50
|
+
}
|
|
51
|
+
.guuey-chat-table th,
|
|
52
|
+
.guuey-chat-table td {
|
|
53
|
+
border: 1px solid var(--guuey-chat-canvas-muted);
|
|
54
|
+
padding: 4px 8px;
|
|
55
|
+
text-align: left; /* per-column align from the AST overrides inline */
|
|
56
|
+
}
|
|
57
|
+
.guuey-chat-table th {
|
|
58
|
+
font-weight: 600;
|
|
59
|
+
background: var(--guuey-chat-canvas-muted);
|
|
60
|
+
}
|
|
61
|
+
|
|
43
62
|
/* ── R0 user ── */
|
|
44
63
|
.guuey-chat-user {
|
|
45
64
|
align-self: flex-end;
|