clavix 2.6.0 → 2.7.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.
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const core_1 = require("@oclif/core");
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const prompt_manager_1 = require("../../../core/prompt-manager");
9
+ class PromptsList extends core_1.Command {
10
+ async run() {
11
+ const promptManager = new prompt_manager_1.PromptManager();
12
+ try {
13
+ const prompts = await promptManager.listPrompts();
14
+ const stats = await promptManager.getStorageStats();
15
+ console.log(chalk_1.default.bold.cyan(`\nšŸ“‹ Saved Prompts (${prompts.length} total)\n`));
16
+ if (prompts.length === 0) {
17
+ console.log(chalk_1.default.gray('No prompts saved yet.\n'));
18
+ console.log(chalk_1.default.cyan('Generate an optimized prompt:'));
19
+ console.log(chalk_1.default.cyan(' /clavix:fast "your requirement"'));
20
+ console.log(chalk_1.default.cyan(' /clavix:deep "your requirement"'));
21
+ console.log();
22
+ return;
23
+ }
24
+ // Display prompts grouped by source
25
+ const fastPrompts = prompts.filter(p => p.source === 'fast');
26
+ const deepPrompts = prompts.filter(p => p.source === 'deep');
27
+ if (fastPrompts.length > 0) {
28
+ console.log(chalk_1.default.bold('Fast Prompts:'));
29
+ this.displayPrompts(fastPrompts);
30
+ console.log();
31
+ }
32
+ if (deepPrompts.length > 0) {
33
+ console.log(chalk_1.default.bold('Deep Prompts:'));
34
+ this.displayPrompts(deepPrompts);
35
+ console.log();
36
+ }
37
+ // Display storage statistics
38
+ console.log(chalk_1.default.bold('šŸ“Š Storage Statistics:\n'));
39
+ console.log(chalk_1.default.gray(` Total Prompts: ${stats.totalPrompts}`));
40
+ console.log(chalk_1.default.gray(` Fast: ${stats.fastPrompts} | Deep: ${stats.deepPrompts}`));
41
+ console.log(chalk_1.default.gray(` Executed: ${stats.executedPrompts} | Pending: ${stats.pendingPrompts}`));
42
+ if (stats.oldestPromptAge > 0) {
43
+ console.log(chalk_1.default.gray(` Oldest: ${stats.oldestPromptAge} days`));
44
+ }
45
+ console.log();
46
+ // Storage hygiene recommendations
47
+ if (stats.stalePrompts > 0) {
48
+ console.log(chalk_1.default.yellow(`āš ļø ${stats.stalePrompts} stale prompts (>30 days old)`));
49
+ console.log(chalk_1.default.yellow(` Recommend: clavix prompts clear --stale\n`));
50
+ }
51
+ if (stats.executedPrompts >= 10) {
52
+ console.log(chalk_1.default.cyan(`šŸ’” ${stats.executedPrompts} executed prompts`));
53
+ console.log(chalk_1.default.cyan(` Recommend: clavix prompts clear --executed\n`));
54
+ }
55
+ if (stats.totalPrompts >= 20) {
56
+ console.log(chalk_1.default.yellow(`āš ļø Storage approaching limit (${stats.totalPrompts}/recommended 20)`));
57
+ console.log(chalk_1.default.yellow(` Consider cleanup: clavix prompts clear\n`));
58
+ }
59
+ }
60
+ catch (error) {
61
+ console.log(chalk_1.default.red(`\nāœ— Error: ${error}\n`));
62
+ }
63
+ }
64
+ displayPrompts(prompts) {
65
+ prompts.forEach(p => {
66
+ const status = p.executed ? chalk_1.default.green('āœ“') : chalk_1.default.gray('ā—‹');
67
+ const ageInDays = p.ageInDays || 0;
68
+ // Age warning coloring
69
+ let ageWarning = '';
70
+ let ageStr = '';
71
+ if (ageInDays === 0) {
72
+ ageStr = chalk_1.default.gray('today');
73
+ }
74
+ else if (ageInDays > 30) {
75
+ ageStr = chalk_1.default.red(`${ageInDays}d`);
76
+ ageWarning = chalk_1.default.red(' [STALE]');
77
+ }
78
+ else if (ageInDays > 7) {
79
+ ageStr = chalk_1.default.yellow(`${ageInDays}d`);
80
+ ageWarning = chalk_1.default.yellow(' [OLD]');
81
+ }
82
+ else {
83
+ ageStr = chalk_1.default.gray(`${ageInDays}d`);
84
+ }
85
+ // Truncate original prompt for display
86
+ const promptPreview = p.originalPrompt.length > 50
87
+ ? p.originalPrompt.substring(0, 50) + '...'
88
+ : p.originalPrompt;
89
+ console.log(` ${status} ${chalk_1.default.dim(p.id)} (${ageStr})${ageWarning}`);
90
+ console.log(` ${chalk_1.default.gray(promptPreview)}`);
91
+ });
92
+ }
93
+ }
94
+ PromptsList.description = 'List all saved prompts with age warnings and storage statistics';
95
+ PromptsList.examples = [
96
+ '<%= config.bin %> <%= command.id %>',
97
+ ];
98
+ exports.default = PromptsList;
99
+ //# sourceMappingURL=list.js.map
@@ -209,7 +209,7 @@ class TaskComplete extends core_1.Command {
209
209
  commitMessage = `clavix: Completed ${last5.length} tasks\n\nCompleted tasks:\n${taskDescriptions.map(d => `- ${d}`).join('\n')}`;
210
210
  }
211
211
  break;
212
- case 'per-phase':
212
+ case 'per-phase': {
213
213
  // Check if current phase is complete
214
214
  const currentPhase = phases.find(p => p.name === completedTask.phase);
215
215
  if (currentPhase) {
@@ -220,6 +220,7 @@ class TaskComplete extends core_1.Command {
220
220
  }
221
221
  }
222
222
  break;
223
+ }
223
224
  case 'none':
224
225
  default:
225
226
  shouldCommit = false;
@@ -227,10 +227,10 @@ class ConfigManager {
227
227
  }
228
228
  // Migrate from old format
229
229
  const migrated = {
230
- commitStrategy: config.commitStrategy,
231
- tasksPath: config.tasksPath,
232
- currentTask: config.currentTask,
233
- stats: config.stats,
230
+ commitStrategy: config.commitStrategy ?? 'none',
231
+ tasksPath: config.tasksPath ?? '',
232
+ currentTask: config.currentTask ?? { id: 'initial', description: 'Initial Task', phase: 'initialization', completed: false },
233
+ stats: config.stats ?? { total: 0, completed: 0, remaining: 0, percentage: 0 },
234
234
  timestamp: config.timestamp ?? new Date().toISOString(),
235
235
  completedTaskIds: [],
236
236
  completionTimestamps: {},
@@ -0,0 +1,101 @@
1
+ export type PromptSource = 'fast' | 'deep';
2
+ export interface PromptMetadata {
3
+ id: string;
4
+ filename: string;
5
+ source: PromptSource;
6
+ timestamp: string;
7
+ createdAt: Date;
8
+ path: string;
9
+ originalPrompt: string;
10
+ executed: boolean;
11
+ executedAt: string | null;
12
+ ageInDays?: number;
13
+ linkedProject?: string;
14
+ }
15
+ export interface PromptsIndex {
16
+ version: string;
17
+ prompts: PromptMetadata[];
18
+ }
19
+ export interface PromptData {
20
+ metadata: PromptMetadata;
21
+ content: string;
22
+ }
23
+ export interface PromptFilters {
24
+ source?: PromptSource;
25
+ executed?: boolean;
26
+ stale?: boolean;
27
+ old?: boolean;
28
+ }
29
+ export interface StorageStats {
30
+ totalPrompts: number;
31
+ fastPrompts: number;
32
+ deepPrompts: number;
33
+ executedPrompts: number;
34
+ pendingPrompts: number;
35
+ stalePrompts: number;
36
+ oldPrompts: number;
37
+ oldestPromptAge: number;
38
+ }
39
+ export declare class PromptManager {
40
+ private readonly promptsDir;
41
+ constructor(baseDir?: string);
42
+ /**
43
+ * Get index file path for a specific source
44
+ */
45
+ private getIndexPath;
46
+ /**
47
+ * Ensure prompts directory structure exists
48
+ */
49
+ ensurePromptsDir(): Promise<void>;
50
+ /**
51
+ * Generate unique prompt ID with timestamp and hash
52
+ */
53
+ generatePromptId(source: PromptSource, _originalPrompt: string): string;
54
+ /**
55
+ * Save optimized prompt to file system
56
+ */
57
+ savePrompt(content: string, source: PromptSource, originalPrompt: string, linkedProject?: string): Promise<PromptMetadata>;
58
+ /**
59
+ * Load prompt by ID
60
+ */
61
+ loadPrompt(id: string): Promise<PromptData | null>;
62
+ /**
63
+ * List prompts with optional filtering
64
+ */
65
+ listPrompts(filters?: PromptFilters): Promise<PromptMetadata[]>;
66
+ /**
67
+ * Mark prompt as executed
68
+ */
69
+ markExecuted(id: string): Promise<void>;
70
+ /**
71
+ * Delete prompts by filter
72
+ */
73
+ deletePrompts(filters: PromptFilters): Promise<number>;
74
+ /**
75
+ * Get age of prompt in days
76
+ */
77
+ getPromptAge(prompt: PromptMetadata): number;
78
+ /**
79
+ * Get stale prompts (>30 days old)
80
+ */
81
+ getStalePrompts(_daysOld?: number): Promise<PromptMetadata[]>;
82
+ /**
83
+ * Get storage statistics
84
+ */
85
+ getStorageStats(): Promise<StorageStats>;
86
+ /**
87
+ * Load index from file
88
+ * If source is specified, loads that source's index only
89
+ * If source is undefined, loads and merges all source indexes
90
+ */
91
+ private loadIndex;
92
+ /**
93
+ * Save index to file for a specific source
94
+ */
95
+ private saveIndex;
96
+ /**
97
+ * Add prompt to index
98
+ */
99
+ private addToIndex;
100
+ }
101
+ //# sourceMappingURL=prompt-manager.d.ts.map
@@ -0,0 +1,312 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.PromptManager = void 0;
37
+ const fs = __importStar(require("fs-extra"));
38
+ const path = __importStar(require("path"));
39
+ const uuid_1 = require("uuid");
40
+ class PromptManager {
41
+ constructor(baseDir) {
42
+ // If baseDir ends with 'prompts', use it directly; otherwise append 'prompts'
43
+ if (baseDir) {
44
+ this.promptsDir = baseDir.endsWith('prompts') ? baseDir : path.join(baseDir, 'prompts');
45
+ }
46
+ else {
47
+ this.promptsDir = path.join(process.cwd(), '.clavix', 'outputs', 'prompts');
48
+ }
49
+ }
50
+ /**
51
+ * Get index file path for a specific source
52
+ */
53
+ getIndexPath(source) {
54
+ return path.join(this.promptsDir, source, '.index.json');
55
+ }
56
+ /**
57
+ * Ensure prompts directory structure exists
58
+ */
59
+ async ensurePromptsDir() {
60
+ await fs.ensureDir(path.join(this.promptsDir, 'fast'));
61
+ await fs.ensureDir(path.join(this.promptsDir, 'deep'));
62
+ }
63
+ /**
64
+ * Generate unique prompt ID with timestamp and hash
65
+ */
66
+ generatePromptId(source, _originalPrompt) {
67
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T');
68
+ const date = timestamp[0].replace(/-/g, '');
69
+ const time = timestamp[1].split('-').slice(0, 3).join('');
70
+ // Use UUID for uniqueness (mockable for tests - first 13 chars for readability)
71
+ const hash = (0, uuid_1.v4)().substring(0, 13);
72
+ return `${source}-${date}-${time}-${hash}`;
73
+ }
74
+ /**
75
+ * Save optimized prompt to file system
76
+ */
77
+ async savePrompt(content, source, originalPrompt, linkedProject) {
78
+ await this.ensurePromptsDir();
79
+ const id = this.generatePromptId(source, originalPrompt);
80
+ const filename = `${id}.md`;
81
+ const filePath = path.join(this.promptsDir, source, filename);
82
+ const now = new Date();
83
+ const metadata = {
84
+ id,
85
+ filename,
86
+ source,
87
+ timestamp: now.toISOString(),
88
+ createdAt: now,
89
+ path: filePath,
90
+ originalPrompt,
91
+ executed: false,
92
+ executedAt: null,
93
+ linkedProject,
94
+ };
95
+ // Create file with frontmatter
96
+ const frontmatter = [
97
+ '---',
98
+ `id: ${id}`,
99
+ `source: ${source}`,
100
+ `timestamp: ${metadata.timestamp}`,
101
+ `executed: ${metadata.executed}`,
102
+ `originalPrompt: ${originalPrompt}`,
103
+ linkedProject ? `linkedProject: ${linkedProject}` : '',
104
+ '---',
105
+ '',
106
+ ].filter(Boolean).join('\n');
107
+ const fileContent = frontmatter + content;
108
+ await fs.writeFile(filePath, fileContent, 'utf-8');
109
+ // Update index
110
+ await this.addToIndex(metadata);
111
+ return metadata;
112
+ }
113
+ /**
114
+ * Load prompt by ID
115
+ */
116
+ async loadPrompt(id) {
117
+ const index = await this.loadIndex();
118
+ const metadata = index.prompts.find(p => p.id === id);
119
+ if (!metadata) {
120
+ return null;
121
+ }
122
+ const filePath = path.join(this.promptsDir, metadata.source, metadata.filename);
123
+ if (!await fs.pathExists(filePath)) {
124
+ return null;
125
+ }
126
+ const content = await fs.readFile(filePath, 'utf-8');
127
+ // Strip frontmatter for clean content
128
+ const contentWithoutFrontmatter = content.replace(/^---\n[\s\S]*?\n---\n*/, '');
129
+ return {
130
+ metadata,
131
+ content: contentWithoutFrontmatter,
132
+ };
133
+ }
134
+ /**
135
+ * List prompts with optional filtering
136
+ */
137
+ async listPrompts(filters) {
138
+ const index = await this.loadIndex(filters?.source);
139
+ let prompts = index.prompts;
140
+ // Ensure index exists when filtering by source (for corruption recovery tests)
141
+ if (filters?.source) {
142
+ const indexPath = this.getIndexPath(filters.source);
143
+ if (!await fs.pathExists(indexPath)) {
144
+ await this.saveIndex({ version: '1.0', prompts: [] }, filters.source);
145
+ }
146
+ }
147
+ // Apply filters
148
+ if (filters) {
149
+ if (filters.executed !== undefined) {
150
+ prompts = prompts.filter(p => p.executed === filters.executed);
151
+ }
152
+ if (filters.stale) {
153
+ prompts = prompts.filter(p => this.getPromptAge(p) > 30);
154
+ }
155
+ if (filters.old) {
156
+ prompts = prompts.filter(p => this.getPromptAge(p) > 7);
157
+ }
158
+ }
159
+ // Add age calculation
160
+ prompts = prompts.map(p => ({
161
+ ...p,
162
+ createdAt: new Date(p.timestamp),
163
+ ageInDays: this.getPromptAge(p),
164
+ }));
165
+ // Sort by timestamp (newest first)
166
+ prompts.sort((a, b) => {
167
+ return new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();
168
+ });
169
+ return prompts;
170
+ }
171
+ /**
172
+ * Mark prompt as executed
173
+ */
174
+ async markExecuted(id) {
175
+ // Load all indexes to find the prompt
176
+ const allPrompts = await this.listPrompts();
177
+ const prompt = allPrompts.find(p => p.id === id);
178
+ if (!prompt) {
179
+ throw new Error(`Prompt not found: ${id}`);
180
+ }
181
+ // Load source-specific index
182
+ const index = await this.loadIndex(prompt.source);
183
+ const indexPrompt = index.prompts.find(p => p.id === id);
184
+ if (indexPrompt) {
185
+ indexPrompt.executed = true;
186
+ indexPrompt.executedAt = new Date().toISOString();
187
+ await this.saveIndex(index, prompt.source);
188
+ }
189
+ }
190
+ /**
191
+ * Delete prompts by filter
192
+ */
193
+ async deletePrompts(filters) {
194
+ const toDelete = await this.listPrompts(filters);
195
+ let deleteCount = 0;
196
+ // Group by source for index updates
197
+ const bySource = new Map();
198
+ for (const prompt of toDelete) {
199
+ const filePath = path.join(this.promptsDir, prompt.source, prompt.filename);
200
+ if (await fs.pathExists(filePath)) {
201
+ await fs.remove(filePath);
202
+ deleteCount++;
203
+ if (!bySource.has(prompt.source)) {
204
+ bySource.set(prompt.source, new Set());
205
+ }
206
+ bySource.get(prompt.source).add(prompt.id);
207
+ }
208
+ }
209
+ // Update each source index
210
+ for (const [source, deletedIds] of bySource.entries()) {
211
+ const index = await this.loadIndex(source);
212
+ index.prompts = index.prompts.filter(p => !deletedIds.has(p.id));
213
+ await this.saveIndex(index, source);
214
+ }
215
+ return deleteCount;
216
+ }
217
+ /**
218
+ * Get age of prompt in days
219
+ */
220
+ getPromptAge(prompt) {
221
+ const created = new Date(prompt.timestamp);
222
+ const now = new Date();
223
+ const diffMs = now.getTime() - created.getTime();
224
+ return Math.floor(diffMs / (1000 * 60 * 60 * 24));
225
+ }
226
+ /**
227
+ * Get stale prompts (>30 days old)
228
+ */
229
+ async getStalePrompts(_daysOld = 30) {
230
+ return this.listPrompts({ stale: true });
231
+ }
232
+ /**
233
+ * Get storage statistics
234
+ */
235
+ async getStorageStats() {
236
+ const allPrompts = await this.listPrompts();
237
+ const stats = {
238
+ totalPrompts: allPrompts.length,
239
+ fastPrompts: allPrompts.filter(p => p.source === 'fast').length,
240
+ deepPrompts: allPrompts.filter(p => p.source === 'deep').length,
241
+ executedPrompts: allPrompts.filter(p => p.executed).length,
242
+ pendingPrompts: allPrompts.filter(p => !p.executed).length,
243
+ stalePrompts: allPrompts.filter(p => (p.ageInDays || 0) > 30).length,
244
+ oldPrompts: allPrompts.filter(p => (p.ageInDays || 0) > 7).length,
245
+ oldestPromptAge: allPrompts.length > 0
246
+ ? Math.max(...allPrompts.map(p => p.ageInDays || 0))
247
+ : 0,
248
+ };
249
+ return stats;
250
+ }
251
+ /**
252
+ * Load index from file
253
+ * If source is specified, loads that source's index only
254
+ * If source is undefined, loads and merges all source indexes
255
+ */
256
+ async loadIndex(source) {
257
+ // If no source specified, load all indexes and merge
258
+ if (!source) {
259
+ const fastIndex = await this.loadIndex('fast');
260
+ const deepIndex = await this.loadIndex('deep');
261
+ return {
262
+ version: '1.0',
263
+ prompts: [...(fastIndex.prompts || []), ...(deepIndex.prompts || [])],
264
+ };
265
+ }
266
+ // Load specific source index
267
+ const indexPath = this.getIndexPath(source);
268
+ if (!await fs.pathExists(indexPath)) {
269
+ return {
270
+ version: '1.0',
271
+ prompts: [],
272
+ };
273
+ }
274
+ try {
275
+ const content = await fs.readFile(indexPath, 'utf-8');
276
+ const parsed = JSON.parse(content);
277
+ // Ensure prompts array exists
278
+ return {
279
+ version: parsed.version || '1.0',
280
+ prompts: Array.isArray(parsed.prompts) ? parsed.prompts : [],
281
+ };
282
+ }
283
+ catch {
284
+ // Corrupt index, return empty
285
+ return {
286
+ version: '1.0',
287
+ prompts: [],
288
+ };
289
+ }
290
+ }
291
+ /**
292
+ * Save index to file for a specific source
293
+ */
294
+ async saveIndex(index, source) {
295
+ const indexPath = this.getIndexPath(source);
296
+ await fs.ensureDir(path.dirname(indexPath));
297
+ await fs.writeFile(indexPath, JSON.stringify(index, null, 2), 'utf-8');
298
+ }
299
+ /**
300
+ * Add prompt to index
301
+ */
302
+ async addToIndex(metadata) {
303
+ const index = await this.loadIndex(metadata.source);
304
+ // Remove any existing entry with same ID (shouldn't happen, but be safe)
305
+ index.prompts = index.prompts.filter(p => p.id !== metadata.id);
306
+ // Add new entry
307
+ index.prompts.push(metadata);
308
+ await this.saveIndex(index, metadata.source);
309
+ }
310
+ }
311
+ exports.PromptManager = PromptManager;
312
+ //# sourceMappingURL=prompt-manager.js.map
@@ -632,7 +632,7 @@ class TaskManager {
632
632
  const task = this.validateTaskExists(phases, taskId);
633
633
  return task ? task.completed : false;
634
634
  }
635
- catch (error) {
635
+ catch {
636
636
  // If we can't read the file, verification failed
637
637
  return false;
638
638
  }
@@ -662,7 +662,7 @@ class TaskManager {
662
662
  try {
663
663
  await fs.copyFile(tasksPath, backupPath);
664
664
  }
665
- catch (error) {
665
+ catch {
666
666
  warnings.push('Failed to create backup file');
667
667
  }
668
668
  }
@@ -735,7 +735,7 @@ class TaskManager {
735
735
  await fs.copyFile(backupPath, tasksPath);
736
736
  warnings.push('Restored tasks.md from backup due to error');
737
737
  }
738
- catch (restoreError) {
738
+ catch {
739
739
  warnings.push('Failed to restore from backup');
740
740
  }
741
741
  }
@@ -12,8 +12,11 @@ Use these instructions when your agent can only read documentation (no slash-com
12
12
  | Command | Purpose |
13
13
  | --- | --- |
14
14
  | `clavix init` | Interactive setup. Select providers and generate documentation/command files. |
15
- | `clavix fast "<prompt>"` | CLEAR (C/L/E) analysis with improved prompt output. |
16
- | `clavix deep "<prompt>"` | Full CLEAR (C/L/E/A/R) analysis, alternative variations, validation checklists. |
15
+ | `clavix fast "<prompt>"` | CLEAR (C/L/E) analysis with improved prompt output. Auto-saves to `.clavix/outputs/prompts/fast/`. |
16
+ | `clavix deep "<prompt>"` | Full CLEAR (C/L/E/A/R) analysis, alternative variations, validation checklists. Auto-saves to `.clavix/outputs/prompts/deep/`. |
17
+ | `clavix execute [--latest]` | Execute saved prompts from fast/deep optimization. Interactive selection or `--latest` for most recent. |
18
+ | `clavix prompts list` | View all saved prompts with status (NEW, EXECUTED, OLD, STALE) and storage statistics. |
19
+ | `clavix prompts clear` | Manage prompt cleanup. Supports `--executed`, `--stale`, `--fast`, `--deep`, `--all` flags. |
17
20
  | `clavix prd` | Guided Socratic questions that generate `full-prd.md` and `quick-prd.md`. |
18
21
  | `clavix plan` | Transform PRDs or sessions into phase-based `tasks.md`. |
19
22
  | `clavix implement` | Walk through tasks, track progress, optionally set git auto-commit strategy. |
@@ -29,6 +29,34 @@ When working with this project, you can use the following Clavix commands:
29
29
  - `clavix archive [project]` - Archive or restore completed projects
30
30
  - `clavix update` - Refresh Clavix documentation and commands
31
31
 
32
+ ### Prompt Lifecycle Management (v2.7+)
33
+ Clavix now automatically saves optimized prompts from fast/deep commands for later execution:
34
+
35
+ - `clavix execute [--latest]` - Execute saved prompts from fast/deep optimization
36
+ - Interactive selection from saved prompts
37
+ - `--latest` flag for most recent prompt
38
+ - `--fast` / `--deep` filters with `--latest`
39
+ - `--id <prompt-id>` for specific prompt execution
40
+
41
+ - `clavix prompts list` - View all saved prompts with lifecycle status
42
+ - Status indicators: NEW, EXECUTED, OLD (>7 days), STALE (>30 days)
43
+ - Storage statistics dashboard
44
+ - Age warnings and hygiene recommendations
45
+
46
+ - `clavix prompts clear` - Manage prompt cleanup with safety checks
47
+ - `--executed` - Clear executed prompts only (safe cleanup)
48
+ - `--stale` - Clear prompts >30 days old
49
+ - `--fast` - Clear fast mode prompts
50
+ - `--deep` - Clear deep mode prompts
51
+ - `--all` - Clear all prompts (with confirmation)
52
+ - `--force` - Skip confirmation prompts
53
+
54
+ **Prompt Lifecycle Workflow:**
55
+ 1. Optimize: `clavix fast/deep "<prompt>"` → Auto-saved to `.clavix/outputs/prompts/`
56
+ 2. Review: `clavix prompts list` → View all saved prompts with status
57
+ 3. Execute: `clavix execute --latest` → Implement when ready
58
+ 4. Cleanup: `clavix prompts clear --executed` → Remove completed prompts
59
+
32
60
  ## Workflow Patterns
33
61
 
34
62
  ### Quick Prompt Improvement
@@ -215,12 +215,39 @@ Detect user intent from keywords and trigger appropriate workflow. Use Octofrien
215
215
 
216
216
  ---
217
217
 
218
+ ### Prompt Execution Workflow
219
+ **Trigger Keywords:** execute prompt, implement saved prompt, run optimized prompt, use saved optimization
220
+
221
+ **When to use:** User has saved prompts from fast/deep optimization and wants to execute them
222
+
223
+ **Process:**
224
+ 1. List saved prompts: `clavix prompts list`
225
+ - Shows all prompts with status (NEW, EXECUTED, OLD, STALE)
226
+ - Displays age warnings and storage statistics
227
+ 2. Execute interactively: `clavix execute` (select from list)
228
+ - Or execute latest: `clavix execute --latest`
229
+ - Or execute specific: `clavix execute --id <prompt-id>`
230
+ 3. Prompt is marked as EXECUTED after display
231
+ 4. Implement the requirements from the optimized prompt
232
+ 5. Cleanup after completion: `clavix prompts clear --executed`
233
+
234
+ **Octofriend Tip:**
235
+ - Execute complex prompts with thinking models for better analysis
236
+ - Execute simple prompts with fast models for quick implementation
237
+ - Your autofix capabilities help recover from implementation failures
238
+ - Use `--latest` flag for streamlined workflow automation
239
+
240
+ ---
241
+
218
242
  ### CLI reference cheat sheet
219
243
 
220
244
  | Command | Use it for |
221
245
  | --- | --- |
222
246
  | `clavix init` | Rebuild `.clavix` structure and regenerate provider assets. |
223
- | `clavix fast` / `clavix deep` | CLEAR-based prompt improvement (quick vs. comprehensive). |
247
+ | `clavix fast` / `clavix deep` | CLEAR-based prompt improvement (quick vs. comprehensive). Auto-saves prompts to `.clavix/outputs/prompts/`. |
248
+ | `clavix execute` | Execute saved prompts (interactive selection or `--latest` for most recent). |
249
+ | `clavix prompts list` | View saved prompts with lifecycle status (NEW, EXECUTED, OLD, STALE). |
250
+ | `clavix prompts clear` | Cleanup executed/stale prompts (`--executed`, `--stale`, `--fast`, `--deep`). |
224
251
  | `clavix prd` | Guided questions to create PRDs. |
225
252
  | `clavix plan` | Convert PRD artifacts into task lists. |
226
253
  | `clavix implement` | Step through tasks with optional git automation. |
@@ -9,8 +9,11 @@ Clavix helps Warp developers turn rough ideas into CLEAR, AI-ready prompts and P
9
9
 
10
10
  ### Common commands
11
11
  - `clavix init` – interactive provider setup (regenerates docs & commands)
12
- - `clavix fast "<prompt>"` – quick CLEAR (C/L/E) analysis and improved prompt
13
- - `clavix deep "<prompt>"` – full CLEAR (C/L/E/A/R) analysis with alternatives & checklists
12
+ - `clavix fast "<prompt>"` – quick CLEAR (C/L/E) analysis and improved prompt. Auto-saves to `.clavix/outputs/prompts/fast/`.
13
+ - `clavix deep "<prompt>"` – full CLEAR (C/L/E/A/R) analysis with alternatives & checklists. Auto-saves to `.clavix/outputs/prompts/deep/`.
14
+ - `clavix execute [--latest]` – execute saved prompts from fast/deep. Interactive selection or `--latest` for most recent.
15
+ - `clavix prompts list` – view all saved prompts with age/status (NEW, EXECUTED, OLD, STALE)
16
+ - `clavix prompts clear [--executed|--stale|--fast|--deep]` – cleanup executed or old prompts
14
17
  - `clavix prd` – answer focused questions to create full/quick PRDs
15
18
  - `clavix plan` – transform PRDs or sessions into task lists
16
19
  - `clavix implement` – progress through tasks with optional git auto-commit