Skip to content

Commit e039190

Browse files
committed
Add skill selection plan
1 parent c0c06ac commit e039190

File tree

5 files changed

+455
-0
lines changed

5 files changed

+455
-0
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
---
2+
phase: design
3+
title: System Design & Architecture
4+
description: Define the technical architecture, components, and data models
5+
feature: skill-add-interactive-selection
6+
---
7+
8+
# System Design & Architecture - Skill Add Interactive Selection
9+
10+
## Architecture Overview
11+
**What is the high-level system structure?**
12+
13+
```mermaid
14+
graph TD
15+
User[User: ai-devkit skill add <registry>] --> SkillCommand
16+
SkillCommand --> SkillManager
17+
SkillManager --> RegistryResolver[fetchMergedRegistry]
18+
SkillManager --> CacheResolver[cloneRepositoryToCache]
19+
CacheResolver --> RegistryRepo[registry checkout/cache]
20+
RegistryRepo --> SkillEnumerator[scan skills/*/SKILL.md]
21+
SkillEnumerator --> Prompt[inquirer list prompt]
22+
Prompt --> SkillManager
23+
SkillManager --> Installer[existing addSkill install path]
24+
Installer --> ConfigManager[project config update]
25+
```
26+
27+
- `packages/cli/src/commands/skill.ts` will change `add` from two required args to one required registry arg plus an optional skill arg.
28+
- `SkillManager` will own the interactive fallback so CLI wiring stays thin and existing validation/cache logic is reused.
29+
- The prompt list will be built from the selected registry checkout after registry resolution; if refresh fails but cache exists, the cached checkout is still used with a warning.
30+
31+
## Data Models
32+
**What data do we need to manage?**
33+
34+
```ts
35+
interface RegistrySkillChoice {
36+
name: string;
37+
description?: string;
38+
skillPath: string;
39+
}
40+
41+
interface AddSkillOptions {
42+
global?: boolean;
43+
environments?: string[];
44+
interactive?: boolean;
45+
}
46+
```
47+
48+
- `RegistrySkillChoice` is an internal prompt model only.
49+
- The persisted config format does not change.
50+
- Skill names continue to be the canonical installation IDs.
51+
52+
## API Design
53+
**How do components communicate?**
54+
55+
**CLI surface:**
56+
57+
- Existing explicit form remains:
58+
- `ai-devkit skill add <registry> <skill-name>`
59+
- New interactive shorthand:
60+
- `ai-devkit skill add <registry>`
61+
62+
**Internal interfaces (proposed):**
63+
64+
```ts
65+
async addSkill(registryId: string, skillName?: string, options?: AddSkillOptions): Promise<void>;
66+
async listRegistrySkills(registryId: string): Promise<RegistrySkillChoice[]>;
67+
async promptForSkillSelection(skills: RegistrySkillChoice[]): Promise<string>;
68+
```
69+
70+
**Behavior contract:**
71+
72+
- If `skillName` is provided, skip prompting.
73+
- If `skillName` is missing and `stdout`/`stdin` are interactive, enumerate skills and prompt.
74+
- If `skillName` is missing in a non-interactive context, fail with an error instructing the user to provide `<skill-name>`.
75+
- If the prompt is cancelled, exit without side effects.
76+
- If exactly one valid skill exists and `skillName` is omitted, still show the selector instead of auto-installing.
77+
78+
## Component Breakdown
79+
**What are the major building blocks?**
80+
81+
1. `packages/cli/src/commands/skill.ts`
82+
- Update the command signature to optional `[skill-name]`.
83+
- Pass control to `SkillManager.addSkill`.
84+
2. `packages/cli/src/lib/SkillManager.ts`
85+
- Split current `addSkill` flow into:
86+
- registry resolution and cache preparation
87+
- optional interactive skill selection
88+
- existing installation logic
89+
- Add a helper that enumerates valid skills from the cloned registry.
90+
- Add a helper that prompts with `inquirer`.
91+
3. `packages/cli/src/__tests__/commands/skill.test.ts`
92+
- Add command-level coverage for omitted skill name.
93+
4. `packages/cli/src/__tests__/lib/SkillManager.test.ts`
94+
- Add behavior coverage for enumeration, prompt selection, cancellation, and non-interactive mode.
95+
96+
## Design Decisions
97+
**Why did we choose this approach?**
98+
99+
- Enumerate from the resolved registry checkout instead of the global search index:
100+
- It guarantees the list reflects the exact target registry the user requested.
101+
- It works with custom registries that may not yet be indexed.
102+
- It avoids coupling install behavior to index freshness.
103+
- Keep interactive selection explicit even for single-skill registries:
104+
- It matches the stated UX requirement.
105+
- It avoids hidden behavior changes between one-skill and multi-skill registries.
106+
- Prefer cached registry contents when refresh fails:
107+
- It keeps the command usable offline or during transient network failures.
108+
- It aligns with existing cache-oriented registry behavior.
109+
- Keep the prompt in `SkillManager`:
110+
- Registry validation, caching, and installation already live there.
111+
- The command layer should not duplicate repo-reading logic.
112+
- Fail in non-interactive mode when the skill name is omitted:
113+
- This preserves scriptability and avoids hanging CI jobs.
114+
115+
**Alternatives considered:**
116+
117+
- Use `skill find` index results to populate the prompt.
118+
- Rejected because it is broader than the selected registry and may be stale.
119+
- Always auto-install when a registry has exactly one skill.
120+
- Rejected for now to keep behavior explicit and predictable.
121+
122+
## Non-Functional Requirements
123+
**How should the system perform?**
124+
125+
- Performance:
126+
- Interactive enumeration should reuse the existing cache and only fetch/update the chosen registry once.
127+
- Reliability:
128+
- Invalid skill folders are skipped during enumeration instead of breaking the entire list.
129+
- Empty registries produce a clear error.
130+
- Refresh failures degrade to cached registry contents when available.
131+
- Security:
132+
- Continue validating `registryId` and selected `skillName` before installation.
133+
- Usability:
134+
- Prompt entries should display skill name and short description when available.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
phase: implementation
3+
title: Implementation Guide
4+
description: Technical implementation notes, patterns, and code guidelines
5+
feature: skill-add-interactive-selection
6+
---
7+
8+
# Implementation Guide - Skill Add Interactive Selection
9+
10+
## Development Setup
11+
**How do we get started?**
12+
13+
- Work in branch `feature-skill-add-interactive-selection`.
14+
- Use the existing CLI test setup under `packages/cli/src/__tests__`.
15+
- Reuse `inquirer` and existing `SkillManager` helpers instead of adding new dependencies.
16+
17+
## Code Structure
18+
**How is the code organized?**
19+
20+
- Command entrypoint: `packages/cli/src/commands/skill.ts`
21+
- Main orchestration: `packages/cli/src/lib/SkillManager.ts`
22+
- Tests: `packages/cli/src/__tests__/commands/skill.test.ts` and `packages/cli/src/__tests__/lib/SkillManager.test.ts`
23+
24+
## Implementation Notes
25+
**Key technical details to remember:**
26+
27+
### Core Features
28+
- Feature 1: Accept an omitted `<skill-name>` argument in the `skill add` command.
29+
- Feature 2: Enumerate installable skills from the resolved registry checkout.
30+
- Feature 3: Prompt for one skill and hand the result back into the existing install path.
31+
32+
### Patterns & Best Practices
33+
- Keep explicit two-argument installs on the current path.
34+
- Isolate prompt selection from installation side effects.
35+
- Skip malformed entries instead of failing enumeration wholesale.
36+
37+
## Integration Points
38+
**How do pieces connect?**
39+
40+
- Registry lookup continues through merged registry resolution.
41+
- Cache refresh continues through the current clone/pull helpers.
42+
- Project config updates remain in `ConfigManager.addSkill`.
43+
44+
## Error Handling
45+
**How do we handle failures?**
46+
47+
- Missing registry: fail before prompting.
48+
- Empty registry: fail with a message explaining no valid skills were found.
49+
- Prompt cancellation: exit cleanly without installation.
50+
- Non-interactive invocation without skill name: fail with explicit remediation text.
51+
52+
## Performance Considerations
53+
**How do we keep it fast?**
54+
55+
- Reuse the cloned cache after registry resolution.
56+
- Read only direct `skills/*/SKILL.md` entries needed to build the prompt.
57+
58+
## Security Notes
59+
**What security measures are in place?**
60+
61+
- Preserve existing registry and skill name validation.
62+
- Do not install unvalidated paths derived from arbitrary user input.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
phase: planning
3+
title: Project Planning & Task Breakdown
4+
description: Break down work into actionable tasks and estimate timeline
5+
feature: skill-add-interactive-selection
6+
---
7+
8+
# Project Planning & Task Breakdown - Skill Add Interactive Selection
9+
10+
## Milestones
11+
**What are the major checkpoints?**
12+
13+
- [ ] Milestone 1: Command contract updated to allow omitted skill name without breaking explicit installs.
14+
- [ ] Milestone 2: `SkillManager` can enumerate registry skills and prompt for one interactively.
15+
- [ ] Milestone 3: Tests cover prompt and non-prompt flows, plus failure cases.
16+
17+
## Task Breakdown
18+
**What specific work needs to be done?**
19+
20+
### Phase 1: Command Surface
21+
- [ ] Task 1.1: Update `packages/cli/src/commands/skill.ts` so `add` accepts `[skill-name]`.
22+
- [ ] Task 1.2: Update command descriptions/help text to document the interactive shorthand.
23+
24+
### Phase 2: Interactive Selection Flow
25+
- [ ] Task 2.1: Refactor `SkillManager.addSkill` so it can resolve a missing skill name before install.
26+
- [ ] Task 2.2: Implement registry skill enumeration from the cloned/cached repository.
27+
- [ ] Task 2.3: Implement an `inquirer` selection prompt with skill name and short description labels.
28+
- [ ] Task 2.4: Handle cancel, empty registry, invalid registry, and non-interactive contexts cleanly.
29+
30+
### Phase 3: Validation & Regression Coverage
31+
- [ ] Task 3.1: Add `SkillManager` unit tests for enumeration and prompt behavior.
32+
- [ ] Task 3.2: Add command-level tests for `ai-devkit skill add <registry>` and explicit two-arg installs.
33+
- [ ] Task 3.3: Verify no regression in config updates and environment resolution after interactive selection.
34+
35+
## Dependencies
36+
**What needs to happen in what order?**
37+
38+
```mermaid
39+
graph TD
40+
T11[1.1 Optional skill arg] --> T21[2.1 Refactor addSkill]
41+
T21 --> T22[2.2 Enumerate registry skills]
42+
T22 --> T23[2.3 Prompt selection]
43+
T23 --> T24[2.4 Edge-case handling]
44+
T24 --> T31[3.1 SkillManager tests]
45+
T11 --> T32[3.2 Command tests]
46+
T23 --> T33[3.3 Regression verification]
47+
```
48+
49+
## Timeline & Estimates
50+
**When will things be done?**
51+
52+
- Phase 1: 0.25 day
53+
- Phase 2: 0.5 day
54+
- Phase 3: 0.5 day
55+
- Total estimated effort: 1.25 days
56+
57+
## Risks & Mitigation
58+
**What could go wrong?**
59+
60+
- Risk: Some registries contain nested or malformed skill directories.
61+
- Mitigation: enumerate only folders containing `SKILL.md` and skip invalid entries.
62+
- Risk: Prompt behavior makes CI jobs hang.
63+
- Mitigation: detect non-interactive execution and require explicit `<skill-name>`.
64+
- Risk: Refactoring `addSkill` accidentally changes direct-install behavior.
65+
- Mitigation: keep installation steps intact after skill resolution and add regression tests for the two-arg path.
66+
67+
## Resources Needed
68+
**What do we need to succeed?**
69+
70+
- Existing `inquirer` dependency already used across the CLI.
71+
- Existing `SkillManager` cache and registry resolution helpers.
72+
- Jest command/lib test suites for regression coverage.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
phase: requirements
3+
title: Requirements & Problem Understanding
4+
description: Clarify the problem space, gather requirements, and define success criteria
5+
feature: skill-add-interactive-selection
6+
---
7+
8+
# Requirements & Problem Understanding - Skill Add Interactive Selection
9+
10+
## Problem Statement
11+
**What problem are we solving?**
12+
13+
- `ai-devkit skill add` currently requires both `<registry-repo>` and `<skill-name>`, even when the user already knows the registry but not the exact skill identifier.
14+
- Users installing from a registry often need a discovery step before installation, so they must leave the CLI and inspect the registry manually.
15+
- This creates friction for first-time installs and makes the add flow inconsistent with the rest of the CLI, which already uses interactive prompts in several commands.
16+
17+
**Who is affected by this problem?**
18+
19+
- Developers using `ai-devkit skill add <registry>` without knowing the exact skill name.
20+
- Teams exposing many skills from a private or custom registry.
21+
- New users evaluating available skills before installation.
22+
23+
**What is the current situation/workaround?**
24+
25+
- Users must inspect the registry repository manually and identify the skill folder name under `skills/<skill-name>`.
26+
- If they omit the skill name, the command fails at CLI argument parsing instead of helping them continue interactively.
27+
28+
## Goals & Objectives
29+
**What do we want to achieve?**
30+
31+
**Primary goals:**
32+
33+
- Allow `ai-devkit skill add <registry>` to enter an interactive selection flow when `<skill-name>` is omitted.
34+
- Build the selectable list from the requested registry itself, not from a hardcoded list.
35+
- Reuse the existing installation path once the user selects a skill.
36+
- Keep the existing explicit flow `ai-devkit skill add <registry> <skill-name>` unchanged.
37+
38+
**Secondary goals:**
39+
40+
- Show clear, user-friendly errors when the registry is missing, empty, or cannot be read.
41+
- Support the same registry sources already supported by `SkillManager` (default, global custom, project custom, cached).
42+
- Keep the selection labels descriptive enough for users to distinguish similar skills.
43+
44+
**Non-goals (explicitly out of scope):**
45+
46+
- Multi-select installation in one command.
47+
- Fuzzy search across all registries in the add flow.
48+
- Changing `skill find` behavior.
49+
- Adding a new registry metadata format.
50+
51+
## User Stories & Use Cases
52+
**How will users interact with the solution?**
53+
54+
1. As a developer, I want to run `ai-devkit skill add my-org/skills` so I can choose a skill interactively when I do not remember the exact skill name.
55+
2. As a developer, I want the CLI to show the actual skills available in that registry so I can install one without opening GitHub.
56+
3. As an automation user, I want `ai-devkit skill add <registry> <skill-name>` to keep working non-interactively so existing scripts do not break.
57+
58+
**Key workflows and scenarios:**
59+
60+
- User runs `ai-devkit skill add <registry>` in a TTY:
61+
- CLI validates the registry.
62+
- CLI fetches or reuses the cached registry repository.
63+
- CLI extracts available skills from `skills/*/SKILL.md`.
64+
- CLI shows an interactive selection list, even if the registry only exposes one valid skill.
65+
- CLI installs the selected skill using the existing add flow.
66+
- User runs `ai-devkit skill add <registry> <skill-name>`:
67+
- Existing direct install flow continues with no interactive prompt.
68+
- User cancels the prompt:
69+
- CLI exits without installing anything and reports cancellation clearly.
70+
- Registry refresh fails but a cached copy exists:
71+
- CLI warns and uses the cached registry contents to build the selection list.
72+
73+
**Edge cases to consider:**
74+
75+
- Registry ID does not exist and is not cached.
76+
- Registry exists but contains no valid skills.
77+
- Registry contains directories without `SKILL.md`.
78+
- Prompt is triggered in a non-interactive environment.
79+
- Cached registry is stale or update fails before enumeration.
80+
81+
## Success Criteria
82+
**How will we know when we're done?**
83+
84+
- `ai-devkit skill add <registry>` is accepted by the CLI.
85+
- When run interactively, the command displays a selection list populated from the target registry.
86+
- The command still shows the selection list when the registry contains exactly one valid skill.
87+
- Selecting a skill installs it through the existing installation path and updates project config exactly as today.
88+
- `ai-devkit skill add <registry> <skill-name>` continues to work without prompting.
89+
- Invalid, empty, and non-interactive cases return actionable error messages.
90+
- If registry refresh fails but a cached copy exists, the command warns and uses the cached list.
91+
- Automated tests cover direct install, interactive selection, cancellation, empty registry, and non-TTY behavior.
92+
93+
## Constraints & Assumptions
94+
**What limitations do we need to work within?**
95+
96+
**Technical constraints:**
97+
98+
- Registry resolution must remain consistent with existing merged registry behavior.
99+
- Skill discovery should rely on the registry repository structure already assumed elsewhere: `skills/<skill-name>/SKILL.md`.
100+
- The feature should reuse the current `inquirer` dependency rather than adding a new prompt library.
101+
102+
**Assumptions:**
103+
104+
- The selected registry is either configured remotely or already available in the local cache.
105+
- Skill folder names remain the install identifiers.
106+
- Description text can be derived from `SKILL.md` when available, or omitted/fallback when not available.
107+
- If a skill name is explicitly provided in the command, direct installation remains the highest-priority path.
108+
109+
## Questions & Open Items
110+
**What do we still need to clarify?**
111+
112+
- None for Phase 2 review. The prompt uses a single-select list whenever `<skill-name>` is omitted, and cached registry content is acceptable when refresh fails.

0 commit comments

Comments
 (0)