@kolbo/mcp 1.86.0 → 1.86.4
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 +2 -1
- package/skill/SKILL.md +435 -434
- package/skill/references/models/3d.md +51 -0
- package/skill/references/models/seedance.md +32 -4
- package/skill/references/workflows/cost-and-validation.md +1 -1
- package/src/apps/index.js +750 -737
- package/src/apps/theme.js +13 -0
- package/src/apps/widgets/generation.js +16 -11
- package/src/apps/widgets/mediaGrid.js +14 -1
- package/src/apps/widgets/upload.js +456 -457
- package/src/index.js +6 -1
- package/src/toolAnnotations.js +1 -1
- package/src/tools/_shared.js +183 -32
- package/src/tools/artifacts.js +5 -2
- package/src/tools/generate.js +141 -36
- package/src/tools/media.js +656 -656
- package/src/tools/projects.js +15 -0
- package/src/tools/visual_dna.js +459 -456
- package/src/tools/voices.js +1 -1
package/src/apps/theme.js
CHANGED
|
@@ -201,6 +201,14 @@ html.k-peek-fs .k-peek img, html.k-peek-fs .k-peek video { max-height: calc(100v
|
|
|
201
201
|
position: relative; border-radius: 10px; overflow: hidden;
|
|
202
202
|
background: var(--surface-2); border: 1px solid var(--border);
|
|
203
203
|
min-height: 120px; max-height: 300px;
|
|
204
|
+
/* width:100% is load-bearing, not cosmetic. Without a definite width the
|
|
205
|
+
aspect-ratio transfers the OTHER way: a 16/9 cell in a 196px auto-fill
|
|
206
|
+
column wants 110px of height, min-height:120px clamps it up, and the ratio
|
|
207
|
+
then back-computes the WIDTH as 120*16/9 = 213px. The item overflows its
|
|
208
|
+
196px track and lands on top of the next tile — which is exactly what a
|
|
209
|
+
3-up video grid looked like. Pinning the width makes the ratio size the
|
|
210
|
+
height only, and min-height just letterboxes a slightly tall cell. */
|
|
211
|
+
width: 100%;
|
|
204
212
|
}
|
|
205
213
|
.k-skel.video { aspect-ratio: 16 / 9; }
|
|
206
214
|
.k-skel.square { aspect-ratio: 1; }
|
|
@@ -368,6 +376,11 @@ html.k-fullscreen .k-actions { flex: none; padding-top: 8px; }
|
|
|
368
376
|
.k-audio-row:hover { background: var(--surface-2); }
|
|
369
377
|
.k-audio-art { width: 40px; height: 40px; border-radius: 8px; object-fit: cover; flex: none;
|
|
370
378
|
background: var(--brand-soft); }
|
|
379
|
+
/* Stand-in when a voice/track has no artwork, or has one the host refuses to
|
|
380
|
+
load — a blank tile and the browser's broken-image glyph both read as "this
|
|
381
|
+
row is broken" rather than "this one has no picture". */
|
|
382
|
+
.k-audio-art-fallback { display: flex; align-items: center; justify-content: center;
|
|
383
|
+
color: var(--brand); font-size: 18px; }
|
|
371
384
|
.k-audio-meta { flex: 1; min-width: 0; }
|
|
372
385
|
.k-audio-title { font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
373
386
|
.k-audio-sub { font-size: 11px; color: var(--text-faint);
|
|
@@ -76,13 +76,13 @@ var TOOL_TITLES = {
|
|
|
76
76
|
get_generation_status: 'Generations'
|
|
77
77
|
};
|
|
78
78
|
var OPEN_ROUTES = {
|
|
79
|
-
generate_image: { path: '/image-tools', tool: '
|
|
80
|
-
generate_image_edit: { path: '/image-tools', tool: 'image
|
|
81
|
-
edit_image: { path: '/image-tools', tool: '
|
|
82
|
-
generate_video: { path: '/video-tools', tool: '
|
|
83
|
-
generate_video_from_image: { path: '/video-tools', tool: '
|
|
84
|
-
generate_elements: { path: '/video-tools', tool: '
|
|
85
|
-
generate_first_last_frame: { path: '/video-tools', tool: '
|
|
79
|
+
generate_image: { path: '/image-tools', tool: 'create-image' },
|
|
80
|
+
generate_image_edit: { path: '/image-tools', tool: 'create-image' },
|
|
81
|
+
edit_image: { path: '/image-tools', tool: 'canvas' },
|
|
82
|
+
generate_video: { path: '/video-tools', tool: 'create-video' },
|
|
83
|
+
generate_video_from_image: { path: '/video-tools', tool: 'create-video' },
|
|
84
|
+
generate_elements: { path: '/video-tools', tool: 'create-video', mode: 'elements' },
|
|
85
|
+
generate_first_last_frame: { path: '/video-tools', tool: 'create-video', mode: 'first-last' },
|
|
86
86
|
generate_video_from_video: { path: '/video-tools', tool: 'video-to-video' },
|
|
87
87
|
generate_lipsync: { path: '/video-tools', tool: 'lipsync' },
|
|
88
88
|
generate_music: { path: '/audio-tools', tool: 'music-generator' },
|
|
@@ -1037,13 +1037,18 @@ function renderBatchGrid(sc) {
|
|
|
1037
1037
|
function renderStatusGrid(sc) {
|
|
1038
1038
|
var items = sc.items;
|
|
1039
1039
|
if (!items.length) return renderError('No results');
|
|
1040
|
-
|
|
1040
|
+
// Classify by extension, same as every other reference/thumb in this file —
|
|
1041
|
+
// the tool only knows a url came back, not what kind it is. Done up front
|
|
1042
|
+
// because the COLUMN COUNT depends on it: this grid used to hardcode
|
|
1043
|
+
// Math.min(items.length, 4) and so put videos 3-4 up, where gridCols caps
|
|
1044
|
+
// them at 2 everywhere else.
|
|
1045
|
+
items.forEach(function (it) {
|
|
1046
|
+
if (it.state === 'completed' && it.url) it.kind = refKind(it.url, 'image');
|
|
1047
|
+
});
|
|
1048
|
+
el('stage').innerHTML = '<div class="k-gen-grid n' + gridCols(items.length, items[0].kind) + '">' +
|
|
1041
1049
|
items.map(function (it, i) {
|
|
1042
1050
|
var cap = it.title ? '<span class="k-skel-cap" title="' + esc(it.title) + '">' + esc(it.title) + '</span>' : '';
|
|
1043
1051
|
if (it.state === 'completed' && it.url) {
|
|
1044
|
-
// Classify by extension, same as every other reference/thumb in this
|
|
1045
|
-
// file — the tool only knows a url came back, not what kind it is.
|
|
1046
|
-
it.kind = refKind(it.url, 'image');
|
|
1047
1052
|
var shape = it.kind === 'video' ? 'video' : 'square';
|
|
1048
1053
|
return '<div class="k-skel done ' + shape + '" data-focus="' + i + '"' +
|
|
1049
1054
|
(it.title ? ' title="' + esc(it.title) + '"' : '') + '>' +
|
|
@@ -102,8 +102,21 @@ function cellHTML(item, i) {
|
|
|
102
102
|
function audioRowHTML(item) {
|
|
103
103
|
var idx = state.items.indexOf(item);
|
|
104
104
|
var src = item.preview_audio || item.url;
|
|
105
|
+
// Same onerror contract as cellHTML, and for the same reason: a thumbnail the
|
|
106
|
+
// host cannot fetch (CSP, 404, expired) otherwise renders the browser's
|
|
107
|
+
// broken-image glyph. Voices are the ONLY items that come down this path, so
|
|
108
|
+
// this row is where a blocked thumbnail is actually visible — cells have
|
|
109
|
+
// degraded gracefully since forever and hid the problem everywhere else.
|
|
110
|
+
// this.outerHTML, NOT this.parentNode.innerHTML: here the <img> IS the art and
|
|
111
|
+
// its parent is the whole row, so the cell version would erase the title,
|
|
112
|
+
// subtitle, Use button and player along with it.
|
|
113
|
+
var artFallback = '<div class="k-audio-art k-audio-art-fallback">' + kindIcon('audio') + '</div>';
|
|
105
114
|
return '<div class="k-audio-row k-generated-audio" data-i="' + idx + '">' +
|
|
106
|
-
(item.thumbnail
|
|
115
|
+
(item.thumbnail
|
|
116
|
+
? '<img class="k-audio-art k-peek-hit" src="' + esc(item.thumbnail) + '" alt=""'
|
|
117
|
+
+ peekAttrs(item.thumbnail, 'image', item.title)
|
|
118
|
+
+ ' onerror="this.outerHTML=this.getAttribute(\\'data-fb\\')" data-fb="' + esc(artFallback) + '">'
|
|
119
|
+
: artFallback) +
|
|
107
120
|
'<div class="k-audio-meta"><div class="k-audio-title">' + esc(item.title || '') + '</div>' +
|
|
108
121
|
'<div class="k-audio-sub">' + esc(item.subtitle || '') + '</div></div>' +
|
|
109
122
|
'<button class="k-btn" data-use="' + idx + '">Use</button>' +
|