Skip to content

Commit c8fe7fe

Browse files
committed
fix(adapters): escape YAML frontmatter values consistently across all command adapters
1 parent 19d4171 commit c8fe7fe

23 files changed

Lines changed: 120 additions & 112 deletions

src/core/command-generation/adapters/amazon-q.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import path from 'path';
88
import type { CommandContent, ToolCommandAdapter } from '../types.js';
9+
import { escapeYamlValue } from '../yaml.js';
910

1011
/**
1112
* Amazon Q adapter for command generation.
@@ -21,7 +22,7 @@ export const amazonQAdapter: ToolCommandAdapter = {
2122

2223
formatFile(content: CommandContent): string {
2324
return `---
24-
description: ${content.description}
25+
description: ${escapeYamlValue(content.description)}
2526
---
2627
2728
${content.body}

src/core/command-generation/adapters/antigravity.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import path from 'path';
88
import type { CommandContent, ToolCommandAdapter } from '../types.js';
9+
import { escapeYamlValue } from '../yaml.js';
910

1011
/**
1112
* Antigravity adapter for command generation.
@@ -21,7 +22,7 @@ export const antigravityAdapter: ToolCommandAdapter = {
2122

2223
formatFile(content: CommandContent): string {
2324
return `---
24-
description: ${content.description}
25+
description: ${escapeYamlValue(content.description)}
2526
---
2627
2728
${content.body}

src/core/command-generation/adapters/auggie.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import path from 'path';
88
import type { CommandContent, ToolCommandAdapter } from '../types.js';
9+
import { escapeYamlValue } from '../yaml.js';
910

1011
/**
1112
* Auggie adapter for command generation.
@@ -21,7 +22,7 @@ export const auggieAdapter: ToolCommandAdapter = {
2122

2223
formatFile(content: CommandContent): string {
2324
return `---
24-
description: ${content.description}
25+
description: ${escapeYamlValue(content.description)}
2526
argument-hint: command arguments
2627
---
2728

src/core/command-generation/adapters/bob.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ import { escapeYamlValue } from '../yaml.js';
1313
/**
1414
* Bob Shell adapter for command generation.
1515
* File path: .bob/commands/opsx-<id>.md
16-
* Frontmatter: description, argument-hint
16+
* Frontmatter: description
17+
*
18+
* Bob uses the filename (minus .md) as the slash command name, so
19+
* opsx-propose.md → /opsx-propose. Command references in the body
20+
* are transformed from /opsx: to /opsx- for consistency.
1721
*/
1822
export const bobAdapter: ToolCommandAdapter = {
1923
toolId: 'bob',
@@ -23,7 +27,6 @@ export const bobAdapter: ToolCommandAdapter = {
2327
},
2428

2529
formatFile(content: CommandContent): string {
26-
// Transform command references from colon to hyphen format for Bob
2730
const transformedBody = transformToHyphenCommands(content.body);
2831

2932
return `---

src/core/command-generation/adapters/claude.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,9 @@
66

77
import path from 'path';
88
import type { CommandContent, ToolCommandAdapter } from '../types.js';
9-
import { escapeYamlValue } from '../yaml.js';
9+
import { escapeYamlValue, formatTagsArray } from '../yaml.js';
1010
import { OPENSPEC_CLI_ALLOWED_TOOLS } from '../../shared/allowed-tools.js';
1111

12-
/**
13-
* Formats a tags array as a YAML array with proper escaping.
14-
*/
15-
function formatTagsArray(tags: string[]): string {
16-
const escapedTags = tags.map((tag) => escapeYamlValue(tag));
17-
return `[${escapedTags.join(', ')}]`;
18-
}
19-
2012
/**
2113
* Claude Code adapter for command generation.
2214
* File path: .claude/commands/opsx/<id>.md

src/core/command-generation/adapters/codebuddy.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import path from 'path';
88
import type { CommandContent, ToolCommandAdapter } from '../types.js';
9+
import { escapeYamlValue } from '../yaml.js';
910

1011
/**
1112
* CodeBuddy adapter for command generation.
@@ -21,8 +22,8 @@ export const codebuddyAdapter: ToolCommandAdapter = {
2122

2223
formatFile(content: CommandContent): string {
2324
return `---
24-
name: ${content.name}
25-
description: "${content.description}"
25+
name: ${escapeYamlValue(content.name)}
26+
description: ${escapeYamlValue(content.description)}
2627
argument-hint: "[command arguments]"
2728
---
2829

src/core/command-generation/adapters/continue.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import path from 'path';
88
import type { CommandContent, ToolCommandAdapter } from '../types.js';
9+
import { escapeYamlValue } from '../yaml.js';
910

1011
/**
1112
* Continue adapter for command generation.
@@ -22,7 +23,7 @@ export const continueAdapter: ToolCommandAdapter = {
2223
formatFile(content: CommandContent): string {
2324
return `---
2425
name: opsx-${content.id}
25-
description: ${content.description}
26+
description: ${escapeYamlValue(content.description)}
2627
invokable: true
2728
---
2829

src/core/command-generation/adapters/costrict.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import path from 'path';
88
import type { CommandContent, ToolCommandAdapter } from '../types.js';
9+
import { escapeYamlValue } from '../yaml.js';
910

1011
/**
1112
* CoStrict adapter for command generation.
@@ -21,7 +22,7 @@ export const costrictAdapter: ToolCommandAdapter = {
2122

2223
formatFile(content: CommandContent): string {
2324
return `---
24-
description: "${content.description}"
25+
description: ${escapeYamlValue(content.description)}
2526
argument-hint: command arguments
2627
---
2728

src/core/command-generation/adapters/crush.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import path from 'path';
88
import type { CommandContent, ToolCommandAdapter } from '../types.js';
9+
import { escapeYamlValue, formatTagsArray } from '../yaml.js';
910

1011
/**
1112
* Crush adapter for command generation.
@@ -20,12 +21,11 @@ export const crushAdapter: ToolCommandAdapter = {
2021
},
2122

2223
formatFile(content: CommandContent): string {
23-
const tagsStr = content.tags.join(', ');
2424
return `---
25-
name: ${content.name}
26-
description: ${content.description}
27-
category: ${content.category}
28-
tags: [${tagsStr}]
25+
name: ${escapeYamlValue(content.name)}
26+
description: ${escapeYamlValue(content.description)}
27+
category: ${escapeYamlValue(content.category)}
28+
tags: ${formatTagsArray(content.tags)}
2929
---
3030
3131
${content.body}

src/core/command-generation/adapters/factory.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import path from 'path';
88
import type { CommandContent, ToolCommandAdapter } from '../types.js';
9+
import { escapeYamlValue } from '../yaml.js';
910

1011
/**
1112
* Factory adapter for command generation.
@@ -21,7 +22,7 @@ export const factoryAdapter: ToolCommandAdapter = {
2122

2223
formatFile(content: CommandContent): string {
2324
return `---
24-
description: ${content.description}
25+
description: ${escapeYamlValue(content.description)}
2526
argument-hint: command arguments
2627
---
2728

0 commit comments

Comments
 (0)