@wiki0/core 0.0.3 → 0.0.4
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 +38 -23
- package/dist/events.d.ts +9 -0
- package/dist/events.js +56 -0
- package/dist/events.js.map +1 -0
- package/dist/facts.js +78 -16
- package/dist/facts.js.map +1 -1
- package/dist/graph.js +14 -2
- package/dist/graph.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/indexer.d.ts +11 -1
- package/dist/indexer.js +132 -21
- package/dist/indexer.js.map +1 -1
- package/dist/lint.js +1 -1
- package/dist/lint.js.map +1 -1
- package/dist/pages.js +25 -3
- package/dist/pages.js.map +1 -1
- package/dist/schema.sql +32 -0
- package/dist/search.d.ts +4 -2
- package/dist/search.js +162 -6
- package/dist/search.js.map +1 -1
- package/dist/topics.d.ts +2 -0
- package/dist/topics.js +55 -0
- package/dist/topics.js.map +1 -0
- package/dist/types.d.ts +67 -22
- package/dist/workflow.js +107 -9
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,9 +8,14 @@ Core wiki0 primitives for local-first Markdown wiki memory.
|
|
|
8
8
|
- Obsidian-style `[[WikiLinks]]` parsing.
|
|
9
9
|
- Page create/read/append/frontmatter operations.
|
|
10
10
|
- SQLite indexing and FTS search.
|
|
11
|
-
-
|
|
11
|
+
- Chunk-level context snippets with `wiki/path.md:line-line`
|
|
12
|
+
citations.
|
|
13
|
+
- Direct indexed chunk lookup for known `path:line` targets.
|
|
12
14
|
- Backlinks, graph data, lint results, review queues, and structured
|
|
13
|
-
facts.
|
|
15
|
+
facts with optional source-line provenance.
|
|
16
|
+
- Stale-index warnings in context responses.
|
|
17
|
+
- Lightweight topic threads and operation logs for agent workflows.
|
|
18
|
+
- Frontmatter-aware chunk ranking using priority, status, and tags.
|
|
14
19
|
- Wiki-building workflow planning for agents that need a deterministic
|
|
15
20
|
source-to-wiki recipe.
|
|
16
21
|
|
|
@@ -18,31 +23,41 @@ Core wiki0 primitives for local-first Markdown wiki memory.
|
|
|
18
23
|
|
|
19
24
|
```ts
|
|
20
25
|
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
} from
|
|
30
|
-
|
|
31
|
-
create_page(
|
|
32
|
-
|
|
26
|
+
bootstrap_wiki,
|
|
27
|
+
create_page,
|
|
28
|
+
index_status,
|
|
29
|
+
index_wiki,
|
|
30
|
+
search_wiki,
|
|
31
|
+
get_wiki_context,
|
|
32
|
+
lint_wiki,
|
|
33
|
+
plan_wiki,
|
|
34
|
+
} from '@wiki0/core';
|
|
35
|
+
|
|
36
|
+
create_page('projects/wiki0', 'Local-first [[topics/memory]].', {
|
|
37
|
+
root: '.',
|
|
33
38
|
});
|
|
34
|
-
index_wiki(
|
|
35
|
-
console.log(index_status(
|
|
36
|
-
console.log(search_wiki(
|
|
37
|
-
console.log(get_wiki_context(
|
|
38
|
-
console.log(lint_wiki(
|
|
39
|
-
console.log(
|
|
40
|
-
|
|
39
|
+
index_wiki('.');
|
|
40
|
+
console.log(index_status('.'));
|
|
41
|
+
console.log(search_wiki('memory', '.', 10));
|
|
42
|
+
console.log(get_wiki_context('what is wiki0?', '.', 5).markdown);
|
|
43
|
+
console.log(lint_wiki('.'));
|
|
44
|
+
console.log(
|
|
45
|
+
plan_wiki({ source_type: 'codebase', scope: 'current repo' }),
|
|
46
|
+
);
|
|
47
|
+
console.log(
|
|
48
|
+
bootstrap_wiki({
|
|
49
|
+
root: '.',
|
|
50
|
+
source_type: 'docs',
|
|
51
|
+
sources: ['docs/guide.md'],
|
|
52
|
+
ingest_sources: true,
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
41
55
|
```
|
|
42
56
|
|
|
43
57
|
## Storage model
|
|
44
58
|
|
|
45
59
|
Markdown files under `wiki/` are canonical. The `.wiki0/wiki0.sqlite`
|
|
46
60
|
database is a rebuildable cache for search, backlinks, graph data, and
|
|
47
|
-
facts. `index_status` reports indexed-at time, schema
|
|
48
|
-
stale reasons when Markdown
|
|
61
|
+
facts. `index_status` reports indexed-at time, schema/package
|
|
62
|
+
versions, and stale reasons when Markdown or index metadata has
|
|
63
|
+
changed since the last rebuild.
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WikiEvent } from './types.js';
|
|
2
|
+
export declare function log_wiki_event(options: {
|
|
3
|
+
root?: string;
|
|
4
|
+
operation: string;
|
|
5
|
+
summary: string;
|
|
6
|
+
target?: string;
|
|
7
|
+
details?: unknown;
|
|
8
|
+
}): WikiEvent;
|
|
9
|
+
export declare function list_wiki_events(root?: string, limit?: number): WikiEvent[];
|
package/dist/events.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { open_wiki_database } from './database.js';
|
|
2
|
+
import { resolve_wiki_root } from './paths.js';
|
|
3
|
+
export function log_wiki_event(options) {
|
|
4
|
+
const wiki_root = resolve_wiki_root(options.root);
|
|
5
|
+
const db = open_wiki_database(wiki_root);
|
|
6
|
+
ensure_events_table(db);
|
|
7
|
+
const result = db
|
|
8
|
+
.prepare(`INSERT INTO wiki_events (operation, summary, target, details)
|
|
9
|
+
VALUES (?, ?, ?, ?)`)
|
|
10
|
+
.run(options.operation, options.summary, options.target ?? null, options.details === undefined
|
|
11
|
+
? null
|
|
12
|
+
: JSON.stringify(options.details));
|
|
13
|
+
const event = select_event_by_id(db, Number(result.lastInsertRowid));
|
|
14
|
+
db.close();
|
|
15
|
+
return event;
|
|
16
|
+
}
|
|
17
|
+
export function list_wiki_events(root = '.', limit = 50) {
|
|
18
|
+
const db = open_wiki_database(root);
|
|
19
|
+
ensure_events_table(db);
|
|
20
|
+
const rows = db
|
|
21
|
+
.prepare(`SELECT id, operation, summary, target, details, created_at
|
|
22
|
+
FROM wiki_events
|
|
23
|
+
ORDER BY id DESC
|
|
24
|
+
LIMIT ?`)
|
|
25
|
+
.all(limit);
|
|
26
|
+
db.close();
|
|
27
|
+
return rows.map(event_from_row);
|
|
28
|
+
}
|
|
29
|
+
function select_event_by_id(db, id) {
|
|
30
|
+
const row = db
|
|
31
|
+
.prepare(`SELECT id, operation, summary, target, details, created_at
|
|
32
|
+
FROM wiki_events WHERE id = ?`)
|
|
33
|
+
.get(id);
|
|
34
|
+
return event_from_row(row);
|
|
35
|
+
}
|
|
36
|
+
function event_from_row(row) {
|
|
37
|
+
return {
|
|
38
|
+
id: Number(row.id),
|
|
39
|
+
operation: String(row.operation),
|
|
40
|
+
summary: String(row.summary),
|
|
41
|
+
target: row.target === null ? null : String(row.target),
|
|
42
|
+
details: row.details === null ? null : String(row.details),
|
|
43
|
+
created_at: String(row.created_at),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function ensure_events_table(db) {
|
|
47
|
+
db.exec(`CREATE TABLE IF NOT EXISTS wiki_events (
|
|
48
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
49
|
+
operation TEXT NOT NULL,
|
|
50
|
+
summary TEXT NOT NULL,
|
|
51
|
+
target TEXT,
|
|
52
|
+
details TEXT,
|
|
53
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
54
|
+
)`);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAqB,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAG/C,MAAM,UAAU,cAAc,CAAC,OAM9B;IACA,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACzC,mBAAmB,CAAC,EAAE,CAAC,CAAC;IACxB,MAAM,MAAM,GAAG,EAAE;SACf,OAAO,CACP;uBACoB,CACpB;SACA,GAAG,CACH,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,MAAM,IAAI,IAAI,EACtB,OAAO,CAAC,OAAO,KAAK,SAAS;QAC5B,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAClC,CAAC;IACH,MAAM,KAAK,GAAG,kBAAkB,CAC/B,EAAE,EACF,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAC9B,CAAC;IACF,EAAE,CAAC,KAAK,EAAE,CAAC;IACX,OAAO,KAAK,CAAC;AACd,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC/B,IAAI,GAAG,GAAG,EACV,KAAK,GAAG,EAAE;IAEV,MAAM,EAAE,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACpC,mBAAmB,CAAC,EAAE,CAAC,CAAC;IACxB,MAAM,IAAI,GAAG,EAAE;SACb,OAAO,CACP;;;WAGQ,CACR;SACA,GAAG,CAAC,KAAK,CAAqC,CAAC;IACjD,EAAE,CAAC,KAAK,EAAE,CAAC;IACX,OAAO,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,kBAAkB,CAAC,EAAgB,EAAE,EAAU;IACvD,MAAM,GAAG,GAAG,EAAE;SACZ,OAAO,CACP;iCAC8B,CAC9B;SACA,GAAG,CAAC,EAAE,CAAmC,CAAC;IAC5C,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,cAAc,CACtB,GAAmC;IAEnC,OAAO;QACN,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;QAChC,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;QAC5B,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;QACvD,OAAO,EAAE,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;QAC1D,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;KAClC,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,EAAgB;IAC5C,EAAE,CAAC,IAAI,CAAC;;;;;;;GAON,CAAC,CAAC;AACL,CAAC"}
|
package/dist/facts.js
CHANGED
|
@@ -1,43 +1,105 @@
|
|
|
1
1
|
import { open_wiki_database } from './database.js';
|
|
2
|
+
import { log_wiki_event } from './events.js';
|
|
2
3
|
import { resolve_page_path } from './pages.js';
|
|
3
4
|
import { resolve_wiki_root } from './paths.js';
|
|
5
|
+
import { show_wiki_chunk } from './search.js';
|
|
4
6
|
export function add_fact(fact) {
|
|
5
7
|
const wiki_root = resolve_wiki_root(fact.root);
|
|
6
8
|
const db = open_wiki_database(wiki_root);
|
|
9
|
+
ensure_fact_provenance_columns(db);
|
|
10
|
+
const source_chunk = fact.source
|
|
11
|
+
? show_wiki_chunk(fact.source, wiki_root)
|
|
12
|
+
: null;
|
|
7
13
|
const page_path = fact.page
|
|
8
14
|
? resolve_page_path(fact.page, wiki_root)
|
|
9
|
-
: null;
|
|
15
|
+
: (source_chunk?.path ?? null);
|
|
10
16
|
const page = page_path
|
|
11
17
|
? db
|
|
12
18
|
.prepare('SELECT id FROM pages WHERE path = ?')
|
|
13
19
|
.get(page_path)
|
|
14
20
|
: undefined;
|
|
15
21
|
const result = db
|
|
16
|
-
.prepare(`INSERT INTO facts (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
LEFT JOIN pages ON pages.id = facts.page_id
|
|
24
|
-
WHERE facts.id = ?`)
|
|
25
|
-
.get(result.lastInsertRowid);
|
|
22
|
+
.prepare(`INSERT INTO facts (
|
|
23
|
+
page_id, category, summary, body, confidence,
|
|
24
|
+
source_path, source_heading, source_start_line, source_end_line, source_quote
|
|
25
|
+
)
|
|
26
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
27
|
+
.run(page?.id ?? null, fact.category, fact.summary, fact.body ?? null, fact.confidence ?? 'unknown', source_chunk?.path ?? null, source_chunk?.heading ?? null, source_chunk?.start_line ?? null, source_chunk?.end_line ?? null, fact.source_quote ?? source_quote(source_chunk));
|
|
28
|
+
const inserted = select_fact_by_id(db, Number(result.lastInsertRowid));
|
|
26
29
|
db.close();
|
|
30
|
+
log_wiki_event({
|
|
31
|
+
root: wiki_root,
|
|
32
|
+
operation: 'add_fact',
|
|
33
|
+
summary: fact.summary,
|
|
34
|
+
target: page_path ?? source_chunk?.path ?? undefined,
|
|
35
|
+
details: {
|
|
36
|
+
category: fact.category,
|
|
37
|
+
confidence: inserted.confidence,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
27
40
|
return inserted;
|
|
28
41
|
}
|
|
29
42
|
export function list_facts(root = '.', category) {
|
|
30
43
|
const db = open_wiki_database(root);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
FROM facts
|
|
34
|
-
LEFT JOIN pages ON pages.id = facts.page_id
|
|
44
|
+
ensure_fact_provenance_columns(db);
|
|
45
|
+
const sql = `${fact_select_sql}
|
|
35
46
|
${category ? 'WHERE facts.category = ?' : ''}
|
|
36
47
|
ORDER BY facts.created_at DESC, facts.id DESC`;
|
|
37
48
|
const rows = category
|
|
38
49
|
? db.prepare(sql).all(category)
|
|
39
50
|
: db.prepare(sql).all();
|
|
40
51
|
db.close();
|
|
41
|
-
return rows;
|
|
52
|
+
return rows.map(fact_from_row);
|
|
53
|
+
}
|
|
54
|
+
const fact_select_sql = `SELECT facts.id, pages.path AS page_path, facts.category,
|
|
55
|
+
facts.summary, facts.body, facts.confidence,
|
|
56
|
+
facts.source_path, facts.source_heading, facts.source_start_line,
|
|
57
|
+
facts.source_end_line, facts.source_quote, facts.created_at AS created_at
|
|
58
|
+
FROM facts
|
|
59
|
+
LEFT JOIN pages ON pages.id = facts.page_id`;
|
|
60
|
+
function select_fact_by_id(db, id) {
|
|
61
|
+
const row = db
|
|
62
|
+
.prepare(`${fact_select_sql} WHERE facts.id = ?`)
|
|
63
|
+
.get(id);
|
|
64
|
+
return fact_from_row(row);
|
|
65
|
+
}
|
|
66
|
+
function fact_from_row(row) {
|
|
67
|
+
return {
|
|
68
|
+
id: Number(row.id),
|
|
69
|
+
page_path: row.page_path === null ? null : String(row.page_path),
|
|
70
|
+
category: String(row.category),
|
|
71
|
+
summary: String(row.summary),
|
|
72
|
+
body: row.body === null ? null : String(row.body),
|
|
73
|
+
confidence: String(row.confidence),
|
|
74
|
+
source_path: row.source_path === null ? null : String(row.source_path),
|
|
75
|
+
source_heading: row.source_heading === null ? null : String(row.source_heading),
|
|
76
|
+
source_start_line: row.source_start_line === null
|
|
77
|
+
? null
|
|
78
|
+
: Number(row.source_start_line),
|
|
79
|
+
source_end_line: row.source_end_line === null
|
|
80
|
+
? null
|
|
81
|
+
: Number(row.source_end_line),
|
|
82
|
+
source_quote: row.source_quote === null ? null : String(row.source_quote),
|
|
83
|
+
created_at: String(row.created_at),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function source_quote(source_chunk) {
|
|
87
|
+
if (!source_chunk)
|
|
88
|
+
return null;
|
|
89
|
+
return source_chunk.body.slice(0, 1000);
|
|
90
|
+
}
|
|
91
|
+
function ensure_fact_provenance_columns(db) {
|
|
92
|
+
const columns = new Set(db.prepare('PRAGMA table_info(facts)').all().map((column) => column.name));
|
|
93
|
+
const migrations = {
|
|
94
|
+
source_path: 'ALTER TABLE facts ADD COLUMN source_path TEXT',
|
|
95
|
+
source_heading: 'ALTER TABLE facts ADD COLUMN source_heading TEXT',
|
|
96
|
+
source_start_line: 'ALTER TABLE facts ADD COLUMN source_start_line INTEGER',
|
|
97
|
+
source_end_line: 'ALTER TABLE facts ADD COLUMN source_end_line INTEGER',
|
|
98
|
+
source_quote: 'ALTER TABLE facts ADD COLUMN source_quote TEXT',
|
|
99
|
+
};
|
|
100
|
+
for (const [column_name, sql] of Object.entries(migrations)) {
|
|
101
|
+
if (!columns.has(column_name))
|
|
102
|
+
db.exec(sql);
|
|
103
|
+
}
|
|
42
104
|
}
|
|
43
105
|
//# sourceMappingURL=facts.js.map
|
package/dist/facts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facts.js","sourceRoot":"","sources":["../src/facts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"facts.js","sourceRoot":"","sources":["../src/facts.ts"],"names":[],"mappings":"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"}
|
package/dist/graph.js
CHANGED
|
@@ -6,11 +6,11 @@ export function graph_wiki(root = '.') {
|
|
|
6
6
|
const nodes = db
|
|
7
7
|
.prepare('SELECT path, title FROM pages ORDER BY path')
|
|
8
8
|
.all();
|
|
9
|
-
const
|
|
9
|
+
const edge_rows = db
|
|
10
10
|
.prepare(`SELECT pages.path AS "from",
|
|
11
11
|
COALESCE(page_links.to_path, page_links.target) AS "to",
|
|
12
12
|
page_links.target,
|
|
13
|
-
page_links.raw_text AS
|
|
13
|
+
page_links.raw_text AS raw_text,
|
|
14
14
|
page_links.alias,
|
|
15
15
|
page_links.embed,
|
|
16
16
|
page_links.status
|
|
@@ -19,6 +19,7 @@ export function graph_wiki(root = '.') {
|
|
|
19
19
|
ORDER BY pages.path, page_links.target`)
|
|
20
20
|
.all();
|
|
21
21
|
db.close();
|
|
22
|
+
const edges = edge_rows.map(graph_edge_from_row);
|
|
22
23
|
return {
|
|
23
24
|
root: wiki_root,
|
|
24
25
|
nodes,
|
|
@@ -31,4 +32,15 @@ export function graph_wiki(root = '.') {
|
|
|
31
32
|
})),
|
|
32
33
|
};
|
|
33
34
|
}
|
|
35
|
+
function graph_edge_from_row(row) {
|
|
36
|
+
return {
|
|
37
|
+
from: String(row.from),
|
|
38
|
+
to: String(row.to),
|
|
39
|
+
target: String(row.target),
|
|
40
|
+
raw_text: String(row.raw_text),
|
|
41
|
+
alias: row.alias === null ? null : String(row.alias),
|
|
42
|
+
embed: Boolean(row.embed),
|
|
43
|
+
status: row.status === 'resolved' ? 'resolved' : 'unresolved',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
34
46
|
//# sourceMappingURL=graph.js.map
|
package/dist/graph.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGrE,MAAM,UAAU,UAAU,CAAC,IAAI,GAAG,GAAG;IACpC,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,EAAE;SACd,OAAO,CAAC,6CAA6C,CAAC;SACtD,GAAG,EAAiB,CAAC;IACvB,MAAM,SAAS,GAAG,EAAE;SAClB,OAAO,CACP;;;;;;;;;0CASuC,CACvC;SACA,GAAG,EAAsC,CAAC;IAC5C,EAAE,CAAC,KAAK,EAAE,CAAC;IAEX,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjD,OAAO;QACN,IAAI,EAAE,SAAS;QACf,KAAK;QACL,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC3B,GAAG,IAAI;YACP,EAAE,EACD,IAAI,CAAC,MAAM,KAAK,UAAU;gBACzB,CAAC,CAAC,IAAI,CAAC,EAAE;gBACT,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC;YACrC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;SAC1B,CAAC,CAAC;KACH,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAC3B,GAAmC;IAEnC,OAAO;QACN,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;QACtB,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;QAC1B,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC9B,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;QACpD,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QACzB,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY;KAC7D,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
export { open_wiki_database, wiki_db_path } from './database.js';
|
|
2
|
+
export { list_wiki_events, log_wiki_event } from './events.js';
|
|
2
3
|
export { add_fact, list_facts } from './facts.js';
|
|
3
4
|
export { graph_wiki } from './graph.js';
|
|
4
|
-
export { current_index_schema_version, index_status, index_wiki, } from './indexer.js';
|
|
5
|
+
export { current_index_package_version, current_index_schema_version, index_status, index_wiki, } from './indexer.js';
|
|
5
6
|
export { lint_wiki } from './lint.js';
|
|
6
7
|
export { page_title_from_markdown, parse_frontmatter, parse_markdown, parse_wikilinks, serialize_frontmatter, strip_fenced_code_blocks, strip_inline_code, } from './markdown.js';
|
|
7
8
|
export { append_page, create_page, list_markdown_page_paths, read_page, resolve_page_path, set_page_frontmatter, } from './pages.js';
|
|
8
9
|
export { display_page_title, page_file_path, page_relative_path, resolve_wiki_root, slugify_title, wikilink_target_path, } from './paths.js';
|
|
9
10
|
export { review_wiki } from './review.js';
|
|
10
11
|
export { schema_sql } from './schema.js';
|
|
11
|
-
export { backlinks_for_page, format_context_markdown, get_wiki_context, search_wiki, } from './search.js';
|
|
12
|
+
export { backlinks_for_page, format_context_markdown, get_wiki_context, search_wiki, search_wiki_chunks, show_wiki_chunk, } from './search.js';
|
|
13
|
+
export { list_topic_threads } from './topics.js';
|
|
12
14
|
export type * from './types.js';
|
|
13
15
|
export { bootstrap_wiki, plan_wiki, wiki_building_workflow_markdown, } from './workflow.js';
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
export { open_wiki_database, wiki_db_path } from './database.js';
|
|
2
|
+
export { list_wiki_events, log_wiki_event } from './events.js';
|
|
2
3
|
export { add_fact, list_facts } from './facts.js';
|
|
3
4
|
export { graph_wiki } from './graph.js';
|
|
4
|
-
export { current_index_schema_version, index_status, index_wiki, } from './indexer.js';
|
|
5
|
+
export { current_index_package_version, current_index_schema_version, index_status, index_wiki, } from './indexer.js';
|
|
5
6
|
export { lint_wiki } from './lint.js';
|
|
6
7
|
export { page_title_from_markdown, parse_frontmatter, parse_markdown, parse_wikilinks, serialize_frontmatter, strip_fenced_code_blocks, strip_inline_code, } from './markdown.js';
|
|
7
8
|
export { append_page, create_page, list_markdown_page_paths, read_page, resolve_page_path, set_page_frontmatter, } from './pages.js';
|
|
8
9
|
export { display_page_title, page_file_path, page_relative_path, resolve_wiki_root, slugify_title, wikilink_target_path, } from './paths.js';
|
|
9
10
|
export { review_wiki } from './review.js';
|
|
10
11
|
export { schema_sql } from './schema.js';
|
|
11
|
-
export { backlinks_for_page, format_context_markdown, get_wiki_context, search_wiki, } from './search.js';
|
|
12
|
+
export { backlinks_for_page, format_context_markdown, get_wiki_context, search_wiki, search_wiki_chunks, show_wiki_chunk, } from './search.js';
|
|
13
|
+
export { list_topic_threads } from './topics.js';
|
|
12
14
|
export { bootstrap_wiki, plan_wiki, wiki_building_workflow_markdown, } from './workflow.js';
|
|
13
15
|
//# 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,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EACN,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,
|
|
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,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAClD,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,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EACN,cAAc,EACd,SAAS,EACT,+BAA+B,GAC/B,MAAM,eAAe,CAAC"}
|
package/dist/indexer.d.ts
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import type { IndexResult, IndexStatus } from './types.js';
|
|
2
|
-
export declare const current_index_schema_version =
|
|
2
|
+
export declare const current_index_schema_version = 4;
|
|
3
|
+
export declare const current_index_package_version: string;
|
|
3
4
|
export declare function index_wiki(root?: string): IndexResult;
|
|
5
|
+
type PageChunk = {
|
|
6
|
+
heading: string | null;
|
|
7
|
+
body: string;
|
|
8
|
+
start_line: number;
|
|
9
|
+
end_line: number;
|
|
10
|
+
sequence: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function chunk_page_body(body: string): PageChunk[];
|
|
4
13
|
export declare function index_status(root?: string): IndexStatus;
|
|
14
|
+
export {};
|
package/dist/indexer.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
|
-
import { existsSync, statSync } from 'node:fs';
|
|
2
|
+
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { open_wiki_database, wiki_db_path } from './database.js';
|
|
5
|
+
import { log_wiki_event } from './events.js';
|
|
5
6
|
import { list_markdown_page_paths, read_page_by_path, } from './pages.js';
|
|
6
7
|
import { resolve_wiki_root, wikilink_target_path } from './paths.js';
|
|
7
|
-
export const current_index_schema_version =
|
|
8
|
+
export const current_index_schema_version = 4;
|
|
9
|
+
export const current_index_package_version = read_package_version();
|
|
8
10
|
export function index_wiki(root = '.') {
|
|
9
11
|
const wiki_root = resolve_wiki_root(root);
|
|
10
12
|
const db_path = wiki_db_path(wiki_root);
|
|
11
13
|
const db = open_wiki_database(wiki_root);
|
|
14
|
+
ensure_index_schema(db);
|
|
12
15
|
let page_count = 0;
|
|
13
16
|
let link_count = 0;
|
|
14
17
|
const upsert_page = db.prepare(`
|
|
@@ -28,7 +31,17 @@ export function index_wiki(root = '.') {
|
|
|
28
31
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
29
32
|
`);
|
|
30
33
|
const clear_fts = db.prepare('DELETE FROM fts_pages');
|
|
34
|
+
const clear_chunks = db.prepare('DELETE FROM page_chunks');
|
|
35
|
+
const clear_chunk_fts = db.prepare('DELETE FROM fts_page_chunks');
|
|
31
36
|
const insert_fts = db.prepare('INSERT INTO fts_pages (path, title, body) VALUES (?, ?, ?)');
|
|
37
|
+
const insert_chunk = db.prepare(`
|
|
38
|
+
INSERT INTO page_chunks (
|
|
39
|
+
page_id, path, title, heading, body, start_line, end_line,
|
|
40
|
+
sequence, page_priority, page_status, page_tags
|
|
41
|
+
)
|
|
42
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
43
|
+
`);
|
|
44
|
+
const insert_chunk_fts = db.prepare('INSERT INTO fts_page_chunks (chunk_id, path, title, heading, body) VALUES (?, ?, ?, ?, ?)');
|
|
32
45
|
const set_meta = db.prepare(`
|
|
33
46
|
INSERT INTO wiki_meta (key, value, updated_at)
|
|
34
47
|
VALUES (?, ?, datetime('now'))
|
|
@@ -58,6 +71,8 @@ export function index_wiki(root = '.') {
|
|
|
58
71
|
try {
|
|
59
72
|
indexed_at = new Date().toISOString();
|
|
60
73
|
clear_fts.run();
|
|
74
|
+
clear_chunks.run();
|
|
75
|
+
clear_chunk_fts.run();
|
|
61
76
|
for (const page of pages) {
|
|
62
77
|
const file_path = join(wiki_root, 'wiki', page.path);
|
|
63
78
|
const modified_at = statSync(file_path).mtime.toISOString();
|
|
@@ -84,6 +99,13 @@ export function index_wiki(root = '.') {
|
|
|
84
99
|
link_count += 1;
|
|
85
100
|
}
|
|
86
101
|
insert_fts.run(page.path, page.title, page.content);
|
|
102
|
+
const page_priority = frontmatter_number(page.frontmatter.priority);
|
|
103
|
+
const page_status = frontmatter_string(page.frontmatter.status);
|
|
104
|
+
const page_tags = frontmatter_string_array(page.frontmatter.tags);
|
|
105
|
+
for (const chunk of chunk_page_body(page.body)) {
|
|
106
|
+
const chunk_result = insert_chunk.run(row.id, page.path, page.title, chunk.heading, chunk.body, chunk.start_line, chunk.end_line, chunk.sequence, page_priority, page_status, JSON.stringify(page_tags));
|
|
107
|
+
insert_chunk_fts.run(chunk_result.lastInsertRowid, page.path, page.title, chunk.heading, chunk.body);
|
|
108
|
+
}
|
|
87
109
|
page_count += 1;
|
|
88
110
|
}
|
|
89
111
|
const placeholders = [...known_paths].map(() => '?').join(', ');
|
|
@@ -95,6 +117,7 @@ export function index_wiki(root = '.') {
|
|
|
95
117
|
}
|
|
96
118
|
set_meta.run('indexed_at', indexed_at);
|
|
97
119
|
set_meta.run('schema_version', String(current_index_schema_version));
|
|
120
|
+
set_meta.run('package_version', current_index_package_version);
|
|
98
121
|
db.exec('COMMIT');
|
|
99
122
|
}
|
|
100
123
|
catch (error) {
|
|
@@ -102,14 +125,85 @@ export function index_wiki(root = '.') {
|
|
|
102
125
|
throw error;
|
|
103
126
|
}
|
|
104
127
|
db.close();
|
|
128
|
+
log_wiki_event({
|
|
129
|
+
root: wiki_root,
|
|
130
|
+
operation: 'index_wiki',
|
|
131
|
+
summary: `Indexed ${page_count} pages and ${link_count} links`,
|
|
132
|
+
target: wiki_root,
|
|
133
|
+
details: {
|
|
134
|
+
page_count,
|
|
135
|
+
link_count,
|
|
136
|
+
schema_version: current_index_schema_version,
|
|
137
|
+
},
|
|
138
|
+
});
|
|
105
139
|
return {
|
|
106
140
|
root: wiki_root,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
141
|
+
db_path: db_path,
|
|
142
|
+
page_count: page_count,
|
|
143
|
+
link_count: link_count,
|
|
144
|
+
indexed_at: indexed_at,
|
|
145
|
+
schema_version: current_index_schema_version,
|
|
146
|
+
package_version: current_index_package_version,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function ensure_index_schema(db) {
|
|
150
|
+
const chunk_columns = new Set(db.prepare('PRAGMA table_info(page_chunks)').all().map((column) => column.name));
|
|
151
|
+
const migrations = {
|
|
152
|
+
page_priority: 'ALTER TABLE page_chunks ADD COLUMN page_priority INTEGER NOT NULL DEFAULT 0',
|
|
153
|
+
page_status: 'ALTER TABLE page_chunks ADD COLUMN page_status TEXT',
|
|
154
|
+
page_tags: 'ALTER TABLE page_chunks ADD COLUMN page_tags TEXT',
|
|
112
155
|
};
|
|
156
|
+
for (const [column_name, sql] of Object.entries(migrations)) {
|
|
157
|
+
if (!chunk_columns.has(column_name))
|
|
158
|
+
db.exec(sql);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
export function chunk_page_body(body) {
|
|
162
|
+
const lines = body.split(/\r?\n/u);
|
|
163
|
+
const heading_lines = lines
|
|
164
|
+
.map((line, index) => ({ line, index }))
|
|
165
|
+
.filter(({ line }) => /^#{1,6}\s+\S/u.test(line));
|
|
166
|
+
if (heading_lines.length === 0) {
|
|
167
|
+
return [
|
|
168
|
+
{
|
|
169
|
+
heading: null,
|
|
170
|
+
body: body.trim(),
|
|
171
|
+
start_line: 1,
|
|
172
|
+
end_line: Math.max(lines.length, 1),
|
|
173
|
+
sequence: 0,
|
|
174
|
+
},
|
|
175
|
+
];
|
|
176
|
+
}
|
|
177
|
+
return heading_lines.map((heading, sequence) => {
|
|
178
|
+
const next_heading = heading_lines[sequence + 1];
|
|
179
|
+
const end_index = next_heading
|
|
180
|
+
? next_heading.index - 1
|
|
181
|
+
: lines.length - 1;
|
|
182
|
+
return {
|
|
183
|
+
heading: heading.line.replace(/^#{1,6}\s+/u, '').trim(),
|
|
184
|
+
body: lines
|
|
185
|
+
.slice(heading.index, end_index + 1)
|
|
186
|
+
.join('\n')
|
|
187
|
+
.trim(),
|
|
188
|
+
start_line: heading.index + 1,
|
|
189
|
+
end_line: end_index + 1,
|
|
190
|
+
sequence,
|
|
191
|
+
};
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
function frontmatter_string(value) {
|
|
195
|
+
return typeof value === 'string' ? value : null;
|
|
196
|
+
}
|
|
197
|
+
function frontmatter_number(value) {
|
|
198
|
+
return typeof value === 'number' && Number.isFinite(value)
|
|
199
|
+
? value
|
|
200
|
+
: 0;
|
|
201
|
+
}
|
|
202
|
+
function frontmatter_string_array(value) {
|
|
203
|
+
if (Array.isArray(value)) {
|
|
204
|
+
return value.filter((item) => typeof item === 'string');
|
|
205
|
+
}
|
|
206
|
+
return typeof value === 'string' ? [value] : [];
|
|
113
207
|
}
|
|
114
208
|
export function index_status(root = '.') {
|
|
115
209
|
const wiki_root = resolve_wiki_root(root);
|
|
@@ -119,13 +213,15 @@ export function index_status(root = '.') {
|
|
|
119
213
|
if (!existsSync(db_path)) {
|
|
120
214
|
return {
|
|
121
215
|
root: wiki_root,
|
|
122
|
-
|
|
216
|
+
db_path: db_path,
|
|
123
217
|
exists: false,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
218
|
+
indexed_at: null,
|
|
219
|
+
schema_version: null,
|
|
220
|
+
current_schema_version: current_index_schema_version,
|
|
221
|
+
package_version: null,
|
|
222
|
+
current_package_version: current_index_package_version,
|
|
223
|
+
page_count: page_paths.length,
|
|
224
|
+
indexed_page_count: 0,
|
|
129
225
|
stale: true,
|
|
130
226
|
reasons: ['missing-index'],
|
|
131
227
|
};
|
|
@@ -137,9 +233,10 @@ export function index_status(root = '.') {
|
|
|
137
233
|
const meta = new Map(meta_rows.map((row) => [row.key, row.value]));
|
|
138
234
|
const indexed_at = meta.get('indexed_at') ?? null;
|
|
139
235
|
const schema_version = Number(meta.get('schema_version') ?? NaN);
|
|
236
|
+
const package_version = meta.get('package_version') ?? null;
|
|
140
237
|
const indexed_page_count = db.prepare('SELECT COUNT(*) AS count FROM pages').get().count;
|
|
141
238
|
const indexed_pages = db
|
|
142
|
-
.prepare('SELECT path, content_hash AS
|
|
239
|
+
.prepare('SELECT path, content_hash AS content_hash FROM pages')
|
|
143
240
|
.all();
|
|
144
241
|
db.close();
|
|
145
242
|
if (!indexed_at)
|
|
@@ -147,11 +244,14 @@ export function index_status(root = '.') {
|
|
|
147
244
|
if (schema_version !== current_index_schema_version) {
|
|
148
245
|
reasons.push('schema-version-mismatch');
|
|
149
246
|
}
|
|
247
|
+
if (package_version !== current_index_package_version) {
|
|
248
|
+
reasons.push('package-version-mismatch');
|
|
249
|
+
}
|
|
150
250
|
if (indexed_page_count !== page_paths.length) {
|
|
151
251
|
reasons.push('page-count-changed');
|
|
152
252
|
}
|
|
153
253
|
const current_paths = new Set(page_paths);
|
|
154
|
-
const indexed_hashes = new Map(indexed_pages.map((page) => [page.path, page.
|
|
254
|
+
const indexed_hashes = new Map(indexed_pages.map((page) => [page.path, page.content_hash]));
|
|
155
255
|
for (const page of indexed_pages) {
|
|
156
256
|
if (!current_paths.has(page.path))
|
|
157
257
|
reasons.push('deleted-pages');
|
|
@@ -169,17 +269,28 @@ export function index_status(root = '.') {
|
|
|
169
269
|
}
|
|
170
270
|
return {
|
|
171
271
|
root: wiki_root,
|
|
172
|
-
|
|
272
|
+
db_path: db_path,
|
|
173
273
|
exists: true,
|
|
174
|
-
|
|
175
|
-
|
|
274
|
+
indexed_at: indexed_at,
|
|
275
|
+
schema_version: Number.isNaN(schema_version)
|
|
176
276
|
? null
|
|
177
277
|
: schema_version,
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
278
|
+
current_schema_version: current_index_schema_version,
|
|
279
|
+
package_version: package_version,
|
|
280
|
+
current_package_version: current_index_package_version,
|
|
281
|
+
page_count: page_paths.length,
|
|
282
|
+
indexed_page_count: indexed_page_count,
|
|
181
283
|
stale: reasons.length > 0,
|
|
182
284
|
reasons: [...new Set(reasons)],
|
|
183
285
|
};
|
|
184
286
|
}
|
|
287
|
+
function read_package_version() {
|
|
288
|
+
try {
|
|
289
|
+
const package_json = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
|
|
290
|
+
return package_json.version ?? '0.0.0';
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
return '0.0.0';
|
|
294
|
+
}
|
|
295
|
+
}
|
|
185
296
|
//# sourceMappingURL=indexer.js.map
|