@fission-ai/openspec 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +285 -77
  3. package/dist/cli/index.js +14 -14
  4. package/dist/core/config.d.ts +7 -5
  5. package/dist/core/config.js +3 -4
  6. package/dist/core/configurators/agents.d.ts +8 -0
  7. package/dist/core/configurators/agents.js +15 -0
  8. package/dist/core/configurators/registry.js +3 -0
  9. package/dist/core/configurators/slash/base.d.ts +17 -0
  10. package/dist/core/configurators/slash/base.js +61 -0
  11. package/dist/core/configurators/slash/claude.d.ts +9 -0
  12. package/dist/core/configurators/slash/claude.js +37 -0
  13. package/dist/core/configurators/slash/cursor.d.ts +9 -0
  14. package/dist/core/configurators/slash/cursor.js +37 -0
  15. package/dist/core/configurators/slash/registry.d.ts +8 -0
  16. package/dist/core/configurators/slash/registry.js +21 -0
  17. package/dist/core/init.d.ts +28 -0
  18. package/dist/core/init.js +387 -47
  19. package/dist/core/templates/agents-template.d.ts +2 -0
  20. package/dist/core/templates/agents-template.js +455 -0
  21. package/dist/core/templates/claude-template.d.ts +1 -1
  22. package/dist/core/templates/claude-template.js +1 -95
  23. package/dist/core/templates/index.d.ts +4 -0
  24. package/dist/core/templates/index.js +10 -3
  25. package/dist/core/templates/slash-command-templates.d.ts +4 -0
  26. package/dist/core/templates/slash-command-templates.js +40 -0
  27. package/dist/core/update.js +39 -6
  28. package/dist/core/view.d.ts +8 -0
  29. package/dist/core/view.js +148 -0
  30. package/dist/utils/file-system.d.ts +1 -0
  31. package/dist/utils/file-system.js +16 -0
  32. package/package.json +2 -2
  33. package/dist/core/diff.d.ts +0 -11
  34. package/dist/core/diff.js +0 -193
  35. package/dist/core/templates/readme-template.d.ts +0 -2
  36. package/dist/core/templates/readme-template.js +0 -519
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 OpenSpec Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md CHANGED
@@ -1,119 +1,327 @@
1
+ <p align="center">
2
+ <a href="https://github.com/Fission-AI/OpenSpec">
3
+ <picture>
4
+ <source srcset="assets/openspec_pixel_dark.svg" media="(prefers-color-scheme: dark)">
5
+ <source srcset="assets/openspec_pixel_light.svg" media="(prefers-color-scheme: light)">
6
+ <img src="assets/openspec_pixel_light.svg" alt="OpenSpec logo" height="64">
7
+ </picture>
8
+ </a>
9
+
10
+ </p>
11
+ <p align="center">Spec-driven development for AI coding assistants.</p>
12
+ <p align="center">
13
+ <a href="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml/badge.svg" /></a>
14
+ <a href="https://www.npmjs.com/package/@fission-ai/openspec"><img alt="npm version" src="https://img.shields.io/npm/v/@fission-ai/openspec?style=flat-square" /></a>
15
+ <a href="https://nodejs.org/"><img alt="node version" src="https://img.shields.io/node/v/@fission-ai/openspec?style=flat-square" /></a>
16
+ <a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" /></a>
17
+ <a href="https://conventionalcommits.org"><img alt="Conventional Commits" src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg?style=flat-square" /></a>
18
+ </p>
19
+
20
+ <p align="center">
21
+ <img src="assets/openspec_dashboard.png" alt="OpenSpec dashboard preview" width="90%">
22
+ </p>
23
+
24
+ <p align="center">
25
+ Follow <a href="https://x.com/0xTab">@0xTab on X</a> for updates.
26
+ </p>
27
+
1
28
  # OpenSpec
2
29
 
3
- A specification-driven development system for maintaining living documentation alongside your code.
30
+ OpenSpec aligns humans and AI coding assistants with spec-driven development so you agree on what to build before any code is written. **No API keys required.**
31
+
32
+ ## Why OpenSpec?
33
+
34
+ AI coding assistants are powerful but unpredictable when requirements live in chat history. OpenSpec adds a lightweight specification workflow that locks intent before implementation, giving you deterministic, reviewable outputs.
35
+
36
+ Key outcomes:
37
+ - Human and AI stakeholders agree on specs before work begins.
38
+ - Structured change folders (proposals, tasks, and spec updates) keep scope explicit and auditable.
39
+ - Shared visibility into what's proposed, active, or archived.
40
+ - Works with the AI tools you already use: custom slash commands where supported, context rules everywhere else.
41
+
42
+ ## How It Works
43
+
44
+ ```
45
+ ┌────────────────────┐
46
+ │ Draft Change │
47
+ │ Proposal │
48
+ └────────┬───────────┘
49
+ │ share intent with your AI
50
+
51
+ ┌────────────────────┐
52
+ │ Review & Align │
53
+ │ (edit specs/tasks) │◀──── feedback loop ──────┐
54
+ └────────┬───────────┘ │
55
+ │ approved plan │
56
+ ▼ │
57
+ ┌────────────────────┐ │
58
+ │ Implement Tasks │──────────────────────────┘
59
+ │ (AI writes code) │
60
+ └────────┬───────────┘
61
+ │ ship the change
62
+
63
+ ┌────────────────────┐
64
+ │ Archive & Update │
65
+ │ Specs (source) │
66
+ └────────────────────┘
67
+
68
+ 1. Draft a change proposal that captures the spec updates you want.
69
+ 2. Review the proposal with your AI assistant until everyone agrees.
70
+ 3. Implement tasks that reference the agreed specs.
71
+ 4. Archive the change to merge the approved updates back into the source-of-truth specs.
72
+ ```
73
+
74
+ ## Getting Started
4
75
 
5
- ## Installation
76
+ ### Supported AI Tools
77
+
78
+ #### Native Slash Commands
79
+ These tools have built-in OpenSpec commands. Select the OpenSpec integration when prompted.
80
+
81
+ | Tool | Commands |
82
+ |------|----------|
83
+ | **Claude Code** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` |
84
+ | **Cursor** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
85
+
86
+ #### AGENTS.md Compatible
87
+ These tools automatically read workflow instructions from `openspec/AGENTS.md`. Ask them to follow the OpenSpec workflow if they need a reminder. Learn more about the [AGENTS.md convention](https://agents.md/).
88
+
89
+ | Tools |
90
+ |-------|
91
+ | Codex • Amp • Jules • OpenCode • Gemini CLI • GitHub Copilot • Others |
92
+
93
+ ### Install & Initialize
94
+
95
+ #### Prerequisites
96
+ - **Node.js >= 20.19.0** - Check your version with `node --version`
97
+
98
+ #### Step 1: Install the CLI globally
6
99
 
7
100
  ```bash
8
- npm install -g openspec
101
+ npm install -g @fission-ai/openspec@latest
9
102
  ```
10
103
 
11
- ## Quick Start
104
+ Verify installation:
105
+ ```bash
106
+ openspec --version
107
+ ```
108
+
109
+ #### Step 2: Initialize OpenSpec in your project
110
+
111
+ Navigate to your project directory:
112
+ ```bash
113
+ cd my-project
114
+ ```
12
115
 
116
+ Run the initialization:
13
117
  ```bash
14
- # Initialize OpenSpec in your project
15
118
  openspec init
119
+ ```
120
+
121
+ **What happens during initialization:**
122
+ - You'll be prompted to select your AI tool (Claude Code, Cursor, etc.)
123
+ - OpenSpec automatically configures slash commands or `AGENTS.md` based on your selection
124
+ - A new `openspec/` directory structure is created in your project
125
+
126
+ **After setup:**
127
+ - Primary AI tools can trigger `/openspec` workflows without additional configuration
128
+ - Run `openspec list` to verify the setup and view any active changes
129
+
130
+ ### Create Your First Change
131
+
132
+ Here's a real example showing the complete OpenSpec workflow. This works with any AI tool. Those with native slash commands will recognize the shortcuts automatically.
133
+
134
+ #### 1. Draft the Proposal
135
+ Start by asking your AI to create a change proposal:
136
+
137
+ ```text
138
+ You: Create an OpenSpec change proposal for adding profile search filters by role and team
139
+ (Shortcut for tools with slash commands: /openspec:proposal Add profile search filters)
140
+
141
+ AI: I'll create an OpenSpec change proposal for profile filters.
142
+ *Scaffolds openspec/changes/add-profile-filters/ with proposal.md, tasks.md, spec deltas.*
143
+ ```
144
+
145
+ #### 2. Verify & Review
146
+ Check that the change was created correctly and review the proposal:
147
+
148
+ ```bash
149
+ $ openspec list # Confirm the change folder exists
150
+ $ openspec validate add-profile-filters # Validate spec formatting
151
+ $ openspec show add-profile-filters # Review proposal, tasks, and spec delta
152
+ ```
153
+
154
+ #### 3. Refine the Specs
155
+ Iterate on the specifications until they match your needs:
16
156
 
17
- # Update existing OpenSpec instructions (team-friendly)
18
- openspec update
157
+ ```text
158
+ You: Can you add acceptance criteria for the role and team filters?
159
+
160
+ AI: I'll update the spec delta with scenarios for role and team filters.
161
+ *Edits openspec/changes/add-profile-filters/specs/profile/spec.md and tasks.md.*
162
+ ```
19
163
 
20
- # List specs or changes
21
- openspec spec list # specs (IDs by default; use --long for details)
22
- openspec change list # changes (IDs by default; use --long for details)
164
+ #### 4. Implement the Change
165
+ Once specs look good, start implementation:
23
166
 
24
- # Show differences between specs and proposed changes
25
- openspec diff [change-name]
167
+ ```text
168
+ You: The specs look good. Let's implement this change.
169
+ (Shortcut for tools with slash commands: /openspec:apply add-profile-filters)
26
170
 
27
- # Archive completed changes
28
- openspec archive [change-name]
171
+ AI: I'll work through the tasks in the add-profile-filters change.
172
+ *Implements tasks from openspec/changes/add-profile-filters/tasks.md*
173
+ *Marks tasks complete: Task 1.1 ✓, Task 1.2 ✓, Task 2.1 ✓...*
29
174
  ```
30
175
 
31
- ## Commands
176
+ #### 5. Archive the Completed Change
177
+ After implementation is complete, archive the change:
32
178
 
33
- ### `openspec init`
179
+ ```text
180
+ AI: All tasks are complete. The implementation is ready.
34
181
 
35
- Initializes OpenSpec in your project by creating:
36
- - `openspec/` directory structure
37
- - `openspec/README.md` with OpenSpec instructions
38
- - AI tool configuration files (based on your selection)
182
+ You: Please archive the change
183
+ (Shortcut for tools with slash commands: /openspec:archive add-profile-filters)
39
184
 
40
- ### `openspec update`
185
+ AI: I'll archive the add-profile-filters change.
186
+ *Runs: openspec archive add-profile-filters*
187
+ ✓ Change archived successfully. Specs updated. Ready for the next feature!
188
+ ```
41
189
 
42
- Updates OpenSpec instructions to the latest version. This command is **team-friendly** and only updates files that already exist:
190
+ Or run the command yourself in terminal:
191
+ ```bash
192
+ $ openspec archive add-profile-filters # Archive the completed change
193
+ ```
43
194
 
44
- - Always updates `openspec/README.md` with the latest OpenSpec instructions
45
- - **Only updates existing AI tool configuration files** (e.g., CLAUDE.md, CURSOR.md)
46
- - **Never creates new AI tool configuration files**
47
- - Preserves content outside of OpenSpec markers in AI tool files
195
+ **Note:** Tools with native slash commands (Claude Code, Cursor) can use the shortcuts shown. All other tools work with natural language requests to "create an OpenSpec proposal", "apply the OpenSpec change", or "archive the change".
48
196
 
49
- This allows team members to use different AI tools without conflicts. Each developer can maintain their preferred AI tool configuration file, and `openspec update` will respect their choice.
197
+ ## Command Reference
50
198
 
51
- ### `openspec spec`
199
+ ```bash
200
+ openspec list # View active change folders
201
+ openspec view # Interactive dashboard of specs and changes
202
+ openspec show <change> # Display change details (proposal, tasks, spec updates)
203
+ openspec validate <change> # Check spec formatting and structure
204
+ openspec archive <change> # Move a completed change into archive/
205
+ ```
206
+
207
+ ## Example: How AI Creates OpenSpec Files
52
208
 
53
- Manage and view specifications.
209
+ When you ask your AI assistant to "add two-factor authentication", it creates:
54
210
 
55
- Examples:
56
- - `openspec spec show <spec-id>`
57
- - Text mode: prints raw `spec.md` content
58
- - JSON mode (`--json`): returns minimal, stable shape
59
- - Filters are JSON-only: `--requirements`, `--no-scenarios`, `-r/--requirement <1-based>`
60
- - `openspec spec list`
61
- - Prints IDs only by default
62
- - Use `--long` to include `title` and `[requirements N]`
63
- - `openspec spec validate <spec-id>`
64
- - Text: human-readable summary to stdout/stderr
65
- - `--json` for structured report
211
+ ```
212
+ openspec/
213
+ ├── specs/
214
+ │ └── auth/
215
+ │ └── spec.md # Current auth spec (if exists)
216
+ └── changes/
217
+ └── add-2fa/ # AI creates this entire structure
218
+ ├── proposal.md # Why and what changes
219
+ ├── tasks.md # Implementation checklist
220
+ ├── design.md # Technical decisions (optional)
221
+ └── specs/
222
+ └── auth/
223
+ └── spec.md # Delta showing additions
224
+ ```
66
225
 
67
- ### `openspec change`
226
+ ### AI-Generated Spec (created in `openspec/specs/auth/spec.md`):
68
227
 
69
- Manage and view change proposals.
228
+ ```markdown
229
+ # Auth Specification
70
230
 
71
- Examples:
72
- - `openspec change show <change-id>`
73
- - Text mode: prints raw `proposal.md` content
74
- - JSON mode (`--json`): `{ id, title, deltaCount, deltas }`
75
- - Filtering is JSON-only: `--deltas-only` (alias: `--requirements-only`, deprecated)
76
- - `openspec change list`
77
- - Prints IDs only by default
78
- - Use `--long` to include `title` and counts `[deltas N] [tasks x/y]`
79
- - `openspec change validate <change-id>`
80
- - Text: human-readable result
81
- - `--json` for structured report
231
+ ## Purpose
232
+ Authentication and session management.
82
233
 
83
- ### `openspec diff [change-name]`
234
+ ## Requirements
235
+ ### Requirement: User Authentication
236
+ The system SHALL issue a JWT on successful login.
84
237
 
85
- Shows the differences between current specs and proposed changes:
86
- - Displays a unified diff format
87
- - Helps review what will change before implementation
88
- - Useful for pull request reviews
238
+ #### Scenario: Valid credentials
239
+ - WHEN a user submits valid credentials
240
+ - THEN a JWT is returned
241
+ ```
89
242
 
90
- ### `openspec archive [change-name]`
243
+ ### AI-Generated Change Delta (created in `openspec/changes/add-2fa/specs/auth/spec.md`):
91
244
 
92
- Archives a completed change:
93
- - Moves change from `openspec/changes/` to `openspec/changes/archive/`
94
- - Adds a date prefix to the archived change
95
- - Updates specs to reflect the new state
96
- - Use `--skip-specs` to archive without updating specs (for abandoned changes)
245
+ ```markdown
246
+ # Delta for Auth
97
247
 
98
- ## Team Collaboration
248
+ ## ADDED Requirements
249
+ ### Requirement: Two-Factor Authentication
250
+ The system MUST require a second factor during login.
99
251
 
100
- OpenSpec is designed for team collaboration:
252
+ #### Scenario: OTP required
253
+ - WHEN a user submits valid credentials
254
+ - THEN an OTP challenge is required
255
+ ```
101
256
 
102
- 1. **AI Tool Flexibility**: Each team member can use their preferred AI assistant (Claude, Cursor, etc.)
103
- 2. **Non-Invasive Updates**: The `update` command only modifies existing files, never forcing tools on team members
104
- 3. **Specification Sharing**: The `openspec/` directory contains shared specifications that all team members work from
105
- 4. **Change Tracking**: Proposed changes are visible to all team members for review before implementation
257
+ ### AI-Generated Tasks (created in `openspec/changes/add-2fa/tasks.md`):
106
258
 
107
- ## Contributing
259
+ ```markdown
260
+ ## 1. Database Setup
261
+ - [ ] 1.1 Add OTP secret column to users table
262
+ - [ ] 1.2 Create OTP verification logs table
108
263
 
109
- See `openspec/specs/` for the current system specifications and `openspec/changes/` for pending improvements.
264
+ ## 2. Backend Implementation
265
+ - [ ] 2.1 Add OTP generation endpoint
266
+ - [ ] 2.2 Modify login flow to require OTP
267
+ - [ ] 2.3 Add OTP verification endpoint
110
268
 
111
- ## Notes
269
+ ## 3. Frontend Updates
270
+ - [ ] 3.1 Create OTP input component
271
+ - [ ] 3.2 Update login flow UI
272
+ ```
273
+
274
+ **Important:** You don't create these files manually. Your AI assistant generates them based on your requirements and the existing codebase.
275
+
276
+ ## Understanding OpenSpec Files
277
+
278
+ ### Delta Format
279
+
280
+ Deltas are "patches" that show how specs change:
281
+
282
+ - **`## ADDED Requirements`** - New capabilities
283
+ - **`## MODIFIED Requirements`** - Changed behavior (include complete updated text)
284
+ - **`## REMOVED Requirements`** - Deprecated features
285
+
286
+ **Format requirements:**
287
+ - Use `### Requirement: <name>` for headers
288
+ - Every requirement needs at least one `#### Scenario:` block
289
+ - Use SHALL/MUST in requirement text
290
+
291
+ ## How OpenSpec Compares
292
+
293
+ ### vs. Kiro.dev
294
+ OpenSpec groups every change for a feature in one folder (`openspec/changes/feature-name/`), making it easy to track related specs, tasks, and designs together. Kiro spreads updates across multiple spec folders, which can make feature tracking harder.
295
+
296
+ ### vs. No Specs
297
+ Without specs, AI coding assistants generate code from vague prompts, often missing requirements or adding unwanted features. OpenSpec brings predictability by agreeing on the desired behavior before any code is written.
298
+
299
+ ## Team Adoption
300
+
301
+ 1. **Initialize OpenSpec** – Run `openspec init` in your repo.
302
+ 2. **Start with new features** – Ask your AI to capture upcoming work as change proposals.
303
+ 3. **Grow incrementally** – Each change archives into living specs that document your system.
304
+ 4. **Stay flexible** – Different teammates can use Claude Code, Cursor, or any AGENTS.md-compatible tool while sharing the same specs.
305
+
306
+ Run `openspec update` whenever someone switches tools so your agents pick up the latest instructions and slash-command bindings.
307
+
308
+ ## Updating OpenSpec
309
+
310
+ 1. **Upgrade the package**
311
+ ```bash
312
+ npm install -g @fission-ai/openspec@latest
313
+ ```
314
+ 2. **Refresh agent instructions**
315
+ - Run `openspec update` inside each project to regenerate AI guidance and ensure the latest slash commands are active.
316
+
317
+ ## Contributing
112
318
 
113
- - The legacy `openspec list` command is deprecated. Use `openspec spec list` and `openspec change list`.
114
- - Text output is raw-first (no formatting or filtering). Prefer `--json` for tooling-friendly output.
115
- - Global `--no-color` disables ANSI colors and respects `NO_COLOR`.
319
+ - Install dependencies: `pnpm install`
320
+ - Build: `pnpm run build`
321
+ - Test: `pnpm test`
322
+ - Develop CLI locally: `pnpm run dev` or `pnpm run dev:cli`
323
+ - Conventional commits (one-line): `type(scope): subject`
116
324
 
117
325
  ## License
118
326
 
119
- MIT
327
+ MIT
package/dist/cli/index.js CHANGED
@@ -5,9 +5,9 @@ import path from 'path';
5
5
  import { promises as fs } from 'fs';
6
6
  import { InitCommand } from '../core/init.js';
7
7
  import { UpdateCommand } from '../core/update.js';
8
- import { DiffCommand } from '../core/diff.js';
9
8
  import { ListCommand } from '../core/list.js';
10
9
  import { ArchiveCommand } from '../core/archive.js';
10
+ import { ViewCommand } from '../core/view.js';
11
11
  import { registerSpecCommand } from '../commands/spec.js';
12
12
  import { ChangeCommand } from '../commands/change.js';
13
13
  import { ValidateCommand } from '../commands/validate.js';
@@ -78,12 +78,15 @@ program
78
78
  }
79
79
  });
80
80
  program
81
- .command('diff [change-name]')
82
- .description('Show differences between proposed spec changes and current specs (includes validation warnings)')
83
- .action(async (changeName) => {
81
+ .command('list')
82
+ .description('List items (changes by default). Use --specs to list specs.')
83
+ .option('--specs', 'List specs instead of changes')
84
+ .option('--changes', 'List changes explicitly (default)')
85
+ .action(async (options) => {
84
86
  try {
85
- const diffCommand = new DiffCommand();
86
- await diffCommand.execute(changeName);
87
+ const listCommand = new ListCommand();
88
+ const mode = options?.specs ? 'specs' : 'changes';
89
+ await listCommand.execute('.', mode);
87
90
  }
88
91
  catch (error) {
89
92
  console.log(); // Empty line for spacing
@@ -92,15 +95,12 @@ program
92
95
  }
93
96
  });
94
97
  program
95
- .command('list')
96
- .description('List items (changes by default). Use --specs to list specs.')
97
- .option('--specs', 'List specs instead of changes')
98
- .option('--changes', 'List changes explicitly (default)')
99
- .action(async (options) => {
98
+ .command('view')
99
+ .description('Display an interactive dashboard of specs and changes')
100
+ .action(async () => {
100
101
  try {
101
- const listCommand = new ListCommand();
102
- const mode = options?.specs ? 'specs' : 'changes';
103
- await listCommand.execute('.', mode);
102
+ const viewCommand = new ViewCommand();
103
+ await viewCommand.execute('.');
104
104
  }
105
105
  catch (error) {
106
106
  console.log(); // Empty line for spacing
@@ -1,14 +1,16 @@
1
1
  export declare const OPENSPEC_DIR_NAME = "openspec";
2
- export interface OpenSpecConfig {
3
- aiTools: string[];
4
- }
5
2
  export declare const OPENSPEC_MARKERS: {
6
3
  start: string;
7
4
  end: string;
8
5
  };
9
- export declare const AI_TOOLS: {
6
+ export interface OpenSpecConfig {
7
+ aiTools: string[];
8
+ }
9
+ export interface AIToolOption {
10
10
  name: string;
11
11
  value: string;
12
12
  available: boolean;
13
- }[];
13
+ successLabel?: string;
14
+ }
15
+ export declare const AI_TOOLS: AIToolOption[];
14
16
  //# sourceMappingURL=config.d.ts.map
@@ -4,9 +4,8 @@ export const OPENSPEC_MARKERS = {
4
4
  end: '<!-- OPENSPEC:END -->'
5
5
  };
6
6
  export const AI_TOOLS = [
7
- { name: 'Claude Code', value: 'claude', available: true },
8
- { name: 'Cursor', value: 'cursor', available: false },
9
- { name: 'Aider', value: 'aider', available: false },
10
- { name: 'Continue', value: 'continue', available: false }
7
+ { name: 'Claude Code (✅ OpenSpec custom slash commands available)', value: 'claude', available: true, successLabel: 'Claude Code' },
8
+ { name: 'Cursor (✅ OpenSpec custom slash commands available)', value: 'cursor', available: true, successLabel: 'Cursor' },
9
+ { name: 'AGENTS.md (works with Codex, Amp, Copilot, …)', value: 'agents', available: true, successLabel: 'your AGENTS.md-compatible assistant' }
11
10
  ];
12
11
  //# sourceMappingURL=config.js.map
@@ -0,0 +1,8 @@
1
+ import { ToolConfigurator } from './base.js';
2
+ export declare class AgentsStandardConfigurator implements ToolConfigurator {
3
+ name: string;
4
+ configFileName: string;
5
+ isAvailable: boolean;
6
+ configure(projectPath: string, _openspecDir: string): Promise<void>;
7
+ }
8
+ //# sourceMappingURL=agents.d.ts.map
@@ -0,0 +1,15 @@
1
+ import path from 'path';
2
+ import { FileSystemUtils } from '../../utils/file-system.js';
3
+ import { TemplateManager } from '../templates/index.js';
4
+ import { OPENSPEC_MARKERS } from '../config.js';
5
+ export class AgentsStandardConfigurator {
6
+ name = 'AGENTS.md standard';
7
+ configFileName = 'AGENTS.md';
8
+ isAvailable = true;
9
+ async configure(projectPath, _openspecDir) {
10
+ const filePath = path.join(projectPath, this.configFileName);
11
+ const content = TemplateManager.getAgentsStandardTemplate();
12
+ await FileSystemUtils.updateFileWithMarkers(filePath, content, OPENSPEC_MARKERS.start, OPENSPEC_MARKERS.end);
13
+ }
14
+ }
15
+ //# sourceMappingURL=agents.js.map
@@ -1,10 +1,13 @@
1
1
  import { ClaudeConfigurator } from './claude.js';
2
+ import { AgentsStandardConfigurator } from './agents.js';
2
3
  export class ToolRegistry {
3
4
  static tools = new Map();
4
5
  static {
5
6
  const claudeConfigurator = new ClaudeConfigurator();
7
+ const agentsConfigurator = new AgentsStandardConfigurator();
6
8
  // Register with the ID that matches the checkbox value
7
9
  this.tools.set('claude', claudeConfigurator);
10
+ this.tools.set('agents', agentsConfigurator);
8
11
  }
9
12
  static register(tool) {
10
13
  this.tools.set(tool.name.toLowerCase().replace(/\s+/g, '-'), tool);
@@ -0,0 +1,17 @@
1
+ import { SlashCommandId } from '../../templates/index.js';
2
+ export interface SlashCommandTarget {
3
+ id: SlashCommandId;
4
+ path: string;
5
+ kind: 'slash';
6
+ }
7
+ export declare abstract class SlashCommandConfigurator {
8
+ abstract readonly toolId: string;
9
+ abstract readonly isAvailable: boolean;
10
+ getTargets(): SlashCommandTarget[];
11
+ generateAll(projectPath: string, _openspecDir: string): Promise<string[]>;
12
+ updateExisting(projectPath: string, _openspecDir: string): Promise<string[]>;
13
+ protected abstract getRelativePath(id: SlashCommandId): string;
14
+ protected abstract getFrontmatter(id: SlashCommandId): string | undefined;
15
+ private updateBody;
16
+ }
17
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1,61 @@
1
+ import path from 'path';
2
+ import { FileSystemUtils } from '../../../utils/file-system.js';
3
+ import { TemplateManager } from '../../templates/index.js';
4
+ import { OPENSPEC_MARKERS } from '../../config.js';
5
+ const ALL_COMMANDS = ['proposal', 'apply', 'archive'];
6
+ export class SlashCommandConfigurator {
7
+ getTargets() {
8
+ return ALL_COMMANDS.map((id) => ({
9
+ id,
10
+ path: this.getRelativePath(id),
11
+ kind: 'slash'
12
+ }));
13
+ }
14
+ async generateAll(projectPath, _openspecDir) {
15
+ const createdOrUpdated = [];
16
+ for (const target of this.getTargets()) {
17
+ const body = TemplateManager.getSlashCommandBody(target.id).trim();
18
+ const filePath = path.join(projectPath, target.path);
19
+ if (await FileSystemUtils.fileExists(filePath)) {
20
+ await this.updateBody(filePath, body);
21
+ }
22
+ else {
23
+ const frontmatter = this.getFrontmatter(target.id);
24
+ const sections = [];
25
+ if (frontmatter) {
26
+ sections.push(frontmatter.trim());
27
+ }
28
+ sections.push(`${OPENSPEC_MARKERS.start}\n${body}\n${OPENSPEC_MARKERS.end}`);
29
+ const content = sections.join('\n') + '\n';
30
+ await FileSystemUtils.writeFile(filePath, content);
31
+ }
32
+ createdOrUpdated.push(target.path);
33
+ }
34
+ return createdOrUpdated;
35
+ }
36
+ async updateExisting(projectPath, _openspecDir) {
37
+ const updated = [];
38
+ for (const target of this.getTargets()) {
39
+ const filePath = path.join(projectPath, target.path);
40
+ if (await FileSystemUtils.fileExists(filePath)) {
41
+ const body = TemplateManager.getSlashCommandBody(target.id).trim();
42
+ await this.updateBody(filePath, body);
43
+ updated.push(target.path);
44
+ }
45
+ }
46
+ return updated;
47
+ }
48
+ async updateBody(filePath, body) {
49
+ const content = await FileSystemUtils.readFile(filePath);
50
+ const startIndex = content.indexOf(OPENSPEC_MARKERS.start);
51
+ const endIndex = content.indexOf(OPENSPEC_MARKERS.end);
52
+ if (startIndex === -1 || endIndex === -1 || endIndex <= startIndex) {
53
+ throw new Error(`Missing OpenSpec markers in ${filePath}`);
54
+ }
55
+ const before = content.slice(0, startIndex + OPENSPEC_MARKERS.start.length);
56
+ const after = content.slice(endIndex);
57
+ const updatedContent = `${before}\n${body}\n${after}`;
58
+ await FileSystemUtils.writeFile(filePath, updatedContent);
59
+ }
60
+ }
61
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1,9 @@
1
+ import { SlashCommandConfigurator } from './base.js';
2
+ import { SlashCommandId } from '../../templates/index.js';
3
+ export declare class ClaudeSlashCommandConfigurator extends SlashCommandConfigurator {
4
+ readonly toolId = "claude";
5
+ readonly isAvailable = true;
6
+ protected getRelativePath(id: SlashCommandId): string;
7
+ protected getFrontmatter(id: SlashCommandId): string;
8
+ }
9
+ //# sourceMappingURL=claude.d.ts.map