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.
Files changed (53) hide show
  1. package/README.md +485 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +100 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/analyze.d.ts +8 -0
  7. package/dist/commands/analyze.d.ts.map +1 -0
  8. package/dist/commands/analyze.js +76 -0
  9. package/dist/commands/analyze.js.map +1 -0
  10. package/dist/commands/diff.d.ts +8 -0
  11. package/dist/commands/diff.d.ts.map +1 -0
  12. package/dist/commands/diff.js +203 -0
  13. package/dist/commands/diff.js.map +1 -0
  14. package/dist/commands/graph.d.ts +12 -0
  15. package/dist/commands/graph.d.ts.map +1 -0
  16. package/dist/commands/graph.js +72 -0
  17. package/dist/commands/graph.js.map +1 -0
  18. package/dist/commands/help.d.ts +2 -0
  19. package/dist/commands/help.d.ts.map +1 -0
  20. package/dist/commands/help.js +234 -0
  21. package/dist/commands/help.js.map +1 -0
  22. package/dist/commands/init.d.ts +6 -0
  23. package/dist/commands/init.d.ts.map +1 -0
  24. package/dist/commands/init.js +37 -0
  25. package/dist/commands/init.js.map +1 -0
  26. package/dist/commands/list.d.ts +7 -0
  27. package/dist/commands/list.d.ts.map +1 -0
  28. package/dist/commands/list.js +148 -0
  29. package/dist/commands/list.js.map +1 -0
  30. package/dist/commands/run.d.ts +10 -0
  31. package/dist/commands/run.d.ts.map +1 -0
  32. package/dist/commands/run.js +388 -0
  33. package/dist/commands/run.js.map +1 -0
  34. package/dist/commands/serve.d.ts +8 -0
  35. package/dist/commands/serve.d.ts.map +1 -0
  36. package/dist/commands/serve.js +137 -0
  37. package/dist/commands/serve.js.map +1 -0
  38. package/dist/index.d.ts +6 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +7 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/queries/calls.ql +53 -0
  43. package/dist/queries/dataflow.ql +62 -0
  44. package/dist/queries/functions.ql +52 -0
  45. package/dist/utils/ascii-graph.d.ts +21 -0
  46. package/dist/utils/ascii-graph.d.ts.map +1 -0
  47. package/dist/utils/ascii-graph.js +431 -0
  48. package/dist/utils/ascii-graph.js.map +1 -0
  49. package/dist/utils/output.d.ts +12 -0
  50. package/dist/utils/output.d.ts.map +1 -0
  51. package/dist/utils/output.js +24 -0
  52. package/dist/utils/output.js.map +1 -0
  53. 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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"}
@@ -0,0 +1,6 @@
1
+ export * from './commands/analyze.js';
2
+ export * from './commands/diff.js';
3
+ export * from './commands/serve.js';
4
+ export * from './commands/init.js';
5
+ export * from './commands/list.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -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,7 @@
1
+ // Re-export for programmatic usage
2
+ export * from './commands/analyze.js';
3
+ export * from './commands/diff.js';
4
+ export * from './commands/serve.js';
5
+ export * from './commands/init.js';
6
+ export * from './commands/list.js';
7
+ //# sourceMappingURL=index.js.map
@@ -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"}