@codemcp/workflows 5.0.1 → 5.1.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 (77) hide show
  1. package/package.json +6 -2
  2. package/skill/SKILL.md +23 -0
  3. package/.prettierignore +0 -2
  4. package/.turbo/turbo-build.log +0 -4
  5. package/.vibe/conversation-state.sqlite +0 -0
  6. package/src/components/beads/beads-instruction-generator.ts +0 -230
  7. package/src/components/beads/beads-plan-manager.ts +0 -333
  8. package/src/components/beads/beads-task-backend-client.ts +0 -229
  9. package/src/index.ts +0 -93
  10. package/src/notification-service.ts +0 -23
  11. package/src/plugin-system/beads-plugin.ts +0 -649
  12. package/src/plugin-system/commit-plugin.ts +0 -252
  13. package/src/plugin-system/index.ts +0 -20
  14. package/src/plugin-system/plugin-interfaces.ts +0 -153
  15. package/src/plugin-system/plugin-registry.ts +0 -190
  16. package/src/resource-handlers/conversation-state.ts +0 -55
  17. package/src/resource-handlers/development-plan.ts +0 -48
  18. package/src/resource-handlers/index.ts +0 -73
  19. package/src/resource-handlers/system-prompt.ts +0 -55
  20. package/src/resource-handlers/workflow-resource.ts +0 -132
  21. package/src/response-renderer.ts +0 -116
  22. package/src/server-config.ts +0 -760
  23. package/src/server-helpers.ts +0 -245
  24. package/src/server-implementation.ts +0 -277
  25. package/src/server.ts +0 -9
  26. package/src/tool-handlers/base-tool-handler.ts +0 -151
  27. package/src/tool-handlers/conduct-review.ts +0 -190
  28. package/src/tool-handlers/get-tool-info.ts +0 -273
  29. package/src/tool-handlers/index.ts +0 -115
  30. package/src/tool-handlers/list-workflows.ts +0 -78
  31. package/src/tool-handlers/no-idea.ts +0 -47
  32. package/src/tool-handlers/proceed-to-phase.ts +0 -296
  33. package/src/tool-handlers/reset-development.ts +0 -90
  34. package/src/tool-handlers/resume-workflow.ts +0 -378
  35. package/src/tool-handlers/setup-project-docs.ts +0 -232
  36. package/src/tool-handlers/start-development.ts +0 -746
  37. package/src/tool-handlers/whats-next.ts +0 -246
  38. package/src/types.ts +0 -135
  39. package/src/version-info.ts +0 -213
  40. package/test/e2e/beads-plugin-integration.test.ts +0 -1623
  41. package/test/e2e/commit-plugin-integration.test.ts +0 -222
  42. package/test/e2e/core-functionality.test.ts +0 -167
  43. package/test/e2e/git-branch-detection.test.ts +0 -351
  44. package/test/e2e/mcp-contract.test.ts +0 -509
  45. package/test/e2e/plan-management.test.ts +0 -334
  46. package/test/e2e/plugin-system-integration.test.ts +0 -1410
  47. package/test/e2e/state-management.test.ts +0 -387
  48. package/test/e2e/workflow-integration.test.ts +0 -498
  49. package/test/unit/beads-instruction-generator.test.ts +0 -979
  50. package/test/unit/beads-phase-task-id-integration.test.ts +0 -535
  51. package/test/unit/beads-plugin-behavioral.test.ts +0 -545
  52. package/test/unit/beads-plugin.test.ts +0 -117
  53. package/test/unit/commit-plugin.test.ts +0 -196
  54. package/test/unit/conduct-review.test.ts +0 -151
  55. package/test/unit/conversation-not-found-error.test.ts +0 -120
  56. package/test/unit/plugin-error-handling.test.ts +0 -240
  57. package/test/unit/proceed-to-phase-plugin-integration.test.ts +0 -150
  58. package/test/unit/reset-functionality.test.ts +0 -72
  59. package/test/unit/resume-workflow.test.ts +0 -193
  60. package/test/unit/server-config-plugin-registry.test.ts +0 -99
  61. package/test/unit/server-tools.test.ts +0 -310
  62. package/test/unit/setup-project-docs-handler.test.ts +0 -268
  63. package/test/unit/start-development-artifact-detection.test.ts +0 -387
  64. package/test/unit/start-development-gitignore.test.ts +0 -178
  65. package/test/unit/start-development-goal-extraction.test.ts +0 -226
  66. package/test/unit/system-prompt-resource.test.ts +0 -102
  67. package/test/unit/tool-handlers/no-idea.test.ts +0 -40
  68. package/test/utils/e2e-test-setup.ts +0 -451
  69. package/test/utils/run-server-in-dir.sh +0 -27
  70. package/test/utils/temp-files.ts +0 -320
  71. package/test/utils/test-access.ts +0 -79
  72. package/test/utils/test-helpers.ts +0 -288
  73. package/test/utils/test-setup.ts +0 -77
  74. package/tsconfig.build.json +0 -10
  75. package/tsconfig.build.tsbuildinfo +0 -1
  76. package/tsconfig.json +0 -12
  77. package/vitest.config.ts +0 -19
@@ -1,296 +0,0 @@
1
- /**
2
- * ProceedToPhase Tool Handler
3
- *
4
- * Handles explicit transitions to specific development phases when the current
5
- * phase is complete or when a direct phase change is needed.
6
- */
7
-
8
- import { ConversationRequiredToolHandler } from './base-tool-handler.js';
9
- import { validateRequiredArgs } from '../server-helpers.js';
10
- import type { ConversationContext } from '@codemcp/workflows-core';
11
- import { ServerContext } from '../types.js';
12
-
13
- /**
14
- * Arguments for the proceed_to_phase tool
15
- */
16
- export interface ProceedToPhaseArgs {
17
- target_phase: string;
18
- reason?: string;
19
- review_state: 'not-required' | 'pending' | 'performed';
20
- }
21
-
22
- /**
23
- * Response from the proceed_to_phase tool
24
- */
25
- export interface ProceedToPhaseResult {
26
- phase: string;
27
- instructions: string;
28
- plan_file_path: string;
29
- transition_reason: string;
30
- }
31
-
32
- /**
33
- * ProceedToPhase tool handler implementation
34
- */
35
- export class ProceedToPhaseHandler extends ConversationRequiredToolHandler<
36
- ProceedToPhaseArgs,
37
- ProceedToPhaseResult
38
- > {
39
- protected async executeWithConversation(
40
- args: ProceedToPhaseArgs,
41
- context: ServerContext,
42
- conversationContext: ConversationContext
43
- ): Promise<ProceedToPhaseResult> {
44
- // Validate required arguments
45
- validateRequiredArgs(args, ['target_phase', 'review_state']);
46
-
47
- const { target_phase, reason = '', review_state } = args;
48
- const conversationId = conversationContext.conversationId;
49
- const currentPhase = conversationContext.currentPhase;
50
-
51
- this.logger.debug('Processing proceed_to_phase request', {
52
- conversationId,
53
- currentPhase,
54
- targetPhase: target_phase,
55
- reason,
56
- reviewState: review_state,
57
- });
58
-
59
- // Validate review state if reviews are required
60
- if (conversationContext.requireReviewsBeforePhaseTransition) {
61
- await this.validateReviewState(
62
- review_state,
63
- currentPhase,
64
- target_phase,
65
- conversationContext.workflowName,
66
- context
67
- );
68
- }
69
-
70
- // Validate agent role for crowd workflows
71
- await this.validateAgentRole(
72
- currentPhase,
73
- target_phase,
74
- conversationContext.workflowName,
75
- conversationContext.projectPath,
76
- context
77
- );
78
-
79
- // Execute plugin hooks before phase transition (replaces if-statement pattern)
80
- const pluginContext = {
81
- conversationId,
82
- planFilePath: conversationContext.planFilePath,
83
- currentPhase,
84
- workflow: conversationContext.workflowName,
85
- projectPath: conversationContext.projectPath,
86
- gitBranch: conversationContext.gitBranch,
87
- targetPhase: target_phase,
88
- };
89
-
90
- // Execute plugin hooks safely - guard against missing plugin registry
91
- if (context.pluginRegistry) {
92
- await context.pluginRegistry.executeHook(
93
- 'beforePhaseTransition',
94
- pluginContext,
95
- currentPhase,
96
- target_phase
97
- );
98
- }
99
-
100
- // Ensure state machine is loaded for this project
101
- this.ensureStateMachineForProject(context, conversationContext.projectPath);
102
-
103
- // Perform explicit transition
104
- const transitionResult = context.transitionEngine.handleExplicitTransition(
105
- currentPhase,
106
- target_phase,
107
- conversationContext.projectPath,
108
- reason,
109
- conversationContext.workflowName
110
- );
111
-
112
- // Update conversation state
113
- await context.conversationManager.updateConversationState(conversationId, {
114
- currentPhase: transitionResult.newPhase,
115
- });
116
-
117
- this.logger.info('Explicit phase transition completed', {
118
- from: currentPhase,
119
- to: transitionResult.newPhase,
120
- reason: transitionResult.transitionReason,
121
- });
122
-
123
- // Ensure plan file exists - or create it
124
- await context.planManager.ensurePlanFile(
125
- conversationContext.planFilePath,
126
- conversationContext.projectPath,
127
- conversationContext.gitBranch
128
- );
129
-
130
- // Check if plan file exists
131
- const planInfo = await context.planManager.getPlanFileInfo(
132
- conversationContext.planFilePath
133
- );
134
-
135
- // Generate enhanced instructions
136
- const instructions =
137
- await context.instructionGenerator.generateInstructions(
138
- transitionResult.instructions,
139
- {
140
- phase: transitionResult.newPhase,
141
- conversationContext: {
142
- ...conversationContext,
143
- currentPhase: transitionResult.newPhase,
144
- },
145
- transitionReason: transitionResult.transitionReason,
146
- isModeled: transitionResult.isModeled,
147
- planFileExists: planInfo.exists,
148
- instructionSource: 'proceed_to_phase',
149
- }
150
- );
151
-
152
- instructions.instructions += `
153
-
154
- After transitioning to the ${transitionResult.newPhase} phase, check the already created tasks and add those that are missing based on the key decisions noted in the plan file.
155
- While doing this, also denote dependencies for each task.
156
- `;
157
-
158
- // Prepare response (commit behavior now handled by CommitPlugin)
159
- const response: ProceedToPhaseResult = {
160
- phase: transitionResult.newPhase,
161
- instructions: instructions.instructions,
162
- plan_file_path: conversationContext.planFilePath,
163
- transition_reason: transitionResult.transitionReason,
164
- };
165
-
166
- // Log interaction
167
- await this.logInteraction(
168
- context,
169
- conversationId,
170
- 'proceed_to_phase',
171
- args,
172
- response,
173
- transitionResult.newPhase
174
- );
175
-
176
- return response;
177
- }
178
-
179
- /**
180
- * Validate review state for transitions that require reviews
181
- */
182
- private async validateReviewState(
183
- reviewState: string,
184
- currentPhase: string,
185
- targetPhase: string,
186
- workflowName: string,
187
- context: ServerContext
188
- ): Promise<void> {
189
- // Get transition configuration from workflow
190
- const stateMachine = context.workflowManager.loadWorkflowForProject(
191
- context.projectPath,
192
- workflowName
193
- );
194
- const currentState = stateMachine.states[currentPhase];
195
-
196
- if (!currentState) {
197
- throw new Error(`Invalid current phase: ${currentPhase}`);
198
- }
199
-
200
- const transition = currentState.transitions.find(t => t.to === targetPhase);
201
- if (!transition) {
202
- throw new Error(
203
- `No transition found from ${currentPhase} to ${targetPhase}`
204
- );
205
- }
206
-
207
- const hasReviewPerspectives =
208
- transition.review_perspectives &&
209
- transition.review_perspectives.length > 0;
210
-
211
- if (hasReviewPerspectives) {
212
- // This transition has review perspectives defined
213
- if (reviewState === 'pending') {
214
- throw new Error(
215
- `Review is required before proceeding to ${targetPhase}. Please use the conduct_review tool first.`
216
- );
217
- }
218
- if (reviewState === 'not-required') {
219
- throw new Error(
220
- `This transition requires review, but review_state is 'not-required'. Use 'pending' or 'performed'.`
221
- );
222
- }
223
- } else {
224
- // No review perspectives defined - transition proceeds normally
225
- // Note: No error thrown when hasReviewPerspectives is false, as per user feedback
226
- }
227
- }
228
-
229
- /**
230
- * Validate that the agent's role allows this phase transition (for crowd workflows)
231
- */
232
- private async validateAgentRole(
233
- currentPhase: string,
234
- targetPhase: string,
235
- workflowName: string,
236
- projectPath: string,
237
- context: ServerContext
238
- ): Promise<void> {
239
- // Get agent role from environment
240
- const agentRole = process.env['VIBE_ROLE'];
241
-
242
- // If no role specified, skip validation (single-agent mode)
243
- if (!agentRole) {
244
- return;
245
- }
246
-
247
- // Load workflow to check if it's a collaborative workflow
248
- const stateMachine = context.workflowManager.loadWorkflowForProject(
249
- projectPath,
250
- workflowName
251
- );
252
-
253
- // If workflow doesn't have collaboration enabled, skip validation
254
- if (!stateMachine.metadata?.collaboration) {
255
- return;
256
- }
257
-
258
- // Get current state definition
259
- const currentState = stateMachine.states[currentPhase];
260
- if (!currentState) {
261
- throw new Error(`Invalid current phase: ${currentPhase}`);
262
- }
263
-
264
- // Find the transition for this agent's role
265
- const agentTransition = currentState.transitions.find(
266
- t => t.to === targetPhase && (t.role === agentRole || !t.role)
267
- );
268
-
269
- if (!agentTransition) {
270
- throw new Error(
271
- `Agent with role '${agentRole}' cannot proceed from ${currentPhase} to ${targetPhase}. ` +
272
- `No transition available for this role.`
273
- );
274
- }
275
-
276
- // Check if agent will be responsible in target phase
277
- // Look at target state's outgoing transitions to determine responsibility
278
- const targetState = stateMachine.states[targetPhase];
279
- if (targetState) {
280
- const isResponsibleInTarget = targetState.transitions.some(
281
- t =>
282
- t.role === agentRole &&
283
- t.additional_instructions?.includes('RESPONSIBLE')
284
- );
285
-
286
- if (!isResponsibleInTarget) {
287
- // Agent is not responsible in target phase
288
- // This is allowed (agent can transition to consultation mode)
289
- this.logger.debug('Agent transitioning to consultative role', {
290
- agentRole,
291
- phase: targetPhase,
292
- });
293
- }
294
- }
295
- }
296
- }
@@ -1,90 +0,0 @@
1
- /**
2
- * ResetDevelopment Tool Handler
3
- *
4
- * Handles resetting conversation state and development progress.
5
- * This permanently deletes conversation state and plan file, while
6
- * soft-deleting interaction logs for audit trail.
7
- */
8
-
9
- import { BaseToolHandler } from './base-tool-handler.js';
10
- import { validateRequiredArgs } from '../server-helpers.js';
11
- import { ServerContext } from '../types.js';
12
-
13
- /**
14
- * Arguments for the reset_development tool
15
- */
16
- export interface ResetDevelopmentArgs {
17
- confirm: boolean;
18
- reason?: string;
19
- }
20
-
21
- /**
22
- * Response from the reset_development tool
23
- */
24
- export interface ResetDevelopmentResult {
25
- success: boolean;
26
- resetItems: string[];
27
- message: string;
28
- }
29
-
30
- /**
31
- * ResetDevelopment tool handler implementation
32
- */
33
- export class ResetDevelopmentHandler extends BaseToolHandler<
34
- ResetDevelopmentArgs,
35
- ResetDevelopmentResult
36
- > {
37
- protected async executeHandler(
38
- args: ResetDevelopmentArgs,
39
- context: ServerContext
40
- ): Promise<ResetDevelopmentResult> {
41
- // Validate required arguments
42
- validateRequiredArgs(args, ['confirm']);
43
-
44
- const { confirm, reason } = args;
45
-
46
- this.logger.debug('Processing reset_development request', {
47
- confirm,
48
- hasReason: !!reason,
49
- });
50
-
51
- // Validate parameters
52
- if (typeof confirm !== 'boolean') {
53
- throw new Error('confirm parameter must be a boolean');
54
- }
55
-
56
- if (!confirm) {
57
- throw new Error(
58
- 'Reset operation requires explicit confirmation. Set confirm parameter to true.'
59
- );
60
- }
61
-
62
- // Ensure state machine is loaded for current project
63
- this.ensureStateMachineForProject(context, context.projectPath);
64
-
65
- // Perform the reset
66
- const resetResult = await context.conversationManager.resetConversation(
67
- confirm,
68
- reason
69
- );
70
-
71
- // Transform to match our interface
72
- const result: ResetDevelopmentResult = {
73
- success: resetResult.success,
74
- resetItems: resetResult.resetItems,
75
- message: resetResult.message,
76
- };
77
-
78
- // Add conversationId for backward compatibility with tests
79
- (
80
- result as ResetDevelopmentResult & { conversationId: string }
81
- ).conversationId = resetResult.conversationId;
82
-
83
- this.logger.info('Reset development completed successfully', {
84
- resetItems: result.resetItems,
85
- reason,
86
- });
87
-
88
- return result;
89
- }
90
- }