Follow-up to 01bc714 — skills/project-bootstrap/ shipped v1.12.0
(template + Step 5.6 table row) but dist-hermes/ regen was forgotten.
Surfaced when build-hermes ran for the session-handoff mapping task.
Per project-discipline Rule 3 ("rebuild packaged artifact in same or
next commit"), shipping the regen now to keep dist-hermes/ coherent
with skills/.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
642 lines
25 KiB
Markdown
642 lines
25 KiB
Markdown
---
|
||
name: project-bootstrap
|
||
version: 1.12.0
|
||
description: >
|
||
Initializes or upgrades a project in the current folder: git, .gitignore, README.md,
|
||
.wiki/ using Karpathy's method, .tasks/ for task tracking, CLAUDE.md with skill triggers.
|
||
Creates remote Gitea repo and syncs projects-meta cache for greenfield projects.
|
||
Use this skill when the user says "initialize project", "bootstrap", "setup project",
|
||
"upgrade project", "add wiki", "add tasks", "start project", "set everything up",
|
||
"create new project", or launches the agent in a new folder and wants a full setup.
|
||
Trigger even if the user just says "let's start a project" or "set it all up".
|
||
---
|
||
|
||
# Project Bootstrap
|
||
|
||
Sets up a complete working environment for a monorepo project in one pass.
|
||
Operates in three modes: **greenfield-full** (new project + remote create), **add-remote**
|
||
(existing git without remote), and **upgrade** (existing project).
|
||
|
||
---
|
||
|
||
## Step 0 — Detect mode
|
||
|
||
Check what already exists in the current directory:
|
||
|
||
```bash
|
||
ls -la
|
||
git rev-parse --git-dir 2>/dev/null && echo "git:yes" || echo "git:no"
|
||
git remote get-url origin 2>/dev/null && echo "remote:yes" || echo "remote:no"
|
||
ls -A 2>/dev/null | grep -q . && echo "empty:no" || echo "empty:yes"
|
||
[ -d .wiki ] && echo "wiki:yes" || echo "wiki:no"
|
||
[ -d .tasks ] && echo "tasks:yes" || echo "tasks:no"
|
||
[ -f CLAUDE.md ] && echo "claude:yes" || echo "claude:no"
|
||
[ -f README.md ] && echo "readme:yes" || echo "readme:no"
|
||
```
|
||
|
||
Determine mode:
|
||
- **greenfield-full**: `git:no` + `empty:yes` — new project, will create remote
|
||
- **add-remote**: `git:yes` + `remote:no` — existing git, offer to create remote
|
||
- **upgrade**: otherwise — existing project, upgrade only
|
||
|
||
Show the user a summary in one block — what was found, what will be created:
|
||
|
||
```
|
||
Mode: greenfield-full (new project + remote create)
|
||
|
||
Found: (empty directory)
|
||
Create: git .wiki .tasks CLAUDE.md .gitignore README.md remote
|
||
```
|
||
|
||
Ask one question: "Looks right? Shall we proceed?" — and wait for confirmation.
|
||
**Create nothing before confirmation.**
|
||
|
||
---
|
||
|
||
## Step 1 — Git
|
||
|
||
If git is not initialized:
|
||
|
||
```bash
|
||
git init
|
||
```
|
||
|
||
### `.gitignore`
|
||
|
||
The template `assets/.gitignore.template` contains two parts:
|
||
|
||
1. Standard ignore rules (deps, build, env, IDE, OS, logs).
|
||
2. **Meta-isolation block** — `!`-inversions for `.claude/`, `.tasks/`, `.wiki/`,
|
||
`.brainstorm/`, `.archive/`, `.mcp/`, `.mcp.json`, `MEMORY.md`. This block
|
||
re-enables tracking of agent meta-paths in **own** repos against the
|
||
global `core.excludesFile` rule (`~/.config/git/ignore`) that hides them
|
||
from forks of upstream open-source. Without it, the `.tasks/`, `.wiki/`,
|
||
and `.claude/` directories created by Steps 3-5 would be invisible to git
|
||
on machines where the global excludesFile is configured, and the first
|
||
commit would be empty of agent obvyaska. Full design: workshop wiki
|
||
`concepts/meta-out-of-repo.md` (sections "Слой 2" and "Новые проекты").
|
||
|
||
Two cases:
|
||
|
||
- **`.gitignore` does not exist** — create from `assets/.gitignore.template`
|
||
(block included unconditionally).
|
||
- **`.gitignore` exists** — check for the marker line
|
||
`# AI обвеска — слой 2:` (substring match, case-sensitive). If absent →
|
||
append the meta-isolation block (with the marker comment) to the end of
|
||
the file, prefixed by a blank line if the file does not already end with
|
||
one. If present → leave the file untouched.
|
||
|
||
The block is **scoped to own projects**. The bootstrap skill currently has no
|
||
fork-of-upstream mode (greenfield-full creates a brand-new Gitea repo;
|
||
add-remote and upgrade operate on the user's own repos), so the block is
|
||
applied unconditionally in all current modes. If a fork-bootstrap mode is
|
||
ever added, the block must be **omitted** there — putting `!.claude/` etc.
|
||
into a fork's `.gitignore` would diverge from upstream's ignore rules.
|
||
|
||
---
|
||
|
||
## Step 1.5 — Remote create (greenfield-full / add-remote modes)
|
||
|
||
Only in **greenfield-full** or **add-remote** mode. Skip for upgrade mode.
|
||
|
||
### Prerequisites
|
||
|
||
Read `~/.config/projects-mcp/auth.toml` to get Gitea credentials:
|
||
|
||
```bash
|
||
# POSIX (Linux/macOS/git-bash):
|
||
source ~/.config/projects-mcp/auth.toml 2>/dev/null || true
|
||
# Windows PowerShell:
|
||
Get-Content ~/.config/projects-mcp/auth.toml | Select-String "base_url|token"
|
||
```
|
||
|
||
If auth file missing → stop and tell user: run `/setup-projects-meta` first.
|
||
|
||
### Validate project name
|
||
|
||
Current folder name becomes the repo name. Must be:
|
||
- **Latin only** — a-z, 0-9, hyphens
|
||
- **kebab-case** — lowercase, hyphens between words
|
||
- **Not a duplicate** — check via Gitea API
|
||
|
||
```bash
|
||
PROJECT_NAME=$(basename "$PWD")
|
||
# Validate: only latin alnum + hyphen, no leading/trailing hyphen
|
||
echo "$PROJECT_NAME" | grep -qE '^[a-z0-9]+(-[a-z0-9]+)*$' || {
|
||
echo "❌ Invalid project name: '$PROJECT_NAME'. Use latin kebab-case (e.g. 'my-project')."
|
||
exit 1
|
||
}
|
||
```
|
||
|
||
### Create repo via Gitea API
|
||
|
||
```bash
|
||
# Extract base_url and token from auth.toml (POSIX):
|
||
BASE_URL=$(grep "^base_url" ~/.config/projects-mcp/auth.toml | cut -d'"' -f2)
|
||
TOKEN=$(grep "^token" ~/.config/projects-mcp/auth.toml | cut -d'"' -f2)
|
||
|
||
# Create repo:
|
||
curl -X POST "$BASE_URL/api/v1/user/repos?token=$TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d "{\"name\":\"$PROJECT_NAME\",\"private\":false,\"auto_init\":false}"
|
||
```
|
||
|
||
On failure → stop and show error. Duplicate name = suggest rename or delete existing.
|
||
|
||
### Add remote and push
|
||
|
||
```bash
|
||
git remote add origin "$BASE_URL/$USER/$PROJECT_NAME.git"
|
||
git branch -M master
|
||
git push -u origin master
|
||
```
|
||
|
||
For **add-remote** mode (git exists, push local commits after adding remote):
|
||
```bash
|
||
git push -u origin master # or main if that's the current branch
|
||
```
|
||
|
||
---
|
||
|
||
## Step 2 — README.md
|
||
|
||
If it does not exist — create a minimal one:
|
||
|
||
```markdown
|
||
# <project folder name>
|
||
|
||
## About
|
||
<!-- Describe the project here -->
|
||
|
||
## Quick start
|
||
<!-- Instructions for running the project -->
|
||
```
|
||
|
||
If it exists — leave it untouched.
|
||
|
||
---
|
||
|
||
## Step 3 — .wiki/
|
||
|
||
**Delegate to the `setup-wiki` skill.** It handles greenfield creation, canon migration, and the no-op case (already canon) uniformly, with its own confirmation gate. Don't recreate the layout inline here — that's how drift happens.
|
||
|
||
If `setup-wiki` is not installed on this machine, **stop** and tell the user: project-bootstrap requires `setup-wiki` (and `setup-tasks`) installed. Don't fall back to ad-hoc creation.
|
||
|
||
**Reference (for context only — `setup-wiki` is the source of truth):** the canonical layout per Karpathy (gist: https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) and `using-wiki`:
|
||
|
||
```
|
||
.wiki/
|
||
CLAUDE.md ← schema: project-specific wiki conventions
|
||
index.md ← catalog of all pages (by type), updated on every ingest
|
||
log.md ← append-only op log: ## [YYYY-MM-DD] op | desc
|
||
overview.md ← single human-readable project overview
|
||
raw/
|
||
README.md ← raw/ is immutable; this file documents that
|
||
entities/ ← entity pages (people, services, modules) — empty .gitkeep
|
||
concepts/ ← concept / design decision pages — empty .gitkeep
|
||
packages/ ← package pages — empty .gitkeep
|
||
sources/ ← one summary per ingested source — empty .gitkeep
|
||
```
|
||
|
||
Page-level workflow (ingest, query, lint) and file formats are owned by the
|
||
`wiki-maintainer` skill. Bootstrap only lays the skeleton; the skill takes
|
||
over from there.
|
||
|
||
### `.wiki/CLAUDE.md` (schema)
|
||
|
||
```markdown
|
||
# Wiki Schema — <project name>
|
||
|
||
Project-specific wiki conventions. Read this before any wiki operation.
|
||
|
||
This wiki follows Karpathy's LLM Wiki pattern:
|
||
**https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f**
|
||
|
||
The `wiki-maintainer` skill enforces the workflow and file formats. This
|
||
file overrides the skill where they conflict.
|
||
|
||
## Page types
|
||
|
||
- `entities/` — discrete things the project tracks (people, services, modules).
|
||
- `concepts/` — recurring ideas, design decisions, gotchas.
|
||
- `packages/` — code packages this project produces or consumes.
|
||
- `sources/` — one summary page per ingested external doc; frontmatter carries `ingested:` and `raw_path:`.
|
||
- `overview.md` — single project-wide overview.
|
||
|
||
## Naming
|
||
|
||
- `kebab-case.md`, **Latin only**. Transliterate Cyrillic in filenames; keep the original title in the H1 + frontmatter.
|
||
|
||
## Domain conventions
|
||
|
||
<!-- Fill in as the project takes shape — what counts as an entity here, which packages exist, naming idioms specific to this codebase. -->
|
||
```
|
||
|
||
### `.wiki/index.md`
|
||
|
||
```markdown
|
||
# Wiki Index
|
||
|
||
Catalog of all wiki pages. One line per page, organized by type. The agent updates this on every ingest.
|
||
|
||
## Overview
|
||
|
||
- [overview.md](overview.md) — project overview
|
||
|
||
## Entities
|
||
|
||
<!-- (none yet) -->
|
||
|
||
## Concepts
|
||
|
||
<!-- (none yet) -->
|
||
|
||
## Packages
|
||
|
||
<!-- (none yet) -->
|
||
|
||
## Sources
|
||
|
||
<!-- (none yet) -->
|
||
```
|
||
|
||
### `.wiki/log.md`
|
||
|
||
```markdown
|
||
# Wiki Log
|
||
|
||
Append-only operation log. One entry per operation. Format:
|
||
|
||
\`\`\`
|
||
## [YYYY-MM-DD] <op> | <one-line description>
|
||
\`\`\`
|
||
|
||
Operations: `init`, `ingest`, `query`, `lint`, `refactor`, `decision`.
|
||
|
||
Parseable: `grep "^## \[" .wiki/log.md | tail -20`.
|
||
|
||
---
|
||
|
||
## [<today's date>] init | bootstrap empty wiki via project-bootstrap
|
||
```
|
||
|
||
### `.wiki/overview.md`
|
||
|
||
```markdown
|
||
# <project name> — overview
|
||
|
||
<!-- Replace with a high-level description: what this project does, who it's for, the main components. -->
|
||
```
|
||
|
||
### `.wiki/raw/README.md`
|
||
|
||
```markdown
|
||
# Raw Sources
|
||
|
||
**Immutable.** Read, never edit. The only allowed modification is appending a `> Status:` blockquote when the user explicitly asks for a status audit.
|
||
|
||
Place raw inputs here — articles, transcripts, PDFs, screenshots — exactly as they came in. The agent reads from `raw/`, writes summaries into `../sources/`, and never modifies raw files.
|
||
|
||
For large or path-sensitive sources that live outside the repo, register them here:
|
||
|
||
\`\`\`
|
||
- short-name → /absolute/path/to/source
|
||
\`\`\`
|
||
```
|
||
|
||
The empty subdirectories (`entities/`, `concepts/`, `packages/`, `sources/`)
|
||
each get a `.gitkeep` so git tracks them.
|
||
|
||
---
|
||
|
||
## Step 4 — .tasks/
|
||
|
||
**Delegate to the `setup-tasks` skill.** It handles greenfield creation, migration from flat STATUS.md, and the no-op case uniformly, with its own confirmation gate. Don't recreate the layout inline.
|
||
|
||
If `setup-tasks` is not installed, **stop** and tell the user — same rule as Step 3.
|
||
|
||
**Reference (for context only — `setup-tasks` is the source of truth):** the canonical layout is `.tasks/STATUS.md` (the board, with emoji status 🔴/🟡/⚪/🟢/🔵) plus `.tasks/<task-slug>.md` per active or paused task. The full pattern is documented in this repo at `.wiki/raw/setup-task-status-wiki.md`.
|
||
|
||
---
|
||
|
||
## Step 5 — CLAUDE.md
|
||
|
||
Two paths, picked by file presence:
|
||
|
||
### Init (file does not exist)
|
||
|
||
Create `CLAUDE.md` from `assets/CLAUDE.md.template`. Substitute the platform line
|
||
on non-Windows hosts (`we're on Linux` / `we're on macOS` instead of
|
||
`we're on Windows`).
|
||
|
||
### Upgrade (file exists) — idempotent merge
|
||
|
||
Treat the template as the canonical trigger set and reconcile the existing file
|
||
against it. Re-runs are no-ops once the file is in canon.
|
||
|
||
1. Read the existing `CLAUDE.md`.
|
||
2. For each non-empty, non-comment line in the template, decide whether it's
|
||
already present:
|
||
- **Trigger lines** (everything except the platform line) — present iff any
|
||
existing line, after `trim` + `tolower`, contains the template line's
|
||
trigger text. Substring match, not equality — tolerates user rewording or
|
||
trailing punctuation.
|
||
- **Platform line** (`we're on Windows`) — present iff any existing line
|
||
matches `we're on (windows|linux|macos)` case-insensitively. If the user
|
||
pinned a different platform on purpose, **leave it alone**. Only append
|
||
the host-appropriate platform line when none of the three is present.
|
||
3. Collect missing lines. If none → print `CLAUDE.md already canon — no changes`
|
||
and skip to Step 5.5.
|
||
4. Show the user the diff (N lines, exact text to append) and ask one question:
|
||
"Append these N missing canonical triggers to the end of CLAUDE.md?" Wait
|
||
for explicit confirmation before writing.
|
||
5. On confirm: append a single newline (if the file doesn't end with one) and
|
||
then the missing lines, one per line. Don't rewrite the file — only append.
|
||
Don't reorder existing lines. Don't dedupe within the existing file.
|
||
|
||
Template contents (`assets/CLAUDE.md.template` — source of truth):
|
||
|
||
```markdown
|
||
# CLAUDE.md
|
||
# Agent instructions. Each line is a trigger for an installed skill.
|
||
|
||
talk like a caveman
|
||
use superpowers
|
||
use project wiki
|
||
use task management system
|
||
check across all projects
|
||
pull remote before work
|
||
follow project discipline
|
||
follow tdd-criteria
|
||
delegate to interns when allowed
|
||
recommend, don't menu
|
||
we're on Windows
|
||
```
|
||
|
||
The `check across all projects` line activates the `using-projects-meta` skill
|
||
so cross-project task aggregation and the shared `projects-wiki` are available
|
||
without an explicit verbal trigger. The skill is a no-op until the
|
||
`projects-meta-mcp` server is registered — install via `setup-projects-meta`
|
||
on a fresh machine if `mcp__projects-meta__*` tools are missing.
|
||
|
||
The `pull remote before work` line activates the `pulling-before-work` skill,
|
||
which runs one `git pull --ff-only` at session start (and on explicit re-sync
|
||
requests like "sync"). It's a no-op outside git repos and skips with a one-line
|
||
warning if the working tree is dirty, HEAD is detached, or the branch has no
|
||
upstream — never auto-merges, stashes, or pushes. Install the skill on the host
|
||
if `pulling-before-work` is not in `~/.claude/skills/`; otherwise the trigger is
|
||
silently dead like any other absent skill.
|
||
|
||
The `follow project discipline` line activates the `project-discipline` skill,
|
||
which codifies four cross-project rules: (1) project CLAUDE.md / .wiki/CLAUDE.md
|
||
/ .tasks/ override defaults from any other skill; (2) all work on master/main,
|
||
no feature branches without explicit user approval; (3) version bump on every
|
||
edit of versioned artifacts per semver, recorded in commit; (4) commit freely,
|
||
push only after explicit per-session approval. Install the skill on the host
|
||
if `project-discipline` is not in `~/.claude/skills/`; otherwise the trigger is
|
||
silently dead like any other absent skill.
|
||
|
||
The `follow tdd-criteria` line activates the `tdd-criteria` skill, which enforces
|
||
test-driven development by default with four bright-line carve-outs (visual CSS,
|
||
spike exploration, oneshot scripts, pure wrappers) and four anti-loophole rules
|
||
(including test-immutability: modifying assertions requires a `[test-modify: ...]`
|
||
marker in the commit subject). Full rationale at `.wiki/concepts/tdd-criteria-design.md`
|
||
in the `claude-skills` repo. Install the skill on the host if `tdd-criteria` is not
|
||
in `~/.claude/skills/`; otherwise the trigger is silently dead like any other absent skill.
|
||
|
||
The `delegate to interns when allowed` line activates the `using-interns` skill,
|
||
which lets Claude offload predictable bulk I/O and summarization tasks
|
||
(reading 3+ files, distilling long transcripts) to cheap intern LLMs via the
|
||
local `interns` MCP server (`mcp__interns__bulk_text_read`,
|
||
`mcp__interns__transcript_distill`, etc.) — saves Anthropic quota at ~125× the
|
||
per-call cost reduction on bulk reads. 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 an
|
||
active grant, session-end reset. The skill is a no-op until the `interns` MCP
|
||
server is registered — install via `setup-interns` on a fresh machine if
|
||
`mcp__interns__*` tools are missing. Full design at
|
||
`.wiki/concepts/interns-design.md` in the `claude-skills` repo.
|
||
|
||
The `recommend, don't menu` line activates the `recommend-dont-menu` skill,
|
||
which overrides the default `superpowers:brainstorming` behavior: in design
|
||
discussions, architecture reviews, or "what should we do" questions, the agent
|
||
gives **one argued recommendation with explicit trade-offs**, not a multiple-
|
||
choice menu. User instructions always take precedence over skill defaults.
|
||
Install the skill on the host if `recommend-dont-menu` is not in `~/.claude/skills/`;
|
||
otherwise the trigger is silently dead like any other absent skill.
|
||
|
||
The `we're on Windows` line activates the `active-platform` skill and pins the
|
||
project's default platform to Windows / PowerShell — so generated commands and
|
||
README quick-starts use PS-native syntax. Bootstrapping on a Linux or macOS
|
||
host? Substitute `we're on Linux` or `we're on macOS` instead.
|
||
|
||
---
|
||
|
||
## Step 5.5 — Bootstrap manifest
|
||
|
||
Write `.wiki/concepts/bootstrap-manifest.md`. The manifest records which skills (and at which versions) initialized this project's `.wiki/` and `.tasks/` layout, so layout drift between projects bootstrapped at different times is debuggable.
|
||
|
||
Read each delegated skill's `SKILL.md` frontmatter to pick up the live `version:` value (don't hardcode):
|
||
|
||
```markdown
|
||
---
|
||
title: Bootstrap Manifest
|
||
type: concept
|
||
updated: <today's date>
|
||
generator: project-bootstrap@<version>
|
||
---
|
||
|
||
# Bootstrap Manifest
|
||
|
||
Skills used to initialize this project's `.wiki/` and `.tasks/` layout, with their versions at install time.
|
||
|
||
| Skill | Version | Role |
|
||
|---|---|---|
|
||
| `project-bootstrap` | <version> | orchestrator |
|
||
| `setup-wiki` | <version> | wiki canonical layout |
|
||
| `setup-tasks` | <version> | tasks canonical layout |
|
||
| `project-discipline` | <version> | cross-project policy |
|
||
| `setup-interns` | <version> | interns MCP server install (one-time, per machine) |
|
||
| `using-interns` | <version> | interns runtime policy + per-session permission grant |
|
||
|
||
This file is overwritten if `project-bootstrap` is re-run on the same project. For history, use `git log .wiki/concepts/bootstrap-manifest.md`.
|
||
```
|
||
|
||
If a delegated setup-skill is unavailable on this machine (e.g. user installed only a subset), record the missing skill as `unknown` in the version column so the gap is visible.
|
||
|
||
---
|
||
|
||
## Step 5.6 — Skill dependencies check (chat-only, never auto-install)
|
||
|
||
The `CLAUDE.md` template just written contains canonical trigger lines.
|
||
Each one is a no-op unless the corresponding skill or plugin is installed
|
||
on the host. On a fresh machine these are often absent, and the user
|
||
won't know the trigger is silently dead. Detect what's missing on this
|
||
machine and print one informational block in chat — never write into any
|
||
project file, never auto-install.
|
||
|
||
### Trigger → fulfiller map
|
||
|
||
Source of truth for this map is the canonical `assets/CLAUDE.md.template`.
|
||
When a new trigger is added there, also add a row here in the same commit.
|
||
Mismatch between template and map → silent gaps in the recommendation.
|
||
|
||
| Trigger line in `CLAUDE.md` | Fulfiller | Kind | Detection path | Install command |
|
||
|---|---|---|---|---|
|
||
| `talk like a caveman` | `caveman` | skill | `~/.claude/skills/caveman/SKILL.md` | `bash scripts/install.sh caveman` |
|
||
| `use superpowers` | `superpowers@claude-plugins-official` | plugin | key `plugins["superpowers@claude-plugins-official"]` in `~/.claude/plugins/installed_plugins.json` | `/plugin install superpowers@claude-plugins-official` |
|
||
| `use project wiki` | `using-wiki` | skill | `~/.claude/skills/using-wiki/SKILL.md` | `bash scripts/install.sh using-wiki` |
|
||
| `use task management system` | `using-tasks` | skill | `~/.claude/skills/using-tasks/SKILL.md` | `bash scripts/install.sh using-tasks` |
|
||
| `check across all projects` | `using-projects-meta` | skill | `~/.claude/skills/using-projects-meta/SKILL.md` | `bash scripts/install.sh using-projects-meta` |
|
||
| `pull remote before work` | `pulling-before-work` | skill | `~/.claude/skills/pulling-before-work/SKILL.md` | `bash scripts/install.sh pulling-before-work` |
|
||
| `session handoff: read on start, write on end` | `session-handoff` | skill | `~/.claude/skills/session-handoff/SKILL.md` | `bash scripts/install.sh session-handoff` |
|
||
| `follow project discipline` | `project-discipline` | skill | `~/.claude/skills/project-discipline/SKILL.md` | `bash scripts/install.sh project-discipline` |
|
||
| `follow tdd-criteria` | `tdd-criteria` | skill | `~/.claude/skills/tdd-criteria/SKILL.md` | `bash scripts/install.sh tdd-criteria` |
|
||
| `delegate to interns when allowed` | `using-interns` | skill | `~/.claude/skills/using-interns/SKILL.md` | `bash scripts/install.sh using-interns` |
|
||
| `recommend, don't menu` | `recommend-dont-menu` | skill | `~/.claude/skills/recommend-dont-menu/SKILL.md` | `bash scripts/install.sh recommend-dont-menu` |
|
||
| `we're on Windows` / `we're on Linux` / `we're on macOS` | `active-platform` | skill | `~/.claude/skills/active-platform/SKILL.md` | `bash scripts/install.sh active-platform` |
|
||
|
||
### Algorithm
|
||
|
||
1. Read the project's `CLAUDE.md` (just-written or pre-existing). Extract
|
||
every non-empty, non-comment line — these are the active triggers for
|
||
THIS project. The user may have removed canonical lines on purpose;
|
||
respect that — only check what's actually in the file.
|
||
2. Match each line against the trigger column above using `trim` + `tolower`
|
||
substring (same matching as Step 5 idempotent merge). Lines that don't
|
||
match any row are user-custom — skip silently. The platform line matches
|
||
the `active-platform` row regardless of which platform is pinned.
|
||
3. For each matched canonical line, check the detection path:
|
||
- `kind: skill` → does `~/.claude/skills/<name>/SKILL.md` exist?
|
||
- `kind: plugin` → does `~/.claude/plugins/installed_plugins.json` contain
|
||
the plugin key under `plugins`? (Treat malformed JSON as "missing" and
|
||
continue — don't crash the bootstrap over a detection edge case.)
|
||
4. Collect every fulfiller that's missing. Two outcomes:
|
||
|
||
- **All present** — print one line:
|
||
|
||
```
|
||
✅ all skill dependencies satisfied — every CLAUDE.md trigger has its fulfiller on this host.
|
||
```
|
||
|
||
Skip to Step 6.
|
||
|
||
- **Some missing** — print one block in chat exactly once. Do **not**
|
||
write it into any project file:
|
||
|
||
```
|
||
ℹ️ Recommended: install the following to fulfill CLAUDE.md triggers
|
||
|
||
The triggers below are present in CLAUDE.md but their fulfillers are
|
||
missing on this machine — they're silently no-ops until installed:
|
||
|
||
trigger fulfiller (kind)
|
||
<trigger-line> <fulfiller> (<kind>)
|
||
<trigger-line> <fulfiller> (<kind>)
|
||
…
|
||
|
||
Install (run inside Claude Code or terminal):
|
||
<install command 1>
|
||
<install command 2>
|
||
…
|
||
|
||
After install + (for plugins) a Claude Code restart, the triggers pick
|
||
them up.
|
||
```
|
||
|
||
### Notes
|
||
|
||
- **MCP-server-backed skills** (`using-context7`, `using-projects-meta`,
|
||
`using-interns`) — only the `using-X` policy skill is checked here. If
|
||
the MCP isn't registered, the `using-X` Prerequisites pointer fires
|
||
`setup-X` at first use; bootstrap doesn't duplicate that detection.
|
||
- The `~/.claude/skills/` and `~/.claude/plugins/` paths resolve identically
|
||
on Windows / Linux / macOS — `~` works under git-bash too.
|
||
- **Hard rule — never auto-install.** Slash commands aren't callable from a
|
||
skill, and silently mutating user-level skill / plugin state without
|
||
consent is overreach. The recommendation is informational. The user can
|
||
install some / all / none of the recommendations, or remove canonical
|
||
lines from `CLAUDE.md` to lean the project's trigger set down.
|
||
|
||
## Step 6 — Commit
|
||
|
||
```bash
|
||
git add .
|
||
git commit -m "chore: bootstrap project structure"
|
||
```
|
||
|
||
If the repo already had commits — commit only the files just created:
|
||
|
||
```bash
|
||
git add .wiki/ .tasks/ CLAUDE.md .gitignore README.md
|
||
git commit -m "chore: upgrade project structure"
|
||
```
|
||
|
||
---
|
||
|
||
## Step 7 — Summary
|
||
|
||
Print a final report:
|
||
|
||
```
|
||
✅ Done! Created:
|
||
.wiki/ — project wiki (Karpathy method)
|
||
.tasks/ — task tracking system
|
||
CLAUDE.md — skill triggers
|
||
.gitignore — standard template
|
||
README.md — starter file
|
||
remote — Gitea repo created and pushed
|
||
|
||
Skipped (already existed):
|
||
git — left untouched
|
||
|
||
Next step: describe the project in README.md and start your first task —
|
||
say "use task management system".
|
||
```
|
||
|
||
For **greenfield-full** mode, append to summary:
|
||
```
|
||
Remote: <Gitea URL>
|
||
```
|
||
|
||
---
|
||
|
||
## Step 8 — projects-meta sync (greenfield-full mode)
|
||
|
||
Only in **greenfield-full** mode. Re-sync the projects-meta cache so the new
|
||
project becomes visible to `mcp__projects-meta__*` tools.
|
||
|
||
```bash
|
||
# POSIX:
|
||
node ~/projects/.common/lib/projects-meta-mcp/dist/sync.js
|
||
|
||
# Windows PowerShell:
|
||
node ~/projects/.common/lib/projects-meta-mcp/dist/sync.js
|
||
```
|
||
|
||
Verify the project is now visible:
|
||
```bash
|
||
# Via MCP (if available in current session):
|
||
# mcp__projects-meta__meta_status
|
||
|
||
# Or manually check the cache file exists:
|
||
ls -la ~/projects/.common/lib/projects-meta-mcp/cache/projects.json
|
||
```
|
||
|
||
If the sync script doesn't exist → skip with informational message:
|
||
```
|
||
ℹ️ projects-meta sync script not found at ~/projects/.common/lib/projects-meta-mcp/dist/sync.js
|
||
Run /setup-projects-meta to install it. The new repo is already created in Gitea.
|
||
```
|
||
|
||
---
|
||
|
||
## Rules
|
||
|
||
- **Never overwrite** existing files without explicit user confirmation
|
||
- **Always show the plan first** — one question, one confirmation
|
||
- **Never invent details** — if the project already exists, read what's there
|
||
- **Commit only what was just created** — do not touch the rest of the file tree
|
||
- **Commit automatically** after each successful step, no extra questions
|
||
- **Push only after explicit user confirmation** — ask "Push to remote?" and wait for "yes"
|