clavix 2.3.1 → 2.4.1

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 (187) hide show
  1. package/README.md +0 -116
  2. package/bin/clavix.js +7 -0
  3. package/dist/cli/commands/implement.js +25 -33
  4. package/dist/cli/commands/plan.js +22 -27
  5. package/dist/cli/commands/prd.js +7 -12
  6. package/dist/cli/commands/start.js +4 -9
  7. package/dist/cli/commands/summarize.js +15 -22
  8. package/dist/core 2/adapters/agents-md-generator.d.ts +26 -0
  9. package/dist/core 2/adapters/agents-md-generator.js +102 -0
  10. package/dist/core 2/adapters/amp-adapter.d.ts +27 -0
  11. package/dist/core 2/adapters/amp-adapter.js +42 -0
  12. package/dist/core 2/adapters/augment-adapter.d.ts +22 -0
  13. package/dist/core 2/adapters/augment-adapter.js +77 -0
  14. package/dist/core 2/adapters/base-adapter.d.ts +45 -0
  15. package/dist/core 2/adapters/base-adapter.js +142 -0
  16. package/dist/core 2/adapters/claude-code-adapter.d.ts +32 -0
  17. package/dist/core 2/adapters/claude-code-adapter.js +116 -0
  18. package/dist/core 2/adapters/cline-adapter.d.ts +34 -0
  19. package/dist/core 2/adapters/cline-adapter.js +52 -0
  20. package/dist/core 2/adapters/codebuddy-adapter.d.ts +24 -0
  21. package/dist/core 2/adapters/codebuddy-adapter.js +82 -0
  22. package/dist/core 2/adapters/codex-adapter.d.ts +24 -0
  23. package/dist/core 2/adapters/codex-adapter.js +79 -0
  24. package/dist/core 2/adapters/copilot-instructions-generator.d.ts +26 -0
  25. package/dist/core 2/adapters/copilot-instructions-generator.js +104 -0
  26. package/dist/core 2/adapters/crush-adapter.d.ts +35 -0
  27. package/dist/core 2/adapters/crush-adapter.js +49 -0
  28. package/dist/core 2/adapters/cursor-adapter.d.ts +25 -0
  29. package/dist/core 2/adapters/cursor-adapter.js +40 -0
  30. package/dist/core 2/adapters/droid-adapter.d.ts +33 -0
  31. package/dist/core 2/adapters/droid-adapter.js +57 -0
  32. package/dist/core 2/adapters/gemini-adapter.d.ts +27 -0
  33. package/dist/core 2/adapters/gemini-adapter.js +90 -0
  34. package/dist/core 2/adapters/kilocode-adapter.d.ts +34 -0
  35. package/dist/core 2/adapters/kilocode-adapter.js +49 -0
  36. package/dist/core 2/adapters/octo-md-generator.d.ts +26 -0
  37. package/dist/core 2/adapters/octo-md-generator.js +102 -0
  38. package/dist/core 2/adapters/opencode-adapter.d.ts +33 -0
  39. package/dist/core 2/adapters/opencode-adapter.js +56 -0
  40. package/dist/core 2/adapters/qwen-adapter.d.ts +27 -0
  41. package/dist/core 2/adapters/qwen-adapter.js +90 -0
  42. package/dist/core 2/adapters/roocode-adapter.d.ts +40 -0
  43. package/dist/core 2/adapters/roocode-adapter.js +68 -0
  44. package/dist/core 2/adapters/warp-md-generator.d.ts +17 -0
  45. package/dist/core 2/adapters/warp-md-generator.js +88 -0
  46. package/dist/core 2/adapters/windsurf-adapter.d.ts +34 -0
  47. package/dist/core 2/adapters/windsurf-adapter.js +49 -0
  48. package/dist/core 2/agent-manager.d.ts +51 -0
  49. package/dist/core 2/agent-manager.js +126 -0
  50. package/dist/core 2/archive-manager.d.ts +100 -0
  51. package/dist/core 2/archive-manager.js +338 -0
  52. package/dist/core 2/conversation-analyzer.d.ts +86 -0
  53. package/dist/core 2/doc-injector.d.ts +51 -0
  54. package/dist/core 2/doc-injector.js +236 -0
  55. package/dist/core 2/git-manager.d.ts +100 -0
  56. package/dist/core 2/git-manager.js +214 -0
  57. package/dist/core 2/prompt-optimizer.d.ts +268 -0
  58. package/dist/core 2/prompt-optimizer.js +963 -0
  59. package/dist/core 2/question-engine.d.ts +167 -0
  60. package/dist/core 2/question-engine.js +395 -0
  61. package/dist/core 2/session-manager.d.ts +139 -0
  62. package/dist/core 2/session-manager.js +403 -0
  63. package/dist/core 2/task-manager.d.ts +155 -0
  64. package/dist/core 2/task-manager.js +689 -0
  65. package/dist/index.js +6 -0
  66. package/dist/utils/template-loader.js +24 -22
  67. package/package.json +1 -1
  68. package/dist/templates/slash-commands/augment/archive.md +0 -291
  69. package/dist/templates/slash-commands/augment/deep.md +0 -207
  70. package/dist/templates/slash-commands/augment/fast.md +0 -183
  71. package/dist/templates/slash-commands/augment/implement.md +0 -267
  72. package/dist/templates/slash-commands/augment/plan.md +0 -173
  73. package/dist/templates/slash-commands/augment/prd.md +0 -178
  74. package/dist/templates/slash-commands/augment/start.md +0 -142
  75. package/dist/templates/slash-commands/augment/summarize.md +0 -179
  76. package/dist/templates/slash-commands/claude-code/archive.md +0 -291
  77. package/dist/templates/slash-commands/claude-code/deep.md +0 -207
  78. package/dist/templates/slash-commands/claude-code/fast.md +0 -183
  79. package/dist/templates/slash-commands/claude-code/implement.md +0 -267
  80. package/dist/templates/slash-commands/claude-code/plan.md +0 -173
  81. package/dist/templates/slash-commands/claude-code/prd.md +0 -178
  82. package/dist/templates/slash-commands/claude-code/start.md +0 -142
  83. package/dist/templates/slash-commands/claude-code/summarize.md +0 -179
  84. package/dist/templates/slash-commands/cline/archive.md +0 -291
  85. package/dist/templates/slash-commands/cline/deep.md +0 -207
  86. package/dist/templates/slash-commands/cline/fast.md +0 -183
  87. package/dist/templates/slash-commands/cline/implement.md +0 -267
  88. package/dist/templates/slash-commands/cline/plan.md +0 -173
  89. package/dist/templates/slash-commands/cline/prd.md +0 -178
  90. package/dist/templates/slash-commands/cline/start.md +0 -142
  91. package/dist/templates/slash-commands/cline/summarize.md +0 -179
  92. package/dist/templates/slash-commands/codebuddy/archive.md +0 -291
  93. package/dist/templates/slash-commands/codebuddy/deep.md +0 -207
  94. package/dist/templates/slash-commands/codebuddy/fast.md +0 -183
  95. package/dist/templates/slash-commands/codebuddy/implement.md +0 -267
  96. package/dist/templates/slash-commands/codebuddy/plan.md +0 -173
  97. package/dist/templates/slash-commands/codebuddy/prd.md +0 -178
  98. package/dist/templates/slash-commands/codebuddy/start.md +0 -142
  99. package/dist/templates/slash-commands/codebuddy/summarize.md +0 -179
  100. package/dist/templates/slash-commands/codex/archive.md +0 -291
  101. package/dist/templates/slash-commands/codex/deep.md +0 -207
  102. package/dist/templates/slash-commands/codex/fast.md +0 -183
  103. package/dist/templates/slash-commands/codex/implement.md +0 -267
  104. package/dist/templates/slash-commands/codex/plan.md +0 -173
  105. package/dist/templates/slash-commands/codex/prd.md +0 -178
  106. package/dist/templates/slash-commands/codex/start.md +0 -142
  107. package/dist/templates/slash-commands/codex/summarize.md +0 -179
  108. package/dist/templates/slash-commands/crush/archive.md +0 -291
  109. package/dist/templates/slash-commands/crush/deep.md +0 -207
  110. package/dist/templates/slash-commands/crush/fast.md +0 -183
  111. package/dist/templates/slash-commands/crush/implement.md +0 -267
  112. package/dist/templates/slash-commands/crush/plan.md +0 -173
  113. package/dist/templates/slash-commands/crush/prd.md +0 -178
  114. package/dist/templates/slash-commands/crush/start.md +0 -142
  115. package/dist/templates/slash-commands/crush/summarize.md +0 -179
  116. package/dist/templates/slash-commands/cursor/archive.md +0 -291
  117. package/dist/templates/slash-commands/cursor/deep.md +0 -207
  118. package/dist/templates/slash-commands/cursor/fast.md +0 -183
  119. package/dist/templates/slash-commands/cursor/implement.md +0 -267
  120. package/dist/templates/slash-commands/cursor/plan.md +0 -173
  121. package/dist/templates/slash-commands/cursor/prd.md +0 -178
  122. package/dist/templates/slash-commands/cursor/start.md +0 -142
  123. package/dist/templates/slash-commands/cursor/summarize.md +0 -179
  124. package/dist/templates/slash-commands/droid/archive.md +0 -291
  125. package/dist/templates/slash-commands/droid/deep.md +0 -207
  126. package/dist/templates/slash-commands/droid/fast.md +0 -183
  127. package/dist/templates/slash-commands/droid/implement.md +0 -267
  128. package/dist/templates/slash-commands/droid/plan.md +0 -173
  129. package/dist/templates/slash-commands/droid/prd.md +0 -178
  130. package/dist/templates/slash-commands/droid/start.md +0 -142
  131. package/dist/templates/slash-commands/droid/summarize.md +0 -179
  132. package/dist/templates/slash-commands/gemini/archive.toml +0 -290
  133. package/dist/templates/slash-commands/gemini/deep.toml +0 -206
  134. package/dist/templates/slash-commands/gemini/fast.toml +0 -182
  135. package/dist/templates/slash-commands/gemini/implement.toml +0 -266
  136. package/dist/templates/slash-commands/gemini/plan.toml +0 -170
  137. package/dist/templates/slash-commands/gemini/prd.toml +0 -177
  138. package/dist/templates/slash-commands/gemini/start.toml +0 -141
  139. package/dist/templates/slash-commands/gemini/summarize.toml +0 -178
  140. package/dist/templates/slash-commands/kilocode/archive.md +0 -291
  141. package/dist/templates/slash-commands/kilocode/deep.md +0 -207
  142. package/dist/templates/slash-commands/kilocode/fast.md +0 -183
  143. package/dist/templates/slash-commands/kilocode/implement.md +0 -267
  144. package/dist/templates/slash-commands/kilocode/plan.md +0 -173
  145. package/dist/templates/slash-commands/kilocode/prd.md +0 -178
  146. package/dist/templates/slash-commands/kilocode/start.md +0 -142
  147. package/dist/templates/slash-commands/kilocode/summarize.md +0 -179
  148. package/dist/templates/slash-commands/opencode/archive.md +0 -291
  149. package/dist/templates/slash-commands/opencode/deep.md +0 -207
  150. package/dist/templates/slash-commands/opencode/fast.md +0 -183
  151. package/dist/templates/slash-commands/opencode/implement.md +0 -267
  152. package/dist/templates/slash-commands/opencode/plan.md +0 -173
  153. package/dist/templates/slash-commands/opencode/prd.md +0 -178
  154. package/dist/templates/slash-commands/opencode/start.md +0 -142
  155. package/dist/templates/slash-commands/opencode/summarize.md +0 -179
  156. package/dist/templates/slash-commands/qwen/archive.toml +0 -290
  157. package/dist/templates/slash-commands/qwen/deep.toml +0 -206
  158. package/dist/templates/slash-commands/qwen/fast.toml +0 -182
  159. package/dist/templates/slash-commands/qwen/implement.toml +0 -266
  160. package/dist/templates/slash-commands/qwen/plan.toml +0 -170
  161. package/dist/templates/slash-commands/qwen/prd.toml +0 -177
  162. package/dist/templates/slash-commands/qwen/start.toml +0 -141
  163. package/dist/templates/slash-commands/qwen/summarize.toml +0 -178
  164. package/dist/templates/slash-commands/roocode/archive.md +0 -291
  165. package/dist/templates/slash-commands/roocode/deep.md +0 -207
  166. package/dist/templates/slash-commands/roocode/fast.md +0 -183
  167. package/dist/templates/slash-commands/roocode/implement.md +0 -267
  168. package/dist/templates/slash-commands/roocode/plan.md +0 -173
  169. package/dist/templates/slash-commands/roocode/prd.md +0 -178
  170. package/dist/templates/slash-commands/roocode/start.md +0 -142
  171. package/dist/templates/slash-commands/roocode/summarize.md +0 -179
  172. package/dist/templates/slash-commands/windsurf/archive.md +0 -291
  173. package/dist/templates/slash-commands/windsurf/deep.md +0 -207
  174. package/dist/templates/slash-commands/windsurf/fast.md +0 -183
  175. package/dist/templates/slash-commands/windsurf/implement.md +0 -267
  176. package/dist/templates/slash-commands/windsurf/plan.md +0 -173
  177. package/dist/templates/slash-commands/windsurf/prd.md +0 -178
  178. package/dist/templates/slash-commands/windsurf/start.md +0 -142
  179. package/dist/templates/slash-commands/windsurf/summarize.md +0 -179
  180. /package/dist/templates/slash-commands/{amp → _canonical}/archive.md +0 -0
  181. /package/dist/templates/slash-commands/{amp → _canonical}/deep.md +0 -0
  182. /package/dist/templates/slash-commands/{amp → _canonical}/fast.md +0 -0
  183. /package/dist/templates/slash-commands/{amp → _canonical}/implement.md +0 -0
  184. /package/dist/templates/slash-commands/{amp → _canonical}/plan.md +0 -0
  185. /package/dist/templates/slash-commands/{amp → _canonical}/prd.md +0 -0
  186. /package/dist/templates/slash-commands/{amp → _canonical}/start.md +0 -0
  187. /package/dist/templates/slash-commands/{amp → _canonical}/summarize.md +0 -0
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DocInjector = void 0;
37
+ const path = __importStar(require("path"));
38
+ const file_system_1 = require("../utils/file-system");
39
+ const errors_1 = require("../types/errors");
40
+ /**
41
+ * DocInjector - manages injection and updating of managed blocks in documentation files
42
+ */
43
+ class DocInjector {
44
+ /**
45
+ * Inject or update managed block in a file
46
+ */
47
+ static async injectBlock(filePath, content, options) {
48
+ const opts = {
49
+ startMarker: options?.startMarker || this.DEFAULT_START_MARKER,
50
+ endMarker: options?.endMarker || this.DEFAULT_END_MARKER,
51
+ content,
52
+ createIfMissing: options?.createIfMissing ?? true,
53
+ validateMarkdown: options?.validateMarkdown ?? true,
54
+ };
55
+ const fullPath = path.resolve(filePath);
56
+ let fileContent = '';
57
+ // Read existing file or create new
58
+ if (await file_system_1.FileSystem.exists(fullPath)) {
59
+ fileContent = await file_system_1.FileSystem.readFile(fullPath);
60
+ }
61
+ else if (!opts.createIfMissing) {
62
+ throw new errors_1.DataError(`File not found: ${filePath}`, 'Set createIfMissing: true to create the file automatically');
63
+ }
64
+ // Build the managed block
65
+ const blockRegex = new RegExp(`${this.escapeRegex(opts.startMarker)}[\\s\\S]*?${this.escapeRegex(opts.endMarker)}`, 'g');
66
+ const wrappedContent = this.wrapContent(opts.content, opts.startMarker, opts.endMarker);
67
+ if (blockRegex.test(fileContent)) {
68
+ // Replace existing block
69
+ await file_system_1.FileSystem.backup(fullPath);
70
+ fileContent = fileContent.replace(blockRegex, wrappedContent);
71
+ }
72
+ else {
73
+ // Append new block
74
+ if (fileContent && !fileContent.endsWith('\n\n')) {
75
+ fileContent += '\n\n';
76
+ }
77
+ fileContent += wrappedContent + '\n';
78
+ }
79
+ // Validate markdown if requested
80
+ if (opts.validateMarkdown) {
81
+ this.validateMarkdown(fileContent);
82
+ }
83
+ try {
84
+ // Ensure parent directory exists
85
+ const dir = path.dirname(fullPath);
86
+ await file_system_1.FileSystem.ensureDir(dir);
87
+ await file_system_1.FileSystem.writeFileAtomic(fullPath, fileContent);
88
+ }
89
+ catch (error) {
90
+ // Attempt to restore backup
91
+ if (await file_system_1.FileSystem.exists(`${fullPath}.backup`)) {
92
+ await file_system_1.FileSystem.restoreBackup(fullPath);
93
+ }
94
+ throw error;
95
+ }
96
+ }
97
+ /**
98
+ * Detect if file contains managed block
99
+ */
100
+ static async hasBlock(filePath, startMarker, endMarker) {
101
+ const start = startMarker || this.DEFAULT_START_MARKER;
102
+ const end = endMarker || this.DEFAULT_END_MARKER;
103
+ if (!(await file_system_1.FileSystem.exists(filePath))) {
104
+ return false;
105
+ }
106
+ const content = await file_system_1.FileSystem.readFile(filePath);
107
+ const blockRegex = new RegExp(`${this.escapeRegex(start)}[\\s\\S]*?${this.escapeRegex(end)}`, 'g');
108
+ return blockRegex.test(content);
109
+ }
110
+ /**
111
+ * Extract content from managed block
112
+ */
113
+ static async extractBlock(filePath, startMarker, endMarker) {
114
+ const start = startMarker || this.DEFAULT_START_MARKER;
115
+ const end = endMarker || this.DEFAULT_END_MARKER;
116
+ if (!(await file_system_1.FileSystem.exists(filePath))) {
117
+ return null;
118
+ }
119
+ const content = await file_system_1.FileSystem.readFile(filePath);
120
+ const blockRegex = new RegExp(`${this.escapeRegex(start)}([\\s\\S]*?)${this.escapeRegex(end)}`, 'g');
121
+ const match = blockRegex.exec(content);
122
+ return match ? match[1].trim() : null;
123
+ }
124
+ /**
125
+ * Remove managed block from file
126
+ */
127
+ static async removeBlock(filePath, startMarker, endMarker) {
128
+ const start = startMarker || this.DEFAULT_START_MARKER;
129
+ const end = endMarker || this.DEFAULT_END_MARKER;
130
+ if (!(await file_system_1.FileSystem.exists(filePath))) {
131
+ return;
132
+ }
133
+ const content = await file_system_1.FileSystem.readFile(filePath);
134
+ const blockRegex = new RegExp(`${this.escapeRegex(start)}[\\s\\S]*?${this.escapeRegex(end)}\\n?`, 'g');
135
+ if (blockRegex.test(content)) {
136
+ await file_system_1.FileSystem.backup(filePath);
137
+ const updated = content.replace(blockRegex, '');
138
+ await file_system_1.FileSystem.writeFileAtomic(filePath, updated);
139
+ }
140
+ }
141
+ /**
142
+ * Wrap content with markers
143
+ */
144
+ static wrapContent(content, startMarker, endMarker) {
145
+ return `${startMarker}\n${content}\n${endMarker}`;
146
+ }
147
+ /**
148
+ * Escape special regex characters
149
+ */
150
+ static escapeRegex(str) {
151
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
152
+ }
153
+ /**
154
+ * Basic markdown validation
155
+ */
156
+ static validateMarkdown(content) {
157
+ // Check for balanced code blocks
158
+ const codeBlockMarkers = (content.match(/```/g) || []).length;
159
+ if (codeBlockMarkers % 2 !== 0) {
160
+ throw new errors_1.DataError('Invalid markdown: Unbalanced code blocks');
161
+ }
162
+ // Check for balanced brackets
163
+ const openBrackets = (content.match(/\[/g) || []).length;
164
+ const closeBrackets = (content.match(/\]/g) || []).length;
165
+ if (openBrackets !== closeBrackets) {
166
+ console.warn('Warning: Unbalanced brackets in markdown');
167
+ }
168
+ }
169
+ /**
170
+ * Create default AGENTS.md content
171
+ */
172
+ static getDefaultAgentsContent() {
173
+ return `# AI Agent Instructions
174
+
175
+ This file contains instructions for AI agents working with this project.
176
+
177
+ <!-- CLAVIX:START -->
178
+ # Clavix - Prompt Improvement Assistant
179
+
180
+ Clavix is installed in this project. Use the following slash commands:
181
+
182
+ - \`/clavix:fast [prompt]\` - Quick prompt improvements with smart triage
183
+ - \`/clavix:deep [prompt]\` - Comprehensive prompt analysis
184
+ - \`/clavix:prd\` - Generate a PRD through guided questions
185
+ - \`/clavix:start\` - Start conversational mode for iterative refinement
186
+ - \`/clavix:summarize\` - Extract optimized prompt from conversation
187
+
188
+ **When to use:**
189
+ - **Fast mode**: Quick cleanup for simple prompts
190
+ - **Deep mode**: Comprehensive analysis for complex requirements
191
+ - **PRD mode**: Strategic planning with architecture and business impact
192
+
193
+ For more information, run \`clavix --help\` in your terminal.
194
+ <!-- CLAVIX:END -->
195
+ `;
196
+ }
197
+ /**
198
+ * Create default CLAUDE.md content for Claude Code
199
+ */
200
+ static getDefaultClaudeContent() {
201
+ return `# Claude Code Instructions
202
+
203
+ <!-- CLAVIX:START -->
204
+ ## Clavix Integration
205
+
206
+ This project uses Clavix for prompt improvement and PRD generation. The following slash commands are available:
207
+
208
+ ### /clavix:fast [prompt]
209
+ Quick prompt improvements with smart triage. Clavix will analyze your prompt and recommend deep analysis if needed. Perfect for making "shitty prompts good" quickly.
210
+
211
+ ### /clavix:deep [prompt]
212
+ Comprehensive prompt analysis with alternative phrasings, edge cases, implementation examples, and potential issues. Use for complex requirements or when you want thorough exploration.
213
+
214
+ ### /clavix:prd
215
+ Launch the PRD generation workflow. Clavix will guide you through strategic questions and generate both a comprehensive PRD and a quick-reference version optimized for AI consumption.
216
+
217
+ ### /clavix:start
218
+ Enter conversational mode for iterative prompt development. Discuss your requirements naturally, and later use \`/clavix:summarize\` to extract an optimized prompt.
219
+
220
+ ### /clavix:summarize
221
+ Analyze the current conversation and extract key requirements into a structured prompt and mini-PRD.
222
+
223
+ **When to use which mode:**
224
+ - **Fast mode** (\`/clavix:fast\`): Quick cleanup for simple prompts
225
+ - **Deep mode** (\`/clavix:deep\`): Comprehensive analysis for complex requirements
226
+ - **PRD mode** (\`/clavix:prd\`): Strategic planning with architecture and business impact
227
+
228
+ **Pro tip**: Start complex features with \`/clavix:prd\` or \`/clavix:start\` to ensure clear requirements before implementation.
229
+ <!-- CLAVIX:END -->
230
+ `;
231
+ }
232
+ }
233
+ exports.DocInjector = DocInjector;
234
+ DocInjector.DEFAULT_START_MARKER = '<!-- CLAVIX:START -->';
235
+ DocInjector.DEFAULT_END_MARKER = '<!-- CLAVIX:END -->';
236
+ //# sourceMappingURL=doc-injector.js.map
@@ -0,0 +1,100 @@
1
+ /**
2
+ * GitManager - Manages git auto-commit functionality for task implementation
3
+ *
4
+ * This class handles:
5
+ * - Checking git repository status
6
+ * - Creating commits based on user preferences
7
+ * - Generating commit messages
8
+ * - Handling commit strategies (per task, per phase, per N tasks)
9
+ */
10
+ /**
11
+ * Git commit strategy options
12
+ */
13
+ export type CommitStrategy = 'per-phase' | 'per-5-tasks' | 'per-task' | 'none';
14
+ /**
15
+ * Options for creating a commit
16
+ */
17
+ export interface CommitOptions {
18
+ tasks: string[];
19
+ phase?: string;
20
+ projectName?: string;
21
+ }
22
+ /**
23
+ * GitManager class
24
+ *
25
+ * Handles git operations for the implement command
26
+ */
27
+ export declare class GitManager {
28
+ /**
29
+ * Check if current directory is a git repository
30
+ */
31
+ isGitRepository(): Promise<boolean>;
32
+ /**
33
+ * Check if there are uncommitted changes
34
+ */
35
+ hasUncommittedChanges(): Promise<boolean>;
36
+ /**
37
+ * Create a commit with the given tasks
38
+ */
39
+ createCommit(options: CommitOptions): Promise<boolean>;
40
+ /**
41
+ * Generate commit message from tasks
42
+ */
43
+ private generateCommitMessage;
44
+ /**
45
+ * Escape commit message for shell
46
+ */
47
+ private escapeCommitMessage;
48
+ /**
49
+ * Get the current branch name
50
+ */
51
+ getCurrentBranch(): Promise<string>;
52
+ /**
53
+ * Check if working directory is clean
54
+ */
55
+ isWorkingDirectoryClean(): Promise<boolean>;
56
+ /**
57
+ * Get short status for display
58
+ */
59
+ getStatus(): Promise<string>;
60
+ /**
61
+ * Validate git setup before implementing
62
+ */
63
+ validateGitSetup(): Promise<{
64
+ isRepo: boolean;
65
+ hasChanges: boolean;
66
+ currentBranch: string;
67
+ }>;
68
+ }
69
+ /**
70
+ * Helper class to track when to commit based on strategy
71
+ */
72
+ export declare class CommitScheduler {
73
+ private strategy;
74
+ private completedTasksInPhase;
75
+ private completedTasksTotal;
76
+ private completedTasksSinceLastCommit;
77
+ private currentPhase;
78
+ constructor(strategy: CommitStrategy);
79
+ /**
80
+ * Mark a task as completed and check if commit should be made
81
+ */
82
+ taskCompleted(taskPhase: string): boolean;
83
+ /**
84
+ * Mark a phase as completed
85
+ */
86
+ phaseCompleted(): boolean;
87
+ /**
88
+ * Check if a commit should be made now
89
+ */
90
+ private shouldCommit;
91
+ /**
92
+ * Reset commit counter (after a commit is made)
93
+ */
94
+ resetCommitCounter(): void;
95
+ /**
96
+ * Get accumulated task count for commit message
97
+ */
98
+ getTaskCountSinceLastCommit(): number;
99
+ }
100
+ //# sourceMappingURL=git-manager.d.ts.map
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ /**
3
+ * GitManager - Manages git auto-commit functionality for task implementation
4
+ *
5
+ * This class handles:
6
+ * - Checking git repository status
7
+ * - Creating commits based on user preferences
8
+ * - Generating commit messages
9
+ * - Handling commit strategies (per task, per phase, per N tasks)
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CommitScheduler = exports.GitManager = void 0;
13
+ const child_process_1 = require("child_process");
14
+ const util_1 = require("util");
15
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
16
+ /**
17
+ * GitManager class
18
+ *
19
+ * Handles git operations for the implement command
20
+ */
21
+ class GitManager {
22
+ /**
23
+ * Check if current directory is a git repository
24
+ */
25
+ async isGitRepository() {
26
+ try {
27
+ await execAsync('git rev-parse --git-dir');
28
+ return true;
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ /**
35
+ * Check if there are uncommitted changes
36
+ */
37
+ async hasUncommittedChanges() {
38
+ try {
39
+ const { stdout } = await execAsync('git status --porcelain');
40
+ return stdout.trim().length > 0;
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ }
46
+ /**
47
+ * Create a commit with the given tasks
48
+ */
49
+ async createCommit(options) {
50
+ try {
51
+ // Check for changes first
52
+ if (!(await this.hasUncommittedChanges())) {
53
+ return false; // No changes to commit
54
+ }
55
+ // Stage all changes
56
+ await execAsync('git add .');
57
+ // Generate commit message
58
+ const message = this.generateCommitMessage(options);
59
+ // Create commit
60
+ await execAsync(`git commit -m "${this.escapeCommitMessage(message)}"`);
61
+ return true;
62
+ }
63
+ catch (error) {
64
+ // If commit fails, log but don't throw
65
+ console.error('Git commit failed:', error);
66
+ return false;
67
+ }
68
+ }
69
+ /**
70
+ * Generate commit message from tasks
71
+ */
72
+ generateCommitMessage(options) {
73
+ const { tasks, phase, projectName } = options;
74
+ let message = '';
75
+ // Header
76
+ if (phase) {
77
+ message += `clavix: ${phase}\n\n`;
78
+ }
79
+ else if (tasks.length === 1) {
80
+ message += `clavix: ${tasks[0]}\n\n`;
81
+ }
82
+ else {
83
+ message += `clavix: implement ${tasks.length} tasks\n\n`;
84
+ }
85
+ // Task list
86
+ message += 'Completed tasks:\n';
87
+ tasks.forEach((task) => {
88
+ message += `- ${task}\n`;
89
+ });
90
+ // Footer
91
+ message += '\n';
92
+ if (projectName) {
93
+ message += `Project: ${projectName}\n`;
94
+ }
95
+ message += 'Generated by Clavix /clavix:implement';
96
+ return message;
97
+ }
98
+ /**
99
+ * Escape commit message for shell
100
+ */
101
+ escapeCommitMessage(message) {
102
+ return message.replace(/"/g, '\\"').replace(/\n/g, '\\n');
103
+ }
104
+ /**
105
+ * Get the current branch name
106
+ */
107
+ async getCurrentBranch() {
108
+ try {
109
+ const { stdout } = await execAsync('git rev-parse --abbrev-ref HEAD');
110
+ return stdout.trim();
111
+ }
112
+ catch {
113
+ return 'unknown';
114
+ }
115
+ }
116
+ /**
117
+ * Check if working directory is clean
118
+ */
119
+ async isWorkingDirectoryClean() {
120
+ return !(await this.hasUncommittedChanges());
121
+ }
122
+ /**
123
+ * Get short status for display
124
+ */
125
+ async getStatus() {
126
+ try {
127
+ const { stdout } = await execAsync('git status --short');
128
+ return stdout.trim();
129
+ }
130
+ catch {
131
+ return 'Unable to get git status';
132
+ }
133
+ }
134
+ /**
135
+ * Validate git setup before implementing
136
+ */
137
+ async validateGitSetup() {
138
+ const isRepo = await this.isGitRepository();
139
+ const hasChanges = await this.hasUncommittedChanges();
140
+ const currentBranch = isRepo ? await this.getCurrentBranch() : '';
141
+ return {
142
+ isRepo,
143
+ hasChanges,
144
+ currentBranch,
145
+ };
146
+ }
147
+ }
148
+ exports.GitManager = GitManager;
149
+ /**
150
+ * Helper class to track when to commit based on strategy
151
+ */
152
+ class CommitScheduler {
153
+ constructor(strategy) {
154
+ this.strategy = strategy;
155
+ this.completedTasksInPhase = 0;
156
+ this.completedTasksTotal = 0;
157
+ this.completedTasksSinceLastCommit = 0;
158
+ this.currentPhase = '';
159
+ }
160
+ /**
161
+ * Mark a task as completed and check if commit should be made
162
+ */
163
+ taskCompleted(taskPhase) {
164
+ this.completedTasksTotal++;
165
+ this.completedTasksSinceLastCommit++;
166
+ if (taskPhase !== this.currentPhase) {
167
+ this.completedTasksInPhase = 0;
168
+ this.currentPhase = taskPhase;
169
+ }
170
+ this.completedTasksInPhase++;
171
+ return this.shouldCommit();
172
+ }
173
+ /**
174
+ * Mark a phase as completed
175
+ */
176
+ phaseCompleted() {
177
+ // Reset phase counter
178
+ this.completedTasksInPhase = 0;
179
+ // If strategy is per-phase, we should commit
180
+ return this.strategy === 'per-phase';
181
+ }
182
+ /**
183
+ * Check if a commit should be made now
184
+ */
185
+ shouldCommit() {
186
+ switch (this.strategy) {
187
+ case 'per-task':
188
+ return true;
189
+ case 'per-5-tasks':
190
+ return this.completedTasksSinceLastCommit >= 5;
191
+ case 'per-phase':
192
+ // Will be handled by phaseCompleted()
193
+ return false;
194
+ case 'none':
195
+ return false;
196
+ default:
197
+ return false;
198
+ }
199
+ }
200
+ /**
201
+ * Reset commit counter (after a commit is made)
202
+ */
203
+ resetCommitCounter() {
204
+ this.completedTasksSinceLastCommit = 0;
205
+ }
206
+ /**
207
+ * Get accumulated task count for commit message
208
+ */
209
+ getTaskCountSinceLastCommit() {
210
+ return this.completedTasksSinceLastCommit;
211
+ }
212
+ }
213
+ exports.CommitScheduler = CommitScheduler;
214
+ //# sourceMappingURL=git-manager.js.map