grov 0.5.11 → 0.6.13
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/dist/cli/agents/registry.d.ts +17 -0
- package/dist/cli/agents/registry.js +132 -0
- package/dist/cli/commands/agents.d.ts +1 -0
- package/dist/cli/commands/agents.js +48 -0
- package/dist/cli/commands/disable.d.ts +1 -0
- package/dist/cli/commands/disable.js +179 -0
- package/dist/cli/commands/doctor.d.ts +1 -0
- package/dist/cli/commands/doctor.js +157 -0
- package/dist/{commands → cli/commands}/drift-test.js +39 -26
- package/dist/cli/commands/init.d.ts +1 -0
- package/dist/cli/commands/init.js +90 -0
- package/dist/{commands → cli/commands}/login.js +19 -18
- package/dist/{commands → cli/commands}/logout.js +1 -1
- package/dist/{commands → cli/commands}/proxy-status.js +1 -1
- package/dist/cli/commands/setup.d.ts +6 -0
- package/dist/cli/commands/setup.js +309 -0
- package/dist/{commands → cli/commands}/status.js +1 -1
- package/dist/{commands → cli/commands}/sync.d.ts +1 -0
- package/dist/{commands → cli/commands}/sync.js +59 -4
- package/dist/{commands → cli/commands}/uninstall.js +2 -2
- package/dist/cli/index.js +270 -0
- package/dist/{lib → core/cloud}/cloud-sync.d.ts +3 -3
- package/dist/{lib → core/cloud}/cloud-sync.js +10 -10
- package/dist/{lib → core/extraction}/correction-builder-proxy.d.ts +1 -1
- package/dist/{lib → core/extraction}/correction-builder-proxy.js +0 -4
- package/dist/{lib → core/extraction}/drift-checker-proxy.d.ts +13 -9
- package/dist/core/extraction/drift-checker-proxy.js +510 -0
- package/dist/{lib → core/extraction}/llm-extractor.d.ts +8 -38
- package/dist/{lib → core/extraction}/llm-extractor.js +132 -220
- package/dist/{lib → core}/store/sessions.js +3 -19
- package/dist/core/store/store.d.ts +1 -0
- package/dist/{lib → core/store}/store.js +1 -1
- package/dist/{lib → core}/store/types.d.ts +0 -4
- package/dist/integrations/mcp/cache.d.ts +27 -0
- package/dist/integrations/mcp/cache.js +106 -0
- package/dist/integrations/mcp/capture/antigravity-parser.d.ts +26 -0
- package/dist/integrations/mcp/capture/antigravity-parser.js +272 -0
- package/dist/integrations/mcp/capture/antigravity-scanner.d.ts +24 -0
- package/dist/integrations/mcp/capture/antigravity-scanner.js +153 -0
- package/dist/integrations/mcp/capture/antigravity-sync-tracker.d.ts +29 -0
- package/dist/integrations/mcp/capture/antigravity-sync-tracker.js +115 -0
- package/dist/integrations/mcp/capture/cli-extractor.d.ts +18 -0
- package/dist/integrations/mcp/capture/cli-extractor.js +258 -0
- package/dist/integrations/mcp/capture/cli-synced.d.ts +4 -0
- package/dist/integrations/mcp/capture/cli-synced.js +62 -0
- package/dist/integrations/mcp/capture/cli-transform.d.ts +30 -0
- package/dist/integrations/mcp/capture/cli-transform.js +62 -0
- package/dist/integrations/mcp/capture/cli-watcher.d.ts +31 -0
- package/dist/integrations/mcp/capture/cli-watcher.js +106 -0
- package/dist/integrations/mcp/capture/hook-handler.d.ts +2 -0
- package/dist/integrations/mcp/capture/hook-handler.js +157 -0
- package/dist/integrations/mcp/capture/sqlite-reader.d.ts +35 -0
- package/dist/integrations/mcp/capture/sqlite-reader.js +388 -0
- package/dist/integrations/mcp/capture/sync-tracker.d.ts +16 -0
- package/dist/integrations/mcp/capture/sync-tracker.js +102 -0
- package/dist/integrations/mcp/clients/cursor/rules-installer.d.ts +19 -0
- package/dist/integrations/mcp/clients/cursor/rules-installer.js +123 -0
- package/dist/integrations/mcp/index.d.ts +1 -0
- package/dist/integrations/mcp/index.js +94 -0
- package/dist/integrations/mcp/logger.d.ts +8 -0
- package/dist/integrations/mcp/logger.js +50 -0
- package/dist/integrations/mcp/server.d.ts +5 -0
- package/dist/integrations/mcp/server.js +58 -0
- package/dist/integrations/mcp/tools/expand.d.ts +1 -0
- package/dist/integrations/mcp/tools/expand.js +53 -0
- package/dist/integrations/mcp/tools/preview.d.ts +1 -0
- package/dist/integrations/mcp/tools/preview.js +64 -0
- package/dist/integrations/proxy/agents/base.d.ts +43 -0
- package/dist/integrations/proxy/agents/base.js +13 -0
- package/dist/{proxy/utils → integrations/proxy/agents/claude}/extractors.d.ts +4 -8
- package/dist/{proxy/utils → integrations/proxy/agents/claude}/extractors.js +4 -33
- package/dist/{proxy → integrations/proxy/agents/claude}/forwarder.d.ts +1 -1
- package/dist/{proxy → integrations/proxy/agents/claude}/forwarder.js +22 -6
- package/dist/integrations/proxy/agents/claude/index.d.ts +43 -0
- package/dist/integrations/proxy/agents/claude/index.js +386 -0
- package/dist/{proxy/action-parser.d.ts → integrations/proxy/agents/claude/parser.d.ts} +1 -1
- package/dist/integrations/proxy/agents/codex/extractors.d.ts +6 -0
- package/dist/integrations/proxy/agents/codex/extractors.js +49 -0
- package/dist/integrations/proxy/agents/codex/forwarder.d.ts +9 -0
- package/dist/integrations/proxy/agents/codex/forwarder.js +125 -0
- package/dist/integrations/proxy/agents/codex/index.d.ts +44 -0
- package/dist/integrations/proxy/agents/codex/index.js +371 -0
- package/dist/integrations/proxy/agents/codex/parser.d.ts +11 -0
- package/dist/integrations/proxy/agents/codex/parser.js +104 -0
- package/dist/integrations/proxy/agents/codex/patch.d.ts +12 -0
- package/dist/integrations/proxy/agents/codex/patch.js +40 -0
- package/dist/integrations/proxy/agents/codex/settings.d.ts +18 -0
- package/dist/integrations/proxy/agents/codex/settings.js +73 -0
- package/dist/integrations/proxy/agents/codex/types.d.ts +59 -0
- package/dist/integrations/proxy/agents/codex/types.js +2 -0
- package/dist/integrations/proxy/agents/index.d.ts +11 -0
- package/dist/integrations/proxy/agents/index.js +25 -0
- package/dist/integrations/proxy/agents/types.d.ts +77 -0
- package/dist/integrations/proxy/agents/types.js +2 -0
- package/dist/{proxy → integrations/proxy/cache}/extended-cache.js +2 -6
- package/dist/{proxy → integrations/proxy}/config.js +1 -1
- package/dist/{proxy → integrations/proxy}/handlers/preprocess.d.ts +3 -3
- package/dist/integrations/proxy/handlers/preprocess.js +194 -0
- package/dist/integrations/proxy/index.js +20 -0
- package/dist/integrations/proxy/injection/memory-injection.d.ts +56 -0
- package/dist/integrations/proxy/injection/memory-injection.js +252 -0
- package/dist/integrations/proxy/orchestrator.d.ts +30 -0
- package/dist/integrations/proxy/orchestrator.js +954 -0
- package/dist/integrations/proxy/request-processor.d.ts +14 -0
- package/dist/integrations/proxy/request-processor.js +68 -0
- package/dist/{proxy → integrations/proxy}/response-processor.d.ts +4 -3
- package/dist/{proxy → integrations/proxy}/response-processor.js +51 -43
- package/dist/{proxy → integrations/proxy}/server.d.ts +0 -1
- package/dist/integrations/proxy/server.js +146 -0
- package/dist/{proxy → integrations/proxy}/types.d.ts +4 -0
- package/dist/{proxy → integrations/proxy}/utils/logging.d.ts +1 -0
- package/dist/{proxy → integrations/proxy}/utils/logging.js +5 -0
- package/package.json +31 -10
- package/postinstall.js +62 -6
- package/dist/cli.js +0 -149
- package/dist/commands/capture.d.ts +0 -6
- package/dist/commands/capture.js +0 -324
- package/dist/commands/disable.d.ts +0 -1
- package/dist/commands/disable.js +0 -14
- package/dist/commands/doctor.d.ts +0 -1
- package/dist/commands/doctor.js +0 -89
- package/dist/commands/init.d.ts +0 -1
- package/dist/commands/init.js +0 -52
- package/dist/commands/inject.d.ts +0 -5
- package/dist/commands/inject.js +0 -88
- package/dist/commands/prompt-inject.d.ts +0 -4
- package/dist/commands/prompt-inject.js +0 -451
- package/dist/commands/unregister.d.ts +0 -1
- package/dist/commands/unregister.js +0 -28
- package/dist/lib/anchor-extractor.d.ts +0 -30
- package/dist/lib/anchor-extractor.js +0 -296
- package/dist/lib/correction-builder.d.ts +0 -10
- package/dist/lib/correction-builder.js +0 -226
- package/dist/lib/drift-checker-proxy.js +0 -373
- package/dist/lib/drift-checker.d.ts +0 -66
- package/dist/lib/drift-checker.js +0 -341
- package/dist/lib/hooks.d.ts +0 -38
- package/dist/lib/hooks.js +0 -291
- package/dist/lib/jsonl-parser.d.ts +0 -87
- package/dist/lib/jsonl-parser.js +0 -281
- package/dist/lib/session-parser.d.ts +0 -44
- package/dist/lib/session-parser.js +0 -256
- package/dist/lib/store.d.ts +0 -1
- package/dist/proxy/cache.d.ts +0 -32
- package/dist/proxy/cache.js +0 -47
- package/dist/proxy/handlers/preprocess.js +0 -186
- package/dist/proxy/index.js +0 -30
- package/dist/proxy/injection/delta-tracking.d.ts +0 -11
- package/dist/proxy/injection/delta-tracking.js +0 -94
- package/dist/proxy/injection/injectors.d.ts +0 -7
- package/dist/proxy/injection/injectors.js +0 -139
- package/dist/proxy/request-processor.d.ts +0 -27
- package/dist/proxy/request-processor.js +0 -233
- package/dist/proxy/server.js +0 -1289
- /package/dist/{commands → cli/commands}/drift-test.d.ts +0 -0
- /package/dist/{commands → cli/commands}/login.d.ts +0 -0
- /package/dist/{commands → cli/commands}/logout.d.ts +0 -0
- /package/dist/{commands → cli/commands}/proxy-status.d.ts +0 -0
- /package/dist/{commands → cli/commands}/status.d.ts +0 -0
- /package/dist/{commands → cli/commands}/uninstall.d.ts +0 -0
- /package/dist/{cli.d.ts → cli/index.d.ts} +0 -0
- /package/dist/{lib → core/cloud}/api-client.d.ts +0 -0
- /package/dist/{lib → core/cloud}/api-client.js +0 -0
- /package/dist/{lib → core/cloud}/credentials.d.ts +0 -0
- /package/dist/{lib → core/cloud}/credentials.js +0 -0
- /package/dist/{lib → core}/store/convenience.d.ts +0 -0
- /package/dist/{lib → core}/store/convenience.js +0 -0
- /package/dist/{lib → core}/store/database.d.ts +0 -0
- /package/dist/{lib → core}/store/database.js +0 -0
- /package/dist/{lib → core}/store/drift.d.ts +0 -0
- /package/dist/{lib → core}/store/drift.js +0 -0
- /package/dist/{lib → core}/store/index.d.ts +0 -0
- /package/dist/{lib → core}/store/index.js +0 -0
- /package/dist/{lib → core}/store/sessions.d.ts +0 -0
- /package/dist/{lib → core}/store/steps.d.ts +0 -0
- /package/dist/{lib → core}/store/steps.js +0 -0
- /package/dist/{lib → core}/store/tasks.d.ts +0 -0
- /package/dist/{lib → core}/store/tasks.js +0 -0
- /package/dist/{lib → core}/store/types.js +0 -0
- /package/dist/{proxy/action-parser.js → integrations/proxy/agents/claude/parser.js} +0 -0
- /package/dist/{lib → integrations/proxy/agents/claude}/settings.d.ts +0 -0
- /package/dist/{lib → integrations/proxy/agents/claude}/settings.js +0 -0
- /package/dist/{proxy → integrations/proxy/cache}/extended-cache.d.ts +0 -0
- /package/dist/{proxy → integrations/proxy}/config.d.ts +0 -0
- /package/dist/{proxy → integrations/proxy}/index.d.ts +0 -0
- /package/dist/{proxy → integrations/proxy}/types.js +0 -0
- /package/dist/{lib → utils}/debug.d.ts +0 -0
- /package/dist/{lib → utils}/debug.js +0 -0
- /package/dist/{lib → utils}/utils.d.ts +0 -0
- /package/dist/{lib → utils}/utils.js +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// grov init - Configure AI agent to use grov proxy/MCP
|
|
2
|
+
import { getAgentByName } from '../../integrations/proxy/agents/index.js';
|
|
3
|
+
import { setupMcpCursor, setupMcpAntigravity, setupMcpZed, setupCursorHooks } from './setup.js';
|
|
4
|
+
import { installProjectRules } from '../../integrations/mcp/clients/cursor/rules-installer.js';
|
|
5
|
+
const AGENT_INSTRUCTIONS = {
|
|
6
|
+
claude: {
|
|
7
|
+
envVar: 'ANTHROPIC_API_KEY',
|
|
8
|
+
command: 'claude',
|
|
9
|
+
keyUrl: 'https://console.anthropic.com/settings/keys',
|
|
10
|
+
},
|
|
11
|
+
codex: {
|
|
12
|
+
envVar: 'OPENAI_API_KEY',
|
|
13
|
+
command: 'codex',
|
|
14
|
+
keyUrl: 'https://platform.openai.com/api-keys',
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
export async function init(agentName = 'claude') {
|
|
18
|
+
// Cursor: MCP-based setup (different from proxy)
|
|
19
|
+
if (agentName === 'cursor') {
|
|
20
|
+
console.log('Configuring grov for Cursor...\n');
|
|
21
|
+
// 1. MCP registration (global)
|
|
22
|
+
await setupMcpCursor();
|
|
23
|
+
// 2. Stop hook registration (global)
|
|
24
|
+
await setupCursorHooks();
|
|
25
|
+
// 3. Project rules (per-project)
|
|
26
|
+
const projectDir = process.cwd();
|
|
27
|
+
const result = installProjectRules(projectDir);
|
|
28
|
+
if (result.grovRules) {
|
|
29
|
+
console.log(' + Created .grov/rules.mdc');
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
console.log(' = .grov/rules.mdc already exists');
|
|
33
|
+
}
|
|
34
|
+
if (result.cursorPointer) {
|
|
35
|
+
console.log(' + Created .cursor/rules/90_grov.mdc');
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
console.log(' = .cursor/rules/90_grov.mdc already exists');
|
|
39
|
+
}
|
|
40
|
+
console.log('\n--- Next Steps ---');
|
|
41
|
+
console.log('1. Restart Cursor');
|
|
42
|
+
console.log('2. Open this project in Cursor');
|
|
43
|
+
console.log('\nRun "grov doctor cursor" to verify setup.');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// Antigravity: MCP-based setup
|
|
47
|
+
if (agentName === 'antigravity') {
|
|
48
|
+
console.log('Configuring grov for Antigravity...\n');
|
|
49
|
+
// MCP registration (global)
|
|
50
|
+
await setupMcpAntigravity();
|
|
51
|
+
console.log('\n--- Next Steps ---');
|
|
52
|
+
console.log('1. Restart Antigravity');
|
|
53
|
+
console.log('2. Open your project in Antigravity');
|
|
54
|
+
console.log('\nRun "grov doctor antigravity" to verify setup.');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Zed: MCP-based setup
|
|
58
|
+
if (agentName === 'zed') {
|
|
59
|
+
console.log('Configuring grov for Zed...\n');
|
|
60
|
+
// MCP registration (global)
|
|
61
|
+
await setupMcpZed();
|
|
62
|
+
console.log('\n--- Next Steps ---');
|
|
63
|
+
console.log('1. Restart Zed');
|
|
64
|
+
console.log('2. Open the Agent Panel in Zed');
|
|
65
|
+
console.log('\nRun "grov doctor zed" to verify setup.');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// Claude/Codex: proxy-based setup
|
|
69
|
+
const agent = getAgentByName(agentName);
|
|
70
|
+
if (!agent) {
|
|
71
|
+
console.error(`Unknown agent: ${agentName}`);
|
|
72
|
+
console.error('Supported agents: claude, codex, cursor');
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
const instructions = AGENT_INSTRUCTIONS[agentName];
|
|
76
|
+
console.log(`Configuring grov for ${agentName}...\n`);
|
|
77
|
+
const settings = agent.getSettings();
|
|
78
|
+
const result = settings.setProxyEnabled(true);
|
|
79
|
+
if (result.action === 'added') {
|
|
80
|
+
console.log(` + Proxy configured for ${agentName}`);
|
|
81
|
+
}
|
|
82
|
+
else if (result.action === 'unchanged') {
|
|
83
|
+
console.log(` = Proxy already configured for ${agentName}`);
|
|
84
|
+
}
|
|
85
|
+
console.log(`\nConfig file: ${settings.getConfigPath()}`);
|
|
86
|
+
console.log('\n--- Next Steps (Claude/Codex) ---');
|
|
87
|
+
console.log('1. Terminal 1: grov proxy');
|
|
88
|
+
console.log(`2. Terminal 2: ${instructions.command}`);
|
|
89
|
+
console.log('\nRun "grov doctor" to verify your setup is complete.');
|
|
90
|
+
}
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
// Authenticates CLI with Grov cloud using OAuth-like device flow
|
|
3
3
|
import open from 'open';
|
|
4
4
|
import * as readline from 'readline';
|
|
5
|
-
import { writeCredentials, isAuthenticated, readCredentials, setTeamId, setSyncEnabled } from '
|
|
6
|
-
import { startDeviceFlow, pollDeviceFlow, sleep, fetchTeams } from '
|
|
5
|
+
import { writeCredentials, isAuthenticated, readCredentials, setTeamId, setSyncEnabled } from '../../core/cloud/credentials.js';
|
|
6
|
+
import { startDeviceFlow, pollDeviceFlow, sleep, fetchTeams } from '../../core/cloud/api-client.js';
|
|
7
|
+
import { isAnyAgentConfigured } from '../agents/registry.js';
|
|
7
8
|
/**
|
|
8
9
|
* Prompt user for input
|
|
9
10
|
*/
|
|
@@ -38,6 +39,7 @@ function decodeTokenPayload(token) {
|
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
export async function login() {
|
|
42
|
+
const autoMode = process.argv.includes('--auto');
|
|
41
43
|
console.log('Logging in to Grov cloud...\n');
|
|
42
44
|
// Check if already authenticated
|
|
43
45
|
if (isAuthenticated()) {
|
|
@@ -119,8 +121,8 @@ export async function login() {
|
|
|
119
121
|
return;
|
|
120
122
|
}
|
|
121
123
|
let selectedTeam = teams[0];
|
|
122
|
-
// If multiple teams, let user choose
|
|
123
|
-
if (teams.length > 1) {
|
|
124
|
+
// If multiple teams, let user choose (skip in auto mode)
|
|
125
|
+
if (teams.length > 1 && !autoMode) {
|
|
124
126
|
console.log('\nYour teams:');
|
|
125
127
|
teams.forEach((team, i) => {
|
|
126
128
|
console.log(` ${i + 1}. ${team.name} (${team.slug})`);
|
|
@@ -131,8 +133,8 @@ export async function login() {
|
|
|
131
133
|
selectedTeam = teams[index];
|
|
132
134
|
}
|
|
133
135
|
}
|
|
134
|
-
// Ask to enable sync (default yes)
|
|
135
|
-
const enableSync = await prompt(`Enable cloud sync to "${selectedTeam.name}"? [Y/n]: `);
|
|
136
|
+
// Ask to enable sync (default yes, skip in auto mode)
|
|
137
|
+
const enableSync = autoMode ? '' : await prompt(`Enable cloud sync to "${selectedTeam.name}"? [Y/n]: `);
|
|
136
138
|
if (enableSync !== 'n' && enableSync !== 'no') {
|
|
137
139
|
setTeamId(selectedTeam.id);
|
|
138
140
|
setSyncEnabled(true);
|
|
@@ -142,21 +144,20 @@ export async function login() {
|
|
|
142
144
|
console.log('║ ║');
|
|
143
145
|
console.log('╚═════════════════════════════════════════╝');
|
|
144
146
|
console.log(`\nSyncing to: ${selectedTeam.name}`);
|
|
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');
|
|
156
147
|
}
|
|
157
148
|
else {
|
|
158
149
|
console.log('\n✓ Logged in. Sync not enabled.');
|
|
159
|
-
|
|
150
|
+
}
|
|
151
|
+
// Continue to agent setup if no agent configured
|
|
152
|
+
if (!isAnyAgentConfigured()) {
|
|
153
|
+
console.log('\n───────────────────────────────────────────────────────────\n');
|
|
154
|
+
console.log('Now let\'s configure your AI agent...\n');
|
|
155
|
+
const { runAgentSetup } = await import('./setup.js');
|
|
156
|
+
await runAgentSetup();
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
console.log('\nRun "grov doctor" to verify your setup is complete.');
|
|
160
|
+
console.log('View memories at: https://app.grov.dev/memories\n');
|
|
160
161
|
}
|
|
161
162
|
}
|
|
162
163
|
catch (err) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Logout command - Clear stored credentials
|
|
2
|
-
import { clearCredentials, readCredentials } from '
|
|
2
|
+
import { clearCredentials, readCredentials } from '../../core/cloud/credentials.js';
|
|
3
3
|
export async function logout() {
|
|
4
4
|
const creds = readCredentials();
|
|
5
5
|
if (!creds) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// grov proxy-status - Show active proxy sessions
|
|
2
|
-
import { getActiveSessionsForStatus } from '
|
|
2
|
+
import { getActiveSessionsForStatus } from '../../core/store/store.js';
|
|
3
3
|
export async function proxyStatus() {
|
|
4
4
|
const sessions = getActiveSessionsForStatus();
|
|
5
5
|
if (sessions.length === 0) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function setupCursorHooks(): Promise<void>;
|
|
2
|
+
export declare function setupMcpCursor(): Promise<void>;
|
|
3
|
+
export declare function setupMcpAntigravity(): Promise<void>;
|
|
4
|
+
export declare function setupMcpZed(): Promise<void>;
|
|
5
|
+
export declare function runAgentSetup(): Promise<void>;
|
|
6
|
+
export declare function setup(): Promise<void>;
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
// Setup commands for grov integrations
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import * as readline from 'readline';
|
|
6
|
+
import { getCliAgentsByType, isAnyAgentConfigured } from '../agents/registry.js';
|
|
7
|
+
const green = '\x1b[32m';
|
|
8
|
+
const yellow = '\x1b[33m';
|
|
9
|
+
const cyan = '\x1b[36m';
|
|
10
|
+
const dim = '\x1b[2m';
|
|
11
|
+
const reset = '\x1b[0m';
|
|
12
|
+
export async function setupCursorHooks() {
|
|
13
|
+
const hooksPath = join(homedir(), '.cursor', 'hooks.json');
|
|
14
|
+
const apiUrl = process.env.GROV_API_URL;
|
|
15
|
+
const command = apiUrl
|
|
16
|
+
? `GROV_API_URL=${apiUrl} grov capture-hook`
|
|
17
|
+
: 'grov capture-hook';
|
|
18
|
+
const grovHook = { command };
|
|
19
|
+
let config = { version: 1, hooks: { stop: [] } };
|
|
20
|
+
if (existsSync(hooksPath)) {
|
|
21
|
+
try {
|
|
22
|
+
const content = readFileSync(hooksPath, 'utf-8');
|
|
23
|
+
config = JSON.parse(content);
|
|
24
|
+
if (!config.hooks)
|
|
25
|
+
config.hooks = {};
|
|
26
|
+
if (!config.hooks.stop)
|
|
27
|
+
config.hooks.stop = [];
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
config = { version: 1, hooks: { stop: [] } };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Remove existing grov hook (if any) to replace with new one
|
|
34
|
+
const hadGrovHook = config.hooks.stop.some((h) => h.command?.includes('grov capture-hook'));
|
|
35
|
+
config.hooks.stop = config.hooks.stop.filter((h) => !h.command?.includes('grov capture-hook'));
|
|
36
|
+
// Add new grov hook
|
|
37
|
+
config.hooks.stop.push(grovHook);
|
|
38
|
+
try {
|
|
39
|
+
writeFileSync(hooksPath, JSON.stringify(config, null, 2));
|
|
40
|
+
if (hadGrovHook) {
|
|
41
|
+
console.log(`${green}✓${reset} Cursor stop hook updated.`);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
console.log(`${green}✓${reset} Cursor stop hook configured.`);
|
|
45
|
+
}
|
|
46
|
+
if (apiUrl) {
|
|
47
|
+
console.log(`${dim} API URL: ${apiUrl}${reset}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
52
|
+
console.error(`${yellow}⚠${reset} Could not write ${hooksPath}: ${msg}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export async function setupMcpCursor() {
|
|
56
|
+
const cursorDir = join(homedir(), '.cursor');
|
|
57
|
+
const mcpPath = join(cursorDir, 'mcp.json');
|
|
58
|
+
// Check if Cursor directory exists
|
|
59
|
+
if (!existsSync(cursorDir)) {
|
|
60
|
+
console.log(`${yellow}⚠${reset} Cursor not installed (~/.cursor not found)`);
|
|
61
|
+
console.log(`${dim}Install Cursor first, then run this command again.${reset}\n`);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// Build grov entry - add env if GROV_API_URL is set
|
|
65
|
+
const apiUrl = process.env.GROV_API_URL;
|
|
66
|
+
const grovEntry = {
|
|
67
|
+
command: 'grov',
|
|
68
|
+
args: ['mcp'],
|
|
69
|
+
};
|
|
70
|
+
if (apiUrl) {
|
|
71
|
+
grovEntry.env = { GROV_API_URL: apiUrl };
|
|
72
|
+
}
|
|
73
|
+
let mcpConfig = { mcpServers: {} };
|
|
74
|
+
// Read existing config
|
|
75
|
+
if (existsSync(mcpPath)) {
|
|
76
|
+
try {
|
|
77
|
+
const content = readFileSync(mcpPath, 'utf-8');
|
|
78
|
+
mcpConfig = JSON.parse(content);
|
|
79
|
+
if (!mcpConfig.mcpServers) {
|
|
80
|
+
mcpConfig.mcpServers = {};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
console.log(`${yellow}⚠${reset} Could not parse ${mcpPath}, creating new config.`);
|
|
85
|
+
mcpConfig = { mcpServers: {} };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const wasConfigured = !!mcpConfig.mcpServers?.grov;
|
|
89
|
+
// Always set/update grov entry
|
|
90
|
+
mcpConfig.mcpServers.grov = grovEntry;
|
|
91
|
+
// Write config
|
|
92
|
+
try {
|
|
93
|
+
writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2));
|
|
94
|
+
if (wasConfigured) {
|
|
95
|
+
console.log(`${green}✓${reset} Cursor MCP updated.`);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
console.log(`${green}✓${reset} Cursor MCP configured.`);
|
|
99
|
+
}
|
|
100
|
+
if (apiUrl) {
|
|
101
|
+
console.log(`${dim} API URL: ${apiUrl}${reset}`);
|
|
102
|
+
}
|
|
103
|
+
console.log(`${dim}Restart Cursor to apply changes.${reset}\n`);
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
107
|
+
console.error(`${yellow}⚠${reset} Could not write ${mcpPath}: ${msg}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export async function setupMcpAntigravity() {
|
|
111
|
+
const antigravityDir = join(homedir(), '.gemini', 'antigravity');
|
|
112
|
+
const mcpConfigPath = join(antigravityDir, 'mcp_config.json');
|
|
113
|
+
// Check if Antigravity directory exists
|
|
114
|
+
if (!existsSync(antigravityDir)) {
|
|
115
|
+
console.log(`${yellow}⚠${reset} Antigravity not installed (~/.gemini/antigravity not found)`);
|
|
116
|
+
console.log(`${dim}Install Antigravity first, then run this command again.${reset}\n`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// Extract project name from cwd (Antigravity runs MCP with cwd="/")
|
|
120
|
+
const projectPath = process.cwd().split('/').filter(Boolean).pop() || 'unknown';
|
|
121
|
+
const grovEntry = {
|
|
122
|
+
command: 'grov',
|
|
123
|
+
args: ['mcp'],
|
|
124
|
+
env: {
|
|
125
|
+
GROV_PROJECT_PATH: projectPath,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
let config = { mcpServers: {} };
|
|
129
|
+
// Read existing config
|
|
130
|
+
if (existsSync(mcpConfigPath)) {
|
|
131
|
+
try {
|
|
132
|
+
const content = readFileSync(mcpConfigPath, 'utf-8');
|
|
133
|
+
config = JSON.parse(content);
|
|
134
|
+
if (!config.mcpServers) {
|
|
135
|
+
config.mcpServers = {};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
console.log(`${yellow}⚠${reset} Could not parse ${mcpConfigPath}, creating new config.`);
|
|
140
|
+
config = { mcpServers: {} };
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Check if already configured
|
|
144
|
+
if (config.mcpServers?.grov) {
|
|
145
|
+
console.log(`${green}✓${reset} Antigravity MCP already configured for grov.`);
|
|
146
|
+
console.log(`${dim}Restart Antigravity to apply any changes.${reset}\n`);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
// Add grov entry
|
|
150
|
+
config.mcpServers.grov = grovEntry;
|
|
151
|
+
// Write config
|
|
152
|
+
try {
|
|
153
|
+
writeFileSync(mcpConfigPath, JSON.stringify(config, null, 2));
|
|
154
|
+
console.log(`${green}✓${reset} Antigravity MCP configured.`);
|
|
155
|
+
console.log(`${dim}Restart Antigravity to activate grov.${reset}\n`);
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
159
|
+
console.error(`${yellow}⚠${reset} Could not write ${mcpConfigPath}: ${msg}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
export async function setupMcpZed() {
|
|
163
|
+
const zedConfigDir = join(homedir(), '.config', 'zed');
|
|
164
|
+
const settingsPath = join(zedConfigDir, 'settings.json');
|
|
165
|
+
// Check if Zed config directory exists
|
|
166
|
+
if (!existsSync(zedConfigDir)) {
|
|
167
|
+
console.log(`${yellow}⚠${reset} Zed not installed (~/.config/zed not found)`);
|
|
168
|
+
console.log(`${dim}Install Zed first, then run this command again.${reset}\n`);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const grovEntry = {
|
|
172
|
+
command: 'grov',
|
|
173
|
+
args: ['mcp'],
|
|
174
|
+
};
|
|
175
|
+
let config = {};
|
|
176
|
+
// Read existing config (preserve all settings)
|
|
177
|
+
if (existsSync(settingsPath)) {
|
|
178
|
+
try {
|
|
179
|
+
// Zed settings.json may have comments, try to parse anyway
|
|
180
|
+
const content = readFileSync(settingsPath, 'utf-8');
|
|
181
|
+
// Remove single-line comments for parsing
|
|
182
|
+
const cleanContent = content.replace(/^\s*\/\/.*$/gm, '');
|
|
183
|
+
config = JSON.parse(cleanContent);
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
console.log(`${yellow}⚠${reset} Could not parse ${settingsPath}. Please add grov manually.`);
|
|
187
|
+
console.log(`\nAdd to your settings.json under "context_servers":`);
|
|
188
|
+
console.log(` "grov": { "command": "grov", "args": ["mcp"] }\n`);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Ensure context_servers object exists
|
|
193
|
+
if (!config.context_servers) {
|
|
194
|
+
config.context_servers = {};
|
|
195
|
+
}
|
|
196
|
+
const contextServers = config.context_servers;
|
|
197
|
+
// Check if already configured
|
|
198
|
+
if (contextServers.grov) {
|
|
199
|
+
console.log(`${green}✓${reset} Zed context_servers already configured for grov.`);
|
|
200
|
+
console.log(`${dim}Restart Zed to apply any changes.${reset}\n`);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
// Add grov entry
|
|
204
|
+
contextServers.grov = grovEntry;
|
|
205
|
+
// Write config
|
|
206
|
+
try {
|
|
207
|
+
writeFileSync(settingsPath, JSON.stringify(config, null, 2));
|
|
208
|
+
console.log(`${green}✓${reset} Zed context_servers configured.`);
|
|
209
|
+
console.log(`${dim}Restart Zed to activate grov.${reset}\n`);
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
213
|
+
console.error(`${yellow}⚠${reset} Could not write ${settingsPath}: ${msg}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function prompt(question) {
|
|
217
|
+
const rl = readline.createInterface({
|
|
218
|
+
input: process.stdin,
|
|
219
|
+
output: process.stdout,
|
|
220
|
+
});
|
|
221
|
+
return new Promise((resolve) => {
|
|
222
|
+
rl.question(question, (answer) => {
|
|
223
|
+
rl.close();
|
|
224
|
+
resolve(answer.trim());
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
export async function runAgentSetup() {
|
|
229
|
+
const cliAgents = getCliAgentsByType('cli');
|
|
230
|
+
const ideAgents = getCliAgentsByType('ide');
|
|
231
|
+
const allAgents = [...cliAgents, ...ideAgents];
|
|
232
|
+
console.log('What AI tool do you use?\n');
|
|
233
|
+
console.log('CLI AGENTS (require proxy running)');
|
|
234
|
+
cliAgents.forEach((agent, i) => {
|
|
235
|
+
console.log(` ${i + 1}. ${agent.name} - ${agent.description}`);
|
|
236
|
+
});
|
|
237
|
+
console.log('\nIDE AGENTS (native integration, no proxy)');
|
|
238
|
+
ideAgents.forEach((agent, i) => {
|
|
239
|
+
console.log(` ${cliAgents.length + i + 1}. ${agent.name} - ${agent.description}`);
|
|
240
|
+
});
|
|
241
|
+
const choice = await prompt(`\nSelect agent [1-${allAgents.length}]: `);
|
|
242
|
+
const index = parseInt(choice, 10) - 1;
|
|
243
|
+
if (index < 0 || index >= allAgents.length || isNaN(index)) {
|
|
244
|
+
console.log('\nInvalid selection. Run "grov setup" to try again.\n');
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const selectedAgent = allAgents[index];
|
|
248
|
+
await configureAgent(selectedAgent);
|
|
249
|
+
showFinalInstructions(selectedAgent);
|
|
250
|
+
}
|
|
251
|
+
async function configureAgent(agent) {
|
|
252
|
+
console.log(`\nConfiguring ${agent.name}...\n`);
|
|
253
|
+
const { init } = await import('./init.js');
|
|
254
|
+
await init(agent.id);
|
|
255
|
+
}
|
|
256
|
+
function showFinalInstructions(agent) {
|
|
257
|
+
console.log('\n╔═════════════════════════════════════════════════════════╗');
|
|
258
|
+
console.log('║ ║');
|
|
259
|
+
console.log('║ ✓ Setup complete! ║');
|
|
260
|
+
console.log('║ ║');
|
|
261
|
+
console.log('╚═════════════════════════════════════════════════════════╝\n');
|
|
262
|
+
if (agent.type === 'cli') {
|
|
263
|
+
console.log('┌─────────────────────────────────────────────────────┐');
|
|
264
|
+
console.log('│ HOW TO USE GROV │');
|
|
265
|
+
console.log('│ │');
|
|
266
|
+
console.log('│ 1. Start proxy (keep running): │');
|
|
267
|
+
console.log('│ $ grov proxy │');
|
|
268
|
+
console.log('│ │');
|
|
269
|
+
console.log('│ 2. In another terminal, use your agent: │');
|
|
270
|
+
console.log(`│ $ ${agent.command}`.padEnd(54) + '│');
|
|
271
|
+
console.log('│ │');
|
|
272
|
+
console.log('│ 3. View your team\'s memories: │');
|
|
273
|
+
console.log('│ https://app.grov.dev │');
|
|
274
|
+
console.log('└─────────────────────────────────────────────────────┘');
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
console.log('┌─────────────────────────────────────────────────────┐');
|
|
278
|
+
console.log('│ HOW TO USE GROV │');
|
|
279
|
+
console.log('│ │');
|
|
280
|
+
console.log(`│ 1. Restart ${agent.name}`.padEnd(54) + '│');
|
|
281
|
+
console.log('│ │');
|
|
282
|
+
console.log(`│ 2. Use ${agent.name} normally`.padEnd(54) + '│');
|
|
283
|
+
console.log('│ Grov runs automatically in the background │');
|
|
284
|
+
console.log('│ │');
|
|
285
|
+
console.log('│ 3. View your team\'s memories: │');
|
|
286
|
+
console.log('│ https://app.grov.dev │');
|
|
287
|
+
console.log('└─────────────────────────────────────────────────────┘');
|
|
288
|
+
}
|
|
289
|
+
console.log('\nTip: Run "grov doctor" anytime to check status\n');
|
|
290
|
+
}
|
|
291
|
+
export async function setup() {
|
|
292
|
+
const { isAuthenticated } = await import('../../core/cloud/credentials.js');
|
|
293
|
+
if (!isAuthenticated()) {
|
|
294
|
+
console.log('Let\'s get you set up with Grov.\n');
|
|
295
|
+
console.log('First, we\'ll connect to your team...\n');
|
|
296
|
+
const { login } = await import('./login.js');
|
|
297
|
+
await login();
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if (isAnyAgentConfigured()) {
|
|
301
|
+
console.log('An agent is already configured.\n');
|
|
302
|
+
const reconfigure = await prompt('Reconfigure? [y/N]: ');
|
|
303
|
+
if (reconfigure.toLowerCase() !== 'y' && reconfigure.toLowerCase() !== 'yes') {
|
|
304
|
+
console.log('\nRun "grov doctor" to check your setup.\n');
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
await runAgentSetup();
|
|
309
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// grov status - Show stored reasoning for current project
|
|
2
|
-
import { getTasksForProject, getTaskCount, getDatabasePath } from '
|
|
2
|
+
import { getTasksForProject, getTaskCount, getDatabasePath } from '../../core/store/store.js';
|
|
3
3
|
export async function status(options) {
|
|
4
4
|
const projectPath = process.cwd();
|
|
5
5
|
console.log('Grov Status');
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
// Sync command - Configure cloud sync settings
|
|
2
|
-
import { readCredentials, setTeamId, setSyncEnabled, getSyncStatus } from '
|
|
3
|
-
import { fetchTeams, getApiUrl } from '
|
|
4
|
-
import { syncTasks } from '
|
|
5
|
-
import { getUnsyncedTasks, markTaskSynced, setTaskSyncError } from '
|
|
2
|
+
import { readCredentials, setTeamId, setSyncEnabled, getSyncStatus } from '../../core/cloud/credentials.js';
|
|
3
|
+
import { fetchTeams, getApiUrl } from '../../core/cloud/api-client.js';
|
|
4
|
+
import { syncTasks } from '../../core/cloud/cloud-sync.js';
|
|
5
|
+
import { getUnsyncedTasks, markTaskSynced, setTaskSyncError } from '../../core/store/store.js';
|
|
6
|
+
import { scanOnce as scanAntigravity } from '../../integrations/mcp/capture/antigravity-scanner.js';
|
|
7
|
+
import { antigravityExists } from '../../integrations/mcp/capture/antigravity-parser.js';
|
|
6
8
|
export async function sync(options) {
|
|
7
9
|
const creds = readCredentials();
|
|
8
10
|
if (!creds) {
|
|
9
11
|
console.log('Not logged in. Run "grov login" first.\n');
|
|
10
12
|
process.exit(1);
|
|
11
13
|
}
|
|
14
|
+
// Sync Antigravity sessions
|
|
15
|
+
if (options.antigravity) {
|
|
16
|
+
await syncAntigravitySessions();
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
12
19
|
// Manual catch-up: push unsynced tasks for current project
|
|
13
20
|
if (options.push) {
|
|
14
21
|
const projectPath = process.cwd();
|
|
@@ -125,3 +132,51 @@ export async function sync(options) {
|
|
|
125
132
|
}
|
|
126
133
|
}
|
|
127
134
|
}
|
|
135
|
+
// ─────────────────────────────────────────────────────────────
|
|
136
|
+
// Antigravity Sync
|
|
137
|
+
// ─────────────────────────────────────────────────────────────
|
|
138
|
+
async function syncAntigravitySessions() {
|
|
139
|
+
// Check prerequisites
|
|
140
|
+
if (!antigravityExists()) {
|
|
141
|
+
console.log('Antigravity not installed.\n');
|
|
142
|
+
console.log('Antigravity IDE stores its data in ~/.gemini/antigravity/');
|
|
143
|
+
console.log('Install Antigravity or check if the directory exists.\n');
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
const syncStatus = getSyncStatus();
|
|
147
|
+
if (!syncStatus?.enabled || !syncStatus.teamId) {
|
|
148
|
+
console.log('Cloud sync not configured.\n');
|
|
149
|
+
console.log('Enable sync first:');
|
|
150
|
+
console.log(' grov sync --enable --team <team-id>\n');
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
console.log('Scanning Antigravity sessions...\n');
|
|
154
|
+
try {
|
|
155
|
+
const result = await scanAntigravity();
|
|
156
|
+
console.log('Antigravity Sync Results\n');
|
|
157
|
+
console.log(` Sessions scanned: ${result.scanned}`);
|
|
158
|
+
console.log(` New memories: ${result.synced}`);
|
|
159
|
+
console.log(` Updated: ${result.updated}`);
|
|
160
|
+
console.log(` Skipped: ${result.skipped}`);
|
|
161
|
+
console.log(` Failed: ${result.failed}`);
|
|
162
|
+
console.log('');
|
|
163
|
+
if (result.errors.length > 0) {
|
|
164
|
+
console.log('Errors:');
|
|
165
|
+
for (const err of result.errors) {
|
|
166
|
+
console.log(` - ${err}`);
|
|
167
|
+
}
|
|
168
|
+
console.log('');
|
|
169
|
+
}
|
|
170
|
+
if (result.scanned === 0) {
|
|
171
|
+
console.log('No sessions found in ~/.gemini/antigravity/brain/');
|
|
172
|
+
console.log('Sessions are created when you use Antigravity IDE.\n');
|
|
173
|
+
}
|
|
174
|
+
else if (result.synced === 0 && result.updated === 0 && result.failed === 0) {
|
|
175
|
+
console.log('All sessions are already synced.\n');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
console.error(`Sync failed: ${err instanceof Error ? err.message : 'Unknown error'}\n`);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -3,8 +3,8 @@ import { rmSync, existsSync } from 'fs';
|
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { join } from 'path';
|
|
5
5
|
import * as readline from 'readline';
|
|
6
|
-
import { setProxyEnv } from '
|
|
7
|
-
import { clearCredentials } from '
|
|
6
|
+
import { setProxyEnv } from '../../integrations/proxy/agents/claude/settings.js';
|
|
7
|
+
import { clearCredentials } from '../../core/cloud/credentials.js';
|
|
8
8
|
const GROV_DIR = join(homedir(), '.grov');
|
|
9
9
|
function prompt(question) {
|
|
10
10
|
const rl = readline.createInterface({
|