@belonguniverseai/react-sdk 0.4.0 → 0.4.2

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 (75) hide show
  1. package/dist/api/client.d.ts +294 -0
  2. package/dist/api/queries.d.ts +16 -0
  3. package/dist/api/query-keys.d.ts +1 -0
  4. package/dist/api/task-schedules.d.ts +3 -3
  5. package/dist/component/{arc-BhIvhaIH.js → arc-COH48Rtu.js} +2 -2
  6. package/dist/component/{architectureDiagram-3BPJPVTR-BWNCirdr.js → architectureDiagram-3BPJPVTR-B5qmE5k5.js} +3 -3
  7. package/dist/component/{blockDiagram-GPEHLZMM-BnslF4z5.js → blockDiagram-GPEHLZMM-lkovkWkX.js} +4 -4
  8. package/dist/component/{c4Diagram-AAUBKEIU-ByIoAzxn.js → c4Diagram-AAUBKEIU-CaWDjxTr.js} +3 -3
  9. package/dist/component/{channel-BSkI2ZMQ.js → channel-DNnfyuhY.js} +2 -2
  10. package/dist/component/{chunk-2J33WTMH-DdP5frJt.js → chunk-2J33WTMH-I7HgfCPn.js} +2 -2
  11. package/dist/component/{chunk-4BX2VUAB-DlsylVfZ.js → chunk-4BX2VUAB-CZBTp8pg.js} +2 -2
  12. package/dist/component/{chunk-55IACEB6-CcJHjxtI.js → chunk-55IACEB6-C-RnqcTj.js} +2 -2
  13. package/dist/component/{chunk-727SXJPM-IzRNu9Aj.js → chunk-727SXJPM-BFV7YyWV.js} +6 -6
  14. package/dist/component/{chunk-AQP2D5EJ-DmcGMHHV.js → chunk-AQP2D5EJ-BDVikNJT.js} +4 -4
  15. package/dist/component/{chunk-FMBD7UC4-T7thtdBK.js → chunk-FMBD7UC4-C864-npb.js} +2 -2
  16. package/dist/component/{chunk-ND2GUHAM-Dm_d0Ags.js → chunk-ND2GUHAM-DuitYR9A.js} +2 -2
  17. package/dist/component/{chunk-QZHKN3VN-D2PGEfVN.js → chunk-QZHKN3VN-B9uI1TYV.js} +2 -2
  18. package/dist/component/{classDiagram-4FO5ZUOK-Bn7KwDp9.js → classDiagram-4FO5ZUOK-BUdCEjaj.js} +3 -3
  19. package/dist/component/{classDiagram-v2-Q7XG4LA2-Bn7KwDp9.js → classDiagram-v2-Q7XG4LA2-BUdCEjaj.js} +3 -3
  20. package/dist/component/{cose-bilkent-S5V4N54A-BtDuNpUN.js → cose-bilkent-S5V4N54A-Dgk__ohs.js} +2 -2
  21. package/dist/component/{dagre-BM42HDAG-BknZdIOQ.js → dagre-BM42HDAG-DGHFHFPf.js} +2 -2
  22. package/dist/component/{diagram-2AECGRRQ-ISHN0dHe.js → diagram-2AECGRRQ-DvGSzrwW.js} +3 -3
  23. package/dist/component/{diagram-5GNKFQAL-7gWbpLCQ.js → diagram-5GNKFQAL-XebuIyjn.js} +4 -4
  24. package/dist/component/{diagram-KO2AKTUF-B63ZLzkh.js → diagram-KO2AKTUF-slUL6XEO.js} +3 -3
  25. package/dist/component/{diagram-LMA3HP47-hhw0MjoS.js → diagram-LMA3HP47-BEPY8GOZ.js} +3 -3
  26. package/dist/component/{diagram-OG6HWLK6-D_L9Gvuh.js → diagram-OG6HWLK6-DHI_0aIk.js} +4 -4
  27. package/dist/component/{erDiagram-TEJ5UH35-BAg27ZHd.js → erDiagram-TEJ5UH35-D-6DbJr-.js} +5 -5
  28. package/dist/component/{flowDiagram-I6XJVG4X-DDYjK7xG.js → flowDiagram-I6XJVG4X-Cw87OG_x.js} +7 -7
  29. package/dist/component/{ganttDiagram-6RSMTGT7-CDNAiKQG.js → ganttDiagram-6RSMTGT7-B47s5HUB.js} +3 -3
  30. package/dist/component/{gitGraphDiagram-PVQCEYII-CY1N7jOJ.js → gitGraphDiagram-PVQCEYII-DqFW3uiq.js} +4 -4
  31. package/dist/component/{highlighted-body-OFNGDK62-DHwLnkF_.js → highlighted-body-OFNGDK62-CBU3EdTE.js} +2 -2
  32. package/dist/component/index.js +2 -2
  33. package/dist/component/{infoDiagram-5YYISTIA-Cbgk6g6j.js → infoDiagram-5YYISTIA-_0W78xb_.js} +2 -2
  34. package/dist/component/{ishikawaDiagram-YF4QCWOH-BUfiorJj.js → ishikawaDiagram-YF4QCWOH-CvybNkGE.js} +2 -2
  35. package/dist/component/{journeyDiagram-JHISSGLW-Bh4IizEm.js → journeyDiagram-JHISSGLW-DgLrQs9G.js} +5 -5
  36. package/dist/component/{kanban-definition-UN3LZRKU-CgWqLfFM.js → kanban-definition-UN3LZRKU-ReYnw5Xl.js} +3 -3
  37. package/dist/component/{linear-D1rJivs3.js → linear-Cih5KQ00.js} +2 -2
  38. package/dist/component/{mermaid-GHXKKRXX-iO2IZZUN.js → mermaid-GHXKKRXX-B6ix-Z04.js} +30129 -29350
  39. package/dist/component/{mindmap-definition-RKZ34NQL-DeQED-9b.js → mindmap-definition-RKZ34NQL-hRhkTdF6.js} +4 -4
  40. package/dist/component/{pieDiagram-4H26LBE5-CZ5Zt_mz.js → pieDiagram-4H26LBE5-DAAEUZCY.js} +4 -4
  41. package/dist/component/{quadrantDiagram-W4KKPZXB-Dib1AukJ.js → quadrantDiagram-W4KKPZXB-Benxdf_G.js} +3 -3
  42. package/dist/component/{requirementDiagram-4Y6WPE33-DubjTJYS.js → requirementDiagram-4Y6WPE33-BxvkbDYP.js} +4 -4
  43. package/dist/component/{sankeyDiagram-5OEKKPKP-Cq2S3XKs.js → sankeyDiagram-5OEKKPKP-RPwwVwu3.js} +2 -2
  44. package/dist/component/{sequenceDiagram-3UESZ5HK-BUo5k0zn.js → sequenceDiagram-3UESZ5HK-C-prnAtS.js} +4 -4
  45. package/dist/component/{stateDiagram-AJRCARHV-DJwQp0D7.js → stateDiagram-AJRCARHV-BEIQAx9e.js} +3 -3
  46. package/dist/component/{stateDiagram-v2-BHNVJYJU-BX77P5aq.js → stateDiagram-v2-BHNVJYJU-BD5dkY8l.js} +3 -3
  47. package/dist/component/{timeline-definition-PNZ67QCA-DnQ481VI.js → timeline-definition-PNZ67QCA-DQJPMkfL.js} +3 -3
  48. package/dist/component/{vennDiagram-CIIHVFJN-BQ0X92lQ.js → vennDiagram-CIIHVFJN-CreOqXMc.js} +2 -2
  49. package/dist/component/{wardleyDiagram-YWT4CUSO-CMTnjVTA.js → wardleyDiagram-YWT4CUSO--dbQqySn.js} +3 -3
  50. package/dist/component/{xychartDiagram-2RQKCTM6-BLSiRWug.js → xychartDiagram-2RQKCTM6-BOSkmQiX.js} +3 -3
  51. package/dist/components/embed/EmbedAvatar.d.ts +8 -1
  52. package/dist/components/embed/EmbedHeader.d.ts +25 -2
  53. package/dist/components/embed/EmbedRail.d.ts +12 -4
  54. package/dist/components/embed/EmbedSessions.d.ts +13 -2
  55. package/dist/components/embed/MobileNavBar.d.ts +4 -1
  56. package/dist/components/embed/SessionStatsPanel.d.ts +12 -0
  57. package/dist/components/embed/rail-flags.d.ts +32 -0
  58. package/dist/embed/adoption-notice.d.ts +10 -0
  59. package/dist/embed/presets.d.ts +10 -0
  60. package/dist/embed/theme.d.ts +13 -0
  61. package/dist/embed/use-workspace-file-download.d.ts +10 -2
  62. package/dist/embed/voice/line-dispatch.d.ts +21 -0
  63. package/dist/embed/voice/line-run-reader.d.ts +16 -1
  64. package/dist/embed/voice/line-slots.d.ts +42 -4
  65. package/dist/embed/voice-call-lines.d.ts +33 -3
  66. package/dist/i18n/messages/en.d.ts +22 -0
  67. package/dist/i18n/messages/surfaces/header.d.ts +12 -0
  68. package/dist/i18n/messages/surfaces/sessions.d.ts +3 -0
  69. package/dist/i18n/messages/surfaces/stats.d.ts +55 -0
  70. package/dist/stream/belong-chat-transport.d.ts +19 -8
  71. package/dist/stream/chat-export-store.d.ts +35 -0
  72. package/dist/stream/preview-panel-store.d.ts +8 -0
  73. package/dist/stream/session-stats-csv.d.ts +52 -0
  74. package/dist/stream/stream-state-store.d.ts +30 -1
  75. package/package.json +1 -1
@@ -107,6 +107,13 @@ export declare const isLineReservation: (line: number, epoch: number) => boolean
107
107
  * (the boolean chat.tsx's aliasing guard needs) and `markLineSeen`'s callers
108
108
  * (which need the actual line number to mark seen). */
109
109
  export declare const lineBoundToSession: (sessionId: string) => AgentLine | undefined;
110
+ /** The line — INCLUDING line 1 — currently bound to `sessionId`, or `undefined`
111
+ * when no agent holds it. Unlike `lineBoundToSession` (deliberately line-1-blind
112
+ * for the aliasing guard), this is the honest "which agent already owns this
113
+ * conversation" lookup a History reopen needs: reopening a session that Agent 1
114
+ * already holds must SWITCH to Agent 1, not adopt (duplicate) it onto whatever
115
+ * background line the user happens to be viewing. */
116
+ export declare const lineOwningSession: (sessionId: string) => AgentLine | undefined;
110
117
  /** True when `sessionId` is already the session of some line OTHER than line
111
118
  * 1 — chat.tsx's line-1 aliasing guard uses this to skip rebinding line 1
112
119
  * onto a background line's session while the user is viewing it via
@@ -185,10 +192,33 @@ export declare const __bindLineSessionForTest: (line: number, sessionId: string)
185
192
  export declare const persistSlotBinding: (line: number, sessionId: string, label: string) => void;
186
193
  /** `stop_agent`'s target: bound by the line-run reader once a background
187
194
  * dispatch's POST returns a runId, and cleared to `null` when that run
188
- * finishes/fails/errors — a stopped or finished run must not look stoppable
189
- * again. No-op on an unknown line or an unchanged value (mirrors
190
- * `setLineStatus`'s re-write-on-every-render tolerance). */
195
+ * reaches a confirmed terminal state — a stopped or finished run must not look
196
+ * stoppable again. Transport-only failures deliberately retain it for
197
+ * re-attachment. No-op on an unknown line or an unchanged value (mirrors
198
+ * `setLineStatus`'s re-write-on-every-render tolerance). In-memory only —
199
+ * production code wanting the binding to SURVIVE a reload calls
200
+ * `persistSlotRun` below instead; this stays exported for the `__force*` /
201
+ * `__bindLineSessionForTest` style test harnesses that intentionally want
202
+ * the memory-only half. */
191
203
  export declare const bindLineRun: (line: number, runId: string | null) => void;
204
+ /**
205
+ * The durable half of `bindLineRun` (F3/R4): call this — not the bare
206
+ * `bindLineRun` — whenever a background dispatch's POST accepts a run, and
207
+ * again when that run reaches a terminal state (`onFinish`/`onError`
208
+ * clearing it back to `null`). Updates the in-memory registry AND the
209
+ * persisted slot together, so the ONE thing a page reload cannot observe by
210
+ * itself — "is this line's run still going?" — survives the reload instead
211
+ * of silently reverting to a lying "idle". `line-dispatch.ts`'s
212
+ * `attachLineReader` is the ONE seam that calls this, shared by a live
213
+ * dispatch and the boot re-attach (`reattachPendingLineRuns`) alike — same
214
+ * discipline as `persistSlotBinding`'s ADOPTION seam.
215
+ *
216
+ * Line 1 never goes through this (line-dispatch.ts never dispatches to line
217
+ * 1 — see its module doc): its `runId` stays the always-`null` value
218
+ * `bindLineRun` already tolerates, and its own run is resolved at stop-time
219
+ * from the stream-state store instead (`AgentLine.runId`'s doc).
220
+ */
221
+ export declare const persistSlotRun: (line: number, runId: string | null) => void;
192
222
  export declare const setLineStatus: (line: number, status: AgentLineStatus, lastText?: string) => void;
193
223
  /** CallScreen's agent board reads this as the live "what is it doing right
194
224
  * now" line under a working line's status dot — written on every phase
@@ -65,6 +65,22 @@ export declare const en: {
65
65
  readonly reconnected: "Reconnected";
66
66
  readonly retry: "Retry";
67
67
  };
68
+ readonly stats: {
69
+ readonly title: "Session stats";
70
+ readonly input: "Input";
71
+ readonly output: "Output";
72
+ readonly total: "Total";
73
+ readonly timeRunning: "Time running";
74
+ readonly turns: "Turns";
75
+ readonly toolCalls: "Tool calls";
76
+ readonly runtime: "Runtime";
77
+ readonly empty: "No activity yet";
78
+ readonly loading: "Loading…";
79
+ readonly loadError: "Could not load stats";
80
+ readonly retry: "Retry";
81
+ readonly exportThis: "Export this session (CSV)";
82
+ readonly exportAll: "Export all sessions (CSV)";
83
+ };
68
84
  readonly sessions: {
69
85
  readonly chats: "Chats";
70
86
  readonly newChat: "New chat";
@@ -84,6 +100,7 @@ export declare const en: {
84
100
  readonly untitledSession: "Untitled session";
85
101
  readonly updated: "updated";
86
102
  readonly loadedIntoAgent: "Loaded into Agent {{line}}";
103
+ readonly loadingChat: "Loading chat…";
87
104
  };
88
105
  readonly scheduled: {
89
106
  readonly viewTitle: "Scheduled";
@@ -214,7 +231,11 @@ export declare const en: {
214
231
  readonly expand: "Expand";
215
232
  readonly collapse: "Collapse";
216
233
  readonly spawnAgent: "New agent";
234
+ readonly closeChat: "Close this chat";
217
235
  readonly closeAgent: "Close {{label}}";
236
+ readonly exportChat: "Download chat (JSON)";
237
+ readonly exportChatGenerating: "Preparing chat export…";
238
+ readonly exportChatLast: "Download chat (JSON) — last export {{time}}";
218
239
  };
219
240
  readonly files: {
220
241
  readonly refreshFiles: "Refresh files";
@@ -388,6 +409,7 @@ export declare const en: {
388
409
  readonly conversation: {
389
410
  readonly thinking: "Thinking…";
390
411
  readonly followerBanner: "This conversation is open in another tab";
412
+ readonly historyUnavailable: "Couldn't load this conversation — try reopening it.";
391
413
  };
392
414
  readonly compaction: {
393
415
  readonly compacted: "Compacted {{count}} earlier messages into a summary.";
@@ -16,7 +16,11 @@ export declare const headerEn: {
16
16
  readonly expand: "Expand";
17
17
  readonly collapse: "Collapse";
18
18
  readonly spawnAgent: "New agent";
19
+ readonly closeChat: "Close this chat";
19
20
  readonly closeAgent: "Close {{label}}";
21
+ readonly exportChat: "Download chat (JSON)";
22
+ readonly exportChatGenerating: "Preparing chat export…";
23
+ readonly exportChatLast: "Download chat (JSON) — last export {{time}}";
20
24
  };
21
25
  };
22
26
  export declare const headerEs: {
@@ -36,7 +40,11 @@ export declare const headerEs: {
36
40
  expand: string;
37
41
  collapse: string;
38
42
  spawnAgent: string;
43
+ closeChat: string;
39
44
  closeAgent: string;
45
+ exportChat: string;
46
+ exportChatGenerating: string;
47
+ exportChatLast: string;
40
48
  };
41
49
  };
42
50
  export declare const headerPt: {
@@ -56,6 +64,10 @@ export declare const headerPt: {
56
64
  expand: string;
57
65
  collapse: string;
58
66
  spawnAgent: string;
67
+ closeChat: string;
59
68
  closeAgent: string;
69
+ exportChat: string;
70
+ exportChatGenerating: string;
71
+ exportChatLast: string;
60
72
  };
61
73
  };
@@ -19,6 +19,7 @@ export declare const sessionsEn: {
19
19
  readonly untitledSession: "Untitled session";
20
20
  readonly updated: "updated";
21
21
  readonly loadedIntoAgent: "Loaded into Agent {{line}}";
22
+ readonly loadingChat: "Loading chat…";
22
23
  };
23
24
  };
24
25
  export declare const sessionsEs: {
@@ -41,6 +42,7 @@ export declare const sessionsEs: {
41
42
  untitledSession: string;
42
43
  updated: string;
43
44
  loadedIntoAgent: string;
45
+ loadingChat: string;
44
46
  };
45
47
  };
46
48
  export declare const sessionsPt: {
@@ -63,5 +65,6 @@ export declare const sessionsPt: {
63
65
  untitledSession: string;
64
66
  updated: string;
65
67
  loadedIntoAgent: string;
68
+ loadingChat: string;
66
69
  };
67
70
  };
@@ -0,0 +1,55 @@
1
+ /** Session stats panel strings. */
2
+ export declare const statsEn: {
3
+ readonly stats: {
4
+ readonly title: "Session stats";
5
+ readonly input: "Input";
6
+ readonly output: "Output";
7
+ readonly total: "Total";
8
+ readonly timeRunning: "Time running";
9
+ readonly turns: "Turns";
10
+ readonly toolCalls: "Tool calls";
11
+ readonly runtime: "Runtime";
12
+ readonly empty: "No activity yet";
13
+ readonly loading: "Loading…";
14
+ readonly loadError: "Could not load stats";
15
+ readonly retry: "Retry";
16
+ readonly exportThis: "Export this session (CSV)";
17
+ readonly exportAll: "Export all sessions (CSV)";
18
+ };
19
+ };
20
+ export declare const statsEs: {
21
+ stats: {
22
+ title: string;
23
+ input: string;
24
+ output: string;
25
+ total: string;
26
+ timeRunning: string;
27
+ turns: string;
28
+ toolCalls: string;
29
+ runtime: string;
30
+ empty: string;
31
+ loading: string;
32
+ loadError: string;
33
+ retry: string;
34
+ exportThis: string;
35
+ exportAll: string;
36
+ };
37
+ };
38
+ export declare const statsPt: {
39
+ stats: {
40
+ title: string;
41
+ input: string;
42
+ output: string;
43
+ total: string;
44
+ timeRunning: string;
45
+ turns: string;
46
+ toolCalls: string;
47
+ runtime: string;
48
+ empty: string;
49
+ loading: string;
50
+ loadError: string;
51
+ retry: string;
52
+ exportThis: string;
53
+ exportAll: string;
54
+ };
55
+ };
@@ -198,36 +198,36 @@ export declare const wireStreamPartSchema: z.ZodDiscriminatedUnion<"type", [z.Zo
198
198
  }, "strip", z.ZodTypeAny, {
199
199
  toolName: string;
200
200
  state: "completed" | "failed" | "started";
201
- input?: Record<string, unknown> | undefined;
202
- output?: Record<string, unknown> | null | undefined;
203
201
  error?: {
204
202
  message: string;
205
203
  code: string;
206
204
  severity?: "error" | "stop" | undefined;
207
205
  } | undefined;
206
+ input?: Record<string, unknown> | undefined;
207
+ output?: Record<string, unknown> | null | undefined;
208
208
  }, {
209
209
  toolName: string;
210
210
  state: "completed" | "failed" | "started";
211
- input?: Record<string, unknown> | undefined;
212
- output?: Record<string, unknown> | null | undefined;
213
211
  error?: {
214
212
  message: string;
215
213
  code: string;
216
214
  severity?: "error" | "stop" | undefined;
217
215
  } | undefined;
216
+ input?: Record<string, unknown> | undefined;
217
+ output?: Record<string, unknown> | null | undefined;
218
218
  }>;
219
219
  }, "strip", z.ZodTypeAny, {
220
220
  id: string;
221
221
  data: {
222
222
  toolName: string;
223
223
  state: "completed" | "failed" | "started";
224
- input?: Record<string, unknown> | undefined;
225
- output?: Record<string, unknown> | null | undefined;
226
224
  error?: {
227
225
  message: string;
228
226
  code: string;
229
227
  severity?: "error" | "stop" | undefined;
230
228
  } | undefined;
229
+ input?: Record<string, unknown> | undefined;
230
+ output?: Record<string, unknown> | null | undefined;
231
231
  };
232
232
  type: "data-tool-call";
233
233
  }, {
@@ -235,13 +235,13 @@ export declare const wireStreamPartSchema: z.ZodDiscriminatedUnion<"type", [z.Zo
235
235
  data: {
236
236
  toolName: string;
237
237
  state: "completed" | "failed" | "started";
238
- input?: Record<string, unknown> | undefined;
239
- output?: Record<string, unknown> | null | undefined;
240
238
  error?: {
241
239
  message: string;
242
240
  code: string;
243
241
  severity?: "error" | "stop" | undefined;
244
242
  } | undefined;
243
+ input?: Record<string, unknown> | undefined;
244
+ output?: Record<string, unknown> | null | undefined;
245
245
  };
246
246
  type: "data-tool-call";
247
247
  }>, z.ZodObject<{
@@ -688,6 +688,9 @@ export declare const STALL_TIMEOUT_MS = 30000;
688
688
  * anywhere inside an armed grace can still resume the run cursor.
689
689
  */
690
690
  export declare const RESUME_GRACE_MS = 120000;
691
+ /** Test-only: forget every claimed live-stream entry (module state persists
692
+ * across tests in the same file otherwise). */
693
+ export declare const __resetLiveStreamRegistryForTest: () => void;
691
694
  export type BelongChatTransportOptions = {
692
695
  /** Belong cloud base URL, e.g. `http://localhost:8787`. */
693
696
  readonly apiBaseUrl: string;
@@ -714,6 +717,14 @@ export type BelongChatTransportOptions = {
714
717
  * Tests may pin it explicitly.
715
718
  */
716
719
  readonly workspaceExternalId?: string | null;
720
+ /**
721
+ * Foreground-mount generation (R2 — order-aware selection). Defaults to the
722
+ * CURRENT generation at construction — captured once, so a transport whose
723
+ * `select_if_empty` persist resolves AFTER a newer ChatRoute remount (a
724
+ * fresher chat already superseded it) never steals the selection pointer
725
+ * from that newer transport. Tests may pin it explicitly.
726
+ */
727
+ readonly foregroundGeneration?: number;
717
728
  };
718
729
  export type StreamContext = {
719
730
  /** Stable id we emit on every `text-delta`. Null when no text run is open. */
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Chat-export state — module-level, so a pending export SURVIVES switching
3
+ * chats/views: the dock header (BelongDock) reads per-session state via
4
+ * `useSyncExternalStore`, while the poller lives here, independent of any
5
+ * mounted route. When the backend job turns `ready`, the file downloads
6
+ * AUTOMATICALLY — even if the user is viewing another chat at that moment —
7
+ * and the session's button reverts.
8
+ *
9
+ * Flow (see belong-cloud session-export.routes.ts):
10
+ * startChatExport → POST /v1/sessions/:id/exports → 202 { exportId }
11
+ * poller (~2s) → GET …/exports/:exportId → queued|running|ready|failed
12
+ * ready → GET …/exports/:exportId/file → browser download
13
+ *
14
+ * Persistence (best-effort `localStorage`, Zod-parsed on read §4):
15
+ * • pending exports — a page reload resumes polling and still auto-downloads
16
+ * • per-session "last export" timestamps — the hover affordance. UI-ONLY by
17
+ * design: the backend intentionally does not persist this.
18
+ */
19
+ export type ChatExportSessionState = {
20
+ readonly status: "idle" | "generating";
21
+ /** Epoch ms of this session's last successful export download (UI-only). */
22
+ readonly lastExportAtMs: number | null;
23
+ };
24
+ export type StartChatExportResult = "started" | "already_generating" | "failed";
25
+ /**
26
+ * Request a fresh export for the session and start (or join) the poller.
27
+ * Idempotent per session while one is in flight — the header button is also
28
+ * disabled while generating, but the store is the authority (§28).
29
+ */
30
+ export declare const startChatExport: (apiBaseUrl: string, sessionId: string) => Promise<StartChatExportResult>;
31
+ /** Per-session snapshot for the header button (identity-stable across reads). */
32
+ export declare const peekChatExportState: (sessionId: string) => ChatExportSessionState;
33
+ export declare const subscribeChatExport: (listener: () => void) => (() => void);
34
+ /** Test-only: drop all state, listeners, storage, and the poll timer. */
35
+ export declare const resetChatExportStoreForTests: () => void;
@@ -21,6 +21,12 @@ export declare const DEFAULT_PREVIEW_PANEL_WIDTH_PX = 480;
21
21
  * What the panel is previewing. A published artifact is fetched by id; a
22
22
  * workspace file by its workspace-relative path. Both resolve to an auth'd
23
23
  * bytes URL in `PreviewPanel`.
24
+ *
25
+ * A workspace target PINS the workspace it was opened from. The path is
26
+ * relative to `ws-<id>/`, so it is only meaningful together with that id —
27
+ * reading the live scope later instead would silently repoint an open preview
28
+ * at a different workspace's file (or, when the scope goes `missing`, at the
29
+ * unscoped root) the next time the panel re-renders.
24
30
  */
25
31
  export type PreviewTarget = {
26
32
  readonly kind: "artifact";
@@ -32,6 +38,8 @@ export type PreviewTarget = {
32
38
  readonly path: string;
33
39
  readonly title: string;
34
40
  readonly mimeType: string;
41
+ /** The workspace this path belongs to; null when the host configures none. */
42
+ readonly workspaceExternalId: string | null;
35
43
  };
36
44
  export type PreviewPanelState = {
37
45
  readonly open: boolean;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Session-stats CSV builders (plan 2026-07-24). Pure string builders (no DOM)
3
+ * so they are unit-tested; `downloadCsv` is the only impure part.
4
+ *
5
+ * Types mirror the belong-cloud `SessionStatsDetail` / `SessionStatsSummaryRow`
6
+ * DTOs. Kept as an explicit local mirror (not inferred from AppType) so the CSV
7
+ * column contract is readable in one place.
8
+ *
9
+ * RFC-4180: CRLF line breaks, header first, a field is quoted when it contains
10
+ * `"`, `,`, CR or LF; interior quotes are doubled. CSV-injection guard: a text
11
+ * field starting with = + - @ is prefixed with a single quote before quoting.
12
+ */
13
+ export type SessionStatsTurn = {
14
+ readonly turn: number;
15
+ readonly at: string;
16
+ readonly inputTokens: number;
17
+ readonly outputTokens: number;
18
+ readonly totalTokens: number;
19
+ };
20
+ export type SessionStatsDetail = {
21
+ readonly totalInputTokens: number;
22
+ readonly totalOutputTokens: number;
23
+ readonly totalTokens: number;
24
+ readonly turns: number;
25
+ readonly runningMs: number;
26
+ readonly toolCalls: number;
27
+ readonly runtimes: readonly string[];
28
+ readonly turnRows: readonly SessionStatsTurn[];
29
+ };
30
+ export type SessionStatsSummaryRow = {
31
+ readonly sessionId: string;
32
+ readonly title: string | null;
33
+ readonly createdAt: string;
34
+ readonly updatedAt: string;
35
+ readonly totalInputTokens: number;
36
+ readonly totalOutputTokens: number;
37
+ readonly totalTokens: number;
38
+ readonly turns: number;
39
+ readonly runningMs: number;
40
+ readonly toolCalls: number;
41
+ readonly runtimes: readonly string[];
42
+ };
43
+ /** Human duration: `m:ss` under an hour, `h:mm:ss` at/over an hour. */
44
+ export declare const formatDurationMs: (ms: number) => string;
45
+ export declare const toPerTurnCsv: (detail: SessionStatsDetail) => string;
46
+ export declare const toSummaryCsv: (rows: readonly SessionStatsSummaryRow[]) => string;
47
+ /**
48
+ * Trigger a browser download of `csv` as `filename`. Appends a transient anchor
49
+ * to document.body (NOT the shadow root) so the click reaches the top document —
50
+ * required for the download to fire from inside the dock's closed Shadow DOM.
51
+ */
52
+ export declare const downloadCsv: (filename: string, csv: string) => void;
@@ -30,6 +30,23 @@ declare const streamStateSchema: z.ZodObject<{
30
30
  lastEventId: string | null;
31
31
  }>;
32
32
  export type PersistedStreamState = z.infer<typeof streamStateSchema>;
33
+ /** Bump the foreground-mount generation. Call exactly once per ChatRoute
34
+ * remount (BelongDock's `chatMount.key` writers), synchronously alongside
35
+ * the pointer change that triggers the remount. */
36
+ export declare const nextForegroundGeneration: () => number;
37
+ /** Read the current foreground-mount generation without bumping it. A
38
+ * transport captures this at construction to stamp its later persists. */
39
+ export declare const peekForegroundGeneration: () => number;
40
+ /** Peek the most recent generation-loss orphan (see above), or null. A single
41
+ * most-recent slot, not a queue: this is a belt-and-braces safety net for the
42
+ * self-referential bind, not the primary recovery mechanism, and the race it
43
+ * guards against produces at most one loser per window in practice. */
44
+ export declare const peekGenerationLostSession: () => string | null;
45
+ /** Consume the orphan once a reconciler has adopted it onto a line. A no-op
46
+ * when `sessionId` does not match the currently-tracked loser (already
47
+ * consumed, or superseded by a newer loss) — a stale reconciler can never
48
+ * clear a loss it did not actually adopt. */
49
+ export declare const consumeGenerationLostSession: (sessionId: string) => void;
33
50
  /**
34
51
  * The tab's active stream state.
35
52
  *
@@ -45,8 +62,20 @@ export type PersistedStreamState = z.infer<typeof streamStateSchema>;
45
62
  * is demoted off the live run cursor.
46
63
  */
47
64
  export declare const readStreamState: (workspaceId?: string | null) => PersistedStreamState | null;
65
+ /**
66
+ * Forget a DELETED session from the shared seed — narrowly, only when the
67
+ * seed still names it. `clearStreamState` (New chat) deliberately leaves the
68
+ * shared seed alone so an unrelated tab's most-recent conversation survives;
69
+ * that assumption breaks when the session in the seed was just deleted, since
70
+ * any brand-new tab (e.g. a spawned browser-automation preview tab — see
71
+ * `readStreamState`'s adoption path) would otherwise adopt a session that
72
+ * 404s/409s on every request. Session delete is the only caller: an ordinary
73
+ * "New chat" must not reach this, which is why it is a separate function
74
+ * rather than a flag on `clearStreamState`.
75
+ */
76
+ export declare const forgetDeletedSessionSeed: (sessionId: string, workspaceId?: string | null) => void;
48
77
  export type StreamStateWriteMode = "select" | "select_if_empty" | "preserve_selection";
49
- export declare const writeStreamState: (state: Omit<PersistedStreamState, "updatedAt">, workspaceId?: string | null, mode?: StreamStateWriteMode) => void;
78
+ export declare const writeStreamState: (state: Omit<PersistedStreamState, "updatedAt">, workspaceId?: string | null, mode?: StreamStateWriteMode, generation?: number) => void;
50
79
  /**
51
80
  * Clear THIS TAB's pointer (New chat). Removes only the per-tab sessionStorage
52
81
  * record and marks the tab "seeded" so a reload stays blank instead of
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@belonguniverseai/react-sdk",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Belong — embeddable React AI assistant dock. Mount <BelongWidget> in your app tree with getToken dependency-injection auth.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",