From 6c96682c605839de0af59768e47d39eece0035b3 Mon Sep 17 00:00:00 2001 From: vitya Date: Thu, 30 Apr 2026 00:21:22 +0300 Subject: [PATCH] feat(skills): add setup-projects-meta + using-projects-meta pair MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wraps the local projects-meta-mcp stdio server with the validated split-pair pattern (setup-X / using-X), 4th application after context7 / wiki / tasks. setup-projects-meta — 8-phase install: clones server repo to ~/.local/projects-meta-mcp, builds, writes ~/.config/projects-mcp/auth.toml, clones shared wiki to ~/projects/projects-wiki/ (canon path; legacy ~/projects/.wiki is detected and migrated — old path caused the wiki-path-mismatch bug, fixed upstream in 621a69f), registers mcpServers.projects-meta in ~/.claude.json. Confirmation gates between discovery and writes. using-projects-meta — runtime policy: read tools (tasks_aggregate, knowledge_search, meta_status, ...) and mutation tools with mandatory two-step preview→confirm. Carries the local-first rule inline: for the current project read .tasks/ / .wiki/ from disk; MCP cache is for *other* projects only. Wiki concept page concepts/projects-meta-skills.md documents the design, the path-canon fix, and the round-trip task lifecycle across machines. Closes [projects-meta-skills] in claude-skills (created from DESKTOP-NSEF0UK via projects-meta-mcp). Co-Authored-By: Claude Opus 4.7 (1M context) --- .tasks/STATUS.md | 10 +- .tasks/projects-meta-skills.md | 49 +++++ .wiki/concepts/projects-meta-skills.md | 72 +++++++ .wiki/index.md | 1 + .wiki/log.md | 2 + dist/setup-projects-meta.skill | Bin 0 -> 7636 bytes dist/using-projects-meta.skill | Bin 0 -> 7077 bytes skills/setup-projects-meta/README.md | 98 ++++++++++ skills/setup-projects-meta/SKILL.md | 247 +++++++++++++++++++++++++ skills/using-projects-meta/README.md | 144 ++++++++++++++ skills/using-projects-meta/SKILL.md | 192 +++++++++++++++++++ 11 files changed, 810 insertions(+), 5 deletions(-) create mode 100644 .tasks/projects-meta-skills.md create mode 100644 .wiki/concepts/projects-meta-skills.md create mode 100644 dist/setup-projects-meta.skill create mode 100644 dist/using-projects-meta.skill create mode 100644 skills/setup-projects-meta/README.md create mode 100644 skills/setup-projects-meta/SKILL.md create mode 100644 skills/using-projects-meta/README.md create mode 100644 skills/using-projects-meta/SKILL.md diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index 8531bcc..e8cfcdd 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -1,5 +1,5 @@ # Task Board -_Updated: 2026-04-28_ +_Updated: 2026-04-29_ diff --git a/.tasks/projects-meta-skills.md b/.tasks/projects-meta-skills.md new file mode 100644 index 0000000..d157157 --- /dev/null +++ b/.tasks/projects-meta-skills.md @@ -0,0 +1,49 @@ +# projects-meta-skills + +## Goal +Ship a `setup-projects-meta` + `using-projects-meta` skill pair that wraps the local `projects-meta-mcp` server (cross-project task aggregation + shared Gitea-backed wiki). Mirrors the validated `setup-context7` / `using-context7` split: setup is one-time intrusive (clones repo, builds, writes `~/.config/projects-mcp/auth.toml`, clones shared wiki to `~/projects/projects-wiki/`, registers `mcpServers.projects-meta` in `~/.claude.json`), using is daily policy with auto-trigger on cross-project / shared-wiki questions and delegates to setup if `mcp__projects-meta__*` tools are missing. + +## Key files +- `skills/setup-projects-meta/SKILL.md` — 8-phase install (model: `skills/setup-context7/SKILL.md`) +- `skills/setup-projects-meta/README.md` — human-facing doc (model: `skills/setup-wiki/README.md`) +- `skills/using-projects-meta/SKILL.md` — runtime policy (model: `skills/using-context7/SKILL.md`) +- `skills/using-projects-meta/README.md` — human-facing doc (model: `skills/using-wiki/README.md`) +- `scripts/build.sh` — packages skills into `dist/.skill` +- `scripts/install.sh` — copies `skills//` → `~/.claude/skills//` + +## Wiki anchors (already in shared wiki) +- `packages/projects-meta-mcp` — full reference: paths, auth.toml, tools list, mutation pattern, sync runner +- `concepts/setup-using-skill-pair` — pattern: 8-phase setup-X structure, using-X structure, hard rules + +## Decisions log +- 2026-04-29: Use `setup-context7` as the structural template for `setup-projects-meta` — same 8-phase shape, same confirmation gates, same rollback section. Reason: pattern already validated end-to-end on context7 (see `feedback_split_policy_from_setup` memory). +- 2026-04-29: Use `setup-wiki/README.md` and `using-wiki/README.md` as the README templates — they're more thorough than the context7 pair (which has no READMEs). Adding READMEs upfront avoids re-opening the [skill-readmes] task later. +- 2026-04-29: `auth.toml` is the secret-bearing file; never echo `gitea_token` in chat. Edit/Write tool calls inevitably contain it (transcript) — that's OK; chat output must not. +- 2026-04-29: `~/.claude.json` `mcpServers.projects-meta` registration uses absolute path to `dist/server.js` (Win path: `C:/Users//.local/projects-meta-mcp/dist/server.js`). Forward slashes work on all three platforms. +- 2026-04-29: Smoke test in setup phase 7 = `mcp__projects-meta__meta_status` (read-only, returns sync diagnostics). Caveat: in-session smoke only proves "MCP still alive", not "new registration is what's serving" — same caveat as context7. +- 2026-04-29: Mutation tools (`tasks_*`, `knowledge_*`) follow two-step preview→confirm pattern; `using-projects-meta` documents the pattern and forbids inlining `confirm: true` without explicit user "ok". +- 2026-04-29: Both skills shipped v1.0.0; `setup-projects-meta` description carries Russian + English triggers ("install/set up/configure projects-meta", "настрой/установи projects-meta", "...не работает / isn't working") same shape as setup-context7; `using-projects-meta` description prioritizes cross-project / shared-wiki triggers and explicitly tells the harness to skip for current-project state. +- 2026-04-30: After user prodded "почему ты pull не сделал в самом начале?", explicit `git pull` on `~/projects/projects-wiki` revealed `wiki-path-mismatch-resolution.md` — canon path changed from `~/projects/.wiki` (write/read mismatch bug) to `~/projects/projects-wiki/` (clone root) with content at `~/projects/projects-wiki/.wiki/`. Fixed all six places in the new skills (setup SKILL+README, using SKILL+README, concept page, this task file). Phase 1 of setup-projects-meta now detects legacy clone; Phase 4 re-clones to canon. Lesson saved as feedback memory `pull_shared_wiki_explicitly`. + +## Open questions +- [ ] `project-bootstrap` Step for `setup-projects-meta`? — concept page says "may be added later as 'recommend installing projects-meta'". Decision: defer, separate task. +- [ ] Should `using-projects-meta` carry its own `Local-first rule` or just point to the wiki anchor? Decision: carry it inline — concept page says "for the **current** project read locally; MCP cache is for **other** projects". Critical enough to repeat. + +## Completed steps +- [x] Read `setup-context7` + `using-context7` SKILL.md as templates +- [x] Fetch `packages/projects-meta-mcp` + `concepts/setup-using-skill-pair` via `knowledge.get` +- [x] Inspect `scripts/build.sh` + `scripts/install.sh` + skill folder layouts (setup-context7 = SKILL.md only; setup-wiki = SKILL.md + README.md) +- [x] Promote task to 🔴 in STATUS.md +- [x] Draft `skills/setup-projects-meta/SKILL.md` (8-phase, model setup-context7) +- [x] Draft `skills/using-projects-meta/SKILL.md` (model using-context7, local-first rule + two-step mutation) +- [x] Write README.md for both skills (model: setup-wiki / using-wiki) +- [x] `bash scripts/build.sh setup-projects-meta using-projects-meta` → both archives in `dist/` +- [x] `bash scripts/install.sh ...` → both installed to `~/.claude/skills/` +- [x] Smoke: both skills visible in `Skill` tool listing in this session +- [x] Wiki: `concepts/projects-meta-skills.md` added; `index.md` + `log.md` updated +- [x] Closed task in STATUS.md (🟢 done); next step is round-trip close via `mcp__projects-meta__tasks_close target_project=claude-skills` to mirror state to Gitea + +## Notes +- Wiki anchors live in shared `projects-wiki` Gitea repo (`https://git.kzntsv.site/OpeItcLoc03/projects-wiki`), cloned to `~/projects/projects-wiki/.wiki` on this machine. +- Original task created from another workstation (`OpeItcLoc03@DESKTOP-NSEF0UK`) via `mcp__projects-meta__tasks_create` — closing it should use `mcp__projects-meta__tasks_close target_project=claude-skills` to round-trip back to the same Gitea board. +- After install, restart Claude Code is required for the new MCP tool registrations to bind to a fresh stdio session — same caveat as setup-context7. diff --git a/.wiki/concepts/projects-meta-skills.md b/.wiki/concepts/projects-meta-skills.md new file mode 100644 index 0000000..1b093f3 --- /dev/null +++ b/.wiki/concepts/projects-meta-skills.md @@ -0,0 +1,72 @@ +--- +title: "projects-meta-skills: setup + using pair for projects-meta-mcp" +type: concept +updated: 2026-04-29 +--- + +# projects-meta-skills: setup + using pair for projects-meta-mcp + +_2026-04-29._ + +## What got built + +A split skill pair for the local `projects-meta-mcp` stdio server (cross-project task aggregation + shared Gitea wiki): + +- [`skills/setup-projects-meta/`](../../skills/setup-projects-meta/) — one-time install: clones the server repo, builds it, writes `~/.config/projects-mcp/auth.toml`, clones the shared wiki to `~/projects/projects-wiki/` (canon path; legacy `~/projects/.wiki` is migrated), registers `mcpServers.projects-meta` in `~/.claude.json`. Eight phases, confirmation gates between Phase 1↔2 and before Phase 3. +- [`skills/using-projects-meta/`](../../skills/using-projects-meta/) — runtime policy: read tools (`tasks_aggregate`, `knowledge_search`, `meta_status`, …) and mutation tools (`tasks_create`, `knowledge_ingest`, …) with mandatory two-step preview → confirm. Carries the **local-first rule** inline: for the *current* project, read `.tasks/` / `.wiki/` from disk; MCP cache is for *other* projects only. + +Both skills v1.0.0, build artifacts in `dist/`, installed to `~/.claude/skills/`. + +## Why split (recap) + +Same reason as [context7-setup.md](context7-setup.md): + +- **Setup** is intrusive (writes secrets, edits `~/.claude.json`, clones repos), one-time per machine, never auto-trigger. +- **Using** is daily policy, auto-triggers on cross-project / shared-wiki phrases. + +Mixing them dilutes the policy skill's description (worse triggering) and pulls install procedure into context every time the user asks "what's on the boards". + +## Pattern reference + +`mcp__projects-meta__knowledge_get slug=concepts/setup-using-skill-pair` — full pattern doc in the shared wiki, written by another machine in the fleet ahead of this build. The 8-phase setup-X structure documented there is exactly what `setup-projects-meta/SKILL.md` follows; the using-X structure is exactly what `using-projects-meta/SKILL.md` follows. + +The pattern is now used in claude-skills three times: `context7`, `wiki`, `tasks`, `projects-meta`. Templated enough that the next setup-X / using-X pair can be produced from these four exemplars in one pass. + +## Local-first rule (decision) + +Concept page calls it out, but it's load-bearing enough to put inline in `using-projects-meta/SKILL.md`: + +| Question | Where to read | +|---|---| +| "What's the status of *this* project?" | local `.tasks/STATUS.md` | +| "What's on all my boards?" | `mcp__projects-meta__tasks_aggregate` | +| "Has *this* project's wiki got X?" | local `.wiki/index.md` | +| "Has the **shared** wiki got X?" | `mcp__projects-meta__knowledge_search` | + +Without this rule, the agent burns latency on a stale MCP cache for state that's six lines away on disk. + +## Mutation pattern (decision) + +All five mutation tools (`tasks_create / update / close`, `knowledge_ingest / promote`) follow strict two-step: + +1. Call without `confirm: true` → dry-run preview. +2. Show preview to user; wait for "ok" / "go" / "поехали". +3. Re-call with `confirm: true` → committed to Gitea. + +Documented in `using-projects-meta/SKILL.md` "Mutate (always two-step)" + "Common mistakes" rows. Forbidden inlining of `confirm: true` is the same hard rule as setup-X's "no auto-mutate of user config". + +## Cross-platform + +Skills are platform-agnostic. Only auxiliary tooling (JSON validate, timestamp gen, `chmod 600` on auth.toml — Linux/macOS only) differs. POSIX paths (`~/.local/...`, `~/.config/...`, `~/projects/...`) work identically under git-bash on Windows. + +## Path canon (caught after first draft) + +Initial draft used `~/projects/.wiki` for the shared wiki clone — the path the wiki anchor still documented. A fresh `git pull` of `projects-wiki` (after the user pointed out we'd skipped pull on session start) revealed [wiki-path-mismatch-resolution](https://git.kzntsv.site/OpeItcLoc03/projects-wiki) — the canon is now `~/projects/projects-wiki/` (clone root), with content at `~/projects/projects-wiki/.wiki/`. Reason: the MCP writer wrote to `/.wiki//.md` while the reader walked `//...` — under the old `~/projects/.wiki` clone the writer's output was invisible to reads. Fixed in upstream commit `621a69f` (branch `fix/wiki-path-mismatch`). + +Both `setup-projects-meta` and `using-projects-meta` now write the canon path. `setup-projects-meta` Phase 1 detects a legacy clone; Phase 4 re-clones to canon and leaves the legacy dir for the user to inspect / delete. + +This is a meta-lesson: **always pull shared/multi-machine resources before relying on cached anchors**. Saved as a feedback memory. + +## Round-trip note + +The task `[projects-meta-skills]` was created on a different machine (`OpeItcLoc03@DESKTOP-NSEF0UK`) via `mcp__projects-meta__tasks_create target_project=claude-skills`. Closing it on this machine via `mcp__projects-meta__tasks_close target_project=claude-skills slug=projects-meta-skills` round-trips back to the same Gitea board — both sides see the 🟢 done state. First end-to-end multi-machine task lifecycle in the fleet. diff --git a/.wiki/index.md b/.wiki/index.md index 0c7a314..855f924 100644 --- a/.wiki/index.md +++ b/.wiki/index.md @@ -16,6 +16,7 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever - [build-notes.md](concepts/build-notes.md) — why `build.ps1` exists alongside `build.sh`; PS 5.1 backslash-in-zip gotcha; how to extract a `.skill` - [install-portability.md](concepts/install-portability.md) — `install.sh` / `build.sh` rewritten to drop `mapfile` (bash 4+) and `find -printf` (GNU only) so stock macOS (bash 3.2 + BSD find) works - [context7-setup.md](concepts/context7-setup.md) — switched context7 from manual MCP entries to the official plugin; API key in `.mcp.json` as `--api-key`; now also captured as `setup-context7` skill (one-time install/migrate flow with key discovery) +- [projects-meta-skills.md](concepts/projects-meta-skills.md) — `setup-projects-meta` + `using-projects-meta` skill pair for the local `projects-meta-mcp` stdio server (cross-project tasks + shared Gitea wiki); local-first rule + two-step mutation pattern - [repo-layout.md](concepts/repo-layout.md) — flat `skills/`, committed `dist/`, bash + PowerShell scripts; install model - [skill-versioning.md](concepts/skill-versioning.md) — why infra skills carry `version: ` in frontmatter and how `project-bootstrap` records them in a per-project manifest - [skill-vs-plugin.md](concepts/skill-vs-plugin.md) — when a bare SKILL.md is enough vs when you actually need a plugin (slash commands, hooks, sub-agents, MCP servers); concrete breakdown of `superpowers` diff --git a/.wiki/log.md b/.wiki/log.md index abc459a..398b124 100644 --- a/.wiki/log.md +++ b/.wiki/log.md @@ -28,5 +28,7 @@ Parseable: `grep "^## \[" .wiki/log.md | tail -20`. ## [2026-04-28] refactor | this repo's `.tasks/` migrated to canonical layout — flat `## Done`/`## Backlog` replaced by emoji-status board (7 ⚪ Ready blocks); historical Done entries dropped (preserved in git log); `.bak` ignored via .gitignore ## [2026-04-28] cleanup | removed stale `~/.claude/skills/{wiki-maintainer,task-status-wiki}/` installs (replaced by `using-wiki`/`using-tasks`); 16 skills installed, no duplicates; context7 plugin (mcp__plugin_context7_context7__*) confirmed live after restart ## [2026-04-28] decision | install-portability — `install.sh`/`build.sh` patched to drop `mapfile`+`find -printf`; stock macOS (bash 3.2 + BSD find) now works; verified on git-bash (16 skills discovered, sorted, installed; build.sh produces archive) +## [2026-04-29] decision | projects-meta-skills — built `setup-projects-meta` (8-phase install of projects-meta-mcp + auth.toml + MCP registration) and `using-projects-meta` (runtime policy with local-first rule and two-step mutation); skill pair pattern applied for the 4th time (context7 / wiki / tasks / projects-meta); both built + installed; visible to the harness +## [2026-04-30] refactor | projects-meta-skills — wiki path canon corrected: `~/projects/.wiki` → `~/projects/projects-wiki/` (clone root), content at `~/projects/projects-wiki/.wiki/`. Old path caused write/read mismatch bug (fixed upstream in commit `621a69f` of `projects-meta-mcp`). Setup-projects-meta Phase 1 now detects legacy clone, Phase 4 re-clones to canon. Lesson: pull shared resources before relying on cached anchors ## [2026-04-28] decision | project-bootstrap@1.1.0 — added Step 5.6: detects `superpowers@claude-plugins-official` via `~/.claude/plugins/installed_plugins.json` and prints install command + upstream link if missing; chat-only, never auto-installs (slash commands aren't callable from a skill, and silent plugin install is overreach) ## [2026-04-28] doc | README.md + README.ru.md — new "Using skills in projects" / "Использование в проектах" section after install quick-start; describes project-bootstrap workflow (git, .gitignore, README, .wiki/, .tasks/, CLAUDE.md, manifest, superpowers-plugin check) and the init/upgrade modes diff --git a/dist/setup-projects-meta.skill b/dist/setup-projects-meta.skill new file mode 100644 index 0000000000000000000000000000000000000000..f80a627f83d3a9536ef05931b6e10d814d8fad40 GIT binary patch literal 7636 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 Y|E(ja$Rhy%wGI1Eru|c&iT~C87r-us9smFU literal 0 HcmV?d00001 diff --git a/skills/setup-projects-meta/README.md b/skills/setup-projects-meta/README.md new file mode 100644 index 0000000..a125071 --- /dev/null +++ b/skills/setup-projects-meta/README.md @@ -0,0 +1,98 @@ +# setup-projects-meta + +One-time skill that brings up the local `projects-meta-mcp` stdio server on a +new (or freshly broken) machine. Clones the server repo, builds it, writes +`~/.config/projects-mcp/auth.toml` with the user's Gitea token, clones the +shared wiki to `~/projects/projects-wiki/.wiki`, and registers `mcpServers.projects-meta` +in `~/.claude.json`. + +The runtime policy for *using* the resulting tools lives in +[`using-projects-meta`](../using-projects-meta/) — `setup-projects-meta` is the +only place that touches user-level config or installs the server. + +`projects-meta-mcp` reference (full): +`mcp__projects-meta__knowledge_get slug=packages/projects-meta-mcp` + +## When it triggers + +- User says: "install projects-meta", "set up projects-meta", "configure projects-meta", + "настрой projects-meta", "установи projects-meta", "projects-meta не работает", + "projects-meta isn't working". +- [`using-projects-meta`](../using-projects-meta/) detects missing + `mcp__projects-meta__*` tools and delegates here via its Prerequisites + section. +- A new machine in the multi-machine fleet — install once per machine. + +## What it installs + +| Path | Role | +|---|---| +| `~/.local/projects-meta-mcp/` | server repo (cloned from Gitea) | +| `~/.local/projects-meta-mcp/dist/server.js` | built stdio entry point | +| `~/.config/projects-mcp/auth.toml` | Gitea credentials (token-bearing) | +| `~/.cache/projects-mcp/tasks.json` | aggregated tasks cache | +| `~/projects/projects-wiki/` | shared wiki clone root (Gitea repo `projects-wiki`) | +| `~/projects/projects-wiki/.wiki/` | wiki content root (read by MCP server) | +| `~/.claude.json` (`mcpServers.projects-meta`) | MCP registration | + +## Hard rules + +- **Never auto-mutate.** Phase 1 (discovery) and Phase 2 (plan) always pause + for explicit confirmation. A trigger phrase grants permission to inspect, + not to clone or write secrets. +- **Never echo the Gitea token in chat.** Edit / Write tool calls inevitably + contain it (that's how it lands in `auth.toml`); chat output must not. +- **Never clone over an unrelated `~/projects/projects-wiki/` (or legacy `~/projects/.wiki`).** + If either path exists with a non-matching `origin`, stop and ask — the user + may have an unrelated wiki there. +- **Don't use the legacy `~/projects/.wiki` path.** It's deprecated — the MCP + server's `loadWiki` reads from `~/projects/projects-wiki/.wiki//...`, + while writes to `~/projects/.wiki/.wiki/...` would be invisible. Phase 4 + detects a legacy clone and migrates to the canon path. +- **Always `chmod 600` `auth.toml` on Linux / macOS.** Token leak otherwise. + +## Procedure (high-level) + +1. **Phase 0** — environment sanity (Node ≥ 18, git, npm, network to Gitea). +2. **Phase 1** — discovery (token / repo / wiki clone / MCP registration / cache). +3. **Phase 2** — plan + confirm. Wait for explicit "ok"/"go"/"поехали". +4. **Phase 3** — backup (`~/.claude.json`, existing `auth.toml`). +5. **Phase 4** — clone / pull repo + `npm install && npm run build`; clone + shared wiki if absent. +6. **Phase 5** — write `~/.config/projects-mcp/auth.toml` with `gitea_token`. +7. **Phase 6** — register `mcpServers.projects-meta` in `~/.claude.json` with + absolute path to `dist/server.js`. +8. **Phase 7** — smoke test (`mcp__projects-meta__meta_status`) + `node dist/sync.js` + to populate the cache. +9. **Phase 8** — restart guidance + final report. + +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 `~/.config/projects-mcp/auth.toml`. +3. Optional: `rm -rf ~/.local/projects-meta-mcp` and `rm -rf ~/.cache/projects-mcp`. + Keep `~/projects/projects-wiki/` — it's a useful clone regardless of MCP state. +4. Restart Claude Code. +5. Confirm `mcp__projects-meta__*` tools are gone (or back to the prior version). + +## Install + +From the repo root: + +```bash +bash scripts/install.sh setup-projects-meta +``` + +Works on Windows under git-bash, Linux, macOS. + +## See also + +- [`using-projects-meta`](../using-projects-meta/) — runtime policy for + cross-project task aggregation and shared-wiki query / ingest. +- [`setup-context7`](../setup-context7/) — companion pattern for the context7 + MCP plugin (similar 8-phase shape). +- [`setup-wiki`](../setup-wiki/), [`setup-tasks`](../setup-tasks/) — + per-project setup skills (in-repo `.wiki/` and `.tasks/`); orthogonal to + this skill, which sets up the cross-project layer. diff --git a/skills/setup-projects-meta/SKILL.md b/skills/setup-projects-meta/SKILL.md new file mode 100644 index 0000000..f24c507 --- /dev/null +++ b/skills/setup-projects-meta/SKILL.md @@ -0,0 +1,247 @@ +--- +name: setup-projects-meta +version: 1.0.0 +description: Installs and configures the local `projects-meta-mcp` stdio server — clones the repo to `~/.local/projects-meta-mcp`, builds it, writes `~/.config/projects-mcp/auth.toml` with the user's Gitea token, clones the shared wiki to `~/projects/projects-wiki/` (content lives at `~/projects/projects-wiki/.wiki/`), and registers `mcpServers.projects-meta` in `~/.claude.json`. Use this skill when the user says "install projects-meta", "set up projects-meta", "configure projects-meta", "настрой projects-meta", "установи projects-meta", "projects-meta не работает", "projects-meta isn't working", or whenever the `mcp__projects-meta__*` tools are missing in a session that needs cross-project task aggregation or the shared Gitea wiki. Cross-platform — Windows / Linux / macOS. Mutates user-level config and writes secrets; pauses for confirmation before every write. Includes a migration step for machines with an old `~/projects/.wiki` clone (deprecated path that caused the wiki-path-mismatch bug). +--- + +# setup-projects-meta + +> One-time skill that gets the local `projects-meta-mcp` server running with the user's Gitea credentials. Stops at confirmation gates because the procedure clones a repo, writes a secret-bearing TOML file, and edits `~/.claude.json`. + +Reference: full `projects-meta-mcp` docs live in the shared wiki at `packages/projects-meta-mcp` (fetch via `mcp__projects-meta__knowledge_get` once the server is up). + +## When to use + +- User explicitly asks: install / set up / configure projects-meta. +- A `using-projects-meta`-driven task fails because `mcp__projects-meta__*` tools aren't available. +- Migrating a stale install (token expired, repo moved, broken cache) — same procedure, Phase 1 detects what's already in place. +- New machine in the user's multi-machine fleet (recall: this is a cross-machine workflow). + +## Out of scope + +- Issuing or rotating Gitea tokens. This skill *uses* a token the user already has; if there's no token, point them at Gitea's settings page (`https://git.kzntsv.site/user/settings/applications`) and stop until they paste one. +- Running `projects-meta-mcp` itself (the MCP harness spawns it). +- Editing `.tasks/STATUS.md` or wiki content — that's `using-projects-meta` / `using-tasks` / `using-wiki`. +- Any other MCP server. + +## Hard rule: don't auto-mutate config + +The procedure clones a repo, writes `~/.config/projects-mcp/auth.toml` (carries the Gitea token), 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 is permission to run discovery, not permission to clone or write secrets. + +## Procedure + +### Phase 0 — Environment sanity + +- Confirm Claude Code is the current harness (need `mcpServers` registration in `~/.claude.json`). +- Confirm `git`, `node`, `npm` are on `PATH`. Node ≥ 18 (the server uses ES modules). +- Confirm network reachability to `https://git.kzntsv.site` (the Gitea host). On HTTP 401/403 later, the token is dead — stop and ask for a new one. +- Pick paths: `~/.local/projects-meta-mcp`, `~/.config/projects-mcp/`, `~/.cache/projects-mcp/`, `~/projects/projects-wiki/` (clone root; content at `~/projects/projects-wiki/.wiki/`). POSIX-style `~/...` resolves correctly under git-bash on Windows. + +**Path note (canon vs legacy).** The shared wiki clone target is `~/projects/projects-wiki/` (content under `.wiki/`). Earlier README versions said `git clone … ~/projects/.wiki` — that path is **deprecated** because it caused a write/read mismatch (writer wrote to `/.wiki//.md`, reader walked `//...`). Phase 1 detects the legacy path and Phase 4 migrates. + +### Phase 1 — Discovery (read-only) + +Search, in order. Report only "found at ", never echo token values. + +**Existing Gitea token.** Look in priority order: + +1. `~/.config/projects-mcp/auth.toml` → `gitea_token = "..."` +2. Env var `PROJECTS_META_GITEA_TOKEN` +3. Existing `~/.claude.json` → `mcpServers.projects-meta` block (rare; legacy installs sometimes inline `env.GITEA_TOKEN`) + +The first hit wins. Capture internally for Phase 5; **never echo it in chat**. + +**Repo install state.** Check whether `~/.local/projects-meta-mcp/.git` exists. If yes, `git -C ~/.local/projects-meta-mcp rev-parse HEAD` → record the SHA so Phase 4 can decide *clone* vs *pull*. + +**Build artifact.** Check `~/.local/projects-meta-mcp/dist/server.js`. If absent, Phase 4 will run `npm install && npm run build`. + +**Shared wiki clone.** Three states to detect: + +1. **Canon clone present** — `~/projects/projects-wiki/.git` exists, `git -C ~/projects/projects-wiki remote get-url origin` matches `https://git.kzntsv.site/OpeItcLoc03/projects-wiki(.git)?`. Phase 4 just `git pull`s. +2. **Legacy clone present** — `~/projects/.wiki/.git` exists with the right `origin`. The path is deprecated (caused the wiki-path-mismatch bug). Phase 4 will migrate: re-clone to `~/projects/projects-wiki/`, then offer to `rm -rf ~/projects/.wiki` once the user confirms there are no local commits or scratch files in there. +3. **Either path exists with a non-matching `origin`** — stop and ask. The user may have an unrelated wiki there. + +If neither path exists — Phase 4 clones fresh into `~/projects/projects-wiki/`. + +**MCP registration.** Read `~/.claude.json` and check `mcpServers.projects-meta`. Note the command + args. If args point at a stale path, Phase 6 will fix it. + +**Cache state.** List `~/.cache/projects-mcp/` (if it exists). Just for the report — don't rely on it. + +### Phase 2 — Plan + confirm + +Present a single-block plan to the user: + +``` +Token: | NOT FOUND — will ask> +Repo: | will clone> +Build artifact: +Wiki clone: +MCP entry: +Backups: ~/.claude.json.bak-, ~/.config/projects-mcp/auth.toml.bak- (if exists) +``` + +Wait for explicit confirmation ("ok", "go", "поехали"). Anything else → stop. + +If no token was found in Phase 1 — first ask: "Paste a Gitea personal access token (scope: `read:repository` for read-only, `write:repository` to enable mutations), or open `https://git.kzntsv.site/user/settings/applications` to create one." Don't proceed past Phase 2 without a token. + +### Phase 3 — Backup + +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 ~/.config/projects-mcp/auth.toml ] && cp ~/.config/projects-mcp/auth.toml ~/.config/projects-mcp/auth.toml.bak-$TS +``` + +Confirm both backups exist (when their source existed) before any further edit. The repo and wiki clones don't need backup — git is the backup. + +### Phase 4 — Clone + build + +```bash +# Server +if [ -d ~/.local/projects-meta-mcp/.git ]; then + git -C ~/.local/projects-meta-mcp pull --ff-only +else + git clone https://git.kzntsv.site/OpeItcLoc03/projects-meta-mcp ~/.local/projects-meta-mcp +fi +cd ~/.local/projects-meta-mcp +npm install +npm run build + +# Shared wiki — canon path is ~/projects/projects-wiki/ (content under .wiki/) +mkdir -p ~/projects +if [ -d ~/projects/projects-wiki/.git ]; then + git -C ~/projects/projects-wiki pull --ff-only +elif [ -d ~/projects/.wiki/.git ]; then + # Legacy path — re-clone to canon and let the user decide what to do with the old dir. + git clone https://git.kzntsv.site/OpeItcLoc03/projects-wiki ~/projects/projects-wiki + echo "Legacy clone at ~/projects/.wiki kept in place. Inspect for local changes; if clean, rm -rf it." +else + git clone https://git.kzntsv.site/OpeItcLoc03/projects-wiki ~/projects/projects-wiki +fi +``` + +Verify `~/.local/projects-meta-mcp/dist/server.js` exists after build. If not — abort, the build failed; ask the user to run `npm run build` manually and paste the output. + +### Phase 5 — Write `auth.toml` + +```bash +mkdir -p ~/.config/projects-mcp +``` + +If `~/.config/projects-mcp/auth.toml` already exists and Phase 1 found a valid `gitea_token` line — skip the write. Otherwise, write the file with the token captured in Phase 1 (or freshly pasted in Phase 2): + +```toml +gitea_url = "https://git.kzntsv.site" +gitea_user = "OpeItcLoc03" +gitea_token = "" +# meta_tasks_repo = "projects-tasks" # uncomment to override default +# meta_wiki_repo = "projects-wiki" # uncomment to override default +``` + +Permissions: on Linux / macOS run `chmod 600 ~/.config/projects-mcp/auth.toml`. On Windows the default ACL is per-user, no extra step. + +### Phase 6 — Register in `~/.claude.json` + +Edit `~/.claude.json`. Add or update the `mcpServers.projects-meta` block: + +```json +{ + "mcpServers": { + "projects-meta": { + "command": "node", + "args": ["/dist/server.js"] + } + } +} +``` + +Absolute path resolution: + +| Platform | `` | +|---|---| +| Windows | `C:/Users//.local/projects-meta-mcp` (forward slashes; works in JSON without escaping) | +| Linux | `/home//.local/projects-meta-mcp` | +| macOS | `/Users//.local/projects-meta-mcp` | + +After each edit, validate JSON: + +```bash +# Windows (git-bash) +powershell.exe -NoProfile -c "Get-Content '' -Raw | ConvertFrom-Json | Out-Null" +# Linux / macOS +jq empty +# fallback +python -c "import json; json.load(open(''))" +``` + +If validation fails → restore from `.bak-*` and abort. + +### Phase 7 — Smoke test (best-effort) + run initial sync + +Best-effort: call `mcp__projects-meta__meta_status`. If it returns a JSON blob with `synced_at` / `wiki_pages_count` — the server is reachable in *this* session. + +Then run a one-shot sync to populate the cache: + +```bash +cd ~/.local/projects-meta-mcp +node dist/sync.js +``` + +Expect a non-zero `projects_count` and a fresh `~/.cache/projects-mcp/tasks.json`. On 401 / 403 → token is wrong scope or expired; rotate via `https://git.kzntsv.site/user/settings/applications` and re-edit `auth.toml`. + +**Important caveat to relay to the user:** in the *same* session that just ran setup, the MCP server you're talking to is whatever was bound at session start. So a passing `meta_status` only proves "some projects-meta is alive" — not "the registration we just wrote is what's serving it". The real test is after Claude Code restart. + +### Phase 8 — Restart guidance + final report + +Tell the user: + +``` +✅ Setup complete. Restart Claude Code so the new mcpServers.projects-meta + registration binds to a fresh stdio session. + +After restart: + • mcp__projects-meta__* tools serve from ~/.local/projects-meta-mcp/dist/server.js + • Cache lives at ~/.cache/projects-mcp/tasks.json (refresh: node dist/sync.js) + • Shared wiki clone at ~/projects/projects-wiki/ (content at .wiki/) — `git -C ~/projects/projects-wiki pull --ff-only` for fresh anchors + • Backups saved at ~/.claude.json.bak- (and auth.toml.bak- if it existed before) + +If something breaks after restart: + • Restore from .bak-* and tell me — we'll roll back together. +``` + +## Rollback procedure + +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 `~/.config/projects-mcp/auth.toml` if applicable). +3. `cp .bak- ` for each. +4. Optional: `rm -rf ~/.local/projects-meta-mcp` and `rm -rf ~/.cache/projects-mcp`. Keep `~/projects/projects-wiki/` — it's a useful clone regardless of MCP state. +5. Restart Claude Code. +6. Confirm `mcp__projects-meta__*` is gone (or back to the pre-existing version). +7. Report what went wrong so we can fix the procedure. + +## Cross-platform notes + +The procedure is platform-agnostic. Only auxiliary tooling differs: + +| | JSON validate | Backup | Permissions on auth.toml | +|---|---|---|---| +| Windows (git-bash) | `powershell.exe -NoProfile -c "Get-Content '' -Raw \| ConvertFrom-Json \| Out-Null"` | `cp` | per-user ACL by default | +| Linux | `jq empty ` (or `python -c "import json; json.load(open(''))"`) | `cp` | `chmod 600` | +| macOS | same as Linux | `cp` | `chmod 600` | + +Path forms (`~/.local/...`, `~/.config/...`, `~/projects/...`) are identical on all three. + +## Common mistakes + +- **Skipping Phase 1.** "User just said 'install projects-meta' — let's go." No — find existing token / repo / wiki first; re-cloning over an existing install loses any local commits in the wiki. +- **Echoing the token.** It's a secret. Edit / Write tool calls inevitably contain it (that's how it gets into `auth.toml`), but no chat output should. +- **Cloning over an unrelated `~/projects/projects-wiki/` (or legacy `~/projects/.wiki`).** If either path exists with a different `origin`, stop. The user may have an unrelated wiki there. +- **Cloning to the legacy path `~/projects/.wiki`.** Path is deprecated — write/read mismatch bug. Always clone to `~/projects/projects-wiki/`. Phase 4 enforces this. +- **Writing `auth.toml` with `0644` perms on Linux/macOS.** Token leak. Always `chmod 600` after write. +- **Treating in-session `meta_status` as proof.** Same as the context7 caveat — the active MCP connection was bound at session start. +- **Auto-running on every "use projects-meta".** This skill is intrusive. Trigger only on explicit "install/setup/configure projects-meta", or when MCP tools are missing and the user is blocked. +- **Forgetting `node dist/sync.js`.** Without an initial sync, the cache is empty and `tasks_aggregate` returns nothing — the user thinks setup failed. diff --git a/skills/using-projects-meta/README.md b/skills/using-projects-meta/README.md new file mode 100644 index 0000000..4e3b9ee --- /dev/null +++ b/skills/using-projects-meta/README.md @@ -0,0 +1,144 @@ +# using-projects-meta + +Runtime policy for the local `projects-meta-mcp` stdio server. Two +responsibilities, one server: + +1. **Cross-project task aggregation** — reads / writes `.tasks/STATUS.md` in + any of the user's Gitea repos. +2. **Shared knowledge wiki** — query / ingest a single Gitea-backed wiki at + `~/projects/projects-wiki/.wiki/` (clone root: `~/projects/projects-wiki/`, + Gitea repo: `projects-wiki`). + +`using-projects-meta` governs *usage* of an installed server. Initial setup +(clone, build, `auth.toml`, MCP registration) is owned by +[`setup-projects-meta`](../setup-projects-meta/). + +Full server reference: +`mcp__projects-meta__knowledge_get slug=packages/projects-meta-mcp`. + +## When it triggers + +- User asks for cross-project state ("what's on the boards", "across all + projects", "что у меня на досках", "по всем проектам"). +- User wants to query / ingest the shared wiki ("check shared wiki", "search + projects-wiki", "ingest into shared wiki", "общая вики", "заингесть в общую"). +- User wants to create / update / close a task in *another* project from the + current cwd ("заведи в проекте X задачу", "close task Y in project Z"). +- User asks for sync diagnostics ("when did the cache last refresh", "are there + sync errors"). +- If `mcp__projects-meta__*` tools are missing, this skill delegates to + [`setup-projects-meta`](../setup-projects-meta/) before doing anything else. + +## Local-first rule (critical) + +For the **current** project — read disk directly (`.tasks/STATUS.md`, +`.wiki/index.md`). The MCP cache: + +- May be stale (sync runs only when triggered). +- Hides `🟢 done` by default. +- May not contain unpushed projects. + +Use MCP only for **other** projects, **other** machines, or the **shared** +wiki content. See the table below. + +| Question | Where to read | +|---|---| +| "What's the status of *this* project?" | local `.tasks/STATUS.md` | +| "What's on all my boards?" | `mcp__projects-meta__tasks_aggregate` | +| "Has *this* project's wiki got X?" | local `.wiki/index.md` | +| "Has the **shared** wiki got X?" | `mcp__projects-meta__knowledge_search` | +| "Sync state across machines?" | `mcp__projects-meta__meta_status` | + +## Two operation classes + +### Read (no confirmation) + +`tasks_aggregate`, `tasks_search`, `tasks_get`, `knowledge_search`, +`knowledge_get`, `knowledge_suggest_promote`, `meta_status` — all +side-effect-free. Call directly, cite the result. + +### Mutate (always two-step) + +`tasks_create`, `tasks_update`, `tasks_close`, `knowledge_ingest`, +`knowledge_promote` — write to Gitea. Procedure: + +1. Call **without** `confirm: true` → returns dry-run preview (proposed file + diff + commit message). +2. Show the preview to the user. Wait for explicit "ok" / "go" / "поехали". +3. Re-call with `confirm: true` → committed. + +**Never inline `confirm: true` on the first call.** A trigger phrase is +permission to plan, not to commit. + +## Tool quick reference + +### Read + +| Tool | Required args | Purpose | +|---|---|---| +| `mcp__projects-meta__tasks_aggregate` | — | All active tasks across cached projects | +| `mcp__projects-meta__tasks_search` | `query` | Substring search across slug + next_action | +| `mcp__projects-meta__tasks_get` | `project` | Raw STATUS.md of one project (cache snapshot) | +| `mcp__projects-meta__knowledge_search` | `query`; opt `domain`, `limit` | Shared-wiki search; default domain auto-detected from cwd | +| `mcp__projects-meta__knowledge_get` | `slug` | Full text of one wiki page | +| `mcp__projects-meta__knowledge_suggest_promote` | — | Local `.wiki/concepts/` candidates for shared promotion | +| `mcp__projects-meta__meta_status` | — | Sync diagnostics (cache age, project / page / error counts) | + +### Mutate (need `write:repository` Gitea scope) + +| Tool | Required args | Effect | +|---|---|---| +| `mcp__projects-meta__tasks_create` | `target_project`, `slug`, `description`, `next_action` | Append block to target's `.tasks/STATUS.md` via Gitea commit | +| `mcp__projects-meta__tasks_update` | `target_project`, `slug` + ≥1 mutable field | Sha-based optimistic lock; 422 on conflict | +| `mcp__projects-meta__tasks_close` | `target_project`, `slug` (+ opt `note`) | Marks task 🟢 done with identity-footer | +| `mcp__projects-meta__knowledge_ingest` | `target_project`, `type`, `slug`, `body` | Three commits: `/.md` + `index.md` + `log.md` | +| `mcp__projects-meta__knowledge_promote` | `target_project`, `slug`, `body` | Move `raw/.md` → `sources/.md` | + +`type` ∈ `entities` / `concepts` / `packages` / `sources` / `raw`. +`target_project` = Gitea repo name, or `_meta` (meta-tasks / meta-wiki repos +from `auth.toml`). + +## Common mistakes + +- **Reading current project's tasks via `tasks_get`.** Read `.tasks/STATUS.md` + on disk; the MCP cache is for *other* projects. +- **Inlining `confirm: true` on first call.** Always preview first; show user; + only then `confirm: true`. +- **Confusing the local `.wiki/` with the shared `projects-wiki`.** They are + two different stores. `using-wiki` operates on the local one; + `using-projects-meta` queries / ingests the shared one. +- **Acting on stale `tasks_aggregate`.** If `meta_status.age_seconds` > 3600, + either run `node dist/sync.js` (in `~/.local/projects-meta-mcp`) or warn the + user about staleness. +- **Vague `knowledge_search` queries.** "auth" returns noise. Multi-word, + specific queries return targeted snippets. +- **Wrong `type` on `knowledge_ingest`.** Mis-typed pages land in the wrong + section and break `index.md`. Pick from the five canonical types. + +## When NOT to use + +- The current project's own tasks — read `.tasks/STATUS.md`. +- The current project's own wiki — read `.wiki/`. +- Library / framework documentation — that's [`using-context7`](../using-context7/). +- Repo-internal code search — that's `Glob` / `Grep`. +- One-off git history questions — `git log`. + +## Install + +From the repo root: + +```bash +bash scripts/install.sh using-projects-meta +``` + +Works on Windows under git-bash, Linux, macOS. + +## See also + +- [`setup-projects-meta`](../setup-projects-meta/) — companion, owns server + install + MCP registration. +- [`using-context7`](../using-context7/) — sister skill for library docs (same + using-X structure). +- [`using-tasks`](../using-tasks/), [`using-wiki`](../using-wiki/) — + per-project policies for in-repo `.tasks/` and `.wiki/`. Orthogonal to this + skill; together they cover both per-project and cross-project state. diff --git a/skills/using-projects-meta/SKILL.md b/skills/using-projects-meta/SKILL.md new file mode 100644 index 0000000..c1a5898 --- /dev/null +++ b/skills/using-projects-meta/SKILL.md @@ -0,0 +1,192 @@ +--- +name: using-projects-meta +version: 1.0.0 +description: Use when working across multiple projects on one or many machines — cross-project task aggregation (`mcp__projects-meta__tasks_*`), shared Gitea-backed wiki query / ingest (`mcp__projects-meta__knowledge_*`), or sync diagnostics (`mcp__projects-meta__meta_status`). Triggers on phrases like "across all projects", "what's on the boards", "check shared wiki", "search projects-wiki", "ingest into shared wiki", "что у меня на досках", "по всем проектам", "общая вики", "cross-project status", or any time the user wants to see / mutate state in another repo than the current cwd. Mutation tools (`tasks_create`, `tasks_update`, `tasks_close`, `knowledge_ingest`, `knowledge_promote`) require two-step preview → confirm. Skip for the **current** project's tasks/wiki — those live on disk in `.tasks/` / `.wiki/` and are read directly. +--- + +# Using the projects-meta MCP server + +## Overview + +`projects-meta-mcp` is a local stdio MCP server. Two responsibilities: + +1. **Cross-project task aggregation** — parses `.tasks/STATUS.md` from every repo on the user's Gitea, caches them in `~/.cache/projects-mcp/tasks.json`. Read tools (`tasks_aggregate`, `tasks_search`, `tasks_get`) hit the cache. Mutations (`tasks_create`, `tasks_update`, `tasks_close`) commit back to Gitea with sha-based optimistic lock. +2. **Shared knowledge wiki** — single Gitea repo (`projects-wiki`) cloned at `~/projects/projects-wiki/` with content at `~/projects/projects-wiki/.wiki/`, structured as packages / concepts / entities / sources / raw. `knowledge_search` + `knowledge_get` for queries, `knowledge_ingest` + `knowledge_promote` for writes. + +Source of truth: Gitea (`https://git.kzntsv.site`, owner `OpeItcLoc03`). Cache and clone are local convenience. + +Full reference: `mcp__projects-meta__knowledge_get slug=packages/projects-meta-mcp`. + +## Prerequisites + +This skill assumes `mcp__projects-meta__*` 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-projects-meta`** skill to clone, build, write `auth.toml`, and register `mcpServers.projects-meta` in `~/.claude.json`. It's a one-time procedure with confirmation gates. + +## Local-first rule + +**For the current project — read disk directly.** `.tasks/STATUS.md` and `.wiki/` files in cwd are always fresher than the MCP cache. The cache: + +- May be stale (default sync runs only when triggered). +- Hides 🟢 done by default. +- May not contain locally-developed projects that aren't pushed to Gitea yet. + +Use MCP only for **other** projects, **other** machines, or **shared** wiki content. + +| Question | Where to read | +|---|---| +| "What's the status of *this* project?" | local `.tasks/STATUS.md` | +| "What's on all my boards?" | `mcp__projects-meta__tasks_aggregate` | +| "Has *this* project's wiki got a page on X?" | local `.wiki/index.md` + relevant file | +| "Has the **shared** wiki got a page on X?" | `mcp__projects-meta__knowledge_search` | +| "Sync state across machines?" | `mcp__projects-meta__meta_status` | + +## When to use + +- Cross-project task overview ("what am I working on across projects", "по всем проектам", "across the board"). +- Hopping into another repo's task state without cloning it ("what's the status of project X"). +- Querying the shared wiki for cross-cutting concepts (patterns, package references, design notes that apply to several repos). +- Ingesting a finished design / decision into the shared wiki so other machines / projects can see it. +- Creating a task in another project's `.tasks/STATUS.md` from the current repo (cross-project handoff). +- Sync diagnostics (when did the cache last refresh, are there errors, how many projects). + +## When NOT to use + +- The current project's own tasks or wiki — read disk. +- Anything inside a single project — `.tasks/.md` and `.wiki/.md` are always closer. +- One-off questions answered by `git log` or a single file. +- Library / framework documentation — that's `using-context7`. +- Code search — that's `Glob` / `Grep`. + +## Workflow + +### Read (no confirmation needed) + +``` +1. Identify what you need: cross-project tasks? shared wiki page? sync state? +2. Pick the right read tool (table below). +3. Cite the result with the source slug / project name. +``` + +### Mutate (always two-step) + +``` +1. Identify the mutation: tasks_create / tasks_update / tasks_close / knowledge_ingest / knowledge_promote. +2. Call the tool WITHOUT `confirm: true` → returns a dry-run preview (the proposed file diff and the Gitea commit message). +3. Show the preview to the user. Wait for explicit "ok" / "go" / "поехали". +4. Re-call with `confirm: true` to commit. +``` + +**Never inline `confirm: true` on the first call.** A trigger phrase ("create a task in project X") is permission to *plan*, not to *commit*. + +## Tool quick reference + +### Read tools + +| Tool | Required args | Purpose | +|---|---|---| +| `mcp__projects-meta__tasks_aggregate` | — | All active tasks across all cached projects | +| `mcp__projects-meta__tasks_search` | `query` | Substring search across slug + next_action | +| `mcp__projects-meta__tasks_get` | `project` | Raw STATUS.md of one project (cached snapshot) | +| `mcp__projects-meta__knowledge_search` | `query`; opt `domain`, `limit` | Shared-wiki search; auto-detects domain from cwd, pass `domain="all"` to disable | +| `mcp__projects-meta__knowledge_get` | `slug` | Full text of one wiki page (e.g. `packages/projects-meta-mcp`) | +| `mcp__projects-meta__knowledge_suggest_promote` | — | Local `.wiki/concepts/` candidates for shared-wiki promotion | +| `mcp__projects-meta__meta_status` | — | Sync diagnostics: cache age, project count, error count, page count | + +### Mutation tools (need `write:repository` Gitea scope; preview → confirm) + +| Tool | Required args | Effect | +|---|---|---| +| `mcp__projects-meta__tasks_create` | `target_project`, `slug`, `description`, `next_action` (+ opt `where_stopped`, `status`, `blocker`, `branch`, `source_project`) | Append block to `/.tasks/STATUS.md` via Gitea commit | +| `mcp__projects-meta__tasks_update` | `target_project`, `slug` + ≥1 of `where_stopped` / `next_action` / `blocker` / `branch` / `description` / `status` | Sha-based optimistic lock; 422 on conflict | +| `mcp__projects-meta__tasks_close` | `target_project`, `slug` (+ opt `note`) | Sets task to 🟢 done; appends identity-footer | +| `mcp__projects-meta__knowledge_ingest` | `target_project`, `type`, `slug`, `body` (+ opt `frontmatter`, `source_project`) | Three commits: `/.md` + `index.md` + `log.md`. `type` ∈ entities / concepts / packages / sources / raw | +| `mcp__projects-meta__knowledge_promote` | `target_project`, `slug`, `body` (+ opt `frontmatter`, `source_project`) | Move `raw/.md` → `sources/.md` with auto `raw_path` link | + +`target_project` is either a Gitea repo name, or `_meta` (the dedicated meta-tasks / meta-wiki repos from `auth.toml`). + +## Examples + +### Read example: cross-project status + +User: "что у меня на досках?" + +``` +1. mcp__projects-meta__tasks_aggregate + → 7 projects, 12 active tasks + +2. Group by project, summarize 1 line per active task. + Cite project name; if a task is stale (cache age > 1h), flag it. +``` + +### Read example: shared wiki query + +User: "есть ли в общей вики что-то про setup-using паттерн?" + +``` +1. mcp__projects-meta__knowledge_search + query: "setup-using skill pair pattern" + domain: "all" + → hits include concepts/setup-using-skill-pair + +2. mcp__projects-meta__knowledge_get + slug: "concepts/setup-using-skill-pair" + → full text + +3. Summarize, link with markdown to the slug. +``` + +### Mutation example: create cross-project task + +User: "заведи в проекте books задачу на миграцию `settings.json`" + +``` +1. mcp__projects-meta__tasks_create + target_project: "books" + slug: "settings-json-migration" + description: "<...>" + next_action: "<...>" + (no `confirm`) + → preview: proposed STATUS.md diff + commit message + +2. Show preview to user. + +3. User: "ok, go" + +4. mcp__projects-meta__tasks_create + (same args + confirm: true) + → committed to Gitea +``` + +### Mutation example: closing a cross-project task + +User: "close `[projects-meta-skills]` in claude-skills" + +``` +1. mcp__projects-meta__tasks_close + target_project: "claude-skills" + slug: "projects-meta-skills" + note: "" + (no `confirm`) + → preview + +2. User confirms. + +3. Re-call with confirm: true. +``` + +## Common mistakes + +| Mistake | Fix | +|---|---| +| Reading current project's tasks via `tasks_get` instead of disk | Read `.tasks/STATUS.md` directly. MCP is for *other* projects. | +| Inlining `confirm: true` on the first mutation call | Always preview first; show user; only then `confirm: true`. | +| Using `knowledge_search` for the project's own wiki | The shared wiki is a separate Gitea repo. Local `.wiki/` is in cwd. | +| Acting on a stale `tasks_aggregate` without checking `meta_status` | If `age_seconds` > 3600 the cache may be behind reality. Either run `node dist/sync.js` or warn the user. | +| Calling `knowledge_ingest` with the wrong `type` | `type` must be one of `entities` / `concepts` / `packages` / `sources` / `raw`. Mis-typed pages land in the wrong section and break `index.md`. | +| Vague `knowledge_search` queries ("auth", "config") | Specific multi-word queries return targeted snippets; vague ones return noise. | +| Forgetting `domain="all"` when searching across families | Default `domain` is auto-detected from cwd; use `"all"` if the wiki page lives in a different family. | + +## Red flags + +- "I'll just commit it directly" → no. Mutation tools have a preview step for a reason — silent writes to another repo are a recipe for drift. +- "The cache is fresh enough" → check `meta_status.age_seconds`. If it's >3600s and the user is about to act on the data, sync first. +- "I'll skip the wiki page" → if you're answering a cross-cutting question and there's no wiki page, that's a `knowledge_ingest` candidate. Surface it to the user.