-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Problem
Pipeline steps depend on external skills (speckit, BMAD, OpenSpec) and tools (gh, git, node) but Wave has no mechanism to:
- Install skills — The
.claude/commands/and.specify/files in the repo were manually created. There's no declarative, reproducible installation path. - Provision workspaces — Workspaces are empty directories (workspace
root: ./with nomount:creates justmkdir). Skills, commands, scripts, and templates aren't available inside them. Claude Code discovers slash commands only by accident (walking up the directory tree to the project root). - Validate dependencies — If a pipeline requires
speckitorgh, Wave doesn't check until the step fails mid-execution — after burning tokens and time. - Isolate git operations — PR fix(pipeline): prevent create-new-feature.sh from switching main repo branch #64 fixed a symptom where concurrent pipeline runs collided because
create-new-feature.shrangit checkout -bon the main repo. The root cause is that workspaces aren't real git checkouts, so all git operations reach back to the shared project root.
The skill_mounts config exists in the manifest schema but is dead code — parsed, validated, never wired into the executor or adapter.
External Skill Sources
These are external open-source projects, not Wave-owned code:
| Skill | Source | Install | Init |
|---|---|---|---|
| Spec-Kit | github/spec-kit | uv tool install specify-cli --from git+https://github.com/github/spec-kit.git |
specify init <project> |
| BMAD | bmad-code-org/BMAD-METHOD | npx bmad-method install (interactive) or npx bmad-method install --tools claude-code --yes |
included in install |
| OpenSpec | Fission-AI/OpenSpec | npm install -g @fission-ai/openspec@latest |
openspec init |
Each tool has its own CLI installer that generates .claude/commands/, .specify/, and related files. Wave should not embed or vendor these — it should delegate installation to their native installers.
Current State (Broken)
wave run speckit-flow "add auth"
│
├─ Workspace: .wave/workspaces/speckit-flow/specify/
│ ├─ .claude/settings.json ✅ (created by prepareWorkspace)
│ ├─ CLAUDE.md ✅ (created by prepareWorkspace)
│ ├─ .claude/commands/ ❌ (blocked by skipDirs)
│ ├─ .specify/ ❌ (no mount, empty workspace)
│ └─ .git ❌ (blocked by skipDirs)
│
├─ Claude Code discovers commands by walking up to project root (accidental)
├─ Prompts contain 80 lines of git/workspace plumbing to compensate
└─ Concurrent runs collide on shared project root (PR #64)
Proposed Design
1. Skill declarations in wave.yaml (optional)
skills:
speckit:
install: "uv tool install specify-cli --from git+https://github.com/github/spec-kit.git"
init: "specify init"
check: "specify --version"
bmad:
install: "npx bmad-method install --tools claude-code --yes"
check: "ls .claude/commands/bmad.*.md"
openspec:
install: "npm install -g @fission-ai/openspec@latest"
init: "openspec init"
check: "openspec --version"Skills are optional — only declare what your project uses. Each skill declares how to install, initialize, and verify itself.
2. Pipeline requires: block
kind: WavePipeline
metadata:
name: speckit-flow
requires:
skills: [speckit]
tools: [git]
steps:
- id: specify
persona: implementer
workspace:
type: worktree
branch: "{{ branch }}"
exec:
type: slash_command
command: speckit.specify
args: "{{ input }}"Pipelines declare their dependencies. skills: checks for installed command files. tools: checks $PATH.
3. Preflight validation with auto-install
Before any step runs:
$ wave run speckit-flow "add auth"
Preflight:
✓ tool 'git' found
✗ skill 'speckit' not installed
→ installing speckit...
running: uv tool install specify-cli --from git+https://github.com/github/spec-kit.git
running: specify init
✓ skill 'speckit' installed
Running pipeline speckit-flow...
- Tools: check
$PATH, fail with actionable error if missing (Wave can't install system tools) - Skills: check if commands exist → if missing and
install:/init:declared → auto-install → recheck → fail if still missing - No install declared: fail with suggestion to add it to wave.yaml or install manually
4. Git worktree workspaces
Instead of empty directories, Wave creates workspaces as git worktrees:
workspace:
type: worktree # Wave creates: git worktree add <workspace-path> <branch>
branch: "{{ branch }}"This means:
- Workspace IS a full git checkout on its own branch
- All project files available (no mount/copy needed for project sources)
- Git operations work natively (commit, push, branch — local to worktree)
- Concurrent pipeline runs cannot collide (each worktree is independent)
- Wave manages worktree lifecycle (create before step, remove after)
- Eliminates the need for PR fix(pipeline): prevent create-new-feature.sh from switching main repo branch #64's prompt-level workarounds entirely
5. Skill provisioning into workspaces
During workspace setup, prepareWorkspace() copies skill commands into the workspace:
workspace/
.claude/
settings.json ← existing (persona permissions)
commands/
speckit.*.md ← NEW (from installed skills)
CLAUDE.md ← existing (persona prompt)
.specify/ ← available via worktree (project files)
artifacts/ ← existing (injected from prior steps)
Claude Code discovers commands locally. No walking up the tree. No reaching back to project root.
6. Prompt simplification
Pipeline prompts shrink from 80 lines of plumbing to pure intent:
Run `/speckit.specify` with: {{ input }}No REPO_ROOT, no cd, no git worktree add, no worktree cleanup. Wave handles all infrastructure.
Target State
wave run speckit-flow "add auth"
│
├─ Preflight
│ ├─ tool 'git' on PATH? ✓
│ ├─ skill 'speckit' installed? → auto-install ✓
│
├─ Step: specify
│ ├─ git worktree add .wave/workspaces/speckit-flow/specify <branch>
│ ├─ copy .claude/commands/speckit.*.md → workspace/.claude/commands/
│ ├─ write .claude/settings.json + CLAUDE.md
│ ├─ launch Claude Code (cwd = worktree)
│ ├─ prompt: "Run /speckit.specify with: add auth"
│ ├─ skill runs natively — commands, scripts, templates all local
│ ├─ git operations safe — isolated worktree, no main repo mutation
│ └─ cleanup: git worktree remove
│
└─ Next step (artifact injection from specify's output)
Implementation Phases
Phase 1: Preflight validation
- Add
requires:field to pipeline schema (skills + tools) - Implement preflight check in executor (before workspace creation)
- Fail-fast with actionable error messages
Phase 2: Skill provisioning
- Wire up
skill_mountsinprepareWorkspace() - Copy
.claude/commands/into workspace alongside settings.json - Remove
.claudefromskipDirsfor commands subdirectory only
Phase 3: Git worktree workspaces
- Add
workspace.type: worktreeoption - Wave creates/removes worktrees as part of step lifecycle
- Branch management moves from prompts to Wave infrastructure
Phase 4: Skill installation
- Add
skills:config to wave.yaml manifest schema - Implement auto-install during preflight using each skill's native installer
install:,init:, andcheck:commands per skill declaration
Phase 5: Prompt cleanup
- Replace 80-line inline prompts with slash command references
- New
exec.type: slash_commandthat just invokes a command with args - Remove all
REPO_ROOT,cd, worktree boilerplate from prompts
Related Issues
- Supersedes feat(workspace): inject Claude skills/commands and external tool configs into pipeline workspaces #48 — this is the full design for skill/command support in workspaces
- Addresses the dependency validation aspect of test(release): validate release binaries and documentation accuracy on fresh Ubuntu VMs #74 (fresh VM testing)
- Solves feat: Add concurrency property to spawn multiple agents for the same step #29's concurrency concern — git worktree workspaces provide isolation for concurrent agent steps
- Makes feat: Add --preserve-workspace flag for debugging #27 (
--preserve-workspace) more meaningful — preserved workspace is a real git worktree, not an empty dir - Replaces the approach in PR fix(pipeline): prevent create-new-feature.sh from switching main repo branch #64 — git safety moves from prompt-level workarounds to infrastructure
References
- github/spec-kit — Python CLI, installed via
uv - bmad-code-org/BMAD-METHOD — npm package, installed via
npx - Fission-AI/OpenSpec — npm package, installed via
npm