@grafema/cli 0.2.4-beta → 0.2.6-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.
- package/README.md +85 -0
- package/dist/cli.js +7 -2
- package/dist/cli.js.map +1 -0
- package/dist/commands/analyze.d.ts +3 -1
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +8 -266
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/analyzeAction.d.ts +28 -0
- package/dist/commands/analyzeAction.d.ts.map +1 -0
- package/dist/commands/analyzeAction.js +243 -0
- package/dist/commands/analyzeAction.js.map +1 -0
- package/dist/commands/check.d.ts +2 -6
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +34 -48
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/context.d.ts +16 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +238 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/coverage.js +1 -0
- package/dist/commands/coverage.js.map +1 -0
- package/dist/commands/doctor/checks.d.ts.map +1 -1
- package/dist/commands/doctor/checks.js +10 -6
- package/dist/commands/doctor/checks.js.map +1 -0
- package/dist/commands/doctor/output.js +1 -0
- package/dist/commands/doctor/output.js.map +1 -0
- package/dist/commands/doctor/types.js +1 -0
- package/dist/commands/doctor/types.js.map +1 -0
- package/dist/commands/doctor.js +1 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/explain.d.ts.map +1 -1
- package/dist/commands/explain.js +5 -3
- package/dist/commands/explain.js.map +1 -0
- package/dist/commands/explore.d.ts.map +1 -1
- package/dist/commands/explore.js +9 -4
- package/dist/commands/explore.js.map +1 -0
- package/dist/commands/file.d.ts +15 -0
- package/dist/commands/file.d.ts.map +1 -0
- package/dist/commands/file.js +144 -0
- package/dist/commands/file.js.map +1 -0
- package/dist/commands/get.d.ts.map +1 -1
- package/dist/commands/get.js +7 -0
- package/dist/commands/get.js.map +1 -0
- package/dist/commands/impact.d.ts.map +1 -1
- package/dist/commands/impact.js +3 -3
- package/dist/commands/impact.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +20 -2
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/ls.d.ts.map +1 -1
- package/dist/commands/ls.js +10 -2
- package/dist/commands/ls.js.map +1 -0
- package/dist/commands/overview.d.ts.map +1 -1
- package/dist/commands/overview.js +1 -0
- package/dist/commands/overview.js.map +1 -0
- package/dist/commands/query.d.ts +8 -0
- package/dist/commands/query.d.ts.map +1 -1
- package/dist/commands/query.js +217 -43
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/schema.d.ts.map +1 -1
- package/dist/commands/schema.js +4 -2
- package/dist/commands/schema.js.map +1 -0
- package/dist/commands/server.d.ts +2 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +76 -14
- package/dist/commands/server.js.map +1 -0
- package/dist/commands/setup-skill.d.ts +17 -0
- package/dist/commands/setup-skill.d.ts.map +1 -0
- package/dist/commands/setup-skill.js +131 -0
- package/dist/commands/setup-skill.js.map +1 -0
- package/dist/commands/stats.js +1 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/trace.d.ts.map +1 -1
- package/dist/commands/trace.js +21 -10
- package/dist/commands/trace.js.map +1 -0
- package/dist/commands/types.js +1 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/plugins/builtinPlugins.d.ts +10 -0
- package/dist/plugins/builtinPlugins.d.ts.map +1 -0
- package/dist/plugins/builtinPlugins.js +68 -0
- package/dist/plugins/builtinPlugins.js.map +1 -0
- package/dist/plugins/pluginLoader.d.ts +16 -0
- package/dist/plugins/pluginLoader.d.ts.map +1 -0
- package/dist/plugins/pluginLoader.js +101 -0
- package/dist/plugins/pluginLoader.js.map +1 -0
- package/dist/plugins/pluginResolver.js +38 -0
- package/dist/utils/codePreview.d.ts +1 -0
- package/dist/utils/codePreview.d.ts.map +1 -1
- package/dist/utils/codePreview.js +6 -3
- package/dist/utils/codePreview.js.map +1 -0
- package/dist/utils/errorFormatter.js +1 -0
- package/dist/utils/errorFormatter.js.map +1 -0
- package/dist/utils/formatNode.d.ts +1 -1
- package/dist/utils/formatNode.d.ts.map +1 -1
- package/dist/utils/formatNode.js +3 -2
- package/dist/utils/formatNode.js.map +1 -0
- package/dist/utils/pathUtils.d.ts +2 -0
- package/dist/utils/pathUtils.d.ts.map +1 -0
- package/dist/utils/pathUtils.js +9 -0
- package/dist/utils/pathUtils.js.map +1 -0
- package/dist/utils/progressRenderer.d.ts +119 -0
- package/dist/utils/progressRenderer.d.ts.map +1 -0
- package/dist/utils/progressRenderer.js +245 -0
- package/dist/utils/progressRenderer.js.map +1 -0
- package/dist/utils/spinner.d.ts +39 -0
- package/dist/utils/spinner.d.ts.map +1 -0
- package/dist/utils/spinner.js +84 -0
- package/dist/utils/spinner.js.map +1 -0
- package/package.json +8 -9
- package/skills/grafema-codebase-analysis/SKILL.md +295 -0
- package/skills/grafema-codebase-analysis/references/node-edge-types.md +123 -0
- package/skills/grafema-codebase-analysis/references/query-patterns.md +205 -0
- package/src/cli.ts +8 -2
- package/src/commands/analyze.ts +7 -342
- package/src/commands/analyzeAction.ts +284 -0
- package/src/commands/check.ts +38 -70
- package/src/commands/context.ts +309 -0
- package/src/commands/doctor/checks.ts +9 -6
- package/src/commands/explain.ts +4 -3
- package/src/commands/explore.tsx +15 -9
- package/src/commands/file.ts +179 -0
- package/src/commands/get.ts +8 -0
- package/src/commands/impact.ts +3 -4
- package/src/commands/init.ts +19 -3
- package/src/commands/ls.ts +11 -2
- package/src/commands/overview.ts +0 -4
- package/src/commands/query.ts +235 -44
- package/src/commands/schema.ts +3 -2
- package/src/commands/server.ts +85 -15
- package/src/commands/setup-skill.ts +162 -0
- package/src/commands/trace.ts +18 -9
- package/src/plugins/builtinPlugins.ts +108 -0
- package/src/plugins/pluginLoader.ts +123 -0
- package/src/plugins/pluginResolver.js +38 -0
- package/src/utils/codePreview.ts +7 -3
- package/src/utils/formatNode.ts +3 -3
- package/src/utils/pathUtils.ts +9 -0
- package/src/utils/progressRenderer.ts +288 -0
- package/src/utils/spinner.ts +94 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin loading — resolves built-in and custom plugins from config.
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - ESM resolve hook for custom plugin @grafema/* imports
|
|
6
|
+
* - Loading custom plugins from .grafema/plugins/
|
|
7
|
+
* - Creating plugin instances from config phases
|
|
8
|
+
*/
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import { existsSync, readdirSync } from 'fs';
|
|
11
|
+
import { pathToFileURL } from 'url';
|
|
12
|
+
import { register } from 'node:module';
|
|
13
|
+
import { BUILTIN_PLUGINS } from './builtinPlugins.js';
|
|
14
|
+
/**
|
|
15
|
+
* Register ESM resolve hook so custom plugins can import @grafema/* packages.
|
|
16
|
+
*
|
|
17
|
+
* Plugins in .grafema/plugins/ do `import { Plugin } from '@grafema/core'`,
|
|
18
|
+
* but @grafema/core isn't in the target project's node_modules/.
|
|
19
|
+
* This hook redirects those imports to the CLI's bundled packages.
|
|
20
|
+
*
|
|
21
|
+
* Uses module.register() (stable Node.js 20.6+ API).
|
|
22
|
+
* Safe to call multiple times — subsequent calls add redundant hooks
|
|
23
|
+
* that short-circuit on the same specifiers.
|
|
24
|
+
*/
|
|
25
|
+
let pluginResolverRegistered = false;
|
|
26
|
+
export function registerPluginResolver() {
|
|
27
|
+
if (pluginResolverRegistered)
|
|
28
|
+
return;
|
|
29
|
+
pluginResolverRegistered = true;
|
|
30
|
+
const grafemaPackages = {};
|
|
31
|
+
for (const pkg of ['@grafema/core', '@grafema/types']) {
|
|
32
|
+
try {
|
|
33
|
+
grafemaPackages[pkg] = import.meta.resolve(pkg);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Package not available from CLI context — skip
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
register(new URL('./pluginResolver.js', import.meta.url), { data: { grafemaPackages } });
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Load custom plugins from .grafema/plugins/ directory
|
|
43
|
+
*/
|
|
44
|
+
export async function loadCustomPlugins(projectPath, log) {
|
|
45
|
+
const pluginsDir = join(projectPath, '.grafema', 'plugins');
|
|
46
|
+
if (!existsSync(pluginsDir)) {
|
|
47
|
+
return {};
|
|
48
|
+
}
|
|
49
|
+
// Ensure @grafema/* imports resolve for custom plugins (REG-380)
|
|
50
|
+
registerPluginResolver();
|
|
51
|
+
const customPlugins = {};
|
|
52
|
+
try {
|
|
53
|
+
const files = readdirSync(pluginsDir).filter((f) => f.endsWith('.js') || f.endsWith('.mjs') || f.endsWith('.cjs'));
|
|
54
|
+
for (const file of files) {
|
|
55
|
+
try {
|
|
56
|
+
const pluginPath = join(pluginsDir, file);
|
|
57
|
+
const pluginUrl = pathToFileURL(pluginPath).href;
|
|
58
|
+
const module = await import(pluginUrl);
|
|
59
|
+
const PluginClass = module.default || module[file.replace(/\.[cm]?js$/, '')];
|
|
60
|
+
if (PluginClass && typeof PluginClass === 'function') {
|
|
61
|
+
const pluginName = PluginClass.name || file.replace(/\.[cm]?js$/, '');
|
|
62
|
+
customPlugins[pluginName] = () => {
|
|
63
|
+
const instance = new PluginClass();
|
|
64
|
+
instance.config.sourceFile = pluginPath;
|
|
65
|
+
return instance;
|
|
66
|
+
};
|
|
67
|
+
log(`Loaded custom plugin: ${pluginName}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
72
|
+
console.warn(`Failed to load plugin ${file}: ${message}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
78
|
+
console.warn(`Error loading custom plugins: ${message}`);
|
|
79
|
+
}
|
|
80
|
+
return customPlugins;
|
|
81
|
+
}
|
|
82
|
+
export function createPlugins(config, customPlugins = {}, verbose = false) {
|
|
83
|
+
const plugins = [];
|
|
84
|
+
const phases = ['discovery', 'indexing', 'analysis', 'enrichment', 'validation'];
|
|
85
|
+
for (const phase of phases) {
|
|
86
|
+
const names = config[phase] || [];
|
|
87
|
+
for (const name of names) {
|
|
88
|
+
// Check built-in first, then custom
|
|
89
|
+
const factory = BUILTIN_PLUGINS[name] || customPlugins[name];
|
|
90
|
+
if (factory) {
|
|
91
|
+
plugins.push(factory());
|
|
92
|
+
}
|
|
93
|
+
else if (verbose) {
|
|
94
|
+
// Only show plugin warning in verbose mode
|
|
95
|
+
console.warn(`Plugin not found: ${name} (skipping). Check .grafema/config.yaml or add to .grafema/plugins/`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return plugins;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=pluginLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pluginLoader.js","sourceRoot":"","sources":["../../src/plugins/pluginLoader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESM resolve hook for custom Grafema plugins.
|
|
3
|
+
*
|
|
4
|
+
* Allows plugins in .grafema/plugins/ to `import { Plugin } from '@grafema/core'`
|
|
5
|
+
* without requiring @grafema/core in the target project's node_modules/.
|
|
6
|
+
*
|
|
7
|
+
* The hook maps @grafema/* bare specifiers to the actual package URLs
|
|
8
|
+
* within the CLI's dependency tree.
|
|
9
|
+
*
|
|
10
|
+
* Registered via module.register() before loading custom plugins.
|
|
11
|
+
* Must be plain JS — loader hooks run in a separate thread.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** @type {Record<string, string>} package name → resolved file URL */
|
|
15
|
+
let grafemaPackages = {};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Called once when the hook is registered via module.register().
|
|
19
|
+
* @param {{ grafemaPackages: Record<string, string> }} data
|
|
20
|
+
*/
|
|
21
|
+
export function initialize(data) {
|
|
22
|
+
grafemaPackages = data.grafemaPackages;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Resolve hook — intercepts bare specifier imports for @grafema/* packages
|
|
27
|
+
* and redirects them to the CLI's bundled versions.
|
|
28
|
+
*
|
|
29
|
+
* Only exact package name matches are handled (e.g. '@grafema/core').
|
|
30
|
+
* All other specifiers pass through to the default resolver.
|
|
31
|
+
*/
|
|
32
|
+
export function resolve(specifier, context, next) {
|
|
33
|
+
if (grafemaPackages[specifier]) {
|
|
34
|
+
return { url: grafemaPackages[specifier], shortCircuit: true };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return next(specifier, context);
|
|
38
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codePreview.d.ts","sourceRoot":"","sources":["../../src/utils/codePreview.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"codePreview.d.ts","sourceRoot":"","sources":["../../src/utils/codePreview.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,GAAG,IAAI,CA4BpF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,iBAAiB,EAC1B,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,EAAE,CAeV"}
|
|
@@ -5,17 +5,19 @@
|
|
|
5
5
|
* for displaying in the explorer UI.
|
|
6
6
|
*/
|
|
7
7
|
import { readFileSync, existsSync } from 'fs';
|
|
8
|
+
import { isAbsolute, join } from 'path';
|
|
8
9
|
/**
|
|
9
10
|
* Get a code preview snippet from a source file.
|
|
10
11
|
* Returns lines around the specified line number with context.
|
|
11
12
|
*/
|
|
12
13
|
export function getCodePreview(options) {
|
|
13
|
-
const { file, line, contextBefore = 2, contextAfter = 12 } = options;
|
|
14
|
-
|
|
14
|
+
const { file, line, contextBefore = 2, contextAfter = 12, projectPath } = options;
|
|
15
|
+
const absoluteFile = projectPath && !isAbsolute(file) ? join(projectPath, file) : file;
|
|
16
|
+
if (!existsSync(absoluteFile)) {
|
|
15
17
|
return null;
|
|
16
18
|
}
|
|
17
19
|
try {
|
|
18
|
-
const content = readFileSync(
|
|
20
|
+
const content = readFileSync(absoluteFile, 'utf-8');
|
|
19
21
|
const allLines = content.split('\n');
|
|
20
22
|
// Calculate range (1-indexed)
|
|
21
23
|
const startLine = Math.max(1, line - contextBefore);
|
|
@@ -49,3 +51,4 @@ export function formatCodePreview(preview, highlightLine) {
|
|
|
49
51
|
return `${prefix}${paddedNum} | ${displayLine}`;
|
|
50
52
|
});
|
|
51
53
|
}
|
|
54
|
+
//# sourceMappingURL=codePreview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codePreview.js","sourceRoot":"","sources":["../../src/utils/codePreview.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAgBxC;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,OAA2B;IACxD,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,GAAG,CAAC,EAAE,YAAY,GAAG,EAAE,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAElF,MAAM,YAAY,GAAG,WAAW,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEvF,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAErC,8BAA8B;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,aAAa,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,GAAG,YAAY,CAAC,CAAC;QAE/D,wDAAwD;QACxD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;QAErD,OAAO;YACL,KAAK;YACL,SAAS;YACT,OAAO;SACR,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAA0B,EAC1B,aAAsB;IAEtB,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACrC,MAAM,UAAU,GAAG,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC;IAE/C,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC/B,MAAM,OAAO,GAAG,SAAS,GAAG,KAAK,CAAC;QAClC,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAErD,2BAA2B;QAC3B,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAExE,OAAO,GAAG,MAAM,GAAG,SAAS,MAAM,WAAW,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorFormatter.js","sourceRoot":"","sources":["../../src/utils/errorFormatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,SAAoB;IAC/D,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IAE5B,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -25,7 +25,7 @@ export interface DisplayableNode {
|
|
|
25
25
|
type: string;
|
|
26
26
|
/** Human-readable name */
|
|
27
27
|
name: string;
|
|
28
|
-
/**
|
|
28
|
+
/** Source file path (relative to project root, or absolute for legacy) */
|
|
29
29
|
file: string;
|
|
30
30
|
/** Line number (optional) */
|
|
31
31
|
line?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatNode.d.ts","sourceRoot":"","sources":["../../src/utils/formatNode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,
|
|
1
|
+
{"version":3,"file":"formatNode.d.ts","sourceRoot":"","sources":["../../src/utils/formatNode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAyBhE;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAoB3F;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAE9D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,WAAW,EAAE,MAAM,GAClB,MAAM,CAIR"}
|
package/dist/utils/formatNode.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Provides consistent formatting for node display across all CLI commands.
|
|
5
5
|
* Semantic IDs are shown as the PRIMARY identifier, with location as secondary.
|
|
6
6
|
*/
|
|
7
|
-
import { relative } from 'path';
|
|
7
|
+
import { isAbsolute, relative } from 'path';
|
|
8
8
|
/**
|
|
9
9
|
* Get the display name for a node based on its type.
|
|
10
10
|
*
|
|
@@ -77,6 +77,7 @@ export function formatNodeInline(node) {
|
|
|
77
77
|
export function formatLocation(file, line, projectPath) {
|
|
78
78
|
if (!file)
|
|
79
79
|
return '';
|
|
80
|
-
const relPath = relative(projectPath, file);
|
|
80
|
+
const relPath = isAbsolute(file) ? relative(projectPath, file) : file;
|
|
81
81
|
return line ? `${relPath}:${line}` : relPath;
|
|
82
82
|
}
|
|
83
|
+
//# sourceMappingURL=formatNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatNode.js","sourceRoot":"","sources":["../../src/utils/formatNode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAoC5C;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAqB;IACtD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,YAAY;YACf,+BAA+B;YAC/B,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC7B,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACvC,CAAC;YACD,MAAM;QACR,KAAK,cAAc;YACjB,yCAAyC;YACzC,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC5B,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACtC,CAAC;YACD,MAAM;IACV,CAAC;IACD,gEAAgE;IAChE,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IACD,sDAAsD;IACtD,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,sCAAsC;IACzD,CAAC;IACD,OAAO,IAAI,CAAC,EAAE,CAAC;AACjB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAqB,EAAE,OAA0B;IACjF,MAAM,EAAE,WAAW,EAAE,YAAY,GAAG,IAAI,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAClE,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,8CAA8C;IAC9C,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC7C,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC,CAAC;IAErD,2BAA2B;IAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,SAAS,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAExC,8BAA8B;IAC9B,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC9D,IAAI,GAAG,EAAE,CAAC;YACR,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,eAAe,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAqB;IACpD,OAAO,IAAI,CAAC,EAAE,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAwB,EACxB,IAAwB,EACxB,WAAmB;IAEnB,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACtE,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pathUtils.d.ts","sourceRoot":"","sources":["../../src/utils/pathUtils.ts"],"names":[],"mappings":"AAMA,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3E"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a node file path to relative display format.
|
|
3
|
+
* Handles both legacy absolute paths and new relative paths (REG-408).
|
|
4
|
+
*/
|
|
5
|
+
import { relative, isAbsolute } from 'path';
|
|
6
|
+
export function toRelativeDisplay(file, projectPath) {
|
|
7
|
+
return isAbsolute(file) ? relative(projectPath, file) : file;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=pathUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pathUtils.js","sourceRoot":"","sources":["../../src/utils/pathUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAE5C,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,WAAmB;IACjE,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC"}
|
|
@@ -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":"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"}
|