blasttrace 1.0.2__py3-none-any.whl

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.

Potentially problematic release.


This version of blasttrace might be problematic. Click here for more details.

@@ -0,0 +1,165 @@
1
+ """
2
+ BlastTrace Mermaid Blast-Radius Visualizer
3
+ Generates render-ready Mermaid.js flowcharts for Full-Stack Contract Blast Radius,
4
+ Cross-Stack Dependency Chains, and Circular Code Dependency Loops.
5
+ """
6
+
7
+ from typing import List, Dict, Any, Optional
8
+
9
+
10
+ def sanitize_id(node_id: str, prefix: str = "N") -> str:
11
+ cleaned = "".join(c if c.isalnum() or c == "_" else "_" for c in node_id)
12
+ return f"{prefix}_{cleaned}"
13
+
14
+
15
+ def sanitize_label(text: str) -> str:
16
+ return text.replace('"', "'").replace("\n", " ").replace("[", "(").replace("]", ")")
17
+
18
+
19
+ def _layer_style_for_node(node_id: str) -> str:
20
+ if node_id.startswith("db:"):
21
+ return "dbNode"
22
+ if node_id.startswith(("orm:", "py:")):
23
+ return "backendNode"
24
+ if node_id.startswith("api"):
25
+ return "apiNode"
26
+ if node_id.startswith("fe:"):
27
+ return "frontendNode"
28
+ if node_id.startswith("test:"):
29
+ return "testNode"
30
+ return "backendNode"
31
+
32
+
33
+ def _layer_icon_for_node(node_id: str) -> str:
34
+ if node_id.startswith("db:"):
35
+ return "๐Ÿ—„๏ธ DB:"
36
+ if node_id.startswith("orm:"):
37
+ return "๐Ÿงฉ ORM:"
38
+ if node_id.startswith("py:"):
39
+ return "โš™๏ธ Backend:"
40
+ if node_id.startswith("api"):
41
+ return "๐Ÿ”Œ API:"
42
+ if node_id.startswith("fe:"):
43
+ return "๐Ÿ–ฅ๏ธ UI:"
44
+ if node_id.startswith("test:"):
45
+ return "๐Ÿงช Test:"
46
+ return "๐Ÿ“ฆ Symbol:"
47
+
48
+
49
+ def generate_mermaid_blast_radius(
50
+ chains: List[List[str]],
51
+ title: str = "Full-Stack Blast Radius",
52
+ gate_status: str = "BLOCK",
53
+ topology: Optional[Dict[str, Any]] = None,
54
+ ) -> str:
55
+ """
56
+ Generates a left-to-right Mermaid diagram visualizing all downstream consumers
57
+ across Database, Backend, API, Frontend, and Tests.
58
+ """
59
+ if not chains or len(chains) == 0:
60
+ return (
61
+ "```mermaid\n"
62
+ "flowchart LR\n"
63
+ " classDef safe fill:#059669,stroke:#047857,stroke-width:2px,color:#ffffff,font-weight:bold;\n"
64
+ " SAFE[\"โœ… Zero Downstream Breaking Impact Detected (PASS)\"]:::safe\n"
65
+ "```"
66
+ )
67
+
68
+ nodes_by_id = (topology or {}).get("nodes_by_id", {})
69
+ lines = [
70
+ "```mermaid",
71
+ "flowchart LR",
72
+ " classDef origin fill:#dc2626,stroke:#7f1d1d,stroke-width:3px,color:#ffffff,font-weight:bold;",
73
+ " classDef dbNode fill:#d97706,stroke:#92400e,stroke-width:2px,color:#ffffff;",
74
+ " classDef backendNode fill:#2563eb,stroke:#1e40af,stroke-width:2px,color:#ffffff;",
75
+ " classDef apiNode fill:#7c3aed,stroke:#5b21b6,stroke-width:2px,color:#ffffff;",
76
+ " classDef frontendNode fill:#db2777,stroke:#9d174d,stroke-width:2px,color:#ffffff;",
77
+ " classDef testNode fill:#0d9488,stroke:#115e59,stroke-width:2px,color:#ffffff;",
78
+ f' subgraph BlastRadius ["{sanitize_label(title)} [{gate_status}]"]',
79
+ " direction LR",
80
+ ]
81
+
82
+ declared_nodes: Dict[str, str] = {}
83
+ declared_edges = set()
84
+ counter = 0
85
+
86
+ for chain in chains:
87
+ for idx, nid in enumerate(chain):
88
+ if nid not in declared_nodes:
89
+ counter += 1
90
+ var_name = f"B{counter}"
91
+ declared_nodes[nid] = var_name
92
+ nmeta = nodes_by_id.get(nid, {})
93
+ display_name = nmeta.get("name") or nid.split(":", 1)[-1]
94
+ rel_file = nmeta.get("file", "")
95
+ icon = "๐Ÿ’ฅ Edited:" if idx == 0 else _layer_icon_for_node(nid)
96
+ style_cls = "origin" if idx == 0 else _layer_style_for_node(nid)
97
+ label_str = f"{icon} {display_name}"
98
+ if rel_file and rel_file not in display_name:
99
+ label_str += f" ({rel_file})"
100
+ lines.append(f' {var_name}["{sanitize_label(label_str)}"]:::{style_cls}')
101
+
102
+ for idx in range(len(chain) - 1):
103
+ u, v = chain[idx], chain[idx + 1]
104
+ if u == v:
105
+ continue
106
+ edge_key = (declared_nodes[u], declared_nodes[v])
107
+ if edge_key not in declared_edges:
108
+ declared_edges.add(edge_key)
109
+ lines.append(f" {edge_key[0]} -->|impacts| {edge_key[1]}")
110
+
111
+ lines.append(" end")
112
+ lines.append("```")
113
+ return "\n".join(lines)
114
+
115
+
116
+ def generate_mermaid_contract_chain(
117
+ path: List[str],
118
+ title: str = "Cross-Stack Contract Chain",
119
+ topology: Optional[Dict[str, Any]] = None,
120
+ ) -> str:
121
+ if not path:
122
+ return generate_mermaid_blast_radius([], title=title, gate_status="PASS", topology=topology)
123
+ return generate_mermaid_blast_radius([path], title=title, gate_status="TRACED", topology=topology)
124
+
125
+
126
+ def generate_mermaid_cycles(cycles: List[List[str]]) -> str:
127
+ """
128
+ Generates Mermaid flowchart syntax for circular code dependency loops.
129
+ """
130
+ if not cycles or len(cycles) == 0:
131
+ return (
132
+ "```mermaid\n"
133
+ "flowchart TD\n"
134
+ " classDef clean fill:#059669,stroke:#047857,stroke-width:2px,color:#ffffff;\n"
135
+ " CLEAN[\"โœ… Zero Circular Code Dependencies Detected\"]:::clean\n"
136
+ "```"
137
+ )
138
+
139
+ lines = [
140
+ "```mermaid",
141
+ "flowchart TD",
142
+ " classDef cycleNode fill:#dc2626,stroke:#7f1d1d,stroke-width:2px,color:#ffffff,font-weight:bold;",
143
+ ]
144
+
145
+ for c_idx, cycle in enumerate(cycles):
146
+ lines.append(f' subgraph Cycle{c_idx} ["๐Ÿ” Circular Dependency Loop #{c_idx + 1}"]')
147
+ lines.append(" direction TB")
148
+ c_vars: List[str] = []
149
+ for n_idx, node in enumerate(cycle):
150
+ var_name = f"C{c_idx}_{n_idx}"
151
+ c_vars.append(var_name)
152
+ lines.append(f' {var_name}["{sanitize_label(node)}"]:::cycleNode')
153
+
154
+ if len(c_vars) == 2:
155
+ lines.append(f" {c_vars[0]} <-->|circular_import| {c_vars[1]}")
156
+ else:
157
+ for idx in range(len(c_vars)):
158
+ src = c_vars[idx]
159
+ dst = c_vars[(idx + 1) % len(c_vars)]
160
+ lines.append(f" {src} -->|imports| {dst}")
161
+ lines.append(" end")
162
+
163
+ lines.append("```")
164
+ return "\n".join(lines)
165
+
@@ -0,0 +1,125 @@
1
+ Metadata-Version: 2.4
2
+ Name: blasttrace
3
+ Version: 1.0.2
4
+ Summary: Pre-Edit Full-Stack Breaking-Change & Contract Blast-Radius Engine
5
+ Home-page: https://blasttrace.dev
6
+ Author: Moin Hasan
7
+ Author-email: Moin Hasan <moin_hasan@live.com>
8
+ License: Proprietary
9
+ Project-URL: Homepage, https://blasttrace.dev
10
+ Project-URL: Documentation, https://blasttrace.dev
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: C++
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Topic :: Software Development :: Testing
15
+ Classifier: Topic :: Software Development :: Quality Assurance
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: fastmcp>=0.1.0
18
+ Requires-Dist: requests>=2.28.0
19
+ Dynamic: author
20
+ Dynamic: home-page
21
+
22
+ # BlastTrace
23
+
24
+ > **Pre-Edit Full-Stack Breaking-Change & Contract Blast-Radius Engine**
25
+ > `Database` $\leftrightarrow$ `Backend ORM` $\leftrightarrow$ `API Route` $\leftrightarrow$ `Frontend UI` $\leftrightarrow$ `Tests`
26
+
27
+ [![PyPI Version](https://img.shields.io/badge/pypi-v1.0.0-orange.svg)](https://pypi.org/project/blasttrace/)
28
+ [![Engine](https://img.shields.io/badge/engine-BlastTrace%20Native%20Core-blue.svg)](https://blasttrace.dev)
29
+ [![License](https://img.shields.io/badge/license-Commercial%20%2F%20Community-green.svg)](https://blasttrace.dev)
30
+
31
+ ---
32
+
33
+ ## โšก What is BlastTrace?
34
+
35
+ BlastTrace is a high-performance **Model Context Protocol (MCP)** server and standalone CLI that prevents AI coding agents (and human developers) from silently breaking full-stack web applications.
36
+
37
+ Existing AST tools only trace single-language file imports (`File A -> File B`). They go **100% blind** when a schema edit crosses boundaries:
38
+ ```text
39
+ [Database Column: users.billing_balance]
40
+ โ†“
41
+ [Backend ORM Model: User.billing_balance]
42
+ โ†“
43
+ [API Endpoint: GET /api/v1/user/summary]
44
+ โ†“
45
+ [Frontend UI Component: CheckoutModal.tsx (data.billing_balance)]
46
+ โ†“
47
+ [Unit & E2E Tests: test_checkout.py, checkout.spec.ts]
48
+ ```
49
+
50
+ BlastTrace deterministically bridges this gap using the **BlastTrace Native Core**, catching breaking changes **before** the file is saved, before `git commit`, and before pull requests merge.
51
+
52
+ ---
53
+
54
+ ## ๐Ÿš€ Quick Start
55
+
56
+ ### 1. Installation
57
+ ```bash
58
+ pip install blasttrace
59
+ ```
60
+ *Or run zero-install via uvx:*
61
+ ```bash
62
+ uvx blasttrace
63
+ ```
64
+
65
+ ### 2. Standalone CLI Usage (Zero AI Required)
66
+ ```bash
67
+ # Check if a proposed edit or signature change breaks downstream consumers
68
+ blasttrace check src/api/routes.py --symbol get_user_profile
69
+
70
+ # Inspect current git diff for breaking full-stack changes
71
+ blasttrace diff
72
+
73
+ # Install git pre-commit safety gate across your repo
74
+ blasttrace pre-commit --install
75
+ ```
76
+
77
+ ### 3. Connect to AI Agents & IDEs (Cursor, Claude Code, Windsurf, VS Code)
78
+ Add to your `claude_desktop_config.json` or `.cursor/mcp.json`:
79
+ ```json
80
+ {
81
+ "mcpServers": {
82
+ "blasttrace": {
83
+ "command": "blasttrace"
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ ---
90
+
91
+ ## ๐Ÿ›ก๏ธ Supported Technology Stacks
92
+
93
+ - **Database & Schemas:** PostgreSQL, MySQL, SQLite migrations (`.sql`), Prisma (`schema.prisma`), Drizzle ORM, SQLAlchemy & Django ORM (`models.py`).
94
+ - **Backend & APIs:** Python (FastAPI, Flask, Django REST, async functions, classes), Node.js / TypeScript (Express, Next.js App Router `app/api/.../route.ts`, NestJS, OpenAPI / Swagger specs).
95
+ - **Frontend Consumers:** React, Next.js, Vue, TypeScript (`.tsx`, `.ts`) calling `fetch()`, `axios`, `useSWR()`, `useQuery()`, and property destructuring.
96
+ - **Test Discovery:** Pytest, Unittest, Jest, Vitest, Playwright, Cypress.
97
+
98
+ ---
99
+
100
+ ## ๐Ÿ”‘ Licensing & Tiers
101
+
102
+ | Tier | Price | Features |
103
+ | :--- | :--- | :--- |
104
+ | **Community** | **$0** (Free) | Index topology, basic single-file symbol reachability, community support |
105
+ | **Pro** | **$19/mo** (or $180/yr) | Pre-Edit Breaking-Change Gate (PASS/WARN/BLOCK), full-stack contract chains, circular dependency interceptor, 2 seats |
106
+ | **Team / CI Gate** | **$99/mo** (or $990/yr) | Everything in Pro, 5 seats, git pre-commit hook enforcement, GitHub Actions / GitLab CI PR Gate integration |
107
+
108
+ Activate your Pro license:
109
+ ```bash
110
+ blasttrace activate YOUR-LICENSE-KEY
111
+ ```
112
+
113
+ ---
114
+
115
+ ## ๐Ÿ”’ Security & Privacy
116
+
117
+ BlastTrace runs **100% locally and air-gapped** on your machine.
118
+ - Zero telemetry.
119
+ - Zero remote code scanning.
120
+ - Zero cloud database uploads.
121
+ - Your code never leaves your workstation.
122
+
123
+ ---
124
+
125
+ ยฉ 2026 BlastTrace Inc. All rights reserved. Official website: [blasttrace.dev](https://blasttrace.dev)
@@ -0,0 +1,18 @@
1
+ blasttrace/__init__.py,sha256=btjn2g5b-X3amyPdt7iYmLh8e9XJPZWPPy8idM7NDOY,160
2
+ blasttrace/classifier.py,sha256=Aj_wc3bFe1j5mPfl9tUe9W5cBgY5I2y42NMaOiuENrc,18932
3
+ blasttrace/license.py,sha256=p1q3mRUFvGWgJ3rX4P2DJhNDwyXAyaFFsc2IDEc6dT4,10663
4
+ blasttrace/remediation.py,sha256=wBswHi6EsWBsawU2jhvcKl-N-x9vAUtQgO37PEWuIOI,9436
5
+ blasttrace/server.py,sha256=CHgf7wj-uEC9o1wLWx8vIrIg3QLURHZMLb_PGMy7yaI,32398
6
+ blasttrace/visualizer.py,sha256=uMl5-NWfVPm4gOIAPLCN2oEM7tRVgyAY-dgXYhcj2Uw,6301
7
+ blasttrace/parsers/__init__.py,sha256=YZz8WFIdpQ31f4w_ldnp6YONucgrcwDO-gOtc1SpzEw,74
8
+ blasttrace/parsers/api_route_parser.py,sha256=LUtsG5LcCeRiRuC2OYEFI4FZBaFWuFkyS-65i0IehsU,12964
9
+ blasttrace/parsers/contract_linker.py,sha256=F5VfQ1z5t95UI2L3PoEfDd8DjjDhlMwJf_WkjeMca_8,22458
10
+ blasttrace/parsers/python_ast_parser.py,sha256=4vc87EuBgDDnjF_zxsfi45S8ypM4N9WRM8tTrgSU9Io,13201
11
+ blasttrace/parsers/sql_schema_parser.py,sha256=3KdBynO1acEyGxgVgvRt78hDKTetRmMlZzR2tGfkuCI,14770
12
+ blasttrace/parsers/test_mapper.py,sha256=DJoI1P0dpcYQIqyxhc6oQy5pSzUAVfTfdke0aT4AruI,6956
13
+ blasttrace/parsers/ts_react_parser.py,sha256=rtJFPp8G2MQvuOaa57j9oTY6neA2x-C6MToF6h0a5-c,11440
14
+ blasttrace-1.0.2.dist-info/METADATA,sha256=qC8FY3hCHNfzcvv7lhkZFHB-FtcxuJDxh5xKcPShxi4,4449
15
+ blasttrace-1.0.2.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
16
+ blasttrace-1.0.2.dist-info/entry_points.txt,sha256=YqImtXzrUYt4ugt24ZrSX8OhCzEsLAJbtl1izOx9dq0,94
17
+ blasttrace-1.0.2.dist-info/top_level.txt,sha256=HvYxGntDu3K7Rrw8WER3ilnqDicEiO7ptEhx_sNq9vo,11
18
+ blasttrace-1.0.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ blasttrace = blasttrace.server:main
3
+ blasttrace-mcp = blasttrace.server:main
@@ -0,0 +1 @@
1
+ blasttrace