clavix 4.11.2 → 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 (162) hide show
  1. package/README.md +72 -60
  2. package/dist/cli/commands/update.js +9 -10
  3. package/dist/templates/agents/agents.md +14 -8
  4. package/dist/templates/agents/copilot-instructions.md +1 -1
  5. package/dist/templates/instructions/core/verification.md +2 -2
  6. package/dist/templates/slash-commands/_canonical/archive.md +83 -121
  7. package/dist/templates/slash-commands/_canonical/execute.md +32 -42
  8. package/dist/templates/slash-commands/_canonical/implement.md +32 -44
  9. package/dist/templates/slash-commands/_canonical/improve.md +14 -53
  10. package/dist/templates/slash-commands/_canonical/start.md +1 -1
  11. package/dist/templates/slash-commands/_canonical/summarize.md +8 -8
  12. package/dist/templates/slash-commands/_components/agent-protocols/cli-reference.md +84 -180
  13. package/dist/templates/slash-commands/_components/agent-protocols/error-handling.md +2 -2
  14. package/dist/templates/slash-commands/_components/agent-protocols/file-formats.md +41 -59
  15. package/dist/templates/slash-commands/_components/agent-protocols/state-assertion.md +1 -1
  16. package/dist/templates/slash-commands/_components/references/intent-types.md +1 -1
  17. package/dist/templates/slash-commands/_components/sections/file-saving-protocol.md +20 -27
  18. package/dist/templates/slash-commands/_components/sections/pattern-visibility.md +29 -46
  19. package/dist/templates/slash-commands/_components/troubleshooting/file-not-saved.md +4 -5
  20. package/dist/types/config.d.ts +57 -0
  21. package/dist/utils/legacy-command-cleanup.js +31 -4
  22. package/package.json +5 -4
  23. package/dist/cli/commands/analyze.d.ts +0 -17
  24. package/dist/cli/commands/analyze.js +0 -133
  25. package/dist/cli/commands/archive.d.ts +0 -36
  26. package/dist/cli/commands/archive.js +0 -266
  27. package/dist/cli/commands/deep.d.ts +0 -17
  28. package/dist/cli/commands/deep.js +0 -170
  29. package/dist/cli/commands/execute.d.ts +0 -15
  30. package/dist/cli/commands/execute.js +0 -168
  31. package/dist/cli/commands/fast.d.ts +0 -18
  32. package/dist/cli/commands/fast.js +0 -219
  33. package/dist/cli/commands/implement.d.ts +0 -24
  34. package/dist/cli/commands/implement.js +0 -289
  35. package/dist/cli/commands/improve.d.ts +0 -32
  36. package/dist/cli/commands/improve.js +0 -250
  37. package/dist/cli/commands/list.d.ts +0 -17
  38. package/dist/cli/commands/list.js +0 -217
  39. package/dist/cli/commands/plan.d.ts +0 -21
  40. package/dist/cli/commands/plan.js +0 -297
  41. package/dist/cli/commands/prd.d.ts +0 -24
  42. package/dist/cli/commands/prd.js +0 -321
  43. package/dist/cli/commands/prompts/clear.d.ts +0 -16
  44. package/dist/cli/commands/prompts/clear.js +0 -222
  45. package/dist/cli/commands/prompts/list.d.ts +0 -8
  46. package/dist/cli/commands/prompts/list.js +0 -88
  47. package/dist/cli/commands/show.d.ts +0 -21
  48. package/dist/cli/commands/show.js +0 -191
  49. package/dist/cli/commands/start.d.ts +0 -40
  50. package/dist/cli/commands/start.js +0 -210
  51. package/dist/cli/commands/summarize.d.ts +0 -17
  52. package/dist/cli/commands/summarize.js +0 -196
  53. package/dist/cli/commands/task-complete.d.ts +0 -27
  54. package/dist/cli/commands/task-complete.js +0 -269
  55. package/dist/cli/commands/verify.d.ts +0 -28
  56. package/dist/cli/commands/verify.js +0 -349
  57. package/dist/core/archive-manager.d.ts +0 -100
  58. package/dist/core/archive-manager.js +0 -302
  59. package/dist/core/basic-checklist-generator.d.ts +0 -35
  60. package/dist/core/basic-checklist-generator.js +0 -344
  61. package/dist/core/checklist-parser.d.ts +0 -48
  62. package/dist/core/checklist-parser.js +0 -238
  63. package/dist/core/config-manager.d.ts +0 -149
  64. package/dist/core/config-manager.js +0 -230
  65. package/dist/core/conversation-analyzer.d.ts +0 -86
  66. package/dist/core/conversation-analyzer.js +0 -387
  67. package/dist/core/conversation-quality-tracker.d.ts +0 -81
  68. package/dist/core/conversation-quality-tracker.js +0 -195
  69. package/dist/core/git-manager.d.ts +0 -126
  70. package/dist/core/git-manager.js +0 -282
  71. package/dist/core/intelligence/confidence-calculator.d.ts +0 -93
  72. package/dist/core/intelligence/confidence-calculator.js +0 -124
  73. package/dist/core/intelligence/index.d.ts +0 -11
  74. package/dist/core/intelligence/index.js +0 -15
  75. package/dist/core/intelligence/intent-detector.d.ts +0 -54
  76. package/dist/core/intelligence/intent-detector.js +0 -723
  77. package/dist/core/intelligence/pattern-library.d.ts +0 -104
  78. package/dist/core/intelligence/pattern-library.js +0 -339
  79. package/dist/core/intelligence/patterns/actionability-enhancer.d.ts +0 -27
  80. package/dist/core/intelligence/patterns/actionability-enhancer.js +0 -192
  81. package/dist/core/intelligence/patterns/alternative-phrasing-generator.d.ts +0 -29
  82. package/dist/core/intelligence/patterns/alternative-phrasing-generator.js +0 -239
  83. package/dist/core/intelligence/patterns/ambiguity-detector.d.ts +0 -22
  84. package/dist/core/intelligence/patterns/ambiguity-detector.js +0 -196
  85. package/dist/core/intelligence/patterns/assumption-explicitizer.d.ts +0 -30
  86. package/dist/core/intelligence/patterns/assumption-explicitizer.js +0 -296
  87. package/dist/core/intelligence/patterns/base-pattern.d.ts +0 -192
  88. package/dist/core/intelligence/patterns/base-pattern.js +0 -103
  89. package/dist/core/intelligence/patterns/completeness-validator.d.ts +0 -27
  90. package/dist/core/intelligence/patterns/completeness-validator.js +0 -221
  91. package/dist/core/intelligence/patterns/conciseness-filter.d.ts +0 -20
  92. package/dist/core/intelligence/patterns/conciseness-filter.js +0 -92
  93. package/dist/core/intelligence/patterns/context-precision.d.ts +0 -32
  94. package/dist/core/intelligence/patterns/context-precision.js +0 -389
  95. package/dist/core/intelligence/patterns/conversation-summarizer.d.ts +0 -30
  96. package/dist/core/intelligence/patterns/conversation-summarizer.js +0 -277
  97. package/dist/core/intelligence/patterns/dependency-identifier.d.ts +0 -23
  98. package/dist/core/intelligence/patterns/dependency-identifier.js +0 -166
  99. package/dist/core/intelligence/patterns/domain-context-enricher.d.ts +0 -21
  100. package/dist/core/intelligence/patterns/domain-context-enricher.js +0 -198
  101. package/dist/core/intelligence/patterns/edge-case-identifier.d.ts +0 -30
  102. package/dist/core/intelligence/patterns/edge-case-identifier.js +0 -269
  103. package/dist/core/intelligence/patterns/error-tolerance-enhancer.d.ts +0 -22
  104. package/dist/core/intelligence/patterns/error-tolerance-enhancer.js +0 -179
  105. package/dist/core/intelligence/patterns/implicit-requirement-extractor.d.ts +0 -24
  106. package/dist/core/intelligence/patterns/implicit-requirement-extractor.js +0 -259
  107. package/dist/core/intelligence/patterns/objective-clarifier.d.ts +0 -22
  108. package/dist/core/intelligence/patterns/objective-clarifier.js +0 -126
  109. package/dist/core/intelligence/patterns/output-format-enforcer.d.ts +0 -22
  110. package/dist/core/intelligence/patterns/output-format-enforcer.js +0 -151
  111. package/dist/core/intelligence/patterns/prd-structure-enforcer.d.ts +0 -23
  112. package/dist/core/intelligence/patterns/prd-structure-enforcer.js +0 -183
  113. package/dist/core/intelligence/patterns/prerequisite-identifier.d.ts +0 -23
  114. package/dist/core/intelligence/patterns/prerequisite-identifier.js +0 -221
  115. package/dist/core/intelligence/patterns/requirement-prioritizer.d.ts +0 -24
  116. package/dist/core/intelligence/patterns/requirement-prioritizer.js +0 -134
  117. package/dist/core/intelligence/patterns/scope-definer.d.ts +0 -26
  118. package/dist/core/intelligence/patterns/scope-definer.js +0 -236
  119. package/dist/core/intelligence/patterns/step-decomposer.d.ts +0 -31
  120. package/dist/core/intelligence/patterns/step-decomposer.js +0 -242
  121. package/dist/core/intelligence/patterns/structure-organizer.d.ts +0 -31
  122. package/dist/core/intelligence/patterns/structure-organizer.js +0 -218
  123. package/dist/core/intelligence/patterns/success-criteria-enforcer.d.ts +0 -22
  124. package/dist/core/intelligence/patterns/success-criteria-enforcer.js +0 -165
  125. package/dist/core/intelligence/patterns/success-metrics-enforcer.d.ts +0 -24
  126. package/dist/core/intelligence/patterns/success-metrics-enforcer.js +0 -165
  127. package/dist/core/intelligence/patterns/technical-context-enricher.d.ts +0 -25
  128. package/dist/core/intelligence/patterns/technical-context-enricher.js +0 -165
  129. package/dist/core/intelligence/patterns/topic-coherence-analyzer.d.ts +0 -26
  130. package/dist/core/intelligence/patterns/topic-coherence-analyzer.js +0 -300
  131. package/dist/core/intelligence/patterns/user-persona-enricher.d.ts +0 -24
  132. package/dist/core/intelligence/patterns/user-persona-enricher.js +0 -141
  133. package/dist/core/intelligence/patterns/validation-checklist-creator.d.ts +0 -31
  134. package/dist/core/intelligence/patterns/validation-checklist-creator.js +0 -242
  135. package/dist/core/intelligence/quality-assessor.d.ts +0 -51
  136. package/dist/core/intelligence/quality-assessor.js +0 -505
  137. package/dist/core/intelligence/types.d.ts +0 -111
  138. package/dist/core/intelligence/types.js +0 -3
  139. package/dist/core/intelligence/universal-optimizer.d.ts +0 -84
  140. package/dist/core/intelligence/universal-optimizer.js +0 -371
  141. package/dist/core/prd-generator.d.ts +0 -76
  142. package/dist/core/prd-generator.js +0 -173
  143. package/dist/core/prompt-manager.d.ts +0 -110
  144. package/dist/core/prompt-manager.js +0 -274
  145. package/dist/core/prompt-optimizer.d.ts +0 -268
  146. package/dist/core/prompt-optimizer.js +0 -959
  147. package/dist/core/question-engine.d.ts +0 -167
  148. package/dist/core/question-engine.js +0 -356
  149. package/dist/core/session-manager.d.ts +0 -139
  150. package/dist/core/session-manager.js +0 -365
  151. package/dist/core/task-manager.d.ts +0 -211
  152. package/dist/core/task-manager.js +0 -981
  153. package/dist/core/verification-hooks.d.ts +0 -67
  154. package/dist/core/verification-hooks.js +0 -309
  155. package/dist/core/verification-manager.d.ts +0 -107
  156. package/dist/core/verification-manager.js +0 -415
  157. package/dist/index 2.js +0 -13
  158. package/dist/index.d 2.ts +0 -4
  159. package/dist/types/session.d.ts +0 -78
  160. package/dist/types/session.js +0 -8
  161. package/dist/types/verification.d.ts +0 -205
  162. package/dist/types/verification.js +0 -9
@@ -1,173 +0,0 @@
1
- /**
2
- * PrdGenerator - Generates Product Requirements Documents from collected answers
3
- *
4
- * This class handles:
5
- * - Template loading and rendering with Handlebars
6
- * - Project name extraction
7
- * - File generation (full PRD and quick PRD)
8
- * - Output organization and timestamps
9
- */
10
- import fs from 'fs-extra';
11
- import * as path from 'path';
12
- import { fileURLToPath } from 'url';
13
- import { dirname } from 'path';
14
- import Handlebars from 'handlebars';
15
- import { FileSystem } from '../utils/file-system.js';
16
- const __filename = fileURLToPath(import.meta.url);
17
- const __dirname = dirname(__filename);
18
- /**
19
- * PrdGenerator class
20
- *
21
- * Generates comprehensive and quick-reference PRD documents
22
- * from collected question answers
23
- */
24
- export class PrdGenerator {
25
- templatesDir;
26
- defaultOutputDir = '.clavix/outputs';
27
- constructor() {
28
- // Templates are in src/templates (or dist/templates when built)
29
- this.templatesDir = path.join(__dirname, '../templates');
30
- }
31
- /**
32
- * Generate PRD documents from answers
33
- *
34
- * @param answers - Collected answers from QuestionEngine
35
- * @param options - Generation options
36
- * @returns Path to the output directory
37
- */
38
- async generate(answers, options = {}) {
39
- const projectName = options.projectName || this.extractProjectName(answers);
40
- const outputDir = options.outputDir || this.defaultOutputDir;
41
- const timestamp = options.timestamp || new Date();
42
- // Create output directory
43
- const projectDir = path.join(outputDir, this.sanitizeProjectName(projectName));
44
- await FileSystem.ensureDir(projectDir);
45
- // Prepare template data
46
- const metadata = {
47
- generatedAt: timestamp.toISOString(),
48
- generatedBy: 'Clavix PRD Generator',
49
- projectName,
50
- version: '1.0.0',
51
- };
52
- const templateData = {
53
- ...this.prepareAnswersForTemplate(answers),
54
- metadata,
55
- timestamp: this.formatTimestamp(timestamp),
56
- };
57
- // Generate full PRD
58
- const fullPrdPath = path.join(projectDir, 'full-prd.md');
59
- await this.generateFullPrd(templateData, fullPrdPath);
60
- // Generate quick PRD
61
- const quickPrdPath = path.join(projectDir, 'quick-prd.md');
62
- await this.generateQuickPrd(templateData, quickPrdPath);
63
- return projectDir;
64
- }
65
- /**
66
- * Extract project name from answers
67
- *
68
- * Tries to infer a project name from the problem statement or user responses
69
- */
70
- extractProjectName(answers) {
71
- // Try to find a project name in the answers
72
- // Look in common question answers like "problem", "name", "title"
73
- const possibleNameFields = ['projectName', 'name', 'title', 'q1', 'problem'];
74
- for (const field of possibleNameFields) {
75
- if (answers[field] && typeof answers[field] === 'string') {
76
- const extracted = this.extractNameFromText(answers[field]);
77
- if (extracted) {
78
- return extracted;
79
- }
80
- }
81
- }
82
- // Default to timestamp-based name
83
- return `project-${Date.now()}`;
84
- }
85
- /**
86
- * Extract a concise name from text (e.g., from problem statement)
87
- */
88
- extractNameFromText(text) {
89
- // Take first few words, clean up, and create a name
90
- const words = text
91
- .split(/\s+/)
92
- .slice(0, 4)
93
- .map((w) => w.toLowerCase())
94
- .filter((w) => w.length > 2);
95
- if (words.length === 0) {
96
- return null;
97
- }
98
- return words.join('-').replace(/[^a-z0-9-]/g, '');
99
- }
100
- /**
101
- * Sanitize project name for use as directory name
102
- */
103
- sanitizeProjectName(name) {
104
- return name
105
- .toLowerCase()
106
- .replace(/[^a-z0-9-]/g, '-')
107
- .replace(/-+/g, '-')
108
- .replace(/^-|-$/g, '')
109
- .substring(0, 50);
110
- }
111
- /**
112
- * Prepare answers for template rendering
113
- */
114
- prepareAnswersForTemplate(answers) {
115
- const prepared = {};
116
- // Map question IDs to friendly names (updated for CLEAR-optimized 5-question flow)
117
- const questionMap = {
118
- q1: 'problem', // What are we building and why?
119
- q2: 'features', // Core features
120
- q3: 'technical', // Tech stack (optional, smart-detected)
121
- q4: 'outOfScope', // Out of scope
122
- q5: 'additional', // Additional context (optional)
123
- };
124
- for (const [questionId, value] of Object.entries(answers)) {
125
- const friendlyName = questionMap[questionId] || questionId;
126
- prepared[friendlyName] = value;
127
- }
128
- return prepared;
129
- }
130
- /**
131
- * Generate full PRD document
132
- */
133
- async generateFullPrd(data, outputPath) {
134
- const templatePath = path.join(this.templatesDir, 'full-prd-template.hbs');
135
- // Check if custom template exists
136
- const customTemplatePath = '.clavix/templates/full-prd-template.hbs';
137
- const templateToUse = await fs.pathExists(customTemplatePath)
138
- ? customTemplatePath
139
- : templatePath;
140
- const template = await fs.readFile(templateToUse, 'utf-8');
141
- const compiled = Handlebars.compile(template);
142
- const rendered = compiled(data);
143
- await FileSystem.writeFileAtomic(outputPath, rendered);
144
- }
145
- /**
146
- * Generate quick PRD document
147
- */
148
- async generateQuickPrd(data, outputPath) {
149
- const templatePath = path.join(this.templatesDir, 'quick-prd-template.hbs');
150
- // Check if custom template exists
151
- const customTemplatePath = '.clavix/templates/quick-prd-template.hbs';
152
- const templateToUse = await fs.pathExists(customTemplatePath)
153
- ? customTemplatePath
154
- : templatePath;
155
- const template = await fs.readFile(templateToUse, 'utf-8');
156
- const compiled = Handlebars.compile(template);
157
- const rendered = compiled(data);
158
- await FileSystem.writeFileAtomic(outputPath, rendered);
159
- }
160
- /**
161
- * Format timestamp for display
162
- */
163
- formatTimestamp(date) {
164
- return date.toLocaleString('en-US', {
165
- year: 'numeric',
166
- month: 'long',
167
- day: 'numeric',
168
- hour: '2-digit',
169
- minute: '2-digit',
170
- });
171
- }
172
- }
173
- //# sourceMappingURL=prd-generator.js.map
@@ -1,110 +0,0 @@
1
- import { DepthLevel } from './intelligence/types.js';
2
- /**
3
- * v4.11: Unified prompt metadata
4
- * Replaces separate fast/deep storage with single directory and depthUsed field
5
- */
6
- export interface PromptMetadata {
7
- id: string;
8
- filename: string;
9
- depthUsed: DepthLevel;
10
- timestamp: string;
11
- createdAt: Date;
12
- path: string;
13
- originalPrompt: string;
14
- executed: boolean;
15
- executedAt: string | null;
16
- ageInDays?: number;
17
- linkedProject?: string;
18
- verificationRequired: boolean;
19
- verified: boolean;
20
- verifiedAt: string | null;
21
- }
22
- export interface PromptsIndex {
23
- version: string;
24
- prompts: PromptMetadata[];
25
- }
26
- export interface PromptData {
27
- metadata: PromptMetadata;
28
- content: string;
29
- }
30
- export interface PromptFilters {
31
- depthUsed?: DepthLevel;
32
- executed?: boolean;
33
- stale?: boolean;
34
- old?: boolean;
35
- }
36
- export interface StorageStats {
37
- totalPrompts: number;
38
- standardPrompts: number;
39
- comprehensivePrompts: number;
40
- executedPrompts: number;
41
- pendingPrompts: number;
42
- stalePrompts: number;
43
- oldPrompts: number;
44
- oldestPromptAge: number;
45
- }
46
- export declare class PromptManager {
47
- private readonly promptsDir;
48
- constructor(baseDir?: string);
49
- /**
50
- * v4.11: Get unified index file path
51
- */
52
- private getIndexPath;
53
- /**
54
- * v4.11: Ensure prompts directory exists (single directory)
55
- */
56
- ensurePromptsDir(): Promise<void>;
57
- /**
58
- * v4.11: Generate unique prompt ID with depth and timestamp
59
- */
60
- generatePromptId(depthLevel: DepthLevel, _originalPrompt: string): string;
61
- /**
62
- * v4.11: Save optimized prompt to file system
63
- */
64
- savePrompt(content: string, depthUsed: DepthLevel, originalPrompt: string, linkedProject?: string): Promise<PromptMetadata>;
65
- /**
66
- * v4.11: Load prompt by ID
67
- */
68
- loadPrompt(id: string): Promise<PromptData | null>;
69
- /**
70
- * v4.11: List prompts with optional filtering
71
- */
72
- listPrompts(filters?: PromptFilters): Promise<PromptMetadata[]>;
73
- /**
74
- * v4.11: Mark prompt as executed
75
- */
76
- markExecuted(id: string): Promise<void>;
77
- /**
78
- * v4.11: Mark prompt as verified (v4.8)
79
- */
80
- markVerified(id: string): Promise<void>;
81
- /**
82
- * v4.11: Delete prompts by filter
83
- */
84
- deletePrompts(filters: PromptFilters): Promise<number>;
85
- /**
86
- * Get age of prompt in days
87
- */
88
- getPromptAge(prompt: PromptMetadata): number;
89
- /**
90
- * Get stale prompts (>30 days old)
91
- */
92
- getStalePrompts(_daysOld?: number): Promise<PromptMetadata[]>;
93
- /**
94
- * v4.11: Get storage statistics
95
- */
96
- getStorageStats(): Promise<StorageStats>;
97
- /**
98
- * v4.11: Load unified index from file
99
- */
100
- private loadIndex;
101
- /**
102
- * v4.11: Save unified index to file
103
- */
104
- private saveIndex;
105
- /**
106
- * v4.11: Add prompt to unified index
107
- */
108
- private addToIndex;
109
- }
110
- //# sourceMappingURL=prompt-manager.d.ts.map
@@ -1,274 +0,0 @@
1
- import fs from 'fs-extra';
2
- import * as path from 'path';
3
- import { v4 as uuidv4 } from 'uuid';
4
- export class PromptManager {
5
- promptsDir;
6
- constructor(baseDir) {
7
- // v4.11: Single prompts directory (no fast/deep subdirs)
8
- if (baseDir) {
9
- this.promptsDir = baseDir.endsWith('prompts') ? baseDir : path.join(baseDir, 'prompts');
10
- }
11
- else {
12
- this.promptsDir = path.join(process.cwd(), '.clavix', 'outputs', 'prompts');
13
- }
14
- }
15
- /**
16
- * v4.11: Get unified index file path
17
- */
18
- getIndexPath() {
19
- return path.join(this.promptsDir, '.index.json');
20
- }
21
- /**
22
- * v4.11: Ensure prompts directory exists (single directory)
23
- */
24
- async ensurePromptsDir() {
25
- await fs.ensureDir(this.promptsDir);
26
- }
27
- /**
28
- * v4.11: Generate unique prompt ID with depth and timestamp
29
- */
30
- generatePromptId(depthLevel, _originalPrompt) {
31
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T');
32
- const date = timestamp[0].replace(/-/g, '');
33
- const time = timestamp[1].split('-').slice(0, 3).join('');
34
- // Use UUID for uniqueness (mockable for tests - first 13 chars for readability)
35
- const hash = uuidv4().substring(0, 13);
36
- // v4.11: Use depth level abbreviation in ID
37
- const depthAbbrev = depthLevel === 'comprehensive' ? 'comp' : 'std';
38
- return `${depthAbbrev}-${date}-${time}-${hash}`;
39
- }
40
- /**
41
- * v4.11: Save optimized prompt to file system
42
- */
43
- async savePrompt(content, depthUsed, originalPrompt, linkedProject) {
44
- await this.ensurePromptsDir();
45
- const id = this.generatePromptId(depthUsed, originalPrompt);
46
- const filename = `${id}.md`;
47
- // v4.11: Single directory, no subdirs
48
- const filePath = path.join(this.promptsDir, filename);
49
- const now = new Date();
50
- const metadata = {
51
- id,
52
- filename,
53
- depthUsed, // v4.11: Replaces 'source'
54
- timestamp: now.toISOString(),
55
- createdAt: now,
56
- path: filePath,
57
- originalPrompt,
58
- executed: false,
59
- executedAt: null,
60
- linkedProject,
61
- // Verification tracking (v4.8)
62
- verificationRequired: true,
63
- verified: false,
64
- verifiedAt: null,
65
- };
66
- // Create file with frontmatter
67
- const frontmatter = [
68
- '---',
69
- `id: ${id}`,
70
- `depthUsed: ${depthUsed}`,
71
- `timestamp: ${metadata.timestamp}`,
72
- `executed: ${metadata.executed}`,
73
- `originalPrompt: ${originalPrompt}`,
74
- linkedProject ? `linkedProject: ${linkedProject}` : '',
75
- `verificationRequired: ${metadata.verificationRequired}`,
76
- `verified: ${metadata.verified}`,
77
- '---',
78
- '',
79
- ]
80
- .filter(Boolean)
81
- .join('\n');
82
- const fileContent = frontmatter + content;
83
- await fs.writeFile(filePath, fileContent, 'utf-8');
84
- // Update index
85
- await this.addToIndex(metadata);
86
- return metadata;
87
- }
88
- /**
89
- * v4.11: Load prompt by ID
90
- */
91
- async loadPrompt(id) {
92
- const index = await this.loadIndex();
93
- const metadata = index.prompts.find((p) => p.id === id);
94
- if (!metadata) {
95
- return null;
96
- }
97
- // v4.11: Single directory - no subdirs
98
- const filePath = path.join(this.promptsDir, metadata.filename);
99
- if (!(await fs.pathExists(filePath))) {
100
- return null;
101
- }
102
- const content = await fs.readFile(filePath, 'utf-8');
103
- // Strip frontmatter for clean content
104
- const contentWithoutFrontmatter = content.replace(/^---\n[\s\S]*?\n---\n*/, '');
105
- return {
106
- metadata,
107
- content: contentWithoutFrontmatter,
108
- };
109
- }
110
- /**
111
- * v4.11: List prompts with optional filtering
112
- */
113
- async listPrompts(filters) {
114
- const index = await this.loadIndex();
115
- let prompts = index.prompts;
116
- // Apply filters
117
- if (filters) {
118
- // v4.11: Filter by depth level
119
- if (filters.depthUsed) {
120
- prompts = prompts.filter((p) => p.depthUsed === filters.depthUsed);
121
- }
122
- if (filters.executed !== undefined) {
123
- prompts = prompts.filter((p) => p.executed === filters.executed);
124
- }
125
- if (filters.stale) {
126
- prompts = prompts.filter((p) => this.getPromptAge(p) > 30);
127
- }
128
- if (filters.old) {
129
- prompts = prompts.filter((p) => this.getPromptAge(p) > 7);
130
- }
131
- }
132
- // Add age calculation
133
- prompts = prompts.map((p) => ({
134
- ...p,
135
- createdAt: new Date(p.timestamp),
136
- ageInDays: this.getPromptAge(p),
137
- }));
138
- // Sort by timestamp (newest first)
139
- prompts.sort((a, b) => {
140
- return new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();
141
- });
142
- return prompts;
143
- }
144
- /**
145
- * v4.11: Mark prompt as executed
146
- */
147
- async markExecuted(id) {
148
- const index = await this.loadIndex();
149
- const indexPrompt = index.prompts.find((p) => p.id === id);
150
- if (!indexPrompt) {
151
- throw new Error(`Prompt not found: ${id}`);
152
- }
153
- indexPrompt.executed = true;
154
- indexPrompt.executedAt = new Date().toISOString();
155
- await this.saveIndex(index);
156
- }
157
- /**
158
- * v4.11: Mark prompt as verified (v4.8)
159
- */
160
- async markVerified(id) {
161
- const index = await this.loadIndex();
162
- const indexPrompt = index.prompts.find((p) => p.id === id);
163
- if (!indexPrompt) {
164
- throw new Error(`Prompt not found: ${id}`);
165
- }
166
- indexPrompt.verified = true;
167
- indexPrompt.verifiedAt = new Date().toISOString();
168
- await this.saveIndex(index);
169
- }
170
- /**
171
- * v4.11: Delete prompts by filter
172
- */
173
- async deletePrompts(filters) {
174
- const toDelete = await this.listPrompts(filters);
175
- let deleteCount = 0;
176
- const deletedIds = new Set();
177
- for (const prompt of toDelete) {
178
- // v4.11: Single directory - no subdirs
179
- const filePath = path.join(this.promptsDir, prompt.filename);
180
- if (await fs.pathExists(filePath)) {
181
- await fs.remove(filePath);
182
- deleteCount++;
183
- deletedIds.add(prompt.id);
184
- }
185
- }
186
- // Update unified index
187
- if (deletedIds.size > 0) {
188
- const index = await this.loadIndex();
189
- index.prompts = index.prompts.filter((p) => !deletedIds.has(p.id));
190
- await this.saveIndex(index);
191
- }
192
- return deleteCount;
193
- }
194
- /**
195
- * Get age of prompt in days
196
- */
197
- getPromptAge(prompt) {
198
- const created = new Date(prompt.timestamp);
199
- const now = new Date();
200
- const diffMs = now.getTime() - created.getTime();
201
- return Math.floor(diffMs / (1000 * 60 * 60 * 24));
202
- }
203
- /**
204
- * Get stale prompts (>30 days old)
205
- */
206
- async getStalePrompts(_daysOld = 30) {
207
- return this.listPrompts({ stale: true });
208
- }
209
- /**
210
- * v4.11: Get storage statistics
211
- */
212
- async getStorageStats() {
213
- const allPrompts = await this.listPrompts();
214
- const stats = {
215
- totalPrompts: allPrompts.length,
216
- standardPrompts: allPrompts.filter((p) => p.depthUsed === 'standard').length,
217
- comprehensivePrompts: allPrompts.filter((p) => p.depthUsed === 'comprehensive').length,
218
- executedPrompts: allPrompts.filter((p) => p.executed).length,
219
- pendingPrompts: allPrompts.filter((p) => !p.executed).length,
220
- stalePrompts: allPrompts.filter((p) => (p.ageInDays || 0) > 30).length,
221
- oldPrompts: allPrompts.filter((p) => (p.ageInDays || 0) > 7).length,
222
- oldestPromptAge: allPrompts.length > 0 ? Math.max(...allPrompts.map((p) => p.ageInDays || 0)) : 0,
223
- };
224
- return stats;
225
- }
226
- /**
227
- * v4.11: Load unified index from file
228
- */
229
- async loadIndex() {
230
- const indexPath = this.getIndexPath();
231
- if (!(await fs.pathExists(indexPath))) {
232
- return {
233
- version: '2.0', // v4.11: New version for unified index
234
- prompts: [],
235
- };
236
- }
237
- try {
238
- const content = await fs.readFile(indexPath, 'utf-8');
239
- const parsed = JSON.parse(content);
240
- // Ensure prompts array exists
241
- return {
242
- version: parsed.version || '2.0',
243
- prompts: Array.isArray(parsed.prompts) ? parsed.prompts : [],
244
- };
245
- }
246
- catch {
247
- // Corrupt index, return empty
248
- return {
249
- version: '2.0',
250
- prompts: [],
251
- };
252
- }
253
- }
254
- /**
255
- * v4.11: Save unified index to file
256
- */
257
- async saveIndex(index) {
258
- const indexPath = this.getIndexPath();
259
- await fs.ensureDir(path.dirname(indexPath));
260
- await fs.writeFile(indexPath, JSON.stringify(index, null, 2), 'utf-8');
261
- }
262
- /**
263
- * v4.11: Add prompt to unified index
264
- */
265
- async addToIndex(metadata) {
266
- const index = await this.loadIndex();
267
- // Remove any existing entry with same ID (shouldn't happen, but be safe)
268
- index.prompts = index.prompts.filter((p) => p.id !== metadata.id);
269
- // Add new entry
270
- index.prompts.push(metadata);
271
- await this.saveIndex(index);
272
- }
273
- }
274
- //# sourceMappingURL=prompt-manager.js.map