feat: add extract-feature and export-spec portability skills
Two new OpenSpec skills for porting features to sandboxed codebases: - /opsx:extract-feature generates minimal, printable code recipes - /opsx:export-spec generates compact specs for AI-assisted reimplementation Both support cumulative dependency analysis across archived changes. Includes first export of migrate-to-semantic-kernel in all three formats: code recipe (~120 lines), portable spec (~40 lines), OpenSpec variant (~25 lines). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
170
.claude/skills/openspec-extract-feature/SKILL.md
Normal file
170
.claude/skills/openspec-extract-feature/SKILL.md
Normal file
@@ -0,0 +1,170 @@
|
||||
---
|
||||
name: openspec-extract-feature
|
||||
description: Extract a feature from a change (archived or active) into a minimal, printable code recipe optimized for manual retyping into a sandboxed codebase.
|
||||
license: MIT
|
||||
compatibility: Requires openspec CLI.
|
||||
metadata:
|
||||
author: openspec
|
||||
version: "1.0"
|
||||
generatedBy: "1.2.0"
|
||||
---
|
||||
|
||||
Extract a feature into a minimal, printable code recipe for manual reimplementation.
|
||||
|
||||
Generates a markdown document with:
|
||||
- Package dependencies
|
||||
- Ordered code blocks (no comments, no boilerplate)
|
||||
- Clear markers for generic vs domain-specific code
|
||||
|
||||
Print it, take it to the sandbox, type it in.
|
||||
|
||||
---
|
||||
|
||||
**Input**: A change name (active or archived), a git commit range, or a list of files. If omitted, prompt for selection.
|
||||
|
||||
**Steps**
|
||||
|
||||
1. **Identify the source feature**
|
||||
|
||||
If a change name is provided:
|
||||
- Check active changes: `openspec list --json`
|
||||
- Check archive: look in `openspec/changes/archive/` for directories ending with the name
|
||||
- If found, read its artifacts: `proposal.md`, `design.md`, `tasks.md`
|
||||
|
||||
If no name provided:
|
||||
- Run `openspec list --json` and list archived changes
|
||||
- Use **AskUserQuestion tool** to let the user select
|
||||
|
||||
If a file list or commit range is provided instead:
|
||||
- Read those files directly
|
||||
- Identify the feature from the code
|
||||
|
||||
2. **Analyze dependency chain (cumulative mode)**
|
||||
|
||||
Features are often not independent — they build on each other. Before generating
|
||||
the recipe, determine what the target feature depends on.
|
||||
|
||||
a. **Read all archived change proposals** in `openspec/changes/archive/` (sorted by date).
|
||||
For each, read `proposal.md` to understand what it adds and what it depends on.
|
||||
|
||||
b. **Build a dependency graph**:
|
||||
- Which changes does the target feature require?
|
||||
- Which earlier changes are superseded? (e.g., if Change 6 replaces Change 3's
|
||||
implementation, include Change 6's version, not Change 3's)
|
||||
- Which changes are unrelated and can be skipped?
|
||||
|
||||
c. **Ask the user** using **AskUserQuestion tool**:
|
||||
> "This feature depends on earlier changes. How should I scope the recipe?"
|
||||
>
|
||||
> Options:
|
||||
> 1. **Cumulative** — include all foundation code this feature needs (recommended if target is a fresh codebase)
|
||||
> 2. **Delta only** — just the code this specific change adds (use if target already has the foundation)
|
||||
> 3. **Custom** — let me pick which dependencies to include
|
||||
|
||||
Show the dependency chain so the user can decide, e.g.:
|
||||
```
|
||||
migrate-to-semantic-kernel depends on:
|
||||
← basic-chat-interface (UI + shared models)
|
||||
← wire-responses-api (superseded — SK replaces the proxy)
|
||||
← multi-turn-conversations (chat history)
|
||||
```
|
||||
|
||||
d. **In cumulative mode**: Merge the dependency chain into a single coherent recipe.
|
||||
- Walk changes in dependency order
|
||||
- Skip superseded code (use the latest version of each file)
|
||||
- Collapse packages from all changes into one prerequisites section
|
||||
- If a file was created in Change 2 and modified in Change 5, include only the final version
|
||||
|
||||
e. **In delta mode**: Include only the code from the selected change.
|
||||
|
||||
3. **Analyze the feature scope**
|
||||
|
||||
From the change artifacts and/or code, determine:
|
||||
- Which files were created or modified (across the full dependency chain if cumulative)
|
||||
- What NuGet/npm packages were added
|
||||
- What the dependency order is (e.g., models before controllers)
|
||||
- What is generic infrastructure vs domain-specific logic
|
||||
|
||||
Read all relevant source files in the current codebase to get the actual current code.
|
||||
**Always read the final current version of each file**, not intermediate versions.
|
||||
|
||||
3. **Generate the code recipe**
|
||||
|
||||
Create a markdown document with these sections, in this order:
|
||||
|
||||
**Header**: Feature name, source change, date
|
||||
|
||||
**Prerequisites**: Package references with exact versions
|
||||
|
||||
**Steps**: Ordered by dependency. Each step contains:
|
||||
- Step number and action (e.g., "New file", "Add to existing file", "Modify")
|
||||
- Target path (relative, adaptable)
|
||||
- Namespace placeholder: `__YOUR_NAMESPACE__` where the target project namespace goes
|
||||
- **Code block**: The actual code, stripped of:
|
||||
- All comments (// and /* */ and /// XML docs)
|
||||
- Redundant blank lines
|
||||
- Verbose variable names that can be shortened
|
||||
- Any code not directly related to the feature
|
||||
- If the step modifies an existing file: show only the code to add, with a brief marker for insertion point (e.g., "Add after AddControllers()")
|
||||
|
||||
**Domain-Specific Sections**: Clearly marked with `// ADAPT:` prefix explaining what to change for the target domain
|
||||
|
||||
4. **Optimize for retyping**
|
||||
|
||||
Review the generated document and:
|
||||
- Merge small files if they can be combined
|
||||
- Remove any using statements that the IDE will auto-add
|
||||
- Shorten any unnecessarily verbose code
|
||||
- Ensure no step exceeds ~40 lines (split if needed)
|
||||
- Add line counts per step so the user can estimate effort
|
||||
- Total the overall line count at the top
|
||||
|
||||
5. **Write the output**
|
||||
|
||||
Save to: `openspec/exports/<change-name>-recipe.md`
|
||||
|
||||
Also display the full content so the user can review it immediately.
|
||||
|
||||
**Output Format**
|
||||
|
||||
```markdown
|
||||
# Feature Recipe: <Feature Name>
|
||||
**Source**: <change-name> | **Lines to type**: ~<N>
|
||||
|
||||
## Prerequisites
|
||||
- `Microsoft.SemanticKernel` 1.74.0
|
||||
- `Microsoft.SemanticKernel.Connectors.OpenAI` 1.74.0
|
||||
|
||||
## Step 1: <Action> — <path> (~N lines)
|
||||
|
||||
```csharp
|
||||
<stripped code>
|
||||
```
|
||||
|
||||
## Step 2: <Action> — <path> (~N lines)
|
||||
|
||||
Insert after `<marker>`:
|
||||
```csharp
|
||||
<stripped code>
|
||||
```
|
||||
|
||||
## Domain-Specific (adapt these)
|
||||
|
||||
### ExtractionPlugin.cs
|
||||
```csharp
|
||||
// ADAPT: Replace field names and validation logic for your domain
|
||||
<code>
|
||||
```
|
||||
```
|
||||
|
||||
**Guardrails**
|
||||
- Never include comments in code blocks — the goal is minimum keystrokes
|
||||
- Always read the actual current source files, not just the change artifacts
|
||||
- Preserve compilation order: models → services → controllers → DI registration
|
||||
- Mark domain-specific code clearly so the user knows what to adapt vs copy verbatim
|
||||
- Keep each step self-contained — the user may take breaks between steps
|
||||
- If a feature spans more than ~200 lines of stripped code, warn the user and suggest using `/opsx:export-spec` instead
|
||||
- Output must be valid markdown that renders well when printed
|
||||
- When in cumulative mode, skip superseded code — always use the latest version of each file
|
||||
- In the output header, show which changes were included and which were skipped (with reason)
|
||||
- If a dependency chain is long (4+ changes), suggest `/opsx:export-spec` as a more efficient alternative
|
||||
Reference in New Issue
Block a user