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
16 changes: 9 additions & 7 deletions openspec/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Instructions for AI coding assistants using OpenSpec for spec-driven development
- Pick a unique `change-id`: kebab-case, verb-led (`add-`, `update-`, `remove-`, `refactor-`)
- Scaffold: `proposal.md`, `tasks.md`, `design.md` (only if needed), and delta specs per affected capability
- Write deltas: use `## ADDED|MODIFIED|REMOVED|RENAMED Requirements`; include at least one `#### Scenario:` per requirement
- Validate: `openspec validate [change-id] --strict` and fix issues
- Validate: `openspec validate [change-id] --strict --no-interactive` and fix issues
- Request approval: Do not start implementation until proposal is approved

## Three-Stage Workflow
Expand Down Expand Up @@ -44,7 +44,7 @@ Skip proposal for:
1. Review `openspec/project.md`, `openspec list`, and `openspec list --specs` to understand current context.
2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, optional `design.md`, and spec deltas under `openspec/changes/<id>/`.
3. Draft spec deltas using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement.
4. Run `openspec validate <id> --strict` and resolve any issues before sharing the proposal.
4. Run `openspec validate <id> --strict --no-interactive` and resolve any issues before sharing the proposal.

### Stage 2: Implementing Changes
Track these steps as TODOs and complete them one by one.
Expand All @@ -61,7 +61,7 @@ After deployment, create separate PR to:
- Move `changes/[name]/` → `changes/archive/YYYY-MM-DD-[name]/`
- Update `specs/` if capabilities changed
- Use `openspec archive <change-id> --skip-specs --yes` for tooling-only changes (always pass the change ID explicitly)
- Run `openspec validate --strict` to confirm the archived change passes checks
- Run `openspec validate --strict --no-interactive` to confirm the archived change passes checks

## Before Any Task

Expand Down Expand Up @@ -108,7 +108,7 @@ openspec validate # Bulk validation mode

# Debugging
openspec show [change] --json --deltas-only
openspec validate [change] --strict
openspec validate [change] --strict --no-interactive
```

### Command Flags
Expand Down Expand Up @@ -160,6 +160,8 @@ New request?

2. **Write proposal.md:**
```markdown
# Change: [Brief description of change]

## Why
[1-2 sentences on problem/opportunity]

Expand Down Expand Up @@ -304,7 +306,7 @@ Example for RENAMED:

```bash
# Always use strict mode for comprehensive checks
openspec validate [change] --strict
openspec validate [change] --strict --no-interactive

# Debug delta parsing
openspec show [change] --json | jq '.deltas'
Expand Down Expand Up @@ -341,7 +343,7 @@ Users MUST provide a second factor during login.
EOF

# 4) Validate
openspec validate $CHANGE --strict
openspec validate $CHANGE --strict --no-interactive
```

## Multi-Capability Example
Expand Down Expand Up @@ -447,7 +449,7 @@ Only add complexity with:
```bash
openspec list # What's in progress?
openspec show [item] # View details
openspec validate --strict # Is it correct?
openspec validate --strict --no-interactive # Is it correct?
openspec archive <change-id> [--yes|-y] # Mark complete (add --yes for automation)
```

Expand Down
14 changes: 7 additions & 7 deletions src/core/templates/agents-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Instructions for AI coding assistants using OpenSpec for spec-driven development
- Pick a unique \`change-id\`: kebab-case, verb-led (\`add-\`, \`update-\`, \`remove-\`, \`refactor-\`)
- Scaffold: \`proposal.md\`, \`tasks.md\`, \`design.md\` (only if needed), and delta specs per affected capability
- Write deltas: use \`## ADDED|MODIFIED|REMOVED|RENAMED Requirements\`; include at least one \`#### Scenario:\` per requirement
- Validate: \`openspec validate [change-id] --strict\` and fix issues
- Validate: \`openspec validate [change-id] --strict --no-interactive\` and fix issues
- Request approval: Do not start implementation until proposal is approved

## Three-Stage Workflow
Expand Down Expand Up @@ -44,7 +44,7 @@ Skip proposal for:
1. Review \`openspec/project.md\`, \`openspec list\`, and \`openspec list --specs\` to understand current context.
2. Choose a unique verb-led \`change-id\` and scaffold \`proposal.md\`, \`tasks.md\`, optional \`design.md\`, and spec deltas under \`openspec/changes/<id>/\`.
3. Draft spec deltas using \`## ADDED|MODIFIED|REMOVED Requirements\` with at least one \`#### Scenario:\` per requirement.
4. Run \`openspec validate <id> --strict\` and resolve any issues before sharing the proposal.
4. Run \`openspec validate <id> --strict --no-interactive\` and resolve any issues before sharing the proposal.

### Stage 2: Implementing Changes
Track these steps as TODOs and complete them one by one.
Expand All @@ -61,7 +61,7 @@ After deployment, create separate PR to:
- Move \`changes/[name]/\` → \`changes/archive/YYYY-MM-DD-[name]/\`
- Update \`specs/\` if capabilities changed
- Use \`openspec archive <change-id> --skip-specs --yes\` for tooling-only changes (always pass the change ID explicitly)
- Run \`openspec validate --strict\` to confirm the archived change passes checks
- Run \`openspec validate --strict --no-interactive\` to confirm the archived change passes checks

## Before Any Task

Expand Down Expand Up @@ -108,7 +108,7 @@ openspec validate # Bulk validation mode

# Debugging
openspec show [change] --json --deltas-only
openspec validate [change] --strict
openspec validate [change] --strict --no-interactive
\`\`\`

### Command Flags
Expand Down Expand Up @@ -306,7 +306,7 @@ Example for RENAMED:

\`\`\`bash
# Always use strict mode for comprehensive checks
openspec validate [change] --strict
openspec validate [change] --strict --no-interactive

# Debug delta parsing
openspec show [change] --json | jq '.deltas'
Expand Down Expand Up @@ -343,7 +343,7 @@ Users MUST provide a second factor during login.
EOF

# 4) Validate
openspec validate $CHANGE --strict
openspec validate $CHANGE --strict --no-interactive
\`\`\`

## Multi-Capability Example
Expand Down Expand Up @@ -449,7 +449,7 @@ Only add complexity with:
\`\`\`bash
openspec list # What's in progress?
openspec show [item] # View details
openspec validate --strict # Is it correct?
openspec validate --strict --no-interactive # Is it correct?
openspec archive <change-id> [--yes|-y] # Mark complete (add --yes for automation)
\`\`\`

Expand Down
4 changes: 2 additions & 2 deletions src/core/templates/slash-command-templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const proposalSteps = `**Steps**
4. Capture architectural reasoning in \`design.md\` when the solution spans multiple systems, introduces new patterns, or demands trade-off discussion before committing to specs.
5. Draft spec deltas in \`changes/<id>/specs/<capability>/spec.md\` (one folder per capability) using \`## ADDED|MODIFIED|REMOVED Requirements\` with at least one \`#### Scenario:\` per requirement and cross-reference related capabilities when relevant.
6. Draft \`tasks.md\` as an ordered list of small, verifiable work items that deliver user-visible progress, include validation (tests, tooling), and highlight dependencies or parallelizable work.
7. Validate with \`openspec validate <id> --strict\` and resolve every issue before sharing the proposal.`;
7. Validate with \`openspec validate <id> --strict --no-interactive\` and resolve every issue before sharing the proposal.`;


const proposalReferences = `**Reference**
Expand Down Expand Up @@ -43,7 +43,7 @@ const archiveSteps = `**Steps**
2. Validate the change ID by running \`openspec list\` (or \`openspec show <id>\`) and stop if the change is missing, already archived, or otherwise not ready to archive.
3. Run \`openspec archive <id> --yes\` so the CLI moves the change and applies spec updates without prompts (use \`--skip-specs\` only for tooling-only work).
4. Review the command output to confirm the target specs were updated and the change landed in \`changes/archive/\`.
5. Validate with \`openspec validate --strict\` and inspect with \`openspec show <id>\` if anything looks off.`;
5. Validate with \`openspec validate --strict --no-interactive\` and inspect with \`openspec show <id>\` if anything looks off.`;

const archiveReferences = `**Reference**
- Use \`openspec list\` to confirm change IDs before archiving.
Expand Down
18 changes: 9 additions & 9 deletions test/core/update.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Old slash content
expect(updated).toContain('name: OpenSpec: Proposal');
expect(updated).toContain('**Guardrails**');
expect(updated).toContain(
'Validate with `openspec validate <id> --strict`'
'Validate with `openspec validate <id> --strict --no-interactive`'
);
expect(updated).not.toContain('Old slash content');

Expand Down Expand Up @@ -317,7 +317,7 @@ Old slash content
expect(updated).toContain('# OpenSpec: Proposal');
expect(updated).toContain('**Guardrails**');
expect(updated).toContain(
'Validate with `openspec validate <id> --strict`'
'Validate with `openspec validate <id> --strict --no-interactive`'
);
expect(updated).not.toContain('Old slash content');

Expand Down Expand Up @@ -1007,7 +1007,7 @@ Old slash content
expect(updated).toContain('name: OpenSpec: Proposal');
expect(updated).toContain('**Guardrails**');
expect(updated).toContain(
'Validate with `openspec validate <id> --strict`'
'Validate with `openspec validate <id> --strict --no-interactive`'
);
expect(updated).not.toContain('Old slash content');

Expand Down Expand Up @@ -1085,7 +1085,7 @@ Old slash content
expect(updated).toContain('name: OpenSpec: Proposal');
expect(updated).toContain('**Guardrails**');
expect(updated).toContain(
'Validate with `openspec validate <id> --strict`'
'Validate with `openspec validate <id> --strict --no-interactive`'
);
expect(updated).not.toContain('Old slash content');

Expand Down Expand Up @@ -1163,7 +1163,7 @@ Old body
expect(updated).toContain('argument-hint: old-hint');
expect(updated).toContain('**Guardrails**');
expect(updated).toContain(
'Validate with `openspec validate <id> --strict`'
'Validate with `openspec validate <id> --strict --no-interactive`'
);
expect(updated).not.toContain('Old body');

Expand Down Expand Up @@ -1204,7 +1204,7 @@ Old slash content
expect(updated).toContain('name: OpenSpec: Proposal');
expect(updated).toContain('**Guardrails**');
expect(updated).toContain(
'Validate with `openspec validate <id> --strict`'
'Validate with `openspec validate <id> --strict --no-interactive`'
);
expect(updated).not.toContain('Old slash content');

Expand Down Expand Up @@ -1244,7 +1244,7 @@ Old body
expect(updated).toContain('# OpenSpec: Proposal');
expect(updated).toContain('**Guardrails**');
expect(updated).toContain(
'Validate with `openspec validate <id> --strict`'
'Validate with `openspec validate <id> --strict --no-interactive`'
);
expect(updated).not.toContain('Old body');

Expand Down Expand Up @@ -1431,7 +1431,7 @@ More instructions after.`;
expect(updated).toContain('## Custom Intro Title');
expect(updated).toContain('Footer stays');
expect(updated).not.toContain('Old body');
expect(updated).toContain('Validate with `openspec validate <id> --strict`');
expect(updated).toContain('Validate with `openspec validate <id> --strict --no-interactive`');
});

it('should handle configurator errors gracefully for CoStrict', async () => {
Expand Down Expand Up @@ -1487,7 +1487,7 @@ More instructions after.`;
expect(updated).toContain('## Custom Intro Title');
expect(updated).toContain('Footer stays');
expect(updated).not.toContain('Old body');
expect(updated).toContain('Validate with `openspec validate <id> --strict`');
expect(updated).toContain('Validate with `openspec validate <id> --strict --no-interactive`');
});

it('should not create missing Windsurf workflows on update', async () => {
Expand Down
Loading