feat: session-handoff v0.4.0 closing ritual (idea 7); setup-context7 v2.0.0 CLI-first (idea 16); backfill vendored pins (idea 2)

This commit is contained in:
2026-08-12 19:48:04 +03:00
parent d64fcd622b
commit 7b80a328be
17 changed files with 127 additions and 98 deletions

View File

@@ -111,8 +111,8 @@ an explicit `adapted-from` marker in its frontmatter.
| skill | provenance | | skill | provenance |
|---|---| |---|---|
| `caveman`, `caveman-commit`, `caveman-compress`, `caveman-help`, `caveman-review` | `adapted-from: JuliusBrussee/caveman` (MIT) — vendored copy, upstream pin TBD | | `caveman`, `caveman-commit`, `caveman-compress`, `caveman-help`, `caveman-review` | `adapted-from: JuliusBrussee/caveman @ 0993277` (MIT) — vendored copy |
| `find-skills` | `adapted-from: vercel-labs/skills` (MIT) — vendored copy, upstream pin TBD | | `find-skills` | `adapted-from: vercel-labs/skills @ c6f69c6` (MIT) — vendored copy |
| `grilling` | `adapted-from: mattpocock/skills @ 84fdeffd` (MIT) — family collapsed to one skill (pi hides `disable-model-invocation` wrappers) | | `grilling` | `adapted-from: mattpocock/skills @ 84fdeffd` (MIT) — family collapsed to one skill (pi hides `disable-model-invocation` wrappers) |
| `brainstorming` | `adapted-from: obra/superpowers @ 6.2.0` (MIT) — divergent phase, visual-companion dropped | | `brainstorming` | `adapted-from: obra/superpowers @ 6.2.0` (MIT) — divergent phase, visual-companion dropped |
| `diagnosing-bugs` | `adapted-from: mattpocock/skills @ 84fdeffd` (MIT) + superpowers 6.2.0 concepts (Iron Law, red flags) | | `diagnosing-bugs` | `adapted-from: mattpocock/skills @ 84fdeffd` (MIT) + superpowers 6.2.0 concepts (Iron Law, red flags) |

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
dist/caveman.skill vendored

Binary file not shown.

BIN
dist/find-skills.skill vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,7 +1,7 @@
--- ---
name: caveman-commit name: caveman-commit
adapted-from: JuliusBrussee/caveman (MIT) — vendored copy, upstream pin TBD adapted-from: JuliusBrussee/caveman @ 0993277 (MIT) — vendored copy
version: 0.1.0 version: 0.1.1
description: > description: >
Ultra-compressed commit message generator. Cuts noise from commit messages while preserving Ultra-compressed commit message generator. Cuts noise from commit messages while preserving
intent and reasoning. Conventional Commits format. Subject ≤50 chars, body only when "why" intent and reasoning. Conventional Commits format. Subject ≤50 chars, body only when "why"

View File

@@ -1,7 +1,7 @@
--- ---
name: caveman-compress name: caveman-compress
adapted-from: JuliusBrussee/caveman (MIT) — vendored copy, upstream pin TBD adapted-from: JuliusBrussee/caveman @ 0993277 (MIT) — vendored copy
version: 1.0.0 version: 1.0.1
description: > description: >
Compress natural language memory files (CLAUDE.md, todos, preferences) into caveman format Compress natural language memory files (CLAUDE.md, todos, preferences) into caveman format
to save input tokens. Preserves all technical substance, code, URLs, and structure. to save input tokens. Preserves all technical substance, code, URLs, and structure.

View File

@@ -1,7 +1,7 @@
--- ---
name: caveman-help name: caveman-help
adapted-from: JuliusBrussee/caveman (MIT) — vendored copy, upstream pin TBD adapted-from: JuliusBrussee/caveman @ 0993277 (MIT) — vendored copy
version: 0.1.0 version: 0.1.1
description: > description: >
Quick-reference card for all caveman modes, skills, and commands. Quick-reference card for all caveman modes, skills, and commands.
One-shot display, not a persistent mode. Trigger: /caveman-help, One-shot display, not a persistent mode. Trigger: /caveman-help,

View File

@@ -1,7 +1,7 @@
--- ---
name: caveman-review name: caveman-review
adapted-from: JuliusBrussee/caveman (MIT) — vendored copy, upstream pin TBD adapted-from: JuliusBrussee/caveman @ 0993277 (MIT) — vendored copy
version: 0.1.0 version: 0.1.1
description: > description: >
Ultra-compressed code review comments. Cuts noise from PR feedback while preserving Ultra-compressed code review comments. Cuts noise from PR feedback while preserving
the actionable signal. Each comment is one line: location, problem, fix. Use when user the actionable signal. Each comment is one line: location, problem, fix. Use when user

View File

@@ -1,7 +1,7 @@
--- ---
name: caveman name: caveman
adapted-from: JuliusBrussee/caveman (MIT) — vendored copy, upstream pin TBD adapted-from: JuliusBrussee/caveman @ 0993277 (MIT) — vendored copy
version: 0.1.0 version: 0.1.1
description: > description: >
Ultra-compressed communication mode. Cuts token usage ~75% by speaking like caveman Ultra-compressed communication mode. Cuts token usage ~75% by speaking like caveman
while keeping full technical accuracy. Supports intensity levels: lite, full (default), ultra, while keeping full technical accuracy. Supports intensity levels: lite, full (default), ultra,

View File

@@ -1,7 +1,7 @@
--- ---
name: find-skills name: find-skills
adapted-from: vercel-labs/skills (MIT) — vendored copy, upstream pin TBD adapted-from: vercel-labs/skills @ c6f69c6 (MIT) — vendored copy
version: 0.1.0 version: 0.1.1
description: Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill. description: Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
--- ---

View File

@@ -1,8 +1,8 @@
--- ---
name: session-handoff name: session-handoff
author: ours author: ours
version: 0.3.3 version: 0.4.0
description: "Sliding handoff between CC sessions via .tasks/NEXT_SESSION.md. Read on session start: orient agent, ask user before action. Write on session-end phrase or substantive commit. Session-end phrases: «завершаем сессию», «сворачиваемся», «закругляемся», «wrap up session», «end session», «we're done for now». Trigger-line in CLAUDE.md: `session handoff: read on start, write on end`. Skip task-zone phrases: «закрываем эту таску», «pause», «отбой», «разбегаемся»." description: "Sliding handoff between CC sessions via .tasks/NEXT_SESSION.md. Read on session start: orient agent, ask user before action. Write on session-end phrase or substantive commit. On session-end the agent ALSO runs the closing ritual on its own (idea 7: no invitation needed): handoff write + PROPOSE wiki-ingest of session knowledge + PROPOSE task-board closes — mutations only after user confirmation. Session-end phrases: «завершаем сессию», «сворачиваемся», «закругляемся», «wrap up session», «end session», «we're done for now». Trigger-line in CLAUDE.md: `session handoff: read on start, write on end`. Skip task-zone phrases: «закрываем эту таску», «pause», «отбой», «разбегаемся»."
--- ---
# session-handoff # session-handoff
@@ -105,6 +105,23 @@ Forward-looking, не timeline: handoff = связка новых вещей к
Пустую секцию — оставить заголовок + пометка `(нет на этом раунде)`. Чтобы next агент видел: не забыто, а пусто. Пустую секцию — оставить заголовок + пометка `(нет на этом раунде)`. Чтобы next агент видел: не забыто, а пусто.
4. **Sliding overwrite.** `Write` поверх `.tasks/NEXT_SESSION.md` (предыдущее содержимое НЕ архивируется в `.archive/handoff-*.md` — sliding contract). История восстанавливается через `git log -p .tasks/NEXT_SESSION.md`. 4. **Sliding overwrite.** `Write` поверх `.tasks/NEXT_SESSION.md` (предыдущее содержимое НЕ архивируется в `.archive/handoff-*.md` — sliding contract). История восстанавливается через `git log -p .tasks/NEXT_SESSION.md`.
5. **Stage.** `git add .tasks/NEXT_SESSION.md` — попадает в следующий commit сессии (или в текущий, если запись была вызвана session-end фразой). 5. **Stage.** `git add .tasks/NEXT_SESSION.md` — попадает в следующий commit сессии (или в текущий, если запись была вызвана session-end фразой).
6. **Closing ritual (idea 7).** На session-end фразе (НЕ на substantive commit) после handoff-write агент сам, без приглашения, предлагает закрытие:
- **(2) Propose wiki-ingest.** Если за сессию появилось durable-знание (паттерн, решение, коррекция user'а, процедура) — ПРЕДЛОЖИТЬ ingest (using-wiki: `sources/`+концепты или global через `knowledge_ingest`), перечислив кандидатов. Ничего не писать без подтверждения.
- **(3) Propose task-board closes.** Прочитать `.tasks/STATUS.md`: если есть задачи, выглядящие закрытыми (outcome достигнут, все шаги сделаны) — ПРЕДЛОЖИТЬ закрытия. Уважать ralph-loop: verifier-задачи (с `**Verifier:**`) закрывать только через verifier, не по виду.
- Формат предложения — один блок: «Ритуал закрытия: (а) заингестить X в вики? (б) закрыть Y? (в) ничего.» Ждать ответа. Отказ = пропуск, не настаивать.
## Ритуал закрытия (детали)
**Граница мутаций:** ритуал берёт инициативу в *проверке и предложении* — но НИ ОДНА мутация (wiki-ingest, закрытие таски) не выполняется молча. Каждая — после явного «да». Причина: вики-шум без ревью и закрытие ralph-loop задач без verifier — дороже пропущенного предложения.
**Skip (silent):**
- Нет `.wiki/` в проекте → шаг (2) пропускается молча.
- Нет `.tasks/STATUS.md` → шаг (3) пропускается молча.
- Не git-папка / нет `.tasks/` → весь ритуал silent exit (совпадает с базовым скилом).
**Триггер:** ритуал на session-end фразе; на substantive commit'е — только handoff-write, ритуал НЕ гонять (mid-session коммит ≠ конец сессии, иначе спам предложений).
**Headless (pi, дизайн):** для автоматического запуска без интерактива нужен pi-extension на `agent_settled` с дедуп-гардом (по образцу inbox-monitor). Не построен — зафиксировано как follow-up; скил покрывает интерактивные харнессы.
## Failure modes ## Failure modes
@@ -115,17 +132,21 @@ Forward-looking, не timeline: handoff = связка новых вещей к
- **Secret detected.** Содержимое handoff'а матчит паттерны секретов (`AKIA...`, `sk-...`, `ghp_...`, `ssh-rsa`, `BEGIN PRIVATE KEY`, JWT в обычном виде, `password=`/`token=` без obfuscation) → **abort write**, не записывать. Файл идёт в git — не место для credentials. Сообщить user'у с указанием подозрительной строки, дать дочистить контекст руками. - **Secret detected.** Содержимое handoff'а матчит паттерны секретов (`AKIA...`, `sk-...`, `ghp_...`, `ssh-rsa`, `BEGIN PRIVATE KEY`, JWT в обычном виде, `password=`/`token=` без obfuscation) → **abort write**, не записывать. Файл идёт в git — не место для credentials. Сообщить user'у с указанием подозрительной строки, дать дочистить контекст руками.
- **Stale handoff (> 7 дней)** в read mode → не silent, **спросить** user'а оверrайдить или продолжить (Q9 resolved 2026-05-24). - **Stale handoff (> 7 дней)** в read mode → не silent, **спросить** user'а оверrайдить или продолжить (Q9 resolved 2026-05-24).
- **Mid-task без STATUS.md entry** в write mode → записать handoff без mid-task секции, не блокировать. - **Mid-task без STATUS.md entry** в write mode → записать handoff без mid-task секции, не блокировать.
- **Ритуал: user отказал во всех предложениях** → пропустить, не настаивать, не повторять в этой сессии. Отказ = решение, не приглашение к уговорам.
## Side effects ## Side effects
- Записывает / перезаписывает `.tasks/NEXT_SESSION.md` (project-scope only). - Записывает / перезаписывает `.tasks/NEXT_SESSION.md` (project-scope only).
- Файл git-tracked, попадает в commit (либо вместе с session work, либо отдельным commit'ом). - Файл git-tracked, попадает в commit (либо вместе с session work, либо отдельным commit'ом).
- Никаких других файлов: `.archive/` не плодим (sliding), `.wiki/log.md` не дёргаем (это не promoted event), `STATUS.md` не правим. - Никаких других файлов: `.archive/` не плодим (sliding), `.wiki/log.md` не дёргаем (это не promoted event), `STATUS.md` не правим.
- Ритуал закрытия предлагает wiki-ingest и закрытия тасок — но НЕ пишет их. Файлы пишет user-подтверждённый следующий шаг (using-wiki / using-tasks), не этот скил.
- Никаких global мутаций, никаких других проектов, никаких user-level config writes. - Никаких global мутаций, никаких других проектов, никаких user-level config writes.
## What NOT to do ## What NOT to do
- **Не auto-execute** действия из read handoff'а. Default = orient + ask. Прошлая сессия могла ошибиться; user agency сохраняем. - **Не auto-execute** действия из read handoff'а. Default = orient + ask. Прошлая сессия могла ошибиться; user agency сохраняем.
- **Не писать в вики / не закрывать таски по ритуалу молча.** Ритуал = предложения (idea 7, граница мутаций). Каждая мутация — после явного «да».
- **Не гонять ритуал на substantive commit.** Только session-end фраза. Mid-session коммит → handoff-write без ритуала (иначе спам предложений).
- **Не append-with-archive.** Sliding only. `.archive/handoff-<date>.md` создавать не нужно — это создавало бы N artefact'ов, которые user не хочет. История — через git log. - **Не append-with-archive.** Sliding only. `.archive/handoff-<date>.md` создавать не нужно — это создавало бы N artefact'ов, которые user не хочет. История — через git log.
- **Не триггерить на task-zone phrases** («закрываем эту таску», «pause»), broad farewells («отбой», «разбегаемся»), partial completions («сейчас завершу одну задачу и тогда поговорим»). - **Не триггерить на task-zone phrases** («закрываем эту таску», «pause»), broad farewells («отбой», «разбегаемся»), partial completions («сейчас завершу одну задачу и тогда поговорим»).
- **Не писать секреты** в handoff. Если контент матчит secret-patterns — abort, попросить user'а вычистить контекст. - **Не писать секреты** в handoff. Если контент матчит secret-patterns — abort, попросить user'а вычистить контекст.

View File

@@ -1,37 +1,41 @@
--- ---
name: setup-context7 name: setup-context7
author: ours author: ours
version: 1.0.0 version: 2.0.0
description: Installs and configures the official context7 MCP plugin (`context7@claude-plugins-official`), reuses the user's existing Context7 API key, and cleans out any manual `mcpServers.context7` entries from `~/.claude.json` and `~/.claude/settings.json`. Use this skill when the user says "install context7", "set up context7", "configure context7", "настрой context7", "установи context7", "context7 не работает", "context7 isn't working", or whenever the `mcp__context7__resolve-library-id` / `mcp__context7__query-docs` tools are missing in a session that needs library docs. Cross-platform — Windows / Linux / macOS. Mutates user-level config; pauses for confirmation before writing. description: "Installs and configures the agent-neutral `ctx7` CLI (npm) for Context7 docs — CLI-first, no MCP registration. Reuses an existing Context7 API key or offers the OAuth flow, and migrates off the legacy context7 MCP plugin (`context7@claude-plugins-official`): uninstalls the plugin, cleans `mcpServers.context7` entries from `~/.claude.json` / `~/.claude/settings.json`. Use when the user says «настрой context7», «установи context7», «context7 не работает», \"set up context7\", \"install context7\", \"context7 isn't working\", or when a session needs library docs and the `ctx7` CLI is missing. Cross-platform — Windows / Linux / macOS. Mutates user-level config; pauses for confirmation before writing."
--- ---
# setup-context7 # setup-context7
> One-time skill that gets the official context7 plugin running with the user's existing API key, with manual MCP entries cleaned up. Stops at confirmation gates because the procedure modifies user-level config files. > One-time skill that gets the **`ctx7` CLI** running with the user's existing Context7 key, and migrates off the legacy MCP plugin. Agent-neutral: any harness (pi / claude / hermes / codex) calls `ctx7` in bash — no MCP registration, no harness-specific tools. Stops at confirmation gates because the procedure modifies user-level config files.
## When to use ## When to use
- User explicitly asks: install / set up / configure context7. - User explicitly asks: install / set up / configure context7.
- A `using-context7`-driven task fails because `mcp__context7__*` tools aren't available. - A `using-context7`-driven task fails because the `ctx7` CLI isn't on PATH.
- Migrating an existing manually-configured context7 to the official plugin. - Migrating an existing plugin/MCP-based context7 install to the CLI (legacy cleanup).
## Out of scope ## Out of scope
- Creating a *new* API key. This skill *reuses* a key the user already has; if there's no key, offer the OAuth flow (`npx ctx7 setup`) and stop. - Creating a *new* API key. This skill *reuses* a key the user already has or offers the OAuth flow (`ctx7 login`); if the user has no key and no account, offer OAuth and stop.
- Rolling back from the official plugin to manual config. - Rolling back from CLI to the plugin (not supported — CLI is the canonical path, idea 16 `claude-to-agents`).
- Any non-context7 MCP server. - Any non-context7 MCP server.
## Hard rule: don't auto-mutate config ## Hard rule: don't auto-mutate config
The procedure modifies `~/.claude.json` and `~/.claude/settings.json`. **Always pause for explicit confirmation between Phase 1 (discovery, read-only) and Phase 2 (plan), and again before Phase 3 (backup + writes).** A trigger phrase is permission to run discovery, not permission to overwrite config. The procedure modifies `~/.claude.json`, `~/.claude/settings.json` and the plugin install state. **Always pause for explicit confirmation between Phase 1 (discovery, read-only) and Phase 2 (plan), and again before Phase 3 (backup + writes).** A trigger phrase is permission to run discovery, not permission to overwrite config.
## Prerequisites
- Node.js / npm on PATH (the CLI is an npm package). Check with `node -v`; if missing, install Node first.
- Git Bash gotcha (Windows): library IDs start with `/` and Git Bash path-converts them — `using-context7` documents the `//owner/repo` double-slash workaround.
## Procedure ## Procedure
### Phase 0 — Environment sanity ### Phase 0 — Environment sanity
- Confirm Claude Code is the current harness (need `/plugin install` capability). - Check whether `ctx7` is already installed: `ctx7 --version`. Installed → skip Phase 4 (install), proceed to Phase 5 (auth) / cleanup as needed.
- Confirm `npx` is on `PATH` (the plugin spawns `npx -y @upstash/context7-mcp`). If missing, install Node.js first. - Pick paths: `~/.claude/` and `~/.config/projects-secrets/` work on all three OSes. In git-bash on Windows, `~` resolves correctly.
- Pick paths: `~/.claude/` works on all three OSes. In git-bash on Windows, `~` resolves correctly.
### Phase 1 — Discovery (read-only) ### Phase 1 — Discovery (read-only)
@@ -39,86 +43,91 @@ Search, in order. Stop reporting verbatim values for keys; report only "found at
**Existing API key.** Look in priority order: **Existing API key.** Look in priority order:
1. `~/.claude/settings.json``mcpServers.context7.headers.CONTEXT7_API_KEY` 1. `~/.config/projects-secrets/ctx7.env``CONTEXT7_API_KEY=` (our secrets convention, cf. `interns.env` / `auth.toml`)
2. `~/.claude.json` → top-level `mcpServers.context7.headers.CONTEXT7_API_KEY` 2. Env var `CONTEXT7_API_KEY`
3. `~/.claude.json``projects.<any>.mcpServers.context7.headers.CONTEXT7_API_KEY` 3. `~/.claude/settings.json``mcpServers.context7.headers.CONTEXT7_API_KEY`
4. `~/.claude/settings.local.json` if present 4. `~/.claude.json` → top-level `mcpServers.context7.headers.CONTEXT7_API_KEY`
5. Env var `CONTEXT7_API_KEY` 5. `~/.claude/settings.local.json` if present
The first hit wins. Capture the key value internally for Phase 5; **never echo it in chat**. The first hit wins. Capture the key value internally for Phase 5; **never echo it in chat**.
**Manual context7 MCP entries.** Find every `mcpServers.context7` block in `~/.claude.json` and `~/.claude/settings.json` (top-level and project-scoped). Note all locations. **Legacy MCP/plugin state** (migration targets — report locations, don't touch yet):
**Plugin install state.** Read `~/.claude/plugins/installed_plugins.json` and check for `context7@claude-plugins-official`. - Manual `mcpServers.context7` blocks in `~/.claude.json` and `~/.claude/settings.json` (top-level and project-scoped).
- Plugin installed: `~/.claude/plugins/installed_plugins.json` contains `context7@claude-plugins-official`?
**Plugin's `.mcp.json` state** (only if plugin is installed). Path: - Plugin cache/data dirs: `~/.claude/plugins/cache/claude-plugins-official/context7/`, `~/.claude/plugins/data/context7*`.
```
~/.claude/plugins/cache/claude-plugins-official/context7/<version>/.mcp.json
```
`<version>` is often `unknown` for un-tagged marketplace plugins. List the cache dir to find it. Check whether `--api-key` is already in `args`.
### Phase 2 — Plan + confirm ### Phase 2 — Plan + confirm
Present a single-block plan to the user: Present a single-block plan to the user:
``` ```
API key: <found-at | NOT FOUND — will ask> ctx7 CLI: <installed vX.Y.Z | will npm i -g ctx7>
Plugin: <installed | will ask user to /plugin install> API key: <found-at | NOT FOUND — will ask / offer OAuth>
Manual entries: <list of paths to remove> Legacy to clean:
plugin: <installed | not installed>
manual MCP: <list of paths to remove>
Backups: ~/.claude.json.bak-<ts>, ~/.claude/settings.json.bak-<ts> Backups: ~/.claude.json.bak-<ts>, ~/.claude/settings.json.bak-<ts>
``` ```
Wait for explicit confirmation ("ok", "go", "поехали"). Anything else → stop. Wait for explicit confirmation ("ok", "go", "поехали"). Anything else → stop.
If no API key was found in Phase 1 — first ask: "Paste a Context7 API key, or run `npx ctx7 setup` to get one (OAuth)?" Don't proceed past Phase 2 without a key. If no API key was found in Phase 1 — first ask: "Paste a Context7 API key, or run `ctx7 login` (OAuth, interactive)?" Don't proceed past Phase 2 without a key.
### Phase 3 — Backup ### Phase 3 — Backup
Copy each file we will modify to `<file>.bak-YYYYMMDD-HHMMSS`: Copy each file we will modify to `<file>.bak-YYYYMMDD-HHMMSS`:
```bash ```bash
TS=$(date +%Y%m%d-%H%M%S) TS=$(date +%Y%m%d-%H%M%S)
cp ~/.claude.json ~/.claude.json.bak-$TS cp ~/.claude.json ~/.claude.json.bak-$TS
cp ~/.claude/settings.json ~/.claude/settings.json.bak-$TS cp ~/.claude/settings.json ~/.claude/settings.json.bak-$TS
``` cp ~/.config/projects-secrets/ctx7.env ~/.config/projects-secrets/ctx7.env.bak-$TS 2>/dev/null || true
Confirm both backups exist before any further edit.
### Phase 4 — Plugin install (if needed)
If the plugin is **not** in `installed_plugins.json`:
1. Ask the user to run `/plugin install context7@claude-plugins-official` in Claude Code (we can't run interactive slash commands).
2. Wait for "поставил" / "installed".
3. Verify by re-reading `installed_plugins.json`.
If the plugin **is** already installed: skip this phase.
### Phase 5 — Inject `--api-key`
Find the live plugin file:
```
~/.claude/plugins/cache/claude-plugins-official/context7/<version>/.mcp.json
``` ```
If the file's `args` already contains `--api-key`, skip. Otherwise edit `args` to append `"--api-key", "<KEY>"`. Final shape: Confirm backups exist before any further edit.
```json ### Phase 4 — Install the CLI
{
"context7": { ```bash
"command": "npx", npm install -g ctx7
"args": ["-y", "@upstash/context7-mcp", "--api-key", "<KEY>"] ctx7 --version # verify
}
}
``` ```
Per Upstash's client-config docs (<https://context7.com/docs/resources/all-clients>), `--api-key` is the recommended form for stdio transport. Header form is for HTTP transport (which the plugin doesn't use). If the user prefers no global install: `npx -y ctx7 ...` works per-call (no install) — but for a standing setup, the global install is one-time and cheaper per call.
### Phase 6Clean manual entries ### Phase 5Auth (key or OAuth)
For each manual entry found in Phase 1: - **Key found** (Phase 1): write `~/.config/projects-secrets/ctx7.env`:
- **Top-level `mcpServers.context7`** in `settings.json` or `.claude.json` → remove the `context7` key. Preserve sibling MCP servers and JSON validity (watch for trailing commas). ```
CONTEXT7_API_KEY=<KEY>
```
(if the file exists, merge the key in; never clobber sibling entries).
- **No key**: run `ctx7 login` (interactive OAuth, one-time, human runs it) or ask the user to paste a key.
Verify: `CONTEXT7_API_KEY=$(grep ... ctx7.env) ctx7 whoami` (or `ctx7 whoami` after exporting) — should resolve to the user's account. On Windows git-bash, set the var inline per call; the skill's `using-context7` documents how to source the env file.
### Phase 6 — Clean legacy MCP/plugin (migration)
For each legacy item found in Phase 1:
- **Plugin** installed → uninstall via CLI:
```bash
claude plugin uninstall context7@claude-plugins-official
```
Then remove leftover cache/data dirs if any remain:
`~/.claude/plugins/cache/claude-plugins-official/context7/`, `~/.claude/plugins/data/context7*`.
- **Manual `mcpServers.context7`** in `settings.json` / `.claude.json` (top-level) → remove the `context7` key. Preserve sibling MCP servers and JSON validity (watch for trailing commas).
- **Project-scoped `projects.<path>.mcpServers.context7`** in `.claude.json` → remove. If the parent `mcpServers` becomes empty, leave it as `{}` (don't delete the key — Claude Code may rely on its presence). - **Project-scoped `projects.<path>.mcpServers.context7`** in `.claude.json` → remove. If the parent `mcpServers` becomes empty, leave it as `{}` (don't delete the key — Claude Code may rely on its presence).
After each edit, validate JSON. On any platform: After each edit, validate JSON. On any platform:
```bash ```bash
# Windows (PowerShell) # Windows (PowerShell)
powershell.exe -NoProfile -c "Get-Content '<file>' -Raw | ConvertFrom-Json | Out-Null" powershell.exe -NoProfile -c "Get-Content '<file>' -Raw | ConvertFrom-Json | Out-Null"
@@ -130,49 +139,44 @@ python -c "import json,sys; json.load(open('<file>'))"
If validation fails → restore the just-edited file from its `.bak-*` and abort with a clear report. Do not continue editing. If validation fails → restore the just-edited file from its `.bak-*` and abort with a clear report. Do not continue editing.
### Phase 7 — Smoke test (best-effort) ### Phase 7 — Smoke test
Call `mcp__context7__resolve-library-id` with a benign query (e.g. `libraryName: "Nuxt"`, `query: "smoke test"`). If it returns library IDs — context7 is reachable in *this* session. Call the CLI with a benign query:
**Important caveat to relay to the user:** in the *same* session that just ran setup, the MCP server is still the legacy connection bound at session start. So a passing smoke test only proves "context7 still works" — not "the plugin is what's serving it". The real test is after Claude Code restart. ```bash
ctx7 library Nuxt "Nuxt 4 config and route rules"
```
If it returns library IDs / snippets — context7 works via CLI in *any* harness. Optionally `ctx7 whoami` to confirm the key.
### Phase 8 — Restart guidance + final report ### Phase 8 — Restart guidance + final report
Tell the user: Tell the user:
``` ```
✅ Setup complete. Restart Claude Code to pick up the plugin's stdio transport. ✅ Setup complete. ctx7 CLI is agent-neutral — no MCP registration, no restart needed for other agents.
After restart: • Usage: ctx7 library <name> / ctx7 docs <libraryId> "<question>" (see using-context7)
mcp__context7__* tools will be served by `npx @upstash/context7-mcp --api-key …` Key: ~/.config/projects-secrets/ctx7.env (CONTEXT7_API_KEY)
Manual entries are gone — single source of truth is the plugin's .mcp.json. Legacy: context7 plugin + mcpServers.context7 entries removed (single source = CLI)
• Backups saved at ~/.claude.json.bak-<ts> and ~/.claude/settings.json.bak-<ts>. • Backups saved at ~/.claude.json.bak-<ts> and ~/.claude/settings.json.bak-<ts>.
If something breaks after restart: If something breaks after cleanup:
• Restore from .bak-* files and tell me — we'll roll back together. • Restore from .bak-* files and tell me — we'll roll back together.
``` ```
## Rollback procedure ## Rollback procedure
If a problem surfaces (now or after restart): If a problem surfaces (now or later):
1. Stop. Don't try to fix forward. 1. Stop. Don't try to fix forward.
2. Find the most recent `.bak-YYYYMMDD-HHMMSS` next to `~/.claude.json` and `~/.claude/settings.json`. 2. Find the most recent `.bak-YYYYMMDD-HHMMSS` next to the modified files.
3. `cp <file>.bak-<ts> <file>` for both. 3. `cp <file>.bak-<ts> <file>` for each.
4. Optional: `/plugin uninstall context7@claude-plugins-official`. 4. Optional: reinstall the plugin via `/plugin install context7@claude-plugins-official` if the user wants the MCP path back.
5. Restart Claude Code. 5. Restart Claude Code.
6. Confirm `mcp__context7__*` is back via the legacy HTTP path. 6. Confirm `mcp__context7__*` is back via the legacy path.
7. Report what went wrong so we can fix the procedure. 7. Report what went wrong so we can fix the procedure.
## Plugin-update gotcha
`/plugin update context7@claude-plugins-official` (or any reinstall) re-fetches the plugin's `.mcp.json` from the marketplace cache. That file is upstream-canonical and **does not** contain `--api-key` — the marketplace doesn't ship secrets. After any plugin update:
- Run this skill again. Phase 1 will detect the missing flag, Phase 5 will re-inject. Phases 4 and 6 are no-ops.
- Or manually re-add `--api-key` to `args` in the live `.mcp.json`.
The marketplace upstream is at `anthropics/claude-plugins-official/external_plugins/context7/.mcp.json`. It's two lines and rarely changes — the `--api-key` re-injection is the only ongoing maintenance cost.
## Cross-platform notes ## Cross-platform notes
The procedure is platform-agnostic. Only auxiliary tooling differs: The procedure is platform-agnostic. Only auxiliary tooling differs:
@@ -183,12 +187,16 @@ The procedure is platform-agnostic. Only auxiliary tooling differs:
| Linux | `jq empty <f>` (or `python -c "import json; json.load(open('<f>'))"`) | `cp` | | Linux | `jq empty <f>` (or `python -c "import json; json.load(open('<f>'))"`) | `cp` |
| macOS | same as Linux | `cp` | | macOS | same as Linux | `cp` |
Path forms (`~/.claude/...`) are identical on all three. Path forms (`~/.claude/...`, `~/.config/projects-secrets/...`) are identical on all three.
## Common mistakes ## Common mistakes
- **Skipping Phase 1.** "User just said 'install context7' — let's go." No — find the existing key first; making the user paste a key when they already have one is rude. - **Skipping Phase 1.** "User just said 'install context7' — let's go." No — find the existing key first; making the user paste a key when they already have one is rude.
- **Echoing the key.** It's a secret. The Edit / Write tool calls inevitably contain it (that's how it gets into the file), but no chat output should. - **Echoing the key.** It's a secret. The Edit / Write tool calls inevitably contain it (that's how it gets into the file), but no chat output should.
- **Mutating `.claude.json` without backup.** That file holds *all* of the user's per-project Claude Code state. Losing it is bad. - **Mutating `.claude.json` without backup.** That file holds *all* of the user's per-project Claude Code state. Losing it is bad.
- **Treating in-session smoke test as proof.** It isn't — the active MCP connection is bound at session start. - **Leaving the legacy plugin installed.** The point of the CLI migration is one agent-neutral path; a stale plugin means two sources of truth. Clean it in Phase 6.
- **Auto-running on every "use context7".** This skill is intrusive. Trigger only when explicitly invoked or when MCP tools are missing and the user is blocked. - **Auto-running on every "use context7".** This skill is intrusive. Trigger only when explicitly invoked or when the CLI is missing and the user is blocked.
## Why CLI-first (design note)
Context7 is an HTTP MCP server + npm CLI. The MCP path (`context7@claude-plugins-official`) is harness-specific glue (claude-plugins-official); pi doesn't see it (the claude-mcp-bridge only reads `~/.claude.json`, and even then it's fragile). Per the sovereign-catalog principle *"что можно сделать CLI — делаем CLI и оборачиваем в скил; MCP только там, где нужен структурированный/интерактивный протокол"* — the CLI is the canonical path (idea 16, `claude-to-agents` running record).