sonance-brand-mcp 1.3.28 → 1.3.30
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.
|
@@ -260,6 +260,35 @@ export function SonanceDevTools() {
|
|
|
260
260
|
}
|
|
261
261
|
}, [mounted, DEVTOOLS_POSITION_KEY]);
|
|
262
262
|
|
|
263
|
+
// Restore apply-first session from localStorage on mount
|
|
264
|
+
// This allows the Accept/Revert UI to survive page refreshes
|
|
265
|
+
useEffect(() => {
|
|
266
|
+
if (!mounted) return;
|
|
267
|
+
try {
|
|
268
|
+
const savedSession = localStorage.getItem("sonance-apply-first-session");
|
|
269
|
+
if (savedSession) {
|
|
270
|
+
const session = JSON.parse(savedSession);
|
|
271
|
+
// Check if session is recent (< 1 hour old)
|
|
272
|
+
const MAX_SESSION_AGE = 60 * 60 * 1000; // 1 hour
|
|
273
|
+
if (session.timestamp && Date.now() - session.timestamp < MAX_SESSION_AGE) {
|
|
274
|
+
console.log("[Apply-First] Restoring session from localStorage:", session.sessionId);
|
|
275
|
+
setApplyFirstSession(session);
|
|
276
|
+
setApplyFirstStatus("reviewing");
|
|
277
|
+
// Auto-open the DevTools panel so user sees the Accept/Revert UI
|
|
278
|
+
setIsOpen(true);
|
|
279
|
+
setActiveTab("components");
|
|
280
|
+
} else {
|
|
281
|
+
// Session expired, clear it
|
|
282
|
+
console.log("[Apply-First] Session expired, clearing localStorage");
|
|
283
|
+
localStorage.removeItem("sonance-apply-first-session");
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
} catch (e) {
|
|
287
|
+
console.warn("[Apply-First] Failed to restore session:", e);
|
|
288
|
+
localStorage.removeItem("sonance-apply-first-session");
|
|
289
|
+
}
|
|
290
|
+
}, [mounted]);
|
|
291
|
+
|
|
263
292
|
// Drag handlers for movable panel
|
|
264
293
|
const headerRef = useRef<HTMLDivElement>(null);
|
|
265
294
|
|
|
@@ -1097,6 +1126,17 @@ export function SonanceDevTools() {
|
|
|
1097
1126
|
setApplyFirstStatus("waiting-hmr");
|
|
1098
1127
|
setVisionModeActive(false);
|
|
1099
1128
|
|
|
1129
|
+
// Persist session to localStorage so it survives page refreshes
|
|
1130
|
+
try {
|
|
1131
|
+
localStorage.setItem("sonance-apply-first-session", JSON.stringify({
|
|
1132
|
+
...session,
|
|
1133
|
+
timestamp: Date.now(),
|
|
1134
|
+
}));
|
|
1135
|
+
console.log("[Apply-First] Session persisted to localStorage");
|
|
1136
|
+
} catch (e) {
|
|
1137
|
+
console.warn("[Apply-First] Failed to persist session:", e);
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1100
1140
|
// After a brief delay, assume HMR has completed
|
|
1101
1141
|
setTimeout(() => {
|
|
1102
1142
|
setApplyFirstStatus("reviewing");
|
|
@@ -1128,6 +1168,13 @@ export function SonanceDevTools() {
|
|
|
1128
1168
|
setApplyFirstStatus("idle");
|
|
1129
1169
|
setVisionFocusedElements([]);
|
|
1130
1170
|
setChangedElements([]); // Clear highlights
|
|
1171
|
+
// Clear persisted session from localStorage
|
|
1172
|
+
try {
|
|
1173
|
+
localStorage.removeItem("sonance-apply-first-session");
|
|
1174
|
+
console.log("[Apply-First] Session cleared from localStorage");
|
|
1175
|
+
} catch (e) {
|
|
1176
|
+
console.warn("[Apply-First] Failed to clear session:", e);
|
|
1177
|
+
}
|
|
1131
1178
|
} else {
|
|
1132
1179
|
console.error("[Apply-First] Accept failed:", result.error);
|
|
1133
1180
|
setApplyFirstStatus("error");
|
|
@@ -1164,6 +1211,13 @@ export function SonanceDevTools() {
|
|
|
1164
1211
|
setVisionFocusedElements([]);
|
|
1165
1212
|
setChangedElements([]); // Clear highlights
|
|
1166
1213
|
// HMR will automatically refresh with restored files
|
|
1214
|
+
// Clear persisted session from localStorage
|
|
1215
|
+
try {
|
|
1216
|
+
localStorage.removeItem("sonance-apply-first-session");
|
|
1217
|
+
console.log("[Apply-First] Session cleared from localStorage");
|
|
1218
|
+
} catch (e) {
|
|
1219
|
+
console.warn("[Apply-First] Failed to clear session:", e);
|
|
1220
|
+
}
|
|
1167
1221
|
} else {
|
|
1168
1222
|
console.error("[Apply-First] Revert failed:", result.error);
|
|
1169
1223
|
setApplyFirstStatus("error");
|
package/dist/index.js
CHANGED
|
@@ -1099,12 +1099,16 @@ function runDevToolsSync(fullSync = false) {
|
|
|
1099
1099
|
let sourceBrandContext;
|
|
1100
1100
|
let sourceApiAnalyze;
|
|
1101
1101
|
let sourceApiSaveColors;
|
|
1102
|
+
let sourceApiVisionApply;
|
|
1103
|
+
let sourceApiVisionEdit;
|
|
1102
1104
|
if (IS_BUNDLED) {
|
|
1103
1105
|
sourceDevTools = path.join(BUNDLED_ASSETS, "dev-tools");
|
|
1104
1106
|
sourceBrandSystem = path.join(BUNDLED_ASSETS, "brand-system.ts");
|
|
1105
1107
|
sourceBrandContext = path.join(BUNDLED_ASSETS, "brand-context.tsx");
|
|
1106
1108
|
sourceApiAnalyze = path.join(BUNDLED_ASSETS, "api/sonance-analyze/route.ts");
|
|
1107
1109
|
sourceApiSaveColors = path.join(BUNDLED_ASSETS, "api/sonance-save-colors/route.ts");
|
|
1110
|
+
sourceApiVisionApply = path.join(BUNDLED_ASSETS, "api/sonance-vision-apply/route.ts");
|
|
1111
|
+
sourceApiVisionEdit = path.join(BUNDLED_ASSETS, "api/sonance-vision-edit/route.ts");
|
|
1108
1112
|
}
|
|
1109
1113
|
else {
|
|
1110
1114
|
sourceDevTools = path.join(DEV_PROJECT_ROOT, "src/components/dev-tools");
|
|
@@ -1112,6 +1116,8 @@ function runDevToolsSync(fullSync = false) {
|
|
|
1112
1116
|
sourceBrandContext = path.join(DEV_PROJECT_ROOT, "src/lib/brand-context.tsx");
|
|
1113
1117
|
sourceApiAnalyze = path.join(DEV_PROJECT_ROOT, "src/app/api/sonance-analyze/route.ts");
|
|
1114
1118
|
sourceApiSaveColors = path.join(DEV_PROJECT_ROOT, "src/app/api/sonance-save-colors/route.ts");
|
|
1119
|
+
sourceApiVisionApply = path.join(DEV_PROJECT_ROOT, "src/app/api/sonance-vision-apply/route.ts");
|
|
1120
|
+
sourceApiVisionEdit = path.join(DEV_PROJECT_ROOT, "src/app/api/sonance-vision-edit/route.ts");
|
|
1115
1121
|
}
|
|
1116
1122
|
// Core files to sync (always synced)
|
|
1117
1123
|
const coreFiles = [
|
|
@@ -1164,7 +1170,33 @@ function runDevToolsSync(fullSync = false) {
|
|
|
1164
1170
|
}
|
|
1165
1171
|
}
|
|
1166
1172
|
}
|
|
1167
|
-
//
|
|
1173
|
+
// Always sync Vision API routes (critical for Vision Mode)
|
|
1174
|
+
const visionApiFiles = [
|
|
1175
|
+
{ src: sourceApiVisionApply, dest: path.join(targetDir, baseDir, "app/api/sonance-vision-apply/route.ts"), name: "sonance-vision-apply" },
|
|
1176
|
+
{ src: sourceApiVisionEdit, dest: path.join(targetDir, baseDir, "app/api/sonance-vision-edit/route.ts"), name: "sonance-vision-edit" },
|
|
1177
|
+
];
|
|
1178
|
+
for (const file of visionApiFiles) {
|
|
1179
|
+
if (fs.existsSync(file.src)) {
|
|
1180
|
+
try {
|
|
1181
|
+
// Ensure directory exists
|
|
1182
|
+
const destDir = path.dirname(file.dest);
|
|
1183
|
+
if (!fs.existsSync(destDir)) {
|
|
1184
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
1185
|
+
}
|
|
1186
|
+
fs.copyFileSync(file.src, file.dest);
|
|
1187
|
+
console.log(` ✓ Synced api/${file.name}/route.ts`);
|
|
1188
|
+
syncedCount++;
|
|
1189
|
+
}
|
|
1190
|
+
catch (err) {
|
|
1191
|
+
console.log(` ✗ Failed: api/${file.name}/route.ts`);
|
|
1192
|
+
errorCount++;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
else {
|
|
1196
|
+
console.log(` ⚠️ Source not found: ${file.name} (run 'npm run build' in mcp-server)`);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
// Full sync includes additional API routes
|
|
1168
1200
|
if (fullSync) {
|
|
1169
1201
|
const apiFiles = [
|
|
1170
1202
|
{ src: sourceApiAnalyze, dest: path.join(targetDir, baseDir, "app/api/sonance-analyze/route.ts"), name: "sonance-analyze" },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sonance-brand-mcp",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.30",
|
|
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",
|