@grafema/cli 0.2.3-beta → 0.2.5-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 (84) hide show
  1. package/README.md +73 -0
  2. package/dist/cli.js +1 -0
  3. package/dist/cli.js.map +1 -0
  4. package/dist/commands/analyze.d.ts +9 -0
  5. package/dist/commands/analyze.d.ts.map +1 -1
  6. package/dist/commands/analyze.js +136 -52
  7. package/dist/commands/analyze.js.map +1 -0
  8. package/dist/commands/check.d.ts +2 -6
  9. package/dist/commands/check.d.ts.map +1 -1
  10. package/dist/commands/check.js +32 -46
  11. package/dist/commands/check.js.map +1 -0
  12. package/dist/commands/coverage.js +1 -0
  13. package/dist/commands/coverage.js.map +1 -0
  14. package/dist/commands/doctor/checks.d.ts.map +1 -1
  15. package/dist/commands/doctor/checks.js +9 -5
  16. package/dist/commands/doctor/checks.js.map +1 -0
  17. package/dist/commands/doctor/output.js +1 -0
  18. package/dist/commands/doctor/output.js.map +1 -0
  19. package/dist/commands/doctor/types.js +1 -0
  20. package/dist/commands/doctor/types.js.map +1 -0
  21. package/dist/commands/doctor.js +1 -0
  22. package/dist/commands/doctor.js.map +1 -0
  23. package/dist/commands/explain.js +1 -0
  24. package/dist/commands/explain.js.map +1 -0
  25. package/dist/commands/explore.d.ts.map +1 -1
  26. package/dist/commands/explore.js +9 -4
  27. package/dist/commands/explore.js.map +1 -0
  28. package/dist/commands/get.d.ts.map +1 -1
  29. package/dist/commands/get.js +7 -0
  30. package/dist/commands/get.js.map +1 -0
  31. package/dist/commands/impact.js +1 -0
  32. package/dist/commands/impact.js.map +1 -0
  33. package/dist/commands/init.d.ts.map +1 -1
  34. package/dist/commands/init.js +7 -1
  35. package/dist/commands/init.js.map +1 -0
  36. package/dist/commands/ls.d.ts.map +1 -1
  37. package/dist/commands/ls.js +7 -0
  38. package/dist/commands/ls.js.map +1 -0
  39. package/dist/commands/overview.d.ts.map +1 -1
  40. package/dist/commands/overview.js +1 -0
  41. package/dist/commands/overview.js.map +1 -0
  42. package/dist/commands/query.d.ts.map +1 -1
  43. package/dist/commands/query.js +68 -1
  44. package/dist/commands/query.js.map +1 -0
  45. package/dist/commands/schema.js +1 -0
  46. package/dist/commands/schema.js.map +1 -0
  47. package/dist/commands/server.d.ts +2 -1
  48. package/dist/commands/server.d.ts.map +1 -1
  49. package/dist/commands/server.js +50 -3
  50. package/dist/commands/server.js.map +1 -0
  51. package/dist/commands/stats.js +1 -0
  52. package/dist/commands/stats.js.map +1 -0
  53. package/dist/commands/trace.js +1 -0
  54. package/dist/commands/trace.js.map +1 -0
  55. package/dist/commands/types.js +1 -0
  56. package/dist/commands/types.js.map +1 -0
  57. package/dist/utils/codePreview.js +1 -0
  58. package/dist/utils/codePreview.js.map +1 -0
  59. package/dist/utils/errorFormatter.js +1 -0
  60. package/dist/utils/errorFormatter.js.map +1 -0
  61. package/dist/utils/formatNode.js +1 -0
  62. package/dist/utils/formatNode.js.map +1 -0
  63. package/dist/utils/progressRenderer.d.ts +119 -0
  64. package/dist/utils/progressRenderer.d.ts.map +1 -0
  65. package/dist/utils/progressRenderer.js +245 -0
  66. package/dist/utils/progressRenderer.js.map +1 -0
  67. package/dist/utils/spinner.d.ts +39 -0
  68. package/dist/utils/spinner.d.ts.map +1 -0
  69. package/dist/utils/spinner.js +84 -0
  70. package/dist/utils/spinner.js.map +1 -0
  71. package/package.json +5 -4
  72. package/src/commands/analyze.ts +150 -55
  73. package/src/commands/check.ts +36 -68
  74. package/src/commands/doctor/checks.ts +8 -5
  75. package/src/commands/explore.tsx +8 -4
  76. package/src/commands/get.ts +8 -0
  77. package/src/commands/impact.ts +1 -1
  78. package/src/commands/init.ts +6 -2
  79. package/src/commands/ls.ts +8 -0
  80. package/src/commands/overview.ts +0 -4
  81. package/src/commands/query.ts +77 -1
  82. package/src/commands/server.ts +57 -3
  83. package/src/utils/progressRenderer.ts +288 -0
  84. package/src/utils/spinner.ts +94 -0
@@ -0,0 +1,119 @@
1
+ /**
2
+ * ProgressRenderer - Formats and displays analysis progress for CLI.
3
+ *
4
+ * Consumes ProgressInfo events from Orchestrator and renders them as
5
+ * user-friendly progress output with phase tracking, elapsed time,
6
+ * and spinner animation.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const renderer = new ProgressRenderer({ isInteractive: true });
11
+ * orchestrator.run({
12
+ * onProgress: (info) => renderer.update(info),
13
+ * });
14
+ * console.log(renderer.finish(elapsed));
15
+ * ```
16
+ */
17
+ import type { ProgressInfo } from '@grafema/core';
18
+ /**
19
+ * Options for creating a ProgressRenderer instance.
20
+ */
21
+ export interface ProgressRendererOptions {
22
+ /** Whether output is to a TTY (enables spinner and line overwriting) */
23
+ isInteractive?: boolean;
24
+ /** Minimum milliseconds between display updates (default: 100) */
25
+ throttle?: number;
26
+ /** Custom write function for output (default: process.stdout.write) */
27
+ write?: (text: string) => void;
28
+ }
29
+ /**
30
+ * ProgressRenderer - Formats and displays analysis progress for CLI.
31
+ *
32
+ * Consumes ProgressInfo events from Orchestrator and renders them as
33
+ * user-friendly progress output with phase tracking, elapsed time,
34
+ * and spinner animation.
35
+ */
36
+ export declare class ProgressRenderer {
37
+ private phases;
38
+ private currentPhaseIndex;
39
+ private currentPhase;
40
+ private currentPlugin;
41
+ private message;
42
+ private totalFiles;
43
+ private processedFiles;
44
+ private servicesAnalyzed;
45
+ private spinnerIndex;
46
+ private isInteractive;
47
+ private startTime;
48
+ private lastDisplayTime;
49
+ private displayThrottle;
50
+ private write;
51
+ private spinnerFrames;
52
+ private activePlugins;
53
+ private nodeCount;
54
+ private edgeCount;
55
+ constructor(options?: ProgressRendererOptions);
56
+ /**
57
+ * Process a progress event from Orchestrator.
58
+ * Updates internal state and displays formatted output if throttle allows.
59
+ */
60
+ update(info: ProgressInfo): void;
61
+ /**
62
+ * Update graph statistics (called separately from progress events).
63
+ * This allows real-time node/edge count updates.
64
+ */
65
+ setStats(nodeCount: number, edgeCount: number): void;
66
+ /**
67
+ * Format and display current state to console.
68
+ */
69
+ private display;
70
+ private formatOutput;
71
+ /**
72
+ * Format elapsed time as human-readable string.
73
+ */
74
+ private formatElapsed;
75
+ private formatInteractive;
76
+ private formatNonInteractive;
77
+ /**
78
+ * Format node/edge counts if available.
79
+ */
80
+ private formatStats;
81
+ /**
82
+ * Format large numbers with K/M suffix.
83
+ */
84
+ private formatNumber;
85
+ /**
86
+ * Get formatted phase label with number, e.g., "[3/5] Analysis..."
87
+ */
88
+ private getPhaseLabel;
89
+ /**
90
+ * Format progress details based on current phase.
91
+ */
92
+ private formatPhaseProgress;
93
+ /**
94
+ * Format plugin list, truncating if more than 3 plugins.
95
+ */
96
+ private formatPluginList;
97
+ /**
98
+ * Get final summary message after analysis complete.
99
+ * @param durationSeconds - Total duration of analysis
100
+ * @returns Formatted completion message
101
+ */
102
+ finish(durationSeconds: number): string;
103
+ /**
104
+ * Expose internal state for testing.
105
+ * @internal
106
+ */
107
+ getState(): {
108
+ phaseIndex: number;
109
+ phase: string;
110
+ processedFiles: number;
111
+ totalFiles: number;
112
+ servicesAnalyzed: number;
113
+ spinnerIndex: number;
114
+ activePlugins: string[];
115
+ nodeCount: number;
116
+ edgeCount: number;
117
+ };
118
+ }
119
+ //# sourceMappingURL=progressRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progressRenderer.d.ts","sourceRoot":"","sources":["../../src/utils/progressRenderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,wEAAwE;IACxE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAA+E;IAC7F,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,aAAa,CAAsD;IAC3E,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,SAAS,CAAa;gBAElB,OAAO,CAAC,EAAE,uBAAuB;IAO7C;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IA+ChC;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAKpD;;OAEG;IACH,OAAO,CAAC,OAAO;IAaf,OAAO,CAAC,YAAY;IAQpB;;OAEG;IACH,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,oBAAoB;IAK5B;;OAEG;IACH,OAAO,CAAC,WAAW;IASnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAUpB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAwB3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;;;OAIG;IACH,MAAM,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM;IAIvC;;;OAGG;IACH,QAAQ,IAAI;QACV,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;QACzB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB;CAaF"}
@@ -0,0 +1,245 @@
1
+ /**
2
+ * ProgressRenderer - Formats and displays analysis progress for CLI.
3
+ *
4
+ * Consumes ProgressInfo events from Orchestrator and renders them as
5
+ * user-friendly progress output with phase tracking, elapsed time,
6
+ * and spinner animation.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const renderer = new ProgressRenderer({ isInteractive: true });
11
+ * orchestrator.run({
12
+ * onProgress: (info) => renderer.update(info),
13
+ * });
14
+ * console.log(renderer.finish(elapsed));
15
+ * ```
16
+ */
17
+ /**
18
+ * ProgressRenderer - Formats and displays analysis progress for CLI.
19
+ *
20
+ * Consumes ProgressInfo events from Orchestrator and renders them as
21
+ * user-friendly progress output with phase tracking, elapsed time,
22
+ * and spinner animation.
23
+ */
24
+ export class ProgressRenderer {
25
+ phases = ['discovery', 'indexing', 'analysis', 'enrichment', 'validation'];
26
+ currentPhaseIndex = -1;
27
+ currentPhase = '';
28
+ currentPlugin = '';
29
+ message = '';
30
+ totalFiles = 0;
31
+ processedFiles = 0;
32
+ servicesAnalyzed = 0;
33
+ spinnerIndex = 0;
34
+ isInteractive;
35
+ startTime;
36
+ lastDisplayTime = 0;
37
+ displayThrottle;
38
+ write;
39
+ spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
40
+ activePlugins = [];
41
+ nodeCount = 0;
42
+ edgeCount = 0;
43
+ constructor(options) {
44
+ this.isInteractive = options?.isInteractive ?? process.stdout.isTTY ?? false;
45
+ this.displayThrottle = options?.throttle ?? 100;
46
+ this.startTime = Date.now();
47
+ this.write = options?.write ?? ((text) => process.stdout.write(text));
48
+ }
49
+ /**
50
+ * Process a progress event from Orchestrator.
51
+ * Updates internal state and displays formatted output if throttle allows.
52
+ */
53
+ update(info) {
54
+ // Update phase tracking
55
+ if (info.phase && info.phase !== this.currentPhase) {
56
+ this.currentPhase = info.phase;
57
+ const idx = this.phases.indexOf(info.phase);
58
+ if (idx !== -1) {
59
+ this.currentPhaseIndex = idx;
60
+ }
61
+ // Reset phase-specific state
62
+ this.activePlugins = [];
63
+ }
64
+ // Update state from progress info
65
+ if (info.currentPlugin !== undefined) {
66
+ this.currentPlugin = info.currentPlugin;
67
+ // Track active plugins for enrichment/validation display
68
+ if ((this.currentPhase === 'enrichment' || this.currentPhase === 'validation') &&
69
+ info.currentPlugin && !this.activePlugins.includes(info.currentPlugin)) {
70
+ this.activePlugins.push(info.currentPlugin);
71
+ }
72
+ }
73
+ if (info.message !== undefined) {
74
+ this.message = info.message;
75
+ }
76
+ if (info.totalFiles !== undefined) {
77
+ this.totalFiles = info.totalFiles;
78
+ }
79
+ if (info.processedFiles !== undefined) {
80
+ this.processedFiles = info.processedFiles;
81
+ }
82
+ if (info.servicesAnalyzed !== undefined) {
83
+ this.servicesAnalyzed = info.servicesAnalyzed;
84
+ }
85
+ // Update spinner
86
+ this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;
87
+ // Check throttling
88
+ const now = Date.now();
89
+ if (now - this.lastDisplayTime < this.displayThrottle) {
90
+ return;
91
+ }
92
+ this.lastDisplayTime = now;
93
+ this.display();
94
+ }
95
+ /**
96
+ * Update graph statistics (called separately from progress events).
97
+ * This allows real-time node/edge count updates.
98
+ */
99
+ setStats(nodeCount, edgeCount) {
100
+ this.nodeCount = nodeCount;
101
+ this.edgeCount = edgeCount;
102
+ }
103
+ /**
104
+ * Format and display current state to console.
105
+ */
106
+ display() {
107
+ const output = this.formatOutput();
108
+ if (this.isInteractive) {
109
+ // TTY mode: overwrite previous line, pad with spaces to clear old content
110
+ const padded = output.padEnd(80, ' ');
111
+ this.write(`\r${padded}`);
112
+ }
113
+ else {
114
+ // Non-TTY mode: append newline
115
+ this.write(`${output}\n`);
116
+ }
117
+ }
118
+ formatOutput() {
119
+ if (this.isInteractive) {
120
+ return this.formatInteractive();
121
+ }
122
+ else {
123
+ return this.formatNonInteractive();
124
+ }
125
+ }
126
+ /**
127
+ * Format elapsed time as human-readable string.
128
+ */
129
+ formatElapsed() {
130
+ const elapsed = (Date.now() - this.startTime) / 1000;
131
+ if (elapsed < 60) {
132
+ return `${elapsed.toFixed(1)}s`;
133
+ }
134
+ const minutes = Math.floor(elapsed / 60);
135
+ const seconds = Math.floor(elapsed % 60);
136
+ return `${minutes}m${seconds}s`;
137
+ }
138
+ formatInteractive() {
139
+ const spinner = this.spinnerFrames[this.spinnerIndex];
140
+ const elapsed = this.formatElapsed();
141
+ const phaseLabel = this.getPhaseLabel();
142
+ const progress = this.formatPhaseProgress();
143
+ const stats = this.formatStats();
144
+ // Format: ⠋ [3/5] Analysis... 150/4047 modules | 12.5s | 1.2M nodes
145
+ return `${spinner} ${phaseLabel}${progress} | ${elapsed}${stats}`;
146
+ }
147
+ formatNonInteractive() {
148
+ const elapsed = this.formatElapsed();
149
+ return `[${this.currentPhase}] ${this.message || this.formatPhaseProgress()} (${elapsed})`;
150
+ }
151
+ /**
152
+ * Format node/edge counts if available.
153
+ */
154
+ formatStats() {
155
+ if (this.nodeCount === 0 && this.edgeCount === 0) {
156
+ return '';
157
+ }
158
+ const nodes = this.formatNumber(this.nodeCount);
159
+ const edges = this.formatNumber(this.edgeCount);
160
+ return ` | ${nodes} nodes, ${edges} edges`;
161
+ }
162
+ /**
163
+ * Format large numbers with K/M suffix.
164
+ */
165
+ formatNumber(n) {
166
+ if (n >= 1_000_000) {
167
+ return `${(n / 1_000_000).toFixed(1)}M`;
168
+ }
169
+ if (n >= 1_000) {
170
+ return `${(n / 1_000).toFixed(1)}K`;
171
+ }
172
+ return String(n);
173
+ }
174
+ /**
175
+ * Get formatted phase label with number, e.g., "[3/5] Analysis..."
176
+ */
177
+ getPhaseLabel() {
178
+ const phaseNum = this.currentPhaseIndex + 1;
179
+ const totalPhases = this.phases.length;
180
+ const phaseName = this.currentPhase.charAt(0).toUpperCase() + this.currentPhase.slice(1);
181
+ return `[${phaseNum}/${totalPhases}] ${phaseName}...`;
182
+ }
183
+ /**
184
+ * Format progress details based on current phase.
185
+ */
186
+ formatPhaseProgress() {
187
+ switch (this.currentPhase) {
188
+ case 'discovery':
189
+ if (this.servicesAnalyzed > 0) {
190
+ return ` ${this.servicesAnalyzed} services found`;
191
+ }
192
+ return '';
193
+ case 'indexing':
194
+ case 'analysis':
195
+ if (this.totalFiles > 0) {
196
+ return ` ${this.processedFiles}/${this.totalFiles} modules`;
197
+ }
198
+ return '';
199
+ case 'enrichment':
200
+ case 'validation':
201
+ if (this.activePlugins.length > 0) {
202
+ return ` (${this.formatPluginList(this.activePlugins)})`;
203
+ }
204
+ return '';
205
+ default:
206
+ return '';
207
+ }
208
+ }
209
+ /**
210
+ * Format plugin list, truncating if more than 3 plugins.
211
+ */
212
+ formatPluginList(plugins) {
213
+ if (plugins.length <= 3) {
214
+ return plugins.join(', ');
215
+ }
216
+ // Truncate to 3 plugins + "..."
217
+ return plugins.slice(0, 3).join(', ') + ', ...';
218
+ }
219
+ /**
220
+ * Get final summary message after analysis complete.
221
+ * @param durationSeconds - Total duration of analysis
222
+ * @returns Formatted completion message
223
+ */
224
+ finish(durationSeconds) {
225
+ return `Analysis complete in ${durationSeconds.toFixed(2)}s`;
226
+ }
227
+ /**
228
+ * Expose internal state for testing.
229
+ * @internal
230
+ */
231
+ getState() {
232
+ return {
233
+ phaseIndex: this.currentPhaseIndex,
234
+ phase: this.currentPhase,
235
+ processedFiles: this.processedFiles,
236
+ totalFiles: this.totalFiles,
237
+ servicesAnalyzed: this.servicesAnalyzed,
238
+ spinnerIndex: this.spinnerIndex,
239
+ activePlugins: [...this.activePlugins],
240
+ nodeCount: this.nodeCount,
241
+ edgeCount: this.edgeCount,
242
+ };
243
+ }
244
+ }
245
+ //# sourceMappingURL=progressRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progressRenderer.js","sourceRoot":"","sources":["../../src/utils/progressRenderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAgBH;;;;;;GAMG;AACH,MAAM,OAAO,gBAAgB;IACnB,MAAM,GAAa,CAAC,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;IACrF,iBAAiB,GAAW,CAAC,CAAC,CAAC;IAC/B,YAAY,GAAW,EAAE,CAAC;IAC1B,aAAa,GAAW,EAAE,CAAC;IAC3B,OAAO,GAAW,EAAE,CAAC;IACrB,UAAU,GAAW,CAAC,CAAC;IACvB,cAAc,GAAW,CAAC,CAAC;IAC3B,gBAAgB,GAAW,CAAC,CAAC;IAC7B,YAAY,GAAW,CAAC,CAAC;IACzB,aAAa,CAAU;IACvB,SAAS,CAAS;IAClB,eAAe,GAAW,CAAC,CAAC;IAC5B,eAAe,CAAS;IACxB,KAAK,CAAyB;IAC9B,aAAa,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACnE,aAAa,GAAa,EAAE,CAAC;IAC7B,SAAS,GAAW,CAAC,CAAC;IACtB,SAAS,GAAW,CAAC,CAAC;IAE9B,YAAY,OAAiC;QAC3C,IAAI,CAAC,aAAa,GAAG,OAAO,EAAE,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC;QAC7E,IAAI,CAAC,eAAe,GAAG,OAAO,EAAE,QAAQ,IAAI,GAAG,CAAC;QAChD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAChF,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,IAAkB;QACvB,wBAAwB;QACxB,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACnD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC;YAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5C,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACf,IAAI,CAAC,iBAAiB,GAAG,GAAG,CAAC;YAC/B,CAAC;YACD,6BAA6B;YAC7B,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QAC1B,CAAC;QAED,kCAAkC;QAClC,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YACxC,yDAAyD;YACzD,IAAI,CAAC,IAAI,CAAC,YAAY,KAAK,YAAY,IAAI,IAAI,CAAC,YAAY,KAAK,YAAY,CAAC;gBAC1E,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC3E,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9B,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACpC,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC5C,CAAC;QACD,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACxC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAChD,CAAC;QAED,iBAAiB;QACjB,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;QAExE,mBAAmB;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YACtD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,eAAe,GAAG,GAAG,CAAC;QAE3B,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,SAAiB,EAAE,SAAiB;QAC3C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;OAEG;IACK,OAAO;QACb,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAEnC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,0EAA0E;YAC1E,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YACtC,IAAI,CAAC,KAAK,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,+BAA+B;YAC/B,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAEO,YAAY;QAClB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,aAAa;QACnB,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;QACrD,IAAI,OAAO,GAAG,EAAE,EAAE,CAAC;YACjB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;QAClC,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QACzC,OAAO,GAAG,OAAO,IAAI,OAAO,GAAG,CAAC;IAClC,CAAC;IAEO,iBAAiB;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAEjC,oEAAoE;QACpE,OAAO,GAAG,OAAO,IAAI,UAAU,GAAG,QAAQ,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACpE,CAAC;IAEO,oBAAoB;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACrC,OAAO,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,mBAAmB,EAAE,KAAK,OAAO,GAAG,CAAC;IAC7F,CAAC;IAED;;OAEG;IACK,WAAW;QACjB,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;YACjD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChD,OAAO,MAAM,KAAK,WAAW,KAAK,QAAQ,CAAC;IAC7C,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,CAAS;QAC5B,IAAI,CAAC,IAAI,SAAS,EAAE,CAAC;YACnB,OAAO,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;YACf,OAAO,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;QACtC,CAAC;QACD,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IAED;;OAEG;IACK,aAAa;QACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACzF,OAAO,IAAI,QAAQ,IAAI,WAAW,KAAK,SAAS,KAAK,CAAC;IACxD,CAAC;IAED;;OAEG;IACK,mBAAmB;QACzB,QAAQ,IAAI,CAAC,YAAY,EAAE,CAAC;YAC1B,KAAK,WAAW;gBACd,IAAI,IAAI,CAAC,gBAAgB,GAAG,CAAC,EAAE,CAAC;oBAC9B,OAAO,IAAI,IAAI,CAAC,gBAAgB,iBAAiB,CAAC;gBACpD,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ,KAAK,UAAU,CAAC;YAChB,KAAK,UAAU;gBACb,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;oBACxB,OAAO,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,UAAU,UAAU,CAAC;gBAC9D,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ,KAAK,YAAY,CAAC;YAClB,KAAK,YAAY;gBACf,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAClC,OAAO,KAAK,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;gBAC3D,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ;gBACE,OAAO,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,OAAiB;QACxC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,gCAAgC;QAChC,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,eAAuB;QAC5B,OAAO,wBAAwB,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAC/D,CAAC;IAED;;;OAGG;IACH,QAAQ;QAWN,OAAO;YACL,UAAU,EAAE,IAAI,CAAC,iBAAiB;YAClC,KAAK,EAAE,IAAI,CAAC,YAAY;YACxB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,aAAa,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC;YACtC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Simple terminal spinner for slow operations.
3
+ *
4
+ * Features:
5
+ * - TTY detection: silent in non-TTY environments (CI, pipes)
6
+ * - Delayed display: spinner only appears after 100ms to avoid flicker
7
+ * - Elapsed time: shows seconds for long operations
8
+ *
9
+ * Usage:
10
+ * const spinner = new Spinner('Querying graph...');
11
+ * spinner.start();
12
+ * await slowOperation();
13
+ * spinner.stop();
14
+ *
15
+ * IMPORTANT: Always call stop() BEFORE any console.log output.
16
+ */
17
+ export declare class Spinner {
18
+ private message;
19
+ private frames;
20
+ private interval;
21
+ private displayTimer;
22
+ private frameIndex;
23
+ private startTime;
24
+ private displayDelay;
25
+ private isSpinning;
26
+ constructor(message: string, displayDelay?: number);
27
+ /**
28
+ * Start the spinner. Spinner appears only after displayDelay ms.
29
+ * In non-TTY environments (CI, pipes), this is a no-op.
30
+ */
31
+ start(): void;
32
+ private render;
33
+ /**
34
+ * Stop the spinner and clear the line.
35
+ * Safe to call multiple times or if spinner never started.
36
+ */
37
+ stop(): void;
38
+ }
39
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/utils/spinner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAsD;IACpE,OAAO,CAAC,QAAQ,CAA+C;IAC/D,OAAO,CAAC,YAAY,CAA8C;IAClE,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,EAAE,MAAM,EAAE,YAAY,SAAM;IAK/C;;;OAGG;IACH,KAAK,IAAI,IAAI;IAqBb,OAAO,CAAC,MAAM;IAYd;;;OAGG;IACH,IAAI,IAAI,IAAI;CAqBb"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Simple terminal spinner for slow operations.
3
+ *
4
+ * Features:
5
+ * - TTY detection: silent in non-TTY environments (CI, pipes)
6
+ * - Delayed display: spinner only appears after 100ms to avoid flicker
7
+ * - Elapsed time: shows seconds for long operations
8
+ *
9
+ * Usage:
10
+ * const spinner = new Spinner('Querying graph...');
11
+ * spinner.start();
12
+ * await slowOperation();
13
+ * spinner.stop();
14
+ *
15
+ * IMPORTANT: Always call stop() BEFORE any console.log output.
16
+ */
17
+ export class Spinner {
18
+ message;
19
+ frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
20
+ interval = null;
21
+ displayTimer = null;
22
+ frameIndex = 0;
23
+ startTime = 0;
24
+ displayDelay;
25
+ isSpinning = false;
26
+ constructor(message, displayDelay = 100) {
27
+ this.message = message;
28
+ this.displayDelay = displayDelay;
29
+ }
30
+ /**
31
+ * Start the spinner. Spinner appears only after displayDelay ms.
32
+ * In non-TTY environments (CI, pipes), this is a no-op.
33
+ */
34
+ start() {
35
+ // TTY check - ora pattern
36
+ if (!process.stdout.isTTY) {
37
+ return;
38
+ }
39
+ this.startTime = Date.now();
40
+ // Defer display to avoid flicker on fast queries
41
+ this.displayTimer = setTimeout(() => {
42
+ this.isSpinning = true;
43
+ this.render();
44
+ // Animate frames at 80ms interval
45
+ this.interval = setInterval(() => {
46
+ this.frameIndex = (this.frameIndex + 1) % this.frames.length;
47
+ this.render();
48
+ }, 80);
49
+ }, this.displayDelay);
50
+ }
51
+ render() {
52
+ if (!this.isSpinning)
53
+ return;
54
+ const frame = this.frames[this.frameIndex];
55
+ const elapsed = Math.floor((Date.now() - this.startTime) / 1000);
56
+ const timeStr = elapsed > 0 ? ` (${elapsed}s)` : '';
57
+ process.stdout.clearLine(0);
58
+ process.stdout.cursorTo(0);
59
+ process.stdout.write(`${frame} ${this.message}${timeStr}`);
60
+ }
61
+ /**
62
+ * Stop the spinner and clear the line.
63
+ * Safe to call multiple times or if spinner never started.
64
+ */
65
+ stop() {
66
+ // Clear deferred display timer
67
+ if (this.displayTimer) {
68
+ clearTimeout(this.displayTimer);
69
+ this.displayTimer = null;
70
+ }
71
+ // Stop animation
72
+ if (this.interval) {
73
+ clearInterval(this.interval);
74
+ this.interval = null;
75
+ }
76
+ // Clear line if we were displaying
77
+ if (this.isSpinning && process.stdout.isTTY) {
78
+ process.stdout.clearLine(0);
79
+ process.stdout.cursorTo(0);
80
+ }
81
+ this.isSpinning = false;
82
+ }
83
+ }
84
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/utils/spinner.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafema/cli",
3
- "version": "0.2.3-beta",
3
+ "version": "0.2.5-beta",
4
4
  "description": "CLI for Grafema code analysis toolkit",
5
5
  "type": "module",
6
6
  "main": "./dist/cli.js",
@@ -28,7 +28,7 @@
28
28
  "author": "Vadim Reshetnikov",
29
29
  "repository": {
30
30
  "type": "git",
31
- "url": "https://github.com/grafema/grafema.git",
31
+ "url": "https://github.com/Disentinel/grafema.git",
32
32
  "directory": "packages/cli"
33
33
  },
34
34
  "dependencies": {
@@ -37,8 +37,9 @@
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.3-beta",
41
- "@grafema/types": "0.2.1-beta"
40
+ "@grafema/api": "0.2.5-beta",
41
+ "@grafema/core": "0.2.5-beta",
42
+ "@grafema/types": "0.2.5-beta"
42
43
  },
43
44
  "devDependencies": {
44
45
  "@types/node": "^25.0.8",