@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 +2 -2
- package/README.md +5 -5
- package/lib/install.js +31 -19
- package/package.json +1 -1
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
|
|
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-конфиг
|
|
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 установщик сохраняет
|
|
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
|
|
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 =
|
|
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,
|
|
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
|
-
:
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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 });
|