@kolbo/mcp 1.82.0 → 1.82.2

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.82.0",
3
+ "version": "1.82.2",
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": {
@@ -1,6 +1,6 @@
1
1
  # AUTO-GENERATED — do not edit
2
2
 
3
- This tree is mirrored from kolbo-code@9c91cff, the single source of truth.
3
+ This tree is mirrored from kolbo-code@c3b231a, the single source of truth.
4
4
  Canonical source: packages/opencode/skills/kolbo/
5
5
  Distribution: .github/workflows/sync-skill-to-plugin.yml
6
6
 
package/skill/SKILL.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- version: 0.9.10
2
+ version: 0.9.11
3
3
  name: kolbo
4
4
  description: |
5
5
  Generate, edit, analyze, and direct creative media through Kolbo AI: images,
@@ -57,6 +57,7 @@ Then generate **only** with the confirmed parameters. If the user changes an opt
57
57
  - **Batch totalling 100+ credits**: run `check_credits` first.
58
58
  - **Quote real cost**: after firing, log `credits_used` (from the tool result) to `.kolbo/production.md` — never `base × count`.
59
59
  - **Never state "credits remaining" from arithmetic** (opening balance − generation costs). Coding/chat usage deducts credits too, so the math is always wrong. Report cost only; if the user asks for their balance, call `check_credits` fresh at that moment.
60
+ - **Out of credits → `show_plans`.** A generation refused for credits already returns the upgrade card automatically — do NOT retry it, and do not re-run the tool "to be sure". Call `show_plans` yourself when the user asks about pricing, plans, upgrading, or how to get more credits. Prices are live and promo-adjusted; never quote them from memory. The user completes any purchase themselves on app.kolbo.ai/pricing — you cannot buy for them.
60
61
 
61
62
  For multi-scene / batch work this pairs with `generate_creative_director` (see below) — still confirm the brief first.
62
63
 
@@ -122,7 +123,7 @@ Each `references/models/*.md` mirrors the matching skill prompt in `kolbo-api/sr
122
123
  ### Discovery, Library, Visual DNA, Moodboards, Chat, Publishing
123
124
  | Tool | Purpose |
124
125
  |------|---------|
125
- | `list_models` / `list_voices` / `check_credits` / `get_generation_status` / `cancel_generation` / `get_session_usage` | Discovery + status. `list_models` with no args returns the recommended shortlist out of ~428 — pass `type` for a full category with per-model caps. `cancel_generation` stops an in-flight job and refunds what it can: use it when the user changes their mind mid-generation instead of letting it run. |
126
+ | `list_models` / `list_voices` / `check_credits` / `show_plans` / `get_generation_status` / `cancel_generation` / `get_session_usage` | Discovery + status. `list_models` with no args returns the recommended shortlist out of ~428 — pass `type` for a full category with per-model caps. `cancel_generation` stops an in-flight job and refunds what it can: use it when the user changes their mind mid-generation instead of letting it run. `show_plans` renders the balance + upgrade card for pricing/plan/upgrade questions. |
126
127
  | `upload_media` / `create_upload_ticket` / `list_media` / `get_media` / `get_media_stats` / `favorite_media` / `unfavorite_media` / `delete_media` / `restore_media` / `permanently_delete_media` / `move_media` / `bulk_*_media` / `*_media_folder` | Media library — see `workflows/media-library.md`. Getting a LOCAL file in depends on where the server runs: `upload_media` with a path only works on a local (stdio) install; over a remote connector use `create_upload_ticket` and POST the file yourself. |
127
128
  | `create_visual_dna` / `update_visual_dna` / `generate_character_sheet` / `list_visual_dnas` / `get_visual_dna` / `delete_visual_dna` / `*_visual_dna_folder` (5 folder tools) | Visual DNA (+ character sheet, character folders) — see `workflows/visual-dna.md`. Edit with `update_visual_dna`; never delete+recreate. |
128
129
  | `list_moodboards` / `get_moodboard` / `list_presets` | Style overlays + sheet presets — see **Preset contract** in Core Workflow. Never omit `preset_id` after claiming a preset was used. |
package/skill/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.10
1
+ 0.9.11
@@ -441,6 +441,47 @@ function iconFor(kind) {
441
441
  /* ---------- generating ---------- */
442
442
  function isBatch(sc) { return !!(sc && sc.generation_ids && sc.generation_ids.length > 1); }
443
443
 
444
+ // Columns for a batch grid. Video caps at 2 per row: a 16:9 cell in a 4-up
445
+ // grid lands around 200px inside a chat card, which is too small to judge a
446
+ // shot and far too small to scrub once <video controls> appears. Images stay
447
+ // 4-up — they read fine as contact-sheet tiles.
448
+ function gridCols(count, kind) {
449
+ return Math.min(count, kind === 'video' ? 2 : 4);
450
+ }
451
+
452
+ // Batch prompts routinely share a long identical preamble (a locked global
453
+ // look, style rules, duration). Clamping from the left then renders EVERY
454
+ // caption as the same string — four cells all reading "Total: 8s [GLOBAL LOOK
455
+ // - LOCKED]…" identify nothing. Drop the shared prefix so the caption shows
456
+ // the part that actually differs. Full text stays in the tooltip.
457
+ function batchCaptions(prompts) {
458
+ var list = (prompts || []).map(function (p) { return String(p == null ? '' : p); });
459
+ if (list.length < 2) return list;
460
+ var first = list[0], n = first.length;
461
+ for (var i = 1; i < list.length && n > 0; i++) {
462
+ var j = 0;
463
+ while (j < n && j < list[i].length && list[i].charAt(j) === first.charAt(j)) j++;
464
+ n = j;
465
+ }
466
+ // Short shared runs are just coincidence ("A ", "The "), not a preamble.
467
+ if (n < 12) return list;
468
+ // Back up to a word boundary so a label never starts mid-word.
469
+ var cut = n;
470
+ while (cut > 0 && !/\s/.test(first.charAt(cut - 1))) cut--;
471
+ if (!cut) cut = n;
472
+ return list.map(function (p) {
473
+ var rest = p.slice(cut).trim();
474
+ // A prompt identical to the prefix has nothing distinct to show — keep it
475
+ // whole rather than rendering an empty chip.
476
+ return rest ? '… ' + rest : p;
477
+ });
478
+ }
479
+ function capAt(sc, i) {
480
+ if (!sc || !sc.prompts || !sc.prompts[i]) return '';
481
+ if (!sc._caps) sc._caps = batchCaptions(sc.prompts);
482
+ return sc._caps[i] || sc.prompts[i];
483
+ }
484
+
444
485
  function renderGenerating(sc) {
445
486
  setPhaseChip('Generating', true);
446
487
  var n = Math.min(sc.count || 1, isBatch(sc) ? 8 : 4);
@@ -449,11 +490,11 @@ function renderGenerating(sc) {
449
490
  var cells = '';
450
491
  for (var i = 0; i < n; i++) {
451
492
  var cap = (sc.prompts && sc.prompts[i])
452
- ? '<span class="k-skel-cap" title="' + esc(sc.prompts[i]) + '">' + esc(sc.prompts[i]) + '</span>' : '';
493
+ ? '<span class="k-skel-cap" title="' + esc(sc.prompts[i]) + '">' + esc(capAt(sc, i)) + '</span>' : '';
453
494
  cells += '<div class="k-skel ' + shape + '" data-cell="' + i + '">' + cap + '</div>';
454
495
  }
455
496
  // Grid class caps at n4 — the auto-fill rule handles any larger batch count.
456
- el('stage').innerHTML = '<div class="k-gen-grid n' + Math.min(n, 4) + '">' + cells + '</div>';
497
+ el('stage').innerHTML = '<div class="k-gen-grid n' + gridCols(n, kind) + '">' + cells + '</div>';
457
498
  renderStopButton(sc);
458
499
  schedulePoll(sc);
459
500
  }
@@ -709,7 +750,7 @@ function handleBatchStatus(sc, st) {
709
750
  }
710
751
  scenes.push({
711
752
  scene_number: i + 1,
712
- title: (sc.prompts && sc.prompts[i]) || '',
753
+ title: capAt(sc, i),
713
754
  image_urls: sc.kind === 'video' ? [] : urls,
714
755
  video_urls: sc.kind === 'video' ? urls : []
715
756
  });
@@ -743,7 +784,7 @@ function fillBatchCell(sc, i, g) {
743
784
  cell.setAttribute('data-done', '1');
744
785
  cell.classList.add('done');
745
786
  var cap = (sc.prompts && sc.prompts[i])
746
- ? '<span class="k-skel-cap" title="' + esc(sc.prompts[i]) + '">' + esc(sc.prompts[i]) + '</span>' : '';
787
+ ? '<span class="k-skel-cap" title="' + esc(sc.prompts[i]) + '">' + esc(capAt(sc, i)) + '</span>' : '';
747
788
  if (sc.prompts && sc.prompts[i]) cell.title = sc.prompts[i];
748
789
  // The controls attribute is not optional here: this cell is a FINISHED result
749
790
  // the user is meant to watch, and without it the tile was a muted poster with
@@ -939,7 +980,7 @@ function renderBatchGrid(sc) {
939
980
  var items = sceneItems(sc);
940
981
  if (!items.length) return renderError('No completed results received');
941
982
  var shape = items[0].type === 'video' ? 'video' : 'square';
942
- el('stage').innerHTML = '<div class="k-gen-grid n' + Math.min(items.length, 4) + '">' +
983
+ el('stage').innerHTML = '<div class="k-gen-grid n' + gridCols(items.length, items[0].type) + '">' +
943
984
  items.map(function (it, i) {
944
985
  return '<div class="k-skel done ' + shape + '" data-focus="' + i + '"' +
945
986
  (it.label ? ' title="' + esc(it.label) + '"' : '') + '>' +