pi-vault-mind 0.16.32 → 0.16.33
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 +10 -0
- package/dist/test/pvm-setup.test.js +24 -1
- package/package.json +1 -1
- package/runtime/pvm-extensions.json +2 -1
- package/scripts/pvm-setup.mjs +20 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.33 — 2026-08-29
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **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.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **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.
|
|
12
|
+
|
|
3
13
|
## 0.16.32 — 2026-08-28
|
|
4
14
|
|
|
5
15
|
### Changed
|
|
@@ -14,6 +14,7 @@ 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
|
+
"git:git@github.com:kylebrodeur/content-writing-system",
|
|
17
18
|
];
|
|
18
19
|
const runtimeSkills = [
|
|
19
20
|
"obsidian-cli",
|
|
@@ -124,7 +125,7 @@ fs.appendFileSync(process.env.PVM_TEST_UV_LOG, JSON.stringify(process.argv.slice
|
|
|
124
125
|
assert.ok(fs.existsSync(path.join(nlmSkillDir, "references", ref)), `nlm-skill reference missing: ${ref}`);
|
|
125
126
|
}
|
|
126
127
|
assert.doesNotMatch(result.stdout + result.stderr, /NOISY INSTALL/);
|
|
127
|
-
assert.match(result.stdout, /\[
|
|
128
|
+
assert.match(result.stdout, /\[7\/7\] git:git@github\.com:kylebrodeur\/content-writing-system \.\.\. done/);
|
|
128
129
|
assert.match(result.stdout, /Curated skills \(5\)/);
|
|
129
130
|
});
|
|
130
131
|
it("removes package paths that escape the vault-local agent directory", () => {
|
|
@@ -191,6 +192,28 @@ if (args[0] === "install" && args[1] === "npm:pi-context") {
|
|
|
191
192
|
assert.ok(fs.existsSync(path.join(vaultPath, ".vault-mind", ".pi", "agent", "skills", skill, "SKILL.md")));
|
|
192
193
|
}
|
|
193
194
|
});
|
|
195
|
+
it("skips extensions already present in the vault settings", () => {
|
|
196
|
+
const agentDir = path.join(vaultPath, ".vault-mind", ".pi", "agent");
|
|
197
|
+
fs.mkdirSync(agentDir, { recursive: true });
|
|
198
|
+
fs.writeFileSync(path.join(agentDir, "settings.json"), `${JSON.stringify({
|
|
199
|
+
packages: ["npm:pi-vault-mind", "npm:pi-context", "npm:pi-subagents@0.58.0"],
|
|
200
|
+
})}\n`);
|
|
201
|
+
const result = runSetup(["--resources-only", vaultPath]);
|
|
202
|
+
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
203
|
+
const installed = installedExtensions();
|
|
204
|
+
for (const present of ["npm:pi-vault-mind", "npm:pi-context", "npm:pi-subagents@0.58.0"]) {
|
|
205
|
+
assert.ok(!installed.includes(present), `expected ${present} to be skipped`);
|
|
206
|
+
}
|
|
207
|
+
for (const missing of [
|
|
208
|
+
"npm:@kylebrodeur/pi-model-discovery",
|
|
209
|
+
"npm:@kylebrodeur/pi-model-router",
|
|
210
|
+
"npm:@juicesharp/rpiv-todo@2.7.1",
|
|
211
|
+
"git:git@github.com:kylebrodeur/content-writing-system",
|
|
212
|
+
]) {
|
|
213
|
+
assert.ok(installed.includes(missing), `expected ${missing} to be installed`);
|
|
214
|
+
}
|
|
215
|
+
assert.match(result.stdout, /npm:pi-subagents@0\.58\.0 \.\.\. already installed/);
|
|
216
|
+
});
|
|
194
217
|
it("preserves customized configuration across repeated full setup", () => {
|
|
195
218
|
const first = runSetup([vaultPath]);
|
|
196
219
|
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.33",
|
|
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,8 @@
|
|
|
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
|
+
"git:git@github.com:kylebrodeur/content-writing-system"
|
|
9
10
|
],
|
|
10
11
|
"optional": ["npm:pi-1password"]
|
|
11
12
|
}
|
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
|
}
|