@exero1/claudecontext 0.1.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/README.md +286 -0
- package/dist/installer/install.d.ts +12 -0
- package/dist/installer/install.d.ts.map +1 -0
- package/dist/installer/install.js +714 -0
- package/dist/installer/install.js.map +1 -0
- package/dist/src/cache/budget.d.ts +48 -0
- package/dist/src/cache/budget.d.ts.map +1 -0
- package/dist/src/cache/budget.js +55 -0
- package/dist/src/cache/budget.js.map +1 -0
- package/dist/src/cache/compressor.d.ts +21 -0
- package/dist/src/cache/compressor.d.ts.map +1 -0
- package/dist/src/cache/compressor.js +89 -0
- package/dist/src/cache/compressor.js.map +1 -0
- package/dist/src/cache/levels.d.ts +16 -0
- package/dist/src/cache/levels.d.ts.map +1 -0
- package/dist/src/cache/levels.js +41 -0
- package/dist/src/cache/levels.js.map +1 -0
- package/dist/src/cache/manager.d.ts +38 -0
- package/dist/src/cache/manager.d.ts.map +1 -0
- package/dist/src/cache/manager.js +196 -0
- package/dist/src/cache/manager.js.map +1 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +279 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/detection/areas.d.ts +13 -0
- package/dist/src/detection/areas.d.ts.map +1 -0
- package/dist/src/detection/areas.js +96 -0
- package/dist/src/detection/areas.js.map +1 -0
- package/dist/src/detection/task.d.ts +28 -0
- package/dist/src/detection/task.d.ts.map +1 -0
- package/dist/src/detection/task.js +77 -0
- package/dist/src/detection/task.js.map +1 -0
- package/dist/src/gating/gate.d.ts +38 -0
- package/dist/src/gating/gate.d.ts.map +1 -0
- package/dist/src/gating/gate.js +74 -0
- package/dist/src/gating/gate.js.map +1 -0
- package/dist/src/graph/edges.d.ts +41 -0
- package/dist/src/graph/edges.d.ts.map +1 -0
- package/dist/src/graph/edges.js +115 -0
- package/dist/src/graph/edges.js.map +1 -0
- package/dist/src/graph/indexer.d.ts +38 -0
- package/dist/src/graph/indexer.d.ts.map +1 -0
- package/dist/src/graph/indexer.js +228 -0
- package/dist/src/graph/indexer.js.map +1 -0
- package/dist/src/graph/traversal.d.ts +25 -0
- package/dist/src/graph/traversal.d.ts.map +1 -0
- package/dist/src/graph/traversal.js +173 -0
- package/dist/src/graph/traversal.js.map +1 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +82 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/indexing/codebase.d.ts +30 -0
- package/dist/src/indexing/codebase.d.ts.map +1 -0
- package/dist/src/indexing/codebase.js +127 -0
- package/dist/src/indexing/codebase.js.map +1 -0
- package/dist/src/markdown/writer.d.ts +34 -0
- package/dist/src/markdown/writer.d.ts.map +1 -0
- package/dist/src/markdown/writer.js +96 -0
- package/dist/src/markdown/writer.js.map +1 -0
- package/dist/src/server.d.ts +15 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +520 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/storage/db.d.ts +123 -0
- package/dist/src/storage/db.d.ts.map +1 -0
- package/dist/src/storage/db.js +318 -0
- package/dist/src/storage/db.js.map +1 -0
- package/dist/src/utils/glob.d.ts +11 -0
- package/dist/src/utils/glob.d.ts.map +1 -0
- package/dist/src/utils/glob.js +20 -0
- package/dist/src/utils/glob.js.map +1 -0
- package/hooks/post-write.mjs +57 -0
- package/hooks/pre-compact.mjs +44 -0
- package/hooks/pre-tool-use.mjs +87 -0
- package/hooks/session-start.mjs +54 -0
- package/package.json +51 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ClaudeContext PreToolUse hook.
|
|
4
|
+
* Gate check on Bash, Write, Edit, MultiEdit tool calls.
|
|
5
|
+
* Timeout: 8s.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execFileSync } from 'node:child_process';
|
|
9
|
+
import { existsSync } from 'node:fs';
|
|
10
|
+
import { join, resolve } from 'node:path';
|
|
11
|
+
|
|
12
|
+
const projectRoot = resolve(process.env.CLAUDECONTEXT_PROJECT_ROOT ?? process.cwd());
|
|
13
|
+
|
|
14
|
+
function findCli() {
|
|
15
|
+
const local = join(projectRoot, 'node_modules', '.bin', 'claudecontext-cli');
|
|
16
|
+
if (existsSync(local)) return local;
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Read hook input from stdin
|
|
21
|
+
let input = '';
|
|
22
|
+
process.stdin.setEncoding('utf8');
|
|
23
|
+
process.stdin.on('data', chunk => { input += chunk; });
|
|
24
|
+
process.stdin.on('end', () => {
|
|
25
|
+
try {
|
|
26
|
+
const hookData = JSON.parse(input);
|
|
27
|
+
const toolName = hookData.tool_name ?? '';
|
|
28
|
+
const gatedTools = ['Bash', 'Write', 'Edit', 'MultiEdit'];
|
|
29
|
+
|
|
30
|
+
if (!gatedTools.includes(toolName)) {
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Extract the command/content to gate-check
|
|
35
|
+
const toolInput = hookData.tool_input ?? {};
|
|
36
|
+
let checkString = '';
|
|
37
|
+
|
|
38
|
+
if (toolName === 'Bash') {
|
|
39
|
+
checkString = toolInput.command ?? '';
|
|
40
|
+
} else if (['Write', 'Edit', 'MultiEdit'].includes(toolName)) {
|
|
41
|
+
checkString = toolInput.file_path ?? toolInput.new_string ?? '';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!checkString) process.exit(0);
|
|
45
|
+
|
|
46
|
+
const cli = findCli();
|
|
47
|
+
const gateRulesPath = join(projectRoot, '.claudecontext', 'gate-rules.json');
|
|
48
|
+
const gateArgs = existsSync(gateRulesPath)
|
|
49
|
+
? ['gate-check', '--rules-file', gateRulesPath, checkString]
|
|
50
|
+
: ['gate-check', checkString];
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
if (cli) {
|
|
54
|
+
execFileSync(cli, gateArgs, {
|
|
55
|
+
cwd: projectRoot,
|
|
56
|
+
env: { ...process.env, NODE_NO_WARNINGS: '1' },
|
|
57
|
+
timeout: 7000,
|
|
58
|
+
stdio: ['ignore', 'ignore', 'pipe'],
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
execFileSync('npx', ['claudecontext-cli', ...gateArgs], {
|
|
62
|
+
cwd: projectRoot,
|
|
63
|
+
env: { ...process.env, NODE_NO_WARNINGS: '1' },
|
|
64
|
+
timeout: 7000,
|
|
65
|
+
stdio: ['ignore', 'ignore', 'pipe'],
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
// Exit 0 = allow (also: exit 1 = warn, execFileSync throws for non-zero but warn is caught below)
|
|
69
|
+
process.exit(0);
|
|
70
|
+
} catch (err) {
|
|
71
|
+
// exit code 2 = deny
|
|
72
|
+
const code = err?.status ?? err?.code;
|
|
73
|
+
if (code === 2) {
|
|
74
|
+
// Extract the DENY: line from stderr (strip any Node.js warning noise)
|
|
75
|
+
const stderrText = String(err?.stderr ?? '');
|
|
76
|
+
const denyLine = stderrText.split('\n').find(l => l.startsWith('DENY:'));
|
|
77
|
+
const reason = denyLine ? denyLine.slice('DENY: '.length).trim() : 'destructive pattern detected';
|
|
78
|
+
process.stdout.write(JSON.stringify({ decision: 'block', reason }));
|
|
79
|
+
process.exit(0);
|
|
80
|
+
}
|
|
81
|
+
// exit 1 = warn — allow but stderr already written
|
|
82
|
+
process.exit(0);
|
|
83
|
+
}
|
|
84
|
+
} catch {
|
|
85
|
+
process.exit(0); // Fail open — don't break tool use
|
|
86
|
+
}
|
|
87
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ClaudeContext SessionStart hook.
|
|
4
|
+
* Fires on Claude Code startup and resume.
|
|
5
|
+
*
|
|
6
|
+
* Detects active task → hydrates context bundle → outputs additionalContext.
|
|
7
|
+
* Timeout: 15s (Claude Code default).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { execFileSync } from 'node:child_process';
|
|
11
|
+
import { existsSync } from 'node:fs';
|
|
12
|
+
import { join, resolve } from 'node:path';
|
|
13
|
+
|
|
14
|
+
const projectRoot = resolve(process.env.CLAUDECONTEXT_PROJECT_ROOT ?? process.cwd());
|
|
15
|
+
|
|
16
|
+
// Prefer installed local binary (~2x faster than npx)
|
|
17
|
+
function findCli() {
|
|
18
|
+
const local = join(projectRoot, 'node_modules', '.bin', 'claudecontext-cli');
|
|
19
|
+
if (existsSync(local)) return local;
|
|
20
|
+
return null; // will fall back to npx
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const cli = findCli();
|
|
25
|
+
let result;
|
|
26
|
+
|
|
27
|
+
if (cli) {
|
|
28
|
+
result = execFileSync(cli, ['hydrate'], {
|
|
29
|
+
cwd: projectRoot,
|
|
30
|
+
env: { ...process.env, NODE_NO_WARNINGS: '1' },
|
|
31
|
+
timeout: 14000,
|
|
32
|
+
encoding: 'utf8',
|
|
33
|
+
});
|
|
34
|
+
} else {
|
|
35
|
+
result = execFileSync('npx', ['claudecontext-cli', 'hydrate'], {
|
|
36
|
+
cwd: projectRoot,
|
|
37
|
+
env: { ...process.env, NODE_NO_WARNINGS: '1' },
|
|
38
|
+
timeout: 14000,
|
|
39
|
+
encoding: 'utf8',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// result is JSON: { additionalContext: "..." }
|
|
44
|
+
const parsed = JSON.parse(result);
|
|
45
|
+
if (parsed.additionalContext) {
|
|
46
|
+
// Output in the format Claude Code expects for session hooks
|
|
47
|
+
process.stdout.write(JSON.stringify({ additionalContext: parsed.additionalContext }));
|
|
48
|
+
}
|
|
49
|
+
} catch (err) {
|
|
50
|
+
// Fail silently — don't break Claude Code startup
|
|
51
|
+
process.stderr.write(`[claudecontext/session-start] Error: ${err?.message ?? err}\n`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
process.exit(0);
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@exero1/claudecontext",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Persistent memory system for Claude Code — hierarchical cache levels + association graph",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=22"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"hooks",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"bin": {
|
|
15
|
+
"claudecontext": "dist/installer/install.js",
|
|
16
|
+
"claudecontext-mcp": "dist/src/index.js",
|
|
17
|
+
"claudecontext-cli": "dist/src/cli.js"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"build:watch": "tsc --watch",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"test": "node --test --experimental-test-coverage 'dist/src/**/*.test.js' 'dist/installer/**/*.test.js'",
|
|
24
|
+
"test:unit": "node --test 'dist/src/cache/*.test.js' 'dist/src/graph/*.test.js' 'dist/src/storage/*.test.js' 'dist/src/markdown/*.test.js' 'dist/src/gating/*.test.js' 'dist/src/utils/*.test.js'",
|
|
25
|
+
"test:integration": "node --test 'dist/src/integration/*.test.js'",
|
|
26
|
+
"lint": "eslint src/**/*.ts installer/**/*.ts",
|
|
27
|
+
"lint:fix": "eslint src/**/*.ts installer/**/*.ts --fix",
|
|
28
|
+
"clean": "rm -rf dist",
|
|
29
|
+
"ci": "npm run typecheck && npm run build && npm run test:unit && npm run test:integration",
|
|
30
|
+
"build:publish": "tsc --project tsconfig.build.json",
|
|
31
|
+
"prepublishOnly": "npm run clean && npm run build:publish && npm run typecheck"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
35
|
+
"acorn": "^8.14.1",
|
|
36
|
+
"acorn-walk": "^8.3.4",
|
|
37
|
+
"simple-git": "^3.27.0",
|
|
38
|
+
"zod": "^3.24.1"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@eslint/js": "^9.0.0",
|
|
42
|
+
"@types/acorn": "^4.0.6",
|
|
43
|
+
"@types/node": "^22.0.0",
|
|
44
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
45
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
46
|
+
"eslint": "^9.0.0",
|
|
47
|
+
"typescript": "^5.7.0"
|
|
48
|
+
},
|
|
49
|
+
"keywords": ["claude", "claude-code", "mcp", "context", "memory", "ai"],
|
|
50
|
+
"license": "MIT"
|
|
51
|
+
}
|