memctx 1.0.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/LICENSE +21 -0
- package/README.md +289 -0
- package/dist/bin/claudectx.d.ts +2 -0
- package/dist/bin/claudectx.js +304 -0
- package/dist/bin/claudectx.js.map +1 -0
- package/dist/installer/daemon.d.ts +3 -0
- package/dist/installer/daemon.js +80 -0
- package/dist/installer/daemon.js.map +1 -0
- package/dist/installer/patch-settings.d.ts +2 -0
- package/dist/installer/patch-settings.js +83 -0
- package/dist/installer/patch-settings.js.map +1 -0
- package/dist/src/api/consolidate.d.ts +3 -0
- package/dist/src/api/consolidate.js +29 -0
- package/dist/src/api/consolidate.js.map +1 -0
- package/dist/src/api/context.d.ts +1 -0
- package/dist/src/api/context.js +26 -0
- package/dist/src/api/context.js.map +1 -0
- package/dist/src/api/force-end-session.d.ts +2 -0
- package/dist/src/api/force-end-session.js +60 -0
- package/dist/src/api/force-end-session.js.map +1 -0
- package/dist/src/api/health.d.ts +1 -0
- package/dist/src/api/health.js +27 -0
- package/dist/src/api/health.js.map +1 -0
- package/dist/src/api/hook.d.ts +2 -0
- package/dist/src/api/hook.js +187 -0
- package/dist/src/api/hook.js.map +1 -0
- package/dist/src/api/logs.d.ts +2 -0
- package/dist/src/api/logs.js +66 -0
- package/dist/src/api/logs.js.map +1 -0
- package/dist/src/api/memory.d.ts +2 -0
- package/dist/src/api/memory.js +93 -0
- package/dist/src/api/memory.js.map +1 -0
- package/dist/src/api/metrics.d.ts +3 -0
- package/dist/src/api/metrics.js +58 -0
- package/dist/src/api/metrics.js.map +1 -0
- package/dist/src/api/observations.d.ts +1 -0
- package/dist/src/api/observations.js +31 -0
- package/dist/src/api/observations.js.map +1 -0
- package/dist/src/api/projects.d.ts +1 -0
- package/dist/src/api/projects.js +29 -0
- package/dist/src/api/projects.js.map +1 -0
- package/dist/src/api/resync.d.ts +3 -0
- package/dist/src/api/resync.js +188 -0
- package/dist/src/api/resync.js.map +1 -0
- package/dist/src/api/search.d.ts +1 -0
- package/dist/src/api/search.js +36 -0
- package/dist/src/api/search.js.map +1 -0
- package/dist/src/api/sessions.d.ts +1 -0
- package/dist/src/api/sessions.js +137 -0
- package/dist/src/api/sessions.js.map +1 -0
- package/dist/src/api/settings.d.ts +2 -0
- package/dist/src/api/settings.js +90 -0
- package/dist/src/api/settings.js.map +1 -0
- package/dist/src/api/tags.d.ts +1 -0
- package/dist/src/api/tags.js +89 -0
- package/dist/src/api/tags.js.map +1 -0
- package/dist/src/config.d.ts +17 -0
- package/dist/src/config.js +39 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/db/client.d.ts +3 -0
- package/dist/src/db/client.js +38 -0
- package/dist/src/db/client.js.map +1 -0
- package/dist/src/db/migrate.d.ts +1 -0
- package/dist/src/db/migrate.js +56 -0
- package/dist/src/db/migrate.js.map +1 -0
- package/dist/src/db/migrations/001_add_memory_tables.sql +149 -0
- package/dist/src/db/migrations/002_add_project_id_to_memory.sql +25 -0
- package/dist/src/db/migrations/003_enhance_sessions_schema.sql +27 -0
- package/dist/src/db/migrations/004_add_bookmarks.sql +5 -0
- package/dist/src/db/migrations/005_add_tags.sql +21 -0
- package/dist/src/db/migrations/006_add_notes.sql +2 -0
- package/dist/src/db/migrations/007_add_archived.sql +2 -0
- package/dist/src/db/queries.d.ts +104 -0
- package/dist/src/db/queries.js +432 -0
- package/dist/src/db/queries.js.map +1 -0
- package/dist/src/db/schema.d.ts +1 -0
- package/dist/src/db/schema.js +81 -0
- package/dist/src/db/schema.js.map +1 -0
- package/dist/src/hooks/post-tool-use.d.ts +1 -0
- package/dist/src/hooks/post-tool-use.js +23 -0
- package/dist/src/hooks/post-tool-use.js.map +1 -0
- package/dist/src/hooks/pre-compact.d.ts +1 -0
- package/dist/src/hooks/pre-compact.js +18 -0
- package/dist/src/hooks/pre-compact.js.map +1 -0
- package/dist/src/hooks/session-end.d.ts +1 -0
- package/dist/src/hooks/session-end.js +20 -0
- package/dist/src/hooks/session-end.js.map +1 -0
- package/dist/src/hooks/session-start.d.ts +1 -0
- package/dist/src/hooks/session-start.js +32 -0
- package/dist/src/hooks/session-start.js.map +1 -0
- package/dist/src/hooks/stop.d.ts +1 -0
- package/dist/src/hooks/stop.js +22 -0
- package/dist/src/hooks/stop.js.map +1 -0
- package/dist/src/hooks/user-prompt-submit.d.ts +1 -0
- package/dist/src/hooks/user-prompt-submit.js +18 -0
- package/dist/src/hooks/user-prompt-submit.js.map +1 -0
- package/dist/src/hooks/utils.d.ts +3 -0
- package/dist/src/hooks/utils.js +96 -0
- package/dist/src/hooks/utils.js.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +92 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/services/auto-summarizer.d.ts +5 -0
- package/dist/src/services/auto-summarizer.js +50 -0
- package/dist/src/services/auto-summarizer.js.map +1 -0
- package/dist/src/services/claude-md-updater.d.ts +1 -0
- package/dist/src/services/claude-md-updater.js +43 -0
- package/dist/src/services/claude-md-updater.js.map +1 -0
- package/dist/src/services/context-builder.d.ts +1 -0
- package/dist/src/services/context-builder.js +97 -0
- package/dist/src/services/context-builder.js.map +1 -0
- package/dist/src/services/fuzzy-task-matcher.d.ts +37 -0
- package/dist/src/services/fuzzy-task-matcher.js +96 -0
- package/dist/src/services/fuzzy-task-matcher.js.map +1 -0
- package/dist/src/services/logger.d.ts +20 -0
- package/dist/src/services/logger.js +43 -0
- package/dist/src/services/logger.js.map +1 -0
- package/dist/src/services/memory-consolidator.d.ts +32 -0
- package/dist/src/services/memory-consolidator.js +192 -0
- package/dist/src/services/memory-consolidator.js.map +1 -0
- package/dist/src/services/memory-decay.d.ts +16 -0
- package/dist/src/services/memory-decay.js +79 -0
- package/dist/src/services/memory-decay.js.map +1 -0
- package/dist/src/services/metrics.d.ts +58 -0
- package/dist/src/services/metrics.js +100 -0
- package/dist/src/services/metrics.js.map +1 -0
- package/dist/src/services/project-detector.d.ts +5 -0
- package/dist/src/services/project-detector.js +43 -0
- package/dist/src/services/project-detector.js.map +1 -0
- package/dist/src/services/queue.d.ts +2 -0
- package/dist/src/services/queue.js +16 -0
- package/dist/src/services/queue.js.map +1 -0
- package/dist/src/services/session-timeout.d.ts +1 -0
- package/dist/src/services/session-timeout.js +50 -0
- package/dist/src/services/session-timeout.js.map +1 -0
- package/dist/src/services/summarization-queue.d.ts +43 -0
- package/dist/src/services/summarization-queue.js +150 -0
- package/dist/src/services/summarization-queue.js.map +1 -0
- package/dist/src/services/summarizer.d.ts +2 -0
- package/dist/src/services/summarizer.js +239 -0
- package/dist/src/services/summarizer.js.map +1 -0
- package/dist/src/services/transcript-reader.d.ts +9 -0
- package/dist/src/services/transcript-reader.js +50 -0
- package/dist/src/services/transcript-reader.js.map +1 -0
- package/dist/src/services/watcher.d.ts +1 -0
- package/dist/src/services/watcher.js +34 -0
- package/dist/src/services/watcher.js.map +1 -0
- package/dist/src/ws/broadcast.d.ts +3 -0
- package/dist/src/ws/broadcast.js +24 -0
- package/dist/src/ws/broadcast.js.map +1 -0
- package/package.json +66 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ClaudeContext Contributors
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# ClaudeContext
|
|
2
|
+
|
|
3
|
+
> Autonomous session memory for Claude Code
|
|
4
|
+
|
|
5
|
+
ClaudeContext automatically captures, analyzes, and summarizes your Claude Code sessions, providing intelligent context injection and a beautiful dashboard to track your development history.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🧠 **Automatic Session Tracking** - Captures every Claude Code session automatically
|
|
10
|
+
- 🤖 **AI-Powered Summaries** - Generates structured summaries with what you did, next steps, and gotchas
|
|
11
|
+
- 📊 **Beautiful Dashboard** - Modern UI to browse sessions, search history, and view metrics
|
|
12
|
+
- 🔍 **Full-Text Search** - Search across all your sessions and conversations
|
|
13
|
+
- 📈 **Live Monitoring** - Real-time view of active sessions
|
|
14
|
+
- 🎯 **Smart Context Injection** - Automatically injects relevant session history into new sessions
|
|
15
|
+
- 🏷️ **Tags & Bookmarks** - Organize sessions with tags and bookmarks
|
|
16
|
+
- 📝 **Session Notes** - Add custom notes to any session
|
|
17
|
+
- 🌓 **Dark/Light Theme** - Beautiful themes for any preference
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Install globally with npm
|
|
23
|
+
npm install -g claudectx
|
|
24
|
+
|
|
25
|
+
# Or with pnpm
|
|
26
|
+
pnpm add -g claudectx
|
|
27
|
+
|
|
28
|
+
# Or with yarn
|
|
29
|
+
yarn global add claudectx
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Install and setup hooks
|
|
36
|
+
claudectx install
|
|
37
|
+
|
|
38
|
+
# Start the service
|
|
39
|
+
claudectx start
|
|
40
|
+
|
|
41
|
+
# Open the dashboard
|
|
42
|
+
claudectx open
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
That's it! ClaudeContext will now automatically capture all your Claude Code sessions.
|
|
46
|
+
|
|
47
|
+
## Requirements
|
|
48
|
+
|
|
49
|
+
- **Node.js** 18.0.0 or higher
|
|
50
|
+
- **Claude Code** CLI installed
|
|
51
|
+
- **Build tools** for native dependencies:
|
|
52
|
+
- Linux: `build-essential`, `python3`
|
|
53
|
+
- macOS: Xcode Command Line Tools
|
|
54
|
+
- Windows: Visual Studio Build Tools
|
|
55
|
+
|
|
56
|
+
## Configuration
|
|
57
|
+
|
|
58
|
+
### Settings Dashboard (Recommended)
|
|
59
|
+
|
|
60
|
+
The easiest way to configure ClaudeContext is through the Settings page in the dashboard:
|
|
61
|
+
|
|
62
|
+
1. Open `http://localhost:9999/settings`
|
|
63
|
+
2. Configure your preferences:
|
|
64
|
+
- **API Provider**: Direct (Anthropic) or Proxy (9router, etc.)
|
|
65
|
+
- **API Key**: Your Anthropic or proxy API key
|
|
66
|
+
- **Base URL**: Custom proxy endpoint (if using proxy)
|
|
67
|
+
- **Model**: Choose Claude Opus, Sonnet, Haiku, or AWS default
|
|
68
|
+
- **Disable Summaries**: Toggle to save API costs
|
|
69
|
+
3. Click "Save Settings"
|
|
70
|
+
4. Restart worker: `claudectx restart`
|
|
71
|
+
|
|
72
|
+
Settings are saved to `~/.claudectx/settings.json` and persist across restarts.
|
|
73
|
+
|
|
74
|
+
### Environment Variables (Alternative)
|
|
75
|
+
|
|
76
|
+
You can also configure via environment variables:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Required for AI summaries
|
|
80
|
+
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
81
|
+
|
|
82
|
+
# Optional: Use proxy (like 9router)
|
|
83
|
+
export ANTHROPIC_BASE_URL="https://your-proxy.com/v1"
|
|
84
|
+
|
|
85
|
+
# Optional: Custom port (default: 9999)
|
|
86
|
+
export CLAUDECTX_PORT=8080
|
|
87
|
+
|
|
88
|
+
# Optional: Custom database location
|
|
89
|
+
export CLAUDECTX_DB_PATH="/path/to/db.sqlite"
|
|
90
|
+
|
|
91
|
+
# Optional: Number of sessions to inject (default: 3)
|
|
92
|
+
export CLAUDECTX_CONTEXT_SESSIONS=5
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Configuration Priority:** Settings Dashboard > Environment Variables > Defaults
|
|
96
|
+
|
|
97
|
+
### Configuration Files
|
|
98
|
+
|
|
99
|
+
ClaudeContext stores its data in `~/.claudectx/`:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
~/.claudectx/
|
|
103
|
+
├── db.sqlite # Session database
|
|
104
|
+
├── settings.json # User preferences (API key, model, etc.)
|
|
105
|
+
├── hooks/ # Claude Code hooks
|
|
106
|
+
└── logs/ # Service logs
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## CLI Commands
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Installation & Setup
|
|
113
|
+
claudectx install # Install hooks and start daemon
|
|
114
|
+
claudectx uninstall # Remove hooks and stop daemon
|
|
115
|
+
|
|
116
|
+
# Service Management
|
|
117
|
+
claudectx start # Start the worker daemon
|
|
118
|
+
claudectx stop # Stop the worker daemon
|
|
119
|
+
claudectx restart # Restart the worker daemon
|
|
120
|
+
claudectx status # Show daemon status and health
|
|
121
|
+
|
|
122
|
+
# Usage
|
|
123
|
+
claudectx open # Open dashboard in browser
|
|
124
|
+
claudectx search <query> # Search sessions from terminal
|
|
125
|
+
claudectx export # Export all sessions as markdown
|
|
126
|
+
claudectx config # Show configuration
|
|
127
|
+
|
|
128
|
+
# Options
|
|
129
|
+
--port <number> # Set custom port
|
|
130
|
+
--api-key <key> # Set Anthropic API key
|
|
131
|
+
--sessions <number> # Number of sessions to inject
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Dashboard
|
|
135
|
+
|
|
136
|
+
Access the dashboard at `http://localhost:9999` (or your custom port).
|
|
137
|
+
|
|
138
|
+
### Pages
|
|
139
|
+
|
|
140
|
+
- **Projects** - View all projects and their sessions
|
|
141
|
+
- **Search** - Full-text search across all sessions
|
|
142
|
+
- **Live** - Real-time monitoring of active sessions
|
|
143
|
+
- **Metrics** - System performance and statistics
|
|
144
|
+
- **Logs** - View service logs
|
|
145
|
+
- **Settings** - Configure API provider, model, and preferences
|
|
146
|
+
|
|
147
|
+
### Features
|
|
148
|
+
|
|
149
|
+
- **Session Details** - View full conversation history, summaries, and observations
|
|
150
|
+
- **Tags** - Create and assign tags to organize sessions
|
|
151
|
+
- **Bookmarks** - Mark important sessions for quick access
|
|
152
|
+
- **Notes** - Add custom notes to any session
|
|
153
|
+
- **Archive** - Archive old sessions to declutter
|
|
154
|
+
- **Export** - Export sessions as markdown or screenshots
|
|
155
|
+
- **Keyboard Shortcuts** - Press `?` to see all shortcuts
|
|
156
|
+
|
|
157
|
+
## How It Works
|
|
158
|
+
|
|
159
|
+
1. **Hooks** - ClaudeContext registers hooks in `~/.claude/settings.json` that trigger on session events
|
|
160
|
+
2. **Worker** - A background service captures session data and stores it in SQLite
|
|
161
|
+
3. **AI Summarization** - When a session ends, Claude analyzes it and generates a structured summary
|
|
162
|
+
4. **Context Injection** - On new sessions, relevant history is automatically injected into `CLAUDE.md`
|
|
163
|
+
5. **Dashboard** - A React app provides a beautiful interface to browse and search your history
|
|
164
|
+
|
|
165
|
+
## Architecture
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
┌─────────────────┐
|
|
169
|
+
│ Claude Code │
|
|
170
|
+
│ (CLI/IDE) │
|
|
171
|
+
└────────┬────────┘
|
|
172
|
+
│ hooks
|
|
173
|
+
▼
|
|
174
|
+
┌─────────────────┐
|
|
175
|
+
│ ClaudeContext │
|
|
176
|
+
│ Worker │◄──── WebSocket ────┐
|
|
177
|
+
│ (Node.js) │ │
|
|
178
|
+
└────────┬────────┘ │
|
|
179
|
+
│ │
|
|
180
|
+
▼ │
|
|
181
|
+
┌─────────────────┐ ┌────────┴────────┐
|
|
182
|
+
│ SQLite DB │ │ Dashboard │
|
|
183
|
+
│ (Sessions) │ │ (React) │
|
|
184
|
+
└─────────────────┘ └─────────────────┘
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Troubleshooting
|
|
188
|
+
|
|
189
|
+
### Service won't start
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# Check if port is in use
|
|
193
|
+
lsof -i :9999
|
|
194
|
+
|
|
195
|
+
# Check logs
|
|
196
|
+
tail -f /tmp/claudectx.log
|
|
197
|
+
|
|
198
|
+
# Restart service
|
|
199
|
+
claudectx restart
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Hooks not working
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# Verify hooks are registered
|
|
206
|
+
cat ~/.claude/settings.json | grep claudectx
|
|
207
|
+
|
|
208
|
+
# Reinstall hooks
|
|
209
|
+
claudectx uninstall
|
|
210
|
+
claudectx install
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### SQLite compilation errors
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Rebuild native modules
|
|
217
|
+
npm rebuild better-sqlite3
|
|
218
|
+
|
|
219
|
+
# Or reinstall
|
|
220
|
+
npm uninstall -g claudectx
|
|
221
|
+
npm install -g claudectx
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### AI summaries not working
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# Check API key is set
|
|
228
|
+
echo $ANTHROPIC_API_KEY
|
|
229
|
+
|
|
230
|
+
# Set API key
|
|
231
|
+
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
232
|
+
|
|
233
|
+
# Restart service
|
|
234
|
+
claudectx restart
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Development
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
# Clone repository
|
|
241
|
+
git clone https://github.com/yourusername/claudectx.git
|
|
242
|
+
cd claudectx
|
|
243
|
+
|
|
244
|
+
# Install dependencies
|
|
245
|
+
pnpm install
|
|
246
|
+
|
|
247
|
+
# Build
|
|
248
|
+
pnpm run build
|
|
249
|
+
|
|
250
|
+
# Link locally
|
|
251
|
+
npm link
|
|
252
|
+
|
|
253
|
+
# Test
|
|
254
|
+
claudectx install
|
|
255
|
+
claudectx start
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Contributing
|
|
259
|
+
|
|
260
|
+
Contributions are welcome! Please:
|
|
261
|
+
|
|
262
|
+
1. Fork the repository
|
|
263
|
+
2. Create a feature branch
|
|
264
|
+
3. Make your changes
|
|
265
|
+
4. Add tests if applicable
|
|
266
|
+
5. Submit a pull request
|
|
267
|
+
|
|
268
|
+
## License
|
|
269
|
+
|
|
270
|
+
MIT © 2026
|
|
271
|
+
|
|
272
|
+
## Support
|
|
273
|
+
|
|
274
|
+
- **Issues**: [GitHub Issues](https://github.com/yourusername/claudectx/issues)
|
|
275
|
+
- **Discussions**: [GitHub Discussions](https://github.com/yourusername/claudectx/discussions)
|
|
276
|
+
- **Email**: your.email@example.com
|
|
277
|
+
|
|
278
|
+
## Acknowledgments
|
|
279
|
+
|
|
280
|
+
Built with:
|
|
281
|
+
- [Claude](https://claude.ai) - AI assistant by Anthropic
|
|
282
|
+
- [Express](https://expressjs.com/) - Web framework
|
|
283
|
+
- [SQLite](https://www.sqlite.org/) - Database
|
|
284
|
+
- [React](https://react.dev/) - UI framework
|
|
285
|
+
- [Vite](https://vitejs.dev/) - Build tool
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
Made with ❤️ for the Claude Code community
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
const fs_1 = __importDefault(require("fs"));
|
|
41
|
+
const path_1 = __importDefault(require("path"));
|
|
42
|
+
const child_process_1 = require("child_process");
|
|
43
|
+
const config_1 = require("../src/config");
|
|
44
|
+
const patch_settings_1 = require("../installer/patch-settings");
|
|
45
|
+
const daemon_1 = require("../installer/daemon");
|
|
46
|
+
const args = process.argv.slice(2);
|
|
47
|
+
const command = args[0];
|
|
48
|
+
function printUsage() {
|
|
49
|
+
console.log(`
|
|
50
|
+
Usage: memctx <command>
|
|
51
|
+
|
|
52
|
+
Commands:
|
|
53
|
+
install Install MemCTX — registers hooks, starts daemon
|
|
54
|
+
uninstall Remove hooks and stop daemon
|
|
55
|
+
start Start the worker daemon
|
|
56
|
+
stop Stop the worker daemon
|
|
57
|
+
restart Restart the worker daemon
|
|
58
|
+
status Show daemon status and health check
|
|
59
|
+
open Open dashboard in browser
|
|
60
|
+
export Export all sessions as markdown files
|
|
61
|
+
search Search sessions from terminal
|
|
62
|
+
config Show or edit configuration
|
|
63
|
+
|
|
64
|
+
Options:
|
|
65
|
+
--port Port for worker (default: 9999)
|
|
66
|
+
--api-key Set Anthropic API key
|
|
67
|
+
--sessions Number of sessions to inject at startup (default: 3)
|
|
68
|
+
`);
|
|
69
|
+
}
|
|
70
|
+
async function checkHealth() {
|
|
71
|
+
try {
|
|
72
|
+
const { default: http } = await Promise.resolve().then(() => __importStar(require('http')));
|
|
73
|
+
return new Promise((resolve) => {
|
|
74
|
+
const req = http.get(`http://localhost:${config_1.CONFIG.port}/api/health`, (res) => {
|
|
75
|
+
let data = '';
|
|
76
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
77
|
+
res.on('end', () => {
|
|
78
|
+
try {
|
|
79
|
+
resolve(JSON.parse(data));
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
resolve(null);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
req.on('error', () => resolve(null));
|
|
87
|
+
req.setTimeout(2000, () => { req.destroy(); resolve(null); });
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function run() {
|
|
95
|
+
switch (command) {
|
|
96
|
+
case 'install': {
|
|
97
|
+
console.log('\n🚀 Installing MemCTX...\n');
|
|
98
|
+
// 1. Create directories
|
|
99
|
+
const dirs = [config_1.CONFIG.dataDir, config_1.CONFIG.hooksDir, config_1.CONFIG.logsDir];
|
|
100
|
+
for (const dir of dirs) {
|
|
101
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
102
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
103
|
+
console.log(` Created ${dir}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// 2. Copy compiled hook scripts
|
|
107
|
+
const hooksDistDir = path_1.default.join(__dirname, '..', 'src', 'hooks');
|
|
108
|
+
const distHooksDir = path_1.default.join(__dirname, '..', 'dist', 'src', 'hooks');
|
|
109
|
+
const hookFiles = [
|
|
110
|
+
'session-start', 'session-end', 'post-tool-use',
|
|
111
|
+
'user-prompt-submit', 'stop', 'pre-compact'
|
|
112
|
+
];
|
|
113
|
+
let hooksSource = '';
|
|
114
|
+
if (fs_1.default.existsSync(distHooksDir)) {
|
|
115
|
+
hooksSource = distHooksDir;
|
|
116
|
+
}
|
|
117
|
+
if (hooksSource) {
|
|
118
|
+
for (const hook of hookFiles) {
|
|
119
|
+
const src = path_1.default.join(hooksSource, `${hook}.js`);
|
|
120
|
+
const dest = path_1.default.join(config_1.CONFIG.hooksDir, `${hook}.js`);
|
|
121
|
+
if (fs_1.default.existsSync(src)) {
|
|
122
|
+
fs_1.default.copyFileSync(src, dest);
|
|
123
|
+
console.log(` Installed hook: ${hook}.js`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
console.log(' Note: Build hooks first with: npm run build:worker');
|
|
129
|
+
console.log(' Then re-run install to copy hook scripts.');
|
|
130
|
+
}
|
|
131
|
+
// 3. Patch Claude settings
|
|
132
|
+
try {
|
|
133
|
+
(0, patch_settings_1.patchClaudeSettings)();
|
|
134
|
+
console.log(' Hooks registered in ~/.claude/settings.json');
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
console.warn(' Could not patch settings.json:', err);
|
|
138
|
+
}
|
|
139
|
+
// 4. Start daemon
|
|
140
|
+
const workerPath = path_1.default.join(__dirname, '..', 'dist', 'src', 'index.js');
|
|
141
|
+
if (fs_1.default.existsSync(workerPath)) {
|
|
142
|
+
(0, daemon_1.startDaemon)(workerPath);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
console.log(' Note: Build first with: npm run build');
|
|
146
|
+
console.log(' Then run: claudectx start');
|
|
147
|
+
}
|
|
148
|
+
// 5. Check if API key is set
|
|
149
|
+
if (!config_1.CONFIG.apiKey) {
|
|
150
|
+
console.log('\n ⚠️ ANTHROPIC_API_KEY not set — AI summaries will be disabled.');
|
|
151
|
+
console.log(' Set it with: export ANTHROPIC_API_KEY=sk-ant-...');
|
|
152
|
+
}
|
|
153
|
+
console.log('\n✅ MemCTX installed!');
|
|
154
|
+
console.log(` Dashboard: http://localhost:${config_1.CONFIG.port}`);
|
|
155
|
+
console.log(' Claude Code will now automatically capture and summarize sessions.\n');
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
case 'uninstall': {
|
|
159
|
+
console.log('Uninstalling MemCTX...');
|
|
160
|
+
(0, patch_settings_1.removeClaudeHooks)();
|
|
161
|
+
(0, daemon_1.stopDaemon)();
|
|
162
|
+
console.log('Done. Data preserved at', config_1.CONFIG.dataDir);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
case 'start': {
|
|
166
|
+
const workerPath = path_1.default.join(__dirname, '..', 'dist', 'src', 'index.js');
|
|
167
|
+
if (!fs_1.default.existsSync(workerPath)) {
|
|
168
|
+
console.error('Worker not built. Run: npm run build');
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
(0, daemon_1.startDaemon)(workerPath);
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
case 'stop': {
|
|
175
|
+
(0, daemon_1.stopDaemon)();
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
case 'restart': {
|
|
179
|
+
(0, daemon_1.stopDaemon)();
|
|
180
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
181
|
+
const workerPath = path_1.default.join(__dirname, '..', 'dist', 'src', 'index.js');
|
|
182
|
+
(0, daemon_1.startDaemon)(workerPath);
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
case 'status': {
|
|
186
|
+
const daemonStatus = (0, daemon_1.getDaemonStatus)();
|
|
187
|
+
console.log(`Daemon: ${daemonStatus}`);
|
|
188
|
+
const health = await checkHealth();
|
|
189
|
+
if (health) {
|
|
190
|
+
console.log(`Worker: online (uptime: ${health.uptime}s)`);
|
|
191
|
+
console.log(`DB: ${health.db}`);
|
|
192
|
+
console.log(`API Key: ${health.api_key ? 'configured' : 'not set'}`);
|
|
193
|
+
console.log(`Queue: ${health.queue_size} items pending`);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
console.log('Worker: offline (not responding on port', config_1.CONFIG.port, ')');
|
|
197
|
+
}
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
case 'open': {
|
|
201
|
+
const url = `http://localhost:${config_1.CONFIG.port}`;
|
|
202
|
+
console.log('Opening', url);
|
|
203
|
+
try {
|
|
204
|
+
(0, child_process_1.execSync)(`open "${url}" 2>/dev/null || xdg-open "${url}" 2>/dev/null || start "${url}"`, { stdio: 'ignore' });
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
console.log('Could not auto-open browser. Visit:', url);
|
|
208
|
+
}
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
case 'export': {
|
|
212
|
+
const { getDB } = await Promise.resolve().then(() => __importStar(require('../src/db/client')));
|
|
213
|
+
const db = getDB();
|
|
214
|
+
const sessions = db.prepare('SELECT * FROM sessions WHERE summary_title IS NOT NULL ORDER BY started_at DESC').all();
|
|
215
|
+
const exportDir = path_1.default.join(process.cwd(), 'memctx-export');
|
|
216
|
+
fs_1.default.mkdirSync(exportDir, { recursive: true });
|
|
217
|
+
for (const s of sessions) {
|
|
218
|
+
const date = new Date(s.started_at * 1000).toISOString().split('T')[0];
|
|
219
|
+
const title = (s.summary_title || 'untitled').replace(/[^a-z0-9-]/gi, '-').toLowerCase();
|
|
220
|
+
const fileName = `${date}-${title}.md`;
|
|
221
|
+
const lines = [
|
|
222
|
+
`# ${s.summary_title || 'Untitled Session'}`,
|
|
223
|
+
`Date: ${new Date(s.started_at * 1000).toLocaleString()}`,
|
|
224
|
+
`Status: ${s.status}`,
|
|
225
|
+
'',
|
|
226
|
+
];
|
|
227
|
+
if (s.summary_what_we_did) {
|
|
228
|
+
lines.push('## What We Did');
|
|
229
|
+
try {
|
|
230
|
+
for (const item of JSON.parse(s.summary_what_we_did)) {
|
|
231
|
+
lines.push(`- ${item}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch { }
|
|
235
|
+
lines.push('');
|
|
236
|
+
}
|
|
237
|
+
if (s.summary_next_steps) {
|
|
238
|
+
lines.push('## Next Steps');
|
|
239
|
+
try {
|
|
240
|
+
for (const item of JSON.parse(s.summary_next_steps)) {
|
|
241
|
+
lines.push(`- ${item}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch { }
|
|
245
|
+
lines.push('');
|
|
246
|
+
}
|
|
247
|
+
if (s.summary_gotchas) {
|
|
248
|
+
lines.push('## Gotchas');
|
|
249
|
+
try {
|
|
250
|
+
for (const item of JSON.parse(s.summary_gotchas)) {
|
|
251
|
+
lines.push(`- ${item}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch { }
|
|
255
|
+
lines.push('');
|
|
256
|
+
}
|
|
257
|
+
fs_1.default.writeFileSync(path_1.default.join(exportDir, fileName), lines.join('\n'), 'utf8');
|
|
258
|
+
}
|
|
259
|
+
console.log(`Exported ${sessions.length} sessions to ${exportDir}`);
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
case 'search': {
|
|
263
|
+
const query = args.slice(1).join(' ');
|
|
264
|
+
if (!query) {
|
|
265
|
+
console.error('Usage: memctx search <query>');
|
|
266
|
+
process.exit(1);
|
|
267
|
+
}
|
|
268
|
+
const { queries } = await Promise.resolve().then(() => __importStar(require('../src/db/queries')));
|
|
269
|
+
const { initDB } = await Promise.resolve().then(() => __importStar(require('../src/db/client')));
|
|
270
|
+
initDB();
|
|
271
|
+
const results = queries.searchObservations(query);
|
|
272
|
+
if (results.length === 0) {
|
|
273
|
+
console.log('No results found for:', query);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
console.log(`\nFound ${results.length} results for "${query}":\n`);
|
|
277
|
+
for (const r of results.slice(0, 10)) {
|
|
278
|
+
const date = new Date(r.created_at * 1000).toLocaleDateString();
|
|
279
|
+
console.log(`[${date}] ${r.project_name} — ${r.session_title || 'Unknown session'}`);
|
|
280
|
+
console.log(` ${r.content}`);
|
|
281
|
+
console.log();
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
case 'config': {
|
|
287
|
+
console.log('\nMemCTX Configuration:');
|
|
288
|
+
console.log(` Data dir: ${config_1.CONFIG.dataDir}`);
|
|
289
|
+
console.log(` DB path: ${config_1.CONFIG.dbPath}`);
|
|
290
|
+
console.log(` Port: ${config_1.CONFIG.port}`);
|
|
291
|
+
console.log(` API key: ${config_1.CONFIG.apiKey ? '***set***' : 'NOT SET'}`);
|
|
292
|
+
console.log(` Summaries: ${config_1.CONFIG.disableSummaries ? 'disabled' : 'enabled'}`);
|
|
293
|
+
console.log(` Context sessions: ${config_1.CONFIG.defaultContextSessions}`);
|
|
294
|
+
console.log();
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
default: {
|
|
298
|
+
printUsage();
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
run().catch(console.error);
|
|
304
|
+
//# sourceMappingURL=claudectx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claudectx.js","sourceRoot":"","sources":["../../bin/claudectx.ts"],"names":[],"mappings":"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"}
|