@purpleraven/hits 0.2.1 → 0.2.3

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 (3) hide show
  1. package/README.md +271 -222
  2. package/bin/hits-mcp.js +133 -0
  3. package/package.json +4 -3
package/README.md CHANGED
@@ -1,116 +1,91 @@
1
- # HITS - Hybrid Intel Trace System
1
+ # hits
2
2
 
3
3
  > Replicate your predecessor's brain as perfectly as possible, using the least amount of AI.
4
4
 
5
- ## Overview
5
+ A secure web-based knowledge management system that preserves organizational context across AI tool sessions. When your Claude session hits the token limit and you switch to a new one — HITS ensures nothing is lost.
6
6
 
7
- HITS is a hybrid knowledge management system designed to preserve organizational core knowledge and decision-making context. It automates project-specific handover when switching between AI tool sessions (Claude, OpenCode, Cursor, etc.).
7
+ ## What Problem Does This Solve?
8
8
 
9
- ### Core Values
9
+ You're working on a project with Claude Code. After a long session, you hit the token limit. A new session starts — but it has **no idea** what you did, what decisions were made, or what was left unfinished.
10
10
 
11
- - **Token Optimization**: Semantic compression and on-demand analysis to reduce AI costs
12
- - **Context Preservation**: Store decision-making processes in a Why-How-What hierarchy
13
- - **Failure Experience**: Record failed approaches alongside successes as Negative Paths
14
- - **Security Hardened**: Argon2id hashing, JWT HttpOnly cookies, CSP, Rate Limiting
15
- - **AI Session Handover**: Automatically transfer project context when AI sessions rotate due to token limits
16
- - **Centralized Storage**: All AI tool work logs are consolidated at `~/.hits/data/`
17
- - **Project Isolation**: Completely independent context management based on project path
11
+ **HITS fixes this:**
18
12
 
19
- ## Tech Stack
13
+ 1. **Record work** during each AI session (manually or via MCP tools)
14
+ 2. **Query handover** when a new session starts — it gets the full context
15
+ 3. **Knowledge trees** preserve the WHY/HOW/WHAT of every project
16
+ 4. **All AI tools share the same data** — Claude, OpenCode, Cursor, it doesn't matter
20
17
 
21
- | Area | Technology |
22
- |------|-----------|
23
- | **Backend** | Python 3.10+, FastAPI, Pydantic v2 |
24
- | **Frontend** | Svelte 5, Vite, TypeScript |
25
- | **Authentication** | Argon2id (passwords), JWT HS256 (HttpOnly cookies) |
26
- | **Storage** | File-based (`~/.hits/data/`), Redis (optional) |
27
- | **Security** | CSP, CORS, Rate Limiting, Secure Headers |
28
-
29
- ## Installation
30
-
31
- ### Requirements
32
-
33
- - Python 3.10 or later
34
- - Node.js 18+ (for frontend build)
35
- - Redis (optional — falls back to file storage)
36
-
37
- ### Quick Start
38
-
39
- ```bash
40
- cd hits
41
- ./run.sh # Auto-install + start server
42
18
  ```
43
-
44
- #### Development Mode
45
-
46
- ```bash
47
- ./run.sh --dev # Vite HMR + FastAPI backend
19
+ [OpenCode session ends] [Claude session starts]
20
+ │ │
21
+ Record work: Query handover:
22
+ "Added JWT auth, → Previous: Added JWT auth
23
+ chose Argon2id over → Decisions: Argon2id > bcrypt
24
+ bcrypt, still need to → Pending: rate limiting
25
+ add rate limiting" → Files: auth/manager.py, ...
48
26
  ```
49
27
 
50
- #### Manual Installation
28
+ ## Quick Start
51
29
 
52
- ```bash
53
- # Python environment
54
- python3 -m venv venv
55
- source venv/bin/activate
56
- pip install -r requirements.txt
30
+ ### One Command — That's It
57
31
 
58
- # Frontend build
59
- cd hits_web
60
- npm install
61
- npm run build
62
- cd ..
63
-
64
- # Start server
65
- python -m hits_core.main --port 8765
32
+ ```bash
33
+ npx hits
66
34
  ```
67
35
 
68
- ## Security
36
+ That single command will:
69
37
 
70
- ### Authentication System
38
+ 1. **Detect Python 3.10+** on your system
39
+ 2. **Create a virtual environment** automatically
40
+ 3. **Install Python dependencies** (FastAPI, Argon2id, etc.)
41
+ 4. **Start the Python backend** (FastAPI on port 8765)
42
+ 5. **Start the web server** (Express on port 8765)
43
+ 6. Open **http://127.0.0.1:8765** in your browser
71
44
 
72
- | Feature | Implementation |
73
- |---------|---------------|
74
- | **Password Hashing** | Argon2id (memory=64MB, iterations=3, parallelism=1) |
75
- | **Minimum Password Length** | 8 characters |
76
- | **JWT Tokens** | HttpOnly + Secure + SameSite=Lax cookies |
77
- | **Access Token** | 15-minute expiry |
78
- | **Refresh Token** | 7-day expiry, sent only to `/api/auth/refresh` |
79
- | **First User** | Automatically assigned admin role |
80
- | **Subsequent Users** | Can only be created by admin |
45
+ ### First Time Setup
81
46
 
82
- ### Security Headers
47
+ On first visit, you'll create an admin account:
83
48
 
84
49
  ```
85
- Content-Security-Policy: default-src 'self'; script-src 'self'; ...
86
- X-Content-Type-Options: nosniff
87
- X-Frame-Options: DENY
88
- Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
89
- Referrer-Policy: strict-origin-when-cross-origin
90
- Permissions-Policy: camera=(), microphone=(), geolocation=()
50
+ ┌──────────────────────────────────────┐
51
+ │ 🌳 HITS │
52
+ │ Hybrid Intel Trace System │
53
+ │ │
54
+ │ ┌────────────────────────────────┐ │
55
+ │ │ Username: [____________] │ │
56
+ │ │ Password: [____________] │ │
57
+ │ │ │ │
58
+ │ │ [ Create Account ] │ │
59
+ │ │ │ │
60
+ │ │ First account = admin role │ │
61
+ │ └────────────────────────────────┘ │
62
+ └──────────────────────────────────────┘
91
63
  ```
92
64
 
93
- ### Rate Limiting
65
+ ### Custom Port
94
66
 
95
- - Login endpoint: 10 requests/minute (per IP)
96
- - Responds with 429 Too Many Requests when exceeded
67
+ ```bash
68
+ npx hits --port 9000
69
+ # or
70
+ HITS_PORT=9000 npx hits
71
+ ```
97
72
 
98
- ### Data Protection
73
+ ## Requirements
99
74
 
100
- | Item | Permissions | Description |
101
- |------|-------------|-------------|
102
- | `~/.hits/.auth/users.json` | 600 | User data (owner only) |
103
- | `~/.hits/.pepper` | 600 | HMAC pepper (owner only) |
104
- | `~/.hits/.jwt_secret` | 600 | JWT signing key (owner only) |
105
- | `~/.hits/.auth/` | 700 | Auth directory (owner only) |
75
+ | Requirement | Version | Why |
76
+ |-------------|---------|-----|
77
+ | **Node.js** | 18 | Runs the web server and manages the Python process |
78
+ | **Python** | 3.10 | Runs the FastAPI backend (auto-installed into venv) |
106
79
 
107
- ## Web UI
80
+ That's it. No database required — HITS uses file-based storage at `~/.hits/data/`.
108
81
 
109
- ### Layout
82
+ ## What You Get
83
+
84
+ ### Web UI
110
85
 
111
86
  ```
112
87
  ┌─────────────┬───────────────────────────────────┐
113
- │ Sidebar │ Header (tabs + user menu)
88
+ │ Sidebar │ Header (tabs + user menu 🌐 lang)
114
89
  │ ├───────────────────────────────────┤
115
90
  │ 📂 Projects│ │
116
91
  │ ────────── │ Main content area │
@@ -121,64 +96,193 @@ Permissions-Policy: camera=(), microphone=(), geolocation=()
121
96
  └─────────────┴───────────────────────────────────┘
122
97
  ```
123
98
 
124
- ### Features
99
+ **Knowledge Tree** — Organize project knowledge as Why-How-What nodes:
125
100
 
126
- - **Knowledge Tree**: Manage Why-How-What nodes by category (full CRUD)
127
- - **Timeline**: Project work logs, grouped by date, with search
128
- - **Handover**: Auto-generated handover summary when a project is selected
129
- - **Project Switching**: Instant context switch via sidebar
130
- - **User Management**: Password change, logout
101
+ ```
102
+ 📁 Authentication
103
+ ├── WHY "Need secure user auth for web UI"
104
+ ├── HOW "Argon2id hashing + JWT HttpOnly cookies"
105
+ └── WHAT "POST /api/auth/login Set-Cookie"
106
+ └── ❌ Negative Path: "Tried bcrypt first — too fast, GPU-vulnerable"
107
+ ```
131
108
 
132
- ## AI Session Handover
109
+ **Timeline** Chronological work log, grouped by date, filterable by project
133
110
 
134
- ### How It Works
111
+ **Handover** Auto-generated summary of a project's context, ready to paste into a new AI session
135
112
 
136
- ```
137
- [OpenCode Session] [Claude Session]
138
- │ │
139
- Perform work Session start
140
- │ │
141
- Record work ──────────────────────→ Query handover
142
- POST /api/work-log GET /api/handover
143
- project_path: /my-project project_path: /my-project
144
- │ │
145
- └──→ ~/.hits/data/ ←──┘ │
146
- (centralized) Understand previous context
147
-
148
- Continue work seamlessly
113
+ **i18n** — Korean/English toggle (🌐 button in header)
114
+
115
+ ### MCP Tools for AI Assistants
116
+
117
+ HITS includes an MCP server so your AI can read and write handover data directly. No need to clone the repo — it works right out of the npm package.
118
+
119
+ #### Register with OpenCode (`~/.config/opencode/opencode.json`)
120
+
121
+ ```json
122
+ {
123
+ "mcp": {
124
+ "hits": {
125
+ "type": "local",
126
+ "command": ["npx", "hits-mcp"]
127
+ }
128
+ }
129
+ }
149
130
  ```
150
131
 
151
- ### MCP Configuration
132
+ #### Register with Claude Code
152
133
 
153
- Add to your OpenCode or Claude MCP settings:
134
+ ```bash
135
+ claude mcp add hits -- npx hits-mcp
136
+ ```
137
+
138
+ #### Register with Any MCP Client
154
139
 
155
140
  ```json
156
141
  {
157
- "hits": {
158
- "type": "local",
159
- "command": ["python", "-m", "hits_core.mcp.server"],
160
- "cwd": "/path/to/hits"
142
+ "mcpServers": {
143
+ "hits": {
144
+ "command": "npx",
145
+ "args": ["hits-mcp"]
146
+ }
161
147
  }
162
148
  }
163
149
  ```
164
150
 
165
- MCP Tools:
166
- - `hits_record_work`: Record work entry
167
- - `hits_get_handover`: Get handover summary
168
- - `hits_search_works`: Search past work
169
- - `hits_list_projects`: List projects
170
- - `hits_get_recent`: Get recent work
151
+ > **How it works:** `npx hits-mcp` auto-detects Python, creates a venv inside the npm package, installs dependencies, and spawns the MCP server over stdio — all automatically on first run.
152
+
153
+ #### 5 MCP Tools
154
+
155
+ | Tool | What It Does |
156
+ |------|-------------|
157
+ | `hits_record_work` | Record a work entry (auto-detects project path from CWD) |
158
+ | `hits_get_handover` | Get handover summary for the current project |
159
+ | `hits_search_works` | Search past work by keyword |
160
+ | `hits_list_projects` | List all projects with recorded work |
161
+ | `hits_get_recent` | Get the most recent work entries |
162
+
163
+ #### Example AI Workflow
164
+
165
+ ```
166
+ User: "Continue working on the auth system"
167
+
168
+ AI (auto-calls hits_get_handover):
169
+ → Previous session added Argon2id password hashing
170
+ → Decisions: Argon2id (not bcrypt), JWT HS256, HttpOnly cookies
171
+ → Pending: Rate limiting, password change endpoint
172
+
173
+ AI: "I see the auth system uses Argon2id + JWT. Let me add rate limiting..."
174
+
175
+ (later)
176
+
177
+ AI (auto-calls hits_record_work):
178
+ → Recorded: "Added rate limiting (10 req/min on login endpoint)"
179
+ ```
180
+
181
+ ### REST API
182
+
183
+ All features are also accessible via HTTP API:
184
+
185
+ ```bash
186
+ # Health check
187
+ curl http://localhost:8765/api/health
188
+
189
+ # Record work
190
+ curl -X POST http://localhost:8765/api/work-log \
191
+ -H "Content-Type: application/json" \
192
+ -b cookies.txt \
193
+ -d '{
194
+ "performed_by": "claude",
195
+ "request_text": "Added rate limiting to login endpoint",
196
+ "context": "10 req/min per IP, 429 response on limit",
197
+ "project_path": "/home/user/my-project",
198
+ "tags": ["security", "api"]
199
+ }'
200
+
201
+ # Get handover summary
202
+ curl "http://localhost:8765/api/handover?project_path=/home/user/my-project" \
203
+ -b cookies.txt
204
+
205
+ # Search past work
206
+ curl "http://localhost:8765/api/work-logs/search?q=auth" \
207
+ -b cookies.txt
208
+ ```
209
+
210
+ ## Security
211
+
212
+ HITS is built with security as a first-class concern:
213
+
214
+ | Feature | Implementation |
215
+ |---------|---------------|
216
+ | **Password Hashing** | Argon2id (64MB memory, 3 iterations, parallelism=1) |
217
+ | **JWT Tokens** | HttpOnly + Secure + SameSite=Lax cookies |
218
+ | **Access Token** | 15-minute expiry |
219
+ | **Refresh Token** | 7-day expiry, restricted to `/api/auth/refresh` path |
220
+ | **Brute Force Protection** | 10 login attempts/minute per IP |
221
+ | **Security Headers** | CSP, X-Frame-Options: DENY, HSTS preload, nosniff |
222
+ | **Data Protection** | Auth files stored with `chmod 600` (owner-only) |
223
+ | **First User Policy** | First registered user becomes admin; subsequent users need admin approval |
224
+
225
+ ## How It Works Under the Hood
226
+
227
+ ```
228
+ npx hits
229
+
230
+ ├── 1. findPython() → Detect Python 3.10+ on system
231
+ ├── 2. setupPython() → Create venv, install deps
232
+ ├── 3. startBackend() → Spawn FastAPI process (port 8765)
233
+ └── 4. startExpress() → Serve frontend + proxy /api → FastAPI
234
+
235
+ Browser Express (8765) FastAPI (8765 internal)
236
+ │ │ │
237
+ ├── GET / ───→ static (Svelte SPA) │
238
+ ├── GET /some/route ───→ SPA fallback │
239
+ └── GET /api/* ───→ proxy ──────────────→ FastAPI routes
240
+ POST /api/* ───→ proxy ──────────────→ FastAPI routes
241
+ ```
242
+
243
+ All data is stored centrally:
171
244
 
172
- ## API Endpoints
245
+ ```
246
+ ~/.hits/
247
+ ├── data/ ← All project data
248
+ │ ├── work_logs/ ← AI session work logs (JSON)
249
+ │ ├── trees/ ← Knowledge trees
250
+ │ └── workflows/ ← Workflows
251
+ ├── .auth/ ← User accounts (chmod 700)
252
+ │ └── users.json ← User data (chmod 600)
253
+ ├── .pepper ← HMAC pepper (chmod 600)
254
+ └── .jwt_secret ← JWT signing key (chmod 600)
255
+
256
+ Override with HITS_DATA_PATH environment variable
257
+ ```
258
+
259
+ ## CLI Options
260
+
261
+ ```
262
+ npx hits [options]
263
+
264
+ Options:
265
+ -p, --port <port> Server port (default: 8765)
266
+ -d, --dev Development mode (verbose logging)
267
+ -s, --setup Install dependencies only, don't start
268
+ -h, --help Show help
269
+
270
+ Environment:
271
+ HITS_PORT Server port override
272
+ HITS_PYTHON Path to python executable (default: auto-detect)
273
+ HITS_DATA_PATH Data storage path (default: ~/.hits/data)
274
+ ```
275
+
276
+ ## API Reference
173
277
 
174
278
  ### Authentication
175
279
 
176
280
  | Method | Path | Description |
177
281
  |--------|------|-------------|
178
- | GET | `/api/auth/status` | Check auth status |
179
- | POST | `/api/auth/register` | Register user |
180
- | POST | `/api/auth/login` | Login (sets HttpOnly cookies) |
181
- | POST | `/api/auth/logout` | Logout |
282
+ | GET | `/api/auth/status` | Check if auth is initialized, current login status |
283
+ | POST | `/api/auth/register` | Register user (first user = admin) |
284
+ | POST | `/api/auth/login` | Login sets HttpOnly cookies |
285
+ | POST | `/api/auth/logout` | Logout — clears cookies |
182
286
  | POST | `/api/auth/refresh` | Refresh access token |
183
287
  | GET | `/api/auth/me` | Get current user info |
184
288
  | PUT | `/api/auth/password` | Change password |
@@ -188,8 +292,8 @@ MCP Tools:
188
292
  | Method | Path | Description |
189
293
  |--------|------|-------------|
190
294
  | POST | `/api/work-log` | Create work log |
191
- | GET | `/api/work-logs` | List work logs (supports `project_path` filter) |
192
- | GET | `/api/work-logs/search?q=...` | Search work logs |
295
+ | GET | `/api/work-logs` | List logs (filter by `project_path`) |
296
+ | GET | `/api/work-logs/search?q=...` | Search logs by keyword |
193
297
  | GET | `/api/work-log/{id}` | Get single entry |
194
298
  | PUT | `/api/work-log/{id}` | Update entry |
195
299
  | DELETE | `/api/work-log/{id}` | Delete entry |
@@ -199,10 +303,10 @@ MCP Tools:
199
303
  | Method | Path | Description |
200
304
  |--------|------|-------------|
201
305
  | GET | `/api/handover?project_path=...` | Get project handover summary |
202
- | GET | `/api/handover/projects` | List projects |
203
- | GET | `/api/handover/project-stats?project_path=...` | Get project stats |
306
+ | GET | `/api/handover/projects` | List all projects |
307
+ | GET | `/api/handover/project-stats?project_path=...` | Get project statistics |
204
308
 
205
- ### Knowledge Categories
309
+ ### Knowledge
206
310
 
207
311
  | Method | Path | Description |
208
312
  |--------|------|-------------|
@@ -210,127 +314,72 @@ MCP Tools:
210
314
  | POST | `/api/knowledge/category` | Create category |
211
315
  | PUT | `/api/knowledge/category/{name}` | Update category |
212
316
  | DELETE | `/api/knowledge/category/{name}` | Delete category |
213
- | POST | `/api/knowledge/category/{name}/nodes` | Add node |
317
+ | POST | `/api/knowledge/category/{name}/nodes` | Add node to category |
214
318
  | PUT | `/api/knowledge/category/{name}/nodes/{idx}` | Update node |
215
319
  | DELETE | `/api/knowledge/category/{name}/nodes/{idx}` | Delete node |
216
320
 
217
- ### performed_by Values
218
-
219
- | AI Tool | Value |
220
- |---------|-------|
221
- | OpenCode | `opencode` |
222
- | Claude Code | `claude` |
223
- | Cursor | `cursor` |
224
- | Manual | `manual` |
225
-
226
- ## Architecture
227
-
228
- ```
229
- ┌──────────────────────────────────────────────────────────┐
230
- │ hits_web (Svelte 5 + Vite) │
231
- │ Material Dark theme · TypeScript │
232
- │ ┌──────────┬──────────┬──────────────────────────┐ │
233
- │ │ Sidebar │ Knowledge│ HandoverPanel │ │
234
- │ │ Projects │ Tree │ Handover summary view │ │
235
- │ │ Filter │ Timeline │ │ │
236
- │ └──────────┴──────────┴──────────────────────────┘ │
237
- │ ↕ API Client (fetch + HttpOnly cookies) │
238
- ├──────────────────────────────────────────────────────────┤
239
- │ hits_core (Apache 2.0) │
240
- │ ┌──────────┬──────────┬──────────┬──────────┐ │
241
- │ │ Models │ Storage │ AI │ Auth │ │
242
- │ │ Tree │ Redis │ Compress │ Argon2id │ │
243
- │ │ Node │ File │ SLM/LLM │ JWT │ │
244
- │ │ WorkLog │(~/.hits) │ Filter │ Middleware│ │
245
- │ └──────────┴──────────┴──────────┴──────────┘ │
246
- │ ┌──────────┬──────────┬──────────┐ │
247
- │ │ API │ Collector│ MCP │ │
248
- │ │ FastAPI │ Git/Shell│ Server │ │
249
- │ │ + Static │ AI Sess. │ 5 Tools │ │
250
- │ │ Serve │ │ │ │
251
- │ └──────────┴──────────┴──────────┘ │
252
- │ ┌──────────────────────────────┐ │
253
- │ │ Service Layer │ │
254
- │ │ TreeService HandoverService│ │
255
- │ │ KnowledgeService │ │
256
- │ └──────────────────────────────┘ │
257
- └──────────────────────────────────────────────────────────┘
258
- ```
259
-
260
- ## Knowledge Tree Structure
261
-
262
- ### Why-How-What Hierarchy
321
+ ## Troubleshooting
263
322
 
264
- ```
265
- ├── WHY (Intent/Purpose)
266
- │ ├── "Why was this system built?"
267
- │ └── "What is the business goal?"
268
-
269
- ├── HOW (Logic/Method)
270
- │ ├── "How was it implemented?"
271
- │ └── "What decisions were made?"
272
-
273
- └── WHAT (Execution/Tasks)
274
- ├── "What specifically does it do?"
275
- └── "Actionable tasks"
276
- ```
323
+ ### "Python 3.10+ not found"
277
324
 
278
- ## Development
325
+ Install Python 3.10 or later:
326
+ ```bash
327
+ # Ubuntu/Debian
328
+ sudo apt install python3.12
279
329
 
280
- ### Development Mode
330
+ # macOS
331
+ brew install python@3.12
281
332
 
282
- ```bash
283
- ./run.sh --dev # Vite HMR + FastAPI
333
+ # Or set manually:
334
+ export HITS_PYTHON=/usr/bin/python3.12
284
335
  ```
285
336
 
286
- ### Testing
337
+ ### "Frontend not built"
287
338
 
339
+ This shouldn't happen with the npm package (frontend is pre-built). If it does:
288
340
  ```bash
289
- ./run.sh --test # Run pytest
341
+ npx hits --setup
290
342
  ```
291
343
 
292
- ### Frontend Development
344
+ ### "ModuleNotFoundError: No module named 'hits_core'"
293
345
 
346
+ Python dependencies failed to install. Try:
294
347
  ```bash
295
- cd hits_web
296
- npm install # Install dependencies
297
- npm run dev # Vite dev server (http://localhost:5173)
298
- npm run build # Production build
348
+ npx hits --setup
299
349
  ```
300
350
 
301
- ## License
351
+ ### Redis Connection Failed
302
352
 
303
- | Package | License | Commercial Use |
304
- |---------|---------|---------------|
305
- | `hits_core` | Apache 2.0 | ✅ Free |
306
- | `hits_web` | Apache 2.0 | ✅ Free |
353
+ Not a problem HITS automatically uses file-based storage. Redis is optional.
307
354
 
308
- ## Troubleshooting
355
+ ## Development
309
356
 
310
- ### Node.js Not Found
357
+ If you're working on HITS itself:
311
358
 
312
359
  ```bash
313
- # Ubuntu/Debian
314
- curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
315
- sudo apt install -y nodejs
316
- ```
360
+ git clone https://github.com/lhjnano/hits.git
361
+ cd hits
317
362
 
318
- ### Redis Connection Failed
363
+ # Backend setup
364
+ python3 -m venv venv
365
+ source venv/bin/activate
366
+ pip install -r requirements.txt
319
367
 
320
- HITS works fine without Redis. It automatically falls back to file-based storage.
368
+ # Frontend build
369
+ cd hits_web && npm install && npm run build && cd ..
321
370
 
322
- ### Where Is Data Stored?
371
+ # Development mode (Vite HMR + FastAPI)
372
+ ./run.sh --dev
323
373
 
374
+ # Run tests
375
+ ./run.sh --test
324
376
  ```
325
- ~/.hits/
326
- ├── data/ ← Default location for all data
327
- │ ├── work_logs/ ← AI session work logs
328
- │ ├── trees/ ← Knowledge trees
329
- │ └── workflows/ ← Workflows
330
- ├── .auth/ ← Authentication data
331
- │ └── users.json ← User info (permissions 600)
332
- ├── .pepper ← HMAC pepper (permissions 600)
333
- └── .jwt_secret ← JWT signing key (permissions 600)
334
377
 
335
- Override with HITS_DATA_PATH environment variable
336
- ```
378
+ ## License
379
+
380
+ Apache 2.0 — free for commercial use.
381
+
382
+ ## Links
383
+
384
+ - **GitHub**: [https://github.com/lhjnano/hits](https://github.com/lhjnano/hits)
385
+ - **Issues**: [https://github.com/lhjnano/hits/issues](https://github.com/lhjnano/hits/issues)
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * HITS MCP Server - Node.js Wrapper
5
+ *
6
+ * Launches the HITS Python MCP server over stdio transport.
7
+ * Auto-detects Python, creates venv, installs deps — same as `npx hits`.
8
+ *
9
+ * Usage:
10
+ * npx hits-mcp
11
+ *
12
+ * Or in MCP config:
13
+ * { "command": ["npx", "hits-mcp"] }
14
+ *
15
+ * Environment:
16
+ * HITS_PYTHON Path to python executable (default: auto-detect)
17
+ * HITS_DATA_PATH Data storage path (default: ~/.hits/data)
18
+ */
19
+
20
+ import { spawn, execSync } from 'node:child_process';
21
+ import { existsSync } from 'node:fs';
22
+ import { join, dirname } from 'node:path';
23
+ import { fileURLToPath } from 'node:url';
24
+ import { platform } from 'node:os';
25
+
26
+ const __dirname = dirname(fileURLToPath(import.meta.url));
27
+ const ROOT = __dirname;
28
+ const isWin = platform() === 'win32';
29
+
30
+ // ─── Python Detection (same logic as server.js) ────────────────
31
+
32
+ function findPython() {
33
+ const envPython = process.env.HITS_PYTHON;
34
+ if (envPython && existsSync(envPython)) return envPython;
35
+
36
+ const candidates = isWin
37
+ ? ['python', 'python3', 'py']
38
+ : ['python3', 'python'];
39
+
40
+ for (const cmd of candidates) {
41
+ try {
42
+ const ver = execSync(`${cmd} --version`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] });
43
+ const match = ver.match(/Python (\d+)\.(\d+)/);
44
+ if (match && (parseInt(match[1]) > 3 || (parseInt(match[1]) === 3 && parseInt(match[2]) >= 10))) {
45
+ return cmd;
46
+ }
47
+ } catch {}
48
+ }
49
+ return null;
50
+ }
51
+
52
+ // ─── Venv Management ────────────────────────────────────────────
53
+
54
+ const VENV_DIR = join(ROOT, 'venv');
55
+ const PYTHON_BIN = isWin
56
+ ? join(VENV_DIR, 'Scripts', 'python.exe')
57
+ : join(VENV_DIR, 'bin', 'python');
58
+
59
+ function runCommand(cmd, args, opts = {}) {
60
+ return new Promise((resolve, reject) => {
61
+ const proc = spawn(cmd, args, { stdio: 'inherit', ...opts });
62
+ proc.on('close', (code) => {
63
+ if (code === 0) resolve();
64
+ else reject(new Error(`Command failed: ${cmd} ${args.join(' ')} (exit ${code})`));
65
+ });
66
+ proc.on('error', reject);
67
+ });
68
+ }
69
+
70
+ async function ensurePython() {
71
+ const pythonCmd = findPython();
72
+ if (!pythonCmd) {
73
+ console.error('[hits-mcp] Error: Python 3.10+ not found.');
74
+ console.error('[hits-mcp] Install: https://www.python.org/downloads/');
75
+ process.exit(1);
76
+ }
77
+
78
+ // Create venv if needed
79
+ if (!existsSync(PYTHON_BIN)) {
80
+ console.error(`[hits-mcp] Creating virtual environment... (${pythonCmd})`);
81
+ await runCommand(pythonCmd, ['-m', 'venv', VENV_DIR], { cwd: ROOT });
82
+ }
83
+
84
+ // Check if deps are installed
85
+ try {
86
+ execSync(
87
+ `${PYTHON_BIN} -c "import fastapi, pydantic, argon2, jose"`,
88
+ { stdio: 'ignore' }
89
+ );
90
+ } catch {
91
+ console.error('[hits-mcp] Installing Python dependencies...');
92
+ await runCommand(PYTHON_BIN, ['-m', 'pip', 'install', '-q', '--upgrade', 'pip'], { cwd: ROOT });
93
+ await runCommand(PYTHON_BIN, ['-m', 'pip', 'install', '-q', '-r', join(ROOT, 'requirements.txt')], { cwd: ROOT });
94
+ console.error('[hits-mcp] Dependencies installed.');
95
+ }
96
+ }
97
+
98
+ // ─── Launch MCP Server ──────────────────────────────────────────
99
+
100
+ async function main() {
101
+ await ensurePython();
102
+
103
+ // Spawn Python MCP server with stdio transport
104
+ const proc = spawn(PYTHON_BIN, ['-m', 'hits_core.mcp.server'], {
105
+ cwd: ROOT,
106
+ stdio: 'inherit', // stdin/stdout/stderr all connected to parent (MCP stdio)
107
+ env: {
108
+ ...process.env,
109
+ PYTHONPATH: ROOT,
110
+ },
111
+ });
112
+
113
+ proc.on('error', (err) => {
114
+ console.error(`[hits-mcp] Failed to start: ${err.message}`);
115
+ process.exit(1);
116
+ });
117
+
118
+ proc.on('exit', (code, signal) => {
119
+ if (signal) {
120
+ console.error(`[hits-mcp] Terminated by signal: ${signal}`);
121
+ }
122
+ process.exit(code || 0);
123
+ });
124
+
125
+ // Forward signals
126
+ process.on('SIGINT', () => proc.kill('SIGINT'));
127
+ process.on('SIGTERM', () => proc.kill('SIGTERM'));
128
+ }
129
+
130
+ main().catch((err) => {
131
+ console.error(`[hits-mcp] Fatal: ${err.message}`);
132
+ process.exit(1);
133
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@purpleraven/hits",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "HITS - Hybrid Intel Trace System. AI session handover with secure web UI.",
5
5
  "keywords": [
6
6
  "knowledge-management",
@@ -12,7 +12,8 @@
12
12
  "author": "HITS Team",
13
13
  "type": "module",
14
14
  "bin": {
15
- "hits": "bin/hits.js"
15
+ "hits": "bin/hits.js",
16
+ "hits-mcp": "bin/hits-mcp.js"
16
17
  },
17
18
  "scripts": {
18
19
  "start": "node bin/hits.js",
@@ -51,7 +52,7 @@
51
52
  "devDependencies": {},
52
53
  "repository": {
53
54
  "type": "git",
54
- "url": "git+https://lhjnano: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@github.com/lhjnano/hits.git"
55
+ "url": "git+https://github.com/lhjnano/hits.git"
55
56
  },
56
57
  "bugs": {
57
58
  "url": "https://github.com/lhjnano/hits/issues"