@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.
- package/README.md +12 -15
- package/bin/mcp-server.js +288 -369
- package/bin/mcp-server.js.map +13 -13
- package/esm/landing-page.d.ts.map +1 -1
- package/esm/landing-page.js +9 -3
- package/esm/landing-page.js.map +1 -1
- package/esm/lib/config.d.ts +3 -3
- package/esm/lib/config.js +3 -3
- package/esm/mcp-server/apps/app-shared.d.ts +6 -5
- package/esm/mcp-server/apps/app-shared.d.ts.map +1 -1
- package/esm/mcp-server/apps/app-shared.js +134 -14
- package/esm/mcp-server/apps/app-shared.js.map +1 -1
- package/esm/mcp-server/apps/asset-details-app.d.ts.map +1 -1
- package/esm/mcp-server/apps/asset-details-app.js +7 -14
- package/esm/mcp-server/apps/asset-details-app.js.map +1 -1
- package/esm/mcp-server/apps/asset-gallery-app.d.ts.map +1 -1
- package/esm/mcp-server/apps/asset-gallery-app.js +99 -306
- package/esm/mcp-server/apps/asset-gallery-app.js.map +1 -1
- package/esm/mcp-server/apps/asset-upload-app.d.ts.map +1 -1
- package/esm/mcp-server/apps/asset-upload-app.js +29 -24
- package/esm/mcp-server/apps/asset-upload-app.js.map +1 -1
- package/esm/mcp-server/apps/config.d.ts.map +1 -1
- package/esm/mcp-server/apps/config.js +1 -2
- package/esm/mcp-server/apps/config.js.map +1 -1
- package/esm/mcp-server/apps/extensions.d.ts.map +1 -1
- package/esm/mcp-server/apps/extensions.js +6 -1
- package/esm/mcp-server/apps/extensions.js.map +1 -1
- package/esm/mcp-server/cli/serve/impl.js +1 -1
- package/esm/mcp-server/cli/serve/impl.js.map +1 -1
- package/esm/mcp-server/mcp-server.js +1 -1
- package/esm/mcp-server/server.js +1 -1
- package/esm/types/bigint.d.ts.map +1 -1
- package/esm/types/bigint.js +4 -3
- package/esm/types/bigint.js.map +1 -1
- package/package.json +1 -1
- package/src/landing-page.ts +9 -3
- package/src/lib/config.ts +3 -3
- package/src/mcp-server/apps/app-shared.ts +135 -14
- package/src/mcp-server/apps/asset-details-app.ts +7 -13
- package/src/mcp-server/apps/asset-gallery-app.ts +99 -305
- package/src/mcp-server/apps/asset-upload-app.ts +29 -23
- package/src/mcp-server/apps/config.ts +1 -2
- package/src/mcp-server/apps/extensions.ts +6 -1
- package/src/mcp-server/cli/serve/impl.ts +1 -1
- package/src/mcp-server/mcp-server.ts +1 -1
- package/src/mcp-server/server.ts +1 -1
- package/src/types/bigint.ts +18 -17
package/bin/mcp-server.js
CHANGED
|
@@ -13960,9 +13960,9 @@ var init_config = __esm(() => {
|
|
|
13960
13960
|
SDK_METADATA = {
|
|
13961
13961
|
language: "typescript",
|
|
13962
13962
|
openapiDocVersion: "0.5.1",
|
|
13963
|
-
sdkVersion: "0.9.
|
|
13964
|
-
genVersion: "2.
|
|
13965
|
-
userAgent: "speakeasy-sdk/mcp-typescript 0.9.
|
|
13963
|
+
sdkVersion: "0.9.3",
|
|
13964
|
+
genVersion: "2.885.1",
|
|
13965
|
+
userAgent: "speakeasy-sdk/mcp-typescript 0.9.3 2.885.1 0.5.1 @cloudinary/asset-management-mcp"
|
|
13966
13966
|
};
|
|
13967
13967
|
});
|
|
13968
13968
|
|
|
@@ -14021,7 +14021,7 @@ var init_config2 = __esm(() => {
|
|
|
14021
14021
|
"asset-details",
|
|
14022
14022
|
"asset-upload"
|
|
14023
14023
|
];
|
|
14024
|
-
DEFAULT_MCP_APPS = [];
|
|
14024
|
+
DEFAULT_MCP_APPS = [...MCP_APPS];
|
|
14025
14025
|
});
|
|
14026
14026
|
|
|
14027
14027
|
// src/mcp-server/console-logger.ts
|
|
@@ -65624,6 +65624,7 @@ var _infoSchema, _uploadSchema, TOOLTIP_MAP_JSON, SHARED_CSS_TOKENS = `
|
|
|
65624
65624
|
[data-theme="dark"] .status-warn, .dark .status-warn { background: #854d0e; color: #fef08a; }
|
|
65625
65625
|
[data-theme="dark"] .status-err, .dark .status-err { background: #991b1b; color: #fecaca; }
|
|
65626
65626
|
|
|
65627
|
+
html { scrollbar-gutter: auto; }
|
|
65627
65628
|
body {
|
|
65628
65629
|
font-family: var(--cld-font);
|
|
65629
65630
|
background: var(--cld-bg);
|
|
@@ -65632,25 +65633,47 @@ body {
|
|
|
65632
65633
|
line-height: 1.5;
|
|
65633
65634
|
font-size: var(--cld-font-xs);
|
|
65634
65635
|
position: relative;
|
|
65636
|
+
overflow-x: hidden;
|
|
65635
65637
|
}
|
|
65636
65638
|
.theme-btn {
|
|
65637
|
-
position: absolute; top: 4px; right: 4px; z-index: 900;
|
|
65638
65639
|
width: 22px; height: 22px; border-radius: 50%;
|
|
65639
65640
|
border: 1px solid transparent; background: transparent;
|
|
65640
65641
|
color: var(--cld-text3); cursor: pointer;
|
|
65641
65642
|
display: flex; align-items: center; justify-content: center;
|
|
65642
65643
|
padding: 0; transition: background 0.15s, color 0.15s, border-color 0.15s;
|
|
65643
|
-
opacity: 0.5;
|
|
65644
|
+
opacity: 0.5; flex-shrink: 0;
|
|
65644
65645
|
}
|
|
65645
65646
|
.theme-btn:hover { background: var(--cld-bg3); color: var(--cld-text); border-color: var(--cld-border); opacity: 1; }
|
|
65646
65647
|
.theme-btn svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
|
65648
|
+
/* Shared icon-button — square pill, same family as theme-btn */
|
|
65649
|
+
.icon-btn {
|
|
65650
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 5px;
|
|
65651
|
+
background: none; border: 1px solid var(--cld-border); border-radius: var(--cld-radius-sm);
|
|
65652
|
+
color: var(--cld-text2); cursor: pointer; padding: 4px 8px;
|
|
65653
|
+
font-size: 12px; font-weight: 500; font-family: inherit; line-height: 1;
|
|
65654
|
+
transition: background 0.15s, color 0.15s, border-color 0.15s;
|
|
65655
|
+
white-space: nowrap; flex-shrink: 0;
|
|
65656
|
+
}
|
|
65657
|
+
.icon-btn:hover { background: var(--cld-bg3); color: var(--cld-text); border-color: var(--cld-border2); }
|
|
65658
|
+
.icon-btn svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
|
|
65659
|
+
/* icon-only variant (no text label) */
|
|
65660
|
+
.icon-btn.icon-only { padding: 4px; width: 28px; height: 28px; }
|
|
65661
|
+
/* header state icon (decorative, not a button) */
|
|
65662
|
+
.upload-header-icon { display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
|
|
65663
|
+
.upload-header-icon svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
|
65664
|
+
.upload-header-icon.icon-success { color: var(--cld-success); }
|
|
65665
|
+
.upload-header-icon.icon-error { color: var(--cld-error); }
|
|
65666
|
+
.upload-header-icon.icon-warning { color: var(--cld-warning); }
|
|
65667
|
+
.upload-header-icon.icon-accent { color: var(--cld-accent); }
|
|
65647
65668
|
`, SHARED_CSS_COMPONENTS = `
|
|
65648
65669
|
.link { cursor: pointer; }
|
|
65649
65670
|
.link:hover { color: var(--cld-accent); text-decoration: underline; }
|
|
65650
65671
|
|
|
65651
|
-
/* Modal
|
|
65672
|
+
/* Modal — positioned absolutely so it can be placed in the part of the
|
|
65673
|
+
* iframe that is currently visible in the host's viewport (since position:fixed
|
|
65674
|
+
* inside a tall iframe anchors to iframe-center, not the user's visible area). */
|
|
65652
65675
|
.modal-overlay {
|
|
65653
|
-
position:
|
|
65676
|
+
position: absolute; left: 0; right: 0;
|
|
65654
65677
|
background: rgba(0,0,0,0.45);
|
|
65655
65678
|
display: flex; align-items: center; justify-content: center;
|
|
65656
65679
|
z-index: 1000; backdrop-filter: blur(3px); padding: 24px;
|
|
@@ -65894,7 +65917,8 @@ details.detail-section > summary.detail-section-title::-webkit-details-marker {
|
|
|
65894
65917
|
}
|
|
65895
65918
|
.upload-zone:hover { border-color: var(--cld-accent); background: var(--cld-accent-bg); }
|
|
65896
65919
|
.upload-zone.dragover { border-color: var(--cld-accent); background: var(--cld-accent-bg); }
|
|
65897
|
-
.upload-zone-icon {
|
|
65920
|
+
.upload-zone-icon { margin-bottom: 8px; color: var(--cld-text3); display: flex; align-items: center; justify-content: center; }
|
|
65921
|
+
.upload-zone-icon svg { width: 36px; height: 36px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
|
|
65898
65922
|
.upload-zone-text { font-size: 14px; color: var(--cld-text2); margin-bottom: 4px; }
|
|
65899
65923
|
.upload-zone-hint { font-size: 12px; color: var(--cld-text3); }
|
|
65900
65924
|
.upload-zone-btn {
|
|
@@ -65940,8 +65964,9 @@ details.detail-section > summary.detail-section-title::-webkit-details-marker {
|
|
|
65940
65964
|
.upload-preview-icon {
|
|
65941
65965
|
width: 56px; height: 56px; border-radius: var(--cld-radius-sm);
|
|
65942
65966
|
background: var(--cld-bg3); flex-shrink: 0; display: flex;
|
|
65943
|
-
align-items: center; justify-content: center;
|
|
65967
|
+
align-items: center; justify-content: center; color: var(--cld-text3);
|
|
65944
65968
|
}
|
|
65969
|
+
.upload-preview-icon svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
|
|
65945
65970
|
.upload-preview-info { flex: 1; min-width: 0; }
|
|
65946
65971
|
.upload-preview-name { font-size: 13px; font-weight: 600; color: var(--cld-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
65947
65972
|
.upload-preview-meta { font-size: 11px; color: var(--cld-text3); margin-top: 2px; }
|
|
@@ -66090,19 +66115,15 @@ details.upload-section > .upload-form { margin: 0; padding: 10px 12px; }
|
|
|
66090
66115
|
background: var(--cld-accent-bg); border: 1px solid var(--cld-accent);
|
|
66091
66116
|
border-radius: var(--cld-radius); margin-bottom: 4px; position: relative;
|
|
66092
66117
|
}
|
|
66093
|
-
.upload-staged-icon {
|
|
66118
|
+
.upload-staged-icon { flex-shrink: 0; display: flex; align-items: center; color: var(--cld-accent); }
|
|
66119
|
+
.upload-staged-icon svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
|
|
66094
66120
|
.upload-staged-info { flex: 1; min-width: 0; }
|
|
66095
66121
|
.upload-staged-name {
|
|
66096
66122
|
font-size: 13px; font-weight: 600; color: var(--cld-text);
|
|
66097
66123
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
66098
66124
|
}
|
|
66099
66125
|
.upload-staged-meta { font-size: 11px; color: var(--cld-text3); margin-top: 2px; }
|
|
66100
|
-
.upload-staged-clear {
|
|
66101
|
-
background: none; border: none; cursor: pointer; font-size: 16px;
|
|
66102
|
-
color: var(--cld-text3); padding: 4px 6px; border-radius: var(--cld-radius-sm);
|
|
66103
|
-
transition: color 0.15s, background 0.15s; flex-shrink: 0;
|
|
66104
|
-
}
|
|
66105
|
-
.upload-staged-clear:hover { color: var(--cld-error); background: rgba(206,25,13,0.08); }
|
|
66126
|
+
.upload-staged-clear:hover { color: var(--cld-error); border-color: var(--cld-error); background: rgba(206,25,13,0.08); }
|
|
66106
66127
|
|
|
66107
66128
|
/* Upload submit button */
|
|
66108
66129
|
.upload-submit {
|
|
@@ -66148,6 +66169,21 @@ details.upload-section > .upload-form { margin: 0; padding: 10px 12px; }
|
|
|
66148
66169
|
.json-bool { color: #a9e34b; }
|
|
66149
66170
|
.json-null { color: #868e96; }
|
|
66150
66171
|
}
|
|
66172
|
+
`, SHARED_JS_ICONS = `
|
|
66173
|
+
var IC = {
|
|
66174
|
+
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>',
|
|
66175
|
+
chevronLeft:'<svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>',
|
|
66176
|
+
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>',
|
|
66177
|
+
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>',
|
|
66178
|
+
zap: '<svg viewBox="0 0 24 24"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>',
|
|
66179
|
+
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>',
|
|
66180
|
+
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>',
|
|
66181
|
+
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>',
|
|
66182
|
+
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>',
|
|
66183
|
+
clock: '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>',
|
|
66184
|
+
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>',
|
|
66185
|
+
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>',
|
|
66186
|
+
};
|
|
66151
66187
|
`, SHARED_JS_MCP_CLIENT = `
|
|
66152
66188
|
var RPC_TIMEOUT_MS = 15000;
|
|
66153
66189
|
var TOOL_CALL_TIMEOUT_MS = 30000;
|
|
@@ -66233,6 +66269,29 @@ class MCPApp {
|
|
|
66233
66269
|
}
|
|
66234
66270
|
}
|
|
66235
66271
|
`, SHARED_JS_HELPERS = `
|
|
66272
|
+
function copyText(text) {
|
|
66273
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
66274
|
+
return navigator.clipboard.writeText(text).catch(function() { return _copyFallback(text); });
|
|
66275
|
+
}
|
|
66276
|
+
return _copyFallback(text);
|
|
66277
|
+
}
|
|
66278
|
+
function _copyFallback(text) {
|
|
66279
|
+
return new Promise(function(resolve, reject) {
|
|
66280
|
+
try {
|
|
66281
|
+
var ta = document.createElement("textarea");
|
|
66282
|
+
ta.value = text;
|
|
66283
|
+
ta.setAttribute("readonly", "");
|
|
66284
|
+
ta.style.position = "fixed"; ta.style.top = "0"; ta.style.left = "0";
|
|
66285
|
+
ta.style.opacity = "0"; ta.style.pointerEvents = "none";
|
|
66286
|
+
document.body.appendChild(ta);
|
|
66287
|
+
ta.select(); ta.setSelectionRange(0, text.length);
|
|
66288
|
+
var ok = document.execCommand("copy");
|
|
66289
|
+
document.body.removeChild(ta);
|
|
66290
|
+
if (ok) resolve(); else reject(new Error("Clipboard unavailable"));
|
|
66291
|
+
} catch (e) { reject(e); }
|
|
66292
|
+
});
|
|
66293
|
+
}
|
|
66294
|
+
|
|
66236
66295
|
function fmtBytes(b) {
|
|
66237
66296
|
if (!b) return "";
|
|
66238
66297
|
var u = ["B","KB","MB","GB"], i = Math.min(Math.floor(Math.log(b)/Math.log(1024)), 3);
|
|
@@ -66450,6 +66509,55 @@ function closeModal() {
|
|
|
66450
66509
|
if (ov) ov.remove();
|
|
66451
66510
|
}
|
|
66452
66511
|
|
|
66512
|
+
/* Position the modal overlay so it's centered on the part of the iframe
|
|
66513
|
+
* the user is currently looking at. Inside an iframe that the host has
|
|
66514
|
+
* sized to scrollHeight, position: fixed anchors to iframe-center, not
|
|
66515
|
+
* the user's visible band — so we compute the visible band ourselves
|
|
66516
|
+
* via IntersectionObserver and place the overlay absolutely there. */
|
|
66517
|
+
function positionModalInVisibleArea(overlay) {
|
|
66518
|
+
if (!overlay) return;
|
|
66519
|
+
var docH = Math.max(document.documentElement.scrollHeight, window.innerHeight);
|
|
66520
|
+
|
|
66521
|
+
// Try IntersectionObserver first (works cross-origin too)
|
|
66522
|
+
if (typeof IntersectionObserver !== "undefined") {
|
|
66523
|
+
var probe = document.createElement("div");
|
|
66524
|
+
probe.style.cssText = "position:absolute;left:0;top:0;width:1px;height:" + docH + "px;pointer-events:none;visibility:hidden;";
|
|
66525
|
+
document.body.appendChild(probe);
|
|
66526
|
+
var io = new IntersectionObserver(function(entries) {
|
|
66527
|
+
try {
|
|
66528
|
+
var entry = entries[0];
|
|
66529
|
+
var rect = entry.intersectionRect;
|
|
66530
|
+
var rootRect = entry.rootBounds || entry.boundingClientRect;
|
|
66531
|
+
// intersectionRect.top is in viewport coords; visible band of the
|
|
66532
|
+
// document is from (probe.top + rect.top) to (probe.top + rect.bottom).
|
|
66533
|
+
var probeTop = entry.boundingClientRect.top; // viewport-relative
|
|
66534
|
+
var visibleTop = rect.top - probeTop; // document-relative
|
|
66535
|
+
var visibleHeight = rect.height;
|
|
66536
|
+
if (visibleHeight > 0) {
|
|
66537
|
+
overlay.style.top = visibleTop + "px";
|
|
66538
|
+
overlay.style.height = visibleHeight + "px";
|
|
66539
|
+
} else {
|
|
66540
|
+
// Fallback: probe not intersecting (shouldn't happen with full-height probe)
|
|
66541
|
+
overlay.style.top = (window.scrollY || 0) + "px";
|
|
66542
|
+
overlay.style.height = window.innerHeight + "px";
|
|
66543
|
+
}
|
|
66544
|
+
} finally {
|
|
66545
|
+
io.disconnect();
|
|
66546
|
+
if (probe.parentNode) probe.parentNode.removeChild(probe);
|
|
66547
|
+
}
|
|
66548
|
+
});
|
|
66549
|
+
io.observe(probe);
|
|
66550
|
+
return;
|
|
66551
|
+
}
|
|
66552
|
+
|
|
66553
|
+
// Fallback: same-origin only — read iframe's bounding rect
|
|
66554
|
+
var rect = document.documentElement.getBoundingClientRect();
|
|
66555
|
+
var visibleTop = rect.top < 0 ? -rect.top : 0;
|
|
66556
|
+
var visibleHeight = Math.min(window.innerHeight, rect.bottom) - Math.max(0, rect.top);
|
|
66557
|
+
overlay.style.top = visibleTop + "px";
|
|
66558
|
+
overlay.style.height = Math.max(visibleHeight, 200) + "px";
|
|
66559
|
+
}
|
|
66560
|
+
|
|
66453
66561
|
function openModal(headerHtml, bodyHtml) {
|
|
66454
66562
|
closeModal();
|
|
66455
66563
|
var h = '<div class="modal-overlay"><div class="modal">';
|
|
@@ -66459,6 +66567,7 @@ function openModal(headerHtml, bodyHtml) {
|
|
|
66459
66567
|
document.body.insertAdjacentHTML("beforeend", h);
|
|
66460
66568
|
|
|
66461
66569
|
var overlay = document.querySelector(".modal-overlay");
|
|
66570
|
+
positionModalInVisibleArea(overlay);
|
|
66462
66571
|
overlay.addEventListener("click", function(e) {
|
|
66463
66572
|
if (e.target === overlay || e.target.classList.contains("modal-close")) {
|
|
66464
66573
|
closeModal();
|
|
@@ -67456,7 +67565,16 @@ function renderThemeToggle() {
|
|
|
67456
67565
|
applyTheme();
|
|
67457
67566
|
renderThemeToggle();
|
|
67458
67567
|
});
|
|
67459
|
-
document.
|
|
67568
|
+
var slot = document.getElementById("header-actions");
|
|
67569
|
+
if (slot) {
|
|
67570
|
+
slot.appendChild(btn);
|
|
67571
|
+
} else {
|
|
67572
|
+
btn.style.position = "absolute";
|
|
67573
|
+
btn.style.top = "4px";
|
|
67574
|
+
btn.style.right = "4px";
|
|
67575
|
+
btn.style.zIndex = "900";
|
|
67576
|
+
document.body.appendChild(btn);
|
|
67577
|
+
}
|
|
67460
67578
|
}
|
|
67461
67579
|
|
|
67462
67580
|
function setupHostContext(app) {
|
|
@@ -67550,90 +67668,10 @@ var GALLERY_CSS = `
|
|
|
67550
67668
|
font-size: var(--cld-font-xxs); color: var(--cld-text3); background: var(--cld-bg3);
|
|
67551
67669
|
padding: 2px 8px; border-radius: 20px; font-weight: 500;
|
|
67552
67670
|
}
|
|
67553
|
-
|
|
67554
|
-
|
|
67555
|
-
|
|
67556
|
-
|
|
67557
|
-
transition: color 0.15s, border-color 0.15s;
|
|
67558
|
-
}
|
|
67559
|
-
.select-all-btn:hover { color: var(--cld-accent); border-color: var(--cld-accent); }
|
|
67560
|
-
.refresh-btn {
|
|
67561
|
-
background: none; border: 1px solid var(--cld-border); border-radius: var(--cld-radius-sm);
|
|
67562
|
-
color: var(--cld-text2); cursor: pointer; font-size: 14px; padding: 2px 7px;
|
|
67563
|
-
line-height: 1; transition: background 0.15s, color 0.15s;
|
|
67564
|
-
}
|
|
67565
|
-
.refresh-btn:hover { background: var(--cld-bg3); color: var(--cld-text); }
|
|
67566
|
-
|
|
67567
|
-
/* ── Filter bar ── */
|
|
67568
|
-
.filter-row {
|
|
67569
|
-
margin-bottom: var(--cld-sp-md); display: flex; gap: 8px; align-items: center;
|
|
67570
|
-
}
|
|
67571
|
-
.filter-text-wrap { position: relative; flex: 1; }
|
|
67572
|
-
.filter-input {
|
|
67573
|
-
width: 100%; height: 36px; padding: 0 12px 0 34px;
|
|
67574
|
-
border: 1px solid var(--cld-border); border-radius: var(--cld-radius);
|
|
67575
|
-
background: var(--cld-bg); font-size: 12.5px; color: var(--cld-text);
|
|
67576
|
-
outline: none; font-family: inherit;
|
|
67577
|
-
transition: border-color 0.18s, box-shadow 0.18s;
|
|
67578
|
-
}
|
|
67579
|
-
.filter-input::placeholder { color: var(--cld-text3); }
|
|
67580
|
-
.filter-input:focus {
|
|
67581
|
-
border-color: var(--cld-accent);
|
|
67582
|
-
box-shadow: 0 0 0 3px rgba(52,72,197,0.1);
|
|
67583
|
-
}
|
|
67584
|
-
[data-theme="dark"] .filter-input:focus { box-shadow: 0 0 0 3px rgba(13,154,255,0.15); }
|
|
67585
|
-
.filter-icon {
|
|
67586
|
-
position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
|
|
67587
|
-
color: var(--cld-text3); pointer-events: none; display: flex; align-items: center;
|
|
67588
|
-
}
|
|
67589
|
-
.filter-clear {
|
|
67590
|
-
position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
|
|
67591
|
-
background: none; border: none; color: var(--cld-text3); cursor: pointer;
|
|
67592
|
-
font-size: 14px; line-height: 1; padding: 2px 4px; border-radius: 4px;
|
|
67593
|
-
display: none; font-family: inherit;
|
|
67594
|
-
}
|
|
67595
|
-
.filter-clear:hover { color: var(--cld-text); background: var(--cld-border); }
|
|
67596
|
-
.filter-clear.visible { display: block; }
|
|
67597
|
-
|
|
67598
|
-
/* Aspect-ratio dropdown */
|
|
67599
|
-
.aspect-dropdown { position: relative; flex-shrink: 0; user-select: none; }
|
|
67600
|
-
.aspect-btn {
|
|
67601
|
-
height: 36px; padding: 0 10px; border: 1px solid var(--cld-border);
|
|
67602
|
-
border-radius: var(--cld-radius); background: var(--cld-bg);
|
|
67603
|
-
font-size: 12.5px; color: var(--cld-text); cursor: pointer;
|
|
67604
|
-
display: flex; align-items: center; gap: 6px; white-space: nowrap;
|
|
67605
|
-
transition: border-color 0.18s, box-shadow 0.18s, background 0.18s;
|
|
67606
|
-
font-family: inherit; outline: none;
|
|
67607
|
-
}
|
|
67608
|
-
.aspect-btn:hover { border-color: var(--cld-border2); }
|
|
67609
|
-
.aspect-btn.active {
|
|
67610
|
-
border-color: var(--cld-accent); background: var(--cld-accent-bg);
|
|
67611
|
-
color: var(--cld-accent); font-weight: 600;
|
|
67612
|
-
}
|
|
67613
|
-
.aspect-btn-chevron { color: var(--cld-text3); flex-shrink: 0; transition: transform 0.18s; }
|
|
67614
|
-
.aspect-btn.open .aspect-btn-chevron { transform: rotate(180deg); }
|
|
67615
|
-
.aspect-menu {
|
|
67616
|
-
position: absolute; top: calc(100% + 6px); right: 0;
|
|
67617
|
-
background: var(--cld-bg); border: 1px solid var(--cld-border);
|
|
67618
|
-
border-radius: 10px; box-shadow: var(--cld-shadow-md);
|
|
67619
|
-
padding: 4px; min-width: 160px; z-index: 50; display: none;
|
|
67620
|
-
}
|
|
67621
|
-
.aspect-menu.open { display: block; }
|
|
67622
|
-
.aspect-option {
|
|
67623
|
-
display: flex; align-items: center; gap: 10px;
|
|
67624
|
-
padding: 7px 10px; border-radius: 6px; font-size: 12.5px;
|
|
67625
|
-
color: var(--cld-text); cursor: pointer; transition: background 0.18s;
|
|
67626
|
-
}
|
|
67627
|
-
.aspect-option:hover { background: var(--cld-bg3); }
|
|
67628
|
-
.aspect-option.selected { color: var(--cld-accent); font-weight: 600; }
|
|
67629
|
-
.aspect-opt-icon { color: var(--cld-text3); display: flex; align-items: center; flex-shrink: 0; }
|
|
67630
|
-
.aspect-option.selected .aspect-opt-icon { color: var(--cld-accent); }
|
|
67631
|
-
.aspect-check { margin-left: auto; color: var(--cld-accent); opacity: 0; }
|
|
67632
|
-
.aspect-option.selected .aspect-check { opacity: 1; }
|
|
67633
|
-
.no-results {
|
|
67634
|
-
grid-column: 1 / -1; padding: 60px 20px;
|
|
67635
|
-
text-align: center; color: var(--cld-text3); font-size: 13px;
|
|
67636
|
-
}
|
|
67671
|
+
/* action-btn svg sizing */
|
|
67672
|
+
.action-btn svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
|
|
67673
|
+
/* select bar svg */
|
|
67674
|
+
.bar-btn svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
|
|
67637
67675
|
|
|
67638
67676
|
/* ── Grid ── */
|
|
67639
67677
|
.grid {
|
|
@@ -67692,18 +67730,11 @@ var GALLERY_CSS = `
|
|
|
67692
67730
|
opacity: 0; transition: opacity 0.18s; z-index: 4; pointer-events: none;
|
|
67693
67731
|
}
|
|
67694
67732
|
.card:hover .tags-overlay { opacity: 1; }
|
|
67695
|
-
.grid.filtering .tags-overlay { opacity: 1; }
|
|
67696
67733
|
.tag-overlay {
|
|
67697
67734
|
font-size: 10px; color: white;
|
|
67698
67735
|
background: rgba(10, 12, 18, 0.55); padding: 2px 7px; border-radius: 20px;
|
|
67699
67736
|
backdrop-filter: blur(6px); font-weight: 600; letter-spacing: 0.02em;
|
|
67700
67737
|
}
|
|
67701
|
-
.tag-overlay.tag-match { background: rgba(52, 72, 197, 0.82); }
|
|
67702
|
-
.tag-overlay mark {
|
|
67703
|
-
background: rgba(255, 213, 79, 0.5); color: white;
|
|
67704
|
-
border-radius: 2px; padding: 0 1px;
|
|
67705
|
-
}
|
|
67706
|
-
|
|
67707
67738
|
/* Floating action buttons */
|
|
67708
67739
|
.card-actions {
|
|
67709
67740
|
position: absolute; bottom: 10px; left: 0; right: 0;
|
|
@@ -67767,18 +67798,27 @@ var GALLERY_CSS = `
|
|
|
67767
67798
|
}
|
|
67768
67799
|
|
|
67769
67800
|
/* ── Multi-select bar ── */
|
|
67801
|
+
/* Wrapper takes layout space ONLY when a selection is active. When idle
|
|
67802
|
+
* it's display:none so it contributes 0 to scrollHeight (no phantom
|
|
67803
|
+
* scrollbar gutter / no extra iframe height). */
|
|
67804
|
+
.select-bar-wrap {
|
|
67805
|
+
display: none;
|
|
67806
|
+
position: sticky; bottom: 0; left: 0; right: 0;
|
|
67807
|
+
justify-content: center; pointer-events: none;
|
|
67808
|
+
z-index: 100; height: 64px;
|
|
67809
|
+
}
|
|
67810
|
+
.select-bar-wrap.visible { display: flex; }
|
|
67770
67811
|
.select-bar {
|
|
67771
|
-
position:
|
|
67772
|
-
transform:
|
|
67812
|
+
position: absolute; bottom: 8px;
|
|
67813
|
+
transform: translateY(80px);
|
|
67773
67814
|
background: #1a1d24; color: white; border-radius: 40px;
|
|
67774
67815
|
padding: 0 6px 0 16px; height: 48px;
|
|
67775
67816
|
display: flex; align-items: center; gap: 4px;
|
|
67776
67817
|
box-shadow: 0 8px 32px rgba(0,0,0,0.4);
|
|
67777
67818
|
transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s;
|
|
67778
|
-
opacity: 0; pointer-events: none;
|
|
67819
|
+
opacity: 0; pointer-events: none; white-space: nowrap;
|
|
67779
67820
|
}
|
|
67780
|
-
.select-bar.visible { transform:
|
|
67781
|
-
.select-bar-spacer { height: 72px; }
|
|
67821
|
+
.select-bar-wrap.visible .select-bar { transform: translateY(0); opacity: 1; pointer-events: all; }
|
|
67782
67822
|
.select-count { font-size: 13px; font-weight: 600; margin-right: 8px; }
|
|
67783
67823
|
.bar-btn {
|
|
67784
67824
|
height: 36px; padding: 0 14px; border: none; border-radius: 30px;
|
|
@@ -67817,8 +67857,6 @@ var pendingCall = {
|
|
|
67817
67857
|
args: null,
|
|
67818
67858
|
};
|
|
67819
67859
|
var selected = new Set();
|
|
67820
|
-
var filterQuery = "";
|
|
67821
|
-
var aspectFilter = "";
|
|
67822
67860
|
var app = new MCPApp({ name: "Cloudinary Asset Gallery", version: "1.0.0" });
|
|
67823
67861
|
setupHostContext(app);
|
|
67824
67862
|
|
|
@@ -67842,33 +67880,13 @@ function showToast(msg) {
|
|
|
67842
67880
|
_toastTimer = setTimeout(function() { t.classList.remove("show"); }, 2000);
|
|
67843
67881
|
}
|
|
67844
67882
|
|
|
67845
|
-
function getAspect(r) {
|
|
67846
|
-
if (!r.width || !r.height) return "";
|
|
67847
|
-
var ratio = r.width / r.height;
|
|
67848
|
-
if (ratio > 1.1) return "landscape";
|
|
67849
|
-
if (ratio < 0.9) return "portrait";
|
|
67850
|
-
return "square";
|
|
67851
|
-
}
|
|
67852
|
-
|
|
67853
|
-
function highlightText(text, query) {
|
|
67854
|
-
if (!query) return esc(text);
|
|
67855
|
-
var lo = text.toLowerCase();
|
|
67856
|
-
var idx = lo.indexOf(query);
|
|
67857
|
-
if (idx === -1) return esc(text);
|
|
67858
|
-
return esc(text.slice(0, idx))
|
|
67859
|
-
+ "<mark>" + esc(text.slice(idx, idx + query.length)) + "</mark>"
|
|
67860
|
-
+ esc(text.slice(idx + query.length));
|
|
67861
|
-
}
|
|
67862
|
-
|
|
67863
67883
|
function updateSelectBar() {
|
|
67864
|
-
var
|
|
67884
|
+
var wrap = document.getElementById("select-bar-wrap");
|
|
67865
67885
|
var countEl = document.getElementById("select-count");
|
|
67866
|
-
if (!
|
|
67886
|
+
if (!wrap || !countEl) return;
|
|
67867
67887
|
var n = selected.size;
|
|
67868
67888
|
countEl.textContent = n + " selected";
|
|
67869
|
-
|
|
67870
|
-
var spacer = document.getElementById("select-bar-spacer");
|
|
67871
|
-
if (spacer) spacer.style.display = n > 0 ? "" : "none";
|
|
67889
|
+
wrap.classList.toggle("visible", n > 0);
|
|
67872
67890
|
var btn = document.getElementById("select-all-btn");
|
|
67873
67891
|
if (btn) {
|
|
67874
67892
|
var visible = getVisibleIndices();
|
|
@@ -67935,11 +67953,9 @@ function copyAssetUrl(type, idx) {
|
|
|
67935
67953
|
var url = r.secure_url || r.url || "";
|
|
67936
67954
|
var copyUrl = type === "optimized" ? optimizedUrl(url, r) : url;
|
|
67937
67955
|
if (!copyUrl) return;
|
|
67938
|
-
|
|
67939
|
-
|
|
67940
|
-
|
|
67941
|
-
});
|
|
67942
|
-
} catch(e) { showError("Copy Failed", String(e)); }
|
|
67956
|
+
copyText(copyUrl).then(function() {
|
|
67957
|
+
showToast(type === "optimized" ? "\\u2728 Optimized URL copied" : "URL copied");
|
|
67958
|
+
}).catch(function(e) { showError("Copy Failed", e && e.message ? e.message : String(e)); });
|
|
67943
67959
|
}
|
|
67944
67960
|
|
|
67945
67961
|
function downloadOne(idx) {
|
|
@@ -67961,134 +67977,74 @@ function copySelectedUrls(type) {
|
|
|
67961
67977
|
urls.push(type === "optimized" ? optimizedUrl(url, r) : url);
|
|
67962
67978
|
});
|
|
67963
67979
|
if (!urls.length) return;
|
|
67964
|
-
|
|
67965
|
-
|
|
67966
|
-
|
|
67967
|
-
});
|
|
67968
|
-
} catch(e) { showError("Copy Failed", String(e)); }
|
|
67980
|
+
copyText(urls.join("\\n")).then(function() {
|
|
67981
|
+
showToast(urls.length + " " + (type === "optimized" ? "optimized " : "") + "URLs copied");
|
|
67982
|
+
}).catch(function(e) { showError("Copy Failed", e && e.message ? e.message : String(e)); });
|
|
67969
67983
|
}
|
|
67970
67984
|
|
|
67971
|
-
function downloadSelected() {
|
|
67972
|
-
|
|
67985
|
+
async function downloadSelected() {
|
|
67986
|
+
if (selected.size === 0) return;
|
|
67987
|
+
|
|
67988
|
+
var picks = [];
|
|
67973
67989
|
selected.forEach(function(i) {
|
|
67974
67990
|
var r = allResources[i];
|
|
67975
|
-
if (
|
|
67976
|
-
var url = r.secure_url || r.url || "";
|
|
67977
|
-
var dl = downloadUrl(url, r);
|
|
67978
|
-
if (dl) { app._rpc("ui/open-link", { url: dl }); count++; }
|
|
67991
|
+
if (r && r.public_id) picks.push(r);
|
|
67979
67992
|
});
|
|
67980
|
-
if (
|
|
67981
|
-
}
|
|
67993
|
+
if (!picks.length) return;
|
|
67982
67994
|
|
|
67983
|
-
|
|
67984
|
-
|
|
67985
|
-
|
|
67986
|
-
|
|
67987
|
-
|
|
67988
|
-
|
|
67995
|
+
var requestBody = {
|
|
67996
|
+
mode: "create",
|
|
67997
|
+
target_format: "zip",
|
|
67998
|
+
keep_derived: true,
|
|
67999
|
+
target_public_id: "mcp-gallery-archive-" + Date.now(),
|
|
68000
|
+
fully_qualified_public_ids: picks.map(function(r) {
|
|
68001
|
+
return (r.resource_type || "image") + "/" + (r.type || "upload") + "/" + r.public_id;
|
|
68002
|
+
}),
|
|
68003
|
+
};
|
|
67989
68004
|
|
|
67990
|
-
var
|
|
67991
|
-
|
|
68005
|
+
var btn = document.getElementById("bar-download");
|
|
68006
|
+
var origLabel = btn ? btn.innerHTML : "";
|
|
68007
|
+
if (btn) { btn.innerHTML = "Creating archive\\u2026"; btn.disabled = true; }
|
|
67992
68008
|
|
|
67993
|
-
|
|
67994
|
-
|
|
67995
|
-
|
|
68009
|
+
try {
|
|
68010
|
+
var res = await app.callServerTool({
|
|
68011
|
+
name: "generate-archive",
|
|
68012
|
+
arguments: {
|
|
68013
|
+
resource_type: "all",
|
|
68014
|
+
RequestBody: requestBody,
|
|
68015
|
+
},
|
|
68016
|
+
});
|
|
67996
68017
|
|
|
67997
|
-
|
|
67998
|
-
|
|
67999
|
-
|
|
68000
|
-
|
|
68001
|
-
|
|
68018
|
+
var data = ingestResult(res);
|
|
68019
|
+
if (data && (data._error || data._parseError)) {
|
|
68020
|
+
showError("Archive Failed", unwrapApiError(data._message));
|
|
68021
|
+
return;
|
|
68022
|
+
}
|
|
68023
|
+
var archiveUrl = data && (data.secure_url || data.url);
|
|
68024
|
+
if (!archiveUrl) {
|
|
68025
|
+
showError("Archive Failed", "No delivery URL returned.");
|
|
68026
|
+
return;
|
|
68027
|
+
}
|
|
68028
|
+
try { await copyText(archiveUrl); } catch (e) { /* ignore */ }
|
|
68029
|
+
app._rpc("ui/open-link", { url: archiveUrl });
|
|
68030
|
+
showToast("Archive saved as raw in Cloudinary \\u2014 opening URL (" + picks.length + " asset" + (picks.length > 1 ? "s" : "") + ")");
|
|
68031
|
+
} catch (e) {
|
|
68032
|
+
showError("Archive Failed", unwrapApiError(e && e.message ? e.message : String(e)));
|
|
68033
|
+
} finally {
|
|
68034
|
+
if (btn) { btn.innerHTML = origLabel; btn.disabled = false; }
|
|
68035
|
+
}
|
|
68036
|
+
}
|
|
68002
68037
|
|
|
68003
|
-
|
|
68004
|
-
|
|
68005
|
-
|
|
68006
|
-
|
|
68007
|
-
|
|
68008
|
-
|
|
68009
|
-
|
|
68010
|
-
|
|
68011
|
-
|
|
68012
|
-
|
|
68013
|
-
var tagsEl = document.getElementById("tags-overlay-" + i);
|
|
68014
|
-
if (tagsEl && tags.length) {
|
|
68015
|
-
var maxOv = 3;
|
|
68016
|
-
var matchedTags = [];
|
|
68017
|
-
var otherTags = [];
|
|
68018
|
-
for (var ti = 0; ti < tags.length; ti++) {
|
|
68019
|
-
var isMatch = filterQuery && tags[ti].toLowerCase().indexOf(filterQuery) !== -1;
|
|
68020
|
-
if (isMatch) matchedTags.push(tags[ti]);
|
|
68021
|
-
else otherTags.push(tags[ti]);
|
|
68022
|
-
}
|
|
68023
|
-
var shown = matchedTags.slice();
|
|
68024
|
-
var remaining = maxOv - shown.length;
|
|
68025
|
-
if (remaining > 0) shown = shown.concat(otherTags.slice(0, remaining));
|
|
68026
|
-
var hidden = tags.length - shown.length;
|
|
68027
|
-
var hiddenTags = tags.filter(function(t) { return shown.indexOf(t) === -1; });
|
|
68028
|
-
tagsEl.innerHTML = shown.map(function(t) {
|
|
68029
|
-
var matched = filterQuery && t.toLowerCase().indexOf(filterQuery) !== -1;
|
|
68030
|
-
return '<span class="tag-overlay' + (matched ? ' tag-match' : '') + '">' + highlightText(t, filterQuery) + '</span>';
|
|
68031
|
-
}).join("") + (hidden > 0 ? '<span class="tag-overlay" title="' + esc(hiddenTags.join(", ")) + '">+' + hidden + '</span>' : '');
|
|
68032
|
-
}
|
|
68033
|
-
|
|
68034
|
-
if (match) visibleCount++;
|
|
68035
|
-
}
|
|
68036
|
-
|
|
68037
|
-
var badge = document.getElementById("count-badge");
|
|
68038
|
-
if (badge) {
|
|
68039
|
-
badge.textContent = anyFilter
|
|
68040
|
-
? visibleCount + " of " + allResources.length
|
|
68041
|
-
: allResources.length + (lastCursor ? "+" : "") + " items";
|
|
68042
|
-
}
|
|
68043
|
-
|
|
68044
|
-
var noRes = document.getElementById("no-results");
|
|
68045
|
-
if (visibleCount === 0 && anyFilter) {
|
|
68046
|
-
if (!noRes && grid) {
|
|
68047
|
-
noRes = document.createElement("div");
|
|
68048
|
-
noRes.id = "no-results";
|
|
68049
|
-
noRes.className = "no-results";
|
|
68050
|
-
grid.appendChild(noRes);
|
|
68051
|
-
}
|
|
68052
|
-
if (noRes) noRes.textContent = "No results" + (filterQuery ? ' for "' + filterQuery + '"' : "") + (aspectFilter ? " in " + aspectFilter + " images" : "");
|
|
68053
|
-
} else if (noRes) {
|
|
68054
|
-
noRes.remove();
|
|
68055
|
-
}
|
|
68056
|
-
}
|
|
68057
|
-
|
|
68058
|
-
function clearFilter() {
|
|
68059
|
-
var input = document.getElementById("filter-input");
|
|
68060
|
-
if (input) input.value = "";
|
|
68061
|
-
aspectFilter = "";
|
|
68062
|
-
var label = document.getElementById("aspect-btn-label");
|
|
68063
|
-
if (label) label.textContent = "All orientations";
|
|
68064
|
-
document.querySelectorAll(".aspect-option").forEach(function(o) {
|
|
68065
|
-
o.classList.toggle("selected", o.getAttribute("data-value") === "");
|
|
68066
|
-
});
|
|
68067
|
-
handleFilter();
|
|
68068
|
-
}
|
|
68069
|
-
|
|
68070
|
-
function toggleAspectMenu(e) {
|
|
68071
|
-
e.stopPropagation();
|
|
68072
|
-
var btn = document.getElementById("aspect-btn");
|
|
68073
|
-
var menu = document.getElementById("aspect-menu");
|
|
68074
|
-
if (!btn || !menu) return;
|
|
68075
|
-
var open = menu.classList.toggle("open");
|
|
68076
|
-
btn.classList.toggle("open", open);
|
|
68077
|
-
}
|
|
68078
|
-
|
|
68079
|
-
function selectAspect(val) {
|
|
68080
|
-
aspectFilter = val;
|
|
68081
|
-
var labels = { "": "All orientations", landscape: "Landscape", portrait: "Portrait", square: "Square" };
|
|
68082
|
-
var label = document.getElementById("aspect-btn-label");
|
|
68083
|
-
if (label) label.textContent = labels[aspectFilter] || "All orientations";
|
|
68084
|
-
document.querySelectorAll(".aspect-option").forEach(function(o) {
|
|
68085
|
-
o.classList.toggle("selected", o.getAttribute("data-value") === aspectFilter);
|
|
68086
|
-
});
|
|
68087
|
-
var menu = document.getElementById("aspect-menu");
|
|
68088
|
-
var btn = document.getElementById("aspect-btn");
|
|
68089
|
-
if (menu) menu.classList.remove("open");
|
|
68090
|
-
if (btn) btn.classList.remove("open");
|
|
68091
|
-
handleFilter();
|
|
68038
|
+
function unwrapApiError(raw) {
|
|
68039
|
+
if (!raw) return "Unknown error.";
|
|
68040
|
+
var msg = String(raw);
|
|
68041
|
+
try {
|
|
68042
|
+
if (msg.charAt(0) === "{") {
|
|
68043
|
+
var parsed = JSON.parse(msg);
|
|
68044
|
+
msg = (parsed && parsed.error && parsed.error.message) || msg;
|
|
68045
|
+
}
|
|
68046
|
+
} catch (e) { /* keep raw */ }
|
|
68047
|
+
return msg;
|
|
68092
68048
|
}
|
|
68093
68049
|
|
|
68094
68050
|
function render() {
|
|
@@ -68108,41 +68064,12 @@ function render() {
|
|
|
68108
68064
|
h += '<h1>Results</h1>';
|
|
68109
68065
|
h += '<span class="count-badge" id="count-badge">' + allResources.length + (lastCursor ? "+" : "") + ' items</span>';
|
|
68110
68066
|
h += '</div>';
|
|
68111
|
-
h += '<div style="display:flex;align-items:center;gap:8px">';
|
|
68112
|
-
h += '<button class="
|
|
68113
|
-
h += '<button class="
|
|
68067
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:8px">';
|
|
68068
|
+
h += '<button class="icon-btn" id="select-all-btn">Select all</button>';
|
|
68069
|
+
h += '<button class="icon-btn icon-only" id="refresh-gallery" title="Refresh">' + IC.refresh + '</button>';
|
|
68114
68070
|
h += '</div>';
|
|
68115
68071
|
h += '</div>';
|
|
68116
68072
|
|
|
68117
|
-
// Filter bar
|
|
68118
|
-
h += '<div class="filter-row">';
|
|
68119
|
-
h += '<div class="filter-text-wrap">';
|
|
68120
|
-
h += '<span class="filter-icon"><svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="6.5" cy="6.5" r="4.5"/><path d="M10.5 10.5l3 3"/></svg></span>';
|
|
68121
|
-
h += '<input class="filter-input" id="filter-input" type="text" placeholder="Filter by filename or tag\\u2026" autocomplete="off" spellcheck="false">';
|
|
68122
|
-
h += '<button class="filter-clear" id="filter-clear">\\u2715</button>';
|
|
68123
|
-
h += '</div>';
|
|
68124
|
-
h += '<div class="aspect-dropdown" id="aspect-dropdown">';
|
|
68125
|
-
h += '<button class="aspect-btn" id="aspect-btn">';
|
|
68126
|
-
h += '<span id="aspect-btn-label">All orientations</span>';
|
|
68127
|
-
h += '<svg class="aspect-btn-chevron" width="11" height="11" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="2,4 6,8 10,4"/></svg>';
|
|
68128
|
-
h += '</button>';
|
|
68129
|
-
h += '<div class="aspect-menu" id="aspect-menu">';
|
|
68130
|
-
var aspects = [
|
|
68131
|
-
{ val: "", label: "All orientations", icon: '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="1" y="1" width="12" height="12" rx="1.5"/></svg>' },
|
|
68132
|
-
{ val: "landscape", label: "Landscape", icon: '<svg width="14" height="10" viewBox="0 0 14 10" fill="none" stroke="currentColor" stroke-width="1.5"><rect x=".75" y=".75" width="12.5" height="8.5" rx="1.5"/></svg>' },
|
|
68133
|
-
{ val: "portrait", label: "Portrait", icon: '<svg width="10" height="14" viewBox="0 0 10 14" fill="none" stroke="currentColor" stroke-width="1.5"><rect x=".75" y=".75" width="8.5" height="12.5" rx="1.5"/></svg>' },
|
|
68134
|
-
{ val: "square", label: "Square", icon: '<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5"><rect x=".75" y=".75" width="10.5" height="10.5" rx="1.5"/></svg>' },
|
|
68135
|
-
];
|
|
68136
|
-
for (var ai = 0; ai < aspects.length; ai++) {
|
|
68137
|
-
var ao = aspects[ai];
|
|
68138
|
-
h += '<div class="aspect-option' + (ao.val === aspectFilter ? ' selected' : '') + '" data-value="' + ao.val + '">';
|
|
68139
|
-
h += '<span class="aspect-opt-icon">' + ao.icon + '</span>';
|
|
68140
|
-
h += ao.label;
|
|
68141
|
-
h += '<svg class="aspect-check" width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><polyline points="2,6 5,9 10,3"/></svg>';
|
|
68142
|
-
h += '</div>';
|
|
68143
|
-
}
|
|
68144
|
-
h += '</div></div></div>';
|
|
68145
|
-
|
|
68146
68073
|
// Grid
|
|
68147
68074
|
h += '<div class="grid" id="gallery-grid">';
|
|
68148
68075
|
for (var i = 0; i < allResources.length; i++) {
|
|
@@ -68191,8 +68118,8 @@ function render() {
|
|
|
68191
68118
|
if (url) {
|
|
68192
68119
|
h += '<div class="card-actions">';
|
|
68193
68120
|
h += '<button class="action-btn act-original" data-copy-original="' + i + '">Copy URL</button>';
|
|
68194
|
-
if (rt !== "raw") h += '<button class="action-btn act-optimized" data-copy-optimized="' + i + '"
|
|
68195
|
-
h += '<button class="action-btn act-download" data-download="' + i + '" title="Download"
|
|
68121
|
+
if (rt !== "raw") h += '<button class="action-btn act-optimized" data-copy-optimized="' + i + '">' + IC.zap + ' Optimized</button>';
|
|
68122
|
+
h += '<button class="action-btn act-download" data-download="' + i + '" title="Download">' + IC.arrowDown + '</button>';
|
|
68196
68123
|
h += '</div>';
|
|
68197
68124
|
}
|
|
68198
68125
|
|
|
@@ -68239,24 +68166,24 @@ function render() {
|
|
|
68239
68166
|
h += "</div>";
|
|
68240
68167
|
}
|
|
68241
68168
|
|
|
68242
|
-
//
|
|
68243
|
-
h += '<div class="select-bar-
|
|
68244
|
-
|
|
68245
|
-
// Multi-select bar
|
|
68169
|
+
// Multi-select bar (sticky, in-flow wrapper so iframe sizing stays truthful)
|
|
68170
|
+
h += '<div class="select-bar-wrap" id="select-bar-wrap">';
|
|
68246
68171
|
h += '<div class="select-bar" id="select-bar">';
|
|
68247
68172
|
h += '<span class="select-count" id="select-count">0 selected</span>';
|
|
68248
68173
|
h += '<div class="bar-divider"></div>';
|
|
68249
|
-
h += '<button class="bar-btn bar-primary" id="bar-copy-optimized" style="display:none"
|
|
68174
|
+
h += '<button class="bar-btn bar-primary" id="bar-copy-optimized" style="display:none">' + IC.zap + ' Copy Optimized</button>';
|
|
68250
68175
|
h += '<button class="bar-btn bar-secondary" id="bar-copy-original">Copy Original</button>';
|
|
68251
|
-
h += '<button class="bar-btn bar-secondary" id="bar-download"
|
|
68176
|
+
h += '<button class="bar-btn bar-secondary" id="bar-download">' + IC.arrowDown + ' Download Selected</button>';
|
|
68252
68177
|
h += '<div class="bar-divider"></div>';
|
|
68253
|
-
h += '<button class="bar-btn bar-ghost" id="bar-clear"
|
|
68178
|
+
h += '<button class="bar-btn bar-ghost" id="bar-clear">' + IC.x + '</button>';
|
|
68179
|
+
h += '</div>';
|
|
68254
68180
|
h += '</div>';
|
|
68255
68181
|
|
|
68256
68182
|
// Toast
|
|
68257
68183
|
h += '<div class="gallery-toast" id="gallery-toast"></div>';
|
|
68258
68184
|
|
|
68259
68185
|
root.innerHTML = h;
|
|
68186
|
+
renderThemeToggle();
|
|
68260
68187
|
|
|
68261
68188
|
// Re-apply selection state
|
|
68262
68189
|
selected.forEach(function(i) {
|
|
@@ -68290,37 +68217,16 @@ function attachEvents() {
|
|
|
68290
68217
|
_eventsAttached = true;
|
|
68291
68218
|
var root = document.getElementById("app");
|
|
68292
68219
|
|
|
68293
|
-
root.addEventListener("input", function(e) {
|
|
68294
|
-
if (e.target && e.target.id === "filter-input") handleFilter();
|
|
68295
|
-
});
|
|
68296
|
-
|
|
68297
|
-
document.addEventListener("click", function(e) {
|
|
68298
|
-
var dd = document.getElementById("aspect-dropdown");
|
|
68299
|
-
if (dd && !dd.contains(e.target)) {
|
|
68300
|
-
var menu = document.getElementById("aspect-menu");
|
|
68301
|
-
var btn = document.getElementById("aspect-btn");
|
|
68302
|
-
if (menu) menu.classList.remove("open");
|
|
68303
|
-
if (btn) btn.classList.remove("open");
|
|
68304
|
-
}
|
|
68305
|
-
});
|
|
68306
|
-
|
|
68307
68220
|
root.addEventListener("click", function(e) {
|
|
68308
68221
|
var el = e.target;
|
|
68309
68222
|
while (el && el !== root) {
|
|
68310
68223
|
if (el.id === "load-more-btn") { loadMore(); return; }
|
|
68311
68224
|
if (el.id === "refresh-gallery") { refreshGallery(); return; }
|
|
68312
68225
|
if (el.id === "select-all-btn") { toggleSelectAll(); return; }
|
|
68313
|
-
if (el.id === "filter-clear") { clearFilter(); return; }
|
|
68314
68226
|
if (el.id === "bar-copy-optimized") { copySelectedUrls("optimized"); return; }
|
|
68315
68227
|
if (el.id === "bar-copy-original") { copySelectedUrls("original"); return; }
|
|
68316
68228
|
if (el.id === "bar-download") { downloadSelected(); return; }
|
|
68317
68229
|
if (el.id === "bar-clear") { clearSelection(); return; }
|
|
68318
|
-
if (el.id === "aspect-btn" || el.parentElement && el.parentElement.id === "aspect-btn") {
|
|
68319
|
-
toggleAspectMenu(e); return;
|
|
68320
|
-
}
|
|
68321
|
-
if (el.classList && el.classList.contains("aspect-option")) {
|
|
68322
|
-
selectAspect(el.getAttribute("data-value") || ""); return;
|
|
68323
|
-
}
|
|
68324
68230
|
if (el.dataset && el.dataset.copyOriginal != null) {
|
|
68325
68231
|
e.stopPropagation();
|
|
68326
68232
|
copyAssetUrl("original", parseInt(el.dataset.copyOriginal, 10)); return;
|
|
@@ -68481,6 +68387,7 @@ function showFetchPrompt() {
|
|
|
68481
68387
|
h += '<button class="prompt-btn prompt-btn-primary" id="fetch-direct-btn">Fetch Directly</button>';
|
|
68482
68388
|
h += "</div></div>";
|
|
68483
68389
|
root.innerHTML = h;
|
|
68390
|
+
renderThemeToggle();
|
|
68484
68391
|
document.getElementById("fetch-direct-btn").addEventListener("click", function() { fetchDirect(); });
|
|
68485
68392
|
}
|
|
68486
68393
|
|
|
@@ -68500,6 +68407,9 @@ async function fetchDirect() {
|
|
|
68500
68407
|
console.log(LOG_PREFIX, "fetchDirect ->", name);
|
|
68501
68408
|
|
|
68502
68409
|
document.getElementById("app").innerHTML = '<div class="status">Fetching assets\\u2026</div>';
|
|
68410
|
+
requestAnimationFrame(function() {
|
|
68411
|
+
app.reportSize(Math.max(document.documentElement.scrollHeight, MIN_HEIGHT));
|
|
68412
|
+
});
|
|
68503
68413
|
try {
|
|
68504
68414
|
var res = await app.callServerTool({ name: name, arguments: args });
|
|
68505
68415
|
var data = ingestResult(res);
|
|
@@ -68551,6 +68461,7 @@ async function loadMore() {
|
|
|
68551
68461
|
function refreshGallery() {
|
|
68552
68462
|
allResources = [];
|
|
68553
68463
|
lastCursor = null;
|
|
68464
|
+
selected.clear();
|
|
68554
68465
|
fetchDirect();
|
|
68555
68466
|
}
|
|
68556
68467
|
|
|
@@ -68558,7 +68469,6 @@ function refreshGallery() {
|
|
|
68558
68469
|
document.addEventListener("keydown", function(e) {
|
|
68559
68470
|
if (e.key === "Escape") {
|
|
68560
68471
|
if (document.querySelector(".modal-overlay")) { closeModal(); return; }
|
|
68561
|
-
if (filterQuery || aspectFilter) { clearFilter(); return; }
|
|
68562
68472
|
if (selected.size > 0) { clearSelection(); return; }
|
|
68563
68473
|
}
|
|
68564
68474
|
});
|
|
@@ -68590,6 +68500,7 @@ ${GALLERY_CSS}
|
|
|
68590
68500
|
<div class="gallery-toast" id="gallery-toast"></div>
|
|
68591
68501
|
|
|
68592
68502
|
<script>
|
|
68503
|
+
${SHARED_JS_ICONS}
|
|
68593
68504
|
${SHARED_JS_MCP_CLIENT}
|
|
68594
68505
|
${SHARED_JS_HELPERS}
|
|
68595
68506
|
${SHARED_JS_TOOLTIPS}
|
|
@@ -68643,16 +68554,6 @@ var ASSET_DETAILS_CSS = `
|
|
|
68643
68554
|
padding: 2px 7px; border-radius: 4px; border: 1px solid var(--cld-border);
|
|
68644
68555
|
}
|
|
68645
68556
|
|
|
68646
|
-
.open-link {
|
|
68647
|
-
padding: 6px 14px; border-radius: var(--cld-radius-sm);
|
|
68648
|
-
font-size: 12px; font-weight: 500; cursor: pointer;
|
|
68649
|
-
border: 1px solid var(--cld-accent); background: transparent;
|
|
68650
|
-
color: var(--cld-accent); font-family: inherit;
|
|
68651
|
-
transition: background 0.15s;
|
|
68652
|
-
white-space: nowrap; flex-shrink: 0;
|
|
68653
|
-
}
|
|
68654
|
-
.open-link:hover { background: var(--cld-accent-bg); }
|
|
68655
|
-
|
|
68656
68557
|
.hero-container {
|
|
68657
68558
|
position: relative; margin-bottom: var(--cld-sp-md);
|
|
68658
68559
|
border-radius: var(--cld-radius); overflow: hidden;
|
|
@@ -68713,9 +68614,9 @@ function renderPage(r) {
|
|
|
68713
68614
|
if (dur) h += '<span class="pill">' + dur + "</span>";
|
|
68714
68615
|
if (size) h += '<span class="pill">' + size + "</span>";
|
|
68715
68616
|
h += "</div></div>";
|
|
68716
|
-
h += '<div style="display:flex;gap:
|
|
68717
|
-
h += '<button class="
|
|
68718
|
-
|
|
68617
|
+
h += '<div id="header-actions" style="display:flex;gap:8px;flex-shrink:0;align-items:center">';
|
|
68618
|
+
if (url) h += '<button class="icon-btn" id="open-asset">Open</button>';
|
|
68619
|
+
h += '<button class="icon-btn icon-only" id="refresh-asset" title="Refresh">' + IC.refresh + '</button>';
|
|
68719
68620
|
h += "</div>";
|
|
68720
68621
|
h += "</div>";
|
|
68721
68622
|
|
|
@@ -68757,6 +68658,7 @@ function renderPage(r) {
|
|
|
68757
68658
|
h += "</div>";
|
|
68758
68659
|
|
|
68759
68660
|
root.innerHTML = h;
|
|
68661
|
+
renderThemeToggle();
|
|
68760
68662
|
|
|
68761
68663
|
// Event delegation
|
|
68762
68664
|
root.addEventListener("click", function handler(e) {
|
|
@@ -68802,6 +68704,7 @@ function showFetchPrompt() {
|
|
|
68802
68704
|
h += '<button class="prompt-btn prompt-btn-primary" id="fetch-direct-btn">Fetch Directly</button>';
|
|
68803
68705
|
h += "</div></div>";
|
|
68804
68706
|
root.innerHTML = h;
|
|
68707
|
+
renderThemeToggle();
|
|
68805
68708
|
document.getElementById("fetch-direct-btn").addEventListener("click", function() { fetchDirect(); });
|
|
68806
68709
|
}
|
|
68807
68710
|
|
|
@@ -68883,6 +68786,7 @@ ${ASSET_DETAILS_CSS}
|
|
|
68883
68786
|
<div id="app"><div class="status">Loading asset details…</div></div>
|
|
68884
68787
|
|
|
68885
68788
|
<script>
|
|
68789
|
+
${SHARED_JS_ICONS}
|
|
68886
68790
|
${SHARED_JS_MCP_CLIENT}
|
|
68887
68791
|
${SHARED_JS_HELPERS}
|
|
68888
68792
|
${SHARED_JS_TOOLTIPS}
|
|
@@ -69122,15 +69026,8 @@ var uploadJsonSchema, rtJsonSchema, allSchemaProperties, rtCopy, SCHEMA_JSON, UP
|
|
|
69122
69026
|
.upload-header h1 {
|
|
69123
69027
|
font-size: var(--cld-font-sm); font-weight: 600; color: var(--cld-text);
|
|
69124
69028
|
}
|
|
69125
|
-
.upload-header-icon {
|
|
69126
|
-
.upload-header {
|
|
69127
|
-
.back-link {
|
|
69128
|
-
position: absolute; top: -2px; right: 0;
|
|
69129
|
-
background: none; border: none; cursor: pointer;
|
|
69130
|
-
color: var(--cld-accent); font-size: var(--cld-font-xs);
|
|
69131
|
-
padding: 2px 6px; border-radius: 4px;
|
|
69132
|
-
}
|
|
69133
|
-
.back-link:hover { text-decoration: underline; background: var(--cld-accent-bg); }
|
|
69029
|
+
.upload-header-icon { display: flex; align-items: center; justify-content: center; }
|
|
69030
|
+
.upload-header-icon svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
|
69134
69031
|
|
|
69135
69032
|
.upload-result .detail-section { padding: 14px 16px; }
|
|
69136
69033
|
.upload-result .detail-section:first-child { padding-top: 0; }
|
|
@@ -69581,16 +69478,18 @@ function renderPicker() {
|
|
|
69581
69478
|
var h = "";
|
|
69582
69479
|
|
|
69583
69480
|
h += '<div class="upload-header">';
|
|
69481
|
+
h += '<span class="upload-header-icon icon-accent">' + IC.uploadCloud + '</span>';
|
|
69482
|
+
h += "<h1>Upload to Cloudinary</h1>";
|
|
69483
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto">';
|
|
69584
69484
|
if (lastResult) {
|
|
69585
|
-
h += '<button class="
|
|
69485
|
+
h += '<button class="icon-btn" id="back-to-result-btn">' + IC.chevronLeft + ' Back</button>';
|
|
69586
69486
|
}
|
|
69587
|
-
h += '
|
|
69588
|
-
h += "<h1>Upload to Cloudinary</h1>";
|
|
69487
|
+
h += '</div>';
|
|
69589
69488
|
h += "</div>";
|
|
69590
69489
|
|
|
69591
69490
|
if (stagedFile) {
|
|
69592
69491
|
h += '<div class="upload-staged">';
|
|
69593
|
-
h += '<div class="upload-staged-icon"
|
|
69492
|
+
h += '<div class="upload-staged-icon">' + IC.file + '</div>';
|
|
69594
69493
|
h += '<div class="upload-staged-info">';
|
|
69595
69494
|
h += '<div class="upload-staged-name">' + esc(stagedFile.name) + "</div>";
|
|
69596
69495
|
if (stagedFile.size) {
|
|
@@ -69601,11 +69500,11 @@ function renderPicker() {
|
|
|
69601
69500
|
h += '<div class="upload-staged-meta">Remote URL</div>';
|
|
69602
69501
|
}
|
|
69603
69502
|
h += "</div>";
|
|
69604
|
-
h += '<button class="upload-staged-clear" id="clear-staged-btn" title="Remove"
|
|
69503
|
+
h += '<button class="upload-staged-clear icon-btn icon-only" id="clear-staged-btn" title="Remove">' + IC.x + '</button>';
|
|
69605
69504
|
h += "</div>";
|
|
69606
69505
|
} else {
|
|
69607
69506
|
h += '<div class="upload-zone" id="drop-zone">';
|
|
69608
|
-
h += '<div class="upload-zone-icon"
|
|
69507
|
+
h += '<div class="upload-zone-icon">' + IC.folderOpen + '</div>';
|
|
69609
69508
|
h += '<div class="upload-zone-text">Drag & drop a file here</div>';
|
|
69610
69509
|
h += '<div class="upload-zone-hint">Images, videos, PDFs, and other files up to 60 MB</div>';
|
|
69611
69510
|
h += '<button class="upload-zone-btn" id="browse-btn">Browse Files</button>';
|
|
@@ -69629,6 +69528,7 @@ function renderPicker() {
|
|
|
69629
69528
|
}
|
|
69630
69529
|
|
|
69631
69530
|
root.innerHTML = h;
|
|
69531
|
+
renderThemeToggle();
|
|
69632
69532
|
|
|
69633
69533
|
var backBtn = document.getElementById("back-to-result-btn");
|
|
69634
69534
|
if (backBtn && lastResult) {
|
|
@@ -69708,12 +69608,13 @@ function renderUploading(name, meta) {
|
|
|
69708
69608
|
var h = "";
|
|
69709
69609
|
|
|
69710
69610
|
h += '<div class="upload-header">';
|
|
69711
|
-
h += '<span class="upload-header-icon"
|
|
69712
|
-
h +=
|
|
69611
|
+
h += '<span class="upload-header-icon icon-accent">' + IC.uploadCloud + '</span>';
|
|
69612
|
+
h += '<h1>Uploading…</h1>';
|
|
69613
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto"></div>';
|
|
69713
69614
|
h += "</div>";
|
|
69714
69615
|
|
|
69715
69616
|
h += '<div class="upload-preview">';
|
|
69716
|
-
h += '<div class="upload-preview-icon"
|
|
69617
|
+
h += '<div class="upload-preview-icon">' + IC.file + '</div>';
|
|
69717
69618
|
h += '<div class="upload-preview-info">';
|
|
69718
69619
|
h += '<div class="upload-preview-name">' + esc(name) + "</div>";
|
|
69719
69620
|
h += '<div class="upload-preview-meta">' + esc(meta) + "</div>";
|
|
@@ -69725,6 +69626,7 @@ function renderUploading(name, meta) {
|
|
|
69725
69626
|
h += "</div>";
|
|
69726
69627
|
|
|
69727
69628
|
root.innerHTML = h;
|
|
69629
|
+
renderThemeToggle();
|
|
69728
69630
|
animateProgress();
|
|
69729
69631
|
}
|
|
69730
69632
|
|
|
@@ -69778,7 +69680,7 @@ function renderUploadError(title, msg) {
|
|
|
69778
69680
|
var header = document.querySelector(".upload-header h1");
|
|
69779
69681
|
if (header) header.textContent = title;
|
|
69780
69682
|
var icon = document.querySelector(".upload-header-icon");
|
|
69781
|
-
if (icon) icon.
|
|
69683
|
+
if (icon) { icon.innerHTML = IC.alertTriangle; icon.className = "upload-header-icon icon-warning"; }
|
|
69782
69684
|
|
|
69783
69685
|
var safeMsg = esc(msg).replace(/\\n/g, "<br>");
|
|
69784
69686
|
var h = '<div class="upload-error-msg">' + safeMsg + "</div>";
|
|
@@ -69790,14 +69692,16 @@ function renderUploadError(title, msg) {
|
|
|
69790
69692
|
var root = document.getElementById("app");
|
|
69791
69693
|
var safeMsg = esc(msg).replace(/\\n/g, "<br>");
|
|
69792
69694
|
var h = '<div class="upload-header">';
|
|
69793
|
-
h += '<span class="upload-header-icon"
|
|
69695
|
+
h += '<span class="upload-header-icon icon-warning">' + IC.alertTriangle + '</span>';
|
|
69794
69696
|
h += "<h1>" + esc(title) + "</h1>";
|
|
69697
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto"></div>';
|
|
69795
69698
|
h += "</div>";
|
|
69796
69699
|
h += '<div class="upload-error-msg">' + safeMsg + "</div>";
|
|
69797
69700
|
h += '<div class="upload-another" style="margin-top:14px;text-align:center">';
|
|
69798
69701
|
h += '<button class="prompt-btn prompt-btn-primary" id="retry-upload-btn">Try from App</button>';
|
|
69799
69702
|
h += "</div>";
|
|
69800
69703
|
root.innerHTML = h;
|
|
69704
|
+
renderThemeToggle();
|
|
69801
69705
|
}
|
|
69802
69706
|
|
|
69803
69707
|
var btn = document.getElementById("retry-upload-btn");
|
|
@@ -69842,8 +69746,9 @@ function renderLocalFileNeeded(expectedName, errMsg) {
|
|
|
69842
69746
|
var classified = classifyFileError(errMsg);
|
|
69843
69747
|
var root = document.getElementById("app");
|
|
69844
69748
|
var h = '<div class="upload-header">';
|
|
69845
|
-
h += '<span class="upload-header-icon"
|
|
69749
|
+
h += '<span class="upload-header-icon icon-accent">' + IC.folderOpen + '</span>';
|
|
69846
69750
|
h += "<h1>" + esc(classified.title) + "</h1>";
|
|
69751
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto"></div>';
|
|
69847
69752
|
h += "</div>";
|
|
69848
69753
|
h += '<div class="prompt" style="margin-bottom:16px">';
|
|
69849
69754
|
h += '<div class="prompt-desc">The file <strong>' + esc(expectedName)
|
|
@@ -69858,13 +69763,14 @@ function renderLocalFileNeeded(expectedName, errMsg) {
|
|
|
69858
69763
|
}
|
|
69859
69764
|
h += "</div>";
|
|
69860
69765
|
h += '<div class="upload-zone" id="drop-zone">';
|
|
69861
|
-
h += '<div class="upload-zone-icon"
|
|
69766
|
+
h += '<div class="upload-zone-icon">' + IC.folderOpen + '</div>';
|
|
69862
69767
|
h += '<div class="upload-zone-text">Drop <strong>' + esc(expectedName) + "</strong> here</div>";
|
|
69863
69768
|
h += '<div class="upload-zone-hint">Or click to browse your files</div>';
|
|
69864
69769
|
h += '<button class="upload-zone-btn" id="browse-btn">Browse Files</button>';
|
|
69865
69770
|
h += '<input type="file" id="file-input" style="display:none">';
|
|
69866
69771
|
h += "</div>";
|
|
69867
69772
|
root.innerHTML = h;
|
|
69773
|
+
renderThemeToggle();
|
|
69868
69774
|
|
|
69869
69775
|
function onFileSelected(file) {
|
|
69870
69776
|
var reader = new FileReader();
|
|
@@ -69977,8 +69883,9 @@ function renderResult(r) {
|
|
|
69977
69883
|
var h = "";
|
|
69978
69884
|
|
|
69979
69885
|
h += '<div class="upload-header">';
|
|
69980
|
-
h += '<span class="upload-header-icon
|
|
69886
|
+
h += '<span class="upload-header-icon ' + (isPending ? "icon-accent" : "icon-success") + '">' + (isPending ? IC.clock : IC.checkCircle) + '</span>';
|
|
69981
69887
|
h += "<h1>" + (isPending ? "Upload Queued" : "Upload Complete") + "</h1>";
|
|
69888
|
+
h += '<div id="header-actions" style="display:flex;align-items:center;gap:6px;margin-left:auto"></div>';
|
|
69982
69889
|
h += "</div>";
|
|
69983
69890
|
|
|
69984
69891
|
h += '<div class="upload-result">';
|
|
@@ -70039,6 +69946,7 @@ function renderResult(r) {
|
|
|
70039
69946
|
h += "</div></div>";
|
|
70040
69947
|
|
|
70041
69948
|
root.innerHTML = h;
|
|
69949
|
+
renderThemeToggle();
|
|
70042
69950
|
|
|
70043
69951
|
root.addEventListener("click", function handler(e) {
|
|
70044
69952
|
var el = e.target;
|
|
@@ -70173,6 +70081,7 @@ ${UPLOAD_CSS}
|
|
|
70173
70081
|
<div id="app"><div class="status">Preparing upload…</div></div>
|
|
70174
70082
|
|
|
70175
70083
|
<script>
|
|
70084
|
+
${SHARED_JS_ICONS}
|
|
70176
70085
|
${SHARED_JS_MCP_CLIENT}
|
|
70177
70086
|
${SHARED_JS_HELPERS}
|
|
70178
70087
|
${SHARED_JS_TOOLTIPS}
|
|
@@ -70192,7 +70101,12 @@ function appResourceContent(uri, html) {
|
|
|
70192
70101
|
uri: uri.toString(),
|
|
70193
70102
|
mimeType: MCP_APP_MIME_TYPE,
|
|
70194
70103
|
text: html,
|
|
70195
|
-
_meta: {
|
|
70104
|
+
_meta: {
|
|
70105
|
+
ui: {
|
|
70106
|
+
csp: { resourceDomains: CSP_RESOURCE_DOMAINS },
|
|
70107
|
+
permissions: { clipboardWrite: {} }
|
|
70108
|
+
}
|
|
70109
|
+
}
|
|
70196
70110
|
}]
|
|
70197
70111
|
};
|
|
70198
70112
|
}
|
|
@@ -74103,7 +74017,7 @@ A report on the status of product environment usage, including storage, credits,
|
|
|
74103
74017
|
function createMCPServer(deps) {
|
|
74104
74018
|
const server = new McpServer({
|
|
74105
74019
|
name: "CloudinaryAssetMgmt",
|
|
74106
|
-
version: "0.9.
|
|
74020
|
+
version: "0.9.3"
|
|
74107
74021
|
});
|
|
74108
74022
|
const getClient = deps.getSDK || (() => new CloudinaryAssetMgmtCore({
|
|
74109
74023
|
security: deps.security,
|
|
@@ -74376,8 +74290,13 @@ This tool creates actual derived assets on Cloudinary using the explicit API.`
|
|
|
74376
74290
|
|
|
74377
74291
|
// src/landing-page.ts
|
|
74378
74292
|
function landingPageExpress(req, res) {
|
|
74379
|
-
const
|
|
74380
|
-
|
|
74293
|
+
const proto = req.get("x-forwarded-proto")?.split(",")[0]?.trim() || req.protocol;
|
|
74294
|
+
const host = req.get("host");
|
|
74295
|
+
if (!host) {
|
|
74296
|
+
res.status(400).send("Missing Host header");
|
|
74297
|
+
return;
|
|
74298
|
+
}
|
|
74299
|
+
res.type("html").send(landingPageHTML(`${proto}://${host}`));
|
|
74381
74300
|
}
|
|
74382
74301
|
function landingPageHTML(origin) {
|
|
74383
74302
|
const o = origin;
|
|
@@ -75280,7 +75199,7 @@ http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "
|
|
|
75280
75199
|
<h1>Instructions</h1>
|
|
75281
75200
|
<p>One-click installation for Claude Desktop users</p>
|
|
75282
75201
|
<div class="instruction-item">
|
|
75283
|
-
<a href="https://github.com/cloudinary/asset-management-mcp/releases/download/v0.9.
|
|
75202
|
+
<a href="https://github.com/cloudinary/asset-management-mcp/releases/download/v0.9.3/mcp-server.mcpb" download="mcp-server.mcpb" class="action-button header-action" style="display: inline-flex; margin-bottom: 16px;">
|
|
75284
75203
|
\uD83D\uDCE5 Download MCP Bundle
|
|
75285
75204
|
</a>
|
|
75286
75205
|
</div>
|
|
@@ -75442,7 +75361,7 @@ async function startStreamableHTTP(cliFlags) {
|
|
|
75442
75361
|
app.use((req, res, next) => {
|
|
75443
75362
|
res.header("Access-Control-Allow-Origin", "*");
|
|
75444
75363
|
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
75445
|
-
res.header("Access-Control-Allow-Headers", "
|
|
75364
|
+
res.header("Access-Control-Allow-Headers", "*");
|
|
75446
75365
|
if (req.method === "OPTIONS") {
|
|
75447
75366
|
res.sendStatus(204);
|
|
75448
75367
|
return;
|
|
@@ -77224,7 +77143,7 @@ var routes = ln({
|
|
|
77224
77143
|
var app = _e(routes, {
|
|
77225
77144
|
name: "mcp",
|
|
77226
77145
|
versionInfo: {
|
|
77227
|
-
currentVersion: "0.9.
|
|
77146
|
+
currentVersion: "0.9.3"
|
|
77228
77147
|
}
|
|
77229
77148
|
});
|
|
77230
77149
|
Yt(app, process4.argv.slice(2), buildContext(process4));
|
|
@@ -77232,5 +77151,5 @@ export {
|
|
|
77232
77151
|
app
|
|
77233
77152
|
};
|
|
77234
77153
|
|
|
77235
|
-
//# debugId=
|
|
77154
|
+
//# debugId=6C5BCA15F724A25664756E2164756E21
|
|
77236
77155
|
//# sourceMappingURL=mcp-server.js.map
|