From c58d3c898e36d204d06c1652306ae4ed6a98c612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Silva=20Ortiz?= Date: Wed, 25 Feb 2026 16:04:22 -0300 Subject: [PATCH 1/3] fix(opencode): use plural `commands/` directory to match OpenCode convention The OpenCode adapter was using `.opencode/command/` (singular) but OpenCode's official documentation specifies `.opencode/commands/` (plural). This aligns with every other adapter in the codebase. Legacy cleanup updated to detect old singular-path artifacts. Fixes #748. Co-Authored-By: Claude Opus 4.6 --- .changeset/fix-opencode-commands-directory.md | 5 ++ docs/supported-tools.md | 2 +- .../.openspec.yaml | 2 + .../fix-opencode-commands-directory/design.md | 48 ++++++++++++++++ .../proposal.md | 26 +++++++++ .../specs/command-generation/spec.md | 55 +++++++++++++++++++ .../fix-opencode-commands-directory/tasks.md | 19 +++++++ .../command-generation/adapters/opencode.ts | 4 +- src/core/legacy-cleanup.ts | 2 +- test/core/command-generation/adapters.test.ts | 2 +- 10 files changed, 160 insertions(+), 5 deletions(-) create mode 100644 .changeset/fix-opencode-commands-directory.md create mode 100644 openspec/changes/fix-opencode-commands-directory/.openspec.yaml create mode 100644 openspec/changes/fix-opencode-commands-directory/design.md create mode 100644 openspec/changes/fix-opencode-commands-directory/proposal.md create mode 100644 openspec/changes/fix-opencode-commands-directory/specs/command-generation/spec.md create mode 100644 openspec/changes/fix-opencode-commands-directory/tasks.md diff --git a/.changeset/fix-opencode-commands-directory.md b/.changeset/fix-opencode-commands-directory.md new file mode 100644 index 000000000..c67a0cfc1 --- /dev/null +++ b/.changeset/fix-opencode-commands-directory.md @@ -0,0 +1,5 @@ +--- +"@fission-ai/openspec": patch +--- + +fix: OpenCode adapter now uses `.opencode/commands/` (plural) to match OpenCode's official directory convention. Fixes #748. diff --git a/docs/supported-tools.md b/docs/supported-tools.md index 2d7e10975..524e597f2 100644 --- a/docs/supported-tools.md +++ b/docs/supported-tools.md @@ -38,7 +38,7 @@ You can enable expanded workflows (`new`, `continue`, `ff`, `verify`, `sync`, `b | iFlow (`iflow`) | `.iflow/skills/openspec-*/SKILL.md` | `.iflow/commands/opsx-.md` | | Kilo Code (`kilocode`) | `.kilocode/skills/openspec-*/SKILL.md` | `.kilocode/workflows/opsx-.md` | | Kiro (`kiro`) | `.kiro/skills/openspec-*/SKILL.md` | `.kiro/prompts/opsx-.prompt.md` | -| OpenCode (`opencode`) | `.opencode/skills/openspec-*/SKILL.md` | `.opencode/command/opsx-.md` | +| OpenCode (`opencode`) | `.opencode/skills/openspec-*/SKILL.md` | `.opencode/commands/opsx-.md` | | Pi (`pi`) | `.pi/skills/openspec-*/SKILL.md` | `.pi/prompts/opsx-.md` | | Qoder (`qoder`) | `.qoder/skills/openspec-*/SKILL.md` | `.qoder/commands/opsx/.md` | | Qwen Code (`qwen`) | `.qwen/skills/openspec-*/SKILL.md` | `.qwen/commands/opsx-.toml` | diff --git a/openspec/changes/fix-opencode-commands-directory/.openspec.yaml b/openspec/changes/fix-opencode-commands-directory/.openspec.yaml new file mode 100644 index 000000000..e331c975d --- /dev/null +++ b/openspec/changes/fix-opencode-commands-directory/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-02-25 diff --git a/openspec/changes/fix-opencode-commands-directory/design.md b/openspec/changes/fix-opencode-commands-directory/design.md new file mode 100644 index 000000000..9be042ca8 --- /dev/null +++ b/openspec/changes/fix-opencode-commands-directory/design.md @@ -0,0 +1,48 @@ +## Context + +The OpenCode adapter in `src/core/command-generation/adapters/opencode.ts` currently generates command files at `.opencode/command/opsx-.md` (singular `command`). OpenCode's official documentation uses `.opencode/commands/` (plural), and every other adapter in the codebase follows the plural convention for commands directories. The legacy cleanup module in `src/core/legacy-cleanup.ts` also references the singular form for detecting old artifacts. + +## Goals / Non-Goals + +**Goals:** +- Align the OpenCode adapter path with OpenCode's official `.opencode/commands/` convention +- Add the old singular path `.opencode/command/` to legacy cleanup so existing installations are properly cleaned +- Update documentation to reflect the corrected path +- Update test assertions to match the new path + +**Non-Goals:** +- Changing the OpenCode skill path (`.opencode/skills/`) — already correct +- Modifying any other adapter's directory structure +- Adding migration prompts or interactive upgrade flows + +## Decisions + +### 1. Direct path rename in adapter + +**Decision:** Change `path.join('.opencode', 'command', ...)` to `path.join('.opencode', 'commands', ...)` in the adapter's `getFilePath` method. + +**Rationale:** This is a single-line change that aligns with the established pattern across all other adapters. No abstraction or indirection needed. + +**Alternatives considered:** +- Add a configuration option for the directory name — rejected as over-engineering for a bug fix +- Keep singular and add plural as alias — rejected as it creates ambiguity about which is canonical + +### 2. Legacy cleanup via existing constant map + +**Decision:** Update the `LEGACY_SLASH_COMMAND_PATHS` entry for `'opencode'` from `'.opencode/command/openspec-*.md'` to `'.opencode/command/opsx-*.md'` (the old singular path becomes the legacy pattern) and ensure the new path is handled by the current command generation pipeline. + +**Rationale:** The existing legacy cleanup infrastructure uses `LEGACY_SLASH_COMMAND_PATHS` as an explicit lookup. The old singular-path pattern already matches the legacy format (`openspec-*` prefix from the old SlashCommandRegistry era). The current command generation uses the `opsx-*` prefix, so we also need to add a legacy pattern for `opsx-*` files in the old singular directory. + +**Alternatives considered:** +- Add a separate migration script — rejected; the existing legacy cleanup mechanism handles this scenario + +### 3. Documentation update + +**Decision:** Update the `docs/supported-tools.md` table entry for OpenCode from `.opencode/command/opsx-.md` to `.opencode/commands/opsx-.md`. + +**Rationale:** Documentation must match the actual generated paths. + +## Risks / Trade-offs + +- **[Existing installations have files at old path]** → Mitigated by legacy cleanup detecting `.opencode/command/` artifacts. On next `openspec init`, old files are cleaned up and new files written to `.opencode/commands/`. +- **[Users referencing old path in custom scripts]** → Low risk. The old path was incorrect per OpenCode's specification, so custom references were already misaligned. diff --git a/openspec/changes/fix-opencode-commands-directory/proposal.md b/openspec/changes/fix-opencode-commands-directory/proposal.md new file mode 100644 index 000000000..ec41e01e5 --- /dev/null +++ b/openspec/changes/fix-opencode-commands-directory/proposal.md @@ -0,0 +1,26 @@ +## Why + +The OpenCode adapter uses `.opencode/command/` (singular) for its commands directory, but OpenCode's official documentation specifies `.opencode/commands/` (plural). Every other adapter in the codebase also uses plural directory names (`.claude/commands/`, `.cursor/commands/`, `.factory/commands/`, etc.). This inconsistency was introduced in Oct 2025 without documented rationale. Fixes [#748](https://github.com/Fission-AI/OpenSpec/issues/748). + +## What Changes + +- OpenCode adapter path changes from `.opencode/command/` to `.opencode/commands/` +- Legacy cleanup adds `.opencode/command/` (old singular path) for backward compatibility +- Documentation updated to reflect the new plural path + +## Capabilities + +### New Capabilities + +_None._ + +### Modified Capabilities + +- `command-generation`: OpenCode adapter path changes from singular `command/` to plural `commands/` to match OpenCode's official directory convention + +## Impact + +- `src/core/command-generation/adapters/opencode.ts` — adapter path +- `src/core/legacy-cleanup.ts` — legacy cleanup pattern + add old singular path +- `docs/supported-tools.md` — documentation table +- `test/core/command-generation/adapters.test.ts` — test assertion diff --git a/openspec/changes/fix-opencode-commands-directory/specs/command-generation/spec.md b/openspec/changes/fix-opencode-commands-directory/specs/command-generation/spec.md new file mode 100644 index 000000000..ae2b24ce1 --- /dev/null +++ b/openspec/changes/fix-opencode-commands-directory/specs/command-generation/spec.md @@ -0,0 +1,55 @@ +## MODIFIED Requirements + +### Requirement: ToolCommandAdapter interface + +The system SHALL define a `ToolCommandAdapter` interface for per-tool formatting. + +#### Scenario: Adapter interface structure + +- **WHEN** implementing a tool adapter +- **THEN** `ToolCommandAdapter` SHALL require: + - `toolId`: string identifier matching `AIToolOption.value` + - `getFilePath(commandId: string)`: returns file path for command (relative from project root, or absolute for global-scoped tools like Codex) + - `formatFile(content: CommandContent)`: returns complete file content with frontmatter + +#### Scenario: Claude adapter formatting + +- **WHEN** formatting a command for Claude Code +- **THEN** the adapter SHALL output YAML frontmatter with `name`, `description`, `category`, `tags` fields +- **AND** file path SHALL follow pattern `.claude/commands/opsx/.md` + +#### Scenario: Cursor adapter formatting + +- **WHEN** formatting a command for Cursor +- **THEN** the adapter SHALL output YAML frontmatter with `name` as `/opsx-`, `id`, `category`, `description` fields +- **AND** file path SHALL follow pattern `.cursor/commands/opsx-.md` + +#### Scenario: Windsurf adapter formatting + +- **WHEN** formatting a command for Windsurf +- **THEN** the adapter SHALL output YAML frontmatter with `name`, `description`, `category`, `tags` fields +- **AND** file path SHALL follow pattern `.windsurf/workflows/opsx-.md` + +#### Scenario: OpenCode adapter formatting + +- **WHEN** formatting a command for OpenCode +- **THEN** the adapter SHALL output YAML frontmatter with `description` field +- **AND** file path SHALL follow pattern `.opencode/commands/opsx-.md` using `path.join('.opencode', 'commands', ...)` for cross-platform compatibility +- **AND** the adapter SHALL transform colon-based command references (`/opsx:name`) to hyphen-based (`/opsx-name`) in the body + +## ADDED Requirements + +### Requirement: Legacy cleanup for renamed OpenCode command directory + +The legacy cleanup module SHALL detect and remove old OpenCode command files from the previous singular `.opencode/command/` directory path. + +#### Scenario: Detect old singular-path OpenCode command files + +- **WHEN** running legacy artifact detection on a project with files matching `.opencode/command/openspec-*.md` or `.opencode/command/opsx-*.md` +- **THEN** the system SHALL include those files in the legacy slash command files list via `LEGACY_SLASH_COMMAND_PATHS` + +#### Scenario: Clean up old OpenCode command files on init + +- **WHEN** a user runs `openspec init` in a project with old `.opencode/command/` artifacts +- **THEN** the system SHALL remove the old files +- **AND** generate new command files at `.opencode/commands/` diff --git a/openspec/changes/fix-opencode-commands-directory/tasks.md b/openspec/changes/fix-opencode-commands-directory/tasks.md new file mode 100644 index 000000000..828731eff --- /dev/null +++ b/openspec/changes/fix-opencode-commands-directory/tasks.md @@ -0,0 +1,19 @@ +## 1. Adapter Fix + +- [x] 1.1 Update `src/core/command-generation/adapters/opencode.ts`: change `path.join('.opencode', 'command', ...)` to `path.join('.opencode', 'commands', ...)` and update the JSDoc comment + +## 2. Legacy Cleanup + +- [x] 2.1 Update `src/core/legacy-cleanup.ts`: change the `'opencode'` entry in `LEGACY_SLASH_COMMAND_PATHS` from `'.opencode/command/openspec-*.md'` to `'.opencode/command/opsx-*.md'` to detect old singular-path artifacts with the current `opsx-*` prefix + +## 3. Documentation + +- [x] 3.1 Update `docs/supported-tools.md`: change OpenCode command path from `.opencode/command/opsx-.md` to `.opencode/commands/opsx-.md` + +## 4. Tests + +- [x] 4.1 Update `test/core/command-generation/adapters.test.ts`: change the OpenCode file path assertion from `path.join('.opencode', 'command', 'opsx-explore.md')` to `path.join('.opencode', 'commands', 'opsx-explore.md')` + +## 5. Changeset + +- [x] 5.1 Create a changeset file (`.changeset/fix-opencode-commands-directory.md`) with a patch bump describing the path fix diff --git a/src/core/command-generation/adapters/opencode.ts b/src/core/command-generation/adapters/opencode.ts index 2b078fc6c..301664b47 100644 --- a/src/core/command-generation/adapters/opencode.ts +++ b/src/core/command-generation/adapters/opencode.ts @@ -10,14 +10,14 @@ import { transformToHyphenCommands } from '../../../utils/command-references.js' /** * OpenCode adapter for command generation. - * File path: .opencode/command/opsx-.md + * File path: .opencode/commands/opsx-.md * Frontmatter: description */ export const opencodeAdapter: ToolCommandAdapter = { toolId: 'opencode', getFilePath(commandId: string): string { - return path.join('.opencode', 'command', `opsx-${commandId}.md`); + return path.join('.opencode', 'commands', `opsx-${commandId}.md`); }, formatFile(content: CommandContent): string { diff --git a/src/core/legacy-cleanup.ts b/src/core/legacy-cleanup.ts index e443a316d..fbf409ffb 100644 --- a/src/core/legacy-cleanup.ts +++ b/src/core/legacy-cleanup.ts @@ -49,7 +49,7 @@ export const LEGACY_SLASH_COMMAND_PATHS: Record { it('should generate correct file path', () => { const filePath = opencodeAdapter.getFilePath('explore'); - expect(filePath).toBe(path.join('.opencode', 'command', 'opsx-explore.md')); + expect(filePath).toBe(path.join('.opencode', 'commands', 'opsx-explore.md')); }); it('should format file with description frontmatter', () => { From f2ece90e1d43d65e511178360408021032203fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Silva=20Ortiz?= Date: Wed, 25 Feb 2026 22:20:07 -0300 Subject: [PATCH 2/3] fix(legacy): detect both opsx-* and openspec-* patterns, auto-cleanup in CI - Extend LegacySlashCommandPattern.pattern to accept string | string[] - OpenCode legacy entry now detects both opsx-*.md and openspec-*.md - Auto-cleanup legacy artifacts in non-interactive mode instead of aborting with exit 1 (safe: slash commands are OpenSpec-managed, config cleanup only removes markers) - Add 7 tests (6 legacy detection + 1 non-interactive init) - Update spec with array pattern support and auto-cleanup scenario Co-Authored-By: Claude Opus 4.6 --- .../specs/command-generation/spec.md | 10 ++- src/core/init.ts | 13 +-- src/core/legacy-cleanup.ts | 31 ++++--- test/core/init.test.ts | 18 ++++ test/core/legacy-cleanup.test.ts | 83 +++++++++++++++++++ 5 files changed, 134 insertions(+), 21 deletions(-) diff --git a/openspec/changes/fix-opencode-commands-directory/specs/command-generation/spec.md b/openspec/changes/fix-opencode-commands-directory/specs/command-generation/spec.md index ae2b24ce1..f00cb3ce8 100644 --- a/openspec/changes/fix-opencode-commands-directory/specs/command-generation/spec.md +++ b/openspec/changes/fix-opencode-commands-directory/specs/command-generation/spec.md @@ -45,11 +45,19 @@ The legacy cleanup module SHALL detect and remove old OpenCode command files fro #### Scenario: Detect old singular-path OpenCode command files -- **WHEN** running legacy artifact detection on a project with files matching `.opencode/command/openspec-*.md` or `.opencode/command/opsx-*.md` +- **WHEN** running legacy artifact detection on a project with files matching `.opencode/command/opsx-*.md` or `.opencode/command/openspec-*.md` - **THEN** the system SHALL include those files in the legacy slash command files list via `LEGACY_SLASH_COMMAND_PATHS` +- **AND** `LegacySlashCommandPattern.pattern` SHALL accept `string | string[]` to support multiple glob patterns per tool #### Scenario: Clean up old OpenCode command files on init - **WHEN** a user runs `openspec init` in a project with old `.opencode/command/` artifacts - **THEN** the system SHALL remove the old files - **AND** generate new command files at `.opencode/commands/` + +#### Scenario: Auto-cleanup legacy artifacts in non-interactive mode + +- **WHEN** a user runs `openspec init` in non-interactive mode (e.g., CI) and legacy artifacts are detected +- **THEN** the system SHALL auto-cleanup legacy artifacts without requiring `--force` +- **AND** legacy slash command files (100% OpenSpec-managed) SHALL be removed +- **AND** config file cleanup SHALL only remove OpenSpec markers (never delete user files) diff --git a/src/core/init.ts b/src/core/init.ts index cf72a5b6f..95728dc7e 100644 --- a/src/core/init.ts +++ b/src/core/init.ts @@ -208,19 +208,14 @@ export class InitCommand { const canPrompt = this.canPromptInteractively(); - if (this.force) { - // --force flag: proceed with cleanup automatically + if (this.force || !canPrompt) { + // --force flag or non-interactive mode: proceed with cleanup automatically. + // Legacy slash commands are 100% OpenSpec-managed, and config file cleanup + // only removes markers (never deletes files), so auto-cleanup is safe. await this.performLegacyCleanup(projectPath, detection); return; } - if (!canPrompt) { - // Non-interactive mode without --force: abort - console.log(chalk.red('Legacy files detected in non-interactive mode.')); - console.log(chalk.dim('Run interactively to upgrade, or use --force to auto-cleanup.')); - process.exit(1); - } - // Interactive mode: prompt for confirmation const { confirm } = await import('@inquirer/prompts'); const shouldCleanup = await confirm({ diff --git a/src/core/legacy-cleanup.ts b/src/core/legacy-cleanup.ts index fbf409ffb..b165b9e99 100644 --- a/src/core/legacy-cleanup.ts +++ b/src/core/legacy-cleanup.ts @@ -49,7 +49,7 @@ export const LEGACY_SLASH_COMMAND_PATHS: Record /^\.cursor\/commands\/openspec-.*\.md$/ - const regexPattern = pattern.pattern - .replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape regex special chars except * - .replace(/\*/g, '.*'); // Replace * with .* - const regex = new RegExp(`^${regexPattern}$`); - if (regex.test(normalizedFile)) { - tools.add(toolId); - break; + const patterns = Array.isArray(pattern.pattern) ? pattern.pattern : [pattern.pattern]; + let matched = false; + for (const p of patterns) { + const regexPattern = p + .replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape regex special chars except * + .replace(/\*/g, '.*'); // Replace * with .* + const regex = new RegExp(`^${regexPattern}$`); + if (regex.test(normalizedFile)) { + tools.add(toolId); + matched = true; + break; + } } + if (matched) break; } } } diff --git a/test/core/init.test.ts b/test/core/init.test.ts index 0f6fb42b7..6af92aed2 100644 --- a/test/core/init.test.ts +++ b/test/core/init.test.ts @@ -536,6 +536,24 @@ describe('InitCommand - profile and detection features', () => { expect(await fileExists(skillFile)).toBe(true); }); + it('should auto-cleanup legacy artifacts in non-interactive mode without --force', async () => { + // Create legacy OpenCode command files (singular 'command' path) + const legacyDir = path.join(testDir, '.opencode', 'command'); + await fs.mkdir(legacyDir, { recursive: true }); + await fs.writeFile(path.join(legacyDir, 'opsx-propose.md'), 'legacy content'); + + // Run init in non-interactive mode without --force + const initCommand = new InitCommand({ tools: 'opencode' }); + await initCommand.execute(testDir); + + // Legacy files should be cleaned up automatically + expect(await fileExists(path.join(legacyDir, 'opsx-propose.md'))).toBe(false); + + // New commands should be at the correct plural path + const newCommandsDir = path.join(testDir, '.opencode', 'commands'); + expect(await directoryExists(newCommandsDir)).toBe(true); + }); + it('should preselect configured tools but not directory-detected tools in extend mode', async () => { // Simulate existing OpenSpec project (extend mode). await fs.mkdir(path.join(testDir, 'openspec'), { recursive: true }); diff --git a/test/core/legacy-cleanup.test.ts b/test/core/legacy-cleanup.test.ts index a69158a39..bfae37805 100644 --- a/test/core/legacy-cleanup.test.ts +++ b/test/core/legacy-cleanup.test.ts @@ -335,6 +335,35 @@ ${OPENSPEC_MARKERS.end}`); const result = await detectLegacySlashCommands(testDir); expect(result.files).toContain('.continue/prompts/openspec-apply.prompt'); }); + + it('should detect legacy OpenCode opsx-* command files', async () => { + const dirPath = path.join(testDir, '.opencode', 'command'); + await fs.mkdir(dirPath, { recursive: true }); + await fs.writeFile(path.join(dirPath, 'opsx-propose.md'), 'content'); + + const result = await detectLegacySlashCommands(testDir); + expect(result.files).toContain('.opencode/command/opsx-propose.md'); + }); + + it('should detect legacy OpenCode openspec-* command files', async () => { + const dirPath = path.join(testDir, '.opencode', 'command'); + await fs.mkdir(dirPath, { recursive: true }); + await fs.writeFile(path.join(dirPath, 'openspec-new.md'), 'content'); + + const result = await detectLegacySlashCommands(testDir); + expect(result.files).toContain('.opencode/command/openspec-new.md'); + }); + + it('should detect both opsx-* and openspec-* OpenCode command files', async () => { + const dirPath = path.join(testDir, '.opencode', 'command'); + await fs.mkdir(dirPath, { recursive: true }); + await fs.writeFile(path.join(dirPath, 'opsx-propose.md'), 'content'); + await fs.writeFile(path.join(dirPath, 'openspec-new.md'), 'content'); + + const result = await detectLegacySlashCommands(testDir); + expect(result.files).toContain('.opencode/command/opsx-propose.md'); + expect(result.files).toContain('.opencode/command/openspec-new.md'); + }); }); describe('detectLegacyStructureFiles', () => { @@ -1058,6 +1087,60 @@ ${OPENSPEC_MARKERS.end}`); expect(tools).toHaveLength(1); }); + it('should handle opencode opsx-* legacy files', () => { + const detection = { + configFiles: [], + configFilesToUpdate: [], + slashCommandDirs: [], + slashCommandFiles: ['.opencode/command/opsx-propose.md'], + hasOpenspecAgents: false, + hasProjectMd: false, + hasRootAgentsWithMarkers: false, + hasLegacyArtifacts: true, + }; + + const tools = getToolsFromLegacyArtifacts(detection); + expect(tools).toContain('opencode'); + expect(tools).toHaveLength(1); + }); + + it('should handle opencode openspec-* legacy files', () => { + const detection = { + configFiles: [], + configFilesToUpdate: [], + slashCommandDirs: [], + slashCommandFiles: ['.opencode/command/openspec-new.md'], + hasOpenspecAgents: false, + hasProjectMd: false, + hasRootAgentsWithMarkers: false, + hasLegacyArtifacts: true, + }; + + const tools = getToolsFromLegacyArtifacts(detection); + expect(tools).toContain('opencode'); + expect(tools).toHaveLength(1); + }); + + it('should deduplicate opencode when both opsx-* and openspec-* files exist', () => { + const detection = { + configFiles: [], + configFilesToUpdate: [], + slashCommandDirs: [], + slashCommandFiles: [ + '.opencode/command/opsx-propose.md', + '.opencode/command/openspec-new.md', + ], + hasOpenspecAgents: false, + hasProjectMd: false, + hasRootAgentsWithMarkers: false, + hasLegacyArtifacts: true, + }; + + const tools = getToolsFromLegacyArtifacts(detection); + expect(tools).toContain('opencode'); + expect(tools).toHaveLength(1); + }); + it('should not extract tools from config files only', () => { // Config files don't indicate which tools were configured // Only slash command dirs/files tell us which tools to upgrade From 692244b3ace52069b027e55a98d21a6f72aa7246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Silva=20Ortiz?= Date: Thu, 26 Feb 2026 14:16:03 -0300 Subject: [PATCH 3/3] chore: update task description to reflect dual-pattern support Co-Authored-By: Claude Opus 4.6 --- openspec/changes/fix-opencode-commands-directory/tasks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openspec/changes/fix-opencode-commands-directory/tasks.md b/openspec/changes/fix-opencode-commands-directory/tasks.md index 828731eff..bfe020764 100644 --- a/openspec/changes/fix-opencode-commands-directory/tasks.md +++ b/openspec/changes/fix-opencode-commands-directory/tasks.md @@ -4,7 +4,7 @@ ## 2. Legacy Cleanup -- [x] 2.1 Update `src/core/legacy-cleanup.ts`: change the `'opencode'` entry in `LEGACY_SLASH_COMMAND_PATHS` from `'.opencode/command/openspec-*.md'` to `'.opencode/command/opsx-*.md'` to detect old singular-path artifacts with the current `opsx-*` prefix +- [x] 2.1 Update `src/core/legacy-cleanup.ts`: update the `'opencode'` entry in `LEGACY_SLASH_COMMAND_PATHS` to detect both `opsx-*.md` and `openspec-*.md` patterns at `.opencode/command/` for backward compatibility ## 3. Documentation