monarch-code-graph 0.3.4
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 +485 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +100 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/analyze.d.ts +8 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +76 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/diff.d.ts +8 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +203 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/graph.d.ts +12 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +72 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/help.d.ts +2 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/help.js +234 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +37 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +7 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +148 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/run.d.ts +10 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +388 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/serve.d.ts +8 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +137 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/queries/calls.ql +53 -0
- package/dist/queries/dataflow.ql +62 -0
- package/dist/queries/functions.ql +52 -0
- package/dist/utils/ascii-graph.d.ts +21 -0
- package/dist/utils/ascii-graph.d.ts.map +1 -0
- package/dist/utils/ascii-graph.js +431 -0
- package/dist/utils/ascii-graph.js.map +1 -0
- package/dist/utils/output.d.ts +12 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/output.js +24 -0
- package/dist/utils/output.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { createServer } from 'http';
|
|
4
|
+
import { isCodeFlowArtifact } from '@codeflow/shared';
|
|
5
|
+
import { log, formatPath } from '../utils/output.js';
|
|
6
|
+
export async function serveCommand(options) {
|
|
7
|
+
const artifactPath = path.resolve(options.artifact);
|
|
8
|
+
const port = parseInt(options.port, 10);
|
|
9
|
+
if (!fs.existsSync(artifactPath)) {
|
|
10
|
+
log.error(`Artifact not found: ${formatPath(artifactPath)}`);
|
|
11
|
+
log.info('Run `monarch analyze` first to generate a graph');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
// Validate artifact
|
|
15
|
+
try {
|
|
16
|
+
const content = fs.readFileSync(artifactPath, 'utf-8');
|
|
17
|
+
const artifact = JSON.parse(content);
|
|
18
|
+
if (!isCodeFlowArtifact(artifact)) {
|
|
19
|
+
log.error('Invalid artifact file');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
log.error(`Failed to read artifact: ${error}`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
// Create a simple HTTP server that serves the UI and artifact
|
|
28
|
+
const server = createServer((req, res) => {
|
|
29
|
+
const url = req.url || '/';
|
|
30
|
+
if (url === '/api/artifact') {
|
|
31
|
+
// Serve the artifact JSON
|
|
32
|
+
res.setHeader('Content-Type', 'application/json');
|
|
33
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
34
|
+
const content = fs.readFileSync(artifactPath, 'utf-8');
|
|
35
|
+
res.end(content);
|
|
36
|
+
}
|
|
37
|
+
else if (url === '/') {
|
|
38
|
+
// Serve a simple HTML page that redirects to the UI
|
|
39
|
+
res.setHeader('Content-Type', 'text/html');
|
|
40
|
+
res.end(getIndexHtml(port));
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
res.statusCode = 404;
|
|
44
|
+
res.end('Not Found');
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
server.listen(port, () => {
|
|
48
|
+
log.title('Monarch Visualization Server');
|
|
49
|
+
log.success(`Server running at http://localhost:${port}`);
|
|
50
|
+
log.info(`Serving artifact: ${formatPath(artifactPath)}`);
|
|
51
|
+
log.dim('\nPress Ctrl+C to stop');
|
|
52
|
+
if (options.open) {
|
|
53
|
+
// Try to open browser
|
|
54
|
+
const url = `http://localhost:${port}`;
|
|
55
|
+
import('child_process').then(({ exec }) => {
|
|
56
|
+
const cmd = process.platform === 'win32' ? 'start' :
|
|
57
|
+
process.platform === 'darwin' ? 'open' : 'xdg-open';
|
|
58
|
+
exec(`${cmd} ${url}`);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
// Handle graceful shutdown
|
|
63
|
+
process.on('SIGINT', () => {
|
|
64
|
+
log.info('\nShutting down server...');
|
|
65
|
+
server.close(() => {
|
|
66
|
+
process.exit(0);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function getIndexHtml(port) {
|
|
71
|
+
return `<!DOCTYPE html>
|
|
72
|
+
<html lang="en">
|
|
73
|
+
<head>
|
|
74
|
+
<meta charset="UTF-8">
|
|
75
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
76
|
+
<title>Monarch - Graph Visualization</title>
|
|
77
|
+
<style>
|
|
78
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
79
|
+
body {
|
|
80
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
81
|
+
background: #16213e;
|
|
82
|
+
color: #fff;
|
|
83
|
+
min-height: 100vh;
|
|
84
|
+
display: flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
justify-content: center;
|
|
87
|
+
}
|
|
88
|
+
.container {
|
|
89
|
+
text-align: center;
|
|
90
|
+
padding: 2rem;
|
|
91
|
+
}
|
|
92
|
+
h1 {
|
|
93
|
+
font-size: 2.5rem;
|
|
94
|
+
margin-bottom: 1rem;
|
|
95
|
+
color: #4a90d9;
|
|
96
|
+
}
|
|
97
|
+
p {
|
|
98
|
+
color: #888;
|
|
99
|
+
margin-bottom: 2rem;
|
|
100
|
+
}
|
|
101
|
+
.info {
|
|
102
|
+
background: #1a1a2e;
|
|
103
|
+
padding: 1.5rem;
|
|
104
|
+
border-radius: 8px;
|
|
105
|
+
margin-bottom: 2rem;
|
|
106
|
+
}
|
|
107
|
+
.info code {
|
|
108
|
+
background: #2d2d44;
|
|
109
|
+
padding: 0.25rem 0.5rem;
|
|
110
|
+
border-radius: 4px;
|
|
111
|
+
font-family: monospace;
|
|
112
|
+
}
|
|
113
|
+
a {
|
|
114
|
+
color: #4a90d9;
|
|
115
|
+
text-decoration: none;
|
|
116
|
+
}
|
|
117
|
+
a:hover {
|
|
118
|
+
text-decoration: underline;
|
|
119
|
+
}
|
|
120
|
+
</style>
|
|
121
|
+
</head>
|
|
122
|
+
<body>
|
|
123
|
+
<div class="container">
|
|
124
|
+
<h1>🔮 Monarch</h1>
|
|
125
|
+
<p>Static Codebase Flow Mapping</p>
|
|
126
|
+
<div class="info">
|
|
127
|
+
<p>API Endpoint: <code>http://localhost:${port}/api/artifact</code></p>
|
|
128
|
+
</div>
|
|
129
|
+
<p>
|
|
130
|
+
To view the full visualization, run the UI package:<br>
|
|
131
|
+
<code>pnpm --filter @codeflow/ui dev</code>
|
|
132
|
+
</p>
|
|
133
|
+
</div>
|
|
134
|
+
</body>
|
|
135
|
+
</html>`;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @name Extract function calls
|
|
3
|
+
* @description Finds all function call relationships
|
|
4
|
+
* @kind problem
|
|
5
|
+
* @id codeflow/calls
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import javascript
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Gets a normalized path relative to the source root
|
|
12
|
+
*/
|
|
13
|
+
string normalizeFilePath(File f) {
|
|
14
|
+
result = f.getRelativePath()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A call expression that we can resolve to a target function
|
|
19
|
+
*/
|
|
20
|
+
class TrackedCall extends CallExpr {
|
|
21
|
+
Function target;
|
|
22
|
+
|
|
23
|
+
TrackedCall() {
|
|
24
|
+
target = this.getCallee().(Function)
|
|
25
|
+
or
|
|
26
|
+
target = this.getCallee().(VarAccess).getVariable().getAnAssignedExpr().(Function)
|
|
27
|
+
or
|
|
28
|
+
exists(FunctionDeclStmt fds |
|
|
29
|
+
this.getCallee().(VarAccess).getName() = fds.getName() and
|
|
30
|
+
target = fds
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Function getTargetFunction() { result = target }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
from TrackedCall call, Function caller, Function callee
|
|
38
|
+
where
|
|
39
|
+
caller = call.getEnclosingFunction() and
|
|
40
|
+
callee = call.getTargetFunction() and
|
|
41
|
+
not caller.getFile().getRelativePath().matches("%node_modules%") and
|
|
42
|
+
not callee.getFile().getRelativePath().matches("%node_modules%") and
|
|
43
|
+
not caller.getFile().getRelativePath().matches("%.d.ts") and
|
|
44
|
+
not callee.getFile().getRelativePath().matches("%.d.ts")
|
|
45
|
+
select
|
|
46
|
+
caller.getName() as callerName,
|
|
47
|
+
normalizeFilePath(caller.getFile()) as callerFile,
|
|
48
|
+
caller.getLocation().getStartLine() as callerStartLine,
|
|
49
|
+
callee.getName() as calleeName,
|
|
50
|
+
normalizeFilePath(callee.getFile()) as calleeFile,
|
|
51
|
+
callee.getLocation().getStartLine() as calleeStartLine,
|
|
52
|
+
call.getLocation().getStartLine() as callsiteLine,
|
|
53
|
+
normalizeFilePath(call.getFile()) as callsiteFile
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @name Extract dataflow paths
|
|
3
|
+
* @description Finds data flow from sources to sinks
|
|
4
|
+
* @kind path-problem
|
|
5
|
+
* @id codeflow/dataflow
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import javascript
|
|
9
|
+
import DataFlow::PathGraph
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for tracking data flow between functions
|
|
13
|
+
*/
|
|
14
|
+
class FunctionDataFlowConfig extends DataFlow::Configuration {
|
|
15
|
+
FunctionDataFlowConfig() { this = "FunctionDataFlowConfig" }
|
|
16
|
+
|
|
17
|
+
override predicate isSource(DataFlow::Node source) {
|
|
18
|
+
// Parameters of functions are sources
|
|
19
|
+
source instanceof DataFlow::ParameterNode
|
|
20
|
+
or
|
|
21
|
+
// Return values of function calls are sources
|
|
22
|
+
source instanceof DataFlow::CallNode
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
override predicate isSink(DataFlow::Node sink) {
|
|
26
|
+
// Arguments to function calls are sinks
|
|
27
|
+
exists(DataFlow::CallNode call | sink = call.getAnArgument())
|
|
28
|
+
or
|
|
29
|
+
// Return statements are sinks
|
|
30
|
+
sink.asExpr() instanceof ReturnStmt
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override predicate isBarrier(DataFlow::Node node) {
|
|
34
|
+
// Exclude node_modules
|
|
35
|
+
node.getFile().getRelativePath().matches("%node_modules%")
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Gets a normalized path relative to the source root
|
|
41
|
+
*/
|
|
42
|
+
string normalizeFilePath(File f) {
|
|
43
|
+
result = f.getRelativePath()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
from FunctionDataFlowConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
|
47
|
+
where
|
|
48
|
+
cfg.hasFlowPath(source, sink) and
|
|
49
|
+
not source.getNode().getFile().getRelativePath().matches("%node_modules%") and
|
|
50
|
+
not sink.getNode().getFile().getRelativePath().matches("%node_modules%") and
|
|
51
|
+
not source.getNode().getFile().getRelativePath().matches("%.d.ts") and
|
|
52
|
+
not sink.getNode().getFile().getRelativePath().matches("%.d.ts")
|
|
53
|
+
select
|
|
54
|
+
sink.getNode(),
|
|
55
|
+
source,
|
|
56
|
+
sink,
|
|
57
|
+
source.getNode().getEnclosingCallable().(Function).getName() as sourceFunction,
|
|
58
|
+
normalizeFilePath(source.getNode().getFile()) as sourceFile,
|
|
59
|
+
source.getNode().getEnclosingCallable().(Function).getLocation().getStartLine() as sourceStartLine,
|
|
60
|
+
sink.getNode().getEnclosingCallable().(Function).getName() as sinkFunction,
|
|
61
|
+
normalizeFilePath(sink.getNode().getFile()) as sinkFile,
|
|
62
|
+
sink.getNode().getEnclosingCallable().(Function).getLocation().getStartLine() as sinkStartLine
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @name Extract function definitions
|
|
3
|
+
* @description Finds all function declarations, methods, and arrow functions
|
|
4
|
+
* @kind problem
|
|
5
|
+
* @id codeflow/functions
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import javascript
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Gets a normalized path relative to the source root
|
|
12
|
+
*/
|
|
13
|
+
string normalizeFilePath(File f) {
|
|
14
|
+
result = f.getRelativePath()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Represents a function-like entity we want to track
|
|
19
|
+
*/
|
|
20
|
+
class TrackedFunction extends Function {
|
|
21
|
+
TrackedFunction() {
|
|
22
|
+
// Include named functions, methods, and arrow functions with names
|
|
23
|
+
this instanceof FunctionDeclStmt
|
|
24
|
+
or this instanceof FunctionExpr and exists(this.getName())
|
|
25
|
+
or this instanceof ArrowFunctionExpr and exists(string name | this = any(VariableDeclarator vd | vd.getInit() = this).getBindingPattern().(Identifier).getName() and name = _)
|
|
26
|
+
or this instanceof MethodDefinition
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
string getFunctionKind() {
|
|
30
|
+
this instanceof ArrowFunctionExpr and result = "arrow"
|
|
31
|
+
or
|
|
32
|
+
this instanceof MethodDefinition and result = "method"
|
|
33
|
+
or
|
|
34
|
+
this instanceof FunctionDeclStmt and result = "function"
|
|
35
|
+
or
|
|
36
|
+
this instanceof FunctionExpr and not this instanceof ArrowFunctionExpr and result = "function"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
from TrackedFunction f
|
|
41
|
+
where
|
|
42
|
+
not f.getFile().getRelativePath().matches("%node_modules%") and
|
|
43
|
+
not f.getFile().getRelativePath().matches("%.d.ts") and
|
|
44
|
+
not f.getFile().getRelativePath().matches("%.test.%") and
|
|
45
|
+
not f.getFile().getRelativePath().matches("%.spec.%")
|
|
46
|
+
select
|
|
47
|
+
f,
|
|
48
|
+
f.getName() as name,
|
|
49
|
+
normalizeFilePath(f.getFile()) as file,
|
|
50
|
+
f.getLocation().getStartLine() as startLine,
|
|
51
|
+
f.getLocation().getEndLine() as endLine,
|
|
52
|
+
f.getFunctionKind() as kind
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CodeFlowArtifact } from '@codeflow/shared';
|
|
2
|
+
export type ViewLevel = 'components' | 'modules' | 'functions';
|
|
3
|
+
interface AsciiGraphOptions {
|
|
4
|
+
maxWidth?: number;
|
|
5
|
+
showEdgeCounts?: boolean;
|
|
6
|
+
colorize?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Render an ASCII graph from a CodeFlowArtifact
|
|
10
|
+
*/
|
|
11
|
+
export declare function renderAsciiGraph(artifact: CodeFlowArtifact, level: ViewLevel, options?: AsciiGraphOptions): string;
|
|
12
|
+
/**
|
|
13
|
+
* Render a specific component or module expanded
|
|
14
|
+
*/
|
|
15
|
+
export declare function renderExpandedView(artifact: CodeFlowArtifact, targetName: string, targetType: 'component' | 'module', options?: AsciiGraphOptions): string;
|
|
16
|
+
/**
|
|
17
|
+
* List available components and modules for expansion
|
|
18
|
+
*/
|
|
19
|
+
export declare function listExpandableItems(artifact: CodeFlowArtifact): string;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=ascii-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ascii-graph.d.ts","sourceRoot":"","sources":["../../src/utils/ascii-graph.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,kBAAkB,CAAC;AAEvE,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,WAAW,CAAC;AAe/D,UAAU,iBAAiB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAeD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CA8BR;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,WAAW,GAAG,QAAQ,EAClC,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CAsGR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CA2BtE"}
|