create-confluence-sync 1.0.2 → 1.0.3
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/package.json +1 -1
- package/src/agents-md.js +107 -155
package/package.json
CHANGED
package/src/agents-md.js
CHANGED
|
@@ -1,168 +1,97 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Build a tree structure from flat pages map.
|
|
6
|
-
* Returns array of root nodes, each with nested `children`.
|
|
7
|
-
*/
|
|
8
|
-
function buildPageTree(pages) {
|
|
9
|
-
const nodes = {};
|
|
10
|
-
const roots = [];
|
|
11
|
-
|
|
12
|
-
for (const [id, page] of Object.entries(pages)) {
|
|
13
|
-
nodes[id] = { id, ...page, children: [] };
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
for (const [id, node] of Object.entries(nodes)) {
|
|
17
|
-
if (node.parentId && nodes[node.parentId]) {
|
|
18
|
-
nodes[node.parentId].children.push(node);
|
|
19
|
-
} else {
|
|
20
|
-
roots.push(node);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Sort children alphabetically by title at each level
|
|
25
|
-
const sortChildren = (nodeList) => {
|
|
26
|
-
nodeList.sort((a, b) => a.title.localeCompare(b.title));
|
|
27
|
-
for (const node of nodeList) {
|
|
28
|
-
sortChildren(node.children);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
sortChildren(roots);
|
|
32
|
-
|
|
33
|
-
return roots;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Render a tree of pages as an indented directory listing.
|
|
38
|
-
* Only visible (non-hidden) pages are shown.
|
|
39
|
-
*/
|
|
40
|
-
function renderTree(roots, space, indent = '') {
|
|
41
|
-
const lines = [];
|
|
42
|
-
|
|
43
|
-
for (let i = 0; i < roots.length; i++) {
|
|
44
|
-
const node = roots[i];
|
|
45
|
-
if (node.hidden) continue;
|
|
46
|
-
|
|
47
|
-
const isLast = i === roots.length - 1;
|
|
48
|
-
const connector = isLast ? '\u2514\u2500\u2500 ' : '\u251c\u2500\u2500 ';
|
|
49
|
-
const childIndent = indent + (isLast ? ' ' : '\u2502 ');
|
|
50
|
-
|
|
51
|
-
lines.push(`${indent}${connector}${node.title}/`);
|
|
52
|
-
lines.push(`${childIndent}\u251c\u2500\u2500 ${node.title}.xhtml`);
|
|
53
|
-
|
|
54
|
-
const visibleChildren = node.children.filter((c) => !c.hidden);
|
|
55
|
-
const childLines = renderTree(visibleChildren, space, childIndent);
|
|
56
|
-
if (childLines.length > 0) {
|
|
57
|
-
lines.push(...childLines);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return lines;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Generate the full AGENTS.md content.
|
|
66
|
-
*/
|
|
67
4
|
function buildContent(config, tree) {
|
|
68
5
|
const space = tree.space || config.space || 'SPACE';
|
|
69
6
|
const baseUrl = tree.baseUrl || config.baseUrl || config.url || '';
|
|
70
7
|
const lastSync = tree.lastSync || 'never';
|
|
71
8
|
|
|
72
|
-
const roots = buildPageTree(tree.pages || {});
|
|
73
|
-
const visibleRoots = roots.filter((r) => !r.hidden);
|
|
74
|
-
const treeLines = renderTree(visibleRoots, space);
|
|
75
|
-
const treeBlock =
|
|
76
|
-
treeLines.length > 0
|
|
77
|
-
? `docs/${space}/\n${treeLines.join('\n')}`
|
|
78
|
-
: `docs/${space}/ (empty)`;
|
|
79
|
-
|
|
80
9
|
return `# AGENTS.md
|
|
81
10
|
|
|
82
|
-
>
|
|
83
|
-
>
|
|
11
|
+
> Автоматически сгенерировано confluence-sync. Не редактировать вручную.
|
|
12
|
+
> Пересоздаётся при каждой синхронизации.
|
|
84
13
|
|
|
85
|
-
##
|
|
14
|
+
## Что это за проект
|
|
86
15
|
|
|
87
|
-
|
|
88
|
-
|
|
16
|
+
Этот репозиторий — **двусторонняя синхронизация документации** между локальной файловой системой и **Confluence**.
|
|
17
|
+
Вся работа происходит через файлы и git-коммиты — прямые вызовы Confluence API не нужны.
|
|
89
18
|
|
|
90
|
-
|
|
|
91
|
-
|
|
19
|
+
| Параметр | Значение |
|
|
20
|
+
|----------|----------|
|
|
92
21
|
| Confluence URL | ${baseUrl} |
|
|
93
|
-
|
|
|
94
|
-
|
|
|
22
|
+
| Пространство | ${space} |
|
|
23
|
+
| Последняя синхронизация | ${lastSync} |
|
|
95
24
|
|
|
96
25
|
---
|
|
97
26
|
|
|
98
|
-
##
|
|
27
|
+
## Структура файлов
|
|
99
28
|
|
|
100
29
|
\`\`\`
|
|
101
30
|
project-root/
|
|
102
|
-
\u251c\u2500\u2500 docs/${space}/ <-
|
|
103
|
-
\u251c\u2500\u2500 .confluence/ <-
|
|
104
|
-
\u2502 \u251c\u2500\u2500 config.json <-
|
|
105
|
-
\u2502 \u2514\u2500\u2500 tree.json <-
|
|
106
|
-
\u251c\u2500\u2500 AGENTS.md <-
|
|
31
|
+
\u251c\u2500\u2500 docs/${space}/ <- зеркало пространства Confluence
|
|
32
|
+
\u251c\u2500\u2500 .confluence/ <- внутренние данные, НЕ ТРОГАТЬ
|
|
33
|
+
\u2502 \u251c\u2500\u2500 config.json <- конфигурация подключения (в .gitignore)
|
|
34
|
+
\u2502 \u2514\u2500\u2500 tree.json <- карта структуры (ID страниц, версии, скрытые флаги)
|
|
35
|
+
\u251c\u2500\u2500 AGENTS.md <- этот файл
|
|
107
36
|
\u2514\u2500\u2500 .gitignore
|
|
108
37
|
\`\`\`
|
|
109
38
|
|
|
110
39
|
### docs/${space}/
|
|
111
40
|
|
|
112
|
-
|
|
41
|
+
Эта папка зеркалирует иерархию пространства Confluence:
|
|
113
42
|
|
|
114
|
-
-
|
|
115
|
-
-
|
|
116
|
-
-
|
|
43
|
+
- **Папка** = страница Confluence
|
|
44
|
+
- **Вложенность** = отношение parent-child
|
|
45
|
+
- **Файл \`{название}.xhtml\`** внутри папки = контент страницы
|
|
117
46
|
|
|
118
47
|
### .confluence/
|
|
119
48
|
|
|
120
|
-
|
|
49
|
+
Внутренние данные синхронизации. **Никогда не редактировать вручную.**
|
|
121
50
|
|
|
122
|
-
- \`tree.json\` —
|
|
123
|
-
- \`config.json\` —
|
|
51
|
+
- \`tree.json\` — карта всех страниц: ID, версии, пути, скрытые флаги
|
|
52
|
+
- \`config.json\` — учётные данные подключения (исключён из git)
|
|
124
53
|
|
|
125
54
|
---
|
|
126
55
|
|
|
127
|
-
##
|
|
56
|
+
## Формат файлов
|
|
128
57
|
|
|
129
|
-
|
|
58
|
+
Страницы хранятся в **Confluence Storage Format** (XHTML с Confluence-специфичными тегами).
|
|
130
59
|
|
|
131
|
-
###
|
|
60
|
+
### Базовая разметка
|
|
132
61
|
|
|
133
62
|
\`\`\`xhtml
|
|
134
|
-
<h2
|
|
135
|
-
<p
|
|
63
|
+
<h2>Заголовок</h2>
|
|
64
|
+
<p>Текст с <strong>жирным</strong> и <em>курсивом</em>.</p>
|
|
136
65
|
|
|
137
66
|
<ul>
|
|
138
|
-
<li
|
|
139
|
-
<li
|
|
67
|
+
<li>Пункт 1</li>
|
|
68
|
+
<li>Пункт 2</li>
|
|
140
69
|
</ul>
|
|
141
70
|
|
|
142
71
|
<ol>
|
|
143
|
-
<li
|
|
144
|
-
<li
|
|
72
|
+
<li>Первый</li>
|
|
73
|
+
<li>Второй</li>
|
|
145
74
|
</ol>
|
|
146
75
|
\`\`\`
|
|
147
76
|
|
|
148
|
-
###
|
|
77
|
+
### Таблицы
|
|
149
78
|
|
|
150
79
|
\`\`\`xhtml
|
|
151
80
|
<table>
|
|
152
81
|
<tbody>
|
|
153
82
|
<tr>
|
|
154
|
-
<th
|
|
155
|
-
<th
|
|
83
|
+
<th>Колонка A</th>
|
|
84
|
+
<th>Колонка B</th>
|
|
156
85
|
</tr>
|
|
157
86
|
<tr>
|
|
158
|
-
<td
|
|
159
|
-
<td
|
|
87
|
+
<td>Значение 1</td>
|
|
88
|
+
<td>Значение 2</td>
|
|
160
89
|
</tr>
|
|
161
90
|
</tbody>
|
|
162
91
|
</table>
|
|
163
92
|
\`\`\`
|
|
164
93
|
|
|
165
|
-
###
|
|
94
|
+
### Блоки кода (макрос Confluence)
|
|
166
95
|
|
|
167
96
|
\`\`\`xhtml
|
|
168
97
|
<ac:structured-macro ac:name="code">
|
|
@@ -175,86 +104,109 @@ Pages are stored in **Confluence Storage Format** (XHTML with Confluence-specifi
|
|
|
175
104
|
</ac:structured-macro>
|
|
176
105
|
\`\`\`
|
|
177
106
|
|
|
178
|
-
###
|
|
107
|
+
### Информационные панели
|
|
179
108
|
|
|
180
109
|
\`\`\`xhtml
|
|
181
110
|
<ac:structured-macro ac:name="info">
|
|
182
111
|
<ac:rich-text-body>
|
|
183
|
-
<p
|
|
112
|
+
<p>Это информационная заметка.</p>
|
|
184
113
|
</ac:rich-text-body>
|
|
185
114
|
</ac:structured-macro>
|
|
186
115
|
\`\`\`
|
|
187
116
|
|
|
188
117
|
---
|
|
189
118
|
|
|
190
|
-
##
|
|
119
|
+
## Правила
|
|
191
120
|
|
|
192
|
-
###
|
|
121
|
+
### ОБЯЗАТЕЛЬНО
|
|
193
122
|
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
-
|
|
197
|
-
-
|
|
123
|
+
- Работать **только через файлы и git** — редактировать \`.xhtml\` файлы, затем \`git commit\`
|
|
124
|
+
- Создавать/редактировать \`.xhtml\` файлы в правильной папке внутри \`docs/${space}/\`
|
|
125
|
+
- Коммитить изменения — синхронизация автоматическая (post-commit hook)
|
|
126
|
+
- Соблюдать валидный XHTML формат (Confluence Storage Format)
|
|
127
|
+
- Можно создать голый \`.xhtml\` файл без папки — sync автоматически обернёт его в одноимённую папку
|
|
198
128
|
|
|
199
|
-
###
|
|
129
|
+
### ЗАПРЕЩЕНО
|
|
200
130
|
|
|
201
|
-
-
|
|
202
|
-
-
|
|
203
|
-
-
|
|
204
|
-
-
|
|
205
|
-
-
|
|
131
|
+
- **НЕ ТРОГАТЬ** папку \`.confluence/\` и любые файлы внутри неё
|
|
132
|
+
- **НЕ ВЫЗЫВАТЬ** Confluence API напрямую
|
|
133
|
+
- **НЕ ОБХОДИТЬ** sync flow
|
|
134
|
+
- **НЕ ИЗМЕНЯТЬ** git hooks (\`.git/hooks/\`)
|
|
135
|
+
- **НЕ КОММИТИТЬ** \`.confluence/config.json\` (содержит учётные данные)
|
|
206
136
|
|
|
207
137
|
---
|
|
208
138
|
|
|
209
|
-
##
|
|
139
|
+
## CLI команды
|
|
140
|
+
|
|
141
|
+
\`\`\`bash
|
|
142
|
+
npx create-confluence-sync sync # ручная синхронизация
|
|
143
|
+
npx create-confluence-sync sync <file> # push конкретного файла
|
|
144
|
+
npx create-confluence-sync restore # восстановить скрытые страницы (интерактивно)
|
|
145
|
+
npx create-confluence-sync restore "Название" # восстановить по имени
|
|
146
|
+
npx create-confluence-sync spaces # список пространств
|
|
147
|
+
npx create-confluence-sync page <id> # содержимое страницы
|
|
148
|
+
npx create-confluence-sync tree # remote дерево
|
|
149
|
+
npx create-confluence-sync local-tree # локальный tree.json
|
|
150
|
+
npx create-confluence-sync delete <id> # удалить страницу
|
|
151
|
+
\`\`\`
|
|
210
152
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Как найти нужную страницу
|
|
156
|
+
|
|
157
|
+
- **По файловой системе**: просмотреть \`docs/${space}/\` — структура папок = структура Confluence
|
|
158
|
+
- **По tree.json**: выполнить \`npx create-confluence-sync local-tree\` — вывод JSON со всеми страницами, их ID, путями и статусами
|
|
159
|
+
- **По содержимому**: использовать grep/поиск по \`.xhtml\` файлам в \`docs/${space}/\`
|
|
160
|
+
- **По ID**: \`npx create-confluence-sync page <id>\` — получить содержимое конкретной страницы из Confluence
|
|
161
|
+
|
|
162
|
+
---
|
|
221
163
|
|
|
222
|
-
##
|
|
164
|
+
## Как создать новую страницу
|
|
223
165
|
|
|
224
|
-
1.
|
|
225
|
-
2.
|
|
226
|
-
3.
|
|
166
|
+
1. Определить родительскую папку в иерархии Confluence
|
|
167
|
+
2. Создать папку с названием страницы: \`docs/${space}/{parent}/Новая страница/\`
|
|
168
|
+
3. Создать файл с тем же именем: \`docs/${space}/{parent}/Новая страница/Новая страница.xhtml\`
|
|
169
|
+
4. Написать контент в XHTML формате (см. примеры выше)
|
|
170
|
+
5. Закоммитить:
|
|
227
171
|
\`\`\`
|
|
228
|
-
git add "docs/${space}/
|
|
229
|
-
git commit -m "
|
|
172
|
+
git add "docs/${space}/{parent}/Новая страница/"
|
|
173
|
+
git commit -m "Добавить страницу: Новая страница"
|
|
230
174
|
\`\`\`
|
|
231
|
-
|
|
175
|
+
6. Страница будет автоматически создана в Confluence
|
|
232
176
|
|
|
233
|
-
|
|
177
|
+
> Также можно просто создать файл \`Новая страница.xhtml\` без папки — sync автоматически обернёт его в папку \`Новая страница/\`.
|
|
234
178
|
|
|
235
|
-
|
|
179
|
+
## Как редактировать страницу
|
|
236
180
|
|
|
237
|
-
1.
|
|
238
|
-
2.
|
|
181
|
+
1. Найти \`.xhtml\` файл нужной страницы
|
|
182
|
+
2. Изменить контент (сохраняя валидный XHTML)
|
|
183
|
+
3. Закоммитить:
|
|
239
184
|
\`\`\`
|
|
240
|
-
git add
|
|
241
|
-
git commit -m "
|
|
185
|
+
git add "docs/${space}/путь/к/Страница.xhtml"
|
|
186
|
+
git commit -m "Обновить страницу: Страница"
|
|
242
187
|
\`\`\`
|
|
243
|
-
|
|
244
|
-
4. The page will not be pulled back on future syncs
|
|
245
|
-
5. To restore: set \`hidden: false\` for the page in \`.confluence/tree.json\` — this is the **only** allowed manual edit of \`.confluence/\` files — the page will reappear on next sync
|
|
188
|
+
4. Изменения будут автоматически отправлены в Confluence
|
|
246
189
|
|
|
247
|
-
|
|
190
|
+
## Как скрыть страницу (виртуальное удаление)
|
|
248
191
|
|
|
249
|
-
|
|
192
|
+
Скрытие убирает страницу из локального дерева без удаления из Confluence.
|
|
250
193
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
\`\`\`
|
|
194
|
+
1. Удалить папку/файл из файловой системы
|
|
195
|
+
2. Закоммитить:
|
|
196
|
+
\`\`\`
|
|
197
|
+
git add -A
|
|
198
|
+
git commit -m "Скрыть страницу: Название"
|
|
199
|
+
\`\`\`
|
|
200
|
+
3. Файл исчезнет локально, но страница в Confluence останется нетронутой
|
|
201
|
+
4. Страница не будет скачиваться при будущих синхронизациях
|
|
202
|
+
5. Для восстановления использовать команду:
|
|
203
|
+
\`\`\`
|
|
204
|
+
npx create-confluence-sync restore
|
|
205
|
+
\`\`\`
|
|
254
206
|
|
|
255
207
|
---
|
|
256
208
|
|
|
257
|
-
|
|
209
|
+
*Сгенерировано confluence-sync*
|
|
258
210
|
`;
|
|
259
211
|
}
|
|
260
212
|
|