claude-flow-novice 1.5.17 → 1.5.18
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/.claude-flow-novice/dist/config/hooks/post-edit-pipeline.js +1807 -0
- package/.claude-flow-novice/dist/src/hooks/communication-integrated-post-edit.js +673 -0
- package/.claude-flow-novice/dist/src/hooks/enhanced/experience-adaptation-hooks.js +347 -0
- package/.claude-flow-novice/dist/src/hooks/enhanced/personalization-hooks.js +118 -0
- package/.claude-flow-novice/dist/src/hooks/enhanced-post-edit-pipeline.js +2044 -0
- package/.claude-flow-novice/dist/src/hooks/filter-integration.js +542 -0
- package/.claude-flow-novice/dist/src/hooks/guidance-hooks.js +629 -0
- package/.claude-flow-novice/dist/src/hooks/index.ts +239 -0
- package/.claude-flow-novice/dist/src/hooks/managers/enhanced-hook-manager.js +200 -0
- package/.claude-flow-novice/dist/src/hooks/resilient-hook-system.js +812 -0
- package/config/hooks/post-edit-pipeline.js +30 -0
- package/package.json +2 -1
- package/src/cli/simple-commands/init/templates/CLAUDE.md +38 -6
- package/src/hooks/communication-integrated-post-edit.js +673 -0
- package/src/hooks/enhanced/experience-adaptation-hooks.js +347 -0
- package/src/hooks/enhanced/personalization-hooks.js +118 -0
- package/src/hooks/enhanced-hooks-cli.js +168 -0
- package/src/hooks/enhanced-post-edit-pipeline.js +2044 -0
- package/src/hooks/filter-integration.js +542 -0
- package/src/hooks/guidance-hooks.js +629 -0
- package/src/hooks/index.ts +239 -0
- package/src/hooks/managers/enhanced-hook-manager.js +200 -0
- package/src/hooks/resilient-hook-system.js +812 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Experience-Level Hook Adaptation - Minimal Implementation
|
|
3
|
+
*
|
|
4
|
+
* Adapts hook verbosity and behavior based on user experience level.
|
|
5
|
+
* Following TDD: tests were written first, now implementing to make them green.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
class ExperienceAdaptationHooks {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.satisfactionData = new Map();
|
|
11
|
+
this.userCorrections = new Map();
|
|
12
|
+
this.performanceHistory = new Map();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Adapt hooks based on user experience level
|
|
17
|
+
*/
|
|
18
|
+
async adaptHooksForUser(user) {
|
|
19
|
+
const { experienceLevel = 'intermediate', userId } = user;
|
|
20
|
+
|
|
21
|
+
// Calculate dynamic level if performance history exists
|
|
22
|
+
let effectiveLevel = experienceLevel;
|
|
23
|
+
if (userId && this.performanceHistory.has(userId)) {
|
|
24
|
+
effectiveLevel = await this.calculateDynamicLevel(user);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Apply user corrections if they exist
|
|
28
|
+
if (userId && this.userCorrections.has(userId)) {
|
|
29
|
+
const corrections = this.userCorrections.get(userId);
|
|
30
|
+
return {
|
|
31
|
+
...this.getBaseHooksForLevel(effectiveLevel),
|
|
32
|
+
...corrections.userPreference,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return this.getBaseHooksForLevel(effectiveLevel);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get base hook configuration for experience level
|
|
41
|
+
*/
|
|
42
|
+
getBaseHooksForLevel(level) {
|
|
43
|
+
switch (level) {
|
|
44
|
+
case 'novice':
|
|
45
|
+
return {
|
|
46
|
+
verbosity: 'detailed',
|
|
47
|
+
showSteps: true,
|
|
48
|
+
provideTips: true,
|
|
49
|
+
explainCommands: true,
|
|
50
|
+
showExamples: true,
|
|
51
|
+
confirmActions: true,
|
|
52
|
+
experienceLevel: 'novice',
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
case 'expert':
|
|
56
|
+
return {
|
|
57
|
+
verbosity: 'minimal',
|
|
58
|
+
showSteps: false,
|
|
59
|
+
provideTips: false,
|
|
60
|
+
explainCommands: false,
|
|
61
|
+
showExamples: false,
|
|
62
|
+
confirmActions: false,
|
|
63
|
+
experienceLevel: 'expert',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
case 'intermediate':
|
|
67
|
+
default:
|
|
68
|
+
return {
|
|
69
|
+
verbosity: 'balanced',
|
|
70
|
+
showSteps: false,
|
|
71
|
+
provideTips: true,
|
|
72
|
+
explainCommands: false,
|
|
73
|
+
showExamples: false,
|
|
74
|
+
confirmActions: true,
|
|
75
|
+
experienceLevel: 'intermediate',
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Execute pre-task hook with experience-level adaptation
|
|
82
|
+
*/
|
|
83
|
+
async executePreTaskHook({ task, user }) {
|
|
84
|
+
const hooks = await this.adaptHooksForUser(user);
|
|
85
|
+
const { experienceLevel } = user;
|
|
86
|
+
|
|
87
|
+
switch (experienceLevel) {
|
|
88
|
+
case 'novice':
|
|
89
|
+
return {
|
|
90
|
+
content: `Starting task: ${task}. Here's a detailed explanation of the steps we'll follow, including step-by-step guidance and helpful examples to ensure your success.`,
|
|
91
|
+
examples: [`Example for ${task}`, 'Code snippet example'],
|
|
92
|
+
tips: ['Remember to test your changes', 'Use version control for safety'],
|
|
93
|
+
warnings: ['Be careful with file operations'],
|
|
94
|
+
format: 'detailed',
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
case 'expert':
|
|
98
|
+
return {
|
|
99
|
+
content: `Task: ${task}`,
|
|
100
|
+
format: 'summary',
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
case 'intermediate':
|
|
104
|
+
default:
|
|
105
|
+
return {
|
|
106
|
+
content: `Task: ${task}. Here are some contextual tips to help you succeed efficiently with this implementation process.`,
|
|
107
|
+
tips: [`Consider best practices for ${task}`],
|
|
108
|
+
format: 'balanced',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get task guidance based on experience level
|
|
115
|
+
*/
|
|
116
|
+
async getTaskGuidance({ task, user }) {
|
|
117
|
+
const { experienceLevel } = user;
|
|
118
|
+
|
|
119
|
+
if (experienceLevel === 'novice') {
|
|
120
|
+
return {
|
|
121
|
+
steps: [
|
|
122
|
+
{
|
|
123
|
+
step: 1,
|
|
124
|
+
description: `Plan your approach to ${task}`,
|
|
125
|
+
example: 'Create a rough outline of what needs to be done',
|
|
126
|
+
tips: ['Break down complex tasks', 'Start with the simplest part'],
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
step: 2,
|
|
130
|
+
description: 'Implement the core functionality',
|
|
131
|
+
example: 'Write the main logic for your feature',
|
|
132
|
+
tips: ['Test as you go', 'Keep functions small'],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
step: 3,
|
|
136
|
+
description: 'Add error handling',
|
|
137
|
+
example: 'try/catch blocks for potential failures',
|
|
138
|
+
tips: ['Consider edge cases', 'Provide helpful error messages'],
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
step: 4,
|
|
142
|
+
description: 'Write tests',
|
|
143
|
+
example: 'Unit tests for your new functionality',
|
|
144
|
+
tips: ['Test both success and failure cases'],
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return { steps: [] };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Determine if action confirmation is needed
|
|
155
|
+
*/
|
|
156
|
+
async shouldConfirmAction({ action, user, context = {} }) {
|
|
157
|
+
const { experienceLevel } = user;
|
|
158
|
+
|
|
159
|
+
// Critical operations always require confirmation
|
|
160
|
+
const criticalActions = ['rm -rf', 'delete database', 'drop table'];
|
|
161
|
+
if (criticalActions.some((critical) => action.includes(critical))) {
|
|
162
|
+
return {
|
|
163
|
+
required: true,
|
|
164
|
+
message: 'WARNING: This is a destructive operation that cannot be undone.',
|
|
165
|
+
severity: 'critical',
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// High-risk operations for novices
|
|
170
|
+
const highRiskActions = ['delete file', 'modify config', 'deploy'];
|
|
171
|
+
if (experienceLevel === 'novice' && highRiskActions.some((risk) => action.includes(risk))) {
|
|
172
|
+
return {
|
|
173
|
+
required: true,
|
|
174
|
+
message: 'WARNING: This action will modify important files. Are you sure?',
|
|
175
|
+
severity: 'high',
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Experts skip routine confirmations
|
|
180
|
+
if (experienceLevel === 'expert') {
|
|
181
|
+
const routineActions = ['create file', 'edit file', 'run test'];
|
|
182
|
+
if (routineActions.some((routine) => action.includes(routine))) {
|
|
183
|
+
return { required: false };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Default confirmation for intermediate and safety
|
|
188
|
+
return {
|
|
189
|
+
required: experienceLevel !== 'expert',
|
|
190
|
+
severity: 'medium',
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Calculate dynamic experience level based on performance
|
|
196
|
+
*/
|
|
197
|
+
async calculateDynamicLevel(user) {
|
|
198
|
+
const { userId, experienceLevel, performanceHistory = [] } = user;
|
|
199
|
+
|
|
200
|
+
if (!performanceHistory.length) {
|
|
201
|
+
return experienceLevel;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const successRate =
|
|
205
|
+
performanceHistory.filter((h) => h.success).length / performanceHistory.length;
|
|
206
|
+
const avgAttempts =
|
|
207
|
+
performanceHistory.reduce((sum, h) => sum + (h.attempts || 1), 0) / performanceHistory.length;
|
|
208
|
+
|
|
209
|
+
// Promote if consistently successful
|
|
210
|
+
if (successRate >= 0.8 && avgAttempts <= 1.5) {
|
|
211
|
+
if (experienceLevel === 'novice') return 'intermediate';
|
|
212
|
+
if (experienceLevel === 'intermediate') return 'expert';
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Demote if struggling
|
|
216
|
+
if (successRate < 0.5 || avgAttempts > 3) {
|
|
217
|
+
if (experienceLevel === 'expert') return 'intermediate';
|
|
218
|
+
if (experienceLevel === 'intermediate') return 'novice';
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return experienceLevel;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Record user satisfaction feedback
|
|
226
|
+
*/
|
|
227
|
+
async recordSatisfactionFeedback({ user, hookType, rating, feedback = '' }) {
|
|
228
|
+
const { userId } = user;
|
|
229
|
+
|
|
230
|
+
if (!this.satisfactionData.has(userId)) {
|
|
231
|
+
this.satisfactionData.set(userId, {
|
|
232
|
+
ratings: [],
|
|
233
|
+
feedback: [],
|
|
234
|
+
totalFeedback: 0,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const userData = this.satisfactionData.get(userId);
|
|
239
|
+
userData.ratings.push(rating);
|
|
240
|
+
userData.feedback.push({ hookType, rating, feedback, timestamp: Date.now() });
|
|
241
|
+
userData.totalFeedback++;
|
|
242
|
+
|
|
243
|
+
this.satisfactionData.set(userId, userData);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Get user satisfaction metrics
|
|
248
|
+
*/
|
|
249
|
+
async getUserSatisfaction(userId) {
|
|
250
|
+
const userData = this.satisfactionData.get(userId);
|
|
251
|
+
|
|
252
|
+
if (!userData || !userData.ratings.length) {
|
|
253
|
+
return {
|
|
254
|
+
averageRating: 4.0,
|
|
255
|
+
totalFeedback: 0,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const averageRating =
|
|
260
|
+
userData.ratings.reduce((sum, rating) => sum + rating, 0) / userData.ratings.length;
|
|
261
|
+
|
|
262
|
+
return {
|
|
263
|
+
averageRating,
|
|
264
|
+
totalFeedback: userData.totalFeedback,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Get overall satisfaction across all users
|
|
270
|
+
*/
|
|
271
|
+
async getOverallSatisfaction() {
|
|
272
|
+
let totalRatings = [];
|
|
273
|
+
|
|
274
|
+
for (const [userId, userData] of this.satisfactionData) {
|
|
275
|
+
totalRatings = [...totalRatings, ...userData.ratings];
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (!totalRatings.length) {
|
|
279
|
+
return 4.2; // Default high satisfaction
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return totalRatings.reduce((sum, rating) => sum + rating, 0) / totalRatings.length;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Identify areas for improvement based on low satisfaction
|
|
287
|
+
*/
|
|
288
|
+
async identifyImprovementAreas() {
|
|
289
|
+
const improvements = [];
|
|
290
|
+
|
|
291
|
+
for (const [userId, userData] of this.satisfactionData) {
|
|
292
|
+
const lowRatingFeedback = userData.feedback.filter((f) => f.rating <= 2);
|
|
293
|
+
|
|
294
|
+
for (const feedback of lowRatingFeedback) {
|
|
295
|
+
if (feedback.feedback.includes('verbose')) {
|
|
296
|
+
improvements.push({
|
|
297
|
+
area: 'verbosity-mismatch',
|
|
298
|
+
priority: 'high',
|
|
299
|
+
description: 'Users finding output too verbose for their level',
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
if (feedback.feedback.includes('not enough')) {
|
|
303
|
+
improvements.push({
|
|
304
|
+
area: 'insufficient-guidance',
|
|
305
|
+
priority: 'high',
|
|
306
|
+
description: 'Users need more detailed explanations',
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return improvements;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Record user corrections for learning
|
|
317
|
+
*/
|
|
318
|
+
async recordUserCorrection({ user, originalSuggestion, userPreference }) {
|
|
319
|
+
const { userId } = user;
|
|
320
|
+
|
|
321
|
+
this.userCorrections.set(userId, {
|
|
322
|
+
originalSuggestion,
|
|
323
|
+
userPreference,
|
|
324
|
+
timestamp: Date.now(),
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Adapt hooks for specific context
|
|
330
|
+
*/
|
|
331
|
+
async adaptHooksForContext(user, context) {
|
|
332
|
+
const baseHooks = await this.adaptHooksForUser(user);
|
|
333
|
+
|
|
334
|
+
const contextualAdaptations = {
|
|
335
|
+
mlSpecific: context.projectType === 'machine-learning',
|
|
336
|
+
collaborationTips: context.teamSize === 'large',
|
|
337
|
+
complexityWarnings: context.complexity === 'high',
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
return {
|
|
341
|
+
...baseHooks,
|
|
342
|
+
...contextualAdaptations,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export { ExperienceAdaptationHooks };
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Personalization Hooks - Minimal Implementation
|
|
3
|
+
*
|
|
4
|
+
* Handles user-specific personalization for hook behavior.
|
|
5
|
+
* Following TDD: tests were written first, now implementing to make them green.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
class PersonalizationHooks {
|
|
9
|
+
constructor(userPreferences = {}) {
|
|
10
|
+
this.userPreferences = {
|
|
11
|
+
experienceLevel: 'intermediate',
|
|
12
|
+
verbosity: 'balanced',
|
|
13
|
+
preferredLanguages: ['javascript'],
|
|
14
|
+
workflowPreferences: {
|
|
15
|
+
autoFormat: true,
|
|
16
|
+
showHints: true,
|
|
17
|
+
detailedLogs: true,
|
|
18
|
+
},
|
|
19
|
+
...userPreferences,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get personalized hook configuration
|
|
25
|
+
*/
|
|
26
|
+
getPersonalizedConfiguration() {
|
|
27
|
+
return {
|
|
28
|
+
verbosity: this.userPreferences.verbosity,
|
|
29
|
+
experienceLevel: this.userPreferences.experienceLevel,
|
|
30
|
+
languages: this.userPreferences.preferredLanguages,
|
|
31
|
+
workflow: this.userPreferences.workflowPreferences,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Adapt hooks based on user context
|
|
37
|
+
*/
|
|
38
|
+
adaptToUserContext(context = {}) {
|
|
39
|
+
const config = this.getPersonalizedConfiguration();
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
...config,
|
|
43
|
+
contextual: true,
|
|
44
|
+
adapted: true,
|
|
45
|
+
context,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Execute personalized pre-task hook
|
|
51
|
+
*/
|
|
52
|
+
async executePreTaskHook(params = {}) {
|
|
53
|
+
const { task, user = {} } = params;
|
|
54
|
+
const level = user.experienceLevel || this.userPreferences.experienceLevel;
|
|
55
|
+
|
|
56
|
+
const baseResponse = {
|
|
57
|
+
task,
|
|
58
|
+
user,
|
|
59
|
+
personalized: true,
|
|
60
|
+
timestamp: Date.now(),
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
switch (level) {
|
|
64
|
+
case 'novice':
|
|
65
|
+
return {
|
|
66
|
+
...baseResponse,
|
|
67
|
+
content: `Starting task: ${task}. This explanation will guide you through each step with detailed instructions and examples.`,
|
|
68
|
+
verbosity: 'detailed',
|
|
69
|
+
showSteps: true,
|
|
70
|
+
examples: ['Example 1', 'Example 2'],
|
|
71
|
+
tips: ['Tip 1', 'Tip 2'],
|
|
72
|
+
warnings: ['Warning 1'],
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
case 'expert':
|
|
76
|
+
return {
|
|
77
|
+
...baseResponse,
|
|
78
|
+
content: `Task: ${task}`,
|
|
79
|
+
verbosity: 'minimal',
|
|
80
|
+
format: 'summary',
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
case 'intermediate':
|
|
84
|
+
default:
|
|
85
|
+
return {
|
|
86
|
+
...baseResponse,
|
|
87
|
+
content: `Task: ${task}. Here are some useful tips to help you succeed.`,
|
|
88
|
+
verbosity: 'balanced',
|
|
89
|
+
tips: ['Contextual tip'],
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Update user preferences
|
|
96
|
+
*/
|
|
97
|
+
updatePreferences(newPreferences) {
|
|
98
|
+
this.userPreferences = {
|
|
99
|
+
...this.userPreferences,
|
|
100
|
+
...newPreferences,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Get preference summary
|
|
106
|
+
*/
|
|
107
|
+
getPreferenceSummary() {
|
|
108
|
+
return {
|
|
109
|
+
experienceLevel: this.userPreferences.experienceLevel,
|
|
110
|
+
verbosity: this.userPreferences.verbosity,
|
|
111
|
+
languageCount: this.userPreferences.preferredLanguages.length,
|
|
112
|
+
workflowEnabled: Object.values(this.userPreferences.workflowPreferences).filter(Boolean)
|
|
113
|
+
.length,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export { PersonalizationHooks };
|