dsh-web-search-pro 0.2.1 → 0.2.4

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 (264) hide show
  1. package/CHANGELOG.md +227 -0
  2. package/README.en.md +117 -0
  3. package/README.md +72 -578
  4. package/assets/skills/dsh-web-search-pro/SKILL.md +13 -12
  5. package/assets/skills/dsh-web-search-pro/references/config.md +36 -0
  6. package/assets/skills/dsh-web-search-pro/references/sources.md +13 -7
  7. package/assets/skills/dsh-web-search-pro/references/troubleshooting.md +3 -1
  8. package/catalog/sources.v1.json +16 -14
  9. package/lib/actions/approval.js +50 -1
  10. package/lib/actions/approval.js.map +1 -1
  11. package/lib/actions/config.js +274 -0
  12. package/lib/actions/config.js.map +1 -0
  13. package/lib/actions/errors.js +8 -1
  14. package/lib/actions/errors.js.map +1 -1
  15. package/lib/actions/format.js +10 -0
  16. package/lib/actions/format.js.map +1 -1
  17. package/lib/actions/index-view.js +2 -2
  18. package/lib/actions/index-view.js.map +1 -1
  19. package/lib/actions/read.js +7 -3
  20. package/lib/actions/read.js.map +1 -1
  21. package/lib/actions/registry.js +3 -1
  22. package/lib/actions/registry.js.map +1 -1
  23. package/lib/actions/run.js +2 -2
  24. package/lib/actions/run.js.map +1 -1
  25. package/lib/actions/schema.js +18 -0
  26. package/lib/actions/schema.js.map +1 -1
  27. package/lib/actions/search.js +7 -2
  28. package/lib/actions/search.js.map +1 -1
  29. package/lib/actions/sources.js +76 -18
  30. package/lib/actions/sources.js.map +1 -1
  31. package/lib/actions/types.js +19 -1
  32. package/lib/actions/types.js.map +1 -1
  33. package/lib/browser-access.js +25 -0
  34. package/lib/browser-access.js.map +1 -1
  35. package/lib/catalog/recommend.js +11 -3
  36. package/lib/catalog/recommend.js.map +1 -1
  37. package/lib/catalog/schema.js +3 -1
  38. package/lib/catalog/schema.js.map +1 -1
  39. package/lib/cli/builtin-specs.js +57 -22
  40. package/lib/cli/builtin-specs.js.map +1 -1
  41. package/lib/cli/chain.js +13 -12
  42. package/lib/cli/chain.js.map +1 -1
  43. package/lib/cli/chains-spec.js +31 -11
  44. package/lib/cli/chains-spec.js.map +1 -1
  45. package/lib/cli/engine.js +19 -3
  46. package/lib/cli/engine.js.map +1 -1
  47. package/lib/cli/opencli-sites.js +83 -0
  48. package/lib/cli/opencli-sites.js.map +1 -0
  49. package/lib/cli/opencli.js +65 -17
  50. package/lib/cli/opencli.js.map +1 -1
  51. package/lib/cli/probe.js +1 -1
  52. package/lib/cli/probe.js.map +1 -1
  53. package/lib/cli/runner.js +217 -27
  54. package/lib/cli/runner.js.map +1 -1
  55. package/lib/cli/spec.js +100 -20
  56. package/lib/cli/spec.js.map +1 -1
  57. package/lib/cli/time-text.js +79 -0
  58. package/lib/cli/time-text.js.map +1 -0
  59. package/lib/cli/trial.js +57 -0
  60. package/lib/cli/trial.js.map +1 -0
  61. package/lib/client/SettingsCard.js +14 -32
  62. package/lib/client/SettingsCard.js.map +1 -1
  63. package/lib/client/agent-mark.js +27 -0
  64. package/lib/client/agent-mark.js.map +1 -0
  65. package/lib/client/card-frame.js +118 -0
  66. package/lib/client/card-frame.js.map +1 -0
  67. package/lib/client/cli-form.js +257 -0
  68. package/lib/client/cli-form.js.map +1 -0
  69. package/lib/client/field-docs.js +130 -0
  70. package/lib/client/field-docs.js.map +1 -0
  71. package/lib/client/field-keys.js +81 -0
  72. package/lib/client/field-keys.js.map +1 -0
  73. package/lib/client/field-rows.js +71 -0
  74. package/lib/client/field-rows.js.map +1 -0
  75. package/lib/client/fill.js +3 -0
  76. package/lib/client/fill.js.map +1 -0
  77. package/lib/client/form-specs.js +13 -1
  78. package/lib/client/form-specs.js.map +1 -1
  79. package/lib/client/form.js +282 -24
  80. package/lib/client/form.js.map +1 -1
  81. package/lib/client/group-advanced.js +23 -0
  82. package/lib/client/group-advanced.js.map +1 -0
  83. package/lib/client/group-agent.js +28 -0
  84. package/lib/client/group-agent.js.map +1 -0
  85. package/lib/client/group-cli.js +136 -0
  86. package/lib/client/group-cli.js.map +1 -0
  87. package/lib/client/group-common.js +29 -0
  88. package/lib/client/group-common.js.map +1 -0
  89. package/lib/client/group-judge.js +67 -0
  90. package/lib/client/group-judge.js.map +1 -0
  91. package/lib/client/group-order.js +201 -0
  92. package/lib/client/group-order.js.map +1 -0
  93. package/lib/client/group-runtime.js +33 -0
  94. package/lib/client/group-runtime.js.map +1 -0
  95. package/lib/client/group-sources.js +83 -0
  96. package/lib/client/group-sources.js.map +1 -0
  97. package/lib/client/groups-basic.js +36 -0
  98. package/lib/client/groups-basic.js.map +1 -0
  99. package/lib/client/index.js.map +1 -1
  100. package/lib/client/json-list.js +50 -0
  101. package/lib/client/json-list.js.map +1 -0
  102. package/lib/client/locales.js +666 -219
  103. package/lib/client/locales.js.map +1 -1
  104. package/lib/client/order.js +192 -0
  105. package/lib/client/order.js.map +1 -0
  106. package/lib/client/overlay-ops.js +46 -0
  107. package/lib/client/overlay-ops.js.map +1 -0
  108. package/lib/client/sources-table.js +1 -0
  109. package/lib/client/sources-table.js.map +1 -1
  110. package/lib/client/styles.js +74 -47
  111. package/lib/client/styles.js.map +1 -1
  112. package/lib/client/text-view.js +98 -0
  113. package/lib/client/text-view.js.map +1 -0
  114. package/lib/client/ui-kit.js +120 -0
  115. package/lib/client/ui-kit.js.map +1 -0
  116. package/lib/client/validators.js +8 -1
  117. package/lib/client/validators.js.map +1 -1
  118. package/lib/client.js +7313 -1571
  119. package/lib/client.js.map +1 -1
  120. package/lib/config-fillers.js +53 -0
  121. package/lib/config-fillers.js.map +1 -0
  122. package/lib/config-groups.js +49 -0
  123. package/lib/config-groups.js.map +1 -0
  124. package/lib/config.js +84 -108
  125. package/lib/config.js.map +1 -1
  126. package/lib/default-chain.js +66 -0
  127. package/lib/default-chain.js.map +1 -0
  128. package/lib/deps.js +1 -1
  129. package/lib/deps.js.map +1 -1
  130. package/lib/engines.js +3 -3
  131. package/lib/engines.js.map +1 -1
  132. package/lib/fetch.js +23 -4
  133. package/lib/fetch.js.map +1 -1
  134. package/lib/fiber-config.js +5 -0
  135. package/lib/fiber-config.js.map +1 -0
  136. package/lib/index.js +36 -7
  137. package/lib/index.js.map +1 -1
  138. package/lib/overlay-types.js +88 -0
  139. package/lib/overlay-types.js.map +1 -0
  140. package/lib/overlay.js +683 -0
  141. package/lib/overlay.js.map +1 -0
  142. package/lib/pipeline/candidates.js +27 -1
  143. package/lib/pipeline/candidates.js.map +1 -1
  144. package/lib/pipeline/compile.js +63 -0
  145. package/lib/pipeline/compile.js.map +1 -1
  146. package/lib/pipeline/confidence.js +64 -0
  147. package/lib/pipeline/confidence.js.map +1 -0
  148. package/lib/pipeline/fusion.js +50 -3
  149. package/lib/pipeline/fusion.js.map +1 -1
  150. package/lib/pipeline/plan.js +2 -2
  151. package/lib/pipeline/plan.js.map +1 -1
  152. package/lib/pipeline/render.js +20 -2
  153. package/lib/pipeline/render.js.map +1 -1
  154. package/lib/pipeline/run.js +17 -5
  155. package/lib/pipeline/run.js.map +1 -1
  156. package/lib/pipeline/sources-spec.js +19 -3
  157. package/lib/pipeline/sources-spec.js.map +1 -1
  158. package/lib/providers/builtin.js +3 -0
  159. package/lib/providers/builtin.js.map +1 -1
  160. package/lib/providers/deepseek.js +348 -0
  161. package/lib/providers/deepseek.js.map +1 -0
  162. package/lib/providers/http.js.map +1 -1
  163. package/lib/providers/keyed-meta.js +7 -0
  164. package/lib/providers/keyed-meta.js.map +1 -1
  165. package/lib/providers/platforms.js +18 -17
  166. package/lib/providers/platforms.js.map +1 -1
  167. package/lib/providers/registry.js.map +1 -1
  168. package/lib/restart.js +47 -0
  169. package/lib/restart.js.map +1 -0
  170. package/lib/router.js +145 -26
  171. package/lib/router.js.map +1 -1
  172. package/lib/rpc-types.js +15 -0
  173. package/lib/rpc-types.js.map +1 -0
  174. package/lib/rpc.js +118 -0
  175. package/lib/rpc.js.map +1 -0
  176. package/lib/tools.js +10 -4
  177. package/lib/tools.js.map +1 -1
  178. package/lib/types/actions/approval.d.ts +11 -0
  179. package/lib/types/actions/config.d.ts +54 -0
  180. package/lib/types/actions/format.d.ts +9 -2
  181. package/lib/types/actions/run.d.ts +1 -0
  182. package/lib/types/actions/schema.d.ts +7 -1
  183. package/lib/types/actions/sources.d.ts +29 -3
  184. package/lib/types/actions/types.d.ts +28 -2
  185. package/lib/types/browser-access.d.ts +17 -0
  186. package/lib/types/catalog/recommend.d.ts +4 -0
  187. package/lib/types/catalog/schema.d.ts +2 -0
  188. package/lib/types/cli/builtin-specs.d.ts +11 -3
  189. package/lib/types/cli/chains-spec.d.ts +12 -3
  190. package/lib/types/cli/engine.d.ts +10 -3
  191. package/lib/types/cli/opencli-sites.d.ts +24 -0
  192. package/lib/types/cli/opencli.d.ts +42 -3
  193. package/lib/types/cli/runner.d.ts +47 -8
  194. package/lib/types/cli/spec.d.ts +101 -8
  195. package/lib/types/cli/time-text.d.ts +12 -0
  196. package/lib/types/cli/trial.d.ts +19 -0
  197. package/lib/types/client/SettingsCard.d.ts +17 -1
  198. package/lib/types/client/agent-mark.d.ts +22 -0
  199. package/lib/types/client/card-frame.d.ts +35 -0
  200. package/lib/types/client/cli-form.d.ts +97 -0
  201. package/lib/types/client/field-docs.d.ts +15 -0
  202. package/lib/types/client/field-keys.d.ts +41 -0
  203. package/lib/types/client/field-rows.d.ts +70 -0
  204. package/lib/types/client/fill.d.ts +2 -0
  205. package/lib/types/client/form-specs.d.ts +12 -3
  206. package/lib/types/client/form.d.ts +79 -1
  207. package/lib/types/client/group-advanced.d.ts +9 -0
  208. package/lib/types/client/group-agent.d.ts +20 -0
  209. package/lib/types/client/group-cli.d.ts +52 -0
  210. package/lib/types/client/group-common.d.ts +12 -0
  211. package/lib/types/client/group-judge.d.ts +17 -0
  212. package/lib/types/client/group-order.d.ts +26 -0
  213. package/lib/types/client/group-runtime.d.ts +15 -0
  214. package/lib/types/client/group-sources.d.ts +46 -0
  215. package/lib/types/client/groups-basic.d.ts +18 -0
  216. package/lib/types/client/index.d.ts +8 -0
  217. package/lib/types/client/json-list.d.ts +21 -0
  218. package/lib/types/client/locales.d.ts +1079 -200
  219. package/lib/types/client/order.d.ts +102 -0
  220. package/lib/types/client/overlay-ops.d.ts +37 -0
  221. package/lib/types/client/styles.d.ts +56 -41
  222. package/lib/types/client/text-view.d.ts +22 -0
  223. package/lib/types/client/ui-kit.d.ts +200 -0
  224. package/lib/types/config-fillers.d.ts +9 -0
  225. package/lib/types/config-groups.d.ts +23 -0
  226. package/lib/types/config.d.ts +263 -225
  227. package/lib/types/default-chain.d.ts +63 -0
  228. package/lib/types/engines.d.ts +29 -1
  229. package/lib/types/fetch.d.ts +12 -3
  230. package/lib/types/fiber-config.d.ts +18 -0
  231. package/lib/types/index.d.ts +164 -150
  232. package/lib/types/overlay-types.d.ts +98 -0
  233. package/lib/types/overlay.d.ts +141 -0
  234. package/lib/types/pipeline/candidates.d.ts +17 -0
  235. package/lib/types/pipeline/compile.d.ts +11 -0
  236. package/lib/types/pipeline/confidence.d.ts +35 -0
  237. package/lib/types/pipeline/fusion.d.ts +23 -1
  238. package/lib/types/pipeline/render.d.ts +16 -0
  239. package/lib/types/pipeline/run.d.ts +2 -1
  240. package/lib/types/pipeline/sources-spec.d.ts +5 -2
  241. package/lib/types/pipeline/types.d.ts +37 -0
  242. package/lib/types/providers/deepseek.d.ts +130 -0
  243. package/lib/types/providers/http.d.ts +2 -1
  244. package/lib/types/providers/keyed-meta.d.ts +5 -0
  245. package/lib/types/providers/registry.d.ts +7 -0
  246. package/lib/types/restart.d.ts +52 -0
  247. package/lib/types/router.d.ts +57 -10
  248. package/lib/types/rpc-types.d.ts +79 -0
  249. package/lib/types/rpc.d.ts +74 -0
  250. package/lib/types/tools.d.ts +6 -0
  251. package/lib/types/util.d.ts +10 -0
  252. package/lib/util.js +10 -1
  253. package/lib/util.js.map +1 -1
  254. package/package.json +53 -44
  255. package/scripts/check-client-bundle.mjs +1 -1
  256. package/scripts/check-docs-links.mjs +107 -0
  257. package/scripts/cli-login-check.mjs +214 -0
  258. package/LOGIN.md +0 -161
  259. package/lib/client/RubricEditor.js +0 -47
  260. package/lib/client/RubricEditor.js.map +0 -1
  261. package/lib/client/fields.js +0 -31
  262. package/lib/client/fields.js.map +0 -1
  263. package/lib/types/client/RubricEditor.d.ts +0 -6
  264. package/lib/types/client/fields.d.ts +0 -65
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Documentation checks, no dependencies:
4
+ * 1. every relative link in the repository's Markdown files points at an existing file, and `#anchor` fragments exist as
5
+ * headings (GitHub slug rules) in the target file;
6
+ * 2. README.md and README.en.md have the same number of second-level headings (the English page mirrors the Chinese one).
7
+ *
8
+ * Skipped: node_modules, lib, .git and bench (bench keeps its own notes), absolute URLs, and anything inside fenced code.
9
+ * Run: node scripts/check-docs-links.mjs (also part of `pnpm run verify`)
10
+ */
11
+ import fs from 'node:fs'
12
+ import path from 'node:path'
13
+ import { fileURLToPath } from 'node:url'
14
+
15
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
16
+ const SKIP_DIRS = new Set(['node_modules', 'lib', '.git', 'bench', '.codegraph'])
17
+
18
+ function walk(dir, out = []) {
19
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
20
+ if (entry.isDirectory()) {
21
+ if (!SKIP_DIRS.has(entry.name)) walk(path.join(dir, entry.name), out)
22
+ } else if (entry.isFile() && entry.name.endsWith('.md')) out.push(path.join(dir, entry.name))
23
+ }
24
+ return out
25
+ }
26
+
27
+ /** Lines outside fenced code blocks, with their 1-based numbers. */
28
+ function proseLines(text) {
29
+ const lines = text.split('\n')
30
+ const out = []
31
+ let fence = null
32
+ lines.forEach((line, i) => {
33
+ const m = /^\s*(```+|~~~+)/.exec(line)
34
+ if (m) {
35
+ if (!fence) fence = m[1][0]
36
+ else if (m[1][0] === fence) fence = null
37
+ return
38
+ }
39
+ if (!fence) out.push([i + 1, line])
40
+ })
41
+ return out
42
+ }
43
+
44
+ /** GitHub's heading slug: lowercase, drop punctuation, spaces to hyphens. */
45
+ function slug(heading) {
46
+ return heading
47
+ .trim()
48
+ .replace(/`/g, '')
49
+ .replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
50
+ .replace(/<[^>]+>/g, '')
51
+ .toLowerCase()
52
+ .replace(/[^\p{L}\p{N}\p{M}_\- ]/gu, '')
53
+ .replace(/ /g, '-')
54
+ }
55
+
56
+ const anchorCache = new Map()
57
+ function anchorsOf(file) {
58
+ if (anchorCache.has(file)) return anchorCache.get(file)
59
+ const seen = new Map()
60
+ const set = new Set()
61
+ for (const [, line] of proseLines(fs.readFileSync(file, 'utf8'))) {
62
+ const m = /^(#{1,6})\s+(.*?)\s*#*\s*$/.exec(line)
63
+ if (!m) continue
64
+ const base = slug(m[2])
65
+ const n = seen.get(base) ?? 0
66
+ seen.set(base, n + 1)
67
+ set.add(n === 0 ? base : `${base}-${n}`)
68
+ }
69
+ anchorCache.set(file, set)
70
+ return set
71
+ }
72
+
73
+ const problems = []
74
+ const files = walk(root)
75
+ for (const file of files) {
76
+ const rel = path.relative(root, file)
77
+ for (const [lineNo, line] of proseLines(fs.readFileSync(file, 'utf8'))) {
78
+ // [text](target) and <target>-less reference-free links only; inline code is stripped first.
79
+ const stripped = line.replace(/`[^`]*`/g, '')
80
+ for (const m of stripped.matchAll(/\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g)) {
81
+ const target = m[1]
82
+ if (/^[a-z][a-z0-9+.-]*:/i.test(target)) continue // http:, https:, mailto: ...
83
+ const [pathPart, rawFragment] = target.split('#')
84
+ const fragment = rawFragment === undefined ? undefined : decodeURIComponent(rawFragment)
85
+ const targetFile = pathPart === '' ? file : path.resolve(path.dirname(file), decodeURIComponent(pathPart))
86
+ if (!fs.existsSync(targetFile)) { problems.push(`${rel}:${lineNo}: missing file ${target}`); continue }
87
+ if (fragment !== undefined && fragment !== '') {
88
+ if (!targetFile.endsWith('.md')) continue
89
+ if (!anchorsOf(targetFile).has(fragment.toLowerCase())) problems.push(`${rel}:${lineNo}: missing anchor #${fragment} in ${path.relative(root, targetFile)}`)
90
+ }
91
+ }
92
+ }
93
+ }
94
+
95
+ function h2Count(file) {
96
+ return proseLines(fs.readFileSync(file, 'utf8')).filter(([, line]) => /^## /.test(line)).length
97
+ }
98
+ const zh = path.join(root, 'README.md')
99
+ const en = path.join(root, 'README.en.md')
100
+ if (!fs.existsSync(zh) || !fs.existsSync(en)) problems.push('README.md and README.en.md must both exist')
101
+ else if (h2Count(zh) !== h2Count(en)) problems.push(`README.md has ${h2Count(zh)} second-level headings but README.en.md has ${h2Count(en)}`)
102
+
103
+ if (problems.length) {
104
+ console.error(`docs check failed (${problems.length}):\n` + problems.map(p => ' ' + p).join('\n'))
105
+ process.exit(1)
106
+ }
107
+ console.log(`docs check ok: ${files.length} Markdown files, links and anchors resolve, README headings match`)
@@ -0,0 +1,214 @@
1
+ /**
2
+ * cli-login-check.mjs - 登录类 CLI 的一键陪测脚本(由用户本人运行)。
3
+ *
4
+ * 做什么:对 xhs、zhihu、rdt、twitter(以及你点名的独立 opencli 站点)逐个执行
5
+ * 1) 插件自己的契约探测(只跑该工具的 --version 与 `search --help`,不搜索、不登录);
6
+ * 2) 与插件完全相同的登录闸门:缺少已保存的登录文件 / 缺少 TWITTER_AUTH_TOKEN+TWITTER_CT0 就跳过,
7
+ * 并给出和插件一样的提示——这样不会触发 xhs / rdt 在没有登录文件时自行读取浏览器 Cookie 的行为;
8
+ * 3) 闸门通过才用插件的内置规格(和插件运行时是同一份 argv、同一个解析器)执行一次只读搜索;
9
+ * 4) 打印解析结果摘要,并把原始 stdout/stderr(已脱敏)和 summary.json 存到输出目录。
10
+ *
11
+ * 不做什么:任何登录命令(xhs login / zhihu login / rdt login / opencli ... login);任何写操作;
12
+ * 不读你的 Cookie 或 Token 内容(只检查登录文件“是否存在”;Token 只通过环境变量交给 twitter 子进程,
13
+ * 保存的原始输出里会被替换)。独立 opencli 会驱动你自己的 Chrome,所以默认不跑,需要 --opencli 点名站点。
14
+ *
15
+ * 用法(在插件包目录内;需要先 `pnpm build`,或使用已发布的包):
16
+ * node scripts/cli-login-check.mjs [--only xhs,zhihu,rdt,twitter] [--count 3] [--out DIR]
17
+ * [--opencli xiaohongshu,twitter,reddit,zhihu] [--query-<id> "词"] [--yes]
18
+ * 例:node scripts/cli-login-check.mjs --only xhs --yes
19
+ * 例:TWITTER_AUTH_TOKEN=... TWITTER_CT0=... node scripts/cli-login-check.mjs --only twitter --yes
20
+ *
21
+ * 退出码:0 = 脚本跑完(无论各 CLI 是否通过,结果看摘要);2 = 参数错误或用户未确认。
22
+ */
23
+
24
+ import fs from 'node:fs'
25
+ import os from 'node:os'
26
+ import path from 'node:path'
27
+ import readline from 'node:readline'
28
+ import { pathToFileURL } from 'node:url'
29
+
30
+ const lib = rel => import(pathToFileURL(path.join(path.dirname(new URL(import.meta.url).pathname), '..', 'lib', rel)).href)
31
+
32
+ let modules
33
+ try {
34
+ const [{ builtinSpecById }, probe, runner, spec, opencli, util] = await Promise.all([
35
+ lib('cli/builtin-specs.js'), lib('cli/probe.js'), lib('cli/runner.js'), lib('cli/spec.js'), lib('cli/opencli.js'), lib('util.js'),
36
+ ])
37
+ modules = { builtinSpecById, ...probe, ...runner, ...spec, ...opencli, runCli: util.runCli }
38
+ } catch (error) {
39
+ console.error('找不到插件的构建产物 lib/(先在包目录运行 `pnpm build`):' + (error instanceof Error ? error.message : String(error)))
40
+ process.exit(2)
41
+ }
42
+ const {
43
+ builtinSpecById, probeCli, savedLoginPresent, missingEnv, loginHint, runCliSearchDetailed, searchSpecFor, listOpencliSites, planOpencliSearch, OPENCLI_PROBE, runCli,
44
+ } = modules
45
+
46
+ // ── 参数 ────────────────────────────────────────────────────────────────────
47
+
48
+ const args = process.argv.slice(2)
49
+ const flag = name => args.includes('--' + name)
50
+ const value = name => { const i = args.indexOf('--' + name); return i >= 0 ? args[i + 1] : undefined }
51
+ if (flag('help') || flag('h')) { console.log(fs.readFileSync(new URL(import.meta.url), 'utf8').split('*/')[0] + '*/'); process.exit(0) }
52
+
53
+ const ALL = ['xhs', 'zhihu', 'rdt', 'twitter']
54
+ const only = (value('only') ?? ALL.join(',')).split(',').map(s => s.trim()).filter(Boolean)
55
+ const unknown = only.filter(id => !ALL.includes(id))
56
+ if (unknown.length) { console.error('未知的 CLI:' + unknown.join(', ') + '(可选:' + ALL.join(', ') + ')'); process.exit(2) }
57
+ const count = Math.min(Math.max(Number(value('count') ?? 3) || 3, 1), 10)
58
+ const opencliSites = (value('opencli') ?? '').split(',').map(s => s.trim()).filter(Boolean)
59
+ const OPENCLI_PLATFORMS = ['xiaohongshu', 'twitter', 'reddit', 'zhihu']
60
+ const badSites = opencliSites.filter(site => !OPENCLI_PLATFORMS.includes(site))
61
+ if (badSites.length) { console.error('--opencli 只接受:' + OPENCLI_PLATFORMS.join(', ')); process.exit(2) }
62
+
63
+ /** 每个 CLI 的默认查询:中文平台用中文,其余用英文。可用 --query-xhs "词" 覆盖。 */
64
+ const DEFAULT_QUERY = { xhs: '露营装备测评', zhihu: '大模型 备案', rdt: 'rust async runtime', twitter: 'DeepSeek Harness' }
65
+ const PLATFORM_OF = { xhs: 'xiaohongshu', zhihu: 'zhihu', rdt: 'reddit', twitter: 'twitter' }
66
+ const queryOf = id => value('query-' + id) ?? DEFAULT_QUERY[id]
67
+
68
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-')
69
+ const outDir = path.resolve(value('out') ?? path.join(process.cwd(), 'cli-login-check-' + stamp))
70
+
71
+ // ── 确认 ────────────────────────────────────────────────────────────────────
72
+
73
+ function plan() {
74
+ const lines = ['将要执行(全部只读;不会运行任何登录命令):']
75
+ for (const id of only) {
76
+ const s = builtinSpecById(id)
77
+ lines.push(' - ' + id + ':' + [s.bins[0], ...searchSpecFor(s, s.platforms[0]).argv].join(' ').replace('{query}', JSON.stringify(queryOf(id))).replace('{count}', String(count)))
78
+ }
79
+ for (const site of opencliSites) lines.push(' - opencli(驱动你自己的 Chrome):opencli ' + site + ' search <查询> -f json')
80
+ lines.push('输出目录:' + outDir)
81
+ return lines.join('\n')
82
+ }
83
+
84
+ async function confirm() {
85
+ console.log(plan())
86
+ if (flag('yes')) return true
87
+ if (!process.stdin.isTTY) { console.error('非交互环境:请加 --yes 确认。'); return false }
88
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
89
+ const answer = await new Promise(resolve => rl.question('继续?[y/N] ', resolve))
90
+ rl.close()
91
+ return /^y(es)?$/i.test(String(answer).trim())
92
+ }
93
+
94
+ // ── 脱敏与摘要 ──────────────────────────────────────────────────────────────
95
+
96
+ const SECRET_KEY = /(cookie|token|secret|session|auth|password|a1|z_c0|d_c0|ct0)/i
97
+
98
+ /** 把原始输出里敏感键的值、已知环境变量的值和 xsec_token 参数替换掉,再写盘。 */
99
+ function redact(text, env) {
100
+ let out = text
101
+ for (const name of ['TWITTER_AUTH_TOKEN', 'TWITTER_CT0']) { const v = env[name]; if (v && v.length >= 6) out = out.split(v).join('[redacted]') }
102
+ out = out.replace(/("(?:[^"\\]|\\.)*")(\s*:\s*)"((?:[^"\\]|\\.)*)"/g, (m, key, colon, val) => (SECRET_KEY.test(key) && val.length > 6 && !/^https?:/.test(val) ? key + colon + '"[redacted]"' : m))
103
+ return out.replace(/(xsec_token=)[^&"\s]+/g, '$1REDACTED')
104
+ }
105
+
106
+ const short = (text, n = 90) => { const t = String(text ?? '').replace(/\s+/g, ' ').trim(); return t.length > n ? t.slice(0, n - 1) + '…' : t }
107
+
108
+ /** 一眼能看出的垃圾:字段名当标题、占位符文本、重复链接、非 http 链接。 */
109
+ function junkChecks(sources) {
110
+ const problems = []
111
+ const seen = new Set()
112
+ for (const s of sources) {
113
+ if (!/^https?:\/\//.test(s.url)) problems.push('非 http(s) 链接:' + short(s.url))
114
+ if (seen.has(s.url)) problems.push('重复链接:' + short(s.url))
115
+ seen.add(s.url)
116
+ if (!s.title || !s.title.trim()) problems.push('空标题:' + short(s.url))
117
+ else if (/^[A-Za-z_][\w.-]*:$/.test(s.title)) problems.push('标题是字段名:' + s.title)
118
+ for (const field of ['title', 'snippet']) if (/(^|[|·] )(NA|None|null|undefined)( |$)/.test(s[field] ?? '')) problems.push(field + ' 含占位符:' + short(s[field]))
119
+ if (s.publishedAt !== undefined && Number.isNaN(Date.parse(s.publishedAt))) problems.push('publishedAt 不是日期:' + s.publishedAt)
120
+ }
121
+ return problems
122
+ }
123
+
124
+ // ── 单个 CLI ────────────────────────────────────────────────────────────────
125
+
126
+ async function checkOne(label, spec, platform, query, runOptions = {}) {
127
+ const row = { id: label, platform, query, status: 'skipped', note: '' }
128
+ const t0 = Date.now()
129
+ const probe = await probeCli(spec, { force: true })
130
+ row.probe = { state: probe.state, version: probe.version, path: probe.path, reason: probe.reason }
131
+ console.log('\n=== ' + label + '(平台 ' + platform + ')')
132
+ console.log(' 探测:' + probe.state + (probe.version ? ' ' + probe.version : '') + (probe.path ? ' @ ' + probe.path : '') + (probe.reason ? ' - ' + probe.reason : ''))
133
+ if (probe.state !== 'detected') { row.note = probe.state === 'missing' ? '未安装:' + spec.packageNote : '已安装但契约不符:' + (probe.reason ?? ''); console.log(' 跳过:' + row.note); return row }
134
+
135
+ // 与插件一致的登录闸门(runCliSearchDetailed 内部会再检查一遍,这里只是先给出明确说明)。
136
+ const missing = missingEnv(spec)
137
+ if (missing.length) { row.note = '缺少环境变量 ' + missing.join(' / ') + ';' + loginHint(spec); row.status = 'needs_login'; console.log(' 跳过(未登录):' + row.note); return row }
138
+ if (savedLoginPresent(spec) === false) {
139
+ row.note = '没有已保存的登录文件(' + (spec.login?.savedCredentialPaths ?? []).join(', ') + ');' + loginHint(spec) + (spec.login?.readsBrowserCookiesWithoutLogin ? '。没有登录文件时该工具会自己读取浏览器 Cookie,所以脚本不运行它' : '')
140
+ row.status = 'needs_login'; console.log(' 跳过(未登录):' + row.note); return row
141
+ }
142
+
143
+ const base = path.join(outDir, label.replace(/[^\w.-]/g, '_'))
144
+ const argv = searchSpecFor(spec, platform).argv
145
+ console.log(' 执行:' + [probe.path ?? spec.bins[0], ...argv].join(' ').replace('{query}', JSON.stringify(query)).replace('{count}', String(count)))
146
+ let raw
147
+ const capture = async (bin, runArgs, opts) => { raw = await runCli(bin, runArgs, opts); return raw }
148
+ try {
149
+ const { sources, skipped } = await runCliSearchDetailed(spec, { query, count }, { platform, bin: probe.path, run: capture, ...runOptions })
150
+ row.status = 'ok'
151
+ row.resultCount = sources.length
152
+ row.skipped = skipped
153
+ row.sample = sources.slice(0, 3).map(s => ({ ...s, url: redact(s.url, process.env) }))
154
+ row.junk = junkChecks(sources)
155
+ row.withPublishedAt = sources.filter(s => s.publishedAt).length
156
+ row.withSnippet = sources.filter(s => s.snippet).length
157
+ console.log(' 结果:' + sources.length + ' 条(请求 ' + count + ';无链接被跳过 ' + skipped + ';带时间 ' + row.withPublishedAt + ';带摘要 ' + row.withSnippet + ')')
158
+ row.sample.forEach((s, i) => console.log(' ' + (i + 1) + '. ' + short(s.title, 70) + ' ' + short(s.url, 80) + (s.publishedAt ? ' [' + s.publishedAt + ']' : '')))
159
+ console.log(' 自动检查:' + (row.junk.length ? '发现问题 ' + row.junk.length + ' 个' : '未发现垃圾行') )
160
+ row.junk.forEach(p => console.log(' ! ' + p))
161
+ } catch (error) {
162
+ row.status = 'error'
163
+ row.code = error?.code
164
+ row.note = (error instanceof Error ? error.message : String(error))
165
+ row.hint = error?.hint
166
+ console.log(' 失败:[' + (row.code ?? 'error') + '] ' + short(row.note, 300) + (row.hint ? '\n 提示:' + row.hint : ''))
167
+ if (raw) console.log(' 工具原话(脱敏,前 240 字符):' + short(redact(raw.stderr.trim() || raw.stdout.trim(), process.env), 240))
168
+ }
169
+ row.ms = Date.now() - t0
170
+ if (raw) {
171
+ fs.mkdirSync(outDir, { recursive: true })
172
+ const env = process.env
173
+ fs.writeFileSync(base + '.stdout.txt', redact(raw.stdout, env))
174
+ fs.writeFileSync(base + '.stderr.txt', redact(raw.stderr, env))
175
+ row.raw = { exit: raw.code, timedOut: !!raw.timedOut, stdout: base + '.stdout.txt', stderr: base + '.stderr.txt', stdoutBytes: raw.stdout.length }
176
+ console.log(' 原始输出(已脱敏):' + row.raw.stdout + '(exit ' + raw.code + ',' + raw.stdout.length + ' 字符)')
177
+ }
178
+ return row
179
+ }
180
+
181
+ // ── 主流程 ──────────────────────────────────────────────────────────────────
182
+
183
+ if (!(await confirm())) { console.error('已取消,没有运行任何东西。'); process.exit(2) }
184
+ fs.mkdirSync(outDir, { recursive: true })
185
+
186
+ console.log('\n主机:' + os.platform() + ' ' + os.release() + ',Node ' + process.version + ';HOME=' + os.homedir())
187
+ const rows = []
188
+ for (const id of only) rows.push(await checkOne(id, builtinSpecById(id), PLATFORM_OF[id], queryOf(id)))
189
+
190
+ if (opencliSites.length) {
191
+ const probe = await probeCli(OPENCLI_PROBE, { force: true })
192
+ console.log('\n=== opencli(独立):' + probe.state + (probe.version ? ' ' + probe.version : '') + (probe.reason ? ' - ' + probe.reason : ''))
193
+ if (probe.state === 'detected') {
194
+ await listOpencliSites({ force: true })
195
+ for (const site of opencliSites) {
196
+ // 与插件完全相同的计划:命令表里的 search 条目、是否带后台窗口 / 临时会话 / 不保留标签页参数、生成的规格。
197
+ const plan = await planOpencliSearch(site, site)
198
+ if (!plan.spec) { rows.push({ id: 'opencli:' + site, platform: site, status: 'skipped', note: plan.problem ?? '生成的规格无效' }); console.log(' ' + site + ':跳过 - ' + rows.at(-1).note); continue }
199
+ const spec = plan.spec
200
+ console.log(' ' + site + ':' + (plan.silent ? '带 --window background --site-session ephemeral --keep-tab false(不抢焦点,用完关标签页)' : '该命令不支持后台窗口参数,按默认方式运行'))
201
+ // 登录态在 Chrome 里,无法本地检查;这里就是用户点名要跑的那一次。
202
+ rows.push(await checkOne('opencli:' + site, { ...spec, probe: OPENCLI_PROBE.probe }, site, DEFAULT_QUERY[Object.keys(PLATFORM_OF).find(k => PLATFORM_OF[k] === site)] ?? 'DeepSeek', { skipCredentialGate: true }))
203
+ }
204
+ } else {
205
+ for (const site of opencliSites) rows.push({ id: 'opencli:' + site, platform: site, status: 'skipped', note: probe.reason ?? 'opencli 不可用' })
206
+ }
207
+ }
208
+
209
+ const summary = { date: new Date().toISOString(), node: process.version, platform: os.platform(), count, results: rows }
210
+ fs.writeFileSync(path.join(outDir, 'summary.json'), JSON.stringify(summary, null, 2))
211
+ console.log('\n──────── 汇总 ────────')
212
+ for (const r of rows) console.log(r.id.padEnd(18) + r.status.padEnd(12) + (r.status === 'ok' ? r.resultCount + ' 条' + (r.junk?.length ? ',有 ' + r.junk.length + ' 个问题' : '') : short(r.note, 70)))
213
+ console.log('\n完整结果:' + path.join(outDir, 'summary.json'))
214
+ console.log('把上面的汇总和 summary.json(以及对应的 *.stdout.txt)发给我即可;里面没有 Cookie / Token。')
package/LOGIN.md DELETED
@@ -1,161 +0,0 @@
1
- # 中文社区平台登录态(复用你已登录的浏览器)
2
-
3
- 知乎 / 微博 / 豆瓣 / 贴吧 / 抖音 / 快手 / 小红书的搜索页都有反爬与登录墙,
4
- 免登录的公开接口基本都被风控。所以这些平台走 **Playwright 驱动登录态浏览器** 的路径:
5
- 在你已登录的浏览器里打开搜索页、读渲染结果——不需要逆向任何签名。
6
-
7
- ## 方式一:登录一次保存登录态(推荐)
8
-
9
- 运行插件包里的脚本,按提示逐个平台登录一次(扫码/账号密码),
10
- 脚本会把所有 cookies 合并保存成一个 storageState JSON:
11
-
12
- ```bash
13
- cd dsh-web-search-pro
14
- node scripts/save-login.mjs all login-state.json
15
- # 或只登录一个平台:
16
- node scripts/save-login.mjs zhihu login-state.json
17
- ```
18
-
19
- 然后在 dsh-browser 的部署配置中创建命名、按域名授权的 AuthProfile:
20
-
21
- ```yaml
22
- # cordis.yml 中的 dsh-browser 插件行
23
- - id: browser
24
- name: '@anweat/dsh-browser'
25
- config:
26
- automationMode: standard # read-only | standard | autonomous | unrestricted
27
- authProfiles:
28
- china-community:
29
- storageStatePath: 'D:/secrets/login-state.json'
30
- allowedDomains: [zhihu.com, weibo.com, douban.com, baidu.com, douyin.com, kuaishou.com]
31
- persistState: false
32
-
33
- # $DSH_HOME/settings.yaml
34
- ---
35
- web-search-pro:
36
- browserBindings:
37
- zhihu: { authProfile: china-community }
38
- weibo: { authProfile: china-community }
39
- ```
40
-
41
- > storageState 是 Playwright 的标准登录态文件(cookies + origins),
42
- > 同一份文件可含多个站点登录态,但每个 AuthProfile 必须显式给出 `allowedDomains`;访问其他域名会被拒绝。`persistState` 默认 false,只有明确开启才会原子回写新 Cookie/localStorage。
43
- > `scripts/save-login.mjs` 优先复用 `@anweat/dsh-browser` 自带的 Playwright;默认启动其 bundled Chromium。如需显式使用已安装的 Chrome,可临时设置 `DSH_BROWSER_CHANNEL=chrome`。
44
-
45
- ## 方式二:用 Cookie 插件导出
46
-
47
- 如果你更习惯手动导出:
48
-
49
- 1. 在浏览器装 Cookie-Editor(或 EditThisCookie)。
50
- 2. 在目标站点导出 cookies(JSON)。
51
- 3. 组装成 storageState 格式:
52
-
53
- ```json
54
- { "cookies": [ ...导出的 cookies... ], "origins": [] }
55
- ```
56
-
57
- 每个 cookie 至少需要 `name` `value` `domain` `path`(可补 `expires` `httpOnly` `secure`)。
58
-
59
- 不要把 Cookie JSON 作为模型工具参数传入;导入到本地 storageState 文件后只在配置中引用路径。
60
-
61
- ## 受控脚本增强(RulePack)
62
-
63
- dsh-browser 可配置命名 RulePack。它适合由部署者长期维护的站点增强,支持有界的 `waitFor` / `click` / `scroll` / `wait` 步骤;可选 init script 只能引用本地文件,必须提供 SHA-256,且文件不超过 64KB。RulePack 同样按 `matches` 限域。
64
-
65
- ```yaml
66
- rulePacks:
67
- zhihu-enhanced:
68
- matches: [zhihu.com]
69
- initScriptPath: 'D:/dsh/rules/zhihu-init.js'
70
- initScriptSha256: '<64位sha256>'
71
- steps:
72
- - { type: waitFor, selector: '.SearchResult-Card', timeoutMs: 10000 }
73
- - { type: scroll, deltaY: 1600, repeat: 2, waitMs: 300 }
74
- ```
75
-
76
- ## 模型生成 Recipe
77
-
78
- 临时、多步骤操作不必先写持久 RulePack。模型可调用 `browser_recipe_run`,每次最多 25 步:
79
-
80
- ```json
81
- {
82
- "url": "https://example.com",
83
- "steps": [
84
- { "type": "wait", "condition": "selector", "value": "h1" },
85
- { "type": "extract", "selector": "h1", "mode": "text" }
86
- ]
87
- }
88
- ```
89
-
90
- `wait`、`extract`、`assert`、`screenshot` 是只读路径;一旦包含 `click`、`fill`、`type`、`press`、`select`、`check`、`hover` 或 `scroll`,`standard` 会发起一次性审批,`autonomous` / `unrestricted` 直接执行,`read-only` 拒绝。
91
-
92
- ## 外部模型生成 UserScript
93
-
94
- 外部模型可以输出油猴格式脚本,但需要走“先验证、后执行”两步:
95
-
96
- ```text
97
- browser_script_validate({ url, source })
98
- browser_userscript_run({ url, source, authProfile? })
99
- ```
100
-
101
- ```javascript
102
- // ==UserScript==
103
- // @name Read page heading
104
- // @match https://example.com/*
105
- // @grant none
106
- // ==/UserScript==
107
- return { heading: document.querySelector('h1')?.textContent || '' }
108
- ```
109
-
110
- 限制与边界:
111
-
112
- - 必须声明 HTTP(S) `@match`,`@exclude` 生效;目标 URL 不匹配时拒绝。
113
- - 只允许 `@grant none`,拒绝 `@require`,源码上限 64KB,输出与运行时间有界。
114
- - 验证结果包含 SHA-256 和静态能力提示,但能力提示不是安全证明。
115
- - 脚本运行在目标页主世界,能读写页面并使用该页已有登录态;除 `unrestricted` 外,`browser_userscript_run` 会进入 DSH 原生一次性审批。无审批测试也不要让脚本回传 Cookie、令牌、表单值等秘密。
116
-
117
- 常见只读任务优先用 `browser_script_catalog` 中的内置 `article-clean`、`links`、`jsonld`、`forms`,无需提交任意脚本。
118
-
119
- ## OpenCLI 社区平台
120
-
121
- Reddit / 小红书 / Twitter / Instagram / Facebook 走 OpenCLI Browser Bridge,使用当前 Chrome 扩展会话,不读取或导出 Cookie。`dsh-browser` 已包含 OpenCLI CLI,但 Chrome 扩展必须已安装并连接:
122
-
123
- ```bash
124
- opencli doctor
125
- opencli reddit search "DeepSeek Harness" -f yaml
126
- opencli browser research open https://example.com --window background
127
- opencli browser research state
128
- opencli browser research extract
129
- opencli browser research close
130
- ```
131
-
132
- 每个 `opencli browser` 子命令都必须显式给出 session 名(上例为 `research`),同名会话复用标签页状态。优先使用已有站点 adapter;没有 adapter 时优先 `network` / `extract`,最后再使用 `state` / `find` / `click` / `fill` 等 DOM 操作。
133
-
134
- 模型内先用 `browser_opencli_status` 检查 daemon、扩展和 profile;高级调用使用 `browser_opencli_run({ args: [...] })`。argv 示例:`["browser", "research", "state"]`。这个通用入口可能触发发帖、删除等站点 adapter,所以除隔离测试用的 `unrestricted` 外都要求一次性审批。
135
-
136
- 若 `doctor` 显示 daemon 正常但 extension disconnected,请显式启动安装了 OpenCLI Browser Bridge 的 Chrome;不要把 Quark 或禁用扩展的 Playwright 临时 profile 当作替代。只有需要在终端独立诊断时,才需要额外全局安装 `@jackwener/opencli`。
137
-
138
- ## 结果选择器可配置
139
-
140
- 站点改版后如果提取不到结果,不用改代码——在 `settings.yaml` 按平台覆盖选择器:
141
-
142
- ```yaml
143
- web-search-pro:
144
- platformRules:
145
- zhihu:
146
- item: '.SearchResult-Card'
147
- title: '.ContentItem-title'
148
- link: '.ContentItem-title a'
149
- text: '.Highlight'
150
- weibo:
151
- item: '.card-wrap'
152
- title: '.txt'
153
- link: '.from a'
154
- ```
155
-
156
- ## 安全与合规提醒
157
-
158
- - 仅做**单次、低频**的搜索调用,不要批量爬取;遵守目标平台的服务条款与 robots.txt。
159
- - 登录态文件包含你的登录凭据,请勿提交到公开仓库或分享给他人。
160
- - 本能力借鉴 MediaCrawler 的思路(登录态浏览器驱动搜索页),
161
- 但为 MIT 许可的独立实现,未使用其 NON-COMMERCIAL 许可下的签名算法代码。
@@ -1,47 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { styles as css } from "./styles.js";
3
- /** Label and hint keys of each rubric text control. */
4
- const CONTROLS = [
5
- { key: 'version', label: 'rubricVersion', hint: 'rubricVersionHint', kind: 'line' },
6
- { key: 'instructions', label: 'rubricInstructions', hint: 'rubricInstructionsHint', kind: 'area' },
7
- { key: 'criteria', label: 'rubricCriteria', hint: 'rubricCriteriaHint', kind: 'area' },
8
- { key: 'maxStateChars', label: 'rubricMaxState', hint: 'rubricMaxStateHint', kind: 'number' },
9
- { key: 'maxCandidateChars', label: 'rubricMaxCandidate', hint: 'rubricMaxCandidateHint', kind: 'number' },
10
- ];
11
- /** The built-in value of a control, shown as the placeholder while the entry leaves it blank. */
12
- function builtinText(rubric, key) {
13
- switch (key) {
14
- case 'version': return rubric.builtin.version;
15
- case 'instructions': return rubric.builtin.instructions;
16
- case 'criteria': return rubric.builtin.criteria.join('\n');
17
- case 'maxStateChars': return String(rubric.builtin.maxStateChars);
18
- case 'maxCandidateChars': return String(rubric.builtin.maxCandidateChars);
19
- }
20
- }
21
- /**
22
- * One built-in rubric: its active version, and an override editor whose controls are views of one staged entry
23
- * (version, instructions, levels, limits). The problems shown are the ones the server would act on: it ignores an
24
- * invalid override and uses the built-in, so the card refuses to save one.
25
- */
26
- function Rubric(props) {
27
- const { t, rubric, disabled } = props;
28
- const idBase = `web-search-pro-rubric-${rubric.id}`;
29
- return (_jsxs("div", { className: css.rubric, "data-web-search-pro-rubric": rubric.id, children: [_jsxs("div", { className: css.rubricHead, children: [_jsxs("span", { children: [_jsx("strong", { children: rubric.id }), _jsxs("span", { className: css.badge, children: [t('rubricActive'), ": ", rubric.activeVersion] }), _jsx("span", { className: css.badge, "data-on": rubric.editing || undefined, children: rubric.editing ? t('rubricOverrideOn') : `${t('rubricBuiltin')} ${rubric.builtin.version}` })] }), _jsx("span", { children: rubric.editing
30
- ? _jsx("button", { type: "button", className: css.linkButton, disabled: disabled, onClick: () => { props.restoreRubric(rubric.id); }, children: t('rubricRestore') })
31
- : _jsx("button", { type: "button", className: css.linkButton, disabled: disabled, onClick: () => { props.startRubric(rubric.id); }, children: t('rubricCreate') }) })] }), _jsx("p", { className: css.hint, children: rubric.description }), rubric.editing ? (_jsx("div", { className: css.grid, children: CONTROLS.filter(control => control.key !== 'criteria' || rubric.kind === 'score').map((control) => {
32
- const id = `${idBase}-${control.key}`;
33
- const value = rubric.entry[control.key];
34
- const common = {
35
- id, value, disabled, placeholder: builtinText(rubric, control.key), spellCheck: false,
36
- 'aria-invalid': rubric.invalid || undefined,
37
- };
38
- return (_jsxs("div", { className: `${css.field} ${control.kind === 'area' ? css.fullRow : ''}`, children: [_jsx("label", { className: css.label, htmlFor: id, children: t(control.label) }), control.kind === 'area'
39
- ? _jsx("textarea", { ...common, className: `${css.input} ${css.textarea} ${css.code}`, rows: control.key === 'criteria' ? 5 : 6, onChange: event => { props.editRubric(rubric.id, control.key, event.currentTarget.value); } })
40
- : _jsx("input", { ...common, className: css.input, type: "text", inputMode: control.kind === 'number' ? 'numeric' : undefined, onChange: event => { props.editRubric(rubric.id, control.key, event.currentTarget.value); } }), _jsx("p", { className: css.hint, children: t(control.hint) })] }, control.key));
41
- }) })) : null, rubric.problems.length > 0 ? (_jsx("ul", { className: rubric.invalid ? css.problem : css.warning, role: "alert", "data-web-search-pro-rubric-problems": true, children: rubric.problems.map((problem, index) => _jsx("li", { children: problem }, index)) })) : null] }));
42
- }
43
- export function RubricEditor(props) {
44
- const { t, state } = props;
45
- return (_jsxs("div", { "data-web-search-pro-rubrics": true, children: [_jsx("p", { className: css.hint, children: t('rubricNotes') }), state.rubrics.map(rubric => _jsx(Rubric, { t: t, rubric: rubric, disabled: props.disabled, editRubric: props.editRubric, startRubric: props.startRubric, restoreRubric: props.restoreRubric }, rubric.id)), state.unknownRubrics.length > 0 ? _jsxs("p", { className: css.warning, role: "note", children: [t('rubricUnknown'), " ", state.unknownRubrics.join(', ')] }) : null] }));
46
- }
47
- //# sourceMappingURL=RubricEditor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RubricEditor.js","sourceRoot":"","sources":["../../src/client/RubricEditor.tsx"],"names":[],"mappings":"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"}
@@ -1,31 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { styles as css } from "./styles.js";
3
- function FieldShell(props) {
4
- return (_jsxs("div", { className: `${css.field} ${props.state?.invalid ? css.fieldInvalid : ''}`, children: [_jsxs("div", { className: css.fieldHeading, children: [_jsx("label", { className: css.label, htmlFor: props.id, children: props.label }), props.field && props.state?.overridden ? (_jsx("button", { type: "button", className: css.reset, disabled: props.disabled, onClick: () => { props.onReset?.(props.field); }, children: props.resetLabel })) : null] }), props.children, props.state?.message ? _jsx("p", { className: css.problem, role: "alert", "data-web-search-pro-problem": true, children: props.state.message }) : null, _jsx("p", { className: css.hint, children: props.state?.invalid && !props.state.message ? props.invalidLabel : props.hint }), props.state?.warning ? _jsx("p", { className: css.warning, role: "note", "data-web-search-pro-warning": true, children: props.state.warning }) : null] }));
5
- }
6
- export function TextField(props) {
7
- const id = `web-search-pro-${props.field}`;
8
- return (_jsx(FieldShell, { id: id, label: props.label, hint: props.hint, field: props.field, state: props.state, disabled: props.disabled, resetLabel: props.t('reset'), invalidLabel: props.t('invalid'), onReset: props.reset, children: _jsx("input", { id: id, className: css.input, type: props.type ?? 'text', inputMode: props.type === 'number' ? 'decimal' : undefined, value: props.state.text, placeholder: props.placeholder, disabled: props.disabled, "aria-invalid": props.state.invalid || undefined, onChange: event => { props.edit(props.field, event.currentTarget.value); } }) }));
9
- }
10
- export function JsonField(props) {
11
- const id = `web-search-pro-${props.field}`;
12
- return (_jsx(FieldShell, { id: id, label: props.label, hint: props.hint, field: props.field, state: props.state, disabled: props.disabled, resetLabel: props.t('reset'), invalidLabel: props.t('invalidJson'), onReset: props.reset, children: _jsx("textarea", { id: id, className: `${css.input} ${css.textarea} ${css.code}`, rows: props.rows ?? 5, value: props.state.text, disabled: props.disabled, spellCheck: false, "aria-invalid": props.state.invalid || undefined, onChange: event => { props.edit(props.field, event.currentTarget.value); } }) }));
13
- }
14
- export function SelectField(props) {
15
- const id = `web-search-pro-${props.field}`;
16
- // A stored value no option names (a provider id of a settings file the draft no longer defines) stays selectable, so it is never lost silently.
17
- const known = props.options.some(option => option.value === props.state.text);
18
- return (_jsx(FieldShell, { id: id, label: props.label, hint: props.hint, field: props.field, state: props.state, disabled: props.disabled, resetLabel: props.t('reset'), invalidLabel: props.t('invalid'), onReset: props.reset, children: _jsxs("select", { id: id, className: `${css.input} ${css.select}`, value: props.state.text, disabled: props.disabled, "aria-invalid": props.state.invalid || undefined, onChange: event => { props.edit(props.field, event.currentTarget.value); }, children: [props.emptyLabel !== undefined ? _jsx("option", { value: "", children: props.emptyLabel }) : null, !known && props.state.text !== '' ? _jsx("option", { value: props.state.text, children: props.state.text }) : null, props.options.map(option => _jsx("option", { value: option.value, children: option.label }, option.value))] }) }));
19
- }
20
- export function ToggleField(props) {
21
- const checked = props.state.text === 'true';
22
- return (_jsxs("div", { className: css.toggleField, children: [_jsxs("label", { className: css.toggleLabel, children: [_jsx("input", { id: `web-search-pro-${props.field}`, className: css.checkbox, type: "checkbox", checked: checked, disabled: props.disabled, onChange: event => { props.edit(props.field, String(event.currentTarget.checked)); } }), _jsxs("span", { className: css.toggleCopy, children: [_jsx("span", { className: css.label, children: props.label }), _jsx("span", { className: css.hint, children: props.hint }), props.state.message ? _jsx("span", { className: css.problem, role: "alert", children: props.state.message }) : null, props.state.warning ? _jsx("span", { className: css.warning, role: "note", children: props.state.warning }) : null] })] }), props.state.overridden ? (_jsx("button", { type: "button", className: css.reset, disabled: props.disabled, onClick: () => { props.reset(props.field); }, children: props.t('reset') })) : null] }));
23
- }
24
- export function CredentialField(props) {
25
- const inputId = `web-search-pro-credential-${props.id}`;
26
- const status = props.state.loading
27
- ? props.t('credentialChecking')
28
- : props.state.configured ? props.t('credentialSet') : props.t('credentialUnset');
29
- return (_jsx(FieldShell, { id: inputId, label: props.label, hint: props.hint, disabled: props.disabled || !props.state.writable, resetLabel: props.t('reset'), invalidLabel: props.t('invalid'), children: _jsxs("div", { className: css.secretRow, children: [_jsx("input", { id: inputId, className: css.input, type: "password", autoComplete: "new-password", value: props.state.text, placeholder: status, disabled: props.disabled || !props.state.writable, onChange: event => { props.edit(props.id, event.currentTarget.value); } }), _jsx("span", { className: css.credentialStatus, "data-configured": props.state.configured ? 'true' : undefined, children: status })] }) }));
30
- }
31
- //# sourceMappingURL=fields.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fields.js","sourceRoot":"","sources":["../../src/client/fields.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +0,0 @@
1
- import type { WebSearchCardState } from './form.ts';
2
- import type { SettingsCardProps } from './index.ts';
3
- export declare function RubricEditor(props: Pick<SettingsCardProps, 't' | 'editRubric' | 'startRubric' | 'restoreRubric'> & {
4
- state: WebSearchCardState;
5
- disabled: boolean;
6
- }): import("react").JSX.Element;