skema-core 0.1.2 → 2.1.0

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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { forwardRef, useState, useRef, useEffect, useCallback, useImperativeHandle, useMemo } from 'react';
2
- import { StateNode, atom, Box, ArrowShapeKindStyle, Tldraw, TldrawOverlays, useEditor, useTools, useIsToolSelected, useValue, GeoShapeGeoStyle } from 'tldraw';
2
+ import { DefaultColorThemePalette, StateNode, atom, Box, ArrowShapeKindStyle, Tldraw, TldrawOverlays, useEditor, useTools, useIsToolSelected, useValue, GeoShapeGeoStyle } from 'tldraw';
3
3
  import 'tldraw/tldraw.css';
4
4
  import { motion, AnimatePresence } from 'framer-motion';
5
5
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
@@ -181,11 +181,21 @@ function useDaemon(options = {}) {
181
181
  autoReconnect = true,
182
182
  reconnectDelay = 2e3
183
183
  } = options;
184
+ const defaultProviderStatus = {
185
+ gemini: { installed: false, authorized: false, message: "Checking..." },
186
+ claude: { installed: false, authorized: false, message: "Checking..." }
187
+ };
184
188
  const [state, setState] = useState({
185
189
  connected: false,
186
190
  provider: "gemini",
191
+ mode: "direct-cli",
187
192
  availableProviders: [],
188
- cwd: ""
193
+ availableModes: ["direct-cli", "mcp"],
194
+ providerStatus: defaultProviderStatus,
195
+ cwd: "",
196
+ mcpServerConnected: false,
197
+ mcpClientName: null,
198
+ annotationCounts: { pending: 0, acknowledged: 0, resolved: 0, dismissed: 0 }
189
199
  });
190
200
  const [isGenerating, setIsGenerating] = useState(false);
191
201
  const [error, setError] = useState(null);
@@ -223,12 +233,24 @@ function useDaemon(options = {}) {
223
233
  ...prev,
224
234
  connected: true,
225
235
  provider: msg.provider || prev.provider,
236
+ mode: msg.mode || prev.mode,
226
237
  availableProviders: msg.availableProviders || prev.availableProviders,
227
- cwd: msg.cwd || prev.cwd
238
+ availableModes: msg.availableModes || prev.availableModes,
239
+ providerStatus: msg.providerStatus || prev.providerStatus,
240
+ cwd: msg.cwd || prev.cwd,
241
+ mcpServerConnected: msg.mcpServerConnected ?? prev.mcpServerConnected,
242
+ mcpClientName: msg.mcpClientName !== void 0 ? msg.mcpClientName : prev.mcpClientName
228
243
  }));
229
244
  setError(null);
230
245
  return;
231
246
  }
247
+ if (msg.type === "provider-statuses") {
248
+ setState((prev) => ({
249
+ ...prev,
250
+ providerStatus: msg.providerStatus || prev.providerStatus
251
+ }));
252
+ return;
253
+ }
232
254
  if (msg.type === "ai-event" && msg.id) {
233
255
  const callback = eventCallbacks.current.get(msg.id);
234
256
  if (callback) {
@@ -246,9 +268,40 @@ function useDaemon(options = {}) {
246
268
  setIsGenerating(false);
247
269
  return;
248
270
  }
271
+ if (msg.type === "annotation-queued" && msg.id) {
272
+ const pending = pendingRequests.current.get(msg.id);
273
+ if (pending) {
274
+ pendingRequests.current.delete(msg.id);
275
+ eventCallbacks.current.delete(msg.id);
276
+ pending.resolve({ success: true, annotationId: msg.annotationId, queued: true });
277
+ }
278
+ setIsGenerating(false);
279
+ return;
280
+ }
281
+ if (msg.type === "annotation-status-changed") {
282
+ return;
283
+ }
284
+ if (msg.type === "mcp-server-status") {
285
+ setState((prev) => ({
286
+ ...prev,
287
+ mcpServerConnected: msg.connected,
288
+ mcpClientName: msg.clientName !== void 0 ? msg.clientName : prev.mcpClientName
289
+ }));
290
+ return;
291
+ }
292
+ if (msg.type === "mcp-annotation-counts") {
293
+ setState((prev) => ({
294
+ ...prev,
295
+ annotationCounts: msg.counts
296
+ }));
297
+ return;
298
+ }
249
299
  if (msg.type === "provider-changed") {
250
300
  setState((prev) => ({ ...prev, provider: msg.provider }));
251
301
  }
302
+ if (msg.type === "mode-changed") {
303
+ setState((prev) => ({ ...prev, mode: msg.mode }));
304
+ }
252
305
  if (msg.type === "error" && msg.id) {
253
306
  const pending = pendingRequests.current.get(msg.id);
254
307
  if (pending) {
@@ -323,7 +376,23 @@ function useDaemon(options = {}) {
323
376
  return false;
324
377
  }
325
378
  }, [sendRequest]);
326
- const generate = useCallback(async (annotation, onEvent) => {
379
+ const setMode = useCallback(async (mode) => {
380
+ try {
381
+ const response = await sendRequest("set-mode", { mode });
382
+ return response.type === "mode-changed";
383
+ } catch (e) {
384
+ console.error("[useDaemon] Failed to set mode:", e);
385
+ return false;
386
+ }
387
+ }, [sendRequest]);
388
+ const refreshProviderStatus = useCallback(async () => {
389
+ try {
390
+ await sendRequest("check-providers", {});
391
+ } catch (e) {
392
+ console.error("[useDaemon] Failed to refresh provider status:", e);
393
+ }
394
+ }, [sendRequest]);
395
+ const generate = useCallback(async (annotation, onEvent, options2) => {
327
396
  const id = nextId();
328
397
  if (onEvent) {
329
398
  eventCallbacks.current.set(id, onEvent);
@@ -339,7 +408,10 @@ function useDaemon(options = {}) {
339
408
  wsRef.current.send(JSON.stringify({
340
409
  id,
341
410
  type: "generate",
342
- annotation
411
+ annotation,
412
+ // Include optional overrides
413
+ ...options2?.mode && { mode: options2.mode },
414
+ ...options2?.provider && { provider: options2.provider }
343
415
  }));
344
416
  });
345
417
  }, [nextId]);
@@ -378,6 +450,8 @@ function useDaemon(options = {}) {
378
450
  connect,
379
451
  disconnect,
380
452
  setProvider,
453
+ setMode,
454
+ refreshProviderStatus,
381
455
  generate,
382
456
  revert,
383
457
  readFile,
@@ -1424,11 +1498,12 @@ var CollapseButton = ({ onClick }) => {
1424
1498
  }
1425
1499
  );
1426
1500
  };
1427
- var SkemaToolbar = ({ onExpandedChange, onStylePanelChange }) => {
1501
+ var SkemaToolbar = ({ isExpanded: controlledExpanded, onExpandedChange, onStylePanelChange, isDark = false }) => {
1428
1502
  const editor = useEditor();
1429
1503
  const tools = useTools();
1430
1504
  const shapesButtonRef = useRef(null);
1431
- const [isExpanded, setIsExpanded] = useState(false);
1505
+ const [internalExpanded, setInternalExpanded] = useState(false);
1506
+ const isExpanded = controlledExpanded !== void 0 ? controlledExpanded : internalExpanded;
1432
1507
  const [isLogoHovered, setIsLogoHovered] = useState(false);
1433
1508
  const [isShapePickerOpen, setIsShapePickerOpen] = useState(false);
1434
1509
  const [isStylePanelOpen, setIsStylePanelOpen] = useState(false);
@@ -1438,7 +1513,7 @@ var SkemaToolbar = ({ onExpandedChange, onStylePanelChange }) => {
1438
1513
  const isEraseSelected = useIsToolSelected(tools["eraser"]);
1439
1514
  const isGeoSelected = useIsToolSelected(tools["geo"]);
1440
1515
  const handleExpand = (expanded) => {
1441
- setIsExpanded(expanded);
1516
+ setInternalExpanded(expanded);
1442
1517
  onExpandedChange?.(expanded);
1443
1518
  if (!expanded) {
1444
1519
  setIsStylePanelOpen(false);
@@ -1483,9 +1558,9 @@ var SkemaToolbar = ({ onExpandedChange, onStylePanelChange }) => {
1483
1558
  alignItems: "center",
1484
1559
  gap: 6,
1485
1560
  padding: "6px 12px",
1486
- backgroundColor: "white",
1561
+ backgroundColor: isDark ? "#1a1a1a" : "white",
1487
1562
  borderRadius: 28,
1488
- boxShadow: "0 2px 10px rgba(0,0,0,0.15)",
1563
+ boxShadow: isDark ? "0 2px 10px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.08)" : "0 2px 10px rgba(0,0,0,0.15)",
1489
1564
  pointerEvents: "auto"
1490
1565
  },
1491
1566
  children: [
@@ -1801,7 +1876,7 @@ var AnnotationsSidebar = ({
1801
1876
  ]
1802
1877
  }
1803
1878
  ),
1804
- /* @__PURE__ */ jsx("div", { style: { overflowY: "auto", maxHeight: "calc(100vh - 200px)" }, children: annotations.length === 0 ? /* @__PURE__ */ jsx("div", { style: { padding: "16px", color: "#6b7280", fontSize: "13px" }, children: "No annotations yet. Use the DOM picker or drawing tools to annotate." }) : annotations.map((annotation) => /* @__PURE__ */ jsxs(
1879
+ /* @__PURE__ */ jsx("div", { style: { overflowY: "auto", maxHeight: "calc(100vh - 200px)" }, children: annotations.length === 0 ? /* @__PURE__ */ jsx("div", { style: { padding: "16px", color: "#6b7280", fontSize: "13px" }, children: "No annotations yet. Double-click to select an element, or use draw/lasso to annotate." }) : annotations.map((annotation) => /* @__PURE__ */ jsxs(
1805
1880
  "div",
1806
1881
  {
1807
1882
  style: {
@@ -2097,15 +2172,31 @@ var ProcessingOverlay = ({ boundingBox, scrollOffset }) => {
2097
2172
  )
2098
2173
  ] });
2099
2174
  };
2175
+ var AccentShape = ({ color, isMultiSelect }) => {
2176
+ const isDrawing = color === "#8B5CF6";
2177
+ if (isMultiSelect && !isDrawing) {
2178
+ return /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx("rect", { x: "1", y: "1", width: "8", height: "8", rx: "1.5", fill: color }) });
2179
+ }
2180
+ if (isDrawing) {
2181
+ return /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx(
2182
+ "path",
2183
+ {
2184
+ d: "M6 1L7.4 4.2L10.8 4.6L8.2 7L8.9 10.4L6 8.7L3.1 10.4L3.8 7L1.2 4.6L4.6 4.2L6 1Z",
2185
+ fill: color
2186
+ }
2187
+ ) });
2188
+ }
2189
+ return /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx("circle", { cx: "5", cy: "5", r: "4", fill: color }) });
2190
+ };
2100
2191
  var styles = {
2101
2192
  popup: {
2102
2193
  position: "fixed",
2103
2194
  transform: "translateX(-50%)",
2104
2195
  width: 280,
2105
- padding: "12px 16px 14px",
2106
- background: "#1a1a1a",
2196
+ padding: "14px 16px 14px",
2197
+ background: "#FFFFFF",
2107
2198
  borderRadius: 16,
2108
- boxShadow: "0 4px 24px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.08)",
2199
+ boxShadow: "0 4px 24px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.06)",
2109
2200
  cursor: "default",
2110
2201
  zIndex: 100001,
2111
2202
  fontFamily: '"Clash Display", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
@@ -2118,53 +2209,67 @@ var styles = {
2118
2209
  },
2119
2210
  popupExit: {
2120
2211
  opacity: 0,
2121
- transform: "translateX(-50%) scale(0.95) translateY(4px)"
2212
+ transform: "translateX(-50%) scale(0.96) translateY(4px)"
2122
2213
  },
2123
2214
  header: {
2124
2215
  display: "flex",
2125
2216
  alignItems: "center",
2126
- justifyContent: "space-between",
2127
- marginBottom: 9
2217
+ gap: 7,
2218
+ marginBottom: 10
2128
2219
  },
2129
2220
  element: {
2130
2221
  fontSize: 12,
2131
- fontWeight: 400,
2132
- color: "rgba(255, 255, 255, 0.5)",
2222
+ fontWeight: 500,
2223
+ color: "#9CA3AF",
2133
2224
  maxWidth: "100%",
2134
2225
  overflow: "hidden",
2135
2226
  textOverflow: "ellipsis",
2136
2227
  whiteSpace: "nowrap",
2137
- flex: 1
2228
+ flex: 1,
2229
+ letterSpacing: "0.01em"
2138
2230
  },
2139
2231
  quote: {
2140
2232
  fontSize: 12,
2141
2233
  fontStyle: "italic",
2142
- color: "rgba(255, 255, 255, 0.6)",
2234
+ color: "#6B7280",
2143
2235
  marginBottom: 8,
2144
- padding: "6px 8px",
2145
- background: "rgba(255, 255, 255, 0.05)",
2146
- borderRadius: 4,
2147
- lineHeight: 1.45
2236
+ padding: "6px 9px",
2237
+ background: "#F9FAFB",
2238
+ borderRadius: 6,
2239
+ lineHeight: 1.45,
2240
+ borderLeft: "2px solid"
2148
2241
  },
2149
2242
  textarea: {
2150
2243
  width: "100%",
2151
- padding: "8px 10px",
2244
+ padding: "9px 11px",
2152
2245
  fontSize: 13,
2153
2246
  fontFamily: "inherit",
2154
- background: "rgba(255, 255, 255, 0.05)",
2155
- color: "#fff",
2156
- border: "1px solid rgba(255, 255, 255, 0.15)",
2157
- borderRadius: 8,
2247
+ background: "#F9FAFB",
2248
+ color: "#1a1a1a",
2249
+ border: "1px solid #E5E7EB",
2250
+ borderRadius: 10,
2158
2251
  resize: "none",
2159
2252
  outline: "none",
2160
- transition: "border-color 0.15s ease",
2161
- boxSizing: "border-box"
2253
+ transition: "border-color 0.15s ease, box-shadow 0.15s ease",
2254
+ boxSizing: "border-box",
2255
+ lineHeight: 1.5
2162
2256
  },
2163
2257
  actions: {
2164
2258
  display: "flex",
2165
- justifyContent: "flex-end",
2166
- gap: 6,
2167
- marginTop: 8
2259
+ alignItems: "center",
2260
+ justifyContent: "space-between",
2261
+ marginTop: 10
2262
+ },
2263
+ hint: {
2264
+ fontSize: 11,
2265
+ color: "#C0C5CE",
2266
+ fontWeight: 400,
2267
+ letterSpacing: "0.01em",
2268
+ userSelect: "none"
2269
+ },
2270
+ buttonGroup: {
2271
+ display: "flex",
2272
+ gap: 6
2168
2273
  },
2169
2274
  button: {
2170
2275
  padding: "6px 14px",
@@ -2173,11 +2278,11 @@ var styles = {
2173
2278
  borderRadius: 16,
2174
2279
  border: "none",
2175
2280
  cursor: "pointer",
2176
- transition: "background-color 0.15s ease, color 0.15s ease, opacity 0.15s ease"
2281
+ transition: "background-color 0.15s ease, color 0.15s ease, opacity 0.15s ease, transform 0.1s ease"
2177
2282
  },
2178
2283
  cancelButton: {
2179
2284
  background: "transparent",
2180
- color: "rgba(255, 255, 255, 0.5)"
2285
+ color: "#9CA3AF"
2181
2286
  },
2182
2287
  submitButton: {
2183
2288
  color: "white"
@@ -2187,7 +2292,7 @@ var AnnotationPopup = forwardRef(
2187
2292
  function AnnotationPopup2({
2188
2293
  element,
2189
2294
  selectedText,
2190
- placeholder = "What should change?",
2295
+ placeholder = "Write your changes?",
2191
2296
  initialValue = "",
2192
2297
  submitLabel = "Add",
2193
2298
  onSubmit,
@@ -2195,7 +2300,8 @@ var AnnotationPopup = forwardRef(
2195
2300
  style,
2196
2301
  accentColor = "#3c82f7",
2197
2302
  isExiting = false,
2198
- isMultiSelect = false
2303
+ isMultiSelect = false,
2304
+ isDark = false
2199
2305
  }, ref) {
2200
2306
  const [text, setText] = useState(initialValue);
2201
2307
  const [isShaking, setIsShaking] = useState(false);
@@ -2261,8 +2367,24 @@ var AnnotationPopup = forwardRef(
2261
2367
  },
2262
2368
  [handleSubmit, handleCancel]
2263
2369
  );
2370
+ const popupBg = isDark ? "#1a1a1a" : "#FFFFFF";
2371
+ const popupBorder = isDark ? "rgba(255,255,255,0.08)" : "rgba(0, 0, 0, 0.06)";
2372
+ const elementColor = isDark ? "#9CA3AF" : "#9CA3AF";
2373
+ const quoteBg = isDark ? "#2a2a2a" : "#F9FAFB";
2374
+ const quoteColor = isDark ? "#a1a1aa" : "#6B7280";
2375
+ const textareaBg = isDark ? "#2a2a2a" : "#F9FAFB";
2376
+ const textareaColor = isDark ? "#f0f0f0" : "#1a1a1a";
2377
+ const textareaBorder = isDark ? "#444444" : "#E5E7EB";
2378
+ const hintColor = isDark ? "#666666" : "#C0C5CE";
2379
+ const kbdBg = isDark ? "#333333" : "#F3F4F6";
2380
+ const kbdBorder = isDark ? "#555555" : "#E5E7EB";
2381
+ const cancelColor = isDark ? "#888888" : "#9CA3AF";
2382
+ const cancelHoverBg = isDark ? "#333333" : "#F3F4F6";
2383
+ const cancelHoverColor = isDark ? "#cccccc" : "#6B7280";
2264
2384
  const popupStyle = {
2265
2385
  ...styles.popup,
2386
+ background: popupBg,
2387
+ boxShadow: isDark ? `0 4px 24px rgba(0, 0, 0, 0.4), 0 0 0 1px ${popupBorder}` : `0 4px 24px rgba(0, 0, 0, 0.12), 0 0 0 1px ${popupBorder}`,
2266
2388
  ...animState === "enter" || animState === "entered" ? styles.popupEnter : {},
2267
2389
  ...animState === "exit" ? styles.popupExit : {},
2268
2390
  ...isShaking ? {
@@ -2270,11 +2392,17 @@ var AnnotationPopup = forwardRef(
2270
2392
  } : {},
2271
2393
  ...style
2272
2394
  };
2395
+ const effectiveAccentColor = isMultiSelect ? "#34C759" : accentColor;
2273
2396
  const textareaStyle = {
2274
2397
  ...styles.textarea,
2275
- ...isFocused ? { borderColor: accentColor } : {}
2398
+ background: textareaBg,
2399
+ color: textareaColor,
2400
+ border: `1px solid ${textareaBorder}`,
2401
+ ...isFocused ? {
2402
+ borderColor: effectiveAccentColor,
2403
+ boxShadow: `0 0 0 2px ${effectiveAccentColor}18`
2404
+ } : {}
2276
2405
  };
2277
- const effectiveAccentColor = isMultiSelect ? "#34C759" : accentColor;
2278
2406
  return /* @__PURE__ */ jsxs(Fragment, { children: [
2279
2407
  /* @__PURE__ */ jsx("style", { children: `
2280
2408
  @keyframes skema-shake {
@@ -2294,8 +2422,11 @@ var AnnotationPopup = forwardRef(
2294
2422
  onClick: (e) => e.stopPropagation(),
2295
2423
  onPointerDown: (e) => e.stopPropagation(),
2296
2424
  children: [
2297
- /* @__PURE__ */ jsx("div", { style: styles.header, children: /* @__PURE__ */ jsx("span", { style: styles.element, children: element }) }),
2298
- selectedText && /* @__PURE__ */ jsxs("div", { style: styles.quote, children: [
2425
+ /* @__PURE__ */ jsxs("div", { style: styles.header, children: [
2426
+ /* @__PURE__ */ jsx(AccentShape, { color: effectiveAccentColor, isMultiSelect }),
2427
+ /* @__PURE__ */ jsx("span", { style: { ...styles.element, color: elementColor }, children: element })
2428
+ ] }),
2429
+ selectedText && /* @__PURE__ */ jsxs("div", { style: { ...styles.quote, borderLeftColor: effectiveAccentColor, background: quoteBg, color: quoteColor }, children: [
2299
2430
  "\u201C",
2300
2431
  selectedText.slice(0, 80),
2301
2432
  selectedText.length > 80 ? "..." : "",
@@ -2316,51 +2447,504 @@ var AnnotationPopup = forwardRef(
2316
2447
  }
2317
2448
  ),
2318
2449
  /* @__PURE__ */ jsxs("div", { style: styles.actions, children: [
2450
+ /* @__PURE__ */ jsxs("span", { style: { ...styles.hint, color: hintColor }, children: [
2451
+ /* @__PURE__ */ jsx("kbd", { style: {
2452
+ fontFamily: "inherit",
2453
+ fontSize: 10,
2454
+ padding: "1px 4px",
2455
+ background: kbdBg,
2456
+ borderRadius: 3,
2457
+ border: `1px solid ${kbdBorder}`
2458
+ }, children: "\u21B5" }),
2459
+ " to send"
2460
+ ] }),
2461
+ /* @__PURE__ */ jsxs("div", { style: styles.buttonGroup, children: [
2462
+ /* @__PURE__ */ jsx(
2463
+ "button",
2464
+ {
2465
+ style: { ...styles.button, ...styles.cancelButton, color: cancelColor },
2466
+ onClick: handleCancel,
2467
+ onMouseEnter: (e) => {
2468
+ e.currentTarget.style.background = cancelHoverBg;
2469
+ e.currentTarget.style.color = cancelHoverColor;
2470
+ },
2471
+ onMouseLeave: (e) => {
2472
+ e.currentTarget.style.background = "transparent";
2473
+ e.currentTarget.style.color = cancelColor;
2474
+ },
2475
+ children: "Cancel"
2476
+ }
2477
+ ),
2478
+ /* @__PURE__ */ jsx(
2479
+ "button",
2480
+ {
2481
+ style: {
2482
+ ...styles.button,
2483
+ ...styles.submitButton,
2484
+ backgroundColor: effectiveAccentColor,
2485
+ opacity: text.trim() ? 1 : 0.4
2486
+ },
2487
+ onClick: handleSubmit,
2488
+ disabled: !text.trim(),
2489
+ onMouseEnter: (e) => {
2490
+ if (text.trim()) {
2491
+ e.currentTarget.style.filter = "brightness(0.92)";
2492
+ e.currentTarget.style.transform = "scale(1.02)";
2493
+ }
2494
+ },
2495
+ onMouseLeave: (e) => {
2496
+ e.currentTarget.style.filter = "none";
2497
+ e.currentTarget.style.transform = "scale(1)";
2498
+ },
2499
+ children: submitLabel
2500
+ }
2501
+ )
2502
+ ] })
2503
+ ] })
2504
+ ]
2505
+ }
2506
+ )
2507
+ ] });
2508
+ }
2509
+ );
2510
+
2511
+ // src/assets/logo-dark.ts
2512
+ var svg = `<svg width="560" height="132" viewBox="430 210 560 132" fill="none" xmlns="http://www.w3.org/2000/svg">
2513
+ <path d="M932.899 341.531C914.746 341.531 903.291 329.319 903.291 308.457C903.291 288.867 914.218 278.691 931.489 275.892L971.319 269.787V262.409C971.319 241.547 964.974 234.169 948.232 234.169C932.018 234.169 924.087 241.801 924.087 260.373V261.391H905.23V260.373C905.23 231.625 921.796 210 949.642 210C977.487 210 990 231.879 990 262.154V338.986H972.552V307.439H971.319C966.737 328.81 952.814 341.531 932.899 341.531ZM922.325 306.676C922.325 316.853 927.083 321.687 938.01 321.687C957.925 321.687 971.319 311.001 971.319 286.069L936.952 291.666C927.083 293.447 922.325 296.754 922.325 306.676Z" fill="#1a1a1a"/>
2514
+ <path d="M754.267 338.986H735.233V212.544H752.68V250.706H753.738C756.029 229.59 765.546 210 787.399 210C807.314 210 818.065 227.554 820.532 251.723H821.589C823.881 230.098 833.75 210 855.956 210C878.691 210 890.146 232.388 890.146 262.918V338.986H871.289V270.295C871.289 245.363 864.415 234.678 847.496 234.678C828.815 234.678 822.118 248.416 822.118 276.401V338.986H803.261V270.295C803.261 245.363 796.564 234.678 779.645 234.678C760.787 234.678 754.267 248.416 754.267 276.401V338.986Z" fill="#1a1a1a"/>
2515
+ <path d="M675.684 341.531C646.957 341.531 628.1 318.125 628.1 275.892C628.1 236.459 646.781 210 675.331 210C702.472 210 720.977 231.625 720.977 270.041C720.977 274.62 720.801 278.182 720.272 281.998H645.9C646.605 306.422 654.888 319.397 675.155 319.397C693.484 319.397 701.062 310.747 701.062 295.737V293.701H720.096V295.991C720.096 322.959 701.767 341.531 675.684 341.531ZM674.979 231.625C655.593 231.625 647.133 244.091 646.076 266.734H703.001V266.225C703.001 242.819 693.66 231.625 674.979 231.625Z" fill="#1a1a1a"/>
2516
+ <path d="M548.771 338.986H529.737L529.737 212.544H548.771L548.771 262.663H573.796L600.056 212.544H622.262L589.305 273.348L622.085 338.986H599.703L573.796 287.341H548.771V338.986Z" fill="#1a1a1a"/>
2517
+ <path d="M475.117 341.531C446.919 341.531 430.881 325.503 430.881 296.245V295.482H449.915V297.517C449.915 314.054 456.788 319.397 475.117 319.397C492.212 319.397 497.323 314.309 497.323 303.114C497.323 292.684 493.093 289.376 480.58 286.832L456.612 282.253C440.046 279.2 430 269.023 430 247.907C430 225.773 443.923 210 470.887 210C497.675 210 513.889 225.519 513.889 255.54V256.303H495.032V254.776C495.032 239.766 489.745 231.879 470.358 231.879C454.321 231.879 448.681 236.968 448.681 248.925C448.681 258.847 452.206 262.409 465.424 264.953L485.691 269.023C506.487 272.84 516.004 283.016 516.004 303.878C516.004 327.538 499.79 341.531 475.117 341.531Z" fill="#1a1a1a"/>
2518
+ </svg>`;
2519
+ var logo_dark_default = "data:image/svg+xml," + encodeURIComponent(svg);
2520
+
2521
+ // src/assets/logo-light.ts
2522
+ var svg2 = `<svg width="560" height="132" viewBox="378 168 560 132" fill="none" xmlns="http://www.w3.org/2000/svg">
2523
+ <path d="M880.899 299.531C862.746 299.531 851.291 287.319 851.291 266.457C851.291 246.867 862.218 236.691 879.489 233.892L919.319 227.787V220.409C919.319 199.547 912.974 192.169 896.232 192.169C880.018 192.169 872.087 199.801 872.087 218.373V219.391H853.23V218.373C853.23 189.625 869.796 168 897.642 168C925.487 168 938 189.879 938 220.154V296.986H920.552V265.439H919.319C914.737 286.81 900.814 299.531 880.899 299.531ZM870.325 264.676C870.325 274.853 875.083 279.687 886.01 279.687C905.925 279.687 919.319 269.001 919.319 244.069L884.952 249.666C875.083 251.447 870.325 254.754 870.325 264.676Z" fill="#FFFCFC"/>
2524
+ <path d="M702.267 296.986H683.233V170.544H700.68V208.706H701.738C704.029 187.59 713.546 168 735.399 168C755.314 168 766.065 185.554 768.532 209.723H769.589C771.881 188.098 781.75 168 803.956 168C826.691 168 838.146 190.388 838.146 220.918V296.986H819.289V228.295C819.289 203.363 812.415 192.678 795.496 192.678C776.815 192.678 770.118 206.416 770.118 234.401V296.986H751.261V228.295C751.261 203.363 744.564 192.678 727.645 192.678C708.787 192.678 702.267 206.416 702.267 234.401V296.986Z" fill="#FFFCFC"/>
2525
+ <path d="M623.684 299.531C594.957 299.531 576.1 276.125 576.1 233.892C576.1 194.459 594.781 168 623.331 168C650.472 168 668.977 189.625 668.977 228.041C668.977 232.62 668.801 236.182 668.272 239.998H593.9C594.605 264.422 602.888 277.397 623.155 277.397C641.484 277.397 649.062 268.747 649.062 253.737V251.701H668.096V253.991C668.096 280.959 649.767 299.531 623.684 299.531ZM622.979 189.625C603.593 189.625 595.133 202.091 594.076 224.734H651.001V224.225C651.001 200.819 641.66 189.625 622.979 189.625Z" fill="#FFFCFC"/>
2526
+ <path d="M496.771 296.986H477.737L477.737 170.544H496.771L496.771 220.663H521.796L548.056 170.544H570.262L537.305 231.348L570.085 296.986H547.703L521.796 245.341H496.771V296.986Z" fill="#FFFCFC"/>
2527
+ <path d="M423.117 299.531C394.919 299.531 378.881 283.503 378.881 254.245V253.482H397.915V255.517C397.915 272.054 404.788 277.397 423.117 277.397C440.212 277.397 445.323 272.309 445.323 261.114C445.323 250.684 441.093 247.376 428.58 244.832L404.612 240.253C388.046 237.2 378 227.023 378 205.907C378 183.773 391.923 168 418.887 168C445.675 168 461.889 183.519 461.889 213.54V214.303H443.032V212.776C443.032 197.766 437.745 189.879 418.358 189.879C402.321 189.879 396.681 194.968 396.681 206.925C396.681 216.847 400.206 220.409 413.424 222.953L433.691 227.023C454.487 230.84 464.004 241.016 464.004 261.878C464.004 285.538 447.79 299.531 423.117 299.531Z" fill="#FFFCFC"/>
2528
+ </svg>`;
2529
+ var logo_light_default = "data:image/svg+xml," + encodeURIComponent(svg2);
2530
+ var SKEMA_VERSION = "0.2.0";
2531
+ var SettingsPanel = ({
2532
+ isOpen,
2533
+ onClose,
2534
+ zIndex,
2535
+ connected,
2536
+ mode,
2537
+ provider,
2538
+ availableProviders,
2539
+ providerStatus,
2540
+ mcpServerConnected,
2541
+ mcpClientName,
2542
+ annotationCounts,
2543
+ onModeChange,
2544
+ onProviderChange,
2545
+ theme,
2546
+ onThemeChange
2547
+ }) => {
2548
+ if (!isOpen) return null;
2549
+ const isDark = theme === "dark";
2550
+ const bgColor = isDark ? "#1a1a1a" : "#ffffff";
2551
+ const textColor = isDark ? "#ffffff" : "#1a1a1a";
2552
+ const borderColor = isDark ? "#333333" : "#e5e5e5";
2553
+ const mutedColor = isDark ? "#888888" : "#666666";
2554
+ return /* @__PURE__ */ jsxs(
2555
+ "div",
2556
+ {
2557
+ style: {
2558
+ position: "fixed",
2559
+ bottom: 70,
2560
+ right: 16,
2561
+ width: 320,
2562
+ backgroundColor: bgColor,
2563
+ borderRadius: 16,
2564
+ boxShadow: "0 8px 32px rgba(0,0,0,0.2)",
2565
+ zIndex: zIndex + 10,
2566
+ pointerEvents: "auto",
2567
+ overflow: "hidden",
2568
+ border: `1px solid ${borderColor}`
2569
+ },
2570
+ children: [
2571
+ /* @__PURE__ */ jsxs(
2572
+ "div",
2573
+ {
2574
+ style: {
2575
+ padding: "16px 20px",
2576
+ borderBottom: `1px solid ${borderColor}`,
2577
+ display: "flex",
2578
+ alignItems: "center",
2579
+ justifyContent: "space-between"
2580
+ },
2581
+ children: [
2582
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [
2583
+ /* @__PURE__ */ jsx(SkemaWordmark, { isDark, height: 24 }),
2584
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 12, color: mutedColor }, children: [
2585
+ "v",
2586
+ SKEMA_VERSION
2587
+ ] })
2588
+ ] }),
2319
2589
  /* @__PURE__ */ jsx(
2320
- "button",
2590
+ "div",
2321
2591
  {
2322
- style: { ...styles.button, ...styles.cancelButton },
2323
- onClick: handleCancel,
2324
- onMouseEnter: (e) => {
2325
- e.currentTarget.style.background = "rgba(255, 255, 255, 0.1)";
2326
- e.currentTarget.style.color = "rgba(255, 255, 255, 0.8)";
2327
- },
2328
- onMouseLeave: (e) => {
2329
- e.currentTarget.style.background = "transparent";
2330
- e.currentTarget.style.color = "rgba(255, 255, 255, 0.5)";
2592
+ style: {
2593
+ fontSize: 11,
2594
+ padding: "4px 8px",
2595
+ borderRadius: 6,
2596
+ backgroundColor: connected ? "#10b98120" : "#ef444420",
2597
+ color: connected ? "#10b981" : "#ef4444"
2331
2598
  },
2332
- children: "Cancel"
2599
+ children: connected ? "Connected" : "Disconnected"
2600
+ }
2601
+ )
2602
+ ]
2603
+ }
2604
+ ),
2605
+ /* @__PURE__ */ jsxs("div", { style: { padding: "16px 20px" }, children: [
2606
+ /* @__PURE__ */ jsx(SettingRow, { label: "Theme", isDark, textColor, mutedColor, children: /* @__PURE__ */ jsx(ThemeIconToggle, { isDark, onToggle: () => onThemeChange(isDark ? "light" : "dark") }) }),
2607
+ !connected && /* @__PURE__ */ jsxs(
2608
+ "div",
2609
+ {
2610
+ style: {
2611
+ display: "flex",
2612
+ alignItems: "center",
2613
+ gap: 8,
2614
+ padding: "10px 12px",
2615
+ borderRadius: 10,
2616
+ backgroundColor: isDark ? "#2a1a1a" : "#fef2f2",
2617
+ border: `1px solid ${isDark ? "#3d2020" : "#fecaca"}`,
2618
+ marginBottom: 12
2619
+ },
2620
+ children: [
2621
+ /* @__PURE__ */ jsx(
2622
+ "span",
2623
+ {
2624
+ style: {
2625
+ width: 7,
2626
+ height: 7,
2627
+ borderRadius: "50%",
2628
+ backgroundColor: "#ef4444",
2629
+ flexShrink: 0,
2630
+ boxShadow: "0 0 6px #ef444460"
2631
+ }
2632
+ }
2633
+ ),
2634
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
2635
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 12, fontWeight: 500, color: isDark ? "#fca5a5" : "#dc2626" }, children: "Daemon not running" }),
2636
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 10, color: isDark ? "#888" : "#999", marginTop: 2, lineHeight: 1.3 }, children: [
2637
+ "Run ",
2638
+ /* @__PURE__ */ jsx("span", { style: { fontFamily: "monospace", fontSize: 10, color: isDark ? "#aaa" : "#666" }, children: "npx skema-core" }),
2639
+ " to start"
2640
+ ] })
2641
+ ] })
2642
+ ]
2643
+ }
2644
+ ),
2645
+ /* @__PURE__ */ jsx(SettingRow, { label: "Mode", isDark, textColor, mutedColor, disabled: !connected, children: /* @__PURE__ */ jsx(
2646
+ ToggleSwitch,
2647
+ {
2648
+ options: ["CLI", "MCP"],
2649
+ value: mode === "mcp" ? 1 : 0,
2650
+ onChange: (idx) => onModeChange(idx === 1 ? "mcp" : "direct-cli"),
2651
+ isDark,
2652
+ disabled: !connected
2653
+ }
2654
+ ) }),
2655
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: mutedColor, marginTop: -6, marginBottom: 12, lineHeight: 1.4, opacity: connected ? 1 : 0.4 }, children: mode === "mcp" ? "Annotations are queued for your AI agent to process" : "Annotations processed instantly via CLI agents" }),
2656
+ mode === "mcp" && connected && /* @__PURE__ */ jsx(
2657
+ McpStatusPanel,
2658
+ {
2659
+ mcpServerConnected,
2660
+ mcpClientName,
2661
+ annotationCounts,
2662
+ isDark,
2663
+ mutedColor
2664
+ }
2665
+ ),
2666
+ mode === "direct-cli" && /* @__PURE__ */ jsxs(Fragment, { children: [
2667
+ /* @__PURE__ */ jsx(SettingRow, { label: "Provider", isDark, textColor, mutedColor, disabled: !connected, children: /* @__PURE__ */ jsx(
2668
+ ToggleSwitch,
2669
+ {
2670
+ options: ["Gemini", "Claude"],
2671
+ value: provider === "claude" ? 1 : 0,
2672
+ onChange: (idx) => onProviderChange(idx === 1 ? "claude" : "gemini"),
2673
+ isDark,
2674
+ disabled: !connected
2675
+ }
2676
+ ) }),
2677
+ connected && /* @__PURE__ */ jsx(
2678
+ ProviderStatusIndicator,
2679
+ {
2680
+ provider,
2681
+ status: providerStatus[provider],
2682
+ isDark,
2683
+ mutedColor
2684
+ }
2685
+ )
2686
+ ] })
2687
+ ] })
2688
+ ]
2689
+ }
2690
+ );
2691
+ };
2692
+ var SettingRow = ({ label, textColor, disabled, children }) => /* @__PURE__ */ jsxs(
2693
+ "div",
2694
+ {
2695
+ style: {
2696
+ display: "flex",
2697
+ alignItems: "center",
2698
+ justifyContent: "space-between",
2699
+ marginBottom: 12
2700
+ },
2701
+ children: [
2702
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 14, color: textColor, opacity: disabled ? 0.4 : 1, transition: "opacity 0.2s ease" }, children: label }),
2703
+ children
2704
+ ]
2705
+ }
2706
+ );
2707
+ var ToggleSwitch = ({ options, value, onChange, isDark, disabled }) => {
2708
+ const bgColor = isDark ? "#2a2a2a" : "#f0f0f0";
2709
+ const activeColor = disabled ? isDark ? "#555" : "#aaa" : "#FF6800";
2710
+ return /* @__PURE__ */ jsx(
2711
+ "div",
2712
+ {
2713
+ style: {
2714
+ display: "flex",
2715
+ backgroundColor: bgColor,
2716
+ borderRadius: 8,
2717
+ padding: 2,
2718
+ opacity: disabled ? 0.5 : 1,
2719
+ transition: "opacity 0.2s ease"
2720
+ },
2721
+ children: options.map((option, idx) => /* @__PURE__ */ jsx(
2722
+ "button",
2723
+ {
2724
+ onClick: () => !disabled && onChange(idx),
2725
+ disabled,
2726
+ style: {
2727
+ padding: "6px 12px",
2728
+ fontSize: 12,
2729
+ fontWeight: 500,
2730
+ border: "none",
2731
+ borderRadius: 6,
2732
+ cursor: disabled ? "not-allowed" : "pointer",
2733
+ backgroundColor: value === idx ? activeColor : "transparent",
2734
+ color: value === idx ? "white" : isDark ? "#888" : "#666",
2735
+ transition: "all 0.2s ease"
2736
+ },
2737
+ children: option
2738
+ },
2739
+ option
2740
+ ))
2741
+ }
2742
+ );
2743
+ };
2744
+ var CLIENT_NAME_MAP = {
2745
+ "cursor": "Cursor",
2746
+ "claude-desktop": "Claude Desktop",
2747
+ "claude-code": "Claude Code",
2748
+ "windsurf": "Windsurf",
2749
+ "cline": "Cline",
2750
+ "continue": "Continue",
2751
+ "zed": "Zed",
2752
+ "anti-gravity": "Anti-Gravity"
2753
+ };
2754
+ function formatClientName(name) {
2755
+ const lower = name.toLowerCase();
2756
+ return CLIENT_NAME_MAP[lower] || name.charAt(0).toUpperCase() + name.slice(1);
2757
+ }
2758
+ var McpStatusPanel = ({
2759
+ mcpServerConnected,
2760
+ mcpClientName,
2761
+ annotationCounts,
2762
+ isDark,
2763
+ mutedColor
2764
+ }) => {
2765
+ const serverDotColor = mcpServerConnected ? "#10b981" : "#ef4444";
2766
+ const serverStatusText = mcpServerConnected ? mcpClientName ? formatClientName(mcpClientName) : "Connected" : "Not detected";
2767
+ const totalActive = annotationCounts.pending + annotationCounts.acknowledged;
2768
+ return /* @__PURE__ */ jsxs(
2769
+ "div",
2770
+ {
2771
+ style: {
2772
+ borderRadius: 10,
2773
+ backgroundColor: isDark ? "#1a2332" : "#f0f7ff",
2774
+ border: `1px solid ${isDark ? "#2a3a4a" : "#d0e4ff"}`,
2775
+ marginBottom: 12,
2776
+ overflow: "hidden"
2777
+ },
2778
+ children: [
2779
+ /* @__PURE__ */ jsxs(
2780
+ "div",
2781
+ {
2782
+ style: {
2783
+ display: "flex",
2784
+ alignItems: "center",
2785
+ gap: 8,
2786
+ padding: "10px 14px",
2787
+ borderBottom: totalActive > 0 ? `1px solid ${isDark ? "#2a3a4a" : "#d0e4ff"}` : "none"
2788
+ },
2789
+ children: [
2790
+ /* @__PURE__ */ jsx(
2791
+ "span",
2792
+ {
2793
+ style: {
2794
+ width: 7,
2795
+ height: 7,
2796
+ borderRadius: "50%",
2797
+ backgroundColor: serverDotColor,
2798
+ flexShrink: 0,
2799
+ boxShadow: `0 0 6px ${serverDotColor}60`
2800
+ }
2333
2801
  }
2334
2802
  ),
2803
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: isDark ? "#c8d6e5" : "#333", fontWeight: 500 }, children: "MCP Server" }),
2335
2804
  /* @__PURE__ */ jsx(
2336
- "button",
2805
+ "span",
2337
2806
  {
2338
2807
  style: {
2339
- ...styles.button,
2340
- ...styles.submitButton,
2341
- backgroundColor: effectiveAccentColor,
2342
- opacity: text.trim() ? 1 : 0.4
2343
- },
2344
- onClick: handleSubmit,
2345
- disabled: !text.trim(),
2346
- onMouseEnter: (e) => {
2347
- if (text.trim()) {
2348
- e.currentTarget.style.filter = "brightness(0.9)";
2349
- }
2350
- },
2351
- onMouseLeave: (e) => {
2352
- e.currentTarget.style.filter = "none";
2808
+ marginLeft: "auto",
2809
+ fontSize: 11,
2810
+ color: serverDotColor,
2811
+ fontWeight: 500
2353
2812
  },
2354
- children: submitLabel
2813
+ children: serverStatusText
2355
2814
  }
2356
2815
  )
2357
- ] })
2358
- ]
2816
+ ]
2817
+ }
2818
+ ),
2819
+ totalActive > 0 && /* @__PURE__ */ jsx("div", { style: { padding: "8px 14px 10px" }, children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 12 }, children: [
2820
+ /* @__PURE__ */ jsx(CountBadge, { label: "Queued", count: annotationCounts.pending, color: "#f59e0b", isDark }),
2821
+ /* @__PURE__ */ jsx(CountBadge, { label: "In Progress", count: annotationCounts.acknowledged, color: "#3b82f6", isDark }),
2822
+ /* @__PURE__ */ jsx(CountBadge, { label: "Done", count: annotationCounts.resolved, color: "#10b981", isDark })
2823
+ ] }) }),
2824
+ !mcpServerConnected && /* @__PURE__ */ jsx("div", { style: { padding: "0 14px 10px", fontSize: 10, color: mutedColor, lineHeight: 1.4 }, children: "Configure the Skema MCP server in your AI agent (Cursor, Claude Desktop, etc.) to connect." })
2825
+ ]
2826
+ }
2827
+ );
2828
+ };
2829
+ var CountBadge = ({ label, count, color, isDark }) => /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", flex: 1 }, children: [
2830
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 16, fontWeight: 600, color, lineHeight: 1 }, children: count }),
2831
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 9, color: isDark ? "#778899" : "#888", marginTop: 2 }, children: label })
2832
+ ] });
2833
+ var ProviderStatusIndicator = ({ provider, status, isDark, mutedColor }) => {
2834
+ let dotColor;
2835
+ let statusText;
2836
+ let bgTint;
2837
+ if (!status || status.message === "Checking...") {
2838
+ dotColor = mutedColor;
2839
+ statusText = "Checking...";
2840
+ bgTint = isDark ? "#2a2a2a" : "#f5f5f5";
2841
+ } else if (status.installed && status.authorized) {
2842
+ dotColor = "#10b981";
2843
+ statusText = "Ready";
2844
+ bgTint = isDark ? "#10b98110" : "#10b98110";
2845
+ } else if (status.installed && !status.authorized) {
2846
+ dotColor = "#f59e0b";
2847
+ statusText = "Not authorized";
2848
+ bgTint = isDark ? "#f59e0b10" : "#f59e0b10";
2849
+ } else {
2850
+ dotColor = "#ef4444";
2851
+ statusText = "Not installed";
2852
+ bgTint = isDark ? "#ef444410" : "#ef444410";
2853
+ }
2854
+ const label = provider === "gemini" ? "Gemini CLI" : "Claude Code";
2855
+ return /* @__PURE__ */ jsxs(
2856
+ "div",
2857
+ {
2858
+ style: {
2859
+ display: "flex",
2860
+ alignItems: "center",
2861
+ gap: 6,
2862
+ fontSize: 11,
2863
+ color: mutedColor,
2864
+ marginTop: -6,
2865
+ marginBottom: 12,
2866
+ padding: "6px 10px",
2867
+ borderRadius: 8,
2868
+ backgroundColor: bgTint
2869
+ },
2870
+ children: [
2871
+ /* @__PURE__ */ jsx(
2872
+ "span",
2873
+ {
2874
+ style: {
2875
+ width: 6,
2876
+ height: 6,
2877
+ borderRadius: "50%",
2878
+ backgroundColor: dotColor,
2879
+ flexShrink: 0,
2880
+ boxShadow: `0 0 4px ${dotColor}60`
2881
+ }
2882
+ }
2883
+ ),
2884
+ /* @__PURE__ */ jsx("span", { children: label }),
2885
+ /* @__PURE__ */ jsx("span", { style: { marginLeft: "auto", fontSize: 10, color: dotColor, fontWeight: 500 }, children: statusText })
2886
+ ]
2887
+ }
2888
+ );
2889
+ };
2890
+ var ThemeIconToggle = ({ isDark, onToggle }) => /* @__PURE__ */ jsx(
2891
+ "button",
2892
+ {
2893
+ onClick: onToggle,
2894
+ title: isDark ? "Switch to light mode" : "Switch to dark mode",
2895
+ style: {
2896
+ display: "flex",
2897
+ alignItems: "center",
2898
+ justifyContent: "center",
2899
+ width: 36,
2900
+ height: 36,
2901
+ border: "none",
2902
+ borderRadius: 10,
2903
+ backgroundColor: isDark ? "#333333" : "#f0f0f0",
2904
+ cursor: "pointer",
2905
+ transition: "all 0.2s ease"
2906
+ },
2907
+ children: isDark ? (
2908
+ // Moon icon
2909
+ /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx(
2910
+ "path",
2911
+ {
2912
+ d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79Z",
2913
+ fill: "#fbbf24",
2914
+ stroke: "#fbbf24",
2915
+ strokeWidth: "2",
2916
+ strokeLinecap: "round",
2917
+ strokeLinejoin: "round"
2359
2918
  }
2360
- )
2361
- ] });
2919
+ ) })
2920
+ ) : (
2921
+ // Sun icon
2922
+ /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
2923
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "5", fill: "#FF6800", stroke: "#FF6800", strokeWidth: "2" }),
2924
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "1", x2: "12", y2: "3", stroke: "#FF6800", strokeWidth: "2", strokeLinecap: "round" }),
2925
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "21", x2: "12", y2: "23", stroke: "#FF6800", strokeWidth: "2", strokeLinecap: "round" }),
2926
+ /* @__PURE__ */ jsx("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64", stroke: "#FF6800", strokeWidth: "2", strokeLinecap: "round" }),
2927
+ /* @__PURE__ */ jsx("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78", stroke: "#FF6800", strokeWidth: "2", strokeLinecap: "round" }),
2928
+ /* @__PURE__ */ jsx("line", { x1: "1", y1: "12", x2: "3", y2: "12", stroke: "#FF6800", strokeWidth: "2", strokeLinecap: "round" }),
2929
+ /* @__PURE__ */ jsx("line", { x1: "21", y1: "12", x2: "23", y2: "12", stroke: "#FF6800", strokeWidth: "2", strokeLinecap: "round" }),
2930
+ /* @__PURE__ */ jsx("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36", stroke: "#FF6800", strokeWidth: "2", strokeLinecap: "round" }),
2931
+ /* @__PURE__ */ jsx("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22", stroke: "#FF6800", strokeWidth: "2", strokeLinecap: "round" })
2932
+ ] })
2933
+ )
2362
2934
  }
2363
2935
  );
2936
+ var SkemaWordmark = ({ isDark, height = 24 }) => {
2937
+ const src = isDark ? logo_light_default : logo_dark_default;
2938
+ return /* @__PURE__ */ jsx(
2939
+ "img",
2940
+ {
2941
+ src,
2942
+ alt: "Skema",
2943
+ height,
2944
+ style: { height, width: "auto", display: "block" }
2945
+ }
2946
+ );
2947
+ };
2364
2948
  function useKeyboardShortcuts({ onToggle, shortcut = "mod+shift+e" }) {
2365
2949
  useEffect(() => {
2366
2950
  const handleKeyDown = (e) => {
@@ -2733,6 +3317,7 @@ var SkemaOverlays = () => {
2733
3317
  };
2734
3318
 
2735
3319
  // src/lib/tldrawConfig.ts
3320
+ DefaultColorThemePalette.darkMode.black = DefaultColorThemePalette.lightMode.black;
2736
3321
  var skemaComponents = {
2737
3322
  Toolbar: null,
2738
3323
  Overlays: SkemaOverlays,
@@ -2781,7 +3366,11 @@ var skemaHiddenUiStyles = `
2781
3366
  .tlui-button[data-testid="back-to-content"],
2782
3367
  .tlui-offscreen-indicator,
2783
3368
  [class*="back-to-content"],
2784
- .tl-offscreen-indicator {
3369
+ .tl-offscreen-indicator,
3370
+ /* Hide "made with tldraw" watermark */
3371
+ .tlui-watermark,
3372
+ .tlui-watermark__inner,
3373
+ [class*="watermark"] {
2785
3374
  display: none !important;
2786
3375
  }
2787
3376
  `;
@@ -2809,7 +3398,6 @@ var Skema = ({
2809
3398
  zIndex = 99999,
2810
3399
  isProcessing: externalIsProcessing
2811
3400
  }) => {
2812
- const [isActive, setIsActive] = useState(enabled);
2813
3401
  const [annotations, setAnnotations] = useState(initialAnnotations);
2814
3402
  const [domSelections, setDomSelections] = useState([]);
2815
3403
  const [pendingAnnotation, setPendingAnnotation] = useState(null);
@@ -2820,12 +3408,30 @@ var Skema = ({
2820
3408
  const [internalIsProcessing, setInternalIsProcessing] = useState(false);
2821
3409
  const [isToolbarExpanded, setIsToolbarExpanded] = useState(false);
2822
3410
  const [isStylePanelOpen, setIsStylePanelOpen] = useState(false);
3411
+ const [currentToolId, setCurrentToolId] = useState("select");
3412
+ const [theme, setTheme] = useState(() => {
3413
+ if (typeof window !== "undefined") {
3414
+ return localStorage.getItem("skema-theme") || "light";
3415
+ }
3416
+ return "light";
3417
+ });
3418
+ const isDark = theme === "dark";
3419
+ useEffect(() => {
3420
+ if (typeof window !== "undefined") {
3421
+ localStorage.setItem("skema-theme", theme);
3422
+ }
3423
+ if (editorRef.current) {
3424
+ editorRef.current.user.updateUserPreferences({ colorScheme: theme });
3425
+ }
3426
+ }, [theme]);
2823
3427
  const annotationChangesRef = useRef(/* @__PURE__ */ new Map());
2824
3428
  const {
2825
3429
  state: daemonState,
2826
3430
  isGenerating,
2827
3431
  generate,
2828
- revert
3432
+ revert,
3433
+ setMode,
3434
+ setProvider
2829
3435
  } = useDaemon({
2830
3436
  url: daemonUrl || "ws://localhost:9999",
2831
3437
  autoConnect: daemonUrl !== null,
@@ -2881,14 +3487,17 @@ var Skema = ({
2881
3487
  const lastDoubleClickRef = useRef(0);
2882
3488
  const cleanupRef = useRef(null);
2883
3489
  useKeyboardShortcuts({
2884
- onToggle: useCallback(() => setIsActive((prev) => !prev), []),
3490
+ onToggle: useCallback(() => {
3491
+ setIsToolbarExpanded((prev) => !prev);
3492
+ setIsStylePanelOpen(false);
3493
+ }, []),
2885
3494
  shortcut: toggleShortcut
2886
3495
  });
2887
- const scrollOffset = useScrollSync(isActive, editorRef);
2888
- useWheelIntercept(isActive);
2889
- useShapePersistence(isActive, editorRef);
3496
+ const scrollOffset = useScrollSync(isToolbarExpanded, editorRef);
3497
+ useWheelIntercept(isToolbarExpanded);
3498
+ useShapePersistence(isToolbarExpanded, editorRef);
2890
3499
  useScribbleDelete({
2891
- isActive,
3500
+ isActive: isToolbarExpanded,
2892
3501
  editorRef,
2893
3502
  setAnnotations,
2894
3503
  setScribbleToast
@@ -2909,7 +3518,7 @@ var Skema = ({
2909
3518
  };
2910
3519
  }, []);
2911
3520
  useEffect(() => {
2912
- if (!isActive) return;
3521
+ if (!isToolbarExpanded) return;
2913
3522
  const handleResize = () => {
2914
3523
  setDomSelections((prevSelections) => {
2915
3524
  if (prevSelections.length === 0) return prevSelections;
@@ -2995,7 +3604,7 @@ var Skema = ({
2995
3604
  };
2996
3605
  window.addEventListener("resize", handleResize);
2997
3606
  return () => window.removeEventListener("resize", handleResize);
2998
- }, [isActive]);
3607
+ }, [isToolbarExpanded]);
2999
3608
  const getSelectedDrawings = useCallback(() => {
3000
3609
  if (!editorRef.current) return [];
3001
3610
  const editor = editorRef.current;
@@ -3258,6 +3867,9 @@ var Skema = ({
3258
3867
  onProcessingCancel?.();
3259
3868
  }
3260
3869
  setProcessingBoundingBox(null);
3870
+ if (editorRef.current) {
3871
+ editorRef.current.setSelectedShapes([]);
3872
+ }
3261
3873
  setTimeout(() => {
3262
3874
  setPendingAnnotation(null);
3263
3875
  setPendingExiting(false);
@@ -3379,6 +3991,7 @@ var Skema = ({
3379
3991
  }, [domSelections, handleDOMSelect, handleMultiDOMSelect, handleDrawingAnnotation]);
3380
3992
  const handleMount = useCallback((editor) => {
3381
3993
  editorRef.current = editor;
3994
+ editor.user.updateUserPreferences({ colorScheme: theme });
3382
3995
  editor.setStyleForNextShapes(ArrowShapeKindStyle, "arc");
3383
3996
  try {
3384
3997
  const selectIdleState = editor.getStateDescendant("select.idle");
@@ -3449,9 +4062,14 @@ var Skema = ({
3449
4062
  lastBrush = next.brush;
3450
4063
  }
3451
4064
  });
3452
- }, [handleDOMSelect, handleBrushSelection, handleLassoSelection, handleMultiDOMSelect, handleDrawingAnnotation]);
4065
+ const handleToolChange = () => {
4066
+ const toolId = editor.getCurrentToolId();
4067
+ setCurrentToolId((prev) => prev !== toolId ? toolId : prev);
4068
+ };
4069
+ editor.sideEffects.registerAfterChangeHandler("instance", handleToolChange);
4070
+ }, [handleDOMSelect, handleBrushSelection, handleLassoSelection, handleMultiDOMSelect, handleDrawingAnnotation, theme]);
3453
4071
  useEffect(() => {
3454
- if (!isActive) return;
4072
+ if (!isToolbarExpanded) return;
3455
4073
  const handlePointerDown = (e) => {
3456
4074
  if (e.button !== 0) return;
3457
4075
  const target = e.target;
@@ -3467,8 +4085,8 @@ var Skema = ({
3467
4085
  };
3468
4086
  document.addEventListener("pointerdown", handlePointerDown, { capture: true });
3469
4087
  return () => document.removeEventListener("pointerdown", handlePointerDown, { capture: true });
3470
- }, [isActive, pendingAnnotation, handleAnnotationCancel]);
3471
- if (!isActive) {
4088
+ }, [isToolbarExpanded, pendingAnnotation, handleAnnotationCancel]);
4089
+ if (!enabled) {
3472
4090
  return null;
3473
4091
  }
3474
4092
  return /* @__PURE__ */ jsxs(
@@ -3483,18 +4101,16 @@ var Skema = ({
3483
4101
  },
3484
4102
  children: [
3485
4103
  /* @__PURE__ */ jsx("style", { children: skemaHiddenUiStyles }),
3486
- !isStylePanelOpen && /* @__PURE__ */ jsx("style", { children: `
3487
- .tlui-style-panel__wrapper,
3488
- .tlui-style-panel {
3489
- display: none !important;
3490
- }
3491
- ` }),
3492
- isStylePanelOpen && /* @__PURE__ */ jsx("style", { children: `
3493
- .tlui-style-panel__wrapper {
3494
- top: 68px !important;
3495
- right: 16px !important;
3496
- }
3497
- ` }),
4104
+ /* @__PURE__ */ jsx("style", { children: `
4105
+ .tlui-style-panel__wrapper {
4106
+ position: fixed !important;
4107
+ top: 16px !important;
4108
+ right: 16px !important;
4109
+ bottom: auto !important;
4110
+ left: auto !important;
4111
+ ${isToolbarExpanded && (currentToolId === "draw" || currentToolId === "geo") ? "" : "display: none !important;"}
4112
+ }
4113
+ ` }),
3498
4114
  isToolbarExpanded && /* @__PURE__ */ jsx(
3499
4115
  "button",
3500
4116
  {
@@ -3502,14 +4118,14 @@ var Skema = ({
3502
4118
  title: isStylePanelOpen ? "Hide style settings" : "Show style settings",
3503
4119
  style: {
3504
4120
  position: "fixed",
3505
- top: 16,
4121
+ bottom: 16,
3506
4122
  right: 16,
3507
4123
  width: 44,
3508
4124
  height: 44,
3509
4125
  display: "flex",
3510
4126
  alignItems: "center",
3511
4127
  justifyContent: "center",
3512
- backgroundColor: isStylePanelOpen ? "#FF6800" : "white",
4128
+ backgroundColor: isStylePanelOpen ? "#FF6800" : isDark ? "#2a2a2a" : "white",
3513
4129
  border: "none",
3514
4130
  borderRadius: 12,
3515
4131
  boxShadow: "0 2px 10px rgba(0,0,0,0.15)",
@@ -3523,7 +4139,7 @@ var Skema = ({
3523
4139
  "path",
3524
4140
  {
3525
4141
  d: "M12 15C13.6569 15 15 13.6569 15 12C15 10.3431 13.6569 9 12 9C10.3431 9 9 10.3431 9 12C9 13.6569 10.3431 15 12 15Z",
3526
- stroke: isStylePanelOpen ? "white" : "#6B7280",
4142
+ stroke: isStylePanelOpen ? "white" : isDark ? "#9CA3AF" : "#6B7280",
3527
4143
  strokeWidth: "2",
3528
4144
  strokeLinecap: "round",
3529
4145
  strokeLinejoin: "round"
@@ -3533,7 +4149,7 @@ var Skema = ({
3533
4149
  "path",
3534
4150
  {
3535
4151
  d: "M19.4 15C19.2669 15.3016 19.2272 15.6362 19.286 15.9606C19.3448 16.285 19.4995 16.5843 19.73 16.82L19.79 16.88C19.976 17.0657 20.1235 17.2863 20.2241 17.5291C20.3248 17.7719 20.3766 18.0322 20.3766 18.295C20.3766 18.5578 20.3248 18.8181 20.2241 19.0609C20.1235 19.3037 19.976 19.5243 19.79 19.71C19.6043 19.896 19.3837 20.0435 19.1409 20.1441C18.8981 20.2448 18.6378 20.2966 18.375 20.2966C18.1122 20.2966 17.8519 20.2448 17.6091 20.1441C17.3663 20.0435 17.1457 19.896 16.96 19.71L16.9 19.65C16.6643 19.4195 16.365 19.2648 16.0406 19.206C15.7162 19.1472 15.3816 19.1869 15.08 19.32C14.7842 19.4468 14.532 19.6572 14.3543 19.9255C14.1766 20.1938 14.0813 20.5082 14.08 20.83V21C14.08 21.5304 13.8693 22.0391 13.4942 22.4142C13.1191 22.7893 12.6104 23 12.08 23C11.5496 23 11.0409 22.7893 10.6658 22.4142C10.2907 22.0391 10.08 21.5304 10.08 21V20.91C10.0723 20.579 9.96512 20.258 9.77251 19.9887C9.5799 19.7194 9.31074 19.5143 9 19.4C8.69838 19.2669 8.36381 19.2272 8.03941 19.286C7.71502 19.3448 7.41568 19.4995 7.18 19.73L7.12 19.79C6.93425 19.976 6.71368 20.1235 6.47088 20.2241C6.22808 20.3248 5.96783 20.3766 5.705 20.3766C5.44217 20.3766 5.18192 20.3248 4.93912 20.2241C4.69632 20.1235 4.47575 19.976 4.29 19.79C4.10405 19.6043 3.95653 19.3837 3.85588 19.1409C3.75523 18.8981 3.70343 18.6378 3.70343 18.375C3.70343 18.1122 3.75523 17.8519 3.85588 17.6091C3.95653 17.3663 4.10405 17.1457 4.29 16.96L4.35 16.9C4.58054 16.6643 4.73519 16.365 4.794 16.0406C4.85282 15.7162 4.81312 15.3816 4.68 15.08C4.55324 14.7842 4.34276 14.532 4.07447 14.3543C3.80618 14.1766 3.49179 14.0813 3.17 14.08H3C2.46957 14.08 1.96086 13.8693 1.58579 13.4942C1.21071 13.1191 1 12.6104 1 12.08C1 11.5496 1.21071 11.0409 1.58579 10.6658C1.96086 10.2907 2.46957 10.08 3 10.08H3.09C3.42099 10.0723 3.742 9.96512 4.0113 9.77251C4.28059 9.5799 4.48572 9.31074 4.6 9C4.73312 8.69838 4.77282 8.36381 4.714 8.03941C4.65519 7.71502 4.50054 7.41568 4.27 7.18L4.21 7.12C4.02405 6.93425 3.87653 6.71368 3.77588 6.47088C3.67523 6.22808 3.62343 5.96783 3.62343 5.705C3.62343 5.44217 3.67523 5.18192 3.77588 4.93912C3.87653 4.69632 4.02405 4.47575 4.21 4.29C4.39575 4.10405 4.61632 3.95653 4.85912 3.85588C5.10192 3.75523 5.36217 3.70343 5.625 3.70343C5.88783 3.70343 6.14808 3.75523 6.39088 3.85588C6.63368 3.95653 6.85425 4.10405 7.04 4.29L7.1 4.35C7.33568 4.58054 7.63502 4.73519 7.95941 4.794C8.28381 4.85282 8.61838 4.81312 8.92 4.68H9C9.29577 4.55324 9.54802 4.34276 9.72569 4.07447C9.90337 3.80618 9.99872 3.49179 10 3.17V3C10 2.46957 10.2107 1.96086 10.5858 1.58579C10.9609 1.21071 11.4696 1 12 1C12.5304 1 13.0391 1.21071 13.4142 1.58579C13.7893 1.96086 14 2.46957 14 3V3.09C14.0013 3.41179 14.0966 3.72618 14.2743 3.99447C14.452 4.26276 14.7042 4.47324 15 4.6C15.3016 4.73312 15.6362 4.77282 15.9606 4.714C16.285 4.65519 16.5843 4.50054 16.82 4.27L16.88 4.21C17.0657 4.02405 17.2863 3.87653 17.5291 3.77588C17.7719 3.67523 18.0322 3.62343 18.295 3.62343C18.5578 3.62343 18.8181 3.67523 19.0609 3.77588C19.3037 3.87653 19.5243 4.02405 19.71 4.21C19.896 4.39575 20.0435 4.61632 20.1441 4.85912C20.2448 5.10192 20.2966 5.36217 20.2966 5.625C20.2966 5.88783 20.2448 6.14808 20.1441 6.39088C20.0435 6.63368 19.896 6.85425 19.71 7.04L19.65 7.1C19.4195 7.33568 19.2648 7.63502 19.206 7.95941C19.1472 8.28381 19.1869 8.61838 19.32 8.92V9C19.4468 9.29577 19.6572 9.54802 19.9255 9.72569C20.1938 9.90337 20.5082 9.99872 20.83 10H21C21.5304 10 22.0391 10.2107 22.4142 10.5858C22.7893 10.9609 23 11.4696 23 12C23 12.5304 22.7893 13.0391 22.4142 13.4142C22.0391 13.7893 21.5304 14 21 14H20.91C20.5882 14.0013 20.2738 14.0966 20.0055 14.2743C19.7372 14.452 19.5268 14.7042 19.4 15Z",
3536
- stroke: isStylePanelOpen ? "white" : "#6B7280",
4152
+ stroke: isStylePanelOpen ? "white" : isDark ? "#9CA3AF" : "#6B7280",
3537
4153
  strokeWidth: "2",
3538
4154
  strokeLinecap: "round",
3539
4155
  strokeLinejoin: "round"
@@ -3542,13 +4158,33 @@ var Skema = ({
3542
4158
  ] })
3543
4159
  }
3544
4160
  ),
4161
+ /* @__PURE__ */ jsx(
4162
+ SettingsPanel,
4163
+ {
4164
+ isOpen: isStylePanelOpen,
4165
+ onClose: () => setIsStylePanelOpen(false),
4166
+ zIndex,
4167
+ connected: daemonState.connected,
4168
+ mode: daemonState.mode,
4169
+ provider: daemonState.provider,
4170
+ availableProviders: daemonState.availableProviders,
4171
+ providerStatus: daemonState.providerStatus,
4172
+ mcpServerConnected: daemonState.mcpServerConnected,
4173
+ mcpClientName: daemonState.mcpClientName,
4174
+ annotationCounts: daemonState.annotationCounts,
4175
+ onModeChange: setMode,
4176
+ onProviderChange: setProvider,
4177
+ theme,
4178
+ onThemeChange: setTheme
4179
+ }
4180
+ ),
3545
4181
  /* @__PURE__ */ jsx(
3546
4182
  "div",
3547
4183
  {
3548
4184
  style: {
3549
4185
  position: "absolute",
3550
4186
  inset: 0,
3551
- pointerEvents: "auto"
4187
+ pointerEvents: isToolbarExpanded ? "auto" : "none"
3552
4188
  },
3553
4189
  children: /* @__PURE__ */ jsx(
3554
4190
  Tldraw,
@@ -3563,8 +4199,10 @@ var Skema = ({
3563
4199
  children: /* @__PURE__ */ jsx(
3564
4200
  SkemaToolbar,
3565
4201
  {
4202
+ isExpanded: isToolbarExpanded,
3566
4203
  onExpandedChange: setIsToolbarExpanded,
3567
- onStylePanelChange: setIsStylePanelOpen
4204
+ onStylePanelChange: setIsStylePanelOpen,
4205
+ isDark
3568
4206
  }
3569
4207
  )
3570
4208
  }
@@ -3616,12 +4254,13 @@ var Skema = ({
3616
4254
  ref: popupRef,
3617
4255
  element: pendingAnnotation.element,
3618
4256
  selectedText: pendingAnnotation.selectedText,
3619
- placeholder: pendingAnnotation.annotationType === "drawing" ? "What does this drawing mean?" : pendingAnnotation.isMultiSelect ? "What should change about these elements?" : "What should change?",
4257
+ placeholder: pendingAnnotation.annotationType === "drawing" ? "What does this drawing mean?" : pendingAnnotation.isMultiSelect ? "What should change about these elements?" : "Write your changes",
3620
4258
  onSubmit: handleAnnotationSubmit,
3621
4259
  onCancel: handleAnnotationCancel,
3622
4260
  isExiting: pendingExiting,
3623
4261
  isMultiSelect: pendingAnnotation.isMultiSelect,
3624
4262
  accentColor: pendingAnnotation.isMultiSelect ? "#34C759" : "#3b82f6",
4263
+ isDark,
3625
4264
  style: {
3626
4265
  left: Math.max(160, Math.min(window.innerWidth - 160, pendingAnnotation.x / 100 * window.innerWidth)),
3627
4266
  ...pendingAnnotation.clientY > window.innerHeight - 250 ? { bottom: window.innerHeight - pendingAnnotation.clientY + 30 } : { top: pendingAnnotation.clientY + 30 },
@@ -3639,35 +4278,6 @@ var Skema = ({
3639
4278
  onExport: handleExport
3640
4279
  }
3641
4280
  ),
3642
- /* @__PURE__ */ jsxs(
3643
- "div",
3644
- {
3645
- "data-skema": "toggle-hint",
3646
- style: {
3647
- position: "fixed",
3648
- bottom: 16,
3649
- left: 16,
3650
- padding: "8px 12px",
3651
- backgroundColor: "rgba(0, 0, 0, 0.7)",
3652
- color: "white",
3653
- borderRadius: "6px",
3654
- fontSize: "12px",
3655
- pointerEvents: "none",
3656
- zIndex: zIndex + 1
3657
- },
3658
- children: [
3659
- "Press ",
3660
- /* @__PURE__ */ jsx("kbd", { style: {
3661
- backgroundColor: "rgba(255,255,255,0.2)",
3662
- padding: "2px 6px",
3663
- borderRadius: "3px",
3664
- marginLeft: "4px",
3665
- marginRight: "4px"
3666
- }, children: "\u2318\u21E7E" }),
3667
- " to toggle Skema"
3668
- ]
3669
- }
3670
- ),
3671
4281
  scribbleToast && /* @__PURE__ */ jsx(
3672
4282
  "div",
3673
4283
  {