clavix 4.12.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/README.md +69 -61
  2. package/dist/templates/slash-commands/_canonical/archive.md +83 -121
  3. package/dist/templates/slash-commands/_canonical/execute.md +32 -42
  4. package/dist/templates/slash-commands/_canonical/implement.md +32 -44
  5. package/dist/templates/slash-commands/_canonical/improve.md +13 -52
  6. package/dist/templates/slash-commands/_components/agent-protocols/cli-reference.md +84 -180
  7. package/dist/templates/slash-commands/_components/agent-protocols/error-handling.md +2 -2
  8. package/dist/templates/slash-commands/_components/agent-protocols/file-formats.md +41 -59
  9. package/dist/templates/slash-commands/_components/sections/file-saving-protocol.md +20 -27
  10. package/dist/templates/slash-commands/_components/troubleshooting/file-not-saved.md +4 -5
  11. package/package.json +2 -2
  12. package/dist/cli/commands/analyze.d.ts +0 -17
  13. package/dist/cli/commands/analyze.js +0 -133
  14. package/dist/cli/commands/archive.d.ts +0 -36
  15. package/dist/cli/commands/archive.js +0 -266
  16. package/dist/cli/commands/deep.d.ts +0 -17
  17. package/dist/cli/commands/deep.js +0 -170
  18. package/dist/cli/commands/execute.d.ts +0 -15
  19. package/dist/cli/commands/execute.js +0 -168
  20. package/dist/cli/commands/fast.d.ts +0 -18
  21. package/dist/cli/commands/fast.js +0 -219
  22. package/dist/cli/commands/implement.d.ts +0 -24
  23. package/dist/cli/commands/implement.js +0 -289
  24. package/dist/cli/commands/improve.d.ts +0 -32
  25. package/dist/cli/commands/improve.js +0 -250
  26. package/dist/cli/commands/list.d.ts +0 -17
  27. package/dist/cli/commands/list.js +0 -217
  28. package/dist/cli/commands/plan.d.ts +0 -21
  29. package/dist/cli/commands/plan.js +0 -297
  30. package/dist/cli/commands/prd.d.ts +0 -24
  31. package/dist/cli/commands/prd.js +0 -321
  32. package/dist/cli/commands/prompts/clear.d.ts +0 -16
  33. package/dist/cli/commands/prompts/clear.js +0 -222
  34. package/dist/cli/commands/prompts/list.d.ts +0 -8
  35. package/dist/cli/commands/prompts/list.js +0 -88
  36. package/dist/cli/commands/show.d.ts +0 -21
  37. package/dist/cli/commands/show.js +0 -191
  38. package/dist/cli/commands/start.d.ts +0 -40
  39. package/dist/cli/commands/start.js +0 -210
  40. package/dist/cli/commands/summarize.d.ts +0 -17
  41. package/dist/cli/commands/summarize.js +0 -196
  42. package/dist/cli/commands/task-complete.d.ts +0 -27
  43. package/dist/cli/commands/task-complete.js +0 -269
  44. package/dist/cli/commands/verify.d.ts +0 -28
  45. package/dist/cli/commands/verify.js +0 -349
  46. package/dist/core/archive-manager.d.ts +0 -100
  47. package/dist/core/archive-manager.js +0 -302
  48. package/dist/core/basic-checklist-generator.d.ts +0 -35
  49. package/dist/core/basic-checklist-generator.js +0 -344
  50. package/dist/core/checklist-parser.d.ts +0 -48
  51. package/dist/core/checklist-parser.js +0 -238
  52. package/dist/core/config-manager.d.ts +0 -149
  53. package/dist/core/config-manager.js +0 -230
  54. package/dist/core/conversation-analyzer.d.ts +0 -86
  55. package/dist/core/conversation-analyzer.js +0 -387
  56. package/dist/core/conversation-quality-tracker.d.ts +0 -81
  57. package/dist/core/conversation-quality-tracker.js +0 -195
  58. package/dist/core/git-manager.d.ts +0 -126
  59. package/dist/core/git-manager.js +0 -282
  60. package/dist/core/intelligence/confidence-calculator.d.ts +0 -93
  61. package/dist/core/intelligence/confidence-calculator.js +0 -124
  62. package/dist/core/intelligence/index.d.ts +0 -11
  63. package/dist/core/intelligence/index.js +0 -15
  64. package/dist/core/intelligence/intent-detector.d.ts +0 -54
  65. package/dist/core/intelligence/intent-detector.js +0 -723
  66. package/dist/core/intelligence/pattern-library.d.ts +0 -104
  67. package/dist/core/intelligence/pattern-library.js +0 -330
  68. package/dist/core/intelligence/patterns/actionability-enhancer.d.ts +0 -27
  69. package/dist/core/intelligence/patterns/actionability-enhancer.js +0 -192
  70. package/dist/core/intelligence/patterns/alternative-phrasing-generator.d.ts +0 -29
  71. package/dist/core/intelligence/patterns/alternative-phrasing-generator.js +0 -239
  72. package/dist/core/intelligence/patterns/ambiguity-detector.d.ts +0 -22
  73. package/dist/core/intelligence/patterns/ambiguity-detector.js +0 -196
  74. package/dist/core/intelligence/patterns/assumption-explicitizer.d.ts +0 -30
  75. package/dist/core/intelligence/patterns/assumption-explicitizer.js +0 -296
  76. package/dist/core/intelligence/patterns/base-pattern.d.ts +0 -192
  77. package/dist/core/intelligence/patterns/base-pattern.js +0 -103
  78. package/dist/core/intelligence/patterns/completeness-validator.d.ts +0 -27
  79. package/dist/core/intelligence/patterns/completeness-validator.js +0 -221
  80. package/dist/core/intelligence/patterns/conciseness-filter.d.ts +0 -20
  81. package/dist/core/intelligence/patterns/conciseness-filter.js +0 -92
  82. package/dist/core/intelligence/patterns/context-precision.d.ts +0 -32
  83. package/dist/core/intelligence/patterns/context-precision.js +0 -389
  84. package/dist/core/intelligence/patterns/conversation-summarizer.d.ts +0 -30
  85. package/dist/core/intelligence/patterns/conversation-summarizer.js +0 -277
  86. package/dist/core/intelligence/patterns/dependency-identifier.d.ts +0 -23
  87. package/dist/core/intelligence/patterns/dependency-identifier.js +0 -166
  88. package/dist/core/intelligence/patterns/domain-context-enricher.d.ts +0 -21
  89. package/dist/core/intelligence/patterns/domain-context-enricher.js +0 -198
  90. package/dist/core/intelligence/patterns/edge-case-identifier.d.ts +0 -30
  91. package/dist/core/intelligence/patterns/edge-case-identifier.js +0 -269
  92. package/dist/core/intelligence/patterns/error-tolerance-enhancer.d.ts +0 -22
  93. package/dist/core/intelligence/patterns/error-tolerance-enhancer.js +0 -179
  94. package/dist/core/intelligence/patterns/implicit-requirement-extractor.d.ts +0 -24
  95. package/dist/core/intelligence/patterns/implicit-requirement-extractor.js +0 -259
  96. package/dist/core/intelligence/patterns/objective-clarifier.d.ts +0 -22
  97. package/dist/core/intelligence/patterns/objective-clarifier.js +0 -126
  98. package/dist/core/intelligence/patterns/output-format-enforcer.d.ts +0 -22
  99. package/dist/core/intelligence/patterns/output-format-enforcer.js +0 -151
  100. package/dist/core/intelligence/patterns/prd-structure-enforcer.d.ts +0 -23
  101. package/dist/core/intelligence/patterns/prd-structure-enforcer.js +0 -183
  102. package/dist/core/intelligence/patterns/prerequisite-identifier.d.ts +0 -23
  103. package/dist/core/intelligence/patterns/prerequisite-identifier.js +0 -221
  104. package/dist/core/intelligence/patterns/requirement-prioritizer.d.ts +0 -24
  105. package/dist/core/intelligence/patterns/requirement-prioritizer.js +0 -134
  106. package/dist/core/intelligence/patterns/scope-definer.d.ts +0 -26
  107. package/dist/core/intelligence/patterns/scope-definer.js +0 -236
  108. package/dist/core/intelligence/patterns/step-decomposer.d.ts +0 -31
  109. package/dist/core/intelligence/patterns/step-decomposer.js +0 -242
  110. package/dist/core/intelligence/patterns/structure-organizer.d.ts +0 -31
  111. package/dist/core/intelligence/patterns/structure-organizer.js +0 -218
  112. package/dist/core/intelligence/patterns/success-criteria-enforcer.d.ts +0 -22
  113. package/dist/core/intelligence/patterns/success-criteria-enforcer.js +0 -165
  114. package/dist/core/intelligence/patterns/success-metrics-enforcer.d.ts +0 -24
  115. package/dist/core/intelligence/patterns/success-metrics-enforcer.js +0 -165
  116. package/dist/core/intelligence/patterns/technical-context-enricher.d.ts +0 -25
  117. package/dist/core/intelligence/patterns/technical-context-enricher.js +0 -165
  118. package/dist/core/intelligence/patterns/topic-coherence-analyzer.d.ts +0 -26
  119. package/dist/core/intelligence/patterns/topic-coherence-analyzer.js +0 -300
  120. package/dist/core/intelligence/patterns/user-persona-enricher.d.ts +0 -24
  121. package/dist/core/intelligence/patterns/user-persona-enricher.js +0 -141
  122. package/dist/core/intelligence/patterns/validation-checklist-creator.d.ts +0 -31
  123. package/dist/core/intelligence/patterns/validation-checklist-creator.js +0 -242
  124. package/dist/core/intelligence/quality-assessor.d.ts +0 -71
  125. package/dist/core/intelligence/quality-assessor.js +0 -525
  126. package/dist/core/intelligence/types.d.ts +0 -111
  127. package/dist/core/intelligence/types.js +0 -3
  128. package/dist/core/intelligence/universal-optimizer.d.ts +0 -91
  129. package/dist/core/intelligence/universal-optimizer.js +0 -399
  130. package/dist/core/prd-generator.d.ts +0 -76
  131. package/dist/core/prd-generator.js +0 -173
  132. package/dist/core/prompt-manager.d.ts +0 -110
  133. package/dist/core/prompt-manager.js +0 -274
  134. package/dist/core/prompt-optimizer.d.ts +0 -268
  135. package/dist/core/prompt-optimizer.js +0 -959
  136. package/dist/core/question-engine.d.ts +0 -167
  137. package/dist/core/question-engine.js +0 -356
  138. package/dist/core/session-manager.d.ts +0 -139
  139. package/dist/core/session-manager.js +0 -365
  140. package/dist/core/task-manager.d.ts +0 -211
  141. package/dist/core/task-manager.js +0 -981
  142. package/dist/core/verification-hooks.d.ts +0 -67
  143. package/dist/core/verification-hooks.js +0 -309
  144. package/dist/core/verification-manager.d.ts +0 -107
  145. package/dist/core/verification-manager.js +0 -415
  146. package/dist/index 2.js +0 -13
  147. package/dist/index.d 2.ts +0 -4
  148. package/dist/types/session.d.ts +0 -78
  149. package/dist/types/session.js +0 -8
  150. package/dist/types/verification.d.ts +0 -205
  151. package/dist/types/verification.js +0 -9
@@ -1,217 +0,0 @@
1
- import { Command, Flags } from '@oclif/core';
2
- import chalk from 'chalk';
3
- import fs from 'fs-extra';
4
- import * as path from 'path';
5
- import { SessionManager } from '../../core/session-manager.js';
6
- export default class List extends Command {
7
- static description = 'List sessions and outputs';
8
- static examples = [
9
- '<%= config.bin %> <%= command.id %>',
10
- '<%= config.bin %> <%= command.id %> --sessions',
11
- '<%= config.bin %> <%= command.id %> --outputs',
12
- '<%= config.bin %> <%= command.id %> --project my-feature',
13
- ];
14
- static flags = {
15
- sessions: Flags.boolean({
16
- char: 's',
17
- description: 'List only sessions',
18
- default: false,
19
- }),
20
- outputs: Flags.boolean({
21
- char: 'o',
22
- description: 'List only outputs',
23
- default: false,
24
- }),
25
- archived: Flags.boolean({
26
- char: 'a',
27
- description: 'Include archived projects in outputs',
28
- default: false,
29
- }),
30
- project: Flags.string({
31
- char: 'p',
32
- description: 'Filter by project name',
33
- }),
34
- limit: Flags.integer({
35
- char: 'l',
36
- description: 'Limit number of results',
37
- default: 20,
38
- }),
39
- };
40
- async run() {
41
- const { flags } = await this.parse(List);
42
- const clavixDir = path.join(process.cwd(), '.clavix');
43
- if (!fs.existsSync(clavixDir)) {
44
- this.error(chalk.red('No .clavix directory found.') +
45
- '\n' +
46
- chalk.yellow('Run ') +
47
- chalk.cyan('clavix init') +
48
- chalk.yellow(' to initialize Clavix in this project.'));
49
- }
50
- // If no specific flag is set, show both
51
- const showSessions = flags.sessions || (!flags.outputs && !flags.sessions);
52
- const showOutputs = flags.outputs || (!flags.outputs && !flags.sessions);
53
- if (showSessions) {
54
- await this.listSessions(flags.project, flags.limit);
55
- }
56
- if (showOutputs) {
57
- if (showSessions) {
58
- this.log(''); // Add spacing
59
- }
60
- await this.listOutputs(flags.project, flags.limit, flags.archived);
61
- }
62
- }
63
- async listSessions(projectFilter, limit) {
64
- this.log(chalk.bold.cyan('📋 Sessions\n'));
65
- const sessionManager = new SessionManager();
66
- const sessions = await sessionManager.listSessions();
67
- if (sessions.length === 0) {
68
- this.log(chalk.gray(' No sessions found.'));
69
- this.log(chalk.gray(' Run ') + chalk.cyan('clavix start') + chalk.gray(' to create a new session.'));
70
- return;
71
- }
72
- // Filter by project if specified
73
- let filteredSessions = sessions;
74
- if (projectFilter) {
75
- filteredSessions = sessions.filter(s => s.projectName?.toLowerCase().includes(projectFilter.toLowerCase()));
76
- }
77
- // Sort by updated date (most recent first)
78
- filteredSessions.sort((a, b) => new Date(b.updated).getTime() - new Date(a.updated).getTime());
79
- // Apply limit
80
- if (limit) {
81
- filteredSessions = filteredSessions.slice(0, limit);
82
- }
83
- if (filteredSessions.length === 0) {
84
- this.log(chalk.gray(` No sessions found matching "${projectFilter}".`));
85
- return;
86
- }
87
- // Display sessions in a table-like format
88
- filteredSessions.forEach((session, index) => {
89
- const isActive = session.status === 'active';
90
- const statusIcon = isActive ? '🟢' : '⚪';
91
- const projectName = session.projectName || 'untitled';
92
- const created = new Date(session.created).toLocaleDateString();
93
- const updated = new Date(session.updated).toLocaleString();
94
- const messageCount = session.messageCount || 0;
95
- this.log(` ${statusIcon} ${chalk.bold(projectName)} ${chalk.gray(`(${session.id})`)}` +
96
- `\n ${chalk.gray('Created:')} ${created} ${chalk.gray('│')} ` +
97
- `${chalk.gray('Updated:')} ${updated}` +
98
- `\n ${chalk.gray('Messages:')} ${messageCount} ${chalk.gray('│')} ` +
99
- `${chalk.gray('Status:')} ${isActive ? chalk.green('active') : chalk.gray('completed')}` +
100
- (index < filteredSessions.length - 1 ? '\n' : ''));
101
- });
102
- this.log('');
103
- this.log(chalk.gray(` Showing ${filteredSessions.length} of ${sessions.length} sessions`));
104
- if (sessions.length > filteredSessions.length && !limit) {
105
- this.log(chalk.gray(` Use ${chalk.cyan('--limit N')} to show more results`));
106
- }
107
- }
108
- async listOutputs(projectFilter, limit, includeArchived = false) {
109
- this.log(chalk.bold.cyan('📁 Outputs\n'));
110
- const outputsDir = path.join(process.cwd(), '.clavix', 'outputs');
111
- if (!fs.existsSync(outputsDir)) {
112
- this.log(chalk.gray(' No outputs found.'));
113
- this.log(chalk.gray(' Run ') + chalk.cyan('clavix prd') + chalk.gray(' or ') + chalk.cyan('clavix summarize') + chalk.gray(' to generate outputs.'));
114
- return;
115
- }
116
- const projectDirs = fs.readdirSync(outputsDir).filter(name => {
117
- const fullPath = path.join(outputsDir, name);
118
- // Skip archive directory in main listing
119
- if (name === 'archive' && !includeArchived) {
120
- return false;
121
- }
122
- return fs.statSync(fullPath).isDirectory();
123
- });
124
- if (projectDirs.length === 0) {
125
- this.log(chalk.gray(' No outputs found.'));
126
- return;
127
- }
128
- // Filter by project if specified
129
- let filteredDirs = projectDirs;
130
- if (projectFilter) {
131
- filteredDirs = projectDirs.filter(dir => dir.toLowerCase().includes(projectFilter.toLowerCase()));
132
- }
133
- // Sort by modification time (most recent first)
134
- filteredDirs.sort((a, b) => {
135
- const aPath = path.join(outputsDir, a);
136
- const bPath = path.join(outputsDir, b);
137
- return fs.statSync(bPath).mtime.getTime() - fs.statSync(aPath).mtime.getTime();
138
- });
139
- // Apply limit
140
- if (limit) {
141
- filteredDirs = filteredDirs.slice(0, limit);
142
- }
143
- if (filteredDirs.length === 0) {
144
- this.log(chalk.gray(` No outputs found matching "${projectFilter}".`));
145
- return;
146
- }
147
- // Display outputs
148
- filteredDirs.forEach((projectDir, index) => {
149
- const projectPath = path.join(outputsDir, projectDir);
150
- const files = fs.readdirSync(projectPath).filter(f => f.endsWith('.md'));
151
- const modified = fs.statSync(projectPath).mtime.toLocaleDateString();
152
- this.log(` 📄 ${chalk.bold(projectDir)}` +
153
- `\n ${chalk.gray('Path:')} ${chalk.dim(path.relative(process.cwd(), projectPath))}` +
154
- `\n ${chalk.gray('Files:')} ${files.join(', ')}` +
155
- `\n ${chalk.gray('Modified:')} ${modified}` +
156
- (index < filteredDirs.length - 1 ? '\n' : ''));
157
- });
158
- this.log('');
159
- this.log(chalk.gray(` Showing ${filteredDirs.length} of ${projectDirs.length} output directories`));
160
- if (projectDirs.length > filteredDirs.length && !limit) {
161
- this.log(chalk.gray(` Use ${chalk.cyan('--limit N')} to show more results`));
162
- }
163
- // Show archived projects if flag is set
164
- if (includeArchived) {
165
- await this.listArchivedOutputs(projectFilter, limit);
166
- }
167
- }
168
- async listArchivedOutputs(projectFilter, limit) {
169
- const archiveDir = path.join(process.cwd(), '.clavix', 'outputs', 'archive');
170
- if (!fs.existsSync(archiveDir)) {
171
- return; // No archived projects
172
- }
173
- const archivedDirs = fs.readdirSync(archiveDir).filter(name => {
174
- const fullPath = path.join(archiveDir, name);
175
- return fs.statSync(fullPath).isDirectory();
176
- });
177
- if (archivedDirs.length === 0) {
178
- return; // No archived projects
179
- }
180
- // Filter by project if specified
181
- let filteredDirs = archivedDirs;
182
- if (projectFilter) {
183
- filteredDirs = archivedDirs.filter(dir => dir.toLowerCase().includes(projectFilter.toLowerCase()));
184
- }
185
- // Sort by modification time (most recent first)
186
- filteredDirs.sort((a, b) => {
187
- const aPath = path.join(archiveDir, a);
188
- const bPath = path.join(archiveDir, b);
189
- return fs.statSync(bPath).mtime.getTime() - fs.statSync(aPath).mtime.getTime();
190
- });
191
- // Apply limit
192
- if (limit) {
193
- filteredDirs = filteredDirs.slice(0, limit);
194
- }
195
- if (filteredDirs.length === 0) {
196
- return; // No matching archived projects
197
- }
198
- // Display archived section header
199
- this.log('');
200
- this.log(chalk.bold.cyan('📦 Archived Outputs\n'));
201
- // Display archived outputs
202
- filteredDirs.forEach((projectDir, index) => {
203
- const projectPath = path.join(archiveDir, projectDir);
204
- const files = fs.readdirSync(projectPath).filter(f => f.endsWith('.md'));
205
- const modified = fs.statSync(projectPath).mtime.toLocaleDateString();
206
- this.log(` 📦 ${chalk.bold(projectDir)} ${chalk.gray('(archived)')}` +
207
- `\n ${chalk.gray('Path:')} ${chalk.dim(path.relative(process.cwd(), projectPath))}` +
208
- `\n ${chalk.gray('Files:')} ${files.join(', ')}` +
209
- `\n ${chalk.gray('Modified:')} ${modified}` +
210
- (index < filteredDirs.length - 1 ? '\n' : ''));
211
- });
212
- this.log('');
213
- this.log(chalk.gray(` Showing ${filteredDirs.length} of ${archivedDirs.length} archived directories`));
214
- this.log(chalk.gray(` Use ${chalk.cyan('clavix archive --restore <project>')} to restore a project`));
215
- }
216
- }
217
- //# sourceMappingURL=list.js.map
@@ -1,21 +0,0 @@
1
- import { Command } from '@oclif/core';
2
- export default class Plan extends Command {
3
- static description: string;
4
- static examples: string[];
5
- static flags: {
6
- project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
- 'prd-path': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
- session: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
- 'active-session': import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
- source: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
- 'max-tasks': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
12
- overwrite: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
- };
14
- run(): Promise<void>;
15
- private validateSessionFlags;
16
- private prepareArtifactsFromSession;
17
- private resolveProjectDirectory;
18
- private sanitizeProjectName;
19
- private isInteractive;
20
- }
21
- //# sourceMappingURL=plan.d.ts.map
@@ -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