@fission-ai/openspec 1.6.0 → 1.8.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 +31 -2
- package/dist/cli/index.js +79 -8
- package/dist/commands/change.d.ts +0 -1
- package/dist/commands/change.js +105 -51
- package/dist/commands/config.js +14 -8
- package/dist/commands/doctor.js +9 -4
- package/dist/commands/feedback.js +74 -23
- package/dist/commands/schema.js +110 -31
- package/dist/commands/show.js +5 -2
- package/dist/commands/spec.js +49 -29
- package/dist/commands/validate.js +20 -5
- package/dist/commands/workflow/index.d.ts +1 -1
- package/dist/commands/workflow/index.js +1 -1
- package/dist/commands/workflow/instructions.d.ts +7 -1
- package/dist/commands/workflow/instructions.js +121 -33
- package/dist/commands/workflow/shared.d.ts +13 -2
- package/dist/commands/workflow/shared.js +34 -4
- package/dist/commands/workflow/status.js +9 -4
- package/dist/commands/workflow/templates.js +15 -5
- package/dist/core/archive.d.ts +14 -1
- package/dist/core/archive.js +1332 -155
- package/dist/core/artifact-graph/graph.d.ts +16 -0
- package/dist/core/artifact-graph/graph.js +30 -6
- package/dist/core/artifact-graph/index.d.ts +1 -1
- package/dist/core/artifact-graph/index.js +1 -1
- package/dist/core/artifact-graph/instruction-loader.d.ts +30 -3
- package/dist/core/artifact-graph/instruction-loader.js +70 -12
- package/dist/core/artifact-graph/outputs.d.ts +1 -0
- package/dist/core/artifact-graph/outputs.js +67 -5
- package/dist/core/artifact-graph/resolver.d.ts +14 -0
- package/dist/core/artifact-graph/resolver.js +69 -15
- package/dist/core/artifact-graph/types.js +21 -3
- package/dist/core/available-tools.d.ts +2 -2
- package/dist/core/available-tools.js +14 -3
- package/dist/core/change-metadata/schema.d.ts +2 -0
- package/dist/core/change-metadata/schema.js +13 -0
- package/dist/core/change-status-policy.d.ts +1 -1
- package/dist/core/change-status-policy.js +2 -2
- package/dist/core/command-generation/adapters/amazon-q.d.ts +4 -0
- package/dist/core/command-generation/adapters/amazon-q.js +7 -1
- package/dist/core/command-generation/adapters/antigravity.js +2 -1
- package/dist/core/command-generation/adapters/auggie.js +2 -1
- package/dist/core/command-generation/adapters/bob.d.ts +5 -1
- package/dist/core/command-generation/adapters/bob.js +6 -5
- package/dist/core/command-generation/adapters/claude.js +1 -8
- package/dist/core/command-generation/adapters/codebuddy.js +3 -2
- package/dist/core/command-generation/adapters/continue.js +3 -2
- package/dist/core/command-generation/adapters/costrict.js +2 -1
- package/dist/core/command-generation/adapters/crush.js +5 -5
- package/dist/core/command-generation/adapters/cursor.js +2 -2
- package/dist/core/command-generation/adapters/devin.d.ts +19 -0
- package/dist/core/command-generation/adapters/devin.js +36 -0
- package/dist/core/command-generation/adapters/factory.js +2 -1
- package/dist/core/command-generation/adapters/gemini.js +37 -2
- package/dist/core/command-generation/adapters/github-copilot.js +2 -1
- package/dist/core/command-generation/adapters/iflow.js +5 -4
- package/dist/core/command-generation/adapters/index.d.ts +2 -2
- package/dist/core/command-generation/adapters/index.js +2 -2
- package/dist/core/command-generation/adapters/junie.js +2 -1
- package/dist/core/command-generation/adapters/kiro.js +2 -1
- package/dist/core/command-generation/adapters/lingma.js +5 -5
- package/dist/core/command-generation/adapters/oh-my-pi.d.ts +2 -2
- package/dist/core/command-generation/adapters/oh-my-pi.js +3 -5
- package/dist/core/command-generation/adapters/opencode.js +3 -5
- package/dist/core/command-generation/adapters/pi.d.ts +2 -2
- package/dist/core/command-generation/adapters/pi.js +3 -6
- package/dist/core/command-generation/adapters/qoder.js +5 -5
- package/dist/core/command-generation/adapters/qwen.d.ts +7 -3
- package/dist/core/command-generation/adapters/qwen.js +12 -7
- package/dist/core/command-generation/adapters/roocode.d.ts +4 -4
- package/dist/core/command-generation/adapters/roocode.js +4 -4
- package/dist/core/command-generation/adapters/trae.js +1 -21
- package/dist/core/command-generation/adapters/zcode.d.ts +16 -0
- package/dist/core/command-generation/adapters/zcode.js +33 -0
- package/dist/core/command-generation/generator.d.ts +8 -0
- package/dist/core/command-generation/generator.js +15 -1
- package/dist/core/command-generation/index.d.ts +1 -1
- package/dist/core/command-generation/index.js +1 -1
- package/dist/core/command-generation/invocation.d.ts +73 -0
- package/dist/core/command-generation/invocation.js +77 -0
- package/dist/core/command-generation/registry.js +4 -4
- package/dist/core/command-generation/types.d.ts +9 -2
- package/dist/core/command-generation/yaml.d.ts +20 -6
- package/dist/core/command-generation/yaml.js +31 -21
- package/dist/core/command-surface.d.ts +15 -0
- package/dist/core/command-surface.js +33 -0
- package/dist/core/completions/command-registry.js +16 -2
- package/dist/core/completions/generators/powershell-generator.js +15 -8
- package/dist/core/completions/installers/zsh-installer.d.ts +9 -0
- package/dist/core/completions/installers/zsh-installer.js +20 -4
- package/dist/core/config-prompts.d.ts +1 -1
- package/dist/core/config-prompts.js +14 -1
- package/dist/core/config-schema.d.ts +10 -1
- package/dist/core/config-schema.js +67 -1
- package/dist/core/config.d.ts +15 -0
- package/dist/core/config.js +45 -5
- package/dist/core/file-state.js +56 -24
- package/dist/core/github-copilot/cloud-agent.d.ts +95 -0
- package/dist/core/github-copilot/cloud-agent.js +497 -0
- package/dist/core/global-config.d.ts +16 -0
- package/dist/core/init.d.ts +58 -0
- package/dist/core/init.js +450 -69
- package/dist/core/legacy-cleanup.d.ts +59 -0
- package/dist/core/legacy-cleanup.js +253 -24
- package/dist/core/list.js +5 -7
- package/dist/core/migration.d.ts +73 -1
- package/dist/core/migration.js +360 -11
- package/dist/core/onboarding-commands.d.ts +30 -0
- package/dist/core/onboarding-commands.js +38 -0
- package/dist/core/parsers/change-parser.d.ts +17 -2
- package/dist/core/parsers/change-parser.js +33 -20
- package/dist/core/parsers/code-fence.d.ts +15 -0
- package/dist/core/parsers/code-fence.js +49 -0
- package/dist/core/parsers/markdown-parser.js +2 -1
- package/dist/core/parsers/requirement-blocks.d.ts +18 -0
- package/dist/core/parsers/requirement-blocks.js +120 -35
- package/dist/core/parsers/requirement-text.d.ts +1 -8
- package/dist/core/parsers/requirement-text.js +4 -42
- package/dist/core/parsers/spec-structure.d.ts +1 -1
- package/dist/core/parsers/spec-structure.js +20 -30
- package/dist/core/profile-sync-drift.d.ts +0 -8
- package/dist/core/profile-sync-drift.js +48 -49
- package/dist/core/project-config.d.ts +28 -6
- package/dist/core/project-config.js +108 -8
- package/dist/core/references.js +42 -4
- package/dist/core/relationship-health.d.ts +8 -0
- package/dist/core/relationship-health.js +13 -0
- package/dist/core/root-selection.d.ts +9 -6
- package/dist/core/root-selection.js +42 -5
- package/dist/core/shared/index.d.ts +1 -0
- package/dist/core/shared/index.js +1 -0
- package/dist/core/shared/skill-content-equivalence.d.ts +7 -0
- package/dist/core/shared/skill-content-equivalence.js +41 -0
- package/dist/core/shared/skill-paths.d.ts +13 -0
- package/dist/core/shared/skill-paths.js +23 -0
- package/dist/core/shared/tool-detection.d.ts +25 -5
- package/dist/core/shared/tool-detection.js +166 -36
- package/dist/core/shared-skill-target.d.ts +16 -0
- package/dist/core/shared-skill-target.js +156 -0
- package/dist/core/specs-apply.d.ts +80 -33
- package/dist/core/specs-apply.js +659 -171
- package/dist/core/store/git.d.ts +13 -0
- package/dist/core/store/git.js +24 -0
- package/dist/core/templates/skill-templates.d.ts +1 -1
- package/dist/core/templates/skill-templates.js +1 -1
- package/dist/core/templates/workflows/apply-change.d.ts +10 -0
- package/dist/core/templates/workflows/apply-change.js +48 -158
- package/dist/core/templates/workflows/archive-change.js +170 -42
- package/dist/core/templates/workflows/bulk-archive-change.js +256 -75
- package/dist/core/templates/workflows/continue-change.js +38 -46
- package/dist/core/templates/workflows/explore.js +54 -18
- package/dist/core/templates/workflows/ff-change.js +46 -30
- package/dist/core/templates/workflows/new-change.js +2 -2
- package/dist/core/templates/workflows/onboard.js +13 -7
- package/dist/core/templates/workflows/propose.js +116 -46
- package/dist/core/templates/workflows/store-selection.d.ts +1 -1
- package/dist/core/templates/workflows/store-selection.js +1 -1
- package/dist/core/templates/workflows/sync-specs.js +260 -32
- package/dist/core/templates/workflows/update-change.js +26 -16
- package/dist/core/templates/workflows/verify-change.js +16 -10
- package/dist/core/update.d.ts +40 -5
- package/dist/core/update.js +389 -93
- package/dist/core/validation/constants.d.ts +4 -1
- package/dist/core/validation/constants.js +4 -1
- package/dist/core/validation/validator.d.ts +22 -8
- package/dist/core/validation/validator.js +222 -50
- package/dist/core/version-check.d.ts +152 -0
- package/dist/core/version-check.js +731 -0
- package/dist/core/view.js +12 -17
- package/dist/prompts/searchable-multi-select.js +1 -1
- package/dist/telemetry/config.d.ts +3 -4
- package/dist/telemetry/index.d.ts +10 -5
- package/dist/telemetry/index.js +75 -41
- package/dist/ui/welcome-screen.d.ts +9 -1
- package/dist/ui/welcome-screen.js +91 -38
- package/dist/utils/change-metadata.d.ts +43 -0
- package/dist/utils/change-metadata.js +123 -7
- package/dist/utils/change-utils.d.ts +10 -4
- package/dist/utils/change-utils.js +20 -13
- package/dist/utils/ci.d.ts +12 -0
- package/dist/utils/ci.js +16 -0
- package/dist/utils/command-references.d.ts +92 -6
- package/dist/utils/command-references.js +180 -7
- package/dist/utils/date.d.ts +8 -0
- package/dist/utils/date.js +13 -0
- package/dist/utils/file-system.d.ts +10 -0
- package/dist/utils/file-system.js +70 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/interactive.d.ts +23 -0
- package/dist/utils/interactive.js +32 -0
- package/dist/utils/item-discovery.d.ts +19 -0
- package/dist/utils/item-discovery.js +30 -48
- package/dist/utils/shell-detection.d.ts +1 -1
- package/dist/utils/shell-detection.js +64 -11
- package/dist/utils/spec-discovery.d.ts +40 -0
- package/dist/utils/spec-discovery.js +115 -0
- package/dist/utils/task-progress.d.ts +17 -0
- package/dist/utils/task-progress.js +41 -13
- package/package.json +14 -12
- package/schemas/spec-driven/schema.yaml +67 -10
- package/schemas/spec-driven/templates/design.md +2 -2
- package/schemas/spec-driven/templates/proposal.md +10 -4
- package/schemas/spec-driven/templates/spec.md +3 -0
- package/dist/core/command-generation/adapters/codex.d.ts +0 -16
- package/dist/core/command-generation/adapters/codex.js +0 -39
- package/dist/core/command-generation/adapters/windsurf.d.ts +0 -14
- package/dist/core/command-generation/adapters/windsurf.js +0 -38
|
@@ -4,6 +4,41 @@
|
|
|
4
4
|
* Formats commands for Gemini CLI following its TOML specification.
|
|
5
5
|
*/
|
|
6
6
|
import path from 'path';
|
|
7
|
+
/**
|
|
8
|
+
* Control characters (C0 except tab/newline/carriage return, plus DEL) are
|
|
9
|
+
* invalid inside TOML strings and must be written as escapes.
|
|
10
|
+
*/
|
|
11
|
+
const TOML_CONTROL_CHARS = new RegExp('[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]', 'g');
|
|
12
|
+
/**
|
|
13
|
+
* TOML basic strings are escape-active: a backslash or double quote in the
|
|
14
|
+
* value breaks the file if written raw. Newlines cannot appear in a
|
|
15
|
+
* single-line basic string at all, so they are escaped too.
|
|
16
|
+
*/
|
|
17
|
+
function escapeTomlBasicString(value) {
|
|
18
|
+
return value
|
|
19
|
+
.replace(/\\/g, '\\\\')
|
|
20
|
+
.replace(/"/g, '\\"')
|
|
21
|
+
.replace(/\n/g, '\\n')
|
|
22
|
+
.replace(/\r/g, '\\r')
|
|
23
|
+
.replace(/\t/g, '\\t')
|
|
24
|
+
.replace(TOML_CONTROL_CHARS, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Multiline basic strings keep raw newlines and tabs, but backslashes are
|
|
28
|
+
* still escape-active, any run of three quotes would end the string, and the
|
|
29
|
+
* same control characters are invalid as in single-line basic strings — a
|
|
30
|
+
* lone carriage return included (only LF and CRLF may appear raw; CRLF is
|
|
31
|
+
* normalized away so the emitted file is single-convention). Escapes are
|
|
32
|
+
* introduced after backslash-doubling so they are not re-doubled.
|
|
33
|
+
*/
|
|
34
|
+
function escapeTomlMultilineBasicString(value) {
|
|
35
|
+
return value
|
|
36
|
+
.replace(/\r\n/g, '\n')
|
|
37
|
+
.replace(/\\/g, '\\\\')
|
|
38
|
+
.replace(/"""/g, '""\\"')
|
|
39
|
+
.replace(/\r/g, '\\r')
|
|
40
|
+
.replace(TOML_CONTROL_CHARS, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`);
|
|
41
|
+
}
|
|
7
42
|
/**
|
|
8
43
|
* Gemini adapter for command generation.
|
|
9
44
|
* File path: .gemini/commands/opsx/<id>.toml
|
|
@@ -15,10 +50,10 @@ export const geminiAdapter = {
|
|
|
15
50
|
return path.join('.gemini', 'commands', 'opsx', `${commandId}.toml`);
|
|
16
51
|
},
|
|
17
52
|
formatFile(content) {
|
|
18
|
-
return `description = "${content.description}"
|
|
53
|
+
return `description = "${escapeTomlBasicString(content.description)}"
|
|
19
54
|
|
|
20
55
|
prompt = """
|
|
21
|
-
${content.body}
|
|
56
|
+
${escapeTomlMultilineBasicString(content.body)}
|
|
22
57
|
"""
|
|
23
58
|
`;
|
|
24
59
|
},
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Formats commands for GitHub Copilot following its .prompt.md specification.
|
|
5
5
|
*/
|
|
6
6
|
import path from 'path';
|
|
7
|
+
import { escapeYamlValue } from '../yaml.js';
|
|
7
8
|
/**
|
|
8
9
|
* GitHub Copilot adapter for command generation.
|
|
9
10
|
* File path: .github/prompts/opsx-<id>.prompt.md
|
|
@@ -16,7 +17,7 @@ export const githubCopilotAdapter = {
|
|
|
16
17
|
},
|
|
17
18
|
formatFile(content) {
|
|
18
19
|
return `---
|
|
19
|
-
description: ${content.description}
|
|
20
|
+
description: ${escapeYamlValue(content.description)}
|
|
20
21
|
---
|
|
21
22
|
|
|
22
23
|
${content.body}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Formats commands for iFlow following its frontmatter specification.
|
|
5
5
|
*/
|
|
6
6
|
import path from 'path';
|
|
7
|
+
import { escapeYamlValue } from '../yaml.js';
|
|
7
8
|
/**
|
|
8
9
|
* iFlow adapter for command generation.
|
|
9
10
|
* File path: .iflow/commands/opsx-<id>.md
|
|
@@ -16,10 +17,10 @@ export const iflowAdapter = {
|
|
|
16
17
|
},
|
|
17
18
|
formatFile(content) {
|
|
18
19
|
return `---
|
|
19
|
-
name:
|
|
20
|
-
id: opsx-${content.id}
|
|
21
|
-
category: ${content.category}
|
|
22
|
-
description: ${content.description}
|
|
20
|
+
name: ${escapeYamlValue(`/opsx-${content.id}`)}
|
|
21
|
+
id: ${escapeYamlValue(`opsx-${content.id}`)}
|
|
22
|
+
category: ${escapeYamlValue(content.category)}
|
|
23
|
+
description: ${escapeYamlValue(content.description)}
|
|
23
24
|
---
|
|
24
25
|
|
|
25
26
|
${content.body}
|
|
@@ -9,12 +9,12 @@ export { auggieAdapter } from './auggie.js';
|
|
|
9
9
|
export { bobAdapter } from './bob.js';
|
|
10
10
|
export { claudeAdapter } from './claude.js';
|
|
11
11
|
export { clineAdapter } from './cline.js';
|
|
12
|
-
export { codexAdapter } from './codex.js';
|
|
13
12
|
export { codebuddyAdapter } from './codebuddy.js';
|
|
14
13
|
export { continueAdapter } from './continue.js';
|
|
15
14
|
export { costrictAdapter } from './costrict.js';
|
|
16
15
|
export { crushAdapter } from './crush.js';
|
|
17
16
|
export { cursorAdapter } from './cursor.js';
|
|
17
|
+
export { devinAdapter } from './devin.js';
|
|
18
18
|
export { factoryAdapter } from './factory.js';
|
|
19
19
|
export { geminiAdapter } from './gemini.js';
|
|
20
20
|
export { githubCopilotAdapter } from './github-copilot.js';
|
|
@@ -30,5 +30,5 @@ export { lingmaAdapter } from './lingma.js';
|
|
|
30
30
|
export { qwenAdapter } from './qwen.js';
|
|
31
31
|
export { roocodeAdapter } from './roocode.js';
|
|
32
32
|
export { traeAdapter } from './trae.js';
|
|
33
|
-
export {
|
|
33
|
+
export { zcodeAdapter } from './zcode.js';
|
|
34
34
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -9,12 +9,12 @@ export { auggieAdapter } from './auggie.js';
|
|
|
9
9
|
export { bobAdapter } from './bob.js';
|
|
10
10
|
export { claudeAdapter } from './claude.js';
|
|
11
11
|
export { clineAdapter } from './cline.js';
|
|
12
|
-
export { codexAdapter } from './codex.js';
|
|
13
12
|
export { codebuddyAdapter } from './codebuddy.js';
|
|
14
13
|
export { continueAdapter } from './continue.js';
|
|
15
14
|
export { costrictAdapter } from './costrict.js';
|
|
16
15
|
export { crushAdapter } from './crush.js';
|
|
17
16
|
export { cursorAdapter } from './cursor.js';
|
|
17
|
+
export { devinAdapter } from './devin.js';
|
|
18
18
|
export { factoryAdapter } from './factory.js';
|
|
19
19
|
export { geminiAdapter } from './gemini.js';
|
|
20
20
|
export { githubCopilotAdapter } from './github-copilot.js';
|
|
@@ -30,5 +30,5 @@ export { lingmaAdapter } from './lingma.js';
|
|
|
30
30
|
export { qwenAdapter } from './qwen.js';
|
|
31
31
|
export { roocodeAdapter } from './roocode.js';
|
|
32
32
|
export { traeAdapter } from './trae.js';
|
|
33
|
-
export {
|
|
33
|
+
export { zcodeAdapter } from './zcode.js';
|
|
34
34
|
//# sourceMappingURL=index.js.map
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Formats commands for Junie following its frontmatter specification.
|
|
5
5
|
*/
|
|
6
6
|
import path from 'path';
|
|
7
|
+
import { escapeYamlValue } from '../yaml.js';
|
|
7
8
|
/**
|
|
8
9
|
* Junie adapter for command generation.
|
|
9
10
|
* File path: .junie/commands/opsx-<id>.md
|
|
@@ -16,7 +17,7 @@ export const junieAdapter = {
|
|
|
16
17
|
},
|
|
17
18
|
formatFile(content) {
|
|
18
19
|
return `---
|
|
19
|
-
description: ${content.description}
|
|
20
|
+
description: ${escapeYamlValue(content.description)}
|
|
20
21
|
---
|
|
21
22
|
|
|
22
23
|
${content.body}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Formats commands for Kiro following its .prompt.md specification.
|
|
5
5
|
*/
|
|
6
6
|
import path from 'path';
|
|
7
|
+
import { escapeYamlValue } from '../yaml.js';
|
|
7
8
|
/**
|
|
8
9
|
* Kiro adapter for command generation.
|
|
9
10
|
* File path: .kiro/prompts/opsx-<id>.prompt.md
|
|
@@ -16,7 +17,7 @@ export const kiroAdapter = {
|
|
|
16
17
|
},
|
|
17
18
|
formatFile(content) {
|
|
18
19
|
return `---
|
|
19
|
-
description: ${content.description}
|
|
20
|
+
description: ${escapeYamlValue(content.description)}
|
|
20
21
|
---
|
|
21
22
|
|
|
22
23
|
${content.body}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Formats commands for Lingma following its frontmatter specification.
|
|
5
5
|
*/
|
|
6
6
|
import path from 'path';
|
|
7
|
+
import { escapeYamlValue, formatTagsArray } from '../yaml.js';
|
|
7
8
|
/**
|
|
8
9
|
* Lingma adapter for command generation.
|
|
9
10
|
* File path: .lingma/commands/opsx/<id>.md
|
|
@@ -15,12 +16,11 @@ export const lingmaAdapter = {
|
|
|
15
16
|
return path.join('.lingma', 'commands', 'opsx', `${commandId}.md`);
|
|
16
17
|
},
|
|
17
18
|
formatFile(content) {
|
|
18
|
-
const tagsStr = content.tags.join(', ');
|
|
19
19
|
return `---
|
|
20
|
-
name: ${content.name}
|
|
21
|
-
description: ${content.description}
|
|
22
|
-
category: ${content.category}
|
|
23
|
-
tags:
|
|
20
|
+
name: ${escapeYamlValue(content.name)}
|
|
21
|
+
description: ${escapeYamlValue(content.description)}
|
|
22
|
+
category: ${escapeYamlValue(content.category)}
|
|
23
|
+
tags: ${formatTagsArray(content.tags)}
|
|
24
24
|
---
|
|
25
25
|
|
|
26
26
|
${content.body}
|
|
@@ -12,8 +12,8 @@ import type { ToolCommandAdapter } from '../types.js';
|
|
|
12
12
|
* Frontmatter: description
|
|
13
13
|
*
|
|
14
14
|
* OMP uses the filename (minus .md) as the slash command name, so
|
|
15
|
-
* opsx-propose.md → /opsx-propose.
|
|
16
|
-
*
|
|
15
|
+
* opsx-propose.md → /opsx-propose. generateCommand rewrites the body's
|
|
16
|
+
* command references to that form before this adapter formats it, and
|
|
17
17
|
* $@ is injected after **Input**: headings so user-supplied arguments
|
|
18
18
|
* (e.g. /opsx-propose my-feature) are visible to the agent.
|
|
19
19
|
*/
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* The filename (minus .md) becomes the slash command name.
|
|
7
7
|
*/
|
|
8
8
|
import path from 'path';
|
|
9
|
-
import { transformToHyphenCommands } from '../../../utils/command-references.js';
|
|
10
9
|
import { escapeYamlValue } from '../yaml.js';
|
|
11
10
|
const OMP_INPUT_HEADING = /^\*\*Input\*\*:[^\n]*$/m;
|
|
12
11
|
function injectOmpArgs(body) {
|
|
@@ -21,8 +20,8 @@ function injectOmpArgs(body) {
|
|
|
21
20
|
* Frontmatter: description
|
|
22
21
|
*
|
|
23
22
|
* OMP uses the filename (minus .md) as the slash command name, so
|
|
24
|
-
* opsx-propose.md → /opsx-propose.
|
|
25
|
-
*
|
|
23
|
+
* opsx-propose.md → /opsx-propose. generateCommand rewrites the body's
|
|
24
|
+
* command references to that form before this adapter formats it, and
|
|
26
25
|
* $@ is injected after **Input**: headings so user-supplied arguments
|
|
27
26
|
* (e.g. /opsx-propose my-feature) are visible to the agent.
|
|
28
27
|
*/
|
|
@@ -32,12 +31,11 @@ export const ohMyPiAdapter = {
|
|
|
32
31
|
return path.join('.omp', 'commands', `opsx-${commandId}.md`);
|
|
33
32
|
},
|
|
34
33
|
formatFile(content) {
|
|
35
|
-
const transformedBody = transformToHyphenCommands(content.body);
|
|
36
34
|
return `---
|
|
37
35
|
description: ${escapeYamlValue(content.description)}
|
|
38
36
|
---
|
|
39
37
|
|
|
40
|
-
${injectOmpArgs(
|
|
38
|
+
${injectOmpArgs(content.body)}
|
|
41
39
|
`;
|
|
42
40
|
},
|
|
43
41
|
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Formats commands for OpenCode following its frontmatter specification.
|
|
5
5
|
*/
|
|
6
6
|
import path from 'path';
|
|
7
|
-
import {
|
|
7
|
+
import { escapeYamlValue } from '../yaml.js';
|
|
8
8
|
/**
|
|
9
9
|
* OpenCode adapter for command generation.
|
|
10
10
|
* File path: .opencode/commands/opsx-<id>.md
|
|
@@ -16,13 +16,11 @@ export const opencodeAdapter = {
|
|
|
16
16
|
return path.join('.opencode', 'commands', `opsx-${commandId}.md`);
|
|
17
17
|
},
|
|
18
18
|
formatFile(content) {
|
|
19
|
-
// Transform command references from colon to hyphen format for OpenCode
|
|
20
|
-
const transformedBody = transformToHyphenCommands(content.body);
|
|
21
19
|
return `---
|
|
22
|
-
description: ${content.description}
|
|
20
|
+
description: ${escapeYamlValue(content.description)}
|
|
23
21
|
---
|
|
24
22
|
|
|
25
|
-
${
|
|
23
|
+
${content.body}
|
|
26
24
|
`;
|
|
27
25
|
},
|
|
28
26
|
};
|
|
@@ -11,8 +11,8 @@ import type { ToolCommandAdapter } from '../types.js';
|
|
|
11
11
|
* Frontmatter: description
|
|
12
12
|
*
|
|
13
13
|
* Pi uses the filename (minus .md) as the slash command name, so
|
|
14
|
-
* opsx-propose.md → /opsx-propose.
|
|
15
|
-
*
|
|
14
|
+
* opsx-propose.md → /opsx-propose. generateCommand rewrites the body's
|
|
15
|
+
* command references to that form before this adapter formats it.
|
|
16
16
|
*/
|
|
17
17
|
export declare const piAdapter: ToolCommandAdapter;
|
|
18
18
|
//# sourceMappingURL=pi.d.ts.map
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* Pi prompt templates live in .pi/prompts/*.md with description frontmatter.
|
|
6
6
|
*/
|
|
7
7
|
import path from 'path';
|
|
8
|
-
import { transformToHyphenCommands } from '../../../utils/command-references.js';
|
|
9
8
|
import { escapeYamlValue } from '../yaml.js';
|
|
10
9
|
const PI_INPUT_HEADING = /^\*\*Input\*\*:[^\n]*$/m;
|
|
11
10
|
function injectPiArgs(body) {
|
|
@@ -20,8 +19,8 @@ function injectPiArgs(body) {
|
|
|
20
19
|
* Frontmatter: description
|
|
21
20
|
*
|
|
22
21
|
* Pi uses the filename (minus .md) as the slash command name, so
|
|
23
|
-
* opsx-propose.md → /opsx-propose.
|
|
24
|
-
*
|
|
22
|
+
* opsx-propose.md → /opsx-propose. generateCommand rewrites the body's
|
|
23
|
+
* command references to that form before this adapter formats it.
|
|
25
24
|
*/
|
|
26
25
|
export const piAdapter = {
|
|
27
26
|
toolId: 'pi',
|
|
@@ -29,13 +28,11 @@ export const piAdapter = {
|
|
|
29
28
|
return path.join('.pi', 'prompts', `opsx-${commandId}.md`);
|
|
30
29
|
},
|
|
31
30
|
formatFile(content) {
|
|
32
|
-
// Transform /opsx: references to /opsx- and inject $@ for template args
|
|
33
|
-
const transformedBody = transformToHyphenCommands(content.body);
|
|
34
31
|
return `---
|
|
35
32
|
description: ${escapeYamlValue(content.description)}
|
|
36
33
|
---
|
|
37
34
|
|
|
38
|
-
${injectPiArgs(
|
|
35
|
+
${injectPiArgs(content.body)}
|
|
39
36
|
`;
|
|
40
37
|
},
|
|
41
38
|
};
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Formats commands for Qoder following its frontmatter specification.
|
|
5
5
|
*/
|
|
6
6
|
import path from 'path';
|
|
7
|
+
import { escapeYamlValue, formatTagsArray } from '../yaml.js';
|
|
7
8
|
/**
|
|
8
9
|
* Qoder adapter for command generation.
|
|
9
10
|
* File path: .qoder/commands/opsx/<id>.md
|
|
@@ -15,12 +16,11 @@ export const qoderAdapter = {
|
|
|
15
16
|
return path.join('.qoder', 'commands', 'opsx', `${commandId}.md`);
|
|
16
17
|
},
|
|
17
18
|
formatFile(content) {
|
|
18
|
-
const tagsStr = content.tags.join(', ');
|
|
19
19
|
return `---
|
|
20
|
-
name: ${content.name}
|
|
21
|
-
description: ${content.description}
|
|
22
|
-
category: ${content.category}
|
|
23
|
-
tags:
|
|
20
|
+
name: ${escapeYamlValue(content.name)}
|
|
21
|
+
description: ${escapeYamlValue(content.description)}
|
|
22
|
+
category: ${escapeYamlValue(content.category)}
|
|
23
|
+
tags: ${formatTagsArray(content.tags)}
|
|
24
24
|
---
|
|
25
25
|
|
|
26
26
|
${content.body}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Qwen Code Command Adapter
|
|
3
3
|
*
|
|
4
|
-
* Formats commands for Qwen Code following its
|
|
4
|
+
* Formats commands for Qwen Code following its Markdown custom command
|
|
5
|
+
* specification. Qwen Code has deprecated TOML commands in favor of
|
|
6
|
+
* Markdown files with YAML frontmatter.
|
|
7
|
+
*
|
|
8
|
+
* @see https://qwenlm.github.io/qwen-code-docs/en/users/features/commands/#markdown-file-format-specification-recommended
|
|
5
9
|
*/
|
|
6
10
|
import type { ToolCommandAdapter } from '../types.js';
|
|
7
11
|
/**
|
|
8
12
|
* Qwen adapter for command generation.
|
|
9
|
-
* File path: .qwen/commands/opsx-<id>.
|
|
10
|
-
* Format:
|
|
13
|
+
* File path: .qwen/commands/opsx-<id>.md
|
|
14
|
+
* Format: Markdown with description frontmatter
|
|
11
15
|
*/
|
|
12
16
|
export declare const qwenAdapter: ToolCommandAdapter;
|
|
13
17
|
//# sourceMappingURL=qwen.d.ts.map
|
|
@@ -1,25 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Qwen Code Command Adapter
|
|
3
3
|
*
|
|
4
|
-
* Formats commands for Qwen Code following its
|
|
4
|
+
* Formats commands for Qwen Code following its Markdown custom command
|
|
5
|
+
* specification. Qwen Code has deprecated TOML commands in favor of
|
|
6
|
+
* Markdown files with YAML frontmatter.
|
|
7
|
+
*
|
|
8
|
+
* @see https://qwenlm.github.io/qwen-code-docs/en/users/features/commands/#markdown-file-format-specification-recommended
|
|
5
9
|
*/
|
|
6
10
|
import path from 'path';
|
|
11
|
+
import { escapeYamlValue } from '../yaml.js';
|
|
7
12
|
/**
|
|
8
13
|
* Qwen adapter for command generation.
|
|
9
|
-
* File path: .qwen/commands/opsx-<id>.
|
|
10
|
-
* Format:
|
|
14
|
+
* File path: .qwen/commands/opsx-<id>.md
|
|
15
|
+
* Format: Markdown with description frontmatter
|
|
11
16
|
*/
|
|
12
17
|
export const qwenAdapter = {
|
|
13
18
|
toolId: 'qwen',
|
|
14
19
|
getFilePath(commandId) {
|
|
15
|
-
return path.join('.qwen', 'commands', `opsx-${commandId}.
|
|
20
|
+
return path.join('.qwen', 'commands', `opsx-${commandId}.md`);
|
|
16
21
|
},
|
|
17
22
|
formatFile(content) {
|
|
18
|
-
return
|
|
23
|
+
return `---
|
|
24
|
+
description: ${escapeYamlValue(content.description)}
|
|
25
|
+
---
|
|
19
26
|
|
|
20
|
-
prompt = """
|
|
21
27
|
${content.body}
|
|
22
|
-
"""
|
|
23
28
|
`;
|
|
24
29
|
},
|
|
25
30
|
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Zoo Code Command Adapter
|
|
3
3
|
*
|
|
4
|
-
* Formats commands for
|
|
5
|
-
*
|
|
4
|
+
* Formats commands for Zoo Code following its workflow specification.
|
|
5
|
+
* Zoo Code uses markdown headers instead of YAML frontmatter.
|
|
6
6
|
*/
|
|
7
7
|
import type { ToolCommandAdapter } from '../types.js';
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Zoo Code adapter for command generation.
|
|
10
10
|
* File path: .roo/commands/opsx-<id>.md
|
|
11
11
|
* Format: Markdown header with description
|
|
12
12
|
*/
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Zoo Code Command Adapter
|
|
3
3
|
*
|
|
4
|
-
* Formats commands for
|
|
5
|
-
*
|
|
4
|
+
* Formats commands for Zoo Code following its workflow specification.
|
|
5
|
+
* Zoo Code uses markdown headers instead of YAML frontmatter.
|
|
6
6
|
*/
|
|
7
7
|
import path from 'path';
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Zoo Code adapter for command generation.
|
|
10
10
|
* File path: .roo/commands/opsx-<id>.md
|
|
11
11
|
* Format: Markdown header with description
|
|
12
12
|
*/
|
|
@@ -4,27 +4,7 @@
|
|
|
4
4
|
* Formats commands for Trae IDE following its command specification.
|
|
5
5
|
*/
|
|
6
6
|
import path from 'path';
|
|
7
|
-
|
|
8
|
-
* Escapes a string value for safe YAML output.
|
|
9
|
-
* Quotes the string if it contains special YAML characters.
|
|
10
|
-
*/
|
|
11
|
-
function escapeYamlValue(value) {
|
|
12
|
-
if (value === '') {
|
|
13
|
-
return '""';
|
|
14
|
-
}
|
|
15
|
-
// Check if value needs quoting (contains special YAML characters or starts/ends with whitespace)
|
|
16
|
-
const needsQuoting = /[:\n\r#{}[\],&*!|>'"%@`]|^\s|\s$/.test(value);
|
|
17
|
-
if (needsQuoting) {
|
|
18
|
-
// Use double quotes and escape internal double quotes, backslashes, and newlines
|
|
19
|
-
const escaped = value
|
|
20
|
-
.replace(/\\/g, '\\\\')
|
|
21
|
-
.replace(/"/g, '\\"')
|
|
22
|
-
.replace(/\n/g, '\\n')
|
|
23
|
-
.replace(/\r/g, '\\r');
|
|
24
|
-
return `"${escaped}"`;
|
|
25
|
-
}
|
|
26
|
-
return value;
|
|
27
|
-
}
|
|
7
|
+
import { escapeYamlValue } from '../yaml.js';
|
|
28
8
|
/**
|
|
29
9
|
* Trae adapter for command generation.
|
|
30
10
|
* File path: .trae/commands/opsx-<id>.md
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZCode Command Adapter
|
|
3
|
+
*
|
|
4
|
+
* Formats commands for ZCode following its frontmatter specification.
|
|
5
|
+
* ZCode shares Claude Code's command format conventions.
|
|
6
|
+
* File path: .zcode/commands/opsx/<id>.md
|
|
7
|
+
* Frontmatter: name, description, category, tags
|
|
8
|
+
*/
|
|
9
|
+
import type { ToolCommandAdapter } from '../types.js';
|
|
10
|
+
/**
|
|
11
|
+
* ZCode adapter for command generation.
|
|
12
|
+
* File path: .zcode/commands/opsx/<id>.md
|
|
13
|
+
* Frontmatter: name, description, category, tags
|
|
14
|
+
*/
|
|
15
|
+
export declare const zcodeAdapter: ToolCommandAdapter;
|
|
16
|
+
//# sourceMappingURL=zcode.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZCode Command Adapter
|
|
3
|
+
*
|
|
4
|
+
* Formats commands for ZCode following its frontmatter specification.
|
|
5
|
+
* ZCode shares Claude Code's command format conventions.
|
|
6
|
+
* File path: .zcode/commands/opsx/<id>.md
|
|
7
|
+
* Frontmatter: name, description, category, tags
|
|
8
|
+
*/
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import { escapeYamlValue, formatTagsArray } from '../yaml.js';
|
|
11
|
+
/**
|
|
12
|
+
* ZCode adapter for command generation.
|
|
13
|
+
* File path: .zcode/commands/opsx/<id>.md
|
|
14
|
+
* Frontmatter: name, description, category, tags
|
|
15
|
+
*/
|
|
16
|
+
export const zcodeAdapter = {
|
|
17
|
+
toolId: 'zcode',
|
|
18
|
+
getFilePath(commandId) {
|
|
19
|
+
return path.join('.zcode', 'commands', 'opsx', `${commandId}.md`);
|
|
20
|
+
},
|
|
21
|
+
formatFile(content) {
|
|
22
|
+
return `---
|
|
23
|
+
name: ${escapeYamlValue(content.name)}
|
|
24
|
+
description: ${escapeYamlValue(content.description)}
|
|
25
|
+
category: ${escapeYamlValue(content.category)}
|
|
26
|
+
tags: ${formatTagsArray(content.tags)}
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
${content.body}
|
|
30
|
+
`;
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=zcode.js.map
|
|
@@ -6,6 +6,14 @@
|
|
|
6
6
|
import type { CommandContent, ToolCommandAdapter, GeneratedCommand } from './types.js';
|
|
7
7
|
/**
|
|
8
8
|
* Generate a single command file using the provided adapter.
|
|
9
|
+
*
|
|
10
|
+
* Command bodies are authored with `/opsx:<id>` references. Tools whose command
|
|
11
|
+
* files are invoked by filename register `/opsx-<id>` instead, and Amazon Q
|
|
12
|
+
* surfaces them in its prompt library as `@opsx-<id>`, so the body is rewritten
|
|
13
|
+
* to the form that tool answers to before the adapter formats it. Doing it here
|
|
14
|
+
* rather than per adapter keeps every tool in step (#727, #1307); adapters stay
|
|
15
|
+
* pure formatters.
|
|
16
|
+
*
|
|
9
17
|
* @param content - The tool-agnostic command content
|
|
10
18
|
* @param adapter - The tool-specific adapter
|
|
11
19
|
* @returns Generated command with path and file content
|
|
@@ -3,16 +3,30 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Functions for generating command files using tool adapters.
|
|
5
5
|
*/
|
|
6
|
+
import { getInvocationForAdapter, needsInvocationRewrite } from './invocation.js';
|
|
7
|
+
import { transformCommandInvocations } from '../../utils/command-references.js';
|
|
6
8
|
/**
|
|
7
9
|
* Generate a single command file using the provided adapter.
|
|
10
|
+
*
|
|
11
|
+
* Command bodies are authored with `/opsx:<id>` references. Tools whose command
|
|
12
|
+
* files are invoked by filename register `/opsx-<id>` instead, and Amazon Q
|
|
13
|
+
* surfaces them in its prompt library as `@opsx-<id>`, so the body is rewritten
|
|
14
|
+
* to the form that tool answers to before the adapter formats it. Doing it here
|
|
15
|
+
* rather than per adapter keeps every tool in step (#727, #1307); adapters stay
|
|
16
|
+
* pure formatters.
|
|
17
|
+
*
|
|
8
18
|
* @param content - The tool-agnostic command content
|
|
9
19
|
* @param adapter - The tool-specific adapter
|
|
10
20
|
* @returns Generated command with path and file content
|
|
11
21
|
*/
|
|
12
22
|
export function generateCommand(content, adapter) {
|
|
23
|
+
const invocation = getInvocationForAdapter(adapter);
|
|
24
|
+
const formatted = needsInvocationRewrite(invocation)
|
|
25
|
+
? { ...content, body: transformCommandInvocations(content.body, invocation) }
|
|
26
|
+
: content;
|
|
13
27
|
return {
|
|
14
28
|
path: adapter.getFilePath(content.id),
|
|
15
|
-
fileContent: adapter.formatFile(
|
|
29
|
+
fileContent: adapter.formatFile(formatted),
|
|
16
30
|
};
|
|
17
31
|
}
|
|
18
32
|
/**
|
|
@@ -18,5 +18,5 @@
|
|
|
18
18
|
export type { CommandContent, ToolCommandAdapter, GeneratedCommand, } from './types.js';
|
|
19
19
|
export { CommandAdapterRegistry } from './registry.js';
|
|
20
20
|
export { generateCommand, generateCommands } from './generator.js';
|
|
21
|
-
export { claudeAdapter, cursorAdapter,
|
|
21
|
+
export { claudeAdapter, cursorAdapter, devinAdapter } from './adapters/index.js';
|
|
22
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -20,5 +20,5 @@ export { CommandAdapterRegistry } from './registry.js';
|
|
|
20
20
|
// Generator functions
|
|
21
21
|
export { generateCommand, generateCommands } from './generator.js';
|
|
22
22
|
// Adapters (for direct access if needed)
|
|
23
|
-
export { claudeAdapter, cursorAdapter,
|
|
23
|
+
export { claudeAdapter, cursorAdapter, devinAdapter } from './adapters/index.js';
|
|
24
24
|
//# sourceMappingURL=index.js.map
|