From ef3d38e79de10e59be91a14ac651e256f3e88e7f Mon Sep 17 00:00:00 2001 From: vitya Date: Thu, 21 May 2026 14:22:51 +0300 Subject: [PATCH] feat(setup-interns, using-interns): secrets at ~/.config/projects-secrets/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aligns claude-skills with secrets-out-of-common etap-1 migration: the canonical home for plain-text local-dev secrets is now ~/.config/projects-secrets/, outside any git tree. setup-interns [v0.3.0 → v0.4.0, MINOR — write target changed]: - Phase 1 drops gitignore-sanity check (no longer needed) - Phase 2 plan block drops Gitignore line - Phase 3 backs up ~/.config/projects-secrets/interns.env if present - Phase 5 writes ~/.config/projects-secrets/interns.env (mkdir -p ahead) - Phase 6 cwd documentation: secrets path no longer relative to cwd; uses INTERNS_SECRETS_PATH env var (or ~/.config default) — independent - Common-mistakes drops "missing gitignore rule" entry using-interns [v0.2.0 → v0.2.1, PATCH — wording]: - Always-ask paths section reflects new canonical secrets home - Prerequisites text updates setup-interns write target interns-design.md (wiki concept): path refs updated for ASCII layer diagram, Layer 1 example block, Phase 5 description, comparison table, and final cross-cutting note. **/projects-secrets/** added to always-ask documentation pattern. dist/: setup-interns.skill + using-interns.skill rebuilt. Co-Authored-By: Claude Opus 4.7 (1M context) --- .wiki/concepts/interns-design.md | 12 +++++----- dist/setup-interns.skill | Bin 8428 -> 8310 bytes dist/using-interns.skill | Bin 7314 -> 7319 bytes skills/setup-interns/README.md | 12 +++++----- skills/setup-interns/SKILL.md | 37 +++++++++++-------------------- skills/using-interns/SKILL.md | 6 ++--- 6 files changed, 28 insertions(+), 39 deletions(-) diff --git a/.wiki/concepts/interns-design.md b/.wiki/concepts/interns-design.md index 16d1868..fe71684 100644 --- a/.wiki/concepts/interns-design.md +++ b/.wiki/concepts/interns-design.md @@ -48,7 +48,7 @@ Triggered by Reddit thread (May 2026) и Medium-статьёй того же а ┌──────────────────────────────────────────────────────────────┐ │ Layer 1 — Config (data, no code) │ │ .common/config/interns/config.yaml — endpoints + tools │ -│ .common/secrets/interns.env — API ключи (gitignored) │ +│ ~/.config/projects-secrets/interns.env — API ключи (outside git) │ └──────────────────────────────────────────────────────────────┘ ``` @@ -98,7 +98,7 @@ interns: transcript. Output structured markdown sections. Be terse. ``` -`.common/secrets/interns.env` (gitignored): +`~/.config/projects-secrets/interns.env` (outside any git tree; canonical home since `secrets-out-of-common` migration): ```dotenv OLLAMA_CLOUD_API_KEY=... @@ -152,7 +152,7 @@ interns-mcp/ **Steps:** 1. Проверить `.common/lib/interns-mcp/` существует. Если нет — инициализировать пустой через template (TBD: см. open question про source repo). 2. `pip install -e .common/lib/interns-mcp/` через активный Python interpreter. -3. Прочитать `.common/config/interns/config.yaml`, для каждого `endpoint..api_key_env` проверить наличие в `.common/secrets/interns.env`. Отсутствующие — спросить интерактивно, preview перед записью, write. +3. Прочитать `.common/config/interns/config.yaml`, для каждого `endpoint..api_key_env` проверить наличие в `~/.config/projects-secrets/interns.env`. Отсутствующие — спросить интерактивно, preview перед записью, write. 4. Зарегистрировать `mcpServers.interns` в `~/.claude.json`: ```json "interns": { @@ -180,7 +180,7 @@ interns-mcp/ 3. **Always-ask paths (даже с активным grant'ом).** Полный список: - `**/.env`, `**/.env.*` — environment files со секретами - - `**/secrets/**` — каноническая папка секретов (включая `.common/secrets/`) + - `**/secrets/**`, `**/projects-secrets/**` — каноническая папка секретов (после миграции `secrets-out-of-common`: `~/.config/projects-secrets/`) - `**/credentials*` — credentials.json и подобные - `**/*.key` — private keys любого формата - `**/*.pem` — PEM-encoded keys/certs @@ -220,7 +220,7 @@ interns-mcp/ | Слой | Windows | Linux | macOS | |---|---|---|---| | `.common/lib/interns-mcp/` (Python 3.11+) | ✅ | ✅ | ✅ | -| `.common/secrets/interns.env` (`python-dotenv`) | ✅ | ✅ | ✅ | +| `~/.config/projects-secrets/interns.env` (`python-dotenv`) | ✅ | ✅ | ✅ | | `setup-interns` install (`python -m pip`) | ✅ | ✅ | ✅ | | MCP registration — путь к Python | `where python` | `which python` | `which python` | | Always-ask matcher (`pathlib.PurePath.match`) | ✅ POSIX-style globs работают везде | ✅ | ✅ | @@ -277,7 +277,7 @@ interns-mcp/ - **Source repo для `.common/lib/interns-mcp/`.** Inline в `.common` или отдельный repo на Gitea + git-subtree/submodule? Текущее склонение — inline (это часть `.common`, не самостоятельный продукт). - **Auto-discovery интернов** в `registry.py` (через `pkgutil.iter_modules`) vs explicit `register_tool` в `server.py`. Auto проще для расширения, explicit прозрачнее. Текущее склонение — explicit для MVP. - **Cost tracking.** В первом релизе — нет. Если оботрётся в реальной работе — добавим в `safety.py` per-call estimate из config (`tokens_used × price_per_M`) и блокировку >$X через always-ask механизм. -- **Sharing endpoint между meeting-room runner и interns-mcp.** Сейчас `.meeting-room/config/config.yaml` имеет свой `providers.ollama_cloud` с собственным ключом; interns-mcp будет иметь свой в `.common/secrets/interns.env`. Дублирование. Унификация — отдельная задача. +- **Sharing endpoint между meeting-room runner и interns-mcp.** Сейчас `.meeting-room/config/config.yaml` имеет свой `providers.ollama_cloud` с собственным ключом; interns-mcp будет иметь свой в `~/.config/projects-secrets/interns.env`. Дублирование. Унификация — отдельная задача. - **Persistent prefix-cache benefit с Ollama Cloud.** Документация Ollama Cloud не подтверждает prefix-cache discount явно (как делает OpenRouter). Если измерения покажут что cache не работает — рассмотреть переключение на OpenRouter как primary endpoint. ## References diff --git a/dist/setup-interns.skill b/dist/setup-interns.skill index 49d4fcfa05d2587feb0e2f427acdb7c714319502..a2c52f7557ca3fc8c43634b0710be3af9984851c 100644 GIT binary patch delta 8165 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 DKh?Fl delta 8279 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 PjfqmEbg&Af|Lgn@Sq1mE diff --git a/dist/using-interns.skill b/dist/using-interns.skill index 6576bd39dff28d03c931446d373b61c9e3c58250..fd5eea89a743148751210064b66427827c43b447 100644 GIT binary patch delta 5237 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 delta 5250 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 I8vp/.common/lib/interns-mcp/`, runs `pip install -e`, writes `.common/secrets/interns.env` with the endpoint API keys, and registers `mcpServers.interns` in `~/.claude.json`. +One-time skill that brings up the local `interns` MCP server on a new (or freshly broken) machine. Detects the runtime source at `/.common/lib/interns-mcp/`, runs `pip install -e`, writes `~/.config/projects-secrets/interns.env` with the endpoint API keys, and registers `mcpServers.interns` in `~/.claude.json`. The runtime policy for *using* the resulting tools lives in [`using-interns`](../using-interns/) — `setup-interns` is the only place that touches user-level config or the project's secrets directory. @@ -21,7 +21,7 @@ Full design (Layer 1 / 2 / 3, MVP catalog, always-ask paths, routing hints): |---|---| | `/.common/lib/interns-mcp/` | server source (must already exist; not created here) | | `/.common/config/interns/config.yaml` | catalog of interns + endpoints (read-only here) | -| `/.common/secrets/interns.env` | endpoint API keys (gitignored) | +| `~/.config/projects-secrets/interns.env` | endpoint API keys (outside any git tree) | | `~/.claude.json` (`mcpServers.interns`) | MCP registration | | `pip` site-packages | editable install of `interns_mcp` | @@ -36,11 +36,11 @@ Full design (Layer 1 / 2 / 3, MVP catalog, always-ask paths, routing hints): ## Procedure (high-level) 1. **Phase 0** — environment sanity (`python` ≥ 3.11, `pip`, network to endpoints). -2. **Phase 1** — discovery (source / module / config / keys / MCP registration / `.gitignore`). +2. **Phase 1** — discovery (source / module / config / keys / MCP registration). 3. **Phase 2** — plan + confirm. Wait for explicit "ok" / "go" / "поехали". -4. **Phase 3** — backup (`~/.claude.json`, existing `.common/secrets/interns.env`). +4. **Phase 3** — backup (`~/.claude.json`, existing `~/.config/projects-secrets/interns.env`). 5. **Phase 4** — `pip install -e .common/lib/interns-mcp/`. -6. **Phase 5** — write `.common/secrets/interns.env` (per-key, missing-only) + ensure `.gitignore` rule. +6. **Phase 5** — write `~/.config/projects-secrets/interns.env` (per-key, missing-only). 7. **Phase 6** — register `mcpServers.interns` in `~/.claude.json` with absolute interpreter path + `cwd`. 8. **Phase 7** — best-effort smoke test (in-session caveat: real verification is after restart). 9. **Phase 8** — restart guidance + final report. @@ -50,7 +50,7 @@ Full procedure with shell snippets and templates lives in [`SKILL.md`](SKILL.md) ## Rollback 1. Stop. Don't fix forward. -2. `cp .bak- ` for `~/.claude.json` and `.common/secrets/interns.env`. +2. `cp .bak- ` for `~/.claude.json` and `~/.config/projects-secrets/interns.env`. 3. Optional: `pip uninstall interns-mcp` to undo the editable install. 4. Restart Claude Code. 5. Confirm `mcp__interns__*` tools are gone (or back to the prior version). diff --git a/skills/setup-interns/SKILL.md b/skills/setup-interns/SKILL.md index 9c2401d..bd27697 100644 --- a/skills/setup-interns/SKILL.md +++ b/skills/setup-interns/SKILL.md @@ -1,7 +1,7 @@ --- name: setup-interns -version: 0.3.0 -description: Installs and configures the local `interns` MCP server — clones the repo to `~/projects/.common/lib/interns-mcp/` (or uses an existing clone), `pip install -e` it, writes `~/projects/.common/secrets/interns.env` with endpoint API keys, and registers `mcpServers.interns` in `~/.claude.json`. Use this skill when the user says "install interns", "set up interns", "configure interns", "настрой интернов", "установи интернов", "interns не работает", "interns isn't working", or whenever the `mcp__interns__*` tools are missing in a session that needs delegation. Cross-platform — Windows / Linux / macOS. Mutates user-level config and writes secrets; pauses for confirmation before every write. +version: 0.4.0 +description: Installs and configures the local `interns` MCP server — clones the repo to `~/projects/.common/lib/interns-mcp/` (or uses an existing clone), `pip install -e` it, writes `~/.config/projects-secrets/interns.env` with endpoint API keys, and registers `mcpServers.interns` in `~/.claude.json`. Use this skill when the user says "install interns", "set up interns", "configure interns", "настрой интернов", "установи интернов", "interns не работает", "interns isn't working", or whenever the `mcp__interns__*` tools are missing in a session that needs delegation. Cross-platform — Windows / Linux / macOS. Mutates user-level config and writes secrets; pauses for confirmation before every write. --- # setup-interns @@ -27,7 +27,7 @@ Reference: full design lives in this repo at `.wiki/concepts/interns-design.md` ## Hard rule: don't auto-mutate config -The procedure runs `pip install`, writes `~/projects/.common/secrets/interns.env` (carries endpoint API keys), and edits `~/.claude.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 grants permission to inspect, not to install or write secrets. +The procedure runs `pip install`, writes `~/.config/projects-secrets/interns.env` (carries endpoint API keys), and edits `~/.claude.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 grants permission to inspect, not to install or write secrets. ## Procedure @@ -39,7 +39,7 @@ The procedure runs `pip install`, writes `~/projects/.common/secrets/interns.env - (Optional, recommended) Pre-warm the repomix binary: `npx --yes repomix@latest --version`. This caches the package so the first real `repo_read` call is instant (5–10s first-run penalty avoided). Skip silently on failure — the call will just be slower the first time. - Confirm network reachability to the configured endpoints (default: `https://ollama.com/v1`). On HTTP 401 / 403 later, the API key is dead — stop and ask for a new one. - Confirm `git` is on `PATH` (needed for clone-fallback in Phase 4 if the source isn't already present). -- Pick paths: `~/projects/.common/lib/interns-mcp/` (source), `~/projects/.common/config/interns/config.yaml` (catalog), `~/projects/.common/secrets/interns.env` (keys, gitignored), `~/.claude.json` (MCP registration). POSIX-style paths resolve correctly under git-bash on Windows. +- Pick paths: `~/projects/.common/lib/interns-mcp/` (source), `~/projects/.common/config/interns/config.yaml` (catalog), `~/.config/projects-secrets/interns.env` (keys, outside any git tree), `~/.claude.json` (MCP registration). POSIX-style paths resolve correctly under git-bash on Windows. ### Phase 1 — Discovery (read-only) @@ -68,7 +68,7 @@ Failed to clone/pull the common monorepo. Options: **Existing endpoint keys.** Look in priority order, per `api_key_env` name from the config: -1. `~/projects/.common/secrets/interns.env` (`=...` lines). +1. `~/.config/projects-secrets/interns.env` (`=...` lines). 2. Process env (`os.environ[]`). 3. `~/.config/projects-mcp/auth.toml` — only if the user has explicitly noted the key is shared with another local MCP server (rare). @@ -76,8 +76,6 @@ The first hit wins per key. **Never echo key values in chat.** **MCP registration.** Read `~/.claude.json` and check `mcpServers.interns`. Note the `command` and `args`. If args point at a stale interpreter, Phase 6 will fix it. -**Gitignore sanity.** Check `~/projects/.gitignore`. If `.common/secrets/` (or `.common/secrets/*.env`) is not listed, flag for Phase 2 — the skill will offer to add it before writing the file. - ### Phase 2 — Plan + confirm Present a single-block plan to the user: @@ -87,9 +85,8 @@ Source: Config: — endpoints: Missing keys: not yet present in interns.env | none> -Gitignore: MCP entry: -Backups: ~/.claude.json.bak-, ~/projects/.common/secrets/interns.env.bak- (if exists) +Backups: ~/.claude.json.bak-, ~/.config/projects-secrets/interns.env.bak- (if exists) ``` Wait for explicit confirmation ("ok", "go", "поехали"). Anything else → stop. @@ -103,7 +100,7 @@ Copy each file we will modify to `.bak-YYYYMMDD-HHMMSS`: ```bash TS=$(date +%Y%m%d-%H%M%S) [ -f ~/.claude.json ] && cp ~/.claude.json ~/.claude.json.bak-$TS -[ -f ~/projects/.common/secrets/interns.env ] && cp ~/projects/.common/secrets/interns.env ~/projects/.common/secrets/interns.env.bak-$TS +[ -f ~/.config/projects-secrets/interns.env ] && cp ~/.config/projects-secrets/interns.env ~/.config/projects-secrets/interns.env.bak-$TS ``` Confirm both backups exist (when their source existed) before any further edit. @@ -141,21 +138,14 @@ python -c "import interns_mcp; print(interns_mcp.__file__)" If import fails — abort. Ask the user to paste the `pip install` output so the failure mode is visible. -### Phase 5 — Write `interns.env` + gitignore +### Phase 5 — Write `interns.env` -If Phase 1 flagged a missing `.gitignore` rule, append it first: - -``` -# interns endpoint API keys -.common/secrets/*.env -``` - -Then write `~/projects/.common/secrets/interns.env`. Per-key behavior: +Write `~/.config/projects-secrets/interns.env` (parent dir `mkdir -p ~/.config/projects-secrets` if missing). The file lives outside any git tree, so no `.gitignore` rule is needed. Per-key behavior: - Existing key in the file with a non-empty value — leave it alone. - Missing key — append `=` if the user pasted one, or `=` (blank) if the user skipped. A blank entry will fail at runtime with a clear `KeyError`; that's acceptable for the "I'll fill it later" path. -Permissions: on Linux / macOS run `chmod 600 ~/projects/.common/secrets/interns.env`. On Windows the default ACL is per-user, no extra step. +Permissions: on Linux / macOS run `chmod 600 ~/.config/projects-secrets/interns.env`. On Windows the default ACL is per-user, no extra step. ### Phase 6 — Register in `~/.claude.json` @@ -173,7 +163,7 @@ Edit `~/.claude.json`. Add or update the `mcpServers.interns` block: } ``` -`cwd` is set so the runtime resolves `.common/config/interns/config.yaml` and `.common/secrets/interns.env` relative to the `~/projects` base directory regardless of where Claude Code was launched. On Windows, expand `~/projects` to the absolute path (e.g. `C:/Users//projects`). +`cwd` is set so the runtime resolves `.common/config/interns/config.yaml` relative to the `~/projects` base directory regardless of where Claude Code was launched. Secrets are loaded from `~/.config/projects-secrets/interns.env` (overridable via `INTERNS_SECRETS_PATH` env var) — independent of `cwd`. On Windows, expand `~/projects` to the absolute path (e.g. `C:/Users//projects`). Absolute interpreter path comes from Phase 0 (`sys.executable`). Forward slashes work in JSON on Windows without escaping. @@ -209,7 +199,7 @@ registration binds to a fresh stdio session. After restart: • mcp__interns__* tools serve from -m interns_mcp.server • Source at ~/projects/.common/lib/interns-mcp/ - • Endpoint keys live in ~/projects/.common/secrets/interns.env (gitignored) + • Endpoint keys live in ~/.config/projects-secrets/interns.env (outside any git tree) • Config catalog at ~/projects/.common/config/interns/config.yaml • Backups saved at ~/.claude.json.bak- (and interns.env.bak- if it existed before) @@ -227,7 +217,7 @@ If something breaks after restart: If a problem surfaces (now or after restart): 1. Stop. Don't try to fix forward. -2. Find the most recent `.bak-YYYYMMDD-HHMMSS` next to `~/.claude.json` (and `~/projects/.common/secrets/interns.env` if applicable). +2. Find the most recent `.bak-YYYYMMDD-HHMMSS` next to `~/.claude.json` (and `~/.config/projects-secrets/interns.env` if applicable). 3. `cp .bak- ` for each. 4. Optional: `pip uninstall interns-mcp` if you want to remove the editable install. 5. Optional: `rm -rf ~/projects/.common/lib/interns-mcp` if you want to remove the cloned source. @@ -254,7 +244,6 @@ Path forms (`~/projects/.common/...`, `~/.config/...`, `~/.claude.json`) are ide - **Pinning `python` instead of ``.** A bare `python` in the MCP `command:` resolves to whatever interpreter is first on `PATH` at session start — often a different env without the `interns_mcp` module. Always use the absolute interpreter path captured in Phase 0. - **Forgetting `cwd: ~/projects`.** Without it the runtime can't find `.common/config/interns/config.yaml` and bombs at startup with a config-not-found error that looks like a Claude Code bug. - **Writing `.env` with `0644` perms on Linux/macOS.** Token leak. Always `chmod 600` after write. -- **Missing the gitignore rule.** Tokens commit to the repo on the next `git add .`. Always check `.gitignore` covers `.common/secrets/*.env` before writing — Phase 5 does it but it's worth double-checking. - **Treating in-session smoke test as proof.** Same as the context7 / projects-meta caveat — the active MCP connection was bound at session start. Real verification happens after restart. - **Auto-running on every "use interns".** This skill is intrusive. Trigger only on explicit "install / set up / configure interns", or when MCP tools are missing and the user is blocked. - **Cloning over an existing source directory.** If `~/projects/.common/lib/interns-mcp/` already exists with `pyproject.toml`, don't clone — use what's there. Clone is only for the "source not found" case. diff --git a/skills/using-interns/SKILL.md b/skills/using-interns/SKILL.md index c5afdfa..2f7ee8a 100644 --- a/skills/using-interns/SKILL.md +++ b/skills/using-interns/SKILL.md @@ -1,6 +1,6 @@ --- name: using-interns -version: 0.2.0 +version: 0.2.1 description: Use when delegating predictable bulk reads or summarization to cheap intern LLMs via the local `interns` MCP server (`mcp__interns__bulk_text_read`, `mcp__interns__transcript_distill`, etc.) so Claude saves Anthropic quota. Activated by `delegate to interns when allowed` in CLAUDE.md or explicit phrases like "use interns", "delegate to an intern", "разреши интернов", "allow interns". Per-session permission grant mirrors `project-discipline` Rule 4: ask-mode default, conversational grant / revoke, always-ask paths for `.env` / secrets / keys / SSH / credentials even with active grant, transitive rule (Claude can't bypass by reading the file itself and forwarding content), session-end reset. Skip for architecture, debugging, auth / payments, final commit messages, or final user-facing text. --- @@ -22,7 +22,7 @@ All currently run on Ollama Cloud (`deepseek-v4-flash`, ~$0.002 / call). Adding ## Prerequisites -This skill assumes `mcp__interns__*` tools are available. If they aren't (tools missing from the session, or calls fail with a connection error), the server isn't running for this session. Trigger the **`setup-interns`** skill to `pip install -e` the runtime, write `.common/secrets/interns.env`, and register `mcpServers.interns` in `~/.claude.json`. It's a one-time procedure with confirmation gates. +This skill assumes `mcp__interns__*` tools are available. If they aren't (tools missing from the session, or calls fail with a connection error), the server isn't running for this session. Trigger the **`setup-interns`** skill to `pip install -e` the runtime, write `~/.config/projects-secrets/interns.env`, and register `mcpServers.interns` in `~/.claude.json`. It's a one-time procedure with confirmation gates. ## When to use @@ -79,7 +79,7 @@ The next session starts in ask-mode regardless of prior grants. Same reasoning a These never go to an intern silently, even when delegation is granted: - `**/.env`, `**/.env.*` -- `**/secrets/**` (including `.common/secrets/`, `~/.config/projects-mcp/`) +- `**/secrets/**`, `**/projects-secrets/**` (including `~/.config/projects-secrets/`, `~/.config/projects-mcp/`) - `**/credentials*`, `**/credentials.json` - `**/*.key`, `**/*.pem` - `**/.ssh/**`