@champpaba/claude-agent-kit 2.3.0 → 2.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.
- package/.claude/CLAUDE.md +155 -24
- package/.claude/commands/csetup.md +643 -185
- package/.claude/commands/pageplan.md +30 -244
- package/README.md +30 -22
- package/package.json +1 -1
|
@@ -249,228 +249,686 @@ Continue anyway? (yes/no)
|
|
|
249
249
|
|
|
250
250
|
---
|
|
251
251
|
|
|
252
|
-
### Step 2.6:
|
|
252
|
+
### Step 2.6: Adaptive Depth Research (v2.4.0)
|
|
253
253
|
|
|
254
|
-
> **NEW:**
|
|
255
|
-
> **
|
|
254
|
+
> **NEW:** Dynamic research layers based on change complexity - replaces hardcoded feature detection
|
|
255
|
+
> **WHY:** Different changes need different research depth. A typo fix needs 0 layers, a healthcare portal needs 10+.
|
|
256
|
+
> **Output:** `openspec/changes/{changeId}/research-checklist.md`
|
|
256
257
|
|
|
257
|
-
|
|
258
|
+
**Key Principles:**
|
|
259
|
+
- Layer 1 is ALWAYS "Best Practice" (คนอื่นทำกันยังไง? / How do others do it?)
|
|
260
|
+
- Layer 2+ determined dynamically based on change context
|
|
261
|
+
- No fixed minimum or maximum - truly adaptive (0 to 10+ layers)
|
|
262
|
+
- Visual design (from /designsetup) is STATIC - this only handles Strategy (WHAT/WHERE)
|
|
263
|
+
- Warns if industry practice conflicts with user's design choices
|
|
258
264
|
|
|
259
265
|
```typescript
|
|
260
|
-
output(`\n
|
|
261
|
-
|
|
262
|
-
// 1.
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
266
|
+
output(`\n🔬 Adaptive Depth Research Analysis...`)
|
|
267
|
+
|
|
268
|
+
// 1. Gather change context from all spec files
|
|
269
|
+
const proposalPath = `openspec/changes/${changeId}/proposal.md`
|
|
270
|
+
const tasksPath = `openspec/changes/${changeId}/tasks.md`
|
|
271
|
+
const designPath = `openspec/changes/${changeId}/design.md`
|
|
272
|
+
|
|
273
|
+
const proposal = fileExists(proposalPath) ? Read(proposalPath) : ''
|
|
274
|
+
const tasks = fileExists(tasksPath) ? Read(tasksPath) : ''
|
|
275
|
+
const design = fileExists(designPath) ? Read(designPath) : ''
|
|
276
|
+
const combined = (proposal + '\n' + tasks + '\n' + design).toLowerCase()
|
|
277
|
+
|
|
278
|
+
// 2. Analyze change characteristics using semantic understanding
|
|
279
|
+
const changeAnalysis = analyzeChangeCharacteristics(combined, proposal, tasks)
|
|
280
|
+
|
|
281
|
+
output(`\n📊 Change Analysis:`)
|
|
282
|
+
output(` Type: ${changeAnalysis.primaryType}`)
|
|
283
|
+
output(` Complexity: ${changeAnalysis.complexity}/10`)
|
|
284
|
+
output(` Risk Level: ${changeAnalysis.riskLevel}`)
|
|
285
|
+
output(` Target Audience: ${changeAnalysis.audience || 'Internal'}`)
|
|
286
|
+
|
|
287
|
+
// 3. Determine required research layers based on change characteristics
|
|
288
|
+
const requiredLayers = determineResearchLayers(changeAnalysis)
|
|
289
|
+
|
|
290
|
+
output(`\n📚 Research Layers Required: ${requiredLayers.length}`)
|
|
291
|
+
|
|
292
|
+
if (requiredLayers.length === 0) {
|
|
293
|
+
output(` ✅ No research needed - trivial change`)
|
|
294
|
+
output(` (Typo fix, debug log, simple badge, etc.)`)
|
|
295
|
+
} else {
|
|
296
|
+
requiredLayers.forEach((layer, idx) => {
|
|
297
|
+
output(` L${idx + 1}: ${layer.name}`)
|
|
298
|
+
output(` Focus: ${layer.focus}`)
|
|
299
|
+
output(` Questions: ${layer.questions.slice(0, 2).join(', ')}...`)
|
|
300
|
+
})
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// 4. Execute research for each layer using Context7 + semantic analysis
|
|
304
|
+
const researchResults = []
|
|
305
|
+
|
|
306
|
+
for (const layer of requiredLayers) {
|
|
307
|
+
output(`\n🔍 Researching L${layer.order}: ${layer.name}...`)
|
|
308
|
+
|
|
309
|
+
const layerResult = await executeLayerResearch(layer, changeAnalysis)
|
|
310
|
+
researchResults.push(layerResult)
|
|
311
|
+
|
|
312
|
+
output(` ✅ Found ${layerResult.findings.length} key findings`)
|
|
313
|
+
if (layerResult.warnings.length > 0) {
|
|
314
|
+
layerResult.warnings.forEach(w => output(` ⚠️ ${w}`))
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// 5. Check for conflicts with design system (if exists)
|
|
319
|
+
const tokensPath = 'design-system/tokens.json'
|
|
320
|
+
if (fileExists(tokensPath) && researchResults.length > 0) {
|
|
321
|
+
const tokens = JSON.parse(Read(tokensPath))
|
|
322
|
+
const conflicts = checkDesignConflicts(tokens, researchResults, changeAnalysis)
|
|
323
|
+
|
|
324
|
+
if (conflicts.length > 0) {
|
|
325
|
+
output(`\n⚠️ Design vs Industry Fit Conflicts:`)
|
|
326
|
+
conflicts.forEach(c => {
|
|
327
|
+
output(` - ${c.aspect}: Your design uses "${c.current}", but ${c.industry}`)
|
|
328
|
+
output(` Recommendation: ${c.recommendation}`)
|
|
329
|
+
})
|
|
330
|
+
output(`\n Note: User design choices take precedence. These are informational warnings.`)
|
|
304
331
|
}
|
|
305
332
|
}
|
|
306
333
|
|
|
307
|
-
//
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
334
|
+
// 6. Generate research-checklist.md
|
|
335
|
+
const checklistPath = `openspec/changes/${changeId}/research-checklist.md`
|
|
336
|
+
const checklistContent = generateResearchChecklist(changeAnalysis, requiredLayers, researchResults)
|
|
337
|
+
|
|
338
|
+
Write(checklistPath, checklistContent)
|
|
339
|
+
output(`\n✅ Generated: ${checklistPath}`)
|
|
340
|
+
|
|
341
|
+
// Store for use by agents
|
|
342
|
+
const adaptiveResearch = {
|
|
343
|
+
layerCount: requiredLayers.length,
|
|
344
|
+
layers: requiredLayers.map(l => l.name),
|
|
345
|
+
complexity: changeAnalysis.complexity,
|
|
346
|
+
checklistPath: checklistPath
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
#### Helper Functions
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
// Analyze change characteristics using semantic understanding
|
|
354
|
+
function analyzeChangeCharacteristics(combined, proposal, tasks) {
|
|
355
|
+
const analysis = {
|
|
356
|
+
primaryType: 'general',
|
|
357
|
+
complexity: 1,
|
|
358
|
+
riskLevel: 'LOW',
|
|
359
|
+
audience: 'internal',
|
|
360
|
+
domains: [],
|
|
361
|
+
features: [],
|
|
362
|
+
hasUI: false,
|
|
363
|
+
hasAPI: false,
|
|
364
|
+
hasDatabase: false,
|
|
365
|
+
hasPayment: false,
|
|
366
|
+
hasAuth: false,
|
|
367
|
+
hasCompliance: false,
|
|
368
|
+
hasSensitiveData: false,
|
|
369
|
+
isExternalFacing: false,
|
|
370
|
+
industryContext: null
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Detect primary type
|
|
374
|
+
if (/marketing|landing|hero|cta|conversion|sales/i.test(combined)) {
|
|
375
|
+
analysis.primaryType = 'marketing'
|
|
376
|
+
analysis.isExternalFacing = true
|
|
377
|
+
} else if (/dashboard|admin|management|analytics/i.test(combined)) {
|
|
378
|
+
analysis.primaryType = 'dashboard'
|
|
379
|
+
} else if (/api|endpoint|rest|graphql/i.test(combined)) {
|
|
380
|
+
analysis.primaryType = 'api'
|
|
381
|
+
} else if (/auth|login|register|password/i.test(combined)) {
|
|
382
|
+
analysis.primaryType = 'auth'
|
|
383
|
+
analysis.hasAuth = true
|
|
384
|
+
} else if (/database|schema|migration|model/i.test(combined)) {
|
|
385
|
+
analysis.primaryType = 'database'
|
|
386
|
+
analysis.hasDatabase = true
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Detect features and domains
|
|
390
|
+
if (/payment|stripe|billing|checkout|subscription/i.test(combined)) {
|
|
391
|
+
analysis.hasPayment = true
|
|
392
|
+
analysis.features.push('payment')
|
|
393
|
+
analysis.riskLevel = 'HIGH'
|
|
394
|
+
}
|
|
395
|
+
if (/health|medical|patient|hipaa|phi/i.test(combined)) {
|
|
396
|
+
analysis.hasCompliance = true
|
|
397
|
+
analysis.hasSensitiveData = true
|
|
398
|
+
analysis.domains.push('healthcare')
|
|
399
|
+
analysis.industryContext = 'healthcare'
|
|
400
|
+
analysis.riskLevel = 'HIGH'
|
|
401
|
+
}
|
|
402
|
+
if (/fintech|banking|finance|pci|financial/i.test(combined)) {
|
|
403
|
+
analysis.hasCompliance = true
|
|
404
|
+
analysis.domains.push('fintech')
|
|
405
|
+
analysis.industryContext = 'fintech'
|
|
406
|
+
analysis.riskLevel = 'HIGH'
|
|
407
|
+
}
|
|
408
|
+
if (/saas|multi-tenant|tenant/i.test(combined)) {
|
|
409
|
+
analysis.domains.push('saas')
|
|
410
|
+
analysis.features.push('multi-tenancy')
|
|
411
|
+
}
|
|
412
|
+
if (/ecommerce|e-commerce|cart|product|shop/i.test(combined)) {
|
|
413
|
+
analysis.domains.push('ecommerce')
|
|
414
|
+
analysis.isExternalFacing = true
|
|
415
|
+
}
|
|
416
|
+
if (/realtime|real-time|websocket|collaboration/i.test(combined)) {
|
|
417
|
+
analysis.features.push('realtime')
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Detect UI/API/Database
|
|
421
|
+
analysis.hasUI = /ui|page|component|form|button|modal/i.test(combined)
|
|
422
|
+
analysis.hasAPI = /api|endpoint|route|controller/i.test(combined)
|
|
423
|
+
analysis.hasDatabase = analysis.hasDatabase || /table|column|relation|index/i.test(combined)
|
|
424
|
+
|
|
425
|
+
// Detect audience
|
|
426
|
+
if (/b2c|consumer|user|customer/i.test(combined)) {
|
|
427
|
+
analysis.audience = 'consumer'
|
|
428
|
+
analysis.isExternalFacing = true
|
|
429
|
+
} else if (/b2b|enterprise|business/i.test(combined)) {
|
|
430
|
+
analysis.audience = 'business'
|
|
431
|
+
analysis.isExternalFacing = true
|
|
312
432
|
}
|
|
433
|
+
|
|
434
|
+
// Calculate complexity (1-10)
|
|
435
|
+
let complexity = 1
|
|
436
|
+
if (analysis.features.length > 0) complexity += analysis.features.length
|
|
437
|
+
if (analysis.domains.length > 0) complexity += analysis.domains.length
|
|
438
|
+
if (analysis.hasCompliance) complexity += 2
|
|
439
|
+
if (analysis.hasPayment) complexity += 2
|
|
440
|
+
if (analysis.hasAuth) complexity += 1
|
|
441
|
+
if (analysis.isExternalFacing) complexity += 1
|
|
442
|
+
if (/integration|external api|third-party/i.test(combined)) complexity += 2
|
|
443
|
+
|
|
444
|
+
analysis.complexity = Math.min(complexity, 10)
|
|
445
|
+
|
|
446
|
+
// Adjust risk level
|
|
447
|
+
if (analysis.complexity >= 7 || analysis.hasCompliance || analysis.hasPayment) {
|
|
448
|
+
analysis.riskLevel = 'HIGH'
|
|
449
|
+
} else if (analysis.complexity >= 4 || analysis.hasAuth) {
|
|
450
|
+
analysis.riskLevel = 'MEDIUM'
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return analysis
|
|
313
454
|
}
|
|
314
455
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
456
|
+
// Determine research layers dynamically based on change characteristics
|
|
457
|
+
function determineResearchLayers(analysis) {
|
|
458
|
+
const layers = []
|
|
459
|
+
let order = 1
|
|
460
|
+
|
|
461
|
+
// Check for trivial changes (0 layers)
|
|
462
|
+
if (analysis.complexity <= 1 &&
|
|
463
|
+
!analysis.hasUI && !analysis.hasAPI && !analysis.hasDatabase &&
|
|
464
|
+
analysis.riskLevel === 'LOW') {
|
|
465
|
+
return [] // No research needed
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// L1: Best Practice (ALWAYS for non-trivial changes)
|
|
469
|
+
layers.push({
|
|
470
|
+
order: order++,
|
|
471
|
+
name: 'Best Practice / Industry Standard',
|
|
472
|
+
focus: `How do others implement ${analysis.primaryType}?`,
|
|
473
|
+
questions: [
|
|
474
|
+
`What is the industry standard for ${analysis.primaryType}?`,
|
|
475
|
+
'What are common patterns and anti-patterns?',
|
|
476
|
+
'What are the key success factors?',
|
|
477
|
+
'What are common failure modes?'
|
|
478
|
+
],
|
|
479
|
+
searchTopics: [`${analysis.primaryType} best practices`, `${analysis.primaryType} patterns`]
|
|
319
480
|
})
|
|
320
481
|
|
|
321
|
-
//
|
|
322
|
-
|
|
482
|
+
// L2+: Dynamic layers based on context
|
|
483
|
+
|
|
484
|
+
// Security layer (for auth, payment, sensitive data)
|
|
485
|
+
if (analysis.hasAuth || analysis.hasPayment || analysis.hasSensitiveData) {
|
|
486
|
+
layers.push({
|
|
487
|
+
order: order++,
|
|
488
|
+
name: 'Security Requirements',
|
|
489
|
+
focus: 'What security measures are required?',
|
|
490
|
+
questions: [
|
|
491
|
+
'What authentication/authorization is needed?',
|
|
492
|
+
'What data protection is required?',
|
|
493
|
+
'What are common security vulnerabilities?',
|
|
494
|
+
'What compliance requirements apply?'
|
|
495
|
+
],
|
|
496
|
+
searchTopics: ['security best practices', `${analysis.primaryType} security`]
|
|
497
|
+
})
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// Compliance layer (for regulated industries)
|
|
501
|
+
if (analysis.hasCompliance || analysis.industryContext) {
|
|
502
|
+
layers.push({
|
|
503
|
+
order: order++,
|
|
504
|
+
name: `${analysis.industryContext || 'Industry'} Compliance`,
|
|
505
|
+
focus: `What ${analysis.industryContext || 'industry'} regulations apply?`,
|
|
506
|
+
questions: [
|
|
507
|
+
'What regulatory requirements must be met?',
|
|
508
|
+
'What audit trails are needed?',
|
|
509
|
+
'What data handling rules apply?',
|
|
510
|
+
'What documentation is required?'
|
|
511
|
+
],
|
|
512
|
+
searchTopics: [`${analysis.industryContext} compliance`, `${analysis.industryContext} regulations`]
|
|
513
|
+
})
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// UX layer (for external-facing UI)
|
|
517
|
+
if (analysis.isExternalFacing && analysis.hasUI) {
|
|
518
|
+
layers.push({
|
|
519
|
+
order: order++,
|
|
520
|
+
name: 'User Experience Patterns',
|
|
521
|
+
focus: 'What UX patterns work for this audience?',
|
|
522
|
+
questions: [
|
|
523
|
+
'What user journey is expected?',
|
|
524
|
+
'What conversion patterns work?',
|
|
525
|
+
'What accessibility requirements apply?',
|
|
526
|
+
'What are user expectations?'
|
|
527
|
+
],
|
|
528
|
+
searchTopics: [`${analysis.primaryType} UX`, `${analysis.audience} UX patterns`]
|
|
529
|
+
})
|
|
530
|
+
}
|
|
323
531
|
|
|
324
|
-
|
|
325
|
-
|
|
532
|
+
// Psychology layer (for marketing/sales)
|
|
533
|
+
if (analysis.primaryType === 'marketing' || /conversion|sales|cta/i.test(analysis.primaryType)) {
|
|
534
|
+
layers.push({
|
|
535
|
+
order: order++,
|
|
536
|
+
name: 'Conversion Psychology',
|
|
537
|
+
focus: 'What psychological triggers work?',
|
|
538
|
+
questions: [
|
|
539
|
+
'What is the buyer awareness level?',
|
|
540
|
+
'What pain points to address?',
|
|
541
|
+
'What objections to overcome?',
|
|
542
|
+
'What social proof is needed?'
|
|
543
|
+
],
|
|
544
|
+
searchTopics: ['conversion psychology', 'landing page psychology']
|
|
545
|
+
})
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// Content Strategy layer (for content-heavy pages)
|
|
549
|
+
if (analysis.primaryType === 'marketing' || /content|blog|documentation/i.test(analysis.primaryType)) {
|
|
550
|
+
layers.push({
|
|
551
|
+
order: order++,
|
|
552
|
+
name: 'Content Strategy',
|
|
553
|
+
focus: 'What content structure works?',
|
|
554
|
+
questions: [
|
|
555
|
+
'What content hierarchy is effective?',
|
|
556
|
+
'What tone and voice to use?',
|
|
557
|
+
'What call-to-actions work?',
|
|
558
|
+
'What content gaps exist?'
|
|
559
|
+
],
|
|
560
|
+
searchTopics: ['content strategy', 'copywriting best practices']
|
|
561
|
+
})
|
|
562
|
+
}
|
|
326
563
|
|
|
327
|
-
|
|
328
|
-
|
|
564
|
+
// Data Architecture layer (for database/data-intensive)
|
|
565
|
+
if (analysis.hasDatabase || /data|analytics|reporting/i.test(analysis.primaryType)) {
|
|
566
|
+
layers.push({
|
|
567
|
+
order: order++,
|
|
568
|
+
name: 'Data Architecture',
|
|
569
|
+
focus: 'What data patterns are appropriate?',
|
|
570
|
+
questions: [
|
|
571
|
+
'What normalization level is appropriate?',
|
|
572
|
+
'What indexing strategy is needed?',
|
|
573
|
+
'What scaling considerations apply?',
|
|
574
|
+
'What data integrity rules?'
|
|
575
|
+
],
|
|
576
|
+
searchTopics: ['database design patterns', 'data architecture']
|
|
577
|
+
})
|
|
578
|
+
}
|
|
329
579
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
580
|
+
// API Design layer (for API-focused changes)
|
|
581
|
+
if (analysis.hasAPI || analysis.primaryType === 'api') {
|
|
582
|
+
layers.push({
|
|
583
|
+
order: order++,
|
|
584
|
+
name: 'API Design',
|
|
585
|
+
focus: 'What API patterns are appropriate?',
|
|
586
|
+
questions: [
|
|
587
|
+
'What API style is appropriate (REST/GraphQL)?',
|
|
588
|
+
'What versioning strategy?',
|
|
589
|
+
'What error handling patterns?',
|
|
590
|
+
'What rate limiting/throttling?'
|
|
591
|
+
],
|
|
592
|
+
searchTopics: ['API design best practices', 'REST API patterns']
|
|
593
|
+
})
|
|
594
|
+
}
|
|
334
595
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
596
|
+
// Multi-tenancy layer (for SaaS)
|
|
597
|
+
if (analysis.features.includes('multi-tenancy')) {
|
|
598
|
+
layers.push({
|
|
599
|
+
order: order++,
|
|
600
|
+
name: 'Multi-tenancy Patterns',
|
|
601
|
+
focus: 'What isolation and scaling patterns?',
|
|
602
|
+
questions: [
|
|
603
|
+
'What data isolation model?',
|
|
604
|
+
'What authentication per tenant?',
|
|
605
|
+
'What resource limits?',
|
|
606
|
+
'What billing model integration?'
|
|
607
|
+
],
|
|
608
|
+
searchTopics: ['multi-tenant architecture', 'SaaS patterns']
|
|
609
|
+
})
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// Real-time layer (for collaboration/live features)
|
|
613
|
+
if (analysis.features.includes('realtime')) {
|
|
614
|
+
layers.push({
|
|
615
|
+
order: order++,
|
|
616
|
+
name: 'Real-time Architecture',
|
|
617
|
+
focus: 'What real-time patterns are needed?',
|
|
618
|
+
questions: [
|
|
619
|
+
'WebSocket vs SSE vs polling?',
|
|
620
|
+
'What conflict resolution?',
|
|
621
|
+
'What offline support?',
|
|
622
|
+
'What scaling for connections?'
|
|
623
|
+
],
|
|
624
|
+
searchTopics: ['real-time architecture', 'WebSocket patterns']
|
|
625
|
+
})
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// Performance layer (for high-traffic or data-intensive)
|
|
629
|
+
if (analysis.isExternalFacing || analysis.complexity >= 6 ||
|
|
630
|
+
/performance|speed|optimization|cache/i.test(analysis.primaryType)) {
|
|
631
|
+
layers.push({
|
|
632
|
+
order: order++,
|
|
633
|
+
name: 'Performance Optimization',
|
|
634
|
+
focus: 'What performance patterns are needed?',
|
|
635
|
+
questions: [
|
|
636
|
+
'What caching strategy?',
|
|
637
|
+
'What lazy loading patterns?',
|
|
638
|
+
'What CDN/edge considerations?',
|
|
639
|
+
'What database optimization?'
|
|
640
|
+
],
|
|
641
|
+
searchTopics: ['performance optimization', 'caching strategies']
|
|
642
|
+
})
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// Integration layer (for external APIs/services)
|
|
646
|
+
if (/integration|external api|third-party|webhook/i.test(analysis.primaryType) ||
|
|
647
|
+
analysis.features.some(f => /payment|email|sms|notification/i.test(f))) {
|
|
648
|
+
layers.push({
|
|
649
|
+
order: order++,
|
|
650
|
+
name: 'Integration Patterns',
|
|
651
|
+
focus: 'What integration patterns are robust?',
|
|
652
|
+
questions: [
|
|
653
|
+
'What retry/circuit breaker patterns?',
|
|
654
|
+
'What error handling for external failures?',
|
|
655
|
+
'What monitoring/alerting?',
|
|
656
|
+
'What idempotency requirements?'
|
|
657
|
+
],
|
|
658
|
+
searchTopics: ['integration patterns', 'API integration best practices']
|
|
659
|
+
})
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// Testing Strategy layer (for complex/high-risk)
|
|
663
|
+
if (analysis.riskLevel === 'HIGH' || analysis.complexity >= 7) {
|
|
664
|
+
layers.push({
|
|
665
|
+
order: order++,
|
|
666
|
+
name: 'Testing Strategy',
|
|
667
|
+
focus: 'What testing coverage is needed?',
|
|
668
|
+
questions: [
|
|
669
|
+
'What unit vs integration vs e2e balance?',
|
|
670
|
+
'What edge cases to cover?',
|
|
671
|
+
'What load/stress testing?',
|
|
672
|
+
'What security testing?'
|
|
673
|
+
],
|
|
674
|
+
searchTopics: ['testing strategy', `${analysis.primaryType} testing`]
|
|
675
|
+
})
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
return layers
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// Execute research for a single layer using Claude's knowledge
|
|
682
|
+
// WHY: Domain knowledge (UX, DB design, security patterns) comes from Claude's training
|
|
683
|
+
// Stack knowledge (Prisma, React) comes from Context7 in Step 2.7
|
|
684
|
+
function executeLayerResearch(layer, changeAnalysis) {
|
|
685
|
+
const result = {
|
|
686
|
+
layer: layer.name,
|
|
687
|
+
findings: [],
|
|
688
|
+
recommendations: [],
|
|
689
|
+
warnings: [],
|
|
690
|
+
source: 'claude-knowledge'
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
// Claude generates best practices based on:
|
|
694
|
+
// - Layer context (what domain?)
|
|
695
|
+
// - Change analysis (what's being built?)
|
|
696
|
+
// - Questions to answer (what to research?)
|
|
697
|
+
//
|
|
698
|
+
// Claude's training includes:
|
|
699
|
+
// - UX: Nielsen Norman, Baymard Institute, Laws of UX
|
|
700
|
+
// - Database: Codd's normalization, indexing patterns
|
|
701
|
+
// - Security: OWASP, auth patterns, encryption
|
|
702
|
+
// - API: REST dissertation, versioning patterns
|
|
703
|
+
// - Architecture: distributed systems, caching, scaling
|
|
704
|
+
|
|
705
|
+
result.findings = generateDomainKnowledge(layer, changeAnalysis)
|
|
706
|
+
result.recommendations = generateRecommendations(layer, changeAnalysis)
|
|
707
|
+
result.warnings = checkForWarnings(layer, changeAnalysis)
|
|
708
|
+
|
|
709
|
+
return result
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// Generate domain knowledge using Claude's reasoning
|
|
713
|
+
// This is where Claude applies its training to the specific change
|
|
714
|
+
function generateDomainKnowledge(layer, changeAnalysis) {
|
|
715
|
+
const findings = []
|
|
716
|
+
|
|
717
|
+
// Based on layer type, Claude will reason about best practices
|
|
718
|
+
// The actual content comes from Claude's response when /csetup runs
|
|
719
|
+
|
|
720
|
+
findings.push({
|
|
721
|
+
question: layer.questions[0],
|
|
722
|
+
// Claude fills this based on its knowledge when executing
|
|
723
|
+
analysis: `[Claude analyzes: ${layer.focus}]`,
|
|
724
|
+
bestPractices: [], // Claude lists industry standards
|
|
725
|
+
antiPatterns: [], // Claude lists what to avoid
|
|
726
|
+
tradeoffs: [] // Claude explains trade-offs
|
|
727
|
+
})
|
|
728
|
+
|
|
729
|
+
return findings
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// Check for conflicts between design system and industry practices
|
|
733
|
+
function checkDesignConflicts(tokens, researchResults, changeAnalysis) {
|
|
734
|
+
const conflicts = []
|
|
735
|
+
|
|
736
|
+
// Only check for marketing/external-facing changes
|
|
737
|
+
if (!changeAnalysis.isExternalFacing) return conflicts
|
|
738
|
+
|
|
739
|
+
// Check color appropriateness for industry
|
|
740
|
+
if (tokens.colors && changeAnalysis.industryContext) {
|
|
741
|
+
const primaryColor = tokens.colors.primary
|
|
742
|
+
|
|
743
|
+
if (changeAnalysis.industryContext === 'healthcare') {
|
|
744
|
+
// Healthcare typically uses blue/green (trust, calm)
|
|
745
|
+
if (/red|orange|yellow/i.test(primaryColor)) {
|
|
746
|
+
conflicts.push({
|
|
747
|
+
aspect: 'Primary Color',
|
|
748
|
+
current: primaryColor,
|
|
749
|
+
industry: 'healthcare typically uses blue/green for trust and calm',
|
|
750
|
+
recommendation: 'Consider if bright colors are appropriate for healthcare context'
|
|
343
751
|
})
|
|
344
752
|
}
|
|
345
753
|
}
|
|
346
754
|
|
|
347
|
-
if (
|
|
348
|
-
|
|
755
|
+
if (changeAnalysis.industryContext === 'fintech') {
|
|
756
|
+
// Fintech typically uses blue/green (trust, money)
|
|
757
|
+
if (/pink|purple|orange/i.test(primaryColor)) {
|
|
758
|
+
conflicts.push({
|
|
759
|
+
aspect: 'Primary Color',
|
|
760
|
+
current: primaryColor,
|
|
761
|
+
industry: 'fintech typically uses blue/green for trust and stability',
|
|
762
|
+
recommendation: 'Consider if playful colors fit financial services context'
|
|
763
|
+
})
|
|
764
|
+
}
|
|
349
765
|
}
|
|
766
|
+
}
|
|
350
767
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
768
|
+
// Check animation appropriateness
|
|
769
|
+
if (tokens.animations && changeAnalysis.hasCompliance) {
|
|
770
|
+
if (tokens.animations.enableScrollAnimations) {
|
|
771
|
+
conflicts.push({
|
|
772
|
+
aspect: 'Scroll Animations',
|
|
773
|
+
current: 'enabled',
|
|
774
|
+
industry: 'compliance-heavy sites often minimize animations for accessibility',
|
|
775
|
+
recommendation: 'Ensure animations have reduced-motion alternatives'
|
|
776
|
+
})
|
|
354
777
|
}
|
|
355
778
|
}
|
|
356
779
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
const tier2Gaps = allGaps.filter(g => g.tier === 2)
|
|
360
|
-
|
|
361
|
-
if (tier1Gaps.length > 0) {
|
|
362
|
-
output(`\n⚠️ Security-Critical Gaps Found (Tier 1)`)
|
|
363
|
-
output(``)
|
|
364
|
-
output(`Your spec is missing these industry-standard requirements:`)
|
|
365
|
-
output(``)
|
|
366
|
-
|
|
367
|
-
// Group by feature
|
|
368
|
-
const byFeature = {}
|
|
369
|
-
tier1Gaps.forEach(g => {
|
|
370
|
-
if (!byFeature[g.feature]) byFeature[g.feature] = []
|
|
371
|
-
byFeature[g.feature].push(g.requirement)
|
|
372
|
-
})
|
|
780
|
+
return conflicts
|
|
781
|
+
}
|
|
373
782
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
783
|
+
// Generate research checklist markdown
|
|
784
|
+
function generateResearchChecklist(changeAnalysis, layers, results) {
|
|
785
|
+
let content = `# Research Checklist: ${changeAnalysis.primaryType}\n\n`
|
|
786
|
+
content += `> Generated by Adaptive Depth Research (v2.4.0)\n`
|
|
787
|
+
content += `> Complexity: ${changeAnalysis.complexity}/10 | Risk: ${changeAnalysis.riskLevel}\n\n`
|
|
788
|
+
|
|
789
|
+
if (layers.length === 0) {
|
|
790
|
+
content += `## ✅ No Research Required\n\n`
|
|
791
|
+
content += `This is a trivial change (complexity ${changeAnalysis.complexity}/10).\n`
|
|
792
|
+
content += `Proceed directly with implementation.\n`
|
|
793
|
+
return content
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
content += `## Summary\n\n`
|
|
797
|
+
content += `| Layer | Focus | Status |\n`
|
|
798
|
+
content += `|-------|-------|--------|\n`
|
|
799
|
+
layers.forEach((layer, idx) => {
|
|
800
|
+
content += `| L${idx + 1}: ${layer.name} | ${layer.focus} | ⏳ Pending |\n`
|
|
801
|
+
})
|
|
802
|
+
|
|
803
|
+
content += `\n---\n\n`
|
|
378
804
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
question: 'How would you like to handle the security gaps?',
|
|
389
|
-
header: 'Spec Gaps',
|
|
390
|
-
options: [
|
|
391
|
-
{ label: 'A) Update spec', description: 'Add missing requirements to design.md (recommended)' },
|
|
392
|
-
{ label: 'B) Document skip', description: 'Record justification for skipping' },
|
|
393
|
-
{ label: 'C) Continue anyway', description: 'Proceed with gap (security risk)' }
|
|
394
|
-
],
|
|
395
|
-
multiSelect: false
|
|
396
|
-
}]
|
|
805
|
+
// Detail each layer
|
|
806
|
+
results.forEach((result, idx) => {
|
|
807
|
+
const layer = layers[idx]
|
|
808
|
+
content += `## L${idx + 1}: ${layer.name}\n\n`
|
|
809
|
+
content += `**Focus:** ${layer.focus}\n\n`
|
|
810
|
+
|
|
811
|
+
content += `### Key Questions\n\n`
|
|
812
|
+
layer.questions.forEach(q => {
|
|
813
|
+
content += `- [ ] ${q}\n`
|
|
397
814
|
})
|
|
398
815
|
|
|
399
|
-
if (
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
reqs.forEach(r => output(`- ${r}`))
|
|
410
|
-
}
|
|
411
|
-
output(``)
|
|
412
|
-
output(`**Source:** Feature Best Practice Validation`)
|
|
413
|
-
output(`**Added:** ${new Date().toISOString().split('T')[0]}`)
|
|
414
|
-
output(`\`\`\``)
|
|
415
|
-
output(``)
|
|
416
|
-
output(`Please update design.md and re-run /csetup.`)
|
|
417
|
-
return
|
|
418
|
-
} else if (decision.includes('B')) {
|
|
419
|
-
// Document conscious skip
|
|
420
|
-
output(`\n📝 Add this to design.md to document the skip:\n`)
|
|
421
|
-
output(`\`\`\`markdown`)
|
|
422
|
-
output(`### D{n}: Conscious Security Trade-offs`)
|
|
423
|
-
output(``)
|
|
424
|
-
output(`**Skipped requirements (with justification):**`)
|
|
425
|
-
output(``)
|
|
426
|
-
output(`| Requirement | Why Skipped | Risk Level | Mitigation |`)
|
|
427
|
-
output(`|-------------|-------------|------------|------------|`)
|
|
428
|
-
for (const gap of tier1Gaps) {
|
|
429
|
-
output(`| ${gap.requirement} | [YOUR REASON] | [LOW/MED/HIGH] | [YOUR MITIGATION] |`)
|
|
430
|
-
}
|
|
431
|
-
output(``)
|
|
432
|
-
output(`**Acknowledged by:** User decision in /csetup`)
|
|
433
|
-
output(`**Date:** ${new Date().toISOString().split('T')[0]}`)
|
|
434
|
-
output(`\`\`\``)
|
|
435
|
-
output(``)
|
|
436
|
-
|
|
437
|
-
const confirm = await askUserQuestion({
|
|
438
|
-
questions: [{
|
|
439
|
-
question: 'Confirm you will document this in design.md?',
|
|
440
|
-
header: 'Confirm',
|
|
441
|
-
options: [
|
|
442
|
-
{ label: 'Yes, continue', description: 'I will add documentation' },
|
|
443
|
-
{ label: 'Cancel', description: 'Go back and update spec' }
|
|
444
|
-
],
|
|
445
|
-
multiSelect: false
|
|
446
|
-
}]
|
|
816
|
+
if (result.findings.length > 0) {
|
|
817
|
+
content += `\n### Findings\n\n`
|
|
818
|
+
result.findings.forEach(f => {
|
|
819
|
+
content += `#### ${f.topic}\n\n`
|
|
820
|
+
if (Array.isArray(f.content)) {
|
|
821
|
+
f.content.forEach(point => content += `- ${point}\n`)
|
|
822
|
+
} else {
|
|
823
|
+
content += `${f.content}\n`
|
|
824
|
+
}
|
|
825
|
+
content += `\n*Source: ${f.source}*\n\n`
|
|
447
826
|
})
|
|
827
|
+
}
|
|
448
828
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
829
|
+
if (result.recommendations.length > 0) {
|
|
830
|
+
content += `### Recommendations\n\n`
|
|
831
|
+
result.recommendations.forEach(r => {
|
|
832
|
+
content += `- ${r}\n`
|
|
833
|
+
})
|
|
453
834
|
}
|
|
454
|
-
|
|
835
|
+
|
|
836
|
+
if (result.warnings.length > 0) {
|
|
837
|
+
content += `\n### ⚠️ Warnings\n\n`
|
|
838
|
+
result.warnings.forEach(w => {
|
|
839
|
+
content += `- ${w}\n`
|
|
840
|
+
})
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
content += `\n---\n\n`
|
|
844
|
+
})
|
|
845
|
+
|
|
846
|
+
// Add Content Guidelines section for marketing pages
|
|
847
|
+
if (changeAnalysis.primaryType === 'marketing' || changeAnalysis.isExternalFacing) {
|
|
848
|
+
content += `## 📝 Content Guidelines\n\n`
|
|
849
|
+
content += `> Claude generates these guidelines based on the change context.\n`
|
|
850
|
+
content += `> Use these as a starting point for content creation.\n\n`
|
|
851
|
+
|
|
852
|
+
content += `### Hero Section\n\n`
|
|
853
|
+
content += `**Headline Strategy:**\n`
|
|
854
|
+
content += `- Lead with primary pain point or aspiration\n`
|
|
855
|
+
content += `- 8-12 words, emotional trigger\n`
|
|
856
|
+
content += `- [Claude: Generate specific headline angle based on proposal]\n\n`
|
|
857
|
+
|
|
858
|
+
content += `**Subheadline:**\n`
|
|
859
|
+
content += `- Concrete benefit + emotional payoff\n`
|
|
860
|
+
content += `- 15-25 words\n`
|
|
861
|
+
content += `- [Claude: Generate based on value proposition]\n\n`
|
|
862
|
+
|
|
863
|
+
content += `**CTA:**\n`
|
|
864
|
+
content += `- Action verb + outcome\n`
|
|
865
|
+
content += `- [Claude: Generate based on user journey stage]\n\n`
|
|
866
|
+
|
|
867
|
+
content += `### Value Proposition\n\n`
|
|
868
|
+
content += `For each feature, translate to:\n`
|
|
869
|
+
content += `| Feature | Benefit | Emotional Payoff |\n`
|
|
870
|
+
content += `|---------|---------|------------------|\n`
|
|
871
|
+
content += `| [Technical] | [What user gets] | [How it makes them feel] |\n\n`
|
|
872
|
+
|
|
873
|
+
content += `### Social Proof\n\n`
|
|
874
|
+
content += `- Use specific results (numbers, timeframes)\n`
|
|
875
|
+
content += `- Match testimonials to target audience\n`
|
|
876
|
+
content += `- Include trust signals (logos, certifications)\n\n`
|
|
877
|
+
|
|
878
|
+
content += `---\n\n`
|
|
455
879
|
}
|
|
456
880
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
881
|
+
content += `## Agent Instructions\n\n`
|
|
882
|
+
content += `When implementing this change, agents should:\n\n`
|
|
883
|
+
content += `1. Review each layer's findings before starting\n`
|
|
884
|
+
content += `2. Check off questions as they are addressed\n`
|
|
885
|
+
content += `3. Follow recommendations where applicable\n`
|
|
886
|
+
content += `4. Address warnings or document exceptions\n`
|
|
887
|
+
|
|
888
|
+
if (changeAnalysis.primaryType === 'marketing' || changeAnalysis.isExternalFacing) {
|
|
889
|
+
content += `5. Use Content Guidelines section for copy direction\n`
|
|
463
890
|
}
|
|
464
|
-
|
|
465
|
-
|
|
891
|
+
|
|
892
|
+
return content
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
// Helper: Generate recommendations based on layer and context
|
|
896
|
+
// Claude fills in actual recommendations when executing /csetup
|
|
897
|
+
function generateRecommendations(layer, changeAnalysis) {
|
|
898
|
+
// These are prompts for Claude to expand with actual knowledge
|
|
899
|
+
// When /csetup runs, Claude will provide specific recommendations
|
|
900
|
+
|
|
901
|
+
return [
|
|
902
|
+
`[Claude: Based on ${layer.name} best practices for ${changeAnalysis.primaryType}]`,
|
|
903
|
+
`[Claude: Specific to this change's context and requirements]`
|
|
904
|
+
]
|
|
466
905
|
}
|
|
467
906
|
|
|
468
|
-
//
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
907
|
+
// Helper: Check for potential warnings based on layer and context
|
|
908
|
+
function checkForWarnings(layer, changeAnalysis) {
|
|
909
|
+
const warnings = []
|
|
910
|
+
|
|
911
|
+
// Risk-based warnings
|
|
912
|
+
if (changeAnalysis.riskLevel === 'HIGH') {
|
|
913
|
+
warnings.push(`HIGH risk change - review ${layer.name} carefully before deployment`)
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// Compliance warnings
|
|
917
|
+
if (layer.name.includes('Compliance') && changeAnalysis.hasCompliance) {
|
|
918
|
+
warnings.push(`Regulatory compliance required - ensure all ${changeAnalysis.industryContext} requirements are met`)
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
// Payment warnings
|
|
922
|
+
if (changeAnalysis.hasPayment) {
|
|
923
|
+
warnings.push('Payment integration - ensure PCI compliance requirements are met')
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// Security warnings
|
|
927
|
+
if (layer.name.includes('Security') && changeAnalysis.hasSensitiveData) {
|
|
928
|
+
warnings.push('Sensitive data handling - ensure proper encryption and access controls')
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
return warnings
|
|
474
932
|
}
|
|
475
933
|
```
|
|
476
934
|
|