@yadsh/dsh-qa-surface 0.16.0 → 0.18.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 (325) hide show
  1. package/README.md +34 -5
  2. package/compatibility.json +1 -1
  3. package/lib/account-remotes.js +13 -0
  4. package/lib/account-remotes.js.map +1 -1
  5. package/lib/accounts/database.js +120 -4
  6. package/lib/accounts/database.js.map +1 -1
  7. package/lib/accounts/file.js.map +1 -1
  8. package/lib/accounts/store.js +131 -5
  9. package/lib/accounts/store.js.map +1 -1
  10. package/lib/accounts/token.js +8 -2
  11. package/lib/accounts/token.js.map +1 -1
  12. package/lib/admin/metrics.js +15 -2
  13. package/lib/admin/metrics.js.map +1 -1
  14. package/lib/admin/read-budget.js +28 -0
  15. package/lib/admin/read-budget.js.map +1 -0
  16. package/lib/admin/service.js +135 -40
  17. package/lib/admin/service.js.map +1 -1
  18. package/lib/admin/session-log.js +63 -4
  19. package/lib/admin/session-log.js.map +1 -1
  20. package/lib/chat-sharing/native-fence.js +31 -2
  21. package/lib/chat-sharing/native-fence.js.map +1 -1
  22. package/lib/chat-sharing/store.js +9 -3
  23. package/lib/chat-sharing/store.js.map +1 -1
  24. package/lib/chat-sharing/transport.js +74 -13
  25. package/lib/chat-sharing/transport.js.map +1 -1
  26. package/lib/chat-sharing/uploads.js +79 -6
  27. package/lib/chat-sharing/uploads.js.map +1 -1
  28. package/lib/cli.js +13 -0
  29. package/lib/cli.js.map +1 -1
  30. package/lib/client/QaAccountsController.js +79 -0
  31. package/lib/client/QaAccountsController.js.map +1 -1
  32. package/lib/client/QaRouteController.js +3 -1
  33. package/lib/client/QaRouteController.js.map +1 -1
  34. package/lib/client/QaSessionController.js +102 -29
  35. package/lib/client/QaSessionController.js.map +1 -1
  36. package/lib/client/QaSurface.js +89 -19
  37. package/lib/client/QaSurface.js.map +1 -1
  38. package/lib/client/QaTranscriptAdapter.js +15 -2
  39. package/lib/client/QaTranscriptAdapter.js.map +1 -1
  40. package/lib/client/account-sessions.js +74 -8
  41. package/lib/client/account-sessions.js.map +1 -1
  42. package/lib/client/admin/CapabilityPicker.js +50 -0
  43. package/lib/client/admin/CapabilityPicker.js.map +1 -0
  44. package/lib/client/admin/CoverageNotice.js +9 -0
  45. package/lib/client/admin/CoverageNotice.js.map +1 -0
  46. package/lib/client/admin/QaAdmin.js +3 -150
  47. package/lib/client/admin/QaAdmin.js.map +1 -1
  48. package/lib/client/admin/RoleEditor.js +46 -0
  49. package/lib/client/admin/RoleEditor.js.map +1 -0
  50. package/lib/client/admin/capability-selection.js +63 -0
  51. package/lib/client/admin/capability-selection.js.map +1 -0
  52. package/lib/client/admin/pages/Conversations.js +35 -17
  53. package/lib/client/admin/pages/Conversations.js.map +1 -1
  54. package/lib/client/admin/pages/Overview.js +3 -2
  55. package/lib/client/admin/pages/Overview.js.map +1 -1
  56. package/lib/client/admin/pages/Quality.js +77 -20
  57. package/lib/client/admin/pages/Quality.js.map +1 -1
  58. package/lib/client/admin/pages/SkillFiles.js +14 -3
  59. package/lib/client/admin/pages/SkillFiles.js.map +1 -1
  60. package/lib/client/admin/shared.js +68 -3
  61. package/lib/client/admin/shared.js.map +1 -1
  62. package/lib/client/answer-review.js +89 -0
  63. package/lib/client/answer-review.js.map +1 -0
  64. package/lib/client/chat-artifacts.js +1 -0
  65. package/lib/client/chat-artifacts.js.map +1 -1
  66. package/lib/client/components/QaAnswerReviewStatus.js +45 -0
  67. package/lib/client/components/QaAnswerReviewStatus.js.map +1 -0
  68. package/lib/client/components/QaAuthGate.js +31 -28
  69. package/lib/client/components/QaAuthGate.js.map +1 -1
  70. package/lib/client/components/QaChangelog.js +79 -0
  71. package/lib/client/components/QaChangelog.js.map +1 -1
  72. package/lib/client/components/QaChatActions.js +52 -0
  73. package/lib/client/components/QaChatActions.js.map +1 -0
  74. package/lib/client/components/QaChatSharing.js +22 -19
  75. package/lib/client/components/QaChatSharing.js.map +1 -1
  76. package/lib/client/components/QaComposer.js +27 -4
  77. package/lib/client/components/QaComposer.js.map +1 -1
  78. package/lib/client/components/QaFormItem.js +63 -0
  79. package/lib/client/components/QaFormItem.js.map +1 -0
  80. package/lib/client/components/QaInputForm.js +281 -0
  81. package/lib/client/components/QaInputForm.js.map +1 -0
  82. package/lib/client/components/QaMarkdownPreview.js +86 -0
  83. package/lib/client/components/QaMarkdownPreview.js.map +1 -0
  84. package/lib/client/components/QaMessage.js +8 -2
  85. package/lib/client/components/QaMessage.js.map +1 -1
  86. package/lib/client/components/QaModal.js +34 -4
  87. package/lib/client/components/QaModal.js.map +1 -1
  88. package/lib/client/components/QaRightRail.js +6 -4
  89. package/lib/client/components/QaRightRail.js.map +1 -1
  90. package/lib/client/components/QaRightRailResize.js +129 -0
  91. package/lib/client/components/QaRightRailResize.js.map +1 -0
  92. package/lib/client/components/QaSidebar.js +10 -1
  93. package/lib/client/components/QaSidebar.js.map +1 -1
  94. package/lib/client/components/QaSourceFilters.js +22 -0
  95. package/lib/client/components/QaSourceFilters.js.map +1 -0
  96. package/lib/client/components/QaSourcesPanel.js +57 -13
  97. package/lib/client/components/QaSourcesPanel.js.map +1 -1
  98. package/lib/client/components/QaSpreadsheetPreview.js +56 -0
  99. package/lib/client/components/QaSpreadsheetPreview.js.map +1 -0
  100. package/lib/client/components/QaWelcomeNotice.js +2 -2
  101. package/lib/client/components/QaWelcomeNotice.js.map +1 -1
  102. package/lib/client/components/QaWorkspaceBrowser.js +22 -9
  103. package/lib/client/components/QaWorkspaceBrowser.js.map +1 -1
  104. package/lib/client/components/QaZoomImage.js +56 -0
  105. package/lib/client/components/QaZoomImage.js.map +1 -0
  106. package/lib/client/components/source-refs.js +18 -4
  107. package/lib/client/components/source-refs.js.map +1 -1
  108. package/lib/client/forms-styles.js +14 -0
  109. package/lib/client/forms-styles.js.map +1 -0
  110. package/lib/client/forms.js +40 -0
  111. package/lib/client/forms.js.map +1 -0
  112. package/lib/client/index.js +31 -3
  113. package/lib/client/index.js.map +1 -1
  114. package/lib/client/markdown/SourceImage.js +52 -0
  115. package/lib/client/markdown/SourceImage.js.map +1 -0
  116. package/lib/client/markdown/blocks.js +150 -115
  117. package/lib/client/markdown/blocks.js.map +1 -1
  118. package/lib/client/markdown/render.js +23 -5
  119. package/lib/client/markdown/render.js.map +1 -1
  120. package/lib/client/markdown/source-chip.js +2 -1
  121. package/lib/client/markdown/source-chip.js.map +1 -1
  122. package/lib/client/oidc-browser.js +39 -0
  123. package/lib/client/oidc-browser.js.map +1 -0
  124. package/lib/client/panels/PanelHost.js +23 -1
  125. package/lib/client/panels/PanelHost.js.map +1 -1
  126. package/lib/client/settings/sections/interface.js +2 -1
  127. package/lib/client/settings/sections/interface.js.map +1 -1
  128. package/lib/client/settings/sections/sources.js +1 -1
  129. package/lib/client/settings/sections/sources.js.map +1 -1
  130. package/lib/client/settings/sections/status.js +3 -1
  131. package/lib/client/settings/sections/status.js.map +1 -1
  132. package/lib/client/settings/styles.js +18 -28
  133. package/lib/client/settings/styles.js.map +1 -1
  134. package/lib/client/source-filters-styles.js +11 -0
  135. package/lib/client/source-filters-styles.js.map +1 -0
  136. package/lib/client/styles.js +56 -5
  137. package/lib/client/styles.js.map +1 -1
  138. package/lib/client/types.js.map +1 -1
  139. package/lib/client/use-right-rail.js +1 -1
  140. package/lib/client/use-right-rail.js.map +1 -1
  141. package/lib/client/user-settings/IntegrationTokensPage.js +30 -6
  142. package/lib/client/user-settings/IntegrationTokensPage.js.map +1 -1
  143. package/lib/client.js +540 -71128
  144. package/lib/client.js.map +1 -1
  145. package/lib/config-resolvers/accounts.js +5 -4
  146. package/lib/config-resolvers/accounts.js.map +1 -1
  147. package/lib/config-resolvers/defaults.js +20 -3
  148. package/lib/config-resolvers/defaults.js.map +1 -1
  149. package/lib/config-resolvers/oidc.js +53 -0
  150. package/lib/config-resolvers/oidc.js.map +1 -0
  151. package/lib/config-resolvers/sources.js +2 -0
  152. package/lib/config-resolvers/sources.js.map +1 -1
  153. package/lib/config.js +74 -0
  154. package/lib/config.js.map +1 -1
  155. package/lib/forms/attachments.js +214 -0
  156. package/lib/forms/attachments.js.map +1 -0
  157. package/lib/forms/errors.js +37 -0
  158. package/lib/forms/errors.js.map +1 -0
  159. package/lib/forms/fingerprint.js +21 -0
  160. package/lib/forms/fingerprint.js.map +1 -0
  161. package/lib/forms/gate.js +125 -0
  162. package/lib/forms/gate.js.map +1 -0
  163. package/lib/forms/schema.js +182 -0
  164. package/lib/forms/schema.js.map +1 -0
  165. package/lib/forms/service.js +220 -0
  166. package/lib/forms/service.js.map +1 -0
  167. package/lib/forms/store.js +194 -0
  168. package/lib/forms/store.js.map +1 -0
  169. package/lib/forms/types.js +2 -0
  170. package/lib/forms/types.js.map +1 -0
  171. package/lib/forms/validation.js +113 -0
  172. package/lib/forms/validation.js.map +1 -0
  173. package/lib/index.js +276 -5
  174. package/lib/index.js.map +1 -1
  175. package/lib/integration/host-runner.js +1 -0
  176. package/lib/integration/host-runner.js.map +1 -1
  177. package/lib/integration/question-policy.js +126 -0
  178. package/lib/integration/question-policy.js.map +1 -0
  179. package/lib/integration/service.js +2 -0
  180. package/lib/integration/service.js.map +1 -1
  181. package/lib/llm-identity.js +27 -0
  182. package/lib/llm-identity.js.map +1 -0
  183. package/lib/markdown-frontmatter.js +47 -0
  184. package/lib/markdown-frontmatter.js.map +1 -0
  185. package/lib/markdown-images.js +33 -0
  186. package/lib/markdown-images.js.map +1 -0
  187. package/lib/oidc/http.js +30 -0
  188. package/lib/oidc/http.js.map +1 -0
  189. package/lib/oidc/service.js +250 -0
  190. package/lib/oidc/service.js.map +1 -0
  191. package/lib/prompt-notes.js +1 -1
  192. package/lib/prompt-notes.js.map +1 -1
  193. package/lib/provenance/collector.js +2 -0
  194. package/lib/provenance/collector.js.map +1 -1
  195. package/lib/provenance/connectors.js +25 -19
  196. package/lib/provenance/connectors.js.map +1 -1
  197. package/lib/provenance/dedupe.js +17 -0
  198. package/lib/provenance/dedupe.js.map +1 -1
  199. package/lib/provenance/document-preview.js +12 -2
  200. package/lib/provenance/document-preview.js.map +1 -1
  201. package/lib/provenance/extractors.js +23 -5
  202. package/lib/provenance/extractors.js.map +1 -1
  203. package/lib/provenance/file-preview.js +9 -2
  204. package/lib/provenance/file-preview.js.map +1 -1
  205. package/lib/provenance/integration-extractor.js +5 -6
  206. package/lib/provenance/integration-extractor.js.map +1 -1
  207. package/lib/provenance/snapshot-store.js +2 -0
  208. package/lib/provenance/snapshot-store.js.map +1 -1
  209. package/lib/provenance/source-content.js +103 -0
  210. package/lib/provenance/source-content.js.map +1 -0
  211. package/lib/provenance/source-image.js +57 -0
  212. package/lib/provenance/source-image.js.map +1 -0
  213. package/lib/provenance/spreadsheet-preview.js +52 -0
  214. package/lib/provenance/spreadsheet-preview.js.map +1 -0
  215. package/lib/qa-tools/activation-manager.js +24 -2
  216. package/lib/qa-tools/activation-manager.js.map +1 -1
  217. package/lib/qa-tools/catalog.js +11 -1
  218. package/lib/qa-tools/catalog.js.map +1 -1
  219. package/lib/qa-tools/index.js +27 -0
  220. package/lib/qa-tools/index.js.map +1 -1
  221. package/lib/qa-tools/request-user-form.js +121 -0
  222. package/lib/qa-tools/request-user-form.js.map +1 -0
  223. package/lib/questions.js +6 -1
  224. package/lib/questions.js.map +1 -1
  225. package/lib/resolve-config.js +2 -0
  226. package/lib/resolve-config.js.map +1 -1
  227. package/lib/secure-session.js +14 -8
  228. package/lib/secure-session.js.map +1 -1
  229. package/lib/shared/documents.js +12 -0
  230. package/lib/shared/documents.js.map +1 -1
  231. package/lib/typert.host.js +5136 -1341
  232. package/lib/typert.remote-client.d.ts +141 -7
  233. package/lib/typert.remote-client.js +5896 -2255
  234. package/lib/types/account-remotes.d.ts +3 -0
  235. package/lib/types/accounts/database.d.ts +13 -0
  236. package/lib/types/accounts/file.d.ts +2 -0
  237. package/lib/types/accounts/store.d.ts +23 -1
  238. package/lib/types/accounts/token.d.ts +3 -1
  239. package/lib/types/admin/metrics.d.ts +5 -1
  240. package/lib/types/admin/read-budget.d.ts +8 -0
  241. package/lib/types/admin/service.d.ts +17 -0
  242. package/lib/types/admin/session-log.d.ts +30 -1
  243. package/lib/types/answer-review.js +2 -0
  244. package/lib/types/answer-review.js.map +1 -0
  245. package/lib/types/chat-sharing/store.d.ts +1 -0
  246. package/lib/types/chat-sharing/transport.d.ts +1 -0
  247. package/lib/types/chat-sharing/uploads.d.ts +2 -1
  248. package/lib/types/client/QaAccountsController.d.ts +5 -0
  249. package/lib/types/client/QaRouteController.d.ts +1 -0
  250. package/lib/types/client/QaSessionController.d.ts +12 -3
  251. package/lib/types/client/QaSurface.d.ts +2 -0
  252. package/lib/types/client/admin/CapabilityPicker.d.ts +14 -0
  253. package/lib/types/client/admin/CoverageNotice.d.ts +6 -0
  254. package/lib/types/client/admin/RoleEditor.d.ts +15 -0
  255. package/lib/types/client/admin/capability-selection.d.ts +27 -0
  256. package/lib/types/client/admin/shared.d.ts +39 -1
  257. package/lib/types/client/answer-review.d.ts +16 -0
  258. package/lib/types/client/components/QaAnswerReviewStatus.d.ts +8 -0
  259. package/lib/types/client/components/QaAuthGate.d.ts +2 -0
  260. package/lib/types/client/components/QaChatActions.d.ts +7 -0
  261. package/lib/types/client/components/QaChatSharing.d.ts +4 -2
  262. package/lib/types/client/components/QaFormItem.d.ts +20 -0
  263. package/lib/types/client/components/QaInputForm.d.ts +18 -0
  264. package/lib/types/client/components/QaMarkdownPreview.d.ts +13 -0
  265. package/lib/types/client/components/QaModal.d.ts +9 -0
  266. package/lib/types/client/components/QaRightRail.d.ts +3 -2
  267. package/lib/types/client/components/QaRightRailResize.d.ts +9 -0
  268. package/lib/types/client/components/QaSidebar.d.ts +2 -0
  269. package/lib/types/client/components/QaSourceFilters.d.ts +12 -0
  270. package/lib/types/client/components/QaSpreadsheetPreview.d.ts +8 -0
  271. package/lib/types/client/components/QaWelcomeNotice.d.ts +1 -1
  272. package/lib/types/client/components/QaZoomImage.d.ts +38 -0
  273. package/lib/types/client/forms-styles.d.ts +2 -0
  274. package/lib/types/client/forms.d.ts +23 -0
  275. package/lib/types/client/markdown/SourceImage.d.ts +7 -0
  276. package/lib/types/client/markdown/blocks.d.ts +8 -1
  277. package/lib/types/client/markdown/render.d.ts +5 -1
  278. package/lib/types/client/markdown/source-chip.d.ts +1 -0
  279. package/lib/types/client/oidc-browser.d.ts +12 -0
  280. package/lib/types/client/settings/styles.d.ts +2 -5
  281. package/lib/types/client/source-filters-styles.d.ts +2 -0
  282. package/lib/types/client/types.d.ts +18 -6
  283. package/lib/types/config-resolvers/oidc.d.ts +3 -0
  284. package/lib/types/forms/attachments.d.ts +48 -0
  285. package/lib/types/forms/errors.d.ts +11 -0
  286. package/lib/types/forms/fingerprint.d.ts +9 -0
  287. package/lib/types/forms/gate.d.ts +33 -0
  288. package/lib/types/forms/schema.d.ts +72 -0
  289. package/lib/types/forms/service.d.ts +15 -0
  290. package/lib/types/forms/store.d.ts +25 -0
  291. package/lib/types/forms/types.d.ts +215 -0
  292. package/lib/types/forms/validation.d.ts +20 -0
  293. package/lib/types/index.d.ts +36 -3
  294. package/lib/types/integration/contract.d.ts +1 -0
  295. package/lib/types/integration/question-policy.d.ts +20 -0
  296. package/lib/types/integration/service.d.ts +1 -0
  297. package/lib/types/llm-identity.d.ts +20 -0
  298. package/lib/types/markdown-frontmatter.d.ts +10 -0
  299. package/lib/types/markdown-images.d.ts +3 -0
  300. package/lib/types/oidc/http.d.ts +5 -0
  301. package/lib/types/oidc/service.d.ts +30 -0
  302. package/lib/types/oidc.js +2 -0
  303. package/lib/types/oidc.js.map +1 -0
  304. package/lib/types/prompt-notes.d.ts +1 -1
  305. package/lib/types/provenance/document-preview.d.ts +3 -2
  306. package/lib/types/provenance/file-preview.d.ts +2 -1
  307. package/lib/types/provenance/source-content.d.ts +19 -0
  308. package/lib/types/provenance/source-image.d.ts +4 -0
  309. package/lib/types/provenance/spreadsheet-preview.d.ts +5 -0
  310. package/lib/types/provenance/types.d.ts +3 -0
  311. package/lib/types/qa-tools/activation-manager.d.ts +5 -0
  312. package/lib/types/qa-tools/catalog.d.ts +4 -1
  313. package/lib/types/qa-tools/index.d.ts +5 -1
  314. package/lib/types/qa-tools/request-user-form.d.ts +5 -0
  315. package/lib/types/questions.d.ts +2 -1
  316. package/lib/types/secure-session.d.ts +1 -0
  317. package/lib/types/shared/documents.d.ts +2 -0
  318. package/lib/types/types/accounts.d.ts +7 -1
  319. package/lib/types/types/admin.d.ts +6 -0
  320. package/lib/types/types/answer-review.d.ts +11 -0
  321. package/lib/types/types/config.d.ts +9 -0
  322. package/lib/types/types/oidc.d.ts +36 -0
  323. package/lib/types/types/session.d.ts +18 -3
  324. package/lib/types/types.d.ts +3 -0
  325. package/package.json +58 -56
@@ -81,6 +81,9 @@ export interface QaAccountRemotes {
81
81
  revokeServiceToken(token: string, tokenId: string): {
82
82
  readonly revoked: boolean;
83
83
  };
84
+ setServiceTokenClarifications(token: string, tokenId: string, allowed: boolean): {
85
+ readonly updated: boolean;
86
+ };
84
87
  }
85
88
  /** Build the account-remotes context for one `QaSurface` service instance. */
86
89
  export declare function createQaAccountRemotes(options: {
@@ -13,6 +13,7 @@ interface PasswordResetRow {
13
13
  * nowhere else.
14
14
  */
15
15
  export interface StoredServiceToken {
16
+ readonly allowClarifications: boolean;
16
17
  readonly id: string;
17
18
  readonly userId: string;
18
19
  readonly label: string;
@@ -73,6 +74,14 @@ export declare class QaAccountsDatabase {
73
74
  insertUser(user: StoredUser): void;
74
75
  /** Replace one account's row in place. */
75
76
  updateUser(user: StoredUser): void;
77
+ oidcUserId(issuer: string, subject: string): string | undefined;
78
+ isOidcUser(userId: string): boolean;
79
+ /** Account creation and identity attachment must commit together. */
80
+ attachOidcIdentity(issuer: string, subject: string, user: StoredUser, create: boolean): void;
81
+ /** Re-read and update authentication facts under the same write transaction. */
82
+ authenticateOidc(userId: string, email: string, displayName: string, role: StoredUser["role"], sid: string, expiresAt: number): StoredUser | undefined;
83
+ oidcSessionActive(id: string, userId: string): boolean;
84
+ revokeOidcSession(id: string): void;
76
85
  /**
77
86
  * Record one forgotten-password request. A repeat from the same account
78
87
  * moves the row up the queue and counts up, so the console shows "asked
@@ -95,6 +104,10 @@ export declare class QaAccountsDatabase {
95
104
  deleteOwnership(sessionIds: readonly string[]): void;
96
105
  /** Record one freshly minted integration token (digest only, never a secret). */
97
106
  insertServiceToken(token: StoredServiceToken): void;
107
+ /** Store the authenticated token policy before admitting its request to the inbox. */
108
+ recordIntegrationRequestPolicy(sessionId: string, requestId: string, allowed: boolean): void;
109
+ integrationClarificationsAllowed(sessionId: string, requestId: string): boolean;
110
+ setServiceTokenClarifications(userId: string, tokenId: string, allowed: boolean): boolean;
98
111
  /**
99
112
  * One integration token by id, revoked and expired ones included.
100
113
  *
@@ -25,6 +25,8 @@ export interface StoredNotifications {
25
25
  desktop?: boolean;
26
26
  }
27
27
  export interface StoredUser {
28
+ /** Derived from the identity table when the database is loaded. */
29
+ readonly authMethod?: "oidc";
28
30
  readonly id: string;
29
31
  readonly email: string;
30
32
  readonly displayName: string;
@@ -6,6 +6,8 @@ export type { QaAccountsErrorReason } from "./errors.js";
6
6
  export { defaultAccountsFilePath } from "./file.js";
7
7
  export type { QaIssuedServiceToken, QaServiceTokenSummary } from "../types.js";
8
8
  export interface QaAccountsOptions {
9
+ readonly oidcEnabled?: boolean;
10
+ readonly localLogin?: boolean;
9
11
  readonly sessionTtlDays: number;
10
12
  readonly allowRegistration: boolean;
11
13
  /** Login/registration attempts accepted per rolling minute, store-wide. */
@@ -41,8 +43,9 @@ export interface QaSessionFacts {
41
43
  export interface QaServiceTokenIssueInput {
42
44
  /** A note for the operator's token list; empty becomes a generic label. */
43
45
  readonly label?: string;
44
- /** Requested scopes; unknown ones are dropped, empty falls back to `ask`. */
46
+ /** Requested scopes; unknown ones are dropped, explicit empty grants none. */
45
47
  readonly scopes?: readonly string[];
48
+ readonly allowClarifications?: boolean;
46
49
  /** How long the token lives; bounded, and the session TTL when omitted. */
47
50
  readonly ttlDays?: number;
48
51
  /**
@@ -54,6 +57,7 @@ export interface QaServiceTokenIssueInput {
54
57
  }
55
58
  /** What a presented integration token resolved to. */
56
59
  export interface QaVerifiedServiceToken {
60
+ readonly allowClarifications: boolean;
57
61
  readonly tokenId: string;
58
62
  readonly userId: string;
59
63
  readonly scopes: readonly QaServiceTokenScope[];
@@ -83,6 +87,8 @@ export declare class QaAccounts {
83
87
  private readonly maxAuthAttemptsPerMinute;
84
88
  private readonly sessionTtlDays;
85
89
  private readonly allowRegistration;
90
+ private readonly oidcEnabled;
91
+ private readonly localLogin;
86
92
  /** Character cap on a stored profile's agent guidance. */
87
93
  private readonly instructionsMaxLength;
88
94
  /** Whether a deployment declares which identity handles an account may hold. */
@@ -124,6 +130,19 @@ export declare class QaAccounts {
124
130
  /** Resolve a token to its user, or null for absent/invalid/expired ones. */
125
131
  verifyToken(token: string): string | null;
126
132
  private mintToken;
133
+ /** Only the server OIDC verifier calls this with authenticated claims. */
134
+ loginOidc(identity: {
135
+ issuer: string;
136
+ subject: string;
137
+ email: string;
138
+ displayName: string;
139
+ role: QaAccountRole;
140
+ expiresAt: number;
141
+ autoProvision: boolean;
142
+ }): QaAccountSession;
143
+ /** Operator-confirmed attachment preserves ownership and revokes old credentials. */
144
+ linkOidcIdentity(email: string, issuer: string, subject: string): QaAccountUserPublic;
145
+ logoutOidc(token: string): boolean;
127
146
  /**
128
147
  * The account behind a token, or an auth-required refusal.
129
148
  *
@@ -421,6 +440,9 @@ export declare class QaAccounts {
421
440
  * @returns true when a live token was revoked.
422
441
  */
423
442
  revokeServiceToken(token: string, tokenId: string): boolean;
443
+ recordIntegrationRequestPolicy(sessionId: string, requestId: string, allowed: boolean): void;
444
+ setServiceTokenClarifications(token: string, tokenId: string, allowed: boolean): boolean;
445
+ integrationClarificationsAllowed(sessionId: string, requestId: string): boolean;
424
446
  /** Revoke one integration token of an account the caller has established. */
425
447
  revokeServiceTokenFor(user: QaAccountUserPublic, tokenId: string): boolean;
426
448
  /** The caller if it administers the deployment, or a refusal. */
@@ -5,6 +5,8 @@ interface TokenUser {
5
5
  }
6
6
  /** The claims carried by a v1 account token payload. */
7
7
  export interface TokenPayload {
8
+ /** OIDC-backed QA session; checked against the account database on every use. */
9
+ readonly sid?: string;
8
10
  readonly uid: string;
9
11
  /** Expiry, epoch milliseconds. */
10
12
  readonly exp: number;
@@ -26,6 +28,6 @@ export declare function mintToken(secret: string, payload: TokenPayload): string
26
28
  * timingSafeEqual) so a signature guess cannot be accelerated by measuring
27
29
  * HMAC rejection time.
28
30
  */
29
- export declare function verifyToken(secret: string, token: string, users: readonly TokenUser[]): string | null;
31
+ export declare function verifyToken(secret: string, token: string, users: readonly TokenUser[], sessionActive?: (id: string, userId: string) => boolean): string | null;
30
32
  export {};
31
33
  //# sourceMappingURL=token.d.ts.map
@@ -13,6 +13,8 @@ export interface QaConversationFact {
13
13
  readonly userId: string;
14
14
  readonly subroleId: string;
15
15
  readonly assistantMessages: number;
16
+ readonly readable?: boolean;
17
+ readonly assistantMessageIds?: readonly string[];
16
18
  /** Epoch ms of the conversation's creation, for the activity window. */
17
19
  readonly createdAt: number;
18
20
  }
@@ -22,8 +24,10 @@ export interface QaAggregationInput {
22
24
  readonly reviews: readonly QaConversationReview[];
23
25
  /** Days of feedback history the trend shows; older buckets are dropped. */
24
26
  readonly trendDays?: number;
27
+ /** False when the request could not read every conversation in its population. */
28
+ readonly complete?: boolean;
25
29
  }
26
- export declare function aggregateQuality({ conversations, feedback, reviews, trendDays, }: QaAggregationInput): QaQualityMetrics;
30
+ export declare function aggregateQuality({ conversations, feedback, reviews, trendDays, complete, }: QaAggregationInput): QaQualityMetrics;
27
31
  /** One rating's contribution to a conversation row, without re-reading logs. */
28
32
  export declare function countRatings(feedback: readonly QaMessageFeedback[]): Readonly<Record<QaFeedbackRating, number>>;
29
33
  //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1,8 @@
1
+ /** One deadline shared by every storage phase of an administrative request. */
2
+ export interface QaReadBudget {
3
+ remaining(): number;
4
+ read<T>(work: () => Promise<T>, fallback: T): Promise<T>;
5
+ }
6
+ export declare const QA_ADMIN_REQUEST_BUDGET_MS = 15000;
7
+ export declare function readBudget(now: () => number, ms?: number): QaReadBudget;
8
+ //# sourceMappingURL=read-budget.d.ts.map
@@ -24,6 +24,18 @@ export declare const QA_ADMIN_PAGE_MAX = 100;
24
24
  * says so; moving these counters onto a real index is the next iteration.
25
25
  */
26
26
  export declare const QA_ADMIN_SCAN_LIMIT = 200;
27
+ /**
28
+ * How long one page may spend reading conversation logs before it answers with
29
+ * what it already has. The newest logs are read until this budget is spent; the
30
+ * rest of the rows are marked unread instead of the page waiting for a store
31
+ * that may never answer. Without this,
32
+ * one conversation whose log cannot be read — a blank chat its process holds
33
+ * open is the usual case on a stand — parked the page for as long as the
34
+ * deployment runs.
35
+ */
36
+ export declare const QA_ADMIN_PAGE_BUDGET_MS = 10000;
37
+ /** The same budget for the aggregate window the overview and metrics read. */
38
+ export declare const QA_ADMIN_SCAN_BUDGET_MS = 10000;
27
39
  interface QaServiceClock {
28
40
  now(): number;
29
41
  }
@@ -101,6 +113,7 @@ export declare class QaAdminService {
101
113
  * reads the log — and what the aggregate pages show instead is the newest
102
114
  * projection of every finished conversation, which is the cheaper lie.
103
115
  */
116
+ private now;
104
117
  private transcript;
105
118
  /** Insert or re-touch one projection, keeping the cache inside its budget. */
106
119
  private retain;
@@ -121,6 +134,10 @@ export declare class QaAdminService {
121
134
  * up between two reads once every caller has left, so a reviewer who abandons a
122
135
  * page that has not answered does not keep the deployment reading logs for an
123
136
  * answer nobody will see.
137
+ *
138
+ * `within` is the pass's read budget. A log the budget no longer covers is not
139
+ * opened: the conversation keeps its row and is marked unread. Metrics then
140
+ * disclose the incomplete population instead of treating it as zero answers.
124
141
  */
125
142
  private walk;
126
143
  overview(token: string, signal?: AbortSignal): Promise<QaAdminOverview>;
@@ -36,7 +36,27 @@ export type QaSessionReadResult = {
36
36
  } | {
37
37
  readonly ok: false;
38
38
  readonly reason: QaTranscriptUnavailableReason;
39
+ /**
40
+ * True when the answer is "storage did not answer in time" rather than a
41
+ * verdict about the log. A caller that scans many logs skips such a
42
+ * conversation and keeps the rest of its rows; the wire reason stays one
43
+ * of the shared three, so no page learns a new word.
44
+ */
45
+ readonly timedOut?: boolean;
39
46
  };
47
+ /**
48
+ * How long one stored log may take before the console stops waiting for it.
49
+ *
50
+ * The durable backend answers a read by listing every session the deployment
51
+ * keeps and replaying the log; a log whose owning process is mid-flush — a
52
+ * blank chat created and left open is the usual case on a stand — can hold that
53
+ * answer indefinitely. The console is a reading surface, so a conversation it
54
+ * cannot read in this budget is reported and skipped rather than allowed to
55
+ * park the whole page.
56
+ */
57
+ export declare const QA_SESSION_READ_TIMEOUT_MS = 5000;
58
+ /** The same budget for the one listing every administrative page needs. */
59
+ export declare const QA_SESSION_LIST_TIMEOUT_MS = 8000;
40
60
  /**
41
61
  * One listing of the deployment's sessions together with what the answer
42
62
  * covers. The distinction is load-bearing: on a deployment that serves no
@@ -111,8 +131,17 @@ export interface QaStoredSessionEraser {
111
131
  * Build the reader for one plugin instance. The services are looked up per
112
132
  * call rather than captured: a cordis provider is only visible once its fiber
113
133
  * is active, and a reference taken at construction time would stay dead.
134
+ *
135
+ * Every call that reaches storage is bounded. The bounded answer is a shape the
136
+ * callers already understand — a listing that answers only for the live store,
137
+ * a log that is "storage-unavailable" — so a store that never replies costs a
138
+ * page its detail instead of its whole payload. The budgets are options only so
139
+ * a test can watch the transition without waiting five seconds for it.
114
140
  */
115
- export declare function createSessionLogReader(ctx: Context): QaSessionLogReader;
141
+ export declare function createSessionLogReader(ctx: Context, options?: {
142
+ readonly readTimeoutMs?: number;
143
+ readonly listTimeoutMs?: number;
144
+ }): QaSessionLogReader;
116
145
  /** A reader over an explicit set of logs; the tests' seam, and the empty default. */
117
146
  export declare function staticSessionLogReader(input: {
118
147
  readonly sessions?: readonly QaStoredSessionHeader[];
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=answer-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answer-review.js","sourceRoot":"","sources":["../../src/types/answer-review.ts"],"names":[],"mappings":""}
@@ -7,6 +7,7 @@ export declare class QaChatSharingStore {
7
7
  readonly storage: SqliteDatabase;
8
8
  constructor(filePath: string, accounts: () => QaAccounts);
9
9
  access(token: string, sessionId: string): QaChatAccess;
10
+ private accessForActor;
10
11
  owner(token: string, sessionId: string): QaChatAccess;
11
12
  write(token: string, sessionId: string): QaChatAccess;
12
13
  /** Exact address lookup after ownership, never an account directory. */
@@ -10,6 +10,7 @@ export declare class QaChatTransport {
10
10
  private readonly locks;
11
11
  constructor(ctx: Context, store: () => QaChatSharingStore, admit: (token: string, id: string) => Promise<unknown>, participantPolicy?: ((userId: string, id: string) => Promise<unknown>) | undefined);
12
12
  list(token: string, signal: AbortSignal): Promise<SessionListValue>;
13
+ private filterListing;
13
14
  page(token: string, request: SessionPageRequest, signal: AbortSignal): Promise<SessionPage>;
14
15
  search(token: string, request: SessionSearchRequest, signal: AbortSignal): Promise<SessionSearchValue>;
15
16
  projections(token: string, id: string, signal: AbortSignal): Promise<SessionProjectionsValue>;
@@ -1,5 +1,6 @@
1
1
  import type { Context } from "@deepseek-ai/cordis";
2
2
  import type { QaChatSharingStore } from "./store.js";
3
+ import type { QaFormAttachmentAdapter } from "../forms/attachments.js";
3
4
  /** Authenticate before transferring the body, and fence every uploaded chunk. */
4
- export declare function installQaChatUploads(ctx: Context, store: () => QaChatSharingStore, admit: (token: string, id: string) => Promise<unknown>): () => Promise<void>;
5
+ export declare function installQaChatUploads(ctx: Context, store: () => QaChatSharingStore, admit: (token: string, id: string) => Promise<unknown>, forms?: QaFormAttachmentAdapter): () => Promise<void>;
5
6
  //# sourceMappingURL=uploads.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import type { QaAccountNotificationsInput, QaAccountProfileInput, QaAccountStartersInput, QaAccountUserPublic, QaIssuedServiceToken, QaOwnershipEntry, QaServiceTokenCreateInput, QaServiceTokenSummary, ResolvedQaSurfaceConfig } from "../types.js";
2
+ import type { QaOidcBrowser } from "./oidc-browser.js";
2
3
  import type { QaAccountsApi, QaIntegrationTokenResult, StorageLike } from "./types.js";
3
4
  /**
4
5
  * What the sign-in card says after a forgotten-password request. It names the
@@ -49,6 +50,7 @@ export declare function accountsErrorMessage(code: string | null): string;
49
50
  /** Extract the coarse account reason code from a Host wire failure. */
50
51
  export declare function accountsReasonOf(failure: unknown): string | null;
51
52
  export interface QaAccountsControllerOptions {
53
+ readonly oidcBrowser?: QaOidcBrowser;
52
54
  readonly remote: QaAccountsApi;
53
55
  readonly storage: StorageLike | undefined;
54
56
  /** Config snapshot getter; the token key follows the deployment identity. */
@@ -79,6 +81,7 @@ export interface QaAccountsControllerOptions {
79
81
  */
80
82
  export declare class QaAccountsController {
81
83
  private readonly options;
84
+ private logoutGeneration;
82
85
  private readonly listeners;
83
86
  private snapshot;
84
87
  private tokenValue;
@@ -101,6 +104,7 @@ export declare class QaAccountsController {
101
104
  /** Boot probe: restore the stored token and ask the Host who it is. */
102
105
  start(): Promise<void>;
103
106
  login(email: string, password: string): Promise<void>;
107
+ loginOidc(): Promise<void>;
104
108
  register(email: string, password: string): Promise<void>;
105
109
  setMode(mode: "login" | "register" | "reset"): void;
106
110
  /**
@@ -181,6 +185,7 @@ export declare class QaAccountsController {
181
185
  * authority on whose token it is; a refusal is shown as it arrives.
182
186
  */
183
187
  revokeServiceToken(tokenId: string): Promise<QaIntegrationTokenResult<null>>;
188
+ setServiceTokenClarifications(tokenId: string, allowed: boolean): Promise<QaIntegrationTokenResult<null>>;
184
189
  private authenticate;
185
190
  /** Own the account, migrate the legacy index, replay held ratings, then auth. */
186
191
  private enterSession;
@@ -11,6 +11,7 @@ interface NavigationWindow {
11
11
  readonly location: {
12
12
  readonly pathname: string;
13
13
  readonly search?: string;
14
+ readonly hash?: string;
14
15
  };
15
16
  readonly history: NavigationHistory;
16
17
  addEventListener(type: "popstate", listener: () => void): void;
@@ -120,7 +120,10 @@ export declare class QaSessionController {
120
120
  private readonly unsubscribeConnection;
121
121
  private ensuring;
122
122
  private materializing;
123
+ /** A successful create survives a failed adoption; retry must not create again. */
124
+ private draftSessionId;
123
125
  private operationError;
126
+ private operationDiagnostic;
124
127
  private admissionPending;
125
128
  private pendingSubmission;
126
129
  private pendingSequence;
@@ -161,9 +164,9 @@ export declare class QaSessionController {
161
164
  * both a failed adoption and {@link unbind} take it back. The converse does
162
165
  * not hold: a held session may name nothing, which is the transcript of an
163
166
  * attestation this chat could not pass and whose caller still reads it. So a
164
- * chat whose first send fell short keeps its identity while naming no session,
165
- * and the retry — which brings a fresh id — stays in the composer the question
166
- * was typed into instead of reading as a move to another chat.
167
+ * chat whose first send fell short keeps its identity while naming no session;
168
+ * a retry adopts the successful create it already holds and preserves the
169
+ * composer the question was typed into.
167
170
  */
168
171
  private namedSession;
169
172
  /**
@@ -212,6 +215,12 @@ export declare class QaSessionController {
212
215
  getSnapshot: () => QaSessionState;
213
216
  subscribe: (listener: () => void) => (() => void);
214
217
  ensureSession(): Promise<void>;
218
+ /** Retry opening a failed draft without abandoning its successful create. */
219
+ retrySession(): Promise<void>;
220
+ failureDiagnostic(): {
221
+ readonly reason: string;
222
+ readonly id: string;
223
+ } | null;
215
224
  /**
216
225
  * Select a different capability profile for the next agent. The current
217
226
  * agent is never mutated: even a blank materialized chat is abandoned in
@@ -4,6 +4,7 @@ import type { QaConfigController } from "./QaConfigController.js";
4
4
  import type { QaRouteController } from "./QaRouteController.js";
5
5
  import type { QaAccountsController } from "./QaAccountsController.js";
6
6
  import type { QaApprovalApi, QaAccessApi, QaAdminApi, QaConversation, QaCreateSession, QaForkSession, QaFileUpload, QaQueueStatusRemote, QaSecureSession, QaSessions, QaSessionsApi, QaQuestionApi, QaSkillApi, QaSlashApi, QaSourceApi } from "./types.js";
7
+ import type { QaFormApi } from "./forms.js";
7
8
  import type { QaSurfacePanelRegistry } from "./panels/registry.js";
8
9
  import type { QaUserSettingsSections } from "./settings-extensions/index.js";
9
10
  import type { QaAuditController } from "./audit/controller.js";
@@ -40,6 +41,7 @@ export interface QaSurfaceFace {
40
41
  readonly approvalApi?: QaApprovalApi;
41
42
  /** Question half of the plugin's namespace, when the Host answers it. */
42
43
  readonly questionApi?: QaQuestionApi;
44
+ readonly formApi?: QaFormApi;
43
45
  /**
44
46
  * Slash half of the plugin's namespace. Absent on a Host build that predates
45
47
  * it: the composer then never opens a palette and ordinary prompts are
@@ -0,0 +1,14 @@
1
+ import type { QaCapabilityDescriptor, QaSkillAccess } from "../../types.js";
2
+ import type { CapabilityType } from "./capability-selection.js";
3
+ export declare function CapabilityPicker(props: {
4
+ readonly type: CapabilityType;
5
+ /** The zone this picker is mounted in, so its rows stay addressable. */
6
+ readonly testId?: string;
7
+ readonly catalog: readonly QaCapabilityDescriptor[];
8
+ readonly selected: readonly string[];
9
+ readonly inherited?: readonly string[];
10
+ readonly system?: readonly string[];
11
+ readonly skillDetails?: readonly QaSkillAccess[];
12
+ readonly onChange?: (next: readonly string[]) => void;
13
+ }): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=CapabilityPicker.d.ts.map
@@ -0,0 +1,6 @@
1
+ import type { QaQualityMetrics } from "../../types.js";
2
+ /** A missing journal cannot be presented as a conversation with no answers. */
3
+ export declare function CoverageNotice({ metrics, }: {
4
+ readonly metrics: QaQualityMetrics;
5
+ }): import("react/jsx-runtime").JSX.Element | null;
6
+ //# sourceMappingURL=CoverageNotice.d.ts.map
@@ -0,0 +1,15 @@
1
+ import type { QaCapabilityDescriptor, QaCapabilitySelection, QaSkillAccess, QaSubrole } from "../../types.js";
2
+ import type { QaAccessApi } from "../types.js";
3
+ export declare function RoleEditor(props: {
4
+ readonly role: QaSubrole | null;
5
+ readonly api: QaAccessApi;
6
+ readonly token: string;
7
+ readonly catalog: readonly QaCapabilityDescriptor[];
8
+ readonly common: QaCapabilitySelection;
9
+ readonly system: QaCapabilitySelection;
10
+ readonly skills: readonly QaSkillAccess[];
11
+ readonly subroles: readonly QaSubrole[];
12
+ readonly onCancel: () => void;
13
+ readonly onSave: (role: QaSubrole) => Promise<void>;
14
+ }): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=RoleEditor.d.ts.map
@@ -0,0 +1,27 @@
1
+ import type { QaCapabilitySelection, QaSkillAccess, QaSubrole } from "../../types.js";
2
+ export type CapabilityType = "tool" | "skill";
3
+ /**
4
+ * The three tool classes: visible immediately, reachable through a loaded
5
+ * skill, or withdrawn from the profile whatever grants them.
6
+ */
7
+ export type ToolBucket = "always" | "skillGrantable" | "deny";
8
+ export declare const TOOL_BUCKET_LABELS: Record<ToolBucket, string>;
9
+ export declare function unique(values: readonly string[]): string[];
10
+ export declare function bucketOf(selection: QaCapabilitySelection, bucket: ToolBucket): readonly string[];
11
+ export declare function emptySelection(): QaCapabilitySelection;
12
+ export declare function emptyRole(): QaSubrole;
13
+ /** Tools and skills one role would receive, and where each one comes from. */
14
+ export declare function roleEffective(props: {
15
+ readonly system: QaCapabilitySelection;
16
+ readonly common: QaCapabilitySelection;
17
+ readonly role: QaCapabilitySelection;
18
+ readonly skills: readonly QaSkillAccess[];
19
+ }, roleId: string): {
20
+ alwaysTools: string[];
21
+ grantable: string[];
22
+ denied: string[];
23
+ via: Map<string, string[]>;
24
+ managed: string[];
25
+ declared: string[];
26
+ };
27
+ //# sourceMappingURL=capability-selection.d.ts.map
@@ -19,6 +19,37 @@ export declare function useRequestSlot(): {
19
19
  readonly start: () => AbortController;
20
20
  readonly cancel: () => void;
21
21
  };
22
+ /**
23
+ * How long a page waits for one Host answer before it stops waiting.
24
+ *
25
+ * The aggregate pages read conversation logs on the Host, and a log the store
26
+ * cannot answer for used to leave the request pending forever: the page then sat
27
+ * on «Загружаю…» with nothing to click. The Host bounds its own reads well
28
+ * inside this budget, so hitting it means the answer is lost, not that the
29
+ * deployment is merely slow.
30
+ */
31
+ export declare const ADMIN_REQUEST_TIMEOUT_MS = 20000;
32
+ /** The copy a page shows once its deadline has passed. */
33
+ export declare function adminTimeoutMessage(timeoutMs?: number): string;
34
+ /** What one Host call did inside its deadline. */
35
+ export type BoundedOutcome<T> = {
36
+ readonly status: "ok";
37
+ readonly value: T;
38
+ } | {
39
+ readonly status: "timeout";
40
+ } | {
41
+ readonly status: "aborted";
42
+ };
43
+ /**
44
+ * Run one Host call under a deadline.
45
+ *
46
+ * A promise that never settles is the shape of the hang this exists for, so the
47
+ * deadline is a race rather than an abort alone: aborting the request is what
48
+ * asks the Host to stop working, and the timer is what lets the page go on
49
+ * without an answer. The abandoned call keeps running on its own; its eventual
50
+ * rejection is observed here so it never surfaces as an unhandled one.
51
+ */
52
+ export declare function callWithDeadline<T>(call: (signal: AbortSignal) => Promise<T>, outer: AbortSignal, timeoutMs?: number): Promise<BoundedOutcome<T>>;
22
53
  /**
23
54
  * Load one administrative resource, keeping the previous value visible while
24
55
  * it refreshes. Reviewers page through lists while new conversations arrive;
@@ -26,8 +57,15 @@ export declare function useRequestSlot(): {
26
57
  *
27
58
  * `load` receives the cancellation of the call it is making: pass it on to the
28
59
  * Remote, and a page the reviewer left stops being read on the server.
60
+ *
61
+ * The call is bounded by {@link ADMIN_REQUEST_TIMEOUT_MS}: a Host that does not
62
+ * answer leaves a stated error and a retry instead of an endless «Загружаю…».
63
+ * Whatever this page already held stays on screen — a partial answer is what a
64
+ * reviewer can still work with.
29
65
  */
30
- export declare function useAdminResource<T>(load: (signal: AbortSignal) => Promise<RemoteResult<T>>, deps: readonly unknown[]): {
66
+ export declare function useAdminResource<T>(load: (signal: AbortSignal) => Promise<RemoteResult<T>>, deps: readonly unknown[], options?: {
67
+ readonly timeoutMs?: number;
68
+ }): {
31
69
  readonly data: T | undefined;
32
70
  readonly error: string | undefined;
33
71
  readonly loading: boolean;
@@ -0,0 +1,16 @@
1
+ import type { SessionEventLike } from "@deepseek-ai/dsh-api-session-controller/client";
2
+ import type { ConversationNodeDefinition, ConversationSnapshot } from "@deepseek-ai/dsh-client-ui-conversation/client";
3
+ import type { QaAnswerReview } from "../types/answer-review.js";
4
+ export declare const QA_REVIEW_NODE = "qa-answer-review";
5
+ declare module "@deepseek-ai/dsh-client-ui-chat/client" {
6
+ interface ChatNodeDataMap {
7
+ "qa-answer-review": QaAnswerReview;
8
+ }
9
+ }
10
+ /** Read only the gate's producer metadata; answer prose never supplies a verdict. */
11
+ export declare function readAnswerReview(event: SessionEventLike): QaAnswerReview | null;
12
+ export declare function parseAnswerReview(receipt: unknown): QaAnswerReview | null;
13
+ /** One current result per human request, with the latest answer's anchor. */
14
+ export declare const answerReviewConversationDefinition: ConversationNodeDefinition<QaAnswerReview>;
15
+ export declare function answerReviewsOf(snapshot: ConversationSnapshot | undefined): ReadonlyMap<number, QaAnswerReview>;
16
+ //# sourceMappingURL=answer-review.d.ts.map
@@ -0,0 +1,8 @@
1
+ import type { PropsRuntime } from "@deepseek-ai/dsh-client-ui-slots";
2
+ import type { QaAnswerReview } from "../../types/answer-review.js";
3
+ export declare function QaAnswerReviewStatus({ review, }: {
4
+ readonly review: QaAnswerReview;
5
+ }): import("react/jsx-runtime").JSX.Element;
6
+ export declare function QaNativeAnswerReviewStatus({ node, }: PropsRuntime<"conversation.chat.node", "qa-answer-review">): import("react/jsx-runtime").JSX.Element;
7
+ export declare const QA_REVIEW_STYLES = "\n.dsh-qa-review-row{padding:4px 0 12px}\n.dsh-qa-review{display:inline-flex;align-items:center;gap:6px;max-width:100%;margin:8px 0 0;padding:4px 9px;border:1px solid var(--dsw-alias-border-l2);border-radius:999px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);font-size:12px;line-height:18px}\n.dsh-qa-review svg{width:14px;height:14px;flex:none;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}\n.dsh-qa-review[data-status=pass]{color:var(--dsw-alias-state-success-primary,var(--dsw-alias-label-primary))}\n";
8
+ //# sourceMappingURL=QaAnswerReviewStatus.d.ts.map
@@ -5,6 +5,8 @@ export interface QaAuthGateProps {
5
5
  readonly title: string;
6
6
  readonly logoUrl: string | null;
7
7
  readonly allowRegistration: boolean;
8
+ readonly localLogin?: boolean;
9
+ readonly oidcLabel?: string | null;
8
10
  }
9
11
  /**
10
12
  * The full-frame login/registration card shown instead of the chat while the
@@ -0,0 +1,7 @@
1
+ /** Quiet actions attached to one owned chat, outside the conversation header. */
2
+ export declare function QaChatActions(props: {
3
+ name: string;
4
+ onShare: () => void;
5
+ onDelete?: (trigger: HTMLButtonElement) => void;
6
+ }): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=QaChatActions.d.ts.map
@@ -5,6 +5,8 @@ export declare function QaChatSharing(props: {
5
5
  access: QaChatAccess;
6
6
  token: string;
7
7
  api: QaSharingApi;
8
- }): import("react/jsx-runtime").JSX.Element;
9
- export declare const QA_SHARING_STYLES = "\n.dsh-qa-sharing{padding:8px 20px;color:var(--dsw-alias-label-secondary);font-size:13px;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;gap:12px;align-items:center;flex-wrap:wrap}\n.dsh-qa-sharing__notice{margin:0;color:var(--dsw-alias-label-tertiary)}\n.dsh-qa-sharing>span{overflow-wrap:anywhere;min-width:0}\n.dsh-qa-sharing>button,.dsh-qa-sharing__body .dsh-qa-btn{appearance:none;cursor:pointer;min-height:40px;font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:8px 12px}\n.dsh-qa-sharing>button:hover,.dsh-qa-sharing__body .dsh-qa-btn:hover{background:var(--dsw-alias-bg-layer-3)}\n.dsh-qa-sharing>button:disabled,.dsh-qa-sharing__body .dsh-qa-btn:disabled{cursor:default;opacity:.55}\n.dsh-qa-sharing>button:focus-visible,.dsh-qa-sharing__body .dsh-qa-btn:focus-visible{outline:var(--dsw-focus-ring-width,2px) solid var(--dsw-focus-ring-color,var(--dsw-alias-brand-primary));outline-offset:2px}\n.dsh-qa-sharing__form{display:grid;gap:12px;margin:16px 0}\n.dsh-qa-sharing__body label{display:flex;flex-direction:column;gap:6px}\n.dsh-qa-sharing__body input,.dsh-qa-sharing__body select{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:8px;min-width:0;max-width:100%}\n.dsh-qa-sharing__people{list-style:none;padding:0;margin:16px 0}\n.dsh-qa-sharing__people li{display:flex;gap:10px;align-items:center;flex-wrap:wrap;padding:12px 0;border-top:1px solid var(--dsw-alias-border-l2)}\n.dsh-qa-sharing__people span{flex:1;min-width:140px;overflow-wrap:anywhere}\n.dsh-qa-sharing__people small{display:block;color:var(--dsw-alias-label-tertiary)}\n";
8
+ open: boolean;
9
+ onClose: () => void;
10
+ }): import("react/jsx-runtime").JSX.Element | null;
11
+ export declare const QA_SHARING_STYLES = "\n.dsh-qa-sharing__body{font-size:13px;color:var(--dsw-alias-label-secondary)}\n.dsh-qa-sharing__intro{margin:0 0 8px;line-height:1.5}\n.dsh-qa-sharing__details{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}\n.dsh-qa-sharing__details summary{cursor:pointer}\n.dsh-qa-sharing__body .dsh-qa-btn{appearance:none;cursor:pointer;min-height:36px;font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:7px 12px}\n.dsh-qa-sharing__body .dsh-qa-btn:hover{background:var(--dsw-alias-bg-layer-3)}\n.dsh-qa-sharing__body .dsh-qa-btn:disabled{cursor:default;opacity:.55}\n.dsh-qa-sharing__body .dsh-qa-btn:focus-visible{outline:var(--dsw-focus-ring-width,2px) solid var(--dsw-focus-ring-color,var(--dsw-alias-brand-primary));outline-offset:2px}\n.dsh-qa-sharing__form{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,160px);gap:12px;margin:20px 0}\n.dsh-qa-sharing__form>.dsh-qa-btn{grid-column:1/-1;justify-self:start}\n.dsh-qa-sharing__body label{display:flex;flex-direction:column;gap:6px}\n.dsh-qa-sharing__body input,.dsh-qa-sharing__body select{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:8px;min-width:0;max-width:100%}\n.dsh-qa-sharing__people{list-style:none;padding:0;margin:16px 0}\n.dsh-qa-sharing__people li{display:flex;gap:10px;align-items:center;flex-wrap:wrap;padding:12px 0;border-top:1px solid var(--dsw-alias-border-l2)}\n.dsh-qa-sharing__people span{flex:1;min-width:140px;overflow-wrap:anywhere}\n.dsh-qa-sharing__people small{display:block;color:var(--dsw-alias-label-tertiary)}\n@media(max-width:480px){.dsh-qa-sharing__form{grid-template-columns:minmax(0,1fr)}}\n";
10
12
  //# sourceMappingURL=QaChatSharing.d.ts.map
@@ -0,0 +1,20 @@
1
+ import type { QaFormAnswer, QaFormItem as Item, QaFormAttachment, QaFormUpload } from "../../forms/types.js";
2
+ interface Props {
3
+ item: Item;
4
+ answer: QaFormAnswer | null;
5
+ files: QaFormAttachment[];
6
+ uploads: QaFormUpload[];
7
+ disabled: boolean;
8
+ onAnswer(answer: QaFormAnswer | null): void;
9
+ onUpload(file: File, target?: {
10
+ attachment_id: string;
11
+ version: number;
12
+ }): void;
13
+ onRemove(file: QaFormAttachment): void;
14
+ onCancel(upload: QaFormUpload): void;
15
+ onOpen(file: QaFormAttachment): void;
16
+ }
17
+ /** Input requirements are separate from file requirements, including in the labels. */
18
+ export declare function QaFormItem(props: Props): import("react/jsx-runtime").JSX.Element;
19
+ export {};
20
+ //# sourceMappingURL=QaFormItem.d.ts.map
@@ -0,0 +1,18 @@
1
+ import type { QaFormView } from "../../forms/types.js";
2
+ import { type QaFormApi } from "../forms.js";
3
+ interface Props {
4
+ policy?: Readonly<import("../../forms/types.js").QaFormPolicy>;
5
+ api: QaFormApi;
6
+ session: string;
7
+ token: string;
8
+ form: QaFormView;
9
+ canStop: boolean;
10
+ onStop(): Promise<void>;
11
+ onResume(id: string): void;
12
+ onTakeover(active: boolean): void;
13
+ }
14
+ export declare function QaInputForm(props: Props): import("react/jsx-runtime").JSX.Element;
15
+ /** Session/identity-keyed parent discards account-local state and aborts transfers on switch. */
16
+ export declare function QaInputForms(props: Omit<Props, "form">): import("react/jsx-runtime").JSX.Element | null;
17
+ export {};
18
+ //# sourceMappingURL=QaInputForm.d.ts.map
@@ -0,0 +1,13 @@
1
+ import type { ReactNode } from "react";
2
+ import type { MarkdownFrontmatter } from "../../markdown-frontmatter.js";
3
+ /** Source-only rendering: original file line numbers survive frontmatter removal. */
4
+ export declare function QaMarkdownPreview({ text, renderFrontmatter, frontmatter, lineStart, lineEnd, renderImage, requestKey, }: {
5
+ readonly text: string;
6
+ readonly renderFrontmatter: boolean;
7
+ readonly frontmatter?: MarkdownFrontmatter;
8
+ readonly lineStart?: number;
9
+ readonly lineEnd?: number;
10
+ readonly renderImage?: (src: string, alt: string) => ReactNode;
11
+ readonly requestKey?: unknown;
12
+ }): import("react/jsx-runtime").JSX.Element;
13
+ //# sourceMappingURL=QaMarkdownPreview.d.ts.map