@reqlan/analytical 0.6.3 → 0.8.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.
Files changed (90) hide show
  1. package/README.md +30 -0
  2. package/out/analysis/fuzzy-search-analyser.d.ts +17 -0
  3. package/out/analysis/fuzzy-search-analyser.js +25 -0
  4. package/out/analysis/fuzzy-search-analyser.js.map +1 -0
  5. package/out/analysis/fuzzy-search-worker-client.d.ts +39 -0
  6. package/out/analysis/fuzzy-search-worker-client.js +178 -0
  7. package/out/analysis/fuzzy-search-worker-client.js.map +1 -0
  8. package/out/analysis/fuzzy-search-worker.d.ts +32 -0
  9. package/out/analysis/fuzzy-search-worker.js +81 -0
  10. package/out/analysis/fuzzy-search-worker.js.map +1 -0
  11. package/out/analysis/fuzzy-search.d.ts +38 -0
  12. package/out/analysis/fuzzy-search.js +217 -0
  13. package/out/analysis/fuzzy-search.js.map +1 -0
  14. package/out/analysis/git-dates-analyser.js +12 -3
  15. package/out/analysis/git-dates-analyser.js.map +1 -1
  16. package/out/analysis-api.d.ts +16 -2
  17. package/out/analysis-api.js +36 -3
  18. package/out/analysis-api.js.map +1 -1
  19. package/out/core/barrel-page.d.ts +46 -0
  20. package/out/core/barrel-page.js +162 -0
  21. package/out/core/barrel-page.js.map +1 -0
  22. package/out/core/filter-specials.d.ts +37 -0
  23. package/out/core/filter-specials.js +113 -0
  24. package/out/core/filter-specials.js.map +1 -0
  25. package/out/core/types.d.ts +27 -1
  26. package/out/core/types.js +1 -0
  27. package/out/core/types.js.map +1 -1
  28. package/out/create-runtime.js +2 -0
  29. package/out/create-runtime.js.map +1 -1
  30. package/out/export/build-export-snapshot.d.ts +2 -2
  31. package/out/export/build-export-snapshot.js +43 -16
  32. package/out/export/build-export-snapshot.js.map +1 -1
  33. package/out/export/export-csv.d.ts +4 -0
  34. package/out/export/export-csv.js +13 -0
  35. package/out/export/export-csv.js.map +1 -0
  36. package/out/export/export-html.d.ts +2 -2
  37. package/out/export/export-html.js +7 -3
  38. package/out/export/export-html.js.map +1 -1
  39. package/out/export/export-json.d.ts +6 -0
  40. package/out/export/export-json.js +28 -0
  41. package/out/export/export-json.js.map +1 -0
  42. package/out/export/export-markdown.d.ts +4 -0
  43. package/out/export/export-markdown.js +23 -0
  44. package/out/export/export-markdown.js.map +1 -0
  45. package/out/export/html-export-assets.d.ts +1 -1
  46. package/out/export/html-export-assets.js +663 -20
  47. package/out/export/html-export-assets.js.map +1 -1
  48. package/out/export/html-export-template.js +160 -61
  49. package/out/export/html-export-template.js.map +1 -1
  50. package/out/export/html-export-utils.d.ts +33 -3
  51. package/out/export/html-export-utils.js +121 -13
  52. package/out/export/html-export-utils.js.map +1 -1
  53. package/out/export/types.d.ts +20 -1
  54. package/out/export/write-csv-export.d.ts +5 -0
  55. package/out/export/write-csv-export.js +132 -0
  56. package/out/export/write-csv-export.js.map +1 -0
  57. package/out/export/write-html-export.d.ts +2 -2
  58. package/out/export/write-html-export.js +61 -29
  59. package/out/export/write-html-export.js.map +1 -1
  60. package/out/export/write-json-export.d.ts +3 -0
  61. package/out/export/write-json-export.js +92 -0
  62. package/out/export/write-json-export.js.map +1 -0
  63. package/out/export/write-markdown-export.d.ts +5 -0
  64. package/out/export/write-markdown-export.js +177 -0
  65. package/out/export/write-markdown-export.js.map +1 -0
  66. package/out/graph/physics-core-source.d.ts +5 -0
  67. package/out/graph/physics-core-source.js +8 -0
  68. package/out/graph/physics-core-source.js.map +1 -0
  69. package/out/index-store/idea-extractor.d.ts +6 -1
  70. package/out/index-store/idea-extractor.js +56 -11
  71. package/out/index-store/idea-extractor.js.map +1 -1
  72. package/out/index-store/index-diagnostics-store.js +1 -2
  73. package/out/index-store/index-diagnostics-store.js.map +1 -1
  74. package/out/index-store/sqlite-store.d.ts +16 -3
  75. package/out/index-store/sqlite-store.js +107 -9
  76. package/out/index-store/sqlite-store.js.map +1 -1
  77. package/out/index-store/webview-graph-queries.d.ts +13 -2
  78. package/out/index-store/webview-graph-queries.js +98 -18
  79. package/out/index-store/webview-graph-queries.js.map +1 -1
  80. package/out/index-store/webview-table-queries.js +1 -0
  81. package/out/index-store/webview-table-queries.js.map +1 -1
  82. package/out/index-store/workspace-index-file.js +22 -1
  83. package/out/index-store/workspace-index-file.js.map +1 -1
  84. package/out/index-store/workspace-index.d.ts +2 -1
  85. package/out/index-store/workspace-index.js +4 -1
  86. package/out/index-store/workspace-index.js.map +1 -1
  87. package/out/index.d.ts +17 -2
  88. package/out/index.js +10 -1
  89. package/out/index.js.map +1 -1
  90. package/package.json +7 -3
@@ -0,0 +1,132 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { formatAttributeValue } from './html-export-utils.js';
4
+ /** Write CSV export(s): ideas.csv with flattened tags/attributes, plus references.csv. */
5
+ export async function writeCsvExport(snapshot, request, onProgress) {
6
+ const outputDir = join(request.outputDir, request.exportName);
7
+ await mkdir(outputDir, { recursive: true });
8
+ const ideasPath = join(outputDir, 'ideas.csv');
9
+ const referencesPath = join(outputDir, 'references.csv');
10
+ const total = 2;
11
+ let completed = 0;
12
+ onProgress?.({
13
+ phase: 'write',
14
+ message: 'Writing ideas.csv…',
15
+ completed,
16
+ total,
17
+ });
18
+ await writeFile(ideasPath, renderIdeasCsv(snapshot), 'utf8');
19
+ completed += 1;
20
+ onProgress?.({
21
+ phase: 'write',
22
+ message: 'Writing references.csv…',
23
+ completed,
24
+ total,
25
+ });
26
+ await writeFile(referencesPath, renderReferencesCsv(snapshot), 'utf8');
27
+ completed += 1;
28
+ onProgress?.({
29
+ phase: 'write',
30
+ message: `Wrote ${total} CSV files`,
31
+ completed,
32
+ total,
33
+ });
34
+ return {
35
+ outputDir,
36
+ indexFilePath: ideasPath,
37
+ printFilePath: ideasPath,
38
+ dataFilePath: referencesPath,
39
+ };
40
+ }
41
+ function renderIdeasCsv(snapshot) {
42
+ const attributeKeys = collectAttributeKeys(snapshot.ideas);
43
+ const headers = [
44
+ 'id',
45
+ 'name',
46
+ 'kind',
47
+ 'fileUri',
48
+ 'lineStart',
49
+ 'status',
50
+ 'tags',
51
+ 'summary',
52
+ ...attributeKeys.map(key => `attr:${key}`),
53
+ ];
54
+ const rows = snapshot.ideas.map(idea => {
55
+ const cells = [
56
+ idea.id,
57
+ idea.name,
58
+ idea.kind,
59
+ idea.fileUri,
60
+ String(idea.lineStart),
61
+ idea.status ?? '',
62
+ idea.tags.join(';'),
63
+ idea.summary,
64
+ ...attributeKeys.map(key => {
65
+ if (!(key in idea.attributes)) {
66
+ return '';
67
+ }
68
+ return formatAttributeValue(idea.attributes[key]);
69
+ }),
70
+ ];
71
+ return cells.map(csvEscape).join(',');
72
+ });
73
+ return `${headers.map(csvEscape).join(',')}\n${rows.join('\n')}${rows.length > 0 ? '\n' : ''}`;
74
+ }
75
+ function renderReferencesCsv(snapshot) {
76
+ const headers = [
77
+ 'sourceIdeaId',
78
+ 'sourceName',
79
+ 'direction',
80
+ 'kind',
81
+ 'label',
82
+ 'targetIdeaId',
83
+ 'targetName',
84
+ 'targetPath',
85
+ 'isResolved',
86
+ 'snippet',
87
+ ];
88
+ const rows = [];
89
+ for (const idea of snapshot.ideas) {
90
+ for (const group of [
91
+ { direction: 'outbound', rows: idea.references.outbound },
92
+ { direction: 'inbound', rows: idea.references.inbound },
93
+ { direction: 'unresolved', rows: idea.references.unresolved },
94
+ ]) {
95
+ for (const row of group.rows) {
96
+ rows.push([
97
+ idea.id,
98
+ idea.name,
99
+ group.direction,
100
+ row.kind,
101
+ row.label,
102
+ row.targetIdeaId ?? '',
103
+ row.targetName,
104
+ row.targetPath,
105
+ row.isResolved ? 'true' : 'false',
106
+ row.snippet ?? '',
107
+ ].map(csvEscape).join(','));
108
+ }
109
+ }
110
+ }
111
+ return `${headers.map(csvEscape).join(',')}\n${rows.join('\n')}${rows.length > 0 ? '\n' : ''}`;
112
+ }
113
+ function collectAttributeKeys(ideas) {
114
+ const keys = new Set();
115
+ for (const idea of ideas) {
116
+ for (const key of Object.keys(idea.attributes)) {
117
+ if (key === 'status' || key === 'tags') {
118
+ continue;
119
+ }
120
+ keys.add(key);
121
+ }
122
+ }
123
+ return [...keys].sort((a, b) => a.localeCompare(b));
124
+ }
125
+ /** RFC 4180-ish CSV cell escaping. */
126
+ export function csvEscape(value) {
127
+ if (/[",\n\r]/.test(value)) {
128
+ return `"${value.replace(/"/g, '""')}"`;
129
+ }
130
+ return value;
131
+ }
132
+ //# sourceMappingURL=write-csv-export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-csv-export.js","sourceRoot":"","sources":["../../src/export/write-csv-export.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import type { ExportRequest, ExportResult, ExportSnapshot } from './types.js';
2
- export declare function writeHtmlExport(snapshot: ExportSnapshot, request: ExportRequest): Promise<ExportResult>;
1
+ import type { ExportProgressCallback, ExportRequest, ExportResult, ExportSnapshot } from './types.js';
2
+ export declare function writeHtmlExport(snapshot: ExportSnapshot, request: ExportRequest, onProgress?: ExportProgressCallback): Promise<ExportResult>;
@@ -3,7 +3,7 @@ import { join } from 'node:path';
3
3
  import { APP_JS, SHARED_STYLES, buildSearchIndexScript } from './html-export-assets.js';
4
4
  import { renderAttributeDetailPage, renderClusterDetailPage, renderClustersIndexPage, renderCodeFileDetailPage, renderCodeFilesIndexPage, renderFileDetailPage, renderFilesIndexPage, renderGraphPage, renderHomePage, renderIdeaDetailPage, renderIdeasIndexPage, renderAttributesIndexPage, renderPrintClusterPage, renderPrintCodeFilePage, renderPrintFilePage, renderPrintHomePage, renderPrintIdeaPage } from './html-export-template.js';
5
5
  import { stringifyJson } from './html-export-utils.js';
6
- export async function writeHtmlExport(snapshot, request) {
6
+ export async function writeHtmlExport(snapshot, request, onProgress) {
7
7
  const outputDir = join(request.outputDir, request.exportName);
8
8
  const assetsDir = join(outputDir, 'assets');
9
9
  const dataDir = join(outputDir, 'data');
@@ -37,13 +37,13 @@ export async function writeHtmlExport(snapshot, request) {
37
37
  mkdir(join(outputDir, 'print/clusters'), { recursive: true })
38
38
  ]);
39
39
  const writes = [
40
- writeFile(join(assetsDir, 'styles.css'), SHARED_STYLES, 'utf8'),
41
- writeFile(join(assetsDir, 'app.js'), APP_JS, 'utf8'),
42
- writeFile(join(assetsDir, 'search-index.js'), buildSearchIndexScript(snapshot.searchDocuments), 'utf8'),
43
- writeFile(dataFilePath, stringifyJson(snapshot), 'utf8'),
44
- writeFile(join(dataDir, 'graph.json'), stringifyJson(snapshot.graphs.workspace), 'utf8'),
45
- writeFile(join(dataDir, 'search.json'), stringifyJson(snapshot.searchDocuments), 'utf8'),
46
- writeFile(manifestFilePath, stringifyJson({
40
+ () => writeFile(join(assetsDir, 'styles.css'), SHARED_STYLES, 'utf8'),
41
+ () => writeFile(join(assetsDir, 'app.js'), APP_JS, 'utf8'),
42
+ () => writeFile(join(assetsDir, 'search-index.js'), buildSearchIndexScript(snapshot.searchDocuments), 'utf8'),
43
+ () => writeFile(dataFilePath, stringifyJson(snapshot), 'utf8'),
44
+ () => writeFile(join(dataDir, 'graph.json'), stringifyJson(snapshot.graphs.workspace), 'utf8'),
45
+ () => writeFile(join(dataDir, 'search.json'), stringifyJson(snapshot.searchDocuments), 'utf8'),
46
+ () => writeFile(manifestFilePath, stringifyJson({
47
47
  ...snapshot.manifest,
48
48
  pageOptions: snapshot.pageOptions,
49
49
  runtimeMode: snapshot.runtimeMode,
@@ -51,79 +51,89 @@ export async function writeHtmlExport(snapshot, request) {
51
51
  }), 'utf8')
52
52
  ];
53
53
  const isPrintMode = snapshot.runtimeMode === 'print';
54
- writes.push(writeFile(indexFilePath, isPrintMode ? renderPrintHomePage(snapshot) : renderHomePage(snapshot), 'utf8'));
54
+ writes.push(() => writeFile(indexFilePath, isPrintMode ? renderPrintHomePage(snapshot) : renderHomePage(snapshot), 'utf8'));
55
55
  if (snapshot.pageOptions.includePrintPages) {
56
- writes.push(writeFile(printFilePath, renderPrintHomePage(snapshot), 'utf8'));
56
+ writes.push(() => writeFile(printFilePath, renderPrintHomePage(snapshot), 'utf8'));
57
57
  }
58
58
  if (!isPrintMode && requirementsFilePath) {
59
- writes.push(writeFile(requirementsFilePath, renderIdeasIndexPage(snapshot), 'utf8'));
59
+ writes.push(() => writeFile(requirementsFilePath, renderIdeasIndexPage(snapshot), 'utf8'));
60
60
  }
61
61
  if (!isPrintMode && graphFilePath && snapshot.pageOptions.includeGraphPage) {
62
- writes.push(writeFile(graphFilePath, renderGraphPage(snapshot), 'utf8'));
62
+ writes.push(() => writeFile(graphFilePath, renderGraphPage(snapshot), 'utf8'));
63
63
  }
64
64
  if (!isPrintMode) {
65
- writes.push(writeFile(ideasIndexFilePath, renderIdeasIndexPage(snapshot), 'utf8'));
65
+ writes.push(() => writeFile(ideasIndexFilePath, renderIdeasIndexPage(snapshot), 'utf8'));
66
66
  if (snapshot.pageOptions.includeFilePages) {
67
- writes.push(writeFile(filesIndexFilePath, renderFilesIndexPage(snapshot), 'utf8'));
67
+ writes.push(() => writeFile(filesIndexFilePath, renderFilesIndexPage(snapshot), 'utf8'));
68
68
  }
69
69
  if (snapshot.pageOptions.includeCodeFilePages) {
70
- writes.push(writeFile(codeFilesIndexFilePath, renderCodeFilesIndexPage(snapshot), 'utf8'));
70
+ writes.push(() => writeFile(codeFilesIndexFilePath, renderCodeFilesIndexPage(snapshot), 'utf8'));
71
71
  }
72
72
  if (snapshot.pageOptions.includeClusterPages) {
73
- writes.push(writeFile(clustersIndexFilePath, renderClustersIndexPage(snapshot), 'utf8'));
73
+ writes.push(() => writeFile(clustersIndexFilePath, renderClustersIndexPage(snapshot), 'utf8'));
74
74
  }
75
- writes.push(writeFile(attributesIndexFilePath, renderAttributesIndexPage(snapshot), 'utf8'));
75
+ writes.push(() => writeFile(attributesIndexFilePath, renderAttributesIndexPage(snapshot), 'utf8'));
76
76
  }
77
77
  if (!isPrintMode && snapshot.pageOptions.includeIdeaPages) {
78
78
  for (const idea of snapshot.ideas) {
79
- writes.push(writeFile(join(outputDir, idea.page.path), renderIdeaDetailPage(snapshot, idea), 'utf8'));
79
+ writes.push(() => writeFile(join(outputDir, idea.page.path), renderIdeaDetailPage(snapshot, idea), 'utf8'));
80
80
  }
81
81
  }
82
82
  if (snapshot.pageOptions.includePrintPages) {
83
83
  for (const idea of snapshot.ideas) {
84
- if (idea.page.printablePath) {
85
- writes.push(writeFile(join(outputDir, idea.page.printablePath), renderPrintIdeaPage(snapshot, idea), 'utf8'));
84
+ const printablePath = idea.page.printablePath;
85
+ if (printablePath) {
86
+ writes.push(() => writeFile(join(outputDir, printablePath), renderPrintIdeaPage(snapshot, idea), 'utf8'));
86
87
  }
87
88
  }
88
89
  }
89
90
  if (!isPrintMode && snapshot.pageOptions.includeFilePages) {
90
91
  for (const file of snapshot.files) {
91
- writes.push(writeFile(join(outputDir, file.page.path), renderFileDetailPage(snapshot, file), 'utf8'));
92
+ writes.push(() => writeFile(join(outputDir, file.page.path), renderFileDetailPage(snapshot, file), 'utf8'));
92
93
  }
93
94
  }
94
95
  if (snapshot.pageOptions.includePrintPages) {
95
96
  for (const file of snapshot.files) {
96
- writes.push(writeFile(join(outputDir, file.printPage.path), renderPrintFilePage(snapshot, file), 'utf8'));
97
+ writes.push(() => writeFile(join(outputDir, file.printPage.path), renderPrintFilePage(snapshot, file), 'utf8'));
97
98
  }
98
99
  }
99
100
  if (!isPrintMode && snapshot.pageOptions.includeCodeFilePages) {
100
101
  for (const file of snapshot.codeFiles) {
101
- writes.push(writeFile(join(outputDir, file.page.path), renderCodeFileDetailPage(snapshot, file), 'utf8'));
102
+ writes.push(() => writeFile(join(outputDir, file.page.path), renderCodeFileDetailPage(snapshot, file), 'utf8'));
102
103
  }
103
104
  }
104
105
  if (snapshot.pageOptions.includePrintPages && snapshot.pageOptions.includeCodeFilePages) {
105
106
  for (const file of snapshot.codeFiles) {
106
- writes.push(writeFile(join(outputDir, file.printPage.path), renderPrintCodeFilePage(snapshot, file), 'utf8'));
107
+ writes.push(() => writeFile(join(outputDir, file.printPage.path), renderPrintCodeFilePage(snapshot, file), 'utf8'));
107
108
  }
108
109
  }
109
110
  if (!isPrintMode && snapshot.pageOptions.includeClusterPages) {
110
111
  for (const cluster of snapshot.clusters) {
111
- writes.push(writeFile(join(outputDir, cluster.page.path), renderClusterDetailPage(snapshot, cluster), 'utf8'));
112
+ writes.push(() => writeFile(join(outputDir, cluster.page.path), renderClusterDetailPage(snapshot, cluster), 'utf8'));
112
113
  }
113
114
  }
114
115
  if (snapshot.pageOptions.includePrintPages && snapshot.pageOptions.includeClusterPages) {
115
116
  for (const cluster of snapshot.clusters) {
116
- if (cluster.page.printablePath) {
117
- writes.push(writeFile(join(outputDir, cluster.page.printablePath), renderPrintClusterPage(snapshot, cluster), 'utf8'));
117
+ const printablePath = cluster.page.printablePath;
118
+ if (printablePath) {
119
+ writes.push(() => writeFile(join(outputDir, printablePath), renderPrintClusterPage(snapshot, cluster), 'utf8'));
118
120
  }
119
121
  }
120
122
  }
121
123
  if (!isPrintMode && snapshot.pageOptions.includeAttributePages) {
122
124
  for (const attribute of snapshot.attributes) {
123
- writes.push(writeFile(join(outputDir, attribute.page.path), renderAttributeDetailPage(snapshot, attribute), 'utf8'));
125
+ writes.push(() => writeFile(join(outputDir, attribute.page.path), renderAttributeDetailPage(snapshot, attribute), 'utf8'));
124
126
  }
125
127
  }
126
- await Promise.all(writes);
128
+ const total = writes.length;
129
+ const report = createWriteProgressReporter(onProgress, total);
130
+ report(0);
131
+ let completed = 0;
132
+ await Promise.all(writes.map(async (write) => {
133
+ await write();
134
+ completed += 1;
135
+ report(completed);
136
+ }));
127
137
  return {
128
138
  outputDir,
129
139
  indexFilePath,
@@ -139,6 +149,28 @@ export async function writeHtmlExport(snapshot, request) {
139
149
  manifestFilePath
140
150
  };
141
151
  }
152
+ function createWriteProgressReporter(onProgress, total) {
153
+ if (!onProgress) {
154
+ return () => undefined;
155
+ }
156
+ let lastReported = -1;
157
+ const step = Math.max(1, Math.floor(total / 40));
158
+ return (completed) => {
159
+ const isBoundary = completed === 0 || completed === total || completed - lastReported >= step;
160
+ if (!isBoundary) {
161
+ return;
162
+ }
163
+ lastReported = completed;
164
+ onProgress({
165
+ phase: 'write',
166
+ message: completed === 0
167
+ ? `Writing ${total} files…`
168
+ : `Writing files (${completed}/${total})…`,
169
+ completed,
170
+ total,
171
+ });
172
+ };
173
+ }
142
174
  function ensureHtmlFileName(value) {
143
175
  const trimmed = value.trim();
144
176
  if (trimmed.toLowerCase().endsWith('.html')) {
@@ -1 +1 @@
1
- {"version":3,"file":"write-html-export.js","sourceRoot":"","sources":["../../src/export/write-html-export.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"write-html-export.js","sourceRoot":"","sources":["../../src/export/write-html-export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ExportProgressCallback, ExportRequest, ExportResult, ExportSnapshot } from './types.js';
2
+ /** Write a structured JSON export for tooling and AI consumption. */
3
+ export declare function writeJsonExport(snapshot: ExportSnapshot, request: ExportRequest, onProgress?: ExportProgressCallback): Promise<ExportResult>;
@@ -0,0 +1,92 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ /** Write a structured JSON export for tooling and AI consumption. */
4
+ export async function writeJsonExport(snapshot, request, onProgress) {
5
+ const outputDir = join(request.outputDir, request.exportName);
6
+ await mkdir(outputDir, { recursive: true });
7
+ const indexFilePath = join(outputDir, 'export.json');
8
+ onProgress?.({
9
+ phase: 'write',
10
+ message: 'Writing export.json…',
11
+ completed: 0,
12
+ total: 1,
13
+ });
14
+ const payload = {
15
+ format: 'json',
16
+ title: snapshot.title,
17
+ generatedAt: snapshot.generatedAt,
18
+ workspaceRoot: snapshot.workspaceRoot,
19
+ scope: snapshot.scope,
20
+ sourceFileUri: snapshot.sourceFileUri,
21
+ counts: snapshot.counts,
22
+ byStatus: snapshot.byStatus,
23
+ byTag: snapshot.byTag,
24
+ ideas: snapshot.ideas.map(idea => ({
25
+ id: idea.id,
26
+ name: idea.name,
27
+ kind: idea.kind,
28
+ fileUri: idea.fileUri,
29
+ lineStart: idea.lineStart,
30
+ summary: idea.summary,
31
+ status: idea.status,
32
+ tags: idea.tags,
33
+ attributes: idea.attributes,
34
+ references: {
35
+ inbound: idea.references.inbound.map(compactRef),
36
+ outbound: idea.references.outbound.map(compactRef),
37
+ unresolved: idea.references.unresolved.map(compactRef),
38
+ },
39
+ clusterIds: idea.clusterIds,
40
+ })),
41
+ files: snapshot.files.map(file => ({
42
+ fileUri: file.fileUri,
43
+ ideaIds: file.ideas.map(idea => idea.id),
44
+ ideaCount: file.ideas.length,
45
+ statuses: file.statuses,
46
+ tags: file.tags,
47
+ })),
48
+ clusters: snapshot.clusters.map(cluster => ({
49
+ id: cluster.id,
50
+ kind: cluster.kind,
51
+ label: cluster.label,
52
+ description: cluster.description,
53
+ ideaIds: cluster.ideaIds,
54
+ counts: cluster.counts,
55
+ })),
56
+ attributes: snapshot.attributes.map(attribute => ({
57
+ key: attribute.key,
58
+ ideaCount: attribute.ideaCount,
59
+ values: attribute.values.map(value => ({
60
+ value: value.value,
61
+ count: value.count,
62
+ ideaIds: value.ideaIds,
63
+ })),
64
+ })),
65
+ };
66
+ await writeFile(indexFilePath, `${JSON.stringify(payload, null, 2)}\n`, 'utf8');
67
+ onProgress?.({
68
+ phase: 'write',
69
+ message: 'Wrote export.json',
70
+ completed: 1,
71
+ total: 1,
72
+ });
73
+ return {
74
+ outputDir,
75
+ indexFilePath,
76
+ printFilePath: indexFilePath,
77
+ dataFilePath: indexFilePath,
78
+ };
79
+ }
80
+ function compactRef(row) {
81
+ return {
82
+ kind: row.kind,
83
+ label: row.label,
84
+ targetName: row.targetName,
85
+ targetPath: row.targetPath,
86
+ targetIdeaId: row.targetIdeaId,
87
+ sourceIdeaId: row.sourceIdeaId,
88
+ isResolved: row.isResolved,
89
+ snippet: row.snippet,
90
+ };
91
+ }
92
+ //# sourceMappingURL=write-json-export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-json-export.js","sourceRoot":"","sources":["../../src/export/write-json-export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { ExportProgressCallback, ExportRequest, ExportResult, ExportSnapshot } from './types.js';
2
+ /** Build markdown paths from HTML-oriented snapshot page paths. */
3
+ export declare function toMarkdownPath(htmlPath: string): string;
4
+ /** Write a multi-file markdown export from an export snapshot. */
5
+ export declare function writeMarkdownExport(snapshot: ExportSnapshot, request: ExportRequest, onProgress?: ExportProgressCallback): Promise<ExportResult>;
@@ -0,0 +1,177 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { formatAttributeValue } from './html-export-utils.js';
4
+ /** Build markdown paths from HTML-oriented snapshot page paths. */
5
+ export function toMarkdownPath(htmlPath) {
6
+ return htmlPath.replace(/\.html$/i, '.md');
7
+ }
8
+ /** Write a multi-file markdown export from an export snapshot. */
9
+ export async function writeMarkdownExport(snapshot, request, onProgress) {
10
+ const outputDir = join(request.outputDir, request.exportName);
11
+ await mkdir(outputDir, { recursive: true });
12
+ const indexFilePath = join(outputDir, 'README.md');
13
+ const ideasDir = join(outputDir, 'ideas');
14
+ if (snapshot.pageOptions.includeIdeaPages) {
15
+ await mkdir(ideasDir, { recursive: true });
16
+ }
17
+ const writes = [
18
+ () => writeFile(indexFilePath, renderReadme(snapshot), 'utf8'),
19
+ ];
20
+ if (snapshot.pageOptions.includeIdeaPages) {
21
+ for (const idea of snapshot.ideas) {
22
+ const path = join(outputDir, ideaMarkdownRelPath(idea));
23
+ writes.push(() => writeFile(path, renderIdeaMarkdown(snapshot, idea), 'utf8'));
24
+ }
25
+ }
26
+ const total = writes.length;
27
+ let completed = 0;
28
+ onProgress?.({
29
+ phase: 'write',
30
+ message: `Writing markdown (${total} files)…`,
31
+ completed: 0,
32
+ total,
33
+ });
34
+ for (const write of writes) {
35
+ await write();
36
+ completed += 1;
37
+ onProgress?.({
38
+ phase: 'write',
39
+ message: `Writing markdown (${completed}/${total})…`,
40
+ completed,
41
+ total,
42
+ });
43
+ }
44
+ return {
45
+ outputDir,
46
+ indexFilePath,
47
+ printFilePath: indexFilePath,
48
+ dataFilePath: indexFilePath,
49
+ ideasIndexFilePath: indexFilePath,
50
+ };
51
+ }
52
+ function ideaMarkdownRelPath(idea) {
53
+ return toMarkdownPath(idea.page.path);
54
+ }
55
+ function renderReadme(snapshot) {
56
+ const lines = [
57
+ `# ${snapshot.title}`,
58
+ '',
59
+ `Generated ${snapshot.generatedAt}`,
60
+ '',
61
+ `Ideas: **${snapshot.counts.ideas}** · Files: **${snapshot.counts.files}** · Clusters: **${snapshot.counts.clusters}**`,
62
+ '',
63
+ ];
64
+ if (Object.keys(snapshot.byStatus).length > 0) {
65
+ lines.push('## Status', '');
66
+ for (const [status, count] of Object.entries(snapshot.byStatus).sort((a, b) => a[0].localeCompare(b[0]))) {
67
+ lines.push(`- ${escapeMd(status)}: ${count}`);
68
+ }
69
+ lines.push('');
70
+ }
71
+ if (Object.keys(snapshot.byTag).length > 0) {
72
+ lines.push('## Tags', '');
73
+ for (const [tag, count] of Object.entries(snapshot.byTag).sort((a, b) => a[0].localeCompare(b[0]))) {
74
+ lines.push(`- ${escapeMd(tag)}: ${count}`);
75
+ }
76
+ lines.push('');
77
+ }
78
+ lines.push('## Ideas', '');
79
+ if (snapshot.ideas.length === 0) {
80
+ lines.push('_No ideas in this export scope._', '');
81
+ }
82
+ else if (snapshot.pageOptions.includeIdeaPages) {
83
+ for (const idea of snapshot.ideas) {
84
+ const href = ideaMarkdownRelPath(idea);
85
+ const status = idea.status ? ` · ${escapeMd(idea.status)}` : '';
86
+ lines.push(`- [${escapeMdLinkText(idea.name)}](${href})${status}`);
87
+ if (idea.summary?.trim()) {
88
+ lines.push(` - ${escapeMd(oneLine(idea.summary))}`);
89
+ }
90
+ }
91
+ lines.push('');
92
+ }
93
+ else {
94
+ for (const idea of snapshot.ideas) {
95
+ lines.push(renderIdeaMarkdown(snapshot, idea, { headingLevel: 3, omitBackLink: true }));
96
+ lines.push('');
97
+ }
98
+ }
99
+ if (snapshot.files.length > 0) {
100
+ lines.push('## Files', '');
101
+ for (const file of snapshot.files) {
102
+ lines.push(`- \`${escapeMd(file.fileUri)}\` (${file.ideas.length} ideas)`);
103
+ }
104
+ lines.push('');
105
+ }
106
+ return `${lines.join('\n').trimEnd()}\n`;
107
+ }
108
+ function renderIdeaMarkdown(snapshot, idea, options) {
109
+ const level = options?.headingLevel ?? 1;
110
+ const heading = `${'#'.repeat(level)} ${escapeMd(idea.name)}`;
111
+ const lines = [heading, ''];
112
+ if (!options?.omitBackLink) {
113
+ lines.push('[← Back to index](../README.md)', '');
114
+ }
115
+ if (idea.summary?.trim()) {
116
+ lines.push(idea.summary.trim(), '');
117
+ }
118
+ lines.push(`- **File:** \`${escapeMd(idea.fileUri)}\``);
119
+ if (idea.status) {
120
+ lines.push(`- **Status:** ${escapeMd(idea.status)}`);
121
+ }
122
+ if (idea.tags.length > 0) {
123
+ lines.push(`- **Tags:** ${idea.tags.map(tag => `\`${escapeMd(tag)}\``).join(', ')}`);
124
+ }
125
+ lines.push('');
126
+ const attrEntries = Object.entries(idea.attributes).filter(([key]) => key !== 'status' && key !== 'tags');
127
+ if (attrEntries.length > 0) {
128
+ lines.push('## Attributes', '');
129
+ for (const [key, value] of attrEntries.sort((a, b) => a[0].localeCompare(b[0]))) {
130
+ lines.push(`- **${escapeMd(key)}:** ${escapeMd(formatAttributeValue(value))}`);
131
+ }
132
+ lines.push('');
133
+ }
134
+ appendRefSection(lines, snapshot, 'Outbound', idea.references.outbound);
135
+ appendRefSection(lines, snapshot, 'Inbound', idea.references.inbound);
136
+ if (idea.references.unresolved.length > 0) {
137
+ lines.push('## Unresolved references', '');
138
+ for (const row of idea.references.unresolved) {
139
+ lines.push(`- ${escapeMd(row.label || row.targetName || row.targetPath || 'unresolved')}`);
140
+ }
141
+ lines.push('');
142
+ }
143
+ return `${lines.join('\n').trimEnd()}\n`;
144
+ }
145
+ function appendRefSection(lines, snapshot, title, rows) {
146
+ if (rows.length === 0) {
147
+ return;
148
+ }
149
+ lines.push(`## ${title}`, '');
150
+ for (const row of rows) {
151
+ const target = row.targetIdeaId ? snapshot.ideasById[row.targetIdeaId] : undefined;
152
+ if (target && snapshot.pageOptions.includeIdeaPages) {
153
+ const fileName = ideaMarkdownRelPath(target).replace(/^ideas\//, '');
154
+ lines.push(`- [${escapeMdLinkText(target.name)}](./${fileName})`);
155
+ }
156
+ else if (target) {
157
+ lines.push(`- ${escapeMd(target.name)}`);
158
+ }
159
+ else if (row.targetPath) {
160
+ lines.push(`- \`${escapeMd(row.targetPath)}\``);
161
+ }
162
+ else {
163
+ lines.push(`- ${escapeMd(row.targetName || row.label || 'reference')}`);
164
+ }
165
+ }
166
+ lines.push('');
167
+ }
168
+ function oneLine(value) {
169
+ return value.replace(/\s+/g, ' ').trim();
170
+ }
171
+ function escapeMd(value) {
172
+ return value.replace(/([\\`*_{}[\]()#+\-.!|>])/g, '\\$1');
173
+ }
174
+ function escapeMdLinkText(value) {
175
+ return value.replace(/([\\\[\]])/g, '\\$1');
176
+ }
177
+ //# sourceMappingURL=write-markdown-export.js.map