kingkont 0.7.39 → 0.7.41

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/settings.html CHANGED
@@ -169,6 +169,27 @@
169
169
  </div>
170
170
  </div>
171
171
 
172
+ <h2>Для Claude</h2>
173
+ <div class="card">
174
+ <div style="font-size:13px; color:var(--text); margin-bottom:8px;">
175
+ Скилл <code>kingkont</code> для Claude Code
176
+ </div>
177
+ <div class="hint" style="margin-top:0; margin-bottom:12px;">
178
+ Положит <code>SKILL.md</code> в папку настроек Claude Code в твоём
179
+ домашнем каталоге (macOS/Linux: <code>~/.claude/skills/kingkont/</code>;
180
+ Windows: <code>%USERPROFILE%\.claude\skills\kingkont\</code>). Claude
181
+ сможет управлять проектами KingKont (создавать ноды, запускать
182
+ генерации) без открытия приложения. После установки нужен
183
+ <code>/reload</code> в Claude Code.
184
+ </div>
185
+ <div class="row">
186
+ <button id="installSkill" class="secondary">Установить skill для Claude</button>
187
+ <span class="saved" id="skillSaved" style="margin-left:auto;">Установлено ✓</span>
188
+ </div>
189
+ <div class="hint" id="skillPath" style="display:none; margin-top:8px; word-break:break-all; font-family:ui-monospace,monospace; color:var(--ok);"></div>
190
+ <div class="error" id="skillError" style="display:none;"></div>
191
+ </div>
192
+
172
193
  <div class="actions">
173
194
  <span class="saved" id="saved">Сохранено</span>
174
195
  <button class="secondary" id="cancel">Закрыть</button>
@@ -309,6 +330,41 @@ function escapeHtml(s) {
309
330
  return String(s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
310
331
  }
311
332
 
333
+ // Кнопка «Установить skill для Claude» — копирует skill/SKILL.md в
334
+ // ~/.claude/skills/kingkont/ (или %USERPROFILE%\.claude\skills\kingkont\
335
+ // на Windows) через main-process IPC. После успеха показывает реальный путь.
336
+ $('installSkill').addEventListener('click', async () => {
337
+ const btn = $('installSkill');
338
+ const ok = $('skillSaved');
339
+ const err = $('skillError');
340
+ const pathEl = $('skillPath');
341
+ err.style.display = 'none';
342
+ pathEl.style.display = 'none';
343
+ ok.classList.remove('show');
344
+ btn.disabled = true;
345
+ btn.textContent = 'Устанавливаю…';
346
+ try {
347
+ const res = await window.claudeMd.installSkill();
348
+ if (res?.ok) {
349
+ btn.textContent = 'Переустановить skill для Claude';
350
+ ok.classList.add('show');
351
+ setTimeout(() => ok.classList.remove('show'), 2500);
352
+ if (res.path) {
353
+ pathEl.style.display = '';
354
+ pathEl.textContent = '✓ ' + res.path;
355
+ }
356
+ } else {
357
+ throw new Error(res?.error || 'Не удалось установить');
358
+ }
359
+ } catch (e) {
360
+ err.style.display = '';
361
+ err.textContent = 'Ошибка: ' + e.message;
362
+ btn.textContent = 'Попробовать снова';
363
+ } finally {
364
+ btn.disabled = false;
365
+ }
366
+ });
367
+
312
368
  loadSettings();
313
369
  </script>
314
370
  </body>
package/skill/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: kingkont
3
- description: Use this skill when the user works with a KingKont project — a film/series scene editor where each scene is a folder with scene.json. Triggers — fraзы вроде «открой/запусти kingkont», «открой редактор сцен», «добавь сцену/персонажа/локацию», «добавь ноду на холст», «сгенерируй картинку/видео/голос/SFX/музыку/текст», или работа с папкой содержащей _characters/ _locations/ <scene>/scene.json. Skill знает формат данных и API-ключи из настроек kingkont, может править scene.json напрямую и запускать UI редактора через `npx -y kingkont serve` для визуальной работы.
3
+ description: Use this skill when the user works with a KingKont project — a film/series scene editor where each scene is a folder with scene.json. Triggers — фразы вроде «открой/запусти kingkont», «открой редактор сцен», «добавь сцену/персонажа/локацию», «добавь ноду на холст», «сгенерируй картинку/видео/голос/SFX/музыку/текст», или работа с папкой содержащей _characters/ _locations/ <scene>/scene.json. Skill знает формат данных и использует CLI `kingkont <cmd>` (open/list/board/add-node/gen/connect/rm-node/upload/voices/balance) для управления нодами и запуска генераций — ключи берутся автоматически из настроек приложения. Для визуальной работы поднимает UI через `npx -y kingkont serve`.
4
4
  ---
5
5
 
6
6
  # KingKont · Chatium — Skill
@@ -201,106 +201,188 @@ open -a "Google Chrome" "http://localhost:17893/"
201
201
 
202
202
  Если ключа не хватает — попроси юзера задать в редакторе через `Cmd+,`.
203
203
 
204
- ## Программная генерация (без UI)
204
+ ## Работа без UI через CLI (предпочтительно)
205
205
 
206
- Запусти `npx kingkont serve` в фоне сервер становится прокси к KIE/
207
- ElevenLabs/OpenRouter с уже подставленными ключами из settings.json.
208
- Дёргай endpoints прямым curl/fetch:
206
+ `kingkont` устанавливается глобально: `npm i -g kingkont`. После этого все
207
+ команды ниже работают **без открытого приложения** — правят `scene.json`
208
+ напрямую через FS, а генерации запускают через те же провайдеры, что и UI
209
+ (KIE / Chatium / ElevenLabs / OpenRouter), используя ключи из
210
+ `settings.json`.
209
211
 
210
- ### `POST http://localhost:17893/api/text`текст (OpenRouter)
211
- ```json
212
- {
213
- "prompt": "...",
214
- "model": "anthropic/claude-sonnet-4", // или openai/gpt-4o, google/gemini-..., etc
215
- "system": "опционально system prompt",
216
- "images": [{ "url": "data:image/jpeg;base64,..." }] // vision-режим
217
- }
212
+ > Все `<project>`путь к корню проекта KingKont (где живут `_characters/`,
213
+ > `_locations/`, папки сцен).
214
+ > Все `<board>` принимаются в любом из форматов:
215
+ > `Scene1`, `_characters/Anna`, `characters/Anna`, `_locations/Office`.
216
+ > `<nodeId>` принимается как полный uuid либо как имя ноды (через `--name`).
217
+
218
+ ### Чтение
219
+
220
+ ```bash
221
+ kingkont open <project> # структура проекта (с --json — JSON)
222
+ kingkont list <project> # списки досок
223
+ kingkont board <project> <board> # одна доска (с --json — полный JSON)
224
+ kingkont status <project> <board> <id> # прогресс in-flight задачи
225
+ kingkont balance # балансы всех включённых провайдеров
226
+ kingkont voices # все ElevenLabs голоса
218
227
  ```
219
- Возвращает `{ "text": "...", "model": "..." }`.
220
228
 
221
- ### `POST http://localhost:17893/api/sfx` звуковой эффект (ElevenLabs)
222
- ```json
223
- {
224
- "text": "heavy door slamming with echo", // лучше английский
225
- "durationSeconds": 3, // 0.5–22, опц.
226
- "promptInfluence": 0.3 // 0–1, опц.
227
- }
229
+ ### Создание / правка нод
230
+
231
+ ```bash
232
+ # Просто добавить пустую ноду без генерации:
233
+ kingkont add-node <project> <board> --kind=text --name=plot --text="..."
234
+ kingkont add-node <project> <board> --kind=image --name=hero
235
+ kingkont add-node <project> <board> --kind=video --name=intro [--x=200 --y=100]
236
+
237
+ # Связать ноды (по id или по name):
238
+ kingkont connect <project> <board> plot hero
239
+
240
+ # Удалить ноду (файл переезжает в _deleted/):
241
+ kingkont rm-node <project> <board> hero
228
242
  ```
229
- Возвращает `audio/mpeg` (mp3 stream). Сохрани в `<board>/audio/sfx_<ts>.mp3`.
230
243
 
231
- ### `POST http://localhost:17893/api/music` музыка (ElevenLabs)
232
- ```json
233
- {
234
- "prompt": "epic orchestral cinematic, slow buildup, hopeful",
235
- "durationMs": 30000 // опц.
236
- }
244
+ ### Генерацияглавная команда `gen`
245
+
246
+ `gen` совмещает «создать ноду + сразу запустить генерацию + дождаться + сохранить
247
+ файл в нужную подпапку доски». Блокируется до завершения (для image — секунды,
248
+ для video — до 10 мин).
249
+
250
+ ```bash
251
+ # Картинка через KingKont/KIE (модель — короткий ключ или полный slug)
252
+ kingkont gen <project> <board> --kind=image --prompt="..." --model=nano-banana-2
253
+ kingkont gen <project> <board> --kind=image --prompt="..." --model=grok --aspect-ratio=16:9
254
+
255
+ # С референсами — @-ссылки на ноды/character/location в проекте
256
+ kingkont gen <project> <board> --kind=image --prompt="hero in @office" \
257
+ --refs=@Anna,@office --model=nano-banana-2
258
+
259
+ # Видео (Seedance, Veo, Kling и др. через Chatium):
260
+ kingkont gen <project> <board> --kind=video --prompt="..." \
261
+ --model=seedance-2 --aspect-ratio=16:9 --duration=5
262
+ kingkont gen <project> <board> --kind=video --prompt="..." \
263
+ --model=kling-3.0 --refs=@hero # i2v: ref → image_urls автоматически
264
+
265
+ # Текст (Claude/Gemini/etc через Chatium или OpenRouter):
266
+ kingkont gen <project> <board> --kind=text --name=script \
267
+ --prompt="напиши диалог двух полицейских" --model=anthropic/claude-sonnet-4
268
+
269
+ # Голос (TTS):
270
+ kingkont gen <project> <board> --kind=audio --prompt="Привет, мир" \
271
+ --voice=JBFqnCBsd6RMkjVDRZzb
272
+
273
+ # SFX (звуковой эффект, лучше en-промпт):
274
+ kingkont gen <project> <board> --kind=audio --sub-kind=sfx --prompt="heavy door slam" --duration=3
275
+
276
+ # Музыка:
277
+ kingkont gen <project> <board> --kind=audio --sub-kind=music \
278
+ --prompt="cinematic orchestral hopeful" --duration-ms=30000
237
279
  ```
238
- Возвращает `audio/mpeg`.
239
280
 
240
- ### `POST http://localhost:17893/api/tts` речь (ElevenLabs)
241
- ```json
242
- {
243
- "text": "...",
244
- "voiceId": "JBFqnCBsd6RMkjVDRZzb", // ElevenLabs voice id
245
- "modelId": "eleven_v3"
246
- }
281
+ После `gen` нода имеет `n.file` (относительный путь к сохранённому файлу),
282
+ а в `n.generated.creditsCharged` — стоимость, если её вернул провайдер.
283
+
284
+ ### Перезапустить ноду в статусе `error` или `draft`
285
+
286
+ ```bash
287
+ kingkont generate <project> <board> <nodeId>
247
288
  ```
248
- Возвращает `audio/mpeg`.
249
289
 
250
- ### `POST http://localhost:17893/api/generate` image/video (KIE, async)
251
- ```json
252
- {
253
- "kind": "image" | "video",
254
- "prompt": "...",
255
- "model": "nano-banana-2" | "flux-schnell" | "sdxl-lightning"
256
- | "seedream" | "seedream-5-lite" | "grok"
257
- | "seedance-2", // для video bytedance/seedance-2
258
- "imageInputs": ["http(s) URL"], // опц., референсы
259
- "aspectRatio": "16:9",
260
- "resolution": "1K"
261
- }
290
+ Берёт `n.generated.prompt` и `n.generated.model` из существующей ноды, резолвит
291
+ её `n.generated.refs`, запускает заново.
292
+
293
+ ### Доступные модели
294
+
295
+ | `--kind` | Поставщик | `--model` ключи |
296
+ |---|---|---|
297
+ | `image` | KingKont / KIE | `nano-banana-2`, `nano-banana-pro`, `grok`, `grok-i2i`, `seedream-5-lite`, `flux-schnell`, `sdxl-lightning` |
298
+ | `video` | KingKont | `seedance-2`, `seedance-2-fast`, `veo-3.1`, `kling-o1`, `kling-3.0`, `kling-v3-omni`, `wan-2.7-i2v`, `runway`, `grok-i2v`, `grok-t2v` |
299
+ | `video` | KIE | `seedance-2` |
300
+ | `text` | KingKont / OpenRouter | `anthropic/claude-sonnet-4`, `openai/gpt-4o`, `google/gemini-2.0-flash`, etc |
301
+ | `audio` (TTS) | KingKont | `qwen/qwen3-tts`, `elevenlabs/v3`, `minimax/speech-02-hd`, `google/gemini-3.1-flash-tts-preview` |
302
+ | `audio` (TTS) | ElevenLabs | `eleven_v3` (форсится при прямом ElevenLabs-подключении) |
303
+ | `audio` (sfx/music) | KingKont / ElevenLabs | без `--model` |
304
+
305
+ Если указанная модель не поддерживается активным провайдером — CLI вернёт
306
+ понятную ошибку со списком доступных.
307
+
308
+ ### Загрузка файла в storage
309
+
310
+ ```bash
311
+ kingkont upload <file> # печатает публичный URL
262
312
  ```
263
- Возвращает `{ "taskId": "..." }`. Затем поллить:
264
313
 
265
- ### `GET http://localhost:17893/api/poll?taskId=...`
266
- Возвращает `{ "status": "pending" | "done" | "error", "url": "https://..." }`.
267
- Когда `done` — скачай `url` (это публичный URL картинки/видео).
314
+ Полезно когда юзер просит «сделай эту картинку референсом для генерации» —
315
+ сначала аплоадим, потом передаём URL в `--refs`.
316
+
317
+ ### `--json` для машино-читаемого вывода
318
+
319
+ Все команды поддерживают `--json` — печатают строгий JSON в stdout (логи и
320
+ прогресс генерации идут в stderr). Используй для парсинга в скриптах.
321
+
322
+ ## HTTP API (альтернатива — когда UI или сервер запущены)
323
+
324
+ Если по каким-то причинам CLI недоступен (другая машина, скрипт с curl,
325
+ интеграция в другой инструмент) — все те же возможности доступны через HTTP.
326
+ Запусти `npx -y kingkont serve` и дёргай endpoints:
268
327
 
269
- ### `POST http://localhost:17893/api/upload` загрузить локальный файл в KIE
270
- Передай binary в body, заголовок `X-File-Name: filename.jpg`.
271
- Возвращает `{ "url": "https://..." }` этот URL можно класть в
272
- `imageInputs`.
328
+ | Метод | Путь | Что |
329
+ |---|---|---|
330
+ | POST | `/api/text` | текст: `{prompt, model, system?, images?}` `{text, model, cost?}` |
331
+ | POST | `/api/tts` | TTS: `{text, voice/voiceId, ttsModel?}` → `audio/mpeg` |
332
+ | POST | `/api/sfx` | SFX: `{text, durationSeconds?, promptInfluence?}` → `audio/mpeg` |
333
+ | POST | `/api/music` | Music: `{prompt, durationMs?}` → `audio/mpeg` |
334
+ | POST | `/api/generate` | image/video: `{kind, prompt, model, imageInputs?, aspectRatio?, ...}` → `{taskId}` |
335
+ | GET | `/api/poll?taskId=...` | poll → `{status: pending\|done\|error, url?, cost?}` |
336
+ | POST | `/api/upload` | upload binary, header `X-File-Name: ...` → `{url, hash, size}` |
337
+ | GET | `/api/proxy?url=...` | прокси для CORS-bypass |
338
+ | GET | `/api/balance/all` | балансы всех провайдеров |
339
+ | GET | `/api/voices` | список ElevenLabs голосов |
273
340
 
274
- ### `GET http://localhost:17893/api/proxy?url=...`
275
- Прокси для скачивания произвольных http(s)-URL минуя CORS.
341
+ Те же ключи и роутинг, что и CLI — не дублируй логику в curl-скриптах,
342
+ лучше используй `kingkont`.
276
343
 
277
344
  ## Распространённые сценарии для агента
278
345
 
279
- **«Открой редактор»** → `npx -y kingkont serve` + сообщить URL.
346
+ **«Открой редактор»** → `npx -y kingkont serve` + сообщить URL для Chrome.
280
347
 
281
- **«Добавь персонажа Анна»** → `mkdir -p _characters/Анна`, создать
282
- минимальный `_characters/Анна/scene.json`:
283
- ```json
284
- { "nodes": [], "connections": [], "character": { "voice": null }, "view": { "zoom": 1, "scrollLeft": 0, "scrollTop": 0 }, "timeline": { "tracks": [], "playhead": 0 } }
348
+ **«Добавь персонажа Анна»**:
349
+ ```bash
350
+ mkdir -p <project>/_characters/Анна
351
+ echo '{"nodes":[],"connections":[]}' > <project>/_characters/Анна/scene.json
352
+ # Дальше — генерим character sheet:
353
+ kingkont gen <project> _characters/Анна --kind=image --name=sheet \
354
+ --prompt="портрет молодой женщины-следователя" --model=nano-banana-2
355
+ ```
356
+
357
+ **«Добавь текстовую ноду на сцену "Прощание" с таким текстом …»**:
358
+ ```bash
359
+ kingkont add-node <project> Прощание --kind=text --name=plot --text="ТЕКСТ"
360
+ ```
361
+
362
+ **«Свяжи ноды @А и @Б»**:
363
+ ```bash
364
+ kingkont connect <project> Прощание А Б
285
365
  ```
286
366
 
287
- **«Добавь текстовую ноду на сцену "Прощание" с таким текстом ...»**:
288
- 1. Записать `Прощание/texts/<slug>.md` с текстом.
289
- 2. Прочитать `Прощание/scene.json`, добавить новую node-запись (`type: 'text'`,
290
- уникальный uuid v4, `file: "texts/<slug>.md"`, `x/y` подальше от
291
- существующих), записать обратно.
367
+ **«Сгенерируй SFX "камни сыпятся"»**:
368
+ ```bash
369
+ kingkont gen <project> <board> --kind=audio --sub-kind=sfx \
370
+ --prompt="rocks falling, gravel cascading" --duration=3
371
+ ```
372
+ (SFX-модель ElevenLabs работает лучше на английском — переводи русский промпт.)
292
373
 
293
- **«Свяжи ноды и @Б»** → найти их id по `name` в `scene.json`, добавить
294
- `{from: "<id-A>", to: "<id-Б>"}` в `connections[]`.
374
+ **«Сделай i2v видео из этой картинки»**:
375
+ ```bash
376
+ # Нода @hero уже есть в этой доске:
377
+ kingkont gen <project> <board> --kind=video --refs=@hero \
378
+ --model=kling-3.0 --prompt="hero turns and walks away"
379
+ ```
295
380
 
296
- **«Сгенерируй SFX "камни сыпятся"»** → `POST /api/sfx` с translated en-промптом
297
- (модель Sound Generation на не-en тексте делает TTS-fallback), сохранить mp3
298
- в `<board>/audio/sfx_<ts>.mp3`, добавить audio-ноду в scene.json с
299
- `generated.subKind = "sfx"`.
381
+ ## Не трогай руками
300
382
 
301
- **Не трогай**: `node.history[]`, `metadata.history.past/future` — это
302
- снимки сцены для Cmd+Z. Поломав, потеряешь возможность отката. Поля с
303
- UUID `id` тоже не меняй на них завязаны связи и timeline-clips.
383
+ - `node.history[]`, `metadata.history.past/future` — снимки сцены для Cmd+Z.
384
+ - `id` нод (UUID) на них завязаны связи и timeline-clips.
385
+ - `_deleted/` корзина (юзер может восстановить через Cmd+Z в редакторе).
304
386
 
305
387
  ## Шорткаты редактора (для подсказок юзеру)
306
388