surf-skill 2.1.1 → 4.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,228 @@
1
1
  # Changelog
2
2
 
3
+ ## v4.0.0 — rename `surf-skill` skill → `surf-search-skill` (consistent suffix), audit cleanup
4
+
5
+ ### Why a major bump
6
+
7
+ In v3.0.0/v3.0.1 (GitHub-only experiments), we shipped a 2-skill bundle
8
+ named `surf-skill` (search) + `surf-plan-skill` (planning). That naming
9
+ was asymmetric — the search skill was missing the `-skill` suffix while
10
+ the planning skill had it. v4.0.0 makes both consistent:
11
+
12
+ - **Skill name `surf-skill` → `surf-search-skill`** (frontmatter, harness
13
+ symlinks, all docs).
14
+ - **Bin `surf-skill` → `surf-search-skill`** (renamed; old bin removed —
15
+ scripts that called `surf-skill ...` need to update).
16
+
17
+ The **npm package name stays `surf-skill`** (it's the bundle name; the
18
+ two skills + 3 bins live inside it). So `npm i -g surf-skill` continues
19
+ to install the package, just exposing different binaries inside.
20
+
21
+ ### Breaking changes for v2.x users
22
+
23
+ - Scripts that ran `surf-skill <subcommand>` must now run
24
+ `surf-search-skill <subcommand>`. Example:
25
+ ```bash
26
+ # before (v2.x)
27
+ surf-skill search "claude api"
28
+
29
+ # after (v4.0.0)
30
+ surf-search-skill search "claude api"
31
+ # OR use the wrapper (NEW in v3+):
32
+ surf search # interactive setup
33
+ ```
34
+ - The harness symlink `~/.claude/skills/surf-skill` is now
35
+ `~/.claude/skills/surf-search-skill`. Postinstall removes the old
36
+ symlink (it's in `LEGACY_NAMES` cleanup) and creates the new one.
37
+ - Agent prompts that referenced "surf-skill" by name should now say
38
+ "surf-search-skill" — this is mainly docs/instructions, since the
39
+ agent discovers skills by what's in `~/.claude/skills/`.
40
+
41
+ ### What's new vs v3.0.1
42
+
43
+ - All `surf-skill` references in skill names, CLI commands, banners,
44
+ HELP text, error messages, postinstall output, and docs updated to
45
+ `surf-search-skill`. npm package name + URLs + library imports remain
46
+ `surf-skill` (correct — that's the npm distribution unit).
47
+ - `harness-install.mjs::SKILLS` array now lists `surf-search-skill` as
48
+ the search skill (was `surf-skill`).
49
+ - `harness-install.mjs::LEGACY_NAMES` adds `surf-skill` and `surf-plan`
50
+ so upgrades from v2/v3 cleanly remove old symlinks before creating new
51
+ ones.
52
+ - `references/plan-workflow.md`, `src/plan/plan-file.mjs`,
53
+ `src/lib/project-config.mjs`, `src/lib/format.mjs`, `src/lib/keys-cmd.mjs`
54
+ all updated.
55
+
56
+ ### Audit fixes (bugs caught while renaming)
57
+
58
+ - v3.0.0/v3.0.1 had several stale `surf-plan` (bare, no `-skill` suffix)
59
+ refs in `src/plan/plan-file.mjs:154` (docstring) and
60
+ `references/plan-workflow.md` (section headers) — leftover from the
61
+ standalone v1.0.0 migration. Fixed.
62
+ - The v3.0.0 `src/install/postinstall.mjs` banner hardcoded `3.0.0` —
63
+ now reads correctly (and updated to 4.0.0).
64
+ - The v3.0.0 `bin/surf-plan-skill.mjs` HELP title was `surf-plan-skill-skill`
65
+ from an over-aggressive sed during the v2→v3 migration. Fixed.
66
+ - `package.json` `test:syntax` script referenced the old `bin/surf-skill.mjs`
67
+ filename — updated to `bin/surf-search-skill.mjs` so CI/local tests pass.
68
+
69
+ ### Files changed (high-level)
70
+
71
+ - Renamed: `bin/surf-skill.mjs` → `bin/surf-search-skill.mjs` (git rename).
72
+ - Edited: `SKILL.md`, `skills/surf-plan-skill/SKILL.md`, all bins,
73
+ `package.json`, `README.md`, `CHANGELOG.md`,
74
+ `src/lib/{harness-install,check-surf-skill,keys-cmd,project-config,format}.mjs`,
75
+ `src/install/postinstall.mjs`, `src/index.mjs`, `src/plan/plan-file.mjs`,
76
+ `references/plan-workflow.md`.
77
+ - Internal `VERSION` constants in all bins, `dispatch.mjs`, and
78
+ `validators/index.mjs` bumped to `4.0.0`.
79
+
80
+ ### What didn't change
81
+
82
+ - npm package name: still `surf-skill`.
83
+ - npm package install: still `npm i -g surf-skill`.
84
+ - Library imports: still `import { search } from 'surf-skill'`.
85
+ - Provider adapter behavior, dispatch fallback, validator logic,
86
+ keys.json schema, plan-file format, harness directories — all
87
+ unchanged from v3.0.1.
88
+ - The `surf-plan-skill` skill name stays as is (was already correct).
89
+
90
+ ### Migration
91
+
92
+ ```bash
93
+ # Upgrade:
94
+ npm i -g surf-skill@latest
95
+
96
+ # Verify all 3 bins:
97
+ surf --version # 4.0.0
98
+ surf-search-skill --version # 4.0.0
99
+ surf-plan-skill --version # 4.0.0
100
+
101
+ # Check the new symlinks (and old ones removed):
102
+ ls ~/.claude/skills/ # surf-search-skill + surf-plan-skill (NO surf-skill)
103
+ ls ~/.agents/skills/ # same
104
+ ```
105
+
106
+ Find/replace in your scripts: `surf-skill ` → `surf-search-skill ` (mind
107
+ the trailing space so you don't break `npm i -g surf-skill`).
108
+
109
+ ---
110
+
111
+ ## v3.0.1 — package.json fix for the v3.0.0 bundle
112
+
113
+ v3.0.0 shipped to GitHub with a partial `package.json` edit: the new
114
+ `surf` and `surf-plan-skill` `bin` entries were missing, the `version`
115
+ field wasn't bumped (still `2.1.1`), and the description didn't mention
116
+ the planning skill. The skill code itself was fine, but `npm i -g
117
+ surf-skill@3.0.0` would only install the `surf-skill` binary, hiding the
118
+ new `surf` wrapper and `surf-plan-skill` CLI. v3.0.1 corrects the
119
+ manifest so the bundle actually exposes all 3 bins on install.
120
+
121
+ What changed in v3.0.1 vs v3.0.0:
122
+
123
+ - `package.json::version` 2.1.1 → 3.0.1
124
+ - `package.json::bin` includes all 3: `surf`, `surf-skill`, `surf-plan-skill`
125
+ - `package.json::description` updated to describe the bundle (2 skills)
126
+ - `package.json::exports` adds `./plan` and `./validators` subpath exports
127
+ - `SKILL.md::metadata.version` 2.1.1 → 3.0.1
128
+ - All internal `VERSION` constants bumped to 3.0.1
129
+
130
+ No code-behavior changes vs v3.0.0; release v3.0.0 is superseded.
131
+
132
+ If you installed v3.0.0 by hand from GitHub: upgrade with
133
+ `npm i -g surf-skill@latest` and `surf doctor` to confirm all 3 bins
134
+ are present.
135
+
136
+ ---
137
+
138
+ ## v3.0.0 — multi-skill bundle: surf-skill + surf-plan-skill + `surf` wrapper with live key validation
139
+
140
+ ### What's new
141
+
142
+ This release reshapes the package from one skill into **two skills + a
143
+ top-level setup wrapper**, all installed by `npm i -g surf-skill`.
144
+
145
+ **New skill: `surf-plan-skill`** — research-driven execution planning
146
+ that follows a strict 6-phase workflow (preflight → project discovery →
147
+ baseline web research → conversation → clarifying questions each backed
148
+ by search → synthesis search → write Markdown plan with `[^N]` cited
149
+ footnotes). Triggers on "make a plan", "design X", "architect Y", etc.
150
+ Plans land in `~/.claude/plans/` (or `./plans/` if it exists).
151
+
152
+ **New CLI: `surf`** — the friendliest entry point. Interactive setup
153
+ wizard that:
154
+ - Detects both skills in all 4 harness skill dirs.
155
+ - Lists configured keys per provider (masked).
156
+ - **Validates every key against its provider's real API before saving**
157
+ (1-credit cost, 1-3s per key). Invalid keys are dropped with a clear
158
+ error; valid keys are saved.
159
+ - Re-validates existing keys on demand.
160
+
161
+ **Validation is now mandatory at every key-add path**:
162
+ - `surf` interactive add: live-validates before saving.
163
+ - `surf-skill setup`: validates each freshly-collected key in the wizard
164
+ batch; drops invalid; reports a summary.
165
+ - `surf-skill keys add --provider X <key>`: validates before saving.
166
+ Opt out with `--skip-validate` (for known-good or offline scenarios).
167
+
168
+ ### Bins shipped (3)
169
+
170
+ - `surf` — interactive setup + key validation (new)
171
+ - `surf-skill` — search engine (unchanged surface; 3.0.0 internal)
172
+ - `surf-plan-skill` — planning skill CLI (list/show/new/doctor)
173
+
174
+ ### Package layout
175
+
176
+ ```
177
+ surf-skill/
178
+ ├── bin/{surf,surf-skill,surf-plan-skill}.mjs
179
+ ├── SKILL.md # surf-skill skill (root)
180
+ ├── skills/surf-plan-skill/SKILL.md # surf-plan-skill (planning)
181
+ ├── src/
182
+ │ ├── index.mjs # library entry (search + extract + ...)
183
+ │ ├── plan/ # plan-file, plans-dir, slug
184
+ │ ├── validators/ # per-provider key validators
185
+ │ ├── lib/ # adapters, dispatch, state, cost, ...
186
+ │ └── install/ # postinstall + preuninstall
187
+ └── references/
188
+ ```
189
+
190
+ ### Postinstall (cross-OS)
191
+
192
+ Each of the 4 supported harness skill dirs now gets **2 symlinks**:
193
+
194
+ - `<harness>/surf-skill` → package root (search skill)
195
+ - `<harness>/surf-plan-skill` → `skills/surf-plan-skill/` (planning skill)
196
+
197
+ Harnesses: `~/.agents/skills`, `~/.claude/skills`, `~/.codex/skills`,
198
+ `~/.pi/agent/skills`. Symlink on POSIX + Windows-with-Developer-Mode;
199
+ falls back to recursive copy on Windows without it.
200
+
201
+ Existing v2.x users: the surf-skill symlink still points at package root
202
+ (unchanged); the new surf-plan-skill symlink is added.
203
+
204
+ ### Migration from v2.x
205
+
206
+ ```bash
207
+ npm i -g surf-skill # picks up v3.0.0
208
+ surf doctor # confirm both skills + keys
209
+ surf # interactive — add more keys if needed
210
+ ```
211
+
212
+ Your existing `~/.config/surf/keys.json` is preserved. CLI commands
213
+ that worked in v2.x still work in v3.0.0 (no breaking flag changes;
214
+ only additive behavior: validation defaults on for `keys add`, opt out
215
+ with `--skip-validate` if needed).
216
+
217
+ ### Migration from the standalone `surf-plan` v1.0.0 (now retired)
218
+
219
+ The standalone `frederico-kluser/surf-plan` repo and the unpublished
220
+ `surf-plan` npm name are retired. Use `npm i -g surf-skill` — it bundles
221
+ the planning skill as `surf-plan-skill`. The SKILL.md frontmatter name
222
+ changed from `surf-plan` → `surf-plan-skill`.
223
+
224
+ ---
225
+
3
226
  ## v2.1.1 — Robust key rotation: Brave 422 now burns the key
4
227
 
5
228
  ### Bug
package/README.md CHANGED
@@ -18,26 +18,54 @@
18
18
 
19
19
  ---
20
20
 
21
- **One command. Three providers. Zero MCP.** Install with `npm i -g surf-skill`.
22
- The agent calling this skill **never picks the provider** — `surf-skill` does.
21
+ **Two skills. Three providers. One install.** `npm i -g surf-skill` now bundles
22
+ both **`surf-search-skill`** (multi-provider web search) and **`surf-plan-skill`**
23
+ (research-driven execution planning), plus a friendly `surf` setup wrapper with
24
+ live key validation.
23
25
 
24
26
  ```
25
- search ─┐ ┌──▶ Tavily (search, extract, crawl, map, research)
26
- extract ┤
27
- crawl ──┼──▶ surf ───┼──▶ Parallel (search, extract, research async)
28
- map ───┤ │
29
- research┘ └──▶ Brave (search only — own index)
27
+ ┌──▶ Tavily (search, extract, crawl, map, research)
28
+ search ─┐
29
+ extract ─┤ │
30
+ crawl ──┼──▶ surf-search-skill ──▶ Parallel (search, extract, research async)
31
+ map ──┤ │
32
+ research ─┘ │
33
+ └──▶ Brave (search only — own index)
34
+
35
+ plan / design ──▶ surf-plan-skill ──┐
36
+ architect / spec ──────────────────►│ (calls surf-search-skill for web research)
37
+ └──▶ Markdown plan file with [^N] citations
30
38
  ```
31
39
 
32
40
  | | |
33
41
  |---|---|
34
- | **Status** | v2.1.0 (npm) |
42
+ | **Status** | v4.0.0 (npm) |
35
43
  | **Install** | `npm i -g surf-skill` (Linux · macOS · Windows) |
44
+ | **Skills shipped** | `surf-search-skill` (search) + `surf-plan-skill` (planning) |
45
+ | **Bins shipped** | `surf` (interactive setup + validation), `surf-search-skill`, `surf-plan-skill` |
36
46
  | **Runtime** | Node ≥ 18. Zero npm deps. |
37
47
  | **Storage** | `~/.config/surf/keys.json` (chmod 600). Never read from env at runtime by the CLI. |
38
48
  | **Supported agents** | Claude Code · GitHub Copilot CLI · Pi Coding Agent · OpenCode · Codex CLI |
39
49
  | **Spec** | [Anthropic Agent Skills](https://docs.claude.com/en/docs/agents-and-tools/agent-skills) |
40
50
 
51
+ ## Quickstart (60 seconds)
52
+
53
+ ```bash
54
+ npm i -g surf-skill # installs BOTH skills + 3 bins (cross-OS)
55
+ surf # interactive: add keys with LIVE validation
56
+ # ✓ valid (tavily, HTTP 200, 1.2s, 1 credit)
57
+ # ✗ invalid (auth, HTTP 401) — NOT saved
58
+
59
+ # Use directly:
60
+ surf-search-skill search "claude 4.7 release notes" --max 3
61
+ surf-search-skill search "X" --provider brave --mode fast
62
+
63
+ # Or ask an AI agent:
64
+ > make a plan for adding rate limiting to my Express API
65
+ # → surf-plan-skill kicks in: reads project, runs surf-search-skill searches,
66
+ # asks 3-5 researched questions, writes ~/.claude/plans/<slug>-<ts>.md
67
+ ```
68
+
41
69
  ---
42
70
 
43
71
  ## Quickstart (30 seconds)
@@ -50,17 +78,17 @@ npm i -g surf-skill
50
78
  # initializes ~/.config/surf/keys.json, and prints a hint.
51
79
  # On first run, an interactive wizard auto-launches in TTY:
52
80
 
53
- surf-skill search "your query"
81
+ surf-search-skill search "your query"
54
82
  # → "No keys configured. Launching setup wizard…"
55
83
  # → prompts for Tavily key #1, #2, …, Parallel key #1, #2, …
56
84
  # → resumes your command
57
85
 
58
- # In each project where you'll use surf-skill (REQUIRED for GH Copilot CLI):
86
+ # In each project where you'll use surf-search-skill (REQUIRED for GH Copilot CLI):
59
87
  cd path/to/your-project
60
- surf-skill project-config
88
+ surf-search-skill project-config
61
89
  ```
62
90
 
63
- You can also run `surf-skill setup` manually anytime to add more keys.
91
+ You can also run `surf-search-skill setup` manually anytime to add more keys.
64
92
 
65
93
  ### Use as a Node library
66
94
 
@@ -101,7 +129,7 @@ to spread cost across accounts. Today every agent skill is **1-to-1** with
101
129
  a provider — when a key dies or a provider has an outage, your agent loop
102
130
  breaks.
103
131
 
104
- `surf-skill` is a connector:
132
+ `surf-search-skill` is a connector:
105
133
 
106
134
  - **Multi-key per provider.** Add as many keys as you want; rotation is
107
135
  automatic on `401`/`403`/`402` (auth, insufficient credits) or persistent
@@ -134,9 +162,9 @@ npm i -g surf-skill
134
162
  # "BASH_MAX_TIMEOUT_MS": "600000" } }
135
163
  ```
136
164
 
137
- The skill becomes available at `~/.claude/skills/surf-skill/`. In a Claude
165
+ The skill becomes available at `~/.claude/skills/surf-search-skill/`. In a Claude
138
166
  Code session, just ask: "search the web for X" — the agent will invoke
139
- `surf-skill` via Bash. For commands that may exceed 5 min, the agent can
167
+ `surf-search-skill` via Bash. For commands that may exceed 5 min, the agent can
140
168
  pass `timeout: 600000` on the Bash call (10 min hard cap), or set
141
169
  `run_in_background: true` and monitor via `/tasks`.
142
170
 
@@ -146,28 +174,28 @@ pass `timeout: 600000` on the Bash call (10 min hard cap), or set
146
174
 
147
175
  ```bash
148
176
  npm i -g surf-skill
149
- # Symlink created at ~/.copilot/skills/ (via ~/.agents/skills/surf-skill).
177
+ # Symlink created at ~/.copilot/skills/ (via ~/.agents/skills/surf-search-skill).
150
178
  ```
151
179
 
152
180
  **Per-project**, run inside the project root:
153
181
 
154
182
  ```bash
155
- surf-skill project-config
183
+ surf-search-skill project-config
156
184
  # writes .github/copilot-hooks.json with { "timeoutSec": 300 }
157
185
  # detects .github/ automatically; use --harness copilot --yes to force
158
186
  ```
159
187
 
160
- Without this, any `surf-skill` command other than `--help`, `--version`,
188
+ Without this, any `surf-search-skill` command other than `--help`, `--version`,
161
189
  `keys list/add`, or `search --max 1` will time out. With it, you can use
162
190
  the full command set up to ~5 min per call.
163
191
 
164
192
  For longer operations, use Copilot CLI's async pattern: `/delegate` the
165
- `surf-skill research-start ...` call, then poll with `surf-skill
193
+ `surf-search-skill research-start ...` call, then poll with `surf-search-skill
166
194
  research-poll <id>` from a regular session.
167
195
 
168
- If surf-skill detects the agent will likely kill the call before it can
196
+ If surf-search-skill detects the agent will likely kill the call before it can
169
197
  finish, it now aborts early with `LikelyAgentTimeout` and tells the agent
170
- to suggest `surf-skill project-config` to the user — instead of dying
198
+ to suggest `surf-search-skill project-config` to the user — instead of dying
171
199
  silently to SIGTERM.
172
200
 
173
201
  ### Pi Coding Agent
@@ -179,14 +207,14 @@ npm i -g surf-skill
179
207
  # "PI_BASH_MAX_TIMEOUT_SECONDS": "600" } }
180
208
  ```
181
209
 
182
- The skill becomes available at `~/.pi/agent/skills/surf-skill/`. Pi reads
210
+ The skill becomes available at `~/.pi/agent/skills/surf-search-skill/`. Pi reads
183
211
  the timeout from env, so the settings.json above is enough. For
184
212
  long-running work, Pi supports subagents with `--bg` and the `await` tool.
185
213
 
186
214
  ### OpenCode & Codex CLI
187
215
 
188
- Also auto-configured by the installer (`~/.agents/skills/surf-skill/` and
189
- `~/.codex/skills/surf-skill/`). OpenCode gets `mcp_timeout` + `bash.timeout_ms`
216
+ Also auto-configured by the installer (`~/.agents/skills/surf-search-skill/` and
217
+ `~/.codex/skills/surf-search-skill/`). OpenCode gets `mcp_timeout` + `bash.timeout_ms`
190
218
  set to 600 000 ms in `~/.config/opencode/opencode.json`.
191
219
 
192
220
  ---
@@ -202,7 +230,7 @@ set to 600 000 ms in `~/.config/opencode/opencode.json`.
202
230
 
203
231
  If you see timeouts, the order of fixes:
204
232
 
205
- 1. Use `surf-skill research-start` + `research-poll` instead of sync
233
+ 1. Use `surf-search-skill research-start` + `research-poll` instead of sync
206
234
  `research`.
207
235
  2. Reduce `--limit` / `--max` / `--max-depth`.
208
236
  3. Bump the per-harness timeout (see the relevant card above).
@@ -228,7 +256,7 @@ If you see timeouts, the order of fixes:
228
256
  | `cost [--reset]` | Local credit ledger (per-provider) | n/a |
229
257
  | `keys <subcmd>` | `add`, `remove`, `list`, `reset`, `clear` | n/a |
230
258
 
231
- Full reference: `skills/surf-skill/SKILL.md`.
259
+ Full reference: `skills/surf-search-skill/SKILL.md`.
232
260
 
233
261
  Global flags every command accepts:
234
262
 
@@ -250,16 +278,16 @@ Global flags every command accepts:
250
278
  ### Search modes
251
279
 
252
280
  ```bash
253
- surf-skill search "X" --mode fast # 5 results / 1 credit Tavily / minimal latency
254
- surf-skill search "X" --mode normal # 10 results / default everywhere
255
- surf-skill search "X" --mode slow # 20 results / Tavily advanced / deeper signal
281
+ surf-search-skill search "X" --mode fast # 5 results / 1 credit Tavily / minimal latency
282
+ surf-search-skill search "X" --mode normal # 10 results / default everywhere
283
+ surf-search-skill search "X" --mode slow # 20 results / Tavily advanced / deeper signal
256
284
  ```
257
285
 
258
286
  Want to force a specific provider for a given mode?
259
287
 
260
288
  ```bash
261
- surf-skill search "X" --provider brave --mode slow # 20 brave results, no fallback
262
- surf-skill search "X" --provider tavily --mode fast # Tavily fast tier
289
+ surf-search-skill search "X" --provider brave --mode slow # 20 brave results, no fallback
290
+ surf-search-skill search "X" --provider tavily --mode fast # Tavily fast tier
263
291
  ```
264
292
 
265
293
  ---
@@ -270,7 +298,7 @@ When you need to research **multiple angles** of the same topic, batch them
270
298
  in a single call. Each positional arg is an independent query:
271
299
 
272
300
  ```bash
273
- surf-skill search "compare X vs Y" "alternatives to X" "X security issues"
301
+ surf-search-skill search "compare X vs Y" "alternatives to X" "X security issues"
274
302
  ```
275
303
 
276
304
  - Runs sequentially (avoids rate-limit thrashing on a single key).
@@ -335,7 +363,7 @@ call flow:
335
363
  Force a specific provider for debugging:
336
364
 
337
365
  ```bash
338
- surf-skill search "x" --provider parallel
366
+ surf-search-skill search "x" --provider parallel
339
367
  # 'parallel' fails ⇒ command fails (no fallback when --provider is set)
340
368
  ```
341
369
 
@@ -345,14 +373,14 @@ surf-skill search "x" --provider parallel
345
373
 
346
374
  ```bash
347
375
  # 1. Wizard (recommended in a TTY)
348
- surf-skill setup
376
+ surf-search-skill setup
349
377
 
350
378
  # 2. Direct
351
- surf-skill keys add --provider tavily tvly-...
352
- surf-skill keys add --provider parallel <key>
379
+ surf-search-skill keys add --provider tavily tvly-...
380
+ surf-search-skill keys add --provider parallel <key>
353
381
 
354
382
  # 3. Auto-launch in TTY: just run any command without keys
355
- surf-skill search "test"
383
+ surf-search-skill search "test"
356
384
  # → "No keys configured. Launching setup wizard…" → prompts → resumes search
357
385
 
358
386
  # 4. Library mode: env vars / .env / explicit opts (no setup needed)
@@ -362,7 +390,7 @@ TAVILY_API_KEY=tvly-... node -e "import('surf-skill').then(m => m.search('x'))"
362
390
  Inspect what was stored (keys are masked):
363
391
 
364
392
  ```bash
365
- surf-skill keys list
393
+ surf-search-skill keys list
366
394
  # **Surf keys** (config: ~/.config/surf/keys.json)
367
395
  # last_ok_provider: `tavily`
368
396
  # ## tavily (2 keys)
@@ -376,25 +404,25 @@ surf-skill keys list
376
404
 
377
405
  **`❌ Error [NoProviderAvailable]: operation 'X' requires one of [...]`**
378
406
  → The op needs a key for a provider you haven't configured. In a TTY the
379
- error already suggests `surf-skill setup`. Outside TTY, run
380
- `surf-skill keys add --provider <name> <key>`.
407
+ error already suggests `surf-search-skill setup`. Outside TTY, run
408
+ `surf-search-skill keys add --provider <name> <key>`.
381
409
 
382
410
  **`❌ Error [AllProvidersExhausted]: ...`**
383
- → Every key on every eligible provider failed. Check `surf-skill keys list`
411
+ → Every key on every eligible provider failed. Check `surf-search-skill keys list`
384
412
  — if everything is `burned`, you've either rotated keys mid-billing-cycle
385
- or the providers are down. Run `surf-skill keys reset` to retry.
413
+ or the providers are down. Run `surf-search-skill keys reset` to retry.
386
414
 
387
415
  **Command timed out in GH Copilot CLI**
388
- → Run `surf-skill project-config` inside the project root. See the
416
+ → Run `surf-search-skill project-config` inside the project root. See the
389
417
  Copilot CLI card above.
390
418
 
391
419
  **`❌ Error [LikelyAgentTimeout]: ...`**
392
- → surf-skill detected the harness will kill the call before it finishes
393
- (typical on Copilot CLI without per-project config). Run `surf-skill
420
+ → surf-search-skill detected the harness will kill the call before it finishes
421
+ (typical on Copilot CLI without per-project config). Run `surf-search-skill
394
422
  project-config` in the project, then retry. Don't retry the same call
395
423
  without fixing the timeout first.
396
424
 
397
- **`❌ Error [KilledBySignal]: surf-skill received SIGTERM/SIGINT`**
425
+ **`❌ Error [KilledBySignal]: surf-search-skill received SIGTERM/SIGINT`**
398
426
  → The harness killed us mid-flight. Same fix as `LikelyAgentTimeout`. The
399
427
  SIGTERM handler exists as a fallback — the self-budget check should fire
400
428
  first when env vars are set.
@@ -404,45 +432,59 @@ first when env vars are set.
404
432
  export `SURF_ALLOW_EXPENSIVE=1` for the session.
405
433
 
406
434
  **`Refusing sync research with model=pro`**
407
- → Use `surf-skill research-start --model pro ...` then `surf-skill
435
+ → Use `surf-search-skill research-start --model pro ...` then `surf-search-skill
408
436
  research-poll <id>`. Sync research is capped at 50 s on purpose.
409
437
 
410
438
  ---
411
439
 
412
- ## Repository layout
440
+ ## Repository layout (v4.0.0)
413
441
 
414
442
  ```text
415
443
  .
416
- ├── package.json
444
+ ├── package.json ← name: surf-skill (npm), version 4.0.0, 3 bins
417
445
  ├── README.md ← you're here
418
446
  ├── CHANGELOG.md
419
447
  ├── LICENSE
420
- └── skills/
421
- └── surf-skill/
422
- ├── SKILL.md
423
- ├── install.sh
424
- ├── bin/
425
- │ └── surf-skill.mjs
426
- ├── lib/
427
- ├── state.mjs ← keys.json I/O, monthly auto-reset
428
- ├── cache.mjs TTL response cache
429
- ├── audit.mjs ← audit + usage JSONL
430
- │ ├── flags.mjs parsing + helpers
431
- │ ├── cost.mjs estimateCredits + guard
432
- │ ├── format.mjs markdown formatters
433
- │ ├── dispatch.mjs ← provider/key fallback + self-budget
434
- │ ├── keys-cmd.mjs ← surf-skill keys add/remove/...
435
- │ ├── setup.mjs interactive onboarding
436
- │ ├── project-config.mjs surf-skill project-config
437
- │ ├── progress.mjs stderr progress events
438
- └── providers/
439
- ├── index.mjs
440
- ├── tavily.mjs
441
- └── parallel.mjs
442
- └── references/
443
- ├── tavily-api.md
444
- ├── parallel-api.md
445
- └── COSTS.md
448
+ ├── logo.png
449
+ ├── SKILL.md ← surf-search-skill (search skill, root of pkg)
450
+ ├── bin/
451
+ ├── surf.mjs ← interactive setup + key validation
452
+ ├── surf-search-skill.mjs ← multi-provider web search CLI
453
+ │ └── surf-plan-skill.mjs ← planning workflow CLI
454
+ ├── skills/
455
+ └── surf-plan-skill/
456
+ └── SKILL.md surf-plan-skill (planning skill)
457
+ ├── src/
458
+ │ ├── index.mjs library entry (search/extract/research/...)
459
+ │ ├── env.mjs key discovery (opts > env > .env > config)
460
+ │ ├── plan/ plan-file, plans-dir, slug (planning lib)
461
+ │ ├── validators/ per-provider key validators (live API)
462
+ │ ├── lib/
463
+ ├── state.mjs ~/.config/surf/keys.json I/O
464
+ ├── cache.mjs TTL response cache
465
+ ├── audit.mjs audit + usage JSONL
466
+ │ ├── flags.mjs, cost.mjs, format.mjs
467
+ ├── dispatch.mjs ← provider/key fallback + self-budget
468
+ ├── keys-cmd.mjs ← surf-search-skill keys add/remove/...
469
+ │ ├── setup.mjs ← interactive onboarding (with validation)
470
+ │ │ ├── project-config.mjs ← surf-search-skill project-config
471
+ │ │ ├── progress.mjs ← stderr progress events
472
+ │ │ ├── check-surf-skill.mjs ← detect companion CLI in PATH
473
+ │ │ ├── harness-install.mjs ← cross-OS symlink install for 2 skills
474
+ │ │ ├── api/ ← library search/extract/crawl/map/research
475
+ │ │ └── providers/
476
+ │ │ ├── index.mjs ← capability map (search + 3 providers)
477
+ │ │ ├── tavily.mjs
478
+ │ │ ├── parallel.mjs
479
+ │ │ └── brave.mjs
480
+ │ └── install/
481
+ │ ├── postinstall.mjs ← cross-OS symlinks + skeleton keys.json
482
+ │ └── preuninstall.mjs ← cleanup our symlinks
483
+ └── references/
484
+ ├── tavily-api.md
485
+ ├── parallel-api.md
486
+ ├── plan-workflow.md ← deeper docs on the 6-phase planning workflow
487
+ └── COSTS.md
446
488
  ```
447
489
 
448
490
  ---
@@ -452,9 +494,9 @@ research-poll <id>`. Sync research is capped at 50 s on purpose.
452
494
  - This repository contains **no real API keys**. The installer only uses
453
495
  placeholders.
454
496
  - Keys are stored exclusively in `~/.config/surf/keys.json` (chmod 600).
455
- `surf-skill` does not read keys from env at runtime.
497
+ `surf-search-skill` does not read keys from env at runtime.
456
498
  - The audit log records only `provider` name and key **index**, never the
457
- key itself. `surf-skill keys list` masks every key (`tvly-…ab12`).
499
+ key itself. `surf-search-skill keys list` masks every key (`tvly-…ab12`).
458
500
  - The skill never executes content returned from the web — it just prints it.
459
501
  - Review any skill before installing. Skills can instruct agents to run
460
502
  commands.