@champpaba/claude-agent-kit 2.7.0 → 2.8.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 (44) hide show
  1. package/.claude/CLAUDE.md +49 -0
  2. package/.claude/commands/csetup.md +364 -38
  3. package/.claude/commands/cview.md +364 -364
  4. package/.claude/contexts/design/accessibility.md +611 -611
  5. package/.claude/contexts/design/layout.md +400 -400
  6. package/.claude/contexts/design/responsive.md +551 -551
  7. package/.claude/contexts/design/shadows.md +522 -522
  8. package/.claude/contexts/design/typography.md +465 -465
  9. package/.claude/contexts/domain/README.md +164 -164
  10. package/.claude/contexts/patterns/agent-coordination.md +388 -388
  11. package/.claude/contexts/patterns/development-principles.md +513 -513
  12. package/.claude/contexts/patterns/error-handling.md +478 -478
  13. package/.claude/contexts/patterns/logging.md +424 -424
  14. package/.claude/contexts/patterns/tdd-classification.md +516 -516
  15. package/.claude/contexts/patterns/testing.md +413 -413
  16. package/.claude/lib/tdd-classifier.md +345 -345
  17. package/.claude/lib/validation-gates.md +484 -484
  18. package/.claude/settings.local.json +42 -42
  19. package/.claude/templates/context-template.md +45 -45
  20. package/.claude/templates/flags-template.json +42 -42
  21. package/.claude/templates/phases-sections/accessibility-test.md +17 -17
  22. package/.claude/templates/phases-sections/api-design.md +37 -37
  23. package/.claude/templates/phases-sections/backend-tests.md +16 -16
  24. package/.claude/templates/phases-sections/backend.md +37 -37
  25. package/.claude/templates/phases-sections/business-logic-validation.md +16 -16
  26. package/.claude/templates/phases-sections/component-tests.md +17 -17
  27. package/.claude/templates/phases-sections/contract-backend.md +16 -16
  28. package/.claude/templates/phases-sections/contract-frontend.md +16 -16
  29. package/.claude/templates/phases-sections/database.md +35 -35
  30. package/.claude/templates/phases-sections/e2e-tests.md +16 -16
  31. package/.claude/templates/phases-sections/fix-implementation.md +17 -17
  32. package/.claude/templates/phases-sections/frontend-integration.md +18 -18
  33. package/.claude/templates/phases-sections/manual-flow-test.md +15 -15
  34. package/.claude/templates/phases-sections/manual-ux-test.md +16 -16
  35. package/.claude/templates/phases-sections/refactor-implementation.md +17 -17
  36. package/.claude/templates/phases-sections/refactor.md +16 -16
  37. package/.claude/templates/phases-sections/regression-tests.md +15 -15
  38. package/.claude/templates/phases-sections/responsive-test.md +16 -16
  39. package/.claude/templates/phases-sections/script-implementation.md +43 -43
  40. package/.claude/templates/phases-sections/test-coverage.md +16 -16
  41. package/.claude/templates/phases-sections/user-approval.md +14 -14
  42. package/LICENSE +21 -21
  43. package/README.md +25 -0
  44. package/package.json +8 -4
package/.claude/CLAUDE.md CHANGED
@@ -302,6 +302,55 @@ User: "Build login system"
302
302
 
303
303
  ---
304
304
 
305
+ ## šŸ†• v2.8.0: Critical Flow Injection
306
+
307
+ **Problem Solved:** Research layers are flexible and context-dependent, but security/compliance items are non-negotiable. Previously, critical requirements like password hashing, PCI-DSS compliance, or HIPAA regulations could be missed if research didn't surface them.
308
+
309
+ **Solution:** Auto-inject critical required items into research layers based on change analysis.
310
+
311
+ ### How It Works
312
+
313
+ ```
314
+ /csetup analyzes change:
315
+ ā”œā”€ā”€ hasAuth: true → Inject auth security items (7 items)
316
+ ā”œā”€ā”€ hasPayment: true → Inject payment security items (5 items)
317
+ ā”œā”€ā”€ industryContext: healthcare → Inject HIPAA compliance items (5 items)
318
+ └── industryContext: fintech → Inject PCI-DSS compliance items (6 items)
319
+
320
+ Research layers (flexible) + Critical items (non-negotiable)
321
+ ```
322
+
323
+ ### Critical Flow Categories
324
+
325
+ | Flow | Layer | Items | Examples |
326
+ |------|-------|-------|----------|
327
+ | Auth | Security | 7 | Password hashing (bcrypt/argon2), JWT secure storage, session timeout |
328
+ | Payment | Security | 5 | PCI key security, no card storage, webhook signature verification |
329
+ | Healthcare | Compliance | 5 | PHI encryption, role-based access, audit trail, BAA, breach plan |
330
+ | Fintech | Compliance | 6 | Data encryption, key rotation, audit logging, access controls |
331
+ | Sensitive Data | Security + Data Architecture | 6 | Encryption at rest/transit, access logging, backup, retention |
332
+
333
+ ### Item Structure
334
+
335
+ Each critical item has:
336
+ ```javascript
337
+ {
338
+ id: 'auth-password-hash', // Unique identifier
339
+ check: '☐ Password hashing...', // Checklist item
340
+ why: 'Plain text passwords...', // Explanation
341
+ severity: 'critical' // Always 'critical'
342
+ }
343
+ ```
344
+
345
+ ### Files Changed
346
+
347
+ | File | Change |
348
+ |------|--------|
349
+ | `tests/helpers.js` | `CRITICAL_FLOWS` constant + `injectCriticalRequiredItems()` function |
350
+ | `csetup.md` Step 2.6 | Calls `injectCriticalRequiredItems()` for each layer |
351
+
352
+ ---
353
+
305
354
  ## šŸ†• v2.7.0: UX Testing Agent (Persona-Based)
306
355
 
307
356
  **Problem Solved:** UI was approved by developers, not real users. No validation that the UI actually converts customers before spending time on backend development.
@@ -189,7 +189,7 @@ if (hasFrontend) {
189
189
 
190
190
  // ========== LOAD data.yaml (v2.0 structure) ==========
191
191
  if (hasTokens) {
192
- tokens = JSON.parse(Read(tokensPath))
192
+ tokens = parseYaml(Read(tokensPath))
193
193
  output(`āœ… data.yaml Loaded:`)
194
194
  output(` - Style: ${tokens.style.name}`)
195
195
  output(` - Theme: ${tokens.theme.name}`)
@@ -212,7 +212,7 @@ if (hasFrontend) {
212
212
  output(` → Run /pageplan first for better component planning`)
213
213
  }
214
214
 
215
- if (!hasTokens || !hasStyleGuide) {
215
+ if (!hasTokens || !hasReadme) {
216
216
  warn(`
217
217
  āš ļø WARNING: UI work detected but design system incomplete!
218
218
 
@@ -318,7 +318,7 @@ for (const layer of requiredLayers) {
318
318
  // 5. Check for conflicts with design system (if exists)
319
319
  const tokensPath = 'design-system/data.yaml'
320
320
  if (fileExists(tokensPath) && researchResults.length > 0) {
321
- const tokens = JSON.parse(Read(tokensPath))
321
+ const tokens = parseYaml(Read(tokensPath))
322
322
  const conflicts = checkDesignConflicts(tokens, researchResults, changeAnalysis)
323
323
 
324
324
  if (conflicts.length > 0) {
@@ -687,6 +687,7 @@ function executeLayerResearch(layer, changeAnalysis) {
687
687
  findings: [],
688
688
  recommendations: [],
689
689
  warnings: [],
690
+ requiredItems: [], // Critical checklist items that MUST be addressed
690
691
  source: 'claude-knowledge'
691
692
  }
692
693
 
@@ -706,9 +707,325 @@ function executeLayerResearch(layer, changeAnalysis) {
706
707
  result.recommendations = generateRecommendations(layer, changeAnalysis)
707
708
  result.warnings = checkForWarnings(layer, changeAnalysis)
708
709
 
710
+ // Inject critical required items based on layer and context
711
+ // WHY: These are non-negotiable security/compliance requirements
712
+ result.requiredItems = injectCriticalRequiredItems(layer, changeAnalysis)
713
+
709
714
  return result
710
715
  }
711
716
 
717
+ // ============================================================
718
+ // CRITICAL FLOW REQUIREMENTS (v2.8.0)
719
+ // ============================================================
720
+ // These are non-negotiable items that MUST be in the checklist
721
+ // WHY: Security/compliance failures have legal/financial consequences
722
+
723
+ /**
724
+ * Inject critical required items based on layer type and change context
725
+ * Returns checklist items that agents MUST verify are implemented
726
+ */
727
+ function injectCriticalRequiredItems(layer, changeAnalysis) {
728
+ const items = []
729
+
730
+ // Security Requirements Layer
731
+ if (layer.name === 'Security Requirements') {
732
+ // Auth-related critical items
733
+ if (changeAnalysis.hasAuth) {
734
+ items.push(...CRITICAL_FLOWS.auth.security)
735
+ }
736
+ // Payment-related critical items
737
+ if (changeAnalysis.hasPayment) {
738
+ items.push(...CRITICAL_FLOWS.payment.security)
739
+ }
740
+ // Sensitive data handling
741
+ if (changeAnalysis.hasSensitiveData) {
742
+ items.push(...CRITICAL_FLOWS.sensitiveData.security)
743
+ }
744
+ }
745
+
746
+ // Compliance Layer
747
+ if (layer.name.includes('Compliance')) {
748
+ if (changeAnalysis.industryContext === 'healthcare') {
749
+ items.push(...CRITICAL_FLOWS.healthcare.compliance)
750
+ }
751
+ if (changeAnalysis.industryContext === 'fintech') {
752
+ items.push(...CRITICAL_FLOWS.fintech.compliance)
753
+ }
754
+ }
755
+
756
+ // Data Architecture Layer
757
+ if (layer.name === 'Data Architecture') {
758
+ if (changeAnalysis.hasSensitiveData) {
759
+ items.push(...CRITICAL_FLOWS.sensitiveData.dataArchitecture)
760
+ }
761
+ }
762
+
763
+ return items
764
+ }
765
+
766
+ /**
767
+ * Critical Flow Definitions
768
+ * Format: { category: { layer: [...items] } }
769
+ * Each item has: id, check, why, severity
770
+ */
771
+ const CRITICAL_FLOWS = {
772
+ // ============================================================
773
+ // AUTH CRITICAL FLOWS
774
+ // ============================================================
775
+ auth: {
776
+ security: [
777
+ {
778
+ id: 'auth-password-hash',
779
+ check: '☐ Password hashing with bcrypt/argon2 (cost factor ≄ 10)',
780
+ why: 'Plain text or weak hashing = immediate breach if DB leaked',
781
+ severity: 'critical'
782
+ },
783
+ {
784
+ id: 'auth-rate-limit',
785
+ check: '☐ Rate limiting on login (max 5 attempts per 15 min)',
786
+ why: 'Prevents brute force attacks',
787
+ severity: 'critical'
788
+ },
789
+ {
790
+ id: 'auth-session-timeout',
791
+ check: '☐ Session timeout configured (≤ 24h, ≤ 15min for sensitive)',
792
+ why: 'Abandoned sessions are attack vectors',
793
+ severity: 'high'
794
+ },
795
+ {
796
+ id: 'auth-csrf',
797
+ check: '☐ CSRF protection on all state-changing endpoints',
798
+ why: 'OWASP Top 10 vulnerability',
799
+ severity: 'critical'
800
+ },
801
+ {
802
+ id: 'auth-secure-cookies',
803
+ check: '☐ Cookies: httpOnly, secure, sameSite=strict',
804
+ why: 'Prevents XSS token theft and CSRF',
805
+ severity: 'critical'
806
+ },
807
+ {
808
+ id: 'auth-password-policy',
809
+ check: '☐ Password policy enforced (min 8 chars, complexity optional)',
810
+ why: 'Weak passwords are #1 breach cause',
811
+ severity: 'high'
812
+ },
813
+ {
814
+ id: 'auth-account-lockout',
815
+ check: '☐ Account lockout after repeated failures (with unlock mechanism)',
816
+ why: 'Prevents brute force, but needs recovery path',
817
+ severity: 'medium'
818
+ }
819
+ ],
820
+ flow: [
821
+ {
822
+ id: 'auth-flow-login',
823
+ check: '☐ Login flow: input → validate → session → redirect',
824
+ why: 'Standard secure login pattern',
825
+ severity: 'high'
826
+ },
827
+ {
828
+ id: 'auth-flow-logout',
829
+ check: '☐ Logout: invalidate session server-side (not just cookie)',
830
+ why: 'Client-side only logout leaves session valid',
831
+ severity: 'high'
832
+ },
833
+ {
834
+ id: 'auth-flow-forgot',
835
+ check: '☐ Forgot password: email → time-limited token → reset',
836
+ why: 'Token must expire (≤ 1 hour)',
837
+ severity: 'high'
838
+ }
839
+ ]
840
+ },
841
+
842
+ // ============================================================
843
+ // PAYMENT CRITICAL FLOWS
844
+ // ============================================================
845
+ payment: {
846
+ security: [
847
+ {
848
+ id: 'payment-no-card-storage',
849
+ check: '☐ NO raw card numbers stored (use Stripe/payment provider tokens)',
850
+ why: 'PCI-DSS requirement, storing cards = massive liability',
851
+ severity: 'critical'
852
+ },
853
+ {
854
+ id: 'payment-https',
855
+ check: '☐ HTTPS enforced on all payment pages',
856
+ why: 'Payment data in transit must be encrypted',
857
+ severity: 'critical'
858
+ },
859
+ {
860
+ id: 'payment-webhook-verify',
861
+ check: '☐ Webhook signature verification (never trust unverified webhooks)',
862
+ why: 'Attackers can fake payment success webhooks',
863
+ severity: 'critical'
864
+ },
865
+ {
866
+ id: 'payment-idempotency',
867
+ check: '☐ Idempotency keys for payment creation',
868
+ why: 'Prevents double charges on retry',
869
+ severity: 'high'
870
+ },
871
+ {
872
+ id: 'payment-amount-verify',
873
+ check: '☐ Server-side price verification (never trust client price)',
874
+ why: 'Attackers modify client-side prices',
875
+ severity: 'critical'
876
+ }
877
+ ],
878
+ flow: [
879
+ {
880
+ id: 'payment-flow-checkout',
881
+ check: '☐ Checkout flow: cart → address → payment → confirm → receipt',
882
+ why: 'Standard e-commerce pattern users expect',
883
+ severity: 'medium'
884
+ },
885
+ {
886
+ id: 'payment-flow-error',
887
+ check: '☐ Payment error handling with clear user message',
888
+ why: 'Failed payments need recovery path',
889
+ severity: 'high'
890
+ },
891
+ {
892
+ id: 'payment-flow-refund',
893
+ check: '☐ Refund flow documented (even if manual)',
894
+ why: 'Legal requirement in most jurisdictions',
895
+ severity: 'high'
896
+ }
897
+ ]
898
+ },
899
+
900
+ // ============================================================
901
+ // SENSITIVE DATA CRITICAL FLOWS
902
+ // ============================================================
903
+ sensitiveData: {
904
+ security: [
905
+ {
906
+ id: 'data-encryption-rest',
907
+ check: '☐ Encryption at rest for PII/PHI (AES-256 or DB-level)',
908
+ why: 'Breached DB without encryption = full exposure',
909
+ severity: 'critical'
910
+ },
911
+ {
912
+ id: 'data-encryption-transit',
913
+ check: '☐ Encryption in transit (TLS 1.2+)',
914
+ why: 'Data interception prevention',
915
+ severity: 'critical'
916
+ },
917
+ {
918
+ id: 'data-access-logging',
919
+ check: '☐ Audit logging for sensitive data access',
920
+ why: 'Required for breach investigation and compliance',
921
+ severity: 'high'
922
+ },
923
+ {
924
+ id: 'data-minimization',
925
+ check: '☐ Data minimization (only collect what is needed)',
926
+ why: 'GDPR principle, reduces breach impact',
927
+ severity: 'medium'
928
+ }
929
+ ],
930
+ dataArchitecture: [
931
+ {
932
+ id: 'data-arch-backup',
933
+ check: '☐ Backup strategy with encryption',
934
+ why: 'Backups are often unencrypted breach vector',
935
+ severity: 'high'
936
+ },
937
+ {
938
+ id: 'data-arch-retention',
939
+ check: '☐ Data retention policy defined',
940
+ why: 'Legal requirement (GDPR right to deletion)',
941
+ severity: 'medium'
942
+ }
943
+ ]
944
+ },
945
+
946
+ // ============================================================
947
+ // HEALTHCARE COMPLIANCE (HIPAA)
948
+ // ============================================================
949
+ healthcare: {
950
+ compliance: [
951
+ {
952
+ id: 'hipaa-phi-encrypt',
953
+ check: '☐ All PHI encrypted at rest and in transit',
954
+ why: 'HIPAA Security Rule requirement',
955
+ severity: 'critical'
956
+ },
957
+ {
958
+ id: 'hipaa-access-control',
959
+ check: '☐ Role-based access control for PHI',
960
+ why: 'Minimum necessary standard',
961
+ severity: 'critical'
962
+ },
963
+ {
964
+ id: 'hipaa-audit-trail',
965
+ check: '☐ Audit trail for all PHI access (who, what, when)',
966
+ why: 'HIPAA requires 6-year audit log retention',
967
+ severity: 'critical'
968
+ },
969
+ {
970
+ id: 'hipaa-baa',
971
+ check: '☐ BAA signed with all vendors handling PHI',
972
+ why: 'Business Associate Agreement legally required',
973
+ severity: 'critical'
974
+ },
975
+ {
976
+ id: 'hipaa-breach-plan',
977
+ check: '☐ Breach notification plan documented',
978
+ why: '60-day notification requirement',
979
+ severity: 'high'
980
+ }
981
+ ]
982
+ },
983
+
984
+ // ============================================================
985
+ // FINTECH COMPLIANCE (PCI-DSS)
986
+ // ============================================================
987
+ fintech: {
988
+ compliance: [
989
+ {
990
+ id: 'pci-no-pan',
991
+ check: '☐ No PAN (card numbers) stored unless PCI certified',
992
+ why: 'PCI-DSS Level 1 requirement',
993
+ severity: 'critical'
994
+ },
995
+ {
996
+ id: 'pci-tokenization',
997
+ check: '☐ Tokenization for card data (Stripe, Braintree)',
998
+ why: 'Removes PCI scope from your systems',
999
+ severity: 'critical'
1000
+ },
1001
+ {
1002
+ id: 'pci-network-segment',
1003
+ check: '☐ Network segmentation for payment systems',
1004
+ why: 'Limits breach blast radius',
1005
+ severity: 'high'
1006
+ },
1007
+ {
1008
+ id: 'fintech-kyc',
1009
+ check: '☐ KYC verification flow for financial accounts',
1010
+ why: 'AML/KYC regulations',
1011
+ severity: 'high'
1012
+ },
1013
+ {
1014
+ id: 'fintech-transaction-limits',
1015
+ check: '☐ Transaction limits and velocity checks',
1016
+ why: 'Fraud prevention, regulatory requirement',
1017
+ severity: 'high'
1018
+ },
1019
+ {
1020
+ id: 'fintech-audit',
1021
+ check: '☐ Transaction audit trail (immutable)',
1022
+ why: 'Regulatory reporting requirement',
1023
+ severity: 'critical'
1024
+ }
1025
+ ]
1026
+ }
1027
+ }
1028
+
712
1029
  // Generate domain knowledge using Claude's reasoning
713
1030
  // This is where Claude applies its training to the specific change
714
1031
  function generateDomainKnowledge(layer, changeAnalysis) {
@@ -1221,16 +1538,18 @@ function extractPotentialLibraryNames(text: string): string[] {
1221
1538
  })
1222
1539
 
1223
1540
  // requirements.txt: sqlalchemy==2.0.0 → sqlalchemy
1224
- const pyDeps = text.match(/^([a-zA-Z][a-zA-Z0-9_-]*)\s*[=<>~!]/gm) || []
1541
+ // Allow optional leading whitespace for indented requirements
1542
+ const pyDeps = text.match(/^\s*([a-zA-Z][a-zA-Z0-9_-]*)\s*[=<>~!]/gm) || []
1225
1543
  pyDeps.forEach(m => {
1226
- const match = m.match(/^([a-zA-Z][a-zA-Z0-9_-]*)/)
1544
+ const match = m.match(/([a-zA-Z][a-zA-Z0-9_-]*)\s*[=<>~!]/)
1227
1545
  if (match) candidates.add(match[1])
1228
1546
  })
1229
1547
 
1230
1548
  // Cargo.toml: tokio = "1.0" → tokio
1231
- const rustDeps = text.match(/^([a-z][a-z0-9_-]*)\s*=/gm) || []
1549
+ // Allow optional leading whitespace for indented dependencies
1550
+ const rustDeps = text.match(/^\s*([a-z][a-z0-9_-]*)\s*=/gm) || []
1232
1551
  rustDeps.forEach(m => {
1233
- const match = m.match(/^([a-z][a-z0-9_-]*)/)
1552
+ const match = m.match(/([a-z][a-z0-9_-]*)\s*=/)
1234
1553
  if (match) candidates.add(match[1])
1235
1554
  })
1236
1555
 
@@ -1274,10 +1593,14 @@ function extractPotentialLibraryNames(text: string): string[] {
1274
1593
  if (match) candidates.add(match[1])
1275
1594
  })
1276
1595
 
1277
- // CamelCase words (FastAPI, SQLAlchemy, NextAuth)
1596
+ // CamelCase words (FastAPI, NextAuth)
1278
1597
  const camelCase = text.match(/\b([A-Z][a-z]+(?:[A-Z][a-z]+)+)\b/g) || []
1279
1598
  camelCase.forEach(w => candidates.add(w))
1280
1599
 
1600
+ // Mixed case words (SQLAlchemy, PostgreSQL, GraphQL - uppercase prefix + CamelCase)
1601
+ const mixedCase = text.match(/\b([A-Z]{2,}[a-z]+[A-Za-z]*)\b/g) || []
1602
+ mixedCase.forEach(w => candidates.add(w))
1603
+
1281
1604
  // === Pattern 3.5: PascalCase single words after tech keywords ===
1282
1605
  // "Framework: Mastra", "ORM: Prisma", "Database: PostgreSQL"
1283
1606
  // WHY: Many library names are single PascalCase words (Mastra, Prisma, Django, Flask)
@@ -1342,34 +1665,35 @@ function extractPotentialLibraryNames(text: string): string[] {
1342
1665
  })
1343
1666
 
1344
1667
  // === Filter out noise ===
1668
+ // Use lowercase for case-insensitive comparison
1345
1669
  const stopWords = new Set([
1346
- // Common English words
1347
- 'The', 'This', 'That', 'With', 'From', 'Using', 'For', 'And', 'But', 'Not',
1348
- 'All', 'Any', 'Can', 'Could', 'Should', 'Would', 'Will', 'May', 'Might',
1349
- 'Each', 'Every', 'Some', 'Many', 'Most', 'Other', 'Such', 'Only', 'Just',
1350
- 'Also', 'Well', 'Back', 'Even', 'Still', 'Already', 'Always', 'Never',
1670
+ // Common English words (all lowercase for comparison)
1671
+ 'the', 'this', 'that', 'with', 'from', 'using', 'for', 'and', 'but', 'not',
1672
+ 'all', 'any', 'can', 'could', 'should', 'would', 'will', 'may', 'might',
1673
+ 'each', 'every', 'some', 'many', 'most', 'other', 'such', 'only', 'just',
1674
+ 'also', 'well', 'back', 'even', 'still', 'already', 'always', 'never',
1351
1675
  // Common programming terms that aren't libraries
1352
- 'API', 'REST', 'HTTP', 'HTTPS', 'JSON', 'XML', 'HTML', 'CSS', 'SQL',
1353
- 'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'URL', 'URI', 'UUID', 'ID',
1354
- 'True', 'False', 'None', 'Null', 'Undefined', 'Error', 'Exception',
1355
- 'Class', 'Function', 'Method', 'Object', 'Array', 'String', 'Number',
1356
- 'Boolean', 'Int', 'Float', 'Double', 'Char', 'Byte', 'Long', 'Short',
1357
- 'Public', 'Private', 'Protected', 'Static', 'Final', 'Const', 'Let', 'Var',
1358
- 'Import', 'Export', 'Module', 'Package', 'Interface', 'Type', 'Enum',
1359
- 'Test', 'Tests', 'Spec', 'Specs', 'Mock', 'Stub', 'Fake', 'Spy',
1360
- 'Config', 'Configuration', 'Settings', 'Options', 'Params', 'Args',
1361
- 'User', 'Users', 'Admin', 'Auth', 'Login', 'Logout', 'Session', 'Token',
1362
- 'Data', 'Database', 'Table', 'Column', 'Row', 'Index', 'Key', 'Value',
1363
- 'File', 'Files', 'Path', 'Dir', 'Directory', 'Folder', 'Name', 'Size',
1364
- 'Create', 'Read', 'Update', 'Delete', 'List', 'Get', 'Set', 'Add', 'Remove',
1365
- 'Start', 'Stop', 'Run', 'Build', 'Deploy', 'Install', 'Setup', 'Init',
1676
+ 'api', 'rest', 'http', 'https', 'json', 'xml', 'html', 'css', 'sql',
1677
+ 'get', 'post', 'put', 'delete', 'patch', 'url', 'uri', 'uuid', 'id',
1678
+ 'true', 'false', 'none', 'null', 'undefined', 'error', 'exception',
1679
+ 'class', 'function', 'method', 'object', 'array', 'string', 'number',
1680
+ 'boolean', 'int', 'float', 'double', 'char', 'byte', 'long', 'short',
1681
+ 'public', 'private', 'protected', 'static', 'final', 'const', 'let', 'var',
1682
+ 'import', 'export', 'module', 'package', 'interface', 'type', 'enum',
1683
+ 'test', 'tests', 'spec', 'specs', 'mock', 'stub', 'fake', 'spy',
1684
+ 'config', 'configuration', 'settings', 'options', 'params', 'args',
1685
+ 'user', 'users', 'admin', 'auth', 'login', 'logout', 'session', 'token',
1686
+ 'data', 'database', 'table', 'column', 'row', 'index', 'key', 'value',
1687
+ 'file', 'files', 'path', 'dir', 'directory', 'folder', 'name', 'size',
1688
+ 'create', 'read', 'update', 'delete', 'list', 'get', 'set', 'add', 'remove',
1689
+ 'start', 'stop', 'run', 'build', 'deploy', 'install', 'setup', 'init',
1366
1690
  // Version/date patterns
1367
- 'Version', 'Release', 'Beta', 'Alpha', 'Stable', 'Latest', 'Current'
1691
+ 'version', 'release', 'beta', 'alpha', 'stable', 'latest', 'current'
1368
1692
  ])
1369
1693
 
1370
1694
  return [...candidates]
1371
1695
  .filter(w => w.length > 2 && w.length < 30)
1372
- .filter(w => !stopWords.has(w))
1696
+ .filter(w => !stopWords.has(w.toLowerCase())) // Case-insensitive comparison
1373
1697
  .filter(w => !/^\d+$/.test(w)) // Not pure numbers
1374
1698
  .filter(w => !/^v?\d+\.\d+/.test(w)) // Not version numbers
1375
1699
  .slice(0, 50) // Limit to avoid too many API calls
@@ -1457,6 +1781,12 @@ function parseContext7Response(response: string, searchTerm: string): {
1457
1781
  ```typescript
1458
1782
  output(`\nšŸ” Validating Library Capabilities...`)
1459
1783
 
1784
+ // Initialize variables at function scope
1785
+ let detectedLibraries = []
1786
+ let specRequirements = []
1787
+ let capabilityGaps = []
1788
+ let customImplementationRequired = []
1789
+
1460
1790
  // 1. Extract spec requirements from design.md
1461
1791
  const designPath = `openspec/changes/${changeId}/design.md`
1462
1792
  if (!fileExists(designPath)) {
@@ -1500,7 +1830,6 @@ if (!fileExists(designPath)) {
1500
1830
  }
1501
1831
 
1502
1832
  // 3. Detect which libraries are mentioned
1503
- const detectedLibraries = []
1504
1833
  for (const [libName, config] of Object.entries(libraryPatterns)) {
1505
1834
  if (config.patterns.some(p => designContent.toLowerCase().includes(p))) {
1506
1835
  detectedLibraries.push({ name: libName, ...config })
@@ -1524,7 +1853,6 @@ if (!fileExists(designPath)) {
1524
1853
  { name: 'Account lockout', pattern: /lockout|lock\s*account/i }
1525
1854
  ]
1526
1855
 
1527
- const specRequirements = []
1528
1856
  for (const rp of requirementPatterns) {
1529
1857
  if (rp.pattern.test(designContent)) {
1530
1858
  specRequirements.push(rp.name)
@@ -1536,8 +1864,6 @@ if (!fileExists(designPath)) {
1536
1864
  specRequirements.forEach(r => output(` - ${r}`))
1537
1865
 
1538
1866
  // 5. Check each library's capability
1539
- const capabilityGaps = []
1540
-
1541
1867
  for (const lib of detectedLibraries) {
1542
1868
  output(`\nšŸ” Checking ${lib.name} capabilities...`)
1543
1869
 
@@ -1675,12 +2001,12 @@ if (!fileExists(designPath)) {
1675
2001
  }
1676
2002
  }
1677
2003
 
1678
- // Store capability analysis
2004
+ // Store capability analysis (variables declared at function scope above)
1679
2005
  const capabilityAnalysis = {
1680
- libraries: detectedLibraries || [],
1681
- requirements: specRequirements || [],
1682
- gaps: capabilityGaps || [],
1683
- customRequired: customImplementationRequired || []
2006
+ libraries: detectedLibraries,
2007
+ requirements: specRequirements,
2008
+ gaps: capabilityGaps,
2009
+ customRequired: customImplementationRequired
1684
2010
  }
1685
2011
  ```
1686
2012