@claudetools/tools 0.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/dist/setup.js ADDED
@@ -0,0 +1,206 @@
1
+ // =============================================================================
2
+ // ClaudeTools Memory Interactive Setup Wizard
3
+ // =============================================================================
4
+ // Guides users through initial configuration with validation
5
+ import readline from 'readline';
6
+ import { stdin as input, stdout as output } from 'process';
7
+ import { loadConfigFromFile, saveConfig, ensureConfigDir, getConfigPath, DEFAULT_CONFIG, } from './helpers/config-manager.js';
8
+ // -----------------------------------------------------------------------------
9
+ // Prompt Helpers
10
+ // -----------------------------------------------------------------------------
11
+ /**
12
+ * Prompt user for input with optional default value
13
+ */
14
+ function prompt(question, defaultValue) {
15
+ const rl = readline.createInterface({ input, output });
16
+ return new Promise((resolve) => {
17
+ const displayQuestion = defaultValue
18
+ ? `${question} [${defaultValue}]: `
19
+ : `${question}: `;
20
+ rl.question(displayQuestion, (answer) => {
21
+ rl.close();
22
+ resolve(answer.trim() || defaultValue || '');
23
+ });
24
+ });
25
+ }
26
+ /**
27
+ * Prompt user for yes/no confirmation
28
+ */
29
+ async function confirm(question, defaultValue = true) {
30
+ const defaultStr = defaultValue ? 'Y/n' : 'y/N';
31
+ const answer = await prompt(`${question} (${defaultStr})`);
32
+ if (!answer) {
33
+ return defaultValue;
34
+ }
35
+ return answer.toLowerCase().startsWith('y');
36
+ }
37
+ // -----------------------------------------------------------------------------
38
+ // API Validation
39
+ // -----------------------------------------------------------------------------
40
+ /**
41
+ * Validate API connection and authentication
42
+ */
43
+ async function validateApiConnection(apiUrl, apiKey) {
44
+ try {
45
+ const headers = {
46
+ 'Content-Type': 'application/json',
47
+ };
48
+ if (apiKey) {
49
+ headers['Authorization'] = `Bearer ${apiKey}`;
50
+ }
51
+ const response = await fetch(`${apiUrl}/health`, {
52
+ headers,
53
+ signal: AbortSignal.timeout(10000), // 10 second timeout
54
+ });
55
+ return response.ok;
56
+ }
57
+ catch (error) {
58
+ return false;
59
+ }
60
+ }
61
+ /**
62
+ * Register this system with the ClaudeTools API
63
+ */
64
+ async function registerSystem(config) {
65
+ try {
66
+ const hostname = require('os').hostname();
67
+ const platform = process.platform;
68
+ const cwd = process.cwd();
69
+ const response = await fetch(`${config.apiUrl}/api/v1/systems/register`, {
70
+ method: 'POST',
71
+ headers: {
72
+ 'Content-Type': 'application/json',
73
+ 'Authorization': config.apiKey ? `Bearer ${config.apiKey}` : '',
74
+ },
75
+ body: JSON.stringify({
76
+ name: hostname,
77
+ platform,
78
+ working_directory: cwd,
79
+ }),
80
+ });
81
+ if (!response.ok) {
82
+ throw new Error(`Registration failed: ${response.status} ${response.statusText}`);
83
+ }
84
+ const data = await response.json();
85
+ return data.system_id;
86
+ }
87
+ catch (error) {
88
+ throw new Error(`Failed to register system: ${error instanceof Error ? error.message : String(error)}`);
89
+ }
90
+ }
91
+ // -----------------------------------------------------------------------------
92
+ // Setup Wizard
93
+ // -----------------------------------------------------------------------------
94
+ export async function runSetup() {
95
+ console.log('\n🧠 ClaudeTools Memory Setup\n');
96
+ console.log('This wizard will guide you through the initial configuration.\n');
97
+ try {
98
+ // 1. Ensure config directory exists
99
+ await ensureConfigDir();
100
+ // 2. Load existing config or use defaults
101
+ const loadedConfig = await loadConfigFromFile();
102
+ // Merge with defaults to ensure all fields exist
103
+ let config = { ...DEFAULT_CONFIG, ...loadedConfig };
104
+ // 3. API URL configuration
105
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
106
+ console.log('API Configuration');
107
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
108
+ const useDefaultApi = await confirm(`Use default API URL (${DEFAULT_CONFIG.apiUrl})?`, true);
109
+ if (!useDefaultApi) {
110
+ const customApiUrl = await prompt('Enter custom API URL');
111
+ if (customApiUrl) {
112
+ config.apiUrl = customApiUrl;
113
+ }
114
+ }
115
+ // 4. API Key configuration
116
+ console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
117
+ console.log('Authentication');
118
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
119
+ if (config.apiKey) {
120
+ console.log(`Current API key: ${config.apiKey.substring(0, 10)}...`);
121
+ const replaceKey = await confirm('Replace existing API key?', false);
122
+ if (replaceKey) {
123
+ const newApiKey = await prompt('Enter new API key (from claudetools.dev/dashboard)');
124
+ if (newApiKey) {
125
+ config.apiKey = newApiKey;
126
+ }
127
+ }
128
+ }
129
+ else {
130
+ console.log('Get your API key from: https://claudetools.dev/dashboard\n');
131
+ const apiKey = await prompt('Enter API key (leave blank to skip)');
132
+ if (apiKey) {
133
+ config.apiKey = apiKey;
134
+ }
135
+ }
136
+ // 5. Validate API connection
137
+ console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
138
+ console.log('Validation');
139
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
140
+ console.log('Validating API connection...');
141
+ const isValid = await validateApiConnection(config.apiUrl || DEFAULT_CONFIG.apiUrl, config.apiKey);
142
+ if (!isValid) {
143
+ console.error('āŒ Could not connect to API.');
144
+ console.error(' Check your API URL and key, or continue without validation.\n');
145
+ const continueAnyway = await confirm('Continue anyway?', false);
146
+ if (!continueAnyway) {
147
+ console.log('\nSetup cancelled.');
148
+ process.exit(1);
149
+ }
150
+ }
151
+ else {
152
+ console.log('āœ… API connection validated');
153
+ }
154
+ // 6. Auto-inject context configuration
155
+ console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
156
+ console.log('Context Injection');
157
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
158
+ console.log('Auto-inject context automatically adds relevant memory to every request.');
159
+ console.log('This uses tokens but provides more contextual responses.\n');
160
+ const enableAutoInject = await confirm('Enable automatic context injection?', config.autoInjectContext);
161
+ config.autoInjectContext = enableAutoInject;
162
+ // 7. System registration (optional)
163
+ if (isValid && config.apiKey) {
164
+ console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
165
+ console.log('System Registration');
166
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
167
+ const shouldRegister = await confirm('Register this system?', true);
168
+ if (shouldRegister) {
169
+ try {
170
+ console.log('Registering system...');
171
+ const systemId = await registerSystem(config);
172
+ console.log(`āœ… System registered: ${systemId}`);
173
+ }
174
+ catch (error) {
175
+ console.error(`āŒ Registration failed: ${error instanceof Error ? error.message : String(error)}`);
176
+ console.error(' You can continue without registration.');
177
+ }
178
+ }
179
+ }
180
+ // 8. Save configuration
181
+ console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
182
+ console.log('Saving Configuration');
183
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
184
+ await saveConfig(config);
185
+ console.log(`āœ… Configuration saved to ${getConfigPath()}`);
186
+ // 9. Show next steps
187
+ console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
188
+ console.log('Next Steps');
189
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
190
+ console.log('1. Add to Claude Code MCP settings:');
191
+ console.log(' Location: ~/.claude/mcp.json\n');
192
+ console.log(' {');
193
+ console.log(' "mcpServers": {');
194
+ console.log(' "claudetools-memory": {');
195
+ console.log(' "command": "claudetools-memory"');
196
+ console.log(' }');
197
+ console.log(' }');
198
+ console.log(' }\n');
199
+ console.log('2. Restart Claude Code\n');
200
+ console.log('Done! šŸŽ‰\n');
201
+ }
202
+ catch (error) {
203
+ console.error('\nāŒ Setup failed:', error instanceof Error ? error.message : String(error));
204
+ process.exit(1);
205
+ }
206
+ }
@@ -0,0 +1,2 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ export declare function registerToolDefinitions(server: Server): void;