context-vault 2.11.0 → 2.12.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/bin/cli.js +49 -19
- package/node_modules/@context-vault/core/package.json +1 -1
- package/node_modules/@context-vault/core/src/constants.js +6 -0
- package/node_modules/@context-vault/core/src/core/telemetry.js +28 -2
- package/node_modules/@context-vault/core/src/server/tools/save-context.js +6 -0
- package/package.json +2 -2
package/bin/cli.js
CHANGED
|
@@ -25,6 +25,7 @@ import { join, resolve, dirname } from "node:path";
|
|
|
25
25
|
import { homedir, platform } from "node:os";
|
|
26
26
|
import { execSync, execFile, execFileSync } from "node:child_process";
|
|
27
27
|
import { fileURLToPath } from "node:url";
|
|
28
|
+
import { APP_URL, API_URL, MARKETING_URL } from "@context-vault/core/constants";
|
|
28
29
|
|
|
29
30
|
const __filename = fileURLToPath(import.meta.url);
|
|
30
31
|
const __dirname = dirname(__filename);
|
|
@@ -272,9 +273,39 @@ async function runSetup() {
|
|
|
272
273
|
existingVault = cfg.vaultDir || existingVault;
|
|
273
274
|
} catch {}
|
|
274
275
|
|
|
276
|
+
// Version check against npm registry (5s timeout, fail silently if offline)
|
|
277
|
+
let latestVersion = null;
|
|
278
|
+
try {
|
|
279
|
+
latestVersion = execSync("npm view context-vault version", {
|
|
280
|
+
encoding: "utf-8",
|
|
281
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
282
|
+
timeout: 5000,
|
|
283
|
+
}).trim();
|
|
284
|
+
} catch {}
|
|
285
|
+
|
|
286
|
+
if (latestVersion === VERSION) {
|
|
287
|
+
console.log(
|
|
288
|
+
green(` ✓ context-vault v${VERSION} is up to date`) +
|
|
289
|
+
dim(` (vault: ${existingVault})`),
|
|
290
|
+
);
|
|
291
|
+
console.log();
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
275
295
|
console.log(yellow(` Existing installation detected`));
|
|
276
296
|
console.log(dim(` Vault: ${existingVault}`));
|
|
277
|
-
|
|
297
|
+
if (latestVersion) {
|
|
298
|
+
console.log();
|
|
299
|
+
console.log(` Current: ${dim(VERSION)}`);
|
|
300
|
+
console.log(` Latest: ${green(latestVersion)}`);
|
|
301
|
+
const upgradeCmd = isNpx()
|
|
302
|
+
? "npx context-vault@latest setup"
|
|
303
|
+
: "npm install -g context-vault";
|
|
304
|
+
console.log();
|
|
305
|
+
console.log(dim(` To upgrade: ${upgradeCmd}`));
|
|
306
|
+
} else {
|
|
307
|
+
console.log(dim(` Config: ${existingConfig}`));
|
|
308
|
+
}
|
|
278
309
|
console.log();
|
|
279
310
|
console.log(` 1) Full reconfigure`);
|
|
280
311
|
console.log(` 2) Update tool configs only ${dim("(skip vault setup)")}`);
|
|
@@ -354,6 +385,7 @@ async function runSetup() {
|
|
|
354
385
|
|
|
355
386
|
console.log();
|
|
356
387
|
console.log(green(" ✓ Tool configs updated."));
|
|
388
|
+
console.log(dim(" Restart your AI tools to apply the changes."));
|
|
357
389
|
console.log();
|
|
358
390
|
return;
|
|
359
391
|
}
|
|
@@ -501,7 +533,7 @@ async function runSetup() {
|
|
|
501
533
|
console.log(
|
|
502
534
|
dim(" file paths, or personal data is ever sent. Off by default."),
|
|
503
535
|
);
|
|
504
|
-
console.log(dim(
|
|
536
|
+
console.log(dim(` Full schema: ${MARKETING_URL}/telemetry`));
|
|
505
537
|
console.log();
|
|
506
538
|
|
|
507
539
|
let telemetryEnabled = vaultConfig.telemetry === true;
|
|
@@ -541,7 +573,12 @@ async function runSetup() {
|
|
|
541
573
|
console.log(
|
|
542
574
|
`\n ${dim("[4/6]")}${bold(" Downloading embedding model...")}`,
|
|
543
575
|
);
|
|
544
|
-
console.log(dim(" all-MiniLM-L6-v2 (~22MB, one-time download)
|
|
576
|
+
console.log(dim(" all-MiniLM-L6-v2 (~22MB, one-time download)"));
|
|
577
|
+
console.log(
|
|
578
|
+
dim(
|
|
579
|
+
` Slow connection? Re-run with --skip-embeddings (enables FTS-only mode)\n`,
|
|
580
|
+
),
|
|
581
|
+
);
|
|
545
582
|
{
|
|
546
583
|
const spinnerFrames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
547
584
|
let frame = 0;
|
|
@@ -731,7 +768,9 @@ async function runSetup() {
|
|
|
731
768
|
const boxLines = [
|
|
732
769
|
` ✓ Setup complete — ${passed}/${checks.length} checks passed (${elapsed}s)`,
|
|
733
770
|
``,
|
|
734
|
-
` ${bold("
|
|
771
|
+
` ${bold("Next:")} restart ${toolName} to activate the vault`,
|
|
772
|
+
``,
|
|
773
|
+
` ${bold("AI Tools")} — once active, try:`,
|
|
735
774
|
` "Search my vault for getting started"`,
|
|
736
775
|
` "Save an insight about [topic]"`,
|
|
737
776
|
` "Show my vault status"`,
|
|
@@ -979,7 +1018,7 @@ This is an example entry showing the decision format. Feel free to delete it.
|
|
|
979
1018
|
|
|
980
1019
|
async function runConnect() {
|
|
981
1020
|
const apiKey = getFlag("--key");
|
|
982
|
-
const hostedUrl = getFlag("--url") ||
|
|
1021
|
+
const hostedUrl = getFlag("--url") || API_URL;
|
|
983
1022
|
|
|
984
1023
|
if (!apiKey) {
|
|
985
1024
|
console.log(`\n ${bold("context-vault connect")}\n`);
|
|
@@ -988,9 +1027,7 @@ async function runConnect() {
|
|
|
988
1027
|
console.log(` context-vault connect --key cv_...\n`);
|
|
989
1028
|
console.log(` Options:`);
|
|
990
1029
|
console.log(` --key <key> API key (required)`);
|
|
991
|
-
console.log(
|
|
992
|
-
` --url <url> Hosted server URL (default: https://api.context-vault.com)`,
|
|
993
|
-
);
|
|
1030
|
+
console.log(` --url <url> Hosted server URL (default: ${API_URL})`);
|
|
994
1031
|
console.log();
|
|
995
1032
|
return;
|
|
996
1033
|
}
|
|
@@ -1232,9 +1269,7 @@ async function runSwitch() {
|
|
|
1232
1269
|
);
|
|
1233
1270
|
console.log(` Options:`);
|
|
1234
1271
|
console.log(` --key <key> API key for hosted mode (cv_...)`);
|
|
1235
|
-
console.log(
|
|
1236
|
-
` --url <url> Hosted server URL (default: https://api.context-vault.com)\n`,
|
|
1237
|
-
);
|
|
1272
|
+
console.log(` --url <url> Hosted server URL (default: ${API_URL})\n`);
|
|
1238
1273
|
return;
|
|
1239
1274
|
}
|
|
1240
1275
|
|
|
@@ -1291,10 +1326,7 @@ async function runSwitch() {
|
|
|
1291
1326
|
console.log(dim(` Server: node ${launcherPath}`));
|
|
1292
1327
|
console.log();
|
|
1293
1328
|
} else {
|
|
1294
|
-
const hostedUrl =
|
|
1295
|
-
getFlag("--url") ||
|
|
1296
|
-
vaultConfig.hostedUrl ||
|
|
1297
|
-
"https://api.context-vault.com";
|
|
1329
|
+
const hostedUrl = getFlag("--url") || vaultConfig.hostedUrl || API_URL;
|
|
1298
1330
|
const apiKey = getFlag("--key") || vaultConfig.apiKey;
|
|
1299
1331
|
|
|
1300
1332
|
if (!apiKey) {
|
|
@@ -1674,15 +1706,13 @@ async function runMigrate() {
|
|
|
1674
1706
|
` context-vault migrate --to-local Download hosted vault to local files`,
|
|
1675
1707
|
);
|
|
1676
1708
|
console.log(`\n Options:`);
|
|
1677
|
-
console.log(
|
|
1678
|
-
` --url <url> Hosted server URL (default: https://api.context-vault.com)`,
|
|
1679
|
-
);
|
|
1709
|
+
console.log(` --url <url> Hosted server URL (default: ${API_URL})`);
|
|
1680
1710
|
console.log(` --key <key> API key (cv_...)`);
|
|
1681
1711
|
console.log();
|
|
1682
1712
|
return;
|
|
1683
1713
|
}
|
|
1684
1714
|
|
|
1685
|
-
const hostedUrl = getFlag("--url") ||
|
|
1715
|
+
const hostedUrl = getFlag("--url") || API_URL;
|
|
1686
1716
|
const apiKey = getFlag("--key");
|
|
1687
1717
|
|
|
1688
1718
|
if (!apiKey) {
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export const APP_URL = "https://app.context-vault.com";
|
|
2
|
+
export const API_URL = "https://api.context-vault.com";
|
|
3
|
+
export const MARKETING_URL = "https://contextvault.dev";
|
|
4
|
+
export const GITHUB_ISSUES_URL =
|
|
5
|
+
"https://github.com/fellanH/context-vault/issues";
|
|
6
|
+
|
|
1
7
|
export const MAX_BODY_LENGTH = 100 * 1024; // 100KB
|
|
2
8
|
export const MAX_TITLE_LENGTH = 500;
|
|
3
9
|
export const MAX_KIND_LENGTH = 64;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { existsSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { API_URL, MARKETING_URL, GITHUB_ISSUES_URL } from "../constants.js";
|
|
3
4
|
|
|
4
|
-
const TELEMETRY_ENDPOINT =
|
|
5
|
+
const TELEMETRY_ENDPOINT = `${API_URL}/telemetry`;
|
|
5
6
|
const NOTICE_MARKER = ".telemetry-notice-shown";
|
|
7
|
+
const FEEDBACK_PROMPT_MARKER = ".feedback-prompt-shown";
|
|
6
8
|
|
|
7
9
|
export function isTelemetryEnabled(config) {
|
|
8
10
|
const envVal = process.env.CONTEXT_VAULT_TELEMETRY;
|
|
@@ -56,7 +58,31 @@ export function maybeShowTelemetryNotice(dataDir) {
|
|
|
56
58
|
"[context-vault] Reports contain only: event type, error code, tool name, version, node version, platform, arch, timestamp.",
|
|
57
59
|
"[context-vault] No vault content, file paths, or personal data is ever sent.",
|
|
58
60
|
'[context-vault] Opt in: set "telemetry": true in ~/.context-mcp/config.json or set CONTEXT_VAULT_TELEMETRY=1.',
|
|
59
|
-
|
|
61
|
+
`[context-vault] Full payload schema: ${MARKETING_URL}/telemetry`,
|
|
62
|
+
];
|
|
63
|
+
for (const line of lines) {
|
|
64
|
+
process.stderr.write(line + "\n");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Print a one-time feedback prompt after the user's first successful save.
|
|
70
|
+
* Uses a marker file in dataDir to ensure it's only shown once.
|
|
71
|
+
* Never throws, never blocks.
|
|
72
|
+
*/
|
|
73
|
+
export function maybeShowFeedbackPrompt(dataDir) {
|
|
74
|
+
try {
|
|
75
|
+
const markerPath = join(dataDir, FEEDBACK_PROMPT_MARKER);
|
|
76
|
+
if (existsSync(markerPath)) return;
|
|
77
|
+
writeFileSync(markerPath, new Date().toISOString() + "\n");
|
|
78
|
+
} catch {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const lines = [
|
|
83
|
+
"[context-vault] First entry saved — nice work!",
|
|
84
|
+
"[context-vault] Got feedback, a bug, or a feature request?",
|
|
85
|
+
`[context-vault] Open an issue: ${GITHUB_ISSUES_URL}`,
|
|
60
86
|
];
|
|
61
87
|
for (const line of lines) {
|
|
62
88
|
process.stderr.write(line + "\n");
|
|
@@ -4,6 +4,7 @@ import { indexEntry } from "../../index/index.js";
|
|
|
4
4
|
import { categoryFor } from "../../core/categories.js";
|
|
5
5
|
import { normalizeKind } from "../../core/files.js";
|
|
6
6
|
import { ok, err, ensureVaultExists, ensureValidKind } from "../helpers.js";
|
|
7
|
+
import { maybeShowFeedbackPrompt } from "../../core/telemetry.js";
|
|
7
8
|
import {
|
|
8
9
|
MAX_BODY_LENGTH,
|
|
9
10
|
MAX_TITLE_LENGTH,
|
|
@@ -398,6 +399,11 @@ export async function handler(
|
|
|
398
399
|
supersedes,
|
|
399
400
|
userId,
|
|
400
401
|
});
|
|
402
|
+
|
|
403
|
+
if (ctx.config?.dataDir) {
|
|
404
|
+
maybeShowFeedbackPrompt(ctx.config.dataDir);
|
|
405
|
+
}
|
|
406
|
+
|
|
401
407
|
const relPath = entry.filePath
|
|
402
408
|
? entry.filePath.replace(config.vaultDir + "/", "")
|
|
403
409
|
: entry.filePath;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "context-vault",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Persistent memory for AI agents — saves and searches knowledge across sessions",
|
|
6
6
|
"bin": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@context-vault/core"
|
|
56
56
|
],
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@context-vault/core": "^2.
|
|
58
|
+
"@context-vault/core": "^2.12.0",
|
|
59
59
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
60
60
|
"sqlite-vec": "^0.1.0"
|
|
61
61
|
}
|