sonance-brand-mcp 1.3.2 → 1.3.4

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 (2) hide show
  1. package/dist/index.js +270 -17
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -274,6 +274,20 @@ const BUNDLED_ASSETS = path.join(__dirname, "assets");
274
274
  const IS_BUNDLED = fs.existsSync(BUNDLED_ASSETS);
275
275
  // Development paths (when running from source)
276
276
  const DEV_PROJECT_ROOT = path.resolve(__dirname, "../..");
277
+ /**
278
+ * Calculate relative path from one file to another for CSS imports
279
+ */
280
+ function getRelativeImportPath(fromFile, toFile) {
281
+ const fromDir = path.dirname(fromFile);
282
+ let relativePath = path.relative(fromDir, toFile);
283
+ // Ensure forward slashes for CSS imports (Windows compatibility)
284
+ relativePath = relativePath.replace(/\\/g, '/');
285
+ // CSS imports need ./ prefix for same-level or relative paths
286
+ if (!relativePath.startsWith('.')) {
287
+ relativePath = './' + relativePath;
288
+ }
289
+ return relativePath;
290
+ }
277
291
  /**
278
292
  * Run the installer for DevTools Plugin (copies files to user project)
279
293
  */
@@ -463,26 +477,260 @@ function runDevToolsInstaller() {
463
477
  fs.writeFileSync(path.join(themeDir, "sonance-config.json"), JSON.stringify(initialConfig, null, 2), "utf-8");
464
478
  console.log(" ✓ Created src/theme/ with initial files");
465
479
  }
480
+ // Detect user's file paths
481
+ const globalsCssPaths = [
482
+ "src/app/globals.css",
483
+ "app/globals.css",
484
+ "src/styles/globals.css",
485
+ "styles/globals.css"
486
+ ];
487
+ const layoutPaths = [
488
+ "src/app/layout.tsx",
489
+ "app/layout.tsx",
490
+ "src/app/layout.jsx",
491
+ "app/layout.jsx"
492
+ ];
493
+ let detectedGlobalsCss = null;
494
+ let detectedLayout = null;
495
+ for (const cssPath of globalsCssPaths) {
496
+ if (fs.existsSync(path.join(targetDir, cssPath))) {
497
+ detectedGlobalsCss = cssPath;
498
+ break;
499
+ }
500
+ }
501
+ for (const layoutPath of layoutPaths) {
502
+ if (fs.existsSync(path.join(targetDir, layoutPath))) {
503
+ detectedLayout = layoutPath;
504
+ break;
505
+ }
506
+ }
507
+ // Track what was auto-configured vs needs manual setup
508
+ let cssAutoConfigured = false;
509
+ let layoutAutoConfigured = false;
510
+ const manualSteps = [];
511
+ // --- Auto-inject CSS imports into globals.css ---
512
+ if (detectedGlobalsCss) {
513
+ const globalsFullPath = path.join(targetDir, detectedGlobalsCss);
514
+ try {
515
+ let cssContent = fs.readFileSync(globalsFullPath, "utf-8");
516
+ // Calculate correct relative paths from globals.css to the target files
517
+ const stylesTarget = path.join(targetDir, "src/styles/brand-overrides.css");
518
+ const themeTarget = path.join(targetDir, "src/theme/sonance-theme.css");
519
+ const import1 = `@import "${getRelativeImportPath(globalsFullPath, stylesTarget)}";`;
520
+ const import2 = `@import "${getRelativeImportPath(globalsFullPath, themeTarget)}";`;
521
+ // Prepend imports if not already present
522
+ const newImports = [];
523
+ if (!cssContent.includes("brand-overrides.css"))
524
+ newImports.push(import1);
525
+ if (!cssContent.includes("sonance-theme.css"))
526
+ newImports.push(import2);
527
+ if (newImports.length > 0) {
528
+ cssContent = newImports.join("\n") + "\n" + cssContent;
529
+ fs.writeFileSync(globalsFullPath, cssContent, "utf-8");
530
+ }
531
+ cssAutoConfigured = true;
532
+ }
533
+ catch (err) {
534
+ manualSteps.push(`Could not modify ${detectedGlobalsCss} - add CSS imports manually`);
535
+ }
536
+ }
537
+ else {
538
+ manualSteps.push("globals.css not found - add these imports to your main CSS file:\n @import \"[path-to]/src/styles/brand-overrides.css\";\n @import \"[path-to]/src/theme/sonance-theme.css\";\n (adjust the path based on your CSS file location)");
539
+ }
540
+ // --- Auto-inject into layout file ---
541
+ if (detectedLayout) {
542
+ const layoutFullPath = path.join(targetDir, detectedLayout);
543
+ try {
544
+ let layoutContent = fs.readFileSync(layoutFullPath, "utf-8");
545
+ let modified = false;
546
+ // Add import if not present
547
+ if (!layoutContent.includes("SonanceDevTools")) {
548
+ const importMatch = layoutContent.match(/^import .+$/gm);
549
+ if (importMatch && importMatch.length > 0) {
550
+ const lastImport = importMatch[importMatch.length - 1];
551
+ layoutContent = layoutContent.replace(lastImport, `${lastImport}\nimport { SonanceDevTools } from '@/components/dev-tools';`);
552
+ modified = true;
553
+ }
554
+ else {
555
+ // No imports found, add at the top
556
+ layoutContent = `import { SonanceDevTools } from '@/components/dev-tools';\n${layoutContent}`;
557
+ modified = true;
558
+ }
559
+ }
560
+ // Add component before </body> if not present
561
+ if (!layoutContent.includes("<SonanceDevTools")) {
562
+ if (layoutContent.includes("</body>")) {
563
+ layoutContent = layoutContent.replace(/<\/body>/, ` {process.env.NODE_ENV === 'development' && <SonanceDevTools />}\n </body>`);
564
+ modified = true;
565
+ }
566
+ else {
567
+ manualSteps.push("Could not find </body> tag - add DevTools component manually");
568
+ }
569
+ }
570
+ if (modified) {
571
+ fs.writeFileSync(layoutFullPath, layoutContent, "utf-8");
572
+ }
573
+ // Check if layout was fully configured
574
+ layoutAutoConfigured = layoutContent.includes("SonanceDevTools") && layoutContent.includes("<SonanceDevTools");
575
+ }
576
+ catch (err) {
577
+ manualSteps.push(`Could not modify ${detectedLayout} - add DevTools import and component manually`);
578
+ }
579
+ }
580
+ else {
581
+ manualSteps.push("layout.tsx not found - add to your layout:\n import { SonanceDevTools } from '@/components/dev-tools';\n {process.env.NODE_ENV === 'development' && <SonanceDevTools />}");
582
+ }
583
+ // --- Output results ---
466
584
  console.log("");
467
585
  console.log(" ✅ Sonance DevTools installed successfully!");
468
586
  console.log("");
469
- console.log(" ┌──────────────────────────────────────────────────────────────────┐");
470
- console.log(" │ Next steps: │");
471
- console.log(" │ │");
472
- console.log(" │ 1. Add to your globals.css: │");
473
- console.log(" │ @import \"../styles/brand-overrides.css\"; │");
474
- console.log(" │ @import \"../theme/sonance-theme.css\"; │");
475
- console.log(" │ │");
476
- console.log(" │ 2. Add to your layout.tsx: │");
477
- console.log(" │ import { SonanceDevTools } from '@/components/dev-tools'; │");
478
- console.log(" │ │");
479
- console.log(" │ 3. Add to your render function: │");
480
- console.log(" {process.env.NODE_ENV === 'development' && <SonanceDevTools />}│");
481
- console.log(" │ │");
482
- console.log(" │ 4. Apply CSS variables to your logo components: │");
483
- console.log(" │ style={{ transform: `scale(var(--sonance-logo-scale, 1))` }} │");
484
- console.log(" │ │");
485
- console.log(" └──────────────────────────────────────────────────────────────────┘");
587
+ if (cssAutoConfigured) {
588
+ console.log(` Auto-configured ${detectedGlobalsCss}`);
589
+ }
590
+ if (layoutAutoConfigured) {
591
+ console.log(` Auto-configured ${detectedLayout}`);
592
+ }
593
+ if (manualSteps.length > 0) {
594
+ console.log("");
595
+ console.log(" ⚠️ Some files need manual setup:");
596
+ console.log("");
597
+ manualSteps.forEach((step, i) => {
598
+ console.log(` ${i + 1}. ${step}`);
599
+ console.log("");
600
+ });
601
+ console.log(" ─────────────────────────────────────────────────────────────────────");
602
+ console.log(" After completing the steps above, run your dev server.");
603
+ console.log(" ─────────────────────────────────────────────────────────────────────");
604
+ }
605
+ else {
606
+ console.log("");
607
+ console.log(" 🚀 DONE! Run your dev server and look for the DevTools button.");
608
+ }
609
+ console.log("");
610
+ }
611
+ /**
612
+ * Run the uninstaller for DevTools Plugin (removes files and imports)
613
+ */
614
+ function runDevToolsUninstaller() {
615
+ console.log("");
616
+ console.log(" ┌─────────────────────────────────────────────────┐");
617
+ console.log(" │ │");
618
+ console.log(" │ 🧹 Sonance DevTools - Uninstaller │");
619
+ console.log(" │ │");
620
+ console.log(" └─────────────────────────────────────────────────┘");
621
+ console.log("");
622
+ const targetDir = process.cwd();
623
+ let removedItems = [];
624
+ let errors = [];
625
+ // Detect file paths (same logic as installer)
626
+ const globalsCssPaths = [
627
+ "src/app/globals.css",
628
+ "app/globals.css",
629
+ "src/styles/globals.css",
630
+ "styles/globals.css"
631
+ ];
632
+ const layoutPaths = [
633
+ "src/app/layout.tsx",
634
+ "app/layout.tsx",
635
+ "src/app/layout.jsx",
636
+ "app/layout.jsx"
637
+ ];
638
+ // --- 1. Remove CSS imports from globals.css ---
639
+ for (const cssPath of globalsCssPaths) {
640
+ const fullPath = path.join(targetDir, cssPath);
641
+ if (fs.existsSync(fullPath)) {
642
+ try {
643
+ let content = fs.readFileSync(fullPath, "utf-8");
644
+ const originalContent = content;
645
+ // Remove lines containing the imports
646
+ content = content.split('\n')
647
+ .filter(line => !line.includes('brand-overrides.css') && !line.includes('sonance-theme.css'))
648
+ .join('\n');
649
+ // Clean up extra blank lines at the top
650
+ content = content.replace(/^\n+/, '');
651
+ if (content !== originalContent) {
652
+ fs.writeFileSync(fullPath, content, "utf-8");
653
+ removedItems.push(`Removed CSS imports from ${cssPath}`);
654
+ }
655
+ }
656
+ catch (err) {
657
+ errors.push(`Could not modify ${cssPath}`);
658
+ }
659
+ break;
660
+ }
661
+ }
662
+ // --- 2. Remove from layout.tsx ---
663
+ for (const layoutPath of layoutPaths) {
664
+ const fullPath = path.join(targetDir, layoutPath);
665
+ if (fs.existsSync(fullPath)) {
666
+ try {
667
+ let content = fs.readFileSync(fullPath, "utf-8");
668
+ const originalContent = content;
669
+ // Remove import line
670
+ content = content.split('\n')
671
+ .filter(line => !line.includes("SonanceDevTools") || !line.includes("import"))
672
+ .join('\n');
673
+ // Remove component usage line
674
+ content = content.split('\n')
675
+ .filter(line => !line.includes("<SonanceDevTools"))
676
+ .join('\n');
677
+ if (content !== originalContent) {
678
+ fs.writeFileSync(fullPath, content, "utf-8");
679
+ removedItems.push(`Removed DevTools from ${layoutPath}`);
680
+ }
681
+ }
682
+ catch (err) {
683
+ errors.push(`Could not modify ${layoutPath}`);
684
+ }
685
+ break;
686
+ }
687
+ }
688
+ // --- 3. Delete installed directories/files ---
689
+ const itemsToDelete = [
690
+ "src/components/dev-tools",
691
+ "src/styles/brand-overrides.css",
692
+ "src/theme",
693
+ "src/app/api/sonance-theme",
694
+ "src/app/api/sonance-components",
695
+ "src/app/api/sonance-save-logo",
696
+ "src/app/api/sonance-assets",
697
+ "src/app/api/sonance-inject-id",
698
+ "src/app/api/sonance-analyze",
699
+ "src/lib/brand-system.ts"
700
+ ];
701
+ for (const item of itemsToDelete) {
702
+ const fullPath = path.join(targetDir, item);
703
+ if (fs.existsSync(fullPath)) {
704
+ try {
705
+ const stats = fs.statSync(fullPath);
706
+ if (stats.isDirectory()) {
707
+ fs.rmSync(fullPath, { recursive: true, force: true });
708
+ }
709
+ else {
710
+ fs.unlinkSync(fullPath);
711
+ }
712
+ removedItems.push(`Deleted ${item}`);
713
+ }
714
+ catch (err) {
715
+ errors.push(`Could not delete ${item}`);
716
+ }
717
+ }
718
+ }
719
+ // --- Output results ---
720
+ if (removedItems.length > 0) {
721
+ console.log(" ✅ Removed:");
722
+ removedItems.forEach(item => console.log(` ✓ ${item}`));
723
+ }
724
+ else {
725
+ console.log(" ℹ️ No DevTools installation found to remove.");
726
+ }
727
+ if (errors.length > 0) {
728
+ console.log("");
729
+ console.log(" ⚠️ Some items could not be removed:");
730
+ errors.forEach(err => console.log(` - ${err}`));
731
+ }
732
+ console.log("");
733
+ console.log(" 🧹 Uninstall complete!");
486
734
  console.log("");
487
735
  }
488
736
  // Check for install-devtools command
@@ -490,6 +738,11 @@ if (process.argv.includes("install-devtools") || process.argv.includes("--instal
490
738
  runDevToolsInstaller();
491
739
  process.exit(0);
492
740
  }
741
+ // Check for uninstall-devtools command
742
+ if (process.argv.includes("uninstall-devtools") || process.argv.includes("--uninstall-devtools")) {
743
+ runDevToolsUninstaller();
744
+ process.exit(0);
745
+ }
493
746
  // Resolve paths based on environment
494
747
  function getAssetPath(assetType) {
495
748
  if (IS_BUNDLED) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sonance-brand-mcp",
3
- "version": "1.3.2",
3
+ "version": "1.3.4",
4
4
  "description": "MCP Server for Sonance Brand Guidelines and Component Library - gives Claude instant access to brand colors, typography, and UI components.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",