clavix 2.4.3 → 2.5.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 (67) hide show
  1. package/dist/cli/commands/task-complete.d.ts +27 -0
  2. package/dist/cli/commands/task-complete.js +305 -0
  3. package/dist/core/config-manager.d.ts +149 -0
  4. package/dist/core/config-manager.js +267 -0
  5. package/dist/core/git-manager.d.ts +27 -1
  6. package/dist/core/git-manager.js +114 -10
  7. package/dist/core/task-manager.d.ts +31 -0
  8. package/dist/core/task-manager.js +142 -0
  9. package/dist/templates/slash-commands/_canonical/implement.md +86 -33
  10. package/package.json +1 -1
  11. /package/dist/{core 2/adapters → core/adapters 2}/agents-md-generator.d.ts +0 -0
  12. /package/dist/{core 2/adapters → core/adapters 2}/agents-md-generator.js +0 -0
  13. /package/dist/{core 2/adapters → core/adapters 2}/amp-adapter.d.ts +0 -0
  14. /package/dist/{core 2/adapters → core/adapters 2}/amp-adapter.js +0 -0
  15. /package/dist/{core 2/adapters → core/adapters 2}/augment-adapter.d.ts +0 -0
  16. /package/dist/{core 2/adapters → core/adapters 2}/augment-adapter.js +0 -0
  17. /package/dist/{core 2/adapters → core/adapters 2}/base-adapter.d.ts +0 -0
  18. /package/dist/{core 2/adapters → core/adapters 2}/base-adapter.js +0 -0
  19. /package/dist/{core 2/adapters → core/adapters 2}/claude-code-adapter.d.ts +0 -0
  20. /package/dist/{core 2/adapters → core/adapters 2}/claude-code-adapter.js +0 -0
  21. /package/dist/{core 2/adapters → core/adapters 2}/cline-adapter.d.ts +0 -0
  22. /package/dist/{core 2/adapters → core/adapters 2}/cline-adapter.js +0 -0
  23. /package/dist/{core 2/adapters → core/adapters 2}/codebuddy-adapter.d.ts +0 -0
  24. /package/dist/{core 2/adapters → core/adapters 2}/codebuddy-adapter.js +0 -0
  25. /package/dist/{core 2/adapters → core/adapters 2}/codex-adapter.d.ts +0 -0
  26. /package/dist/{core 2/adapters → core/adapters 2}/codex-adapter.js +0 -0
  27. /package/dist/{core 2/adapters → core/adapters 2}/copilot-instructions-generator.d.ts +0 -0
  28. /package/dist/{core 2/adapters → core/adapters 2}/copilot-instructions-generator.js +0 -0
  29. /package/dist/{core 2/adapters → core/adapters 2}/crush-adapter.d.ts +0 -0
  30. /package/dist/{core 2/adapters → core/adapters 2}/crush-adapter.js +0 -0
  31. /package/dist/{core 2/adapters → core/adapters 2}/cursor-adapter.d.ts +0 -0
  32. /package/dist/{core 2/adapters → core/adapters 2}/cursor-adapter.js +0 -0
  33. /package/dist/{core 2/adapters → core/adapters 2}/droid-adapter.d.ts +0 -0
  34. /package/dist/{core 2/adapters → core/adapters 2}/droid-adapter.js +0 -0
  35. /package/dist/{core 2/adapters → core/adapters 2}/gemini-adapter.d.ts +0 -0
  36. /package/dist/{core 2/adapters → core/adapters 2}/gemini-adapter.js +0 -0
  37. /package/dist/{core 2/adapters → core/adapters 2}/kilocode-adapter.d.ts +0 -0
  38. /package/dist/{core 2/adapters → core/adapters 2}/kilocode-adapter.js +0 -0
  39. /package/dist/{core 2/adapters → core/adapters 2}/octo-md-generator.d.ts +0 -0
  40. /package/dist/{core 2/adapters → core/adapters 2}/octo-md-generator.js +0 -0
  41. /package/dist/{core 2/adapters → core/adapters 2}/opencode-adapter.d.ts +0 -0
  42. /package/dist/{core 2/adapters → core/adapters 2}/opencode-adapter.js +0 -0
  43. /package/dist/{core 2/adapters → core/adapters 2}/qwen-adapter.d.ts +0 -0
  44. /package/dist/{core 2/adapters → core/adapters 2}/qwen-adapter.js +0 -0
  45. /package/dist/{core 2/adapters → core/adapters 2}/roocode-adapter.d.ts +0 -0
  46. /package/dist/{core 2/adapters → core/adapters 2}/roocode-adapter.js +0 -0
  47. /package/dist/{core 2/adapters → core/adapters 2}/warp-md-generator.d.ts +0 -0
  48. /package/dist/{core 2/adapters → core/adapters 2}/warp-md-generator.js +0 -0
  49. /package/dist/{core 2/adapters → core/adapters 2}/windsurf-adapter.d.ts +0 -0
  50. /package/dist/{core 2/adapters → core/adapters 2}/windsurf-adapter.js +0 -0
  51. /package/dist/{core 2/agent-manager.js → core/agent-manager 2.js} +0 -0
  52. /package/dist/{core 2/agent-manager.d.ts → core/agent-manager.d 2.ts} +0 -0
  53. /package/dist/{core 2/archive-manager.js → core/archive-manager 2.js} +0 -0
  54. /package/dist/{core 2/archive-manager.d.ts → core/archive-manager.d 2.ts} +0 -0
  55. /package/dist/{core 2/conversation-analyzer.d.ts → core/conversation-analyzer.d 2.ts} +0 -0
  56. /package/dist/{core 2/doc-injector.js → core/doc-injector 2.js} +0 -0
  57. /package/dist/{core 2/doc-injector.d.ts → core/doc-injector.d 2.ts} +0 -0
  58. /package/dist/{core 2/git-manager.js → core/git-manager 2.js} +0 -0
  59. /package/dist/{core 2/git-manager.d.ts → core/git-manager.d 2.ts} +0 -0
  60. /package/dist/{core 2/prompt-optimizer.js → core/prompt-optimizer 2.js} +0 -0
  61. /package/dist/{core 2/prompt-optimizer.d.ts → core/prompt-optimizer.d 2.ts} +0 -0
  62. /package/dist/{core 2/question-engine.js → core/question-engine 2.js} +0 -0
  63. /package/dist/{core 2/question-engine.d.ts → core/question-engine.d 2.ts} +0 -0
  64. /package/dist/{core 2/session-manager.js → core/session-manager 2.js} +0 -0
  65. /package/dist/{core 2/session-manager.d.ts → core/session-manager.d 2.ts} +0 -0
  66. /package/dist/{core 2/task-manager.js → core/task-manager 2.js} +0 -0
  67. /package/dist/{core 2/task-manager.d.ts → core/task-manager.d 2.ts} +0 -0
@@ -0,0 +1,27 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class TaskComplete extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ taskId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ 'no-git': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
+ config: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
+ };
13
+ run(): Promise<void>;
14
+ /**
15
+ * Find config file (auto-discover or use provided path)
16
+ */
17
+ private findConfigFile;
18
+ /**
19
+ * Handle git commit based on strategy
20
+ */
21
+ private handleGitCommit;
22
+ /**
23
+ * Show next incomplete task
24
+ */
25
+ private showNextTask;
26
+ }
27
+ //# sourceMappingURL=task-complete.d.ts.map
@@ -0,0 +1,305 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const core_1 = require("@oclif/core");
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const task_manager_1 = require("../../core/task-manager");
42
+ const config_manager_1 = require("../../core/config-manager");
43
+ const git_manager_1 = require("../../core/git-manager");
44
+ const path = __importStar(require("path"));
45
+ const fs = __importStar(require("fs-extra"));
46
+ class TaskComplete extends core_1.Command {
47
+ async run() {
48
+ const { args, flags } = await this.parse(TaskComplete);
49
+ const taskId = args.taskId;
50
+ console.log(chalk_1.default.bold.cyan(`\nTask Completion: ${taskId}\n`));
51
+ try {
52
+ const taskManager = new task_manager_1.TaskManager();
53
+ const configManager = new config_manager_1.ConfigManager();
54
+ const gitManager = new git_manager_1.GitManager();
55
+ // Find config file
56
+ const configPath = await this.findConfigFile(flags.config);
57
+ console.log(chalk_1.default.dim(`Config: ${configPath}\n`));
58
+ // Read config
59
+ const config = await configManager.read(configPath);
60
+ const tasksPath = config.tasksPath;
61
+ // Read tasks
62
+ const phases = await taskManager.readTasksFile(tasksPath);
63
+ // Validate task exists
64
+ const task = taskManager.validateTaskExists(phases, taskId);
65
+ if (!task) {
66
+ // Smart recovery: List available tasks
67
+ console.log(chalk_1.default.red(`✗ Task ID "${taskId}" not found\n`));
68
+ console.log(chalk_1.default.yellow('Available task IDs:\n'));
69
+ phases.forEach(phase => {
70
+ console.log(chalk_1.default.bold(` ${phase.name}:`));
71
+ phase.tasks.forEach(t => {
72
+ const status = t.completed ? chalk_1.default.green('[x]') : chalk_1.default.gray('[ ]');
73
+ console.log(` ${status} ${chalk_1.default.cyan(t.id)} - ${t.description}`);
74
+ });
75
+ console.log();
76
+ });
77
+ this.error('Task not found. Please use one of the task IDs listed above.');
78
+ }
79
+ // Check if already completed
80
+ if (task.completed && !flags.force) {
81
+ console.log(chalk_1.default.yellow(`⚠ Task "${taskId}" is already marked as completed\n`));
82
+ // Check if it's in config too
83
+ const isInConfig = await configManager.isTaskCompleted(configPath, taskId);
84
+ if (isInConfig) {
85
+ console.log(chalk_1.default.dim('Task is tracked in config as completed.\n'));
86
+ }
87
+ console.log(chalk_1.default.gray('Use --force to re-mark this task as completed.\n'));
88
+ // Show next task
89
+ await this.showNextTask(taskManager, phases);
90
+ return;
91
+ }
92
+ // Mark task as completed with validation
93
+ console.log(chalk_1.default.dim('Marking task as completed...'));
94
+ const result = await taskManager.markTaskCompletedWithValidation(tasksPath, taskId);
95
+ if (!result.success) {
96
+ // Smart recovery: Show error and suggestions
97
+ console.log(chalk_1.default.red(`\n✗ Failed to mark task as completed\n`));
98
+ console.log(chalk_1.default.yellow(`Error: ${result.error}\n`));
99
+ if (result.warnings && result.warnings.length > 0) {
100
+ console.log(chalk_1.default.yellow('Warnings:'));
101
+ result.warnings.forEach(warning => console.log(chalk_1.default.yellow(` • ${warning}`)));
102
+ console.log();
103
+ }
104
+ // Provide recovery suggestions
105
+ console.log(chalk_1.default.bold('Recovery Options:\n'));
106
+ console.log(chalk_1.default.gray(' 1. Check if tasks.md file is readable and writable'));
107
+ console.log(chalk_1.default.gray(' 2. Verify task ID matches exactly (run "clavix implement" to see current task)'));
108
+ console.log(chalk_1.default.gray(' 3. Try running with --force flag if task is already completed'));
109
+ console.log(chalk_1.default.gray(' 4. Check tasks.md.backup file if one was created\n'));
110
+ this.error('Task completion failed');
111
+ }
112
+ // Display warnings if any
113
+ if (result.warnings && result.warnings.length > 0) {
114
+ console.log(chalk_1.default.yellow('\nWarnings:'));
115
+ result.warnings.forEach(warning => console.log(chalk_1.default.yellow(` • ${warning}`)));
116
+ console.log();
117
+ }
118
+ // Success!
119
+ if (result.alreadyCompleted) {
120
+ console.log(chalk_1.default.green(`✓ Task was already completed (tracking updated)\n`));
121
+ }
122
+ else {
123
+ console.log(chalk_1.default.green(`✓ Task marked as completed\n`));
124
+ }
125
+ // Track completion in config
126
+ console.log(chalk_1.default.dim('Updating configuration...'));
127
+ await configManager.trackCompletion(configPath, taskId);
128
+ // Update stats
129
+ const updatedStats = taskManager.getTaskStats(phases);
130
+ await configManager.update(configPath, { stats: updatedStats });
131
+ console.log(chalk_1.default.green('✓ Configuration updated\n'));
132
+ // Show progress
133
+ console.log(chalk_1.default.bold('Progress:'));
134
+ console.log(chalk_1.default.cyan(` Completed: ${updatedStats.completed}/${updatedStats.total} tasks (${updatedStats.percentage.toFixed(0)}%)`));
135
+ console.log(chalk_1.default.cyan(` Remaining: ${updatedStats.remaining} tasks\n`));
136
+ // Create git commit if enabled
137
+ if (!flags['no-git'] && config.commitStrategy !== 'none') {
138
+ await this.handleGitCommit(gitManager, configManager, configPath, config.commitStrategy, task, phases);
139
+ }
140
+ // Show next task
141
+ await this.showNextTask(taskManager, phases);
142
+ }
143
+ catch (error) {
144
+ const errorMessage = error instanceof Error ? error.message : 'An unexpected error occurred';
145
+ console.log(chalk_1.default.red(`\n✗ Error: ${errorMessage}\n`));
146
+ this.error(errorMessage);
147
+ }
148
+ }
149
+ /**
150
+ * Find config file (auto-discover or use provided path)
151
+ */
152
+ async findConfigFile(providedPath) {
153
+ if (providedPath) {
154
+ if (await fs.pathExists(providedPath)) {
155
+ return providedPath;
156
+ }
157
+ throw new Error(`Config file not found: ${providedPath}`);
158
+ }
159
+ // Auto-discover: Look for .clavix/outputs/*/.clavix-implement-config.json
160
+ const outputsDir = path.join(process.cwd(), '.clavix', 'outputs');
161
+ if (!(await fs.pathExists(outputsDir))) {
162
+ throw new Error('No .clavix/outputs directory found.\n\nHint: Run "clavix implement" first to initialize');
163
+ }
164
+ // Search for config files
165
+ const entries = await fs.readdir(outputsDir, { withFileTypes: true });
166
+ const configFiles = [];
167
+ for (const entry of entries) {
168
+ if (!entry.isDirectory() || entry.name === 'archive') {
169
+ continue;
170
+ }
171
+ const configPath = path.join(outputsDir, entry.name, '.clavix-implement-config.json');
172
+ if (await fs.pathExists(configPath)) {
173
+ configFiles.push(configPath);
174
+ }
175
+ }
176
+ if (configFiles.length === 0) {
177
+ throw new Error('No config files found.\n\nHint: Run "clavix implement" first to initialize');
178
+ }
179
+ // Use most recent config
180
+ const configsWithStats = await Promise.all(configFiles.map(async (filePath) => {
181
+ const stat = await fs.stat(filePath);
182
+ return { path: filePath, mtime: stat.mtime };
183
+ }));
184
+ configsWithStats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
185
+ return configsWithStats[0].path;
186
+ }
187
+ /**
188
+ * Handle git commit based on strategy
189
+ */
190
+ async handleGitCommit(gitManager, configManager, configPath, strategy, completedTask, phases) {
191
+ console.log(chalk_1.default.dim(`Checking git commit strategy (${strategy})...`));
192
+ const config = await configManager.read(configPath);
193
+ const completedCount = config.completedTaskIds?.length ?? 0;
194
+ let shouldCommit = false;
195
+ let commitMessage = '';
196
+ switch (strategy) {
197
+ case 'per-task':
198
+ shouldCommit = true;
199
+ commitMessage = `clavix: ${completedTask.description}`;
200
+ break;
201
+ case 'per-5-tasks':
202
+ shouldCommit = completedCount % 5 === 0;
203
+ if (shouldCommit) {
204
+ const last5 = config.completedTaskIds?.slice(-5) ?? [];
205
+ const taskDescriptions = phases
206
+ .flatMap(p => p.tasks)
207
+ .filter((t) => last5.includes(t.id))
208
+ .map((t) => t.description);
209
+ commitMessage = `clavix: Completed ${last5.length} tasks\n\nCompleted tasks:\n${taskDescriptions.map(d => `- ${d}`).join('\n')}`;
210
+ }
211
+ break;
212
+ case 'per-phase':
213
+ // Check if current phase is complete
214
+ const currentPhase = phases.find(p => p.name === completedTask.phase);
215
+ if (currentPhase) {
216
+ const phaseComplete = currentPhase.tasks.every((t) => t.completed);
217
+ shouldCommit = phaseComplete;
218
+ if (shouldCommit) {
219
+ commitMessage = `clavix: Completed ${currentPhase.name}\n\nCompleted tasks:\n${currentPhase.tasks.map((t) => `- ${t.description}`).join('\n')}`;
220
+ }
221
+ }
222
+ break;
223
+ case 'none':
224
+ default:
225
+ shouldCommit = false;
226
+ break;
227
+ }
228
+ if (!shouldCommit) {
229
+ console.log(chalk_1.default.dim('No commit needed (strategy criteria not met)\n'));
230
+ return;
231
+ }
232
+ // Check git status
233
+ const gitStatus = await gitManager.validateGitSetup();
234
+ if (!gitStatus.isRepo) {
235
+ console.log(chalk_1.default.yellow('⚠ Not a git repository - skipping commit\n'));
236
+ return;
237
+ }
238
+ if (!gitStatus.hasChanges) {
239
+ console.log(chalk_1.default.dim('No git changes to commit\n'));
240
+ return;
241
+ }
242
+ // Create commit
243
+ console.log(chalk_1.default.dim('Creating git commit...'));
244
+ const fullMessage = `${commitMessage}\n\nGenerated by Clavix task-complete`;
245
+ const success = await gitManager.createCommit({
246
+ message: fullMessage,
247
+ description: completedTask.description,
248
+ projectName: path.basename(path.dirname(configPath)),
249
+ });
250
+ if (success) {
251
+ console.log(chalk_1.default.green('✓ Git commit created\n'));
252
+ }
253
+ else {
254
+ console.log(chalk_1.default.yellow('⚠ Git commit failed (non-critical)\n'));
255
+ }
256
+ }
257
+ /**
258
+ * Show next incomplete task
259
+ */
260
+ async showNextTask(taskManager, phases) {
261
+ const nextTask = taskManager.findFirstIncompleteTask(phases);
262
+ if (!nextTask) {
263
+ console.log(chalk_1.default.bold.green('🎉 All tasks completed!\n'));
264
+ console.log(chalk_1.default.gray('Great work! All implementation tasks are done.\n'));
265
+ console.log(chalk_1.default.dim('Hint: Run "clavix archive" to archive this project\n'));
266
+ return;
267
+ }
268
+ console.log(chalk_1.default.bold('Next Task:'));
269
+ console.log(chalk_1.default.bold.white(` ID: ${chalk_1.default.cyan(nextTask.id)}`));
270
+ console.log(chalk_1.default.bold.white(` ${nextTask.description}`));
271
+ if (nextTask.prdReference) {
272
+ console.log(chalk_1.default.dim(` Reference: ${nextTask.prdReference}`));
273
+ }
274
+ console.log(chalk_1.default.dim(` Phase: ${nextTask.phase}\n`));
275
+ }
276
+ }
277
+ TaskComplete.description = 'Mark a task as completed with validation and optional git commit';
278
+ TaskComplete.examples = [
279
+ '<%= config.bin %> <%= command.id %> phase-1-auth-1',
280
+ '<%= config.bin %> <%= command.id %> phase-2-api-3 --no-git',
281
+ '<%= config.bin %> <%= command.id %> setup-1 --force',
282
+ ];
283
+ TaskComplete.args = {
284
+ taskId: core_1.Args.string({
285
+ description: 'Task ID to mark as completed',
286
+ required: true,
287
+ }),
288
+ };
289
+ TaskComplete.flags = {
290
+ 'no-git': core_1.Flags.boolean({
291
+ description: 'Skip git commit even if strategy is enabled',
292
+ default: false,
293
+ }),
294
+ force: core_1.Flags.boolean({
295
+ char: 'f',
296
+ description: 'Force completion even if already marked complete',
297
+ default: false,
298
+ }),
299
+ config: core_1.Flags.string({
300
+ char: 'c',
301
+ description: 'Path to config file (defaults to auto-discover)',
302
+ }),
303
+ };
304
+ exports.default = TaskComplete;
305
+ //# sourceMappingURL=task-complete.js.map
@@ -0,0 +1,149 @@
1
+ /**
2
+ * ConfigManager - Manages .clavix-implement-config.json
3
+ *
4
+ * This class handles:
5
+ * - Reading/writing implementation configuration
6
+ * - Tracking task completion state
7
+ * - Managing resume checkpoints
8
+ * - Storing git commit strategy preferences
9
+ */
10
+ import { Task } from './task-manager';
11
+ import { CommitStrategy } from './git-manager';
12
+ /**
13
+ * Configuration for task implementation
14
+ */
15
+ export interface ImplementConfig {
16
+ /** Git commit strategy */
17
+ commitStrategy: CommitStrategy;
18
+ /** Path to tasks.md file */
19
+ tasksPath: string;
20
+ /** Current task being worked on */
21
+ currentTask: Task;
22
+ /** Overall task statistics */
23
+ stats: {
24
+ total: number;
25
+ completed: number;
26
+ remaining: number;
27
+ percentage: number;
28
+ };
29
+ /** Timestamp when config was last updated */
30
+ timestamp: string;
31
+ /** ID of the last completed task */
32
+ lastCompletedTaskId?: string;
33
+ /** Array of all completed task IDs (for validation and resume) */
34
+ completedTaskIds?: string[];
35
+ /** Timestamps for each task completion (for tracking progress) */
36
+ completionTimestamps?: Record<string, string>;
37
+ /** Array of blocked task IDs with reasons */
38
+ blockedTasks?: Array<{
39
+ taskId: string;
40
+ reason: string;
41
+ timestamp: string;
42
+ }>;
43
+ /** Resume checkpoint for interrupted sessions */
44
+ resumeCheckpoint?: {
45
+ lastTaskId: string;
46
+ phaseProgress: Record<string, number>;
47
+ sessionStartTime: string;
48
+ };
49
+ }
50
+ /**
51
+ * Options for updating config
52
+ */
53
+ export interface ConfigUpdateOptions {
54
+ /** Merge with existing config (true) or overwrite (false) */
55
+ merge?: boolean;
56
+ /** Validate config structure before writing */
57
+ validate?: boolean;
58
+ }
59
+ /**
60
+ * ConfigManager class
61
+ *
62
+ * Manages implementation configuration and task tracking state
63
+ */
64
+ export declare class ConfigManager {
65
+ /**
66
+ * Read implementation config from file
67
+ * @param configPath - Path to config file (.clavix-implement-config.json)
68
+ * @returns Implementation configuration
69
+ */
70
+ read(configPath: string): Promise<ImplementConfig>;
71
+ /**
72
+ * Write implementation config to file
73
+ * @param configPath - Path to config file
74
+ * @param config - Configuration to write
75
+ * @param options - Update options
76
+ */
77
+ write(configPath: string, config: ImplementConfig, options?: ConfigUpdateOptions): Promise<void>;
78
+ /**
79
+ * Update specific fields in config
80
+ * @param configPath - Path to config file
81
+ * @param updates - Partial config updates
82
+ */
83
+ update(configPath: string, updates: Partial<ImplementConfig>): Promise<void>;
84
+ /**
85
+ * Track a task completion
86
+ * @param configPath - Path to config file
87
+ * @param taskId - ID of completed task
88
+ */
89
+ trackCompletion(configPath: string, taskId: string): Promise<void>;
90
+ /**
91
+ * Add a blocked task
92
+ * @param configPath - Path to config file
93
+ * @param taskId - ID of blocked task
94
+ * @param reason - Reason for blocking
95
+ */
96
+ addBlockedTask(configPath: string, taskId: string, reason: string): Promise<void>;
97
+ /**
98
+ * Remove a blocked task (unblock)
99
+ * @param configPath - Path to config file
100
+ * @param taskId - ID of task to unblock
101
+ */
102
+ removeBlockedTask(configPath: string, taskId: string): Promise<void>;
103
+ /**
104
+ * Get current implementation state
105
+ * @param configPath - Path to config file
106
+ * @returns State summary
107
+ */
108
+ getState(configPath: string): Promise<{
109
+ currentTaskId: string;
110
+ completedCount: number;
111
+ remainingCount: number;
112
+ blockedCount: number;
113
+ lastCompletedTaskId?: string;
114
+ lastCompletionTime?: string;
115
+ }>;
116
+ /**
117
+ * Check if a task has been completed
118
+ * @param configPath - Path to config file
119
+ * @param taskId - Task ID to check
120
+ * @returns true if task is in completed list
121
+ */
122
+ isTaskCompleted(configPath: string, taskId: string): Promise<boolean>;
123
+ /**
124
+ * Validate config structure
125
+ * @param config - Configuration to validate
126
+ * @throws Error if config is invalid
127
+ */
128
+ private validateConfig;
129
+ /**
130
+ * Migrate old config format to new format
131
+ * @param config - Old config format
132
+ * @returns Migrated config
133
+ */
134
+ private migrateConfig;
135
+ /**
136
+ * Create a resume checkpoint
137
+ * @param configPath - Path to config file
138
+ * @param currentTaskId - Current task being worked on
139
+ * @param phaseProgress - Progress by phase (phase name -> completed count)
140
+ */
141
+ createResumeCheckpoint(configPath: string, currentTaskId: string, phaseProgress: Record<string, number>): Promise<void>;
142
+ /**
143
+ * Get the config file path for a PRD directory
144
+ * @param prdPath - Path to PRD directory
145
+ * @returns Path to config file
146
+ */
147
+ static getConfigPath(prdPath: string): string;
148
+ }
149
+ //# sourceMappingURL=config-manager.d.ts.map