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/assets/PROJECT_CLAUDE.md +31 -132
- package/bin/kingkont.js +59 -49
- package/index.html +9 -10137
- package/lib/cli.js +504 -0
- package/lib/projectFs.js +391 -0
- package/lib/providers.js +689 -0
- package/lib/settings.js +70 -0
- package/main.js +28 -0
- package/package.json +6 -1
- package/preload.js +7 -0
- package/renderer/board.js +1522 -0
- package/renderer/generate.js +1727 -0
- package/renderer/media.js +1413 -0
- package/renderer/settings.js +1128 -0
- package/renderer/state.js +566 -0
- package/renderer/styles.css +1018 -0
- package/renderer/timeline.js +2836 -0
- package/server.js +103 -787
- package/settings.html +56 -0
- package/skill/SKILL.md +160 -78
package/lib/settings.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Загрузка настроек KingKont — общая для server.js, main.js (Electron) и
|
|
2
|
+
// bin/kingkont.js (CLI). Источник правды — userData/settings.json,
|
|
3
|
+
// который пишется главным процессом Electron.
|
|
4
|
+
//
|
|
5
|
+
// Структура settings.json:
|
|
6
|
+
// {
|
|
7
|
+
// // Провайдеры — какие включены (use* checkbox в UI):
|
|
8
|
+
// useChatium: bool,
|
|
9
|
+
// useOpenrouter: bool,
|
|
10
|
+
// useElevenlabs: bool,
|
|
11
|
+
// useKie: bool,
|
|
12
|
+
// // Прямые ключи (если юзер подключил провайдеров напрямую):
|
|
13
|
+
// kieKey: '...',
|
|
14
|
+
// elevenKey: '...',
|
|
15
|
+
// openrouterKey: '...',
|
|
16
|
+
// // Chatium-сессия (логин по token-flow):
|
|
17
|
+
// chatium: { token: '...', base: 'https://kingkont.ru', userId, appName }
|
|
18
|
+
// }
|
|
19
|
+
|
|
20
|
+
'use strict';
|
|
21
|
+
|
|
22
|
+
const fs = require('node:fs');
|
|
23
|
+
const os = require('node:os');
|
|
24
|
+
const path = require('node:path');
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Кросс-платформенный путь к userData/settings.json.
|
|
28
|
+
* macOS: ~/Library/Application Support/KingKont/settings.json
|
|
29
|
+
* Linux: ~/.config/KingKont/settings.json
|
|
30
|
+
* Windows: %APPDATA%\KingKont\settings.json
|
|
31
|
+
*/
|
|
32
|
+
function defaultSettingsPath() {
|
|
33
|
+
if (process.platform === 'darwin') {
|
|
34
|
+
return path.join(os.homedir(), 'Library', 'Application Support', 'KingKont', 'settings.json');
|
|
35
|
+
}
|
|
36
|
+
if (process.platform === 'win32') {
|
|
37
|
+
const appData = process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');
|
|
38
|
+
return path.join(appData, 'KingKont', 'settings.json');
|
|
39
|
+
}
|
|
40
|
+
return path.join(process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config'), 'KingKont', 'settings.json');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Прочитать settings.json. Если нет — вернёт {} (не падаем). */
|
|
44
|
+
function loadSettings(p = defaultSettingsPath()) {
|
|
45
|
+
try {
|
|
46
|
+
if (!fs.existsSync(p)) return {};
|
|
47
|
+
return JSON.parse(fs.readFileSync(p, 'utf-8'));
|
|
48
|
+
} catch {
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Прокидывает прямые API-ключи в process.env, если они есть.
|
|
55
|
+
* server.js / lib/providers ожидают KIE_API_KEY / ELEVENLABS_API_KEY /
|
|
56
|
+
* OPENROUTER_API_KEY в env (исторически, для совместимости с .env).
|
|
57
|
+
* Безопасно вызывать многократно.
|
|
58
|
+
*/
|
|
59
|
+
function applySettingsToEnv(s) {
|
|
60
|
+
if (!s) return;
|
|
61
|
+
if (s.kieKey) process.env.KIE_API_KEY = s.kieKey;
|
|
62
|
+
if (s.elevenKey) process.env.ELEVENLABS_API_KEY = s.elevenKey;
|
|
63
|
+
if (s.openrouterKey) process.env.OPENROUTER_API_KEY = s.openrouterKey;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = {
|
|
67
|
+
defaultSettingsPath,
|
|
68
|
+
loadSettings,
|
|
69
|
+
applySettingsToEnv,
|
|
70
|
+
};
|
package/main.js
CHANGED
|
@@ -9,6 +9,7 @@ app.setName('KingKont');
|
|
|
9
9
|
const { spawn } = require('node:child_process');
|
|
10
10
|
const path = require('node:path');
|
|
11
11
|
const fs = require('node:fs');
|
|
12
|
+
const os = require('node:os');
|
|
12
13
|
const { start } = require('./server');
|
|
13
14
|
|
|
14
15
|
let win = null;
|
|
@@ -153,6 +154,31 @@ ipcMain.handle('claudeMd:template', () => {
|
|
|
153
154
|
catch { return ''; }
|
|
154
155
|
});
|
|
155
156
|
|
|
157
|
+
// Установить kingkont skill в ~/.claude/skills/kingkont/SKILL.md
|
|
158
|
+
// (на Windows: %USERPROFILE%\.claude\skills\kingkont\SKILL.md).
|
|
159
|
+
// То же самое что `kingkont install-skill` в CLI — для юзеров которые
|
|
160
|
+
// никогда не запускали bin/kingkont напрямую (только Electron-приложение).
|
|
161
|
+
//
|
|
162
|
+
// Read+write, не copyFileSync — source может лежать внутри app.asar в
|
|
163
|
+
// bundled-сборке (.dmg/.exe), там copy с asar→disk периодически глючит.
|
|
164
|
+
ipcMain.handle('claudeMd:installSkill', () => {
|
|
165
|
+
try {
|
|
166
|
+
const src = path.join(__dirname, 'skill', 'SKILL.md');
|
|
167
|
+
let buf;
|
|
168
|
+
try { buf = fs.readFileSync(src); }
|
|
169
|
+
catch (e) {
|
|
170
|
+
return { ok: false, error: 'Шаблон skill/SKILL.md не найден в пакете: ' + e.message };
|
|
171
|
+
}
|
|
172
|
+
const dest = path.join(os.homedir(), '.claude', 'skills', 'kingkont');
|
|
173
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
174
|
+
const destFile = path.join(dest, 'SKILL.md');
|
|
175
|
+
fs.writeFileSync(destFile, buf);
|
|
176
|
+
return { ok: true, path: destFile };
|
|
177
|
+
} catch (e) {
|
|
178
|
+
return { ok: false, error: e?.message || String(e) };
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
156
182
|
ipcMain.handle('settings:get', () => readSettings());
|
|
157
183
|
ipcMain.handle('settings:save', (_e, partial) => {
|
|
158
184
|
const cur = readSettings();
|
|
@@ -476,6 +502,8 @@ ipcMain.handle('updates:install', async (e, target = 'latest') => {
|
|
|
476
502
|
});
|
|
477
503
|
});
|
|
478
504
|
|
|
505
|
+
ipcMain.handle('app:version', () => app.getVersion());
|
|
506
|
+
|
|
479
507
|
ipcMain.handle('app:relaunch', () => {
|
|
480
508
|
// app.relaunch() запускает ТЕКУЩИЙ execPath. Если юзер обновился через
|
|
481
509
|
// `npm i -g`, новая kingkont лежит в global-bin, а не в npx-кэше где сидит
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kingkont",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.41",
|
|
4
4
|
"description": "KingKont \u00b7 Chatium \u2014 \u043d\u043e\u0434-\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0441\u0446\u0435\u043d \u0441 AI-\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0435\u0439 (\u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438/\u0432\u0438\u0434\u0435\u043e/\u0433\u043e\u043b\u043e\u0441/SFX/\u043c\u0443\u0437\u044b\u043a\u0430/\u0442\u0435\u043a\u0441\u0442)",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"bin": {
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
"settings.html",
|
|
15
15
|
"assets/**/*",
|
|
16
16
|
"bin/**/*",
|
|
17
|
+
"lib/**/*",
|
|
18
|
+
"renderer/**/*",
|
|
17
19
|
"scripts/**/*",
|
|
18
20
|
"skill/**/*",
|
|
19
21
|
"README.md",
|
|
@@ -59,6 +61,9 @@
|
|
|
59
61
|
"index.html",
|
|
60
62
|
"settings.html",
|
|
61
63
|
"assets/**/*",
|
|
64
|
+
"lib/**/*",
|
|
65
|
+
"renderer/**/*",
|
|
66
|
+
"skill/**/*",
|
|
62
67
|
"package.json",
|
|
63
68
|
"updates.html"
|
|
64
69
|
],
|
package/preload.js
CHANGED
|
@@ -29,6 +29,12 @@ contextBridge.exposeInMainWorld('appWindow', {
|
|
|
29
29
|
minimize: () => ipcRenderer.invoke('window:minimize'),
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
+
// Версия приложения — пробрасываем app.getVersion() из main, чтобы рендер
|
|
33
|
+
// показывал актуальный номер на welcome-экране и в шапке.
|
|
34
|
+
contextBridge.exposeInMainWorld('appInfo', {
|
|
35
|
+
version: () => ipcRenderer.invoke('app:version'),
|
|
36
|
+
});
|
|
37
|
+
|
|
32
38
|
contextBridge.exposeInMainWorld('appProject', {
|
|
33
39
|
notifyState: (isOpen) => ipcRenderer.send('project:state', !!isOpen),
|
|
34
40
|
});
|
|
@@ -76,4 +82,5 @@ contextBridge.exposeInMainWorld('appChatium', {
|
|
|
76
82
|
|
|
77
83
|
contextBridge.exposeInMainWorld('claudeMd', {
|
|
78
84
|
template: () => ipcRenderer.invoke('claudeMd:template'),
|
|
85
|
+
installSkill: () => ipcRenderer.invoke('claudeMd:installSkill'),
|
|
79
86
|
});
|