4.5 KiB
4.5 KiB
Session Skills — Implementation Plan
Spec: docs/superpowers/specs/2026-07-03-session-skills-design.md
Approach: subagent-driven TDD (sonnet), build + test + commit per task, stage files by
path (never git add -A).
Pre-flight (do first, before building anything): manual smoke test — drop a skill
into a scratch worktree's .claude/skills/ and run claude -p to confirm cwd skills are
discovered in headless mode. The whole feature rests on this. If it fails, stop and
redesign around CLAUDE_CONFIG_DIR.
Task 1 — Data layer: columns + registry table + migration
- Add nullable
SessionSkills(string, JSON array) toTaskEntity,ListConfigEntity,AppSettingsEntity; mapsession_skillscolumns in their*Configuration.cs. - New
SessionSkillEntity(namePK,source_url,pinned_ref,description,added_at) + configuration +session_skillstable. - New
SessionSkillRepository(async, CancellationToken):ListAsync,GetAsync(name),UpsertAsync,DeleteAsync. - EF migration
AddSessionSkills(columns + table). - Tests (Data.Tests): repository CRUD on real SQLite; JSON column round-trips a name list.
Task 2 — Registry service (install / update / remove)
Skills/SessionSkillRegistry+Skills/Interfaces/ISessionSkillRegistry,IRepoCloner(clone abstraction so tests inject a local source dir).GitRepoCloner(production) doesgit clone+ resolves HEAD SHA.- Install: clone → require root
SKILL.md→ parse YAML frontmatter (name,description) → move to~/.todo-app/session-skills/<name>/→ upsert row. Reject collision / missingSKILL.md. - Update / Remove per spec.
- Tests (Worker.Tests): install from a local fixture dir (fake cloner) parses
frontmatter + writes registry + copies files; missing-
SKILL.mdrejected; collision rejected; remove deletes dir + row. No real network / no real claude CLI.
Task 3 — Resolution: union into ClaudeRunConfig
- Add
IReadOnlyList<string> SkillNamestoClaudeRunConfig(default empty). - In
TaskRunner.ResolveConfigAsync: parse each level'ssession_skills, union + dedup, filter to registry-existing names (drop + log missing). - Tests (Worker.Tests): union across the three levels; dedup; unknown name dropped.
Task 4 — Seeder
Skills/SessionSkillSeeder+ interface.SeedAsync(cwd, skillNames, isWorktree, ct): copy each installed skill dir →<cwd>/.claude/skills/<name>/; if worktree, append/.claude/skills/<name>/togit rev-parse --git-path info/excludetarget if absent.- Wire into
TaskRunnerafter run-dir resolution, beforeClaudeProcess.RunAsync(both worktree and sandbox paths). - Tests (Worker.Tests): seeds into real temp dir; idempotent re-seed; worktree
exclude line written once and not duplicated; seeded path is git-ignored (real git
temp repo →
git statusclean for the seeded dir).
Task 5 — Hub + DTOs + client
WorkerHub:GetSessionSkills,InstallSessionSkill(url),UpdateSessionSkill(name),RemoveSessionSkill(name).- New
SessionSkillDto; extendAppSettingsDto,ListConfigDto,UpdateListConfigDto,UpdateTaskAgentSettingsDtowith skill-name lists; map in the update handlers. IWorkerClient+WorkerClientadditions.- Update hand-rolled fakes in Worker.Tests + Ui.Tests (memory
iworkerclient_fakes_sync). - Tests: hub method round-trip via existing hub test harness where present.
Task 6 — UI: registry tab + selectors
SessionSkillsSettingsTabViewModel+ a Skills tab inSettingsModalView.axaml: installed list, Add (URL), Update, Remove, status line. MirrorFilesSettingsTabViewModel.- Global multi-select in General settings tab →
AppSettings.SessionSkills. - Skills multi-select in shared
AgentConfigEditor(covers List + Task) with inheritance badge, wired throughAgentConfigEditorViewModel. - Localization: add EN + DE keys in parity (Localization.Tests enforces).
- Tests (Ui.Tests / Localization.Tests): VM load/save of selections; locale parity.
- Visual verification is Mika's — flag the gaps.
Task 7 — Wiring, build, end-to-end smoke
- DI registration (registry, cloner, seeder) in
Program.cs. - Build all touched projects
-c Release; run Worker/Data/Ui/Localization test projects. - Manual E2E: install ponytail via the UI, enable per-task, run a task, confirm the skill is available to the agent and not committed and not in interactive sessions.
Commit per task with Conventional Commits (feat(worker|ui|data): …). Commit the
spec + plan docs first.