@superkou/openspec 1.4.1 → 1.4.3
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/dist/core/command-generation/adapters/index.d.ts +2 -0
- package/dist/core/command-generation/adapters/index.js +2 -0
- package/dist/core/command-generation/adapters/trae.d.ts +18 -0
- package/dist/core/command-generation/adapters/trae.js +32 -0
- package/dist/core/command-generation/adapters/zcode.d.ts +15 -0
- package/dist/core/command-generation/adapters/zcode.js +29 -0
- package/dist/core/command-generation/registry.js +4 -0
- package/dist/core/config.js +2 -1
- package/dist/utils/change-utils.d.ts +11 -5
- package/dist/utils/change-utils.js +22 -11
- package/package.json +4 -4
- package/schemas/spec-driven/templates/proposal.md +13 -4
|
@@ -28,5 +28,7 @@ export { qoderAdapter } from './qoder.js';
|
|
|
28
28
|
export { lingmaAdapter } from './lingma.js';
|
|
29
29
|
export { qwenAdapter } from './qwen.js';
|
|
30
30
|
export { roocodeAdapter } from './roocode.js';
|
|
31
|
+
export { traeAdapter } from './trae.js';
|
|
31
32
|
export { windsurfAdapter } from './windsurf.js';
|
|
33
|
+
export { zcodeAdapter } from './zcode.js';
|
|
32
34
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -28,5 +28,7 @@ export { qoderAdapter } from './qoder.js';
|
|
|
28
28
|
export { lingmaAdapter } from './lingma.js';
|
|
29
29
|
export { qwenAdapter } from './qwen.js';
|
|
30
30
|
export { roocodeAdapter } from './roocode.js';
|
|
31
|
+
export { traeAdapter } from './trae.js';
|
|
31
32
|
export { windsurfAdapter } from './windsurf.js';
|
|
33
|
+
export { zcodeAdapter } from './zcode.js';
|
|
32
34
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trae Command Adapter
|
|
3
|
+
*
|
|
4
|
+
* Formats commands for Trae following its command specification.
|
|
5
|
+
* Docs: Trae IDE 官方文档 - 命令功能
|
|
6
|
+
*
|
|
7
|
+
* Trae 支持项目级命令(.trae/commands/)和全局命令(~/.trae/commands/),
|
|
8
|
+
* 支持最多 3 层目录嵌套。本 adapter 生成项目级命令,路径为
|
|
9
|
+
* .trae/commands/opsx/<id>.md(2 层嵌套,在 3 层限制内)。
|
|
10
|
+
*/
|
|
11
|
+
import type { ToolCommandAdapter } from '../types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Trae adapter for command generation.
|
|
14
|
+
* File path: .trae/commands/opsx/<id>.md
|
|
15
|
+
* Frontmatter: name, description
|
|
16
|
+
*/
|
|
17
|
+
export declare const traeAdapter: ToolCommandAdapter;
|
|
18
|
+
//# sourceMappingURL=trae.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trae Command Adapter
|
|
3
|
+
*
|
|
4
|
+
* Formats commands for Trae following its command specification.
|
|
5
|
+
* Docs: Trae IDE 官方文档 - 命令功能
|
|
6
|
+
*
|
|
7
|
+
* Trae 支持项目级命令(.trae/commands/)和全局命令(~/.trae/commands/),
|
|
8
|
+
* 支持最多 3 层目录嵌套。本 adapter 生成项目级命令,路径为
|
|
9
|
+
* .trae/commands/opsx/<id>.md(2 层嵌套,在 3 层限制内)。
|
|
10
|
+
*/
|
|
11
|
+
import path from 'path';
|
|
12
|
+
/**
|
|
13
|
+
* Trae adapter for command generation.
|
|
14
|
+
* File path: .trae/commands/opsx/<id>.md
|
|
15
|
+
* Frontmatter: name, description
|
|
16
|
+
*/
|
|
17
|
+
export const traeAdapter = {
|
|
18
|
+
toolId: 'trae',
|
|
19
|
+
getFilePath(commandId) {
|
|
20
|
+
return path.join('.trae', 'commands', 'opsx', `${commandId}.md`);
|
|
21
|
+
},
|
|
22
|
+
formatFile(content) {
|
|
23
|
+
return `---
|
|
24
|
+
name: ${content.name}
|
|
25
|
+
description: "${content.description}"
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
${content.body}
|
|
29
|
+
`;
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=trae.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZCode Command Adapter
|
|
3
|
+
*
|
|
4
|
+
* Formats commands for ZCode CLI following its command specification.
|
|
5
|
+
* ZCode 在 .zcode/commands/ 下使用扁平的 opsx-<id>.md 命令文件,
|
|
6
|
+
* frontmatter 含 description 与可选的 argument-hint。
|
|
7
|
+
*/
|
|
8
|
+
import type { ToolCommandAdapter } from '../types.js';
|
|
9
|
+
/**
|
|
10
|
+
* ZCode adapter for command generation.
|
|
11
|
+
* File path: .zcode/commands/opsx-<id>.md
|
|
12
|
+
* Frontmatter: description, argument-hint
|
|
13
|
+
*/
|
|
14
|
+
export declare const zcodeAdapter: ToolCommandAdapter;
|
|
15
|
+
//# sourceMappingURL=zcode.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZCode Command Adapter
|
|
3
|
+
*
|
|
4
|
+
* Formats commands for ZCode CLI following its command specification.
|
|
5
|
+
* ZCode 在 .zcode/commands/ 下使用扁平的 opsx-<id>.md 命令文件,
|
|
6
|
+
* frontmatter 含 description 与可选的 argument-hint。
|
|
7
|
+
*/
|
|
8
|
+
import path from 'path';
|
|
9
|
+
/**
|
|
10
|
+
* ZCode adapter for command generation.
|
|
11
|
+
* File path: .zcode/commands/opsx-<id>.md
|
|
12
|
+
* Frontmatter: description, argument-hint
|
|
13
|
+
*/
|
|
14
|
+
export const zcodeAdapter = {
|
|
15
|
+
toolId: 'zcode',
|
|
16
|
+
getFilePath(commandId) {
|
|
17
|
+
return path.join('.zcode', 'commands', `opsx-${commandId}.md`);
|
|
18
|
+
},
|
|
19
|
+
formatFile(content) {
|
|
20
|
+
return `---
|
|
21
|
+
description: ${content.description}
|
|
22
|
+
argument-hint: command arguments
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
${content.body}
|
|
26
|
+
`;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=zcode.js.map
|
|
@@ -29,7 +29,9 @@ import { qoderAdapter } from './adapters/qoder.js';
|
|
|
29
29
|
import { lingmaAdapter } from './adapters/lingma.js';
|
|
30
30
|
import { qwenAdapter } from './adapters/qwen.js';
|
|
31
31
|
import { roocodeAdapter } from './adapters/roocode.js';
|
|
32
|
+
import { traeAdapter } from './adapters/trae.js';
|
|
32
33
|
import { windsurfAdapter } from './adapters/windsurf.js';
|
|
34
|
+
import { zcodeAdapter } from './adapters/zcode.js';
|
|
33
35
|
/**
|
|
34
36
|
* Registry for looking up tool command adapters.
|
|
35
37
|
*/
|
|
@@ -62,7 +64,9 @@ export class CommandAdapterRegistry {
|
|
|
62
64
|
CommandAdapterRegistry.register(lingmaAdapter);
|
|
63
65
|
CommandAdapterRegistry.register(qwenAdapter);
|
|
64
66
|
CommandAdapterRegistry.register(roocodeAdapter);
|
|
67
|
+
CommandAdapterRegistry.register(traeAdapter);
|
|
65
68
|
CommandAdapterRegistry.register(windsurfAdapter);
|
|
69
|
+
CommandAdapterRegistry.register(zcodeAdapter);
|
|
66
70
|
}
|
|
67
71
|
/**
|
|
68
72
|
* Register a tool command adapter.
|
package/dist/core/config.js
CHANGED
|
@@ -32,8 +32,9 @@ export const AI_TOOLS = [
|
|
|
32
32
|
{ name: 'Qoder', value: 'qoder', available: true, successLabel: 'Qoder', skillsDir: '.qoder' },
|
|
33
33
|
{ name: 'Qwen Code', value: 'qwen', available: true, successLabel: 'Qwen Code', skillsDir: '.qwen' },
|
|
34
34
|
{ name: 'RooCode', value: 'roocode', available: true, successLabel: 'RooCode', skillsDir: '.roo' },
|
|
35
|
-
{ name: 'Trae', value: 'trae', available: true, successLabel: 'Trae', skillsDir: '.trae' },
|
|
35
|
+
{ name: 'Trae', value: 'trae', available: true, successLabel: 'Trae', skillsDir: '.trae', detectionPaths: ['.trae/commands', '.trae/skills'] },
|
|
36
36
|
{ name: 'Windsurf', value: 'windsurf', available: true, successLabel: 'Windsurf', skillsDir: '.windsurf' },
|
|
37
|
+
{ name: 'ZCode', value: 'zcode', available: true, successLabel: 'ZCode', skillsDir: '.zcode', detectionPaths: ['.zcode/commands', '.zcode/skills'] },
|
|
37
38
|
{ name: 'AGENTS.md (works with Amp, VS Code, …)', value: 'agents', available: false, successLabel: 'your AGENTS.md-compatible assistant' }
|
|
38
39
|
];
|
|
39
40
|
//# sourceMappingURL=config.js.map
|
|
@@ -31,18 +31,24 @@ export interface ValidationResult {
|
|
|
31
31
|
/**
|
|
32
32
|
* Validates that a change name follows kebab-case conventions.
|
|
33
33
|
*
|
|
34
|
-
* Valid names:
|
|
35
|
-
* -
|
|
34
|
+
* Valid names (two accepted forms):
|
|
35
|
+
* - Classic kebab-case: starts with a lowercase letter
|
|
36
|
+
* (e.g., `add-auth`, `refactor-db`)
|
|
37
|
+
* - MMDD-prefixed kebab-case: starts with a 4-digit date (MMDD) followed by `-`
|
|
38
|
+
* and a kebab-case suffix (e.g., `0628-add-auth`)
|
|
39
|
+
*
|
|
40
|
+
* Both forms:
|
|
36
41
|
* - Contain only lowercase letters, numbers, and hyphens
|
|
37
|
-
* - Do not start or end with a hyphen
|
|
42
|
+
* - Do not start or end with a hyphen (the MMDD prefix's hyphen is part of the prefix)
|
|
38
43
|
* - Do not contain consecutive hyphens
|
|
39
44
|
*
|
|
40
45
|
* @param name - The change name to validate
|
|
41
46
|
* @returns Validation result with `valid: true` or `valid: false` with an error message
|
|
42
47
|
*
|
|
43
48
|
* @example
|
|
44
|
-
* validateChangeName('add-auth')
|
|
45
|
-
* validateChangeName('
|
|
49
|
+
* validateChangeName('add-auth') // { valid: true }
|
|
50
|
+
* validateChangeName('0628-add-auth') // { valid: true }
|
|
51
|
+
* validateChangeName('Add-Auth') // { valid: false, error: '...' }
|
|
46
52
|
*/
|
|
47
53
|
export declare function validateChangeName(name: string): ValidationResult;
|
|
48
54
|
/**
|
|
@@ -6,23 +6,30 @@ const DEFAULT_SCHEMA = 'spec-driven';
|
|
|
6
6
|
/**
|
|
7
7
|
* Validates that a change name follows kebab-case conventions.
|
|
8
8
|
*
|
|
9
|
-
* Valid names:
|
|
10
|
-
* -
|
|
9
|
+
* Valid names (two accepted forms):
|
|
10
|
+
* - Classic kebab-case: starts with a lowercase letter
|
|
11
|
+
* (e.g., `add-auth`, `refactor-db`)
|
|
12
|
+
* - MMDD-prefixed kebab-case: starts with a 4-digit date (MMDD) followed by `-`
|
|
13
|
+
* and a kebab-case suffix (e.g., `0628-add-auth`)
|
|
14
|
+
*
|
|
15
|
+
* Both forms:
|
|
11
16
|
* - Contain only lowercase letters, numbers, and hyphens
|
|
12
|
-
* - Do not start or end with a hyphen
|
|
17
|
+
* - Do not start or end with a hyphen (the MMDD prefix's hyphen is part of the prefix)
|
|
13
18
|
* - Do not contain consecutive hyphens
|
|
14
19
|
*
|
|
15
20
|
* @param name - The change name to validate
|
|
16
21
|
* @returns Validation result with `valid: true` or `valid: false` with an error message
|
|
17
22
|
*
|
|
18
23
|
* @example
|
|
19
|
-
* validateChangeName('add-auth')
|
|
20
|
-
* validateChangeName('
|
|
24
|
+
* validateChangeName('add-auth') // { valid: true }
|
|
25
|
+
* validateChangeName('0628-add-auth') // { valid: true }
|
|
26
|
+
* validateChangeName('Add-Auth') // { valid: false, error: '...' }
|
|
21
27
|
*/
|
|
22
28
|
export function validateChangeName(name) {
|
|
23
|
-
// Pattern:
|
|
24
|
-
//
|
|
25
|
-
|
|
29
|
+
// Pattern: two accepted forms.
|
|
30
|
+
// Form 1 (classic): ^[a-z][a-z0-9]*(-[a-z0-9]+)*$
|
|
31
|
+
// Form 2 (MMDD-prefixed): ^\d{4}-[a-z][a-z0-9]*(-[a-z0-9]+)*$
|
|
32
|
+
const kebabCasePattern = /^(?:[a-z][a-z0-9]*(?:-[a-z0-9]+)*|\d{4}-[a-z][a-z0-9]*(?:-[a-z0-9]+)*)$/;
|
|
26
33
|
if (!name) {
|
|
27
34
|
return { valid: false, error: 'Change name cannot be empty' };
|
|
28
35
|
}
|
|
@@ -49,10 +56,14 @@ export function validateChangeName(name) {
|
|
|
49
56
|
if (/[^a-z0-9-]/.test(name)) {
|
|
50
57
|
return { valid: false, error: 'Change name can only contain lowercase letters, numbers, and hyphens' };
|
|
51
58
|
}
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
// Numeric-prefixed name that didn't match Form 2: diagnose the date prefix shape
|
|
60
|
+
if (/^\d/.test(name)) {
|
|
61
|
+
if (!/^\d{4}-[a-z]/.test(name)) {
|
|
62
|
+
return { valid: false, error: 'Numeric-prefixed change name must use MMDD-<kebab> form (e.g., 0628-add-auth)' };
|
|
63
|
+
}
|
|
64
|
+
return { valid: false, error: 'Change name with MMDD prefix must be followed by kebab-case (e.g., 0628-add-auth)' };
|
|
54
65
|
}
|
|
55
|
-
return { valid: false, error: 'Change name must follow kebab-case convention (e.g., add-auth,
|
|
66
|
+
return { valid: false, error: 'Change name must follow kebab-case convention (e.g., add-auth, 0628-add-auth)' };
|
|
56
67
|
}
|
|
57
68
|
return { valid: true };
|
|
58
69
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superkou/openspec",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"description": "AI-native system for spec-driven development",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openspec",
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
"ai",
|
|
10
10
|
"development"
|
|
11
11
|
],
|
|
12
|
-
"homepage": "https://github.com/
|
|
12
|
+
"homepage": "https://github.com/sevensky/OpenSpec",
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
|
-
"url": "https://github.com/
|
|
15
|
+
"url": "git+https://github.com/sevensky/OpenSpec.git"
|
|
16
16
|
},
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"author": "OpenSpec Contributors",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
"bin": {
|
|
31
|
-
"openspec": "
|
|
31
|
+
"openspec": "bin/openspec.js"
|
|
32
32
|
},
|
|
33
33
|
"files": [
|
|
34
34
|
"dist",
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
命名约定:change 目录名用 MMDD-<kebab> 前缀(如 0628-add-auth),便于按日期排序与追溯。
|
|
3
|
+
校验已支持两种形式:经典 kebab(add-auth)与 MMDD- 前缀(0628-add-auth),优先用后者。
|
|
4
|
+
-->
|
|
5
|
+
|
|
1
6
|
## Why
|
|
2
7
|
|
|
3
8
|
<!-- 说明此变更的动机。解决什么问题?为什么现在做? -->
|
|
@@ -9,13 +14,17 @@
|
|
|
9
14
|
## Capabilities
|
|
10
15
|
|
|
11
16
|
### New Capabilities
|
|
12
|
-
<!--
|
|
17
|
+
<!--
|
|
18
|
+
引入的新能力。将 <name> 替换为 kebab-case 标识符(例如 user-auth、data-export、api-rate-limiting)。每个将创建 specs/<name>/spec.md
|
|
19
|
+
-->
|
|
13
20
|
- `<name>`: <此能力覆盖范围的简要描述>
|
|
14
21
|
|
|
15
22
|
### Modified Capabilities
|
|
16
|
-
<!--
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
<!--
|
|
24
|
+
需求发生变化的既有能力(不涉及实现细节)。
|
|
25
|
+
仅当 spec 级别行为变化时列出。每个需要 delta spec 文件。
|
|
26
|
+
使用 openspec/specs/ 中的既有 spec 名称。如无需求变更则留空。
|
|
27
|
+
-->
|
|
19
28
|
- `<existing-name>`: <哪些需求正在变化>
|
|
20
29
|
|
|
21
30
|
## Impact
|