depwire-cli 1.0.4 → 1.0.7

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/dist/index.js CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  stashChanges,
18
18
  updateFileInGraph,
19
19
  watchProject
20
- } from "./chunk-JPDK7SOI.js";
20
+ } from "./chunk-IOJJTKI4.js";
21
21
  import {
22
22
  SimulationEngine,
23
23
  analyzeDeadCode,
@@ -31,7 +31,7 @@ import {
31
31
  parseProject,
32
32
  scanSecurity,
33
33
  searchSymbols
34
- } from "./chunk-7HLVFIVW.js";
34
+ } from "./chunk-SLGC72RW.js";
35
35
 
36
36
  // src/index.ts
37
37
  import { Command } from "commander";
@@ -528,6 +528,11 @@ function generateWhatIfHtml(currentVizData, simulatedVizData, simulationResult,
528
528
  </details>` : "";
529
529
  const currentDataJson = JSON.stringify(currentVizData);
530
530
  const simulatedDataJson = JSON.stringify(simulatedVizData);
531
+ const removedFilePairs = diff.removedEdges.map((e) => ({
532
+ source: e.source.split("::")[0],
533
+ target: e.target.split("::")[0]
534
+ }));
535
+ const removedFilePairsJson = JSON.stringify(removedFilePairs);
531
536
  return `<!DOCTYPE html>
532
537
  <html lang="en">
533
538
  <head>
@@ -616,6 +621,12 @@ function generateWhatIfHtml(currentVizData, simulatedVizData, simulationResult,
616
621
  width: 100%;
617
622
  height: 100%;
618
623
  }
624
+ .broken-arc {
625
+ stroke: #ef4444 !important;
626
+ stroke-opacity: 1.0 !important;
627
+ stroke-width: 2px !important;
628
+ filter: drop-shadow(0 0 4px rgba(239, 68, 68, 0.6));
629
+ }
619
630
  .broken-section {
620
631
  padding: 0 24px 24px;
621
632
  }
@@ -670,6 +681,57 @@ function generateWhatIfHtml(currentVizData, simulatedVizData, simulationResult,
670
681
  <script>
671
682
  const currentData = ${currentDataJson};
672
683
  const simulatedData = ${simulatedDataJson};
684
+ const removedFilePairs = ${removedFilePairsJson};
685
+
686
+ // Inject broken arcs and ghost files into the simulated data
687
+ // so they render on the right diagram and can be colored red
688
+ if (removedFilePairs.length > 0) {
689
+ // Deduplicate removed edges to file-level arcs
690
+ const brokenArcMap = new Map();
691
+ const ghostFiles = new Set();
692
+ const existingFiles = new Set(simulatedData.files.map(f => f.path));
693
+
694
+ for (const pair of removedFilePairs) {
695
+ const key = pair.source + '::' + pair.target;
696
+ if (brokenArcMap.has(key)) {
697
+ brokenArcMap.get(key).edgeCount++;
698
+ } else {
699
+ brokenArcMap.set(key, {
700
+ sourceFile: pair.source,
701
+ targetFile: pair.target,
702
+ edgeCount: 1,
703
+ edgeKinds: ['imports'],
704
+ broken: true,
705
+ });
706
+ }
707
+ // Track files that don't exist in simulated data (deleted files)
708
+ if (!existingFiles.has(pair.source)) ghostFiles.add(pair.source);
709
+ if (!existingFiles.has(pair.target)) ghostFiles.add(pair.target);
710
+ }
711
+
712
+ // Add ghost file bars for deleted files
713
+ for (const gf of ghostFiles) {
714
+ simulatedData.files.push({
715
+ path: gf,
716
+ directory: gf.includes('/') ? gf.substring(0, gf.lastIndexOf('/')) : '.',
717
+ symbolCount: 0,
718
+ incomingCount: 0,
719
+ outgoingCount: 0,
720
+ ghost: true,
721
+ });
722
+ }
723
+
724
+ // Re-sort files so ghost files are in correct position
725
+ simulatedData.files.sort((a, b) => {
726
+ if (a.directory !== b.directory) return a.directory.localeCompare(b.directory);
727
+ return a.path.localeCompare(b.path);
728
+ });
729
+
730
+ // Add broken arcs to simulated data
731
+ for (const arc of brokenArcMap.values()) {
732
+ simulatedData.arcs.push(arc);
733
+ }
734
+ }
673
735
 
674
736
  const left = window.createArcDiagram('arc-diagram-current', 'svg-current', 'tooltip-current', currentData);
675
737
  const right = window.createArcDiagram('arc-diagram-simulated', 'svg-simulated', 'tooltip-simulated', simulatedData);
@@ -677,9 +739,33 @@ function generateWhatIfHtml(currentVizData, simulatedVizData, simulationResult,
677
739
  left.render();
678
740
  right.render();
679
741
 
742
+ // After render: color broken arcs red and ghost file bars red on the right diagram
743
+ if (removedFilePairs.length > 0) {
744
+ d3.select('#arc-diagram-simulated').selectAll('.arc')
745
+ .filter(d => d.broken === true)
746
+ .classed('broken-arc', true);
747
+
748
+ d3.select('#arc-diagram-simulated').selectAll('.file-bar')
749
+ .filter(d => d.ghost === true)
750
+ .attr('fill', '#ef4444')
751
+ .attr('opacity', 0.8);
752
+ }
753
+
680
754
  window.addEventListener('resize', () => {
681
755
  left.render();
682
756
  right.render();
757
+
758
+ // Re-apply broken styling after resize re-render
759
+ if (removedFilePairs.length > 0) {
760
+ d3.select('#arc-diagram-simulated').selectAll('.arc')
761
+ .filter(d => d.broken === true)
762
+ .classed('broken-arc', true);
763
+
764
+ d3.select('#arc-diagram-simulated').selectAll('.file-bar')
765
+ .filter(d => d.ghost === true)
766
+ .attr('fill', '#ef4444')
767
+ .attr('opacity', 0.8);
768
+ }
683
769
  });
684
770
  </script>
685
771
  </body>
@@ -791,6 +877,16 @@ async function whatif(dir, options) {
791
877
  try {
792
878
  const result = engine.simulate(action);
793
879
  printResult(result);
880
+ const currentVizData = prepareVizData(graph, projectRoot);
881
+ const simulatedVizData = result.simulatedGraphInstance ? prepareVizData(result.simulatedGraphInstance, projectRoot) : currentVizData;
882
+ const { simulatedGraphInstance, ...serializableResult } = result;
883
+ await serveWhatIfViz(
884
+ currentVizData,
885
+ simulatedVizData,
886
+ serializableResult,
887
+ action.type,
888
+ action.target
889
+ );
794
890
  } catch (err) {
795
891
  console.error(chalk.red(`Simulation failed: ${err.message}`));
796
892
  process.exit(1);
@@ -4,11 +4,11 @@ import {
4
4
  startMcpServer,
5
5
  updateFileInGraph,
6
6
  watchProject
7
- } from "./chunk-JPDK7SOI.js";
7
+ } from "./chunk-IOJJTKI4.js";
8
8
  import {
9
9
  buildGraph,
10
10
  parseProject
11
- } from "./chunk-7HLVFIVW.js";
11
+ } from "./chunk-SLGC72RW.js";
12
12
 
13
13
  // src/mcpb-entry.ts
14
14
  import { resolve } from "path";
package/dist/sdk.d.ts CHANGED
@@ -169,6 +169,8 @@ interface SimulationResult {
169
169
  simulatedGraph: GraphSnapshot;
170
170
  diff: GraphDiff;
171
171
  healthDelta: HealthDelta;
172
+ /** The cloned graph with the simulation applied — available for viz data generation */
173
+ simulatedGraphInstance?: DirectedGraph;
172
174
  }
173
175
  interface GraphSnapshot {
174
176
  nodeCount: number;
package/dist/sdk.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  parseProject,
11
11
  scanSecurity,
12
12
  searchSymbols
13
- } from "./chunk-7HLVFIVW.js";
13
+ } from "./chunk-SLGC72RW.js";
14
14
 
15
15
  // src/sdk.ts
16
16
  import { readFileSync } from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "depwire-cli",
3
- "version": "1.0.4",
3
+ "version": "1.0.7",
4
4
  "description": "Dependency graph + 17 MCP tools for AI coding assistants. Impact analysis, health scoring, security scanner.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -40,7 +40,8 @@
40
40
  "what-if-analysis",
41
41
  "refactor-simulation",
42
42
  "blast-radius",
43
- "deterministic-graph"
43
+ "deterministic-graph",
44
+ "kotlin"
44
45
  ],
45
46
  "author": "Atef Ataya (https://www.youtube.com/@atefataya)",
46
47
  "license": "BUSL-1.1",