userflow-mcp 0.2.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 (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +177 -0
  3. package/dist/analysis/clarity.d.ts +7 -0
  4. package/dist/analysis/clarity.d.ts.map +1 -0
  5. package/dist/analysis/clarity.js +114 -0
  6. package/dist/analysis/clarity.js.map +1 -0
  7. package/dist/analysis/cognitive-load.d.ts +7 -0
  8. package/dist/analysis/cognitive-load.d.ts.map +1 -0
  9. package/dist/analysis/cognitive-load.js +45 -0
  10. package/dist/analysis/cognitive-load.js.map +1 -0
  11. package/dist/analysis/emotional-arc.d.ts +10 -0
  12. package/dist/analysis/emotional-arc.d.ts.map +1 -0
  13. package/dist/analysis/emotional-arc.js +95 -0
  14. package/dist/analysis/emotional-arc.js.map +1 -0
  15. package/dist/analysis/friction.d.ts +23 -0
  16. package/dist/analysis/friction.d.ts.map +1 -0
  17. package/dist/analysis/friction.js +61 -0
  18. package/dist/analysis/friction.js.map +1 -0
  19. package/dist/feedback/comparison.d.ts +11 -0
  20. package/dist/feedback/comparison.d.ts.map +1 -0
  21. package/dist/feedback/comparison.js +156 -0
  22. package/dist/feedback/comparison.js.map +1 -0
  23. package/dist/feedback/generator.d.ts +19 -0
  24. package/dist/feedback/generator.d.ts.map +1 -0
  25. package/dist/feedback/generator.js +139 -0
  26. package/dist/feedback/generator.js.map +1 -0
  27. package/dist/feedback/report.d.ts +10 -0
  28. package/dist/feedback/report.d.ts.map +1 -0
  29. package/dist/feedback/report.js +123 -0
  30. package/dist/feedback/report.js.map +1 -0
  31. package/dist/index.d.ts +3 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +13 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/personas/engine.d.ts +39 -0
  36. package/dist/personas/engine.d.ts.map +1 -0
  37. package/dist/personas/engine.js +58 -0
  38. package/dist/personas/engine.js.map +1 -0
  39. package/dist/personas/presets.d.ts +11 -0
  40. package/dist/personas/presets.d.ts.map +1 -0
  41. package/dist/personas/presets.js +251 -0
  42. package/dist/personas/presets.js.map +1 -0
  43. package/dist/personas/types.d.ts +11 -0
  44. package/dist/personas/types.d.ts.map +1 -0
  45. package/dist/personas/types.js +23 -0
  46. package/dist/personas/types.js.map +1 -0
  47. package/dist/server.d.ts +3 -0
  48. package/dist/server.d.ts.map +1 -0
  49. package/dist/server.js +288 -0
  50. package/dist/server.js.map +1 -0
  51. package/dist/session/session-manager.d.ts +54 -0
  52. package/dist/session/session-manager.d.ts.map +1 -0
  53. package/dist/session/session-manager.js +228 -0
  54. package/dist/session/session-manager.js.map +1 -0
  55. package/dist/session/types.d.ts +35 -0
  56. package/dist/session/types.d.ts.map +1 -0
  57. package/dist/session/types.js +2 -0
  58. package/dist/session/types.js.map +1 -0
  59. package/dist/types.d.ts +284 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +3 -0
  62. package/dist/types.js.map +1 -0
  63. package/dist/utils/actions.d.ts +17 -0
  64. package/dist/utils/actions.d.ts.map +1 -0
  65. package/dist/utils/actions.js +89 -0
  66. package/dist/utils/actions.js.map +1 -0
  67. package/dist/utils/browser.d.ts +22 -0
  68. package/dist/utils/browser.d.ts.map +1 -0
  69. package/dist/utils/browser.js +122 -0
  70. package/dist/utils/browser.js.map +1 -0
  71. package/dist/utils/page-snapshot.d.ts +11 -0
  72. package/dist/utils/page-snapshot.d.ts.map +1 -0
  73. package/dist/utils/page-snapshot.js +102 -0
  74. package/dist/utils/page-snapshot.js.map +1 -0
  75. package/dist/walker/action-planner.d.ts +15 -0
  76. package/dist/walker/action-planner.d.ts.map +1 -0
  77. package/dist/walker/action-planner.js +236 -0
  78. package/dist/walker/action-planner.js.map +1 -0
  79. package/dist/walker/flow-walker.d.ts +10 -0
  80. package/dist/walker/flow-walker.d.ts.map +1 -0
  81. package/dist/walker/flow-walker.js +107 -0
  82. package/dist/walker/flow-walker.js.map +1 -0
  83. package/dist/walker/session-recorder.d.ts +28 -0
  84. package/dist/walker/session-recorder.d.ts.map +1 -0
  85. package/dist/walker/session-recorder.js +90 -0
  86. package/dist/walker/session-recorder.js.map +1 -0
  87. package/package.json +71 -0
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Compare sessions from multiple personas on the same flow.
3
+ * Identifies shared friction points and divergence points.
4
+ */
5
+ export function comparePersonaSessions(sessions) {
6
+ if (sessions.length === 0) {
7
+ return {
8
+ personas: [],
9
+ sessions: [],
10
+ sharedFriction: [],
11
+ divergencePoints: [],
12
+ overallRecommendations: [],
13
+ };
14
+ }
15
+ const personas = sessions.map((s) => s.persona);
16
+ // Find friction points that appear across multiple personas
17
+ const frictionByUrl = new Map();
18
+ for (const session of sessions) {
19
+ for (const step of session.steps) {
20
+ for (const friction of step.frictionPoints) {
21
+ const urlFriction = frictionByUrl.get(friction.location) ?? [];
22
+ // Check if similar friction already recorded
23
+ const existing = urlFriction.find((f) => f.friction.description === friction.description);
24
+ if (existing) {
25
+ existing.personas.add(session.persona.name);
26
+ }
27
+ else {
28
+ urlFriction.push({
29
+ friction,
30
+ personas: new Set([session.persona.name]),
31
+ });
32
+ }
33
+ frictionByUrl.set(friction.location, urlFriction);
34
+ }
35
+ }
36
+ }
37
+ // Shared friction = friction experienced by 2+ personas
38
+ const sharedFriction = [];
39
+ for (const [, frictionList] of frictionByUrl) {
40
+ for (const item of frictionList) {
41
+ if (item.personas.size >= 2) {
42
+ sharedFriction.push(item.friction);
43
+ }
44
+ }
45
+ }
46
+ // Divergence points: steps where personas took different actions on the same URL
47
+ const divergencePoints = [];
48
+ // Build URL → persona action map per step index
49
+ const maxSteps = Math.max(...sessions.map((s) => s.steps.length));
50
+ for (let step = 0; step < Math.min(maxSteps, 20); step++) {
51
+ const actionsAtStep = [];
52
+ for (const session of sessions) {
53
+ const sessionStep = session.steps[step];
54
+ if (sessionStep) {
55
+ actionsAtStep.push({
56
+ persona: session.persona.name,
57
+ action: `${sessionStep.action.type}${sessionStep.action.target ? ` → ${sessionStep.action.target}` : ""}`,
58
+ thought: sessionStep.thought,
59
+ url: sessionStep.page.url,
60
+ });
61
+ }
62
+ }
63
+ // Check if actions diverge
64
+ const uniqueActions = new Set(actionsAtStep.map((a) => a.action));
65
+ if (uniqueActions.size > 1 && actionsAtStep.length > 1) {
66
+ divergencePoints.push({
67
+ step,
68
+ url: actionsAtStep[0].url,
69
+ personaActions: actionsAtStep.map((a) => ({
70
+ persona: a.persona,
71
+ action: a.action,
72
+ thought: a.thought,
73
+ })),
74
+ });
75
+ }
76
+ }
77
+ // Generate overall recommendations
78
+ const overallRecommendations = [];
79
+ if (sharedFriction.length > 0) {
80
+ overallRecommendations.push(`Fix ${sharedFriction.length} shared friction point(s) first — these affect ALL user types`);
81
+ }
82
+ const failedSessions = sessions.filter((s) => !s.summary.goalAchieved);
83
+ if (failedSessions.length > 0) {
84
+ const failedPersonas = failedSessions.map((s) => s.persona.name).join(", ");
85
+ overallRecommendations.push(`${failedSessions.length}/${sessions.length} personas could not achieve their goal (${failedPersonas})`);
86
+ }
87
+ const avgFriction = sessions.reduce((sum, s) => sum + s.summary.frictionScore, 0) / sessions.length;
88
+ if (avgFriction > 5) {
89
+ overallRecommendations.push(`Average friction score is ${avgFriction.toFixed(1)}/10 — the flow needs significant UX improvement`);
90
+ }
91
+ if (divergencePoints.length > 3) {
92
+ overallRecommendations.push(`${divergencePoints.length} divergence points found — the UI is interpreted differently by different user types`);
93
+ }
94
+ return {
95
+ personas,
96
+ sessions: [...sessions],
97
+ sharedFriction,
98
+ divergencePoints,
99
+ overallRecommendations,
100
+ };
101
+ }
102
+ /**
103
+ * Generate a markdown comparison report.
104
+ */
105
+ export function generateComparisonReport(comparison) {
106
+ const lines = [];
107
+ lines.push(`# Multi-Persona Comparison Report`);
108
+ lines.push(``);
109
+ lines.push(`**Personas tested:** ${comparison.personas.map((p) => p.name).join(", ")}`);
110
+ lines.push(``);
111
+ // Summary table
112
+ lines.push(`## Session Summary`);
113
+ lines.push(``);
114
+ lines.push(`| Persona | Steps | Friction | Goal | Emotional Trend |`);
115
+ lines.push(`|---------|-------|----------|------|-----------------|`);
116
+ for (const session of comparison.sessions) {
117
+ lines.push(`| ${session.persona.name} | ${session.summary.totalSteps} | ${session.summary.frictionScore}/10 | ${session.summary.goalAchieved ? "✅" : "❌"} | ${session.summary.emotionalJourney[session.summary.emotionalJourney.length - 1] ?? "n/a"} |`);
118
+ }
119
+ lines.push(``);
120
+ // Shared friction
121
+ if (comparison.sharedFriction.length > 0) {
122
+ lines.push(`## Shared Friction Points (affect all users)`);
123
+ lines.push(``);
124
+ for (const friction of comparison.sharedFriction) {
125
+ lines.push(`- **[${friction.severity.toUpperCase()}]** ${friction.description}`);
126
+ lines.push(` → ${friction.suggestion}`);
127
+ }
128
+ lines.push(``);
129
+ }
130
+ // Divergence points
131
+ if (comparison.divergencePoints.length > 0) {
132
+ lines.push(`## Divergence Points`);
133
+ lines.push(``);
134
+ lines.push(`These are moments where different personas interpreted the UI differently:`);
135
+ lines.push(``);
136
+ for (const dp of comparison.divergencePoints.slice(0, 10)) {
137
+ lines.push(`### Step ${dp.step} — ${dp.url}`);
138
+ for (const pa of dp.personaActions) {
139
+ lines.push(`- **${pa.persona}:** ${pa.action}`);
140
+ lines.push(` > ${pa.thought}`);
141
+ }
142
+ lines.push(``);
143
+ }
144
+ }
145
+ // Overall recommendations
146
+ if (comparison.overallRecommendations.length > 0) {
147
+ lines.push(`## Overall Recommendations`);
148
+ lines.push(``);
149
+ for (let i = 0; i < comparison.overallRecommendations.length; i++) {
150
+ lines.push(`${i + 1}. ${comparison.overallRecommendations[i]}`);
151
+ }
152
+ lines.push(``);
153
+ }
154
+ return lines.join("\n");
155
+ }
156
+ //# sourceMappingURL=comparison.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparison.js","sourceRoot":"","sources":["../../src/feedback/comparison.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { UserSession, EmotionalState } from "../types.js";
2
+ /**
3
+ * Generate a complete markdown feedback report from a user session.
4
+ */
5
+ export declare function generateSessionReport(session: UserSession): string;
6
+ /**
7
+ * Generate a brief first-impression report.
8
+ */
9
+ export declare function generateQuickImpressionReport(params: {
10
+ readonly url: string;
11
+ readonly personaName: string;
12
+ readonly firstImpression: string;
13
+ readonly whatItDoes: string;
14
+ readonly clarityScore: number;
15
+ readonly emotionalReaction: EmotionalState;
16
+ readonly wouldContinue: boolean;
17
+ readonly reasoning: string;
18
+ }): string;
19
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/feedback/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAA8B,cAAc,EAAE,MAAM,aAAa,CAAC;AAuB3F;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CA4FlE;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE;IACpD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,cAAc,CAAC;IAC3C,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,GAAG,MAAM,CAoBT"}
@@ -0,0 +1,139 @@
1
+ import { analyzeEmotionalArc, summarizeEmotionalArc } from "../analysis/emotional-arc.js";
2
+ import { assessCognitiveLoad } from "../analysis/cognitive-load.js";
3
+ import { assessClarity } from "../analysis/clarity.js";
4
+ const EMOTION_ICONS = {
5
+ curious: "🔍",
6
+ confident: "✅",
7
+ neutral: "😐",
8
+ confused: "❓",
9
+ frustrated: "😤",
10
+ delighted: "😊",
11
+ anxious: "😰",
12
+ bored: "😴",
13
+ };
14
+ const SEVERITY_ICONS = {
15
+ low: "💡",
16
+ medium: "⚠️",
17
+ high: "🛑",
18
+ critical: "🚨",
19
+ };
20
+ /**
21
+ * Generate a complete markdown feedback report from a user session.
22
+ */
23
+ export function generateSessionReport(session) {
24
+ const { persona, steps, summary } = session;
25
+ const arc = analyzeEmotionalArc(steps);
26
+ const arcSummary = summarizeEmotionalArc(arc);
27
+ const lines = [];
28
+ // Header
29
+ lines.push(`# UserFlow Session Report`);
30
+ lines.push(``);
31
+ lines.push(`**URL:** ${session.startUrl}`);
32
+ lines.push(`**Persona:** ${persona.name} — ${persona.description}`);
33
+ lines.push(`**Background:** ${persona.background}`);
34
+ lines.push(`**Goals:** ${persona.goals.join(", ")}`);
35
+ lines.push(`**Tech Literacy:** ${persona.traits.techLiteracy} | **Patience:** ${persona.traits.patience} | **Device:** ${persona.traits.devicePreference}`);
36
+ lines.push(`**Started:** ${session.startedAt} | **Completed:** ${session.completedAt}`);
37
+ lines.push(``);
38
+ // Summary card
39
+ lines.push(`## Summary`);
40
+ lines.push(``);
41
+ lines.push(`| Metric | Value |`);
42
+ lines.push(`|--------|-------|`);
43
+ lines.push(`| Steps taken | ${summary.totalSteps} |`);
44
+ lines.push(`| Friction score | **${summary.frictionScore}/10** ${frictionLabel(summary.frictionScore)} |`);
45
+ lines.push(`| Goal achieved | ${summary.goalAchieved ? "✅ Yes" : "❌ No"} |`);
46
+ lines.push(`| Drop-off risk | ${summary.dropOffRisk} |`);
47
+ lines.push(`| Emotional trend | ${arc.trend} |`);
48
+ lines.push(``);
49
+ // Emotional journey
50
+ lines.push(`## Emotional Journey`);
51
+ lines.push(``);
52
+ lines.push(summary.emotionalJourney.map((e, i) => `Step ${i}: ${EMOTION_ICONS[e]} ${e}`).join(" → "));
53
+ lines.push(``);
54
+ lines.push(arcSummary);
55
+ lines.push(``);
56
+ // Step-by-step walkthrough
57
+ lines.push(`## Step-by-Step Walkthrough`);
58
+ lines.push(``);
59
+ for (const step of steps) {
60
+ lines.push(`### Step ${step.index}: ${step.page.title || step.page.url}`);
61
+ lines.push(``);
62
+ lines.push(`${EMOTION_ICONS[step.emotionalState]} **${step.emotionalState}** | ${step.action.type}${step.action.target ? ` → \`${step.action.target}\`` : ""}`);
63
+ lines.push(``);
64
+ lines.push(`> ${step.thought}`);
65
+ lines.push(``);
66
+ // Page analysis (for first and key steps)
67
+ if (step.index === 0 || step.frictionPoints.length > 0) {
68
+ const cogLoad = assessCognitiveLoad(step.page);
69
+ const clarity = assessClarity(step.page);
70
+ lines.push(`📊 Cognitive Load: ${cogLoad.score}/10 (${cogLoad.visualComplexity}) | Clarity: ${clarity.score}/10`);
71
+ lines.push(``);
72
+ }
73
+ // Friction points
74
+ if (step.frictionPoints.length > 0) {
75
+ for (const friction of step.frictionPoints) {
76
+ lines.push(`${SEVERITY_ICONS[friction.severity]} **${friction.severity.toUpperCase()}:** ${friction.description}`);
77
+ lines.push(` → ${friction.suggestion}`);
78
+ }
79
+ lines.push(``);
80
+ }
81
+ }
82
+ // Top friction points
83
+ if (summary.topFrictionPoints.length > 0) {
84
+ lines.push(`## Top Friction Points`);
85
+ lines.push(``);
86
+ lines.push(`| # | Severity | Issue | Suggestion |`);
87
+ lines.push(`|---|----------|-------|------------|`);
88
+ for (let i = 0; i < summary.topFrictionPoints.length; i++) {
89
+ const f = summary.topFrictionPoints[i];
90
+ lines.push(`| ${i + 1} | ${SEVERITY_ICONS[f.severity]} ${f.severity} | ${f.description} | ${f.suggestion} |`);
91
+ }
92
+ lines.push(``);
93
+ }
94
+ // Recommendations
95
+ if (summary.recommendations.length > 0) {
96
+ lines.push(`## Recommendations`);
97
+ lines.push(``);
98
+ for (let i = 0; i < summary.recommendations.length; i++) {
99
+ lines.push(`${i + 1}. ${summary.recommendations[i]}`);
100
+ }
101
+ lines.push(``);
102
+ }
103
+ return lines.join("\n");
104
+ }
105
+ /**
106
+ * Generate a brief first-impression report.
107
+ */
108
+ export function generateQuickImpressionReport(params) {
109
+ const lines = [];
110
+ lines.push(`# Quick Impression Report`);
111
+ lines.push(``);
112
+ lines.push(`**URL:** ${params.url}`);
113
+ lines.push(`**Persona:** ${params.personaName}`);
114
+ lines.push(``);
115
+ lines.push(`## First Impression`);
116
+ lines.push(``);
117
+ lines.push(`> ${params.firstImpression}`);
118
+ lines.push(``);
119
+ lines.push(`**What the user thinks it does:** ${params.whatItDoes}`);
120
+ lines.push(`**Clarity score:** ${params.clarityScore}/10`);
121
+ lines.push(`**Emotional reaction:** ${EMOTION_ICONS[params.emotionalReaction]} ${params.emotionalReaction}`);
122
+ lines.push(`**Would continue:** ${params.wouldContinue ? "✅ Yes" : "❌ No"}`);
123
+ lines.push(``);
124
+ lines.push(`**Reasoning:** ${params.reasoning}`);
125
+ lines.push(``);
126
+ return lines.join("\n");
127
+ }
128
+ function frictionLabel(score) {
129
+ if (score <= 2)
130
+ return "(Low — smooth experience)";
131
+ if (score <= 4)
132
+ return "(Moderate — some bumps)";
133
+ if (score <= 6)
134
+ return "(High — significant friction)";
135
+ if (score <= 8)
136
+ return "(Very High — likely abandonment)";
137
+ return "(Critical — broken experience)";
138
+ }
139
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/feedback/generator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,aAAa,GAA6C;IAC9D,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,GAAG;IACd,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,GAAG;IACb,UAAU,EAAE,IAAI;IAChB,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,IAAI;IACb,KAAK,EAAE,IAAI;CACZ,CAAC;AAEF,MAAM,cAAc,GAAqC;IACvD,GAAG,EAAE,IAAI;IACT,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,IAAI;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAoB;IACxD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC5C,MAAM,GAAG,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAE9C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,SAAS;IACT,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACxC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC3C,KAAK,CAAC,IAAI,CAAC,gBAAgB,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACpE,KAAK,CAAC,IAAI,CAAC,mBAAmB,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACpD,KAAK,CAAC,IAAI,CAAC,cAAc,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrD,KAAK,CAAC,IAAI,CAAC,sBAAsB,OAAO,CAAC,MAAM,CAAC,YAAY,oBAAoB,OAAO,CAAC,MAAM,CAAC,QAAQ,kBAAkB,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAC5J,KAAK,CAAC,IAAI,CAAC,gBAAgB,OAAO,CAAC,SAAS,qBAAqB,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACxF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,eAAe;IACf,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACjC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACjC,KAAK,CAAC,IAAI,CAAC,mBAAmB,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;IACtD,KAAK,CAAC,IAAI,CAAC,wBAAwB,OAAO,CAAC,aAAa,SAAS,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC3G,KAAK,CAAC,IAAI,CAAC,qBAAqB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;IAC7E,KAAK,CAAC,IAAI,CAAC,qBAAqB,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,uBAAuB,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;IACjD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,oBAAoB;IACpB,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACnC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACtG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,2BAA2B;IAC3B,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,IAAI,CAAC,cAAc,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChK,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEf,0CAA0C;QAC1C,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvD,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,sBAAsB,OAAO,CAAC,KAAK,QAAQ,OAAO,CAAC,gBAAgB,gBAAgB,OAAO,CAAC,KAAK,KAAK,CAAC,CAAC;YAClH,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QAED,kBAAkB;QAClB,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC3C,KAAK,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;gBACnH,KAAK,CAAC,IAAI,CAAC,QAAQ,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YAC5C,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,IAAI,OAAO,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACpD,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1D,MAAM,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,WAAW,MAAM,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC;QAChH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,kBAAkB;IAClB,IAAI,OAAO,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,6BAA6B,CAAC,MAS7C;IACC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACxC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IACrC,KAAK,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IACjD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAClC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC;IAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,qCAAqC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IACrE,KAAK,CAAC,IAAI,CAAC,sBAAsB,MAAM,CAAC,YAAY,KAAK,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,2BAA2B,aAAa,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAC7G,KAAK,CAAC,IAAI,CAAC,uBAAuB,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IACjD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,2BAA2B,CAAC;IACnD,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,yBAAyB,CAAC;IACjD,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,+BAA+B,CAAC;IACvD,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,kCAAkC,CAAC;IAC1D,OAAO,gCAAgC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { UserSession, PersonaComparison } from "../types.js";
2
+ /**
3
+ * Generate a standalone HTML report from a user session.
4
+ */
5
+ export declare function generateHtmlReport(session: UserSession): string;
6
+ /**
7
+ * Generate an HTML comparison report for multiple personas.
8
+ */
9
+ export declare function generateHtmlComparisonReport(comparison: PersonaComparison): string;
10
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/feedback/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIlE;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAwF/D;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,iBAAiB,GAAG,MAAM,CAqBlF"}
@@ -0,0 +1,123 @@
1
+ import { generateSessionReport } from "./generator.js";
2
+ import { generateComparisonReport } from "./comparison.js";
3
+ /**
4
+ * Generate a standalone HTML report from a user session.
5
+ */
6
+ export function generateHtmlReport(session) {
7
+ const markdown = generateSessionReport(session);
8
+ const { persona, summary } = session;
9
+ const frictionColor = summary.frictionScore <= 3 ? "#22c55e"
10
+ : summary.frictionScore <= 6 ? "#eab308"
11
+ : "#ef4444";
12
+ return `<!DOCTYPE html>
13
+ <html lang="en">
14
+ <head>
15
+ <meta charset="UTF-8">
16
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
17
+ <title>UserFlow Report — ${persona.name} on ${session.startUrl}</title>
18
+ <style>
19
+ * { margin: 0; padding: 0; box-sizing: border-box; }
20
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #1a1a2e; background: #f8f9fa; padding: 2rem; max-width: 900px; margin: 0 auto; }
21
+ h1 { font-size: 1.8rem; margin-bottom: 0.5rem; color: #1a1a2e; }
22
+ h2 { font-size: 1.3rem; margin: 2rem 0 1rem; color: #16213e; border-bottom: 2px solid #e2e8f0; padding-bottom: 0.5rem; }
23
+ h3 { font-size: 1.1rem; margin: 1.5rem 0 0.5rem; color: #0f3460; }
24
+ .card { background: white; border-radius: 12px; padding: 1.5rem; margin-bottom: 1.5rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
25
+ .metric { display: inline-block; padding: 0.5rem 1rem; border-radius: 8px; margin: 0.25rem; font-weight: 600; }
26
+ .friction-score { background: ${frictionColor}20; color: ${frictionColor}; font-size: 1.5rem; padding: 0.75rem 1.5rem; }
27
+ .goal-yes { background: #22c55e20; color: #22c55e; }
28
+ .goal-no { background: #ef444420; color: #ef4444; }
29
+ table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
30
+ th, td { padding: 0.75rem; text-align: left; border-bottom: 1px solid #e2e8f0; }
31
+ th { background: #f1f5f9; font-weight: 600; }
32
+ blockquote { border-left: 3px solid #6366f1; padding-left: 1rem; margin: 1rem 0; color: #4a5568; font-style: italic; }
33
+ .step { border-left: 3px solid #e2e8f0; padding-left: 1rem; margin: 1rem 0; }
34
+ .step.has-friction { border-left-color: #ef4444; }
35
+ .friction-tag { display: inline-block; padding: 0.2rem 0.5rem; border-radius: 4px; font-size: 0.8rem; font-weight: 600; margin-right: 0.5rem; }
36
+ .friction-low { background: #dbeafe; color: #1d4ed8; }
37
+ .friction-medium { background: #fef3c7; color: #92400e; }
38
+ .friction-high { background: #fee2e2; color: #991b1b; }
39
+ .friction-critical { background: #991b1b; color: white; }
40
+ .emotion-bar { display: flex; gap: 0.25rem; margin: 1rem 0; flex-wrap: wrap; }
41
+ .emotion-step { padding: 0.3rem 0.6rem; border-radius: 6px; font-size: 0.8rem; background: #f1f5f9; }
42
+ .persona-info { color: #64748b; font-size: 0.9rem; }
43
+ footer { margin-top: 3rem; text-align: center; color: #94a3b8; font-size: 0.85rem; }
44
+ </style>
45
+ </head>
46
+ <body>
47
+ <div class="card">
48
+ <h1>UserFlow Session Report</h1>
49
+ <p class="persona-info"><strong>${persona.name}</strong> — ${persona.description}</p>
50
+ <p class="persona-info">Goals: ${persona.goals.join(", ")}</p>
51
+ <p class="persona-info">URL: <a href="${session.startUrl}">${session.startUrl}</a></p>
52
+ </div>
53
+
54
+ <div class="card">
55
+ <h2>Summary</h2>
56
+ <span class="metric friction-score">Friction: ${summary.frictionScore}/10</span>
57
+ <span class="metric ${summary.goalAchieved ? "goal-yes" : "goal-no"}">${summary.goalAchieved ? "Goal Achieved ✅" : "Goal Not Achieved ❌"}</span>
58
+ <span class="metric" style="background: #f1f5f9;">${summary.totalSteps} steps</span>
59
+
60
+ <h3>Emotional Journey</h3>
61
+ <div class="emotion-bar">
62
+ ${summary.emotionalJourney.map((e, i) => `<span class="emotion-step">Step ${i}: ${e}</span>`).join("\n ")}
63
+ </div>
64
+ <p>${summary.dropOffRisk}</p>
65
+ </div>
66
+
67
+ ${session.steps.length > 0 ? `
68
+ <div class="card">
69
+ <h2>Step-by-Step Walkthrough</h2>
70
+ ${session.steps.map((step) => `
71
+ <div class="step ${step.frictionPoints.length > 0 ? "has-friction" : ""}">
72
+ <h3>Step ${step.index}: ${step.page.title || step.page.url}</h3>
73
+ <p><strong>${step.emotionalState}</strong> | ${step.action.type}${step.action.target ? ` → <code>${step.action.target}</code>` : ""}</p>
74
+ <blockquote>${step.thought}</blockquote>
75
+ ${step.frictionPoints.map((f) => `<p><span class="friction-tag friction-${f.severity}">${f.severity.toUpperCase()}</span> ${f.description}<br><em>→ ${f.suggestion}</em></p>`).join("\n ")}
76
+ </div>`).join("\n")}
77
+ </div>` : ""}
78
+
79
+ ${summary.recommendations.length > 0 ? `
80
+ <div class="card">
81
+ <h2>Recommendations</h2>
82
+ <ol>
83
+ ${summary.recommendations.map((r) => `<li>${r}</li>`).join("\n ")}
84
+ </ol>
85
+ </div>` : ""}
86
+
87
+ <footer>
88
+ Generated by <strong>UserFlow MCP</strong> — Persona-based UX feedback for developers
89
+ </footer>
90
+ </body>
91
+ </html>`;
92
+ }
93
+ /**
94
+ * Generate an HTML comparison report for multiple personas.
95
+ */
96
+ export function generateHtmlComparisonReport(comparison) {
97
+ const markdown = generateComparisonReport(comparison);
98
+ // For comparison reports, use markdown-based output wrapped in basic HTML
99
+ return `<!DOCTYPE html>
100
+ <html lang="en">
101
+ <head>
102
+ <meta charset="UTF-8">
103
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
104
+ <title>UserFlow Multi-Persona Comparison</title>
105
+ <style>
106
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #1a1a2e; background: #f8f9fa; padding: 2rem; max-width: 900px; margin: 0 auto; }
107
+ pre { background: #f1f5f9; padding: 1rem; border-radius: 8px; overflow-x: auto; white-space: pre-wrap; }
108
+ footer { margin-top: 3rem; text-align: center; color: #94a3b8; font-size: 0.85rem; }
109
+ </style>
110
+ </head>
111
+ <body>
112
+ <pre>${escapeHtml(markdown)}</pre>
113
+ <footer>Generated by <strong>UserFlow MCP</strong></footer>
114
+ </body>
115
+ </html>`;
116
+ }
117
+ function escapeHtml(text) {
118
+ return text
119
+ .replace(/&/g, "&amp;")
120
+ .replace(/</g, "&lt;")
121
+ .replace(/>/g, "&gt;");
122
+ }
123
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/feedback/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { createServer } from "./server.js";
4
+ async function main() {
5
+ const server = createServer();
6
+ const transport = new StdioServerTransport();
7
+ await server.connect(transport);
8
+ }
9
+ main().catch((error) => {
10
+ console.error("Fatal error starting UserFlow MCP server:", error);
11
+ process.exit(1);
12
+ });
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,2CAA2C,EAAE,KAAK,CAAC,CAAC;IAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,39 @@
1
+ import type { Persona, PersonaTraits } from "../types.js";
2
+ import { PERSONA_PRESETS, getPresetByName, getPresetById } from "./presets.js";
3
+ export { PERSONA_PRESETS, getPresetByName, getPresetById };
4
+ /**
5
+ * Create a custom persona from user-provided parameters.
6
+ * Merges provided traits with sensible defaults.
7
+ */
8
+ export declare function createCustomPersona(params: {
9
+ readonly name: string;
10
+ readonly description: string;
11
+ readonly background?: string;
12
+ readonly goals: readonly string[];
13
+ readonly traits?: Partial<PersonaTraits>;
14
+ readonly behaviorNotes?: readonly string[];
15
+ }): Persona;
16
+ /**
17
+ * Resolve a persona from a name/id string. Checks presets first, returns undefined if not found.
18
+ */
19
+ export declare function resolvePersona(nameOrId: string): Persona | undefined;
20
+ /**
21
+ * Get the maximum steps this persona will take before giving up.
22
+ */
23
+ export declare function getMaxSteps(persona: Persona): number;
24
+ /**
25
+ * Get the probability (0-1) this persona discovers a non-obvious UI element.
26
+ */
27
+ export declare function getDiscoveryProbability(persona: Persona): number;
28
+ /**
29
+ * Get viewport dimensions for this persona's device preference.
30
+ */
31
+ export declare function getViewport(persona: Persona): {
32
+ readonly width: number;
33
+ readonly height: number;
34
+ };
35
+ /**
36
+ * List all available preset persona names.
37
+ */
38
+ export declare function listPresetNames(): readonly string[];
39
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/personas/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG/E,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C,GAAG,OAAO,CAoBV;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAEpE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAEhE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAEjG;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,SAAS,MAAM,EAAE,CAEnD"}
@@ -0,0 +1,58 @@
1
+ import { PERSONA_PRESETS, getPresetByName, getPresetById } from "./presets.js";
2
+ import { PATIENCE_STEP_LIMITS, DISCOVERY_PROBABILITY, DEVICE_VIEWPORTS } from "./types.js";
3
+ export { PERSONA_PRESETS, getPresetByName, getPresetById };
4
+ /**
5
+ * Create a custom persona from user-provided parameters.
6
+ * Merges provided traits with sensible defaults.
7
+ */
8
+ export function createCustomPersona(params) {
9
+ const defaultTraits = {
10
+ techLiteracy: "intermediate",
11
+ patience: "moderate",
12
+ ageGroup: "adult",
13
+ devicePreference: "desktop",
14
+ accessibilityNeeds: ["none"],
15
+ domainKnowledge: 5,
16
+ attentionToDetail: 5,
17
+ };
18
+ return {
19
+ id: `custom-${params.name.toLowerCase().replace(/\s+/g, "-")}-${Date.now()}`,
20
+ name: params.name,
21
+ description: params.description,
22
+ background: params.background ?? `Custom persona: ${params.description}`,
23
+ goals: params.goals,
24
+ traits: { ...defaultTraits, ...params.traits },
25
+ behaviorNotes: params.behaviorNotes ?? [],
26
+ };
27
+ }
28
+ /**
29
+ * Resolve a persona from a name/id string. Checks presets first, returns undefined if not found.
30
+ */
31
+ export function resolvePersona(nameOrId) {
32
+ return getPresetByName(nameOrId) ?? getPresetById(nameOrId);
33
+ }
34
+ /**
35
+ * Get the maximum steps this persona will take before giving up.
36
+ */
37
+ export function getMaxSteps(persona) {
38
+ return PATIENCE_STEP_LIMITS[persona.traits.patience] ?? 12;
39
+ }
40
+ /**
41
+ * Get the probability (0-1) this persona discovers a non-obvious UI element.
42
+ */
43
+ export function getDiscoveryProbability(persona) {
44
+ return DISCOVERY_PROBABILITY[persona.traits.techLiteracy] ?? 0.5;
45
+ }
46
+ /**
47
+ * Get viewport dimensions for this persona's device preference.
48
+ */
49
+ export function getViewport(persona) {
50
+ return DEVICE_VIEWPORTS[persona.traits.devicePreference] ?? DEVICE_VIEWPORTS.desktop;
51
+ }
52
+ /**
53
+ * List all available preset persona names.
54
+ */
55
+ export function listPresetNames() {
56
+ return PERSONA_PRESETS.map((p) => p.name);
57
+ }
58
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/personas/engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE3F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC;AAE3D;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAOnC;IACC,MAAM,aAAa,GAAkB;QACnC,YAAY,EAAE,cAAc;QAC5B,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE,OAAO;QACjB,gBAAgB,EAAE,SAAS;QAC3B,kBAAkB,EAAE,CAAC,MAAM,CAAC;QAC5B,eAAe,EAAE,CAAC;QAClB,iBAAiB,EAAE,CAAC;KACrB,CAAC;IAEF,OAAO;QACL,EAAE,EAAE,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE;QAC5E,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,mBAAmB,MAAM,CAAC,WAAW,EAAE;QACxE,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,EAAE,GAAG,aAAa,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE;QAC9C,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,EAAE;KAC1C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,eAAe,CAAC,QAAQ,CAAC,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,OAAO,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,OAAO,qBAAqB,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,OAAO,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,CAAC,OAAO,CAAC;AACvF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Persona } from "../types.js";
2
+ export declare const PERSONA_PRESETS: readonly Persona[];
3
+ /**
4
+ * Find a preset persona by display name (case-insensitive).
5
+ */
6
+ export declare function getPresetByName(name: string): Persona | undefined;
7
+ /**
8
+ * Find a preset persona by its unique id.
9
+ */
10
+ export declare function getPresetById(id: string): Persona | undefined;
11
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/personas/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,eAAe,EAAE,SAAS,OAAO,EAoP7C,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAGjE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAE7D"}