context-vault 3.5.1 → 3.7.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/assets/vault-error-hook.mjs +106 -0
- package/assets/vault-recall-hook.mjs +67 -0
- package/bin/cli.js +607 -2
- package/dist/register-tools.d.ts.map +1 -1
- package/dist/register-tools.js +4 -0
- package/dist/register-tools.js.map +1 -1
- package/dist/tools/clear-context.d.ts +7 -3
- package/dist/tools/clear-context.d.ts.map +1 -1
- package/dist/tools/clear-context.js +157 -8
- package/dist/tools/clear-context.js.map +1 -1
- package/dist/tools/context-status.d.ts.map +1 -1
- package/dist/tools/context-status.js +42 -0
- package/dist/tools/context-status.js.map +1 -1
- package/dist/tools/get-context.d.ts.map +1 -1
- package/dist/tools/get-context.js +66 -1
- package/dist/tools/get-context.js.map +1 -1
- package/dist/tools/recall.d.ts +25 -0
- package/dist/tools/recall.d.ts.map +1 -0
- package/dist/tools/recall.js +257 -0
- package/dist/tools/recall.js.map +1 -0
- package/dist/tools/save-context.d.ts.map +1 -1
- package/dist/tools/save-context.js +20 -0
- package/dist/tools/save-context.js.map +1 -1
- package/dist/tools/session-end.d.ts +20 -0
- package/dist/tools/session-end.d.ts.map +1 -0
- package/dist/tools/session-end.js +288 -0
- package/dist/tools/session-end.js.map +1 -0
- package/dist/tools/session-start.d.ts +2 -1
- package/dist/tools/session-start.d.ts.map +1 -1
- package/dist/tools/session-start.js +16 -5
- package/dist/tools/session-start.js.map +1 -1
- package/node_modules/@context-vault/core/package.json +1 -1
- package/package.json +2 -2
- package/src/register-tools.ts +4 -0
- package/src/tools/clear-context.ts +195 -10
- package/src/tools/context-status.ts +65 -0
- package/src/tools/get-context.ts +86 -1
- package/src/tools/recall.ts +307 -0
- package/src/tools/save-context.ts +25 -0
- package/src/tools/session-end.ts +338 -0
- package/src/tools/session-start.ts +18 -5
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Context Vault — PostToolUse hook for Bash error recall.
|
|
4
|
+
*
|
|
5
|
+
* Fires after every Bash tool use. If the result indicates an error
|
|
6
|
+
* (non-zero exit code or stderr content), extracts the error text and
|
|
7
|
+
* calls `context-vault recall` to surface entries about similar errors.
|
|
8
|
+
*
|
|
9
|
+
* Designed for <200ms total execution. Fails silently on any error.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { execSync } from 'node:child_process';
|
|
13
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
14
|
+
import { join, basename } from 'node:path';
|
|
15
|
+
|
|
16
|
+
// ── Parse stdin (hook payload) ──────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
let input;
|
|
19
|
+
try {
|
|
20
|
+
input = JSON.parse(readFileSync('/dev/stdin', 'utf-8'));
|
|
21
|
+
} catch {
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// ── Check for error signals ─────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
const toolResponse = input.tool_response ?? input.tool_output ?? '';
|
|
28
|
+
const output = typeof toolResponse === 'string' ? toolResponse : JSON.stringify(toolResponse);
|
|
29
|
+
|
|
30
|
+
// Detect error: exit code, stderr markers, common error patterns
|
|
31
|
+
const hasExitCode = /exit code[:\s]+[1-9]\d*/i.test(output) ||
|
|
32
|
+
/exited with\s+[1-9]/i.test(output) ||
|
|
33
|
+
/returned?\s+(?:non-zero|[1-9]\d*)/i.test(output);
|
|
34
|
+
const hasErrorPattern = /(?:^|\n)\s*(?:error|Error|ERROR|FATAL|fatal|panic|Traceback|SyntaxError|TypeError|ReferenceError|ENOENT|EACCES|ECONNREFUSED|MODULE_NOT_FOUND|Cannot find module)/m.test(output);
|
|
35
|
+
|
|
36
|
+
if (!hasExitCode && !hasErrorPattern) {
|
|
37
|
+
process.exit(0);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ── Extract error text (first meaningful error lines, max 500 chars) ────────
|
|
41
|
+
|
|
42
|
+
function extractErrorSignal(text) {
|
|
43
|
+
const lines = text.split('\n');
|
|
44
|
+
const errorLines = [];
|
|
45
|
+
let capturing = false;
|
|
46
|
+
|
|
47
|
+
for (const line of lines) {
|
|
48
|
+
if (/(?:error|Error|ERROR|FATAL|fatal|panic|Traceback|ENOENT|EACCES|ECONNREFUSED)/i.test(line)) {
|
|
49
|
+
capturing = true;
|
|
50
|
+
}
|
|
51
|
+
if (capturing) {
|
|
52
|
+
errorLines.push(line.trim());
|
|
53
|
+
if (errorLines.length >= 5) break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (errorLines.length === 0) {
|
|
58
|
+
// Fall back to last 5 non-empty lines
|
|
59
|
+
const nonEmpty = lines.filter((l) => l.trim()).slice(-5);
|
|
60
|
+
return nonEmpty.join('\n').slice(0, 500);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return errorLines.join('\n').slice(0, 500);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const errorSignal = extractErrorSignal(output);
|
|
67
|
+
if (!errorSignal || errorSignal.length < 10) {
|
|
68
|
+
process.exit(0);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ── Detect project bucket from cwd ──────────────────────────────────────────
|
|
72
|
+
|
|
73
|
+
const cwd = input.cwd || process.cwd();
|
|
74
|
+
|
|
75
|
+
function detectBucket(dir) {
|
|
76
|
+
try {
|
|
77
|
+
const yamlPath = join(dir, 'workspace.yaml');
|
|
78
|
+
if (existsSync(yamlPath)) {
|
|
79
|
+
const yaml = readFileSync(yamlPath, 'utf-8');
|
|
80
|
+
const match = yaml.match(/vault_bucket:\s*(\S+)/);
|
|
81
|
+
if (match) return match[1];
|
|
82
|
+
}
|
|
83
|
+
} catch {}
|
|
84
|
+
return basename(dir);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const bucket = detectBucket(cwd);
|
|
88
|
+
|
|
89
|
+
// ── Call context-vault recall ────────────────────────────────────────────────
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const payload = JSON.stringify({ prompt: errorSignal, bucket });
|
|
93
|
+
const result = execSync('context-vault recall', {
|
|
94
|
+
input: payload,
|
|
95
|
+
encoding: 'utf-8',
|
|
96
|
+
timeout: 3000,
|
|
97
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
98
|
+
env: { ...process.env, NODE_OPTIONS: '--no-warnings=ExperimentalWarning' },
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
if (result && result.trim()) {
|
|
102
|
+
process.stdout.write(result);
|
|
103
|
+
}
|
|
104
|
+
} catch {
|
|
105
|
+
// Silent failure: never block Claude Code
|
|
106
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Context Vault — UserPromptSubmit hook for proactive recall.
|
|
4
|
+
*
|
|
5
|
+
* Reads the Claude Code hook payload from stdin, extracts the user prompt,
|
|
6
|
+
* calls `context-vault recall` to surface relevant vault entries, and
|
|
7
|
+
* outputs hints for injection into the conversation context.
|
|
8
|
+
*
|
|
9
|
+
* Designed for <200ms total execution. Fails silently on any error.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { execSync } from 'node:child_process';
|
|
13
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
14
|
+
import { join, basename } from 'node:path';
|
|
15
|
+
|
|
16
|
+
// ── Parse stdin (hook payload) ──────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
let input;
|
|
19
|
+
try {
|
|
20
|
+
input = JSON.parse(readFileSync('/dev/stdin', 'utf-8'));
|
|
21
|
+
} catch {
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const prompt = (input.prompt ?? '').trim();
|
|
26
|
+
if (!prompt || prompt.startsWith('/') || prompt.length < 10) {
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ── Detect project bucket from cwd ──────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
const cwd = input.cwd || process.cwd();
|
|
33
|
+
|
|
34
|
+
function detectBucket(dir) {
|
|
35
|
+
// Check for workspace.yaml with vault_bucket
|
|
36
|
+
try {
|
|
37
|
+
const yamlPath = join(dir, 'workspace.yaml');
|
|
38
|
+
if (existsSync(yamlPath)) {
|
|
39
|
+
const yaml = readFileSync(yamlPath, 'utf-8');
|
|
40
|
+
const match = yaml.match(/vault_bucket:\s*(\S+)/);
|
|
41
|
+
if (match) return match[1];
|
|
42
|
+
}
|
|
43
|
+
} catch {}
|
|
44
|
+
// Fall back to directory name
|
|
45
|
+
return basename(dir);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const bucket = detectBucket(cwd);
|
|
49
|
+
|
|
50
|
+
// ── Call context-vault recall ────────────────────────────────────────────────
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const payload = JSON.stringify({ prompt, bucket });
|
|
54
|
+
const result = execSync('context-vault recall', {
|
|
55
|
+
input: payload,
|
|
56
|
+
encoding: 'utf-8',
|
|
57
|
+
timeout: 3000,
|
|
58
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
59
|
+
env: { ...process.env, NODE_OPTIONS: '--no-warnings=ExperimentalWarning' },
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
if (result && result.trim()) {
|
|
63
|
+
process.stdout.write(result);
|
|
64
|
+
}
|
|
65
|
+
} catch {
|
|
66
|
+
// Silent failure: never block Claude Code
|
|
67
|
+
}
|