@adverant/nexus-memory-skill 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,6 +10,8 @@
10
10
 
11
11
  ### Give Your AI Perfect Recall — Across Every Session, Every Project, Forever
12
12
 
13
+ [![npm version](https://img.shields.io/npm/v/@adverant/nexus-memory-skill.svg)](https://www.npmjs.com/package/@adverant/nexus-memory-skill)
14
+ [![npm downloads](https://img.shields.io/npm/dm/@adverant/nexus-memory-skill.svg)](https://www.npmjs.com/package/@adverant/nexus-memory-skill)
13
15
  [![MIT License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
14
16
  [![Claude Code](https://img.shields.io/badge/Claude%20Code-Skill-blue.svg)](https://claude.ai/code)
15
17
  [![GraphRAG](https://img.shields.io/badge/Powered%20by-GraphRAG-purple.svg)](https://adverant.ai)
@@ -114,20 +116,44 @@ Unlike simple vector search, **GraphRAG** (Graph-based Retrieval Augmented Gener
114
116
 
115
117
  ## Quick Start
116
118
 
117
- ### One-Command Install
119
+ ### One-Line Install (Recommended)
118
120
 
119
121
  ```bash
120
- git clone https://github.com/adverant/nexus-memory-skill.git ~/.claude/skills/nexus-memory \
121
- && cp ~/.claude/skills/nexus-memory/hooks/*.sh ~/.claude/hooks/ \
122
- && chmod +x ~/.claude/hooks/*.sh \
123
- && echo "✅ Nexus Memory installed!"
122
+ curl -fsSL https://raw.githubusercontent.com/adverant/nexus-memory-skill/main/install.sh | bash
123
+ ```
124
+
125
+ This will:
126
+ 1. Install all skill files and hooks
127
+ 2. Configure automatic memory (auto-recall + auto-store)
128
+ 3. Open a browser to get your free API key
129
+ 4. Verify everything works
130
+
131
+ ### Install via npm
132
+
133
+ ```bash
134
+ npm install -g @adverant/nexus-memory-skill
135
+ ```
136
+
137
+ Then run the installer:
138
+ ```bash
139
+ $(npm root -g)/@adverant/nexus-memory-skill/install.sh
140
+ ```
141
+
142
+ ### Install via Git
143
+
144
+ ```bash
145
+ git clone https://github.com/adverant/nexus-memory-skill.git
146
+ cd nexus-memory-skill
147
+ ./install.sh
124
148
  ```
125
149
 
126
150
  ### Verify Installation
127
151
 
128
152
  ```bash
129
- ls -la ~/.claude/skills/nexus-memory/SKILL.md && echo "Skill installed"
130
- ls -la ~/.claude/hooks/store-memory.sh && echo " Hooks installed"
153
+ ls -la ~/.claude/skills/nexus-memory/SKILL.md && echo "Skill installed"
154
+ ls -la ~/.claude/hooks/auto-recall.sh && echo "Auto-recall hook installed"
155
+ ls -la ~/.claude/hooks/store-memory.sh && echo "Store hook installed"
156
+ ls -la ~/.claude/hooks/episode-summary.sh && echo "Episode summary hook installed"
131
157
  ```
132
158
 
133
159
  ### Manual Installation
@@ -140,28 +166,103 @@ ls -la ~/.claude/hooks/store-memory.sh && echo "✅ Hooks installed"
140
166
  git clone https://github.com/adverant/nexus-memory-skill.git
141
167
  ```
142
168
 
143
- 2. **Copy skill to Claude Code**
169
+ 2. **Create directories**
144
170
  ```bash
145
- mkdir -p ~/.claude/skills
146
- cp -r nexus-memory-skill ~/.claude/skills/nexus-memory
171
+ mkdir -p ~/.claude/skills/nexus-memory ~/.claude/hooks
147
172
  ```
148
173
 
149
- 3. **Install hooks**
174
+ 3. **Copy skill and hooks**
150
175
  ```bash
176
+ cp nexus-memory-skill/SKILL.md ~/.claude/skills/nexus-memory/
151
177
  cp nexus-memory-skill/hooks/*.sh ~/.claude/hooks/
152
178
  chmod +x ~/.claude/hooks/*.sh
153
179
  ```
154
180
 
155
- 4. **Verify**
181
+ 4. **Configure settings.json for automatic memory**
156
182
  ```bash
157
- cat ~/.claude/skills/nexus-memory/SKILL.md | head -10
183
+ cat > ~/.claude/settings.json << 'EOF'
184
+ {
185
+ "hooks": {
186
+ "UserPromptSubmit": [
187
+ {
188
+ "matcher": "",
189
+ "hooks": [
190
+ {"type": "command", "command": "~/.claude/hooks/auto-recall.sh"},
191
+ {"type": "command", "command": "~/.claude/hooks/store-memory.sh"}
192
+ ]
193
+ }
194
+ ],
195
+ "PostToolUse": [
196
+ {
197
+ "matcher": "",
198
+ "hooks": [
199
+ {"type": "command", "command": "~/.claude/hooks/store-memory.sh"},
200
+ {"type": "command", "command": "~/.claude/hooks/episode-summary.sh"}
201
+ ]
202
+ }
203
+ ]
204
+ }
205
+ }
206
+ EOF
207
+ ```
208
+
209
+ 5. **Get your API key**
210
+
211
+ Visit https://dashboard.adverant.ai/dashboard/api-keys and create a free API key.
212
+
213
+ 6. **Configure API key**
214
+ ```bash
215
+ echo "export NEXUS_API_KEY='your-api-key-here'" >> ~/.zshrc
216
+ source ~/.zshrc
158
217
  ```
159
218
 
160
219
  </details>
161
220
 
162
221
  ---
163
222
 
164
- ## Usage
223
+ ## Automatic Memory (Zero-Config)
224
+
225
+ Once installed, Nexus Memory works **automatically** with no manual intervention:
226
+
227
+ ### What Happens Automatically
228
+
229
+ | Event | Action | Hook |
230
+ |-------|--------|------|
231
+ | **You send a prompt** | Relevant memories are recalled and injected as context | `auto-recall.sh` |
232
+ | **You send a prompt** | Your prompt is stored for future recall | `store-memory.sh` |
233
+ | **A tool is used** | Tool inputs/outputs are captured | `store-memory.sh` |
234
+ | **Every 10 tool uses** | Conversation segment is summarized as an "episode" | `episode-summary.sh` |
235
+
236
+ ### Example: Automatic Context
237
+
238
+ When you ask Claude about something you've worked on before:
239
+
240
+ ```
241
+ You: "How did we fix that CORS issue?"
242
+
243
+ [auto-recall.sh retrieves relevant memories]
244
+
245
+ Claude: "Based on my memory, you fixed the CORS issue by adding
246
+ credentials: 'include' to fetch options in src/api/client.ts.
247
+ This was needed because the server requires cookie authentication."
248
+ ```
249
+
250
+ **No manual recall needed** — relevant context is automatically provided.
251
+
252
+ ### Environment Variables
253
+
254
+ | Variable | Default | Description |
255
+ |----------|---------|-------------|
256
+ | `NEXUS_API_KEY` | (required) | Your API key from dashboard.adverant.ai |
257
+ | `NEXUS_RECALL_LIMIT` | `5` | Number of memories to auto-recall per prompt |
258
+ | `NEXUS_EPISODE_THRESHOLD` | `10` | Tool uses before generating episode summary |
259
+ | `NEXUS_VERBOSE` | `0` | Set to `1` to see debug output |
260
+
261
+ ---
262
+
263
+ ## Manual Usage
264
+
265
+ You can also manually store and recall memories:
165
266
 
166
267
  ### Store Memory
167
268
 
package/SKILL.md CHANGED
@@ -8,6 +8,69 @@ allowed-tools: Bash
8
8
 
9
9
  This skill integrates Claude Code with Nexus GraphRAG for persistent memory across ALL sessions and projects.
10
10
 
11
+ ## Automatic Memory Features
12
+
13
+ When properly configured, Nexus Memory provides **fully automatic** memory management:
14
+
15
+ ### Auto-Recall (On Every Prompt)
16
+ - Triggered automatically when you send a prompt
17
+ - Retrieves relevant context from past sessions
18
+ - Enriches Claude's responses with historical knowledge
19
+ - No manual intervention required
20
+
21
+ ### Auto-Store (Continuous Capture)
22
+ - **UserPromptSubmit**: Every prompt you send is captured
23
+ - **PostToolUse**: Every tool execution result is stored
24
+ - Includes project context, timestamps, and session IDs
25
+ - Fire-and-forget async storage (non-blocking)
26
+
27
+ ### Episode Summaries (Periodic)
28
+ - Automatically generated after every 10 tool uses
29
+ - Summarizes conversation segments for long-term memory
30
+ - Captures: topics discussed, decisions made, problems solved
31
+ - Stored with `event_type: "episode"` for easy retrieval
32
+
33
+ ### Configuration
34
+
35
+ The automatic features are controlled by `~/.claude/settings.json`:
36
+
37
+ ```json
38
+ {
39
+ "hooks": {
40
+ "UserPromptSubmit": [
41
+ {
42
+ "matcher": "",
43
+ "hooks": [
44
+ {"type": "command", "command": "~/.claude/hooks/auto-recall.sh"},
45
+ {"type": "command", "command": "~/.claude/hooks/store-memory.sh"}
46
+ ]
47
+ }
48
+ ],
49
+ "PostToolUse": [
50
+ {
51
+ "matcher": "",
52
+ "hooks": [
53
+ {"type": "command", "command": "~/.claude/hooks/store-memory.sh"},
54
+ {"type": "command", "command": "~/.claude/hooks/episode-summary.sh"}
55
+ ]
56
+ }
57
+ ]
58
+ }
59
+ }
60
+ ```
61
+
62
+ ### Environment Variables
63
+
64
+ | Variable | Default | Description |
65
+ |----------|---------|-------------|
66
+ | `NEXUS_API_KEY` | (required) | API key from dashboard.adverant.ai |
67
+ | `NEXUS_API_URL` | `https://api.adverant.ai` | API endpoint |
68
+ | `NEXUS_RECALL_LIMIT` | `5` | Number of memories to auto-recall |
69
+ | `NEXUS_EPISODE_THRESHOLD` | `10` | Tool count before episode summary |
70
+ | `NEXUS_VERBOSE` | `0` | Set to `1` for debug output |
71
+
72
+ ---
73
+
11
74
  ## IMPORTANT: First-Time Setup Check
12
75
 
13
76
  **Before doing ANYTHING else, you MUST check if `NEXUS_API_KEY` is configured.**
@@ -28,6 +91,12 @@ if [ -z "$NEXUS_API_KEY" ]; then echo "NOT_CONFIGURED"; else echo "CONFIGURED";
28
91
  2. **Ask the user to get their API key:**
29
92
  > "Please get your API key from: **https://dashboard.adverant.ai/dashboard/api-keys**
30
93
  >
94
+ > **Important:** When creating your API key in the dashboard:
95
+ > - Log in or create an account (this automatically creates your organization)
96
+ > - Navigate to API Keys section
97
+ > - Click "Create New Key"
98
+ > - Your key will be automatically scoped to your organization for proper data isolation
99
+ >
31
100
  > Once you have it, paste it here and I'll configure it for you."
32
101
 
33
102
  3. **When the user provides the API key, configure it automatically:**
@@ -95,24 +164,20 @@ The FileProcessAgent SmartRouter automatically routes files to the appropriate p
95
164
  curl -X POST "https://api.adverant.ai/fileprocess/api/process/url" \
96
165
  -H "Content-Type: application/json" \
97
166
  -H "Authorization: Bearer $NEXUS_API_KEY" \
98
- -H "X-Company-ID: adverant" \
99
- -H "X-App-ID: claude-code" \
100
167
  -d '{
101
168
  "fileUrl": "YOUR_URL_HERE",
102
- "filename": "filename",
103
- "userId": "user-id"
169
+ "filename": "filename"
104
170
  }'
105
171
  ```
106
172
 
173
+ > **Note:** The `X-Company-ID` header is automatically derived from your API key. Your data is isolated to your account.
174
+
107
175
  ### Upload Files Directly
108
176
 
109
177
  ```bash
110
178
  curl -X POST "https://api.adverant.ai/fileprocess/api/process" \
111
179
  -H "Authorization: Bearer $NEXUS_API_KEY" \
112
- -H "X-Company-ID: adverant" \
113
- -H "X-App-ID: claude-code" \
114
- -F "file=@/path/to/file" \
115
- -F "userId=user-id"
180
+ -F "file=@/path/to/file"
116
181
  ```
117
182
 
118
183
  ---
@@ -125,7 +190,7 @@ You can ingest entire GitHub repositories into Nexus memory. This creates a "dig
125
190
  - Voyage AI embeddings in Qdrant for semantic search
126
191
  - GraphRAG episodic memory for context
127
192
 
128
- ### Usage
193
+ ### Public Repositories
129
194
 
130
195
  Submit a GitHub repository URL to the FileProcessAgent:
131
196
 
@@ -133,15 +198,45 @@ Submit a GitHub repository URL to the FileProcessAgent:
133
198
  curl -X POST "https://api.adverant.ai/fileprocess/api/process/url" \
134
199
  -H "Content-Type: application/json" \
135
200
  -H "Authorization: Bearer $NEXUS_API_KEY" \
136
- -H "X-Company-ID: adverant" \
137
- -H "X-App-ID: claude-code" \
138
201
  -d '{
139
202
  "fileUrl": "https://github.com/owner/repo",
140
- "filename": "repository",
141
- "userId": "user-id"
203
+ "filename": "repository"
204
+ }'
205
+ ```
206
+
207
+ ### Private Repositories
208
+
209
+ For private repositories, you need to provide a GitHub Personal Access Token (PAT) via the `X-GitHub-Token` header:
210
+
211
+ **Step 1: Create a GitHub PAT**
212
+ 1. Go to GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
213
+ 2. Click "Generate new token (classic)"
214
+ 3. Select scopes: `repo` (Full control of private repositories)
215
+ 4. Copy the generated token
216
+
217
+ **Step 2: Set the token as an environment variable (recommended)**
218
+ ```bash
219
+ export GITHUB_PAT='ghp_your_token_here'
220
+ ```
221
+
222
+ **Step 3: Ingest the private repository**
223
+ ```bash
224
+ curl -X POST "https://api.adverant.ai/fileprocess/api/process/url" \
225
+ -H "Content-Type: application/json" \
226
+ -H "Authorization: Bearer $NEXUS_API_KEY" \
227
+ -H "X-GitHub-Token: $GITHUB_PAT" \
228
+ -d '{
229
+ "fileUrl": "https://github.com/owner/private-repo",
230
+ "filename": "repository"
142
231
  }'
143
232
  ```
144
233
 
234
+ **Security Notes:**
235
+ - Never commit your GitHub PAT to version control
236
+ - Use fine-grained tokens with minimal permissions when possible
237
+ - The token is only used for cloning and is not stored permanently
238
+ - Consider using GitHub App tokens for organization repositories
239
+
145
240
  ### Supported URL Formats
146
241
 
147
242
  - `https://github.com/owner/repo`
@@ -182,6 +277,47 @@ echo '{"query": "authentication middleware implementation in owner/repo"}' | ~/.
182
277
  echo '{"query": "how does the login function work in owner/repo"}' | ~/.claude/hooks/recall-memory.sh
183
278
  ```
184
279
 
280
+ ### Check Sync Status
281
+
282
+ After starting a repository ingestion, you can check the progress and ETA:
283
+
284
+ ```bash
285
+ # Get repository ID from the ingestion response, then check status
286
+ REPO_ID="your-repo-id-from-response"
287
+
288
+ curl -s "https://api.adverant.ai/github/api/repositories/$REPO_ID/sync/status" \
289
+ -H "Authorization: Bearer $NEXUS_API_KEY" | jq '.data.currentJob.progress'
290
+ ```
291
+
292
+ **Response Example:**
293
+ ```json
294
+ {
295
+ "phase": "generating_embeddings",
296
+ "percentage": 72,
297
+ "filesProcessed": 450,
298
+ "totalFiles": 625,
299
+ "currentFile": "src/services/auth.ts",
300
+ "message": "Generating embeddings for parsed files",
301
+ "elapsedTime": "3m 45s",
302
+ "eta": "1m 30s",
303
+ "estimatedCompletionAt": "2025-12-29T18:05:00Z"
304
+ }
305
+ ```
306
+
307
+ **Sync Phases:**
308
+ 1. `cloning` - Cloning the repository
309
+ 2. `parsing` - Discovering and parsing source files
310
+ 3. `building_graph` - Building code graph in Neo4j
311
+ 4. `generating_embeddings` - Creating Voyage AI embeddings
312
+ 5. `extracting` - Extracting blame and history data
313
+ 6. `complete` - Sync finished
314
+
315
+ **Quick Status Check (one-liner):**
316
+ ```bash
317
+ curl -s "https://api.adverant.ai/github/api/repositories/$REPO_ID/sync/status" \
318
+ -H "Authorization: Bearer $NEXUS_API_KEY" | jq '{state: .data.state, phase: .data.currentJob.progress.phase, progress: "\(.data.currentJob.progress.percentage)%", eta: .data.currentJob.progress.eta}'
319
+ ```
320
+
185
321
  ---
186
322
 
187
323
  ## Video & YouTube Processing
@@ -192,8 +328,6 @@ Process videos for transcription, frame analysis, and metadata extraction:
192
328
  # YouTube videos
193
329
  curl -X POST "https://api.adverant.ai/fileprocess/api/process/url" \
194
330
  -H "Authorization: Bearer $NEXUS_API_KEY" \
195
- -H "X-Company-ID: adverant" \
196
- -H "X-App-ID: claude-code" \
197
331
  -H "Content-Type: application/json" \
198
332
  -d '{"fileUrl": "https://youtube.com/watch?v=VIDEO_ID", "filename": "video"}'
199
333
  ```
@@ -214,10 +348,7 @@ Process geospatial and LiDAR data:
214
348
  # GeoJSON, KML, Shapefile, LAS/LAZ files
215
349
  curl -X POST "https://api.adverant.ai/fileprocess/api/process" \
216
350
  -H "Authorization: Bearer $NEXUS_API_KEY" \
217
- -H "X-Company-ID: adverant" \
218
- -H "X-App-ID: claude-code" \
219
- -F "file=@/path/to/data.geojson" \
220
- -F "userId=user-id"
351
+ -F "file=@/path/to/data.geojson"
221
352
  ```
222
353
 
223
354
  **Supported Formats:**
@@ -242,10 +373,7 @@ Analyze executables and suspicious files:
242
373
  # Binary analysis with CyberAgent
243
374
  curl -X POST "https://api.adverant.ai/fileprocess/api/process" \
244
375
  -H "Authorization: Bearer $NEXUS_API_KEY" \
245
- -H "X-Company-ID: adverant" \
246
- -H "X-App-ID: claude-code" \
247
- -F "file=@/path/to/binary.exe" \
248
- -F "userId=user-id"
376
+ -F "file=@/path/to/binary.exe"
249
377
  ```
250
378
 
251
379
  **Capabilities:**
@@ -271,10 +399,7 @@ Process PDFs, Office documents, and text files:
271
399
  # Documents via MageAgent
272
400
  curl -X POST "https://api.adverant.ai/fileprocess/api/process" \
273
401
  -H "Authorization: Bearer $NEXUS_API_KEY" \
274
- -H "X-Company-ID: adverant" \
275
- -H "X-App-ID: claude-code" \
276
- -F "file=@/path/to/document.pdf" \
277
- -F "userId=user-id"
402
+ -F "file=@/path/to/document.pdf"
278
403
  ```
279
404
 
280
405
  **Supported Formats:**
@@ -350,17 +475,16 @@ The hooks use the Nexus API Gateway at `https://api.adverant.ai`:
350
475
 
351
476
  ### Authentication
352
477
 
353
- All requests require the following headers:
478
+ All requests require the Authorization header:
354
479
 
355
480
  ```
356
481
  Authorization: Bearer <NEXUS_API_KEY>
357
- X-Company-ID: adverant
358
- X-App-ID: claude-code
359
- X-User-ID: <user>
360
482
  ```
361
483
 
362
484
  The `NEXUS_API_KEY` environment variable provides the Bearer token for authentication.
363
485
 
486
+ **Multi-tenancy:** Your company_id and user_id are automatically derived from your API key. There's no need to manually set `X-Company-ID` or `X-User-ID` headers - the backend determines tenant context from your API key ownership.
487
+
364
488
  ## Automatic Storage
365
489
 
366
490
  The hooks automatically store:
@@ -0,0 +1,161 @@
1
+ #!/bin/bash
2
+ #
3
+ # Nexus Memory - Auto Recall Hook
4
+ # Automatically recalls relevant context from Nexus GraphRAG on every user prompt.
5
+ #
6
+ # This hook is triggered on UserPromptSubmit to enrich Claude's context with
7
+ # relevant memories from past sessions, decisions, fixes, and learnings.
8
+ #
9
+ # Usage (automatic via settings.json):
10
+ # Triggered on every user prompt submission
11
+ #
12
+ # Environment Variables:
13
+ # NEXUS_API_KEY - API key for authentication (REQUIRED)
14
+ # NEXUS_API_URL - API endpoint (default: https://api.adverant.ai)
15
+ # NEXUS_COMPANY_ID - Company identifier (default: adverant)
16
+ # NEXUS_APP_ID - Application identifier (default: claude-code)
17
+ # NEXUS_VERBOSE - Set to 1 for debug output
18
+ # NEXUS_RECALL_LIMIT - Number of memories to recall (default: 5)
19
+ #
20
+ # Output:
21
+ # Returns relevant memories as context for Claude to use
22
+ #
23
+
24
+ set -o pipefail
25
+
26
+ # Configuration with environment variable overrides
27
+ NEXUS_API_KEY="${NEXUS_API_KEY:-}"
28
+ NEXUS_API_URL="${NEXUS_API_URL:-https://api.adverant.ai}"
29
+ COMPANY_ID="${NEXUS_COMPANY_ID:-adverant}"
30
+ APP_ID="${NEXUS_APP_ID:-claude-code}"
31
+ VERBOSE="${NEXUS_VERBOSE:-0}"
32
+ RECALL_LIMIT="${NEXUS_RECALL_LIMIT:-5}"
33
+
34
+ # Logging function
35
+ log() {
36
+ if [[ "$VERBOSE" == "1" ]]; then
37
+ echo "[auto-recall] $1" >&2
38
+ fi
39
+ }
40
+
41
+ log_error() {
42
+ echo "[auto-recall] ERROR: $1" >&2
43
+ }
44
+
45
+ # Skip if no API key (silently - don't block conversation)
46
+ if [[ -z "$NEXUS_API_KEY" ]]; then
47
+ log "NEXUS_API_KEY not set, skipping auto-recall"
48
+ exit 0
49
+ fi
50
+
51
+ # Check dependencies silently
52
+ if ! command -v jq &> /dev/null; then
53
+ log "jq not installed, skipping auto-recall"
54
+ exit 0
55
+ fi
56
+
57
+ if ! command -v curl &> /dev/null; then
58
+ log "curl not installed, skipping auto-recall"
59
+ exit 0
60
+ fi
61
+
62
+ # Read input from stdin (the user's prompt)
63
+ INPUT=$(cat)
64
+
65
+ if [[ -z "$INPUT" ]]; then
66
+ log "No input provided, skipping"
67
+ exit 0
68
+ fi
69
+
70
+ log "Received prompt: ${INPUT:0:100}..."
71
+
72
+ # Extract the user's prompt/query
73
+ QUERY=$(echo "$INPUT" | jq -r '.prompt // .content // .tool_input.command // empty' 2>/dev/null)
74
+
75
+ # Skip if no query content
76
+ if [[ -z "$QUERY" ]] || [[ "$QUERY" == "null" ]]; then
77
+ log "No query content, skipping"
78
+ exit 0
79
+ fi
80
+
81
+ # Truncate very long queries for recall
82
+ if [[ ${#QUERY} -gt 500 ]]; then
83
+ QUERY="${QUERY:0:500}"
84
+ log "Query truncated to 500 characters for recall"
85
+ fi
86
+
87
+ # Get current project for context
88
+ PROJECT_NAME=$(basename "$(pwd)")
89
+ PROJECT_DIR=$(pwd)
90
+
91
+ log "Query: ${QUERY:0:100}..."
92
+ log "Project: $PROJECT_NAME"
93
+ log "Limit: $RECALL_LIMIT"
94
+
95
+ # Build the recall payload with project context
96
+ PAYLOAD=$(jq -n \
97
+ --arg query "$QUERY" \
98
+ --argjson limit "$RECALL_LIMIT" \
99
+ --arg project "$PROJECT_NAME" \
100
+ '{
101
+ query: $query,
102
+ limit: $limit,
103
+ filters: {
104
+ project: $project
105
+ }
106
+ }')
107
+
108
+ log "Recalling from $NEXUS_API_URL/api/memory/recall"
109
+
110
+ # Search GraphRAG for relevant memories via API Gateway
111
+ # Use short timeout to not block conversation
112
+ RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "$NEXUS_API_URL/api/memory/recall" \
113
+ -H "Content-Type: application/json" \
114
+ -H "Authorization: Bearer $NEXUS_API_KEY" \
115
+ -H "X-Company-ID: $COMPANY_ID" \
116
+ -H "X-App-ID: $APP_ID" \
117
+ -H "X-User-ID: ${USER:-unknown}" \
118
+ -d "$PAYLOAD" \
119
+ --max-time 5 2>&1)
120
+
121
+ # Parse response
122
+ HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
123
+ BODY=$(echo "$RESPONSE" | sed '$d')
124
+
125
+ log "Response code: $HTTP_CODE"
126
+
127
+ # Check for errors (silently fail - don't block conversation)
128
+ if [[ "$HTTP_CODE" != "200" ]]; then
129
+ log "Failed to recall memories (HTTP $HTTP_CODE), continuing without context"
130
+ exit 0
131
+ fi
132
+
133
+ # Validate JSON response
134
+ if ! echo "$BODY" | jq . &>/dev/null; then
135
+ log "Invalid JSON response, continuing without context"
136
+ exit 0
137
+ fi
138
+
139
+ # Extract memories and format as context
140
+ MEMORIES=$(echo "$BODY" | jq -r '.memories // []' 2>/dev/null)
141
+ MEMORY_COUNT=$(echo "$MEMORIES" | jq 'length' 2>/dev/null || echo "0")
142
+
143
+ log "Found $MEMORY_COUNT relevant memories"
144
+
145
+ # If we have memories, output them as context for Claude
146
+ if [[ "$MEMORY_COUNT" -gt 0 ]] && [[ "$MEMORY_COUNT" != "null" ]]; then
147
+ # Format memories as readable context
148
+ echo ""
149
+ echo "<nexus-memory-context>"
150
+ echo "The following relevant context was automatically recalled from Nexus Memory:"
151
+ echo ""
152
+
153
+ echo "$MEMORIES" | jq -r '.[] |
154
+ "- [\(.metadata.eventType // "context")] \(.content | if length > 300 then .[0:300] + "..." else . end)"
155
+ ' 2>/dev/null | head -n 10
156
+
157
+ echo ""
158
+ echo "</nexus-memory-context>"
159
+ fi
160
+
161
+ exit 0
@@ -0,0 +1,223 @@
1
+ #!/bin/bash
2
+ #
3
+ # Nexus Memory - Episode Summary Hook
4
+ # Generates periodic summaries of conversation segments as "episodes" for long-term memory.
5
+ #
6
+ # This hook can be triggered:
7
+ # - At session end (Stop hook)
8
+ # - After N tool uses (counter-based)
9
+ # - Manually to summarize current conversation
10
+ #
11
+ # Episodes capture:
12
+ # - Topics discussed
13
+ # - Decisions made
14
+ # - Problems solved
15
+ # - Key learnings
16
+ #
17
+ # Usage:
18
+ # echo '{"conversation_summary": "...", "tool_count": 5}' | episode-summary.sh
19
+ #
20
+ # Environment Variables:
21
+ # NEXUS_API_KEY - API key for authentication (REQUIRED)
22
+ # NEXUS_API_URL - API endpoint (default: https://api.adverant.ai)
23
+ # NEXUS_COMPANY_ID - Company identifier (default: adverant)
24
+ # NEXUS_APP_ID - Application identifier (default: claude-code)
25
+ # NEXUS_VERBOSE - Set to 1 for debug output
26
+ # NEXUS_EPISODE_THRESHOLD - Tool count threshold for episode generation (default: 10)
27
+ #
28
+
29
+ set -o pipefail
30
+
31
+ # Configuration with environment variable overrides
32
+ NEXUS_API_KEY="${NEXUS_API_KEY:-}"
33
+ NEXUS_API_URL="${NEXUS_API_URL:-https://api.adverant.ai}"
34
+ COMPANY_ID="${NEXUS_COMPANY_ID:-adverant}"
35
+ APP_ID="${NEXUS_APP_ID:-claude-code}"
36
+ VERBOSE="${NEXUS_VERBOSE:-0}"
37
+ EPISODE_THRESHOLD="${NEXUS_EPISODE_THRESHOLD:-10}"
38
+
39
+ # State file for tracking tool count
40
+ STATE_DIR="${HOME}/.claude/session-env"
41
+ COUNTER_FILE="${STATE_DIR}/episode_counter"
42
+
43
+ # Logging function
44
+ log() {
45
+ if [[ "$VERBOSE" == "1" ]]; then
46
+ echo "[episode-summary] $1" >&2
47
+ fi
48
+ }
49
+
50
+ log_error() {
51
+ echo "[episode-summary] ERROR: $1" >&2
52
+ }
53
+
54
+ # Skip if no API key
55
+ if [[ -z "$NEXUS_API_KEY" ]]; then
56
+ log "NEXUS_API_KEY not set, skipping episode summary"
57
+ exit 0
58
+ fi
59
+
60
+ # Check dependencies
61
+ if ! command -v jq &> /dev/null; then
62
+ log "jq not installed, skipping episode summary"
63
+ exit 0
64
+ fi
65
+
66
+ if ! command -v curl &> /dev/null; then
67
+ log "curl not installed, skipping episode summary"
68
+ exit 0
69
+ fi
70
+
71
+ # Ensure state directory exists
72
+ mkdir -p "$STATE_DIR"
73
+
74
+ # Read input from stdin
75
+ INPUT=$(cat)
76
+
77
+ if [[ -z "$INPUT" ]]; then
78
+ log "No input provided"
79
+ exit 0
80
+ fi
81
+
82
+ log "Received input: ${INPUT:0:100}..."
83
+
84
+ # Extract fields from input
85
+ FORCE_SUMMARY=$(echo "$INPUT" | jq -r '.force // false' 2>/dev/null)
86
+ SESSION_END=$(echo "$INPUT" | jq -r '.session_end // false' 2>/dev/null)
87
+ CONTENT=$(echo "$INPUT" | jq -r '.content // .conversation_summary // .prompt // empty' 2>/dev/null)
88
+
89
+ # Get current counter
90
+ if [[ -f "$COUNTER_FILE" ]]; then
91
+ CURRENT_COUNT=$(cat "$COUNTER_FILE" 2>/dev/null || echo "0")
92
+ else
93
+ CURRENT_COUNT=0
94
+ fi
95
+
96
+ # Increment counter
97
+ NEW_COUNT=$((CURRENT_COUNT + 1))
98
+ echo "$NEW_COUNT" > "$COUNTER_FILE"
99
+
100
+ log "Tool count: $NEW_COUNT (threshold: $EPISODE_THRESHOLD)"
101
+
102
+ # Determine if we should generate an episode summary
103
+ SHOULD_SUMMARIZE=false
104
+
105
+ if [[ "$FORCE_SUMMARY" == "true" ]]; then
106
+ SHOULD_SUMMARIZE=true
107
+ log "Forced summary requested"
108
+ elif [[ "$SESSION_END" == "true" ]]; then
109
+ SHOULD_SUMMARIZE=true
110
+ log "Session end summary"
111
+ elif [[ "$NEW_COUNT" -ge "$EPISODE_THRESHOLD" ]]; then
112
+ SHOULD_SUMMARIZE=true
113
+ log "Threshold reached, generating episode"
114
+ # Reset counter
115
+ echo "0" > "$COUNTER_FILE"
116
+ fi
117
+
118
+ # Exit if we shouldn't summarize
119
+ if [[ "$SHOULD_SUMMARIZE" != "true" ]]; then
120
+ log "Not generating episode yet (count: $NEW_COUNT/$EPISODE_THRESHOLD)"
121
+ exit 0
122
+ fi
123
+
124
+ # Get project context
125
+ PROJECT_NAME=$(basename "$(pwd)")
126
+ PROJECT_DIR=$(pwd)
127
+ TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
128
+ SESSION_ID=$(date +%Y%m%d-%H%M%S)
129
+
130
+ # Skip if no content to summarize
131
+ if [[ -z "$CONTENT" ]] || [[ "$CONTENT" == "null" ]]; then
132
+ # Try to get recent content from session
133
+ CONTENT="Conversation segment in $PROJECT_NAME project"
134
+ fi
135
+
136
+ # Truncate very long content
137
+ if [[ ${#CONTENT} -gt 5000 ]]; then
138
+ CONTENT="${CONTENT:0:5000}... [truncated]"
139
+ fi
140
+
141
+ # Generate episode summary
142
+ # For now, we create a structured episode from the content
143
+ # Future enhancement: Use LLM to generate smart summaries
144
+ EPISODE_CONTENT=$(cat <<EOF
145
+ [Episode Summary - $PROJECT_NAME]
146
+ Timestamp: $TIMESTAMP
147
+ Project: $PROJECT_NAME
148
+ Directory: $PROJECT_DIR
149
+
150
+ Session Activity:
151
+ $CONTENT
152
+
153
+ ---
154
+ This episode was automatically generated after $NEW_COUNT tool interactions.
155
+ EOF
156
+ )
157
+
158
+ log "Generating episode summary for $PROJECT_NAME"
159
+
160
+ # Build the payload
161
+ PAYLOAD=$(jq -n \
162
+ --arg content "$EPISODE_CONTENT" \
163
+ --arg session "$SESSION_ID" \
164
+ --arg project "$PROJECT_NAME" \
165
+ --arg projectDir "$PROJECT_DIR" \
166
+ --arg timestamp "$TIMESTAMP" \
167
+ --argjson toolCount "$NEW_COUNT" \
168
+ '{
169
+ content: $content,
170
+ tags: ["claude-code", "type:episode", "project:\($project)", "session:\($session)"],
171
+ metadata: {
172
+ sessionId: $session,
173
+ eventType: "episode",
174
+ projectDir: $projectDir,
175
+ projectName: $project,
176
+ timestamp: $timestamp,
177
+ toolCount: $toolCount,
178
+ isEpisodeSummary: true
179
+ }
180
+ }')
181
+
182
+ log "Storing episode to $NEXUS_API_URL/api/memory/store"
183
+
184
+ # Store to GraphRAG via API Gateway
185
+ if [[ "$VERBOSE" == "1" ]]; then
186
+ # Sync mode with output for debugging
187
+ RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "$NEXUS_API_URL/api/memory/store" \
188
+ -H "Content-Type: application/json" \
189
+ -H "Authorization: Bearer $NEXUS_API_KEY" \
190
+ -H "X-Company-ID: $COMPANY_ID" \
191
+ -H "X-App-ID: $APP_ID" \
192
+ -H "X-User-ID: ${USER:-unknown}" \
193
+ -d "$PAYLOAD" \
194
+ --max-time 10 2>&1)
195
+
196
+ HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
197
+ BODY=$(echo "$RESPONSE" | sed '$d')
198
+
199
+ log "Response code: $HTTP_CODE"
200
+ log "Response body: $BODY"
201
+
202
+ if [[ "$HTTP_CODE" != "200" ]] && [[ "$HTTP_CODE" != "201" ]]; then
203
+ log_error "Failed to store episode (HTTP $HTTP_CODE)"
204
+ else
205
+ log "Episode stored successfully"
206
+ fi
207
+ else
208
+ # Async mode (fire-and-forget) for normal operation
209
+ (curl -s -X POST "$NEXUS_API_URL/api/memory/store" \
210
+ -H "Content-Type: application/json" \
211
+ -H "Authorization: Bearer $NEXUS_API_KEY" \
212
+ -H "X-Company-ID: $COMPANY_ID" \
213
+ -H "X-App-ID: $APP_ID" \
214
+ -H "X-User-ID: ${USER:-unknown}" \
215
+ -d "$PAYLOAD" \
216
+ --max-time 5 &>/dev/null) &
217
+ fi
218
+
219
+ # Reset counter after successful summary
220
+ echo "0" > "$COUNTER_FILE"
221
+
222
+ log "Episode summary complete"
223
+ exit 0
package/install.sh ADDED
@@ -0,0 +1,355 @@
1
+ #!/bin/bash
2
+ #
3
+ # Nexus Memory - Installation Script
4
+ # Installs the Nexus Memory skill for Claude Code with automatic memory features.
5
+ #
6
+ # Usage:
7
+ # curl -fsSL https://raw.githubusercontent.com/adverant/nexus-memory-skill/main/install.sh | bash
8
+ # OR
9
+ # ./install.sh
10
+ #
11
+ # What this script does:
12
+ # 1. Creates necessary directories (~/.claude/skills, ~/.claude/hooks)
13
+ # 2. Copies skill and hook files
14
+ # 3. Configures settings.json for automatic memory
15
+ # 4. Helps you set up your API key (opens browser if needed)
16
+ # 5. Verifies the installation
17
+ #
18
+
19
+ set -e
20
+
21
+ # Colors for output
22
+ RED='\033[0;31m'
23
+ GREEN='\033[0;32m'
24
+ YELLOW='\033[1;33m'
25
+ BLUE='\033[0;34m'
26
+ NC='\033[0m' # No Color
27
+
28
+ # Logging functions
29
+ log_info() {
30
+ echo -e "${BLUE}[INFO]${NC} $1"
31
+ }
32
+
33
+ log_success() {
34
+ echo -e "${GREEN}[SUCCESS]${NC} $1"
35
+ }
36
+
37
+ log_warn() {
38
+ echo -e "${YELLOW}[WARN]${NC} $1"
39
+ }
40
+
41
+ log_error() {
42
+ echo -e "${RED}[ERROR]${NC} $1"
43
+ }
44
+
45
+ # Check for required commands
46
+ check_dependencies() {
47
+ local missing=()
48
+
49
+ if ! command -v curl &> /dev/null; then
50
+ missing+=("curl")
51
+ fi
52
+
53
+ if ! command -v jq &> /dev/null; then
54
+ missing+=("jq")
55
+ fi
56
+
57
+ if [ ${#missing[@]} -ne 0 ]; then
58
+ log_error "Missing required dependencies: ${missing[*]}"
59
+ echo ""
60
+ echo "Please install them first:"
61
+ if [[ "$OSTYPE" == "darwin"* ]]; then
62
+ echo " brew install ${missing[*]}"
63
+ else
64
+ echo " sudo apt-get install ${missing[*]}"
65
+ fi
66
+ exit 1
67
+ fi
68
+ }
69
+
70
+ # Get the script directory (works for both local and remote install)
71
+ get_source_dir() {
72
+ if [ -d "$(dirname "$0")/hooks" ]; then
73
+ echo "$(cd "$(dirname "$0")" && pwd)"
74
+ else
75
+ # Remote install - download to temp directory
76
+ local temp_dir=$(mktemp -d)
77
+ log_info "Downloading Nexus Memory skill..."
78
+ git clone --depth 1 https://github.com/adverant/nexus-memory-skill.git "$temp_dir" 2>/dev/null || {
79
+ log_error "Failed to download. Please check your internet connection."
80
+ exit 1
81
+ }
82
+ echo "$temp_dir"
83
+ fi
84
+ }
85
+
86
+ # Create required directories
87
+ create_directories() {
88
+ log_info "Creating directories..."
89
+ mkdir -p ~/.claude/skills/nexus-memory
90
+ mkdir -p ~/.claude/hooks
91
+ mkdir -p ~/.claude/session-env
92
+ }
93
+
94
+ # Copy skill and hooks
95
+ install_files() {
96
+ local source_dir="$1"
97
+
98
+ log_info "Installing skill file..."
99
+ cp "$source_dir/SKILL.md" ~/.claude/skills/nexus-memory/SKILL.md
100
+
101
+ log_info "Installing hooks..."
102
+ cp "$source_dir/hooks/store-memory.sh" ~/.claude/hooks/
103
+ cp "$source_dir/hooks/recall-memory.sh" ~/.claude/hooks/
104
+ cp "$source_dir/hooks/auto-recall.sh" ~/.claude/hooks/
105
+ cp "$source_dir/hooks/episode-summary.sh" ~/.claude/hooks/
106
+
107
+ # Make hooks executable
108
+ chmod +x ~/.claude/hooks/store-memory.sh
109
+ chmod +x ~/.claude/hooks/recall-memory.sh
110
+ chmod +x ~/.claude/hooks/auto-recall.sh
111
+ chmod +x ~/.claude/hooks/episode-summary.sh
112
+
113
+ # Copy upload-document.sh if it exists
114
+ if [ -f "$source_dir/hooks/upload-document.sh" ]; then
115
+ cp "$source_dir/hooks/upload-document.sh" ~/.claude/hooks/
116
+ chmod +x ~/.claude/hooks/upload-document.sh
117
+ fi
118
+
119
+ log_success "Files installed successfully"
120
+ }
121
+
122
+ # Configure settings.json
123
+ configure_settings() {
124
+ log_info "Configuring Claude Code settings..."
125
+
126
+ local settings_file=~/.claude/settings.json
127
+
128
+ # Create settings.json with automatic memory hooks
129
+ cat > "$settings_file" << 'EOF'
130
+ {
131
+ "hooks": {
132
+ "UserPromptSubmit": [
133
+ {
134
+ "matcher": "",
135
+ "hooks": [
136
+ {
137
+ "type": "command",
138
+ "command": "~/.claude/hooks/auto-recall.sh"
139
+ },
140
+ {
141
+ "type": "command",
142
+ "command": "~/.claude/hooks/store-memory.sh"
143
+ }
144
+ ]
145
+ }
146
+ ],
147
+ "PostToolUse": [
148
+ {
149
+ "matcher": "",
150
+ "hooks": [
151
+ {
152
+ "type": "command",
153
+ "command": "~/.claude/hooks/store-memory.sh"
154
+ },
155
+ {
156
+ "type": "command",
157
+ "command": "~/.claude/hooks/episode-summary.sh"
158
+ }
159
+ ]
160
+ }
161
+ ]
162
+ }
163
+ }
164
+ EOF
165
+
166
+ log_success "Settings configured for automatic memory"
167
+ }
168
+
169
+ # Open browser to get API key
170
+ open_browser() {
171
+ local url="$1"
172
+
173
+ if [[ "$OSTYPE" == "darwin"* ]]; then
174
+ open "$url" 2>/dev/null || true
175
+ elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
176
+ xdg-open "$url" 2>/dev/null || true
177
+ elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]]; then
178
+ start "$url" 2>/dev/null || true
179
+ fi
180
+ }
181
+
182
+ # Setup API key
183
+ setup_api_key() {
184
+ echo ""
185
+ log_info "Checking API key configuration..."
186
+
187
+ if [ -n "$NEXUS_API_KEY" ]; then
188
+ log_success "NEXUS_API_KEY is already configured"
189
+ return 0
190
+ fi
191
+
192
+ echo ""
193
+ echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
194
+ echo -e "${YELLOW} API Key Setup Required ${NC}"
195
+ echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
196
+ echo ""
197
+ echo "Nexus Memory requires an API key to store and recall memories."
198
+ echo ""
199
+ echo "Steps to get your API key:"
200
+ echo " 1. A browser window will open to the Nexus Dashboard"
201
+ echo " 2. Log in or create a free account"
202
+ echo " 3. Navigate to 'API Keys' section"
203
+ echo " 4. Click 'Create New Key'"
204
+ echo " 5. Copy your new API key"
205
+ echo ""
206
+
207
+ read -p "Press Enter to open the dashboard in your browser..."
208
+
209
+ open_browser "https://dashboard.adverant.ai/dashboard/api-keys"
210
+
211
+ echo ""
212
+ echo "Paste your API key below (it will be hidden):"
213
+ read -s api_key
214
+ echo ""
215
+
216
+ if [ -z "$api_key" ]; then
217
+ log_warn "No API key provided. You can set it later with:"
218
+ echo " export NEXUS_API_KEY='your-api-key-here'"
219
+ return 1
220
+ fi
221
+
222
+ # Detect shell profile
223
+ local shell_profile=""
224
+ if [ -f ~/.zshrc ]; then
225
+ shell_profile=~/.zshrc
226
+ elif [ -f ~/.bashrc ]; then
227
+ shell_profile=~/.bashrc
228
+ elif [ -f ~/.bash_profile ]; then
229
+ shell_profile=~/.bash_profile
230
+ fi
231
+
232
+ if [ -n "$shell_profile" ]; then
233
+ # Remove any existing NEXUS_API_KEY line
234
+ grep -v "^export NEXUS_API_KEY=" "$shell_profile" > "${shell_profile}.tmp" 2>/dev/null && mv "${shell_profile}.tmp" "$shell_profile"
235
+
236
+ # Add the new key
237
+ echo "export NEXUS_API_KEY='$api_key'" >> "$shell_profile"
238
+ log_success "API key added to $shell_profile"
239
+ fi
240
+
241
+ # Export for current session
242
+ export NEXUS_API_KEY="$api_key"
243
+
244
+ # Verify the key works
245
+ log_info "Verifying API key..."
246
+ local response=$(curl -s -o /dev/null -w "%{http_code}" -X POST "https://api.adverant.ai/api/memory/recall" \
247
+ -H "Content-Type: application/json" \
248
+ -H "Authorization: Bearer $api_key" \
249
+ -d '{"query": "test", "limit": 1}' \
250
+ --max-time 10 2>/dev/null)
251
+
252
+ if [ "$response" = "200" ] || [ "$response" = "201" ]; then
253
+ log_success "API key verified successfully!"
254
+ elif [ "$response" = "401" ]; then
255
+ log_warn "API key verification failed (401). Please check your key is correct."
256
+ else
257
+ log_warn "Could not verify API key (HTTP $response). Please check your internet connection."
258
+ fi
259
+
260
+ echo ""
261
+ log_info "To apply the API key in your current terminal, run:"
262
+ echo " source $shell_profile"
263
+ }
264
+
265
+ # Verify installation
266
+ verify_installation() {
267
+ echo ""
268
+ log_info "Verifying installation..."
269
+
270
+ local errors=0
271
+
272
+ if [ -f ~/.claude/skills/nexus-memory/SKILL.md ]; then
273
+ log_success "Skill file: OK"
274
+ else
275
+ log_error "Skill file: MISSING"
276
+ ((errors++))
277
+ fi
278
+
279
+ for hook in store-memory.sh recall-memory.sh auto-recall.sh episode-summary.sh; do
280
+ if [ -x ~/.claude/hooks/$hook ]; then
281
+ log_success "Hook $hook: OK"
282
+ else
283
+ log_error "Hook $hook: MISSING or not executable"
284
+ ((errors++))
285
+ fi
286
+ done
287
+
288
+ if [ -f ~/.claude/settings.json ]; then
289
+ log_success "Settings file: OK"
290
+ else
291
+ log_error "Settings file: MISSING"
292
+ ((errors++))
293
+ fi
294
+
295
+ if [ $errors -gt 0 ]; then
296
+ log_error "Installation completed with $errors error(s)"
297
+ return 1
298
+ fi
299
+
300
+ return 0
301
+ }
302
+
303
+ # Print success message
304
+ print_success() {
305
+ echo ""
306
+ echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
307
+ echo -e "${GREEN} Nexus Memory Installation Complete! ${NC}"
308
+ echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
309
+ echo ""
310
+ echo "Automatic Memory Features Enabled:"
311
+ echo " - Auto-recall: Relevant memories fetched on every prompt"
312
+ echo " - Auto-store: Every prompt and tool use captured"
313
+ echo " - Episode summaries: Generated every 10 tool uses"
314
+ echo ""
315
+ echo "Manual Commands:"
316
+ echo " Store: echo '{\"content\": \"...\", \"event_type\": \"learning\"}' | ~/.claude/hooks/store-memory.sh"
317
+ echo " Recall: echo '{\"query\": \"...\"}' | ~/.claude/hooks/recall-memory.sh"
318
+ echo ""
319
+ echo "Environment Variables:"
320
+ echo " NEXUS_VERBOSE=1 Enable debug output"
321
+ echo " NEXUS_RECALL_LIMIT=10 Number of memories to auto-recall"
322
+ echo ""
323
+ echo "Documentation: https://github.com/adverant/nexus-memory-skill"
324
+ echo ""
325
+ }
326
+
327
+ # Main installation function
328
+ main() {
329
+ echo ""
330
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
331
+ echo -e "${BLUE} Nexus Memory Installer ${NC}"
332
+ echo -e "${BLUE} Give Your AI Perfect Recall — Across Every Session ${NC}"
333
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
334
+ echo ""
335
+
336
+ check_dependencies
337
+
338
+ local source_dir
339
+ source_dir=$(get_source_dir)
340
+
341
+ create_directories
342
+ install_files "$source_dir"
343
+ configure_settings
344
+ setup_api_key
345
+
346
+ if verify_installation; then
347
+ print_success
348
+ else
349
+ log_error "Installation verification failed. Please check the errors above."
350
+ exit 1
351
+ fi
352
+ }
353
+
354
+ # Run main
355
+ main "$@"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adverant/nexus-memory-skill",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Claude Code skill for persistent memory via Nexus GraphRAG - store and recall memories across all sessions and projects",
5
5
  "main": "SKILL.md",
6
6
  "type": "module",
@@ -30,7 +30,8 @@
30
30
  "README.md",
31
31
  "LICENSE",
32
32
  "hooks/",
33
- "docs/"
33
+ "docs/",
34
+ "install.sh"
34
35
  ],
35
36
  "publishConfig": {
36
37
  "access": "public",