arcvision 0.2.4 → 0.2.6
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/LICENSE +21 -0
- package/README.md +85 -74
- package/dist/index.js +899 -96
- package/docs/blast-radius-implementation.md +76 -0
- package/docs/blast-radius.md +44 -0
- package/package.json +7 -3
- package/schema/arcvision_context_schema_v1.json +221 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Blast Radius Implementation
|
|
2
|
+
|
|
3
|
+
## Architecture
|
|
4
|
+
|
|
5
|
+
### Files Added/Modified
|
|
6
|
+
1. `src/core/blastRadius.js` - Core blast radius calculation logic
|
|
7
|
+
2. `src/core/scanner.js` - Modified to include blast radius in output
|
|
8
|
+
3. `src/index.js` - Modified to display blast radius insight
|
|
9
|
+
|
|
10
|
+
### Core Functions
|
|
11
|
+
|
|
12
|
+
#### `buildReverseDependencyGraph(architectureMap)`
|
|
13
|
+
- Creates a reverse dependency map where keys are imported files and values are arrays of files that import them
|
|
14
|
+
- Takes the architecture map (with nodes and edges) as input
|
|
15
|
+
- Returns a map: `{ [importedFile]: [importingFile1, importingFile2, ...] }`
|
|
16
|
+
|
|
17
|
+
#### `computeBlastRadius(reverseGraph)`
|
|
18
|
+
- Calculates the blast radius for each file as the count of files that import it
|
|
19
|
+
- Takes the reverse dependency graph as input
|
|
20
|
+
- Returns a map: `{ [filePath]: blastRadiusNumber }`
|
|
21
|
+
|
|
22
|
+
#### `findHighestBlastRadius(blastRadiusMap)`
|
|
23
|
+
- Finds the file with the highest blast radius value
|
|
24
|
+
- Takes the blast radius map as input
|
|
25
|
+
- Returns an object: `{ file: filePath, blast_radius: radius }` or null
|
|
26
|
+
|
|
27
|
+
## Data Flow
|
|
28
|
+
|
|
29
|
+
1. **Scanning Phase**: The scanner builds the architecture map with nodes and edges as before
|
|
30
|
+
2. **Blast Radius Calculation Phase**: After the architecture map is built:
|
|
31
|
+
- Reverse dependency graph is built from the edges
|
|
32
|
+
- Blast radius is computed for each file
|
|
33
|
+
- Blast radius values are added to each node's metadata
|
|
34
|
+
3. **Output Phase**: The CLI prints the architecture map as JSON and then shows the blast radius insight
|
|
35
|
+
|
|
36
|
+
## Data Structure Changes
|
|
37
|
+
|
|
38
|
+
### Node Metadata
|
|
39
|
+
Each node in the architecture map now includes:
|
|
40
|
+
```javascript
|
|
41
|
+
{
|
|
42
|
+
id: "relative/file/path.js",
|
|
43
|
+
type: "file",
|
|
44
|
+
metadata: {
|
|
45
|
+
imports: [...],
|
|
46
|
+
exports: [...],
|
|
47
|
+
functions: [...],
|
|
48
|
+
apiCalls: [...],
|
|
49
|
+
blast_radius: 5 // NEW FIELD
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### CLI Output
|
|
55
|
+
The CLI now prints an additional message after the scan:
|
|
56
|
+
```
|
|
57
|
+
⚠️ src/core/utils.js has the highest blast radius (5). Changes here may affect many parts of the system.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Algorithm Complexity
|
|
61
|
+
- **Time Complexity**: O(V + E) where V is the number of files and E is the number of import relationships
|
|
62
|
+
- **Space Complexity**: O(V + E) for storing the reverse dependency graph
|
|
63
|
+
|
|
64
|
+
## Error Handling
|
|
65
|
+
- Handles empty repositories gracefully
|
|
66
|
+
- Handles files with no imports or no dependents
|
|
67
|
+
- Maintains backward compatibility with existing functionality
|
|
68
|
+
- Preserves all existing fields in the architecture map
|
|
69
|
+
|
|
70
|
+
## Testing Considerations
|
|
71
|
+
The implementation should be tested with:
|
|
72
|
+
- Empty repositories
|
|
73
|
+
- Repositories with no dependencies
|
|
74
|
+
- Repositories with complex dependency chains
|
|
75
|
+
- Repositories with circular dependencies
|
|
76
|
+
- Large repositories with many files
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Blast Radius Feature
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
The Blast Radius feature analyzes your codebase to identify files that are most critical to your application. It calculates how many other files depend on each file, helping you identify high-structure areas where changes could have wide-ranging roles.
|
|
5
|
+
|
|
6
|
+
## How It Works
|
|
7
|
+
- **Blast Radius Score**: For each file, the blast radius is calculated as the number of files that import it (direct dependencies only).
|
|
8
|
+
- **Reverse Dependency Graph**: The system builds a reverse dependency graph to track which files import each file.
|
|
9
|
+
- **Structure Assessment**: Files with higher blast radius scores are considered higher structure because changes to them could affect many other parts of the system.
|
|
10
|
+
|
|
11
|
+
## Output
|
|
12
|
+
The blast radius score is added to each file's metadata in the architecture map:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"nodes": [
|
|
17
|
+
{
|
|
18
|
+
"id": "src/auth/session.ts",
|
|
19
|
+
"type": "file",
|
|
20
|
+
"metadata": {
|
|
21
|
+
"imports": ["src/db/client.ts", "src/utils/logger.ts"],
|
|
22
|
+
"exports": [],
|
|
23
|
+
"functions": [],
|
|
24
|
+
"apiCalls": [],
|
|
25
|
+
"blast_radius": 2
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"edges": [...]
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## CLI Output
|
|
34
|
+
After scanning, the CLI will display a warning for the file with the highest blast radius:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
⚠️ src/auth/session.ts has the highest blast radius (2). Changes here may affect many parts of the system.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Use Cases
|
|
41
|
+
- Identify critical files that require extra care during refactoring
|
|
42
|
+
- Understand the potential role of code changes
|
|
43
|
+
- Prioritize code review efforts for high-structure files
|
|
44
|
+
- Analyze architectural dependencies in your codebase
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcvision",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "Architecture scanner for modern codebases",
|
|
5
5
|
"bin": {
|
|
6
6
|
"arcvision": "./dist/index.js"
|
|
@@ -38,11 +38,15 @@
|
|
|
38
38
|
"author": "ArcVision",
|
|
39
39
|
"repository": {
|
|
40
40
|
"type": "git",
|
|
41
|
-
"url": "https://github.com/
|
|
41
|
+
"url": "https://github.com/arcvision/arcvision.git"
|
|
42
42
|
},
|
|
43
43
|
"license": "MIT",
|
|
44
44
|
"files": [
|
|
45
|
-
"dist"
|
|
45
|
+
"dist",
|
|
46
|
+
"README.md",
|
|
47
|
+
"LICENSE",
|
|
48
|
+
"schema",
|
|
49
|
+
"docs"
|
|
46
50
|
],
|
|
47
51
|
"publishConfig": {
|
|
48
52
|
"access": "public"
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Arcvision System-Level Structural Context",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"required": [
|
|
6
|
+
"schema_version",
|
|
7
|
+
"generated_at",
|
|
8
|
+
"system",
|
|
9
|
+
"nodes",
|
|
10
|
+
"edges",
|
|
11
|
+
"metrics",
|
|
12
|
+
"assumptions",
|
|
13
|
+
"source",
|
|
14
|
+
"integrity",
|
|
15
|
+
"structural_layers",
|
|
16
|
+
"project_envelope"
|
|
17
|
+
],
|
|
18
|
+
"properties": {
|
|
19
|
+
"schema_version": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "Semantic version of the Arcvision context schema (e.g. 1.0.0)"
|
|
22
|
+
},
|
|
23
|
+
"generated_at": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"format": "date-time",
|
|
26
|
+
"description": "ISO-8601 timestamp when context was generated"
|
|
27
|
+
},
|
|
28
|
+
"system": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"required": ["name", "root_path", "language"],
|
|
31
|
+
"properties": {
|
|
32
|
+
"name": { "type": "string" },
|
|
33
|
+
"root_path": { "type": "string" },
|
|
34
|
+
"language": { "type": "string" }
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"nodes": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"items": {
|
|
40
|
+
"type": "object",
|
|
41
|
+
"required": ["id", "type", "path", "role"],
|
|
42
|
+
"properties": {
|
|
43
|
+
"id": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"description": "Deterministic, stable ID (never random)"
|
|
46
|
+
},
|
|
47
|
+
"type": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"enum": ["file", "module", "class", "function", "service"]
|
|
50
|
+
},
|
|
51
|
+
"path": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"description": "Normalized relative path"
|
|
54
|
+
},
|
|
55
|
+
"role": {
|
|
56
|
+
"type": "string",
|
|
57
|
+
"description": "Why this node exists in the system"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"type": "array",
|
|
61
|
+
"items": { "type": "string" }
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"edges": {
|
|
67
|
+
"type": "array",
|
|
68
|
+
"items": {
|
|
69
|
+
"type": "object",
|
|
70
|
+
"required": ["from", "to", "relation"],
|
|
71
|
+
"properties": {
|
|
72
|
+
"from": { "type": "string" },
|
|
73
|
+
"to": { "type": "string" },
|
|
74
|
+
"relation": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"enum": ["imports", "calls", "owns", "depends_on"]
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"metrics": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"description": "System-wide aggregate metrics",
|
|
84
|
+
"additionalProperties": {
|
|
85
|
+
"type": ["number", "string"]
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"assumptions": {
|
|
89
|
+
"type": "array",
|
|
90
|
+
"description": "Explicit assumptions about analysis limitations",
|
|
91
|
+
"items": {
|
|
92
|
+
"type": "string"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"source": {
|
|
96
|
+
"type": "object",
|
|
97
|
+
"description": "Source repository and commit information",
|
|
98
|
+
"required": ["repo", "commit", "generated_at", "arcvision_version"],
|
|
99
|
+
"properties": {
|
|
100
|
+
"repo": { "type": "string" },
|
|
101
|
+
"commit": { "type": "string" },
|
|
102
|
+
"generated_at": { "type": "string" },
|
|
103
|
+
"arcvision_version": { "type": "string" }
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"integrity": {
|
|
107
|
+
"type": "object",
|
|
108
|
+
"description": "Integrity hash of the artifact",
|
|
109
|
+
"required": ["sha256"],
|
|
110
|
+
"properties": {
|
|
111
|
+
"sha256": { "type": "string" }
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"structural_layers": {
|
|
115
|
+
"type": "object",
|
|
116
|
+
"description": "Defines which structural layers are included in the analysis",
|
|
117
|
+
"required": ["runtime_code", "execution_scripts", "infrastructure_scripts", "configuration", "documentation", "assets"],
|
|
118
|
+
"properties": {
|
|
119
|
+
"runtime_code": {
|
|
120
|
+
"type": "object",
|
|
121
|
+
"required": ["status", "description"],
|
|
122
|
+
"properties": {
|
|
123
|
+
"status": { "type": "string", "enum": ["included", "excluded"] },
|
|
124
|
+
"description": { "type": "string" }
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"execution_scripts": {
|
|
128
|
+
"type": "object",
|
|
129
|
+
"required": ["status", "description"],
|
|
130
|
+
"properties": {
|
|
131
|
+
"status": { "type": "string", "enum": ["included", "excluded"] },
|
|
132
|
+
"description": { "type": "string" }
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"infrastructure_scripts": {
|
|
136
|
+
"type": "object",
|
|
137
|
+
"required": ["status", "description"],
|
|
138
|
+
"properties": {
|
|
139
|
+
"status": { "type": "string", "enum": ["included", "excluded"] },
|
|
140
|
+
"description": { "type": "string" }
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
"configuration": {
|
|
144
|
+
"type": "object",
|
|
145
|
+
"required": ["status", "description"],
|
|
146
|
+
"properties": {
|
|
147
|
+
"status": { "type": "string", "enum": ["included", "excluded", "optional"] },
|
|
148
|
+
"description": { "type": "string" }
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"documentation": {
|
|
152
|
+
"type": "object",
|
|
153
|
+
"required": ["status", "description"],
|
|
154
|
+
"properties": {
|
|
155
|
+
"status": { "type": "string", "enum": ["included", "excluded", "optional"] },
|
|
156
|
+
"description": { "type": "string" }
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
"assets": {
|
|
160
|
+
"type": "object",
|
|
161
|
+
"required": ["status", "description"],
|
|
162
|
+
"properties": {
|
|
163
|
+
"status": { "type": "string", "enum": ["included", "excluded"] },
|
|
164
|
+
"description": { "type": "string" }
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
"project_envelope": {
|
|
170
|
+
"type": "object",
|
|
171
|
+
"description": "Project-level files that provide context but are not execution graph nodes",
|
|
172
|
+
"properties": {
|
|
173
|
+
"configuration_files": {
|
|
174
|
+
"type": "array",
|
|
175
|
+
"items": {
|
|
176
|
+
"type": "object",
|
|
177
|
+
"properties": {
|
|
178
|
+
"path": { "type": "string" },
|
|
179
|
+
"role": { "type": "string" }
|
|
180
|
+
},
|
|
181
|
+
"required": ["path", "role"]
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
"documentation": {
|
|
185
|
+
"type": "array",
|
|
186
|
+
"items": {
|
|
187
|
+
"type": "object",
|
|
188
|
+
"properties": {
|
|
189
|
+
"path": { "type": "string" },
|
|
190
|
+
"role": { "type": "string" }
|
|
191
|
+
},
|
|
192
|
+
"required": ["path", "role"]
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"build_tools": {
|
|
196
|
+
"type": "array",
|
|
197
|
+
"items": {
|
|
198
|
+
"type": "object",
|
|
199
|
+
"properties": {
|
|
200
|
+
"path": { "type": "string" },
|
|
201
|
+
"role": { "type": "string" }
|
|
202
|
+
},
|
|
203
|
+
"required": ["path", "role"]
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"diff_summary": {
|
|
209
|
+
"type": "object",
|
|
210
|
+
"description": "Structural diff summary between commits",
|
|
211
|
+
"properties": {
|
|
212
|
+
"nodes_added": { "type": "number" },
|
|
213
|
+
"nodes_removed": { "type": "number" },
|
|
214
|
+
"edges_added": { "type": "number" },
|
|
215
|
+
"edges_removed": { "type": "number" },
|
|
216
|
+
"roles_changed": { "type": "number" },
|
|
217
|
+
"blast_radius_changes": { "type": "number" }
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|