@gian-tiaga/eda 0.4.6 → 0.5.1

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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > Поточная разработка с AI-агентами — на русском языке.
4
4
  > Набор готовых скилов для **Claude Code** и **Codex CLI**, которые ведут тебя через весь цикл: от исследования до коммита.
5
5
 
6
- `eda` — это десять скилов, каждый отвечает за свой кусок работы. Вместо того чтобы каждый раз объяснять модели, как делать ревью или как исполнять план, ты говоришь одно слово — и она следует чёткой инструкции на русском, со всеми правилами, проверками и артефактами в нужных папках.
6
+ `eda` — это одиннадцать скилов, каждый отвечает за свой кусок работы. Вместо того чтобы каждый раз объяснять модели, как делать ревью или как исполнять план, ты говоришь одно слово — и она следует чёткой инструкции на русском, со всеми правилами, проверками и артефактами в нужных папках.
7
7
 
8
8
  ---
9
9
 
@@ -19,7 +19,7 @@ npm install -g @gian-tiaga/eda
19
19
  eda init
20
20
  ```
21
21
 
22
- Установщик покажет чекбоксы: стрелками выбираешь среду, пробелом отмечаешь, Enter продолжает. Можно поставить Claude Code, Codex CLI или обе среды сразу. Если `docs/settings.yaml` ещё нет, установщик также предложит выбрать настройки скилов и создаст этот файл.
22
+ Установщик покажет чекбоксы: стрелками выбираешь среду, пробелом отмечаешь, Enter продолжает. Можно поставить Claude Code, Codex CLI или обе среды сразу. Если `docs/settings.yaml` ещё нет, установщик также предложит выбрать настройки скилов и создаст этот файл. В конце `eda init` пишет, сколько скилов установлено.
23
23
 
24
24
  ---
25
25
 
@@ -27,6 +27,7 @@ eda init
27
27
 
28
28
  | Скил | Что делает | Куда складывает |
29
29
  |---|---|---|
30
+ | `eda-roadmap` | Создаёт roadmap-файл: список будущих задач с короткими, понятными и недвусмысленными описаниями без деталей реализации, файлов, библиотек, API и пошагового плана | `docs/roadmaps/` |
30
31
  | `eda-explore` | Исследует тему до конкретного результата: описание проблемы, релевантная архитектура, закрытые развилки, риски внутри решений и короткий выбранный вариант решения без плана. Если нужны пакеты или ПО — проверяет актуальные стабильные версии через context7 или web search | `docs/researches/` |
31
32
  | `eda-plan` | Пишет план реализации через стандартный Plan Mode хост-агента. Подтягивает контекст из `docs/rules.md`, `docs/arch.md`, при желании — релевантное исследование. Затем три параллельных модели (слабая, средняя, мощная) проверяют план на реалистичность, пропущенные шаги и нарушения правил — главный планировщик сам решает, что применить | `docs/plans/` |
32
33
  | `eda-execute` | Выполняет план. Спрашивает, где работать (текущая ветка, новая ветка, отдельный worktree). Тесты пишет внутри каждого шага. В конце — полный прогон тестов и линтеров | `docs/executions/` |
@@ -64,22 +65,29 @@ eda init
64
65
  version: 1
65
66
 
66
67
  defaults:
68
+ # Включает strict-режим по умолчанию для eda-explore, eda-plan и eda-review.
67
69
  # true | false
68
70
  strict: false
71
+ # Задаёт размер плана по умолчанию для eda-plan.
69
72
  # normal | short | ask_each_time
70
73
  plan_size: normal
74
+ # Определяет, как eda-explore и eda-plan принимают существенные решения.
71
75
  # autonomous | recommend_and_ask | ask_each_time
72
76
  decision_mode: recommend_and_ask
77
+ # Задаёт стратегию тестов по умолчанию для eda-plan.
73
78
  # after_each_phase | tdd_each_phase | end_of_plan | ask_each_time
74
79
  test_strategy: ask_each_time
80
+ # Задаёт стратегию логирования по умолчанию для eda-plan.
75
81
  # debug_precise | standard | ask_each_time
76
82
  logging_strategy: ask_each_time
77
83
 
78
84
  automate:
85
+ # Добавляет docs/plans/ в обычный запуск eda-automate.
79
86
  # true | false
80
87
  include_plans: false
81
88
 
82
89
  review:
90
+ # Добавляет в eda-review проверку качества кода и meta-reviewer quality-check.
83
91
  # true | false
84
92
  include_code_quality: true
85
93
  ```
@@ -103,15 +111,15 @@ review:
103
111
  docs ───────────────┬───────────────┐
104
112
  │ │
105
113
  v v
106
- explore ─────────> plan ────────> execute ───┬──> review ───> fix-by-review ───┬──> send-review
107
- │ │
108
- v └──> commit
109
- fix ─────────────> review
114
+ roadmap ────────> explore ─────> plan ───> execute ───┬──> review ───> fix-by-review ───┬──> send-review
115
+ │ │
116
+ └──────────────> plan v └──> commit
117
+ fix ─────────────> review
110
118
 
111
119
  automate может запускаться от review, fix-by-review или fix.
112
120
  ```
113
121
 
114
- Использовать всю цепочку не обязательно — каждый скил самодостаточен. Можно начать с `eda-explore`, или сразу с `eda-execute` на готовом плане, или просто `eda-commit`, когда правки уже сделаны.
122
+ Использовать всю цепочку не обязательно — каждый скил самодостаточен. Можно начать с `eda-roadmap`, `eda-explore`, или сразу с `eda-execute` на готовом плане, или просто `eda-commit`, когда правки уже сделаны.
115
123
 
116
124
  ---
117
125
 
@@ -129,7 +137,7 @@ automate может запускаться от review, fix-by-review или fix
129
137
 
130
138
  ```bash
131
139
  eda init # выбрать Claude Code / Codex / обе среды и установить скилы
132
- eda update # обновить скилы и создать docs/settings.yaml, если его ещё нет
140
+ eda update # обновить скилы, показать их количество и создать docs/settings.yaml, если его ещё нет
133
141
  eda --version # показать версию установленного пакета
134
142
  eda --help # справка
135
143
  ```
@@ -152,7 +160,7 @@ eda update # синхронизировать скилы в текущ
152
160
  | **Claude Code** | `<project>/.claude/skills/<skill>/SKILL.md` — отдельная папка на каждый скил |
153
161
  | **Codex CLI** | `<project>/.codex/skills/<skill>/SKILL.md` — отдельная папка на каждый скил |
154
162
 
155
- `eda update` идемпотентно перезаписывает файлы в обеих папках. При обновлении старые файлы Codex-формата `<project>/.codex/skills/<skill>.md`, созданные версиями `eda` до этой структуры, удаляются. Если ты хочешь подправить скил локально — лучше копию сделай рядом, а не прямо в `.claude/skills/` или `.codex/skills/`, иначе при следующем `update` твои правки потеряются.
163
+ `eda update` идемпотентно перезаписывает файлы в обеих папках и в конце пишет, сколько скилов обновлено. При обновлении старые файлы Codex-формата `<project>/.codex/skills/<skill>.md`, созданные версиями `eda` до этой структуры, удаляются. Если ты хочешь подправить скил локально — лучше копию сделай рядом, а не прямо в `.claude/skills/` или `.codex/skills/`, иначе при следующем `update` твои правки потеряются.
156
164
 
157
165
  `AGENTS.md` (как и любые другие файлы в корне проекта) установщик **не трогает**. Если хочешь, чтобы Codex автоматически подгружал скилы, дай ему знать сам — например, одной строкой в `AGENTS.md`: «следуй инструкциям из `.codex/skills/`».
158
166
 
package/lib/install.js CHANGED
@@ -108,7 +108,7 @@ export async function init({ cwd, input = process.stdin, output = process.stdout
108
108
  return;
109
109
  }
110
110
  await ensureSettings(cwd, { input, output });
111
- await syncSkills(cwd, targets, output);
111
+ await syncSkills(cwd, targets, output, { action: 'install' });
112
112
  }
113
113
 
114
114
  export async function update({ cwd, input = process.stdin, output = process.stdout }) {
@@ -119,7 +119,7 @@ export async function update({ cwd, input = process.stdin, output = process.stdo
119
119
  }
120
120
  output.write(`Найдены установленные среды: ${targets.join(', ')}\n`);
121
121
  await ensureSettings(cwd, { input, output });
122
- await syncSkills(cwd, targets, output);
122
+ await syncSkills(cwd, targets, output, { action: 'update' });
123
123
  }
124
124
 
125
125
  export async function askTargets({ input = process.stdin, output = process.stdout } = {}) {
@@ -211,7 +211,7 @@ async function detectTargets(cwd) {
211
211
  return targets;
212
212
  }
213
213
 
214
- async function syncSkills(cwd, targets, output = process.stdout) {
214
+ async function syncSkills(cwd, targets, output = process.stdout, { action = 'update' } = {}) {
215
215
  const skills = await listSkills();
216
216
  if (skills.length === 0) {
217
217
  throw new Error(`В пакете нет скилов (искал в ${SKILLS_SRC}).`);
@@ -222,6 +222,8 @@ async function syncSkills(cwd, targets, output = process.stdout) {
222
222
  if (targets.includes('codex')) await installToCodex(cwd, skills, output);
223
223
  await removeRetiredSkills(cwd, targets);
224
224
 
225
+ const actionLabel = action === 'install' ? 'Установлено' : 'Обновлено';
226
+ output.write(`${actionLabel} ${formatSkillCount(skills.length)}.\n`);
225
227
  output.write('\nГотово.\n');
226
228
  }
227
229
 
@@ -252,22 +254,29 @@ function formatSettings(settings) {
252
254
  return `version: 1
253
255
 
254
256
  defaults:
257
+ # Включает strict-режим по умолчанию для eda-explore, eda-plan и eda-review.
255
258
  # true | false
256
259
  strict: ${settings.strict ? 'true' : 'false'}
260
+ # Задаёт размер плана по умолчанию для eda-plan.
257
261
  # normal | short | ask_each_time
258
262
  plan_size: ${settings.planSize}
263
+ # Определяет, как eda-explore и eda-plan принимают существенные решения.
259
264
  # autonomous | recommend_and_ask | ask_each_time
260
265
  decision_mode: ${settings.decisionMode}
266
+ # Задаёт стратегию тестов по умолчанию для eda-plan.
261
267
  # after_each_phase | tdd_each_phase | end_of_plan | ask_each_time
262
268
  test_strategy: ${settings.testStrategy}
269
+ # Задаёт стратегию логирования по умолчанию для eda-plan.
263
270
  # debug_precise | standard | ask_each_time
264
271
  logging_strategy: ${settings.loggingStrategy}
265
272
 
266
273
  automate:
274
+ # Добавляет docs/plans/ в обычный запуск eda-automate.
267
275
  # true | false
268
276
  include_plans: ${settings.includePlans ? 'true' : 'false'}
269
277
 
270
278
  review:
279
+ # Добавляет в eda-review проверку качества кода и meta-reviewer quality-check.
271
280
  # true | false
272
281
  include_code_quality: ${settings.includeCodeQuality ? 'true' : 'false'}
273
282
  `;
@@ -282,7 +291,7 @@ async function installToClaude(cwd, skills, output = process.stdout) {
282
291
  const content = await fs.readFile(skill.path, 'utf-8');
283
292
  await fs.writeFile(path.join(skillDir, 'SKILL.md'), content);
284
293
  }
285
- output.write(` ✓ Claude Code: ${dst}\n`);
294
+ output.write(` ✓ Claude Code: ${dst} (${formatSkillCount(skills.length)})\n`);
286
295
  }
287
296
 
288
297
  async function installToCodex(cwd, skills, output = process.stdout) {
@@ -295,7 +304,19 @@ async function installToCodex(cwd, skills, output = process.stdout) {
295
304
  await fs.writeFile(path.join(skillDir, 'SKILL.md'), content);
296
305
  await removeObsoleteCodexFile(dst, skill.name);
297
306
  }
298
- output.write(` ✓ Codex CLI: ${dst}\n`);
307
+ output.write(` ✓ Codex CLI: ${dst} (${formatSkillCount(skills.length)})\n`);
308
+ }
309
+
310
+ function formatSkillCount(count) {
311
+ return `${count} ${pluralizeSkill(count)}`;
312
+ }
313
+
314
+ function pluralizeSkill(count) {
315
+ const mod10 = count % 10;
316
+ const mod100 = count % 100;
317
+ if (mod10 === 1 && mod100 !== 11) return 'скил';
318
+ if (mod10 >= 2 && mod10 <= 4 && (mod100 < 12 || mod100 > 14)) return 'скила';
319
+ return 'скилов';
299
320
  }
300
321
 
301
322
  async function removeObsoleteCodexFile(dst, skillName) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gian-tiaga/eda",
3
- "version": "0.4.6",
4
- "description": "Набор скилов eda-* для Claude Code и Codex CLI: explore, plan, execute, fix, review, fix-by-review, send-review, commit, docs, automate",
3
+ "version": "0.5.1",
4
+ "description": "Набор скилов eda-* для Claude Code и Codex CLI: roadmap, explore, plan, execute, fix, review, fix-by-review, send-review, commit, docs, automate",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "eda": "bin/cli.js"
@@ -0,0 +1,142 @@
1
+ ---
2
+ name: eda-roadmap
3
+ description: 'Создаёт roadmap-файл по продуктовой или технической теме: собирает из сообщения пользователя цель, ограничения и список задач, формулирует задачи коротко, понятно и недвусмысленно, без деталей реализации, файлов, библиотек, API и пошагового плана. При необходимости читает docs/rules.md, docs/arch.md и существующие docs/roadmaps/. Задаёт вопросы только если без ответа нельзя составить корректный список задач. Итог сохраняет в docs/roadmaps/. Не исследует глубоко, не планирует реализацию и не меняет код.'
4
+ ---
5
+
6
+ # Скил: Roadmap (eda-roadmap)
7
+
8
+ Создаёшь roadmap: список будущих задач по продуктовой или технической теме. Roadmap отвечает на вопрос «что нужно сделать и зачем», но не отвечает «как именно реализовывать».
9
+
10
+ ## Режимы вызова
11
+
12
+ | Режим | Запуск | Что делает |
13
+ |---|---|---|
14
+ | Обычный | `eda-roadmap <тема>` | Создаёт roadmap-файл в `docs/roadmaps/`. |
15
+ | Из текста | `eda-roadmap <список идей или требований>` | Нормализует вход в ясный список задач без деталей реализации. |
16
+
17
+ ## Вход из сообщения пользователя
18
+
19
+ Текст рядом с вызовом скилла в текущем сообщении пользователя — главный вход. Сначала разбери именно его: тему, цель, аудиторию, ограничения, примерный горизонт roadmap, уже названные задачи и прямые указания.
20
+
21
+ Если входа достаточно, продолжай без вопроса. `AskUserQuestion` задавай только если входа нет, он противоречивый, найдено несколько равных вариантов или есть риск составить roadmap не для той цели. Старое обсуждение в истории не считай входом, если пользователь не связал его с текущим вызовом явно.
22
+
23
+ ## Главные правила
24
+
25
+ 1. **Никаких правок кода.** Запись только в `docs/roadmaps/`.
26
+ 2. **Roadmap — не план реализации.** Не указывай файлы, модули, библиотеки, API, миграции, команды, схемы данных, тесты и порядок технической реализации.
27
+ 3. **Задачи формулируй как пользовательскую или проектную ценность.** Хорошо: «Аутентификация через email, ВК и Яндекс». Плохо: «Добавить OAuth-клиент, роуты callback и таблицу provider_accounts».
28
+ 4. **Каждая задача короткая, но однозначная.** Читатель должен понять границы задачи без дополнительного созвона.
29
+ 5. **Можно чуть подробнее, если это снимает двусмысленность.** Допускается одно короткое описание: что должно появиться, для кого и какой результат ожидается.
30
+ 6. **Не выдумывай обязательства.** Если пользователь дал только направление, формулируй разумный черновик и явно помечай предположения.
31
+ 7. **Прочитай `docs/rules.md` и `docs/arch.md`**, если есть, чтобы не противоречить зафиксированным правилам и архитектурным ограничениям.
32
+ 8. **Существующие roadmap-файлы учитывай только при явной необходимости.** Если пользователь просит продолжить, обновить или не дублировать прошлый roadmap — прочитай релевантные файлы из `docs/roadmaps/`.
33
+
34
+ ## Интерактивные вопросы
35
+
36
+ Когда инструкция говорит `AskUserQuestion`, это означает блокирующий интерактивный вопрос.
37
+ - Claude Code: используй `AskUserQuestion`.
38
+ - Codex interactive: если доступен `request_user_input`, используй его. Если tool недоступен, задай один короткий вопрос в чат, дай варианты 1–3, напиши «Ответь номером или своим вариантом. Я продолжу только после ответа.» и остановись.
39
+ - Codex exec / неинтерактивный запуск: не задавай вопросы и не пытайся читать stdin. Если без ответа нельзя безопасно продолжать, заверши работу со статусом `blocked: нужен ответ пользователя`, перечисли вопросы и варианты, не выполняй рискованные действия.
40
+ - Не запускай команды, которые ждут интерактивного ввода в терминале.
41
+
42
+ ## Этапы
43
+
44
+ ### 1. Понять назначение roadmap
45
+
46
+ Определи:
47
+ - тему roadmap;
48
+ - для кого он нужен: продукт, команда разработки, владелец проекта, пользовательский сценарий;
49
+ - горизонт, если он указан: ближайший релиз, квартал, MVP, несколько этапов;
50
+ - уровень детализации: только список задач или задачи с короткими описаниями.
51
+
52
+ Если тема или назначение неясны — задай `AskUserQuestion` и остановись до ответа.
53
+
54
+ ### 2. Собрать минимальный контекст
55
+
56
+ Прочитай `docs/rules.md` и `docs/arch.md`, если они есть. Не делай глубокое исследование кода, если пользователь прямо не просит привязать roadmap к текущему состоянию проекта.
57
+
58
+ Если пользователь просит продолжить или обновить существующий roadmap:
59
+ - найди релевантный файл по указанному пути или теме;
60
+ - если найдено несколько равных вариантов, спроси, какой использовать;
61
+ - не перезаписывай старый файл, если пользователь явно не попросил обновить именно его.
62
+
63
+ ### 3. Сформировать задачи
64
+
65
+ Собери задачи в список. Для каждой задачи:
66
+ - дай короткое название;
67
+ - добавь 1–2 предложения описания, если без них задача может быть понята по-разному;
68
+ - опиши результат на уровне поведения или возможности, а не реализации;
69
+ - не добавляй подзадачи с техническими шагами;
70
+ - не добавляй оценки сроков, если пользователь не просил.
71
+
72
+ Хорошие формулировки:
73
+ - «Аутентификация через email, ВК и Яндекс. Пользователь может войти удобным способом и восстановить доступ без обращения в поддержку.»
74
+ - «Личный кабинет пользователя. Пользователь видит свои данные, статус подписки и основные действия по аккаунту в одном месте.»
75
+ - «Базовая модерация контента. Команда может скрывать спорные материалы и видеть причину модерационного решения.»
76
+
77
+ Плохие формулировки:
78
+ - «Подключить `passport-yandex`, добавить callback route и таблицу OAuth-профилей.»
79
+ - «Создать `auth.service.ts`, миграцию и e2e-тесты.»
80
+ - «Реализовать через Redis и очередь фоновых задач.»
81
+
82
+ ### 4. Сохранить файл
83
+
84
+ Сохрани roadmap в `docs/roadmaps/{YYYY-MM-DD}_{HH-MM}_{slug}.md`.
85
+
86
+ Формат файла:
87
+
88
+ ```markdown
89
+ ---
90
+ title: <заголовок>
91
+ date: <YYYY-MM-DD HH:MM>
92
+ status: draft
93
+ sources:
94
+ rules: <путь или —>
95
+ arch: <путь или —>
96
+ previous_roadmap: <путь или —>
97
+ ---
98
+
99
+ # <Заголовок>
100
+
101
+ ## Контекст
102
+
103
+ Коротко: зачем нужен roadmap, для кого он и какой горизонт покрывает.
104
+
105
+ ## Предположения
106
+
107
+ - <предположение, если было>
108
+
109
+ Если предположений нет: «Не требовались.»
110
+
111
+ ## Задачи
112
+
113
+ | # | Задача | Описание |
114
+ |---|---|---|
115
+ | 1 | <короткая задача> | <понятное описание без деталей реализации> |
116
+
117
+ ## Не входит
118
+
119
+ - <что явно не включаем, если это важно>
120
+
121
+ Если явных исключений нет: «Не зафиксировано.»
122
+ ```
123
+
124
+ Quality gate перед сохранением:
125
+ - файл лежит в `docs/roadmaps/`;
126
+ - есть ровно один основной список задач в разделе `Задачи`;
127
+ - каждая задача имеет короткое название и понятное описание;
128
+ - задачи не содержат деталей реализации: файлов, библиотек, API, команд, миграций, схем таблиц, тестовых стратегий;
129
+ - roadmap можно использовать как вход для `eda-explore` или `eda-plan`, но сам он не является исследованием или планом реализации.
130
+
131
+ ### 5. Финал
132
+
133
+ Короткое сообщение: путь к roadmap-файлу, количество задач, 3–5 самых важных задач простыми словами. Если были предположения — явно скажи, что они записаны в файл.
134
+
135
+ ## Чего НЕ делать
136
+
137
+ - Править код, конфиги, зависимости или тесты.
138
+ - Писать план реализации по фазам.
139
+ - Делать техническое исследование вместо roadmap.
140
+ - Указывать конкретные библиотеки, файлы, API, миграции, команды или тестовые сценарии.
141
+ - Раздувать задачу до спецификации или ТЗ.
142
+ - Сохранять файл куда-либо кроме `docs/roadmaps/`.