clavix 4.12.0 → 5.0.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 (163) hide show
  1. package/README.md +69 -61
  2. package/dist/cli/commands/init.js +54 -153
  3. package/dist/cli/commands/update.js +19 -21
  4. package/dist/templates/agents/agents.md +28 -26
  5. package/dist/templates/agents/copilot-instructions.md +42 -36
  6. package/dist/templates/agents/octo.md +41 -36
  7. package/dist/templates/agents/warp.md +24 -24
  8. package/dist/templates/instructions/README.md +8 -5
  9. package/dist/templates/slash-commands/_canonical/archive.md +83 -121
  10. package/dist/templates/slash-commands/_canonical/execute.md +32 -42
  11. package/dist/templates/slash-commands/_canonical/implement.md +32 -44
  12. package/dist/templates/slash-commands/_canonical/improve.md +13 -52
  13. package/dist/templates/slash-commands/_canonical/plan.md +8 -20
  14. package/dist/templates/slash-commands/_canonical/verify.md +9 -9
  15. package/dist/templates/slash-commands/_components/agent-protocols/assertion-checkpoints.md +1 -1
  16. package/dist/templates/slash-commands/_components/agent-protocols/cli-reference.md +84 -180
  17. package/dist/templates/slash-commands/_components/agent-protocols/decision-rules.md +5 -6
  18. package/dist/templates/slash-commands/_components/agent-protocols/error-handling.md +2 -2
  19. package/dist/templates/slash-commands/_components/agent-protocols/file-formats.md +41 -59
  20. package/dist/templates/slash-commands/_components/agent-protocols/state-awareness.md +5 -7
  21. package/dist/templates/slash-commands/_components/sections/file-saving-protocol.md +20 -27
  22. package/dist/templates/slash-commands/_components/troubleshooting/file-not-saved.md +4 -5
  23. package/dist/templates/slash-commands/_components/troubleshooting/vibecoder-recovery.md +2 -2
  24. package/dist/utils/agent-error-messages.js +13 -12
  25. package/package.json +2 -2
  26. package/dist/cli/commands/analyze.d.ts +0 -17
  27. package/dist/cli/commands/analyze.js +0 -133
  28. package/dist/cli/commands/archive.d.ts +0 -36
  29. package/dist/cli/commands/archive.js +0 -266
  30. package/dist/cli/commands/deep.d.ts +0 -17
  31. package/dist/cli/commands/deep.js +0 -170
  32. package/dist/cli/commands/execute.d.ts +0 -15
  33. package/dist/cli/commands/execute.js +0 -168
  34. package/dist/cli/commands/fast.d.ts +0 -18
  35. package/dist/cli/commands/fast.js +0 -219
  36. package/dist/cli/commands/implement.d.ts +0 -24
  37. package/dist/cli/commands/implement.js +0 -289
  38. package/dist/cli/commands/improve.d.ts +0 -32
  39. package/dist/cli/commands/improve.js +0 -250
  40. package/dist/cli/commands/list.d.ts +0 -17
  41. package/dist/cli/commands/list.js +0 -217
  42. package/dist/cli/commands/plan.d.ts +0 -21
  43. package/dist/cli/commands/plan.js +0 -297
  44. package/dist/cli/commands/prd.d.ts +0 -24
  45. package/dist/cli/commands/prd.js +0 -321
  46. package/dist/cli/commands/prompts/clear.d.ts +0 -16
  47. package/dist/cli/commands/prompts/clear.js +0 -222
  48. package/dist/cli/commands/prompts/list.d.ts +0 -8
  49. package/dist/cli/commands/prompts/list.js +0 -88
  50. package/dist/cli/commands/show.d.ts +0 -21
  51. package/dist/cli/commands/show.js +0 -191
  52. package/dist/cli/commands/start.d.ts +0 -40
  53. package/dist/cli/commands/start.js +0 -210
  54. package/dist/cli/commands/summarize.d.ts +0 -17
  55. package/dist/cli/commands/summarize.js +0 -196
  56. package/dist/cli/commands/task-complete.d.ts +0 -27
  57. package/dist/cli/commands/task-complete.js +0 -269
  58. package/dist/cli/commands/verify.d.ts +0 -28
  59. package/dist/cli/commands/verify.js +0 -349
  60. package/dist/core/archive-manager.d.ts +0 -100
  61. package/dist/core/archive-manager.js +0 -302
  62. package/dist/core/basic-checklist-generator.d.ts +0 -35
  63. package/dist/core/basic-checklist-generator.js +0 -344
  64. package/dist/core/checklist-parser.d.ts +0 -48
  65. package/dist/core/checklist-parser.js +0 -238
  66. package/dist/core/config-manager.d.ts +0 -149
  67. package/dist/core/config-manager.js +0 -230
  68. package/dist/core/conversation-analyzer.d.ts +0 -86
  69. package/dist/core/conversation-analyzer.js +0 -387
  70. package/dist/core/conversation-quality-tracker.d.ts +0 -81
  71. package/dist/core/conversation-quality-tracker.js +0 -195
  72. package/dist/core/git-manager.d.ts +0 -126
  73. package/dist/core/git-manager.js +0 -282
  74. package/dist/core/intelligence/confidence-calculator.d.ts +0 -93
  75. package/dist/core/intelligence/confidence-calculator.js +0 -124
  76. package/dist/core/intelligence/index.d.ts +0 -11
  77. package/dist/core/intelligence/index.js +0 -15
  78. package/dist/core/intelligence/intent-detector.d.ts +0 -54
  79. package/dist/core/intelligence/intent-detector.js +0 -723
  80. package/dist/core/intelligence/pattern-library.d.ts +0 -104
  81. package/dist/core/intelligence/pattern-library.js +0 -330
  82. package/dist/core/intelligence/patterns/actionability-enhancer.d.ts +0 -27
  83. package/dist/core/intelligence/patterns/actionability-enhancer.js +0 -192
  84. package/dist/core/intelligence/patterns/alternative-phrasing-generator.d.ts +0 -29
  85. package/dist/core/intelligence/patterns/alternative-phrasing-generator.js +0 -239
  86. package/dist/core/intelligence/patterns/ambiguity-detector.d.ts +0 -22
  87. package/dist/core/intelligence/patterns/ambiguity-detector.js +0 -196
  88. package/dist/core/intelligence/patterns/assumption-explicitizer.d.ts +0 -30
  89. package/dist/core/intelligence/patterns/assumption-explicitizer.js +0 -296
  90. package/dist/core/intelligence/patterns/base-pattern.d.ts +0 -192
  91. package/dist/core/intelligence/patterns/base-pattern.js +0 -103
  92. package/dist/core/intelligence/patterns/completeness-validator.d.ts +0 -27
  93. package/dist/core/intelligence/patterns/completeness-validator.js +0 -221
  94. package/dist/core/intelligence/patterns/conciseness-filter.d.ts +0 -20
  95. package/dist/core/intelligence/patterns/conciseness-filter.js +0 -92
  96. package/dist/core/intelligence/patterns/context-precision.d.ts +0 -32
  97. package/dist/core/intelligence/patterns/context-precision.js +0 -389
  98. package/dist/core/intelligence/patterns/conversation-summarizer.d.ts +0 -30
  99. package/dist/core/intelligence/patterns/conversation-summarizer.js +0 -277
  100. package/dist/core/intelligence/patterns/dependency-identifier.d.ts +0 -23
  101. package/dist/core/intelligence/patterns/dependency-identifier.js +0 -166
  102. package/dist/core/intelligence/patterns/domain-context-enricher.d.ts +0 -21
  103. package/dist/core/intelligence/patterns/domain-context-enricher.js +0 -198
  104. package/dist/core/intelligence/patterns/edge-case-identifier.d.ts +0 -30
  105. package/dist/core/intelligence/patterns/edge-case-identifier.js +0 -269
  106. package/dist/core/intelligence/patterns/error-tolerance-enhancer.d.ts +0 -22
  107. package/dist/core/intelligence/patterns/error-tolerance-enhancer.js +0 -179
  108. package/dist/core/intelligence/patterns/implicit-requirement-extractor.d.ts +0 -24
  109. package/dist/core/intelligence/patterns/implicit-requirement-extractor.js +0 -259
  110. package/dist/core/intelligence/patterns/objective-clarifier.d.ts +0 -22
  111. package/dist/core/intelligence/patterns/objective-clarifier.js +0 -126
  112. package/dist/core/intelligence/patterns/output-format-enforcer.d.ts +0 -22
  113. package/dist/core/intelligence/patterns/output-format-enforcer.js +0 -151
  114. package/dist/core/intelligence/patterns/prd-structure-enforcer.d.ts +0 -23
  115. package/dist/core/intelligence/patterns/prd-structure-enforcer.js +0 -183
  116. package/dist/core/intelligence/patterns/prerequisite-identifier.d.ts +0 -23
  117. package/dist/core/intelligence/patterns/prerequisite-identifier.js +0 -221
  118. package/dist/core/intelligence/patterns/requirement-prioritizer.d.ts +0 -24
  119. package/dist/core/intelligence/patterns/requirement-prioritizer.js +0 -134
  120. package/dist/core/intelligence/patterns/scope-definer.d.ts +0 -26
  121. package/dist/core/intelligence/patterns/scope-definer.js +0 -236
  122. package/dist/core/intelligence/patterns/step-decomposer.d.ts +0 -31
  123. package/dist/core/intelligence/patterns/step-decomposer.js +0 -242
  124. package/dist/core/intelligence/patterns/structure-organizer.d.ts +0 -31
  125. package/dist/core/intelligence/patterns/structure-organizer.js +0 -218
  126. package/dist/core/intelligence/patterns/success-criteria-enforcer.d.ts +0 -22
  127. package/dist/core/intelligence/patterns/success-criteria-enforcer.js +0 -165
  128. package/dist/core/intelligence/patterns/success-metrics-enforcer.d.ts +0 -24
  129. package/dist/core/intelligence/patterns/success-metrics-enforcer.js +0 -165
  130. package/dist/core/intelligence/patterns/technical-context-enricher.d.ts +0 -25
  131. package/dist/core/intelligence/patterns/technical-context-enricher.js +0 -165
  132. package/dist/core/intelligence/patterns/topic-coherence-analyzer.d.ts +0 -26
  133. package/dist/core/intelligence/patterns/topic-coherence-analyzer.js +0 -300
  134. package/dist/core/intelligence/patterns/user-persona-enricher.d.ts +0 -24
  135. package/dist/core/intelligence/patterns/user-persona-enricher.js +0 -141
  136. package/dist/core/intelligence/patterns/validation-checklist-creator.d.ts +0 -31
  137. package/dist/core/intelligence/patterns/validation-checklist-creator.js +0 -242
  138. package/dist/core/intelligence/quality-assessor.d.ts +0 -71
  139. package/dist/core/intelligence/quality-assessor.js +0 -525
  140. package/dist/core/intelligence/types.d.ts +0 -111
  141. package/dist/core/intelligence/types.js +0 -3
  142. package/dist/core/intelligence/universal-optimizer.d.ts +0 -91
  143. package/dist/core/intelligence/universal-optimizer.js +0 -399
  144. package/dist/core/prd-generator.d.ts +0 -76
  145. package/dist/core/prd-generator.js +0 -173
  146. package/dist/core/prompt-manager.d.ts +0 -110
  147. package/dist/core/prompt-manager.js +0 -274
  148. package/dist/core/prompt-optimizer.d.ts +0 -268
  149. package/dist/core/prompt-optimizer.js +0 -959
  150. package/dist/core/question-engine.d.ts +0 -167
  151. package/dist/core/question-engine.js +0 -356
  152. package/dist/core/session-manager.d.ts +0 -139
  153. package/dist/core/session-manager.js +0 -365
  154. package/dist/core/task-manager.d.ts +0 -211
  155. package/dist/core/task-manager.js +0 -981
  156. package/dist/core/verification-hooks.d.ts +0 -67
  157. package/dist/core/verification-hooks.js +0 -309
  158. package/dist/core/verification-manager.d.ts +0 -107
  159. package/dist/core/verification-manager.js +0 -415
  160. package/dist/types/session.d.ts +0 -78
  161. package/dist/types/session.js +0 -8
  162. package/dist/types/verification.d.ts +0 -205
  163. package/dist/types/verification.js +0 -9
@@ -1,297 +0,0 @@
1
- import { Command, Flags } from '@oclif/core';
2
- import chalk from 'chalk';
3
- import inquirer from 'inquirer';
4
- import fs from 'fs-extra';
5
- import * as path from 'path';
6
- import { TaskManager } from '../../core/task-manager.js';
7
- import { SessionManager } from '../../core/session-manager.js';
8
- import { ConversationAnalyzer } from '../../core/conversation-analyzer.js';
9
- import { FileSystem } from '../../utils/file-system.js';
10
- import { AgentErrorMessages } from '../../utils/agent-error-messages.js';
11
- export default class Plan extends Command {
12
- static description = 'Generate implementation task breakdown from PRD';
13
- static examples = [
14
- '<%= config.bin %> <%= command.id %>',
15
- '<%= config.bin %> <%= command.id %> --project my-app',
16
- '<%= config.bin %> <%= command.id %> --prd-path .clavix/outputs/my-project',
17
- '<%= config.bin %> <%= command.id %> --session 1234-5678',
18
- ];
19
- static flags = {
20
- project: Flags.string({
21
- char: 'p',
22
- description: 'PRD project name (defaults to most recent)',
23
- }),
24
- 'prd-path': Flags.string({
25
- description: 'Direct path to PRD directory',
26
- }),
27
- session: Flags.string({
28
- description: 'Session ID to plan from (generates mini-prd.md automatically)',
29
- }),
30
- 'active-session': Flags.boolean({
31
- description: 'Use the most recent active session as input',
32
- default: false,
33
- }),
34
- source: Flags.string({
35
- description: 'Preferred PRD source (auto|full|quick|mini|prompt)',
36
- options: ['auto', 'full', 'quick', 'mini', 'prompt'],
37
- default: 'auto',
38
- }),
39
- 'max-tasks': Flags.integer({
40
- description: 'Maximum tasks per phase',
41
- default: 20,
42
- }),
43
- overwrite: Flags.boolean({
44
- char: 'o',
45
- description: 'Overwrite existing tasks.md file',
46
- default: false,
47
- }),
48
- };
49
- async run() {
50
- const { flags } = await this.parse(Plan);
51
- console.log(chalk.bold.cyan('\nTask Plan Generator\n'));
52
- console.log(chalk.gray('Analyzing PRD and generating implementation tasks...\n'));
53
- try {
54
- this.validateSessionFlags(flags.session, flags['active-session']);
55
- const manager = new TaskManager();
56
- const sourcePreference = (flags.source ?? 'auto');
57
- let projectName = null;
58
- let prdPath = flags['prd-path'] ? path.resolve(flags['prd-path']) : null;
59
- let generatedFromSession = false;
60
- const generatedArtifacts = [];
61
- if (flags.session || flags['active-session']) {
62
- const sessionResult = await this.prepareArtifactsFromSession(flags.session, flags['active-session']);
63
- prdPath = sessionResult.prdPath;
64
- projectName = sessionResult.projectName;
65
- generatedFromSession = true;
66
- generatedArtifacts.push(...sessionResult.generatedArtifacts);
67
- }
68
- let selectedProject = null;
69
- if (!prdPath) {
70
- selectedProject = await this.resolveProjectDirectory(manager, flags.project);
71
- if (!selectedProject) {
72
- this.error(AgentErrorMessages.noPrdFound());
73
- }
74
- prdPath = selectedProject.path;
75
- projectName = selectedProject.name;
76
- }
77
- if (!prdPath) {
78
- throw new Error('Unable to resolve PRD directory.');
79
- }
80
- const resolvedProjectName = projectName ?? path.basename(prdPath);
81
- // Check if tasks.md already exists
82
- const tasksPath = path.join(prdPath, 'tasks.md');
83
- if ((await fs.pathExists(tasksPath)) && !flags.overwrite) {
84
- console.log(chalk.yellow('Warning: tasks.md already exists.'));
85
- console.log(chalk.gray(`Location: ${tasksPath}`));
86
- console.log(chalk.gray('Use --overwrite to regenerate tasks.md.\n'));
87
- return;
88
- }
89
- console.log(chalk.dim('Looking for PRD artifacts...'));
90
- const availableSources = await manager.detectAvailableSources(prdPath);
91
- if (availableSources.length === 0) {
92
- this.error(AgentErrorMessages.noPrdFound());
93
- }
94
- if (sourcePreference !== 'auto' && !availableSources.includes(sourcePreference)) {
95
- this.error(`Preferred source "${sourcePreference}" not found in ${prdPath}\n\n` +
96
- `Available sources: ${availableSources.join(', ') || 'none'}\n` +
97
- 'Hint: Override with --source flag');
98
- }
99
- if (availableSources.length > 1 && sourcePreference === 'auto') {
100
- console.log(chalk.dim(`Found multiple sources (${availableSources.join(', ')}). Selecting best match...`));
101
- }
102
- // Generate tasks
103
- console.log(chalk.dim('Analyzing PRD content...'));
104
- const result = await manager.generateTasksFromPrd(prdPath, {
105
- maxTasksPerPhase: flags['max-tasks'],
106
- includeReferences: true,
107
- clearMode: 'fast',
108
- source: sourcePreference,
109
- });
110
- const chosenSourceFile = path.basename(result.sourcePath);
111
- const usingOverride = sourcePreference !== 'auto';
112
- if (usingOverride) {
113
- console.log(chalk.dim(`Using source: ${chosenSourceFile}`));
114
- }
115
- else {
116
- console.log(chalk.dim(`Using source: ${chosenSourceFile} (override with --source to pick a different artifact).`));
117
- }
118
- // Display results
119
- console.log(chalk.bold.green('\nTask plan generated successfully!\n'));
120
- if (generatedFromSession) {
121
- console.log(chalk.bold('Generated artifacts:'));
122
- generatedArtifacts.forEach((artifact) => {
123
- console.log(chalk.gray(` • ${artifact}`));
124
- });
125
- console.log();
126
- }
127
- console.log(chalk.bold('Summary:'));
128
- console.log(chalk.cyan(` Project: ${resolvedProjectName}`));
129
- console.log(chalk.cyan(` Source: ${chosenSourceFile}`));
130
- console.log(chalk.cyan(` Total Phases: ${result.phases.length}`));
131
- console.log(chalk.cyan(` Total Tasks: ${result.totalTasks}`));
132
- console.log();
133
- console.log(chalk.bold('Task Breakdown:\n'));
134
- for (const phase of result.phases) {
135
- console.log(chalk.bold(` ${phase.name}`));
136
- console.log(chalk.gray(` ${phase.tasks.length} tasks`));
137
- const preview = phase.tasks.slice(0, 3);
138
- preview.forEach((task) => {
139
- console.log(chalk.dim(` • ${task.description}`));
140
- });
141
- if (phase.tasks.length > 3) {
142
- console.log(chalk.dim(` ... and ${phase.tasks.length - 3} more`));
143
- }
144
- console.log();
145
- }
146
- console.log(chalk.bold('Output:'));
147
- console.log(chalk.cyan(` ${result.outputPath}`));
148
- console.log();
149
- console.log(chalk.bold.green('Next Steps:\n'));
150
- console.log(chalk.gray(' 1. Review the generated tasks in tasks.md'));
151
- console.log(chalk.gray(' 2. Edit if needed (add/remove/modify tasks)'));
152
- console.log(chalk.gray(' 3. Run'), chalk.cyan('clavix implement'), chalk.gray('to start implementation'));
153
- console.log();
154
- console.log(chalk.dim('Tip: Tasks are optimized with Clavix Intelligence for optimal AI execution\n'));
155
- }
156
- catch (error) {
157
- const errorMessage = error instanceof Error ? error.message : 'An unexpected error occurred';
158
- this.error(errorMessage);
159
- }
160
- }
161
- validateSessionFlags(session, activeSession) {
162
- if (session && activeSession) {
163
- throw new Error('Use either --session or --active-session, not both.');
164
- }
165
- }
166
- async prepareArtifactsFromSession(sessionId, useActive) {
167
- const sessionManager = new SessionManager();
168
- const analyzer = new ConversationAnalyzer();
169
- let session = null;
170
- if (sessionId) {
171
- session = await sessionManager.getSession(sessionId);
172
- if (!session) {
173
- throw new Error(`Session not found: ${sessionId}`);
174
- }
175
- }
176
- else if (useActive) {
177
- session = await sessionManager.getActiveSession();
178
- if (!session) {
179
- throw new Error('No active session found.');
180
- }
181
- }
182
- if (!session) {
183
- throw new Error('Session resolution failed.');
184
- }
185
- if (session.messages.length === 0) {
186
- throw new Error('Session has no messages to analyze.');
187
- }
188
- console.log(chalk.dim(`Generating mini-PRD from session ${session.id}...`));
189
- const analysis = analyzer.analyze(session);
190
- const projectDirName = this.sanitizeProjectName(session.projectName);
191
- const outputsDir = path.join('.clavix', 'outputs', projectDirName);
192
- await FileSystem.ensureDir(outputsDir);
193
- const miniPrdPath = path.join(outputsDir, 'mini-prd.md');
194
- const promptPath = path.join(outputsDir, 'optimized-prompt.md');
195
- const miniPrdContent = analyzer.generateMiniPrd(session, analysis);
196
- const promptContent = analyzer.generateOptimizedPrompt(session, analysis);
197
- await FileSystem.writeFileAtomic(miniPrdPath, miniPrdContent);
198
- await FileSystem.writeFileAtomic(promptPath, promptContent);
199
- console.log(chalk.dim(`Saved mini-prd.md and optimized-prompt.md to ${outputsDir}.\n`));
200
- return {
201
- prdPath: outputsDir,
202
- projectName: projectDirName,
203
- generatedArtifacts: [miniPrdPath, promptPath],
204
- };
205
- }
206
- async resolveProjectDirectory(manager, projectName) {
207
- const outputsDir = path.join(process.cwd(), '.clavix', 'outputs');
208
- if (!(await fs.pathExists(outputsDir))) {
209
- return null;
210
- }
211
- const entries = await fs.readdir(outputsDir, { withFileTypes: true });
212
- const projects = [];
213
- for (const entry of entries) {
214
- if (!entry.isDirectory()) {
215
- continue;
216
- }
217
- if (entry.name === 'archive') {
218
- continue;
219
- }
220
- const projectPath = path.join(outputsDir, entry.name);
221
- const sources = await manager.detectAvailableSources(projectPath);
222
- if (sources.length === 0) {
223
- continue;
224
- }
225
- const hasTasks = await fs.pathExists(path.join(projectPath, 'tasks.md'));
226
- const stats = await fs.stat(projectPath);
227
- projects.push({
228
- name: entry.name,
229
- path: projectPath,
230
- sources,
231
- hasTasks,
232
- mtime: stats.mtime,
233
- });
234
- }
235
- if (projectName) {
236
- const match = projects.find((project) => project.name === projectName);
237
- if (!match) {
238
- throw new Error(`PRD project not found: ${projectName}`);
239
- }
240
- console.log(chalk.dim(`Selected project: ${match.name}`));
241
- return match;
242
- }
243
- if (projects.length === 0) {
244
- return null;
245
- }
246
- if (projects.length === 1) {
247
- const [project] = projects;
248
- console.log(chalk.dim(`Auto-selected project: ${project.name}`));
249
- return project;
250
- }
251
- if (this.isInteractive()) {
252
- console.log(chalk.bold('Select a PRD project to generate a task plan:\n'));
253
- const choices = projects.map((project) => {
254
- const sourceLabel = project.sources.join('/') || 'prompt';
255
- const taskLabel = project.hasTasks ? 'tasks present' : 'no tasks yet';
256
- return {
257
- name: `${project.name} — sources: ${sourceLabel}; ${taskLabel}`,
258
- value: project.name,
259
- };
260
- });
261
- const response = await inquirer.prompt([
262
- {
263
- type: 'list',
264
- name: 'project',
265
- message: 'Project:',
266
- choices,
267
- },
268
- ]);
269
- const selected = projects.find((project) => project.name === response.project);
270
- if (!selected) {
271
- throw new Error('Project selection failed.');
272
- }
273
- return selected;
274
- }
275
- projects.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
276
- const chosen = projects[0];
277
- console.log(chalk.dim(`Multiple PRD projects found; selected most recent: ${chosen.name}. Use --project to choose explicitly.`));
278
- return chosen;
279
- }
280
- sanitizeProjectName(name) {
281
- const fallback = 'session-project';
282
- if (!name) {
283
- return fallback;
284
- }
285
- const sanitized = name
286
- .toLowerCase()
287
- .replace(/[^a-z0-9-]/g, '-')
288
- .replace(/-+/g, '-')
289
- .replace(/^-|-$/g, '')
290
- .substring(0, 50);
291
- return sanitized || fallback;
292
- }
293
- isInteractive() {
294
- return Boolean(process.stdin.isTTY && process.stdout.isTTY);
295
- }
296
- }
297
- //# sourceMappingURL=plan.js.map
@@ -1,24 +0,0 @@
1
- import { Command } from '@oclif/core';
2
- export default class Prd extends Command {
3
- static description: string;
4
- static examples: string[];
5
- static flags: {
6
- quick: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
- project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
- template: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
- };
10
- run(): Promise<void>;
11
- /**
12
- * Derive a project name from the answers
13
- */
14
- private deriveProjectName;
15
- /**
16
- * Auto-detect project tech stack from common config files
17
- */
18
- private detectProjectTechStack;
19
- /**
20
- * Validate the generated quick-prd.md for AI consumption quality
21
- */
22
- private validatePrdQuality;
23
- }
24
- //# sourceMappingURL=prd.d.ts.map
@@ -1,321 +0,0 @@
1
- import { Command, Flags } from '@oclif/core';
2
- import chalk from 'chalk';
3
- import inquirer from 'inquirer';
4
- import * as path from 'path';
5
- import { fileURLToPath } from 'url';
6
- import { dirname } from 'path';
7
- import fs from 'fs-extra';
8
- import { QuestionEngine } from '../../core/question-engine.js';
9
- import { PrdGenerator } from '../../core/prd-generator.js';
10
- import { UniversalOptimizer } from '../../core/intelligence/index.js';
11
- const __filename = fileURLToPath(import.meta.url);
12
- const __dirname = dirname(__filename);
13
- export default class Prd extends Command {
14
- static description = 'Launch Clavix Planning Mode - transform ideas into structured PRDs through strategic questions';
15
- static examples = [
16
- '<%= config.bin %> <%= command.id %>',
17
- '<%= config.bin %> <%= command.id %> --quick',
18
- '<%= config.bin %> <%= command.id %> --project my-app',
19
- ];
20
- static flags = {
21
- quick: Flags.boolean({
22
- char: 'q',
23
- description: 'Use quick mode with fewer questions',
24
- default: false,
25
- }),
26
- project: Flags.string({
27
- char: 'p',
28
- description: 'Project name for organizing outputs',
29
- }),
30
- template: Flags.string({
31
- char: 't',
32
- description: 'Path to custom question template',
33
- }),
34
- };
35
- async run() {
36
- const { flags } = await this.parse(Prd);
37
- console.log(chalk.bold.cyan('\n🔑 Clavix Planning Mode\n'));
38
- console.log(chalk.gray('Transform your idea into structured requirements through strategic questions.\n'));
39
- console.log(chalk.gray('This will generate two documents:'));
40
- console.log(chalk.gray(' 📄 Full PRD - Comprehensive team-facing document'));
41
- console.log(chalk.gray(' ⚡ Quick PRD - AI-optimized 2-3 paragraph version\n'));
42
- try {
43
- // Initialize QuestionEngine
44
- const engine = new QuestionEngine();
45
- // Determine template path
46
- const templatePath = flags.template || path.join(__dirname, '../../templates/prd-questions.md');
47
- // Load question flow
48
- console.log(chalk.dim('Loading questions...\n'));
49
- const flow = await engine.loadFlow(templatePath);
50
- console.log(chalk.bold(`${flow.name}`));
51
- console.log(chalk.gray(flow.description));
52
- console.log();
53
- // Collect answers through Socratic questioning
54
- const answers = {};
55
- let question = engine.getNextQuestion();
56
- let detectedStack = null;
57
- let stackDetectionDone = false;
58
- while (question) {
59
- const progress = engine.getProgress();
60
- console.log(chalk.dim(`[${progress.current + 1}/${progress.total}]`));
61
- let answer;
62
- if (question.type === 'confirm') {
63
- const response = await inquirer.prompt([
64
- {
65
- type: 'confirm',
66
- name: 'answer',
67
- message: question.text,
68
- default: question.default,
69
- },
70
- ]);
71
- answer = response.answer;
72
- }
73
- else if (question.type === 'list' && question.choices) {
74
- const response = await inquirer.prompt([
75
- {
76
- type: 'list',
77
- name: 'answer',
78
- message: question.text,
79
- choices: question.choices,
80
- },
81
- ]);
82
- answer = response.answer;
83
- }
84
- else {
85
- // Text input
86
- const currentQuestion = question;
87
- // Special handling for tech stack question - auto-detect
88
- if (question.id === 'techStack' && !stackDetectionDone) {
89
- detectedStack = await this.detectProjectTechStack();
90
- stackDetectionDone = true;
91
- if (detectedStack) {
92
- console.log(chalk.cyan(`\n💡 Detected: ${detectedStack}\n`));
93
- const useDetected = await inquirer.prompt([
94
- {
95
- type: 'confirm',
96
- name: 'use',
97
- message: 'Use detected tech stack?',
98
- default: true,
99
- },
100
- ]);
101
- if (useDetected.use) {
102
- answer = detectedStack;
103
- engine.submitAnswer(question.id, answer);
104
- question = engine.getNextQuestion();
105
- continue;
106
- }
107
- }
108
- }
109
- const response = await inquirer.prompt([
110
- {
111
- type: 'input',
112
- name: 'answer',
113
- message: question.text,
114
- default: question.default,
115
- validate: question.validate ||
116
- ((input) => {
117
- if (currentQuestion.required && !input.trim()) {
118
- return 'This field is required';
119
- }
120
- return true;
121
- }),
122
- },
123
- ]);
124
- answer = response.answer;
125
- }
126
- // Submit answer and get next question
127
- engine.submitAnswer(question.id, answer);
128
- answers[question.id] = answer;
129
- question = engine.getNextQuestion();
130
- console.log();
131
- }
132
- console.log(chalk.green('\n✓ All questions answered\n'));
133
- // Determine project name
134
- const projectName = flags.project || this.deriveProjectName(answers);
135
- // Generate PRD documents
136
- console.log(chalk.cyan('📝 Generating PRD documents...\n'));
137
- const generator = new PrdGenerator();
138
- const outputPath = path.join(process.cwd(), '.clavix', 'outputs', projectName);
139
- await fs.ensureDir(outputPath);
140
- // Generate both full and quick PRDs
141
- await generator.generateFullPrd(answers, outputPath);
142
- await generator.generateQuickPrd(answers, outputPath);
143
- console.log(chalk.green('✓ PRD documents generated\n'));
144
- // Validate the quick PRD for AI consumption quality
145
- await this.validatePrdQuality(outputPath);
146
- // Display output locations
147
- console.log(chalk.bold.cyan('📄 Documents Generated:\n'));
148
- console.log(chalk.cyan(` • full-prd.md - Comprehensive team-facing document`));
149
- console.log(chalk.cyan(` • quick-prd.md - AI-optimized 2-3 paragraph version\n`));
150
- console.log(chalk.gray(`Location: ${outputPath}\n`));
151
- // Next steps
152
- console.log(chalk.bold.blue('💡 Next Steps:\n'));
153
- console.log(chalk.blue(' 1. Review the generated documents'));
154
- console.log(chalk.blue(' 2. Run: clavix plan (generate task breakdown)'));
155
- console.log(chalk.blue(' 3. Run: clavix implement (start implementation)\n'));
156
- }
157
- catch (error) {
158
- if (error instanceof Error) {
159
- console.log(chalk.red(`\n✗ Error: ${error.message}\n`));
160
- }
161
- else {
162
- console.log(chalk.red('\n✗ An unexpected error occurred\n'));
163
- }
164
- this.exit(1);
165
- }
166
- }
167
- /**
168
- * Derive a project name from the answers
169
- */
170
- deriveProjectName(answers) {
171
- // Try to extract from first answer (usually "what are we building")
172
- const firstAnswer = Object.values(answers)[0];
173
- if (typeof firstAnswer === 'string') {
174
- // Extract first few words, convert to kebab-case
175
- const words = firstAnswer
176
- .toLowerCase()
177
- .replace(/[^a-z0-9\s]/g, '')
178
- .split(/\s+/)
179
- .filter((w) => w.length > 0)
180
- .slice(0, 3);
181
- if (words.length > 0) {
182
- return words.join('-');
183
- }
184
- }
185
- // Fallback to timestamp
186
- return `project-${Date.now()}`;
187
- }
188
- /**
189
- * Auto-detect project tech stack from common config files
190
- */
191
- async detectProjectTechStack() {
192
- const detectedTech = [];
193
- try {
194
- // Check package.json (Node.js/JavaScript)
195
- if (await fs.pathExists('package.json')) {
196
- const pkg = await fs.readJson('package.json');
197
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
198
- // Detect popular frameworks
199
- if (deps.react)
200
- detectedTech.push('React');
201
- if (deps.vue)
202
- detectedTech.push('Vue');
203
- if (deps.angular)
204
- detectedTech.push('Angular');
205
- if (deps.next)
206
- detectedTech.push('Next.js');
207
- if (deps.astro)
208
- detectedTech.push('Astro');
209
- if (deps.tailwindcss)
210
- detectedTech.push('Tailwind CSS');
211
- if (deps.typescript)
212
- detectedTech.push('TypeScript');
213
- if (deps.express)
214
- detectedTech.push('Express');
215
- if (deps.fastify)
216
- detectedTech.push('Fastify');
217
- if (detectedTech.length === 0)
218
- detectedTech.push('Node.js');
219
- }
220
- // Check requirements.txt (Python)
221
- if (await fs.pathExists('requirements.txt')) {
222
- const content = await fs.readFile('requirements.txt', 'utf-8');
223
- if (content.includes('django'))
224
- detectedTech.push('Django');
225
- if (content.includes('flask'))
226
- detectedTech.push('Flask');
227
- if (content.includes('fastapi'))
228
- detectedTech.push('FastAPI');
229
- if (detectedTech.length === 0)
230
- detectedTech.push('Python');
231
- }
232
- // Check Gemfile (Ruby)
233
- if (await fs.pathExists('Gemfile')) {
234
- const content = await fs.readFile('Gemfile', 'utf-8');
235
- if (content.includes('rails'))
236
- detectedTech.push('Rails');
237
- if (detectedTech.length === 0)
238
- detectedTech.push('Ruby');
239
- }
240
- // Check go.mod (Go)
241
- if (await fs.pathExists('go.mod')) {
242
- detectedTech.push('Go');
243
- }
244
- // Check Cargo.toml (Rust)
245
- if (await fs.pathExists('Cargo.toml')) {
246
- detectedTech.push('Rust');
247
- }
248
- // Check composer.json (PHP)
249
- if (await fs.pathExists('composer.json')) {
250
- const composer = await fs.readJson('composer.json');
251
- if (composer.require?.['laravel/framework'])
252
- detectedTech.push('Laravel');
253
- if (composer.require?.['symfony/symfony'])
254
- detectedTech.push('Symfony');
255
- if (detectedTech.length === 0)
256
- detectedTech.push('PHP');
257
- }
258
- if (detectedTech.length > 0) {
259
- return detectedTech.join(', ');
260
- }
261
- return null;
262
- }
263
- catch {
264
- return null;
265
- }
266
- }
267
- /**
268
- * Validate the generated quick-prd.md for AI consumption quality
269
- */
270
- async validatePrdQuality(outputPath) {
271
- try {
272
- const quickPrdPath = path.join(outputPath, 'quick-prd.md');
273
- // Read the generated quick-prd.md
274
- const prdContent = await fs.readFile(quickPrdPath, 'utf-8');
275
- console.log(chalk.bold.cyan('✅ Validating Quick PRD Quality\n'));
276
- console.log(chalk.gray('Analyzing for AI consumption quality...\n'));
277
- // Run quality assessment (v4.11: use improve mode)
278
- const optimizer = new UniversalOptimizer();
279
- const result = await optimizer.optimize(prdContent, 'improve');
280
- const getScoreColor = (score) => {
281
- if (score >= 80)
282
- return chalk.green;
283
- if (score >= 60)
284
- return chalk.yellow;
285
- return chalk.red;
286
- };
287
- // Display quality assessment
288
- console.log(chalk.bold('📊 Quality Assessment:\n'));
289
- console.log(getScoreColor(result.quality.clarity)(` Clarity: ${result.quality.clarity.toFixed(0)}%`));
290
- console.log(getScoreColor(result.quality.structure)(` Structure: ${result.quality.structure.toFixed(0)}%`));
291
- console.log(getScoreColor(result.quality.completeness)(` Completeness: ${result.quality.completeness.toFixed(0)}%`));
292
- console.log(getScoreColor(result.quality.overall).bold(`\n Overall: ${result.quality.overall.toFixed(0)}%\n`));
293
- if (result.quality.overall >= 80) {
294
- console.log(chalk.green('✨ Excellent! Your Quick PRD is AI-ready.\n'));
295
- }
296
- else if (result.quality.overall >= 70) {
297
- console.log(chalk.yellow('✓ Good quality. Consider the suggestions below:\n'));
298
- if (result.quality.improvements && result.quality.improvements.length > 0) {
299
- result.quality.improvements.forEach((imp) => {
300
- console.log(chalk.yellow(` • ${imp}`));
301
- });
302
- console.log();
303
- }
304
- }
305
- else {
306
- console.log(chalk.yellow('💡 Suggestions for improvement:\n'));
307
- if (result.quality.improvements && result.quality.improvements.length > 0) {
308
- result.quality.improvements.forEach((imp) => {
309
- console.log(chalk.yellow(` • ${imp}`));
310
- });
311
- console.log();
312
- }
313
- }
314
- }
315
- catch {
316
- console.log(chalk.yellow('⚠️ Could not validate PRD quality'));
317
- console.log(chalk.gray('Continuing without validation...\n'));
318
- }
319
- }
320
- }
321
- //# sourceMappingURL=prd.js.map
@@ -1,16 +0,0 @@
1
- import { Command } from '@oclif/core';
2
- export default class PromptsClear extends Command {
3
- static description: string;
4
- static examples: string[];
5
- static flags: {
6
- standard: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
- comprehensive: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
- executed: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
- stale: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
- all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
- force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
- };
13
- run(): Promise<void>;
14
- private interactiveClear;
15
- }
16
- //# sourceMappingURL=clear.d.ts.map