diff --git a/README.md b/README.md index 70f17b38..40291298 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ These tools have built-in OpenSpec commands. Select the OpenSpec integration whe |------|----------| | **Claude Code** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` | | **CodeBuddy Code (CLI)** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.codebuddy/commands/`) — see [docs](https://www.codebuddy.ai/cli) | -| **Costrict** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.cospec/openspec/commands/`) — see [docs](https://costrict.ai)| +| **CoStrict** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.cospec/openspec/commands/`) — see [docs](https://costrict.ai)| | **Cursor** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` | | **Cline** | Rules in `.clinerules/` directory (`.clinerules/openspec-*.md`) | | **Crush** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.crush/commands/openspec/`) | diff --git a/src/core/config.ts b/src/core/config.ts index a0e64a8a..e3e9c656 100644 --- a/src/core/config.ts +++ b/src/core/config.ts @@ -21,7 +21,7 @@ export const AI_TOOLS: AIToolOption[] = [ { name: 'Claude Code', value: 'claude', available: true, successLabel: 'Claude Code' }, { name: 'Cline', value: 'cline', available: true, successLabel: 'Cline' }, { name: 'CodeBuddy Code (CLI)', value: 'codebuddy', available: true, successLabel: 'CodeBuddy Code' }, - { name: 'Costrict', value: 'costrict', available: true, successLabel: 'Costrict' }, + { name: 'CoStrict', value: 'costrict', available: true, successLabel: 'CoStrict' }, { name: 'Crush', value: 'crush', available: true, successLabel: 'Crush' }, { name: 'Cursor', value: 'cursor', available: true, successLabel: 'Cursor' }, { name: 'Factory Droid', value: 'factory', available: true, successLabel: 'Factory Droid' }, diff --git a/src/core/configurators/costrict.ts b/src/core/configurators/costrict.ts index 1966c898..6a1a8d1d 100644 --- a/src/core/configurators/costrict.ts +++ b/src/core/configurators/costrict.ts @@ -5,7 +5,7 @@ import { TemplateManager } from '../templates/index.js'; import { OPENSPEC_MARKERS } from '../config.js'; export class CostrictConfigurator implements ToolConfigurator { - name = 'Costrict'; + name = 'CoStrict'; configFileName = 'COSTRICT.md'; isAvailable = true; diff --git a/src/core/configurators/slash/costrict.ts b/src/core/configurators/slash/costrict.ts index dae43c19..0ba92c64 100644 --- a/src/core/configurators/slash/costrict.ts +++ b/src/core/configurators/slash/costrict.ts @@ -1,13 +1,13 @@ import { SlashCommandConfigurator } from './base.js'; import { SlashCommandId } from '../../templates/index.js'; -const FILE_PATHS: Record = { +const FILE_PATHS = { proposal: '.cospec/openspec/commands/openspec-proposal.md', apply: '.cospec/openspec/commands/openspec-apply.md', - archive: '.cospec/openspec/commands/openspec-archive.md' -}; + archive: '.cospec/openspec/commands/openspec-archive.md', +} as const satisfies Record; -const FRONTMATTER: Record = { +const FRONTMATTER = { proposal: `--- description: "Scaffold a new OpenSpec change and validate strictly." argument-hint: feature description or request @@ -20,7 +20,7 @@ argument-hint: change-id description: "Archive a deployed OpenSpec change and update specs." argument-hint: change-id ---` -}; +} as const satisfies Record; export class CostrictSlashCommandConfigurator extends SlashCommandConfigurator { readonly toolId = 'costrict'; diff --git a/test/core/init.test.ts b/test/core/init.test.ts index c2f6ae00..fcf0fab3 100644 --- a/test/core/init.test.ts +++ b/test/core/init.test.ts @@ -996,7 +996,7 @@ describe('InitCommand', () => { expect(crushChoice.configured).toBe(true); }); - it('should create Costrict slash command files with templates', async () => { + it('should create CoStrict slash command files with templates', async () => { queueSelections('costrict', DONE); await initCommand.execute(testDir); @@ -1038,7 +1038,7 @@ describe('InitCommand', () => { expect(archiveContent).toContain('openspec archive --yes'); }); - it('should mark Costrict as already configured during extend mode', async () => { + it('should mark CoStrict as already configured during extend mode', async () => { queueSelections('costrict', DONE, 'costrict', DONE); await initCommand.execute(testDir); await initCommand.execute(testDir); @@ -1050,7 +1050,7 @@ describe('InitCommand', () => { expect(costrictChoice.configured).toBe(true); }); - it('should create COSTRICT.md when Costrict is selected', async () => { + it('should create COSTRICT.md when CoStrict is selected', async () => { queueSelections('costrict', DONE); await initCommand.execute(testDir); @@ -1070,7 +1070,7 @@ describe('InitCommand', () => { const costrictPath = path.join(testDir, 'COSTRICT.md'); const existingContent = - '# My Costrict Instructions\nCustom instructions here'; + '# My CoStrict Instructions\nCustom instructions here'; await fs.writeFile(costrictPath, existingContent); await initCommand.execute(testDir); diff --git a/test/core/update.test.ts b/test/core/update.test.ts index e580adab..a1c9f1d2 100644 --- a/test/core/update.test.ts +++ b/test/core/update.test.ts @@ -819,7 +819,7 @@ Old body await expect(FileSystemUtils.fileExists(crushArchive)).resolves.toBe(false); }); - it('should refresh existing Costrict slash command files', async () => { + it('should refresh existing CoStrict slash command files', async () => { const costrictPath = path.join( testDir, '.cospec/openspec/commands/openspec-proposal.md' @@ -860,7 +860,7 @@ Old body consoleSpy.mockRestore(); }); - it('should not create missing Costrict slash command files on update', async () => { + it('should not create missing CoStrict slash command files on update', async () => { const costrictApply = path.join( testDir, '.cospec/openspec/commands/openspec-apply.md' @@ -898,9 +898,9 @@ Old it('should update only existing COSTRICT.md file', async () => { // Create COSTRICT.md file with initial content const costrictPath = path.join(testDir, 'COSTRICT.md'); - const initialContent = `# Costrict Instructions + const initialContent = `# CoStrict Instructions -Some existing Costrict instructions here. +Some existing CoStrict instructions here. Old OpenSpec content @@ -920,7 +920,7 @@ More instructions after.`; expect(updatedContent).toContain(''); expect(updatedContent).toContain("@/openspec/AGENTS.md"); expect(updatedContent).toContain('openspec update'); - expect(updatedContent).toContain('Some existing Costrict instructions here'); + expect(updatedContent).toContain('Some existing CoStrict instructions here'); expect(updatedContent).toContain('More instructions after'); // Check console output @@ -945,7 +945,7 @@ More instructions after.`; expect(fileExists).toBe(false); }); - it('should preserve Costrict content outside markers during update', async () => { + it('should preserve CoStrict content outside markers during update', async () => { const costrictPath = path.join( testDir, '.cospec/openspec/commands/openspec-proposal.md' @@ -963,14 +963,13 @@ More instructions after.`; expect(updated).toContain('Validate with `openspec validate --strict`'); }); - it('should handle configurator errors gracefully for Costrict', async () => { + it('should handle configurator errors gracefully for CoStrict', async () => { // Create COSTRICT.md file but make it read-only to cause an error const costrictPath = path.join(testDir, 'COSTRICT.md'); await fs.writeFile( costrictPath, '\nOld\n' ); - await fs.chmod(costrictPath, 0o444); // Read-only const consoleSpy = vi.spyOn(console, 'log'); const errorSpy = vi.spyOn(console, 'error'); @@ -997,8 +996,6 @@ More instructions after.`; expect(logMessage).toContain('AGENTS.md (created)'); expect(logMessage).toContain('Failed to update: COSTRICT.md'); - // Restore permissions for cleanup - await fs.chmod(costrictPath, 0o644); consoleSpy.mockRestore(); errorSpy.mockRestore(); writeSpy.mockRestore();