@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.
Files changed (78) hide show
  1. package/README.md +286 -0
  2. package/dist/installer/install.d.ts +12 -0
  3. package/dist/installer/install.d.ts.map +1 -0
  4. package/dist/installer/install.js +714 -0
  5. package/dist/installer/install.js.map +1 -0
  6. package/dist/src/cache/budget.d.ts +48 -0
  7. package/dist/src/cache/budget.d.ts.map +1 -0
  8. package/dist/src/cache/budget.js +55 -0
  9. package/dist/src/cache/budget.js.map +1 -0
  10. package/dist/src/cache/compressor.d.ts +21 -0
  11. package/dist/src/cache/compressor.d.ts.map +1 -0
  12. package/dist/src/cache/compressor.js +89 -0
  13. package/dist/src/cache/compressor.js.map +1 -0
  14. package/dist/src/cache/levels.d.ts +16 -0
  15. package/dist/src/cache/levels.d.ts.map +1 -0
  16. package/dist/src/cache/levels.js +41 -0
  17. package/dist/src/cache/levels.js.map +1 -0
  18. package/dist/src/cache/manager.d.ts +38 -0
  19. package/dist/src/cache/manager.d.ts.map +1 -0
  20. package/dist/src/cache/manager.js +196 -0
  21. package/dist/src/cache/manager.js.map +1 -0
  22. package/dist/src/cli.d.ts +3 -0
  23. package/dist/src/cli.d.ts.map +1 -0
  24. package/dist/src/cli.js +279 -0
  25. package/dist/src/cli.js.map +1 -0
  26. package/dist/src/detection/areas.d.ts +13 -0
  27. package/dist/src/detection/areas.d.ts.map +1 -0
  28. package/dist/src/detection/areas.js +96 -0
  29. package/dist/src/detection/areas.js.map +1 -0
  30. package/dist/src/detection/task.d.ts +28 -0
  31. package/dist/src/detection/task.d.ts.map +1 -0
  32. package/dist/src/detection/task.js +77 -0
  33. package/dist/src/detection/task.js.map +1 -0
  34. package/dist/src/gating/gate.d.ts +38 -0
  35. package/dist/src/gating/gate.d.ts.map +1 -0
  36. package/dist/src/gating/gate.js +74 -0
  37. package/dist/src/gating/gate.js.map +1 -0
  38. package/dist/src/graph/edges.d.ts +41 -0
  39. package/dist/src/graph/edges.d.ts.map +1 -0
  40. package/dist/src/graph/edges.js +115 -0
  41. package/dist/src/graph/edges.js.map +1 -0
  42. package/dist/src/graph/indexer.d.ts +38 -0
  43. package/dist/src/graph/indexer.d.ts.map +1 -0
  44. package/dist/src/graph/indexer.js +228 -0
  45. package/dist/src/graph/indexer.js.map +1 -0
  46. package/dist/src/graph/traversal.d.ts +25 -0
  47. package/dist/src/graph/traversal.d.ts.map +1 -0
  48. package/dist/src/graph/traversal.js +173 -0
  49. package/dist/src/graph/traversal.js.map +1 -0
  50. package/dist/src/index.d.ts +3 -0
  51. package/dist/src/index.d.ts.map +1 -0
  52. package/dist/src/index.js +82 -0
  53. package/dist/src/index.js.map +1 -0
  54. package/dist/src/indexing/codebase.d.ts +30 -0
  55. package/dist/src/indexing/codebase.d.ts.map +1 -0
  56. package/dist/src/indexing/codebase.js +127 -0
  57. package/dist/src/indexing/codebase.js.map +1 -0
  58. package/dist/src/markdown/writer.d.ts +34 -0
  59. package/dist/src/markdown/writer.d.ts.map +1 -0
  60. package/dist/src/markdown/writer.js +96 -0
  61. package/dist/src/markdown/writer.js.map +1 -0
  62. package/dist/src/server.d.ts +15 -0
  63. package/dist/src/server.d.ts.map +1 -0
  64. package/dist/src/server.js +520 -0
  65. package/dist/src/server.js.map +1 -0
  66. package/dist/src/storage/db.d.ts +123 -0
  67. package/dist/src/storage/db.d.ts.map +1 -0
  68. package/dist/src/storage/db.js +318 -0
  69. package/dist/src/storage/db.js.map +1 -0
  70. package/dist/src/utils/glob.d.ts +11 -0
  71. package/dist/src/utils/glob.d.ts.map +1 -0
  72. package/dist/src/utils/glob.js +20 -0
  73. package/dist/src/utils/glob.js.map +1 -0
  74. package/hooks/post-write.mjs +57 -0
  75. package/hooks/pre-compact.mjs +44 -0
  76. package/hooks/pre-tool-use.mjs +87 -0
  77. package/hooks/session-start.mjs +54 -0
  78. 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
+ }