@grackle-ai/web-components 0.118.0 → 0.119.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 (32) hide show
  1. package/.rush/temp/{e5461b19665f030d269f07cf8797f2bcfeac1bf7.tar.log → 5029e8eb2a183283a13abb63c8b98671df398046.tar.log} +2 -2
  2. package/.rush/temp/{54cccf3e758698925ef11c80c60777421e1be435.untar.log → 5029e8eb2a183283a13abb63c8b98671df398046.untar.log} +2 -2
  3. package/.rush/temp/{54cccf3e758698925ef11c80c60777421e1be435.tar.log → 9e64c83035307e17fee515015bb370270d4cf3c8.tar.log} +14 -11
  4. package/.rush/temp/{e5461b19665f030d269f07cf8797f2bcfeac1bf7.untar.log → 9e64c83035307e17fee515015bb370270d4cf3c8.untar.log} +2 -2
  5. package/.rush/temp/chunked-rush-logs/web-components._phase_build.chunks.jsonl +8 -8
  6. package/.rush/temp/chunked-rush-logs/web-components._phase_test.chunks.jsonl +23 -22
  7. package/.rush/temp/operation/_phase_build/all.log +8 -8
  8. package/.rush/temp/operation/_phase_build/log-chunks.jsonl +8 -8
  9. package/.rush/temp/operation/_phase_build/state.json +1 -1
  10. package/.rush/temp/operation/_phase_test/all.log +23 -22
  11. package/.rush/temp/operation/_phase_test/log-chunks.jsonl +23 -22
  12. package/.rush/temp/operation/_phase_test/state.json +1 -1
  13. package/.rush/temp/shrinkwrap-deps.json +3 -3
  14. package/dist/index.css +1 -1
  15. package/dist/index.js +5801 -5768
  16. package/package.json +2 -2
  17. package/rush-logs/web-components._phase_build.cache.log +1 -1
  18. package/rush-logs/web-components._phase_build.log +8 -8
  19. package/rush-logs/web-components._phase_test.cache.log +1 -1
  20. package/rush-logs/web-components._phase_test.log +23 -22
  21. package/src/components/streams/StreamDetailPanel.stories.tsx +16 -1
  22. package/src/components/streams/StreamDetailPanel.tsx +10 -7
  23. package/src/components/streams/StreamTranscript.module.scss +47 -0
  24. package/src/components/streams/StreamTranscript.stories.tsx +42 -0
  25. package/src/components/streams/StreamTranscript.tsx +58 -0
  26. package/src/components/streams/index.ts +2 -0
  27. package/src/hooks/types.ts +20 -0
  28. package/src/index.ts +3 -3
  29. package/src/mocks/MockGrackleProvider.tsx +4 -0
  30. package/src/mocks/mockData.ts +1 -1
  31. package/src/mocks/mockStreamsData.ts +10 -1
  32. package/temp/build/lint/_eslint-5eVG3S6w.json +17 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grackle-ai/web-components",
3
- "version": "0.118.0",
3
+ "version": "0.119.0",
4
4
  "description": "Presentational React component library for the Grackle web UI",
5
5
  "license": "MIT",
6
6
  "sideEffects": [
@@ -47,7 +47,7 @@
47
47
  "remark-gfm": "^4.0.0",
48
48
  "lucide-react": "~0.474.0",
49
49
  "react-router": "^7.0.0",
50
- "@grackle-ai/common": "0.118.0"
50
+ "@grackle-ai/common": "0.119.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@rushstack/heft": "1.2.7",
@@ -1,4 +1,4 @@
1
1
  Build cache hit.
2
- Cache key: 54cccf3e758698925ef11c80c60777421e1be435
2
+ Cache key: 9e64c83035307e17fee515015bb370270d4cf3c8
3
3
  Clearing cached folders: dist, storybook-static, mcp-app-runtime, .rush/temp/operation/_phase_build
4
4
  Successfully restored output from the build cache.
@@ -7,20 +7,20 @@ Invoking: heft run --only build -- --clean
7
7
  [build:lint] Using ESLint version 9.39.4
8
8
  vite v6.4.2 building for production...
9
9
  transforming...
10
- 2712 modules transformed.
10
+ 2714 modules transformed.
11
11
  rendering chunks...
12
12
  computing gzip size...
13
- dist/index.css 155.14 kB │ gzip: 20.34 kB
13
+ dist/index.css 155.86 kB │ gzip: 20.51 kB
14
14
  dist/McpAppWidget-CSX2W2Vb.js 205.28 kB │ gzip: 47.19 kB
15
- dist/index.js 1,375.56 kB │ gzip: 353.02 kB
16
- ✓ built in 5.83s
15
+ dist/index.js 1,377.57 kB │ gzip: 353.56 kB
16
+ ✓ built in 5.62s
17
17
  vite v6.4.2 building for production...
18
18
  transforming...
19
- 2870 modules transformed.
19
+ 2872 modules transformed.
20
20
  rendering chunks...
21
21
  computing gzip size...
22
22
  mcp-app-runtime/runtime.js 1,243.84 kB │ gzip: 267.73 kB
23
- ✓ built in 4.99s
23
+ ✓ built in 4.81s
24
24
  [build:vite-build] Vite build completed.
25
- ---- build finished (85.920s) ----
26
- -------------------- Finished (85.925s) --------------------
25
+ ---- build finished (83.403s) ----
26
+ -------------------- Finished (83.407s) --------------------
@@ -1,4 +1,4 @@
1
1
  Build cache hit.
2
- Cache key: e5461b19665f030d269f07cf8797f2bcfeac1bf7
2
+ Cache key: 5029e8eb2a183283a13abb63c8b98671df398046
3
3
  Clearing cached folders: .rush/temp/operation/_phase_test
4
4
  Successfully restored output from the build cache.
@@ -5,31 +5,32 @@ The provided list of phases does not contain all phase dependencies. You may nee
5
5
 
6
6
  RUN v3.2.4 /home/runner/work/grackle/grackle/packages/web-components
7
7
 
8
- ✓ src/utils/sessionEvents.test.ts (14 tests) 46ms
9
- ✓ src/utils/eventContent.test.ts (38 tests) 65ms
10
- ✓ src/utils/dashboard.test.ts (4 tests) 14ms
11
- ✓ src/utils/streamCoordination.test.ts (10 tests) 34ms
12
- ✓ src/utils/route-config.test.ts (16 tests) 38ms
13
- ✓ src/utils/breadcrumbs.test.ts (15 tests) 90ms
14
- ✓ src/utils/scrollUtils.test.ts (11 tests) 31ms
15
- ✓ src/components/tools/classifyTool.test.ts (6 tests) 15ms
16
- ✓ src/utils/assetUrl.test.ts (3 tests) 27ms
17
- ✓ src/components/tools/toolCardHelpers.test.ts (10 tests) 19ms
18
- ✓ src/components/display/extractText.test.tsx (8 tests) 12ms
19
- ✓ src/components/editable/useEditableField.test.tsx (17 tests) 159ms
20
- ✓ src/hooks/useEventSelection.test.ts (13 tests) 271ms
21
- ✓ src/components/display/McpAppWidget.test.tsx (3 tests) 312ms
22
- ✓ src/components/notifications/UpdateBanner.test.tsx (4 tests) 217ms
23
- src/utils/grackleHostStyleVariables.test.ts (2 tests) 337ms
24
- grackleHostStyleVariables > always returns the MCP-standard fallback variables 327ms
8
+ ✓ src/utils/eventContent.test.ts (38 tests) 61ms
9
+ ✓ src/utils/sessionEvents.test.ts (14 tests) 23ms
10
+ ✓ src/utils/streamCoordination.test.ts (10 tests) 19ms
11
+ ✓ src/utils/dashboard.test.ts (4 tests) 33ms
12
+ ✓ src/utils/breadcrumbs.test.ts (15 tests) 59ms
13
+ ✓ src/utils/route-config.test.ts (16 tests) 73ms
14
+ ✓ src/utils/scrollUtils.test.ts (11 tests) 48ms
15
+ ✓ src/components/tools/classifyTool.test.ts (6 tests) 17ms
16
+ ✓ src/utils/assetUrl.test.ts (3 tests) 6ms
17
+ ✓ src/components/tools/toolCardHelpers.test.ts (10 tests) 18ms
18
+ ✓ src/components/display/extractText.test.tsx (8 tests) 11ms
19
+ ✓ src/components/editable/useEditableField.test.tsx (17 tests) 202ms
20
+ ✓ src/hooks/useEventSelection.test.ts (13 tests) 200ms
21
+ ✓ src/components/notifications/UpdateBanner.test.tsx (4 tests) 123ms
22
+ ✓ src/utils/grackleHostStyleVariables.test.ts (2 tests) 395ms
23
+ ✓ grackleHostStyleVariables > always returns the MCP-standard fallback variables 375ms
24
+ src/components/display/McpAppWidget.test.tsx (3 tests) 371ms
25
+ ✓ McpAppWidget > mounts an iframe host for the widget 300ms
25
26
 
26
27
  Test Files 16 passed (16)
27
28
  Tests 174 passed (174)
28
- Start at 14:54:51
29
- Duration 15.79s (transform 2.65s, setup 0ms, collect 17.82s, tests 1.69s, environment 12.03s, prepare 5.23s)
29
+ Start at 18:20:37
30
+ Duration 16.15s (transform 2.75s, setup 0ms, collect 16.48s, tests 1.66s, environment 13.02s, prepare 5.17s)
30
31
 
31
32
  [test:vitest] Vitest completed.
32
- [test:storybook-test] Starting Storybook static server on port 46639...
33
+ [test:storybook-test] Starting Storybook static server on port 38031...
33
34
  [test:storybook-test] Storybook server ready. Running interaction tests...
34
35
  jest-haste-map: duplicate manual mock found: adapter-manager
35
36
  The following files share their name; please delete one of them:
@@ -122,5 +123,5 @@ jest-haste-map: duplicate manual mock found: utils/network
122
123
  * <rootDir>/packages/server/src/__mocks__/utils/network.ts
123
124
 
124
125
  [test:storybook-test] Storybook interaction tests completed.
125
- ---- test finished (114.090s) ----
126
- -------------------- Finished (114.096s) --------------------
126
+ ---- test finished (110.698s) ----
127
+ -------------------- Finished (110.709s) --------------------
@@ -1,6 +1,6 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
2
  import { expect, fn } from "@storybook/test";
3
- import type { StreamData } from "../../hooks/types.js";
3
+ import type { StreamData, StreamMessageData } from "../../hooks/types.js";
4
4
  import { withMockGrackleRoute } from "../../test-utils/storybook-helpers.js";
5
5
  import { StreamDetailPanel } from "./StreamDetailPanel.js";
6
6
 
@@ -125,6 +125,21 @@ export const AllPermissionModes: Story = {
125
125
  },
126
126
  };
127
127
 
128
+ const sampleMessages: StreamMessageData[] = [
129
+ { streamId: "stream-abc123", seq: "01A", senderId: "session-aabbccdd-eeff-0011", content: "Proposing JWT with RS256.", timestamp: "2026-05-24T18:00:01.000Z" },
130
+ { streamId: "stream-abc123", seq: "01B", senderId: "session-11223344-5566-7788", content: "Agreed; rotate refresh tokens on use.", timestamp: "2026-05-24T18:00:07.000Z" },
131
+ ];
132
+
133
+ /** Stream with a populated conversation transcript. */
134
+ export const WithTranscript: Story = {
135
+ args: {
136
+ messages: sampleMessages,
137
+ },
138
+ play: async ({ canvas }) => {
139
+ await expect(canvas.getAllByTestId("stream-transcript-message")).toHaveLength(2);
140
+ },
141
+ };
142
+
128
143
  /** Close button calls onClose. */
129
144
  export const CloseButton: Story = {
130
145
  play: async ({ canvas, args }) => {
@@ -6,21 +6,26 @@
6
6
  *
7
7
  * Read-only: participants link to their sessions; low-level wiring (fds, full
8
8
  * GUIDs, permission/delivery mode) is tucked behind an "Advanced" disclosure.
9
- * Live conversation content arrives in V2 (#1230).
9
+ * The Conversation section shows the durable room transcript (RFC #1264 Phase 2).
10
10
  *
11
11
  * @module
12
12
  */
13
13
 
14
14
  import { useEffect, type JSX } from "react";
15
- import type { StreamData } from "../../hooks/types.js";
15
+ import type { StreamData, StreamMessageData } from "../../hooks/types.js";
16
16
  import { useAppNavigate, sessionUrl } from "../../utils/navigation.js";
17
17
  import { streamKind, type StreamKind } from "../../utils/streamCoordination.js";
18
+ import { StreamTranscript } from "./StreamTranscript.js";
18
19
  import styles from "./StreamDetailPanel.module.scss";
19
20
 
20
21
  /** Props for the StreamDetailPanel component. */
21
22
  export interface StreamDetailPanelProps {
22
23
  /** The stream to display details for. */
23
24
  stream: StreamData;
25
+ /** The stream's transcript messages, oldest first (scrollback + live merged). */
26
+ messages?: StreamMessageData[];
27
+ /** Whether the transcript is currently loading. */
28
+ transcriptLoading?: boolean;
24
29
  /** Called when the user requests to close the panel. */
25
30
  onClose: () => void;
26
31
  }
@@ -56,7 +61,7 @@ function DeliveryModeBadge({ mode }: { mode: string }): JSX.Element {
56
61
  * Pull-out right drawer showing stream metadata: overview, participants, and an
57
62
  * Advanced disclosure with low-level wiring. Conversation content is V2.
58
63
  */
59
- export function StreamDetailPanel({ stream, onClose }: StreamDetailPanelProps): JSX.Element {
64
+ export function StreamDetailPanel({ stream, messages, transcriptLoading, onClose }: StreamDetailPanelProps): JSX.Element {
60
65
  const navigate = useAppNavigate();
61
66
 
62
67
  // Close on Escape key
@@ -119,12 +124,10 @@ export function StreamDetailPanel({ stream, onClose }: StreamDetailPanelProps):
119
124
  )}
120
125
  </div>
121
126
 
122
- {/* Live conversation V2 */}
127
+ {/* Live conversation transcript (RFC #1264 Phase 2) */}
123
128
  <div className={styles.section}>
124
129
  <div className={styles.sectionLabel}>Conversation</div>
125
- <div className={styles.placeholder} data-testid="stream-conversation-placeholder">
126
- Live conversation view — coming in V2.
127
- </div>
130
+ <StreamTranscript messages={messages ?? []} loading={transcriptLoading ?? false} />
128
131
  </div>
129
132
 
130
133
  {/* Advanced wiring */}
@@ -0,0 +1,47 @@
1
+ .transcript {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 10px;
5
+ max-height: 320px;
6
+ overflow-y: auto;
7
+ padding: 4px 2px;
8
+ }
9
+
10
+ .message {
11
+ display: flex;
12
+ flex-direction: column;
13
+ gap: 2px;
14
+ }
15
+
16
+ .meta {
17
+ display: flex;
18
+ justify-content: space-between;
19
+ align-items: baseline;
20
+ gap: 8px;
21
+ font-size: 11px;
22
+ }
23
+
24
+ .sender {
25
+ font-family: var(--font-mono, monospace);
26
+ color: var(--color-text-secondary, #8b949e);
27
+ }
28
+
29
+ .time {
30
+ color: var(--color-text-tertiary, #6e7681);
31
+ font-variant-numeric: tabular-nums;
32
+ }
33
+
34
+ .content {
35
+ white-space: pre-wrap;
36
+ word-break: break-word;
37
+ font-size: 13px;
38
+ line-height: 1.45;
39
+ color: var(--color-text-primary, #e6edf3);
40
+ }
41
+
42
+ .state {
43
+ padding: 16px 8px;
44
+ font-size: 13px;
45
+ font-style: italic;
46
+ color: var(--color-text-secondary, #8b949e);
47
+ }
@@ -0,0 +1,42 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { expect } from "@storybook/test";
3
+ import type { StreamMessageData } from "../../hooks/types.js";
4
+ import { StreamTranscript } from "./StreamTranscript.js";
5
+
6
+ const messages: StreamMessageData[] = [
7
+ { streamId: "s1", seq: "01A", senderId: "session-aabbccdd-eeff", content: "Proposing JWT with RS256.", timestamp: "2026-05-24T18:00:01.000Z" },
8
+ { streamId: "s1", seq: "01B", senderId: "session-11223344-5566", content: "Agreed; rotate refresh tokens on use.", timestamp: "2026-05-24T18:00:07.000Z" },
9
+ { streamId: "s1", seq: "01C", senderId: "session-aabbccdd-eeff", content: "Ship it.", timestamp: "2026-05-24T18:00:14.000Z" },
10
+ ];
11
+
12
+ const meta: Meta<typeof StreamTranscript> = {
13
+ title: "Grackle/Streams/StreamTranscript",
14
+ component: StreamTranscript,
15
+ args: { messages },
16
+ };
17
+
18
+ export default meta;
19
+ type Story = StoryObj<typeof StreamTranscript>;
20
+
21
+ /** Populated transcript renders one row per message. */
22
+ export const Populated: Story = {
23
+ play: async ({ canvas }) => {
24
+ await expect(canvas.getAllByTestId("stream-transcript-message")).toHaveLength(3);
25
+ },
26
+ };
27
+
28
+ /** Empty transcript shows the empty state. */
29
+ export const Empty: Story = {
30
+ args: { messages: [] },
31
+ play: async ({ canvas }) => {
32
+ await expect(canvas.getByTestId("stream-transcript-empty")).toBeInTheDocument();
33
+ },
34
+ };
35
+
36
+ /** Loading state while scrollback is being fetched. */
37
+ export const Loading: Story = {
38
+ args: { messages: [], loading: true },
39
+ play: async ({ canvas }) => {
40
+ await expect(canvas.getByTestId("stream-transcript-loading")).toBeInTheDocument();
41
+ },
42
+ };
@@ -0,0 +1,58 @@
1
+ /**
2
+ * StreamTranscript — read-only transcript of an IPC stream room (RFC #1264 Phase 2).
3
+ *
4
+ * Pure presentational: renders an ordered (oldest-first) list of stream messages
5
+ * with sender + timestamp. Fed by the durable transcript (scrollback) merged with
6
+ * the live message feed; the owning page supplies the data and loading state.
7
+ *
8
+ * @module
9
+ */
10
+
11
+ import { type JSX } from "react";
12
+ import type { StreamMessageData } from "../../hooks/types.js";
13
+ import styles from "./StreamTranscript.module.scss";
14
+
15
+ /** Props for the StreamTranscript component. */
16
+ export interface StreamTranscriptProps {
17
+ /** Messages to render, oldest first. */
18
+ messages: StreamMessageData[];
19
+ /** Whether the transcript is currently loading (scrollback fetch in flight). */
20
+ loading?: boolean;
21
+ }
22
+
23
+ /** Format an ISO 8601 timestamp as a short local time. */
24
+ function formatTime(iso: string): string {
25
+ const date = new Date(iso);
26
+ return Number.isNaN(date.getTime()) ? iso : date.toLocaleTimeString();
27
+ }
28
+
29
+ /** Read-only, ordered transcript of an IPC stream room's messages. */
30
+ export function StreamTranscript({ messages, loading = false }: StreamTranscriptProps): JSX.Element {
31
+ if (loading) {
32
+ return (
33
+ <div className={styles.state} data-testid="stream-transcript-loading">
34
+ Loading transcript…
35
+ </div>
36
+ );
37
+ }
38
+ if (messages.length === 0) {
39
+ return (
40
+ <div className={styles.state} data-testid="stream-transcript-empty">
41
+ No messages yet.
42
+ </div>
43
+ );
44
+ }
45
+ return (
46
+ <div className={styles.transcript} data-testid="stream-transcript">
47
+ {messages.map((m) => (
48
+ <div key={m.seq} className={styles.message} data-testid="stream-transcript-message">
49
+ <div className={styles.meta}>
50
+ <span className={styles.sender} title={m.senderId}>{m.senderId.slice(0, 12)}</span>
51
+ <span className={styles.time}>{formatTime(m.timestamp)}</span>
52
+ </div>
53
+ <div className={styles.content}>{m.content}</div>
54
+ </div>
55
+ ))}
56
+ </div>
57
+ );
58
+ }
@@ -8,3 +8,5 @@ export { CoordinationList } from "./CoordinationList.js";
8
8
  export type { CoordinationListProps } from "./CoordinationList.js";
9
9
  export { StreamDetailPanel } from "./StreamDetailPanel.js";
10
10
  export type { StreamDetailPanelProps } from "./StreamDetailPanel.js";
11
+ export { StreamTranscript } from "./StreamTranscript.js";
12
+ export type { StreamTranscriptProps } from "./StreamTranscript.js";
@@ -604,6 +604,20 @@ export interface StreamData {
604
604
  selfEcho: boolean;
605
605
  }
606
606
 
607
+ /** A single message in an IPC stream room transcript (RFC #1264 Phase 2). */
608
+ export interface StreamMessageData {
609
+ /** The stream (room) this message belongs to. */
610
+ streamId: string;
611
+ /** ULID transcript sequence key (monotonic per stream, ascending = chronological). */
612
+ seq: string;
613
+ /** Session id of the sender. */
614
+ senderId: string;
615
+ /** Message content. */
616
+ content: string;
617
+ /** ISO 8601 timestamp. */
618
+ timestamp: string;
619
+ }
620
+
607
621
  /** Values returned by the streams domain hook. */
608
622
  export interface UseStreamsResult {
609
623
  /** All known IPC streams. */
@@ -619,6 +633,12 @@ export interface UseStreamsResult {
619
633
  * to surface internal IPC plumbing (lifecycle/pipe/stdin); defaults to false.
620
634
  */
621
635
  loadStreams: (includeInternal?: boolean) => Promise<void>;
636
+ /** Transcript buffer keyed by stream id (scrollback + live, deduped by seq, ascending). */
637
+ liveMessages: Record<string, StreamMessageData[]>;
638
+ /** Fetch a stream's durable transcript (scrollback) and merge it into the buffer. */
639
+ loadTranscript: (streamId: string, beforeSeq?: string) => Promise<void>;
640
+ /** Append a live stream message to the per-stream buffer. */
641
+ handleStreamMessage: (message: StreamMessageData) => void;
622
642
  /** Handle a domain event from the event bus. Returns `true` if handled. */
623
643
  handleEvent: (event: GrackleEvent) => boolean;
624
644
  /** Lifecycle hook for connect/disconnect/event routing. */
package/src/index.ts CHANGED
@@ -87,8 +87,8 @@ export type { ScheduleManagerProps } from "./components/schedules/ScheduleManage
87
87
  export { SettingsNav } from "./components/settings/SettingsNav.js";
88
88
 
89
89
  // Streams (Coordination tab)
90
- export { CoordinationList, StreamDetailPanel } from "./components/streams/index.js";
91
- export type { CoordinationListProps, StreamDetailPanelProps } from "./components/streams/index.js";
90
+ export { CoordinationList, StreamDetailPanel, StreamTranscript } from "./components/streams/index.js";
91
+ export type { CoordinationListProps, StreamDetailPanelProps, StreamTranscriptProps } from "./components/streams/index.js";
92
92
 
93
93
  // Tools
94
94
  export { ToolCard } from "./components/tools/ToolCard.js";
@@ -135,7 +135,7 @@ export type {
135
135
  UseTasksResult, UseTokensResult,
136
136
  UseCredentialsResult, UseCodespacesResult, UseDockerContainersResult, UsePersonasResult,
137
137
  UsePluginsResult, PluginData,
138
- StreamData, StreamSubscriberData, UseStreamsResult,
138
+ StreamData, StreamSubscriberData, StreamMessageData, UseStreamsResult,
139
139
  UseGitHubAccountsResult, GitHubAccountData,
140
140
  DomainHook,
141
141
  ConnectionStatus,
@@ -44,6 +44,7 @@ import {
44
44
  MOCK_ENVIRONMENTS,
45
45
  MOCK_SESSIONS,
46
46
  MOCK_STREAMS,
47
+ MOCK_STREAM_MESSAGES,
47
48
  MOCK_EVENTS,
48
49
  MOCK_WORKSPACES,
49
50
  MOCK_TASKS,
@@ -1123,6 +1124,9 @@ export function MockGrackleProvider({ children }: MockGrackleProviderProps): JSX
1123
1124
  streamsLoadedOnce: true,
1124
1125
  streamsLoadError: false,
1125
1126
  loadStreams: async (includeInternal = false) => { setStreams(filterMockStreams(includeInternal)); },
1127
+ liveMessages: MOCK_STREAM_MESSAGES,
1128
+ loadTranscript: async () => { /* mock transcripts are static */ },
1129
+ handleStreamMessage: () => { /* no-op in mock */ },
1126
1130
  domainHook: NOOP_DOMAIN_HOOK,
1127
1131
  },
1128
1132
 
@@ -16,7 +16,7 @@ import type {
16
16
  PersonaData,
17
17
  } from "../hooks/types.js";
18
18
  export { MOCK_KNOWLEDGE_NODES, MOCK_KNOWLEDGE_LINKS, MOCK_KNOWLEDGE_DETAILS } from "./mockKnowledgeData.js";
19
- export { MOCK_STREAMS } from "./mockStreamsData.js";
19
+ export { MOCK_STREAMS, MOCK_STREAM_MESSAGES } from "./mockStreamsData.js";
20
20
 
21
21
  // ─── Environments ───────────────────────────────────
22
22
 
@@ -9,7 +9,7 @@
9
9
  * @module
10
10
  */
11
11
 
12
- import type { StreamData } from "../hooks/types.js";
12
+ import type { StreamData, StreamMessageData } from "../hooks/types.js";
13
13
 
14
14
  /** Sample IPC streams: a chatroom + channel attributed to tasks, an unattached
15
15
  * stream, and internal plumbing streams. */
@@ -78,3 +78,12 @@ export const MOCK_STREAMS: StreamData[] = [
78
78
  ],
79
79
  },
80
80
  ];
81
+
82
+ /** Sample transcript messages for the planning room, keyed by stream id (RFC #1264 Phase 2). */
83
+ export const MOCK_STREAM_MESSAGES: Record<string, StreamMessageData[]> = {
84
+ "stream-planning": [
85
+ { streamId: "stream-planning", seq: "01J0000000000000000000MSG1", senderId: "sess-001", content: "Proposing JWT with RS256 + 15-min access tokens.", timestamp: "2026-05-24T18:00:01.000Z" },
86
+ { streamId: "stream-planning", seq: "01J0000000000000000000MSG2", senderId: "sess-002", content: "Agreed. Refresh tokens rotate on use; store the jti denylist in Redis.", timestamp: "2026-05-24T18:00:07.000Z" },
87
+ { streamId: "stream-planning", seq: "01J0000000000000000000MSG3", senderId: "sess-001", content: "Ship it. I'll wire the middleware; you take the refresh endpoint.", timestamp: "2026-05-24T18:00:14.000Z" },
88
+ ],
89
+ };
@@ -7,7 +7,7 @@
7
7
  ],
8
8
  [
9
9
  "hooks/types.ts",
10
- "m51Zk1lQIpucGwfVy6FR3h3fgY0=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
10
+ "6r0o+OaciGsZexJET91xeVksGXI=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
11
11
  ],
12
12
  [
13
13
  "components/chat/ChatInput.tsx",
@@ -405,13 +405,17 @@
405
405
  "components/streams/CoordinationList.tsx",
406
406
  "xDBNKE1Nr/O3BrdHcyQlPea6MtM=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
407
407
  ],
408
+ [
409
+ "components/streams/StreamTranscript.tsx",
410
+ "do8OXELxLObi1qnOSEyGglfwrY8=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
411
+ ],
408
412
  [
409
413
  "components/streams/StreamDetailPanel.tsx",
410
- "OnOHSENhCoxiHgkVDZM3a06WeO4=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
414
+ "aeawtCjddBuXTyEKaxOyJvCZIAA=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
411
415
  ],
412
416
  [
413
417
  "components/streams/index.ts",
414
- "6ayws8aPUPY31xaNAyWGY2MkjFY=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
418
+ "0chJAM7tVb+DCTTPCPOs4k2KfD4=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
415
419
  ],
416
420
  [
417
421
  "utils/boardColumns.ts",
@@ -455,15 +459,15 @@
455
459
  ],
456
460
  [
457
461
  "mocks/mockStreamsData.ts",
458
- "sV8iV8PeiQ+2LXWFB7zKll/xSIs=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
462
+ "XXQoCU5/w8kXwVBl8S8i/5vMg1Q=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
459
463
  ],
460
464
  [
461
465
  "mocks/mockData.ts",
462
- "kbhREjA6iPR+RFsk6TyHECbjFN8=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
466
+ "LHqkwplEmqmBdfMiMvyPWZAaI+Y=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
463
467
  ],
464
468
  [
465
469
  "mocks/MockGrackleProvider.tsx",
466
- "to2SSz5PviiRBVcdKxmv/VGf45g=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
470
+ "5Fo6VDfUkysHIFcc2CV/yWKhFw8=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
467
471
  ],
468
472
  [
469
473
  "test-utils/storybook-decorators.tsx",
@@ -475,7 +479,7 @@
475
479
  ],
476
480
  [
477
481
  "index.ts",
478
- "UyNF82ITEot6wdXX5ij47791vLU=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
482
+ "0HAGVKwcQlcxpA1aUtgUrMWpu98=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
479
483
  ],
480
484
  [
481
485
  "components/index.ts",
@@ -707,7 +711,11 @@
707
711
  ],
708
712
  [
709
713
  "components/streams/StreamDetailPanel.stories.tsx",
710
- "wXCDWxvXnuORr2+5yl/rwfioFFE=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
714
+ "j2qugPMk7KA5jov7N6kNpUxenqw=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
715
+ ],
716
+ [
717
+ "components/streams/StreamTranscript.stories.tsx",
718
+ "/AkYRGxhKte2p1+RLA17HPgJulU=_7W3TvvwZxl0TGST6/dyQa8DKDDc="
711
719
  ],
712
720
  [
713
721
  "components/tools/AgentToolCard.stories.tsx",
@@ -826,5 +834,5 @@
826
834
  "tcFLEiIFvYYLO/1jT41tcJ4CIX4=_orHdc0vDZqoYfD6TIDl1Za3EAL4="
827
835
  ]
828
836
  ],
829
- "filesHash": "DNaGWodZdPGqzAPxzYjKFQ"
837
+ "filesHash": "u_c8NEn8Xzoz1UbJZkZoyg"
830
838
  }