@gymmymac/bob-widget 3.1.19 โ†’ 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,49 @@ All notable changes to the `@gymmymac/bob-widget` package will be documented in
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [v3.2.1] - 2026-02-15
9
+
10
+ ### Added
11
+ - ๐Ÿ“œ **Auto-Scroll to Highlighted Category**: Mobile/tablet product shelf now auto-scrolls to the matching partslot group when Bob mentions a specific part type (e.g. "front pads"), bringing parity with desktop behaviour
12
+
13
+ ### Changed
14
+ - ๐ŸŸข **PTT Idle Button Colour**: Changed from blue to green to match the breathing idle ring
15
+
16
+ ---
17
+
18
+ ## [v3.2.0] - 2026-02-15
19
+
20
+ ### Added
21
+ - ๐ŸŽฏ **PTT 4-State Visual Feedback**: Push-to-Talk button now provides visual cues via circumference rings and chat bar overlays across four states (idle, listening, processing, speaking)
22
+ - ๐ŸŸข **Green Idle PTT**: Idle state uses green button and breathing green ring to indicate "action required"
23
+ - ๐ŸŸ  **Orange Listening State**: Expanding orange wave rings around PTT + pulsing dot in chat bar
24
+ - โš™๏ธ **Processing Overlay**: Grey contracting ring + "Bob is researching your input." message in chat bar
25
+ - ๐Ÿ”Š **Speaking Waveform**: Green glowing ring + 5-bar CSS waveform visualizer in chat bar with muted warning icon
26
+
27
+ ### Changed
28
+ - ๐ŸŽจ **Chat Bar**: White background (#FFFFFF) with Deep Navy text (#0F172A) for high contrast โ€” enforced via `!important` overrides to prevent host-site bleeding
29
+ - ๐Ÿ”ค **Processing Text**: Changed from "Bob is thinking..." to "Bob is researching your input."
30
+ - ๐ŸŸข **PTT Button Colour**: Idle state changed from blue to green to match the idle ring
31
+
32
+ ### Fixed
33
+ - ๐ŸŽจ **Chat Bar Dark Blue Override**: Fixed `widget-reset.css` forcing dark blue background on inputs โ€” now forces white
34
+
35
+ ---
36
+
37
+ ## [3.1.20] - 2026-02-13
38
+
39
+ ### Added
40
+ - ๐Ÿ“ฆ **CARFIX Installation Brief**: README.md now serves as the comprehensive installation document with full container preparation requirements, anti-patterns table, pre-mount checklist, and layout diagram
41
+ - ๐Ÿงช **Quality Baseline Tests**: 36 unit tests locked in across rear brake filter, bundle discount pricing, and callback stability
42
+ - ๐Ÿ’ฐ **Bundle Discount Display**: Was/Now pricing with savings badges for service package tiers when `savingsAmount > 0`
43
+ - ๐Ÿ›’ **Bundle Cart Metadata**: Cart items from service packages now include `is_bundle_item`, `bundle_discount_percentage`, `service_package_name`, and `quality_tier`
44
+
45
+ ### Changed
46
+ - ๐Ÿ“– **README Overhaul**: Full installation brief is now front-and-center โ€” visible on npm, GitHub, and in `node_modules`
47
+ - ๐Ÿ“ **Container Anti-Patterns**: Documented all prohibited CSS properties (`overflow: hidden`, `transform`, etc.) that break Bob's layering
48
+
49
+ ---
50
+
8
51
  ## [3.1.19] - 2026-02-04
9
52
 
10
53
  ### Added
@@ -15,6 +58,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
15
58
  - ๐Ÿ”ข **Speech Count Alignment**: Bob's spoken variant count now matches the deduplicated UI cards shown on screen
16
59
  - ๐ŸŽด **Variant Card Display**: Cards now show specs-first format without characterization text
17
60
 
61
+ ### Documentation
62
+ - ๐Ÿ“ **bottomOffset Clarification**: `bottomOffset` prop only applies to fixed-position variants. Contained/embedded variants position relative to their container (which should already be sized to fit between header/footer).
63
+
18
64
  ---
19
65
 
20
66
  ## [3.1.18] - 2026-01-28
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # @gymmymac/bob-widget
2
2
 
3
- AI-powered automotive parts assistant widget for integration into partner websites.
3
+ AI-powered automotive parts assistant widget for partner websites.
4
4
 
5
- **Current Version:** 3.1.19
5
+ **Current Version:** v3.2.1 | **36 unit tests** | **8+ E2E scenarios** | Production-ready
6
6
 
7
7
  ---
8
8
 
9
- ## ๐Ÿšจ STOP - RUN THE INSTALLER FIRST
9
+ ## ๐Ÿšจ STOP โ€” RUN THE INSTALLER FIRST
10
10
 
11
11
  Bob v3.1.19 includes an **executable 3-stage installer**. Do NOT skip this step.
12
12
 
@@ -21,63 +21,460 @@ npx @gymmymac/bob-widget carfix stage-b --target next-pages --output pages/ask-b
21
21
  npx @gymmymac/bob-widget carfix stage-c --partner CARFIX
22
22
  ```
23
23
 
24
- ### ๐Ÿ“– Required Reading
24
+ ---
25
25
 
26
- | Document | Description |
27
- |----------|-------------|
28
- | **[BOB-DOCUMENTATION.md](./BOB-DOCUMENTATION.md)** | **Complete integration guide** - Contains CARFIX-specific installation steps, container height calculations, and verification tests. **START HERE.** |
29
- | **[CHANGELOG.md](./CHANGELOG.md)** | Version history and release notes |
30
- | **[install/carfix/](./install/carfix/)** | Installer scripts and templates |
26
+ ## 1. Peer Dependencies
31
27
 
32
- ### โš ๏ธ Critical Installation Notes
28
+ ```json
29
+ {
30
+ "peerDependencies": {
31
+ "react": "^18.0.0",
32
+ "react-dom": "^18.0.0"
33
+ }
34
+ }
35
+ ```
33
36
 
34
- 1. **3-Stage Installation Process**: Bob v3.1.19 requires a strict 3-stage installation via CLI. See the commands above.
35
- 2. **Container Height**: Bob requires `height: calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))` for CARFIX header/footer
36
- 3. **HTTPS Required**: Push-to-Talk (PTT) requires HTTPS - will be disabled on HTTP connections
37
- 4. **No Background Blur**: v3.1.10 removes hardcoded blur - background is crisp by default
37
+ > `@supabase/supabase-js` and `@tanstack/react-query` are bundled โ€” no action needed.
38
+ > If CARFIX already uses `@tanstack/react-query`, ensure v5+ compatibility.
38
39
 
39
40
  ---
40
41
 
41
- ## Quick Start
42
-
43
- After completing the 3-stage installation:
42
+ ## 2. Minimal Integration (4 Lines)
44
43
 
45
44
  ```tsx
46
45
  import { BobStandalone } from '@gymmymac/bob-widget';
47
46
 
48
- <BobStandalone
49
- partner="CARFIX"
50
- sessionToken={sessionToken}
51
- onAddToCart={(item) => addToCart(item)}
52
- onNavigate={(url) => router.push(url)}
53
- onCheckout={(url) => window.location.href = url}
54
- />
47
+ function AskBobPage() {
48
+ const router = useRouter();
49
+ const sessionToken = router.query.session as string;
50
+
51
+ return (
52
+ <div style={{
53
+ height: 'calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))',
54
+ position: 'relative',
55
+ /* DO NOT use overflow: hidden โ€” clips PTT button and chat drawer */
56
+ }}>
57
+ <BobStandalone
58
+ partner="CARFIX"
59
+ sessionToken={sessionToken}
60
+ bottomOffset={0}
61
+ zIndexBase={100}
62
+ onAddToCart={async (item) => await carfixCart.add(item)}
63
+ onNavigate={(url) => router.push(url)}
64
+ onCheckout={(checkoutUrl) => window.location.href = checkoutUrl}
65
+ onError={(error) => console.error('[Bob Error]', error)}
66
+ />
67
+ </div>
68
+ );
69
+ }
70
+ ```
71
+
72
+ > **Auto-configuration:** `partner="CARFIX"` loads all API URLs, credentials, layout defaults, and feature flags from the `bob_partners` database table. No manual config needed.
73
+
74
+ ---
75
+
76
+ ## 3. CARFIX API Configuration (Already in Database)
77
+
78
+ ```json
79
+ {
80
+ "baseUrl": "https://flpzjbasdsfwoeruyxgp.supabase.co/functions/v1",
81
+ "apiKey": "(anon key โ€” auto-loaded)",
82
+ "partnerCode": "CARFIX"
83
+ }
84
+ ```
85
+
86
+ ### Available Endpoints
87
+
88
+ | Endpoint | Purpose |
89
+ |---|---|
90
+ | `partner-api` | Session creation, cart, user context, orders |
91
+ | `calculate-service-bundles` | Service packs with `preparedTiers[]` (incl. bundle discounts) |
92
+ | `retrieve-vehicle-info` | NZ rego lookup |
93
+ | `retrieve-parts` | Vehicle parts by category |
94
+
95
+ ---
96
+
97
+ ## 4. Host Container Preparation (MANDATORY)
98
+
99
+ > โš ๏ธ **Bob will not render correctly if the host container is misconfigured.** Complete ALL items below before mounting `<BobStandalone>`.
100
+
101
+ ### 4.1 Container Requirements
102
+
103
+ The CARFIX page that hosts Bob **must** provide a container element with these exact properties:
104
+
105
+ ```css
106
+ /* The Bob container โ€” EVERY property is required */
107
+ .bob-container {
108
+ height: calc(100dvh - 144px - env(safe-area-inset-bottom, 0px));
109
+ position: relative;
110
+ width: 100%;
111
+
112
+ /* โŒ PROHIBITED โ€” these WILL break Bob */
113
+ /* overflow: hidden; โ† Clips PTT button, chat drawer, and expand handle */
114
+ /* overflow: clip; โ† Same issue on WebKit */
115
+ /* overflow: auto; โ† Creates nested scroll context, breaks shelf scrolling */
116
+ /* overflow: scroll; โ† Same as above */
117
+ /* transform: ...; โ† Creates new stacking context, breaks z-index layering */
118
+ }
119
+ ```
120
+
121
+ ```tsx
122
+ // โœ… Correct JSX
123
+ <div style={{
124
+ height: 'calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))',
125
+ position: 'relative',
126
+ width: '100%',
127
+ }}>
128
+ <BobStandalone partner="CARFIX" ... />
129
+ </div>
130
+
131
+ // โŒ WRONG โ€” overflow hidden clips Bob's interactive elements
132
+ <div style={{ height: '100%', overflow: 'hidden' }}>
133
+ <BobStandalone partner="CARFIX" ... />
134
+ </div>
135
+ ```
136
+
137
+ ### 4.2 Height Calculation Breakdown
138
+
139
+ | Component | Height | Notes |
140
+ |---|---|---|
141
+ | CARFIX Header | 72px | `position: fixed; top: 0; z-index: 40` |
142
+ | CARFIX Bottom Nav | 72px | `position: fixed; bottom: 0; z-index: 30` |
143
+ | **Total chrome** | **144px** | Subtracted from viewport |
144
+ | Safe area inset | Variable | For notched devices (iPhone, etc.) |
145
+ | **Bob container** | `100dvh - 144px - safe-area` | Everything between header and nav |
146
+
147
+ ### 4.3 Header & Bottom Nav Requirements
148
+
149
+ Bob's UI layers (chat drawer at z-130, PTT at z-145) must sit **above** CARFIX navigation:
150
+
151
+ ```css
152
+ /* CARFIX Header */
153
+ .carfix-header {
154
+ position: fixed;
155
+ top: 0;
156
+ left: 0;
157
+ right: 0;
158
+ height: 72px;
159
+ z-index: 40; /* Bob uses zIndexBase=100, so Bob layers above this */
160
+ }
161
+
162
+ /* CARFIX Bottom Nav */
163
+ .carfix-bottom-nav {
164
+ position: fixed;
165
+ bottom: 0;
166
+ left: 0;
167
+ right: 0;
168
+ height: 72px;
169
+ z-index: 30; /* Must be BELOW Bob's z-base of 100 */
170
+ }
171
+ ```
172
+
173
+ > **If your header or nav use `z-index: 50` or higher**, increase Bob's `zIndexBase` prop accordingly (e.g., `zIndexBase={150}`).
174
+
175
+ ### 4.4 Container Anti-Patterns (WILL CAUSE BUGS)
176
+
177
+ | โŒ Don't Do This | Why It Breaks |
178
+ |---|---|
179
+ | `overflow: hidden` on container | Clips PTT button, chat drawer, and expand handle |
180
+ | `overflow: auto/scroll` on container | Creates nested scroll context โ€” product shelf scroll breaks |
181
+ | `transform` on container or ancestors | Creates new stacking context โ€” z-index layering fails |
182
+ | `isolation: isolate` on container | Same stacking context issue (Bob manages its own isolation) |
183
+ | Container height as `%` without parent height | Bob collapses to 0px |
184
+ | Missing `position: relative` | Absolutely-positioned Bob layers escape the container |
185
+ | Wrapping Bob in a scrollable parent | Bob has its own scroll management โ€” nesting causes conflicts |
186
+
187
+ ### 4.5 Pre-Mount Checklist
188
+
189
+ Before writing any integration code, verify:
190
+
191
+ ```
192
+ โ–ก Header is position: fixed, 72px tall, z-index โ‰ค 49
193
+ โ–ก Bottom nav is position: fixed, 72px tall, z-index โ‰ค 49
194
+ โ–ก Bob container uses calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))
195
+ โ–ก Bob container has position: relative
196
+ โ–ก Bob container has NO overflow property set
197
+ โ–ก Bob container has NO transform property set
198
+ โ–ก No ancestor element between <body> and Bob container has overflow: hidden
199
+ โ–ก No ancestor element has a transform that creates a stacking context
200
+ โ–ก Container renders at correct height (inspect element in DevTools)
201
+ โ–ก HTTPS is enabled (required for Push-to-Talk microphone access)
202
+ ```
203
+
204
+ ---
205
+
206
+ ### 4.6 Layout Diagram
207
+
208
+ ```
209
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
210
+ โ”‚ CARFIX Header (72px, z-40) โ”‚ โ† position: fixed; top: 0
211
+ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
212
+ โ”‚ โ”‚
213
+ โ”‚ Bob Container โ”‚ โ† position: relative
214
+ โ”‚ height: calc(100dvh - 144px โ”‚ NO overflow property
215
+ โ”‚ - safe-area-inset) โ”‚ NO transform property
216
+ โ”‚ โ”‚
217
+ โ”‚ โ”Œโ”€ Bob Internal Layers โ”€โ”€โ”€โ” โ”‚
218
+ โ”‚ โ”‚ PTT Button z-145 โ”‚ โ”‚
219
+ โ”‚ โ”‚ Chat Drawer z-130 โ”‚ โ”‚
220
+ โ”‚ โ”‚ Counter Overlay z-70 โ”‚ โ”‚
221
+ โ”‚ โ”‚ Bob Character z-60 โ”‚ โ”‚
222
+ โ”‚ โ”‚ Product Shelf z-55 โ”‚ โ”‚
223
+ โ”‚ โ”‚ Backdrop z-10 โ”‚ โ”‚
224
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
225
+ โ”‚ โ”‚
226
+ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
227
+ โ”‚ Bottom Nav (72px, z-30) โ”‚ โ† position: fixed; bottom: 0
228
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
229
+ ```
230
+
231
+ **Bob's internal z-index stack (relative to `zIndexBase={100}`):**
232
+
233
+ | Layer | z-index |
234
+ |---|---|
235
+ | Chat PTT Button | 145 |
236
+ | Chat Drawer | 130 |
237
+ | Counter Overlay | 70 |
238
+ | Bob Character | 60 |
239
+ | Product Shelf | 55 |
240
+ | Backdrop | 10 |
241
+
242
+ ---
243
+
244
+ ## 5. Callback Signatures
245
+
246
+ ### onAddToCart
247
+
248
+ ```typescript
249
+ onAddToCart: (item: {
250
+ product_id: string;
251
+ product_name: string;
252
+ quantity: number;
253
+ unit_price: number; // Final price (discount already applied for bundle items)
254
+ sku?: string;
255
+ brand?: string;
256
+ image_url?: string;
257
+ vehicle_id?: string;
258
+ // Bundle metadata (present when item is part of a service package)
259
+ is_bundle_item?: boolean;
260
+ bundle_discount_percentage?: number;
261
+ service_package_name?: string;
262
+ service_package_id?: string;
263
+ quality_tier?: string; // "Economy" | "Standard" | "Premium" | "Performance"
264
+ }) => Promise<void> | void;
265
+ ```
266
+
267
+ ### onNavigate
268
+
269
+ ```typescript
270
+ onNavigate: (url: string) => void;
271
+ // Example urls: "/product/SKU123", "/checkout"
272
+ ```
273
+
274
+ ### onCheckout
275
+
276
+ ```typescript
277
+ onCheckout: (checkoutUrl: string) => void;
278
+ // checkoutUrl is a full Stripe payment URL
279
+ ```
280
+
281
+ ### onError
282
+
283
+ ```typescript
284
+ onError: (error: Error) => void;
285
+ // Bob shows toast by default โ€” this is for host-side logging
286
+ ```
287
+
288
+ ---
289
+
290
+ ## 6. Bundle Discount Fields (NEW)
291
+
292
+ The `calculate-service-bundles` API returns these fields per `PreparedTier`:
293
+
294
+ ```typescript
295
+ interface PreparedTier {
296
+ tierName: string; // "Economy" | "Standard" | "Premium" | "Performance"
297
+ displayName: string;
298
+ description: string;
299
+ isRecommended: boolean; // true = CARFIX Value tier
300
+ isHidden: boolean; // true = filter out (duplicate price)
301
+
302
+ // Pricing (pre-calculated by API โ€” never recompute)
303
+ totalPrice: number; // Discounted bundle price
304
+ originalTotalPrice?: number; // Full price before discount
305
+ savingsAmount?: number; // Dollar savings
306
+ bundleDiscountPercentage?: number; // Discount % (0โ€“50)
307
+
308
+ productCount: number;
309
+ dominantBrand: string | null;
310
+ brands: PreparedTierBrand[];
311
+ products: PreparedTierProduct[];
312
+ }
313
+
314
+ interface PreparedTierProduct {
315
+ partslotId: number;
316
+ partslotName: string; // "BRAKE PADS FRONT"
317
+ sku: string;
318
+ name: string;
319
+ brand: string;
320
+ brandFullName: string;
321
+ brandImageUrl: string; // Full URL โ€” use directly in <img>
322
+ productImageUrl: string; // Full URL โ€” use directly in <img>
323
+ price: number; // Legacy unit price
324
+ unitPrice: number; // Per-unit price
325
+ displayPrice: number; // Total (unitPrice ร— perCarQty) โ€” USE THIS
326
+ isRotor: boolean; // Show "[Pair]" badge
327
+ isMultiQty: boolean; // Show quantity breakdown (e.g. spark plugs)
328
+ perCarQty: number;
329
+ partNumber: string | null;
330
+ webDescription: string | null;
331
+ viscosity: string | null;
332
+ volume: number | null;
333
+ }
334
+
335
+ interface PreparedTierBrand {
336
+ name: string;
337
+ fullName: string;
338
+ imageUrl: string; // Full URL
339
+ }
340
+ ```
341
+
342
+ ### Rendering Rules
343
+
344
+ 1. **Filter hidden tiers:** `preparedTiers.filter(t => !t.isHidden)`
345
+ 2. **When `savingsAmount > 0`:** Show ~~$originalTotalPrice~~ โ†’ **$totalPrice** + "SAVE $XX โ€” X% Bundle Deal"
346
+ 3. **When `savingsAmount === 0`:** Show `totalPrice` normally, no discount UI
347
+ 4. **Use `displayPrice`** for individual products (already includes quantity)
348
+ 5. **Never calculate prices client-side** โ€” all values arrive pre-calculated
349
+
350
+ ---
351
+
352
+ ## 7. Session Handoff (Pre-authenticated Users)
353
+
354
+ ```
355
+ 1. CARFIX calls partner-api: { action: "create_session", vehicle_id: 42899 }
356
+ โ†’ vehicle_id MUST be a NUMBER (not string)
357
+ โ†’ Returns: { session_token: "abc123..." }
358
+
359
+ 2. Redirect to: /ask-bob?session=abc123...
360
+
361
+ 3. BobStandalone reads sessionToken โ†’ resolves vehicle + customer context
362
+ ```
363
+
364
+ > **Critical:** `vehicle_id` must be numeric throughout the pipeline. String values cause silent API failures.
365
+
366
+ ---
367
+
368
+ ## 8. Design Tokens
369
+
370
+ Exported from the package for use on CARFIX pages that mirror Bob's styling:
371
+
372
+ ```typescript
373
+ import {
374
+ CARFIX_COLORS,
375
+ QUALITY_TIER_CONFIG,
376
+ IMAGE_URLS,
377
+ BADGE_CONFIG,
378
+ TYPOGRAPHY,
379
+ isRotorProduct,
380
+ getDisplayPrice,
381
+ formatNZD,
382
+ } from '@gymmymac/bob-widget';
55
383
  ```
56
384
 
57
- **That's it!** Bob auto-configures from the database.
385
+ ### Key Colors
386
+
387
+ | Token | Value | Usage |
388
+ |---|---|---|
389
+ | `primary` | `#0052CC` | Standard tier, CTAs, CARFIX Value |
390
+ | `secondary` | `#38BDF8` | Accents, links |
391
+ | `accent` | `#FF8C00` | Premium tier |
392
+ | `success` | `#22C55E` | "Fits Vehicle" badges, Add to Cart |
393
+ | `destructive` | `#EF4444` | Performance tier |
394
+
395
+ ### Tier Visual Config
396
+
397
+ | Tier | Color | Background | Badge |
398
+ |---|---|---|---|
399
+ | Economy | `#475569` | `#F1F5F9` | ๐Ÿ’ฐ |
400
+ | Standard | `#0052CC` | `rgba(0,82,204,0.1)` | โญ CARFIX Value |
401
+ | Premium | `#D97706` | `#FEF3C7` | ๐Ÿ† |
402
+ | Performance | `#DC2626` | `#FEE2E2` | โšก |
58
403
 
59
404
  ---
60
405
 
61
- ## What's New in v3.1.19
406
+ ## 9. Exported Types (Full List)
407
+
408
+ ```typescript
409
+ // Components
410
+ export { BobStandalone } from '@gymmymac/bob-widget';
411
+ export type { StandaloneWidgetProps } from '@gymmymac/bob-widget';
62
412
 
63
- - ๐Ÿš— **Vehicle Variant Deduplication**: Smart filtering of duplicate variants based on parts-relevant specs
64
- - ๐Ÿ› ๏ธ **Executable CLI Installer**: Run `npx @gymmymac/bob-widget carfix stage-a|b|c`
65
- - ๐ŸŽจ **Fixed Visual Issues**: Removed hardcoded blur, fixed Bob positioning/scale
66
- - ๐Ÿ“ฆ **Full Package Distribution**: CLI, install scripts, and docs shipped in npm
67
- - ๐Ÿ”ง **Embedded Mode Default**: BobStandalone now uses `inline` variant (container-respecting)
68
- - ๐Ÿ”’ **Auth Isolation**: Unique storage keys prevent host-site auth collisions
413
+ // Types
414
+ export type {
415
+ HostContext, HostUserContext, HostVehicleContext, HostCartContext,
416
+ BobConfig, HostApiConfig, BobCallbacks, BobProviderConfig, BobLayoutConfig,
417
+ Product, CartItem, ServicePackage, PreparedTier, PreparedTierProduct, PreparedTierBrand,
418
+ Partslot, QualityTiers, Part,
419
+ PartnerConfig, PartnerFeatureFlags, EssentialCallbacks,
420
+ Vehicle, Message, HighlightedProduct,
421
+ BobAnalyticsEvent, BobGA4Config,
422
+ } from '@gymmymac/bob-widget';
423
+ ```
69
424
 
70
- ## Dependencies
425
+ ---
71
426
 
72
- Only requires:
73
- - `react` ^18.0.0
74
- - `react-dom` ^18.0.0
427
+ ## 10. Post-Install Verification Checklist
428
+
429
+ ```
430
+ โ–ก npm install completes without peer dependency warnings
431
+ โ–ก BobStandalone renders loading spinner, then Bob appears
432
+ โ–ก Bob character sits between header (72px) and bottom nav (72px)
433
+ โ–ก Chat drawer opens above bottom navigation (z-index check)
434
+ โ–ก PTT button is visible and not clipped
435
+ โ–ก Vehicle lookup works (try rego: HZP550)
436
+ โ–ก Service packages appear with tier cards
437
+ โ–ก Bundle discount shows Was/Now pricing where applicable
438
+ โ–ก "Add to Cart" callback fires with correct item shape
439
+ โ–ก Session handoff works (pass ?session=TOKEN)
440
+ โ–ก No console errors (filter for [Bob)
441
+ โ–ก Mobile: safe-area-inset respected on notched devices
442
+ ```
75
443
 
76
- All other dependencies are bundled.
444
+ ---
445
+
446
+ ## 11. Test Baseline
447
+
448
+ Bob ships with **36 unit tests** and **8+ E2E scenarios** covering:
449
+
450
+ - Callback mapping and stability
451
+ - Tier validation and empty states
452
+ - Rear Brake Disc/Drum filter logic
453
+ - Bundle discount display and cart pricing
454
+ - Vehicle lookup flow
455
+ - Service package rendering
456
+
457
+ Run locally: `cd packages/bob-widget && npx vitest run`
458
+
459
+ ---
460
+
461
+ ## ๐Ÿ“– Additional Documentation
462
+
463
+ | Document | Description |
464
+ |----------|-------------|
465
+ | **[BOB-DOCUMENTATION.md](./BOB-DOCUMENTATION.md)** | Complete integration guide with troubleshooting |
466
+ | **[CHANGELOG.md](./CHANGELOG.md)** | Version history and release notes |
467
+ | **[install/carfix/](./install/carfix/)** | Installer scripts, templates, and verification checklists |
468
+
469
+ ---
77
470
 
78
471
  ## Support
79
472
 
80
- For integration issues, check the troubleshooting section in [BOB-DOCUMENTATION.md](./BOB-DOCUMENTATION.md#9-troubleshooting).
473
+ For integration issues, the Bob team needs:
474
+ 1. Browser console output (filter for `[Bob`)
475
+ 2. Network tab showing failed API calls
476
+ 3. Screenshot of layout issue
477
+ 4. Device / browser / viewport info
81
478
 
82
479
  ## License
83
480
 
@@ -18,7 +18,7 @@ const __filename = fileURLToPath(import.meta.url);
18
18
  const __dirname = dirname(__filename);
19
19
  const INSTALL_DIR = join(__dirname, '..', 'install', 'carfix');
20
20
 
21
- const VERSION = '3.1.19';
21
+ const VERSION = '3.2.1';
22
22
 
23
23
  const COLORS = {
24
24
  reset: '\x1b[0m',
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Bob Callback Stability Tests
3
+ *
4
+ * These tests verify that the callback refs in Bob.tsx maintain stable references
5
+ * and correctly update state when parts/packages are received.
6
+ *
7
+ * Critical for preventing the "500 parts received but not displayed" regression.
8
+ * See: .lovable/plan.md - "Layer 2: Unit Tests for State Management"
9
+ */
10
+ export {};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Bundle Discount Pricing โ€” Baseline Unit Tests
3
+ *
4
+ * Tests the rendering decisions and cart discount calculations
5
+ * for the PreparedTier bundle discount fields.
6
+ */
7
+ export {};
@@ -0,0 +1,13 @@
1
+ /**
2
+ * PTT Long-Press Protection Tests
3
+ *
4
+ * Verifies the 3-layer defense against mobile browsers triggering
5
+ * "Save image" context menus when users long-press the PTT button.
6
+ *
7
+ * Layer 1: CSS properties on all widget images (-webkit-touch-callout, user-select, draggable)
8
+ * Layer 2: contextmenu event prevention on the widget container
9
+ * Layer 3: preventDefault() on PTT touchstart/mousedown handlers
10
+ *
11
+ * See: .lovable/plan.md - "Fix: PTT Long-Press Triggers Save Image on Mobile"
12
+ */
13
+ export {};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Rear Brake Filter โ€” Baseline Unit Tests
3
+ *
4
+ * Tests the pure utility functions that power the Disc/Drum toggle
5
+ * on the Rear Brake Service package.
6
+ */
7
+ export {};
@@ -10,11 +10,10 @@ interface ProductTileProps {
10
10
  /**
11
11
  * ProductTile - Premium Glassmorphism Product Cards
12
12
  *
13
- * iOS 26-inspired liquid glass design:
14
- * - Frosted translucent glass with backdrop blur
15
- * - Sharp white text with high contrast
16
- * - CARFIX orange price highlights
17
- * - Hover: scale(1.04), translateY(-4px), enhanced glow
13
+ * Image fallback chain:
14
+ * 1. product.image_url (product photo)
15
+ * 2. product.brandImageUrl (brand logo)
16
+ * 3. "No Image" placeholder
18
17
  */
19
18
  export declare const ProductTile: React.FC<ProductTileProps>;
20
19
  export {};