pi-vault-mind 0.14.2 → 0.16.3
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 +293 -0
- package/README.md +5 -5
- package/agents/broadcaster.agent.md +2 -2
- package/agents/heavy-lifter.agent.md +1 -1
- package/agents/main.agent.md +29 -0
- package/agents/manager.agent.md +1 -1
- package/agents/miner.agent.md +1 -1
- package/dist/packages/obsidian/src/client.js +331 -0
- package/dist/packages/obsidian/src/types.js +1 -0
- package/dist/src/activity.d.ts +49 -0
- package/dist/src/activity.js +175 -0
- package/dist/src/agent-bus/Agent.d.ts +9 -1
- package/dist/src/agent-bus/Agent.js +18 -2
- package/dist/src/agent-bus/index.d.ts +5 -5
- package/dist/src/agent-bus/index.js +1 -1
- package/dist/src/agent-queue.js +12 -3
- package/dist/src/agents/BroadcasterAgent.d.ts +1 -1
- package/dist/src/agents/BroadcasterAgent.js +2 -2
- package/dist/src/agents/HeavyLifterAgent.d.ts +1 -1
- package/dist/src/agents/HeavyLifterAgent.js +2 -2
- package/dist/src/agents/ManagerAgent.js +1 -1
- package/dist/src/agents/MinerAgent.d.ts +1 -1
- package/dist/src/agents/MinerAgent.js +2 -2
- package/dist/src/agents/index.d.ts +2 -2
- package/dist/src/agents/index.js +2 -2
- package/dist/src/auth.d.ts +17 -15
- package/dist/src/auth.js +26 -37
- package/dist/src/autosync.js +2 -2
- package/dist/src/commands.d.ts +2 -19
- package/dist/src/commands.js +301 -231
- package/dist/src/config-keys.d.ts +16 -0
- package/dist/src/config-keys.js +45 -0
- package/dist/src/discover-schema.js +4 -4
- package/dist/src/edits.d.ts +21 -0
- package/dist/src/edits.js +75 -0
- package/dist/src/embedding-probe.d.ts +34 -0
- package/dist/src/embedding-probe.js +142 -0
- package/dist/src/embedding-providers.d.ts +133 -0
- package/dist/src/embedding-providers.js +173 -0
- package/dist/src/embedding-secrets.d.ts +38 -0
- package/dist/src/embedding-secrets.js +291 -0
- package/dist/src/engine.d.ts +6 -0
- package/dist/src/engine.js +78 -6
- package/dist/src/events.js +7 -10
- package/dist/src/extension-packages.d.ts +9 -0
- package/dist/src/extension-packages.js +14 -0
- package/dist/src/git.d.ts +19 -0
- package/dist/src/git.js +78 -0
- package/dist/src/graph.d.ts +2 -1
- package/dist/src/graph.js +47 -13
- package/dist/src/identities-config.d.ts +6 -0
- package/dist/src/identities-config.js +39 -0
- package/dist/src/identity-injector.js +1 -1
- package/dist/src/index.js +9 -26
- package/dist/src/lance.d.ts +9 -0
- package/dist/src/lance.js +143 -203
- package/dist/src/modal-client.d.ts +16 -0
- package/dist/src/modal-client.js +16 -0
- package/dist/src/modal-config.d.ts +37 -14
- package/dist/src/modal-config.js +59 -32
- package/dist/src/model-router.d.ts +27 -0
- package/dist/src/model-router.js +67 -0
- package/dist/src/models.d.ts +42 -0
- package/dist/src/models.js +78 -0
- package/dist/src/personalize.js +17 -3
- package/dist/src/scaffold.d.ts +48 -0
- package/dist/src/scaffold.js +246 -0
- package/dist/src/server.d.ts +47 -4
- package/dist/src/server.js +988 -221
- package/dist/src/session-search.d.ts +63 -0
- package/dist/src/session-search.js +379 -0
- package/dist/src/settings-ui.d.ts +2 -2
- package/dist/src/settings-ui.js +76 -135
- package/dist/src/sync.d.ts +3 -3
- package/dist/src/sync.js +19 -15
- package/dist/src/tool-catalog.d.ts +18 -0
- package/dist/src/tool-catalog.js +232 -0
- package/dist/src/tools/marksman.js +1 -1
- package/dist/src/tools.js +111 -65
- package/dist/src/types.d.ts +127 -71
- package/dist/src/utils.d.ts +57 -6
- package/dist/src/utils.js +114 -28
- package/dist/src/vault-tools.d.ts +34 -0
- package/dist/src/vault-tools.js +99 -0
- package/dist/src/vault-writer.js +4 -1
- package/dist/src/vm-handlers.js +140 -43
- package/dist/src/watcher.js +9 -9
- package/dist/test/activity-tool.test.js +54 -0
- package/dist/test/agent-bus/Agent.test.js +174 -0
- package/dist/test/agent-bus/AgentLoader.test.js +180 -0
- package/dist/test/agent-bus/AgentRegistry.test.js +86 -0
- package/dist/test/agent-bus/LLMProvider.test.js +162 -0
- package/dist/test/agent-bus/TaskQueue.test.js +256 -0
- package/dist/test/agent-dispatch-context.test.js +73 -0
- package/dist/test/agent-queue.test.js +1 -1
- package/dist/test/agents/Agents.test.js +282 -0
- package/dist/test/auth.test.js +57 -56
- package/dist/test/bridge-identity.test.js +34 -3
- package/dist/test/classify-search-mode.test.js +51 -0
- package/dist/test/commands.test.js +410 -0
- package/dist/test/config-merge.test.js +98 -0
- package/dist/test/context-capture.test.js +56 -0
- package/dist/test/discover-schema.test.js +8 -5
- package/dist/test/dispatch.test.js +45 -91
- package/dist/test/edits.test.js +144 -0
- package/dist/test/embedding-probe.test.js +424 -0
- package/dist/test/embedding-providers.test.js +157 -0
- package/dist/test/embedding-secrets.test.js +210 -0
- package/dist/test/engine-identity.test.js +1 -1
- package/dist/test/events.test.js +675 -0
- package/dist/test/git-bridge.test.js +160 -0
- package/dist/test/graph.test.js +464 -0
- package/dist/test/helpers/server.js +81 -0
- package/dist/test/identity-injector.test.js +197 -0
- package/dist/test/index.test.js +5 -7
- package/dist/test/lance-modal.test.js +67 -2
- package/dist/test/lance.test.js +429 -0
- package/dist/test/modal-client.test.js +1 -1
- package/dist/test/modal-config.test.js +92 -79
- package/dist/test/model-readiness.test.js +122 -0
- package/dist/test/model-router.test.js +99 -0
- package/dist/test/obsidian-client.test.js +42 -0
- package/dist/test/personalize.test.js +1 -1
- package/dist/test/rest-models.test.js +153 -0
- package/dist/test/rest-queue.test.js +135 -87
- package/dist/test/rest-setup.test.js +625 -115
- package/dist/test/rest-vm.test.js +355 -94
- package/dist/test/server-cors.test.js +48 -0
- package/dist/test/server-ws.test.js +61 -34
- package/dist/test/session-crud.test.js +323 -0
- package/dist/test/session-search.test.js +139 -0
- package/dist/test/settings-ui.test.js +113 -4
- package/dist/test/sync.test.js +12 -12
- package/dist/test/tombstone.test.js +8 -10
- package/dist/test/tool-catalog.test.js +86 -0
- package/dist/test/utils.test.js +588 -0
- package/dist/test/vault-tools.test.js +103 -12
- package/dist/test/vault-writer.test.js +371 -0
- package/dist/test/vm-handlers.test.js +620 -0
- package/extension-packages.json +9 -0
- package/package.json +107 -90
- package/pi-vault-mind.config.example.json +24 -2
- package/scripts/check-deps.sh +35 -32
- package/scripts/cli-e2e.mjs +215 -0
- package/scripts/configuration-e2e.mjs +783 -0
- package/scripts/e2e-commands.mjs +391 -0
- package/scripts/e2e-ws.mjs +3 -2
- package/scripts/fetch-modal-token.sh +4 -3
- package/scripts/generate-config-keys-json.mjs +45 -0
- package/scripts/generate-extension-packages-json.mjs +55 -0
- package/scripts/pi-session-query +0 -0
- package/scripts/publish-obsidian-plugin.sh +0 -0
- package/scripts/reset-test-vault.sh +2 -2
- package/scripts/setup-test-config.sh +0 -0
- package/scripts/setup-vault-pi.sh +48 -9
- package/scripts/test-slash-commands.mjs +2 -2
- package/scripts/vault-pi.sh +12 -3
- package/skills/github-release-notes-file/SKILL.md +42 -0
- package/skills/obsidian-guided-test-session/SKILL.md +110 -0
- package/skills/obsidian-interactive-test/SKILL.md +88 -0
- package/skills/obsidian-plugin-publish/SKILL.md +58 -0
- package/skills/pi-vault-mind-release/SKILL.md +141 -0
- package/skills/pre-test-release/SKILL.md +116 -0
- package/dist/test/auto-indexer.test.js +0 -2
package/dist/src/agent-queue.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import * as fs from "node:fs";
|
|
14
14
|
import * as path from "node:path";
|
|
15
|
+
import { loadConfig, resolveVaultFile } from "./utils.js";
|
|
15
16
|
const queueSubscribers = new Set();
|
|
16
17
|
/** Subscribe to queue events. Returns an unsubscribe function. */
|
|
17
18
|
export const subscribeQueue = (cb) => {
|
|
@@ -35,8 +36,16 @@ const eventTypeFor = (status, prev) => {
|
|
|
35
36
|
return "job-completed";
|
|
36
37
|
return "job-updated";
|
|
37
38
|
};
|
|
38
|
-
|
|
39
|
-
const
|
|
39
|
+
/** Per-vault queue path, resolved from config once and memoized. */
|
|
40
|
+
const queuePathCache = new Map();
|
|
41
|
+
const queuePath = (vaultPath) => {
|
|
42
|
+
const cached = queuePathCache.get(vaultPath);
|
|
43
|
+
if (cached)
|
|
44
|
+
return cached;
|
|
45
|
+
const resolved = path.join(vaultPath, resolveVaultFile(loadConfig(vaultPath).vaultMind, "queue"));
|
|
46
|
+
queuePathCache.set(vaultPath, resolved);
|
|
47
|
+
return resolved;
|
|
48
|
+
};
|
|
40
49
|
const ensureQueueDir = (vaultPath) => {
|
|
41
50
|
const dir = path.dirname(queuePath(vaultPath));
|
|
42
51
|
if (!fs.existsSync(dir)) {
|
|
@@ -125,7 +134,7 @@ export const markJobRunning = (vaultPath, id) => {
|
|
|
125
134
|
/** Mark a pending job as cancelled. */
|
|
126
135
|
export const cancelJob = (vaultPath, id) => {
|
|
127
136
|
const current = getJob(vaultPath, id);
|
|
128
|
-
if (
|
|
137
|
+
if (current?.status !== "pending")
|
|
129
138
|
return undefined;
|
|
130
139
|
return updateJob(vaultPath, id, "cancelled");
|
|
131
140
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* BroadcasterAgent — content distribution agent.
|
|
3
3
|
*
|
|
4
|
-
* Allowed tools: read, write, edit, vm_search
|
|
4
|
+
* Allowed tools: read, write, edit, vm_search
|
|
5
5
|
* Cannot write to durable store or publish.
|
|
6
6
|
* Writes output only under Agent/Presentations/.
|
|
7
7
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* BroadcasterAgent — content distribution agent.
|
|
3
3
|
*
|
|
4
|
-
* Allowed tools: read, write, edit, vm_search
|
|
4
|
+
* Allowed tools: read, write, edit, vm_search
|
|
5
5
|
* Cannot write to durable store or publish.
|
|
6
6
|
* Writes output only under Agent/Presentations/.
|
|
7
7
|
*/
|
|
@@ -25,7 +25,7 @@ export class BroadcasterAgent extends Agent {
|
|
|
25
25
|
if (!this.taskQueue.claim(taskId, this.config.id))
|
|
26
26
|
return;
|
|
27
27
|
try {
|
|
28
|
-
await this.executeJob(job);
|
|
28
|
+
await this.withDispatchContext(job.dispatchId, () => this.executeJob(job));
|
|
29
29
|
this.taskQueue.complete(taskId, this.config.id, { dispatchId: job.dispatchId });
|
|
30
30
|
await this.broadcast("JOB_COMPLETED", {
|
|
31
31
|
dispatchId: job.dispatchId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* HeavyLifterAgent — external CLI execution agent.
|
|
3
3
|
*
|
|
4
|
-
* Allowed tools: read, write, edit, grep, find, ls, bash, vm_search
|
|
4
|
+
* Allowed tools: read, write, edit, grep, find, ls, bash, vm_search
|
|
5
5
|
* Cannot write to durable store or publish.
|
|
6
6
|
* Runs bash in isolated worktree.
|
|
7
7
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* HeavyLifterAgent — external CLI execution agent.
|
|
3
3
|
*
|
|
4
|
-
* Allowed tools: read, write, edit, grep, find, ls, bash, vm_search
|
|
4
|
+
* Allowed tools: read, write, edit, grep, find, ls, bash, vm_search
|
|
5
5
|
* Cannot write to durable store or publish.
|
|
6
6
|
* Runs bash in isolated worktree.
|
|
7
7
|
*/
|
|
@@ -25,7 +25,7 @@ export class HeavyLifterAgent extends Agent {
|
|
|
25
25
|
if (!this.taskQueue.claim(taskId, this.config.id))
|
|
26
26
|
return;
|
|
27
27
|
try {
|
|
28
|
-
await this.executeJob(job);
|
|
28
|
+
await this.withDispatchContext(job.dispatchId, () => this.executeJob(job));
|
|
29
29
|
this.taskQueue.complete(taskId, this.config.id, { dispatchId: job.dispatchId });
|
|
30
30
|
await this.broadcast("JOB_COMPLETED", {
|
|
31
31
|
dispatchId: job.dispatchId,
|
|
@@ -26,7 +26,7 @@ export class ManagerAgent extends Agent {
|
|
|
26
26
|
if (!this.taskQueue.claim(taskId, this.config.id))
|
|
27
27
|
return;
|
|
28
28
|
try {
|
|
29
|
-
await this.executeJob(job);
|
|
29
|
+
await this.withDispatchContext(job.dispatchId, () => this.executeJob(job));
|
|
30
30
|
this.taskQueue.complete(taskId, this.config.id, { dispatchId: job.dispatchId });
|
|
31
31
|
await this.broadcast("JOB_COMPLETED", {
|
|
32
32
|
dispatchId: job.dispatchId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MinerAgent — knowledge extraction and storage agent.
|
|
3
3
|
*
|
|
4
|
-
* Allowed tools: read, write, edit, grep, find, ls, vm_search,
|
|
4
|
+
* Allowed tools: read, write, edit, grep, find, ls, vm_search, vm_append
|
|
5
5
|
* Write collections: main, research
|
|
6
6
|
* Cannot publish (vm_sync disabled).
|
|
7
7
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MinerAgent — knowledge extraction and storage agent.
|
|
3
3
|
*
|
|
4
|
-
* Allowed tools: read, write, edit, grep, find, ls, vm_search,
|
|
4
|
+
* Allowed tools: read, write, edit, grep, find, ls, vm_search, vm_append
|
|
5
5
|
* Write collections: main, research
|
|
6
6
|
* Cannot publish (vm_sync disabled).
|
|
7
7
|
*/
|
|
@@ -25,7 +25,7 @@ export class MinerAgent extends Agent {
|
|
|
25
25
|
if (!this.taskQueue.claim(taskId, this.config.id))
|
|
26
26
|
return;
|
|
27
27
|
try {
|
|
28
|
-
await this.executeJob(job);
|
|
28
|
+
await this.withDispatchContext(job.dispatchId, () => this.executeJob(job));
|
|
29
29
|
this.taskQueue.complete(taskId, this.config.id, { dispatchId: job.dispatchId });
|
|
30
30
|
await this.broadcast("JOB_COMPLETED", {
|
|
31
31
|
dispatchId: job.dispatchId,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { HeavyLifterAgent, type DispatchJob } from "./HeavyLifterAgent.js";
|
|
2
|
-
export { MinerAgent } from "./MinerAgent.js";
|
|
3
1
|
export { BroadcasterAgent } from "./BroadcasterAgent.js";
|
|
2
|
+
export { type DispatchJob, HeavyLifterAgent } from "./HeavyLifterAgent.js";
|
|
4
3
|
export { ManagerAgent } from "./ManagerAgent.js";
|
|
4
|
+
export { MinerAgent } from "./MinerAgent.js";
|
package/dist/src/agents/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { HeavyLifterAgent } from "./HeavyLifterAgent.js";
|
|
2
|
-
export { MinerAgent } from "./MinerAgent.js";
|
|
3
1
|
export { BroadcasterAgent } from "./BroadcasterAgent.js";
|
|
2
|
+
export { HeavyLifterAgent } from "./HeavyLifterAgent.js";
|
|
4
3
|
export { ManagerAgent } from "./ManagerAgent.js";
|
|
4
|
+
export { MinerAgent } from "./MinerAgent.js";
|
package/dist/src/auth.d.ts
CHANGED
|
@@ -3,18 +3,20 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Token resolution order:
|
|
5
5
|
* 1. `process.env.PVM_API_TOKEN`
|
|
6
|
-
* 2. `<
|
|
7
|
-
* 3. `vaultMind.embedding.modal.apiToken` in the loaded config
|
|
6
|
+
* 2. `<vault>/.vault-mind/vault-mind.env` (key=value, # comments)
|
|
8
7
|
*
|
|
9
8
|
* Returns `null` if no token is configured (auth is off until set).
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
* dotenv file is
|
|
13
|
-
*
|
|
10
|
+
* The token env path is resolved from the vault cwd via `getTokenEnvPath`;
|
|
11
|
+
* `chmod 600` on the dotenv file is best-effort and a no-op on win32 (the file
|
|
12
|
+
* system doesn't honor POSIX modes there).
|
|
13
|
+
*
|
|
14
|
+
* Provider credentials (PVM_REMOTE_EMBEDDING_API_KEY, PVM_MODAL_*_TOKEN,
|
|
15
|
+
* PVM_LOCAL_EMBEDDING_API_KEY) are intentionally never consulted for bridge
|
|
16
|
+
* authentication — see `src/embedding-secrets.ts` for provider secrets.
|
|
14
17
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export declare const resolveAuthToken: (cfg?: UniversalConfig) => string | null;
|
|
18
|
+
/** Resolve the bearer token from env or dotenv only. */
|
|
19
|
+
export declare const resolveAuthToken: () => string | null;
|
|
18
20
|
/** Resolved identity for a per-role bearer token. */
|
|
19
21
|
export interface TokenIdentity {
|
|
20
22
|
token: string;
|
|
@@ -49,7 +51,7 @@ export interface AuthResult {
|
|
|
49
51
|
* 2. Legacy `PVM_API_TOKEN` — returns `ok: true` with no identity (full access).
|
|
50
52
|
* 3. No token configured → `ok: true` (auth is off).
|
|
51
53
|
*/
|
|
52
|
-
export declare const authoriseRequest: (req: IncomingLike
|
|
54
|
+
export declare const authoriseRequest: (req: IncomingLike) => AuthResult;
|
|
53
55
|
/** Test-only: forget the cached token so tests get a fresh resolve on each call. */
|
|
54
56
|
export declare const _resetAuthCache: () => void;
|
|
55
57
|
/** Set an in-memory token override for the current process. Invalidates any cached value. */
|
|
@@ -58,16 +60,16 @@ export declare const setToken: (value: string) => void;
|
|
|
58
60
|
export declare const clearToken: () => void;
|
|
59
61
|
/**
|
|
60
62
|
* Revoke a role-specific bearer token by removing `PVM_TOKEN_<IDENTITY>`
|
|
61
|
-
* from
|
|
62
|
-
* Returns `true` if the variable was found and removed.
|
|
63
|
+
* from `<vault>/.vault-mind/vault-mind.env`. Preserves all other lines and
|
|
64
|
+
* comments. Returns `true` if the variable was found and removed.
|
|
63
65
|
*/
|
|
64
66
|
export declare const revokeToken: (identity: string) => boolean;
|
|
65
67
|
/**
|
|
66
68
|
* Generate a fresh 32-byte base64url token, persist it to
|
|
67
|
-
* `<
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
69
|
+
* `<vault>/.vault-mind/vault-mind.env` (replacing any existing `PVM_API_TOKEN`
|
|
70
|
+
* line while preserving all other lines and comments), create the directory +
|
|
71
|
+
* file if missing, apply `chmod 600` (best-effort; no-op on win32), update the
|
|
72
|
+
* in-process cache, and return the new token.
|
|
71
73
|
*
|
|
72
74
|
* **Env-var precedence note:** if `PVM_API_TOKEN` is exported as an environment
|
|
73
75
|
* variable it takes precedence over the dotenv file at resolution time, so the
|
package/dist/src/auth.js
CHANGED
|
@@ -3,28 +3,27 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Token resolution order:
|
|
5
5
|
* 1. `process.env.PVM_API_TOKEN`
|
|
6
|
-
* 2. `<
|
|
7
|
-
* 3. `vaultMind.embedding.modal.apiToken` in the loaded config
|
|
6
|
+
* 2. `<vault>/.vault-mind/vault-mind.env` (key=value, # comments)
|
|
8
7
|
*
|
|
9
8
|
* Returns `null` if no token is configured (auth is off until set).
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
* dotenv file is
|
|
13
|
-
*
|
|
10
|
+
* The token env path is resolved from the vault cwd via `getTokenEnvPath`;
|
|
11
|
+
* `chmod 600` on the dotenv file is best-effort and a no-op on win32 (the file
|
|
12
|
+
* system doesn't honor POSIX modes there).
|
|
13
|
+
*
|
|
14
|
+
* Provider credentials (PVM_REMOTE_EMBEDDING_API_KEY, PVM_MODAL_*_TOKEN,
|
|
15
|
+
* PVM_LOCAL_EMBEDDING_API_KEY) are intentionally never consulted for bridge
|
|
16
|
+
* authentication — see `src/embedding-secrets.ts` for provider secrets.
|
|
14
17
|
*/
|
|
15
18
|
import * as crypto from "node:crypto";
|
|
16
19
|
import * as fs from "node:fs";
|
|
17
|
-
import * as os from "node:os";
|
|
18
20
|
import * as path from "node:path";
|
|
21
|
+
import { getTokenEnvPath } from "./utils.js";
|
|
19
22
|
const ENV_VAR = "PVM_API_TOKEN";
|
|
20
|
-
const DOTENV_REL = path.join(".pi", "agent", "vault-mind.env");
|
|
21
23
|
/** Cached token resolution. The cache is invalidated by `setToken` / `clearToken`. */
|
|
22
24
|
let cached = null;
|
|
23
25
|
const readDotenvToken = () => {
|
|
24
|
-
const
|
|
25
|
-
if (!home)
|
|
26
|
-
return null;
|
|
27
|
-
const p = path.join(home, DOTENV_REL);
|
|
26
|
+
const p = getTokenEnvPath(process.cwd());
|
|
28
27
|
try {
|
|
29
28
|
const text = fs.readFileSync(p, "utf-8");
|
|
30
29
|
for (const line of text.split(/\r?\n/)) {
|
|
@@ -41,11 +40,8 @@ const readDotenvToken = () => {
|
|
|
41
40
|
}
|
|
42
41
|
return null;
|
|
43
42
|
};
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
};
|
|
47
|
-
/** Resolve the bearer token. `cfg` is optional; pass the loaded config to fall back to it. */
|
|
48
|
-
export const resolveAuthToken = (cfg) => {
|
|
43
|
+
/** Resolve the bearer token from env or dotenv only. */
|
|
44
|
+
export const resolveAuthToken = () => {
|
|
49
45
|
if (process.env[ENV_VAR])
|
|
50
46
|
return process.env[ENV_VAR] ?? null;
|
|
51
47
|
if (cached && cached.value !== null)
|
|
@@ -55,11 +51,6 @@ export const resolveAuthToken = (cfg) => {
|
|
|
55
51
|
cached = { value: fromFile };
|
|
56
52
|
return fromFile;
|
|
57
53
|
}
|
|
58
|
-
const fromCfg = readConfigToken(cfg);
|
|
59
|
-
if (fromCfg) {
|
|
60
|
-
cached = { value: fromCfg };
|
|
61
|
-
return fromCfg;
|
|
62
|
-
}
|
|
63
54
|
return null;
|
|
64
55
|
};
|
|
65
56
|
/**
|
|
@@ -106,16 +97,14 @@ const safeEqual = (a, b) => {
|
|
|
106
97
|
* 2. Legacy `PVM_API_TOKEN` — returns `ok: true` with no identity (full access).
|
|
107
98
|
* 3. No token configured → `ok: true` (auth is off).
|
|
108
99
|
*/
|
|
109
|
-
export const authoriseRequest = (req
|
|
100
|
+
export const authoriseRequest = (req) => {
|
|
110
101
|
const raw = req.headers.authorization;
|
|
111
102
|
const header = Array.isArray(raw) ? raw[0] : raw;
|
|
112
103
|
// Auth off: no tokens configured at all → allow everything
|
|
113
|
-
const
|
|
114
|
-
const hasLegacy = resolveAuthToken(cfg) !== null;
|
|
104
|
+
const hasLegacy = resolveAuthToken() !== null;
|
|
115
105
|
if (!hasLegacy && !hasAnyPerRoleToken()) {
|
|
116
|
-
// No tokens configured — auth is off, allow all requests
|
|
117
|
-
|
|
118
|
-
return { ok: true };
|
|
106
|
+
// No tokens configured — auth is off, allow all requests regardless of header
|
|
107
|
+
return { ok: true };
|
|
119
108
|
}
|
|
120
109
|
if (!header)
|
|
121
110
|
return { ok: false, reason: "missing" };
|
|
@@ -128,9 +117,9 @@ export const authoriseRequest = (req, cfg) => {
|
|
|
128
117
|
if (identity)
|
|
129
118
|
return { ok: true, identity };
|
|
130
119
|
// 2. Legacy single-token fallback
|
|
131
|
-
const expected = resolveAuthToken(
|
|
120
|
+
const expected = resolveAuthToken();
|
|
132
121
|
if (!expected)
|
|
133
|
-
return { ok:
|
|
122
|
+
return { ok: false, reason: "mismatch" }; // tokens are configured but none matched
|
|
134
123
|
if (!safeEqual(token, expected))
|
|
135
124
|
return { ok: false, reason: "mismatch" };
|
|
136
125
|
return { ok: true };
|
|
@@ -149,12 +138,12 @@ export const clearToken = () => {
|
|
|
149
138
|
};
|
|
150
139
|
/**
|
|
151
140
|
* Revoke a role-specific bearer token by removing `PVM_TOKEN_<IDENTITY>`
|
|
152
|
-
* from
|
|
153
|
-
* Returns `true` if the variable was found and removed.
|
|
141
|
+
* from `<vault>/.vault-mind/vault-mind.env`. Preserves all other lines and
|
|
142
|
+
* comments. Returns `true` if the variable was found and removed.
|
|
154
143
|
*/
|
|
155
144
|
export const revokeToken = (identity) => {
|
|
156
145
|
const varName = `PVM_TOKEN_${identity.toUpperCase()}`;
|
|
157
|
-
const dotenvPath =
|
|
146
|
+
const dotenvPath = getTokenEnvPath(process.cwd());
|
|
158
147
|
let lines = [];
|
|
159
148
|
try {
|
|
160
149
|
lines = fs.readFileSync(dotenvPath, "utf-8").split(/\r?\n/);
|
|
@@ -183,10 +172,10 @@ export const revokeToken = (identity) => {
|
|
|
183
172
|
};
|
|
184
173
|
/**
|
|
185
174
|
* Generate a fresh 32-byte base64url token, persist it to
|
|
186
|
-
* `<
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
175
|
+
* `<vault>/.vault-mind/vault-mind.env` (replacing any existing `PVM_API_TOKEN`
|
|
176
|
+
* line while preserving all other lines and comments), create the directory +
|
|
177
|
+
* file if missing, apply `chmod 600` (best-effort; no-op on win32), update the
|
|
178
|
+
* in-process cache, and return the new token.
|
|
190
179
|
*
|
|
191
180
|
* **Env-var precedence note:** if `PVM_API_TOKEN` is exported as an environment
|
|
192
181
|
* variable it takes precedence over the dotenv file at resolution time, so the
|
|
@@ -195,7 +184,7 @@ export const revokeToken = (identity) => {
|
|
|
195
184
|
*/
|
|
196
185
|
export const rotateToken = () => {
|
|
197
186
|
const newToken = crypto.randomBytes(32).toString("base64url");
|
|
198
|
-
const dotenvPath =
|
|
187
|
+
const dotenvPath = getTokenEnvPath(process.cwd());
|
|
199
188
|
const dir = path.dirname(dotenvPath);
|
|
200
189
|
if (!fs.existsSync(dir))
|
|
201
190
|
fs.mkdirSync(dir, { recursive: true });
|
package/dist/src/autosync.js
CHANGED
|
@@ -20,14 +20,14 @@ export const startAutoSync = (intervalMs = 300_000) => {
|
|
|
20
20
|
const tick = async () => {
|
|
21
21
|
try {
|
|
22
22
|
const cfg = loadConfig(process.cwd());
|
|
23
|
-
const sync = cfg.vaultMind.embedding.
|
|
23
|
+
const sync = cfg.vaultMind.embedding.sync;
|
|
24
24
|
if (!sync?.autoSync)
|
|
25
25
|
return; // off by default
|
|
26
26
|
if (!isModalConfigured(cfg.vaultMind))
|
|
27
27
|
return; // nothing to sync
|
|
28
28
|
const ms = sync.autoSyncIntervalMs ?? intervalMs;
|
|
29
29
|
void ms; // cadence is fixed at start; tick honors config toggle
|
|
30
|
-
await syncAll(cfg);
|
|
30
|
+
await syncAll(cfg, process.cwd());
|
|
31
31
|
console.log("[pi-vault-mind] auto-sync tick complete");
|
|
32
32
|
}
|
|
33
33
|
catch (err) {
|
package/dist/src/commands.d.ts
CHANGED
|
@@ -1,27 +1,10 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import type
|
|
2
|
+
import { type ServerState } from "./server.js";
|
|
3
3
|
export declare const auditConfig: (ctx: ExtensionContext) => Promise<void>;
|
|
4
4
|
export declare const selectActiveCollection: (ctx: ExtensionContext) => Promise<void>;
|
|
5
|
-
/**
|
|
6
|
-
* Vault-root `.gitignore` entries that keep pi-vault-mind compatible with
|
|
7
|
-
* `obsidian-git` (and, transitively, Obsidian Sync setups that also back up via
|
|
8
|
-
* git): the LanceDB index is a large, per-device, rebuildable binary and must
|
|
9
|
-
* never be committed; Obsidian's workspace UI state churns constantly. See
|
|
10
|
-
* docs/OBSIDIAN_SETUP.md §6.
|
|
11
|
-
*/
|
|
12
|
-
export declare const GITIGNORE_ENTRIES: string[];
|
|
13
|
-
/**
|
|
14
|
-
* Decide what to do with the vault `.gitignore`, given its current contents
|
|
15
|
-
* (`null` if absent). Pure — does no I/O — so it is unit-testable. Creates the
|
|
16
|
-
* file when missing, appends only the entries that aren't already present
|
|
17
|
-
* (line-exact match, trimmed), and skips when everything is covered.
|
|
18
|
-
*/
|
|
19
|
-
export declare const planGitignore: (existing: string | null) => {
|
|
20
|
-
action: "create" | "append" | "skip";
|
|
21
|
-
content: string;
|
|
22
|
-
};
|
|
23
5
|
export declare const watcherState: import("./watcher.js").WatcherState;
|
|
24
6
|
/** Module-level server state, referenced by the /vm server command.
|
|
25
7
|
* Port is set when the server starts in index.ts. */
|
|
26
8
|
export declare const serverState: ServerState;
|
|
9
|
+
export declare const writeTokenEnv: (token: string, cwd: string, varName?: string) => void;
|
|
27
10
|
export declare const registerCommands: (pi: ExtensionAPI) => void;
|