@schandlergarcia/sf-web-components 1.9.88 → 2.1.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 (44) hide show
  1. package/.a4drules/features/command-center-dashboard-rule.md +1 -1
  2. package/.a4drules/skills/command-center-builder/SKILL.md +33 -36
  3. package/.a4drules/skills/command-center-builder/getting-started.md +64 -104
  4. package/.a4drules/skills/command-center-builder/improved-build-process.md +28 -34
  5. package/.a4drules/skills/command-center-guide/SKILL.md +9 -9
  6. package/.a4drules/skills/command-center-project/SKILL.md +4 -5
  7. package/.a4drules/skills/component-library/SKILL.md +8 -10
  8. package/.a4drules/skills/component-library/card-components.md +3 -3
  9. package/.a4drules/skills/component-library/chat-data.md +4 -6
  10. package/.a4drules/troubleshooting/codegen-overwrites-types.md +21 -162
  11. package/.a4drules/troubleshooting/graphql-introspection-failure.md +13 -264
  12. package/.a4drules/validation-requirements.md +3 -5
  13. package/.a4drules/webapp-data.md +1 -1
  14. package/CHANGELOG.md +33 -0
  15. package/CLAUDE.md +42 -39
  16. package/brands/engine/brand.css +40 -0
  17. package/brands/engine/global.css +234 -0
  18. package/dist/components/library/cards/ActivityCard.js +9 -9
  19. package/dist/components/library/cards/ActivityCard.js.map +1 -1
  20. package/dist/styles/base.css +112 -27
  21. package/dist/styles/global.css +15 -30
  22. package/package.json +7 -4
  23. package/scripts/apply-brand.mjs +178 -0
  24. package/scripts/postinstall.mjs +24 -201
  25. package/scripts/reset-command-center.sh +53 -411
  26. package/scripts/validate-dashboard.sh +4 -4
  27. package/src/components/library/cards/ActivityCard.jsx +2 -2
  28. package/src/styles/base.css +223 -0
  29. package/src/styles/global.css +223 -0
  30. package/src/templates/config/vite.config.ts.template +0 -18
  31. package/.a4drules/features/engine-dashboard-rule.md +0 -63
  32. package/.a4drules/features/phase2-data-pattern.md +0 -15
  33. package/data/README.md +0 -202
  34. package/data/USAGE.md +0 -81
  35. package/data/copy-to-webapp.sh +0 -61
  36. package/scripts/generate-schema-from-sample.mjs +0 -370
  37. /package/{data → brands/engine}/agentApiConfig.ts +0 -0
  38. /package/{data → brands/engine}/engine-command-center-prd.md +0 -0
  39. /package/{data → brands/engine}/engine-live-data.js +0 -0
  40. /package/{data → brands/engine}/engine-sample-data.js +0 -0
  41. /package/{assets/images → brands/engine}/engine_logo.png +0 -0
  42. /package/{data → brands/engine}/schema.graphql +0 -0
  43. /package/{data → brands/engine}/useEngineLiveData.ts +0 -0
  44. /package/{data → brands/engine}/useEvaAgent.ts +0 -0
@@ -398,413 +398,75 @@ echo "→ Cleaning caches…"
398
398
  rm -rf node_modules/.vite 2>/dev/null && echo " ✓ Cleared Vite cache" || true
399
399
  echo ""
400
400
 
401
- # ── 9. Restore Engine-branded global.css ────────────────────────────────────
401
+ # ── 9. Restore global.css (brand-aware) ──────────────────────────────────────
402
402
 
403
- # Ensure src/styles directory exists
404
403
  mkdir -p src/styles
405
404
 
406
405
  GLOBAL_CSS="src/styles/global.css"
407
- echo "→ Restoring Engine-branded ${GLOBAL_CSS}..."
406
+ echo "→ Restoring ${GLOBAL_CSS}..."
408
407
 
409
- cat > "$GLOBAL_CSS" << 'GLOBAL_CSS_EOF'
410
- @import '@heroui/styles';
411
-
412
- @layer base {
413
- html,
414
- body,
415
- #root {
416
- @apply min-h-screen;
417
- }
418
-
419
- body {
420
- @apply antialiased bg-white;
421
- }
422
- }
423
-
424
- @import 'tw-animate-css';
425
- @import 'shadcn/tailwind.css';
426
-
427
- @custom-variant dark (&:is(.dark *));
428
-
429
- @source "../components/library";
430
- @source "../components/pages";
431
-
432
- @theme inline {
433
- --color-background: var(--background);
434
- --color-foreground: var(--foreground);
435
- --color-card: var(--card);
436
- --color-card-foreground: var(--card-foreground);
437
- --color-popover: var(--popover);
438
- --color-popover-foreground: var(--popover-foreground);
439
- --color-primary: var(--primary);
440
- --color-primary-foreground: var(--primary-foreground);
441
- --color-secondary: var(--secondary);
442
- --color-secondary-foreground: var(--secondary-foreground);
443
- --color-muted: var(--muted);
444
- --color-muted-foreground: var(--muted-foreground);
445
- --color-accent: var(--accent);
446
- --color-accent-foreground: var(--accent-foreground);
447
- --color-destructive: var(--destructive);
448
- --color-destructive-foreground: var(--destructive-foreground);
449
- --color-border: var(--border);
450
- --color-input: var(--input);
451
- --color-ring: var(--ring);
452
- --color-chart-1: var(--chart-1);
453
- --color-chart-2: var(--chart-2);
454
- --color-chart-3: var(--chart-3);
455
- --color-chart-4: var(--chart-4);
456
- --color-chart-5: var(--chart-5);
457
- --radius-sm: calc(var(--radius) - 4px);
458
- --radius-md: calc(var(--radius) - 2px);
459
- --radius-lg: var(--radius);
460
- --radius-xl: calc(var(--radius) + 4px);
461
- --color-sidebar: var(--sidebar);
462
- --color-sidebar-foreground: var(--sidebar-foreground);
463
- --color-sidebar-primary: var(--sidebar-primary);
464
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
465
- --color-sidebar-accent: var(--sidebar-accent);
466
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
467
- --color-sidebar-border: var(--sidebar-border);
468
- --color-sidebar-ring: var(--sidebar-ring);
469
-
470
- /* Engine brand palette */
471
- --color-engine-black: #111111;
472
- --color-engine-teal: #5BC8C8;
473
- --color-engine-green: #3DAB5F;
474
- --color-engine-coral: #FF5722;
475
- --color-engine-orange: #F59E0B;
476
- --color-engine-savings: #16A34A;
477
- --color-engine-bg: #F7F8FA;
478
- --color-engine-border: #E5E7EB;
479
- --color-engine-text: #111111;
480
- --color-engine-muted: #6B7280;
481
- --color-engine-label: #9CA3AF;
482
-
483
- /* Engine teal brand palette */
484
- --color-brand-50: #ECFDF9;
485
- --color-brand-100: #D1FAF0;
486
- --color-brand-200: #A7F3E1;
487
- --color-brand-300: #6EE7C8;
488
- --color-brand-400: #34D3AB;
489
- --color-brand-500: #5BC8C8;
490
- --color-brand-600: #0D9488;
491
- --color-brand-700: #0F766E;
492
- --color-brand-800: #115E59;
493
- --color-brand-900: #134E4A;
494
- --color-brand-950: #042F2E;
495
-
496
- --font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
497
- --font-mono: 'JetBrains Mono', ui-monospace, monospace;
498
-
499
- /* Engine border radius tokens */
500
- --radius-pill: 9999px;
501
- --radius-card: 10px;
502
- }
503
-
504
- :root {
505
- --radius: 0.625rem;
506
- --background: oklch(1 0 0);
507
- --foreground: oklch(0.145 0 0);
508
- --card: oklch(1 0 0);
509
- --card-foreground: oklch(0.145 0 0);
510
- --popover: oklch(1 0 0);
511
- --popover-foreground: oklch(0.145 0 0);
512
- --primary: oklch(0.205 0 0);
513
- --primary-foreground: oklch(0.985 0 0);
514
- --secondary: oklch(0.97 0 0);
515
- --secondary-foreground: oklch(0.205 0 0);
516
- --muted: oklch(0.97 0 0);
517
- --muted-foreground: oklch(0.556 0 0);
518
- --accent: oklch(0.97 0 0);
519
- --accent-foreground: oklch(0.205 0 0);
520
- --destructive: oklch(0.577 0.245 27.325);
521
- --border: oklch(0.922 0 0);
522
- --input: oklch(0.922 0 0);
523
- --ring: oklch(0.708 0 0);
524
- --chart-1: oklch(0.646 0.222 41.116);
525
- --chart-2: oklch(0.6 0.118 184.704);
526
- --chart-3: oklch(0.398 0.07 227.392);
527
- --chart-4: oklch(0.828 0.189 84.429);
528
- --chart-5: oklch(0.769 0.188 70.08);
529
- --sidebar: oklch(0.985 0 0);
530
- --sidebar-foreground: oklch(0.145 0 0);
531
- --sidebar-primary: oklch(0.205 0 0);
532
- --sidebar-primary-foreground: oklch(0.985 0 0);
533
- --sidebar-accent: oklch(0.97 0 0);
534
- --sidebar-accent-foreground: oklch(0.205 0 0);
535
- --sidebar-border: oklch(0.922 0 0);
536
- --sidebar-ring: oklch(0.708 0 0);
537
- }
538
-
539
- .dark {
540
- --background: oklch(0.145 0 0);
541
- --foreground: oklch(0.985 0 0);
542
- --card: oklch(0.205 0 0);
543
- --card-foreground: oklch(0.985 0 0);
544
- --popover: oklch(0.205 0 0);
545
- --popover-foreground: oklch(0.985 0 0);
546
- --primary: oklch(0.922 0 0);
547
- --primary-foreground: oklch(0.205 0 0);
548
- --secondary: oklch(0.269 0 0);
549
- --secondary-foreground: oklch(0.985 0 0);
550
- --muted: oklch(0.269 0 0);
551
- --muted-foreground: oklch(0.708 0 0);
552
- --accent: oklch(0.269 0 0);
553
- --accent-foreground: oklch(0.985 0 0);
554
- --destructive: oklch(0.704 0.191 22.216);
555
- --border: oklch(1 0 0 / 10%);
556
- --input: oklch(1 0 0 / 15%);
557
- --ring: oklch(0.556 0 0);
558
- --chart-1: oklch(0.488 0.243 264.376);
559
- --chart-2: oklch(0.696 0.17 162.48);
560
- --chart-3: oklch(0.769 0.188 70.08);
561
- --chart-4: oklch(0.627 0.265 303.9);
562
- --chart-5: oklch(0.645 0.246 16.439);
563
- --sidebar: oklch(0.205 0 0);
564
- --sidebar-foreground: oklch(0.985 0 0);
565
- --sidebar-primary: oklch(0.488 0.243 264.376);
566
- --sidebar-primary-foreground: oklch(0.985 0 0);
567
- --sidebar-accent: oklch(0.269 0 0);
568
- --sidebar-accent-foreground: oklch(0.985 0 0);
569
- --sidebar-border: oklch(1 0 0 / 10%);
570
- --sidebar-ring: oklch(0.556 0 0);
571
- }
572
-
573
- @layer base {
574
- * {
575
- @apply border-border outline-ring/50;
576
- }
577
- body {
578
- @apply bg-background text-foreground;
579
- }
580
- }
581
-
582
- /*
583
- * Restore HeroUI theme variables inside the Command Center scope.
584
- * shadcn redefines --muted, --accent, --accent-foreground with different
585
- * semantics (bg colors vs text colors). This scope restores HeroUI's values
586
- * so HeroUI components render correctly.
587
- */
588
- .heroui-scope {
589
- /* Engine HeroUI theme overrides */
590
- --primary: #000000;
591
- --primary-foreground: oklch(0.9911 0 0);
592
- --secondary: #5BC8C8;
593
- --secondary-foreground: oklch(0.2103 0.0059 285.89);
594
- --success: #16A34A;
595
- --success-foreground: oklch(0.9911 0 0);
596
- --warning: #F59E0B;
597
- --warning-foreground: oklch(0.2103 0.0059 285.89);
598
- --danger: #FF5722;
599
- --danger-foreground: oklch(0.9911 0 0);
600
-
601
- --muted: oklch(0.5517 0.0138 285.94);
602
- --accent: oklch(0.6204 0.195 253.83);
603
- --accent-foreground: oklch(0.9911 0 0);
604
- --background: oklch(0.9702 0 0);
605
- --foreground: oklch(0.2103 0.0059 285.89);
606
- --default: oklch(94% 0.001 286.375);
607
- --default-foreground: oklch(0.2103 0.0059 285.89);
608
- --border: oklch(90% 0.004 286.32);
609
- --separator: oklch(92% 0.004 286.32);
610
- --segment: oklch(100% 0 0);
611
- --segment-foreground: oklch(0.2103 0.0059 285.89);
612
- --surface: oklch(100% 0 0);
613
- --surface-foreground: oklch(0.2103 0.0059 285.89);
614
- --overlay: oklch(100% 0 0);
615
- --overlay-foreground: oklch(0.2103 0.0059 285.89);
616
- --focus: oklch(0.6204 0.195 253.83);
617
- --link: oklch(0.2103 0.0059 285.89);
618
- }
619
-
620
- .dark .heroui-scope,
621
- .heroui-scope.dark {
622
- --muted: oklch(70.5% 0.015 286.067);
623
- --background: oklch(12% 0.005 285.823);
624
- --foreground: oklch(0.9911 0 0);
625
- --default: oklch(27.4% 0.006 286.033);
626
- --default-foreground: oklch(0.9911 0 0);
627
- --border: oklch(28% 0.006 286.033);
628
- --separator: oklch(25% 0.006 286.033);
629
- --segment: oklch(0.3964 0.01 285.93);
630
- --segment-foreground: oklch(0.9911 0 0);
631
- --surface: oklch(0.2103 0.0059 285.89);
632
- --surface-foreground: oklch(0.9911 0 0);
633
- --overlay: oklch(0.2103 0.0059 285.89);
634
- --overlay-foreground: oklch(0.9911 0 0);
635
- --warning: oklch(0.8203 0.1388 76.34);
636
- --warning-foreground: oklch(0.2103 0.0059 285.89);
637
- --danger: oklch(0.594 0.1967 24.63);
638
- --danger-foreground: oklch(0.9911 0 0);
639
- --focus: oklch(0.6204 0.195 253.83);
640
- --link: oklch(0.9911 0 0);
641
- }
642
- GLOBAL_CSS_EOF
643
-
644
- echo " ✓ Engine branding restored"
645
- echo ""
646
-
647
- # ── 10. Restore Engine sample data and schema ──────────────────────────────
648
-
649
- # Ensure src/data directory exists
650
- mkdir -p src/data
651
-
652
- ENGINE_DATA="src/data/engine-sample-data.js"
653
- echo "→ Restoring ${ENGINE_DATA}..."
654
-
655
- # Detect package location
656
- if [ -d "node_modules/@schandlergarcia/sf-web-components/data" ]; then
657
- PKG="node_modules/@schandlergarcia/sf-web-components"
658
- PACKAGE_DATA="$PKG/data/engine-sample-data.js"
659
- PACKAGE_LIVE_DATA="$PKG/data/engine-live-data.js"
660
- PACKAGE_LIVE_HOOK="$PKG/data/useEngineLiveData.ts"
661
- PACKAGE_SCHEMA="$PKG/data/schema.graphql"
662
- PACKAGE_EVA_HOOK="$PKG/data/useEvaAgent.ts"
663
- PACKAGE_AGENT_CONFIG="$PKG/data/agentApiConfig.ts"
664
- PACKAGE_DATA_STRATEGY="$PKG/src/templates/lib/dataStrategy.ts.template"
665
- elif [ -f "$SCRIPT_DIR/../data/engine-sample-data.js" ]; then
666
- # Running from package source
667
- PACKAGE_DATA="$SCRIPT_DIR/../data/engine-sample-data.js"
668
- PACKAGE_LIVE_DATA="$SCRIPT_DIR/../data/engine-live-data.js"
669
- PACKAGE_LIVE_HOOK="$SCRIPT_DIR/../data/useEngineLiveData.ts"
670
- PACKAGE_SCHEMA="$SCRIPT_DIR/../data/schema.graphql"
671
- PACKAGE_EVA_HOOK="$SCRIPT_DIR/../data/useEvaAgent.ts"
672
- PACKAGE_AGENT_CONFIG="$SCRIPT_DIR/../data/agentApiConfig.ts"
673
- PACKAGE_DATA_STRATEGY="$SCRIPT_DIR/../src/templates/lib/dataStrategy.ts.template"
674
- else
675
- echo " ⚠ Could not find engine-sample-data.js in package"
676
- PACKAGE_DATA=""
677
- PACKAGE_LIVE_DATA=""
678
- PACKAGE_LIVE_HOOK=""
679
- PACKAGE_SCHEMA=""
680
- PACKAGE_EVA_HOOK=""
681
- PACKAGE_AGENT_CONFIG=""
682
- PACKAGE_DATA_STRATEGY=""
683
- fi
684
-
685
- if [ -n "$PACKAGE_DATA" ] && [ -f "$PACKAGE_DATA" ]; then
686
- cp "$PACKAGE_DATA" "$ENGINE_DATA"
687
- echo " ✓ Engine sample data restored"
688
- else
689
- echo " ⚠ Skipped sample data (package data not found)"
690
- fi
691
-
692
- # Restore schema.graphql
693
- SCHEMA_FILE="schema.graphql"
694
- echo "→ Restoring ${SCHEMA_FILE}..."
695
-
696
- if [ -n "$PACKAGE_SCHEMA" ] && [ -f "$PACKAGE_SCHEMA" ]; then
697
- cp "$PACKAGE_SCHEMA" "$SCHEMA_FILE"
698
- echo " ✓ GraphQL schema restored (pre-built from sample data)"
699
- else
700
- echo " ⚠ Skipped schema (package schema not found)"
408
+ # Check if a brand is active
409
+ ACTIVE_BRAND=""
410
+ if [ -f ".brand" ]; then
411
+ ACTIVE_BRAND="$(cat .brand | tr -d '[:space:]')"
701
412
  fi
702
413
 
703
- # Restore engine-live-data.js
704
- ENGINE_LIVE_DATA="src/data/engine-live-data.js"
705
- echo "→ Restoring ${ENGINE_LIVE_DATA}..."
706
-
707
- if [ -n "$PACKAGE_LIVE_DATA" ] && [ -f "$PACKAGE_LIVE_DATA" ]; then
708
- cp "$PACKAGE_LIVE_DATA" "$ENGINE_LIVE_DATA"
709
- echo " ✓ Engine live data restored"
710
- else
711
- echo " ⚠ Skipped live data (package data not found)"
414
+ PACKAGE_CSS=""
415
+ if [ -n "$ACTIVE_BRAND" ]; then
416
+ # Use the brand's global.css
417
+ if [ -f "node_modules/@schandlergarcia/sf-web-components/brands/$ACTIVE_BRAND/global.css" ]; then
418
+ PACKAGE_CSS="node_modules/@schandlergarcia/sf-web-components/brands/$ACTIVE_BRAND/global.css"
419
+ elif [ -f "$SCRIPT_DIR/../brands/$ACTIVE_BRAND/global.css" ]; then
420
+ PACKAGE_CSS="$SCRIPT_DIR/../brands/$ACTIVE_BRAND/global.css"
421
+ fi
712
422
  fi
713
423
 
714
- # Restore useEngineLiveData.ts
715
- mkdir -p src/hooks
716
- LIVE_HOOK="src/hooks/useEngineLiveData.ts"
717
- echo "→ Restoring ${LIVE_HOOK}..."
718
-
719
- if [ -n "$PACKAGE_LIVE_HOOK" ] && [ -f "$PACKAGE_LIVE_HOOK" ]; then
720
- cp "$PACKAGE_LIVE_HOOK" "$LIVE_HOOK"
721
- echo " ✓ Live data hook restored"
722
- else
723
- echo " ⚠ Skipped live data hook (package hook not found)"
424
+ # Fall back to neutral if no brand or brand CSS not found
425
+ if [ -z "$PACKAGE_CSS" ]; then
426
+ if [ -f "node_modules/@schandlergarcia/sf-web-components/src/styles/global.css" ]; then
427
+ PACKAGE_CSS="node_modules/@schandlergarcia/sf-web-components/src/styles/global.css"
428
+ elif [ -f "$SCRIPT_DIR/../src/styles/global.css" ]; then
429
+ PACKAGE_CSS="$SCRIPT_DIR/../src/styles/global.css"
430
+ fi
724
431
  fi
725
432
 
726
- # Restore useEvaAgent.ts (Agentforce Agent API hook)
727
- EVA_HOOK="src/hooks/useEvaAgent.ts"
728
- echo "→ Restoring ${EVA_HOOK}..."
729
-
730
- if [ -n "$PACKAGE_EVA_HOOK" ] && [ -f "$PACKAGE_EVA_HOOK" ]; then
731
- cp "$PACKAGE_EVA_HOOK" "$EVA_HOOK"
732
- echo " ✓ Eva agent hook restored"
433
+ if [ -n "$PACKAGE_CSS" ] && [ -f "$PACKAGE_CSS" ]; then
434
+ cp "$PACKAGE_CSS" "$GLOBAL_CSS"
435
+ if [ -n "$ACTIVE_BRAND" ]; then
436
+ echo " ✓ Theme restored (brand: $ACTIVE_BRAND)"
437
+ else
438
+ echo " Theme restored (neutral)"
439
+ fi
733
440
  else
734
- echo " ⚠ Skipped Eva agent hook (package hook not found)"
441
+ echo " ⚠ Skipped global.css (package CSS not found)"
735
442
  fi
443
+ echo ""
736
444
 
737
- # Restore agentApiConfig.ts src/config/agentApi.ts
738
- mkdir -p src/config
739
- AGENT_CONFIG="src/config/agentApi.ts"
740
- echo "→ Restoring ${AGENT_CONFIG}..."
445
+ # ── 10. Restore dataStrategy.ts ─────────────────────────────────────────────
741
446
 
742
- if [ -n "$PACKAGE_AGENT_CONFIG" ] && [ -f "$PACKAGE_AGENT_CONFIG" ]; then
743
- cp "$PACKAGE_AGENT_CONFIG" "$AGENT_CONFIG"
744
- echo " ✓ Agent API config restored"
745
- else
746
- echo " ⚠ Skipped Agent API config (package config not found)"
447
+ PACKAGE_DATA_STRATEGY=""
448
+ if [ -f "node_modules/@schandlergarcia/sf-web-components/src/templates/lib/dataStrategy.ts.template" ]; then
449
+ PACKAGE_DATA_STRATEGY="node_modules/@schandlergarcia/sf-web-components/src/templates/lib/dataStrategy.ts.template"
450
+ elif [ -f "$SCRIPT_DIR/../src/templates/lib/dataStrategy.ts.template" ]; then
451
+ PACKAGE_DATA_STRATEGY="$SCRIPT_DIR/../src/templates/lib/dataStrategy.ts.template"
747
452
  fi
748
453
 
749
- # Restore dataStrategy.ts (reset ENABLE_SAMPLE_DATA_CACHE back to true)
750
454
  DATA_STRATEGY="src/lib/dataStrategy.ts"
751
455
  echo "→ Restoring ${DATA_STRATEGY}..."
752
456
 
753
457
  if [ -n "$PACKAGE_DATA_STRATEGY" ] && [ -f "$PACKAGE_DATA_STRATEGY" ]; then
458
+ mkdir -p src/lib
754
459
  cp "$PACKAGE_DATA_STRATEGY" "$DATA_STRATEGY"
755
460
  echo " ✓ Data strategy restored (ENABLE_SAMPLE_DATA_CACHE = true)"
756
461
  else
757
462
  echo " ⚠ Skipped data strategy (package template not found)"
758
463
  fi
464
+ echo ""
759
465
 
760
- # Restore engine-command-center-prd.md
761
- PRD_FILE="engine-command-center-prd.md"
762
- echo "→ Restoring ${PRD_FILE}..."
763
-
764
- # Detect package location for PRD
765
- if [ -d "node_modules/@schandlergarcia/sf-web-components/data" ]; then
766
- PACKAGE_PRD="node_modules/@schandlergarcia/sf-web-components/data/engine-command-center-prd.md"
767
- elif [ -f "$SCRIPT_DIR/../data/engine-command-center-prd.md" ]; then
768
- # Running from package source
769
- PACKAGE_PRD="$SCRIPT_DIR/../data/engine-command-center-prd.md"
770
- else
771
- PACKAGE_PRD=""
772
- fi
773
-
774
- if [ -n "$PACKAGE_PRD" ] && [ -f "$PACKAGE_PRD" ]; then
775
- cp "$PACKAGE_PRD" "$PRD_FILE"
776
- echo " ✓ Engine PRD restored"
777
- else
778
- echo " ⚠ Skipped PRD (package PRD not found)"
779
- fi
780
-
781
- # Restore engine_logo.png
782
- mkdir -p src/assets/images
783
- ENGINE_LOGO="src/assets/images/engine_logo.png"
784
- echo "→ Restoring ${ENGINE_LOGO}..."
785
-
786
- # Detect package location for logo
787
- if [ -d "node_modules/@schandlergarcia/sf-web-components/assets/images" ]; then
788
- PACKAGE_LOGO="node_modules/@schandlergarcia/sf-web-components/assets/images/engine_logo.png"
789
- elif [ -f "$SCRIPT_DIR/../assets/images/engine_logo.png" ]; then
790
- # Running from package source
791
- PACKAGE_LOGO="$SCRIPT_DIR/../assets/images/engine_logo.png"
792
- else
793
- PACKAGE_LOGO=""
794
- fi
795
-
796
- if [ -n "$PACKAGE_LOGO" ] && [ -f "$PACKAGE_LOGO" ]; then
797
- cp "$PACKAGE_LOGO" "$ENGINE_LOGO"
798
- echo " ✓ Engine logo restored"
799
- else
800
- echo " ⚠ Skipped logo (package logo not found)"
801
- fi
802
-
803
- # ── Restore .a4drules to project root ─────────────────────────────────────────
466
+ # ── 11. Restore .a4drules to project root ────────────────────────────────────
804
467
 
805
468
  echo "→ Restoring AI assistant rules (.a4drules)..."
806
469
 
807
- # Detect package .a4drules location
808
470
  PACKAGE_A4D=""
809
471
  if [ -d "node_modules/@schandlergarcia/sf-web-components/.a4drules" ]; then
810
472
  PACKAGE_A4D="node_modules/@schandlergarcia/sf-web-components/.a4drules"
@@ -813,7 +475,6 @@ elif [ -d "$SCRIPT_DIR/../.a4drules" ]; then
813
475
  fi
814
476
 
815
477
  if [ -n "$PACKAGE_A4D" ]; then
816
- # Resolve project root (5 levels up from webapp, or 1 level up from package source)
817
478
  PROJECT_ROOT=""
818
479
  if [[ "$ROOT_ABS" == */force-app/main/default/* ]]; then
819
480
  PROJECT_ROOT="${ROOT_ABS%%/force-app/main/default/*}"
@@ -825,7 +486,6 @@ if [ -n "$PACKAGE_A4D" ]; then
825
486
  TARGET_A4D="$PROJECT_ROOT/.a4drules"
826
487
  a4d_copied=0
827
488
 
828
- # Force-copy every .md file individually (cp -R doesn't always overwrite)
829
489
  while IFS= read -r src_file; do
830
490
  rel="${src_file#$PACKAGE_A4D/}"
831
491
  dst="$TARGET_A4D/$rel"
@@ -841,12 +501,10 @@ else
841
501
  fi
842
502
  echo ""
843
503
 
844
- # ── Clean Salesforce metadata created during the demo ────────────────────────
504
+ # ── 12. Clean Salesforce metadata created during the build ───────────────────
845
505
 
846
506
  SFDX_DEFAULT=""
847
507
 
848
- # The webapp lives inside force-app/main/default/uiBundles/..., so extract
849
- # the SFDX default directory from our own path first.
850
508
  if [[ "$ROOT_ABS" == */force-app/main/default/* ]]; then
851
509
  SFDX_DEFAULT="${ROOT_ABS%%/force-app/main/default/*}/force-app/main/default"
852
510
  fi
@@ -854,34 +512,23 @@ fi
854
512
  if [ -n "$SFDX_DEFAULT" ]; then
855
513
  metadata_cleaned=0
856
514
 
857
- # Remove Apex classes (.cls and .cls-meta.xml), preserving permanent classes
858
- KEEP_CLASSES=("TCC_TravelMetricsController")
515
+ # Remove Apex classes (.cls and .cls-meta.xml)
859
516
  CLASSES_DIR="$SFDX_DEFAULT/classes"
860
517
  if [ -d "$CLASSES_DIR" ]; then
861
518
  cls_removed=0
862
519
  for f in "$CLASSES_DIR"/*.cls "$CLASSES_DIR"/*.cls-meta.xml; do
863
520
  [ -f "$f" ] || continue
864
- base="$(basename "$f")"
865
- skip=false
866
- for keep in "${KEEP_CLASSES[@]}"; do
867
- if [[ "$base" == "$keep".cls || "$base" == "$keep".cls-meta.xml ]]; then
868
- skip=true
869
- break
870
- fi
871
- done
872
- if [ "$skip" = false ]; then
873
- [ "$metadata_cleaned" -eq 0 ] && [ "$cls_removed" -eq 0 ] && echo "→ Cleaning Salesforce metadata…"
874
- rm "$f"
875
- cls_removed=$((cls_removed + 1))
876
- fi
521
+ rm "$f"
522
+ cls_removed=$((cls_removed + 1))
877
523
  done
878
524
  if [ "$cls_removed" -gt 0 ]; then
879
- echo " Removed $cls_removed Apex class files (kept ${KEEP_CLASSES[*]})"
525
+ [ "$metadata_cleaned" -eq 0 ] && echo "→ Cleaning Salesforce metadata…"
526
+ echo " ✓ Removed $cls_removed Apex class files"
880
527
  metadata_cleaned=1
881
528
  fi
882
529
  fi
883
530
 
884
- # Remove platform event directories (but NOT custom fields — those persist across resets)
531
+ # Remove platform event directories
885
532
  OBJECTS_DIR="$SFDX_DEFAULT/objects"
886
533
  if [ -d "$OBJECTS_DIR" ]; then
887
534
  for evt_dir in "$OBJECTS_DIR"/*__e; do
@@ -903,24 +550,19 @@ echo "╔═══════════════════════
903
550
  echo "║ ✓ Reset complete! ║"
904
551
  echo "║ ║"
905
552
  echo "║ Restored: ║"
906
- echo "║ • Engine brand theme (global.css) ║"
907
- echo "║ • Engine sample data + live data ║"
908
- echo "║ • Live data hook (useEngineLiveData.ts) ║"
909
- echo "║ • Eva agent hook (useEvaAgent.ts) ║"
910
- echo "║ • Agent API config (src/config/agentApi.ts)║"
911
- echo "║ • Data strategy (ENABLE_SAMPLE_DATA_CACHE) ║"
912
- echo "║ • GraphQL schema + PRD + logo ║"
553
+ echo "║ • Theme (global.css) ║"
554
+ echo "║ • Data strategy (sample data cache) ║"
913
555
  echo "║ • Component library + theme providers ║"
914
- echo "║ • AI assistant rules (.a4drules) ║"
556
+ echo "║ • AI assistant rules (.a4drules) ║"
915
557
  echo "║ ║"
916
558
  echo "║ Cleaned: ║"
917
- echo "║ • Apex classes (force-app classes/) ║"
918
- echo "║ • Platform events (force-app *__e/) ║"
559
+ echo "║ • Custom dashboard pages ║"
560
+ echo "║ • Apex classes (if SFDX project) ║"
561
+ echo "║ • Platform events (if SFDX project) ║"
919
562
  echo "║ ║"
920
563
  echo "║ Layout: ║"
921
564
  echo "║ / → Home (search page) ║"
922
- echo "║ /search Search (search page) ║"
923
- echo "║ Nav bar on Home + Search pages only ║"
565
+ echo "║ /accounts Account search ║"
924
566
  echo "║ ║"
925
567
  echo "║ Start building: ║"
926
568
  echo "║ npm run dev ║"
@@ -14,7 +14,7 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
14
14
  cd "$ROOT"
15
15
 
16
16
  PAGES_DIR="src/components/pages"
17
- TRAVEL_DIR="src/components/travel"
17
+ CUSTOM_DIR="src/components/custom"
18
18
  ERRORS=0
19
19
  WARNINGS=0
20
20
 
@@ -43,9 +43,9 @@ echo ""
43
43
 
44
44
  # ── 2. Find all dashboard files to scan ──────────────────────────────────────
45
45
 
46
- # Collect all .jsx/.tsx in pages/ and travel/ dirs (excluding BlankDashboard, HelloWorld, CommandCenter)
46
+ # Collect all .jsx/.tsx in pages/ and custom/ dirs (excluding BlankDashboard, HelloWorld, CommandCenter)
47
47
  SCAN_FILES=()
48
- for dir in "$PAGES_DIR" "$TRAVEL_DIR" "src/pages"; do
48
+ for dir in "$PAGES_DIR" "$CUSTOM_DIR" "src/pages"; do
49
49
  if [ -d "$dir" ]; then
50
50
  while IFS= read -r f; do
51
51
  base=$(basename "$f")
@@ -231,7 +231,7 @@ echo "── File extensions (dashboard pages should be .jsx) ──"
231
231
  for f in "${SCAN_FILES[@]}"; do
232
232
  base=$(basename "$f")
233
233
 
234
- if [[ "$f" == *.tsx ]] && [[ "$f" == *components/pages* || "$f" == *components/travel* ]]; then
234
+ if [[ "$f" == *.tsx ]] && [[ "$f" == *components/pages* || "$f" == *components/custom* ]]; then
235
235
  yellow "$base: dashboard component uses .tsx — convention is .jsx"
236
236
  WARNINGS=$((WARNINGS + 1))
237
237
  fi
@@ -23,9 +23,9 @@ function ActionItem({ action }) {
23
23
  <s.Icon className={`mt-0.5 h-4 w-4 shrink-0 ${s.color} ${s.spin ? "animate-spin" : ""}`} />
24
24
  <div className="min-w-0">
25
25
  <div className="text-xs font-medium text-slate-700 dark:text-slate-200">{action.title ?? action.action}</div>
26
- {(action.subtitle ?? action.traveler ?? action.timestamp ?? action.startedAt) && (
26
+ {(action.subtitle ?? action.description ?? action.timestamp ?? action.startedAt) && (
27
27
  <div className="mt-0.5 text-[10px] text-slate-400">
28
- {[action.subtitle, action.traveler, action.timestamp ?? action.startedAt].filter(Boolean).join(" · ")}
28
+ {[action.subtitle, action.description, action.timestamp ?? action.startedAt].filter(Boolean).join(" · ")}
29
29
  </div>
30
30
  )}
31
31
  </div>