@codemcp/workflows-core 3.1.16

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 (114) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/LICENSE +674 -0
  3. package/dist/config-manager.d.ts +24 -0
  4. package/dist/config-manager.js +68 -0
  5. package/dist/config-manager.js.map +1 -0
  6. package/dist/conversation-manager.d.ts +97 -0
  7. package/dist/conversation-manager.js +367 -0
  8. package/dist/conversation-manager.js.map +1 -0
  9. package/dist/database.d.ts +73 -0
  10. package/dist/database.js +500 -0
  11. package/dist/database.js.map +1 -0
  12. package/dist/file-detection-manager.d.ts +53 -0
  13. package/dist/file-detection-manager.js +221 -0
  14. package/dist/file-detection-manager.js.map +1 -0
  15. package/dist/git-manager.d.ts +14 -0
  16. package/dist/git-manager.js +59 -0
  17. package/dist/git-manager.js.map +1 -0
  18. package/dist/index.d.ts +19 -0
  19. package/dist/index.js +25 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/instruction-generator.d.ts +69 -0
  22. package/dist/instruction-generator.js +133 -0
  23. package/dist/instruction-generator.js.map +1 -0
  24. package/dist/interaction-logger.d.ts +37 -0
  25. package/dist/interaction-logger.js +87 -0
  26. package/dist/interaction-logger.js.map +1 -0
  27. package/dist/logger.d.ts +64 -0
  28. package/dist/logger.js +283 -0
  29. package/dist/logger.js.map +1 -0
  30. package/dist/path-validation-utils.d.ts +51 -0
  31. package/dist/path-validation-utils.js +202 -0
  32. package/dist/path-validation-utils.js.map +1 -0
  33. package/dist/plan-manager.d.ts +65 -0
  34. package/dist/plan-manager.js +256 -0
  35. package/dist/plan-manager.js.map +1 -0
  36. package/dist/project-docs-manager.d.ts +119 -0
  37. package/dist/project-docs-manager.js +357 -0
  38. package/dist/project-docs-manager.js.map +1 -0
  39. package/dist/state-machine-loader.d.ts +60 -0
  40. package/dist/state-machine-loader.js +235 -0
  41. package/dist/state-machine-loader.js.map +1 -0
  42. package/dist/state-machine-types.d.ts +58 -0
  43. package/dist/state-machine-types.js +7 -0
  44. package/dist/state-machine-types.js.map +1 -0
  45. package/dist/state-machine.d.ts +52 -0
  46. package/dist/state-machine.js +256 -0
  47. package/dist/state-machine.js.map +1 -0
  48. package/dist/system-prompt-generator.d.ts +17 -0
  49. package/dist/system-prompt-generator.js +113 -0
  50. package/dist/system-prompt-generator.js.map +1 -0
  51. package/dist/template-manager.d.ts +61 -0
  52. package/dist/template-manager.js +229 -0
  53. package/dist/template-manager.js.map +1 -0
  54. package/dist/transition-engine.d.ts +70 -0
  55. package/dist/transition-engine.js +240 -0
  56. package/dist/transition-engine.js.map +1 -0
  57. package/dist/types.d.ts +56 -0
  58. package/dist/types.js +5 -0
  59. package/dist/types.js.map +1 -0
  60. package/dist/workflow-manager.d.ts +89 -0
  61. package/dist/workflow-manager.js +466 -0
  62. package/dist/workflow-manager.js.map +1 -0
  63. package/package.json +27 -0
  64. package/src/config-manager.ts +96 -0
  65. package/src/conversation-manager.ts +492 -0
  66. package/src/database.ts +685 -0
  67. package/src/file-detection-manager.ts +302 -0
  68. package/src/git-manager.ts +64 -0
  69. package/src/index.ts +28 -0
  70. package/src/instruction-generator.ts +210 -0
  71. package/src/interaction-logger.ts +109 -0
  72. package/src/logger.ts +353 -0
  73. package/src/path-validation-utils.ts +261 -0
  74. package/src/plan-manager.ts +323 -0
  75. package/src/project-docs-manager.ts +522 -0
  76. package/src/state-machine-loader.ts +308 -0
  77. package/src/state-machine-types.ts +72 -0
  78. package/src/state-machine.ts +370 -0
  79. package/src/system-prompt-generator.ts +122 -0
  80. package/src/template-manager.ts +321 -0
  81. package/src/transition-engine.ts +386 -0
  82. package/src/types.ts +60 -0
  83. package/src/workflow-manager.ts +601 -0
  84. package/test/unit/conversation-manager.test.ts +179 -0
  85. package/test/unit/custom-workflow-loading.test.ts +174 -0
  86. package/test/unit/directory-linking-and-extensions.test.ts +338 -0
  87. package/test/unit/file-linking-integration.test.ts +256 -0
  88. package/test/unit/git-commit-integration.test.ts +91 -0
  89. package/test/unit/git-manager.test.ts +86 -0
  90. package/test/unit/install-workflow.test.ts +138 -0
  91. package/test/unit/instruction-generator.test.ts +247 -0
  92. package/test/unit/list-workflows-filtering.test.ts +68 -0
  93. package/test/unit/none-template-functionality.test.ts +224 -0
  94. package/test/unit/project-docs-manager.test.ts +337 -0
  95. package/test/unit/state-machine-loader.test.ts +234 -0
  96. package/test/unit/template-manager.test.ts +217 -0
  97. package/test/unit/validate-workflow-name.test.ts +150 -0
  98. package/test/unit/workflow-domain-filtering.test.ts +75 -0
  99. package/test/unit/workflow-enum-generation.test.ts +92 -0
  100. package/test/unit/workflow-manager-enhanced-path-resolution.test.ts +369 -0
  101. package/test/unit/workflow-manager-path-resolution.test.ts +150 -0
  102. package/test/unit/workflow-migration.test.ts +155 -0
  103. package/test/unit/workflow-override-by-name.test.ts +116 -0
  104. package/test/unit/workflow-prioritization.test.ts +38 -0
  105. package/test/unit/workflow-validation.test.ts +303 -0
  106. package/test/utils/e2e-test-setup.ts +453 -0
  107. package/test/utils/run-server-in-dir.sh +27 -0
  108. package/test/utils/temp-files.ts +308 -0
  109. package/test/utils/test-access.ts +79 -0
  110. package/test/utils/test-helpers.ts +286 -0
  111. package/test/utils/test-setup.ts +78 -0
  112. package/tsconfig.build.json +21 -0
  113. package/tsconfig.json +8 -0
  114. package/vitest.config.ts +18 -0
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Path Validation Utilities
3
+ *
4
+ * Provides utilities for validating file paths, resolving relative paths,
5
+ * and ensuring security constraints for the file linking functionality.
6
+ */
7
+ import { access, stat } from 'node:fs/promises';
8
+ import { resolve, isAbsolute, join, normalize } from 'node:path';
9
+ import { createLogger } from './logger.js';
10
+ const logger = createLogger('PathValidationUtils');
11
+ export class PathValidationUtils {
12
+ /**
13
+ * Validate if a string is a known template name
14
+ */
15
+ static isTemplateName(value, availableTemplates) {
16
+ return availableTemplates.includes(value);
17
+ }
18
+ /**
19
+ * Validate and resolve a file path
20
+ */
21
+ static async validateFilePath(filePath, projectPath) {
22
+ try {
23
+ // Resolve the path to absolute
24
+ const resolvedPath = this.resolvePath(filePath, projectPath);
25
+ // Security validation - prevent directory traversal
26
+ if (!this.isPathSafe(resolvedPath, projectPath)) {
27
+ return {
28
+ isValid: false,
29
+ error: 'Path is outside project boundaries for security reasons',
30
+ };
31
+ }
32
+ // Check if file exists and is readable
33
+ await access(resolvedPath);
34
+ // Verify it's a file (not a directory)
35
+ const stats = await stat(resolvedPath);
36
+ if (!stats.isFile()) {
37
+ return {
38
+ isValid: false,
39
+ error: 'Path points to a directory, not a file',
40
+ };
41
+ }
42
+ logger.debug('File path validated successfully', {
43
+ originalPath: filePath,
44
+ resolvedPath,
45
+ });
46
+ return {
47
+ isValid: true,
48
+ resolvedPath,
49
+ };
50
+ }
51
+ catch (error) {
52
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
53
+ logger.debug('File path validation failed', {
54
+ filePath,
55
+ error: errorMessage,
56
+ });
57
+ return {
58
+ isValid: false,
59
+ error: `File not found or not accessible: ${errorMessage}`,
60
+ };
61
+ }
62
+ }
63
+ /**
64
+ * Validate and resolve a file or directory path
65
+ */
66
+ static async validateFileOrDirectoryPath(filePath, projectPath) {
67
+ try {
68
+ // Resolve the path to absolute
69
+ const resolvedPath = this.resolvePath(filePath, projectPath);
70
+ // Security validation - prevent directory traversal
71
+ if (!this.isPathSafe(resolvedPath, projectPath)) {
72
+ return {
73
+ isValid: false,
74
+ error: 'Path is outside project boundaries for security reasons',
75
+ };
76
+ }
77
+ // Check if file or directory exists and is readable
78
+ await access(resolvedPath);
79
+ // Verify it's either a file or directory
80
+ const stats = await stat(resolvedPath);
81
+ if (!stats.isFile() && !stats.isDirectory()) {
82
+ return {
83
+ isValid: false,
84
+ error: 'Path is neither a file nor a directory',
85
+ };
86
+ }
87
+ logger.debug('File or directory path validated successfully', {
88
+ originalPath: filePath,
89
+ resolvedPath,
90
+ isFile: stats.isFile(),
91
+ isDirectory: stats.isDirectory(),
92
+ });
93
+ return {
94
+ isValid: true,
95
+ resolvedPath,
96
+ };
97
+ }
98
+ catch (error) {
99
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
100
+ logger.debug('File or directory path validation failed', {
101
+ filePath,
102
+ error: errorMessage,
103
+ });
104
+ return {
105
+ isValid: false,
106
+ error: `File or directory not found or not accessible: ${errorMessage}`,
107
+ };
108
+ }
109
+ }
110
+ /**
111
+ * Resolve a file path to absolute, handling various formats
112
+ */
113
+ static resolvePath(filePath, projectPath) {
114
+ // If already absolute, return as-is
115
+ if (isAbsolute(filePath)) {
116
+ return normalize(filePath);
117
+ }
118
+ // Handle relative paths (./file, ../file, file)
119
+ return resolve(projectPath, filePath);
120
+ }
121
+ /**
122
+ * Check if a resolved path is within safe boundaries
123
+ * Prevents directory traversal attacks
124
+ */
125
+ static isPathSafe(resolvedPath, projectPath) {
126
+ const normalizedResolved = normalize(resolvedPath);
127
+ const normalizedProject = normalize(projectPath);
128
+ // Allow paths within the project directory
129
+ if (normalizedResolved.startsWith(normalizedProject)) {
130
+ return true;
131
+ }
132
+ // Allow paths in common documentation locations relative to project
133
+ const allowedPaths = [
134
+ normalize(join(projectPath, '..')), // Parent directory (for monorepos)
135
+ '/usr/share/doc', // System documentation
136
+ '/opt/docs', // Optional documentation
137
+ ];
138
+ return allowedPaths.some(allowedPath => normalizedResolved.startsWith(allowedPath));
139
+ }
140
+ /**
141
+ * Validate parameter as either template name or file path
142
+ */
143
+ static async validateParameter(value, availableTemplates, projectPath) {
144
+ // First check if it's a template name
145
+ if (this.isTemplateName(value, availableTemplates)) {
146
+ return {
147
+ isTemplate: true,
148
+ isFilePath: false,
149
+ };
150
+ }
151
+ // Then validate as file or directory path
152
+ const pathValidation = await this.validateFileOrDirectoryPath(value, projectPath);
153
+ if (pathValidation.isValid) {
154
+ return {
155
+ isTemplate: false,
156
+ isFilePath: true,
157
+ resolvedPath: pathValidation.resolvedPath,
158
+ };
159
+ }
160
+ // Neither template nor valid file/directory path
161
+ return {
162
+ isTemplate: false,
163
+ isFilePath: false,
164
+ error: `Invalid parameter: not a known template (${availableTemplates.join(', ')}) and not a valid file or directory path (${pathValidation.error})`,
165
+ };
166
+ }
167
+ /**
168
+ * Get common file patterns for documentation
169
+ */
170
+ static getCommonDocumentationPatterns() {
171
+ return {
172
+ architecture: [
173
+ 'ARCHITECTURE.md',
174
+ 'ARCHITECTURE.txt',
175
+ 'architecture.md',
176
+ 'Architecture.md',
177
+ 'docs/ARCHITECTURE.md',
178
+ 'docs/architecture.md',
179
+ 'README.md', // Can contain architecture info
180
+ ],
181
+ requirements: [
182
+ 'REQUIREMENTS.md',
183
+ 'REQUIREMENTS.txt',
184
+ 'requirements.md',
185
+ 'Requirements.md',
186
+ 'docs/REQUIREMENTS.md',
187
+ 'docs/requirements.md',
188
+ 'README.md', // Often contains requirements
189
+ ],
190
+ design: [
191
+ 'DESIGN.md',
192
+ 'DESIGN.txt',
193
+ 'design.md',
194
+ 'Design.md',
195
+ 'docs/DESIGN.md',
196
+ 'docs/design.md',
197
+ 'README.md', // Can contain design info
198
+ ],
199
+ };
200
+ }
201
+ }
202
+ //# sourceMappingURL=path-validation-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-validation-utils.js","sourceRoot":"","sources":["../src/path-validation-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Plan Manager
3
+ *
4
+ * Handles the creation, updating, and maintenance of project development plan files.
5
+ * Manages markdown plan files that serve as long-term project memory.
6
+ * Supports custom state machine definitions for dynamic plan file generation.
7
+ */
8
+ import type { YamlStateMachine } from './state-machine-types.js';
9
+ export interface PlanFileInfo {
10
+ path: string;
11
+ exists: boolean;
12
+ content?: string;
13
+ }
14
+ export declare class PlanManager {
15
+ private stateMachine;
16
+ /**
17
+ * Set the state machine definition for dynamic plan generation
18
+ */
19
+ setStateMachine(stateMachine: YamlStateMachine): void;
20
+ /**
21
+ * Get plan file information
22
+ */
23
+ getPlanFileInfo(planFilePath: string): Promise<PlanFileInfo>;
24
+ /**
25
+ * Create initial plan file if it doesn't exist
26
+ */
27
+ ensurePlanFile(planFilePath: string, projectPath: string, gitBranch: string): Promise<void>;
28
+ /**
29
+ * Create initial plan file with template content
30
+ */
31
+ private createInitialPlanFile;
32
+ /**
33
+ * Generate initial plan file content based on state machine definition
34
+ */
35
+ private generateInitialPlanContent;
36
+ /**
37
+ * Update plan file with new content (this is typically done by the LLM)
38
+ */
39
+ updatePlanFile(planFilePath: string, content: string): Promise<void>;
40
+ /**
41
+ * Get plan file content for LLM context
42
+ */
43
+ getPlanFileContent(planFilePath: string): Promise<string>;
44
+ /**
45
+ * Generate phase-specific plan file guidance based on state machine
46
+ */
47
+ generatePlanFileGuidance(phase: string): string;
48
+ /**
49
+ * Delete plan file
50
+ */
51
+ deletePlanFile(planFilePath: string): Promise<boolean>;
52
+ /**
53
+ * Ensure plan file is deleted (verify deletion)
54
+ */
55
+ ensurePlanFileDeleted(planFilePath: string): Promise<boolean>;
56
+ /**
57
+ * Capitalize phase name for display
58
+ */
59
+ private capitalizePhase;
60
+ /**
61
+ * Generate workflow documentation URL for predefined workflows
62
+ * Returns undefined for custom workflows
63
+ */
64
+ private generateWorkflowDocumentationUrl;
65
+ }
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Plan Manager
3
+ *
4
+ * Handles the creation, updating, and maintenance of project development plan files.
5
+ * Manages markdown plan files that serve as long-term project memory.
6
+ * Supports custom state machine definitions for dynamic plan file generation.
7
+ */
8
+ import { writeFile, readFile, access } from 'node:fs/promises';
9
+ import { dirname } from 'node:path';
10
+ import { mkdir } from 'node:fs/promises';
11
+ import { createLogger } from './logger.js';
12
+ const logger = createLogger('PlanManager');
13
+ export class PlanManager {
14
+ stateMachine = null;
15
+ /**
16
+ * Set the state machine definition for dynamic plan generation
17
+ */
18
+ setStateMachine(stateMachine) {
19
+ this.stateMachine = stateMachine;
20
+ logger.debug('State machine set for plan manager', {
21
+ name: stateMachine.name,
22
+ phases: Object.keys(stateMachine.states),
23
+ });
24
+ }
25
+ /**
26
+ * Get plan file information
27
+ */
28
+ async getPlanFileInfo(planFilePath) {
29
+ try {
30
+ await access(planFilePath);
31
+ const content = await readFile(planFilePath, 'utf-8');
32
+ return {
33
+ path: planFilePath,
34
+ exists: true,
35
+ content,
36
+ };
37
+ }
38
+ catch (_error) {
39
+ return {
40
+ path: planFilePath,
41
+ exists: false,
42
+ };
43
+ }
44
+ }
45
+ /**
46
+ * Create initial plan file if it doesn't exist
47
+ */
48
+ async ensurePlanFile(planFilePath, projectPath, gitBranch) {
49
+ logger.debug('Ensuring plan file exists', {
50
+ planFilePath,
51
+ projectPath,
52
+ gitBranch,
53
+ });
54
+ const planInfo = await this.getPlanFileInfo(planFilePath);
55
+ if (!planInfo.exists) {
56
+ logger.info('Plan file not found, creating initial plan', {
57
+ planFilePath,
58
+ });
59
+ await this.createInitialPlanFile(planFilePath, projectPath, gitBranch);
60
+ logger.info('Initial plan file created successfully', { planFilePath });
61
+ }
62
+ else {
63
+ logger.debug('Plan file already exists', { planFilePath });
64
+ }
65
+ }
66
+ /**
67
+ * Create initial plan file with template content
68
+ */
69
+ async createInitialPlanFile(planFilePath, projectPath, gitBranch) {
70
+ logger.debug('Creating initial plan file', { planFilePath });
71
+ try {
72
+ // Ensure directory exists
73
+ await mkdir(dirname(planFilePath), { recursive: true });
74
+ logger.debug('Plan file directory ensured', {
75
+ directory: dirname(planFilePath),
76
+ });
77
+ const projectName = projectPath.split('/').pop() || 'Unknown Project';
78
+ const branchInfo = gitBranch !== 'no-git' ? ` (${gitBranch} branch)` : '';
79
+ const initialContent = this.generateInitialPlanContent(projectName, branchInfo);
80
+ await writeFile(planFilePath, initialContent, 'utf-8');
81
+ logger.info('Initial plan file written successfully', {
82
+ planFilePath,
83
+ contentLength: initialContent.length,
84
+ projectName,
85
+ });
86
+ }
87
+ catch (error) {
88
+ logger.error('Failed to create initial plan file', error, {
89
+ planFilePath,
90
+ });
91
+ throw error;
92
+ }
93
+ }
94
+ /**
95
+ * Generate initial plan file content based on state machine definition
96
+ */
97
+ generateInitialPlanContent(projectName, branchInfo) {
98
+ const timestamp = new Date().toISOString().split('T')[0];
99
+ if (!this.stateMachine) {
100
+ throw new Error('State machine not set. This should not happen as state machine is always loaded.');
101
+ }
102
+ const phases = Object.keys(this.stateMachine.states);
103
+ const initialPhase = this.stateMachine.initial_state;
104
+ const documentationUrl = this.generateWorkflowDocumentationUrl(this.stateMachine.name);
105
+ let content = `# Development Plan: ${projectName}${branchInfo}
106
+
107
+ *Generated on ${timestamp} by Vibe Feature MCP*
108
+ *Workflow: ${documentationUrl
109
+ ? '[' + this.stateMachine.name + ']' + '(' + documentationUrl + ')'
110
+ : this.stateMachine.name}*
111
+
112
+ ## Goal
113
+ *Define what you're building or fixing - this will be updated as requirements are gathered*
114
+
115
+ ## ${this.capitalizePhase(initialPhase)}
116
+ ### Tasks
117
+ - [ ] *Tasks will be added as they are identified*
118
+
119
+ ### Completed
120
+ - [x] Created development plan file
121
+
122
+ `;
123
+ // Generate simple sections for each phase
124
+ for (const phase of phases) {
125
+ if (phase !== initialPhase) {
126
+ content += `## ${this.capitalizePhase(phase)}
127
+ ### Tasks
128
+ - [ ] *To be added when this phase becomes active*
129
+
130
+ ### Completed
131
+ *None yet*
132
+
133
+ `;
134
+ }
135
+ }
136
+ content += `## Key Decisions
137
+ *Important decisions will be documented here as they are made*
138
+
139
+ ## Notes
140
+ *Additional context and observations*
141
+
142
+ ---
143
+ *This plan is maintained by the LLM. Tool responses provide guidance on which section to focus on and what tasks to work on.*
144
+ `;
145
+ return content;
146
+ }
147
+ /**
148
+ * Update plan file with new content (this is typically done by the LLM)
149
+ */
150
+ async updatePlanFile(planFilePath, content) {
151
+ // Ensure directory exists
152
+ await mkdir(dirname(planFilePath), { recursive: true });
153
+ await writeFile(planFilePath, content, 'utf-8');
154
+ }
155
+ /**
156
+ * Get plan file content for LLM context
157
+ */
158
+ async getPlanFileContent(planFilePath) {
159
+ const planInfo = await this.getPlanFileInfo(planFilePath);
160
+ if (!planInfo.exists) {
161
+ return 'Plan file does not exist yet. It will be created when the LLM updates it.';
162
+ }
163
+ return planInfo.content || '';
164
+ }
165
+ /**
166
+ * Generate phase-specific plan file guidance based on state machine
167
+ */
168
+ generatePlanFileGuidance(phase) {
169
+ if (!this.stateMachine) {
170
+ throw new Error('State machine not set. This should not happen as state machine is always loaded.');
171
+ }
172
+ const phaseDefinition = this.stateMachine.states[phase];
173
+ if (!phaseDefinition) {
174
+ logger.warn('Unknown phase for plan file guidance', { phase });
175
+ return `Update the ${this.capitalizePhase(phase)} section with current progress and mark completed tasks.`;
176
+ }
177
+ const capitalizedPhase = this.capitalizePhase(phase);
178
+ return `Update the ${capitalizedPhase} section with progress. Mark completed tasks with [x] and add new tasks as they are identified.`;
179
+ }
180
+ /**
181
+ * Delete plan file
182
+ */
183
+ async deletePlanFile(planFilePath) {
184
+ logger.debug('Deleting plan file', { planFilePath });
185
+ try {
186
+ // Check if file exists first
187
+ await access(planFilePath);
188
+ // Import unlink dynamically to avoid issues
189
+ const { unlink } = await import('node:fs/promises');
190
+ await unlink(planFilePath);
191
+ logger.info('Plan file deleted successfully', { planFilePath });
192
+ return true;
193
+ }
194
+ catch (error) {
195
+ if (error.code === 'ENOENT') {
196
+ logger.debug('Plan file does not exist, nothing to delete', {
197
+ planFilePath,
198
+ });
199
+ return true; // Consider it successful if file doesn't exist
200
+ }
201
+ logger.error('Failed to delete plan file', error, {
202
+ planFilePath,
203
+ });
204
+ throw error;
205
+ }
206
+ }
207
+ /**
208
+ * Ensure plan file is deleted (verify deletion)
209
+ */
210
+ async ensurePlanFileDeleted(planFilePath) {
211
+ logger.debug('Ensuring plan file is deleted', { planFilePath });
212
+ try {
213
+ await access(planFilePath);
214
+ // If we reach here, file still exists
215
+ logger.warn('Plan file still exists after deletion attempt', {
216
+ planFilePath,
217
+ });
218
+ return false;
219
+ }
220
+ catch (error) {
221
+ if (error.code === 'ENOENT') {
222
+ logger.debug('Plan file successfully deleted (does not exist)', {
223
+ planFilePath,
224
+ });
225
+ return true;
226
+ }
227
+ // Some other error occurred
228
+ logger.error('Error checking plan file deletion', error, {
229
+ planFilePath,
230
+ });
231
+ throw error;
232
+ }
233
+ }
234
+ /**
235
+ * Capitalize phase name for display
236
+ */
237
+ capitalizePhase(phase) {
238
+ return phase
239
+ .split('_')
240
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
241
+ .join(' ');
242
+ }
243
+ /**
244
+ * Generate workflow documentation URL for predefined workflows
245
+ * Returns undefined for custom workflows
246
+ */
247
+ generateWorkflowDocumentationUrl(workflowName) {
248
+ // Don't generate URL for custom workflows
249
+ if (workflowName === 'custom') {
250
+ return undefined;
251
+ }
252
+ // Generate URL for predefined workflows
253
+ return `https://mrsimpson.github.io/responsible-vibe-mcp/workflows/${workflowName}`;
254
+ }
255
+ }
256
+ //# sourceMappingURL=plan-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-manager.js","sourceRoot":"","sources":["../src/plan-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Project Docs Manager
3
+ *
4
+ * Manages project documentation artifacts (architecture.md, requirements.md, design.md)
5
+ * separate from the workflow-specific plan files. Handles creation, validation, and
6
+ * path resolution for project documents. Now supports both template creation and
7
+ * file linking via symlinks.
8
+ */
9
+ import { TemplateManager, TemplateOptions } from './template-manager.js';
10
+ export interface ProjectDocsInfo {
11
+ architecture: {
12
+ path: string;
13
+ exists: boolean;
14
+ };
15
+ requirements: {
16
+ path: string;
17
+ exists: boolean;
18
+ };
19
+ design: {
20
+ path: string;
21
+ exists: boolean;
22
+ };
23
+ }
24
+ export interface CreateOrLinkResult {
25
+ created: string[];
26
+ linked: string[];
27
+ skipped: string[];
28
+ }
29
+ export declare class ProjectDocsManager {
30
+ templateManager: TemplateManager;
31
+ constructor();
32
+ /**
33
+ * Get project docs directory path
34
+ */
35
+ getDocsPath(projectPath: string): string;
36
+ /**
37
+ * Determine the appropriate extension for a document based on source path
38
+ */
39
+ private getDocumentExtension;
40
+ /**
41
+ * Get the target filename for a document type
42
+ */
43
+ private getDocumentFilename;
44
+ /**
45
+ * Get paths for all project documents
46
+ */
47
+ getDocumentPaths(projectPath: string): {
48
+ architecture: string;
49
+ requirements: string;
50
+ design: string;
51
+ };
52
+ /**
53
+ * Get paths for all project documents with dynamic extensions based on source paths
54
+ */
55
+ getDocumentPathsWithExtensions(projectPath: string, sourcePaths?: Partial<{
56
+ architecture: string;
57
+ requirements: string;
58
+ design: string;
59
+ }>): Promise<{
60
+ architecture: string;
61
+ requirements: string;
62
+ design: string;
63
+ }>;
64
+ /**
65
+ * Check which project documents exist
66
+ */
67
+ getProjectDocsInfo(projectPath: string): Promise<ProjectDocsInfo>;
68
+ /**
69
+ * Create project documents using templates (legacy method for backward compatibility)
70
+ */
71
+ createProjectDocs(projectPath: string, options?: TemplateOptions): Promise<{
72
+ created: string[];
73
+ skipped: string[];
74
+ }>;
75
+ /**
76
+ * Create or link project documents using templates and/or file paths
77
+ */
78
+ createOrLinkProjectDocs(projectPath: string, templateOptions?: Partial<TemplateOptions>, filePaths?: Partial<{
79
+ architecture: string;
80
+ requirements: string;
81
+ design: string;
82
+ }>): Promise<CreateOrLinkResult>;
83
+ /**
84
+ * Create a symlink to an existing file
85
+ */
86
+ createSymlink(sourcePath: string, targetPath: string): Promise<void>;
87
+ /**
88
+ * Remove existing document or symlink
89
+ */
90
+ private removeExistingDocument;
91
+ /**
92
+ * Create a single document from template
93
+ */
94
+ private createDocument;
95
+ /**
96
+ * Get variable substitutions for workflow instructions
97
+ */
98
+ getVariableSubstitutions(projectPath: string): Record<string, string>;
99
+ /**
100
+ * Get variable substitutions for workflow instructions with dynamic paths
101
+ */
102
+ getVariableSubstitutionsWithExtensions(projectPath: string, sourcePaths?: Partial<{
103
+ architecture: string;
104
+ requirements: string;
105
+ design: string;
106
+ }>): Promise<Record<string, string>>;
107
+ /**
108
+ * Read a project document - returns the path for LLM to read as needed
109
+ */
110
+ readDocument(projectPath: string, type: 'architecture' | 'requirements' | 'design'): Promise<string>;
111
+ /**
112
+ * Check if all project documents exist
113
+ */
114
+ allDocumentsExist(projectPath: string): Promise<boolean>;
115
+ /**
116
+ * Check if a document is a symlink
117
+ */
118
+ isSymlink(projectPath: string, type: 'architecture' | 'requirements' | 'design'): Promise<boolean>;
119
+ }