clavix 4.12.0 → 5.0.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.
- package/README.md +69 -61
- package/dist/templates/slash-commands/_canonical/archive.md +83 -121
- package/dist/templates/slash-commands/_canonical/execute.md +32 -42
- package/dist/templates/slash-commands/_canonical/implement.md +32 -44
- package/dist/templates/slash-commands/_canonical/improve.md +13 -52
- package/dist/templates/slash-commands/_components/agent-protocols/cli-reference.md +84 -180
- package/dist/templates/slash-commands/_components/agent-protocols/error-handling.md +2 -2
- package/dist/templates/slash-commands/_components/agent-protocols/file-formats.md +41 -59
- package/dist/templates/slash-commands/_components/sections/file-saving-protocol.md +20 -27
- package/dist/templates/slash-commands/_components/troubleshooting/file-not-saved.md +4 -5
- package/package.json +2 -2
- package/dist/cli/commands/analyze.d.ts +0 -17
- package/dist/cli/commands/analyze.js +0 -133
- package/dist/cli/commands/archive.d.ts +0 -36
- package/dist/cli/commands/archive.js +0 -266
- package/dist/cli/commands/deep.d.ts +0 -17
- package/dist/cli/commands/deep.js +0 -170
- package/dist/cli/commands/execute.d.ts +0 -15
- package/dist/cli/commands/execute.js +0 -168
- package/dist/cli/commands/fast.d.ts +0 -18
- package/dist/cli/commands/fast.js +0 -219
- package/dist/cli/commands/implement.d.ts +0 -24
- package/dist/cli/commands/implement.js +0 -289
- package/dist/cli/commands/improve.d.ts +0 -32
- package/dist/cli/commands/improve.js +0 -250
- package/dist/cli/commands/list.d.ts +0 -17
- package/dist/cli/commands/list.js +0 -217
- package/dist/cli/commands/plan.d.ts +0 -21
- package/dist/cli/commands/plan.js +0 -297
- package/dist/cli/commands/prd.d.ts +0 -24
- package/dist/cli/commands/prd.js +0 -321
- package/dist/cli/commands/prompts/clear.d.ts +0 -16
- package/dist/cli/commands/prompts/clear.js +0 -222
- package/dist/cli/commands/prompts/list.d.ts +0 -8
- package/dist/cli/commands/prompts/list.js +0 -88
- package/dist/cli/commands/show.d.ts +0 -21
- package/dist/cli/commands/show.js +0 -191
- package/dist/cli/commands/start.d.ts +0 -40
- package/dist/cli/commands/start.js +0 -210
- package/dist/cli/commands/summarize.d.ts +0 -17
- package/dist/cli/commands/summarize.js +0 -196
- package/dist/cli/commands/task-complete.d.ts +0 -27
- package/dist/cli/commands/task-complete.js +0 -269
- package/dist/cli/commands/verify.d.ts +0 -28
- package/dist/cli/commands/verify.js +0 -349
- package/dist/core/archive-manager.d.ts +0 -100
- package/dist/core/archive-manager.js +0 -302
- package/dist/core/basic-checklist-generator.d.ts +0 -35
- package/dist/core/basic-checklist-generator.js +0 -344
- package/dist/core/checklist-parser.d.ts +0 -48
- package/dist/core/checklist-parser.js +0 -238
- package/dist/core/config-manager.d.ts +0 -149
- package/dist/core/config-manager.js +0 -230
- package/dist/core/conversation-analyzer.d.ts +0 -86
- package/dist/core/conversation-analyzer.js +0 -387
- package/dist/core/conversation-quality-tracker.d.ts +0 -81
- package/dist/core/conversation-quality-tracker.js +0 -195
- package/dist/core/git-manager.d.ts +0 -126
- package/dist/core/git-manager.js +0 -282
- package/dist/core/intelligence/confidence-calculator.d.ts +0 -93
- package/dist/core/intelligence/confidence-calculator.js +0 -124
- package/dist/core/intelligence/index.d.ts +0 -11
- package/dist/core/intelligence/index.js +0 -15
- package/dist/core/intelligence/intent-detector.d.ts +0 -54
- package/dist/core/intelligence/intent-detector.js +0 -723
- package/dist/core/intelligence/pattern-library.d.ts +0 -104
- package/dist/core/intelligence/pattern-library.js +0 -330
- package/dist/core/intelligence/patterns/actionability-enhancer.d.ts +0 -27
- package/dist/core/intelligence/patterns/actionability-enhancer.js +0 -192
- package/dist/core/intelligence/patterns/alternative-phrasing-generator.d.ts +0 -29
- package/dist/core/intelligence/patterns/alternative-phrasing-generator.js +0 -239
- package/dist/core/intelligence/patterns/ambiguity-detector.d.ts +0 -22
- package/dist/core/intelligence/patterns/ambiguity-detector.js +0 -196
- package/dist/core/intelligence/patterns/assumption-explicitizer.d.ts +0 -30
- package/dist/core/intelligence/patterns/assumption-explicitizer.js +0 -296
- package/dist/core/intelligence/patterns/base-pattern.d.ts +0 -192
- package/dist/core/intelligence/patterns/base-pattern.js +0 -103
- package/dist/core/intelligence/patterns/completeness-validator.d.ts +0 -27
- package/dist/core/intelligence/patterns/completeness-validator.js +0 -221
- package/dist/core/intelligence/patterns/conciseness-filter.d.ts +0 -20
- package/dist/core/intelligence/patterns/conciseness-filter.js +0 -92
- package/dist/core/intelligence/patterns/context-precision.d.ts +0 -32
- package/dist/core/intelligence/patterns/context-precision.js +0 -389
- package/dist/core/intelligence/patterns/conversation-summarizer.d.ts +0 -30
- package/dist/core/intelligence/patterns/conversation-summarizer.js +0 -277
- package/dist/core/intelligence/patterns/dependency-identifier.d.ts +0 -23
- package/dist/core/intelligence/patterns/dependency-identifier.js +0 -166
- package/dist/core/intelligence/patterns/domain-context-enricher.d.ts +0 -21
- package/dist/core/intelligence/patterns/domain-context-enricher.js +0 -198
- package/dist/core/intelligence/patterns/edge-case-identifier.d.ts +0 -30
- package/dist/core/intelligence/patterns/edge-case-identifier.js +0 -269
- package/dist/core/intelligence/patterns/error-tolerance-enhancer.d.ts +0 -22
- package/dist/core/intelligence/patterns/error-tolerance-enhancer.js +0 -179
- package/dist/core/intelligence/patterns/implicit-requirement-extractor.d.ts +0 -24
- package/dist/core/intelligence/patterns/implicit-requirement-extractor.js +0 -259
- package/dist/core/intelligence/patterns/objective-clarifier.d.ts +0 -22
- package/dist/core/intelligence/patterns/objective-clarifier.js +0 -126
- package/dist/core/intelligence/patterns/output-format-enforcer.d.ts +0 -22
- package/dist/core/intelligence/patterns/output-format-enforcer.js +0 -151
- package/dist/core/intelligence/patterns/prd-structure-enforcer.d.ts +0 -23
- package/dist/core/intelligence/patterns/prd-structure-enforcer.js +0 -183
- package/dist/core/intelligence/patterns/prerequisite-identifier.d.ts +0 -23
- package/dist/core/intelligence/patterns/prerequisite-identifier.js +0 -221
- package/dist/core/intelligence/patterns/requirement-prioritizer.d.ts +0 -24
- package/dist/core/intelligence/patterns/requirement-prioritizer.js +0 -134
- package/dist/core/intelligence/patterns/scope-definer.d.ts +0 -26
- package/dist/core/intelligence/patterns/scope-definer.js +0 -236
- package/dist/core/intelligence/patterns/step-decomposer.d.ts +0 -31
- package/dist/core/intelligence/patterns/step-decomposer.js +0 -242
- package/dist/core/intelligence/patterns/structure-organizer.d.ts +0 -31
- package/dist/core/intelligence/patterns/structure-organizer.js +0 -218
- package/dist/core/intelligence/patterns/success-criteria-enforcer.d.ts +0 -22
- package/dist/core/intelligence/patterns/success-criteria-enforcer.js +0 -165
- package/dist/core/intelligence/patterns/success-metrics-enforcer.d.ts +0 -24
- package/dist/core/intelligence/patterns/success-metrics-enforcer.js +0 -165
- package/dist/core/intelligence/patterns/technical-context-enricher.d.ts +0 -25
- package/dist/core/intelligence/patterns/technical-context-enricher.js +0 -165
- package/dist/core/intelligence/patterns/topic-coherence-analyzer.d.ts +0 -26
- package/dist/core/intelligence/patterns/topic-coherence-analyzer.js +0 -300
- package/dist/core/intelligence/patterns/user-persona-enricher.d.ts +0 -24
- package/dist/core/intelligence/patterns/user-persona-enricher.js +0 -141
- package/dist/core/intelligence/patterns/validation-checklist-creator.d.ts +0 -31
- package/dist/core/intelligence/patterns/validation-checklist-creator.js +0 -242
- package/dist/core/intelligence/quality-assessor.d.ts +0 -71
- package/dist/core/intelligence/quality-assessor.js +0 -525
- package/dist/core/intelligence/types.d.ts +0 -111
- package/dist/core/intelligence/types.js +0 -3
- package/dist/core/intelligence/universal-optimizer.d.ts +0 -91
- package/dist/core/intelligence/universal-optimizer.js +0 -399
- package/dist/core/prd-generator.d.ts +0 -76
- package/dist/core/prd-generator.js +0 -173
- package/dist/core/prompt-manager.d.ts +0 -110
- package/dist/core/prompt-manager.js +0 -274
- package/dist/core/prompt-optimizer.d.ts +0 -268
- package/dist/core/prompt-optimizer.js +0 -959
- package/dist/core/question-engine.d.ts +0 -167
- package/dist/core/question-engine.js +0 -356
- package/dist/core/session-manager.d.ts +0 -139
- package/dist/core/session-manager.js +0 -365
- package/dist/core/task-manager.d.ts +0 -211
- package/dist/core/task-manager.js +0 -981
- package/dist/core/verification-hooks.d.ts +0 -67
- package/dist/core/verification-hooks.js +0 -309
- package/dist/core/verification-manager.d.ts +0 -107
- package/dist/core/verification-manager.js +0 -415
- package/dist/index 2.js +0 -13
- package/dist/index.d 2.ts +0 -4
- package/dist/types/session.d.ts +0 -78
- package/dist/types/session.js +0 -8
- package/dist/types/verification.d.ts +0 -205
- package/dist/types/verification.js +0 -9
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
import { Command, Flags, Args } from '@oclif/core';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { TaskManager } from '../../core/task-manager.js';
|
|
4
|
-
import { ConfigManager } from '../../core/config-manager.js';
|
|
5
|
-
import { GitManager } from '../../core/git-manager.js';
|
|
6
|
-
import * as path from 'path';
|
|
7
|
-
import fs from 'fs-extra';
|
|
8
|
-
export default class TaskComplete extends Command {
|
|
9
|
-
static description = 'Mark a task as completed with validation and optional git commit';
|
|
10
|
-
static examples = [
|
|
11
|
-
'<%= config.bin %> <%= command.id %> phase-1-auth-1',
|
|
12
|
-
'<%= config.bin %> <%= command.id %> phase-2-api-3 --no-git',
|
|
13
|
-
'<%= config.bin %> <%= command.id %> setup-1 --force',
|
|
14
|
-
];
|
|
15
|
-
static args = {
|
|
16
|
-
taskId: Args.string({
|
|
17
|
-
description: 'Task ID to mark as completed',
|
|
18
|
-
required: true,
|
|
19
|
-
}),
|
|
20
|
-
};
|
|
21
|
-
static flags = {
|
|
22
|
-
'no-git': Flags.boolean({
|
|
23
|
-
description: 'Skip git commit even if strategy is enabled',
|
|
24
|
-
default: false,
|
|
25
|
-
}),
|
|
26
|
-
force: Flags.boolean({
|
|
27
|
-
char: 'f',
|
|
28
|
-
description: 'Force completion even if already marked complete',
|
|
29
|
-
default: false,
|
|
30
|
-
}),
|
|
31
|
-
config: Flags.string({
|
|
32
|
-
char: 'c',
|
|
33
|
-
description: 'Path to config file (defaults to auto-discover)',
|
|
34
|
-
}),
|
|
35
|
-
};
|
|
36
|
-
async run() {
|
|
37
|
-
const { args, flags } = await this.parse(TaskComplete);
|
|
38
|
-
const taskId = args.taskId;
|
|
39
|
-
console.log(chalk.bold.cyan(`\nTask Completion: ${taskId}\n`));
|
|
40
|
-
try {
|
|
41
|
-
const taskManager = new TaskManager();
|
|
42
|
-
const configManager = new ConfigManager();
|
|
43
|
-
const gitManager = new GitManager();
|
|
44
|
-
// Find config file
|
|
45
|
-
const configPath = await this.findConfigFile(flags.config);
|
|
46
|
-
console.log(chalk.dim(`Config: ${configPath}\n`));
|
|
47
|
-
// Read config
|
|
48
|
-
const config = await configManager.read(configPath);
|
|
49
|
-
const tasksPath = config.tasksPath;
|
|
50
|
-
// Read tasks
|
|
51
|
-
const phases = await taskManager.readTasksFile(tasksPath);
|
|
52
|
-
// Validate task exists
|
|
53
|
-
const task = taskManager.validateTaskExists(phases, taskId);
|
|
54
|
-
if (!task) {
|
|
55
|
-
// Smart recovery: List available tasks
|
|
56
|
-
console.log(chalk.red(`✗ Task ID "${taskId}" not found\n`));
|
|
57
|
-
console.log(chalk.yellow('Available task IDs:\n'));
|
|
58
|
-
phases.forEach(phase => {
|
|
59
|
-
console.log(chalk.bold(` ${phase.name}:`));
|
|
60
|
-
phase.tasks.forEach(t => {
|
|
61
|
-
const status = t.completed ? chalk.green('[x]') : chalk.gray('[ ]');
|
|
62
|
-
console.log(` ${status} ${chalk.cyan(t.id)} - ${t.description}`);
|
|
63
|
-
});
|
|
64
|
-
console.log();
|
|
65
|
-
});
|
|
66
|
-
this.error('Task not found. Please use one of the task IDs listed above.');
|
|
67
|
-
}
|
|
68
|
-
// Check if already completed
|
|
69
|
-
if (task.completed && !flags.force) {
|
|
70
|
-
console.log(chalk.yellow(`⚠ Task "${taskId}" is already marked as completed\n`));
|
|
71
|
-
// Check if it's in config too
|
|
72
|
-
const isInConfig = await configManager.isTaskCompleted(configPath, taskId);
|
|
73
|
-
if (isInConfig) {
|
|
74
|
-
console.log(chalk.dim('Task is tracked in config as completed.\n'));
|
|
75
|
-
}
|
|
76
|
-
console.log(chalk.gray('Use --force to re-mark this task as completed.\n'));
|
|
77
|
-
// Show next task
|
|
78
|
-
await this.showNextTask(taskManager, phases);
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
// Mark task as completed with validation
|
|
82
|
-
console.log(chalk.dim('Marking task as completed...'));
|
|
83
|
-
const result = await taskManager.markTaskCompletedWithValidation(tasksPath, taskId);
|
|
84
|
-
if (!result.success) {
|
|
85
|
-
// Smart recovery: Show error and suggestions
|
|
86
|
-
console.log(chalk.red(`\n✗ Failed to mark task as completed\n`));
|
|
87
|
-
console.log(chalk.yellow(`Error: ${result.error}\n`));
|
|
88
|
-
if (result.warnings && result.warnings.length > 0) {
|
|
89
|
-
console.log(chalk.yellow('Warnings:'));
|
|
90
|
-
result.warnings.forEach(warning => console.log(chalk.yellow(` • ${warning}`)));
|
|
91
|
-
console.log();
|
|
92
|
-
}
|
|
93
|
-
// Provide recovery suggestions
|
|
94
|
-
console.log(chalk.bold('Recovery Options:\n'));
|
|
95
|
-
console.log(chalk.gray(' 1. Check if tasks.md file is readable and writable'));
|
|
96
|
-
console.log(chalk.gray(' 2. Verify task ID matches exactly (run "clavix implement" to see current task)'));
|
|
97
|
-
console.log(chalk.gray(' 3. Try running with --force flag if task is already completed'));
|
|
98
|
-
console.log(chalk.gray(' 4. Check tasks.md.backup file if one was created\n'));
|
|
99
|
-
this.error('Task completion failed');
|
|
100
|
-
}
|
|
101
|
-
// Display warnings if any
|
|
102
|
-
if (result.warnings && result.warnings.length > 0) {
|
|
103
|
-
console.log(chalk.yellow('\nWarnings:'));
|
|
104
|
-
result.warnings.forEach(warning => console.log(chalk.yellow(` • ${warning}`)));
|
|
105
|
-
console.log();
|
|
106
|
-
}
|
|
107
|
-
// Success!
|
|
108
|
-
if (result.alreadyCompleted) {
|
|
109
|
-
console.log(chalk.green(`✓ Task was already completed (tracking updated)\n`));
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
console.log(chalk.green(`✓ Task marked as completed\n`));
|
|
113
|
-
}
|
|
114
|
-
// Re-read tasks file to get updated state (CRITICAL: phases object is stale)
|
|
115
|
-
const updatedPhases = await taskManager.readTasksFile(tasksPath);
|
|
116
|
-
// Track completion in config
|
|
117
|
-
console.log(chalk.dim('Updating configuration...'));
|
|
118
|
-
await configManager.trackCompletion(configPath, taskId);
|
|
119
|
-
// Update stats
|
|
120
|
-
const updatedStats = taskManager.getTaskStats(updatedPhases);
|
|
121
|
-
await configManager.update(configPath, { stats: updatedStats });
|
|
122
|
-
console.log(chalk.green('✓ Configuration updated\n'));
|
|
123
|
-
// Show progress
|
|
124
|
-
console.log(chalk.bold('Progress:'));
|
|
125
|
-
console.log(chalk.cyan(` Completed: ${updatedStats.completed}/${updatedStats.total} tasks (${updatedStats.percentage.toFixed(0)}%)`));
|
|
126
|
-
console.log(chalk.cyan(` Remaining: ${updatedStats.remaining} tasks\n`));
|
|
127
|
-
// Create git commit if enabled
|
|
128
|
-
if (!flags['no-git'] && config.commitStrategy !== 'none') {
|
|
129
|
-
await this.handleGitCommit(gitManager, configManager, configPath, config.commitStrategy, task, updatedPhases);
|
|
130
|
-
}
|
|
131
|
-
// Show next task
|
|
132
|
-
await this.showNextTask(taskManager, updatedPhases);
|
|
133
|
-
}
|
|
134
|
-
catch (error) {
|
|
135
|
-
const errorMessage = error instanceof Error ? error.message : 'An unexpected error occurred';
|
|
136
|
-
console.log(chalk.red(`\n✗ Error: ${errorMessage}\n`));
|
|
137
|
-
this.error(errorMessage);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Find config file (auto-discover or use provided path)
|
|
142
|
-
*/
|
|
143
|
-
async findConfigFile(providedPath) {
|
|
144
|
-
if (providedPath) {
|
|
145
|
-
if (await fs.pathExists(providedPath)) {
|
|
146
|
-
return providedPath;
|
|
147
|
-
}
|
|
148
|
-
throw new Error(`Config file not found: ${providedPath}`);
|
|
149
|
-
}
|
|
150
|
-
// Auto-discover: Look for .clavix/outputs/*/.clavix-implement-config.json
|
|
151
|
-
const outputsDir = path.join(process.cwd(), '.clavix', 'outputs');
|
|
152
|
-
if (!(await fs.pathExists(outputsDir))) {
|
|
153
|
-
throw new Error('No .clavix/outputs directory found.\n\nHint: Run "clavix implement" first to initialize');
|
|
154
|
-
}
|
|
155
|
-
// Search for config files
|
|
156
|
-
const entries = await fs.readdir(outputsDir, { withFileTypes: true });
|
|
157
|
-
const configFiles = [];
|
|
158
|
-
for (const entry of entries) {
|
|
159
|
-
if (!entry.isDirectory() || entry.name === 'archive') {
|
|
160
|
-
continue;
|
|
161
|
-
}
|
|
162
|
-
const configPath = path.join(outputsDir, entry.name, '.clavix-implement-config.json');
|
|
163
|
-
if (await fs.pathExists(configPath)) {
|
|
164
|
-
configFiles.push(configPath);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
if (configFiles.length === 0) {
|
|
168
|
-
throw new Error('No config files found.\n\nHint: Run "clavix implement" first to initialize');
|
|
169
|
-
}
|
|
170
|
-
// Use most recent config
|
|
171
|
-
const configsWithStats = await Promise.all(configFiles.map(async (filePath) => {
|
|
172
|
-
const stat = await fs.stat(filePath);
|
|
173
|
-
return { path: filePath, mtime: stat.mtime };
|
|
174
|
-
}));
|
|
175
|
-
configsWithStats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
176
|
-
return configsWithStats[0].path;
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Handle git commit based on strategy
|
|
180
|
-
*/
|
|
181
|
-
async handleGitCommit(gitManager, configManager, configPath, strategy, completedTask, phases) {
|
|
182
|
-
console.log(chalk.dim(`Checking git commit strategy (${strategy})...`));
|
|
183
|
-
const config = await configManager.read(configPath);
|
|
184
|
-
const completedCount = config.completedTaskIds?.length ?? 0;
|
|
185
|
-
let shouldCommit = false;
|
|
186
|
-
let commitMessage = '';
|
|
187
|
-
switch (strategy) {
|
|
188
|
-
case 'per-task':
|
|
189
|
-
shouldCommit = true;
|
|
190
|
-
commitMessage = `clavix: ${completedTask.description}`;
|
|
191
|
-
break;
|
|
192
|
-
case 'per-5-tasks':
|
|
193
|
-
shouldCommit = completedCount % 5 === 0;
|
|
194
|
-
if (shouldCommit) {
|
|
195
|
-
const last5 = config.completedTaskIds?.slice(-5) ?? [];
|
|
196
|
-
const taskDescriptions = phases
|
|
197
|
-
.flatMap(p => p.tasks)
|
|
198
|
-
.filter((t) => last5.includes(t.id))
|
|
199
|
-
.map((t) => t.description);
|
|
200
|
-
commitMessage = `clavix: Completed ${last5.length} tasks\n\nCompleted tasks:\n${taskDescriptions.map(d => `- ${d}`).join('\n')}`;
|
|
201
|
-
}
|
|
202
|
-
break;
|
|
203
|
-
case 'per-phase': {
|
|
204
|
-
// Check if current phase is complete
|
|
205
|
-
const currentPhase = phases.find(p => p.name === completedTask.phase);
|
|
206
|
-
if (currentPhase) {
|
|
207
|
-
const phaseComplete = currentPhase.tasks.every((t) => t.completed);
|
|
208
|
-
shouldCommit = phaseComplete;
|
|
209
|
-
if (shouldCommit) {
|
|
210
|
-
commitMessage = `clavix: Completed ${currentPhase.name}\n\nCompleted tasks:\n${currentPhase.tasks.map((t) => `- ${t.description}`).join('\n')}`;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
break;
|
|
214
|
-
}
|
|
215
|
-
case 'none':
|
|
216
|
-
default:
|
|
217
|
-
shouldCommit = false;
|
|
218
|
-
break;
|
|
219
|
-
}
|
|
220
|
-
if (!shouldCommit) {
|
|
221
|
-
console.log(chalk.dim('No commit needed (strategy criteria not met)\n'));
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
// Check git status
|
|
225
|
-
const gitStatus = await gitManager.validateGitSetup();
|
|
226
|
-
if (!gitStatus.isRepo) {
|
|
227
|
-
console.log(chalk.yellow('⚠ Not a git repository - skipping commit\n'));
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
if (!gitStatus.hasChanges) {
|
|
231
|
-
console.log(chalk.dim('No git changes to commit\n'));
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
// Create commit
|
|
235
|
-
console.log(chalk.dim('Creating git commit...'));
|
|
236
|
-
const fullMessage = `${commitMessage}\n\nGenerated by Clavix task-complete`;
|
|
237
|
-
const success = await gitManager.createCommit({
|
|
238
|
-
message: fullMessage,
|
|
239
|
-
description: completedTask.description,
|
|
240
|
-
projectName: path.basename(path.dirname(configPath)),
|
|
241
|
-
});
|
|
242
|
-
if (success) {
|
|
243
|
-
console.log(chalk.green('✓ Git commit created\n'));
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
console.log(chalk.yellow('⚠ Git commit failed (non-critical)\n'));
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Show next incomplete task
|
|
251
|
-
*/
|
|
252
|
-
async showNextTask(taskManager, phases) {
|
|
253
|
-
const nextTask = taskManager.findFirstIncompleteTask(phases);
|
|
254
|
-
if (!nextTask) {
|
|
255
|
-
console.log(chalk.bold.green('🎉 All tasks completed!\n'));
|
|
256
|
-
console.log(chalk.gray('Great work! All implementation tasks are done.\n'));
|
|
257
|
-
console.log(chalk.dim('Hint: Run "clavix archive" to archive this project\n'));
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
console.log(chalk.bold('Next Task:'));
|
|
261
|
-
console.log(chalk.bold.white(` ID: ${chalk.cyan(nextTask.id)}`));
|
|
262
|
-
console.log(chalk.bold.white(` ${nextTask.description}`));
|
|
263
|
-
if (nextTask.prdReference) {
|
|
264
|
-
console.log(chalk.dim(` Reference: ${nextTask.prdReference}`));
|
|
265
|
-
}
|
|
266
|
-
console.log(chalk.dim(` Phase: ${nextTask.phase}\n`));
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
//# sourceMappingURL=task-complete.js.map
|
|
@@ -1,28 +0,0 @@
|
|
|
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
|
-
standard: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
-
comprehensive: 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
|
|
@@ -1,349 +0,0 @@
|
|
|
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 improve mode';
|
|
11
|
-
static examples = [
|
|
12
|
-
'<%= config.bin %> <%= command.id %> --latest',
|
|
13
|
-
'<%= config.bin %> <%= command.id %> --latest --comprehensive',
|
|
14
|
-
'<%= config.bin %> <%= command.id %> --id comp-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
|
-
standard: Flags.boolean({
|
|
24
|
-
char: 's',
|
|
25
|
-
description: 'Filter to standard depth prompts only (use with --latest)',
|
|
26
|
-
default: false,
|
|
27
|
-
}),
|
|
28
|
-
comprehensive: Flags.boolean({
|
|
29
|
-
char: 'c',
|
|
30
|
-
description: 'Filter to comprehensive depth prompts only (use with --latest)',
|
|
31
|
-
default: false,
|
|
32
|
-
}),
|
|
33
|
-
id: Flags.string({
|
|
34
|
-
description: 'Verify specific prompt by ID',
|
|
35
|
-
}),
|
|
36
|
-
status: Flags.boolean({
|
|
37
|
-
description: 'Show verification status only',
|
|
38
|
-
default: false,
|
|
39
|
-
}),
|
|
40
|
-
'retry-failed': Flags.boolean({
|
|
41
|
-
description: 'Re-run only failed items',
|
|
42
|
-
default: false,
|
|
43
|
-
}),
|
|
44
|
-
export: Flags.string({
|
|
45
|
-
description: 'Export report format',
|
|
46
|
-
options: ['markdown', 'json'],
|
|
47
|
-
}),
|
|
48
|
-
'run-hooks': Flags.boolean({
|
|
49
|
-
description: 'Run automated hooks during verification',
|
|
50
|
-
default: true,
|
|
51
|
-
}),
|
|
52
|
-
};
|
|
53
|
-
promptManager;
|
|
54
|
-
verificationManager;
|
|
55
|
-
checklistParser;
|
|
56
|
-
basicChecklistGenerator;
|
|
57
|
-
intentDetector;
|
|
58
|
-
async run() {
|
|
59
|
-
const { flags } = await this.parse(Verify);
|
|
60
|
-
this.promptManager = new PromptManager();
|
|
61
|
-
this.verificationManager = new VerificationManager();
|
|
62
|
-
this.checklistParser = new ChecklistParser();
|
|
63
|
-
this.basicChecklistGenerator = new BasicChecklistGenerator();
|
|
64
|
-
this.intentDetector = new IntentDetector();
|
|
65
|
-
try {
|
|
66
|
-
// Get all prompts
|
|
67
|
-
const allPrompts = await this.promptManager.listPrompts();
|
|
68
|
-
if (allPrompts.length === 0) {
|
|
69
|
-
console.log(chalk.yellow('\n⚠️ No prompts found\n'));
|
|
70
|
-
console.log(chalk.cyan('Generate an optimized prompt first:'));
|
|
71
|
-
console.log(chalk.cyan(' /clavix:improve "your requirement"'));
|
|
72
|
-
console.log();
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
let selectedPrompt = null;
|
|
76
|
-
// Select prompt by ID
|
|
77
|
-
if (flags.id) {
|
|
78
|
-
selectedPrompt = allPrompts.find((p) => p.id === flags.id) || null;
|
|
79
|
-
if (!selectedPrompt) {
|
|
80
|
-
console.log(chalk.red(`\n✗ Prompt not found: ${flags.id}\n`));
|
|
81
|
-
console.log(chalk.cyan('Run clavix prompts list to see available prompts'));
|
|
82
|
-
console.log();
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// Auto-select latest with optional filtering
|
|
87
|
-
else if (flags.latest) {
|
|
88
|
-
let filtered = allPrompts;
|
|
89
|
-
// Filter by depth
|
|
90
|
-
if (flags.standard && !flags.comprehensive) {
|
|
91
|
-
filtered = allPrompts.filter((p) => p.depthUsed === 'standard');
|
|
92
|
-
}
|
|
93
|
-
else if (flags.comprehensive && !flags.standard) {
|
|
94
|
-
filtered = allPrompts.filter((p) => p.depthUsed === 'comprehensive');
|
|
95
|
-
}
|
|
96
|
-
// Filter to executed prompts preferably
|
|
97
|
-
const executedFiltered = filtered.filter((p) => p.executed);
|
|
98
|
-
if (executedFiltered.length > 0) {
|
|
99
|
-
filtered = executedFiltered;
|
|
100
|
-
}
|
|
101
|
-
if (filtered.length === 0) {
|
|
102
|
-
const depth = flags.standard ? 'standard' : flags.comprehensive ? 'comprehensive' : 'any';
|
|
103
|
-
console.log(chalk.yellow(`\n⚠️ No ${depth} prompts found\n`));
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
selectedPrompt = filtered[0];
|
|
107
|
-
}
|
|
108
|
-
// Interactive selection
|
|
109
|
-
else {
|
|
110
|
-
selectedPrompt = await this.selectPromptInteractively(allPrompts);
|
|
111
|
-
if (!selectedPrompt)
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
// Handle status-only flag
|
|
115
|
-
if (flags.status) {
|
|
116
|
-
await this.showStatus(selectedPrompt);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
// Handle export flag
|
|
120
|
-
if (flags.export) {
|
|
121
|
-
await this.exportReport(selectedPrompt, flags.export);
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
// Run verification
|
|
125
|
-
await this.runVerification(selectedPrompt, {
|
|
126
|
-
retryFailed: flags['retry-failed'],
|
|
127
|
-
runHooks: flags['run-hooks'],
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
catch (error) {
|
|
131
|
-
console.log(chalk.red(`\n✗ Error: ${error}\n`));
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
async selectPromptInteractively(prompts) {
|
|
135
|
-
console.log(chalk.bold.cyan('\n📋 Select Prompt to Verify\n'));
|
|
136
|
-
const choices = prompts.map((p) => {
|
|
137
|
-
const executed = p.executed ? chalk.green('✓') : chalk.gray('○');
|
|
138
|
-
const age = p.ageInDays === 0 ? 'today' : `${p.ageInDays}d ago`;
|
|
139
|
-
const ageColor = (p.ageInDays || 0) > 30 ? chalk.red : (p.ageInDays || 0) > 7 ? chalk.yellow : chalk.gray;
|
|
140
|
-
const depthLabel = p.depthUsed === 'comprehensive' ? 'comp' : 'std';
|
|
141
|
-
return {
|
|
142
|
-
name: `${executed} [${depthLabel}] ${p.originalPrompt.substring(0, 50)}... ${ageColor(`(${age})`)}`,
|
|
143
|
-
value: p.id,
|
|
144
|
-
short: p.id,
|
|
145
|
-
};
|
|
146
|
-
});
|
|
147
|
-
const { promptId } = await inquirer.prompt([
|
|
148
|
-
{
|
|
149
|
-
type: 'list',
|
|
150
|
-
name: 'promptId',
|
|
151
|
-
message: 'Select a prompt to verify:',
|
|
152
|
-
choices,
|
|
153
|
-
pageSize: 15,
|
|
154
|
-
},
|
|
155
|
-
]);
|
|
156
|
-
return prompts.find((p) => p.id === promptId) || null;
|
|
157
|
-
}
|
|
158
|
-
async showStatus(prompt) {
|
|
159
|
-
console.log(chalk.bold.cyan(`\n🔍 Verification Status: ${prompt.id}\n`));
|
|
160
|
-
const status = await this.verificationManager.getVerificationStatus(prompt.id);
|
|
161
|
-
if (!status.hasReport) {
|
|
162
|
-
console.log(chalk.yellow('No verification report found.'));
|
|
163
|
-
console.log(chalk.cyan('\nRun: clavix verify --latest'));
|
|
164
|
-
console.log();
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
console.log(chalk.gray(`Status: ${this.formatStatus(status.status)}`));
|
|
168
|
-
console.log();
|
|
169
|
-
if (status.summary) {
|
|
170
|
-
console.log(chalk.bold('Summary:'));
|
|
171
|
-
console.log(` Total: ${status.summary.total} items`);
|
|
172
|
-
console.log(` Passed: ${chalk.green(status.summary.passed)} (${status.summary.coveragePercent}%)`);
|
|
173
|
-
console.log(` Failed: ${chalk.red(status.summary.failed)}`);
|
|
174
|
-
console.log(` Skipped: ${chalk.gray(status.summary.skipped)}`);
|
|
175
|
-
console.log();
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
async exportReport(prompt, format) {
|
|
179
|
-
const report = await this.verificationManager.loadReport(prompt.id);
|
|
180
|
-
if (!report) {
|
|
181
|
-
console.log(chalk.yellow('No verification report found.'));
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
if (format === 'json') {
|
|
185
|
-
console.log(JSON.stringify(report, null, 2));
|
|
186
|
-
}
|
|
187
|
-
else if (format === 'markdown') {
|
|
188
|
-
console.log(this.verificationManager.formatReportForDisplay(report));
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
async runVerification(prompt, options) {
|
|
192
|
-
console.log(chalk.bold.cyan(`\n🔍 Verifying: ${prompt.id}\n`));
|
|
193
|
-
console.log(chalk.gray(`Depth: ${prompt.depthUsed}`));
|
|
194
|
-
console.log(chalk.gray(`Created: ${new Date(prompt.timestamp).toLocaleDateString()}`));
|
|
195
|
-
console.log();
|
|
196
|
-
// Load prompt content
|
|
197
|
-
const promptData = await this.promptManager.loadPrompt(prompt.id);
|
|
198
|
-
if (!promptData) {
|
|
199
|
-
console.log(chalk.red('Could not load prompt content.'));
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
// Parse checklist from prompt
|
|
203
|
-
let checklist = this.checklistParser.parse(promptData.content);
|
|
204
|
-
// Handle standard depth - generate basic checklist if none exists
|
|
205
|
-
if (!checklist.hasChecklist && prompt.depthUsed === 'standard') {
|
|
206
|
-
console.log(chalk.yellow('⚠️ No checklist found (standard depth prompt)'));
|
|
207
|
-
console.log(chalk.cyan('Generating basic checklist based on intent...\n'));
|
|
208
|
-
// Detect intent from original prompt
|
|
209
|
-
const intent = this.intentDetector.analyze(prompt.originalPrompt);
|
|
210
|
-
checklist = this.basicChecklistGenerator.generateFromPrompt(prompt.originalPrompt, intent.primaryIntent);
|
|
211
|
-
console.log(chalk.gray(`Intent: ${intent.primaryIntent} (${intent.confidence}% confidence)`));
|
|
212
|
-
console.log(chalk.gray(`Generated ${checklist.totalItems} checklist items\n`));
|
|
213
|
-
console.log(chalk.yellow('💡 For comprehensive checklists, use /clavix:improve --comprehensive\n'));
|
|
214
|
-
}
|
|
215
|
-
if (!checklist.hasChecklist) {
|
|
216
|
-
console.log(chalk.yellow('No checklist items to verify.'));
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
// Initialize or load existing report
|
|
220
|
-
let report = await this.verificationManager.loadReport(prompt.id);
|
|
221
|
-
if (!report) {
|
|
222
|
-
report = await this.verificationManager.initializeVerification(prompt.id);
|
|
223
|
-
// Update with parsed checklist if from standard depth
|
|
224
|
-
if (prompt.depthUsed === 'standard') {
|
|
225
|
-
report.items = [...checklist.validationItems, ...checklist.edgeCases, ...checklist.risks];
|
|
226
|
-
report.results = report.items.map((item) => ({
|
|
227
|
-
itemId: item.id,
|
|
228
|
-
status: 'pending',
|
|
229
|
-
method: item.verificationType === 'automated' ? 'automated' : 'manual',
|
|
230
|
-
confidence: 'low',
|
|
231
|
-
verifiedAt: '',
|
|
232
|
-
}));
|
|
233
|
-
await this.verificationManager.saveReport(report);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
// Run automated hooks if requested
|
|
237
|
-
if (options.runHooks) {
|
|
238
|
-
console.log(chalk.cyan('Running automated verification hooks...\n'));
|
|
239
|
-
report = await this.verificationManager.runAutomatedVerification(prompt.id);
|
|
240
|
-
// Display hook results
|
|
241
|
-
const automatedResults = report.results.filter((r) => r.method === 'automated' && r.status !== 'pending');
|
|
242
|
-
for (const result of automatedResults) {
|
|
243
|
-
const item = report.items.find((i) => i.id === result.itemId);
|
|
244
|
-
if (item) {
|
|
245
|
-
const icon = result.status === 'passed' ? chalk.green('✓') : chalk.red('✗');
|
|
246
|
-
console.log(`${icon} [automated] ${item.content}`);
|
|
247
|
-
if (result.evidence) {
|
|
248
|
-
console.log(chalk.gray(` Evidence: ${result.evidence.substring(0, 60)}...`));
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
if (automatedResults.length > 0) {
|
|
253
|
-
console.log();
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
// Get pending items for manual verification
|
|
257
|
-
const pendingItems = this.verificationManager.getPendingItems(report);
|
|
258
|
-
if (pendingItems.length > 0) {
|
|
259
|
-
console.log(chalk.cyan(`Manual verification needed for ${pendingItems.length} items:\n`));
|
|
260
|
-
for (const item of pendingItems) {
|
|
261
|
-
report = await this.verifyItemInteractively(report, item);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
// Show final report
|
|
265
|
-
console.log();
|
|
266
|
-
console.log(this.verificationManager.formatReportForDisplay(report));
|
|
267
|
-
// Mark prompt as verified if complete
|
|
268
|
-
if (this.verificationManager.isComplete(report)) {
|
|
269
|
-
console.log(chalk.green('\n✓ Verification complete!\n'));
|
|
270
|
-
}
|
|
271
|
-
else if (this.verificationManager.requiresAttention(report)) {
|
|
272
|
-
console.log(chalk.yellow('\n⚠️ Some items require attention.\n'));
|
|
273
|
-
console.log(chalk.cyan('Fix issues and re-run: clavix verify --retry-failed --id ' + prompt.id));
|
|
274
|
-
console.log();
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
async verifyItemInteractively(report, item) {
|
|
278
|
-
console.log(chalk.bold(`\n📋 ${item.content}`));
|
|
279
|
-
if (item.group) {
|
|
280
|
-
console.log(chalk.gray(` Category: ${item.group}`));
|
|
281
|
-
}
|
|
282
|
-
console.log();
|
|
283
|
-
const { status } = await inquirer.prompt([
|
|
284
|
-
{
|
|
285
|
-
type: 'list',
|
|
286
|
-
name: 'status',
|
|
287
|
-
message: 'Verification status:',
|
|
288
|
-
choices: [
|
|
289
|
-
{ name: '✓ Passed - Item is verified', value: 'passed' },
|
|
290
|
-
{ name: '✗ Failed - Item is not covered', value: 'failed' },
|
|
291
|
-
{ name: '⏭️ Skip - Will verify later', value: 'skipped' },
|
|
292
|
-
{ name: '➖ N/A - Does not apply', value: 'not-applicable' },
|
|
293
|
-
],
|
|
294
|
-
},
|
|
295
|
-
]);
|
|
296
|
-
let evidence;
|
|
297
|
-
let reason;
|
|
298
|
-
if (status === 'passed') {
|
|
299
|
-
const { evidenceInput } = await inquirer.prompt([
|
|
300
|
-
{
|
|
301
|
-
type: 'input',
|
|
302
|
-
name: 'evidenceInput',
|
|
303
|
-
message: 'Evidence (optional):',
|
|
304
|
-
},
|
|
305
|
-
]);
|
|
306
|
-
evidence = evidenceInput || undefined;
|
|
307
|
-
}
|
|
308
|
-
else if (status === 'failed') {
|
|
309
|
-
const { reasonInput } = await inquirer.prompt([
|
|
310
|
-
{
|
|
311
|
-
type: 'input',
|
|
312
|
-
name: 'reasonInput',
|
|
313
|
-
message: 'Why is it not covered?',
|
|
314
|
-
},
|
|
315
|
-
]);
|
|
316
|
-
reason = reasonInput || 'Not specified';
|
|
317
|
-
}
|
|
318
|
-
else if (status === 'skipped') {
|
|
319
|
-
const { reasonInput } = await inquirer.prompt([
|
|
320
|
-
{
|
|
321
|
-
type: 'input',
|
|
322
|
-
name: 'reasonInput',
|
|
323
|
-
message: 'Reason for skipping:',
|
|
324
|
-
},
|
|
325
|
-
]);
|
|
326
|
-
reason = reasonInput || 'Will verify later';
|
|
327
|
-
}
|
|
328
|
-
return this.verificationManager.markItemVerified(report.promptId, item.id, status, {
|
|
329
|
-
evidence,
|
|
330
|
-
reason,
|
|
331
|
-
confidence: 'medium',
|
|
332
|
-
method: 'manual',
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
formatStatus(status) {
|
|
336
|
-
switch (status) {
|
|
337
|
-
case 'completed':
|
|
338
|
-
return chalk.green('Completed');
|
|
339
|
-
case 'in-progress':
|
|
340
|
-
return chalk.yellow('In Progress');
|
|
341
|
-
case 'requires-attention':
|
|
342
|
-
return chalk.red('Requires Attention');
|
|
343
|
-
case 'pending':
|
|
344
|
-
default:
|
|
345
|
-
return chalk.gray('Pending');
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
//# sourceMappingURL=verify.js.map
|