clavix 5.2.1 → 5.3.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.
Files changed (48) hide show
  1. package/README.md +3 -4
  2. package/dist/cli/commands/diagnose.js +1 -1
  3. package/dist/cli/commands/init.d.ts +4 -0
  4. package/dist/cli/commands/init.js +130 -24
  5. package/dist/cli/commands/update.js +1 -1
  6. package/dist/constants.d.ts +18 -0
  7. package/dist/constants.js +24 -0
  8. package/dist/core/adapter-registry.d.ts +39 -0
  9. package/dist/core/adapter-registry.js +208 -0
  10. package/dist/core/adapters/base-adapter.d.ts +1 -0
  11. package/dist/core/adapters/base-adapter.js +3 -1
  12. package/dist/core/adapters/universal-adapter.d.ts +49 -0
  13. package/dist/core/adapters/universal-adapter.js +88 -0
  14. package/dist/core/command-transformer.d.ts +11 -12
  15. package/dist/core/command-transformer.js +11 -12
  16. package/dist/core/doc-injector.d.ts +0 -4
  17. package/dist/core/doc-injector.js +5 -10
  18. package/dist/core/template-assembler.d.ts +1 -1
  19. package/dist/core/template-assembler.js +1 -1
  20. package/dist/templates/agents/agents.md +1 -2
  21. package/dist/templates/agents/copilot-instructions.md +1 -2
  22. package/dist/templates/agents/octo.md +1 -1
  23. package/dist/templates/agents/warp.md +2 -2
  24. package/dist/templates/instructions/core/file-operations.md +15 -11
  25. package/dist/templates/slash-commands/_canonical/plan.md +1 -2
  26. package/dist/templates/slash-commands/_components/MANIFEST.md +81 -0
  27. package/dist/templates/slash-commands/_components/agent-protocols/AGENT_MANUAL.md +1 -1
  28. package/dist/templates/slash-commands/_components/agent-protocols/cli-reference.md +15 -17
  29. package/dist/types/adapter-config.d.ts +73 -0
  30. package/dist/types/adapter-config.js +24 -0
  31. package/dist/types/config.js +3 -2
  32. package/dist/utils/error-utils.d.ts +4 -0
  33. package/dist/utils/error-utils.js +6 -0
  34. package/dist/utils/file-system.js +7 -12
  35. package/dist/utils/legacy-command-cleanup.d.ts +14 -0
  36. package/dist/utils/legacy-command-cleanup.js +14 -0
  37. package/dist/utils/logger.d.ts +32 -0
  38. package/dist/utils/logger.js +56 -0
  39. package/dist/utils/string-utils.d.ts +10 -0
  40. package/dist/utils/string-utils.js +12 -0
  41. package/dist/utils/version.d.ts +20 -0
  42. package/dist/utils/version.js +43 -0
  43. package/oclif.manifest.json +130 -0
  44. package/package.json +1 -1
  45. package/dist/cli/commands/config.d.ts +0 -28
  46. package/dist/cli/commands/config.js +0 -447
  47. package/dist/templates/slash-commands/_components/agent-protocols/decision-rules.md +0 -232
  48. package/dist/templates/slash-commands/_components/agent-protocols/error-handling.md +0 -177
package/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  | Version | Highlights | Details |
14
14
  | --- | --- | --- |
15
- | **v5.2.0** (Latest) | Diagnose command, DRY architecture, feature matrix | [Changelog](CHANGELOG.md) |
15
+ | **v5.2.1** (Latest) | Diagnose command, DRY architecture, feature matrix | [Changelog](CHANGELOG.md) |
16
16
  | **v5.0.0** | Agentic-first architecture - lean template delivery | [Changelog](CHANGELOG.md#500---2025-01-27) |
17
17
  | **v4.12.0** | Final v4 release with full CLI commands | [Changelog](docs/archive/v4-changelog.md) |
18
18
 
@@ -113,13 +113,12 @@ clavix update # After npm update clavix
113
113
 
114
114
  ## CLI Commands
115
115
 
116
- Clavix v5 has 5 CLI commands (for setup and diagnostics, not workflows):
116
+ Clavix v5 has 4 CLI commands (for setup and diagnostics, not workflows):
117
117
 
118
118
  | Command | Purpose |
119
119
  |---------|---------|
120
- | `clavix init` | Initialize Clavix in a project |
120
+ | `clavix init` | Initialize or reconfigure Clavix in a project |
121
121
  | `clavix update` | Update templates after package update |
122
- | `clavix config` | Manage configuration |
123
122
  | `clavix diagnose` | Check installation and report issues |
124
123
  | `clavix version` | Show version |
125
124
 
@@ -136,7 +136,7 @@ export default class Diagnose extends Command {
136
136
  return {
137
137
  status: 'warn',
138
138
  message: 'No integrations configured',
139
- details: 'Run `clavix config` to add integrations',
139
+ details: 'Run `clavix init` to add integrations',
140
140
  };
141
141
  }
142
142
  return {
@@ -3,6 +3,10 @@ export default class Init extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  run(): Promise<void>;
6
+ /**
7
+ * Regenerate commands for existing integrations (update mode)
8
+ */
9
+ private regenerateCommands;
6
10
  private createDirectoryStructure;
7
11
  private generateConfig;
8
12
  private generateInstructions;
@@ -21,24 +21,9 @@ export default class Init extends Command {
21
21
  async run() {
22
22
  console.log(chalk.bold.cyan('\nšŸš€ Clavix Initialization\n'));
23
23
  try {
24
- // Check if already initialized
25
- if (await FileSystem.exists('.clavix')) {
26
- const { reinit } = await inquirer.prompt([
27
- {
28
- type: 'confirm',
29
- name: 'reinit',
30
- message: 'Clavix is already initialized. Reinitialize?',
31
- default: false,
32
- },
33
- ]);
34
- if (!reinit) {
35
- console.log(chalk.yellow('\nāœ“ Initialization cancelled\n'));
36
- return;
37
- }
38
- }
39
- // Load existing config if re-initializing
40
24
  const agentManager = new AgentManager();
41
25
  let existingIntegrations = [];
26
+ // Load existing config if present
42
27
  if (await FileSystem.exists('.clavix/config.json')) {
43
28
  try {
44
29
  const configContent = await FileSystem.readFile('.clavix/config.json');
@@ -49,6 +34,45 @@ export default class Init extends Command {
49
34
  // Ignore parse errors, will use empty array
50
35
  }
51
36
  }
37
+ // Check if already initialized
38
+ if (await FileSystem.exists('.clavix')) {
39
+ // Show current state
40
+ console.log(chalk.cyan('You have existing Clavix configuration:'));
41
+ if (existingIntegrations.length > 0) {
42
+ const displayNames = existingIntegrations.map((name) => {
43
+ const adapter = agentManager.getAdapter(name);
44
+ return adapter?.displayName || name;
45
+ });
46
+ console.log(chalk.gray(` Integrations: ${displayNames.join(', ')}\n`));
47
+ }
48
+ else {
49
+ console.log(chalk.gray(' Integrations: (none configured)\n'));
50
+ }
51
+ const { action } = await inquirer.prompt([
52
+ {
53
+ type: 'list',
54
+ name: 'action',
55
+ message: 'What would you like to do?',
56
+ choices: [
57
+ { name: 'Reconfigure integrations', value: 'reconfigure' },
58
+ { name: 'Update existing (regenerate commands)', value: 'update' },
59
+ { name: 'Cancel', value: 'cancel' },
60
+ ],
61
+ },
62
+ ]);
63
+ if (action === 'cancel') {
64
+ console.log(chalk.yellow('\nāœ“ Initialization cancelled\n'));
65
+ return;
66
+ }
67
+ if (action === 'update') {
68
+ // Just regenerate commands for existing integrations
69
+ console.log(chalk.cyan('\nšŸ“ Regenerating commands...\n'));
70
+ await this.regenerateCommands(agentManager, existingIntegrations);
71
+ console.log(chalk.green('\nāœ… Commands updated successfully!\n'));
72
+ return;
73
+ }
74
+ // Continue with reconfiguration flow below
75
+ }
52
76
  // Select integrations using shared utility
53
77
  console.log(chalk.gray('Select AI development tools to support:\n'));
54
78
  console.log(chalk.gray('(Space to select, Enter to confirm)\n'));
@@ -83,6 +107,32 @@ export default class Init extends Command {
83
107
  if (cleanupAction === 'cleanup') {
84
108
  console.log(chalk.gray('\nšŸ—‘ļø Cleaning up deselected integrations...'));
85
109
  for (const integrationName of deselectedIntegrations) {
110
+ // Handle doc generators (AGENTS.md, OCTO.md, WARP.md, copilot-instructions)
111
+ if (integrationName === 'agents-md') {
112
+ await DocInjector.removeBlock('AGENTS.md');
113
+ console.log(chalk.gray(' āœ“ Cleaned AGENTS.md Clavix block'));
114
+ continue;
115
+ }
116
+ if (integrationName === 'octo-md') {
117
+ await DocInjector.removeBlock('OCTO.md');
118
+ console.log(chalk.gray(' āœ“ Cleaned OCTO.md Clavix block'));
119
+ continue;
120
+ }
121
+ if (integrationName === 'warp-md') {
122
+ await DocInjector.removeBlock('WARP.md');
123
+ console.log(chalk.gray(' āœ“ Cleaned WARP.md Clavix block'));
124
+ continue;
125
+ }
126
+ if (integrationName === 'copilot-instructions') {
127
+ await DocInjector.removeBlock('.github/copilot-instructions.md');
128
+ console.log(chalk.gray(' āœ“ Cleaned copilot-instructions.md Clavix block'));
129
+ continue;
130
+ }
131
+ // Handle Claude Code (has CLAUDE.md doc injection)
132
+ if (integrationName === 'claude-code') {
133
+ await DocInjector.removeBlock('CLAUDE.md');
134
+ console.log(chalk.gray(' āœ“ Cleaned CLAUDE.md Clavix block'));
135
+ }
86
136
  const adapter = agentManager.getAdapter(integrationName);
87
137
  if (adapter) {
88
138
  const removed = await adapter.removeAllCommands();
@@ -247,8 +297,69 @@ export default class Init extends Command {
247
297
  throw toError(error);
248
298
  }
249
299
  }
300
+ /**
301
+ * Regenerate commands for existing integrations (update mode)
302
+ */
303
+ async regenerateCommands(agentManager, integrations) {
304
+ for (const integrationName of integrations) {
305
+ // Handle doc generators (not adapters)
306
+ if (integrationName === 'agents-md') {
307
+ console.log(chalk.gray(' āœ“ Regenerating AGENTS.md...'));
308
+ await AgentsMdGenerator.generate();
309
+ continue;
310
+ }
311
+ if (integrationName === 'copilot-instructions') {
312
+ console.log(chalk.gray(' āœ“ Regenerating .github/copilot-instructions.md...'));
313
+ await CopilotInstructionsGenerator.generate();
314
+ continue;
315
+ }
316
+ if (integrationName === 'octo-md') {
317
+ console.log(chalk.gray(' āœ“ Regenerating OCTO.md...'));
318
+ await OctoMdGenerator.generate();
319
+ continue;
320
+ }
321
+ if (integrationName === 'warp-md') {
322
+ console.log(chalk.gray(' āœ“ Regenerating WARP.md...'));
323
+ await WarpMdGenerator.generate();
324
+ continue;
325
+ }
326
+ // Handle regular adapters
327
+ const adapter = agentManager.getAdapter(integrationName);
328
+ if (!adapter) {
329
+ console.log(chalk.yellow(` ⚠ Unknown integration: ${integrationName}`));
330
+ continue;
331
+ }
332
+ console.log(chalk.gray(` āœ“ Regenerating ${adapter.displayName} commands...`));
333
+ // Remove existing commands before regenerating
334
+ const removed = await adapter.removeAllCommands();
335
+ if (removed > 0) {
336
+ console.log(chalk.gray(` Removed ${removed} existing command(s)`));
337
+ }
338
+ // Generate slash commands
339
+ const templates = await this.generateSlashCommands(adapter);
340
+ // Handle legacy command cleanup (silent in update mode)
341
+ const commandNames = templates.map((template) => template.name);
342
+ const legacyFiles = await collectLegacyCommandFiles(adapter, commandNames);
343
+ if (legacyFiles.length > 0) {
344
+ for (const file of legacyFiles) {
345
+ await FileSystem.remove(file);
346
+ }
347
+ console.log(chalk.gray(` Cleaned ${legacyFiles.length} legacy file(s)`));
348
+ }
349
+ // Re-inject documentation blocks (Claude Code only)
350
+ if (integrationName === 'claude-code') {
351
+ console.log(chalk.gray(' āœ“ Updating CLAUDE.md documentation...'));
352
+ await this.injectDocumentation(adapter);
353
+ }
354
+ }
355
+ // Regenerate instructions folder if needed
356
+ if (InstructionsGenerator.needsGeneration(integrations)) {
357
+ console.log(chalk.gray('\nšŸ“ Updating .clavix/instructions/ reference folder...'));
358
+ await InstructionsGenerator.generate();
359
+ }
360
+ }
250
361
  async createDirectoryStructure() {
251
- const dirs = ['.clavix', '.clavix/sessions', '.clavix/outputs', '.clavix/templates'];
362
+ const dirs = ['.clavix', '.clavix/outputs', '.clavix/templates'];
252
363
  for (const dir of dirs) {
253
364
  await FileSystem.ensureDir(dir);
254
365
  }
@@ -274,7 +385,6 @@ Welcome to Clavix! This directory contains your local Clavix configuration and d
274
385
  ā”œā”€ā”€ config.json # Your Clavix configuration
275
386
  ā”œā”€ā”€ INSTRUCTIONS.md # This file
276
387
  ā”œā”€ā”€ instructions/ # Workflow instruction files for AI agents
277
- ā”œā”€ā”€ sessions/ # Conversational mode session files
278
388
  ā”œā”€ā”€ outputs/
279
389
  │ ā”œā”€ā”€ <project-name>/ # Per-project outputs
280
390
  │ │ ā”œā”€ā”€ full-prd.md
@@ -293,7 +403,7 @@ Welcome to Clavix! This directory contains your local Clavix configuration and d
293
403
  |---------|---------|
294
404
  | \`clavix init\` | Initialize Clavix in a project |
295
405
  | \`clavix update\` | Update templates after package update |
296
- | \`clavix config\` | Manage configuration |
406
+ | \`clavix diagnose\` | Check installation health |
297
407
  | \`clavix version\` | Show version |
298
408
 
299
409
  ### Workflow Commands (Slash Commands)
@@ -363,11 +473,7 @@ PRD Creation → Task Planning → Implementation → Archive
363
473
 
364
474
  Create custom templates in \`.clavix/templates/\` to override defaults.
365
475
 
366
- Edit configuration:
367
- \`\`\`bash
368
- clavix config edit # Opens config.json in $EDITOR
369
- clavix config set key=value
370
- \`\`\`
476
+ To reconfigure integrations, run \`clavix init\` again.
371
477
 
372
478
  ## Need Help?
373
479
 
@@ -220,7 +220,7 @@ This project uses Clavix for prompt improvement and PRD generation.
220
220
  |---------|---------|
221
221
  | \`clavix init\` | Initialize Clavix in a project |
222
222
  | \`clavix update\` | Update templates after package update |
223
- | \`clavix config\` | Manage configuration |
223
+ | \`clavix diagnose\` | Check installation health |
224
224
  | \`clavix version\` | Show version |
225
225
 
226
226
  ### Workflow Commands (Slash Commands)
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Clavix constants and magic values
3
+ * Centralizes hardcoded values for maintainability
4
+ */
5
+ export declare const BACKUP_EXTENSION = ".backup";
6
+ export declare const SEPARATOR_WIDTH = 50;
7
+ export declare const SEPARATOR_CHAR = "\u2500";
8
+ export declare const CLAVIX_BLOCK_START = "<!-- CLAVIX:START -->";
9
+ export declare const CLAVIX_BLOCK_END = "<!-- CLAVIX:END -->";
10
+ export declare const WINDSURF_CHAR_LIMIT = 12000;
11
+ export declare const DEPTH_STANDARD = "standard";
12
+ export declare const DEPTH_COMPREHENSIVE = "comprehensive";
13
+ export declare const CLAVIX_CONFIG_DIR = ".clavix";
14
+ export declare const CLAVIX_CONFIG_FILE = "config.json";
15
+ export declare const CLAVIX_OUTPUTS_DIR = "outputs";
16
+ export declare const CLAVIX_PROMPTS_DIR = "prompts";
17
+ export declare const CLAVIX_TEMPLATES_DIR = "templates";
18
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Clavix constants and magic values
3
+ * Centralizes hardcoded values for maintainability
4
+ */
5
+ // File system
6
+ export const BACKUP_EXTENSION = '.backup';
7
+ // CLI formatting
8
+ export const SEPARATOR_WIDTH = 50;
9
+ export const SEPARATOR_CHAR = '─';
10
+ // Clavix managed block markers
11
+ export const CLAVIX_BLOCK_START = '<!-- CLAVIX:START -->';
12
+ export const CLAVIX_BLOCK_END = '<!-- CLAVIX:END -->';
13
+ // Adapter-specific limits
14
+ export const WINDSURF_CHAR_LIMIT = 12000;
15
+ // Depth terminology (canonical)
16
+ export const DEPTH_STANDARD = 'standard';
17
+ export const DEPTH_COMPREHENSIVE = 'comprehensive';
18
+ // File patterns
19
+ export const CLAVIX_CONFIG_DIR = '.clavix';
20
+ export const CLAVIX_CONFIG_FILE = 'config.json';
21
+ export const CLAVIX_OUTPUTS_DIR = 'outputs';
22
+ export const CLAVIX_PROMPTS_DIR = 'prompts';
23
+ export const CLAVIX_TEMPLATES_DIR = 'templates';
24
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Adapter Registry - Config-driven adapter definitions
3
+ *
4
+ * This registry provides configuration for all simple adapters that can
5
+ * be represented as pure configuration without custom logic.
6
+ *
7
+ * For adapters requiring custom behavior (TOML format, doc injection),
8
+ * dedicated adapter classes still exist.
9
+ *
10
+ * @since v5.3.0
11
+ */
12
+ import { AdapterConfig } from '../types/adapter-config.js';
13
+ /**
14
+ * Registry of all adapter configurations
15
+ *
16
+ * These configurations describe how each adapter behaves:
17
+ * - Where commands are stored
18
+ * - File extension and naming pattern
19
+ * - Feature support (subdirectories, frontmatter, etc.)
20
+ * - Detection method for project environment
21
+ */
22
+ export declare const ADAPTER_CONFIGS: AdapterConfig[];
23
+ /**
24
+ * Get adapter configuration by name
25
+ */
26
+ export declare function getAdapterConfig(name: string): AdapterConfig | undefined;
27
+ /**
28
+ * Get all adapter configurations
29
+ */
30
+ export declare function getAllAdapterConfigs(): AdapterConfig[];
31
+ /**
32
+ * Get adapters that require special handling
33
+ */
34
+ export declare function getSpecialAdapters(): AdapterConfig[];
35
+ /**
36
+ * Get simple adapters (can use UniversalAdapter)
37
+ */
38
+ export declare function getSimpleAdapters(): AdapterConfig[];
39
+ //# sourceMappingURL=adapter-registry.d.ts.map
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Adapter Registry - Config-driven adapter definitions
3
+ *
4
+ * This registry provides configuration for all simple adapters that can
5
+ * be represented as pure configuration without custom logic.
6
+ *
7
+ * For adapters requiring custom behavior (TOML format, doc injection),
8
+ * dedicated adapter classes still exist.
9
+ *
10
+ * @since v5.3.0
11
+ */
12
+ import { DEFAULT_MD_FEATURES, DEFAULT_TOML_FEATURES, } from '../types/adapter-config.js';
13
+ /**
14
+ * Registry of all adapter configurations
15
+ *
16
+ * These configurations describe how each adapter behaves:
17
+ * - Where commands are stored
18
+ * - File extension and naming pattern
19
+ * - Feature support (subdirectories, frontmatter, etc.)
20
+ * - Detection method for project environment
21
+ */
22
+ export const ADAPTER_CONFIGS = [
23
+ // IDE Extensions (Markdown-based)
24
+ {
25
+ name: 'cursor',
26
+ displayName: 'Cursor',
27
+ directory: '.cursor/rules',
28
+ fileExtension: '.md',
29
+ filenamePattern: 'clavix-{name}',
30
+ features: { ...DEFAULT_MD_FEATURES },
31
+ detection: { type: 'directory', path: '.cursor' },
32
+ },
33
+ {
34
+ name: 'windsurf',
35
+ displayName: 'Windsurf',
36
+ directory: '.windsurf/rules',
37
+ fileExtension: '.md',
38
+ filenamePattern: 'clavix-{name}',
39
+ features: { ...DEFAULT_MD_FEATURES },
40
+ detection: { type: 'directory', path: '.windsurf' },
41
+ },
42
+ {
43
+ name: 'kilocode',
44
+ displayName: 'Kilocode',
45
+ directory: '.kilocode/rules',
46
+ fileExtension: '.md',
47
+ filenamePattern: 'clavix-{name}',
48
+ features: { ...DEFAULT_MD_FEATURES },
49
+ detection: { type: 'directory', path: '.kilocode' },
50
+ },
51
+ {
52
+ name: 'roocode',
53
+ displayName: 'Roo-Code',
54
+ directory: '.roo/rules',
55
+ fileExtension: '.md',
56
+ filenamePattern: 'clavix-{name}',
57
+ features: { ...DEFAULT_MD_FEATURES },
58
+ detection: { type: 'directory', path: '.roo' },
59
+ },
60
+ {
61
+ name: 'cline',
62
+ displayName: 'Cline',
63
+ directory: '.cline/rules',
64
+ fileExtension: '.md',
65
+ filenamePattern: 'clavix-{name}',
66
+ features: { ...DEFAULT_MD_FEATURES },
67
+ detection: { type: 'directory', path: '.cline' },
68
+ },
69
+ {
70
+ name: 'droid',
71
+ displayName: 'Droid',
72
+ directory: '.droid/rules',
73
+ fileExtension: '.md',
74
+ filenamePattern: 'clavix-{name}',
75
+ features: { ...DEFAULT_MD_FEATURES },
76
+ detection: { type: 'directory', path: '.droid' },
77
+ },
78
+ {
79
+ name: 'opencode',
80
+ displayName: 'OpenCode',
81
+ directory: '.opencode/rules',
82
+ fileExtension: '.md',
83
+ filenamePattern: 'clavix-{name}',
84
+ features: { ...DEFAULT_MD_FEATURES },
85
+ detection: { type: 'directory', path: '.opencode' },
86
+ },
87
+ {
88
+ name: 'crush',
89
+ displayName: 'Crush',
90
+ directory: '.crush/rules',
91
+ fileExtension: '.md',
92
+ filenamePattern: 'clavix-{name}',
93
+ features: { ...DEFAULT_MD_FEATURES },
94
+ detection: { type: 'directory', path: '.crush' },
95
+ },
96
+ {
97
+ name: 'codex',
98
+ displayName: 'Codex CLI',
99
+ directory: '.codex/instructions',
100
+ fileExtension: '.md',
101
+ filenamePattern: 'clavix-{name}',
102
+ features: { ...DEFAULT_MD_FEATURES },
103
+ detection: { type: 'directory', path: '.codex' },
104
+ },
105
+ {
106
+ name: 'codebuddy',
107
+ displayName: 'CodeBuddy',
108
+ directory: '.codebuddy/rules',
109
+ fileExtension: '.md',
110
+ filenamePattern: 'clavix-{name}',
111
+ features: { ...DEFAULT_MD_FEATURES },
112
+ detection: { type: 'directory', path: '.codebuddy' },
113
+ },
114
+ {
115
+ name: 'amp',
116
+ displayName: 'Amp',
117
+ directory: '.amp/rules',
118
+ fileExtension: '.md',
119
+ filenamePattern: 'clavix-{name}',
120
+ features: { ...DEFAULT_MD_FEATURES },
121
+ detection: { type: 'directory', path: '.amp' },
122
+ },
123
+ {
124
+ name: 'augment',
125
+ displayName: 'Augment Code',
126
+ directory: '.augment/rules',
127
+ fileExtension: '.md',
128
+ filenamePattern: 'clavix-{name}',
129
+ features: { ...DEFAULT_MD_FEATURES },
130
+ detection: { type: 'directory', path: '.augment' },
131
+ },
132
+ // Claude Code (requires doc injection - special adapter kept)
133
+ {
134
+ name: 'claude-code',
135
+ displayName: 'Claude Code',
136
+ directory: '.claude/commands/clavix',
137
+ fileExtension: '.md',
138
+ filenamePattern: '{name}',
139
+ features: {
140
+ ...DEFAULT_MD_FEATURES,
141
+ supportsSubdirectories: true,
142
+ supportsFrontmatter: true,
143
+ supportsDocInjection: true,
144
+ commandSeparator: ':',
145
+ },
146
+ detection: { type: 'directory', path: '.claude' },
147
+ specialAdapter: 'doc-injection',
148
+ },
149
+ // TOML-based adapters (require special formatting - special adapter kept)
150
+ {
151
+ name: 'gemini',
152
+ displayName: 'Gemini CLI',
153
+ directory: '.gemini/commands/clavix',
154
+ fileExtension: '.toml',
155
+ filenamePattern: '{name}',
156
+ features: { ...DEFAULT_TOML_FEATURES },
157
+ detection: { type: 'directory', path: '.gemini' },
158
+ specialAdapter: 'toml',
159
+ rootDir: '.gemini',
160
+ },
161
+ {
162
+ name: 'qwen',
163
+ displayName: 'Qwen CLI',
164
+ directory: '.qwen/commands/clavix',
165
+ fileExtension: '.toml',
166
+ filenamePattern: '{name}',
167
+ features: { ...DEFAULT_TOML_FEATURES },
168
+ detection: { type: 'directory', path: '.qwen' },
169
+ specialAdapter: 'toml',
170
+ rootDir: '.qwen',
171
+ },
172
+ {
173
+ name: 'llxprt',
174
+ displayName: 'LLXpert',
175
+ directory: '.llxprt/commands/clavix',
176
+ fileExtension: '.toml',
177
+ filenamePattern: '{name}',
178
+ features: { ...DEFAULT_TOML_FEATURES },
179
+ detection: { type: 'directory', path: '.llxprt' },
180
+ specialAdapter: 'toml',
181
+ rootDir: '.llxprt',
182
+ },
183
+ ];
184
+ /**
185
+ * Get adapter configuration by name
186
+ */
187
+ export function getAdapterConfig(name) {
188
+ return ADAPTER_CONFIGS.find((config) => config.name === name);
189
+ }
190
+ /**
191
+ * Get all adapter configurations
192
+ */
193
+ export function getAllAdapterConfigs() {
194
+ return [...ADAPTER_CONFIGS];
195
+ }
196
+ /**
197
+ * Get adapters that require special handling
198
+ */
199
+ export function getSpecialAdapters() {
200
+ return ADAPTER_CONFIGS.filter((config) => config.specialAdapter !== undefined);
201
+ }
202
+ /**
203
+ * Get simple adapters (can use UniversalAdapter)
204
+ */
205
+ export function getSimpleAdapters() {
206
+ return ADAPTER_CONFIGS.filter((config) => config.specialAdapter === undefined);
207
+ }
208
+ //# sourceMappingURL=adapter-registry.js.map
@@ -52,6 +52,7 @@ export declare abstract class BaseAdapter implements AgentAdapter {
52
52
  injectDocumentation(_blocks: ManagedBlock[]): Promise<void>;
53
53
  /**
54
54
  * Escape special regex characters
55
+ * @deprecated Use escapeRegex from utils/string-utils.js directly
55
56
  */
56
57
  protected escapeRegex(str: string): string;
57
58
  }
@@ -1,6 +1,7 @@
1
1
  import * as path from 'path';
2
2
  import { FileSystem } from '../../utils/file-system.js';
3
3
  import { IntegrationError } from '../../types/errors.js';
4
+ import { escapeRegex } from '../../utils/string-utils.js';
4
5
  /**
5
6
  * Base adapter class with shared logic for all integrations
6
7
  * Ensures consistency and reduces code duplication
@@ -135,9 +136,10 @@ export class BaseAdapter {
135
136
  }
136
137
  /**
137
138
  * Escape special regex characters
139
+ * @deprecated Use escapeRegex from utils/string-utils.js directly
138
140
  */
139
141
  escapeRegex(str) {
140
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
142
+ return escapeRegex(str);
141
143
  }
142
144
  }
143
145
  //# sourceMappingURL=base-adapter.js.map
@@ -0,0 +1,49 @@
1
+ /**
2
+ * UniversalAdapter - Config-driven adapter implementation
3
+ *
4
+ * This adapter can handle any simple adapter by accepting configuration
5
+ * at construction time. It provides the same interface as dedicated
6
+ * adapter classes but derives all behavior from AdapterConfig.
7
+ *
8
+ * For adapters requiring custom logic (TOML formatting, doc injection),
9
+ * dedicated adapter classes should be used instead.
10
+ *
11
+ * @since v5.3.0
12
+ */
13
+ import { BaseAdapter } from './base-adapter.js';
14
+ import { AdapterConfig } from '../../types/adapter-config.js';
15
+ import { IntegrationFeatures } from '../../types/agent.js';
16
+ export declare class UniversalAdapter extends BaseAdapter {
17
+ private config;
18
+ constructor(config: AdapterConfig);
19
+ get name(): string;
20
+ get displayName(): string;
21
+ get directory(): string;
22
+ get fileExtension(): string;
23
+ /**
24
+ * Get integration features for command transformation
25
+ */
26
+ getIntegrationFeatures(): IntegrationFeatures;
27
+ /**
28
+ * Generate the target filename based on config pattern
29
+ */
30
+ getTargetFilename(commandName: string): string;
31
+ /**
32
+ * Get full command path
33
+ */
34
+ getCommandPath(): string;
35
+ /**
36
+ * Check if this adapter's project environment is detected
37
+ * Required by BaseAdapter abstract class
38
+ */
39
+ detectProject(): Promise<boolean>;
40
+ /**
41
+ * Check if this adapter supports subdirectories
42
+ */
43
+ supportsSubdirectories(): boolean;
44
+ /**
45
+ * Check if this adapter supports frontmatter
46
+ */
47
+ supportsFrontmatter(): boolean;
48
+ }
49
+ //# sourceMappingURL=universal-adapter.d.ts.map