@anweat/dsh-browser 0.2.1 → 0.2.2

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 (169) hide show
  1. package/README.md +267 -69
  2. package/assets/skills/dsh-browser/SKILL.md +13 -11
  3. package/assets/skills/dsh-browser/references/files.md +36 -0
  4. package/assets/skills/dsh-browser/references/observe.md +2 -2
  5. package/assets/skills/dsh-browser/references/policy.md +32 -0
  6. package/cordis.patch.yml +10 -3
  7. package/lib/actions/errors.js +7 -2
  8. package/lib/actions/errors.js.map +1 -1
  9. package/lib/actions/index-view.d.ts +4 -1
  10. package/lib/actions/index-view.js +16 -3
  11. package/lib/actions/index-view.js.map +1 -1
  12. package/lib/actions/inspect.js +15 -0
  13. package/lib/actions/inspect.js.map +1 -1
  14. package/lib/actions/observe.js +1 -1
  15. package/lib/actions/observe.js.map +1 -1
  16. package/lib/actions/opencli.d.ts +1 -1
  17. package/lib/actions/opencli.js +4 -4
  18. package/lib/actions/opencli.js.map +1 -1
  19. package/lib/actions/policy.d.ts +15 -0
  20. package/lib/actions/policy.js +131 -0
  21. package/lib/actions/policy.js.map +1 -0
  22. package/lib/actions/registry.js +6 -5
  23. package/lib/actions/registry.js.map +1 -1
  24. package/lib/actions/runtime.js +2 -2
  25. package/lib/actions/runtime.js.map +1 -1
  26. package/lib/actions/target.js +35 -3
  27. package/lib/actions/target.js.map +1 -1
  28. package/lib/actions/types.d.ts +1 -1
  29. package/lib/actions/types.js.map +1 -1
  30. package/lib/approval-policy.d.ts +10 -1
  31. package/lib/approval-policy.js +42 -1
  32. package/lib/approval-policy.js.map +1 -1
  33. package/lib/auth-profiles.d.ts +4 -1
  34. package/lib/auth-profiles.js +3 -0
  35. package/lib/auth-profiles.js.map +1 -1
  36. package/lib/automation-assets-rpc.js +26 -0
  37. package/lib/automation-assets-rpc.js.map +1 -1
  38. package/lib/browser-service.d.ts +165 -4
  39. package/lib/browser-service.js +505 -55
  40. package/lib/browser-service.js.map +1 -1
  41. package/lib/client/SettingsCard.d.ts +10 -8
  42. package/lib/client/SettingsCard.js +12 -137
  43. package/lib/client/SettingsCard.js.map +1 -1
  44. package/lib/client/auth-profiles-form.d.ts +23 -0
  45. package/lib/client/auth-profiles-form.js +64 -0
  46. package/lib/client/auth-profiles-form.js.map +1 -0
  47. package/lib/client/card-frame.d.ts +22 -0
  48. package/lib/client/card-frame.js +61 -0
  49. package/lib/client/card-frame.js.map +1 -0
  50. package/lib/client/field-rows.d.ts +59 -0
  51. package/lib/client/field-rows.js +63 -0
  52. package/lib/client/field-rows.js.map +1 -0
  53. package/lib/client/field-rules.d.ts +17 -0
  54. package/lib/client/field-rules.js +68 -0
  55. package/lib/client/field-rules.js.map +1 -0
  56. package/lib/client/form.d.ts +108 -7
  57. package/lib/client/form.js +255 -11
  58. package/lib/client/form.js.map +1 -1
  59. package/lib/client/group-access.d.ts +14 -0
  60. package/lib/client/group-access.js +97 -0
  61. package/lib/client/group-access.js.map +1 -0
  62. package/lib/client/group-advanced.d.ts +11 -0
  63. package/lib/client/group-advanced.js +32 -0
  64. package/lib/client/group-advanced.js.map +1 -0
  65. package/lib/client/group-assets.d.ts +13 -0
  66. package/lib/client/group-assets.js +50 -0
  67. package/lib/client/group-assets.js.map +1 -0
  68. package/lib/client/group-browser.d.ts +9 -0
  69. package/lib/client/group-browser.js +27 -0
  70. package/lib/client/group-browser.js.map +1 -0
  71. package/lib/client/group-common.d.ts +10 -0
  72. package/lib/client/group-common.js +21 -0
  73. package/lib/client/group-common.js.map +1 -0
  74. package/lib/client/group-context.d.ts +20 -0
  75. package/lib/client/group-context.js +76 -0
  76. package/lib/client/group-context.js.map +1 -0
  77. package/lib/client/group-downloads.d.ts +10 -0
  78. package/lib/client/group-downloads.js +33 -0
  79. package/lib/client/group-downloads.js.map +1 -0
  80. package/lib/client/group-limits.d.ts +9 -0
  81. package/lib/client/group-limits.js +57 -0
  82. package/lib/client/group-limits.js.map +1 -0
  83. package/lib/client/group-prompts.d.ts +13 -0
  84. package/lib/client/group-prompts.js +136 -0
  85. package/lib/client/group-prompts.js.map +1 -0
  86. package/lib/client/index.d.ts +21 -1
  87. package/lib/client/index.js +10 -4
  88. package/lib/client/index.js.map +1 -1
  89. package/lib/client/locales-policy.d.ts +83 -0
  90. package/lib/client/locales-policy.js +46 -0
  91. package/lib/client/locales-policy.js.map +1 -0
  92. package/lib/client/locales-prompts.d.ts +57 -0
  93. package/lib/client/locales-prompts.js +41 -0
  94. package/lib/client/locales-prompts.js.map +1 -0
  95. package/lib/client/locales-ui.d.ts +223 -0
  96. package/lib/client/locales-ui.js +157 -0
  97. package/lib/client/locales-ui.js.map +1 -0
  98. package/lib/client/locales.d.ts +359 -67
  99. package/lib/client/locales.js +68 -22
  100. package/lib/client/locales.js.map +1 -1
  101. package/lib/client/policy-fields.d.ts +31 -0
  102. package/lib/client/policy-fields.js +66 -0
  103. package/lib/client/policy-fields.js.map +1 -0
  104. package/lib/client/policy-status-client.d.ts +91 -0
  105. package/lib/client/policy-status-client.js +64 -0
  106. package/lib/client/policy-status-client.js.map +1 -0
  107. package/lib/client/prompts-form.d.ts +33 -0
  108. package/lib/client/prompts-form.js +87 -0
  109. package/lib/client/prompts-form.js.map +1 -1
  110. package/lib/client/prompts-status-client.d.ts +21 -1
  111. package/lib/client/prompts-status-client.js +36 -4
  112. package/lib/client/prompts-status-client.js.map +1 -1
  113. package/lib/client/properties-form.d.ts +90 -0
  114. package/lib/client/properties-form.js +187 -0
  115. package/lib/client/properties-form.js.map +1 -0
  116. package/lib/client/property-docs.d.ts +18 -0
  117. package/lib/client/property-docs.js +78 -0
  118. package/lib/client/property-docs.js.map +1 -0
  119. package/lib/client/size-units.d.ts +12 -0
  120. package/lib/client/size-units.js +29 -0
  121. package/lib/client/size-units.js.map +1 -0
  122. package/lib/client/styles.d.ts +47 -31
  123. package/lib/client/styles.js +59 -20
  124. package/lib/client/styles.js.map +1 -1
  125. package/lib/client/ui-kit.d.ts +173 -0
  126. package/lib/client/ui-kit.js +112 -0
  127. package/lib/client/ui-kit.js.map +1 -0
  128. package/lib/client.js +5291 -834
  129. package/lib/client.js.map +1 -1
  130. package/lib/config-rules.d.ts +40 -0
  131. package/lib/config-rules.js +103 -0
  132. package/lib/config-rules.js.map +1 -0
  133. package/lib/config.d.ts +64 -2
  134. package/lib/config.js +106 -0
  135. package/lib/config.js.map +1 -1
  136. package/lib/context-options.d.ts +85 -0
  137. package/lib/context-options.js +206 -0
  138. package/lib/context-options.js.map +1 -0
  139. package/lib/deps.d.ts +42 -5
  140. package/lib/deps.js +219 -9
  141. package/lib/deps.js.map +1 -1
  142. package/lib/downloads.d.ts +79 -0
  143. package/lib/downloads.js +189 -0
  144. package/lib/downloads.js.map +1 -0
  145. package/lib/index.d.ts +3 -2
  146. package/lib/index.js +7 -3
  147. package/lib/index.js.map +1 -1
  148. package/lib/policy-keys.d.ts +39 -0
  149. package/lib/policy-keys.js +21 -0
  150. package/lib/policy-keys.js.map +1 -1
  151. package/lib/policy-overlay.d.ts +189 -0
  152. package/lib/policy-overlay.js +649 -0
  153. package/lib/policy-overlay.js.map +1 -0
  154. package/lib/prompts-yaml.d.ts +11 -0
  155. package/lib/prompts-yaml.js +121 -0
  156. package/lib/prompts-yaml.js.map +1 -0
  157. package/lib/prompts.d.ts +2 -0
  158. package/lib/prompts.js +7 -3
  159. package/lib/prompts.js.map +1 -1
  160. package/lib/system-browser.d.ts +61 -0
  161. package/lib/system-browser.js +109 -0
  162. package/lib/system-browser.js.map +1 -0
  163. package/lib/tools.js +9 -1
  164. package/lib/tools.js.map +1 -1
  165. package/lib/usage-policy.d.ts +3 -1
  166. package/lib/usage-policy.js +2 -0
  167. package/lib/usage-policy.js.map +1 -1
  168. package/package.json +42 -38
  169. package/scripts/dump-prompts.mjs +12 -2
@@ -0,0 +1,78 @@
1
+ /**
2
+ * The comments printed in front of every key of the default-parameters text (the "Advanced: text mode" view), in the
3
+ * language of the card: what the setting is for, its allowed values or range, its default, and the risk when there is
4
+ * one. Comment lines start with `#`, which the parser ignores, so they are never data and a round trip keeps every key.
5
+ * Pure, with no DOM: `properties-form.ts` prints with these, the tests read them.
6
+ * @module dsh-browser/client/property-docs
7
+ */
8
+ const EN = {
9
+ header: [
10
+ 'Default parameters: what every new browser context starts from. An agent copies these for a task and changes only what the task needs.',
11
+ '`key = value` overrides the default. A line starting with # is a comment and is ignored when you save; the comment above each key explains it.',
12
+ 'A commented `# key = value` line shows the value in force now. Delete or comment a line to go back to the default.',
13
+ ],
14
+ group: { runtime: 'Browser runtime', context: 'Page environment (window, language, egress)', files: 'Login state, files and limits' },
15
+ key: {
16
+ browserRuntime: 'Driver: playwright | patchright (Chromium only, better against bot checks). Default: playwright',
17
+ channel: 'Browser: chromium (Playwright Chromium; the installed Chrome / Edge is used when it is missing) | chrome | msedge (always that installed browser). Patchright works best with chrome. Default: chromium',
18
+ headless: 'true = no browser window | false = show it. Default: true',
19
+ autoInstall: 'true = download Playwright Chromium when it is missing (about 190 MB download; the system Chrome is then not used instead) | false. Keep false: an installed Chrome / Edge is used directly, else use the runtime.install action. Default: false',
20
+ executablePath: 'Absolute path of a custom browser; empty = Playwright Chromium, or the system Chrome / Edge when it is missing. Default: empty',
21
+ cdpPort: 'Local remote-debugging (CDP) port, 1-65535; empty = off. Risk: other programs on this machine can then control the browser. Default: empty',
22
+ maxSessions: 'Sessions that may hold a page at once, 1-64; past it the least recently used one is closed. Default: 8',
23
+ args: 'Extra Chromium launch arguments as one JSON array line, e.g. ["--disable-gpu"]. Add only arguments you understand. Default: [] (none)',
24
+ viewportMode: 'Viewport: window = browser default | 720p (1280x720) | 1080p (1920x1080) | custom (needs width and height). Default: window',
25
+ viewportWidth: 'Custom viewport width in pixels, 200-7680; used only with viewportMode = custom. Default: empty',
26
+ viewportHeight: 'Custom viewport height in pixels, 200-4320; used only with viewportMode = custom. Default: empty',
27
+ userAgent: 'User-Agent header, up to 512 characters. Risk: changes the browser fingerprint sites see. Empty = the browser\'s own. Default: empty',
28
+ locale: 'Language tag (BCP 47) such as en-US or zh-CN; empty = the browser\'s own. Default: empty',
29
+ timezoneId: 'IANA time zone such as Asia/Shanghai; empty = this machine\'s. Default: empty',
30
+ proxyServer: 'Proxy such as http://127.0.0.1:7890 or socks5://127.0.0.1:1080. No accounts or passwords: never put credentials here. Empty = direct. Default: empty',
31
+ proxyBypass: 'Hosts that skip the proxy, comma-separated, e.g. example.com,.internal.test; needs proxyServer. Default: empty',
32
+ storageStatePath: 'Global login-state file (legacy: applies to every site, no domain limit). Use login profiles instead. Default: empty',
33
+ defaultAuthProfile: 'Name of the login profile used when none is named; it must exist. crawl is always anonymous. Default: empty',
34
+ allowPrivateHosts: 'true = an agent policy action may allow localhost and LAN addresses in a login profile | false. Risk: widens what an agent can authorize. Default: false',
35
+ snapshotDir: 'Absolute directory for screenshots; empty = $DSH_HOME/data/browser/snapshots. Default: empty',
36
+ downloadDir: 'Absolute directory downloads are saved to; empty = $DSH_HOME/data/browser/downloads. Default: empty',
37
+ downloadMaxBytes: 'Largest single download in bytes, 1 to 10737418240 (10 GiB); a bigger one is stopped and removed. Default: 104857600 (100 MiB)',
38
+ verbose: 'true = print startup and diagnostic details | false. Default: false',
39
+ },
40
+ };
41
+ const ZH = {
42
+ header: [
43
+ '默认参数:每个新 browser context 的起点;agent 按任务复制它们,只改任务需要改的部分。',
44
+ '`key = value` 表示覆盖默认值;以 # 开头的行是注释,保存时忽略;每个键上面的注释说明它的用途。',
45
+ '被注释的 `# key = 值` 行显示当前生效的值;删掉或注释一行即恢复默认。',
46
+ ],
47
+ group: { runtime: '浏览器运行时', context: '页面环境(窗口、语言、出口)', files: '登录态、文件与限额' },
48
+ key: {
49
+ browserRuntime: '驱动:playwright | patchright(仅 Chromium,对反爬检测更友好)。默认 playwright',
50
+ channel: '浏览器:chromium(Playwright 的 Chromium,缺失时自动改用本机 Chrome / Edge)| chrome | msedge(固定用本机已装的那个)。Patchright 推荐 chrome。默认 chromium',
51
+ headless: 'true = 不显示浏览器窗口 | false = 显示。默认 true',
52
+ autoInstall: 'true = 缺失时自动下载 Playwright Chromium(下载约 190 MB,且不再改用系统 Chrome)| false。建议保持 false:装了 Chrome / Edge 就直接用,没有再用 runtime.install 动作。默认 false',
53
+ executablePath: '自定义浏览器的绝对路径;留空 = Playwright Chromium,缺失时用系统 Chrome / Edge。默认 空',
54
+ cdpPort: '本机远程调试(CDP)端口,1–65535;留空 = 关闭。风险:同机其它程序可借此控制浏览器。默认 空',
55
+ maxSessions: '同时持有页面的会话数,1–64;超出时关闭最久未使用的。默认 8',
56
+ args: '追加的 Chromium 启动参数,写成一行 JSON 数组,如 ["--disable-gpu"];只加你理解的参数。默认 [](无)',
57
+ viewportMode: '视口:window = 浏览器默认 | 720p(1280x720)| 1080p(1920x1080)| custom(需同时填宽高)。默认 window',
58
+ viewportWidth: '自定义视口宽度(像素),200–7680;仅 viewportMode = custom 时生效。默认 空',
59
+ viewportHeight: '自定义视口高度(像素),200–4320;仅 viewportMode = custom 时生效。默认 空',
60
+ userAgent: 'User-Agent 头,至多 512 字符。风险:会改变站点看到的浏览器指纹;留空 = 浏览器自带。默认 空',
61
+ locale: '语言标签(BCP 47),如 en-US、zh-CN;留空 = 浏览器自带。默认 空',
62
+ timezoneId: 'IANA 时区,如 Asia/Shanghai;留空 = 本机时区。默认 空',
63
+ proxyServer: '代理,如 http://127.0.0.1:7890 或 socks5://127.0.0.1:1080。不支持账号密码,切勿把凭据写在这里;留空 = 直连。默认 空',
64
+ proxyBypass: '不走代理的主机,逗号分隔,如 example.com,.internal.test;需先设 proxyServer。默认 空',
65
+ storageStatePath: '全局登录态文件(旧版入口:对所有站点生效,没有域名限制);请改用登录 profile。默认 空',
66
+ defaultAuthProfile: '未指定时使用的登录 profile 名,必须已存在;crawl 始终匿名。默认 空',
67
+ allowPrivateHosts: 'true = agent 的策略动作可把 localhost 与内网地址加入登录 profile | false。风险:扩大 agent 可授权的范围。默认 false',
68
+ snapshotDir: '截图目录的绝对路径;留空 = $DSH_HOME/data/browser/snapshots。默认 空',
69
+ downloadDir: '下载目录的绝对路径;留空 = $DSH_HOME/data/browser/downloads。默认 空',
70
+ downloadMaxBytes: '单个下载的字节上限,1 到 10737418240(10 GiB);超出会中止并删除。默认 104857600(100 MiB)',
71
+ verbose: 'true = 输出启动与诊断信息 | false。默认 false',
72
+ },
73
+ };
74
+ /** The docs of a language; anything but `zh` is English. */
75
+ export function propertyDocs(lang = 'en') {
76
+ return lang === 'zh' ? ZH : EN;
77
+ }
78
+ //# sourceMappingURL=property-docs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"property-docs.js","sourceRoot":"","sources":["../../src/client/property-docs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH,MAAM,EAAE,GAAiB;IACvB,MAAM,EAAE;QACN,wIAAwI;QACxI,gJAAgJ;QAChJ,oHAAoH;KACrH;IACD,KAAK,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,6CAA6C,EAAE,KAAK,EAAE,+BAA+B,EAAE;IACrI,GAAG,EAAE;QACH,cAAc,EAAE,iGAAiG;QACjH,OAAO,EAAE,yMAAyM;QAClN,QAAQ,EAAE,2DAA2D;QACrE,WAAW,EAAE,kPAAkP;QAC/P,cAAc,EAAE,gIAAgI;QAChJ,OAAO,EAAE,4IAA4I;QACrJ,WAAW,EAAE,wGAAwG;QACrH,IAAI,EAAE,uIAAuI;QAC7I,YAAY,EAAE,6HAA6H;QAC3I,aAAa,EAAE,iGAAiG;QAChH,cAAc,EAAE,kGAAkG;QAClH,SAAS,EAAE,sIAAsI;QACjJ,MAAM,EAAE,0FAA0F;QAClG,UAAU,EAAE,+EAA+E;QAC3F,WAAW,EAAE,sJAAsJ;QACnK,WAAW,EAAE,gHAAgH;QAC7H,gBAAgB,EAAE,sHAAsH;QACxI,kBAAkB,EAAE,6GAA6G;QACjI,iBAAiB,EAAE,0JAA0J;QAC7K,WAAW,EAAE,8FAA8F;QAC3G,WAAW,EAAE,qGAAqG;QAClH,gBAAgB,EAAE,gIAAgI;QAClJ,OAAO,EAAE,qEAAqE;KAC/E;CACF,CAAA;AAED,MAAM,EAAE,GAAiB;IACvB,MAAM,EAAE;QACN,wDAAwD;QACxD,yDAAyD;QACzD,0CAA0C;KAC3C;IACD,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,WAAW,EAAE;IAC3E,GAAG,EAAE;QACH,cAAc,EAAE,+DAA+D;QAC/E,OAAO,EAAE,2HAA2H;QACpI,QAAQ,EAAE,sCAAsC;QAChD,WAAW,EAAE,wIAAwI;QACrJ,cAAc,EAAE,gEAAgE;QAChF,OAAO,EAAE,sDAAsD;QAC/D,WAAW,EAAE,kCAAkC;QAC/C,IAAI,EAAE,sEAAsE;QAC5E,YAAY,EAAE,gFAAgF;QAC9F,aAAa,EAAE,uDAAuD;QACtE,cAAc,EAAE,uDAAuD;QACvE,SAAS,EAAE,yDAAyD;QACpE,MAAM,EAAE,4CAA4C;QACpD,UAAU,EAAE,wCAAwC;QACpD,WAAW,EAAE,qFAAqF;QAClG,WAAW,EAAE,gEAAgE;QAC7E,gBAAgB,EAAE,iDAAiD;QACnE,kBAAkB,EAAE,2CAA2C;QAC/D,iBAAiB,EAAE,sFAAsF;QACzG,WAAW,EAAE,sDAAsD;QACnE,WAAW,EAAE,sDAAsD;QACnE,gBAAgB,EAAE,kEAAkE;QACpF,OAAO,EAAE,mCAAmC;KAC7C;CACF,CAAA;AAED,4DAA4D;AAC5D,MAAM,UAAU,YAAY,CAAC,OAAyB,IAAI;IACxD,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;AAChC,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Byte counts as a number in a unit, for the download size control. The setting itself stays a plain byte count.
3
+ * @module dsh-browser/client/size-units
4
+ */
5
+ export declare const SIZE_UNITS: readonly [readonly ["B", 1], readonly ["KiB", 1024], readonly ["MiB", number], readonly ["GiB", number]];
6
+ export type SizeUnit = typeof SIZE_UNITS[number][0];
7
+ /** The unit a byte count is shown in: the largest that divides it exactly (MiB when there is no count). */
8
+ export declare function unitFor(bytes: number | undefined): SizeUnit;
9
+ /** A byte count as the text of one unit, without a trailing ".0". */
10
+ export declare function bytesToUnitText(bytes: number, unit: SizeUnit): string;
11
+ /** The bytes a number typed in a unit stands for: '' for an empty text ("unset"), undefined when it is not a positive number. */
12
+ export declare function unitTextToBytes(text: string, unit: SizeUnit): number | '' | undefined;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Byte counts as a number in a unit, for the download size control. The setting itself stays a plain byte count.
3
+ * @module dsh-browser/client/size-units
4
+ */
5
+ export const SIZE_UNITS = [['B', 1], ['KiB', 1024], ['MiB', 1024 ** 2], ['GiB', 1024 ** 3]];
6
+ const factor = (unit) => SIZE_UNITS.find(([name]) => name === unit)[1];
7
+ /** The unit a byte count is shown in: the largest that divides it exactly (MiB when there is no count). */
8
+ export function unitFor(bytes) {
9
+ if (bytes === undefined || !Number.isFinite(bytes) || bytes <= 0)
10
+ return 'MiB';
11
+ for (const [name, size] of [...SIZE_UNITS].reverse())
12
+ if (bytes % size === 0)
13
+ return name;
14
+ return 'B';
15
+ }
16
+ /** A byte count as the text of one unit, without a trailing ".0". */
17
+ export function bytesToUnitText(bytes, unit) {
18
+ return String(bytes / factor(unit));
19
+ }
20
+ /** The bytes a number typed in a unit stands for: '' for an empty text ("unset"), undefined when it is not a positive number. */
21
+ export function unitTextToBytes(text, unit) {
22
+ if (text.trim() === '')
23
+ return '';
24
+ const value = Number(text);
25
+ if (!Number.isFinite(value) || value <= 0)
26
+ return undefined;
27
+ return Math.round(value * factor(unit));
28
+ }
29
+ //# sourceMappingURL=size-units.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"size-units.js","sourceRoot":"","sources":["../../src/client/size-units.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,CAAC,CAAU,CAAA;AAGpG,MAAM,MAAM,GAAG,CAAC,IAAc,EAAU,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAE,CAAC,CAAC,CAAC,CAAA;AAEzF,2GAA2G;AAC3G,MAAM,UAAU,OAAO,CAAC,KAAyB;IAC/C,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IAC9E,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC,OAAO,EAAE;QAAE,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;IACzF,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,IAAc;IAC3D,OAAO,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;AACrC,CAAC;AAED,iIAAiI;AACjI,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,IAAc;IAC1D,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,CAAA;IACjC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,SAAS,CAAA;IAC3D,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;AACzC,CAAC"}
@@ -1,48 +1,64 @@
1
1
  export declare const styles: {
2
- readonly card: "dsb-card";
3
- readonly open: "dsb-open";
4
- readonly header: "dsb-header";
5
- readonly head: "dsb-head";
6
- readonly titleRow: "dsb-title-row";
7
- readonly name: "dsb-name";
8
- readonly description: "dsb-description";
9
- readonly badge: "dsb-badge";
10
- readonly chevron: "dsb-chevron";
11
- readonly chevronOpen: "dsb-chevron-open";
12
- readonly body: "dsb-body";
13
2
  readonly notice: "dsb-notice";
14
- readonly section: "dsb-section";
15
- readonly sectionHead: "dsb-section-head";
16
- readonly grid: "dsb-grid";
17
3
  readonly field: "dsb-field";
18
- readonly invalid: "dsb-invalid";
19
4
  readonly fieldHead: "dsb-field-head";
20
5
  readonly label: "dsb-label";
21
6
  readonly hint: "dsb-hint";
22
7
  readonly input: "dsb-input";
23
8
  readonly textarea: "dsb-textarea";
24
9
  readonly code: "dsb-code";
25
- readonly reset: "dsb-reset";
26
- readonly toggle: "dsb-toggle";
27
- readonly toggleLabel: "dsb-toggle-label";
28
- readonly check: "dsb-check";
29
- readonly advanced: "dsb-advanced";
30
- readonly footer: "dsb-footer";
31
- readonly status: "dsb-status";
32
10
  readonly failed: "dsb-failed";
33
11
  readonly actions: "dsb-actions";
34
- readonly primary: "dsb-primary";
35
- readonly secondary: "dsb-secondary";
36
- readonly assetGroup: "dsb-asset-group";
37
- readonly assetRow: "dsb-asset-row";
12
+ readonly root: "dsb-root";
13
+ readonly summaryBar: "dsb-summary";
14
+ readonly chips: "dsb-chips";
15
+ readonly chip: "dsb-chip";
16
+ readonly chipRemove: "dsb-chip-remove";
17
+ readonly chipInput: "dsb-chip-input";
18
+ readonly group: "dsb-group";
19
+ readonly groupHead: "dsb-group-head";
20
+ readonly groupTitle: "dsb-group-title";
21
+ readonly groupSub: "dsb-group-sub";
22
+ readonly groupBadges: "dsb-group-badges";
23
+ readonly groupBody: "dsb-group-body";
24
+ readonly row: "dsb-row";
25
+ readonly rowText: "dsb-row-text";
26
+ readonly rowLabel: "dsb-row-label";
27
+ readonly rowControl: "dsb-row-control";
28
+ readonly rowHint: "dsb-row-hint";
29
+ readonly rowMeta: "dsb-row-meta";
30
+ readonly muted: "dsb-muted";
31
+ readonly select: "dsb-select";
32
+ readonly unitInput: "dsb-unit-input";
33
+ readonly unit: "dsb-unit";
34
+ readonly help: "dsb-help";
35
+ readonly link: "dsb-link";
36
+ readonly danger: "dsb-danger";
37
+ readonly list: "dsb-list";
38
+ readonly item: "dsb-item";
39
+ readonly itemMain: "dsb-item-main";
40
+ readonly itemTitle: "dsb-item-title";
41
+ readonly itemMeta: "dsb-item-meta";
42
+ readonly itemActions: "dsb-item-actions";
43
+ readonly empty: "dsb-empty";
44
+ readonly subHead: "dsb-sub-head";
45
+ readonly compare: "dsb-compare";
46
+ readonly compareCol: "dsb-compare-col";
47
+ readonly preview: "dsb-preview";
48
+ readonly savebar: "dsb-savebar";
49
+ readonly saveText: "dsb-save-text";
50
+ readonly dialogBody: "dsb-dialog-body";
51
+ readonly stack: "dsb-stack";
52
+ readonly fold: "dsb-fold";
53
+ readonly foldBody: "dsb-fold-body";
54
+ readonly foldHint: "dsb-fold-hint";
38
55
  readonly assetToolbar: "dsb-asset-toolbar";
39
- readonly assetLayout: "dsb-asset-layout";
40
- readonly assetList: "dsb-asset-list";
41
- readonly assetItem: "dsb-asset-item";
42
- readonly assetSelected: "dsb-asset-selected";
43
- readonly assetTest: "dsb-asset-test";
44
56
  readonly assetTestForm: "dsb-asset-test-form";
45
57
  readonly assetEditor: "dsb-asset-editor";
46
58
  readonly invalidInput: "dsb-invalid-input";
47
59
  };
60
+ /**
61
+ * Inject the card's stylesheet, or refresh it in place. A Host that hot-reloads the plugin keeps the page (and the
62
+ * `<style>` an older version injected), so an existing element gets the current CSS instead of being kept as is.
63
+ */
48
64
  export declare function ensureStyles(): void;
@@ -1,28 +1,67 @@
1
1
  export const styles = {
2
- card: 'dsb-card', open: 'dsb-open', header: 'dsb-header', head: 'dsb-head', titleRow: 'dsb-title-row', name: 'dsb-name', description: 'dsb-description', badge: 'dsb-badge',
3
- chevron: 'dsb-chevron', chevronOpen: 'dsb-chevron-open', body: 'dsb-body', notice: 'dsb-notice', section: 'dsb-section', sectionHead: 'dsb-section-head', grid: 'dsb-grid',
4
- field: 'dsb-field', invalid: 'dsb-invalid', fieldHead: 'dsb-field-head', label: 'dsb-label', hint: 'dsb-hint', input: 'dsb-input', textarea: 'dsb-textarea', code: 'dsb-code', reset: 'dsb-reset',
5
- toggle: 'dsb-toggle', toggleLabel: 'dsb-toggle-label', check: 'dsb-check', advanced: 'dsb-advanced', footer: 'dsb-footer', status: 'dsb-status', failed: 'dsb-failed', actions: 'dsb-actions', primary: 'dsb-primary', secondary: 'dsb-secondary',
6
- assetGroup: 'dsb-asset-group', assetRow: 'dsb-asset-row', assetToolbar: 'dsb-asset-toolbar', assetLayout: 'dsb-asset-layout', assetList: 'dsb-asset-list', assetItem: 'dsb-asset-item', assetSelected: 'dsb-asset-selected', assetTest: 'dsb-asset-test', assetTestForm: 'dsb-asset-test-form', assetEditor: 'dsb-asset-editor', invalidInput: 'dsb-invalid-input',
2
+ notice: 'dsb-notice', field: 'dsb-field', fieldHead: 'dsb-field-head', label: 'dsb-label', hint: 'dsb-hint', input: 'dsb-input',
3
+ textarea: 'dsb-textarea', code: 'dsb-code', failed: 'dsb-failed', actions: 'dsb-actions', root: 'dsb-root', summaryBar: 'dsb-summary',
4
+ chips: 'dsb-chips', chip: 'dsb-chip', chipRemove: 'dsb-chip-remove', chipInput: 'dsb-chip-input', group: 'dsb-group', groupHead: 'dsb-group-head',
5
+ groupTitle: 'dsb-group-title', groupSub: 'dsb-group-sub', groupBadges: 'dsb-group-badges', groupBody: 'dsb-group-body', row: 'dsb-row', rowText: 'dsb-row-text',
6
+ rowLabel: 'dsb-row-label', rowControl: 'dsb-row-control', rowHint: 'dsb-row-hint', rowMeta: 'dsb-row-meta', muted: 'dsb-muted', select: 'dsb-select',
7
+ unitInput: 'dsb-unit-input', unit: 'dsb-unit', help: 'dsb-help', link: 'dsb-link', danger: 'dsb-danger', list: 'dsb-list',
8
+ item: 'dsb-item', itemMain: 'dsb-item-main', itemTitle: 'dsb-item-title', itemMeta: 'dsb-item-meta', itemActions: 'dsb-item-actions', empty: 'dsb-empty',
9
+ subHead: 'dsb-sub-head', compare: 'dsb-compare', compareCol: 'dsb-compare-col', preview: 'dsb-preview', savebar: 'dsb-savebar', saveText: 'dsb-save-text',
10
+ dialogBody: 'dsb-dialog-body', stack: 'dsb-stack', fold: 'dsb-fold', foldBody: 'dsb-fold-body', foldHint: 'dsb-fold-hint', assetToolbar: 'dsb-asset-toolbar',
11
+ assetTestForm: 'dsb-asset-test-form', assetEditor: 'dsb-asset-editor', invalidInput: 'dsb-invalid-input',
7
12
  };
13
+ /**
14
+ * Inject the card's stylesheet, or refresh it in place. A Host that hot-reloads the plugin keeps the page (and the
15
+ * `<style>` an older version injected), so an existing element gets the current CSS instead of being kept as is.
16
+ */
8
17
  export function ensureStyles() {
9
- if (document.getElementById('dsh-browser-settings-styles'))
10
- return;
11
- const style = document.createElement('style');
18
+ const existing = document.getElementById('dsh-browser-settings-styles');
19
+ const style = existing ?? document.createElement('style');
12
20
  style.id = 'dsh-browser-settings-styles';
13
- style.textContent = `
14
- .dsb-card{list-style:none;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-3);transition:border-color .16s,background .16s}.dsb-card:hover{border-color:var(--dsw-alias-label-dimmed)}.dsb-open{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}
15
- .dsb-header{width:100%;appearance:none;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;display:flex;align-items:center;gap:12px;padding:14px 16px;border-radius:12px}.dsb-header:focus-visible,.dsb-input:focus-visible,.dsb-reset:focus-visible,.dsb-primary:focus-visible,.dsb-secondary:focus-visible,.dsb-check:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}
16
- .dsb-head{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.dsb-title-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.dsb-name{font-size:15px;font-weight:600;color:var(--dsw-alias-label-primary)}.dsb-description,.dsb-hint,.dsb-section-head p{font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary);margin:0}.dsb-badge{font-size:11px;padding:2px 7px;border-radius:9px;color:var(--dsw-alias-brand-primary);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 12%,transparent)}
17
- .dsb-chevron{flex:none;color:var(--dsw-alias-label-tertiary);transition:transform .16s}.dsb-chevron-open{transform:rotate(180deg)}.dsb-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding:4px 0 8px}.dsb-notice{margin:12px 0 0;padding:9px 11px;border-radius:8px;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-3)}
18
- .dsb-section{padding:18px 0}.dsb-section+.dsb-section{border-top:1px solid var(--dsw-alias-border-l2)}.dsb-section-head{margin-bottom:14px}.dsb-section-head h3{margin:0;font-size:14px;color:var(--dsw-alias-label-primary)}.dsb-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px 16px}.dsb-field{display:flex;min-width:0;flex-direction:column;gap:6px}.dsb-field-head{display:flex;align-items:center;justify-content:space-between;gap:8px}.dsb-label{font-size:13px;font-weight:500;color:var(--dsw-alias-label-primary)}
19
- .dsb-input{box-sizing:border-box;width:100%;min-width:0;height:34px;padding:0 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3);font:inherit;font-size:13px;color:var(--dsw-alias-label-primary)}.dsb-input:focus-visible{outline:none;border-color:var(--dsw-alias-brand-primary)}.dsb-input:disabled{opacity:.55}.dsb-invalid .dsb-input{border-color:var(--dsw-alias-label-error)}.dsb-textarea{height:auto;padding:9px 10px;resize:vertical;line-height:1.45}.dsb-code{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px}.dsb-reset{appearance:none;border:0;background:none;padding:0;color:var(--dsw-alias-brand-primary);font:inherit;font-size:11px;cursor:pointer}
20
- .dsb-toggle{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;padding-top:2px}.dsb-toggle-label{display:flex;align-items:flex-start;gap:9px;cursor:pointer}.dsb-check{width:16px;height:16px;flex:none;margin:2px 0 0;accent-color:var(--dsw-alias-brand-primary)}.dsb-advanced{padding:16px 0;border-top:1px solid var(--dsw-alias-border-l2)}.dsb-advanced>summary{cursor:pointer;font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary)}
21
- .dsb-footer{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 0 4px;border-top:1px solid var(--dsw-alias-border-l2)}.dsb-status,.dsb-failed{margin:0;font-size:12px}.dsb-status{color:var(--dsw-alias-label-tertiary)}.dsb-failed{color:var(--dsw-alias-label-error)}.dsb-actions{display:flex;gap:8px}.dsb-primary,.dsb-secondary{appearance:none;border-radius:8px;padding:6px 14px;font:inherit;font-size:13px;cursor:pointer}.dsb-primary{border:1px solid transparent;background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.dsb-secondary{border:1px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-primary)}.dsb-primary:disabled,.dsb-secondary:disabled,.dsb-reset:disabled{opacity:.4;cursor:default}
22
- .dsb-asset-group{display:flex;flex-direction:column;gap:8px;margin-bottom:16px}.dsb-asset-group h4{margin:0;font-size:13px}.dsb-asset-row,.dsb-asset-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px}.dsb-asset-row p,.dsb-asset-toolbar p{margin:3px 0 0;font-size:11px;color:var(--dsw-alias-label-tertiary)}.dsb-asset-toolbar{margin-bottom:10px;border:0;padding:0}.dsb-asset-layout{display:grid;grid-template-columns:minmax(180px,.7fr) minmax(0,1.3fr);gap:12px}.dsb-asset-list{display:flex;flex-direction:column;gap:6px;max-height:500px;overflow:auto}.dsb-asset-item{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;padding:9px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer}.dsb-asset-item span:first-child{display:flex;min-width:0;flex-direction:column;gap:3px}.dsb-asset-item small,.dsb-asset-test{font-size:10px;color:var(--dsw-alias-label-tertiary)}.dsb-asset-selected{border-color:var(--dsw-alias-brand-primary);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 8%,var(--dsw-alias-bg-layer-3))}.dsb-asset-editor{display:flex;min-width:0;flex-direction:column;gap:8px}.dsb-asset-editor .dsb-actions{justify-content:flex-end;flex-wrap:wrap}.dsb-invalid-input{border-color:var(--dsw-alias-label-error)}
21
+ const css = `
22
+ .dsb-notice{margin:0;padding:9px 11px;border-radius:8px;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-3)}.dsb-hint{font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary);margin:0}
23
+ .dsb-field{display:flex;min-width:0;flex-direction:column;gap:6px}.dsb-field-head{display:flex;align-items:center;justify-content:space-between;gap:8px}.dsb-label{font-size:13px;font-weight:500;color:var(--dsw-alias-label-primary)}
24
+ .dsb-input{box-sizing:border-box;width:100%;min-width:0;height:34px;padding:0 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3);font:inherit;font-size:13px;color:var(--dsw-alias-label-primary)}.dsb-input:focus-visible{outline:none;border-color:var(--dsw-alias-state-business-primary)}.dsb-input:disabled{opacity:.55}.dsb-textarea{height:auto;padding:9px 10px;resize:vertical;line-height:1.45}.dsb-code{font-family:var(--ds-font-family-code);font-size:12px}
25
+ .dsb-failed{margin:0;font-size:12px;color:var(--dsw-alias-state-error-primary)}.dsb-actions{display:flex;flex-wrap:wrap;gap:8px}.dsb-invalid-input{border-color:var(--dsw-alias-state-error-primary)}
26
+ .dsb-asset-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px}.dsb-asset-toolbar p{margin:3px 0 0;font-size:11px;color:var(--dsw-alias-label-tertiary)}.dsb-asset-editor{display:flex;min-width:0;flex-direction:column;gap:8px}.dsb-asset-editor .dsb-actions{justify-content:flex-end}
23
27
  .dsb-asset-test-form{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:8px}.dsb-asset-test-form .dsb-textarea{min-height:64px}
24
- @media(max-width:720px){.dsb-grid,.dsb-asset-layout{grid-template-columns:minmax(0,1fr)}.dsb-footer,.dsb-asset-row,.dsb-asset-toolbar{align-items:stretch;flex-direction:column}.dsb-actions{justify-content:flex-end}}@media(max-width:420px){.dsb-body{margin:0 12px}.dsb-actions{display:grid;grid-template-columns:1fr 1fr}.dsb-primary,.dsb-secondary{width:100%}}
28
+ @media(max-width:560px){.dsb-asset-test-form{grid-template-columns:minmax(0,1fr)}.dsb-asset-toolbar{align-items:stretch;flex-direction:column}}
29
+ .dsb-root{container-type:inline-size;display:flex;flex-direction:column;gap:12px;min-width:0}
30
+ .dsb-summary{display:flex;flex-wrap:wrap;align-items:center;gap:6px 8px;padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-3)}.dsb-summary>strong{font-size:12px;font-weight:600;color:var(--dsw-alias-label-secondary);margin-right:2px}
31
+ .dsb-link{appearance:none;border:0;background:none;padding:0;margin:0;font:inherit;font-size:12px;color:var(--dsw-alias-state-business-primary);cursor:pointer;text-decoration:none}.dsb-link:hover{text-decoration:underline}.dsb-link:disabled{opacity:.4;cursor:default;text-decoration:none}.dsb-danger{color:var(--dsw-alias-state-error-primary)}
32
+ .dsb-group{border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-3);min-width:0}.dsb-group[open]{background:var(--dsw-alias-bg-layer-2)}
33
+ .dsb-group-head{list-style:none;display:flex;align-items:center;gap:10px;padding:12px 14px;cursor:pointer;border-radius:12px;min-width:0}.dsb-group-head::-webkit-details-marker{display:none}.dsb-group-head::marker{content:''}
34
+ .dsb-group-head::after{content:'';flex:none;width:7px;height:7px;margin:0 4px 2px 2px;border-right:1.5px solid var(--dsw-alias-label-tertiary);border-bottom:1.5px solid var(--dsw-alias-label-tertiary);transform:rotate(45deg);transition:transform .16s}.dsb-group[open]>.dsb-group-head::after{transform:rotate(-135deg);margin-bottom:-2px}
35
+ .dsb-group-head:hover{background:var(--dsw-alias-interactive-bg-hover)}.dsb-group-head:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px}
36
+ .dsb-group-title{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.dsb-group-title strong{font-size:14px;font-weight:600;color:var(--dsw-alias-label-primary)}.dsb-group-sub{font-size:12px;line-height:1.4;color:var(--dsw-alias-label-tertiary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
37
+ .dsb-group-badges{display:flex;flex:none;align-items:center;gap:6px}.dsb-group-body{padding:2px 14px 14px;border-top:1px solid var(--dsw-alias-border-l2);display:flex;flex-direction:column}
38
+ .dsb-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(180px,260px);gap:6px 16px;align-items:start;padding:12px 0}.dsb-row+.dsb-row,.dsb-row+.dsb-sub-head,.dsb-sub-head+.dsb-row{border-top:1px solid var(--dsw-alias-border-l1)}
39
+ .dsb-row-text{display:flex;flex-direction:column;gap:3px;min-width:0}.dsb-row-label{display:flex;flex-wrap:wrap;align-items:center;gap:6px}.dsb-row-label label,.dsb-row-label>span:first-child{font-size:13px;font-weight:500;color:var(--dsw-alias-label-primary)}
40
+ .dsb-row-hint{margin:0;font-size:12px;line-height:1.45;color:var(--dsw-alias-label-tertiary)}.dsb-row-hint.dsb-bad,.dsb-bad{color:var(--dsw-alias-state-error-primary)}.dsb-row-control{display:flex;flex-direction:column;gap:6px;min-width:0}.dsb-row-control.dsb-inline{flex-direction:row;align-items:center;justify-content:flex-end}.dsb-row-wide{grid-template-columns:minmax(0,1fr)}
41
+ .dsb-row-meta{font-size:11px;color:var(--dsw-alias-label-tertiary);opacity:.85}.dsb-muted{color:var(--dsw-alias-label-tertiary)}.dsb-sub-head{margin:14px 0 2px;padding-top:2px;font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--dsw-alias-label-tertiary)}.dsb-sub-head:first-child{margin-top:8px}
42
+ .dsb-select{box-sizing:border-box;width:100%;min-width:0;height:34px;padding:0 28px 0 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background-color:var(--dsw-alias-bg-layer-3);font:inherit;font-size:13px;color:var(--dsw-alias-label-primary);cursor:pointer;appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--dsw-alias-label-tertiary) 50%),linear-gradient(135deg,var(--dsw-alias-label-tertiary) 50%,transparent 50%);background-position:calc(100% - 15px) 14px,calc(100% - 10px) 14px;background-size:5px 5px;background-repeat:no-repeat}
43
+ .dsb-select:focus-visible{outline:none;border-color:var(--dsw-alias-state-business-primary)}.dsb-select:disabled{opacity:.55;cursor:default}.dsb-select.dsb-muted,.dsb-input.dsb-muted{color:var(--dsw-alias-label-tertiary)}.dsb-select option{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}
44
+ .dsb-input:focus-visible{border-color:var(--dsw-alias-state-business-primary)}.dsb-unit-input{display:flex;align-items:center;gap:6px;min-width:0}.dsb-unit-input .dsb-input{flex:none;width:120px}.dsb-input.dsb-num{max-width:160px}.dsb-unit-input .dsb-select{flex:none;width:auto;min-width:72px}.dsb-unit{flex:none;font-size:12px;color:var(--dsw-alias-label-tertiary)}
45
+ .dsb-help{appearance:none;display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:1px solid var(--dsw-alias-border-l3);border-radius:50%;background:transparent;font:inherit;font-size:10px;line-height:1;color:var(--dsw-alias-label-tertiary);cursor:pointer}.dsb-help:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-tertiary)}.dsb-help:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}
46
+ .dsb-chips{display:flex;flex-wrap:wrap;align-items:center;gap:6px;padding:6px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3);min-width:0}.dsb-chips:focus-within{border-color:var(--dsw-alias-state-business-primary)}
47
+ .dsb-chip{display:inline-flex;align-items:center;gap:4px;max-width:100%;padding:2px 4px 2px 8px;border-radius:999px;background:var(--dsw-alias-interactive-bg-hover);font-size:12px;color:var(--dsw-alias-label-primary)}.dsb-chip>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
48
+ .dsb-chip-remove{appearance:none;border:0;background:none;padding:0 4px;font:inherit;font-size:13px;line-height:1;color:var(--dsw-alias-label-tertiary);cursor:pointer;border-radius:50%}.dsb-chip-remove:hover{color:var(--dsw-alias-state-error-primary)}.dsb-chip-remove:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary)}
49
+ .dsb-chip-input{flex:1;min-width:120px;height:24px;border:0;background:transparent;font:inherit;font-size:13px;color:var(--dsw-alias-label-primary)}.dsb-chip-input:focus{outline:none}
50
+ .dsb-list{display:flex;flex-direction:column;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;overflow:hidden;background:var(--dsw-alias-bg-layer-3)}.dsb-item{display:flex;align-items:center;gap:10px;padding:9px 12px;min-width:0}.dsb-item+.dsb-item{border-top:1px solid var(--dsw-alias-border-l1)}
51
+ .dsb-item-main{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.dsb-item-title{display:flex;align-items:center;flex-wrap:wrap;gap:6px;font-size:13px;color:var(--dsw-alias-label-primary)}.dsb-item-title code{font-family:var(--ds-font-family-code);font-size:12px}.dsb-item-meta{font-size:11px;line-height:1.4;color:var(--dsw-alias-label-tertiary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
52
+ .dsb-item-actions{display:flex;flex:none;align-items:center;gap:6px}.dsb-empty{margin:0;padding:12px;font-size:12px;color:var(--dsw-alias-label-tertiary)}
53
+ .dsb-compare{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px}.dsb-compare-col{display:flex;flex-direction:column;gap:6px;min-width:0}.dsb-compare-col>label,.dsb-compare-col>strong{font-size:12px;font-weight:600;color:var(--dsw-alias-label-secondary)}
54
+ .dsb-preview{margin:0;padding:9px 10px;max-height:280px;overflow:auto;border:1px dashed var(--dsw-alias-border-l3);border-radius:8px;background:var(--dsw-alias-bg-layer-1);font-family:var(--ds-font-family-code);font-size:12px;line-height:1.5;color:var(--dsw-alias-label-secondary);white-space:pre-wrap;word-break:break-word}
55
+ .dsb-dialog-body{display:flex;flex-direction:column;gap:14px;min-width:0}.dsb-dialog-body .dsb-row{padding:8px 0}.dsb-stack{display:flex;flex-direction:column;gap:8px}
56
+ div.dsb-modal{width:min(560px,100%);max-height:100%}div.dsb-modal-wide{width:min(980px,100%)}.dsb-modal-content{min-height:0;overflow:auto}div.dsb-modal{gap:16px}
57
+ .dsb-savebar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:4px;padding:10px 12px;border:1px solid var(--dsw-alias-border-l3);border-radius:12px;background:var(--dsw-alias-bg-layer-2)}.dsb-savebar[data-dsb-floating]{position:sticky;bottom:0;z-index:2;box-shadow:0 -6px 16px -8px rgba(0,0,0,.35)}.dsb-save-text{display:flex;flex-direction:column;gap:2px;min-width:0;font-size:12px;color:var(--dsw-alias-label-secondary)}.dsb-save-text .dsb-bad{margin:0}
58
+ .dsb-fold{margin-top:6px;border-top:1px solid var(--dsw-alias-border-l1)}.dsb-fold>summary{list-style:none;display:flex;align-items:center;gap:6px;padding:10px 0;cursor:pointer;font-size:12px;font-weight:600;color:var(--dsw-alias-label-secondary)}.dsb-fold>summary::-webkit-details-marker{display:none}.dsb-fold>summary::before{content:'';width:6px;height:6px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(-45deg);transition:transform .16s}.dsb-fold[open]>summary::before{transform:rotate(45deg)}.dsb-fold>summary:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.dsb-fold-body{display:flex;flex-direction:column}.dsb-fold-hint{font-weight:400;color:var(--dsw-alias-label-tertiary)}
59
+ @container (max-width:560px){.dsb-row{grid-template-columns:minmax(0,1fr)}.dsb-row-control.dsb-inline{justify-content:flex-start}.dsb-compare{grid-template-columns:minmax(0,1fr)}.dsb-group-sub{white-space:normal}.dsb-item{flex-wrap:wrap}.dsb-savebar{flex-wrap:wrap}.dsb-savebar .dsb-actions{margin-left:auto}}
60
+ @media(max-width:560px){.dsb-compare{grid-template-columns:minmax(0,1fr)}div.dsb-modal{width:100%}}
25
61
  `;
26
- document.head.append(style);
62
+ if (style.textContent !== css)
63
+ style.textContent = css;
64
+ if (!existing)
65
+ document.head.append(style);
27
66
  }
28
67
  //# sourceMappingURL=styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/client/styles.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,KAAK,EAAE,WAAW;IAC3K,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,kBAAkB,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,kBAAkB,EAAE,IAAI,EAAE,UAAU;IAC1K,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW;IACjM,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe;IACjP,UAAU,EAAE,iBAAiB,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,kBAAkB,EAAE,SAAS,EAAE,gBAAgB,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,EAAE,oBAAoB,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,EAAE,qBAAqB,EAAE,WAAW,EAAE,kBAAkB,EAAE,YAAY,EAAE,mBAAmB;CAC1V,CAAA;AAEV,MAAM,UAAU,YAAY;IAC1B,IAAI,QAAQ,CAAC,cAAc,CAAC,6BAA6B,CAAC;QAAE,OAAM;IAClE,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;IAC7C,KAAK,CAAC,EAAE,GAAG,6BAA6B,CAAA;IACxC,KAAK,CAAC,WAAW,GAAG;;;;;;;;;;;;CAYrB,CAAA;IACC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC7B,CAAC"}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/client/styles.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW;IAC/H,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa;IACrI,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,iBAAiB,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,gBAAgB;IACjJ,UAAU,EAAE,iBAAiB,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc;IAC/J,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY;IACpJ,SAAS,EAAE,gBAAgB,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU;IACzH,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,KAAK,EAAE,WAAW;IACxJ,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe;IACzJ,UAAU,EAAE,iBAAiB,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,mBAAmB;IAC5J,aAAa,EAAE,qBAAqB,EAAE,WAAW,EAAE,kBAAkB,EAAE,YAAY,EAAE,mBAAmB;CAChG,CAAA;AAEV;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,6BAA6B,CAAC,CAAA;IACvE,MAAM,KAAK,GAAG,QAAQ,IAAI,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;IACzD,KAAK,CAAC,EAAE,GAAG,6BAA6B,CAAA;IACxC,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCb,CAAA;IACC,IAAI,KAAK,CAAC,WAAW,KAAK,GAAG;QAAE,KAAK,CAAC,WAAW,GAAG,GAAG,CAAA;IACtD,IAAI,CAAC,QAAQ;QAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC5C,CAAC"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * The small set of controls the settings card is made of.
3
+ *
4
+ * Switches, buttons, badges, dialogs and the click-to-read help bubble are the Host's own
5
+ * (`@deepseek-ai/dsh-client-ui-primitives`). The Host ships no select, no chip input, no accordion and no
6
+ * list-row, so those four are built here from native elements (`<select>`, `<details>`, `<input>`) and the
7
+ * `--dsw-alias-*` tokens, which makes them follow the light and dark themes without a color of their own.
8
+ * Nothing in this file knows about a configuration field: callers pass text and callbacks.
9
+ * @module dsh-browser/client/ui-kit
10
+ */
11
+ import { type ReactNode } from 'react';
12
+ export type Tone = 'neutral' | 'info' | 'success' | 'warning' | 'danger' | 'outline';
13
+ /** A read-only badge. */
14
+ export declare function Badge(props: {
15
+ tone?: Tone;
16
+ children: ReactNode;
17
+ }): import("react").JSX.Element;
18
+ /** The `?` button: its text opens on click, so a long explanation costs one glyph until someone asks. */
19
+ export declare function Help(props: {
20
+ label: string;
21
+ text: string;
22
+ }): import("react").JSX.Element;
23
+ /** Labels every row shares, so a row does not need the dictionary itself. */
24
+ export interface RowLabels {
25
+ overridden: string;
26
+ reset: string;
27
+ help: string;
28
+ invalid: string;
29
+ }
30
+ export interface RowProps {
31
+ /** The configuration field this row is the entry of (one per public field; the render test counts them). */
32
+ field?: string;
33
+ /** The id of the control, so the label is tied to it. */
34
+ id?: string;
35
+ label: string;
36
+ /** One short sentence. Anything longer belongs in `help`. */
37
+ hint?: string;
38
+ help?: string;
39
+ overridden?: boolean;
40
+ invalid?: boolean;
41
+ /** Replaces the hint while the value is invalid. */
42
+ problem?: string;
43
+ /** `field.key` of a policy key's row (usagePolicy.minDelayMs), for the render test and for tests that drive a row. */
44
+ policyKey?: string;
45
+ /** A small grey line under the hint: a range, a default. */
46
+ meta?: string;
47
+ /** A short warning badge beside the label, for a setting that widens what an agent may do. */
48
+ risk?: string;
49
+ disabled?: boolean;
50
+ labels: RowLabels;
51
+ onReset?: () => void;
52
+ /** Control placement: beside the text (default) or on its own line. */
53
+ wide?: boolean;
54
+ inline?: boolean;
55
+ children: ReactNode;
56
+ }
57
+ /** One setting: label, one-line hint, an optional `?`, the "overridden" badge with its reset, and the control. */
58
+ export declare function Row(props: RowProps): import("react").JSX.Element;
59
+ /** A closed-by-default fold inside a group, for the items few people need. */
60
+ export declare function Fold(props: {
61
+ id: string;
62
+ title: string;
63
+ hint?: string;
64
+ children: ReactNode;
65
+ }): import("react").JSX.Element;
66
+ /** A small heading inside a group, for sets of rows that belong together. */
67
+ export declare function SubHead(props: {
68
+ children: ReactNode;
69
+ }): import("react").JSX.Element;
70
+ /**
71
+ * One group of the card, an accordion item. `<details>` keeps every control in the document while the group is
72
+ * closed (so a server-rendered check still sees them) and gives keyboard and screen-reader behavior for free.
73
+ */
74
+ export declare function Group(props: {
75
+ id: string;
76
+ title: string;
77
+ summary?: string;
78
+ badges?: ReactNode;
79
+ defaultOpen?: boolean;
80
+ children: ReactNode;
81
+ }): import("react").JSX.Element;
82
+ export interface SelectOption {
83
+ value: string;
84
+ label: string;
85
+ }
86
+ /**
87
+ * A native select. A stored value that is not among the options (a channel the list does not know, an older
88
+ * enum value) is shown as its own entry instead of being silently replaced by the first option.
89
+ */
90
+ export declare function Select(props: {
91
+ id?: string;
92
+ value: string;
93
+ options: readonly SelectOption[];
94
+ onChange: (value: string) => void;
95
+ disabled?: boolean;
96
+ muted?: boolean;
97
+ invalid?: boolean;
98
+ ariaLabel?: string;
99
+ }): import("react").JSX.Element;
100
+ /** A single-line text input; `muted` greys the value while it is only the inherited default. */
101
+ export declare function TextInput(props: {
102
+ id?: string;
103
+ value: string;
104
+ onChange: (value: string) => void;
105
+ placeholder?: string;
106
+ disabled?: boolean;
107
+ muted?: boolean;
108
+ invalid?: boolean;
109
+ list?: string;
110
+ numeric?: boolean;
111
+ ariaLabel?: string;
112
+ code?: boolean;
113
+ }): import("react").JSX.Element;
114
+ /** A text input followed by a fixed unit. */
115
+ export declare function UnitInput(props: {
116
+ id?: string;
117
+ value: string;
118
+ unit: string;
119
+ onChange: (value: string) => void;
120
+ placeholder?: string;
121
+ disabled?: boolean;
122
+ muted?: boolean;
123
+ invalid?: boolean;
124
+ ariaLabel?: string;
125
+ }): import("react").JSX.Element;
126
+ /** The Host's switch, named by its row. */
127
+ export declare function Toggle(props: {
128
+ label: string;
129
+ checked: boolean;
130
+ onChange: (next: boolean) => void;
131
+ disabled?: boolean;
132
+ }): import("react").JSX.Element;
133
+ /** A list of short strings as removable chips with an add box (Enter or comma adds; Backspace on an empty box removes the last). */
134
+ export declare function Chips(props: {
135
+ id?: string;
136
+ values: readonly string[];
137
+ onChange: (values: string[]) => void;
138
+ placeholder?: string;
139
+ disabled?: boolean;
140
+ /** Why a new entry is refused, or undefined. */
141
+ check?: (value: string, existing: readonly string[]) => string | undefined;
142
+ removeLabel: string;
143
+ addLabel: string;
144
+ }): import("react").JSX.Element;
145
+ /** A dialog on the Host's modal: a title, a scrolling body, and a footer of actions. */
146
+ export declare function Dialog(props: {
147
+ open: boolean;
148
+ title: string;
149
+ closeLabel: string;
150
+ description?: string;
151
+ onClose: () => void;
152
+ footer?: ReactNode;
153
+ wide?: boolean;
154
+ children: ReactNode;
155
+ }): import("react").JSX.Element;
156
+ /** Primary and secondary buttons at the card's size. */
157
+ export declare function Btn(props: {
158
+ children: ReactNode;
159
+ onClick?: () => void;
160
+ primary?: boolean;
161
+ disabled?: boolean;
162
+ danger?: boolean;
163
+ title?: string;
164
+ data?: string;
165
+ }): import("react").JSX.Element;
166
+ /** A list row: a title with badges, a meta line, and actions on the right. */
167
+ export declare function Item(props: {
168
+ title: ReactNode;
169
+ badges?: ReactNode;
170
+ meta?: ReactNode;
171
+ actions?: ReactNode;
172
+ data?: string;
173
+ }): import("react").JSX.Element;