@anysiteio/agent-skills 1.0.1 → 1.3.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.
@@ -0,0 +1,548 @@
1
+ ---
2
+ name: anysite-cli
3
+ description: Operate the anysite command-line tool for web data extraction, batch API processing, multi-source dataset pipelines with scheduling/transforms/exports, database operations, and LLM-powered data analysis. Use when users ask to collect data from LinkedIn, Instagram, Twitter, or any web source via CLI; create or run dataset pipelines; schedule automated collection; batch-process API calls; query collected data with SQL; load data into PostgreSQL or SQLite; analyze data with LLM (summarize, classify, enrich, match, deduplicate); or work with anysite commands. Triggers on anysite CLI usage, data collection, dataset creation, scraping, API batch calls, scheduling, database loading, or LLM analysis tasks.
4
+ ---
5
+
6
+ # Anysite CLI
7
+
8
+ Command-line tool for web data extraction, dataset pipelines, and database operations.
9
+
10
+ ## Agent Planning Workflow
11
+
12
+ **BEFORE planning any data collection task, follow this sequence:**
13
+
14
+ 1. **Discover available endpoints**
15
+ ```bash
16
+ anysite describe --search "<keyword>" # Search by domain (linkedin, company, user, etc.)
17
+ ```
18
+
19
+ 2. **Select endpoints needed for the task** — identify which endpoints will provide the required data
20
+
21
+ 3. **Inspect each selected endpoint**
22
+ ```bash
23
+ anysite describe /api/linkedin/company # View input params and output fields
24
+ ```
25
+
26
+ 4. **Only then plan** — now you know the exact parameters, field names, and data structure to build your config or API calls
27
+
28
+ This prevents errors from wrong endpoint paths, missing required parameters, or incorrect field names in dependencies.
29
+
30
+ ## Best Practices
31
+
32
+ 1. **Use dataset pipelines for multi-step tasks**
33
+ - If a task requires sequential API calls, LLM enrichment, or chained data processing — create a `dataset.yaml` config instead of running multiple ad-hoc commands
34
+ - Dataset pipelines handle dependencies, incremental collection, and error recovery automatically
35
+ - Even for "simple" tasks that grow in scope, a dataset config is easier to maintain
36
+ - Benefits: run history, incremental sync, scheduling, notifications, DB loading
37
+
38
+ 2. **Save data in Parquet format by default** — unless user requests another format or CSV/JSON fits better
39
+
40
+ 3. **Prefer datasets over ad-hoc scripts** — one dataset.yaml replaces dozens of shell commands
41
+
42
+ ## Quick Start Checklist
43
+
44
+ Before any data collection task:
45
+
46
+ ```bash
47
+ # 1. Check CLI is available and see latest changes
48
+ anysite --version
49
+ anysite changelog --last 1 --json # Check what's new in this version
50
+ # If not found: source .venv/bin/activate or pip install anysite-cli
51
+
52
+ # 2. Update schema cache (required for endpoint discovery)
53
+ anysite schema update
54
+
55
+ # 3. Verify API key
56
+ anysite config get api_key
57
+ # If not set: anysite config set api_key sk-xxxxx
58
+ ```
59
+
60
+ After upgrading, run `anysite changelog --since <old_version> --json` to discover new features.
61
+
62
+ ## Endpoint Discovery
63
+
64
+ **ALWAYS discover endpoints before writing API calls or dataset configs:**
65
+
66
+ ```bash
67
+ anysite describe # List all endpoints
68
+ anysite describe --search "company" # Search with dependency context
69
+ anysite describe /api/linkedin/company # Full details: params, output, connections
70
+
71
+ ```
72
+
73
+ Search returns matched endpoints plus upstream providers (who can supply input IDs) and downstream consumers (who can use output IDs). Use this to plan endpoint chains for dataset pipelines.
74
+
75
+ Input params show type, description, examples, and defaults. Array params show item structure:
76
+ ```
77
+ Input parameters:
78
+ * urn string User URN, only fsd_profile urn type is allowed
79
+ example: "urn:li:fsd_profile:ACoAABXy1234"
80
+ count integer Number of posts to return
81
+ default: 20
82
+ companies array[object{type,value}] Company URNs
83
+ example: [{"type": "company", "value": "14064608"}]
84
+ ```
85
+
86
+ ## Prerequisites
87
+
88
+ ```bash
89
+ pip install "anysite-cli[data]" # DuckDB + PyArrow for dataset commands
90
+ pip install "anysite-cli[llm]" # LLM analysis (openai/anthropic)
91
+ pip install "anysite-cli[postgres]" # PostgreSQL adapter
92
+ pip install "anysite-cli[clickhouse]" # ClickHouse adapter
93
+
94
+ anysite config set api_key sk-xxxxx # Configure API key
95
+ anysite schema update # Update schema cache
96
+ anysite llm setup # Interactive setup (human)
97
+ anysite llm setup --provider openai --api-key sk-xxx --no-test # Non-interactive (agent)
98
+ anysite llm setup --provider anthropic --api-key-env ANTHROPIC_API_KEY --no-test
99
+ anysite db add pg --type postgres --host localhost --database mydb --user app --password secret
100
+ # Or via env var: anysite db add pg ... --password-env PGPASS
101
+ anysite db add ch --type clickhouse --host ch.example.com --port 8443 --database analytics --user app --password secret --ssl
102
+ ```
103
+
104
+ ## Authentication
105
+
106
+ ```bash
107
+ anysite auth login # Interactive browser-based OAuth2 (human)
108
+ anysite auth login --force --no-browser # Re-authenticate without confirmation (agent)
109
+ anysite auth status # Check current auth status
110
+ anysite auth status --json # Machine-readable auth status
111
+ anysite auth logout # Interactive logout (human)
112
+ anysite auth logout --force # Logout without confirmation (agent)
113
+ ```
114
+
115
+ ## Single API Call
116
+
117
+ ```bash
118
+ anysite api /api/linkedin/user user=satyanadella
119
+ anysite api /api/linkedin/company company=anthropic --format table
120
+ anysite api /api/linkedin/search/users keywords="CTO" count=50 --format csv --output ctos.csv
121
+ anysite api /api/linkedin/user user=satyanadella --fields "name,headline,urn.value" -q | jq
122
+ ```
123
+
124
+ ### URN/Name Parameter Formats
125
+
126
+ Parameters like `location`, `current_companies`, `industry` accept two formats:
127
+
128
+ ```bash
129
+ # Single name (text search) — resolves to URNs automatically
130
+ location="London"
131
+ current_companies="Microsoft"
132
+
133
+ # Multiple URNs (direct) — use JSON array in single quotes
134
+ 'location=["urn:li:geo:101165590", "urn:li:geo:101282230"]'
135
+ 'current_companies=["urn:li:company:1035", "urn:li:company:1441"]'
136
+ ```
137
+
138
+ **Note:** List of names `["Microsoft", "Google"]` is NOT supported — use either one name OR multiple URNs.
139
+
140
+ ## Batch Processing
141
+
142
+ ```bash
143
+ anysite api /api/linkedin/user --from-file users.txt --input-key user \
144
+ --parallel 5 --rate-limit "10/s" --on-error skip --progress --stats
145
+ ```
146
+
147
+ ## Dataset Pipeline (Multi-Source Collection)
148
+
149
+ For complex data collection with dependencies, LLM enrichment, scheduling — use dataset pipelines.
150
+
151
+ ### Initialize
152
+
153
+ ```bash
154
+ anysite dataset init my-dataset
155
+ # Creates my-dataset/dataset.yaml with template config
156
+ ```
157
+
158
+ ### Six Source Types
159
+
160
+ 1. **Independent** — single API call with static `input`
161
+ 2. **from_file** — batch calls iterating over input file values
162
+ 3. **Dependent** — batch calls using values extracted from a parent source
163
+ 4. **Union (type: union)** — combine records from multiple parent sources into one
164
+ 5. **LLM (type: llm)** — process parent data through LLM without API calls
165
+ 6. **SQL (type: sql)** — query a database connection or dataset Parquet files via DuckDB
166
+
167
+ ### Comprehensive Dataset YAML Reference
168
+
169
+ ```yaml
170
+ name: my-dataset # Dataset name (required)
171
+ description: Optional description # Human-readable description
172
+
173
+ sources:
174
+ # === TYPE 1: Independent source (single API call) ===
175
+ - id: search_results # Unique identifier (required)
176
+ endpoint: /api/linkedin/search/users # API endpoint (required for type: api)
177
+ input: # Static API parameters
178
+ keywords: "software engineer"
179
+ count: 50
180
+ parallel: 1 # Concurrent requests: 1-10 (default: 1)
181
+ rate_limit: "10/s" # Rate limit: "N/s", "N/m", "N/h"
182
+ on_error: stop # Error handling: stop | skip (default: stop)
183
+
184
+ - id: search_extra # Another search (can be combined with union)
185
+ endpoint: /api/linkedin/search/users
186
+ input: { keywords: "data engineer", count: 50 }
187
+
188
+ # === TYPE 2: from_file source (batch from file) ===
189
+ - id: companies
190
+ endpoint: /api/linkedin/company
191
+ from_file: companies.txt # Input file: .txt (line per value), .csv, .jsonl
192
+ file_field: company_slug # CSV column name (for CSV files only)
193
+ input_key: company # API parameter to fill with each value
194
+ parallel: 3
195
+
196
+ # === TYPE 3: Dependent source (values from parent) ===
197
+ - id: employees
198
+ endpoint: /api/linkedin/company/employees
199
+ dependency:
200
+ from_source: companies # Parent source ID (required)
201
+ field: urn.value # Dot-notation path to extract from parent records
202
+ match_by: name # Alternative: fuzzy match instead of exact field
203
+ dedupe: true # Remove duplicate values (default: false)
204
+ input_key: companies # API parameter for extracted values
205
+ input_template: # Transform values before API call
206
+ companies:
207
+ - type: company
208
+ value: "{value}" # {value} = extracted value placeholder
209
+ count: 5
210
+ refresh: auto # Incremental behavior: auto (default) | always | never
211
+ # never = skip if data exists
212
+
213
+ # === Shorthand for dependent sources ===
214
+ # ${source.field} auto-expands to dependency + input_key:
215
+ - id: profiles
216
+ endpoint: /api/linkedin/user
217
+ input:
218
+ user: ${companies.urn.value} # Equivalent to dependency + input_key above
219
+
220
+ # === TYPE 4: Union source (combine multiple sources) ===
221
+ - id: all_search_results
222
+ type: union # Source type: api (default) | union | llm | sql
223
+ sources: [search_results, search_extra] # Parent source IDs to combine (required)
224
+ dedupe_by: urn.value # Optional: field path for deduplication (dot-notation)
225
+ # NOTE: type: union cannot have endpoint, dependency, from_file, input_key, input
226
+ # NOTE: all sources in the list must have the same endpoint (same data structure)
227
+ # Records are annotated with _union_source = parent source ID
228
+
229
+ # === TYPE 5: LLM source (process parent data without API) ===
230
+ - id: employees_analyzed
231
+ type: llm # Source type: api (default) | union | llm | sql
232
+ dependency:
233
+ from_source: employees
234
+ field: name # Required by schema (not used for LLM sources)
235
+ llm: # LLM enrichment steps (required for type: llm)
236
+ - type: classify # Step types: classify | enrich | summarize | generate
237
+ categories: "developer,recruiter,executive" # Comma-separated (omit for auto-detect)
238
+ output_column: role_type # Output column name (default: category)
239
+ fields: [headline] # Record fields to include in LLM prompt
240
+ - type: enrich
241
+ add: # Field specs (required for enrich)
242
+ - "sentiment:positive/negative/neutral" # Enum: value1/value2/value3
243
+ - "language:string" # Types: string | number | integer | boolean
244
+ - "quality_score:1-10" # Range: min-max
245
+ fields: [headline, summary]
246
+ temperature: 0.0 # LLM temperature: 0.0-1.0 (default: 0.0)
247
+ provider: openai # Provider override: openai | anthropic
248
+ model: gpt-4o-mini # Model override
249
+ - type: summarize
250
+ max_length: 50 # Max words (default: 100)
251
+ output_column: bio
252
+ - type: generate
253
+ prompt: "Write pitch for {name}" # Template with {field} placeholders (required)
254
+ output_column: pitch
255
+ temperature: 0.7 # Higher for creative text
256
+ export: # Export destinations (runs after Parquet write)
257
+ - type: file
258
+ path: ./output/{{source}}-{{date}}.csv # Templates: {{date}}, {{source}}, {{dataset}}
259
+ format: csv # Format: json | jsonl | csv
260
+ # NOTE: type: llm cannot have endpoint, from_file, input_key, input
261
+
262
+ # === TYPE 6: SQL source (query a database) ===
263
+ # Mode A: Named connection (query external database)
264
+ - id: billing_users
265
+ type: sql
266
+ connection: billing # Named connection from 'anysite db add'
267
+ query: "SELECT name, email FROM subscriptions WHERE status = 'inactive'"
268
+ # query_file: queries/inactive.sql # Alternative: read SQL from file
269
+ filter: ".email != null" # All base fields work: filter, llm, transform, export, db_load
270
+
271
+ # Mode B: Dataset views (no connection — query Parquet via DuckDB)
272
+ # Each collected source becomes a view by its id (hyphens → underscores)
273
+ - id: enriched_profiles
274
+ type: sql
275
+ query: |
276
+ SELECT u.*, c.description as company_desc
277
+ FROM user_profiles u
278
+ LEFT JOIN company_profiles c ON u._input_value = c._input_value
279
+ # Use for cross-source JOINs within the pipeline — no external DB needed
280
+ # NOTE: type: sql cannot have endpoint, from_file, input_key, input, parallel, rate_limit, on_error
281
+
282
+ # === OPTIONAL BLOCKS (any source type) ===
283
+ # THREE-LEVEL FILTERING:
284
+ # Level 1: source.filter — before LLM + Parquet (saves tokens, drops records entirely)
285
+ # Level 2: transform.filter — before exports only (Parquet keeps all records)
286
+ # Level 3: db_load.filter — before DB loading (Parquet keeps all records)
287
+ # All use same syntax: .field op value, booleans (true/false), and/or
288
+ - id: profiles
289
+ endpoint: /api/linkedin/user
290
+ dependency: { from_source: employees, field: internal_id.value }
291
+ input_key: user
292
+ filter: '.follower_count > 100' # Level 1: early filter (before LLM + Parquet)
293
+ transform: # Level 2: export filter (Parquet keeps all)
294
+ filter: '.location != ""' # Safe expression
295
+ fields: # Field selection with dot-notation aliases
296
+ - name
297
+ - urn.value AS urn_id
298
+ - headline
299
+ add_columns: # Static columns to inject
300
+ batch: "q1-2026"
301
+ export:
302
+ - type: file
303
+ path: ./output/profiles.csv
304
+ format: csv
305
+ - type: webhook
306
+ url: https://example.com/hook
307
+ headers: { X-Token: abc }
308
+ db_load: # Database loading config
309
+ filter: '.active == true' # Level 3: DB filter (only active to DB)
310
+ table: people # Custom table name (default: source ID)
311
+ key: urn.value # Unique key for diff-based incremental sync
312
+ sync: full # Sync mode: full (default) | append (no DELETE)
313
+ fields: # Fields to load (default: all except _input_value)
314
+ - name
315
+ - urn.value AS urn_id
316
+ - headline
317
+ exclude: [_input_value, raw_html] # Fields to skip
318
+
319
+ storage:
320
+ format: parquet # Storage format (only parquet supported)
321
+ path: ./data/ # Storage directory (relative to dataset.yaml)
322
+
323
+ schedule:
324
+ cron: "0 9 * * *" # Cron expression for scheduling
325
+
326
+ notifications:
327
+ on_complete:
328
+ - url: "https://hooks.slack.com/xxx"
329
+ headers: { Authorization: "Bearer token" }
330
+ on_failure:
331
+ - url: "https://alerts.example.com/fail"
332
+ ```
333
+
334
+ ### type: union Source Details
335
+
336
+ The `type: union` source combines records from multiple parent sources:
337
+
338
+ - **Requires**: non-empty `sources` list (parent source IDs)
339
+ - **Optional**: `dedupe_by` field path for removing duplicates (supports dot-notation)
340
+ - **Cannot have**: `endpoint`, `dependency`, `from_file`, `input_key`, `input`
341
+ - **Validation**: all parent sources must have the same endpoint (same data structure)
342
+ - **Use case**: merge multiple search results before a single dependent source processes them
343
+
344
+ ```yaml
345
+ sources:
346
+ - id: search_cto
347
+ endpoint: /api/linkedin/search/users
348
+ input: { keywords: "CTO fintech", count: 50 }
349
+
350
+ - id: search_vp
351
+ endpoint: /api/linkedin/search/users
352
+ input: { keywords: "VP Engineering", count: 50 }
353
+
354
+ # Union combines all search results
355
+ - id: all_candidates
356
+ type: union
357
+ sources: [search_cto, search_vp]
358
+ dedupe_by: urn.value # Remove duplicates by URN
359
+
360
+ # Single dependent source processes all candidates
361
+ - id: profiles
362
+ endpoint: /api/linkedin/user
363
+ dependency:
364
+ from_source: all_candidates
365
+ field: urn.value
366
+ input_key: user
367
+ ```
368
+
369
+ Records from union sources are annotated with `_union_source` (the parent source ID they came from).
370
+
371
+ ### type: llm Source Details
372
+
373
+ The `type: llm` source processes existing parent data without making API calls:
374
+
375
+ - **Requires**: `dependency` (parent source) and non-empty `llm` list
376
+ - **Cannot have**: `endpoint`, `from_file`, `input_key`, `input`
377
+ - **Use case**: Run LLM enrichment on already-collected data, re-analyze with different prompts
378
+
379
+ ```bash
380
+ # Collect only the LLM source (reads parent Parquet, applies LLM steps)
381
+ anysite dataset collect dataset.yaml --source employees_analyzed
382
+ ```
383
+
384
+ ### Validate & Collect Commands
385
+
386
+ ```bash
387
+ anysite dataset validate dataset.yaml # Validate config (catches errors early)
388
+ anysite dataset collect dataset.yaml --dry-run # Preview plan
389
+ anysite dataset collect dataset.yaml # Run collection
390
+ anysite dataset collect dataset.yaml --load-db pg # Collect + auto-load to DB
391
+ anysite dataset collect dataset.yaml --incremental # Skip already-collected inputs
392
+ anysite dataset collect dataset.yaml --source employees # Single source + dependencies
393
+ anysite dataset collect dataset.yaml --no-llm # Skip LLM enrichment steps
394
+ anysite dataset collect dataset.yaml --limit 100 # Pilot run: max 100 inputs per source
395
+ ```
396
+
397
+ ### Incremental Collection (Resume Where You Left Off)
398
+
399
+ For `from_file` and `dependency` sources, anysite tracks collected input values in `metadata.json`. This enables resuming collection without re-fetching existing data.
400
+
401
+ **Workflow:**
402
+ ```bash
403
+ # First run — collects all inputs
404
+ anysite dataset collect dataset.yaml
405
+
406
+ # Later: add new items to input file, run with --incremental
407
+ anysite dataset collect dataset.yaml --incremental
408
+ # → Only new items are collected, existing ones skipped
409
+
410
+ # Force full re-collection
411
+ anysite dataset reset-cursor dataset.yaml
412
+ anysite dataset collect dataset.yaml
413
+ ```
414
+
415
+ **Per-source `refresh` option:**
416
+ ```yaml
417
+ sources:
418
+ - id: profiles
419
+ refresh: auto # (default) respects --incremental
420
+
421
+ - id: posts
422
+ refresh: always # always re-collects, ignores --incremental
423
+ # use for time-sensitive data (feeds, activity)
424
+
425
+ - id: companies
426
+ refresh: never # skip if data exists (any snapshot)
427
+ ```
428
+
429
+ **Reset cursor:**
430
+ ```bash
431
+ anysite dataset reset-cursor dataset.yaml # all sources
432
+ anysite dataset reset-cursor dataset.yaml --source posts # specific source
433
+ ```
434
+
435
+ ### Query with DuckDB
436
+
437
+ ```bash
438
+ anysite dataset query dataset.yaml --sql "SELECT * FROM companies LIMIT 10"
439
+ anysite dataset query dataset.yaml --source profiles --fields "name, urn.value AS id"
440
+ anysite dataset query dataset.yaml --source profiles --exclude "_input_value,_parent_source"
441
+ anysite dataset query dataset.yaml --interactive # SQL shell
442
+ anysite dataset stats dataset.yaml --source companies
443
+ anysite dataset profile dataset.yaml
444
+ ```
445
+
446
+ ### Load into Database
447
+
448
+ ```bash
449
+ anysite dataset load-db dataset.yaml -c pg --drop-existing # Full load
450
+ anysite dataset load-db dataset.yaml -c pg # Incremental sync (when db_load.key set)
451
+ anysite dataset load-db dataset.yaml -c pg --snapshot 2026-01-15
452
+ ```
453
+
454
+ ### Compare Snapshots
455
+
456
+ ```bash
457
+ anysite dataset diff dataset.yaml --source profiles --key urn.value
458
+ anysite dataset diff dataset.yaml --source profiles --key urn.value --from 2026-01-30 --to 2026-02-01
459
+ ```
460
+
461
+ ### Scheduling & History
462
+
463
+ ```bash
464
+ anysite dataset schedule dataset.yaml --incremental --load-db pg # Generate cron entry
465
+ anysite dataset history my-dataset
466
+ anysite dataset logs my-dataset --run 42
467
+ anysite dataset reset-cursor dataset.yaml # Clear incremental state
468
+ ```
469
+
470
+ ## Database Operations
471
+
472
+ ```bash
473
+ # Connection management
474
+ anysite db add pg --type postgres --host localhost --database mydb --user app --password secret
475
+ anysite db add pg --type postgres --host localhost --database mydb --user app --password-env PGPASS
476
+ anysite db add ch --type clickhouse --host ch.example.com --port 8443 --database analytics --user app --password secret --ssl
477
+ anysite db add local --type sqlite --path ./data.db
478
+ anysite db add replica --type postgres --host replica.example.com --read-only
479
+ anysite db list
480
+ anysite db test pg
481
+
482
+ # Data operations
483
+ cat data.jsonl | anysite db insert pg --table users --stdin --auto-create
484
+ anysite db query pg --sql "SELECT * FROM users" --format table
485
+ anysite db query pg --sql "SELECT * FROM users" --format parquet --output users.parquet
486
+ anysite db query pg --sql "SELECT * FROM users" --format csv --output "reports/{{date}}/users.csv"
487
+
488
+ # Pipe API output to database
489
+ anysite api /api/linkedin/user user=satyanadella -q --format jsonl \
490
+ | anysite db insert pg --table profiles --stdin --auto-create
491
+
492
+ # Database discovery (schema introspection, sample data, LLM descriptions)
493
+ anysite db discover mydb # Discover schema
494
+ anysite db discover mydb --with-llm # Add LLM table/column descriptions
495
+ anysite db discover mydb --tables users,posts # Filter tables
496
+ anysite db discover mydb --exclude-tables _migrations
497
+
498
+ # View saved catalogs
499
+ anysite db catalog # List all catalogs
500
+ anysite db catalog mydb # Show full catalog
501
+ anysite db catalog mydb --table users # Show specific table
502
+ anysite db catalog mydb --json # JSON output for agents
503
+ ```
504
+
505
+ Credentials: `--password` saves directly in `~/.anysite/connections.yaml`, `--password-env` references an env var. Direct value takes priority. LLM API keys follow the same pattern via `anysite llm setup`.
506
+
507
+ Supported databases: SQLite, PostgreSQL, ClickHouse. ClickHouse uses `clickhouse-connect` driver (HTTP protocol, port 8123 default, 8443 for HTTPS/SSL).
508
+
509
+ ## LLM Analysis Commands
510
+
511
+ Analyze collected dataset records using LLM. Requires `anysite llm setup` first.
512
+
513
+ Non-interactive setup (for agents):
514
+ ```bash
515
+ anysite llm setup --provider openai --api-key <key> --no-test
516
+ anysite llm setup --provider anthropic --api-key-env ANTHROPIC_API_KEY --model claude-sonnet-4-5-20250514 --no-test
517
+ ```
518
+
519
+ ```bash
520
+ anysite llm summarize dataset.yaml --source profiles --fields "name,headline" --format table
521
+ anysite llm classify dataset.yaml --source posts --categories "positive,negative,neutral"
522
+ anysite llm enrich dataset.yaml --source profiles \
523
+ --add "seniority:junior/mid/senior" --add "is_technical:boolean"
524
+ anysite llm generate dataset.yaml --source profiles \
525
+ --prompt "Write intro for {name} who works as {headline}" --temperature 0.7
526
+ anysite llm match dataset.yaml --source-a profiles --source-b companies --top-k 3
527
+ anysite llm deduplicate dataset.yaml --source profiles --key name --threshold 0.8
528
+ anysite llm cache-stats
529
+ anysite llm cache-clear
530
+ ```
531
+
532
+
533
+ Use `anysite describe --search <keyword>` for more endpoints.
534
+
535
+ ## Key Patterns
536
+
537
+ - **Output formats**: `--format json|jsonl|csv|table|parquet` (parquet requires `--output`)
538
+ - **Array params**: `keywords=a,b,c` auto-wraps as `["a","b","c"]`
539
+ - **Field selection**: `--fields "name,headline,urn.value"` (dot-notation for nested)
540
+ - **Error handling**: `--on-error stop|skip|retry`
541
+ - **Config priority**: CLI args > ENV vars > `~/.anysite/config.yaml` > defaults
542
+
543
+ ## References
544
+
545
+ For detailed option tables and advanced configuration:
546
+ - [api-reference.md](references/api-reference.md) — all CLI options
547
+ - [llm-reference.md](references/llm-reference.md) — LLM provider config, cache, prompts
548
+ - [dataset-guide.md](references/dataset-guide.md) — full YAML schema, advanced features