workflow-ai 1.0.39 → 1.0.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.
Files changed (35) hide show
  1. package/agent-templates/CLAUDE.md.tpl +10 -1
  2. package/agent-templates/QWEN.md.tpl +18 -1
  3. package/package.json +3 -1
  4. package/src/cli.mjs +79 -1
  5. package/src/global-dir.mjs +90 -0
  6. package/src/init.mjs +15 -30
  7. package/src/junction-manager.mjs +184 -0
  8. package/src/runner.mjs +26 -7
  9. package/src/scripts/check-conditions.js +7 -0
  10. package/src/scripts/move-to-ready.js +6 -0
  11. package/src/scripts/move-to-review.js +5 -1
  12. package/src/scripts/pick-next-task.js +67 -0
  13. package/src/skills/coach/SKILL.md +12 -2
  14. package/src/skills/coach/workflows/analyze.md +12 -0
  15. package/src/skills/create-plan/SKILL.md +9 -0
  16. package/src/skills/decompose-gaps/SKILL.md +6 -0
  17. package/src/skills/decompose-plan/SKILL.md +52 -1
  18. package/src/skills/deep-research/README.md +50 -0
  19. package/src/skills/deep-research/SKILL.md +148 -0
  20. package/src/skills/deep-research/algorithms/source-scoring.md +63 -0
  21. package/src/skills/deep-research/algorithms/synthesis.md +67 -0
  22. package/src/skills/deep-research/knowledge/data-validation.md +44 -0
  23. package/src/skills/deep-research/knowledge/research-methodology.md +54 -0
  24. package/src/skills/deep-research/knowledge/source-evaluation.md +33 -0
  25. package/src/skills/deep-research/scripts/perplexity-research.js +315 -0
  26. package/src/skills/deep-research/templates/brief-summary.md +25 -0
  27. package/src/skills/deep-research/templates/research-report.md +76 -0
  28. package/src/skills/deep-research/workflows/benchmark.md +56 -0
  29. package/src/skills/deep-research/workflows/competitor.md +63 -0
  30. package/src/skills/deep-research/workflows/custom.md +45 -0
  31. package/src/skills/deep-research/workflows/market.md +64 -0
  32. package/src/skills/deep-research/workflows/technology.md +52 -0
  33. package/src/skills/deep-research/workflows/trend.md +51 -0
  34. package/src/skills/execute-task/SKILL.md +48 -2
  35. package/src/skills/review-result/SKILL.md +329 -285
@@ -0,0 +1,54 @@
1
+ # Методология проведения исследований
2
+
3
+ Базовая методология для всех типов исследовательских задач.
4
+
5
+ ## Этапы исследования
6
+
7
+ | Этап | Описание | Выход |
8
+ |------|----------|-------|
9
+ | **1. Скоупинг** | Определить границы: что ищем, зачем, для кого | Чёткий исследовательский вопрос |
10
+ | **2. Сбор данных** | Поиск по множеству источников | Сырые данные с ссылками |
11
+ | **3. Фильтрация** | Отсеять нерелевантные, устаревшие, ненадёжные | Валидированный пул данных |
12
+ | **4. Анализ** | Выявить паттерны, противоречия, пробелы | Аналитические находки |
13
+ | **5. Синтез** | Сформулировать выводы и рекомендации | Структурированный отчёт |
14
+ | **6. Валидация** | Проверить ключевые выводы через доп. источники | Верифицированный отчёт |
15
+
16
+ ## Типы источников и их приоритет
17
+
18
+ | Приоритет | Тип источника | Примеры |
19
+ |-----------|---------------|---------|
20
+ | 1 (высший) | Первичные данные | Официальная статистика, API, базы данных |
21
+ | 2 | Отраслевые отчёты | Statista, SimilarWeb, Sensor Tower, App Annie |
22
+ | 3 | Авторитетные издания | TechCrunch, The Verge, Ars Technica, отраслевые блоги |
23
+ | 4 | Экспертные мнения | Блоги экспертов, конференции, подкасты |
24
+ | 5 (низший) | Пользовательский контент | Reddit, форумы, отзывы, комментарии |
25
+
26
+ ## Стратегии поиска
27
+
28
+ ### Breadth-First (для обзорных исследований)
29
+ 1. Начни с широких запросов
30
+ 2. Выяви ключевые подтемы и терминологию
31
+ 3. Углубись в каждую подтему
32
+ 4. Собери перекрёстные ссылки
33
+
34
+ ### Depth-First (для точечных вопросов)
35
+ 1. Начни с конкретного запроса
36
+ 2. Найди авторитетный источник
37
+ 3. Пройди по его ссылкам и цитатам
38
+ 4. Верифицируй через альтернативные источники
39
+
40
+ ### Adversarial (для верификации)
41
+ 1. Сформулируй тезис
42
+ 2. Целенаправленно ищи опровержения
43
+ 3. Оцени силу аргументов за и против
44
+ 4. Сформулируй взвешенный вывод
45
+
46
+ ## Правила работы с данными
47
+
48
+ - **Числа**: всегда указывай источник, дату, методологию сбора
49
+ - **Проценты**: указывай базу (% от чего)
50
+ - **Прогнозы**: отделяй от фактов, указывай автора прогноза
51
+ - **Цитаты**: только прямые с указанием автора и контекста
52
+ - **Устаревшие данные**: помечай `[DATA: YYYY]` если старше 1 года
53
+
54
+ <!-- РАСШИРЕНИЕ: добавляй новые методологические подходы ниже -->
@@ -0,0 +1,33 @@
1
+ # Оценка надёжности источников
2
+
3
+ Критерии для оценки качества и надёжности найденных источников.
4
+
5
+ ## CRAAP-тест (адаптированный)
6
+
7
+ | Критерий | Вопрос | Вес |
8
+ |----------|--------|-----|
9
+ | **Currency** (актуальность) | Когда опубликовано? Обновлялось ли? | 20% |
10
+ | **Relevance** (релевантность) | Напрямую отвечает на вопрос? | 25% |
11
+ | **Authority** (авторитетность) | Кто автор? Какой опыт/квалификация? | 25% |
12
+ | **Accuracy** (точность) | Есть ли ссылки на первоисточники? Подтверждается другими? | 20% |
13
+ | **Purpose** (цель) | Информирование vs продажа vs мнение? | 10% |
14
+
15
+ ## Красные флаги источников
16
+
17
+ | Флаг | Описание | Действие |
18
+ |------|----------|----------|
19
+ | Нет автора | Анонимный контент | Понизить доверие, искать подтверждение |
20
+ | Нет даты | Неизвестная актуальность | Помечать `[DATE: unknown]` |
21
+ | Affiliate/sponsored | Коммерческая заинтересованность | Помечать `[SPONSORED]`, не использовать как единственный |
22
+ | Circular citation | Источники ссылаются друг на друга | Найти первоисточник |
23
+ | Outlier data | Данные сильно отличаются от консенсуса | Отдельно исследовать причину |
24
+
25
+ ## Уровни доверия
26
+
27
+ | Уровень | Условие | Маркировка |
28
+ |---------|---------|------------|
29
+ | **HIGH** | 2+ независимых авторитетных источника подтверждают | `[HIGH]` |
30
+ | **MEDIUM** | 1 авторитетный источник ИЛИ 2+ неавторитетных совпадают | `[MEDIUM]` |
31
+ | **LOW** | 1 неавторитетный источник ИЛИ данные противоречивы | `[LOW]` |
32
+
33
+ <!-- РАСШИРЕНИЕ: добавляй критерии оценки специфических типов источников ниже -->
@@ -0,0 +1,315 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * perplexity-research.js — обёртка для вызова Perplexity через kilo proxy без tool use.
5
+ *
6
+ * Проблема: kilo CLI всегда отправляет tool definitions → Perplexity через OpenRouter
7
+ * не поддерживает tool use и возвращает ошибку.
8
+ *
9
+ * Решение: вызываем OpenRouter API через kilo proxy напрямую (без tools),
10
+ * получаем текстовый ответ и выводим в stdout.
11
+ *
12
+ * Использование:
13
+ * node perplexity-research.js "тема исследования"
14
+ * node perplexity-research.js --model perplexity/sonar "тема"
15
+ * node perplexity-research.js --system "Ты исследователь..." "тема"
16
+ *
17
+ * Результат (markdown) выводится в stdout.
18
+ * Прогресс и ошибки — в stderr.
19
+ */
20
+
21
+ import fs from 'fs';
22
+ import path from 'path';
23
+ import http from 'http';
24
+ import https from 'https';
25
+ import { findProjectRoot } from '../../../lib/find-root.mjs';
26
+ import { createLogger } from '../../../lib/logger.mjs';
27
+
28
+ const logger = createLogger();
29
+
30
+ const AUTH_FILE = path.join(
31
+ process.env.HOME || process.env.USERPROFILE,
32
+ '.local', 'share', 'kilo', 'auth.json'
33
+ );
34
+
35
+ const API_URL = 'https://api.kilo.ai/api/openrouter/chat/completions';
36
+ const DEFAULT_MODEL = 'perplexity/sonar-deep-research';
37
+
38
+ const DEFAULT_SYSTEM_PROMPT = `Ты — опытный исследователь-аналитик. Проводи глубокие исследования по заданным темам.
39
+
40
+ Принципы:
41
+ - Каждый факт подкреплён ссылкой на источник. Нет источника = нет факта.
42
+ - Ключевые данные подтверждай минимум 2 независимыми источниками. Если не удалось — помечай [SINGLE SOURCE].
43
+ - Помечай уровень уверенности: [HIGH], [MEDIUM], [LOW].
44
+ - Всегда указывай дату данных.
45
+ - Отделяй факты от прогнозов и мнений.
46
+
47
+ Формат ответа:
48
+ 1. Executive Summary (3-5 предложений)
49
+ 2. Ключевые находки (с уровнями уверенности)
50
+ 3. Детальный анализ (данные, таблицы, сравнения)
51
+ 4. Выводы и рекомендации
52
+ 5. Пробелы и ограничения
53
+ 6. Источники (полный список с URL)
54
+
55
+ Язык: русский. Формат: markdown.`;
56
+
57
+ function parseArgs(argv) {
58
+ const args = argv.slice(2);
59
+ const result = {
60
+ model: DEFAULT_MODEL,
61
+ system: DEFAULT_SYSTEM_PROMPT,
62
+ message: null,
63
+ };
64
+
65
+ let i = 0;
66
+ const messageParts = [];
67
+
68
+ while (i < args.length) {
69
+ if (args[i] === '--model' && i + 1 < args.length) {
70
+ result.model = args[++i];
71
+ } else if (args[i] === '--system' && i + 1 < args.length) {
72
+ result.system = args[++i];
73
+ } else if (args[i] === '--help' || args[i] === '-h') {
74
+ console.log(`
75
+ Использование: node perplexity-research.js [опции] "тема исследования"
76
+
77
+ Результат (markdown) выводится в stdout.
78
+
79
+ Опции:
80
+ --model <id> Модель Perplexity (по умолчанию: ${DEFAULT_MODEL})
81
+ --system <text> Системный промпт (по умолчанию: встроенный промпт исследователя)
82
+ -h, --help Показать справку
83
+ `);
84
+ process.exit(0);
85
+ } else {
86
+ messageParts.push(args[i]);
87
+ }
88
+ i++;
89
+ }
90
+
91
+ result.message = messageParts.join(' ');
92
+ return result;
93
+ }
94
+
95
+ function loadKiloToken() {
96
+ if (!fs.existsSync(AUTH_FILE)) {
97
+ throw new Error(`Kilo auth file not found: ${AUTH_FILE}\nRun 'kilo auth login' first.`);
98
+ }
99
+
100
+ const auth = JSON.parse(fs.readFileSync(AUTH_FILE, 'utf-8'));
101
+ const kiloAuth = auth.kilo;
102
+
103
+ if (!kiloAuth || !kiloAuth.access) {
104
+ throw new Error('Kilo OAuth token not found in auth.json. Run "kilo auth login" first.');
105
+ }
106
+
107
+ if (kiloAuth.expires && Date.now() > kiloAuth.expires) {
108
+ throw new Error('Kilo OAuth token expired. Run "kilo auth login" to refresh.');
109
+ }
110
+
111
+ return kiloAuth.access;
112
+ }
113
+
114
+ function loadEnvFile() {
115
+ const PROJECT_DIR = findProjectRoot();
116
+ const envPath = path.join(PROJECT_DIR, '.workflow', 'config', '.env');
117
+ if (!fs.existsSync(envPath)) return;
118
+
119
+ const content = fs.readFileSync(envPath, 'utf-8');
120
+ for (const line of content.split('\n')) {
121
+ const trimmed = line.trim();
122
+ if (!trimmed || trimmed.startsWith('#')) continue;
123
+ const eq = trimmed.indexOf('=');
124
+ if (eq === -1) continue;
125
+ const key = trimmed.slice(0, eq).trim();
126
+ const val = trimmed.slice(eq + 1).trim();
127
+ if (!process.env[key]) {
128
+ process.env[key] = val;
129
+ }
130
+ }
131
+ }
132
+
133
+ function getProxyUrl() {
134
+ return process.env.HTTPS_PROXY || process.env.https_proxy
135
+ || process.env.HTTP_PROXY || process.env.http_proxy
136
+ || process.env.ALL_PROXY || process.env.all_proxy
137
+ || null;
138
+ }
139
+
140
+ function callPerplexityAPI(token, model, systemPrompt, userMessage) {
141
+ return new Promise((resolve, reject) => {
142
+ const payload = JSON.stringify({
143
+ model,
144
+ messages: [
145
+ { role: 'system', content: systemPrompt },
146
+ { role: 'user', content: userMessage },
147
+ ],
148
+ });
149
+
150
+ const targetUrl = new URL(API_URL);
151
+ const proxyUrl = getProxyUrl();
152
+
153
+ const requestHeaders = {
154
+ 'Content-Type': 'application/json',
155
+ 'Authorization': `Bearer ${token}`,
156
+ 'Content-Length': Buffer.byteLength(payload),
157
+ };
158
+
159
+ function handleResponse(res) {
160
+ let data = '';
161
+ res.on('data', (chunk) => { data += chunk; });
162
+ res.on('end', () => {
163
+ if (res.statusCode !== 200) {
164
+ reject(new Error(`API error ${res.statusCode}: ${data}`));
165
+ return;
166
+ }
167
+ try {
168
+ const json = JSON.parse(data);
169
+ resolve(json);
170
+ } catch (e) {
171
+ reject(new Error(`Failed to parse API response: ${e.message}\n${data}`));
172
+ }
173
+ });
174
+ }
175
+
176
+ let req;
177
+
178
+ if (proxyUrl) {
179
+ const proxy = new URL(proxyUrl);
180
+ const proxyAuth = proxy.username && proxy.password
181
+ ? `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`
182
+ : null;
183
+
184
+ const connectOptions = {
185
+ hostname: proxy.hostname,
186
+ port: parseInt(proxy.port) || 8080,
187
+ method: 'CONNECT',
188
+ path: `${targetUrl.hostname}:443`,
189
+ headers: {
190
+ 'Host': `${targetUrl.hostname}:443`,
191
+ },
192
+ };
193
+
194
+ if (proxyAuth) {
195
+ connectOptions.headers['Proxy-Authorization'] =
196
+ 'Basic ' + Buffer.from(proxyAuth).toString('base64');
197
+ }
198
+
199
+ logger.info(`Using proxy: ${proxy.hostname}:${proxy.port}`);
200
+
201
+ const proxyReq = http.request(connectOptions);
202
+
203
+ proxyReq.on('connect', (res, socket) => {
204
+ if (res.statusCode !== 200) {
205
+ reject(new Error(`Proxy CONNECT failed: ${res.statusCode}`));
206
+ socket.destroy();
207
+ return;
208
+ }
209
+
210
+ const tlsOptions = {
211
+ hostname: targetUrl.hostname,
212
+ path: targetUrl.pathname,
213
+ method: 'POST',
214
+ headers: requestHeaders,
215
+ socket,
216
+ agent: false,
217
+ };
218
+
219
+ req = https.request(tlsOptions, handleResponse);
220
+ req.on('error', (e) => reject(new Error(`Request failed: ${e.message}`)));
221
+ req.setTimeout(600000, () => {
222
+ req.destroy();
223
+ reject(new Error('Request timeout (10 minutes)'));
224
+ });
225
+ req.write(payload);
226
+ req.end();
227
+ });
228
+
229
+ proxyReq.on('error', (e) => reject(new Error(`Proxy connection failed: ${e.message}`)));
230
+ proxyReq.setTimeout(30000, () => {
231
+ proxyReq.destroy();
232
+ reject(new Error('Proxy connection timeout'));
233
+ });
234
+ proxyReq.end();
235
+
236
+ } else {
237
+ const options = {
238
+ hostname: targetUrl.hostname,
239
+ port: 443,
240
+ path: targetUrl.pathname,
241
+ method: 'POST',
242
+ headers: requestHeaders,
243
+ };
244
+
245
+ req = https.request(options, handleResponse);
246
+ req.on('error', (e) => reject(new Error(`Request failed: ${e.message}`)));
247
+ req.setTimeout(600000, () => {
248
+ req.destroy();
249
+ reject(new Error('Request timeout (10 minutes)'));
250
+ });
251
+ req.write(payload);
252
+ req.end();
253
+ }
254
+ });
255
+ }
256
+
257
+ function formatOutput(apiResponse, model, userMessage) {
258
+ const choice = apiResponse.choices?.[0];
259
+ if (!choice) throw new Error('No response from API');
260
+
261
+ const content = choice.message?.content || '';
262
+ const annotations = choice.message?.annotations || [];
263
+
264
+ let output = content;
265
+
266
+ if (annotations.length > 0) {
267
+ const urlCitations = annotations.filter(a => a.type === 'url_citation' && a.url_citation?.url);
268
+ const uniqueUrls = [...new Set(urlCitations.map(a => a.url_citation.url))];
269
+
270
+ if (uniqueUrls.length > 0) {
271
+ output += '\n\n---\n\n## Источники (автоматические цитаты)\n\n';
272
+ uniqueUrls.forEach((url, i) => {
273
+ const citation = urlCitations.find(a => a.url_citation.url === url);
274
+ const title = citation.url_citation.title || url;
275
+ output += `${i + 1}. [${title}](${url})\n`;
276
+ });
277
+ }
278
+ }
279
+
280
+ return output;
281
+ }
282
+
283
+ async function main() {
284
+ loadEnvFile();
285
+ const args = parseArgs(process.argv);
286
+
287
+ if (!args.message) {
288
+ console.error('Ошибка: не указана тема исследования');
289
+ console.error('Использование: node perplexity-research.js "тема исследования"');
290
+ process.exit(1);
291
+ }
292
+
293
+ logger.info(`Research query: ${args.message}`);
294
+ logger.info(`Model: ${args.model}`);
295
+
296
+ const token = loadKiloToken();
297
+
298
+ console.error(`Запуск исследования через ${args.model}...`);
299
+ console.error(`Ожидание ответа (deep research может занять до 5-10 минут)...`);
300
+
301
+ const response = await callPerplexityAPI(token, args.model, args.system, args.message);
302
+ const output = formatOutput(response, args.model, args.message);
303
+ const usage = response.usage || {};
304
+
305
+ // Результат — в stdout
306
+ console.log(output);
307
+
308
+ // Метаданные — в stderr
309
+ console.error(`Готово. Токены: ${usage.total_tokens || 'N/A'}, стоимость: $${usage.cost || 'N/A'}`);
310
+ }
311
+
312
+ main().catch((err) => {
313
+ console.error(`Ошибка: ${err.message}`);
314
+ process.exit(1);
315
+ });
@@ -0,0 +1,25 @@
1
+ # Шаблон: Краткая справка
2
+
3
+ Используется для быстрых исследовательских ответов, когда полный отчёт избыточен.
4
+
5
+ ## Структура
6
+
7
+ ```markdown
8
+ # Справка: {Тема}
9
+
10
+ **Дата:** {YYYY-MM-DD} | **Заказчик:** {тикет-ID}
11
+
12
+ ## Ответ
13
+
14
+ {2-3 абзаца с ключевыми данными и выводами}
15
+
16
+ ## Ключевые данные
17
+
18
+ | Метрика | Значение | Источник | Уверенность |
19
+ |---------|----------|----------|-------------|
20
+ | {метрика} | {значение} | {источник} | [HIGH/MEDIUM/LOW] |
21
+
22
+ ## Источники
23
+
24
+ 1. {Название} — {URL} ({дата})
25
+ ```
@@ -0,0 +1,76 @@
1
+ # Шаблон: Исследовательский отчёт
2
+
3
+ ## Структура отчёта
4
+
5
+ ```markdown
6
+ # {Тема исследования}
7
+
8
+ **Дата исследования:** {YYYY-MM-DD}
9
+ **Заказчик:** {тикет-ID, скил}
10
+ **Исследовательский вопрос:** {формулировка}
11
+ **Скоуп:** {что входит и не входит}
12
+
13
+ ---
14
+
15
+ ## Executive Summary
16
+
17
+ {3-5 предложений: главные находки, ключевой вывод, уровень уверенности}
18
+
19
+ ---
20
+
21
+ ## Ключевые находки
22
+
23
+ ### 1. {Находка}
24
+ **Уверенность:** [HIGH/MEDIUM/LOW]
25
+
26
+ {Описание находки}
27
+
28
+ | Источник | Данные | Дата |
29
+ |----------|--------|------|
30
+ | {название} | {факт/число} | {дата} |
31
+
32
+ ### 2. {Находка}
33
+ ...
34
+
35
+ ---
36
+
37
+ ## Детальный анализ
38
+
39
+ ### {Подтема 1}
40
+
41
+ {Развёрнутый анализ с данными, таблицами, сравнениями}
42
+
43
+ ### {Подтема 2}
44
+ ...
45
+
46
+ ---
47
+
48
+ ## Выводы и рекомендации
49
+
50
+ | # | Вывод | Уверенность | Рекомендация |
51
+ |---|-------|-------------|--------------|
52
+ | 1 | {тезис} | [HIGH] | {что делать} |
53
+ | 2 | {тезис} | [MEDIUM] | {что делать} |
54
+
55
+ ---
56
+
57
+ ## Пробелы и ограничения
58
+
59
+ - {Что не удалось найти и почему}
60
+ - {Какие данные требуют дополнительной верификации}
61
+ - {Известные ограничения методологии}
62
+
63
+ ---
64
+
65
+ ## За пределами скоупа
66
+
67
+ {Интересные находки, не входящие в скоуп, но потенциально полезные}
68
+
69
+ ---
70
+
71
+ ## Источники
72
+
73
+ | # | Название | URL | Тип | Дата | Оценка |
74
+ |---|----------|-----|-----|------|--------|
75
+ | 1 | {название} | {url} | {тип} | {дата} | {A/B/C} |
76
+ ```
@@ -0,0 +1,56 @@
1
+ # Воркфлоу: BENCHMARK — Сбор бенчмарков
2
+
3
+ Сбор отраслевых бенчмарков и лучших практик для сравнения с текущими показателями.
4
+
5
+ ## Алгоритм выполнения
6
+
7
+ ### 1. Определи что бенчмаркить
8
+
9
+ - Какие метрики нужны (retention, conversion, ARPU, etc.)
10
+ - В какой нише/сегменте
11
+ - Какой масштаб продукта (стартап vs enterprise)
12
+
13
+ ### 2. Собери бенчмарки
14
+
15
+ Приоритет источников:
16
+ 1. Отраслевые отчёты с методологией (Mixpanel, Amplitude, Lenny's Newsletter)
17
+ 2. Публичные данные компаний (S-1 filings, earnings reports)
18
+ 3. Агрегаторы бенчмарков (ChartMogul, ProfitWell)
19
+ 4. Экспертные статьи с данными
20
+ 5. Кейс-стади
21
+
22
+ ### 3. Нормализуй данные
23
+
24
+ - Привести к единой методологии (DAU vs WAU vs MAU)
25
+ - Учесть разницу в определениях (что считается active user?)
26
+ - Учесть сегмент (mobile vs web vs extension)
27
+ - Учесть stage (pre-PMF vs growth vs mature)
28
+
29
+ ### 4. Сформируй таблицу бенчмарков
30
+
31
+ | Метрика | Bottom 25% | Median | Top 25% | Best-in-class | Наш | Источник |
32
+ |---------|-----------|--------|---------|--------------|-----|----------|
33
+ | ... | ... | ... | ... | ... | ... | ... |
34
+
35
+ ### 5. Проанализируй gaps
36
+
37
+ Для каждой метрики где наш показатель ниже медианы:
38
+ - Насколько критичен gap
39
+ - Что делают top-performers иначе
40
+ - Реалистично ли достичь медианы и за какой срок
41
+
42
+ ### 6. Синтезируй выводы
43
+
44
+ → Загрузи `algorithms/synthesis.md`
45
+
46
+ ### 7. Сформируй отчёт
47
+
48
+ → Используй `templates/research-report.md`
49
+
50
+ ### 8. Валидация
51
+
52
+ - [ ] Бенчмарки из 2+ источников для ключевых метрик
53
+ - [ ] Данные нормализованы (единая методология)
54
+ - [ ] Указаны сегмент и stage для каждого бенчмарка
55
+ - [ ] Gap-анализ с приоритизацией
56
+ - [ ] Источники с датами
@@ -0,0 +1,63 @@
1
+ # Воркфлоу: COMPETITOR — Анализ конкурентов
2
+
3
+ Глубокий анализ конкурентов: продукты, позиционирование, метрики, сильные/слабые стороны.
4
+
5
+ ## Алгоритм выполнения
6
+
7
+ ### 1. Определи скоуп
8
+
9
+ - Каких конкурентов анализировать (или найти самостоятельно)
10
+ - По каким параметрам сравнивать
11
+ - Прямые vs косвенные конкуренты
12
+
13
+ ### 2. Составь список конкурентов
14
+
15
+ Если не задан:
16
+ 1. Поиск по ключевым запросам в нише
17
+ 2. Маркетплейсы/сторы (Chrome Web Store, App Store, etc.)
18
+ 3. Обзорные статьи "Top N {category}"
19
+ 4. Альтернативы (AlternativeTo, G2, Capterra)
20
+
21
+ ### 3. Собери данные по каждому конкуренту
22
+
23
+ | Параметр | Что искать |
24
+ |----------|-----------|
25
+ | Продукт | Функции, цены, модель монетизации |
26
+ | Масштаб | Пользователи, загрузки, revenue (если публично) |
27
+ | Позиционирование | Messaging, целевая аудитория, USP |
28
+ | Каналы | Как привлекают пользователей |
29
+ | Отзывы | Рейтинги, частые жалобы, что хвалят |
30
+ | Технологии | Стек, интеграции, открытый код |
31
+
32
+ → Загрузи `algorithms/source-scoring.md` для оценки данных
33
+
34
+ ### 4. Проведи сравнительный анализ
35
+
36
+ Создай comparison matrix:
37
+
38
+ | Параметр | Конкурент A | Конкурент B | Наш продукт |
39
+ |----------|------------|------------|-------------|
40
+ | ... | ... | ... | ... |
41
+
42
+ ### 5. Определи паттерны
43
+
44
+ - Общие стратегии успешных конкурентов
45
+ - Незанятые ниши
46
+ - Типичные ошибки
47
+ - Тренды в продуктах
48
+
49
+ ### 6. Синтезируй выводы
50
+
51
+ → Загрузи `algorithms/synthesis.md`
52
+
53
+ ### 7. Сформируй отчёт
54
+
55
+ → Используй `templates/research-report.md`
56
+
57
+ ### 8. Валидация
58
+
59
+ - [ ] Минимум 5 конкурентов проанализировано (или все если < 5)
60
+ - [ ] Данные по каждому из одного периода
61
+ - [ ] Comparison matrix заполнена
62
+ - [ ] Выводы actionable для заказчика
63
+ - [ ] Источники указаны для каждого факта
@@ -0,0 +1,45 @@
1
+ # Воркфлоу: CUSTOM — Кастомное исследование
2
+
3
+ Исследование по произвольному ТЗ, не попадающее в стандартные типы.
4
+
5
+ ## Алгоритм выполнения
6
+
7
+ ### 1. Определи исследовательский вопрос
8
+
9
+ Из тикета извлеки:
10
+ - Что именно нужно узнать (конкретный вопрос)
11
+ - Для чего (контекст решения)
12
+ - Глубина: справка (brief) vs полное исследование (report)
13
+ - Ограничения по скоупу
14
+
15
+ ### 2. Выбери стратегию поиска
16
+
17
+ → Загрузи `knowledge/research-methodology.md`
18
+
19
+ - Обзорный вопрос → Breadth-First
20
+ - Конкретный вопрос → Depth-First
21
+ - Проверка гипотезы → Adversarial
22
+
23
+ ### 3. Проведи исследование
24
+
25
+ 1. Сформулируй 3-5 поисковых запросов
26
+ 2. Для каждого запроса собери топ-5 релевантных результатов
27
+ 3. Оцени источники → `algorithms/source-scoring.md`
28
+ 4. Валидируй данные → `knowledge/data-validation.md`
29
+
30
+ ### 4. Синтезируй
31
+
32
+ → Загрузи `algorithms/synthesis.md`
33
+
34
+ ### 5. Сформируй результат
35
+
36
+ - Справка → `templates/brief-summary.md`
37
+ - Полное исследование → `templates/research-report.md`
38
+
39
+ ### 6. Валидация
40
+
41
+ - [ ] Исследовательский вопрос отвечен
42
+ - [ ] Ключевые данные подкреплены источниками
43
+ - [ ] Уровни уверенности указаны
44
+ - [ ] Пробелы в данных явно отмечены
45
+ - [ ] Формат соответствует глубине запроса