@grafema/cli 0.2.12-beta → 0.3.1-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/dist/cli.js +13 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +2 -4
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/analyzeAction.d.ts +5 -3
- package/dist/commands/analyzeAction.d.ts.map +1 -1
- package/dist/commands/analyzeAction.js +109 -151
- package/dist/commands/analyzeAction.js.map +1 -1
- package/dist/commands/check.d.ts +1 -1
- package/dist/commands/check.js +4 -4
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/context.js +2 -2
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/coverage.js +2 -2
- package/dist/commands/coverage.js.map +1 -1
- package/dist/commands/describe.d.ts +13 -0
- package/dist/commands/describe.d.ts.map +1 -0
- package/dist/commands/describe.js +131 -0
- package/dist/commands/describe.js.map +1 -0
- package/dist/commands/doctor/checks.d.ts +6 -1
- package/dist/commands/doctor/checks.d.ts.map +1 -1
- package/dist/commands/doctor/checks.js +128 -13
- package/dist/commands/doctor/checks.js.map +1 -1
- package/dist/commands/doctor.d.ts +10 -9
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +12 -10
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain.js +2 -2
- package/dist/commands/explain.js.map +1 -1
- package/dist/commands/file.js +2 -2
- package/dist/commands/file.js.map +1 -1
- package/dist/commands/get.js +2 -2
- package/dist/commands/get.js.map +1 -1
- package/dist/commands/git-ingest.d.ts +6 -0
- package/dist/commands/git-ingest.d.ts.map +1 -0
- package/dist/commands/git-ingest.js +46 -0
- package/dist/commands/git-ingest.js.map +1 -0
- package/dist/commands/impact.d.ts.map +1 -1
- package/dist/commands/impact.js +276 -50
- package/dist/commands/impact.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +20 -22
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/ls.js +2 -2
- package/dist/commands/ls.js.map +1 -1
- package/dist/commands/overview.js +2 -2
- package/dist/commands/overview.js.map +1 -1
- package/dist/commands/query.d.ts +1 -1
- package/dist/commands/query.d.ts.map +1 -1
- package/dist/commands/query.js +169 -7
- package/dist/commands/query.js.map +1 -1
- package/dist/commands/schema.js +2 -2
- package/dist/commands/schema.js.map +1 -1
- package/dist/commands/server.js +11 -6
- package/dist/commands/server.js.map +1 -1
- package/dist/commands/stats.js +2 -2
- package/dist/commands/stats.js.map +1 -1
- package/dist/commands/tldr.d.ts +12 -0
- package/dist/commands/tldr.d.ts.map +1 -0
- package/dist/commands/tldr.js +81 -0
- package/dist/commands/tldr.js.map +1 -0
- package/dist/commands/trace.d.ts +1 -1
- package/dist/commands/trace.d.ts.map +1 -1
- package/dist/commands/trace.js +17 -133
- package/dist/commands/trace.js.map +1 -1
- package/dist/commands/types.js +2 -2
- package/dist/commands/types.js.map +1 -1
- package/dist/commands/who.d.ts +12 -0
- package/dist/commands/who.d.ts.map +1 -0
- package/dist/commands/who.js +184 -0
- package/dist/commands/who.js.map +1 -0
- package/dist/commands/why.d.ts +12 -0
- package/dist/commands/why.d.ts.map +1 -0
- package/dist/commands/why.js +118 -0
- package/dist/commands/why.js.map +1 -0
- package/dist/commands/wtf.d.ts +12 -0
- package/dist/commands/wtf.d.ts.map +1 -0
- package/dist/commands/wtf.js +117 -0
- package/dist/commands/wtf.js.map +1 -0
- package/dist/plugins/builtinPlugins.d.ts +1 -9
- package/dist/plugins/builtinPlugins.d.ts.map +1 -1
- package/dist/plugins/builtinPlugins.js +2 -67
- package/dist/plugins/builtinPlugins.js.map +1 -1
- package/dist/plugins/pluginLoader.d.ts +1 -15
- package/dist/plugins/pluginLoader.d.ts.map +1 -1
- package/dist/plugins/pluginLoader.js +2 -100
- package/dist/plugins/pluginLoader.js.map +1 -1
- package/dist/plugins/pluginResolver.js +3 -3
- package/dist/utils/progressRenderer.d.ts +15 -1
- package/dist/utils/progressRenderer.d.ts.map +1 -1
- package/dist/utils/progressRenderer.js.map +1 -1
- package/dist/utils/queryHints.d.ts +6 -0
- package/dist/utils/queryHints.d.ts.map +1 -0
- package/dist/utils/queryHints.js +36 -0
- package/dist/utils/queryHints.js.map +1 -0
- package/package.json +4 -4
- package/skills/grafema-codebase-analysis/SKILL.md +1 -1
- package/src/cli.ts +14 -0
- package/src/commands/analyze.ts +2 -4
- package/src/commands/analyzeAction.ts +122 -168
- package/src/commands/check.ts +5 -5
- package/src/commands/context.ts +3 -3
- package/src/commands/coverage.ts +2 -2
- package/src/commands/describe.ts +160 -0
- package/src/commands/doctor/checks.ts +153 -10
- package/src/commands/doctor.ts +13 -9
- package/src/commands/explain.ts +2 -2
- package/src/commands/explore.tsx +2 -2
- package/src/commands/file.ts +3 -3
- package/src/commands/get.ts +2 -2
- package/src/commands/git-ingest.ts +49 -0
- package/src/commands/impact.ts +318 -55
- package/src/commands/init.ts +20 -22
- package/src/commands/ls.ts +2 -2
- package/src/commands/overview.ts +2 -2
- package/src/commands/query.ts +197 -7
- package/src/commands/schema.ts +2 -2
- package/src/commands/server.ts +12 -6
- package/src/commands/stats.ts +2 -2
- package/src/commands/tldr.ts +103 -0
- package/src/commands/trace.ts +19 -161
- package/src/commands/types.ts +2 -2
- package/src/commands/who.ts +215 -0
- package/src/commands/why.ts +134 -0
- package/src/commands/wtf.ts +140 -0
- package/src/plugins/builtinPlugins.ts +1 -108
- package/src/plugins/pluginLoader.ts +1 -123
- package/src/plugins/pluginResolver.js +3 -3
- package/src/utils/progressRenderer.ts +15 -1
- package/src/utils/queryHints.ts +46 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* who command — "Who uses this?"
|
|
3
|
+
*
|
|
4
|
+
* Find all callers and references to a symbol.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* grafema who authenticate # Who calls authenticate()?
|
|
8
|
+
* grafema who UserService.findById # Who calls this method?
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
import { resolve, join, isAbsolute, relative } from 'path';
|
|
12
|
+
import { existsSync } from 'fs';
|
|
13
|
+
import { RFDBServerBackend } from '@grafema/util';
|
|
14
|
+
import { exitWithError } from '../utils/errorFormatter.js';
|
|
15
|
+
import { Spinner } from '../utils/spinner.js';
|
|
16
|
+
export const whoCommand = new Command('who')
|
|
17
|
+
.description('Who uses this? — find all callers/references to a symbol')
|
|
18
|
+
.argument('<symbol>', 'Function or method name')
|
|
19
|
+
.option('-p, --project <path>', 'Project path', '.')
|
|
20
|
+
.option('-j, --json', 'Output as JSON')
|
|
21
|
+
.addHelpText('after', `
|
|
22
|
+
Examples:
|
|
23
|
+
grafema who authenticate Who calls authenticate()?
|
|
24
|
+
grafema who UserService.findById Who calls this method?
|
|
25
|
+
grafema who handleRequest --json Output as JSON
|
|
26
|
+
`)
|
|
27
|
+
.action(async (symbol, options) => {
|
|
28
|
+
const projectPath = resolve(options.project);
|
|
29
|
+
const grafemaDir = join(projectPath, '.grafema');
|
|
30
|
+
const dbPath = join(grafemaDir, 'graph.rfdb');
|
|
31
|
+
if (!existsSync(dbPath)) {
|
|
32
|
+
exitWithError('No graph database found', ['Run: grafema analyze']);
|
|
33
|
+
}
|
|
34
|
+
const backend = new RFDBServerBackend({ dbPath, clientName: 'cli' });
|
|
35
|
+
await backend.connect();
|
|
36
|
+
const spinner = new Spinner('Searching for callers...');
|
|
37
|
+
spinner.start();
|
|
38
|
+
try {
|
|
39
|
+
const lowerSymbol = symbol.toLowerCase();
|
|
40
|
+
// If symbol has a dot, extract the part after the last dot for method matching
|
|
41
|
+
const dotIndex = symbol.lastIndexOf('.');
|
|
42
|
+
const methodPart = dotIndex >= 0 ? symbol.substring(dotIndex + 1).toLowerCase() : null;
|
|
43
|
+
// Strategy 1: Find CALL nodes that match the symbol name
|
|
44
|
+
// (same approach as MCP handleFindCalls)
|
|
45
|
+
const matchingCalls = [];
|
|
46
|
+
for await (const node of backend.queryNodes({ type: 'CALL' })) {
|
|
47
|
+
const callName = (node.name || '').toLowerCase();
|
|
48
|
+
// Match exact name or method part after last dot
|
|
49
|
+
let isMatch = callName === lowerSymbol;
|
|
50
|
+
if (!isMatch && methodPart) {
|
|
51
|
+
const callMethodPart = callName.lastIndexOf('.') >= 0
|
|
52
|
+
? callName.substring(callName.lastIndexOf('.') + 1)
|
|
53
|
+
: callName;
|
|
54
|
+
isMatch = callMethodPart === methodPart;
|
|
55
|
+
}
|
|
56
|
+
if (!isMatch && !methodPart) {
|
|
57
|
+
// Also match if the call name ends with the symbol (e.g., "obj.authenticate" matches "authenticate")
|
|
58
|
+
const callMethodPart = callName.lastIndexOf('.') >= 0
|
|
59
|
+
? callName.substring(callName.lastIndexOf('.') + 1)
|
|
60
|
+
: null;
|
|
61
|
+
if (callMethodPart === lowerSymbol)
|
|
62
|
+
isMatch = true;
|
|
63
|
+
}
|
|
64
|
+
if (!isMatch)
|
|
65
|
+
continue;
|
|
66
|
+
// Check resolution status via CALLS edges
|
|
67
|
+
const edges = await backend.getOutgoingEdges(node.id, ['CALLS']);
|
|
68
|
+
const resolved = edges.length > 0;
|
|
69
|
+
// Extract caller name from semantic ID
|
|
70
|
+
// Format: "file->SCOPE->TYPE->name" — parent scope is the caller
|
|
71
|
+
const idParts = node.id.split('->');
|
|
72
|
+
let callerName = '<anonymous>';
|
|
73
|
+
// Walk up the scope chain to find a FUNCTION or METHOD parent
|
|
74
|
+
for (let i = idParts.length - 3; i >= 1; i--) {
|
|
75
|
+
if (idParts[i] === 'FUNCTION' || idParts[i] === 'METHOD') {
|
|
76
|
+
callerName = idParts[i + 1] || callerName;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const file = node.file || '';
|
|
81
|
+
matchingCalls.push({
|
|
82
|
+
file,
|
|
83
|
+
line: node.line,
|
|
84
|
+
callerName,
|
|
85
|
+
resolved,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
// Strategy 2: Find the target function/method node and check incoming CALLS/READS_FROM edges
|
|
89
|
+
const incomingCallers = [];
|
|
90
|
+
let funcNode = null;
|
|
91
|
+
// Search for FUNCTION, METHOD, CLASS, or CONSTANT node matching the symbol
|
|
92
|
+
for (const nodeType of ['FUNCTION', 'METHOD', 'CLASS', 'CONSTANT']) {
|
|
93
|
+
for await (const n of backend.queryNodes({ type: nodeType })) {
|
|
94
|
+
const name = (n.name || '').toLowerCase();
|
|
95
|
+
if (name === lowerSymbol || (methodPart && name === methodPart)) {
|
|
96
|
+
funcNode = n;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (funcNode)
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
if (funcNode) {
|
|
104
|
+
const incomingEdges = await backend.getIncomingEdges(funcNode.id, ['CALLS', 'READS_FROM', 'IMPORTS_FROM']);
|
|
105
|
+
for (const edge of incomingEdges) {
|
|
106
|
+
const srcNode = await backend.getNode(edge.src);
|
|
107
|
+
if (!srcNode)
|
|
108
|
+
continue;
|
|
109
|
+
// Deduplicate — skip if we already found this call via Strategy 1
|
|
110
|
+
if (matchingCalls.some(c => c.file === (srcNode.file || '') && c.line === srcNode.line)) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
incomingCallers.push({
|
|
114
|
+
file: srcNode.file || '',
|
|
115
|
+
line: srcNode.line,
|
|
116
|
+
callerName: srcNode.name || '<anonymous>',
|
|
117
|
+
resolved: true,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Strategy 3: Find IMPORT_BINDING nodes that import this symbol
|
|
122
|
+
// (for classes/exports that are imported across files/repos)
|
|
123
|
+
const importers = [];
|
|
124
|
+
for await (const n of backend.queryNodes({ type: 'IMPORT_BINDING' })) {
|
|
125
|
+
const bindingName = (n.name || '').toLowerCase();
|
|
126
|
+
if (bindingName !== lowerSymbol && !(methodPart && bindingName === methodPart))
|
|
127
|
+
continue;
|
|
128
|
+
// Skip if already found via Strategy 1 or 2
|
|
129
|
+
if (matchingCalls.some(c => c.file === (n.file || '') && c.line === n.line))
|
|
130
|
+
continue;
|
|
131
|
+
if (incomingCallers.some(c => c.file === (n.file || '') && c.line === n.line))
|
|
132
|
+
continue;
|
|
133
|
+
importers.push({
|
|
134
|
+
file: n.file || '',
|
|
135
|
+
line: n.line,
|
|
136
|
+
callerName: `imports ${n.name || symbol}`,
|
|
137
|
+
resolved: true,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
spinner.stop();
|
|
141
|
+
// Merge results
|
|
142
|
+
const allCallers = [...matchingCalls, ...incomingCallers, ...importers];
|
|
143
|
+
if (options.json) {
|
|
144
|
+
console.log(JSON.stringify({
|
|
145
|
+
symbol,
|
|
146
|
+
targetNode: funcNode ? { id: funcNode.id, type: funcNode.type, name: funcNode.name, file: funcNode.file } : null,
|
|
147
|
+
callers: allCallers.map(c => ({
|
|
148
|
+
file: c.file,
|
|
149
|
+
line: c.line,
|
|
150
|
+
caller: c.callerName,
|
|
151
|
+
resolved: c.resolved,
|
|
152
|
+
})),
|
|
153
|
+
total: allCallers.length,
|
|
154
|
+
}, null, 2));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (allCallers.length === 0) {
|
|
158
|
+
console.log(`${symbol} — no callers found`);
|
|
159
|
+
console.log('');
|
|
160
|
+
console.log('Hints:');
|
|
161
|
+
console.log(' - Check the symbol name is correct');
|
|
162
|
+
console.log(' - The function may be exported but unused in analyzed code');
|
|
163
|
+
console.log(' - Use: grafema query "<name>" to verify the symbol exists');
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
console.log(`${symbol} — ${allCallers.length} caller${allCallers.length === 1 ? '' : 's'}`);
|
|
167
|
+
console.log('');
|
|
168
|
+
for (const caller of allCallers) {
|
|
169
|
+
const relFile = isAbsolute(caller.file)
|
|
170
|
+
? relative(projectPath, caller.file)
|
|
171
|
+
: caller.file;
|
|
172
|
+
const location = caller.line ? `${relFile}:${caller.line}` : relFile;
|
|
173
|
+
const status = caller.resolved ? '[resolved]' : '[unresolved]';
|
|
174
|
+
const paddedLocation = location.padEnd(30);
|
|
175
|
+
const paddedCaller = caller.callerName.padEnd(20);
|
|
176
|
+
console.log(` ${paddedLocation} ${paddedCaller} ${status}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
spinner.stop();
|
|
181
|
+
await backend.close();
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
//# sourceMappingURL=who.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"who.js","sourceRoot":"","sources":["../../src/commands/who.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* why command — "Why is it this way?"
|
|
3
|
+
*
|
|
4
|
+
* Query knowledge base for architectural decisions and facts about a symbol or module.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* grafema why auth-middleware # Why was auth middleware designed this way?
|
|
8
|
+
* grafema why UserService # Decisions about UserService
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
export declare const whyCommand: Command;
|
|
12
|
+
//# sourceMappingURL=why.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"why.d.ts","sourceRoot":"","sources":["../../src/commands/why.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,eAAO,MAAM,UAAU,SA8GnB,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* why command — "Why is it this way?"
|
|
3
|
+
*
|
|
4
|
+
* Query knowledge base for architectural decisions and facts about a symbol or module.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* grafema why auth-middleware # Why was auth middleware designed this way?
|
|
8
|
+
* grafema why UserService # Decisions about UserService
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
import { resolve, join } from 'path';
|
|
12
|
+
import { existsSync } from 'fs';
|
|
13
|
+
import { KnowledgeBase } from '@grafema/util';
|
|
14
|
+
import { exitWithError } from '../utils/errorFormatter.js';
|
|
15
|
+
import { Spinner } from '../utils/spinner.js';
|
|
16
|
+
export const whyCommand = new Command('why')
|
|
17
|
+
.description('Why is it this way? — query knowledge base decisions and facts')
|
|
18
|
+
.argument('<query>', 'Search text (symbol name, module, or topic)')
|
|
19
|
+
.option('-p, --project <path>', 'Project path', '.')
|
|
20
|
+
.option('-j, --json', 'Output as JSON')
|
|
21
|
+
.addHelpText('after', `
|
|
22
|
+
Examples:
|
|
23
|
+
grafema why auth-middleware Why was auth middleware designed this way?
|
|
24
|
+
grafema why UserService Decisions about UserService
|
|
25
|
+
grafema why "error handling" Facts about error handling approach
|
|
26
|
+
grafema why dataflow --json Output as JSON
|
|
27
|
+
`)
|
|
28
|
+
.action(async (query, options) => {
|
|
29
|
+
const projectPath = resolve(options.project);
|
|
30
|
+
const knowledgeDir = join(projectPath, 'knowledge');
|
|
31
|
+
if (!existsSync(knowledgeDir)) {
|
|
32
|
+
exitWithError('No knowledge base found', [
|
|
33
|
+
'Knowledge directory not found: ' + knowledgeDir,
|
|
34
|
+
'Use `add_knowledge` MCP tool to capture architectural decisions',
|
|
35
|
+
]);
|
|
36
|
+
}
|
|
37
|
+
const spinner = new Spinner('Searching knowledge base...');
|
|
38
|
+
spinner.start();
|
|
39
|
+
try {
|
|
40
|
+
const kb = new KnowledgeBase(knowledgeDir);
|
|
41
|
+
await kb.load();
|
|
42
|
+
// Search DECISION nodes matching query text
|
|
43
|
+
const decisions = await kb.queryNodes({ type: 'DECISION', text: query });
|
|
44
|
+
// Search FACT nodes matching query text
|
|
45
|
+
const facts = await kb.queryNodes({ type: 'FACT', text: query });
|
|
46
|
+
spinner.stop();
|
|
47
|
+
if (options.json) {
|
|
48
|
+
console.log(JSON.stringify({
|
|
49
|
+
query,
|
|
50
|
+
decisions: decisions.map(d => ({
|
|
51
|
+
id: d.id,
|
|
52
|
+
status: d.status,
|
|
53
|
+
content: d.content,
|
|
54
|
+
applies_to: d.applies_to,
|
|
55
|
+
relates_to: d.relates_to,
|
|
56
|
+
})),
|
|
57
|
+
facts: facts.map(f => ({
|
|
58
|
+
id: f.id,
|
|
59
|
+
confidence: f.confidence,
|
|
60
|
+
content: f.content,
|
|
61
|
+
relates_to: f.relates_to,
|
|
62
|
+
})),
|
|
63
|
+
total: decisions.length + facts.length,
|
|
64
|
+
}, null, 2));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (decisions.length === 0 && facts.length === 0) {
|
|
68
|
+
console.log(`No knowledge found for: "${query}"`);
|
|
69
|
+
console.log('');
|
|
70
|
+
console.log('No decisions or facts recorded matching this query.');
|
|
71
|
+
console.log('Use `add_knowledge` MCP tool to capture architectural decisions.');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// Display decisions
|
|
75
|
+
if (decisions.length > 0) {
|
|
76
|
+
console.log(`Decisions (${decisions.length}):`);
|
|
77
|
+
console.log('');
|
|
78
|
+
for (const d of decisions) {
|
|
79
|
+
console.log(` [${d.status?.toUpperCase() || 'ACTIVE'}] ${d.id}`);
|
|
80
|
+
// Show first ~200 chars of content as summary
|
|
81
|
+
const summary = d.content.length > 200
|
|
82
|
+
? d.content.substring(0, 200) + '...'
|
|
83
|
+
: d.content;
|
|
84
|
+
// Indent content lines
|
|
85
|
+
for (const line of summary.split('\n')) {
|
|
86
|
+
console.log(` ${line}`);
|
|
87
|
+
}
|
|
88
|
+
if (d.applies_to && d.applies_to.length > 0) {
|
|
89
|
+
console.log(` Applies to: ${d.applies_to.join(', ')}`);
|
|
90
|
+
}
|
|
91
|
+
console.log('');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Display facts
|
|
95
|
+
if (facts.length > 0) {
|
|
96
|
+
console.log(`Facts (${facts.length}):`);
|
|
97
|
+
console.log('');
|
|
98
|
+
for (const f of facts) {
|
|
99
|
+
const confidence = f.confidence ? ` [${f.confidence}]` : '';
|
|
100
|
+
console.log(` ${f.id}${confidence}`);
|
|
101
|
+
const summary = f.content.length > 200
|
|
102
|
+
? f.content.substring(0, 200) + '...'
|
|
103
|
+
: f.content;
|
|
104
|
+
for (const line of summary.split('\n')) {
|
|
105
|
+
console.log(` ${line}`);
|
|
106
|
+
}
|
|
107
|
+
if (f.relates_to && f.relates_to.length > 0) {
|
|
108
|
+
console.log(` Relates to: ${f.relates_to.join(', ')}`);
|
|
109
|
+
}
|
|
110
|
+
console.log('');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
spinner.stop();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
//# sourceMappingURL=why.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"why.js","sourceRoot":"","sources":["../../src/commands/why.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wtf command — "Where does this come from?"
|
|
3
|
+
*
|
|
4
|
+
* Backward dataflow trace with arrow-formatted output.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* grafema wtf req.user # Backward trace
|
|
8
|
+
* grafema wtf config.apiKey # Where does this value originate?
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
export declare const wtfCommand: Command;
|
|
12
|
+
//# sourceMappingURL=wtf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wtf.d.ts","sourceRoot":"","sources":["../../src/commands/wtf.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,eAAO,MAAM,UAAU,SA+GnB,CAAC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wtf command — "Where does this come from?"
|
|
3
|
+
*
|
|
4
|
+
* Backward dataflow trace with arrow-formatted output.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* grafema wtf req.user # Backward trace
|
|
8
|
+
* grafema wtf config.apiKey # Where does this value originate?
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
import { resolve, join } from 'path';
|
|
12
|
+
import { existsSync } from 'fs';
|
|
13
|
+
import { RFDBServerBackend, traceDataflow, renderTraceNarrative, } from '@grafema/util';
|
|
14
|
+
import { exitWithError } from '../utils/errorFormatter.js';
|
|
15
|
+
import { Spinner } from '../utils/spinner.js';
|
|
16
|
+
export const wtfCommand = new Command('wtf')
|
|
17
|
+
.description('Where does this come from? — backward dataflow trace')
|
|
18
|
+
.argument('<symbol>', 'Variable, constant, or parameter name to trace')
|
|
19
|
+
.option('-p, --project <path>', 'Project path', '.')
|
|
20
|
+
.option('-d, --depth <n>', 'Max trace depth', '10')
|
|
21
|
+
.option('-j, --json', 'Output as JSON')
|
|
22
|
+
.addHelpText('after', `
|
|
23
|
+
Examples:
|
|
24
|
+
grafema wtf req.user Trace where req.user comes from
|
|
25
|
+
grafema wtf config.apiKey Where does this value originate?
|
|
26
|
+
grafema wtf userId --depth 5 Limit trace depth
|
|
27
|
+
grafema wtf token --json Output as JSON
|
|
28
|
+
`)
|
|
29
|
+
.action(async (symbol, options) => {
|
|
30
|
+
const projectPath = resolve(options.project);
|
|
31
|
+
const grafemaDir = join(projectPath, '.grafema');
|
|
32
|
+
const dbPath = join(grafemaDir, 'graph.rfdb');
|
|
33
|
+
if (!existsSync(dbPath)) {
|
|
34
|
+
exitWithError('No graph database found', ['Run: grafema analyze']);
|
|
35
|
+
}
|
|
36
|
+
const maxDepth = parseInt(options.depth, 10);
|
|
37
|
+
if (isNaN(maxDepth) || maxDepth < 1) {
|
|
38
|
+
exitWithError('Invalid depth', ['Provide a positive integer']);
|
|
39
|
+
}
|
|
40
|
+
const backend = new RFDBServerBackend({ dbPath, clientName: 'cli' });
|
|
41
|
+
await backend.connect();
|
|
42
|
+
const spinner = new Spinner('Searching for symbol...');
|
|
43
|
+
spinner.start();
|
|
44
|
+
try {
|
|
45
|
+
// Find the node: search VARIABLE, CONSTANT, PARAMETER by name (case-insensitive)
|
|
46
|
+
// Also try PROPERTY_ACCESS by matching method part after last dot
|
|
47
|
+
const lowerSymbol = symbol.toLowerCase();
|
|
48
|
+
// If symbol has a dot, extract the part after the last dot for method matching
|
|
49
|
+
const dotIndex = symbol.lastIndexOf('.');
|
|
50
|
+
const methodPart = dotIndex >= 0 ? symbol.substring(dotIndex + 1).toLowerCase() : null;
|
|
51
|
+
let found = null;
|
|
52
|
+
for (const nodeType of ['VARIABLE', 'CONSTANT', 'PARAMETER']) {
|
|
53
|
+
for await (const n of backend.queryNodes({ type: nodeType })) {
|
|
54
|
+
const name = (n.name || '').toLowerCase();
|
|
55
|
+
if (name === lowerSymbol) {
|
|
56
|
+
found = { id: n.id, type: n.type || nodeType, name: n.name || '', file: n.file || '', line: n.line };
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (found)
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
// Try PROPERTY_ACCESS if not found and symbol has a dot
|
|
64
|
+
if (!found && methodPart) {
|
|
65
|
+
for await (const n of backend.queryNodes({ type: 'PROPERTY_ACCESS' })) {
|
|
66
|
+
const name = (n.name || '').toLowerCase();
|
|
67
|
+
// Match by full name or by the part after last dot
|
|
68
|
+
const nameMethodPart = name.lastIndexOf('.') >= 0
|
|
69
|
+
? name.substring(name.lastIndexOf('.') + 1)
|
|
70
|
+
: name;
|
|
71
|
+
if (name === lowerSymbol || nameMethodPart === methodPart) {
|
|
72
|
+
found = { id: n.id, type: n.type || 'PROPERTY_ACCESS', name: n.name || '', file: n.file || '', line: n.line };
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!found) {
|
|
78
|
+
spinner.stop();
|
|
79
|
+
exitWithError(`Symbol not found: "${symbol}"`, [
|
|
80
|
+
'Check the symbol name and try again',
|
|
81
|
+
'Use: grafema query "<name>" to search available nodes',
|
|
82
|
+
]);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
spinner.stop();
|
|
86
|
+
// Cast backend to DataflowBackend
|
|
87
|
+
const dfDb = backend;
|
|
88
|
+
// Trace backward
|
|
89
|
+
const results = await traceDataflow(dfDb, found.id, {
|
|
90
|
+
direction: 'backward',
|
|
91
|
+
maxDepth,
|
|
92
|
+
});
|
|
93
|
+
if (options.json) {
|
|
94
|
+
console.log(JSON.stringify({
|
|
95
|
+
symbol: found.name,
|
|
96
|
+
node: found,
|
|
97
|
+
results: results.map(r => ({
|
|
98
|
+
direction: r.direction,
|
|
99
|
+
startNode: r.startNode,
|
|
100
|
+
reached: r.reached,
|
|
101
|
+
totalReached: r.totalReached,
|
|
102
|
+
})),
|
|
103
|
+
}, null, 2));
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
console.log(`${found.name} (${found.type}) — ${found.file}${found.line ? ':' + found.line : ''}`);
|
|
107
|
+
console.log('');
|
|
108
|
+
const narrative = renderTraceNarrative(results, found.name, { detail: 'normal' });
|
|
109
|
+
console.log(narrative);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
spinner.stop();
|
|
114
|
+
await backend.close();
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
//# sourceMappingURL=wtf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wtf.js","sourceRoot":"","sources":["../../src/commands/wtf.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* Built-in plugin registry — maps plugin names to factory functions.
|
|
3
|
-
*
|
|
4
|
-
* Each entry creates a fresh plugin instance. Plugin names match the class names
|
|
5
|
-
* and are referenced by name in .grafema/config.yaml under phases:
|
|
6
|
-
* discovery, indexing, analysis, enrichment, validation.
|
|
7
|
-
*/
|
|
8
|
-
import type { Plugin } from '@grafema/core';
|
|
9
|
-
export declare const BUILTIN_PLUGINS: Record<string, () => Plugin>;
|
|
1
|
+
export {};
|
|
10
2
|
//# sourceMappingURL=builtinPlugins.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtinPlugins.d.ts","sourceRoot":"","sources":["../../src/plugins/builtinPlugins.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"builtinPlugins.d.ts","sourceRoot":"","sources":["../../src/plugins/builtinPlugins.ts"],"names":[],"mappings":""}
|
|
@@ -1,68 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* Each entry creates a fresh plugin instance. Plugin names match the class names
|
|
5
|
-
* and are referenced by name in .grafema/config.yaml under phases:
|
|
6
|
-
* discovery, indexing, analysis, enrichment, validation.
|
|
7
|
-
*/
|
|
8
|
-
import {
|
|
9
|
-
// Discovery
|
|
10
|
-
SimpleProjectDiscovery, MonorepoServiceDiscovery, WorkspaceDiscovery,
|
|
11
|
-
// Indexing
|
|
12
|
-
JSModuleIndexer, RustModuleIndexer,
|
|
13
|
-
// Analysis
|
|
14
|
-
JSASTAnalyzer, ExpressRouteAnalyzer, ExpressResponseAnalyzer, NestJSRouteAnalyzer, SocketIOAnalyzer, DatabaseAnalyzer, FetchAnalyzer, ServiceLayerAnalyzer, ReactAnalyzer, RustAnalyzer,
|
|
15
|
-
// Enrichment
|
|
16
|
-
MethodCallResolver, ArgumentParameterLinker, AliasTracker, ValueDomainAnalyzer, MountPointResolver, ExpressHandlerLinker, PrefixEvaluator, InstanceOfResolver, ImportExportLinker, FunctionCallResolver, HTTPConnectionEnricher, ConfigRoutingMapBuilder, ServiceConnectionEnricher, RustFFIEnricher, RejectionPropagationEnricher, CallbackCallResolver,
|
|
17
|
-
// Validation
|
|
18
|
-
CallResolverValidator, EvalBanValidator, SQLInjectionValidator, AwaitInLoopValidator, ShadowingDetector, GraphConnectivityValidator, DataFlowValidator, TypeScriptDeadCodeValidator, BrokenImportValidator, UnconnectedRouteValidator, PackageCoverageValidator, } from '@grafema/core';
|
|
19
|
-
export const BUILTIN_PLUGINS = {
|
|
20
|
-
// Discovery
|
|
21
|
-
SimpleProjectDiscovery: () => new SimpleProjectDiscovery(),
|
|
22
|
-
MonorepoServiceDiscovery: () => new MonorepoServiceDiscovery(),
|
|
23
|
-
WorkspaceDiscovery: () => new WorkspaceDiscovery(),
|
|
24
|
-
// Indexing
|
|
25
|
-
JSModuleIndexer: () => new JSModuleIndexer(),
|
|
26
|
-
RustModuleIndexer: () => new RustModuleIndexer(),
|
|
27
|
-
// Analysis
|
|
28
|
-
JSASTAnalyzer: () => new JSASTAnalyzer(),
|
|
29
|
-
ExpressRouteAnalyzer: () => new ExpressRouteAnalyzer(),
|
|
30
|
-
ExpressResponseAnalyzer: () => new ExpressResponseAnalyzer(),
|
|
31
|
-
NestJSRouteAnalyzer: () => new NestJSRouteAnalyzer(),
|
|
32
|
-
SocketIOAnalyzer: () => new SocketIOAnalyzer(),
|
|
33
|
-
DatabaseAnalyzer: () => new DatabaseAnalyzer(),
|
|
34
|
-
FetchAnalyzer: () => new FetchAnalyzer(),
|
|
35
|
-
ServiceLayerAnalyzer: () => new ServiceLayerAnalyzer(),
|
|
36
|
-
ReactAnalyzer: () => new ReactAnalyzer(),
|
|
37
|
-
RustAnalyzer: () => new RustAnalyzer(),
|
|
38
|
-
// Enrichment
|
|
39
|
-
MethodCallResolver: () => new MethodCallResolver(),
|
|
40
|
-
ArgumentParameterLinker: () => new ArgumentParameterLinker(),
|
|
41
|
-
AliasTracker: () => new AliasTracker(),
|
|
42
|
-
ValueDomainAnalyzer: () => new ValueDomainAnalyzer(),
|
|
43
|
-
MountPointResolver: () => new MountPointResolver(),
|
|
44
|
-
ExpressHandlerLinker: () => new ExpressHandlerLinker(),
|
|
45
|
-
PrefixEvaluator: () => new PrefixEvaluator(),
|
|
46
|
-
InstanceOfResolver: () => new InstanceOfResolver(),
|
|
47
|
-
ImportExportLinker: () => new ImportExportLinker(),
|
|
48
|
-
FunctionCallResolver: () => new FunctionCallResolver(),
|
|
49
|
-
HTTPConnectionEnricher: () => new HTTPConnectionEnricher(),
|
|
50
|
-
ConfigRoutingMapBuilder: () => new ConfigRoutingMapBuilder(),
|
|
51
|
-
ServiceConnectionEnricher: () => new ServiceConnectionEnricher(),
|
|
52
|
-
RustFFIEnricher: () => new RustFFIEnricher(),
|
|
53
|
-
RejectionPropagationEnricher: () => new RejectionPropagationEnricher(),
|
|
54
|
-
CallbackCallResolver: () => new CallbackCallResolver(),
|
|
55
|
-
// Validation
|
|
56
|
-
CallResolverValidator: () => new CallResolverValidator(),
|
|
57
|
-
EvalBanValidator: () => new EvalBanValidator(),
|
|
58
|
-
SQLInjectionValidator: () => new SQLInjectionValidator(),
|
|
59
|
-
AwaitInLoopValidator: () => new AwaitInLoopValidator(),
|
|
60
|
-
ShadowingDetector: () => new ShadowingDetector(),
|
|
61
|
-
GraphConnectivityValidator: () => new GraphConnectivityValidator(),
|
|
62
|
-
DataFlowValidator: () => new DataFlowValidator(),
|
|
63
|
-
TypeScriptDeadCodeValidator: () => new TypeScriptDeadCodeValidator(),
|
|
64
|
-
BrokenImportValidator: () => new BrokenImportValidator(),
|
|
65
|
-
UnconnectedRouteValidator: () => new UnconnectedRouteValidator(),
|
|
66
|
-
PackageCoverageValidator: () => new PackageCoverageValidator(),
|
|
67
|
-
};
|
|
1
|
+
export {};
|
|
2
|
+
// Deleted: plugin registration moved to grafema-orchestrator (Rust).
|
|
68
3
|
//# sourceMappingURL=builtinPlugins.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtinPlugins.js","sourceRoot":"","sources":["../../src/plugins/builtinPlugins.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"builtinPlugins.js","sourceRoot":"","sources":["../../src/plugins/builtinPlugins.ts"],"names":[],"mappings":";AAAA,qEAAqE"}
|
|
@@ -1,16 +1,2 @@
|
|
|
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 type { Plugin, GrafemaConfig } from '@grafema/core';
|
|
10
|
-
export declare function registerPluginResolver(): void;
|
|
11
|
-
/**
|
|
12
|
-
* Load custom plugins from .grafema/plugins/ directory
|
|
13
|
-
*/
|
|
14
|
-
export declare function loadCustomPlugins(projectPath: string, log: (msg: string) => void): Promise<Record<string, () => Plugin>>;
|
|
15
|
-
export declare function createPlugins(config: GrafemaConfig['plugins'], customPlugins?: Record<string, () => Plugin>, verbose?: boolean): Plugin[];
|
|
1
|
+
export {};
|
|
16
2
|
//# sourceMappingURL=pluginLoader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pluginLoader.d.ts","sourceRoot":"","sources":["../../src/plugins/pluginLoader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pluginLoader.d.ts","sourceRoot":"","sources":["../../src/plugins/pluginLoader.ts"],"names":[],"mappings":""}
|