@schandlergarcia/sf-web-components 1.9.87 → 1.9.88

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,13 @@ All notable changes to this project will be documented in this file.
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
+ ## [1.9.88] - 2026-04-07
9
+
10
+ ### Fixed
11
+ - **Postinstall `.a4drules` copy** — now copies all root-level `.md` files (`webapp-ui.md`, `webapp-data.md`, `validation-requirements.md`, `RULES.md`) and all subdirectories (`skills/`, `features/`, `troubleshooting/`), not just `skills/` and `features/`. Ensures the full build guide reaches consuming projects.
12
+ - **Postinstall vite proxy injection** — when `vite.config.ts` already exists, the postinstall now checks for and injects the Agent API proxy rules (`/sf-oauth`, `/sf-agent`) if they're missing, rather than silently skipping.
13
+ - **Reset script `.a4drules` restore** — the reset script now force-copies every `.md` file from the package's `.a4drules` to the project root, preventing stale stubs from persisting across resets.
14
+
8
15
  ## [1.9.87] - 2026-04-07
9
16
 
10
17
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schandlergarcia/sf-web-components",
3
- "version": "1.9.87",
3
+ "version": "1.9.88",
4
4
  "description": "Reusable Salesforce web components library with Tailwind CSS v4 and shadcn/ui",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -429,7 +429,46 @@ if (fs.existsSync(viteConfigTemplatePath) && !fs.existsSync(viteConfigPath)) {
429
429
  console.error(` ✗ Failed to install vite.config.ts: ${error.message}`);
430
430
  }
431
431
  } else if (fs.existsSync(viteConfigPath)) {
432
- console.log(' ℹ vite.config.ts already exists (not overwriting)');
432
+ // Ensure Agent API proxy rules exist even in pre-existing vite.config.ts
433
+ try {
434
+ const existing = fs.readFileSync(viteConfigPath, 'utf-8');
435
+ if (!existing.includes('/sf-oauth') || !existing.includes("api.salesforce.com")) {
436
+ const proxyBlock = `
437
+ // Proxy Agentforce Agent API calls through the dev server to avoid CORS.
438
+ // /sf-oauth/* → Salesforce org (for OAuth client-credentials token)
439
+ // /sf-agent/* → Agent API base (for session + message calls)
440
+ server: {
441
+ proxy: {
442
+ '/sf-oauth': {
443
+ target: 'https://tdx26-keynote-org-1com.my.salesforce.com',
444
+ changeOrigin: true,
445
+ rewrite: (p: string) => p.replace(/^\\/sf-oauth/, ''),
446
+ },
447
+ '/sf-agent': {
448
+ target: 'https://api.salesforce.com',
449
+ changeOrigin: true,
450
+ rewrite: (p: string) => p.replace(/^\\/sf-agent/, ''),
451
+ },
452
+ },
453
+ },
454
+ `;
455
+ // Insert before the build: { section if it exists
456
+ if (existing.includes('build: {') && !existing.includes('server: {')) {
457
+ const updated = existing.replace(
458
+ /(\s*)(\/\/.*Build|build:\s*\{)/,
459
+ proxyBlock + '\n$1$2'
460
+ );
461
+ if (updated !== existing) {
462
+ fs.writeFileSync(viteConfigPath, updated, 'utf-8');
463
+ console.log(' ✓ Added Agent API proxy rules to existing vite.config.ts');
464
+ }
465
+ }
466
+ } else {
467
+ console.log(' ℹ vite.config.ts already has proxy rules');
468
+ }
469
+ } catch {
470
+ // Non-critical — proxy can be added manually
471
+ }
433
472
  }
434
473
 
435
474
  // Copy dataStrategy.ts template
@@ -501,35 +540,48 @@ if (fs.existsSync(packageJsonPath)) {
501
540
 
502
541
  // Copy .a4drules from package to project root (so AI assistants can discover them)
503
542
  const packageA4dRules = path.join(packageRoot, '.a4drules');
504
- const projectRootA4dRules = path.join(cwd, '../../../../../.a4drules'); // Go up from webapp to project root
505
543
 
506
544
  if (fs.existsSync(packageA4dRules)) {
507
545
  console.log('\n📋 Copying AI assistant rules to project root...\n');
508
546
 
509
- // Resolve to absolute path
510
547
  const projectRootPath = path.resolve(cwd, '../../../../../');
511
548
  const targetA4dRules = path.join(projectRootPath, '.a4drules');
512
549
 
513
- // Create .a4drules if it doesn't exist
514
550
  if (!fs.existsSync(targetA4dRules)) {
515
551
  fs.mkdirSync(targetA4dRules, { recursive: true });
516
552
  }
517
553
 
518
- // Copy skills directory
519
- const skillsSource = path.join(packageA4dRules, 'skills');
520
- const skillsTarget = path.join(targetA4dRules, 'skills');
521
- if (fs.existsSync(skillsSource)) {
522
- const skillsCopied = copyDirectoryRecursive(skillsSource, skillsTarget);
523
- console.log(` ✓ Copied ${skillsCopied} skill files`);
554
+ let totalA4dCopied = 0;
555
+
556
+ // Force-copy root-level .md files first
557
+ const rootFiles = fs.readdirSync(packageA4dRules).filter(f => f.endsWith('.md'));
558
+ for (const file of rootFiles) {
559
+ try {
560
+ fs.copyFileSync(path.join(packageA4dRules, file), path.join(targetA4dRules, file));
561
+ totalA4dCopied++;
562
+ } catch (error) {
563
+ console.error(` ✗ Failed to copy ${file}: ${error.message}`);
564
+ }
565
+ }
566
+ if (rootFiles.length > 0) {
567
+ console.log(` ✓ Copied ${rootFiles.length} root rule files`);
524
568
  }
525
569
 
526
- // Copy features directory
527
- const featuresSource = path.join(packageA4dRules, 'features');
528
- const featuresTarget = path.join(targetA4dRules, 'features');
529
- if (fs.existsSync(featuresSource)) {
530
- const featuresCopied = copyDirectoryRecursive(featuresSource, featuresTarget);
531
- console.log(` ✓ Copied ${featuresCopied} feature rule files`);
570
+ // Copy all subdirectories (skills, features, troubleshooting)
571
+ const subdirs = fs.readdirSync(packageA4dRules).filter(d => {
572
+ const full = path.join(packageA4dRules, d);
573
+ return fs.statSync(full).isDirectory();
574
+ });
575
+
576
+ for (const subdir of subdirs) {
577
+ const src = path.join(packageA4dRules, subdir);
578
+ const dst = path.join(targetA4dRules, subdir);
579
+ const copied = copyDirectoryRecursive(src, dst);
580
+ totalA4dCopied += copied;
581
+ console.log(` ✓ Copied ${copied} files from ${subdir}/`);
532
582
  }
583
+
584
+ console.log(` 📋 Total: ${totalA4dCopied} rule files installed`);
533
585
  }
534
586
 
535
587
  // Migrate any dashboards from old location (src/components/pages/) to new location (src/pages/)
@@ -27,6 +27,7 @@ else
27
27
  fi
28
28
 
29
29
  cd "$ROOT"
30
+ ROOT_ABS="$(cd "$ROOT" && pwd)"
30
31
 
31
32
  echo ""
32
33
  echo "╔════════════════════════════════════════════════╗"
@@ -799,15 +800,53 @@ else
799
800
  echo " ⚠ Skipped logo (package logo not found)"
800
801
  fi
801
802
 
803
+ # ── Restore .a4drules to project root ─────────────────────────────────────────
804
+
805
+ echo "→ Restoring AI assistant rules (.a4drules)..."
806
+
807
+ # Detect package .a4drules location
808
+ PACKAGE_A4D=""
809
+ if [ -d "node_modules/@schandlergarcia/sf-web-components/.a4drules" ]; then
810
+ PACKAGE_A4D="node_modules/@schandlergarcia/sf-web-components/.a4drules"
811
+ elif [ -d "$SCRIPT_DIR/../.a4drules" ]; then
812
+ PACKAGE_A4D="$SCRIPT_DIR/../.a4drules"
813
+ fi
814
+
815
+ if [ -n "$PACKAGE_A4D" ]; then
816
+ # Resolve project root (5 levels up from webapp, or 1 level up from package source)
817
+ PROJECT_ROOT=""
818
+ if [[ "$ROOT_ABS" == */force-app/main/default/* ]]; then
819
+ PROJECT_ROOT="${ROOT_ABS%%/force-app/main/default/*}"
820
+ else
821
+ PROJECT_ROOT="$ROOT/.."
822
+ fi
823
+
824
+ if [ -n "$PROJECT_ROOT" ] && [ -d "$PROJECT_ROOT" ]; then
825
+ TARGET_A4D="$PROJECT_ROOT/.a4drules"
826
+ a4d_copied=0
827
+
828
+ # Force-copy every .md file individually (cp -R doesn't always overwrite)
829
+ while IFS= read -r src_file; do
830
+ rel="${src_file#$PACKAGE_A4D/}"
831
+ dst="$TARGET_A4D/$rel"
832
+ mkdir -p "$(dirname "$dst")"
833
+ cp -f "$src_file" "$dst"
834
+ a4d_copied=$((a4d_copied + 1))
835
+ done < <(find "$PACKAGE_A4D" -name "*.md" -type f)
836
+
837
+ echo " ✓ Restored $a4d_copied rule files to $TARGET_A4D"
838
+ fi
839
+ else
840
+ echo " ⚠ Skipped .a4drules (package rules not found)"
841
+ fi
842
+ echo ""
843
+
802
844
  # ── Clean Salesforce metadata created during the demo ────────────────────────
803
845
 
804
846
  SFDX_DEFAULT=""
805
847
 
806
848
  # The webapp lives inside force-app/main/default/uiBundles/..., so extract
807
- # the SFDX default directory from our own path first. Only fall back to
808
- # searching child directories if the pattern doesn't match (standalone app).
809
- ROOT_ABS="$(cd "$ROOT" && pwd)"
810
-
849
+ # the SFDX default directory from our own path first.
811
850
  if [[ "$ROOT_ABS" == */force-app/main/default/* ]]; then
812
851
  SFDX_DEFAULT="${ROOT_ABS%%/force-app/main/default/*}/force-app/main/default"
813
852
  fi
@@ -872,6 +911,7 @@ echo "║ • Agent API config (src/config/agentApi.ts)║"
872
911
  echo "║ • Data strategy (ENABLE_SAMPLE_DATA_CACHE) ║"
873
912
  echo "║ • GraphQL schema + PRD + logo ║"
874
913
  echo "║ • Component library + theme providers ║"
914
+ echo "║ • AI assistant rules (.a4drules) ║"
875
915
  echo "║ ║"
876
916
  echo "║ Cleaned: ║"
877
917
  echo "║ • Apex classes (force-app classes/) ║"