decklens 0.1.0__tar.gz

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.
decklens-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Maya Kachina
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,192 @@
1
+ Metadata-Version: 2.4
2
+ Name: decklens
3
+ Version: 0.1.0
4
+ Summary: Engineering-aware semantic diff tool for CAE input files
5
+ Author-email: Maya Kachina <pj.kachina@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/pj-kachina/DeckLens-Semantic-Diff-for-CAE
8
+ Project-URL: Documentation, https://github.com/pj-kachina/DeckLens-Semantic-Diff-for-CAE#readme
9
+ Project-URL: Repository, https://github.com/pj-kachina/DeckLens-Semantic-Diff-for-CAE.git
10
+ Project-URL: Issues, https://github.com/pj-kachina/DeckLens-Semantic-Diff-for-CAE/issues
11
+ Project-URL: Changelog, https://github.com/pj-kachina/DeckLens-Semantic-Diff-for-CAE/blob/main/CHANGELOG.md
12
+ Keywords: CAE,FEA,diff,OpenRadioss,NASTRAN,LS-DYNA,semantic-diff,engineering,simulation,comparison
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Intended Audience :: End Users/Desktop
16
+ Classifier: Topic :: Scientific/Engineering
17
+ Classifier: Topic :: Utilities
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Requires-Python: >=3.11
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: anthropic>=0.49.0
27
+ Requires-Dist: click>=8.1
28
+ Requires-Dist: rich>=13.0
29
+ Requires-Dist: python-dotenv>=1.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=8.0; extra == "dev"
32
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ # DeckLens: Semantic Diff for CAE
36
+
37
+ ![VS Code Extension](https://img.shields.io/badge/extension-VS%20Code-blue)
38
+ ![License](https://img.shields.io/badge/license-MIT-green)
39
+
40
+ **DeckLens** は CAE(計算力学)入力ファイルの**セマンティックdiff**ツールです。テキスト差分ではなく、エンジニアリング観点から「何が変わった」かを理解します。
41
+
42
+ ## 問題
43
+
44
+ CAE検証チームの現状:
45
+ - 型紙(テンプレート)から修正内容を手動確認 → ボトルネック
46
+ - `grep` + テキストエディタで変更追跡 → ミスが多い
47
+ - 厚さ変更は単なる%数値表示 → 剛性への影響が不明確
48
+ - 境界条件削除が見落とされやすい
49
+
50
+ ## ソリューション
51
+
52
+ ```bash
53
+ $ decklens diff before.rad after.rad
54
+
55
+ ─────────── DeckLens Semantic Diff ──────────
56
+ Before: before.rad
57
+ After: after.rad
58
+
59
+ ┌─ Summary ─┐
60
+ │ 2 CRITICAL, 4 WARNING │
61
+ └────────────┘
62
+
63
+ ┌────────┬─────────┬────────────┬─────────────────────┐
64
+ │ Sev │ Type │ Name │ Field │
65
+ ├────────┼─────────┼────────────┼─────────────────────┤
66
+ │ [CRIT] │ PROP/SH │ OUTER_PNL │ thickness │
67
+ │ │ │ │ (bend-stiffness │
68
+ │ │ │ │ +138%) │
69
+ │ [CRIT] │ CLOAD │ FORCE_Z │ Fscale_y: 1000→2000│
70
+ │ [WARN] │ MAT/ELS │ STEEL │ E: 210k→206k (-1.9%)
71
+ │ [WARN] │ BCS │ FIXED_SUP │ RX: free→fixed │
72
+ └────────┴─────────┴────────────┴─────────────────────┘
73
+
74
+ 🤖 AI Engineering Analysis (Claude Opus 4.8)
75
+ ─────────────────────────────────────────
76
+ 曲げ剛性が +138% 増加(t³則)するため、座屈荷重が大幅に上昇。
77
+ ただし Young の係数が -1.9% 低下しているため、相殺効果は限定的。
78
+ 回転拘束追加により、モーメント反力が発生可能性あり。
79
+ 負荷 2 倍は FOS に直結 — 応力状態の再確認推奨。
80
+ ```
81
+
82
+ ### 主な機能
83
+
84
+ ✅ **OpenRadioss パーサー**
85
+ - `/PROP/SHELL`, `/MAT/ELAST`, `/MAT/PLAS_JOHNS`, `/PART`, `/BCS`, `/LOAD`, `/INTER` 対応
86
+ - FORTRAN D-notation(`7.85D-9`)自動変換
87
+
88
+ ✅ **セマンティック差分エンジン**
89
+ - 厚さ変更 → 曲げ剛性(EI ∝ t³)を自動計算・注釈
90
+ - Young係数 → 剛性への影響を評価
91
+ - 境界条件追加/削除 → 重大度を自動判定
92
+ - 負荷 2 倍 → CRITICAL フラグ
93
+
94
+ ✅ **重大度自動判定**
95
+ | 重大度 | 条件 |
96
+ |--------|------|
97
+ | CRITICAL | ≥20% 変化、または BC/PART 削除 |
98
+ | WARNING | 5–20% 変化、または BC 追加 |
99
+ | INFO | <5% 変化 |
100
+
101
+ ✅ **Claude AI 分析(オプション)**
102
+ - `claude-opus-4-8` による自動解釈
103
+ - 適応思考(adaptive thinking)で複雑な物理関係を推論
104
+ - JSON 出力対応(CI/CD 統合)
105
+
106
+ ## インストール
107
+
108
+ ### PyPI(CLI ツール)
109
+
110
+ ```bash
111
+ pip install decklens-semantic-diff
112
+ ```
113
+
114
+ ### VS Code 拡張機能
115
+
116
+ 1. VS Code Marketplace で「DeckLens」検索
117
+ 2. インストール
118
+ 3. `.env` に `ANTHROPIC_API_KEY` 設定(AI 分析有効化)
119
+
120
+ ## 使い方
121
+
122
+ ### CLI
123
+
124
+ ```bash
125
+ # 基本的な diff
126
+ decklens diff before.rad after.rad
127
+
128
+ # AI 分析をスキップ
129
+ decklens diff before.rad after.rad --no-ai
130
+
131
+ # JSON 出力(CI/CD 連携)
132
+ decklens diff before.rad after.rad --format json
133
+
134
+ # 重大度フィルタ
135
+ decklens diff before.rad after.rad --min-severity WARNING
136
+
137
+ # 別の Claude モデル指定
138
+ decklens diff before.rad after.rad --model claude-sonnet-4-6
139
+ ```
140
+
141
+ ### VS Code 拡張機能
142
+
143
+ 右クリック → **DeckLens: Compare with** → ファイル選択 → サイドパネルに結果表示
144
+
145
+ ## 対応フォーマット
146
+
147
+ | フォーマット | サポート | ロードマップ |
148
+ |------------|---------|-----------|
149
+ | OpenRadioss (.rad) | ✅ | 本実装 |
150
+ | NASTRAN (.bdf) | 🔜 | Q3 2026 |
151
+ | LS-DYNA (.k) | 🔜 | Q3 2026 |
152
+
153
+ ## 技術仕様
154
+
155
+ - **言語**: Python 3.11+(CLI)、TypeScript(VS Code 拡張)
156
+ - **API**: Claude Opus 4.8、adaptive thinking、high effort
157
+ - **出力**: Rich テーブル、Markdown、JSON
158
+ - **ライセンス**: MIT
159
+
160
+ ## 必要な環境
161
+
162
+ - Python 3.11+
163
+ - VS Code 1.85+(拡張機能使用時)
164
+ - ANTHROPIC_API_KEY(AI 分析機能使用時)
165
+
166
+ ## トラブルシューティング
167
+
168
+ ### Q: AI 分析が実行されない
169
+ **A**: `.env` に `ANTHROPIC_API_KEY` が設定されているか確認。未設定なら `--no-ai` を付与。
170
+
171
+ ### Q: 出力が文字化けする(Windows)
172
+ **A**: PowerShell で UTF-8 出力を有効化:
173
+ ```powershell
174
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
175
+ ```
176
+
177
+ ## 開発
178
+
179
+ ```bash
180
+ git clone https://github.com/YOUR_GITHUB_USERNAME/DeckLens-Semantic-Diff-for-CAE.git
181
+ cd DeckLens-Semantic-Diff-for-CAE
182
+ pip install -e ".[dev]"
183
+ pytest -v
184
+ ```
185
+
186
+ ## フィードバック
187
+
188
+ Issue や Discussion は [GitHub](https://github.com/YOUR_GITHUB_USERNAME/DeckLens-Semantic-Diff-for-CAE/issues) へ。
189
+
190
+ ---
191
+
192
+ **Made with ❤️ by CAE engineers, for CAE engineers**
@@ -0,0 +1,158 @@
1
+ # DeckLens: Semantic Diff for CAE
2
+
3
+ ![VS Code Extension](https://img.shields.io/badge/extension-VS%20Code-blue)
4
+ ![License](https://img.shields.io/badge/license-MIT-green)
5
+
6
+ **DeckLens** は CAE(計算力学)入力ファイルの**セマンティックdiff**ツールです。テキスト差分ではなく、エンジニアリング観点から「何が変わった」かを理解します。
7
+
8
+ ## 問題
9
+
10
+ CAE検証チームの現状:
11
+ - 型紙(テンプレート)から修正内容を手動確認 → ボトルネック
12
+ - `grep` + テキストエディタで変更追跡 → ミスが多い
13
+ - 厚さ変更は単なる%数値表示 → 剛性への影響が不明確
14
+ - 境界条件削除が見落とされやすい
15
+
16
+ ## ソリューション
17
+
18
+ ```bash
19
+ $ decklens diff before.rad after.rad
20
+
21
+ ─────────── DeckLens Semantic Diff ──────────
22
+ Before: before.rad
23
+ After: after.rad
24
+
25
+ ┌─ Summary ─┐
26
+ │ 2 CRITICAL, 4 WARNING │
27
+ └────────────┘
28
+
29
+ ┌────────┬─────────┬────────────┬─────────────────────┐
30
+ │ Sev │ Type │ Name │ Field │
31
+ ├────────┼─────────┼────────────┼─────────────────────┤
32
+ │ [CRIT] │ PROP/SH │ OUTER_PNL │ thickness │
33
+ │ │ │ │ (bend-stiffness │
34
+ │ │ │ │ +138%) │
35
+ │ [CRIT] │ CLOAD │ FORCE_Z │ Fscale_y: 1000→2000│
36
+ │ [WARN] │ MAT/ELS │ STEEL │ E: 210k→206k (-1.9%)
37
+ │ [WARN] │ BCS │ FIXED_SUP │ RX: free→fixed │
38
+ └────────┴─────────┴────────────┴─────────────────────┘
39
+
40
+ 🤖 AI Engineering Analysis (Claude Opus 4.8)
41
+ ─────────────────────────────────────────
42
+ 曲げ剛性が +138% 増加(t³則)するため、座屈荷重が大幅に上昇。
43
+ ただし Young の係数が -1.9% 低下しているため、相殺効果は限定的。
44
+ 回転拘束追加により、モーメント反力が発生可能性あり。
45
+ 負荷 2 倍は FOS に直結 — 応力状態の再確認推奨。
46
+ ```
47
+
48
+ ### 主な機能
49
+
50
+ ✅ **OpenRadioss パーサー**
51
+ - `/PROP/SHELL`, `/MAT/ELAST`, `/MAT/PLAS_JOHNS`, `/PART`, `/BCS`, `/LOAD`, `/INTER` 対応
52
+ - FORTRAN D-notation(`7.85D-9`)自動変換
53
+
54
+ ✅ **セマンティック差分エンジン**
55
+ - 厚さ変更 → 曲げ剛性(EI ∝ t³)を自動計算・注釈
56
+ - Young係数 → 剛性への影響を評価
57
+ - 境界条件追加/削除 → 重大度を自動判定
58
+ - 負荷 2 倍 → CRITICAL フラグ
59
+
60
+ ✅ **重大度自動判定**
61
+ | 重大度 | 条件 |
62
+ |--------|------|
63
+ | CRITICAL | ≥20% 変化、または BC/PART 削除 |
64
+ | WARNING | 5–20% 変化、または BC 追加 |
65
+ | INFO | <5% 変化 |
66
+
67
+ ✅ **Claude AI 分析(オプション)**
68
+ - `claude-opus-4-8` による自動解釈
69
+ - 適応思考(adaptive thinking)で複雑な物理関係を推論
70
+ - JSON 出力対応(CI/CD 統合)
71
+
72
+ ## インストール
73
+
74
+ ### PyPI(CLI ツール)
75
+
76
+ ```bash
77
+ pip install decklens-semantic-diff
78
+ ```
79
+
80
+ ### VS Code 拡張機能
81
+
82
+ 1. VS Code Marketplace で「DeckLens」検索
83
+ 2. インストール
84
+ 3. `.env` に `ANTHROPIC_API_KEY` 設定(AI 分析有効化)
85
+
86
+ ## 使い方
87
+
88
+ ### CLI
89
+
90
+ ```bash
91
+ # 基本的な diff
92
+ decklens diff before.rad after.rad
93
+
94
+ # AI 分析をスキップ
95
+ decklens diff before.rad after.rad --no-ai
96
+
97
+ # JSON 出力(CI/CD 連携)
98
+ decklens diff before.rad after.rad --format json
99
+
100
+ # 重大度フィルタ
101
+ decklens diff before.rad after.rad --min-severity WARNING
102
+
103
+ # 別の Claude モデル指定
104
+ decklens diff before.rad after.rad --model claude-sonnet-4-6
105
+ ```
106
+
107
+ ### VS Code 拡張機能
108
+
109
+ 右クリック → **DeckLens: Compare with** → ファイル選択 → サイドパネルに結果表示
110
+
111
+ ## 対応フォーマット
112
+
113
+ | フォーマット | サポート | ロードマップ |
114
+ |------------|---------|-----------|
115
+ | OpenRadioss (.rad) | ✅ | 本実装 |
116
+ | NASTRAN (.bdf) | 🔜 | Q3 2026 |
117
+ | LS-DYNA (.k) | 🔜 | Q3 2026 |
118
+
119
+ ## 技術仕様
120
+
121
+ - **言語**: Python 3.11+(CLI)、TypeScript(VS Code 拡張)
122
+ - **API**: Claude Opus 4.8、adaptive thinking、high effort
123
+ - **出力**: Rich テーブル、Markdown、JSON
124
+ - **ライセンス**: MIT
125
+
126
+ ## 必要な環境
127
+
128
+ - Python 3.11+
129
+ - VS Code 1.85+(拡張機能使用時)
130
+ - ANTHROPIC_API_KEY(AI 分析機能使用時)
131
+
132
+ ## トラブルシューティング
133
+
134
+ ### Q: AI 分析が実行されない
135
+ **A**: `.env` に `ANTHROPIC_API_KEY` が設定されているか確認。未設定なら `--no-ai` を付与。
136
+
137
+ ### Q: 出力が文字化けする(Windows)
138
+ **A**: PowerShell で UTF-8 出力を有効化:
139
+ ```powershell
140
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
141
+ ```
142
+
143
+ ## 開発
144
+
145
+ ```bash
146
+ git clone https://github.com/YOUR_GITHUB_USERNAME/DeckLens-Semantic-Diff-for-CAE.git
147
+ cd DeckLens-Semantic-Diff-for-CAE
148
+ pip install -e ".[dev]"
149
+ pytest -v
150
+ ```
151
+
152
+ ## フィードバック
153
+
154
+ Issue や Discussion は [GitHub](https://github.com/YOUR_GITHUB_USERNAME/DeckLens-Semantic-Diff-for-CAE/issues) へ。
155
+
156
+ ---
157
+
158
+ **Made with ❤️ by CAE engineers, for CAE engineers**
@@ -0,0 +1,3 @@
1
+ """DeckLens Semantic Diff for CAE — OpenRadioss input file analysis."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,199 @@
1
+ """CLI entry point for DeckLens Semantic Diff."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ import click
10
+ from rich.columns import Columns
11
+ from rich.console import Console
12
+ from rich.panel import Panel
13
+ from rich.table import Table
14
+ from rich.text import Text
15
+
16
+ from .diff.engine import Change, DiffEngine
17
+ from .parsers.openradioss import parse_deck
18
+
19
+ def _make_console() -> Console:
20
+ import sys
21
+ if sys.platform == "win32":
22
+ try:
23
+ sys.stdout.reconfigure(encoding="utf-8", errors="replace") # type: ignore[attr-defined]
24
+ sys.stderr.reconfigure(encoding="utf-8", errors="replace") # type: ignore[attr-defined]
25
+ except (AttributeError, Exception):
26
+ pass
27
+ return Console(highlight=False, safe_box=True)
28
+
29
+
30
+ console = _make_console()
31
+
32
+ _SEVERITY_STYLE = {
33
+ "CRITICAL": "bold red",
34
+ "WARNING": "bold yellow",
35
+ "INFO": "cyan",
36
+ }
37
+ _SEVERITY_LABEL = {
38
+ "CRITICAL": "CRIT",
39
+ "WARNING": "WARN",
40
+ "INFO": "INFO",
41
+ }
42
+
43
+
44
+ def _fmt_value(v, unit: str | None) -> str:
45
+ if v is None:
46
+ return "-"
47
+ u = f" {unit}" if unit else ""
48
+ if isinstance(v, float):
49
+ return f"{v:g}{u}"
50
+ return f"{v}{u}"
51
+
52
+
53
+ def _pct_text(pct: float | None) -> Text:
54
+ if pct is None:
55
+ return Text("")
56
+ sign = "+" if pct > 0 else ""
57
+ color = "red" if abs(pct) >= 20 else "yellow" if abs(pct) >= 5 else "green"
58
+ return Text(f"{sign}{pct:.1f}%", style=color)
59
+
60
+
61
+ def _build_table(changes: list[Change]) -> Table:
62
+ table = Table(
63
+ show_header=True,
64
+ header_style="bold white on dark_blue",
65
+ border_style="bright_black",
66
+ safe_box=True,
67
+ )
68
+ table.add_column("Sev", style="bold", no_wrap=True)
69
+ table.add_column("Category", no_wrap=True)
70
+ table.add_column("Type / ID", no_wrap=True)
71
+ table.add_column("Name")
72
+ table.add_column("Field", ratio=2)
73
+ table.add_column("Before", justify="right", no_wrap=True)
74
+ table.add_column("After", justify="right", no_wrap=True)
75
+ table.add_column("Change", justify="right", no_wrap=True)
76
+
77
+ for ch in changes:
78
+ style = _SEVERITY_STYLE[ch.severity]
79
+ icon = Text("[" + _SEVERITY_LABEL[ch.severity] + "]", style=style)
80
+ table.add_row(
81
+ icon,
82
+ Text(ch.category, style="dim"),
83
+ Text(f"{ch.item_type}/{ch.item_id}", style="bright_white"),
84
+ Text(str(ch.item_name), style="white"),
85
+ Text(str(ch.field)),
86
+ Text(_fmt_value(ch.old_value, None)),
87
+ Text(_fmt_value(ch.new_value, ch.unit)),
88
+ _pct_text(ch.percent_change),
89
+ )
90
+
91
+ return table
92
+
93
+
94
+ def _build_summary(changes: list[Change]) -> Panel:
95
+ counts = {"CRITICAL": 0, "WARNING": 0, "INFO": 0}
96
+ for ch in changes:
97
+ counts[ch.severity] += 1
98
+
99
+ parts = []
100
+ for sev in ("CRITICAL", "WARNING", "INFO"):
101
+ n = counts[sev]
102
+ style = _SEVERITY_STYLE[sev]
103
+ parts.append(Text(f" {n} {sev} ", style=style))
104
+
105
+ content = Text("").join(parts)
106
+ return Panel(content, title="[bold]Summary", expand=False)
107
+
108
+
109
+ @click.group()
110
+ @click.version_option(package_name="DeckLens-Semantic-Diff-for-CAE")
111
+ def main() -> None:
112
+ """DeckLens: Semantic Diff for CAE input files."""
113
+
114
+
115
+ @main.command()
116
+ @click.argument("before", type=click.Path(exists=True, path_type=Path))
117
+ @click.argument("after", type=click.Path(exists=True, path_type=Path))
118
+ @click.option("--no-ai", is_flag=True, default=False, help="Skip Claude AI analysis.")
119
+ @click.option(
120
+ "--format", "output_format",
121
+ type=click.Choice(["text", "json"], case_sensitive=False),
122
+ default="text",
123
+ help="Output format.",
124
+ )
125
+ @click.option("--model", default="claude-opus-4-8", show_default=True,
126
+ help="Claude model ID for AI analysis.")
127
+ @click.option("--min-severity",
128
+ type=click.Choice(["INFO", "WARNING", "CRITICAL"], case_sensitive=False),
129
+ default="INFO", show_default=True,
130
+ help="Minimum severity level to display.")
131
+ def diff(
132
+ before: Path,
133
+ after: Path,
134
+ no_ai: bool,
135
+ output_format: str,
136
+ model: str,
137
+ min_severity: str,
138
+ ) -> None:
139
+ """Compare two OpenRadioss deck files and show engineering-aware changes.
140
+
141
+ BEFORE and AFTER are paths to .rad input files.
142
+ """
143
+ _sev_rank = {"INFO": 0, "WARNING": 1, "CRITICAL": 2}
144
+ min_rank = _sev_rank[min_severity.upper()]
145
+
146
+ # Parse
147
+ with console.status("[bold green]Parsing decks...", spinner="dots"):
148
+ try:
149
+ deck_before = parse_deck(before)
150
+ deck_after = parse_deck(after)
151
+ except Exception as exc:
152
+ console.print(f"[red]Parse error: {exc}")
153
+ sys.exit(1)
154
+
155
+ # Diff
156
+ engine = DiffEngine()
157
+ all_changes = engine.diff(deck_before, deck_after)
158
+ changes = [ch for ch in all_changes if _sev_rank[ch.severity] >= min_rank]
159
+
160
+ if output_format == "json":
161
+ import dataclasses
162
+ click.echo(json.dumps([dataclasses.asdict(ch) for ch in changes], indent=2))
163
+ return
164
+
165
+ # Rich text output
166
+ console.print()
167
+ console.rule(f"[bold blue]DeckLens Semantic Diff")
168
+ console.print(f" [dim]Before:[/dim] [white]{before}")
169
+ console.print(f" [dim]After: [/dim] [white]{after}")
170
+ console.print()
171
+
172
+ if not changes:
173
+ console.print("[green]No changes found above the specified severity threshold.[/green]")
174
+ return
175
+
176
+ console.print(_build_summary(all_changes))
177
+ console.print()
178
+ console.print(_build_table(changes))
179
+
180
+ # AI analysis
181
+ if not no_ai:
182
+ try:
183
+ from dotenv import load_dotenv
184
+ load_dotenv()
185
+ except ImportError:
186
+ pass
187
+
188
+ import os
189
+ if not os.environ.get("ANTHROPIC_API_KEY"):
190
+ console.print(
191
+ "\n[yellow]Tip: Set ANTHROPIC_API_KEY in .env for AI analysis. "
192
+ "Use --no-ai to suppress this message.[/yellow]"
193
+ )
194
+ return
195
+
196
+ from .explainer.claude import ClaudeExplainer
197
+ with console.status("[bold green]Generating AI analysis...", spinner="dots"):
198
+ explainer = ClaudeExplainer(model=model)
199
+ explainer.explain(changes, str(before), str(after), console=console)
@@ -0,0 +1,3 @@
1
+ from .engine import Change, DiffEngine
2
+
3
+ __all__ = ["Change", "DiffEngine"]