clavix 4.6.0 → 4.8.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,422 @@
1
+ /**
2
+ * Clavix v4.8: Verification Manager
3
+ *
4
+ * Manages verification state, execution flow, and persistence.
5
+ * Coordinates between checklist parsing, hook execution, and result storage.
6
+ */
7
+ import fs from 'fs-extra';
8
+ import * as path from 'path';
9
+ import { ChecklistParser } from './checklist-parser.js';
10
+ import { VerificationHooks } from './verification-hooks.js';
11
+ import { PromptManager } from './prompt-manager.js';
12
+ /**
13
+ * Verification Manager
14
+ */
15
+ export class VerificationManager {
16
+ promptManager;
17
+ checklistParser;
18
+ verificationHooks;
19
+ outputDir;
20
+ constructor(baseDir) {
21
+ this.outputDir = baseDir || path.join(process.cwd(), '.clavix', 'outputs', 'prompts');
22
+ this.promptManager = new PromptManager(this.outputDir);
23
+ this.checklistParser = new ChecklistParser();
24
+ this.verificationHooks = new VerificationHooks();
25
+ }
26
+ /**
27
+ * Initialize verification for a prompt
28
+ */
29
+ async initializeVerification(promptId) {
30
+ // Load prompt
31
+ const promptData = await this.promptManager.loadPrompt(promptId);
32
+ if (!promptData) {
33
+ throw new Error(`Prompt not found: ${promptId}`);
34
+ }
35
+ // Parse checklist from prompt content
36
+ const checklist = this.checklistParser.parse(promptData.content);
37
+ // Get all items
38
+ const items = [...checklist.validationItems, ...checklist.edgeCases, ...checklist.risks];
39
+ // Detect available hooks
40
+ const detectedHooks = await this.verificationHooks.detectHooks();
41
+ // Create initial report
42
+ const report = {
43
+ version: '1.0',
44
+ promptId,
45
+ source: promptData.metadata.source,
46
+ startedAt: new Date().toISOString(),
47
+ status: items.length > 0 ? 'pending' : 'completed',
48
+ items,
49
+ results: items.map((item) => ({
50
+ itemId: item.id,
51
+ status: 'pending',
52
+ method: item.verificationType === 'automated' ? 'automated' : 'manual',
53
+ confidence: 'low',
54
+ verifiedAt: '',
55
+ })),
56
+ summary: this.calculateSummary([]),
57
+ detectedHooks,
58
+ };
59
+ // Save initial report
60
+ await this.saveReport(report);
61
+ return report;
62
+ }
63
+ /**
64
+ * Get verification report path for a prompt
65
+ */
66
+ getReportPath(promptId, source) {
67
+ return path.join(this.outputDir, source, `${promptId}.verification.json`);
68
+ }
69
+ /**
70
+ * Load verification report
71
+ */
72
+ async loadReport(promptId) {
73
+ // Try both sources
74
+ for (const source of ['deep', 'fast']) {
75
+ const reportPath = this.getReportPath(promptId, source);
76
+ if (await fs.pathExists(reportPath)) {
77
+ try {
78
+ return await fs.readJson(reportPath);
79
+ }
80
+ catch {
81
+ // Corrupt file, ignore
82
+ }
83
+ }
84
+ }
85
+ return null;
86
+ }
87
+ /**
88
+ * Save verification report
89
+ */
90
+ async saveReport(report) {
91
+ const reportPath = this.getReportPath(report.promptId, report.source);
92
+ await fs.ensureDir(path.dirname(reportPath));
93
+ await fs.writeJson(reportPath, report, { spaces: 2 });
94
+ }
95
+ /**
96
+ * Mark a single item as verified
97
+ */
98
+ async markItemVerified(promptId, itemId, status, options = {}) {
99
+ let report = await this.loadReport(promptId);
100
+ if (!report) {
101
+ // Initialize if doesn't exist
102
+ report = await this.initializeVerification(promptId);
103
+ }
104
+ // Find and update result
105
+ const resultIndex = report.results.findIndex((r) => r.itemId === itemId);
106
+ if (resultIndex === -1) {
107
+ throw new Error(`Item not found: ${itemId}`);
108
+ }
109
+ const item = report.items.find((i) => i.id === itemId);
110
+ report.results[resultIndex] = {
111
+ itemId,
112
+ status,
113
+ method: options.method || (item?.verificationType === 'automated' ? 'automated' : 'manual'),
114
+ confidence: options.confidence || 'medium',
115
+ evidence: options.evidence,
116
+ reason: options.reason,
117
+ verifiedAt: new Date().toISOString(),
118
+ };
119
+ // Recalculate summary and status
120
+ report.summary = this.calculateSummary(report.results);
121
+ report.status = this.calculateReportStatus(report.results);
122
+ if (report.status === 'completed') {
123
+ report.completedAt = new Date().toISOString();
124
+ }
125
+ await this.saveReport(report);
126
+ return report;
127
+ }
128
+ /**
129
+ * Run automated verification for a prompt
130
+ */
131
+ async runAutomatedVerification(promptId) {
132
+ let report = await this.loadReport(promptId);
133
+ if (!report) {
134
+ report = await this.initializeVerification(promptId);
135
+ }
136
+ // Find automated items that are pending
137
+ const automatedItems = report.items.filter((item) => item.verificationType === 'automated' &&
138
+ report.results.find((r) => r.itemId === item.id)?.status === 'pending');
139
+ if (automatedItems.length === 0) {
140
+ return report;
141
+ }
142
+ // Detect hooks
143
+ const detectedHooks = await this.verificationHooks.detectHooks();
144
+ // Run relevant hooks
145
+ const hookResults = await this.verificationHooks.runAllHooks();
146
+ // Map hook results to checklist items
147
+ for (const item of automatedItems) {
148
+ const lowerContent = item.content.toLowerCase();
149
+ // Match item to hook result
150
+ let matched = false;
151
+ for (const hookResult of hookResults) {
152
+ if (this.matchItemToHook(lowerContent, hookResult.hook.name)) {
153
+ const resultIndex = report.results.findIndex((r) => r.itemId === item.id);
154
+ if (resultIndex !== -1) {
155
+ report.results[resultIndex] = {
156
+ itemId: item.id,
157
+ status: hookResult.success ? 'passed' : 'failed',
158
+ method: 'automated',
159
+ confidence: hookResult.confidence,
160
+ evidence: this.truncateOutput(hookResult.output),
161
+ reason: hookResult.success ? undefined : 'Hook failed',
162
+ verifiedAt: new Date().toISOString(),
163
+ };
164
+ matched = true;
165
+ break;
166
+ }
167
+ }
168
+ }
169
+ // If no hook matched, mark as requiring manual verification
170
+ if (!matched) {
171
+ const resultIndex = report.results.findIndex((r) => r.itemId === item.id);
172
+ if (resultIndex !== -1 && report.results[resultIndex].status === 'pending') {
173
+ report.results[resultIndex].method = 'manual';
174
+ }
175
+ }
176
+ }
177
+ // Update summary and status
178
+ report.summary = this.calculateSummary(report.results);
179
+ report.status = this.calculateReportStatus(report.results);
180
+ report.detectedHooks = detectedHooks;
181
+ await this.saveReport(report);
182
+ return report;
183
+ }
184
+ /**
185
+ * Match checklist item content to hook type
186
+ */
187
+ matchItemToHook(content, hookName) {
188
+ const hookKeywords = {
189
+ test: ['tests pass', 'test pass', 'all tests', 'unit test', 'test coverage'],
190
+ build: ['compiles', 'builds', 'build succeeds', 'no errors', 'runs without errors'],
191
+ lint: ['lint', 'no warnings', 'style guide', 'conventions'],
192
+ typecheck: ['typecheck', 'type check', 'type errors', 'typescript'],
193
+ };
194
+ const keywords = hookKeywords[hookName] || [];
195
+ return keywords.some((kw) => content.includes(kw));
196
+ }
197
+ /**
198
+ * Truncate output for storage
199
+ */
200
+ truncateOutput(output, maxLength = 500) {
201
+ if (output.length <= maxLength) {
202
+ return output;
203
+ }
204
+ return output.substring(0, maxLength) + '... (truncated)';
205
+ }
206
+ /**
207
+ * Calculate summary from results
208
+ */
209
+ calculateSummary(results) {
210
+ const total = results.length;
211
+ const passed = results.filter((r) => r.status === 'passed').length;
212
+ const failed = results.filter((r) => r.status === 'failed').length;
213
+ const skipped = results.filter((r) => r.status === 'skipped').length;
214
+ const notApplicable = results.filter((r) => r.status === 'not-applicable').length;
215
+ const automatedChecks = results.filter((r) => r.method === 'automated').length;
216
+ const manualChecks = results.filter((r) => r.method === 'manual' || r.method === 'semi-automated').length;
217
+ const denominator = total - skipped - notApplicable;
218
+ const coveragePercent = denominator > 0 ? Math.round((passed / denominator) * 100) : 0;
219
+ return {
220
+ total,
221
+ passed,
222
+ failed,
223
+ skipped,
224
+ notApplicable,
225
+ coveragePercent,
226
+ automatedChecks,
227
+ manualChecks,
228
+ };
229
+ }
230
+ /**
231
+ * Calculate overall report status
232
+ */
233
+ calculateReportStatus(results) {
234
+ const pending = results.filter((r) => r.status === 'pending').length;
235
+ const failed = results.filter((r) => r.status === 'failed').length;
236
+ if (pending === results.length) {
237
+ return 'pending';
238
+ }
239
+ if (pending > 0) {
240
+ return 'in-progress';
241
+ }
242
+ if (failed > 0) {
243
+ return 'requires-attention';
244
+ }
245
+ return 'completed';
246
+ }
247
+ /**
248
+ * Get pending items from report
249
+ */
250
+ getPendingItems(report) {
251
+ const pendingIds = new Set(report.results.filter((r) => r.status === 'pending').map((r) => r.itemId));
252
+ return report.items.filter((item) => pendingIds.has(item.id));
253
+ }
254
+ /**
255
+ * Get failed items from report
256
+ */
257
+ getFailedItems(report) {
258
+ return report.results
259
+ .filter((r) => r.status === 'failed')
260
+ .map((result) => ({
261
+ item: report.items.find((i) => i.id === result.itemId),
262
+ result,
263
+ }))
264
+ .filter((r) => r.item);
265
+ }
266
+ /**
267
+ * Check if verification is complete
268
+ */
269
+ isComplete(report) {
270
+ return report.status === 'completed';
271
+ }
272
+ /**
273
+ * Check if verification requires attention (has failures)
274
+ */
275
+ requiresAttention(report) {
276
+ return report.status === 'requires-attention';
277
+ }
278
+ /**
279
+ * Delete verification report
280
+ */
281
+ async deleteReport(promptId) {
282
+ for (const source of ['deep', 'fast']) {
283
+ const reportPath = this.getReportPath(promptId, source);
284
+ if (await fs.pathExists(reportPath)) {
285
+ await fs.remove(reportPath);
286
+ return true;
287
+ }
288
+ }
289
+ return false;
290
+ }
291
+ /**
292
+ * Get all verification reports
293
+ */
294
+ async listReports() {
295
+ const reports = [];
296
+ for (const source of ['deep', 'fast']) {
297
+ const sourceDir = path.join(this.outputDir, source);
298
+ if (await fs.pathExists(sourceDir)) {
299
+ const files = await fs.readdir(sourceDir);
300
+ for (const file of files) {
301
+ if (file.endsWith('.verification.json')) {
302
+ try {
303
+ const report = await fs.readJson(path.join(sourceDir, file));
304
+ reports.push(report);
305
+ }
306
+ catch {
307
+ // Ignore corrupt files
308
+ }
309
+ }
310
+ }
311
+ }
312
+ }
313
+ return reports;
314
+ }
315
+ /**
316
+ * Get verification status for a prompt
317
+ */
318
+ async getVerificationStatus(promptId) {
319
+ const report = await this.loadReport(promptId);
320
+ if (!report) {
321
+ return {
322
+ hasReport: false,
323
+ status: null,
324
+ summary: null,
325
+ };
326
+ }
327
+ return {
328
+ hasReport: true,
329
+ status: report.status,
330
+ summary: report.summary,
331
+ };
332
+ }
333
+ /**
334
+ * Format verification report for display
335
+ */
336
+ formatReportForDisplay(report) {
337
+ const lines = [];
338
+ const sep = '═'.repeat(70);
339
+ lines.push(sep);
340
+ lines.push(' VERIFICATION REPORT');
341
+ lines.push(` ${report.promptId}`);
342
+ lines.push(sep);
343
+ lines.push('');
344
+ // Group results by category
345
+ const byCategory = new Map();
346
+ for (const item of report.items) {
347
+ const result = report.results.find((r) => r.itemId === item.id);
348
+ if (!result)
349
+ continue;
350
+ const category = item.category;
351
+ if (!byCategory.has(category)) {
352
+ byCategory.set(category, []);
353
+ }
354
+ byCategory.get(category).push({ item, result });
355
+ }
356
+ // Display each category
357
+ for (const [category, items] of byCategory.entries()) {
358
+ const categoryName = category === 'validation'
359
+ ? 'VALIDATION CHECKLIST'
360
+ : category === 'edge-case'
361
+ ? 'EDGE CASES'
362
+ : 'RISKS';
363
+ lines.push(`📋 ${categoryName} (${items.length} items)`);
364
+ lines.push('');
365
+ for (const { item, result } of items) {
366
+ const statusIcon = this.getStatusIcon(result.status);
367
+ const method = result.method === 'automated'
368
+ ? '[automated]'
369
+ : result.method === 'semi-automated'
370
+ ? '[semi-auto]'
371
+ : '[manual]';
372
+ lines.push(`${statusIcon} ${method} ${item.content}`);
373
+ if (result.evidence) {
374
+ lines.push(` Evidence: ${result.evidence.substring(0, 80)}`);
375
+ }
376
+ if (result.status === 'failed' && result.reason) {
377
+ lines.push(` Reason: ${result.reason}`);
378
+ }
379
+ if (result.confidence) {
380
+ lines.push(` Confidence: ${result.confidence.toUpperCase()}`);
381
+ }
382
+ lines.push('');
383
+ }
384
+ }
385
+ // Summary
386
+ lines.push(sep);
387
+ lines.push(' SUMMARY');
388
+ lines.push(sep);
389
+ lines.push(`Total: ${report.summary.total} items`);
390
+ lines.push(`Passed: ${report.summary.passed} (${report.summary.coveragePercent}%)`);
391
+ lines.push(`Failed: ${report.summary.failed}${report.summary.failed > 0 ? ' (requires attention)' : ''}`);
392
+ lines.push(`Skipped: ${report.summary.skipped}`);
393
+ lines.push('');
394
+ lines.push(`Automated: ${report.summary.automatedChecks} checks`);
395
+ lines.push(`Manual: ${report.summary.manualChecks} checks`);
396
+ if (report.summary.failed > 0) {
397
+ lines.push('');
398
+ lines.push(`⚠️ ${report.summary.failed} item(s) require attention before marking complete`);
399
+ }
400
+ lines.push(sep);
401
+ return lines.join('\n');
402
+ }
403
+ /**
404
+ * Get status icon for display
405
+ */
406
+ getStatusIcon(status) {
407
+ switch (status) {
408
+ case 'passed':
409
+ return '✅';
410
+ case 'failed':
411
+ return '❌';
412
+ case 'skipped':
413
+ return '⏭️';
414
+ case 'not-applicable':
415
+ return '➖';
416
+ case 'pending':
417
+ default:
418
+ return '⏳';
419
+ }
420
+ }
421
+ }
422
+ //# sourceMappingURL=verification-manager.js.map
@@ -4,18 +4,25 @@ This guide is for agents that can only read documentation (no slash-command supp
4
4
 
5
5
  ---
6
6
 
7
- ## CLAVIX PLANNING MODE
7
+ ## CLAVIX MODE ENFORCEMENT (v4.7)
8
8
 
9
- **You are in Clavix prompt/PRD development mode. You help create planning documents, NOT implement features.**
9
+ **CRITICAL: Know which mode you're in and STOP at the right point.**
10
10
 
11
- **PLANNING workflows** (requirements & documentation):
12
- - Conversational mode, requirement extraction, fast/deep optimization, PRD generation
11
+ **OPTIMIZATION workflows** (NO CODE ALLOWED):
12
+ - Fast/deep optimization - Prompt improvement only
13
+ - Your role: Analyze, optimize, show improved prompt, **STOP**
14
+ - ❌ DO NOT implement the prompt's requirements
15
+ - ✅ After showing optimized prompt, tell user: "Run `/clavix:execute --latest` to implement"
16
+
17
+ **PLANNING workflows** (NO CODE ALLOWED):
18
+ - Conversational mode, requirement extraction, PRD generation
13
19
  - Your role: Ask questions, create PRDs/prompts, extract requirements
14
- - DO NOT implement features during these workflows
20
+ - DO NOT implement features during these workflows
15
21
 
16
- **IMPLEMENTATION workflows** (code execution):
17
- - Only when user explicitly says: "Now implement this" or "Build the feature"
22
+ **IMPLEMENTATION workflows** (CODE ALLOWED):
23
+ - Only after user runs execute/implement commands
18
24
  - Your role: Write code, execute tasks, implement features
25
+ - ✅ DO implement code during these workflows
19
26
 
20
27
  **If unsure, ASK:** "Should I implement this now, or continue with planning?"
21
28
 
@@ -4,18 +4,25 @@ These instructions enhance GitHub Copilot's understanding of Clavix Intelligence
4
4
 
5
5
  ---
6
6
 
7
- ## CLAVIX PLANNING MODE
7
+ ## CLAVIX MODE ENFORCEMENT (v4.7)
8
8
 
9
- **You are in Clavix prompt/PRD development mode. You help create planning documents, NOT implement features.**
9
+ **CRITICAL: Know which mode you're in and STOP at the right point.**
10
10
 
11
- **PLANNING workflows** (requirements & documentation):
12
- - Conversational mode, requirement extraction, fast/deep optimization, PRD generation
11
+ **OPTIMIZATION workflows** (NO CODE ALLOWED):
12
+ - Fast/deep optimization - Prompt improvement only
13
+ - Your role: Analyze, optimize, show improved prompt, **STOP**
14
+ - ❌ DO NOT implement the prompt's requirements
15
+ - ✅ After showing optimized prompt, tell user: "Run `/clavix:execute --latest` to implement"
16
+
17
+ **PLANNING workflows** (NO CODE ALLOWED):
18
+ - Conversational mode, requirement extraction, PRD generation
13
19
  - Your role: Ask questions, create PRDs/prompts, extract requirements
14
- - DO NOT implement features during these workflows
20
+ - DO NOT implement features during these workflows
15
21
 
16
- **IMPLEMENTATION workflows** (code execution):
17
- - Only when user explicitly says: "Now implement this" or "Build the feature"
22
+ **IMPLEMENTATION workflows** (CODE ALLOWED):
23
+ - Only after user runs execute/implement commands
18
24
  - Your role: Write code, execute tasks, implement features
25
+ - ✅ DO implement code during these workflows
19
26
 
20
27
  **If unsure, ASK:** "Should I implement this now, or continue with planning?"
21
28
 
@@ -4,19 +4,25 @@ Clavix workflows optimized for Octofriend's capabilities: model switching, multi
4
4
 
5
5
  ---
6
6
 
7
- ## CLAVIX PLANNING MODE
7
+ ## CLAVIX MODE ENFORCEMENT (v4.7)
8
8
 
9
- **Know which mode you're in:**
9
+ **CRITICAL: Know which mode you're in and STOP at the right point.**
10
10
 
11
- **PLANNING workflows** (requirements & documentation):
12
- - start, summarize, fast, deep, prd, plan
11
+ **OPTIMIZATION workflows** (NO CODE ALLOWED):
12
+ - `/clavix:fast`, `/clavix:deep` - Prompt optimization only
13
+ - Your role: Analyze, optimize, show improved prompt, **STOP**
14
+ - ❌ DO NOT implement the prompt's requirements
15
+ - ✅ After showing optimized prompt, tell user: "Run `/clavix:execute --latest` to implement"
16
+
17
+ **PLANNING workflows** (NO CODE ALLOWED):
18
+ - `/clavix:start`, `/clavix:summarize`, `/clavix:prd`, `/clavix:plan`
13
19
  - Your role: Ask questions, create PRDs/prompts, extract requirements
14
- - **DO NOT implement features during these workflows**
20
+ - DO NOT implement features during these workflows
15
21
 
16
- **IMPLEMENTATION workflows** (code execution):
17
- - implement, execute, task-complete
22
+ **IMPLEMENTATION workflows** (CODE ALLOWED):
23
+ - `/clavix:implement`, `/clavix:execute`, `clavix task-complete`
18
24
  - Your role: Write code, execute tasks, implement features
19
- - **DO implement code during these workflows**
25
+ - DO implement code during these workflows
20
26
 
21
27
  See `.clavix/instructions/core/clavix-mode.md` for complete mode documentation.
22
28
 
@@ -4,20 +4,25 @@ Clavix helps Warp developers turn rough ideas into quality, AI-ready prompts and
4
4
 
5
5
  ---
6
6
 
7
- ### ⚠️ CLAVIX MODE: Requirements & Planning Only
7
+ ### CLAVIX MODE ENFORCEMENT (v4.7)
8
8
 
9
- **When using Clavix workflows, you are in PLANNING mode, NOT implementation mode.**
9
+ **CRITICAL: Know which mode you're in and STOP at the right point.**
10
10
 
11
- **YOUR ROLE:**
12
- - Generate PRDs and prompts
13
- - Extract requirements
14
- - Optimize prompt quality
11
+ **OPTIMIZATION workflows** (NO CODE ALLOWED):
12
+ - Fast/deep optimization - Prompt improvement only
13
+ - Your role: Analyze, optimize, show improved prompt, **STOP**
14
+ - DO NOT implement the prompt's requirements
15
+ - ✅ After showing optimized prompt, tell user: "Run `/clavix:execute --latest` to implement"
15
16
 
16
- **DO NOT IMPLEMENT. DO NOT IMPLEMENT. DO NOT IMPLEMENT.**
17
- - DO NOT write application code during Clavix workflows
18
- - DO NOT implement features being planned
17
+ **PLANNING workflows** (NO CODE ALLOWED):
18
+ - Conversational mode, requirement extraction, PRD generation
19
+ - Your role: Ask questions, create PRDs/prompts, extract requirements
20
+ - ❌ DO NOT implement features during these workflows
19
21
 
20
- **ONLY implement if user explicitly says: "Now implement this"**
22
+ **IMPLEMENTATION workflows** (CODE ALLOWED):
23
+ - Only after user runs execute/implement commands
24
+ - Your role: Write code, execute tasks, implement features
25
+ - ✅ DO implement code during these workflows
21
26
 
22
27
  See `.clavix/instructions/core/clavix-mode.md` for complete mode documentation.
23
28
 
@@ -158,21 +158,22 @@ Fast/deep prompts from `/clavix:fast` and `/clavix:deep` are stored separately i
158
158
 
159
159
  **Prompts are NOT archived with PRD projects.**
160
160
 
161
- **Manage prompts separately:**
161
+ **Manage prompts separately (CLI commands):**
162
162
  ```bash
163
163
  clavix prompts list # View all prompts
164
- clavix prompts clear # Cleanup prompts
165
- /clavix:prompts # Full management workflow
164
+ clavix prompts clear # Interactive cleanup
165
+ clavix prompts clear --executed # Remove executed only
166
+ clavix prompts clear --stale # Remove >30 day old
166
167
  ```
167
168
 
168
169
  **Before archiving, consider cleanup:**
169
170
  ```bash
170
- /clavix:prompts clear --executed
171
+ clavix prompts clear --executed
171
172
  ```
172
173
 
173
174
  **Prompts lifecycle:**
174
175
  - Independent from PRD lifecycle
175
- - Managed via `/clavix:prompts`
176
+ - Managed via CLI commands
176
177
  - Clear manually when project complete
177
178
 
178
179
  ## Example Workflows