@codemcp/workflows 5.0.1 → 5.1.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.
- package/SKILL.md +23 -0
- package/package.json +6 -2
- package/.prettierignore +0 -2
- package/.turbo/turbo-build.log +0 -4
- package/.vibe/conversation-state.sqlite +0 -0
- package/src/components/beads/beads-instruction-generator.ts +0 -230
- package/src/components/beads/beads-plan-manager.ts +0 -333
- package/src/components/beads/beads-task-backend-client.ts +0 -229
- package/src/index.ts +0 -93
- package/src/notification-service.ts +0 -23
- package/src/plugin-system/beads-plugin.ts +0 -649
- package/src/plugin-system/commit-plugin.ts +0 -252
- package/src/plugin-system/index.ts +0 -20
- package/src/plugin-system/plugin-interfaces.ts +0 -153
- package/src/plugin-system/plugin-registry.ts +0 -190
- package/src/resource-handlers/conversation-state.ts +0 -55
- package/src/resource-handlers/development-plan.ts +0 -48
- package/src/resource-handlers/index.ts +0 -73
- package/src/resource-handlers/system-prompt.ts +0 -55
- package/src/resource-handlers/workflow-resource.ts +0 -132
- package/src/response-renderer.ts +0 -116
- package/src/server-config.ts +0 -760
- package/src/server-helpers.ts +0 -245
- package/src/server-implementation.ts +0 -277
- package/src/server.ts +0 -9
- package/src/tool-handlers/base-tool-handler.ts +0 -151
- package/src/tool-handlers/conduct-review.ts +0 -190
- package/src/tool-handlers/get-tool-info.ts +0 -273
- package/src/tool-handlers/index.ts +0 -115
- package/src/tool-handlers/list-workflows.ts +0 -78
- package/src/tool-handlers/no-idea.ts +0 -47
- package/src/tool-handlers/proceed-to-phase.ts +0 -296
- package/src/tool-handlers/reset-development.ts +0 -90
- package/src/tool-handlers/resume-workflow.ts +0 -378
- package/src/tool-handlers/setup-project-docs.ts +0 -232
- package/src/tool-handlers/start-development.ts +0 -746
- package/src/tool-handlers/whats-next.ts +0 -246
- package/src/types.ts +0 -135
- package/src/version-info.ts +0 -213
- package/test/e2e/beads-plugin-integration.test.ts +0 -1623
- package/test/e2e/commit-plugin-integration.test.ts +0 -222
- package/test/e2e/core-functionality.test.ts +0 -167
- package/test/e2e/git-branch-detection.test.ts +0 -351
- package/test/e2e/mcp-contract.test.ts +0 -509
- package/test/e2e/plan-management.test.ts +0 -334
- package/test/e2e/plugin-system-integration.test.ts +0 -1410
- package/test/e2e/state-management.test.ts +0 -387
- package/test/e2e/workflow-integration.test.ts +0 -498
- package/test/unit/beads-instruction-generator.test.ts +0 -979
- package/test/unit/beads-phase-task-id-integration.test.ts +0 -535
- package/test/unit/beads-plugin-behavioral.test.ts +0 -545
- package/test/unit/beads-plugin.test.ts +0 -117
- package/test/unit/commit-plugin.test.ts +0 -196
- package/test/unit/conduct-review.test.ts +0 -151
- package/test/unit/conversation-not-found-error.test.ts +0 -120
- package/test/unit/plugin-error-handling.test.ts +0 -240
- package/test/unit/proceed-to-phase-plugin-integration.test.ts +0 -150
- package/test/unit/reset-functionality.test.ts +0 -72
- package/test/unit/resume-workflow.test.ts +0 -193
- package/test/unit/server-config-plugin-registry.test.ts +0 -99
- package/test/unit/server-tools.test.ts +0 -310
- package/test/unit/setup-project-docs-handler.test.ts +0 -268
- package/test/unit/start-development-artifact-detection.test.ts +0 -387
- package/test/unit/start-development-gitignore.test.ts +0 -178
- package/test/unit/start-development-goal-extraction.test.ts +0 -226
- package/test/unit/system-prompt-resource.test.ts +0 -102
- package/test/unit/tool-handlers/no-idea.test.ts +0 -40
- package/test/utils/e2e-test-setup.ts +0 -451
- package/test/utils/run-server-in-dir.sh +0 -27
- package/test/utils/temp-files.ts +0 -320
- package/test/utils/test-access.ts +0 -79
- package/test/utils/test-helpers.ts +0 -288
- package/test/utils/test-setup.ts +0 -77
- package/tsconfig.build.json +0 -10
- package/tsconfig.build.tsbuildinfo +0 -1
- package/tsconfig.json +0 -12
- 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
|
-
}
|