Skip to content

Commit 59bd5f8

Browse files
authored
feat(skills): bundle Agent Skills + gsccli skills install for 4 CLIs (#5)
## Summary - Ship a curated `SKILL.md` (Agent Skills standard) for **Claude Code, Codex, Gemini CLI, Qwen Code** under `agents/`, distributed via the npm tarball. - Add **`gsccli skills install --agent <name> [--scope user|project]`** subcommand that copies the right package to the right per-CLI location. Idempotent SHA-256 content diff; `--dry-run`, `--force`, `--agent all` (auto-detects installed CLIs). - Per-CLI frontmatter exploits each CLI's particularities: Claude `allowed-tools: Bash(gsccli *)` + `argument-hint`; Codex `agents/openai.yaml` UI metadata + `default_prompt`; Gemini `when_to_use` + `user_invocable` + `allowed_tools: [run_shell_command]`; Qwen minimal per-spec. - **No MCP, no plugins, no extensions, no settings-file mutations** — each CLI auto-discovers `~/.<cli>/skills/`; we only write inside. - Surfaces per-CLI caveats in install output: Claude `permissions.deny` precedence, Codex project-trust requirement, Gemini sandbox + browser-auth, Qwen issue #2343 + OAuth deprecation. - Bumps to **v1.2.0**. ## Test plan - [x] `pnpm verify` — lint + type-check + 156/156 tests + build, all green. - [x] `pnpm dev skills install --agent <X> --dry-run` for `claude|codex|gemini|qwen|all` — confirmed correct target paths, file sizes, and per-CLI caveats surface. - [x] `pnpm start skills install --agent claude --dry-run` — confirms post-build production binary resolves `agents/` source via `import.meta.url`. - [x] `npm pack --dry-run` — confirmed all 5 SKILL.md files + Codex `openai.yaml` + `agents/README.md` ship in tarball. - [x] Tests: 40 service-level (target paths, planning, install, idempotency, force, status, uninstall) + 10 CLI-surface (via spawned tsx).
1 parent 818cb48 commit 59bd5f8

20 files changed

Lines changed: 1780 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
_Nothing yet. New entries land here between releases._
1111

12+
## [1.2.0] - 2026-05-02
13+
14+
### Added — AI agent integration
15+
16+
- **Bundled Agent Skills (`SKILL.md`)** for the four major AI coding-agent CLIs:
17+
Claude Code, Codex (with companion `agents/openai.yaml` UI metadata), Gemini
18+
CLI (with `when_to_use` and `allowed_tools: [run_shell_command]`), and Qwen
19+
Code. Identical 600-word body across all four; only the per-CLI frontmatter
20+
differs. Ships under `agents/` in the npm tarball.
21+
- **`gsccli skills install|uninstall|list|status`** subcommand. Copies the
22+
bundled `SKILL.md` package to the right location for the chosen agent and
23+
scope (`--scope user|project`, default `user`). Idempotent (SHA-256 content
24+
diff), supports `--dry-run` and `--force`. `--agent all` auto-detects which
25+
CLIs are installed by probing `~/.claude/`, `~/.codex/`, `~/.gemini/`,
26+
`~/.qwen/`. Refuses `--scope project` unless the CWD has a project marker
27+
(`.git`, `package.json`, `pyproject.toml`, etc.). Surfaces per-CLI caveats
28+
in the install output (Claude `permissions.deny` precedence, Codex
29+
project-trust requirement, Gemini sandbox + browser auth, Qwen issue #2343
30+
+ OAuth deprecation).
31+
32+
### Notes
33+
34+
- No MCP wiring, plugins, extensions, custom slash commands, profile snippets,
35+
or settings-file mutations. Just the right `SKILL.md` in the right place per
36+
CLI. Each CLI auto-discovers its skills directory.
37+
1238
## [1.1.0] - 2026-05-02
1339

1440
First public release on npm. Published as **`@nalyk/gsccli`** (npm rejected the

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,45 @@ gsccli mcp serve
191191
gsccli explore
192192
```
193193

194+
## AI agent integration — make your coding agent a `gsccli` power user
195+
196+
`gsccli` ships with a curated `SKILL.md` (Agent Skills standard) for each of the
197+
four major AI coding-agent CLIs. Install the right one and your agent will know
198+
the killer workflows (period comparison, `--all` streaming, `--cache 1h`,
199+
parallel batch inspection), the silent gotchas (country lowercase, device
200+
uppercase, 25 000-row hard cap, `searchAppearance` solo, `dataState=final`
201+
3-day lag), and the recovery patterns (`auth login` after `invalid_grant`, lower
202+
`--rps` after `quotaExceeded`, `gsccli sites list` to fix `notFound`).
203+
204+
```bash
205+
# Install for one agent (default: user scope, lands in ~/.<cli>/skills/gsccli/)
206+
gsccli skills install --agent claude
207+
gsccli skills install --agent codex
208+
gsccli skills install --agent gemini
209+
gsccli skills install --agent qwen
210+
211+
# Project scope — drops the skill into ./.<cli>/skills/gsccli/ for the current repo
212+
gsccli skills install --agent claude --scope project
213+
214+
# Detect every installed CLI and install for all of them
215+
gsccli skills install --agent all
216+
217+
# Dry-run, idempotency, force overwrite
218+
gsccli skills install --agent all --dry-run
219+
gsccli skills install --agent claude --force
220+
221+
# Inventory + status
222+
gsccli skills list
223+
gsccli skills status
224+
gsccli skills uninstall --agent claude
225+
```
226+
227+
The skill content is identical across the four CLIs; only the frontmatter
228+
differs. Per-CLI caveats (Claude `permissions.deny` precedence, Gemini sandbox
229+
+ browser auth, Codex project-trust requirement, Qwen issue #2343 + OAuth
230+
deprecation) are surfaced in the install output and detailed in
231+
[`agents/README.md`](./agents/README.md).
232+
194233
## Command structure
195234

196235
```
@@ -204,6 +243,7 @@ gsccli
204243
config set|get|list
205244
explore
206245
mcp serve
246+
skills install|uninstall|list|status
207247
```
208248

209249
## Output formats

agents/README.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# gsccli agent skills
2+
3+
This directory ships with the `@nalyk/gsccli` npm package. It contains a single
4+
**Agent Skills** (`SKILL.md`) per supported AI coding-agent CLI. Each skill teaches
5+
the agent to use `gsccli` like a senior power user — knowing the `--all` streaming
6+
trick, the `--cache 1h` cache, the `country=usa` lowercase / `device=MOBILE`
7+
uppercase rule, the `!~=` filter parser order, the period-comparison delta sort,
8+
the 25,000-row hard cap and 50,000 daily property pair cap, the `searchAppearance`
9+
solo constraint, and the rest.
10+
11+
There is no MCP, no plugin, no extension manifest, no custom slash command, no
12+
profile snippet. Just one `SKILL.md` per CLI, optionally with that CLI's idiomatic
13+
companion (Codex's `agents/openai.yaml` UI metadata).
14+
15+
## Install
16+
17+
The recommended path is the bundled subcommand:
18+
19+
```bash
20+
gsccli skills install --agent <claude|codex|gemini|qwen|all>
21+
[--scope <user|project>] # default: user
22+
[--dry-run]
23+
[--force]
24+
```
25+
26+
Manual install also works — copy the per-CLI directory yourself:
27+
28+
| Agent | `--scope user` (default) | `--scope project` |
29+
| ----------- | ------------------------------------------------------- | -------------------------------------------- |
30+
| Claude Code | `cp -r agents/claude-code/gsccli ~/.claude/skills/` | `cp -r agents/claude-code/gsccli .claude/skills/` |
31+
| Codex | `cp -r agents/codex/gsccli ~/.codex/skills/` | `cp -r agents/codex/gsccli .codex/skills/` |
32+
| Gemini | `cp -r agents/gemini/gsccli ~/.gemini/skills/` | `cp -r agents/gemini/gsccli .gemini/skills/` |
33+
| Qwen Code | `cp -r agents/qwen/gsccli ~/.qwen/skills/` | `cp -r agents/qwen/gsccli .qwen/skills/` |
34+
35+
After install, restart the agent or run its skill-reload command.
36+
37+
## Per-CLI caveats
38+
39+
### Claude Code
40+
- The skill uses `allowed-tools: Bash(gsccli *), Read` to pre-approve all `gsccli`
41+
invocations. **Note:** if your global `~/.claude/settings.json` (or
42+
`.claude/settings.json`) contains a `permissions.deny` entry that matches
43+
`Bash(gsccli *)` or `Bash(*)`, deny wins; the skill cannot override it. Permission
44+
precedence: deny > ask > allow.
45+
46+
### Codex
47+
- The skill ships with an `agents/openai.yaml` UI metadata file (display name,
48+
short description, brand color, `default_prompt` for implicit invocation,
49+
dependency declarations).
50+
- For `--scope project`, the project must be marked
51+
`[projects."<absolute-path>"] trust_level = "trusted"` in `~/.codex/config.toml`
52+
for Codex to load `.codex/skills/`. Run `codex` from the project once and it will
53+
prompt you, or add the entry by hand.
54+
- Codex profiles are stable in CLI/IDE 0.125+ but remain experimental in the Codex
55+
app. Codex deprecated custom commands in 0.126 in favor of skills — this skill
56+
package is the right approach.
57+
58+
### Gemini CLI
59+
- The skill uses Gemini's `when_to_use`, `user_invocable`, and
60+
`allowed_tools: [run_shell_command]` frontmatter fields.
61+
- **`gsccli auth login` opens a browser for OAuth.** Gemini's sandbox modes
62+
(Docker / Podman / Seatbelt restrictive) block browser launch. Run
63+
`gsccli auth login` ONCE outside the sandbox to cache tokens at
64+
`~/.gsccli/oauth-tokens.json`; subsequent `gsccli` calls inside Gemini will
65+
use the cached tokens.
66+
67+
### Qwen Code
68+
- Qwen has open issue **#2343** where skills sometimes don't auto-discover. If
69+
the skill isn't picked up, run `/skills` once to load it manually.
70+
- **Qwen OAuth free tier was discontinued 2026-04-15.** You must have a
71+
`DASHSCOPE_API_KEY`, an Alibaba Cloud Coding Plan, or an OpenAI-compatible
72+
endpoint configured. Cached free-tier tokens no longer work.
73+
- Recommended model for tool-use reliability: `qwen3-coder-plus` (production)
74+
or `qwen3-coder-next` (local inference). `qwen3-coder-flash` works but
75+
becomes unreliable with many tools loaded.
76+
77+
## Verification
78+
79+
After install, ask the agent these in order:
80+
81+
1. **"List my Search Console properties."** Expect `gsccli sites list -f json`
82+
(or table) with results.
83+
2. **"Find pages losing clicks compared to last month."** Expect a `gsccli query
84+
compare -d page --vs-start-date ... --sort-by delta_clicks:asc` invocation.
85+
3. **"Show top queries from USA on mobile."** Expect `country=usa` (lowercase)
86+
and `device=MOBILE` (uppercase). Either case wrong → the skill needs sharpening.
87+
4. **"Inspect 5,000 URLs."** Expect `gsccli inspect batch --concurrency 5 --rps 8`
88+
AND a warning about the 2,000/day per-property quota.
89+
90+
Skill content is identical across all four CLIs; only the frontmatter and (for
91+
Codex) the UI metadata file differ.
92+
93+
## Updating
94+
95+
When you upgrade gsccli (`npm i -g @nalyk/gsccli@latest`), re-run the install
96+
command with `--force` to refresh the deployed skills:
97+
98+
```bash
99+
gsccli skills install --agent all --force
100+
```
101+
102+
## Authoring vs deployment
103+
104+
The files under `agents/<cli>/gsccli/` are the **canonical, version-controlled**
105+
skill packages. The install subcommand simply copies them to the target locations.
106+
If you want to customize a skill for your own use, edit the deployed copy at
107+
`~/.<cli>/skills/gsccli/SKILL.md` rather than this directory — your changes here
108+
will be overwritten on the next `gsccli skills install --force`.

agents/claude-code/gsccli/SKILL.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
---
2+
name: gsccli
3+
description: Use when the user wants to query Google Search Console search analytics (clicks/impressions/CTR/position by query/page/country/device), inspect URL indexing status, manage sitemaps, or send Indexing API notifications via the `gsccli` shell command. Triggers on GSC, Search Console, sitemap, indexing API, mobile usability, AMP, rich results, search analytics period comparison, queries losing clicks, top pages, top queries, optimization gold, robots.txt rendering.
4+
allowed-tools: Bash(gsccli *), Read
5+
argument-hint: "[query|sites|sitemaps|inspect|index|config|explore]"
6+
---
7+
8+
# gsccli — Google Search Console + Indexing API CLI
9+
10+
You are a senior-grade user of the `gsccli` shell command (npm: `@nalyk/gsccli`). The
11+
human installed it; you wield it. This skill is the playbook.
12+
13+
## Pre-flight (do these once, then never again)
14+
15+
- `gsccli --version` to confirm install. If missing, tell the user `npm i -g @nalyk/gsccli`.
16+
- `gsccli auth login` once in a real shell (browser OAuth; tokens saved to
17+
`~/.gsccli/oauth-tokens.json` mode 0600). Auth priority: OAuth >
18+
`GOOGLE_APPLICATION_CREDENTIALS` env > config `credentials` key.
19+
- `gsccli config set site <url> --local` to pin the default site for the project.
20+
URL-prefix property needs trailing slash (`https://example.com/`); Domain property
21+
uses `sc-domain:example.com` (no scheme, no path, no slash). They are DIFFERENT
22+
properties even for the same domain.
23+
24+
## The 9 commands at a glance
25+
26+
`auth` (OAuth), `query` (Search Analytics), `sites` (properties), `sitemaps`,
27+
`inspect` (URL Inspection), `index` (Indexing API for job postings + livestream),
28+
`config` (CLI config layers), `explore` (interactive reference), `mcp` (MCP server
29+
mode — out of scope for this skill).
30+
31+
## The 10 killer workflows
32+
33+
```bash
34+
# Top movers, period over period — the optimization-finding workhorse.
35+
gsccli query compare -d query --row-limit 25000 --sort-by delta_clicks:desc | head -20
36+
37+
# Optimization gold — high impressions, low CTR (compose, don't mega-call).
38+
gsccli query run -d query --all --sort-by impressions:desc --max-rows 5000 -f ndjson > a.ndjson
39+
# then re-sort by CTR ascending in the next step.
40+
41+
# Stream all rows OOM-free — only when --all + -f ndjson + no -o (uses generator).
42+
gsccli query run -d page --all -f ndjson > pages.ndjson
43+
44+
# Client-side sort on any of the 4 metrics (GSC API only sorts by clicks desc).
45+
gsccli query top-queries --sort-by ctr:asc
46+
47+
# Cache repeated queries while iterating — never on writes.
48+
gsccli query top-pages --row-limit 1000 --cache 1h
49+
50+
# Parallel batch URL inspection with quota-aware rate pacing.
51+
gsccli inspect batch --urls-file urls.txt --concurrency 5 --rps 8 -f ndjson
52+
53+
# Year-over-year comparison.
54+
gsccli query compare -d page --vs-start-date 393daysAgo --vs-end-date 365daysAgo \
55+
--sort-by delta_position:asc
56+
57+
# Multi-account / multi-agent isolation (separate OAuth tokens, no contention).
58+
GSCCLI_CONFIG_DIR=~/.gsccli-account-x gsccli query top-queries
59+
60+
# Filter chain (AND). Operators: == != ~= !~= =~ !~. Don't hand-edit filter strings.
61+
gsccli query top-pages --filter 'page=~/blog/.*' 'country!=usa' 'device==MOBILE'
62+
63+
# Index publish (job postings + livestream ONLY per Google policy; 200/day default).
64+
gsccli index publish https://example.com/jobs/123 --type URL_UPDATED
65+
gsccli index batch --urls-file jobs.txt --concurrency 3 --rps 3
66+
```
67+
68+
## The 7 silent gotchas (the things that look right and break silently)
69+
70+
1. URL-prefix vs Domain are DIFFERENT properties for the same domain.
71+
2. 4 fixed metrics only: `clicks`, `impressions`, `ctr`, `position`. No custom metrics.
72+
3. Default `--data-state final` excludes the last ~3 days. Use `--data-state all` for fresh.
73+
4. Country = ISO-3166-1 alpha-3 LOWERCASE (`usa`, `gbr`, `fra`). Device = UPPERCASE (`MOBILE`, `DESKTOP`, `TABLET`).
74+
5. 25,000-row hard cap per request. Use `--all` for more; the daily 50,000 page+keyword pair cap self-limits.
75+
6. `searchAppearance` cannot combine with other dimensions.
76+
7. `discover` search type cannot use the `query` dimension.
77+
78+
## Output discipline
79+
80+
stdout = data only; stderr = status. Pipes:
81+
- `-f json | jq '...'` for structured queries
82+
- `-f ndjson > file` for streaming large pulls
83+
- `-f csv` for spreadsheets
84+
- `-f chart` for terminal viz
85+
- `-f table` (default) for human reading
86+
87+
Never pipe `-f table` to `jq` — use `-f json`.
88+
89+
## Validation gates (run BEFORE the operation, not after a failure)
90+
91+
- If site URL is unknown: `gsccli sites list -f json` then pick from `rows[].keys[0]`.
92+
- If freshness matters: pass `--data-state all` explicitly (default `final` excludes ~3 days).
93+
- If row count >25,000 expected: `--all -f ndjson` and stream.
94+
- If batch >2000 URLs: chunk across days; the inspect-batch quota is 2,000/day per property.
95+
96+
## Common errors → recovery (self-heal, don't blind-retry)
97+
98+
- `unauthorized` / `invalid_grant` → tell the user to run `gsccli auth login` once in a shell, then re-run.
99+
- `quotaExceeded` (429) on `query` → built-in retry handles transient; if persistent, propose `--cache 1h` to reduce calls.
100+
- `quotaExceeded` on `inspect batch` → reduce `--rps` to 4, or split URLs across days (2,000/day per property).
101+
- `notFound` on a property → run `gsccli sites list -f json` to surface exact strings; trailing slash and `sc-domain:` mismatches are 90% of these.
102+
- `searchAppearance` + another dimension → split into two queries.
103+
- `discover` + `query` dimension → use `-d page` or `-d country` instead.
104+
105+
## Anti-patterns (don't do these)
106+
107+
- Don't hand-loop `--row-limit`. Use `--all`.
108+
- Don't try to add custom metrics. There are only 4.
109+
- Don't bake credentials into scripts. Use `gsccli auth login` once.
110+
- Don't pipe `-f table` to `jq`. Use `-f json`.
111+
- Don't `index batch` non-job-posting/livestream content (Google policy ignores the notification).
112+
- Don't compose a single mega-invocation when 2 small steps (query → re-sort, or query → filter) is clearer and faster to debug.
113+
114+
## Verification
115+
116+
Check `rowCount` in JSON envelopes; check exit code (0 = success, 16 = auth, 8 = rate limit, 7 = permission). For writes (`sites add`, `sitemaps submit`, `index publish`), read the response message before claiming success.

0 commit comments

Comments
 (0)