@purpleraven/hits 0.2.0 → 0.2.2
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/AGENTS.md +75 -75
- package/README.md +280 -243
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -19,137 +19,137 @@ If pre-flight checks fail, fix the errors before proceeding.
|
|
|
19
19
|
|
|
20
20
|
## AI Session Handover Protocol
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
When an AI session is replaced due to token limits, project-specific handover activates automatically.
|
|
23
|
+
All data is centrally stored at `~/.hits/data/` and isolated by project path.
|
|
24
24
|
|
|
25
|
-
###
|
|
25
|
+
### On Session Start
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
# HTTP API (HITS
|
|
28
|
+
# HTTP API (when HITS server is running)
|
|
29
29
|
curl -s "http://localhost:8765/api/handover?project_path=$(pwd)" | python -m json.tool
|
|
30
30
|
|
|
31
|
-
#
|
|
32
|
-
# hits_get_handover →
|
|
31
|
+
# Or via MCP tool (when HITS MCP is configured):
|
|
32
|
+
# hits_get_handover → Retrieve previous session's work, decisions, and unfinished items
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
###
|
|
35
|
+
### On Session End (MUST record)
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
curl -X POST http://localhost:8765/api/work-log \
|
|
39
39
|
-H "Content-Type: application/json" \
|
|
40
40
|
-d '{
|
|
41
|
-
"performed_by": "<
|
|
42
|
-
"request_text": "
|
|
43
|
-
"context": "
|
|
41
|
+
"performed_by": "<AI_tool_name>",
|
|
42
|
+
"request_text": "<work summary>",
|
|
43
|
+
"context": "<details, decisions>",
|
|
44
44
|
"source": "ai_session",
|
|
45
|
-
"tags": ["
|
|
46
|
-
"project_path": "
|
|
45
|
+
"tags": ["<tag>"],
|
|
46
|
+
"project_path": "<project_absolute_path>",
|
|
47
47
|
"result_data": {
|
|
48
|
-
"files_modified": ["
|
|
49
|
-
"commands_run": ["
|
|
48
|
+
"files_modified": ["<modified_file>"],
|
|
49
|
+
"commands_run": ["<executed_command>"]
|
|
50
50
|
}
|
|
51
51
|
}'
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
### performed_by
|
|
54
|
+
### performed_by Values
|
|
55
55
|
|
|
56
|
-
| AI
|
|
57
|
-
|
|
56
|
+
| AI Tool | performed_by Value |
|
|
57
|
+
|---------|-------------------|
|
|
58
58
|
| OpenCode | `"opencode"` |
|
|
59
59
|
| Claude Code | `"claude"` |
|
|
60
60
|
| Cursor | `"cursor"` |
|
|
61
61
|
| GitHub Copilot | `"copilot"` |
|
|
62
|
-
|
|
|
62
|
+
| Manual | `"manual"` or username |
|
|
63
63
|
|
|
64
|
-
### project_path
|
|
64
|
+
### project_path Rules
|
|
65
65
|
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
66
|
+
- **Always use absolute paths**: `"/home/user/source/my-project"` (O), `"./my-project"` (X)
|
|
67
|
+
- **Auto-detection**: Use the directory containing `.git` from CWD as the project path
|
|
68
|
+
- **Project isolation**: Different `project_path` values have completely independent handover contexts
|
|
69
69
|
|
|
70
|
-
### MCP
|
|
70
|
+
### MCP Tools (Recommended)
|
|
71
71
|
|
|
72
|
-
HITS MCP
|
|
72
|
+
When the HITS MCP server is configured, use direct tool calls instead of HTTP API:
|
|
73
73
|
|
|
74
74
|
```
|
|
75
|
-
hits_record_work →
|
|
76
|
-
hits_get_handover →
|
|
77
|
-
hits_search_works →
|
|
78
|
-
hits_list_projects →
|
|
79
|
-
hits_get_recent →
|
|
75
|
+
hits_record_work → Record work entry (auto-detects project_path)
|
|
76
|
+
hits_get_handover → Query handover summary
|
|
77
|
+
hits_search_works → Search past work
|
|
78
|
+
hits_list_projects → List projects
|
|
79
|
+
hits_get_recent → Get recent work
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
###
|
|
82
|
+
### When to Record
|
|
83
83
|
|
|
84
|
-
-
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
-
|
|
84
|
+
- At the end of a long work session with the user
|
|
85
|
+
- After completing a major feature implementation
|
|
86
|
+
- After fixing a bug
|
|
87
|
+
- When the user explicitly requests to end the session
|
|
88
|
+
- **On token limit warning** (record immediately!)
|
|
89
89
|
|
|
90
|
-
###
|
|
90
|
+
### Data Store
|
|
91
91
|
|
|
92
|
-
|
|
|
93
|
-
|
|
94
|
-
| `~/.hits/data/work_logs/` |
|
|
95
|
-
| `~/.hits/data/trees/` |
|
|
96
|
-
| `~/.hits/data/workflows/` |
|
|
97
|
-
| `~/.hits/.auth/` |
|
|
98
|
-
| `HITS_DATA_PATH`
|
|
92
|
+
| Location | Description |
|
|
93
|
+
|----------|-------------|
|
|
94
|
+
| `~/.hits/data/work_logs/` | Work logs (JSON) |
|
|
95
|
+
| `~/.hits/data/trees/` | Knowledge trees |
|
|
96
|
+
| `~/.hits/data/workflows/` | Workflows |
|
|
97
|
+
| `~/.hits/.auth/` | Auth data (permissions 600/700) |
|
|
98
|
+
| `HITS_DATA_PATH` env var | Override storage path |
|
|
99
99
|
|
|
100
100
|
## API Endpoints
|
|
101
101
|
|
|
102
|
-
###
|
|
102
|
+
### Authentication
|
|
103
103
|
|
|
104
104
|
| Method | Path | Description |
|
|
105
105
|
|--------|------|-------------|
|
|
106
|
-
| GET | `/api/auth/status` |
|
|
107
|
-
| POST | `/api/auth/register` |
|
|
108
|
-
| POST | `/api/auth/login` |
|
|
109
|
-
| POST | `/api/auth/logout` |
|
|
110
|
-
| POST | `/api/auth/refresh` |
|
|
111
|
-
| GET | `/api/auth/me` |
|
|
112
|
-
| PUT | `/api/auth/password` |
|
|
106
|
+
| GET | `/api/auth/status` | Auth status (initialized, logged in) |
|
|
107
|
+
| POST | `/api/auth/register` | Register user (first user = admin) |
|
|
108
|
+
| POST | `/api/auth/login` | Login (sets HttpOnly cookies) |
|
|
109
|
+
| POST | `/api/auth/logout` | Logout |
|
|
110
|
+
| POST | `/api/auth/refresh` | Refresh access token |
|
|
111
|
+
| GET | `/api/auth/me` | Current user info |
|
|
112
|
+
| PUT | `/api/auth/password` | Change password |
|
|
113
113
|
|
|
114
|
-
###
|
|
114
|
+
### Work Logs
|
|
115
115
|
|
|
116
116
|
| Method | Path | Description |
|
|
117
117
|
|--------|------|-------------|
|
|
118
|
-
| GET | `/api/health` |
|
|
119
|
-
| POST | `/api/work-log` |
|
|
120
|
-
| GET | `/api/work-logs` |
|
|
121
|
-
| GET | `/api/work-logs/search?q
|
|
122
|
-
| GET | `/api/work-log/{id}` |
|
|
123
|
-
| PUT | `/api/work-log/{id}` |
|
|
124
|
-
| DELETE | `/api/work-log/{id}` |
|
|
118
|
+
| GET | `/api/health` | Server health check |
|
|
119
|
+
| POST | `/api/work-log` | Create work log |
|
|
120
|
+
| GET | `/api/work-logs` | List work logs (supports `project_path` filter) |
|
|
121
|
+
| GET | `/api/work-logs/search?q=keyword` | Search work logs (supports `project_path` filter) |
|
|
122
|
+
| GET | `/api/work-log/{id}` | Get single entry |
|
|
123
|
+
| PUT | `/api/work-log/{id}` | Update entry |
|
|
124
|
+
| DELETE | `/api/work-log/{id}` | Delete entry |
|
|
125
125
|
|
|
126
|
-
###
|
|
126
|
+
### Handover
|
|
127
127
|
|
|
128
128
|
| Method | Path | Description |
|
|
129
129
|
|--------|------|-------------|
|
|
130
|
-
| GET | `/api/handover?project_path=...` |
|
|
131
|
-
| GET | `/api/handover/projects` |
|
|
132
|
-
| GET | `/api/handover/project-stats?project_path=...` |
|
|
130
|
+
| GET | `/api/handover?project_path=...` | Project handover summary |
|
|
131
|
+
| GET | `/api/handover/projects` | List projects |
|
|
132
|
+
| GET | `/api/handover/project-stats?project_path=...` | Project stats |
|
|
133
133
|
|
|
134
|
-
###
|
|
134
|
+
### Knowledge Categories
|
|
135
135
|
|
|
136
136
|
| Method | Path | Description |
|
|
137
137
|
|--------|------|-------------|
|
|
138
|
-
| GET | `/api/knowledge/categories` |
|
|
139
|
-
| POST | `/api/knowledge/category` |
|
|
140
|
-
| PUT | `/api/knowledge/category/{name}` |
|
|
141
|
-
| DELETE | `/api/knowledge/category/{name}` |
|
|
142
|
-
| POST | `/api/knowledge/category/{name}/nodes` |
|
|
143
|
-
| PUT | `/api/knowledge/category/{name}/nodes/{idx}` |
|
|
144
|
-
| DELETE | `/api/knowledge/category/{name}/nodes/{idx}` |
|
|
138
|
+
| GET | `/api/knowledge/categories` | List categories |
|
|
139
|
+
| POST | `/api/knowledge/category` | Create category |
|
|
140
|
+
| PUT | `/api/knowledge/category/{name}` | Update category |
|
|
141
|
+
| DELETE | `/api/knowledge/category/{name}` | Delete category |
|
|
142
|
+
| POST | `/api/knowledge/category/{name}/nodes` | Add node |
|
|
143
|
+
| PUT | `/api/knowledge/category/{name}/nodes/{idx}` | Update node |
|
|
144
|
+
| DELETE | `/api/knowledge/category/{name}/nodes/{idx}` | Delete node |
|
|
145
145
|
|
|
146
|
-
###
|
|
146
|
+
### Knowledge Tree (Node-based)
|
|
147
147
|
|
|
148
148
|
| Method | Path | Description |
|
|
149
149
|
|--------|------|-------------|
|
|
150
|
-
| POST | `/api/node` |
|
|
151
|
-
| PUT | `/api/node/{id}` |
|
|
152
|
-
| DELETE | `/api/node/{id}` |
|
|
150
|
+
| POST | `/api/node` | Create knowledge node |
|
|
151
|
+
| PUT | `/api/node/{id}` | Update knowledge node |
|
|
152
|
+
| DELETE | `/api/node/{id}` | Delete knowledge node |
|
|
153
153
|
|
|
154
154
|
## Development Workflow
|
|
155
155
|
|
package/README.md
CHANGED
|
@@ -1,336 +1,373 @@
|
|
|
1
|
-
#
|
|
1
|
+
# hits
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Replicate your predecessor's brain as perfectly as possible, using the least amount of AI.
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
|
|
7
|
+
## What Problem Does This Solve?
|
|
8
8
|
|
|
9
|
-
|
|
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
|
-
|
|
12
|
-
- **맥락 보존**: Why-How-What 계층 구조로 의사결정 과정 저장
|
|
13
|
-
- **실패 경험**: Negative Path로 실패한 접근법도 함께 기록
|
|
14
|
-
- **보안 강화**: Argon2id 해싱, JWT HttpOnly 쿠키, CSP, Rate Limiting
|
|
15
|
-
- **AI 세션 인수인계**: 토큰 한계로 AI 교체 시 프로젝트별 컨텍스트 자동 전달
|
|
16
|
-
- **중앙 집중 저장**: `~/.hits/data/`에 모든 AI 도구의 작업 기록이 통합 저장
|
|
17
|
-
- **프로젝트별 격리**: 프로젝트 경로 기반으로 완전히 독립된 컨텍스트 관리
|
|
11
|
+
**HITS fixes this:**
|
|
18
12
|
|
|
19
|
-
|
|
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
|
-
| 영역 | 기술 |
|
|
22
|
-
|------|------|
|
|
23
|
-
| **백엔드** | Python 3.10+, FastAPI, Pydantic v2 |
|
|
24
|
-
| **프론트엔드** | Svelte 5, Vite, TypeScript |
|
|
25
|
-
| **인증** | Argon2id (비밀번호), JWT HS256 (HttpOnly 쿠키) |
|
|
26
|
-
| **저장소** | 파일 기반 (`~/.hits/data/`), Redis (선택) |
|
|
27
|
-
| **보안** | CSP, CORS, Rate Limiting, Secure Headers |
|
|
28
|
-
|
|
29
|
-
## 설치
|
|
30
|
-
|
|
31
|
-
### 요구사항
|
|
32
|
-
|
|
33
|
-
- Python 3.10 이상
|
|
34
|
-
- Node.js 18+ (프론트엔드 빌드용)
|
|
35
|
-
- Redis (선택사항, 없으면 파일 저장소 사용)
|
|
36
|
-
|
|
37
|
-
### 빠른 시작
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
cd hits
|
|
41
|
-
./run.sh # 자동 설치 + 서버 시작
|
|
42
18
|
```
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
28
|
+
## Quick Start
|
|
51
29
|
|
|
52
|
-
|
|
53
|
-
# Python 환경
|
|
54
|
-
python3 -m venv venv
|
|
55
|
-
source venv/bin/activate
|
|
56
|
-
pip install -r requirements.txt
|
|
57
|
-
|
|
58
|
-
# 프론트엔드 빌드
|
|
59
|
-
cd hits_web
|
|
60
|
-
npm install
|
|
61
|
-
npm run build
|
|
62
|
-
cd ..
|
|
30
|
+
### One Command — That's It
|
|
63
31
|
|
|
64
|
-
|
|
65
|
-
|
|
32
|
+
```bash
|
|
33
|
+
npx hits
|
|
66
34
|
```
|
|
67
35
|
|
|
68
|
-
|
|
36
|
+
That single command will:
|
|
69
37
|
|
|
70
|
-
|
|
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
|
-
|
|
73
|
-
|------|------|
|
|
74
|
-
| **비밀번호 해싱** | Argon2id (memory=64MB, iterations=3, parallelism=1) |
|
|
75
|
-
| **비밀번호 최소 길이** | 8자 |
|
|
76
|
-
| **JWT 토큰** | HttpOnly + Secure + SameSite=Lax 쿠키 |
|
|
77
|
-
| **액세스 토큰** | 15분 만료 |
|
|
78
|
-
| **리프레시 토큰** | 7일 만료, `/api/auth/refresh` 경로에서만 전송 |
|
|
79
|
-
| **첫 사용자** | 자동으로 admin 역할 부여 |
|
|
80
|
-
| **이후 사용자** | admin만 생성 가능 |
|
|
45
|
+
### First Time Setup
|
|
81
46
|
|
|
82
|
-
|
|
47
|
+
On first visit, you'll create an admin account:
|
|
83
48
|
|
|
84
49
|
```
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
###
|
|
65
|
+
### Custom Port
|
|
94
66
|
|
|
95
|
-
|
|
96
|
-
|
|
67
|
+
```bash
|
|
68
|
+
npx hits --port 9000
|
|
69
|
+
# or
|
|
70
|
+
HITS_PORT=9000 npx hits
|
|
71
|
+
```
|
|
97
72
|
|
|
98
|
-
|
|
73
|
+
## Requirements
|
|
99
74
|
|
|
100
|
-
|
|
|
101
|
-
|
|
102
|
-
|
|
|
103
|
-
|
|
|
104
|
-
| `~/.hits/.jwt_secret` | 600 | JWT 서명 키 (소유자만) |
|
|
105
|
-
| `~/.hits/.auth/` | 700 | 인증 디렉토리 (소유자만) |
|
|
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
|
-
|
|
80
|
+
That's it. No database required — HITS uses file-based storage at `~/.hits/data/`.
|
|
108
81
|
|
|
109
|
-
|
|
82
|
+
## What You Get
|
|
83
|
+
|
|
84
|
+
### Web UI
|
|
110
85
|
|
|
111
86
|
```
|
|
112
87
|
┌─────────────┬───────────────────────────────────┐
|
|
113
|
-
│
|
|
88
|
+
│ Sidebar │ Header (tabs + user menu 🌐 lang) │
|
|
114
89
|
│ ├───────────────────────────────────┤
|
|
115
|
-
│ 📂
|
|
116
|
-
│ ────────── │
|
|
90
|
+
│ 📂 Projects│ │
|
|
91
|
+
│ ────────── │ Main content area │
|
|
117
92
|
│ /project-a │ │
|
|
118
|
-
│ /project-b │ 📋
|
|
93
|
+
│ /project-b │ 📋 Knowledge | 📝 Timeline | 🔄 Handover │
|
|
119
94
|
│ /project-c │ │
|
|
120
95
|
│ │ │
|
|
121
96
|
└─────────────┴───────────────────────────────────┘
|
|
122
97
|
```
|
|
123
98
|
|
|
124
|
-
|
|
99
|
+
**Knowledge Tree** — Organize project knowledge as Why-How-What nodes:
|
|
125
100
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
109
|
+
**Timeline** — Chronological work log, grouped by date, filterable by project
|
|
133
110
|
|
|
134
|
-
|
|
111
|
+
**Handover** — Auto-generated summary of a project's context, ready to paste into a new AI session
|
|
135
112
|
|
|
136
|
-
|
|
137
|
-
[OpenCode 세션] [Claude 세션]
|
|
138
|
-
│ │
|
|
139
|
-
작업 수행 세션 시작
|
|
140
|
-
│ │
|
|
141
|
-
작업 기록 ──────────────────────→ 인수인계 조회
|
|
142
|
-
POST /api/work-log GET /api/handover
|
|
143
|
-
project_path: /my-project project_path: /my-project
|
|
144
|
-
│ │
|
|
145
|
-
└──→ ~/.hits/data/ ←──┘ │
|
|
146
|
-
(중앙 집중) 이전 컨텍스트 파악
|
|
147
|
-
│
|
|
148
|
-
작업 이어서 수행
|
|
149
|
-
```
|
|
113
|
+
**i18n** — Korean/English toggle (🌐 button in header)
|
|
150
114
|
|
|
151
|
-
### MCP
|
|
115
|
+
### MCP Tools for AI Assistants
|
|
152
116
|
|
|
153
|
-
|
|
117
|
+
HITS includes an MCP server so your AI can read and write handover data directly:
|
|
118
|
+
|
|
119
|
+
#### Register with OpenCode (`~/.config/opencode/opencode.json`)
|
|
154
120
|
|
|
155
121
|
```json
|
|
156
122
|
{
|
|
157
|
-
"
|
|
158
|
-
"
|
|
159
|
-
|
|
160
|
-
|
|
123
|
+
"mcp": {
|
|
124
|
+
"hits": {
|
|
125
|
+
"type": "local",
|
|
126
|
+
"command": ["python", "-m", "hits_core.mcp.server"],
|
|
127
|
+
"cwd": "/path/to/hits"
|
|
128
|
+
}
|
|
161
129
|
}
|
|
162
130
|
}
|
|
163
131
|
```
|
|
164
132
|
|
|
165
|
-
|
|
166
|
-
- `hits_record_work`: 작업 기록
|
|
167
|
-
- `hits_get_handover`: 인수인계 요약
|
|
168
|
-
- `hits_search_works`: 작업 검색
|
|
169
|
-
- `hits_list_projects`: 프로젝트 목록
|
|
170
|
-
- `hits_get_recent`: 최근 작업
|
|
133
|
+
#### Register with Claude Code
|
|
171
134
|
|
|
172
|
-
|
|
135
|
+
```bash
|
|
136
|
+
claude mcp add hits \
|
|
137
|
+
-e HITS_DATA_PATH="$HOME/.hits/data" \
|
|
138
|
+
-- python -m hits_core.mcp.server
|
|
139
|
+
```
|
|
173
140
|
|
|
174
|
-
|
|
141
|
+
#### 5 MCP Tools
|
|
175
142
|
|
|
176
|
-
|
|
|
177
|
-
|
|
178
|
-
|
|
|
179
|
-
|
|
|
180
|
-
|
|
|
181
|
-
|
|
|
182
|
-
|
|
|
183
|
-
| GET | `/api/auth/me` | 현재 사용자 정보 |
|
|
184
|
-
| PUT | `/api/auth/password` | 비밀번호 변경 |
|
|
143
|
+
| Tool | What It Does |
|
|
144
|
+
|------|-------------|
|
|
145
|
+
| `hits_record_work` | Record a work entry (auto-detects project path from CWD) |
|
|
146
|
+
| `hits_get_handover` | Get handover summary for the current project |
|
|
147
|
+
| `hits_search_works` | Search past work by keyword |
|
|
148
|
+
| `hits_list_projects` | List all projects with recorded work |
|
|
149
|
+
| `hits_get_recent` | Get the most recent work entries |
|
|
185
150
|
|
|
186
|
-
|
|
151
|
+
#### Example AI Workflow
|
|
187
152
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
| POST | `/api/work-log` | 작업 기록 생성 |
|
|
191
|
-
| GET | `/api/work-logs` | 작업 목록 (`project_path` 필터) |
|
|
192
|
-
| GET | `/api/work-logs/search?q=...` | 작업 검색 |
|
|
193
|
-
| GET | `/api/work-log/{id}` | 단건 조회 |
|
|
194
|
-
| PUT | `/api/work-log/{id}` | 수정 |
|
|
195
|
-
| DELETE | `/api/work-log/{id}` | 삭제 |
|
|
153
|
+
```
|
|
154
|
+
User: "Continue working on the auth system"
|
|
196
155
|
|
|
197
|
-
|
|
156
|
+
AI (auto-calls hits_get_handover):
|
|
157
|
+
→ Previous session added Argon2id password hashing
|
|
158
|
+
→ Decisions: Argon2id (not bcrypt), JWT HS256, HttpOnly cookies
|
|
159
|
+
→ Pending: Rate limiting, password change endpoint
|
|
198
160
|
|
|
199
|
-
|
|
200
|
-
|--------|------|-------------|
|
|
201
|
-
| GET | `/api/handover?project_path=...` | 프로젝트별 인수인계 요약 |
|
|
202
|
-
| GET | `/api/handover/projects` | 프로젝트 목록 |
|
|
203
|
-
| GET | `/api/handover/project-stats?project_path=...` | 프로젝트 통계 |
|
|
161
|
+
AI: "I see the auth system uses Argon2id + JWT. Let me add rate limiting..."
|
|
204
162
|
|
|
205
|
-
|
|
163
|
+
(later)
|
|
206
164
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
165
|
+
AI (auto-calls hits_record_work):
|
|
166
|
+
→ Recorded: "Added rate limiting (10 req/min on login endpoint)"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### REST API
|
|
170
|
+
|
|
171
|
+
All features are also accessible via HTTP API:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Health check
|
|
175
|
+
curl http://localhost:8765/api/health
|
|
176
|
+
|
|
177
|
+
# Record work
|
|
178
|
+
curl -X POST http://localhost:8765/api/work-log \
|
|
179
|
+
-H "Content-Type: application/json" \
|
|
180
|
+
-b cookies.txt \
|
|
181
|
+
-d '{
|
|
182
|
+
"performed_by": "claude",
|
|
183
|
+
"request_text": "Added rate limiting to login endpoint",
|
|
184
|
+
"context": "10 req/min per IP, 429 response on limit",
|
|
185
|
+
"project_path": "/home/user/my-project",
|
|
186
|
+
"tags": ["security", "api"]
|
|
187
|
+
}'
|
|
188
|
+
|
|
189
|
+
# Get handover summary
|
|
190
|
+
curl "http://localhost:8765/api/handover?project_path=/home/user/my-project" \
|
|
191
|
+
-b cookies.txt
|
|
192
|
+
|
|
193
|
+
# Search past work
|
|
194
|
+
curl "http://localhost:8765/api/work-logs/search?q=auth" \
|
|
195
|
+
-b cookies.txt
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Security
|
|
216
199
|
|
|
217
|
-
|
|
200
|
+
HITS is built with security as a first-class concern:
|
|
218
201
|
|
|
219
|
-
|
|
|
220
|
-
|
|
221
|
-
|
|
|
222
|
-
|
|
|
223
|
-
|
|
|
224
|
-
|
|
|
202
|
+
| Feature | Implementation |
|
|
203
|
+
|---------|---------------|
|
|
204
|
+
| **Password Hashing** | Argon2id (64MB memory, 3 iterations, parallelism=1) |
|
|
205
|
+
| **JWT Tokens** | HttpOnly + Secure + SameSite=Lax cookies |
|
|
206
|
+
| **Access Token** | 15-minute expiry |
|
|
207
|
+
| **Refresh Token** | 7-day expiry, restricted to `/api/auth/refresh` path |
|
|
208
|
+
| **Brute Force Protection** | 10 login attempts/minute per IP |
|
|
209
|
+
| **Security Headers** | CSP, X-Frame-Options: DENY, HSTS preload, nosniff |
|
|
210
|
+
| **Data Protection** | Auth files stored with `chmod 600` (owner-only) |
|
|
211
|
+
| **First User Policy** | First registered user becomes admin; subsequent users need admin approval |
|
|
225
212
|
|
|
226
|
-
##
|
|
213
|
+
## How It Works Under the Hood
|
|
227
214
|
|
|
228
215
|
```
|
|
229
|
-
|
|
230
|
-
│
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
│
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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
|
-
└──────────────────────────────────────────────────────────┘
|
|
216
|
+
npx hits
|
|
217
|
+
│
|
|
218
|
+
├── 1. findPython() → Detect Python 3.10+ on system
|
|
219
|
+
├── 2. setupPython() → Create venv, install deps
|
|
220
|
+
├── 3. startBackend() → Spawn FastAPI process (port 8765)
|
|
221
|
+
└── 4. startExpress() → Serve frontend + proxy /api → FastAPI
|
|
222
|
+
|
|
223
|
+
Browser Express (8765) FastAPI (8765 internal)
|
|
224
|
+
│ │ │
|
|
225
|
+
├── GET / ───→ static (Svelte SPA) │
|
|
226
|
+
├── GET /some/route ───→ SPA fallback │
|
|
227
|
+
└── GET /api/* ───→ proxy ──────────────→ FastAPI routes
|
|
228
|
+
POST /api/* ───→ proxy ──────────────→ FastAPI routes
|
|
258
229
|
```
|
|
259
230
|
|
|
260
|
-
|
|
231
|
+
All data is stored centrally:
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
~/.hits/
|
|
235
|
+
├── data/ ← All project data
|
|
236
|
+
│ ├── work_logs/ ← AI session work logs (JSON)
|
|
237
|
+
│ ├── trees/ ← Knowledge trees
|
|
238
|
+
│ └── workflows/ ← Workflows
|
|
239
|
+
├── .auth/ ← User accounts (chmod 700)
|
|
240
|
+
│ └── users.json ← User data (chmod 600)
|
|
241
|
+
├── .pepper ← HMAC pepper (chmod 600)
|
|
242
|
+
└── .jwt_secret ← JWT signing key (chmod 600)
|
|
243
|
+
|
|
244
|
+
Override with HITS_DATA_PATH environment variable
|
|
245
|
+
```
|
|
261
246
|
|
|
262
|
-
|
|
247
|
+
## CLI Options
|
|
263
248
|
|
|
264
249
|
```
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
250
|
+
npx hits [options]
|
|
251
|
+
|
|
252
|
+
Options:
|
|
253
|
+
-p, --port <port> Server port (default: 8765)
|
|
254
|
+
-d, --dev Development mode (verbose logging)
|
|
255
|
+
-s, --setup Install dependencies only, don't start
|
|
256
|
+
-h, --help Show help
|
|
257
|
+
|
|
258
|
+
Environment:
|
|
259
|
+
HITS_PORT Server port override
|
|
260
|
+
HITS_PYTHON Path to python executable (default: auto-detect)
|
|
261
|
+
HITS_DATA_PATH Data storage path (default: ~/.hits/data)
|
|
276
262
|
```
|
|
277
263
|
|
|
278
|
-
##
|
|
264
|
+
## API Reference
|
|
265
|
+
|
|
266
|
+
### Authentication
|
|
267
|
+
|
|
268
|
+
| Method | Path | Description |
|
|
269
|
+
|--------|------|-------------|
|
|
270
|
+
| GET | `/api/auth/status` | Check if auth is initialized, current login status |
|
|
271
|
+
| POST | `/api/auth/register` | Register user (first user = admin) |
|
|
272
|
+
| POST | `/api/auth/login` | Login — sets HttpOnly cookies |
|
|
273
|
+
| POST | `/api/auth/logout` | Logout — clears cookies |
|
|
274
|
+
| POST | `/api/auth/refresh` | Refresh access token |
|
|
275
|
+
| GET | `/api/auth/me` | Get current user info |
|
|
276
|
+
| PUT | `/api/auth/password` | Change password |
|
|
277
|
+
|
|
278
|
+
### Work Logs
|
|
279
|
+
|
|
280
|
+
| Method | Path | Description |
|
|
281
|
+
|--------|------|-------------|
|
|
282
|
+
| POST | `/api/work-log` | Create work log |
|
|
283
|
+
| GET | `/api/work-logs` | List logs (filter by `project_path`) |
|
|
284
|
+
| GET | `/api/work-logs/search?q=...` | Search logs by keyword |
|
|
285
|
+
| GET | `/api/work-log/{id}` | Get single entry |
|
|
286
|
+
| PUT | `/api/work-log/{id}` | Update entry |
|
|
287
|
+
| DELETE | `/api/work-log/{id}` | Delete entry |
|
|
288
|
+
|
|
289
|
+
### Handover
|
|
279
290
|
|
|
280
|
-
|
|
291
|
+
| Method | Path | Description |
|
|
292
|
+
|--------|------|-------------|
|
|
293
|
+
| GET | `/api/handover?project_path=...` | Get project handover summary |
|
|
294
|
+
| GET | `/api/handover/projects` | List all projects |
|
|
295
|
+
| GET | `/api/handover/project-stats?project_path=...` | Get project statistics |
|
|
281
296
|
|
|
297
|
+
### Knowledge
|
|
298
|
+
|
|
299
|
+
| Method | Path | Description |
|
|
300
|
+
|--------|------|-------------|
|
|
301
|
+
| GET | `/api/knowledge/categories` | List categories |
|
|
302
|
+
| POST | `/api/knowledge/category` | Create category |
|
|
303
|
+
| PUT | `/api/knowledge/category/{name}` | Update category |
|
|
304
|
+
| DELETE | `/api/knowledge/category/{name}` | Delete category |
|
|
305
|
+
| POST | `/api/knowledge/category/{name}/nodes` | Add node to category |
|
|
306
|
+
| PUT | `/api/knowledge/category/{name}/nodes/{idx}` | Update node |
|
|
307
|
+
| DELETE | `/api/knowledge/category/{name}/nodes/{idx}` | Delete node |
|
|
308
|
+
|
|
309
|
+
## Troubleshooting
|
|
310
|
+
|
|
311
|
+
### "Python 3.10+ not found"
|
|
312
|
+
|
|
313
|
+
Install Python 3.10 or later:
|
|
282
314
|
```bash
|
|
283
|
-
|
|
315
|
+
# Ubuntu/Debian
|
|
316
|
+
sudo apt install python3.12
|
|
317
|
+
|
|
318
|
+
# macOS
|
|
319
|
+
brew install python@3.12
|
|
320
|
+
|
|
321
|
+
# Or set manually:
|
|
322
|
+
export HITS_PYTHON=/usr/bin/python3.12
|
|
284
323
|
```
|
|
285
324
|
|
|
286
|
-
###
|
|
325
|
+
### "Frontend not built"
|
|
287
326
|
|
|
327
|
+
This shouldn't happen with the npm package (frontend is pre-built). If it does:
|
|
288
328
|
```bash
|
|
289
|
-
|
|
329
|
+
npx hits --setup
|
|
290
330
|
```
|
|
291
331
|
|
|
292
|
-
###
|
|
332
|
+
### "ModuleNotFoundError: No module named 'hits_core'"
|
|
293
333
|
|
|
334
|
+
Python dependencies failed to install. Try:
|
|
294
335
|
```bash
|
|
295
|
-
|
|
296
|
-
npm install # 의존성 설치
|
|
297
|
-
npm run dev # Vite 개발 서버 (http://localhost:5173)
|
|
298
|
-
npm run build # 프로덕션 빌드
|
|
336
|
+
npx hits --setup
|
|
299
337
|
```
|
|
300
338
|
|
|
301
|
-
|
|
339
|
+
### Redis Connection Failed
|
|
302
340
|
|
|
303
|
-
|
|
304
|
-
|--------|---------|-------------|
|
|
305
|
-
| `hits_core` | Apache 2.0 | ✅ 자유로움 |
|
|
306
|
-
| `hits_web` | Apache 2.0 | ✅ 자유로움 |
|
|
341
|
+
Not a problem — HITS automatically uses file-based storage. Redis is optional.
|
|
307
342
|
|
|
308
|
-
##
|
|
343
|
+
## Development
|
|
309
344
|
|
|
310
|
-
|
|
345
|
+
If you're working on HITS itself:
|
|
311
346
|
|
|
312
347
|
```bash
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
sudo apt install -y nodejs
|
|
316
|
-
```
|
|
348
|
+
git clone https://github.com/lhjnano/hits.git
|
|
349
|
+
cd hits
|
|
317
350
|
|
|
318
|
-
|
|
351
|
+
# Backend setup
|
|
352
|
+
python3 -m venv venv
|
|
353
|
+
source venv/bin/activate
|
|
354
|
+
pip install -r requirements.txt
|
|
319
355
|
|
|
320
|
-
|
|
356
|
+
# Frontend build
|
|
357
|
+
cd hits_web && npm install && npm run build && cd ..
|
|
321
358
|
|
|
322
|
-
|
|
359
|
+
# Development mode (Vite HMR + FastAPI)
|
|
360
|
+
./run.sh --dev
|
|
323
361
|
|
|
362
|
+
# Run tests
|
|
363
|
+
./run.sh --test
|
|
324
364
|
```
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
HITS_DATA_PATH 환경변수로 경로 변경 가능
|
|
336
|
-
```
|
|
365
|
+
|
|
366
|
+
## License
|
|
367
|
+
|
|
368
|
+
Apache 2.0 — free for commercial use.
|
|
369
|
+
|
|
370
|
+
## Links
|
|
371
|
+
|
|
372
|
+
- **GitHub**: [https://github.com/lhjnano/hits](https://github.com/lhjnano/hits)
|
|
373
|
+
- **Issues**: [https://github.com/lhjnano/hits/issues](https://github.com/lhjnano/hits/issues)
|