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:
131
.claude/commands/opsx/export-spec.md
Normal file
131
.claude/commands/opsx/export-spec.md
Normal file
@@ -0,0 +1,131 @@
|
||||
---
|
||||
name: "OPSX: Export Spec"
|
||||
description: Export a feature as a compact, portable spec for AI-assisted reimplementation on a sandboxed machine
|
||||
category: Workflow
|
||||
tags: [workflow, portability, experimental]
|
||||
---
|
||||
|
||||
Export a feature as a portable spec for AI-assisted reimplementation.
|
||||
|
||||
Instead of retyping code, you retype a compact spec. The AI on the sandbox generates the code.
|
||||
|
||||
---
|
||||
|
||||
**Input**: The argument after `/opsx:export-spec` is a change name (active or archived), or a description of the feature. If omitted, prompt for selection.
|
||||
|
||||
**Steps**
|
||||
|
||||
1. **Identify the source feature**
|
||||
|
||||
Same selection logic as `/opsx:extract-feature`:
|
||||
- Check active changes and archive for the change name
|
||||
- If not found, prompt with **AskUserQuestion tool**
|
||||
- Read all artifacts: `proposal.md`, `design.md`, `tasks.md`, specs
|
||||
|
||||
2. **Analyze dependency chain (cumulative mode)**
|
||||
|
||||
Features often build on each other. Before generating the spec, determine
|
||||
what the target feature depends on.
|
||||
|
||||
a. Read all archived change proposals in `openspec/changes/archive/` (sorted by date).
|
||||
b. Build a dependency graph: what does the target require? What's superseded?
|
||||
c. Ask the user:
|
||||
> "This feature depends on earlier changes. How should I scope the spec?"
|
||||
> 1. **Cumulative** — include all foundation (recommended for fresh codebase)
|
||||
> 2. **Delta only** — just this change (target already has foundation)
|
||||
> 3. **Custom** — pick which dependencies to include
|
||||
|
||||
d. In cumulative mode: merge into one coherent spec, skip superseded components.
|
||||
e. In delta mode: add an "Assumes" section listing what must already exist.
|
||||
|
||||
3. **Read the actual implementation**
|
||||
|
||||
Read all source files created or modified by this feature (and dependencies if cumulative).
|
||||
The spec must reflect what was actually built, not just what was planned.
|
||||
|
||||
4. **Determine the target context**
|
||||
|
||||
Use **AskUserQuestion tool** to ask:
|
||||
> "Tell me about the target codebase:
|
||||
> 1. Project name / root namespace
|
||||
> 2. Existing stack (ASP.NET Core? Blazor? MudBlazor?)
|
||||
> 3. Does it already have any of these? (controllers, DI setup, chat endpoint)
|
||||
> 4. Does the target have OpenSpec? GitHub Copilot? Claude Code?"
|
||||
|
||||
This shapes what the spec assumes vs what it must specify.
|
||||
|
||||
5. **Generate the portable spec**
|
||||
|
||||
Create a single markdown document that is:
|
||||
- **Compact**: Target ~30-50 lines for a medium feature
|
||||
- **Precise**: Unambiguous enough for an AI to implement correctly
|
||||
- **Self-contained**: No references to external files or repos
|
||||
- **Stack-aware**: Uses the right terminology for the target stack
|
||||
|
||||
Structure:
|
||||
|
||||
```markdown
|
||||
# Feature: <Name>
|
||||
## Target: <project name> (<stack>)
|
||||
|
||||
## Packages
|
||||
<list with versions>
|
||||
|
||||
## Architecture
|
||||
<2-3 sentence overview>
|
||||
|
||||
## Components
|
||||
### <Component>: <path hint>
|
||||
- <What it does>
|
||||
- <Key behavior>
|
||||
- <Interface/contract>
|
||||
|
||||
## Contracts
|
||||
<API shapes, model definitions — things that MUST be exact>
|
||||
|
||||
## Wiring
|
||||
<DI registration, middleware order, config keys — dependency order>
|
||||
|
||||
## Behavior
|
||||
<Non-obvious requirements>
|
||||
```
|
||||
|
||||
**Compression strategies:**
|
||||
- Use bullet points, not prose
|
||||
- Specify contracts precisely (field names, types, API shapes)
|
||||
- Let the AI infer standard patterns
|
||||
- Only specify non-obvious behavior
|
||||
- Omit anything the AI would do by default
|
||||
|
||||
6. **Estimate typing effort**
|
||||
|
||||
Count characters in the spec. Compare to the code recipe equivalent.
|
||||
Show the compression ratio.
|
||||
|
||||
7. **Optionally generate an OpenSpec-compatible version**
|
||||
|
||||
If the target has OpenSpec, also generate:
|
||||
- A `proposal.md` (minimal — 5-10 lines)
|
||||
- A `tasks.md` (implementation steps)
|
||||
|
||||
Save as: `openspec/exports/<change-name>-openspec.md`
|
||||
|
||||
8. **Write the output**
|
||||
|
||||
Save to: `openspec/exports/<change-name>-spec.md`
|
||||
Display the full content for review.
|
||||
|
||||
**Guardrails**
|
||||
- Prioritize precision over brevity — ambiguity wastes more time than length
|
||||
- Always include exact field names, types, and API shapes
|
||||
- Include non-obvious gotchas (like /v1 base URL requirements)
|
||||
- Mental test: could an AI implement this correctly without seeing the original code?
|
||||
- If too complex for ~50 lines, split into multiple specs by component
|
||||
- Always show the compression ratio
|
||||
- Must be readable when printed in monospace — no wide tables or long lines
|
||||
- In cumulative mode, the spec must read as one coherent feature, not a list of changes
|
||||
- Skip superseded components — always describe the latest version
|
||||
- In delta mode, add an "Assumes" section so the target AI knows what must exist
|
||||
- In the output header, note which changes were included and which were skipped
|
||||
|
||||
ARGUMENTS: based on the above
|
||||
113
.claude/commands/opsx/extract-feature.md
Normal file
113
.claude/commands/opsx/extract-feature.md
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
name: "OPSX: Extract Feature"
|
||||
description: Extract a feature into a minimal, printable code recipe for manual reimplementation
|
||||
category: Workflow
|
||||
tags: [workflow, portability, experimental]
|
||||
---
|
||||
|
||||
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**: The argument after `/opsx:extract-feature` is 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 often 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).
|
||||
b. Build a dependency graph: what does the target require? What's superseded?
|
||||
c. Ask the user:
|
||||
> "This feature depends on earlier changes. How should I scope the recipe?"
|
||||
> 1. **Cumulative** — include all foundation code (recommended for fresh codebase)
|
||||
> 2. **Delta only** — just this change's code (target already has foundation)
|
||||
> 3. **Custom** — pick which dependencies to include
|
||||
|
||||
d. In cumulative mode: merge the chain, skip superseded code, use final file versions.
|
||||
e. In delta mode: include only the selected change's code.
|
||||
|
||||
3. **Analyze the feature scope**
|
||||
|
||||
From the change artifacts and/or code (across full dependency chain if cumulative), determine:
|
||||
- Which files were created or modified
|
||||
- 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. Always read the final current version of each file.
|
||||
|
||||
4. **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
|
||||
|
||||
5. **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
|
||||
|
||||
6. **Write the output**
|
||||
|
||||
Save to: `openspec/exports/<change-name>-recipe.md`
|
||||
|
||||
Also display the full content so the user can review it immediately.
|
||||
|
||||
**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
|
||||
- If a dependency chain is long (4+ changes), suggest `/opsx:export-spec` as more efficient
|
||||
|
||||
ARGUMENTS: based on the above
|
||||
Reference in New Issue
Block a user