@kolbo/mcp 1.106.3 → 1.106.5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolbo/mcp",
3
- "version": "1.106.3",
3
+ "version": "1.106.5",
4
4
  "description": "Kolbo AI MCP Server - Generate images, videos, music, speech, and sound effects from Claude Code",
5
5
  "main": "src/index.js",
6
6
  "bin": {
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" media="print" onload="this.media='all'">
20
+ <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&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
@@ -11,7 +11,10 @@
11
11
  const KOLBO_CSS = `
12
12
  :root {
13
13
  --bg: #0f0f0f;
14
- --card: rgba(22, 22, 25, 0.96);
14
+ /* A translucent lift, not a fixed colour: every host paints its own dark grey
15
+ behind the iframe (claude.ai, ChatGPT, Codex, Kolbo Code all differ), and a
16
+ fixed near-black card read as a hole cut into the chat. */
17
+ --card: rgba(255, 255, 255, 0.04);
15
18
  --card-solid: #161619;
16
19
  --panel: rgba(255, 255, 255, 0.035);
17
20
  --surface: rgba(255, 255, 255, 0.03);
@@ -31,7 +34,13 @@ const KOLBO_CSS = `
31
34
  --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
32
35
  --smooth: cubic-bezier(0.25, 0.46, 0.45, 0.94);
33
36
  --specular: inset 0 1px 0 rgba(255, 255, 255, 0.18);
34
- color-scheme: dark;
37
+ /* "light dark" on the ROOT, never a fixed scheme. When an iframe's root
38
+ scheme differs from the host frame's, the browser paints an OPAQUE canvas
39
+ behind the page: a fixed "dark" here drew a dark square around every card
40
+ in hosts whose frame is light/normal (Codex). "light dark" adopts the host
41
+ frame's scheme, so the canvas stays transparent everywhere. The card
42
+ carries the real theme for its native controls below. */
43
+ color-scheme: light dark;
35
44
  }
36
45
  [data-theme="light"] {
37
46
  --bg: #f5f5f2;
@@ -47,12 +56,13 @@ const KOLBO_CSS = `
47
56
  --text-faint: rgba(10, 10, 12, 0.40);
48
57
  --brand-soft: rgba(59, 130, 246, 0.10);
49
58
  --specular: inset 0 1px 0 rgba(255, 255, 255, 0.65);
50
- color-scheme: light;
51
59
  }
52
60
  * { box-sizing: border-box; margin: 0; padding: 0; }
53
61
  html, body { background: transparent; }
62
+ .k-card { color-scheme: dark; }
63
+ [data-theme="light"] .k-card { color-scheme: light; }
54
64
  body {
55
- font-family: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
65
+ font-family: 'Poppins', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
56
66
  color: var(--text);
57
67
  font-size: 14px;
58
68
  line-height: 1.5;
@@ -67,7 +77,8 @@ body {
67
77
  -webkit-backdrop-filter: blur(20px) saturate(180%);
68
78
  border: 1px solid var(--border);
69
79
  border-radius: var(--radius-card);
70
- box-shadow: 0 2px 16px rgba(0, 0, 0, 0.22), var(--specular);
80
+ /* No drop shadow: on a dark host it only adds a muddy halo. */
81
+ box-shadow: var(--specular);
71
82
  overflow: hidden;
72
83
  animation: k-in 400ms var(--spring);
73
84
  }
@@ -110,7 +121,6 @@ body {
110
121
  .k-mention {
111
122
  display: inline; padding: 1px 5px; border-radius: 5px;
112
123
  background: var(--brand-soft); color: var(--brand);
113
- font-family: 'JetBrains Mono', ui-monospace, monospace;
114
124
  font-size: 0.94em; font-weight: 500;
115
125
  }
116
126
  /* Single-line media caption (scene / batch prompt under the viewer) */
@@ -139,7 +149,7 @@ body {
139
149
  .k-chip .k-mono-icon {
140
150
  width: 14px; height: 14px; border-radius: 4px; background: var(--brand);
141
151
  color: #fff; font-size: 9px; font-weight: 700; display: inline-flex;
142
- align-items: center; justify-content: center; font-family: 'Inter', sans-serif;
152
+ align-items: center; justify-content: center; font-family: inherit;
143
153
  }
144
154
  .k-chip img.k-voice-thumb { width: 18px; height: 18px; border-radius: 999px; margin-left: -3px; }
145
155
  .k-ref-thumb { width: 26px; height: 26px; border-radius: 6px; object-fit: cover; border: 1px solid var(--border-strong); }
@@ -157,7 +167,7 @@ html.k-peek-open .k-card { min-height: 460px; }
157
167
  .k-peek-bar { flex: none; display: flex; align-items: center; gap: 8px; padding: 8px 8px 8px 14px; min-height: 44px; }
158
168
  .k-peek-cap { flex: 1; min-width: 0; font-size: 12.5px; color: rgba(255,255,255,0.78);
159
169
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
160
- .k-peek-count { flex: none; font-size: 11.5px; color: rgba(255,255,255,0.55); font-family: 'JetBrains Mono', ui-monospace, monospace; }
170
+ .k-peek-count { flex: none; font-size: 11.5px; color: rgba(255,255,255,0.55); font-variant-numeric: tabular-nums; }
161
171
  .k-peek-btn {
162
172
  flex: none; width: 32px; height: 32px; border: 1px solid rgba(255,255,255,0.14); border-radius: 999px;
163
173
  background: rgba(255,255,255,0.08); color: #fff; cursor: pointer; font-size: 15px;
@@ -299,7 +309,7 @@ video::-webkit-media-controls-fullscreen-button { display: none !important; }
299
309
  animating k-sweep skeleton forced per-frame backdrop re-sampling on phones;
300
310
  0.65 black over the shimmer reads identically without it */
301
311
  border: 1px solid rgba(255, 255, 255, 0.14);
302
- font-size: 11px; font-weight: 600; color: #fff;
312
+ font-size: 11px; font-weight: 600; color: #fff; text-transform: capitalize;
303
313
  }
304
314
  .k-spin {
305
315
  width: 12px; height: 12px; border-radius: 50%;
@@ -459,7 +469,7 @@ video::-webkit-media-controls-fullscreen-button { display: none !important; }
459
469
  .k-dot.on { width: 22px; opacity: 0.95; cursor: default; }
460
470
  .k-dot.ghost { cursor: default; opacity: 0.14; }
461
471
  .k-pager-label { font-size: 11px; color: var(--text-faint);
462
- font-family: 'JetBrains Mono', ui-monospace, monospace; min-width: 58px; text-align: center; }
472
+ font-variant-numeric: tabular-nums; min-width: 58px; text-align: center; }
463
473
 
464
474
  /* ---- Audio rows ---- */
465
475
  .k-audio-row { display: flex; align-items: center; gap: 10px; padding: 9px 10px;
@@ -529,7 +539,7 @@ video::-webkit-media-controls-fullscreen-button { display: none !important; }
529
539
  .k-footer:not(:has(.k-credits:not(:empty))) { display: none; }
530
540
  .k-footer a { color: var(--text-faint); text-decoration: none; }
531
541
  .k-footer a:hover { color: var(--brand); }
532
- .k-credits { margin-left: auto; font-family: 'JetBrains Mono', monospace; }
542
+ .k-credits { margin-left: auto; font-variant-numeric: tabular-nums; }
533
543
  `;
534
544
 
535
545
  /**
@@ -4,27 +4,34 @@ const { widgetPage } = require('../html');
4
4
 
5
5
  const BODY = `
6
6
  <style>
7
- #loading[hidden], #balance[hidden], #error[hidden] { display: none !important; }
8
- .k-credit-total { font-size: clamp(30px, 8vw, 46px); font-weight: 600; letter-spacing: -1.5px; line-height: 1.2; overflow-wrap: anywhere; }
9
- .k-credit-label { color: var(--text-muted); font-size: 12px; margin-top: 6px; }
10
- .k-credit-breakdown { margin: 22px 0 0; padding: 0; }
11
- .k-credit-row { display: flex; justify-content: space-between; gap: 16px; padding: 11px 0; border-top: 1px solid var(--border); font-size: 13px; }
7
+ #loading[hidden], #balance[hidden], #error[hidden], #breakdown[hidden] { display: none !important; }
8
+ /* One line by default. Agents check the balance at session start and before
9
+ big batches; a full-height balance card each time buried the chat. */
10
+ .k-credit-line { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
11
+ .k-credit-total { font-size: 22px; font-weight: 650; letter-spacing: -0.5px; line-height: 1.2;
12
+ font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
13
+ .k-credit-label { color: var(--text-muted); font-size: 12px; }
14
+ .k-credit-line .k-text-btn { margin-left: auto; align-self: center; }
15
+ .k-credit-breakdown { margin: 10px 0 0; padding: 0; }
16
+ .k-credit-row { display: flex; justify-content: space-between; gap: 16px; padding: 8px 0; border-top: 1px solid var(--border); font-size: 12.5px; }
12
17
  .k-credit-row dt { color: var(--text-muted); }
13
18
  .k-credit-row dd { margin: 0; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; text-align: right; }
14
19
  </style>
15
20
  <div class="k-card">
16
- <div class="k-head"><span class="k-logo" id="logo"></span><span class="k-title">Credit balance</span></div>
21
+ <div class="k-head"><span class="k-logo" id="logo"></span><span class="k-title">Credits</span></div>
17
22
  <div class="k-body" aria-live="polite">
18
- <div id="loading" class="k-skel" style="height:160px" aria-label="Loading credit balance"></div>
23
+ <div id="loading" class="k-skel" style="min-height:0;height:28px" aria-label="Loading credit balance"></div>
19
24
  <div id="balance" hidden>
20
- <div class="k-credit-total" id="total"></div>
21
- <div class="k-credit-label">Available credits</div>
22
- <dl class="k-credit-breakdown">
25
+ <div class="k-credit-line">
26
+ <span class="k-credit-total" id="total"></span>
27
+ <span class="k-credit-label">available</span>
28
+ <button type="button" class="k-text-btn" id="toggle" aria-expanded="false" aria-controls="breakdown">Details</button>
29
+ </div>
30
+ <dl class="k-credit-breakdown" id="breakdown" hidden>
23
31
  <div class="k-credit-row"><dt>Plan credits</dt><dd id="plan"></dd></div>
24
32
  <div class="k-credit-row"><dt>Credit pack</dt><dd id="pack"></dd></div>
25
33
  <div class="k-credit-row"><dt>Redemption</dt><dd id="redemption"></dd></div>
26
34
  </dl>
27
- <div class="k-credit-label">Balance at time of check</div>
28
35
  </div>
29
36
  <div id="error" class="k-error" hidden>Credit balance unavailable. Please check again.</div>
30
37
  </div>
@@ -32,6 +39,13 @@ const BODY = `
32
39
 
33
40
  const SCRIPT = `
34
41
  el('logo').innerHTML = KOLBO_LOGO + '<span>Kolbo</span>';
42
+ el('toggle').onclick = function () {
43
+ var open = el('breakdown').hidden;
44
+ el('breakdown').hidden = !open;
45
+ el('toggle').setAttribute('aria-expanded', String(open));
46
+ el('toggle').textContent = open ? 'Hide' : 'Details';
47
+ window.kolbo.notifySize();
48
+ };
35
49
  function amount(value) {
36
50
  if (value == null || value === '' || !Number.isFinite(Number(value))) return '\u2014';
37
51
  return Number(value).toLocaleString('en-US', { maximumFractionDigits: 8 });
@@ -453,11 +453,17 @@ function moodboardChipsHTML(sc, s) {
453
453
  }
454
454
  return h;
455
455
  }
456
- function chip(inner) { return '<span class="k-chip">' + inner + '</span>'; }
456
+ // Labels read as words: "Image", "Enhanced", "Web search" — the first letter
457
+ // of the visible text (after any leading icon markup) is uppercased. Digits
458
+ // first ("1080p", "16:9", "7 images") are left alone.
459
+ function capLabel(inner) {
460
+ return String(inner).replace(/(^|>)(\\s*)([a-z])/, function (m, gt, sp, ch) { return gt + sp + ch.toUpperCase(); });
461
+ }
462
+ function chip(inner) { return '<span class="k-chip">' + capLabel(inner) + '</span>'; }
457
463
  // Same chip with a hover title — used to surface the asset id behind a
458
464
  // "2 Visual DNA" / "preset" label without spending chip width on it.
459
465
  function chipT(inner, title) {
460
- return '<span class="k-chip" title="' + esc(title) + '">' + inner + '</span>';
466
+ return '<span class="k-chip" title="' + esc(title) + '">' + capLabel(inner) + '</span>';
461
467
  }
462
468
  function iconFor(kind) {
463
469
  switch (kind) {
@@ -30,7 +30,7 @@ const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
30
30
 
31
31
  function trendTile(t) {
32
32
  const example = (t.examples || [])[0] || {};
33
- const poster = t.cover?.image || example.poster || t.source_poster;
33
+ const poster = t.cover?.image || example.poster;
34
34
  return {
35
35
  id: t.slug,
36
36
  title: t.name,