kingkont 0.3.0 → 0.4.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/skill/SKILL.md +284 -53
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -1,84 +1,315 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: kingkont
|
|
3
|
-
description: Use this skill when the user
|
|
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` для визуальной работы.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# KingKont · Chatium — Skill
|
|
7
7
|
|
|
8
|
-
KingKont
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
KingKont — нод-редактор сцен фильма/сериала с AI-генерацией. Каждая сцена/
|
|
9
|
+
персонаж/локация — папка на диске с `scene.json` и подпапками для медиа.
|
|
10
|
+
Формат plain JSON + plain files: всё можно читать и менять руками или
|
|
11
|
+
через AI-агента, не запуская сам редактор.
|
|
11
12
|
|
|
12
|
-
##
|
|
13
|
+
## Когда использовать этот skill
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
- Юзер работает в папке-проекте KingKont (есть `_characters/`,
|
|
16
|
+
`_locations/`, любая папка с `scene.json`, или файл `CLAUDE.md` в корне).
|
|
17
|
+
- Просит «открой редактор», «запусти kingkont», «открой проект» —
|
|
18
|
+
поднимаешь UI через `npx -y kingkont serve` (см. ниже).
|
|
19
|
+
- Просит править данные: «добавь персонажа Анна», «добавь сцену
|
|
20
|
+
«Прощание»», «вставь текстовую ноду на сцену 3 с этим текстом», «свяжи
|
|
21
|
+
ноды @Анна и @сценарий», «сгенерируй картинку», «озвучь реплику» — это
|
|
22
|
+
работа со scene.json и/или вызов API; делается без открытия UI.
|
|
23
|
+
- Любые правки тексту, перестановка нод, чистка истории, бэкап — все
|
|
24
|
+
через прямую правку `scene.json` и `texts/*.md`.
|
|
17
25
|
|
|
18
|
-
|
|
19
|
-
- "редактор сцен", "scene editor"
|
|
20
|
-
- "видео-редактор", "film editor"
|
|
21
|
-
- if the current folder contains `CLAUDE.md` mentioning "KingKont" or
|
|
22
|
-
has subfolders like `_characters/`, `_locations/` and `scene.json` files
|
|
23
|
-
— this is a KingKont project.
|
|
24
|
-
|
|
25
|
-
## How to launch
|
|
26
|
-
|
|
27
|
-
Run **in the current working directory** (the project root):
|
|
26
|
+
## Как открыть UI редактора
|
|
28
27
|
|
|
29
28
|
```bash
|
|
30
29
|
npx -y kingkont serve
|
|
31
30
|
```
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
3. Print `▶ KingKont готов: http://localhost:17893/` when ready.
|
|
37
|
-
|
|
38
|
-
Then tell the user to open the URL in **Chrome / Edge / Brave** (Safari and
|
|
39
|
-
Firefox do not support the File System Access API needed to open project
|
|
40
|
-
folders). On macOS you can open it for the user:
|
|
32
|
+
Печатает `▶ KingKont готов: http://localhost:17893/`. Скажи юзеру открыть
|
|
33
|
+
этот URL в **Chrome / Edge / Brave** (Safari/Firefox не поддерживают
|
|
34
|
+
File System Access API). На macOS можно открыть автоматом:
|
|
41
35
|
|
|
42
36
|
```bash
|
|
43
37
|
open -a "Google Chrome" "http://localhost:17893/"
|
|
44
38
|
```
|
|
45
39
|
|
|
46
|
-
|
|
47
|
-
folder.
|
|
40
|
+
Альтернатива — Electron-приложение (без браузера): `npx -y kingkont`.
|
|
48
41
|
|
|
49
|
-
##
|
|
42
|
+
## Формат проектной папки
|
|
50
43
|
|
|
51
44
|
```
|
|
52
|
-
<
|
|
53
|
-
├── CLAUDE.md
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
├──
|
|
57
|
-
│
|
|
58
|
-
|
|
59
|
-
│
|
|
60
|
-
|
|
61
|
-
│
|
|
62
|
-
|
|
45
|
+
<root>/
|
|
46
|
+
├── CLAUDE.md ← подробный формат (создаётся редактором при первом
|
|
47
|
+
│ открытии в его UI; идентичен этому skill, но
|
|
48
|
+
│ живёт рядом с проектом)
|
|
49
|
+
├── _characters/
|
|
50
|
+
│ └── <имя>/ ← одна доска на персонажа
|
|
51
|
+
├── _locations/
|
|
52
|
+
│ └── <имя>/ ← одна доска на локацию
|
|
53
|
+
├── <имя сцены>/ ← сцены лежат в корне как любые папки
|
|
54
|
+
│ │ (имена не начинающиеся с `_` и `.`,
|
|
55
|
+
│ │ не равные _characters / _locations)
|
|
56
|
+
│ ├── scene.json ← главный файл — описан ниже
|
|
57
|
+
│ ├── clips/ ← видео (mp4, mov, webm)
|
|
58
|
+
│ ├── images/ ← картинки (jpg, png, webp)
|
|
59
|
+
│ ├── audio/ ← аудио (mp3, wav, m4a)
|
|
60
|
+
│ └── texts/ ← .md-файлы текстовых нод
|
|
61
|
+
├── _deleted/ ← корзина: при удалении ноды/доски файл/папка
|
|
62
|
+
│ переезжает сюда. Cmd+Z в редакторе
|
|
63
|
+
│ восстанавливает.
|
|
64
|
+
└── (любые другие файлы редактор не трогает)
|
|
63
65
|
```
|
|
64
66
|
|
|
65
|
-
`scene.json`
|
|
67
|
+
## Формат `scene.json` (полный)
|
|
66
68
|
|
|
67
|
-
|
|
69
|
+
```json5
|
|
70
|
+
{
|
|
71
|
+
"nodes": [
|
|
72
|
+
{
|
|
73
|
+
"id": "uuid", // UUID v4, уникальный в пределах доски
|
|
74
|
+
"type": "image" | "video" | "audio" | "text",
|
|
75
|
+
"name": "опц. имя для @-ссылок", // используется в [@name] и автокомплите
|
|
76
|
+
"file": "images/foo.jpg", // относительный путь в папке доски
|
|
77
|
+
"x": 100, "y": 200, // координаты на холсте (логические px)
|
|
78
|
+
"width": 280, "height": 320, // опц., если юзер ресайзил
|
|
79
|
+
"generated": { // опц., если создано генерацией
|
|
80
|
+
"kind": "image" | "video" | "audio" | "text",
|
|
81
|
+
"subKind": "sfx" | "music", // только для audio: тип эффекта
|
|
82
|
+
"prompt": "...", // финальный промпт после resolve
|
|
83
|
+
"rawPrompt": "...", // исходный с [@ref]
|
|
84
|
+
"translatedPrompt": "...", // для SFX/music: en-перевод (для ElevenLabs)
|
|
85
|
+
"model": "nano-banana-2" | "bytedance/seedance-2"
|
|
86
|
+
| "eleven_v3" | "eleven-sfx" | "eleven-music"
|
|
87
|
+
| "anthropic/claude-sonnet-4" | ...,
|
|
88
|
+
"modelKey": "ключ модели для KIE",
|
|
89
|
+
"voiceId": "...", // для голоса
|
|
90
|
+
"voiceName": "...",
|
|
91
|
+
"tones": ["шепот", ...], // ElevenLabs v3 audio-tags
|
|
92
|
+
"durationSeconds": 3, // для SFX
|
|
93
|
+
"durationMs": 30000, // для music
|
|
94
|
+
"refs": [{ "name": "...", "type": "image", "file": "..." }],
|
|
95
|
+
"state": "submitting" | "queued" | "generating" | "success" | "error",
|
|
96
|
+
"taskId": "..." // KIE job id
|
|
97
|
+
},
|
|
98
|
+
"status": "generating" | "draft" | "error", // отсутствует если нода готова
|
|
99
|
+
"error": "...",
|
|
100
|
+
"history": [...], // история правок (через ⇄ Заменить)
|
|
101
|
+
"historyIndex": 0
|
|
102
|
+
}
|
|
103
|
+
// Текст ноды (n.text для type=text) в JSON НЕ хранится; контент лежит в texts/<file>.md
|
|
104
|
+
],
|
|
105
|
+
"connections": [
|
|
106
|
+
{ "from": "node-id", "to": "node-id" } // направленная связь
|
|
107
|
+
],
|
|
108
|
+
"view": {
|
|
109
|
+
"scrollLeft": 0, // pan/zoom холста для восстановления
|
|
110
|
+
"scrollTop": 0,
|
|
111
|
+
"zoom": 1.0
|
|
112
|
+
},
|
|
113
|
+
"character": { // только для _characters/<name>/scene.json
|
|
114
|
+
"characterSheet": "images/sheet.jpg", // референс-картинка персонажа
|
|
115
|
+
"voice": "elevenlabs-voice-id", // дефолтный голос для генерации
|
|
116
|
+
"voiceName": "...",
|
|
117
|
+
"tone": "по умолчанию",
|
|
118
|
+
"commonTones": ["шепот", "крик", ...],
|
|
119
|
+
"lastTones": [],
|
|
120
|
+
"replicas": [
|
|
121
|
+
{ "id": "...", "text": "...", "audio": "audio/replica_1.mp3", ... }
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
"location": { // только для _locations/<name>/scene.json
|
|
125
|
+
"sheet": "images/sheet.jpg"
|
|
126
|
+
},
|
|
127
|
+
"timeline": { // монтажный лист сцены
|
|
128
|
+
"tracks": [
|
|
129
|
+
{
|
|
130
|
+
"id": "tv",
|
|
131
|
+
"name": "Видео" | "Голос" | "Эффекты" | "Музыка" | ...,
|
|
132
|
+
"kind": "video" | "audio",
|
|
133
|
+
"clips": [
|
|
134
|
+
{
|
|
135
|
+
"id": "uuid",
|
|
136
|
+
"nodeId": "node-id" | null, // привязка к ноде (если из неё)
|
|
137
|
+
"type": "video" | "image" | "audio",
|
|
138
|
+
"file": "clips/foo.mp4",
|
|
139
|
+
"name": "...",
|
|
140
|
+
"duration": 5.0, // в секундах
|
|
141
|
+
"start": 0, // позиция начала на дорожке
|
|
142
|
+
"trimStart": 0, // обрезка спереди
|
|
143
|
+
"sourceDuration": 5.0, // полная длительность файла
|
|
144
|
+
"_durationLoaded": true,
|
|
145
|
+
"groupId": "...", // опц., группа клипов
|
|
146
|
+
"disabled": false // skip при playback
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
],
|
|
151
|
+
"playhead": 0.27 // секунды
|
|
152
|
+
},
|
|
153
|
+
"history": { // undo/redo стек редактора
|
|
154
|
+
"past": [{ "ts": ..., "label": "...", "snap": "JSON-string", "movedFiles": [...] }],
|
|
155
|
+
"future": [...]
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
68
159
|
|
|
69
|
-
|
|
70
|
-
- **KIE** for images/video
|
|
71
|
-
- **ElevenLabs** for voice/SFX/music
|
|
72
|
-
- **OpenRouter** for text and vision
|
|
160
|
+
## Текстовые ноды
|
|
73
161
|
|
|
74
|
-
|
|
75
|
-
|
|
162
|
+
`node.text` в JSON отсутствует. Контент текстовой ноды лежит в
|
|
163
|
+
`texts/<filename>.md` (путь в `node.file`). Редактируй .md руками; редактор
|
|
164
|
+
подхватит изменения при следующем открытии доски.
|
|
76
165
|
|
|
77
|
-
|
|
166
|
+
Чтобы создать новую текстовую ноду через правку файлов:
|
|
78
167
|
|
|
79
|
-
|
|
80
|
-
|
|
168
|
+
1. Записать содержимое в `<board>/texts/some-name.md`.
|
|
169
|
+
2. Добавить ноду в `<board>/scene.json`:
|
|
170
|
+
```json5
|
|
171
|
+
{
|
|
172
|
+
"id": "<uuid v4>",
|
|
173
|
+
"type": "text",
|
|
174
|
+
"name": "опционально, для @-ссылок",
|
|
175
|
+
"file": "texts/some-name.md",
|
|
176
|
+
"x": 100, "y": 100
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Файловые операции
|
|
181
|
+
|
|
182
|
+
- **Удаление ноды**: файл переезжает в `<root>/_deleted/<уникальное-имя>`.
|
|
183
|
+
Cmd+Z в редакторе восстанавливает (через movedFiles в history).
|
|
184
|
+
- **Замена/перегенерация**: новый файл записывается в подпапку, старый
|
|
185
|
+
сохраняется в `node.history[]` для отката (⇄ Заменить).
|
|
186
|
+
- **Импорт через drag-drop**: файлы копируются в правильную подпапку с
|
|
187
|
+
уникальным именем, нода создаётся автоматически.
|
|
188
|
+
|
|
189
|
+
## API-ключи (для генерации)
|
|
190
|
+
|
|
191
|
+
Хранятся в `~/Library/Application Support/KingKont/settings.json` (macOS)
|
|
192
|
+
или `~/.config/KingKont/settings.json` (Linux):
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"kieKey": "...", // для картинок и видео (api.kie.ai)
|
|
197
|
+
"elevenKey": "...", // для голоса/SFX/музыки (elevenlabs.io)
|
|
198
|
+
"openrouterKey": "..." // для текста и vision (openrouter.ai)
|
|
199
|
+
}
|
|
81
200
|
```
|
|
82
201
|
|
|
83
|
-
|
|
84
|
-
|
|
202
|
+
Если ключа не хватает — попроси юзера задать в редакторе через `Cmd+,`.
|
|
203
|
+
|
|
204
|
+
## Программная генерация (без UI)
|
|
205
|
+
|
|
206
|
+
Запусти `npx kingkont serve` в фоне — сервер становится прокси к KIE/
|
|
207
|
+
ElevenLabs/OpenRouter с уже подставленными ключами из settings.json.
|
|
208
|
+
Дёргай endpoints прямым curl/fetch:
|
|
209
|
+
|
|
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
|
+
}
|
|
218
|
+
```
|
|
219
|
+
Возвращает `{ "text": "...", "model": "..." }`.
|
|
220
|
+
|
|
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
|
+
}
|
|
228
|
+
```
|
|
229
|
+
Возвращает `audio/mpeg` (mp3 stream). Сохрани в `<board>/audio/sfx_<ts>.mp3`.
|
|
230
|
+
|
|
231
|
+
### `POST http://localhost:17893/api/music` — музыка (ElevenLabs)
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"prompt": "epic orchestral cinematic, slow buildup, hopeful",
|
|
235
|
+
"durationMs": 30000 // опц.
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
Возвращает `audio/mpeg`.
|
|
239
|
+
|
|
240
|
+
### `POST http://localhost:17893/api/tts` — речь (ElevenLabs)
|
|
241
|
+
```json
|
|
242
|
+
{
|
|
243
|
+
"text": "...",
|
|
244
|
+
"voiceId": "JBFqnCBsd6RMkjVDRZzb", // ElevenLabs voice id
|
|
245
|
+
"modelId": "eleven_v3"
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
Возвращает `audio/mpeg`.
|
|
249
|
+
|
|
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
|
+
}
|
|
262
|
+
```
|
|
263
|
+
Возвращает `{ "taskId": "..." }`. Затем поллить:
|
|
264
|
+
|
|
265
|
+
### `GET http://localhost:17893/api/poll?taskId=...`
|
|
266
|
+
Возвращает `{ "status": "pending" | "done" | "error", "url": "https://..." }`.
|
|
267
|
+
Когда `done` — скачай `url` (это публичный URL картинки/видео).
|
|
268
|
+
|
|
269
|
+
### `POST http://localhost:17893/api/upload` — загрузить локальный файл в KIE
|
|
270
|
+
Передай binary в body, заголовок `X-File-Name: filename.jpg`.
|
|
271
|
+
Возвращает `{ "url": "https://..." }` — этот URL можно класть в
|
|
272
|
+
`imageInputs`.
|
|
273
|
+
|
|
274
|
+
### `GET http://localhost:17893/api/proxy?url=...`
|
|
275
|
+
Прокси для скачивания произвольных http(s)-URL минуя CORS.
|
|
276
|
+
|
|
277
|
+
## Распространённые сценарии для агента
|
|
278
|
+
|
|
279
|
+
**«Открой редактор»** → `npx -y kingkont serve` + сообщить URL.
|
|
280
|
+
|
|
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 } }
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**«Добавь текстовую ноду на сцену "Прощание" с таким текстом ...»**:
|
|
288
|
+
1. Записать `Прощание/texts/<slug>.md` с текстом.
|
|
289
|
+
2. Прочитать `Прощание/scene.json`, добавить новую node-запись (`type: 'text'`,
|
|
290
|
+
уникальный uuid v4, `file: "texts/<slug>.md"`, `x/y` подальше от
|
|
291
|
+
существующих), записать обратно.
|
|
292
|
+
|
|
293
|
+
**«Свяжи ноды @А и @Б»** → найти их id по `name` в `scene.json`, добавить
|
|
294
|
+
`{from: "<id-A>", to: "<id-Б>"}` в `connections[]`.
|
|
295
|
+
|
|
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"`.
|
|
300
|
+
|
|
301
|
+
**Не трогай**: `node.history[]`, `metadata.history.past/future` — это
|
|
302
|
+
снимки сцены для Cmd+Z. Поломав, потеряешь возможность отката. Поля с
|
|
303
|
+
UUID `id` тоже не меняй — на них завязаны связи и timeline-clips.
|
|
304
|
+
|
|
305
|
+
## Шорткаты редактора (для подсказок юзеру)
|
|
306
|
+
|
|
307
|
+
- `Cmd+O` — открыть проект
|
|
308
|
+
- `Cmd+N` — новая сцена
|
|
309
|
+
- `Cmd+W` — закрыть проект (при втором нажатии — свернуть)
|
|
310
|
+
- `Cmd+,` — настройки (API-ключи)
|
|
311
|
+
- `Cmd+Z` / `Cmd+Shift+Z` — undo/redo
|
|
312
|
+
- `Cmd+X / C / V` — cut/copy/paste нод и клипов
|
|
313
|
+
- ПКМ по ноде / клипу / папке — контекст-меню
|
|
314
|
+
- ПКМ на пустом холсте — добавить новую ноду (Текст / Сгенерить ...)
|
|
315
|
+
- Тяга от точки на правом краю ноды → меню «что генерить»
|