3 Commits

Author SHA1 Message Date
London Dávila d58743b5eb Doctor skill: track schema_version 3, quote the gh issue title, list ~/.grok (#262)
doctor still described `schema_version` 1 and 2 + bailed above 2, but
CLI emitted 3 since 0.22.0 and skill pins `@tiny-fish/cli@latest`. as
shipped it degraded to `--pretty` on every run. The feedback skill also
passed an unquoted, user-derived title to `gh issue create`. three fixes
landed in tinyfish-web-agent-integrations#29; this keeps the two copies
of the plugin textually identical

- `doctor`: schema 3 — `cli_version`, `ok_harnesses`/`ok_cli`,
`checks[].scope`, `repairs[].action`, and the exit code coming from the
harness scope alone, so `ok_cli: false` beside exit `0` is a real state.
Drops the `registered, API key present but unverified` string the CLI no
longer emits; `--fix` examples run through `npx` like step 1.
- `feedback`: `--title "$title" --body-file "$body_file"`, injection
warning widened to the title, and `eval` / constructed command strings
prohibited.
- `plugins/tinyfish/README.md`: adds `~/.grok` to the config dirs doctor
reads, per the CLI's `CONFIG_DIRS`. The rest of that list matches.
- 1.2.3 → 1.2.4 in `plugin.json` and the marketplace entry —
`validate-skills.mjs` fails if they diverge

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 15:45:11 -06:00
London Dávila 074962c11a TinyFish setup + skills: doctor/feedback skills, generator, CI validation, INSTALL.md (#252)
Ships plugin **v1.2.2** to the Claude Code marketplace. `main` serves
v1.1.0, which has no doctor/feedback skills at all — the first coworker
install got the stale version because the marketplace serves the default
branch.

## What changed since the original review

The CLI now ships `tinyfish doctor` — structured JSON, exit codes,
`--fix`. The skill used to re-implement those checks by hand; it now
runs the CLI for them and keeps only the job the CLI structurally cannot
do.

| | |
|---|---|
| Was | 4 hand-rolled checks + repair table + report allowlist |
| Now | run `doctor`, read `checks[]`/`repairs[]`, then prove harness
reach with a real MCP call |

`provesHarnessReach` requires `authMode === "api-key"`, so it is **false
for every OAuth harness** — the CLI cannot borrow the harness's token.
Closing that gap is the whole skill.

## Contents

| Path | |
|---|---|
| `skills-src/` | single source for doctor + feedback |
| `scripts/generate-harness-skills.mjs` | per-target substitution;
targets opt in per file |
| `plugins/tinyfish/skills/{doctor,feedback}/` | Claude Code variant
(`/tinyfish:doctor`) |
| `skills/tinyfish-doctor/` | generic variant — `npx skills add
tinyfish-io/tinyfish-cookbook --skill tinyfish-doctor` |
| `.github/workflows/validate-skills.yml`, `scripts/validate-skills.mjs`
| frontmatter validity (≤1024-char descriptions — Codex hard limit),
source↔generated sync, marketplace.json path resolution (#241 regression
guard) |
| `INSTALL.md` | CLI-first verify/repair |

Two non-obvious constraints the generator now encodes:

- the `skills` CLI matches `--skill` on **frontmatter name only**, so
the generic variant must be named `tinyfish-doctor` — and output dirs no
longer derive from the source name
- targets are opt-in per file, so Claude-specific `feedback` cannot leak
into the repo root as a generic `skills/feedback/`

`dist/harness-skills/` is deleted — nothing consumed it. `connect`
installs `use-tinyfish` from the repo root via the skills CLI, and the
CLI tarball ships no skill files.

## Verified end to end

Two live tests against the real endpoint, in opposite directions.
Neither conclusion is reachable from the CLI's output alone:

| Scenario | CLI alone says | Truth | Skill says |
|---|---|---|---|
| Healthy harness, dead CLI env key | exit 1, "fix your key" | harness
fine | harness fine ✓ |
| Stale key header on the registration | `registration: PASS` |
registration dead (401 on the wire) | broken ✓ |

The second test also surfaced a defect, fixed in a3ca8c3: several
TinyFish servers can be registered against the same endpoint at once
(plugin, CLI-written entry, account-level connector), and a healthy
sibling answering the test call was being read as proof that the
*flagged* registration works. Step 2 now counts servers first and names
which one answered.

## Upstream CLI issues found (tracked separately, not fixed here)

- registration detection reports key **presence, not validity** — a
stale key header passes as `registration: PASS` while every call 401s,
and the only repair offered (`auth login`) does not touch it
- `claude mcp get tinyfish` does not resolve `plugin:tinyfish:tinyfish`,
so `auth_mode` is permanently `unknown` for plugin installs
- doctor inspects only the server named `tinyfish` and cannot see
siblings

The design spec was removed from the repo — it was branch-scoped and
described this location as "a temporary home".

Footgun: none of this touches the CLI — the `connect --all` work is the
separate ux-labs stack (#4053–#4055).

## Review fixes (0049be5)

Three of these are things an agent following the skill would get wrong;
the `gh issue create --body` one executes user-controlled text.

| Fix | |
|---|---|
| `feedback` files via `--body-file` | the body carries free-form user
text + doctor JSON verbatim, so backticks or `$(…)` were evaluated by
the filing shell; URL fallback now says to percent-encode |
| generic `doctor`: `harnesses[]` shape | one entry per harness doctor
*knows*, not per detected one — `harness-detect.js` maps
`ALL_HARNESSES`, so an uninstalled harness returns `detected: false`,
`registered: "no"`. Old wording read as five broken registrations |
| `unattended_safe: false` is the common case | `connect <harness>` is
unsafe for every harness except Cursor, and Cursor only while the CLI
credential resolves. Read the field, don't infer from the command |
| read `schema_version` (`1`) first | the command pins `@latest`, so a
newer CLI can hand the skill a shape it doesn't know |
| `validate-skills` refuses a dirty tree | it regenerates into
`plugins/` and `skills/`; validating locally silently overwrote
uncommitted edits |
| `validate-skills` covers all of `skills/` | every skill ships through
the same `skills` CLI and faces the same 1024-char Codex limit. Surfaced
one real violation — `oss-bounty-finder` at 1127 chars, trimmed to 953 |

Plugin bumped 1.2.1 → 1.2.2: the marketplace cache is version-keyed, so
skill edits need one.


🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Zachary Lyon <zachary@lyonfamily.org>
2026-08-17 12:59:50 -06:00
Pranav Janakiraman 4d0588f8b9 Add Raycast TinyFish Search script (#212)
## Summary

Adds a new `scripts/` section to the cookbook with a Raycast Script
Command for TinyFish Search.

The script lets users search the web from Raycast using the TinyFish CLI
and returns formatted result URLs, titles, site names, and snippets.

## What's included

- `scripts/README.md` as an index for small copyable scripts
- `scripts/raycast-tinyfish-search/tinyfish-search.sh` Raycast Script
Command
- `scripts/raycast-tinyfish-search/README.md` with setup and usage
instructions
- Root `README.md` link to the new scripts section

## Setup flow for users

1. Install and authenticate the TinyFish CLI:
   ```bash
   npm install -g @tiny-fish/cli
   tinyfish auth login
   ```
2. Copy `tinyfish-search.sh` into the Raycast Script Commands folder.
3. Run `chmod +x tinyfish-search.sh`.
4. Open Raycast, run **TinyFish Search**, and type any query.

## Validation

- Ran `bash -n scripts/raycast-tinyfish-search/tinyfish-search.sh`
- Ran the script locally with `TinyFish AI` and confirmed formatted
search results are returned
- Ran `python3 -m json.tool .tags.json`
- Ran `git diff --check`
2026-05-18 10:00:59 -07:00