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
@@ -1,447 +0,0 @@
1
- import { Command, Args } from '@oclif/core';
2
- import chalk from 'chalk';
3
- import fs from 'fs-extra';
4
- import * as path from 'path';
5
- import inquirer from 'inquirer';
6
- import { AgentManager } from '../../core/agent-manager.js';
7
- import { DEFAULT_CONFIG, isLegacyConfig, migrateConfig } from '../../types/config.js';
8
- import { loadCommandTemplates } from '../../utils/template-loader.js';
9
- export default class Config extends Command {
10
- static description = 'Manage Clavix configuration';
11
- static examples = [
12
- '<%= config.bin %> <%= command.id %>',
13
- '<%= config.bin %> <%= command.id %> get integrations',
14
- '<%= config.bin %> <%= command.id %> set preferences.verboseLogging true',
15
- ];
16
- static args = {
17
- action: Args.string({
18
- description: 'Action to perform (get, set, edit, reset)',
19
- options: ['get', 'set', 'edit', 'reset'],
20
- required: false,
21
- }),
22
- key: Args.string({
23
- description: 'Configuration key',
24
- required: false,
25
- }),
26
- value: Args.string({
27
- description: 'Configuration value (for set action)',
28
- required: false,
29
- }),
30
- };
31
- static flags = {};
32
- async run() {
33
- const { args } = await this.parse(Config);
34
- const clavixDir = path.join(process.cwd(), '.clavix');
35
- const configPath = path.join(clavixDir, 'config.json');
36
- if (!fs.existsSync(clavixDir) || !fs.existsSync(configPath)) {
37
- this.error(chalk.red('No .clavix directory found.') +
38
- '\n' +
39
- chalk.yellow('Run ') +
40
- chalk.cyan('clavix init') +
41
- chalk.yellow(' to initialize Clavix in this project.'));
42
- }
43
- // If no action specified, show interactive menu
44
- if (!args.action) {
45
- await this.showInteractiveMenu(configPath);
46
- return;
47
- }
48
- switch (args.action) {
49
- case 'get':
50
- await this.getConfig(configPath, args.key);
51
- break;
52
- case 'set':
53
- await this.setConfig(configPath, args.key, args.value);
54
- break;
55
- case 'edit':
56
- await this.editConfig(configPath);
57
- break;
58
- case 'reset':
59
- await this.resetConfig(configPath);
60
- break;
61
- default:
62
- this.error(chalk.red(`Unknown action: ${args.action}`));
63
- }
64
- }
65
- async showInteractiveMenu(configPath) {
66
- let continueMenu = true;
67
- while (continueMenu) {
68
- const config = this.loadConfig(configPath);
69
- this.log(chalk.bold.cyan('\n⚙️ Clavix Configuration\n'));
70
- this.displayConfig(config);
71
- const { action } = await inquirer.prompt([
72
- {
73
- type: 'list',
74
- name: 'action',
75
- message: 'What would you like to do?',
76
- choices: [
77
- { name: 'View current configuration', value: 'view' },
78
- { name: 'Manage integrations (add/remove)', value: 'integrations' },
79
- { name: 'Edit preferences', value: 'edit-preferences' },
80
- { name: 'Reset to defaults', value: 'reset' },
81
- { name: 'Exit', value: 'exit' },
82
- ],
83
- },
84
- ]);
85
- switch (action) {
86
- case 'view':
87
- // Already displayed above
88
- break;
89
- case 'integrations':
90
- await this.manageIntegrations(config, configPath);
91
- break;
92
- case 'edit-preferences':
93
- await this.editPreferences(configPath, config);
94
- break;
95
- case 'reset':
96
- await this.resetConfig(configPath);
97
- break;
98
- case 'exit':
99
- continueMenu = false;
100
- break;
101
- }
102
- }
103
- }
104
- async manageIntegrations(config, configPath) {
105
- const agentManager = new AgentManager();
106
- while (true) {
107
- // Show current integrations
108
- this.log(chalk.cyan('\n📦 Current Integrations:'));
109
- if (config.integrations.length === 0) {
110
- this.log(chalk.gray(' (none configured)'));
111
- }
112
- else {
113
- for (const integrationName of config.integrations) {
114
- const adapter = agentManager.getAdapter(integrationName);
115
- const displayName = adapter?.displayName || integrationName;
116
- this.log(chalk.gray(` • ${displayName}`));
117
- }
118
- }
119
- // Submenu
120
- const { action } = await inquirer.prompt([
121
- {
122
- type: 'list',
123
- name: 'action',
124
- message: 'What would you like to do?',
125
- choices: [
126
- { name: 'Add integration', value: 'add' },
127
- { name: 'Remove integration', value: 'remove' },
128
- { name: 'Replace all integrations', value: 'replace' },
129
- { name: 'Back to main menu', value: 'back' },
130
- ],
131
- },
132
- ]);
133
- if (action === 'back')
134
- break;
135
- switch (action) {
136
- case 'add':
137
- await this.addIntegrations(config, configPath);
138
- break;
139
- case 'remove':
140
- await this.removeIntegrations(config, configPath);
141
- break;
142
- case 'replace':
143
- await this.replaceIntegrations(config, configPath);
144
- break;
145
- }
146
- // Reload config after modifications
147
- config = this.loadConfig(configPath);
148
- }
149
- }
150
- async addIntegrations(config, configPath) {
151
- const agentManager = new AgentManager();
152
- const allIntegrations = agentManager.getAdapters();
153
- // Show only non-selected providers
154
- const availableToAdd = allIntegrations.filter((a) => !config.integrations.includes(a.name));
155
- if (availableToAdd.length === 0) {
156
- this.log(chalk.yellow('\n✓ All integrations already added!'));
157
- return;
158
- }
159
- // Multi-select checkbox
160
- const { newIntegrations } = await inquirer.prompt([
161
- {
162
- type: 'checkbox',
163
- name: 'newIntegrations',
164
- message: 'Select providers to add:',
165
- choices: availableToAdd.map((adapter) => ({
166
- name: `${adapter.displayName} (${adapter.directory})`,
167
- value: adapter.name,
168
- })),
169
- },
170
- ]);
171
- if (newIntegrations.length === 0) {
172
- this.log(chalk.gray('No integrations selected'));
173
- return;
174
- }
175
- // Add to config
176
- config.integrations.push(...newIntegrations);
177
- this.saveConfig(configPath, config);
178
- this.log(chalk.gray('\n🔧 Generating commands for new integrations...'));
179
- // Generate commands for new integrations
180
- for (const integrationName of newIntegrations) {
181
- const adapter = agentManager.getAdapter(integrationName);
182
- if (!adapter)
183
- continue;
184
- const templates = await loadCommandTemplates(adapter);
185
- await adapter.generateCommands(templates);
186
- this.log(chalk.green(` ✓ Generated ${templates.length} command(s) for ${adapter.displayName}`));
187
- }
188
- this.log(chalk.green('\n✅ Integrations added successfully!'));
189
- }
190
- async removeIntegrations(config, configPath) {
191
- if (config.integrations.length === 0) {
192
- this.log(chalk.yellow('\n⚠ No integrations configured!'));
193
- return;
194
- }
195
- const agentManager = new AgentManager();
196
- // Multi-select from current integrations
197
- const { integrationsToRemove } = await inquirer.prompt([
198
- {
199
- type: 'checkbox',
200
- name: 'integrationsToRemove',
201
- message: 'Select providers to remove:',
202
- choices: config.integrations.map((name) => {
203
- const adapter = agentManager.getAdapter(name);
204
- return {
205
- name: `${adapter?.displayName || name} (${adapter?.directory || 'unknown'})`,
206
- value: name,
207
- };
208
- }),
209
- validate: (answer) => {
210
- if (answer.length === config.integrations.length) {
211
- return 'You must keep at least one integration. Use "Reset to defaults" to reconfigure completely.';
212
- }
213
- return true;
214
- },
215
- },
216
- ]);
217
- if (integrationsToRemove.length === 0) {
218
- this.log(chalk.gray('No integrations selected'));
219
- return;
220
- }
221
- // Confirm cleanup
222
- const { cleanup } = await inquirer.prompt([
223
- {
224
- type: 'confirm',
225
- name: 'cleanup',
226
- message: 'Remove command files for these integrations?',
227
- default: true,
228
- },
229
- ]);
230
- // Remove from config
231
- config.integrations = config.integrations.filter((p) => !integrationsToRemove.includes(p));
232
- this.saveConfig(configPath, config);
233
- // Clean up command files
234
- if (cleanup) {
235
- this.log(chalk.gray('\n🗑️ Cleaning up command files...'));
236
- for (const integrationName of integrationsToRemove) {
237
- const adapter = agentManager.getAdapter(integrationName);
238
- if (adapter) {
239
- const removed = await adapter.removeAllCommands();
240
- this.log(chalk.gray(` ✓ Removed ${removed} command(s) from ${adapter.displayName}`));
241
- }
242
- }
243
- }
244
- this.log(chalk.green('\n✅ Integrations removed successfully!'));
245
- }
246
- async replaceIntegrations(config, configPath) {
247
- const agentManager = new AgentManager();
248
- // Use shared provider selector
249
- const { selectIntegrations } = await import('../../utils/integration-selector.js');
250
- const newIntegrations = await selectIntegrations(agentManager, config.integrations);
251
- if (newIntegrations.length === 0) {
252
- this.log(chalk.gray('No integrations selected'));
253
- return;
254
- }
255
- // Find deselected integrations
256
- const deselected = config.integrations.filter((p) => !newIntegrations.includes(p));
257
- // Handle cleanup if providers were deselected
258
- if (deselected.length > 0) {
259
- this.log(chalk.yellow('\n⚠ Previously configured but not selected:'));
260
- for (const integrationName of deselected) {
261
- const adapter = agentManager.getAdapter(integrationName);
262
- const displayName = adapter?.displayName || integrationName;
263
- const directory = adapter?.directory || 'unknown';
264
- this.log(chalk.gray(` • ${displayName} (${directory})`));
265
- }
266
- const { cleanupAction } = await inquirer.prompt([
267
- {
268
- type: 'list',
269
- name: 'cleanupAction',
270
- message: 'What would you like to do with these integrations?',
271
- choices: [
272
- { name: 'Clean up (remove all command files)', value: 'cleanup' },
273
- { name: 'Skip (leave as-is)', value: 'skip' },
274
- ],
275
- },
276
- ]);
277
- if (cleanupAction === 'cleanup') {
278
- this.log(chalk.gray('\n🗑️ Cleaning up deselected integrations...'));
279
- for (const integrationName of deselected) {
280
- const adapter = agentManager.getAdapter(integrationName);
281
- if (adapter) {
282
- const removed = await adapter.removeAllCommands();
283
- this.log(chalk.gray(` ✓ Removed ${removed} command(s) from ${adapter.displayName}`));
284
- }
285
- }
286
- }
287
- }
288
- // Update config
289
- config.integrations = newIntegrations;
290
- this.saveConfig(configPath, config);
291
- // Prompt to run update
292
- const { runUpdate } = await inquirer.prompt([
293
- {
294
- type: 'confirm',
295
- name: 'runUpdate',
296
- message: 'Run update to regenerate all commands?',
297
- default: true,
298
- },
299
- ]);
300
- if (runUpdate) {
301
- this.log(chalk.gray('\n🔧 Regenerating commands for all integrations...\n'));
302
- const Update = (await import('./update.js')).default;
303
- await Update.run([]);
304
- }
305
- this.log(chalk.green('\n✅ Integrations replaced successfully!'));
306
- }
307
- async getConfig(configPath, key) {
308
- const config = this.loadConfig(configPath);
309
- if (!key) {
310
- this.log(chalk.bold.cyan('⚙️ Current Configuration\n'));
311
- this.displayConfig(config);
312
- return;
313
- }
314
- const value = this.getNestedValue(config, key);
315
- if (value === undefined) {
316
- this.error(chalk.red(`Configuration key "${key}" not found`));
317
- }
318
- this.log(chalk.cyan(key) + chalk.gray(': ') + JSON.stringify(value, null, 2));
319
- }
320
- async setConfig(configPath, key, value) {
321
- if (!key || value === undefined) {
322
- this.error('Usage: clavix config set <key> <value>');
323
- }
324
- const config = this.loadConfig(configPath);
325
- // Parse value as JSON if possible
326
- let parsedValue;
327
- try {
328
- parsedValue = JSON.parse(value);
329
- }
330
- catch {
331
- parsedValue = value;
332
- }
333
- this.setNestedValue(config, key, parsedValue);
334
- this.saveConfig(configPath, config);
335
- this.log(chalk.green(`✅ Set ${chalk.cyan(key)} to ${JSON.stringify(parsedValue)}`));
336
- }
337
- async editConfig(configPath) {
338
- const config = this.loadConfig(configPath);
339
- await this.editPreferences(configPath, config);
340
- }
341
- async resetConfig(configPath) {
342
- const { confirm } = await inquirer.prompt([
343
- {
344
- type: 'confirm',
345
- name: 'confirm',
346
- message: 'Are you sure you want to reset configuration to defaults?',
347
- default: false,
348
- },
349
- ]);
350
- if (!confirm) {
351
- this.log(chalk.gray('Cancelled'));
352
- return;
353
- }
354
- const config = this.loadConfig(configPath);
355
- const defaultConfig = {
356
- ...DEFAULT_CONFIG,
357
- providers: config.integrations, // Keep existing integrations
358
- };
359
- this.saveConfig(configPath, defaultConfig);
360
- this.log(chalk.green('✅ Configuration reset to defaults (integrations preserved)'));
361
- }
362
- async editPreferences(configPath, config) {
363
- const preferences = config.preferences || DEFAULT_CONFIG.preferences;
364
- const answers = await inquirer.prompt([
365
- {
366
- type: 'confirm',
367
- name: 'autoOpenOutputs',
368
- message: 'Auto-open generated outputs?',
369
- default: preferences.autoOpenOutputs,
370
- },
371
- {
372
- type: 'confirm',
373
- name: 'verboseLogging',
374
- message: 'Enable verbose logging?',
375
- default: preferences.verboseLogging,
376
- },
377
- {
378
- type: 'confirm',
379
- name: 'preserveSessions',
380
- message: 'Preserve completed sessions?',
381
- default: preferences.preserveSessions,
382
- },
383
- ]);
384
- config.preferences = answers;
385
- this.saveConfig(configPath, config);
386
- this.log(chalk.green('\n✅ Preferences updated'));
387
- }
388
- loadConfig(configPath) {
389
- try {
390
- const rawConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
391
- // Check if legacy config and migrate
392
- if (isLegacyConfig(rawConfig)) {
393
- this.warn(chalk.yellow('Detected legacy config format. Migrating to new format...'));
394
- const migratedConfig = migrateConfig(rawConfig);
395
- this.saveConfig(configPath, migratedConfig);
396
- return migratedConfig;
397
- }
398
- return rawConfig;
399
- }
400
- catch (error) {
401
- this.error(chalk.red(`Failed to load configuration: ${error.message}`));
402
- }
403
- }
404
- saveConfig(configPath, config) {
405
- try {
406
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
407
- }
408
- catch (error) {
409
- this.error(chalk.red(`Failed to save configuration: ${error.message}`));
410
- }
411
- }
412
- displayConfig(config) {
413
- this.log(` ${chalk.gray('Version:')} ${config.version}`);
414
- this.log(` ${chalk.gray('Integrations:')} ${config.integrations.map((p) => chalk.cyan(p)).join(', ') || chalk.gray('(none)')}`);
415
- if (config.preferences) {
416
- this.log(`\n ${chalk.bold('Preferences:')}`);
417
- this.log(` ${chalk.gray('Auto-open outputs:')} ${config.preferences.autoOpenOutputs ? chalk.green('yes') : chalk.gray('no')}`);
418
- this.log(` ${chalk.gray('Verbose logging:')} ${config.preferences.verboseLogging ? chalk.green('yes') : chalk.gray('no')}`);
419
- this.log(` ${chalk.gray('Preserve sessions:')} ${config.preferences.preserveSessions ? chalk.green('yes') : chalk.gray('no')}`);
420
- }
421
- if (config.outputs) {
422
- this.log(`\n ${chalk.bold('Outputs:')}`);
423
- this.log(` ${chalk.gray('Path:')} ${config.outputs.path}`);
424
- this.log(` ${chalk.gray('Format:')} ${config.outputs.format}`);
425
- }
426
- this.log('');
427
- }
428
- getNestedValue(obj, path) {
429
- return path.split('.').reduce((current, key) => {
430
- if (current && typeof current === 'object' && key in current) {
431
- return current[key];
432
- }
433
- return undefined;
434
- }, obj);
435
- }
436
- setNestedValue(obj, path, value) {
437
- const keys = path.split('.');
438
- const lastKey = keys.pop();
439
- const target = keys.reduce((current, key) => {
440
- if (!current[key])
441
- current[key] = {};
442
- return current[key];
443
- }, obj);
444
- target[lastKey] = value;
445
- }
446
- }
447
- //# sourceMappingURL=config.js.map
@@ -1,232 +0,0 @@
1
- ## Agent Decision Rules
2
-
3
- These rules define deterministic agent behavior. Follow exactly - no interpretation needed.
4
-
5
- ### Rule 1: Quality-Based Mode Decision
6
-
7
- ```
8
- IF quality < 60%:
9
- IF (completeness < 50%) OR (clarity < 50%) OR (actionability < 50%):
10
- → ACTION: Strongly recommend comprehensive depth
11
- → SAY: "Quality is [X]%. Comprehensive depth strongly recommended for: [low dimensions]"
12
- ELSE:
13
- → ACTION: Suggest comprehensive depth
14
- → SAY: "Quality is [X]%. Consider comprehensive depth for better results."
15
-
16
- IF quality >= 60% AND quality < 80%:
17
- → ACTION: Proceed with optimization
18
- → SHOW: Improvement suggestions
19
-
20
- IF quality >= 80%:
21
- → ACTION: Prompt is ready
22
- → SAY: "Prompt quality is good ([X]%). Ready to execute."
23
- ```
24
-
25
- ### Rule 2: Intent Confidence Decision
26
-
27
- ```
28
- IF confidence >= 85%:
29
- → ACTION: Proceed with detected intent
30
- → NO secondary intent shown
31
-
32
- IF confidence 70-84%:
33
- → ACTION: Proceed, note secondary if >25%
34
- → SHOW: "Primary: [intent] ([X]%). Also detected: [secondary] ([Y]%)"
35
-
36
- IF confidence 50-69%:
37
- → ACTION: Ask user to confirm
38
- → ASK: "Detected [intent] with [X]% confidence. Is this correct?"
39
-
40
- IF confidence < 50%:
41
- → ACTION: Cannot proceed autonomously
42
- → ASK: "I'm unclear on intent. Is this: [option A] | [option B] | [option C]?"
43
- ```
44
-
45
- ### Rule 3: Escalation Decision
46
-
47
- ```
48
- IF escalation_score >= 75:
49
- → ACTION: Strongly recommend comprehensive depth
50
- → SHOW: Top 3 contributing factors
51
-
52
- IF escalation_score 60-74:
53
- → ACTION: Recommend comprehensive depth
54
- → SHOW: Primary contributing factor
55
-
56
- IF escalation_score 45-59:
57
- → ACTION: Suggest comprehensive depth as option
58
- → SAY: "Comprehensive depth available for more thorough analysis"
59
-
60
- IF escalation_score < 45:
61
- → ACTION: Standard depth sufficient
62
- → NO escalation mention
63
- ```
64
-
65
- ### Rule 4: Task Completion (Implementation Mode)
66
-
67
- ```
68
- AFTER implementing task:
69
- → EDIT tasks.md: Change - [ ] to - [x] for completed task
70
- → Use Edit tool to update the checkbox
71
-
72
- IF edit succeeds:
73
- → SHOW: Next task automatically
74
- → CONTINUE with next task
75
-
76
- IF edit fails:
77
- → SHOW error to user
78
- → ASK: "Task completion failed: [error]. How to proceed?"
79
- ```
80
-
81
- ### Rule 5: Workflow State Check
82
-
83
- ```
84
- BEFORE starting /clavix:implement:
85
- → CHECK: .clavix-implement-config.json exists?
86
-
87
- IF exists AND stats.remaining > 0:
88
- → SAY: "Resuming implementation. Progress: [X]/[Y] tasks."
89
- → CONTINUE from currentTask
90
-
91
- IF exists AND stats.remaining == 0:
92
- → SAY: "All tasks complete. Consider /clavix:archive"
93
-
94
- IF not exists:
95
- → CREATE config file and start implementation
96
- ```
97
-
98
- ### Rule 6: File Operations
99
-
100
- ```
101
- BEFORE writing files:
102
- → CHECK: Target directory exists
103
- → IF not exists: Create directory first
104
-
105
- AFTER writing files:
106
- → VERIFY: File was created successfully
107
- → IF failed: Report error, suggest manual action
108
- ```
109
-
110
- ### Rule 7: Pattern Application Decision
111
-
112
- ```
113
- WHEN applying patterns:
114
- → ALWAYS show which patterns were applied
115
- → LIST each pattern with its effect
116
-
117
- IF pattern not applicable to intent:
118
- → SKIP silently (no output)
119
-
120
- IF pattern applicable but skipped:
121
- → EXPLAIN: "Skipped [pattern] because [reason]"
122
-
123
- COMPREHENSIVE DEPTH ONLY:
124
- → MUST include alternatives (2-3)
125
- → MUST include validation checklist
126
- → MUST include edge cases
127
- ```
128
-
129
- ### Rule 8: Mode Transition Decision
130
-
131
- ```
132
- IF user requests standard depth but quality < 50%:
133
- → ACTION: Warn and suggest comprehensive
134
- → SAY: "Quality is [X]%. Standard depth may be insufficient."
135
- → ALLOW: User can override and proceed
136
-
137
- IF user requests comprehensive depth but prompt is simple (quality > 85%):
138
- → ACTION: Note efficiency
139
- → SAY: "Prompt is already high quality. Standard depth would suffice."
140
- → CONTINUE: With comprehensive analysis anyway
141
-
142
- IF strategic keywords detected (3+ architecture/security/scalability):
143
- → ACTION: Suggest PRD mode
144
- → SAY: "Detected strategic scope. Consider /clavix:prd for comprehensive planning."
145
- ```
146
-
147
- ### Rule 9: Output Validation Decision
148
-
149
- ```
150
- BEFORE presenting optimized prompt:
151
- → VERIFY: All 6 quality dimensions scored
152
- → VERIFY: Intent detected with confidence shown
153
- → VERIFY: Patterns applied are listed
154
-
155
- IF any verification fails:
156
- → HALT: Do not present incomplete output
157
- → ACTION: Complete missing analysis first
158
-
159
- AFTER optimization complete:
160
- → MUST save prompt to .clavix/outputs/prompts/
161
- → SHOW: "✓ Prompt saved: [filename]"
162
- ```
163
-
164
- ### Rule 10: Error Recovery Decision
165
-
166
- ```
167
- IF pattern application fails:
168
- → LOG: Which pattern failed
169
- → CONTINUE: With remaining patterns
170
- → REPORT: "Pattern [X] skipped due to error"
171
-
172
- IF file write fails:
173
- → RETRY: Once with alternative path
174
- → IF still fails: Report error with manual steps
175
-
176
- IF CLI command fails:
177
- → SHOW: Command output and error
178
- → SUGGEST: Alternative action
179
- → NEVER: Silently ignore failures
180
-
181
- IF user prompt is empty/invalid:
182
- → ASK: For valid input
183
- → NEVER: Proceed with assumption
184
- ```
185
-
186
- ### Rule 11: Execution Verification (v4.6)
187
-
188
- ```
189
- BEFORE completing response:
190
- → INCLUDE verification block at end
191
- → VERIFY all checkpoints met for current mode
192
-
193
- IF any checkpoint failed:
194
- → REPORT which checkpoint failed
195
- → EXPLAIN why it failed
196
- → SUGGEST recovery action
197
-
198
- IF all checkpoints passed:
199
- → SHOW verification block with all items checked
200
- ```
201
-
202
- **Verification Block Template:**
203
- ```
204
- ## Clavix Execution Verification
205
- - [x] Intent detected: {type} ({confidence}%)
206
- - [x] Quality assessed: {overall}%
207
- - [x] {N} patterns applied
208
- - [x] Prompt saved: {filename}
209
- - [x] Mode: {fast|deep|prd|plan}
210
- ```
211
-
212
- ---
213
-
214
- ### Rule Summary Table
215
-
216
- | Condition | Action | User Communication |
217
- |-----------|--------|-------------------|
218
- | quality < 60% + critical dim < 50% | Recommend deep | "[X]%. Deep mode recommended" |
219
- | quality 60-79% | Proceed | Show improvements |
220
- | quality >= 80% | Ready | "[X]%. Ready to execute" |
221
- | confidence >= 85% | Proceed | Primary intent only |
222
- | confidence 70-84% | Proceed | Show secondary if >25% |
223
- | confidence 50-69% | Confirm | Ask user to verify |
224
- | confidence < 50% | Cannot proceed | Ask for clarification |
225
- | escalation >= 75 | Strong recommend | Show top 3 factors |
226
- | escalation 45-74 | Suggest | Show primary factor |
227
- | escalation < 45 | No action | Silent |
228
- | fast requested + quality < 50% | Warn | "Quality low, consider deep" |
229
- | 3+ strategic keywords | Suggest PRD | "Strategic scope detected" |
230
- | pattern fails | Skip + report | "Pattern [X] skipped" |
231
- | file write fails | Retry then report | "Error: [details]" |
232
- | response complete | Include verification | Show checkpoint status |