telos-framework 0.1.4 → 0.3.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.
Files changed (104) hide show
  1. package/.claude/agents/behavioral-transformation-agent.md +144 -0
  2. package/.claude/agents/command-system-agent.md +335 -0
  3. package/.claude/agents/completion-gate.md +71 -0
  4. package/.claude/agents/component-implementation-agent.md +174 -0
  5. package/.claude/agents/devops-agent.md +128 -0
  6. package/.claude/agents/dynamic-agent-creator.md +103 -0
  7. package/.claude/agents/enhanced-project-manager-agent.md +145 -0
  8. package/.claude/agents/enhanced-quality-gate.md +54 -0
  9. package/.claude/agents/feature-implementation-agent.md +148 -0
  10. package/.claude/agents/functional-testing-agent.md +51 -0
  11. package/.claude/agents/hook-integration-agent.md +204 -0
  12. package/.claude/agents/infrastructure-implementation-agent.md +175 -0
  13. package/.claude/agents/lib/research-analyzer.js +470 -0
  14. package/.claude/agents/metrics-collection-agent.md +374 -0
  15. package/.claude/agents/npx-package-agent.md +246 -0
  16. package/.claude/agents/polish-implementation-agent.md +151 -0
  17. package/.claude/agents/prd-agent.md +76 -0
  18. package/.claude/agents/prd-mvp.md +101 -0
  19. package/.claude/agents/prd-research-agent.md +482 -0
  20. package/.claude/agents/quality-agent.md +128 -0
  21. package/.claude/agents/readiness-gate.md +104 -0
  22. package/.claude/agents/research-agent.md +173 -0
  23. package/.claude/agents/routing-agent.md +108 -0
  24. package/.claude/agents/task-checker.md +163 -0
  25. package/.claude/agents/task-executor.md +107 -0
  26. package/.claude/agents/task-orchestrator.md +343 -0
  27. package/.claude/agents/tdd-validation-agent.md +187 -0
  28. package/.claude/agents/testing-implementation-agent.md +151 -0
  29. package/.claude/agents/van-maintenance-agent.md +64 -0
  30. package/.claude/agents/workflow-agent.md +87 -0
  31. package/.claude/commands/autocompact.md +41 -0
  32. package/.claude/commands/continue-handoff.md +98 -0
  33. package/.claude/commands/mock.md +45 -0
  34. package/.claude/commands/reset-handoff.md +59 -0
  35. package/.claude/commands/telos/init.md +326 -0
  36. package/.claude/commands/telos/quick.md +90 -0
  37. package/.claude/commands/telos/reset.md +100 -0
  38. package/.claude/commands/telos/status.md +170 -0
  39. package/.claude/commands/telos/validate.md +143 -0
  40. package/.claude/commands/tm/add-dependency/add-dependency.md +55 -0
  41. package/.claude/commands/tm/add-subtask/add-subtask.md +76 -0
  42. package/.claude/commands/tm/add-subtask/convert-task-to-subtask.md +71 -0
  43. package/.claude/commands/tm/add-task/add-task.md +78 -0
  44. package/.claude/commands/tm/analyze-complexity/analyze-complexity.md +121 -0
  45. package/.claude/commands/tm/clear-subtasks/clear-all-subtasks.md +93 -0
  46. package/.claude/commands/tm/clear-subtasks/clear-subtasks.md +86 -0
  47. package/.claude/commands/tm/complexity-report/complexity-report.md +117 -0
  48. package/.claude/commands/tm/expand/expand-all-tasks.md +51 -0
  49. package/.claude/commands/tm/expand/expand-task.md +49 -0
  50. package/.claude/commands/tm/fix-dependencies/fix-dependencies.md +81 -0
  51. package/.claude/commands/tm/generate/generate-tasks.md +121 -0
  52. package/.claude/commands/tm/help.md +81 -0
  53. package/.claude/commands/tm/init/init-project-quick.md +46 -0
  54. package/.claude/commands/tm/init/init-project.md +50 -0
  55. package/.claude/commands/tm/learn.md +103 -0
  56. package/.claude/commands/tm/list/list-tasks-by-status.md +39 -0
  57. package/.claude/commands/tm/list/list-tasks-with-subtasks.md +29 -0
  58. package/.claude/commands/tm/list/list-tasks.md +43 -0
  59. package/.claude/commands/tm/models/setup-models.md +51 -0
  60. package/.claude/commands/tm/models/view-models.md +51 -0
  61. package/.claude/commands/tm/next/next-task.md +66 -0
  62. package/.claude/commands/tm/parse-prd/parse-prd-with-research.md +48 -0
  63. package/.claude/commands/tm/parse-prd/parse-prd.md +49 -0
  64. package/.claude/commands/tm/remove-dependency/remove-dependency.md +62 -0
  65. package/.claude/commands/tm/remove-subtask/remove-subtask.md +84 -0
  66. package/.claude/commands/tm/remove-task/remove-task.md +107 -0
  67. package/.claude/commands/tm/set-status/to-cancelled.md +55 -0
  68. package/.claude/commands/tm/set-status/to-deferred.md +47 -0
  69. package/.claude/commands/tm/set-status/to-done.md +44 -0
  70. package/.claude/commands/tm/set-status/to-in-progress.md +36 -0
  71. package/.claude/commands/tm/set-status/to-pending.md +32 -0
  72. package/.claude/commands/tm/set-status/to-review.md +40 -0
  73. package/.claude/commands/tm/setup/install-taskmaster.md +117 -0
  74. package/.claude/commands/tm/setup/quick-install-taskmaster.md +22 -0
  75. package/.claude/commands/tm/show/show-task.md +82 -0
  76. package/.claude/commands/tm/status/project-status.md +64 -0
  77. package/.claude/commands/tm/sync-readme/sync-readme.md +117 -0
  78. package/.claude/commands/tm/tm-main.md +146 -0
  79. package/.claude/commands/tm/update/update-single-task.md +119 -0
  80. package/.claude/commands/tm/update/update-task.md +72 -0
  81. package/.claude/commands/tm/update/update-tasks-from-id.md +108 -0
  82. package/.claude/commands/tm/utils/analyze-project.md +97 -0
  83. package/.claude/commands/tm/validate-dependencies/validate-dependencies.md +71 -0
  84. package/.claude/commands/tm/workflows/auto-implement-tasks.md +97 -0
  85. package/.claude/commands/tm/workflows/command-pipeline.md +77 -0
  86. package/.claude/commands/tm/workflows/smart-workflow.md +55 -0
  87. package/.claude/commands/van.md +150 -0
  88. package/.claude/docs/README.md +214 -0
  89. package/.claude/docs/TROUBLESHOOTING.md +126 -0
  90. package/.claude/hooks/block-destructive-commands.sh +243 -0
  91. package/.claude/hooks/collective-metrics.sh +291 -0
  92. package/.claude/hooks/directive-enforcer.sh +117 -0
  93. package/.claude/hooks/load-behavioral-system.sh +49 -0
  94. package/.claude/hooks/routing-executor.sh +4 -0
  95. package/.claude/hooks/test-driven-handoff.sh +653 -0
  96. package/.claude/settings.json +125 -0
  97. package/README.md +39 -15
  98. package/lib/commands/init-state.js +102 -0
  99. package/lib/commands/init.js +58 -95
  100. package/lib/installers/memory-files.js +77 -0
  101. package/lib/installers/slash-commands.js +77 -0
  102. package/package.json +7 -2
  103. package/templates/AGENTS.md +79 -0
  104. package/templates/CLAUDE.md +54 -0
@@ -0,0 +1,470 @@
1
+ /**
2
+ * ResearchDrivenAnalyzer - Autonomous complexity analysis using Context7 research cache
3
+ *
4
+ * This class replaces task-master delegation with research-informed decision making.
5
+ * It analyzes tasks against cached Context7 documentation to make autonomous complexity scoring
6
+ * and selective expansion decisions.
7
+ */
8
+ class ResearchDrivenAnalyzer {
9
+ constructor(projectRoot, cacheDirectory = '.taskmaster/docs/research/') {
10
+ this.projectRoot = projectRoot;
11
+ this.cacheDir = cacheDirectory;
12
+ this.researchCache = {};
13
+ this.complexityFactors = {
14
+ // React patterns from Context7
15
+ 'custom-hooks': { weight: 3, patterns: ['useState', 'useEffect', 'useCallback', 'useMemo'] },
16
+ 'context-api': { weight: 2, patterns: ['createContext', 'useContext', 'Provider'] },
17
+ 'react-router': { weight: 2, patterns: ['Routes', 'Route', 'useNavigate', 'useParams'] },
18
+ 'react-query': { weight: 3, patterns: ['useQuery', 'useMutation', 'QueryClient'] },
19
+
20
+ // TypeScript complexity from Context7
21
+ 'typescript-generics': { weight: 4, patterns: ['<T>', 'extends', 'keyof', 'Pick', 'Omit'] },
22
+ 'typescript-interfaces': { weight: 2, patterns: ['interface', 'type', 'Record'] },
23
+ 'typescript-decorators': { weight: 4, patterns: ['@Component', '@Injectable', 'reflect-metadata'] },
24
+
25
+ // Build/tooling complexity from Context7
26
+ 'vite-plugins': { weight: 3, patterns: ['defineConfig', 'plugins', 'rollupOptions'] },
27
+ 'webpack-config': { weight: 4, patterns: ['webpack.config', 'loaders', 'plugins'] },
28
+ 'babel-config': { weight: 3, patterns: ['.babelrc', 'babel.config', 'presets'] },
29
+
30
+ // Testing complexity from Context7
31
+ 'vitest-mocking': { weight: 2, patterns: ['vi.mock', 'vi.spyOn', 'mockImplementation'] },
32
+ 'jest-config': { weight: 3, patterns: ['jest.config', 'setupTests', 'testEnvironment'] },
33
+ 'playwright-e2e': { weight: 4, patterns: ['test.describe', 'page.goto', 'expect.toHaveText'] },
34
+
35
+ // Data/state complexity from Context7
36
+ 'state-management': { weight: 3, patterns: ['redux', 'zustand', 'jotai', 'recoil'] },
37
+ 'database-integration': { weight: 4, patterns: ['prisma', 'typeorm', 'mongoose', 'supabase'] },
38
+ 'api-integration': { weight: 3, patterns: ['axios', 'fetch', 'graphql', 'tRPC'] },
39
+
40
+ // Common utilities from Context7
41
+ 'localStorage': { weight: 1, patterns: ['localStorage.setItem', 'localStorage.getItem'] },
42
+ 'responsive-design': { weight: 2, patterns: ['@media', 'flexbox', 'grid', 'mobile-first'] },
43
+ 'authentication': { weight: 4, patterns: ['jwt', 'oauth', 'passport', 'auth0'] },
44
+ 'deployment': { weight: 3, patterns: ['docker', 'vercel', 'netlify', 'aws'] }
45
+ };
46
+
47
+ this.expansionThreshold = 5; // Tasks scoring > 5 need subtasks
48
+ this.maxSubtasks = 8; // Limit subtask explosion
49
+ }
50
+
51
+ /**
52
+ * Load all research cache files into memory for analysis
53
+ */
54
+ async loadResearchCache() {
55
+ try {
56
+ // Use LS tool to get research files
57
+ const researchFiles = await this.listFiles(this.cacheDir);
58
+
59
+ for (const file of researchFiles) {
60
+ if (file.endsWith('.md')) {
61
+ const content = await this.readFile(`${this.cacheDir}${file}`);
62
+ const technology = this.extractTechnologyFromFilename(file);
63
+
64
+ this.researchCache[technology] = {
65
+ file: file,
66
+ content: content,
67
+ patterns: this.extractPatternsFromResearch(content),
68
+ examples: this.extractCodeExamples(content),
69
+ lastUpdated: this.extractDateFromFilename(file)
70
+ };
71
+ }
72
+ }
73
+
74
+ console.log(`✅ Loaded research cache: ${Object.keys(this.researchCache).length} technologies`);
75
+ return this.researchCache;
76
+ } catch (error) {
77
+ console.error('❌ Failed to load research cache:', error);
78
+ return {};
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Analyze a task's complexity using loaded research cache
84
+ */
85
+ analyzeTaskComplexity(task) {
86
+ let score = 0;
87
+ const detectedFactors = [];
88
+ const researchHints = [];
89
+
90
+ // Analyze task description against complexity factors
91
+ const taskText = `${task.title} ${task.description}`.toLowerCase();
92
+
93
+ for (const [factorName, factor] of Object.entries(this.complexityFactors)) {
94
+ if (this.taskInvolvesPattern(taskText, factor.patterns)) {
95
+ score += factor.weight;
96
+ detectedFactors.push({
97
+ factor: factorName,
98
+ weight: factor.weight,
99
+ patterns: factor.patterns.filter(p => taskText.includes(p.toLowerCase()))
100
+ });
101
+
102
+ // Add research-specific hints if we have cache for this technology
103
+ const relatedResearch = this.findRelatedResearch(factorName);
104
+ if (relatedResearch) {
105
+ researchHints.push({
106
+ factor: factorName,
107
+ researchFile: relatedResearch.file,
108
+ keyPatterns: relatedResearch.patterns.slice(0, 3) // Top 3 patterns
109
+ });
110
+ }
111
+ }
112
+ }
113
+
114
+ return {
115
+ taskId: task.id,
116
+ title: task.title,
117
+ complexityScore: score,
118
+ detectedFactors,
119
+ researchHints,
120
+ needsExpansion: score > this.expansionThreshold,
121
+ suggestedSubtasks: this.generateResearchBasedSubtasks(task, detectedFactors, researchHints),
122
+ researchContext: this.buildResearchContext(detectedFactors, researchHints)
123
+ };
124
+ }
125
+
126
+ /**
127
+ * Analyze all tasks and create complexity report
128
+ */
129
+ analyzeAllTasks(tasks) {
130
+ const analyses = [];
131
+ let totalScore = 0;
132
+ let tasksNeedingExpansion = 0;
133
+
134
+ for (const task of tasks) {
135
+ const analysis = this.analyzeTaskComplexity(task);
136
+ analyses.push(analysis);
137
+ totalScore += analysis.complexityScore;
138
+
139
+ if (analysis.needsExpansion) {
140
+ tasksNeedingExpansion++;
141
+ }
142
+ }
143
+
144
+ return {
145
+ totalTasks: tasks.length,
146
+ totalComplexityScore: totalScore,
147
+ averageComplexity: totalScore / tasks.length,
148
+ tasksNeedingExpansion,
149
+ expansionPercentage: (tasksNeedingExpansion / tasks.length) * 100,
150
+ taskAnalyses: analyses,
151
+ researchUtilization: this.calculateResearchUtilization(analyses),
152
+ recommendations: this.generateRecommendations(analyses)
153
+ };
154
+ }
155
+
156
+ /**
157
+ * Generate subtasks based on research patterns
158
+ */
159
+ generateResearchBasedSubtasks(task, detectedFactors, researchHints) {
160
+ const subtasks = [];
161
+ const maxSubtasks = Math.min(this.maxSubtasks, Math.ceil(detectedFactors.length * 1.5));
162
+
163
+ // Group factors by category for logical subtask structure
164
+ const categories = this.groupFactorsByCategory(detectedFactors);
165
+
166
+ for (const [category, factors] of Object.entries(categories)) {
167
+ const categorySubtasks = this.generateCategorySubtasks(category, factors, researchHints);
168
+ subtasks.push(...categorySubtasks.slice(0, 2)); // Max 2 per category
169
+ }
170
+
171
+ // Always include TDD subtasks based on research
172
+ if (researchHints.length > 0) {
173
+ subtasks.unshift({
174
+ type: 'testing',
175
+ title: `Write tests first using ${this.getTestingFrameworkFromResearch(researchHints)}`,
176
+ researchReference: this.getTestingResearchFile(researchHints)
177
+ });
178
+ }
179
+
180
+ return subtasks.slice(0, maxSubtasks);
181
+ }
182
+
183
+ /**
184
+ * Check if task involves specific patterns
185
+ */
186
+ taskInvolvesPattern(taskText, patterns) {
187
+ return patterns.some(pattern =>
188
+ taskText.includes(pattern.toLowerCase()) ||
189
+ taskText.includes(pattern.replace(/([A-Z])/g, '-$1').toLowerCase()) ||
190
+ taskText.includes(pattern.replace(/([A-Z])/g, ' $1').toLowerCase())
191
+ );
192
+ }
193
+
194
+ /**
195
+ * Find related research cache for a complexity factor
196
+ */
197
+ findRelatedResearch(factorName) {
198
+ // Map complexity factors to research cache
199
+ const researchMappings = {
200
+ 'custom-hooks': ['react', 'react-18', 'react-hooks'],
201
+ 'context-api': ['react', 'react-18', 'react-context'],
202
+ 'typescript-generics': ['typescript', 'typescript-config'],
203
+ 'vite-plugins': ['vite', 'vite-config'],
204
+ 'vitest-mocking': ['vitest', 'vitest-testing'],
205
+ // Add more mappings as needed
206
+ };
207
+
208
+ const possibleKeys = researchMappings[factorName] || [factorName];
209
+
210
+ for (const key of possibleKeys) {
211
+ if (this.researchCache[key]) {
212
+ return this.researchCache[key];
213
+ }
214
+ }
215
+
216
+ return null;
217
+ }
218
+
219
+ /**
220
+ * Build research context object for task enhancement
221
+ */
222
+ buildResearchContext(detectedFactors, researchHints) {
223
+ const requiredResearch = [...new Set(researchHints.map(hint => hint.factor))];
224
+ const researchFiles = [...new Set(researchHints.map(hint => hint.researchFile))];
225
+ const keyFindings = researchHints.flatMap(hint => hint.keyPatterns).slice(0, 5);
226
+
227
+ return {
228
+ required_research: requiredResearch,
229
+ research_files: researchFiles.map(f => `.taskmaster/docs/research/${f}`),
230
+ key_findings: keyFindings,
231
+ complexity_factors: detectedFactors.map(f => ({ factor: f.factor, weight: f.weight }))
232
+ };
233
+ }
234
+
235
+ /**
236
+ * Utility methods for file operations (would use MCP tools in practice)
237
+ */
238
+ async listFiles(directory) {
239
+ // In practice, this would use LS tool
240
+ // For now, return mock data
241
+ return ['2025-01-13_react-18-patterns.md', '2025-01-13_typescript-config.md'];
242
+ }
243
+
244
+ async readFile(filePath) {
245
+ // In practice, this would use Read tool
246
+ // For now, return mock content
247
+ return 'Mock research content with patterns and examples';
248
+ }
249
+
250
+ extractTechnologyFromFilename(filename) {
251
+ // Extract technology name from filename pattern: YYYY-MM-DD_{tech}-*.md
252
+ const match = filename.match(/\d{4}-\d{2}-\d{2}_(.+?)-/);
253
+ return match ? match[1] : filename.replace('.md', '');
254
+ }
255
+
256
+ extractDateFromFilename(filename) {
257
+ const match = filename.match(/(\d{4}-\d{2}-\d{2})/);
258
+ return match ? new Date(match[1]) : new Date();
259
+ }
260
+
261
+ extractPatternsFromResearch(content) {
262
+ // Extract code patterns, configurations, and examples from research
263
+ const patterns = [];
264
+
265
+ // Extract JavaScript/TypeScript patterns
266
+ const codeBlocks = content.match(/```(?:javascript|typescript|jsx|tsx)\n([\s\S]*?)\n```/g) || [];
267
+ patterns.push(...codeBlocks);
268
+
269
+ // Extract configuration patterns
270
+ const configs = content.match(/```(?:json|yaml|toml)\n([\s\S]*?)\n```/g) || [];
271
+ patterns.push(...configs);
272
+
273
+ return patterns;
274
+ }
275
+
276
+ extractCodeExamples(content) {
277
+ // Extract working code examples from research
278
+ return this.extractPatternsFromResearch(content);
279
+ }
280
+
281
+ groupFactorsByCategory(factors) {
282
+ const categories = {
283
+ frontend: [],
284
+ backend: [],
285
+ testing: [],
286
+ tooling: [],
287
+ deployment: []
288
+ };
289
+
290
+ const categoryMap = {
291
+ 'custom-hooks': 'frontend',
292
+ 'context-api': 'frontend',
293
+ 'react-router': 'frontend',
294
+ 'typescript-generics': 'frontend',
295
+ 'vitest-mocking': 'testing',
296
+ 'jest-config': 'testing',
297
+ 'vite-plugins': 'tooling',
298
+ 'webpack-config': 'tooling',
299
+ 'api-integration': 'backend',
300
+ 'database-integration': 'backend',
301
+ 'deployment': 'deployment'
302
+ };
303
+
304
+ for (const factor of factors) {
305
+ const category = categoryMap[factor.factor] || 'tooling';
306
+ categories[category].push(factor);
307
+ }
308
+
309
+ // Remove empty categories
310
+ Object.keys(categories).forEach(key => {
311
+ if (categories[key].length === 0) {
312
+ delete categories[key];
313
+ }
314
+ });
315
+
316
+ return categories;
317
+ }
318
+
319
+ generateCategorySubtasks(category, factors, researchHints) {
320
+ const subtasks = [];
321
+
322
+ switch (category) {
323
+ case 'frontend':
324
+ subtasks.push({
325
+ type: 'implementation',
326
+ title: `Implement ${factors.map(f => f.factor).join(' and ')} components`,
327
+ researchReference: this.getResearchFileForCategory(category, researchHints)
328
+ });
329
+ break;
330
+
331
+ case 'testing':
332
+ subtasks.push({
333
+ type: 'testing',
334
+ title: `Set up testing infrastructure for ${factors.map(f => f.factor).join(' and ')}`,
335
+ researchReference: this.getResearchFileForCategory(category, researchHints)
336
+ });
337
+ break;
338
+
339
+ case 'tooling':
340
+ subtasks.push({
341
+ type: 'configuration',
342
+ title: `Configure ${factors.map(f => f.factor).join(' and ')} build tools`,
343
+ researchReference: this.getResearchFileForCategory(category, researchHints)
344
+ });
345
+ break;
346
+
347
+ default:
348
+ subtasks.push({
349
+ type: 'implementation',
350
+ title: `Implement ${factors.map(f => f.factor).join(' and ')}`,
351
+ researchReference: this.getResearchFileForCategory(category, researchHints)
352
+ });
353
+ }
354
+
355
+ return subtasks;
356
+ }
357
+
358
+ getTestingFrameworkFromResearch(researchHints) {
359
+ const testingFrameworks = ['vitest', 'jest', 'playwright', 'cypress'];
360
+
361
+ for (const hint of researchHints) {
362
+ for (const framework of testingFrameworks) {
363
+ if (hint.factor.includes(framework)) {
364
+ return framework;
365
+ }
366
+ }
367
+ }
368
+
369
+ return 'vitest'; // Default
370
+ }
371
+
372
+ getTestingResearchFile(researchHints) {
373
+ for (const hint of researchHints) {
374
+ if (hint.factor.includes('test') || hint.factor.includes('mock')) {
375
+ return hint.researchFile;
376
+ }
377
+ }
378
+
379
+ return null;
380
+ }
381
+
382
+ getResearchFileForCategory(category, researchHints) {
383
+ // Return the most relevant research file for the category
384
+ return researchHints.length > 0 ? researchHints[0].researchFile : null;
385
+ }
386
+
387
+ calculateResearchUtilization(analyses) {
388
+ let totalFactors = 0;
389
+ let researchBackedFactors = 0;
390
+
391
+ for (const analysis of analyses) {
392
+ totalFactors += analysis.detectedFactors.length;
393
+ researchBackedFactors += analysis.researchHints.length;
394
+ }
395
+
396
+ return {
397
+ totalFactors,
398
+ researchBackedFactors,
399
+ utilizationPercentage: totalFactors > 0 ? (researchBackedFactors / totalFactors) * 100 : 0
400
+ };
401
+ }
402
+
403
+ generateRecommendations(analyses) {
404
+ const recommendations = [];
405
+
406
+ // High complexity tasks
407
+ const highComplexityTasks = analyses.filter(a => a.complexityScore > 8);
408
+ if (highComplexityTasks.length > 0) {
409
+ recommendations.push({
410
+ type: 'high_complexity',
411
+ message: `${highComplexityTasks.length} tasks have high complexity (>8). Consider breaking them down further.`,
412
+ tasks: highComplexityTasks.map(t => ({ id: t.taskId, score: t.complexityScore }))
413
+ });
414
+ }
415
+
416
+ // Missing research coverage
417
+ const lowResearchCoverage = analyses.filter(a => a.detectedFactors.length > a.researchHints.length);
418
+ if (lowResearchCoverage.length > 0) {
419
+ recommendations.push({
420
+ type: 'missing_research',
421
+ message: `${lowResearchCoverage.length} tasks could benefit from additional Context7 research.`,
422
+ tasks: lowResearchCoverage.map(t => t.taskId)
423
+ });
424
+ }
425
+
426
+ // Expansion recommendations
427
+ const expansionCandidates = analyses.filter(a => a.needsExpansion);
428
+ if (expansionCandidates.length > 0) {
429
+ recommendations.push({
430
+ type: 'expansion_needed',
431
+ message: `${expansionCandidates.length} tasks need subtask expansion based on complexity.`,
432
+ tasks: expansionCandidates.map(t => ({
433
+ id: t.taskId,
434
+ score: t.complexityScore,
435
+ subtaskCount: t.suggestedSubtasks.length
436
+ }))
437
+ });
438
+ }
439
+
440
+ return recommendations;
441
+ }
442
+ }
443
+
444
+ // Export for use in agent
445
+ if (typeof module !== 'undefined' && module.exports) {
446
+ module.exports = ResearchDrivenAnalyzer;
447
+ }
448
+
449
+ /**
450
+ * USAGE EXAMPLE:
451
+ *
452
+ * const analyzer = new ResearchDrivenAnalyzer('/project/root');
453
+ * await analyzer.loadResearchCache();
454
+ *
455
+ * const tasks = [
456
+ * { id: "1", title: "Create React hooks", description: "Build custom hooks with useState and useEffect" },
457
+ * { id: "2", title: "Setup TypeScript", description: "Configure TypeScript with generics and interfaces" }
458
+ * ];
459
+ *
460
+ * const report = analyzer.analyzeAllTasks(tasks);
461
+ * console.log('Complexity Report:', report);
462
+ *
463
+ * // Use results to enhance tasks with research context
464
+ * for (const analysis of report.taskAnalyses) {
465
+ * if (analysis.needsExpansion) {
466
+ * // Expand task using analysis.suggestedSubtasks
467
+ * // Update task with analysis.researchContext
468
+ * }
469
+ * }
470
+ */