@hasna/knowledge 0.2.21 → 0.2.23

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.
@@ -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:
@@ -237,6 +245,20 @@ freshness and permission notes, graph evidence, and final rerank scores. The
237
245
  local SQLite index can later move to pgvector or a managed hosted vector store
238
246
  without changing CLI/MCP result shape.
239
247
 
248
+ MCP has a stable agent-facing contract layered over the older `ok_*`
249
+ compatibility tools. Agents should prefer `knowledge_search`, `knowledge_ask`,
250
+ `knowledge_build`, `knowledge_get`, `knowledge_ingest`,
251
+ `knowledge_web_search`, `knowledge_lint`, `knowledge_run_status`,
252
+ `knowledge_storage`, and `knowledge_resolve_source`. The same server publishes
253
+ project-scope JSON resources at `knowledge://project/config`,
254
+ `knowledge://project/storage`, `knowledge://project/schema`,
255
+ `knowledge://project/sources`, `knowledge://project/open-files`,
256
+ `knowledge://project/wiki/pages`, `knowledge://project/indexes`,
257
+ `knowledge://project/runs`, and `knowledge://project/decisions`, plus templated
258
+ reads for individual items, sources, wiki pages, indexes, runs, and decisions.
259
+ These resources expose derived chunks, generated wiki artifacts, citations, run
260
+ ledgers, and storage/index metadata without exposing raw source bytes.
261
+
240
262
  Index freshness is explicit. `reindex_queue` tracks missing or stale embedding
241
263
  work, `open-knowledge reindex status|enqueue|embeddings` operates the local
242
264
  queue, and MCP exposes the same controls through `ok_reindex_status`,
@@ -59,11 +59,11 @@ open-knowledge embeddings search "company wiki policy" --scope project --json
59
59
  ```
60
60
 
61
61
  `search` is the structured hybrid layer for agents. `embeddings search` is the
62
- lower-level vector-only command. MCP exposes the same capability through
63
- `ok_search`, `knowledge_search`, `ok_embeddings_status`, `ok_embeddings_index`,
64
- `ok_semantic_search`, `ok_reindex_status`, `ok_reindex_enqueue`, and
65
- `ok_reindex_embeddings`. Deterministic `--fake` embeddings exist for tests and
66
- offline verification only.
62
+ lower-level vector-only command. MCP exposes the agent-facing path through
63
+ `knowledge_search`, `knowledge_ask`, `knowledge_build`, `knowledge_get`,
64
+ `knowledge_run_status`, and `knowledge_lint`, with lower-level compatibility
65
+ tools for `ok_search`, embeddings, and reindexing. Deterministic `--fake`
66
+ embeddings exist for tests and offline verification only.
67
67
 
68
68
  ## Hosted Indexes
69
69
 
@@ -144,13 +144,14 @@ search rows using exact-term coverage, citation availability, source freshness,
144
144
  and source/wiki authority, then emits excerpts and citation objects that preserve
145
145
  source refs, artifact URIs, revision/hash metadata, offsets, and provenance.
146
146
  `open-knowledge ask|build <prompt>`, the installed `knowledge <prompt>` alias,
147
- and MCP `knowledge_ask` wrap this context pack in a run ledger and return a
148
- citation draft or explicit AI SDK generated answer.
147
+ and MCP `knowledge_ask|knowledge_build` wrap this context pack in a run ledger
148
+ and return a citation draft or explicit AI SDK generated answer.
149
149
 
150
150
  Provider-native web search lives beside local retrieval. `open-knowledge web
151
- search` and MCP `ok_web_search` are safety-gated, capture provider sources, and
152
- can file snippets as read-only `web` source refs so later local retrieval treats
153
- them like other cited sources.
151
+ search` and MCP `knowledge_web_search` are safety-gated, capture provider
152
+ sources, and can file snippets as read-only `web` source refs so later local
153
+ retrieval treats them like other cited sources. The lower-level `ok_web_search`
154
+ tool remains for compatibility.
154
155
 
155
156
  ## Reindexing
156
157
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/knowledge",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
4
4
  "description": "Agent-friendly local knowledge CLI with JSON output, pagination, and safe destructive actions",
5
5
  "type": "module",
6
6
  "bin": {
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 Initialize scalable wiki/schema/index/log artifacts
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 !== 'init') throw new Error("Invalid wiki action. Use 'init'.");
516
- const result = await service.initWiki();
517
- output({ ok: true, ...result, message: `Initialized wiki layout in ${service.workspace.home}` }, flags.json);
518
- return;
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') {