@belonguniverseai/react-sdk 0.3.6 → 0.4.1

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 (97) hide show
  1. package/dist/api/client.d.ts +238 -0
  2. package/dist/api/queries.d.ts +16 -0
  3. package/dist/api/query-keys.d.ts +1 -0
  4. package/dist/api/report-client-error.d.ts +1 -1
  5. package/dist/api/task-schedules.d.ts +3 -3
  6. package/dist/component/BelongWidget.d.ts +5 -3
  7. package/dist/component/{arc-6nY2VvBR.js → arc-Du1-HUt0.js} +2 -2
  8. package/dist/component/{architectureDiagram-3BPJPVTR-8NzFzSu-.js → architectureDiagram-3BPJPVTR-NTFoFNN-.js} +3 -3
  9. package/dist/component/{blockDiagram-GPEHLZMM-DUEwMafH.js → blockDiagram-GPEHLZMM-9LBL4EUV.js} +4 -4
  10. package/dist/component/{c4Diagram-AAUBKEIU-CDD_6To7.js → c4Diagram-AAUBKEIU-C1enIoRg.js} +3 -3
  11. package/dist/component/{channel-B4iaYdVF.js → channel-CNnOkAN_.js} +2 -2
  12. package/dist/component/{chunk-2J33WTMH-DyOrhFxY.js → chunk-2J33WTMH-X2Iy3mMD.js} +2 -2
  13. package/dist/component/{chunk-4BX2VUAB-Bc66-Fjy.js → chunk-4BX2VUAB-BLlcE09Q.js} +2 -2
  14. package/dist/component/{chunk-55IACEB6-CIN0g3JH.js → chunk-55IACEB6-23v_td5T.js} +2 -2
  15. package/dist/component/{chunk-727SXJPM-BGs-m5or.js → chunk-727SXJPM-BC2kAa1t.js} +6 -6
  16. package/dist/component/{chunk-AQP2D5EJ-CPlwnVcL.js → chunk-AQP2D5EJ-CsRFVdwF.js} +4 -4
  17. package/dist/component/{chunk-FMBD7UC4-09viRWEH.js → chunk-FMBD7UC4-CWrggihb.js} +2 -2
  18. package/dist/component/{chunk-ND2GUHAM-BJo4K53f.js → chunk-ND2GUHAM-Bj78QMsn.js} +2 -2
  19. package/dist/component/{chunk-QZHKN3VN-DufugBok.js → chunk-QZHKN3VN-CS_FAlLS.js} +2 -2
  20. package/dist/component/{classDiagram-4FO5ZUOK-DfAygW-7.js → classDiagram-4FO5ZUOK-ci84KOU1.js} +3 -3
  21. package/dist/component/{classDiagram-v2-Q7XG4LA2-DfAygW-7.js → classDiagram-v2-Q7XG4LA2-ci84KOU1.js} +3 -3
  22. package/dist/component/{cose-bilkent-S5V4N54A-CUKOuMcm.js → cose-bilkent-S5V4N54A-QLIj0pt2.js} +2 -2
  23. package/dist/component/{dagre-BM42HDAG-BPRObW6r.js → dagre-BM42HDAG-D32wP-VH.js} +2 -2
  24. package/dist/component/{diagram-2AECGRRQ-Cxsg-pXz.js → diagram-2AECGRRQ-Dn47q_hT.js} +3 -3
  25. package/dist/component/{diagram-5GNKFQAL-U6L8NDef.js → diagram-5GNKFQAL-Df7a_ICg.js} +4 -4
  26. package/dist/component/{diagram-KO2AKTUF-BxN_e8Dk.js → diagram-KO2AKTUF-CNcoKufc.js} +3 -3
  27. package/dist/component/{diagram-LMA3HP47-Dbkb79LU.js → diagram-LMA3HP47-Dq8j6XNs.js} +3 -3
  28. package/dist/component/{diagram-OG6HWLK6-SASqlYMy.js → diagram-OG6HWLK6-CZ1WglbZ.js} +4 -4
  29. package/dist/component/{erDiagram-TEJ5UH35-CDTBM9wY.js → erDiagram-TEJ5UH35-CDlHARAu.js} +5 -5
  30. package/dist/component/{flowDiagram-I6XJVG4X-DugkNxCw.js → flowDiagram-I6XJVG4X-Cw1mKy8X.js} +7 -7
  31. package/dist/component/{ganttDiagram-6RSMTGT7-D3FuGu21.js → ganttDiagram-6RSMTGT7-B3FUForj.js} +3 -3
  32. package/dist/component/{gitGraphDiagram-PVQCEYII-DMKggb_e.js → gitGraphDiagram-PVQCEYII-BgHuuQ27.js} +4 -4
  33. package/dist/component/{highlighted-body-OFNGDK62-Bnl71RgK.js → highlighted-body-OFNGDK62-BTv_Fxf3.js} +2 -2
  34. package/dist/component/index.js +2 -2
  35. package/dist/component/{infoDiagram-5YYISTIA-BaUo1fFU.js → infoDiagram-5YYISTIA-DE9i_OcK.js} +2 -2
  36. package/dist/component/{ishikawaDiagram-YF4QCWOH-DofOP6uV.js → ishikawaDiagram-YF4QCWOH-BDe88Hz2.js} +2 -2
  37. package/dist/component/{journeyDiagram-JHISSGLW-D-xl9LqQ.js → journeyDiagram-JHISSGLW-D3t45UC1.js} +5 -5
  38. package/dist/component/{kanban-definition-UN3LZRKU-Lfcidbpn.js → kanban-definition-UN3LZRKU-DfFJIuhU.js} +3 -3
  39. package/dist/component/{linear-CtCl_nrs.js → linear-AXxuun7R.js} +2 -2
  40. package/dist/component/{mermaid-GHXKKRXX-CnzRBGo3.js → mermaid-GHXKKRXX-D7NVqIBP.js} +31181 -29271
  41. package/dist/component/{mindmap-definition-RKZ34NQL-RZVaz4dV.js → mindmap-definition-RKZ34NQL-cTac4kYU.js} +4 -4
  42. package/dist/component/{pieDiagram-4H26LBE5-CEwcfNwI.js → pieDiagram-4H26LBE5-B1SubLQb.js} +4 -4
  43. package/dist/component/{quadrantDiagram-W4KKPZXB-BJBEiTgK.js → quadrantDiagram-W4KKPZXB-CzyBW8Cr.js} +3 -3
  44. package/dist/component/{requirementDiagram-4Y6WPE33-CVHog8O-.js → requirementDiagram-4Y6WPE33-DgS33NcX.js} +4 -4
  45. package/dist/component/{sankeyDiagram-5OEKKPKP-Cn1N0qrl.js → sankeyDiagram-5OEKKPKP-Cp4o_akq.js} +2 -2
  46. package/dist/component/{sequenceDiagram-3UESZ5HK-CRaBqdL0.js → sequenceDiagram-3UESZ5HK-2gf91-2b.js} +4 -4
  47. package/dist/component/{stateDiagram-AJRCARHV-9q4hv0ii.js → stateDiagram-AJRCARHV-BByZezJw.js} +3 -3
  48. package/dist/component/{stateDiagram-v2-BHNVJYJU-By7O-5eN.js → stateDiagram-v2-BHNVJYJU-B-IObShO.js} +3 -3
  49. package/dist/component/{timeline-definition-PNZ67QCA-BWfxZI7f.js → timeline-definition-PNZ67QCA-D_2NG1sj.js} +3 -3
  50. package/dist/component/{vennDiagram-CIIHVFJN-B_PQ6bU6.js → vennDiagram-CIIHVFJN-BjrQUaEs.js} +2 -2
  51. package/dist/component/{wardleyDiagram-YWT4CUSO-P7tCzeA0.js → wardleyDiagram-YWT4CUSO-DYcvfAeQ.js} +3 -3
  52. package/dist/component/{xychartDiagram-2RQKCTM6-B4Z_Zrko.js → xychartDiagram-2RQKCTM6-CtLaJFtQ.js} +3 -3
  53. package/dist/components/embed/AgentChatIcon.d.ts +16 -0
  54. package/dist/components/embed/AgentPhaseIcon.d.ts +17 -0
  55. package/dist/components/embed/EmbedAvatar.d.ts +21 -2
  56. package/dist/components/embed/EmbedHeader.d.ts +25 -2
  57. package/dist/components/embed/EmbedRail.d.ts +20 -1
  58. package/dist/components/embed/EmbedSessions.d.ts +33 -8
  59. package/dist/components/embed/MobileNavBar.d.ts +4 -1
  60. package/dist/components/embed/SessionStatsPanel.d.ts +12 -0
  61. package/dist/components/embed/rail-flags.d.ts +23 -0
  62. package/dist/embed/adoption-notice.d.ts +32 -0
  63. package/dist/embed/auth0-cache.d.ts +32 -0
  64. package/dist/embed/auth0-refresh.d.ts +8 -5
  65. package/dist/embed/copy.d.ts +2 -0
  66. package/dist/embed/dock-state.d.ts +16 -0
  67. package/dist/embed/global.d.ts +6 -0
  68. package/dist/embed/host-layout-vars.d.ts +24 -0
  69. package/dist/embed/host-push-controller.d.ts +67 -0
  70. package/dist/embed/host-surface.d.ts +57 -0
  71. package/dist/embed/presets.d.ts +10 -0
  72. package/dist/embed/theme.d.ts +13 -0
  73. package/dist/embed/voice/agent-spawn.d.ts +38 -0
  74. package/dist/embed/voice/audio-utils.d.ts +6 -0
  75. package/dist/embed/voice/call-active-marker.d.ts +67 -0
  76. package/dist/embed/voice/line-dispatch.d.ts +34 -4
  77. package/dist/embed/voice/line-run-reader.d.ts +29 -1
  78. package/dist/embed/voice/line-slots.d.ts +99 -0
  79. package/dist/embed/voice/reconnect-offer.d.ts +29 -0
  80. package/dist/embed/voice/session-create.d.ts +26 -0
  81. package/dist/embed/voice/voice-http.d.ts +12 -0
  82. package/dist/embed/voice-bus.d.ts +2 -0
  83. package/dist/embed/voice-call-lines.d.ts +241 -14
  84. package/dist/embed/voice-call.d.ts +34 -6
  85. package/dist/i18n/messages/en.d.ts +33 -0
  86. package/dist/i18n/messages/surfaces/header.d.ts +18 -0
  87. package/dist/i18n/messages/surfaces/sessions.d.ts +6 -0
  88. package/dist/i18n/messages/surfaces/stats.d.ts +55 -0
  89. package/dist/i18n/messages/surfaces/stream.d.ts +3 -0
  90. package/dist/stream/belong-chat-transport.d.ts +45 -8
  91. package/dist/stream/belong-data-parts.d.ts +8 -0
  92. package/dist/stream/chat-export-store.d.ts +35 -0
  93. package/dist/stream/route-dispatch.d.ts +17 -0
  94. package/dist/stream/session-stats-csv.d.ts +52 -0
  95. package/dist/stream/stream-state-store.d.ts +36 -6
  96. package/dist/types/public.d.ts +3 -1
  97. package/package.json +1 -1
@@ -1,31 +1,258 @@
1
+ import { WorkPhase } from './voice-narration.ts';
2
+ export declare const MAX_AGENT_LINES = 3;
1
3
  /**
2
- * Agent lines registrythe Operator's switchboard. Line 1 is the
3
- * FOREGROUND chat (existing single-line behavior, unchanged); lines 2+ are
4
- * background sessions dispatched over plain HTTP and monitored by the
5
- * line-run reader. External-store singleton, same idiom as voice-bus.ts.
4
+ * "idle" is the not-busy resting state no work in flight, and nothing
5
+ * completed/failed yet worth reporting (a fresh call, or a line rebound onto
6
+ * a persisted session with no activity this call). "ready" is the DISTINCT
7
+ * terminal state after a run actually finished successfully it carries a
8
+ * result (`lastText`) worth showing, unlike "idle" which never conflates the
9
+ * two anymore (pre-CallScreen-board, both were folded into "ready").
6
10
  */
7
- export declare const MAX_AGENT_LINES = 3;
8
- export type AgentLineStatus = "working" | "ready" | "failed" | "needs_approval";
11
+ export type AgentLineStatus = "idle" | "working" | "ready" | "failed" | "needs_approval";
9
12
  export type AgentLine = {
10
13
  readonly line: number;
14
+ /**
15
+ * Monotonic stamp identifying THIS occupancy of the slot — bumped every time
16
+ * a line entry is CREATED (`openAgentLine`, a line-1 reset, a rehydrate), and
17
+ * carried unchanged through every later write (they all spread `...l`).
18
+ *
19
+ * The line NUMBER is not an identity: `closeAgentLine(2)` frees it and the
20
+ * very next `openAgentLine` hands the same number to a different reservation.
21
+ * Anything holding a line across an await (`spawnAgentLine`'s session mint,
22
+ * line-dispatch's find-or-create) must therefore re-check the epoch, not just
23
+ * that "line 2 exists" — otherwise a spawn whose chip the user closed
24
+ * mid-mint binds its session onto the NEXT spawn's line. Compare via
25
+ * `isLineReservation` below.
26
+ */
27
+ readonly epoch: number;
11
28
  readonly sessionId: string | null;
12
29
  readonly label: string;
13
30
  readonly status: AgentLineStatus;
14
31
  readonly lastText: string;
32
+ /** The line's current run, for `stop_agent` to target — bound by the
33
+ * line-run reader once a background dispatch's POST returns a runId, and
34
+ * cleared back to `null` when that run reaches a terminal state. Line 1
35
+ * (foreground) never gets this written: its runId is resolved at stop-time
36
+ * from the stream-state store instead (the same source the on-screen Stop
37
+ * button reads), so this stays `null` for line 1 always. */
38
+ readonly runId: string | null;
39
+ /** The live "what is it doing right now" label (e.g. "writing code"),
40
+ * written by `setLineStep` as phase notifications arrive while `status`
41
+ * is `"working"`. Cleared back to `null` once the line reaches a terminal
42
+ * status (ready/failed) or starts a fresh dispatch — CallScreen's agent
43
+ * board reads this to show a step under the status dot instead of just a
44
+ * bare "working" chip. */
45
+ readonly currentStepLabel: string | null;
46
+ /** The step's phase classification — what KIND of work the line is doing
47
+ * right now (`classifyToolPhase`), so a working card wears the same phase
48
+ * icon the orb's work badge does (code / files / actions; spinner while
49
+ * unknown). Written and cleared together with `currentStepLabel` by
50
+ * `setLineStep`. */
51
+ readonly currentPhase: WorkPhase | null;
52
+ /** True when this line reached a terminal status (ready/failed) while its
53
+ * session was NOT the one on screen — a finished result the user hasn't
54
+ * looked at yet (product vision: the rail's green "unseen" dot). Written by
55
+ * `deliverLineReply`/`deliverLineFailure` (voice-call.ts) for background
56
+ * lines; line 1's own terminal writes never set it (the foreground chat IS
57
+ * what's on screen, so its own results are seen by definition). Cleared by
58
+ * `markLineSeen` once the user actually views that line's session. */
59
+ readonly unseenResult: boolean;
15
60
  };
16
61
  export declare const peekAgentLines: () => readonly AgentLine[];
17
62
  export declare const subscribeAgentLines: (listener: () => void) => (() => void);
63
+ /** Hard reset: rebuilds every line from its persisted slot, ephemeral fields
64
+ * clean. Used by `initAgentLines()`, a host workspace switch, and the
65
+ * `__forceAgentLines` test/E2E harness —
66
+ * NOT on a call boundary any more (see the module doc's "CALL BOUNDARY"
67
+ * section); a live call uses `resetForCallStart()` below instead. */
18
68
  export declare const resetAgentLines: () => void;
69
+ /**
70
+ * The registry's FIRST read of the durable slots, and the one that binds it to
71
+ * the host's workspace. The dock calls this once on mount — i.e. after
72
+ * `configureWorkspaceScope` / `setWorkspace` have run — so the boot rehydrate
73
+ * uses the workspace-suffixed storage key that every later write also uses
74
+ * (a module-eval read would have used the legacy unsuffixed one).
75
+ *
76
+ * It also subscribes to the workspace-scope store: a host workspace switch
77
+ * hard-resets the registry and re-reads the slots under the NEW key, so the
78
+ * rail can never keep offering the previous workspace's sessions. Idempotent —
79
+ * a second call just re-reads; only one subscription is ever held.
80
+ */
81
+ export declare const initAgentLines: () => void;
82
+ /** Test-only: drop the workspace subscription so each case starts unsubscribed. */
83
+ export declare const __resetAgentLinesInitForTest: () => void;
84
+ /**
85
+ * Call-boundary reset — narrower than `resetAgentLines()`. A call ENDING no
86
+ * longer touches the registry at all (a finished result and its
87
+ * `unseenResult` flag must survive the hang-up). By the time the NEXT call
88
+ * starts, the only genuinely stale ephemera left behind is a line stuck at
89
+ * "working": its reader was torn down mid-flight when the previous call ended
90
+ * (`abortAllLineReaders` in line-dispatch.ts) without the run ever reaching a
91
+ * terminal status. Everything else — bindings, terminal statuses,
92
+ * `unseenResult` — is left exactly as it is. No-op (no emit) when nothing was
93
+ * actually "working".
94
+ */
95
+ export declare const resetForCallStart: () => void;
19
96
  export declare const getLine: (line: number) => AgentLine | undefined;
20
97
  /**
21
- * The "foreground-routed alias": a background line (≥ 2) bound to the SAME
22
- * session line 1 currently shows (the user opened it in the chat via
23
- * `show_agent_line`). New work for that line is routed through the foreground
24
- * pipeline so the visible chat renders the run but the background line's
25
- * strip status must still be kept truthful, and this finds the line to update.
26
- * Returns `undefined` when line 1 is unbound or no background line aliases it.
98
+ * Is the slot `line` STILL held by the reservation stamped `epoch`? The check
99
+ * every holder of a line across an await owes the registry before it adopts a
100
+ * session into that line (see `AgentLine.epoch`). False means the reservation
101
+ * is gone released outright, or already replaced by a different one that
102
+ * happens to wear the same number.
103
+ */
104
+ export declare const isLineReservation: (line: number, epoch: number) => boolean;
105
+ /** The line (other than 1) currently bound to `sessionId`, or `undefined` when
106
+ * no background line holds it — the shared scan behind `isBoundToAnotherLine`
107
+ * (the boolean chat.tsx's aliasing guard needs) and `markLineSeen`'s callers
108
+ * (which need the actual line number to mark seen). */
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;
117
+ /** True when `sessionId` is already the session of some line OTHER than line
118
+ * 1 — chat.tsx's line-1 aliasing guard uses this to skip rebinding line 1
119
+ * onto a background line's session while the user is viewing it via
120
+ * `show_agent_line` (rebinding would overwrite line 1's own identity). */
121
+ export declare const isBoundToAnotherLine: (sessionId: string) => boolean;
122
+ /**
123
+ * The line number the FOREGROUND chat's registry writes belong to. The visible
124
+ * chat is NOT always line 1: the rail's spawn flow and `show_agent_line` both
125
+ * put a BACKGROUND line's session on screen, and work done there must light
126
+ * that line's badge — not line 1's, which would leave the agent the user is
127
+ * actually watching sitting idle. Falls back to line 1 when the on-screen
128
+ * session is line 1's own (or unknown), which is the common case.
129
+ *
130
+ * This SUPERSEDED the old `findAliasedLine()` helper, which served the INVERSE
131
+ * premise: line 1 having ADOPTED a background line's session, so a line-1 write
132
+ * had to be mirrored onto the aliased background line. The aliasing guards
133
+ * (`isBoundToAnotherLine`, in chat.tsx's line-1 bind effect and voice-call.ts's
134
+ * eager foreground mint) now stop line 1 from ever adopting another line's
135
+ * session, so that premise can no longer hold in production — the helper was
136
+ * permanently `undefined`, i.e. dead code that read as live, and was deleted.
137
+ * Every foreground write resolves its ONE target through this function instead.
27
138
  */
28
- export declare const findAliasedLine: () => AgentLine | undefined;
139
+ export declare const foregroundLineNumber: (sessionId: string | null) => number;
29
140
  export declare const openAgentLine: (label: string) => AgentLine | null;
30
- export declare const bindLineSession: (line: number, sessionId: string) => void;
141
+ /**
142
+ * RELEASE a line — the mirror of `persistSlotBinding`'s adoption: clears the
143
+ * in-memory entry AND its durable slot together, so the freed number is
144
+ * immediately re-mintable by `openAgentLine` and does not rehydrate on the next
145
+ * boot. Called when a spawn's session mint fails (otherwise the slot is burned
146
+ * until reload) and when the user deletes a session a line was bound to
147
+ * (otherwise the rail keeps offering a chip that opens a session that is gone).
148
+ *
149
+ * Line 1 is the foreground chat and is never REMOVED — releasing it resets it
150
+ * to the familiar fresh/unbound line 1 instead. No-op on an unknown line.
151
+ */
152
+ export declare const closeAgentLine: (line: number) => void;
153
+ /**
154
+ * TEST/HARNESS-ONLY memory-only bind — the `__` prefix is load-bearing. This
155
+ * writes the in-memory registry WITHOUT the durable slot, which is precisely
156
+ * the divergence `persistSlotBinding` exists to eliminate: a line bound only in
157
+ * memory looks right until the next rehydrate, then silently reverts (or, after
158
+ * a workspace switch, rehydrates onto the OTHER workspace's session). Production
159
+ * adoption has exactly one seam and it is `persistSlotBinding`.
160
+ *
161
+ * It stays exported solely so unit tests, the rail stories, and the
162
+ * `__forceAgentLines` E2E hook can construct a registry state without writing
163
+ * durable slots that would then leak across cases (and, for `__forceAgentLines`,
164
+ * survive an E2E reload as phantom agents). Renamed from the old public
165
+ * `bindLineSession` so no production writer can reach for it by accident.
166
+ */
167
+ export declare const __bindLineSessionForTest: (line: number, sessionId: string) => void;
168
+ /**
169
+ * The ADOPTION seam (the one rule for what "Agent N" means): call this
170
+ * whenever `sessionId` becomes the ACTIVE session for `line` — line 1's
171
+ * foreground bind effect, the eager foreground mint at call start, and a
172
+ * background line's find-or-create dispatch. Updates the in-memory registry
173
+ * and the durable slot together, so a slot's identity never drifts between
174
+ * the two. No-ops on an unchanged binding, so calling this on every render
175
+ * (chat.tsx's bind effect has no dep array) is cheap.
176
+ *
177
+ * The two halves must move TOGETHER — both of these were real divergences:
178
+ *
179
+ * - An UNKNOWN line writes nothing. Every adoption site has an async gap
180
+ * between reserving the line and minting its session (`spawnAgentLine`,
181
+ * line-dispatch's find-or-create), and the line can be released inside that
182
+ * gap — a failed sibling spawn, a deleted session, a workspace switch that
183
+ * re-reads the slots. Writing the slot anyway left a durable binding for a
184
+ * line the registry does not hold, which rehydrates on the next boot as a
185
+ * phantom agent (and, after a workspace switch, one pointing at the OTHER
186
+ * workspace's session).
187
+ * - The `label` is written to memory too, not only to storage. Adopting under
188
+ * a new label with an unchanged `sessionId` used to update the durable slot
189
+ * while the in-memory line kept the old label, so the rail's chip and the
190
+ * label that survives a reload disagreed until the next rehydration.
191
+ */
192
+ export declare const persistSlotBinding: (line: number, sessionId: string, label: string) => void;
193
+ /** `stop_agent`'s target: bound by the line-run reader once a background
194
+ * dispatch's POST returns a runId, and cleared to `null` when that run
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. */
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;
31
222
  export declare const setLineStatus: (line: number, status: AgentLineStatus, lastText?: string) => void;
223
+ /** CallScreen's agent board reads this as the live "what is it doing right
224
+ * now" line under a working line's status dot — written on every phase
225
+ * notification (`notifyLinePhase`) and cleared (`null`) once the line's run
226
+ * reaches a terminal state. `phase` rides along so the working card can wear
227
+ * the matching phase icon (omitted/null = kind unknown → spinner); a `null`
228
+ * label always clears both. No-op on an unknown line or unchanged values
229
+ * (mirrors `setLineStatus`'s tolerance). */
230
+ export declare const setLineStep: (line: number, label: string | null, phase?: WorkPhase | null) => void;
231
+ /** Write a line's `unseenResult` flag directly — `deliverLineReply`/
232
+ * `deliverLineFailure` (voice-call.ts) call this alongside `setLineStatus` to
233
+ * mark a background line's finish/failure unseen when its session isn't the
234
+ * one on screen. No-op on an unknown line or an unchanged value (mirrors
235
+ * `setLineStatus`'s tolerance). Most callers want `markLineSeen` below rather
236
+ * than calling this with `false` directly. */
237
+ export declare const setLineUnseenResult: (line: number, unseenResult: boolean) => void;
238
+ /** The user is now looking at this line's session — clear its unseen-result
239
+ * flag. Called from BelongDock's `onSelectSession` (any surface that opens a
240
+ * session — the sessions list, `show_agent_line`, a notification click) once
241
+ * it resolves which line, if any, owns the opened session. */
242
+ export declare const markLineSeen: (line: number) => void;
243
+ /**
244
+ * The user opened `sessionId` — clear the unseen-result flag on EVERY line
245
+ * bound to it. More than one line can share a session: line 1 aliases whatever
246
+ * the chat is showing, so a background line the user opened is held by both.
247
+ * Marking only the FIRST match (line 1, which sorts first) left the background
248
+ * agent's green dot lit forever with no way to clear it. No-op when no line
249
+ * owns the session.
250
+ */
251
+ export declare const markSessionSeen: (sessionId: string) => void;
252
+ /**
253
+ * The session behind `sessionId` is gone (the user deleted it) — RELEASE every
254
+ * line bound to it, in memory and durably. Without this the registry and its
255
+ * reload-surviving slot keep pointing at a session that no longer exists, so
256
+ * the rail goes on offering a chip that opens nothing.
257
+ */
258
+ export declare const releaseLinesForSession: (sessionId: string) => void;
@@ -1,4 +1,5 @@
1
1
  import { AgentLineStatus } from './voice-call-lines.ts';
2
+ import { WorkPhase } from './voice-narration.ts';
2
3
  export type CallStatus = "idle" | "connecting" | "in_call" | "error";
3
4
  /**
4
5
  * One row of the call's execution timeline (the CallScreen activity card):
@@ -112,6 +113,7 @@ declare let lineDispatcher: ((req: {
112
113
  }) => void) | null;
113
114
  export declare const registerCallLineDispatcher: (dispatcher: NonNullable<typeof lineDispatcher>) => (() => void);
114
115
  export declare const registerCallLineViewSwitcher: (switcher: (sessionId: string) => void) => (() => void);
116
+ export declare const registerCallClearNotifier: (notifier: (sessionId: string) => void) => (() => void);
115
117
  /**
116
118
  * ChatRoute calls this when a tool-approval card appears while a call is
117
119
  * live: the ask lands on the timeline and the voice model asks the user to
@@ -133,7 +135,24 @@ export declare const setCallWorkPhase: (phase: CallState["workPhase"]) => void;
133
135
  * (e.g. ChatRoute hasn't mounted).
134
136
  */
135
137
  export declare const showLineOnScreen: (line: number) => void;
136
- export declare const startCall: () => Promise<void>;
138
+ /**
139
+ * `isReconnect`: set by the dock's boot-time auto-redial (BEL — call survives
140
+ * page reload) when a per-tab {@link readCallActiveMarker} marker says a call
141
+ * was live when the page went away. Everything else about starting the call
142
+ * is identical to a manual dial — a fresh page load already rehydrates every
143
+ * line straight from its persisted slot session at MODULE BOOT (the registry's
144
+ * own initializer, `voice-call-lines.ts`), and `ensureForegroundLineSession`
145
+ * reuses line 1's persisted session pointer (stream-state-store.ts), so no
146
+ * line state is lost either way; `resetForCallStart()` below only clears a
147
+ * line that was genuinely left stuck "working" by an earlier call's teardown.
148
+ * The ONE thing a fresh page load can't recover on its own is the call's
149
+ * spoken timeline (in-memory, wiped by definition) — `resumeDigest`, captured
150
+ * from the marker BEFORE this call's own lifecycle overwrites it, carries that
151
+ * recap into the reconnected realtime session (see `onOpen` below).
152
+ */
153
+ export declare const startCall: (options?: {
154
+ readonly isReconnect?: boolean;
155
+ }) => Promise<void>;
137
156
  export declare const endCall: () => void;
138
157
  export declare const toggleCallMuted: () => void;
139
158
  /** Dismiss a sticky error state (the overlay's ✕). */
@@ -173,10 +192,13 @@ export declare const deliverLineArtifact: (line: number, artifact: {
173
192
  export declare const deliverLineFailure: (line: number, message: string) => void;
174
193
  /** A background line is blocked on a tool approval — steer the user to it. */
175
194
  export declare const notifyLineApprovalNeeded: (line: number, timelineText: string) => void;
176
- /** A background line advanced a phase — land a tagged row + a spoken nudge.
177
- * Guarded like its delivery siblings: a stale phase from an ended call (there
178
- * is no registry write here) must not touch a new call's timeline. */
179
- export declare const notifyLinePhase: (line: number, phaseLabel: string) => void;
195
+ /** A background line advanced a phase — record it as the line's live step
196
+ * (CallScreen's agent board), land a tagged timeline row, and nudge a spoken
197
+ * update. The registry write is unconditional (line-dispatch's own `isStale`
198
+ * guard already keeps a stale-call phase from ever reaching here); the
199
+ * timeline/spoken half stays guarded like its delivery siblings so a phase
200
+ * that DOES arrive with no live call just updates the board silently. */
201
+ export declare const notifyLinePhase: (line: number, phaseLabel: string, phase?: WorkPhase | null) => void;
180
202
  /** True while a call holds the audio path — ChatRoute gates TTS autoplay on it. */
181
203
  export declare const isCallActive: () => boolean;
182
204
  /**
@@ -196,7 +218,7 @@ export declare const __forceCallAudioLevel: (level: number) => void;
196
218
  * CallScreen lines strip in E2E and sandboxed browsers. Resets the registry,
197
219
  * then replays the same store calls a live Operator run makes: `openAgentLine`
198
220
  * to create each background line (sequential, mirroring real dispatch),
199
- * `bindLineSession` + `setLineStatus` to fill it in. Line 1 is the existing
221
+ * `__bindLineSessionForTest` + `setLineStatus` to fill it in. Line 1 is the existing
200
222
  * foreground line and is updated in place rather than opened. Entries are
201
223
  * replayed in ascending `line` order regardless of input order, so lines 2/3
202
224
  * always land on their expected slots.
@@ -206,5 +228,11 @@ export declare const __forceAgentLines: (forced: readonly {
206
228
  label: string;
207
229
  status: AgentLineStatus;
208
230
  sessionId?: string;
231
+ /** Optional live step label (CallScreen's agent board) — mirrors what
232
+ * `notifyLinePhase` writes on a real background dispatch. */
233
+ currentStepLabel?: string;
234
+ /** Optional phase classification for the step — drives the working
235
+ * card's phase icon (omitted = spinner). */
236
+ currentPhase?: WorkPhase;
209
237
  }[]) => void;
210
238
  export {};
@@ -57,6 +57,7 @@ export declare const en: {
57
57
  readonly executingTasks: "Working on it…";
58
58
  readonly workedSteps_one: "Worked · {{count}} step";
59
59
  readonly workedSteps_other: "Worked · {{count}} steps";
60
+ readonly resumingAfterPause: "Taking longer than expected — picking it back up…";
60
61
  readonly open: "Open";
61
62
  readonly reconnectNeeded: "The {{provider}} session needs reconnecting to continue.";
62
63
  readonly reconnect: "Reconnect";
@@ -64,6 +65,22 @@ export declare const en: {
64
65
  readonly reconnected: "Reconnected";
65
66
  readonly retry: "Retry";
66
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
+ };
67
84
  readonly sessions: {
68
85
  readonly chats: "Chats";
69
86
  readonly newChat: "New chat";
@@ -82,6 +99,8 @@ export declare const en: {
82
99
  readonly noSessionsYet: "No sessions yet.";
83
100
  readonly untitledSession: "Untitled session";
84
101
  readonly updated: "updated";
102
+ readonly loadedIntoAgent: "Loaded into Agent {{line}}";
103
+ readonly loadingChat: "Loading chat…";
85
104
  };
86
105
  readonly scheduled: {
87
106
  readonly viewTitle: "Scheduled";
@@ -211,6 +230,12 @@ export declare const en: {
211
230
  readonly hotkeyHint: "Hold {{key}} to talk — chat can stay closed";
212
231
  readonly expand: "Expand";
213
232
  readonly collapse: "Collapse";
233
+ readonly spawnAgent: "New agent";
234
+ readonly closeChat: "Close this chat";
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}}";
214
239
  };
215
240
  readonly files: {
216
241
  readonly refreshFiles: "Refresh files";
@@ -384,6 +409,7 @@ export declare const en: {
384
409
  readonly conversation: {
385
410
  readonly thinking: "Thinking…";
386
411
  readonly followerBanner: "This conversation is open in another tab";
412
+ readonly historyUnavailable: "Couldn't load this conversation — try reopening it.";
387
413
  };
388
414
  readonly compaction: {
389
415
  readonly compacted: "Compacted {{count}} earlier messages into a summary.";
@@ -434,6 +460,7 @@ export declare const en: {
434
460
  readonly endCall: "End call";
435
461
  readonly dismiss: "Dismiss";
436
462
  readonly startCall: "Start voice call";
463
+ readonly reconnectCall: "Reconnect voice call";
437
464
  };
438
465
  readonly callScreen: {
439
466
  readonly title: "Voice call";
@@ -475,6 +502,12 @@ export declare const en: {
475
502
  readonly lineWorking: "working";
476
503
  readonly lineReady: "ready";
477
504
  readonly lineFailed: "failed";
505
+ readonly lineIdle: "idle";
506
+ readonly lineNotStarted: "not started";
507
+ readonly lineNoChat: "no chat yet";
508
+ readonly activity: "Activity";
509
+ readonly showConversationLog: "Show conversation log";
510
+ readonly hideConversationLog: "Hide conversation log";
478
511
  readonly ambientTypingCode: "Typing code…";
479
512
  readonly ambientReviewingDiff: "Reviewing the diff…";
480
513
  readonly ambientRunningChecks: "Running checks…";
@@ -15,6 +15,12 @@ export declare const headerEn: {
15
15
  readonly hotkeyHint: "Hold {{key}} to talk — chat can stay closed";
16
16
  readonly expand: "Expand";
17
17
  readonly collapse: "Collapse";
18
+ readonly spawnAgent: "New agent";
19
+ readonly closeChat: "Close this chat";
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}}";
18
24
  };
19
25
  };
20
26
  export declare const headerEs: {
@@ -33,6 +39,12 @@ export declare const headerEs: {
33
39
  hotkeyHint: string;
34
40
  expand: string;
35
41
  collapse: string;
42
+ spawnAgent: string;
43
+ closeChat: string;
44
+ closeAgent: string;
45
+ exportChat: string;
46
+ exportChatGenerating: string;
47
+ exportChatLast: string;
36
48
  };
37
49
  };
38
50
  export declare const headerPt: {
@@ -51,5 +63,11 @@ export declare const headerPt: {
51
63
  hotkeyHint: string;
52
64
  expand: string;
53
65
  collapse: string;
66
+ spawnAgent: string;
67
+ closeChat: string;
68
+ closeAgent: string;
69
+ exportChat: string;
70
+ exportChatGenerating: string;
71
+ exportChatLast: string;
54
72
  };
55
73
  };
@@ -18,6 +18,8 @@ export declare const sessionsEn: {
18
18
  readonly noSessionsYet: "No sessions yet.";
19
19
  readonly untitledSession: "Untitled session";
20
20
  readonly updated: "updated";
21
+ readonly loadedIntoAgent: "Loaded into Agent {{line}}";
22
+ readonly loadingChat: "Loading chat…";
21
23
  };
22
24
  };
23
25
  export declare const sessionsEs: {
@@ -39,6 +41,8 @@ export declare const sessionsEs: {
39
41
  noSessionsYet: string;
40
42
  untitledSession: string;
41
43
  updated: string;
44
+ loadedIntoAgent: string;
45
+ loadingChat: string;
42
46
  };
43
47
  };
44
48
  export declare const sessionsPt: {
@@ -60,5 +64,7 @@ export declare const sessionsPt: {
60
64
  noSessionsYet: string;
61
65
  untitledSession: string;
62
66
  updated: string;
67
+ loadedIntoAgent: string;
68
+ loadingChat: string;
63
69
  };
64
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
+ };
@@ -57,6 +57,7 @@ export declare const streamEn: {
57
57
  readonly executingTasks: "Working on it…";
58
58
  readonly workedSteps_one: "Worked · {{count}} step";
59
59
  readonly workedSteps_other: "Worked · {{count}} steps";
60
+ readonly resumingAfterPause: "Taking longer than expected — picking it back up…";
60
61
  readonly open: "Open";
61
62
  readonly reconnectNeeded: "The {{provider}} session needs reconnecting to continue.";
62
63
  readonly reconnect: "Reconnect";
@@ -116,6 +117,7 @@ export declare const streamEs: {
116
117
  executingTasks: string;
117
118
  workedSteps_one: string;
118
119
  workedSteps_other: string;
120
+ resumingAfterPause: string;
119
121
  open: string;
120
122
  reconnectNeeded: string;
121
123
  reconnect: string;
@@ -175,6 +177,7 @@ export declare const streamPt: {
175
177
  executingTasks: string;
176
178
  workedSteps_one: string;
177
179
  workedSteps_other: string;
180
+ resumingAfterPause: string;
178
181
  open: string;
179
182
  reconnectNeeded: string;
180
183
  reconnect: string;