@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.
- package/README.md +24 -3
- package/dist/commands/change.js +6 -6
- package/dist/core/archive.d.ts +1 -0
- package/dist/core/archive.js +3 -2
- package/dist/core/config.js +7 -0
- package/dist/core/configurators/cline.d.ts +8 -0
- package/dist/core/configurators/cline.js +15 -0
- package/dist/core/configurators/codebuddy.d.ts +8 -0
- package/dist/core/configurators/codebuddy.js +15 -0
- package/dist/core/configurators/costrict.d.ts +8 -0
- package/dist/core/configurators/costrict.js +15 -0
- package/dist/core/configurators/qoder.d.ts +30 -0
- package/dist/core/configurators/qoder.js +42 -0
- package/dist/core/configurators/qwen.d.ts +24 -0
- package/dist/core/configurators/qwen.js +37 -0
- package/dist/core/configurators/registry.js +15 -0
- package/dist/core/configurators/slash/auggie.d.ts +9 -0
- package/dist/core/configurators/slash/auggie.js +31 -0
- package/dist/core/configurators/slash/cline.d.ts +9 -0
- package/dist/core/configurators/slash/cline.js +23 -0
- package/dist/core/configurators/slash/codebuddy.d.ts +9 -0
- package/dist/core/configurators/slash/codebuddy.js +37 -0
- package/dist/core/configurators/slash/costrict.d.ts +9 -0
- package/dist/core/configurators/slash/costrict.js +31 -0
- package/dist/core/configurators/slash/crush.d.ts +9 -0
- package/dist/core/configurators/slash/crush.js +37 -0
- package/dist/core/configurators/slash/opencode.d.ts +3 -0
- package/dist/core/configurators/slash/opencode.js +41 -2
- package/dist/core/configurators/slash/qoder.d.ts +35 -0
- package/dist/core/configurators/slash/qoder.js +76 -0
- package/dist/core/configurators/slash/qwen.d.ts +37 -0
- package/dist/core/configurators/slash/qwen.js +74 -0
- package/dist/core/configurators/slash/registry.js +21 -0
- package/dist/core/init.d.ts +2 -0
- package/dist/core/init.js +68 -17
- package/dist/core/parsers/requirement-blocks.d.ts +6 -0
- package/dist/core/parsers/requirement-blocks.js +28 -5
- package/dist/core/templates/agents-template.d.ts +1 -1
- package/dist/core/templates/agents-template.js +5 -5
- package/dist/core/templates/cline-template.d.ts +2 -0
- package/dist/core/templates/cline-template.js +2 -0
- package/dist/core/templates/costrict-template.d.ts +2 -0
- package/dist/core/templates/costrict-template.js +2 -0
- package/dist/core/templates/index.d.ts +2 -0
- package/dist/core/templates/index.js +8 -0
- package/dist/core/templates/slash-command-templates.js +10 -4
- package/dist/core/validation/validator.d.ts +1 -0
- package/dist/core/validation/validator.js +57 -6
- 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
|
|
package/dist/commands/change.js
CHANGED
|
@@ -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+)?(.+)$/
|
|
251
|
-
return match ? match[1].trim() :
|
|
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');
|
package/dist/core/archive.d.ts
CHANGED
package/dist/core/archive.js
CHANGED
|
@@ -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 (!
|
|
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 (!
|
|
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):`));
|
package/dist/core/config.js
CHANGED
|
@@ -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
|