claude-memory-agent 2.0.1 → 2.2.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.
Files changed (97) hide show
  1. package/README.md +206 -206
  2. package/agent_card.py +186 -0
  3. package/bin/cli.js +327 -185
  4. package/bin/lib/banner.js +39 -0
  5. package/bin/lib/environment.js +166 -0
  6. package/bin/lib/installer.js +291 -0
  7. package/bin/lib/models.js +95 -0
  8. package/bin/lib/steps/advanced.js +101 -0
  9. package/bin/lib/steps/confirm.js +87 -0
  10. package/bin/lib/steps/model.js +57 -0
  11. package/bin/lib/steps/provider.js +65 -0
  12. package/bin/lib/steps/scope.js +59 -0
  13. package/bin/lib/steps/server.js +74 -0
  14. package/bin/lib/ui.js +75 -0
  15. package/bin/onboarding.js +164 -0
  16. package/bin/postinstall.js +35 -270
  17. package/config.py +103 -4
  18. package/dashboard.html +4902 -2689
  19. package/hooks/extract_memories.py +439 -0
  20. package/hooks/grounding-hook.py +422 -348
  21. package/hooks/pre_compact_hook.py +76 -0
  22. package/hooks/session_end.py +293 -192
  23. package/hooks/session_end_hook.py +149 -0
  24. package/hooks/session_start.py +227 -227
  25. package/hooks/stop_hook.py +372 -0
  26. package/install.py +972 -902
  27. package/main.py +5240 -2859
  28. package/mcp_server.py +451 -0
  29. package/package.json +58 -47
  30. package/requirements.txt +12 -8
  31. package/services/__init__.py +50 -50
  32. package/services/adaptive_ranker.py +272 -0
  33. package/services/agent_catalog.json +153 -0
  34. package/services/agent_registry.py +245 -730
  35. package/services/claude_md_sync.py +320 -4
  36. package/services/consolidation.py +417 -0
  37. package/services/curator.py +1606 -0
  38. package/services/database.py +4118 -2485
  39. package/services/embedding_pipeline.py +262 -0
  40. package/services/embeddings.py +493 -85
  41. package/services/memory_decay.py +408 -0
  42. package/services/native_memory_paths.py +86 -0
  43. package/services/native_memory_sync.py +496 -0
  44. package/services/response_manager.py +183 -0
  45. package/services/terminal_ui.py +199 -0
  46. package/services/tier_manager.py +235 -0
  47. package/services/websocket.py +26 -6
  48. package/skills/__init__.py +21 -1
  49. package/skills/confidence_tracker.py +441 -0
  50. package/skills/context.py +675 -0
  51. package/skills/curator.py +348 -0
  52. package/skills/search.py +444 -213
  53. package/skills/session_review.py +605 -0
  54. package/skills/store.py +484 -179
  55. package/terminal_dashboard.py +474 -0
  56. package/update_system.py +829 -817
  57. package/hooks/__pycache__/auto-detect-response.cpython-312.pyc +0 -0
  58. package/hooks/__pycache__/auto_capture.cpython-312.pyc +0 -0
  59. package/hooks/__pycache__/session_end.cpython-312.pyc +0 -0
  60. package/hooks/__pycache__/session_start.cpython-312.pyc +0 -0
  61. package/services/__pycache__/__init__.cpython-312.pyc +0 -0
  62. package/services/__pycache__/agent_registry.cpython-312.pyc +0 -0
  63. package/services/__pycache__/auth.cpython-312.pyc +0 -0
  64. package/services/__pycache__/auto_inject.cpython-312.pyc +0 -0
  65. package/services/__pycache__/claude_md_sync.cpython-312.pyc +0 -0
  66. package/services/__pycache__/cleanup.cpython-312.pyc +0 -0
  67. package/services/__pycache__/compaction_flush.cpython-312.pyc +0 -0
  68. package/services/__pycache__/confidence.cpython-312.pyc +0 -0
  69. package/services/__pycache__/daily_log.cpython-312.pyc +0 -0
  70. package/services/__pycache__/database.cpython-312.pyc +0 -0
  71. package/services/__pycache__/embeddings.cpython-312.pyc +0 -0
  72. package/services/__pycache__/insights.cpython-312.pyc +0 -0
  73. package/services/__pycache__/llm_analyzer.cpython-312.pyc +0 -0
  74. package/services/__pycache__/memory_md_sync.cpython-312.pyc +0 -0
  75. package/services/__pycache__/retry_queue.cpython-312.pyc +0 -0
  76. package/services/__pycache__/timeline.cpython-312.pyc +0 -0
  77. package/services/__pycache__/vector_index.cpython-312.pyc +0 -0
  78. package/services/__pycache__/websocket.cpython-312.pyc +0 -0
  79. package/skills/__pycache__/__init__.cpython-312.pyc +0 -0
  80. package/skills/__pycache__/admin.cpython-312.pyc +0 -0
  81. package/skills/__pycache__/checkpoint.cpython-312.pyc +0 -0
  82. package/skills/__pycache__/claude_md.cpython-312.pyc +0 -0
  83. package/skills/__pycache__/cleanup.cpython-312.pyc +0 -0
  84. package/skills/__pycache__/grounding.cpython-312.pyc +0 -0
  85. package/skills/__pycache__/insights.cpython-312.pyc +0 -0
  86. package/skills/__pycache__/natural_language.cpython-312.pyc +0 -0
  87. package/skills/__pycache__/retrieve.cpython-312.pyc +0 -0
  88. package/skills/__pycache__/search.cpython-312.pyc +0 -0
  89. package/skills/__pycache__/state.cpython-312.pyc +0 -0
  90. package/skills/__pycache__/store.cpython-312.pyc +0 -0
  91. package/skills/__pycache__/summarize.cpython-312.pyc +0 -0
  92. package/skills/__pycache__/timeline.cpython-312.pyc +0 -0
  93. package/skills/__pycache__/verification.cpython-312.pyc +0 -0
  94. package/test_automation.py +0 -221
  95. package/test_complete.py +0 -338
  96. package/test_full.py +0 -322
  97. package/verify_db.py +0 -134
package/bin/cli.js CHANGED
@@ -1,185 +1,327 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Claude Memory Agent CLI
5
- *
6
- * This is the npm entry point that wraps the Python CLI.
7
- * Usage:
8
- * claude-memory-agent install - Run installation wizard
9
- * claude-memory-agent start - Start the agent
10
- * claude-memory-agent stop - Stop the agent
11
- * claude-memory-agent status - Check status
12
- * claude-memory-agent dashboard - Open dashboard
13
- */
14
-
15
- const { spawn, execSync } = require('child_process');
16
- const path = require('path');
17
- const fs = require('fs');
18
-
19
- const AGENT_DIR = path.dirname(__dirname);
20
- const args = process.argv.slice(2);
21
- const command = args[0] || 'help';
22
-
23
- // Check Python availability
24
- function getPython() {
25
- const pythonCommands = ['python3', 'python', 'py'];
26
-
27
- for (const cmd of pythonCommands) {
28
- try {
29
- const result = execSync(`${cmd} --version`, {
30
- encoding: 'utf8',
31
- stdio: ['pipe', 'pipe', 'pipe']
32
- });
33
- if (result.includes('Python 3')) {
34
- return cmd;
35
- }
36
- } catch (e) {
37
- continue;
38
- }
39
- }
40
- return null;
41
- }
42
-
43
- // Check if Python dependencies are installed
44
- function checkDependencies(python) {
45
- try {
46
- execSync(`${python} -c "import fastapi, uvicorn, dotenv"`, {
47
- cwd: AGENT_DIR,
48
- stdio: ['pipe', 'pipe', 'pipe']
49
- });
50
- return true;
51
- } catch (e) {
52
- return false;
53
- }
54
- }
55
-
56
- // Install Python dependencies
57
- function installDependencies(python) {
58
- console.log('Installing Python dependencies...');
59
- try {
60
- execSync(`${python} -m pip install -r requirements.txt -q`, {
61
- cwd: AGENT_DIR,
62
- stdio: 'inherit'
63
- });
64
- return true;
65
- } catch (e) {
66
- console.error('Failed to install dependencies:', e.message);
67
- return false;
68
- }
69
- }
70
-
71
- // Run Python script
72
- function runPython(script, scriptArgs = []) {
73
- const python = getPython();
74
-
75
- if (!python) {
76
- console.error('Error: Python 3 is required but not found.');
77
- console.error('Please install Python 3.9+ from https://python.org/');
78
- process.exit(1);
79
- }
80
-
81
- const proc = spawn(python, [script, ...scriptArgs], {
82
- cwd: AGENT_DIR,
83
- stdio: 'inherit',
84
- shell: process.platform === 'win32'
85
- });
86
-
87
- proc.on('close', (code) => {
88
- process.exit(code || 0);
89
- });
90
-
91
- proc.on('error', (err) => {
92
- console.error('Failed to start:', err.message);
93
- process.exit(1);
94
- });
95
- }
96
-
97
- // Print help
98
- function printHelp() {
99
- console.log(`
100
- Claude Memory Agent v2.0.0
101
- Persistent semantic memory for Claude Code sessions
102
-
103
- USAGE:
104
- claude-memory-agent <command> [options]
105
-
106
- COMMANDS:
107
- install Run the installation wizard
108
- start Start the memory agent in background
109
- stop Stop the running agent
110
- status Check if agent is running
111
- dashboard Open the web dashboard
112
- logs Show recent log output
113
- help Show this help message
114
-
115
- QUICK START:
116
- 1. Install Ollama: https://ollama.ai/download
117
- 2. Pull embedding model: ollama pull nomic-embed-text
118
- 3. Start Ollama: ollama serve
119
- 4. Configure: claude-memory-agent install
120
- 5. Start agent: claude-memory-agent start
121
- 6. Open dashboard: claude-memory-agent dashboard
122
-
123
- REQUIREMENTS:
124
- - Python 3.9+ (https://python.org)
125
- - Ollama (https://ollama.ai)
126
- - nomic-embed-text (ollama pull nomic-embed-text)
127
- - Claude Code (npm install -g @anthropic-ai/claude-code)
128
-
129
- For more info: https://www.npmjs.com/package/claude-memory-agent
130
- `);
131
- }
132
-
133
- // Main
134
- function main() {
135
- switch (command) {
136
- case 'install':
137
- case 'setup':
138
- runPython('install.py', args.slice(1));
139
- break;
140
-
141
- case 'start':
142
- runPython('memory-agent', ['start', ...args.slice(1)]);
143
- break;
144
-
145
- case 'stop':
146
- runPython('memory-agent', ['stop', ...args.slice(1)]);
147
- break;
148
-
149
- case 'status':
150
- runPython('memory-agent', ['status', ...args.slice(1)]);
151
- break;
152
-
153
- case 'dashboard':
154
- runPython('memory-agent', ['dashboard', ...args.slice(1)]);
155
- break;
156
-
157
- case 'logs':
158
- runPython('memory-agent', ['logs', ...args.slice(1)]);
159
- break;
160
-
161
- case 'run':
162
- case 'server':
163
- // Run directly (not in background)
164
- runPython('main.py', args.slice(1));
165
- break;
166
-
167
- case 'help':
168
- case '--help':
169
- case '-h':
170
- printHelp();
171
- break;
172
-
173
- case '--version':
174
- case '-v':
175
- console.log('claude-memory-agent v2.0.0');
176
- break;
177
-
178
- default:
179
- console.error(`Unknown command: ${command}`);
180
- console.error('Run "claude-memory-agent help" for usage.');
181
- process.exit(1);
182
- }
183
- }
184
-
185
- main();
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Claude Memory Agent CLI
5
+ *
6
+ * This is the npm entry point that wraps the Python CLI.
7
+ * Usage:
8
+ * claude-memory-agent install - Run installation wizard
9
+ * claude-memory-agent start - Start the agent
10
+ * claude-memory-agent stop - Stop the agent
11
+ * claude-memory-agent status - Check status
12
+ * claude-memory-agent dashboard - Open dashboard
13
+ */
14
+
15
+ const { spawn, execSync } = require('child_process');
16
+ const path = require('path');
17
+ const fs = require('fs');
18
+
19
+ const AGENT_DIR = path.dirname(__dirname);
20
+ const args = process.argv.slice(2);
21
+ const command = args[0] || 'help';
22
+
23
+ // Check Python availability
24
+ function getPython() {
25
+ const pythonCommands = ['python3', 'python', 'py'];
26
+
27
+ for (const cmd of pythonCommands) {
28
+ try {
29
+ const result = execSync(`${cmd} --version`, {
30
+ encoding: 'utf8',
31
+ stdio: ['pipe', 'pipe', 'pipe']
32
+ });
33
+ if (result.includes('Python 3')) {
34
+ return cmd;
35
+ }
36
+ } catch (e) {
37
+ continue;
38
+ }
39
+ }
40
+ return null;
41
+ }
42
+
43
+ // Check if Python dependencies are installed
44
+ function checkDependencies(python) {
45
+ try {
46
+ execSync(`${python} -c "import fastapi, uvicorn, dotenv"`, {
47
+ cwd: AGENT_DIR,
48
+ stdio: ['pipe', 'pipe', 'pipe']
49
+ });
50
+ return true;
51
+ } catch (e) {
52
+ return false;
53
+ }
54
+ }
55
+
56
+ // Install Python dependencies
57
+ function installDependencies(python) {
58
+ console.log('Installing Python dependencies...');
59
+ try {
60
+ execSync(`${python} -m pip install -r requirements.txt -q`, {
61
+ cwd: AGENT_DIR,
62
+ stdio: 'inherit'
63
+ });
64
+ return true;
65
+ } catch (e) {
66
+ console.error('Failed to install dependencies:', e.message);
67
+ return false;
68
+ }
69
+ }
70
+
71
+ // Run Python script
72
+ function runPython(script, scriptArgs = []) {
73
+ const python = getPython();
74
+
75
+ if (!python) {
76
+ console.error('Error: Python 3 is required but not found.');
77
+ console.error('Please install Python 3.9+ from https://python.org/');
78
+ process.exit(1);
79
+ }
80
+
81
+ const proc = spawn(python, [script, ...scriptArgs], {
82
+ cwd: AGENT_DIR,
83
+ stdio: 'inherit',
84
+ shell: process.platform === 'win32'
85
+ });
86
+
87
+ proc.on('close', (code) => {
88
+ process.exit(code || 0);
89
+ });
90
+
91
+ proc.on('error', (err) => {
92
+ console.error('Failed to start:', err.message);
93
+ process.exit(1);
94
+ });
95
+ }
96
+
97
+ // Doctor - diagnose issues (async)
98
+ async function runDoctor() {
99
+ console.log('\n🩺 Claude Memory Agent - System Check\n');
100
+ console.log('='.repeat(50));
101
+
102
+ let issues = 0;
103
+ let warnings = 0;
104
+
105
+ // Check Python
106
+ process.stdout.write('Python 3.9+........... ');
107
+ const python = getPython();
108
+ if (python) {
109
+ console.log('✓ OK');
110
+ } else {
111
+ console.log('✗ NOT FOUND');
112
+ console.log(' Install from: https://python.org/');
113
+ issues++;
114
+ }
115
+
116
+ // Check Ollama
117
+ process.stdout.write('Ollama................ ');
118
+ const ollamaOk = await checkUrl('http://localhost:11434/api/tags');
119
+ if (ollamaOk) {
120
+ console.log('✓ Running');
121
+ } else {
122
+ console.log('✗ NOT RUNNING');
123
+ console.log(' Install from: https://ollama.ai/download');
124
+ console.log(' Then run: ollama serve');
125
+ issues++;
126
+ }
127
+
128
+ // Check embedding model
129
+ if (ollamaOk) {
130
+ process.stdout.write('Embedding model....... ');
131
+ const modelOk = await checkOllamaModel();
132
+ if (modelOk) {
133
+ console.log('✓ nomic-embed-text');
134
+ } else {
135
+ console.log('✗ NOT INSTALLED');
136
+ console.log(' Run: ollama pull nomic-embed-text');
137
+ issues++;
138
+ }
139
+ }
140
+
141
+ // Check Memory Agent
142
+ process.stdout.write('Memory Agent.......... ');
143
+ const agentOk = await checkUrl('http://localhost:8102/health');
144
+ if (agentOk) {
145
+ console.log('✓ Running');
146
+ } else {
147
+ console.log('✗ NOT RUNNING');
148
+ console.log(' Run: claude-memory-agent start');
149
+ warnings++;
150
+ }
151
+
152
+ // Check .env file
153
+ process.stdout.write('.env file............. ');
154
+ if (fs.existsSync(path.join(AGENT_DIR, '.env'))) {
155
+ console.log('✓ Exists');
156
+ } else {
157
+ console.log('✗ MISSING');
158
+ console.log(' Run: claude-memory-agent install');
159
+ issues++;
160
+ }
161
+
162
+ // Summary
163
+ console.log('\n' + '='.repeat(50));
164
+ if (issues === 0 && warnings === 0) {
165
+ console.log('✅ All systems operational!\n');
166
+ } else if (issues === 0) {
167
+ console.log(`⚠️ ${warnings} warning(s) - agent may not be running\n`);
168
+ } else {
169
+ console.log(`❌ ${issues} issue(s) found - fix above problems\n`);
170
+ }
171
+ }
172
+
173
+ // Helper: Check if URL responds
174
+ function checkUrl(url) {
175
+ return new Promise((resolve) => {
176
+ const http = require('http');
177
+ const req = http.get(url, { timeout: 2000 }, (res) => {
178
+ resolve(res.statusCode === 200);
179
+ });
180
+ req.on('error', () => resolve(false));
181
+ req.on('timeout', () => { req.destroy(); resolve(false); });
182
+ });
183
+ }
184
+
185
+ // Helper: Check if Ollama has embedding model
186
+ function checkOllamaModel() {
187
+ return new Promise((resolve) => {
188
+ const http = require('http');
189
+ http.get('http://localhost:11434/api/tags', (res) => {
190
+ let data = '';
191
+ res.on('data', chunk => data += chunk);
192
+ res.on('end', () => {
193
+ try {
194
+ const json = JSON.parse(data);
195
+ const models = json.models || [];
196
+ const hasModel = models.some(m => m.name && m.name.includes('nomic-embed-text'));
197
+ resolve(hasModel);
198
+ } catch (e) {
199
+ resolve(false);
200
+ }
201
+ });
202
+ }).on('error', () => resolve(false));
203
+ });
204
+ }
205
+
206
+ // Print help
207
+ function printHelp() {
208
+ console.log(`
209
+ Claude Memory Agent v2.0.1
210
+ Persistent semantic memory for Claude Code sessions
211
+
212
+ USAGE:
213
+ claude-memory-agent <command> [options]
214
+
215
+ COMMANDS:
216
+ install Run the installation wizard
217
+ start Start the memory agent in background
218
+ stop Stop the running agent
219
+ restart Restart the memory agent
220
+ status Check if agent is running
221
+ dashboard Open the web dashboard
222
+ logs Show recent log output
223
+ doctor Diagnose issues and check requirements
224
+ uninstall Remove Claude Code integration
225
+ help Show this help message
226
+
227
+ QUICK START:
228
+ 1. Install Ollama: https://ollama.ai/download
229
+ 2. Pull embedding model: ollama pull nomic-embed-text
230
+ 3. Start Ollama: ollama serve
231
+ 4. Configure: claude-memory-agent install
232
+ 5. Start agent: claude-memory-agent start
233
+ 6. Open dashboard: claude-memory-agent dashboard
234
+
235
+ REQUIREMENTS:
236
+ - Python 3.9+ (https://python.org)
237
+ - Ollama (https://ollama.ai)
238
+ - nomic-embed-text (ollama pull nomic-embed-text)
239
+ - Claude Code (npm install -g @anthropic-ai/claude-code)
240
+
241
+ For more info: https://www.npmjs.com/package/claude-memory-agent
242
+ `);
243
+ }
244
+
245
+ // Main
246
+ function main() {
247
+ switch (command) {
248
+ case 'install':
249
+ case 'setup':
250
+ // Run the onboarding wizard
251
+ try {
252
+ const { main: runOnboarding } = require('./onboarding');
253
+ runOnboarding().catch(err => {
254
+ console.error('Setup error:', err.message);
255
+ process.exit(1);
256
+ });
257
+ } catch (e) {
258
+ // Fallback to Python installer if onboarding deps missing
259
+ runPython('install.py', args.slice(1));
260
+ }
261
+ break;
262
+
263
+ case 'start':
264
+ runPython('memory-agent', ['start', ...args.slice(1)]);
265
+ break;
266
+
267
+ case 'stop':
268
+ runPython('memory-agent', ['stop', ...args.slice(1)]);
269
+ break;
270
+
271
+ case 'status':
272
+ runPython('memory-agent', ['status', ...args.slice(1)]);
273
+ break;
274
+
275
+ case 'dashboard':
276
+ runPython('memory-agent', ['dashboard', ...args.slice(1)]);
277
+ break;
278
+
279
+ case 'logs':
280
+ runPython('memory-agent', ['logs', ...args.slice(1)]);
281
+ break;
282
+
283
+ case 'restart':
284
+ // Stop then start
285
+ console.log('Restarting Memory Agent...');
286
+ try {
287
+ execSync(`${getPython()} memory-agent stop`, { cwd: AGENT_DIR, stdio: 'inherit', shell: process.platform === 'win32' });
288
+ } catch (e) { /* ignore stop errors */ }
289
+ setTimeout(() => {
290
+ runPython('memory-agent', ['start']);
291
+ }, 1000);
292
+ break;
293
+
294
+ case 'doctor':
295
+ case 'diagnose':
296
+ runDoctor();
297
+ break;
298
+
299
+ case 'uninstall':
300
+ runPython('install.py', ['--uninstall']);
301
+ break;
302
+
303
+ case 'run':
304
+ case 'server':
305
+ // Run directly (not in background)
306
+ runPython('main.py', args.slice(1));
307
+ break;
308
+
309
+ case 'help':
310
+ case '--help':
311
+ case '-h':
312
+ printHelp();
313
+ break;
314
+
315
+ case '--version':
316
+ case '-v':
317
+ console.log('claude-memory-agent v2.0.0');
318
+ break;
319
+
320
+ default:
321
+ console.error(`Unknown command: ${command}`);
322
+ console.error('Run "claude-memory-agent help" for usage.');
323
+ process.exit(1);
324
+ }
325
+ }
326
+
327
+ main();
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ const chalk = require('chalk');
4
+ const gradient = require('gradient-string');
5
+
6
+ const BANNER = `
7
+ ██████╗██╗ █████╗ ██╗ ██╗██████╗ ███████╗
8
+ ██╔════╝██║ ██╔══██╗██║ ██║██╔══██╗██╔════╝
9
+ ██║ ██║ ███████║██║ ██║██║ ██║█████╗
10
+ ██║ ██║ ██╔══██║██║ ██║██║ ██║██╔══╝
11
+ ╚██████╗███████╗██║ ██║╚██████╔╝██████╔╝███████╗
12
+ ╚═════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝
13
+ ███╗ ███╗███████╗███╗ ███╗ ██████╗ ██████╗ ██╗ ██╗
14
+ ████╗ ████║██╔════╝████╗ ████║██╔═══██╗██╔══██╗╚██╗ ██╔╝
15
+ ██╔████╔██║█████╗ ██╔████╔██║██║ ██║██████╔╝ ╚████╔╝
16
+ ██║╚██╔╝██║██╔══╝ ██║╚██╔╝██║██║ ██║██╔══██╗ ╚██╔╝
17
+ ██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║╚██████╔╝██║ ██║ ██║
18
+ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝`;
19
+
20
+ const VERSION = 'v2.1.0';
21
+
22
+ /**
23
+ * Print the Claude Memory Agent ASCII art banner with gradient coloring.
24
+ * Uses a cool blue-to-purple gradient (mind -> cristal).
25
+ */
26
+ function printBanner() {
27
+ const coolGradient = gradient(['#0575E6', '#7B68EE', '#A855F7', '#6C63FF']);
28
+ console.log(coolGradient(BANNER));
29
+
30
+ // Center the version string beneath the banner
31
+ const bannerWidth = 56; // approximate width of the widest banner line
32
+ const padding = Math.max(0, Math.floor((bannerWidth - VERSION.length) / 2));
33
+ const centeredVersion = ' '.repeat(padding) + VERSION;
34
+ console.log('');
35
+ console.log(chalk.dim(centeredVersion));
36
+ console.log('');
37
+ }
38
+
39
+ module.exports = { printBanner };