@kolbo/mcp 1.30.9 → 1.31.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/package.json +1 -1
- package/src/apps/bridge.js +9 -1
- package/src/apps/html.js +1 -1
- package/src/apps/theme.js +14 -2
- package/src/apps/widgets/generation.js +36 -2
package/package.json
CHANGED
package/src/apps/bridge.js
CHANGED
|
@@ -106,8 +106,12 @@ const BRIDGE_JS = `
|
|
|
106
106
|
clearTimeout(sizeTimer);
|
|
107
107
|
sizeTimer = setTimeout(notifySize, delay || 120);
|
|
108
108
|
}
|
|
109
|
+
// With ResizeObserver present, attribute churn (class/style toggles) that
|
|
110
|
+
// actually changes layout is caught by RO on the card — observing attributes
|
|
111
|
+
// here would just re-fire on EVERY class/style write. Only watch attributes
|
|
112
|
+
// as a fallback when RO is unavailable.
|
|
109
113
|
new MutationObserver(function () { queueSize(120); })
|
|
110
|
-
.observe(document.documentElement, { childList: true, subtree: true, attributes:
|
|
114
|
+
.observe(document.documentElement, { childList: true, subtree: true, attributes: !window.ResizeObserver });
|
|
111
115
|
// DOM mutations don't fire when an <img>/<video> finishes loading and reflows
|
|
112
116
|
// the card — without this the host keeps the pre-image height and the card
|
|
113
117
|
// gets an inner scrollbar. ResizeObserver catches every layout change.
|
|
@@ -137,6 +141,10 @@ const BRIDGE_JS = `
|
|
|
137
141
|
updateModelContext: function (text) {
|
|
138
142
|
return request('ui/update-model-context', { content: [{ type: 'text', text: text }] });
|
|
139
143
|
},
|
|
144
|
+
// Resolves with the mode the host ACTUALLY granted ('inline'|'fullscreen'|'pip').
|
|
145
|
+
requestDisplayMode: function (mode) {
|
|
146
|
+
return request('ui/request-display-mode', { mode: mode });
|
|
147
|
+
},
|
|
140
148
|
notifySize: notifySize,
|
|
141
149
|
hostContext: function () { return hostContext; }
|
|
142
150
|
};
|
package/src/apps/html.js
CHANGED
|
@@ -17,7 +17,7 @@ function widgetPage({ title, body, script }) {
|
|
|
17
17
|
<title>${title}</title>
|
|
18
18
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
19
19
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
20
|
-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
20
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" media="print" onload="this.media='all'">
|
|
21
21
|
<style>${KOLBO_CSS}</style>
|
|
22
22
|
</head>
|
|
23
23
|
<body>
|
package/src/apps/theme.js
CHANGED
|
@@ -131,7 +131,9 @@ body {
|
|
|
131
131
|
position: absolute; top: 10px; left: 10px; z-index: 2;
|
|
132
132
|
display: inline-flex; align-items: center; gap: 6px;
|
|
133
133
|
padding: 4px 10px; border-radius: 999px;
|
|
134
|
-
background: rgba(0, 0, 0, 0.65); backdrop-filter: blur
|
|
134
|
+
background: rgba(0, 0, 0, 0.65); /* no backdrop-filter: nested blur over the
|
|
135
|
+
animating k-sweep skeleton forced per-frame backdrop re-sampling on phones;
|
|
136
|
+
0.65 black over the shimmer reads identically without it */
|
|
135
137
|
border: 1px solid rgba(255, 255, 255, 0.14);
|
|
136
138
|
font-size: 11px; font-weight: 600; color: #fff;
|
|
137
139
|
}
|
|
@@ -159,11 +161,21 @@ body {
|
|
|
159
161
|
|
|
160
162
|
/* Keep the whole completed card under the host's iframe height cap (~800px):
|
|
161
163
|
header + prompt + chips + viewer + thumbs + actions + footer must all fit,
|
|
162
|
-
or claude.ai adds an inner scrollbar. Click the image to
|
|
164
|
+
or claude.ai adds an inner scrollbar. Click the image to expand in-Claude. */
|
|
163
165
|
.k-viewer { margin-bottom: 10px; }
|
|
164
166
|
.k-viewer img, .k-viewer video { display: block; width: 100%; max-height: 340px; object-fit: contain;
|
|
165
167
|
border-radius: 12px; background: #000; border: 1px solid var(--border); cursor: zoom-in; }
|
|
166
168
|
.k-viewer video { cursor: default; }
|
|
169
|
+
|
|
170
|
+
/* ---- Fullscreen (ui/request-display-mode granted) ---- */
|
|
171
|
+
html.k-fullscreen, html.k-fullscreen body { height: 100%; }
|
|
172
|
+
html.k-fullscreen .k-card { height: 100%; display: flex; flex-direction: column; border-radius: 0; }
|
|
173
|
+
html.k-fullscreen .k-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
|
174
|
+
html.k-fullscreen .k-viewer { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; }
|
|
175
|
+
html.k-fullscreen .k-viewer img, html.k-fullscreen .k-viewer video {
|
|
176
|
+
max-height: 100%; max-width: 100%; width: auto; margin: 0 auto; cursor: zoom-out; }
|
|
177
|
+
html.k-fullscreen .k-thumbs .k-thumb { width: 64px; height: 64px; }
|
|
178
|
+
.k-expand-hint { display: none; }
|
|
167
179
|
.k-thumbs { display: flex; gap: 6px; margin: 10px 0 2px; }
|
|
168
180
|
.k-thumbs .k-thumb { width: 48px; height: 48px; border-radius: 8px; overflow: hidden; cursor: pointer;
|
|
169
181
|
border: 2px solid transparent; opacity: 0.75; transition: all 150ms var(--smooth); flex: none; }
|
|
@@ -173,10 +173,12 @@ function renderImages(sc, urls) {
|
|
|
173
173
|
// instead of a broken empty viewer.
|
|
174
174
|
var viewer = '<div class="k-viewer"><img id="main-img" src="' + esc(urls[selected]) + '" alt="" onerror="window.__imgFail && window.__imgFail()"></div>';
|
|
175
175
|
window.__imgFail = function () { renderLinks(urls); window.kolbo.notifySize(); };
|
|
176
|
-
//
|
|
176
|
+
// Click → expand into an in-Claude fullscreen viewer (all actions stay
|
|
177
|
+
// available); click again (or Exit) collapses back. Hosts that refuse
|
|
178
|
+
// fullscreen fall back to opening the original in a new tab.
|
|
177
179
|
setTimeout(function () {
|
|
178
180
|
var img = el('main-img');
|
|
179
|
-
if (img) img.onclick =
|
|
181
|
+
if (img) img.onclick = toggleFullscreen;
|
|
180
182
|
}, 0);
|
|
181
183
|
var thumbs = '';
|
|
182
184
|
if (urls.length > 1) {
|
|
@@ -262,6 +264,38 @@ function renderError(msg) {
|
|
|
262
264
|
window.kolbo.notifySize();
|
|
263
265
|
}
|
|
264
266
|
|
|
267
|
+
/* ---------- fullscreen viewer ---------- */
|
|
268
|
+
var isFullscreen = false;
|
|
269
|
+
function toggleFullscreen() {
|
|
270
|
+
var want = isFullscreen ? 'inline' : 'fullscreen';
|
|
271
|
+
window.kolbo.requestDisplayMode(want).then(function (res) {
|
|
272
|
+
var granted = res && res.mode;
|
|
273
|
+
if (granted === 'fullscreen') { isFullscreen = true; applyFullscreen(true); }
|
|
274
|
+
else if (granted === 'inline' || isFullscreen) { isFullscreen = false; applyFullscreen(false); }
|
|
275
|
+
else if (!isFullscreen) {
|
|
276
|
+
// Host refused fullscreen — degrade to opening the original file.
|
|
277
|
+
window.kolbo.openLink(state.urls && state.urls[selected]);
|
|
278
|
+
}
|
|
279
|
+
}).catch(function () {
|
|
280
|
+
if (!isFullscreen) window.kolbo.openLink(state.urls && state.urls[selected]);
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
function applyFullscreen(on) {
|
|
284
|
+
document.documentElement.classList.toggle('k-fullscreen', on);
|
|
285
|
+
var c = el('phase-chip');
|
|
286
|
+
if (on) {
|
|
287
|
+
c.style.display = '';
|
|
288
|
+
c.innerHTML = '✕ ' + esc('Exit');
|
|
289
|
+
c.style.cursor = 'pointer';
|
|
290
|
+
c.onclick = toggleFullscreen;
|
|
291
|
+
} else {
|
|
292
|
+
c.style.display = 'none';
|
|
293
|
+
c.onclick = null;
|
|
294
|
+
c.style.cursor = '';
|
|
295
|
+
}
|
|
296
|
+
window.kolbo.notifySize();
|
|
297
|
+
}
|
|
298
|
+
|
|
265
299
|
function setPhaseChip(text, spinning) {
|
|
266
300
|
var c = el('phase-chip');
|
|
267
301
|
if (!text) { c.style.display = 'none'; return; }
|