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.
- package/dist/index.js +270 -17
- 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
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
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.
|
|
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",
|