@gian-tiaga/eda 3.10.0 → 3.10.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/MIGRATION.md CHANGED
@@ -77,9 +77,9 @@ docs/
77
77
 
78
78
  Версия npm-пакета и версия схемы настроек независимы: в eda 3.3 актуальным остаётся `docs/settings.yaml` с `version: 3`.
79
79
 
80
- Установщик по-прежнему сохраняет полный валидный v3 байт-в-байт — кроме случая, когда в файле остались устаревшие ключи: тогда он перезаписывает файл без вопросов и печатает, что именно убрал. Старый, неизвестный или неполный YAML нормализуется: известные валидные значения переносятся, а отсутствующие спрашиваются в TTY или получают defaults без TTY.
80
+ Установщик по-прежнему сохраняет полный валидный v3 как есть — кроме двух случаев: если в файле остались устаревшие ключи или если текст файла отстал от шаблона пакета. Тогда он перезаписывает файл без вопросов, сохраняет значения и печатает, что сделал. Старый, неизвестный или неполный YAML нормализуется: известные валидные значения переносятся, а отсутствующие спрашиваются в TTY или получают defaults без TTY.
81
81
 
82
- В `eda update-all` режим `configure` один раз спрашивает общий профиль v3 и записывает его во все проекты. Режим `skip` сохраняет полный v3, индивидуально переносит остальные конфиги и создаёт defaults только при отсутствии файла.
82
+ В `eda update-all` режим `configure` один раз спрашивает общий профиль v3 и записывает его во все проекты. Режим `skip` сохраняет актуальный полный v3, перерисовывает устаревший по шаблону, индивидуально переносит остальные конфиги и создаёт defaults только при отсутствии файла.
83
83
 
84
84
  ## Ревью и полировка
85
85
 
package/README.md CHANGED
@@ -25,7 +25,7 @@ eda init
25
25
 
26
26
  `eda update` сначала переносит старые рабочие каталоги из `docs/<тип>/` в `docs/artifacts/<тип>/`, затем обновляет настройки, скилы и агентов. Содержимое файлов при переносе не меняется. Если один относительный путь уже существует в новой структуре, новый файл сохраняется, а старый удаляется.
27
27
 
28
- Полный валидный v3-конфиг сохраняется байт-в-байт. Старый, неизвестный или неполный файл разбирается как YAML: известные значения переносятся, в TTY спрашиваются только отсутствующие, затем профиль целиком атомарно записывается как v3. Без TTY используются перенесённые значения и defaults.
28
+ Полный валидный v3-конфиг сохраняется, пока совпадает с актуальным шаблоном; если в пакете появились новые значения или подсказки, файл молча перерисовывается с сохранением ваших значений. Старый, неизвестный или неполный файл разбирается как YAML: известные значения переносятся, в TTY спрашиваются только отсутствующие, затем профиль целиком атомарно записывается как v3. Без TTY используются перенесённые значения и defaults.
29
29
 
30
30
  Если пакет уже стоит во многих проектах, можно обновить его одной командой:
31
31
 
@@ -33,7 +33,7 @@ eda init
33
33
  eda update-all ~/Code
34
34
  ```
35
35
 
36
- `eda update-all` ищет проекты в указанной директории, её прямых подпапках и подпапках второго уровня. Проект считается найденным, если в нём уже есть установленный скил, агент или manifest `eda` для Claude/Codex. В каждом проекте команда переносит рабочие артефакты, затем предлагает настроить один общий профиль для всех проектов или выбрать `skip`. В режиме `skip` полный v3 сохраняется, старые и неполные конфиги индивидуально переносятся, отсутствующие создаются с defaults. Без TTY автоматически используется `skip`. Ошибка одного проекта не останавливает остальные.
36
+ `eda update-all` ищет проекты в указанной директории, её прямых подпапках и подпапках второго уровня. Проект считается найденным, если в нём уже есть установленный скил, агент или manifest `eda` для Claude/Codex. В каждом проекте команда переносит рабочие артефакты, затем предлагает настроить один общий профиль для всех проектов или выбрать `skip`. В режиме `skip` актуальный полный v3 сохраняется, устаревший по шаблону перерисовывается, старые и неполные конфиги индивидуально переносятся, отсутствующие создаются с defaults. Без TTY автоматически используется `skip`. Ошибка одного проекта не останавливает остальные.
37
37
 
38
38
  ---
39
39
 
@@ -414,9 +414,9 @@ discover-automations:
414
414
 
415
415
  Каждый скилл читает только свой раздел. Для `eda-review` прямое указание в текущем запросе может разово включить или отключить проверку и заменить её модель, например: «без performance, включи business, architecture на opus».
416
416
 
417
- Поддерживается только `version: 3`. Полный валидный v3 установщик сохраняет байт-в-байт. Старые, неизвестные и неполные файлы разбираются через YAML: валидные известные значения переносятся, в TTY спрашиваются только отсутствующие, затем профиль целиком атомарно нормализуется. Без TTY недостающие поля получают defaults. `plan.meta_review` переносится в `plan.review`, а `plan-polish.strict` удаляется.
417
+ Поддерживается только `version: 3`. Полный валидный v3 установщик сохраняет как есть, пока его текст совпадает с шаблоном пакета; когда шаблон меняется — например, у настройки появляется новое допустимое значение, — файл перерисовывается без вопросов: ваши значения переносятся, посторонние ключи и ручные комментарии не сохраняются. Старые, неизвестные и неполные файлы разбираются через YAML: валидные известные значения переносятся, в TTY спрашиваются только отсутствующие, затем профиль целиком атомарно нормализуется. Без TTY недостающие поля получают defaults. `plan.meta_review` переносится в `plan.review`, а `plan-polish.strict` удаляется.
418
418
 
419
- `eda update-all configure` записывает один общий v3-профиль. `skip` сохраняет полный v3, индивидуально переносит остальные конфиги и создаёт defaults при отсутствии файла. Подробности перехода приведены в [MIGRATION.md](MIGRATION.md)
419
+ `eda update-all configure` записывает один общий v3-профиль. `skip` сохраняет актуальный полный v3 и перерисовывает устаревший по шаблону, индивидуально переносит остальные конфиги и создаёт defaults при отсутствии файла. Подробности перехода приведены в [MIGRATION.md](MIGRATION.md)
420
420
 
421
421
  ---
422
422
 
@@ -526,7 +526,7 @@ eda update-all ~/Code
526
526
  | Агент | `.claude/agents/<agent>.md` | `.codex/agents/<agent>.toml` |
527
527
  | Manifest владения | `.claude/eda-manifest.json` | `.codex/eda-manifest.json` |
528
528
 
529
- `eda update` переносит известные старые каталоги артефактов, сохраняет полный v3-конфиг как есть, а старый или неполный умно переносит и целиком нормализует; затем идемпотентно синхронизирует обе группы компонентов и отдельно показывает реально изменившиеся скилы и агенты. Manifest хранит только идентификаторы компонентов, которыми владеет `eda`: retired-компоненты удаляются, а чужие скилы и агенты остаются нетронутыми. `eda update-all [dir]` выполняет тот же перенос артефактов в каждом проекте, затем либо записывает общий профиль, либо в `skip` сохраняет полный v3 и переносит остальные настройки. При миграции Codex установщик переносит актуальные скилы в `.agents/skills/` и удаляет принадлежащие `eda` старые копии `.codex/skills/<skill>/` и `.codex/skills/<skill>.md`, не затрагивая чужие компоненты.
529
+ `eda update` переносит известные старые каталоги артефактов, сохраняет актуальный полный v3-конфиг как есть, устаревший по шаблону перерисовывает с сохранением значений, а старый или неполный умно переносит и целиком нормализует; затем идемпотентно синхронизирует обе группы компонентов и отдельно показывает реально изменившиеся скилы и агенты. Manifest хранит только идентификаторы компонентов, которыми владеет `eda`: retired-компоненты удаляются, а чужие скилы и агенты остаются нетронутыми. `eda update-all [dir]` выполняет тот же перенос артефактов в каждом проекте, затем либо записывает общий профиль, либо в `skip` сохраняет актуальный полный v3, перерисовывает устаревший по шаблону и переносит остальные настройки. При миграции Codex установщик переносит актуальные скилы в `.agents/skills/` и удаляет принадлежащие `eda` старые копии `.codex/skills/<skill>/` и `.codex/skills/<skill>.md`, не затрагивая чужие компоненты.
530
530
 
531
531
  Установленные копии не являются источником правды. Локальные изменения внутри `.claude/skills/eda-*`, `.agents/skills/eda-*`, `.claude/agents/eda-*` или `.codex/agents/eda-*` будут заменены следующим обновлением.
532
532
 
package/lib/install.js CHANGED
@@ -607,21 +607,18 @@ export async function updateAll({
607
607
  const projectSettingsPath = path.join(projectDir, SETTINGS_RELATIVE_PATH);
608
608
  if (resolvedSettingsMode === 'skip' && await fileExists(projectSettingsPath)) {
609
609
  const existingContent = await fs.readFile(projectSettingsPath, 'utf8');
610
- const migrated = migrateSettingsContent(existingContent);
611
- if (
612
- migrated.version === SETTINGS_VERSION
613
- && migrated.missingKeys.size === 0
614
- && migrated.retiredPaths.length === 0
615
- && migrated.normalizedPaths.length === 0
616
- ) {
610
+ const { migrated, needsMigration, rendered, formatChanged } = resolveSettingsUpdate(existingContent);
611
+ if (!needsMigration && migrated.retiredPaths.length === 0 && !formatChanged) {
617
612
  output.write(`Полный файл настроек сохранён: ${SETTINGS_RELATIVE_PATH}\n`);
618
613
  } else {
619
- await writeSettingsContent(projectDir, formatSettings(migrated.settings));
614
+ await writeSettingsContent(projectDir, rendered);
620
615
  output.write(migrated.retiredPaths.length > 0
621
616
  ? `Из файла настроек убраны устаревшие ключи (${migrated.retiredPaths.join(', ')}): ${SETTINGS_RELATIVE_PATH}\n`
622
617
  : migrated.normalizedPaths.length > 0
623
618
  ? `Переименованы значения настроек (${migrated.normalizedPaths.join(', ')}): ${SETTINGS_RELATIVE_PATH}\n`
624
- : `Старый или неполный файл настроек перенесён на version: ${SETTINGS_VERSION}: ${SETTINGS_RELATIVE_PATH}\n`);
619
+ : needsMigration
620
+ ? `Старый или неполный файл настроек перенесён на version: ${SETTINGS_VERSION}: ${SETTINGS_RELATIVE_PATH}\n`
621
+ : `Файл настроек обновлён до актуального формата, значения сохранены: ${SETTINGS_RELATIVE_PATH}\n`);
625
622
  }
626
623
  } else {
627
624
  await writeSettingsContent(projectDir, sharedSettingsContent);
@@ -1089,12 +1086,14 @@ async function ensureSettings(cwd, { input = process.stdin, output = process.std
1089
1086
  return;
1090
1087
  }
1091
1088
 
1092
- const migrated = migrateSettingsContent(existingContent);
1093
- const needsMigration = migrated.version !== SETTINGS_VERSION
1094
- || migrated.missingKeys.size > 0
1095
- || migrated.normalizedPaths.length > 0;
1089
+ const { migrated, needsMigration, rendered, formatChanged } = resolveSettingsUpdate(existingContent);
1096
1090
  if (!needsMigration && migrated.retiredPaths.length === 0) {
1097
- output.write(`Настройки уже есть: ${SETTINGS_RELATIVE_PATH}\n`);
1091
+ if (!formatChanged) {
1092
+ output.write(`Настройки уже есть: ${SETTINGS_RELATIVE_PATH}\n`);
1093
+ return;
1094
+ }
1095
+ await writeSettingsContent(cwd, rendered);
1096
+ output.write(`Обновил ${SETTINGS_RELATIVE_PATH} до актуального формата: значения сохранены.\n`);
1098
1097
  return;
1099
1098
  }
1100
1099
 
@@ -1125,12 +1124,14 @@ async function configureSettings(cwd, { input = process.stdin, output = process.
1125
1124
  return;
1126
1125
  }
1127
1126
 
1128
- const migrated = migrateSettingsContent(existingContent);
1129
- const needsMigration = migrated.version !== SETTINGS_VERSION
1130
- || migrated.missingKeys.size > 0
1131
- || migrated.normalizedPaths.length > 0;
1127
+ const { migrated, needsMigration, rendered, formatChanged } = resolveSettingsUpdate(existingContent);
1132
1128
  if (!needsMigration && migrated.retiredPaths.length === 0) {
1133
- output.write(`Настройки ${SETTINGS_RELATIVE_PATH} версии ${SETTINGS_VERSION} полные — вопросы не требуются.\n`);
1129
+ if (!formatChanged) {
1130
+ output.write(`Настройки ${SETTINGS_RELATIVE_PATH} версии ${SETTINGS_VERSION} полные — вопросы не требуются.\n`);
1131
+ return;
1132
+ }
1133
+ await writeSettingsContent(cwd, rendered);
1134
+ output.write(`Обновил ${SETTINGS_RELATIVE_PATH} до актуального формата: значения сохранены, вопросы не требуются.\n`);
1134
1135
  return;
1135
1136
  }
1136
1137
 
@@ -1150,6 +1151,17 @@ async function configureSettings(cwd, { input = process.stdin, output = process.
1150
1151
  output.write(`Переписан файл настроек: ${SETTINGS_RELATIVE_PATH} → version: ${SETTINGS_VERSION}.\n`);
1151
1152
  }
1152
1153
 
1154
+ // Конфиг несёт подсказки и списки допустимых значений, поэтому при обновлении пакета
1155
+ // его форма пересобирается заново: значения пользователя переносятся, текст догоняет актуальный.
1156
+ function resolveSettingsUpdate(existingContent) {
1157
+ const migrated = migrateSettingsContent(existingContent);
1158
+ const needsMigration = migrated.version !== SETTINGS_VERSION
1159
+ || migrated.missingKeys.size > 0
1160
+ || migrated.normalizedPaths.length > 0;
1161
+ const rendered = formatSettings(migrated.settings);
1162
+ return { migrated, needsMigration, rendered, formatChanged: rendered !== existingContent };
1163
+ }
1164
+
1153
1165
  async function writeSettingsContent(cwd, content) {
1154
1166
  const settingsPath = path.join(cwd, SETTINGS_RELATIVE_PATH);
1155
1167
  await fs.mkdir(path.dirname(settingsPath), { recursive: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gian-tiaga/eda",
3
- "version": "3.10.0",
3
+ "version": "3.10.1",
4
4
  "description": "Пакет скилов и специализированных агентов eda-* для Claude Code и Codex CLI",
5
5
  "type": "module",
6
6
  "bin": {