@wiki0/core 0.0.4 → 0.0.5
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/README.md +5 -5
- package/dist/documents.d.ts +12 -0
- package/dist/documents.js +143 -0
- package/dist/documents.js.map +1 -0
- package/dist/facts.d.ts +4 -0
- package/dist/facts.js +30 -0
- package/dist/facts.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/ingest.d.ts +2 -0
- package/dist/ingest.js +253 -0
- package/dist/ingest.js.map +1 -0
- package/dist/sync.d.ts +2 -0
- package/dist/sync.js +340 -0
- package/dist/sync.js.map +1 -0
- package/dist/types.d.ts +20 -11
- package/dist/workflow.d.ts +2 -3
- package/dist/workflow.js +2 -187
- package/dist/workflow.js.map +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -23,13 +23,14 @@ Core wiki0 primitives for local-first Markdown wiki memory.
|
|
|
23
23
|
|
|
24
24
|
```ts
|
|
25
25
|
import {
|
|
26
|
-
bootstrap_wiki,
|
|
27
26
|
create_page,
|
|
28
27
|
index_status,
|
|
29
28
|
index_wiki,
|
|
30
29
|
search_wiki,
|
|
31
30
|
get_wiki_context,
|
|
31
|
+
sync_documents,
|
|
32
32
|
lint_wiki,
|
|
33
|
+
parse_document,
|
|
33
34
|
plan_wiki,
|
|
34
35
|
} from '@wiki0/core';
|
|
35
36
|
|
|
@@ -44,12 +45,11 @@ console.log(lint_wiki('.'));
|
|
|
44
45
|
console.log(
|
|
45
46
|
plan_wiki({ source_type: 'codebase', scope: 'current repo' }),
|
|
46
47
|
);
|
|
48
|
+
console.log(await parse_document('docs/guide.md'));
|
|
47
49
|
console.log(
|
|
48
|
-
|
|
50
|
+
await sync_documents({
|
|
49
51
|
root: '.',
|
|
50
|
-
|
|
51
|
-
sources: ['docs/guide.md'],
|
|
52
|
-
ingest_sources: true,
|
|
52
|
+
sources: ['docs'],
|
|
53
53
|
}),
|
|
54
54
|
);
|
|
55
55
|
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type ParsedDocumentKind = 'markdown' | 'text' | 'pdf' | 'docx' | 'unsupported';
|
|
2
|
+
export type ParsedDocumentMetadata = Record<string, string | number | boolean | null>;
|
|
3
|
+
export interface ParsedDocument {
|
|
4
|
+
source_path: string;
|
|
5
|
+
kind: ParsedDocumentKind;
|
|
6
|
+
title?: string;
|
|
7
|
+
text: string;
|
|
8
|
+
metadata: ParsedDocumentMetadata;
|
|
9
|
+
warnings: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function parse_document(source_path: string): Promise<ParsedDocument>;
|
|
12
|
+
export declare function document_kind(source_path: string): ParsedDocumentKind;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import mammoth from 'mammoth';
|
|
2
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
3
|
+
import { basename, extname, resolve } from 'node:path';
|
|
4
|
+
import { PDFParse } from 'pdf-parse';
|
|
5
|
+
import { page_title_from_markdown, parse_markdown, } from './markdown.js';
|
|
6
|
+
export async function parse_document(source_path) {
|
|
7
|
+
const resolved_path = resolve(source_path);
|
|
8
|
+
const kind = document_kind(source_path);
|
|
9
|
+
const base_result = {
|
|
10
|
+
source_path,
|
|
11
|
+
kind,
|
|
12
|
+
text: '',
|
|
13
|
+
metadata: {},
|
|
14
|
+
warnings: [],
|
|
15
|
+
};
|
|
16
|
+
try {
|
|
17
|
+
const stats = await stat(resolved_path);
|
|
18
|
+
if (!stats.isFile()) {
|
|
19
|
+
return {
|
|
20
|
+
...base_result,
|
|
21
|
+
kind: 'unsupported',
|
|
22
|
+
warnings: ['Source is not a file.'],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
return {
|
|
28
|
+
...base_result,
|
|
29
|
+
kind: 'unsupported',
|
|
30
|
+
warnings: [`Source could not be read: ${error_message(error)}`],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
if (kind === 'markdown')
|
|
34
|
+
return parse_markdown_document(source_path);
|
|
35
|
+
if (kind === 'text')
|
|
36
|
+
return parse_text_document(source_path);
|
|
37
|
+
if (kind === 'pdf')
|
|
38
|
+
return parse_pdf_document(source_path);
|
|
39
|
+
if (kind === 'docx')
|
|
40
|
+
return parse_docx_document(source_path);
|
|
41
|
+
return {
|
|
42
|
+
...base_result,
|
|
43
|
+
warnings: [`Unsupported document type: ${extname(source_path)}`],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export function document_kind(source_path) {
|
|
47
|
+
const extension = extname(source_path).toLowerCase();
|
|
48
|
+
if (extension === '.md' || extension === '.markdown')
|
|
49
|
+
return 'markdown';
|
|
50
|
+
if (extension === '.txt')
|
|
51
|
+
return 'text';
|
|
52
|
+
if (extension === '.pdf')
|
|
53
|
+
return 'pdf';
|
|
54
|
+
if (extension === '.docx')
|
|
55
|
+
return 'docx';
|
|
56
|
+
return 'unsupported';
|
|
57
|
+
}
|
|
58
|
+
async function parse_markdown_document(source_path) {
|
|
59
|
+
const text = await readFile(source_path, 'utf-8');
|
|
60
|
+
const parsed = parse_markdown(text);
|
|
61
|
+
return {
|
|
62
|
+
source_path,
|
|
63
|
+
kind: 'markdown',
|
|
64
|
+
title: page_title_from_markdown(text, basename(source_path)),
|
|
65
|
+
text: normalize_text(parsed.content),
|
|
66
|
+
metadata: {
|
|
67
|
+
bytes: Buffer.byteLength(text),
|
|
68
|
+
...flatten_frontmatter_metadata(parsed.frontmatter),
|
|
69
|
+
},
|
|
70
|
+
warnings: [],
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
async function parse_text_document(source_path) {
|
|
74
|
+
const text = await readFile(source_path, 'utf-8');
|
|
75
|
+
return {
|
|
76
|
+
source_path,
|
|
77
|
+
kind: 'text',
|
|
78
|
+
title: basename(source_path),
|
|
79
|
+
text: normalize_text(text),
|
|
80
|
+
metadata: { bytes: Buffer.byteLength(text) },
|
|
81
|
+
warnings: [],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
async function parse_pdf_document(source_path) {
|
|
85
|
+
const parser = new PDFParse({ data: await readFile(source_path) });
|
|
86
|
+
try {
|
|
87
|
+
const [text_result, info_result] = await Promise.all([
|
|
88
|
+
parser.getText(),
|
|
89
|
+
parser.getInfo().catch(() => null),
|
|
90
|
+
]);
|
|
91
|
+
const info = info_result?.info;
|
|
92
|
+
return {
|
|
93
|
+
source_path,
|
|
94
|
+
kind: 'pdf',
|
|
95
|
+
title: string_metadata(info?.Title) ?? basename(source_path),
|
|
96
|
+
text: normalize_text(text_result.text),
|
|
97
|
+
metadata: compact_metadata({
|
|
98
|
+
pages: text_result.total,
|
|
99
|
+
title: string_metadata(info?.Title),
|
|
100
|
+
author: string_metadata(info?.Author),
|
|
101
|
+
subject: string_metadata(info?.Subject),
|
|
102
|
+
creator: string_metadata(info?.Creator),
|
|
103
|
+
producer: string_metadata(info?.Producer),
|
|
104
|
+
}),
|
|
105
|
+
warnings: [],
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
await parser.destroy();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function parse_docx_document(source_path) {
|
|
113
|
+
const result = await mammoth.extractRawText({ path: source_path });
|
|
114
|
+
return {
|
|
115
|
+
source_path,
|
|
116
|
+
kind: 'docx',
|
|
117
|
+
title: basename(source_path),
|
|
118
|
+
text: normalize_text(result.value),
|
|
119
|
+
metadata: {},
|
|
120
|
+
warnings: result.messages.map((message) => message.message),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function normalize_text(text) {
|
|
124
|
+
return text.replace(/\r\n?/gu, '\n').trim();
|
|
125
|
+
}
|
|
126
|
+
function flatten_frontmatter_metadata(frontmatter) {
|
|
127
|
+
return Object.fromEntries(Object.entries(frontmatter)
|
|
128
|
+
.filter((entry) => entry[1] === null ||
|
|
129
|
+
['string', 'number', 'boolean'].includes(typeof entry[1]))
|
|
130
|
+
.map(([key, value]) => [`frontmatter_${key}`, value]));
|
|
131
|
+
}
|
|
132
|
+
function compact_metadata(metadata) {
|
|
133
|
+
return Object.fromEntries(Object.entries(metadata).filter((entry) => entry[1] !== undefined));
|
|
134
|
+
}
|
|
135
|
+
function string_metadata(value) {
|
|
136
|
+
return typeof value === 'string' && value.trim().length > 0
|
|
137
|
+
? value.trim()
|
|
138
|
+
: undefined;
|
|
139
|
+
}
|
|
140
|
+
function error_message(error) {
|
|
141
|
+
return error instanceof Error ? error.message : String(error);
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=documents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documents.js","sourceRoot":"","sources":["../src/documents.ts"],"names":[],"mappings":"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"}
|
package/dist/facts.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import type { Fact, FactWriteOptions } from './types.js';
|
|
2
|
+
export type DerivedFactCandidate = Omit<FactWriteOptions, 'root' | 'page' | 'source'> & {
|
|
3
|
+
line: number;
|
|
4
|
+
};
|
|
2
5
|
export declare function add_fact(fact: FactWriteOptions): Fact;
|
|
3
6
|
export declare function list_facts(root?: string, category?: string): Fact[];
|
|
7
|
+
export declare function derive_facts_from_markdown(markdown: string): DerivedFactCandidate[];
|
package/dist/facts.js
CHANGED
|
@@ -51,6 +51,36 @@ export function list_facts(root = '.', category) {
|
|
|
51
51
|
db.close();
|
|
52
52
|
return rows.map(fact_from_row);
|
|
53
53
|
}
|
|
54
|
+
export function derive_facts_from_markdown(markdown) {
|
|
55
|
+
return markdown
|
|
56
|
+
.split(/\n/u)
|
|
57
|
+
.map((line, index) => ({
|
|
58
|
+
line: line.trim(),
|
|
59
|
+
line_number: index + 1,
|
|
60
|
+
}))
|
|
61
|
+
.filter(({ line }) => /\b(should|must|required|requirement|decision|constraint|risk|assumption|fact)\b/iu.test(line))
|
|
62
|
+
.slice(0, 20)
|
|
63
|
+
.map(({ line, line_number }) => ({
|
|
64
|
+
category: fact_category(line),
|
|
65
|
+
summary: line.replace(/^[-*]\s*/u, '').slice(0, 240),
|
|
66
|
+
body: `Derived from extracted source text line ${line_number}.`,
|
|
67
|
+
confidence: 'low',
|
|
68
|
+
source_quote: line,
|
|
69
|
+
line: line_number,
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
function fact_category(line) {
|
|
73
|
+
if (/\b(decision)\b/iu.test(line))
|
|
74
|
+
return 'decision';
|
|
75
|
+
if (/\b(risk)\b/iu.test(line))
|
|
76
|
+
return 'risk';
|
|
77
|
+
if (/\b(assumption)\b/iu.test(line))
|
|
78
|
+
return 'assumption';
|
|
79
|
+
if (/\b(constraint|must|required|requirement|should)\b/iu.test(line)) {
|
|
80
|
+
return 'constraint';
|
|
81
|
+
}
|
|
82
|
+
return 'note';
|
|
83
|
+
}
|
|
54
84
|
const fact_select_sql = `SELECT facts.id, pages.path AS page_path, facts.category,
|
|
55
85
|
facts.summary, facts.body, facts.confidence,
|
|
56
86
|
facts.source_path, facts.source_heading, facts.source_start_line,
|
package/dist/facts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facts.js","sourceRoot":"","sources":["../src/facts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAqB,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"facts.js","sourceRoot":"","sources":["../src/facts.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { open_wiki_database, wiki_db_path } from './database.js';
|
|
2
|
+
export { document_kind, parse_document, type ParsedDocument, type ParsedDocumentKind, type ParsedDocumentMetadata, } from './documents.js';
|
|
2
3
|
export { list_wiki_events, log_wiki_event } from './events.js';
|
|
3
|
-
export { add_fact, list_facts } from './facts.js';
|
|
4
|
+
export { add_fact, derive_facts_from_markdown, list_facts, type DerivedFactCandidate, } from './facts.js';
|
|
4
5
|
export { graph_wiki } from './graph.js';
|
|
5
6
|
export { current_index_package_version, current_index_schema_version, index_status, index_wiki, } from './indexer.js';
|
|
6
7
|
export { lint_wiki } from './lint.js';
|
|
@@ -10,6 +11,7 @@ export { display_page_title, page_file_path, page_relative_path, resolve_wiki_ro
|
|
|
10
11
|
export { review_wiki } from './review.js';
|
|
11
12
|
export { schema_sql } from './schema.js';
|
|
12
13
|
export { backlinks_for_page, format_context_markdown, get_wiki_context, search_wiki, search_wiki_chunks, show_wiki_chunk, } from './search.js';
|
|
14
|
+
export { sync_documents } from './sync.js';
|
|
13
15
|
export { list_topic_threads } from './topics.js';
|
|
14
16
|
export type * from './types.js';
|
|
15
|
-
export {
|
|
17
|
+
export { plan_wiki, wiki_building_workflow_markdown, } from './workflow.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { open_wiki_database, wiki_db_path } from './database.js';
|
|
2
|
+
export { document_kind, parse_document, } from './documents.js';
|
|
2
3
|
export { list_wiki_events, log_wiki_event } from './events.js';
|
|
3
|
-
export { add_fact, list_facts } from './facts.js';
|
|
4
|
+
export { add_fact, derive_facts_from_markdown, list_facts, } from './facts.js';
|
|
4
5
|
export { graph_wiki } from './graph.js';
|
|
5
6
|
export { current_index_package_version, current_index_schema_version, index_status, index_wiki, } from './indexer.js';
|
|
6
7
|
export { lint_wiki } from './lint.js';
|
|
@@ -10,6 +11,7 @@ export { display_page_title, page_file_path, page_relative_path, resolve_wiki_ro
|
|
|
10
11
|
export { review_wiki } from './review.js';
|
|
11
12
|
export { schema_sql } from './schema.js';
|
|
12
13
|
export { backlinks_for_page, format_context_markdown, get_wiki_context, search_wiki, search_wiki_chunks, show_wiki_chunk, } from './search.js';
|
|
14
|
+
export { sync_documents } from './sync.js';
|
|
13
15
|
export { list_topic_threads } from './topics.js';
|
|
14
|
-
export {
|
|
16
|
+
export { plan_wiki, wiki_building_workflow_markdown, } from './workflow.js';
|
|
15
17
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EACN,aAAa,EACb,cAAc,GAId,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EACN,QAAQ,EACR,0BAA0B,EAC1B,UAAU,GAEV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EACN,6BAA6B,EAC7B,4BAA4B,EAC5B,YAAY,EACZ,UAAU,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EACN,wBAAwB,EACxB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,wBAAwB,EACxB,iBAAiB,GACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,WAAW,EACX,WAAW,EACX,wBAAwB,EACxB,SAAS,EACT,iBAAiB,EACjB,oBAAoB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,oBAAoB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACN,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,eAAe,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EACN,SAAS,EACT,+BAA+B,GAC/B,MAAM,eAAe,CAAC"}
|
package/dist/ingest.d.ts
ADDED
package/dist/ingest.js
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, readFileSync, readdirSync, statSync, } from 'node:fs';
|
|
3
|
+
import { join, relative, resolve } from 'node:path';
|
|
4
|
+
import { parse_document } from './documents.js';
|
|
5
|
+
import { log_wiki_event } from './events.js';
|
|
6
|
+
import { index_wiki } from './indexer.js';
|
|
7
|
+
import { parse_markdown, serialize_frontmatter } from './markdown.js';
|
|
8
|
+
import { create_page } from './pages.js';
|
|
9
|
+
import { page_file_path, resolve_wiki_root, slugify_title, } from './paths.js';
|
|
10
|
+
const supported_extensions = new Set([
|
|
11
|
+
'.md',
|
|
12
|
+
'.markdown',
|
|
13
|
+
'.txt',
|
|
14
|
+
'.pdf',
|
|
15
|
+
'.docx',
|
|
16
|
+
]);
|
|
17
|
+
export async function ingest_documents(options) {
|
|
18
|
+
const root = resolve_wiki_root(options.root);
|
|
19
|
+
const sources = discover_sources(root, options.sources);
|
|
20
|
+
const display_sources = sources.map((source) => source_display_path(root, source));
|
|
21
|
+
const created = [];
|
|
22
|
+
const skipped = [];
|
|
23
|
+
const ingested_sources = [];
|
|
24
|
+
for (const source of sources) {
|
|
25
|
+
const display_source = source_display_path(root, source);
|
|
26
|
+
const page = source_page_path(display_source);
|
|
27
|
+
const file_path = page_file_path(page, root);
|
|
28
|
+
const page_exists = existsSync(file_path);
|
|
29
|
+
const fingerprint = source_fingerprint(source);
|
|
30
|
+
const existing_fingerprint = page_exists
|
|
31
|
+
? existing_source_fingerprint(file_path)
|
|
32
|
+
: null;
|
|
33
|
+
const existing_kind = page_exists
|
|
34
|
+
? existing_source_kind(file_path)
|
|
35
|
+
: 'unsupported';
|
|
36
|
+
if (page_exists &&
|
|
37
|
+
fingerprint !== null &&
|
|
38
|
+
existing_fingerprint === fingerprint) {
|
|
39
|
+
skipped.push(page);
|
|
40
|
+
ingested_sources.push({
|
|
41
|
+
source: display_source,
|
|
42
|
+
page: `${page}.md`,
|
|
43
|
+
kind: existing_kind,
|
|
44
|
+
status: 'unchanged',
|
|
45
|
+
warnings: [],
|
|
46
|
+
});
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (page_exists && !options.overwrite) {
|
|
50
|
+
skipped.push(page);
|
|
51
|
+
ingested_sources.push({
|
|
52
|
+
source: display_source,
|
|
53
|
+
page: `${page}.md`,
|
|
54
|
+
kind: existing_kind,
|
|
55
|
+
status: 'changed',
|
|
56
|
+
warnings: [
|
|
57
|
+
'Source page exists and source fingerprint changed; rerun with overwrite to refresh generated content.',
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const parsed = await parse_document(source);
|
|
63
|
+
create_page(page, source_page_template(parsed, display_source, fingerprint), {
|
|
64
|
+
root,
|
|
65
|
+
overwrite: options.overwrite,
|
|
66
|
+
});
|
|
67
|
+
created.push(page);
|
|
68
|
+
ingested_sources.push({
|
|
69
|
+
source: display_source,
|
|
70
|
+
page: `${page}.md`,
|
|
71
|
+
kind: parsed.kind,
|
|
72
|
+
status: parsed.kind === 'unsupported'
|
|
73
|
+
? 'warning'
|
|
74
|
+
: page_exists
|
|
75
|
+
? 'updated'
|
|
76
|
+
: 'created',
|
|
77
|
+
warnings: parsed.warnings,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
const indexed = options.index === false ? null : index_wiki(root);
|
|
81
|
+
log_wiki_event({
|
|
82
|
+
root,
|
|
83
|
+
operation: 'ingest_documents',
|
|
84
|
+
summary: `Ingested ${created.length} document sources`,
|
|
85
|
+
target: root,
|
|
86
|
+
details: {
|
|
87
|
+
sources: display_sources,
|
|
88
|
+
created,
|
|
89
|
+
skipped,
|
|
90
|
+
ingested_sources,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
root,
|
|
95
|
+
sources: display_sources,
|
|
96
|
+
created,
|
|
97
|
+
skipped,
|
|
98
|
+
ingested_sources,
|
|
99
|
+
indexed,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function discover_sources(root, sources) {
|
|
103
|
+
const discovered = [];
|
|
104
|
+
for (const source of sources) {
|
|
105
|
+
const absolute_source = resolve(root, source);
|
|
106
|
+
if (!existsSync(absolute_source)) {
|
|
107
|
+
discovered.push(absolute_source);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const stats = statSync(absolute_source);
|
|
111
|
+
if (stats.isDirectory()) {
|
|
112
|
+
discovered.push(...discover_directory(absolute_source));
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
discovered.push(absolute_source);
|
|
116
|
+
}
|
|
117
|
+
return [...new Set(discovered)].sort();
|
|
118
|
+
}
|
|
119
|
+
function discover_directory(directory) {
|
|
120
|
+
const sources = [];
|
|
121
|
+
for (const entry of readdirSync(directory, {
|
|
122
|
+
withFileTypes: true,
|
|
123
|
+
})) {
|
|
124
|
+
if (entry.name.startsWith('.'))
|
|
125
|
+
continue;
|
|
126
|
+
const entry_path = join(directory, entry.name);
|
|
127
|
+
if (entry.isDirectory()) {
|
|
128
|
+
sources.push(...discover_directory(entry_path));
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (supported_extensions.has(extension(entry.name))) {
|
|
132
|
+
sources.push(entry_path);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return sources;
|
|
136
|
+
}
|
|
137
|
+
function source_page_path(source) {
|
|
138
|
+
return `sources/ingested/${slugify_title(source)}`;
|
|
139
|
+
}
|
|
140
|
+
function source_page_template(parsed, display_source, fingerprint) {
|
|
141
|
+
const frontmatter = serialize_frontmatter({
|
|
142
|
+
title: `Source: ${parsed.title ?? display_source}`,
|
|
143
|
+
tags: ['source', parsed.kind],
|
|
144
|
+
status: parsed.kind === 'unsupported' ? 'review' : 'draft',
|
|
145
|
+
source_path: display_source,
|
|
146
|
+
source_kind: parsed.kind,
|
|
147
|
+
source_fingerprint: fingerprint,
|
|
148
|
+
});
|
|
149
|
+
return `${frontmatter}# Source: ${parsed.title ?? display_source}
|
|
150
|
+
|
|
151
|
+
Source path: \`${display_source}\`
|
|
152
|
+
Source kind: \`${parsed.kind}\`
|
|
153
|
+
|
|
154
|
+
## Extracted text
|
|
155
|
+
|
|
156
|
+
${format_extracted_text(parsed)}
|
|
157
|
+
|
|
158
|
+
## Parser metadata
|
|
159
|
+
|
|
160
|
+
${format_metadata(parsed)}
|
|
161
|
+
|
|
162
|
+
## Parser warnings
|
|
163
|
+
|
|
164
|
+
${format_list(parsed.warnings, '- None.')}
|
|
165
|
+
|
|
166
|
+
## Candidate facts
|
|
167
|
+
|
|
168
|
+
${format_candidate_facts(parsed.text)}
|
|
169
|
+
|
|
170
|
+
## Open questions
|
|
171
|
+
|
|
172
|
+
- What claims from this source should become stable wiki pages?
|
|
173
|
+
- What needs citation, owner confirmation, or freshness review?
|
|
174
|
+
`;
|
|
175
|
+
}
|
|
176
|
+
function format_extracted_text(parsed) {
|
|
177
|
+
if (parsed.text.length === 0)
|
|
178
|
+
return '- No text extracted.';
|
|
179
|
+
const fence = markdown_code_fence(parsed.text);
|
|
180
|
+
return `${fence}\n${parsed.text}\n${fence}`;
|
|
181
|
+
}
|
|
182
|
+
function markdown_code_fence(text) {
|
|
183
|
+
const longest_backtick_run = Math.max(0, ...Array.from(text.matchAll(/`+/gu), (match) => match[0]?.length ?? 0));
|
|
184
|
+
return '`'.repeat(Math.max(3, longest_backtick_run + 1));
|
|
185
|
+
}
|
|
186
|
+
function format_metadata(parsed) {
|
|
187
|
+
const entries = Object.entries(parsed.metadata);
|
|
188
|
+
if (entries.length === 0)
|
|
189
|
+
return '- None.';
|
|
190
|
+
return entries
|
|
191
|
+
.map(([key, value]) => `- ${key}: ${value ?? 'null'}`)
|
|
192
|
+
.join('\n');
|
|
193
|
+
}
|
|
194
|
+
function format_list(items, empty) {
|
|
195
|
+
return items.length > 0
|
|
196
|
+
? items.map((item) => `- ${item}`).join('\n')
|
|
197
|
+
: empty;
|
|
198
|
+
}
|
|
199
|
+
function format_candidate_facts(text) {
|
|
200
|
+
const facts = text
|
|
201
|
+
.split(/\n/u)
|
|
202
|
+
.map((line, index) => ({
|
|
203
|
+
line: line.trim(),
|
|
204
|
+
line_number: index + 1,
|
|
205
|
+
}))
|
|
206
|
+
.filter(({ line }) => /\b(should|must|required|requirement|decision|constraint|risk|assumption|fact)\b/iu.test(line))
|
|
207
|
+
.slice(0, 20)
|
|
208
|
+
.map(({ line, line_number }) => `- Candidate from extracted line ${line_number}: ${line}`);
|
|
209
|
+
return facts.length > 0
|
|
210
|
+
? facts.join('\n')
|
|
211
|
+
: '- Review this source and promote durable claims into wiki pages.';
|
|
212
|
+
}
|
|
213
|
+
function extension(path) {
|
|
214
|
+
return path.slice(path.lastIndexOf('.')).toLowerCase();
|
|
215
|
+
}
|
|
216
|
+
function source_display_path(root, source) {
|
|
217
|
+
const relative_source = relative(root, source);
|
|
218
|
+
return relative_source.startsWith('..') || relative_source === ''
|
|
219
|
+
? source
|
|
220
|
+
: relative_source;
|
|
221
|
+
}
|
|
222
|
+
function source_fingerprint(source) {
|
|
223
|
+
try {
|
|
224
|
+
const stats = statSync(source);
|
|
225
|
+
if (!stats.isFile())
|
|
226
|
+
return null;
|
|
227
|
+
return createHash('sha256')
|
|
228
|
+
.update(readFileSync(source))
|
|
229
|
+
.digest('hex');
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function existing_source_fingerprint(file_path) {
|
|
236
|
+
const fingerprint = parse_markdown(readFileSync(file_path, 'utf-8'))
|
|
237
|
+
.frontmatter.source_fingerprint;
|
|
238
|
+
return typeof fingerprint === 'string' && fingerprint.length > 0
|
|
239
|
+
? fingerprint
|
|
240
|
+
: null;
|
|
241
|
+
}
|
|
242
|
+
function existing_source_kind(file_path) {
|
|
243
|
+
const kind = parse_markdown(readFileSync(file_path, 'utf-8'))
|
|
244
|
+
.frontmatter.source_kind;
|
|
245
|
+
return kind === 'markdown' ||
|
|
246
|
+
kind === 'text' ||
|
|
247
|
+
kind === 'pdf' ||
|
|
248
|
+
kind === 'docx' ||
|
|
249
|
+
kind === 'unsupported'
|
|
250
|
+
? kind
|
|
251
|
+
: 'unsupported';
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=ingest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest.js","sourceRoot":"","sources":["../src/ingest.ts"],"names":[],"mappings":"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"}
|
package/dist/sync.d.ts
ADDED
package/dist/sync.js
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, readFileSync, readdirSync, statSync, } from 'node:fs';
|
|
3
|
+
import { join, relative, resolve } from 'node:path';
|
|
4
|
+
import { parse_document } from './documents.js';
|
|
5
|
+
import { log_wiki_event } from './events.js';
|
|
6
|
+
import { add_fact, derive_facts_from_markdown } from './facts.js';
|
|
7
|
+
import { index_wiki } from './indexer.js';
|
|
8
|
+
import { parse_markdown, serialize_frontmatter } from './markdown.js';
|
|
9
|
+
import { create_page } from './pages.js';
|
|
10
|
+
import { page_file_path, resolve_wiki_root, slugify_title, } from './paths.js';
|
|
11
|
+
const supported_extensions = new Set([
|
|
12
|
+
'.md',
|
|
13
|
+
'.markdown',
|
|
14
|
+
'.txt',
|
|
15
|
+
'.pdf',
|
|
16
|
+
'.docx',
|
|
17
|
+
]);
|
|
18
|
+
export async function sync_documents(options) {
|
|
19
|
+
const root = resolve_wiki_root(options.root);
|
|
20
|
+
const sources = discover_sources(root, options.sources, {
|
|
21
|
+
include: options.include,
|
|
22
|
+
ignore: options.ignore,
|
|
23
|
+
});
|
|
24
|
+
const display_sources = sources.map((source) => source_display_path(root, source));
|
|
25
|
+
const created = [];
|
|
26
|
+
const skipped = [];
|
|
27
|
+
const proposed_pages = [];
|
|
28
|
+
const fact_inputs = [];
|
|
29
|
+
const synced_sources = [];
|
|
30
|
+
for (const source of sources) {
|
|
31
|
+
const display_source = source_display_path(root, source);
|
|
32
|
+
const page = source_page_path(display_source);
|
|
33
|
+
const file_path = page_file_path(page, root);
|
|
34
|
+
const page_exists = existsSync(file_path);
|
|
35
|
+
const fingerprint = source_fingerprint(source);
|
|
36
|
+
const existing_fingerprint = page_exists
|
|
37
|
+
? existing_source_fingerprint(file_path)
|
|
38
|
+
: null;
|
|
39
|
+
const existing_kind = page_exists
|
|
40
|
+
? existing_source_kind(file_path)
|
|
41
|
+
: 'unsupported';
|
|
42
|
+
if (page_exists &&
|
|
43
|
+
fingerprint !== null &&
|
|
44
|
+
existing_fingerprint === fingerprint) {
|
|
45
|
+
skipped.push(page);
|
|
46
|
+
synced_sources.push({
|
|
47
|
+
source: display_source,
|
|
48
|
+
page: `${page}.md`,
|
|
49
|
+
kind: existing_kind,
|
|
50
|
+
status: 'unchanged',
|
|
51
|
+
warnings: [],
|
|
52
|
+
});
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (page_exists && !options.overwrite) {
|
|
56
|
+
skipped.push(page);
|
|
57
|
+
synced_sources.push({
|
|
58
|
+
source: display_source,
|
|
59
|
+
page: `${page}.md`,
|
|
60
|
+
kind: existing_kind,
|
|
61
|
+
status: 'changed',
|
|
62
|
+
warnings: [
|
|
63
|
+
'Source page exists and source fingerprint changed; rerun with overwrite to refresh generated content.',
|
|
64
|
+
],
|
|
65
|
+
});
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const parsed = await parse_document(source);
|
|
69
|
+
create_page(page, source_page_template(parsed, display_source, fingerprint), {
|
|
70
|
+
root,
|
|
71
|
+
overwrite: options.overwrite,
|
|
72
|
+
});
|
|
73
|
+
created.push(page);
|
|
74
|
+
if (options.derive_facts !== false && options.index !== false) {
|
|
75
|
+
for (const fact of derive_facts_from_markdown(parsed.text)) {
|
|
76
|
+
fact_inputs.push({ page, fact });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (options.propose_pages) {
|
|
80
|
+
proposed_pages.push(...create_proposed_pages(parsed, display_source, root));
|
|
81
|
+
}
|
|
82
|
+
synced_sources.push({
|
|
83
|
+
source: display_source,
|
|
84
|
+
page: `${page}.md`,
|
|
85
|
+
kind: parsed.kind,
|
|
86
|
+
status: parsed.kind === 'unsupported'
|
|
87
|
+
? 'warning'
|
|
88
|
+
: page_exists
|
|
89
|
+
? 'updated'
|
|
90
|
+
: 'created',
|
|
91
|
+
warnings: parsed.warnings,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const indexed = options.index === false ? null : index_wiki(root);
|
|
95
|
+
const derived_facts = fact_inputs.map(({ page, fact }) => add_fact({
|
|
96
|
+
root,
|
|
97
|
+
page,
|
|
98
|
+
source: `${page}.md:${fact.line}`,
|
|
99
|
+
...fact,
|
|
100
|
+
}));
|
|
101
|
+
log_wiki_event({
|
|
102
|
+
root,
|
|
103
|
+
operation: 'sync_documents',
|
|
104
|
+
summary: `Synced ${created.length} document sources`,
|
|
105
|
+
target: root,
|
|
106
|
+
details: {
|
|
107
|
+
sources: display_sources,
|
|
108
|
+
created,
|
|
109
|
+
skipped,
|
|
110
|
+
proposed_pages,
|
|
111
|
+
derived_fact_count: derived_facts.length,
|
|
112
|
+
synced_sources,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
return {
|
|
116
|
+
root,
|
|
117
|
+
sources: display_sources,
|
|
118
|
+
created,
|
|
119
|
+
skipped,
|
|
120
|
+
proposed_pages,
|
|
121
|
+
derived_facts,
|
|
122
|
+
synced_sources,
|
|
123
|
+
indexed,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function discover_sources(root, sources, filters = {}) {
|
|
127
|
+
const discovered = [];
|
|
128
|
+
for (const source of sources) {
|
|
129
|
+
const absolute_source = resolve(root, source);
|
|
130
|
+
if (!existsSync(absolute_source)) {
|
|
131
|
+
discovered.push(absolute_source);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const stats = statSync(absolute_source);
|
|
135
|
+
if (stats.isDirectory()) {
|
|
136
|
+
discovered.push(...discover_directory(absolute_source, root, filters));
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (matches_source_filters(root, absolute_source, filters)) {
|
|
140
|
+
discovered.push(absolute_source);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return [...new Set(discovered)].sort();
|
|
144
|
+
}
|
|
145
|
+
function discover_directory(directory, root, filters) {
|
|
146
|
+
const sources = [];
|
|
147
|
+
for (const entry of readdirSync(directory, {
|
|
148
|
+
withFileTypes: true,
|
|
149
|
+
})) {
|
|
150
|
+
if (entry.name.startsWith('.'))
|
|
151
|
+
continue;
|
|
152
|
+
const entry_path = join(directory, entry.name);
|
|
153
|
+
if (entry.isDirectory()) {
|
|
154
|
+
sources.push(...discover_directory(entry_path, root, filters));
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (supported_extensions.has(extension(entry.name)) &&
|
|
158
|
+
matches_source_filters(root, entry_path, filters)) {
|
|
159
|
+
sources.push(entry_path);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return sources;
|
|
163
|
+
}
|
|
164
|
+
function matches_source_filters(root, source, filters) {
|
|
165
|
+
const display = source_display_path(root, source);
|
|
166
|
+
const included = !filters.include ||
|
|
167
|
+
filters.include.length === 0 ||
|
|
168
|
+
filters.include.some((pattern) => glob_match(pattern, display));
|
|
169
|
+
const ignored = (filters.ignore ?? []).some((pattern) => glob_match(pattern, display));
|
|
170
|
+
return included && !ignored;
|
|
171
|
+
}
|
|
172
|
+
function glob_match(pattern, value) {
|
|
173
|
+
let regex = '';
|
|
174
|
+
for (let index = 0; index < pattern.length; index += 1) {
|
|
175
|
+
const character = pattern[index];
|
|
176
|
+
const next = pattern[index + 1];
|
|
177
|
+
if (character === '*' && next === '*') {
|
|
178
|
+
regex += '.*';
|
|
179
|
+
index += 1;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (character === '*') {
|
|
183
|
+
regex += '[^/]*';
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
regex += character?.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&') ?? '';
|
|
187
|
+
}
|
|
188
|
+
return new RegExp(`^${regex}$`, 'u').test(value);
|
|
189
|
+
}
|
|
190
|
+
function source_page_path(source) {
|
|
191
|
+
return `sources/synced/${slugify_title(source)}`;
|
|
192
|
+
}
|
|
193
|
+
function source_page_template(parsed, display_source, fingerprint) {
|
|
194
|
+
const frontmatter = serialize_frontmatter({
|
|
195
|
+
title: `Source: ${parsed.title ?? display_source}`,
|
|
196
|
+
tags: ['source', parsed.kind],
|
|
197
|
+
status: parsed.kind === 'unsupported' ? 'review' : 'draft',
|
|
198
|
+
source_path: display_source,
|
|
199
|
+
source_kind: parsed.kind,
|
|
200
|
+
source_fingerprint: fingerprint,
|
|
201
|
+
});
|
|
202
|
+
return `${frontmatter}# Source: ${parsed.title ?? display_source}
|
|
203
|
+
|
|
204
|
+
Source path: \`${display_source}\`
|
|
205
|
+
Source kind: \`${parsed.kind}\`
|
|
206
|
+
|
|
207
|
+
## Extracted text
|
|
208
|
+
|
|
209
|
+
${format_extracted_text(parsed)}
|
|
210
|
+
|
|
211
|
+
## Parser metadata
|
|
212
|
+
|
|
213
|
+
${format_metadata(parsed)}
|
|
214
|
+
|
|
215
|
+
## Parser warnings
|
|
216
|
+
|
|
217
|
+
${format_list(parsed.warnings, '- None.')}
|
|
218
|
+
|
|
219
|
+
## Candidate facts
|
|
220
|
+
|
|
221
|
+
${format_candidate_facts(parsed.text)}
|
|
222
|
+
|
|
223
|
+
## Open questions
|
|
224
|
+
|
|
225
|
+
- What claims from this source should become stable wiki pages?
|
|
226
|
+
- What needs citation, owner confirmation, or freshness review?
|
|
227
|
+
`;
|
|
228
|
+
}
|
|
229
|
+
function format_extracted_text(parsed) {
|
|
230
|
+
if (parsed.text.length === 0)
|
|
231
|
+
return '- No text extracted.';
|
|
232
|
+
const fence = markdown_code_fence(parsed.text);
|
|
233
|
+
return `${fence}\n${parsed.text}\n${fence}`;
|
|
234
|
+
}
|
|
235
|
+
function markdown_code_fence(text) {
|
|
236
|
+
const longest_backtick_run = Math.max(0, ...Array.from(text.matchAll(/`+/gu), (match) => match[0]?.length ?? 0));
|
|
237
|
+
return '`'.repeat(Math.max(3, longest_backtick_run + 1));
|
|
238
|
+
}
|
|
239
|
+
function format_metadata(parsed) {
|
|
240
|
+
const entries = Object.entries(parsed.metadata);
|
|
241
|
+
if (entries.length === 0)
|
|
242
|
+
return '- None.';
|
|
243
|
+
return entries
|
|
244
|
+
.map(([key, value]) => `- ${key}: ${value ?? 'null'}`)
|
|
245
|
+
.join('\n');
|
|
246
|
+
}
|
|
247
|
+
function format_list(items, empty) {
|
|
248
|
+
return items.length > 0
|
|
249
|
+
? items.map((item) => `- ${item}`).join('\n')
|
|
250
|
+
: empty;
|
|
251
|
+
}
|
|
252
|
+
function format_candidate_facts(text) {
|
|
253
|
+
const facts = derive_facts_from_markdown(text).map((fact) => `- Candidate from extracted line ${fact.line}: ${fact.summary}`);
|
|
254
|
+
return facts.length > 0
|
|
255
|
+
? facts.join('\n')
|
|
256
|
+
: '- Review this source and promote durable claims into wiki pages.';
|
|
257
|
+
}
|
|
258
|
+
function create_proposed_pages(parsed, display_source, root) {
|
|
259
|
+
const pages = [];
|
|
260
|
+
for (const proposal of propose_pages(parsed, display_source)) {
|
|
261
|
+
if (existsSync(page_file_path(proposal.path, root)))
|
|
262
|
+
continue;
|
|
263
|
+
create_page(proposal.path, proposal.body, {
|
|
264
|
+
root,
|
|
265
|
+
overwrite: false,
|
|
266
|
+
});
|
|
267
|
+
pages.push(proposal.path);
|
|
268
|
+
}
|
|
269
|
+
return pages;
|
|
270
|
+
}
|
|
271
|
+
function propose_pages(parsed, display_source) {
|
|
272
|
+
const headings = parsed.text
|
|
273
|
+
.split(/\n/u)
|
|
274
|
+
.map((line) => line.match(/^#{1,3}\s+(.+)$/u)?.[1]?.trim())
|
|
275
|
+
.filter((heading) => Boolean(heading))
|
|
276
|
+
.slice(0, 5);
|
|
277
|
+
const workflow_lines = parsed.text
|
|
278
|
+
.split(/\n/u)
|
|
279
|
+
.filter((line) => /\b(workflow|process|step|how to)\b/iu.test(line))
|
|
280
|
+
.slice(0, 3);
|
|
281
|
+
return [
|
|
282
|
+
...headings.map((heading) => proposed_page('concepts', heading, display_source)),
|
|
283
|
+
...workflow_lines.map((line) => proposed_page('workflows', line.replace(/^[-*]\s*/u, '').slice(0, 80), display_source)),
|
|
284
|
+
];
|
|
285
|
+
}
|
|
286
|
+
function proposed_page(section, title, display_source) {
|
|
287
|
+
const clean_title = title.replace(/[#:]/gu, '').trim();
|
|
288
|
+
const path = `${section}/proposed/${slugify_title(clean_title)}`;
|
|
289
|
+
const frontmatter = serialize_frontmatter({
|
|
290
|
+
title: clean_title,
|
|
291
|
+
tags: [section.slice(0, -1), 'proposed', 'needs-review'],
|
|
292
|
+
status: 'review',
|
|
293
|
+
source_path: display_source,
|
|
294
|
+
});
|
|
295
|
+
return {
|
|
296
|
+
path,
|
|
297
|
+
body: `${frontmatter}# ${clean_title}\n\nProposed from [[${source_page_path(display_source)}|${display_source}]].\n\n## Notes\n\n- Needs human review before becoming a stable wiki page.\n`,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function extension(path) {
|
|
301
|
+
return path.slice(path.lastIndexOf('.')).toLowerCase();
|
|
302
|
+
}
|
|
303
|
+
function source_display_path(root, source) {
|
|
304
|
+
const relative_source = relative(root, source);
|
|
305
|
+
return relative_source.startsWith('..') || relative_source === ''
|
|
306
|
+
? source
|
|
307
|
+
: relative_source;
|
|
308
|
+
}
|
|
309
|
+
function source_fingerprint(source) {
|
|
310
|
+
try {
|
|
311
|
+
const stats = statSync(source);
|
|
312
|
+
if (!stats.isFile())
|
|
313
|
+
return null;
|
|
314
|
+
return createHash('sha256')
|
|
315
|
+
.update(readFileSync(source))
|
|
316
|
+
.digest('hex');
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
function existing_source_fingerprint(file_path) {
|
|
323
|
+
const fingerprint = parse_markdown(readFileSync(file_path, 'utf-8'))
|
|
324
|
+
.frontmatter.source_fingerprint;
|
|
325
|
+
return typeof fingerprint === 'string' && fingerprint.length > 0
|
|
326
|
+
? fingerprint
|
|
327
|
+
: null;
|
|
328
|
+
}
|
|
329
|
+
function existing_source_kind(file_path) {
|
|
330
|
+
const kind = parse_markdown(readFileSync(file_path, 'utf-8'))
|
|
331
|
+
.frontmatter.source_kind;
|
|
332
|
+
return kind === 'markdown' ||
|
|
333
|
+
kind === 'text' ||
|
|
334
|
+
kind === 'pdf' ||
|
|
335
|
+
kind === 'docx' ||
|
|
336
|
+
kind === 'unsupported'
|
|
337
|
+
? kind
|
|
338
|
+
: 'unsupported';
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=sync.js.map
|
package/dist/sync.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -155,11 +155,6 @@ export type WikiPlanOptions = {
|
|
|
155
155
|
scope?: string;
|
|
156
156
|
sources?: string[];
|
|
157
157
|
};
|
|
158
|
-
export type WikiBootstrapOptions = WikiPlanOptions & {
|
|
159
|
-
root?: string;
|
|
160
|
-
overwrite?: boolean;
|
|
161
|
-
ingest_sources?: boolean;
|
|
162
|
-
};
|
|
163
158
|
export type WikiPlanPage = {
|
|
164
159
|
title: string;
|
|
165
160
|
path: string;
|
|
@@ -173,18 +168,32 @@ export type WikiPlanResult = {
|
|
|
173
168
|
pages: WikiPlanPage[];
|
|
174
169
|
next_steps: string[];
|
|
175
170
|
};
|
|
176
|
-
export type
|
|
171
|
+
export type WikiDocumentSyncOptions = {
|
|
172
|
+
root?: string;
|
|
173
|
+
sources: string[];
|
|
174
|
+
overwrite?: boolean;
|
|
175
|
+
index?: boolean;
|
|
176
|
+
include?: string[];
|
|
177
|
+
ignore?: string[];
|
|
178
|
+
derive_facts?: boolean;
|
|
179
|
+
propose_pages?: boolean;
|
|
180
|
+
};
|
|
181
|
+
export type WikiDocumentSync = {
|
|
177
182
|
source: string;
|
|
178
183
|
page: string;
|
|
179
|
-
kind: '
|
|
184
|
+
kind: 'markdown' | 'text' | 'pdf' | 'docx' | 'unsupported';
|
|
185
|
+
status: 'created' | 'updated' | 'unchanged' | 'changed' | 'warning';
|
|
186
|
+
warnings: string[];
|
|
180
187
|
};
|
|
181
|
-
export type
|
|
188
|
+
export type WikiDocumentSyncResult = {
|
|
182
189
|
root: string;
|
|
183
|
-
|
|
190
|
+
sources: string[];
|
|
184
191
|
created: string[];
|
|
185
192
|
skipped: string[];
|
|
186
|
-
|
|
187
|
-
|
|
193
|
+
proposed_pages: string[];
|
|
194
|
+
derived_facts: Fact[];
|
|
195
|
+
synced_sources: WikiDocumentSync[];
|
|
196
|
+
indexed: IndexResult | null;
|
|
188
197
|
};
|
|
189
198
|
export type WikiEvent = {
|
|
190
199
|
id: number;
|
package/dist/workflow.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const wiki_building_workflow_markdown = "# Wiki building workflow\n\nUse this workflow when a user asks to
|
|
1
|
+
import type { WikiPlanOptions, WikiPlanResult } from './types.js';
|
|
2
|
+
export declare const wiki_building_workflow_markdown = "# Wiki building workflow\n\nUse this workflow when a user asks to plan, sync, generate, or improve a wiki from source material. A codebase is one source type; the same workflow applies to docs, notes, research, transcripts, or any mixed knowledge corpus.\n\n## Steps\n\n1. Clarify the source scope only if it is ambiguous.\n2. Inspect source material before writing pages.\n3. Propose a small page plan with names, purposes, and review flags.\n4. Create an index page that explains the corpus and links to major sections.\n5. Create focused pages for concepts, workflows, decisions, sources, and open questions.\n6. Use [[WikiLinks]] to connect related pages instead of duplicating context.\n7. Use frontmatter for title, aliases, tags, status, and review markers.\n8. Add structured facts for durable claims, decisions, or constraints.\n9. Run sync after source discovery, then index_wiki after page creation.\n10. Run lint_wiki and fix unresolved links or duplicate names.\n11. Run review_wiki and surface pages that still need human review.\n\n## Quality bar\n\n- Prefer many focused pages over one giant dump.\n- Mark uncertain pages with needs-review instead of inventing confidence.\n- Preserve citations or source paths when facts come from external material.\n- Make the wiki navigable for humans and retrievable for agents.\n";
|
|
3
3
|
export declare function plan_wiki(options?: WikiPlanOptions): WikiPlanResult;
|
|
4
|
-
export declare function bootstrap_wiki(options?: WikiBootstrapOptions): WikiBootstrapResult;
|
package/dist/workflow.js
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import { existsSync, readFileSync, readdirSync, statSync, } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { log_wiki_event } from './events.js';
|
|
4
|
-
import { index_wiki } from './indexer.js';
|
|
5
|
-
import { serialize_frontmatter } from './markdown.js';
|
|
6
|
-
import { create_page } from './pages.js';
|
|
7
|
-
import { page_file_path, resolve_wiki_root } from './paths.js';
|
|
8
1
|
export const wiki_building_workflow_markdown = `# Wiki building workflow
|
|
9
2
|
|
|
10
|
-
Use this workflow when a user asks to
|
|
3
|
+
Use this workflow when a user asks to plan, sync, generate, or improve a wiki from source material. A codebase is one source type; the same workflow applies to docs, notes, research, transcripts, or any mixed knowledge corpus.
|
|
11
4
|
|
|
12
5
|
## Steps
|
|
13
6
|
|
|
@@ -19,7 +12,7 @@ Use this workflow when a user asks to build, bootstrap, generate, or improve a w
|
|
|
19
12
|
6. Use [[WikiLinks]] to connect related pages instead of duplicating context.
|
|
20
13
|
7. Use frontmatter for title, aliases, tags, status, and review markers.
|
|
21
14
|
8. Add structured facts for durable claims, decisions, or constraints.
|
|
22
|
-
9. Run index_wiki after page creation.
|
|
15
|
+
9. Run sync after source discovery, then index_wiki after page creation.
|
|
23
16
|
10. Run lint_wiki and fix unresolved links or duplicate names.
|
|
24
17
|
11. Run review_wiki and surface pages that still need human review.
|
|
25
18
|
|
|
@@ -120,182 +113,4 @@ export function plan_wiki(options = {}) {
|
|
|
120
113
|
],
|
|
121
114
|
};
|
|
122
115
|
}
|
|
123
|
-
export function bootstrap_wiki(options = {}) {
|
|
124
|
-
const root = resolve_wiki_root(options.root);
|
|
125
|
-
const plan = plan_wiki(options);
|
|
126
|
-
const created = [];
|
|
127
|
-
const skipped = [];
|
|
128
|
-
const detected_sources = detect_source_inventory(root, plan.source_type, options.sources, plan.scope);
|
|
129
|
-
for (const page of plan.pages) {
|
|
130
|
-
if (!options.overwrite &&
|
|
131
|
-
existsSync(page_file_path(page.path, root))) {
|
|
132
|
-
skipped.push(page.path);
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
create_page(page.path, page_template(page, plan, detected_sources), {
|
|
136
|
-
root,
|
|
137
|
-
overwrite: options.overwrite,
|
|
138
|
-
});
|
|
139
|
-
created.push(page.path);
|
|
140
|
-
}
|
|
141
|
-
const ingested_sources = options.ingest_sources
|
|
142
|
-
? ingest_sources(root, detected_sources, options.overwrite, created, skipped)
|
|
143
|
-
: [];
|
|
144
|
-
const indexed = index_wiki(root);
|
|
145
|
-
log_wiki_event({
|
|
146
|
-
root,
|
|
147
|
-
operation: 'bootstrap_wiki',
|
|
148
|
-
summary: `Bootstrapped ${created.length} pages and ${ingested_sources.length} sources`,
|
|
149
|
-
target: root,
|
|
150
|
-
details: { created, skipped, ingested_sources },
|
|
151
|
-
});
|
|
152
|
-
return {
|
|
153
|
-
root,
|
|
154
|
-
plan,
|
|
155
|
-
created,
|
|
156
|
-
skipped,
|
|
157
|
-
ingested_sources: ingested_sources,
|
|
158
|
-
indexed,
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
function page_template(page, plan, detected_sources) {
|
|
162
|
-
if (page.path === 'index')
|
|
163
|
-
return index_template(page, plan);
|
|
164
|
-
const frontmatter = serialize_frontmatter({
|
|
165
|
-
title: page.title,
|
|
166
|
-
tags: page.tags,
|
|
167
|
-
});
|
|
168
|
-
if (page.path === 'sources/index') {
|
|
169
|
-
return `${frontmatter}# ${page.title}\n\n${page.purpose}\n\n## Source scope\n\n${plan.scope}\n\n## Detected sources\n\n${format_source_inventory(detected_sources)}\n\n## Ingestion notes\n\n- Record source paths, URLs, owners, and freshness before extracting durable facts.\n`;
|
|
170
|
-
}
|
|
171
|
-
if (page.path === 'questions/open-questions') {
|
|
172
|
-
return `${frontmatter}# ${page.title}\n\n${page.purpose}\n\n## Source scope\n\n${plan.scope}\n\n## Questions\n\n- What source material has not been inspected yet?\n- Which claims need citations or owner confirmation?\n- Which pages should move from needs-review to verified?\n`;
|
|
173
|
-
}
|
|
174
|
-
return `${frontmatter}# ${page.title}\n\n${page.purpose}\n\n## Source scope\n\n${plan.scope}\n\n## Evidence\n\n- Add source-backed details here with citations or file paths.\n\n## Candidate facts\n\n- Add durable claims here before promoting them with add_fact.\n`;
|
|
175
|
-
}
|
|
176
|
-
function index_template(page, plan) {
|
|
177
|
-
const frontmatter = serialize_frontmatter({
|
|
178
|
-
title: page.title,
|
|
179
|
-
tags: page.tags,
|
|
180
|
-
});
|
|
181
|
-
const links = plan.pages
|
|
182
|
-
.filter((planned_page) => planned_page.path !== page.path)
|
|
183
|
-
.map((planned_page) => `- [[${planned_page.path}|${planned_page.title}]] — ${planned_page.purpose}`)
|
|
184
|
-
.join('\n');
|
|
185
|
-
return `${frontmatter}# ${page.title}\n\nWiki for ${plan.scope}.\n\n## Start here\n\n${links}\n\n## Workflow\n\nUse [[workflows/index|Workflows]] to capture repeatable processes, [[sources/index|Sources]] to track inspected material, and [[questions/open-questions|Open questions]] for uncertain claims.\n`;
|
|
186
|
-
}
|
|
187
|
-
function detect_source_inventory(root, source_type, explicit_sources = [], scope = '') {
|
|
188
|
-
const candidates = ['README.md', 'package.json', 'docs'];
|
|
189
|
-
if (source_type === 'codebase')
|
|
190
|
-
candidates.push('packages');
|
|
191
|
-
const sources = [
|
|
192
|
-
...explicit_sources,
|
|
193
|
-
...extract_urls(scope),
|
|
194
|
-
];
|
|
195
|
-
for (const candidate of candidates) {
|
|
196
|
-
const candidate_path = join(root, candidate);
|
|
197
|
-
if (!existsSync(candidate_path))
|
|
198
|
-
continue;
|
|
199
|
-
if (candidate === 'packages') {
|
|
200
|
-
for (const entry of readdirSync(candidate_path, {
|
|
201
|
-
withFileTypes: true,
|
|
202
|
-
})) {
|
|
203
|
-
if (entry.isDirectory()) {
|
|
204
|
-
sources.push(`packages/${entry.name}/package.json`);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
continue;
|
|
208
|
-
}
|
|
209
|
-
sources.push(candidate);
|
|
210
|
-
}
|
|
211
|
-
return [...new Set(sources)];
|
|
212
|
-
}
|
|
213
|
-
function ingest_sources(root, sources, overwrite, created, skipped) {
|
|
214
|
-
const ingested = [];
|
|
215
|
-
for (const source of sources) {
|
|
216
|
-
const source_page = `sources/detected/${source_slug(source)}`;
|
|
217
|
-
if (!overwrite && existsSync(page_file_path(source_page, root))) {
|
|
218
|
-
skipped.push(source_page);
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
const source_kind = source.startsWith('http')
|
|
222
|
-
? 'url'
|
|
223
|
-
: existsSync(join(root, source))
|
|
224
|
-
? 'file'
|
|
225
|
-
: 'missing';
|
|
226
|
-
create_page(source_page, source_template(root, source, source_kind), {
|
|
227
|
-
root,
|
|
228
|
-
overwrite,
|
|
229
|
-
});
|
|
230
|
-
created.push(source_page);
|
|
231
|
-
ingested.push({
|
|
232
|
-
source,
|
|
233
|
-
page: `${source_page}.md`,
|
|
234
|
-
kind: source_kind,
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
return ingested;
|
|
238
|
-
}
|
|
239
|
-
function source_template(root, source, kind) {
|
|
240
|
-
const frontmatter = serialize_frontmatter({
|
|
241
|
-
title: `Source: ${source}`,
|
|
242
|
-
tags: ['source', kind],
|
|
243
|
-
status: kind === 'missing' ? 'review' : 'draft',
|
|
244
|
-
});
|
|
245
|
-
const source_path = join(root, source);
|
|
246
|
-
const excerpt = kind === 'file' ? source_excerpt(source_path) : '';
|
|
247
|
-
const candidate_facts = kind === 'file' ? source_candidate_facts(source_path) : [];
|
|
248
|
-
const evidence = kind === 'file'
|
|
249
|
-
? `## Extracted excerpt\n\n${excerpt}\n\n`
|
|
250
|
-
: kind === 'url'
|
|
251
|
-
? '## Extraction\n\n- URL ingestion is registered; fetch and summarize this source before promoting facts.\n\n'
|
|
252
|
-
: '## Extraction\n\n- Source was listed but not found locally; confirm the path or URL.\n\n';
|
|
253
|
-
return `${frontmatter}# Source: ${source}\n\nSource kind: ${kind}\n\n${evidence}## Candidate facts\n\n${format_candidate_facts(candidate_facts)}\n\n## Open questions\n\n- What claims from this source should become stable wiki pages?\n- What needs citation, owner confirmation, or freshness review?\n`;
|
|
254
|
-
}
|
|
255
|
-
function source_excerpt(file_path) {
|
|
256
|
-
const stats = statSync(file_path);
|
|
257
|
-
if (stats.isDirectory())
|
|
258
|
-
return '- Directory source; inspect child files before extracting facts.';
|
|
259
|
-
const content = readFileSync(file_path, 'utf-8')
|
|
260
|
-
.slice(0, 2000)
|
|
261
|
-
.trim();
|
|
262
|
-
return content.length > 0
|
|
263
|
-
? `\`\`\`\n${content}\n\`\`\``
|
|
264
|
-
: '- Source file is empty.';
|
|
265
|
-
}
|
|
266
|
-
function source_candidate_facts(file_path) {
|
|
267
|
-
const stats = statSync(file_path);
|
|
268
|
-
if (stats.isDirectory())
|
|
269
|
-
return [];
|
|
270
|
-
const lines = readFileSync(file_path, 'utf-8').split(/\r?\n/u);
|
|
271
|
-
return lines
|
|
272
|
-
.map((line, index) => ({
|
|
273
|
-
line: line.trim(),
|
|
274
|
-
line_number: index + 1,
|
|
275
|
-
}))
|
|
276
|
-
.filter(({ line }) => /\b(should|must|required|requirement|decision|constraint|risk|assumption|fact)\b/iu.test(line))
|
|
277
|
-
.slice(0, 10)
|
|
278
|
-
.map(({ line, line_number }) => `- Candidate from line ${line_number}: ${line}`);
|
|
279
|
-
}
|
|
280
|
-
function format_candidate_facts(candidate_facts) {
|
|
281
|
-
return candidate_facts.length > 0
|
|
282
|
-
? candidate_facts.join('\n')
|
|
283
|
-
: '- Review this source and promote durable claims with add_fact.';
|
|
284
|
-
}
|
|
285
|
-
function source_slug(source) {
|
|
286
|
-
return (source
|
|
287
|
-
.replace(/^https?:\/\//u, '')
|
|
288
|
-
.replace(/[^A-Za-z0-9]+/gu, '-')
|
|
289
|
-
.replace(/^-+|-+$/gu, '')
|
|
290
|
-
.toLowerCase() || 'source');
|
|
291
|
-
}
|
|
292
|
-
function extract_urls(scope) {
|
|
293
|
-
return scope.match(/https?:\/\/[^\s)]+/gu) ?? [];
|
|
294
|
-
}
|
|
295
|
-
function format_source_inventory(sources) {
|
|
296
|
-
if (sources.length === 0) {
|
|
297
|
-
return '- No local sources detected automatically; add source paths or URLs here.';
|
|
298
|
-
}
|
|
299
|
-
return sources.map((source) => `- \`${source}\``).join('\n');
|
|
300
|
-
}
|
|
301
116
|
//# sourceMappingURL=workflow.js.map
|
package/dist/workflow.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,+BAA+B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwB9C,CAAC;AAEF,MAAM,YAAY,GAAmB;IACpC;QACC,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,OAAO;QACb,OAAO,EACN,mEAAmE;QACpE,IAAI,EAAE,CAAC,OAAO,CAAC;KACf;IACD;QACC,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,sDAAsD;QAC/D,IAAI,EAAE,CAAC,SAAS,CAAC;KACjB;IACD;QACC,KAAK,EAAE,UAAU;QACjB,IAAI,EAAE,gBAAgB;QACtB,OAAO,EACN,2DAA2D;QAC5D,IAAI,EAAE,CAAC,UAAU,CAAC;KAClB;IACD;QACC,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,iBAAiB;QACvB,OAAO,EACN,2DAA2D;QAC5D,IAAI,EAAE,CAAC,UAAU,CAAC;KAClB;IACD;QACC,KAAK,EAAE,gBAAgB;QACvB,IAAI,EAAE,0BAA0B;QAChC,OAAO,EACN,6DAA6D;QAC9D,IAAI,EAAE,CAAC,cAAc,EAAE,WAAW,CAAC;KACnC;CACD,CAAC;AAEF,MAAM,YAAY,GAA2C;IAC5D,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE;QACT;YACC,KAAK,EAAE,uBAAuB;YAC9B,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EACN,oEAAoE;YACrE,IAAI,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC;SACtC;QACD;YACC,KAAK,EAAE,sBAAsB;YAC7B,IAAI,EAAE,gBAAgB;YACtB,OAAO,EACN,gEAAgE;YACjE,IAAI,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;SAC7B;KACD;IACD,IAAI,EAAE;QACL;YACC,KAAK,EAAE,mBAAmB;YAC1B,IAAI,EAAE,wBAAwB;YAC9B,OAAO,EACN,oEAAoE;YACrE,IAAI,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC;SACvC;KACD;IACD,QAAQ,EAAE;QACT;YACC,KAAK,EAAE,mBAAmB;YAC1B,IAAI,EAAE,mBAAmB;YACzB,OAAO,EACN,4DAA4D;YAC7D,IAAI,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC;SAClC;KACD;IACD,KAAK,EAAE;QACN;YACC,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,gBAAgB;YACtB,OAAO,EACN,0DAA0D;YAC3D,IAAI,EAAE,CAAC,OAAO,EAAE,cAAc,CAAC;SAC/B;KACD;CACD,CAAC;AAEF,MAAM,UAAU,SAAS,CACxB,UAA2B,EAAE;IAE7B,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,SAAS,CAAC;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,+BAA+B,CAAC;IAC/D,MAAM,KAAK,GAAG,CAAC,GAAG,YAAY,EAAE,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC;IAE9D,OAAO;QACN,WAAW,EAAE,WAAW;QACxB,KAAK;QACL,QAAQ,EAAE,+BAA+B;QACzC,KAAK;QACL,UAAU,EAAE;YACX,wEAAwE;YACxE,gFAAgF;YAChF,sDAAsD;YACtD,gEAAgE;SAChE;KACD,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wiki0/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Core wiki0 Markdown wiki indexing and retrieval primitives",
|
|
5
5
|
"homepage": "https://github.com/spences10/wiki0/tree/main/packages/core#readme",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
+
"mammoth": "^1.12.0",
|
|
31
|
+
"pdf-parse": "^2.4.5",
|
|
30
32
|
"yaml": "^2.9.0"
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|