@iwonz/ywtc 2.0.2 → 3.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/CHANGELOG.md CHANGED
@@ -2,6 +2,41 @@
2
2
 
3
3
  Notable changes to `ywtc` are documented in this file. Versions follow [Semantic Versioning](https://semver.org/).
4
4
 
5
+ ## [3.0.0](https://github.com/iwonz/ywtc/compare/v2.0.3...v3.0.0) (2026-10-15)
6
+
7
+
8
+ ### ⚠ BREAKING CHANGES
9
+
10
+ * **workspace:** consolidate runtime configuration
11
+
12
+ ### Features
13
+
14
+ * **workspace:** consolidate runtime configuration ([123f13b](https://github.com/iwonz/ywtc/commit/123f13ba2883de034b9b8f458fd01ad02576be70))
15
+
16
+
17
+ ### Documentation
18
+
19
+ * **readme:** depict universal transfer paths ([1c7d01f](https://github.com/iwonz/ywtc/commit/1c7d01f907205bed8a44a8dc7819717a84130316))
20
+ * **readme:** stabilize information architecture ([03eb3e3](https://github.com/iwonz/ywtc/commit/03eb3e3ee8aefb76a00237aec7e2561184b214f5))
21
+
22
+
23
+ ### Maintenance
24
+
25
+ * **ci:** resume release after commit validation ([1540b51](https://github.com/iwonz/ywtc/commit/1540b51727e6ca58816a1099b2add73a3eacf7cf))
26
+ * **homebrew:** update formula to v2.0.3 ([63262bb](https://github.com/iwonz/ywtc/commit/63262bb13e5765aa2f3a15f04e6f98a0379f247e))
27
+
28
+ ## [2.0.3](https://github.com/iwonz/ywtc/compare/v2.0.2...v2.0.3) (2026-10-15)
29
+
30
+
31
+ ### Bug Fixes
32
+
33
+ * **release:** wait for npm registry propagation ([e27d2e1](https://github.com/iwonz/ywtc/commit/e27d2e18fb41d80c8b07dea4fe610fab15ab6676))
34
+
35
+
36
+ ### Maintenance
37
+
38
+ * **homebrew:** update formula to v2.0.2 ([479f375](https://github.com/iwonz/ywtc/commit/479f375afbb1344f41f261e4e77f1960b897bd4f))
39
+
5
40
  ## [2.0.2](https://github.com/iwonz/ywtc/compare/v2.0.1...v2.0.2) (2026-10-15)
6
41
 
7
42
 
package/README.md CHANGED
@@ -1,34 +1,27 @@
1
1
  <p align="center">
2
- <img src="docs/assets/readme-header.png" alt="Yandex Wiki and Confluence content moving through the ywtc pipeline" width="100%">
2
+ <img src="docs/assets/readme-header.png" alt="Yandex Wiki and Confluence sources moving through ywtc to Confluence, Yandex Wiki, Markdown, and HTML destinations" width="100%">
3
3
  </p>
4
4
 
5
5
  # ywtc
6
6
 
7
- `ywtc` — CLI для контролируемого переноса страниц между Yandex Wiki и Confluence, а также экспорта в Markdown или автономный HTML. Утилита сохраняет структуру, ссылки и вложения, отмечает деградации, проверяет результат и продолжает прерванную операцию по state-файлу. Исходные данные и страницы назначения автоматически не удаляются.
7
+ ## Описание
8
8
 
9
- Требуются Node.js `>=24` и npm `>=11.5.1`.
9
+ `ywtc` — CLI для переноса страниц между Yandex Wiki и Confluence и экспорта в Markdown или автономный HTML. Утилита сохраняет структуру, ссылки и вложения, явно отмечает деградации и продолжает прерванные операции по state-файлу. Исходные данные и страницы назначения автоматически не удаляются.
10
+
11
+ Требуются Node.js `>=24` и npm `>=11.5.1`. Лицензия — [MIT](LICENSE).
10
12
 
11
13
  ## Возможности
12
14
 
13
15
  | Что переносится | Результат |
14
16
  | --- | --- |
15
17
  | Страницы и иерархия | Одна страница, структурное поддерево или граф связанных страниц |
16
- | Заголовки, текст, списки, цитаты, код, таблицы | Нативная разметка назначения, насколько это допускает формат |
18
+ | Заголовки, текст, списки, цитаты, код и таблицы | Нативная разметка назначения, насколько это допускает формат |
17
19
  | Внутренние ссылки и якоря | Переписываются на перенесённые страницы; внешние остаются внешними |
18
20
  | Изображения и вложения | Потоковая передача с проверкой имени, размера и SHA-256 |
19
21
  | Yandex notes, cuts, tabs и Grid | Ближайший нативный эквивалент; Grid становится статической таблицей |
20
- | Confluence macros и resource identifiers | Сохраняются напрямую для same-vendor transfer либо преобразуются |
21
- | Неподдерживаемые vendor-конструкции | Читаемый fallback и raw snapshot: attachment или файл в `_source/` |
22
- | История, комментарии, пользователи, права, watchers | Не переносятся |
23
-
24
- ## Минимальный сценарий
25
-
26
- - [ ] Установите CLI: `npm install -g @iwonz/ywtc`.
27
- - [ ] Создайте workspace: `ywtc init`.
28
- - [ ] Заполните `~/.ywtc/ywtc.config.yaml` и секреты в `~/.ywtc/.env`.
29
- - [ ] Проверьте доступ: `ywtc doctor --source <source> --destination <destination>`.
30
- - [ ] Выполните dry-run: `ywtc migrate --source <source> --destination <destination> --dry-run`.
31
- - [ ] Повторите команду без `--dry-run`.
22
+ | Confluence macros и resource identifiers | Сохраняются напрямую при переносе между Confluence либо преобразуются |
23
+ | Неподдерживаемые vendor-конструкции | Читаемый fallback и raw snapshot в attachment или `_source/` |
24
+ | История, комментарии, пользователи, права и watchers | Не переносятся |
32
25
 
33
26
  ## Установка
34
27
 
@@ -36,7 +29,7 @@
36
29
  # npm
37
30
  npm install -g @iwonz/ywtc
38
31
 
39
- # без глобальной установки
32
+ # npx без глобальной установки
40
33
  npx @iwonz/ywtc@latest --version
41
34
 
42
35
  # Homebrew
@@ -45,196 +38,212 @@ brew trust --tap iwonz/ywtc
45
38
  brew install ywtc
46
39
  ```
47
40
 
48
- Homebrew 7 требует явно доверить сторонний tap. Команда `brew trust --tap iwonz/ywtc` разрешает загрузку формул только из этого репозитория; перед выполнением можно проверить его содержимое на GitHub.
41
+ Homebrew 7 требует доверить сторонний tap; команда `brew trust` относится только к `iwonz/ywtc`.
49
42
 
50
- Проверить или установить обновление:
43
+ Обновление:
51
44
 
52
45
  ```bash
53
- ywtc update
54
- ywtc update --install # только global npm или Homebrew
55
- ywtc update --install --via brew
46
+ ywtc update # только проверка
47
+ ywtc update --install # канал текущей установки
48
+ ywtc update --install --via brew # явно через Homebrew
56
49
  ```
57
50
 
58
- ## Профили и workspace
51
+ ## Минимальный сценарий
52
+
53
+ - [ ] Установите CLI одним из способов выше.
54
+ - [ ] Создайте рабочий каталог: `ywtc init`.
55
+ - [ ] Заполните подключения и токены в `~/.ywtc/ywtc.config.yaml`.
56
+ - [ ] Проверьте доступ: `ywtc doctor --source <source> --destination <destination>`.
57
+ - [ ] Проверьте план: `ywtc migrate --source <source> --destination <destination> --dry-run`.
58
+ - [ ] Запустите ту же команду без `--dry-run`.
59
+
60
+ ## Конфигурация
59
61
 
60
- Workspace выбирается в порядке `--workdir` → текущий каталог с `.ywtc-workspace.json` → `~/.ywtc`. Команда `init` идемпотентна и не перезаписывает существующие файлы:
62
+ Для рабочих команд каталог выбирается в порядке: `--workdir` → текущий каталог, если непосредственно в нём есть `ywtc.config.yaml` → `~/.ywtc`. Поиск по родительским каталогам не выполняется. `ywtc init` без `--workdir` всегда использует `~/.ywtc`; `migrate` автоматически инициализирует отсутствующий workspace.
61
63
 
62
64
  ```text
63
65
  ~/.ywtc/
64
- ├── .ywtc-workspace.json
65
- ├── .env # только секреты, mode 0600
66
- ├── ywtc.config.yaml # подключения без секретов
67
- └── .states/ # state, cache и HTML-отчёты
66
+ ├── ywtc.config.yaml # подключения, настройки и токены; mode 0600 при создании
67
+ └── .states/ # state, cache и отчёты
68
68
  ```
69
69
 
70
- Минимальная конфигурация двух подключений:
71
-
72
- ```yaml
73
- schemaVersion: 2
74
- defaults:
75
- timeoutMs: 30000
76
- concurrency: 4
77
-
78
- connections:
79
- wiki-prod:
80
- type: yandex-wiki
81
- apiUrl: https://api.wiki.yandex.net/v1
82
- webUrl: https://wiki.example.ru
83
- authType: oauth
84
- tokenEnv: YANDEX_WIKI_TOKEN
85
- organization: {type: yandex360, id: organization-id}
86
-
87
- confluence-prod:
88
- type: confluence
89
- deployment: data-center
90
- baseUrl: https://confluence.example.ru/confluence
91
- authType: pat
92
- tokenEnv: CONFLUENCE_TOKEN
93
- ```
70
+ `ywtc init` создаёт безопасный шаблон. Полный пример с Yandex Wiki, Confluence Data Center, Confluence Cloud и сетевыми лимитами: [`ywtc.config.example.yaml`](ywtc.config.example.yaml).
94
71
 
95
- ```dotenv
96
- YANDEX_WIKI_TOKEN=
97
- CONFLUENCE_TOKEN=
98
- # Для Confluence Cloud:
99
- CONFLUENCE_EMAIL=
100
- ```
72
+ ### Поля профилей
101
73
 
102
- Полный шаблон с сетевыми лимитами находится в [`ywtc.config.example.yaml`](ywtc.config.example.yaml). Значения process environment имеют приоритет над `.env`. Секреты проверяются только для профилей, участвующих в текущей операции.
74
+ | Поле | Для кого | Обязательность / значения | Назначение |
75
+ | --- | --- | --- | --- |
76
+ | `defaults.timeoutMs` | файл | `1000..300000`, default `30000` | Таймаут HTTP-запроса |
77
+ | `defaults.concurrency` | файл | `1..64`, default `4` | Общая параллельность операции |
78
+ | `connections.<name>` | файл | минимум один; имя `[a-z0-9._-]+` | Именованное подключение |
79
+ | `type` | все профили | `yandex-wiki` или `confluence` | Тип провайдера |
80
+ | `token` | все профили | непустой для используемого профиля | OAuth, IAM, PAT или API token |
81
+ | `apiUrl` | Yandex Wiki | URL Public API v1 | API endpoint |
82
+ | `webUrl` | Yandex Wiki | URL | Базовый адрес Wiki для ссылок и выбора профиля |
83
+ | `authType` | Yandex Wiki | `oauth` (default) или `iam` | Схема авторизации |
84
+ | `organization.type` | Yandex Wiki | `yandex360` (default) или `cloud` | Заголовок `X-Org-Id` или `X-Cloud-Org-Id` |
85
+ | `organization.id` | Yandex Wiki | непустая строка | ID организации |
86
+ | `deployment` | Confluence | `data-center` или `cloud` | Тип развёртывания |
87
+ | `baseUrl` | Confluence | URL | Адрес инстанса, включая context path |
88
+ | `authType` | Confluence | `pat` для Data Center; `api-token` для Cloud | Схема авторизации |
89
+ | `email` | Confluence Cloud | непустой для используемого профиля | Email Atlassian-аккаунта |
90
+ | `limits.readConcurrency` | все профили | `1..64`, default `4` | Параллельные чтения |
91
+ | `limits.writeConcurrency` | все профили | `1..32`, default `2` | Параллельные записи |
92
+ | `limits.downloadConcurrency` | все профили | `1..32`, default `2` | Параллельные скачивания |
93
+ | `limits.uploadConcurrency` | все профили | `1..32`, default `2` | Параллельные загрузки |
94
+ | `limits.requestsPerSecond` | все профили | `1..1000`, default `8` | Средняя частота запросов |
95
+ | `limits.burst` | все профили | `1..1000`, default `8` | Допустимый кратковременный burst |
96
+
97
+ Конфигурация строгая: неизвестные поля считаются ошибкой. Все значения, включая токены, email, таймауты и лимиты, читаются только из `ywtc.config.yaml`; process environment их не переопределяет. Файл рабочего каталога игнорируется Git, а токены маскируются в диагностике и отчётах.
98
+
99
+ ## Направления и совместимость
100
+
101
+ | Source | Destination | Поддержка |
102
+ | --- | --- | --- |
103
+ | Yandex Wiki | Confluence | Да |
104
+ | Yandex Wiki | Yandex Wiki | Да, включая другой профиль или инстанс |
105
+ | Confluence | Yandex Wiki | Да |
106
+ | Confluence | Confluence | Да, включая другой профиль или инстанс |
107
+ | Yandex Wiki или Confluence | Markdown | Да |
108
+ | Yandex Wiki или Confluence | статический HTML | Да |
109
+
110
+ | Система | Контракт | Авторизация |
111
+ | --- | --- | --- |
112
+ | Yandex Wiki | Public API v1; новые необязательные поля принимаются | OAuth или пользовательский IAM; `X-Org-Id`/`X-Cloud-Org-Id` |
113
+ | Confluence Data Center | 7.9+ без верхней границы; capabilities проверяются до записи | Bearer PAT |
114
+ | Confluence Cloud | REST v2 для страниц и REST v1 для attachments | Email + API token |
115
+
116
+ Confluence Server, Data Center Basic Auth и OAuth app-flow не поддерживаются. Совместимость определяется preflight-проверкой необходимых API/capabilities, а не сертификацией каждой patch-версии.
103
117
 
104
118
  ## Как получить токены
105
119
 
106
120
  ### Yandex Wiki
107
121
 
108
- - [ ] Создайте приложение в [Яндекс OAuth](https://oauth.yandex.ru/) для доступа к API.
109
- - [ ] Выдайте приложению права Wiki на чтение; для destination также нужны права записи.
110
- - [ ] Получите OAuth-токен пользователя, имеющего доступ к нужным страницам. Для федеративного пользователя Yandex Cloud можно использовать IAM-токен и `authType: iam`.
122
+ - [ ] Создайте приложение в [Яндекс OAuth](https://oauth.yandex.ru/).
123
+ - [ ] Выдайте права Wiki на чтение; для destination также нужны права записи.
124
+ - [ ] Получите OAuth-токен пользователя с доступом к страницам. Для федеративного пользователя Yandex Cloud допустим IAM-токен и `authType: iam`.
111
125
  - [ ] Найдите ID организации в **Yandex Tracker → Администрирование → Организации**.
112
- - [ ] Укажите `organization.type: yandex360` для Яндекс 360 либо `cloud` для Cloud Organization.
113
- - [ ] Сохраните токен в env-переменной, указанной в `tokenEnv`.
126
+ - [ ] Укажите `organization.type: yandex360` для Яндекс 360 или `cloud` для Cloud Organization.
127
+ - [ ] Запишите токен в `connections.<name>.token` выбранного профиля.
114
128
 
115
129
  ### Confluence Data Center
116
130
 
117
131
  - [ ] Откройте **Avatar → Settings → Personal access tokens → Create token**.
118
- - [ ] Создайте PAT и сохраните его в env-переменной из `tokenEnv`.
132
+ - [ ] Создайте PAT и запишите его в `connections.<name>.token`.
119
133
  - [ ] Используйте `deployment: data-center` и `authType: pat`.
120
- - [ ] Убедитесь, что пользователь может читать source и создавать/изменять страницы и вложения destination.
134
+ - [ ] Проверьте права на чтение source и создание/изменение страниц и вложений destination.
121
135
 
122
136
  ### Confluence Cloud
123
137
 
124
138
  - [ ] Создайте [Atlassian API token](https://id.atlassian.com/manage-profile/security/api-tokens).
125
- - [ ] Используйте `deployment: cloud`, `authType: api-token`, `tokenEnv` и `emailEnv`.
126
- - [ ] Сохраните API token и email Atlassian-аккаунта в соответствующих env-переменных.
127
- - [ ] Проверьте доступ аккаунта к source/destination space.
139
+ - [ ] Используйте `deployment: cloud`, `authType: api-token`, `token` и `email`.
140
+ - [ ] Запишите API token и email аккаунта непосредственно в выбранный профиль.
141
+ - [ ] Проверьте доступ аккаунта к source и destination spaces.
128
142
 
129
- ## Направления и совместимость
143
+ ## Параметры
130
144
 
131
- | Source | Destination | Поддержка |
132
- | --- | --- | --- |
133
- | Yandex Wiki | Confluence | Да |
134
- | Yandex Wiki | Yandex Wiki | Да, включая другой профиль/инстанс |
135
- | Confluence | Yandex Wiki | Да |
136
- | Confluence | Confluence | Да, включая другой профиль/инстанс |
137
- | Yandex Wiki или Confluence | Markdown | Да |
138
- | Yandex Wiki или Confluence | статический HTML | Да |
139
-
140
- | Система | Поддерживаемый контракт | Авторизация |
141
- | --- | --- | --- |
142
- | Yandex Wiki | Public API v1; tolerant parsing новых необязательных полей | OAuth или пользовательский IAM; `X-Org-Id`/`X-Cloud-Org-Id` |
143
- | Confluence Data Center | 7.9+ без искусственной верхней границы; capabilities проверяются до записи | Bearer PAT |
144
- | Confluence Cloud | Текущий публичный REST v2 для страниц и v1 для attachments | Email + API token |
145
-
146
- Confluence Server, Data Center Basic Auth и OAuth app-flow пока не поддерживаются. Совместимость определяется preflight-проверкой используемых API/capabilities, а не обещанием для каждой patch-версии.
145
+ ### Команды
147
146
 
148
- ## Параметры `migrate`
147
+ | Команда | Назначение |
148
+ | --- | --- |
149
+ | `ywtc init [--workdir <path>]` | Создать или дополнить workspace без перезаписи данных |
150
+ | `ywtc doctor [options]` | Проверить workspace; с source и destination выполнить read-only preflight |
151
+ | `ywtc migrate --source <locator> --destination <locator\|directory> [options]` | Перенести или экспортировать выбранный граф страниц |
152
+ | `ywtc update [--install] [--via npm\|brew]` | Проверить или установить обновление безопасным для текущего канала способом |
153
+ | `ywtc --help`, `ywtc <command> --help` | Показать общую или командную справку |
154
+ | `ywtc --version` | Показать версию |
149
155
 
150
- ```text
151
- ywtc migrate --source <locator> --destination <locator|directory> [options]
152
- ```
156
+ ### Опции
153
157
 
154
- | Параметр | Обязателен | Значения / default | Назначение |
158
+ | Опция | Команды | Обязательность / значения | Назначение |
155
159
  | --- | --- | --- | --- |
156
- | `--source <value>` | Да | URL, page ID или slug | Исходная страница |
157
- | `--destination <value>` | Да | URL, page ID, slug или каталог | Родительская страница либо каталог экспорта |
158
- | `--source-profile <name>` | Иногда | имя из `connections` | Нужен для неоднозначного короткого ID/slug |
159
- | `--destination-profile <name>` | Иногда | имя из `connections` | То же для удалённой destination |
160
- | `--scope <mode>` | Нет | `page`, `subtree` (default), `linked` | Граница выбора страниц |
161
- | `--format <format>` | Для каталога | `markdown`, `html` | Однозначно включает файловый экспорт |
162
- | `--archive` | Нет | только с `--format` | Оставляет каталог и создаёт ZIP рядом |
163
- | `--dry-run` | Нет | `false` | Полный discovery/план без destination writes |
164
- | `--workdir <path>` | Нет | marker CWD или `~/.ywtc` | Выбирает workspace |
165
- | `--state <path>` | Нет | `.states/<automatic-id>.json` | Явный state внутри workspace |
166
- | `--fresh` | Нет | `false` | Не использует mappings; live-run сохраняет backup state |
167
- | `--concurrency <n>` | Нет | `1..64`, config default `4` | Параллельность оркестрации; профильные лимиты действуют отдельно |
168
-
169
- Полный URL автоматически сопоставляется с профилем по нормализованному base URL. Для короткого ID/slug профиль выбирается автоматически только при единственном подходящем подключении; иначе CLI перечисляет допустимые имена. Каталог считается файловой destination только вместе с `--format`.
160
+ | `--source <value>` | `doctor`, `migrate` | обязательно для `migrate`; в `doctor` вместе с destination | URL, page ID или Yandex slug |
161
+ | `--destination <value>` | `doctor`, `migrate` | обязательно для `migrate`; в `doctor` вместе с source | Родительская страница или каталог экспорта |
162
+ | `--source-profile <name>` | `doctor`, `migrate` | при неоднозначном коротком locator | Профиль source из `connections` |
163
+ | `--destination-profile <name>` | `doctor`, `migrate` | при неоднозначном remote locator | Профиль destination; несовместим с файловым экспортом |
164
+ | `--scope <mode>` | `doctor`, `migrate` | `page`, `subtree` (default), `linked` | Граница выбора страниц |
165
+ | `--format <format>` | `doctor`, `migrate` | `markdown` или `html` | Делает destination файловым каталогом |
166
+ | `--archive` | `migrate` | только вместе с `--format` | Дополнительно создать ZIP рядом с каталогом |
167
+ | `--dry-run` | `migrate` | default `false` | Discovery и план без записи в destination |
168
+ | `--fresh` | `migrate` | default `false` | Игнорировать mappings текущего state |
169
+ | `--concurrency <n>` | `migrate` | `1..64`; иначе config default | Общая параллельность; профильные лимиты сохраняются |
170
+ | `--state <path>` | `migrate` | внутри workspace | Явный state вместо автоматического |
171
+ | `--workdir <path>` | `init`, `doctor`, `migrate` | config в CWD или `~/.ywtc` | Явно выбрать workspace; поддерживается `~/...` |
172
+ | `--install` | `update` | default `false` | Установить найденное обновление |
173
+ | `--via <channel>` | `update` | `npm` или `brew` | Явно выбрать совместимый канал обновления |
174
+ | `-h`, `--help` | CLI и команды | необязательно | Справка |
175
+ | `-v`, `--version` | CLI | необязательно | Версия |
176
+
177
+ ### Локаторы
178
+
179
+ - Yandex Wiki: полный URL, числовой page ID или slug, например `team/start`.
180
+ - Confluence: числовой page ID, URL с `pageId=<id>` либо URL с `/pages/<id>` или `/content/<id>`.
181
+ - Полный URL автоматически выбирает профиль по нормализованному base URL.
182
+ - Короткий ID/slug выбирается автоматически только при единственном подходящем профиле; иначе нужен `--source-profile` или `--destination-profile`.
183
+ - Каталог является файловой destination только вместе с `--format`.
170
184
 
171
185
  ### Scope
172
186
 
173
187
  - `page` — только исходная страница.
174
- - `subtree` — страница и все структурные потомки; режим по умолчанию.
175
- - `linked` — детерминированный BFS по внутренним ссылкам и page/include references до фиксированной точки. Циклы безопасно завершаются, страница обрабатывается один раз. Внешние и недоступные ссылки не обходятся и отражаются в отчёте.
188
+ - `subtree` — страница и все структурные потомки; default.
189
+ - `linked` — детерминированный BFS по внутренним ссылкам и page/include references до фиксированной точки. Циклы завершаются безопасно, каждая страница обрабатывается один раз; внешние и недоступные ссылки не обходятся и попадают в отчёт.
176
190
 
177
191
  ## Частые примеры
178
192
 
179
193
  ```bash
180
- # Связанные страницы Yandex Wiki → Confluence
181
- ywtc migrate \
182
- --source https://wiki.example.ru/team/start \
183
- --destination https://confluence.example.ru/pages/viewpage.action?pageId=123 \
194
+ # Yandex Wiki → Confluence: граф связанных страниц
195
+ ywtc migrate --source https://wiki.example.com/team/start \
196
+ --destination https://confluence.example.com/confluence/pages/viewpage.action?pageId=123 \
184
197
  --scope linked
185
198
 
186
- # Confluence → Yandex Wiki по коротким идентификаторам
187
- ywtc migrate \
188
- --source-profile confluence-prod --source 123456 \
189
- --destination-profile wiki-prod --destination team/archive \
190
- --scope subtree
199
+ # Confluence → Yandex Wiki
200
+ ywtc migrate --source-profile confluence-prod --source 123456 \
201
+ --destination-profile wiki-prod --destination team/archive
191
202
 
192
- # Одна страница без потомков
203
+ # Yandex Wiki → Yandex Wiki: одна страница
193
204
  ywtc migrate --source-profile wiki-prod --source team/start \
194
- --destination-profile confluence-prod --destination 123 --scope page
205
+ --destination-profile wiki-archive --destination archive/start --scope page
206
+
207
+ # Confluence → Confluence: новый state в отдельном workspace
208
+ ywtc migrate --workdir ./migration --source-profile confluence-prod --source 123456 \
209
+ --destination-profile confluence-archive --destination 654321 --fresh
195
210
 
196
- # Автономный HTML-сайт и ZIP
211
+ # Автономный HTML и ZIP
197
212
  ywtc migrate --source-profile confluence-prod --source 123456 \
198
213
  --destination ./exports/knowledge-base --format html --scope linked --archive
199
214
 
200
- # Markdown-экспорт в отдельном workspace
201
- ywtc migrate --workdir ./migration --source-profile wiki-prod --source team/start \
202
- --destination ./export --format markdown --dry-run
215
+ # Markdown dry-run
216
+ ywtc migrate --source-profile wiki-prod --source team/start \
217
+ --destination ./exports/knowledge-base --format markdown --dry-run
203
218
  ```
204
219
 
205
- `doctor` принимает те же `source`, `destination`, profile, `scope` и `format`; с endpoints выполняет только read-only capability-preflight. Без endpoints проверяет workspace, конфигурацию и все секреты.
220
+ `doctor` принимает те же endpoints, profiles, `scope` и `format`. Без endpoints он проверяет workspace, конфигурацию и секреты; с обоими endpoints выполняет read-only capability-preflight.
206
221
 
207
222
  ## Файловый экспорт
208
223
 
209
- Markdown создаёт `index.md`, `pages/`, `attachments/`, manifest `.ywtc-export.json` и, при деградациях, `_source/`. HTML создаёт автономный адаптивный сайт с теми же данными и локальным `assets/site.css`; он работает через `file://` и на обычном static hosting без CDN/runtime.
224
+ Markdown создаёт `index.md`, `pages/`, `attachments/`, `.ywtc-export.json` и, при деградациях, `_source/`. HTML создаёт автономный адаптивный сайт с локальным `assets/site.css`; он работает через `file://` и на static hosting без CDN или внешнего runtime.
210
225
 
211
- Экспорт строится в staging-каталоге. Существующий каталог заменяется только при совпадающем ywtc manifest; предыдущая версия сохраняется как timestamped backup. ZIP не перезаписывает уже существующий архив.
226
+ Экспорт сначала строится в staging-каталоге. Существующий каталог заменяется только при строгом актуальном manifest с `tool: ywtc` и той же canonical identity, а прежний каталог сохраняется как timestamped backup. `--archive` оставляет каталог и создаёт новый ZIP, не перезаписывая существующий архив.
212
227
 
213
- ## State, отчёты и повторный запуск
228
+ ## State
214
229
 
215
- Автоматический state ID строится из канонических профилей и ID source/destination; форма URL/slug/ID и `scope` на него не влияют. Поэтому одна и та же пара endpoints возобновляет один state, а разные пары получают разные файлы.
230
+ По умолчанию state хранится в `<workdir>/.states/<automatic-id>.json`. ID строится из канонических профилей и ID source/destination, а для файлового экспорта также из формата; форма locator и `scope` на ID не влияют. State имеет единственный строгий актуальный формат без поля версии. Несоответствующий файл не преобразуется и не изменяется. Относительный `--state` разрешается внутри workspace, выход за его границы запрещён.
216
231
 
217
- - Повторный запуск обновляет только сопоставленные объекты и не создаёт дубликаты.
218
- - Страница, изменённая вручную после прошлого запуска, получает `conflict` и не перезаписывается.
219
- - `--fresh` начинает с чистых mappings; live-run сохраняет прежний state как backup и может создать новые страницы.
220
- - State schema v1 не мигрируется автоматически и остаётся нетронутой.
221
- - SIGINT/SIGTERM останавливает постановку новых задач, сохраняет state/report и возвращает `130`/`143`.
222
- - Каждый запуск создаёт `.states/reports/<run-id>/index.html` и `report.json`: направление, дерево, link graph, циклы, вложения, размеры, деградации, ошибки и side-by-side preview.
232
+ ### Повторные запуски
223
233
 
224
- Коды выхода: `0` — завершено; `1` — partial/ошибка verification; `2` — usage/config/preflight; `130`/`143` — остановка сигналом.
234
+ - Одинаковые source и destination автоматически подхватывают один state независимо от формы URL/ID/slug.
235
+ - Уже сопоставленные страницы и вложения обновляются без создания дубликатов.
236
+ - Страница, изменённая вручную после прошлого запуска, получает `conflict` и не перезаписывается.
237
+ - `--fresh` игнорирует mappings; перед live-run прежний state сохраняется как backup, а destination может получить новые объекты.
238
+ - Удалённые из source объекты автоматически не удаляются из destination.
225
239
 
226
- ## Переход на 2.0
240
+ При SIGINT/SIGTERM новые задачи не ставятся, активные безопасные операции завершаются, state и отчёт сохраняются. Коды выхода: `0` — completed; `1` — partial или verification failure; `2` — usage/config/preflight; `130`/`143` — остановка сигналом.
227
241
 
228
- Обратной совместимости с предварительным CLI и state v1 нет:
242
+ ## Отчёты
229
243
 
230
- | Было | Стало |
231
- | --- | --- |
232
- | `--target <value>` | `--destination <value>` |
233
- | `--single-page` | `--scope page` |
234
- | Один набор env-подключений | Именованные подключения в `ywtc.config.yaml`; `.env` содержит только секреты |
235
- | State schema v1 | Новый автоматический provider-neutral state v2 |
244
+ Каждый запуск создаёт `<workdir>/.states/reports/<run-id>/index.html` и `report.json`. Отчёт содержит направление, профили, дерево и link graph, циклы, вложения, размеры, деградации, raw snapshots, ошибки и side-by-side preview страниц; unversioned JSON доступен для автоматической обработки.
236
245
 
237
- Старые флаги отклоняются с точной подсказкой. Для переноса создайте новый workspace или сохраните старые state-файлы отдельно и выполните `ywtc init`.
246
+ Итоговый статус запуска: `completed`, `completed-with-warnings`, `partial`, `failed`, `cancelled` или `interrupted`. Для страниц фиксируются `discovered`, `planned`, `skeleton-created`, `complete`, `partial`, `conflict`, `failed` и `blocked`.
238
247
 
239
248
  ## Разработка
240
249
 
@@ -246,27 +255,6 @@ npm run workspace:init
246
255
  npm run check
247
256
  ```
248
257
 
249
- `npm run check` запускает release/hygiene checks, аудит production-зависимостей (high/critical), TypeScript, Biome, Knip, тесты, сборку, проверку устанавливаемого tarball и строгую OpenSpec-валидацию. Изменения оформляются полным OpenSpec-циклом согласно [`AGENTS.md`](AGENTS.md).
250
-
251
- ## Релизы (для сопровождающего)
252
-
253
- Release Please формирует PR из Conventional Commits. После его проверки и merge workflow повторяет полный quality gate, создаёт GitHub Release, публикует npm-пакет с OIDC provenance и обновляет проверенную Homebrew-формулу. Версии `package.json`, lock-файла и changelog вручную не меняются; регулярные релизы не требуют npm OTP или `NPM_TOKEN`.
254
-
255
- Если GitHub Release уже создан, а публикация остановилась, повторите существующий тег идемпотентным recovery:
256
-
257
- ```bash
258
- gh workflow run release.yml --repo iwonz/ywtc -f release_tag=vX.Y.Z
259
- ```
260
-
261
- Recovery проверяет неизменённый tag актуальным trusted validator, не перезаписывает существующую npm-версию и восстанавливает только недостающие artifacts, release notes и Homebrew-формулу.
262
-
263
- Одноразовая инициализация нового npm-пакета выполняется так:
264
-
265
- - [ ] Установить npm `>=11.15`, выполнить `npm login` и проверить владельца через `npm whoami`.
266
- - [ ] Опубликовать placeholder с интерактивной 2FA: `npm run release:bootstrap`; не передавать OTP в файлах, командах или CI.
267
- - [ ] Выполнить `npm trust github @iwonz/ywtc --file release.yml --repo iwonz/ywtc --allow-publish`.
268
- - [ ] В **Settings → Actions → General → Workflow permissions** включить **Allow GitHub Actions to create and approve pull requests**; возможности каждого job дополнительно ограничены его `permissions`.
269
-
270
- Для `@iwonz/ywtc` эта инициализация уже выполнена. Подробности: [npm trusted publishing](https://docs.npmjs.com/trusted-publishers/) и [`npm trust`](https://docs.npmjs.com/cli/v11/commands/npm-trust/).
258
+ `npm run check` запускает проверку репозитория и секретов, production audit уровня high/critical, TypeScript, Biome, Knip, тесты, сборку, проверку npm-пакета и строгую OpenSpec-валидацию. Любое изменение проходит полный OpenSpec-цикл из [`AGENTS.md`](AGENTS.md).
271
259
 
272
- Лицензия: [MIT](LICENSE).
260
+ Release Please рассчитывает SemVer из Conventional Commits. После merge release PR GitHub Actions проверяет релиз, публикует GitHub Release и npm-пакет через OIDC provenance, затем обновляет и проверяет Homebrew-формулу. Версии и changelog вручную не изменяются.
@@ -64,7 +64,7 @@ export function createCliProgram(onCommand = () => undefined) {
64
64
  .addOption(new Option('--scope <scope>', 'selection scope').choices(['page', 'subtree', 'linked']).default('subtree'))
65
65
  .addOption(new Option('--format <format>', 'filesystem format').choices(['markdown', 'html']))
66
66
  .option('--archive', 'also create a ZIP for filesystem output', false)
67
- .option('--workdir <path>', 'workspace (marked CWD, then ~/.ywtc)')
67
+ .option('--workdir <path>', 'workspace (configured CWD, then ~/.ywtc)')
68
68
  .option('--dry-run', 'discover and render without destination writes', false)
69
69
  .option('--fresh', 'ignore mappings and preserve existing live state as a backup', false)
70
70
  .option('--concurrency <n>', 'orchestration concurrency from 1 to 64', concurrency)
@@ -108,10 +108,6 @@ export function createCliProgram(onCommand = () => undefined) {
108
108
  return program;
109
109
  }
110
110
  export function parseCliArguments(argv) {
111
- if (argv.includes('--target'))
112
- throw new Error('--target was removed in ywtc 2.0. Use --destination.');
113
- if (argv.includes('--single-page'))
114
- throw new Error('--single-page was removed in ywtc 2.0. Use --scope page.');
115
111
  if (argv.length === 0 || (argv.length === 1 && ['--help', '-h'].includes(argv[0])))
116
112
  return { command: 'help' };
117
113
  if (argv.length === 1 && ['--version', '-v'].includes(argv[0]))
@@ -127,7 +123,12 @@ export function parseCliArguments(argv) {
127
123
  const output = [];
128
124
  const program = createCliProgram((command) => { parsed = command; });
129
125
  program.exitOverride();
130
- program.configureOutput({ writeOut: (value) => output.push(value), writeErr: (value) => output.push(value) });
126
+ for (const command of program.commands)
127
+ command.exitOverride();
128
+ const writers = { writeOut: (value) => output.push(value), writeErr: (value) => output.push(value) };
129
+ program.configureOutput(writers);
130
+ for (const command of program.commands)
131
+ command.configureOutput(writers);
131
132
  try {
132
133
  program.parse(['node', 'ywtc', ...argv], { from: 'node' });
133
134
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cli-arguments.js","sourceRoot":"","sources":["../src/cli-arguments.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-arguments.js","sourceRoot":"","sources":["../src/cli-arguments.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import { resolveDestinationLocator, resolveSourceLocator } from './locators.js';
6
6
  import { createLogger, redact } from './logger.js';
7
7
  import { runUpdate } from './updater.js';
8
8
  import { packageVersion } from './version.js';
9
- import { initializeWorkspace, resolveWorkspace, resolveWorkspacePath, validateWorkspaceMarker } from './workspace.js';
9
+ import { initializeWorkspace, resolveInitWorkspace, resolveWorkspace, resolveWorkspacePath, workspaceIsInitialized, } from './workspace.js';
10
10
  const color = process.stdout.isTTY && !process.env.NO_COLOR;
11
11
  const paint = (code, value) => color ? `\u001b[${code}m${value}\u001b[0m` : value;
12
12
  function heading(label) {
@@ -15,8 +15,7 @@ function heading(label) {
15
15
  async function migrate(command) {
16
16
  const workspace = await resolveWorkspace(command.workdir ? { explicit: command.workdir } : {});
17
17
  const initialized = await initializeWorkspace(workspace);
18
- await validateWorkspaceMarker(workspace);
19
- const config = readWorkspaceConfig(workspace.envFile, workspace.configFile);
18
+ const config = readWorkspaceConfig(workspace.configFile);
20
19
  const secrets = secretValues(config);
21
20
  const source = resolveSourceLocator(config, command.source, command.sourceProfile);
22
21
  const destination = resolveDestinationLocator({
@@ -118,22 +117,23 @@ export async function main(argv = process.argv.slice(2)) {
118
117
  return 0;
119
118
  }
120
119
  if (command.command === 'init') {
121
- const workspace = await resolveWorkspace(command.workdir ? { explicit: command.workdir } : {});
120
+ const workspace = resolveInitWorkspace(command.workdir ? { explicit: command.workdir } : {});
122
121
  const result = await initializeWorkspace(workspace);
123
122
  heading('Workspace ready');
124
123
  console.log(` Path ${workspace.root}`);
125
- console.log(` Profiles ${workspace.configFile}`);
126
- console.log(` Secrets ${workspace.envFile}`);
124
+ console.log(` Config ${workspace.configFile}`);
127
125
  console.log(` State ${workspace.statesDirectory}`);
128
126
  console.log(` Created ${result.created.length ? result.created.join(', ') : 'nothing'}`);
129
127
  console.log(` Reused ${result.existing.length ? result.existing.join(', ') : 'nothing'}`);
130
- console.log(` Next Fill profiles/secrets, then run: ywtc doctor --workdir "${workspace.root}"`);
128
+ console.log(` Next Fill connection settings and credentials, then run: ywtc doctor --workdir "${workspace.root}"`);
131
129
  return 0;
132
130
  }
133
131
  if (command.command === 'doctor') {
134
132
  const workspace = await resolveWorkspace(command.workdir ? { explicit: command.workdir } : {});
135
- await validateWorkspaceMarker(workspace);
136
- const config = readWorkspaceConfig(workspace.envFile, workspace.configFile);
133
+ if (!await workspaceIsInitialized(workspace)) {
134
+ throw new Error(`Workspace is not initialized: ${workspace.configFile}. Run: ywtc init --workdir ${JSON.stringify(workspace.root)}.`);
135
+ }
136
+ const config = readWorkspaceConfig(workspace.configFile);
137
137
  heading('Workspace diagnosis');
138
138
  console.log(` Workdir ${paint(32, workspace.root)}`);
139
139
  console.log(` Profiles ${Object.values(config.profiles).map((profile) => `${profile.name}:${profile.type}`).join(', ')}`);