@fission-ai/openspec 0.12.0 → 0.14.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 (49) hide show
  1. package/README.md +24 -3
  2. package/dist/commands/change.js +6 -6
  3. package/dist/core/archive.d.ts +1 -0
  4. package/dist/core/archive.js +3 -2
  5. package/dist/core/config.js +7 -0
  6. package/dist/core/configurators/cline.d.ts +8 -0
  7. package/dist/core/configurators/cline.js +15 -0
  8. package/dist/core/configurators/codebuddy.d.ts +8 -0
  9. package/dist/core/configurators/codebuddy.js +15 -0
  10. package/dist/core/configurators/costrict.d.ts +8 -0
  11. package/dist/core/configurators/costrict.js +15 -0
  12. package/dist/core/configurators/qoder.d.ts +30 -0
  13. package/dist/core/configurators/qoder.js +42 -0
  14. package/dist/core/configurators/qwen.d.ts +24 -0
  15. package/dist/core/configurators/qwen.js +37 -0
  16. package/dist/core/configurators/registry.js +15 -0
  17. package/dist/core/configurators/slash/auggie.d.ts +9 -0
  18. package/dist/core/configurators/slash/auggie.js +31 -0
  19. package/dist/core/configurators/slash/cline.d.ts +9 -0
  20. package/dist/core/configurators/slash/cline.js +23 -0
  21. package/dist/core/configurators/slash/codebuddy.d.ts +9 -0
  22. package/dist/core/configurators/slash/codebuddy.js +37 -0
  23. package/dist/core/configurators/slash/costrict.d.ts +9 -0
  24. package/dist/core/configurators/slash/costrict.js +31 -0
  25. package/dist/core/configurators/slash/crush.d.ts +9 -0
  26. package/dist/core/configurators/slash/crush.js +37 -0
  27. package/dist/core/configurators/slash/opencode.d.ts +3 -0
  28. package/dist/core/configurators/slash/opencode.js +41 -2
  29. package/dist/core/configurators/slash/qoder.d.ts +35 -0
  30. package/dist/core/configurators/slash/qoder.js +76 -0
  31. package/dist/core/configurators/slash/qwen.d.ts +37 -0
  32. package/dist/core/configurators/slash/qwen.js +74 -0
  33. package/dist/core/configurators/slash/registry.js +21 -0
  34. package/dist/core/init.d.ts +2 -0
  35. package/dist/core/init.js +68 -17
  36. package/dist/core/parsers/requirement-blocks.d.ts +6 -0
  37. package/dist/core/parsers/requirement-blocks.js +28 -5
  38. package/dist/core/templates/agents-template.d.ts +1 -1
  39. package/dist/core/templates/agents-template.js +5 -5
  40. package/dist/core/templates/cline-template.d.ts +2 -0
  41. package/dist/core/templates/cline-template.js +2 -0
  42. package/dist/core/templates/costrict-template.d.ts +2 -0
  43. package/dist/core/templates/costrict-template.js +2 -0
  44. package/dist/core/templates/index.d.ts +2 -0
  45. package/dist/core/templates/index.js +8 -0
  46. package/dist/core/templates/slash-command-templates.js +10 -4
  47. package/dist/core/validation/validator.d.ts +1 -0
  48. package/dist/core/validation/validator.js +57 -6
  49. package/package.json +2 -2
package/README.md CHANGED
@@ -91,14 +91,22 @@ These tools have built-in OpenSpec commands. Select the OpenSpec integration whe
91
91
  | Tool | Commands |
92
92
  |------|----------|
93
93
  | **Claude Code** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` |
94
+ | **CodeBuddy Code (CLI)** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.codebuddy/commands/`) — see [docs](https://www.codebuddy.ai/cli) |
95
+ | **CoStrict** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.cospec/openspec/commands/`) — see [docs](https://costrict.ai)|
94
96
  | **Cursor** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
97
+ | **Cline** | Rules in `.clinerules/` directory (`.clinerules/openspec-*.md`) |
98
+ | **Crush** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.crush/commands/openspec/`) |
95
99
  | **Factory Droid** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.factory/commands/`) |
96
100
  | **OpenCode** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
97
101
  | **Kilo Code** | `/openspec-proposal.md`, `/openspec-apply.md`, `/openspec-archive.md` (`.kilocode/workflows/`) |
102
+ | **Qoder (CLI)** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.qoder/commands/openspec/`) — see [docs](https://qoder.com/cli) |
98
103
  | **Windsurf** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.windsurf/workflows/`) |
99
104
  | **Codex** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (global: `~/.codex/prompts`, auto-installed) |
100
105
  | **GitHub Copilot** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.github/prompts/`) |
101
106
  | **Amazon Q Developer** | `@openspec-proposal`, `@openspec-apply`, `@openspec-archive` (`.amazonq/prompts/`) |
107
+ | **Auggie (Augment CLI)** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.augment/commands/`) |
108
+ | **Qwen Code** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.qwen/commands/`) |
109
+
102
110
 
103
111
  Kilo Code discovers team workflows automatically. Save the generated files under `.kilocode/workflows/` and trigger them from the command palette with `/openspec-proposal.md`, `/openspec-apply.md`, or `/openspec-archive.md`.
104
112
 
@@ -138,13 +146,26 @@ openspec init
138
146
  ```
139
147
 
140
148
  **What happens during initialization:**
141
- - You'll be prompted to pick any natively supported AI tools (Claude Code, Cursor, OpenCode, etc.); other assistants always rely on the shared `AGENTS.md` stub
149
+ - You'll be prompted to pick any natively supported AI tools (Claude Code, CodeBuddy, Cursor, OpenCode, Qoder,etc.); other assistants always rely on the shared `AGENTS.md` stub
142
150
  - OpenSpec automatically configures slash commands for the tools you choose and always writes a managed `AGENTS.md` hand-off at the project root
143
151
  - A new `openspec/` directory structure is created in your project
144
152
 
145
153
  **After setup:**
146
154
  - Primary AI tools can trigger `/openspec` workflows without additional configuration
147
155
  - Run `openspec list` to verify the setup and view any active changes
156
+ - If your coding assistant doesn't surface the new slash commands right away, restart it. Slash commands are loaded at startup,
157
+ so a fresh launch ensures they appear
158
+
159
+ ### Optional: Populate Project Context
160
+
161
+ After `openspec init` completes, you'll receive a suggested prompt to help populate your project context:
162
+
163
+ ```text
164
+ Populate your project context:
165
+ "Please read openspec/project.md and help me fill it out with details about my project, tech stack, and conventions"
166
+ ```
167
+
168
+ Use `openspec/project.md` to define project-level conventions, standards, architectural patterns, and other guidelines that should be followed across all changes.
148
169
 
149
170
  ### Create Your First Change
150
171
 
@@ -211,7 +232,7 @@ Or run the command yourself in terminal:
211
232
  $ openspec archive add-profile-filters --yes # Archive the completed change without prompts
212
233
  ```
213
234
 
214
- **Note:** Tools with native slash commands (Claude Code, Cursor, Codex) 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".
235
+ **Note:** Tools with native slash commands (Claude Code, CodeBuddy, Cursor, Codex, Qoder) 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".
215
236
 
216
237
  ## Command Reference
217
238
 
@@ -323,7 +344,7 @@ Without specs, AI coding assistants generate code from vague prompts, often miss
323
344
  1. **Initialize OpenSpec** – Run `openspec init` in your repo.
324
345
  2. **Start with new features** – Ask your AI to capture upcoming work as change proposals.
325
346
  3. **Grow incrementally** – Each change archives into living specs that document your system.
326
- 4. **Stay flexible** – Different teammates can use Claude Code, Cursor, or any AGENTS.md-compatible tool while sharing the same specs.
347
+ 4. **Stay flexible** – Different teammates can use Claude Code, CodeBuddy, Cursor, or any AGENTS.md-compatible tool while sharing the same specs.
327
348
 
328
349
  Run `openspec update` whenever someone switches tools so your agents pick up the latest instructions and slash-command bindings.
329
350
 
@@ -59,7 +59,7 @@ export class ChangeCommand {
59
59
  }
60
60
  const parsed = JSON.parse(jsonOutput);
61
61
  const contentForTitle = await fs.readFile(proposalPath, 'utf-8');
62
- const title = this.extractTitle(contentForTitle);
62
+ const title = this.extractTitle(contentForTitle, changeName);
63
63
  const id = parsed.name;
64
64
  const deltas = parsed.deltas || [];
65
65
  if (options.requirementsOnly || options.deltasOnly) {
@@ -111,7 +111,7 @@ export class ChangeCommand {
111
111
  }
112
112
  return {
113
113
  id: changeName,
114
- title: this.extractTitle(content),
114
+ title: this.extractTitle(content, changeName),
115
115
  deltaCount: change.deltas.length,
116
116
  taskStatus,
117
117
  };
@@ -145,7 +145,7 @@ export class ChangeCommand {
145
145
  const tasksPath = path.join(changesPath, changeName, 'tasks.md');
146
146
  try {
147
147
  const content = await fs.readFile(proposalPath, 'utf-8');
148
- const title = this.extractTitle(content);
148
+ const title = this.extractTitle(content, changeName);
149
149
  let taskStatusText = '';
150
150
  try {
151
151
  const tasksContent = await fs.readFile(tasksPath, 'utf-8');
@@ -246,9 +246,9 @@ export class ChangeCommand {
246
246
  return [];
247
247
  }
248
248
  }
249
- extractTitle(content) {
250
- const match = content.match(/^#\s+(?:Change:\s+)?(.+)$/m);
251
- return match ? match[1].trim() : 'Untitled Change';
249
+ extractTitle(content, changeName) {
250
+ const match = content.match(/^#\s+(?:Change:\s+)?(.+)$/im);
251
+ return match ? match[1].trim() : changeName;
252
252
  }
253
253
  countTasks(content) {
254
254
  const lines = content.split('\n');
@@ -3,6 +3,7 @@ export declare class ArchiveCommand {
3
3
  yes?: boolean;
4
4
  skipSpecs?: boolean;
5
5
  noValidate?: boolean;
6
+ validate?: boolean;
6
7
  }): Promise<void>;
7
8
  private selectChange;
8
9
  private checkIncompleteTasks;
@@ -38,8 +38,9 @@ export class ArchiveCommand {
38
38
  catch {
39
39
  throw new Error(`Change '${changeName}' not found.`);
40
40
  }
41
+ const skipValidation = options.validate === false || options.noValidate === true;
41
42
  // Validate specs and change before archiving
42
- if (!options.noValidate) {
43
+ if (!skipValidation) {
43
44
  const validator = new Validator();
44
45
  let hasValidationErrors = false;
45
46
  // Validate proposal.md (non-blocking unless strict mode desired in future)
@@ -182,7 +183,7 @@ export class ArchiveCommand {
182
183
  let totals = { added: 0, modified: 0, removed: 0, renamed: 0 };
183
184
  for (const p of prepared) {
184
185
  const specName = path.basename(path.dirname(p.update.target));
185
- if (!options.noValidate) {
186
+ if (!skipValidation) {
186
187
  const report = await new Validator().validateSpecContent(specName, p.rebuilt);
187
188
  if (!report.valid) {
188
189
  console.log(chalk.red(`\nValidation errors in rebuilt spec for ${specName} (will not write changes):`));
@@ -4,15 +4,22 @@ export const OPENSPEC_MARKERS = {
4
4
  end: '<!-- OPENSPEC:END -->'
5
5
  };
6
6
  export const AI_TOOLS = [
7
+ { name: 'Auggie (Augment CLI)', value: 'auggie', available: true, successLabel: 'Auggie' },
7
8
  { name: 'Claude Code', value: 'claude', available: true, successLabel: 'Claude Code' },
9
+ { name: 'Cline', value: 'cline', available: true, successLabel: 'Cline' },
10
+ { name: 'CodeBuddy Code (CLI)', value: 'codebuddy', available: true, successLabel: 'CodeBuddy Code' },
11
+ { name: 'CoStrict', value: 'costrict', available: true, successLabel: 'CoStrict' },
12
+ { name: 'Crush', value: 'crush', available: true, successLabel: 'Crush' },
8
13
  { name: 'Cursor', value: 'cursor', available: true, successLabel: 'Cursor' },
9
14
  { name: 'Factory Droid', value: 'factory', available: true, successLabel: 'Factory Droid' },
10
15
  { name: 'OpenCode', value: 'opencode', available: true, successLabel: 'OpenCode' },
11
16
  { name: 'Kilo Code', value: 'kilocode', available: true, successLabel: 'Kilo Code' },
17
+ { name: 'Qoder (CLI)', value: 'qoder', available: true, successLabel: 'Qoder' },
12
18
  { name: 'Windsurf', value: 'windsurf', available: true, successLabel: 'Windsurf' },
13
19
  { name: 'Codex', value: 'codex', available: true, successLabel: 'Codex' },
14
20
  { name: 'GitHub Copilot', value: 'github-copilot', available: true, successLabel: 'GitHub Copilot' },
15
21
  { name: 'Amazon Q Developer', value: 'amazon-q', available: true, successLabel: 'Amazon Q Developer' },
22
+ { name: 'Qwen Code', value: 'qwen', available: true, successLabel: 'Qwen Code' },
16
23
  { name: 'AGENTS.md (works with Amp, VS Code, …)', value: 'agents', available: false, successLabel: 'your AGENTS.md-compatible assistant' }
17
24
  ];
18
25
  //# sourceMappingURL=config.js.map
@@ -0,0 +1,8 @@
1
+ import { ToolConfigurator } from './base.js';
2
+ export declare class ClineConfigurator implements ToolConfigurator {
3
+ name: string;
4
+ configFileName: string;
5
+ isAvailable: boolean;
6
+ configure(projectPath: string, openspecDir: string): Promise<void>;
7
+ }
8
+ //# sourceMappingURL=cline.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 ClineConfigurator {
6
+ name = 'Cline';
7
+ configFileName = 'CLINE.md';
8
+ isAvailable = true;
9
+ async configure(projectPath, openspecDir) {
10
+ const filePath = path.join(projectPath, this.configFileName);
11
+ const content = TemplateManager.getClineTemplate();
12
+ await FileSystemUtils.updateFileWithMarkers(filePath, content, OPENSPEC_MARKERS.start, OPENSPEC_MARKERS.end);
13
+ }
14
+ }
15
+ //# sourceMappingURL=cline.js.map
@@ -0,0 +1,8 @@
1
+ import { ToolConfigurator } from './base.js';
2
+ export declare class CodeBuddyConfigurator implements ToolConfigurator {
3
+ name: string;
4
+ configFileName: string;
5
+ isAvailable: boolean;
6
+ configure(projectPath: string, openspecDir: string): Promise<void>;
7
+ }
8
+ //# sourceMappingURL=codebuddy.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 CodeBuddyConfigurator {
6
+ name = 'CodeBuddy';
7
+ configFileName = 'CODEBUDDY.md';
8
+ isAvailable = true;
9
+ async configure(projectPath, openspecDir) {
10
+ const filePath = path.join(projectPath, this.configFileName);
11
+ const content = TemplateManager.getClaudeTemplate();
12
+ await FileSystemUtils.updateFileWithMarkers(filePath, content, OPENSPEC_MARKERS.start, OPENSPEC_MARKERS.end);
13
+ }
14
+ }
15
+ //# sourceMappingURL=codebuddy.js.map
@@ -0,0 +1,8 @@
1
+ import { ToolConfigurator } from './base.js';
2
+ export declare class CostrictConfigurator implements ToolConfigurator {
3
+ name: string;
4
+ configFileName: string;
5
+ isAvailable: boolean;
6
+ configure(projectPath: string, openspecDir: string): Promise<void>;
7
+ }
8
+ //# sourceMappingURL=costrict.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 CostrictConfigurator {
6
+ name = 'CoStrict';
7
+ configFileName = 'COSTRICT.md';
8
+ isAvailable = true;
9
+ async configure(projectPath, openspecDir) {
10
+ const filePath = path.join(projectPath, this.configFileName);
11
+ const content = TemplateManager.getCostrictTemplate();
12
+ await FileSystemUtils.updateFileWithMarkers(filePath, content, OPENSPEC_MARKERS.start, OPENSPEC_MARKERS.end);
13
+ }
14
+ }
15
+ //# sourceMappingURL=costrict.js.map
@@ -0,0 +1,30 @@
1
+ import { ToolConfigurator } from './base.js';
2
+ /**
3
+ * Qoder AI Tool Configurator
4
+ *
5
+ * Configures OpenSpec integration for Qoder AI coding assistant.
6
+ * Creates and manages QODER.md configuration file with OpenSpec instructions.
7
+ *
8
+ * @implements {ToolConfigurator}
9
+ */
10
+ export declare class QoderConfigurator implements ToolConfigurator {
11
+ /** Display name for the Qoder tool */
12
+ name: string;
13
+ /** Configuration file name at project root */
14
+ configFileName: string;
15
+ /** Indicates tool is available for configuration */
16
+ isAvailable: boolean;
17
+ /**
18
+ * Configure Qoder integration for a project
19
+ *
20
+ * Creates or updates QODER.md file with OpenSpec instructions.
21
+ * Uses Claude-compatible template for instruction content.
22
+ * Wrapped with OpenSpec markers for future updates.
23
+ *
24
+ * @param {string} projectPath - Absolute path to project root directory
25
+ * @param {string} openspecDir - Path to openspec directory (unused but required by interface)
26
+ * @returns {Promise<void>} Resolves when configuration is complete
27
+ */
28
+ configure(projectPath: string, openspecDir: string): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=qoder.d.ts.map
@@ -0,0 +1,42 @@
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
+ /**
6
+ * Qoder AI Tool Configurator
7
+ *
8
+ * Configures OpenSpec integration for Qoder AI coding assistant.
9
+ * Creates and manages QODER.md configuration file with OpenSpec instructions.
10
+ *
11
+ * @implements {ToolConfigurator}
12
+ */
13
+ export class QoderConfigurator {
14
+ /** Display name for the Qoder tool */
15
+ name = 'Qoder';
16
+ /** Configuration file name at project root */
17
+ configFileName = 'QODER.md';
18
+ /** Indicates tool is available for configuration */
19
+ isAvailable = true;
20
+ /**
21
+ * Configure Qoder integration for a project
22
+ *
23
+ * Creates or updates QODER.md file with OpenSpec instructions.
24
+ * Uses Claude-compatible template for instruction content.
25
+ * Wrapped with OpenSpec markers for future updates.
26
+ *
27
+ * @param {string} projectPath - Absolute path to project root directory
28
+ * @param {string} openspecDir - Path to openspec directory (unused but required by interface)
29
+ * @returns {Promise<void>} Resolves when configuration is complete
30
+ */
31
+ async configure(projectPath, openspecDir) {
32
+ // Construct full path to QODER.md at project root
33
+ const filePath = path.join(projectPath, this.configFileName);
34
+ // Get Claude-compatible instruction template
35
+ // This ensures Qoder receives the same high-quality OpenSpec instructions
36
+ const content = TemplateManager.getClaudeTemplate();
37
+ // Write or update file with managed content between markers
38
+ // This allows future updates to refresh instructions automatically
39
+ await FileSystemUtils.updateFileWithMarkers(filePath, content, OPENSPEC_MARKERS.start, OPENSPEC_MARKERS.end);
40
+ }
41
+ }
42
+ //# sourceMappingURL=qoder.js.map
@@ -0,0 +1,24 @@
1
+ import { ToolConfigurator } from './base.js';
2
+ /**
3
+ * QwenConfigurator class provides integration with Qwen Code
4
+ * by creating and managing the necessary configuration files.
5
+ * Currently configures the QWEN.md file with OpenSpec instructions.
6
+ */
7
+ export declare class QwenConfigurator implements ToolConfigurator {
8
+ /** Display name for the Qwen Code tool */
9
+ name: string;
10
+ /** Configuration file name for Qwen Code */
11
+ configFileName: string;
12
+ /** Availability status for the Qwen Code tool */
13
+ isAvailable: boolean;
14
+ /**
15
+ * Configures the Qwen Code integration by creating or updating the QWEN.md file
16
+ * with OpenSpec instructions and markers.
17
+ *
18
+ * @param {string} projectPath - The path to the project root
19
+ * @param {string} _openspecDir - The path to the openspec directory (unused)
20
+ * @returns {Promise<void>} A promise that resolves when configuration is complete
21
+ */
22
+ configure(projectPath: string, _openspecDir: string): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=qwen.d.ts.map
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Qwen Code configurator for OpenSpec integration.
3
+ * This class handles the configuration of Qwen Code as an AI tool within OpenSpec.
4
+ *
5
+ * @implements {ToolConfigurator}
6
+ */
7
+ import path from 'path';
8
+ import { FileSystemUtils } from '../../utils/file-system.js';
9
+ import { TemplateManager } from '../templates/index.js';
10
+ import { OPENSPEC_MARKERS } from '../config.js';
11
+ /**
12
+ * QwenConfigurator class provides integration with Qwen Code
13
+ * by creating and managing the necessary configuration files.
14
+ * Currently configures the QWEN.md file with OpenSpec instructions.
15
+ */
16
+ export class QwenConfigurator {
17
+ /** Display name for the Qwen Code tool */
18
+ name = 'Qwen Code';
19
+ /** Configuration file name for Qwen Code */
20
+ configFileName = 'QWEN.md';
21
+ /** Availability status for the Qwen Code tool */
22
+ isAvailable = true;
23
+ /**
24
+ * Configures the Qwen Code integration by creating or updating the QWEN.md file
25
+ * with OpenSpec instructions and markers.
26
+ *
27
+ * @param {string} projectPath - The path to the project root
28
+ * @param {string} _openspecDir - The path to the openspec directory (unused)
29
+ * @returns {Promise<void>} A promise that resolves when configuration is complete
30
+ */
31
+ async configure(projectPath, _openspecDir) {
32
+ const filePath = path.join(projectPath, this.configFileName);
33
+ const content = TemplateManager.getAgentsStandardTemplate();
34
+ await FileSystemUtils.updateFileWithMarkers(filePath, content, OPENSPEC_MARKERS.start, OPENSPEC_MARKERS.end);
35
+ }
36
+ }
37
+ //# sourceMappingURL=qwen.js.map
@@ -1,13 +1,28 @@
1
1
  import { ClaudeConfigurator } from './claude.js';
2
+ import { ClineConfigurator } from './cline.js';
3
+ import { CodeBuddyConfigurator } from './codebuddy.js';
4
+ import { CostrictConfigurator } from './costrict.js';
5
+ import { QoderConfigurator } from './qoder.js';
2
6
  import { AgentsStandardConfigurator } from './agents.js';
7
+ import { QwenConfigurator } from './qwen.js';
3
8
  export class ToolRegistry {
4
9
  static tools = new Map();
5
10
  static {
6
11
  const claudeConfigurator = new ClaudeConfigurator();
12
+ const clineConfigurator = new ClineConfigurator();
13
+ const codeBuddyConfigurator = new CodeBuddyConfigurator();
14
+ const costrictConfigurator = new CostrictConfigurator();
15
+ const qoderConfigurator = new QoderConfigurator();
7
16
  const agentsConfigurator = new AgentsStandardConfigurator();
17
+ const qwenConfigurator = new QwenConfigurator();
8
18
  // Register with the ID that matches the checkbox value
9
19
  this.tools.set('claude', claudeConfigurator);
20
+ this.tools.set('cline', clineConfigurator);
21
+ this.tools.set('codebuddy', codeBuddyConfigurator);
22
+ this.tools.set('costrict', costrictConfigurator);
23
+ this.tools.set('qoder', qoderConfigurator);
10
24
  this.tools.set('agents', agentsConfigurator);
25
+ this.tools.set('qwen', qwenConfigurator);
11
26
  }
12
27
  static register(tool) {
13
28
  this.tools.set(tool.name.toLowerCase().replace(/\s+/g, '-'), tool);
@@ -0,0 +1,9 @@
1
+ import { SlashCommandConfigurator } from './base.js';
2
+ import { SlashCommandId } from '../../templates/index.js';
3
+ export declare class AuggieSlashCommandConfigurator extends SlashCommandConfigurator {
4
+ readonly toolId = "auggie";
5
+ readonly isAvailable = true;
6
+ protected getRelativePath(id: SlashCommandId): string;
7
+ protected getFrontmatter(id: SlashCommandId): string;
8
+ }
9
+ //# sourceMappingURL=auggie.d.ts.map
@@ -0,0 +1,31 @@
1
+ import { SlashCommandConfigurator } from './base.js';
2
+ const FILE_PATHS = {
3
+ proposal: '.augment/commands/openspec-proposal.md',
4
+ apply: '.augment/commands/openspec-apply.md',
5
+ archive: '.augment/commands/openspec-archive.md'
6
+ };
7
+ const FRONTMATTER = {
8
+ proposal: `---
9
+ description: Scaffold a new OpenSpec change and validate strictly.
10
+ argument-hint: feature description or request
11
+ ---`,
12
+ apply: `---
13
+ description: Implement an approved OpenSpec change and keep tasks in sync.
14
+ argument-hint: change-id
15
+ ---`,
16
+ archive: `---
17
+ description: Archive a deployed OpenSpec change and update specs.
18
+ argument-hint: change-id
19
+ ---`
20
+ };
21
+ export class AuggieSlashCommandConfigurator extends SlashCommandConfigurator {
22
+ toolId = 'auggie';
23
+ isAvailable = true;
24
+ getRelativePath(id) {
25
+ return FILE_PATHS[id];
26
+ }
27
+ getFrontmatter(id) {
28
+ return FRONTMATTER[id];
29
+ }
30
+ }
31
+ //# sourceMappingURL=auggie.js.map
@@ -0,0 +1,9 @@
1
+ import { SlashCommandConfigurator } from './base.js';
2
+ import { SlashCommandId } from '../../templates/index.js';
3
+ export declare class ClineSlashCommandConfigurator extends SlashCommandConfigurator {
4
+ readonly toolId = "cline";
5
+ readonly isAvailable = true;
6
+ protected getRelativePath(id: SlashCommandId): string;
7
+ protected getFrontmatter(id: SlashCommandId): string | undefined;
8
+ }
9
+ //# sourceMappingURL=cline.d.ts.map
@@ -0,0 +1,23 @@
1
+ import { SlashCommandConfigurator } from './base.js';
2
+ const FILE_PATHS = {
3
+ proposal: '.clinerules/openspec-proposal.md',
4
+ apply: '.clinerules/openspec-apply.md',
5
+ archive: '.clinerules/openspec-archive.md'
6
+ };
7
+ export class ClineSlashCommandConfigurator extends SlashCommandConfigurator {
8
+ toolId = 'cline';
9
+ isAvailable = true;
10
+ getRelativePath(id) {
11
+ return FILE_PATHS[id];
12
+ }
13
+ getFrontmatter(id) {
14
+ const descriptions = {
15
+ proposal: 'Scaffold a new OpenSpec change and validate strictly.',
16
+ apply: 'Implement an approved OpenSpec change and keep tasks in sync.',
17
+ archive: 'Archive a deployed OpenSpec change and update specs.'
18
+ };
19
+ const description = descriptions[id];
20
+ return `# OpenSpec: ${id.charAt(0).toUpperCase() + id.slice(1)}\n\n${description}`;
21
+ }
22
+ }
23
+ //# sourceMappingURL=cline.js.map
@@ -0,0 +1,9 @@
1
+ import { SlashCommandConfigurator } from './base.js';
2
+ import { SlashCommandId } from '../../templates/index.js';
3
+ export declare class CodeBuddySlashCommandConfigurator extends SlashCommandConfigurator {
4
+ readonly toolId = "codebuddy";
5
+ readonly isAvailable = true;
6
+ protected getRelativePath(id: SlashCommandId): string;
7
+ protected getFrontmatter(id: SlashCommandId): string;
8
+ }
9
+ //# sourceMappingURL=codebuddy.d.ts.map
@@ -0,0 +1,37 @@
1
+ import { SlashCommandConfigurator } from './base.js';
2
+ const FILE_PATHS = {
3
+ proposal: '.codebuddy/commands/openspec/proposal.md',
4
+ apply: '.codebuddy/commands/openspec/apply.md',
5
+ archive: '.codebuddy/commands/openspec/archive.md'
6
+ };
7
+ const FRONTMATTER = {
8
+ proposal: `---
9
+ name: OpenSpec: Proposal
10
+ description: Scaffold a new OpenSpec change and validate strictly.
11
+ category: OpenSpec
12
+ tags: [openspec, change]
13
+ ---`,
14
+ apply: `---
15
+ name: OpenSpec: Apply
16
+ description: Implement an approved OpenSpec change and keep tasks in sync.
17
+ category: OpenSpec
18
+ tags: [openspec, apply]
19
+ ---`,
20
+ archive: `---
21
+ name: OpenSpec: Archive
22
+ description: Archive a deployed OpenSpec change and update specs.
23
+ category: OpenSpec
24
+ tags: [openspec, archive]
25
+ ---`
26
+ };
27
+ export class CodeBuddySlashCommandConfigurator extends SlashCommandConfigurator {
28
+ toolId = 'codebuddy';
29
+ isAvailable = true;
30
+ getRelativePath(id) {
31
+ return FILE_PATHS[id];
32
+ }
33
+ getFrontmatter(id) {
34
+ return FRONTMATTER[id];
35
+ }
36
+ }
37
+ //# sourceMappingURL=codebuddy.js.map
@@ -0,0 +1,9 @@
1
+ import { SlashCommandConfigurator } from './base.js';
2
+ import { SlashCommandId } from '../../templates/index.js';
3
+ export declare class CostrictSlashCommandConfigurator extends SlashCommandConfigurator {
4
+ readonly toolId = "costrict";
5
+ readonly isAvailable = true;
6
+ protected getRelativePath(id: SlashCommandId): string;
7
+ protected getFrontmatter(id: SlashCommandId): string | undefined;
8
+ }
9
+ //# sourceMappingURL=costrict.d.ts.map
@@ -0,0 +1,31 @@
1
+ import { SlashCommandConfigurator } from './base.js';
2
+ const FILE_PATHS = {
3
+ proposal: '.cospec/openspec/commands/openspec-proposal.md',
4
+ apply: '.cospec/openspec/commands/openspec-apply.md',
5
+ archive: '.cospec/openspec/commands/openspec-archive.md',
6
+ };
7
+ const FRONTMATTER = {
8
+ proposal: `---
9
+ description: "Scaffold a new OpenSpec change and validate strictly."
10
+ argument-hint: feature description or request
11
+ ---`,
12
+ apply: `---
13
+ description: "Implement an approved OpenSpec change and keep tasks in sync."
14
+ argument-hint: change-id
15
+ ---`,
16
+ archive: `---
17
+ description: "Archive a deployed OpenSpec change and update specs."
18
+ argument-hint: change-id
19
+ ---`
20
+ };
21
+ export class CostrictSlashCommandConfigurator extends SlashCommandConfigurator {
22
+ toolId = 'costrict';
23
+ isAvailable = true;
24
+ getRelativePath(id) {
25
+ return FILE_PATHS[id];
26
+ }
27
+ getFrontmatter(id) {
28
+ return FRONTMATTER[id];
29
+ }
30
+ }
31
+ //# sourceMappingURL=costrict.js.map
@@ -0,0 +1,9 @@
1
+ import { SlashCommandConfigurator } from './base.js';
2
+ import { SlashCommandId } from '../../templates/index.js';
3
+ export declare class CrushSlashCommandConfigurator extends SlashCommandConfigurator {
4
+ readonly toolId = "crush";
5
+ readonly isAvailable = true;
6
+ protected getRelativePath(id: SlashCommandId): string;
7
+ protected getFrontmatter(id: SlashCommandId): string;
8
+ }
9
+ //# sourceMappingURL=crush.d.ts.map
@@ -0,0 +1,37 @@
1
+ import { SlashCommandConfigurator } from './base.js';
2
+ const FILE_PATHS = {
3
+ proposal: '.crush/commands/openspec/proposal.md',
4
+ apply: '.crush/commands/openspec/apply.md',
5
+ archive: '.crush/commands/openspec/archive.md'
6
+ };
7
+ const FRONTMATTER = {
8
+ proposal: `---
9
+ name: OpenSpec: Proposal
10
+ description: Scaffold a new OpenSpec change and validate strictly.
11
+ category: OpenSpec
12
+ tags: [openspec, change]
13
+ ---`,
14
+ apply: `---
15
+ name: OpenSpec: Apply
16
+ description: Implement an approved OpenSpec change and keep tasks in sync.
17
+ category: OpenSpec
18
+ tags: [openspec, apply]
19
+ ---`,
20
+ archive: `---
21
+ name: OpenSpec: Archive
22
+ description: Archive a deployed OpenSpec change and update specs.
23
+ category: OpenSpec
24
+ tags: [openspec, archive]
25
+ ---`
26
+ };
27
+ export class CrushSlashCommandConfigurator extends SlashCommandConfigurator {
28
+ toolId = 'crush';
29
+ isAvailable = true;
30
+ getRelativePath(id) {
31
+ return FILE_PATHS[id];
32
+ }
33
+ getFrontmatter(id) {
34
+ return FRONTMATTER[id];
35
+ }
36
+ }
37
+ //# sourceMappingURL=crush.js.map
@@ -5,5 +5,8 @@ export declare class OpenCodeSlashCommandConfigurator extends SlashCommandConfig
5
5
  readonly isAvailable = true;
6
6
  protected getRelativePath(id: SlashCommandId): string;
7
7
  protected getFrontmatter(id: SlashCommandId): string | undefined;
8
+ generateAll(projectPath: string, _openspecDir: string): Promise<string[]>;
9
+ updateExisting(projectPath: string, _openspecDir: string): Promise<string[]>;
10
+ private rewriteArchiveFile;
8
11
  }
9
12
  //# sourceMappingURL=opencode.d.ts.map