Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,17 @@ template/epicspec/ → epicspec/

Then use `/epicspec-create-spec` in Cursor chat.

**GitHub Copilot**

Copy these into your project root:

```
template/.github/prompts/epicspec-*.prompt.md → .github/prompts/
template/epicspec/ → epicspec/
```

Then use `/epicspec-create-spec` in Copilot Chat (VS Code, Visual Studio, or JetBrains).

### npm install

```bash
Expand Down Expand Up @@ -282,6 +293,7 @@ epicspec/
|---|---|
| Claude Code | Available — `/epicspec:create-spec` |
| Cursor | Available — `/epicspec-create-spec` |
| GitHub Copilot | Available — `/epicspec-create-spec` |
| Windsurf | Planned |

---
Expand Down Expand Up @@ -310,6 +322,7 @@ Files you'll most likely edit:
|---|---|
| `template/.claude/commands/epicspec/` | Claude Code commands |
| `template/.cursor/commands/` | Cursor commands |
| `template/.github/prompts/` | GitHub Copilot prompt files |
| `template/epicspec/` | Spec and story templates |
| `README.md` | Docs |

Expand Down
13 changes: 13 additions & 0 deletions bin/epicspec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const TEMPLATE_DIR = join(__dirname, '..', 'template');
const AGENTS = [
{ value: 'claude', label: 'Claude Code' },
{ value: 'cursor', label: 'Cursor' },
{ value: 'copilot', label: 'GitHub Copilot' },
];

// ── argument parsing ──────────────────────────────────────────────────────────
Expand Down Expand Up @@ -113,6 +114,18 @@ async function init(targetPath, force) {
}
s.stop('.cursor/commands/ ✓');
}

// GitHub Copilot
if (agents.includes('copilot')) {
s.start('Setting up GitHub Copilot...');
const dest = join(targetPath, '.github', 'prompts');
mkdirSync(dest, { recursive: true });
const src = join(TEMPLATE_DIR, '.github', 'prompts');
for (const file of readdirSync(src).filter(f => f.startsWith('epicspec'))) {
cpSync(join(src, file), join(dest, file));
}
s.stop('.github/prompts/ ✓');
}
} catch (err) {
s.stop('Failed.');
log.error(`Could not copy files: ${err.message}`);
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@epicspec/epicspec",
"version": "1.1.1",
"version": "1.2.0",
"description": "Spec-first development for AI-assisted engineering",
"author": "Eduardo Brunaldi",
"license": "MIT",
Expand Down
6 changes: 3 additions & 3 deletions template/.claude/commands/epicspec/create-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ You are a product engineering expert. Your job is to lead a structured conversat

## Goal

Gather enough context — through conversation and codebase exploration — to produce a spec rich enough for `/create-stories` to generate detailed, actionable stories without losing context between phases.
Gather enough context — through conversation and codebase exploration — to produce a spec rich enough for `/epicspec:create-stories` to generate detailed, actionable stories without losing context between phases.

The final spec will be saved at `epicspec/epics/<NNN-feature-name>/spec.md`, using `epicspec/spec-template.md` as the base.

Expand Down Expand Up @@ -121,7 +121,7 @@ Confirm to draft the spec, or adjust the approach.

Once the approach is validated, create `epicspec/epics/<NNN-feature-name>/` if it doesn't exist, then draft the spec using `epicspec/spec-template.md` as the structure.

Fill every section using what you gathered in Phases 1–3. The following guidance ensures each section has the depth that `/create-stories` needs downstream.
Fill every section using what you gathered in Phases 1–3. The following guidance ensures each section has the depth that `/epicspec:create-stories` needs downstream.

### Section-by-section guidance

Expand Down Expand Up @@ -192,7 +192,7 @@ Once approved:
Spec saved: epicspec/epics/<NNN-feature-name>/spec.md

Sections filled: N/N
Next step: run /create-stories to break this into implementable stories.
Next step: run /epicspec:create-stories to break this into implementable stories.
```

---
Expand Down
2 changes: 1 addition & 1 deletion template/.cursor/commands/epicspec-archive.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Command: /archive
# Command: /epicspec-archive

You are a project engineer. Your job is to archive a completed epic — moving it out of active development so the project stays clean and focused.

Expand Down
6 changes: 3 additions & 3 deletions template/.cursor/commands/epicspec-create-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ You are a product engineering expert. Your job is to lead a structured conversat

## Goal

Gather enough context — through conversation and codebase exploration — to produce a spec rich enough for `/create-stories` to generate detailed, actionable stories without losing context between phases.
Gather enough context — through conversation and codebase exploration — to produce a spec rich enough for `/epicspec-create-stories` to generate detailed, actionable stories without losing context between phases.

The final spec will be saved at `epicspec/epics/<NNN-feature-name>/spec.md`, using `epicspec/spec-template.md` as the base.

Expand Down Expand Up @@ -121,7 +121,7 @@ Confirm to draft the spec, or adjust the approach.

Once the approach is validated, create `epicspec/epics/<NNN-feature-name>/` if it doesn't exist, then draft the spec using `epicspec/spec-template.md` as the structure.

Fill every section using what you gathered in Phases 1–3. The following guidance ensures each section has the depth that `/create-stories` needs downstream.
Fill every section using what you gathered in Phases 1–3. The following guidance ensures each section has the depth that `/epicspec-create-stories` needs downstream.

### Section-by-section guidance

Expand Down Expand Up @@ -192,7 +192,7 @@ Once approved:
Spec saved: epicspec/epics/<NNN-feature-name>/spec.md

Sections filled: N/N
Next step: run /create-stories to break this into implementable stories.
Next step: run /epicspec-create-stories to break this into implementable stories.
```

---
Expand Down
4 changes: 2 additions & 2 deletions template/.cursor/commands/epicspec-implement-story.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ After producing the completion summary, check whether the full epic is done:
─────────────────────────────────────
All N stories in this epic are complete.

Run /epicspec:archive to archive <NNN-feature-name> and move it out of active development.
Run /epicspec-archive to archive <NNN-feature-name> and move it out of active development.
─────────────────────────────────────
```

Expand Down Expand Up @@ -342,6 +342,6 @@ To resume: start from Task 3 after resolving <blocker>.
- **Never mark the story done if any acceptance criterion is unverified** — the Phase 4 sweep must pass before the completion summary
- **Never silently skip unavailable verification** — if you can't run a verification, tell the user and ask how to proceed
- **Always update story Status in the file** — set `In Progress` when implementation begins (Phase 1), set `Done` when the story is fully verified (Phase 5); never leave the file with a stale status
- **Always check for epic completion after story completion** — if all stories in the epic are Done, suggest /epicspec:archive
- **Always check for epic completion after story completion** — if all stories in the epic are Done, suggest /epicspec-archive
- **Never implement without establishing architectural ground truth** — always run Phase 0 before touching any code; discovering the architecture after writing code is too late
- **Architecture mismatches are blockers** — treat a task description that violates the discovered architecture the same as a missing file: stop and ask, never improvise a pattern
109 changes: 109 additions & 0 deletions template/.github/prompts/epicspec-archive.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
description: "Archive a completed epic, moving it out of active development"
agent: "agent"
---

# Command: /epicspec-archive

You are a project engineer. Your job is to archive a completed epic — moving it out of active development so the project stays clean and focused.

---

## Phase 1 — Detect active epics

Scan `epicspec/epics/` for subdirectories, excluding `archive/`. Each subdirectory is a candidate epic.

**If zero epics found:**

```
No active epics found in epicspec/epics/. Nothing to archive.
```

Stop.

**If one epic found:**

```
Ready to archive: <NNN-feature-name>

Confirm? (yes / no)
```

Wait for the user to confirm before proceeding.

**If two or more epics found:**

```
Active epics:

1. <NNN-feature-name-1>
2. <NNN-feature-name-2>
...

Which epic should be archived? Reply with the number or name.
```

Wait for the user's answer before proceeding.

---

## Phase 2 — Pre-archive summary

Read the story files in `epicspec/epics/<NNN-feature-name>/stories/`. For each file, check its `Status:` field.

Present a summary:

```
Ready to archive: <NNN-feature-name>

Stories:
✓ <story-1> — Done
✓ <story-2> — Done
⚠ <story-3> — In Progress

Location: epicspec/epics/<NNN-feature-name>/ → epicspec/epics/archive/<NNN-feature-name>/

Confirm to proceed, or reply "no" to cancel.
```

If any story is not `Done`, include a warning before asking for confirmation:

```
⚠ Warning: <N> stories are not marked Done. Archiving will move the epic as-is — no data is lost, but the stories will remain unfinished in the archive.
Continue anyway? (yes / no)
```

Do not proceed until the user confirms.

---

## Phase 3 — Archive

1. Create `epicspec/epics/archive/` if it doesn't exist
2. Move `epicspec/epics/<NNN-feature-name>/` to `epicspec/epics/archive/<NNN-feature-name>/`
3. Open every `.md` file in `epicspec/epics/archive/<NNN-feature-name>/stories/` and update its `Status:` field to `Archived`

---

## Phase 4 — Confirm

```
Archived: <NNN-feature-name>

Moved to: epicspec/epics/archive/<NNN-feature-name>/
Stories marked Archived: N

To review:
epicspec/epics/archive/<NNN-feature-name>/spec.md
epicspec/epics/archive/<NNN-feature-name>/stories/
```

---

## Rules

- **Never archive without user confirmation** — always present the pre-archive summary and wait for an explicit yes
- **Never silently skip stories that aren't Done** — warn the user and require an explicit "yes" to continue with incomplete stories
- **Never delete files** — archiving is a move operation only; nothing is lost
- **Always update story statuses to Archived after moving** — the Status field must reflect the epic's archived state
- **Always create `archive/` if it doesn't exist** — do not fail if the directory is missing
Loading
Loading