docs-combiner 0.2.2 → 1.0.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/dist/agentApi/agentControlClaim.js +26 -0
- package/dist/agentApi/approachMatrixView.js +19 -0
- package/dist/agentApi/capabilitiesMeta.js +78 -0
- package/dist/agentApi/catalogUrlPresets.js +26 -0
- package/dist/agentApi/constants.js +11 -0
- package/dist/agentApi/creativeSelections.js +25 -0
- package/dist/agentApi/escalation.js +221 -0
- package/dist/agentApi/generatedPairsGuard.js +85 -0
- package/dist/agentApi/httpHelpers.js +77 -0
- package/dist/agentApi/imagesReadiness.js +60 -0
- package/dist/agentApi/jobStatus.js +113 -0
- package/dist/agentApi/productImageDrive.js +39 -0
- package/dist/agentApi/regenerateImages.js +125 -0
- package/dist/agentApi/rendererTypes.js +3 -0
- package/dist/agentApi/routes.js +440 -0
- package/dist/agentApi/sessionSnapshot.js +82 -0
- package/dist/agentApi/sessionTypes.js +2 -0
- package/dist/agentApi/spec.js +1045 -0
- package/dist/agentApi/types.js +2 -0
- package/dist/agentApi/validation.js +32 -0
- package/dist/campaignsCsv.js +420 -0
- package/dist/contentPairs.js +62 -0
- package/dist/flexcardBalance.js +88 -0
- package/dist/integrations/driveApi.js +420 -0
- package/dist/integrations/httpTimeout.js +116 -0
- package/dist/integrations/openrouter.js +532 -0
- package/dist/main.js +830 -165
- package/dist/models.js +17 -0
- package/dist/offerSettings.js +19 -0
- package/dist/preload.js +28 -0
- package/dist/promptOverrides.js +437 -0
- package/dist/prompts.js +1243 -0
- package/dist/renderer.js +19 -19
- package/dist/renderer.js.LICENSE.txt +4 -0
- package/dist/renderer.js.map +1 -1
- package/dist/server/app.js +378 -0
- package/dist/server/auth.js +74 -0
- package/dist/server/contentJobs.js +367 -0
- package/dist/server/driveCatalog.js +122 -0
- package/dist/server/driveProxy.js +220 -0
- package/dist/server/flexcardMeta.js +29 -0
- package/dist/server/googleAuth.js +84 -0
- package/dist/server/imageAssets.js +87 -0
- package/dist/server/imageJobs.js +776 -0
- package/dist/server/index.js +38 -0
- package/dist/server/jobEvents.js +116 -0
- package/dist/server/jobs.js +358 -0
- package/dist/server/openRouterMeta.js +58 -0
- package/dist/server/spec.js +544 -0
- package/dist/server/storage.js +133 -0
- package/dist/server/telegram.js +53 -0
- package/dist/server/workspaceSnapshot.js +273 -0
- package/package.json +18 -4
package/dist/models.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Конфигурация моделей для генерации контента
|
|
4
|
+
* Здесь можно легко изменить модели для разных задач
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.MODELS = void 0;
|
|
8
|
+
exports.MODELS = {
|
|
9
|
+
// Модель для генерации заголовков и текстов
|
|
10
|
+
contentGeneration: 'openai/gpt-5.2',
|
|
11
|
+
// Модель для генерации изображений креативов
|
|
12
|
+
// imageGeneration: 'openai/gpt-5-image',
|
|
13
|
+
imageGeneration: 'openai/gpt-5-image-mini',
|
|
14
|
+
// Модель для валидации креативов
|
|
15
|
+
// creativeValidation: 'openai/gpt-4o',
|
|
16
|
+
creativeValidation: 'openai/gpt-5.2-pro',
|
|
17
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OFFER_SETTINGS_FILENAME = void 0;
|
|
4
|
+
exports.parseOfferSettingsData = parseOfferSettingsData;
|
|
5
|
+
exports.OFFER_SETTINGS_FILENAME = 'offer-settings.json';
|
|
6
|
+
/** Разбор offer-settings.json из папки оффера. */
|
|
7
|
+
function parseOfferSettingsData(data) {
|
|
8
|
+
const empty = { generateProduct: '', generateAdditionalInfo: '' };
|
|
9
|
+
if (!data || typeof data !== 'object')
|
|
10
|
+
return empty;
|
|
11
|
+
const settings = data.aiGenerationSettings;
|
|
12
|
+
if (!settings || typeof settings !== 'object')
|
|
13
|
+
return empty;
|
|
14
|
+
const ai = settings;
|
|
15
|
+
return {
|
|
16
|
+
generateProduct: typeof ai.generateProduct === 'string' ? ai.generateProduct : '',
|
|
17
|
+
generateAdditionalInfo: typeof ai.generateAdditionalInfo === 'string' ? ai.generateAdditionalInfo : '',
|
|
18
|
+
};
|
|
19
|
+
}
|
package/dist/preload.js
CHANGED
|
@@ -58,6 +58,34 @@ electron_1.contextBridge.exposeInMainWorld('electronAPI', {
|
|
|
58
58
|
reopenPendingAuthBrowser: () => electron_1.ipcRenderer.invoke('reopen-pending-auth-browser'),
|
|
59
59
|
cancelPendingAuth: () => electron_1.ipcRenderer.invoke('cancel-pending-auth'),
|
|
60
60
|
openExternal: (url) => electron_1.ipcRenderer.invoke('open-external', url),
|
|
61
|
+
registerWorkspaceFolder: (folderId) => electron_1.ipcRenderer.invoke('register-workspace-folder', folderId),
|
|
62
|
+
unregisterWorkspaceFolder: (folderId) => electron_1.ipcRenderer.invoke('unregister-workspace-folder', folderId),
|
|
63
|
+
newWindow: (workspaceId) => electron_1.ipcRenderer.invoke('new-window', workspaceId),
|
|
64
|
+
loadWorkspaceSnapshot: (workspaceId) => electron_1.ipcRenderer.invoke('load-workspace-snapshot', workspaceId),
|
|
65
|
+
saveWorkspaceSnapshot: (snapshot) => electron_1.ipcRenderer.invoke('save-workspace-snapshot', snapshot),
|
|
66
|
+
setWorkspaceWindowMeta: (payload) => electron_1.ipcRenderer.invoke('set-workspace-window-meta', payload),
|
|
67
|
+
listWorkspaceWindows: () => electron_1.ipcRenderer.invoke('list-workspace-windows'),
|
|
68
|
+
focusWorkspaceWindow: (webContentsId) => electron_1.ipcRenderer.invoke('focus-workspace-window', webContentsId),
|
|
69
|
+
closeWorkspaceWindow: (webContentsId) => electron_1.ipcRenderer.invoke('close-workspace-window', webContentsId),
|
|
70
|
+
closeAllWorkspaceWindows: () => electron_1.ipcRenderer.invoke('close-all-workspace-windows'),
|
|
71
|
+
closeOtherWorkspaceWindows: () => electron_1.ipcRenderer.invoke('close-other-workspace-windows'),
|
|
72
|
+
getAgentControlMode: () => electron_1.ipcRenderer.invoke('get-agent-control-mode'),
|
|
73
|
+
releaseAgentControl: () => electron_1.ipcRenderer.invoke('release-agent-control'),
|
|
74
|
+
onAgentControlModeChanged: (callback) => {
|
|
75
|
+
const listener = (_event, payload) => callback(payload);
|
|
76
|
+
electron_1.ipcRenderer.on('agent-control-mode-changed', listener);
|
|
77
|
+
return () => electron_1.ipcRenderer.removeListener('agent-control-mode-changed', listener);
|
|
78
|
+
},
|
|
79
|
+
onWorkspaceWindowsUpdated: (callback) => {
|
|
80
|
+
const listener = (_event, windows) => callback(windows);
|
|
81
|
+
electron_1.ipcRenderer.on('workspace-windows-updated', listener);
|
|
82
|
+
return () => electron_1.ipcRenderer.removeListener('workspace-windows-updated', listener);
|
|
83
|
+
},
|
|
84
|
+
onConfigUpdated: (callback) => {
|
|
85
|
+
const listener = (_event, config) => callback(config);
|
|
86
|
+
electron_1.ipcRenderer.on('config-updated', listener);
|
|
87
|
+
return () => electron_1.ipcRenderer.removeListener('config-updated', listener);
|
|
88
|
+
},
|
|
61
89
|
log: (level, ...args) => electron_1.ipcRenderer.invoke('log', level, ...args),
|
|
62
90
|
telegramSendTest: (botToken, chatId) => electron_1.ipcRenderer.invoke('telegram-send-test', { botToken, chatId }),
|
|
63
91
|
telegramSendMessage: (botToken, chatId, text) => electron_1.ipcRenderer.invoke('telegram-send-message', { botToken, chatId, text }),
|
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Утилиты для работы с oверрайдами промптов
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PROMPT_OVERRIDES_SAVED_EVENT = exports.MAX_IMAGES_PER_CREO_APPROACH = exports.PRODUCT_TYPE_IMAGE_PRESETS = exports.PRODUCT_TYPE_TEXT_PAIR_PRESETS = void 0;
|
|
7
|
+
exports.productPresetNumbersToIndices = productPresetNumbersToIndices;
|
|
8
|
+
exports.productPresetNumbersToImageCounts = productPresetNumbersToImageCounts;
|
|
9
|
+
exports.getSelectedPairApproaches = getSelectedPairApproaches;
|
|
10
|
+
exports.getPairsCount = getPairsCount;
|
|
11
|
+
exports.normalizeImageApproachCountsLength = normalizeImageApproachCountsLength;
|
|
12
|
+
exports.normalizeApproachMatrixFromDrive = normalizeApproachMatrixFromDrive;
|
|
13
|
+
exports.textApproachIndicesFromMatrix = textApproachIndicesFromMatrix;
|
|
14
|
+
exports.imageApproachCountsFromMatrix = imageApproachCountsFromMatrix;
|
|
15
|
+
exports.normalizeSelectedPairApproachesFromDrive = normalizeSelectedPairApproachesFromDrive;
|
|
16
|
+
exports.normalizeImageApproachCountsFromDrive = normalizeImageApproachCountsFromDrive;
|
|
17
|
+
exports.getImageBulletsGlobalOff = getImageBulletsGlobalOff;
|
|
18
|
+
exports.getImageApproachNoBulletsMode = getImageApproachNoBulletsMode;
|
|
19
|
+
exports.getImageApproachCounts = getImageApproachCounts;
|
|
20
|
+
exports.loadPromptOverrides = loadPromptOverrides;
|
|
21
|
+
exports.savePromptOverrides = savePromptOverrides;
|
|
22
|
+
exports.parseApproachesFromDriveData = parseApproachesFromDriveData;
|
|
23
|
+
exports.applyParsedApproachesFromDrive = applyParsedApproachesFromDrive;
|
|
24
|
+
exports.mergePromptApproachesFromDriveFile = mergePromptApproachesFromDriveFile;
|
|
25
|
+
exports.getPromptOverride = getPromptOverride;
|
|
26
|
+
exports.setPromptOverride = setPromptOverride;
|
|
27
|
+
exports.getCreoApproachOverride = getCreoApproachOverride;
|
|
28
|
+
exports.setCreoApproachOverride = setCreoApproachOverride;
|
|
29
|
+
exports.resetPromptOverride = resetPromptOverride;
|
|
30
|
+
exports.resetCreoApproachOverride = resetCreoApproachOverride;
|
|
31
|
+
exports.resetAllOverrides = resetAllOverrides;
|
|
32
|
+
exports.loadOverridesFromElectron = loadOverridesFromElectron;
|
|
33
|
+
const prompts_1 = require("./prompts");
|
|
34
|
+
const STORAGE_KEY = 'promptOverrides';
|
|
35
|
+
function stripWorkspaceSelections(overrides) {
|
|
36
|
+
const next = Object.assign({}, overrides);
|
|
37
|
+
delete next.selectedPairApproaches;
|
|
38
|
+
delete next.imageApproachCounts;
|
|
39
|
+
delete next.approachMatrixEnabled;
|
|
40
|
+
delete next.approachMatrix;
|
|
41
|
+
delete next.selectedImageApproaches;
|
|
42
|
+
delete next.pairsCount;
|
|
43
|
+
return next;
|
|
44
|
+
}
|
|
45
|
+
/** Номера 1–10 = строка в таблице подходов (PAIR_APPROACH_POOL[i] → номер i + 1). Порядок в массиве не важен — при применении сортируется по номеру строки. */
|
|
46
|
+
exports.PRODUCT_TYPE_TEXT_PAIR_PRESETS = {
|
|
47
|
+
Похудение: [3, 1, 7, 8, 5],
|
|
48
|
+
Суставы: [3, 2, 8, 1, 10, 7],
|
|
49
|
+
Потенция: [6, 2, 1, 10, 8, 3],
|
|
50
|
+
Простатит: [3, 5, 8, 6, 7, 10],
|
|
51
|
+
Детокс: [10, 6, 3],
|
|
52
|
+
};
|
|
53
|
+
/** Номера 1–N = строка в таблице (CREO_APPROACHES[i] → i + 1). Стабильны: новые подходы только в конец массива. */
|
|
54
|
+
exports.PRODUCT_TYPE_IMAGE_PRESETS = {
|
|
55
|
+
Похудение: [2, 8, 3, 5],
|
|
56
|
+
Суставы: [4, 6, 8, 10, 3, 5],
|
|
57
|
+
Потенция: [5, 10, 1, 8, 4, 2],
|
|
58
|
+
Простатит: [7, 6, 9, 1, 5, 8],
|
|
59
|
+
Детокс: [9, 9, 1, 1],
|
|
60
|
+
};
|
|
61
|
+
/** Индексы PAIR_APPROACH_POOL (0-based), по возрастанию. */
|
|
62
|
+
function productPresetNumbersToIndices(oneBased) {
|
|
63
|
+
const poolLen = 10;
|
|
64
|
+
const seen = new Set();
|
|
65
|
+
for (const n of oneBased) {
|
|
66
|
+
const i = n - 1;
|
|
67
|
+
if (i >= 0 && i < poolLen)
|
|
68
|
+
seen.add(i);
|
|
69
|
+
}
|
|
70
|
+
return [...seen].sort((a, b) => a - b);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Пресет типа товара → массив длиной CREO_APPROACHES.length.
|
|
74
|
+
* Повтор номера увеличивает количество крео для подхода: [9, 9, 1, 1] => C9 x2 и C1 x2.
|
|
75
|
+
*/
|
|
76
|
+
function productPresetNumbersToImageCounts(oneBased) {
|
|
77
|
+
const counts = Array(imageApproachPoolSize()).fill(0);
|
|
78
|
+
for (const n of oneBased) {
|
|
79
|
+
const i = n - 1;
|
|
80
|
+
if (i >= 0 && i < imageApproachPoolSize()) {
|
|
81
|
+
counts[i] = Math.min(exports.MAX_IMAGES_PER_CREO_APPROACH, counts[i] + 1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return counts;
|
|
85
|
+
}
|
|
86
|
+
// Debug logging — пишет в терминал Electron (или в console как fallback)
|
|
87
|
+
function _debugLog(...args) {
|
|
88
|
+
if (typeof localStorage === 'undefined' ||
|
|
89
|
+
localStorage.getItem('promptOverridesDebug') !== 'true') {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const api = typeof window !== 'undefined' ? window.electronAPI : null;
|
|
93
|
+
if (api === null || api === void 0 ? void 0 : api.log) {
|
|
94
|
+
api.log('log', '[PromptOverrides]', ...args).catch(() => console.log('[PromptOverrides]', ...args));
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
console.log('[PromptOverrides]', ...args);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Получить выбранные индексы подходов (из PAIR_APPROACH_POOL).
|
|
102
|
+
* По умолчанию — первые 3 (индексы [0, 1, 2]).
|
|
103
|
+
*/
|
|
104
|
+
function getSelectedPairApproaches() {
|
|
105
|
+
const overrides = loadPromptOverrides();
|
|
106
|
+
if (overrides.selectedPairApproaches && overrides.selectedPairApproaches.length >= 2) {
|
|
107
|
+
return overrides.selectedPairApproaches;
|
|
108
|
+
}
|
|
109
|
+
// backward compat: если был старый pairsCount
|
|
110
|
+
if (overrides.pairsCount && overrides.pairsCount >= 2) {
|
|
111
|
+
return Array.from({ length: Math.min(10, overrides.pairsCount) }, (_, i) => i);
|
|
112
|
+
}
|
|
113
|
+
return [0, 1, 2]; // default: first 3 approaches
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Получить количество пар (длина выбранных подходов)
|
|
117
|
+
*/
|
|
118
|
+
function getPairsCount() {
|
|
119
|
+
return getSelectedPairApproaches().length;
|
|
120
|
+
}
|
|
121
|
+
/** Количество подходов для изображений (= CREO_APPROACHES.length). */
|
|
122
|
+
function imageApproachPoolSize() {
|
|
123
|
+
return prompts_1.CREO_APPROACHES.length;
|
|
124
|
+
}
|
|
125
|
+
/** Дополнить/обрезать массив counts до актуального числа подходов (новые слоты = 1). */
|
|
126
|
+
function normalizeImageApproachCountsLength(counts) {
|
|
127
|
+
const size = imageApproachPoolSize();
|
|
128
|
+
const next = counts.map(c => Math.max(0, Math.min(exports.MAX_IMAGES_PER_CREO_APPROACH, c)));
|
|
129
|
+
while (next.length < size)
|
|
130
|
+
next.push(1);
|
|
131
|
+
return next.slice(0, size);
|
|
132
|
+
}
|
|
133
|
+
/** Максимум картинок на один визуальный подход (слоты в UI и clamp при загрузке). */
|
|
134
|
+
exports.MAX_IMAGES_PER_CREO_APPROACH = 10;
|
|
135
|
+
const PAIR_APPROACH_POOL_LEN = 10;
|
|
136
|
+
/** Нормализация JSON-матрицы связок (номера 1–10, порядок строк сохраняется). */
|
|
137
|
+
function normalizeApproachMatrixFromDrive(raw) {
|
|
138
|
+
if (!Array.isArray(raw))
|
|
139
|
+
return null;
|
|
140
|
+
const out = [];
|
|
141
|
+
for (const row of raw) {
|
|
142
|
+
if (!Array.isArray(row) || row.length < 2)
|
|
143
|
+
return null;
|
|
144
|
+
const imageNumber = typeof row[0] === 'number' && Number.isInteger(row[0])
|
|
145
|
+
? row[0]
|
|
146
|
+
: parseInt(String(row[0]), 10);
|
|
147
|
+
if (!Number.isInteger(imageNumber) || imageNumber < 1 || imageNumber > imageApproachPoolSize()) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
const rawTexts = row[1];
|
|
151
|
+
if (!Array.isArray(rawTexts))
|
|
152
|
+
return null;
|
|
153
|
+
const seenTexts = new Set();
|
|
154
|
+
const textNumbers = [];
|
|
155
|
+
for (const item of rawTexts) {
|
|
156
|
+
const textNumber = typeof item === 'number' && Number.isInteger(item)
|
|
157
|
+
? item
|
|
158
|
+
: parseInt(String(item), 10);
|
|
159
|
+
if (!Number.isInteger(textNumber) || textNumber < 1 || textNumber > PAIR_APPROACH_POOL_LEN) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
if (!seenTexts.has(textNumber)) {
|
|
163
|
+
seenTexts.add(textNumber);
|
|
164
|
+
textNumbers.push(textNumber);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (textNumbers.length === 0)
|
|
168
|
+
return null;
|
|
169
|
+
out.push([imageNumber, textNumbers]);
|
|
170
|
+
}
|
|
171
|
+
return out.length > 0 ? out : null;
|
|
172
|
+
}
|
|
173
|
+
function textApproachIndicesFromMatrix(matrix) {
|
|
174
|
+
const seen = new Set();
|
|
175
|
+
const out = [];
|
|
176
|
+
for (const [, textNumbers] of matrix) {
|
|
177
|
+
for (const n of textNumbers) {
|
|
178
|
+
const idx = n - 1;
|
|
179
|
+
if (idx >= 0 && idx < PAIR_APPROACH_POOL_LEN && !seen.has(idx)) {
|
|
180
|
+
seen.add(idx);
|
|
181
|
+
out.push(idx);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return out;
|
|
186
|
+
}
|
|
187
|
+
function imageApproachCountsFromMatrix(matrix) {
|
|
188
|
+
const counts = Array(imageApproachPoolSize()).fill(0);
|
|
189
|
+
for (const [imageNumber] of matrix) {
|
|
190
|
+
const idx = imageNumber - 1;
|
|
191
|
+
if (idx >= 0 && idx < imageApproachPoolSize()) {
|
|
192
|
+
counts[idx] = Math.min(exports.MAX_IMAGES_PER_CREO_APPROACH, counts[idx] + 1);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return counts;
|
|
196
|
+
}
|
|
197
|
+
/** Нормализация индексов пар из JSON с диска (0-based, уникальные, отсортированные, минимум 2). */
|
|
198
|
+
function normalizeSelectedPairApproachesFromDrive(raw) {
|
|
199
|
+
if (!Array.isArray(raw))
|
|
200
|
+
return null;
|
|
201
|
+
const seen = new Set();
|
|
202
|
+
for (const x of raw) {
|
|
203
|
+
const n = typeof x === 'number' && Number.isInteger(x) ? x : parseInt(String(x), 10);
|
|
204
|
+
if (Number.isInteger(n) && n >= 0 && n < PAIR_APPROACH_POOL_LEN)
|
|
205
|
+
seen.add(n);
|
|
206
|
+
}
|
|
207
|
+
const out = [...seen].sort((a, b) => a - b);
|
|
208
|
+
return out.length >= 2 ? out : null;
|
|
209
|
+
}
|
|
210
|
+
/** Нормализация количеств крео из JSON с диска (длина 10, 0–MAX; хотя бы один подход > 0). */
|
|
211
|
+
function normalizeImageApproachCountsFromDrive(raw) {
|
|
212
|
+
if (!Array.isArray(raw))
|
|
213
|
+
return null;
|
|
214
|
+
const out = [];
|
|
215
|
+
for (let i = 0; i < imageApproachPoolSize(); i++) {
|
|
216
|
+
const v = raw[i];
|
|
217
|
+
const n = typeof v === 'number' && Number.isFinite(v) ? v : parseInt(String(v), 10);
|
|
218
|
+
out.push(Number.isFinite(n) ? Math.max(0, Math.min(exports.MAX_IMAGES_PER_CREO_APPROACH, Math.round(n))) : 0);
|
|
219
|
+
}
|
|
220
|
+
if (out.every(c => c === 0))
|
|
221
|
+
return null;
|
|
222
|
+
return out;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* «Везде без обязательных буллетов» (генерация + валидатор). Через `promptOverrides` (localStorage).
|
|
226
|
+
*/
|
|
227
|
+
function getImageBulletsGlobalOff() {
|
|
228
|
+
return Boolean(loadPromptOverrides().imageBulletsGlobalOff);
|
|
229
|
+
}
|
|
230
|
+
/** Режим буллетов для крео-подхода; без записи = default. */
|
|
231
|
+
function getImageApproachNoBulletsMode(approachName) {
|
|
232
|
+
var _a;
|
|
233
|
+
const raw = (_a = loadPromptOverrides().imageApproachNoBulletsMode) === null || _a === void 0 ? void 0 : _a[approachName];
|
|
234
|
+
if (raw === 'off' || raw === 'on' || raw === 'default')
|
|
235
|
+
return raw;
|
|
236
|
+
return 'default';
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Получить количество изображений по каждому подходу (N элементов, 0–MAX_IMAGES_PER_CREO_APPROACH).
|
|
240
|
+
* По умолчанию — по 1 на каждый подход.
|
|
241
|
+
*/
|
|
242
|
+
function getImageApproachCounts() {
|
|
243
|
+
const overrides = loadPromptOverrides();
|
|
244
|
+
const defaultCounts = Array(imageApproachPoolSize()).fill(1);
|
|
245
|
+
if (overrides.imageApproachCounts && overrides.imageApproachCounts.length > 0) {
|
|
246
|
+
return normalizeImageApproachCountsLength(overrides.imageApproachCounts);
|
|
247
|
+
}
|
|
248
|
+
// backward compat: selectedImageApproaches -> counts (1 for selected, 0 for not)
|
|
249
|
+
if (overrides.selectedImageApproaches && overrides.selectedImageApproaches.length >= 1) {
|
|
250
|
+
const counts = Array(imageApproachPoolSize()).fill(0);
|
|
251
|
+
for (const i of overrides.selectedImageApproaches) {
|
|
252
|
+
if (i >= 0 && i < imageApproachPoolSize())
|
|
253
|
+
counts[i] = 1;
|
|
254
|
+
}
|
|
255
|
+
return counts;
|
|
256
|
+
}
|
|
257
|
+
return defaultCounts;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Загрузить оверрайды из localStorage
|
|
261
|
+
*/
|
|
262
|
+
function loadPromptOverrides() {
|
|
263
|
+
if (typeof localStorage === 'undefined')
|
|
264
|
+
return {};
|
|
265
|
+
try {
|
|
266
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
267
|
+
if (stored) {
|
|
268
|
+
return JSON.parse(stored);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
console.error('Failed to load prompt overrides:', err);
|
|
273
|
+
}
|
|
274
|
+
return {};
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Сохранить оверрайды в localStorage
|
|
278
|
+
*/
|
|
279
|
+
function savePromptOverrides(overrides) {
|
|
280
|
+
try {
|
|
281
|
+
const globalOverrides = stripWorkspaceSelections(overrides);
|
|
282
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(globalOverrides));
|
|
283
|
+
// Также сохраняем через Electron API если доступно
|
|
284
|
+
const electronAPI = window.electronAPI;
|
|
285
|
+
if (electronAPI && electronAPI.saveConfig) {
|
|
286
|
+
electronAPI.loadConfig().then((config) => {
|
|
287
|
+
electronAPI.saveConfig(Object.assign(Object.assign({}, config), { promptOverrides: globalOverrides })).catch((err) => {
|
|
288
|
+
console.error('Failed to save prompt overrides via Electron:', err);
|
|
289
|
+
});
|
|
290
|
+
}).catch(() => {
|
|
291
|
+
// Ignore
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
catch (err) {
|
|
296
|
+
console.error('Failed to save prompt overrides:', err);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/** Имя события после сохранения подходов в менеджере промптов — чтобы синхронизировать JSON на Drive. */
|
|
300
|
+
exports.PROMPT_OVERRIDES_SAVED_EVENT = 'docs-combiner-prompt-overrides-saved';
|
|
301
|
+
/** Прочитать валидные подходы из объекта настроек с диска (без записи в localStorage). */
|
|
302
|
+
function parseApproachesFromDriveData(loadedData) {
|
|
303
|
+
const matrix = normalizeApproachMatrixFromDrive(loadedData.approachMatrix);
|
|
304
|
+
let matrixEnabled;
|
|
305
|
+
if (typeof loadedData.approachMatrixEnabled === 'boolean')
|
|
306
|
+
matrixEnabled = loadedData.approachMatrixEnabled;
|
|
307
|
+
else
|
|
308
|
+
matrixEnabled = matrix ? true : null;
|
|
309
|
+
return {
|
|
310
|
+
pairs: normalizeSelectedPairApproachesFromDrive(loadedData.selectedPairApproaches),
|
|
311
|
+
counts: normalizeImageApproachCountsFromDrive(loadedData.imageApproachCounts),
|
|
312
|
+
matrixEnabled,
|
|
313
|
+
matrix,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Legacy helper: selected approaches are no longer part of global prompt overrides.
|
|
318
|
+
* New code should keep them in per-window state and project-settings.json.
|
|
319
|
+
*/
|
|
320
|
+
function applyParsedApproachesFromDrive(pairs, counts) {
|
|
321
|
+
if (!pairs && !counts)
|
|
322
|
+
return false;
|
|
323
|
+
const overrides = loadPromptOverrides();
|
|
324
|
+
let dirty = false;
|
|
325
|
+
if (pairs) {
|
|
326
|
+
overrides.selectedPairApproaches = pairs;
|
|
327
|
+
dirty = true;
|
|
328
|
+
}
|
|
329
|
+
if (counts) {
|
|
330
|
+
overrides.imageApproachCounts = counts;
|
|
331
|
+
dirty = true;
|
|
332
|
+
}
|
|
333
|
+
if (dirty) {
|
|
334
|
+
savePromptOverrides(overrides);
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Подмешать в localStorage выбранные подходы из project-settings.json на Drive (если поля валидны).
|
|
341
|
+
*/
|
|
342
|
+
function mergePromptApproachesFromDriveFile(loadedData) {
|
|
343
|
+
const { pairs, counts } = parseApproachesFromDriveData(loadedData);
|
|
344
|
+
return applyParsedApproachesFromDrive(pairs, counts);
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Получить оверрайд для простого промпта
|
|
348
|
+
*/
|
|
349
|
+
function getPromptOverride(promptName) {
|
|
350
|
+
const overrides = loadPromptOverrides();
|
|
351
|
+
const result = overrides[promptName];
|
|
352
|
+
_debugLog(`getPromptOverride('${promptName}'):`, `found=${!!result}`, `enabled=${result === null || result === void 0 ? void 0 : result.enabled}`, `hasCustomPrompt=${!!(result === null || result === void 0 ? void 0 : result.customPrompt)}`);
|
|
353
|
+
return result;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Установить оверрайд для простого промпта
|
|
357
|
+
*/
|
|
358
|
+
function setPromptOverride(promptName, override) {
|
|
359
|
+
const overrides = loadPromptOverrides();
|
|
360
|
+
overrides[promptName] = Object.assign(Object.assign({}, override), { lastModified: new Date().toISOString() });
|
|
361
|
+
savePromptOverrides(overrides);
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Получить оверрайд для подхода креативов
|
|
365
|
+
*/
|
|
366
|
+
function getCreoApproachOverride(approachName) {
|
|
367
|
+
var _a;
|
|
368
|
+
const overrides = loadPromptOverrides();
|
|
369
|
+
return (_a = overrides.creoApproaches) === null || _a === void 0 ? void 0 : _a[approachName];
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Установить оверрайд для подхода креативов
|
|
373
|
+
*/
|
|
374
|
+
function setCreoApproachOverride(approachName, override) {
|
|
375
|
+
const overrides = loadPromptOverrides();
|
|
376
|
+
if (!overrides.creoApproaches) {
|
|
377
|
+
overrides.creoApproaches = {};
|
|
378
|
+
}
|
|
379
|
+
overrides.creoApproaches[approachName] = Object.assign(Object.assign({}, override), { lastModified: new Date().toISOString() });
|
|
380
|
+
savePromptOverrides(overrides);
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Сбросить оверрайд для простого промпта
|
|
384
|
+
*/
|
|
385
|
+
function resetPromptOverride(promptName) {
|
|
386
|
+
const overrides = loadPromptOverrides();
|
|
387
|
+
delete overrides[promptName];
|
|
388
|
+
savePromptOverrides(overrides);
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Сбросить оверрайд для подхода креативов
|
|
392
|
+
*/
|
|
393
|
+
function resetCreoApproachOverride(approachName) {
|
|
394
|
+
const overrides = loadPromptOverrides();
|
|
395
|
+
if (overrides.creoApproaches) {
|
|
396
|
+
delete overrides.creoApproaches[approachName];
|
|
397
|
+
savePromptOverrides(overrides);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Сбросить все оверрайды
|
|
402
|
+
*/
|
|
403
|
+
function resetAllOverrides() {
|
|
404
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
405
|
+
// Также очищаем в Electron config
|
|
406
|
+
const electronAPI = window.electronAPI;
|
|
407
|
+
if (electronAPI && electronAPI.saveConfig) {
|
|
408
|
+
electronAPI.loadConfig().then((config) => {
|
|
409
|
+
delete config.promptOverrides;
|
|
410
|
+
electronAPI.saveConfig(config).catch(() => {
|
|
411
|
+
// Ignore
|
|
412
|
+
});
|
|
413
|
+
}).catch(() => {
|
|
414
|
+
// Ignore
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Загрузить оверрайды из Electron config при старте
|
|
420
|
+
*/
|
|
421
|
+
function loadOverridesFromElectron() {
|
|
422
|
+
const electronAPI = window.electronAPI;
|
|
423
|
+
if (electronAPI && electronAPI.loadConfig) {
|
|
424
|
+
electronAPI.loadConfig().then((config) => {
|
|
425
|
+
if (config.promptOverrides) {
|
|
426
|
+
try {
|
|
427
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(config.promptOverrides));
|
|
428
|
+
}
|
|
429
|
+
catch (err) {
|
|
430
|
+
console.error('Failed to load prompt overrides from Electron:', err);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}).catch(() => {
|
|
434
|
+
// Ignore
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
}
|