scoutline 0.22.0 → 0.24.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.
- package/README.md +108 -26
- package/dist/capabilities/investigation.d.ts +134 -0
- package/dist/capabilities/investigation.d.ts.map +1 -0
- package/dist/capabilities/investigation.js +278 -0
- package/dist/capabilities/investigation.js.map +1 -0
- package/dist/capabilities/search.d.ts +18 -4
- package/dist/capabilities/search.d.ts.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +14 -5
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/crawl.d.ts.map +1 -1
- package/dist/commands/crawl.js +2 -1
- package/dist/commands/crawl.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +2 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts +42 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +42 -5
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/investigate.d.ts +232 -0
- package/dist/commands/investigate.d.ts.map +1 -0
- package/dist/commands/investigate.js +838 -0
- package/dist/commands/investigate.js.map +1 -0
- package/dist/commands/map.d.ts.map +1 -1
- package/dist/commands/map.js +2 -1
- package/dist/commands/map.js.map +1 -1
- package/dist/commands/quota.d.ts.map +1 -1
- package/dist/commands/quota.js +2 -2
- package/dist/commands/quota.js.map +1 -1
- package/dist/commands/read.d.ts.map +1 -1
- package/dist/commands/read.js +2 -1
- package/dist/commands/read.js.map +1 -1
- package/dist/commands/repo.js +1 -1
- package/dist/commands/research.d.ts.map +1 -1
- package/dist/commands/research.js +2 -1
- package/dist/commands/research.js.map +1 -1
- package/dist/commands/search.d.ts +54 -6
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +273 -25
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/vision.d.ts.map +1 -1
- package/dist/commands/vision.js +15 -2
- package/dist/commands/vision.js.map +1 -1
- package/dist/index.d.ts +93 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +737 -14
- package/dist/index.js.map +1 -1
- package/dist/lib/code-mode.d.ts +12 -0
- package/dist/lib/code-mode.d.ts.map +1 -1
- package/dist/lib/code-mode.js +18 -10
- package/dist/lib/code-mode.js.map +1 -1
- package/dist/lib/config-store.d.ts +45 -1
- package/dist/lib/config-store.d.ts.map +1 -1
- package/dist/lib/config-store.js +70 -1
- package/dist/lib/config-store.js.map +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +5 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/errors.d.ts +7 -1
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +8 -2
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/execution.d.ts +14 -5
- package/dist/lib/execution.d.ts.map +1 -1
- package/dist/lib/execution.js +25 -6
- package/dist/lib/execution.js.map +1 -1
- package/dist/lib/investigate-claims.d.ts +90 -0
- package/dist/lib/investigate-claims.d.ts.map +1 -0
- package/dist/lib/investigate-claims.js +188 -0
- package/dist/lib/investigate-claims.js.map +1 -0
- package/dist/lib/investigate-extract.d.ts +35 -0
- package/dist/lib/investigate-extract.d.ts.map +1 -0
- package/dist/lib/investigate-extract.js +101 -0
- package/dist/lib/investigate-extract.js.map +1 -0
- package/dist/lib/investigate-planner.d.ts +58 -0
- package/dist/lib/investigate-planner.d.ts.map +1 -0
- package/dist/lib/investigate-planner.js +141 -0
- package/dist/lib/investigate-planner.js.map +1 -0
- package/dist/lib/mcp-client.d.ts +7 -0
- package/dist/lib/mcp-client.d.ts.map +1 -1
- package/dist/lib/mcp-client.js +11 -1
- package/dist/lib/mcp-client.js.map +1 -1
- package/dist/lib/parse-zoned-instant.d.ts +13 -0
- package/dist/lib/parse-zoned-instant.d.ts.map +1 -0
- package/dist/lib/parse-zoned-instant.js +17 -0
- package/dist/lib/parse-zoned-instant.js.map +1 -0
- package/dist/lib/quota-mapping.d.ts +4 -2
- package/dist/lib/quota-mapping.d.ts.map +1 -1
- package/dist/lib/quota-mapping.js +25 -2
- package/dist/lib/quota-mapping.js.map +1 -1
- package/dist/lib/redact.d.ts +3 -2
- package/dist/lib/redact.d.ts.map +1 -1
- package/dist/lib/redact.js +90 -24
- package/dist/lib/redact.js.map +1 -1
- package/dist/lib/timeout.d.ts +28 -0
- package/dist/lib/timeout.d.ts.map +1 -0
- package/dist/lib/timeout.js +30 -0
- package/dist/lib/timeout.js.map +1 -0
- package/dist/lib/url.d.ts +10 -4
- package/dist/lib/url.d.ts.map +1 -1
- package/dist/lib/url.js +21 -6
- package/dist/lib/url.js.map +1 -1
- package/dist/providers/arxiv/client.d.ts +4 -1
- package/dist/providers/arxiv/client.d.ts.map +1 -1
- package/dist/providers/arxiv/client.js +11 -3
- package/dist/providers/arxiv/client.js.map +1 -1
- package/dist/providers/bocha/adapter.d.ts +43 -0
- package/dist/providers/bocha/adapter.d.ts.map +1 -0
- package/dist/providers/bocha/adapter.js +197 -0
- package/dist/providers/bocha/adapter.js.map +1 -0
- package/dist/providers/bocha/client.d.ts +51 -0
- package/dist/providers/bocha/client.d.ts.map +1 -0
- package/dist/providers/bocha/client.js +104 -0
- package/dist/providers/bocha/client.js.map +1 -0
- package/dist/providers/bocha/credentials.d.ts +12 -0
- package/dist/providers/bocha/credentials.d.ts.map +1 -0
- package/dist/providers/bocha/credentials.js +29 -0
- package/dist/providers/bocha/credentials.js.map +1 -0
- package/dist/providers/bocha/diagnostics.d.ts +17 -0
- package/dist/providers/bocha/diagnostics.d.ts.map +1 -0
- package/dist/providers/bocha/diagnostics.js +33 -0
- package/dist/providers/bocha/diagnostics.js.map +1 -0
- package/dist/providers/brave/adapter.d.ts.map +1 -1
- package/dist/providers/brave/adapter.js +4 -3
- package/dist/providers/brave/adapter.js.map +1 -1
- package/dist/providers/brave/client.d.ts +1 -0
- package/dist/providers/brave/client.d.ts.map +1 -1
- package/dist/providers/brave/client.js +4 -6
- package/dist/providers/brave/client.js.map +1 -1
- package/dist/providers/brave/credentials.d.ts +2 -0
- package/dist/providers/brave/credentials.d.ts.map +1 -1
- package/dist/providers/brave/credentials.js +2 -0
- package/dist/providers/brave/credentials.js.map +1 -1
- package/dist/providers/catalog.d.ts +34 -0
- package/dist/providers/catalog.d.ts.map +1 -0
- package/dist/providers/catalog.js +57 -0
- package/dist/providers/catalog.js.map +1 -0
- package/dist/providers/crossref/adapter.js +2 -2
- package/dist/providers/crossref/adapter.js.map +1 -1
- package/dist/providers/crossref/client.d.ts +4 -1
- package/dist/providers/crossref/client.d.ts.map +1 -1
- package/dist/providers/crossref/client.js +11 -3
- package/dist/providers/crossref/client.js.map +1 -1
- package/dist/providers/crossref/diagnostics.d.ts +1 -1
- package/dist/providers/crossref/diagnostics.js +1 -1
- package/dist/providers/crossref/diagnostics.js.map +1 -1
- package/dist/providers/europepmc/adapter.js +2 -2
- package/dist/providers/europepmc/adapter.js.map +1 -1
- package/dist/providers/europepmc/client.d.ts +4 -1
- package/dist/providers/europepmc/client.d.ts.map +1 -1
- package/dist/providers/europepmc/client.js +11 -3
- package/dist/providers/europepmc/client.js.map +1 -1
- package/dist/providers/exa/client.d.ts +1 -0
- package/dist/providers/exa/client.d.ts.map +1 -1
- package/dist/providers/exa/client.js +3 -2
- package/dist/providers/exa/client.js.map +1 -1
- package/dist/providers/exa/credentials.d.ts +2 -0
- package/dist/providers/exa/credentials.d.ts.map +1 -1
- package/dist/providers/exa/credentials.js +2 -0
- package/dist/providers/exa/credentials.js.map +1 -1
- package/dist/providers/firecrawl/adapter.d.ts.map +1 -1
- package/dist/providers/firecrawl/adapter.js +2 -1
- package/dist/providers/firecrawl/adapter.js.map +1 -1
- package/dist/providers/firecrawl/client.d.ts +1 -0
- package/dist/providers/firecrawl/client.d.ts.map +1 -1
- package/dist/providers/firecrawl/client.js +3 -2
- package/dist/providers/firecrawl/client.js.map +1 -1
- package/dist/providers/firecrawl/credentials.d.ts +2 -0
- package/dist/providers/firecrawl/credentials.d.ts.map +1 -1
- package/dist/providers/firecrawl/credentials.js +2 -0
- package/dist/providers/firecrawl/credentials.js.map +1 -1
- package/dist/providers/firecrawl/quota.d.ts.map +1 -1
- package/dist/providers/firecrawl/quota.js +5 -2
- package/dist/providers/firecrawl/quota.js.map +1 -1
- package/dist/providers/jina/adapter.d.ts.map +1 -1
- package/dist/providers/jina/adapter.js +6 -4
- package/dist/providers/jina/adapter.js.map +1 -1
- package/dist/providers/jina/client.d.ts +2 -0
- package/dist/providers/jina/client.d.ts.map +1 -1
- package/dist/providers/jina/client.js +6 -5
- package/dist/providers/jina/client.js.map +1 -1
- package/dist/providers/jina/credentials.d.ts +2 -0
- package/dist/providers/jina/credentials.d.ts.map +1 -1
- package/dist/providers/jina/credentials.js +2 -0
- package/dist/providers/jina/credentials.js.map +1 -1
- package/dist/providers/kagi/adapter.d.ts +44 -0
- package/dist/providers/kagi/adapter.d.ts.map +1 -0
- package/dist/providers/kagi/adapter.js +188 -0
- package/dist/providers/kagi/adapter.js.map +1 -0
- package/dist/providers/kagi/client.d.ts +41 -0
- package/dist/providers/kagi/client.d.ts.map +1 -0
- package/dist/providers/kagi/client.js +100 -0
- package/dist/providers/kagi/client.js.map +1 -0
- package/dist/providers/kagi/credentials.d.ts +15 -0
- package/dist/providers/kagi/credentials.d.ts.map +1 -0
- package/dist/providers/kagi/credentials.js +35 -0
- package/dist/providers/kagi/credentials.js.map +1 -0
- package/dist/providers/kagi/diagnostics.d.ts +17 -0
- package/dist/providers/kagi/diagnostics.d.ts.map +1 -0
- package/dist/providers/kagi/diagnostics.js +33 -0
- package/dist/providers/kagi/diagnostics.js.map +1 -0
- package/dist/providers/linkup/client.d.ts +1 -0
- package/dist/providers/linkup/client.d.ts.map +1 -1
- package/dist/providers/linkup/client.js +3 -2
- package/dist/providers/linkup/client.js.map +1 -1
- package/dist/providers/linkup/credentials.d.ts +2 -0
- package/dist/providers/linkup/credentials.d.ts.map +1 -1
- package/dist/providers/linkup/credentials.js +2 -0
- package/dist/providers/linkup/credentials.js.map +1 -1
- package/dist/providers/minimax/adapter.d.ts.map +1 -1
- package/dist/providers/minimax/adapter.js +2 -2
- package/dist/providers/minimax/adapter.js.map +1 -1
- package/dist/providers/minimax/coding-plan-client.d.ts +1 -0
- package/dist/providers/minimax/coding-plan-client.d.ts.map +1 -1
- package/dist/providers/minimax/coding-plan-client.js +3 -2
- package/dist/providers/minimax/coding-plan-client.js.map +1 -1
- package/dist/providers/minimax/quota-client.d.ts +1 -0
- package/dist/providers/minimax/quota-client.d.ts.map +1 -1
- package/dist/providers/minimax/quota-client.js +3 -2
- package/dist/providers/minimax/quota-client.js.map +1 -1
- package/dist/providers/openalex/client.d.ts +2 -0
- package/dist/providers/openalex/client.d.ts.map +1 -1
- package/dist/providers/openalex/client.js +10 -3
- package/dist/providers/openalex/client.js.map +1 -1
- package/dist/providers/openalex/diagnostics.d.ts +1 -1
- package/dist/providers/openalex/diagnostics.js +1 -1
- package/dist/providers/openalex/diagnostics.js.map +1 -1
- package/dist/providers/parallel/client.d.ts +1 -0
- package/dist/providers/parallel/client.d.ts.map +1 -1
- package/dist/providers/parallel/client.js +3 -2
- package/dist/providers/parallel/client.js.map +1 -1
- package/dist/providers/parallel/credentials.d.ts +2 -0
- package/dist/providers/parallel/credentials.d.ts.map +1 -1
- package/dist/providers/parallel/credentials.js +2 -0
- package/dist/providers/parallel/credentials.js.map +1 -1
- package/dist/providers/perplexity/client.d.ts +2 -0
- package/dist/providers/perplexity/client.d.ts.map +1 -1
- package/dist/providers/perplexity/client.js +5 -4
- package/dist/providers/perplexity/client.js.map +1 -1
- package/dist/providers/perplexity/credentials.d.ts +2 -0
- package/dist/providers/perplexity/credentials.d.ts.map +1 -1
- package/dist/providers/perplexity/credentials.js +2 -0
- package/dist/providers/perplexity/credentials.js.map +1 -1
- package/dist/providers/pubmed/client.d.ts +2 -0
- package/dist/providers/pubmed/client.d.ts.map +1 -1
- package/dist/providers/pubmed/client.js +10 -3
- package/dist/providers/pubmed/client.js.map +1 -1
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +10 -1
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/searchapi/adapter.d.ts +54 -0
- package/dist/providers/searchapi/adapter.d.ts.map +1 -0
- package/dist/providers/searchapi/adapter.js +310 -0
- package/dist/providers/searchapi/adapter.js.map +1 -0
- package/dist/providers/searchapi/client.d.ts +73 -0
- package/dist/providers/searchapi/client.d.ts.map +1 -0
- package/dist/providers/searchapi/client.js +196 -0
- package/dist/providers/searchapi/client.js.map +1 -0
- package/dist/providers/searchapi/credentials.d.ts +46 -0
- package/dist/providers/searchapi/credentials.d.ts.map +1 -0
- package/dist/providers/searchapi/credentials.js +71 -0
- package/dist/providers/searchapi/credentials.js.map +1 -0
- package/dist/providers/searchapi/diagnostics.d.ts +48 -0
- package/dist/providers/searchapi/diagnostics.d.ts.map +1 -0
- package/dist/providers/searchapi/diagnostics.js +70 -0
- package/dist/providers/searchapi/diagnostics.js.map +1 -0
- package/dist/providers/searchapi/quota.d.ts +60 -0
- package/dist/providers/searchapi/quota.d.ts.map +1 -0
- package/dist/providers/searchapi/quota.js +125 -0
- package/dist/providers/searchapi/quota.js.map +1 -0
- package/dist/providers/spider/client.d.ts +2 -0
- package/dist/providers/spider/client.d.ts.map +1 -1
- package/dist/providers/spider/client.js +16 -6
- package/dist/providers/spider/client.js.map +1 -1
- package/dist/providers/spider/credentials.d.ts +2 -0
- package/dist/providers/spider/credentials.d.ts.map +1 -1
- package/dist/providers/spider/credentials.js +2 -0
- package/dist/providers/spider/credentials.js.map +1 -1
- package/dist/providers/tavily/client.d.ts +1 -0
- package/dist/providers/tavily/client.d.ts.map +1 -1
- package/dist/providers/tavily/client.js +3 -2
- package/dist/providers/tavily/client.js.map +1 -1
- package/dist/providers/tavily/credentials.d.ts +2 -0
- package/dist/providers/tavily/credentials.d.ts.map +1 -1
- package/dist/providers/tavily/credentials.js +2 -0
- package/dist/providers/tavily/credentials.js.map +1 -1
- package/dist/providers/types.d.ts +31 -2
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js +3 -0
- package/dist/providers/types.js.map +1 -1
- package/dist/providers/you/client.d.ts +4 -0
- package/dist/providers/you/client.d.ts.map +1 -1
- package/dist/providers/you/client.js +4 -5
- package/dist/providers/you/client.js.map +1 -1
- package/dist/providers/you/credentials.d.ts +2 -0
- package/dist/providers/you/credentials.d.ts.map +1 -1
- package/dist/providers/you/credentials.js +3 -3
- package/dist/providers/you/credentials.js.map +1 -1
- package/dist/providers/zai/adapter.d.ts.map +1 -1
- package/dist/providers/zai/adapter.js +219 -4
- package/dist/providers/zai/adapter.js.map +1 -1
- package/dist/providers/zai/credentials.d.ts +2 -0
- package/dist/providers/zai/credentials.d.ts.map +1 -1
- package/dist/providers/zai/credentials.js +2 -0
- package/dist/providers/zai/credentials.js.map +1 -1
- package/dist/providers/zai/layout-parsing.d.ts +76 -0
- package/dist/providers/zai/layout-parsing.d.ts.map +1 -0
- package/dist/providers/zai/layout-parsing.js +151 -0
- package/dist/providers/zai/layout-parsing.js.map +1 -0
- package/dist/providers/zai/media.d.ts +19 -0
- package/dist/providers/zai/media.d.ts.map +1 -1
- package/dist/providers/zai/media.js +61 -0
- package/dist/providers/zai/media.js.map +1 -1
- package/dist/providers/zai/monitor-client.d.ts +1 -0
- package/dist/providers/zai/monitor-client.d.ts.map +1 -1
- package/dist/providers/zai/monitor-client.js +3 -2
- package/dist/providers/zai/monitor-client.js.map +1 -1
- package/dist/providers/zai/quota.d.ts +4 -0
- package/dist/providers/zai/quota.d.ts.map +1 -1
- package/dist/providers/zai/quota.js +16 -1
- package/dist/providers/zai/quota.js.map +1 -1
- package/package.json +1 -1
- package/skills/scoutline/SKILL.md +163 -45
- package/skills/scoutline/references/advanced.md +12 -10
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
- **Repo** - Search and read GitHub repository code via ZRead
|
|
22
22
|
- **Tools** - MCP tool discovery, schemas, and raw calls
|
|
23
23
|
- **Code Mode** - TypeScript tool chaining for agent automation
|
|
24
|
-
- **Provider selection** - Run shared capabilities through Z.AI, MiniMax, Tavily, Exa, Brave, Firecrawl, Parallel AI, Perplexity, Jina AI, You.com, Linkup,
|
|
24
|
+
- **Provider selection** - Run shared capabilities through Z.AI, MiniMax, Tavily, Exa, Brave, Firecrawl, Parallel AI, Perplexity, Jina AI, You.com, Linkup, Spider.cloud, Bocha AI, SearchApi.io, or Kagi
|
|
25
25
|
- **Usage ledger** - Local 90-day call-usage history per provider and capability (`scoutline usage`), counters only
|
|
26
26
|
- **Saved artifacts** - Durable clean reports from any provider-backed run (`--save`), content + request id only, plus a credential-free `scoutline history` inventory (list/show/stats/recall/export/note/clear)
|
|
27
27
|
- **Research journal** - Always-on local memory of every `search`/`read`/`research` call: thin skeletons (query, provider, url+title identity, content hash) recorded under `~/.scoutline/artifacts/` and re-found offline via `history recall`; opt out per call (`--no-journal`) or globally (`journal: false`)
|
|
@@ -53,6 +53,30 @@ npx scoutline --provider brave search "AI policy news" --topic news
|
|
|
53
53
|
npx scoutline --provider brave search "rust async" --type video
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
To use Bocha AI (Search and Diagnostics):
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
export BOCHA_API_KEY="your-bocha-key"
|
|
60
|
+
npx scoutline --provider bocha search "AI policy news"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Get your Bocha AI API key at: https://open.bochaai.com/
|
|
64
|
+
|
|
65
|
+
To use Kagi (Search and Diagnostics):
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
export KAGI_API_KEY="your-kagi-key"
|
|
69
|
+
npx scoutline --provider kagi search "AI policy news"
|
|
70
|
+
npx scoutline --provider kagi search "AI policy" --topic news
|
|
71
|
+
npx scoutline doctor --provider kagi
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Kagi reads the key from `KAGI_API_KEY` (legacy alias `KAGI_TOKEN`).
|
|
75
|
+
Search rides `GET /api/v1/search` (`Authorization: Bot <key>`);
|
|
76
|
+
`--topic news` routes to `GET /api/v0/enrich/news`.
|
|
77
|
+
|
|
78
|
+
Get your Kagi API key at: https://kagi.com/settings/api
|
|
79
|
+
|
|
56
80
|
### Interactive Onboarding (`scoutline init`)
|
|
57
81
|
|
|
58
82
|
Instead of exporting environment variables, run the interactive wizard to
|
|
@@ -63,7 +87,8 @@ scoutline init
|
|
|
63
87
|
```
|
|
64
88
|
|
|
65
89
|
The wizard walks you through a registry-derived provider checklist
|
|
66
|
-
(all
|
|
90
|
+
(all 20 built-in registry entries — 15 Providers plus the five science
|
|
91
|
+
suppliers — rendered in registry order — equal
|
|
67
92
|
weight, none pre-checked), takes each key via
|
|
68
93
|
hidden input, and performs a single inline validation probe against an
|
|
69
94
|
ephemeral in-memory environment (the candidate key is never persisted or
|
|
@@ -142,9 +167,9 @@ npx scoutline --help
|
|
|
142
167
|
## Provider Selection
|
|
143
168
|
|
|
144
169
|
Shared commands (`search`, `vision`, `quota`, `doctor`, `repo`) accept a global
|
|
145
|
-
`--provider <zai|minimax|tavily|exa|brave|firecrawl|parallel|perplexity|jina|you|linkup|spider>` flag. Resolution precedence:
|
|
170
|
+
`--provider <zai|minimax|tavily|exa|brave|firecrawl|parallel|perplexity|jina|you|linkup|spider|bocha|searchapi|kagi>` flag. Resolution precedence:
|
|
146
171
|
|
|
147
|
-
1. Explicit `--provider <zai|minimax|tavily|exa|brave|firecrawl|parallel|perplexity|jina|you|linkup|spider>` on the command line
|
|
172
|
+
1. Explicit `--provider <zai|minimax|tavily|exa|brave|firecrawl|parallel|perplexity|jina|you|linkup|spider|bocha|searchapi|kagi>` on the command line
|
|
148
173
|
2. `SCOUTLINE_PROVIDER` environment variable
|
|
149
174
|
3. Per-capability **routing table** (`config.json` `routing` key; the first
|
|
150
175
|
configured, capable provider in the list wins — over quota ranking)
|
|
@@ -187,7 +212,7 @@ selected provider does not advertise the capability (for example,
|
|
|
187
212
|
MiniMax does not advertise `repository-exploration` or `reader`) or
|
|
188
213
|
fails at runtime, Scoutline emits a stderr notice and silently
|
|
189
214
|
reroutes to the next eligible configured provider in registry order
|
|
190
|
-
`[zai, minimax, tavily, exa, brave, firecrawl, parallel, perplexity, jina, you, linkup, spider, arxiv, openalex, crossref, pubmed, europepmc]`. Pass `--no-fallback`
|
|
215
|
+
`[zai, minimax, tavily, exa, brave, firecrawl, parallel, perplexity, jina, you, linkup, spider, bocha, searchapi, kagi, arxiv, openalex, crossref, pubmed, europepmc]`. Pass `--no-fallback`
|
|
191
216
|
(or set `SCOUTLINE_NO_FALLBACK=1`) to restore the previous strict
|
|
192
217
|
single-provider, fail-loud behavior for scripting or cost-sensitive
|
|
193
218
|
workflows. See
|
|
@@ -238,6 +263,15 @@ every arm runs every sub-query and occurrences span the arms ×
|
|
|
238
263
|
sub-queries grid. Disable the standing switch with
|
|
239
264
|
`scoutline config set fanout false`.
|
|
240
265
|
|
|
266
|
+
**Ranking (fusion):** as of this release, merged lists — from fan-out
|
|
267
|
+
and from `--merge` — no longer rank by raw occurrence count but by
|
|
268
|
+
reciprocal rank fusion (Σ 1/(60 + rank) over every arm × sub-query
|
|
269
|
+
occurrence; each row carries a fixed 3-decimal `fusionScore`, and
|
|
270
|
+
near-duplicate cluster members travel on `clusterUrls`). If you need
|
|
271
|
+
the old order back, `scoutline config set fusion occurrence` restores
|
|
272
|
+
the pre-fusion ordering byte-for-byte (or set `SCOUTLINE_FUSION=occurrence`
|
|
273
|
+
per invocation; the config key is `fusion`, default `rrf`).
|
|
274
|
+
|
|
241
275
|
### Local Context (`--context` / `--context-stdin`)
|
|
242
276
|
|
|
243
277
|
Steer `research` and `search` with a local notes file (markdown headings and
|
|
@@ -370,33 +404,34 @@ for the full contract.
|
|
|
370
404
|
The matrix below is generated from the production provider registry
|
|
371
405
|
(`packages/scoutline/src/providers/registry.ts`) and reflects the
|
|
372
406
|
release-shipped capability advertisements; the registry order is
|
|
373
|
-
`[zai, minimax, tavily, exa, brave, firecrawl, parallel, perplexity, jina, you, linkup, spider, arxiv, openalex, crossref, pubmed, europepmc]`.
|
|
407
|
+
`[zai, minimax, tavily, exa, brave, firecrawl, parallel, perplexity, jina, you, linkup, spider, bocha, searchapi, kagi, arxiv, openalex, crossref, pubmed, europepmc]`.
|
|
374
408
|
The matrix columns cover the shared-capability providers — the five
|
|
375
409
|
keyless science suppliers (arXiv, OpenAlex, Crossref, PubMed, Europe
|
|
376
410
|
PMC) serve only `scoutline science ...` and `doctor` (see the Science
|
|
377
411
|
section). The exact same `descriptor.capabilities()` set drives
|
|
378
412
|
executor preflight, Provider selection, and `doctor`.
|
|
379
413
|
|
|
380
|
-
| Capability | Z.AI | MiniMax | Tavily | Exa | Brave | Firecrawl | Parallel | Perplexity | Jina | You.com | Linkup | Spider.cloud | Notes |
|
|
381
|
-
|
|
382
|
-
| `search` | Yes | Yes | Yes | Yes | Yes (incl. `type: "video"`) | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Parallel (declarative semantic), Jina (neural web search) |
|
|
383
|
-
| `vision.interpret-image` (analyze) | Yes | Yes | No | No | No | No | No | No | No | No | No | No | Provider-specific media limits; uncached |
|
|
384
|
-
| `vision.ui-artifact` (ui-to-code) | Yes | Available | No | No | No | No | No | No | No | No | No | No | Live-attested; conformance-gated |
|
|
385
|
-
| `vision.extract-text` | Yes | Pending | No | No | No | No | No | No | No | No | No | No | Implemented, pending live conformance |
|
|
386
|
-
| `vision.diagnose-error` | Yes | Available | No | No | No | No | No | No | No | No | No | No | Live-attested; conformance-gated |
|
|
387
|
-
| `vision.diagram` | Yes | Pending | No | No | No | No | No | No | No | No | No | No | Implemented, pending live conformance |
|
|
388
|
-
| `vision.chart` | Yes | Pending | No | No | No | No | No | No | No | No | No | No | Implemented, pending live conformance |
|
|
389
|
-
| `vision.diff` (image diff) | Yes | No | No | No | No | No | No | No | No | No | No | No | Z.AI-only (never MiniMax-claimable) |
|
|
390
|
-
| `vision.video` | Yes | No | No | No | No | No | No | No | No | No | No | No | Z.AI-only (never MiniMax-claimable) |
|
|
391
|
-
| `quota` | Yes | Yes | Yes | No | Yes | Yes (USD balance) | No | No | Yes (rate-limit telemetry, not spend) | No | Yes (credits) | Yes (credits) | Normalized `QuotaDashboard` (ADR-0001) |
|
|
392
|
-
| `diagnostics` (`doctor`) | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Lists every Provider; probes configured |
|
|
393
|
-
| `read` (Reader) | Yes | **No** | Yes | Yes | No | Yes | Yes | No | Yes | Yes | Yes | Yes | Parallel (Extract API), Jina, You.com, Linkup, and Spider.cloud add Reader support |
|
|
394
|
-
| `crawl` | **No** | **No** | Yes | No | No | Yes (async) | No | No | No | No | No | Yes (sync) | Tavily sync; Firecrawl async (resumable after Ctrl-C) |
|
|
395
|
-
| `map` | **No** | **No** | Yes | No | No | Yes | No | No | No | No | No | Yes | URL-set discovery; no per-page content |
|
|
396
|
-
| `research` | **No** | **No** | Yes | Yes | **No** | **No** | Yes | Yes | Yes | Yes | Yes | No | Tavily, Exa, Parallel, Perplexity (Agent API `high` preset), Jina DeepSearch, You.com, and Linkup research report synthesis |
|
|
397
|
-
| `
|
|
398
|
-
| `
|
|
399
|
-
| `
|
|
414
|
+
| Capability | Z.AI | MiniMax | Tavily | Exa | Brave | Firecrawl | Parallel | Perplexity | Jina AI | You.com | Linkup | Spider.cloud | Bocha AI | SearchApi | Kagi | Notes |
|
|
415
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
416
|
+
| `search` | Yes | Yes | Yes | Yes | Yes (incl. `type: "video"`) | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Parallel (declarative semantic), Jina (neural web search) |
|
|
417
|
+
| `vision.interpret-image` (analyze) | Yes | Yes | No | No | No | No | No | No | No | No | No | No | No | No | No | Provider-specific media limits; uncached |
|
|
418
|
+
| `vision.ui-artifact` (ui-to-code) | Yes | Available | No | No | No | No | No | No | No | No | No | No | No | No | No | Live-attested; conformance-gated |
|
|
419
|
+
| `vision.extract-text` | Yes (GLM-OCR engine: PDF ≤50MB, images ≤10MB, content-hash cached; exhaustion falls back to the vision model) | Pending | No | No | No | No | No | No | No | No | No | No | No | No | No | Implemented, pending live conformance |
|
|
420
|
+
| `vision.diagnose-error` | Yes | Available | No | No | No | No | No | No | No | No | No | No | No | No | No | Live-attested; conformance-gated |
|
|
421
|
+
| `vision.diagram` | Yes | Pending | No | No | No | No | No | No | No | No | No | No | No | No | No | Implemented, pending live conformance |
|
|
422
|
+
| `vision.chart` | Yes | Pending | No | No | No | No | No | No | No | No | No | No | No | No | No | Implemented, pending live conformance |
|
|
423
|
+
| `vision.diff` (image diff) | Yes | No | No | No | No | No | No | No | No | No | No | No | No | No | No | Z.AI-only (never MiniMax-claimable) |
|
|
424
|
+
| `vision.video` | Yes | No | No | No | No | No | No | No | No | No | No | No | No | No | No | Z.AI-only (never MiniMax-claimable) |
|
|
425
|
+
| `quota` | Yes | Yes | Yes | No | Yes | Yes (USD balance) | No | No | Yes (rate-limit telemetry, not spend) | No | Yes (credits) | Yes (credits) | No | Yes (credits) | No | Normalized `QuotaDashboard` (ADR-0001) |
|
|
426
|
+
| `diagnostics` (`doctor`) | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Lists every Provider; probes configured |
|
|
427
|
+
| `read` (Reader) | Yes | **No** | Yes | Yes | No | Yes | Yes | No | Yes | Yes | Yes | Yes | No | **No** | No | Parallel (Extract API), Jina, You.com, Linkup, and Spider.cloud add Reader support |
|
|
428
|
+
| `crawl` | **No** | **No** | Yes | No | No | Yes (async) | No | No | No | No | No | Yes (sync) | No | **No** | No | Tavily sync; Firecrawl async (resumable after Ctrl-C) |
|
|
429
|
+
| `map` | **No** | **No** | Yes | No | No | Yes | No | No | No | No | No | Yes | No | **No** | No | URL-set discovery; no per-page content |
|
|
430
|
+
| `research` | **No** | **No** | Yes | Yes | **No** | **No** | Yes | Yes | Yes | Yes | Yes | No | No | **No** | No | Tavily, Exa, Parallel, Perplexity (Agent API `high` preset), Jina DeepSearch, You.com, and Linkup research report synthesis |
|
|
431
|
+
| `investigation` (EvidencePack) | Yes | **No** (no reader) | Yes | Yes | **No** (no reader) | Yes | Yes | **No** (no reader) | Yes | Yes | Yes | Yes | **No** (no reader) | **No** (no reader) | **No** (no reader) | Provider-composed — supplied by the search+reader supplier union (Z.AI, Tavily, Exa, Firecrawl, Parallel, Jina AI, You.com, Linkup, Spider.cloud); `--synthesize` is Z.AI-only |
|
|
432
|
+
| `repo search` / `repo read` / `repo tree` / `repo brief` | Yes | **No** | **No** | **No** | **No** | **No** | **No** | **No** | **No** | No | No | No | No | No | No | Participates in selection; only Z.AI supplies `repository-exploration` |
|
|
433
|
+
| `tools`, `tool`, `call` (Raw tools) | Yes | No | No | No | No | No | No | No | No | No | No | No | No | No | No | Z.AI-only; accepts but ignores `--provider` |
|
|
434
|
+
| `code` (Code Mode) | Yes | No | No | No | No | No | No | No | No | No | No | No | No | No | No | Z.AI-only; accepts but ignores `--provider` |
|
|
400
435
|
|
|
401
436
|
Media limits for general single-image interpretation:
|
|
402
437
|
|
|
@@ -491,6 +526,53 @@ the supplier wire supports them (rejected with `UNSUPPORTED_OPTION`
|
|
|
491
526
|
elsewhere — never silently dropped). `science get <identifier>` fetches
|
|
492
527
|
one work by bare DOI, numeric PMID, or arXiv id.
|
|
493
528
|
|
|
529
|
+
### Investigation (`investigate`)
|
|
530
|
+
|
|
531
|
+
`scoutline investigate <question>` runs a local, transparent,
|
|
532
|
+
cache-resumable pipeline ([ADR-0013](https://github.com/vikasagarwal101/scoutline/blob/main/docs/adr/0013-local-investigation-pipeline.md)):
|
|
533
|
+
plan sub-queries → fan-out search → Fusion merge → read the top
|
|
534
|
+
`--sources` (default 5) → deterministic passage extraction → an
|
|
535
|
+
EvidencePack (`schemaVersion` 1). No provider-side job runs — distinct
|
|
536
|
+
from Research, an opaque billed provider job. The pack is data, not
|
|
537
|
+
prose: agents consume it directly and text output modes fall back to
|
|
538
|
+
JSON (agent-synthesis is the default; you write the prose). Warm re-runs
|
|
539
|
+
replay the response cache (`coverage.cacheHits` reflects it).
|
|
540
|
+
|
|
541
|
+
```bash
|
|
542
|
+
scoutline investigate "rust async runtime benchmarks"
|
|
543
|
+
scoutline investigate "rust async | rust tokio" # pipes split explicit sub-queries
|
|
544
|
+
scoutline investigate "topic" --provider tavily,exa --sources 8
|
|
545
|
+
scoutline investigate "topic" --max-chars 20000 --synthesize
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
Sub-query planning precedence: explicit pipes (the `--merge` grammar) >
|
|
549
|
+
`--context <path>` (a local notes file — it never leaves the machine,
|
|
550
|
+
only the derived sub-query strings are searched) > deterministic
|
|
551
|
+
templates of the bare question (original, key terms,
|
|
552
|
+
overview/evidence/criticism; deduped, capped at 5). Provider selection
|
|
553
|
+
reuses search's fan-out activation tiers verbatim (comma-list/`all`
|
|
554
|
+
fan-out, single pin, `config set fanout true`). Cost is stated in one
|
|
555
|
+
stderr notice before any billable work: N sub-queries × M arms billable
|
|
556
|
+
searches + up to K reads.
|
|
557
|
+
|
|
558
|
+
Controls: `--sources <n>`, `--max-chars <n>` (passages trim first, late
|
|
559
|
+
sources drop; the full untrimmed pack is saved and recoverable via
|
|
560
|
+
`scoutline history show <ref>`), `--no-cache`, `--no-journal`, `--save`,
|
|
561
|
+
`--isolated`. Sources surfaced but unread land in `coverage.unread` with
|
|
562
|
+
a reason code — never silently dropped. `--synthesize` attaches an
|
|
563
|
+
additive `brief` via Z.AI chat (Z.AI-only; absent by default; a
|
|
564
|
+
synthesis failure is the run's terminal error, never a degraded pack).
|
|
565
|
+
`--depth`, `--arms`, and `--budget-tokens` are rejected with
|
|
566
|
+
`VALIDATION_ERROR` by design.
|
|
567
|
+
|
|
568
|
+
`--verify` turns the positional into a statement: sentence-claims
|
|
569
|
+
(≤ 8, fail-loud) are searched verbatim and matched to the extracted
|
|
570
|
+
passages; the pack gains an additive `verify` block — per claim, a
|
|
571
|
+
verdict (`corroborated` / `contradicted` / `unresolved`), evidence
|
|
572
|
+
pointers, and a negation-cue count. `contradicted` is a disclosed
|
|
573
|
+
negation-cue heuristic (hint-grade), not semantic judgment;
|
|
574
|
+
`--context` + `--verify` is a mode-conflict VALIDATION_ERROR.
|
|
575
|
+
|
|
494
576
|
## Usage
|
|
495
577
|
|
|
496
578
|
The CLI is self-documenting. Use `--help` at any level:
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EvidencePack schema + total decoder (T1, docs/plans/investigate-pipeline
|
|
3
|
+
* PRD AC-6; ADR-0013 §7).
|
|
4
|
+
*
|
|
5
|
+
* The EvidencePack is the self-contained deliverable of an Investigation
|
|
6
|
+
* (CONTEXT.md glossary): question, sub-queries, sources with per-source
|
|
7
|
+
* content hashes and extracted passages, and a coverage block. The pack is
|
|
8
|
+
* data, not prose — agent-synthesis is the contract; `--synthesize` (T7)
|
|
9
|
+
* attaches a `brief` additively and is not part of this schema.
|
|
10
|
+
*
|
|
11
|
+
* This module declares the pack type, its total decoder, and the
|
|
12
|
+
* contentSha256 shape predicate. It imports NOTHING from other src modules
|
|
13
|
+
* (self-contained by ticket contract; hashing itself lands in T5 — this
|
|
14
|
+
* module only validates hash *shape*).
|
|
15
|
+
*
|
|
16
|
+
* Decoder discipline mirrors capabilities/reader.ts exactly:
|
|
17
|
+
* - accepts `unknown`, returns the pack or `null`, never throws,
|
|
18
|
+
* never trusts a generic cast;
|
|
19
|
+
* - reject primitives and arrays at the top level;
|
|
20
|
+
* - `schemaVersion` MUST be the literal number 1 (rejects "1", 1.5,
|
|
21
|
+
* bigints, any future version);
|
|
22
|
+
* - `title: null` is a valid decoded value (reader parity);
|
|
23
|
+
* - optional fields preserved verbatim when present.
|
|
24
|
+
*/
|
|
25
|
+
/** `[start, end)` character offsets into the source `content` string. */
|
|
26
|
+
export type CharRange = readonly [number, number];
|
|
27
|
+
/**
|
|
28
|
+
* One extracted passage. `quote` is pinned to the content by `charRange`:
|
|
29
|
+
* `content.slice(...charRange) === quote` for every passage (D4). The pin
|
|
30
|
+
* is enforced where content is available (assembly in T5, extraction in
|
|
31
|
+
* T3); the decoder enforces the shape so a decoded pack is at least
|
|
32
|
+
* structurally sound.
|
|
33
|
+
*/
|
|
34
|
+
export interface EvidencePassage {
|
|
35
|
+
readonly quote: string;
|
|
36
|
+
readonly charRange: CharRange;
|
|
37
|
+
}
|
|
38
|
+
/** One read source: reader-envelope fields + passages. */
|
|
39
|
+
export interface EvidenceSource {
|
|
40
|
+
readonly url: string;
|
|
41
|
+
/** The URL the Reader actually fetched (provider rewrite possible). */
|
|
42
|
+
readonly finalUrl: string;
|
|
43
|
+
/** Page title if the provider returned one; `null` if absent (reader parity). */
|
|
44
|
+
readonly title: string | null;
|
|
45
|
+
/** ISO-8601 UTC Z timestamp captured when the read resolved (D5). */
|
|
46
|
+
readonly fetchedAt: string;
|
|
47
|
+
/** Provider id that surfaced the source (search-arm winner). */
|
|
48
|
+
readonly provider: string;
|
|
49
|
+
/** Mirrors the read `format`; `"markdown"` or `"text"`. */
|
|
50
|
+
readonly contentFormat: "markdown" | "text";
|
|
51
|
+
/** Lowercase hex SHA-256 of the UTF-8 normalized content string (D5). */
|
|
52
|
+
readonly contentSha256: string;
|
|
53
|
+
readonly passages: readonly EvidencePassage[];
|
|
54
|
+
}
|
|
55
|
+
/** Coverage block: how much of the planned grid actually produced evidence. */
|
|
56
|
+
export interface EvidenceCoverage {
|
|
57
|
+
/** Number of planned sub-queries. */
|
|
58
|
+
readonly subQueries: number;
|
|
59
|
+
/** Number of search arms actually used. */
|
|
60
|
+
readonly armsUsed: number;
|
|
61
|
+
/** Number of post-cluster candidate sources surfaced. */
|
|
62
|
+
readonly sourcesConsidered: number;
|
|
63
|
+
/** Number of sources whose read resolved successfully. */
|
|
64
|
+
readonly sourcesRead: number;
|
|
65
|
+
/** Count of search arms + reads served warm from cache (D5). */
|
|
66
|
+
readonly cacheHits: number;
|
|
67
|
+
/**
|
|
68
|
+
* Sources surfaced but not read, each with a reason code only —
|
|
69
|
+
* redacted, no error prose crossing the interface (house rule, D5).
|
|
70
|
+
*/
|
|
71
|
+
readonly unread: readonly {
|
|
72
|
+
readonly url: string;
|
|
73
|
+
readonly reason: string;
|
|
74
|
+
}[];
|
|
75
|
+
}
|
|
76
|
+
/** The self-contained Investigation deliverable (PRD AC-6). */
|
|
77
|
+
export interface EvidencePack {
|
|
78
|
+
readonly schemaVersion: 1;
|
|
79
|
+
readonly question: string;
|
|
80
|
+
readonly subQueries: readonly string[];
|
|
81
|
+
readonly sources: readonly EvidenceSource[];
|
|
82
|
+
readonly coverage: EvidenceCoverage;
|
|
83
|
+
/**
|
|
84
|
+
* investigate-verify lane T2 (PRD AC-6): the additive claim-
|
|
85
|
+
* corroboration block. ABSENT on question-mode packs (byte-identity
|
|
86
|
+
* pin); present only when `investigate --verify` assembled the pack.
|
|
87
|
+
*/
|
|
88
|
+
readonly verify?: VerifyBlock;
|
|
89
|
+
}
|
|
90
|
+
/** The deterministic verdict vocabulary (cue heuristic, PRD AC-5). */
|
|
91
|
+
export type ClaimVerdict = "corroborated" | "contradicted" | "unresolved";
|
|
92
|
+
/** One evidence pointer into the pack's own `sources` array. */
|
|
93
|
+
export interface ClaimEvidencePointer {
|
|
94
|
+
readonly sourceIndex: number;
|
|
95
|
+
readonly passageIndex: number;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* One claim row: the claim text, its verdict, the count of cue-bearing
|
|
99
|
+
* matching passages (agent re-judgment input — the cue heuristic is
|
|
100
|
+
* DISCLOSED hint-grade), and first-encounter evidence pointers.
|
|
101
|
+
*/
|
|
102
|
+
export interface ClaimRow {
|
|
103
|
+
readonly text: string;
|
|
104
|
+
readonly verdict: ClaimVerdict;
|
|
105
|
+
readonly negationCues: number;
|
|
106
|
+
readonly evidence: readonly ClaimEvidencePointer[];
|
|
107
|
+
}
|
|
108
|
+
/** The additive verify block: the statement plus one row per claim. */
|
|
109
|
+
export interface VerifyBlock {
|
|
110
|
+
readonly statement: string;
|
|
111
|
+
readonly claims: readonly ClaimRow[];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* `contentSha256` validity: a 64-character lowercase hex string —
|
|
115
|
+
* the exact shape of `createHash("sha256")…digest("hex")` output.
|
|
116
|
+
* Ruling (ticket T1): hex-shape is enforced at decode, so an
|
|
117
|
+
* uppercased, truncated, or non-hex string fails closed. Full
|
|
118
|
+
* recompute-vs-content binding belongs to assembly (T5), which is the
|
|
119
|
+
* only place the paired content string exists.
|
|
120
|
+
*/
|
|
121
|
+
export declare function isValidContentSha256(value: unknown): value is string;
|
|
122
|
+
/**
|
|
123
|
+
* Decode an `unknown` value into a canonical `EvidencePack`. Returns the
|
|
124
|
+
* typed pack on success, `null` for any malformed value. NEVER throws,
|
|
125
|
+
* NEVER trusts a generic cast.
|
|
126
|
+
*
|
|
127
|
+
* `title: null` is valid (reader parity). `sources` and `passages` may be
|
|
128
|
+
* empty arrays (a pack whose every read failed is still a valid, sad pack).
|
|
129
|
+
* `brief` (T7) is additive: unknown keys are NOT rejected — a decoded pack
|
|
130
|
+
* carries exactly the AC-6 keys, and an input carrying extra keys decodes
|
|
131
|
+
* to the canonical subset.
|
|
132
|
+
*/
|
|
133
|
+
export declare function decodeInvestigationPack(value: unknown): EvidencePack | null;
|
|
134
|
+
//# sourceMappingURL=investigation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"investigation.d.ts","sourceRoot":"","sources":["../../src/capabilities/investigation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EvidencePack schema + total decoder (T1, docs/plans/investigate-pipeline
|
|
3
|
+
* PRD AC-6; ADR-0013 §7).
|
|
4
|
+
*
|
|
5
|
+
* The EvidencePack is the self-contained deliverable of an Investigation
|
|
6
|
+
* (CONTEXT.md glossary): question, sub-queries, sources with per-source
|
|
7
|
+
* content hashes and extracted passages, and a coverage block. The pack is
|
|
8
|
+
* data, not prose — agent-synthesis is the contract; `--synthesize` (T7)
|
|
9
|
+
* attaches a `brief` additively and is not part of this schema.
|
|
10
|
+
*
|
|
11
|
+
* This module declares the pack type, its total decoder, and the
|
|
12
|
+
* contentSha256 shape predicate. It imports NOTHING from other src modules
|
|
13
|
+
* (self-contained by ticket contract; hashing itself lands in T5 — this
|
|
14
|
+
* module only validates hash *shape*).
|
|
15
|
+
*
|
|
16
|
+
* Decoder discipline mirrors capabilities/reader.ts exactly:
|
|
17
|
+
* - accepts `unknown`, returns the pack or `null`, never throws,
|
|
18
|
+
* never trusts a generic cast;
|
|
19
|
+
* - reject primitives and arrays at the top level;
|
|
20
|
+
* - `schemaVersion` MUST be the literal number 1 (rejects "1", 1.5,
|
|
21
|
+
* bigints, any future version);
|
|
22
|
+
* - `title: null` is a valid decoded value (reader parity);
|
|
23
|
+
* - optional fields preserved verbatim when present.
|
|
24
|
+
*/
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Field predicates
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
function isPlainObject(value) {
|
|
29
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
30
|
+
}
|
|
31
|
+
function isNonEmptyString(value) {
|
|
32
|
+
return typeof value === "string" && value.length > 0;
|
|
33
|
+
}
|
|
34
|
+
function isFiniteNumber(value) {
|
|
35
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* `contentSha256` validity: a 64-character lowercase hex string —
|
|
39
|
+
* the exact shape of `createHash("sha256")…digest("hex")` output.
|
|
40
|
+
* Ruling (ticket T1): hex-shape is enforced at decode, so an
|
|
41
|
+
* uppercased, truncated, or non-hex string fails closed. Full
|
|
42
|
+
* recompute-vs-content binding belongs to assembly (T5), which is the
|
|
43
|
+
* only place the paired content string exists.
|
|
44
|
+
*/
|
|
45
|
+
export function isValidContentSha256(value) {
|
|
46
|
+
if (typeof value !== "string" || value.length !== 64)
|
|
47
|
+
return false;
|
|
48
|
+
for (const ch of value) {
|
|
49
|
+
const code = ch.charCodeAt(0);
|
|
50
|
+
const isDigit = code >= 48 && code <= 57;
|
|
51
|
+
const isLowerHex = (code >= 97 && code <= 102) || isDigit;
|
|
52
|
+
if (!isLowerHex)
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// Total decoder
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
function decodeCharRange(value) {
|
|
61
|
+
// PR #264 F2: the documented `[start, end)` invariant, enforced at
|
|
62
|
+
// decode — safe integers, non-negative start, strictly increasing
|
|
63
|
+
// (an empty range cannot quote a non-empty passage).
|
|
64
|
+
return (Array.isArray(value) &&
|
|
65
|
+
value.length === 2 &&
|
|
66
|
+
Number.isSafeInteger(value[0]) &&
|
|
67
|
+
Number.isSafeInteger(value[1]) &&
|
|
68
|
+
value[0] >= 0 &&
|
|
69
|
+
value[1] > value[0]);
|
|
70
|
+
}
|
|
71
|
+
function decodePassage(value) {
|
|
72
|
+
if (!isPlainObject(value))
|
|
73
|
+
return null;
|
|
74
|
+
if (!isNonEmptyString(value.quote))
|
|
75
|
+
return null;
|
|
76
|
+
if (!decodeCharRange(value.charRange))
|
|
77
|
+
return null;
|
|
78
|
+
return { quote: value.quote, charRange: [value.charRange[0], value.charRange[1]] };
|
|
79
|
+
}
|
|
80
|
+
function decodeSource(value) {
|
|
81
|
+
if (!isPlainObject(value))
|
|
82
|
+
return null;
|
|
83
|
+
if (!isNonEmptyString(value.url))
|
|
84
|
+
return null;
|
|
85
|
+
if (!isNonEmptyString(value.finalUrl))
|
|
86
|
+
return null;
|
|
87
|
+
const title = value.title;
|
|
88
|
+
if (title !== null && typeof title !== "string")
|
|
89
|
+
return null;
|
|
90
|
+
if (!isNonEmptyString(value.fetchedAt))
|
|
91
|
+
return null;
|
|
92
|
+
if (!isNonEmptyString(value.provider))
|
|
93
|
+
return null;
|
|
94
|
+
if (value.contentFormat !== "markdown" && value.contentFormat !== "text")
|
|
95
|
+
return null;
|
|
96
|
+
if (!isValidContentSha256(value.contentSha256))
|
|
97
|
+
return null;
|
|
98
|
+
if (!Array.isArray(value.passages))
|
|
99
|
+
return null;
|
|
100
|
+
const passages = [];
|
|
101
|
+
for (const raw of value.passages) {
|
|
102
|
+
const passage = decodePassage(raw);
|
|
103
|
+
if (passage === null)
|
|
104
|
+
return null;
|
|
105
|
+
passages.push(passage);
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
url: value.url,
|
|
109
|
+
finalUrl: value.finalUrl,
|
|
110
|
+
title: title,
|
|
111
|
+
fetchedAt: value.fetchedAt,
|
|
112
|
+
provider: value.provider,
|
|
113
|
+
contentFormat: value.contentFormat,
|
|
114
|
+
contentSha256: value.contentSha256,
|
|
115
|
+
passages,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function decodeCoverage(value) {
|
|
119
|
+
if (!isPlainObject(value))
|
|
120
|
+
return null;
|
|
121
|
+
if (!isFiniteNumber(value.subQueries))
|
|
122
|
+
return null;
|
|
123
|
+
if (!isFiniteNumber(value.armsUsed))
|
|
124
|
+
return null;
|
|
125
|
+
if (!isFiniteNumber(value.sourcesConsidered))
|
|
126
|
+
return null;
|
|
127
|
+
if (!isFiniteNumber(value.sourcesRead))
|
|
128
|
+
return null;
|
|
129
|
+
if (!isFiniteNumber(value.cacheHits))
|
|
130
|
+
return null;
|
|
131
|
+
if (!Array.isArray(value.unread))
|
|
132
|
+
return null;
|
|
133
|
+
const unread = [];
|
|
134
|
+
for (const raw of value.unread) {
|
|
135
|
+
if (!isPlainObject(raw))
|
|
136
|
+
return null;
|
|
137
|
+
if (!isNonEmptyString(raw.url))
|
|
138
|
+
return null;
|
|
139
|
+
if (!isNonEmptyString(raw.reason))
|
|
140
|
+
return null;
|
|
141
|
+
unread.push({ url: raw.url, reason: raw.reason });
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
subQueries: value.subQueries,
|
|
145
|
+
armsUsed: value.armsUsed,
|
|
146
|
+
sourcesConsidered: value.sourcesConsidered,
|
|
147
|
+
sourcesRead: value.sourcesRead,
|
|
148
|
+
cacheHits: value.cacheHits,
|
|
149
|
+
unread,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Decode an `unknown` value into a canonical `EvidencePack`. Returns the
|
|
154
|
+
* typed pack on success, `null` for any malformed value. NEVER throws,
|
|
155
|
+
* NEVER trusts a generic cast.
|
|
156
|
+
*
|
|
157
|
+
* `title: null` is valid (reader parity). `sources` and `passages` may be
|
|
158
|
+
* empty arrays (a pack whose every read failed is still a valid, sad pack).
|
|
159
|
+
* `brief` (T7) is additive: unknown keys are NOT rejected — a decoded pack
|
|
160
|
+
* carries exactly the AC-6 keys, and an input carrying extra keys decodes
|
|
161
|
+
* to the canonical subset.
|
|
162
|
+
*/
|
|
163
|
+
export function decodeInvestigationPack(value) {
|
|
164
|
+
// PR #264 F1: total containment for the never-throws contract — a
|
|
165
|
+
// throwing getter or Proxy trap on untrusted input must surface as
|
|
166
|
+
// a fail-closed null, never as an exception out of the decoder.
|
|
167
|
+
try {
|
|
168
|
+
return decodeInvestigationPackInner(value);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function decodeInvestigationPackInner(value) {
|
|
175
|
+
if (!isPlainObject(value))
|
|
176
|
+
return null;
|
|
177
|
+
if (value.schemaVersion !== 1)
|
|
178
|
+
return null;
|
|
179
|
+
if (!isNonEmptyString(value.question))
|
|
180
|
+
return null;
|
|
181
|
+
if (!Array.isArray(value.subQueries))
|
|
182
|
+
return null;
|
|
183
|
+
for (const q of value.subQueries) {
|
|
184
|
+
if (!isNonEmptyString(q))
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
if (!Array.isArray(value.sources))
|
|
188
|
+
return null;
|
|
189
|
+
const sources = [];
|
|
190
|
+
for (const raw of value.sources) {
|
|
191
|
+
const source = decodeSource(raw);
|
|
192
|
+
if (source === null)
|
|
193
|
+
return null;
|
|
194
|
+
sources.push(source);
|
|
195
|
+
}
|
|
196
|
+
const coverage = decodeCoverage(value.coverage);
|
|
197
|
+
if (coverage === null)
|
|
198
|
+
return null;
|
|
199
|
+
// investigate-verify lane T2 (D4): additive-optional `verify` — absent
|
|
200
|
+
// keeps the canonical subset (question-mode byte identity); present is
|
|
201
|
+
// validated row-by-row and fails closed on any malformed row.
|
|
202
|
+
const verify = decodeVerifyBlock(value.verify, sources.length, (sourceIndex) => sources[sourceIndex] === undefined ? 0 : sources[sourceIndex].passages.length);
|
|
203
|
+
if (verify === undefined)
|
|
204
|
+
return null;
|
|
205
|
+
return {
|
|
206
|
+
schemaVersion: 1,
|
|
207
|
+
question: value.question,
|
|
208
|
+
subQueries: [...value.subQueries],
|
|
209
|
+
sources,
|
|
210
|
+
coverage,
|
|
211
|
+
...(verify !== null ? { verify } : {}),
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const CLAIM_VERDICTS = ["corroborated", "contradicted", "unresolved"];
|
|
215
|
+
/**
|
|
216
|
+
* Decode the additive verify block. `undefined` = malformed (the caller
|
|
217
|
+
* fails closed); `null` = absent (the canonical subset stands); the
|
|
218
|
+
* decoded block = present + valid.
|
|
219
|
+
*
|
|
220
|
+
* PR #270 babysit: pointer RANGE is cross-checked against the decoded
|
|
221
|
+
* sources of the SAME pack (sourceIndex < sourceCount; passageIndex <
|
|
222
|
+
* that source's passage count) — a shape-safe but out-of-range pointer
|
|
223
|
+
* is malformed, INCLUDING any pointer into a zero-source pack (it can
|
|
224
|
+
* never dereference; assembly emits empty evidence there by
|
|
225
|
+
* construction, so only hand-built input reaches that arm).
|
|
226
|
+
*/
|
|
227
|
+
function decodeVerifyBlock(value, sourceCount, passageCountAt) {
|
|
228
|
+
if (value === undefined)
|
|
229
|
+
return null;
|
|
230
|
+
if (!isPlainObject(value))
|
|
231
|
+
return undefined;
|
|
232
|
+
if (!isNonEmptyString(value.statement))
|
|
233
|
+
return undefined;
|
|
234
|
+
if (!Array.isArray(value.claims))
|
|
235
|
+
return undefined;
|
|
236
|
+
const claims = [];
|
|
237
|
+
for (const raw of value.claims) {
|
|
238
|
+
if (!isPlainObject(raw))
|
|
239
|
+
return undefined;
|
|
240
|
+
if (!isNonEmptyString(raw.text))
|
|
241
|
+
return undefined;
|
|
242
|
+
if (typeof raw.verdict !== "string" || !CLAIM_VERDICTS.includes(raw.verdict)) {
|
|
243
|
+
return undefined;
|
|
244
|
+
}
|
|
245
|
+
if (typeof raw.negationCues !== "number" ||
|
|
246
|
+
!Number.isSafeInteger(raw.negationCues) ||
|
|
247
|
+
raw.negationCues < 0) {
|
|
248
|
+
return undefined;
|
|
249
|
+
}
|
|
250
|
+
if (!Array.isArray(raw.evidence))
|
|
251
|
+
return undefined;
|
|
252
|
+
const evidence = [];
|
|
253
|
+
for (const pointer of raw.evidence) {
|
|
254
|
+
if (!isPlainObject(pointer))
|
|
255
|
+
return undefined;
|
|
256
|
+
if (!isSafeIndex(pointer.sourceIndex) || !isSafeIndex(pointer.passageIndex)) {
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
if (pointer.sourceIndex >= sourceCount ||
|
|
260
|
+
pointer.passageIndex >= passageCountAt(pointer.sourceIndex)) {
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
evidence.push({ sourceIndex: pointer.sourceIndex, passageIndex: pointer.passageIndex });
|
|
264
|
+
}
|
|
265
|
+
claims.push({
|
|
266
|
+
text: raw.text,
|
|
267
|
+
verdict: raw.verdict,
|
|
268
|
+
negationCues: raw.negationCues,
|
|
269
|
+
evidence,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
return { statement: value.statement, claims };
|
|
273
|
+
}
|
|
274
|
+
/** Finite, safe, non-negative integer index (evidence pointer guard). */
|
|
275
|
+
function isSafeIndex(value) {
|
|
276
|
+
return (typeof value === "number" && Number.isSafeInteger(value) && value >= 0);
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=investigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"investigation.js","sourceRoot":"","sources":["../../src/capabilities/investigation.ts"],"names":[],"mappings":"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"}
|