@grafema/cli 0.1.1-alpha → 0.2.0-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.
Files changed (79) hide show
  1. package/dist/cli.js +10 -0
  2. package/dist/commands/analyze.d.ts.map +1 -1
  3. package/dist/commands/analyze.js +28 -7
  4. package/dist/commands/check.d.ts +6 -0
  5. package/dist/commands/check.d.ts.map +1 -1
  6. package/dist/commands/check.js +177 -1
  7. package/dist/commands/coverage.d.ts.map +1 -1
  8. package/dist/commands/coverage.js +7 -0
  9. package/dist/commands/doctor/checks.d.ts +55 -0
  10. package/dist/commands/doctor/checks.d.ts.map +1 -0
  11. package/dist/commands/doctor/checks.js +534 -0
  12. package/dist/commands/doctor/output.d.ts +20 -0
  13. package/dist/commands/doctor/output.d.ts.map +1 -0
  14. package/dist/commands/doctor/output.js +94 -0
  15. package/dist/commands/doctor/types.d.ts +42 -0
  16. package/dist/commands/doctor/types.d.ts.map +1 -0
  17. package/dist/commands/doctor/types.js +4 -0
  18. package/dist/commands/doctor.d.ts +17 -0
  19. package/dist/commands/doctor.d.ts.map +1 -0
  20. package/dist/commands/doctor.js +80 -0
  21. package/dist/commands/explain.d.ts +16 -0
  22. package/dist/commands/explain.d.ts.map +1 -0
  23. package/dist/commands/explain.js +145 -0
  24. package/dist/commands/explore.d.ts +7 -1
  25. package/dist/commands/explore.d.ts.map +1 -1
  26. package/dist/commands/explore.js +204 -85
  27. package/dist/commands/get.d.ts.map +1 -1
  28. package/dist/commands/get.js +16 -4
  29. package/dist/commands/impact.d.ts.map +1 -1
  30. package/dist/commands/impact.js +48 -50
  31. package/dist/commands/init.d.ts.map +1 -1
  32. package/dist/commands/init.js +93 -15
  33. package/dist/commands/ls.d.ts +14 -0
  34. package/dist/commands/ls.d.ts.map +1 -0
  35. package/dist/commands/ls.js +132 -0
  36. package/dist/commands/overview.d.ts.map +1 -1
  37. package/dist/commands/overview.js +15 -2
  38. package/dist/commands/query.d.ts +98 -0
  39. package/dist/commands/query.d.ts.map +1 -1
  40. package/dist/commands/query.js +549 -136
  41. package/dist/commands/schema.d.ts +13 -0
  42. package/dist/commands/schema.d.ts.map +1 -0
  43. package/dist/commands/schema.js +279 -0
  44. package/dist/commands/server.d.ts.map +1 -1
  45. package/dist/commands/server.js +13 -6
  46. package/dist/commands/stats.d.ts.map +1 -1
  47. package/dist/commands/stats.js +7 -0
  48. package/dist/commands/trace.d.ts +73 -0
  49. package/dist/commands/trace.d.ts.map +1 -1
  50. package/dist/commands/trace.js +500 -5
  51. package/dist/commands/types.d.ts +12 -0
  52. package/dist/commands/types.d.ts.map +1 -0
  53. package/dist/commands/types.js +79 -0
  54. package/dist/utils/formatNode.d.ts +13 -0
  55. package/dist/utils/formatNode.d.ts.map +1 -1
  56. package/dist/utils/formatNode.js +35 -2
  57. package/package.json +3 -3
  58. package/src/cli.ts +10 -0
  59. package/src/commands/analyze.ts +31 -5
  60. package/src/commands/check.ts +201 -0
  61. package/src/commands/coverage.ts +7 -0
  62. package/src/commands/doctor/checks.ts +612 -0
  63. package/src/commands/doctor/output.ts +115 -0
  64. package/src/commands/doctor/types.ts +45 -0
  65. package/src/commands/doctor.ts +106 -0
  66. package/src/commands/explain.ts +173 -0
  67. package/src/commands/explore.tsx +247 -97
  68. package/src/commands/get.ts +20 -6
  69. package/src/commands/impact.ts +55 -61
  70. package/src/commands/init.ts +101 -14
  71. package/src/commands/ls.ts +166 -0
  72. package/src/commands/overview.ts +15 -2
  73. package/src/commands/query.ts +643 -149
  74. package/src/commands/schema.ts +345 -0
  75. package/src/commands/server.ts +13 -6
  76. package/src/commands/stats.ts +7 -0
  77. package/src/commands/trace.ts +647 -6
  78. package/src/commands/types.ts +94 -0
  79. package/src/utils/formatNode.ts +42 -2
package/dist/cli.js CHANGED
@@ -7,6 +7,8 @@ import { initCommand } from './commands/init.js';
7
7
  import { analyzeCommand } from './commands/analyze.js';
8
8
  import { overviewCommand } from './commands/overview.js';
9
9
  import { queryCommand } from './commands/query.js';
10
+ import { typesCommand } from './commands/types.js';
11
+ import { lsCommand } from './commands/ls.js';
10
12
  import { getCommand } from './commands/get.js';
11
13
  import { traceCommand } from './commands/trace.js';
12
14
  import { impactCommand } from './commands/impact.js';
@@ -15,6 +17,9 @@ import { statsCommand } from './commands/stats.js';
15
17
  import { checkCommand } from './commands/check.js';
16
18
  import { serverCommand } from './commands/server.js';
17
19
  import { coverageCommand } from './commands/coverage.js';
20
+ import { doctorCommand } from './commands/doctor.js';
21
+ import { schemaCommand } from './commands/schema.js';
22
+ import { explainCommand } from './commands/explain.js';
18
23
  const program = new Command();
19
24
  program
20
25
  .name('grafema')
@@ -25,6 +30,8 @@ program.addCommand(initCommand);
25
30
  program.addCommand(analyzeCommand);
26
31
  program.addCommand(overviewCommand);
27
32
  program.addCommand(queryCommand);
33
+ program.addCommand(typesCommand);
34
+ program.addCommand(lsCommand);
28
35
  program.addCommand(getCommand);
29
36
  program.addCommand(traceCommand);
30
37
  program.addCommand(impactCommand);
@@ -33,4 +40,7 @@ program.addCommand(statsCommand); // Keep for backwards compat
33
40
  program.addCommand(coverageCommand);
34
41
  program.addCommand(checkCommand);
35
42
  program.addCommand(serverCommand);
43
+ program.addCommand(doctorCommand);
44
+ program.addCommand(schemaCommand);
45
+ program.addCommand(explainCommand);
36
46
  program.parse();
@@ -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;AAyHpC,eAAO,MAAM,cAAc,SAiJvB,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;AAiIpC,eAAO,MAAM,cAAc,SAmKvB,CAAC"}
@@ -10,11 +10,11 @@ SimpleProjectDiscovery, MonorepoServiceDiscovery, WorkspaceDiscovery,
10
10
  // Indexing
11
11
  JSModuleIndexer, RustModuleIndexer,
12
12
  // Analysis
13
- JSASTAnalyzer, ExpressRouteAnalyzer, SocketIOAnalyzer, DatabaseAnalyzer, FetchAnalyzer, ServiceLayerAnalyzer, ReactAnalyzer, RustAnalyzer,
13
+ JSASTAnalyzer, ExpressRouteAnalyzer, ExpressResponseAnalyzer, SocketIOAnalyzer, DatabaseAnalyzer, FetchAnalyzer, ServiceLayerAnalyzer, ReactAnalyzer, RustAnalyzer,
14
14
  // Enrichment
15
- MethodCallResolver, AliasTracker, ValueDomainAnalyzer, MountPointResolver, PrefixEvaluator, InstanceOfResolver, ImportExportLinker, HTTPConnectionEnricher, RustFFIEnricher,
15
+ MethodCallResolver, ArgumentParameterLinker, AliasTracker, ValueDomainAnalyzer, MountPointResolver, PrefixEvaluator, InstanceOfResolver, ImportExportLinker, FunctionCallResolver, HTTPConnectionEnricher, RustFFIEnricher,
16
16
  // Validation
17
- CallResolverValidator, EvalBanValidator, SQLInjectionValidator, ShadowingDetector, GraphConnectivityValidator, DataFlowValidator, TypeScriptDeadCodeValidator, } from '@grafema/core';
17
+ CallResolverValidator, EvalBanValidator, SQLInjectionValidator, ShadowingDetector, GraphConnectivityValidator, DataFlowValidator, TypeScriptDeadCodeValidator, BrokenImportValidator, } from '@grafema/core';
18
18
  const BUILTIN_PLUGINS = {
19
19
  // Discovery
20
20
  SimpleProjectDiscovery: () => new SimpleProjectDiscovery(),
@@ -26,6 +26,7 @@ const BUILTIN_PLUGINS = {
26
26
  // Analysis
27
27
  JSASTAnalyzer: () => new JSASTAnalyzer(),
28
28
  ExpressRouteAnalyzer: () => new ExpressRouteAnalyzer(),
29
+ ExpressResponseAnalyzer: () => new ExpressResponseAnalyzer(),
29
30
  SocketIOAnalyzer: () => new SocketIOAnalyzer(),
30
31
  DatabaseAnalyzer: () => new DatabaseAnalyzer(),
31
32
  FetchAnalyzer: () => new FetchAnalyzer(),
@@ -34,12 +35,14 @@ const BUILTIN_PLUGINS = {
34
35
  RustAnalyzer: () => new RustAnalyzer(),
35
36
  // Enrichment
36
37
  MethodCallResolver: () => new MethodCallResolver(),
38
+ ArgumentParameterLinker: () => new ArgumentParameterLinker(),
37
39
  AliasTracker: () => new AliasTracker(),
38
40
  ValueDomainAnalyzer: () => new ValueDomainAnalyzer(),
39
41
  MountPointResolver: () => new MountPointResolver(),
40
42
  PrefixEvaluator: () => new PrefixEvaluator(),
41
43
  InstanceOfResolver: () => new InstanceOfResolver(),
42
44
  ImportExportLinker: () => new ImportExportLinker(),
45
+ FunctionCallResolver: () => new FunctionCallResolver(),
43
46
  HTTPConnectionEnricher: () => new HTTPConnectionEnricher(),
44
47
  RustFFIEnricher: () => new RustFFIEnricher(),
45
48
  // Validation
@@ -50,6 +53,7 @@ const BUILTIN_PLUGINS = {
50
53
  GraphConnectivityValidator: () => new GraphConnectivityValidator(),
51
54
  DataFlowValidator: () => new DataFlowValidator(),
52
55
  TypeScriptDeadCodeValidator: () => new TypeScriptDeadCodeValidator(),
56
+ BrokenImportValidator: () => new BrokenImportValidator(),
53
57
  };
54
58
  function createPlugins(config) {
55
59
  const plugins = [];
@@ -95,6 +99,17 @@ export const analyzeCommand = new Command('analyze')
95
99
  .option('-v, --verbose', 'Show verbose logging')
96
100
  .option('--debug', 'Enable debug mode (writes diagnostics.log)')
97
101
  .option('--log-level <level>', 'Set log level (silent, errors, warnings, info, debug)')
102
+ .option('--strict', 'Enable strict mode (fail on unresolved references)')
103
+ .addHelpText('after', `
104
+ Examples:
105
+ grafema analyze Analyze current project
106
+ grafema analyze ./my-project Analyze specific directory
107
+ grafema analyze --clear Clear database and rebuild from scratch
108
+ grafema analyze -s api Analyze only "api" service (monorepo)
109
+ grafema analyze -v Verbose output with progress details
110
+ grafema analyze --debug Write diagnostics.log for debugging
111
+ grafema analyze --strict Fail on unresolved references (debugging)
112
+ `)
98
113
  .action(async (path, options) => {
99
114
  const projectPath = resolve(path);
100
115
  const grafemaDir = join(projectPath, '.grafema');
@@ -124,6 +139,11 @@ export const analyzeCommand = new Command('analyze')
124
139
  }
125
140
  const plugins = createPlugins(config.plugins);
126
141
  log(`Loaded ${plugins.length} plugins`);
142
+ // Resolve strict mode: CLI flag overrides config
143
+ const strictMode = options.strict ?? config.strict ?? false;
144
+ if (strictMode) {
145
+ log('Strict mode enabled - analysis will fail on unresolved references');
146
+ }
127
147
  const startTime = Date.now();
128
148
  const orchestrator = new Orchestrator({
129
149
  graph: backend,
@@ -133,6 +153,7 @@ export const analyzeCommand = new Command('analyze')
133
153
  forceAnalysis: options.clear || false,
134
154
  logger,
135
155
  services: config.services.length > 0 ? config.services : undefined, // Pass config services (REG-174)
156
+ strictMode, // REG-330: Pass strict mode flag
136
157
  onProgress: (progress) => {
137
158
  if (options.verbose) {
138
159
  log(`[${progress.phase}] ${progress.message}`);
@@ -155,17 +176,17 @@ export const analyzeCommand = new Command('analyze')
155
176
  // Print summary if there are any issues
156
177
  if (diagnostics.count() > 0) {
157
178
  log('');
158
- log(reporter.summary());
179
+ log(reporter.categorizedSummary());
159
180
  // In verbose mode, print full report
160
181
  if (options.verbose) {
161
182
  log('');
162
183
  log(reporter.report({ format: 'text', includeSummary: false }));
163
184
  }
164
185
  }
165
- // Write diagnostics.log in debug mode
186
+ // Always write diagnostics.log (required for `grafema check` command)
187
+ const writer = new DiagnosticWriter();
188
+ await writer.write(diagnostics, grafemaDir);
166
189
  if (options.debug) {
167
- const writer = new DiagnosticWriter();
168
- await writer.write(diagnostics, grafemaDir);
169
190
  log(`Diagnostics written to ${writer.getLogPath(grafemaDir)}`);
170
191
  }
171
192
  // Determine exit code based on severity
@@ -6,5 +6,11 @@
6
6
  * 2. Built-in validators: --guarantee=<name> (e.g., --guarantee=node-creation)
7
7
  */
8
8
  import { Command } from 'commander';
9
+ export interface DiagnosticCheckCategory {
10
+ name: string;
11
+ description: string;
12
+ codes: string[];
13
+ }
14
+ export declare const CHECK_CATEGORIES: Record<string, DiagnosticCheckCategory>;
9
15
  export declare const checkCommand: Command;
10
16
  //# sourceMappingURL=check.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCpC,eAAO,MAAM,YAAY,SAwMtB,CAAC"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiCpC,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAGD,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAqBpE,CAAC;AAEF,eAAO,MAAM,YAAY,SA2OtB,CAAC"}
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { Command } from 'commander';
9
9
  import { resolve, join } from 'path';
10
- import { existsSync } from 'fs';
10
+ import { existsSync, readFileSync } from 'fs';
11
11
  import { RFDBServerBackend, GuaranteeManager, NodeCreationValidator, GraphFreshnessChecker, IncrementalReanalyzer } from '@grafema/core';
12
12
  import { exitWithError } from '../utils/errorFormatter.js';
13
13
  // Available built-in validators
@@ -17,6 +17,29 @@ const BUILT_IN_VALIDATORS = {
17
17
  description: 'Validates that all nodes are created through NodeFactory'
18
18
  }
19
19
  };
20
+ // Available diagnostic categories
21
+ export const CHECK_CATEGORIES = {
22
+ 'connectivity': {
23
+ name: 'Graph Connectivity',
24
+ description: 'Check for disconnected nodes in the graph',
25
+ codes: ['ERR_DISCONNECTED_NODES', 'ERR_DISCONNECTED_NODE'],
26
+ },
27
+ 'calls': {
28
+ name: 'Call Resolution',
29
+ description: 'Check for unresolved function calls',
30
+ codes: ['ERR_UNRESOLVED_CALL'],
31
+ },
32
+ 'dataflow': {
33
+ name: 'Data Flow',
34
+ description: 'Check for missing assignments and broken references',
35
+ codes: ['ERR_MISSING_ASSIGNMENT', 'ERR_BROKEN_REFERENCE', 'ERR_NO_LEAF_NODE'],
36
+ },
37
+ 'imports': {
38
+ name: 'Import Validation',
39
+ description: 'Check for broken imports and undefined symbols',
40
+ codes: ['ERR_BROKEN_IMPORT', 'ERR_UNDEFINED_SYMBOL'],
41
+ },
42
+ };
20
43
  export const checkCommand = new Command('check')
21
44
  .description('Check invariants/guarantees')
22
45
  .argument('[rule]', 'Specific rule ID to check (or "all" for all rules)')
@@ -26,9 +49,36 @@ export const checkCommand = new Command('check')
26
49
  .option('-j, --json', 'Output results as JSON')
27
50
  .option('-q, --quiet', 'Only output failures')
28
51
  .option('--list-guarantees', 'List available built-in guarantees')
52
+ .option('--list-categories', 'List available diagnostic categories')
29
53
  .option('--skip-reanalysis', 'Skip automatic reanalysis of stale modules')
30
54
  .option('--fail-on-stale', 'Exit with error if stale modules found (CI mode)')
55
+ .addHelpText('after', `
56
+ Examples:
57
+ grafema check Run all guarantee checks
58
+ grafema check connectivity Check graph connectivity
59
+ grafema check calls Check call resolution
60
+ grafema check dataflow Check data flow integrity
61
+ grafema check all Run all diagnostic categories
62
+ grafema check --guarantee node-creation Run built-in validator
63
+ grafema check --list-categories List available categories
64
+ grafema check --list-guarantees List built-in guarantees
65
+ grafema check --fail-on-stale CI mode: fail if graph is stale
66
+ grafema check -q Only show failures (quiet mode)
67
+ `)
31
68
  .action(async (rule, options) => {
69
+ // List available categories
70
+ if (options.listCategories) {
71
+ console.log('Available diagnostic categories:');
72
+ console.log('');
73
+ for (const [key, category] of Object.entries(CHECK_CATEGORIES)) {
74
+ console.log(` ${key}`);
75
+ console.log(` ${category.name}`);
76
+ console.log(` ${category.description}`);
77
+ console.log(` Usage: grafema check ${key}`);
78
+ console.log('');
79
+ }
80
+ return;
81
+ }
32
82
  // List available guarantees
33
83
  if (options.listGuarantees) {
34
84
  console.log('Available built-in guarantees:');
@@ -40,6 +90,11 @@ export const checkCommand = new Command('check')
40
90
  }
41
91
  return;
42
92
  }
93
+ // Check if rule argument is a category name
94
+ if (rule && (rule in CHECK_CATEGORIES || rule === 'all')) {
95
+ await runCategoryCheck(rule, options);
96
+ return;
97
+ }
43
98
  // Run built-in guarantee validator
44
99
  if (options.guarantee) {
45
100
  const validatorInfo = BUILT_IN_VALIDATORS[options.guarantee];
@@ -293,3 +348,124 @@ async function runBuiltInValidator(guaranteeName, projectPath, options) {
293
348
  await backend.close();
294
349
  }
295
350
  }
351
+ /**
352
+ * Run category-based diagnostic check
353
+ */
354
+ async function runCategoryCheck(category, options) {
355
+ const resolvedPath = resolve(options.project);
356
+ const grafemaDir = join(resolvedPath, '.grafema');
357
+ const diagnosticsLogPath = join(grafemaDir, 'diagnostics.log');
358
+ if (!existsSync(diagnosticsLogPath)) {
359
+ exitWithError('No diagnostics found', [
360
+ 'Run: grafema analyze',
361
+ 'Diagnostics are collected during analysis'
362
+ ]);
363
+ }
364
+ // Read diagnostics from log file (JSON lines format)
365
+ const diagnosticsContent = readFileSync(diagnosticsLogPath, 'utf-8');
366
+ const allDiagnostics = diagnosticsContent
367
+ .split('\n')
368
+ .filter(line => line.trim())
369
+ .map(line => {
370
+ try {
371
+ return JSON.parse(line);
372
+ }
373
+ catch (e) {
374
+ return null;
375
+ }
376
+ })
377
+ .filter(Boolean);
378
+ // Filter diagnostics by category codes
379
+ let filteredDiagnostics = allDiagnostics;
380
+ if (category !== 'all') {
381
+ const categoryInfo = CHECK_CATEGORIES[category];
382
+ if (!categoryInfo) {
383
+ exitWithError(`Unknown category: ${category}`, [
384
+ 'Use --list-categories to see available options'
385
+ ]);
386
+ }
387
+ filteredDiagnostics = allDiagnostics.filter((d) => categoryInfo.codes.includes(d.code));
388
+ }
389
+ if (options.json) {
390
+ console.log(JSON.stringify({
391
+ category: category,
392
+ total: filteredDiagnostics.length,
393
+ diagnostics: filteredDiagnostics
394
+ }, null, 2));
395
+ }
396
+ else {
397
+ const categoryName = category === 'all'
398
+ ? 'All Categories'
399
+ : CHECK_CATEGORIES[category].name;
400
+ if (!options.quiet) {
401
+ console.log(`Checking ${categoryName}...`);
402
+ console.log('');
403
+ }
404
+ if (filteredDiagnostics.length === 0) {
405
+ console.log('\x1b[32m✓\x1b[0m No issues found');
406
+ }
407
+ else {
408
+ console.log(`\x1b[33m⚠\x1b[0m Found ${filteredDiagnostics.length} diagnostic(s):`);
409
+ console.log('');
410
+ // Group by severity
411
+ const errors = filteredDiagnostics.filter((d) => d.severity === 'error' || d.severity === 'fatal');
412
+ const warnings = filteredDiagnostics.filter((d) => d.severity === 'warning');
413
+ const infos = filteredDiagnostics.filter((d) => d.severity === 'info');
414
+ // Display errors first
415
+ if (errors.length > 0) {
416
+ console.log(`\x1b[31mErrors (${errors.length}):\x1b[0m`);
417
+ for (const diag of errors.slice(0, 10)) {
418
+ const location = diag.file ? `${diag.file}${diag.line ? `:${diag.line}` : ''}` : '';
419
+ console.log(` \x1b[31m•\x1b[0m [${diag.code}] ${diag.message}`);
420
+ if (location) {
421
+ console.log(` ${location}`);
422
+ }
423
+ if (diag.suggestion && !options.quiet) {
424
+ console.log(` Suggestion: ${diag.suggestion}`);
425
+ }
426
+ }
427
+ if (errors.length > 10) {
428
+ console.log(` ... and ${errors.length - 10} more errors`);
429
+ }
430
+ console.log('');
431
+ }
432
+ // Display warnings
433
+ if (warnings.length > 0) {
434
+ console.log(`\x1b[33mWarnings (${warnings.length}):\x1b[0m`);
435
+ for (const diag of warnings.slice(0, 10)) {
436
+ const location = diag.file ? `${diag.file}${diag.line ? `:${diag.line}` : ''}` : '';
437
+ console.log(` \x1b[33m•\x1b[0m [${diag.code}] ${diag.message}`);
438
+ if (location) {
439
+ console.log(` ${location}`);
440
+ }
441
+ if (diag.suggestion && !options.quiet) {
442
+ console.log(` Suggestion: ${diag.suggestion}`);
443
+ }
444
+ }
445
+ if (warnings.length > 10) {
446
+ console.log(` ... and ${warnings.length - 10} more warnings`);
447
+ }
448
+ console.log('');
449
+ }
450
+ // Display infos
451
+ if (infos.length > 0 && !options.quiet) {
452
+ console.log(`\x1b[36mInfo (${infos.length}):\x1b[0m`);
453
+ for (const diag of infos.slice(0, 5)) {
454
+ const location = diag.file ? `${diag.file}${diag.line ? `:${diag.line}` : ''}` : '';
455
+ console.log(` \x1b[36m•\x1b[0m [${diag.code}] ${diag.message}`);
456
+ if (location) {
457
+ console.log(` ${location}`);
458
+ }
459
+ }
460
+ if (infos.length > 5) {
461
+ console.log(` ... and ${infos.length - 5} more info messages`);
462
+ }
463
+ console.log('');
464
+ }
465
+ }
466
+ console.log('');
467
+ if (filteredDiagnostics.some((d) => d.severity === 'error' || d.severity === 'fatal')) {
468
+ process.exit(1);
469
+ }
470
+ }
471
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/commands/coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,eAAe,SA6BxB,CAAC"}
1
+ {"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/commands/coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,eAAe,SAoCxB,CAAC"}
@@ -16,6 +16,13 @@ export const coverageCommand = new Command('coverage')
16
16
  .option('-p, --project <path>', 'Project path', '.')
17
17
  .option('-j, --json', 'Output as JSON')
18
18
  .option('-v, --verbose', 'Show detailed file lists')
19
+ .addHelpText('after', `
20
+ Examples:
21
+ grafema coverage Show coverage summary
22
+ grafema coverage --verbose Show detailed file lists
23
+ grafema coverage --json Output coverage as JSON
24
+ grafema coverage -p ./app Coverage for specific project
25
+ `)
19
26
  .action(async (options) => {
20
27
  const projectPath = resolve(options.project);
21
28
  const grafemaDir = join(projectPath, '.grafema');
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Diagnostic check functions for `grafema doctor` command - REG-214
3
+ *
4
+ * Checks are organized in levels:
5
+ * - Level 1: Prerequisites (fail-fast) - checkGrafemaInitialized, checkServerStatus
6
+ * - Level 2: Configuration - checkConfigValidity, checkEntrypoints
7
+ * - Level 3: Graph Health - checkDatabaseExists, checkGraphStats, checkConnectivity, checkFreshness
8
+ * - Level 4: Informational - checkVersions
9
+ */
10
+ import type { DoctorCheckResult } from './types.js';
11
+ /**
12
+ * Check if .grafema directory exists with config file.
13
+ * FAIL if not initialized.
14
+ */
15
+ export declare function checkGrafemaInitialized(projectPath: string): Promise<DoctorCheckResult>;
16
+ /**
17
+ * Check if RFDB server is running and responsive.
18
+ * WARN if not running (server starts on-demand during analyze).
19
+ */
20
+ export declare function checkServerStatus(projectPath: string): Promise<DoctorCheckResult>;
21
+ /**
22
+ * Validate config file syntax and structure.
23
+ * Uses existing loadConfig() which throws on errors.
24
+ */
25
+ export declare function checkConfigValidity(projectPath: string): Promise<DoctorCheckResult>;
26
+ /**
27
+ * Check that entrypoints can be resolved.
28
+ * For config-defined services, validates that entrypoint files exist.
29
+ */
30
+ export declare function checkEntrypoints(projectPath: string): Promise<DoctorCheckResult>;
31
+ /**
32
+ * Check if database file exists and has data.
33
+ */
34
+ export declare function checkDatabaseExists(projectPath: string): Promise<DoctorCheckResult>;
35
+ /**
36
+ * Get graph statistics (requires server running).
37
+ */
38
+ export declare function checkGraphStats(projectPath: string): Promise<DoctorCheckResult>;
39
+ /**
40
+ * Check graph connectivity - find disconnected nodes.
41
+ * Thresholds:
42
+ * 0-5%: pass (normal for external modules)
43
+ * 5-20%: warn
44
+ * >20%: fail (critical issue)
45
+ */
46
+ export declare function checkConnectivity(projectPath: string): Promise<DoctorCheckResult>;
47
+ /**
48
+ * Check if graph is fresh (no stale modules).
49
+ */
50
+ export declare function checkFreshness(projectPath: string): Promise<DoctorCheckResult>;
51
+ /**
52
+ * Collect version information (always passes).
53
+ */
54
+ export declare function checkVersions(projectPath: string): Promise<DoctorCheckResult>;
55
+ //# sourceMappingURL=checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/checks.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAYH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA2BpD;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAgC5B;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAkC5B;AAMD;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CA+C5B;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CA+E5B;AAMD;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CA6B5B;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CA6C5B;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAgI5B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CA4C5B;AAMD;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CA6C5B"}