@champpaba/claude-agent-kit 1.1.1 → 1.4.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.
@@ -0,0 +1,694 @@
1
+ # Task Analyzer - TaskMaster-style Analysis
2
+
3
+ > **Enhanced task analysis for intelligent phase generation**
4
+ > **Version:** 1.3.0 (TaskMaster Integration)
5
+ > **Used by:** `/csetup` command
6
+
7
+ ---
8
+
9
+ ## 🎯 Purpose
10
+
11
+ Analyze tasks.md (from OpenSpec) and generate **intelligent task metadata** including:
12
+ - Complexity scoring (1-10)
13
+ - Dependency detection
14
+ - Risk assessment
15
+ - Research requirements
16
+ - Subtask breakdown recommendations
17
+ - Priority ranking
18
+
19
+ **Inspired by:** [claude-task-master](https://github.com/eyaltoledano/claude-task-master)
20
+
21
+ ---
22
+
23
+ ## 📋 Analysis Framework
24
+
25
+ ### 1. Complexity Scoring (1-10)
26
+
27
+ **Factors:**
28
+ ```typescript
29
+ function calculateComplexity(task: Task): number {
30
+ let score = 3 // Base complexity
31
+
32
+ // Factor 1: Estimated time
33
+ if (task.estimatedTime > 120) score += 3 // > 2 hours
34
+ else if (task.estimatedTime > 60) score += 2 // > 1 hour
35
+ else if (task.estimatedTime > 30) score += 1 // > 30 min
36
+
37
+ // Factor 2: Keywords
38
+ const highComplexityKeywords = [
39
+ 'authentication', 'security', 'payment', 'real-time',
40
+ 'websocket', 'oauth', 'encryption', 'migration',
41
+ 'refactor', 'optimization', 'performance'
42
+ ]
43
+ const matches = highComplexityKeywords.filter(kw =>
44
+ task.description.toLowerCase().includes(kw)
45
+ )
46
+ score += matches.length
47
+
48
+ // Factor 3: Multi-step indicator
49
+ if (task.description.match(/\band\b/gi)?.length > 2) score += 1
50
+ if (task.description.match(/\bthen\b/gi)?.length > 1) score += 1
51
+
52
+ // Factor 4: External dependencies
53
+ if (task.description.match(/(api|library|service|integration)/i)) score += 1
54
+
55
+ // Cap at 10
56
+ return Math.min(score, 10)
57
+ }
58
+ ```
59
+
60
+ **Complexity Levels:**
61
+ - 1-3: Simple (CRUD, UI components)
62
+ - 4-6: Moderate (Business logic, integrations)
63
+ - 7-8: Complex (Auth, payments, real-time)
64
+ - 9-10: Critical (Security, migrations, major refactors)
65
+
66
+ ---
67
+
68
+ ### 2. Dependency Detection
69
+
70
+ **Analysis:**
71
+ ```typescript
72
+ function detectDependencies(task: Task, allTasks: Task[]): Dependencies {
73
+ const dependencies = {
74
+ blocks: [], // Tasks this task blocks
75
+ blockedBy: [], // Tasks blocking this task
76
+ parallelizable: [] // Tasks that can run in parallel
77
+ }
78
+
79
+ // Rule 1: UI depends on backend
80
+ if (task.type === 'frontend-integration') {
81
+ const apiTasks = allTasks.filter(t =>
82
+ t.type === 'backend' &&
83
+ t.description.match(/api|endpoint/i)
84
+ )
85
+ dependencies.blockedBy.push(...apiTasks.map(t => t.id))
86
+ }
87
+
88
+ // Rule 2: Backend depends on database
89
+ if (task.type === 'backend') {
90
+ const dbTasks = allTasks.filter(t =>
91
+ t.type === 'database' &&
92
+ task.description.includes(t.description.split(' ')[0]) // Common entity
93
+ )
94
+ dependencies.blockedBy.push(...dbTasks.map(t => t.id))
95
+ }
96
+
97
+ // Rule 3: Tests depend on implementation
98
+ if (task.type === 'test') {
99
+ const implTasks = allTasks.filter(t =>
100
+ t.type !== 'test' &&
101
+ task.description.toLowerCase().includes(t.description.split(' ')[0].toLowerCase())
102
+ )
103
+ dependencies.blockedBy.push(...implTasks.map(t => t.id))
104
+ }
105
+
106
+ // Rule 4: Integration depends on both UI and API
107
+ if (task.description.match(/connect|integrate|link/i)) {
108
+ const uiTasks = allTasks.filter(t => t.type === 'uxui-frontend')
109
+ const apiTasks = allTasks.filter(t => t.type === 'backend')
110
+ dependencies.blockedBy.push(...uiTasks.map(t => t.id), ...apiTasks.map(t => t.id))
111
+ }
112
+
113
+ // Rule 5: Parallel work (no shared entities)
114
+ const parallelizable = allTasks.filter(t => {
115
+ if (t.id === task.id) return false
116
+ const taskEntities = extractEntities(task.description)
117
+ const otherEntities = extractEntities(t.description)
118
+ return taskEntities.every(e => !otherEntities.includes(e))
119
+ })
120
+ dependencies.parallelizable = parallelizable.map(t => t.id)
121
+
122
+ return dependencies
123
+ }
124
+ ```
125
+
126
+ ---
127
+
128
+ ### 3. Risk Assessment
129
+
130
+ **Risk Factors:**
131
+ ```typescript
132
+ function assessRisk(task: Task, complexity: number): RiskLevel {
133
+ let riskScore = 0
134
+
135
+ // Factor 1: Complexity
136
+ if (complexity >= 9) riskScore += 3
137
+ else if (complexity >= 7) riskScore += 2
138
+ else if (complexity >= 5) riskScore += 1
139
+
140
+ // Factor 2: Security-critical
141
+ const securityKeywords = ['auth', 'password', 'token', 'security', 'payment', 'encryption']
142
+ if (securityKeywords.some(kw => task.description.toLowerCase().includes(kw))) {
143
+ riskScore += 3
144
+ }
145
+
146
+ // Factor 3: External dependencies
147
+ const externalKeywords = ['api', 'third-party', 'service', 'integration', 'library']
148
+ if (externalKeywords.some(kw => task.description.toLowerCase().includes(kw))) {
149
+ riskScore += 1
150
+ }
151
+
152
+ // Factor 4: Data migration
153
+ if (task.description.match(/migrat|transform|convert/i)) {
154
+ riskScore += 2
155
+ }
156
+
157
+ // Factor 5: User-facing
158
+ if (task.type === 'uxui-frontend' && task.description.match(/checkout|payment|profile|login/i)) {
159
+ riskScore += 1
160
+ }
161
+
162
+ // Risk levels
163
+ if (riskScore >= 6) return { level: 'HIGH', score: riskScore, mitigation: [] }
164
+ if (riskScore >= 3) return { level: 'MEDIUM', score: riskScore, mitigation: [] }
165
+ return { level: 'LOW', score: riskScore, mitigation: [] }
166
+ }
167
+
168
+ function generateMitigation(risk: RiskLevel, task: Task): string[] {
169
+ const mitigation = []
170
+
171
+ if (risk.level === 'HIGH' || risk.level === 'MEDIUM') {
172
+ mitigation.push('TDD required (write tests first)')
173
+ mitigation.push('Code review checkpoint')
174
+ }
175
+
176
+ if (task.description.match(/auth|security|payment/i)) {
177
+ mitigation.push('Security checklist validation')
178
+ mitigation.push('Use battle-tested libraries (no custom crypto)')
179
+ }
180
+
181
+ if (task.description.match(/migration|transform/i)) {
182
+ mitigation.push('Backup data before migration')
183
+ mitigation.push('Dry-run test on staging')
184
+ }
185
+
186
+ if (risk.level === 'HIGH') {
187
+ mitigation.push('Add 50% time buffer')
188
+ mitigation.push('Pair programming recommended')
189
+ }
190
+
191
+ return mitigation
192
+ }
193
+ ```
194
+
195
+ ---
196
+
197
+ ### 4. Research Requirements Detection
198
+
199
+ > **Integration with /pageplan (v1.4.0):**
200
+ > - `/pageplan` handles: Component reuse analysis + Content drafting + Asset checklist
201
+ > - `TaskMaster` handles: Technical research (libraries, APIs, migrations)
202
+ > - **No overlap:** UX/accessibility research is skipped if `page-plan.md` exists
203
+
204
+ **Decision Matrix:**
205
+
206
+ | Task Type | Has page-plan.md | Research Triggered |
207
+ |-----------|------------------|--------------------|
208
+ | UI Landing | ✅ Yes | ❌ Skip UX patterns<br>❌ Skip accessibility<br>✅ Check library/migration |
209
+ | UI Landing | ❌ No | ✅ UX patterns research<br>✅ Accessibility research<br>✅ Check library |
210
+ | API Integration | ✅ Yes | ✅ Integration research (not affected) |
211
+ | Database Migration | ❌ No | ✅ Migration research (not affected) |
212
+
213
+ **Why this separation?**
214
+ - `/pageplan` = **Design-level** (which components, what content, what assets)
215
+ - `TaskMaster` = **Technical-level** (how to implement, which libraries, what patterns)
216
+ - Avoids redundant "landing page best practices" research when page structure is already planned
217
+
218
+ **Detection Logic:**
219
+ ```typescript
220
+ function detectResearchNeeds(task: Task, changeContext: any): ResearchRequirement | null {
221
+ // Check if page-plan.md exists (skip UX/accessibility research)
222
+ const hasPagePlan = fileExists(`.changes/${changeContext.changeId}/page-plan.md`)
223
+
224
+ const researchIndicators = {
225
+ // Technical research (always check)
226
+ newTechnology: /new|latest|modern|upgrade|v\d+/i,
227
+ bestPractices: /best practice|pattern|approach|strategy|how to/i,
228
+ integration: /integrate|connect|setup|configure/i,
229
+ performance: /optimi[sz]e|performance|speed|faster/i,
230
+ migration: /migrat|upgrade|convert/i,
231
+
232
+ // UX research (skip if page-plan exists)
233
+ uxPatterns: hasPagePlan ? null : /dashboard|landing|e-commerce|checkout|wizard|onboarding/i,
234
+ accessibility: hasPagePlan ? null : /form|input|modal|navigation|menu|dialog|button/i,
235
+
236
+ // Design system (always check)
237
+ componentLibrary: /component library|ui library|design system/i,
238
+ designGuidelines: /brand|style|visual|aesthetic|appearance/i
239
+ }
240
+
241
+ // Check for multiple patterns (prioritize by order)
242
+ const detectedPatterns = []
243
+
244
+ for (const [category, pattern] of Object.entries(researchIndicators)) {
245
+ if (pattern && pattern.test(task.description)) {
246
+ detectedPatterns.push({
247
+ category,
248
+ reason: `Task involves ${category} - requires research phase`,
249
+ suggestedQueries: generateResearchQueries(task, category),
250
+ estimatedTime: getEstimatedResearchTime(category)
251
+ })
252
+ }
253
+ }
254
+
255
+ // Special case: If no design system exists and UI work detected
256
+ if (task.type === 'uxui-frontend' && !fileExists('design-system/STYLE_GUIDE.md')) {
257
+ detectedPatterns.push({
258
+ category: 'missingDesignSystem',
259
+ reason: 'No design system found - component library selection needed',
260
+ suggestedQueries: [
261
+ 'shadcn/ui vs Radix UI comparison 2025',
262
+ 'React component library recommendations',
263
+ 'Headless UI libraries for Tailwind CSS'
264
+ ],
265
+ estimatedTime: 10
266
+ })
267
+ }
268
+
269
+ // Log skipped research
270
+ if (hasPagePlan && detectedPatterns.length === 0) {
271
+ console.log(`ℹ️ UX/accessibility research skipped (page-plan.md exists)`)
272
+ }
273
+
274
+ // Return highest priority research need
275
+ return detectedPatterns[0] || null
276
+ }
277
+
278
+ function getEstimatedResearchTime(category: string): number {
279
+ const timeMap = {
280
+ newTechnology: 15,
281
+ bestPractices: 10,
282
+ integration: 20,
283
+ performance: 10,
284
+ migration: 15,
285
+ uxPatterns: 10,
286
+ accessibility: 5,
287
+ componentLibrary: 10,
288
+ designGuidelines: 5,
289
+ missingDesignSystem: 10
290
+ }
291
+ return timeMap[category] || 15
292
+ }
293
+
294
+ function generateResearchQueries(task: Task, category: string): string[] {
295
+ const queries = []
296
+
297
+ if (category === 'newTechnology') {
298
+ queries.push(`Latest version and features of ${extractTechnology(task.description)}`)
299
+ queries.push(`Migration guide from current version`)
300
+ }
301
+
302
+ if (category === 'bestPractices') {
303
+ queries.push(`Best practices for ${extractContext(task.description)}`)
304
+ queries.push(`Common pitfalls and how to avoid them`)
305
+ }
306
+
307
+ if (category === 'integration') {
308
+ const services = extractServices(task.description)
309
+ queries.push(`${services[0]} integration with ${services[1]} guide`)
310
+ queries.push(`Authentication and security considerations`)
311
+ }
312
+
313
+ if (category === 'performance') {
314
+ queries.push(`Performance optimization techniques for ${extractContext(task.description)}`)
315
+ queries.push(`Benchmarking and profiling tools`)
316
+ }
317
+
318
+ if (category === 'migration') {
319
+ const tech = extractTechnology(task.description)
320
+ queries.push(`${tech} migration guide 2025`)
321
+ queries.push(`Breaking changes and upgrade path`)
322
+ queries.push(`Data migration strategies and best practices`)
323
+ }
324
+
325
+ if (category === 'uxPatterns') {
326
+ const pageType = extractPageType(task.description)
327
+ queries.push(`${pageType} best practices 2025`)
328
+ queries.push(`${pageType} UX patterns and examples`)
329
+ queries.push(`${pageType} conversion optimization techniques`)
330
+ }
331
+
332
+ if (category === 'accessibility') {
333
+ const component = extractComponent(task.description)
334
+ queries.push(`${component} accessibility best practices`)
335
+ queries.push(`WCAG 2.1 guidelines for ${component}`)
336
+ queries.push(`Screen reader support for ${component}`)
337
+ queries.push(`Keyboard navigation patterns`)
338
+ }
339
+
340
+ if (category === 'componentLibrary') {
341
+ queries.push('shadcn/ui vs Radix UI comparison 2025')
342
+ queries.push('React component library recommendations')
343
+ queries.push('Headless UI libraries for Tailwind CSS')
344
+ queries.push('Component library installation and setup')
345
+ }
346
+
347
+ if (category === 'designGuidelines') {
348
+ queries.push('Modern design trends 2025')
349
+ queries.push('Color palette generation tools')
350
+ queries.push('Typography pairing recommendations')
351
+ queries.push('Design system structure and organization')
352
+ }
353
+
354
+ return queries
355
+ }
356
+
357
+ // Helper functions
358
+ function extractPageType(desc: string): string {
359
+ const pageTypes = {
360
+ 'dashboard': 'Dashboard',
361
+ 'landing': 'Landing page',
362
+ 'e-commerce': 'E-commerce product page',
363
+ 'checkout': 'Checkout flow',
364
+ 'wizard': 'Multi-step wizard',
365
+ 'onboarding': 'User onboarding'
366
+ }
367
+
368
+ for (const [key, value] of Object.entries(pageTypes)) {
369
+ if (desc.toLowerCase().includes(key)) return value
370
+ }
371
+ return 'Page'
372
+ }
373
+
374
+ function extractComponent(desc: string): string {
375
+ const components = ['form', 'input', 'modal', 'navigation', 'menu', 'dialog', 'button', 'table', 'dropdown']
376
+ const found = components.find(c => desc.toLowerCase().includes(c))
377
+ return found ? found.charAt(0).toUpperCase() + found.slice(1) : 'Component'
378
+ }
379
+ ```
380
+
381
+ ---
382
+
383
+ ### 5. Subtask Breakdown
384
+
385
+ **When to break down:**
386
+ ```typescript
387
+ function needsSubtaskBreakdown(task: Task, complexity: number): boolean {
388
+ // Rule 1: High complexity
389
+ if (complexity >= 7) return true
390
+
391
+ // Rule 2: Multiple verbs (multi-step)
392
+ const verbs = task.description.match(/\b(create|build|implement|design|develop|add|update|refactor)\b/gi)
393
+ if (verbs && verbs.length > 2) return true
394
+
395
+ // Rule 3: Estimated time > 90 minutes
396
+ if (task.estimatedTime > 90) return true
397
+
398
+ // Rule 4: Explicit "and" connectors > 2
399
+ if (task.description.match(/\band\b/gi)?.length > 2) return true
400
+
401
+ return false
402
+ }
403
+
404
+ function generateSubtasks(task: Task): Subtask[] {
405
+ const subtasks = []
406
+
407
+ // Pattern 1: UI + Backend pattern
408
+ if (task.description.match(/ui|component|page/i) && task.description.match(/api|backend|endpoint/i)) {
409
+ subtasks.push({
410
+ id: `${task.id}.1`,
411
+ description: `Create UI component for ${extractEntity(task.description)}`,
412
+ type: 'uxui-frontend',
413
+ estimatedTime: 45
414
+ })
415
+ subtasks.push({
416
+ id: `${task.id}.2`,
417
+ description: `Create API endpoint for ${extractEntity(task.description)}`,
418
+ type: 'backend',
419
+ estimatedTime: 30
420
+ })
421
+ subtasks.push({
422
+ id: `${task.id}.3`,
423
+ description: `Integrate UI with API`,
424
+ type: 'frontend',
425
+ estimatedTime: 20
426
+ })
427
+ }
428
+
429
+ // Pattern 2: CRUD operations
430
+ if (task.description.match(/crud|create.*read.*update.*delete/i)) {
431
+ ['Create', 'Read', 'Update', 'Delete'].forEach((op, i) => {
432
+ subtasks.push({
433
+ id: `${task.id}.${i + 1}`,
434
+ description: `Implement ${op} operation for ${extractEntity(task.description)}`,
435
+ type: task.type,
436
+ estimatedTime: 20
437
+ })
438
+ })
439
+ }
440
+
441
+ // Pattern 3: Multi-entity
442
+ const entities = extractEntities(task.description)
443
+ if (entities.length > 1) {
444
+ entities.forEach((entity, i) => {
445
+ subtasks.push({
446
+ id: `${task.id}.${i + 1}`,
447
+ description: `${task.description.split(' ')[0]} ${entity}`,
448
+ type: task.type,
449
+ estimatedTime: Math.ceil(task.estimatedTime / entities.length)
450
+ })
451
+ })
452
+ }
453
+
454
+ return subtasks
455
+ }
456
+ ```
457
+
458
+ ---
459
+
460
+ ### 6. Priority Ranking
461
+
462
+ **Priority Score:**
463
+ ```typescript
464
+ function calculatePriority(task: Task, metadata: TaskMetadata): number {
465
+ let priority = 50 // Base priority
466
+
467
+ // Factor 1: Business value (from keywords)
468
+ const criticalKeywords = ['login', 'checkout', 'payment', 'core', 'critical']
469
+ if (criticalKeywords.some(kw => task.description.toLowerCase().includes(kw))) {
470
+ priority += 30
471
+ }
472
+
473
+ // Factor 2: Blocks other tasks
474
+ priority += metadata.dependencies.blocks.length * 10
475
+
476
+ // Factor 3: No blockers (can start immediately)
477
+ if (metadata.dependencies.blockedBy.length === 0) {
478
+ priority += 20
479
+ }
480
+
481
+ // Factor 4: Risk (high risk = higher priority to tackle early)
482
+ if (metadata.risk.level === 'HIGH') priority += 15
483
+ if (metadata.risk.level === 'MEDIUM') priority += 5
484
+
485
+ // Factor 5: Complexity (simpler = higher priority for quick wins)
486
+ if (metadata.complexity <= 3) priority += 10
487
+
488
+ // Factor 6: User-facing
489
+ if (task.type === 'uxui-frontend') priority += 10
490
+
491
+ return Math.min(priority, 100)
492
+ }
493
+
494
+ function getPriorityLabel(score: number): string {
495
+ if (score >= 80) return 'CRITICAL'
496
+ if (score >= 60) return 'HIGH'
497
+ if (score >= 40) return 'MEDIUM'
498
+ return 'LOW'
499
+ }
500
+ ```
501
+
502
+ ---
503
+
504
+ ## 📊 Output Format
505
+
506
+ ### Enhanced Task Metadata
507
+
508
+ ```typescript
509
+ interface TaskMetadata {
510
+ id: string
511
+ title: string
512
+ description: string
513
+ type: AgentType
514
+
515
+ // TaskMaster-style analysis
516
+ complexity: {
517
+ score: number // 1-10
518
+ level: 'Simple' | 'Moderate' | 'Complex' | 'Critical'
519
+ factors: string[] // What contributed to score
520
+ }
521
+
522
+ dependencies: {
523
+ blocks: string[] // Task IDs this blocks
524
+ blockedBy: string[] // Task IDs blocking this
525
+ parallelizable: string[] // Can run in parallel with
526
+ }
527
+
528
+ risk: {
529
+ level: 'LOW' | 'MEDIUM' | 'HIGH'
530
+ score: number
531
+ mitigation: string[] // Risk mitigation strategies
532
+ }
533
+
534
+ research: {
535
+ required: boolean
536
+ category?: string
537
+ queries?: string[]
538
+ estimatedTime?: number
539
+ } | null
540
+
541
+ subtasks: Subtask[] // If needs breakdown
542
+
543
+ priority: {
544
+ score: number // 0-100
545
+ label: 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW'
546
+ reason: string
547
+ }
548
+
549
+ estimatedTime: {
550
+ original: number // From OpenSpec
551
+ adjusted: number // With buffer for complexity/risk
552
+ buffer: number // Percentage added
553
+ }
554
+ }
555
+ ```
556
+
557
+ ---
558
+
559
+ ## 🔄 Usage in /csetup
560
+
561
+ **Integration Point: STEP 3.5 (after task detection, before template selection)**
562
+
563
+ ```typescript
564
+ // STEP 3.5: Analyze Tasks (TaskMaster-style)
565
+
566
+ const tasks = parseTasksFromMd(tasksContent)
567
+ const analyzedTasks = []
568
+
569
+ for (const task of tasks) {
570
+ const complexity = calculateComplexity(task)
571
+ const dependencies = detectDependencies(task, tasks)
572
+ const risk = assessRisk(task, complexity)
573
+ const research = detectResearchNeeds(task)
574
+ const needsBreakdown = needsSubtaskBreakdown(task, complexity)
575
+ const subtasks = needsBreakdown ? generateSubtasks(task) : []
576
+ const priority = calculatePriority(task, { complexity, dependencies, risk })
577
+
578
+ analyzedTasks.push({
579
+ ...task,
580
+ complexity: {
581
+ score: complexity,
582
+ level: getComplexityLevel(complexity),
583
+ factors: explainComplexity(task, complexity)
584
+ },
585
+ dependencies,
586
+ risk: {
587
+ ...risk,
588
+ mitigation: generateMitigation(risk, task)
589
+ },
590
+ research,
591
+ subtasks,
592
+ priority: {
593
+ score: priority,
594
+ label: getPriorityLabel(priority),
595
+ reason: explainPriority(task, priority)
596
+ },
597
+ estimatedTime: {
598
+ original: task.estimatedTime,
599
+ adjusted: adjustTimeForComplexity(task.estimatedTime, complexity, risk),
600
+ buffer: calculateBuffer(complexity, risk)
601
+ }
602
+ })
603
+ }
604
+
605
+ // Sort by priority
606
+ analyzedTasks.sort((a, b) => b.priority.score - a.priority.score)
607
+
608
+ // Report analysis
609
+ output(`
610
+ 📊 Task Analysis Complete
611
+
612
+ Total tasks: ${analyzedTasks.length}
613
+ Priority breakdown:
614
+ - CRITICAL: ${analyzedTasks.filter(t => t.priority.label === 'CRITICAL').length}
615
+ - HIGH: ${analyzedTasks.filter(t => t.priority.label === 'HIGH').length}
616
+ - MEDIUM: ${analyzedTasks.filter(t => t.priority.label === 'MEDIUM').length}
617
+ - LOW: ${analyzedTasks.filter(t => t.priority.label === 'LOW').length}
618
+
619
+ Risk assessment:
620
+ - HIGH risk: ${analyzedTasks.filter(t => t.risk.level === 'HIGH').length}
621
+ - MEDIUM risk: ${analyzedTasks.filter(t => t.risk.level === 'MEDIUM').length}
622
+
623
+ Research required: ${analyzedTasks.filter(t => t.research?.required).length} tasks
624
+
625
+ Subtask breakdown: ${analyzedTasks.filter(t => t.subtasks.length > 0).length} tasks expanded
626
+ `)
627
+ ```
628
+
629
+ ---
630
+
631
+ ## 📖 Helper Functions
632
+
633
+ ```typescript
634
+ function extractEntity(description: string): string {
635
+ // Extract main entity (User, Post, Comment, etc.)
636
+ const match = description.match(/\b([A-Z][a-z]+(?:\s+[A-Z][a-z]+)*)\b/)
637
+ return match ? match[1] : 'entity'
638
+ }
639
+
640
+ function extractEntities(description: string): string[] {
641
+ const entities = description.match(/\b([A-Z][a-z]+)\b/g) || []
642
+ return [...new Set(entities)] // Remove duplicates
643
+ }
644
+
645
+ function extractTechnology(description: string): string {
646
+ // Extract tech names (React, Next.js, Prisma, etc.)
647
+ const techPattern = /\b(React|Next\.js|Prisma|PostgreSQL|Redis|TypeScript|etc\.)\b/i
648
+ const match = description.match(techPattern)
649
+ return match ? match[1] : 'technology'
650
+ }
651
+
652
+ function extractServices(description: string): string[] {
653
+ // Extract service/API names
654
+ const services = description.match(/\b([A-Z][a-z]+(?:\s+API)?)\b/g) || []
655
+ return services.slice(0, 2) // First two
656
+ }
657
+
658
+ function getComplexityLevel(score: number): string {
659
+ if (score <= 3) return 'Simple'
660
+ if (score <= 6) return 'Moderate'
661
+ if (score <= 8) return 'Complex'
662
+ return 'Critical'
663
+ }
664
+
665
+ function adjustTimeForComplexity(time: number, complexity: number, risk: RiskLevel): number {
666
+ let adjusted = time
667
+
668
+ // Add buffer for complexity
669
+ if (complexity >= 7) adjusted *= 1.5
670
+ else if (complexity >= 5) adjusted *= 1.3
671
+
672
+ // Add buffer for risk
673
+ if (risk.level === 'HIGH') adjusted *= 1.5
674
+ else if (risk.level === 'MEDIUM') adjusted *= 1.2
675
+
676
+ return Math.ceil(adjusted)
677
+ }
678
+
679
+ function calculateBuffer(complexity: number, risk: RiskLevel): number {
680
+ let buffer = 0
681
+
682
+ if (complexity >= 7) buffer += 50
683
+ else if (complexity >= 5) buffer += 30
684
+
685
+ if (risk.level === 'HIGH') buffer += 50
686
+ else if (risk.level === 'MEDIUM') buffer += 20
687
+
688
+ return buffer
689
+ }
690
+ ```
691
+
692
+ ---
693
+
694
+ **This framework transforms simple tasks.md into intelligent, analyzed workflows! 🚀**