pi-vault-mind 0.12.11 → 0.14.0
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/CHANGELOG.md +26 -0
- package/dist/src/index.js +5 -1
- package/dist/src/server.d.ts +1 -1
- package/dist/src/server.js +97 -8
- package/dist/src/tools/codegraph.d.ts +15 -0
- package/dist/src/tools/codegraph.js +118 -0
- package/dist/src/tools/marksman.d.ts +93 -0
- package/dist/src/tools/marksman.js +534 -0
- package/dist/src/tools.js +4 -0
- package/dist/src/types.d.ts +8 -0
- package/dist/src/watcher.d.ts +18 -0
- package/dist/src/watcher.js +102 -30
- package/dist/test/dispatch.test.js +155 -0
- package/dist/test/marksman-tools.test.js +171 -0
- package/package.json +1 -1
- package/skills/vault-mind/SKILL.md +11 -0
- package/skills/vault-mind-broadcaster/SKILL.md +2 -0
- package/skills/vault-mind-heavy-lifter/SKILL.md +1 -0
- package/skills/vault-mind-manager/SKILL.md +1 -0
- package/skills/vault-mind-miner/SKILL.md +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.1 — 2026-06-28
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Bundled `json5` into the Obsidian plugin (`main.js`) so the plugin loads in Obsidian without requiring the dependency externally.
|
|
8
|
+
|
|
9
|
+
## 0.13.0 / 0.5.0 — 2026-06-28
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Arrow.js chat UI refactor** — reactive composer (`chat/arrow/`), model chip in the input bar, mentionable badges with preview popup, per-assistant-message action row (copy/info/rewind), keyboard-navigable session popover, and Arrow-based permission modals.
|
|
14
|
+
- **`@agent` dispatch command** — Obsidian palette command that picks a vault-mind role, prompts for an instruction, and calls `POST /vault-mind/dispatch`; also adds `VaultMindClient.scan()` for immediate tag-based scanning.
|
|
15
|
+
- **Marksman LSP tool wrappers** — `vm_backlinks`, `vm_broken_links`, `vm_related` with graceful degradation when `marksman` is unavailable.
|
|
16
|
+
- **Setup model-router picker** — vault init now lets users choose the primary chat model and fallback model sequence, writing choices directly into `.pi/model-router.json`.
|
|
17
|
+
- **`op://` 1Password resolution** — Modal setup resolves `op://` references via the 1Password CLI and stores the actual token in the Obsidian keychain; test-connection now sends the bearer token and reports detailed errors.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- `docs/ROADMAP.md` is now the single source of truth for project direction; `docs/NEXT_STEPS.md` is deprecated.
|
|
22
|
+
- `packages/obsidian/package.json` version now tracks the plugin manifest version.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- PVM_API_TOKEN injection into the `pi` subprocess via `resolveToken()` in `ChatTab.mount()`.
|
|
27
|
+
- Modal test connection failing silently because it did not send an `Authorization` header.
|
|
28
|
+
|
|
3
29
|
## 0.8.0 - 2026-06-24
|
|
4
30
|
|
|
5
31
|
### Added
|
package/dist/src/index.js
CHANGED
|
@@ -53,7 +53,11 @@ export default function (pi) {
|
|
|
53
53
|
})()
|
|
54
54
|
: {};
|
|
55
55
|
const projectEmbed = projectCfg.vaultMind?.embedding;
|
|
56
|
-
const
|
|
56
|
+
const projectAgentLLM = projectCfg.vaultMind?.agentLLM;
|
|
57
|
+
const isSetup = !!(projectEmbed?.remoteUrl ||
|
|
58
|
+
projectEmbed?.localUrl ||
|
|
59
|
+
projectEmbed?.model ||
|
|
60
|
+
projectAgentLLM?.model);
|
|
57
61
|
const sessionCfg = loadConfig(ctx.cwd);
|
|
58
62
|
const piCtxCfg = sessionCfg.extensionCompatibility?.["pi-context"];
|
|
59
63
|
if (isSetup && piCtxCfg?.enabled && piCtxCfg?.autoEnableAcm !== false) {
|
package/dist/src/server.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Endpoints:
|
|
5
5
|
* GET /vault-mind/status → { running, dispatches, vaults, uptime }
|
|
6
6
|
* POST /vault-mind/scan → scan a file for @agent markers { file }
|
|
7
|
-
* POST /vault-mind/dispatch → fire a manual dispatch
|
|
7
|
+
* POST /vault-mind/dispatch → fire a manual dispatch { role, instruction, file?, vault? }
|
|
8
8
|
* POST /vault-mind/context → push active editor context from Obsidian { filePath, selection, cursor }
|
|
9
9
|
* GET /vault-mind/context → latest editor context (file, cursor, selection) for pi agents
|
|
10
10
|
*
|
package/dist/src/server.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Endpoints:
|
|
5
5
|
* GET /vault-mind/status → { running, dispatches, vaults, uptime }
|
|
6
6
|
* POST /vault-mind/scan → scan a file for @agent markers { file }
|
|
7
|
-
* POST /vault-mind/dispatch → fire a manual dispatch
|
|
7
|
+
* POST /vault-mind/dispatch → fire a manual dispatch { role, instruction, file?, vault? }
|
|
8
8
|
* POST /vault-mind/context → push active editor context from Obsidian { filePath, selection, cursor }
|
|
9
9
|
* GET /vault-mind/context → latest editor context (file, cursor, selection) for pi agents
|
|
10
10
|
*
|
|
@@ -33,7 +33,7 @@ import { queryGraph } from "./graph.js";
|
|
|
33
33
|
import { searchFts, searchHybrid, upsertEntry } from "./lance.js";
|
|
34
34
|
import { DEFAULT_CONFIG } from "./types.js";
|
|
35
35
|
import { ensureDir, expandHome, findConfig, loadConfig, resolveInitCollectionName, shrinkHome, } from "./utils.js";
|
|
36
|
-
import { processQueue, scanFile, startWatcher, stopWatcher } from "./watcher.js";
|
|
36
|
+
import { createManualDispatch, processQueue, scanFile, startWatcher, stopWatcher, } from "./watcher.js";
|
|
37
37
|
export function createServerState(port = 11435) {
|
|
38
38
|
return { server: null, wss: null, port, startTime: 0 };
|
|
39
39
|
}
|
|
@@ -85,7 +85,7 @@ export function startServer(pi, serverState, watcherState) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
serverState.vaultPath = vaultPath;
|
|
88
|
-
serverState.server = http.createServer((req, res) => {
|
|
88
|
+
serverState.server = http.createServer(async (req, res) => {
|
|
89
89
|
// CORS for localhost-only access
|
|
90
90
|
res.setHeader("Access-Control-Allow-Origin", `http://localhost:${serverState.port}`);
|
|
91
91
|
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
@@ -116,7 +116,7 @@ export function startServer(pi, serverState, watcherState) {
|
|
|
116
116
|
res.end(JSON.stringify({ error: "Method not allowed" }));
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
|
-
handleDispatch(req, res, pi, watcherState);
|
|
119
|
+
await handleDispatch(req, res, pi, watcherState, serverState);
|
|
120
120
|
break;
|
|
121
121
|
case "/vault-mind/context":
|
|
122
122
|
if (req.method === "POST") {
|
|
@@ -224,6 +224,14 @@ export function startServer(pi, serverState, watcherState) {
|
|
|
224
224
|
}
|
|
225
225
|
withAuth(req, res, () => handleVmPending(res, serverState));
|
|
226
226
|
break;
|
|
227
|
+
case "/vm/stats":
|
|
228
|
+
if (req.method !== "GET") {
|
|
229
|
+
res.writeHead(405);
|
|
230
|
+
res.end(JSON.stringify({ error: "Method not allowed" }));
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
withAuth(req, res, () => handleVmStatsRoute(res, serverState));
|
|
234
|
+
break;
|
|
227
235
|
default:
|
|
228
236
|
if (url.pathname.startsWith("/agent/jobs/")) {
|
|
229
237
|
withAuth(req, res, () => handleAgentJob(req, res, url.pathname), {
|
|
@@ -427,11 +435,61 @@ function handleScan(req, res, pi, watcherState) {
|
|
|
427
435
|
}
|
|
428
436
|
});
|
|
429
437
|
}
|
|
430
|
-
function handleDispatch(req, res,
|
|
438
|
+
async function handleDispatch(req, res, pi, watcherState, serverState) {
|
|
439
|
+
let body;
|
|
440
|
+
try {
|
|
441
|
+
body = await readJsonBody(req);
|
|
442
|
+
}
|
|
443
|
+
catch {
|
|
444
|
+
res.writeHead(400);
|
|
445
|
+
res.end(JSON.stringify({ error: "Invalid JSON body" }));
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
if (!body || typeof body !== "object") {
|
|
449
|
+
res.writeHead(400);
|
|
450
|
+
res.end(JSON.stringify({ error: "Expected a JSON object body" }));
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
if (!("role" in body) || typeof body.role !== "string" || body.role.trim() === "") {
|
|
454
|
+
res.writeHead(400);
|
|
455
|
+
res.end(JSON.stringify({ error: "Missing or invalid 'role' field" }));
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
if (!("instruction" in body) ||
|
|
459
|
+
typeof body.instruction !== "string" ||
|
|
460
|
+
body.instruction.trim() === "") {
|
|
461
|
+
res.writeHead(400);
|
|
462
|
+
res.end(JSON.stringify({ error: "Missing or invalid 'instruction' field" }));
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
if ("file" in body && body.file !== undefined && typeof body.file !== "string") {
|
|
466
|
+
res.writeHead(400);
|
|
467
|
+
res.end(JSON.stringify({ error: "'file' must be a string when provided" }));
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
if ("vault" in body && body.vault !== undefined && typeof body.vault !== "string") {
|
|
471
|
+
res.writeHead(400);
|
|
472
|
+
res.end(JSON.stringify({ error: "'vault' must be a string when provided" }));
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const role = body.role.trim();
|
|
476
|
+
const instruction = body.instruction.trim();
|
|
477
|
+
const file = "file" in body && typeof body.file === "string" ? body.file : undefined;
|
|
478
|
+
const vault = "vault" in body && typeof body.vault === "string" ? body.vault : undefined;
|
|
479
|
+
const vaultPath = vault || serverState.vaultPath || process.cwd();
|
|
480
|
+
const result = createManualDispatch(pi, watcherState, {
|
|
481
|
+
role,
|
|
482
|
+
instruction,
|
|
483
|
+
filePath: file,
|
|
484
|
+
vaultPath,
|
|
485
|
+
});
|
|
486
|
+
if ("error" in result) {
|
|
487
|
+
res.writeHead(500);
|
|
488
|
+
res.end(JSON.stringify({ error: result.error }));
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
431
491
|
res.writeHead(200);
|
|
432
|
-
res.end(JSON.stringify({
|
|
433
|
-
message: "Manual dispatch not yet implemented. Use /vm watcher status for state.",
|
|
434
|
-
}));
|
|
492
|
+
res.end(JSON.stringify({ ok: true, jobId: result.jobId, message: result.message }));
|
|
435
493
|
}
|
|
436
494
|
async function handleVaultMindContextUpdate(req, res, serverState) {
|
|
437
495
|
const body = (await readJsonBody(req));
|
|
@@ -1009,3 +1067,34 @@ function handleVmPending(res, serverState) {
|
|
|
1009
1067
|
res.writeHead(200);
|
|
1010
1068
|
res.end(JSON.stringify({ pending }));
|
|
1011
1069
|
}
|
|
1070
|
+
function handleVmStatsRoute(res, serverState) {
|
|
1071
|
+
const vaultPath = serverState.vaultPath || process.cwd();
|
|
1072
|
+
const cfg = loadConfig(vaultPath);
|
|
1073
|
+
const collections = [];
|
|
1074
|
+
for (const [name, def] of Object.entries(cfg.collections)) {
|
|
1075
|
+
let count = 0;
|
|
1076
|
+
let malformed = 0;
|
|
1077
|
+
let size = 0;
|
|
1078
|
+
if (fs.existsSync(def.path)) {
|
|
1079
|
+
try {
|
|
1080
|
+
size = fs.statSync(def.path).size;
|
|
1081
|
+
const lines = fs.readFileSync(def.path, "utf-8").split("\n").filter(Boolean);
|
|
1082
|
+
for (const line of lines) {
|
|
1083
|
+
try {
|
|
1084
|
+
JSON.parse(line);
|
|
1085
|
+
count++;
|
|
1086
|
+
}
|
|
1087
|
+
catch {
|
|
1088
|
+
malformed++;
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
catch {
|
|
1093
|
+
// file unreadable — leave counts at 0
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
collections.push({ name, path: def.path, schema: def.schema, count, size, malformed });
|
|
1097
|
+
}
|
|
1098
|
+
res.writeHead(200);
|
|
1099
|
+
res.end(JSON.stringify({ collections }));
|
|
1100
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
/**
|
|
4
|
+
* Look up `symbol` in the `.codegraph/` index at `projectRoot` and return a
|
|
5
|
+
* concise, human-readable impact summary.
|
|
6
|
+
*
|
|
7
|
+
* Runs `codegraph impact` and `codegraph callers` in parallel, formats the
|
|
8
|
+
* results into a text block, and never throws — all errors surface as message
|
|
9
|
+
* strings suitable for direct tool output.
|
|
10
|
+
*/
|
|
11
|
+
export declare const getCodegraphImpact: (symbol: string, projectRoot: string) => Promise<string>;
|
|
12
|
+
export declare const vmCodegraphImpactTool: import("@earendil-works/pi-coding-agent").ToolDefinition<Type.TObject<{
|
|
13
|
+
symbol: Type.TString;
|
|
14
|
+
}>, {}, any> & import("@earendil-works/pi-coding-agent").ToolDefinition<any, any, any>;
|
|
15
|
+
export declare const registerCodegraphTool: (pi: ExtensionAPI) => void;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import * as cp from "node:child_process";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { defineTool, } from "@earendil-works/pi-coding-agent";
|
|
6
|
+
import { Type } from "typebox";
|
|
7
|
+
const execFile = promisify(cp.execFile);
|
|
8
|
+
// ── Core helper ──────────────────────────────────────────────────────────────
|
|
9
|
+
/**
|
|
10
|
+
* Look up `symbol` in the `.codegraph/` index at `projectRoot` and return a
|
|
11
|
+
* concise, human-readable impact summary.
|
|
12
|
+
*
|
|
13
|
+
* Runs `codegraph impact` and `codegraph callers` in parallel, formats the
|
|
14
|
+
* results into a text block, and never throws — all errors surface as message
|
|
15
|
+
* strings suitable for direct tool output.
|
|
16
|
+
*/
|
|
17
|
+
export const getCodegraphImpact = async (symbol, projectRoot) => {
|
|
18
|
+
if (!fs.existsSync(path.join(projectRoot, ".codegraph", "codegraph.db"))) {
|
|
19
|
+
return ("Codegraph index not found. A `.codegraph/` directory must exist at the " +
|
|
20
|
+
"project root. Run `codegraph init` then `codegraph index` to build it, " +
|
|
21
|
+
"and ensure the `codegraph` CLI is on PATH.");
|
|
22
|
+
}
|
|
23
|
+
const run = async (command) => {
|
|
24
|
+
try {
|
|
25
|
+
const { stdout } = await execFile("codegraph", [command, symbol, "--json"], {
|
|
26
|
+
cwd: projectRoot,
|
|
27
|
+
timeout: 15_000,
|
|
28
|
+
});
|
|
29
|
+
return stdout;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
// Run both queries in parallel for speed.
|
|
36
|
+
const [impactRaw, callersRaw] = await Promise.all([run("impact"), run("callers")]);
|
|
37
|
+
let impactData = null;
|
|
38
|
+
let callersData = null;
|
|
39
|
+
if (impactRaw) {
|
|
40
|
+
try {
|
|
41
|
+
impactData = JSON.parse(impactRaw);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Malformed JSON — treat as unavailable.
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (callersRaw) {
|
|
48
|
+
try {
|
|
49
|
+
callersData = JSON.parse(callersRaw);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Malformed JSON — treat as unavailable.
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!impactData && !callersData) {
|
|
56
|
+
return `Codegraph: no data returned for \`${symbol}\`. The symbol may not be in the index, or the \`codegraph\` CLI may be missing from PATH. Try running \`codegraph sync\` at the project root.`;
|
|
57
|
+
}
|
|
58
|
+
const lines = [`Codegraph impact for \`${symbol}\`:\n`];
|
|
59
|
+
// ── Direct callers ─────────────────────────────────────────────────────
|
|
60
|
+
if (callersData) {
|
|
61
|
+
const { callers } = callersData;
|
|
62
|
+
if (callers.length === 0) {
|
|
63
|
+
lines.push("Direct callers: none — this symbol may be an entry point or is not called directly.");
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
lines.push(`Direct callers (${callers.length}):`);
|
|
67
|
+
for (const c of callers) {
|
|
68
|
+
lines.push(` • ${c.name} [${c.kind}] ${c.filePath}:${c.startLine}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
lines.push("");
|
|
72
|
+
}
|
|
73
|
+
// ── Full impact set ────────────────────────────────────────────────────
|
|
74
|
+
if (impactData) {
|
|
75
|
+
// Exclude the queried symbol itself; report only downstream dependents.
|
|
76
|
+
const downstream = impactData.affected.filter((a) => a.name !== symbol);
|
|
77
|
+
if (downstream.length === 0) {
|
|
78
|
+
lines.push(`Full impact (depth ${impactData.depth}): no downstream dependents found.`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
lines.push(`Full impact (depth ${impactData.depth}, ${impactData.nodeCount} nodes, ${impactData.edgeCount} edges):`);
|
|
82
|
+
for (const a of downstream) {
|
|
83
|
+
lines.push(` • ${a.name} [${a.kind}] ${a.filePath}:${a.startLine}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return lines.join("\n");
|
|
88
|
+
};
|
|
89
|
+
// ── Tool definition ──────────────────────────────────────────────────────────
|
|
90
|
+
export const vmCodegraphImpactTool = defineTool({
|
|
91
|
+
name: "vm_codegraph_impact",
|
|
92
|
+
label: "Codegraph Impact",
|
|
93
|
+
description: "Report which code depends on a given symbol using the workspace codegraph index.",
|
|
94
|
+
promptSnippet: 'vm_codegraph_impact(symbol="registerTools")',
|
|
95
|
+
promptGuidelines: [
|
|
96
|
+
"Requires a `.codegraph/` index at the project root (`codegraph init && codegraph index`).",
|
|
97
|
+
"Returns direct callers and the full downstream impact set for the named symbol.",
|
|
98
|
+
"Useful for assessing blast radius before modifying an exported function, class, or type.",
|
|
99
|
+
],
|
|
100
|
+
parameters: Type.Object({
|
|
101
|
+
symbol: Type.String({
|
|
102
|
+
description: "Symbol name to look up (function, class, variable, type, etc.)",
|
|
103
|
+
}),
|
|
104
|
+
}),
|
|
105
|
+
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
106
|
+
const summary = await getCodegraphImpact(params.symbol, ctx.cwd);
|
|
107
|
+
return {
|
|
108
|
+
content: [{ type: "text", text: summary }],
|
|
109
|
+
details: {},
|
|
110
|
+
};
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
// ── Registration ─────────────────────────────────────────────────────────────
|
|
114
|
+
export const registerCodegraphTool = (pi) => {
|
|
115
|
+
const existing = new Set(pi.getAllTools().map((t) => t.name));
|
|
116
|
+
if (!existing.has("vm_codegraph_impact"))
|
|
117
|
+
pi.registerTool(vmCodegraphImpactTool);
|
|
118
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
export declare const isMarksmanAvailable: () => Promise<boolean>;
|
|
4
|
+
export type LspPosition = {
|
|
5
|
+
line: number;
|
|
6
|
+
character: number;
|
|
7
|
+
};
|
|
8
|
+
export type LspRange = {
|
|
9
|
+
start: LspPosition;
|
|
10
|
+
end: LspPosition;
|
|
11
|
+
};
|
|
12
|
+
export type LspLocation = {
|
|
13
|
+
uri: string;
|
|
14
|
+
range: LspRange;
|
|
15
|
+
};
|
|
16
|
+
export type LspDocumentLink = {
|
|
17
|
+
range: LspRange;
|
|
18
|
+
target?: string;
|
|
19
|
+
tooltip?: string;
|
|
20
|
+
};
|
|
21
|
+
export type LspDiagnostic = {
|
|
22
|
+
range: LspRange;
|
|
23
|
+
severity?: number;
|
|
24
|
+
code?: string | number;
|
|
25
|
+
source?: string;
|
|
26
|
+
message: string;
|
|
27
|
+
};
|
|
28
|
+
export type WorkspaceDiagnosticItem = {
|
|
29
|
+
uri: string;
|
|
30
|
+
kind?: number;
|
|
31
|
+
items: LspDiagnostic[];
|
|
32
|
+
};
|
|
33
|
+
export interface IMarksmanClient {
|
|
34
|
+
initialize(): Promise<void>;
|
|
35
|
+
openDocument(uri: string, text?: string): Promise<void>;
|
|
36
|
+
closeDocument(uri: string): Promise<void>;
|
|
37
|
+
documentLinks(uri: string): Promise<LspDocumentLink[]>;
|
|
38
|
+
documentSymbols(uri: string): Promise<unknown[]>;
|
|
39
|
+
references(uri: string, position: LspPosition): Promise<LspLocation[]>;
|
|
40
|
+
workspaceDiagnostics(): Promise<WorkspaceDiagnosticItem[]>;
|
|
41
|
+
shutdown(): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
export declare class MarksmanClient implements IMarksmanClient {
|
|
44
|
+
#private;
|
|
45
|
+
constructor(vaultPath: string);
|
|
46
|
+
initialize(): Promise<void>;
|
|
47
|
+
openDocument(uri: string, text?: string): Promise<void>;
|
|
48
|
+
closeDocument(uri: string): Promise<void>;
|
|
49
|
+
documentLinks(uri: string): Promise<LspDocumentLink[]>;
|
|
50
|
+
documentSymbols(uri: string): Promise<unknown[]>;
|
|
51
|
+
references(uri: string, position: LspPosition): Promise<LspLocation[]>;
|
|
52
|
+
workspaceDiagnostics(): Promise<WorkspaceDiagnosticItem[]>;
|
|
53
|
+
shutdown(): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
type Backlink = {
|
|
56
|
+
file: string;
|
|
57
|
+
target?: string;
|
|
58
|
+
range?: LspRange;
|
|
59
|
+
};
|
|
60
|
+
export declare const backlinksForNote: (client: IMarksmanClient, vaultPath: string, note: string) => Promise<{
|
|
61
|
+
note: string;
|
|
62
|
+
backlinks: Backlink[];
|
|
63
|
+
}>;
|
|
64
|
+
type BrokenLink = {
|
|
65
|
+
file: string;
|
|
66
|
+
message: string;
|
|
67
|
+
range?: LspRange;
|
|
68
|
+
};
|
|
69
|
+
export declare const brokenLinks: (client: IMarksmanClient, vaultPath: string) => Promise<{
|
|
70
|
+
broken: BrokenLink[];
|
|
71
|
+
}>;
|
|
72
|
+
type Edge = {
|
|
73
|
+
from: string;
|
|
74
|
+
to: string;
|
|
75
|
+
type: "backlink" | "forward";
|
|
76
|
+
};
|
|
77
|
+
export declare const relatedNotes: (client: IMarksmanClient, vaultPath: string, entity: string, depth?: number) => Promise<{
|
|
78
|
+
entity: string;
|
|
79
|
+
depth: number;
|
|
80
|
+
nodes: string[];
|
|
81
|
+
edges: Edge[];
|
|
82
|
+
titles: Record<string, string>;
|
|
83
|
+
}>;
|
|
84
|
+
export declare const vmBacklinksTool: import("@earendil-works/pi-coding-agent").ToolDefinition<Type.TObject<{
|
|
85
|
+
note: Type.TString;
|
|
86
|
+
}>, Record<string, unknown>, any> & import("@earendil-works/pi-coding-agent").ToolDefinition<any, any, any>;
|
|
87
|
+
export declare const vmBrokenLinksTool: import("@earendil-works/pi-coding-agent").ToolDefinition<Type.TObject<{}>, Record<string, unknown>, any> & import("@earendil-works/pi-coding-agent").ToolDefinition<any, any, any>;
|
|
88
|
+
export declare const vmRelatedTool: import("@earendil-works/pi-coding-agent").ToolDefinition<Type.TObject<{
|
|
89
|
+
entity: Type.TString;
|
|
90
|
+
depth: Type.TOptional<Type.TNumber>;
|
|
91
|
+
}>, Record<string, unknown>, any> & import("@earendil-works/pi-coding-agent").ToolDefinition<any, any, any>;
|
|
92
|
+
export declare const registerMarksmanTools: (pi: ExtensionAPI) => void;
|
|
93
|
+
export {};
|