@guuey/chat 0.4.0 → 0.6.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.
Files changed (69) hide show
  1. package/dist/hitl.d.ts +58 -0
  2. package/dist/hitl.d.ts.map +1 -0
  3. package/dist/hitl.js +81 -0
  4. package/dist/index.d.ts +3 -2
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -1
  7. package/dist/native/components.d.ts +110 -0
  8. package/dist/native/components.d.ts.map +1 -0
  9. package/dist/native/components.js +341 -0
  10. package/dist/native/markdown.d.ts +31 -0
  11. package/dist/native/markdown.d.ts.map +1 -0
  12. package/dist/native/markdown.js +69 -0
  13. package/dist/native/theme-native.d.ts +27 -0
  14. package/dist/native/theme-native.d.ts.map +1 -0
  15. package/dist/native/theme-native.js +28 -0
  16. package/dist/native/transcript.d.ts +48 -0
  17. package/dist/native/transcript.d.ts.map +1 -0
  18. package/dist/native/transcript.js +86 -0
  19. package/dist/native.d.ts +26 -0
  20. package/dist/native.d.ts.map +1 -0
  21. package/dist/native.js +27 -0
  22. package/dist/plan.d.ts +15 -0
  23. package/dist/plan.d.ts.map +1 -1
  24. package/dist/plan.js +211 -13
  25. package/dist/policy.d.ts +4 -0
  26. package/dist/policy.d.ts.map +1 -1
  27. package/dist/policy.js +2 -0
  28. package/dist/react/components.d.ts +42 -5
  29. package/dist/react/components.d.ts.map +1 -1
  30. package/dist/react/components.js +51 -1
  31. package/dist/react/guuey-chat.d.ts +62 -4
  32. package/dist/react/guuey-chat.d.ts.map +1 -1
  33. package/dist/react/guuey-chat.js +73 -8
  34. package/dist/react/transcript.d.ts +1 -1
  35. package/dist/react/transcript.d.ts.map +1 -1
  36. package/dist/react/transcript.js +2 -2
  37. package/dist/react/use-transcript.d.ts +21 -2
  38. package/dist/react/use-transcript.d.ts.map +1 -1
  39. package/dist/react/use-transcript.js +57 -3
  40. package/dist/react.d.ts +2 -2
  41. package/dist/react.d.ts.map +1 -1
  42. package/dist/react.js +1 -1
  43. package/dist/strings.d.ts +13 -0
  44. package/dist/strings.d.ts.map +1 -1
  45. package/dist/strings.js +8 -0
  46. package/dist/types.d.ts +146 -7
  47. package/dist/types.d.ts.map +1 -1
  48. package/package.json +18 -7
  49. package/src/corpus/README.md +13 -1
  50. package/src/corpus/__snapshots__/corpus.test.ts.snap +304 -0
  51. package/src/corpus/drive.ts +3 -3
  52. package/src/corpus/fixtures.ts +220 -1
  53. package/src/hitl.ts +103 -0
  54. package/src/index.ts +15 -0
  55. package/src/native/components.tsx +812 -0
  56. package/src/native/markdown.tsx +205 -0
  57. package/src/native/theme-native.ts +48 -0
  58. package/src/native/transcript.tsx +189 -0
  59. package/src/native.tsx +63 -0
  60. package/src/plan.ts +233 -20
  61. package/src/policy.ts +4 -0
  62. package/src/react/components.tsx +171 -8
  63. package/src/react/guuey-chat.tsx +143 -9
  64. package/src/react/transcript.tsx +4 -3
  65. package/src/react/use-transcript.ts +83 -5
  66. package/src/react.tsx +3 -1
  67. package/src/strings.ts +25 -0
  68. package/src/types.ts +152 -6
  69. package/styles.css +21 -0
@@ -0,0 +1,86 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * `<NativeTranscript>` — the plan walker + the §3.2 renderer obligations,
4
+ * restated over React Native's own mechanics:
5
+ *
6
+ * - **Scroll contract, the inverted way.** The list is an INVERTED
7
+ * FlatList over the reversed plan (the chat-app contract portal's
8
+ * agent-chat screen ratified — guuey#94/#100): content grows at the
9
+ * scroll ORIGIN, so "stick to bottom while streaming" and "never shift
10
+ * the viewport while the reader is up in history" hold by construction
11
+ * — no scrollTo calls during streaming, no re-pin race with content
12
+ * resize (an R6 card growing at the origin cannot move the reader's
13
+ * viewport). "Release on scroll-up" is likewise structural; the kit
14
+ * adds the jump-to-latest affordance when the reader has left the
15
+ * newest turn, and its scroll animation respects the platform
16
+ * reduce-motion setting.
17
+ * - **Windowing** is the list primitive's own virtualization — FlatList
18
+ * windows the DOM-equivalent natively; the plan's stable keys are the
19
+ * `keyExtractor`, so item identity survives streaming updates.
20
+ * - **Accessibility** lives on the item components (`components.tsx`).
21
+ *
22
+ * Platform chrome (keyboard insets, dismiss modes, dock scroll policies)
23
+ * stays HOST-OWNED: `listProps` passes the host's FlatList behavior
24
+ * through, with the kit composing `onScroll` so both the host's policy and
25
+ * the jump affordance see every event. The kit owns data/renderItem/keys/
26
+ * inversion — a host overriding those would be fighting the plan.
27
+ */
28
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
29
+ import { AccessibilityInfo, FlatList, Pressable, Text, View, } from "react-native";
30
+ import { DEFAULT_CHAT_THEME } from "../theme.js";
31
+ import { defaultChatStrings } from "../strings.js";
32
+ import { nativeTranscriptComponents, renderNativeItem, } from "./components.js";
33
+ import { resolveNativeTheme } from "./theme-native.js";
34
+ /** Offset (px) past which the reader counts as "up in history". */
35
+ const JUMP_THRESHOLD_PX = 160;
36
+ export function NativeTranscript(props) {
37
+ const { plan, components, strings = defaultChatStrings, theme = DEFAULT_CHAT_THEME, mode = "light", listProps, onToggle, onRetry, onPromptAction, onErrorAction, resolvedMounts, onViewPhase, onViewRef, } = props;
38
+ const tokens = useMemo(() => resolveNativeTheme(theme, mode), [theme, mode]);
39
+ const resolvedComponents = useMemo(() => ({ ...nativeTranscriptComponents, ...components }), [components]);
40
+ const ctx = useMemo(() => ({ strings, tokens, onToggle, onRetry, onPromptAction, onErrorAction, resolvedMounts, onViewPhase, onViewRef }), [strings, tokens, onToggle, onRetry, onPromptAction, onErrorAction, resolvedMounts, onViewPhase, onViewRef]);
41
+ // Inverted-list data: reversed plan, newest at index 0 (the visual
42
+ // bottom / scroll origin). Keys are the plan's stable keys.
43
+ const data = useMemo(() => [...plan.items].reverse(), [plan.items]);
44
+ // Reduce motion: the ONE animation the kit owns is the jump scroll.
45
+ const [reduceMotion, setReduceMotion] = useState(false);
46
+ useEffect(() => {
47
+ let alive = true;
48
+ void AccessibilityInfo.isReduceMotionEnabled().then((v) => {
49
+ if (alive)
50
+ setReduceMotion(v);
51
+ });
52
+ const sub = AccessibilityInfo.addEventListener("reduceMotionChanged", setReduceMotion);
53
+ return () => {
54
+ alive = false;
55
+ sub.remove();
56
+ };
57
+ }, []);
58
+ const listRef = useRef(null);
59
+ const [showJump, setShowJump] = useState(false);
60
+ const hostOnScroll = listProps?.onScroll;
61
+ const onScroll = useCallback((e) => {
62
+ // Inverted coordinates: offset 0 IS the newest turn.
63
+ setShowJump(e.nativeEvent.contentOffset.y > JUMP_THRESHOLD_PX);
64
+ hostOnScroll?.(e);
65
+ }, [hostOnScroll]);
66
+ const StatusComponent = resolvedComponents.status;
67
+ return (_jsxs(View, { style: { flex: 1, backgroundColor: tokens.palette.canvas }, children: [_jsx(FlatList, { ref: listRef, ...listProps, onScroll: onScroll, scrollEventThrottle: listProps?.scrollEventThrottle ?? 16,
68
+ // Inverted only while non-empty: an inverted ListEmptyComponent
69
+ // renders upside-down (RN gotcha — portal's receipt).
70
+ inverted: data.length > 0, data: data, keyExtractor: (item) => item.key, renderItem: ({ item }) => (_jsx(View, { style: { paddingVertical: tokens.gap / 2 }, children: renderNativeItem(item, resolvedComponents, ctx) })),
71
+ // Inverted list: the header renders at the VISUAL BOTTOM — where
72
+ // the live status line belongs.
73
+ ListHeaderComponent: plan.status !== null ? _jsx(StatusComponent, { item: plan.status, ctx: ctx }) : null }), showJump ? (_jsx(Pressable, { accessibilityRole: "button", onPress: () => {
74
+ setShowJump(false);
75
+ listRef.current?.scrollToOffset({ offset: 0, animated: !reduceMotion });
76
+ }, style: {
77
+ position: "absolute",
78
+ bottom: 12,
79
+ alignSelf: "center",
80
+ backgroundColor: tokens.palette.surface,
81
+ borderRadius: 999,
82
+ paddingHorizontal: 14,
83
+ paddingVertical: 8,
84
+ elevation: 3,
85
+ }, children: _jsx(Text, { style: { color: tokens.palette.ink, fontSize: tokens.fontSize - 2, fontFamily: tokens.fontFamily }, children: strings.jumpToLatest }) })) : null] }));
86
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * React Native entry point (`@guuey/chat/native`) — the RN renderer over
3
+ * the SAME headless view-model as `./react` (wave 3c, guuey#135).
4
+ *
5
+ * Zero duplication by construction: the view-model, policies, theme
6
+ * schema, and strings are the root subpath's exports, and the
7
+ * renderer-state hooks (`useTranscript`, `useTranscriptInputs`) are the
8
+ * SAME modules the web kit uses — they are React-generic (no DOM), so both
9
+ * arms share one implementation. Only the walk differs: RN primitives, the
10
+ * inverted-list scroll contract, and the schema's native theme projection
11
+ * (`resolveNativeTheme` — CSS custom properties are the web projection).
12
+ *
13
+ * The R6 default is the documented native default-gap: this tier ships
14
+ * WITHOUT a WebView dependency, so `view` is a required override (a
15
+ * labeled placeholder renders otherwise — never blank). See
16
+ * `native/components.tsx`.
17
+ *
18
+ * `react` and `react-native` are OPTIONAL peers — the root subpath stays
19
+ * importable everywhere; this arm loads only inside an RN runtime.
20
+ */
21
+ export { NativeTranscript, type NativeTranscriptProps, type NativeTranscriptListProps, } from "./native/transcript.js";
22
+ export { nativeTranscriptComponents, renderNativeItem, NativeUserMessage, NativeText, NativeReasoning, NativeTool, NativeToolGroup, NativeDataResult, NativeView, NativeViewRef, NativeMedia, NativeCode, NativeCitations, NativePrompt, NativeError, NativeHistoryBoundary, NativeCompaction, NativeUnknown, NativeStatus, type NativeTranscriptComponents, type NativeTranscriptItemContext, } from "./native/components.js";
23
+ export { NativeMarkdown } from "./native/markdown.js";
24
+ export { resolveNativeTheme, type NativeChatTokens, type NativeThemeMode, } from "./native/theme-native.js";
25
+ export { useTranscript, useTranscriptInputs, type UseTranscriptArgs, type UseTranscriptResult, type UseTranscriptInputsResult, } from "./react/use-transcript.js";
26
+ //# sourceMappingURL=native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EACL,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,GAC/B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,WAAW,EACX,UAAU,EACV,eAAe,EACf,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,GACjC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EACL,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,GAC/B,MAAM,2BAA2B,CAAC"}
package/dist/native.js ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * React Native entry point (`@guuey/chat/native`) — the RN renderer over
3
+ * the SAME headless view-model as `./react` (wave 3c, guuey#135).
4
+ *
5
+ * Zero duplication by construction: the view-model, policies, theme
6
+ * schema, and strings are the root subpath's exports, and the
7
+ * renderer-state hooks (`useTranscript`, `useTranscriptInputs`) are the
8
+ * SAME modules the web kit uses — they are React-generic (no DOM), so both
9
+ * arms share one implementation. Only the walk differs: RN primitives, the
10
+ * inverted-list scroll contract, and the schema's native theme projection
11
+ * (`resolveNativeTheme` — CSS custom properties are the web projection).
12
+ *
13
+ * The R6 default is the documented native default-gap: this tier ships
14
+ * WITHOUT a WebView dependency, so `view` is a required override (a
15
+ * labeled placeholder renders otherwise — never blank). See
16
+ * `native/components.tsx`.
17
+ *
18
+ * `react` and `react-native` are OPTIONAL peers — the root subpath stays
19
+ * importable everywhere; this arm loads only inside an RN runtime.
20
+ */
21
+ export { NativeTranscript, } from "./native/transcript.js";
22
+ export { nativeTranscriptComponents, renderNativeItem, NativeUserMessage, NativeText, NativeReasoning, NativeTool, NativeToolGroup, NativeDataResult, NativeView, NativeViewRef, NativeMedia, NativeCode, NativeCitations, NativePrompt, NativeError, NativeHistoryBoundary, NativeCompaction, NativeUnknown, NativeStatus, } from "./native/components.js";
23
+ export { NativeMarkdown } from "./native/markdown.js";
24
+ export { resolveNativeTheme, } from "./native/theme-native.js";
25
+ // The React-generic renderer-state owner + live assembler — shared with
26
+ // the web kit (one implementation, two walks).
27
+ export { useTranscript, useTranscriptInputs, } from "./react/use-transcript.js";
package/dist/plan.d.ts CHANGED
@@ -1,5 +1,20 @@
1
+ import { type ViewMount } from "@guuey/mcp-apps-host";
1
2
  import type { TranscriptPolicy } from "./policy.js";
2
3
  import type { TranscriptInputs, TranscriptOverrides, TranscriptPlan } from "./types.js";
3
4
  /** The one pure function (spec §7). */
4
5
  export declare function planTranscript(inputs: TranscriptInputs, policy: TranscriptPolicy, overrides?: TranscriptOverrides): TranscriptPlan;
6
+ /**
7
+ * The plan key of the NEWEST mountable view — what a "most recent card"
8
+ * stage (the widget's CanvasPane) will show, derived in the same family
9
+ * the plan's own emission uses: live fold mounts (transcript order, last
10
+ * wins) outrank history cards (ascending `seq`). `undefined` when nothing
11
+ * narrows to a mountable resource. Hosts pass the key back as
12
+ * `TranscriptInputs.promotedViewKey`; `channel` lets a host decline to
13
+ * promote a bare locator when no reader is wired (the stage would show
14
+ * nothing, and a chip must never point at an empty canvas).
15
+ */
16
+ export declare function newestViewKey(inputs: Pick<TranscriptInputs, "result" | "historyCards">): {
17
+ key: string;
18
+ channel: ViewMount["channel"];
19
+ } | undefined;
5
20
  //# sourceMappingURL=plan.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAQV,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EAGf,MAAM,YAAY,CAAC;AAoiBpB,uCAAuC;AACvC,wBAAgB,cAAc,CAC5B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,gBAAgB,EACxB,SAAS,GAAE,mBAAwB,GAClC,cAAc,CA4IhB"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AAkCA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACzG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,OAAO,KAAK,EASV,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EAIf,MAAM,YAAY,CAAC;AAslBpB,uCAAuC;AACvC,wBAAgB,cAAc,CAC5B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,gBAAgB,EACxB,SAAS,GAAE,mBAAwB,GAClC,cAAc,CA0QhB;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
@@ -1,4 +1,5 @@
1
1
  import { snapshotViewMount, toolResultViewMount, uiLocator } from "@guuey/mcp-apps-host";
2
+ import { grantModeDisplay } from "./hitl.js";
2
3
  /** R5's giant threshold: above this byte count the state is `giant`. */
3
4
  const GIANT_RESULT_BYTES = 16_384;
4
5
  /** Approximate byte size of a JSON value — deterministic, allocation-bounded. */
@@ -28,6 +29,13 @@ function resolveExpanded(key, policyDefault, overrides) {
28
29
  const override = overrides[key]?.expanded;
29
30
  return override ?? policyDefault;
30
31
  }
32
+ /** R16 notice text: the message's text blocks, joined (non-text blocks carry no notice prose). */
33
+ function noticeText(content) {
34
+ return content
35
+ .filter((b) => b.type === "text")
36
+ .map((b) => b.text)
37
+ .join("\n");
38
+ }
31
39
  function foldAssistantSources(result, inFlight, aborted) {
32
40
  // Real pod folds carry `tool-result` blocks in separate `role: "tool"`
33
41
  // messages between assistant turns (the production ggui-render capture is
@@ -35,21 +43,49 @@ function foldAssistantSources(result, inFlight, aborted) {
35
43
  // assistant-only filter orphans every call and drops every mount. A tool
36
44
  // message's blocks belong to the PRECEDING assistant slot's walk, exactly
37
45
  // the whole-fold message order the retired first-party renderers used.
46
+ //
47
+ // LIVE detection is turn-identity-based where the fold carries it: while
48
+ // a turn is in flight, an assistant message whose `turnId` maps to a turn
49
+ // record WITHOUT an `outcome` belongs to the open turn — settled earlier
50
+ // turns stay settled even mid-session (what makes the tail alignment
51
+ // below count them correctly). Nothing is live once the status is back to
52
+ // `ready`, whatever the records say (a fold that missed `turn.done` must
53
+ // not pin a settled turn open forever). Folds without turn identity (a
54
+ // hand-driven fold that never saw `turn.*` lifecycle) fall back to the
55
+ // last-source-is-live-iff-in-flight heuristic — the pre-refinement
56
+ // behaviour, kept so identity-less folds plan exactly as before.
57
+ const openTurns = new Set(result.turns.filter((t) => t.outcome === undefined).map((t) => t.turnId));
58
+ const hasTurnIdentity = result.messages.some((m) => m.role === "assistant" && m.turnId !== undefined);
38
59
  const sources = [];
60
+ const notices = [];
39
61
  for (const m of result.messages) {
40
62
  if (m.role === "assistant") {
41
- sources.push({ blocks: [...m.content], live: false, stopped: false });
63
+ sources.push({
64
+ blocks: [...m.content],
65
+ live: inFlight && hasTurnIdentity && m.turnId !== undefined && openTurns.has(m.turnId),
66
+ stopped: false,
67
+ });
42
68
  }
43
69
  else if (m.role === "tool" && sources.length > 0) {
44
70
  sources[sources.length - 1].blocks.push(...m.content);
45
71
  }
72
+ else if (m.role === "notice") {
73
+ // R16 (spec draft.2): a session annotation — a PEER row, never folded
74
+ // into assistant content; it anchors after the source it followed.
75
+ notices.push({
76
+ text: noticeText(m.content),
77
+ source: m.noticeSource ?? null,
78
+ afterSourceIndex: sources.length - 1,
79
+ });
80
+ }
46
81
  }
47
82
  const last = sources[sources.length - 1];
48
83
  if (last) {
49
- last.live = inFlight;
84
+ if (!hasTurnIdentity)
85
+ last.live = inFlight;
50
86
  last.stopped = aborted;
51
87
  }
52
- return sources;
88
+ return { sources, notices };
53
89
  }
54
90
  function flatAssistantSources(inputs, inFlight) {
55
91
  const settled = inputs.messages
@@ -521,11 +557,74 @@ export function planTranscript(inputs, policy, overrides = {}) {
521
557
  }
522
558
  const inFlight = inputs.status !== "ready";
523
559
  const users = inputs.messages.filter((m) => m.role === "user");
524
- const assistants = inputs.result
525
- ? foldAssistantSources(inputs.result, inFlight, inputs.aborted === true)
526
- : flatAssistantSources(inputs, inFlight);
560
+ // R16 notice rows are session annotations anchored between turns: a
561
+ // flat notice renders after the conversation slot of the user turn it
562
+ // followed (usersSeen-1; -1 = before the conversation). They are PEER
563
+ // rows — excluded from both the user pairing and the assistant seam
564
+ // count, so the fold alignment below never sees them.
565
+ const notices = [];
566
+ if (policy.notice.show) {
567
+ let usersSeen = 0;
568
+ inputs.messages.forEach((m, i) => {
569
+ if (m.role === "user")
570
+ usersSeen += 1;
571
+ else if (m.role === "notice") {
572
+ notices.push({ key: `n${i}`, text: m.text, source: m.noticeSource ?? null, afterSlot: usersSeen - 1 });
573
+ }
574
+ });
575
+ }
576
+ // Turn-scoped fold composition (guuey#135 kit refinement): the fold owns
577
+ // the TRAILING assistant turns it actually covers — its settled sources
578
+ // replace that many trailing flat assistant entries; any EARLIER flat
579
+ // entries (a rehydrated/persisted prefix the session's Reducer never saw)
580
+ // keep rendering as flat text slots in front. When the fold spans the
581
+ // whole conversation (a pure-live session — the corpus's world), the kept
582
+ // prefix is empty and the plan is byte-identical to the old wholesale
583
+ // replace. Alignment is by COUNT (trailing flat entries ↔ settled fold
584
+ // sources): flat rows carry no turn identity, so a persisted CARD-ONLY
585
+ // turn inside the fold's span (an empty-text assistant row the assembler
586
+ // dropped) can offset the seam by one — a documented approximation, same
587
+ // class as the header's read-plane-seq note, resolved for the visible
588
+ // cards by the actionScope dedupe below.
589
+ let assistants;
590
+ if (inputs.result) {
591
+ const fold = foldAssistantSources(inputs.result, inFlight, inputs.aborted === true);
592
+ const foldSources = fold.sources;
593
+ const settledFoldCount = foldSources.filter((s) => !s.live).length;
594
+ const flatSettled = inputs.messages.filter((m) => m.role === "assistant");
595
+ const keep = Math.max(0, flatSettled.length - settledFoldCount);
596
+ assistants = [
597
+ ...flatSettled.slice(0, keep).map((m) => ({
598
+ blocks: [{ type: "text", text: m.text }],
599
+ live: false,
600
+ stopped: false,
601
+ })),
602
+ ...foldSources,
603
+ ];
604
+ if (policy.notice.show) {
605
+ // Fold-borne notices anchor to the fold source they followed, which
606
+ // sits at global slot `keep + afterSourceIndex` after the seam.
607
+ fold.notices.forEach((n, i) => {
608
+ notices.push({ key: `nf${i}`, text: n.text, source: n.source, afterSlot: keep + n.afterSourceIndex });
609
+ });
610
+ }
611
+ }
612
+ else {
613
+ assistants = flatAssistantSources(inputs, inFlight);
614
+ }
527
615
  const slots = Math.max(users.length, assistants.length);
528
616
  const conversation = [];
617
+ const noticeItem = (n) => ({
618
+ kind: "notice",
619
+ key: n.key,
620
+ expanded: true,
621
+ text: n.text,
622
+ source: n.source,
623
+ sourceLabel: policy.debugDetail && n.source !== null ? n.source : null,
624
+ });
625
+ for (const n of notices)
626
+ if (n.afterSlot < 0)
627
+ conversation.push(noticeItem(n));
529
628
  for (let slot = 0; slot < slots; slot++) {
530
629
  const user = users[slot];
531
630
  if (user) {
@@ -546,15 +645,37 @@ export function planTranscript(inputs, policy, overrides = {}) {
546
645
  if (assistant) {
547
646
  conversation.push(...planAssistantSource(assistant, slot, inputs, policy, overrides));
548
647
  }
648
+ for (const n of notices)
649
+ if (n.afterSlot === slot)
650
+ conversation.push(noticeItem(n));
549
651
  }
550
652
  items.push(...groupTools(conversation, policy, overrides));
551
653
  // R13 — persisted cards, seq order. (Position: after the settled
552
654
  // conversation; true in-turn interleave needs read-plane seqs the flat
553
655
  // surface lacks — the 3b assemblers own that refinement.)
656
+ //
657
+ // Dedupe against LIVE mounts by actionScope (the persisted `ui://`
658
+ // identity both sides carry): a session whose fold still holds a turn the
659
+ // read plane has ALSO persisted — the #192 adopted turn, a thread view's
660
+ // post-handoff refetch — would otherwise render the same card twice. The
661
+ // fold's view row owns it (richer phase state); the history snapshot
662
+ // renders only when no live mount claims its identity.
663
+ const liveViewScopes = new Set();
664
+ for (const item of items) {
665
+ if (item.kind === "view" && item.actionScope !== null)
666
+ liveViewScopes.add(item.actionScope);
667
+ }
554
668
  const cards = [...(inputs.historyCards ?? [])].sort((a, b) => a.seq - b.seq);
555
669
  for (const card of cards) {
556
670
  const key = `card.${card.seq}`;
557
671
  const mount = snapshotViewMount(card.cardSnapshot);
672
+ const scope = mount === undefined
673
+ ? null
674
+ : mount.channel === "locator"
675
+ ? mount.resourceUri
676
+ : mount.resource.uri;
677
+ if (scope !== null && liveViewScopes.has(scope))
678
+ continue; // live mount owns it
558
679
  const view = {
559
680
  kind: "view",
560
681
  key,
@@ -565,18 +686,40 @@ export function planTranscript(inputs, policy, overrides = {}) {
565
686
  label: null,
566
687
  attribution: null,
567
688
  toolTitle: null,
568
- actionScope: mount === undefined
569
- ? null
570
- : mount.channel === "locator"
571
- ? mount.resourceUri
572
- : mount.resource.uri,
689
+ actionScope: scope,
573
690
  };
574
691
  view.label = viewLabel(view, policy);
575
692
  items.push(view);
576
693
  }
577
- // R10 — prompts, in input order.
694
+ // R10 — prompts, in input order (narrow on `kind`: the guuey-wire
695
+ // profile arm vs the AgJSON hitl arm, spec draft.2).
578
696
  for (const prompt of inputs.prompts) {
579
697
  const key = `p.${prompt.id}`;
698
+ if (prompt.kind === "hitl") {
699
+ const chosen = prompt.grantModeId !== undefined
700
+ ? (prompt.ask.grantModes ?? []).find((m) => m.id === prompt.grantModeId)
701
+ : undefined;
702
+ items.push({
703
+ kind: "prompt",
704
+ key,
705
+ promptId: prompt.id,
706
+ // `cancelled` collapses to a dismissed record but stays expandable —
707
+ // guuey's re-askable ruling (silverprotocol#16); pending opens.
708
+ expanded: resolveExpanded(key, prompt.state === "pending", overrides),
709
+ promptKind: "hitl",
710
+ ask: prompt.ask,
711
+ message: prompt.ask.message ?? null,
712
+ askKind: prompt.ask.kind,
713
+ grantModes: prompt.ask.grantModes ?? [],
714
+ state: prompt.state,
715
+ chosenModeId: prompt.grantModeId ?? null,
716
+ chosenModeLabel: chosen !== undefined ? grantModeDisplay(chosen) : null,
717
+ raw: policy.prompt.rawPayload
718
+ ? { askId: prompt.ask.askId, kind: prompt.ask.kind, state: prompt.state, grantModeId: prompt.grantModeId ?? null }
719
+ : null,
720
+ });
721
+ continue;
722
+ }
580
723
  items.push({
581
724
  kind: "prompt",
582
725
  key,
@@ -621,9 +764,64 @@ export function planTranscript(inputs, policy, overrides = {}) {
621
764
  verbatim: policy.error.verbatim ? `${code ?? "uncoded"}: ${inputs.error.message}` : null,
622
765
  });
623
766
  }
767
+ // guuey#204 "promote and reference": the ONE mount a host-owned stage
768
+ // shows (`inputs.promotedViewKey`) renders as a compact reference chip
769
+ // instead of a second live app instance. A key matching nothing (stale
770
+ // host state) or an expired mount promotes nothing — the honest no-op;
771
+ // the next render's key corrects it. The chip keeps the mount's key, so
772
+ // overrides and phase reports survive a swap back to the full mount.
773
+ const promoted = inputs.promotedViewKey;
774
+ const finalItems = promoted === undefined
775
+ ? items
776
+ : items.map((item) => {
777
+ if (item.kind !== "view" || item.key !== promoted)
778
+ return item;
779
+ if (item.phase === "expired" || item.mount === null)
780
+ return item;
781
+ const title = item.toolTitle ?? policy.strings.viewRefFallbackTitle;
782
+ const ref = {
783
+ kind: "viewRef",
784
+ key: item.key,
785
+ expanded: false,
786
+ title,
787
+ label: policy.strings.viewPromoted(title),
788
+ };
789
+ return ref;
790
+ });
624
791
  return {
625
- items,
792
+ items: finalItems,
626
793
  status: deriveStatus(inputs, policy),
627
794
  recovery: inputs.adopted === true && policy.debugDetail ? policy.strings.recoveredFromHistory : null,
628
795
  };
629
796
  }
797
+ /**
798
+ * The plan key of the NEWEST mountable view — what a "most recent card"
799
+ * stage (the widget's CanvasPane) will show, derived in the same family
800
+ * the plan's own emission uses: live fold mounts (transcript order, last
801
+ * wins) outrank history cards (ascending `seq`). `undefined` when nothing
802
+ * narrows to a mountable resource. Hosts pass the key back as
803
+ * `TranscriptInputs.promotedViewKey`; `channel` lets a host decline to
804
+ * promote a bare locator when no reader is wired (the stage would show
805
+ * nothing, and a chip must never point at an empty canvas).
806
+ */
807
+ export function newestViewKey(inputs) {
808
+ let newest;
809
+ const cards = [...(inputs.historyCards ?? [])].sort((a, b) => a.seq - b.seq);
810
+ for (const card of cards) {
811
+ const mount = snapshotViewMount(card.cardSnapshot);
812
+ if (mount === undefined)
813
+ continue;
814
+ newest = { key: `card.${card.seq}`, channel: mount.channel };
815
+ }
816
+ for (const message of inputs.result?.messages ?? []) {
817
+ for (const block of message.content) {
818
+ if (block.type !== "tool-result")
819
+ continue;
820
+ const mount = toolResultViewMount(block);
821
+ if (mount === undefined)
822
+ continue;
823
+ newest = { key: `view.${block.toolCallId}`, channel: mount.channel };
824
+ }
825
+ }
826
+ return newest;
827
+ }
package/dist/policy.d.ts CHANGED
@@ -93,6 +93,10 @@ export interface TranscriptPolicy {
93
93
  wakingMs: number;
94
94
  longStartMs: number;
95
95
  };
96
+ /** R16 (spec draft.2) — notice rows; provenance facet shows under debug. */
97
+ notice: {
98
+ show: boolean;
99
+ };
96
100
  /** R14. */
97
101
  compaction: {
98
102
  show: boolean;
@@ -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,kEAAkE;IAClE,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,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,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;AAkDD,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":"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,kEAAkE;IAClE,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,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"}
package/dist/policy.js CHANGED
@@ -27,6 +27,7 @@ function withOverrides(base, overrides) {
27
27
  prompt: { ...base.prompt, ...(overrides.prompt ?? {}) },
28
28
  error: { ...base.error, ...(overrides.error ?? {}) },
29
29
  status: { ...base.status, ...(overrides.status ?? {}) },
30
+ notice: { ...base.notice, ...(overrides.notice ?? {}) },
30
31
  compaction: { ...base.compaction, ...(overrides.compaction ?? {}) },
31
32
  unknown: { ...base.unknown, ...(overrides.unknown ?? {}) },
32
33
  };
@@ -46,6 +47,7 @@ function calmBase() {
46
47
  media: { inlineImageCapRem: 20, chipOnly: false },
47
48
  code: { capRem: 16, wrap: false },
48
49
  citations: { style: "chips" },
50
+ notice: { show: true },
49
51
  prompt: { placement: "inline", rawPayload: false },
50
52
  error: { verbatim: false, copyByCode: {}, verbatimCodes: [] },
51
53
  status: { wakingMs: 2500, longStartMs: 15_000 },
@@ -22,7 +22,7 @@ import { type ComponentType, type ReactNode } from "react";
22
22
  import { type GuueyViewProps } from "@guuey/mcp-apps-host/react";
23
23
  import type { ResolvedViewMount, ViewHostPhase } from "@guuey/mcp-apps-host";
24
24
  import type { ChatStrings } from "../strings.js";
25
- import type { CitationsItem, CodeItem, CompactionItem, DataResultItem, DisplayItem, ErrorItem, HistoryBoundaryItem, ItemKey, MediaItem, PromptItem, ReasoningItem, StatusLineItem, ToolGroupItem, ToolItem, UnknownItem, UserMessageItem, TextItem, ViewMountItem } from "../types.js";
25
+ import type { CitationsItem, CodeItem, CompactionItem, DataResultItem, DisplayItem, ErrorItem, HistoryBoundaryItem, ItemKey, MediaItem, NoticeItem, PromptItem, ReasoningItem, StatusLineItem, ToolGroupItem, ToolItem, UnknownItem, UserMessageItem, TextItem, ViewMountItem, ViewRefItem } from "../types.js";
26
26
  /** Everything a rendered item may need beyond itself. */
27
27
  export interface TranscriptItemContext {
28
28
  strings: ChatStrings;
@@ -30,17 +30,40 @@ export interface TranscriptItemContext {
30
30
  onToggle: (key: ItemKey) => void;
31
31
  /** R0 failed-send retry. */
32
32
  onRetry?: (item: UserMessageItem) => void;
33
- /** R10 prompt actions — the host owns what accept/decline DO. */
34
- onPromptAction?: (item: PromptItem, action: "accept" | "decline" | "dismiss") => void;
33
+ /**
34
+ * R10 prompt actions the host owns what accept/decline DO. A hitl card
35
+ * with declared grant modes reports the pick as `{ grantModeId }` (spec
36
+ * draft.2); plain accepts stay the `"accept"` string.
37
+ */
38
+ onPromptAction?: (item: PromptItem, action: "accept" | "decline" | "dismiss" | {
39
+ grantModeId: string;
40
+ }) => void;
35
41
  /** R11 action slots (sign-in / upgrade / retry affordances). */
36
42
  onErrorAction?: (item: ErrorItem) => void;
37
43
  /** R6: locator mounts resolved by `useTranscript` ("expired" = failed). */
38
44
  resolvedMounts: ReadonlyMap<ItemKey, ResolvedViewMount | "expired">;
39
45
  /** R6: live phase reports wired back into the next plan. */
40
46
  onViewPhase: (key: ItemKey, phase: ViewHostPhase) => void;
41
- /** R6 pass-through (sandbox overrides etc. — policy-gated by the host). */
42
- viewProps?: Pick<GuueyViewProps, "hostCapabilities" | "hostInfo" | "hostContext" | "onCallTool" | "negotiationTimeoutMs" | "dangerouslyAddSandboxFlags" | "allow">;
47
+ /**
48
+ * guuey#204: a promoted-view reference chip was activated the host
49
+ * focuses/reveals its stage (canvas). Absent ⇒ the chip renders as a
50
+ * non-interactive label.
51
+ */
52
+ onViewRef?: (item: ViewRefItem) => void;
53
+ /**
54
+ * R6 pass-through (sandbox overrides, the two-origin mount, relay hooks
55
+ * — policy-gated by the host). Static, or a FUNCTION of the mount being
56
+ * rendered: view configuration legitimately varies per mount — the
57
+ * relay-page URL picks a per-channel egress grant (`?channel=`), and a
58
+ * `tools/call` hook scopes to the item's persisted locator (guuey#158) —
59
+ * so the function form receives the item and its resolved mount and is
60
+ * called only when something actually mounts. Static keeps working
61
+ * unchanged.
62
+ */
63
+ viewProps?: ViewSlotProps | ((item: ViewMountItem, mount: ResolvedViewMount) => ViewSlotProps);
43
64
  }
65
+ /** The per-view slice of `GuueyViewProps` a transcript may configure. */
66
+ export type ViewSlotProps = Pick<GuueyViewProps, "hostCapabilities" | "hostInfo" | "hostContext" | "onCallTool" | "onReadResource" | "onSizeChanged" | "negotiationTimeoutMs" | "dangerouslyAddSandboxFlags" | "allow" | "sandboxPageUrl" | "autoResize">;
44
67
  interface ItemProps<T> {
45
68
  item: T;
46
69
  ctx: TranscriptItemContext;
@@ -52,10 +75,22 @@ export declare function DefaultDataResult({ item, ctx }: ItemProps<DataResultIte
52
75
  export declare function DefaultTool({ item, ctx }: ItemProps<ToolItem>): ReactNode;
53
76
  export declare function DefaultToolGroup({ item, ctx }: ItemProps<ToolGroupItem>): ReactNode;
54
77
  export declare function DefaultView({ item, ctx }: ItemProps<ViewMountItem>): ReactNode;
78
+ /**
79
+ * guuey#204: the "promote and reference" chip — stands in for the one
80
+ * mount the host's stage shows. A real button when the host wires
81
+ * `onViewRef` (keyboard-accessible for free); a plain label otherwise.
82
+ */
83
+ export declare function DefaultViewRef({ item, ctx }: ItemProps<ViewRefItem>): ReactNode;
55
84
  export declare function DefaultMedia({ item }: ItemProps<MediaItem>): ReactNode;
56
85
  export declare function DefaultCode({ item, ctx }: ItemProps<CodeItem>): ReactNode;
57
86
  export declare function DefaultCitations({ item, ctx }: ItemProps<CitationsItem>): ReactNode;
58
87
  export declare function DefaultPrompt({ item, ctx }: ItemProps<PromptItem>): ReactNode;
88
+ /**
89
+ * A `role:"notice"` session annotation (spec draft.2) — a labeled,
90
+ * non-conversational row that must never read as agent-authored. Calm
91
+ * shows the quiet label; debug appends the provenance facet verbatim.
92
+ */
93
+ export declare function DefaultNotice({ item, ctx }: ItemProps<NoticeItem>): ReactNode;
59
94
  export declare function DefaultError({ item, ctx }: ItemProps<ErrorItem>): ReactNode;
60
95
  export declare function DefaultHistoryBoundary({ item }: ItemProps<HistoryBoundaryItem>): ReactNode;
61
96
  export declare function DefaultCompaction({ item }: ItemProps<CompactionItem>): ReactNode;
@@ -70,10 +105,12 @@ export interface TranscriptComponents {
70
105
  toolGroup: ComponentType<ItemProps<ToolGroupItem>>;
71
106
  dataResult: ComponentType<ItemProps<DataResultItem>>;
72
107
  view: ComponentType<ItemProps<ViewMountItem>>;
108
+ viewRef: ComponentType<ItemProps<ViewRefItem>>;
73
109
  media: ComponentType<ItemProps<MediaItem>>;
74
110
  code: ComponentType<ItemProps<CodeItem>>;
75
111
  citations: ComponentType<ItemProps<CitationsItem>>;
76
112
  prompt: ComponentType<ItemProps<PromptItem>>;
113
+ notice: ComponentType<ItemProps<NoticeItem>>;
77
114
  error: ComponentType<ItemProps<ErrorItem>>;
78
115
  history: ComponentType<ItemProps<HistoryBoundaryItem>>;
79
116
  compaction: ComponentType<ItemProps<CompactionItem>>;
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/react/components.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/react/components.tsx"],"names":[],"mappings":"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"}