sonance-brand-mcp 1.3.5 → 1.3.7
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,72 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createContext,
|
|
5
|
+
useContext,
|
|
6
|
+
useState,
|
|
7
|
+
useEffect,
|
|
8
|
+
useCallback,
|
|
9
|
+
type ReactNode,
|
|
10
|
+
} from "react";
|
|
11
|
+
import { BrandId, brandPresets, applyThemeToDOM } from "./brand-system";
|
|
12
|
+
|
|
13
|
+
// ============================================
|
|
14
|
+
// BRAND CONTEXT
|
|
15
|
+
// Global state for the currently selected brand
|
|
16
|
+
// ============================================
|
|
17
|
+
|
|
18
|
+
const STORAGE_KEY = "sonance-devtools-brand";
|
|
19
|
+
|
|
20
|
+
interface BrandContextValue {
|
|
21
|
+
currentBrand: BrandId;
|
|
22
|
+
setBrand: (brand: BrandId) => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const BrandContext = createContext<BrandContextValue | null>(null);
|
|
26
|
+
|
|
27
|
+
export function BrandProvider({ children }: { children: ReactNode }) {
|
|
28
|
+
const [currentBrand, setCurrentBrand] = useState<BrandId>("sonance");
|
|
29
|
+
const [mounted, setMounted] = useState(false);
|
|
30
|
+
|
|
31
|
+
// Load persisted brand from localStorage on mount
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
setMounted(true);
|
|
34
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
35
|
+
if (stored && (stored === "sonance" || stored === "iport" || stored === "blaze")) {
|
|
36
|
+
setCurrentBrand(stored as BrandId);
|
|
37
|
+
// Apply the theme when restoring from localStorage
|
|
38
|
+
const preset = brandPresets.find((p) => p.id === stored);
|
|
39
|
+
if (preset) {
|
|
40
|
+
applyThemeToDOM(preset.config);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}, []);
|
|
44
|
+
|
|
45
|
+
const setBrand = useCallback((brand: BrandId) => {
|
|
46
|
+
setCurrentBrand(brand);
|
|
47
|
+
localStorage.setItem(STORAGE_KEY, brand);
|
|
48
|
+
}, []);
|
|
49
|
+
|
|
50
|
+
// Don't render children until mounted to prevent hydration mismatch
|
|
51
|
+
if (!mounted) {
|
|
52
|
+
return <>{children}</>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<BrandContext.Provider value={{ currentBrand, setBrand }}>
|
|
57
|
+
{children}
|
|
58
|
+
</BrandContext.Provider>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function useBrand(): BrandContextValue {
|
|
63
|
+
const context = useContext(BrandContext);
|
|
64
|
+
if (!context) {
|
|
65
|
+
// Return default values if not within provider (for SSR/initial render)
|
|
66
|
+
return {
|
|
67
|
+
currentBrand: "sonance",
|
|
68
|
+
setBrand: () => {},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return context;
|
|
72
|
+
}
|
|
@@ -4,7 +4,7 @@ import { useState, useEffect, useCallback, useRef } from "react";
|
|
|
4
4
|
import { createPortal } from "react-dom";
|
|
5
5
|
import { Palette, X, Copy, Check, RotateCcw, ChevronDown, Save, Loader2, AlertCircle, CheckCircle, Sun, Moon, Eye, EyeOff, Zap, Image as ImageIcon, Wand2, Scan, FileCode, Tag, Type, MousePointer, FormInput, Box } from "lucide-react";
|
|
6
6
|
import { useTheme } from "next-themes";
|
|
7
|
-
import { cn } from "
|
|
7
|
+
import { cn } from "../../lib/utils";
|
|
8
8
|
import {
|
|
9
9
|
ThemeConfig,
|
|
10
10
|
BrandId,
|
|
@@ -17,8 +17,8 @@ import {
|
|
|
17
17
|
generateThemeCSS,
|
|
18
18
|
componentSnippets,
|
|
19
19
|
isLightColor,
|
|
20
|
-
} from "
|
|
21
|
-
import { useBrand } from "
|
|
20
|
+
} from "../../lib/brand-system";
|
|
21
|
+
import { useBrand } from "../../lib/brand-context";
|
|
22
22
|
|
|
23
23
|
// ============================================
|
|
24
24
|
// SONANCE DEVTOOLS
|
package/dist/index.js
CHANGED
|
@@ -313,6 +313,7 @@ function runDevToolsInstaller() {
|
|
|
313
313
|
const themeDir = path.join(targetDir, "src/theme");
|
|
314
314
|
// Source resolution
|
|
315
315
|
let sourceBrandSystem;
|
|
316
|
+
let sourceBrandContext;
|
|
316
317
|
let sourceDevTools;
|
|
317
318
|
let sourceBrandOverridesCss;
|
|
318
319
|
let sourceApiTheme;
|
|
@@ -323,6 +324,7 @@ function runDevToolsInstaller() {
|
|
|
323
324
|
let sourceApiAnalyze;
|
|
324
325
|
if (IS_BUNDLED) {
|
|
325
326
|
sourceBrandSystem = path.join(BUNDLED_ASSETS, "brand-system.ts");
|
|
327
|
+
sourceBrandContext = path.join(BUNDLED_ASSETS, "brand-context.tsx");
|
|
326
328
|
sourceDevTools = path.join(BUNDLED_ASSETS, "dev-tools");
|
|
327
329
|
sourceBrandOverridesCss = path.join(BUNDLED_ASSETS, "styles/brand-overrides.css");
|
|
328
330
|
sourceApiTheme = path.join(BUNDLED_ASSETS, "api/sonance-theme/route.ts");
|
|
@@ -334,6 +336,7 @@ function runDevToolsInstaller() {
|
|
|
334
336
|
}
|
|
335
337
|
else {
|
|
336
338
|
sourceBrandSystem = path.join(DEV_PROJECT_ROOT, "src/lib/brand-system.ts");
|
|
339
|
+
sourceBrandContext = path.join(DEV_PROJECT_ROOT, "src/lib/brand-context.tsx");
|
|
337
340
|
sourceDevTools = path.join(DEV_PROJECT_ROOT, "src/components/dev-tools");
|
|
338
341
|
sourceBrandOverridesCss = path.join(DEV_PROJECT_ROOT, "src/styles/brand-overrides.css");
|
|
339
342
|
sourceApiTheme = path.join(DEV_PROJECT_ROOT, "src/app/api/sonance-theme/route.ts");
|
|
@@ -349,6 +352,11 @@ function runDevToolsInstaller() {
|
|
|
349
352
|
console.error(` Path: ${sourceBrandSystem}`);
|
|
350
353
|
process.exit(1);
|
|
351
354
|
}
|
|
355
|
+
if (!fs.existsSync(sourceBrandContext)) {
|
|
356
|
+
console.error(" ❌ Error: Could not find brand-context.tsx source file.");
|
|
357
|
+
console.error(` Path: ${sourceBrandContext}`);
|
|
358
|
+
process.exit(1);
|
|
359
|
+
}
|
|
352
360
|
if (!fs.existsSync(sourceDevTools)) {
|
|
353
361
|
console.error(" ❌ Error: Could not find dev-tools source directory.");
|
|
354
362
|
console.error(` Path: ${sourceDevTools}`);
|
|
@@ -390,12 +398,14 @@ function runDevToolsInstaller() {
|
|
|
390
398
|
process.exit(1);
|
|
391
399
|
}
|
|
392
400
|
console.log(" 📂 Installing files...");
|
|
393
|
-
// 1. Install brand-system.ts
|
|
401
|
+
// 1. Install brand-system.ts and brand-context.tsx
|
|
394
402
|
if (!fs.existsSync(libDir)) {
|
|
395
403
|
fs.mkdirSync(libDir, { recursive: true });
|
|
396
404
|
}
|
|
397
405
|
fs.copyFileSync(sourceBrandSystem, path.join(libDir, "brand-system.ts"));
|
|
398
406
|
console.log(" ✓ Created src/lib/brand-system.ts");
|
|
407
|
+
fs.copyFileSync(sourceBrandContext, path.join(libDir, "brand-context.tsx"));
|
|
408
|
+
console.log(" ✓ Created src/lib/brand-context.tsx");
|
|
399
409
|
// 2. Install DevTools components
|
|
400
410
|
if (!fs.existsSync(devToolsDir)) {
|
|
401
411
|
fs.mkdirSync(devToolsDir, { recursive: true });
|
|
@@ -543,17 +553,23 @@ function runDevToolsInstaller() {
|
|
|
543
553
|
try {
|
|
544
554
|
let layoutContent = fs.readFileSync(layoutFullPath, "utf-8");
|
|
545
555
|
let modified = false;
|
|
556
|
+
// Calculate relative import path from layout to dev-tools
|
|
557
|
+
const devToolsTarget = path.join(targetDir, "src/components/dev-tools");
|
|
558
|
+
let devToolsImportPath = getRelativeImportPath(layoutFullPath, devToolsTarget);
|
|
559
|
+
// Remove trailing slash for JS/TS imports
|
|
560
|
+
devToolsImportPath = devToolsImportPath.replace(/\/$/, '');
|
|
561
|
+
const importLine = `import { SonanceDevTools } from '${devToolsImportPath}';`;
|
|
546
562
|
// Add import if not present
|
|
547
563
|
if (!layoutContent.includes("SonanceDevTools")) {
|
|
548
564
|
const importMatch = layoutContent.match(/^import .+$/gm);
|
|
549
565
|
if (importMatch && importMatch.length > 0) {
|
|
550
566
|
const lastImport = importMatch[importMatch.length - 1];
|
|
551
|
-
layoutContent = layoutContent.replace(lastImport, `${lastImport}\
|
|
567
|
+
layoutContent = layoutContent.replace(lastImport, `${lastImport}\n${importLine}`);
|
|
552
568
|
modified = true;
|
|
553
569
|
}
|
|
554
570
|
else {
|
|
555
571
|
// No imports found, add at the top
|
|
556
|
-
layoutContent =
|
|
572
|
+
layoutContent = `${importLine}\n${layoutContent}`;
|
|
557
573
|
modified = true;
|
|
558
574
|
}
|
|
559
575
|
}
|
|
@@ -578,7 +594,7 @@ function runDevToolsInstaller() {
|
|
|
578
594
|
}
|
|
579
595
|
}
|
|
580
596
|
else {
|
|
581
|
-
manualSteps.push("layout.tsx not found - add to your layout:\n import { SonanceDevTools } from '
|
|
597
|
+
manualSteps.push("layout.tsx not found - add to your layout:\n import { SonanceDevTools } from '[path-to]/src/components/dev-tools';\n {process.env.NODE_ENV === 'development' && <SonanceDevTools />}\n (adjust the path based on your layout file location)");
|
|
582
598
|
}
|
|
583
599
|
// --- Output results ---
|
|
584
600
|
console.log("");
|
|
@@ -696,7 +712,8 @@ function runDevToolsUninstaller() {
|
|
|
696
712
|
"src/app/api/sonance-assets",
|
|
697
713
|
"src/app/api/sonance-inject-id",
|
|
698
714
|
"src/app/api/sonance-analyze",
|
|
699
|
-
"src/lib/brand-system.ts"
|
|
715
|
+
"src/lib/brand-system.ts",
|
|
716
|
+
"src/lib/brand-context.tsx"
|
|
700
717
|
];
|
|
701
718
|
for (const item of itemsToDelete) {
|
|
702
719
|
const fullPath = path.join(targetDir, item);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sonance-brand-mcp",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.7",
|
|
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",
|