@guuey/chat 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  * rendering, tests, and RN bundlers consume the view-model directly.
12
12
  */
13
13
  export { newestViewKey, planTranscript, } from "./plan.js";
14
- export { calmPolicy, debugPolicy, type TranscriptPolicy, } from "./policy.js";
14
+ export { calmPolicy, type TranscriptPolicyOverrides, debugPolicy, type TranscriptPolicy, } from "./policy.js";
15
15
  export { defaultChatStrings, humanizeToolName, type ChatStrings, } from "./strings.js";
16
16
  export { transcriptInputsFromHistory } from "./history-inputs.js";
17
17
  export { buildHitlAnswer, grantModeDisplay, hitlPromptsFromFold, type HitlAnswerRecord, type HitlPromptAction, } from "./hitl.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EACL,aAAa,EACb,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,UAAU,EACV,WAAW,EACX,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,WAAW,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,cAAc,EACd,aAAa,EACb,QAAQ,EACR,cAAc,EACd,cAAc,EACd,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,OAAO,EACP,eAAe,EACf,cAAc,EACd,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,WAAW,EACX,eAAe,EACf,aAAa,EACb,WAAW,GACZ,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EACL,aAAa,EACb,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,UAAU,EACV,KAAK,yBAAyB,EAC9B,WAAW,EACX,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,WAAW,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,cAAc,EACd,aAAa,EACb,QAAQ,EACR,cAAc,EACd,cAAc,EACd,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,OAAO,EACP,eAAe,EACf,cAAc,EACd,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,WAAW,EACX,eAAe,EACf,aAAa,EACb,WAAW,GACZ,MAAM,YAAY,CAAC"}
package/dist/policy.d.ts CHANGED
@@ -115,8 +115,18 @@ export interface TranscriptPolicy {
115
115
  raw: boolean;
116
116
  };
117
117
  }
118
+ /** Deep-ish merge for the one level of nesting policies actually have. */
119
+ /**
120
+ * Per-section partial overrides — the shape `withOverrides` actually
121
+ * merges (each section spreads over its base), so the type tells the
122
+ * truth: `{ view: { presentation: 'chips' } }` is valid without
123
+ * restating the section's other fields (guuey#321 surfaced the lie).
124
+ */
125
+ export type TranscriptPolicyOverrides = {
126
+ [K in keyof TranscriptPolicy]?: Partial<TranscriptPolicy[K]>;
127
+ };
118
128
  /** The `calm` preset — the end-user default (spec §5). */
119
- export declare function calmPolicy(overrides?: Partial<TranscriptPolicy>): TranscriptPolicy;
129
+ export declare function calmPolicy(overrides?: TranscriptPolicyOverrides): TranscriptPolicy;
120
130
  /** The `debug` preset — the builder surface (Studio's test chat, spec §5). */
121
- export declare function debugPolicy(overrides?: Partial<TranscriptPolicy>): TranscriptPolicy;
131
+ export declare function debugPolicy(overrides?: TranscriptPolicyOverrides): TranscriptPolicy;
122
132
  //# sourceMappingURL=policy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtF,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,OAAO,EAAE,WAAW,CAAC;IACrB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU;IACV,WAAW,EAAE;QAAE,eAAe,EAAE,OAAO,CAAA;KAAE,CAAC;IAC1C,+EAA+E;IAC/E,IAAI,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5B,UAAU;IACV,SAAS,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,iBAAiB,EAAE,OAAO,CAAA;KAAE,CAAC;IACzD,UAAU;IACV,IAAI,EAAE;QACJ,eAAe,EAAE,OAAO,CAAC;QACzB,WAAW,EAAE,OAAO,CAAC;QACrB,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;KAC7C,CAAC;IACF,iEAAiE;IACjE,SAAS,EAAE;QAAE,SAAS,EAAE,MAAM,GAAG,KAAK,CAAA;KAAE,CAAC;IACzC,UAAU;IACV,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,OAAO,CAAC;QACrB,eAAe,EAAE,OAAO,CAAC;QACzB,+EAA+E;QAC/E,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF;;;;;;;OAOG;IACH,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,QAAQ,GAAG,OAAO,CAAA;KAAE,CAAC;IAC9D,UAAU;IACV,KAAK,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IACxD,UAAU;IACV,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IACxC,UAAU;IACV,SAAS,EAAE;QAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAAA;KAAE,CAAC;IACvC,WAAW;IACX,MAAM,EAAE;QAAE,SAAS,EAAE,QAAQ,GAAG,OAAO,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IAC/D;;;;;;;;;;;OAWG;IACH,KAAK,EAAE;QACL,QAAQ,EAAE,OAAO,CAAC;QAClB,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC7C,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAAC;KAC1C,CAAC;IACF,oFAAoF;IACpF,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,4EAA4E;IAC5E,MAAM,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IAC1B,WAAW;IACX,UAAU,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IAC9B,WAAW;IACX,OAAO,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,CAAC;CAC1C;AAoDD,0DAA0D;AAC1D,wBAAgB,UAAU,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAElF;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAcnF"}
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
package/dist/policy.js CHANGED
@@ -6,7 +6,6 @@
6
6
  * rest of the preset.
7
7
  */
8
8
  import { defaultChatStrings, humanizeToolName } from "./strings.js";
9
- /** Deep-ish merge for the one level of nesting policies actually have. */
10
9
  function withOverrides(base, overrides) {
11
10
  if (!overrides)
12
11
  return base;
@@ -48,7 +48,7 @@ import { type CSSProperties } from "react";
48
48
  import { type AgentInvokeAdapters } from "@guuey/agent-client";
49
49
  import type { AgHitlAnswer, AgPausedAsk } from "@silverprotocol/core";
50
50
  import type { UiResourceReader } from "@guuey/mcp-apps-host";
51
- import { type TranscriptPolicy } from "../policy.js";
51
+ import { type TranscriptPolicyOverrides } from "../policy.js";
52
52
  import { type ChatStrings } from "../strings.js";
53
53
  import { type GuueyChatTheme } from "../theme.js";
54
54
  import type { ChatDebugEvent, ErrorItem, PlanViewSummary, PromptItem, ViewRefItem } from "../types.js";
@@ -146,8 +146,12 @@ export interface GuueyChatProps {
146
146
  adapters?: AgentInvokeAdapters;
147
147
  /** Policy preset (spec §5). Default `"calm"`. */
148
148
  preset?: "calm" | "debug";
149
- /** Knob overrides applied on top of the preset (spec §3's columns). */
150
- policy?: Partial<TranscriptPolicy>;
149
+ /**
150
+ * Knob overrides applied on top of the preset (spec §3's columns) —
151
+ * per-SECTION partials (`{ view: { presentation: "chips" } }` needs no
152
+ * other view fields; guuey#321 made the type tell the merge's truth).
153
+ */
154
+ policy?: TranscriptPolicyOverrides;
151
155
  /** Per-slot component overrides (spec §3's override column). */
152
156
  components?: Partial<TranscriptComponents>;
153
157
  /** String overrides — merged over the preset's `ChatStrings` (§4.2). */
@@ -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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"}
@@ -48,7 +48,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
48
48
  import { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef, useState, } from "react";
49
49
  import { createUiActionRelay, createUiResourceReader, createWebAdapters, } from "@guuey/agent-client";
50
50
  import { useAgentInvoke } from "@guuey/agent-client/react";
51
- import { unavailableToolCallResult } from "@guuey/mcp-apps-host";
51
+ import { unavailableToolCallResult, withActionStaging } from "@guuey/mcp-apps-host";
52
52
  import { calmPolicy, debugPolicy } from "../policy.js";
53
53
  import { useStructuralIdentity } from "./structural-identity.js";
54
54
  import { defaultChatStrings } from "../strings.js";
@@ -205,6 +205,24 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
205
205
  // `viewProps.hostContext` keys win; `theme` is only defaulted. Hosts
206
206
  // mounting views DIRECTLY (a canvas over the roster) announce on their
207
207
  // own <GuueyView hostContext> — this covers the kit's own mounts.
208
+ // ── Composer ─────────────────────────────────────────────────────────
209
+ const [input, setInput] = useState("");
210
+ const inputRef = useRef(null);
211
+ // Browser form-field heuristics (a11y/autofill lints) flag a field with
212
+ // neither id nor name on every embedding site. useId keeps the id unique
213
+ // when several chats mount on one page — a static id would collide.
214
+ const composerId = useId();
215
+ const busy = invoke.status !== "ready";
216
+ const available = endpointUrl !== null;
217
+ const canSend = available && !busy && input.trim() !== "";
218
+ // ── The imperative seam (guuey#210) ──────────────────────────────────
219
+ // ONE stable handle for the component's whole life (hosts capture it in
220
+ // `onReady` and keep it), reading live truth through a ref so a call
221
+ // always sees the CURRENT gate — never a stale closure's.
222
+ const liveRef = useRef({ available, busy, invoke, onReady });
223
+ useEffect(() => {
224
+ liveRef.current = { available, busy, invoke, onReady };
225
+ });
208
226
  // The DEFAULT ACTION RELAY (guuey#335 — the founder-hit Confirm bug):
209
227
  // pod-then-persisted, built over the SAME identity as the reader, thread
210
228
  // read through the ref at CALL time. Without it, a kit-mounted render's
@@ -242,10 +260,27 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
242
260
  byteSize: JSON.stringify(params)?.length ?? 0,
243
261
  });
244
262
  }, []);
263
+ // Post-turn action STAGING (guuey#356 — the widget's ratified #198/#215/
264
+ // #218 policy, ONE copy in the kit): with no live turn, an allowlisted
265
+ // semantic card action stages its human-readable projection into the
266
+ // composer (append, never clobber — the staged-composer semantic) and the
267
+ // view hears the queued acceptance; everything else rides the relay path
268
+ // untouched. Rides viewSlotProps too, so canvas hosts get it for free.
269
+ const stagedDefaultOnCallTool = useMemo(() => {
270
+ if (defaultOnCallTool === undefined)
271
+ return undefined;
272
+ return withActionStaging(defaultOnCallTool, {
273
+ isTurnLive: () => liveRef.current.busy,
274
+ stage: (text) => {
275
+ setInput((prev) => (prev.trim() === "" ? text : `${prev.trimEnd()} ${text}`));
276
+ inputRef.current?.focus();
277
+ },
278
+ });
279
+ }, [defaultOnCallTool]);
245
280
  const effectiveViewProps = useMemo(() => viewPropsWithThemeAnnounce(viewProps, mode, {
246
- ...(defaultOnCallTool !== undefined ? { onCallTool: defaultOnCallTool } : {}),
281
+ ...(stagedDefaultOnCallTool !== undefined ? { onCallTool: stagedDefaultOnCallTool } : {}),
247
282
  onUpdateModelContext: defaultOnUpdateModelContext,
248
- }), [viewProps, mode, defaultOnCallTool, defaultOnUpdateModelContext]);
283
+ }), [viewProps, mode, stagedDefaultOnCallTool, defaultOnUpdateModelContext]);
249
284
  // The canvas-host door (guuey#335): a host mounting views DIRECTLY from
250
285
  // the roster (the chat-rail shell) needs the SAME slot wiring the kit's
251
286
  // inline mounts get — theme announce, action relay, context sink. Read
@@ -256,29 +291,11 @@ export const GuueyChat = forwardRef(function GuueyChat(props, ref) {
256
291
  staticSlotPropsRef.current =
257
292
  typeof effectiveViewProps === "function"
258
293
  ? {
259
- ...(defaultOnCallTool !== undefined ? { onCallTool: defaultOnCallTool } : {}),
294
+ ...(stagedDefaultOnCallTool !== undefined ? { onCallTool: stagedDefaultOnCallTool } : {}),
260
295
  onUpdateModelContext: defaultOnUpdateModelContext,
261
296
  hostContext: { theme: mode },
262
297
  }
263
298
  : (effectiveViewProps ?? {});
264
- // ── Composer ─────────────────────────────────────────────────────────
265
- const [input, setInput] = useState("");
266
- const inputRef = useRef(null);
267
- // Browser form-field heuristics (a11y/autofill lints) flag a field with
268
- // neither id nor name on every embedding site. useId keeps the id unique
269
- // when several chats mount on one page — a static id would collide.
270
- const composerId = useId();
271
- const busy = invoke.status !== "ready";
272
- const available = endpointUrl !== null;
273
- const canSend = available && !busy && input.trim() !== "";
274
- // ── The imperative seam (guuey#210) ──────────────────────────────────
275
- // ONE stable handle for the component's whole life (hosts capture it in
276
- // `onReady` and keep it), reading live truth through a ref so a call
277
- // always sees the CURRENT gate — never a stale closure's.
278
- const liveRef = useRef({ available, busy, invoke, onReady });
279
- useEffect(() => {
280
- liveRef.current = { available, busy, invoke, onReady };
281
- });
282
299
  const handle = useMemo(() => ({
283
300
  send: (text) => {
284
301
  const live = liveRef.current;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guuey/chat",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
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.1",
40
40
  "@silverprotocol/richtext": "0.5.1",
41
41
  "zod": "^4.3.6",
42
- "@guuey/agent-client": "0.13.0",
43
- "@guuey/mcp-apps-host": "0.13.0"
42
+ "@guuey/agent-client": "0.14.0",
43
+ "@guuey/mcp-apps-host": "0.14.0"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "react": ">=18",
@@ -65,7 +65,7 @@
65
65
  "react-dom": "^19.0.0",
66
66
  "react-native": "0.81.5",
67
67
  "typescript": "^5.0.0",
68
- "vitest": "^3.0.0"
68
+ "vitest": "^3.2.7"
69
69
  },
70
70
  "publishConfig": {
71
71
  "access": "public"
package/src/index.ts CHANGED
@@ -16,6 +16,7 @@ export {
16
16
  } from "./plan.js";
17
17
  export {
18
18
  calmPolicy,
19
+ type TranscriptPolicyOverrides,
19
20
  debugPolicy,
20
21
  type TranscriptPolicy,
21
22
  } from "./policy.js";
package/src/policy.ts CHANGED
@@ -85,7 +85,17 @@ export interface TranscriptPolicy {
85
85
  }
86
86
 
87
87
  /** Deep-ish merge for the one level of nesting policies actually have. */
88
- function withOverrides(base: TranscriptPolicy, overrides?: Partial<TranscriptPolicy>): TranscriptPolicy {
88
+ /**
89
+ * Per-section partial overrides — the shape `withOverrides` actually
90
+ * merges (each section spreads over its base), so the type tells the
91
+ * truth: `{ view: { presentation: 'chips' } }` is valid without
92
+ * restating the section's other fields (guuey#321 surfaced the lie).
93
+ */
94
+ export type TranscriptPolicyOverrides = {
95
+ [K in keyof TranscriptPolicy]?: Partial<TranscriptPolicy[K]>;
96
+ };
97
+
98
+ function withOverrides(base: TranscriptPolicy, overrides?: TranscriptPolicyOverrides): TranscriptPolicy {
89
99
  if (!overrides) return base;
90
100
  return {
91
101
  ...base,
@@ -135,12 +145,12 @@ function calmBase(): TranscriptPolicy {
135
145
  }
136
146
 
137
147
  /** The `calm` preset — the end-user default (spec §5). */
138
- export function calmPolicy(overrides?: Partial<TranscriptPolicy>): TranscriptPolicy {
148
+ export function calmPolicy(overrides?: TranscriptPolicyOverrides): TranscriptPolicy {
139
149
  return withOverrides(calmBase(), overrides);
140
150
  }
141
151
 
142
152
  /** The `debug` preset — the builder surface (Studio's test chat, spec §5). */
143
- export function debugPolicy(overrides?: Partial<TranscriptPolicy>): TranscriptPolicy {
153
+ export function debugPolicy(overrides?: TranscriptPolicyOverrides): TranscriptPolicy {
144
154
  const base = calmBase();
145
155
  const debug: TranscriptPolicy = {
146
156
  ...base,
@@ -64,9 +64,9 @@ import {
64
64
  } from "@guuey/agent-client";
65
65
  import type { AgHitlAnswer, AgPausedAsk } from "@silverprotocol/core";
66
66
  import { useAgentInvoke } from "@guuey/agent-client/react";
67
- import { unavailableToolCallResult } from "@guuey/mcp-apps-host";
67
+ import { unavailableToolCallResult, withActionStaging } from "@guuey/mcp-apps-host";
68
68
  import type { McpToolCallResult, UiActionRequest, UiResourceReader } from "@guuey/mcp-apps-host";
69
- import { calmPolicy, debugPolicy, type TranscriptPolicy } from "../policy.js";
69
+ import { calmPolicy, debugPolicy, type TranscriptPolicyOverrides } from "../policy.js";
70
70
  import { useStructuralIdentity } from "./structural-identity.js";
71
71
  import { defaultChatStrings, type ChatStrings } from "../strings.js";
72
72
  import { DEFAULT_CHAT_THEME, type GuueyChatTheme } from "../theme.js";
@@ -192,8 +192,12 @@ export interface GuueyChatProps {
192
192
  adapters?: AgentInvokeAdapters;
193
193
  /** Policy preset (spec §5). Default `"calm"`. */
194
194
  preset?: "calm" | "debug";
195
- /** Knob overrides applied on top of the preset (spec §3's columns). */
196
- policy?: Partial<TranscriptPolicy>;
195
+ /**
196
+ * Knob overrides applied on top of the preset (spec §3's columns) —
197
+ * per-SECTION partials (`{ view: { presentation: "chips" } }` needs no
198
+ * other view fields; guuey#321 made the type tell the merge's truth).
199
+ */
200
+ policy?: TranscriptPolicyOverrides;
197
201
  /** Per-slot component overrides (spec §3's override column). */
198
202
  components?: Partial<TranscriptComponents>;
199
203
  /** String overrides — merged over the preset's `ChatStrings` (§4.2). */
@@ -443,6 +447,26 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
443
447
  // `viewProps.hostContext` keys win; `theme` is only defaulted. Hosts
444
448
  // mounting views DIRECTLY (a canvas over the roster) announce on their
445
449
  // own <GuueyView hostContext> — this covers the kit's own mounts.
450
+ // ── Composer ─────────────────────────────────────────────────────────
451
+ const [input, setInput] = useState("");
452
+ const inputRef = useRef<HTMLTextAreaElement | null>(null);
453
+ // Browser form-field heuristics (a11y/autofill lints) flag a field with
454
+ // neither id nor name on every embedding site. useId keeps the id unique
455
+ // when several chats mount on one page — a static id would collide.
456
+ const composerId = useId();
457
+ const busy = invoke.status !== "ready";
458
+ const available = endpointUrl !== null;
459
+ const canSend = available && !busy && input.trim() !== "";
460
+
461
+ // ── The imperative seam (guuey#210) ──────────────────────────────────
462
+ // ONE stable handle for the component's whole life (hosts capture it in
463
+ // `onReady` and keep it), reading live truth through a ref so a call
464
+ // always sees the CURRENT gate — never a stale closure's.
465
+ const liveRef = useRef({ available, busy, invoke, onReady });
466
+ useEffect(() => {
467
+ liveRef.current = { available, busy, invoke, onReady };
468
+ });
469
+
446
470
  // The DEFAULT ACTION RELAY (guuey#335 — the founder-hit Confirm bug):
447
471
  // pod-then-persisted, built over the SAME identity as the reader, thread
448
472
  // read through the ref at CALL time. Without it, a kit-mounted render's
@@ -480,13 +504,32 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
480
504
  });
481
505
  }, []);
482
506
 
507
+ // Post-turn action STAGING (guuey#356 — the widget's ratified #198/#215/
508
+ // #218 policy, ONE copy in the kit): with no live turn, an allowlisted
509
+ // semantic card action stages its human-readable projection into the
510
+ // composer (append, never clobber — the staged-composer semantic) and the
511
+ // view hears the queued acceptance; everything else rides the relay path
512
+ // untouched. Rides viewSlotProps too, so canvas hosts get it for free.
513
+ const stagedDefaultOnCallTool = useMemo<
514
+ ((request: UiActionRequest) => Promise<McpToolCallResult>) | undefined
515
+ >(() => {
516
+ if (defaultOnCallTool === undefined) return undefined;
517
+ return withActionStaging(defaultOnCallTool, {
518
+ isTurnLive: () => liveRef.current.busy,
519
+ stage: (text) => {
520
+ setInput((prev) => (prev.trim() === "" ? text : `${prev.trimEnd()} ${text}`));
521
+ inputRef.current?.focus();
522
+ },
523
+ });
524
+ }, [defaultOnCallTool]);
525
+
483
526
  const effectiveViewProps = useMemo<TranscriptItemContext["viewProps"]>(
484
527
  () =>
485
528
  viewPropsWithThemeAnnounce(viewProps, mode, {
486
- ...(defaultOnCallTool !== undefined ? { onCallTool: defaultOnCallTool } : {}),
529
+ ...(stagedDefaultOnCallTool !== undefined ? { onCallTool: stagedDefaultOnCallTool } : {}),
487
530
  onUpdateModelContext: defaultOnUpdateModelContext,
488
531
  }),
489
- [viewProps, mode, defaultOnCallTool, defaultOnUpdateModelContext],
532
+ [viewProps, mode, stagedDefaultOnCallTool, defaultOnUpdateModelContext],
490
533
  );
491
534
 
492
535
  // The canvas-host door (guuey#335): a host mounting views DIRECTLY from
@@ -499,32 +542,12 @@ export const GuueyChat = forwardRef<GuueyChatHandle, GuueyChatProps>(function Gu
499
542
  staticSlotPropsRef.current =
500
543
  typeof effectiveViewProps === "function"
501
544
  ? {
502
- ...(defaultOnCallTool !== undefined ? { onCallTool: defaultOnCallTool } : {}),
545
+ ...(stagedDefaultOnCallTool !== undefined ? { onCallTool: stagedDefaultOnCallTool } : {}),
503
546
  onUpdateModelContext: defaultOnUpdateModelContext,
504
547
  hostContext: { theme: mode },
505
548
  }
506
549
  : (effectiveViewProps ?? {});
507
550
 
508
- // ── Composer ─────────────────────────────────────────────────────────
509
- const [input, setInput] = useState("");
510
- const inputRef = useRef<HTMLTextAreaElement | null>(null);
511
- // Browser form-field heuristics (a11y/autofill lints) flag a field with
512
- // neither id nor name on every embedding site. useId keeps the id unique
513
- // when several chats mount on one page — a static id would collide.
514
- const composerId = useId();
515
- const busy = invoke.status !== "ready";
516
- const available = endpointUrl !== null;
517
- const canSend = available && !busy && input.trim() !== "";
518
-
519
- // ── The imperative seam (guuey#210) ──────────────────────────────────
520
- // ONE stable handle for the component's whole life (hosts capture it in
521
- // `onReady` and keep it), reading live truth through a ref so a call
522
- // always sees the CURRENT gate — never a stale closure's.
523
- const liveRef = useRef({ available, busy, invoke, onReady });
524
- useEffect(() => {
525
- liveRef.current = { available, busy, invoke, onReady };
526
- });
527
-
528
551
  const handle = useMemo<GuueyChatHandle>(
529
552
  () => ({
530
553
  send: (text: string): boolean => {