@belonguniverseai/react-sdk 0.6.20 → 0.6.22

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 (177) hide show
  1. package/README.md +69 -0
  2. package/dist/api/client.d.ts +784 -43
  3. package/dist/api/goals.d.ts +179 -0
  4. package/dist/api/issue-reports.d.ts +13 -0
  5. package/dist/api/query-keys.d.ts +18 -0
  6. package/dist/api/questions.d.ts +2 -6
  7. package/dist/api/report-client-error.d.ts +3 -0
  8. package/dist/api/retry-fetch.d.ts +19 -0
  9. package/dist/api/skill-library.d.ts +100 -0
  10. package/dist/api/skills.d.ts +3 -1
  11. package/dist/app/dock-outlet.d.ts +15 -5
  12. package/dist/browser/allowed-ops.d.ts +18 -0
  13. package/dist/browser/host-mcp.d.ts +31 -0
  14. package/dist/component/{abnfDiagram-N423BO3Z-BhpvofGI.js → abnfDiagram-N423BO3Z-D4mVRMw9.js} +4 -4
  15. package/dist/component/{arc-BDj2q5CZ.js → arc-GBp6w3tF.js} +2 -2
  16. package/dist/component/{architectureDiagram-T3A2C74G-CWQqfm2n.js → architectureDiagram-T3A2C74G-Cxm-USYQ.js} +3 -3
  17. package/dist/component/{blockDiagram-VBNYF7ZC-DegT976u.js → blockDiagram-VBNYF7ZC-BAiLpxJf.js} +4 -4
  18. package/dist/component/{c4Diagram-5PPSVZJV-CSnfnID_.js → c4Diagram-5PPSVZJV-Sy6sLJOj.js} +3 -3
  19. package/dist/component/{channel-CUQQeqtV.js → channel-DPbaAkCI.js} +2 -2
  20. package/dist/component/{chunk-2GRJ4B5K-BmCkMXuE.js → chunk-2GRJ4B5K-8r8YJzCc.js} +2 -2
  21. package/dist/component/{chunk-2Q5K7J3B-ACFPsFU_.js → chunk-2Q5K7J3B-RZqny7-R.js} +2 -2
  22. package/dist/component/{chunk-5RXB4S5H-Bu-wqNe4.js → chunk-5RXB4S5H-QFCY9Dtl.js} +5 -5
  23. package/dist/component/{chunk-5VM5RSS4-DDzdObQ5.js → chunk-5VM5RSS4-BG8q5ODa.js} +2 -2
  24. package/dist/component/{chunk-6Q2QTUOP-35aGDtbe.js → chunk-6Q2QTUOP-D6ec2nI7.js} +2 -2
  25. package/dist/component/{chunk-GF5L2VYU-CBooNwOJ.js → chunk-GF5L2VYU-D7yROYf0.js} +6 -6
  26. package/dist/component/{chunk-JWPE2WC7-CZN_bZMl.js → chunk-JWPE2WC7-CmGlHqne.js} +2 -2
  27. package/dist/component/{chunk-KBJHAD2P-Cj08hUgE.js → chunk-KBJHAD2P-W03s7swc.js} +2 -2
  28. package/dist/component/{chunk-RYQCIY6F-CC4FyEwj.js → chunk-RYQCIY6F-D0oyMUJ7.js} +2 -2
  29. package/dist/component/{chunk-XXDRQBXY-CJW3AYPF.js → chunk-XXDRQBXY-D4s0eyp4.js} +2 -2
  30. package/dist/component/{classDiagram-JCYQIIEL-LpH5TtI1.js → classDiagram-JCYQIIEL-DwNAC2XG.js} +3 -3
  31. package/dist/component/{classDiagram-v2-OCEON4UE-LpH5TtI1.js → classDiagram-v2-OCEON4UE-DwNAC2XG.js} +3 -3
  32. package/dist/component/{cose-bilkent-JH36ORCC-h8wo2OH9.js → cose-bilkent-JH36ORCC-DhGvXDdi.js} +2 -2
  33. package/dist/component/{cynefinDiagram-MW4NZA55-DuieCsNY.js → cynefinDiagram-MW4NZA55-BCUeX7pB.js} +3 -3
  34. package/dist/component/{dagre-VZM6K2ZE-DqMvwkom.js → dagre-VZM6K2ZE-DWofHoga.js} +3 -3
  35. package/dist/component/{diagram-7IWD3JNH-BThr9-R3.js → diagram-7IWD3JNH-DjCFF_Dr.js} +4 -4
  36. package/dist/component/{diagram-B4RE2ZJO-rjoRYPDB.js → diagram-B4RE2ZJO-CSovrpFW.js} +3 -3
  37. package/dist/component/{diagram-LBJQPF4R-C41ccwxG.js → diagram-LBJQPF4R-Cgpae-sR.js} +3 -3
  38. package/dist/component/{diagram-Q27KOJAE-DPN9msRq.js → diagram-Q27KOJAE-DikMPfLU.js} +4 -4
  39. package/dist/component/{diagram-UB23O5K3-DSjf5_Nk.js → diagram-UB23O5K3-sQU6rZbO.js} +3 -3
  40. package/dist/component/{ebnfDiagram-BXEA7PRR-vPL9oktk.js → ebnfDiagram-BXEA7PRR-B9t8-G8R.js} +4 -4
  41. package/dist/component/{erDiagram-JOGREHBK-Kc3mZe4M.js → erDiagram-JOGREHBK-DKg1HhSl.js} +5 -5
  42. package/dist/component/{flowDiagram-UKHOOZJN-2aUAXRZU.js → flowDiagram-UKHOOZJN-BO8jpT1D.js} +7 -7
  43. package/dist/component/{ganttDiagram-PKOTCBZU-DMZtqJSP.js → ganttDiagram-PKOTCBZU-BPXYyB9Q.js} +3 -3
  44. package/dist/component/{gitGraphDiagram-DS77QQ5N-E77l0Z1u.js → gitGraphDiagram-DS77QQ5N-BjVLFBUS.js} +4 -4
  45. package/dist/component/{highlighted-body-OFNGDK62-C1DkgW7U.js → highlighted-body-OFNGDK62-BKot66c3.js} +2 -2
  46. package/dist/component/{index-Dips44uG.js → index-i49DPVb4.js} +960 -464
  47. package/dist/component/index.js +2 -2
  48. package/dist/component/{infoDiagram-6WML65LV-CpvnNYd0.js → infoDiagram-6WML65LV-BkAC5Bwv.js} +2 -2
  49. package/dist/component/{ishikawaDiagram-WSZJBQD7-B1q_lFLX.js → ishikawaDiagram-WSZJBQD7-oplkIs_t.js} +2 -2
  50. package/dist/component/{journeyDiagram-NVQOT4AX-6uEmqBOC.js → journeyDiagram-NVQOT4AX-CuliMCSv.js} +5 -5
  51. package/dist/component/{kanban-definition-27J2QSJJ-C2QioWX9.js → kanban-definition-27J2QSJJ-DdzOdEiL.js} +3 -3
  52. package/dist/component/{linear-BT5VqKju.js → linear-zZDwdGmK.js} +2 -2
  53. package/dist/component/{mermaid-GHXKKRXX-C8vyJd7j.js → mermaid-GHXKKRXX-aX5umm-y.js} +49795 -42603
  54. package/dist/component/{mindmap-definition-FAOFIHXS-D9m5nI-X.js → mindmap-definition-FAOFIHXS-DD2HF9oE.js} +4 -4
  55. package/dist/component/{pegDiagram-VL7TDLO6-C6Voiy3J.js → pegDiagram-VL7TDLO6-DyiDl9bF.js} +4 -4
  56. package/dist/component/{pieDiagram-7S7Q4E2Y-sqStHf6X.js → pieDiagram-7S7Q4E2Y-DflxKS_B.js} +4 -4
  57. package/dist/component/{quadrantDiagram-CIZ2JOQS-J4smKtsQ.js → quadrantDiagram-CIZ2JOQS-nwwayVOP.js} +3 -3
  58. package/dist/component/{railroadDiagram-AXF67PYL-DWSgdnlw.js → railroadDiagram-AXF67PYL-BTtD2eN9.js} +4 -4
  59. package/dist/component/{requirementDiagram-LRYGKXZP-CD2psvke.js → requirementDiagram-LRYGKXZP-B37q1LKL.js} +4 -4
  60. package/dist/component/{sankeyDiagram-W5VNT64P-BTctWXxs.js → sankeyDiagram-W5VNT64P-zY0W9eje.js} +2 -2
  61. package/dist/component/{sequenceDiagram-SI44F4Z6-BSr4jTRw.js → sequenceDiagram-SI44F4Z6-CmQiqB8F.js} +4 -4
  62. package/dist/component/{sizeCapture-X5ZJPWSS-DDKZl6MR.js → sizeCapture-X5ZJPWSS-dF3FvIT8.js} +2 -2
  63. package/dist/component/snapdom-DkzCA8S0.js +7061 -0
  64. package/dist/component/{stateDiagram-OKZ733FA-DpICd9vK.js → stateDiagram-OKZ733FA-CX61F3L0.js} +3 -3
  65. package/dist/component/{stateDiagram-v2-UEYNNEHI-CDWkukZc.js → stateDiagram-v2-UEYNNEHI-DnFZhhu3.js} +3 -3
  66. package/dist/component/{swimlanes-SLNWSIFB-C2qUEfbN.js → swimlanes-SLNWSIFB-CX9XGBvw.js} +4 -4
  67. package/dist/component/{swimlanesDiagram-ULZ7WXOC-BATYiMa7.js → swimlanesDiagram-ULZ7WXOC-Bqkgx7qk.js} +3 -3
  68. package/dist/component/{timeline-definition-Z64GVDOM-BANf8HvQ.js → timeline-definition-Z64GVDOM-BUX4OSm1.js} +3 -3
  69. package/dist/component/{vennDiagram-T6HMQDX7-ByIwO7x1.js → vennDiagram-T6HMQDX7-BpVOq4Rh.js} +2 -2
  70. package/dist/component/{wardleyDiagram-T6FBY63Y-5_6KGTWP.js → wardleyDiagram-T6FBY63Y-BUDGa8Mv.js} +3 -3
  71. package/dist/component/{xychartDiagram-ELKLHX3M-KS7oMXi0.js → xychartDiagram-ELKLHX3M-FIA_LnIu.js} +3 -3
  72. package/dist/components/embed/EmbedComposer.d.ts +11 -1
  73. package/dist/components/embed/EmbedHeader.d.ts +7 -1
  74. package/dist/components/embed/EmbedRail.d.ts +18 -2
  75. package/dist/components/embed/GoalActions.d.ts +15 -0
  76. package/dist/components/embed/GoalBadge.d.ts +17 -0
  77. package/dist/components/embed/GoalClearDialog.d.ts +6 -0
  78. package/dist/components/embed/GoalClearedLine.d.ts +3 -0
  79. package/dist/components/embed/GoalCompletionCard.d.ts +12 -0
  80. package/dist/components/embed/GoalComposeSheet.d.ts +19 -0
  81. package/dist/components/embed/GoalProposalCard.d.ts +29 -0
  82. package/dist/components/embed/GoalRailView.d.ts +15 -0
  83. package/dist/components/embed/GoalRefusalCard.d.ts +22 -0
  84. package/dist/components/embed/GoalSetCard.d.ts +5 -0
  85. package/dist/components/embed/GoalSnoozeMenu.d.ts +14 -0
  86. package/dist/components/embed/GoalStatusRow.d.ts +6 -0
  87. package/dist/components/embed/GoalTimeline.d.ts +6 -0
  88. package/dist/components/embed/MobileNavBar.d.ts +5 -1
  89. package/dist/components/embed/QuestionCard.d.ts +12 -1
  90. package/dist/components/embed/ScheduleNotices.d.ts +23 -0
  91. package/dist/components/embed/SentAsGoalTag.d.ts +1 -0
  92. package/dist/components/embed/SubagentsPaneBody.d.ts +3 -0
  93. package/dist/components/embed/rail-flags.d.ts +13 -0
  94. package/dist/components/feedback/IssueReportController.d.ts +1 -0
  95. package/dist/components/feedback/IssueReportDialog.d.ts +6 -0
  96. package/dist/components/skills/ConfirmDeleteSkillDialog.d.ts +9 -0
  97. package/dist/components/skills/SkillLibraryToolSync.d.ts +4 -0
  98. package/dist/components/skills/SkillsListSurface.d.ts +26 -0
  99. package/dist/components/skills/UploadSkillDialog.d.ts +32 -0
  100. package/dist/components/skills/skill-archive-file.d.ts +15 -0
  101. package/dist/components/ui/badge.d.ts +1 -1
  102. package/dist/embed/client-error-log.d.ts +72 -0
  103. package/dist/embed/copy.d.ts +1 -0
  104. package/dist/embed/dev-mode.d.ts +5 -7
  105. package/dist/embed/dock-open-request.d.ts +32 -0
  106. package/dist/embed/dock-state.d.ts +1 -1
  107. package/dist/embed/goal-actions-model.d.ts +9 -0
  108. package/dist/embed/goal-cap-notice.d.ts +36 -0
  109. package/dist/embed/goal-deep-link.d.ts +24 -0
  110. package/dist/embed/goal-edit-command.d.ts +25 -0
  111. package/dist/embed/goal-journal.d.ts +53 -0
  112. package/dist/embed/goal-live-status.d.ts +2 -0
  113. package/dist/embed/goal-plain-units.d.ts +35 -0
  114. package/dist/embed/goal-progress.d.ts +15 -0
  115. package/dist/embed/goal-proposal-dismissal.d.ts +11 -0
  116. package/dist/embed/goal-resume-time.d.ts +22 -0
  117. package/dist/embed/goal-row-model.d.ts +27 -0
  118. package/dist/embed/goal-runway.d.ts +5 -0
  119. package/dist/embed/goal-schedule-handoff.d.ts +12 -0
  120. package/dist/embed/goal-status-label.d.ts +3 -0
  121. package/dist/embed/goal-time-usage.d.ts +19 -0
  122. package/dist/embed/issue-report-bus.d.ts +14 -0
  123. package/dist/embed/issue-report-open.d.ts +8 -0
  124. package/dist/embed/issue-report.d.ts +41 -0
  125. package/dist/embed/locale.d.ts +1 -1
  126. package/dist/embed/screen-capture.d.ts +74 -0
  127. package/dist/embed/slash-commands.d.ts +24 -0
  128. package/dist/embed/task-schedule-command.d.ts +7 -0
  129. package/dist/embed/voice/line-run-reader.d.ts +8 -0
  130. package/dist/embed/voice-call.d.ts +4 -0
  131. package/dist/i18n/messages/en.d.ts +385 -13
  132. package/dist/i18n/messages/it.d.ts +3 -0
  133. package/dist/i18n/messages/surfaces/aiElements.d.ts +52 -0
  134. package/dist/i18n/messages/surfaces/app.d.ts +18 -0
  135. package/dist/i18n/messages/surfaces/connectors.d.ts +235 -0
  136. package/dist/i18n/messages/surfaces/embedMisc.d.ts +45 -0
  137. package/dist/i18n/messages/surfaces/feedback.d.ts +93 -0
  138. package/dist/i18n/messages/surfaces/files.d.ts +37 -0
  139. package/dist/i18n/messages/surfaces/header.d.ts +44 -0
  140. package/dist/i18n/messages/surfaces/login.d.ts +8 -0
  141. package/dist/i18n/messages/surfaces/plan.d.ts +17 -0
  142. package/dist/i18n/messages/surfaces/prompts.d.ts +43 -0
  143. package/dist/i18n/messages/surfaces/scheduled.d.ts +108 -0
  144. package/dist/i18n/messages/surfaces/sessions.d.ts +23 -0
  145. package/dist/i18n/messages/surfaces/skills.d.ts +216 -0
  146. package/dist/i18n/messages/surfaces/stats.d.ts +18 -0
  147. package/dist/i18n/messages/surfaces/stream.d.ts +290 -27
  148. package/dist/i18n/messages/surfaces/usage.d.ts +26 -0
  149. package/dist/i18n/messages/surfaces/workspace.d.ts +30 -0
  150. package/dist/public-api.d.ts +1 -1
  151. package/dist/routes/chat/part-renderer-extra-props.d.ts +43 -0
  152. package/dist/routes/chat/use-goal-receipt.d.ts +37 -0
  153. package/dist/routes/chat/use-host-draft-request.d.ts +2 -0
  154. package/dist/routes/chat/use-session-goal.d.ts +226 -0
  155. package/dist/routes/chat.d.ts +10 -1
  156. package/dist/routes/goal.d.ts +1 -0
  157. package/dist/routes/skills.d.ts +2 -0
  158. package/dist/stream/activity-items.d.ts +25 -0
  159. package/dist/stream/ai-sdk-part-renderers.d.ts +70 -25
  160. package/dist/stream/belong-chat-transport.d.ts +147 -2
  161. package/dist/stream/belong-data-parts.d.ts +55 -7
  162. package/dist/stream/goal-store.d.ts +43 -0
  163. package/dist/stream/message-continuation.d.ts +29 -0
  164. package/dist/stream/message-metadata.d.ts +1 -0
  165. package/dist/stream/message-parts.d.ts +42 -0
  166. package/dist/stream/run-line-progress.d.ts +1 -0
  167. package/dist/stream/select-goal-set-part-id.d.ts +2 -0
  168. package/dist/stream/select-latest-goal.d.ts +13 -0
  169. package/dist/stream/subagent-controls-store.d.ts +20 -0
  170. package/dist/stream/subagent-lanes-model.d.ts +175 -0
  171. package/dist/stream/subagent-lanes.d.ts +89 -0
  172. package/dist/stream/use-publish-subagent-controls.d.ts +11 -0
  173. package/dist/stream/workspace-focus-store.d.ts +7 -1
  174. package/dist/test/render.d.ts +18 -1
  175. package/dist/test/subagent-fixtures.d.ts +24 -0
  176. package/dist/types/public.d.ts +55 -2
  177. package/package.json +1 -1
@@ -0,0 +1,226 @@
1
+ import { UseChatHelpers } from '@ai-sdk/react';
2
+ import { fetchSessionGoal, GoalView } from '../../api/goals.ts';
3
+ import { GoalRefusal } from '../../embed/goal-cap-notice.ts';
4
+ import { ChatMode } from '../../embed/chat-mode.ts';
5
+ import { GoalRunwayPreset } from '../../embed/goal-runway.ts';
6
+ import { BuiltinCommand } from '../../embed/slash-commands.ts';
7
+ import { GoalComposeValue } from '../../components/embed/GoalComposeSheet.tsx';
8
+ import { BelongUIMessage, GoalProposalData } from '../../stream/belong-data-parts.ts';
9
+ /**
10
+ * The card a waiting goal is waiting ON, named by the row action that offers
11
+ * it. Client-only (appendix A §4): the wait ends when the user acts on the
12
+ * CARD, never when a button on the row is pressed, so this scrolls and
13
+ * focuses and does nothing else.
14
+ */
15
+ export type PendingCardKind = "answer" | "review" | "show_me";
16
+ /**
17
+ * `startGoal`'s input (Task 16) — the ONE creation path's full shape, shared
18
+ * by every door: the compose sheet's submit, `/goal <objective>` (via the
19
+ * sheet), the proposal card's future Confirm, and the row's `new_goal`
20
+ * hand-off (Task 8, which only ever fills in `objective`). `criteria` and
21
+ * `runway` ride straight onto the message body (Task 15's `goal: { objective,
22
+ * criteria?, runway? }`); `mode`, when given, is the door's OWN resolved
23
+ * choice and is sent as-is — see the fallback below for the one caller that
24
+ * still doesn't resolve it itself.
25
+ */
26
+ export type StartGoalInput = {
27
+ readonly objective: string;
28
+ readonly criteria?: readonly string[];
29
+ readonly runway?: GoalRunwayPreset;
30
+ readonly mode?: ChatMode;
31
+ };
32
+ /**
33
+ * Fix wave (Task 8 review, finding 1): the KIND decides the selector — a goal
34
+ * waiting for an approval must not land on a question card just because a
35
+ * question card appears first in the transcript. And within one kind, the card
36
+ * the goal is waiting on is the NEWEST: a transcript keeps every card the
37
+ * conversation ever showed, so `querySelector`'s first match is the OLDEST,
38
+ * which is normally one the user already settled. Prefer an explicitly pending
39
+ * card; otherwise take the last.
40
+ */
41
+ export declare const scrollAndFocusPendingCard: (kind: PendingCardKind) => void;
42
+ /** Every prop `<GoalComposeSheet>` takes — named once so `composeSheet` and
43
+ * `goalDoor.composeSheet` below don't have to repeat the shape. */
44
+ type GoalComposeSheetProps = {
45
+ readonly open: boolean;
46
+ readonly initial: GoalComposeValue;
47
+ readonly planModeResolved: boolean;
48
+ readonly onCancel: () => void;
49
+ readonly onSubmit: (value: GoalComposeValue) => void;
50
+ };
51
+ /** `openGoalComposeSheet`'s optional prefill — every field optional so a
52
+ * bare `/goal` (no prefill at all) and "Edit first" (all three) share one
53
+ * door. */
54
+ export type GoalComposeSheetPrefill = {
55
+ readonly objective?: string;
56
+ readonly criteria?: readonly string[];
57
+ readonly runway?: GoalRunwayPreset;
58
+ };
59
+ export type SessionGoalApi = {
60
+ /** The ON-SCREEN session's goal, or null. */
61
+ readonly goal: GoalView | null;
62
+ readonly hasLiveGoal: boolean;
63
+ readonly startGoal: (input: StartGoalInput) => Promise<void>;
64
+ /** The proposal card's Confirm (`ai-sdk-part-renderers.tsx`'s `onConfirmGoal`)
65
+ * hands over the WHOLE offer — this adapts it onto `startGoal` so `chat.tsx`
66
+ * doesn't need its own wrapper (the line-count ratchet). Fix round 1
67
+ * (Medium 1) — widened from a bare objective so Start actually creates
68
+ * what the card promised (criteria + runway included). */
69
+ readonly confirmGoal: (proposal: GoalProposalData) => Promise<void>;
70
+ readonly runGoalCommand: (command: Extract<BuiltinCommand, {
71
+ type: "goal";
72
+ }>) => Promise<void>;
73
+ /** Opens the compose sheet — `chat.tsx`'s mode-menu "Set a goal…" entry —
74
+ * or `undefined` once a `goals_disabled` 503 has been seen this mount (the
75
+ * initial fetch, or a refused creation): a deployment without goals never
76
+ * shows a door the backend will only refuse. */
77
+ readonly onSetGoal: (() => void) | undefined;
78
+ /** The compose sheet's open/closed state and what it starts from — the ONE
79
+ * door onto `startGoal`, reached from the mode menu, a bare `/goal` (or
80
+ * `/goal <objective>`, prefilled), and — Task 17 — the proposal card's
81
+ * "Edit first". Flat fields for tests that drive one at a time; `composeSheet`
82
+ * below bundles them exactly as `<GoalComposeSheet>` takes them, so
83
+ * `chat.tsx` can spread the whole thing in one line. */
84
+ readonly sheetOpen: boolean;
85
+ readonly sheetInitial: GoalComposeValue;
86
+ /** True when the composer was in plan mode at the moment this sheet
87
+ * opened — the sheet says so and resolves the send to Auto itself. */
88
+ readonly sheetPlanModeResolved: boolean;
89
+ /** Task 17 widens this from a bare objective to the sheet's whole prefill
90
+ * — "Edit first" needs criteria and a runway too, not just the text. */
91
+ readonly openGoalComposeSheet: (prefill?: GoalComposeSheetPrefill) => void;
92
+ readonly closeGoalComposeSheet: () => void;
93
+ readonly submitGoalComposeSheet: (value: GoalComposeValue) => void;
94
+ /** `<GoalComposeSheet {...composeSheet} />` — every prop that component
95
+ * takes, bundled once so the ratchet on `chat.tsx` (CLAUDE.md) never has
96
+ * to grow for this door. */
97
+ readonly composeSheet: GoalComposeSheetProps;
98
+ /**
99
+ * Task 17 — the proposal card's "Started" state (spec §7), given the
100
+ * offer's own objective text: derived from `GoalView` + the loaded
101
+ * message list (never local state — §12/§41), true only when the
102
+ * session's goal origin message is BOTH a goal-origin message (Task 9's
103
+ * `isGoalOriginMessage`) AND carries this exact objective — so a goal
104
+ * started via `/goal` or the compose sheet with different words leaves an
105
+ * unanswered proposal card as-is (fix round 1, Low 4). Takes the
106
+ * objective rather than being a bare boolean because only the dispatch
107
+ * site (`ai-sdk-part-renderers.tsx`) knows which offer's card is asking.
108
+ */
109
+ readonly isGoalProposalStarted: (objective: string) => boolean;
110
+ /** Opens the compose sheet prefilled from a proposal's own fields — the
111
+ * proposal card's "Edit first" (Task 17). */
112
+ readonly onEditGoalProposal: (proposal: GoalProposalData) => void;
113
+ /**
114
+ * The ON-SCREEN session id, for the proposal card's per-device dismissal
115
+ * key (ruling 5) — `null` for the rare frame before any session is known.
116
+ * Fix round 1 (Low 5) — was `?? ""`, which would have made every such
117
+ * render share ONE dismissal key (`belong:goal-proposal-dismissed:`);
118
+ * `null` instead tells the card to render without "Not now" until a real
119
+ * session id exists, per `GoalProposalCard`'s own `sessionId` prop.
120
+ */
121
+ readonly goalProposalSessionId: string | null;
122
+ /** `onSetGoal`, `confirmGoal` and `composeSheet` again, bundled into ONE
123
+ * destructured field so `chat.tsx` (CLAUDE.md's line-count ratchet) needs
124
+ * exactly one line to receive the whole door. */
125
+ readonly goalDoor: {
126
+ readonly onSetGoal: (() => void) | undefined;
127
+ readonly confirmGoal: (proposal: GoalProposalData) => Promise<void>;
128
+ readonly composeSheet: GoalComposeSheetProps;
129
+ readonly isGoalProposalStarted: (objective: string) => boolean;
130
+ readonly onEditGoalProposal: (proposal: GoalProposalData) => void;
131
+ readonly goalProposalSessionId: string | null;
132
+ };
133
+ /** Hand the mount `GET /goal` its answer. Publishes the view AND the settled
134
+ * signal, so both halves of "what does this session's goal look like" are
135
+ * decided in one place. */
136
+ readonly seedGoalFromServer: (sessionId: string, outcome: Awaited<ReturnType<typeof fetchSessionGoal>>) => void;
137
+ /** The next user message resumes the goal (the row's `Tell it what to try`). */
138
+ readonly armResumeOnNextSend: () => void;
139
+ /** The client message ids `startGoal` has sent with a `goal` body, this
140
+ * mount. Task 9's `SentAsGoalTag` reconciliation: the optimistic source of
141
+ * truth for the render frame(s) before `GoalView.originatingClientMessageId`
142
+ * exists (§41 — a reload takes over from there). See `isGoalOriginMessage`. */
143
+ readonly goalOriginIds: ReadonlySet<string>;
144
+ /** Fix round 1 (Task 9 review, finding 2) — `handleCreateSendError` calls
145
+ * this once it has confirmed the failed send WAS a goal-creation send. A
146
+ * refused creation must not leave its message id tagged forever: this
147
+ * drops it from `goalOriginIds` if it was already captured, and disarms
148
+ * the one-shot arm if the message never arrived (e.g. the transport
149
+ * rejected before `messages` ever grew). Exposed mainly for the test
150
+ * suite, which drives it directly to simulate that call. */
151
+ readonly dropGoalOriginOnRefusal: () => void;
152
+ /** Task 14 — the refused `/goal`'s ANSWER, a card under the user's own
153
+ * bubble instead of a chat notice telling them to type another command.
154
+ * `null` when there is nothing to answer. Client-only state (never
155
+ * reconciled from the server), so it never survives a reload. */
156
+ readonly refusal: GoalRefusal | null;
157
+ /** The id of the user message this refusal is answering, so `chat.tsx` can
158
+ * render the card under that exact bubble. `null` for a refusal that
159
+ * never got as far as sending anything (the client's own "you already
160
+ * have one" pre-check) — `chat.tsx` renders the card in the transcript
161
+ * flow instead, where the old notice used to sit. */
162
+ readonly refusalMessageId: string | null;
163
+ /** Fix round 1 — Replace/Retry's async chain is in flight; the card
164
+ * disables its buttons on this so a fast double click can't fire two. */
165
+ readonly refusalBusy: boolean;
166
+ /** Answers the card's dismiss — clears the refusal and nothing else. */
167
+ readonly dismissRefusal: () => void;
168
+ /** `useChat`'s `onError` (final review, finding 1) — the send-error path
169
+ * for a goal-creation send. `wasGoalCreateSend` is read internally
170
+ * (`isGoalCreateSendPending`'s old job): every OTHER failure of the chat
171
+ * is left entirely to its own error surface. A refusal `goalRefusalFromError`
172
+ * recognises is HELD as `refusal` (never a `notice(...)` string) and the
173
+ * chat's own error state is cleared so the generic bubble never doubles
174
+ * up on the same refusal. */
175
+ readonly handleCreateSendError: (error: unknown, clearChatError: () => void) => void;
176
+ /** "Clear it and set this one" — clears the existing goal, then starts this
177
+ * one with the objective the refused send carried. */
178
+ readonly onRefusalReplace: () => void;
179
+ /** "Keep the text" — puts the refused objective back in the composer. */
180
+ readonly onRefusalKeepText: () => void;
181
+ /** `not_sent` → "Try again"; `plan_mode` → "Run on Auto". Both just
182
+ * re-send the same objective (`startGoal` resolves plan mode itself). */
183
+ readonly onRefusalRetry: () => void;
184
+ };
185
+ /**
186
+ * True when THIS message is the one that started the goal. Reconciled from
187
+ * `GoalView.originatingClientMessageId` (Task 6) so the tag survives a
188
+ * reload; the optimistic local flag only covers the first frame — matching on
189
+ * the client message id (never the objective text) is what makes the two
190
+ * agree without ever tagging the wrong bubble when the user sends the same
191
+ * sentence twice.
192
+ *
193
+ * Fix round 1 (Task 9 review, finding 2) — once the SERVER has answered
194
+ * (`goal.originatingClientMessageId` is set), that answer is authoritative
195
+ * and wins outright (§12: check the fact directly, don't lean on a flag that
196
+ * might be stale). Before this, a stale id still sitting in `optimisticIds`
197
+ * (one the refusal cleanup below didn't reach, or a future multi-attempt
198
+ * race) could keep tagging a bubble the server never named as the origin.
199
+ * The optimistic set is consulted ONLY for the frame(s) before the server has
200
+ * said anything about this session's goal.
201
+ */
202
+ export declare const isGoalOriginMessage: (input: {
203
+ readonly goal: Pick<GoalView, "originatingClientMessageId"> | null;
204
+ readonly clientMessageId: string | null | undefined;
205
+ readonly optimisticIds: ReadonlySet<string>;
206
+ }) => boolean;
207
+ export type SessionGoalInput = {
208
+ readonly apiBaseUrl: string;
209
+ readonly sessionId: string | null;
210
+ readonly transportSessionId: string | null;
211
+ readonly messages: readonly BelongUIMessage[];
212
+ readonly mode: ChatMode;
213
+ readonly sendMessage: UseChatHelpers<BelongUIMessage>["sendMessage"];
214
+ readonly onModeChange: (mode: ChatMode) => void;
215
+ readonly notice: (text: string) => void;
216
+ /** Runs inside the click gesture, immediately before a creation send —
217
+ * ChatRoute's TTS unlock + voice-turn reset, which stay its business. */
218
+ readonly beforeSend: () => void;
219
+ readonly devOverrides: Readonly<Record<string, unknown>>;
220
+ /** Task 14 — "Keep the text" (a refused goal's cap card) hands the refused
221
+ * objective back to the composer through the SAME door
222
+ * `useGoalReceipt`'s follow-ups already use. */
223
+ readonly setDraft: (value: string) => void;
224
+ };
225
+ export declare const useSessionGoal: (input: SessionGoalInput) => SessionGoalApi;
226
+ export {};
@@ -25,7 +25,16 @@ export type QueuedMessage = {
25
25
  readonly submittedAt: number;
26
26
  readonly state: "queued" | "failed";
27
27
  };
28
- export declare const ChatRoute: ({ sessionId, reconcileBackgroundRun, }?: {
28
+ export declare const ChatRoute: ({ sessionId, reconcileBackgroundRun, onOpenGoalView, onOpenFilesView, }?: {
29
29
  readonly sessionId?: string;
30
30
  readonly reconcileBackgroundRun?: boolean;
31
+ /** Put the Goal view on screen (the dock owns navigation — same path the
32
+ * header pill takes). Omitted in tests and stories, where the row's
33
+ * Details simply does nothing. */
34
+ readonly onOpenGoalView?: (() => void) | undefined;
35
+ /** Put the Files view on screen — same navigation door as the rail's Files
36
+ * item (Task 13's completion card "Get the files"). Omitted in tests and
37
+ * stories, where the button simply doesn't render (`GoalCompletionCard`
38
+ * hides it on `undefined`). */
39
+ readonly onOpenFilesView?: (() => void) | undefined;
31
40
  }) => import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare const GoalRoute: () => import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ /** /skills — the user's skill library (rail tab). */
2
+ export declare const SkillsRoute: () => import("react").JSX.Element;
@@ -0,0 +1,25 @@
1
+ import { SandboxCommandData, SubagentData, ToolCallData } from './belong-data-parts.ts';
2
+ /** One tool call in an activity run, paired (for shell) with its same-id output. */
3
+ export type ToolActivityItem = {
4
+ readonly tool: ToolCallData;
5
+ readonly output: SandboxCommandData | null;
6
+ };
7
+ /**
8
+ * BEL-199 — a delegated subagent in an activity run. It sits INSIDE the one
9
+ * collapsed line beside the tool items, never beside the group.
10
+ */
11
+ export type SubagentActivityItem = {
12
+ readonly kind: "subagent";
13
+ readonly subagentId: string;
14
+ readonly data: SubagentData;
15
+ };
16
+ /**
17
+ * Deliberate shape note: the TOOL variant carries no `kind` discriminant. It is
18
+ * the shape every existing fixture and story already builds, and a subagent item
19
+ * is distinguishable without one (`"kind" in item`) — so this stays a sound
20
+ * union while a required discriminant would have churned ~25 unrelated call
21
+ * sites across four story files for no safety the guard below doesn't give.
22
+ */
23
+ export type ActivityItem = ToolActivityItem | SubagentActivityItem;
24
+ export declare const isSubagentItem: (item: ActivityItem) => item is SubagentActivityItem;
25
+ export declare const isToolItem: (item: ActivityItem) => item is ToolActivityItem;
@@ -1,29 +1,19 @@
1
- import { BelongDataParts, BelongUIMessage, SandboxCommandData, SubagentData, ToolCallData } from './belong-data-parts.ts';
2
- /** One tool call in an activity run, paired (for shell) with its same-id output. */
3
- export type ToolActivityItem = {
4
- readonly tool: ToolCallData;
5
- readonly output: SandboxCommandData | null;
6
- };
7
- /**
8
- * BEL-199 — a delegated subagent in an activity run. It sits INSIDE the one
9
- * collapsed line beside the tool items, never beside the group.
10
- */
11
- export type SubagentActivityItem = {
12
- readonly kind: "subagent";
13
- readonly subagentId: string;
14
- readonly data: SubagentData;
15
- };
16
- /**
17
- * Deliberate shape note: the TOOL variant carries no `kind` discriminant. It is
18
- * the shape every existing fixture and story already builds, and a subagent item
19
- * is distinguishable without one (`"kind" in item`) — so this stays a sound
20
- * union while a required discriminant would have churned ~25 unrelated call
21
- * sites across four story files for no safety the guard below doesn't give.
22
- */
23
- export type ActivityItem = ToolActivityItem | SubagentActivityItem;
24
- export declare const ActivityGroup: ({ items, live, }: {
1
+ import { MessageContinuation } from './message-continuation.ts';
2
+ import { BelongDataParts, BelongUIMessage, GoalProposalData } from './belong-data-parts.ts';
3
+ import { ActivityItem } from './activity-items.ts';
4
+ import { SubagentLanesContext, SubagentMessageIndex } from './subagent-lanes-model.ts';
5
+ export declare const ActivityGroup: ({ items, live, subagents, }: {
25
6
  readonly items: readonly ActivityItem[];
7
+ /** The collapsed line's shimmer: true only for the LAST group of the streaming message. */
26
8
  readonly live?: boolean | undefined;
9
+ /**
10
+ * Spec 2026-09-16 §4a — the message this group belongs to. The lanes nest
11
+ * their calls (and a wave its lanes) from every group of it, and tick and
12
+ * offer Stop while IT streams: an approval or question card after them makes
13
+ * this group non-last while the subagents still run. Absent (a story, a unit
14
+ * test), the group is its own message and the lanes follow `live`.
15
+ */
16
+ readonly subagents?: SubagentLanesContext | undefined;
27
17
  }) => import("react").JSX.Element;
28
18
  /** A segment of a message's text: prose to render as markdown, or a `@`-mention. */
29
19
  type TextSegment = {
@@ -50,7 +40,31 @@ export type PartRendererProps = {
50
40
  * omits it while a run streams so the CTA can't double-submit).
51
41
  */
52
42
  readonly onExecutePlan?: (() => void) | undefined;
43
+ /**
44
+ * Renders the goal-proposal card's Confirm when provided (chat.tsx omits
45
+ * it while a run streams, so the CTA can't double-submit — same rule as
46
+ * `onExecutePlan`).
47
+ */
48
+ readonly onConfirmGoal?: ((proposal: GoalProposalData) => Promise<void>) | undefined;
49
+ /** Task 17 — the proposal card's "Edit first", gated the same as
50
+ * `onConfirmGoal` (streaming, or already resolved). */
51
+ readonly onEditGoalProposal?: ((proposal: GoalProposalData) => void) | undefined;
52
+ /** Task 17 — the proposal card's collapsed "Started" line's "Open it". */
53
+ readonly onOpenGoalProposal?: (() => void) | undefined;
54
+ /** Task 17 — derived from `GoalView`, never local state (§12/§41). Fix
55
+ * round 1 (Low 4) — a function of the SPECIFIC offer's objective, called
56
+ * at the `data-goal-proposal` dispatch arm below where that text is
57
+ * known, so an unrelated goal elsewhere in the transcript can't flip
58
+ * this offer's card to "Started". */
59
+ readonly isGoalProposalStarted?: ((objective: string) => boolean) | undefined;
60
+ /** Task 17 — ruling 5's per-device dismissal key is per session. */
61
+ readonly goalProposalSessionId?: string | null | undefined;
53
62
  readonly onContinueConnector?: ((connectorId: string, name: string) => Promise<void>) | undefined;
63
+ /**
64
+ * Follows the turn an approval card's decision started (an agent-raised plan
65
+ * card's 200 names it). Absent = the card resolves and follows nothing.
66
+ */
67
+ readonly onFollowContinuation?: ((continuation: MessageContinuation) => void) | undefined;
54
68
  /**
55
69
  * The part belongs to a restored-history message (`metadata.fromHistory`,
56
70
  * stamped by `loadSessionHistory`). The dispatch renderers (navigation,
@@ -58,6 +72,36 @@ export type PartRendererProps = {
58
72
  * side effects. Absent/false = live part, dispatch as usual.
59
73
  */
60
74
  readonly historical?: boolean | undefined;
75
+ /**
76
+ * Task 12 — true when THIS `data-goal` part is the ONE part designated,
77
+ * FOR ITS GOAL, to render the "Goal set" receipt (fix round 1: one per
78
+ * `goalId`, not one globally). `chat.tsx` computes the designated ids once
79
+ * per render (`useGoalReceipt` / `selectGoalSetPartIds`,
80
+ * `routes/chat/use-goal-receipt.ts`) and gates this prop per-part via
81
+ * `isGoalSetPart`, the same way it gates `onExecutePlan`/`onConfirmGoal` on
82
+ * `isStreaming`/`hasLiveGoal`. Every other `data-goal` part — including
83
+ * every earlier/later status update of the SAME goal, and every part of a
84
+ * DIFFERENT goal that already claimed its own receipt — renders nothing
85
+ * (see the dispatch below).
86
+ */
87
+ readonly renderGoalSetCard?: boolean | undefined;
88
+ /**
89
+ * Task 13 — the ending's inputs (spec §5). `goalFileCount` is the whole
90
+ * session's `file`/`data-artifact` part count (`countSessionFiles`),
91
+ * threaded through unconditionally — unlike the CTAs above, the completion
92
+ * card is not a mid-run double-submit risk, so it needs no `isStreaming`
93
+ * gate. `onGoalGetFiles` stays optional at THIS layer too: undefined hides
94
+ * the button exactly as `GoalCompletionCard` documents.
95
+ */
96
+ readonly goalFileCount?: number | undefined;
97
+ readonly onGoalSchedule?: ((command: string) => void) | undefined;
98
+ readonly onGoalGetFiles?: (() => void) | undefined;
99
+ readonly onGoalStartAnother?: (() => void) | undefined;
100
+ /**
101
+ * Spec 2026-09-16 §4a — the subagents of this part's message, so an approval
102
+ * card a subagent raised can name it. Absent = no attribution.
103
+ */
104
+ readonly subagents?: SubagentMessageIndex | undefined;
61
105
  };
62
106
  /**
63
107
  * The AI SDK's `UIMessagePart` union is open at the patch-version
@@ -66,7 +110,7 @@ export type PartRendererProps = {
66
110
  * `BelongDataParts` (above) plus the SDK's built-in `text` and
67
111
  * `reasoning` parts.
68
112
  */
69
- export declare const PartRenderer: ({ part, onExecutePlan, historical, onContinueConnector, }: PartRendererProps) => import("react").JSX.Element | null;
113
+ export declare const PartRenderer: ({ part, onExecutePlan, onConfirmGoal, onEditGoalProposal, onOpenGoalProposal, isGoalProposalStarted, goalProposalSessionId, historical, onContinueConnector, renderGoalSetCard, goalFileCount, onGoalSchedule, onGoalGetFiles, onGoalStartAnother, onFollowContinuation, subagents, }: PartRendererProps) => import("react").JSX.Element | null;
70
114
  export type RenderGroup = {
71
115
  readonly kind: "part";
72
116
  readonly part: BelongMessagePart;
@@ -78,3 +122,4 @@ export type RenderGroup = {
78
122
  };
79
123
  export declare const groupMessageParts: (parts: readonly BelongMessagePart[]) => readonly RenderGroup[];
80
124
  export type { BelongDataParts };
125
+ export type { ActivityItem, ToolActivityItem } from './activity-items.ts';
@@ -22,9 +22,9 @@ export declare const choiceAnswerSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
22
22
  export declare const choiceStateSchema: z.ZodEnum<{
23
23
  detached: "detached";
24
24
  pending: "pending";
25
+ cancelled: "cancelled";
25
26
  dismissed: "dismissed";
26
27
  answered: "answered";
27
- cancelled: "cancelled";
28
28
  }>;
29
29
  /**
30
30
  * The wire/stored part union. Exported so the history loader (chat.tsx) can
@@ -129,6 +129,22 @@ export declare const wireStreamPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
129
129
  stepsUsed: z.ZodOptional<z.ZodNumber>;
130
130
  summary: z.ZodOptional<z.ZodString>;
131
131
  timedOut: z.ZodOptional<z.ZodBoolean>;
132
+ outcome: z.ZodCatch<z.ZodOptional<z.ZodEnum<{
133
+ error: "error";
134
+ ok: "ok";
135
+ timeout: "timeout";
136
+ stopped: "stopped";
137
+ stalled: "stalled";
138
+ interrupted: "interrupted";
139
+ }>>>;
140
+ queued: z.ZodOptional<z.ZodBoolean>;
141
+ startedAt: z.ZodOptional<z.ZodString>;
142
+ durationMs: z.ZodOptional<z.ZodNumber>;
143
+ tokensCount: z.ZodOptional<z.ZodNumber>;
144
+ waveId: z.ZodOptional<z.ZodString>;
145
+ groupLabel: z.ZodOptional<z.ZodString>;
146
+ planStepId: z.ZodOptional<z.ZodString>;
147
+ stoppable: z.ZodOptional<z.ZodBoolean>;
132
148
  }, z.core.$strip>;
133
149
  }, z.core.$strip>, z.ZodObject<{
134
150
  type: z.ZodLiteral<"data-sandbox-command">;
@@ -195,6 +211,8 @@ export declare const wireStreamPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
195
211
  throttled: "throttled";
196
212
  }>;
197
213
  message: z.ZodOptional<z.ZodString>;
214
+ outcome: z.ZodOptional<z.ZodString>;
215
+ terminationReason: z.ZodOptional<z.ZodString>;
198
216
  retryable: z.ZodOptional<z.ZodBoolean>;
199
217
  }, z.core.$strip>;
200
218
  }, z.core.$strip>, z.ZodObject<{
@@ -226,9 +244,9 @@ export declare const wireStreamPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
226
244
  state: z.ZodEnum<{
227
245
  detached: "detached";
228
246
  pending: "pending";
247
+ cancelled: "cancelled";
229
248
  dismissed: "dismissed";
230
249
  answered: "answered";
231
- cancelled: "cancelled";
232
250
  }>;
233
251
  questions: z.ZodArray<z.ZodObject<{
234
252
  id: z.ZodString;
@@ -253,6 +271,92 @@ export declare const wireStreamPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
253
271
  }, z.core.$strip>], "kind">>>;
254
272
  reply: z.ZodOptional<z.ZodString>;
255
273
  }, z.core.$strip>;
274
+ }, z.core.$strip>, z.ZodObject<{
275
+ type: z.ZodLiteral<"data-goal">;
276
+ id: z.ZodString;
277
+ data: z.ZodObject<{
278
+ goalId: z.ZodString;
279
+ status: z.ZodEnum<{
280
+ active: "active";
281
+ paused: "paused";
282
+ clarifying: "clarifying";
283
+ completion_claimed: "completion_claimed";
284
+ deferred: "deferred";
285
+ waiting_for_user: "waiting_for_user";
286
+ waiting_for_approval: "waiting_for_approval";
287
+ waiting_for_ui_action: "waiting_for_ui_action";
288
+ blocked: "blocked";
289
+ budget_limited: "budget_limited";
290
+ complete: "complete";
291
+ cleared: "cleared";
292
+ }>;
293
+ statusReason: z.ZodNullable<z.ZodString>;
294
+ objective: z.ZodString;
295
+ successCriteria: z.ZodArray<z.ZodObject<{
296
+ id: z.ZodString;
297
+ text: z.ZodString;
298
+ status: z.ZodEnum<{
299
+ open: "open";
300
+ met: "met";
301
+ }>;
302
+ evidence: z.ZodOptional<z.ZodNullable<z.ZodString>>;
303
+ }, z.core.$strip>>;
304
+ constraints: z.ZodArray<z.ZodString>;
305
+ tokensUsed: z.ZodNumber;
306
+ tokenBudget: z.ZodNumber;
307
+ turnsUsed: z.ZodNumber;
308
+ maxTurns: z.ZodNumber;
309
+ activeSeconds: z.ZodNumber;
310
+ maxActiveSeconds: z.ZodNumber;
311
+ lastProgressNote: z.ZodNullable<z.ZodString>;
312
+ updatedAt: z.ZodString;
313
+ startedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
314
+ originatingClientMessageId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
315
+ clarifyMaxQuestions: z.ZodOptional<z.ZodNumber>;
316
+ judgeFeedback: z.ZodOptional<z.ZodNullable<z.ZodString>>;
317
+ judgeRejections: z.ZodOptional<z.ZodNumber>;
318
+ clarifyingTurns: z.ZodOptional<z.ZodNumber>;
319
+ resumeAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
320
+ journal: z.ZodOptional<z.ZodArray<z.ZodObject<{
321
+ seq: z.ZodNumber;
322
+ kind: z.ZodString;
323
+ actor: z.ZodString;
324
+ toStatus: z.ZodNullable<z.ZodEnum<{
325
+ active: "active";
326
+ paused: "paused";
327
+ clarifying: "clarifying";
328
+ completion_claimed: "completion_claimed";
329
+ deferred: "deferred";
330
+ waiting_for_user: "waiting_for_user";
331
+ waiting_for_approval: "waiting_for_approval";
332
+ waiting_for_ui_action: "waiting_for_ui_action";
333
+ blocked: "blocked";
334
+ budget_limited: "budget_limited";
335
+ complete: "complete";
336
+ cleared: "cleared";
337
+ }>>;
338
+ note: z.ZodNullable<z.ZodString>;
339
+ at: z.ZodString;
340
+ }, z.core.$strip>>>;
341
+ runway: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
342
+ quick: "quick";
343
+ normal: "normal";
344
+ long: "long";
345
+ }>>>;
346
+ }, z.core.$strip>;
347
+ }, z.core.$strip>, z.ZodObject<{
348
+ type: z.ZodLiteral<"data-goal-proposal">;
349
+ id: z.ZodString;
350
+ data: z.ZodObject<{
351
+ objective: z.ZodString;
352
+ why: z.ZodString;
353
+ criteria: z.ZodOptional<z.ZodArray<z.ZodString>>;
354
+ runway: z.ZodOptional<z.ZodEnum<{
355
+ quick: "quick";
356
+ normal: "normal";
357
+ long: "long";
358
+ }>>;
359
+ }, z.core.$strip>;
256
360
  }, z.core.$strip>], "type">;
257
361
  /** A request was 401'd twice (once with a freshly re-read token): the host
258
362
  * session is expired — the dock must surface re-auth, not retry forever. */
@@ -260,6 +364,22 @@ export declare const AUTH_EXPIRED_ERROR_PREFIX = "auth_expired:";
260
364
  /** The SSE reconnect loop exhausted its attempt budget without the backend
261
365
  * delivering a single event — the service is unreachable. */
262
366
  export declare const BACKEND_UNAVAILABLE_ERROR_PREFIX = "backend_unavailable:";
367
+ /**
368
+ * `POST /v1/sessions/:id/messages` refused the send. Carries the raw status
369
+ * + body — the same shape as `AttachmentUploadError`'s precedent
370
+ * (`chat-upload.ts`) — so a caller can recognize a SPECIFIC refusal (e.g. the
371
+ * goal-cap 429s, `goal_cap_user` / `goal_cap_tenant`) instead of pattern-
372
+ * matching the thrown `Error`'s message string. Deviation 11: this is the
373
+ * minimum honest channel — the send path had no error surface at all before
374
+ * this, so `goal_exists` and the new caps were previously invisible in the
375
+ * dock. The message text is unchanged from the plain `Error` this replaces,
376
+ * so every existing `.rejects.toThrow(...)` assertion still passes.
377
+ */
378
+ export declare class PostMessageError extends Error {
379
+ readonly status: number;
380
+ readonly body: string;
381
+ constructor(status: number, body: string);
382
+ }
263
383
  /** First reconnect delay — identical to the historic fixed delay, so the
264
384
  * BEL-48 mid-run clean-EOF reconnect regains the stream just as fast. */
265
385
  export declare const RECONNECT_BASE_DELAY_MS = 1000;
@@ -372,6 +492,9 @@ export declare class BelongChatTransport implements ChatTransport<BelongUIMessag
372
492
  get sessionId(): string | null;
373
493
  /** The construction-captured workspace (see #workspaceExternalId). */
374
494
  get workspaceExternalId(): string | null;
495
+ /** Includes an outstanding SSE handshake and the transport's retry loop,
496
+ * which can own the Session before useChat reports `streaming`. */
497
+ get hasLiveStream(): boolean;
375
498
  /** Drop the cached session so the next `sendMessages` creates a new one. */
376
499
  reset(): void;
377
500
  /**
@@ -386,6 +509,28 @@ export declare class BelongChatTransport implements ChatTransport<BelongUIMessag
386
509
  * best-effort.
387
510
  */
388
511
  cancelRun: (runId: string) => Promise<readonly RecalledQueuedMessage[]>;
512
+ /**
513
+ * Spec 2026-09-16 §1.4/§3.5 — ask belong-cloud to stop ONE subagent of a
514
+ * live run (`POST /v1/runs/:runId/subagents/:subagentId/stop`, 202
515
+ * `{ status: "stop_requested" }`). Modelled on `cancelRun`: same auth
516
+ * headers, same transient retries (the route is idempotent, §18). It changes
517
+ * nothing locally — the lane flips only when the `subagent_finished` part
518
+ * arrives — and the stop is best-effort BY DESIGN (spec §5: the backend
519
+ * swallows delivery failures too), so the dock promises nothing here.
520
+ *
521
+ * The two failure families are deliberately NOT collapsed into one. A 404
522
+ * (`subagent_not_found`, or an API that has not deployed the route yet) and a
523
+ * 409 (`subagent_not_running` — it finished while the user was clicking) are
524
+ * ordinary things that happen to a working product: the lane simply never
525
+ * flips and nothing is said. A 401 is something else entirely — the host
526
+ * session going stale mid-click — so it takes the same §C3 treatment every
527
+ * other authed call in this transport gets: one FORCED token rotation and one
528
+ * retry, which makes a merely stale token still stop the subagent. Only a
529
+ * SECOND 401 is a genuinely expired session, and that is reported as
530
+ * `auth_expired` (the evidence behind the dock's re-auth surface), never as an
531
+ * unaccepted stop.
532
+ */
533
+ stopSubagent: (runId: string, subagentId: string) => Promise<void>;
389
534
  sendMessages: ChatTransport<BelongUIMessage>["sendMessages"];
390
535
  reconnectToStream: ChatTransport<BelongUIMessage>["reconnectToStream"];
391
536
  }