@zosmaai/pi-llm-wiki 0.11.5 → 0.11.6

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.
@@ -5,11 +5,15 @@
5
5
  * used by Pi tools. No operation parses YAML, scans files, scores
6
6
  * registry entries, or builds page strings itself.
7
7
  */
8
+ import { join } from "node:path";
8
9
  import { bootstrapVault } from "../extensions/llm-wiki/lib/bootstrap.js";
10
+ import { applyWikilinkGate, buildWikilinkIndex, } from "../extensions/llm-wiki/lib/knowledge-links.js";
9
11
  import { rebuildMetadata } from "../extensions/llm-wiki/lib/metadata.js";
10
12
  import { searchWikiLayered } from "../extensions/llm-wiki/lib/recall.js";
11
13
  import { saveInsight } from "../extensions/llm-wiki/lib/retro.js";
12
14
  import { captureFile, captureText, captureUrl } from "../extensions/llm-wiki/lib/source-packet.js";
15
+ import { resolveWikilinkValidation } from "../extensions/llm-wiki/lib/task-config.js";
16
+ import { readJson } from "../extensions/llm-wiki/lib/utils.js";
13
17
  import { VaultWriteError, inspectVaultFormat, inspectWritableVault, } from "../extensions/llm-wiki/lib/vault-format.js";
14
18
  import { getWikiStatus, searchRegistry } from "../extensions/llm-wiki/lib/wiki-service.js";
15
19
  function projectionOutcome(projection) {
@@ -87,7 +91,7 @@ export async function statusOperation(paths) {
87
91
  };
88
92
  }
89
93
  /** Shared retro operation: validates vault then delegates to saveInsight. */
90
- export async function retroOperation(paths, slug, title, body, category) {
94
+ export async function retroOperation(paths, slug, title, body, category, wikilinkValidation) {
91
95
  const vaultCheck = inspectWritableVault(paths);
92
96
  if (!vaultCheck.ok) {
93
97
  return {
@@ -95,8 +99,23 @@ export async function retroOperation(paths, slug, title, body, category) {
95
99
  diagnostics: vaultCheck.diagnostics.map((d) => ({ code: d.code, message: d.message })),
96
100
  };
97
101
  }
102
+ // Pre-write wikilink gate (#172): validate/normalize caller-supplied body.
103
+ const mode = resolveWikilinkValidation({ wikilinkValidation });
104
+ let gateBody = body;
105
+ if (mode !== "off") {
106
+ const registry = readJson(join(paths.meta, "registry.json"), { pages: {} });
107
+ const gate = applyWikilinkGate(body, buildWikilinkIndex(Object.keys(registry.pages)), `sources/${slug}`, mode);
108
+ if (!gate.ok) {
109
+ return {
110
+ ok: false,
111
+ diagnostics: gate.diagnostics.map((d) => ({ code: "link_validation", message: d.message })),
112
+ };
113
+ }
114
+ if (mode === "normalize")
115
+ gateBody = gate.body;
116
+ }
98
117
  try {
99
- const result = saveInsight(paths, slug, title, body, category, { rebuild: false });
118
+ const result = saveInsight(paths, slug, title, gateBody, category, { rebuild: false });
100
119
  const projection = projectionOutcome(rebuildMetadata(paths));
101
120
  if (!projection.ok)
102
121
  return projection;
@@ -58,6 +58,7 @@ All of the above are viewable and editable in the `/wiki-settings` TUI (persists
58
58
  | `taskModel` | — | Model for background tasks (`{ provider: "openai", id: "gpt-4o" }`) |
59
59
  | `synthesisLanguage` | — | BCP 47 language tag for ingest synthesis (e.g. `"ru"`, `"fr"`). When unset, synthesis defaults to English. |
60
60
  | `synthesisMaxTokens` | 16384 | Max output tokens for ingest/synthesis runs (stored as a plain number) |
61
+ | `wikilinkValidation` | warn | Pre-write wikilink gate for page writes (ingest, `wiki_ensure_page`, `wiki_retro`, MCP `wiki_retro`). `off` ignore, `warn` report, `normalize` rewrite resolvable links, `strict` block writes with unresolved/ambiguous links |
61
62
  | `trajectories` | false | Enable agent-trajectory working-memory |
62
63
  | `notices` | true | Show wiki activity notices in chat |
63
64
  | `ambientPersonalVault` | host-dependent | Let the personal vault act as the ambient vault in projects that have no wiki. `true` under pi, `false` under oh-my-pi — see below. |
package/docs/obsidian.md CHANGED
@@ -2,20 +2,20 @@
2
2
 
3
3
  ## Setup
4
4
 
5
- 1. Open `.llm-wiki/wiki/` as an Obsidian vault
6
- 2. The extension generates `.llm-wiki/meta/index.md` as a browsable catalog
7
- 3. `.llm-wiki/meta/backlinks.json` is available for graph plugins
5
+ 1. Open `.llm-wiki/` as an Obsidian vault
6
+ 2. Your wiki pages live in `wiki/` — Graph View and Backlinks work on these automatically
7
+ 3. The extension generates `meta/index.md` (browsable catalog) and `meta/backlinks.json` (link map) — both are read-only, regenerated on each rebuild
8
8
 
9
9
  ## Recommended Plugins
10
10
 
11
11
  - [Dataview](https://github.com/blacksmithgu/obsidian-dataview) — Query pages by frontmatter
12
- - [Graph View](https://obsidian.md) (built-in) — Visualize `[[wikilink]]` connections
12
+ - [Graph View](https://obsidian.md) (built-in) — Visualize `[[wikilink]]` connections in `wiki/`
13
13
  - [Backlinks](https://obsidian.md) (built-in) — See inbound links
14
14
 
15
15
  ## Web Clipper
16
16
 
17
- Use [Obsidian Web Clipper](https://obsidian.md/clipper) to save articles directly into `.llm-wiki/raw/articles/`.
17
+ Use [Obsidian Web Clipper](https://obsidian.md/clipper) to save articles directly into `raw/articles/`.
18
18
 
19
19
  ## Dataview Dashboard
20
20
 
21
- The extension creates `.llm-wiki/meta/index.md` with page listings. For custom dashboards, use Dataview queries against frontmatter fields like `type`, `domain`, `category`, `sources`.
21
+ For custom dashboards, use Dataview queries against frontmatter fields like `type`, `domain`, `category`, `sources`. Query the `wiki/` directory for knowledge pages.