@gymmymac/bob-widget 3.1.9 → 3.1.19

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,1074 @@
1
+ # Bob Widget - Complete Documentation
2
+
3
+ > **Version:** 3.1.19 | **Last Updated:** February 2026
4
+
5
+ AI-powered automotive parts assistant widget for seamless integration into partner websites.
6
+
7
+ ---
8
+
9
+ ## Table of Contents
10
+
11
+ 1. [Overview](#1-overview)
12
+ 2. [Quick Start](#2-quick-start)
13
+ 3. [Integration Guide](#3-integration-guide)
14
+ 4. [Props Reference](#4-props-reference)
15
+ 5. [Session Handoff](#5-session-handoff)
16
+ 6. [CSS Customization](#6-css-customization)
17
+ 7. [Bob's Behaviour Guidelines](#7-bobs-behaviour-guidelines)
18
+ 8. [API Reference](#8-api-reference)
19
+ 9. [Troubleshooting](#9-troubleshooting)
20
+ 10. [CARFIX 3-Stage Installation](#10-carfix-3-stage-installation)
21
+ 11. [Changelog Summary](#11-changelog-summary)
22
+
23
+ ---
24
+
25
+ ## 1. Overview
26
+
27
+ Bob is a friendly Kiwi auto parts expert that helps customers find the right parts for their vehicles through natural conversation. The widget is designed as a **"black box"** that auto-configures from the database—partners only need to provide a partner code.
28
+
29
+ ### Key Features (v3.1.19)
30
+
31
+ | Feature | Description |
32
+ |---------|-------------|
33
+ | **CLI Installer** | 3-stage installation via `npx @gymmymac/bob-widget carfix stage-a\|b\|c` |
34
+ | **`--with-layout` Flag** | Stage B can generate CARFIX Header (72px) and BottomNav (72px) components |
35
+ | **BobStandalone** | Auto-configures from database - 4 lines to integrate |
36
+ | **No Hardcoded Blur** | Background uses CSS variable `--bob-blur-intensity` (default: 0) |
37
+ | **Partner Config System** | All settings stored in `bob_partners` table |
38
+ | **CSS Variables** | Customizable blur, opacity, colors via CSS |
39
+ | **Debug Overlay** | Visual diagnostic tool for troubleshooting |
40
+ | **Session Handoff** | Pre-authenticated sessions for vehicle handoff |
41
+ | **SwipeableBob** | Gesture-based interactions - swipe Bob away or back |
42
+ | **RAF Animations** | Smooth 60fps animations using requestAnimationFrame |
43
+ | **HTTPS Validation** | Programmatic check for PTT with user warnings |
44
+
45
+ ---
46
+
47
+ ## 2. Quick Start
48
+
49
+ > ⚠️ **IMPORTANT: Run the 3-Stage Installer First**
50
+ >
51
+ > Bob v3.1.10 includes an executable CLI installer. Do NOT skip this step.
52
+ >
53
+ > ```bash
54
+ > npx @gymmymac/bob-widget carfix stage-a # Forensic removal
55
+ > npx @gymmymac/bob-widget carfix stage-b --target next-pages # Generate template
56
+ > npx @gymmymac/bob-widget carfix stage-c --partner CARFIX # Install & verify
57
+ > ```
58
+
59
+ ### Recommended: BobStandalone (Simplest)
60
+
61
+ ```tsx
62
+ import { BobStandalone } from '@gymmymac/bob-widget';
63
+
64
+ function AskBobPage() {
65
+ const { addToCart } = useCart();
66
+ const router = useRouter();
67
+ const sessionToken = router.query.session as string;
68
+
69
+ return (
70
+ <div className="h-[calc(100dvh-144px)]" style={{ paddingBottom: 'env(safe-area-inset-bottom, 0px)' }}>
71
+ <BobStandalone
72
+ partner="CARFIX"
73
+ sessionToken={sessionToken}
74
+ onAddToCart={(item) => addToCart(item)}
75
+ onNavigate={(url) => router.push(url)}
76
+ />
77
+ </div>
78
+ );
79
+ }
80
+ ```
81
+
82
+ **That's it!** Bob handles everything else internally.
83
+
84
+ ### Alternative: BobWidget (More Control)
85
+
86
+ Use this if you need to override database defaults:
87
+
88
+ ```tsx
89
+ import { BobWidget } from '@gymmymac/bob-widget';
90
+
91
+ <BobWidget
92
+ bobConfig={{
93
+ supabaseUrl: 'https://gjoguxzstsihhxvdgpto.supabase.co',
94
+ supabaseKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
95
+ }}
96
+ hostApiConfig={{
97
+ baseUrl: 'https://flpzjbasdsfwoeruyxgp.supabase.co/functions/v1',
98
+ apiKey: '', // Handled server-side
99
+ partnerCode: 'CARFIX',
100
+ }}
101
+ callbacks={{
102
+ onAddToCart: (item) => addToCart(item),
103
+ }}
104
+ variant="mobile"
105
+ bottomOffset={72}
106
+ />
107
+ ```
108
+
109
+ ### Checking Bob's Version
110
+
111
+ Ask Bob directly: **"What version are you running?"**
112
+
113
+ Or programmatically:
114
+ ```tsx
115
+ import { getBobVersion, BOB_VERSION } from '@gymmymac/bob-widget';
116
+
117
+ console.log(`Bob Widget Version: ${getBobVersion()}`); // "3.1.9"
118
+ ```
119
+
120
+ ---
121
+
122
+ ## 3. Integration Guide
123
+
124
+ ### What's Auto-Configured
125
+
126
+ | Setting | Value | Source |
127
+ |---------|-------|--------|
128
+ | API Base URL | `https://flpzjbasdsfwoeruyxgp.supabase.co/functions/v1` | `bob_partners` table |
129
+ | Bottom Offset | 72px | `bob_partners` table |
130
+ | Backdrop Blur | 4px | `bob_partners` table |
131
+ | Overlay Opacity | 10% | `bob_partners` table |
132
+ | Service Packages | Enabled | Feature flag |
133
+ | TTS | Enabled | Feature flag |
134
+ | Speech Recognition | Enabled | Feature flag |
135
+
136
+ ### Pre-Installation Checklist
137
+
138
+ > ⚠️ **MANDATORY: Complete the 3-Stage Installation Process (Section 10) BEFORE proceeding**
139
+
140
+ 1. ✅ Complete **Stage A: Forensic Removal** ([Section 10](#10-carfix-3-stage-installation))
141
+ 2. ✅ Complete **Stage B: Page Preparation** ([Section 10](#10-carfix-3-stage-installation))
142
+ 3. ✅ Ensure HTTPS is enabled (required for Push-to-Talk)
143
+ 4. ✅ Verify Node.js v18+ is installed
144
+ 5. ✅ Confirm React ^18.0.0 is installed
145
+
146
+ ### Installation (Stage C)
147
+
148
+ ```bash
149
+ # Install Bob Widget (Stage C - after completing Stages A and B)
150
+ npm install @gymmymac/bob-widget@^3.1.9
151
+
152
+ # Clear cache after installation
153
+ rm -rf node_modules/.vite
154
+ npm run dev
155
+ ```
156
+
157
+ ### Container Requirements
158
+
159
+ > **CRITICAL: Page Layout Context**
160
+ >
161
+ > The Bob container is designed to be placed on a page that **already includes** the CARFIX Header (72px) and Bottom Navigation (72px). Bob's container occupies the space **between** these fixed elements—it does NOT replace them.
162
+
163
+ Bob's container **MUST** meet these specifications for correct rendering:
164
+
165
+ #### Required Container Height Formula
166
+
167
+ ```css
168
+ height: calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))
169
+ ```
170
+
171
+ **CARFIX Reference Measurements:**
172
+
173
+ | Element | Height | Source |
174
+ |---------|--------|--------|
175
+ | CARFIX Header | 72px | Fixed header |
176
+ | Bottom Navigation | 72px | `py-2` (16px) + `min-h-[56px]` |
177
+ | Safe Area (notched devices) | Variable | `env(safe-area-inset-bottom)` |
178
+ | **Total Fixed Offset** | **144px** | Header + Bottom Nav |
179
+
180
+ #### Container CSS Requirements
181
+
182
+ ```css
183
+ .bob-container {
184
+ height: calc(100dvh - 144px - env(safe-area-inset-bottom, 0px));
185
+ position: relative;
186
+ overflow: hidden;
187
+ width: 100%;
188
+ }
189
+ ```
190
+
191
+ **Critical Container Rules:**
192
+
193
+ | Requirement | Reason |
194
+ |-------------|--------|
195
+ | `position: relative` | Bob uses `position: absolute` internally |
196
+ | Defined height (NOT auto or 100%) | Bob needs a fixed container boundary |
197
+ | `overflow: hidden` | Prevents content bleed outside container |
198
+ | No parent CSS transforms | Transforms break absolute positioning |
199
+
200
+ #### Complete Integration Example
201
+
202
+ ```tsx
203
+ import { BobStandalone } from '@gymmymac/bob-widget';
204
+
205
+ function AskBobPage() {
206
+ const { addToCart } = useCart();
207
+ const router = useRouter();
208
+ const sessionToken = router.query.session as string;
209
+
210
+ return (
211
+ <div
212
+ className="bob-container"
213
+ style={{
214
+ height: 'calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))',
215
+ position: 'relative',
216
+ overflow: 'hidden',
217
+ width: '100%'
218
+ }}
219
+ >
220
+ <BobStandalone
221
+ partner="CARFIX"
222
+ sessionToken={sessionToken}
223
+ bottomOffset={72} // Matches CARFIX bottom nav height
224
+ onAddToCart={(item) => addToCart(item)}
225
+ onNavigate={(url) => router.push(url)}
226
+ />
227
+ </div>
228
+ );
229
+ }
230
+ ```
231
+
232
+ #### Layout Measurements Reference
233
+
234
+ Based on visual analysis of CARFIX components:
235
+
236
+ ```
237
+ ┌─────────────────────────────────┐
238
+ │ CARFIX HEADER │ ← 72px fixed
239
+ ├─────────────────────────────────┤
240
+ │ │
241
+ │ ┌─────────┐ ┌──────────────┐ │
242
+ │ │ BOB'S │ │ │ │
243
+ │ │ SHELF │ │ PRODUCTS │ │
244
+ │ │ HEADER │ │ (scrolls) │ │
245
+ │ ├─────────┤ │ │ │
246
+ │ │ │ │ │ │
247
+ │ │ BOB │ │ │ │ ← Bob container
248
+ │ │ (char) │ │ │ │ height: calc(100dvh - 144px - env(...))
249
+ │ │ ╲ │ │ │ │
250
+ │ │ ╲ │ │ │ │
251
+ │ ├──────╲──┴──┴──────────────┤ │
252
+ │ │ COUNTER OVERLAY (22%) │ │
253
+ │ ├───────────────────────────┤ │
254
+ │ │ CHAT DRAWER (collapsed) │ │ ← 70px collapsed
255
+ ├─────────────────────────────────┤
256
+ │ BOTTOM NAV (72px visible) │ ← py-2 + min-h-[56px]
257
+ │ + safe-area-inset-bottom │ ← notched device padding
258
+ └─────────────────────────────────┘
259
+ ```
260
+
261
+ | Element | Height/Value | Notes |
262
+ |---------|--------------|-------|
263
+ | Bob Container | `calc(100dvh - 144px - env(...))` | After header, before bottom nav |
264
+ | `bottomOffset` prop | `72` | Height of CARFIX bottom nav in pixels |
265
+ | Counter Overlay | 22% | Percentage of container height |
266
+ | Chat Drawer (collapsed) | 70px | From bottom of container |
267
+ | Chat Drawer (expanded) | 55% | Of container height |
268
+ | Bob Character | ~140% scale | Mobile base scale |
269
+ | z-index base | 50 | Default, configurable |
270
+
271
+ ---
272
+
273
+ ## 4. Props Reference
274
+
275
+ ### BobStandalone Props
276
+
277
+ #### Required Props
278
+
279
+ | Prop | Type | Description |
280
+ |------|------|-------------|
281
+ | `partner` | `string` | Partner code - `"CARFIX"` |
282
+
283
+ #### Optional Props
284
+
285
+ | Prop | Type | Default | Description |
286
+ |------|------|---------|-------------|
287
+ | `sessionToken` | `string` | - | Pre-authenticated session token from Partner API |
288
+ | `bottomOffset` | `number` | 72 | Override database default (for bottom nav) |
289
+ | `zIndexBase` | `number` | 50 | Override z-index base |
290
+ | `backdropBlurIntensity` | `number` | 4 | Blur intensity (0-20) |
291
+ | `backdropOverlayOpacity` | `number` | 0.1 | Overlay opacity (0-1) |
292
+ | `debug` | `boolean` | false | Show diagnostic overlay |
293
+ | `embedded` | `boolean` | false | Use absolute positioning for host containers |
294
+ | `className` | `string` | - | Additional CSS class |
295
+
296
+ #### Callbacks
297
+
298
+ | Callback | Type | Description |
299
+ |----------|------|-------------|
300
+ | `onAddToCart` | `(item: CartItem) => void` | **Essential** - Handle cart addition |
301
+ | `onNavigate` | `(url: string) => void` | SPA navigation |
302
+ | `onCheckout` | `(url: string) => void` | Handle checkout redirect |
303
+ | `onError` | `(error: Error) => void` | Custom error handling |
304
+
305
+ ### BobWidget Props
306
+
307
+ | Prop | Type | Description |
308
+ |------|------|-------------|
309
+ | `bobConfig` | `BobConfig` | Bob's Supabase credentials (for animations, TTS) |
310
+ | `hostApiConfig` | `HostApiConfig` | Your API credentials for product/vehicle lookups |
311
+ | `hostContext` | `HostContext` | Current user, vehicle, cart, and purchase history |
312
+ | `callbacks` | `BobCallbacks` | Event handlers for Bob actions |
313
+ | `queryClient` | `QueryClient` | Optional: share your app's QueryClient |
314
+ | `variant` | `'mobile' \| 'inline' \| 'floating' \| 'fullscreen'` | Display variant |
315
+ | `bottomOffset` | `number` | Pixels from bottom (for nav bars) |
316
+
317
+ ---
318
+
319
+ ## 5. Session Handoff
320
+
321
+ When a customer selects a vehicle on the main site, create a session before redirecting to Bob:
322
+
323
+ ### Creating a Session
324
+
325
+ ```typescript
326
+ // 1. Create session via Partner API
327
+ const response = await fetch('https://flpzjbasdsfwoeruyxgp.supabase.co/functions/v1/partner-api', {
328
+ method: 'POST',
329
+ headers: {
330
+ 'Content-Type': 'application/json',
331
+ 'X-Partner-Key': 'bob_carfix_p4rtner_2024_x7kL9mNqR3wY5vBc'
332
+ },
333
+ body: JSON.stringify({
334
+ action: 'create_session',
335
+ vehicle: {
336
+ vehicle_id: 42899, // MUST be numeric
337
+ make: 'MAZDA',
338
+ model: 'DEMIO',
339
+ year: 2008
340
+ },
341
+ user_email: customer?.email // Optional
342
+ })
343
+ });
344
+
345
+ const { session_token } = await response.json();
346
+
347
+ // 2. Redirect to Bob with session
348
+ router.push(`/ask-bob?session=${session_token}`);
349
+ ```
350
+
351
+ **Critical:** `vehicle_id` MUST be a numeric type, not a string!
352
+
353
+ ### Session Data Flow
354
+
355
+ 1. Customer selects vehicle on main site
356
+ 2. Main site calls Partner API `create_session`
357
+ 3. Receives `session_token`
358
+ 4. Redirects to Bob page with `?session=TOKEN`
359
+ 5. Bob reads token, calls `session-handoff` edge function
360
+ 6. Vehicle and customer context injected into chat
361
+
362
+ ---
363
+
364
+ ## 6. CSS Customization
365
+
366
+ ### Override via CSS Variables
367
+
368
+ Bob uses CSS variables that can be overridden in your container:
369
+
370
+ ```css
371
+ /* In your stylesheet */
372
+ .bob-container {
373
+ --bob-blur-intensity: 2px; /* Reduce blur */
374
+ --bob-overlay-opacity: 0.05; /* Lighter overlay */
375
+ --bob-primary-color: #0052cc; /* Match brand blue */
376
+ --bob-accent-color: #ff8c00; /* Orange for highlights */
377
+ }
378
+ ```
379
+
380
+ ### CSS Isolation
381
+
382
+ Bob v3.1.5 uses aggressive CSS isolation via `.bob-widget-root`:
383
+
384
+ ```css
385
+ .bob-widget-root {
386
+ isolation: isolate;
387
+ all: initial;
388
+ contain: layout style;
389
+ /* All internal styles scoped */
390
+ }
391
+ ```
392
+
393
+ This prevents host site styles from bleeding into Bob and vice versa.
394
+
395
+ ---
396
+
397
+ ## 7. Bob's Behaviour Guidelines
398
+
399
+ ### Personality & Voice
400
+
401
+ Bob is a friendly, knowledgeable Kiwi auto parts expert with a relaxed, helpful tone.
402
+
403
+ | Expression | Meaning | When to Use |
404
+ |------------|---------|-------------|
405
+ | "Sweet as" | All good, perfect | Confirming something |
406
+ | "Mate" | Friendly address | Throughout conversation |
407
+ | "Choice" | Excellent | When something is good |
408
+ | "Chur" | Thanks/Cool | Quick acknowledgment |
409
+ | "She'll be right" | It'll be fine | Reassurance |
410
+ | "Yeah nah" | No | Gentle decline |
411
+ | "Away laughing" | Sorted, good to go | After solving a problem |
412
+
413
+ ### Response Length Guidelines
414
+
415
+ | Situation | Response Style |
416
+ |-----------|----------------|
417
+ | No vehicle identified yet | SHORT - 1-2 sentences max |
418
+ | Vehicle confirmed | Can be slightly longer |
419
+ | Product recommendation | 2-3 sentences + point to shelf |
420
+ | Checkout/cart | Brief confirmation |
421
+
422
+ ### Vehicle Identification Workflow
423
+
424
+ 1. **REGO (License Plate)** - Primary identifier, gives exact match
425
+ 2. **Make + Model + Year + Engine CC** - Fallback when no REGO
426
+
427
+ ```
428
+ First ask: "What's your rego, mate?"
429
+ If no rego: "No worries - what make, model, and year is she?"
430
+ If needed: "What's the engine size? 1.8L, 2.0L...?"
431
+ ```
432
+
433
+ ### Product Recommendations - Golden Rules
434
+
435
+ 1. **NEVER recommend cheapest first** - Lowest margin, lowest quality
436
+ 2. **Lead with mid-priced "best value"** option
437
+ 3. **Max 2-3 products mentioned verbally** - Let the shelf show the rest
438
+ 4. **ONLY recommend products from retrieve_parts results** - Never hallucinate brands
439
+
440
+ ### Cart & Checkout Rules (CRITICAL)
441
+
442
+ - **NEVER add to cart** unless customer explicitly says:
443
+ - "add to cart", "I'll take it", "buy it", "yes please"
444
+ - If customer says "that one" or "the first one", **confirm WHICH product** before adding
445
+ - **NEVER claim to add products without calling add_to_cart tool**
446
+
447
+ ### Things Bob NEVER Does
448
+
449
+ | Never Do | Why |
450
+ |----------|-----|
451
+ | Offer to fit parts | CARFIX only sells parts - DIY or workshop fitment |
452
+ | Mention stock status | All displayed parts are in stock |
453
+ | List more than 3 products verbally | Let the shelf do the work |
454
+ | Recommend cheapest option first | Low margin, low quality perception |
455
+ | Hallucinate brands or products | Only recommend from actual tool results |
456
+ | Add to cart without explicit request | Customer must say "add", "buy", "take it" |
457
+
458
+ ### Anti-Hallucination Rules
459
+
460
+ 1. **ONLY mention products that appear in tool responses**
461
+ 2. If no tool returned products, **DO NOT invent alternatives**
462
+ 3. If search fails or returns empty, say: "I don't have that in my system right now"
463
+ 4. **NEVER recommend brands, SKUs, or prices** not retrieved from tools
464
+ 5. **NEVER fabricate product names** like "Best Value wipers"
465
+
466
+ ---
467
+
468
+ ## 8. API Reference
469
+
470
+ ### Exported Components
471
+
472
+ ```tsx
473
+ // Main components
474
+ import {
475
+ BobStandalone, // v3.1.5 recommended entry point
476
+ BobWidget, // Self-contained widget
477
+ Bob, // Core Bob component (needs BobProvider)
478
+ BobProvider, // Context provider
479
+ BobCharacter, // Animated character
480
+ ChatInterface, // Chat UI
481
+ SwipeableBob, // Gesture wrapper
482
+ ProductTile, // Product display
483
+ MatrixProductLoader, // Loading animation
484
+ SparkDealBanner, // Promo banners
485
+ BobDebugOverlay, // Debug diagnostics
486
+ } from '@gymmymac/bob-widget';
487
+ ```
488
+
489
+ ### Exported Hooks
490
+
491
+ ```tsx
492
+ import {
493
+ useBobContext, // Access Bob's full context
494
+ useHostContext, // Access host-provided context
495
+ useBobCallbacks, // Access callback functions
496
+ useBobChat, // Chat functionality
497
+ useBobAnimation, // Animation control
498
+ useSpeechSynthesis, // TTS control
499
+ useSpeechRecognition, // Speech input
500
+ usePartnerConfig, // Partner configuration
501
+ useBobHealthCheck, // Connectivity verification
502
+ } from '@gymmymac/bob-widget';
503
+ ```
504
+
505
+ ### Exported Types
506
+
507
+ ```tsx
508
+ import type {
509
+ HostContext,
510
+ BobConfig,
511
+ HostApiConfig,
512
+ BobCallbacks,
513
+ Vehicle,
514
+ Product,
515
+ CartItem,
516
+ ServicePackage,
517
+ PartnerConfig,
518
+ StandaloneWidgetProps,
519
+ } from '@gymmymac/bob-widget';
520
+ ```
521
+
522
+ ---
523
+
524
+ ## 9. Troubleshooting
525
+
526
+ ### Debug Mode
527
+
528
+ Enable debug overlay for troubleshooting:
529
+
530
+ ```tsx
531
+ <BobStandalone
532
+ partner="CARFIX"
533
+ debug={true} // Shows diagnostic overlay
534
+ />
535
+ ```
536
+
537
+ The overlay displays:
538
+ - Partner config loaded status
539
+ - Session token status
540
+ - Viewport size and device type
541
+ - Position factors being applied
542
+ - Feature flags
543
+ - CSS conflicts detected
544
+
545
+ ### Console Verification
546
+
547
+ Open browser DevTools (F12) and check the console. You should see:
548
+
549
+ ```
550
+ [BobWidget] Package loaded - v3.1.5
551
+ [BobStandalone] Initialized { version: "3.1.5", partner: "CARFIX", session: "present" }
552
+ [BobWidget] Loading partner config for: CARFIX
553
+ [BobWidget] Partner config loaded: { partner: "CARFIX", bottomOffset: 72, ... }
554
+ ```
555
+
556
+ ### Common Issues
557
+
558
+ | Issue | Solution |
559
+ |-------|----------|
560
+ | Old version showing in console | Clear `node_modules/.vite`, restart dev server |
561
+ | Blank screen | Check console for errors, verify partner code |
562
+ | "Partner not found" error | Ensure `bob_partners` table has entry |
563
+ | No products loading | Verify vehicle_id is numeric in session token |
564
+ | Version mismatch | Run `npm ls @gymmymac/bob-widget` to check version |
565
+ | Bob doesn't appear / is cropped | Check parent containers for `overflow: hidden` |
566
+ | Service packages not showing | Check `calculate-service-bundles` response in Network tab |
567
+ | Blur/overlay too strong | Use props or CSS variables to adjust |
568
+ | PTT not working | Ensure HTTPS connection (required for Web Speech API) |
569
+
570
+ ### Cache Clearing
571
+
572
+ ```bash
573
+ # Full clean install
574
+ rm -rf node_modules package-lock.json
575
+ npm install
576
+ npm run dev
577
+
578
+ # Just clear Vite cache
579
+ rm -rf node_modules/.vite
580
+ npm run dev
581
+ ```
582
+
583
+ ---
584
+
585
+ ## 10. CARFIX 3-Stage Installation
586
+
587
+ > 🚨 **CRITICAL: Use the CLI Installer**
588
+ >
589
+ > Bob v3.1.10 includes an executable CLI for the 3-stage installation process.
590
+ >
591
+ > ```bash
592
+ > # Stage A: Forensic Scan & Purge
593
+ > npx @gymmymac/bob-widget carfix stage-a
594
+ >
595
+ > # Stage B: Generate Page Template
596
+ > npx @gymmymac/bob-widget carfix stage-b --target next-pages --output pages/ask-bob.tsx
597
+ >
598
+ > # Stage C: Install & Verify
599
+ > npx @gymmymac/bob-widget carfix stage-c --partner CARFIX
600
+ > ```
601
+
602
+ ### Where the Install Files Live
603
+
604
+ After installation, you can find the scripts in:
605
+ ```
606
+ node_modules/@gymmymac/bob-widget/
607
+ ├── bin/bob-widget.mjs # CLI entrypoint
608
+ ├── install/carfix/
609
+ │ ├── 00-README-PREINSTALL.md # This guide
610
+ │ └── 05-runtime-verification-checklist.md
611
+ ├── BOB-DOCUMENTATION.md # Full documentation
612
+ └── CHANGELOG.md # Version history
613
+ ```
614
+
615
+ ### Why 3 Stages?
616
+
617
+ > **Must complete BEFORE Stage B**
618
+
619
+ Remove **every line** of Bob-related code from the CARFIX codebase. This is a FULL CODE AUDIT.
620
+
621
+ #### What Gets Removed
622
+
623
+ | Category | Patterns |
624
+ |----------|----------|
625
+ | Component files | `Bob*.tsx`, `*Bob*.tsx`, `AskBob*.tsx` |
626
+ | Hook files | `useBob*.ts`, `useBob*.tsx` |
627
+ | Type definitions | `*bob*.d.ts` |
628
+ | Imports | Any file with `@gymmymac/bob-widget` or `useBob` |
629
+ | State variables | `vehicle`, `parts`, `servicePackages` managed for Bob |
630
+ | Environment variables | Any containing `BOB_` |
631
+ | Cached packages | `node_modules/@gymmymac`, `.vite`, `.next/cache` |
632
+ | The npm package | `@gymmymac/bob-widget` |
633
+
634
+ #### Stage A Cleanup Script
635
+
636
+ > ⚠️ **This script EXITS with an error** if any Bob files or imports are found, forcing you to manually delete them. This is intentional.
637
+
638
+ ```bash
639
+ #!/bin/bash
640
+ set -e
641
+
642
+ echo "══════════════════════════════════════════════════════════════"
643
+ echo " STAGE A: FORENSIC REMOVAL - Bob Widget Complete Uninstall"
644
+ echo "══════════════════════════════════════════════════════════════"
645
+ echo ""
646
+ echo "⚠️ WARNING: This will remove ALL Bob-related code from your project"
647
+ echo ""
648
+
649
+ # Step 1: Find and list all Bob-related files
650
+ echo "Step 1: Scanning for Bob-related files..."
651
+ BOB_FILES=$(find . -path ./node_modules -prune -o \( \
652
+ -name "Bob*.tsx" -o \
653
+ -name "*Bob*.tsx" -o \
654
+ -name "AskBob*.tsx" -o \
655
+ -name "useBob*.ts" -o \
656
+ -name "useBob*.tsx" -o \
657
+ -name "*bob*.d.ts" \
658
+ \) -print 2>/dev/null | grep -v node_modules || true)
659
+
660
+ if [ -n "$BOB_FILES" ]; then
661
+ echo " ✗ Found Bob component/hook files:"
662
+ echo "$BOB_FILES"
663
+ echo ""
664
+ echo " ACTION REQUIRED: Delete these files manually, then re-run this script."
665
+ exit 1
666
+ fi
667
+
668
+ # Step 2: Check for Bob imports in remaining files
669
+ echo "Step 2: Scanning for Bob imports in source files..."
670
+ BOB_IMPORTS=$(grep -rl "@gymmymac/bob-widget\|from 'bob-widget'\|useBob\|<Bob\|<BobWidget\|<BobStandalone" --include="*.tsx" --include="*.ts" --exclude-dir=node_modules . 2>/dev/null || true)
671
+
672
+ if [ -n "$BOB_IMPORTS" ]; then
673
+ echo " ✗ Found Bob imports in:"
674
+ echo "$BOB_IMPORTS"
675
+ echo ""
676
+ echo " ACTION REQUIRED: Remove all Bob imports from these files, then re-run this script."
677
+ exit 1
678
+ fi
679
+
680
+ # Step 3: Check for BOB_ environment variables
681
+ echo "Step 3: Scanning for legacy environment variables..."
682
+ BOB_ENV=$(grep -l "BOB_SUPABASE\|BOB_API\|BOB_PARTNER" .env* 2>/dev/null || true)
683
+
684
+ if [ -n "$BOB_ENV" ]; then
685
+ echo " ✗ Found BOB_ variables in:"
686
+ echo "$BOB_ENV"
687
+ echo ""
688
+ echo " ACTION REQUIRED: Remove all BOB_ variables from these files, then re-run this script."
689
+ exit 1
690
+ fi
691
+
692
+ # Step 4: Uninstall package and clear all caches
693
+ echo "Step 4: Uninstalling Bob package..."
694
+ npm uninstall @gymmymac/bob-widget 2>/dev/null || true
695
+
696
+ echo "Step 5: Removing node_modules..."
697
+ rm -rf node_modules
698
+
699
+ echo "Step 6: Clearing all caches..."
700
+ rm -rf node_modules/.vite node_modules/.cache .next/cache .vite dist .turbo
701
+
702
+ echo "Step 7: Removing lock file..."
703
+ rm -f package-lock.json
704
+
705
+ echo "Step 8: Cleaning npm cache..."
706
+ npm cache clean --force
707
+
708
+ echo "Step 9: Reinstalling base dependencies..."
709
+ npm install
710
+
711
+ echo ""
712
+ echo "══════════════════════════════════════════════════════════════"
713
+ echo " ✓ STAGE A COMPLETE - Forensic removal successful"
714
+ echo "══════════════════════════════════════════════════════════════"
715
+ echo ""
716
+ echo "NEXT: Proceed to STAGE B - Page Preparation"
717
+ ```
718
+
719
+ #### Stage A Verification
720
+
721
+ Before proceeding to Stage B, confirm:
722
+
723
+ - [ ] Script completed without errors (exit code 0)
724
+ - [ ] No `Bob*.tsx` files exist outside node_modules
725
+ - [ ] No `useBob*.ts` files exist outside node_modules
726
+ - [ ] No `BOB_` environment variables in `.env*` files
727
+ - [ ] `npm ls @gymmymac/bob-widget` returns "empty" or not found
728
+
729
+ ---
730
+
731
+ ### STAGE B: Page Preparation
732
+
733
+ > **Must complete AFTER Stage A, BEFORE Stage C**
734
+
735
+ Create the blank page that will host Bob. **Do NOT import Bob yet** - that happens in Stage C.
736
+
737
+ #### CARFIX Layout Components (Required)
738
+
739
+ Before creating the Bob container, ensure your CARFIX application has:
740
+
741
+ 1. **Fixed Header (72px)** - Fixed to top of viewport
742
+ 2. **Fixed Bottom Navigation (72px)** - Fixed to bottom of viewport
743
+
744
+ **If these elements do NOT exist**, you must create them first. The 144px height offset
745
+ in the container formula ASSUMES both elements are present.
746
+
747
+ ##### Option A: Use Existing Layout
748
+
749
+ If your CARFIX app already has a header and bottom nav, confirm their heights:
750
+ - Header: Must be exactly 72px
751
+ - Bottom Nav: Must be exactly 72px (plus safe-area-inset-bottom on mobile)
752
+
753
+ ##### Option B: Generate Layout Components
754
+
755
+ Run Stage B with the `--with-layout` flag to generate placeholder components:
756
+
757
+ ```bash
758
+ npx @gymmymac/bob-widget carfix stage-b --target next-pages --with-layout
759
+ ```
760
+
761
+ This generates:
762
+ - `components/CarfixHeader.tsx` (72px header)
763
+ - `components/CarfixBottomNav.tsx` (72px bottom nav)
764
+ - `pages/ask-bob.tsx` (complete page with layout)
765
+
766
+ #### Requirements
767
+
768
+ 1. Page must use the standard CARFIX layout (Header + Bottom Navigation)
769
+ 2. Page must have a container BETWEEN these fixed elements
770
+ 3. Container must have the correct height calculation
771
+
772
+ #### Layout Diagram
773
+
774
+ ```text
775
+ ┌─────────────────────────────────────────────────────────┐
776
+ │ CARFIX HEADER (72px) │ ← Fixed position: top
777
+ ├─────────────────────────────────────────────────────────┤
778
+ │ │
779
+ │ │
780
+ │ │
781
+ │ BOB CONTAINER (Stage B) │
782
+ │ height: calc(100dvh - 144px - env(...)) │ ← position: relative
783
+ │ │
784
+ │ │
785
+ │ │
786
+ │ │
787
+ ├─────────────────────────────────────────────────────────┤
788
+ │ BOTTOM NAVIGATION (72px) │ ← Fixed position: bottom
789
+ │ + env(safe-area-inset-bottom) │
790
+ └─────────────────────────────────────────────────────────┘
791
+ ```
792
+
793
+ #### Stage B Page Template
794
+
795
+ ```tsx
796
+ // pages/ask-bob.tsx (or your routing equivalent)
797
+ //
798
+ // ⚠️ PREREQUISITES:
799
+ // - STAGE A (Forensic Removal) must be complete
800
+ // - This file should be EMPTY before starting Stage B
801
+ // - Do NOT import Bob yet - that happens in Stage C
802
+
803
+ import React from 'react';
804
+
805
+ /**
806
+ * AskBob Page - Bob Widget Container
807
+ *
808
+ * This page is rendered within the CARFIX layout which provides:
809
+ * - Header: 72px fixed at top
810
+ * - Bottom Navigation: 72px fixed at bottom
811
+ *
812
+ * The container below fits BETWEEN these elements.
813
+ */
814
+ export default function AskBobPage() {
815
+ // Placeholder container - Bob will be installed in Stage C
816
+ return (
817
+ <div
818
+ id="bob-container"
819
+ style={{
820
+ height: 'calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))',
821
+ position: 'relative',
822
+ overflow: 'hidden',
823
+ width: '100%',
824
+ backgroundColor: '#0a1628', // Placeholder background
825
+ display: 'flex',
826
+ alignItems: 'center',
827
+ justifyContent: 'center',
828
+ color: 'white'
829
+ }}
830
+ >
831
+ <p>Bob Container Ready - Proceed to Stage C</p>
832
+ </div>
833
+ );
834
+ }
835
+ ```
836
+
837
+ #### Stage B Verification
838
+
839
+ Before proceeding to Stage C, confirm:
840
+
841
+ - [ ] Page renders within CARFIX layout (header visible at top)
842
+ - [ ] Bottom navigation is visible at bottom
843
+ - [ ] Container shows placeholder text "Bob Container Ready"
844
+ - [ ] Container fills space between header and bottom nav
845
+ - [ ] No Bob imports in the file
846
+
847
+ ---
848
+
849
+ ### STAGE C: Install & Verify
850
+
851
+ > **Must complete AFTER Stage B**
852
+
853
+ Install Bob and run verification tests.
854
+
855
+ #### Stage C Installation Script
856
+
857
+ ```bash
858
+ #!/bin/bash
859
+ set -e
860
+
861
+ echo "══════════════════════════════════════════════════════════════"
862
+ echo " STAGE C: INSTALL & VERIFY - Bob Widget v3.1.9"
863
+ echo "══════════════════════════════════════════════════════════════"
864
+
865
+ # Check Stage A was completed
866
+ if npm ls @gymmymac/bob-widget 2>/dev/null | grep -q "@gymmymac"; then
867
+ echo " ✗ ERROR: Old Bob package still detected!"
868
+ echo " ✗ Please complete STAGE A before running Stage C"
869
+ exit 1
870
+ fi
871
+
872
+ # Install Bob
873
+ echo ""
874
+ echo "Step 1: Installing @gymmymac/bob-widget@3.1.9..."
875
+ npm install @gymmymac/bob-widget@3.1.9
876
+
877
+ # Verify installation
878
+ echo ""
879
+ echo "Step 2: Verifying installation..."
880
+ INSTALLED_VERSION=$(npm ls @gymmymac/bob-widget --depth=0 2>/dev/null | grep "@gymmymac/bob-widget" | sed 's/.*@//')
881
+
882
+ if [ "$INSTALLED_VERSION" != "3.1.9" ]; then
883
+ echo " ✗ ERROR: Expected v3.1.9 but found $INSTALLED_VERSION"
884
+ exit 1
885
+ fi
886
+
887
+ echo " ✓ Package version: $INSTALLED_VERSION"
888
+
889
+ echo ""
890
+ echo "══════════════════════════════════════════════════════════════"
891
+ echo " ✓ STAGE C COMPLETE - Bob Widget installed successfully"
892
+ echo "══════════════════════════════════════════════════════════════"
893
+ echo ""
894
+ echo "NEXT: Add BobStandalone component to your container and test"
895
+ ```
896
+
897
+ #### Final Code Integration
898
+
899
+ Update your page from Stage B to import and use Bob:
900
+
901
+ ```tsx
902
+ // pages/ask-bob.tsx - FINAL VERSION after Stage C
903
+ import React from 'react';
904
+ import { BobStandalone } from '@gymmymac/bob-widget';
905
+ import { useCart } from '@/hooks/useCart'; // Your cart hook
906
+ import { useRouter } from 'next/router'; // Or your router
907
+
908
+ /**
909
+ * AskBob Page - Bob Widget Container
910
+ *
911
+ * This page is rendered within the CARFIX layout which provides:
912
+ * - Header: 72px fixed at top
913
+ * - Bottom Navigation: 72px fixed at bottom
914
+ *
915
+ * Bob container height = 100dvh - 144px (header + nav) - safe-area
916
+ */
917
+ export default function AskBobPage() {
918
+ const { addToCart } = useCart();
919
+ const router = useRouter();
920
+ const sessionToken = router.query.session as string;
921
+
922
+ return (
923
+ <div
924
+ id="bob-container"
925
+ style={{
926
+ height: 'calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))',
927
+ position: 'relative',
928
+ overflow: 'hidden',
929
+ width: '100%'
930
+ }}
931
+ >
932
+ <BobStandalone
933
+ partner="CARFIX"
934
+ sessionToken={sessionToken}
935
+ onAddToCart={(item) => {
936
+ addToCart({
937
+ productId: item.product_id,
938
+ name: item.product_name,
939
+ quantity: item.quantity,
940
+ price: item.unit_price,
941
+ sku: item.sku,
942
+ brand: item.brand,
943
+ imageUrl: item.image_url,
944
+ });
945
+ }}
946
+ onNavigate={(url) => router.push(url)}
947
+ onCheckout={(url) => window.location.href = url}
948
+ />
949
+ </div>
950
+ );
951
+ }
952
+ ```
953
+
954
+ #### Stage C Verification Checklist (MANDATORY)
955
+
956
+ | Test | How to Verify | Expected Result |
957
+ |------|---------------|-----------------|
958
+ | **Version** | Open browser console | `[BobWidget] Package loaded - v3.1.9` |
959
+ | **DB Connection** | Open Network tab, filter `gjoguxzstsihhxvdgpto` | 200 responses from Supabase |
960
+ | **Animation Data** | Check console for `[BobWidget]` logs | Animation states loaded (idle, talking, etc.) |
961
+ | **Partner Config** | Check Network for `bob_partners` query | CARFIX config returned |
962
+ | **Bob Visibility** | Visual check | Bob character fully visible, not cropped |
963
+ | **No Blur** | Visual check | Background is NOT blurred (clean backdrop) |
964
+ | **Correct Scale** | Visual check | Bob is prominently sized, not tiny |
965
+ | **Position** | Visual check | Bob positioned above counter overlay |
966
+ | **Chat Input** | Type a message | Message sends and Bob responds |
967
+ | **PTT** | Click microphone (HTTPS only) | Speech recognition activates |
968
+ | **Vehicle Lookup** | Enter REGO | Vehicle results returned |
969
+ | **Add to Cart** | Say "add to cart" | onAddToCart callback fires |
970
+
971
+ ---
972
+
973
+ ### Migration Comparison
974
+
975
+ | Aspect | Old Process | v3.1.9 3-Stage Process |
976
+ |--------|-------------|------------------------|
977
+ | Cleanup | Intermingled with install | **Stage A**: Separate, mandatory |
978
+ | Page setup | Assumed | **Stage B**: Explicit template |
979
+ | Installation | Single step | **Stage C**: With verification |
980
+ | Error detection | After issues appear | Script exits on detection |
981
+ | Verification | Optional | Mandatory checklist |
982
+ | Success rate | Variable | High (issues caught early) |
983
+
984
+ ---
985
+
986
+ ## 11. Changelog Summary
987
+
988
+ ### v3.1.9 (Current)
989
+ - 🔧 **3-Stage Installation Process**: Complete rewrite of Section 10 with strict sequential stages
990
+ - **Stage A: Forensic Removal** - Script now EXITS with error if any Bob files/imports found
991
+ - **Stage B: Page Preparation** - Clear template for creating blank container page
992
+ - **Stage C: Install & Verify** - Fresh installation with mandatory verification checklist
993
+ - 📖 **Documentation Restructure**: Installation and cleanup clearly separated into distinct stages
994
+ - ⚠️ **Prevents Legacy Code Interference**: Enhanced cleanup script with comprehensive detection
995
+
996
+ ### v3.1.8
997
+ - 📖 **Documentation Clarity**: Clarified that Bob container is placed on a page WITH existing CARFIX header/bottom nav
998
+ - ⚠️ **Pre-Install Requirements**: Emphasized mandatory forensic cleanup before installation
999
+ - 📐 **Page Layout Context**: Added explicit guidance that Bob fits BETWEEN fixed layout elements
1000
+
1001
+ ### v3.1.7
1002
+ - 📦 **Version Sync**: Prepared release with all version references aligned
1003
+
1004
+ ### v3.1.6
1005
+ - 📖 **README Update**: Added prominent "Read Before Installing" section
1006
+ - 📐 **Layout Corrections**: Documented 144px offset formula with safe-area support
1007
+
1008
+ ### v3.1.5
1009
+ - 📦 **Version Sync**: Re-released to sync package.json version with GitHub release tag
1010
+ - 📐 **Layout Corrections**: Updated CARFIX measurements to 72px header + 72px bottom nav
1011
+
1012
+ ### v3.1.4
1013
+ - 📦 **Supabase Bundling**: Removed @supabase/supabase-js from external to prevent "module not found" errors
1014
+ - 🔒 **HTTPS Validation**: Added programmatic check for PTT - warns users on HTTP connections
1015
+ - 🔧 **Debug Logging**: Consolidated all internal logs via bobLog utility respecting debug prop
1016
+
1017
+ ### v3.1.3
1018
+ - 🎨 **CSS Isolation**: Enhanced with `isolation: isolate` and `all: initial`
1019
+ - 📐 **Embedded Mode**: Added `embedded` prop for fullscreen variant in host containers
1020
+
1021
+ ### v3.1.2
1022
+ - 🔊 **Pre-recorded Audio Clips**: Fixed context property mismatch where `useSpeechSynthesis` was accessing `supabase` instead of `bobSupabase`, causing pre-recorded clips to never play
1023
+
1024
+ ### v3.1.1
1025
+ - ⚛️ **React Hooks Order Violation**: Fixed hooks being called after conditional returns
1026
+ - 🌐 **Allowed Origins**: Added Lovable preview domain support
1027
+
1028
+ ### v3.1.0
1029
+ - 🎯 **BobStandalone**: Auto-configures from database - 4 lines to integrate
1030
+ - 🗄️ **Partner Config System**: All settings in `bob_partners` table
1031
+ - 🎨 **CSS Variables**: Customizable blur, opacity, colors
1032
+ - 🔍 **Debug Overlay**: Visual diagnostic tool
1033
+ - 📦 **Simplified Callbacks**: Only essential callbacks required
1034
+
1035
+ ### v3.0.x
1036
+ - 🎭 **SwipeableBob**: Gesture-based interactions
1037
+ - 🏢 **Multi-Tenant Support**: Configurable looks and animations per tenant
1038
+ - 🎬 **RAF Animations**: Smooth 60fps animations
1039
+ - ⚡ **MatrixProductLoader**: Cyberpunk-style loading
1040
+ - 🔥 **SparkDealBanner**: Animated promotional banners
1041
+ - 👋 **Returning User Detection**: Personalized greetings
1042
+
1043
+ See [CHANGELOG.md](./CHANGELOG.md) for full version history.
1044
+
1045
+ ---
1046
+
1047
+ ## Dependencies
1048
+
1049
+ Bob Widget v3.1.9 **bundles** its own dependencies. Your project only needs:
1050
+
1051
+ | Dependency | Version | Required |
1052
+ |------------|---------|----------|
1053
+ | `react` | ^18.0.0 | ✅ Yes |
1054
+ | `react-dom` | ^18.0.0 | ✅ Yes |
1055
+ | `@tanstack/react-query` | any | ❌ Optional (bundled) |
1056
+ | `@supabase/supabase-js` | any | ❌ Optional (bundled) |
1057
+
1058
+ ---
1059
+
1060
+ ## Support
1061
+
1062
+ If you encounter any issues:
1063
+
1064
+ 1. Enable debug mode (`debug={true}`)
1065
+ 2. Check browser console for `[BobWidget]` logs
1066
+ 3. Check Network tab for API responses
1067
+ 4. Verify HTTPS for PTT functionality
1068
+ 5. Contact the Bob Widget team with console logs and version info
1069
+
1070
+ ---
1071
+
1072
+ ## License
1073
+
1074
+ MIT