@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,255 @@
1
+ /**
2
+ * Pure presentation helpers of the QA Surface settings card.
3
+ *
4
+ * Kept out of the components so the wording and the draft parsing are
5
+ * unit-testable without a DOM, and so every place that renders the same value
6
+ * renders it identically. Nothing here may reach the Host config surface: the
7
+ * card bundle must not pull schemastery into the page.
8
+ */
9
+ /**
10
+ * Header badge: the route the page answers on, or that the surface is off.
11
+ * The route is the one fact an operator scanning the plugin list looks for.
12
+ */
13
+ export function badgeText(enabled, routePath) {
14
+ if (enabled === false)
15
+ return "Выключено";
16
+ return routePath === undefined || routePath === "" ? "/qa" : routePath;
17
+ }
18
+ /** Wording of the session-policy control. */
19
+ export function describeSessionPolicy(policy) {
20
+ switch (policy) {
21
+ case "new-on-load":
22
+ return {
23
+ label: "Новый чат при каждой загрузке",
24
+ hint: "Каждый заход начинается с пустой беседы; прошлые чаты остаются в истории хоста.",
25
+ };
26
+ case "fixed":
27
+ return {
28
+ label: "Один фиксированный чат",
29
+ hint: "Все посетители работают в одной заранее созданной сессии.",
30
+ };
31
+ case "browser-persistent":
32
+ return {
33
+ label: "Чат закреплён за браузером",
34
+ hint: "Перезагрузка страницы возвращает ту же беседу этого браузера.",
35
+ };
36
+ default:
37
+ return {
38
+ label: "Чат закреплён за браузером",
39
+ hint: "Перезагрузка страницы возвращает ту же беседу этого браузера.",
40
+ };
41
+ }
42
+ }
43
+ /** Wording of the sandbox-mode control. */
44
+ export function describeSandbox(mode) {
45
+ switch (mode) {
46
+ case "workspace-write":
47
+ return {
48
+ label: "Запись в рабочее пространство",
49
+ hint: "Допустима только вместе с персональными рабочими пространствами аккаунтов.",
50
+ };
51
+ default:
52
+ return {
53
+ label: "Только чтение",
54
+ hint: "Инструменты не могут изменить рабочую директорию сессии.",
55
+ };
56
+ }
57
+ }
58
+ /**
59
+ * Parse a numeric control's draft text.
60
+ * @param text - raw input value.
61
+ * @param min - lowest accepted value, clamped into range on commit.
62
+ * @param max - highest accepted value, clamped into range on commit.
63
+ * @returns the integer, or null when the field is empty or not numeric (the
64
+ * caller leaves the stored value alone rather than writing a NaN).
65
+ */
66
+ export function parseNumberDraft(text, min, max) {
67
+ const trimmed = text.trim();
68
+ if (trimmed.length === 0)
69
+ return null;
70
+ const value = Number(trimmed);
71
+ if (!Number.isFinite(value))
72
+ return null;
73
+ return Math.min(max, Math.max(min, Math.round(value)));
74
+ }
75
+ /**
76
+ * Parse a one-entry-per-line list control's draft text. Questions and phrases
77
+ * are free copy, so a comma inside an entry must stay part of that entry.
78
+ */
79
+ export function parseLineList(text) {
80
+ return text
81
+ .split(/\r?\n/u)
82
+ .map((entry) => entry.trim())
83
+ .filter((entry) => entry.length > 0);
84
+ }
85
+ /** Parse a list control whose entries may also be comma-separated. */
86
+ export function parseCommaList(text) {
87
+ return text
88
+ .split(/[\n,]/u)
89
+ .map((entry) => entry.trim())
90
+ .filter((entry) => entry.length > 0);
91
+ }
92
+ /** Identity keys are lowercase labels; the same shape the Host enforces. */
93
+ const IDENTITY_KEY = /^[a-z][a-z0-9_-]{0,31}$/u;
94
+ /** Longest accepted display label of one identity field (Host rule). */
95
+ const IDENTITY_LABEL_MAX = 40;
96
+ /**
97
+ * Parse the identity-field control: one `key = подпись` entry per line. A
98
+ * missing label falls back to the key, and an entry whose key cannot exist on
99
+ * the Host is dropped here rather than refused as a whole write.
100
+ */
101
+ export function parseIdentityFields(text) {
102
+ const fields = [];
103
+ const seen = new Set();
104
+ for (const line of text.split(/\r?\n/u)) {
105
+ const [rawKey = "", ...rest] = line.split("=");
106
+ const key = rawKey.trim().toLowerCase();
107
+ if (!IDENTITY_KEY.test(key) || seen.has(key))
108
+ continue;
109
+ seen.add(key);
110
+ const label = rest.join("=").trim().slice(0, IDENTITY_LABEL_MAX);
111
+ fields.push({ key, label: label === "" ? key : label });
112
+ }
113
+ return fields;
114
+ }
115
+ /** Render declared identity fields back into the control's draft text. */
116
+ export function formatIdentityFields(fields) {
117
+ return (fields ?? [])
118
+ .map((field) => `${field.key} = ${field.label}`)
119
+ .join("\n");
120
+ }
121
+ /**
122
+ * Prerequisites `accounts.perUserWorkspace` cannot run without. The Host
123
+ * refuses the configuration while any of them is unmet, and the sandbox mode
124
+ * is the one entry the card must write together with the flag: both
125
+ * `workspace-write` alone and per-user workspaces alone are refused.
126
+ */
127
+ export function perUserWorkspaceGaps(config) {
128
+ const gaps = [];
129
+ if (config.accounts?.enabled !== true)
130
+ gaps.push("включены аккаунты");
131
+ if ((config.session?.workspaceId ?? null) === null)
132
+ gaps.push("задан session.workspaceId");
133
+ if (config.session?.policy === "fixed")
134
+ gaps.push("политика сессии не «фиксированный чат»");
135
+ if (config.lockdown?.enabled !== true)
136
+ gaps.push("включена блокировка");
137
+ if (config.lockdown?.enforceFixedWorkspace !== true)
138
+ gaps.push("включён lockdown.enforceFixedWorkspace");
139
+ if (config.lockdown?.sandboxMode !== "workspace-write")
140
+ gaps.push("sandboxMode = «запись в рабочее пространство»");
141
+ return gaps;
142
+ }
143
+ /**
144
+ * Whether the raw user layer carries this path, which is what marks a field
145
+ * overridden — a value equal to the composition default is still an override.
146
+ * @param user - raw user section from the settings snapshot.
147
+ * @param path - path from the section root.
148
+ * @returns true when every segment exists in the user layer.
149
+ */
150
+ export function isOverridden(user, path) {
151
+ let cursor = user;
152
+ for (const segment of path) {
153
+ if (typeof cursor !== "object" ||
154
+ cursor === null ||
155
+ Array.isArray(cursor)) {
156
+ return false;
157
+ }
158
+ const record = cursor;
159
+ if (!Object.hasOwn(record, segment))
160
+ return false;
161
+ cursor = record[segment];
162
+ }
163
+ return true;
164
+ }
165
+ /** Top-level keys the user layer carries; the reset-all action clears exactly these. */
166
+ export function overriddenKeys(user) {
167
+ if (typeof user !== "object" || user === null || Array.isArray(user)) {
168
+ return [];
169
+ }
170
+ return Object.keys(user).sort();
171
+ }
172
+ /**
173
+ * Read a path out of a settings section.
174
+ * @param value - section root (the snapshot's effective value or user layer).
175
+ * @param path - path from the section root.
176
+ * @returns the value found, or undefined when any segment is absent.
177
+ */
178
+ export function readPath(value, path) {
179
+ let cursor = value;
180
+ for (const segment of path) {
181
+ if (typeof cursor !== "object" || cursor === null)
182
+ return undefined;
183
+ cursor = cursor[segment];
184
+ }
185
+ return cursor;
186
+ }
187
+ /** Empty in every form the resolver accepts: absent, null, or an empty string. */
188
+ function isEmptySetting(value) {
189
+ return value === undefined || value === null || value === "";
190
+ }
191
+ /** Whether two settings values are the same as the Host would store them. */
192
+ function isSameSetting(left, right) {
193
+ if (isEmptySetting(left) && isEmptySetting(right))
194
+ return true;
195
+ return JSON.stringify(left) === JSON.stringify(right);
196
+ }
197
+ /**
198
+ * Whether a settled mutation left the section holding what it asked for.
199
+ *
200
+ * The scope resolves a Host-rejected write instead of rejecting it — it
201
+ * reloads Host state and returns — so acceptance is confirmed here. The
202
+ * namespace revision advances on every committed change, and a write that
203
+ * changed nothing is indistinguishable from a refusal; in that one case the
204
+ * section itself answers whether the value already stood.
205
+ * @param entries - writes the mutation asked for.
206
+ * @param cleared - paths the mutation asked to clear.
207
+ * @param snapshot - the scope snapshot as it stands after the settlement.
208
+ * @returns true when the mutation's intent is visible in the section.
209
+ */
210
+ export function mutationLanded(entries, cleared, snapshot) {
211
+ for (const entry of entries) {
212
+ if (!isSameSetting(readPath(snapshot.value, entry.path), entry.value)) {
213
+ return false;
214
+ }
215
+ }
216
+ for (const path of cleared) {
217
+ if (isOverridden(snapshot.user, path))
218
+ return false;
219
+ }
220
+ return true;
221
+ }
222
+ /** Wall-clock stamp of the last Host answer, for the status line. */
223
+ export function formatClock(timestamp) {
224
+ if (timestamp === undefined || !Number.isFinite(timestamp))
225
+ return "—";
226
+ return new Date(timestamp).toLocaleTimeString("ru-RU", {
227
+ hour: "2-digit",
228
+ minute: "2-digit",
229
+ second: "2-digit",
230
+ });
231
+ }
232
+ /**
233
+ * Count with the Russian form of its noun: 1 ключ, 2 ключа, 5 ключей.
234
+ * @param count - counted value.
235
+ * @param forms - singular, few, and many forms of the noun.
236
+ * @returns the counted noun as the copy renders it.
237
+ */
238
+ export function pluralRu(count, forms) {
239
+ const mod100 = count % 100;
240
+ const mod10 = count % 10;
241
+ if (mod100 >= 11 && mod100 <= 14)
242
+ return `${String(count)} ${forms[2]}`;
243
+ if (mod10 === 1)
244
+ return `${String(count)} ${forms[0]}`;
245
+ if (mod10 >= 2 && mod10 <= 4)
246
+ return `${String(count)} ${forms[1]}`;
247
+ return `${String(count)} ${forms[2]}`;
248
+ }
249
+ /** Thousands separator so long byte budgets stay readable. */
250
+ export function formatCount(value) {
251
+ if (value === undefined || !Number.isFinite(value))
252
+ return "—";
253
+ return Math.round(value).toLocaleString("ru-RU");
254
+ }
255
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/client/settings/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Access and route: the only section whose consequences reach beyond this
4
+ * plugin's namespace — the path it claims on the Host and where external
5
+ * visitors of the harness root land.
6
+ */
7
+ import { Notice, Section, TextField, Toggle } from "../fields.js";
8
+ import { overriddenAny, resetAside, } from "./common.js";
9
+ /** Where the page lives and who may reach it. */
10
+ export function AccessSection(props) {
11
+ const config = props.config;
12
+ const disabled = !props.writable;
13
+ const paths = [["enabled"], ["route"], ["entry"]];
14
+ const modified = overriddenAny(props, paths);
15
+ return (_jsxs(Section, { title: "\u0414\u043E\u0441\u0442\u0443\u043F \u0438 \u043C\u0430\u0440\u0448\u0440\u0443\u0442", modified: modified, aside: resetAside(props, paths), children: [_jsxs("div", { className: "qa-card-grid", children: [_jsx(Toggle, { checked: config?.enabled ?? true, disabled: disabled, label: "\u0421\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u0432\u043A\u043B\u044E\u0447\u0435\u043D\u0430", hint: "\u0412\u044B\u043A\u043B\u044E\u0447\u0435\u043D\u043D\u0430\u044F \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u043D\u0435 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043F\u043E \u043C\u0430\u0440\u0448\u0440\u0443\u0442\u0443 \u0438 \u043D\u0435 \u043F\u0435\u0440\u0435\u043D\u0430\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u0442 \u0432\u043D\u0435\u0448\u043D\u0438\u0435 \u0432\u0445\u043E\u0434\u044B.", onChange: (value) => {
16
+ props.write(["enabled"], value);
17
+ } }), _jsx(Toggle, { checked: config?.route?.matchChildren ?? true, disabled: disabled, label: "\u0412\u043A\u043B\u044E\u0447\u0430\u044F \u0432\u043B\u043E\u0436\u0435\u043D\u043D\u044B\u0435 \u043F\u0443\u0442\u0438", hint: "\u041C\u0430\u0440\u0448\u0440\u0443\u0442 \u0441 \u0432\u043B\u043E\u0436\u0435\u043D\u043D\u044B\u043C\u0438 \u0430\u0434\u0440\u0435\u0441\u0430\u043C\u0438 \u043E\u0441\u0442\u0430\u0451\u0442\u0441\u044F \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435\u0439 \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A\u0430.", onChange: (value) => {
18
+ props.write(["route", "matchChildren"], value);
19
+ } }), _jsx(TextField, { label: "\u041F\u0443\u0442\u044C \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B", value: config?.route?.path ?? "/qa", disabled: disabled, placeholder: "/qa", hint: "\u041D\u0430\u0447\u0438\u043D\u0430\u0435\u0442\u0441\u044F \u0441 \u00AB/\u00BB; \u043D\u0435\u043B\u044C\u0437\u044F \u0437\u0430\u043D\u044F\u0442\u044C \u00AB/\u00BB, \u00AB/api\u00BB \u0438 \u00AB/plugins\u00BB. \u0421\u043C\u0435\u043D\u0430 \u043F\u0443\u0442\u0438 \u043F\u0435\u0440\u0435\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u043C\u0430\u0440\u0448\u0440\u0443\u0442 \u043D\u0430 \u0445\u043E\u0441\u0442\u0435.", onChange: (value) => {
20
+ props.write(["route", "path"], value);
21
+ } }), _jsx(Toggle, { checked: config?.entry?.redirectNonLoopback ?? true, disabled: disabled, label: "\u0412\u043D\u0435\u0448\u043D\u0438\u0435 \u0432\u0445\u043E\u0434\u044B \u2014 \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A\u0430", hint: "\u041A\u043E\u0440\u0435\u043D\u044C \u0445\u0430\u0440\u043D\u0435\u0441\u0441\u0430, \u043E\u0442\u043A\u0440\u044B\u0442\u044B\u0439 \u043F\u043E \u0432\u043D\u0435\u0448\u043D\u0435\u043C\u0443 \u0430\u0434\u0440\u0435\u0441\u0443, \u043F\u0435\u0440\u0435\u0430\u0434\u0440\u0435\u0441\u0443\u0435\u0442\u0441\u044F \u0441\u044E\u0434\u0430. \u041B\u043E\u043A\u0430\u043B\u044C\u043D\u044B\u0439 \u0432\u0445\u043E\u0434 \u043E\u043F\u0435\u0440\u0430\u0442\u043E\u0440\u0430 \u043D\u0435 \u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u0435\u0442\u0441\u044F.", onChange: (value) => {
22
+ props.write(["entry", "redirectNonLoopback"], value);
23
+ } })] }), (config?.entry?.redirectNonLoopback ?? true) ? (_jsx(Notice, { tone: "info", children: "\u041F\u0435\u0440\u0435\u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0432\u043A\u043B\u044E\u0447\u0435\u043D\u043E: \u043B\u044E\u0431\u043E\u0439, \u043A\u0442\u043E \u043E\u0442\u043A\u0440\u044B\u043B \u0445\u0430\u0440\u043D\u0435\u0441\u0441 \u043F\u043E \u0432\u043D\u0435\u0448\u043D\u0435\u043C\u0443 \u0430\u0434\u0440\u0435\u0441\u0443, \u043F\u043E\u043F\u0430\u0434\u0451\u0442 \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A\u0430, \u0430 \u043D\u0435 \u0432 \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A\u0430." })) : (_jsx(Notice, { tone: "warn", children: "\u041F\u0435\u0440\u0435\u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0432\u044B\u043A\u043B\u044E\u0447\u0435\u043D\u043E: \u0432\u043D\u0435\u0448\u043D\u0438\u0439 \u043F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u044C \u043A\u043E\u0440\u043D\u044F \u0445\u0430\u0440\u043D\u0435\u0441\u0441\u0430 \u043E\u0441\u0442\u0430\u0451\u0442\u0441\u044F \u0432 \u043F\u043E\u043B\u043D\u043E\u043C \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A\u0430. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044C, \u0447\u0442\u043E \u043E\u043D \u0437\u0430\u043A\u0440\u044B\u0442 \u0434\u0440\u0443\u0433\u0438\u043C\u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043C\u0438." }))] }));
24
+ }
25
+ //# sourceMappingURL=access.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.js","sourceRoot":"","sources":["../../../../src/client/settings/sections/access.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EACL,aAAa,EACb,UAAU,GAGX,MAAM,aAAa,CAAC;AAErB,iDAAiD;AACjD,MAAM,UAAU,aAAa,CAAC,KAAkB;IAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;IACjC,MAAM,KAAK,GAAiB,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC7C,OAAO,CACL,MAAC,OAAO,IACN,KAAK,EAAC,wFAAkB,EACxB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,aAE/B,eAAK,SAAS,EAAC,cAAc,aAC3B,KAAC,MAAM,IACL,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,IAAI,EAChC,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAC,mGAAmB,EACzB,IAAI,EAAC,qaAAiF,EACtF,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;4BAClB,KAAK,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;wBAClC,CAAC,GACD,EACF,KAAC,MAAM,IACL,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,IAAI,IAAI,EAC7C,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAC,4HAAwB,EAC9B,IAAI,EAAC,iUAA6D,EAClE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;4BAClB,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,KAAK,CAAC,CAAC;wBACjD,CAAC,GACD,EACF,KAAC,SAAS,IACR,KAAK,EAAC,2EAAe,EACrB,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,KAAK,EACnC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAC,KAAK,EACjB,IAAI,EAAC,4cAAyG,EAC9G,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;4BAClB,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;wBACxC,CAAC,GACD,EACF,KAAC,MAAM,IACL,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,IAAI,IAAI,EACnD,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAC,uMAAuC,EAC7C,IAAI,EAAC,gkBAA+G,EACpH,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;4BAClB,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,qBAAqB,CAAC,EAAE,KAAK,CAAC,CAAC;wBACvD,CAAC,GACD,IACE,EACL,CAAC,MAAM,EAAE,KAAK,EAAE,mBAAmB,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAC9C,KAAC,MAAM,IAAC,IAAI,EAAC,MAAM,isBAGV,CACV,CAAC,CAAC,CAAC,CACF,KAAC,MAAM,IAAC,IAAI,EAAC,MAAM,qyBAIV,CACV,IACO,CACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Accounts: the account gate, the self-declared profile, and per-user
4
+ * workspaces. The per-user toggle lands together with the sandbox mode —
5
+ * the Host accepts that pairing or nothing.
6
+ */
7
+ import { IdentitiesField, Notice, NumberField, Section, Toggle, } from "../fields.js";
8
+ import { perUserWorkspaceGaps } from "../format.js";
9
+ import { overriddenAny, resetAside, } from "./common.js";
10
+ /** The account gate, the self-declared profile, and per-user workspaces. */
11
+ export function AccountsSection(props) {
12
+ const config = props.config;
13
+ const disabled = !props.writable;
14
+ const accounts = config?.accounts;
15
+ const enabled = accounts?.enabled ?? false;
16
+ const profile = accounts?.profile;
17
+ const perUser = accounts?.perUserWorkspace ?? false;
18
+ const gaps = perUser ? [] : perUserWorkspaceGaps(config ?? {});
19
+ const paths = [["accounts"]];
20
+ const modified = overriddenAny(props, paths);
21
+ return (_jsxs(Section, { title: "\u0410\u043A\u043A\u0430\u0443\u043D\u0442\u044B", modified: modified, aside: resetAside(props, paths), children: [_jsxs("div", { className: "qa-card-grid", children: [_jsx(Toggle, { checked: enabled, disabled: disabled, label: "\u0412\u0445\u043E\u0434 \u043F\u043E \u0430\u043A\u043A\u0430\u0443\u043D\u0442\u0430\u043C", hint: "\u041F\u043E\u043A\u0430 \u0432\u044B\u043A\u043B\u044E\u0447\u0435\u043D\u043E, \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u043E\u0442\u043A\u0440\u044B\u0442\u0430 \u0432\u0441\u044F\u043A\u043E\u043C\u0443, \u043A\u0442\u043E \u0434\u043E \u043D\u0435\u0451 \u0434\u043E\u0448\u0451\u043B.", onChange: (value) => {
22
+ props.write(["accounts", "enabled"], value);
23
+ } }), _jsx(Toggle, { checked: accounts?.allowRegistration ?? true, disabled: disabled || !enabled, label: "\u0421\u0430\u043C\u043E\u0441\u0442\u043E\u044F\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F", hint: "\u041F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u044C \u043C\u043E\u0436\u0435\u0442 \u0437\u0430\u0432\u0435\u0441\u0442\u0438 \u0430\u043A\u043A\u0430\u0443\u043D\u0442 \u0441\u0430\u043C. \u041F\u0435\u0440\u0432\u044B\u0439 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0441\u044F \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u043E\u043C.", onChange: (value) => {
24
+ props.write(["accounts", "allowRegistration"], value);
25
+ } }), _jsx(NumberField, { label: "\u0421\u0440\u043E\u043A \u0436\u0438\u0437\u043D\u0438 \u0432\u0445\u043E\u0434\u0430, \u0434\u043D\u0435\u0439", value: accounts?.sessionTtlDays ?? 30, min: 1, max: 365, disabled: disabled || !enabled, hint: "\u0427\u0435\u0440\u0435\u0437 \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0434\u043D\u0435\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0443 \u043F\u0440\u0438\u0434\u0451\u0442\u0441\u044F \u0432\u043E\u0439\u0442\u0438 \u0437\u0430\u043D\u043E\u0432\u043E.", onChange: (value) => {
26
+ props.write(["accounts", "sessionTtlDays"], value);
27
+ } }), _jsx(Toggle, { checked: accounts?.showOtherUsersChats ?? false, disabled: disabled || !enabled, label: "\u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u0430\u043C \u0432\u0438\u0434\u043D\u044B \u0447\u0443\u0436\u0438\u0435 \u0447\u0430\u0442\u044B", hint: "\u041E\u0431\u044B\u0447\u043D\u044B\u0439 \u0430\u043A\u043A\u0430\u0443\u043D\u0442 \u0432\u0438\u0434\u0438\u0442 \u0442\u043E\u043B\u044C\u043A\u043E \u0441\u0432\u043E\u0438 \u0447\u0430\u0442\u044B; \u044D\u0442\u0430 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u0430\u043C \u0441\u043F\u0438\u0441\u043E\u043A \u0432\u0441\u0435\u0445.", onChange: (value) => {
28
+ props.write(["accounts", "showOtherUsersChats"], value);
29
+ } })] }), enabled ? (_jsx(Notice, { tone: "info", children: "\u0410\u043A\u043A\u0430\u0443\u043D\u0442\u044B \u043D\u0430\u0437\u044B\u0432\u0430\u044E\u0442 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u0438 \u0437\u0430\u043A\u0440\u0435\u043F\u043B\u044F\u044E\u0442 \u0437\u0430 \u043D\u0438\u043C \u0447\u0430\u0442\u044B. \u041E\u043D\u0438 \u043D\u0435 \u043E\u0442\u0433\u043E\u0440\u0430\u0436\u0438\u0432\u0430\u044E\u0442 \u0445\u0430\u0440\u043D\u0435\u0441\u0441: \u0441\u0435\u0441\u0441\u0438\u044F \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A\u0430 \u0432\u0441\u0451 \u0440\u0430\u0432\u043D\u043E \u0436\u0438\u0432\u0451\u0442 \u0432 \u043F\u0440\u0430\u0432\u0430\u0445 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430 \u0445\u043E\u0441\u0442\u0430." })) : (_jsx(Notice, { tone: "info", children: "\u0410\u043A\u043A\u0430\u0443\u043D\u0442\u044B \u0432\u044B\u043A\u043B\u044E\u0447\u0435\u043D\u044B: \u0432\u0441\u0435 \u043F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u0438 \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u044B, \u0447\u0430\u0442\u044B \u043D\u0435 \u0437\u0430\u043A\u0440\u0435\u043F\u043B\u044F\u044E\u0442\u0441\u044F \u0437\u0430 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u043E\u043C, \u0430 \u043E\u0431\u0449\u0430\u044F \u0438\u0441\u0442\u043E\u0440\u0438\u044F \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u043A\u0430\u0436\u0434\u043E\u043C\u0443." })), enabled && (accounts?.showOtherUsersChats ?? false) ? (_jsx(Notice, { tone: "warn", children: "\u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u044B \u0432\u0438\u0434\u044F\u0442 \u0447\u0430\u0442\u044B \u0434\u0440\u0443\u0433\u0438\u0445 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439. \u042D\u0442\u043E \u043E\u0441\u043E\u0437\u043D\u0430\u043D\u043D\u043E\u0435 \u0440\u0435\u0448\u0435\u043D\u0438\u0435 \u0441\u0442\u0435\u043D\u0434\u0430: \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0435 \u0447\u0443\u0436\u0438\u0445 \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432 \u043F\u043E\u043F\u0430\u0434\u0430\u0435\u0442 \u043D\u0430 \u044D\u043A\u0440\u0430\u043D \u0442\u043E\u043C\u0443, \u043A\u0442\u043E \u0438\u0445 \u043D\u0435 \u0432\u0451\u043B." })) : null, _jsx("div", { className: "qa-card-grid", children: _jsx(Toggle, { checked: perUser, disabled: disabled || !enabled, label: "\u041E\u0442\u0434\u0435\u043B\u044C\u043D\u043E\u0435 \u0440\u0430\u0431\u043E\u0447\u0435\u0435 \u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u0441\u0442\u0432\u043E \u043A\u0430\u0436\u0434\u043E\u043C\u0443", hint: "\u0421\u0435\u0441\u0441\u0438\u0438 \u0440\u0430\u0441\u0445\u043E\u0434\u044F\u0442\u0441\u044F \u043F\u043E \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430\u043C \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439 \u0432\u043D\u0443\u0442\u0440\u0438 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u0440\u0430\u0431\u043E\u0447\u0435\u0433\u043E \u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u0441\u0442\u0432\u0430. \u0421\u043E\u0445\u0440\u0430\u043D\u044F\u0435\u0442\u0441\u044F \u0432\u043C\u0435\u0441\u0442\u0435 \u0441 \u0440\u0435\u0436\u0438\u043C\u043E\u043C \u043F\u0435\u0441\u043E\u0447\u043D\u0438\u0446\u044B \u00AB\u0437\u0430\u043F\u0438\u0441\u044C\u00BB, \u0438\u043D\u0430\u0447\u0435 \u0445\u043E\u0441\u0442 \u043E\u0442\u0432\u0435\u0440\u0433\u0430\u0435\u0442 \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044E.", onChange: (value) => {
30
+ props.writeMany([
31
+ { path: ["accounts", "perUserWorkspace"], value },
32
+ {
33
+ path: ["lockdown", "sandboxMode"],
34
+ value: value ? "workspace-write" : "read-only",
35
+ },
36
+ ]);
37
+ } }) }), !perUser && gaps.length > 0 ? (_jsxs(Notice, { tone: "info", children: ["\u0414\u043B\u044F \u043F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0445 \u0440\u0430\u0431\u043E\u0447\u0438\u0445 \u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u0441\u0442\u0432 \u043D\u0443\u0436\u043D\u043E \u0435\u0449\u0451: ", gaps.join("; "), "."] })) : null, _jsxs("div", { className: "qa-card-grid", children: [_jsx(Toggle, { checked: profile?.enabled ?? true, disabled: disabled || !enabled, label: "\u041F\u0440\u043E\u0444\u0438\u043B\u044C \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F", hint: "\u0424\u043E\u0440\u043C\u0430 \u00AB\u043E \u0441\u0435\u0431\u0435\u00BB \u0432 \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A\u0430; \u0431\u0435\u0437 \u0430\u043A\u043A\u0430\u0443\u043D\u0442\u043E\u0432 \u0435\u0451 \u043D\u0435\u043A\u043E\u043C\u0443 \u0437\u0430\u043F\u043E\u043B\u043D\u044F\u0442\u044C.", onChange: (value) => {
38
+ props.write(["accounts", "profile", "enabled"], value);
39
+ } }), _jsx(Toggle, { checked: profile?.inject ?? true, disabled: disabled || !enabled || !(profile?.enabled ?? true), label: "\u041F\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044C \u043F\u0440\u043E\u0444\u0438\u043B\u044C \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A\u0443", hint: "\u0418\u043C\u044F, \u043F\u043E\u0447\u0442\u0430 \u0438 \u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u043D\u044B\u0435 \u043F\u043E\u043B\u044F \u043F\u0440\u043E\u0444\u0438\u043B\u044F \u0443\u0445\u043E\u0434\u044F\u0442 \u0432 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u0443\u044E \u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0443, \u0447\u0442\u043E\u0431\u044B \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A \u0437\u043D\u0430\u043B, \u0441 \u043A\u0435\u043C \u0433\u043E\u0432\u043E\u0440\u0438\u0442.", onChange: (value) => {
40
+ props.write(["accounts", "profile", "inject"], value);
41
+ } }), _jsx(NumberField, { label: "\u041F\u0440\u0435\u0434\u0435\u043B \u0434\u043B\u0438\u043D\u044B \u0438\u043D\u0441\u0442\u0440\u0443\u043A\u0446\u0438\u0439, \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432", value: profile?.instructionsMaxLength ?? 2000, min: 200, max: 20_000, disabled: disabled || !enabled || !(profile?.enabled ?? true), hint: "\u0421\u043A\u043E\u043B\u044C\u043A\u043E \u0441\u0432\u043E\u0431\u043E\u0434\u043D\u043E\u0433\u043E \u0442\u0435\u043A\u0441\u0442\u0430 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C \u043C\u043E\u0436\u0435\u0442 \u043D\u0430\u043F\u0438\u0441\u0430\u0442\u044C \u043E \u0442\u043E\u043C, \u043A\u0430\u043A \u0435\u043C\u0443 \u043E\u0442\u0432\u0435\u0447\u0430\u0442\u044C.", onChange: (value) => {
42
+ props.write(["accounts", "profile", "instructionsMaxLength"], value);
43
+ } })] }), _jsx(IdentitiesField, { value: profile?.identities ?? [], disabled: disabled || !enabled || !(profile?.enabled ?? true), onCommit: (fields) => {
44
+ props.write(["accounts", "profile", "identities"], fields);
45
+ } })] }));
46
+ }
47
+ //# sourceMappingURL=accounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../../../src/client/settings/sections/accounts.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Attachments: what a visitor may attach to one message. Like the interface
4
+ * section, the list fields show the value in effect — a stored list, else the
5
+ * Host's resolved one — so an untouched deployment never sees an empty box
6
+ * for a setting that is active.
7
+ */
8
+ import { DEFAULT_QA_TEXT_EXTENSIONS } from "../../../attachment-rules.js";
9
+ import { ListField, Notice, NumberField, Section, Toggle } from "../fields.js";
10
+ import { parseCommaList } from "../format.js";
11
+ import { overriddenAny, resetAside, } from "./common.js";
12
+ /**
13
+ * What a visitor may attach to one message. Files never ride the prompt
14
+ * inline: the browser stages them on the Host and the prompt cites the
15
+ * receipt, so the model resolves the stored copy through its file tools — the
16
+ * deployment's tool allow-list has to keep `read` for that to be useful.
17
+ */
18
+ export function AttachmentsSection(props) {
19
+ const config = props.config;
20
+ const disabled = !props.writable;
21
+ const attachments = config?.attachments;
22
+ const textFiles = attachments?.textFiles ?? true;
23
+ const pastedTextLines = attachments?.pastedTextLines ?? 200;
24
+ const maxFileBytes = attachments?.maxFileBytes ?? 10_485_760;
25
+ const maxPending = attachments?.maxPending ?? 8;
26
+ const paths = [["attachments"]];
27
+ const modified = overriddenAny(props, paths);
28
+ // The field shows the list in effect: a stored list wins, the Host's
29
+ // resolved list stands in for it, then the built-in default.
30
+ const stored = attachments?.extensions;
31
+ const extensions = stored !== undefined && stored.length > 0
32
+ ? stored
33
+ : (props.effective?.attachments.extensions ?? DEFAULT_QA_TEXT_EXTENSIONS);
34
+ return (_jsxs(Section, { title: "\u0412\u043B\u043E\u0436\u0435\u043D\u0438\u044F", modified: modified, aside: resetAside(props, paths), children: [_jsxs("div", { className: "qa-card-grid", children: [_jsx(Toggle, { checked: textFiles, disabled: disabled, label: "\u0422\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0435 \u0444\u0430\u0439\u043B\u044B", hint: "\u041A \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u043C \u043C\u043E\u0436\u043D\u043E \u043F\u0440\u0438\u043A\u043B\u0430\u0434\u044B\u0432\u0430\u0442\u044C md, txt, log \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0442\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0435 \u0444\u0430\u0439\u043B\u044B. \u0412\u044B\u043A\u043B\u044E\u0447\u0435\u043D\u043E \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F.", onChange: (value) => {
35
+ props.write(["attachments", "textFiles"], value);
36
+ } }), _jsx(NumberField, { label: "\u041F\u0435\u0440\u0435\u043D\u043E\u0441\u0438\u0442\u044C \u0432\u0441\u0442\u0430\u0432\u043A\u0443, \u0441\u0442\u0440\u043E\u043A", value: pastedTextLines, min: 0, max: 10_000, disabled: disabled || !textFiles, hint: "\u0412\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u043D\u044B\u0439 \u0442\u0435\u043A\u0441\u0442 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 \u044D\u0442\u043E\u0433\u043E \u0447\u0438\u0441\u043B\u0430 \u0441\u0442\u0440\u043E\u043A \u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0441\u044F \u0432\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043C. 0 \u043E\u0442\u043A\u043B\u044E\u0447\u0430\u0435\u0442 \u043F\u0435\u0440\u0435\u043D\u043E\u0441.", onChange: (value) => {
37
+ props.write(["attachments", "pastedTextLines"], value);
38
+ } }), _jsx(NumberField, { label: "\u041B\u0438\u043C\u0438\u0442 \u0444\u0430\u0439\u043B\u0430, \u0431\u0430\u0439\u0442", value: maxFileBytes, min: 1_024, max: 52_428_800, disabled: disabled || !textFiles, hint: "\u041F\u0440\u0435\u0434\u0435\u043B\u044C\u043D\u044B\u0439 \u0440\u0430\u0437\u043C\u0435\u0440 \u043E\u0434\u043D\u043E\u0433\u043E \u043F\u0440\u0438\u043A\u043B\u0430\u0434\u044B\u0432\u0430\u0435\u043C\u043E\u0433\u043E \u0444\u0430\u0439\u043B\u0430.", onChange: (value) => {
39
+ props.write(["attachments", "maxFileBytes"], value);
40
+ } }), _jsx(NumberField, { label: "\u0412\u043B\u043E\u0436\u0435\u043D\u0438\u0439 \u043D\u0430 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435", value: maxPending, min: 1, max: 40, disabled: disabled, hint: "\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F \u0438 \u0444\u0430\u0439\u043B\u044B \u0441\u0447\u0438\u0442\u0430\u044E\u0442\u0441\u044F \u0432\u043C\u0435\u0441\u0442\u0435.", onChange: (value) => {
41
+ props.write(["attachments", "maxPending"], value);
42
+ } })] }), _jsx(ListField, { label: "\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F \u0442\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0445 \u0444\u0430\u0439\u043B\u043E\u0432", value: extensions, disabled: disabled || !textFiles, placeholder: "md\\ntxt\\nlog", hint: "\u041F\u043E \u043E\u0434\u043D\u043E\u043C\u0443 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044E \u043D\u0430 \u0441\u0442\u0440\u043E\u043A\u0443, \u0431\u0435\u0437 \u0442\u043E\u0447\u043A\u0438. \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u0435\u0442\u0441\u044F \u0432\u0441\u0451, \u0447\u0442\u043E \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043F\u043E\u043C\u0435\u0447\u0430\u0435\u0442 \u043A\u0430\u043A text/*.", parse: parseCommaList, onCommit: (values) => {
43
+ props.write(["attachments", "extensions"], values);
44
+ } }), _jsx(Notice, { tone: "info", children: "\u0424\u0430\u0439\u043B \u0441\u043E\u0445\u0440\u0430\u043D\u044F\u0435\u0442\u0441\u044F \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043A\u0430\u043A \u0435\u0441\u0442\u044C, \u0430 \u0432 \u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0435 \u043C\u043E\u0434\u0435\u043B\u0438 \u0443\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442\u0441\u044F \u043F\u0443\u0442\u044C \u043A \u043A\u043E\u043F\u0438\u0438: \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0435 \u0447\u0438\u0442\u0430\u0435\u0442 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442 \u0447\u0442\u0435\u043D\u0438\u044F. \u0414\u0435\u0440\u0436\u0438\u0442\u0435 \u00ABread\u00BB \u0432 \u0441\u043F\u0438\u0441\u043A\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043D\u043D\u044B\u0445 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u043E\u0432, \u0438\u043D\u0430\u0447\u0435 \u0432\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u043E\u0441\u0442\u0430\u043D\u0435\u0442\u0441\u044F \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u043C \u0434\u043B\u044F \u043C\u043E\u0434\u0435\u043B\u0438." })] }));
45
+ }
46
+ //# sourceMappingURL=attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../../../src/client/settings/sections/attachments.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Branding: pure copy the visitor reads, so nothing here constrains what the
4
+ * Host accepts — every field is free-form and safe to leave empty.
5
+ */
6
+ import { Notice, Section, TextField } from "../fields.js";
7
+ import { overriddenAny, resetAside, } from "./common.js";
8
+ /** Titles, welcome copy, and the notice under the composer. */
9
+ export function BrandingSection(props) {
10
+ const config = props.config;
11
+ const disabled = !props.writable;
12
+ const paths = [["branding"]];
13
+ const modified = overriddenAny(props, paths);
14
+ return (_jsxs(Section, { title: "\u041E\u0444\u043E\u0440\u043C\u043B\u0435\u043D\u0438\u0435", modified: modified, aside: resetAside(props, paths), children: [_jsxs("div", { className: "qa-card-grid", children: [_jsx(TextField, { label: "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435", value: config?.branding?.title ?? "", disabled: disabled, placeholder: "\u041F\u043E\u043C\u043E\u0449\u043D\u0438\u043A", hint: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435 \u0438 \u0432 \u0438\u0441\u0442\u043E\u0440\u0438\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430.", onChange: (value) => {
15
+ props.write(["branding", "title"], value);
16
+ } }), _jsx(TextField, { label: "\u041F\u043E\u0434\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A", value: config?.branding?.subtitle ?? "", disabled: disabled, hint: "\u0421\u0442\u0440\u043E\u043A\u0430 \u043F\u043E\u0434 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435\u043C; \u043F\u0443\u0441\u0442\u043E \u2014 \u0431\u0435\u0437 \u043F\u043E\u0434\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430.", onChange: (value) => {
17
+ props.write(["branding", "subtitle"], value);
18
+ } }), _jsx(TextField, { label: "\u041F\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435", value: config?.branding?.welcomeMessage ?? "", disabled: disabled, hint: "\u041F\u0435\u0440\u0432\u043E\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0432 \u043F\u0443\u0441\u0442\u043E\u043C \u0447\u0430\u0442\u0435.", onChange: (value) => {
19
+ props.write(["branding", "welcomeMessage"], value);
20
+ } }), _jsx(TextField, { label: "\u041F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0430 \u0432 \u043F\u043E\u043B\u0435 \u0432\u0432\u043E\u0434\u0430", value: config?.branding?.placeholder ?? "", disabled: disabled, hint: "\u0422\u0435\u043A\u0441\u0442-\u0437\u0430\u0433\u043B\u0443\u0448\u043A\u0430 \u0432 \u0441\u0442\u0440\u043E\u043A\u0435 \u0432\u043E\u043F\u0440\u043E\u0441\u0430.", onChange: (value) => {
21
+ props.write(["branding", "placeholder"], value);
22
+ } }), _jsx(TextField, { label: "\u0410\u0434\u0440\u0435\u0441 \u043B\u043E\u0433\u043E\u0442\u0438\u043F\u0430", value: config?.branding?.logoUrl ?? "", disabled: disabled, placeholder: "https://\u2026/logo.svg", hint: "\u041F\u0443\u0441\u0442\u043E \u2014 \u0431\u0435\u0437 \u043B\u043E\u0433\u043E\u0442\u0438\u043F\u0430. \u041A\u0430\u0440\u0442\u0438\u043D\u043A\u0430 \u0433\u0440\u0443\u0437\u0438\u0442\u0441\u044F \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043E\u043C \u043F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u044F, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u0432\u043D\u0435\u0448\u043D\u0438\u0439 \u0430\u0434\u0440\u0435\u0441 \u0432\u0438\u0434\u0435\u043D \u0435\u043C\u0443 \u0438 \u0435\u0433\u043E \u0441\u0435\u0442\u0438.", onChange: (value) => {
23
+ props.write(["branding", "logoUrl"], value);
24
+ } })] }), _jsx(TextField, { label: "\u041F\u043B\u0430\u0448\u043A\u0430 \u043E \u0434\u0430\u043D\u043D\u044B\u0445", value: config?.branding?.disclaimer ?? "", disabled: disabled, multiline: true, rows: 3, hint: "\u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442\u0441\u044F \u043F\u043E\u0434 \u0441\u0442\u0440\u043E\u043A\u043E\u0439 \u0432\u0432\u043E\u0434\u0430. \u041F\u0443\u0441\u0442\u043E\u0435 \u043F\u043E\u043B\u0435 \u0441\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u043F\u043B\u0430\u0448\u043A\u0443: \u0442\u043E\u0433\u0434\u0430 \u043E \u0432\u0438\u0434\u0438\u043C\u043E\u0441\u0442\u0438 \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432 \u0438 \u0438\u0445 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0438 \u0441\u043E\u043E\u0431\u0449\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u043C.", onChange: (value) => {
25
+ props.write(["branding", "disclaimer"], value);
26
+ } }), (config?.branding?.disclaimer ?? "") === "" ? (_jsx(Notice, { tone: "warn", children: "\u041F\u043B\u0430\u0448\u043A\u0430 \u043E \u0434\u0430\u043D\u043D\u044B\u0445 \u0441\u043A\u0440\u044B\u0442\u0430. \u0414\u0438\u0430\u043B\u043E\u0433\u0438 \u043C\u043E\u0433\u0443\u0442 \u0431\u044B\u0442\u044C \u0432\u0438\u0434\u043D\u044B \u0434\u0440\u0443\u0433\u0438\u043C \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F\u043C \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C\u0441\u044F \u0434\u043B\u044F \u0443\u043B\u0443\u0447\u0448\u0435\u043D\u0438\u044F \u043E\u0442\u0432\u0435\u0442\u043E\u0432 \u2014 \u043F\u0440\u0435\u0434\u0443\u043F\u0440\u0435\u0434\u0438\u0442\u0435 \u043E\u0431 \u044D\u0442\u043E\u043C \u0441\u0430\u043C\u0438." })) : null] }));
27
+ }
28
+ //# sourceMappingURL=branding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branding.js","sourceRoot":"","sources":["../../../../src/client/settings/sections/branding.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ResetButton } from "../fields.js";
3
+ /** Whether the user layer overrides any of the paths the section owns. */
4
+ export function overriddenAny(props, paths) {
5
+ return paths.some((path) => props.overridden(path));
6
+ }
7
+ /**
8
+ * The reset control beside a section whose paths the user layer overrides:
9
+ * one button clearing every path of the section, disabled while the settings
10
+ * namespace itself is read-only.
11
+ */
12
+ export function resetAside(props, paths) {
13
+ if (!overriddenAny(props, paths))
14
+ return undefined;
15
+ return (_jsx(ResetButton, { disabled: !props.writable, label: "\u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C", onClick: () => {
16
+ for (const path of paths)
17
+ props.unset(path);
18
+ } }));
19
+ }
20
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../../src/client/settings/sections/common.tsx"],"names":[],"mappings":";AAWA,OAAO,EAAE,WAAW,EAAqB,MAAM,cAAc,CAAC;AAe9D,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAC3B,KAAkB,EAClB,KAAmB;IAEnB,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAkB,EAAE,KAAmB;IAChE,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACnD,OAAO,CACL,KAAC,WAAW,IACV,QAAQ,EAAE,CAAC,KAAK,CAAC,QAAQ,EACzB,KAAK,EAAC,kDAAU,EAChB,OAAO,EAAE,GAAG,EAAE;YACZ,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9C,CAAC,GACD,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Embedding: one CSP field with a wide blast radius — an overly generous
4
+ * frame-ancestors list lets any listed site run this page as its own UI.
5
+ */
6
+ import { Notice, Section, TextField } from "../fields.js";
7
+ import { overriddenAny, resetAside, } from "./common.js";
8
+ /** Embedding the page into another site's frame. */
9
+ export function EmbeddingSection(props) {
10
+ const config = props.config;
11
+ const disabled = !props.writable;
12
+ const frameAncestors = config?.embedding?.frameAncestors ?? "";
13
+ const paths = [["embedding"]];
14
+ const modified = overriddenAny(props, paths);
15
+ return (_jsxs(Section, { title: "\u0412\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043D\u0438\u0435", modified: modified, aside: resetAside(props, paths), children: [_jsx(TextField, { label: "\u0418\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0438 \u0434\u043B\u044F iframe", value: frameAncestors, disabled: disabled, placeholder: "https://portal.example", hint: "\u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430 Content-Security-Policy: frame-ancestors. \u041F\u0443\u0441\u0442\u043E \u2014 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u043D\u0435\u043B\u044C\u0437\u044F \u0432\u0441\u0442\u0440\u043E\u0438\u0442\u044C \u0432 \u0447\u0443\u0436\u043E\u0439 \u0444\u0440\u0435\u0439\u043C.", onChange: (value) => {
16
+ props.write(["embedding", "frameAncestors"], value);
17
+ } }), frameAncestors !== "" ? (_jsxs(Notice, { tone: "warn", children: ["\u0412\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043D\u0438\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u043E \u0434\u043B\u044F \u00AB", frameAncestors, "\u00BB. \u042D\u0442\u0438 \u0441\u0430\u0439\u0442\u044B \u0441\u043C\u043E\u0433\u0443\u0442 \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A\u0430 \u0432 \u0441\u0432\u043E\u0451\u043C \u0444\u0440\u0435\u0439\u043C\u0435; \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044C, \u0447\u0442\u043E \u0441\u043F\u0438\u0441\u043E\u043A \u0443\u0437\u043A\u0438\u0439."] })) : null] }));
18
+ }
19
+ //# sourceMappingURL=embedding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.js","sourceRoot":"","sources":["../../../../src/client/settings/sections/embedding.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EACL,aAAa,EACb,UAAU,GAGX,MAAM,aAAa,CAAC;AAErB,oDAAoD;AACpD,MAAM,UAAU,gBAAgB,CAAC,KAAkB;IACjD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;IACjC,MAAM,cAAc,GAAG,MAAM,EAAE,SAAS,EAAE,cAAc,IAAI,EAAE,CAAC;IAC/D,MAAM,KAAK,GAAiB,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC7C,OAAO,CACL,MAAC,OAAO,IACN,KAAK,EAAC,oEAAa,EACnB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,aAE/B,KAAC,SAAS,IACR,KAAK,EAAC,kFAAsB,EAC5B,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAC,wBAAwB,EACpC,IAAI,EAAC,sYAA8G,EACnH,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;oBAClB,KAAK,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,gBAAgB,CAAC,EAAE,KAAK,CAAC,CAAC;gBACtD,CAAC,GACD,EACD,cAAc,KAAK,EAAE,CAAC,CAAC,CAAC,CACvB,MAAC,MAAM,IAAC,IAAI,EAAC,MAAM,oKACW,cAAc,2dAGnC,CACV,CAAC,CAAC,CAAC,IAAI,IACA,CACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Interface: what the visitor sees of the conversation. The show-reset toggle
4
+ * stays disabled while the lockdown section withholds session reset — the
5
+ * Host refuses one without the other.
6
+ */
7
+ import { DEFAULT_THINKING_PHRASES } from "../../../thinking-phrases.js";
8
+ import { ListField, Notice, NumberField, Section, Toggle } from "../fields.js";
9
+ import { parseLineList } from "../format.js";
10
+ import { overriddenAny, resetAside, } from "./common.js";
11
+ /** What the visitor sees of the conversation. */
12
+ export function InterfaceSection(props) {
13
+ const config = props.config;
14
+ const disabled = !props.writable;
15
+ const lockdownEnabled = config?.lockdown?.enabled ?? true;
16
+ const allowReset = config?.lockdown?.allowSessionReset ?? false;
17
+ const resetBlocked = lockdownEnabled && !allowReset;
18
+ const reasoning = config?.ui?.showReasoning ?? false;
19
+ const tools = config?.ui?.showToolActivity ?? false;
20
+ const paths = [
21
+ ["ui"],
22
+ ["suggestedQuestions"],
23
+ ["thinkingPhrases"],
24
+ ];
25
+ const modified = overriddenAny(props, paths);
26
+ const storedPhrases = config?.thinkingPhrases;
27
+ // The field shows the list that is actually in effect: a stored list wins,
28
+ // and otherwise the Host's resolved list stands in for it, so an untouched
29
+ // deployment sees its running phrases instead of an empty box. The built-in
30
+ // list is the last resort, before the Remote has answered.
31
+ const phrases = storedPhrases !== undefined && storedPhrases.length > 0
32
+ ? storedPhrases
33
+ : (props.effective?.thinkingPhrases ?? DEFAULT_THINKING_PHRASES);
34
+ return (_jsxs(Section, { title: "\u0418\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441", modified: modified, aside: resetAside(props, paths), children: [_jsxs("div", { className: "qa-card-grid", children: [_jsx(Toggle, { checked: config?.ui?.showHeader ?? true, disabled: disabled, label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B", hint: "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0438 \u043F\u043E\u0434\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0432 \u0432\u0435\u0440\u0445\u043D\u0435\u0439 \u043F\u043E\u043B\u043E\u0441\u0435.", onChange: (value) => {
35
+ props.write(["ui", "showHeader"], value);
36
+ } }), _jsx(Toggle, { checked: config?.ui?.showStop ?? true, disabled: disabled, label: "\u041A\u043D\u043E\u043F\u043A\u0430 \u043E\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438", hint: "\u041F\u043E\u0437\u0432\u043E\u043B\u044F\u0435\u0442 \u043F\u0440\u0435\u0440\u0432\u0430\u0442\u044C \u043E\u0442\u0432\u0435\u0442 \u0434\u043E \u0435\u0433\u043E \u043A\u043E\u043D\u0446\u0430.", onChange: (value) => {
37
+ props.write(["ui", "showStop"], value);
38
+ } }), _jsx(Toggle, { checked: config?.ui?.showReset ?? false, disabled: disabled || resetBlocked, label: "\u041A\u043D\u043E\u043F\u043A\u0430 \u043D\u043E\u0432\u043E\u0433\u043E \u0447\u0430\u0442\u0430", hint: resetBlocked
39
+ ? "Требует «Разрешить сброс сессии» в разделе блокировки: без него хост отвергает конфигурацию."
40
+ : "Создаёт новый чат, не покидая страницу.", onChange: (value) => {
41
+ props.write(["ui", "showReset"], value);
42
+ } }), _jsx(Toggle, { checked: config?.ui?.showTimestamps ?? false, disabled: disabled, label: "\u0412\u0440\u0435\u043C\u044F \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439", hint: "\u041E\u0442\u043C\u0435\u0442\u043A\u0430 \u0432\u0440\u0435\u043C\u0435\u043D\u0438 \u0443 \u043A\u0430\u0436\u0434\u043E\u0433\u043E \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F.", onChange: (value) => {
43
+ props.write(["ui", "showTimestamps"], value);
44
+ } }), _jsx(Toggle, { checked: config?.ui?.renderMarkdown ?? true, disabled: disabled, label: "\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430 \u0432 \u043E\u0442\u0432\u0435\u0442\u0430\u0445", hint: "\u041E\u0442\u0432\u0435\u0442\u044B \u0440\u0435\u043D\u0434\u0435\u0440\u044F\u0442\u0441\u044F \u043A\u0430\u043A Markdown, \u0430 \u043D\u0435 \u043A\u0430\u043A \u043E\u0431\u044B\u0447\u043D\u044B\u0439 \u0442\u0435\u043A\u0441\u0442.", onChange: (value) => {
45
+ props.write(["ui", "renderMarkdown"], value);
46
+ } }), _jsx(Toggle, { checked: config?.ui?.showSessionList ?? false, disabled: disabled, label: "\u0421\u043F\u0438\u0441\u043E\u043A \u0447\u0430\u0442\u043E\u0432", hint: "\u0411\u043E\u043A\u043E\u0432\u0430\u044F \u0438\u0441\u0442\u043E\u0440\u0438\u044F \u0447\u0430\u0442\u043E\u0432 \u044D\u0442\u043E\u0433\u043E \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430; \u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435 \u0447\u0430\u0442\u0430 \u0437\u0430\u043D\u043E\u0432\u043E \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442 \u043F\u043E\u043B\u0438\u0442\u0438\u043A\u0443.", onChange: (value) => {
47
+ props.write(["ui", "showSessionList"], value);
48
+ } }), _jsx(Toggle, { checked: reasoning, disabled: disabled, label: "\u0420\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043D\u0438\u044F \u043C\u043E\u0434\u0435\u043B\u0438", hint: "\u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u0445\u043E\u0434 \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043D\u0438\u0439 \u0432 \u0441\u0432\u0451\u0440\u043D\u0443\u0442\u043E\u043C \u0431\u043B\u043E\u043A\u0435.", onChange: (value) => {
49
+ props.write(["ui", "showReasoning"], value);
50
+ } }), _jsx(Toggle, { checked: tools, disabled: disabled, label: "\u0412\u044B\u0437\u043E\u0432\u044B \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u043E\u0432", hint: "\u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442, \u043A\u0430\u043A\u0438\u0435 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u044B \u0432\u044B\u0437\u044B\u0432\u0430\u043B\u0438\u0441\u044C \u0438 \u0441 \u0447\u0435\u043C.", onChange: (value) => {
51
+ props.write(["ui", "showToolActivity"], value);
52
+ } }), _jsx(NumberField, { label: "\u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0433\u043E, px", value: config?.ui?.minContentWidth ?? 650, min: 480, max: 1600, disabled: disabled, hint: "\u041D\u0438\u0436\u043D\u044F\u044F \u0433\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B \u043F\u0435\u0440\u0435\u043F\u0438\u0441\u043A\u0438; \u0448\u0438\u0440\u0435 \u043F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u044C \u0440\u0430\u0441\u0448\u0438\u0440\u044F\u0435\u0442 \u0435\u0451 \u0441\u0430\u043C \u2014 \u0434\u043E \u043A\u0440\u0430\u0451\u0432 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B.", onChange: (value) => {
53
+ props.write(["ui", "minContentWidth"], value);
54
+ } })] }), reasoning || tools ? (_jsx(Notice, { tone: "warn", children: "\u0420\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043D\u0438\u044F \u043C\u043E\u0434\u0435\u043B\u0438 \u0438 \u0432\u044B\u0437\u043E\u0432\u044B \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u0441\u0442\u0430\u043D\u043E\u0432\u044F\u0442\u0441\u044F \u0432\u0438\u0434\u043D\u044B \u043A\u043E\u043D\u0435\u0447\u043D\u044B\u043C \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F\u043C. \u0412\u043A\u043B\u044E\u0447\u0430\u0439\u0442\u0435 \u0438\u0445 \u0442\u0430\u043C, \u0433\u0434\u0435 \u0442\u0430\u043A\u043E\u0435 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0435 \u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u043E." })) : null, _jsx(ListField, { label: "\u0411\u044B\u0441\u0442\u0440\u044B\u0435 \u0432\u043E\u043F\u0440\u043E\u0441\u044B", value: config?.suggestedQuestions ?? [], disabled: disabled, placeholder: "Что ты умеешь?\nС чего начать?", hint: "\u041F\u043E \u043E\u0434\u043D\u043E\u043C\u0443 \u0432\u043E\u043F\u0440\u043E\u0441\u0443 \u043D\u0430 \u0441\u0442\u0440\u043E\u043A\u0443: \u043A\u043D\u043E\u043F\u043A\u0438-\u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0438 \u043D\u0430\u0434 \u0441\u0442\u0440\u043E\u043A\u043E\u0439 \u0432\u0432\u043E\u0434\u0430. \u041F\u0443\u0441\u0442\u043E\u0439 \u0441\u043F\u0438\u0441\u043E\u043A \u0443\u0431\u0438\u0440\u0430\u0435\u0442 \u0438\u0445.", parse: parseLineList, onCommit: (values) => {
55
+ props.write(["suggestedQuestions"], values);
56
+ } }), _jsx(ListField, { label: "\u0424\u0440\u0430\u0437\u044B \u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F", value: phrases, disabled: disabled, placeholder: "Думаю…\nСобираю ответ…", hint: "\u041F\u043E \u043E\u0434\u043D\u043E\u0439 \u0444\u0440\u0430\u0437\u0435 \u043D\u0430 \u0441\u0442\u0440\u043E\u043A\u0443: \u0438\u0445 \u0441\u043C\u0435\u043D\u044F\u0435\u0442 \u0438\u043D\u0434\u0438\u043A\u0430\u0442\u043E\u0440, \u043F\u043E\u043A\u0430 \u043C\u043E\u0434\u0435\u043B\u044C \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442. \u041F\u0443\u0441\u0442\u043E\u0439 \u0441\u043F\u0438\u0441\u043E\u043A \u0432\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0435 \u0444\u0440\u0430\u0437\u044B \u2014 \u0438\u043D\u0434\u0438\u043A\u0430\u0442\u043E\u0440 \u0432\u0441\u0435\u0433\u0434\u0430 \u0447\u0442\u043E-\u0442\u043E \u0433\u043E\u0432\u043E\u0440\u0438\u0442.", parse: parseLineList, onCommit: (values) => {
57
+ props.write(["thinkingPhrases"], values);
58
+ } })] }));
59
+ }
60
+ //# sourceMappingURL=interface.js.map