@yadsh/dsh-qa-surface 0.3.0 → 0.5.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 (276) hide show
  1. package/README.md +192 -15
  2. package/cordis.patch.yml +8 -0
  3. package/lib/account-remotes.js +100 -0
  4. package/lib/account-remotes.js.map +1 -0
  5. package/lib/accounts/credentials.js +35 -0
  6. package/lib/accounts/credentials.js.map +1 -0
  7. package/lib/accounts/errors.js +9 -0
  8. package/lib/accounts/errors.js.map +1 -0
  9. package/lib/accounts/file.js +101 -0
  10. package/lib/accounts/file.js.map +1 -0
  11. package/lib/accounts/store.js +159 -161
  12. package/lib/accounts/store.js.map +1 -1
  13. package/lib/accounts/token.js +61 -0
  14. package/lib/accounts/token.js.map +1 -0
  15. package/lib/approvals.js +179 -0
  16. package/lib/approvals.js.map +1 -0
  17. package/lib/attachment-rules.js +111 -0
  18. package/lib/attachment-rules.js.map +1 -0
  19. package/lib/cli.js +132 -9
  20. package/lib/cli.js.map +1 -1
  21. package/lib/client/QaAccountsController.js +32 -2
  22. package/lib/client/QaAccountsController.js.map +1 -1
  23. package/lib/client/QaSessionController.js +140 -65
  24. package/lib/client/QaSessionController.js.map +1 -1
  25. package/lib/client/QaSurface.js +134 -107
  26. package/lib/client/QaSurface.js.map +1 -1
  27. package/lib/client/QaTranscriptAdapter.js +71 -6
  28. package/lib/client/QaTranscriptAdapter.js.map +1 -1
  29. package/lib/client/approvals.js +104 -0
  30. package/lib/client/approvals.js.map +1 -0
  31. package/lib/client/attachments.js +150 -0
  32. package/lib/client/attachments.js.map +1 -0
  33. package/lib/client/attestation.js +4 -1
  34. package/lib/client/attestation.js.map +1 -1
  35. package/lib/client/base64.js +16 -0
  36. package/lib/client/base64.js.map +1 -0
  37. package/lib/client/chat-files.js +48 -0
  38. package/lib/client/chat-files.js.map +1 -0
  39. package/lib/client/components/Markdown.js +1 -1
  40. package/lib/client/components/Markdown.js.map +1 -1
  41. package/lib/client/components/QaApproval.js +23 -0
  42. package/lib/client/components/QaApproval.js.map +1 -0
  43. package/lib/client/components/QaChangelog.js +62 -19
  44. package/lib/client/components/QaChangelog.js.map +1 -1
  45. package/lib/client/components/QaComposer.js +56 -74
  46. package/lib/client/components/QaComposer.js.map +1 -1
  47. package/lib/client/components/QaFileAttachment.js +19 -0
  48. package/lib/client/components/QaFileAttachment.js.map +1 -0
  49. package/lib/client/components/QaFilesPanel.js +45 -0
  50. package/lib/client/components/QaFilesPanel.js.map +1 -0
  51. package/lib/client/components/QaHeader.js +34 -0
  52. package/lib/client/components/QaHeader.js.map +1 -0
  53. package/lib/client/components/QaMessage.js +17 -4
  54. package/lib/client/components/QaMessage.js.map +1 -1
  55. package/lib/client/components/QaModal.js +31 -0
  56. package/lib/client/components/QaModal.js.map +1 -0
  57. package/lib/client/components/QaProfile.js +64 -0
  58. package/lib/client/components/QaProfile.js.map +1 -0
  59. package/lib/client/components/QaQuestions.js +96 -0
  60. package/lib/client/components/QaQuestions.js.map +1 -0
  61. package/lib/client/components/QaRightRail.js +15 -0
  62. package/lib/client/components/QaRightRail.js.map +1 -0
  63. package/lib/client/components/QaSidebar.js +6 -1
  64. package/lib/client/components/QaSidebar.js.map +1 -1
  65. package/lib/client/components/{QaSourcesDrawer.js → QaSourcesPanel.js} +3 -3
  66. package/lib/client/components/QaSourcesPanel.js.map +1 -0
  67. package/lib/client/components/QaTurnRail.js +15 -0
  68. package/lib/client/components/QaTurnRail.js.map +1 -1
  69. package/lib/client/components/QaWidthHandle.js +25 -20
  70. package/lib/client/components/QaWidthHandle.js.map +1 -1
  71. package/lib/client/components/QaWorkGroup.js +19 -20
  72. package/lib/client/components/QaWorkGroup.js.map +1 -1
  73. package/lib/client/components/surface-utils.js +28 -0
  74. package/lib/client/components/surface-utils.js.map +1 -0
  75. package/lib/client/components/thinking-phrases.js +24 -0
  76. package/lib/client/components/thinking-phrases.js.map +1 -0
  77. package/lib/client/create-session.js +7 -32
  78. package/lib/client/create-session.js.map +1 -1
  79. package/lib/client/failure-copy.js +63 -0
  80. package/lib/client/failure-copy.js.map +1 -0
  81. package/lib/client/index.js +49 -7
  82. package/lib/client/index.js.map +1 -1
  83. package/lib/client/project-session-state.js +5 -3
  84. package/lib/client/project-session-state.js.map +1 -1
  85. package/lib/client/prompt-content.js +54 -0
  86. package/lib/client/prompt-content.js.map +1 -0
  87. package/lib/client/questions.js +114 -0
  88. package/lib/client/questions.js.map +1 -0
  89. package/lib/client/settings/card.js +143 -0
  90. package/lib/client/settings/card.js.map +1 -0
  91. package/lib/client/settings/fields.js +145 -0
  92. package/lib/client/settings/fields.js.map +1 -0
  93. package/lib/client/settings/format.js +255 -0
  94. package/lib/client/settings/format.js.map +1 -0
  95. package/lib/client/settings/sections/access.js +25 -0
  96. package/lib/client/settings/sections/access.js.map +1 -0
  97. package/lib/client/settings/sections/accounts.js +47 -0
  98. package/lib/client/settings/sections/accounts.js.map +1 -0
  99. package/lib/client/settings/sections/attachments.js +46 -0
  100. package/lib/client/settings/sections/attachments.js.map +1 -0
  101. package/lib/client/settings/sections/branding.js +28 -0
  102. package/lib/client/settings/sections/branding.js.map +1 -0
  103. package/lib/client/settings/sections/common.js +20 -0
  104. package/lib/client/settings/sections/common.js.map +1 -0
  105. package/lib/client/settings/sections/embedding.js +19 -0
  106. package/lib/client/settings/sections/embedding.js.map +1 -0
  107. package/lib/client/settings/sections/interface.js +60 -0
  108. package/lib/client/settings/sections/interface.js.map +1 -0
  109. package/lib/client/settings/sections/lockdown.js +82 -0
  110. package/lib/client/settings/sections/lockdown.js.map +1 -0
  111. package/lib/client/settings/sections/session.js +53 -0
  112. package/lib/client/settings/sections/session.js.map +1 -0
  113. package/lib/client/settings/sections/sources.js +74 -0
  114. package/lib/client/settings/sections/sources.js.map +1 -0
  115. package/lib/client/settings/sections/status.js +37 -0
  116. package/lib/client/settings/sections/status.js.map +1 -0
  117. package/lib/client/settings/sections.js +23 -0
  118. package/lib/client/settings/sections.js.map +1 -0
  119. package/lib/client/settings/styles.js +57 -0
  120. package/lib/client/settings/styles.js.map +1 -0
  121. package/lib/client/stream-publisher.js +47 -0
  122. package/lib/client/stream-publisher.js.map +1 -0
  123. package/lib/client/styles.js +127 -19
  124. package/lib/client/styles.js.map +1 -1
  125. package/lib/client/types.js +2 -0
  126. package/lib/client/types.js.map +1 -1
  127. package/lib/client/use-right-rail.js +96 -0
  128. package/lib/client/use-right-rail.js.map +1 -0
  129. package/lib/client/use-session-ui-state.js +26 -19
  130. package/lib/client/use-session-ui-state.js.map +1 -1
  131. package/lib/client.js +5694 -813
  132. package/lib/client.js.map +1 -1
  133. package/lib/config-resolvers/accounts.js +60 -0
  134. package/lib/config-resolvers/accounts.js.map +1 -0
  135. package/lib/config-resolvers/attachments.js +28 -0
  136. package/lib/config-resolvers/attachments.js.map +1 -0
  137. package/lib/config-resolvers/basics.js +61 -0
  138. package/lib/config-resolvers/basics.js.map +1 -0
  139. package/lib/config-resolvers/defaults.js +136 -0
  140. package/lib/config-resolvers/defaults.js.map +1 -0
  141. package/lib/config-resolvers/lockdown.js +90 -0
  142. package/lib/config-resolvers/lockdown.js.map +1 -0
  143. package/lib/config-resolvers/session.js +42 -0
  144. package/lib/config-resolvers/session.js.map +1 -0
  145. package/lib/config-resolvers/shared.js +51 -0
  146. package/lib/config-resolvers/shared.js.map +1 -0
  147. package/lib/config-resolvers/sources.js +83 -0
  148. package/lib/config-resolvers/sources.js.map +1 -0
  149. package/lib/config-resolvers/ui.js +20 -0
  150. package/lib/config-resolvers/ui.js.map +1 -0
  151. package/lib/config.js +76 -6
  152. package/lib/config.js.map +1 -1
  153. package/lib/entry-redirect.js +2 -1
  154. package/lib/entry-redirect.js.map +1 -1
  155. package/lib/index.js +198 -79
  156. package/lib/index.js.map +1 -1
  157. package/lib/profile.js +214 -0
  158. package/lib/profile.js.map +1 -0
  159. package/lib/prompt-notes.js +231 -0
  160. package/lib/prompt-notes.js.map +1 -0
  161. package/lib/provenance/host-store.js +25 -9
  162. package/lib/provenance/host-store.js.map +1 -1
  163. package/lib/provenance/reported.js +37 -12
  164. package/lib/provenance/reported.js.map +1 -1
  165. package/lib/questions.js +185 -0
  166. package/lib/questions.js.map +1 -0
  167. package/lib/resolve-config.js +35 -410
  168. package/lib/resolve-config.js.map +1 -1
  169. package/lib/secure-session.js +139 -21
  170. package/lib/secure-session.js.map +1 -1
  171. package/lib/session-ownership.js +55 -0
  172. package/lib/session-ownership.js.map +1 -0
  173. package/lib/shared/session-key.js +18 -0
  174. package/lib/shared/session-key.js.map +1 -0
  175. package/lib/shared/settings.js +10 -0
  176. package/lib/shared/settings.js.map +1 -0
  177. package/lib/thinking-phrases.js +68 -0
  178. package/lib/thinking-phrases.js.map +1 -0
  179. package/lib/typert.host.js +506 -21
  180. package/lib/typert.remote-client.d.ts +15 -1
  181. package/lib/typert.remote-client.js +407 -15
  182. package/lib/types/account-remotes.d.ts +42 -0
  183. package/lib/types/accounts/credentials.d.ts +20 -0
  184. package/lib/types/accounts/errors.d.ts +11 -0
  185. package/lib/types/accounts/file.d.ts +82 -0
  186. package/lib/types/accounts/store.d.ts +74 -43
  187. package/lib/types/accounts/token.d.ts +31 -0
  188. package/lib/types/approvals.d.ts +65 -0
  189. package/lib/types/attachment-rules.d.ts +44 -0
  190. package/lib/types/cli.d.ts +2 -2
  191. package/lib/types/client/QaAccountsController.d.ts +8 -1
  192. package/lib/types/client/QaSessionController.d.ts +53 -16
  193. package/lib/types/client/QaSurface.d.ts +14 -1
  194. package/lib/types/client/approvals.d.ts +39 -0
  195. package/lib/types/client/attachments.d.ts +54 -0
  196. package/lib/types/client/base64.d.ts +10 -0
  197. package/lib/types/client/chat-files.d.ts +30 -0
  198. package/lib/types/client/components/QaApproval.d.ts +13 -0
  199. package/lib/types/client/components/QaChangelog.d.ts +1 -1
  200. package/lib/types/client/components/QaComposer.d.ts +8 -4
  201. package/lib/types/client/components/QaFileAttachment.d.ts +14 -0
  202. package/lib/types/client/components/QaFilesPanel.d.ts +15 -0
  203. package/lib/types/client/components/QaHeader.d.ts +41 -0
  204. package/lib/types/client/components/QaMessage.d.ts +3 -1
  205. package/lib/types/client/components/QaModal.d.ts +26 -0
  206. package/lib/types/client/components/QaProfile.d.ts +25 -0
  207. package/lib/types/client/components/QaQuestions.d.ts +13 -0
  208. package/lib/types/client/components/QaRightRail.d.ts +23 -0
  209. package/lib/types/client/components/QaSidebar.d.ts +14 -0
  210. package/lib/types/client/components/{QaSourcesDrawer.d.ts → QaSourcesPanel.d.ts} +7 -4
  211. package/lib/types/client/components/QaTurnRail.d.ts +6 -0
  212. package/lib/types/client/components/QaWidthHandle.d.ts +14 -7
  213. package/lib/types/client/components/QaWorkGroup.d.ts +5 -3
  214. package/lib/types/client/components/surface-utils.d.ts +11 -0
  215. package/lib/types/client/components/thinking-phrases.d.ts +9 -0
  216. package/lib/types/client/create-session.d.ts +6 -9
  217. package/lib/types/client/failure-copy.d.ts +19 -0
  218. package/lib/types/client/project-session-state.d.ts +8 -1
  219. package/lib/types/client/prompt-content.d.ts +30 -0
  220. package/lib/types/client/questions.d.ts +45 -0
  221. package/lib/types/client/settings/card.d.ts +23 -0
  222. package/lib/types/client/settings/fields.d.ts +139 -0
  223. package/lib/types/client/settings/format.d.ts +108 -0
  224. package/lib/types/client/settings/sections/access.d.ts +9 -0
  225. package/lib/types/client/settings/sections/accounts.d.ts +9 -0
  226. package/lib/types/client/settings/sections/attachments.d.ts +15 -0
  227. package/lib/types/client/settings/sections/branding.d.ts +8 -0
  228. package/lib/types/client/settings/sections/common.d.ts +28 -0
  229. package/lib/types/client/settings/sections/embedding.d.ts +8 -0
  230. package/lib/types/client/settings/sections/interface.d.ts +9 -0
  231. package/lib/types/client/settings/sections/lockdown.d.ts +9 -0
  232. package/lib/types/client/settings/sections/session.d.ts +9 -0
  233. package/lib/types/client/settings/sections/sources.d.ts +9 -0
  234. package/lib/types/client/settings/sections/status.d.ts +22 -0
  235. package/lib/types/client/settings/sections.d.ts +25 -0
  236. package/lib/types/client/settings/styles.d.ts +8 -0
  237. package/lib/types/client/stream-publisher.d.ts +28 -0
  238. package/lib/types/client/types.d.ts +76 -1
  239. package/lib/types/client/use-right-rail.d.ts +56 -0
  240. package/lib/types/client/use-session-ui-state.d.ts +13 -7
  241. package/lib/types/config-resolvers/accounts.d.ts +15 -0
  242. package/lib/types/config-resolvers/attachments.d.ts +6 -0
  243. package/lib/types/config-resolvers/basics.d.ts +8 -0
  244. package/lib/types/config-resolvers/defaults.d.ts +4 -0
  245. package/lib/types/config-resolvers/lockdown.d.ts +10 -0
  246. package/lib/types/config-resolvers/session.d.ts +6 -0
  247. package/lib/types/config-resolvers/shared.d.ts +23 -0
  248. package/lib/types/config-resolvers/sources.d.ts +6 -0
  249. package/lib/types/config-resolvers/ui.d.ts +6 -0
  250. package/lib/types/index.d.ts +48 -15
  251. package/lib/types/profile.d.ts +76 -0
  252. package/lib/types/prompt-notes.d.ts +110 -0
  253. package/lib/types/provenance/reported.d.ts +9 -1
  254. package/lib/types/questions.d.ts +83 -0
  255. package/lib/types/resolve-config.d.ts +8 -3
  256. package/lib/types/secure-session.d.ts +46 -2
  257. package/lib/types/session-ownership.d.ts +30 -0
  258. package/lib/types/shared/session-key.d.ts +23 -0
  259. package/lib/types/shared/settings.d.ts +10 -0
  260. package/lib/types/thinking-phrases.d.ts +17 -0
  261. package/lib/types/types.d.ts +203 -9
  262. package/lib/types/user-workspace.d.ts +42 -0
  263. package/lib/user-workspace.js +246 -0
  264. package/lib/user-workspace.js.map +1 -0
  265. package/package.json +15 -8
  266. package/CHANGELOG.md +0 -176
  267. package/SPEC-dsh-qa-surface.md +0 -2425
  268. package/docs/ARCHITECTURE.md +0 -66
  269. package/docs/COMPATIBILITY.md +0 -14
  270. package/docs/CONFIGURATION.md +0 -199
  271. package/docs/EMBEDDING.md +0 -13
  272. package/docs/SOURCES-MIGRATION.md +0 -28
  273. package/docs/SOURCES-PROVENANCE-AUDIT.md +0 -88
  274. package/docs/SPEC-dsh-qa-surface-accounts.md +0 -219
  275. package/docs/SPEC-dsh-qa-surface-sources-provenance.md +0 -1692
  276. package/lib/client/components/QaSourcesDrawer.js.map +0 -1
@@ -0,0 +1,60 @@
1
+ import { QA_PROFILE_INSTRUCTIONS_MAX_MAX, QA_PROFILE_INSTRUCTIONS_MAX_MIN, validateIdentityFields, } from "../profile.js";
2
+ import { DEFAULT_QA_SURFACE_CONFIG } from "./defaults.js";
3
+ import { assertIntInRange } from "./shared.js";
4
+ /**
5
+ * Resolve the accounts domain. The per-user workspace boundary spans session
6
+ * and lockdown, so their resolved slices arrive as dependencies and the
7
+ * boundary checks run here, next to the flag they guard.
8
+ */
9
+ export function resolveAccounts(input, dependencies) {
10
+ const sessionTtlDays = input.accounts?.sessionTtlDays ??
11
+ DEFAULT_QA_SURFACE_CONFIG.accounts.sessionTtlDays;
12
+ assertIntInRange("accounts.sessionTtlDays", sessionTtlDays, 1, 365);
13
+ const accountsEnabled = input.accounts?.enabled ?? DEFAULT_QA_SURFACE_CONFIG.accounts.enabled;
14
+ const instructionsMaxLength = input.accounts?.profile?.instructionsMaxLength ??
15
+ DEFAULT_QA_SURFACE_CONFIG.accounts.profile.instructionsMaxLength;
16
+ assertIntInRange("accounts.profile.instructionsMaxLength", instructionsMaxLength, QA_PROFILE_INSTRUCTIONS_MAX_MIN, QA_PROFILE_INSTRUCTIONS_MAX_MAX);
17
+ const identityFields = validateIdentityFields(input.accounts?.profile?.identities);
18
+ if (!identityFields.ok) {
19
+ throw new TypeError(`dsh-qa-surface: accounts.profile.identities ${identityFields.message}`);
20
+ }
21
+ const perUserWorkspace = input.accounts?.perUserWorkspace ??
22
+ DEFAULT_QA_SURFACE_CONFIG.accounts.perUserWorkspace;
23
+ if (perUserWorkspace && !accountsEnabled) {
24
+ throw new TypeError("dsh-qa-surface: accounts.perUserWorkspace requires accounts.enabled");
25
+ }
26
+ const { session, lockdown } = dependencies;
27
+ if (perUserWorkspace && session.workspaceId === null) {
28
+ throw new TypeError("dsh-qa-surface: accounts.perUserWorkspace requires session.workspaceId");
29
+ }
30
+ if (perUserWorkspace && session.policy === "fixed") {
31
+ throw new TypeError("dsh-qa-surface: accounts.perUserWorkspace does not support fixed sessions");
32
+ }
33
+ if (perUserWorkspace &&
34
+ (!lockdown.enabled ||
35
+ !lockdown.enforceFixedWorkspace ||
36
+ lockdown.sandboxMode !== "workspace-write")) {
37
+ throw new TypeError("dsh-qa-surface: accounts.perUserWorkspace requires lockdown.enabled, enforceFixedWorkspace, and workspace-write");
38
+ }
39
+ if (lockdown.sandboxMode === "workspace-write" && !perUserWorkspace) {
40
+ throw new TypeError("dsh-qa-surface: workspace-write is allowed only with accounts.perUserWorkspace");
41
+ }
42
+ return Object.freeze({
43
+ enabled: accountsEnabled,
44
+ allowRegistration: input.accounts?.allowRegistration ??
45
+ DEFAULT_QA_SURFACE_CONFIG.accounts.allowRegistration,
46
+ sessionTtlDays,
47
+ showOtherUsersChats: input.accounts?.showOtherUsersChats ??
48
+ DEFAULT_QA_SURFACE_CONFIG.accounts.showOtherUsersChats,
49
+ perUserWorkspace,
50
+ profile: Object.freeze({
51
+ enabled: input.accounts?.profile?.enabled ??
52
+ DEFAULT_QA_SURFACE_CONFIG.accounts.profile.enabled,
53
+ inject: input.accounts?.profile?.inject ??
54
+ DEFAULT_QA_SURFACE_CONFIG.accounts.profile.inject,
55
+ identities: Object.freeze(identityFields.value.map((field) => Object.freeze({ ...field }))),
56
+ instructionsMaxLength,
57
+ }),
58
+ });
59
+ }
60
+ //# sourceMappingURL=accounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/config-resolvers/accounts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { QA_MAX_FILE_BYTES_MAX, QA_MAX_FILE_BYTES_MIN, QA_MAX_PENDING_MAX, QA_MAX_PENDING_MIN, QA_PASTED_TEXT_LINES_MAX, QA_PASTED_TEXT_LINES_MIN, normalizeTextExtensions, } from "../attachment-rules.js";
2
+ import { DEFAULT_QA_SURFACE_CONFIG } from "./defaults.js";
3
+ import { assertIntInRange } from "./shared.js";
4
+ /** Resolve the attachments domain: intake toggles and byte/line bounds. */
5
+ export function resolveAttachments(input) {
6
+ const pastedTextLines = input.attachments?.pastedTextLines ??
7
+ DEFAULT_QA_SURFACE_CONFIG.attachments.pastedTextLines;
8
+ const maxFileBytes = input.attachments?.maxFileBytes ??
9
+ DEFAULT_QA_SURFACE_CONFIG.attachments.maxFileBytes;
10
+ const maxPending = input.attachments?.maxPending ??
11
+ DEFAULT_QA_SURFACE_CONFIG.attachments.maxPending;
12
+ assertIntInRange("attachments.pastedTextLines", pastedTextLines, QA_PASTED_TEXT_LINES_MIN, QA_PASTED_TEXT_LINES_MAX);
13
+ assertIntInRange("attachments.maxFileBytes", maxFileBytes, QA_MAX_FILE_BYTES_MIN, QA_MAX_FILE_BYTES_MAX);
14
+ assertIntInRange("attachments.maxPending", maxPending, QA_MAX_PENDING_MIN, QA_MAX_PENDING_MAX);
15
+ return Object.freeze({
16
+ textFiles: input.attachments?.textFiles ??
17
+ DEFAULT_QA_SURFACE_CONFIG.attachments.textFiles,
18
+ pastedTextLines,
19
+ maxFileBytes,
20
+ maxPending,
21
+ // An operator names extensions; anything the browser reports as
22
+ // `text/*` still passes the composer's own check, so an empty list is a
23
+ // narrowing, not a lockout.
24
+ extensions: normalizeTextExtensions(input.attachments?.extensions ??
25
+ DEFAULT_QA_SURFACE_CONFIG.attachments.extensions),
26
+ });
27
+ }
28
+ //# sourceMappingURL=attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/config-resolvers/attachments.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/C,2EAA2E;AAC3E,MAAM,UAAU,kBAAkB,CAAC,KAAsB;IACvD,MAAM,eAAe,GACnB,KAAK,CAAC,WAAW,EAAE,eAAe;QAClC,yBAAyB,CAAC,WAAW,CAAC,eAAe,CAAC;IACxD,MAAM,YAAY,GAChB,KAAK,CAAC,WAAW,EAAE,YAAY;QAC/B,yBAAyB,CAAC,WAAW,CAAC,YAAY,CAAC;IACrD,MAAM,UAAU,GACd,KAAK,CAAC,WAAW,EAAE,UAAU;QAC7B,yBAAyB,CAAC,WAAW,CAAC,UAAU,CAAC;IACnD,gBAAgB,CACd,6BAA6B,EAC7B,eAAe,EACf,wBAAwB,EACxB,wBAAwB,CACzB,CAAC;IACF,gBAAgB,CACd,0BAA0B,EAC1B,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,CACtB,CAAC;IACF,gBAAgB,CACd,wBAAwB,EACxB,UAAU,EACV,kBAAkB,EAClB,kBAAkB,CACnB,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,SAAS,EACP,KAAK,CAAC,WAAW,EAAE,SAAS;YAC5B,yBAAyB,CAAC,WAAW,CAAC,SAAS;QACjD,eAAe;QACf,YAAY;QACZ,UAAU;QACV,gEAAgE;QAChE,wEAAwE;QACxE,4BAA4B;QAC5B,UAAU,EAAE,uBAAuB,CACjC,KAAK,CAAC,WAAW,EAAE,UAAU;YAC3B,yBAAyB,CAAC,WAAW,CAAC,UAAU,CACnD;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { DEFAULT_QA_SURFACE_CONFIG } from "./defaults.js";
2
+ import { optionalText } from "./shared.js";
3
+ export function normalizeRoutePath(value) {
4
+ const trimmed = value.trim();
5
+ if (trimmed === "" || !trimmed.startsWith("/")) {
6
+ throw new TypeError("dsh-qa-surface: route.path must start with /");
7
+ }
8
+ const path = trimmed.length > 1 ? trimmed.replace(/\/+$/u, "") : trimmed;
9
+ if (path === "/") {
10
+ throw new TypeError("dsh-qa-surface: route.path cannot replace the operator root");
11
+ }
12
+ if (path === "/api" || path.startsWith("/api/")) {
13
+ throw new TypeError("dsh-qa-surface: route.path cannot claim /api");
14
+ }
15
+ if (path === "/plugins" || path.startsWith("/plugins/")) {
16
+ throw new TypeError("dsh-qa-surface: route.path cannot claim /plugins");
17
+ }
18
+ return path;
19
+ }
20
+ /** Resolve the master switch, route, branding, embedding, and entry domains. */
21
+ export function resolveBasics(input) {
22
+ return {
23
+ enabled: input.enabled ?? DEFAULT_QA_SURFACE_CONFIG.enabled,
24
+ route: Object.freeze({
25
+ path: normalizeRoutePath(input.route?.path ?? DEFAULT_QA_SURFACE_CONFIG.route.path),
26
+ matchChildren: input.route?.matchChildren ??
27
+ DEFAULT_QA_SURFACE_CONFIG.route.matchChildren,
28
+ }),
29
+ branding: Object.freeze({
30
+ title: input.branding?.title?.trim() ||
31
+ DEFAULT_QA_SURFACE_CONFIG.branding.title,
32
+ subtitle: input.branding?.subtitle?.trim() ?? "",
33
+ welcomeMessage: input.branding?.welcomeMessage?.trim() ??
34
+ DEFAULT_QA_SURFACE_CONFIG.branding.welcomeMessage,
35
+ placeholder: input.branding?.placeholder?.trim() ||
36
+ DEFAULT_QA_SURFACE_CONFIG.branding.placeholder,
37
+ logoUrl: optionalText(input.branding?.logoUrl),
38
+ // Undefined falls back to the default notice; an explicit null or
39
+ // empty string hides the plate entirely.
40
+ disclaimer: input.branding?.disclaimer === undefined
41
+ ? DEFAULT_QA_SURFACE_CONFIG.branding.disclaimer
42
+ : (optionalText(input.branding.disclaimer) ?? ""),
43
+ }),
44
+ embedding: Object.freeze({
45
+ frameAncestors: optionalText(input.embedding?.frameAncestors),
46
+ }),
47
+ entry: Object.freeze({
48
+ redirectNonLoopback: input.entry?.redirectNonLoopback ??
49
+ DEFAULT_QA_SURFACE_CONFIG.entry.redirectNonLoopback,
50
+ cookieBootstrap: input.entry?.cookieBootstrap ??
51
+ DEFAULT_QA_SURFACE_CONFIG.entry.cookieBootstrap,
52
+ }),
53
+ interaction: Object.freeze({
54
+ approvals: input.interaction?.approvals ??
55
+ DEFAULT_QA_SURFACE_CONFIG.interaction.approvals,
56
+ questions: input.interaction?.questions ??
57
+ DEFAULT_QA_SURFACE_CONFIG.interaction.questions,
58
+ }),
59
+ };
60
+ }
61
+ //# sourceMappingURL=basics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basics.js","sourceRoot":"","sources":["../../src/config-resolvers/basics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,136 @@
1
+ import { DEFAULT_QA_TEXT_EXTENSIONS } from "../attachment-rules.js";
2
+ import { QA_PROFILE_DEFAULT_INSTRUCTIONS_MAX } from "../profile.js";
3
+ import { DEFAULT_THINKING_PHRASES } from "../thinking-phrases.js";
4
+ /** The canonical resolved config; every domain resolver defaults from it. */
5
+ export const DEFAULT_QA_SURFACE_CONFIG = Object.freeze({
6
+ enabled: true,
7
+ route: Object.freeze({ path: "/qa", matchChildren: true }),
8
+ branding: Object.freeze({
9
+ title: "Помощник",
10
+ subtitle: "",
11
+ welcomeMessage: "Чем могу помочь?",
12
+ placeholder: "Задайте вопрос…",
13
+ logoUrl: null,
14
+ disclaimer: "Диалоги могут быть видны другим пользователям сервера и используются для улучшения качества ответов.",
15
+ }),
16
+ session: Object.freeze({
17
+ policy: "browser-persistent",
18
+ storageKey: "dsh-qa-surface.session",
19
+ cwd: null,
20
+ workspaceId: null,
21
+ fixedSessionId: null,
22
+ agentPreset: null,
23
+ provider: null,
24
+ model: null,
25
+ reasoningEffort: null,
26
+ }),
27
+ ui: Object.freeze({
28
+ showHeader: true,
29
+ showReset: false,
30
+ showStop: true,
31
+ showTimestamps: false,
32
+ showToolActivity: false,
33
+ showReasoning: false,
34
+ renderMarkdown: true,
35
+ minContentWidth: 650,
36
+ showSessionList: false,
37
+ }),
38
+ suggestedQuestions: Object.freeze([
39
+ "Что ты умеешь?",
40
+ "С чего начать?",
41
+ "Помоги разобраться с ошибкой",
42
+ ]),
43
+ thinkingPhrases: DEFAULT_THINKING_PHRASES,
44
+ interaction: Object.freeze({
45
+ // Fail closed: a deployment that wants the operator to answer a composed
46
+ // tool gate's `ask` opts in with `interactive`.
47
+ approvals: "blocked",
48
+ questions: "unsupported",
49
+ }),
50
+ lockdown: Object.freeze({
51
+ enabled: true,
52
+ enforceFixedAgentPreset: true,
53
+ enforceFixedWorkspace: true,
54
+ enforceFixedModel: true,
55
+ sandboxMode: "read-only",
56
+ approvalPolicy: "never",
57
+ permissionPreset: "qa-read-only",
58
+ allowPermissionChanges: false,
59
+ allowSlashCommands: false,
60
+ allowSettingsMutation: false,
61
+ allowSessionReset: false,
62
+ allowSessionRename: false,
63
+ allowSessionDelete: false,
64
+ allowArbitrarySessionOpen: false,
65
+ toolPolicy: Object.freeze({
66
+ mode: "allow-list",
67
+ allow: Object.freeze([]),
68
+ }),
69
+ sharedReadOnlyRoots: Object.freeze([]),
70
+ }),
71
+ embedding: Object.freeze({ frameAncestors: null }),
72
+ accounts: Object.freeze({
73
+ enabled: false,
74
+ allowRegistration: true,
75
+ sessionTtlDays: 30,
76
+ showOtherUsersChats: false,
77
+ perUserWorkspace: false,
78
+ profile: Object.freeze({
79
+ enabled: true,
80
+ inject: true,
81
+ identities: Object.freeze([]),
82
+ instructionsMaxLength: QA_PROFILE_DEFAULT_INSTRUCTIONS_MAX,
83
+ }),
84
+ }),
85
+ entry: Object.freeze({
86
+ redirectNonLoopback: true,
87
+ cookieBootstrap: true,
88
+ }),
89
+ sources: Object.freeze({
90
+ enabled: true,
91
+ collect: Object.freeze({
92
+ parentAgent: true,
93
+ subagents: true,
94
+ persistTurnEvent: true,
95
+ }),
96
+ display: Object.freeze({
97
+ sidebar: true,
98
+ footer: true,
99
+ groupByKind: true,
100
+ showDiscovered: false,
101
+ showOriginBadges: false,
102
+ maxInitiallyVisiblePerGroup: 8,
103
+ }),
104
+ webSearch: Object.freeze({
105
+ promoteSearchResultsWithoutFetch: true,
106
+ maxPromotedPerSearch: 5,
107
+ }),
108
+ dedupe: Object.freeze({
109
+ normalizeUrls: true,
110
+ stripTrackingParams: true,
111
+ mergeFileRanges: true,
112
+ }),
113
+ filePreview: Object.freeze({
114
+ enabled: true,
115
+ markdownRenderedByDefault: true,
116
+ allowRawToggle: true,
117
+ maxBytes: 2_000_000,
118
+ maxMarkdownRenderBytes: 1_000_000,
119
+ }),
120
+ subagents: Object.freeze({
121
+ inheritSources: true,
122
+ enableReportToolFallback: true,
123
+ markIncompleteOpaqueRuns: true,
124
+ validateReportedSources: true,
125
+ }),
126
+ legacy: Object.freeze({ parseAssistantSourcesBlock: false }),
127
+ }),
128
+ attachments: Object.freeze({
129
+ textFiles: true,
130
+ pastedTextLines: 200,
131
+ maxFileBytes: 10_485_760,
132
+ maxPending: 8,
133
+ extensions: DEFAULT_QA_TEXT_EXTENSIONS,
134
+ }),
135
+ });
136
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config-resolvers/defaults.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import { DEFAULT_QA_SURFACE_CONFIG } from "./defaults.js";
2
+ import { isAbsoluteDirectoryPath } from "./shared.js";
3
+ /** Tool allow-list names are capped so they stay legible in host echoes. */
4
+ function uniqueToolNames(values) {
5
+ const names = [
6
+ ...new Set(values.map((value) => value.trim()).filter(Boolean)),
7
+ ];
8
+ if (names.some((value) => value.length > 200)) {
9
+ throw new TypeError("dsh-qa-surface: lockdown.toolPolicy.allow names must be at most 200 characters");
10
+ }
11
+ return Object.freeze(names);
12
+ }
13
+ function uniqueAbsoluteRoots(values) {
14
+ const roots = [
15
+ ...new Set(values.map((value) => value.trim()).filter(Boolean)),
16
+ ];
17
+ if (roots.some((value) => !isAbsoluteDirectoryPath(value))) {
18
+ throw new TypeError("dsh-qa-surface: lockdown.sharedReadOnlyRoots must contain only absolute paths");
19
+ }
20
+ return Object.freeze(roots);
21
+ }
22
+ /**
23
+ * Resolve the lockdown domain. The capability flags are clamped shut, and
24
+ * showing the reset control needs an explicit authorization here, so the
25
+ * resolved UI slice arrives as a neighbor.
26
+ */
27
+ export function resolveLockdown(input, ui) {
28
+ const lockdownEnabled = input.lockdown?.enabled ?? DEFAULT_QA_SURFACE_CONFIG.lockdown.enabled;
29
+ const rawLockdown = input.lockdown;
30
+ const forbiddenCapabilityFlags = [
31
+ ["allowPermissionChanges", rawLockdown?.allowPermissionChanges],
32
+ ["allowSlashCommands", rawLockdown?.allowSlashCommands],
33
+ ["allowSettingsMutation", rawLockdown?.allowSettingsMutation],
34
+ ["allowSessionRename", rawLockdown?.allowSessionRename],
35
+ ["allowSessionDelete", rawLockdown?.allowSessionDelete],
36
+ ["allowArbitrarySessionOpen", rawLockdown?.allowArbitrarySessionOpen],
37
+ ];
38
+ const weakenedFlag = forbiddenCapabilityFlags.find(([, value]) => value === true);
39
+ if (weakenedFlag !== undefined) {
40
+ throw new TypeError(`dsh-qa-surface: lockdown.${weakenedFlag[0]} cannot be enabled`);
41
+ }
42
+ const sandboxMode = input.lockdown?.sandboxMode ??
43
+ DEFAULT_QA_SURFACE_CONFIG.lockdown.sandboxMode;
44
+ if (sandboxMode !== "read-only" && sandboxMode !== "workspace-write") {
45
+ throw new TypeError("dsh-qa-surface: lockdown.sandboxMode must be read-only or workspace-write");
46
+ }
47
+ if (input.lockdown?.approvalPolicy !== undefined &&
48
+ input.lockdown.approvalPolicy !== "never") {
49
+ throw new TypeError("dsh-qa-surface: lockdown.approvalPolicy must be never");
50
+ }
51
+ if (input.lockdown?.toolPolicy?.mode !== undefined &&
52
+ input.lockdown.toolPolicy.mode !== "allow-list") {
53
+ throw new TypeError("dsh-qa-surface: lockdown.toolPolicy.mode must be allow-list");
54
+ }
55
+ const permissionPreset = input.lockdown?.permissionPreset?.trim() ??
56
+ DEFAULT_QA_SURFACE_CONFIG.lockdown.permissionPreset;
57
+ if (lockdownEnabled && permissionPreset === "") {
58
+ throw new TypeError("dsh-qa-surface: lockdown.permissionPreset is required when lockdown is enabled");
59
+ }
60
+ const allowSessionReset = input.lockdown?.allowSessionReset ??
61
+ DEFAULT_QA_SURFACE_CONFIG.lockdown.allowSessionReset;
62
+ if (lockdownEnabled && ui.showReset && !allowSessionReset) {
63
+ throw new TypeError("dsh-qa-surface: ui.showReset requires lockdown.allowSessionReset");
64
+ }
65
+ return Object.freeze({
66
+ enabled: lockdownEnabled,
67
+ enforceFixedAgentPreset: input.lockdown?.enforceFixedAgentPreset ??
68
+ DEFAULT_QA_SURFACE_CONFIG.lockdown.enforceFixedAgentPreset,
69
+ enforceFixedWorkspace: input.lockdown?.enforceFixedWorkspace ??
70
+ DEFAULT_QA_SURFACE_CONFIG.lockdown.enforceFixedWorkspace,
71
+ enforceFixedModel: input.lockdown?.enforceFixedModel ??
72
+ DEFAULT_QA_SURFACE_CONFIG.lockdown.enforceFixedModel,
73
+ sandboxMode,
74
+ approvalPolicy: "never",
75
+ permissionPreset,
76
+ allowPermissionChanges: false,
77
+ allowSlashCommands: false,
78
+ allowSettingsMutation: false,
79
+ allowSessionReset,
80
+ allowSessionRename: false,
81
+ allowSessionDelete: false,
82
+ allowArbitrarySessionOpen: false,
83
+ toolPolicy: Object.freeze({
84
+ mode: "allow-list",
85
+ allow: uniqueToolNames(input.lockdown?.toolPolicy?.allow ?? []),
86
+ }),
87
+ sharedReadOnlyRoots: uniqueAbsoluteRoots(input.lockdown?.sharedReadOnlyRoots ?? []),
88
+ });
89
+ }
90
+ //# sourceMappingURL=lockdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lockdown.js","sourceRoot":"","sources":["../../src/config-resolvers/lockdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { DEFAULT_QA_SURFACE_CONFIG } from "./defaults.js";
2
+ import { isAbsoluteDirectoryPath, optionalText } from "./shared.js";
3
+ /** Resolve the session domain: policy, pinning, and model selection. */
4
+ export function resolveSession(input) {
5
+ const policy = input.session?.policy ?? DEFAULT_QA_SURFACE_CONFIG.session.policy;
6
+ const fixedSessionId = optionalText(input.session?.fixedSessionId);
7
+ if (policy === "fixed" && fixedSessionId === null) {
8
+ throw new TypeError("dsh-qa-surface: session.fixedSessionId is required for fixed policy");
9
+ }
10
+ // The cwd pin is the no-registry alternative to workspaceId; both pin the
11
+ // session to one directory, so together they are a configuration error.
12
+ const cwd = optionalText(input.session?.cwd);
13
+ if (cwd !== null && !isAbsoluteDirectoryPath(cwd)) {
14
+ throw new TypeError("dsh-qa-surface: session.cwd must be an absolute directory path");
15
+ }
16
+ const workspaceId = optionalText(input.session?.workspaceId);
17
+ if (workspaceId !== null && cwd !== null) {
18
+ throw new TypeError("dsh-qa-surface: session.workspaceId and session.cwd are mutually exclusive");
19
+ }
20
+ const provider = optionalText(input.session?.provider);
21
+ const model = optionalText(input.session?.model);
22
+ if ((provider === null) !== (model === null)) {
23
+ throw new TypeError("dsh-qa-surface: session.provider and session.model must be set together");
24
+ }
25
+ const storageKey = input.session?.storageKey?.trim() ??
26
+ DEFAULT_QA_SURFACE_CONFIG.session.storageKey;
27
+ if (storageKey === "") {
28
+ throw new TypeError("dsh-qa-surface: session.storageKey cannot be empty");
29
+ }
30
+ return Object.freeze({
31
+ policy,
32
+ storageKey,
33
+ cwd,
34
+ workspaceId,
35
+ fixedSessionId,
36
+ agentPreset: optionalText(input.session?.agentPreset),
37
+ provider,
38
+ model,
39
+ reasoningEffort: optionalText(input.session?.reasoningEffort),
40
+ });
41
+ }
42
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/config-resolvers/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIpE,wEAAwE;AACxE,MAAM,UAAU,cAAc,CAAC,KAAsB;IACnD,MAAM,MAAM,GACV,KAAK,CAAC,OAAO,EAAE,MAAM,IAAI,yBAAyB,CAAC,OAAO,CAAC,MAAM,CAAC;IACpE,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACnE,IAAI,MAAM,KAAK,OAAO,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,SAAS,CACjB,qEAAqE,CACtE,CAAC;IACJ,CAAC;IACD,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7C,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,SAAS,CACjB,gEAAgE,CACjE,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAC7D,IAAI,WAAW,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACzC,MAAM,IAAI,SAAS,CACjB,4EAA4E,CAC7E,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACjD,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,SAAS,CACjB,yEAAyE,CAC1E,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GACd,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE;QACjC,yBAAyB,CAAC,OAAO,CAAC,UAAU,CAAC;IAC/C,IAAI,UAAU,KAAK,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,SAAS,CAAC,oDAAoD,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,MAAM;QACN,UAAU;QACV,GAAG;QACH,WAAW;QACX,cAAc;QACd,WAAW,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC;QACrD,QAAQ;QACR,KAAK;QACL,eAAe,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC;KAC9D,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { DEFAULT_THINKING_PHRASES } from "../thinking-phrases.js";
2
+ /** Trim an optional string; a blank value collapses to null. */
3
+ export function optionalText(value) {
4
+ const trimmed = value?.trim() ?? "";
5
+ return trimmed === "" ? null : trimmed;
6
+ }
7
+ /**
8
+ * Whether a configured directory is absolute. The rule reads a drive-letter
9
+ * path as absolute on every platform, like `session.cwd` does: a deployment
10
+ * profile is authored on one machine and may be read on another, so a
11
+ * Windows-style root is not a mistake to reject on a POSIX host.
12
+ */
13
+ export function isAbsoluteDirectoryPath(value) {
14
+ return /^([a-zA-Z]:[/\\]|\/)/u.test(value);
15
+ }
16
+ /**
17
+ * Shared numeric guard for operator-tuned limits: the value has to be a safe
18
+ * integer inside [min, max], and every rejection carries the same message.
19
+ */
20
+ export function assertIntInRange(name, value, min, max) {
21
+ if (!Number.isSafeInteger(value) || value < min || value > max) {
22
+ throw new TypeError(`dsh-qa-surface: ${name} must be an integer from ${min} to ${max}`);
23
+ }
24
+ }
25
+ /** Deduplicate and trim the operator's quick questions. */
26
+ export function uniqueQuestions(values) {
27
+ const questions = [
28
+ ...new Set(values.map((value) => value.trim()).filter(Boolean)),
29
+ ];
30
+ if (questions.some((value) => value.length > 500)) {
31
+ throw new TypeError("dsh-qa-surface: suggested questions must be at most 500 characters");
32
+ }
33
+ return Object.freeze(questions);
34
+ }
35
+ /**
36
+ * Normalize the operator's phrase list. Unlike quick questions, an empty list
37
+ * cannot mean "hide the control": the running indicator has to say something,
38
+ * so emptiness restores the built-in phrases.
39
+ */
40
+ export function uniquePhrases(values) {
41
+ const phrases = [
42
+ ...new Set(values.map((value) => value.trim()).filter(Boolean)),
43
+ ];
44
+ if (phrases.length === 0)
45
+ return DEFAULT_THINKING_PHRASES;
46
+ if (phrases.some((value) => value.length > 120)) {
47
+ throw new TypeError("dsh-qa-surface: thinking phrases must be at most 120 characters");
48
+ }
49
+ return Object.freeze(phrases);
50
+ }
51
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/config-resolvers/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE,gEAAgE;AAChE,MAAM,UAAU,YAAY,CAAC,KAAgC;IAC3D,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACpC,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;AACzC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,KAAa,EACb,GAAW,EACX,GAAW;IAEX,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;QAC/D,MAAM,IAAI,SAAS,CACjB,mBAAmB,IAAI,4BAA4B,GAAG,OAAO,GAAG,EAAE,CACnE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,eAAe,CAAC,MAAyB;IACvD,MAAM,SAAS,GAAG;QAChB,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;KAChE,CAAC;IACF,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,SAAS,CACjB,oEAAoE,CACrE,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,MAAyB;IACrD,MAAM,OAAO,GAAG;QACd,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;KAChE,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,wBAAwB,CAAC;IAC1D,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,SAAS,CACjB,iEAAiE,CAClE,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,83 @@
1
+ import { DEFAULT_QA_SURFACE_CONFIG } from "./defaults.js";
2
+ import { assertIntInRange } from "./shared.js";
3
+ /** Resolve the sources domain: collection, display, and preview bounds. */
4
+ export function resolveSources(input) {
5
+ const maxInitiallyVisiblePerGroup = input.sources?.display?.maxInitiallyVisiblePerGroup ??
6
+ DEFAULT_QA_SURFACE_CONFIG.sources.display.maxInitiallyVisiblePerGroup;
7
+ const maxPromotedPerSearch = input.sources?.webSearch?.maxPromotedPerSearch ??
8
+ DEFAULT_QA_SURFACE_CONFIG.sources.webSearch.maxPromotedPerSearch;
9
+ const maxBytes = input.sources?.filePreview?.maxBytes ??
10
+ DEFAULT_QA_SURFACE_CONFIG.sources.filePreview.maxBytes;
11
+ const maxMarkdownRenderBytes = input.sources?.filePreview?.maxMarkdownRenderBytes ??
12
+ DEFAULT_QA_SURFACE_CONFIG.sources.filePreview.maxMarkdownRenderBytes;
13
+ assertIntInRange("sources.display.maxInitiallyVisiblePerGroup", maxInitiallyVisiblePerGroup, 1, 100);
14
+ assertIntInRange("sources.webSearch.maxPromotedPerSearch", maxPromotedPerSearch, 0, 50);
15
+ assertIntInRange("sources.filePreview.maxBytes", maxBytes, 1_024, 20_000_000);
16
+ assertIntInRange("sources.filePreview.maxMarkdownRenderBytes", maxMarkdownRenderBytes, 1_024, 10_000_000);
17
+ if (maxMarkdownRenderBytes > maxBytes) {
18
+ throw new TypeError("dsh-qa-surface: sources.filePreview.maxMarkdownRenderBytes cannot exceed maxBytes");
19
+ }
20
+ return Object.freeze({
21
+ enabled: input.sources?.enabled ?? DEFAULT_QA_SURFACE_CONFIG.sources.enabled,
22
+ collect: Object.freeze({
23
+ parentAgent: input.sources?.collect?.parentAgent ??
24
+ DEFAULT_QA_SURFACE_CONFIG.sources.collect.parentAgent,
25
+ subagents: input.sources?.collect?.subagents ??
26
+ DEFAULT_QA_SURFACE_CONFIG.sources.collect.subagents,
27
+ persistTurnEvent: input.sources?.collect?.persistTurnEvent ??
28
+ DEFAULT_QA_SURFACE_CONFIG.sources.collect.persistTurnEvent,
29
+ }),
30
+ display: Object.freeze({
31
+ sidebar: input.sources?.display?.sidebar ??
32
+ DEFAULT_QA_SURFACE_CONFIG.sources.display.sidebar,
33
+ footer: input.sources?.display?.footer ??
34
+ DEFAULT_QA_SURFACE_CONFIG.sources.display.footer,
35
+ groupByKind: input.sources?.display?.groupByKind ??
36
+ DEFAULT_QA_SURFACE_CONFIG.sources.display.groupByKind,
37
+ showDiscovered: input.sources?.display?.showDiscovered ??
38
+ DEFAULT_QA_SURFACE_CONFIG.sources.display.showDiscovered,
39
+ showOriginBadges: input.sources?.display?.showOriginBadges ??
40
+ DEFAULT_QA_SURFACE_CONFIG.sources.display.showOriginBadges,
41
+ maxInitiallyVisiblePerGroup,
42
+ }),
43
+ webSearch: Object.freeze({
44
+ promoteSearchResultsWithoutFetch: input.sources?.webSearch?.promoteSearchResultsWithoutFetch ??
45
+ DEFAULT_QA_SURFACE_CONFIG.sources.webSearch
46
+ .promoteSearchResultsWithoutFetch,
47
+ maxPromotedPerSearch,
48
+ }),
49
+ dedupe: Object.freeze({
50
+ normalizeUrls: input.sources?.dedupe?.normalizeUrls ??
51
+ DEFAULT_QA_SURFACE_CONFIG.sources.dedupe.normalizeUrls,
52
+ stripTrackingParams: input.sources?.dedupe?.stripTrackingParams ??
53
+ DEFAULT_QA_SURFACE_CONFIG.sources.dedupe.stripTrackingParams,
54
+ mergeFileRanges: input.sources?.dedupe?.mergeFileRanges ??
55
+ DEFAULT_QA_SURFACE_CONFIG.sources.dedupe.mergeFileRanges,
56
+ }),
57
+ filePreview: Object.freeze({
58
+ enabled: input.sources?.filePreview?.enabled ??
59
+ DEFAULT_QA_SURFACE_CONFIG.sources.filePreview.enabled,
60
+ markdownRenderedByDefault: input.sources?.filePreview?.markdownRenderedByDefault ??
61
+ DEFAULT_QA_SURFACE_CONFIG.sources.filePreview.markdownRenderedByDefault,
62
+ allowRawToggle: input.sources?.filePreview?.allowRawToggle ??
63
+ DEFAULT_QA_SURFACE_CONFIG.sources.filePreview.allowRawToggle,
64
+ maxBytes,
65
+ maxMarkdownRenderBytes,
66
+ }),
67
+ subagents: Object.freeze({
68
+ inheritSources: input.sources?.subagents?.inheritSources ??
69
+ DEFAULT_QA_SURFACE_CONFIG.sources.subagents.inheritSources,
70
+ enableReportToolFallback: input.sources?.subagents?.enableReportToolFallback ??
71
+ DEFAULT_QA_SURFACE_CONFIG.sources.subagents.enableReportToolFallback,
72
+ markIncompleteOpaqueRuns: input.sources?.subagents?.markIncompleteOpaqueRuns ??
73
+ DEFAULT_QA_SURFACE_CONFIG.sources.subagents.markIncompleteOpaqueRuns,
74
+ validateReportedSources: input.sources?.subagents?.validateReportedSources ??
75
+ DEFAULT_QA_SURFACE_CONFIG.sources.subagents.validateReportedSources,
76
+ }),
77
+ legacy: Object.freeze({
78
+ parseAssistantSourcesBlock: input.sources?.legacy?.parseAssistantSourcesBlock ??
79
+ DEFAULT_QA_SURFACE_CONFIG.sources.legacy.parseAssistantSourcesBlock,
80
+ }),
81
+ });
82
+ }
83
+ //# sourceMappingURL=sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/config-resolvers/sources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { DEFAULT_QA_SURFACE_CONFIG } from "./defaults.js";
2
+ import { assertIntInRange } from "./shared.js";
3
+ /** Resolve the UI domain: widget visibility and the content width floor. */
4
+ export function resolveUi(input) {
5
+ const minContentWidth = input.ui?.minContentWidth ?? DEFAULT_QA_SURFACE_CONFIG.ui.minContentWidth;
6
+ assertIntInRange("ui.minContentWidth", minContentWidth, 480, 1600);
7
+ return Object.freeze({
8
+ showHeader: input.ui?.showHeader ?? DEFAULT_QA_SURFACE_CONFIG.ui.showHeader,
9
+ showReset: input.ui?.showReset ?? DEFAULT_QA_SURFACE_CONFIG.ui.showReset,
10
+ showStop: input.ui?.showStop ?? DEFAULT_QA_SURFACE_CONFIG.ui.showStop,
11
+ showTimestamps: input.ui?.showTimestamps ?? DEFAULT_QA_SURFACE_CONFIG.ui.showTimestamps,
12
+ showToolActivity: input.ui?.showToolActivity ??
13
+ DEFAULT_QA_SURFACE_CONFIG.ui.showToolActivity,
14
+ showReasoning: input.ui?.showReasoning ?? DEFAULT_QA_SURFACE_CONFIG.ui.showReasoning,
15
+ renderMarkdown: input.ui?.renderMarkdown ?? DEFAULT_QA_SURFACE_CONFIG.ui.renderMarkdown,
16
+ minContentWidth,
17
+ showSessionList: input.ui?.showSessionList ?? DEFAULT_QA_SURFACE_CONFIG.ui.showSessionList,
18
+ });
19
+ }
20
+ //# sourceMappingURL=ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/config-resolvers/ui.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/C,4EAA4E;AAC5E,MAAM,UAAU,SAAS,CAAC,KAAsB;IAC9C,MAAM,eAAe,GACnB,KAAK,CAAC,EAAE,EAAE,eAAe,IAAI,yBAAyB,CAAC,EAAE,CAAC,eAAe,CAAC;IAC5E,gBAAgB,CAAC,oBAAoB,EAAE,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACnE,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,UAAU,EAAE,KAAK,CAAC,EAAE,EAAE,UAAU,IAAI,yBAAyB,CAAC,EAAE,CAAC,UAAU;QAC3E,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,IAAI,yBAAyB,CAAC,EAAE,CAAC,SAAS;QACxE,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,QAAQ,IAAI,yBAAyB,CAAC,EAAE,CAAC,QAAQ;QACrE,cAAc,EACZ,KAAK,CAAC,EAAE,EAAE,cAAc,IAAI,yBAAyB,CAAC,EAAE,CAAC,cAAc;QACzE,gBAAgB,EACd,KAAK,CAAC,EAAE,EAAE,gBAAgB;YAC1B,yBAAyB,CAAC,EAAE,CAAC,gBAAgB;QAC/C,aAAa,EACX,KAAK,CAAC,EAAE,EAAE,aAAa,IAAI,yBAAyB,CAAC,EAAE,CAAC,aAAa;QACvE,cAAc,EACZ,KAAK,CAAC,EAAE,EAAE,cAAc,IAAI,yBAAyB,CAAC,EAAE,CAAC,cAAc;QACzE,eAAe;QACf,eAAe,EACb,KAAK,CAAC,EAAE,EAAE,eAAe,IAAI,yBAAyB,CAAC,EAAE,CAAC,eAAe;KAC5E,CAAC,CAAC;AACL,CAAC"}