@yadsh/dsh-qa-surface 0.1.1 → 0.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 (192) hide show
  1. package/CHANGELOG.md +151 -0
  2. package/README.md +239 -16
  3. package/SPEC-dsh-qa-surface.md +600 -96
  4. package/capability-policy.json +5 -0
  5. package/compatibility.json +18 -4
  6. package/cordis.patch.yml +11 -0
  7. package/docs/ARCHITECTURE.md +50 -8
  8. package/docs/COMPATIBILITY.md +5 -4
  9. package/docs/CONFIGURATION.md +184 -3
  10. package/docs/SOURCES-MIGRATION.md +28 -0
  11. package/docs/SOURCES-PROVENANCE-AUDIT.md +88 -0
  12. package/docs/SPEC-dsh-qa-surface-accounts.md +219 -0
  13. package/docs/SPEC-dsh-qa-surface-sources-provenance.md +1692 -0
  14. package/lib/accounts/index.js +2 -0
  15. package/lib/accounts/index.js.map +1 -0
  16. package/lib/accounts/store.js +478 -0
  17. package/lib/accounts/store.js.map +1 -0
  18. package/lib/attestation.js +10 -0
  19. package/lib/attestation.js.map +1 -0
  20. package/lib/cli.js +143 -0
  21. package/lib/cli.js.map +1 -0
  22. package/lib/client/QaAccountsController.js +329 -0
  23. package/lib/client/QaAccountsController.js.map +1 -0
  24. package/lib/client/QaConfigController.js +111 -4
  25. package/lib/client/QaConfigController.js.map +1 -1
  26. package/lib/client/QaSessionController.js +621 -163
  27. package/lib/client/QaSessionController.js.map +1 -1
  28. package/lib/client/QaSurface.js +303 -24
  29. package/lib/client/QaSurface.js.map +1 -1
  30. package/lib/client/QaTranscriptAdapter.js +324 -49
  31. package/lib/client/QaTranscriptAdapter.js.map +1 -1
  32. package/lib/client/attestation.js +66 -0
  33. package/lib/client/attestation.js.map +1 -0
  34. package/lib/client/chat-index.js +86 -0
  35. package/lib/client/chat-index.js.map +1 -0
  36. package/lib/client/components/Markdown.js +124 -13
  37. package/lib/client/components/Markdown.js.map +1 -1
  38. package/lib/client/components/QaAgentsDrawer.js +40 -0
  39. package/lib/client/components/QaAgentsDrawer.js.map +1 -0
  40. package/lib/client/components/QaAuthGate.js +40 -0
  41. package/lib/client/components/QaAuthGate.js.map +1 -0
  42. package/lib/client/components/QaChangelog.js +112 -0
  43. package/lib/client/components/QaChangelog.js.map +1 -0
  44. package/lib/client/components/QaComposer.js +132 -15
  45. package/lib/client/components/QaComposer.js.map +1 -1
  46. package/lib/client/components/QaMessage.js +214 -10
  47. package/lib/client/components/QaMessage.js.map +1 -1
  48. package/lib/client/components/QaSidebar.js +167 -0
  49. package/lib/client/components/QaSidebar.js.map +1 -0
  50. package/lib/client/components/QaSourcesDrawer.js +127 -0
  51. package/lib/client/components/QaSourcesDrawer.js.map +1 -0
  52. package/lib/client/components/QaTurnRail.js +281 -0
  53. package/lib/client/components/QaTurnRail.js.map +1 -0
  54. package/lib/client/components/QaWelcomeNotice.js +125 -0
  55. package/lib/client/components/QaWelcomeNotice.js.map +1 -0
  56. package/lib/client/components/QaWidthHandle.js +142 -0
  57. package/lib/client/components/QaWidthHandle.js.map +1 -0
  58. package/lib/client/components/QaWorkGroup.js +135 -0
  59. package/lib/client/components/QaWorkGroup.js.map +1 -0
  60. package/lib/client/components/VariantSwitcher.js +29 -0
  61. package/lib/client/components/VariantSwitcher.js.map +1 -0
  62. package/lib/client/components/format.js +48 -0
  63. package/lib/client/components/format.js.map +1 -0
  64. package/lib/client/components/source-refs.js +78 -0
  65. package/lib/client/components/source-refs.js.map +1 -0
  66. package/lib/client/create-session.js +51 -0
  67. package/lib/client/create-session.js.map +1 -0
  68. package/lib/client/index.js +166 -35
  69. package/lib/client/index.js.map +1 -1
  70. package/lib/client/project-session-state.js +78 -0
  71. package/lib/client/project-session-state.js.map +1 -0
  72. package/lib/client/session-admission.js +38 -0
  73. package/lib/client/session-admission.js.map +1 -0
  74. package/lib/client/session-assets.js +52 -0
  75. package/lib/client/session-assets.js.map +1 -0
  76. package/lib/client/session-sources.js +61 -0
  77. package/lib/client/session-sources.js.map +1 -0
  78. package/lib/client/settlement.js +24 -0
  79. package/lib/client/settlement.js.map +1 -0
  80. package/lib/client/styles.js +450 -43
  81. package/lib/client/styles.js.map +1 -1
  82. package/lib/client/tool-presentation.js +102 -0
  83. package/lib/client/tool-presentation.js.map +1 -0
  84. package/lib/client/turn-sources.js +98 -0
  85. package/lib/client/turn-sources.js.map +1 -0
  86. package/lib/client/types.js +15 -0
  87. package/lib/client/types.js.map +1 -0
  88. package/lib/client/use-session-ui-state.js +68 -0
  89. package/lib/client/use-session-ui-state.js.map +1 -0
  90. package/lib/client/use-transcript-view.js +44 -0
  91. package/lib/client/use-transcript-view.js.map +1 -0
  92. package/lib/client/wait-for.js +49 -0
  93. package/lib/client/wait-for.js.map +1 -0
  94. package/lib/client.js +12551 -918
  95. package/lib/client.js.map +1 -1
  96. package/lib/config.js +226 -58
  97. package/lib/config.js.map +1 -1
  98. package/lib/entry-redirect.js +44 -0
  99. package/lib/entry-redirect.js.map +1 -0
  100. package/lib/host-route.js +25 -1
  101. package/lib/host-route.js.map +1 -1
  102. package/lib/index.js +354 -72
  103. package/lib/index.js.map +1 -1
  104. package/lib/launch-token.js +42 -0
  105. package/lib/launch-token.js.map +1 -0
  106. package/lib/lockdown-policy.js +20 -0
  107. package/lib/lockdown-policy.js.map +1 -0
  108. package/lib/provenance/collector.js +40 -0
  109. package/lib/provenance/collector.js.map +1 -0
  110. package/lib/provenance/connectors.js +147 -0
  111. package/lib/provenance/connectors.js.map +1 -0
  112. package/lib/provenance/dedupe.js +89 -0
  113. package/lib/provenance/dedupe.js.map +1 -0
  114. package/lib/provenance/extractors.js +340 -0
  115. package/lib/provenance/extractors.js.map +1 -0
  116. package/lib/provenance/file-preview.js +39 -0
  117. package/lib/provenance/file-preview.js.map +1 -0
  118. package/lib/provenance/host-store.js +387 -0
  119. package/lib/provenance/host-store.js.map +1 -0
  120. package/lib/provenance/index.js +9 -0
  121. package/lib/provenance/index.js.map +1 -0
  122. package/lib/provenance/normalize.js +128 -0
  123. package/lib/provenance/normalize.js.map +1 -0
  124. package/lib/provenance/reported.js +53 -0
  125. package/lib/provenance/reported.js.map +1 -0
  126. package/lib/provenance/types.js +2 -0
  127. package/lib/provenance/types.js.map +1 -0
  128. package/lib/resolve-config.js +283 -10
  129. package/lib/resolve-config.js.map +1 -1
  130. package/lib/secure-session.js +212 -0
  131. package/lib/secure-session.js.map +1 -0
  132. package/lib/typert.host.d.ts +3 -0
  133. package/lib/typert.host.js +784 -0
  134. package/lib/typert.remote-client.d.ts +40 -0
  135. package/lib/typert.remote-client.js +597 -0
  136. package/lib/types/accounts/index.d.ts +2 -0
  137. package/lib/types/accounts/store.d.ts +121 -0
  138. package/lib/types/attestation.d.ts +17 -0
  139. package/lib/types/cli.d.ts +9 -0
  140. package/lib/types/client/QaAccountsController.d.ts +95 -0
  141. package/lib/types/client/QaConfigController.d.ts +35 -3
  142. package/lib/types/client/QaSessionController.d.ts +146 -20
  143. package/lib/types/client/QaSurface.d.ts +11 -5
  144. package/lib/types/client/QaTranscriptAdapter.d.ts +13 -3
  145. package/lib/types/client/attestation.d.ts +25 -0
  146. package/lib/types/client/chat-index.d.ts +28 -0
  147. package/lib/types/client/components/Markdown.d.ts +17 -3
  148. package/lib/types/client/components/QaAgentsDrawer.d.ts +25 -0
  149. package/lib/types/client/components/QaAuthGate.d.ts +15 -0
  150. package/lib/types/client/components/QaChangelog.d.ts +21 -0
  151. package/lib/types/client/components/QaComposer.d.ts +12 -2
  152. package/lib/types/client/components/QaMessage.d.ts +22 -2
  153. package/lib/types/client/components/QaSidebar.d.ts +69 -0
  154. package/lib/types/client/components/QaSourcesDrawer.d.ts +20 -0
  155. package/lib/types/client/components/QaTurnRail.d.ts +59 -0
  156. package/lib/types/client/components/QaWelcomeNotice.d.ts +27 -0
  157. package/lib/types/client/components/QaWidthHandle.d.ts +36 -0
  158. package/lib/types/client/components/QaWorkGroup.d.ts +19 -0
  159. package/lib/types/client/components/VariantSwitcher.d.ts +19 -0
  160. package/lib/types/client/components/format.d.ts +9 -0
  161. package/lib/types/client/components/source-refs.d.ts +16 -0
  162. package/lib/types/client/create-session.d.ts +16 -0
  163. package/lib/types/client/index.d.ts +2 -5
  164. package/lib/types/client/project-session-state.d.ts +30 -0
  165. package/lib/types/client/session-admission.d.ts +23 -0
  166. package/lib/types/client/session-assets.d.ts +20 -0
  167. package/lib/types/client/session-sources.d.ts +28 -0
  168. package/lib/types/client/settlement.d.ts +6 -0
  169. package/lib/types/client/tool-presentation.d.ts +6 -0
  170. package/lib/types/client/turn-sources.d.ts +14 -0
  171. package/lib/types/client/types.d.ts +93 -0
  172. package/lib/types/client/use-session-ui-state.d.ts +35 -0
  173. package/lib/types/client/use-transcript-view.d.ts +20 -0
  174. package/lib/types/client/wait-for.d.ts +11 -0
  175. package/lib/types/entry-redirect.d.ts +20 -0
  176. package/lib/types/host-route.d.ts +14 -1
  177. package/lib/types/index.d.ts +67 -7
  178. package/lib/types/launch-token.d.ts +21 -0
  179. package/lib/types/lockdown-policy.d.ts +18 -0
  180. package/lib/types/provenance/collector.d.ts +26 -0
  181. package/lib/types/provenance/connectors.d.ts +11 -0
  182. package/lib/types/provenance/dedupe.d.ts +6 -0
  183. package/lib/types/provenance/extractors.d.ts +14 -0
  184. package/lib/types/provenance/file-preview.d.ts +10 -0
  185. package/lib/types/provenance/host-store.d.ts +54 -0
  186. package/lib/types/provenance/index.d.ts +10 -0
  187. package/lib/types/provenance/normalize.d.ts +13 -0
  188. package/lib/types/provenance/reported.d.ts +5 -0
  189. package/lib/types/provenance/types.d.ts +78 -0
  190. package/lib/types/secure-session.d.ts +31 -0
  191. package/lib/types/types.d.ts +304 -1
  192. package/package.json +70 -27
@@ -1,4 +1,87 @@
1
+ import type { QaTurnSources } from "./provenance/types.js";
1
2
  export type QaSessionPolicy = "browser-persistent" | "new-on-load" | "fixed";
3
+ export type QaSandboxMode = "read-only";
4
+ export type QaApprovalPolicy = "never";
5
+ export type QaToolPolicyMode = "allow-list";
6
+ export type QaAccountRole = "user" | "admin";
7
+ /** The account fields projected to browsers; never includes credentials. */
8
+ export interface QaAccountUserPublic {
9
+ readonly id: string;
10
+ readonly email: string;
11
+ readonly displayName: string;
12
+ readonly role: QaAccountRole;
13
+ readonly createdAt: string;
14
+ readonly lastLoginAt: string | null;
15
+ readonly disabled: boolean;
16
+ }
17
+ /** One successful login/registration: the bearer token plus the user. */
18
+ export interface QaAccountSession {
19
+ readonly token: string;
20
+ readonly user: QaAccountUserPublic;
21
+ }
22
+ export type QaWhoamiResult = {
23
+ readonly authenticated: false;
24
+ } | {
25
+ readonly authenticated: true;
26
+ readonly user: QaAccountUserPublic;
27
+ };
28
+ /** Bulk ownership claim outcome for one browser's local chat index. */
29
+ export interface QaClaimResult {
30
+ readonly claimed: number;
31
+ /** Ids already owned by a different user; the browser drops them. */
32
+ readonly conflicts: readonly string[];
33
+ }
34
+ /**
35
+ * One chat-ownership entry as the admin views see it: the session, its owner
36
+ * and the owner's display name resolved at read time (a disabled account
37
+ * still names its chats).
38
+ */
39
+ export interface QaOwnershipEntry {
40
+ readonly sessionId: string;
41
+ readonly userId: string;
42
+ readonly displayName: string;
43
+ readonly claimedAt: string;
44
+ }
45
+ export interface QaSourcesConfig {
46
+ readonly enabled?: boolean;
47
+ readonly collect?: {
48
+ readonly parentAgent?: boolean;
49
+ readonly subagents?: boolean;
50
+ readonly persistTurnEvent?: boolean;
51
+ };
52
+ readonly display?: {
53
+ readonly sidebar?: boolean;
54
+ readonly footer?: boolean;
55
+ readonly groupByKind?: boolean;
56
+ readonly showDiscovered?: boolean;
57
+ readonly showOriginBadges?: boolean;
58
+ readonly maxInitiallyVisiblePerGroup?: number;
59
+ };
60
+ readonly webSearch?: {
61
+ readonly promoteSearchResultsWithoutFetch?: boolean;
62
+ readonly maxPromotedPerSearch?: number;
63
+ };
64
+ readonly dedupe?: {
65
+ readonly normalizeUrls?: boolean;
66
+ readonly stripTrackingParams?: boolean;
67
+ readonly mergeFileRanges?: boolean;
68
+ };
69
+ readonly filePreview?: {
70
+ readonly enabled?: boolean;
71
+ readonly markdownRenderedByDefault?: boolean;
72
+ readonly allowRawToggle?: boolean;
73
+ readonly maxBytes?: number;
74
+ readonly maxMarkdownRenderBytes?: number;
75
+ };
76
+ readonly subagents?: {
77
+ readonly inheritSources?: boolean;
78
+ readonly enableReportToolFallback?: boolean;
79
+ readonly markIncompleteOpaqueRuns?: boolean;
80
+ };
81
+ readonly legacy?: {
82
+ readonly parseAssistantSourcesBlock?: boolean;
83
+ };
84
+ }
2
85
  export interface QaSurfaceConfig {
3
86
  readonly enabled?: boolean;
4
87
  readonly route?: {
@@ -11,10 +94,14 @@ export interface QaSurfaceConfig {
11
94
  readonly welcomeMessage?: string;
12
95
  readonly placeholder?: string;
13
96
  readonly logoUrl?: string | null;
97
+ /** Data-usage notice under the composer; empty string hides the plate. */
98
+ readonly disclaimer?: string | null;
14
99
  };
15
100
  readonly session?: {
16
101
  readonly policy?: QaSessionPolicy;
17
102
  readonly storageKey?: string;
103
+ /** Absolute directory pinned as the session cwd (alternative to workspaceId). */
104
+ readonly cwd?: string | null;
18
105
  readonly workspaceId?: string | null;
19
106
  readonly fixedSessionId?: string | null;
20
107
  readonly agentPreset?: string | null;
@@ -31,15 +118,51 @@ export interface QaSurfaceConfig {
31
118
  readonly showReasoning?: boolean;
32
119
  readonly renderMarkdown?: boolean;
33
120
  readonly maxContentWidth?: number;
121
+ readonly showSessionList?: boolean;
34
122
  };
35
123
  readonly suggestedQuestions?: readonly string[];
36
124
  readonly interaction?: {
37
125
  readonly approvals?: "blocked";
38
126
  readonly questions?: "unsupported";
39
127
  };
128
+ readonly lockdown?: {
129
+ readonly enabled?: boolean;
130
+ readonly enforceFixedAgentPreset?: boolean;
131
+ readonly enforceFixedWorkspace?: boolean;
132
+ readonly enforceFixedModel?: boolean;
133
+ readonly sandboxMode?: QaSandboxMode;
134
+ readonly approvalPolicy?: QaApprovalPolicy;
135
+ readonly permissionPreset?: string;
136
+ readonly allowPermissionChanges?: false;
137
+ readonly allowSlashCommands?: false;
138
+ readonly allowSettingsMutation?: false;
139
+ readonly allowSessionReset?: boolean;
140
+ readonly allowSessionRename?: false;
141
+ readonly allowSessionDelete?: false;
142
+ readonly allowArbitrarySessionOpen?: false;
143
+ readonly toolPolicy?: {
144
+ readonly mode?: QaToolPolicyMode;
145
+ readonly allow?: readonly string[];
146
+ };
147
+ };
40
148
  readonly embedding?: {
41
149
  readonly frameAncestors?: string | null;
42
150
  };
151
+ readonly accounts?: {
152
+ /** Opt-in; the QA gate stays off until the deployment turns this on. */
153
+ readonly enabled?: boolean;
154
+ readonly allowRegistration?: boolean;
155
+ readonly sessionTtlDays?: number;
156
+ /** Let admins see chats owned by other QA accounts. */
157
+ readonly showOtherUsersChats?: boolean;
158
+ };
159
+ readonly entry?: {
160
+ /** Inject the root → /qa redirect for non-loopback hostnames. */
161
+ readonly redirectNonLoopback?: boolean;
162
+ /** Cookie-less /qa navigations go through the one-time ?token= exchange. */
163
+ readonly cookieBootstrap?: boolean;
164
+ };
165
+ readonly sources?: QaSourcesConfig;
43
166
  }
44
167
  export interface ResolvedQaSurfaceConfig {
45
168
  readonly enabled: boolean;
@@ -53,10 +176,12 @@ export interface ResolvedQaSurfaceConfig {
53
176
  readonly welcomeMessage: string;
54
177
  readonly placeholder: string;
55
178
  readonly logoUrl: string | null;
179
+ readonly disclaimer: string;
56
180
  };
57
181
  readonly session: {
58
182
  readonly policy: QaSessionPolicy;
59
183
  readonly storageKey: string;
184
+ readonly cwd: string | null;
60
185
  readonly workspaceId: string | null;
61
186
  readonly fixedSessionId: string | null;
62
187
  readonly agentPreset: string | null;
@@ -70,18 +195,110 @@ export interface ResolvedQaSurfaceConfig {
70
195
  readonly showStop: boolean;
71
196
  readonly showTimestamps: boolean;
72
197
  readonly showToolActivity: boolean;
73
- readonly showReasoning: false;
198
+ readonly showReasoning: boolean;
74
199
  readonly renderMarkdown: boolean;
75
200
  readonly maxContentWidth: number;
201
+ readonly showSessionList: boolean;
76
202
  };
77
203
  readonly suggestedQuestions: readonly string[];
78
204
  readonly interaction: {
79
205
  readonly approvals: "blocked";
80
206
  readonly questions: "unsupported";
81
207
  };
208
+ readonly lockdown: {
209
+ readonly enabled: boolean;
210
+ readonly enforceFixedAgentPreset: boolean;
211
+ readonly enforceFixedWorkspace: boolean;
212
+ readonly enforceFixedModel: boolean;
213
+ readonly sandboxMode: QaSandboxMode;
214
+ readonly approvalPolicy: QaApprovalPolicy;
215
+ readonly permissionPreset: string;
216
+ readonly allowPermissionChanges: false;
217
+ readonly allowSlashCommands: false;
218
+ readonly allowSettingsMutation: false;
219
+ readonly allowSessionReset: boolean;
220
+ readonly allowSessionRename: false;
221
+ readonly allowSessionDelete: false;
222
+ readonly allowArbitrarySessionOpen: false;
223
+ readonly toolPolicy: {
224
+ readonly mode: QaToolPolicyMode;
225
+ readonly allow: readonly string[];
226
+ };
227
+ };
82
228
  readonly embedding: {
83
229
  readonly frameAncestors: string | null;
84
230
  };
231
+ readonly accounts: {
232
+ readonly enabled: boolean;
233
+ readonly allowRegistration: boolean;
234
+ readonly sessionTtlDays: number;
235
+ readonly showOtherUsersChats: boolean;
236
+ };
237
+ readonly entry: {
238
+ readonly redirectNonLoopback: boolean;
239
+ readonly cookieBootstrap: boolean;
240
+ };
241
+ readonly sources: {
242
+ readonly enabled: boolean;
243
+ readonly collect: {
244
+ readonly parentAgent: boolean;
245
+ readonly subagents: boolean;
246
+ readonly persistTurnEvent: boolean;
247
+ };
248
+ readonly display: {
249
+ readonly sidebar: boolean;
250
+ readonly footer: boolean;
251
+ readonly groupByKind: boolean;
252
+ readonly showDiscovered: boolean;
253
+ readonly showOriginBadges: boolean;
254
+ readonly maxInitiallyVisiblePerGroup: number;
255
+ };
256
+ readonly webSearch: {
257
+ readonly promoteSearchResultsWithoutFetch: boolean;
258
+ readonly maxPromotedPerSearch: number;
259
+ };
260
+ readonly dedupe: {
261
+ readonly normalizeUrls: boolean;
262
+ readonly stripTrackingParams: boolean;
263
+ readonly mergeFileRanges: boolean;
264
+ };
265
+ readonly filePreview: {
266
+ readonly enabled: boolean;
267
+ readonly markdownRenderedByDefault: boolean;
268
+ readonly allowRawToggle: boolean;
269
+ readonly maxBytes: number;
270
+ readonly maxMarkdownRenderBytes: number;
271
+ };
272
+ readonly subagents: {
273
+ readonly inheritSources: boolean;
274
+ readonly enableReportToolFallback: boolean;
275
+ readonly markIncompleteOpaqueRuns: boolean;
276
+ };
277
+ readonly legacy: {
278
+ readonly parseAssistantSourcesBlock: boolean;
279
+ };
280
+ };
281
+ }
282
+ export interface QaSourceFilePreview {
283
+ readonly path: string;
284
+ readonly content: string;
285
+ readonly size: number;
286
+ readonly truncated: boolean;
287
+ readonly markdown: boolean;
288
+ readonly renderableMarkdown: boolean;
289
+ }
290
+ /** Host-attested facts required before the QA composer may become writable. */
291
+ export interface QaLockdownProof {
292
+ readonly sessionId: string;
293
+ readonly enabled: boolean;
294
+ readonly agentPresetMatches: boolean;
295
+ readonly workspaceMatches: boolean;
296
+ readonly modelMatches: boolean;
297
+ readonly sandboxIsReadOnly: boolean;
298
+ readonly approvalIsNever: boolean;
299
+ readonly permissionPreset: string;
300
+ readonly toolPolicyLoaded: boolean;
301
+ readonly toolAllowList: readonly string[];
85
302
  }
86
303
  export type QaMessage = {
87
304
  readonly id: string;
@@ -89,20 +306,98 @@ export type QaMessage = {
89
306
  readonly text: string;
90
307
  readonly status: "committed";
91
308
  readonly timestamp?: number;
309
+ readonly images?: readonly QaImageView[];
310
+ /**
311
+ * Chat owner's display name, set only for an admin reading a foreign
312
+ * chat; the owner themself sees their messages unlabeled.
313
+ */
314
+ readonly author?: string;
92
315
  } | {
93
316
  readonly id: string;
94
317
  readonly role: "assistant";
95
318
  readonly text: string;
96
319
  readonly status: "streaming" | "committed" | "failed";
97
320
  readonly timestamp?: number;
321
+ /** Host turn this answer belongs to; groups regenerations into variants. */
322
+ readonly turn?: number;
323
+ /** Canonical evidence snapshot shared with this answer's source drawer. */
324
+ readonly sources?: readonly QaSource[];
325
+ readonly sourcesComplete?: boolean;
326
+ readonly incompleteSourceOrigins?: QaTurnSources["incompleteOrigins"];
327
+ /** Host-recorded response timing, present on finalized messages only. */
328
+ readonly stats?: {
329
+ /** step start → final message. */
330
+ readonly durationMs: number;
331
+ /** step start → first token; null when no token delta was recorded. */
332
+ readonly ttftMs: number | null;
333
+ /** Estimated from visible text (≈4 chars/token) over the generation window. */
334
+ readonly tokensPerSecond: number | null;
335
+ };
98
336
  } | {
99
337
  readonly id: string;
100
338
  readonly role: "system";
101
339
  readonly text: string;
102
340
  readonly status: "info" | "error";
103
341
  readonly timestamp?: number;
342
+ /** Collapsible settlement row (subagent finished/stopped/failed). */
343
+ readonly notice?: {
344
+ readonly title: string;
345
+ readonly body: string;
346
+ };
347
+ } | {
348
+ readonly id: string;
349
+ readonly role: "work";
350
+ readonly turn: number;
351
+ readonly status: "running" | "complete";
352
+ readonly startedAt?: number;
353
+ readonly endedAt?: number;
354
+ readonly items: readonly QaWorkItem[];
355
+ };
356
+ export type QaWorkItem = {
357
+ readonly id: string;
358
+ readonly kind: "reasoning" | "progress";
359
+ readonly text: string;
360
+ readonly status: "running" | "complete";
361
+ } | {
362
+ readonly id: string;
363
+ readonly kind: "tool";
364
+ readonly name: string;
365
+ readonly label: string;
366
+ readonly summary: string;
367
+ readonly input: string | null;
368
+ readonly output: string | null;
369
+ readonly status: "running" | "ok" | "error" | "stopped";
370
+ /** Durable child id, present on subagent launch calls that started one. */
371
+ readonly subagentId?: string;
372
+ readonly startedAt?: number;
373
+ readonly endedAt?: number;
104
374
  };
105
375
  export type QaSessionPhase = "idle" | "creating" | "ready" | "running" | "reconnecting" | "blocked" | "error";
376
+ export type { QaSourceEvidence, QaSourceKind, QaSourceLocation, QaSourceOrigin, QaSourceReference, QaTurnSources, } from "./provenance/types.js";
377
+ /** Transitional UI name; the drawer now consumes the canonical source object. */
378
+ export type QaSource = import("./provenance/types.js").QaSourceReference;
379
+ /** Raster formats the attachment path accepts (mirrors the host contract). */
380
+ export type QaImageMediaType = "image/png" | "image/jpeg" | "image/webp" | "image/gif";
381
+ /** One image pending in the composer, browser-owned until the prompt lands. */
382
+ export interface QaImageDraft {
383
+ readonly id: string;
384
+ readonly mediaType: QaImageMediaType;
385
+ readonly name: string;
386
+ /** Canonical base64 of the image bytes, without the data: URL prefix. */
387
+ readonly data: string;
388
+ /** Local object URL for the preview thumbnail. */
389
+ readonly previewUrl: string;
390
+ }
391
+ /** A durable image attached to a sent message. */
392
+ export interface QaImageView {
393
+ readonly attachmentId: string;
394
+ readonly mediaType: QaImageMediaType;
395
+ }
396
+ /** A subagent transcript opened read-only from the agents panel. */
397
+ export interface QaSubagentView {
398
+ readonly id: string;
399
+ readonly title: string;
400
+ }
106
401
  export interface QaSessionState {
107
402
  readonly phase: QaSessionPhase;
108
403
  readonly sessionId: string | null;
@@ -110,5 +405,13 @@ export interface QaSessionState {
110
405
  readonly error: string | null;
111
406
  readonly canSend: boolean;
112
407
  readonly canStop: boolean;
408
+ /** Bumped whenever this browser's chat index changes (add/forget). */
409
+ readonly chatsRevision: number;
410
+ /** Tool-derived sources of the current chat (web targets and files read). */
411
+ readonly sources: readonly QaSource[];
412
+ readonly sourcesComplete: boolean;
413
+ readonly incompleteSourceOrigins: QaTurnSources["incompleteOrigins"];
414
+ /** Set while the bound session is a subagent watched from the panel. */
415
+ readonly viewingSubagent: QaSubagentView | null;
113
416
  }
114
417
  //# sourceMappingURL=types.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yadsh/dsh-qa-surface",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "A focused end-user QA surface backed by native DeepSeek Harness sessions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,6 +14,9 @@
14
14
  "type": "module",
15
15
  "main": "./lib/index.js",
16
16
  "types": "./lib/types/index.d.ts",
17
+ "bin": {
18
+ "qa-accounts": "./lib/cli.js"
19
+ },
17
20
  "exports": {
18
21
  ".": {
19
22
  "types": "./lib/types/index.d.ts",
@@ -23,6 +26,14 @@
23
26
  "types": "./lib/types/client/index.d.ts",
24
27
  "default": "./lib/client.js"
25
28
  },
29
+ "./remote": {
30
+ "types": "./lib/typert.remote-client.d.ts",
31
+ "default": "./lib/typert.remote-client.js"
32
+ },
33
+ "./typert": {
34
+ "types": "./lib/typert.host.d.ts",
35
+ "default": "./lib/typert.host.js"
36
+ },
26
37
  "./types": {
27
38
  "types": "./lib/types/types.d.ts",
28
39
  "default": "./lib/types.js"
@@ -39,8 +50,9 @@
39
50
  ],
40
51
  "inject": [
41
52
  "@deepseek-ai/dsh-api-gateway",
53
+ "@deepseek-ai/dsh-api-session-controller",
54
+ "@deepseek-ai/dsh-agent-presets",
42
55
  "@deepseek-ai/dsh-client-connection",
43
- "@deepseek-ai/dsh-client-runtime",
44
56
  "@deepseek-ai/dsh-client-ui-layout",
45
57
  "@deepseek-ai/dsh-client-ui-settings",
46
58
  "@deepseek-ai/dsh-client-ui-theme"
@@ -51,9 +63,10 @@
51
63
  "files": [
52
64
  "lib/**/*.js",
53
65
  "lib/**/*.js.map",
54
- "lib/types/**/*.d.ts",
66
+ "lib/**/*.d.ts",
55
67
  "cordis.patch.yml",
56
68
  "compatibility.json",
69
+ "capability-policy.json",
57
70
  "README.md",
58
71
  "CHANGELOG.md",
59
72
  "docs/*.md",
@@ -74,45 +87,75 @@
74
87
  "node": "^22.19.0 || >=24.0.0"
75
88
  },
76
89
  "peerDependencies": {
77
- "@deepseek-ai/cordis": "^4.0.1",
78
- "@deepseek-ai/schemastery": "^3.18.1",
79
- "@deepseek-ai/dsh-api-gateway": ">=0.1.1-rc.2 <0.2.0",
80
- "@deepseek-ai/dsh-client-connection": ">=0.1.1-rc.2 <0.2.0",
81
- "@deepseek-ai/dsh-client-runtime": ">=0.1.1-rc.2 <0.2.0",
82
- "@deepseek-ai/dsh-client-ui-layout": ">=0.1.1-rc.2 <0.2.0",
83
- "@deepseek-ai/dsh-client-ui-settings": ">=0.1.1-rc.2 <0.2.0",
84
- "@deepseek-ai/dsh-client-ui-slots": ">=0.1.1-rc.2 <0.2.0",
85
- "@deepseek-ai/dsh-client-ui-theme": ">=0.1.1-rc.2 <0.2.0",
86
- "@deepseek-ai/dsh-host-webserver": ">=0.1.1-rc.2 <0.2.0",
87
- "@deepseek-ai/dsh-settings": ">=0.1.1-rc.2 <0.2.0",
88
- "react": "^18.2.0"
90
+ "@deepseek-ai/cordis": "^4.0.2",
91
+ "@deepseek-ai/schemastery": "^3.18.2",
92
+ "@deepseek-ai/dsh-api-gateway": ">=0.1.5-rc.2 <0.2.0",
93
+ "@deepseek-ai/dsh-agent": ">=0.1.5-rc.2 <0.2.0",
94
+ "@deepseek-ai/dsh-agent-presets": ">=0.1.5-rc.2 <0.2.0",
95
+ "@deepseek-ai/dsh-api-session-controller": ">=0.1.5-rc.2 <0.2.0",
96
+ "@deepseek-ai/dsh-api-workspace-controller": ">=0.1.5-rc.2 <0.2.0",
97
+ "@deepseek-ai/dsh-client-connection": ">=0.1.5-rc.2 <0.2.0",
98
+ "@deepseek-ai/dsh-client-ui-conversation": ">=0.1.5-rc.2 <0.2.0",
99
+ "@deepseek-ai/dsh-client-ui-chat": ">=0.1.5-rc.2 <0.2.0",
100
+ "@deepseek-ai/dsh-client-ui-layout": ">=0.1.5-rc.2 <0.2.0",
101
+ "@deepseek-ai/dsh-client-ui-renderer": ">=0.1.5-rc.2 <0.2.0",
102
+ "@deepseek-ai/dsh-client-ui-settings": ">=0.1.5-rc.2 <0.2.0",
103
+ "@deepseek-ai/dsh-client-ui-slots": ">=0.1.5-rc.2 <0.2.0",
104
+ "@deepseek-ai/dsh-client-ui-theme": ">=0.1.5-rc.2 <0.2.0",
105
+ "@deepseek-ai/dsh-host-webserver": ">=0.1.5-rc.2 <0.2.0",
106
+ "@deepseek-ai/dsh-permission-presets": ">=0.1.5-rc.2 <0.2.0",
107
+ "@deepseek-ai/dsh-session": ">=0.1.5-rc.2 <0.2.0",
108
+ "@deepseek-ai/dsh-settings": ">=0.1.5-rc.2 <0.2.0",
109
+ "@deepseek-ai/dsh-system-prompt": ">=0.1.5-rc.2 <0.2.0",
110
+ "@deepseek-ai/dsh-tools": ">=0.1.5-rc.2 <0.2.0",
111
+ "@deepseek-ai/dsh-typert-protocol": ">=0.1.5-rc.2 <0.2.0",
112
+ "@deepseek-ai/dsh-workspace": ">=0.1.5-rc.2 <0.2.0",
113
+ "react": "^18.2.0",
114
+ "react-dom": "^18.2.0"
89
115
  },
90
116
  "dependencies": {
117
+ "zod": "^4.4.3",
91
118
  "@yadsh/dsh-plugin-log": "^0.2.1"
92
119
  },
93
120
  "devDependencies": {
94
- "@deepseek-ai/cordis": "4.0.1",
95
- "@deepseek-ai/schemastery": "3.18.1",
96
- "@deepseek-ai/dsh-api-gateway": "0.1.1-rc.2",
97
- "@deepseek-ai/dsh-client-connection": "0.1.1-rc.2",
98
- "@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
99
- "@deepseek-ai/dsh-client-ui-layout": "0.1.1-rc.2",
100
- "@deepseek-ai/dsh-client-ui-settings": "0.1.1-rc.2",
101
- "@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
102
- "@deepseek-ai/dsh-client-ui-theme": "0.1.1-rc.2",
103
- "@deepseek-ai/dsh-host-webserver": "0.1.1-rc.2",
104
- "@deepseek-ai/dsh-settings": "0.1.1-rc.2",
121
+ "@deepseek-ai/cordis": "4.0.2",
122
+ "@deepseek-ai/schemastery": "3.18.2",
123
+ "@deepseek-ai/dsh-api-gateway": "0.1.5-rc.2",
124
+ "@deepseek-ai/dsh-agent": "0.1.5-rc.2",
125
+ "@deepseek-ai/dsh-agent-presets": "0.1.5-rc.2",
126
+ "@deepseek-ai/dsh-api-session-controller": "0.1.5-rc.2",
127
+ "@deepseek-ai/dsh-api-workspace-controller": "0.1.5-rc.2",
128
+ "@deepseek-ai/dsh-client-connection": "0.1.5-rc.2",
129
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.2",
130
+ "@deepseek-ai/dsh-client-ui-chat": "0.1.5-rc.2",
131
+ "@deepseek-ai/dsh-client-ui-layout": "0.1.5-rc.2",
132
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.2",
133
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.2",
134
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.2",
135
+ "@deepseek-ai/dsh-client-ui-theme": "0.1.5-rc.2",
136
+ "@deepseek-ai/dsh-host-webserver": "0.1.5-rc.2",
137
+ "@deepseek-ai/dsh-permission-presets": "0.1.5-rc.2",
138
+ "@deepseek-ai/dsh-session": "0.1.5-rc.2",
139
+ "@deepseek-ai/dsh-settings": "0.1.5-rc.2",
140
+ "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.2",
141
+ "@deepseek-ai/dsh-tools": "0.1.5-rc.2",
142
+ "@deepseek-ai/dsh-typert-generator": "0.1.5-rc.2",
143
+ "@deepseek-ai/dsh-typert-protocol": "0.1.5-rc.2",
144
+ "@deepseek-ai/dsh-workspace": "0.1.5-rc.2",
105
145
  "@testing-library/react": "^16.3.0",
106
146
  "@types/node": "^26.4.0",
107
147
  "@types/react": "18.3.28",
148
+ "@types/react-dom": "18.3.7",
108
149
  "eslint": "10.9.1",
109
150
  "jsdom": "^26.1.0",
110
151
  "playwright": "1.62.1",
111
152
  "prettier": "^3.6.2",
112
153
  "react": "18.3.1",
154
+ "react-dom": "18.3.1",
113
155
  "tsdown": "^0.22.14",
114
156
  "typescript": "^7.0.2",
115
157
  "vitest": "^4.1.11",
158
+ "@yadsh/dsh-plugin-scripts": "^0.0.0",
116
159
  "@yadsh/dsh-config": "^0.0.0"
117
160
  },
118
161
  "publishConfig": {
@@ -121,7 +164,7 @@
121
164
  },
122
165
  "scripts": {
123
166
  "clean": "node -e \"require('node:fs').rmSync('lib', { recursive: true, force: true })\"",
124
- "build": "pnpm run clean && tsdown && tsc -p tsconfig.build.json",
167
+ "build": "pnpm run lint && pnpm run clean && node scripts/generate-typert.mjs && tsc -p tsconfig.build.json && tsdown",
125
168
  "lint": "eslint src tests scripts tsdown.config.ts",
126
169
  "format": "prettier --check . --end-of-line auto",
127
170
  "format:write": "prettier --write . --end-of-line auto",