@codeflow-map/core 0.1.0 → 0.1.2

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 (2) hide show
  1. package/README.md +118 -69
  2. package/package.json +8 -7
package/README.md CHANGED
@@ -1,157 +1,206 @@
1
- # @flowmap/core
1
+ # @codeflow-map/core
2
2
 
3
- Language-agnostic call-graph analysis engine powered by [Tree-sitter](https://tree-sitter.github.io/tree-sitter/). Parse source files into a structured call graph with typed nodes, edges, and execution flowsentirely local, no LLM, no cloud.
3
+ Language-agnostic call-graph engine powered by [Tree-sitter](https://tree-sitter.github.io/tree-sitter/). Feed it source files, get back a structured graph of every function, every call relationship, and every execution flowdeterministic, fully local, no LLM, no cloud.
4
4
 
5
- Used by the [FlowMap VS Code extension](https://github.com/devricky-codes/flowmap-vscode-extension) to render interactive call-flow diagrams.
5
+ Used by the [CallSight VS Code extension](https://github.com/devricky-codes/callsight-vscode-extension) to render interactive call-flow diagrams for any codebase.
6
+
7
+ ---
6
8
 
7
9
  ## Supported Languages
8
10
 
9
- | Language | Functions | Calls | Components/Hooks |
10
- |------------|-----------|-------|------------------|
11
- | TypeScript | ✅ | ✅ | ✅ |
12
- | JavaScript | ✅ | ✅ | ✅ |
13
- | TSX | ✅ | ✅ | ✅ |
14
- | JSX | ✅ | ✅ | ✅ |
15
- | Python | ✅ | ✅ | |
16
- | Go | ✅ | ✅ ||
11
+ | Language | Functions | Calls | Components / Hooks |
12
+ |------------|:---------:|:-----:|:-----------------:|
13
+ | TypeScript | ✅ | ✅ | ✅ |
14
+ | JavaScript | ✅ | ✅ | ✅ |
15
+ | TSX | ✅ | ✅ | ✅ |
16
+ | JSX | ✅ | ✅ | ✅ |
17
+ | Python | ✅ | ✅ | - |
18
+ | Go | ✅ | ✅ | - |
19
+
20
+ ---
17
21
 
18
22
  ## Installation
19
23
 
20
24
  ```bash
21
- npm install @flowmap/core
25
+ npm install @codeflow-map/core
22
26
  # or
23
- pnpm add @flowmap/core
27
+ pnpm add @codeflow-map/core
24
28
  ```
25
29
 
26
- > **Note:** `web-tree-sitter` requires WASM grammar files at runtime. You must provide a `wasmDirectory` pointing to a folder that contains the relevant `tree-sitter-<language>.wasm` files. These are available from the [`tree-sitter-<language>`](https://github.com/tree-sitter) grammar packages.
30
+ > **Runtime requirement:** `web-tree-sitter` parses source files using WebAssembly grammar files.
31
+ > You must supply a `wasmDirectory` that contains one `.wasm` file per language you want to analyse
32
+ > (e.g. `tree-sitter-typescript.wasm`, `tree-sitter-python.wasm`).
33
+ > Pre-built grammars are available from the official
34
+ > [tree-sitter grammar repositories](https://github.com/tree-sitter).
35
+
36
+ ---
27
37
 
28
- ## Usage
38
+ ## Quick Start
29
39
 
30
- ### Parse a directory into a call graph
40
+ ### Analyse an entire directory
31
41
 
32
42
  ```typescript
33
- import { analyzeDirectory } from '@flowmap/core';
43
+ import { analyzeDirectory } from '@codeflow-map/core';
34
44
 
35
45
  const graph = await analyzeDirectory({
36
- rootPath: '/absolute/path/to/project',
46
+ rootPath: '/absolute/path/to/project',
37
47
  wasmDirectory: '/path/to/wasm/grammars',
38
- include: ['**/*.ts', '**/*.tsx'],
39
- exclude: ['**/node_modules/**', '**/dist/**'],
48
+ include: ['**/*.ts', '**/*.tsx'],
49
+ exclude: ['**/node_modules/**', '**/dist/**'],
40
50
  });
41
51
 
42
52
  console.log(`Scanned ${graph.scannedFiles} files in ${graph.durationMs}ms`);
43
- console.log(`Found ${graph.nodes.length} functions, ${graph.edges.length} call edges`);
44
- console.log(`Partitioned into ${graph.flows.length} flows`);
53
+ console.log(`${graph.nodes.length} functions · ${graph.edges.length} call edges · ${graph.flows.length} flows`);
45
54
  ```
46
55
 
47
- ### Parse a single file
56
+ ### Analyse a single file
48
57
 
49
58
  ```typescript
50
- import { parseFile } from '@flowmap/core';
59
+ import { parseFile } from '@codeflow-map/core';
51
60
 
52
61
  const { functions, calls } = await parseFile(
53
- 'src/index.ts', // relative path (used as node IDs)
54
- '/absolute/src/index.ts', // absolute path (for reading the file)
62
+ 'src/index.ts', // relative path used as node ID prefix
63
+ '/absolute/src/index.ts', // absolute path used to read the file
55
64
  '/path/to/wasm', // wasmDirectory
56
- 'typescript' // SupportedLanguage
65
+ 'typescript', // SupportedLanguage
57
66
  );
58
67
  ```
59
68
 
60
- ### Build a call graph manually
69
+ ### Build a call graph from raw parse results
61
70
 
62
71
  ```typescript
63
- import { buildCallGraph, detectEntryPoints, partitionFlows } from '@flowmap/core';
72
+ import { buildCallGraph, detectEntryPoints, partitionFlows } from '@codeflow-map/core';
64
73
 
65
- // nodes: FunctionNode[], rawCalls: RawCall[] — from parseFile()
66
- const edges = buildCallGraph(nodes, rawCalls);
67
- const nodesWithEntries = detectEntryPoints(nodes, edges);
68
- const { flows, orphans } = partitionFlows(nodesWithEntries, edges);
74
+ const edges = buildCallGraph(functions, calls);
75
+ const nodesWithEntries = detectEntryPoints(functions, edges);
76
+ const { flows, orphans } = partitionFlows(nodesWithEntries, edges);
69
77
  ```
70
78
 
79
+ ---
80
+
71
81
  ## Data Model
72
82
 
73
83
  ### `FunctionNode`
74
84
 
85
+ Represents a single function, method, component, or hook extracted from source.
86
+
75
87
  ```typescript
76
88
  interface FunctionNode {
77
- id: string; // "relative/path.ts::functionName::startLine"
78
- name: string;
79
- filePath: string; // relative to workspace root
80
- startLine: number; // 0-indexed
81
- endLine: number;
82
- params: Parameter[];
83
- returnType: string | null;
84
- isAsync: boolean;
85
- isExported: boolean;
86
- isEntryPoint: boolean;
87
- language: SupportedLanguage;
88
- kind?: 'function' | 'component' | 'hook' | 'method' | 'class' | 'iife';
89
- parentFunctionId?: string;
89
+ id: string; // "relative/path.ts::functionName::startLine"
90
+ name: string; // human-readable, e.g. "UserService.getUser"
91
+ filePath: string; // relative to workspace root
92
+ startLine: number; // 0-indexed
93
+ endLine: number;
94
+ params: Parameter[]; // name + type (type is null for untyped languages)
95
+ returnType: string | null;
96
+ isAsync: boolean;
97
+ isExported: boolean;
98
+ isEntryPoint: boolean; // true when in-degree = 0 and out-degree > 0
99
+ language: SupportedLanguage;
100
+ kind?: 'function' | 'component' | 'hook' | 'method' | 'class' | 'iife';
101
+ parentFunctionId?: string; // set for inner / nested functions
90
102
  }
91
103
  ```
92
104
 
93
105
  ### `CallEdge`
94
106
 
107
+ Represents a directed call relationship between two functions.
108
+
95
109
  ```typescript
96
110
  interface CallEdge {
97
- from: string; // caller FunctionNode.id
98
- to: string; // callee FunctionNode.id
99
- line: number;
111
+ from: string; // caller FunctionNode.id
112
+ to: string; // callee FunctionNode.id
113
+ line: number; // source line where the call occurs
100
114
  callType?: 'direct' | 'ref' | 'concurrent' | 'goroutine';
101
115
  }
102
116
  ```
103
117
 
118
+ `callType` distinguishes how the call happens:
119
+ - `direct` — standard synchronous call
120
+ - `ref` — function passed as a reference (e.g. event handler, callback)
121
+ - `concurrent` — call inside `Promise.all`, `asyncio.gather`, etc.
122
+ - `goroutine` — Go `go fn()` launch
123
+
104
124
  ### `Flow`
105
125
 
126
+ A connected subgraph reachable from a single entry point.
127
+
106
128
  ```typescript
107
129
  interface Flow {
108
- id: string;
109
- entryPoint: string; // FunctionNode.id of the root function
110
- nodeIds: string[]; // all reachable function IDs in this flow
130
+ id: string; // derived from the entry point's FunctionNode.id
131
+ entryPoint: string; // FunctionNode.id of the root function
132
+ nodeIds: string[]; // all function IDs reachable from this entry point
111
133
  }
112
134
  ```
113
135
 
114
136
  ### `Graph`
115
137
 
138
+ The complete analysis result returned by `analyzeDirectory`.
139
+
116
140
  ```typescript
117
141
  interface Graph {
118
- nodes: FunctionNode[];
119
- edges: CallEdge[];
120
- flows: Flow[];
121
- orphans: string[]; // FunctionNode IDs with no connections
142
+ nodes: FunctionNode[];
143
+ edges: CallEdge[];
144
+ flows: Flow[];
145
+ orphans: string[]; // FunctionNode IDs unreachable from any entry point
122
146
  scannedFiles: number;
123
- durationMs: number;
147
+ durationMs: number;
124
148
  }
125
149
  ```
126
150
 
151
+ ---
152
+
127
153
  ## API Reference
128
154
 
129
155
  ### `analyzeDirectory(options): Promise<Graph>`
130
156
 
131
- Scans a directory, parses all matched source files, and returns a complete `Graph`.
157
+ Scans a directory, parses all matched source files, builds the call graph, detects entry points, and partitions execution flows in a single call.
158
+
159
+ | Option | Type | Required | Description |
160
+ |-----------------|------------|:--------:|--------------------------------------------------|
161
+ | `rootPath` | `string` | ✅ | Absolute path to the project root |
162
+ | `wasmDirectory` | `string` | ✅ | Directory containing `.wasm` Tree-sitter grammars |
163
+ | `include` | `string[]` | ✅ | Glob patterns for files to include |
164
+ | `exclude` | `string[]` | | Glob patterns for files to exclude |
132
165
 
133
- | Option | Type | Description |
134
- |----------------|------------|--------------------------------------------------|
135
- | `rootPath` | `string` | Absolute path to the project root |
136
- | `wasmDirectory`| `string` | Directory containing `.wasm` grammar files |
137
- | `include` | `string[]` | Glob patterns for files to include |
138
- | `exclude` | `string[]` | Glob patterns for files to exclude |
166
+ ---
139
167
 
140
- ### `parseFile(relativePath, absolutePath, wasmDirectory, language): Promise<{functions, calls}>`
168
+ ### `parseFile(relativePath, absolutePath, wasmDirectory, language): Promise<{ functions, calls }>`
141
169
 
142
- Parses a single source file using Tree-sitter.
170
+ Parses a single source file and returns the raw extracted functions and call sites. Use this when you want fine-grained control over the analysis pipeline.
171
+
172
+ ---
143
173
 
144
174
  ### `buildCallGraph(nodes, rawCalls): CallEdge[]`
145
175
 
146
- Resolves raw call references into typed `CallEdge` objects.
176
+ Resolves raw call references into typed `CallEdge` objects by matching callee names against the indexed function nodes.
177
+
178
+ ---
147
179
 
148
180
  ### `detectEntryPoints(nodes, edges): FunctionNode[]`
149
181
 
150
- Marks functions with no callers (in-degree = 0) but at least one outgoing call as entry points.
182
+ Marks nodes as entry points using graph topology — a node is an entry point when nothing calls it (in-degree = 0) but it calls at least one other function (out-degree > 0). No language-specific heuristics, no name matching.
183
+
184
+ ---
151
185
 
152
186
  ### `partitionFlows(nodes, edges): { flows: Flow[], orphans: string[] }`
153
187
 
154
- Groups the call graph into independent execution flows using BFS from each entry point.
188
+ Runs BFS from each entry point to group the call graph into independent execution flows. Functions unreachable from any entry point are collected separately as `orphans` — useful for dead code detection.
189
+
190
+ ---
191
+
192
+ ## How Entry Points Are Detected
193
+
194
+ Entry point detection is purely graph-based — no hardcoded names, no language-specific rules. A function is an entry point if and only if:
195
+
196
+ 1. No other function in the graph calls it (in-degree = 0)
197
+ 2. It calls at least one other function (out-degree > 0)
198
+
199
+ This means `main()` in Go, route handlers in Flask, React root components, and CLI entry functions are all detected automatically and consistently across all supported languages.
200
+
201
+ > **Single-file caveat:** When analysing a single file in isolation, functions that only call external code will appear as orphans because their callees are not in scope. Run `analyzeDirectory` across the full workspace for accurate entry point detection.
202
+
203
+ ---
155
204
 
156
205
  ## License
157
206
 
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@codeflow-map/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Language-agnostic call-graph analysis engine powered by Tree-sitter. Parses TypeScript, JavaScript, TSX, JSX, Python, and Go source files into a structured call graph with flows.",
5
5
  "keywords": [
6
- "flowmap",
6
+ "callsight",
7
7
  "call-graph",
8
8
  "tree-sitter",
9
9
  "static-analysis",
@@ -18,10 +18,10 @@
18
18
  "author": "devricky-codes",
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "https://github.com/devricky-codes/flowmap-vscode-extension.git",
21
+ "url": "https://github.com/devricky-codes/callsight-vscode-extension.git",
22
22
  "directory": "packages/core"
23
23
  },
24
- "homepage": "https://github.com/devricky-codes/flowmap-vscode-extension#readme",
24
+ "homepage": "https://github.com/devricky-codes/callsight-vscode-extension#readme",
25
25
  "main": "dist/index.js",
26
26
  "types": "dist/index.d.ts",
27
27
  "files": [
@@ -35,14 +35,15 @@
35
35
  "access": "public"
36
36
  },
37
37
  "scripts": {
38
- "build": "../../node_modules/.bin/tsc",
39
- "watch": "../../node_modules/.bin/tsc --watch"
38
+ "build": "tsc",
39
+ "watch": "tsc --watch"
40
40
  },
41
41
  "dependencies": {
42
42
  "web-tree-sitter": "^0.24.4",
43
43
  "minimatch": "^9.0.3"
44
44
  },
45
45
  "devDependencies": {
46
- "@types/node": "^20.10.6"
46
+ "@types/node": "^20.10.6",
47
+ "typescript": "^5.3.3"
47
48
  }
48
49
  }