claude-code-orchestrator-kit 1.4.1 → 1.4.15

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 (218) hide show
  1. package/.claude/agents/business/workers/lead-research-assistant.md +199 -0
  2. package/.claude/agents/database/workers/database-architect.md +3 -3
  3. package/.claude/agents/database/workers/supabase-auditor.md +7 -7
  4. package/.claude/agents/development/workers/code-reviewer.md +17 -2
  5. package/.claude/agents/frontend/workers/nextjs-ui-designer.md +30 -0
  6. package/.claude/agents/health/workers/bug-fixer.md +31 -2
  7. package/.claude/agents/health/workers/bug-hunter.md +0 -1
  8. package/.claude/agents/health/workers/dead-code-hunter.md +167 -75
  9. package/.claude/agents/health/workers/dead-code-remover.md +217 -66
  10. package/.claude/agents/health/workers/dependency-auditor.md +83 -24
  11. package/.claude/agents/health/workers/dependency-updater.md +0 -1
  12. package/.claude/agents/health/workers/security-scanner.md +0 -1
  13. package/.claude/agents/infrastructure/workers/deployment-engineer.md +446 -0
  14. package/.claude/agents/infrastructure/workers/infrastructure-specialist.md +2 -2
  15. package/.claude/agents/meta/workers/meta-agent-v3.md +22 -0
  16. package/.claude/agents/testing/workers/integration-tester.md +1 -1
  17. package/.claude/agents/testing/workers/test-writer.md +16 -0
  18. package/.claude/commands/health-bugs.md +14 -281
  19. package/.claude/commands/health-cleanup.md +14 -281
  20. package/.claude/commands/health-deps.md +14 -281
  21. package/.claude/commands/health-metrics.md +51 -709
  22. package/.claude/commands/health-reuse.md +14 -311
  23. package/.claude/commands/health-security.md +14 -281
  24. package/.claude/commands/push.md +17 -3
  25. package/.claude/commands/speckit.implement.md +0 -11
  26. package/.claude/commands/worktree.md +150 -0
  27. package/.claude/scripts/gates/check-bundle-size.sh +0 -0
  28. package/.claude/scripts/gates/check-coverage.sh +0 -0
  29. package/.claude/scripts/gates/check-security.sh +0 -0
  30. package/.claude/scripts/release.sh +469 -94
  31. package/.claude/skills/algorithmic-art/LICENSE.txt +202 -0
  32. package/.claude/skills/algorithmic-art/SKILL.md +405 -0
  33. package/.claude/skills/algorithmic-art/templates/generator_template.js +223 -0
  34. package/.claude/skills/algorithmic-art/templates/viewer.html +599 -0
  35. package/.claude/skills/artifacts-builder/LICENSE.txt +202 -0
  36. package/.claude/skills/artifacts-builder/SKILL.md +74 -0
  37. package/.claude/skills/artifacts-builder/scripts/bundle-artifact.sh +54 -0
  38. package/.claude/skills/artifacts-builder/scripts/init-artifact.sh +322 -0
  39. package/.claude/skills/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  40. package/.claude/skills/bug-health-inline/SKILL.md +221 -0
  41. package/.claude/skills/bug-health-inline/references/worker-prompts.md +182 -0
  42. package/.claude/skills/canvas-design/LICENSE.txt +202 -0
  43. package/.claude/skills/canvas-design/SKILL.md +130 -0
  44. package/.claude/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
  45. package/.claude/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  46. package/.claude/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  47. package/.claude/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
  48. package/.claude/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  49. package/.claude/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
  50. package/.claude/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
  51. package/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  52. package/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
  53. package/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  54. package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  55. package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  56. package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
  57. package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  58. package/.claude/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
  59. package/.claude/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
  60. package/.claude/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
  61. package/.claude/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
  62. package/.claude/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
  63. package/.claude/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
  64. package/.claude/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
  65. package/.claude/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
  66. package/.claude/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
  67. package/.claude/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  68. package/.claude/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
  69. package/.claude/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  70. package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  71. package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  72. package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  73. package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  74. package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  75. package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  76. package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  77. package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
  78. package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  79. package/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  80. package/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  81. package/.claude/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
  82. package/.claude/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
  83. package/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  84. package/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
  85. package/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  86. package/.claude/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
  87. package/.claude/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
  88. package/.claude/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
  89. package/.claude/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
  90. package/.claude/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  91. package/.claude/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
  92. package/.claude/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  93. package/.claude/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
  94. package/.claude/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
  95. package/.claude/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
  96. package/.claude/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
  97. package/.claude/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
  98. package/.claude/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
  99. package/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
  100. package/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  101. package/.claude/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
  102. package/.claude/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
  103. package/.claude/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
  104. package/.claude/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  105. package/.claude/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
  106. package/.claude/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
  107. package/.claude/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  108. package/.claude/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  109. package/.claude/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
  110. package/.claude/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  111. package/.claude/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
  112. package/.claude/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  113. package/.claude/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  114. package/.claude/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
  115. package/.claude/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
  116. package/.claude/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
  117. package/.claude/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
  118. package/.claude/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
  119. package/.claude/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  120. package/.claude/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
  121. package/.claude/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
  122. package/.claude/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
  123. package/.claude/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
  124. package/.claude/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  125. package/.claude/skills/changelog-generator/SKILL.md +104 -0
  126. package/.claude/skills/cleanup-health-inline/SKILL.md +224 -0
  127. package/.claude/skills/code-reviewer/SKILL.md +209 -0
  128. package/.claude/skills/code-reviewer/references/code_review_checklist.md +103 -0
  129. package/.claude/skills/code-reviewer/references/coding_standards.md +103 -0
  130. package/.claude/skills/code-reviewer/references/common_antipatterns.md +103 -0
  131. package/.claude/skills/code-reviewer/scripts/code_quality_checker.py +114 -0
  132. package/.claude/skills/code-reviewer/scripts/pr_analyzer.py +114 -0
  133. package/.claude/skills/code-reviewer/scripts/review_report_generator.py +114 -0
  134. package/.claude/skills/content-research-writer/SKILL.md +538 -0
  135. package/.claude/skills/deps-health-inline/SKILL.md +227 -0
  136. package/.claude/skills/frontend-aesthetics/SKILL.md +51 -396
  137. package/.claude/skills/git-commit-helper/SKILL.md +203 -0
  138. package/.claude/skills/lead-research-assistant/SKILL.md +199 -0
  139. package/.claude/skills/reuse-health-inline/SKILL.md +248 -0
  140. package/.claude/skills/rollback-changes/SKILL.md +50 -524
  141. package/.claude/skills/run-quality-gate/SKILL.md +36 -346
  142. package/.claude/skills/security-health-inline/SKILL.md +224 -0
  143. package/.claude/skills/senior-devops/SKILL.md +209 -0
  144. package/.claude/skills/senior-devops/references/cicd_pipeline_guide.md +103 -0
  145. package/.claude/skills/senior-devops/references/deployment_strategies.md +103 -0
  146. package/.claude/skills/senior-devops/references/infrastructure_as_code.md +103 -0
  147. package/.claude/skills/senior-devops/scripts/deployment_manager.py +114 -0
  148. package/.claude/skills/senior-devops/scripts/pipeline_generator.py +114 -0
  149. package/.claude/skills/senior-devops/scripts/terraform_scaffolder.py +114 -0
  150. package/.claude/skills/senior-prompt-engineer/SKILL.md +226 -0
  151. package/.claude/skills/senior-prompt-engineer/references/agentic_system_design.md +80 -0
  152. package/.claude/skills/senior-prompt-engineer/references/llm_evaluation_frameworks.md +80 -0
  153. package/.claude/skills/senior-prompt-engineer/references/prompt_engineering_patterns.md +80 -0
  154. package/.claude/skills/senior-prompt-engineer/scripts/agent_orchestrator.py +100 -0
  155. package/.claude/skills/senior-prompt-engineer/scripts/prompt_optimizer.py +100 -0
  156. package/.claude/skills/senior-prompt-engineer/scripts/rag_evaluator.py +100 -0
  157. package/.claude/skills/setup-knip/SKILL.md +372 -0
  158. package/.claude/skills/systematic-debugging/CREATION-LOG.md +119 -0
  159. package/.claude/skills/systematic-debugging/SKILL.md +296 -0
  160. package/.claude/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
  161. package/.claude/skills/systematic-debugging/condition-based-waiting.md +115 -0
  162. package/.claude/skills/systematic-debugging/defense-in-depth.md +122 -0
  163. package/.claude/skills/systematic-debugging/find-polluter.sh +63 -0
  164. package/.claude/skills/systematic-debugging/root-cause-tracing.md +169 -0
  165. package/.claude/skills/systematic-debugging/test-academic.md +14 -0
  166. package/.claude/skills/systematic-debugging/test-pressure-1.md +58 -0
  167. package/.claude/skills/systematic-debugging/test-pressure-2.md +68 -0
  168. package/.claude/skills/systematic-debugging/test-pressure-3.md +69 -0
  169. package/.claude/skills/theme-factory/LICENSE.txt +202 -0
  170. package/.claude/skills/theme-factory/SKILL.md +59 -0
  171. package/.claude/skills/theme-factory/theme-showcase.pdf +0 -0
  172. package/.claude/skills/theme-factory/themes/arctic-frost.md +19 -0
  173. package/.claude/skills/theme-factory/themes/botanical-garden.md +19 -0
  174. package/.claude/skills/theme-factory/themes/desert-rose.md +19 -0
  175. package/.claude/skills/theme-factory/themes/forest-canopy.md +19 -0
  176. package/.claude/skills/theme-factory/themes/golden-hour.md +19 -0
  177. package/.claude/skills/theme-factory/themes/midnight-galaxy.md +19 -0
  178. package/.claude/skills/theme-factory/themes/modern-minimalist.md +19 -0
  179. package/.claude/skills/theme-factory/themes/ocean-depths.md +19 -0
  180. package/.claude/skills/theme-factory/themes/sunset-boulevard.md +19 -0
  181. package/.claude/skills/theme-factory/themes/tech-innovation.md +19 -0
  182. package/.claude/skills/ui-design-system/SKILL.md +32 -0
  183. package/.claude/skills/ui-design-system/scripts/design_token_generator.py +529 -0
  184. package/.claude/skills/ux-researcher-designer/SKILL.md +30 -0
  185. package/.claude/skills/ux-researcher-designer/scripts/persona_generator.py +508 -0
  186. package/.claude/skills/webapp-testing/LICENSE.txt +202 -0
  187. package/.claude/skills/webapp-testing/SKILL.md +96 -0
  188. package/.claude/skills/webapp-testing/examples/console_logging.py +35 -0
  189. package/.claude/skills/webapp-testing/examples/element_discovery.py +40 -0
  190. package/.claude/skills/webapp-testing/examples/static_html_automation.py +33 -0
  191. package/.claude/skills/webapp-testing/scripts/with_server.py +106 -0
  192. package/.gitignore +4 -0
  193. package/README.md +492 -1093
  194. package/README.ru.md +719 -0
  195. package/docs/Agents Ecosystem/AGENT-ORCHESTRATION.md +2 -2
  196. package/docs/COMMANDS-GUIDE.md +0 -15
  197. package/docs/reports/skills/new-skills-analysis-2025-12.md +331 -0
  198. package/package.json +11 -3
  199. package/.claude/agents/health/orchestrators/bug-orchestrator.md +0 -1084
  200. package/.claude/agents/health/orchestrators/dead-code-orchestrator.md +0 -1064
  201. package/.claude/agents/health/orchestrators/dependency-orchestrator.md +0 -1064
  202. package/.claude/agents/health/orchestrators/reuse-orchestrator.md +0 -1112
  203. package/.claude/agents/health/orchestrators/security-orchestrator.md +0 -1064
  204. package/.claude/commands/worktree-cleanup.md +0 -382
  205. package/.claude/commands/worktree-create.md +0 -287
  206. package/.claude/commands/worktree-list.md +0 -239
  207. package/.claude/commands/worktree-remove.md +0 -339
  208. package/.claude/project-index.md +0 -75
  209. package/.claude/skills/load-project-context/SKILL.md +0 -89
  210. package/.claude/skills/resume-session/SKILL.md +0 -164
  211. package/.claude/skills/save-session-context/SKILL.md +0 -123
  212. package/.claude/templates/project-index.template.md +0 -67
  213. package/.claude/templates/session/context.template.md +0 -40
  214. package/.claude/templates/session/log.template.md +0 -72
  215. package/.github/BRANCH_PROTECTION.md +0 -137
  216. package/.github/workflows/build.yml +0 -70
  217. package/.github/workflows/deploy-staging.yml +0 -90
  218. package/.github/workflows/test.yml +0 -104
@@ -0,0 +1,508 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Data-Driven Persona Generator
4
+ Creates research-backed user personas from user data and interviews
5
+ """
6
+
7
+ import json
8
+ from typing import Dict, List, Tuple
9
+ from collections import Counter, defaultdict
10
+ import random
11
+
12
+ class PersonaGenerator:
13
+ """Generate data-driven personas from user research"""
14
+
15
+ def __init__(self):
16
+ self.persona_components = {
17
+ 'demographics': ['age', 'location', 'occupation', 'education', 'income'],
18
+ 'psychographics': ['goals', 'frustrations', 'motivations', 'values'],
19
+ 'behaviors': ['tech_savviness', 'usage_frequency', 'preferred_devices', 'key_activities'],
20
+ 'needs': ['functional', 'emotional', 'social']
21
+ }
22
+
23
+ self.archetype_templates = {
24
+ 'power_user': {
25
+ 'characteristics': ['tech-savvy', 'frequent user', 'early adopter', 'efficiency-focused'],
26
+ 'goals': ['maximize productivity', 'automate workflows', 'access advanced features'],
27
+ 'frustrations': ['slow performance', 'limited customization', 'lack of shortcuts'],
28
+ 'quote': "I need tools that can keep up with my workflow"
29
+ },
30
+ 'casual_user': {
31
+ 'characteristics': ['occasional user', 'basic needs', 'prefers simplicity'],
32
+ 'goals': ['accomplish specific tasks', 'easy to use', 'minimal learning curve'],
33
+ 'frustrations': ['complexity', 'too many options', 'unclear navigation'],
34
+ 'quote': "I just want it to work without having to think about it"
35
+ },
36
+ 'business_user': {
37
+ 'characteristics': ['professional context', 'ROI-focused', 'team collaboration'],
38
+ 'goals': ['improve team efficiency', 'track metrics', 'integrate with tools'],
39
+ 'frustrations': ['lack of reporting', 'poor collaboration features', 'no enterprise features'],
40
+ 'quote': "I need to show clear value to my stakeholders"
41
+ },
42
+ 'mobile_first': {
43
+ 'characteristics': ['primarily mobile', 'on-the-go usage', 'quick interactions'],
44
+ 'goals': ['access anywhere', 'quick actions', 'offline capability'],
45
+ 'frustrations': ['poor mobile experience', 'desktop-only features', 'slow loading'],
46
+ 'quote': "My phone is my primary computing device"
47
+ }
48
+ }
49
+
50
+ def generate_persona_from_data(self, user_data: List[Dict],
51
+ interview_insights: List[Dict] = None) -> Dict:
52
+ """Generate persona from user data and optional interview insights"""
53
+
54
+ # Analyze user data for patterns
55
+ patterns = self._analyze_user_patterns(user_data)
56
+
57
+ # Identify persona archetype
58
+ archetype = self._identify_archetype(patterns)
59
+
60
+ # Generate persona
61
+ persona = {
62
+ 'name': self._generate_name(archetype),
63
+ 'archetype': archetype,
64
+ 'tagline': self._generate_tagline(patterns),
65
+ 'demographics': self._aggregate_demographics(user_data),
66
+ 'psychographics': self._extract_psychographics(patterns, interview_insights),
67
+ 'behaviors': self._analyze_behaviors(user_data),
68
+ 'needs_and_goals': self._identify_needs(patterns, interview_insights),
69
+ 'frustrations': self._extract_frustrations(patterns, interview_insights),
70
+ 'scenarios': self._generate_scenarios(archetype, patterns),
71
+ 'quote': self._select_quote(interview_insights, archetype),
72
+ 'data_points': self._calculate_data_points(user_data),
73
+ 'design_implications': self._derive_design_implications(patterns)
74
+ }
75
+
76
+ return persona
77
+
78
+ def _analyze_user_patterns(self, user_data: List[Dict]) -> Dict:
79
+ """Analyze patterns in user data"""
80
+
81
+ patterns = {
82
+ 'usage_frequency': defaultdict(int),
83
+ 'feature_usage': defaultdict(int),
84
+ 'devices': defaultdict(int),
85
+ 'contexts': defaultdict(int),
86
+ 'pain_points': [],
87
+ 'success_metrics': []
88
+ }
89
+
90
+ for user in user_data:
91
+ # Frequency patterns
92
+ freq = user.get('usage_frequency', 'medium')
93
+ patterns['usage_frequency'][freq] += 1
94
+
95
+ # Feature usage
96
+ for feature in user.get('features_used', []):
97
+ patterns['feature_usage'][feature] += 1
98
+
99
+ # Device patterns
100
+ device = user.get('primary_device', 'desktop')
101
+ patterns['devices'][device] += 1
102
+
103
+ # Context patterns
104
+ context = user.get('usage_context', 'work')
105
+ patterns['contexts'][context] += 1
106
+
107
+ # Pain points
108
+ if 'pain_points' in user:
109
+ patterns['pain_points'].extend(user['pain_points'])
110
+
111
+ return patterns
112
+
113
+ def _identify_archetype(self, patterns: Dict) -> str:
114
+ """Identify persona archetype based on patterns"""
115
+
116
+ # Simple heuristic-based archetype identification
117
+ freq_pattern = max(patterns['usage_frequency'].items(), key=lambda x: x[1])[0] if patterns['usage_frequency'] else 'medium'
118
+ device_pattern = max(patterns['devices'].items(), key=lambda x: x[1])[0] if patterns['devices'] else 'desktop'
119
+
120
+ if freq_pattern == 'daily' and len(patterns['feature_usage']) > 10:
121
+ return 'power_user'
122
+ elif device_pattern in ['mobile', 'tablet']:
123
+ return 'mobile_first'
124
+ elif patterns['contexts'].get('work', 0) > patterns['contexts'].get('personal', 0):
125
+ return 'business_user'
126
+ else:
127
+ return 'casual_user'
128
+
129
+ def _generate_name(self, archetype: str) -> str:
130
+ """Generate persona name based on archetype"""
131
+
132
+ names = {
133
+ 'power_user': ['Alex', 'Sam', 'Jordan', 'Morgan'],
134
+ 'casual_user': ['Pat', 'Jamie', 'Casey', 'Riley'],
135
+ 'business_user': ['Taylor', 'Cameron', 'Avery', 'Blake'],
136
+ 'mobile_first': ['Quinn', 'Skylar', 'River', 'Sage']
137
+ }
138
+
139
+ name_pool = names.get(archetype, names['casual_user'])
140
+ first_name = random.choice(name_pool)
141
+
142
+ roles = {
143
+ 'power_user': 'the Power User',
144
+ 'casual_user': 'the Casual User',
145
+ 'business_user': 'the Business Professional',
146
+ 'mobile_first': 'the Mobile Native'
147
+ }
148
+
149
+ return f"{first_name} {roles[archetype]}"
150
+
151
+ def _generate_tagline(self, patterns: Dict) -> str:
152
+ """Generate persona tagline"""
153
+
154
+ freq = max(patterns['usage_frequency'].items(), key=lambda x: x[1])[0] if patterns['usage_frequency'] else 'regular'
155
+ context = max(patterns['contexts'].items(), key=lambda x: x[1])[0] if patterns['contexts'] else 'general'
156
+
157
+ return f"A {freq} user who primarily uses the product for {context} purposes"
158
+
159
+ def _aggregate_demographics(self, user_data: List[Dict]) -> Dict:
160
+ """Aggregate demographic information"""
161
+
162
+ demographics = {
163
+ 'age_range': '',
164
+ 'location_type': '',
165
+ 'occupation_category': '',
166
+ 'education_level': '',
167
+ 'tech_proficiency': ''
168
+ }
169
+
170
+ if not user_data:
171
+ return demographics
172
+
173
+ # Age range
174
+ ages = [u.get('age', 30) for u in user_data if 'age' in u]
175
+ if ages:
176
+ avg_age = sum(ages) / len(ages)
177
+ if avg_age < 25:
178
+ demographics['age_range'] = '18-24'
179
+ elif avg_age < 35:
180
+ demographics['age_range'] = '25-34'
181
+ elif avg_age < 45:
182
+ demographics['age_range'] = '35-44'
183
+ else:
184
+ demographics['age_range'] = '45+'
185
+
186
+ # Location type
187
+ locations = [u.get('location_type', 'urban') for u in user_data if 'location_type' in u]
188
+ if locations:
189
+ demographics['location_type'] = Counter(locations).most_common(1)[0][0]
190
+
191
+ # Tech proficiency
192
+ tech_scores = [u.get('tech_proficiency', 5) for u in user_data if 'tech_proficiency' in u]
193
+ if tech_scores:
194
+ avg_tech = sum(tech_scores) / len(tech_scores)
195
+ if avg_tech < 3:
196
+ demographics['tech_proficiency'] = 'Beginner'
197
+ elif avg_tech < 7:
198
+ demographics['tech_proficiency'] = 'Intermediate'
199
+ else:
200
+ demographics['tech_proficiency'] = 'Advanced'
201
+
202
+ return demographics
203
+
204
+ def _extract_psychographics(self, patterns: Dict, interviews: List[Dict] = None) -> Dict:
205
+ """Extract psychographic information"""
206
+
207
+ psychographics = {
208
+ 'motivations': [],
209
+ 'values': [],
210
+ 'attitudes': [],
211
+ 'lifestyle': ''
212
+ }
213
+
214
+ # Extract from patterns
215
+ if patterns['usage_frequency'].get('daily', 0) > 0:
216
+ psychographics['motivations'].append('Efficiency')
217
+ psychographics['values'].append('Time-saving')
218
+
219
+ if patterns['devices'].get('mobile', 0) > patterns['devices'].get('desktop', 0):
220
+ psychographics['lifestyle'] = 'On-the-go, mobile-first'
221
+ psychographics['values'].append('Flexibility')
222
+
223
+ # Extract from interviews if available
224
+ if interviews:
225
+ for interview in interviews:
226
+ if 'motivations' in interview:
227
+ psychographics['motivations'].extend(interview['motivations'])
228
+ if 'values' in interview:
229
+ psychographics['values'].extend(interview['values'])
230
+
231
+ # Deduplicate
232
+ psychographics['motivations'] = list(set(psychographics['motivations']))[:5]
233
+ psychographics['values'] = list(set(psychographics['values']))[:5]
234
+
235
+ return psychographics
236
+
237
+ def _analyze_behaviors(self, user_data: List[Dict]) -> Dict:
238
+ """Analyze user behaviors"""
239
+
240
+ behaviors = {
241
+ 'usage_patterns': [],
242
+ 'feature_preferences': [],
243
+ 'interaction_style': '',
244
+ 'learning_preference': ''
245
+ }
246
+
247
+ if not user_data:
248
+ return behaviors
249
+
250
+ # Usage patterns
251
+ frequencies = [u.get('usage_frequency', 'medium') for u in user_data]
252
+ freq_counter = Counter(frequencies)
253
+ behaviors['usage_patterns'] = [f"{freq}: {count} users" for freq, count in freq_counter.most_common(3)]
254
+
255
+ # Feature preferences
256
+ all_features = []
257
+ for user in user_data:
258
+ all_features.extend(user.get('features_used', []))
259
+
260
+ feature_counter = Counter(all_features)
261
+ behaviors['feature_preferences'] = [feat for feat, count in feature_counter.most_common(5)]
262
+
263
+ # Interaction style
264
+ if len(behaviors['feature_preferences']) > 10:
265
+ behaviors['interaction_style'] = 'Exploratory - uses many features'
266
+ else:
267
+ behaviors['interaction_style'] = 'Focused - uses core features'
268
+
269
+ return behaviors
270
+
271
+ def _identify_needs(self, patterns: Dict, interviews: List[Dict] = None) -> Dict:
272
+ """Identify user needs and goals"""
273
+
274
+ needs = {
275
+ 'primary_goals': [],
276
+ 'secondary_goals': [],
277
+ 'functional_needs': [],
278
+ 'emotional_needs': []
279
+ }
280
+
281
+ # Derive from usage patterns
282
+ if patterns['usage_frequency'].get('daily', 0) > 0:
283
+ needs['primary_goals'].append('Complete tasks efficiently')
284
+ needs['functional_needs'].append('Speed and performance')
285
+
286
+ if patterns['contexts'].get('work', 0) > 0:
287
+ needs['primary_goals'].append('Professional productivity')
288
+ needs['functional_needs'].append('Integration with work tools')
289
+
290
+ # Common emotional needs
291
+ needs['emotional_needs'] = [
292
+ 'Feel confident using the product',
293
+ 'Trust the system with data',
294
+ 'Feel supported when issues arise'
295
+ ]
296
+
297
+ # Extract from interviews
298
+ if interviews:
299
+ for interview in interviews:
300
+ if 'goals' in interview:
301
+ needs['primary_goals'].extend(interview['goals'][:2])
302
+ if 'needs' in interview:
303
+ needs['functional_needs'].extend(interview['needs'][:3])
304
+
305
+ return needs
306
+
307
+ def _extract_frustrations(self, patterns: Dict, interviews: List[Dict] = None) -> List[str]:
308
+ """Extract user frustrations"""
309
+
310
+ frustrations = []
311
+
312
+ # Common frustrations from patterns
313
+ if patterns['pain_points']:
314
+ frustration_counter = Counter(patterns['pain_points'])
315
+ frustrations = [pain for pain, count in frustration_counter.most_common(5)]
316
+
317
+ # Add archetype-specific frustrations if not enough from data
318
+ if len(frustrations) < 3:
319
+ frustrations.extend([
320
+ 'Slow loading times',
321
+ 'Confusing navigation',
322
+ 'Lack of mobile optimization'
323
+ ])
324
+
325
+ return frustrations[:5]
326
+
327
+ def _generate_scenarios(self, archetype: str, patterns: Dict) -> List[Dict]:
328
+ """Generate usage scenarios"""
329
+
330
+ scenarios = []
331
+
332
+ # Common scenarios based on archetype
333
+ scenario_templates = {
334
+ 'power_user': [
335
+ {
336
+ 'title': 'Bulk Processing',
337
+ 'context': 'Monday morning, needs to process week\'s data',
338
+ 'goal': 'Complete batch operations quickly',
339
+ 'steps': ['Import data', 'Apply bulk actions', 'Export results'],
340
+ 'pain_points': ['No keyboard shortcuts', 'Slow processing']
341
+ }
342
+ ],
343
+ 'casual_user': [
344
+ {
345
+ 'title': 'Quick Task',
346
+ 'context': 'Needs to complete single task',
347
+ 'goal': 'Get in, complete task, get out',
348
+ 'steps': ['Find feature', 'Complete task', 'Save/Exit'],
349
+ 'pain_points': ['Can\'t find feature', 'Too many steps']
350
+ }
351
+ ],
352
+ 'business_user': [
353
+ {
354
+ 'title': 'Team Collaboration',
355
+ 'context': 'Working with team on project',
356
+ 'goal': 'Share and collaborate efficiently',
357
+ 'steps': ['Create content', 'Share with team', 'Track feedback'],
358
+ 'pain_points': ['No real-time collaboration', 'Poor permission management']
359
+ }
360
+ ],
361
+ 'mobile_first': [
362
+ {
363
+ 'title': 'On-the-Go Access',
364
+ 'context': 'Commuting, needs quick access',
365
+ 'goal': 'Complete task on mobile',
366
+ 'steps': ['Open mobile app', 'Quick action', 'Sync with desktop'],
367
+ 'pain_points': ['Feature parity issues', 'Poor mobile UX']
368
+ }
369
+ ]
370
+ }
371
+
372
+ return scenario_templates.get(archetype, scenario_templates['casual_user'])
373
+
374
+ def _select_quote(self, interviews: List[Dict] = None, archetype: str = 'casual_user') -> str:
375
+ """Select representative quote"""
376
+
377
+ if interviews:
378
+ # Try to find a real quote
379
+ for interview in interviews:
380
+ if 'quotes' in interview and interview['quotes']:
381
+ return interview['quotes'][0]
382
+
383
+ # Use archetype default
384
+ return self.archetype_templates[archetype]['quote']
385
+
386
+ def _calculate_data_points(self, user_data: List[Dict]) -> Dict:
387
+ """Calculate supporting data points"""
388
+
389
+ return {
390
+ 'sample_size': len(user_data),
391
+ 'confidence_level': 'High' if len(user_data) > 50 else 'Medium' if len(user_data) > 20 else 'Low',
392
+ 'last_updated': 'Current',
393
+ 'validation_method': 'Quantitative analysis + Qualitative interviews'
394
+ }
395
+
396
+ def _derive_design_implications(self, patterns: Dict) -> List[str]:
397
+ """Derive design implications from persona"""
398
+
399
+ implications = []
400
+
401
+ # Based on frequency
402
+ if patterns['usage_frequency'].get('daily', 0) > patterns['usage_frequency'].get('weekly', 0):
403
+ implications.append('Optimize for speed and efficiency')
404
+ implications.append('Provide keyboard shortcuts and power features')
405
+ else:
406
+ implications.append('Focus on discoverability and guidance')
407
+ implications.append('Simplify onboarding experience')
408
+
409
+ # Based on device
410
+ if patterns['devices'].get('mobile', 0) > 0:
411
+ implications.append('Mobile-first responsive design')
412
+ implications.append('Touch-optimized interactions')
413
+
414
+ # Based on context
415
+ if patterns['contexts'].get('work', 0) > patterns['contexts'].get('personal', 0):
416
+ implications.append('Professional visual design')
417
+ implications.append('Enterprise features (SSO, audit logs)')
418
+
419
+ return implications[:5]
420
+
421
+ def format_persona_output(self, persona: Dict) -> str:
422
+ """Format persona for display"""
423
+
424
+ output = []
425
+ output.append("=" * 60)
426
+ output.append(f"PERSONA: {persona['name']}")
427
+ output.append("=" * 60)
428
+ output.append(f"\nšŸ“ {persona['tagline']}\n")
429
+
430
+ output.append(f"Archetype: {persona['archetype'].replace('_', ' ').title()}")
431
+ output.append(f"Quote: \"{persona['quote']}\"\n")
432
+
433
+ output.append("šŸ‘¤ Demographics:")
434
+ for key, value in persona['demographics'].items():
435
+ if value:
436
+ output.append(f" • {key.replace('_', ' ').title()}: {value}")
437
+
438
+ output.append("\n🧠 Psychographics:")
439
+ if persona['psychographics']['motivations']:
440
+ output.append(f" Motivations: {', '.join(persona['psychographics']['motivations'])}")
441
+ if persona['psychographics']['values']:
442
+ output.append(f" Values: {', '.join(persona['psychographics']['values'])}")
443
+
444
+ output.append("\nšŸŽÆ Goals & Needs:")
445
+ for goal in persona['needs_and_goals'].get('primary_goals', [])[:3]:
446
+ output.append(f" • {goal}")
447
+
448
+ output.append("\n😤 Frustrations:")
449
+ for frustration in persona['frustrations'][:3]:
450
+ output.append(f" • {frustration}")
451
+
452
+ output.append("\nšŸ“Š Behaviors:")
453
+ for pref in persona['behaviors'].get('feature_preferences', [])[:3]:
454
+ output.append(f" • Frequently uses: {pref}")
455
+
456
+ output.append("\nšŸ’” Design Implications:")
457
+ for implication in persona['design_implications']:
458
+ output.append(f" → {implication}")
459
+
460
+ output.append(f"\nšŸ“ˆ Data: Based on {persona['data_points']['sample_size']} users")
461
+ output.append(f" Confidence: {persona['data_points']['confidence_level']}")
462
+
463
+ return "\n".join(output)
464
+
465
+ def create_sample_user_data():
466
+ """Create sample user data for testing"""
467
+ return [
468
+ {
469
+ 'user_id': f'user_{i}',
470
+ 'age': 25 + (i % 30),
471
+ 'usage_frequency': ['daily', 'weekly', 'monthly'][i % 3],
472
+ 'features_used': ['dashboard', 'reports', 'settings', 'sharing', 'export'][:3 + (i % 3)],
473
+ 'primary_device': ['desktop', 'mobile', 'tablet'][i % 3],
474
+ 'usage_context': ['work', 'personal'][i % 2],
475
+ 'tech_proficiency': 3 + (i % 7),
476
+ 'pain_points': ['slow loading', 'confusing UI', 'missing features'][:(i % 3) + 1]
477
+ }
478
+ for i in range(30)
479
+ ]
480
+
481
+ def main():
482
+ import sys
483
+
484
+ generator = PersonaGenerator()
485
+
486
+ # Create sample data
487
+ user_data = create_sample_user_data()
488
+
489
+ # Optional interview insights
490
+ interview_insights = [
491
+ {
492
+ 'quotes': ["I need to see all my data in one place"],
493
+ 'motivations': ['Efficiency', 'Control'],
494
+ 'goals': ['Save time', 'Make better decisions']
495
+ }
496
+ ]
497
+
498
+ # Generate persona
499
+ persona = generator.generate_persona_from_data(user_data, interview_insights)
500
+
501
+ # Output
502
+ if len(sys.argv) > 1 and sys.argv[1] == 'json':
503
+ print(json.dumps(persona, indent=2))
504
+ else:
505
+ print(generator.format_persona_output(persona))
506
+
507
+ if __name__ == "__main__":
508
+ main()