@grafema/cli 0.2.2-beta → 0.2.4-beta

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.
@@ -1 +1 @@
1
- {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgLpC,eAAO,MAAM,cAAc,SAqKvB,CAAC"}
1
+ {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgLpC,eAAO,MAAM,cAAc,SAgMvB,CAAC"}
@@ -135,6 +135,7 @@ export const analyzeCommand = new Command('analyze')
135
135
  .option('--debug', 'Enable debug mode (writes diagnostics.log)')
136
136
  .option('--log-level <level>', 'Set log level (silent, errors, warnings, info, debug)')
137
137
  .option('--strict', 'Enable strict mode (fail on unresolved references)')
138
+ .option('--auto-start', 'Auto-start RFDB server if not running')
138
139
  .addHelpText('after', `
139
140
  Examples:
140
141
  grafema analyze Analyze current project
@@ -144,6 +145,9 @@ Examples:
144
145
  grafema analyze -v Verbose output with progress details
145
146
  grafema analyze --debug Write diagnostics.log for debugging
146
147
  grafema analyze --strict Fail on unresolved references (debugging)
148
+ grafema analyze --auto-start Auto-start server (useful for CI)
149
+
150
+ Note: Start the server first with: grafema server start
147
151
  `)
148
152
  .action(async (path, options) => {
149
153
  const projectPath = resolve(path);
@@ -157,8 +161,31 @@ Examples:
157
161
  const logLevel = getLogLevel(options);
158
162
  const logger = createLogger(logLevel);
159
163
  log(`Analyzing project: ${projectPath}`);
160
- const backend = new RFDBServerBackend({ dbPath });
161
- await backend.connect();
164
+ // Connect to RFDB server
165
+ // Default: require explicit `grafema server start`
166
+ // Use --auto-start for CI or backwards compatibility
167
+ const backend = new RFDBServerBackend({
168
+ dbPath,
169
+ autoStart: options.autoStart ?? false
170
+ });
171
+ try {
172
+ await backend.connect();
173
+ }
174
+ catch (err) {
175
+ if (!options.autoStart && err instanceof Error && err.message.includes('not running')) {
176
+ console.error('');
177
+ console.error('RFDB server is not running.');
178
+ console.error('');
179
+ console.error('Start the server first:');
180
+ console.error(' grafema server start');
181
+ console.error('');
182
+ console.error('Or use --auto-start flag:');
183
+ console.error(' grafema analyze --auto-start');
184
+ console.error('');
185
+ process.exit(1);
186
+ }
187
+ throw err;
188
+ }
162
189
  if (options.clear) {
163
190
  log('Clearing existing database...');
164
191
  await backend.clear();
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+FpC,eAAO,MAAM,aAAa,SAQxB,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgDpC,eAAO,MAAM,aAAa,SAaxB,CAAC"}
@@ -7,60 +7,12 @@
7
7
  * grafema server status - Check if server is running
8
8
  */
9
9
  import { Command } from 'commander';
10
- import { resolve, join, dirname } from 'path';
10
+ import { resolve, join } from 'path';
11
11
  import { existsSync, unlinkSync, writeFileSync, readFileSync } from 'fs';
12
12
  import { spawn } from 'child_process';
13
- import { fileURLToPath } from 'url';
14
13
  import { setTimeout as sleep } from 'timers/promises';
15
- import { RFDBClient } from '@grafema/core';
14
+ import { RFDBClient, loadConfig, findRfdbBinary, getBinaryNotFoundMessage } from '@grafema/core';
16
15
  import { exitWithError } from '../utils/errorFormatter.js';
17
- const __filename = fileURLToPath(import.meta.url);
18
- const __dirname = dirname(__filename);
19
- /**
20
- * Find RFDB server binary in order of preference:
21
- * 1. @grafema/rfdb npm package
22
- * 2. packages/rfdb-server/target/release (monorepo development)
23
- * 3. packages/rfdb-server/target/debug
24
- */
25
- function findServerBinary() {
26
- // 1. Check @grafema/rfdb npm package
27
- try {
28
- const rfdbPkg = require.resolve('@grafema/rfdb');
29
- const rfdbDir = dirname(rfdbPkg);
30
- const platform = process.platform;
31
- const arch = process.arch;
32
- let platformDir;
33
- if (platform === 'darwin') {
34
- platformDir = arch === 'arm64' ? 'darwin-arm64' : 'darwin-x64';
35
- }
36
- else if (platform === 'linux') {
37
- platformDir = arch === 'arm64' ? 'linux-arm64' : 'linux-x64';
38
- }
39
- else {
40
- platformDir = `${platform}-${arch}`;
41
- }
42
- const npmBinary = join(rfdbDir, 'prebuilt', platformDir, 'rfdb-server');
43
- if (existsSync(npmBinary)) {
44
- return npmBinary;
45
- }
46
- }
47
- catch {
48
- // @grafema/rfdb not installed
49
- }
50
- // 2. Check packages/rfdb-server in monorepo
51
- // From packages/cli/dist/commands -> project root is 4 levels up
52
- const projectRoot = join(__dirname, '../../../..');
53
- const releaseBinary = join(projectRoot, 'packages/rfdb-server/target/release/rfdb-server');
54
- if (existsSync(releaseBinary)) {
55
- return releaseBinary;
56
- }
57
- // 3. Check debug build
58
- const debugBinary = join(projectRoot, 'packages/rfdb-server/target/debug/rfdb-server');
59
- if (existsSync(debugBinary)) {
60
- return debugBinary;
61
- }
62
- return null;
63
- }
64
16
  /**
65
17
  * Check if server is running by attempting to ping it
66
18
  */
@@ -97,16 +49,22 @@ export const serverCommand = new Command('server')
97
49
  .description('Manage RFDB server lifecycle')
98
50
  .addHelpText('after', `
99
51
  Examples:
100
- grafema server start Start the RFDB server (detached)
101
- grafema server stop Stop the running server
102
- grafema server status Check if server is running
103
- grafema server status --json Server status as JSON
52
+ grafema server start Start the RFDB server
53
+ grafema server start --binary /path/to/bin Start with specific binary
54
+ grafema server stop Stop the running server
55
+ grafema server status Check if server is running
56
+ grafema server status --json Server status as JSON
57
+
58
+ Config (in .grafema/config.yaml):
59
+ server:
60
+ binaryPath: /path/to/rfdb-server # Optional: path to binary
104
61
  `);
105
62
  // grafema server start
106
63
  serverCommand
107
64
  .command('start')
108
65
  .description('Start the RFDB server')
109
66
  .option('-p, --project <path>', 'Project path', '.')
67
+ .option('-b, --binary <path>', 'Path to rfdb-server binary')
110
68
  .action(async (options) => {
111
69
  const projectPath = resolve(options.project);
112
70
  const { grafemaDir, socketPath, dbPath, pidPath } = getProjectPaths(projectPath);
@@ -130,15 +88,37 @@ serverCommand
130
88
  if (existsSync(socketPath)) {
131
89
  unlinkSync(socketPath);
132
90
  }
133
- // Find server binary
134
- const binaryPath = findServerBinary();
91
+ // Determine binary path: CLI flag > config > auto-detect
92
+ let explicitPath;
93
+ if (options.binary) {
94
+ // Explicit --binary flag
95
+ explicitPath = options.binary;
96
+ }
97
+ else {
98
+ // Try to read from config
99
+ try {
100
+ const config = loadConfig(projectPath);
101
+ const serverConfig = config.server;
102
+ if (serverConfig?.binaryPath) {
103
+ explicitPath = serverConfig.binaryPath;
104
+ }
105
+ }
106
+ catch {
107
+ // Config not found or invalid - continue with auto-detect
108
+ }
109
+ }
110
+ const binaryPath = findRfdbBinary({ explicitPath });
135
111
  if (!binaryPath) {
136
- exitWithError('RFDB server binary not found', [
137
- 'Install: npm install @grafema/rfdb',
138
- 'Or build: cargo build --release --bin rfdb-server'
139
- ]);
112
+ // If explicit path was given but not found, show specific error
113
+ if (explicitPath) {
114
+ exitWithError(`Specified binary not found: ${resolve(explicitPath)}`, [
115
+ 'Check the path and try again'
116
+ ]);
117
+ }
118
+ exitWithError('RFDB server binary not found', getBinaryNotFoundMessage().split('\n').slice(2));
140
119
  }
141
120
  console.log(`Starting RFDB server...`);
121
+ console.log(` Binary: ${binaryPath}`);
142
122
  console.log(` Database: ${dbPath}`);
143
123
  console.log(` Socket: ${socketPath}`);
144
124
  // Start server
@@ -152,16 +132,17 @@ serverCommand
152
132
  if (serverProcess.pid) {
153
133
  writeFileSync(pidPath, String(serverProcess.pid));
154
134
  }
155
- // Wait for socket to appear
135
+ // Wait for socket to appear (increased timeout for slow systems)
156
136
  let attempts = 0;
157
- while (!existsSync(socketPath) && attempts < 50) {
137
+ while (!existsSync(socketPath) && attempts < 100) {
158
138
  await sleep(100);
159
139
  attempts++;
160
140
  }
161
141
  if (!existsSync(socketPath)) {
162
142
  exitWithError('Server failed to start', [
163
143
  'Check if database path is valid',
164
- 'Check server logs for errors'
144
+ 'Check server logs for errors',
145
+ `Binary used: ${binaryPath}`
165
146
  ]);
166
147
  }
167
148
  // Verify server is responsive
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafema/cli",
3
- "version": "0.2.2-beta",
3
+ "version": "0.2.4-beta",
4
4
  "description": "CLI for Grafema code analysis toolkit",
5
5
  "type": "module",
6
6
  "main": "./dist/cli.js",
@@ -37,8 +37,8 @@
37
37
  "ink-text-input": "^6.0.0",
38
38
  "react": "^19.2.3",
39
39
  "yaml": "^2.8.2",
40
- "@grafema/core": "0.2.1-beta",
41
- "@grafema/types": "0.2.1-beta"
40
+ "@grafema/core": "0.2.4-beta",
41
+ "@grafema/types": "0.2.4-beta"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^25.0.8",
@@ -189,6 +189,7 @@ export const analyzeCommand = new Command('analyze')
189
189
  .option('--debug', 'Enable debug mode (writes diagnostics.log)')
190
190
  .option('--log-level <level>', 'Set log level (silent, errors, warnings, info, debug)')
191
191
  .option('--strict', 'Enable strict mode (fail on unresolved references)')
192
+ .option('--auto-start', 'Auto-start RFDB server if not running')
192
193
  .addHelpText('after', `
193
194
  Examples:
194
195
  grafema analyze Analyze current project
@@ -198,8 +199,11 @@ Examples:
198
199
  grafema analyze -v Verbose output with progress details
199
200
  grafema analyze --debug Write diagnostics.log for debugging
200
201
  grafema analyze --strict Fail on unresolved references (debugging)
202
+ grafema analyze --auto-start Auto-start server (useful for CI)
203
+
204
+ Note: Start the server first with: grafema server start
201
205
  `)
202
- .action(async (path: string, options: { service?: string; entrypoint?: string; clear?: boolean; quiet?: boolean; verbose?: boolean; debug?: boolean; logLevel?: string; strict?: boolean }) => {
206
+ .action(async (path: string, options: { service?: string; entrypoint?: string; clear?: boolean; quiet?: boolean; verbose?: boolean; debug?: boolean; logLevel?: string; strict?: boolean; autoStart?: boolean }) => {
203
207
  const projectPath = resolve(path);
204
208
  const grafemaDir = join(projectPath, '.grafema');
205
209
  const dbPath = join(grafemaDir, 'graph.rfdb');
@@ -216,8 +220,31 @@ Examples:
216
220
 
217
221
  log(`Analyzing project: ${projectPath}`);
218
222
 
219
- const backend = new RFDBServerBackend({ dbPath });
220
- await backend.connect();
223
+ // Connect to RFDB server
224
+ // Default: require explicit `grafema server start`
225
+ // Use --auto-start for CI or backwards compatibility
226
+ const backend = new RFDBServerBackend({
227
+ dbPath,
228
+ autoStart: options.autoStart ?? false
229
+ });
230
+
231
+ try {
232
+ await backend.connect();
233
+ } catch (err) {
234
+ if (!options.autoStart && err instanceof Error && err.message.includes('not running')) {
235
+ console.error('');
236
+ console.error('RFDB server is not running.');
237
+ console.error('');
238
+ console.error('Start the server first:');
239
+ console.error(' grafema server start');
240
+ console.error('');
241
+ console.error('Or use --auto-start flag:');
242
+ console.error(' grafema analyze --auto-start');
243
+ console.error('');
244
+ process.exit(1);
245
+ }
246
+ throw err;
247
+ }
221
248
 
222
249
  if (options.clear) {
223
250
  log('Clearing existing database...');
@@ -8,63 +8,16 @@
8
8
  */
9
9
 
10
10
  import { Command } from 'commander';
11
- import { resolve, join, dirname } from 'path';
11
+ import { resolve, join } from 'path';
12
12
  import { existsSync, unlinkSync, writeFileSync, readFileSync } from 'fs';
13
13
  import { spawn } from 'child_process';
14
- import { fileURLToPath } from 'url';
15
14
  import { setTimeout as sleep } from 'timers/promises';
16
- import { RFDBClient } from '@grafema/core';
15
+ import { RFDBClient, loadConfig, findRfdbBinary, getBinaryNotFoundMessage } from '@grafema/core';
17
16
  import { exitWithError } from '../utils/errorFormatter.js';
18
17
 
19
- const __filename = fileURLToPath(import.meta.url);
20
- const __dirname = dirname(__filename);
21
-
22
- /**
23
- * Find RFDB server binary in order of preference:
24
- * 1. @grafema/rfdb npm package
25
- * 2. packages/rfdb-server/target/release (monorepo development)
26
- * 3. packages/rfdb-server/target/debug
27
- */
28
- function findServerBinary(): string | null {
29
- // 1. Check @grafema/rfdb npm package
30
- try {
31
- const rfdbPkg = require.resolve('@grafema/rfdb');
32
- const rfdbDir = dirname(rfdbPkg);
33
- const platform = process.platform;
34
- const arch = process.arch;
35
-
36
- let platformDir: string;
37
- if (platform === 'darwin') {
38
- platformDir = arch === 'arm64' ? 'darwin-arm64' : 'darwin-x64';
39
- } else if (platform === 'linux') {
40
- platformDir = arch === 'arm64' ? 'linux-arm64' : 'linux-x64';
41
- } else {
42
- platformDir = `${platform}-${arch}`;
43
- }
44
-
45
- const npmBinary = join(rfdbDir, 'prebuilt', platformDir, 'rfdb-server');
46
- if (existsSync(npmBinary)) {
47
- return npmBinary;
48
- }
49
- } catch {
50
- // @grafema/rfdb not installed
51
- }
52
-
53
- // 2. Check packages/rfdb-server in monorepo
54
- // From packages/cli/dist/commands -> project root is 4 levels up
55
- const projectRoot = join(__dirname, '../../../..');
56
- const releaseBinary = join(projectRoot, 'packages/rfdb-server/target/release/rfdb-server');
57
- if (existsSync(releaseBinary)) {
58
- return releaseBinary;
59
- }
60
-
61
- // 3. Check debug build
62
- const debugBinary = join(projectRoot, 'packages/rfdb-server/target/debug/rfdb-server');
63
- if (existsSync(debugBinary)) {
64
- return debugBinary;
65
- }
66
-
67
- return null;
18
+ // Extend config type for server settings
19
+ interface ServerConfig {
20
+ binaryPath?: string;
68
21
  }
69
22
 
70
23
  /**
@@ -106,10 +59,15 @@ export const serverCommand = new Command('server')
106
59
  .description('Manage RFDB server lifecycle')
107
60
  .addHelpText('after', `
108
61
  Examples:
109
- grafema server start Start the RFDB server (detached)
110
- grafema server stop Stop the running server
111
- grafema server status Check if server is running
112
- grafema server status --json Server status as JSON
62
+ grafema server start Start the RFDB server
63
+ grafema server start --binary /path/to/bin Start with specific binary
64
+ grafema server stop Stop the running server
65
+ grafema server status Check if server is running
66
+ grafema server status --json Server status as JSON
67
+
68
+ Config (in .grafema/config.yaml):
69
+ server:
70
+ binaryPath: /path/to/rfdb-server # Optional: path to binary
113
71
  `);
114
72
 
115
73
  // grafema server start
@@ -117,7 +75,8 @@ serverCommand
117
75
  .command('start')
118
76
  .description('Start the RFDB server')
119
77
  .option('-p, --project <path>', 'Project path', '.')
120
- .action(async (options: { project: string }) => {
78
+ .option('-b, --binary <path>', 'Path to rfdb-server binary')
79
+ .action(async (options: { project: string; binary?: string }) => {
121
80
  const projectPath = resolve(options.project);
122
81
  const { grafemaDir, socketPath, dbPath, pidPath } = getProjectPaths(projectPath);
123
82
 
@@ -144,16 +103,39 @@ serverCommand
144
103
  unlinkSync(socketPath);
145
104
  }
146
105
 
147
- // Find server binary
148
- const binaryPath = findServerBinary();
106
+ // Determine binary path: CLI flag > config > auto-detect
107
+ let explicitPath: string | undefined;
108
+
109
+ if (options.binary) {
110
+ // Explicit --binary flag
111
+ explicitPath = options.binary;
112
+ } else {
113
+ // Try to read from config
114
+ try {
115
+ const config = loadConfig(projectPath);
116
+ const serverConfig = (config as unknown as { server?: ServerConfig }).server;
117
+ if (serverConfig?.binaryPath) {
118
+ explicitPath = serverConfig.binaryPath;
119
+ }
120
+ } catch {
121
+ // Config not found or invalid - continue with auto-detect
122
+ }
123
+ }
124
+
125
+ const binaryPath = findRfdbBinary({ explicitPath });
126
+
149
127
  if (!binaryPath) {
150
- exitWithError('RFDB server binary not found', [
151
- 'Install: npm install @grafema/rfdb',
152
- 'Or build: cargo build --release --bin rfdb-server'
153
- ]);
128
+ // If explicit path was given but not found, show specific error
129
+ if (explicitPath) {
130
+ exitWithError(`Specified binary not found: ${resolve(explicitPath)}`, [
131
+ 'Check the path and try again'
132
+ ]);
133
+ }
134
+ exitWithError('RFDB server binary not found', getBinaryNotFoundMessage().split('\n').slice(2));
154
135
  }
155
136
 
156
137
  console.log(`Starting RFDB server...`);
138
+ console.log(` Binary: ${binaryPath}`);
157
139
  console.log(` Database: ${dbPath}`);
158
140
  console.log(` Socket: ${socketPath}`);
159
141
 
@@ -171,9 +153,9 @@ serverCommand
171
153
  writeFileSync(pidPath, String(serverProcess.pid));
172
154
  }
173
155
 
174
- // Wait for socket to appear
156
+ // Wait for socket to appear (increased timeout for slow systems)
175
157
  let attempts = 0;
176
- while (!existsSync(socketPath) && attempts < 50) {
158
+ while (!existsSync(socketPath) && attempts < 100) {
177
159
  await sleep(100);
178
160
  attempts++;
179
161
  }
@@ -181,7 +163,8 @@ serverCommand
181
163
  if (!existsSync(socketPath)) {
182
164
  exitWithError('Server failed to start', [
183
165
  'Check if database path is valid',
184
- 'Check server logs for errors'
166
+ 'Check server logs for errors',
167
+ `Binary used: ${binaryPath}`
185
168
  ]);
186
169
  }
187
170