pi-vault-mind 0.9.0 → 0.9.2
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/dist/src/commands.js
CHANGED
|
@@ -33,7 +33,8 @@ const VM_USAGE = [
|
|
|
33
33
|
" /vm collection select Select active collection",
|
|
34
34
|
" /vm collection list List configured collections",
|
|
35
35
|
" /vm collection create Create a new collection (wizard)",
|
|
36
|
-
" /vm collection reindex Rebuild FTS + vector indexes
|
|
36
|
+
" /vm collection reindex Rebuild FTS + vector indexes",
|
|
37
|
+
" /vm index [--all] [--reembed] [--remote] Index collections (alias: reindex)",
|
|
37
38
|
" /vm discover-schema Infer schema from a JSONL file",
|
|
38
39
|
" /vm injector create Create a new injector (wizard)",
|
|
39
40
|
" /vm context enable|disable Enable/disable pi-context integration",
|
|
@@ -647,7 +648,7 @@ const handleReindex = async (args, ctx, pi) => {
|
|
|
647
648
|
lines.unshift("**Reindex Report:**", "");
|
|
648
649
|
lines.push("", rebuildEmbeddings
|
|
649
650
|
? "Entries will be re-embedded with current embedding model on next append."
|
|
650
|
-
: "Use /vm
|
|
651
|
+
: "Use /vm index --reembed to regenerate embeddings after model switch.");
|
|
651
652
|
ctx.ui.notify(lines.join("\n"), "info");
|
|
652
653
|
};
|
|
653
654
|
// ── /vm embedding ──────────────────────────────────────────────────────────
|
|
@@ -1561,7 +1562,7 @@ const handleToken = (args, ctx) => {
|
|
|
1561
1562
|
// ── Main /vm command ───────────────────────────────────────────────────────
|
|
1562
1563
|
export const registerCommands = (pi) => {
|
|
1563
1564
|
pi.registerCommand("vm", {
|
|
1564
|
-
description: "pi-vault-mind: manage collections, embedding,
|
|
1565
|
+
description: "pi-vault-mind: manage collections, embedding, indexing, and config.",
|
|
1565
1566
|
getArgumentCompletions: (_prefix) => {
|
|
1566
1567
|
const words = _prefix.trim().split(/\s+/);
|
|
1567
1568
|
const top = [
|
|
@@ -1582,6 +1583,8 @@ export const registerCommands = (pi) => {
|
|
|
1582
1583
|
"personalize",
|
|
1583
1584
|
"setup",
|
|
1584
1585
|
"token",
|
|
1586
|
+
"index",
|
|
1587
|
+
"reindex",
|
|
1585
1588
|
];
|
|
1586
1589
|
if (words.length === 1 || (words.length === 2 && words[1] === "")) {
|
|
1587
1590
|
return top
|
|
@@ -1690,6 +1693,9 @@ export const registerCommands = (pi) => {
|
|
|
1690
1693
|
return handleSetup(rest, ctx, pi);
|
|
1691
1694
|
case "token":
|
|
1692
1695
|
return handleToken(rest, ctx);
|
|
1696
|
+
case "index":
|
|
1697
|
+
case "reindex":
|
|
1698
|
+
return handleReindex(rest, ctx, pi);
|
|
1693
1699
|
default:
|
|
1694
1700
|
ctx.ui.notify(VM_USAGE, "info");
|
|
1695
1701
|
}
|
package/dist/src/index.js
CHANGED
|
@@ -37,7 +37,12 @@ export default function (pi) {
|
|
|
37
37
|
* during extension loading — the runtime must be initialized first. */
|
|
38
38
|
pi.on("session_start", async (_event, ctx) => {
|
|
39
39
|
updateActiveCollectionWidget(ctx);
|
|
40
|
-
|
|
40
|
+
/* Only enable ACM when this session has a vault configured */
|
|
41
|
+
const sessionCfg = loadConfig(ctx.cwd);
|
|
42
|
+
const piCtxCfg = sessionCfg.extensionCompatibility?.["pi-context"];
|
|
43
|
+
if (piCtxCfg?.enabled && piCtxCfg?.autoEnableAcm !== false) {
|
|
44
|
+
enableACM(pi);
|
|
45
|
+
}
|
|
41
46
|
/* register shortcut */
|
|
42
47
|
pi.registerShortcut("ctrl+alt+l", {
|
|
43
48
|
description: "Select Active Collection",
|
package/dist/src/settings-ui.js
CHANGED
|
@@ -8,10 +8,10 @@ const ONBOARDING_PLUGIN_REQUIREMENTS = [
|
|
|
8
8
|
id: "obsidian42-brat",
|
|
9
9
|
label: "BRAT (Beta Reviewer's Auto-update Tester)",
|
|
10
10
|
required: true,
|
|
11
|
-
reason: "required to install
|
|
11
|
+
reason: "required to install vault-mind plugin (not yet in community registry)",
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
|
-
id: "
|
|
14
|
+
id: "vault-mind",
|
|
15
15
|
label: "Vault Mind plugin",
|
|
16
16
|
required: true,
|
|
17
17
|
reason: "native setup/status/chat UI and local bridge controls",
|
|
@@ -67,7 +67,7 @@ const formatExecError = (err) => {
|
|
|
67
67
|
}
|
|
68
68
|
return err instanceof Error ? err.message : String(err);
|
|
69
69
|
};
|
|
70
|
-
const BRAT_REPO = "kylebrodeur/obsidian-
|
|
70
|
+
const BRAT_REPO = "kylebrodeur/obsidian-vault-mind";
|
|
71
71
|
const installViaBrat = () => {
|
|
72
72
|
try {
|
|
73
73
|
execFileSync("obsidian", ["eval", `app.plugins.getPlugin("obsidian42-brat").addPlugin("${BRAT_REPO}")`], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
|
|
@@ -79,7 +79,7 @@ const installViaBrat = () => {
|
|
|
79
79
|
};
|
|
80
80
|
const installObsidianPlugin = (pluginId) => {
|
|
81
81
|
// vault-mind plugin must be installed via BRAT (not in community registry)
|
|
82
|
-
if (pluginId === "
|
|
82
|
+
if (pluginId === "vault-mind") {
|
|
83
83
|
return installViaBrat();
|
|
84
84
|
}
|
|
85
85
|
try {
|
|
@@ -94,14 +94,14 @@ const installObsidianPlugin = (pluginId) => {
|
|
|
94
94
|
}
|
|
95
95
|
};
|
|
96
96
|
export const buildPluginInstallGuidance = (plugins) => {
|
|
97
|
-
const bratPlugins = plugins.filter((p) => p.id === "
|
|
98
|
-
const registryPlugins = plugins.filter((p) => p.id !== "
|
|
97
|
+
const bratPlugins = plugins.filter((p) => p.id === "vault-mind");
|
|
98
|
+
const registryPlugins = plugins.filter((p) => p.id !== "vault-mind");
|
|
99
99
|
const lines = ["Install missing Obsidian plugins:", ""];
|
|
100
100
|
if (registryPlugins.length > 0) {
|
|
101
101
|
lines.push("CLI (when Obsidian CLI is available):", ...registryPlugins.map((plugin) => ` obsidian plugin:install id=${plugin.id} enable`), "", "Deep links (open each URI):", ...registryPlugins.map((plugin) => ` obsidian://show-plugin?id=${encodeURIComponent(plugin.id)}`), "", "GUI fallback: Obsidian → Settings → Community plugins → Browse");
|
|
102
102
|
}
|
|
103
103
|
if (bratPlugins.length > 0) {
|
|
104
|
-
lines.push("", "Via BRAT (not yet in community registry):", ` Settings → BRAT → "Add Beta plugin" → ${BRAT_REPO}`, ` Or CLI: obsidian eval 'app.plugins.getPlugin("obsidian42-brat").addPlugin("${BRAT_REPO}")'`);
|
|
104
|
+
lines.push("", "Via BRAT (not yet in community registry):", ` Settings → BRAT → "Add Beta plugin" → ${BRAT_REPO}`, ` Or CLI: obsidian eval code='await app.plugins.getPlugin("obsidian42-brat").addPlugin("${BRAT_REPO}")'`);
|
|
105
105
|
}
|
|
106
106
|
return lines.join("\n");
|
|
107
107
|
};
|
|
@@ -408,6 +408,41 @@ export const setupWizard = async (ctx, cliArgs) => {
|
|
|
408
408
|
}
|
|
409
409
|
// ── Step 1.5: Obsidian plugin readiness ────────────────────────────────
|
|
410
410
|
await runPluginOnboarding(ctx, vaultPath);
|
|
411
|
+
// ── Step 1.6: Pi skills ────────────────────────────────────────────────
|
|
412
|
+
const installSkills = await ctx.ui.confirm("Pi skills", "Install recommended Obsidian skills for agents? (obsidian-markdown, obsidian-bases, json-canvas, obsidian-cli, defuddle)");
|
|
413
|
+
if (installSkills) {
|
|
414
|
+
try {
|
|
415
|
+
execFileSync("npx", [
|
|
416
|
+
"-y",
|
|
417
|
+
"skills",
|
|
418
|
+
"add",
|
|
419
|
+
"https://github.com/kepano/obsidian-skills",
|
|
420
|
+
"--skill",
|
|
421
|
+
"obsidian-markdown",
|
|
422
|
+
"--skill",
|
|
423
|
+
"obsidian-bases",
|
|
424
|
+
"--skill",
|
|
425
|
+
"json-canvas",
|
|
426
|
+
"--skill",
|
|
427
|
+
"obsidian-cli",
|
|
428
|
+
"--skill",
|
|
429
|
+
"defuddle",
|
|
430
|
+
"-g",
|
|
431
|
+
"-a",
|
|
432
|
+
"pi",
|
|
433
|
+
"--copy",
|
|
434
|
+
"-y",
|
|
435
|
+
], {
|
|
436
|
+
encoding: "utf-8",
|
|
437
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
438
|
+
env: { ...process.env, DISABLE_TELEMETRY: "1" },
|
|
439
|
+
});
|
|
440
|
+
ctx.ui.notify("✅ Pi skills installed.", "info");
|
|
441
|
+
}
|
|
442
|
+
catch (err) {
|
|
443
|
+
ctx.ui.notify(`⚠️ Skill install failed: ${formatExecError(err)}\nInstall manually: see INSTALL.md §Layer 2`, "warning");
|
|
444
|
+
}
|
|
445
|
+
}
|
|
411
446
|
// ── Step 2: Embedding config ──────────────────────────────────────────
|
|
412
447
|
let remoteUrl = "";
|
|
413
448
|
let localUrl = "";
|
|
@@ -529,22 +564,30 @@ export const setupWizard = async (ctx, cliArgs) => {
|
|
|
529
564
|
};
|
|
530
565
|
config.vaultMind.graph = config.vaultMind.graph || { enabled: true, canvasSync: true };
|
|
531
566
|
config.vaultMind.ftsEnabled = config.vaultMind.ftsEnabled !== false;
|
|
532
|
-
|
|
533
|
-
|
|
567
|
+
const dir = path.dirname(getGlobalConfigPath());
|
|
568
|
+
if (!fs.existsSync(dir))
|
|
569
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
570
|
+
fs.writeFileSync(getGlobalConfigPath(), `${JSON.stringify(config, null, 2)}\n`, "utf-8");
|
|
571
|
+
// Write extension compatibility to the PROJECT config (not global)
|
|
572
|
+
// so pi-context settings are scoped to this vault, not every session.
|
|
573
|
+
const projectCfgPath = path.join(vaultPath, "pi-vault-mind.config.json");
|
|
574
|
+
const projectCfg = fs.existsSync(projectCfgPath)
|
|
575
|
+
? JSON.parse(fs.readFileSync(projectCfgPath, "utf-8"))
|
|
576
|
+
: {};
|
|
577
|
+
projectCfg.extensionCompatibility = projectCfg.extensionCompatibility || {};
|
|
578
|
+
projectCfg.extensionCompatibility["pi-context"] = {
|
|
534
579
|
tagPatterns: [],
|
|
535
580
|
enhanceInjectors: false,
|
|
536
581
|
autoEnableAcm: true,
|
|
537
582
|
indexContextEvents: true,
|
|
538
|
-
...(
|
|
583
|
+
...(projectCfg.extensionCompatibility["pi-context"] || {}),
|
|
539
584
|
enabled: enableContextAutomation,
|
|
540
585
|
};
|
|
541
|
-
|
|
542
|
-
if (!fs.existsSync(dir))
|
|
543
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
544
|
-
fs.writeFileSync(getGlobalConfigPath(), `${JSON.stringify(config, null, 2)}\n`, "utf-8");
|
|
586
|
+
fs.writeFileSync(projectCfgPath, `${JSON.stringify(projectCfg, null, 2)}\n`, "utf-8");
|
|
545
587
|
ctx.ui.notify([
|
|
546
|
-
"✅
|
|
547
|
-
` ${getGlobalConfigPath()}`,
|
|
588
|
+
"✅ Config written!",
|
|
589
|
+
` Global: ${getGlobalConfigPath()}`,
|
|
590
|
+
` Project: ${projectCfgPath}`,
|
|
548
591
|
"",
|
|
549
592
|
` Vault: ${vaultPath}`,
|
|
550
593
|
` Remote: ${remoteUrl || "none"}`,
|
|
@@ -555,13 +598,6 @@ export const setupWizard = async (ctx, cliArgs) => {
|
|
|
555
598
|
"",
|
|
556
599
|
"Next: /vm watcher start (or restart pi for auto-start)",
|
|
557
600
|
].join("\n"), "info");
|
|
558
|
-
if (remoteUrl?.includes("modal.run")) {
|
|
559
|
-
ctx.ui.notify([
|
|
560
|
-
"Modal token reminder:",
|
|
561
|
-
"- /vm remote token",
|
|
562
|
-
"- ./scripts/fetch-modal-token.sh --write",
|
|
563
|
-
].join("\n"), "info");
|
|
564
|
-
}
|
|
565
601
|
};
|
|
566
602
|
/**
|
|
567
603
|
* Interactive Modal embedding configuration + "Test connection" action.
|
|
@@ -54,7 +54,7 @@ describe("setupWizard plugin onboarding helpers", () => {
|
|
|
54
54
|
const guidance = buildPluginInstallGuidance(getMissingOnboardingPlugins(vault));
|
|
55
55
|
assert.match(guidance, /obsidian plugin:install id=obsidian42-brat enable/);
|
|
56
56
|
assert.match(guidance, /obsidian plugin:install id=actions-uri enable/);
|
|
57
|
-
assert.match(guidance, /BRAT.*kylebrodeur\/obsidian-
|
|
57
|
+
assert.match(guidance, /BRAT.*kylebrodeur\/obsidian-vault-mind/);
|
|
58
58
|
fs.rmSync(vault, { recursive: true, force: true });
|
|
59
59
|
});
|
|
60
60
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-vault-mind",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"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.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"agents",
|
|
11
11
|
"skills",
|
|
12
12
|
"scripts",
|
|
13
|
+
"pi-vault-mind.config.example.json",
|
|
13
14
|
"CHANGELOG.md",
|
|
14
15
|
"README.md",
|
|
15
16
|
"LICENSE"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 2,
|
|
3
|
+
"collections": {
|
|
4
|
+
"main": {
|
|
5
|
+
"path": "collections/main.jsonl",
|
|
6
|
+
"schema": ["id", "domain", "source", "fact", "tag", "artifact"],
|
|
7
|
+
"dedupField": "fact"
|
|
8
|
+
},
|
|
9
|
+
"pending": {
|
|
10
|
+
"path": "collections/pending.jsonl",
|
|
11
|
+
"schema": "main"
|
|
12
|
+
},
|
|
13
|
+
"context_events": {
|
|
14
|
+
"path": "collections/context_events.jsonl",
|
|
15
|
+
"schema": ["id", "type", "session_entry_id", "content", "timestamp", "tags"],
|
|
16
|
+
"dedupField": "id"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"injectors": [],
|
|
20
|
+
"vaultMind": {
|
|
21
|
+
"dataDir": ".lancedb",
|
|
22
|
+
"embedding": {
|
|
23
|
+
"localUrl": "http://127.0.0.1:11434",
|
|
24
|
+
"useTransformers": true
|
|
25
|
+
},
|
|
26
|
+
"graph": {
|
|
27
|
+
"enabled": true,
|
|
28
|
+
"canvasSync": false
|
|
29
|
+
},
|
|
30
|
+
"ftsEnabled": true,
|
|
31
|
+
"httpPort": 11435,
|
|
32
|
+
"autoIndex": false
|
|
33
|
+
},
|
|
34
|
+
"extensionCompatibility": {
|
|
35
|
+
"pi-context": {
|
|
36
|
+
"enabled": true,
|
|
37
|
+
"tagPatterns": [],
|
|
38
|
+
"enhanceInjectors": false,
|
|
39
|
+
"autoEnableAcm": true,
|
|
40
|
+
"indexContextEvents": true
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scripts/publish-obsidian-plugin.sh
|
|
3
|
+
#
|
|
4
|
+
# Publishes the Obsidian plugin from packages/obsidian/ to the separate
|
|
5
|
+
# kylebrodeur/obsidian-vault-mind repo and creates a GitHub release.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# ./scripts/publish-obsidian-plugin.sh [version]
|
|
9
|
+
#
|
|
10
|
+
# If version is omitted, reads from packages/obsidian/manifest.json.
|
|
11
|
+
# Requires: gh (GitHub CLI), git, jq
|
|
12
|
+
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
16
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
17
|
+
PLUGIN_DIR="$REPO_ROOT/packages/obsidian"
|
|
18
|
+
TARGET_REPO="kylebrodeur/obsidian-vault-mind"
|
|
19
|
+
|
|
20
|
+
# Get version from manifest or argument
|
|
21
|
+
VERSION="${1:-$(jq -r .version "$PLUGIN_DIR/manifest.json")}"
|
|
22
|
+
echo "Publishing vault-mind plugin v$VERSION"
|
|
23
|
+
|
|
24
|
+
# Verify required files exist
|
|
25
|
+
for f in main.js manifest.json styles.css; do
|
|
26
|
+
if [ ! -f "$PLUGIN_DIR/$f" ]; then
|
|
27
|
+
echo "ERROR: $PLUGIN_DIR/$f not found. Run the plugin build first."
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
done
|
|
31
|
+
|
|
32
|
+
# Clone the target repo into a temp dir
|
|
33
|
+
TMPDIR="$(mktemp -d)"
|
|
34
|
+
trap 'rm -rf "$TMPDIR"' EXIT
|
|
35
|
+
|
|
36
|
+
if [ -n "${GH_TOKEN:-}" ]; then
|
|
37
|
+
git clone "https://x-access-token:${GH_TOKEN}@github.com/$TARGET_REPO.git" "$TMPDIR/repo" --depth 1
|
|
38
|
+
else
|
|
39
|
+
git clone "git@github.com:$TARGET_REPO.git" "$TMPDIR/repo" --depth 1
|
|
40
|
+
fi
|
|
41
|
+
cd "$TMPDIR/repo"
|
|
42
|
+
|
|
43
|
+
# Copy built assets
|
|
44
|
+
cp "$PLUGIN_DIR/main.js" .
|
|
45
|
+
cp "$PLUGIN_DIR/manifest.json" .
|
|
46
|
+
cp "$PLUGIN_DIR/styles.css" .
|
|
47
|
+
cp "$PLUGIN_DIR/versions.json" .
|
|
48
|
+
cp "$PLUGIN_DIR/README.md" .
|
|
49
|
+
|
|
50
|
+
# Commit and push if anything changed
|
|
51
|
+
if git diff --quiet && git diff --cached --quiet; then
|
|
52
|
+
echo "No changes to plugin files."
|
|
53
|
+
else
|
|
54
|
+
git add -A
|
|
55
|
+
git commit -m "release: v$VERSION"
|
|
56
|
+
git push origin main
|
|
57
|
+
echo "Pushed updated plugin files to $TARGET_REPO"
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# Create release with assets (tag = version, no 'v' prefix per Obsidian convention)
|
|
61
|
+
if gh release view "$VERSION" --repo "$TARGET_REPO" >/dev/null 2>&1; then
|
|
62
|
+
echo "Release $VERSION already exists, skipping."
|
|
63
|
+
else
|
|
64
|
+
gh release create "$VERSION" \
|
|
65
|
+
main.js \
|
|
66
|
+
manifest.json \
|
|
67
|
+
styles.css \
|
|
68
|
+
--repo "$TARGET_REPO" \
|
|
69
|
+
--title "v$VERSION" \
|
|
70
|
+
--notes "Release v$VERSION of the Vault Mind Obsidian plugin.
|
|
71
|
+
|
|
72
|
+
Install via BRAT: add \`kylebrodeur/obsidian-vault-mind\` as a beta plugin.
|
|
73
|
+
Or download assets and extract to \`.obsidian/plugins/vault-mind/\`."
|
|
74
|
+
echo "Created release $VERSION on $TARGET_REPO"
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
echo "Done."
|