grov 0.5.5 → 0.5.7
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 +41 -2
- package/dist/cli.js +8 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +89 -0
- package/dist/commands/init.js +14 -10
- package/dist/commands/login.js +11 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -166,6 +166,7 @@ grov proxy-status # Show active sessions
|
|
|
166
166
|
grov status # Show captured tasks
|
|
167
167
|
grov login # Login to cloud dashboard
|
|
168
168
|
grov sync # Sync memories to team dashboard
|
|
169
|
+
grov doctor # Diagnose setup issues
|
|
169
170
|
grov disable # Disable grov
|
|
170
171
|
grov drift-test # Test drift detection
|
|
171
172
|
```
|
|
@@ -213,7 +214,7 @@ Browse, search, and manage your team's AI knowledge at [app.grov.dev](https://ap
|
|
|
213
214
|
## Environment Variables
|
|
214
215
|
|
|
215
216
|
```bash
|
|
216
|
-
# Required for
|
|
217
|
+
# Required for memory sync and drift detection
|
|
217
218
|
export ANTHROPIC_API_KEY=sk-ant-...
|
|
218
219
|
|
|
219
220
|
# Optional
|
|
@@ -222,7 +223,45 @@ export PROXY_HOST=127.0.0.1 # Proxy host
|
|
|
222
223
|
export PROXY_PORT=8080 # Proxy port
|
|
223
224
|
```
|
|
224
225
|
|
|
225
|
-
Without an API key, Grov uses basic extraction and
|
|
226
|
+
Without an API key, Grov uses basic extraction and **memories will not sync**.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Troubleshooting
|
|
231
|
+
|
|
232
|
+
### Memories not syncing?
|
|
233
|
+
|
|
234
|
+
Run `grov doctor` to diagnose:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
grov doctor
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
This checks your proxy, API key, login, sync status, and local database.
|
|
241
|
+
|
|
242
|
+
### ⚠️ Common Issue: API Key Not Persisting
|
|
243
|
+
|
|
244
|
+
**Using `export ANTHROPIC_API_KEY=...` directly in terminal only works in THAT terminal session.** When you open a new terminal, the key is gone.
|
|
245
|
+
|
|
246
|
+
**Fix:** Add the key to your shell profile so it persists:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
# For zsh (macOS default):
|
|
250
|
+
echo 'export ANTHROPIC_API_KEY=sk-ant-...' >> ~/.zshrc
|
|
251
|
+
source ~/.zshrc
|
|
252
|
+
|
|
253
|
+
# For bash:
|
|
254
|
+
echo 'export ANTHROPIC_API_KEY=sk-ant-...' >> ~/.bashrc
|
|
255
|
+
source ~/.bashrc
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Then run `grov doctor` to verify:
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
✓ ANTHROPIC_API_KEY: Set
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Get your API key at: https://console.anthropic.com/settings/keys
|
|
226
265
|
|
|
227
266
|
---
|
|
228
267
|
|
package/dist/cli.js
CHANGED
|
@@ -127,4 +127,12 @@ program
|
|
|
127
127
|
const { sync } = await import('./commands/sync.js');
|
|
128
128
|
await sync(options);
|
|
129
129
|
}));
|
|
130
|
+
// grov doctor - Diagnose setup issues
|
|
131
|
+
program
|
|
132
|
+
.command('doctor')
|
|
133
|
+
.description('Check grov setup and diagnose issues')
|
|
134
|
+
.action(safeAction(async () => {
|
|
135
|
+
const { doctor } = await import('./commands/doctor.js');
|
|
136
|
+
await doctor();
|
|
137
|
+
}));
|
|
130
138
|
program.parse();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function doctor(): Promise<void>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// grov doctor - Check setup and diagnose issues
|
|
2
|
+
import { existsSync, readFileSync } from 'fs';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { request } from 'undici';
|
|
6
|
+
import { readCredentials, getSyncStatus } from '../lib/credentials.js';
|
|
7
|
+
import { initDatabase } from '../lib/store/database.js';
|
|
8
|
+
const CLAUDE_SETTINGS_PATH = join(homedir(), '.claude', 'settings.json');
|
|
9
|
+
const DB_PATH = join(homedir(), '.grov', 'memory.db');
|
|
10
|
+
export async function doctor() {
|
|
11
|
+
console.log('\nGrov Doctor');
|
|
12
|
+
console.log('===========\n');
|
|
13
|
+
// Check proxy
|
|
14
|
+
const proxyRunning = await checkProxy();
|
|
15
|
+
printCheck('Proxy', proxyRunning, 'Running on port 8080', 'Not running', 'grov proxy');
|
|
16
|
+
// Check Claude settings
|
|
17
|
+
const baseUrlConfigured = checkBaseUrl();
|
|
18
|
+
printCheck('ANTHROPIC_BASE_URL', baseUrlConfigured, 'Configured for proxy', 'Not configured', 'grov init');
|
|
19
|
+
// Check API key
|
|
20
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
21
|
+
const hasApiKey = !!(apiKey && apiKey.length > 10);
|
|
22
|
+
const shell = process.env.SHELL?.includes('zsh') ? '~/.zshrc' : '~/.bashrc';
|
|
23
|
+
const apiKeyFix = process.platform === 'win32'
|
|
24
|
+
? 'setx ANTHROPIC_API_KEY "sk-ant-..." (permanent) or add to System Environment Variables'
|
|
25
|
+
: `Add to ${shell}: echo 'export ANTHROPIC_API_KEY=sk-ant-...' >> ${shell} && source ${shell}`;
|
|
26
|
+
printCheck('ANTHROPIC_API_KEY', hasApiKey, 'Set', 'NOT SET - memories will not sync!', apiKeyFix);
|
|
27
|
+
// Check login
|
|
28
|
+
const creds = readCredentials();
|
|
29
|
+
printCheck('Login', !!creds, creds ? `Logged in as ${creds.email}` : 'Not logged in', 'Not logged in', 'grov login');
|
|
30
|
+
// Check sync
|
|
31
|
+
const syncStatus = getSyncStatus();
|
|
32
|
+
const syncOk = syncStatus?.enabled && syncStatus?.teamId;
|
|
33
|
+
const syncMsg = syncOk
|
|
34
|
+
? `Team ${syncStatus.teamId.substring(0, 8)}...`
|
|
35
|
+
: syncStatus?.teamId ? 'Disabled' : 'No team';
|
|
36
|
+
printCheck('Cloud Sync', !!syncOk, syncMsg, syncMsg, 'grov sync --enable --team <id>');
|
|
37
|
+
// Check database
|
|
38
|
+
const dbStats = checkDatabase();
|
|
39
|
+
const dbOk = dbStats.tasks > 0 || dbStats.sessions > 0;
|
|
40
|
+
const dbMsg = `${dbStats.tasks} tasks, ${dbStats.unsynced} unsynced, ${dbStats.sessions} active`;
|
|
41
|
+
printCheck('Local Database', dbOk, dbMsg, 'Empty', 'Use Claude Code with proxy running');
|
|
42
|
+
console.log('');
|
|
43
|
+
}
|
|
44
|
+
async function checkProxy() {
|
|
45
|
+
try {
|
|
46
|
+
const res = await request('http://127.0.0.1:8080/health', {
|
|
47
|
+
headersTimeout: 2000,
|
|
48
|
+
bodyTimeout: 2000
|
|
49
|
+
});
|
|
50
|
+
return res.statusCode === 200;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function checkBaseUrl() {
|
|
57
|
+
if (!existsSync(CLAUDE_SETTINGS_PATH))
|
|
58
|
+
return false;
|
|
59
|
+
try {
|
|
60
|
+
const settings = JSON.parse(readFileSync(CLAUDE_SETTINGS_PATH, 'utf-8'));
|
|
61
|
+
return settings.env?.ANTHROPIC_BASE_URL === 'http://127.0.0.1:8080';
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function checkDatabase() {
|
|
68
|
+
if (!existsSync(DB_PATH)) {
|
|
69
|
+
return { tasks: 0, unsynced: 0, sessions: 0 };
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const db = initDatabase();
|
|
73
|
+
const tasks = db.prepare('SELECT COUNT(*) as c FROM tasks').get().c;
|
|
74
|
+
const unsynced = db.prepare('SELECT COUNT(*) as c FROM tasks WHERE synced_at IS NULL').get().c;
|
|
75
|
+
const sessions = db.prepare("SELECT COUNT(*) as c FROM session_states WHERE status = 'active'").get().c;
|
|
76
|
+
return { tasks, unsynced, sessions };
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return { tasks: 0, unsynced: 0, sessions: 0 };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function printCheck(name, ok, successMsg, failMsg, fix) {
|
|
83
|
+
const icon = ok ? '\x1b[32m✓\x1b[0m' : '\x1b[31m✗\x1b[0m';
|
|
84
|
+
const msg = ok ? successMsg : failMsg;
|
|
85
|
+
console.log(`${icon} ${name}: ${msg}`);
|
|
86
|
+
if (!ok) {
|
|
87
|
+
console.log(` \x1b[90m→ ${fix}\x1b[0m`);
|
|
88
|
+
}
|
|
89
|
+
}
|
package/dist/commands/init.js
CHANGED
|
@@ -13,24 +13,28 @@ export async function init() {
|
|
|
13
13
|
}
|
|
14
14
|
console.log(`\nSettings file: ${getSettingsPath()}`);
|
|
15
15
|
// Check for API key and provide helpful instructions
|
|
16
|
+
const shell = process.env.SHELL?.includes('zsh') ? '~/.zshrc' : '~/.bashrc';
|
|
16
17
|
if (!process.env.ANTHROPIC_API_KEY) {
|
|
17
|
-
console.log('\n'
|
|
18
|
-
console.log(' ANTHROPIC_API_KEY
|
|
19
|
-
console.log('
|
|
20
|
-
console.log('\
|
|
21
|
-
console.log(' 1. Get your API key at:');
|
|
18
|
+
console.log('\n╔═══════════════════════════════════════════════════════════╗');
|
|
19
|
+
console.log('║ ⚠️ ANTHROPIC_API_KEY NOT SET - MEMORIES WILL NOT SYNC! ║');
|
|
20
|
+
console.log('╚═══════════════════════════════════════════════════════════╝');
|
|
21
|
+
console.log('\n 1. Get your API key at:');
|
|
22
22
|
console.log(' https://console.anthropic.com/settings/keys\n');
|
|
23
|
-
console.log(' 2. Add to your shell
|
|
24
|
-
console.log('
|
|
25
|
-
console.log(' 3.
|
|
23
|
+
console.log(' 2. Add PERMANENTLY to your shell (not just "export" in terminal):');
|
|
24
|
+
console.log(` echo 'export ANTHROPIC_API_KEY=sk-ant-...' >> ${shell}\n`);
|
|
25
|
+
console.log(' 3. Apply changes:');
|
|
26
|
+
console.log(` source ${shell}\n`);
|
|
27
|
+
console.log(' ⚠️ Using "export" alone only works in THAT terminal!');
|
|
28
|
+
console.log(' The key will be gone when you open a new terminal.\n');
|
|
26
29
|
}
|
|
27
30
|
else {
|
|
28
|
-
console.log('\n ANTHROPIC_API_KEY found');
|
|
31
|
+
console.log('\n ✓ ANTHROPIC_API_KEY found');
|
|
29
32
|
}
|
|
30
33
|
console.log('\n--- Next Steps ---');
|
|
31
34
|
console.log('1. Terminal 1: grov proxy');
|
|
32
35
|
console.log('2. Terminal 2: claude');
|
|
33
|
-
console.log('\
|
|
36
|
+
console.log('\nRun "grov doctor" to verify your setup is complete.');
|
|
37
|
+
console.log('Grov will automatically capture reasoning and inject context.');
|
|
34
38
|
}
|
|
35
39
|
catch (error) {
|
|
36
40
|
console.error('Failed to configure grov:', error instanceof Error ? error.message : 'Unknown error');
|
package/dist/commands/login.js
CHANGED
|
@@ -142,8 +142,17 @@ export async function login() {
|
|
|
142
142
|
console.log('║ ║');
|
|
143
143
|
console.log('╚═════════════════════════════════════════╝');
|
|
144
144
|
console.log(`\nSyncing to: ${selectedTeam.name}`);
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
// Check API key and warn if not set
|
|
146
|
+
if (!process.env.ANTHROPIC_API_KEY) {
|
|
147
|
+
const shell = process.env.SHELL?.includes('zsh') ? '~/.zshrc' : '~/.bashrc';
|
|
148
|
+
console.log('\n⚠️ WARNING: ANTHROPIC_API_KEY not set - memories will NOT sync!');
|
|
149
|
+
console.log('\n Add PERMANENTLY to your shell (not just "export"):');
|
|
150
|
+
console.log(` echo 'export ANTHROPIC_API_KEY=sk-ant-...' >> ${shell}`);
|
|
151
|
+
console.log(` source ${shell}`);
|
|
152
|
+
console.log('\n Get your key at: https://console.anthropic.com/settings/keys');
|
|
153
|
+
}
|
|
154
|
+
console.log('\nRun "grov doctor" to verify your setup is complete.');
|
|
155
|
+
console.log('View memories at: https://app.grov.dev/memories\n');
|
|
147
156
|
}
|
|
148
157
|
else {
|
|
149
158
|
console.log('\n✓ Logged in. Sync not enabled.');
|
package/package.json
CHANGED