--- 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/-recipe.md` Also display the full content so the user can review it immediately. **Output Format** ```markdown # Feature Recipe: **Source**: | **Lines to type**: ~ ## Prerequisites - `Microsoft.SemanticKernel` 1.74.0 - `Microsoft.SemanticKernel.Connectors.OpenAI` 1.74.0 ## Step 1: (~N lines) ```csharp ``` ## Step 2: (~N lines) Insert after ``: ```csharp ``` ## Domain-Specific (adapt these) ### ExtractionPlugin.cs ```csharp // ADAPT: Replace field names and validation logic for your domain ``` ``` **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