clavix 2.7.0 → 2.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.
Files changed (165) hide show
  1. package/README.md +22 -8
  2. package/bin/clavix.js +12 -5
  3. package/dist/cli/commands/archive.d.ts +5 -4
  4. package/dist/cli/commands/archive.js +135 -161
  5. package/dist/cli/commands/config.d.ts +4 -4
  6. package/dist/cli/commands/config.js +66 -105
  7. package/dist/cli/commands/deep.d.ts +3 -3
  8. package/dist/cli/commands/deep.js +97 -103
  9. package/dist/cli/commands/execute.d.ts +4 -4
  10. package/dist/cli/commands/execute.js +57 -63
  11. package/dist/cli/commands/fast.d.ts +3 -3
  12. package/dist/cli/commands/fast.js +122 -128
  13. package/dist/cli/commands/implement.d.ts +4 -4
  14. package/dist/cli/commands/implement.js +84 -148
  15. package/dist/cli/commands/init.js +87 -126
  16. package/dist/cli/commands/list.d.ts +5 -5
  17. package/dist/cli/commands/list.js +72 -111
  18. package/dist/cli/commands/plan.d.ts +7 -7
  19. package/dist/cli/commands/plan.js +92 -131
  20. package/dist/cli/commands/prd.d.ts +4 -4
  21. package/dist/cli/commands/prd.js +76 -111
  22. package/dist/cli/commands/prompts/clear.d.ts +6 -6
  23. package/dist/cli/commands/prompts/clear.js +70 -76
  24. package/dist/cli/commands/prompts/list.js +37 -43
  25. package/dist/cli/commands/show.d.ts +4 -4
  26. package/dist/cli/commands/show.js +72 -111
  27. package/dist/cli/commands/start.d.ts +3 -3
  28. package/dist/cli/commands/start.js +63 -101
  29. package/dist/cli/commands/summarize.d.ts +4 -4
  30. package/dist/cli/commands/summarize.js +81 -120
  31. package/dist/cli/commands/task-complete.d.ts +4 -4
  32. package/dist/cli/commands/task-complete.js +86 -123
  33. package/dist/cli/commands/update.d.ts +3 -3
  34. package/dist/cli/commands/update.js +97 -130
  35. package/dist/cli/commands/version.js +13 -48
  36. package/dist/core/adapters/agents-md-generator.js +17 -50
  37. package/dist/core/adapters/amp-adapter.d.ts +1 -1
  38. package/dist/core/adapters/amp-adapter.js +13 -21
  39. package/dist/core/adapters/augment-adapter.d.ts +2 -2
  40. package/dist/core/adapters/augment-adapter.js +16 -56
  41. package/dist/core/adapters/base-adapter.d.ts +1 -1
  42. package/dist/core/adapters/base-adapter.js +11 -47
  43. package/dist/core/adapters/claude-code-adapter.d.ts +2 -2
  44. package/dist/core/adapters/claude-code-adapter.js +19 -60
  45. package/dist/core/adapters/cline-adapter.d.ts +1 -1
  46. package/dist/core/adapters/cline-adapter.js +13 -21
  47. package/dist/core/adapters/codebuddy-adapter.d.ts +2 -2
  48. package/dist/core/adapters/codebuddy-adapter.js +17 -57
  49. package/dist/core/adapters/codex-adapter.d.ts +2 -2
  50. package/dist/core/adapters/codex-adapter.js +16 -56
  51. package/dist/core/adapters/copilot-instructions-generator.js +18 -51
  52. package/dist/core/adapters/crush-adapter.d.ts +2 -2
  53. package/dist/core/adapters/crush-adapter.js +13 -20
  54. package/dist/core/adapters/cursor-adapter.d.ts +1 -1
  55. package/dist/core/adapters/cursor-adapter.js +12 -20
  56. package/dist/core/adapters/droid-adapter.d.ts +2 -2
  57. package/dist/core/adapters/droid-adapter.js +14 -21
  58. package/dist/core/adapters/gemini-adapter.d.ts +2 -2
  59. package/dist/core/adapters/gemini-adapter.js +16 -52
  60. package/dist/core/adapters/kilocode-adapter.d.ts +1 -1
  61. package/dist/core/adapters/kilocode-adapter.js +12 -20
  62. package/dist/core/adapters/octo-md-generator.js +17 -50
  63. package/dist/core/adapters/opencode-adapter.d.ts +2 -2
  64. package/dist/core/adapters/opencode-adapter.js +14 -21
  65. package/dist/core/adapters/qwen-adapter.d.ts +2 -2
  66. package/dist/core/adapters/qwen-adapter.js +16 -52
  67. package/dist/core/adapters/roocode-adapter.d.ts +2 -2
  68. package/dist/core/adapters/roocode-adapter.js +12 -19
  69. package/dist/core/adapters/warp-md-generator.js +17 -50
  70. package/dist/core/adapters/windsurf-adapter.d.ts +1 -1
  71. package/dist/core/adapters/windsurf-adapter.js +12 -20
  72. package/dist/core/agent-manager.d.ts +1 -1
  73. package/dist/core/agent-manager.js +34 -38
  74. package/dist/core/archive-manager.js +10 -46
  75. package/dist/core/config-manager.d.ts +2 -2
  76. package/dist/core/config-manager.js +3 -40
  77. package/dist/core/conversation-analyzer.d.ts +1 -1
  78. package/dist/core/conversation-analyzer.js +1 -5
  79. package/dist/core/doc-injector.js +23 -60
  80. package/dist/core/git-manager.js +11 -48
  81. package/dist/core/prd-generator.js +16 -51
  82. package/dist/core/prompt-manager.js +6 -42
  83. package/dist/core/prompt-optimizer.js +1 -5
  84. package/dist/core/question-engine.js +6 -45
  85. package/dist/core/session-manager.d.ts +1 -1
  86. package/dist/core/session-manager.js +11 -49
  87. package/dist/core/task-manager.d.ts +26 -0
  88. package/dist/core/task-manager.js +243 -101
  89. package/dist/index.d.ts +2 -1
  90. package/dist/index.js +8 -12
  91. package/dist/templates/agents/agents.md +31 -2
  92. package/dist/templates/agents/copilot-instructions.md +1 -1
  93. package/dist/templates/agents/octo.md +20 -1
  94. package/dist/templates/agents/warp.md +1 -1
  95. package/dist/templates/slash-commands/_canonical/implement.md +33 -11
  96. package/dist/types/agent.js +1 -2
  97. package/dist/types/config.js +3 -8
  98. package/dist/types/errors.js +7 -13
  99. package/dist/types/session.js +1 -2
  100. package/dist/utils/agent-error-messages.js +1 -5
  101. package/dist/utils/error-utils.js +5 -12
  102. package/dist/utils/file-system.js +20 -57
  103. package/dist/utils/legacy-command-cleanup.d.ts +1 -1
  104. package/dist/utils/legacy-command-cleanup.js +9 -45
  105. package/dist/utils/template-loader.d.ts +1 -1
  106. package/dist/utils/template-loader.js +9 -41
  107. package/dist/utils/toml-templates.js +1 -4
  108. package/package.json +12 -7
  109. package/dist/core/adapters 2/agents-md-generator.d.ts +0 -26
  110. package/dist/core/adapters 2/agents-md-generator.js +0 -102
  111. package/dist/core/adapters 2/amp-adapter.d.ts +0 -27
  112. package/dist/core/adapters 2/amp-adapter.js +0 -42
  113. package/dist/core/adapters 2/augment-adapter.d.ts +0 -22
  114. package/dist/core/adapters 2/augment-adapter.js +0 -77
  115. package/dist/core/adapters 2/base-adapter.d.ts +0 -45
  116. package/dist/core/adapters 2/base-adapter.js +0 -142
  117. package/dist/core/adapters 2/claude-code-adapter.d.ts +0 -32
  118. package/dist/core/adapters 2/claude-code-adapter.js +0 -116
  119. package/dist/core/adapters 2/cline-adapter.d.ts +0 -34
  120. package/dist/core/adapters 2/cline-adapter.js +0 -52
  121. package/dist/core/adapters 2/codebuddy-adapter.d.ts +0 -24
  122. package/dist/core/adapters 2/codebuddy-adapter.js +0 -82
  123. package/dist/core/adapters 2/codex-adapter.d.ts +0 -24
  124. package/dist/core/adapters 2/codex-adapter.js +0 -79
  125. package/dist/core/adapters 2/copilot-instructions-generator.d.ts +0 -26
  126. package/dist/core/adapters 2/copilot-instructions-generator.js +0 -104
  127. package/dist/core/adapters 2/crush-adapter.d.ts +0 -35
  128. package/dist/core/adapters 2/crush-adapter.js +0 -49
  129. package/dist/core/adapters 2/cursor-adapter.d.ts +0 -25
  130. package/dist/core/adapters 2/cursor-adapter.js +0 -40
  131. package/dist/core/adapters 2/droid-adapter.d.ts +0 -33
  132. package/dist/core/adapters 2/droid-adapter.js +0 -57
  133. package/dist/core/adapters 2/gemini-adapter.d.ts +0 -27
  134. package/dist/core/adapters 2/gemini-adapter.js +0 -90
  135. package/dist/core/adapters 2/kilocode-adapter.d.ts +0 -34
  136. package/dist/core/adapters 2/kilocode-adapter.js +0 -49
  137. package/dist/core/adapters 2/octo-md-generator.d.ts +0 -26
  138. package/dist/core/adapters 2/octo-md-generator.js +0 -102
  139. package/dist/core/adapters 2/opencode-adapter.d.ts +0 -33
  140. package/dist/core/adapters 2/opencode-adapter.js +0 -56
  141. package/dist/core/adapters 2/qwen-adapter.d.ts +0 -27
  142. package/dist/core/adapters 2/qwen-adapter.js +0 -90
  143. package/dist/core/adapters 2/roocode-adapter.d.ts +0 -40
  144. package/dist/core/adapters 2/roocode-adapter.js +0 -68
  145. package/dist/core/adapters 2/warp-md-generator.d.ts +0 -17
  146. package/dist/core/adapters 2/warp-md-generator.js +0 -88
  147. package/dist/core/adapters 2/windsurf-adapter.d.ts +0 -34
  148. package/dist/core/adapters 2/windsurf-adapter.js +0 -49
  149. package/dist/core/agent-manager 2.js +0 -126
  150. package/dist/core/agent-manager.d 2.ts +0 -51
  151. package/dist/core/archive-manager 2.js +0 -338
  152. package/dist/core/archive-manager.d 2.ts +0 -100
  153. package/dist/core/conversation-analyzer.d 2.ts +0 -86
  154. package/dist/core/doc-injector 2.js +0 -236
  155. package/dist/core/doc-injector.d 2.ts +0 -51
  156. package/dist/core/git-manager 2.js +0 -214
  157. package/dist/core/git-manager.d 2.ts +0 -100
  158. package/dist/core/prompt-optimizer 2.js +0 -963
  159. package/dist/core/prompt-optimizer.d 2.ts +0 -268
  160. package/dist/core/question-engine 2.js +0 -395
  161. package/dist/core/question-engine.d 2.ts +0 -167
  162. package/dist/core/session-manager 2.js +0 -403
  163. package/dist/core/session-manager.d 2.ts +0 -139
  164. package/dist/core/task-manager 2.js +0 -689
  165. package/dist/core/task-manager.d 2.ts +0 -155
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * TaskManager - Manages PRD-based task generation and execution
4
3
  *
@@ -9,45 +8,10 @@
9
8
  * - Tracking task completion state
10
9
  * - Managing session resume capability
11
10
  */
12
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
- if (k2 === undefined) k2 = k;
14
- var desc = Object.getOwnPropertyDescriptor(m, k);
15
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
- desc = { enumerable: true, get: function() { return m[k]; } };
17
- }
18
- Object.defineProperty(o, k2, desc);
19
- }) : (function(o, m, k, k2) {
20
- if (k2 === undefined) k2 = k;
21
- o[k2] = m[k];
22
- }));
23
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
- Object.defineProperty(o, "default", { enumerable: true, value: v });
25
- }) : function(o, v) {
26
- o["default"] = v;
27
- });
28
- var __importStar = (this && this.__importStar) || (function () {
29
- var ownKeys = function(o) {
30
- ownKeys = Object.getOwnPropertyNames || function (o) {
31
- var ar = [];
32
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
- return ar;
34
- };
35
- return ownKeys(o);
36
- };
37
- return function (mod) {
38
- if (mod && mod.__esModule) return mod;
39
- var result = {};
40
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
- __setModuleDefault(result, mod);
42
- return result;
43
- };
44
- })();
45
- Object.defineProperty(exports, "__esModule", { value: true });
46
- exports.TaskManager = void 0;
47
- const fs = __importStar(require("fs-extra"));
48
- const path = __importStar(require("path"));
49
- const prompt_optimizer_1 = require("./prompt-optimizer");
50
- const file_system_1 = require("../utils/file-system");
11
+ import fs from 'fs-extra';
12
+ import * as path from 'path';
13
+ import { PromptOptimizer } from './prompt-optimizer.js';
14
+ import { FileSystem } from '../utils/file-system.js';
51
15
  const SOURCE_FILE_MAP = {
52
16
  full: ['full-prd.md', 'PRD.md', 'prd.md', 'Full-PRD.md', 'FULL_PRD.md', 'FULL-PRD.md'],
53
17
  quick: ['quick-prd.md', 'QUICK_PRD.md'],
@@ -61,9 +25,10 @@ const ALL_KNOWN_PRD_FILES = Array.from(new Set(Object.values(SOURCE_FILE_MAP).fl
61
25
  *
62
26
  * Generates and manages implementation tasks from PRD documents
63
27
  */
64
- class TaskManager {
28
+ export class TaskManager {
29
+ optimizer;
65
30
  constructor() {
66
- this.optimizer = new prompt_optimizer_1.PromptOptimizer();
31
+ this.optimizer = new PromptOptimizer();
67
32
  }
68
33
  /**
69
34
  * Generate tasks.md from PRD
@@ -161,60 +126,204 @@ class TaskManager {
161
126
  }
162
127
  return null;
163
128
  }
129
+ /**
130
+ * Generate phases from core features with intelligent grouping
131
+ * CRITICAL FIX: Group related features instead of 1 phase per bullet
132
+ */
164
133
  generatePhasesFromCoreFeatures(coreContent, options) {
165
134
  const bullets = this.extractListItems(coreContent);
166
135
  if (bullets.length === 0) {
167
136
  return [];
168
137
  }
169
- const maxTasks = options.maxTasksPerPhase ?? 20;
138
+ // GRANULARITY CONTROL: Warn if too many bullets
139
+ if (bullets.length > 50) {
140
+ console.warn(`Warning: PRD contains ${bullets.length} top-level features. Consider grouping related items.`);
141
+ }
142
+ // Group features by type/category instead of creating separate phases
143
+ const groupedFeatures = this.groupFeaturesByCategory(bullets);
170
144
  const phases = [];
171
- bullets.forEach((rawFeature, index) => {
172
- const feature = rawFeature.trim();
173
- if (!feature) {
174
- return;
175
- }
176
- const phaseName = `Phase ${index + 1}: ${this.toTitleCase(feature)}`;
177
- const baseDescriptions = this.buildFeatureTaskDescriptions(feature);
178
- const allowed = Math.max(1, Math.min(maxTasks, baseDescriptions.length));
179
- const minTasks = maxTasks >= 2 ? 2 : 1;
180
- const taskCount = Math.max(minTasks, allowed);
181
- const limitedDescriptions = baseDescriptions.slice(0, Math.min(taskCount, baseDescriptions.length));
182
- const tasks = limitedDescriptions.map((description, taskIndex) => ({
183
- id: `${this.sanitizeId(phaseName)}-${taskIndex + 1}`,
184
- description,
185
- phase: phaseName,
186
- completed: false,
187
- prdReference: feature,
188
- }));
189
- phases.push({
190
- name: phaseName,
191
- tasks,
145
+ let phaseNumber = 1;
146
+ for (const [category, features] of Object.entries(groupedFeatures)) {
147
+ const phaseName = `Phase ${phaseNumber}: ${category}`;
148
+ const tasks = [];
149
+ // Generate tasks for each feature in this group
150
+ features.forEach((feature) => {
151
+ const taskDescriptions = this.buildFeatureTaskDescriptions(feature);
152
+ taskDescriptions.forEach((description) => {
153
+ tasks.push({
154
+ id: `${this.sanitizeId(phaseName)}-${tasks.length + 1}`,
155
+ description,
156
+ phase: phaseName,
157
+ completed: false,
158
+ prdReference: feature,
159
+ });
160
+ });
192
161
  });
193
- });
162
+ // GRANULARITY CONTROL: Skip empty phases
163
+ if (tasks.length > 0) {
164
+ phases.push({
165
+ name: phaseName,
166
+ tasks,
167
+ });
168
+ phaseNumber++;
169
+ }
170
+ }
171
+ // GRANULARITY CONTROL: Cap total tasks (merge if exceeding)
172
+ const totalTasks = phases.reduce((sum, p) => sum + p.tasks.length, 0);
173
+ if (totalTasks > 50) {
174
+ console.warn(`Warning: Generated ${totalTasks} tasks. Consider merging related tasks or simplifying PRD.`);
175
+ }
194
176
  return phases;
195
177
  }
178
+ /**
179
+ * Group features by category for logical phase organization
180
+ * Replaces "1 bullet = 1 phase" with intelligent grouping
181
+ */
182
+ groupFeaturesByCategory(features) {
183
+ const groups = {
184
+ 'Configuration & Setup': [],
185
+ 'Core Implementation': [],
186
+ 'Testing & Validation': [],
187
+ 'Documentation': [],
188
+ 'Integration & Release': [],
189
+ };
190
+ features.forEach((feature) => {
191
+ const lower = feature.toLowerCase();
192
+ // Config/setup phase
193
+ if (/\b(config|configuration|setup|install|package|tsconfig|dependencies|environment)\b/i.test(feature)) {
194
+ groups['Configuration & Setup'].push(feature);
195
+ }
196
+ // Testing phase
197
+ else if (/\b(test|testing|coverage|validation|verify|qa)\b/i.test(feature)) {
198
+ groups['Testing & Validation'].push(feature);
199
+ }
200
+ // Documentation phase
201
+ else if (/\b(document|documentation|readme|changelog|guide|comment)\b/i.test(feature)) {
202
+ groups['Documentation'].push(feature);
203
+ }
204
+ // Integration/release phase
205
+ else if (/\b(integrate|integration|release|deploy|publish|build|distribution)\b/i.test(feature)) {
206
+ groups['Integration & Release'].push(feature);
207
+ }
208
+ // Default to core implementation
209
+ else {
210
+ groups['Core Implementation'].push(feature);
211
+ }
212
+ });
213
+ // Remove empty groups
214
+ return Object.fromEntries(Object.entries(groups).filter(([_, features]) => features.length > 0));
215
+ }
216
+ /**
217
+ * Extract top-level list items only (ignore nested bullets)
218
+ * This prevents sub-bullets from being treated as separate tasks
219
+ */
196
220
  extractListItems(sectionContent) {
197
221
  const items = [];
198
- const regex = /^\s*(?:[-*]|\d+[.)])\s+(.+)$/gm;
199
- let match;
200
- while ((match = regex.exec(sectionContent)) !== null) {
201
- const value = match[1].trim();
202
- if (value) {
203
- items.push(value.replace(/\s+/g, ' ').replace(/\.$/, ''));
222
+ const lines = sectionContent.split('\n');
223
+ let inCodeBlock = false;
224
+ for (const line of lines) {
225
+ // Track code blocks to ignore bullets inside them
226
+ if (line.trim().startsWith('```')) {
227
+ inCodeBlock = !inCodeBlock;
228
+ continue;
229
+ }
230
+ if (inCodeBlock) {
231
+ continue;
232
+ }
233
+ // Match ONLY top-level bullets (no indentation at all)
234
+ // Nested bullets (2+ spaces) are implementation details, not separate tasks
235
+ const topLevelMatch = line.match(/^(?:[-*]|\d+[.)])\s+(.+)$/);
236
+ if (topLevelMatch) {
237
+ const value = topLevelMatch[1].trim();
238
+ // Skip items that look like code examples, file paths, or implementation details
239
+ if (value && !this.looksLikeCodeOrPath(value) && !this.looksLikeImplementationDetail(value)) {
240
+ items.push(value.replace(/\s+/g, ' ').replace(/\.$/, ''));
241
+ }
204
242
  }
205
243
  }
206
244
  return items;
207
245
  }
246
+ /**
247
+ * Detect if a line looks like code or a file path (not a task)
248
+ */
249
+ looksLikeCodeOrPath(text) {
250
+ // File paths with extensions
251
+ if (/\.(ts|js|json|md|tsx|jsx|mjs|cjs)/.test(text)) {
252
+ return true;
253
+ }
254
+ // Code-like patterns
255
+ if (text.includes('import ') || text.includes('export ') || text.includes('require(')) {
256
+ return true;
257
+ }
258
+ // JSON-like
259
+ if (text.trim().startsWith('{') || text.trim().startsWith('[')) {
260
+ return true;
261
+ }
262
+ // Very short technical commands
263
+ if (text.length < 15 && /^[a-z-]+:[a-z-]+$/i.test(text)) {
264
+ return true;
265
+ }
266
+ return false;
267
+ }
268
+ /**
269
+ * Detect if text is an implementation detail rather than a feature
270
+ * Implementation details are constraints, requirements, or sub-steps
271
+ */
272
+ looksLikeImplementationDetail(text) {
273
+ const lower = text.toLowerCase();
274
+ // Constraints and requirements (not tasks)
275
+ if (lower.includes(' must ') || lower.includes(' should ') || lower.includes(' required')) {
276
+ return true;
277
+ }
278
+ // Very short items (< 25 chars) are likely details, not features
279
+ if (text.length < 25 && !lower.startsWith('implement') && !lower.startsWith('create')) {
280
+ return true;
281
+ }
282
+ // Specific technical constraints
283
+ if (/^(password|email|session|token|rate|https)/i.test(text)) {
284
+ return true;
285
+ }
286
+ return false;
287
+ }
288
+ /**
289
+ * Build context-aware task descriptions based on feature type and complexity
290
+ * Replaces the old 5-task boilerplate with intelligent task generation
291
+ */
208
292
  buildFeatureTaskDescriptions(feature) {
209
293
  const formattedFeature = this.formatInlineText(feature);
210
- const tasks = [
294
+ const featureLower = feature.toLowerCase();
295
+ // Detect task type
296
+ const isConfig = /\b(config|configuration|setup|install|update.*json|tsconfig|package\.json)\b/i.test(feature);
297
+ const isTest = /\b(test|testing|coverage|validation|verify)\b/i.test(feature);
298
+ const isDocumentation = /\b(document|documentation|readme|changelog|guide)\b/i.test(feature);
299
+ const isConversion = /\b(convert|migrate|refactor|replace|update.*code)\b/i.test(feature);
300
+ // Simple tasks (config, documentation) - Single task only
301
+ if (isConfig) {
302
+ return [this.convertBehaviorToTask(feature)];
303
+ }
304
+ if (isDocumentation) {
305
+ return [this.convertBehaviorToTask(feature)];
306
+ }
307
+ // Testing tasks - Implementation + validation
308
+ if (isTest) {
309
+ return [
310
+ this.convertBehaviorToTask(feature),
311
+ `Verify ${formattedFeature} passes successfully`,
312
+ ];
313
+ }
314
+ // Conversion/migration tasks - Convert + test
315
+ if (isConversion) {
316
+ return [
317
+ this.convertBehaviorToTask(feature),
318
+ `Test ${formattedFeature} works correctly`,
319
+ ];
320
+ }
321
+ // Default for complex features - Implementation + testing only
322
+ // (No more "integrate into end-to-end" boilerplate)
323
+ return [
211
324
  this.convertBehaviorToTask(feature),
212
325
  `Add tests covering ${formattedFeature}`,
213
- `Integrate ${formattedFeature} into the end-to-end experience`,
214
- `Document ${formattedFeature} for stakeholders`,
215
- `Validate ${formattedFeature} against requirements`,
216
326
  ];
217
- return tasks;
218
327
  }
219
328
  formatInlineText(text) {
220
329
  if (!text) {
@@ -333,8 +442,9 @@ class TaskManager {
333
442
  const featuresContent = mustHaveMatch[1];
334
443
  // Split by feature headers (#### Number. Feature Name)
335
444
  const featureHeaders = [...featuresContent.matchAll(/####\s+(\d+)\.\s+(.+)/g)];
445
+ // Collect all top-level behaviors from all features
446
+ const allBehaviors = [];
336
447
  for (let i = 0; i < featureHeaders.length; i++) {
337
- const featureNumber = featureHeaders[i][1];
338
448
  const featureName = featureHeaders[i][2].trim();
339
449
  // Extract content between this header and the next one
340
450
  const startIndex = featureHeaders[i].index;
@@ -342,10 +452,45 @@ class TaskManager {
342
452
  ? featureHeaders[i + 1].index
343
453
  : featuresContent.length;
344
454
  const featureContent = featuresContent.substring(startIndex, endIndex);
345
- // Generate phase for this feature
346
- const phase = this.generatePhaseFromFeature(featureName, featureContent, `Phase ${featureNumber}`);
347
- if (phase && phase.tasks.length > 0) {
348
- phases.push(phase);
455
+ // Extract behavior points using hierarchical parsing
456
+ const behaviorMatch = featureContent.match(/\*\*Behavior\*\*:([\s\S]*?)(?=\*\*|####|$)/);
457
+ if (behaviorMatch) {
458
+ const behaviors = behaviorMatch[1];
459
+ const bulletPoints = this.extractListItems(behaviors);
460
+ // Add all top-level behaviors to the list
461
+ allBehaviors.push(...bulletPoints);
462
+ }
463
+ else {
464
+ // If no Behavior section, add the feature name itself
465
+ allBehaviors.push(featureName);
466
+ }
467
+ }
468
+ // Now group all behaviors by category (instead of 1 phase per feature)
469
+ if (allBehaviors.length > 0) {
470
+ const groupedFeatures = this.groupFeaturesByCategory(allBehaviors);
471
+ let phaseNumber = 1;
472
+ for (const [category, features] of Object.entries(groupedFeatures)) {
473
+ const phaseName = `Phase ${phaseNumber}: ${category}`;
474
+ const tasks = [];
475
+ features.forEach((feature) => {
476
+ const taskDescriptions = this.buildFeatureTaskDescriptions(feature);
477
+ taskDescriptions.forEach((description) => {
478
+ tasks.push({
479
+ id: `${this.sanitizeId(phaseName)}-${tasks.length + 1}`,
480
+ description,
481
+ phase: phaseName,
482
+ completed: false,
483
+ prdReference: feature,
484
+ });
485
+ });
486
+ });
487
+ if (tasks.length > 0) {
488
+ phases.push({
489
+ name: phaseName,
490
+ tasks,
491
+ });
492
+ phaseNumber++;
493
+ }
349
494
  }
350
495
  }
351
496
  }
@@ -360,26 +505,24 @@ class TaskManager {
360
505
  */
361
506
  generatePhaseFromFeature(featureName, featureContent, phasePrefix) {
362
507
  const tasks = [];
363
- // Extract behavior points
508
+ // Extract behavior points using hierarchical parsing
364
509
  const behaviorMatch = featureContent.match(/\*\*Behavior\*\*:([\s\S]*?)(?=\*\*|####|$)/);
365
510
  if (behaviorMatch) {
366
511
  const behaviors = behaviorMatch[1];
367
- const bulletPoints = behaviors.match(/^[-*]\s+(.+)$/gm);
368
- if (bulletPoints) {
369
- bulletPoints.forEach((bullet, index) => {
370
- const description = bullet.replace(/^[-*]\s+/, '').trim();
371
- // Skip overly long bullets (likely multi-line descriptions)
372
- if (description.length < 200) {
373
- tasks.push({
374
- id: `${this.sanitizeId(featureName)}-${index + 1}`,
375
- description: this.convertBehaviorToTask(description),
376
- phase: phasePrefix,
377
- completed: false,
378
- prdReference: featureName,
379
- });
380
- }
381
- });
382
- }
512
+ // Use the same hierarchical parsing as extractListItems()
513
+ const bulletPoints = this.extractListItems(behaviors);
514
+ bulletPoints.forEach((description, index) => {
515
+ // Skip overly long bullets (likely multi-line descriptions)
516
+ if (description.length < 200) {
517
+ tasks.push({
518
+ id: `${this.sanitizeId(featureName)}-${index + 1}`,
519
+ description: this.convertBehaviorToTask(description),
520
+ phase: phasePrefix,
521
+ completed: false,
522
+ prdReference: featureName,
523
+ });
524
+ }
525
+ });
383
526
  }
384
527
  // If no behavior points, try to extract from feature description
385
528
  if (tasks.length === 0) {
@@ -490,7 +633,7 @@ class TaskManager {
490
633
  // Add footer
491
634
  content += '---\n\n';
492
635
  content += '*Generated by Clavix /clavix:plan*\n';
493
- await file_system_1.FileSystem.writeFileAtomic(outputPath, content);
636
+ await FileSystem.writeFileAtomic(outputPath, content);
494
637
  }
495
638
  /**
496
639
  * Read tasks from tasks.md file
@@ -597,7 +740,7 @@ class TaskManager {
597
740
  : '';
598
741
  const regex = new RegExp(`^(-\\s+\\[)( )(\\]\\s+${taskDescPattern}${refPattern})$`, 'm');
599
742
  const updatedContent = content.replace(regex, '$1x$3');
600
- await file_system_1.FileSystem.writeFileAtomic(tasksPath, updatedContent);
743
+ await FileSystem.writeFileAtomic(tasksPath, updatedContent);
601
744
  }
602
745
  /**
603
746
  * Escape special regex characters
@@ -827,5 +970,4 @@ class TaskManager {
827
970
  return available;
828
971
  }
829
972
  }
830
- exports.TaskManager = TaskManager;
831
973
  //# sourceMappingURL=task-manager.js.map
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  #!/usr/bin/env node
2
- export declare function run(argv?: string[]): Promise<unknown>;
2
+ import { run } from '@oclif/core';
3
+ export { run };
3
4
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,17 +1,13 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.run = run;
5
- const core_1 = require("@oclif/core");
6
- async function run(argv) {
7
- // Disable debug mode (stack traces) unless explicitly requested via DEBUG env var
8
- if (!process.env.DEBUG) {
9
- core_1.settings.debug = false;
10
- }
11
- return (0, core_1.run)(argv);
2
+ import { run, handle, settings } from '@oclif/core';
3
+ // Disable debug mode (stack traces) unless explicitly requested via DEBUG env var
4
+ if (!process.env.DEBUG) {
5
+ settings.debug = false;
12
6
  }
13
7
  // Run if called directly
14
- if (require.main === module) {
15
- run().catch(core_1.handle);
8
+ if (import.meta.url === `file://${process.argv[1]}`) {
9
+ run().catch(handle);
16
10
  }
11
+ // Export for testing
12
+ export { run };
17
13
  //# sourceMappingURL=index.js.map
@@ -19,7 +19,7 @@ Use these instructions when your agent can only read documentation (no slash-com
19
19
  | `clavix prompts clear` | Manage prompt cleanup. Supports `--executed`, `--stale`, `--fast`, `--deep`, `--all` flags. |
20
20
  | `clavix prd` | Guided Socratic questions that generate `full-prd.md` and `quick-prd.md`. |
21
21
  | `clavix plan` | Transform PRDs or sessions into phase-based `tasks.md`. |
22
- | `clavix implement` | Walk through tasks, track progress, optionally set git auto-commit strategy. |
22
+ | `clavix implement [--commit-strategy=<type>]` | Start task execution. Git strategies: per-task, per-5-tasks, per-phase, none (default: none). |
23
23
  | `clavix start` | Begin conversational capture session for requirements gathering. |
24
24
  | `clavix summarize [session-id]` | Extract mini PRD and optimized prompts from saved sessions. |
25
25
  | `clavix list` | List sessions and/or output projects (`--sessions`, `--outputs`, filters). |
@@ -32,10 +32,39 @@ Use these instructions when your agent can only read documentation (no slash-com
32
32
  ## Typical workflows
33
33
  - **Improve prompts quickly:** run `clavix fast` or `clavix deep` depending on complexity.
34
34
  - **Create strategy:** run `clavix prd` then `clavix plan` for an implementation checklist.
35
- - **Execute tasks:** use `clavix implement`, commit work, repeat until tasks complete.
35
+ - **Execute tasks:** use `clavix implement [--commit-strategy=<type>]`, commit work, repeat until tasks complete.
36
36
  - **Capture conversations:** record with `clavix start`, extract with `clavix summarize`.
37
37
  - **Stay organized:** inspect with `clavix list/show`, archive with `clavix archive`, refresh docs via `clavix update`.
38
38
 
39
+ ## Implementation with Git Strategy (Agent Workflow)
40
+
41
+ When implementing tasks with `clavix implement`:
42
+
43
+ 1. **Check task count**: Read `tasks.md` and count phases
44
+ 2. **Ask user for git preferences** (optional, only if >3 phases):
45
+ ```
46
+ "I notice this implementation has [X] phases with [Y] tasks.
47
+
48
+ Git auto-commit preferences?
49
+ - per-task: Commit after each task (detailed history)
50
+ - per-5-tasks: Commit every 5 tasks (balanced)
51
+ - per-phase: Commit when phase completes (milestones)
52
+ - none: Manual git workflow (default)
53
+
54
+ I'll use 'none' if you don't specify."
55
+ ```
56
+
57
+ 3. **Run implement with strategy**:
58
+ ```bash
59
+ # With git strategy (if user specified):
60
+ clavix implement --commit-strategy=per-phase
61
+
62
+ # Or without (defaults to 'none' - manual commits):
63
+ clavix implement
64
+ ```
65
+
66
+ 4. **Default behavior**: If no `--commit-strategy` flag provided, defaults to `none` (manual commits)
67
+
39
68
  Artifacts are stored under `.clavix/`:
40
69
  - `.clavix/outputs/<project>/` for PRDs, tasks, prompts
41
70
  - `.clavix/sessions/` for captured conversations
@@ -17,7 +17,7 @@ When working with this project, you can use the following Clavix commands:
17
17
  ### Strategic Planning
18
18
  - `clavix prd` - Interactive PRD generation through Socratic questioning
19
19
  - `clavix plan` - Transform PRDs into phase-based implementation tasks
20
- - `clavix implement` - Execute tasks with progress tracking
20
+ - `clavix implement [--commit-strategy=<type>]` - Execute tasks with progress tracking (git: per-task, per-5-tasks, per-phase, none [default])
21
21
 
22
22
  ### Conversational Workflows
23
23
  - `clavix start` - Begin conversational session for requirements gathering
@@ -196,6 +196,25 @@ Detect user intent from keywords and trigger appropriate workflow. Use Octofrien
196
196
  - Switch to thinking models when encountering complex architectural decisions or debugging
197
197
  - Your autofix capabilities help recover from tool call failures automatically
198
198
 
199
+ **Git Auto-Commit Strategy (Agent-Friendly):**
200
+
201
+ When starting implementation with `clavix implement`:
202
+
203
+ 1. **Check task complexity** (optional, only if >3 phases in tasks.md):
204
+ - Ask user: "Git auto-commit preferences? (per-task, per-5-tasks, per-phase, none)"
205
+ - Default to 'none' if user doesn't specify
206
+
207
+ 2. **Run with explicit strategy**:
208
+ ```bash
209
+ # If user wants commits:
210
+ clavix implement --commit-strategy=per-phase
211
+
212
+ # Otherwise (or no preference):
213
+ clavix implement
214
+ ```
215
+
216
+ 3. **Default behavior**: No `--commit-strategy` flag → defaults to 'none' (manual git workflow)
217
+
199
218
  ---
200
219
 
201
220
  ### Archive Workflow
@@ -250,7 +269,7 @@ Detect user intent from keywords and trigger appropriate workflow. Use Octofrien
250
269
  | `clavix prompts clear` | Cleanup executed/stale prompts (`--executed`, `--stale`, `--fast`, `--deep`). |
251
270
  | `clavix prd` | Guided questions to create PRDs. |
252
271
  | `clavix plan` | Convert PRD artifacts into task lists. |
253
- | `clavix implement` | Step through tasks with optional git automation. |
272
+ | `clavix implement [--commit-strategy=<type>]` | Start task execution (git: per-task, per-5-tasks, per-phase, none [default]). |
254
273
  | `clavix start` | Capture conversational requirements. |
255
274
  | `clavix summarize` | Extract mini PRDs and prompts from sessions. |
256
275
  | `clavix list` | List sessions or outputs (use `--sessions`, `--outputs`, `--archived`). |
@@ -16,7 +16,7 @@ Clavix helps Warp developers turn rough ideas into CLEAR, AI-ready prompts and P
16
16
  - `clavix prompts clear [--executed|--stale|--fast|--deep]` – cleanup executed or old prompts
17
17
  - `clavix prd` – answer focused questions to create full/quick PRDs
18
18
  - `clavix plan` – transform PRDs or sessions into task lists
19
- - `clavix implement` – progress through tasks with optional git auto-commit
19
+ - `clavix implement [--commit-strategy=<type>]` – execute tasks (git: per-task, per-5-tasks, per-phase, none [default])
20
20
  - `clavix start` – capture requirement conversations in Warp
21
21
  - `clavix summarize [session-id]` – extract mini PRDs and optimized prompts
22
22
  - `clavix list` – list sessions/outputs (`--sessions`, `--outputs`, `--archived`)
@@ -9,21 +9,43 @@ You are helping the user implement tasks from their task plan with AI assistance
9
9
 
10
10
  ## Instructions
11
11
 
12
- 1. **First-time setup - Run CLI command if needed**:
12
+ 1. **First-time setup - Run CLI command with optional git strategy**:
13
13
 
14
14
  Check if `.clavix-implement-config.json` exists in the PRD output folder.
15
15
 
16
16
  **If config file does NOT exist** (first time running implement):
17
- - Run the CLI command to initialize:
18
- ```bash
19
- clavix implement
20
- ```
21
- - This will:
22
- - Show current progress
23
- - Display the next incomplete task
24
- - Prompt user for git auto-commit preferences
25
- - Create `.clavix-implement-config.json` file
26
- - Wait for command to complete, then proceed with step 2
17
+
18
+ a. **Check if user wants git auto-commits** (optional, only if tasks.md has >3 phases):
19
+ ```
20
+ "I notice this implementation has [X] phases with [Y] tasks total.
21
+
22
+ Would you like me to create git commits automatically as I complete tasks?
23
+
24
+ Options:
25
+ - per-task: Commit after each task (frequent commits, detailed history)
26
+ - per-5-tasks: Commit every 5 tasks (balanced approach)
27
+ - per-phase: Commit when each phase completes (milestone commits)
28
+ - none: Manual git workflow (I won't create commits)
29
+
30
+ Please choose one, or I'll proceed with 'none' (manual commits)."
31
+ ```
32
+
33
+ b. **Run the CLI command to initialize**:
34
+ ```bash
35
+ # With git strategy (if user specified):
36
+ clavix implement --commit-strategy=per-phase
37
+
38
+ # Or without (defaults to 'none' - manual commits):
39
+ clavix implement
40
+ ```
41
+
42
+ c. **This will**:
43
+ - Show current progress
44
+ - Display the next incomplete task
45
+ - Create `.clavix-implement-config.json` file
46
+ - Set git auto-commit strategy (or default to 'none')
47
+
48
+ d. Wait for command to complete, then proceed with step 2
27
49
 
28
50
  **If config file already exists**:
29
51
  - Skip to step 2 (implementation loop)
@@ -1,6 +1,5 @@
1
- "use strict";
2
1
  /**
3
2
  * Agent integration types
4
3
  */
5
- Object.defineProperty(exports, "__esModule", { value: true });
4
+ export {};
6
5
  //# sourceMappingURL=agent.js.map