@codemcp/workflows 4.10.1 → 4.10.2
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/.turbo/turbo-build.log +1 -1
- package/dist/components/beads/beads-instruction-generator.d.ts +3 -4
- package/dist/components/beads/beads-instruction-generator.d.ts.map +1 -1
- package/dist/components/beads/beads-instruction-generator.js +12 -7
- package/dist/components/beads/beads-instruction-generator.js.map +1 -1
- package/dist/components/beads/beads-task-backend-client.d.ts.map +1 -1
- package/dist/components/beads/beads-task-backend-client.js +1 -4
- package/dist/components/beads/beads-task-backend-client.js.map +1 -1
- package/dist/plugin-system/beads-plugin.d.ts +70 -0
- package/dist/plugin-system/beads-plugin.d.ts.map +1 -0
- package/dist/plugin-system/beads-plugin.js +459 -0
- package/dist/plugin-system/beads-plugin.js.map +1 -0
- package/dist/plugin-system/index.d.ts +9 -0
- package/dist/plugin-system/index.d.ts.map +1 -0
- package/dist/plugin-system/index.js +9 -0
- package/dist/plugin-system/index.js.map +1 -0
- package/dist/plugin-system/plugin-interfaces.d.ts +99 -0
- package/dist/plugin-system/plugin-interfaces.d.ts.map +1 -0
- package/dist/plugin-system/plugin-interfaces.js +9 -0
- package/dist/plugin-system/plugin-interfaces.js.map +1 -0
- package/dist/plugin-system/plugin-registry.d.ts +44 -0
- package/dist/plugin-system/plugin-registry.d.ts.map +1 -0
- package/dist/plugin-system/plugin-registry.js +132 -0
- package/dist/plugin-system/plugin-registry.js.map +1 -0
- package/dist/server-config.d.ts.map +1 -1
- package/dist/server-config.js +28 -8
- package/dist/server-config.js.map +1 -1
- package/dist/tool-handlers/conduct-review.d.ts.map +1 -1
- package/dist/tool-handlers/conduct-review.js +1 -2
- package/dist/tool-handlers/conduct-review.js.map +1 -1
- package/dist/tool-handlers/proceed-to-phase.d.ts +0 -5
- package/dist/tool-handlers/proceed-to-phase.d.ts.map +1 -1
- package/dist/tool-handlers/proceed-to-phase.js +15 -93
- package/dist/tool-handlers/proceed-to-phase.js.map +1 -1
- package/dist/tool-handlers/start-development.d.ts +0 -13
- package/dist/tool-handlers/start-development.d.ts.map +1 -1
- package/dist/tool-handlers/start-development.js +29 -124
- package/dist/tool-handlers/start-development.js.map +1 -1
- package/dist/tool-handlers/whats-next.d.ts.map +1 -1
- package/dist/tool-handlers/whats-next.js +1 -0
- package/dist/tool-handlers/whats-next.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/components/beads/beads-instruction-generator.ts +12 -12
- package/src/components/beads/beads-task-backend-client.ts +1 -4
- package/src/plugin-system/beads-plugin.ts +641 -0
- package/src/plugin-system/index.ts +20 -0
- package/src/plugin-system/plugin-interfaces.ts +154 -0
- package/src/plugin-system/plugin-registry.ts +190 -0
- package/src/server-config.ts +30 -8
- package/src/tool-handlers/conduct-review.ts +1 -2
- package/src/tool-handlers/proceed-to-phase.ts +19 -135
- package/src/tool-handlers/start-development.ts +35 -205
- package/src/tool-handlers/whats-next.ts +1 -0
- package/src/types.ts +2 -0
- package/test/e2e/beads-plugin-integration.test.ts +1609 -0
- package/test/e2e/plugin-system-integration.test.ts +1729 -0
- package/test/unit/beads-plugin-behavioral.test.ts +512 -0
- package/test/unit/beads-plugin.test.ts +94 -0
- package/test/unit/plugin-error-handling.test.ts +240 -0
- package/test/unit/proceed-to-phase-plugin-integration.test.ts +150 -0
- package/test/unit/server-config-plugin-registry.test.ts +81 -0
- package/test/unit/start-development-goal-extraction.test.ts +22 -16
- package/test/utils/test-helpers.ts +3 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/components/server-components-factory.d.ts +0 -39
- package/dist/components/server-components-factory.d.ts.map +0 -1
- package/dist/components/server-components-factory.js +0 -62
- package/dist/components/server-components-factory.js.map +0 -1
- package/src/components/server-components-factory.ts +0 -86
- package/test/e2e/component-substitution.test.ts +0 -208
- package/test/unit/beads-integration-filename.test.ts +0 -93
- package/test/unit/server-components-factory.test.ts +0 -279
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Beads Plugin Implementation
|
|
3
|
+
*
|
|
4
|
+
* Plugin that integrates beads task management system with responsible-vibe-mcp.
|
|
5
|
+
* Encapsulates ALL beads-specific functionality to maintain zero core application
|
|
6
|
+
* coupling as specified in plugin architecture design.
|
|
7
|
+
*
|
|
8
|
+
* Core Principle: This plugin must be completely self-contained and the core
|
|
9
|
+
* application must have ZERO knowledge of beads functionality.
|
|
10
|
+
*/
|
|
11
|
+
import { BeadsStateManager, BeadsIntegration, createLogger, PlanManager, } from '@codemcp/workflows-core';
|
|
12
|
+
import { BeadsTaskBackendClient } from '../components/beads/beads-task-backend-client.js';
|
|
13
|
+
const logger = createLogger('BeadsPlugin');
|
|
14
|
+
/**
|
|
15
|
+
* BeadsPlugin class implementing the IPlugin interface
|
|
16
|
+
*
|
|
17
|
+
* Activation: Only when process.env.TASK_BACKEND === 'beads'
|
|
18
|
+
* Priority: Sequence 100 (middle priority)
|
|
19
|
+
* Encapsulation: All beads functionality contained within this plugin
|
|
20
|
+
*/
|
|
21
|
+
export class BeadsPlugin {
|
|
22
|
+
projectPath;
|
|
23
|
+
beadsStateManager;
|
|
24
|
+
beadsTaskBackendClient;
|
|
25
|
+
planManager;
|
|
26
|
+
constructor(options) {
|
|
27
|
+
this.projectPath = options.projectPath;
|
|
28
|
+
// Initialize internal beads components
|
|
29
|
+
this.beadsStateManager = new BeadsStateManager(this.projectPath);
|
|
30
|
+
this.beadsTaskBackendClient = new BeadsTaskBackendClient(this.projectPath);
|
|
31
|
+
this.planManager = new PlanManager();
|
|
32
|
+
logger.debug('BeadsPlugin initialized', { projectPath: this.projectPath });
|
|
33
|
+
}
|
|
34
|
+
getName() {
|
|
35
|
+
return 'BeadsPlugin';
|
|
36
|
+
}
|
|
37
|
+
getSequence() {
|
|
38
|
+
return 100; // Middle priority as specified
|
|
39
|
+
}
|
|
40
|
+
isEnabled() {
|
|
41
|
+
const enabled = process.env.TASK_BACKEND === 'beads';
|
|
42
|
+
logger.debug('BeadsPlugin enablement check', {
|
|
43
|
+
TASK_BACKEND: process.env.TASK_BACKEND,
|
|
44
|
+
enabled,
|
|
45
|
+
});
|
|
46
|
+
return enabled;
|
|
47
|
+
}
|
|
48
|
+
getHooks() {
|
|
49
|
+
return {
|
|
50
|
+
afterStartDevelopment: this.handleAfterStartDevelopment.bind(this),
|
|
51
|
+
beforePhaseTransition: this.handleBeforePhaseTransition.bind(this),
|
|
52
|
+
afterPlanFileCreated: this.handleAfterPlanFileCreated.bind(this),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Handle beforePhaseTransition hook
|
|
57
|
+
* Replaces validateBeadsTaskCompletion() method from proceed-to-phase.ts
|
|
58
|
+
*/
|
|
59
|
+
async handleBeforePhaseTransition(context, currentPhase, targetPhase) {
|
|
60
|
+
logger.info('BeadsPlugin: Validating task completion before phase transition', {
|
|
61
|
+
conversationId: context.conversationId,
|
|
62
|
+
currentPhase,
|
|
63
|
+
targetPhase,
|
|
64
|
+
});
|
|
65
|
+
try {
|
|
66
|
+
await this.validateBeadsTaskCompletion(context.conversationId, currentPhase, targetPhase, context.projectPath);
|
|
67
|
+
logger.info('BeadsPlugin: Task validation passed, allowing phase transition', {
|
|
68
|
+
conversationId: context.conversationId,
|
|
69
|
+
currentPhase,
|
|
70
|
+
targetPhase,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
logger.info('BeadsPlugin: Task validation failed, blocking phase transition', {
|
|
75
|
+
conversationId: context.conversationId,
|
|
76
|
+
currentPhase,
|
|
77
|
+
targetPhase,
|
|
78
|
+
error: error instanceof Error ? error.message : String(error),
|
|
79
|
+
});
|
|
80
|
+
// Re-throw validation errors to block transitions
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Handle afterStartDevelopment hook
|
|
86
|
+
* Replaces setupBeadsIntegration() method from start-development.ts
|
|
87
|
+
* Implements graceful degradation: continues app operation even if beads operations fail
|
|
88
|
+
*/
|
|
89
|
+
async handleAfterStartDevelopment(context, args, _result) {
|
|
90
|
+
logger.info('BeadsPlugin: Setting up beads integration', {
|
|
91
|
+
conversationId: context.conversationId,
|
|
92
|
+
workflow: args.workflow,
|
|
93
|
+
projectPath: context.projectPath,
|
|
94
|
+
});
|
|
95
|
+
// Verify we have the required state machine information
|
|
96
|
+
if (!context.stateMachine) {
|
|
97
|
+
logger.error('BeadsPlugin: State machine not provided in plugin context');
|
|
98
|
+
logger.warn('BeadsPlugin: Beads integration disabled - continuing without beads');
|
|
99
|
+
return; // Graceful degradation: continue without beads
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
const beadsIntegration = new BeadsIntegration(context.projectPath);
|
|
103
|
+
const projectName = context.projectPath.split('/').pop() || 'Unknown Project';
|
|
104
|
+
// Extract goal from plan file if it exists and has meaningful content
|
|
105
|
+
let goalDescription;
|
|
106
|
+
try {
|
|
107
|
+
const planFileContent = await this.planManager.getPlanFileContent(context.planFilePath);
|
|
108
|
+
goalDescription = this.extractGoalFromPlan(planFileContent);
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
logger.warn('BeadsPlugin: Could not extract goal from plan file', {
|
|
112
|
+
error: error instanceof Error ? error.message : String(error),
|
|
113
|
+
planFilePath: context.planFilePath,
|
|
114
|
+
});
|
|
115
|
+
// Continue without goal - it's optional
|
|
116
|
+
}
|
|
117
|
+
// Extract plan filename for use in epic title
|
|
118
|
+
const planFilename = context.planFilePath.split('/').pop();
|
|
119
|
+
// Try to create project epic
|
|
120
|
+
let epicId;
|
|
121
|
+
try {
|
|
122
|
+
epicId = await beadsIntegration.createProjectEpic(projectName, args.workflow, goalDescription, planFilename);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
126
|
+
logger.warn('BeadsPlugin: Failed to create beads project epic - continuing without beads integration', {
|
|
127
|
+
error: errorMsg,
|
|
128
|
+
projectPath: context.projectPath,
|
|
129
|
+
});
|
|
130
|
+
// Graceful degradation: continue app operation without beads
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// Try to create phase tasks
|
|
134
|
+
let phaseTasks;
|
|
135
|
+
try {
|
|
136
|
+
phaseTasks = await beadsIntegration.createPhaseTasks(epicId, context.stateMachine.states, args.workflow);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
140
|
+
logger.warn('BeadsPlugin: Failed to create beads phase tasks - continuing without phase tracking', {
|
|
141
|
+
error: errorMsg,
|
|
142
|
+
epicId,
|
|
143
|
+
});
|
|
144
|
+
// Graceful degradation: continue without phase tracking
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
// Try to create sequential dependencies between phases
|
|
148
|
+
try {
|
|
149
|
+
await beadsIntegration.createPhaseDependencies(phaseTasks);
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
153
|
+
logger.warn('BeadsPlugin: Failed to create phase dependencies - continuing without dependencies', {
|
|
154
|
+
error: errorMsg,
|
|
155
|
+
phaseCount: phaseTasks.length,
|
|
156
|
+
});
|
|
157
|
+
// Graceful degradation: continue without dependencies
|
|
158
|
+
}
|
|
159
|
+
// Try to update plan file with phase task IDs
|
|
160
|
+
try {
|
|
161
|
+
await this.updatePlanFileWithPhaseTaskIds(context.planFilePath, phaseTasks);
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
165
|
+
logger.warn('BeadsPlugin: Failed to update plan file with beads task IDs - continuing without plan file updates', {
|
|
166
|
+
error: errorMsg,
|
|
167
|
+
planFilePath: context.planFilePath,
|
|
168
|
+
});
|
|
169
|
+
// Graceful degradation: continue without plan file updates
|
|
170
|
+
}
|
|
171
|
+
// Try to create beads state for this conversation
|
|
172
|
+
try {
|
|
173
|
+
await this.beadsStateManager.createState(context.conversationId, epicId, phaseTasks);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
177
|
+
logger.warn('BeadsPlugin: Failed to create beads state - continuing without state persistence', {
|
|
178
|
+
error: errorMsg,
|
|
179
|
+
conversationId: context.conversationId,
|
|
180
|
+
});
|
|
181
|
+
// Graceful degradation: continue without state persistence
|
|
182
|
+
}
|
|
183
|
+
logger.info('BeadsPlugin: Beads integration setup complete', {
|
|
184
|
+
conversationId: context.conversationId,
|
|
185
|
+
epicId,
|
|
186
|
+
phaseCount: phaseTasks?.length || 0,
|
|
187
|
+
planFilePath: context.planFilePath,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
// Catch-all for unexpected errors: log and continue
|
|
192
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
193
|
+
logger.warn('BeadsPlugin: Unexpected error during beads integration setup - continuing application without beads', {
|
|
194
|
+
error: errorMsg,
|
|
195
|
+
conversationId: context.conversationId,
|
|
196
|
+
});
|
|
197
|
+
// Graceful degradation: never crash the app due to beads errors
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Handle afterPlanFileCreated hook
|
|
202
|
+
* Enhances the plan file with beads-specific templates and placeholders
|
|
203
|
+
*
|
|
204
|
+
* This hook is called after a plan file is created. For beads integration,
|
|
205
|
+
* it ensures the plan file has TBD placeholders for phase task IDs that
|
|
206
|
+
* will be filled in later by afterStartDevelopment.
|
|
207
|
+
*
|
|
208
|
+
* Note: Task IDs themselves are created in afterStartDevelopment, not here.
|
|
209
|
+
* This hook ensures the plan has the proper structure to receive them.
|
|
210
|
+
*/
|
|
211
|
+
async handleAfterPlanFileCreated(_context, planFilePath, content) {
|
|
212
|
+
logger.debug('BeadsPlugin: afterPlanFileCreated hook invoked', {
|
|
213
|
+
planFilePath,
|
|
214
|
+
contentLength: content.length,
|
|
215
|
+
});
|
|
216
|
+
// The plan file is already created with TBD placeholders by BeadsPlanManager
|
|
217
|
+
// No additional modifications needed at this stage.
|
|
218
|
+
// The beads task IDs will be added by afterStartDevelopment hook
|
|
219
|
+
// which calls updatePlanFileWithPhaseTaskIds.
|
|
220
|
+
//
|
|
221
|
+
// This hook currently returns content unchanged, but could be extended in the
|
|
222
|
+
// future for additional beads-specific plan enhancements such as:
|
|
223
|
+
// - Adding beads CLI usage instructions
|
|
224
|
+
// - Adding task templates
|
|
225
|
+
// - Adding workflow guidance
|
|
226
|
+
return content;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Validate beads task completion before phase transition
|
|
230
|
+
* Implements graceful error handling: logs errors but continues on non-validation failures
|
|
231
|
+
*/
|
|
232
|
+
async validateBeadsTaskCompletion(conversationId, currentPhase, targetPhase, projectPath) {
|
|
233
|
+
try {
|
|
234
|
+
// Check if beads backend client is available
|
|
235
|
+
let isAvailable = false;
|
|
236
|
+
try {
|
|
237
|
+
isAvailable = await this.beadsTaskBackendClient.isAvailable();
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
241
|
+
logger.warn('BeadsPlugin: Failed to check beads availability', {
|
|
242
|
+
error: errorMsg,
|
|
243
|
+
conversationId,
|
|
244
|
+
});
|
|
245
|
+
// Graceful degradation: assume beads is unavailable and continue
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
if (!isAvailable) {
|
|
249
|
+
// Not in beads mode or beads not available, skip validation
|
|
250
|
+
logger.debug('BeadsPlugin: Skipping beads task validation - beads CLI not available', {
|
|
251
|
+
conversationId,
|
|
252
|
+
currentPhase,
|
|
253
|
+
targetPhase,
|
|
254
|
+
});
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
// Get beads state for this conversation
|
|
258
|
+
let currentPhaseTaskId = null;
|
|
259
|
+
try {
|
|
260
|
+
currentPhaseTaskId = await this.beadsStateManager.getPhaseTaskId(conversationId, currentPhase);
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
264
|
+
logger.warn('BeadsPlugin: Failed to get beads phase task ID', {
|
|
265
|
+
error: errorMsg,
|
|
266
|
+
conversationId,
|
|
267
|
+
currentPhase,
|
|
268
|
+
});
|
|
269
|
+
// Graceful degradation: continue without validation
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
if (!currentPhaseTaskId) {
|
|
273
|
+
// No beads state found for this conversation - fallback to graceful handling
|
|
274
|
+
logger.debug('BeadsPlugin: No beads phase task ID found for current phase', {
|
|
275
|
+
conversationId,
|
|
276
|
+
currentPhase,
|
|
277
|
+
targetPhase,
|
|
278
|
+
projectPath,
|
|
279
|
+
});
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
logger.debug('BeadsPlugin: Checking for incomplete beads tasks using task backend client', {
|
|
283
|
+
conversationId,
|
|
284
|
+
currentPhase,
|
|
285
|
+
currentPhaseTaskId,
|
|
286
|
+
});
|
|
287
|
+
// Use task backend client to validate task completion
|
|
288
|
+
let validationResult;
|
|
289
|
+
try {
|
|
290
|
+
validationResult =
|
|
291
|
+
await this.beadsTaskBackendClient.validateTasksCompleted(currentPhaseTaskId);
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
295
|
+
logger.warn('BeadsPlugin: Failed to validate tasks with beads backend', {
|
|
296
|
+
error: errorMsg,
|
|
297
|
+
conversationId,
|
|
298
|
+
currentPhaseTaskId,
|
|
299
|
+
});
|
|
300
|
+
// Graceful degradation: allow transition if validation fails
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
if (!validationResult.valid) {
|
|
304
|
+
// Get the incomplete tasks from the validation result
|
|
305
|
+
const incompleteTasks = validationResult.openTasks || [];
|
|
306
|
+
// Create detailed error message with incomplete tasks
|
|
307
|
+
const taskDetails = incompleteTasks
|
|
308
|
+
.map(task => ` • ${task.id} - ${task.title || 'Untitled task'}`)
|
|
309
|
+
.join('\n');
|
|
310
|
+
const errorMessage = `Cannot proceed to ${targetPhase} - ${incompleteTasks.length} incomplete task(s) in current phase "${currentPhase}":
|
|
311
|
+
|
|
312
|
+
${taskDetails}
|
|
313
|
+
|
|
314
|
+
To proceed, check the in-progress-tasks using:
|
|
315
|
+
|
|
316
|
+
bd list --parent ${currentPhaseTaskId} --status open
|
|
317
|
+
|
|
318
|
+
You can also defer tasks if they're no longer needed:
|
|
319
|
+
bd defer <task-id> --until tomorrow`;
|
|
320
|
+
logger.info('BeadsPlugin: Blocking phase transition due to incomplete beads tasks', {
|
|
321
|
+
conversationId,
|
|
322
|
+
currentPhase,
|
|
323
|
+
targetPhase,
|
|
324
|
+
currentPhaseTaskId,
|
|
325
|
+
incompleteTaskCount: incompleteTasks.length,
|
|
326
|
+
incompleteTaskIds: incompleteTasks.map(t => t.id),
|
|
327
|
+
});
|
|
328
|
+
throw new Error(errorMessage);
|
|
329
|
+
}
|
|
330
|
+
logger.info('BeadsPlugin: All beads tasks completed in current phase, allowing transition', {
|
|
331
|
+
conversationId,
|
|
332
|
+
currentPhase,
|
|
333
|
+
targetPhase,
|
|
334
|
+
currentPhaseTaskId,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
// Re-throw validation errors (incomplete tasks)
|
|
339
|
+
if (error instanceof Error &&
|
|
340
|
+
error.message.includes('Cannot proceed to')) {
|
|
341
|
+
throw error;
|
|
342
|
+
}
|
|
343
|
+
// Log other errors but allow transition (graceful degradation)
|
|
344
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
345
|
+
logger.warn('BeadsPlugin: Beads task validation failed, allowing transition to proceed', {
|
|
346
|
+
error: errorMessage,
|
|
347
|
+
conversationId,
|
|
348
|
+
currentPhase,
|
|
349
|
+
targetPhase,
|
|
350
|
+
projectPath,
|
|
351
|
+
});
|
|
352
|
+
// Graceful degradation: continue without beads state validation
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Extract Goal section content from plan file
|
|
357
|
+
* Returns the goal content if it exists and is meaningful, otherwise undefined
|
|
358
|
+
*/
|
|
359
|
+
extractGoalFromPlan(planContent) {
|
|
360
|
+
if (!planContent || typeof planContent !== 'string') {
|
|
361
|
+
return undefined;
|
|
362
|
+
}
|
|
363
|
+
// Split content into lines for more reliable parsing
|
|
364
|
+
const lines = planContent.split('\n');
|
|
365
|
+
const goalIndex = lines.findIndex(line => line.trim() === '## Goal');
|
|
366
|
+
if (goalIndex === -1) {
|
|
367
|
+
return undefined;
|
|
368
|
+
}
|
|
369
|
+
// Find the next section (## anything) after the Goal section
|
|
370
|
+
const nextSectionIndex = lines.findIndex((line, index) => index > goalIndex && line.trim().startsWith('## '));
|
|
371
|
+
// Extract content between Goal and next section (or end of content)
|
|
372
|
+
const contentLines = nextSectionIndex === -1
|
|
373
|
+
? lines.slice(goalIndex + 1)
|
|
374
|
+
: lines.slice(goalIndex + 1, nextSectionIndex);
|
|
375
|
+
const goalContent = contentLines.join('\n').trim();
|
|
376
|
+
// Check if the goal content is meaningful (not just a placeholder or comment)
|
|
377
|
+
const meaninglessPatterns = [
|
|
378
|
+
/^\*.*\*$/, // Enclosed in asterisks like "*Define what you're building...*"
|
|
379
|
+
/^To be defined/i,
|
|
380
|
+
/^TBD$/i,
|
|
381
|
+
/^TODO/i,
|
|
382
|
+
/^Define what you're building/i,
|
|
383
|
+
/^This will be updated/i,
|
|
384
|
+
];
|
|
385
|
+
const isMeaningless = meaninglessPatterns.some(pattern => pattern.test(goalContent));
|
|
386
|
+
if (isMeaningless || goalContent.length < 10) {
|
|
387
|
+
return undefined;
|
|
388
|
+
}
|
|
389
|
+
return goalContent;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Update plan file to include beads phase task IDs in comments
|
|
393
|
+
* Implements graceful degradation: logs errors but continues app operation if update fails
|
|
394
|
+
*/
|
|
395
|
+
async updatePlanFileWithPhaseTaskIds(planFilePath, phaseTasks) {
|
|
396
|
+
try {
|
|
397
|
+
const { readFile, writeFile } = await import('node:fs/promises');
|
|
398
|
+
// Try to read the plan file
|
|
399
|
+
let content;
|
|
400
|
+
try {
|
|
401
|
+
content = await readFile(planFilePath, 'utf-8');
|
|
402
|
+
}
|
|
403
|
+
catch (error) {
|
|
404
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
405
|
+
logger.warn('BeadsPlugin: Failed to read plan file for update', {
|
|
406
|
+
error: errorMsg,
|
|
407
|
+
planFilePath,
|
|
408
|
+
});
|
|
409
|
+
// Graceful degradation: continue without updating plan file
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
// Replace TBD placeholders with actual task IDs
|
|
413
|
+
for (const phaseTask of phaseTasks) {
|
|
414
|
+
const phaseHeader = `## ${phaseTask.phaseName}`;
|
|
415
|
+
const placeholderPattern = new RegExp(`(${phaseHeader.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*\n)<!-- beads-phase-id: TBD -->`, 'g');
|
|
416
|
+
content = content.replace(placeholderPattern, `$1<!-- beads-phase-id: ${phaseTask.taskId} -->`);
|
|
417
|
+
}
|
|
418
|
+
// Validate that all TBD placeholders were replaced
|
|
419
|
+
const remainingTBDs = content.match(/<!-- beads-phase-id: TBD -->/g);
|
|
420
|
+
if (remainingTBDs && remainingTBDs.length > 0) {
|
|
421
|
+
logger.warn('BeadsPlugin: Failed to replace all TBD placeholders in plan file', {
|
|
422
|
+
planFilePath,
|
|
423
|
+
unreplacedCount: remainingTBDs.length,
|
|
424
|
+
reason: 'Phase names in plan file may not match workflow phases or beads task creation may have failed for some phases',
|
|
425
|
+
});
|
|
426
|
+
// Graceful degradation: continue without full update
|
|
427
|
+
// But still try to write what we have
|
|
428
|
+
}
|
|
429
|
+
// Try to write the updated plan file
|
|
430
|
+
try {
|
|
431
|
+
await writeFile(planFilePath, content, 'utf-8');
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
435
|
+
logger.warn('BeadsPlugin: Failed to write updated plan file', {
|
|
436
|
+
error: errorMsg,
|
|
437
|
+
planFilePath,
|
|
438
|
+
});
|
|
439
|
+
// Graceful degradation: continue without writing to plan file
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
logger.info('BeadsPlugin: Successfully updated plan file with beads phase task IDs', {
|
|
443
|
+
planFilePath,
|
|
444
|
+
phaseTaskCount: phaseTasks.length,
|
|
445
|
+
replacedTasks: phaseTasks.map(task => `${task.phaseName}: ${task.taskId}`),
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
catch (error) {
|
|
449
|
+
// Catch-all for unexpected errors
|
|
450
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
451
|
+
logger.warn('BeadsPlugin: Unexpected error while updating plan file with phase task IDs', {
|
|
452
|
+
error: errorMsg,
|
|
453
|
+
planFilePath,
|
|
454
|
+
});
|
|
455
|
+
// Graceful degradation: never crash the app due to plan file updates
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
//# sourceMappingURL=beads-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beads-plugin.js","sourceRoot":"","sources":["../../src/plugin-system/beads-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin system exports
|
|
3
|
+
*
|
|
4
|
+
* This module provides the core plugin system for extending responsible-vibe-mcp
|
|
5
|
+
* functionality without if-statements in the core application.
|
|
6
|
+
*/
|
|
7
|
+
export type { IPlugin, IPluginRegistry, PluginHooks, PluginHookContext, StartDevelopmentArgs, StartDevelopmentResult, GeneratedInstructions, } from './plugin-interfaces.js';
|
|
8
|
+
export { PluginRegistry } from './plugin-registry.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin-system/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,OAAO,EACP,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin system exports
|
|
3
|
+
*
|
|
4
|
+
* This module provides the core plugin system for extending responsible-vibe-mcp
|
|
5
|
+
* functionality without if-statements in the core application.
|
|
6
|
+
*/
|
|
7
|
+
// Plugin registry implementation
|
|
8
|
+
export { PluginRegistry } from './plugin-registry.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugin-system/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,iCAAiC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin system interfaces for extending the responsible-vibe-mcp server
|
|
3
|
+
*
|
|
4
|
+
* Core Principle: Plugins receive only read-only context data and cannot
|
|
5
|
+
* directly manipulate core server components. They extend behavior through
|
|
6
|
+
* semantic lifecycle hooks only.
|
|
7
|
+
*/
|
|
8
|
+
import type { YamlState } from '@codemcp/workflows-core';
|
|
9
|
+
/**
|
|
10
|
+
* Plugin interface - all plugins must implement this
|
|
11
|
+
*/
|
|
12
|
+
export interface IPlugin {
|
|
13
|
+
/** Unique plugin name */
|
|
14
|
+
getName(): string;
|
|
15
|
+
/** Execution sequence (lower numbers execute first) */
|
|
16
|
+
getSequence(): number;
|
|
17
|
+
/** Whether plugin is enabled (typically based on environment) */
|
|
18
|
+
isEnabled(): boolean;
|
|
19
|
+
/** Lifecycle hooks this plugin provides */
|
|
20
|
+
getHooks(): PluginHooks;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Lifecycle hooks that plugins can implement
|
|
24
|
+
* All hooks receive standardized PluginHookContext as first parameter
|
|
25
|
+
*/
|
|
26
|
+
export interface PluginHooks {
|
|
27
|
+
/** Called before development workflow starts */
|
|
28
|
+
beforeStartDevelopment?: (context: PluginHookContext, args: StartDevelopmentArgs) => Promise<void>;
|
|
29
|
+
/** Called after development workflow has started */
|
|
30
|
+
afterStartDevelopment?: (context: PluginHookContext, args: StartDevelopmentArgs, result: StartDevelopmentResult) => Promise<void>;
|
|
31
|
+
/** Called after plan file is created - can modify content */
|
|
32
|
+
afterPlanFileCreated?: (context: PluginHookContext, planFilePath: string, content: string) => Promise<string>;
|
|
33
|
+
/** Called before phase transition (can block by throwing) */
|
|
34
|
+
beforePhaseTransition?: (context: PluginHookContext, currentPhase: string, targetPhase: string) => Promise<void>;
|
|
35
|
+
/** Called after instructions are generated - can modify them */
|
|
36
|
+
afterInstructionsGenerated?: (context: PluginHookContext, instructions: GeneratedInstructions) => Promise<GeneratedInstructions>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Standardized context provided to all plugin hooks
|
|
40
|
+
* Contains ONLY read-only data - no server components
|
|
41
|
+
*/
|
|
42
|
+
export interface PluginHookContext {
|
|
43
|
+
/** Current conversation ID */
|
|
44
|
+
conversationId: string;
|
|
45
|
+
/** Path to the plan file */
|
|
46
|
+
planFilePath: string;
|
|
47
|
+
/** Current development phase */
|
|
48
|
+
currentPhase: string;
|
|
49
|
+
/** Active workflow name */
|
|
50
|
+
workflow: string;
|
|
51
|
+
/** Project directory path */
|
|
52
|
+
projectPath: string;
|
|
53
|
+
/** Git branch name */
|
|
54
|
+
gitBranch: string;
|
|
55
|
+
/** Target phase (only available in phase transitions) */
|
|
56
|
+
targetPhase?: string;
|
|
57
|
+
/** Workflow state machine definition (read-only) - available in afterStartDevelopment */
|
|
58
|
+
stateMachine?: {
|
|
59
|
+
readonly name: string;
|
|
60
|
+
readonly description: string;
|
|
61
|
+
readonly initial_state: string;
|
|
62
|
+
readonly states: Record<string, YamlState>;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Plugin registry interface for managing and executing plugins
|
|
67
|
+
*/
|
|
68
|
+
export interface IPluginRegistry {
|
|
69
|
+
/** Register a plugin */
|
|
70
|
+
registerPlugin(plugin: IPlugin): void;
|
|
71
|
+
/** Get all enabled plugins sorted by sequence */
|
|
72
|
+
getEnabledPlugins(): IPlugin[];
|
|
73
|
+
/** Execute a specific hook on all plugins that implement it */
|
|
74
|
+
executeHook<T extends keyof PluginHooks>(hookName: T, ...args: Parameters<NonNullable<PluginHooks[T]>>): Promise<unknown>;
|
|
75
|
+
/** Check if any plugin has a specific hook */
|
|
76
|
+
hasHook(hookName: keyof PluginHooks): boolean;
|
|
77
|
+
/** Get names of all registered plugins */
|
|
78
|
+
getPluginNames(): string[];
|
|
79
|
+
/** Clear all plugins (mainly for testing) */
|
|
80
|
+
clear(): void;
|
|
81
|
+
}
|
|
82
|
+
export interface StartDevelopmentArgs {
|
|
83
|
+
workflow: string;
|
|
84
|
+
commit_behaviour: string;
|
|
85
|
+
require_reviews?: boolean;
|
|
86
|
+
project_path?: string;
|
|
87
|
+
}
|
|
88
|
+
export interface StartDevelopmentResult {
|
|
89
|
+
conversationId: string;
|
|
90
|
+
planFilePath: string;
|
|
91
|
+
phase: string;
|
|
92
|
+
workflow: string;
|
|
93
|
+
}
|
|
94
|
+
export interface GeneratedInstructions {
|
|
95
|
+
instructions: string;
|
|
96
|
+
planFilePath: string;
|
|
97
|
+
phase: string;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=plugin-interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-interfaces.d.ts","sourceRoot":"","sources":["../../src/plugin-system/plugin-interfaces.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin system interfaces for extending the responsible-vibe-mcp server
|
|
3
|
+
*
|
|
4
|
+
* Core Principle: Plugins receive only read-only context data and cannot
|
|
5
|
+
* directly manipulate core server components. They extend behavior through
|
|
6
|
+
* semantic lifecycle hooks only.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=plugin-interfaces.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-interfaces.js","sourceRoot":"","sources":["../../src/plugin-system/plugin-interfaces.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|