confluence-exporter 1.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.
Files changed (91) hide show
  1. package/.eslintrc.cjs +18 -0
  2. package/.github/copilot-instructions.md +3 -0
  3. package/.github/prompts/analyze.prompt.md +101 -0
  4. package/.github/prompts/clarify.prompt.md +158 -0
  5. package/.github/prompts/constitution.prompt.md +73 -0
  6. package/.github/prompts/implement.prompt.md +56 -0
  7. package/.github/prompts/plan.prompt.md +50 -0
  8. package/.github/prompts/specify.prompt.md +21 -0
  9. package/.github/prompts/tasks.prompt.md +69 -0
  10. package/LICENSE +21 -0
  11. package/README.md +332 -0
  12. package/agents.md +1174 -0
  13. package/dist/api.d.ts +73 -0
  14. package/dist/api.js +387 -0
  15. package/dist/api.js.map +1 -0
  16. package/dist/commands/download.command.d.ts +18 -0
  17. package/dist/commands/download.command.js +257 -0
  18. package/dist/commands/download.command.js.map +1 -0
  19. package/dist/commands/executor.d.ts +22 -0
  20. package/dist/commands/executor.js +52 -0
  21. package/dist/commands/executor.js.map +1 -0
  22. package/dist/commands/help.command.d.ts +8 -0
  23. package/dist/commands/help.command.js +68 -0
  24. package/dist/commands/help.command.js.map +1 -0
  25. package/dist/commands/index.command.d.ts +14 -0
  26. package/dist/commands/index.command.js +95 -0
  27. package/dist/commands/index.command.js.map +1 -0
  28. package/dist/commands/index.d.ts +13 -0
  29. package/dist/commands/index.js +13 -0
  30. package/dist/commands/index.js.map +1 -0
  31. package/dist/commands/plan.command.d.ts +54 -0
  32. package/dist/commands/plan.command.js +272 -0
  33. package/dist/commands/plan.command.js.map +1 -0
  34. package/dist/commands/registry.d.ts +12 -0
  35. package/dist/commands/registry.js +32 -0
  36. package/dist/commands/registry.js.map +1 -0
  37. package/dist/commands/transform.command.d.ts +69 -0
  38. package/dist/commands/transform.command.js +951 -0
  39. package/dist/commands/transform.command.js.map +1 -0
  40. package/dist/commands/types.d.ts +12 -0
  41. package/dist/commands/types.js +5 -0
  42. package/dist/commands/types.js.map +1 -0
  43. package/dist/commands/update.command.d.ts +10 -0
  44. package/dist/commands/update.command.js +201 -0
  45. package/dist/commands/update.command.js.map +1 -0
  46. package/dist/constants.d.ts +1 -0
  47. package/dist/constants.js +2 -0
  48. package/dist/constants.js.map +1 -0
  49. package/dist/index.d.ts +5 -0
  50. package/dist/index.js +110 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/logger.d.ts +15 -0
  53. package/dist/logger.js +52 -0
  54. package/dist/logger.js.map +1 -0
  55. package/dist/types.d.ts +167 -0
  56. package/dist/types.js +5 -0
  57. package/dist/types.js.map +1 -0
  58. package/dist/utils.d.ts +56 -0
  59. package/dist/utils.js +178 -0
  60. package/dist/utils.js.map +1 -0
  61. package/eslint.config.js +29 -0
  62. package/jest.config.cjs +25 -0
  63. package/migrate-meta.js +132 -0
  64. package/package.json +53 -0
  65. package/src/api.ts +469 -0
  66. package/src/commands/download.command.ts +324 -0
  67. package/src/commands/executor.ts +62 -0
  68. package/src/commands/help.command.ts +72 -0
  69. package/src/commands/index.command.ts +111 -0
  70. package/src/commands/index.ts +14 -0
  71. package/src/commands/plan.command.ts +318 -0
  72. package/src/commands/registry.ts +39 -0
  73. package/src/commands/transform.command.ts +1103 -0
  74. package/src/commands/types.ts +16 -0
  75. package/src/commands/update.command.ts +229 -0
  76. package/src/constants.ts +0 -0
  77. package/src/index.ts +120 -0
  78. package/src/logger.ts +60 -0
  79. package/src/test.sh +66 -0
  80. package/src/types.ts +176 -0
  81. package/src/utils.ts +204 -0
  82. package/tests/commands/README.md +123 -0
  83. package/tests/commands/download.command.test.ts +8 -0
  84. package/tests/commands/help.command.test.ts +8 -0
  85. package/tests/commands/index.command.test.ts +8 -0
  86. package/tests/commands/plan.command.test.ts +15 -0
  87. package/tests/commands/transform.command.test.ts +8 -0
  88. package/tests/fixtures/_index.yaml +38 -0
  89. package/tests/fixtures/mock-pages.ts +62 -0
  90. package/tsconfig.json +25 -0
  91. package/vite.config.ts +45 -0
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Plan command handler - Creates _queue.yaml for download
3
+ */
4
+ import * as fs from 'fs';
5
+ import path from 'path';
6
+ import yaml from 'yaml';
7
+ import { checkPageStatus } from '../utils.js';
8
+ export class PlanCommand {
9
+ config;
10
+ queuePath;
11
+ treePath;
12
+ tree;
13
+ constructor(config) {
14
+ this.config = config;
15
+ this.queuePath = path.join(this.config.outputDir, '_queue.yaml');
16
+ this.treePath = path.join(this.config.outputDir, '_tree.yaml');
17
+ this.tree = [];
18
+ }
19
+ async execute(context) {
20
+ // Create output directory if it doesn't exist
21
+ fs.mkdirSync(this.config.outputDir, { recursive: true });
22
+ // Check for --force flag
23
+ const forceMode = this.config.force === true;
24
+ if (forceMode) {
25
+ console.log('\n⚠️ Force mode enabled - all pages will be queued regardless of status\n');
26
+ }
27
+ // Step 1: Build complete tree structure (no limits applied here)
28
+ this.tree = this.buildTreeFromIndex();
29
+ if (this.config.pageId) {
30
+ // Build tree from specific page and all children
31
+ console.log(`Building tree from specific page: ${this.config.pageId}`);
32
+ this.tree = [this.collectPageTree(this.config.pageId)];
33
+ }
34
+ // Step 2: Create queue from tree with smart filtering
35
+ console.log(`\nCreating download queue from tree...`);
36
+ try {
37
+ const allPages = this.flattenTreeArray(this.tree);
38
+ console.log(`Flattened tree to ${allPages.length} pages`);
39
+ // Apply smart filtering (check if pages need downloading)
40
+ const { pagesToQueue, stats } = this.filterPagesForQueue(allPages, forceMode);
41
+ // Apply limit if specified (only affects queue, not tree)
42
+ const finalQueue = this.config.limit ? pagesToQueue.slice(0, this.config.limit) : pagesToQueue;
43
+ if (this.config.limit && pagesToQueue.length > this.config.limit) {
44
+ console.log(`Limiting queue to first ${this.config.limit} pages`);
45
+ }
46
+ this.writeQueue(this.queuePath, this.config, finalQueue);
47
+ console.log(`\n✓ Queue created: ${this.queuePath}`);
48
+ console.log(` 📊 Statistics:`);
49
+ console.log(` New pages: ${stats.new}`);
50
+ console.log(` Updated pages: ${stats.updated}`);
51
+ console.log(` Skipped: ${stats.skipped} (up-to-date)`);
52
+ console.log(` Total queued: ${finalQueue.length}`);
53
+ console.log(` Total in tree: ${allPages.length}`);
54
+ }
55
+ catch (error) {
56
+ throw new Error(`Failed to create queue from tree: ${error instanceof Error ? error.message : error}`);
57
+ }
58
+ }
59
+ /**
60
+ * Recursively collect a page and all its descendants
61
+ */
62
+ collectPageTree(pageId, depth = 0) {
63
+ const indent = ' '.repeat(depth);
64
+ // Find the page in the tree
65
+ const node = this.findNodeInTree(this.tree, pageId);
66
+ if (!node) {
67
+ throw new Error(`Page ${pageId} not found in tree`);
68
+ }
69
+ console.log(`${indent}Found page: ${node.title} (${node.id})`);
70
+ return node;
71
+ }
72
+ /**
73
+ * Find a node by ID in the tree structure
74
+ */
75
+ findNodeInTree(nodes, pageId) {
76
+ for (const node of nodes) {
77
+ if (node.id === pageId) {
78
+ return node;
79
+ }
80
+ if (node.children && node.children.length > 0) {
81
+ const found = this.findNodeInTree(node.children, pageId);
82
+ if (found) {
83
+ return found;
84
+ }
85
+ }
86
+ }
87
+ return null;
88
+ }
89
+ /**
90
+ * Flatten tree structure to array of PageIndexEntry
91
+ */
92
+ flattenTree(node, result = []) {
93
+ result.push({
94
+ id: node.id,
95
+ title: node.title,
96
+ version: node.version,
97
+ parentId: node.parentId,
98
+ modifiedDate: node.modifiedDate,
99
+ indexedDate: new Date().toISOString(),
100
+ pageNumber: 0
101
+ });
102
+ if (node.children) {
103
+ for (const child of node.children) {
104
+ this.flattenTree(child, result);
105
+ }
106
+ }
107
+ return result;
108
+ }
109
+ /**
110
+ * Flatten array of tree nodes to array of PageIndexEntry
111
+ */
112
+ flattenTreeArray(trees) {
113
+ const result = [];
114
+ for (const tree of trees) {
115
+ this.flattenTree(tree, result);
116
+ }
117
+ return result;
118
+ }
119
+ /**
120
+ * Filter pages based on whether they need to be downloaded
121
+ * Checks for existing files and compares versions/dates
122
+ *
123
+ * @param pages - All pages from the tree
124
+ * @param forceMode - If true, skip all checks and include all pages
125
+ * @returns Filtered pages with queueReason and statistics
126
+ */
127
+ filterPagesForQueue(pages, forceMode) {
128
+ const pagesToQueue = [];
129
+ const stats = { new: 0, updated: 0, skipped: 0 };
130
+ console.log('\n📋 Checking page status...');
131
+ // Force mode: include all pages without checking
132
+ if (forceMode) {
133
+ for (const page of pages) {
134
+ pagesToQueue.push({ ...page, queueReason: 'new' });
135
+ stats.new++;
136
+ }
137
+ return { pagesToQueue, stats };
138
+ }
139
+ // Read index once for all lookups
140
+ const indexPath = path.join(this.config.outputDir, '_index.yaml');
141
+ const indexEntries = this.loadIndexEntries(indexPath);
142
+ const indexMap = new Map(indexEntries.map(entry => [entry.id, entry]));
143
+ console.log(`Loaded ${indexEntries.length} entries from index for status checking`);
144
+ // Process pages in batches of 100 for better performance
145
+ const batchSize = 100;
146
+ for (let i = 0; i < pages.length; i += batchSize) {
147
+ const batch = pages.slice(i, i + batchSize);
148
+ console.log(`Processing batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(pages.length / batchSize)} (${batch.length} pages)`);
149
+ for (const page of batch) {
150
+ // Check if page has been downloaded by looking at index entry
151
+ const existingEntry = indexMap.get(page.id);
152
+ if (!existingEntry || !existingEntry.downloadedVersion) {
153
+ // Page not downloaded yet
154
+ console.log(` [NEW] ${page.title} (${page.id})`);
155
+ pagesToQueue.push({ ...page, queueReason: 'new' });
156
+ stats.new++;
157
+ continue;
158
+ }
159
+ // Check if page needs update
160
+ const status = checkPageStatus(existingEntry);
161
+ if (status.needsDownload) {
162
+ const details = status.details ? ` - ${status.details}` : '';
163
+ console.log(` [UPDATE] ${page.title} (${page.id})${details}`);
164
+ pagesToQueue.push({ ...page, queueReason: 'updated' });
165
+ stats.updated++;
166
+ }
167
+ else {
168
+ console.log(` [SKIP] ${page.title} (${page.id}) - up to date (v${existingEntry.downloadedVersion})`);
169
+ stats.skipped++;
170
+ }
171
+ }
172
+ }
173
+ return { pagesToQueue, stats };
174
+ }
175
+ /**
176
+ * Load all index entries from _index.yaml file
177
+ */
178
+ loadIndexEntries(indexPath) {
179
+ if (!fs.existsSync(indexPath))
180
+ return [];
181
+ try {
182
+ const content = fs.readFileSync(indexPath, 'utf-8');
183
+ return yaml.parse(content);
184
+ }
185
+ catch (error) {
186
+ console.warn(`Warning: Failed to load index file ${indexPath}: ${error}`);
187
+ return [];
188
+ }
189
+ }
190
+ /**
191
+ * Build tree structure from flat index
192
+ */
193
+ buildTreeFromIndex() {
194
+ const indexPath = path.join(this.config.outputDir, '_index.yaml');
195
+ const yamlContent = fs.readFileSync(indexPath, 'utf-8');
196
+ const pages = yaml.parse(yamlContent);
197
+ console.log(`Read ${pages.length} pages from _index.yaml`);
198
+ const nodeMap = new Map();
199
+ const roots = [];
200
+ // First pass: create all nodes
201
+ for (const page of pages) {
202
+ nodeMap.set(page.id, {
203
+ id: page.id,
204
+ title: page.title,
205
+ version: page.version,
206
+ parentId: page.parentId,
207
+ modifiedDate: page.modifiedDate,
208
+ children: []
209
+ });
210
+ }
211
+ // Second pass: build tree structure
212
+ for (const page of pages) {
213
+ const node = nodeMap.get(page.id);
214
+ if (!node)
215
+ continue;
216
+ if (page.parentId && nodeMap.has(page.parentId)) {
217
+ // Add as child to parent
218
+ const parent = nodeMap.get(page.parentId);
219
+ if (parent?.children) {
220
+ parent.children.push(node);
221
+ }
222
+ }
223
+ else {
224
+ // No parent or parent not in index - it's a root
225
+ roots.push(node);
226
+ }
227
+ }
228
+ this.writeTree(roots);
229
+ console.log(`✓ Complete tree structure saved: ${this.treePath}`);
230
+ return roots;
231
+ }
232
+ /**
233
+ * Write _tree.yaml file with hierarchical structure
234
+ */
235
+ writeTree(tree) {
236
+ const header = `# Confluence Page Tree
237
+ # Space: ${this.config.spaceKey}
238
+ # Created: ${new Date().toISOString()}
239
+
240
+ `;
241
+ const yamlContent = yaml.stringify(tree, {
242
+ indent: 2,
243
+ lineWidth: 0 // No line wrapping
244
+ });
245
+ fs.writeFileSync(this.treePath, header + yamlContent, 'utf-8');
246
+ }
247
+ /**
248
+ * Write _queue.yaml file
249
+ */
250
+ writeQueue(queuePath, config, pages) {
251
+ const header = `# Confluence Download Queue
252
+ # Space: ${config.spaceKey}
253
+ # Created: ${new Date().toISOString()}
254
+ # Total Pages: ${pages.length}
255
+
256
+ `;
257
+ fs.writeFileSync(queuePath, header, 'utf-8');
258
+ // Write each page as YAML array entry
259
+ for (const page of pages) {
260
+ const yamlDoc = yaml.stringify(page).trim();
261
+ const lines = yamlDoc.split('\n');
262
+ const arrayItem = lines.map((line, index) => {
263
+ if (index === 0) {
264
+ return `- ${line}`;
265
+ }
266
+ return ` ${line}`;
267
+ }).join('\n');
268
+ fs.appendFileSync(queuePath, arrayItem + '\n', 'utf-8');
269
+ }
270
+ }
271
+ }
272
+ //# sourceMappingURL=plan.command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.command.js","sourceRoot":"","sources":["../../src/commands/plan.command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Command registry - maps command names to handlers
3
+ */
4
+ import type { Command, CommandHandler } from './types.js';
5
+ import { ConfluenceConfig } from 'src/types.js';
6
+ export declare class CommandRegistry {
7
+ private handlers;
8
+ constructor(config?: ConfluenceConfig);
9
+ getHandler(command: Command): CommandHandler | undefined;
10
+ isValidCommand(command: string): command is Command;
11
+ getValidCommands(): Command[];
12
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Command registry - maps command names to handlers
3
+ */
4
+ import { HelpCommand } from './help.command.js';
5
+ import { IndexCommand } from './index.command.js';
6
+ import { UpdateCommand } from './update.command.js';
7
+ import { PlanCommand } from './plan.command.js';
8
+ import { DownloadCommand } from './download.command.js';
9
+ import { TransformCommand } from './transform.command.js';
10
+ export class CommandRegistry {
11
+ handlers;
12
+ constructor(config) {
13
+ this.handlers = new Map([
14
+ ['help', new HelpCommand()],
15
+ ['index', new IndexCommand(config)],
16
+ ['update', new UpdateCommand(config)],
17
+ ['plan', new PlanCommand(config)],
18
+ ['download', new DownloadCommand(config)],
19
+ ['transform', new TransformCommand(config)]
20
+ ]);
21
+ }
22
+ getHandler(command) {
23
+ return this.handlers.get(command);
24
+ }
25
+ isValidCommand(command) {
26
+ return this.handlers.has(command);
27
+ }
28
+ getValidCommands() {
29
+ return Array.from(this.handlers.keys());
30
+ }
31
+ }
32
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/commands/registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAI1D,MAAM,OAAO,eAAe;IAClB,QAAQ,CAA+B;IAE/C,YAAY,MAAyB;QACnC,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,CAA0B;YAC/C,CAAC,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;YAC3B,CAAC,OAAO,EAAE,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;YACnC,CAAC,QAAQ,EAAE,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;YACrC,CAAC,MAAM,EAAE,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;YACjC,CAAC,UAAU,EAAE,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;YACzC,CAAC,WAAW,EAAE,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,UAAU,CAAC,OAAgB;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,cAAc,CAAC,OAAe;QAC5B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAkB,CAAC,CAAC;IAC/C,CAAC;IAED,gBAAgB;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;CACF"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Transform command handler - Transforms HTML files to Markdown
3
+ */
4
+ import type { CommandContext, CommandHandler } from './types.js';
5
+ import type { ConfluenceConfig } from '../types.js';
6
+ export declare class TransformCommand implements CommandHandler {
7
+ private config;
8
+ private pendingIncludes;
9
+ private api;
10
+ constructor(config: ConfluenceConfig);
11
+ execute(_context: CommandContext): Promise<void>;
12
+ /**
13
+ * Process a single HTML file to Markdown
14
+ */
15
+ private processFile;
16
+ /**
17
+ * Basic HTML to Markdown conversion
18
+ */
19
+ private htmlToMarkdown;
20
+ /**
21
+ * Transform images and download attachments
22
+ */
23
+ private transformImages;
24
+ /**
25
+ * Build a Markdown list from an included page's HTML content.
26
+ * Prefer extracting <ul>/<ol> list items and anchor links; fall back to full page transform.
27
+ */
28
+ private buildIncludeList;
29
+ /**
30
+ * Transform Confluence macros to Markdown
31
+ */
32
+ private transformMacros;
33
+ /**
34
+ * Transform user links to display names
35
+ */
36
+ private transformUserLinks;
37
+ /**
38
+ * Transform page links to markdown links
39
+ */
40
+ private transformPageLinks;
41
+ /**
42
+ * Clean up malformed markdown patterns
43
+ */
44
+ private cleanMarkdown;
45
+ /**
46
+ * Clean up specific problematic patterns that appear in Confluence exports
47
+ */
48
+ private cleanConfluencePatterns;
49
+ /**
50
+ * General markdown cleanup
51
+ */
52
+ private cleanGeneral;
53
+ /**
54
+ * Create links folder with symlinks and _links.md with tree structure
55
+ */
56
+ private createLinksStructure;
57
+ /**
58
+ * Build a tree structure from flat file list
59
+ */
60
+ private buildFileTree;
61
+ /**
62
+ * Generate markdown tree structure
63
+ */
64
+ private generateTreeMarkdown;
65
+ /**
66
+ * Recursively clear existing .md files and images folders
67
+ */
68
+ private clearExistingFiles;
69
+ }