@hasna/knowledge 0.2.21 → 0.2.22
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 +16 -0
- package/bin/open-knowledge-mcp.js +583 -11
- package/bin/open-knowledge.js +140 -70
- package/docs/architecture/ai-native-knowledge-base.md +8 -0
- package/package.json +1 -1
- package/src/cli.ts +44 -6
- package/src/service.ts +44 -0
- package/src/wiki-compiler.ts +711 -0
|
@@ -207,6 +207,14 @@ The database catalog tracks every schema, index shard, log partition, wiki page,
|
|
|
207
207
|
source citation, and generated artifact. Markdown remains the readable layer;
|
|
208
208
|
SQLite/Postgres and object storage carry the scalable catalog.
|
|
209
209
|
|
|
210
|
+
The first compile/write loop is local and approval-gated. `wiki compile`
|
|
211
|
+
generates cited pages from derived source chunks, creates concept backlinks,
|
|
212
|
+
updates index rows, records storage objects, and appends dated JSONL logs.
|
|
213
|
+
`wiki file-answer` writes answer notes only with `--approve-write`; otherwise it
|
|
214
|
+
returns the dry-run proposal. `wiki lint` checks missing/stale citations,
|
|
215
|
+
duplicates, orphan pages, unresolved source refs, contradiction markers, and
|
|
216
|
+
new-article candidates.
|
|
217
|
+
|
|
210
218
|
## Search Model
|
|
211
219
|
|
|
212
220
|
Search is hybrid:
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -209,7 +209,8 @@ Commands:
|
|
|
209
209
|
remote contracts|status Inspect hosted client contracts/readiness
|
|
210
210
|
storage status|validate Inspect local/S3 artifact storage contract
|
|
211
211
|
db init|stats Initialize or inspect local knowledge.db
|
|
212
|
-
wiki init
|
|
212
|
+
wiki init|compile|file-answer|lint
|
|
213
|
+
Initialize, compile, file, or lint wiki artifacts
|
|
213
214
|
source resolve <source-ref> Resolve read-only source content and citation evidence
|
|
214
215
|
ingest manifest <file|s3://> Ingest an open-files manifest into knowledge.db
|
|
215
216
|
ingest source <source-ref> Ingest a read-only source ref into knowledge.db
|
|
@@ -303,7 +304,7 @@ function printCommandHelp(command: string): void {
|
|
|
303
304
|
if (command === 'remote') { console.log('Usage: open-knowledge remote contracts|status [--scope local|global|project] [--json]'); return; }
|
|
304
305
|
if (command === 'storage') { console.log('Usage: open-knowledge storage status|validate [--scope local|global|project] [--json]'); return; }
|
|
305
306
|
if (command === 'db') { console.log('Usage: open-knowledge db init|stats [--scope local|global|project] [--json]'); return; }
|
|
306
|
-
if (command === 'wiki') { console.log('Usage: open-knowledge wiki init [--scope local|global|project] [--json]'); return; }
|
|
307
|
+
if (command === 'wiki') { console.log('Usage: open-knowledge wiki init|compile|file-answer|lint [query|prompt] [--title <title>] [--content <answer>] [--approve-write] [--limit <n>] [--scope local|global|project] [--json]'); return; }
|
|
307
308
|
if (command === 'source') { console.log('Usage: open-knowledge source resolve <source-ref> [--purpose knowledge_answer|knowledge_index] [--limit <n>] [--scope local|global|project] [--json]'); return; }
|
|
308
309
|
if (command === 'ingest') { console.log('Usage: open-knowledge ingest manifest <file|s3://bucket/key> | source <source-ref> [--purpose knowledge_index] [--scope local|global|project] [--json]'); return; }
|
|
309
310
|
if (command === 'reindex') { console.log('Usage: open-knowledge reindex status|enqueue|embeddings|outbox [file|s3://bucket/key] [--full] [--fake] [--scope local|global|project] [--json]'); return; }
|
|
@@ -512,10 +513,47 @@ async function run(argv: string[]): Promise<void> {
|
|
|
512
513
|
|
|
513
514
|
if (command === 'wiki') {
|
|
514
515
|
const action = positional[1] ?? 'init';
|
|
515
|
-
if (action
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
516
|
+
if (action === 'init') {
|
|
517
|
+
const result = await service.initWiki();
|
|
518
|
+
output({ ok: true, ...result, message: `Initialized wiki layout in ${service.workspace.home}` }, flags.json);
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
if (action === 'compile') {
|
|
522
|
+
const args = positional.slice(2);
|
|
523
|
+
const sourceRefs = args.filter((arg) => /^(open-files|file|s3|https?):\/\//.test(arg));
|
|
524
|
+
const query = args.filter((arg) => !/^(open-files|file|s3|https?):\/\//.test(arg)).join(' ');
|
|
525
|
+
const result = await service.compileWiki({
|
|
526
|
+
title: flags.title,
|
|
527
|
+
query: query || flags.search,
|
|
528
|
+
sourceRefs: sourceRefs.length > 0 ? sourceRefs : undefined,
|
|
529
|
+
limit: flags.limit,
|
|
530
|
+
});
|
|
531
|
+
output({ ok: true, ...result, message: `Compiled wiki page ${result.path}` }, flags.json);
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
if (action === 'file-answer' || action === 'answer') {
|
|
535
|
+
const prompt = positional.slice(2).join(' ');
|
|
536
|
+
if (!prompt) throw new Error('Usage: open-knowledge wiki file-answer <prompt> --content <answer> --approve-write');
|
|
537
|
+
if (!flags.content) throw new Error('Missing --content <answer> for wiki file-answer.');
|
|
538
|
+
const result = await service.fileAnswer({
|
|
539
|
+
prompt,
|
|
540
|
+
answer: flags.content,
|
|
541
|
+
approveWrite: flags.approveWrite,
|
|
542
|
+
limit: flags.limit,
|
|
543
|
+
semantic: flags.semantic,
|
|
544
|
+
modelRef: flags.model,
|
|
545
|
+
dimensions: flags.dimensions,
|
|
546
|
+
fake: flags.fake,
|
|
547
|
+
});
|
|
548
|
+
output({ ok: true, ...result }, flags.json);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
if (action === 'lint') {
|
|
552
|
+
const result = service.lintWiki();
|
|
553
|
+
output({ ok: result.ok, ...result, message: result.ok ? 'Wiki lint passed' : `Wiki lint found ${result.issue_count} issue(s)` }, flags.json);
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
throw new Error("Invalid wiki action. Use 'init', 'compile', 'file-answer', or 'lint'.");
|
|
519
557
|
}
|
|
520
558
|
|
|
521
559
|
if (command === 'safety') {
|
package/src/service.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { retrieveKnowledgeContext, type RetrievalOptions } from './retrieval';
|
|
|
26
26
|
import { hybridSearch, type HybridSearchOptions } from './search';
|
|
27
27
|
import { resolveSafetyPolicy } from './safety';
|
|
28
28
|
import { runProviderWebSearch, type WebSearchOptions } from './web-search';
|
|
29
|
+
import { compileWikiPage, fileAnswerToWiki, lintWiki, type WikiCompileOptions } from './wiki-compiler';
|
|
29
30
|
import {
|
|
30
31
|
recordStorageObjects,
|
|
31
32
|
resolveStorageContract,
|
|
@@ -245,6 +246,49 @@ export class KnowledgeService {
|
|
|
245
246
|
return result;
|
|
246
247
|
}
|
|
247
248
|
|
|
249
|
+
async compileWiki(options: Omit<WikiCompileOptions, 'dbPath' | 'store'> = {}) {
|
|
250
|
+
const workspace = this.ensureWorkspace();
|
|
251
|
+
return compileWikiPage({
|
|
252
|
+
...options,
|
|
253
|
+
dbPath: workspace.knowledgeDbPath,
|
|
254
|
+
store: this.artifactStore(),
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async fileAnswer(options: {
|
|
259
|
+
prompt: string;
|
|
260
|
+
answer: string;
|
|
261
|
+
approveWrite?: boolean;
|
|
262
|
+
limit?: number;
|
|
263
|
+
semantic?: boolean;
|
|
264
|
+
modelRef?: string;
|
|
265
|
+
dimensions?: number;
|
|
266
|
+
fake?: boolean;
|
|
267
|
+
}) {
|
|
268
|
+
const workspace = this.ensureWorkspace();
|
|
269
|
+
const context = await this.retrieveContext({
|
|
270
|
+
query: options.prompt,
|
|
271
|
+
limit: options.limit,
|
|
272
|
+
semantic: options.semantic,
|
|
273
|
+
modelRef: options.modelRef,
|
|
274
|
+
dimensions: options.dimensions,
|
|
275
|
+
fake: options.fake,
|
|
276
|
+
});
|
|
277
|
+
return fileAnswerToWiki({
|
|
278
|
+
dbPath: workspace.knowledgeDbPath,
|
|
279
|
+
store: this.artifactStore(),
|
|
280
|
+
prompt: options.prompt,
|
|
281
|
+
answer: options.answer,
|
|
282
|
+
context,
|
|
283
|
+
approveWrite: options.approveWrite,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
lintWiki() {
|
|
288
|
+
const workspace = this.ensureWorkspace();
|
|
289
|
+
return lintWiki({ dbPath: workspace.knowledgeDbPath });
|
|
290
|
+
}
|
|
291
|
+
|
|
248
292
|
async ingestManifest(input: string) {
|
|
249
293
|
const workspace = this.ensureWorkspace();
|
|
250
294
|
return ingestOpenFilesManifest({
|