pi-vault-mind 0.16.32 → 0.16.34
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 +16 -0
- package/dist/test/personalize.test.js +10 -0
- package/dist/test/pvm-setup.test.js +26 -1
- package/package.json +1 -1
- package/runtime/pvm-extensions.json +3 -1
- package/scripts/pvm-setup.mjs +20 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.34 — 2026-08-29
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Ollama web tools.** `pvm setup` now installs the official `@ollama/pi-web-search` extension as a required extension, giving the vault agent Ollama-backed web search and fetch tools.
|
|
8
|
+
|
|
9
|
+
## 0.16.33 — 2026-08-29
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Content-writing-system runtime.** `pvm setup` now installs the private `content-writing-system` Pi package (`git:git@github.com:kylebrodeur/content-writing-system`) as a required extension, registering both its skill and the `/check-writing` command in the vault-local agent. Requires git/SSH access to the repository at setup time.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- **Idempotent extension install.** `pvm setup` now reads the vault-local `settings.json` and skips extensions already present at the recorded spec (including pinned versions), reinstalling only missing specs or changed version pins. Repeated `pvm setup` / `--resources-only` runs no longer re-clone or re-fetch unchanged extensions.
|
|
18
|
+
|
|
3
19
|
## 0.16.32 — 2026-08-28
|
|
4
20
|
|
|
5
21
|
### Changed
|
|
@@ -138,6 +138,7 @@ const suggestionJson = (systemContent, agentsContent = "") => JSON.stringify({
|
|
|
138
138
|
describe("personalize", () => {
|
|
139
139
|
let testDir;
|
|
140
140
|
let savedHome;
|
|
141
|
+
let savedAgentDir;
|
|
141
142
|
beforeEach(() => {
|
|
142
143
|
testDir = path.join(tmpdir(), `pi-vault-mind-personalize-test-${randomUUID()}`);
|
|
143
144
|
fs.mkdirSync(testDir, { recursive: true });
|
|
@@ -145,12 +146,21 @@ describe("personalize", () => {
|
|
|
145
146
|
savedHome = process.env.HOME;
|
|
146
147
|
process.env.HOME = testDir;
|
|
147
148
|
process.env.USERPROFILE = testDir;
|
|
149
|
+
// Isolate the resolved agent dir under the temp vault so these tests never
|
|
150
|
+
// touch a real or inherited PI_CODING_AGENT_DIR (getAgentDir() would
|
|
151
|
+
// otherwise return that absolute path, ignoring the per-test cwd).
|
|
152
|
+
savedAgentDir = process.env.PI_CODING_AGENT_DIR;
|
|
153
|
+
process.env.PI_CODING_AGENT_DIR = path.join(testDir, ".pi", "agent");
|
|
148
154
|
});
|
|
149
155
|
afterEach(() => {
|
|
150
156
|
if (savedHome !== undefined)
|
|
151
157
|
process.env.HOME = savedHome;
|
|
152
158
|
else
|
|
153
159
|
process.env.HOME = undefined;
|
|
160
|
+
if (savedAgentDir !== undefined)
|
|
161
|
+
process.env.PI_CODING_AGENT_DIR = savedAgentDir;
|
|
162
|
+
else
|
|
163
|
+
delete process.env.PI_CODING_AGENT_DIR;
|
|
154
164
|
if (fs.existsSync(testDir))
|
|
155
165
|
fs.rmSync(testDir, { recursive: true });
|
|
156
166
|
});
|
|
@@ -14,6 +14,8 @@ const requiredExtensions = [
|
|
|
14
14
|
"npm:@kylebrodeur/pi-model-router",
|
|
15
15
|
"npm:@juicesharp/rpiv-todo@2.7.1",
|
|
16
16
|
"npm:pi-subagents@0.58.0",
|
|
17
|
+
"npm:@ollama/pi-web-search",
|
|
18
|
+
"git:git@github.com:kylebrodeur/content-writing-system",
|
|
17
19
|
];
|
|
18
20
|
const runtimeSkills = [
|
|
19
21
|
"obsidian-cli",
|
|
@@ -124,7 +126,7 @@ fs.appendFileSync(process.env.PVM_TEST_UV_LOG, JSON.stringify(process.argv.slice
|
|
|
124
126
|
assert.ok(fs.existsSync(path.join(nlmSkillDir, "references", ref)), `nlm-skill reference missing: ${ref}`);
|
|
125
127
|
}
|
|
126
128
|
assert.doesNotMatch(result.stdout + result.stderr, /NOISY INSTALL/);
|
|
127
|
-
assert.match(result.stdout, /\[
|
|
129
|
+
assert.match(result.stdout, /\[8\/8\] git:git@github\.com:kylebrodeur\/content-writing-system \.\.\. done/);
|
|
128
130
|
assert.match(result.stdout, /Curated skills \(5\)/);
|
|
129
131
|
});
|
|
130
132
|
it("removes package paths that escape the vault-local agent directory", () => {
|
|
@@ -191,6 +193,29 @@ if (args[0] === "install" && args[1] === "npm:pi-context") {
|
|
|
191
193
|
assert.ok(fs.existsSync(path.join(vaultPath, ".vault-mind", ".pi", "agent", "skills", skill, "SKILL.md")));
|
|
192
194
|
}
|
|
193
195
|
});
|
|
196
|
+
it("skips extensions already present in the vault settings", () => {
|
|
197
|
+
const agentDir = path.join(vaultPath, ".vault-mind", ".pi", "agent");
|
|
198
|
+
fs.mkdirSync(agentDir, { recursive: true });
|
|
199
|
+
fs.writeFileSync(path.join(agentDir, "settings.json"), `${JSON.stringify({
|
|
200
|
+
packages: ["npm:pi-vault-mind", "npm:pi-context", "npm:pi-subagents@0.58.0"],
|
|
201
|
+
})}\n`);
|
|
202
|
+
const result = runSetup(["--resources-only", vaultPath]);
|
|
203
|
+
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
204
|
+
const installed = installedExtensions();
|
|
205
|
+
for (const present of ["npm:pi-vault-mind", "npm:pi-context", "npm:pi-subagents@0.58.0"]) {
|
|
206
|
+
assert.ok(!installed.includes(present), `expected ${present} to be skipped`);
|
|
207
|
+
}
|
|
208
|
+
for (const missing of [
|
|
209
|
+
"npm:@kylebrodeur/pi-model-discovery",
|
|
210
|
+
"npm:@kylebrodeur/pi-model-router",
|
|
211
|
+
"npm:@juicesharp/rpiv-todo@2.7.1",
|
|
212
|
+
"npm:@ollama/pi-web-search",
|
|
213
|
+
"git:git@github.com:kylebrodeur/content-writing-system",
|
|
214
|
+
]) {
|
|
215
|
+
assert.ok(installed.includes(missing), `expected ${missing} to be installed`);
|
|
216
|
+
}
|
|
217
|
+
assert.match(result.stdout, /npm:pi-subagents@0\.58\.0 \.\.\. already installed/);
|
|
218
|
+
});
|
|
194
219
|
it("preserves customized configuration across repeated full setup", () => {
|
|
195
220
|
const first = runSetup([vaultPath]);
|
|
196
221
|
assert.equal(first.status, 0, first.stderr || first.stdout);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-vault-mind",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.34",
|
|
4
4
|
"packageManager": "pnpm@10.34.5",
|
|
5
5
|
"description": "Passive Obsidian vault extension for pi. Watches @agent markers, dispatches forked subagents (Miner, Broadcaster, Heavy-Lifter), stores in LanceDB with vector + FTS + graph. Multi-agent 'Drop & Forget' workflow for the pi agent ecosystem.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
"npm:@kylebrodeur/pi-model-discovery",
|
|
6
6
|
"npm:@kylebrodeur/pi-model-router",
|
|
7
7
|
"npm:@juicesharp/rpiv-todo@2.7.1",
|
|
8
|
-
"npm:pi-subagents@0.58.0"
|
|
8
|
+
"npm:pi-subagents@0.58.0",
|
|
9
|
+
"npm:@ollama/pi-web-search",
|
|
10
|
+
"git:git@github.com:kylebrodeur/content-writing-system"
|
|
9
11
|
],
|
|
10
12
|
"optional": ["npm:pi-1password"]
|
|
11
13
|
}
|
package/scripts/pvm-setup.mjs
CHANGED
|
@@ -158,6 +158,21 @@ function removeStaleExtensions(agentDir) {
|
|
|
158
158
|
for (const extension of STALE_EXTENSIONS) removeStaleExtension(extension, agentDir);
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
function readInstalledPackages(agentDir) {
|
|
162
|
+
const settingsPath = path.join(agentDir, "settings.json");
|
|
163
|
+
try {
|
|
164
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
|
165
|
+
if (!Array.isArray(settings.packages)) return new Set();
|
|
166
|
+
return new Set(
|
|
167
|
+
settings.packages
|
|
168
|
+
.map((entry) => (typeof entry === "string" ? entry : entry?.source))
|
|
169
|
+
.filter((source) => typeof source === "string")
|
|
170
|
+
);
|
|
171
|
+
} catch {
|
|
172
|
+
return new Set();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
161
176
|
function installExtensions(agentDir) {
|
|
162
177
|
const manifest = readExtensionManifest();
|
|
163
178
|
const extensions = [...manifest.required];
|
|
@@ -168,8 +183,13 @@ function installExtensions(agentDir) {
|
|
|
168
183
|
}
|
|
169
184
|
}
|
|
170
185
|
|
|
186
|
+
const installed = readInstalledPackages(agentDir);
|
|
171
187
|
console.log(`==> Pi extensions (${extensions.length})`);
|
|
172
188
|
for (const [index, extension] of extensions.entries()) {
|
|
189
|
+
if (installed.has(extension)) {
|
|
190
|
+
console.log(` [${index + 1}/${extensions.length}] ${extension} ... already installed`);
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
173
193
|
installExtension(extension, agentDir, index + 1, extensions.length);
|
|
174
194
|
}
|
|
175
195
|
}
|