@zosmaai/pi-llm-wiki 0.11.7 → 0.11.8
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 +7 -0
- package/dist/extensions/llm-wiki/lib/dashboard-command.js +7 -2
- package/dist/extensions/llm-wiki/lib/dashboard.js +1 -1
- package/dist/extensions/llm-wiki/lib/host.js +1 -1
- package/dist/extensions/llm-wiki/lib/ingest-worker.js +1 -1
- package/dist/extensions/llm-wiki/lib/knowledge-links.js +1 -1
- package/dist/extensions/llm-wiki/lib/legacy-repair.js +1 -1
- package/dist/extensions/llm-wiki/lib/metadata.js +1 -1
- package/dist/extensions/llm-wiki/lib/model-command.js +77 -4
- package/dist/extensions/llm-wiki/lib/recall.js +2 -2
- package/dist/extensions/llm-wiki/lib/runtime.js +1 -1
- package/dist/extensions/llm-wiki/lib/settings-command.js +6 -1
- package/dist/extensions/llm-wiki/lib/source-extractors.js +21 -5
- package/dist/extensions/llm-wiki/lib/tools.js +1 -1
- package/dist/extensions/llm-wiki/lib/trajectory.js +1 -1
- package/dist/extensions/llm-wiki/lib/utils.js +1 -1
- package/dist/extensions/llm-wiki/lib/vault-format.js +1 -1
- package/dist/extensions/llm-wiki/lib/visible-status.js +1 -1
- package/dist/mcp/operations.js +1 -1
- package/docs/superpowers/plans/2026-08-29-custom-wiki-page-types.md +378 -0
- package/docs/superpowers/plans/2026-08-29-keyless-provider-ingest-fix.md +256 -0
- package/extensions/llm-wiki/lib/bootstrap.ts +2 -2
- package/extensions/llm-wiki/lib/dashboard-command.ts +9 -3
- package/extensions/llm-wiki/lib/dashboard.ts +1 -1
- package/extensions/llm-wiki/lib/embeddings.ts +1 -1
- package/extensions/llm-wiki/lib/guardrails.ts +2 -2
- package/extensions/llm-wiki/lib/host.ts +1 -1
- package/extensions/llm-wiki/lib/ingest-worker.ts +6 -6
- package/extensions/llm-wiki/lib/knowledge-links.ts +1 -1
- package/extensions/llm-wiki/lib/legacy-repair.ts +4 -4
- package/extensions/llm-wiki/lib/metadata.ts +3 -3
- package/extensions/llm-wiki/lib/model-command.ts +116 -6
- package/extensions/llm-wiki/lib/observation.ts +2 -2
- package/extensions/llm-wiki/lib/recall.ts +4 -4
- package/extensions/llm-wiki/lib/retro.ts +1 -1
- package/extensions/llm-wiki/lib/runtime.ts +1 -1
- package/extensions/llm-wiki/lib/settings-command.ts +9 -2
- package/extensions/llm-wiki/lib/source-extractors.ts +20 -12
- package/extensions/llm-wiki/lib/source-packet.ts +2 -3
- package/extensions/llm-wiki/lib/task-config.ts +1 -1
- package/extensions/llm-wiki/lib/tools.ts +3 -3
- package/extensions/llm-wiki/lib/trajectory.ts +2 -2
- package/extensions/llm-wiki/lib/utils.ts +1 -1
- package/extensions/llm-wiki/lib/vault-format.ts +2 -2
- package/extensions/llm-wiki/lib/visible-status.ts +1 -1
- package/extensions/llm-wiki/lib/wiki-service.ts +1 -1
- package/mcp/operations.ts +3 -3
- package/package.json +7 -7
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
|
|
2
1
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
|
|
3
3
|
import { scheduleReindex } from "./indexing.js";
|
|
4
4
|
import { rebuildMetadataLight } from "./metadata.js";
|
|
5
5
|
import type { Runtime } from "./runtime.js";
|
|
6
|
-
import { isPathWithin, isProtectedPath, resolveVaultPaths } from "./utils.js";
|
|
7
6
|
import type { VaultPaths } from "./utils.js";
|
|
7
|
+
import { isPathWithin, isProtectedPath, resolveVaultPaths } from "./utils.js";
|
|
8
8
|
import { inspectVaultFormat, isGeneratedOkfPath } from "./vault-format.js";
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -129,7 +129,7 @@ export function resolveProjectSettingsPath(cwd: string, host: HostKind = detectH
|
|
|
129
129
|
*
|
|
130
130
|
* Always writes to `settings.json` inside the agent dir — both hosts read it.
|
|
131
131
|
*/
|
|
132
|
-
export function resolveGlobalSettingsPath(
|
|
132
|
+
export function resolveGlobalSettingsPath(_host: HostKind = detectHost()): string {
|
|
133
133
|
let agentDir = "";
|
|
134
134
|
try {
|
|
135
135
|
agentDir = getAgentDir();
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { existsSync, mkdirSync
|
|
1
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
4
4
|
import type { Api, Model } from "@mariozechner/pi-ai";
|
|
5
|
-
import { Type } from "typebox";
|
|
6
5
|
import type { Static } from "typebox";
|
|
6
|
+
import { Type } from "typebox";
|
|
7
7
|
import {
|
|
8
|
+
createKnowledgeDocument,
|
|
8
9
|
type KnowledgeDiagnostic,
|
|
9
10
|
type KnowledgeDocument,
|
|
10
|
-
createKnowledgeDocument,
|
|
11
11
|
patchKnowledgeDocument,
|
|
12
12
|
readKnowledgeDocumentFile,
|
|
13
13
|
serializeKnowledgeDocument,
|
|
14
14
|
writeKnowledgeDocumentFile,
|
|
15
15
|
} from "./knowledge-document.js";
|
|
16
16
|
import {
|
|
17
|
-
type WikilinkValidationMode,
|
|
18
17
|
auditWikilinks,
|
|
19
18
|
buildWikilinkIndex,
|
|
19
|
+
type WikilinkValidationMode,
|
|
20
20
|
} from "./knowledge-links.js";
|
|
21
21
|
import { appendEvent, rebuildMetadataLight } from "./metadata.js";
|
|
22
22
|
import { runSubAgent } from "./subagent.js";
|
|
23
23
|
import { resolveWikilinkValidation } from "./task-config.js";
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
24
|
+
import { fmtDate, readJson, slugify, type VaultPaths } from "./utils.js";
|
|
25
|
+
import { assertWritableVault, VaultWriteError } from "./vault-format.js";
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Background ingest synthesis (issue #65, part of epic #63).
|
|
@@ -225,7 +225,7 @@ function resolveMarkdownTarget(
|
|
|
225
225
|
// Convert decoded backslashes to /
|
|
226
226
|
const normalized = decoded.map((s) => s.replace(/\\/g, "/")).join("/");
|
|
227
227
|
|
|
228
|
-
const sourceDir = sourceId.replace(/[
|
|
228
|
+
const sourceDir = sourceId.replace(/[^/]*$/, ""); // directory of source
|
|
229
229
|
const parts = normalized.split("/");
|
|
230
230
|
const isRootRelative = normalized.startsWith("/");
|
|
231
231
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import {
|
|
3
|
-
constants,
|
|
4
3
|
chmodSync,
|
|
5
4
|
closeSync,
|
|
5
|
+
constants,
|
|
6
6
|
existsSync,
|
|
7
7
|
fstatSync,
|
|
8
8
|
fsyncSync,
|
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
lstatSync,
|
|
11
11
|
mkdirSync,
|
|
12
12
|
openSync,
|
|
13
|
-
readFileSync,
|
|
14
13
|
readdirSync,
|
|
14
|
+
readFileSync,
|
|
15
15
|
renameSync,
|
|
16
16
|
unlinkSync,
|
|
17
17
|
utimesSync,
|
|
@@ -19,14 +19,14 @@ import {
|
|
|
19
19
|
} from "node:fs";
|
|
20
20
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
21
21
|
import {
|
|
22
|
+
createKnowledgeDocument,
|
|
22
23
|
type DiagnosticCode,
|
|
23
24
|
type KnowledgeDiagnostic,
|
|
24
|
-
createKnowledgeDocument,
|
|
25
25
|
parseKnowledgeDocument,
|
|
26
26
|
parseMarkdownFrontmatter,
|
|
27
27
|
serializeKnowledgeDocument,
|
|
28
28
|
} from "./knowledge-document.js";
|
|
29
|
-
import { type VaultPaths
|
|
29
|
+
import { readJson, type VaultPaths } from "./utils.js";
|
|
30
30
|
import { discoverKnowledgeDocuments, inspectVaultFormat } from "./vault-format.js";
|
|
31
31
|
|
|
32
32
|
const RECOVERABLE = new Set<DiagnosticCode>([
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
existsSync,
|
|
4
4
|
lstatSync,
|
|
5
5
|
mkdirSync,
|
|
6
|
-
readFileSync,
|
|
7
6
|
readdirSync,
|
|
7
|
+
readFileSync,
|
|
8
8
|
renameSync,
|
|
9
9
|
rmSync,
|
|
10
10
|
writeFileSync,
|
|
@@ -12,11 +12,11 @@ import {
|
|
|
12
12
|
import { dirname, join } from "node:path";
|
|
13
13
|
import type { KnowledgeDiagnostic, KnowledgeDocument } from "./knowledge-document.js";
|
|
14
14
|
import {
|
|
15
|
-
type WikilinkIndex,
|
|
16
15
|
buildResolvedBacklinks,
|
|
17
16
|
buildWikilinkIndex,
|
|
17
|
+
type WikilinkIndex,
|
|
18
18
|
} from "./knowledge-links.js";
|
|
19
|
-
import {
|
|
19
|
+
import { isPathWithin, readJson, type VaultPaths } from "./utils.js";
|
|
20
20
|
import {
|
|
21
21
|
assertWritableVault,
|
|
22
22
|
compareCodePoint,
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
1
|
+
import type { ExtensionAPI, Theme } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import {
|
|
3
|
+
Container,
|
|
4
|
+
matchesKey,
|
|
5
|
+
type SelectItem,
|
|
6
|
+
SelectList,
|
|
7
|
+
type SelectListTheme,
|
|
8
|
+
Spacer,
|
|
9
|
+
Text,
|
|
10
|
+
} from "@mariozechner/pi-tui";
|
|
2
11
|
import type { Runtime } from "./runtime.js";
|
|
3
|
-
import {
|
|
12
|
+
import { parseModelRef, persistTaskModel, type TaskConfig } from "./task-config.js";
|
|
4
13
|
|
|
5
14
|
/**
|
|
6
15
|
* Model selection surface for the wiki background lane (issue #69, epic #63).
|
|
@@ -25,6 +34,12 @@ interface ModelLike {
|
|
|
25
34
|
/** Words that clear the override and revert to the session model. */
|
|
26
35
|
const CLEAR_WORDS = new Set(["session", "default", "reset", "clear", "none", "unset"]);
|
|
27
36
|
|
|
37
|
+
/** Sentinel value for the "use session model" picker row — not a valid provider/id. */
|
|
38
|
+
const SESSION_VALUE = "__session__";
|
|
39
|
+
|
|
40
|
+
/** Same window size as pi's built-in `/model` picker. */
|
|
41
|
+
const MAX_VISIBLE = 10;
|
|
42
|
+
|
|
28
43
|
/** The status-bar key for the active-model label (so we can update it in place). */
|
|
29
44
|
export const MODEL_STATUS_KEY = "llm-wiki-model";
|
|
30
45
|
|
|
@@ -43,6 +58,85 @@ function modelRef(m: ModelLike): string {
|
|
|
43
58
|
return `${m.provider}/${m.id}`;
|
|
44
59
|
}
|
|
45
60
|
|
|
61
|
+
function buildSelectTheme(theme: Theme): SelectListTheme {
|
|
62
|
+
return {
|
|
63
|
+
selectedPrefix: (text) => theme.fg("accent", text),
|
|
64
|
+
selectedText: (text) => theme.fg("accent", text),
|
|
65
|
+
description: (text) => theme.fg("dim", text),
|
|
66
|
+
scrollInfo: (text) => theme.fg("dim", text),
|
|
67
|
+
noMatch: (text) => theme.fg("muted", text),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function buildPickerItems(
|
|
72
|
+
pool: ModelLike[],
|
|
73
|
+
currentRef: string | undefined,
|
|
74
|
+
): { items: SelectItem[]; selectedIndex: number } {
|
|
75
|
+
const items: SelectItem[] = [
|
|
76
|
+
{
|
|
77
|
+
value: SESSION_VALUE,
|
|
78
|
+
label: "↩ Use session model (clear override)",
|
|
79
|
+
description: currentRef ? undefined : "current",
|
|
80
|
+
},
|
|
81
|
+
];
|
|
82
|
+
let selectedIndex = 0;
|
|
83
|
+
for (const m of pool) {
|
|
84
|
+
const ref = modelRef(m);
|
|
85
|
+
const isCurrent = currentRef === ref;
|
|
86
|
+
items.push({
|
|
87
|
+
value: ref,
|
|
88
|
+
label: ref,
|
|
89
|
+
description: isCurrent ? "current" : undefined,
|
|
90
|
+
});
|
|
91
|
+
if (isCurrent) selectedIndex = items.length - 1;
|
|
92
|
+
}
|
|
93
|
+
return { items, selectedIndex };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Editor-dock picker; `ui.custom` without overlay replaces the input slot like `/model`. */
|
|
97
|
+
class ModelPickerScreen extends Container {
|
|
98
|
+
private list: SelectList;
|
|
99
|
+
private doneFn: (result?: string) => void;
|
|
100
|
+
private closed = false;
|
|
101
|
+
|
|
102
|
+
constructor(
|
|
103
|
+
title: string,
|
|
104
|
+
items: SelectItem[],
|
|
105
|
+
selectedIndex: number,
|
|
106
|
+
theme: Theme,
|
|
107
|
+
done: (result?: string) => void,
|
|
108
|
+
) {
|
|
109
|
+
super();
|
|
110
|
+
this.doneFn = done;
|
|
111
|
+
this.addChild(new Text(title, 0, 0));
|
|
112
|
+
this.addChild(new Spacer(1));
|
|
113
|
+
this.list = new SelectList(
|
|
114
|
+
items,
|
|
115
|
+
Math.min(MAX_VISIBLE, Math.max(items.length, 1)),
|
|
116
|
+
buildSelectTheme(theme),
|
|
117
|
+
);
|
|
118
|
+
this.list.setSelectedIndex(selectedIndex);
|
|
119
|
+
this.list.onSelect = (item) => this.finish(item.value);
|
|
120
|
+
this.list.onCancel = () => this.finish(undefined);
|
|
121
|
+
this.addChild(this.list);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
handleInput(data: string): void {
|
|
125
|
+
// matchesKey covers kitty CSI-u Esc; SelectList cancel is the fallback.
|
|
126
|
+
if (matchesKey(data, "escape")) {
|
|
127
|
+
this.finish(undefined);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
this.list.handleInput(data);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private finish(result?: string): void {
|
|
134
|
+
if (this.closed) return;
|
|
135
|
+
this.closed = true;
|
|
136
|
+
this.doneFn(result);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
46
140
|
/**
|
|
47
141
|
* Register the `/wiki-model` slash command. Lets the user view the active
|
|
48
142
|
* background task model and choose another (or revert to the session model).
|
|
@@ -108,15 +202,31 @@ export function registerWikiModelCommand(pi: ExtensionAPI, runtime: Runtime): vo
|
|
|
108
202
|
return;
|
|
109
203
|
}
|
|
110
204
|
|
|
205
|
+
if (typeof ctx.ui.custom !== "function") {
|
|
206
|
+
ctx.ui.notify(
|
|
207
|
+
`LLM Wiki: this host does not support the model picker. Pass provider/id (e.g. anthropic/claude-haiku) or "session". Active: ${current}.`,
|
|
208
|
+
"warning",
|
|
209
|
+
);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
111
213
|
const available = (ctx.modelRegistry.getAvailable() as ModelLike[]) ?? [];
|
|
112
214
|
const pool = available.length > 0 ? available : (ctx.modelRegistry.getAll() as ModelLike[]);
|
|
113
|
-
const
|
|
114
|
-
const
|
|
215
|
+
const currentRef = runtime.config.taskModel ? modelRef(runtime.config.taskModel) : undefined;
|
|
216
|
+
const { items, selectedIndex } = buildPickerItems(pool, currentRef);
|
|
115
217
|
|
|
116
|
-
const picked = await ctx.ui.
|
|
218
|
+
const picked = await ctx.ui.custom<string | undefined>((_tui, theme, _keybindings, done) => {
|
|
219
|
+
return new ModelPickerScreen(
|
|
220
|
+
`Wiki background model (current: ${current})`,
|
|
221
|
+
items,
|
|
222
|
+
selectedIndex,
|
|
223
|
+
theme,
|
|
224
|
+
done,
|
|
225
|
+
);
|
|
226
|
+
});
|
|
117
227
|
if (picked === undefined) return; // cancelled
|
|
118
228
|
|
|
119
|
-
if (picked ===
|
|
229
|
+
if (picked === SESSION_VALUE) {
|
|
120
230
|
apply(undefined);
|
|
121
231
|
return;
|
|
122
232
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
-
import type { ExtensionAPI
|
|
2
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
3
3
|
import { Type } from "typebox";
|
|
4
4
|
import { scheduleReindex } from "./indexing.js";
|
|
5
5
|
import { createKnowledgeDocument, writeKnowledgeDocumentFile } from "./knowledge-document.js";
|
|
6
6
|
import { appendEvent, rebuildMetadataLight } from "./metadata.js";
|
|
7
7
|
import type { Runtime } from "./runtime.js";
|
|
8
|
-
import {
|
|
8
|
+
import { fmtDate, resolveVaultPaths, type VaultPaths } from "./utils.js";
|
|
9
9
|
import { assertWritableVault, inspectWritableVault } from "./vault-format.js";
|
|
10
10
|
|
|
11
11
|
// ─── Types ─────────────────────────────────────────────
|
|
@@ -3,9 +3,9 @@ import { join } from "node:path";
|
|
|
3
3
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
4
4
|
import { Type } from "typebox";
|
|
5
5
|
import {
|
|
6
|
+
cosineSimilarity,
|
|
6
7
|
type Embedder,
|
|
7
8
|
type EmbeddingStore,
|
|
8
|
-
cosineSimilarity,
|
|
9
9
|
normalizeVector,
|
|
10
10
|
readEmbeddingStore,
|
|
11
11
|
resolveEmbedder,
|
|
@@ -15,11 +15,11 @@ import type { Registry } from "./metadata.js";
|
|
|
15
15
|
import type { Runtime } from "./runtime.js";
|
|
16
16
|
import type { TaskConfig } from "./task-config.js";
|
|
17
17
|
import {
|
|
18
|
-
type VaultPaths,
|
|
19
18
|
getPersonalWikiPaths,
|
|
20
19
|
isPersonalVault,
|
|
21
20
|
readJson,
|
|
22
21
|
resolveVaultPaths,
|
|
22
|
+
type VaultPaths,
|
|
23
23
|
} from "./utils.js";
|
|
24
24
|
import { inspectVaultFormat } from "./vault-format.js";
|
|
25
25
|
|
|
@@ -111,7 +111,7 @@ function normalizeText(value: unknown): string {
|
|
|
111
111
|
return flattenSearchValue(value)
|
|
112
112
|
.toLowerCase()
|
|
113
113
|
.normalize("NFKC")
|
|
114
|
-
.replace(/[
|
|
114
|
+
.replace(/[-_./\\]+/g, " ")
|
|
115
115
|
.replace(/[\p{P}\p{S}]+/gu, " ")
|
|
116
116
|
.replace(/\s+/g, " ")
|
|
117
117
|
.trim();
|
|
@@ -333,7 +333,7 @@ function chunkPreview(heading: string, content: string): string {
|
|
|
333
333
|
function extractExpansionTerms(
|
|
334
334
|
scored: Scored[],
|
|
335
335
|
originalQuery: string,
|
|
336
|
-
|
|
336
|
+
_paths: VaultPaths,
|
|
337
337
|
maxTerms = 6,
|
|
338
338
|
): string[] {
|
|
339
339
|
const topResults = scored.slice(0, Math.min(3, scored.length));
|
|
@@ -7,7 +7,7 @@ import { applyWikilinkGate, buildWikilinkIndex } from "./knowledge-links.js";
|
|
|
7
7
|
import { appendEvent, rebuildMetadataLight } from "./metadata.js";
|
|
8
8
|
import type { Runtime } from "./runtime.js";
|
|
9
9
|
import { loadTaskConfig, resolveWikilinkValidation } from "./task-config.js";
|
|
10
|
-
import {
|
|
10
|
+
import { fmtDate, readJson, resolveVaultPaths, type VaultPaths } from "./utils.js";
|
|
11
11
|
import { assertWritableVault, inspectWritableVault } from "./vault-format.js";
|
|
12
12
|
|
|
13
13
|
// ─── Public API ────────────────────────────────────────
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
-
import { TASK_DEFAULTS, type TaskConfig
|
|
2
|
+
import { loadTaskConfig, noticesEnabled, TASK_DEFAULTS, type TaskConfig } from "./task-config.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Background-task runtime for the LLM Wiki (issue #64, part of #63).
|
|
@@ -11,11 +11,11 @@ import {
|
|
|
11
11
|
} from "@mariozechner/pi-tui";
|
|
12
12
|
import type { Runtime } from "./runtime.js";
|
|
13
13
|
import {
|
|
14
|
-
type SettingScope,
|
|
15
14
|
loadTaskConfig,
|
|
16
15
|
loadTaskConfigSources,
|
|
17
16
|
parseModelRef,
|
|
18
17
|
persistSetting,
|
|
18
|
+
type SettingScope,
|
|
19
19
|
trajectoriesEnabled,
|
|
20
20
|
} from "./task-config.js";
|
|
21
21
|
|
|
@@ -49,6 +49,7 @@ interface Ui {
|
|
|
49
49
|
keybindings: unknown,
|
|
50
50
|
done: (result?: unknown) => void,
|
|
51
51
|
) => unknown,
|
|
52
|
+
options?: { overlay?: boolean; overlayOptions?: Record<string, unknown> },
|
|
52
53
|
): Promise<unknown>;
|
|
53
54
|
}
|
|
54
55
|
|
|
@@ -363,6 +364,12 @@ function scopeTitle(scope: SettingScope): string {
|
|
|
363
364
|
return `\u{1F9E0} LLM Wiki Settings \u2014 ${scope === "global" ? "Global" : "Project"} (Esc to close)`;
|
|
364
365
|
}
|
|
365
366
|
|
|
367
|
+
// ponytail: overlay options matching pi-blackhole's config modal style
|
|
368
|
+
const OVERLAY_OPTS = {
|
|
369
|
+
overlay: true,
|
|
370
|
+
overlayOptions: { anchor: "center", width: "92%", maxHeight: "95%" },
|
|
371
|
+
};
|
|
372
|
+
|
|
366
373
|
async function showSettingsTui(ui: Ui, cwd: string, scope: SettingScope): Promise<void> {
|
|
367
374
|
if (typeof ui.custom !== "function") {
|
|
368
375
|
ui.notify(
|
|
@@ -445,7 +452,7 @@ async function showSettingsTui(ui: Ui, cwd: string, scope: SettingScope): Promis
|
|
|
445
452
|
);
|
|
446
453
|
screenRef = new SettingsScreen(scopeTitle(writeScope), list);
|
|
447
454
|
return screenRef;
|
|
448
|
-
});
|
|
455
|
+
}, OVERLAY_OPTS);
|
|
449
456
|
}
|
|
450
457
|
|
|
451
458
|
/**
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { open } from "node:fs/promises";
|
|
2
|
-
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
3
2
|
import { NodeHtmlMarkdown } from "node-html-markdown";
|
|
4
3
|
import { type ExecApi, exec } from "./utils.js";
|
|
5
4
|
|
|
@@ -270,8 +269,8 @@ async function extractWithMarkItDown(
|
|
|
270
269
|
if (!(await hasMarkItDown(pi, signal))) return "";
|
|
271
270
|
const mdResult = await exec(
|
|
272
271
|
pi,
|
|
273
|
-
"
|
|
274
|
-
["
|
|
272
|
+
"uvx",
|
|
273
|
+
["--from", "markitdown[docx,pdf]", "markitdown", source],
|
|
275
274
|
{ signal, timeout: markitdownTimeoutMs() },
|
|
276
275
|
);
|
|
277
276
|
return mdResult.stdout.trim() ? mdResult.stdout : "";
|
|
@@ -281,13 +280,21 @@ async function extractWithMarkItDown(
|
|
|
281
280
|
}
|
|
282
281
|
|
|
283
282
|
async function hasMarkItDown(pi: ExecApi, signal?: AbortSignal): Promise<boolean> {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
"
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
283
|
+
// Probe without shell to avoid CWE-78; try which/where then uvx --version
|
|
284
|
+
try {
|
|
285
|
+
await exec(pi, "which", ["uvx"], { signal });
|
|
286
|
+
return true;
|
|
287
|
+
} catch {}
|
|
288
|
+
try {
|
|
289
|
+
await exec(pi, "where", ["uvx"], { signal });
|
|
290
|
+
return true;
|
|
291
|
+
} catch {}
|
|
292
|
+
try {
|
|
293
|
+
await exec(pi, "uvx", ["--version"], { signal });
|
|
294
|
+
return true;
|
|
295
|
+
} catch {
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
291
298
|
}
|
|
292
299
|
|
|
293
300
|
async function fetchTextUrl(pi: ExecApi, url: string, signal?: AbortSignal): Promise<string> {
|
|
@@ -350,7 +357,8 @@ function decodeHtmlEntities(text: string): string {
|
|
|
350
357
|
};
|
|
351
358
|
const lower = entity.toLowerCase();
|
|
352
359
|
if (map[lower]) return map[lower];
|
|
353
|
-
if (lower.startsWith("&#"))
|
|
360
|
+
if (lower.startsWith("&#"))
|
|
361
|
+
return String.fromCodePoint(Number.parseInt(entity.slice(2, -1), 10));
|
|
354
362
|
return entity;
|
|
355
363
|
});
|
|
356
364
|
}
|
|
@@ -369,7 +377,7 @@ function xmlToMarkdown(xml: string): string {
|
|
|
369
377
|
let prev = "";
|
|
370
378
|
while (prev !== text) {
|
|
371
379
|
prev = text;
|
|
372
|
-
text = text.replace(/<[a-zA-Z
|
|
380
|
+
text = text.replace(/<[a-zA-Z/!?][^>]*>/g, "");
|
|
373
381
|
}
|
|
374
382
|
text = text.replace(/</g, "");
|
|
375
383
|
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { copyFile } from "node:fs/promises";
|
|
3
3
|
import { extname, join } from "node:path";
|
|
4
|
-
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
5
4
|
import { createKnowledgeDocument, serializeKnowledgeDocument } from "./knowledge-document.js";
|
|
6
5
|
import { appendEvent } from "./metadata.js";
|
|
7
6
|
import {
|
|
8
|
-
type ExtractedContent,
|
|
9
7
|
binaryExtractionFailureMessage,
|
|
10
8
|
detectBinaryMagicBytes,
|
|
9
|
+
type ExtractedContent,
|
|
11
10
|
extractUrlContent,
|
|
12
11
|
fileExtractorFor,
|
|
13
12
|
} from "./source-extractors.js";
|
|
14
13
|
import {
|
|
15
14
|
type ExecApi,
|
|
16
|
-
type VaultPaths,
|
|
17
15
|
exec,
|
|
18
16
|
fmtDate,
|
|
19
17
|
nextSourceId,
|
|
20
18
|
readText,
|
|
19
|
+
type VaultPaths,
|
|
21
20
|
writeJson,
|
|
22
21
|
} from "./utils.js";
|
|
23
22
|
import { assertWritableVault } from "./vault-format.js";
|
|
@@ -2,8 +2,8 @@ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { dirname } from "node:path";
|
|
3
3
|
import { parse as parseYaml } from "yaml";
|
|
4
4
|
import {
|
|
5
|
-
type HostKind,
|
|
6
5
|
detectHost,
|
|
6
|
+
type HostKind,
|
|
7
7
|
listGlobalSettingsFiles,
|
|
8
8
|
listProjectSettingsFiles,
|
|
9
9
|
resolveGlobalSettingsPath,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, mkdirSync,
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join, relative } from "node:path";
|
|
3
3
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
4
4
|
import { Type } from "typebox";
|
|
@@ -17,18 +17,18 @@ import {
|
|
|
17
17
|
buildWikilinkIndex,
|
|
18
18
|
} from "./knowledge-links.js";
|
|
19
19
|
import { repairLegacyKnowledgeDocuments } from "./legacy-repair.js";
|
|
20
|
-
import { type Registry,
|
|
20
|
+
import { appendEvent, type Registry, rebuildMetadata, rebuildMetadataLight } from "./metadata.js";
|
|
21
21
|
import type { Runtime } from "./runtime.js";
|
|
22
22
|
import { captureFile, captureText, captureUrl } from "./source-packet.js";
|
|
23
23
|
import { loadTaskConfig, parseModelRef, resolveWikilinkValidation } from "./task-config.js";
|
|
24
24
|
import {
|
|
25
|
-
type VaultPaths,
|
|
26
25
|
detectVaultFormat,
|
|
27
26
|
fmtDate,
|
|
28
27
|
getVaultPaths,
|
|
29
28
|
readJson,
|
|
30
29
|
resolveVaultPaths,
|
|
31
30
|
slugify,
|
|
31
|
+
type VaultPaths,
|
|
32
32
|
writeJson,
|
|
33
33
|
} from "./utils.js";
|
|
34
34
|
import {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { existsSync, mkdirSync,
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
|
|
4
4
|
import { Type } from "typebox";
|
|
5
5
|
import { appendEvent, rebuildMetadataLight } from "./metadata.js";
|
|
6
6
|
import { searchWikiLayered } from "./recall.js";
|
|
7
7
|
import {
|
|
8
|
-
type VaultPaths,
|
|
9
8
|
fmtDate,
|
|
10
9
|
nextTrajectoryId,
|
|
11
10
|
readJson,
|
|
12
11
|
resolveVaultPaths,
|
|
12
|
+
type VaultPaths,
|
|
13
13
|
writeJson,
|
|
14
14
|
} from "./utils.js";
|
|
15
15
|
import { assertWritableVault, inspectWritableVault } from "./vault-format.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, lstatSync,
|
|
1
|
+
import { existsSync, lstatSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { isAbsolute, join, relative, sep } from "node:path";
|
|
3
3
|
import {
|
|
4
4
|
type KnowledgeDiagnostic,
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
parseKnowledgeDocument,
|
|
7
7
|
parseMarkdownFrontmatter,
|
|
8
8
|
} from "./knowledge-document.js";
|
|
9
|
-
import { type VaultPaths
|
|
9
|
+
import { relativePhysicalPath, type VaultPaths } from "./utils.js";
|
|
10
10
|
|
|
11
11
|
export type KnowledgeFormat = "legacy" | "okf-0.2";
|
|
12
12
|
|
|
@@ -2,8 +2,8 @@ import { existsSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import type { KnowledgeDiagnostic } from "./knowledge-document.js";
|
|
4
4
|
import type { Registry } from "./metadata.js";
|
|
5
|
-
import { readJson } from "./utils.js";
|
|
6
5
|
import type { VaultPaths } from "./utils.js";
|
|
6
|
+
import { readJson } from "./utils.js";
|
|
7
7
|
import type { KnowledgeFormat } from "./vault-format.js";
|
|
8
8
|
import {
|
|
9
9
|
compareCodePoint,
|
package/mcp/operations.ts
CHANGED
|
@@ -10,20 +10,20 @@ import { join } from "node:path";
|
|
|
10
10
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
11
11
|
import { bootstrapVault } from "../extensions/llm-wiki/lib/bootstrap.js";
|
|
12
12
|
import {
|
|
13
|
-
type WikilinkValidationMode,
|
|
14
13
|
applyWikilinkGate,
|
|
15
14
|
buildWikilinkIndex,
|
|
15
|
+
type WikilinkValidationMode,
|
|
16
16
|
} from "../extensions/llm-wiki/lib/knowledge-links.js";
|
|
17
17
|
import { type ProjectionResult, rebuildMetadata } from "../extensions/llm-wiki/lib/metadata.js";
|
|
18
18
|
import { type RecallResult, searchWikiLayered } from "../extensions/llm-wiki/lib/recall.js";
|
|
19
19
|
import { saveInsight } from "../extensions/llm-wiki/lib/retro.js";
|
|
20
20
|
import { captureFile, captureText, captureUrl } from "../extensions/llm-wiki/lib/source-packet.js";
|
|
21
21
|
import { resolveWikilinkValidation } from "../extensions/llm-wiki/lib/task-config.js";
|
|
22
|
-
import { type VaultPaths
|
|
22
|
+
import { readJson, type VaultPaths } from "../extensions/llm-wiki/lib/utils.js";
|
|
23
23
|
import {
|
|
24
|
-
VaultWriteError,
|
|
25
24
|
inspectVaultFormat,
|
|
26
25
|
inspectWritableVault,
|
|
26
|
+
VaultWriteError,
|
|
27
27
|
} from "../extensions/llm-wiki/lib/vault-format.js";
|
|
28
28
|
import { getWikiStatus, searchRegistry } from "../extensions/llm-wiki/lib/wiki-service.js";
|
|
29
29
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zosmaai/pi-llm-wiki",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.8",
|
|
4
4
|
"description": "Self-maintaining LLM Wiki for Pi — Karpathy-pattern knowledge base with immutable source capture, automated ingestion, search, linting, and Obsidian-compatible vault. auto-updating personal & company wiki.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
84
|
"@cfworker/json-schema": "^4.1.1",
|
|
85
|
-
"@mariozechner/pi-tui": "0.
|
|
85
|
+
"@mariozechner/pi-tui": "0.73.1",
|
|
86
86
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
87
87
|
"mdast-util-from-markdown": "^2.0.3",
|
|
88
88
|
"node-html-markdown": "^2.0.0",
|
|
@@ -92,16 +92,16 @@
|
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
94
|
"@astrojs/starlight": "^0.41.10",
|
|
95
|
-
"@biomejs/biome": "^
|
|
96
|
-
"@mariozechner/pi-agent-core": "^0.
|
|
97
|
-
"@mariozechner/pi-ai": "^0.
|
|
95
|
+
"@biomejs/biome": "^2.5.11",
|
|
96
|
+
"@mariozechner/pi-agent-core": "^0.73.1",
|
|
97
|
+
"@mariozechner/pi-ai": "^0.73.1",
|
|
98
98
|
"@mariozechner/pi-coding-agent": "^0.70.2",
|
|
99
99
|
"@mermaid-js/mermaid-cli": "^11.12.0",
|
|
100
100
|
"@types/mdast": "^4.0.4",
|
|
101
|
-
"@types/node": "^
|
|
101
|
+
"@types/node": "^26",
|
|
102
102
|
"@vitest/coverage-v8": "^3.2.4",
|
|
103
103
|
"astro": "^7.2.9",
|
|
104
|
-
"typescript": "^
|
|
104
|
+
"typescript": "^7.0.2",
|
|
105
105
|
"vitest": "^3.0.0"
|
|
106
106
|
},
|
|
107
107
|
"scripts": {
|