@bfra.me/workspace-analyzer 0.1.0 → 0.2.1
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 +218 -0
- package/lib/{chunk-WOJ4C7N7.js → chunk-4V5KYQED.js} +3697 -10
- package/lib/cli.js +315 -9
- package/lib/index.d.ts +566 -5
- package/lib/index.js +49 -1
- package/package.json +4 -3
- package/src/cli/commands/analyze.ts +8 -5
- package/src/cli/commands/visualize.ts +406 -0
- package/src/cli/index.ts +45 -1
- package/src/cli/types.ts +43 -0
- package/src/config/schema.ts +3 -3
- package/src/index.ts +49 -0
- package/src/visualizer/graph-builder.ts +397 -0
- package/src/visualizer/html-renderer.ts +556 -0
- package/src/visualizer/index.ts +83 -0
- package/src/visualizer/mermaid-exporter.ts +234 -0
- package/src/visualizer/templates/d3-bundle.ts +1566 -0
- package/src/visualizer/templates/graph-template.ts +959 -0
- package/src/visualizer/templates/styles.ts +928 -0
- package/src/visualizer/types.ts +226 -0
- package/src/visualizer/violation-collector.ts +246 -0
package/README.md
CHANGED
|
@@ -76,6 +76,224 @@ workspace-analyzer --dry-run # Preview without analysis
|
|
|
76
76
|
| `--interactive` | Interactive package selection |
|
|
77
77
|
| `--fix` | Apply auto-fixes where available (placeholder) |
|
|
78
78
|
|
|
79
|
+
### Visualization Command
|
|
80
|
+
|
|
81
|
+
Generate interactive dependency graph visualizations with the `visualize` command:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Generate interactive HTML visualization
|
|
85
|
+
workspace-analyzer visualize
|
|
86
|
+
|
|
87
|
+
# Generate JSON data for external tools
|
|
88
|
+
workspace-analyzer visualize --format json --output graph.json
|
|
89
|
+
|
|
90
|
+
# Generate Mermaid diagram
|
|
91
|
+
workspace-analyzer visualize --format mermaid --output graph.mmd
|
|
92
|
+
|
|
93
|
+
# Interactive mode with options
|
|
94
|
+
workspace-analyzer visualize --interactive
|
|
95
|
+
|
|
96
|
+
# Custom title and node limits
|
|
97
|
+
workspace-analyzer visualize --title "My Project" --max-nodes 100
|
|
98
|
+
|
|
99
|
+
# Generate both HTML and JSON
|
|
100
|
+
workspace-analyzer visualize --format both
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### Visualization Options
|
|
104
|
+
|
|
105
|
+
| Option | Description | Default |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| `--output <path>` | Output file path | `workspace-graph.html` |
|
|
108
|
+
| `--format <format>` | Output format: html, json, mermaid, both | `html` |
|
|
109
|
+
| `--no-open` | Disable auto-opening in browser | false (opens by default) |
|
|
110
|
+
| `--title <title>` | Visualization title | `Workspace Dependency Graph` |
|
|
111
|
+
| `--max-nodes <number>` | Maximum nodes to render (performance) | `1000` |
|
|
112
|
+
| `--include-type-imports` | Include type-only imports in graph | `false` |
|
|
113
|
+
| `--interactive` | Interactive mode for options selection | false |
|
|
114
|
+
|
|
115
|
+
#### Export Formats
|
|
116
|
+
|
|
117
|
+
**HTML** - Self-contained interactive visualization with D3.js:
|
|
118
|
+
|
|
119
|
+
- Force-directed graph layout with zoom/pan controls
|
|
120
|
+
- Filter by layer, severity, package scope
|
|
121
|
+
- View modes: all, cycles-only, violations-only
|
|
122
|
+
- Node tooltips with violation details
|
|
123
|
+
- No external network requests (fully offline)
|
|
124
|
+
|
|
125
|
+
**JSON** - Structured data for external tools and custom processing:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"nodes": [
|
|
130
|
+
{
|
|
131
|
+
"id": "src/utils/helpers.ts",
|
|
132
|
+
"name": "helpers.ts",
|
|
133
|
+
"filePath": "src/utils/helpers.ts",
|
|
134
|
+
"packageName": "@myorg/utils",
|
|
135
|
+
"layer": "infrastructure",
|
|
136
|
+
"importsCount": 5,
|
|
137
|
+
"importedByCount": 12,
|
|
138
|
+
"isInCycle": false,
|
|
139
|
+
"violations": [
|
|
140
|
+
{
|
|
141
|
+
"id": "v1",
|
|
142
|
+
"message": "Layer violation: infrastructure importing from domain",
|
|
143
|
+
"severity": "error",
|
|
144
|
+
"ruleId": "layer-dependency"
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
"highestViolationSeverity": "error"
|
|
148
|
+
}
|
|
149
|
+
],
|
|
150
|
+
"edges": [
|
|
151
|
+
{
|
|
152
|
+
"source": "src/utils/helpers.ts",
|
|
153
|
+
"target": "src/core/types.ts",
|
|
154
|
+
"type": "static",
|
|
155
|
+
"isInCycle": false
|
|
156
|
+
}
|
|
157
|
+
],
|
|
158
|
+
"cycles": [
|
|
159
|
+
{
|
|
160
|
+
"id": "cycle-1",
|
|
161
|
+
"nodes": ["src/a.ts", "src/b.ts"],
|
|
162
|
+
"edges": [
|
|
163
|
+
{"from": "src/a.ts", "to": "src/b.ts"},
|
|
164
|
+
{"from": "src/b.ts", "to": "src/a.ts"}
|
|
165
|
+
],
|
|
166
|
+
"length": 2,
|
|
167
|
+
"description": "Circular dependency: a.ts → b.ts → a.ts"
|
|
168
|
+
}
|
|
169
|
+
],
|
|
170
|
+
"statistics": {
|
|
171
|
+
"totalNodes": 250,
|
|
172
|
+
"totalEdges": 380,
|
|
173
|
+
"totalCycles": 3,
|
|
174
|
+
"nodesByLayer": {
|
|
175
|
+
"domain": 50,
|
|
176
|
+
"application": 80,
|
|
177
|
+
"infrastructure": 120
|
|
178
|
+
},
|
|
179
|
+
"violationsBySeverity": {
|
|
180
|
+
"critical": 0,
|
|
181
|
+
"error": 5,
|
|
182
|
+
"warning": 15,
|
|
183
|
+
"info": 2
|
|
184
|
+
},
|
|
185
|
+
"packagesAnalyzed": 12,
|
|
186
|
+
"filesAnalyzed": 250
|
|
187
|
+
},
|
|
188
|
+
"metadata": {
|
|
189
|
+
"workspacePath": "/path/to/workspace",
|
|
190
|
+
"generatedAt": "2025-12-10T00:00:00Z",
|
|
191
|
+
"analyzerVersion": "0.1.0"
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Mermaid** - Diagram markup for documentation and external rendering:
|
|
197
|
+
|
|
198
|
+
```mermaid
|
|
199
|
+
graph LR
|
|
200
|
+
src_utils_helpers_ts["helpers.ts"]:::class-error
|
|
201
|
+
src_core_types_ts["types.ts"]:::class-normal
|
|
202
|
+
src_utils_helpers_ts --> src_core_types_ts
|
|
203
|
+
|
|
204
|
+
classDef class-critical fill:#ff4444,stroke:#cc0000,stroke-width:3px,color:#fff
|
|
205
|
+
classDef class-error fill:#ff8844,stroke:#cc4400,stroke-width:2px,color:#fff
|
|
206
|
+
classDef class-warning fill:#ffcc44,stroke:#ccaa00,stroke-width:2px,color:#000
|
|
207
|
+
classDef class-info fill:#4488ff,stroke:#0044cc,stroke-width:1px,color:#fff
|
|
208
|
+
classDef class-normal fill:#88ccff,stroke:#0088cc,stroke-width:1px,color:#000
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### Common Visualization Scenarios
|
|
212
|
+
|
|
213
|
+
**Investigate Circular Dependencies:**
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Generate visualization focusing on cycles
|
|
217
|
+
workspace-analyzer visualize --title "Circular Dependencies" --output cycles.html
|
|
218
|
+
|
|
219
|
+
# Export cycle data for CI validation
|
|
220
|
+
workspace-analyzer visualize --format json --output cycles.json
|
|
221
|
+
|
|
222
|
+
# Generate Mermaid diagram for documentation
|
|
223
|
+
workspace-analyzer visualize --format mermaid --output cycles.mmd
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Analyze Layer Architecture:**
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# Visualize architectural boundaries with violations highlighted
|
|
230
|
+
workspace-analyzer visualize --title "Architecture Review" --output architecture.html
|
|
231
|
+
|
|
232
|
+
# Focus on specific package scope
|
|
233
|
+
workspace-analyzer visualize --title "Core Packages" --output core.html
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**Performance Analysis:**
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
# Limit visualization to high-impact nodes
|
|
240
|
+
workspace-analyzer visualize --max-nodes 200 --output critical-paths.html
|
|
241
|
+
|
|
242
|
+
# Export JSON for custom metrics calculation
|
|
243
|
+
workspace-analyzer visualize --format json --output metrics.json
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**CI/CD Integration:**
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
# Generate artifacts for PR review
|
|
250
|
+
workspace-analyzer visualize --format both --no-open --output build/graph
|
|
251
|
+
|
|
252
|
+
# Validate no new circular dependencies
|
|
253
|
+
workspace-analyzer visualize --format json | jq '.statistics.totalCycles == 0'
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
#### Integration with External Tools
|
|
257
|
+
|
|
258
|
+
The JSON export format is designed for integration with custom analysis pipelines:
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
import {readFile} from 'node:fs/promises'
|
|
262
|
+
|
|
263
|
+
const data = JSON.parse(await readFile('graph.json', 'utf-8'))
|
|
264
|
+
|
|
265
|
+
// Find all files with critical violations
|
|
266
|
+
const criticalFiles = data.nodes.filter(
|
|
267
|
+
node => node.highestViolationSeverity === 'critical'
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
// Identify largest cycles
|
|
271
|
+
const largeCycles = data.cycles
|
|
272
|
+
.filter(cycle => cycle.length > 5)
|
|
273
|
+
.sort((a, b) => b.length - a.length)
|
|
274
|
+
|
|
275
|
+
// Calculate dependency metrics
|
|
276
|
+
const avgImportsPerFile = data.statistics.totalEdges / data.statistics.totalNodes
|
|
277
|
+
const cycleRate = data.statistics.totalCycles / data.statistics.totalNodes
|
|
278
|
+
|
|
279
|
+
// Detect architectural hotspots
|
|
280
|
+
const layerViolations = data.nodes
|
|
281
|
+
.filter(node => node.violations.some(v => v.ruleId === 'layer-dependency'))
|
|
282
|
+
.map(node => ({
|
|
283
|
+
file: node.filePath,
|
|
284
|
+
layer: node.layer,
|
|
285
|
+
violations: node.violations.length,
|
|
286
|
+
}))
|
|
287
|
+
.sort((a, b) => b.violations - a.violations)
|
|
288
|
+
|
|
289
|
+
// Find most connected nodes (potential coupling issues)
|
|
290
|
+
const highlyConnected = data.nodes
|
|
291
|
+
.filter(node => node.importsCount + node.importedByCount > 20)
|
|
292
|
+
.sort((a, b) =>
|
|
293
|
+
(b.importsCount + b.importedByCount) - (a.importsCount + a.importedByCount)
|
|
294
|
+
)
|
|
295
|
+
```
|
|
296
|
+
|
|
79
297
|
## Programmatic API
|
|
80
298
|
|
|
81
299
|
### `analyzeWorkspace(path, options)`
|