@deina-labs/deina-core 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,190 @@
1
+ import type { StandardQuality, TimelineQuestionKey, MindsetQuestionKey, EnforcementQuestionKey, TradeOffQuestionKey } from './quiz-questions.js';
2
+
3
+ type StandardsAnswers = Record<StandardQuality, number | string | null>;
4
+ type TimelineAnswers = Record<TimelineQuestionKey, string | null>;
5
+ type MindsetAnswers = Record<MindsetQuestionKey, string | null>;
6
+ type EnforcementAnswers = Record<EnforcementQuestionKey, string | null>;
7
+ type TradeOffAnswers = Record<TradeOffQuestionKey, string | null>;
8
+
9
+ export function getStandardsHook(answers: StandardsAnswers): string {
10
+ const low = (key: StandardQuality) => {
11
+ const v = answers[key];
12
+ return typeof v === 'number' && v <= 2;
13
+ };
14
+ const high = (key: StandardQuality) => {
15
+ const v = answers[key];
16
+ return typeof v === 'number' && v >= 4;
17
+ };
18
+
19
+ // Follow-through option-based
20
+ const ft = answers.followThrough;
21
+ if (ft === 'I let it go — people forget' || ft === 'I notice but don\'t say anything') {
22
+ return 'You just admitted you let people break promises without saying a word. That\'s not patience — that\'s a pattern.';
23
+ }
24
+
25
+ // Long-term goals option-based
26
+ const ltg = answers.longTermGoals;
27
+ if (ltg === 'I avoid it because I\'m scared of what he\'ll say') {
28
+ return 'You\'d rather not know than hear something you can\'t handle. That fear is running more of your decisions than you think.';
29
+ }
30
+ if (ltg === 'I wait for him to bring it up') {
31
+ return 'You\'re waiting for someone else to decide your future. You already know that\'s a problem.';
32
+ }
33
+
34
+ if (high('physicalAttraction') && low('emotionalStability')) {
35
+ return 'You rated attraction high and emotional stability low. You already know which one keeps winning.';
36
+ }
37
+ if (low('communicationFrequency') && low('initiativeAndEffort')) {
38
+ return 'You rated communication and effort low. You\'ve trained yourself to expect less — and you\'re getting exactly that.';
39
+ }
40
+ if (high('initiativeAndEffort') && low('followThrough' as StandardQuality)) {
41
+ return 'You want him to lead but you don\'t hold him to his word. That gap is where most of your disappointment lives.';
42
+ }
43
+ if (low('emotionalAvailability')) {
44
+ return 'You rated emotional availability low. You\'ve accepted silence as normal — but that doesn\'t mean it doesn\'t hurt.';
45
+ }
46
+ if (high('weeklyConsistency') && low('communicationFrequency')) {
47
+ return 'You need to see him but you don\'t need to hear from him? Or have you just stopped asking for both?';
48
+ }
49
+
50
+ // Generic fallback based on overall pattern
51
+ const numericValues = Object.entries(answers)
52
+ .filter(([, v]) => typeof v === 'number')
53
+ .map(([, v]) => v as number);
54
+ const avg = numericValues.reduce((a, b) => a + b, 0) / numericValues.length;
55
+
56
+ if (avg <= 2.5) {
57
+ return 'Your standards are low across the board. Either you genuinely don\'t need much — or you\'ve given up on asking for what you actually want.';
58
+ }
59
+ if (avg >= 4) {
60
+ return 'You rated almost everything high. The real test is whether you actually walk away when someone doesn\'t meet them.';
61
+ }
62
+
63
+ return 'You know what you want. But knowing has never been your problem, has it?';
64
+ }
65
+
66
+ export function getTimelineHook(answers: TimelineAnswers): string {
67
+ if (answers.exclusivityExpectation === 'I avoid bringing it up') {
68
+ return 'You won\'t even ask where you stand. That silence isn\'t peace — it\'s fear.';
69
+ }
70
+ if (answers.intentionClarity === 'I wait for them to bring it up') {
71
+ return 'You\'re leaving the biggest decision to someone who hasn\'t earned that power yet.';
72
+ }
73
+ if (answers.progressionPace === 'I go with whatever he sets') {
74
+ return 'You just said you follow his pace. That means you don\'t have one — you have his.';
75
+ }
76
+ if (answers.communicationCadence === 'Only when there\'s a plan') {
77
+ return 'You only expect to hear from him when there\'s a plan. You\'ve made it easy to be forgotten between dates.';
78
+ }
79
+ if (answers.firstDateWindow === 'I don\'t push for it') {
80
+ return 'You don\'t push for a date. Which means you\'ll text someone for weeks hoping they eventually ask — and call it patience.';
81
+ }
82
+ if (answers.secondDateWindow === 'I try not to think about it') {
83
+ return 'You\'re trying not to think about it. That\'s not calm — that\'s anxiety disguised as chill.';
84
+ }
85
+ if (answers.meetFriendsFamily === 'I don\'t push for it') {
86
+ return 'You don\'t push to be part of his real life. You\'re fine existing only in private — and that should worry you.';
87
+ }
88
+ if (answers.progressionPace === 'I move fast when I\'m excited') {
89
+ return 'You move fast when you\'re excited. That excitement has probably cost you clarity more than once.';
90
+ }
91
+
92
+ return 'Your timeline tells a story you might not want to hear. The pace you accept is the pace you\'ll always get.';
93
+ }
94
+
95
+ export function getMindsetHook(answers: MindsetAnswers): string {
96
+ if (answers.relationshipRole === 'It would finally make me feel chosen') {
97
+ return 'You said a relationship would make you feel chosen. That means right now, you don\'t feel like you are.';
98
+ }
99
+ if (answers.relationshipRole === 'It would fill a void I feel right now') {
100
+ return 'You said a relationship would fill a void. That void doesn\'t go away when someone shows up — it just gets louder when they leave.';
101
+ }
102
+ if (answers.effortInterpretation === 'I probably did something wrong') {
103
+ return 'His effort dropped and your first thought was that it\'s your fault. That instinct is protecting him, not you.';
104
+ }
105
+ if (answers.ambiguityTolerance === 'I replay everything trying to figure out what I did') {
106
+ return 'You replay conversations looking for what you did wrong. You\'re investigating yourself instead of evaluating him.';
107
+ }
108
+ if (answers.ambiguityTolerance === 'I convince myself he\'s losing interest and start spiraling') {
109
+ return 'One dry day and you\'re already spiraling. That\'s not intuition — that\'s anxiety making decisions for you.';
110
+ }
111
+ if (answers.emotionalInvestmentSpeed === 'Immediately — I can already picture it') {
112
+ return 'One date and you\'re already picturing a future. You fall for the idea of someone before you even know who they are.';
113
+ }
114
+
115
+ // Scale-based checks (stored as string numbers "1"-"5")
116
+ const fearOfLosing = Number(answers.fearOfLosingConnection);
117
+ if (fearOfLosing <= 2) {
118
+ return 'You said the urge to chase is strong. That urge has probably kept you in situations you should\'ve left a long time ago.';
119
+ }
120
+
121
+ const fulfillment = Number(answers.fulfillmentOutsideDating);
122
+ if (fulfillment <= 2) {
123
+ return 'You said your life feels like something is missing without a relationship. That means whoever shows up next has too much power before they\'ve earned any.';
124
+ }
125
+
126
+ const standardsConf = Number(answers.standardsConfidence);
127
+ if (standardsConf <= 2) {
128
+ return 'You doubt your own standards when you like someone. That\'s how you end up accepting things you said you never would.';
129
+ }
130
+
131
+ return 'The way you see yourself in the dynamic shapes everything — who you pick, what you accept, and how long you stay.';
132
+ }
133
+
134
+ export function getEnforcementHook(answers: EnforcementAnswers): string {
135
+ if (answers.disappointmentResponse === 'I try harder to make it work') {
136
+ return 'He disappointed you and your response was to try harder. You\'re rewarding the exact behavior that hurt you.';
137
+ }
138
+ if (answers.disappointmentResponse === 'I overthink it for days') {
139
+ return 'He disappointed you and you spent days overthinking it instead of addressing it. He moved on. You didn\'t.';
140
+ }
141
+ if (answers.cancelDowngrade === 'I usually let it go') {
142
+ return 'He keeps canceling and you keep letting it go. That\'s not forgiveness — that\'s teaching him your time doesn\'t matter.';
143
+ }
144
+ if (answers.noFollowUpResponse === 'I wait and hope he reaches out') {
145
+ return 'He went silent after a date and you waited. You already know what waiting gets you.';
146
+ }
147
+ if (answers.noFollowUpResponse === 'I pretend I didn\'t notice') {
148
+ return 'You noticed the silence. You just pretended you didn\'t. That\'s not strength — it\'s self-betrayal.';
149
+ }
150
+ if (answers.effortDecreaseDowngrade === 'I usually don\'t pull back') {
151
+ return 'His effort dropped and you stayed the same. You\'re giving someone full access to you while they give you less and less.';
152
+ }
153
+ if (answers.exclusivityNotDiscussed === 'I keep going and hope it comes up') {
154
+ return 'You\'re hoping exclusivity just happens. It won\'t. And the longer you wait, the more you\'re telling him it doesn\'t matter to you.';
155
+ }
156
+ if (answers.redFlagSpeed === 'Only if it\'s something serious') {
157
+ return 'You only act on red flags if they\'re serious. Which means every small one gets a pass — until they add up to something you can\'t ignore.';
158
+ }
159
+
160
+ return 'Your boundaries exist on paper. The question is whether they exist in practice.';
161
+ }
162
+
163
+ export function getTradeOffsHook(answers: TradeOffAnswers): string {
164
+ if (answers.pastPattern === 'I fall for potential instead of proof') {
165
+ return 'You said you fall for potential. That means you keep investing in who someone could be — instead of seeing who they actually are.';
166
+ }
167
+ if (answers.pastPattern === 'I stay way past the expiration date') {
168
+ return 'You said you stay too long. You already knew that. The question is why you keep doing it anyway.';
169
+ }
170
+ if (answers.pastPattern === 'I give too much too soon') {
171
+ return 'You said you give too much too soon. By the time you realize it, they already have everything — and you have nothing to protect.';
172
+ }
173
+ if (answers.consistencyVsChemistry === 'Intense chemistry, even if he\'s inconsistent') {
174
+ return 'You chose chemistry over consistency. That\'s the choice that keeps pulling you back to people who aren\'t good for you.';
175
+ }
176
+ if (answers.stabilityVsIntensity === 'The passionate, intense one') {
177
+ return 'You\'re drawn to intensity. But intensity without stability isn\'t passion — it\'s chaos that feels familiar.';
178
+ }
179
+ if (answers.earlyDatingTendency === 'I get emotionally attached too fast') {
180
+ return 'You get attached too fast. Which means by the time you see someone clearly, you\'re already too deep to walk away easily.';
181
+ }
182
+ if (answers.earlyDatingTendency === 'I keep a wall up no matter what') {
183
+ return 'You keep a wall up. It protects you — but it also makes sure no one ever gets close enough to actually stay.';
184
+ }
185
+ if (answers.toleratedFlaw === 'Won\'t commit at your pace') {
186
+ return 'The flaw you tolerate the longest is someone who won\'t commit. You already know what that says about you.';
187
+ }
188
+
189
+ return 'Your choices reveal a pattern. And patterns don\'t change until you see them clearly.';
190
+ }