claude-contextmesh 0.1.0__tar.gz

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 (41) hide show
  1. claude_contextmesh-0.1.0/.gitignore +6 -0
  2. claude_contextmesh-0.1.0/CLAUDE.md +18 -0
  3. claude_contextmesh-0.1.0/LICENSE +21 -0
  4. claude_contextmesh-0.1.0/PKG-INFO +222 -0
  5. claude_contextmesh-0.1.0/README.md +189 -0
  6. claude_contextmesh-0.1.0/pyproject.toml +78 -0
  7. claude_contextmesh-0.1.0/scripts/hook_event.sh +34 -0
  8. claude_contextmesh-0.1.0/scripts/install.sh +109 -0
  9. claude_contextmesh-0.1.0/src/contextmesh/__init__.py +4 -0
  10. claude_contextmesh-0.1.0/src/contextmesh/bootstrap.py +110 -0
  11. claude_contextmesh-0.1.0/src/contextmesh/cli.py +290 -0
  12. claude_contextmesh-0.1.0/src/contextmesh/config.py +199 -0
  13. claude_contextmesh-0.1.0/src/contextmesh/daemon/__init__.py +0 -0
  14. claude_contextmesh-0.1.0/src/contextmesh/daemon/handlers.py +375 -0
  15. claude_contextmesh-0.1.0/src/contextmesh/daemon/server.py +252 -0
  16. claude_contextmesh-0.1.0/src/contextmesh/embeddings/__init__.py +0 -0
  17. claude_contextmesh-0.1.0/src/contextmesh/embeddings/store.py +114 -0
  18. claude_contextmesh-0.1.0/src/contextmesh/graph/__init__.py +0 -0
  19. claude_contextmesh-0.1.0/src/contextmesh/graph/repo.py +249 -0
  20. claude_contextmesh-0.1.0/src/contextmesh/graph/session.py +133 -0
  21. claude_contextmesh-0.1.0/src/contextmesh/installer.py +123 -0
  22. claude_contextmesh-0.1.0/src/contextmesh/mcp/__init__.py +0 -0
  23. claude_contextmesh-0.1.0/src/contextmesh/mcp/server.py +101 -0
  24. claude_contextmesh-0.1.0/src/contextmesh/models/__init__.py +0 -0
  25. claude_contextmesh-0.1.0/src/contextmesh/models/edges.py +112 -0
  26. claude_contextmesh-0.1.0/src/contextmesh/models/nodes.py +317 -0
  27. claude_contextmesh-0.1.0/src/contextmesh/proxy.py +74 -0
  28. claude_contextmesh-0.1.0/src/contextmesh/router/__init__.py +0 -0
  29. claude_contextmesh-0.1.0/src/contextmesh/router/assembler.py +178 -0
  30. claude_contextmesh-0.1.0/src/contextmesh/router/scorer.py +103 -0
  31. claude_contextmesh-0.1.0/src/contextmesh/store/__init__.py +0 -0
  32. claude_contextmesh-0.1.0/src/contextmesh/store/db.py +262 -0
  33. claude_contextmesh-0.1.0/src/contextmesh/store/schema.py +246 -0
  34. claude_contextmesh-0.1.0/src/contextmesh/tasks/__init__.py +0 -0
  35. claude_contextmesh-0.1.0/src/contextmesh/tasks/detector.py +216 -0
  36. claude_contextmesh-0.1.0/src/contextmesh/tasks/hierarchy.py +175 -0
  37. claude_contextmesh-0.1.0/src/contextmesh/tracker/__init__.py +0 -0
  38. claude_contextmesh-0.1.0/src/contextmesh/tracker/reporter.py +81 -0
  39. claude_contextmesh-0.1.0/src/contextmesh/tracker/savings.py +113 -0
  40. claude_contextmesh-0.1.0/src/contextmesh/wrapper.py +25 -0
  41. claude_contextmesh-0.1.0/tests/test_smoke.py +197 -0
@@ -0,0 +1,6 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ .pytest_cache/
5
+ .contextmesh/
6
+
@@ -0,0 +1,18 @@
1
+ # Project Context
2
+
3
+ ## ContextMesh Active
4
+
5
+ This project uses ContextMesh for intelligent context management.
6
+
7
+ **At the start of EVERY response**, call the `get_context` tool to load relevant context:
8
+
9
+ ```
10
+ get_context(session_id="$CLAUDE_SESSION_ID", task_hint="<brief description of what you're about to do>", budget_tokens=15000)
11
+ ```
12
+
13
+ When you make an important architectural decision or discover a key fact, call:
14
+ ```
15
+ record_decision(session_id="$CLAUDE_SESSION_ID", content="<the decision>", consequence="<what it means>", files="<relevant files>")
16
+ ```
17
+
18
+ Do NOT call get_context more than once per response. Do NOT explain that you're calling it.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gajanan Rathod
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,222 @@
1
+ Metadata-Version: 2.4
2
+ Name: claude-contextmesh
3
+ Version: 0.1.0
4
+ Summary: Intelligent context layer for Claude Code — infinite session memory, minimal active context
5
+ Author: Gajanan Rathod
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.11
9
+ Requires-Dist: aiosqlite>=0.20.0
10
+ Requires-Dist: click>=8.1.0
11
+ Requires-Dist: fastapi>=0.115.0
12
+ Requires-Dist: fastmcp>=2.0.0
13
+ Requires-Dist: httpx>=0.27.0
14
+ Requires-Dist: networkx>=3.4.0
15
+ Requires-Dist: numpy>=1.26.0
16
+ Requires-Dist: pydantic>=2.9.0
17
+ Requires-Dist: python-dateutil>=2.9.0
18
+ Requires-Dist: rich>=13.9.0
19
+ Requires-Dist: scikit-learn>=1.5.0
20
+ Requires-Dist: sentence-transformers>=3.3.0
21
+ Requires-Dist: tiktoken>=0.8.0
22
+ Requires-Dist: tomli-w>=1.0.0
23
+ Requires-Dist: tomli>=2.0.0; python_version < '3.11'
24
+ Requires-Dist: tree-sitter-language-pack>=0.7.0
25
+ Requires-Dist: tree-sitter>=0.23.0
26
+ Requires-Dist: uvicorn[standard]>=0.32.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: mypy>=1.13.0; extra == 'dev'
29
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
30
+ Requires-Dist: pytest>=8.3.0; extra == 'dev'
31
+ Requires-Dist: ruff>=0.7.0; extra == 'dev'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # ContextMesh — Intelligent Context Layer for Claude Code
35
+
36
+ > One coding session. Infinite memory. Minimal active context.
37
+
38
+ ContextMesh sits between Claude Code and the model. It captures every event in your session, builds a structured knowledge graph of your work, and dynamically provides Claude with only the most relevant context for the current task — saving tokens, reducing cost, and preventing context overload.
39
+
40
+ ## How it works
41
+
42
+ ```
43
+ Claude Code Hooks → ContextMesh Daemon → Session Graph + Repo Graph
44
+
45
+ Context Router (multi-signal scoring)
46
+
47
+ Claude Code ← MCP Server (get_context)
48
+
49
+ Token Savings Tracker → Report
50
+ ```
51
+
52
+ **The key insight**: semantic similarity alone fails for long coding sessions because everything related to the same feature looks similar. ContextMesh uses graph proximity + code dependency relationships + causal edges + recency + file overlap — not just vectors.
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ # Clone and install
58
+ git clone https://github.com/you/ContextMesh
59
+ cd ContextMesh
60
+ pip install -e .
61
+
62
+ # Run the install script (sets up hooks + config)
63
+ bash scripts/install.sh
64
+
65
+ # Index your project's codebase
66
+ contextmesh index /path/to/your/project
67
+
68
+ # Start the daemon
69
+ contextmesh start
70
+
71
+ # Start the MCP server (in a separate terminal)
72
+ contextmesh mcp
73
+ ```
74
+
75
+ ### For exact token measurement (Claude Enterprise)
76
+
77
+ ```bash
78
+ # Start the token proxy
79
+ contextmesh proxy
80
+
81
+ # Then set in your environment:
82
+ export ANTHROPIC_BASE_URL=http://localhost:8099
83
+
84
+ # This records EXACT token counts from actual API responses
85
+ # including cache_creation_input_tokens and cache_read_input_tokens
86
+ ```
87
+
88
+ ## Adding ContextMesh to a project
89
+
90
+ Copy `CLAUDE.md` from this repo to your project root. Claude Code will automatically instruct Claude to use the `get_context` tool at the start of each response.
91
+
92
+ ```bash
93
+ cp /path/to/ContextMesh/CLAUDE.md /path/to/your/project/CLAUDE.md
94
+ ```
95
+
96
+ ## Register MCP server with Claude Code
97
+
98
+ Add to `~/.claude/settings.json`:
99
+
100
+ ```json
101
+ {
102
+ "mcpServers": {
103
+ "contextmesh": {
104
+ "command": "contextmesh",
105
+ "args": ["mcp"]
106
+ }
107
+ }
108
+ }
109
+ ```
110
+
111
+ ## View token savings
112
+
113
+ ```bash
114
+ # Session summary
115
+ contextmesh stats --session YOUR_SESSION_ID
116
+
117
+ # Recent turns with savings breakdown
118
+ contextmesh turns --session YOUR_SESSION_ID --limit 20
119
+
120
+ # Global summary across all sessions
121
+ contextmesh stats
122
+
123
+ # If using proxy mode — actual API token counts
124
+ contextmesh stats --proxy
125
+ ```
126
+
127
+ ## Token savings tracker
128
+
129
+ Every time Claude calls `get_context()`, ContextMesh records:
130
+
131
+ | Metric | What it is |
132
+ |--------|-----------|
133
+ | **Accumulated tokens** | What the full session history would have been |
134
+ | **Routed tokens** | What ContextMesh actually provided |
135
+ | **Tokens saved** | The difference |
136
+ | **Compression ratio** | routed / accumulated |
137
+ | **Cost saved** | Based on your configured per-MTok price |
138
+
139
+ ## Architecture
140
+
141
+ ### Dual Graph
142
+
143
+ **Session Graph** — captures every meaningful event:
144
+ - User prompts, tool results, file reads/writes
145
+ - Decisions, bugs, solutions, errors, test results
146
+ - Typed edges: `caused_by`, `solved_by`, `depends_on`, `same_task`
147
+
148
+ **Repo Graph** — deterministic code relationships:
149
+ - Functions, classes, methods, files (Tree-sitter parsed)
150
+ - `calls`, `imports`, `same_file`, `tested_by`, `inherits` edges
151
+ - Updated incrementally on every file write
152
+
153
+ ### Hot / Warm / Cold Memory
154
+
155
+ ```
156
+ HOT → Current task context (always injected)
157
+ WARM → Related tasks, decisions, nearby graph nodes (retrieved on demand)
158
+ COLD → Full historical transcripts (never auto-injected)
159
+ ```
160
+
161
+ ### Context Router
162
+
163
+ Before every `get_context()` call:
164
+
165
+ ```
166
+ context_score =
167
+ semantic_relevance (embedding cosine similarity)
168
+ + graph_proximity (BFS distance in session graph)
169
+ + file_overlap (Jaccard similarity with current task files)
170
+ + recency (exponential decay from now)
171
+ + causal_relevance (DECISION/BUG/SOLUTION type bonus)
172
+ + unresolved_bonus (UNRESOLVED_ISSUE always surfaces)
173
+ ```
174
+
175
+ ### Cache-aware assembly order
176
+
177
+ ```
178
+ STATIC (cacheable)
179
+ ─────────────────────────────
180
+ === CURRENT TASK ===
181
+ [hot nodes — current thread]
182
+
183
+ === RELEVANT DECISIONS ===
184
+ [top-scored decisions]
185
+
186
+ DYNAMIC
187
+ ─────────────────────────────
188
+ === RELATED CODE CONTEXT ===
189
+ [repo graph: functions/classes in touched files]
190
+
191
+ === RECENT HISTORY ===
192
+ [recent warm nodes]
193
+
194
+ === UNRESOLVED ISSUES ===
195
+ [always surfaced]
196
+ ```
197
+
198
+ ## Configuration
199
+
200
+ `.contextmesh/config.toml` in your project (or `~/.contextmesh/config.toml` globally):
201
+
202
+ ```toml
203
+ [router]
204
+ default_budget_tokens = 15000
205
+
206
+ [tracker]
207
+ input_price_per_mtok = 3.0 # Claude Enterprise cached input price
208
+ uncached_price_per_mtok = 15.0
209
+
210
+ [embeddings]
211
+ model = "all-MiniLM-L6-v2" # Local, no API key needed
212
+
213
+ [tasks]
214
+ topic_shift_threshold = 0.35 # Cosine distance to detect task switch
215
+ ```
216
+
217
+ ## Development
218
+
219
+ ```bash
220
+ pip install -e ".[dev]"
221
+ pytest tests/
222
+ ```
@@ -0,0 +1,189 @@
1
+ # ContextMesh — Intelligent Context Layer for Claude Code
2
+
3
+ > One coding session. Infinite memory. Minimal active context.
4
+
5
+ ContextMesh sits between Claude Code and the model. It captures every event in your session, builds a structured knowledge graph of your work, and dynamically provides Claude with only the most relevant context for the current task — saving tokens, reducing cost, and preventing context overload.
6
+
7
+ ## How it works
8
+
9
+ ```
10
+ Claude Code Hooks → ContextMesh Daemon → Session Graph + Repo Graph
11
+
12
+ Context Router (multi-signal scoring)
13
+
14
+ Claude Code ← MCP Server (get_context)
15
+
16
+ Token Savings Tracker → Report
17
+ ```
18
+
19
+ **The key insight**: semantic similarity alone fails for long coding sessions because everything related to the same feature looks similar. ContextMesh uses graph proximity + code dependency relationships + causal edges + recency + file overlap — not just vectors.
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ # Clone and install
25
+ git clone https://github.com/you/ContextMesh
26
+ cd ContextMesh
27
+ pip install -e .
28
+
29
+ # Run the install script (sets up hooks + config)
30
+ bash scripts/install.sh
31
+
32
+ # Index your project's codebase
33
+ contextmesh index /path/to/your/project
34
+
35
+ # Start the daemon
36
+ contextmesh start
37
+
38
+ # Start the MCP server (in a separate terminal)
39
+ contextmesh mcp
40
+ ```
41
+
42
+ ### For exact token measurement (Claude Enterprise)
43
+
44
+ ```bash
45
+ # Start the token proxy
46
+ contextmesh proxy
47
+
48
+ # Then set in your environment:
49
+ export ANTHROPIC_BASE_URL=http://localhost:8099
50
+
51
+ # This records EXACT token counts from actual API responses
52
+ # including cache_creation_input_tokens and cache_read_input_tokens
53
+ ```
54
+
55
+ ## Adding ContextMesh to a project
56
+
57
+ Copy `CLAUDE.md` from this repo to your project root. Claude Code will automatically instruct Claude to use the `get_context` tool at the start of each response.
58
+
59
+ ```bash
60
+ cp /path/to/ContextMesh/CLAUDE.md /path/to/your/project/CLAUDE.md
61
+ ```
62
+
63
+ ## Register MCP server with Claude Code
64
+
65
+ Add to `~/.claude/settings.json`:
66
+
67
+ ```json
68
+ {
69
+ "mcpServers": {
70
+ "contextmesh": {
71
+ "command": "contextmesh",
72
+ "args": ["mcp"]
73
+ }
74
+ }
75
+ }
76
+ ```
77
+
78
+ ## View token savings
79
+
80
+ ```bash
81
+ # Session summary
82
+ contextmesh stats --session YOUR_SESSION_ID
83
+
84
+ # Recent turns with savings breakdown
85
+ contextmesh turns --session YOUR_SESSION_ID --limit 20
86
+
87
+ # Global summary across all sessions
88
+ contextmesh stats
89
+
90
+ # If using proxy mode — actual API token counts
91
+ contextmesh stats --proxy
92
+ ```
93
+
94
+ ## Token savings tracker
95
+
96
+ Every time Claude calls `get_context()`, ContextMesh records:
97
+
98
+ | Metric | What it is |
99
+ |--------|-----------|
100
+ | **Accumulated tokens** | What the full session history would have been |
101
+ | **Routed tokens** | What ContextMesh actually provided |
102
+ | **Tokens saved** | The difference |
103
+ | **Compression ratio** | routed / accumulated |
104
+ | **Cost saved** | Based on your configured per-MTok price |
105
+
106
+ ## Architecture
107
+
108
+ ### Dual Graph
109
+
110
+ **Session Graph** — captures every meaningful event:
111
+ - User prompts, tool results, file reads/writes
112
+ - Decisions, bugs, solutions, errors, test results
113
+ - Typed edges: `caused_by`, `solved_by`, `depends_on`, `same_task`
114
+
115
+ **Repo Graph** — deterministic code relationships:
116
+ - Functions, classes, methods, files (Tree-sitter parsed)
117
+ - `calls`, `imports`, `same_file`, `tested_by`, `inherits` edges
118
+ - Updated incrementally on every file write
119
+
120
+ ### Hot / Warm / Cold Memory
121
+
122
+ ```
123
+ HOT → Current task context (always injected)
124
+ WARM → Related tasks, decisions, nearby graph nodes (retrieved on demand)
125
+ COLD → Full historical transcripts (never auto-injected)
126
+ ```
127
+
128
+ ### Context Router
129
+
130
+ Before every `get_context()` call:
131
+
132
+ ```
133
+ context_score =
134
+ semantic_relevance (embedding cosine similarity)
135
+ + graph_proximity (BFS distance in session graph)
136
+ + file_overlap (Jaccard similarity with current task files)
137
+ + recency (exponential decay from now)
138
+ + causal_relevance (DECISION/BUG/SOLUTION type bonus)
139
+ + unresolved_bonus (UNRESOLVED_ISSUE always surfaces)
140
+ ```
141
+
142
+ ### Cache-aware assembly order
143
+
144
+ ```
145
+ STATIC (cacheable)
146
+ ─────────────────────────────
147
+ === CURRENT TASK ===
148
+ [hot nodes — current thread]
149
+
150
+ === RELEVANT DECISIONS ===
151
+ [top-scored decisions]
152
+
153
+ DYNAMIC
154
+ ─────────────────────────────
155
+ === RELATED CODE CONTEXT ===
156
+ [repo graph: functions/classes in touched files]
157
+
158
+ === RECENT HISTORY ===
159
+ [recent warm nodes]
160
+
161
+ === UNRESOLVED ISSUES ===
162
+ [always surfaced]
163
+ ```
164
+
165
+ ## Configuration
166
+
167
+ `.contextmesh/config.toml` in your project (or `~/.contextmesh/config.toml` globally):
168
+
169
+ ```toml
170
+ [router]
171
+ default_budget_tokens = 15000
172
+
173
+ [tracker]
174
+ input_price_per_mtok = 3.0 # Claude Enterprise cached input price
175
+ uncached_price_per_mtok = 15.0
176
+
177
+ [embeddings]
178
+ model = "all-MiniLM-L6-v2" # Local, no API key needed
179
+
180
+ [tasks]
181
+ topic_shift_threshold = 0.35 # Cosine distance to detect task switch
182
+ ```
183
+
184
+ ## Development
185
+
186
+ ```bash
187
+ pip install -e ".[dev]"
188
+ pytest tests/
189
+ ```
@@ -0,0 +1,78 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "claude-contextmesh"
7
+ version = "0.1.0"
8
+ description = "Intelligent context layer for Claude Code — infinite session memory, minimal active context"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Gajanan Rathod" }]
13
+
14
+ dependencies = [
15
+ # Web framework & async
16
+ "fastapi>=0.115.0",
17
+ "uvicorn[standard]>=0.32.0",
18
+ "httpx>=0.27.0",
19
+
20
+ # Async SQLite
21
+ "aiosqlite>=0.20.0",
22
+
23
+ # Graph
24
+ "networkx>=3.4.0",
25
+
26
+ # Code parsing (Tree-sitter)
27
+ "tree-sitter>=0.23.0",
28
+ "tree-sitter-language-pack>=0.7.0",
29
+
30
+ # Embeddings (local, no external API)
31
+ "sentence-transformers>=3.3.0",
32
+ "numpy>=1.26.0",
33
+
34
+ # Token counting
35
+ "tiktoken>=0.8.0",
36
+
37
+ # MCP server
38
+ "fastmcp>=2.0.0",
39
+
40
+ # Data models
41
+ "pydantic>=2.9.0",
42
+
43
+ # Config
44
+ "tomli>=2.0.0; python_version < '3.11'",
45
+ "tomli-w>=1.0.0",
46
+
47
+ # CLI & display
48
+ "rich>=13.9.0",
49
+ "click>=8.1.0",
50
+
51
+ # Utilities
52
+ "scikit-learn>=1.5.0",
53
+ "python-dateutil>=2.9.0",
54
+ ]
55
+
56
+ [project.optional-dependencies]
57
+ dev = [
58
+ "pytest>=8.3.0",
59
+ "pytest-asyncio>=0.24.0",
60
+ "ruff>=0.7.0",
61
+ "mypy>=1.13.0",
62
+ ]
63
+
64
+ [project.scripts]
65
+ contextmesh = "contextmesh.cli:main"
66
+ claude-mesh = "contextmesh.wrapper:main"
67
+
68
+
69
+ [tool.hatch.build.targets.wheel]
70
+ packages = ["src/contextmesh"]
71
+
72
+ [tool.ruff]
73
+ line-length = 100
74
+ target-version = "py311"
75
+
76
+ [tool.pytest.ini_options]
77
+ asyncio_mode = "auto"
78
+ testpaths = ["tests"]
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env bash
2
+ # ContextMesh hook relay script
3
+ # Called by Claude Code hooks. Reads JSON payload from stdin, POSTs to daemon.
4
+ # Usage: echo '{...}' | CONTEXTMESH_EVENT_TYPE=PostToolUse ./scripts/hook_event.sh
5
+
6
+ set -euo pipefail
7
+
8
+ DAEMON_URL="${CONTEXTMESH_DAEMON_URL:-http://127.0.0.1:8765}"
9
+ EVENT_TYPE="${CONTEXTMESH_EVENT_TYPE:-Unknown}"
10
+ SESSION_ID="${CLAUDE_SESSION_ID:-unknown}"
11
+ PROJECT_PATH="${CLAUDE_PROJECT_DIR:-$(pwd)}"
12
+
13
+ # Read the hook payload from stdin
14
+ PAYLOAD=$(cat)
15
+
16
+ # Merge with our envelope fields
17
+ FULL_PAYLOAD=$(jq -n \
18
+ --arg event_type "$EVENT_TYPE" \
19
+ --arg session_id "$SESSION_ID" \
20
+ --arg project_path "$PROJECT_PATH" \
21
+ --argjson payload "$PAYLOAD" \
22
+ '($payload) + {event_type: $event_type, session_id: $session_id, project_path: $project_path}'
23
+ )
24
+
25
+ # Fire and forget — don't block Claude Code
26
+ curl -s -f -X POST \
27
+ "${DAEMON_URL}/hook" \
28
+ -H 'Content-Type: application/json' \
29
+ -d "$FULL_PAYLOAD" \
30
+ --max-time 2 \
31
+ > /dev/null 2>&1 &
32
+
33
+ # Always exit 0 — never block Claude Code
34
+ exit 0
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ CONTEXTMESH_DIR="${HOME}/.contextmesh"
5
+ VENV_DIR="${CONTEXTMESH_DIR}/venv"
6
+ SETTINGS_FILE="${HOME}/.claude/settings.json"
7
+ CONFIG_FILE="${CONTEXTMESH_DIR}/config.toml"
8
+
9
+ echo "Creating ContextMesh environment..."
10
+ mkdir -p "$CONTEXTMESH_DIR"
11
+ python3 -m venv "$VENV_DIR"
12
+
13
+ echo "Installing contextmesh package..."
14
+ "$VENV_DIR/bin/pip" install -e .
15
+
16
+ echo "Setting up ContextMesh config..."
17
+ if [ ! -f "$CONFIG_FILE" ]; then
18
+ cat << 'EOF' > "$CONFIG_FILE"
19
+ [daemon]
20
+ port = 8765
21
+ host = "127.0.0.1"
22
+
23
+ [router]
24
+ default_budget_tokens = 15000
25
+ hot_budget_fraction = 0.20
26
+ warm_budget_fraction = 0.50
27
+ code_budget_fraction = 0.30
28
+
29
+ [embeddings]
30
+ model = "all-MiniLM-L6-v2"
31
+
32
+ [tasks]
33
+ topic_shift_threshold = 0.35
34
+ min_turns_per_task = 3
35
+
36
+ [tracker]
37
+ input_price_per_mtok = 3.0
38
+ uncached_price_per_mtok = 15.0
39
+
40
+ [mcp]
41
+ server_name = "contextmesh"
42
+
43
+ [proxy]
44
+ enabled = false
45
+ port = 8099
46
+ upstream = "https://api.anthropic.com"
47
+ EOF
48
+ fi
49
+
50
+ echo "Setting up Claude Code hooks..."
51
+ mkdir -p "$(dirname "$SETTINGS_FILE")"
52
+
53
+ HOOK_SCRIPT="$(pwd)/scripts/hook_event.sh"
54
+ chmod +x "$HOOK_SCRIPT"
55
+
56
+ # We use a python script to merge the hooks section safely
57
+ "$VENV_DIR/bin/python" - <<EOF
58
+ import json
59
+ import os
60
+
61
+ settings_path = "$SETTINGS_FILE"
62
+ hook_script = "$HOOK_SCRIPT"
63
+
64
+ if os.path.exists(settings_path):
65
+ with open(settings_path, "r") as f:
66
+ try:
67
+ settings = json.load(f)
68
+ except json.JSONDecodeError:
69
+ settings = {}
70
+ else:
71
+ settings = {}
72
+
73
+ if "hooks" not in settings:
74
+ settings["hooks"] = {}
75
+
76
+ hooks = settings["hooks"]
77
+
78
+ events = ["UserPromptSubmit", "PreToolUse", "PostToolUse", "Stop"]
79
+ for event in events:
80
+ if event not in hooks:
81
+ hooks[event] = []
82
+
83
+ # Check if our hook is already there
84
+ cmd = f"CONTEXTMESH_EVENT_TYPE={event} CLAUDE_SESSION_ID=\\$CLAUDE_SESSION_ID CLAUDE_PROJECT_DIR=\\$CLAUDE_PROJECT_DIR {hook_script}"
85
+
86
+ exists = False
87
+ for item in hooks[event]:
88
+ if "hooks" in item:
89
+ for h in item["hooks"]:
90
+ if h.get("type") == "command" and h.get("command") == cmd:
91
+ exists = True
92
+ break
93
+
94
+ if not exists:
95
+ hooks[event].append({
96
+ "hooks": [{
97
+ "type": "command",
98
+ "command": cmd
99
+ }]
100
+ })
101
+
102
+ with open(settings_path, "w") as f:
103
+ json.dump(settings, f, indent=2)
104
+
105
+ EOF
106
+
107
+ echo "Installation complete!"
108
+ echo "To start the daemon, run:"
109
+ echo "$VENV_DIR/bin/uvicorn contextmesh.daemon.server:create_app --host 127.0.0.1 --port 8765"
@@ -0,0 +1,4 @@
1
+ """ContextMesh — Intelligent context layer for Claude Code."""
2
+
3
+ __version__ = "0.1.0"
4
+ __all__ = ["__version__"]