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
@@ -16,13 +16,38 @@ export type OutputFormat = typeof OUTPUT_FORMATS[number];
16
16
  /** How far a spec has been checked against the real tool (recorded in the spec and shown in `sources.status`). */
17
17
  export declare const CLI_VERIFICATIONS: readonly ["live", "contract-only", "docs-only"];
18
18
  export type CliVerification = typeof CLI_VERIFICATIONS[number];
19
+ /**
20
+ * The short honest tag shown next to a backend that was not verified with a real search ("detected and configured" is not "works"),
21
+ * or undefined for `live` and for backends that are not CLI specs.
22
+ */
23
+ export declare function verificationTag(status: string): string | undefined;
24
+ /** The verification word of a user-defined spec: it is unverified by definition and says so in every result it returns. */
25
+ export declare const USER_DEFINED = "user-defined";
26
+ /** The honest label a custom CLI's results and chain entries carry. */
27
+ export declare const USER_DEFINED_TAG = "user-defined, not verified by the plugin (\u7528\u6237\u81EA\u5B9A\u4E49\uFF0C\u672A\u7ECF\u63D2\u4EF6\u9A8C\u8BC1)";
28
+ /** Confidence of a custom CLI whose spec gives none: below the built-in sources (1), because nothing here checked its output. */
29
+ export declare const DEFAULT_CUSTOM_CONFIDENCE = 0.5;
30
+ /** Default and largest size of a whole-output result's text, in characters (`output.lines.maxChars`). */
31
+ export declare const WHOLE_OUTPUT_DEFAULT_CHARS = 2000;
32
+ export declare const WHOLE_OUTPUT_MAX_CHARS = 8000;
33
+ /** Scheme of the stand-in link of a whole-output result (`cli://<id>?q=<query>`): not a web page, so nothing fetches it. */
34
+ export declare const WHOLE_OUTPUT_SCHEME = "cli://";
19
35
  export declare const CLI_ERROR_CODES: readonly ["CLI_NOT_FOUND", "CLI_CONTRACT_MISMATCH", "CLI_NOT_LOGGED_IN", "ENGINE_EMPTY", "CLI_FAILED"];
20
36
  export type CliErrorCode = typeof CLI_ERROR_CODES[number];
21
- /** One piece of a joined field: a path, optionally with text put before / after the value. */
37
+ /**
38
+ * One piece of a joined field: a path, optionally with text put before / after the value, a `{ template }` over the item (dropped
39
+ * when a placeholder is empty), or a `{ time }` path whose text is read as a time (see {@link FieldSource}) and dropped when it is not one.
40
+ */
22
41
  export type JoinPart = string | {
23
42
  path: string;
24
43
  prefix?: string;
25
44
  suffix?: string;
45
+ } | {
46
+ template: string;
47
+ } | {
48
+ time: string;
49
+ prefix?: string;
50
+ suffix?: string;
26
51
  };
27
52
  /** `{ template }` fills `{path}` placeholders from the item and yields nothing when one is empty; `when` makes it apply to one kind of item. */
28
53
  export interface TemplateSource {
@@ -38,7 +63,11 @@ export interface TemplateSource {
38
63
  * - a list of paths and templates: the first non-empty one wins;
39
64
  * - `{ template }`: `{path}` placeholders over the item, dropped when any of them is empty;
40
65
  * - `{ join }`: the non-empty parts joined with `sep` (default ` | `);
41
- * - `{ epoch }`: a Unix timestamp (seconds) as an ISO date; `{ date }`: the date part (first 10 characters) of an ISO timestamp.
66
+ * - `{ epoch }`: a Unix timestamp (seconds) as an ISO date; `{ date }`: the date part (first 10 characters) of an ISO timestamp;
67
+ * - `{ time }`: a time text the tool prints (ISO, the X API's `created_at`, `2026-10-27`, `08-26`, `3小时前`, `昨天 10:20`, ...) as an
68
+ * ISO date or timestamp, and nothing when the text is none of the exactly known formats (see cli/time-text.ts).
69
+ * A dotted path may hold a `key=value` segment that picks the first element of an array with that field value
70
+ * (`note_card.corner_tag_info.type=publish_time.text`).
42
71
  */
43
72
  export type FieldSource = string | readonly (string | TemplateSource)[] | TemplateSource | {
44
73
  join: readonly JoinPart[];
@@ -47,6 +76,8 @@ export type FieldSource = string | readonly (string | TemplateSource)[] | Templa
47
76
  epoch: string;
48
77
  } | {
49
78
  date: string;
79
+ } | {
80
+ time: string;
50
81
  };
51
82
  export interface CliOutputSpec {
52
83
  format: OutputFormat;
@@ -59,19 +90,32 @@ export interface CliOutputSpec {
59
90
  }[];
60
91
  /** Paths of the tool's own error text, read when `expect` fails (first non-empty one). */
61
92
  errorPaths?: readonly string[];
62
- /** text: how a line becomes an item (`tsv`: tab separated columns; `url-lines`: lines holding a URL, `url` + `title`). */
93
+ /**
94
+ * text: how a line becomes an item (`tsv`: tab separated columns; `url-lines`: lines holding a URL, `url` + `title`; `whole`: the
95
+ * whole stdout is ONE result, for a tool that prints just a block of text: its text capped at `maxChars` (default
96
+ * {@link WHOLE_OUTPUT_DEFAULT_CHARS}) with a note when it was cut, the title "<id>: <query>" and the link `cli://<id>?q=<query>`).
97
+ */
63
98
  lines?: {
64
99
  mode: 'tsv';
65
100
  columns: readonly string[];
66
101
  } | {
67
102
  mode: 'url-lines';
103
+ } | {
104
+ mode: 'whole';
105
+ maxChars?: number;
68
106
  };
69
- fields: {
70
- url: FieldSource;
107
+ /** Required (with `url`) for every mode except `whole`, which maps nothing. */
108
+ fields?: {
109
+ url?: FieldSource;
71
110
  title?: FieldSource;
72
111
  snippet?: FieldSource;
73
112
  publishedAt?: FieldSource;
74
113
  };
114
+ /** Items whose `path` equals the value are not results at all and are not counted as skipped (xhs: `model_type` is `hot_query` for the suggestion cards its result list also carries). */
115
+ skipWhen?: {
116
+ path: string;
117
+ equals: string | number | boolean;
118
+ };
75
119
  /** Strip HTML tags from title and snippet. */
76
120
  stripTags?: boolean;
77
121
  /** Values read as "empty" (`None`). */
@@ -83,16 +127,54 @@ export interface CliOutputSpec {
83
127
  /** Drop items without a title (a line that is not a result). */
84
128
  requireTitle?: boolean;
85
129
  }
130
+ /**
131
+ * How a tool reports a failed command in its machine-readable format (a YAML / JSON payload on stderr, else stdout), and what
132
+ * each of its error codes means. A listed code is mapped to a structured plugin error; a code that is not listed keeps the
133
+ * tool's own message (`<tool> search failed: [CODE] message`).
134
+ */
135
+ export interface CliErrorCodesSpec {
136
+ /** Dotted path of the tool's error code in the failure payload (`error.code`). */
137
+ codePath: string;
138
+ /** Dotted path of its message (`error.message`). */
139
+ messagePath?: string;
140
+ /** Codes that mean "not logged in" (CLI_NOT_LOGGED_IN). */
141
+ notLoggedIn?: readonly string[];
142
+ /** Exit codes that mean "not logged in" when the output carries no readable code. */
143
+ notLoggedInExit?: readonly number[];
144
+ /** Codes that mean "no results" (ENGINE_EMPTY). */
145
+ empty?: readonly string[];
146
+ /** Codes that mean the site answered with a web page or blocked the request: risk control, IP block, login wall (CLI_FAILED, said so). */
147
+ blocked?: readonly string[];
148
+ /** Case-insensitive fragments of the tool's message that mean the same (a JSON parse error on an HTML page: `Unexpected token '<'`). */
149
+ blockedPatterns?: readonly string[];
150
+ /** Codes that mean the tool cannot reach its browser (CLI_FAILED, not retryable). */
151
+ unavailable?: readonly string[];
152
+ /** Codes that mean a timeout (ENGINE_TIMEOUT). */
153
+ timeout?: readonly string[];
154
+ /** Codes that mean the tool rejected its arguments (CLI_CONTRACT_MISMATCH: the adapter does not match this version). */
155
+ usage?: readonly string[];
156
+ }
86
157
  export interface CliSearchSpec {
87
- /** Arguments after the binary. `{query}` and `{count}` are the placeholders; a token may embed one (`ytsearch{count}:{query}`). */
158
+ /**
159
+ * Arguments after the binary. `{query}` and `{count}` are the placeholders; a token may embed one (`ytsearch{count}:{query}`).
160
+ * A token that is exactly `{terms}` expands to the query split into one argv token per word (double quotes keep a phrase together):
161
+ * for tools that join their positional arguments themselves and would otherwise quote a one-token query as an exact phrase (`gh search`).
162
+ */
88
163
  argv: readonly string[];
89
164
  /** Largest `{count}` sent (the search call's count is clamped to 1..maxCount). */
90
165
  maxCount?: number;
166
+ /**
167
+ * Extra results asked of the tool beyond the count (`{count}` becomes count + overfetch), for tools whose list can hold entries the
168
+ * mapper must drop (bili: courses and series without a link). The mapper still returns at most `count`.
169
+ */
170
+ overfetch?: number;
91
171
  output: CliOutputSpec;
92
172
  /** Case-insensitive fragments of the tool's output that mean "no results" rather than a failure. */
93
173
  emptyWhen?: readonly string[];
94
174
  /** Case-insensitive fragments of the tool's output that mean "not logged in" (maps to CLI_NOT_LOGGED_IN). */
95
175
  notLoggedInPatterns?: readonly string[];
176
+ /** The tool's structured error codes (checked before the fragments above). */
177
+ errorCodes?: CliErrorCodesSpec;
96
178
  }
97
179
  export interface CliProbeSpec {
98
180
  versionArgs: readonly string[];
@@ -101,10 +183,14 @@ export interface CliProbeSpec {
101
183
  helpArgs: readonly string[];
102
184
  /** Fragments the help output must contain: the subcommands and flags that prove this is the tool the spec describes. */
103
185
  mustContain: readonly string[];
186
+ /** Appended to the reason when `mustContain` is not met (which version is known to have the contract, for example). */
187
+ contractHint?: string;
104
188
  }
105
189
  export interface CliLoginSpec {
106
190
  /** What the user runs themselves (`xhs login`); never run by the plugin. */
107
- command: string;
191
+ command?: string;
192
+ /** What the user does, in words, when the tool takes its login from somewhere the plugin cannot run (the login of the user's own Chrome): shown instead of a command. One of `command` / `hint` is required. */
193
+ hint?: string;
108
194
  /** Home-relative files that exist once the user has logged in. Only their existence is checked, never their content. */
109
195
  savedCredentialPaths?: readonly string[];
110
196
  /** The tool reads the browser's cookies by itself when it has no saved login: then it is never run without one. */
@@ -116,8 +202,15 @@ export interface CliAdapterSpec {
116
202
  bins: readonly string[];
117
203
  /** What the package is called, which can differ from the command (`pip install pyzhihu-cli` runs `zhihu`). */
118
204
  packageNote: string;
119
- /** Platform ids the spec can serve (`search.run platform=`); a user spec's platform is `custom-cli:<id>`. */
205
+ /**
206
+ * Platform ids the spec serves: the platforms whose backend chain it may sit in (`platformBackends.<platform>`). A user spec is
207
+ * also a platform of its own, `custom-cli:<id>`, and may list none when it is a general `engine`.
208
+ */
120
209
  platforms: readonly string[];
210
+ /** User specs only: also a general search engine, listed in `engines` as `custom-cli:<id>` (fused and de-duplicated with the others). */
211
+ engine?: boolean;
212
+ /** User specs only: 0..1, default {@link DEFAULT_CUSTOM_CONFIDENCE}. `sources.confidence.custom-cli:<id>` overrides it. */
213
+ confidence?: number;
121
214
  probe: CliProbeSpec;
122
215
  /** Every command word the argv templates use. */
123
216
  allowedSubcommands: readonly string[];
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Conservative parsing of the time texts CLI tools print (a field source `{ time }` of the adapter spec): an exact format is
3
+ * turned into an ISO date or timestamp, anything else gives nothing, so a result never carries a guessed time. Pure; the clock is
4
+ * a parameter. Chinese relative and calendar texts are read in China time (UTC+8), which is what the sites print.
5
+ * - ISO 8601 (`2026-10-27T08:38:08Z`, with or without a zone offset or fraction) -> normalized timestamp;
6
+ * - the `created_at` of the X API (`Tue Oct 27 08:38:08 +0000 2026`) -> timestamp;
7
+ * - `YYYY-MM-DD` -> that date; `MM-DD` -> the latest such date that is not after today (a date in the future means last year);
8
+ * - `N分钟前` / `N小时前` -> timestamp (now minus N); `N天前` -> date; `昨天 HH:MM` -> timestamp (China time).
9
+ * @module web-search-pro/cli/time-text
10
+ */
11
+ /** The text as an ISO date (`YYYY-MM-DD`) or timestamp, or undefined when it is not one of the formats above. */
12
+ export declare function normalizeTimeText(raw: string, now?: number): string | undefined;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The trial run of a custom CLI spec (settings card, "Try it"): what a search with the draft spec would do, shown before it is saved.
3
+ * It is a real run, not a simulation: the spec is validated by the rule every spec goes through (the read-only guard, no shell, no
4
+ * credentials in argv), the command is probed (version and help only), then ONE search for the sample query runs through the same
5
+ * runner with the spec's own timeout and output cap. The first results and the tool's own words come back; secrets are redacted,
6
+ * a login is never run, and nothing is stored.
7
+ * @module web-search-pro/cli/trial
8
+ */
9
+ import { type runCli } from '../util.ts';
10
+ import type { TrialResult } from '../rpc-types.ts';
11
+ export interface TrialOptions {
12
+ /** `enableCliBackends`: with it off no custom command runs, trial or search. */
13
+ enabled: boolean;
14
+ signal?: AbortSignal;
15
+ /** Test seams. */
16
+ run?: typeof runCli;
17
+ env?: NodeJS.ProcessEnv;
18
+ }
19
+ export declare function trialCli(id: string, rawSpec: unknown, query: string, options: TrialOptions): Promise<TrialResult>;
@@ -1,2 +1,18 @@
1
+ /**
2
+ * The Web Search Pro settings card, as the Plugins page renders it.
3
+ *
4
+ * The page owns the card frame (its title, disclosure and artwork come from the slot registration), so this component renders
5
+ * only what goes inside: the one-liner for `view: 'summary'`, and for `view: 'page'` a status summary, twelve groups (only
6
+ * "Common" open) and a save bar that stays in view.
7
+ *
8
+ * Common · Search order · Sources · Custom CLI · Reading and evidence · Scoring model · Built-in web tool route ·
9
+ * Runtime and backends · Network and cache · Ranking weights · Agent changes · Advanced: text mode and raw JSON
10
+ *
11
+ * Each group is its own module (`group-*.tsx`) built from the controls in `ui-kit.tsx`: the Host's own switches, buttons,
12
+ * badges, dialogs and help bubbles, plus the few controls the Host has no component for. Every public config field has
13
+ * exactly one entry in the groups (test/settings-card-render.test.ts counts them); the text of the last group is a view of
14
+ * the same fields, not a second place they live.
15
+ * @module web-search-pro/client/SettingsCard
16
+ */
1
17
  import type { SettingsCardProps } from './index.ts';
2
- export declare function SettingsCard(props: SettingsCardProps): string | import("react").JSX.Element | null;
18
+ export declare function SettingsCard(props: SettingsCardProps): import("react").JSX.Element;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The mark beside a setting that an agent changed with `config.*`: "Changed by agent", whose tooltip says what the agent set, what the
3
+ * configuration holds, why and when, and (outside the cramped list rows) the two buttons that settle it: adopt the value into the
4
+ * configuration, or revoke it. The data is the plugin's overlay, read once over the card's RPC channel when the panel opens and again
5
+ * on the refresh button (see group-agent.tsx).
6
+ * @module web-search-pro/client/agent-mark
7
+ */
8
+ import type { OverlayItem } from '../overlay-types.ts';
9
+ import type { Card } from './field-rows.tsx';
10
+ /** The overlay item of a key in the card's state, or undefined. */
11
+ export declare function useOverlayItem(card: Card, key: string): OverlayItem | undefined;
12
+ /** One sentence for the tooltip: the value the agent set, the one in the configuration, the reason, who and when. */
13
+ export declare function agentTip(t: Card['t'], item: OverlayItem): string;
14
+ /**
15
+ * `compact` shows the tag only (list rows have no room for buttons; the "Agent changes" group holds them); otherwise the tag is followed
16
+ * by "Adopt into configuration" and "Revoke".
17
+ */
18
+ export declare function AgentMark({ card, itemKey, compact }: {
19
+ card: Card;
20
+ itemKey: string;
21
+ compact?: boolean;
22
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The frame around the groups: the status summary on top (with the warnings dialog) and the save bar at the bottom.
3
+ *
4
+ * The Host's `SettingsForm` offers one save button below the controls. This card needs the bar to stay in view while a long
5
+ * page scrolls, to say how many edits are waiting, and to offer "Discard", so the frame is built here; the behaviors a
6
+ * settings form has are kept: it says so when the settings are not served or read-only, and it drops the staged edits when
7
+ * the page is left.
8
+ * @module web-search-pro/client/card-frame
9
+ */
10
+ import { type ReactNode } from 'react';
11
+ import { type ChainInput } from '../default-chain.ts';
12
+ import { type Card } from './field-rows.tsx';
13
+ import type { WebSearchCardState } from './form.ts';
14
+ /** What the default chain rule reads from the staged settings: the list, the preferences, the ready common sources, the policy. */
15
+ export declare function chainInputOf(snapshot: Pick<WebSearchCardState, 'fields' | 'credentials'>): ChainInput;
16
+ /** The chain a plain search would try, from the staged settings; undefined when the draft leaves nothing to try. */
17
+ export declare function chainOf(snapshot: Pick<WebSearchCardState, 'fields' | 'credentials'>): string[] | undefined;
18
+ /**
19
+ * The chain a plain search tries once the agent's changes (engines, priority, disabled of the overlay) are on top of the staged settings,
20
+ * by the same rule; undefined while the agent changed none of the three, an empty list when it would leave nothing to try.
21
+ */
22
+ export declare function agentChainOf(snapshot: Pick<WebSearchCardState, 'fields' | 'credentials' | 'server'>): string[] | undefined;
23
+ /** Everything the warnings badge counts: what the validation says about a field, and the rubric problems. */
24
+ export declare function warningsOf(snapshot: WebSearchCardState, t: Card['t']): string[];
25
+ export declare function SummaryBar({ card }: {
26
+ card: Card;
27
+ }): import("react").JSX.Element;
28
+ export declare function SaveBar({ card }: {
29
+ card: Card;
30
+ }): import("react").JSX.Element;
31
+ /** The page frame: nothing but a notice while the settings are not served; the staged edits are dropped when the page is left. */
32
+ export declare function Frame({ card, children }: {
33
+ card: Card;
34
+ children: ReactNode;
35
+ }): import("react").JSX.Element;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * The form side of the custom CLI editor: a `cliAdapters` entry (the JSON spec) as the fields of the edit dialog and back. Two
3
+ * views of one object: the form writes the keys it has controls for onto a copy of the spec and leaves every other key as it
4
+ * was (searches, read, env, login, errorCodes, a field mapping that is not a plain path), and the JSON box edits the whole spec.
5
+ * Validation is `validateCliAdapterSpec`, the function the server registers specs with; its messages are sorted to the field they
6
+ * are about. `allowedSubcommands` is derived from the command words of the argv templates, never typed.
7
+ * Pure: no Host, no DOM.
8
+ * @module web-search-pro/client/cli-form
9
+ */
10
+ import { WHOLE_OUTPUT_DEFAULT_CHARS, type OutputFormat } from '../cli/spec.ts';
11
+ type Json = Record<string, unknown>;
12
+ /** The result fields the form maps, in display order; each takes a dotted path into one item of the tool's output. */
13
+ export declare const FIELD_KEYS: readonly ["url", "title", "snippet", "publishedAt"];
14
+ export type FieldKey = typeof FIELD_KEYS[number];
15
+ /** How a plain text tool's lines become items (`whole` is a switch of its own). */
16
+ export declare const LINE_MODES: readonly ["url-lines", "tsv"];
17
+ export type LineMode = typeof LINE_MODES[number];
18
+ export interface CliForm {
19
+ /** The key in `cliAdapters` (`custom-cli:<id>` everywhere else). */
20
+ id: string;
21
+ /** The command: a name on PATH, never a path. */
22
+ bin: string;
23
+ /** The argument template, one token per entry; `{query}`, `{count}` and `{terms}` are filled in. */
24
+ argv: string[];
25
+ format: OutputFormat;
26
+ /** Text output only: the whole stdout is one result (no field mapping). */
27
+ whole: boolean;
28
+ wholeMax: string;
29
+ /** json / yaml: dotted path of the result array (empty = the root array or the first array found). */
30
+ itemsPath: string;
31
+ linesMode: LineMode;
32
+ /** tsv: the column names, comma separated. */
33
+ columns: string;
34
+ /** A plain dotted path per result field; a mapping that is more than a path is kept as it is and listed in `complex`. */
35
+ fields: Record<FieldKey, string>;
36
+ complex: FieldKey[];
37
+ timeoutMs: string;
38
+ maxOutputBytes: string;
39
+ /** The purposes: a general search engine, and/or the platforms whose backend chain it may sit in. */
40
+ engine: boolean;
41
+ platforms: string[];
42
+ /** Empty = the default (0.5). */
43
+ confidence: string;
44
+ packageNote: string;
45
+ /** The probe: the help command (space separated) and the fragments its output must contain. */
46
+ helpArgs: string;
47
+ mustContain: string[];
48
+ }
49
+ /** The spec a new entry starts from: a JSON-printing tool mapped url / title / snippet. The form fills the command in. */
50
+ export declare function newSpec(): Json;
51
+ /** The example of the dialog: `echo`, whose whole output is the result (no field mapping), a way to see the pieces work without a real tool. */
52
+ export declare function echoSpec(): Json;
53
+ /** The form fields of a spec (plain or not): everything the dialog shows, as text. */
54
+ export declare function specToForm(id: string, raw: unknown): CliForm;
55
+ /** The command words the argv templates of a spec use, in order, without repeats: what `allowedSubcommands` must list. */
56
+ export declare function derivedSubcommands(spec: Json): string[];
57
+ /**
58
+ * The spec the form describes, built on `base` (the entry as it was: every key the form has no control for is kept). Nothing is
59
+ * validated here; a value that is not what its box wants is written as typed so `validateCliAdapterSpec` names it.
60
+ */
61
+ export declare function formToSpec(form: CliForm, base?: Json): Json;
62
+ /** The names of the dialog's fields that an error message can be about. */
63
+ export type ErrorField = 'id' | 'bin' | 'argv' | 'format' | 'itemsPath' | 'lines' | 'fields' | FieldKey | 'timeoutMs' | 'maxOutputBytes' | 'platforms' | 'engine' | 'confidence' | 'packageNote' | 'probe' | 'general';
64
+ /** Sort the validator's messages (`cliAdapters.<id>.<path>: ...`) to the dialog field they are about. */
65
+ export declare function errorsByField(id: string, errors: readonly string[]): Partial<Record<ErrorField, string[]>>;
66
+ export interface CliCheck {
67
+ spec: Json;
68
+ /** The validator's messages (empty = valid). */
69
+ errors: string[];
70
+ byField: Partial<Record<ErrorField, string[]>>;
71
+ ok: boolean;
72
+ }
73
+ /** Build the spec of a form and validate it the way the server does; `taken` are the ids of the other entries (a new id may not repeat one). */
74
+ export declare function checkForm(form: CliForm, base: Json, taken?: readonly string[]): CliCheck;
75
+ /** Validate a spec (the JSON view): the server's function, plus the one rule only the editor has (an id is not used twice). */
76
+ export declare function checkSpec(id: string, spec: Json, taken?: readonly string[]): CliCheck;
77
+ /** The confidence the entry has: its own, else the default. */
78
+ export declare const confidenceOfForm: (form: CliForm) => number;
79
+ export { WHOLE_OUTPUT_DEFAULT_CHARS };
80
+ /** The JSON text of a spec as the dialog's raw box prints it. */
81
+ export declare const specText: (spec: Json) => string;
82
+ /** The spec a raw JSON text holds, or the reason it is not one. */
83
+ export declare function parseSpecText(text: string): {
84
+ spec: Json;
85
+ } | {
86
+ error: string;
87
+ };
88
+ /** The `cliAdapters` object of the staged text (empty text = no entries); undefined when it is not an object. */
89
+ export declare function adaptersOf(text: string): Json | undefined;
90
+ /**
91
+ * The `cliAdapters` text with entry `id` set to `spec` (a new key goes last), or removed when `spec` is undefined. The other
92
+ * entries are kept as they were. The object with no entries comes back as the empty text, which the form model stores as "not set".
93
+ * Undefined when the current text is not an object (the raw JSON box has to be fixed first).
94
+ */
95
+ export declare function withAdapter(text: string, id: string, spec: Json | undefined): string | undefined;
96
+ /** A free id for a copy or a new entry: `base`, `base-2`, `base-3`, ... */
97
+ export declare function freeId(base: string, taken: readonly string[]): string;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The comment printed in front of every key of the text view ("Advanced: text mode"), in the language of the card: what the
3
+ * setting is for, its allowed values or range, its default, and the risk when there is one. Comment lines start with `#`, so
4
+ * the text stays valid YAML and a round trip never reads a comment as data. Pure (it imports only config-groups.ts): the text view and the
5
+ * tests read it, and the client bundle includes it. Nothing here names a secret value: keys are only ever referenced by name.
6
+ * @module web-search-pro/client/field-docs
7
+ */
8
+ export type DocLang = 'en' | 'zh';
9
+ /** The doc of a config field in a language; undefined only for a field the card does not know. */
10
+ export declare function fieldDoc(field: string, lang?: DocLang | string): string | undefined;
11
+ /** The docs of the groups of keys and the header of the text view. */
12
+ export declare function textViewDocs(lang?: DocLang | string): {
13
+ header: readonly string[];
14
+ group: Readonly<Record<string, string>>;
15
+ };
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Which dictionary entry names a field, which fields carry a `?` text of their own, and the facts about the sources the
3
+ * card lists. Pure data (no imports): the rows, the text view and the tests all read it.
4
+ * @module web-search-pro/client/field-keys
5
+ */
6
+ import { type ConfigGroupId } from '../config-groups.ts';
7
+ export declare function labelKey(field: string): string;
8
+ /** The fields whose dictionary has a `<key>Help` text (a longer explanation behind the `?`). */
9
+ export declare const WITH_HELP: ReadonlySet<string>;
10
+ /** `?` text applies to the generic budget keys too. */
11
+ export declare const hasHelp: (field: string) => boolean;
12
+ /** Dictionary key of the sentence saying why a start-up-only field needs a plugin restart (restart.ts lists the fields). */
13
+ export declare function restartWhyKey(field: string): string;
14
+ export type SourceTier = 'paid' | 'free-quota' | 'anonymous';
15
+ /** One source the "Sources" list shows and its edit dialog is made of. */
16
+ export interface SourceDef {
17
+ id: string;
18
+ name: string;
19
+ tier: SourceTier;
20
+ /** "常用": the plugin's recommended source (pinned to the registry descriptors by a test). */
21
+ common?: boolean;
22
+ /** The write-only key of the source (`CredentialId`), and the field naming the credential / variable it is stored under. */
23
+ credential?: string;
24
+ envField?: string;
25
+ defaultEnv?: string;
26
+ baseUrlField?: string;
27
+ /** Other fields the dialog holds, in order. */
28
+ extra?: readonly string[];
29
+ /** The request budget of the source (`sources.budget.<id>.total|daily`). */
30
+ budget?: boolean;
31
+ }
32
+ export declare const SOURCE_DEFS: readonly SourceDef[];
33
+ /** Fields of a source dialog in display order (the key itself is a credential, not a field). */
34
+ export declare function sourceFields(def: SourceDef): string[];
35
+ /** Fields shown as JSON objects, each in its own dialog: the field, the group it sits in. */
36
+ export declare const JSON_FIELDS: readonly {
37
+ field: string;
38
+ group: 'judge' | 'runtime' | 'platform' | 'advanced';
39
+ }[];
40
+ /** Group of the text view of any field: the group of its top-level key (see config-groups.ts, the one list of the layout). */
41
+ export declare function textGroupOf(field: string): ConfigGroupId;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Rows for the configuration fields the groups edit, wired to the card's staged form state.
3
+ *
4
+ * One component per control kind (switch, select, text, number, list of ids). Each is the single entry of its field: it renders
5
+ * `data-wsp-field="<field>"`, which test/settings-card-render.test.ts counts, and it reads the label, the one-line hint and the
6
+ * optional `?` text from the dictionary by the field's name (`<key>`, `<key>Hint`, `<key>Help`, see field-keys.ts).
7
+ * @module web-search-pro/client/field-rows
8
+ */
9
+ import type { SettingsCardProps } from './index.ts';
10
+ import type { CardFieldState, WebSearchCardState } from './form.ts';
11
+ import { fill } from './fill.ts';
12
+ import { type RowLabels, type SelectOption } from './ui-kit.tsx';
13
+ export type Card = SettingsCardProps;
14
+ export type Translator = Card['t'];
15
+ export type LabelKey = Parameters<Translator>[0];
16
+ export { fill };
17
+ export declare function rowLabels(t: Translator): RowLabels;
18
+ /** The id of a field's control, tied to its label. */
19
+ export declare const controlId: (field: string) => string;
20
+ /** The units a number field is written with. */
21
+ declare const UNIT_KEYS: {
22
+ readonly ms: "unitMs";
23
+ readonly sec: "unitSeconds";
24
+ readonly chars: "unitChars";
25
+ readonly count: "unitCount";
26
+ readonly tokens: "unitTokens";
27
+ readonly days: "unitDays";
28
+ readonly rounds: "unitCount";
29
+ };
30
+ export type Unit = keyof typeof UNIT_KEYS;
31
+ export interface FieldProps {
32
+ card: Card;
33
+ /** The setting field this row is the entry of. */
34
+ field: string;
35
+ /** Replaces the dictionary hint. */
36
+ hint?: string;
37
+ placeholder?: string;
38
+ /** Replaces the dictionary label. */
39
+ label?: string;
40
+ /** A short warning badge beside the label. */
41
+ risk?: string;
42
+ /** Hide the "overridden" badge and reset: for fields whose "default" is a computed one. */
43
+ code?: boolean;
44
+ }
45
+ /** How many of these fields carry an override: the number a group's badge shows. */
46
+ export declare function useOverriddenCount(card: Card, fields: readonly string[]): number;
47
+ /** The staged state of a field. */
48
+ export declare const stateOf: (snapshot: WebSearchCardState, field: string) => CardFieldState | undefined;
49
+ export declare function useField(card: Card, field: string): {
50
+ state: CardFieldState;
51
+ disabled: boolean;
52
+ edit: (text: string) => void;
53
+ reset: () => void;
54
+ };
55
+ /** A boolean field as a switch. */
56
+ export declare function SwitchRow(props: FieldProps): import("react").JSX.Element;
57
+ /** An enumerated field as a drop-down. */
58
+ export declare function SelectRow(props: FieldProps & {
59
+ options: readonly SelectOption[];
60
+ }): import("react").JSX.Element;
61
+ /** A free-text field. */
62
+ export declare function TextRow(props: FieldProps): import("react").JSX.Element;
63
+ /** A number field with its unit written after the input. */
64
+ export declare function NumberRow(props: FieldProps & {
65
+ unit?: Unit;
66
+ }): import("react").JSX.Element;
67
+ declare const parseList: (text: string) => string[];
68
+ /** A comma-separated list (engine ids, domains) as removable chips with an add box. */
69
+ export declare function ListRow(props: FieldProps): import("react").JSX.Element;
70
+ export { parseList };
@@ -0,0 +1,2 @@
1
+ /** Fill `{name}` placeholders of a dictionary entry. */
2
+ export declare const fill: (text: string, values: Record<string, string | number>) => string;
@@ -12,7 +12,7 @@
12
12
  */
13
13
  export type Json = Record<string, unknown>;
14
14
  /** Top-level config fields (one Host write each). */
15
- export type TopField = 'engines' | 'parallelEngines' | 'searchMaxResults' | 'timeoutMs' | 'fetchDefaultChars' | 'exaContentsPerUrlChars' | 'exaContentsTotalChars' | 'exaApiKeyEnv' | 'jinaApiKeyEnv' | 'githubTokenEnv' | 'bochaApiKeyEnv' | 'bochaBaseUrl' | 'bochaSummary' | 'searxngUrl' | 'openalexMailto' | 'enableCliBackends' | 'opencliEnabled' | 'agentReachEnabled' | 'providerId' | 'registerProvider' | 'toolSurface' | 'playwright' | 'ttlSeconds' | 'memoryCacheEntries' | 'rrfConstant' | 'freshnessBoost' | 'freshnessDays' | 'authorityBoost' | 'authorityDomains' | 'dbPath' | 'allowProxyFakeIp' | 'platformRules' | 'customPlatforms' | 'browserBindings' | 'platformBackends' | 'cliAdapters' | 'verbose';
15
+ export type TopField = 'engines' | 'parallelEngines' | 'searchMaxResults' | 'timeoutMs' | 'fetchDefaultChars' | 'exaContentsPerUrlChars' | 'exaContentsTotalChars' | 'exaApiKeyEnv' | 'jinaApiKeyEnv' | 'githubTokenEnv' | 'twitterAuthTokenEnv' | 'twitterCt0Env' | 'bochaApiKeyEnv' | 'bochaBaseUrl' | 'bochaSummary' | 'deepseekFetch' | 'searxngUrl' | 'openalexMailto' | 'enableCliBackends' | 'opencliEnabled' | 'agentReachEnabled' | 'providerId' | 'registerProvider' | 'toolSurface' | 'playwright' | 'ttlSeconds' | 'memoryCacheEntries' | 'rrfConstant' | 'freshnessBoost' | 'freshnessDays' | 'authorityBoost' | 'authorityDomains' | 'dbPath' | 'allowProxyFakeIp' | 'platformRules' | 'customPlatforms' | 'browserBindings' | 'platformBackends' | 'cliAdapters' | 'verbose';
16
16
  /** Options inside `evidence` / `provider`, addressed by their dotted config path. */
17
17
  export type PathField = 'evidence.autoProviders' | 'evidence.sourcePolicy' | 'evidence.maxRounds' | 'evidence.maxQueries' | 'evidence.judge.mode' | 'evidence.hybridBorderline' | 'evidence.judge.provider' | 'evidence.maxJevQuestions' | 'evidence.judge.allowLlm' | 'evidence.judge.providers' | 'evidence.coverage.mode' | 'evidence.coverage.provider' | 'evidence.coverage.thresholds.weak' | 'evidence.coverage.thresholds.covered' | 'evidence.budget.perSearchInputTokens' | 'evidence.budget.dailyInputTokens' | 'evidence.budget.timezone' | 'evidence.budget.providers' | 'provider.evidence' | 'provider.deadlineMs' | 'sources.priority' | 'sources.disabled';
18
18
  /** One rubric override entry (`evidence.rubrics.<id>`) and one keyed-source field. */
@@ -20,7 +20,9 @@ export type RubricField = `evidence.rubrics.${string}`;
20
20
  export type KeyedField = `keyedSources.${string}.apiKeyEnv` | `keyedSources.${string}.baseUrl`;
21
21
  /** One axis of one source's request budget (`sources.budget.<id>.total|daily`). */
22
22
  export type BudgetField = `sources.budget.${string}.${'total' | 'daily'}`;
23
- export type SettingField = TopField | PathField | RubricField | KeyedField | BudgetField;
23
+ /** The confidence of one source or platform backend (`sources.confidence.<id>`): the ids are open, so these fields are made on demand. */
24
+ export type ConfidenceField = `sources.confidence.${string}`;
25
+ export type SettingField = TopField | PathField | RubricField | KeyedField | BudgetField | ConfidenceField;
24
26
  export type RootKey = 'evidence' | 'provider' | 'keyedSources' | 'sources';
25
27
  export type FieldWrite = {
26
28
  kind: 'set';
@@ -89,8 +91,11 @@ export declare const DEFAULTS: {
89
91
  };
90
92
  readonly toolSurface: "indexed";
91
93
  readonly bochaApiKeyEnv: "BOCHA_SEARCH_API_KEY";
94
+ readonly twitterAuthTokenEnv: "TWITTER_AUTH_TOKEN";
95
+ readonly twitterCt0Env: "TWITTER_CT0";
92
96
  readonly bochaBaseUrl: "https://api.bocha.cn";
93
97
  readonly bochaSummary: true;
98
+ readonly deepseekFetch: false;
94
99
  };
95
100
  /** Top-level fields, in display order. */
96
101
  export declare const FIELD_SPECS: readonly FieldSpec[];
@@ -105,11 +110,15 @@ export declare const KEYED_SPECS: readonly PathSpec[];
105
110
  /** The sources the card has a request budget for: Bocha and the keyed sources (any registered id works in settings.yaml). */
106
111
  export declare const BUDGETED_SOURCES: readonly string[];
107
112
  export declare const BUDGET_SPECS: readonly PathSpec[];
113
+ /** `sources.confidence.<id>`: a number 0..1; empty = the default (1 for a built-in source, the spec's own for a custom CLI). */
114
+ export declare const confidenceSpec: (id: string) => PathSpec;
115
+ export declare const confidenceField: (id: string) => ConfidenceField;
116
+ export declare const CONFIDENCE_PREFIX = "sources.confidence.";
108
117
  /** The spec of a rubric override entry: the whole object as one JSON draft, which the rubric editor builds field by field. */
109
118
  export declare const rubricSpec: (id: string) => PathSpec;
110
119
  export declare const rubricField: (id: string) => RubricField;
111
120
  /** Fields that a Host write can never take as text (credentials go through the credentials remote). */
112
- export declare const CREDENTIAL_IDS: readonly ["exa", "jina", "github", "bocha", ...`keyed:${string}`[]];
121
+ export declare const CREDENTIAL_IDS: readonly ["exa", "jina", "github", "bocha", "twitter-auth-token", "twitter-ct0", ...`keyed:${string}`[]];
113
122
  export type CredentialId = typeof CREDENTIAL_IDS[number];
114
123
  /** The settings field holding the credentials ref / environment variable name of each credential, and its default name. */
115
124
  export declare function credentialRef(id: CredentialId): {