archbyte 0.4.2 → 0.5.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.
Files changed (38) hide show
  1. package/README.md +9 -25
  2. package/bin/archbyte.js +6 -41
  3. package/dist/agents/static/component-detector.js +71 -107
  4. package/dist/agents/static/connection-mapper.js +24 -25
  5. package/dist/agents/static/deep-drill.d.ts +72 -0
  6. package/dist/agents/static/deep-drill.js +388 -0
  7. package/dist/agents/static/doc-parser.js +73 -48
  8. package/dist/agents/static/env-detector.js +3 -6
  9. package/dist/agents/static/event-detector.js +20 -26
  10. package/dist/agents/static/infra-analyzer.js +15 -1
  11. package/dist/agents/static/structure-scanner.js +56 -57
  12. package/dist/agents/static/taxonomy.d.ts +19 -0
  13. package/dist/agents/static/taxonomy.js +147 -0
  14. package/dist/agents/tools/local-fs.js +5 -2
  15. package/dist/cli/analyze.js +49 -27
  16. package/dist/cli/license-gate.js +47 -19
  17. package/dist/cli/run.js +117 -1
  18. package/dist/cli/setup.d.ts +6 -1
  19. package/dist/cli/setup.js +35 -16
  20. package/dist/cli/shared.d.ts +0 -11
  21. package/dist/cli/shared.js +0 -61
  22. package/dist/cli/workflow.js +8 -15
  23. package/dist/server/src/index.js +276 -168
  24. package/package.json +2 -2
  25. package/templates/archbyte.yaml +28 -7
  26. package/ui/dist/assets/index-BQouokNH.css +1 -0
  27. package/ui/dist/assets/index-QllGSFhe.js +72 -0
  28. package/ui/dist/index.html +2 -2
  29. package/dist/cli/arch-diff.d.ts +0 -38
  30. package/dist/cli/arch-diff.js +0 -61
  31. package/dist/cli/diff.d.ts +0 -10
  32. package/dist/cli/diff.js +0 -144
  33. package/dist/cli/patrol.d.ts +0 -18
  34. package/dist/cli/patrol.js +0 -596
  35. package/dist/cli/validate.d.ts +0 -53
  36. package/dist/cli/validate.js +0 -299
  37. package/ui/dist/assets/index-DDCNauh7.css +0 -1
  38. package/ui/dist/assets/index-DO4t5Xu1.js +0 -72
@@ -6,8 +6,8 @@
6
6
  <title>ArchByte</title>
7
7
  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png">
8
8
  <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16.png">
9
- <script type="module" crossorigin src="/assets/index-DO4t5Xu1.js"></script>
10
- <link rel="stylesheet" crossorigin href="/assets/index-DDCNauh7.css">
9
+ <script type="module" crossorigin src="/assets/index-QllGSFhe.js"></script>
10
+ <link rel="stylesheet" crossorigin href="/assets/index-BQouokNH.css">
11
11
  </head>
12
12
  <body>
13
13
  <script>try{if(localStorage.getItem('archbyte-theme')==='light')document.documentElement.setAttribute('data-theme','light')}catch(e){}</script>
@@ -1,38 +0,0 @@
1
- /**
2
- * Architecture diff — computes structural changes between two architecture snapshots.
3
- * Used by patrol for change detection and by diff command for comparison.
4
- */
5
- import type { Architecture } from "../server/src/generator/index.js";
6
- export interface StructuralDiff {
7
- addedNodes: Array<{
8
- id: string;
9
- label: string;
10
- type: string;
11
- layer: string;
12
- }>;
13
- removedNodes: Array<{
14
- id: string;
15
- label: string;
16
- type: string;
17
- layer: string;
18
- }>;
19
- modifiedNodes: Array<{
20
- id: string;
21
- field: string;
22
- from: string;
23
- to: string;
24
- }>;
25
- addedEdges: Array<{
26
- source: string;
27
- target: string;
28
- label?: string;
29
- }>;
30
- removedEdges: Array<{
31
- source: string;
32
- target: string;
33
- label?: string;
34
- }>;
35
- }
36
- export declare function diffArchitectures(prev: Architecture, curr: Architecture): StructuralDiff;
37
- export declare function loadArchitectureJSON(rootDir: string): Architecture | null;
38
- export declare function hasStructuralChanges(diff: StructuralDiff): boolean;
@@ -1,61 +0,0 @@
1
- /**
2
- * Architecture diff — computes structural changes between two architecture snapshots.
3
- * Used by patrol for change detection and by diff command for comparison.
4
- */
5
- import * as fs from "fs";
6
- import * as path from "path";
7
- export function diffArchitectures(prev, curr) {
8
- const prevNodeMap = new Map();
9
- for (const n of prev.nodes)
10
- prevNodeMap.set(n.id, n);
11
- const currNodeMap = new Map();
12
- for (const n of curr.nodes)
13
- currNodeMap.set(n.id, n);
14
- const prevNodeIds = new Set(prev.nodes.map((n) => n.id));
15
- const currNodeIds = new Set(curr.nodes.map((n) => n.id));
16
- const addedNodes = curr.nodes
17
- .filter((n) => !prevNodeIds.has(n.id))
18
- .map((n) => ({ id: n.id, label: n.label, type: n.type, layer: n.layer }));
19
- const removedNodes = prev.nodes
20
- .filter((n) => !currNodeIds.has(n.id))
21
- .map((n) => ({ id: n.id, label: n.label, type: n.type, layer: n.layer }));
22
- const modifiedNodes = [];
23
- for (const n of curr.nodes) {
24
- const old = prevNodeMap.get(n.id);
25
- if (!old)
26
- continue;
27
- for (const field of ["label", "type", "layer"]) {
28
- if (old[field] !== n[field]) {
29
- modifiedNodes.push({ id: n.id, field, from: old[field], to: n[field] });
30
- }
31
- }
32
- }
33
- const edgeKey = (e) => `${e.source}->${e.target}`;
34
- const prevEdgeKeys = new Set(prev.edges.map(edgeKey));
35
- const currEdgeKeys = new Set(curr.edges.map(edgeKey));
36
- const addedEdges = curr.edges
37
- .filter((e) => !prevEdgeKeys.has(edgeKey(e)))
38
- .map((e) => ({ source: e.source, target: e.target, label: e.label }));
39
- const removedEdges = prev.edges
40
- .filter((e) => !currEdgeKeys.has(edgeKey(e)))
41
- .map((e) => ({ source: e.source, target: e.target, label: e.label }));
42
- return { addedNodes, removedNodes, modifiedNodes, addedEdges, removedEdges };
43
- }
44
- export function loadArchitectureJSON(rootDir) {
45
- const archPath = path.join(rootDir, ".archbyte", "architecture.json");
46
- if (!fs.existsSync(archPath))
47
- return null;
48
- try {
49
- return JSON.parse(fs.readFileSync(archPath, "utf-8"));
50
- }
51
- catch {
52
- return null;
53
- }
54
- }
55
- export function hasStructuralChanges(diff) {
56
- return (diff.addedNodes.length > 0 ||
57
- diff.removedNodes.length > 0 ||
58
- diff.modifiedNodes.length > 0 ||
59
- diff.addedEdges.length > 0 ||
60
- diff.removedEdges.length > 0);
61
- }
@@ -1,10 +0,0 @@
1
- interface DiffOptions {
2
- baseline: string;
3
- current?: string;
4
- config?: string;
5
- }
6
- /**
7
- * Compare two architecture snapshots and show drift report.
8
- */
9
- export declare function handleDiff(options: DiffOptions): Promise<void>;
10
- export {};
package/dist/cli/diff.js DELETED
@@ -1,144 +0,0 @@
1
- import * as path from "path";
2
- import chalk from "chalk";
3
- import { resolveArchitecturePath, loadArchitectureFile, loadRulesConfig, getRuleLevel, getThreshold, } from "./shared.js";
4
- import { checkNoLayerBypass, checkMaxConnections, checkNoOrphans, checkCircularDeps, } from "./validate.js";
5
- /**
6
- * Compare two architecture snapshots and show drift report.
7
- */
8
- export async function handleDiff(options) {
9
- if (!options.baseline) {
10
- console.error(chalk.red("--baseline <path> is required"));
11
- process.exit(1);
12
- }
13
- const baseArch = loadArchitectureFile(path.resolve(process.cwd(), options.baseline));
14
- const currentPath = options.current
15
- ? path.resolve(process.cwd(), options.current)
16
- : resolveArchitecturePath({});
17
- const currentArch = loadArchitectureFile(currentPath);
18
- const projectName = process.cwd().split("/").pop() || "project";
19
- console.log();
20
- console.log(chalk.bold.cyan(`⚡ ArchByte Diff: ${projectName}`));
21
- console.log(chalk.gray(` Baseline: ${options.baseline}`));
22
- console.log(chalk.gray(` Current: ${options.current || ".archbyte/architecture.json"}`));
23
- console.log();
24
- // ── Components ──
25
- const baseNodes = new Set(baseArch.nodes.map((n) => n.id));
26
- const currentNodes = new Set(currentArch.nodes.map((n) => n.id));
27
- const added = [...currentNodes].filter((id) => !baseNodes.has(id));
28
- const removed = [...baseNodes].filter((id) => !currentNodes.has(id));
29
- const currentNodeMap = new Map();
30
- for (const n of currentArch.nodes)
31
- currentNodeMap.set(n.id, n);
32
- const baseNodeMap = new Map();
33
- for (const n of baseArch.nodes)
34
- baseNodeMap.set(n.id, n);
35
- console.log(chalk.bold(" Components:"));
36
- if (added.length === 0 && removed.length === 0) {
37
- console.log(chalk.green(" No changes"));
38
- }
39
- else {
40
- for (const id of added) {
41
- const node = currentNodeMap.get(id);
42
- console.log(chalk.green(` + ${node?.label || id} (${node?.layer || "unknown"})`));
43
- }
44
- for (const id of removed) {
45
- const node = baseNodeMap.get(id);
46
- console.log(chalk.red(` - ${node?.label || id} (${node?.layer || "unknown"})`));
47
- }
48
- }
49
- console.log();
50
- // ── Connections ──
51
- const edgeKey = (e) => `${e.source}->${e.target}`;
52
- const baseEdges = new Set(baseArch.edges.map(edgeKey));
53
- const currentEdges = new Set(currentArch.edges.map(edgeKey));
54
- const addedEdges = currentArch.edges.filter((e) => !baseEdges.has(edgeKey(e)));
55
- const removedEdges = baseArch.edges.filter((e) => !currentEdges.has(edgeKey(e)));
56
- console.log(chalk.bold(" Connections:"));
57
- if (addedEdges.length === 0 && removedEdges.length === 0) {
58
- console.log(chalk.green(" No changes"));
59
- }
60
- else {
61
- for (const e of addedEdges) {
62
- const src = currentNodeMap.get(e.source)?.label || e.source;
63
- const tgt = currentNodeMap.get(e.target)?.label || e.target;
64
- console.log(chalk.green(` + ${src} → ${tgt}`));
65
- }
66
- for (const e of removedEdges) {
67
- const src = baseNodeMap.get(e.source)?.label || e.source;
68
- const tgt = baseNodeMap.get(e.target)?.label || e.target;
69
- console.log(chalk.red(` - ${src} → ${tgt}`));
70
- }
71
- }
72
- console.log();
73
- // ── Density Change ──
74
- const calcDensity = (arch) => {
75
- const n = arch.nodes.length;
76
- const possible = n > 1 ? (n * (n - 1)) / 2 : 1;
77
- return arch.edges.length / possible;
78
- };
79
- const baseDensity = calcDensity(baseArch);
80
- const currentDensity = calcDensity(currentArch);
81
- const densityDelta = currentDensity - baseDensity;
82
- console.log(chalk.bold(" Density:"));
83
- const arrow = densityDelta > 0 ? "↑" : densityDelta < 0 ? "↓" : "=";
84
- const densityColor = Math.abs(densityDelta) < 0.01 ? chalk.gray : densityDelta > 0 ? chalk.yellow : chalk.green;
85
- console.log(densityColor(` ${baseDensity.toFixed(3)} → ${currentDensity.toFixed(3)} (${arrow} ${Math.abs(densityDelta).toFixed(3)})`));
86
- console.log();
87
- // ── Violations Diff ──
88
- const config = loadRulesConfig(options.config);
89
- const getViolations = (arch) => {
90
- const nodes = arch.nodes;
91
- const map = new Map();
92
- for (const n of nodes)
93
- map.set(n.id, n);
94
- const violations = [];
95
- const bypassLevel = getRuleLevel(config, "no-layer-bypass", "error");
96
- if (bypassLevel !== "off")
97
- violations.push(...checkNoLayerBypass(arch, nodes, map, bypassLevel));
98
- const maxLevel = getRuleLevel(config, "max-connections", "warn");
99
- if (maxLevel !== "off")
100
- violations.push(...checkMaxConnections(arch, nodes, maxLevel, getThreshold(config, "max-connections", 6)));
101
- const orphanLevel = getRuleLevel(config, "no-orphans", "warn");
102
- if (orphanLevel !== "off")
103
- violations.push(...checkNoOrphans(arch, nodes, orphanLevel));
104
- const circularLevel = getRuleLevel(config, "no-circular-deps", "error");
105
- if (circularLevel !== "off")
106
- violations.push(...checkCircularDeps(arch, nodes, map, circularLevel));
107
- return violations;
108
- };
109
- const baseViolations = getViolations(baseArch);
110
- const currentViolations = getViolations(currentArch);
111
- const violationKey = (v) => `${v.rule}:${v.message}`;
112
- const baseViolationKeys = new Set(baseViolations.map(violationKey));
113
- const currentViolationKeys = new Set(currentViolations.map(violationKey));
114
- const newViolations = currentViolations.filter((v) => !baseViolationKeys.has(violationKey(v)));
115
- const resolvedViolations = baseViolations.filter((v) => !currentViolationKeys.has(violationKey(v)));
116
- console.log(chalk.bold(" Violations:"));
117
- if (newViolations.length === 0 && resolvedViolations.length === 0) {
118
- console.log(chalk.green(" No changes"));
119
- }
120
- else {
121
- for (const v of newViolations) {
122
- const icon = v.level === "error" ? chalk.red("NEW") : chalk.yellow("NEW");
123
- console.log(` ${icon} [${v.rule}] ${v.message}`);
124
- }
125
- for (const v of resolvedViolations) {
126
- console.log(chalk.green(` RESOLVED [${v.rule}] ${v.message}`));
127
- }
128
- }
129
- // ── Summary ──
130
- console.log();
131
- const totalChanges = added.length + removed.length + addedEdges.length + removedEdges.length;
132
- if (totalChanges === 0 && newViolations.length === 0) {
133
- console.log(chalk.green(" No architectural drift detected."));
134
- }
135
- else {
136
- console.log(` Summary: ${chalk.green(`+${added.length}`)} / ${chalk.red(`-${removed.length}`)} components, ` +
137
- `${chalk.green(`+${addedEdges.length}`)} / ${chalk.red(`-${removedEdges.length}`)} connections, ` +
138
- `${chalk.red(`${newViolations.length} new`)} / ${chalk.green(`${resolvedViolations.length} resolved`)} violations`);
139
- }
140
- console.log();
141
- if (newViolations.some((v) => v.level === "error")) {
142
- process.exit(1);
143
- }
144
- }
@@ -1,18 +0,0 @@
1
- interface PatrolOptions {
2
- diagram?: string;
3
- config?: string;
4
- interval?: string;
5
- onViolation?: string;
6
- daemon?: boolean;
7
- once?: boolean;
8
- watch?: boolean;
9
- history?: boolean;
10
- }
11
- /**
12
- * Run the architecture patrol daemon.
13
- * Each cycle: snapshot → analyze (incremental) → generate → validate → diff
14
- *
15
- * --once: run a single cycle then exit (used by UI "Run Now")
16
- */
17
- export declare function handlePatrol(options: PatrolOptions): Promise<void>;
18
- export {};