✨ Add spire:init skill with adept scaffolding
Human-triggered skill that detects install type, auto-fills project facts, scaffolds .claude/spire/project.md and workpad adept templates, handles gitignore for personal installs, and optionally commits for shared installs. All seven phases from the design.
This commit is contained in:
@@ -0,0 +1,296 @@
|
||||
---
|
||||
name: init
|
||||
description: >
|
||||
Initialize Spire for the current project — detect project facts,
|
||||
scaffold .claude/spire/project.md, create adept templates, and
|
||||
handle shared vs. personal install. Human-triggered.
|
||||
disable-model-invocation: true
|
||||
allowed-tools: Bash(cat:*), Bash(grep:*), Bash(ls:*), Bash(just:*), Bash(git:*), Read, Write, Glob, Grep
|
||||
---
|
||||
|
||||
# Spire — Init
|
||||
|
||||
Initialize Spire for the current project. Run this once after installing the
|
||||
Spire plugin, or again after major structural changes. Re-init is safe — it
|
||||
will not clobber hand-edited files.
|
||||
|
||||
Seven phases: detect install type, detect project facts, scaffold project.md,
|
||||
scaffold adept templates, gitignore (if personal), optional alias, and commit
|
||||
(if shared).
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — Detect install type
|
||||
|
||||
Determine whether Spire is a **shared** (project-level) or **personal**
|
||||
(user-level) install. This governs whether scaffolded files get committed or
|
||||
gitignored.
|
||||
|
||||
1. Read `.claude/settings.json` (if it exists). Search for any string
|
||||
containing `spire` in the `plugins` or `mcpServers` keys — typically
|
||||
`"spire@reliquary"` or a path containing `/spire/`.
|
||||
2. Read `.claude/settings.local.json` (if it exists). Same search.
|
||||
3. Classify:
|
||||
|
||||
| Spire found in | Install type | Action |
|
||||
|---|---|---|
|
||||
| `settings.json` | **Shared** | Files will be committed |
|
||||
| `settings.local.json` only | **Personal** | Files will be gitignored |
|
||||
| Neither file | **Ambiguous** | Ask the user: "Should the Spire config be shared with the project (committed) or personal (gitignored)?" |
|
||||
|
||||
Store the result as `$INSTALL_TYPE` (shared or personal) for later phases.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Detect project facts
|
||||
|
||||
Auto-detect as much as possible. Each fact that cannot be detected becomes a
|
||||
placeholder in the scaffolded `project.md`.
|
||||
|
||||
### 2.1 — Workpad location
|
||||
|
||||
Resolve the workpad using the `spire:workpad` resolution chain (environment
|
||||
variable, `just workpad-folder`, `docs/workpad/`, `.workpad/`). Record the
|
||||
path as `$WORKPAD`.
|
||||
|
||||
### 2.2 — Pinned agents
|
||||
|
||||
List `.claude/agents/*.md`. For each file, read its frontmatter to extract
|
||||
`name` and `description`. These become the "Pinned agents" list.
|
||||
|
||||
### 2.3 — Verification commands
|
||||
|
||||
Check these files in order for verification commands:
|
||||
|
||||
- **Justfile**: Look for recipes named `check`, `test`, `lint`, `build`,
|
||||
`verify`, `ci`, or similar. Run `just --list` if available.
|
||||
- **Makefile**: Look for targets named `check`, `test`, `lint`, `build`.
|
||||
- **package.json**: Read `scripts` for `test`, `lint`, `build`, `check`.
|
||||
- **Cargo.toml**: If present, `cargo check`, `cargo test`, `cargo clippy`
|
||||
are likely verification commands.
|
||||
|
||||
### 2.4 — Conventions
|
||||
|
||||
Read the root `CLAUDE.md` for project conventions — commit message style,
|
||||
branching strategy, review process, language/framework preferences.
|
||||
Summarize relevant conventions concisely.
|
||||
|
||||
### 2.5 — Tome presence
|
||||
|
||||
Check whether the `tome` plugin is installed:
|
||||
- Search `.claude/settings.json` and `.claude/settings.local.json` for
|
||||
`tome` references.
|
||||
- Check for a `*-tome:navigate` skill or `tome@reliquary` plugin reference.
|
||||
- If found, note the tome skill name for the project.md template.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — Scaffold `project.md`
|
||||
|
||||
Write `.claude/spire/project.md` using the detected facts.
|
||||
|
||||
### 3.1 — Re-init safety check
|
||||
|
||||
If `.claude/spire/project.md` already exists:
|
||||
- Read its YAML frontmatter.
|
||||
- If `status: authored` — **stop**. Tell the user: "project.md has been
|
||||
manually edited (status: authored). Skipping to avoid clobbering your
|
||||
changes. Delete or change status to `generated` to allow re-scaffolding."
|
||||
- If `status: generated` — proceed, overwriting the file.
|
||||
- If no status field — treat as authored, do not overwrite.
|
||||
|
||||
### 3.2 — Write the file
|
||||
|
||||
Create `.claude/spire/` directory if needed. Write `project.md` with this
|
||||
structure:
|
||||
|
||||
```markdown
|
||||
---
|
||||
status: generated
|
||||
generated: <YYYY-MM-DD>
|
||||
---
|
||||
# Project Knowledge (per-project — swap this file when adopting Igor)
|
||||
|
||||
Project-specific facts for Igor and the athanor. The generic behavior files
|
||||
stay unchanged across projects; only this file (and any tome/navigation skill
|
||||
preload) changes.
|
||||
|
||||
## This project
|
||||
|
||||
- **Tome skill**: <detected tome skill or "none detected — Igor will orient via direct file reads">
|
||||
- **Workpad**: <detected workpad path with subfolder structure>
|
||||
- **Adepts**: Domain knowledge agents with persistent folders at `<workpad>/adepts/<domain-slug>/`.
|
||||
- **Pinned agents** (prefer these over generic tiers):
|
||||
<list of detected agents with name and description, or placeholder comment>
|
||||
- **Verification commands**: <detected commands, or placeholder comment>
|
||||
- **Domain skills to route to subagents when relevant**: <!-- detect and list, or leave as placeholder -->
|
||||
- **Conventions**: <summarized conventions from CLAUDE.md, or placeholder comment>
|
||||
```
|
||||
|
||||
Fill every field that was detected; leave a `<!-- placeholder -->` comment for
|
||||
fields that were not.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — Scaffold adept templates
|
||||
|
||||
Create the adept directory structure in the workpad. These files are
|
||||
referenced by the `adept` agent during genesis (see `agents/adept.md`).
|
||||
|
||||
### 4.1 — Create the adepts directory
|
||||
|
||||
```bash
|
||||
mkdir -p "${WORKPAD}/adepts/_template"
|
||||
```
|
||||
|
||||
### 4.2 — Write `adepts/CLAUDE.md`
|
||||
|
||||
If `${WORKPAD}/adepts/CLAUDE.md` already exists and contains
|
||||
`status: authored` in its frontmatter, skip it. Otherwise write:
|
||||
|
||||
```markdown
|
||||
---
|
||||
status: generated
|
||||
---
|
||||
# Adepts
|
||||
|
||||
This directory holds domain knowledge accumulated by adept agents. Each
|
||||
subfolder is one domain — a subsystem, a library, a cross-cutting concern —
|
||||
named with a short kebab-case slug.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
adepts/
|
||||
CLAUDE.md ← you are here
|
||||
_template/CLAUDE.md ← starter template for new domains
|
||||
<domain-slug>/
|
||||
CLAUDE.md ← domain orientation, key files, conventions
|
||||
YYYY-MM-DD-HH-journal-*.md ← session journals from adept work
|
||||
```
|
||||
|
||||
## Conventions
|
||||
|
||||
- **One domain per folder.** If two domains overlap, pick the stricter scope.
|
||||
Broad names are gravity wells — prefer specificity.
|
||||
- **CLAUDE.md is the handoff document.** When an adept spawns into an existing
|
||||
domain, it reads this file first. Write it for your successor, not yourself.
|
||||
- **Journals are append-only.** Each session gets a new journal entry. Include
|
||||
what you found, what you changed, what's still unclear, and what steps you
|
||||
took to orient (files read, searches run, what was useful vs. noise).
|
||||
- **Don't hoard.** If a finding belongs in the project's main docs or workpad
|
||||
reports, put it there and link from here. The adept folder is for domain
|
||||
context that helps the next adept orient, not a shadow wiki.
|
||||
```
|
||||
|
||||
### 4.3 — Write `adepts/_template/CLAUDE.md`
|
||||
|
||||
If `${WORKPAD}/adepts/_template/CLAUDE.md` already exists and contains
|
||||
`status: authored`, skip it. Otherwise write:
|
||||
|
||||
```markdown
|
||||
---
|
||||
status: generated
|
||||
---
|
||||
# <Domain Name>
|
||||
|
||||
<!-- Replace this heading with the domain name. Fill in the sections below
|
||||
during your genesis orientation. -->
|
||||
|
||||
## Domain
|
||||
|
||||
<!-- What this domain covers. One paragraph: scope, boundaries, why it exists
|
||||
as a separate domain. -->
|
||||
|
||||
## Key files
|
||||
|
||||
<!-- Files and directories central to this domain. Use a table or bullet list.
|
||||
Include paths relative to the repo root. -->
|
||||
|
||||
| Path | What it is |
|
||||
|------|-----------|
|
||||
| <!-- e.g. src/auth/ --> | <!-- e.g. Authentication module --> |
|
||||
|
||||
## Conventions
|
||||
|
||||
<!-- Domain-specific conventions: naming patterns, error handling style,
|
||||
testing expectations, dependency rules. Only note things that differ
|
||||
from or add to the project-wide conventions. -->
|
||||
|
||||
## Open questions
|
||||
|
||||
<!-- Things the founding adept couldn't resolve. Future adepts should
|
||||
attempt these before adding new ones. Remove entries as they're
|
||||
answered. -->
|
||||
|
||||
- <!-- e.g. "Why does FooService bypass the standard auth middleware?" -->
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 5 — Gitignore (personal install only)
|
||||
|
||||
If `$INSTALL_TYPE` is **personal**:
|
||||
|
||||
1. Read `.claude/.gitignore` (create it if it does not exist).
|
||||
2. Check whether it already contains a line matching `spire/`.
|
||||
3. If not present, append `spire/` on its own line.
|
||||
|
||||
If `$INSTALL_TYPE` is **shared**, skip this phase entirely.
|
||||
|
||||
---
|
||||
|
||||
## Phase 6 — Optional alias
|
||||
|
||||
Offer the user an optional convenience alias:
|
||||
|
||||
> "Would you like to create `/assistant` as an alias for `/spire:igor`?
|
||||
> This creates `.claude/skills/assistant/SKILL.md` so you can invoke Igor
|
||||
> as just `/assistant`."
|
||||
|
||||
If the user accepts:
|
||||
|
||||
1. Create `.claude/skills/assistant/` directory if needed.
|
||||
2. Write `.claude/skills/assistant/SKILL.md`:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: assistant
|
||||
description: Start an Igor session — alias for spire:igor.
|
||||
user-invocable: true
|
||||
---
|
||||
|
||||
Invoke the `spire:igor` skill. Pass through any arguments:
|
||||
|
||||
/spire:igor $ARGUMENTS
|
||||
```
|
||||
|
||||
If the user declines or doesn't respond, skip.
|
||||
|
||||
---
|
||||
|
||||
## Phase 7 — Commit (shared install only)
|
||||
|
||||
If `$INSTALL_TYPE` is **shared**:
|
||||
|
||||
1. Stage all files created or modified by this init run:
|
||||
- `.claude/spire/project.md`
|
||||
- `${WORKPAD}/adepts/CLAUDE.md`
|
||||
- `${WORKPAD}/adepts/_template/CLAUDE.md`
|
||||
- `.claude/skills/assistant/SKILL.md` (if created in Phase 6)
|
||||
2. Commit with message: `🤖 Initialize Spire project config`
|
||||
|
||||
If `$INSTALL_TYPE` is **personal**, do not commit — the files are gitignored.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
After all phases, report to the user:
|
||||
|
||||
- Install type detected (shared / personal)
|
||||
- What was scaffolded (list files created or updated)
|
||||
- What was skipped (files with `status: authored`, phases that didn't apply)
|
||||
- Next steps: "Edit `.claude/spire/project.md` to fill in any remaining
|
||||
placeholders, then change `status` from `generated` to `authored` to
|
||||
lock it against future re-inits."
|
||||
Reference in New Issue
Block a user