scoutline 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/README.md +60 -26
  2. package/dist/capabilities/search.d.ts +18 -4
  3. package/dist/capabilities/search.d.ts.map +1 -1
  4. package/dist/commands/config.d.ts.map +1 -1
  5. package/dist/commands/config.js +14 -5
  6. package/dist/commands/config.js.map +1 -1
  7. package/dist/commands/crawl.d.ts.map +1 -1
  8. package/dist/commands/crawl.js +2 -1
  9. package/dist/commands/crawl.js.map +1 -1
  10. package/dist/commands/doctor.d.ts.map +1 -1
  11. package/dist/commands/doctor.js +2 -1
  12. package/dist/commands/doctor.js.map +1 -1
  13. package/dist/commands/init.d.ts +42 -1
  14. package/dist/commands/init.d.ts.map +1 -1
  15. package/dist/commands/init.js +42 -5
  16. package/dist/commands/init.js.map +1 -1
  17. package/dist/commands/map.d.ts.map +1 -1
  18. package/dist/commands/map.js +2 -1
  19. package/dist/commands/map.js.map +1 -1
  20. package/dist/commands/quota.d.ts.map +1 -1
  21. package/dist/commands/quota.js +2 -2
  22. package/dist/commands/quota.js.map +1 -1
  23. package/dist/commands/read.d.ts.map +1 -1
  24. package/dist/commands/read.js +2 -1
  25. package/dist/commands/read.js.map +1 -1
  26. package/dist/commands/repo.js +1 -1
  27. package/dist/commands/research.d.ts.map +1 -1
  28. package/dist/commands/research.js +2 -1
  29. package/dist/commands/research.js.map +1 -1
  30. package/dist/commands/search.d.ts +54 -6
  31. package/dist/commands/search.d.ts.map +1 -1
  32. package/dist/commands/search.js +273 -25
  33. package/dist/commands/search.js.map +1 -1
  34. package/dist/index.d.ts +72 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +364 -8
  37. package/dist/index.js.map +1 -1
  38. package/dist/lib/code-mode.d.ts +12 -0
  39. package/dist/lib/code-mode.d.ts.map +1 -1
  40. package/dist/lib/code-mode.js +18 -10
  41. package/dist/lib/code-mode.js.map +1 -1
  42. package/dist/lib/config-store.d.ts +45 -1
  43. package/dist/lib/config-store.d.ts.map +1 -1
  44. package/dist/lib/config-store.js +70 -1
  45. package/dist/lib/config-store.js.map +1 -1
  46. package/dist/lib/config.d.ts.map +1 -1
  47. package/dist/lib/config.js +5 -1
  48. package/dist/lib/config.js.map +1 -1
  49. package/dist/lib/errors.d.ts +7 -1
  50. package/dist/lib/errors.d.ts.map +1 -1
  51. package/dist/lib/errors.js +8 -2
  52. package/dist/lib/errors.js.map +1 -1
  53. package/dist/lib/execution.d.ts +14 -5
  54. package/dist/lib/execution.d.ts.map +1 -1
  55. package/dist/lib/execution.js +25 -6
  56. package/dist/lib/execution.js.map +1 -1
  57. package/dist/lib/mcp-client.d.ts +7 -0
  58. package/dist/lib/mcp-client.d.ts.map +1 -1
  59. package/dist/lib/mcp-client.js +11 -1
  60. package/dist/lib/mcp-client.js.map +1 -1
  61. package/dist/lib/parse-zoned-instant.d.ts +13 -0
  62. package/dist/lib/parse-zoned-instant.d.ts.map +1 -0
  63. package/dist/lib/parse-zoned-instant.js +17 -0
  64. package/dist/lib/parse-zoned-instant.js.map +1 -0
  65. package/dist/lib/quota-mapping.d.ts +4 -2
  66. package/dist/lib/quota-mapping.d.ts.map +1 -1
  67. package/dist/lib/quota-mapping.js +25 -2
  68. package/dist/lib/quota-mapping.js.map +1 -1
  69. package/dist/lib/redact.d.ts +3 -2
  70. package/dist/lib/redact.d.ts.map +1 -1
  71. package/dist/lib/redact.js +90 -24
  72. package/dist/lib/redact.js.map +1 -1
  73. package/dist/lib/timeout.d.ts +28 -0
  74. package/dist/lib/timeout.d.ts.map +1 -0
  75. package/dist/lib/timeout.js +30 -0
  76. package/dist/lib/timeout.js.map +1 -0
  77. package/dist/lib/url.d.ts +10 -4
  78. package/dist/lib/url.d.ts.map +1 -1
  79. package/dist/lib/url.js +21 -6
  80. package/dist/lib/url.js.map +1 -1
  81. package/dist/providers/arxiv/client.d.ts +4 -1
  82. package/dist/providers/arxiv/client.d.ts.map +1 -1
  83. package/dist/providers/arxiv/client.js +11 -3
  84. package/dist/providers/arxiv/client.js.map +1 -1
  85. package/dist/providers/bocha/adapter.d.ts +43 -0
  86. package/dist/providers/bocha/adapter.d.ts.map +1 -0
  87. package/dist/providers/bocha/adapter.js +197 -0
  88. package/dist/providers/bocha/adapter.js.map +1 -0
  89. package/dist/providers/bocha/client.d.ts +51 -0
  90. package/dist/providers/bocha/client.d.ts.map +1 -0
  91. package/dist/providers/bocha/client.js +104 -0
  92. package/dist/providers/bocha/client.js.map +1 -0
  93. package/dist/providers/bocha/credentials.d.ts +12 -0
  94. package/dist/providers/bocha/credentials.d.ts.map +1 -0
  95. package/dist/providers/bocha/credentials.js +29 -0
  96. package/dist/providers/bocha/credentials.js.map +1 -0
  97. package/dist/providers/bocha/diagnostics.d.ts +17 -0
  98. package/dist/providers/bocha/diagnostics.d.ts.map +1 -0
  99. package/dist/providers/bocha/diagnostics.js +33 -0
  100. package/dist/providers/bocha/diagnostics.js.map +1 -0
  101. package/dist/providers/brave/adapter.d.ts.map +1 -1
  102. package/dist/providers/brave/adapter.js +4 -3
  103. package/dist/providers/brave/adapter.js.map +1 -1
  104. package/dist/providers/brave/client.d.ts +1 -0
  105. package/dist/providers/brave/client.d.ts.map +1 -1
  106. package/dist/providers/brave/client.js +4 -6
  107. package/dist/providers/brave/client.js.map +1 -1
  108. package/dist/providers/brave/credentials.d.ts +2 -0
  109. package/dist/providers/brave/credentials.d.ts.map +1 -1
  110. package/dist/providers/brave/credentials.js +2 -0
  111. package/dist/providers/brave/credentials.js.map +1 -1
  112. package/dist/providers/catalog.d.ts +34 -0
  113. package/dist/providers/catalog.d.ts.map +1 -0
  114. package/dist/providers/catalog.js +57 -0
  115. package/dist/providers/catalog.js.map +1 -0
  116. package/dist/providers/crossref/adapter.js +2 -2
  117. package/dist/providers/crossref/adapter.js.map +1 -1
  118. package/dist/providers/crossref/client.d.ts +4 -1
  119. package/dist/providers/crossref/client.d.ts.map +1 -1
  120. package/dist/providers/crossref/client.js +11 -3
  121. package/dist/providers/crossref/client.js.map +1 -1
  122. package/dist/providers/crossref/diagnostics.d.ts +1 -1
  123. package/dist/providers/crossref/diagnostics.js +1 -1
  124. package/dist/providers/crossref/diagnostics.js.map +1 -1
  125. package/dist/providers/europepmc/adapter.js +2 -2
  126. package/dist/providers/europepmc/adapter.js.map +1 -1
  127. package/dist/providers/europepmc/client.d.ts +4 -1
  128. package/dist/providers/europepmc/client.d.ts.map +1 -1
  129. package/dist/providers/europepmc/client.js +11 -3
  130. package/dist/providers/europepmc/client.js.map +1 -1
  131. package/dist/providers/exa/client.d.ts +1 -0
  132. package/dist/providers/exa/client.d.ts.map +1 -1
  133. package/dist/providers/exa/client.js +3 -2
  134. package/dist/providers/exa/client.js.map +1 -1
  135. package/dist/providers/exa/credentials.d.ts +2 -0
  136. package/dist/providers/exa/credentials.d.ts.map +1 -1
  137. package/dist/providers/exa/credentials.js +2 -0
  138. package/dist/providers/exa/credentials.js.map +1 -1
  139. package/dist/providers/firecrawl/adapter.d.ts.map +1 -1
  140. package/dist/providers/firecrawl/adapter.js +2 -1
  141. package/dist/providers/firecrawl/adapter.js.map +1 -1
  142. package/dist/providers/firecrawl/client.d.ts +1 -0
  143. package/dist/providers/firecrawl/client.d.ts.map +1 -1
  144. package/dist/providers/firecrawl/client.js +3 -2
  145. package/dist/providers/firecrawl/client.js.map +1 -1
  146. package/dist/providers/firecrawl/credentials.d.ts +2 -0
  147. package/dist/providers/firecrawl/credentials.d.ts.map +1 -1
  148. package/dist/providers/firecrawl/credentials.js +2 -0
  149. package/dist/providers/firecrawl/credentials.js.map +1 -1
  150. package/dist/providers/firecrawl/quota.d.ts.map +1 -1
  151. package/dist/providers/firecrawl/quota.js +5 -2
  152. package/dist/providers/firecrawl/quota.js.map +1 -1
  153. package/dist/providers/jina/adapter.d.ts.map +1 -1
  154. package/dist/providers/jina/adapter.js +6 -4
  155. package/dist/providers/jina/adapter.js.map +1 -1
  156. package/dist/providers/jina/client.d.ts +2 -0
  157. package/dist/providers/jina/client.d.ts.map +1 -1
  158. package/dist/providers/jina/client.js +6 -5
  159. package/dist/providers/jina/client.js.map +1 -1
  160. package/dist/providers/jina/credentials.d.ts +2 -0
  161. package/dist/providers/jina/credentials.d.ts.map +1 -1
  162. package/dist/providers/jina/credentials.js +2 -0
  163. package/dist/providers/jina/credentials.js.map +1 -1
  164. package/dist/providers/kagi/adapter.d.ts +44 -0
  165. package/dist/providers/kagi/adapter.d.ts.map +1 -0
  166. package/dist/providers/kagi/adapter.js +188 -0
  167. package/dist/providers/kagi/adapter.js.map +1 -0
  168. package/dist/providers/kagi/client.d.ts +41 -0
  169. package/dist/providers/kagi/client.d.ts.map +1 -0
  170. package/dist/providers/kagi/client.js +100 -0
  171. package/dist/providers/kagi/client.js.map +1 -0
  172. package/dist/providers/kagi/credentials.d.ts +15 -0
  173. package/dist/providers/kagi/credentials.d.ts.map +1 -0
  174. package/dist/providers/kagi/credentials.js +35 -0
  175. package/dist/providers/kagi/credentials.js.map +1 -0
  176. package/dist/providers/kagi/diagnostics.d.ts +17 -0
  177. package/dist/providers/kagi/diagnostics.d.ts.map +1 -0
  178. package/dist/providers/kagi/diagnostics.js +33 -0
  179. package/dist/providers/kagi/diagnostics.js.map +1 -0
  180. package/dist/providers/linkup/client.d.ts +1 -0
  181. package/dist/providers/linkup/client.d.ts.map +1 -1
  182. package/dist/providers/linkup/client.js +3 -2
  183. package/dist/providers/linkup/client.js.map +1 -1
  184. package/dist/providers/linkup/credentials.d.ts +2 -0
  185. package/dist/providers/linkup/credentials.d.ts.map +1 -1
  186. package/dist/providers/linkup/credentials.js +2 -0
  187. package/dist/providers/linkup/credentials.js.map +1 -1
  188. package/dist/providers/minimax/adapter.d.ts.map +1 -1
  189. package/dist/providers/minimax/adapter.js +2 -2
  190. package/dist/providers/minimax/adapter.js.map +1 -1
  191. package/dist/providers/minimax/coding-plan-client.d.ts +1 -0
  192. package/dist/providers/minimax/coding-plan-client.d.ts.map +1 -1
  193. package/dist/providers/minimax/coding-plan-client.js +3 -2
  194. package/dist/providers/minimax/coding-plan-client.js.map +1 -1
  195. package/dist/providers/minimax/quota-client.d.ts +1 -0
  196. package/dist/providers/minimax/quota-client.d.ts.map +1 -1
  197. package/dist/providers/minimax/quota-client.js +3 -2
  198. package/dist/providers/minimax/quota-client.js.map +1 -1
  199. package/dist/providers/openalex/client.d.ts +2 -0
  200. package/dist/providers/openalex/client.d.ts.map +1 -1
  201. package/dist/providers/openalex/client.js +10 -3
  202. package/dist/providers/openalex/client.js.map +1 -1
  203. package/dist/providers/openalex/diagnostics.d.ts +1 -1
  204. package/dist/providers/openalex/diagnostics.js +1 -1
  205. package/dist/providers/openalex/diagnostics.js.map +1 -1
  206. package/dist/providers/parallel/client.d.ts +1 -0
  207. package/dist/providers/parallel/client.d.ts.map +1 -1
  208. package/dist/providers/parallel/client.js +3 -2
  209. package/dist/providers/parallel/client.js.map +1 -1
  210. package/dist/providers/parallel/credentials.d.ts +2 -0
  211. package/dist/providers/parallel/credentials.d.ts.map +1 -1
  212. package/dist/providers/parallel/credentials.js +2 -0
  213. package/dist/providers/parallel/credentials.js.map +1 -1
  214. package/dist/providers/perplexity/client.d.ts +2 -0
  215. package/dist/providers/perplexity/client.d.ts.map +1 -1
  216. package/dist/providers/perplexity/client.js +5 -4
  217. package/dist/providers/perplexity/client.js.map +1 -1
  218. package/dist/providers/perplexity/credentials.d.ts +2 -0
  219. package/dist/providers/perplexity/credentials.d.ts.map +1 -1
  220. package/dist/providers/perplexity/credentials.js +2 -0
  221. package/dist/providers/perplexity/credentials.js.map +1 -1
  222. package/dist/providers/pubmed/client.d.ts +2 -0
  223. package/dist/providers/pubmed/client.d.ts.map +1 -1
  224. package/dist/providers/pubmed/client.js +10 -3
  225. package/dist/providers/pubmed/client.js.map +1 -1
  226. package/dist/providers/registry.d.ts.map +1 -1
  227. package/dist/providers/registry.js +6 -0
  228. package/dist/providers/registry.js.map +1 -1
  229. package/dist/providers/searchapi/adapter.d.ts +54 -0
  230. package/dist/providers/searchapi/adapter.d.ts.map +1 -0
  231. package/dist/providers/searchapi/adapter.js +310 -0
  232. package/dist/providers/searchapi/adapter.js.map +1 -0
  233. package/dist/providers/searchapi/client.d.ts +73 -0
  234. package/dist/providers/searchapi/client.d.ts.map +1 -0
  235. package/dist/providers/searchapi/client.js +196 -0
  236. package/dist/providers/searchapi/client.js.map +1 -0
  237. package/dist/providers/searchapi/credentials.d.ts +46 -0
  238. package/dist/providers/searchapi/credentials.d.ts.map +1 -0
  239. package/dist/providers/searchapi/credentials.js +71 -0
  240. package/dist/providers/searchapi/credentials.js.map +1 -0
  241. package/dist/providers/searchapi/diagnostics.d.ts +48 -0
  242. package/dist/providers/searchapi/diagnostics.d.ts.map +1 -0
  243. package/dist/providers/searchapi/diagnostics.js +70 -0
  244. package/dist/providers/searchapi/diagnostics.js.map +1 -0
  245. package/dist/providers/searchapi/quota.d.ts +60 -0
  246. package/dist/providers/searchapi/quota.d.ts.map +1 -0
  247. package/dist/providers/searchapi/quota.js +125 -0
  248. package/dist/providers/searchapi/quota.js.map +1 -0
  249. package/dist/providers/spider/client.d.ts +2 -0
  250. package/dist/providers/spider/client.d.ts.map +1 -1
  251. package/dist/providers/spider/client.js +16 -6
  252. package/dist/providers/spider/client.js.map +1 -1
  253. package/dist/providers/spider/credentials.d.ts +2 -0
  254. package/dist/providers/spider/credentials.d.ts.map +1 -1
  255. package/dist/providers/spider/credentials.js +2 -0
  256. package/dist/providers/spider/credentials.js.map +1 -1
  257. package/dist/providers/tavily/client.d.ts +1 -0
  258. package/dist/providers/tavily/client.d.ts.map +1 -1
  259. package/dist/providers/tavily/client.js +3 -2
  260. package/dist/providers/tavily/client.js.map +1 -1
  261. package/dist/providers/tavily/credentials.d.ts +2 -0
  262. package/dist/providers/tavily/credentials.d.ts.map +1 -1
  263. package/dist/providers/tavily/credentials.js +2 -0
  264. package/dist/providers/tavily/credentials.js.map +1 -1
  265. package/dist/providers/types.d.ts +1 -1
  266. package/dist/providers/types.d.ts.map +1 -1
  267. package/dist/providers/types.js +3 -0
  268. package/dist/providers/types.js.map +1 -1
  269. package/dist/providers/you/client.d.ts +4 -0
  270. package/dist/providers/you/client.d.ts.map +1 -1
  271. package/dist/providers/you/client.js +4 -5
  272. package/dist/providers/you/client.js.map +1 -1
  273. package/dist/providers/you/credentials.d.ts +2 -0
  274. package/dist/providers/you/credentials.d.ts.map +1 -1
  275. package/dist/providers/you/credentials.js +3 -3
  276. package/dist/providers/you/credentials.js.map +1 -1
  277. package/dist/providers/zai/adapter.d.ts.map +1 -1
  278. package/dist/providers/zai/adapter.js +2 -1
  279. package/dist/providers/zai/adapter.js.map +1 -1
  280. package/dist/providers/zai/credentials.d.ts +2 -0
  281. package/dist/providers/zai/credentials.d.ts.map +1 -1
  282. package/dist/providers/zai/credentials.js +2 -0
  283. package/dist/providers/zai/credentials.js.map +1 -1
  284. package/dist/providers/zai/monitor-client.d.ts +1 -0
  285. package/dist/providers/zai/monitor-client.d.ts.map +1 -1
  286. package/dist/providers/zai/monitor-client.js +3 -2
  287. package/dist/providers/zai/monitor-client.js.map +1 -1
  288. package/dist/providers/zai/quota.d.ts +4 -0
  289. package/dist/providers/zai/quota.d.ts.map +1 -1
  290. package/dist/providers/zai/quota.js +16 -1
  291. package/dist/providers/zai/quota.js.map +1 -1
  292. package/package.json +1 -1
  293. package/skills/scoutline/SKILL.md +93 -45
  294. package/skills/scoutline/references/advanced.md +12 -10
package/dist/index.d.ts CHANGED
@@ -7,13 +7,68 @@ import { readLog } from "./lib/artifacts.js";
7
7
  import { type JournalableCapability } from "./lib/journal.js";
8
8
  import { type CommandInvocationAdapter } from "./command-invocation.js";
9
9
  import { type ResponseCache } from "./lib/cache.js";
10
- import { type ScoutlineConfig } from "./lib/config-store.js";
10
+ import { type FusionMode, type ScoutlineConfig } from "./lib/config-store.js";
11
11
  import { type VerificationPromotionStore, type HintShownStore } from "./lib/config-store.js";
12
12
  import { type QuotaStore, type QuotaState } from "./lib/quota-store.js";
13
13
  import type { ProviderVerificationSummary } from "./capabilities/diagnostics.js";
14
14
  import { type ConsumptionSink } from "./lib/consumption.js";
15
15
  import type { ProviderDescriptor, ProviderId } from "./providers/types.js";
16
16
  import { type InitDependencies, type InitPrompts } from "./commands/init.js";
17
+ /**
18
+ * Guard for flag-forbidden features (#242): parseArgs maps `--no-X` to
19
+ * BOTH `flags.X = false` AND `flags["no-X"] = true`, so a feature that
20
+ * must reject a flag has to reject both spellings — checking one
21
+ * silently accepts the other (the footgun the fusion lane hit when its
22
+ * `--fusion` rejection had to know to test both). Throws the CALLER's
23
+ * error (built lazily, so the no-reject path allocates nothing) when
24
+ * either spelling of `--<name>` / `--no-<name>` is present.
25
+ */
26
+ export declare function rejectFlagPair(flags: Record<string, string | boolean>, name: string, makeError: () => Error): void;
27
+ /**
28
+ * Per-command accepted flag spellings for SCOUTLINE_STRICT_FLAGS mode
29
+ * (#241). Keys are post-dash spellings (`no-journal`, not
30
+ * `--no-journal`); sets are the UNION across a command's subcommands.
31
+ * Exported for the strict-mode tests and the DISPATCHED_COMMANDS
32
+ * coverage pin.
33
+ */
34
+ export declare const STRICT_FLAG_ALLOWLIST: Readonly<Record<string, ReadonlySet<string>>>;
35
+ /**
36
+ * The strict-flag gate (#241): scan a command's argv (the tokens AFTER
37
+ * the command name — global options were already extracted) and return
38
+ * the first flag token the command's allowlist does not name, or
39
+ * `undefined` when every token is accepted. Pure; throws never; the
40
+ * caller owns the error envelope. Commands without an allowlist row
41
+ * (unknown commands — the dispatcher's own `Unknown command` path) scan
42
+ * nothing.
43
+ */
44
+ export declare function findUnknownStrictFlag(command: string, args: readonly string[]): string | undefined;
45
+ /**
46
+ * One early resolution pass over the known env doors (#244), so a bad
47
+ * value fails identically on EVERY command — previously
48
+ * SCOUTLINE_FUSION=bogus failed `quota` (the credentialed path
49
+ * resolves the door unconditionally) but silently succeeded on
50
+ * early-return commands (`config get` never read it).
51
+ *
52
+ * - SCOUTLINE_FUSION — strict enum via {@link resolveFusionMode}
53
+ * (config passed as undefined: this pass validates the ENV door
54
+ * only; the file value arrives at the later resolution already
55
+ * leniently parsed). Empty string is unset.
56
+ * - SCOUTLINE_PROVIDER — a single shared Provider id via
57
+ * {@link parseProviderId}, the exact validation the shared-capability
58
+ * paths already run — except on `science`, whose env-door grammar
59
+ * is the science supplier ids + "all" and is validated inside
60
+ * handleScience against the D5 arm order. The `--provider` FLAG is
61
+ * out of scope: it is extracted globally and still surfaces its
62
+ * per-command errors where it is consumed.
63
+ * - SCOUTLINE_NO_FALLBACK — boolean kill-switch: any non-empty value
64
+ * disables fallback, so there is nothing to validate (listed here
65
+ * because the door set is the contract, not just the checks).
66
+ *
67
+ * Pure; throws ValidationError on a bad door. `main` runs this
68
+ * pre-dispatch for every command (help/version bare short-circuits have
69
+ * already returned) and owns the error envelope.
70
+ */
71
+ export declare function validateEnvDoors(env: NodeJS.ProcessEnv, command: string, explicitProvider?: string): void;
17
72
  /** Artifact serialization formats (spec ruling: json | markdown, default json). */
18
73
  declare const SAVE_FORMATS: readonly ["json", "markdown"];
19
74
  type SaveFormat = (typeof SAVE_FORMATS)[number];
@@ -134,6 +189,15 @@ export interface HandlerDependencies {
134
189
  * pre-fan-out behavior).
135
190
  */
136
191
  readonly configFanout?: boolean;
192
+ /**
193
+ * Effective merged-search ranking algorithm (fusion seed-24).
194
+ * Production derives this once per invocation via `resolveFusionMode`
195
+ * (SCOUTLINE_FUSION env > config `fusion` > default "rrf"); tests
196
+ * inject it directly so precedence/consumption assertions stay
197
+ * hermetic. Absent → the "rrf" default applies (byte-identical
198
+ * pre-fusion ranking).
199
+ */
200
+ readonly fusionMode?: FusionMode;
137
201
  /**
138
202
  * save-artifacts T4: present only when this run will actually save
139
203
  * (save-capable command + --save + not a help invocation). Handlers
@@ -477,6 +541,13 @@ export interface MainDependencies {
477
541
  * the switch from the loaded config.
478
542
  */
479
543
  readonly configFanout?: boolean;
544
+ /**
545
+ * Injectable fusion-mode override (fusion seed-24). When provided,
546
+ * this wins over the resolveFusionMode derivation (SCOUTLINE_FUSION
547
+ * env > config `fusion` > default "rrf") so precedence/consumption
548
+ * tests stay hermetic. Production leaves it undefined.
549
+ */
550
+ readonly fusionMode?: FusionMode;
480
551
  /**
481
552
  * Injectable routing preference override (#72). When provided, this
482
553
  * wins over the config file's routing table — the injectable-wins
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -42,15 +42,16 @@ import { invokeCommand, } from "./command-invocation.js";
42
42
  import { createFileResponseCache, defaultResponseCache, isIsolatedEnv, responseCacheDir, } from "./lib/cache.js";
43
43
  import { MAX_SUBQUERIES, parseContextText, readContextSource } from "./lib/context-file.js";
44
44
  import { configuredSecrets, redactSecrets } from "./lib/redact.js";
45
- import { configFilePath, readConfig, resolveConfigRoot, resolveConfigRootPure, resolveEnvFromConfig, setConfigValue, unsetConfigValue, } from "./lib/config-store.js";
45
+ import { configFilePath, readConfig, resolveConfigRoot, resolveConfigRootPure, resolveEnvFromConfig, setConfigValue, unsetConfigValue, resolveFusionMode, } from "./lib/config-store.js";
46
46
  import { inspectConfig, createDefaultVerificationPromoter, createDefaultHintShownStore, } from "./lib/config-store.js";
47
47
  import { createDefaultQuotaStore, refreshQuotaSnapshots, } from "./lib/quota-store.js";
48
48
  import { createCompositeConsumptionSink, createQuotaStoreConsumptionSink, } from "./lib/consumption.js";
49
49
  import { createUsageLedgerSink, readUsageLedger, resolveUsageLedgerPath, } from "./lib/usage-ledger.js";
50
50
  import { classifyCredentialState, formatEnvOnlyHint, isCommandHelpInvocation, isDryRunBatchInvocation, OBSERVATIONAL_COMMANDS, } from "./lib/trigger-detection.js";
51
- import { resolveProviderId, resolveEffectiveProvider } from "./providers/selection.js";
51
+ import { resolveProviderId, resolveEffectiveProvider, parseProviderId, } from "./providers/selection.js";
52
52
  import { BUILT_IN_PROVIDER_DESCRIPTORS } from "./providers/registry.js";
53
53
  import { PROVIDER_IDS } from "./providers/types.js";
54
+ import { SHARED_PROVIDER_FLAG_IDS, SHARED_PROVIDER_IDS } from "./providers/catalog.js";
54
55
  import { executeWithFallback } from "./lib/provider-fallback.js";
55
56
  import { visionOperationToCapability } from "./capabilities/vision.js";
56
57
  import { handleInitWithHelp, createInquirerPrompts, createDefaultConfigStore, } from "./commands/init.js";
@@ -64,7 +65,7 @@ Usage: scoutline <command> [args] [options]
64
65
 
65
66
  Commands:
66
67
  vision Image and video analysis (Z.AI; MiniMax for interpret-image)
67
- search Real-time web search (shared: all 12 Providers; --topic
68
+ search Real-time web search (shared: all ${SHARED_PROVIDER_IDS.length} Providers; --topic
68
69
  honored by every Provider)
69
70
  read Fetch and parse web pages (Provider Capability; Z.AI, Tavily,
70
71
  Exa, Firecrawl, Parallel, Jina, You.com, Linkup, and Spider.cloud supply it) crawl Crawl a website from a starting URL (Provider Capability;
@@ -105,7 +106,7 @@ Commands:
105
106
  credential-free)
106
107
 
107
108
  Provider selection (precedence: --provider, then SCOUTLINE_PROVIDER, then zai):
108
- --provider <zai|minimax|tavily|exa|brave|firecrawl|parallel|perplexity|jina|you|linkup|spider> Select the active Provider for shared capabilities (science suppliers pin only within "scoutline science ...") SCOUTLINE_PROVIDER=<id> Fallback when --provider is not passed
109
+ --provider <${SHARED_PROVIDER_FLAG_IDS}> Select the active Provider for shared capabilities (science suppliers pin only within "scoutline science ...") SCOUTLINE_PROVIDER=<id> Fallback when --provider is not passed
109
110
 
110
111
  Shared capabilities accept --provider. The 'repo', 'read', 'crawl', 'map',
111
112
  and 'research' commands participate in Provider selection: Z.AI
@@ -115,8 +116,10 @@ advertises and supplies search, reader, and research; Parallel AI
115
116
  advertises search, research, and reader; Perplexity advertises search
116
117
  and research; Jina AI advertises search, reader, and research (keyless
117
118
  supported); You.com advertises search, reader, and research; Linkup advertises search, reader, and research; Spider.cloud
118
- advertises search, reader, crawl, and map; MiniMax advertises and supplies none of those
119
- Provider-only Capabilities.
119
+ advertises search, reader, crawl, and map; Bocha AI advertises and
120
+ supplies search; SearchApi advertises and supplies search; Kagi
121
+ advertises and supplies search; MiniMax advertises and supplies none of
122
+ those Provider-only Capabilities.
120
123
  Provider fallback is always-on by default (0.11.0+): selecting a
121
124
  non-supplier emits a stderr notice and silently reroutes to the next
122
125
  eligible configured Provider in registry order. Use --no-fallback (or
@@ -125,6 +128,16 @@ UNSUPPORTED_CAPABILITY behavior. Z.AI-only commands (tools, tool,
125
128
  call, code) carry the flag but ignore it. Quota and doctor report
126
129
  per-Provider; --provider picks the effective Provider for metadata.
127
130
 
131
+ Merged-search ranking: fan-out and --merge results rank by reciprocal
132
+ rank fusion (SCOUTLINE_FUSION=<rrf|occurrence>; default rrf; also the
133
+ config \`fusion\` key, env wins). \`occurrence\` restores the legacy
134
+ ordering byte-for-byte. See \`scoutline search --help\`.
135
+
136
+ Flag strictness: unknown command flags are silently ignored by default
137
+ (a typo like --fusio runs as if the flag were absent). Set
138
+ SCOUTLINE_STRICT_FLAGS=1 to reject unknown flags on every command with
139
+ a VALIDATION_ERROR naming the offender.
140
+
128
141
  Global Options:
129
142
  --output-format <data|json|pretty|compact|markdown|refs|tty> Output mode (default: data)
130
143
  -O <mode> Alias for --output-format
@@ -165,6 +178,16 @@ function parseArgs(args) {
165
178
  break;
166
179
  if (arg.startsWith("--")) {
167
180
  const key = arg.slice(2);
181
+ // TWO-SPELLING CONTRACT (#242): this branch maps `--no-X` to BOTH
182
+ // `flags.X = false` AND `flags["no-X"] = true`. A feature that
183
+ // must reject a flag therefore has to reject BOTH spellings — a
184
+ // handler checking only `flags.X` silently accepts `--no-X`, and
185
+ // one checking only `flags["no-X"]` misses the plain form. Use
186
+ // `rejectFlagPair(flags, name, makeError)` (below) for every
187
+ // flag-forbidden surface; the fusion rejection is the reference
188
+ // retrofit. (A structural fix — making `--no-X` set a single
189
+ // `flags.noX` key — would break every existing `--no-*`
190
+ // consumer.)
168
191
  if (key.startsWith("no-")) {
169
192
  flags[key.slice(3)] = false;
170
193
  flags[key] = true;
@@ -200,6 +223,20 @@ function parseArgs(args) {
200
223
  }
201
224
  return { flags, positional };
202
225
  }
226
+ /**
227
+ * Guard for flag-forbidden features (#242): parseArgs maps `--no-X` to
228
+ * BOTH `flags.X = false` AND `flags["no-X"] = true`, so a feature that
229
+ * must reject a flag has to reject both spellings — checking one
230
+ * silently accepts the other (the footgun the fusion lane hit when its
231
+ * `--fusion` rejection had to know to test both). Throws the CALLER's
232
+ * error (built lazily, so the no-reject path allocates nothing) when
233
+ * either spelling of `--<name>` / `--no-<name>` is present.
234
+ */
235
+ export function rejectFlagPair(flags, name, makeError) {
236
+ if (flags[name] !== undefined || flags[`no-${name}`] !== undefined) {
237
+ throw makeError();
238
+ }
239
+ }
203
240
  /**
204
241
  * Collect every occurrence of a long `--<name>` flag in argv order,
205
242
  * mirroring parseArgs' value-consumption rule (the next argument is the
@@ -226,6 +263,271 @@ function collectLongFlagValues(args, name) {
226
263
  return values;
227
264
  }
228
265
  // ---------------------------------------------------------------------------
266
+ // Strict flag mode (#241). Outside `batch` (and `vision batch` /
267
+ // `history clear`, which carry their own gates) unknown CLI flags are
268
+ // silently ignored — `search "q" --fusio rrf` runs as if the flag were
269
+ // absent and parseArgs swallows the value into flag state. Global
270
+ // strictness would break users passing redundant flags, so rejection is
271
+ // OPT-IN: SCOUTLINE_STRICT_FLAGS set to any non-empty value (the
272
+ // SCOUTLINE_NO_FALLBACK idiom) makes the dispatcher reject every flag
273
+ // token the command's allowlist does not name, with the batch-style
274
+ // error naming the offender.
275
+ //
276
+ // Semantics of the scan (deliberate rulings):
277
+ // - Exact spellings: `--no-journal` is accepted only as the literal
278
+ // `no-journal` row; it does NOT license a bare `--journal`. The
279
+ // parseArgs `--no-X` double-map never participates — the scan reads
280
+ // raw argv tokens, not parsed flag state.
281
+ // - Short flags are checked too (`-h` everywhere; fetch's `-A/-X/-H`).
282
+ // A multi-dash-letter token like `-ab` (which parseArgs would treat
283
+ // as positional) rejects under strict mode — strict means strict.
284
+ // - Global flags (`--provider`, `--output-format`, `--save*`, ...) are
285
+ // stripped by extractGlobalOptions BEFORE this gate, so they are not
286
+ // listed; a few commands (cache/usage) keep `provider` rows anyway
287
+ // for direct in-process callers whose argv was never extracted.
288
+ // - Flags a command's handler REJECTS with a specific error (e.g.
289
+ // search's `--fusion`, map's `--max-chars`) are absent from the set
290
+ // on purpose: under strict mode the generic rejection fires first;
291
+ // under the lenient default the handler's specific error still does.
292
+ // - When you add a flag to a command, add its spelling here — a miss
293
+ // only bites strict-mode users, but it bites them loudly.
294
+ // ---------------------------------------------------------------------------
295
+ /**
296
+ * Per-command accepted flag spellings for SCOUTLINE_STRICT_FLAGS mode
297
+ * (#241). Keys are post-dash spellings (`no-journal`, not
298
+ * `--no-journal`); sets are the UNION across a command's subcommands.
299
+ * Exported for the strict-mode tests and the DISPATCHED_COMMANDS
300
+ * coverage pin.
301
+ */
302
+ export const STRICT_FLAG_ALLOWLIST = {
303
+ vision: new Set([
304
+ "help",
305
+ "h",
306
+ "context",
307
+ "focus",
308
+ "language",
309
+ "output",
310
+ "type",
311
+ // `vision batch` wrapper (the VISION_BATCH_FLAGS surface)
312
+ "out",
313
+ "prompt",
314
+ "concurrency",
315
+ "dry-run",
316
+ ]),
317
+ search: new Set([
318
+ "help",
319
+ "h",
320
+ "count",
321
+ "domain",
322
+ "fields",
323
+ "recency",
324
+ "topic",
325
+ "type",
326
+ "location",
327
+ "content-size",
328
+ "merge",
329
+ "max-summary",
330
+ "no-cache",
331
+ "max-chars",
332
+ "context",
333
+ "context-stdin",
334
+ "no-journal",
335
+ ]),
336
+ read: new Set([
337
+ "help",
338
+ "h",
339
+ "extract",
340
+ "format",
341
+ "full-envelope",
342
+ "keep-img-data-url",
343
+ "no-cache",
344
+ "no-gfm",
345
+ "no-images",
346
+ "timeout",
347
+ "with-images-summary",
348
+ "with-links",
349
+ "max-chars",
350
+ "no-journal",
351
+ ]),
352
+ crawl: new Set([
353
+ "help",
354
+ "h",
355
+ "breadth",
356
+ "content-size",
357
+ "depth",
358
+ "exclude-paths",
359
+ "format",
360
+ "instructions",
361
+ "limit",
362
+ "no-cache",
363
+ "select-paths",
364
+ "timeout",
365
+ "max-chars",
366
+ ]),
367
+ map: new Set([
368
+ "help",
369
+ "h",
370
+ "breadth",
371
+ "depth",
372
+ "exclude-paths",
373
+ "instructions",
374
+ "limit",
375
+ "no-cache",
376
+ "select-paths",
377
+ ]),
378
+ research: new Set([
379
+ "help",
380
+ "h",
381
+ "citation-format",
382
+ "context",
383
+ "context-mode",
384
+ "context-stdin",
385
+ "domain",
386
+ "model",
387
+ "no-cache",
388
+ "output-length",
389
+ "timeout",
390
+ "max-chars",
391
+ "no-journal",
392
+ ]),
393
+ repo: new Set([
394
+ "help",
395
+ "h",
396
+ "depth",
397
+ "focus",
398
+ "lang",
399
+ "language",
400
+ "max-chars",
401
+ "no-cache",
402
+ "no-focus",
403
+ "path",
404
+ ]),
405
+ batch: new Set(["help", "h", "concurrency", "fail-fast", "dry-run"]),
406
+ tools: new Set(["help", "h", "filter", "full", "ts", "typescript", "vision", "no-vision"]),
407
+ tool: new Set(["help", "h", "vision", "no-vision"]),
408
+ call: new Set(["help", "h", "dry-run", "file", "json", "stdin", "vision", "no-vision"]),
409
+ doctor: new Set(["help", "h", "available", "health", "no-tools"]),
410
+ quota: new Set(["help", "h", "all-providers"]),
411
+ code: new Set(["help", "h", "logs", "timeout"]),
412
+ cache: new Set(["help", "h", "capability", "older-than", "provider"]),
413
+ usage: new Set(["help", "h", "days", "provider"]),
414
+ history: new Set([
415
+ "help",
416
+ "h",
417
+ "all",
418
+ "as-of",
419
+ "capability",
420
+ "command",
421
+ "kind",
422
+ "limit",
423
+ "repeats",
424
+ "since",
425
+ "tags",
426
+ // `history note` consumes --url/--title pairs through its own
427
+ // raw-argv scan (repeatable rows, not parseArgs flag state) — the
428
+ // final-review false-reject probe.
429
+ "url",
430
+ "title",
431
+ ]),
432
+ init: new Set(["help", "h", "unregister"]),
433
+ config: new Set(["help", "h"]),
434
+ fetch: new Set([
435
+ "help",
436
+ "h",
437
+ "md5",
438
+ "sha256",
439
+ "raw",
440
+ "out",
441
+ "ua",
442
+ "user-agent",
443
+ "A",
444
+ "method",
445
+ "X",
446
+ "data",
447
+ "header",
448
+ "H",
449
+ "pdf",
450
+ "pdf-repair",
451
+ "timeout",
452
+ ]),
453
+ archive: new Set(["help", "h", "at", "from", "limit", "raw", "since", "status", "timeout", "to"]),
454
+ watch: new Set(["help", "h", "all", "format", "keep", "name", "purge", "timeout"]),
455
+ science: new Set([
456
+ "help",
457
+ "h",
458
+ "author",
459
+ "year",
460
+ "venue",
461
+ "type",
462
+ "provider",
463
+ "no-cache",
464
+ "max-chars",
465
+ "no-journal",
466
+ ]),
467
+ };
468
+ /**
469
+ * The strict-flag gate (#241): scan a command's argv (the tokens AFTER
470
+ * the command name — global options were already extracted) and return
471
+ * the first flag token the command's allowlist does not name, or
472
+ * `undefined` when every token is accepted. Pure; throws never; the
473
+ * caller owns the error envelope. Commands without an allowlist row
474
+ * (unknown commands — the dispatcher's own `Unknown command` path) scan
475
+ * nothing.
476
+ */
477
+ export function findUnknownStrictFlag(command, args) {
478
+ const allowed = STRICT_FLAG_ALLOWLIST[command];
479
+ if (allowed === undefined)
480
+ return undefined;
481
+ for (const arg of args) {
482
+ if (typeof arg !== "string" || !arg.startsWith("-") || arg.length < 2)
483
+ continue;
484
+ const key = arg.startsWith("--") ? arg.slice(2) : arg.slice(1);
485
+ if (key.length === 0)
486
+ continue; // a bare `--` token: never a flag name
487
+ if (!allowed.has(key))
488
+ return arg;
489
+ }
490
+ return undefined;
491
+ }
492
+ /**
493
+ * One early resolution pass over the known env doors (#244), so a bad
494
+ * value fails identically on EVERY command — previously
495
+ * SCOUTLINE_FUSION=bogus failed `quota` (the credentialed path
496
+ * resolves the door unconditionally) but silently succeeded on
497
+ * early-return commands (`config get` never read it).
498
+ *
499
+ * - SCOUTLINE_FUSION — strict enum via {@link resolveFusionMode}
500
+ * (config passed as undefined: this pass validates the ENV door
501
+ * only; the file value arrives at the later resolution already
502
+ * leniently parsed). Empty string is unset.
503
+ * - SCOUTLINE_PROVIDER — a single shared Provider id via
504
+ * {@link parseProviderId}, the exact validation the shared-capability
505
+ * paths already run — except on `science`, whose env-door grammar
506
+ * is the science supplier ids + "all" and is validated inside
507
+ * handleScience against the D5 arm order. The `--provider` FLAG is
508
+ * out of scope: it is extracted globally and still surfaces its
509
+ * per-command errors where it is consumed.
510
+ * - SCOUTLINE_NO_FALLBACK — boolean kill-switch: any non-empty value
511
+ * disables fallback, so there is nothing to validate (listed here
512
+ * because the door set is the contract, not just the checks).
513
+ *
514
+ * Pure; throws ValidationError on a bad door. `main` runs this
515
+ * pre-dispatch for every command (help/version bare short-circuits have
516
+ * already returned) and owns the error envelope.
517
+ */
518
+ export function validateEnvDoors(env, command, explicitProvider) {
519
+ resolveFusionMode(env, undefined);
520
+ // PR #253 round 1: a present --provider flag (any value — id, comma
521
+ // list, or "all") wins the precedence chain, so SCOUTLINE_PROVIDER is
522
+ // a dead value on a pinned run and must not fail it. The flag's own
523
+ // value is validated downstream, where the consuming command reads it.
524
+ if (command !== "science" &&
525
+ explicitProvider === undefined &&
526
+ env.SCOUTLINE_PROVIDER !== undefined) {
527
+ parseProviderId(env.SCOUTLINE_PROVIDER);
528
+ }
529
+ }
530
+ // ---------------------------------------------------------------------------
229
531
  // Save-artifacts flag surface (batch ticket T3). `--save [<path>]`,
230
532
  // `--save-format <json|markdown>`, and `--save-force` are global options:
231
533
  // extracted for every command, removed from the rest stream, and consumed
@@ -871,6 +1173,14 @@ async function handleSearch(args, outputMode, deps) {
871
1173
  if (typeof flags["context-stdin"] === "string") {
872
1174
  throw new ValidationError("--context-stdin does not take a value.", 'Pipe the context on standard input: cat notes.md | scoutline search "<query>" --context-stdin.');
873
1175
  }
1176
+ // Fusion seed-24 AC-1 pin: search takes NO --fusion flag — the
1177
+ // algorithm is a standing setting, not a per-query option — so a
1178
+ // query flag could never exist. rejectFlagPair (#242) guards BOTH
1179
+ // spellings (parseArgs maps `--no-fusion` to flags.fusion=false AND
1180
+ // flags["no-fusion"]=true); rejection runs BEFORE the help-gate for
1181
+ // the same reason as `--context` above (parseArgs swallows the value
1182
+ // into flag state, and help would exit 0).
1183
+ rejectFlagPair(flags, "fusion", () => new ValidationError("search has no --fusion flag; the ranking algorithm is a standing setting, not a per-query option.", "Use `scoutline config set fusion <rrf|occurrence>` or the SCOUTLINE_FUSION environment variable."));
874
1184
  if (flags.help || flags.h || positional.length === 0) {
875
1185
  deps.invocation.writeStdout(SEARCH_HELP);
876
1186
  return 0;
@@ -1227,6 +1537,9 @@ async function handleSearch(args, outputMode, deps) {
1227
1537
  env: deps.env,
1228
1538
  query: dispatchQuery,
1229
1539
  searchOptions,
1540
+ // Seed-24 T3: the resolved ranking mode (env > config >
1541
+ // "rrf") — the executor's merge names it explicitly.
1542
+ fusionMode: deps.fusionMode ?? "rrf",
1230
1543
  dependencies: {
1231
1544
  cache: deps.searchCache,
1232
1545
  sleep: deps.searchSleep,
@@ -1268,6 +1581,10 @@ async function handleSearch(args, outputMode, deps) {
1268
1581
  cache: deps.searchCache,
1269
1582
  sleep: deps.searchSleep,
1270
1583
  random: deps.searchRandom,
1584
+ // Seed-24 T3: the resolved ranking mode (env > config >
1585
+ // "rrf") reaches the single-provider --merge seam too, so
1586
+ // one merge implementation serves both paths.
1587
+ fusionMode: deps.fusionMode ?? "rrf",
1271
1588
  // PB-T2 parity with the fan-out path above (usage-ledger
1272
1589
  // DESIGN D7): thread the configured consumption sink +
1273
1590
  // clock so every billable sub-query on the single-pin path
@@ -3891,6 +4208,39 @@ export async function main(args, dependencies) {
3891
4208
  }
3892
4209
  const command = rest[0] ?? "";
3893
4210
  const commandArgs = rest.slice(1);
4211
+ // #244: validate the env doors ONCE, pre-dispatch, for ALL command
4212
+ // RUNS — a typo'd env value used to fail only on the paths that
4213
+ // happened to resolve it first (quota yes, config get no). Help
4214
+ // invocations stay exempt (documentation, not a run — the same
4215
+ // doctrine as the --max-chars/--no-journal gates and the existing
4216
+ // "<cmd> --help succeeds with an invalid SCOUTLINE_PROVIDER" pins:
4217
+ // rendering help must never require a valid environment). Runs before
4218
+ // the strict-flags gate and every command-specific gate, and before
4219
+ // any disk or network work (the agent-registration check below), so a
4220
+ // doomed run costs nothing. Bare `--help`/`--version` already
4221
+ // returned above.
4222
+ if (!isCommandHelpInvocation(commandArgs)) {
4223
+ try {
4224
+ validateEnvDoors(env, command, provider);
4225
+ }
4226
+ catch (error) {
4227
+ invocation.writeStderr(formatErrorOutput(error, outputMode, envSecrets));
4228
+ return getErrorExitCode(error);
4229
+ }
4230
+ }
4231
+ // #241: opt-in strict flag mode. Fires before every other pre-dispatch
4232
+ // gate (and before the agent-registration disk check) so a doomed run
4233
+ // costs nothing: with SCOUTLINE_STRICT_FLAGS set to any non-empty
4234
+ // value, a flag token the command's allowlist does not name rejects
4235
+ // with the batch-style error. The lenient default (unset/empty env)
4236
+ // stays byte-identical — unknown flags are accepted and dropped.
4237
+ if (typeof env.SCOUTLINE_STRICT_FLAGS === "string" && env.SCOUTLINE_STRICT_FLAGS.length > 0) {
4238
+ const unknownFlag = findUnknownStrictFlag(command, commandArgs);
4239
+ if (unknownFlag !== undefined) {
4240
+ invocation.writeStderr(formatErrorOutput(new ValidationError(`unknown flag "${unknownFlag}" for command "${command}" (SCOUTLINE_STRICT_FLAGS is enabled)`, `Run "scoutline ${command} --help" for the accepted flags, or unset SCOUTLINE_STRICT_FLAGS to restore lenient flag handling.`), outputMode, envSecrets));
4241
+ return 1;
4242
+ }
4243
+ }
3894
4244
  // Lazy agent-registration stamp check (agent registration D5/D6):
3895
4245
  // fires exactly once per CLI run, before command dispatch. Stamp-absent
3896
4246
  // runs are zero-cost no-ops; drift refreshes the registered tools. A
@@ -4010,7 +4360,7 @@ export async function main(args, dependencies) {
4010
4360
  // Build HandlerDependencies for a given credential view. The
4011
4361
  // cache/sleep/random fields are always available (resolved above); only
4012
4362
  // env/secrets/fallbackEnabled depend on whether config has been loaded.
4013
- const buildHandlerDeps = (credEnv, credSecrets, credFallback, credRouting = undefined, credFanout = undefined) => ({
4363
+ const buildHandlerDeps = (credEnv, credSecrets, credFallback, credRouting = undefined, credFanout = undefined, credFusion = undefined) => ({
4014
4364
  invocation,
4015
4365
  env: credEnv,
4016
4366
  secrets: credSecrets,
@@ -4020,6 +4370,7 @@ export async function main(args, dependencies) {
4020
4370
  fallbackEnabled: credFallback,
4021
4371
  routing: credRouting,
4022
4372
  configFanout: credFanout,
4373
+ fusionMode: credFusion,
4023
4374
  searchCache,
4024
4375
  searchSleep,
4025
4376
  searchRandom,
@@ -4541,9 +4892,14 @@ export async function main(args, dependencies) {
4541
4892
  // Ticket 4. Read leniently: an absent or non-boolean field simply means
4542
4893
  // fan-out stays off.
4543
4894
  const configFanout = dependencies.configFanout ?? config.fanout === true;
4895
+ // Fusion seed-24: resolve the effective ranking mode ONCE per
4896
+ // invocation, injectable-wins exactly like configFanout above.
4897
+ // Strict: a non-enum SCOUTLINE_FUSION throws here (exit 1) — typos
4898
+ // never silently fall back to rrf.
4899
+ const fusionMode = dependencies.fusionMode ?? resolveFusionMode(env, config);
4544
4900
  const handlerDeps = buildHandlerDeps(resolvedEnv, secrets, fallbackEnabled,
4545
4901
  // #72: injectable-wins, mirroring configFanout above.
4546
- dependencies.routing ?? config.routing, configFanout);
4902
+ dependencies.routing ?? config.routing, configFanout, fusionMode);
4547
4903
  // PB-T5 — derive Plan A verification records from the loaded config
4548
4904
  // AFTER `config` is in scope. `buildHandlerDeps` runs once BEFORE
4549
4905
  // config load (the cache short-circuit), so this derivation cannot