clavix 4.7.0 → 4.8.1

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 (45) hide show
  1. package/dist/cli/commands/execute.js +29 -9
  2. package/dist/cli/commands/verify.d.ts +28 -0
  3. package/dist/cli/commands/verify.js +347 -0
  4. package/dist/core/adapters/amp-adapter.d.ts +3 -0
  5. package/dist/core/adapters/amp-adapter.js +1 -0
  6. package/dist/core/adapters/cline-adapter.d.ts +3 -0
  7. package/dist/core/adapters/cline-adapter.js +1 -0
  8. package/dist/core/adapters/codebuddy-adapter.d.ts +3 -0
  9. package/dist/core/adapters/codebuddy-adapter.js +1 -0
  10. package/dist/core/adapters/codex-adapter.d.ts +3 -0
  11. package/dist/core/adapters/codex-adapter.js +1 -0
  12. package/dist/core/adapters/cursor-adapter.d.ts +3 -0
  13. package/dist/core/adapters/cursor-adapter.js +1 -0
  14. package/dist/core/adapters/droid-adapter.d.ts +3 -0
  15. package/dist/core/adapters/droid-adapter.js +1 -0
  16. package/dist/core/adapters/instructions-generator.js +9 -2
  17. package/dist/core/adapters/kilocode-adapter.d.ts +3 -0
  18. package/dist/core/adapters/kilocode-adapter.js +1 -0
  19. package/dist/core/adapters/opencode-adapter.d.ts +3 -0
  20. package/dist/core/adapters/opencode-adapter.js +1 -0
  21. package/dist/core/adapters/roocode-adapter.d.ts +3 -0
  22. package/dist/core/adapters/roocode-adapter.js +1 -0
  23. package/dist/core/adapters/windsurf-adapter.d.ts +3 -0
  24. package/dist/core/adapters/windsurf-adapter.js +1 -0
  25. package/dist/core/basic-checklist-generator.d.ts +35 -0
  26. package/dist/core/basic-checklist-generator.js +344 -0
  27. package/dist/core/checklist-parser.d.ts +48 -0
  28. package/dist/core/checklist-parser.js +238 -0
  29. package/dist/core/command-transformer.d.ts +55 -0
  30. package/dist/core/command-transformer.js +65 -0
  31. package/dist/core/prompt-manager.d.ts +7 -0
  32. package/dist/core/prompt-manager.js +47 -22
  33. package/dist/core/verification-hooks.d.ts +67 -0
  34. package/dist/core/verification-hooks.js +309 -0
  35. package/dist/core/verification-manager.d.ts +106 -0
  36. package/dist/core/verification-manager.js +422 -0
  37. package/dist/templates/slash-commands/_canonical/execute.md +72 -1
  38. package/dist/templates/slash-commands/_canonical/verify.md +292 -0
  39. package/dist/templates/slash-commands/_components/agent-protocols/verification-methods.md +184 -0
  40. package/dist/types/agent.d.ts +4 -0
  41. package/dist/types/verification.d.ts +204 -0
  42. package/dist/types/verification.js +8 -0
  43. package/dist/utils/template-loader.d.ts +1 -1
  44. package/dist/utils/template-loader.js +5 -1
  45. package/package.json +1 -1
@@ -2,6 +2,7 @@ import { Command, Flags } from '@oclif/core';
2
2
  import chalk from 'chalk';
3
3
  import inquirer from 'inquirer';
4
4
  import { PromptManager } from '../../core/prompt-manager.js';
5
+ import { ChecklistParser } from '../../core/checklist-parser.js';
5
6
  export default class Execute extends Command {
6
7
  static description = 'Execute a saved prompt from fast/deep optimization';
7
8
  static examples = [
@@ -45,7 +46,7 @@ export default class Execute extends Command {
45
46
  let selectedPrompt = null;
46
47
  // Execute specific prompt by ID
47
48
  if (flags.id) {
48
- selectedPrompt = allPrompts.find(p => p.id === flags.id) || null;
49
+ selectedPrompt = allPrompts.find((p) => p.id === flags.id) || null;
49
50
  if (!selectedPrompt) {
50
51
  console.log(chalk.red(`\nāœ— Prompt not found: ${flags.id}\n`));
51
52
  console.log(chalk.cyan('Run clavix prompts list to see available prompts'));
@@ -58,10 +59,10 @@ export default class Execute extends Command {
58
59
  let filtered = allPrompts;
59
60
  // Apply source filter
60
61
  if (flags.fast && !flags.deep) {
61
- filtered = allPrompts.filter(p => p.source === 'fast');
62
+ filtered = allPrompts.filter((p) => p.source === 'fast');
62
63
  }
63
64
  else if (flags.deep && !flags.fast) {
64
- filtered = allPrompts.filter(p => p.source === 'deep');
65
+ filtered = allPrompts.filter((p) => p.source === 'deep');
65
66
  }
66
67
  if (filtered.length === 0) {
67
68
  const source = flags.fast ? 'fast' : flags.deep ? 'deep' : 'any';
@@ -89,7 +90,7 @@ export default class Execute extends Command {
89
90
  }
90
91
  async selectPromptInteractively(prompts) {
91
92
  console.log(chalk.bold.cyan('\nšŸ“‹ Available Prompts\n'));
92
- const choices = prompts.map(p => {
93
+ const choices = prompts.map((p) => {
93
94
  const status = p.executed ? chalk.green('āœ“') : chalk.gray('ā—‹');
94
95
  const age = p.ageInDays === 0 ? 'today' : `${p.ageInDays}d ago`;
95
96
  const ageColor = (p.ageInDays || 0) > 30 ? chalk.red : (p.ageInDays || 0) > 7 ? chalk.yellow : chalk.gray;
@@ -108,7 +109,7 @@ export default class Execute extends Command {
108
109
  pageSize: 15,
109
110
  },
110
111
  ]);
111
- return prompts.find(p => p.id === promptId) || null;
112
+ return prompts.find((p) => p.id === promptId) || null;
112
113
  }
113
114
  async executePrompt(prompt, manager) {
114
115
  const promptData = await manager.loadPrompt(prompt.id);
@@ -126,20 +127,39 @@ export default class Execute extends Command {
126
127
  console.log(promptData.content);
127
128
  console.log(chalk.dim('─'.repeat(80)));
128
129
  console.log();
130
+ // Parse and display checklist summary
131
+ const checklistParser = new ChecklistParser();
132
+ const checklist = checklistParser.parse(promptData.content);
133
+ if (checklist.hasChecklist) {
134
+ const summary = checklistParser.getSummary(checklist);
135
+ console.log(chalk.bold.cyan('šŸ“‹ Checklist Summary:'));
136
+ console.log(chalk.gray(` Validation items: ${summary.validation}`));
137
+ console.log(chalk.gray(` Edge cases: ${summary.edgeCases}`));
138
+ console.log(chalk.gray(` Risks: ${summary.risks}`));
139
+ console.log(chalk.gray(` Total: ${checklist.totalItems} items to verify`));
140
+ console.log();
141
+ }
129
142
  // Mark as executed
130
143
  if (!prompt.executed) {
131
144
  await manager.markExecuted(prompt.id);
132
145
  console.log(chalk.green('āœ“ Prompt marked as executed\n'));
133
146
  }
147
+ // Display REQUIRED verification notice
148
+ console.log(chalk.bgYellow.black(' āš ļø VERIFICATION REQUIRED '));
149
+ console.log(chalk.yellow('After implementing, run verification:'));
150
+ console.log(chalk.cyan(` clavix verify --id ${prompt.id}`));
151
+ console.log(chalk.cyan(' Or: /clavix:verify'));
152
+ console.log();
134
153
  // Suggest cleanup
135
154
  const stats = await manager.getStorageStats();
136
155
  if (stats.executedPrompts >= 5) {
137
- console.log(chalk.yellow(`šŸ’” Cleanup suggestion:`));
138
- console.log(chalk.yellow(` You have ${stats.executedPrompts} executed prompts.`));
139
- console.log(chalk.yellow(` Run /clavix:prompts clear to clean up.`));
156
+ console.log(chalk.gray(`šŸ’” You have ${stats.executedPrompts} executed prompts.`));
157
+ console.log(chalk.gray(` Clean up after verification: clavix prompts clear --executed`));
140
158
  console.log();
141
159
  }
142
- console.log(chalk.cyan('šŸ’” Next: Implement the requirements described above'));
160
+ console.log(chalk.cyan('šŸ’” Next steps:'));
161
+ console.log(chalk.cyan(' 1. Implement the requirements described above'));
162
+ console.log(chalk.cyan(' 2. Run: clavix verify --latest'));
143
163
  console.log();
144
164
  }
145
165
  }
@@ -0,0 +1,28 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Verify extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ latest: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ fast: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ deep: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ id: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ status: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ 'retry-failed': import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ export: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ 'run-hooks': import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ };
15
+ private promptManager;
16
+ private verificationManager;
17
+ private checklistParser;
18
+ private basicChecklistGenerator;
19
+ private intentDetector;
20
+ run(): Promise<void>;
21
+ private selectPromptInteractively;
22
+ private showStatus;
23
+ private exportReport;
24
+ private runVerification;
25
+ private verifyItemInteractively;
26
+ private formatStatus;
27
+ }
28
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1,347 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import inquirer from 'inquirer';
4
+ import { PromptManager } from '../../core/prompt-manager.js';
5
+ import { VerificationManager } from '../../core/verification-manager.js';
6
+ import { ChecklistParser } from '../../core/checklist-parser.js';
7
+ import { BasicChecklistGenerator } from '../../core/basic-checklist-generator.js';
8
+ import { IntentDetector } from '../../core/intelligence/intent-detector.js';
9
+ export default class Verify extends Command {
10
+ static description = 'Verify implementation against checklist from deep/fast mode';
11
+ static examples = [
12
+ '<%= config.bin %> <%= command.id %> --latest',
13
+ '<%= config.bin %> <%= command.id %> --latest --deep',
14
+ '<%= config.bin %> <%= command.id %> --id deep-20250117-143022-a3f2',
15
+ '<%= config.bin %> <%= command.id %> --status',
16
+ '<%= config.bin %> <%= command.id %> --retry-failed',
17
+ ];
18
+ static flags = {
19
+ latest: Flags.boolean({
20
+ description: 'Verify latest executed prompt',
21
+ default: false,
22
+ }),
23
+ fast: Flags.boolean({
24
+ description: 'Filter to fast prompts only (use with --latest)',
25
+ default: false,
26
+ }),
27
+ deep: Flags.boolean({
28
+ description: 'Filter to deep prompts only (use with --latest)',
29
+ default: false,
30
+ }),
31
+ id: Flags.string({
32
+ description: 'Verify specific prompt by ID',
33
+ }),
34
+ status: Flags.boolean({
35
+ description: 'Show verification status only',
36
+ default: false,
37
+ }),
38
+ 'retry-failed': Flags.boolean({
39
+ description: 'Re-run only failed items',
40
+ default: false,
41
+ }),
42
+ export: Flags.string({
43
+ description: 'Export report format',
44
+ options: ['markdown', 'json'],
45
+ }),
46
+ 'run-hooks': Flags.boolean({
47
+ description: 'Run automated hooks during verification',
48
+ default: true,
49
+ }),
50
+ };
51
+ promptManager;
52
+ verificationManager;
53
+ checklistParser;
54
+ basicChecklistGenerator;
55
+ intentDetector;
56
+ async run() {
57
+ const { flags } = await this.parse(Verify);
58
+ this.promptManager = new PromptManager();
59
+ this.verificationManager = new VerificationManager();
60
+ this.checklistParser = new ChecklistParser();
61
+ this.basicChecklistGenerator = new BasicChecklistGenerator();
62
+ this.intentDetector = new IntentDetector();
63
+ try {
64
+ // Get all prompts
65
+ const allPrompts = await this.promptManager.listPrompts();
66
+ if (allPrompts.length === 0) {
67
+ console.log(chalk.yellow('\nāš ļø No prompts found\n'));
68
+ console.log(chalk.cyan('Generate an optimized prompt first:'));
69
+ console.log(chalk.cyan(' /clavix:fast "your requirement"'));
70
+ console.log(chalk.cyan(' /clavix:deep "your requirement"'));
71
+ console.log();
72
+ return;
73
+ }
74
+ let selectedPrompt = null;
75
+ // Select prompt by ID
76
+ if (flags.id) {
77
+ selectedPrompt = allPrompts.find((p) => p.id === flags.id) || null;
78
+ if (!selectedPrompt) {
79
+ console.log(chalk.red(`\nāœ— Prompt not found: ${flags.id}\n`));
80
+ console.log(chalk.cyan('Run clavix prompts list to see available prompts'));
81
+ console.log();
82
+ return;
83
+ }
84
+ }
85
+ // Auto-select latest with optional filtering
86
+ else if (flags.latest) {
87
+ let filtered = allPrompts;
88
+ // Filter by source
89
+ if (flags.fast && !flags.deep) {
90
+ filtered = allPrompts.filter((p) => p.source === 'fast');
91
+ }
92
+ else if (flags.deep && !flags.fast) {
93
+ filtered = allPrompts.filter((p) => p.source === 'deep');
94
+ }
95
+ // Filter to executed prompts preferably
96
+ const executedFiltered = filtered.filter((p) => p.executed);
97
+ if (executedFiltered.length > 0) {
98
+ filtered = executedFiltered;
99
+ }
100
+ if (filtered.length === 0) {
101
+ const source = flags.fast ? 'fast' : flags.deep ? 'deep' : 'any';
102
+ console.log(chalk.yellow(`\nāš ļø No ${source} prompts found\n`));
103
+ return;
104
+ }
105
+ selectedPrompt = filtered[0];
106
+ }
107
+ // Interactive selection
108
+ else {
109
+ selectedPrompt = await this.selectPromptInteractively(allPrompts);
110
+ if (!selectedPrompt)
111
+ return;
112
+ }
113
+ // Handle status-only flag
114
+ if (flags.status) {
115
+ await this.showStatus(selectedPrompt);
116
+ return;
117
+ }
118
+ // Handle export flag
119
+ if (flags.export) {
120
+ await this.exportReport(selectedPrompt, flags.export);
121
+ return;
122
+ }
123
+ // Run verification
124
+ await this.runVerification(selectedPrompt, {
125
+ retryFailed: flags['retry-failed'],
126
+ runHooks: flags['run-hooks'],
127
+ });
128
+ }
129
+ catch (error) {
130
+ console.log(chalk.red(`\nāœ— Error: ${error}\n`));
131
+ }
132
+ }
133
+ async selectPromptInteractively(prompts) {
134
+ console.log(chalk.bold.cyan('\nšŸ“‹ Select Prompt to Verify\n'));
135
+ const choices = prompts.map((p) => {
136
+ const executed = p.executed ? chalk.green('āœ“') : chalk.gray('ā—‹');
137
+ const age = p.ageInDays === 0 ? 'today' : `${p.ageInDays}d ago`;
138
+ const ageColor = (p.ageInDays || 0) > 30 ? chalk.red : (p.ageInDays || 0) > 7 ? chalk.yellow : chalk.gray;
139
+ return {
140
+ name: `${executed} [${p.source}] ${p.originalPrompt.substring(0, 50)}... ${ageColor(`(${age})`)}`,
141
+ value: p.id,
142
+ short: p.id,
143
+ };
144
+ });
145
+ const { promptId } = await inquirer.prompt([
146
+ {
147
+ type: 'list',
148
+ name: 'promptId',
149
+ message: 'Select a prompt to verify:',
150
+ choices,
151
+ pageSize: 15,
152
+ },
153
+ ]);
154
+ return prompts.find((p) => p.id === promptId) || null;
155
+ }
156
+ async showStatus(prompt) {
157
+ console.log(chalk.bold.cyan(`\nšŸ” Verification Status: ${prompt.id}\n`));
158
+ const status = await this.verificationManager.getVerificationStatus(prompt.id);
159
+ if (!status.hasReport) {
160
+ console.log(chalk.yellow('No verification report found.'));
161
+ console.log(chalk.cyan('\nRun: clavix verify --latest'));
162
+ console.log();
163
+ return;
164
+ }
165
+ console.log(chalk.gray(`Status: ${this.formatStatus(status.status)}`));
166
+ console.log();
167
+ if (status.summary) {
168
+ console.log(chalk.bold('Summary:'));
169
+ console.log(` Total: ${status.summary.total} items`);
170
+ console.log(` Passed: ${chalk.green(status.summary.passed)} (${status.summary.coveragePercent}%)`);
171
+ console.log(` Failed: ${chalk.red(status.summary.failed)}`);
172
+ console.log(` Skipped: ${chalk.gray(status.summary.skipped)}`);
173
+ console.log();
174
+ }
175
+ }
176
+ async exportReport(prompt, format) {
177
+ const report = await this.verificationManager.loadReport(prompt.id);
178
+ if (!report) {
179
+ console.log(chalk.yellow('No verification report found.'));
180
+ return;
181
+ }
182
+ if (format === 'json') {
183
+ console.log(JSON.stringify(report, null, 2));
184
+ }
185
+ else if (format === 'markdown') {
186
+ console.log(this.verificationManager.formatReportForDisplay(report));
187
+ }
188
+ }
189
+ async runVerification(prompt, options) {
190
+ console.log(chalk.bold.cyan(`\nšŸ” Verifying: ${prompt.id}\n`));
191
+ console.log(chalk.gray(`Source: ${prompt.source}`));
192
+ console.log(chalk.gray(`Created: ${new Date(prompt.timestamp).toLocaleDateString()}`));
193
+ console.log();
194
+ // Load prompt content
195
+ const promptData = await this.promptManager.loadPrompt(prompt.id);
196
+ if (!promptData) {
197
+ console.log(chalk.red('Could not load prompt content.'));
198
+ return;
199
+ }
200
+ // Parse checklist from prompt
201
+ let checklist = this.checklistParser.parse(promptData.content);
202
+ // Handle fast mode - generate basic checklist if none exists
203
+ if (!checklist.hasChecklist && prompt.source === 'fast') {
204
+ console.log(chalk.yellow('āš ļø No checklist found (fast mode prompt)'));
205
+ console.log(chalk.cyan('Generating basic checklist based on intent...\n'));
206
+ // Detect intent from original prompt
207
+ const intent = this.intentDetector.analyze(prompt.originalPrompt);
208
+ checklist = this.basicChecklistGenerator.generateFromPrompt(prompt.originalPrompt, intent.primaryIntent);
209
+ console.log(chalk.gray(`Intent: ${intent.primaryIntent} (${intent.confidence}% confidence)`));
210
+ console.log(chalk.gray(`Generated ${checklist.totalItems} checklist items\n`));
211
+ console.log(chalk.yellow('šŸ’” For comprehensive checklists, use /clavix:deep\n'));
212
+ }
213
+ if (!checklist.hasChecklist) {
214
+ console.log(chalk.yellow('No checklist items to verify.'));
215
+ return;
216
+ }
217
+ // Initialize or load existing report
218
+ let report = await this.verificationManager.loadReport(prompt.id);
219
+ if (!report) {
220
+ report = await this.verificationManager.initializeVerification(prompt.id);
221
+ // Update with parsed checklist if from fast mode
222
+ if (prompt.source === 'fast') {
223
+ report.items = [...checklist.validationItems, ...checklist.edgeCases, ...checklist.risks];
224
+ report.results = report.items.map((item) => ({
225
+ itemId: item.id,
226
+ status: 'pending',
227
+ method: item.verificationType === 'automated' ? 'automated' : 'manual',
228
+ confidence: 'low',
229
+ verifiedAt: '',
230
+ }));
231
+ await this.verificationManager.saveReport(report);
232
+ }
233
+ }
234
+ // Run automated hooks if requested
235
+ if (options.runHooks) {
236
+ console.log(chalk.cyan('Running automated verification hooks...\n'));
237
+ report = await this.verificationManager.runAutomatedVerification(prompt.id);
238
+ // Display hook results
239
+ const automatedResults = report.results.filter((r) => r.method === 'automated' && r.status !== 'pending');
240
+ for (const result of automatedResults) {
241
+ const item = report.items.find((i) => i.id === result.itemId);
242
+ if (item) {
243
+ const icon = result.status === 'passed' ? chalk.green('āœ“') : chalk.red('āœ—');
244
+ console.log(`${icon} [automated] ${item.content}`);
245
+ if (result.evidence) {
246
+ console.log(chalk.gray(` Evidence: ${result.evidence.substring(0, 60)}...`));
247
+ }
248
+ }
249
+ }
250
+ if (automatedResults.length > 0) {
251
+ console.log();
252
+ }
253
+ }
254
+ // Get pending items for manual verification
255
+ const pendingItems = this.verificationManager.getPendingItems(report);
256
+ if (pendingItems.length > 0) {
257
+ console.log(chalk.cyan(`Manual verification needed for ${pendingItems.length} items:\n`));
258
+ for (const item of pendingItems) {
259
+ report = await this.verifyItemInteractively(report, item);
260
+ }
261
+ }
262
+ // Show final report
263
+ console.log();
264
+ console.log(this.verificationManager.formatReportForDisplay(report));
265
+ // Mark prompt as verified if complete
266
+ if (this.verificationManager.isComplete(report)) {
267
+ console.log(chalk.green('\nāœ“ Verification complete!\n'));
268
+ }
269
+ else if (this.verificationManager.requiresAttention(report)) {
270
+ console.log(chalk.yellow('\nāš ļø Some items require attention.\n'));
271
+ console.log(chalk.cyan('Fix issues and re-run: clavix verify --retry-failed --id ' + prompt.id));
272
+ console.log();
273
+ }
274
+ }
275
+ async verifyItemInteractively(report, item) {
276
+ console.log(chalk.bold(`\nšŸ“‹ ${item.content}`));
277
+ if (item.group) {
278
+ console.log(chalk.gray(` Category: ${item.group}`));
279
+ }
280
+ console.log();
281
+ const { status } = await inquirer.prompt([
282
+ {
283
+ type: 'list',
284
+ name: 'status',
285
+ message: 'Verification status:',
286
+ choices: [
287
+ { name: 'āœ“ Passed - Item is verified', value: 'passed' },
288
+ { name: 'āœ— Failed - Item is not covered', value: 'failed' },
289
+ { name: 'ā­ļø Skip - Will verify later', value: 'skipped' },
290
+ { name: 'āž– N/A - Does not apply', value: 'not-applicable' },
291
+ ],
292
+ },
293
+ ]);
294
+ let evidence;
295
+ let reason;
296
+ if (status === 'passed') {
297
+ const { evidenceInput } = await inquirer.prompt([
298
+ {
299
+ type: 'input',
300
+ name: 'evidenceInput',
301
+ message: 'Evidence (optional):',
302
+ },
303
+ ]);
304
+ evidence = evidenceInput || undefined;
305
+ }
306
+ else if (status === 'failed') {
307
+ const { reasonInput } = await inquirer.prompt([
308
+ {
309
+ type: 'input',
310
+ name: 'reasonInput',
311
+ message: 'Why is it not covered?',
312
+ },
313
+ ]);
314
+ reason = reasonInput || 'Not specified';
315
+ }
316
+ else if (status === 'skipped') {
317
+ const { reasonInput } = await inquirer.prompt([
318
+ {
319
+ type: 'input',
320
+ name: 'reasonInput',
321
+ message: 'Reason for skipping:',
322
+ },
323
+ ]);
324
+ reason = reasonInput || 'Will verify later';
325
+ }
326
+ return this.verificationManager.markItemVerified(report.promptId, item.id, status, {
327
+ evidence,
328
+ reason,
329
+ confidence: 'medium',
330
+ method: 'manual',
331
+ });
332
+ }
333
+ formatStatus(status) {
334
+ switch (status) {
335
+ case 'completed':
336
+ return chalk.green('Completed');
337
+ case 'in-progress':
338
+ return chalk.yellow('In Progress');
339
+ case 'requires-attention':
340
+ return chalk.red('Requires Attention');
341
+ case 'pending':
342
+ default:
343
+ return chalk.gray('Pending');
344
+ }
345
+ }
346
+ }
347
+ //# sourceMappingURL=verify.js.map
@@ -13,6 +13,9 @@ export declare class AmpAdapter extends BaseAdapter {
13
13
  supportsSubdirectories: boolean;
14
14
  supportsFrontmatter: boolean;
15
15
  supportsExecutableCommands: boolean;
16
+ commandFormat: {
17
+ separator: "-";
18
+ };
16
19
  };
17
20
  /**
18
21
  * Detect if Amp is available in the project
@@ -14,6 +14,7 @@ export class AmpAdapter extends BaseAdapter {
14
14
  supportsSubdirectories: false,
15
15
  supportsFrontmatter: false,
16
16
  supportsExecutableCommands: true,
17
+ commandFormat: { separator: '-' },
17
18
  };
18
19
  /**
19
20
  * Detect if Amp is available in the project
@@ -19,6 +19,9 @@ export declare class ClineAdapter extends BaseAdapter {
19
19
  readonly features: {
20
20
  supportsSubdirectories: boolean;
21
21
  supportsFrontmatter: boolean;
22
+ commandFormat: {
23
+ separator: "-";
24
+ };
22
25
  };
23
26
  /**
24
27
  * Detect if Cline is available in the project
@@ -20,6 +20,7 @@ export class ClineAdapter extends BaseAdapter {
20
20
  features = {
21
21
  supportsSubdirectories: false,
22
22
  supportsFrontmatter: false,
23
+ commandFormat: { separator: '-' },
23
24
  };
24
25
  /**
25
26
  * Detect if Cline is available in the project
@@ -14,6 +14,9 @@ export declare class CodeBuddyAdapter extends BaseAdapter {
14
14
  supportsFrontmatter: boolean;
15
15
  argumentPlaceholder: string;
16
16
  frontmatterFields: string[];
17
+ commandFormat: {
18
+ separator: "-";
19
+ };
17
20
  };
18
21
  detectProject(): Promise<boolean>;
19
22
  getCommandPath(): string;
@@ -16,6 +16,7 @@ export class CodeBuddyAdapter extends BaseAdapter {
16
16
  supportsFrontmatter: true,
17
17
  argumentPlaceholder: '$1',
18
18
  frontmatterFields: ['description', 'argument-hint'],
19
+ commandFormat: { separator: '-' },
19
20
  };
20
21
  async detectProject() {
21
22
  if (await FileSystem.exists('.codebuddy')) {
@@ -14,6 +14,9 @@ export declare class CodexAdapter extends BaseAdapter {
14
14
  supportsFrontmatter: boolean;
15
15
  argumentPlaceholder: string;
16
16
  frontmatterFields: string[];
17
+ commandFormat: {
18
+ separator: "-";
19
+ };
17
20
  };
18
21
  detectProject(): Promise<boolean>;
19
22
  getCommandPath(): string;
@@ -16,6 +16,7 @@ export class CodexAdapter extends BaseAdapter {
16
16
  supportsFrontmatter: true,
17
17
  argumentPlaceholder: '$ARGUMENTS',
18
18
  frontmatterFields: ['description', 'argument-hint'],
19
+ commandFormat: { separator: '-' },
19
20
  };
20
21
  async detectProject() {
21
22
  const codexDir = path.join(this.getHomeDir(), '.codex');
@@ -11,6 +11,9 @@ export declare class CursorAdapter extends BaseAdapter {
11
11
  readonly features: {
12
12
  supportsSubdirectories: boolean;
13
13
  supportsFrontmatter: boolean;
14
+ commandFormat: {
15
+ separator: "-";
16
+ };
14
17
  };
15
18
  /**
16
19
  * Detect if Cursor is available in the project
@@ -12,6 +12,7 @@ export class CursorAdapter extends BaseAdapter {
12
12
  features = {
13
13
  supportsSubdirectories: false,
14
14
  supportsFrontmatter: false,
15
+ commandFormat: { separator: '-' },
15
16
  };
16
17
  /**
17
18
  * Detect if Cursor is available in the project
@@ -15,6 +15,9 @@ export declare class DroidAdapter extends BaseAdapter {
15
15
  supportsFrontmatter: boolean;
16
16
  frontmatterFields: string[];
17
17
  argumentPlaceholder: string;
18
+ commandFormat: {
19
+ separator: "-";
20
+ };
18
21
  };
19
22
  /**
20
23
  * Detect if Droid CLI is available in the project
@@ -15,6 +15,7 @@ export class DroidAdapter extends BaseAdapter {
15
15
  supportsFrontmatter: true,
16
16
  frontmatterFields: ['description', 'argument-hint'],
17
17
  argumentPlaceholder: '$ARGUMENTS',
18
+ commandFormat: { separator: '-' },
18
19
  };
19
20
  /**
20
21
  * Detect if Droid CLI is available in the project
@@ -1,5 +1,6 @@
1
1
  import { FileSystem } from '../../utils/file-system.js';
2
2
  import { TemplateAssembler } from '../template-assembler.js';
3
+ import { CommandTransformer } from '../command-transformer.js';
3
4
  import * as path from 'path';
4
5
  import { fileURLToPath } from 'url';
5
6
  import { dirname } from 'path';
@@ -79,17 +80,23 @@ export class InstructionsGenerator {
79
80
  // Copy all .md files from canonical, resolving includes
80
81
  const entries = await FileSystem.readdir(canonicalPath, { withFileTypes: true });
81
82
  const mdFiles = entries.filter((f) => f.isFile() && f.name.endsWith('.md'));
83
+ // v4.8.1: Generic integrations use hyphen format for slash commands
84
+ const genericFeatures = { commandFormat: { separator: '-' } };
82
85
  for (const file of mdFiles) {
83
86
  const destPath = path.join(workflowsTarget, file.name);
84
87
  try {
85
88
  // v4.5: Use TemplateAssembler to resolve {{INCLUDE:}} markers
86
89
  const result = await assembler.assembleTemplate(file.name);
87
- await FileSystem.writeFileAtomic(destPath, result.content);
90
+ // v4.8.1: Transform command references to hyphen format for generic integrations
91
+ const transformedContent = CommandTransformer.transform(result.content, genericFeatures);
92
+ await FileSystem.writeFileAtomic(destPath, transformedContent);
88
93
  }
89
94
  catch {
90
95
  // Fallback: copy without include resolution if assembly fails
91
96
  const srcPath = path.join(canonicalPath, file.name);
92
- const content = await FileSystem.readFile(srcPath);
97
+ let content = await FileSystem.readFile(srcPath);
98
+ // v4.8.1: Still transform command references in fallback path
99
+ content = CommandTransformer.transform(content, genericFeatures);
93
100
  await FileSystem.writeFileAtomic(destPath, content);
94
101
  }
95
102
  }
@@ -19,6 +19,9 @@ export declare class KilocodeAdapter extends BaseAdapter {
19
19
  readonly features: {
20
20
  supportsSubdirectories: boolean;
21
21
  supportsFrontmatter: boolean;
22
+ commandFormat: {
23
+ separator: "-";
24
+ };
22
25
  };
23
26
  /**
24
27
  * Detect if Kilocode is available in the project
@@ -20,6 +20,7 @@ export class KilocodeAdapter extends BaseAdapter {
20
20
  features = {
21
21
  supportsSubdirectories: false,
22
22
  supportsFrontmatter: false,
23
+ commandFormat: { separator: '-' },
23
24
  };
24
25
  /**
25
26
  * Detect if Kilocode is available in the project
@@ -15,6 +15,9 @@ export declare class OpenCodeAdapter extends BaseAdapter {
15
15
  supportsFrontmatter: boolean;
16
16
  frontmatterFields: string[];
17
17
  argumentPlaceholder: string;
18
+ commandFormat: {
19
+ separator: "-";
20
+ };
18
21
  };
19
22
  /**
20
23
  * Detect if OpenCode is available in the project
@@ -15,6 +15,7 @@ export class OpenCodeAdapter extends BaseAdapter {
15
15
  supportsFrontmatter: true,
16
16
  frontmatterFields: ['description', 'agent', 'model'],
17
17
  argumentPlaceholder: '$ARGUMENTS',
18
+ commandFormat: { separator: '-' },
18
19
  };
19
20
  /**
20
21
  * Detect if OpenCode is available in the project