@cloudinary/asset-management-mcp 0.9.1 → 0.9.3

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 (47) hide show
  1. package/README.md +12 -15
  2. package/bin/mcp-server.js +288 -369
  3. package/bin/mcp-server.js.map +13 -13
  4. package/esm/landing-page.d.ts.map +1 -1
  5. package/esm/landing-page.js +9 -3
  6. package/esm/landing-page.js.map +1 -1
  7. package/esm/lib/config.d.ts +3 -3
  8. package/esm/lib/config.js +3 -3
  9. package/esm/mcp-server/apps/app-shared.d.ts +6 -5
  10. package/esm/mcp-server/apps/app-shared.d.ts.map +1 -1
  11. package/esm/mcp-server/apps/app-shared.js +134 -14
  12. package/esm/mcp-server/apps/app-shared.js.map +1 -1
  13. package/esm/mcp-server/apps/asset-details-app.d.ts.map +1 -1
  14. package/esm/mcp-server/apps/asset-details-app.js +7 -14
  15. package/esm/mcp-server/apps/asset-details-app.js.map +1 -1
  16. package/esm/mcp-server/apps/asset-gallery-app.d.ts.map +1 -1
  17. package/esm/mcp-server/apps/asset-gallery-app.js +99 -306
  18. package/esm/mcp-server/apps/asset-gallery-app.js.map +1 -1
  19. package/esm/mcp-server/apps/asset-upload-app.d.ts.map +1 -1
  20. package/esm/mcp-server/apps/asset-upload-app.js +29 -24
  21. package/esm/mcp-server/apps/asset-upload-app.js.map +1 -1
  22. package/esm/mcp-server/apps/config.d.ts.map +1 -1
  23. package/esm/mcp-server/apps/config.js +1 -2
  24. package/esm/mcp-server/apps/config.js.map +1 -1
  25. package/esm/mcp-server/apps/extensions.d.ts.map +1 -1
  26. package/esm/mcp-server/apps/extensions.js +6 -1
  27. package/esm/mcp-server/apps/extensions.js.map +1 -1
  28. package/esm/mcp-server/cli/serve/impl.js +1 -1
  29. package/esm/mcp-server/cli/serve/impl.js.map +1 -1
  30. package/esm/mcp-server/mcp-server.js +1 -1
  31. package/esm/mcp-server/server.js +1 -1
  32. package/esm/types/bigint.d.ts.map +1 -1
  33. package/esm/types/bigint.js +4 -3
  34. package/esm/types/bigint.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/landing-page.ts +9 -3
  37. package/src/lib/config.ts +3 -3
  38. package/src/mcp-server/apps/app-shared.ts +135 -14
  39. package/src/mcp-server/apps/asset-details-app.ts +7 -13
  40. package/src/mcp-server/apps/asset-gallery-app.ts +99 -305
  41. package/src/mcp-server/apps/asset-upload-app.ts +29 -23
  42. package/src/mcp-server/apps/config.ts +1 -2
  43. package/src/mcp-server/apps/extensions.ts +6 -1
  44. package/src/mcp-server/cli/serve/impl.ts +1 -1
  45. package/src/mcp-server/mcp-server.ts +1 -1
  46. package/src/mcp-server/server.ts +1 -1
  47. package/src/types/bigint.ts +18 -17
@@ -111,6 +111,7 @@ export const SHARED_CSS_TOKENS = /* css */ `
111
111
  [data-theme="dark"] .status-warn, .dark .status-warn { background: #854d0e; color: #fef08a; }
112
112
  [data-theme="dark"] .status-err, .dark .status-err { background: #991b1b; color: #fecaca; }
113
113
 
114
+ html { scrollbar-gutter: auto; }
114
115
  body {
115
116
  font-family: var(--cld-font);
116
117
  background: var(--cld-bg);
@@ -119,27 +120,49 @@ body {
119
120
  line-height: 1.5;
120
121
  font-size: var(--cld-font-xs);
121
122
  position: relative;
123
+ overflow-x: hidden;
122
124
  }
123
125
  .theme-btn {
124
- position: absolute; top: 4px; right: 4px; z-index: 900;
125
126
  width: 22px; height: 22px; border-radius: 50%;
126
127
  border: 1px solid transparent; background: transparent;
127
128
  color: var(--cld-text3); cursor: pointer;
128
129
  display: flex; align-items: center; justify-content: center;
129
130
  padding: 0; transition: background 0.15s, color 0.15s, border-color 0.15s;
130
- opacity: 0.5;
131
+ opacity: 0.5; flex-shrink: 0;
131
132
  }
132
133
  .theme-btn:hover { background: var(--cld-bg3); color: var(--cld-text); border-color: var(--cld-border); opacity: 1; }
133
134
  .theme-btn svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
135
+ /* Shared icon-button — square pill, same family as theme-btn */
136
+ .icon-btn {
137
+ display: inline-flex; align-items: center; justify-content: center; gap: 5px;
138
+ background: none; border: 1px solid var(--cld-border); border-radius: var(--cld-radius-sm);
139
+ color: var(--cld-text2); cursor: pointer; padding: 4px 8px;
140
+ font-size: 12px; font-weight: 500; font-family: inherit; line-height: 1;
141
+ transition: background 0.15s, color 0.15s, border-color 0.15s;
142
+ white-space: nowrap; flex-shrink: 0;
143
+ }
144
+ .icon-btn:hover { background: var(--cld-bg3); color: var(--cld-text); border-color: var(--cld-border2); }
145
+ .icon-btn svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
146
+ /* icon-only variant (no text label) */
147
+ .icon-btn.icon-only { padding: 4px; width: 28px; height: 28px; }
148
+ /* header state icon (decorative, not a button) */
149
+ .upload-header-icon { display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
150
+ .upload-header-icon svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
151
+ .upload-header-icon.icon-success { color: var(--cld-success); }
152
+ .upload-header-icon.icon-error { color: var(--cld-error); }
153
+ .upload-header-icon.icon-warning { color: var(--cld-warning); }
154
+ .upload-header-icon.icon-accent { color: var(--cld-accent); }
134
155
  `;
135
156
  // ── CSS: Shared component styles ────────────────────────────────────
136
157
  export const SHARED_CSS_COMPONENTS = /* css */ `
137
158
  .link { cursor: pointer; }
138
159
  .link:hover { color: var(--cld-accent); text-decoration: underline; }
139
160
 
140
- /* Modal */
161
+ /* Modal — positioned absolutely so it can be placed in the part of the
162
+ * iframe that is currently visible in the host's viewport (since position:fixed
163
+ * inside a tall iframe anchors to iframe-center, not the user's visible area). */
141
164
  .modal-overlay {
142
- position: fixed; inset: 0;
165
+ position: absolute; left: 0; right: 0;
143
166
  background: rgba(0,0,0,0.45);
144
167
  display: flex; align-items: center; justify-content: center;
145
168
  z-index: 1000; backdrop-filter: blur(3px); padding: 24px;
@@ -383,7 +406,8 @@ details.detail-section > summary.detail-section-title::-webkit-details-marker {
383
406
  }
384
407
  .upload-zone:hover { border-color: var(--cld-accent); background: var(--cld-accent-bg); }
385
408
  .upload-zone.dragover { border-color: var(--cld-accent); background: var(--cld-accent-bg); }
386
- .upload-zone-icon { font-size: 36px; margin-bottom: 8px; color: var(--cld-text3); }
409
+ .upload-zone-icon { margin-bottom: 8px; color: var(--cld-text3); display: flex; align-items: center; justify-content: center; }
410
+ .upload-zone-icon svg { width: 36px; height: 36px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
387
411
  .upload-zone-text { font-size: 14px; color: var(--cld-text2); margin-bottom: 4px; }
388
412
  .upload-zone-hint { font-size: 12px; color: var(--cld-text3); }
389
413
  .upload-zone-btn {
@@ -429,8 +453,9 @@ details.detail-section > summary.detail-section-title::-webkit-details-marker {
429
453
  .upload-preview-icon {
430
454
  width: 56px; height: 56px; border-radius: var(--cld-radius-sm);
431
455
  background: var(--cld-bg3); flex-shrink: 0; display: flex;
432
- align-items: center; justify-content: center; font-size: 24px; color: var(--cld-text3);
456
+ align-items: center; justify-content: center; color: var(--cld-text3);
433
457
  }
458
+ .upload-preview-icon svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
434
459
  .upload-preview-info { flex: 1; min-width: 0; }
435
460
  .upload-preview-name { font-size: 13px; font-weight: 600; color: var(--cld-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
436
461
  .upload-preview-meta { font-size: 11px; color: var(--cld-text3); margin-top: 2px; }
@@ -579,19 +604,15 @@ details.upload-section > .upload-form { margin: 0; padding: 10px 12px; }
579
604
  background: var(--cld-accent-bg); border: 1px solid var(--cld-accent);
580
605
  border-radius: var(--cld-radius); margin-bottom: 4px; position: relative;
581
606
  }
582
- .upload-staged-icon { font-size: 24px; flex-shrink: 0; }
607
+ .upload-staged-icon { flex-shrink: 0; display: flex; align-items: center; color: var(--cld-accent); }
608
+ .upload-staged-icon svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
583
609
  .upload-staged-info { flex: 1; min-width: 0; }
584
610
  .upload-staged-name {
585
611
  font-size: 13px; font-weight: 600; color: var(--cld-text);
586
612
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
587
613
  }
588
614
  .upload-staged-meta { font-size: 11px; color: var(--cld-text3); margin-top: 2px; }
589
- .upload-staged-clear {
590
- background: none; border: none; cursor: pointer; font-size: 16px;
591
- color: var(--cld-text3); padding: 4px 6px; border-radius: var(--cld-radius-sm);
592
- transition: color 0.15s, background 0.15s; flex-shrink: 0;
593
- }
594
- .upload-staged-clear:hover { color: var(--cld-error); background: rgba(206,25,13,0.08); }
615
+ .upload-staged-clear:hover { color: var(--cld-error); border-color: var(--cld-error); background: rgba(206,25,13,0.08); }
595
616
 
596
617
  /* Upload submit button */
597
618
  .upload-submit {
@@ -638,6 +659,23 @@ details.upload-section > .upload-form { margin: 0; padding: 10px 12px; }
638
659
  .json-null { color: #868e96; }
639
660
  }
640
661
  `;
662
+ // ── JS: SVG icon strings (Lucide-style, 24px viewBox, stroke-based) ──
663
+ export const SHARED_JS_ICONS = /* js */ `
664
+ var IC = {
665
+ refresh: '<svg viewBox="0 0 24 24"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/></svg>',
666
+ chevronLeft:'<svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>',
667
+ arrowDown: '<svg viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/></svg>',
668
+ x: '<svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',
669
+ zap: '<svg viewBox="0 0 24 24"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>',
670
+ uploadCloud:'<svg viewBox="0 0 24 24"><polyline points="16 16 12 12 8 16"/><line x1="12" y1="12" x2="12" y2="21"/><path d="M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3"/></svg>',
671
+ alertTriangle:'<svg viewBox="0 0 24 24"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>',
672
+ folderOpen: '<svg viewBox="0 0 24 24"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/><polyline points="22 13 17 13 15 16 9 16 7 13 2 13"/></svg>',
673
+ checkCircle:'<svg viewBox="0 0 24 24"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>',
674
+ clock: '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>',
675
+ file: '<svg viewBox="0 0 24 24"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><polyline points="13 2 13 9 20 9"/></svg>',
676
+ image: '<svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>',
677
+ };
678
+ `;
641
679
  // ── JS: MCPApp client class ─────────────────────────────────────────
642
680
  export const SHARED_JS_MCP_CLIENT = /* js */ `
643
681
  var RPC_TIMEOUT_MS = 15000;
@@ -726,6 +764,29 @@ class MCPApp {
726
764
  `;
727
765
  // ── JS: Helper functions ────────────────────────────────────────────
728
766
  export const SHARED_JS_HELPERS = /* js */ `
767
+ function copyText(text) {
768
+ if (navigator.clipboard && navigator.clipboard.writeText) {
769
+ return navigator.clipboard.writeText(text).catch(function() { return _copyFallback(text); });
770
+ }
771
+ return _copyFallback(text);
772
+ }
773
+ function _copyFallback(text) {
774
+ return new Promise(function(resolve, reject) {
775
+ try {
776
+ var ta = document.createElement("textarea");
777
+ ta.value = text;
778
+ ta.setAttribute("readonly", "");
779
+ ta.style.position = "fixed"; ta.style.top = "0"; ta.style.left = "0";
780
+ ta.style.opacity = "0"; ta.style.pointerEvents = "none";
781
+ document.body.appendChild(ta);
782
+ ta.select(); ta.setSelectionRange(0, text.length);
783
+ var ok = document.execCommand("copy");
784
+ document.body.removeChild(ta);
785
+ if (ok) resolve(); else reject(new Error("Clipboard unavailable"));
786
+ } catch (e) { reject(e); }
787
+ });
788
+ }
789
+
729
790
  function fmtBytes(b) {
730
791
  if (!b) return "";
731
792
  var u = ["B","KB","MB","GB"], i = Math.min(Math.floor(Math.log(b)/Math.log(1024)), 3);
@@ -945,6 +1006,55 @@ function closeModal() {
945
1006
  if (ov) ov.remove();
946
1007
  }
947
1008
 
1009
+ /* Position the modal overlay so it's centered on the part of the iframe
1010
+ * the user is currently looking at. Inside an iframe that the host has
1011
+ * sized to scrollHeight, position: fixed anchors to iframe-center, not
1012
+ * the user's visible band — so we compute the visible band ourselves
1013
+ * via IntersectionObserver and place the overlay absolutely there. */
1014
+ function positionModalInVisibleArea(overlay) {
1015
+ if (!overlay) return;
1016
+ var docH = Math.max(document.documentElement.scrollHeight, window.innerHeight);
1017
+
1018
+ // Try IntersectionObserver first (works cross-origin too)
1019
+ if (typeof IntersectionObserver !== "undefined") {
1020
+ var probe = document.createElement("div");
1021
+ probe.style.cssText = "position:absolute;left:0;top:0;width:1px;height:" + docH + "px;pointer-events:none;visibility:hidden;";
1022
+ document.body.appendChild(probe);
1023
+ var io = new IntersectionObserver(function(entries) {
1024
+ try {
1025
+ var entry = entries[0];
1026
+ var rect = entry.intersectionRect;
1027
+ var rootRect = entry.rootBounds || entry.boundingClientRect;
1028
+ // intersectionRect.top is in viewport coords; visible band of the
1029
+ // document is from (probe.top + rect.top) to (probe.top + rect.bottom).
1030
+ var probeTop = entry.boundingClientRect.top; // viewport-relative
1031
+ var visibleTop = rect.top - probeTop; // document-relative
1032
+ var visibleHeight = rect.height;
1033
+ if (visibleHeight > 0) {
1034
+ overlay.style.top = visibleTop + "px";
1035
+ overlay.style.height = visibleHeight + "px";
1036
+ } else {
1037
+ // Fallback: probe not intersecting (shouldn't happen with full-height probe)
1038
+ overlay.style.top = (window.scrollY || 0) + "px";
1039
+ overlay.style.height = window.innerHeight + "px";
1040
+ }
1041
+ } finally {
1042
+ io.disconnect();
1043
+ if (probe.parentNode) probe.parentNode.removeChild(probe);
1044
+ }
1045
+ });
1046
+ io.observe(probe);
1047
+ return;
1048
+ }
1049
+
1050
+ // Fallback: same-origin only — read iframe's bounding rect
1051
+ var rect = document.documentElement.getBoundingClientRect();
1052
+ var visibleTop = rect.top < 0 ? -rect.top : 0;
1053
+ var visibleHeight = Math.min(window.innerHeight, rect.bottom) - Math.max(0, rect.top);
1054
+ overlay.style.top = visibleTop + "px";
1055
+ overlay.style.height = Math.max(visibleHeight, 200) + "px";
1056
+ }
1057
+
948
1058
  function openModal(headerHtml, bodyHtml) {
949
1059
  closeModal();
950
1060
  var h = '<div class="modal-overlay"><div class="modal">';
@@ -954,6 +1064,7 @@ function openModal(headerHtml, bodyHtml) {
954
1064
  document.body.insertAdjacentHTML("beforeend", h);
955
1065
 
956
1066
  var overlay = document.querySelector(".modal-overlay");
1067
+ positionModalInVisibleArea(overlay);
957
1068
  overlay.addEventListener("click", function(e) {
958
1069
  if (e.target === overlay || e.target.classList.contains("modal-close")) {
959
1070
  closeModal();
@@ -1955,7 +2066,16 @@ function renderThemeToggle() {
1955
2066
  applyTheme();
1956
2067
  renderThemeToggle();
1957
2068
  });
1958
- document.body.appendChild(btn);
2069
+ var slot = document.getElementById("header-actions");
2070
+ if (slot) {
2071
+ slot.appendChild(btn);
2072
+ } else {
2073
+ btn.style.position = "absolute";
2074
+ btn.style.top = "4px";
2075
+ btn.style.right = "4px";
2076
+ btn.style.zIndex = "900";
2077
+ document.body.appendChild(btn);
2078
+ }
1959
2079
  }
1960
2080
 
1961
2081
  function setupHostContext(app) {
@@ -1 +1 @@
1
- {"version":3,"file":"app-shared.js","sourceRoot":"","sources":["../../../src/mcp-server/apps/app-shared.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-shared.js","sourceRoot":"","sources":["../../../src/mcp-server/apps/app-shared.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"asset-details-app.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/apps/asset-details-app.ts"],"names":[],"mappings":"AAoBA,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7D"}
1
+ {"version":3,"file":"asset-details-app.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/apps/asset-details-app.ts"],"names":[],"mappings":"AAqBA,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7D"}
@@ -5,7 +5,7 @@
5
5
  * Shares CLDS tokens, MCPApp client, helpers, and detail renderers
6
6
  * with the gallery app via app-shared.ts.
7
7
  */
8
- import { SHARED_CSS_TOKENS, SHARED_CSS_COMPONENTS, SHARED_JS_MCP_CLIENT, SHARED_JS_HELPERS, SHARED_JS_TOOLTIPS, SHARED_JS_MODAL, SHARED_JS_DETAIL_RENDERERS, SHARED_JS_HOST_CONTEXT, } from "./app-shared.js";
8
+ import { SHARED_CSS_TOKENS, SHARED_CSS_COMPONENTS, SHARED_JS_ICONS, SHARED_JS_MCP_CLIENT, SHARED_JS_HELPERS, SHARED_JS_TOOLTIPS, SHARED_JS_MODAL, SHARED_JS_DETAIL_RENDERERS, SHARED_JS_HOST_CONTEXT, } from "./app-shared.js";
9
9
  import { injectToolName } from "./uri.js";
10
10
  export function getAssetDetailsHtml(toolName) {
11
11
  return injectToolName(ASSET_DETAILS_HTML, toolName);
@@ -47,16 +47,6 @@ const ASSET_DETAILS_CSS = /* css */ `
47
47
  padding: 2px 7px; border-radius: 4px; border: 1px solid var(--cld-border);
48
48
  }
49
49
 
50
- .open-link {
51
- padding: 6px 14px; border-radius: var(--cld-radius-sm);
52
- font-size: 12px; font-weight: 500; cursor: pointer;
53
- border: 1px solid var(--cld-accent); background: transparent;
54
- color: var(--cld-accent); font-family: inherit;
55
- transition: background 0.15s;
56
- white-space: nowrap; flex-shrink: 0;
57
- }
58
- .open-link:hover { background: var(--cld-accent-bg); }
59
-
60
50
  .hero-container {
61
51
  position: relative; margin-bottom: var(--cld-sp-md);
62
52
  border-radius: var(--cld-radius); overflow: hidden;
@@ -118,9 +108,9 @@ function renderPage(r) {
118
108
  if (dur) h += '<span class="pill">' + dur + "</span>";
119
109
  if (size) h += '<span class="pill">' + size + "</span>";
120
110
  h += "</div></div>";
121
- h += '<div style="display:flex;gap:6px;flex-shrink:0">';
122
- h += '<button class="open-link" id="refresh-asset" title="Refresh">\\u21BB</button>';
123
- if (url) h += '<button class="open-link" id="open-asset">Open</button>';
111
+ h += '<div id="header-actions" style="display:flex;gap:8px;flex-shrink:0;align-items:center">';
112
+ if (url) h += '<button class="icon-btn" id="open-asset">Open</button>';
113
+ h += '<button class="icon-btn icon-only" id="refresh-asset" title="Refresh">' + IC.refresh + '</button>';
124
114
  h += "</div>";
125
115
  h += "</div>";
126
116
 
@@ -162,6 +152,7 @@ function renderPage(r) {
162
152
  h += "</div>";
163
153
 
164
154
  root.innerHTML = h;
155
+ renderThemeToggle();
165
156
 
166
157
  // Event delegation
167
158
  root.addEventListener("click", function handler(e) {
@@ -207,6 +198,7 @@ function showFetchPrompt() {
207
198
  h += '<button class="prompt-btn prompt-btn-primary" id="fetch-direct-btn">Fetch Directly</button>';
208
199
  h += "</div></div>";
209
200
  root.innerHTML = h;
201
+ renderThemeToggle();
210
202
  document.getElementById("fetch-direct-btn").addEventListener("click", function() { fetchDirect(); });
211
203
  }
212
204
 
@@ -286,6 +278,7 @@ ${ASSET_DETAILS_CSS}
286
278
  <div id="app"><div class="status">Loading asset details&hellip;</div></div>
287
279
 
288
280
  <script>
281
+ ${SHARED_JS_ICONS}
289
282
  ${SHARED_JS_MCP_CLIENT}
290
283
  ${SHARED_JS_HELPERS}
291
284
  ${SHARED_JS_TOOLTIPS}
@@ -1 +1 @@
1
- {"version":3,"file":"asset-details-app.js","sourceRoot":"","sources":["../../../src/mcp-server/apps/asset-details-app.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,UAAU,mBAAmB,CAAC,QAAiB;IACnD,OAAO,cAAc,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,iBAAiB,GAAG,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsEnC,CAAC;AAEF,MAAM,gBAAgB,GAAG,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4LjC,CAAC;AAEF,MAAM,kBAAkB,GAAG,UAAU,CAAC;;;;;;;EAOpC,iBAAiB;EACjB,qBAAqB;EACrB,iBAAiB;;;;;;;EAOjB,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB;EAClB,eAAe;EACf,0BAA0B;EAC1B,sBAAsB;EACtB,gBAAgB;;;QAGV,CAAC"}
1
+ {"version":3,"file":"asset-details-app.js","sourceRoot":"","sources":["../../../src/mcp-server/apps/asset-details-app.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,UAAU,mBAAmB,CAAC,QAAiB;IACnD,OAAO,cAAc,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,iBAAiB,GAAG,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4DnC,CAAC;AAEF,MAAM,gBAAgB,GAAG,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8LjC,CAAC;AAEF,MAAM,kBAAkB,GAAG,UAAU,CAAC;;;;;;;EAOpC,iBAAiB;EACjB,qBAAqB;EACrB,iBAAiB;;;;;;;EAOjB,eAAe;EACf,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB;EAClB,eAAe;EACf,0BAA0B;EAC1B,sBAAsB;EACtB,gBAAgB;;;QAGV,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"asset-gallery-app.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/apps/asset-gallery-app.ts"],"names":[],"mappings":"AAqBA,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7D"}
1
+ {"version":3,"file":"asset-gallery-app.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/apps/asset-gallery-app.ts"],"names":[],"mappings":"AAsBA,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7D"}