@devaccel-labs/app-comments-toolbar 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +148 -30
  2. package/dist/react.js +417 -64
  3. package/dist/server.js +342 -14
  4. package/dist/types/capture/api.d.ts +30 -0
  5. package/dist/types/capture/editor.d.ts +10 -0
  6. package/dist/types/capture/ignore.d.ts +19 -0
  7. package/dist/types/capture/index.d.ts +1 -0
  8. package/dist/types/capture/picker.d.ts +9 -0
  9. package/dist/types/capture/picture.d.ts +29 -0
  10. package/dist/types/capture/surface.d.ts +39 -0
  11. package/dist/types/core/index.d.ts +2 -2
  12. package/dist/types/core/resolve.d.ts +2 -1
  13. package/dist/types/core/types.d.ts +11 -0
  14. package/dist/types/debug-context.d.ts +7 -0
  15. package/dist/types/dictation.d.ts +9 -0
  16. package/dist/types/embed/controller.d.ts +61 -0
  17. package/dist/types/embed/index.d.ts +1 -0
  18. package/dist/types/embed/options.d.ts +35 -0
  19. package/dist/types/help/index.d.ts +1 -0
  20. package/dist/types/help/panel-index.d.ts +1 -0
  21. package/dist/types/help/panel-styles.d.ts +1 -0
  22. package/dist/types/help/panel.d.ts +4 -0
  23. package/dist/types/help/pill-styles.d.ts +11 -0
  24. package/dist/types/help/pill.d.ts +44 -0
  25. package/dist/types/help/react.d.ts +12 -0
  26. package/dist/types/help/requests.d.ts +2 -0
  27. package/dist/types/help/types.d.ts +119 -0
  28. package/dist/types/help/wire.d.ts +61 -0
  29. package/dist/types/native-wire.d.ts +63 -0
  30. package/dist/types/native.d.ts +43 -0
  31. package/dist/types/react.d.ts +7 -0
  32. package/dist/types/replay.d.ts +6 -0
  33. package/dist/types/runtime/api.d.ts +250 -0
  34. package/dist/types/runtime/attachment-model.d.ts +16 -0
  35. package/dist/types/runtime/attachments.d.ts +43 -7
  36. package/dist/types/runtime/boot.d.ts +39 -0
  37. package/dist/types/runtime/browser-label.d.ts +5 -0
  38. package/dist/types/runtime/build-id.d.ts +1 -0
  39. package/dist/types/runtime/capture-ui.d.ts +45 -21
  40. package/dist/types/runtime/clarity-model.d.ts +260 -0
  41. package/dist/types/runtime/clarity-ui.d.ts +62 -0
  42. package/dist/types/runtime/client.d.ts +6 -197
  43. package/dist/types/runtime/composer-size.d.ts +30 -0
  44. package/dist/types/runtime/dashboard.d.ts +17 -2
  45. package/dist/types/runtime/debug-context-core.d.ts +88 -0
  46. package/dist/types/runtime/debug-context-host.d.ts +39 -0
  47. package/dist/types/runtime/debug-context-model.d.ts +352 -0
  48. package/dist/types/runtime/debug-context-redact.d.ts +48 -0
  49. package/dist/types/runtime/debug-context.d.ts +36 -0
  50. package/dist/types/runtime/details-model.d.ts +7 -0
  51. package/dist/types/runtime/details.d.ts +7 -5
  52. package/dist/types/runtime/dictation-engine.d.ts +98 -0
  53. package/dist/types/runtime/dictation-model.d.ts +28 -0
  54. package/dist/types/runtime/dictation-ui.d.ts +56 -0
  55. package/dist/types/runtime/dictation.d.ts +66 -0
  56. package/dist/types/runtime/draft-dock.d.ts +32 -0
  57. package/dist/types/runtime/draft-model.d.ts +104 -0
  58. package/dist/types/runtime/draft-store.d.ts +15 -0
  59. package/dist/types/runtime/edits.d.ts +1 -1
  60. package/dist/types/runtime/font.d.ts +16 -0
  61. package/dist/types/runtime/format.d.ts +30 -1
  62. package/dist/types/runtime/host-watch.d.ts +20 -0
  63. package/dist/types/runtime/icons.d.ts +16 -2
  64. package/dist/types/runtime/index.d.ts +2 -0
  65. package/dist/types/runtime/ink.d.ts +8 -0
  66. package/dist/types/runtime/kind-model.d.ts +14 -0
  67. package/dist/types/runtime/live-model.d.ts +25 -0
  68. package/dist/types/runtime/loader.d.ts +5 -3
  69. package/dist/types/runtime/markup-editor.d.ts +54 -0
  70. package/dist/types/runtime/markup-model.d.ts +126 -0
  71. package/dist/types/runtime/markup.d.ts +69 -0
  72. package/dist/types/runtime/mention-parse.d.ts +18 -0
  73. package/dist/types/runtime/mentions.d.ts +4 -4
  74. package/dist/types/runtime/page-background.d.ts +9 -0
  75. package/dist/types/runtime/page-image.d.ts +64 -11
  76. package/dist/types/runtime/placement.d.ts +6 -3
  77. package/dist/types/runtime/record.d.ts +18 -2
  78. package/dist/types/runtime/related.d.ts +1 -1
  79. package/dist/types/runtime/replay-model.d.ts +80 -0
  80. package/dist/types/runtime/replay.d.ts +5 -38
  81. package/dist/types/runtime/screen.d.ts +47 -0
  82. package/dist/types/runtime/screenshot.d.ts +60 -8
  83. package/dist/types/runtime/session-source.d.ts +45 -0
  84. package/dist/types/runtime/session.d.ts +20 -18
  85. package/dist/types/runtime/shield.d.ts +9 -0
  86. package/dist/types/runtime/shot.d.ts +45 -0
  87. package/dist/types/runtime/sketch.d.ts +26 -0
  88. package/dist/types/runtime/styles.d.ts +1 -1
  89. package/dist/types/runtime/sync.d.ts +1 -0
  90. package/dist/types/runtime/thread-model.d.ts +18 -0
  91. package/dist/types/runtime/ticket-form-model.d.ts +57 -0
  92. package/dist/types/runtime/ticket-form.d.ts +9 -0
  93. package/dist/types/runtime/toolbar.d.ts +37 -1
  94. package/dist/types/runtime/ui-scale.d.ts +17 -0
  95. package/dist/types/runtime/update.d.ts +32 -8
  96. package/dist/types/runtime/use-debug-context.d.ts +27 -0
  97. package/dist/types/server/index.d.ts +22 -0
  98. package/dist/types/server/support.d.ts +20 -0
  99. package/dist/types/server.d.ts +2 -0
  100. package/dist/types/vite/plugin.d.ts +15 -0
  101. package/dist/vite.js +121 -41
  102. package/package.json +24 -11
  103. package/src/capture/api.ts +128 -0
  104. package/src/capture/editor.tsx +178 -0
  105. package/src/capture/ignore.ts +38 -0
  106. package/src/capture/index.ts +27 -0
  107. package/src/capture/picker.tsx +171 -0
  108. package/src/capture/picture.ts +90 -0
  109. package/src/capture/surface.tsx +185 -0
  110. package/src/compiler/annotate.ts +202 -0
  111. package/src/compiler/babel.d.ts +11 -0
  112. package/src/compiler/enabled.ts +55 -0
  113. package/src/compiler/index.ts +2 -0
  114. package/src/core/index.ts +8 -0
  115. package/src/core/resolve.ts +307 -0
  116. package/src/core/types.ts +58 -0
  117. package/src/debug-context.ts +47 -0
  118. package/src/dictation.ts +17 -0
  119. package/src/embed/controller.ts +215 -0
  120. package/src/embed/index.ts +68 -0
  121. package/src/embed/options.ts +100 -0
  122. package/src/help/index.ts +38 -0
  123. package/src/help/panel-index.ts +17 -0
  124. package/src/help/panel-styles.ts +123 -0
  125. package/src/help/panel.ts +840 -0
  126. package/src/help/pill-styles.ts +75 -0
  127. package/src/help/pill.ts +338 -0
  128. package/src/help/react.tsx +143 -0
  129. package/src/help/requests.ts +111 -0
  130. package/src/help/types.ts +124 -0
  131. package/src/help/wire.ts +55 -0
  132. package/src/native-wire.ts +124 -0
  133. package/src/native.ts +282 -0
  134. package/src/react.ts +27 -0
  135. package/src/replay.ts +13 -0
  136. package/src/runtime/api.ts +531 -0
  137. package/src/runtime/attachment-model.ts +42 -0
  138. package/src/runtime/attachments.tsx +1260 -0
  139. package/src/runtime/boot.ts +95 -0
  140. package/src/runtime/browser-label.ts +31 -0
  141. package/src/runtime/build-id.ts +10 -0
  142. package/src/runtime/capture-ui.tsx +306 -0
  143. package/src/runtime/capture.ts +508 -0
  144. package/src/runtime/clarity-model.ts +634 -0
  145. package/src/runtime/clarity-ui.tsx +454 -0
  146. package/src/runtime/client.ts +151 -0
  147. package/src/runtime/composer-size.tsx +146 -0
  148. package/src/runtime/dashboard.tsx +1130 -0
  149. package/src/runtime/debug-context-core.ts +681 -0
  150. package/src/runtime/debug-context-host.ts +56 -0
  151. package/src/runtime/debug-context-model.ts +1319 -0
  152. package/src/runtime/debug-context-redact.ts +259 -0
  153. package/src/runtime/debug-context.ts +613 -0
  154. package/src/runtime/details-model.ts +30 -0
  155. package/src/runtime/details.tsx +395 -0
  156. package/src/runtime/dictation-engine.ts +616 -0
  157. package/src/runtime/dictation-model.ts +79 -0
  158. package/src/runtime/dictation-ui.tsx +363 -0
  159. package/src/runtime/dictation.ts +271 -0
  160. package/src/runtime/dock.ts +108 -0
  161. package/src/runtime/draft-dock.tsx +124 -0
  162. package/src/runtime/draft-model.ts +251 -0
  163. package/src/runtime/draft-store.ts +149 -0
  164. package/src/runtime/edits.tsx +165 -0
  165. package/src/runtime/font.ts +42 -0
  166. package/src/runtime/format.ts +129 -0
  167. package/src/runtime/freshness.ts +23 -0
  168. package/src/runtime/handoff.ts +76 -0
  169. package/src/runtime/host-watch.ts +64 -0
  170. package/src/runtime/icons.tsx +295 -0
  171. package/src/runtime/idle.ts +20 -0
  172. package/src/runtime/index.ts +11 -0
  173. package/src/runtime/ink.ts +6 -0
  174. package/src/runtime/kind-model.ts +20 -0
  175. package/src/runtime/live-model.ts +32 -0
  176. package/src/runtime/loader.tsx +87 -0
  177. package/src/runtime/markup-editor.tsx +1333 -0
  178. package/src/runtime/markup-model.ts +485 -0
  179. package/src/runtime/markup.ts +382 -0
  180. package/src/runtime/members.ts +58 -0
  181. package/src/runtime/mention-parse.ts +56 -0
  182. package/src/runtime/mentions.tsx +205 -0
  183. package/src/runtime/page-background.ts +51 -0
  184. package/src/runtime/page-image.ts +1592 -0
  185. package/src/runtime/placement.ts +336 -0
  186. package/src/runtime/record.ts +402 -0
  187. package/src/runtime/redact.ts +30 -0
  188. package/src/runtime/related.ts +34 -0
  189. package/src/runtime/render-page.ts +2 -0
  190. package/src/runtime/replay-model.ts +232 -0
  191. package/src/runtime/replay.ts +173 -0
  192. package/src/runtime/runtime-version.ts +7 -0
  193. package/src/runtime/runtime.tsx +51 -0
  194. package/src/runtime/screen.ts +182 -0
  195. package/src/runtime/screenshot.ts +260 -0
  196. package/src/runtime/session-source.ts +112 -0
  197. package/src/runtime/session.ts +108 -0
  198. package/src/runtime/shield.ts +34 -0
  199. package/src/runtime/shot.tsx +422 -0
  200. package/src/runtime/sketch.ts +139 -0
  201. package/src/runtime/styles.ts +1541 -0
  202. package/src/runtime/sync.ts +300 -0
  203. package/src/runtime/thread-model.ts +71 -0
  204. package/src/runtime/ticket-form-model.ts +128 -0
  205. package/src/runtime/ticket-form.tsx +342 -0
  206. package/src/runtime/toolbar.tsx +4427 -0
  207. package/src/runtime/ui-scale.ts +75 -0
  208. package/src/runtime/update.ts +98 -0
  209. package/src/runtime/use-debug-context.ts +81 -0
  210. package/src/server/index.ts +133 -0
  211. package/src/server/support.ts +499 -0
  212. package/src/server.ts +4 -0
  213. package/src/vite/plugin.ts +102 -0
  214. package/src/vite.ts +1 -0
@@ -0,0 +1,250 @@
1
+ /**
2
+ * The comment service's HTTP API: wire types and request functions. DOM-free, so native clients
3
+ * (`@devaccel-labs/app-comments-native`) share it; `./client.ts` re-exports it with the browser-only sign-in
4
+ * relay and storage helpers.
5
+ */
6
+ import type { Anchor } from "../core/index.js";
7
+ import type { ClarityDraft, ClarityMode } from "./clarity-model.js";
8
+ import type { ReportKind } from "./kind-model.js";
9
+ import { type Session } from "./session-source.js";
10
+ import type { TicketDraft, TicketForm } from "./ticket-form-model.js";
11
+ export type Mentioned = {
12
+ id: string;
13
+ name: string;
14
+ };
15
+ /** Where a page screenshot was taken. */
16
+ export type Capture = {
17
+ url: string;
18
+ viewport?: {
19
+ width: number;
20
+ height: number;
21
+ };
22
+ browser?: string;
23
+ };
24
+ export type Attachment = {
25
+ id: string;
26
+ name: string;
27
+ contentType: string;
28
+ size: number;
29
+ url: string;
30
+ capture?: Capture;
31
+ };
32
+ /** An earlier version of a message. `createdAt` is when that version was written. */
33
+ export type Revision = {
34
+ body: string;
35
+ mentions?: Mentioned[];
36
+ createdAt: string;
37
+ };
38
+ export type CommentMessage = {
39
+ id: string;
40
+ body: string;
41
+ author: string;
42
+ /** Missing on messages written before author ids were stored. */
43
+ authorId?: string | null;
44
+ createdAt: string;
45
+ editedAt?: string | null;
46
+ mentions?: Mentioned[];
47
+ attachments?: Attachment[];
48
+ /** Earlier versions, oldest first. The current body is the version after the last one. */
49
+ revisions?: Revision[];
50
+ };
51
+ export type Member = {
52
+ id: string;
53
+ name: string;
54
+ email: string;
55
+ };
56
+ export type Delivery = {
57
+ emailed: Mentioned[];
58
+ skipped: Array<Mentioned & {
59
+ reason: "rate_limited" | "muted" | "disabled" | string;
60
+ }>;
61
+ };
62
+ export type Profile = {
63
+ name: string;
64
+ email: string | null;
65
+ mentionEmails: boolean;
66
+ };
67
+ export type PostExtras = {
68
+ mentions?: string[];
69
+ screenshot?: string | null;
70
+ attachments?: string[];
71
+ };
72
+ export type FieldDef = {
73
+ id: string;
74
+ label: string;
75
+ };
76
+ export type FieldValue = FieldDef & {
77
+ value: string;
78
+ };
79
+ export type Settings = {
80
+ roles: {
81
+ enabled: boolean;
82
+ options: string[];
83
+ };
84
+ fields: {
85
+ enabled: boolean;
86
+ items: FieldDef[];
87
+ };
88
+ };
89
+ /** Role and custom field values for a new or edited comment, keyed by field id. */
90
+ export type Details = {
91
+ role: string | null;
92
+ fields: Record<string, string>;
93
+ };
94
+ export type Thread = {
95
+ id: string;
96
+ /** The environment the comment was left in. Differs from the session's for comments from a linked environment. */
97
+ environment?: string;
98
+ route: string;
99
+ /** The page the comment was left on, including query and hash. */
100
+ url: string;
101
+ role: string | null;
102
+ fields: FieldValue[];
103
+ anchor: Anchor;
104
+ status: "open" | "resolved";
105
+ createdBy: string;
106
+ createdAt: string;
107
+ updatedAt: string;
108
+ messages: CommentMessage[];
109
+ /** Set when the team turned this comment into a ticket in their tracker. */
110
+ ticket?: TicketBadge;
111
+ };
112
+ /** A comment's support ticket, as the commenter sees it: number and status only. */
113
+ export type TicketBadge = {
114
+ number: string;
115
+ status: string;
116
+ label: string;
117
+ };
118
+ export declare class ApiError extends Error {
119
+ readonly status: number;
120
+ readonly code: string;
121
+ constructor(status: number, code: string, message: string);
122
+ }
123
+ export declare function storageKey(session: Pick<Session, "apiUrl" | "project" | "environment">): string;
124
+ /**
125
+ * Where a client keeps its member token, keyed by `storageKey(session)`. The web toolbar keeps it in the page's
126
+ * `localStorage` itself; native clients pass the device keychain.
127
+ */
128
+ export type MemberTokenStore = {
129
+ read(key: string): Promise<string | null>;
130
+ write(key: string, token: string): Promise<void>;
131
+ remove(key: string): Promise<void>;
132
+ };
133
+ /** The stored member token for `session`, or null when there is none or it has expired. */
134
+ export declare function readMemberToken(session: Pick<Session, "apiUrl" | "project" | "environment">, store: MemberTokenStore): Promise<string | null>;
135
+ export declare function memberIsCurrent(token: string): boolean;
136
+ /**
137
+ * How people can sign in here: through the service's identity connection, or not at all. Passphrase sign-in is
138
+ * gone. The wire keeps the connection under `msf`, its name from before.
139
+ */
140
+ export type SignInOptions = {
141
+ passphrase: false;
142
+ /** `label` names the account to sign in with; "your account" when the service names none. */
143
+ msf: {
144
+ authorizeUrl: string;
145
+ label: string;
146
+ } | null;
147
+ /** The options request failed. */
148
+ unavailable?: boolean;
149
+ /** The status it failed with, when the service answered. */
150
+ status?: number;
151
+ };
152
+ export declare function signInOptions(session: Session): Promise<SignInOptions>;
153
+ /** Base64url without padding, as OAuth PKCE wants for the state, verifier and challenge. */
154
+ export declare function base64Url(bytes: Uint8Array): string;
155
+ /**
156
+ * The identity connection's authorize URL for an OAuth 2.0 request with PKCE (S256). The sign-in callback sends the code
157
+ * back to `returnTo` (a page of this app, without a hash, or a native app's `<scheme>://app/app-comments/auth`).
158
+ */
159
+ export declare function msfAuthorizeUrl(authorizeUrl: string, returnTo: string, state: string, challenge: string): string;
160
+ /** Trades the authorization code for a member token. */
161
+ export declare function finishMsfSignIn(session: Session, input: {
162
+ state: string;
163
+ verifier: string;
164
+ code: string;
165
+ }): Promise<string>;
166
+ /** What the sign-in window hands back to the app (a code, or an error such as access_denied). */
167
+ export type MsfHandoff = {
168
+ state: string;
169
+ code?: string;
170
+ error?: string;
171
+ at: number;
172
+ };
173
+ /** The sign-in result the callback puts in the return address's hash (`cs-msf-state`, `cs-msf-code`, `cs-msf-error`). */
174
+ export declare function msfHandoffFrom(hash: string, at?: number): MsfHandoff | null;
175
+ export declare function createInvite(session: Session, memberToken: string): Promise<{
176
+ invite: string;
177
+ invitedBy: string;
178
+ expiresAt: string;
179
+ }>;
180
+ export declare function getProfile(session: Session, memberToken: string): Promise<Profile>;
181
+ export declare function updateProfile(session: Session, memberToken: string, patch: {
182
+ displayName?: string;
183
+ email?: string;
184
+ mentionEmails?: boolean;
185
+ }): Promise<Profile & {
186
+ token: string;
187
+ }>;
188
+ export declare function uploadAttachment(session: Session, memberToken: string, file: Blob, name: string, environment?: string, capture?: Capture,
189
+ /** The image was drawn on in the markup editor; the comment service shows it to the title model first. */
190
+ markedUp?: boolean): Promise<Attachment>;
191
+ /**
192
+ * One dictated piece to text, sent as its blob's type (`audio/wav`, `audio/mp4`, `audio/x-m4a`; WAV when the
193
+ * blob is untyped). `prompt` is the writing just before it, for continuity.
194
+ */
195
+ export declare function transcribeAudio(session: Session, memberToken: string, audio: Blob, prompt: string, signal: AbortSignal, environment?: string): Promise<string>;
196
+ export declare function listMembers(session: Session, memberToken: string, environment?: string): Promise<Member[]>;
197
+ /** "view": this person may read but not comment. Older services don't send it, which means "edit". */
198
+ export type Access = "edit" | "view";
199
+ export declare function listThreads(session: Session, memberToken: string): Promise<{
200
+ threads: Thread[];
201
+ settings: Settings;
202
+ environment?: string | null;
203
+ linked?: string[];
204
+ access?: Access;
205
+ /** Set by the project's people settings. A tester comments with the ticket form. */
206
+ memberType?: "client" | "tester";
207
+ /**
208
+ * Whether this environment checks a new comment before it is posted (`./clarity-model.ts`). A service
209
+ * that predates the check doesn't send it, and is never asked to check.
210
+ */
211
+ clarity?: ClarityMode;
212
+ }>;
213
+ /**
214
+ * Asks whether a comment that has not been posted yet says enough for a reader to act on. Resolves with the
215
+ * service's answer as it came (`readClarityResponse` reads it) and rejects on any other status; the caller
216
+ * posts the comment either way (`askClarity`).
217
+ */
218
+ export declare function checkClarity(session: Session, memberToken: string, draft: ClarityDraft, signal?: AbortSignal): Promise<unknown>;
219
+ /** The tracker's ticket form, for testers only. */
220
+ export declare function fetchTicketForm(session: Session, memberToken: string): Promise<TicketForm>;
221
+ /** A socket that says "changed" whenever comments change in this environment or one it links to. */
222
+ export declare function openLive(session: Session, memberToken: string): WebSocket;
223
+ export declare function saveSettings(session: Session, memberToken: string, settings: Settings): Promise<Settings>;
224
+ export declare function createThread(session: Session, memberToken: string, anchor: Anchor, body: string, extras?: PostExtras & Partial<Details> & {
225
+ url?: string;
226
+ ticket?: TicketDraft;
227
+ kind?: ReportKind;
228
+ }): Promise<{
229
+ thread: Thread;
230
+ delivery?: Delivery;
231
+ }>;
232
+ export declare function replyToThread(session: Session, memberToken: string, threadId: string, body: string, extras?: PostExtras): Promise<{
233
+ message: CommentMessage;
234
+ delivery?: Delivery;
235
+ }>;
236
+ export declare function updateThread(session: Session, memberToken: string, threadId: string, patch: {
237
+ status?: "open" | "resolved";
238
+ anchor?: Anchor;
239
+ url?: string;
240
+ } & Partial<Details>): Promise<{
241
+ id: string;
242
+ }>;
243
+ export declare function editMessage(session: Session, memberToken: string, threadId: string, messageId: string, body: string, mentions: string[]): Promise<{
244
+ message: {
245
+ id: string;
246
+ body: string;
247
+ editedAt: string | null;
248
+ };
249
+ delivery: Delivery | null;
250
+ }>;
@@ -0,0 +1,16 @@
1
+ /** How attachments are limited, named and described. DOM-free, so native clients share it. */
2
+ /** Largest file one message may carry. */
3
+ export declare const ATTACHMENT_MAX_BYTES: number;
4
+ /** Most files one message may carry. */
5
+ export declare const ATTACHMENT_MAX_FILES = 5;
6
+ /** The file types a message may carry (the file picker's `accept` list). */
7
+ export declare const ATTACHMENT_TYPES: readonly string[];
8
+ /** `2026-10-31-13-56-37` (UTC): the stamp in `recording-…`, `replay-…` and other attachment names. */
9
+ export declare function attachmentStamp(at: number | Date): string;
10
+ /** `512 B`, `40 KB`, `2.4 MB`. */
11
+ export declare function formatSize(bytes: number): string;
12
+ /** A `replay-*.json` activity file (an instant replay or a clip's timeline). */
13
+ export declare function isReplayFile(file: {
14
+ name: string;
15
+ contentType: string;
16
+ }): boolean;
@@ -1,6 +1,16 @@
1
- import { type ClipboardEvent } from "react";
1
+ import { type ButtonHTMLAttributes, type ClipboardEvent } from "react";
2
2
  import { type Attachment, type Capture } from "./client.js";
3
+ import type { MarkupShape } from "./markup.js";
4
+ import { type MarkupResult } from "./markup-editor.js";
3
5
  import type { Session } from "./session.js";
6
+ export { ATTACHMENT_MAX_BYTES, formatSize, isReplayFile } from "./attachment-model.js";
7
+ /** The file an image was marked up from, so markup stays editable until the message is sent. */
8
+ export type MarkupSource = {
9
+ blob: Blob;
10
+ url: string;
11
+ name: string;
12
+ shapes: MarkupShape[];
13
+ };
4
14
  export type Pending = {
5
15
  key: string;
6
16
  name: string;
@@ -8,11 +18,12 @@ export type Pending = {
8
18
  contentType: string;
9
19
  preview: string | null;
10
20
  status: "uploading" | "ready" | "failed";
21
+ blob: Blob;
11
22
  id?: string;
12
23
  error?: string;
13
- capture?: Capture;
24
+ capture?: Capture | undefined;
25
+ markup?: MarkupSource | undefined;
14
26
  };
15
- export declare function formatSize(bytes: number): string;
16
27
  /** Files attached to one draft. Each upload starts immediately so posting doesn't wait on the network. */
17
28
  export declare function useAttachments(session: Session | null, memberToken: string | null, onError: (message: string) => void, environment?: string): {
18
29
  items: Pending[];
@@ -20,9 +31,22 @@ export declare function useAttachments(session: Session | null, memberToken: str
20
31
  blob: Blob;
21
32
  name: string;
22
33
  capture?: Capture;
23
- }>) => void;
34
+ }>) => string[];
35
+ replace: (key: string, result: MarkupResult) => string | null;
24
36
  remove: (key: string) => void;
25
37
  reset: () => void;
38
+ restore: (files: Array<{
39
+ key: string;
40
+ blob: Blob;
41
+ name: string;
42
+ capture?: Capture | undefined;
43
+ markup?: {
44
+ blob: Blob;
45
+ name: string;
46
+ shapes: MarkupShape[];
47
+ } | undefined;
48
+ }>) => void;
49
+ settled: () => Promise<Pending[]>;
26
50
  ids: string[];
27
51
  uploading: boolean;
28
52
  };
@@ -35,7 +59,13 @@ export type PreviewFile = {
35
59
  name: string;
36
60
  contentType: string;
37
61
  url: string;
38
- capture?: Capture;
62
+ capture?: Capture | undefined;
63
+ /** A draft image's unmarked original and its markup, for the editor. */
64
+ markup?: {
65
+ src: string;
66
+ name: string;
67
+ shapes: MarkupShape[];
68
+ } | undefined;
39
69
  };
40
70
  /** Images, videos, and replays waiting in a draft, in tray order, for the preview beside the composer. */
41
71
  export declare function pendingPreviews(items: Pending[]): PreviewFile[];
@@ -45,6 +75,7 @@ export declare function AttachmentTray({ items, activeKey, onPreview, onRemove,
45
75
  onPreview?: (item: Pending) => void;
46
76
  onRemove: (key: string) => void;
47
77
  }): import("react/jsx-runtime").JSX.Element | null;
78
+ export declare function AttachButton({ onPointerDown, onPointerLeave, ...props }: ButtonHTMLAttributes<HTMLButtonElement>): import("react/jsx-runtime").JSX.Element;
48
79
  export declare function AttachButtons({ onFiles, onSnapshot, onRecord, onReplay, capturing, }: {
49
80
  onFiles: (files: Array<{
50
81
  blob: Blob;
@@ -64,10 +95,15 @@ export declare function MessageAttachments({ attachments, activeId, onPreview, }
64
95
  activeId?: string | null;
65
96
  onPreview: (file: Attachment) => void;
66
97
  }): import("react/jsx-runtime").JSX.Element | null;
67
- /** The image, video, or replay open beside a thread. Arrows walk the thread's other previewable files. */
68
- export declare function MediaPane({ files, fileId, onSelect, onClose, }: {
98
+ /**
99
+ * The image, video, or replay open beside a thread. Arrows walk the thread's other previewable files. With
100
+ * `onMarkup`, a draft image can be marked up; `onMarkingUp` hears when the editor opens and closes.
101
+ */
102
+ export declare function MediaPane({ files, fileId, onSelect, onClose, onMarkup, onMarkingUp, }: {
69
103
  files: PreviewFile[];
70
104
  fileId: string;
71
105
  onSelect: (fileId: string) => void;
72
106
  onClose: () => void;
107
+ onMarkup?: (fileId: string, result: MarkupResult) => void;
108
+ onMarkingUp?: (open: boolean) => void;
73
109
  }): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,39 @@
1
+ import type { RuntimeProps, ToolbarHandle } from "./runtime.js";
2
+ import type { Session } from "./session-source.js";
3
+ export type Runtime = {
4
+ mount(container: HTMLElement, props: RuntimeProps): ToolbarHandle;
5
+ };
6
+ /** The session request waits for the page to go idle, but no longer than this after the loader starts. */
7
+ export declare const IDLE_TIMEOUT_MS = 3000;
8
+ /** Runs `task` later and returns a function that cancels it. */
9
+ export type Wait = (task: () => void) => () => void;
10
+ declare const importModule: (url: string) => Promise<unknown>;
11
+ /**
12
+ * The toolbar always comes from the App comments worker, never from the host's own bundle: every deploy of the
13
+ * service serves the new build, open toolbars swap to it on their own, and a host never needs an update for it.
14
+ */
15
+ export declare function loadRuntime(apiUrl: string, load?: typeof importModule): Promise<Runtime>;
16
+ export type Boot = {
17
+ /** Asks the session route, or reuses its kept answer. Null, or a rejection, means no toolbar. */
18
+ getSession: () => Promise<Session | null>;
19
+ /** Read when the toolbar mounts, so it starts with the host's latest props. */
20
+ props: () => RuntimeProps;
21
+ /** Called once the toolbar is mounted, with its handle and the element it is mounted in. */
22
+ onMount?: (handle: ToolbarHandle, container: HTMLElement) => void;
23
+ /** Called when this attempt is over: the toolbar is mounted, or it will not be. */
24
+ onSettled?: () => void;
25
+ /** When to start. Default: when the page is idle, or after IDLE_TIMEOUT_MS at the latest. */
26
+ wait?: Wait;
27
+ /** Where the runtime comes from. Default: `loadRuntime`. */
28
+ load?: (apiUrl: string) => Promise<Runtime>;
29
+ };
30
+ /**
31
+ * One attempt to bring the toolbar up. Does nothing until `wait` runs it; then asks for the session once, and
32
+ * only when comments are on loads the runtime and mounts it in a new `<div data-cs-runtime="latest">` at the
33
+ * end of `<body>`.
34
+ *
35
+ * Returns `stop`: before the mount it calls the attempt off, after it it unmounts the toolbar and removes the
36
+ * element.
37
+ */
38
+ export declare function bootToolbar(boot: Boot): () => void;
39
+ export {};
@@ -0,0 +1,5 @@
1
+ /** "Chrome 142" from a user agent, or undefined. Only the name and major version: never the full string. */
2
+ export declare function browserName(agent: string): string | undefined;
3
+ export declare function systemName(agent: string): string | undefined;
4
+ /** "Chrome 142 · macOS", or undefined when neither is known. */
5
+ export declare function browserLabel(agent: string): string | undefined;
@@ -2,5 +2,6 @@
2
2
  * Identifies this build of the runtime. `scripts/app-comments/build-toolbar.mjs` defines it from a hash of the
3
3
  * runtime's source and writes the same value to `/v1/toolbar/build.json` next to the bundle, so a running toolbar
4
4
  * can tell when the worker started serving a newer build. "dev" when the bundle was built without it (tests).
5
+ * Any change under src/runtime or src/core changes the id, so every deploy that touches the toolbar is announced.
5
6
  */
6
7
  export declare const runtimeBuild: string;
@@ -4,32 +4,56 @@ type AddFiles = (files: Array<{
4
4
  name: string;
5
5
  capture?: Capture;
6
6
  }>) => void;
7
- /** Records the current tab, then asks before the file is attached. Nothing is uploaded here. */
8
- export declare function useTabRecording(onError: (message: string) => void): {
9
- phase: "idle" | "recording" | "review";
10
- elapsed: number;
11
- review: {
12
- url: string;
7
+ /** What a take tells the world while it runs, and what goes with the file when it is kept. */
8
+ export type RecordingExtras = {
9
+ /** Every chunk as it lands (see `RecordOptions.onChunk`). */
10
+ onChunk?: (chunk: Blob, index: number, mime: string) => void;
11
+ /** Files to attach beside the recording, named after the same stamp (a replay of what happened in it). */
12
+ companions?: (info: {
13
+ stamp: string;
14
+ startedAt: number;
15
+ durationMs: number;
16
+ name: string;
17
+ }) => Array<{
13
18
  blob: Blob;
14
- } | null;
15
- tooBig: boolean;
16
- begin: (add: AddFiles) => Promise<void>;
19
+ name: string;
20
+ }>;
21
+ };
22
+ /**
23
+ * The recording's sound: `on` and `muted` while the mic is in the take, `off` when the person chose no sound,
24
+ * `refused` when they wanted it but the mic wasn't given.
25
+ */
26
+ export type RecordingSound = "on" | "muted" | "off" | "refused";
27
+ /**
28
+ * Records the current tab and attaches the file to the draft as soon as it stops. Nothing is uploaded here. `sound` is the
29
+ * person's saved choice to record the mic; `onSoundChange` saves a new one.
30
+ */
31
+ export declare function useTabRecording(onError: (message: string) => void, sound: boolean, onSoundChange: (sound: boolean) => void): {
32
+ phase: "idle" | "recording";
33
+ elapsed: number;
34
+ sound: RecordingSound;
35
+ /** What the next recording will do about sound. */
36
+ soundNext: boolean;
37
+ toggleSound: () => void;
38
+ begin: (add: AddFiles, more?: RecordingExtras) => Promise<void>;
17
39
  stop: () => void | undefined;
18
40
  cancel: () => void;
19
- keep: () => void;
20
- again: () => void;
21
41
  };
22
- export declare function RecordChrome({ phase, elapsed, review, tooBig, onStop, onCancel, onKeep, onAgain, }: {
23
- phase: "recording" | "review";
42
+ /** Dictation into the comment the recording belongs to, driven from the record bar. */
43
+ export type RecordDictation = {
44
+ listening: boolean;
45
+ /** Pieces still being written. */
46
+ queued: number;
47
+ toggle: () => void;
48
+ };
49
+ export declare function RecordChrome({ elapsed, sound, soundNext, dictation, onToggleSound, onStop, onCancel, }: {
24
50
  elapsed: number;
25
- review: {
26
- url: string;
27
- blob: Blob;
28
- } | null;
29
- tooBig: boolean;
51
+ sound: RecordingSound;
52
+ soundNext: boolean;
53
+ /** Absent when there is no comment box to type into. */
54
+ dictation?: RecordDictation;
55
+ onToggleSound: () => void;
30
56
  onStop: () => void;
31
57
  onCancel: () => void;
32
- onKeep: () => void;
33
- onAgain: () => void;
34
- }): import("react/jsx-runtime").JSX.Element | null;
58
+ }): import("react/jsx-runtime").JSX.Element;
35
59
  export {};